UNPKG

pptx-automizer

Version:

A template based pptx generator

201 lines 8.75 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _a; Object.defineProperty(exports, "__esModule", { value: true }); const modify_hyperlink_element_1 = __importDefault(require("./modify-hyperlink-element")); const xml_helper_1 = require("./xml-helper"); const general_helper_1 = require("./general-helper"); /** * Helper class for modifying hyperlinks in PowerPoint elements */ class ModifyHyperlinkHelper { static createRelationshipData(target, isInternal) { if (isInternal) { return { Type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', Target: `../slides/${target}`, Id: '', // Will be set later }; } return { Type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', Target: target.toString(), TargetMode: 'External', Id: '', // Will be set later }; } static addRelationship(relation, relData) { const relNodes = relation.getElementsByTagName('Relationship'); const maxId = xml_helper_1.XmlHelper.getMaxId(relNodes, 'Id', true); const newRelId = `rId${maxId}`; const newRel = relation.ownerDocument.createElement('Relationship'); newRel.setAttribute('Id', newRelId); Object.entries(relData).forEach(([key, value]) => { if (value) newRel.setAttribute(key, value); }); relNodes.item(0).parentNode.appendChild(newRel); return newRelId; } static addHyperlinkToTextRuns(element, hyperlinkElement) { const textRuns = element.getElementsByTagName('a:r'); Array.from(textRuns).forEach((run) => { let rPr = run.getElementsByTagName('a:rPr')[0]; if (!rPr) { rPr = element.ownerDocument.createElement('a:rPr'); const textElement = run.getElementsByTagName('a:t')[0]; if (textElement) { run.insertBefore(rPr, textElement); } else { run.appendChild(rPr); } } rPr.appendChild(hyperlinkElement.createHlinkClick()); }); } static addHyperlinkToParagraph(paragraph, hyperlinkElement) { const existingText = paragraph.getElementsByTagName('a:t')[0]; const text = (existingText === null || existingText === void 0 ? void 0 : existingText.textContent) || 'Hyperlink'; if (existingText === null || existingText === void 0 ? void 0 : existingText.parentNode) { paragraph.removeChild(existingText.parentNode); } const run = hyperlinkElement.createTextRun(text); paragraph.appendChild(run); } static createNewTextStructure(txBody, hyperlinkElement) { const p = txBody.ownerDocument.createElement('a:p'); const run = hyperlinkElement.createTextRun('Hyperlink'); p.appendChild(run); txBody.appendChild(p); } } exports.default = ModifyHyperlinkHelper; _a = ModifyHyperlinkHelper; /** * Set the target URL of a hyperlink * * @param target The new target URL for the hyperlink * @param isExternal Whether the hyperlink is external (true) or internal (false) * @returns A callback function that modifies the hyperlink */ ModifyHyperlinkHelper.setHyperlinkTarget = (target, isExternal = true) => (element, relation) => __awaiter(void 0, void 0, void 0, function* () { if (!element || !relation) { general_helper_1.Logger.log('SetHyperlinkTarget: Missing element or relation', 2); return; } // Find existing hyperlinks const hlinkClicks = element.getElementsByTagName('a:hlinkClick'); if (hlinkClicks.length === 0) { general_helper_1.Logger.log('No hyperlinks found to modify', 1); return; } // Get all existing rIds from hyperlinks const existingRIds = Array.from(hlinkClicks) .map((hlink) => hlink.getAttribute('r:id')) .filter(Boolean); if (existingRIds.length === 0) { general_helper_1.Logger.log('No valid relationship IDs found in hyperlinks', 1); return; } // Create new relationship data const relData = _a.createRelationshipData(target, !isExternal); const newRelId = _a.addRelationship(relation, relData); // Update all hyperlink elements with new relationship ID Array.from(hlinkClicks).forEach((hlink) => { // Update relationship ID hlink.setAttribute('r:id', newRelId); // Update internal/external specific attributes if (!isExternal) { hlink.setAttribute('action', 'ppaction://hlinksldjump'); hlink.setAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); hlink.setAttribute('xmlns:p14', 'http://schemas.microsoft.com/office/powerpoint/2010/main'); } else { hlink.removeAttribute('action'); // Keep xmlns attributes as they're still needed for the relationship } }); // Remove old relationships const relationships = relation.getElementsByTagName('Relationship'); Array.from(relationships).forEach((rel) => { const relId = rel.getAttribute('Id'); if (relId && existingRIds.includes(relId)) { relation.removeChild(rel); } }); general_helper_1.Logger.log('SetHyperlinkTarget: Successfully updated hyperlink target', 2); }); /** * Add a hyperlink to an element * * @param target The target URL for external links, or slide number for internal links * @param isInternalLink * @returns A callback function that adds a hyperlink */ ModifyHyperlinkHelper.addHyperlink = (target, isInternalLink) => (element, relation) => { if (!element || !relation) return; if (typeof target === 'number') { target = `slide${target}.xml`; isInternalLink = true; } const relData = _a.createRelationshipData(target, isInternalLink); const newRelId = _a.addRelationship(relation, relData); const hasHlink = element.getElementsByTagName('a:hlinkClick'); if (hasHlink.item(0)) { // Link has already been set by e.g. pptxGenJs, don't add another link to element return; } const hyperlinkElement = new modify_hyperlink_element_1.default(element.ownerDocument, newRelId, isInternalLink); const textRuns = element.getElementsByTagName('a:r'); if (textRuns.length > 0) { _a.addHyperlinkToTextRuns(element, hyperlinkElement); } else { const paragraphs = element.getElementsByTagName('a:p'); if (paragraphs.length > 0) { _a.addHyperlinkToParagraph(paragraphs[0], hyperlinkElement); } else { const txBody = element.getElementsByTagName('p:txBody')[0] || element.getElementsByTagName('a:txBody')[0]; if (txBody) { _a.createNewTextStructure(txBody, hyperlinkElement); } else { console.error('No suitable text element found to add hyperlink to'); } } } general_helper_1.Logger.log('AddHyperlink: Successfully completed', 2); }; /** * Remove hyperlinks from an element * * @returns A callback function that removes hyperlinks */ ModifyHyperlinkHelper.removeHyperlink = () => (element, relation) => __awaiter(void 0, void 0, void 0, function* () { if (!element) return; try { const hlinkClicks = element.getElementsByTagName('a:hlinkClick'); Array.from(hlinkClicks).forEach((hlink) => { var _b; return (_b = hlink.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(hlink); }); general_helper_1.Logger.log('RemoveHyperlink: Successfully completed', 2); } catch (error) { console.error('Error in RemoveHyperlink:', error); } }); //# sourceMappingURL=modify-hyperlink-helper.js.map