diff --git a/__tests__/modify-master-external-image.test.ts b/__tests__/modify-master-external-image.test.ts new file mode 100644 index 0000000..5746636 --- /dev/null +++ b/__tests__/modify-master-external-image.test.ts @@ -0,0 +1,29 @@ +import Automizer from '../src/automizer'; +import { ModifyImageHelper, ModifyShapeHelper } from '../src'; +import { CmToDxa } from '../src/helper/modify-helper'; + +test('Load external media, modify image target on slide master', async () => { + const automizer = new Automizer({ + templateDir: `${__dirname}/../__tests__/pptx-templates`, + outputDir: `${__dirname}/../__tests__/pptx-output`, + mediaDir: `${__dirname}/../__tests__/images`, + removeExistingSlides: true, + cleanup: true, + }); + + const pres = automizer + .loadRoot(`RootTemplateWithImages.pptx`) + .loadMedia([`test.jpg`]) + .load(`RootTemplateWithImages.pptx`, 'base'); + + pres.addMaster('base', 1, (master) => { + master.modifyElement('masterImagePNG', [ + ModifyImageHelper.setRelationTarget('test.jpg'), + ]); + }); + + // Expect imported slide master (#2) to have swapped (left top) background image + const result = await pres.write(`modify-master-add-external-image.test.pptx`); + + expect(result.images).toBe(8); +}); diff --git a/__tests__/pptx-templates/RootTemplateWithImages.pptx b/__tests__/pptx-templates/RootTemplateWithImages.pptx index 1d9e0bb..9c1bacd 100644 Binary files a/__tests__/pptx-templates/RootTemplateWithImages.pptx and b/__tests__/pptx-templates/RootTemplateWithImages.pptx differ diff --git a/src/classes/has-shapes.ts b/src/classes/has-shapes.ts index 5d7bd2c..38c1be1 100644 --- a/src/classes/has-shapes.ts +++ b/src/classes/has-shapes.ts @@ -32,6 +32,7 @@ import { Image } from '../shapes/image'; import { ElementType } from '../enums/element-type'; import { GenericShape } from '../shapes/generic'; import { XmlSlideHelper } from '../helper/xml-slide-helper'; +import { vd } from '../helper/general-helper'; export default class HasShapes { /** @@ -387,17 +388,27 @@ export default class HasShapes { ? this.getSlideNumber(template, importElement.slideNumber) : importElement.slideNumber; - let sourcePath = `ppt/slides/slide${slideNumber}.xml`; - + let currentMode = 'slideToSlide'; if (this.targetType === 'slideMaster') { - // It is possible to import shapes from loaded presentations, - // as well as to modify an existing shape on current slideMaster - sourcePath = - importElement.mode === 'append' - ? `ppt/slides/slide${slideNumber}.xml` - : `ppt/slideMasters/slideMaster${slideNumber}.xml`; + if (importElement.mode === 'append') { + currentMode = 'slideToMaster'; + } else { + currentMode = 'onMaster'; + } } + // It is possible to import shapes from loaded slides to slideMaster, + // as well as to modify an existing shape on current slideMaster + const sourcePath = + currentMode === 'onMaster' + ? `ppt/slideMasters/slideMaster${slideNumber}.xml` + : `ppt/slides/slide${slideNumber}.xml`; + + const sourceRelPath = + currentMode === 'onMaster' + ? `ppt/slideMasters/_rels/slideMaster${slideNumber}.xml.rels` + : `ppt/slides/_rels/slide${slideNumber}.xml.rels`; + const sourceArchive = await template.archive; const useCreationIds = template.useCreationIds === true && template.creationIds !== undefined; @@ -420,7 +431,7 @@ export default class HasShapes { const appendElementParams = await this.analyzeElement( sourceElement, sourceArchive, - slideNumber, + sourceRelPath, ); return { @@ -754,13 +765,13 @@ export default class HasShapes { async analyzeElement( sourceElement: XmlElement, sourceArchive: IArchive, - slideNumber: number, + relsPath: string, ): Promise { const isChart = sourceElement.getElementsByTagName('c:chart'); if (isChart.length) { const target = await XmlHelper.getTargetByRelId( sourceArchive, - slideNumber, + relsPath, sourceElement, 'chart', ); @@ -775,7 +786,7 @@ export default class HasShapes { if (isChartEx.length) { const target = await XmlHelper.getTargetByRelId( sourceArchive, - slideNumber, + relsPath, sourceElement, 'chartEx', ); @@ -792,7 +803,7 @@ export default class HasShapes { type: ElementType.Image, target: await XmlHelper.getTargetByRelId( sourceArchive, - slideNumber, + relsPath, sourceElement, 'image', ), diff --git a/src/helper/xml-helper.ts b/src/helper/xml-helper.ts index d45e275..310a57e 100644 --- a/src/helper/xml-helper.ts +++ b/src/helper/xml-helper.ts @@ -331,7 +331,7 @@ export class XmlHelper { static async getTargetByRelId( archive: IArchive, - slideNumber: number, + relsPath: string, element: XmlElement, type: string, ): Promise { @@ -339,7 +339,6 @@ export class XmlHelper { const sourceRid = element .getElementsByTagName(params.relRootTag)[0] .getAttribute(params.relAttribute); - const relsPath = `ppt/slides/_rels/slide${slideNumber}.xml.rels`; const imageRels = await XmlHelper.getRelationshipTargetsByPrefix( archive, relsPath, diff --git a/src/shapes/image.ts b/src/shapes/image.ts index 49d11d7..b5f6380 100644 --- a/src/shapes/image.ts +++ b/src/shapes/image.ts @@ -82,9 +82,10 @@ export class Image extends Shape implements IImage { this.applyImageCallbacks(); if (this.hasSvgRelation()) { + const relsPath = `ppt/slides/_rels/slide${this.sourceSlideNumber}.xml.rels`; const target = await XmlHelper.getTargetByRelId( this.sourceArchive, - this.sourceSlideNumber, + relsPath, this.targetElement, 'image:svg', );