pptx-automizer
Version:
A template based pptx generator
343 lines • 13.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const xml_helper_1 = require("./xml-helper");
const xml_slide_helper_1 = require("./xml-slide-helper");
const index_1 = require("../index");
/**
* Helper class for cleaning and clearing PowerPoint effects in XML structure
*/
class ModifyCleanupHelper {
/**
* Removes unwanted visual effects from PowerPoint elements based on their type
* Preserves certain effects for drawings but removes distracting effects from photos
*
* @param element - The XML element to clean up
*/
static removeEffects(element) {
ModifyCleanupHelper.removeShapeStyle(element);
ModifyCleanupHelper.removeColorAdjustment(element);
ModifyCleanupHelper.removeShadowEffects(element);
ModifyCleanupHelper.remove3dEffects(element);
ModifyCleanupHelper.removeFillEffects(element);
ModifyCleanupHelper.removeTextEffects(element);
ModifyCleanupHelper.removeExtLst(element);
// Determine the visual type of the element (picture, chart, etc.)
// Apply type-specific cleanup
const elementType = xml_slide_helper_1.XmlSlideHelper.getElementVisualType(element);
switch (elementType) {
case 'picture':
case 'svgImage':
case 'pictogram':
// Remove artistic effects
[
'a:duotone',
'a:artistic',
'a:colorChange',
'a:softEdge',
'a:prstTxWarp',
'a:sketch',
'ask:lineSketchStyleProps',
].forEach((tag) => {
xml_helper_1.XmlHelper.removeByTagName(element, tag);
});
break;
case 'chart':
// For charts, be more conservative - only remove extreme effects
['c:view3D', 'c:perspective', 'a:prstTxWarp'].forEach((tag) => {
xml_helper_1.XmlHelper.removeByTagName(element, tag);
});
break;
default:
// For unknown types, be conservative - only remove clearly problematic effects
['a:prstTxWarp', 'a:sketch', 'ask:lineSketchStyleProps'].forEach((tag) => {
xml_helper_1.XmlHelper.removeByTagName(element, tag);
});
}
}
/**
* Removes text formatting effects
*
* @param element - The XML element containing text runs to clean up
*/
static removeTextEffects(element) {
// Get all text run property elements
const textRuns = element.getElementsByTagName('a:rPr');
// Process each text run
xml_helper_1.XmlHelper.modifyCollection(textRuns, (textRun) => {
// Remove font specification elements
const latin = textRun.getElementsByTagName('a:latin').item(0);
const ea = textRun.getElementsByTagName('a:ea').item(0);
const cs = textRun.getElementsByTagName('a:cs').item(0);
// Remove all font elements
xml_helper_1.XmlHelper.remove(latin);
xml_helper_1.XmlHelper.remove(ea);
xml_helper_1.XmlHelper.remove(cs);
});
}
/**
* Removes extension list (extLst) elements from PowerPoint shapes
*
* The extLst (Extension List) element in OOXML contains application-specific extensions
* and future compatibility features that may not be supported across all Office versions.
* These extensions can include:
* - Custom drawing effects and transformations
* - Third-party add-in specific properties
* - Version-specific features that may cause rendering inconsistencies
* - Experimental or preview features
*
* Removing extLst helps ensure cross-version compatibility and prevents rendering
* issues when the presentation is opened in different versions of PowerPoint or
* other OOXML-compatible applications.
*
* @param element - The XML element containing extension lists to remove
*/
static removeExtLst(element) {
const extLst = element.getElementsByTagName('a:extLst').item(0);
xml_helper_1.XmlHelper.remove(extLst);
}
static clearTextUnderlineToBold(element) {
const textRuns = element.getElementsByTagName('a:rPr');
xml_helper_1.XmlHelper.modifyCollection(textRuns, (textRun) => {
const isUnderlined = textRun.getAttribute('u');
// Convert underlined text to bold text
if (textRun && isUnderlined) {
textRun.removeAttribute('u');
textRun.setAttribute('b', '1');
}
});
}
static clearTextItalicsToBold(element) {
const textRuns = element.getElementsByTagName('a:rPr');
xml_helper_1.XmlHelper.modifyCollection(textRuns, (textRun) => {
const isItalics = textRun.getAttribute('i');
// Convert italics text to bold text
if (textRun && isItalics) {
textRun.removeAttribute('i');
textRun.setAttribute('b', '1');
}
});
}
static clearTextUnderline(element) {
const textRuns = element.getElementsByTagName('a:rPr');
xml_helper_1.XmlHelper.modifyCollection(textRuns, (textRun) => {
textRun === null || textRun === void 0 ? void 0 : textRun.removeAttribute('u');
});
}
static clearTextBold(element) {
const textRuns = element.getElementsByTagName('a:rPr');
xml_helper_1.XmlHelper.modifyCollection(textRuns, (textRun) => {
textRun === null || textRun === void 0 ? void 0 : textRun.removeAttribute('b');
});
}
static clearTextSize(element) {
const textRuns = element.getElementsByTagName('a:rPr');
xml_helper_1.XmlHelper.modifyCollection(textRuns, (textRun) => {
textRun === null || textRun === void 0 ? void 0 : textRun.removeAttribute('sz');
});
}
static clearTextColor(element, color) {
const textRuns = element.getElementsByTagName('a:rPr');
xml_helper_1.XmlHelper.modifyCollection(textRuns, (textRun) => {
if (color) {
index_1.ModifyColorHelper.solidFill(color, 0)(textRun);
}
else {
// Remove all color-related elements from text run properties
const solidFill = textRun.getElementsByTagName('a:solidFill')[0];
if (solidFill) {
xml_helper_1.XmlHelper.remove(solidFill);
}
const gradFill = textRun.getElementsByTagName('a:gradFill')[0];
if (gradFill) {
xml_helper_1.XmlHelper.remove(gradFill);
}
const pattFill = textRun.getElementsByTagName('a:pattFill')[0];
if (pattFill) {
xml_helper_1.XmlHelper.remove(pattFill);
}
const noFill = textRun.getElementsByTagName('a:noFill')[0];
if (noFill) {
xml_helper_1.XmlHelper.remove(noFill);
}
// Remove highlight color
const highlight = textRun.getElementsByTagName('a:highlight')[0];
if (highlight) {
xml_helper_1.XmlHelper.remove(highlight);
}
}
});
}
static removeFillEffects(element) {
// Remove reflection, glow effects, gradients and complex fill effects
['a:reflection', 'a:glow', 'a:gradFill', 'a:pattFill', 'a:grpFill'].forEach((tag) => {
xml_helper_1.XmlHelper.removeByTagName(element, tag);
});
['a:scene3d', 'a:sp3d'].forEach((tag) => {
xml_helper_1.XmlHelper.removeByTagName(element, tag);
});
}
static remove3dEffects(element) {
['a:scene3d', 'a:sp3d'].forEach((tag) => {
xml_helper_1.XmlHelper.removeByTagName(element, tag);
});
}
static removeShadowEffects(element) {
// Remove shadow effects for all types
[
'a:outerShdw',
'a:innerShdw',
'a:gradFill',
'a:pattFill',
'a:grpFill',
].forEach((tag) => {
xml_helper_1.XmlHelper.removeByTagName(element, tag);
});
}
static removeColorAdjustment(element) {
// Remove color adjustments and transformations
[
'a:alpha',
'a:alphaInv',
'a:alphaMod',
'a:alphaOff',
'a:blue',
'a:blueMod',
'a:blueOff',
'a:comp',
'a:gamma',
'a:gray',
'a:green',
'a:greenMod',
'a:greenOff',
'a:hue',
'a:hueMod',
'a:hueOff',
'a:inv',
'a:invGamma',
'a:lum',
'a:lumMod',
'a:lumOff',
'a:red',
'a:redMod',
'a:redOff',
'a:sat',
'a:satMod',
'a:satOff',
'a:shade',
'a:tint',
].forEach((tag) => {
xml_helper_1.XmlHelper.removeByTagName(element, tag);
});
}
}
exports.default = ModifyCleanupHelper;
/**
* Removes background color and fill elements from a shape
* This removes both visible and hidden fill properties and sets explicit noFill
*
* @param element - The XML element representing the shape
*/
ModifyCleanupHelper.removeBackground = (element) => {
// Find the spPr (ShapeProperties) element where fill properties are defined
const spPr = element.getElementsByTagName('p:spPr')[0] ||
element.getElementsByTagName('a:spPr')[0];
if (!spPr) {
return; // No shape properties found, nothing to remove
}
// Remove all types of fill elements
// 1. solidFill - used for solid color backgrounds
const solidFill = spPr.getElementsByTagName('a:solidFill')[0];
if (solidFill) {
xml_helper_1.XmlHelper.remove(solidFill);
}
// 2. gradFill - used for gradient backgrounds
const gradFill = spPr.getElementsByTagName('a:gradFill')[0];
if (gradFill) {
xml_helper_1.XmlHelper.remove(gradFill);
}
// 3. pattFill - used for pattern backgrounds
const pattFill = spPr.getElementsByTagName('a:pattFill')[0];
if (pattFill) {
xml_helper_1.XmlHelper.remove(pattFill);
}
// 4. grpFill - used when inheriting fill from parent group
const grpFill = spPr.getElementsByTagName('a:grpFill')[0];
if (grpFill) {
xml_helper_1.XmlHelper.remove(grpFill);
}
};
/**
* Removes shape style but preserves fill color information by moving it to a standard fill element
* This converts the p:style reference colors to direct solidFill colors on the shape
*
* @param element - The XML element representing the shape
*/
ModifyCleanupHelper.removeShapeStyle = (element) => {
// Find the style element in the shape
const styleElement = element.getElementsByTagName('p:style')[0];
if (!styleElement) {
return; // No style element found, nothing to do
}
// First extract the fill color information before removing the style
const fillRef = styleElement.getElementsByTagName('a:fillRef')[0];
let colorInfo = null;
if (fillRef) {
// Try to get the scheme color information
const schemeClr = fillRef.getElementsByTagName('a:schemeClr')[0];
if (schemeClr) {
const colorValue = schemeClr.getAttribute('val');
if (colorValue) {
colorInfo = {
type: 'schemeClr',
value: colorValue,
};
}
}
// Check for srgbClr as an alternative
const srgbClr = fillRef.getElementsByTagName('a:srgbClr')[0];
if (srgbClr && !colorInfo) {
const colorValue = srgbClr.getAttribute('val');
if (colorValue) {
colorInfo = {
type: 'srgbClr',
value: colorValue,
};
}
}
}
// Now remove the style element
xml_helper_1.XmlHelper.remove(styleElement);
// If we found color information, apply it to the shape as a standard fill
if (colorInfo) {
index_1.ModifyColorHelper.solidFill(colorInfo)(element.getElementsByTagName('p:spPr').item(0));
}
};
/**
* Removes border/outline from a shape
* This function removes the a:ln (line) element which defines the border properties
*
* @param element - The XML element representing the shape
*/
ModifyCleanupHelper.removeBorder = (element) => {
// Find the spPr (ShapeProperties) element where line/border properties are defined
const spPr = element.getElementsByTagName('p:spPr')[0] ||
element.getElementsByTagName('a:spPr')[0];
if (!spPr) {
return; // No shape properties found, nothing to remove
}
// Remove the a:ln element which defines the border/outline
const ln = spPr.getElementsByTagName('a:ln')[0];
if (ln) {
xml_helper_1.XmlHelper.remove(ln);
}
// Also check for table cell borders (lnL, lnR, lnT, lnB) if they exist
// These are used for table cell borders in PowerPoint
const tableBorders = ['a:lnL', 'a:lnR', 'a:lnT', 'a:lnB'];
tableBorders.forEach((borderTag) => {
const border = element.getElementsByTagName(borderTag)[0];
if (border) {
xml_helper_1.XmlHelper.remove(border);
}
});
};
//# sourceMappingURL=modify-cleanup-helper.js.map