@@ -2,7 +2,7 @@ import { FileHelper } from '../helper/file-helper';
22import { XmlHelper } from '../helper/xml-helper' ;
33import { Shape } from '../classes/shape' ;
44import { ImportedElement , ShapeTargetType , Target } from '../types/types' ;
5- import { XmlElement } from '../types/xml-types' ;
5+ import { XmlElement , RelationshipAttribute } from '../types/xml-types' ;
66import IArchive from '../interfaces/iarchive' ;
77import { RootPresTemplate } from '../interfaces/root-pres-template' ;
88import { contentTracker } from '../helper/content-tracker' ;
@@ -55,6 +55,9 @@ export class OLEObject extends Shape {
5555 ) : Promise < OLEObject > {
5656 await this . prepare ( targetTemplate , targetSlideNumber ) ;
5757 await this . removeFromSlideTree ( ) ;
58+ await this . removeOleObjectFile ( ) ;
59+ await this . removeFromContentTypes ( ) ;
60+ await this . removeFromSlideRels ( ) ;
5861
5962 return this ;
6063 }
@@ -66,8 +69,6 @@ export class OLEObject extends Shape {
6669 ) : Promise < void > {
6770 await this . setTarget ( targetTemplate , targetSlideNumber ) ;
6871
69- this . targetNumber = this . targetTemplate . incrementCounter ( 'oleObjects' ) ;
70-
7172 const allOleObjects = oleObjects || await OLEObject . getAllOnSlide ( this . sourceArchive , this . targetSlideRelFile ) ;
7273
7374 const oleObject = allOleObjects . find ( obj => obj . rId === this . sourceRid ) ;
@@ -77,17 +78,17 @@ export class OLEObject extends Shape {
7778
7879 const sourceFilePath = `ppt/embeddings/${ oleObject . file . split ( '/' ) . pop ( ) } ` ;
7980
80- await this . copyFiles ( sourceFilePath ) ;
81- await this . appendTypes ( ) ;
82- }
81+ this . createdRid = await XmlHelper . getNextRelId ( this . targetArchive , this . targetSlideRelFile ) ;
8382
84- private async copyFiles ( sourceFilePath : string ) : Promise < void > {
85- if ( ! this . createdRid ) {
86- this . createdRid = await XmlHelper . getNextRelId ( this . targetArchive , this . targetSlideRelFile ) ;
87- }
83+ await this . copyOleObjectFile ( sourceFilePath ) ;
84+ await this . appendToContentTypes ( ) ;
85+ await this . updateSlideRels ( ) ;
86+ await this . updateSlideXml ( ) ;
87+ }
8888
89+ private async copyOleObjectFile ( sourceFilePath : string ) : Promise < void > {
8990 const fileExtension = this . getFileExtension ( sourceFilePath ) ;
90- const targetFileName = `ppt/embeddings/${ this . createdRid } ${ fileExtension } ` ;
91+ const targetFileName = `ppt/embeddings/oleObject ${ this . createdRid } ${ fileExtension } ` ;
9192
9293 try {
9394 await FileHelper . zipCopy (
@@ -102,46 +103,13 @@ export class OLEObject extends Shape {
102103 }
103104 }
104105
105- private async appendTypes ( ) : Promise < void > {
106- await this . appendOleObjectToContentType ( ) ;
107- }
108-
109- private async editTargetOleObjectRel ( ) : Promise < void > {
110- const targetRelFile = this . targetSlideRelFile ;
111- const relXml = await XmlHelper . getXmlFromArchive ( this . targetArchive , targetRelFile ) ;
112- const relations = relXml . getElementsByTagName ( 'Relationship' ) ;
113-
114- Array . from ( relations ) . forEach ( ( element ) => {
115- const type = element . getAttribute ( 'Type' ) ;
116- if ( type === 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject' ) {
117- const fileExtension = this . getFileExtension ( element . getAttribute ( 'Target' ) ) ;
118- this . updateTargetOleObjectRelation (
119- element ,
120- 'Target' ,
121- `../embeddings/${ this . createdRid } ${ fileExtension } ` ,
122- ) ;
123- }
124- } ) ;
125-
126- XmlHelper . writeXmlToArchive ( this . targetArchive , targetRelFile , relXml ) ;
127- }
128-
129- private updateTargetOleObjectRelation ( element : Element , attribute : string , value : string ) : void {
130- element . setAttribute ( attribute , value ) ;
131- contentTracker . trackRelation ( this . targetSlideRelFile , {
132- Id : element . getAttribute ( 'Id' ) || '' ,
133- Target : value ,
134- Type : element . getAttribute ( 'Type' ) || '' ,
135- } ) ;
136- }
137-
138- private async appendOleObjectToContentType ( ) : Promise < void > {
106+ private async appendToContentTypes ( ) : Promise < void > {
139107 const contentTypesPath = '[Content_Types].xml' ;
140108 const contentTypesXml = await XmlHelper . getXmlFromArchive ( this . targetArchive , contentTypesPath ) ;
141109
142110 const types = contentTypesXml . getElementsByTagName ( 'Types' ) [ 0 ] ;
143111 const fileExtension = this . getFileExtension ( this . oleObjectPath ) ;
144- const partName = `/ppt/embeddings/${ this . createdRid } ${ fileExtension } ` ;
112+ const partName = `/ppt/embeddings/oleObject ${ this . createdRid } ${ fileExtension } ` ;
145113 const existingOverride = Array . from ( types . getElementsByTagName ( 'Override' ) ) . find (
146114 ( override ) => override . getAttribute ( 'PartName' ) === partName
147115 ) ;
@@ -152,10 +120,61 @@ export class OLEObject extends Shape {
152120 newOverride . setAttribute ( 'ContentType' , this . getContentType ( fileExtension ) ) ;
153121 types . appendChild ( newOverride ) ;
154122
155- XmlHelper . writeXmlToArchive ( this . targetArchive , contentTypesPath , contentTypesXml ) ;
123+ await XmlHelper . writeXmlToArchive ( this . targetArchive , contentTypesPath , contentTypesXml ) ;
156124 }
157125 }
158126
127+ private async updateSlideRels ( ) : Promise < void > {
128+ const targetRelFile = `ppt/${ this . targetType } s/_rels/${ this . targetType } ${ this . targetSlideNumber } .xml.rels` ;
129+ const relXml = await XmlHelper . getXmlFromArchive ( this . targetArchive , targetRelFile ) ;
130+ const relationships = relXml . getElementsByTagName ( 'Relationship' ) ;
131+
132+ const fileExtension = this . getFileExtension ( this . oleObjectPath ) ;
133+ const newTarget = `../embeddings/oleObject${ this . createdRid } ${ fileExtension } ` ;
134+
135+ // Update or create the relationship
136+ let relationshipUpdated = false ;
137+ for ( let i = 0 ; i < relationships . length ; i ++ ) {
138+ if ( relationships [ i ] . getAttribute ( 'Id' ) === this . sourceRid ) {
139+ relationships [ i ] . setAttribute ( 'Id' , this . createdRid ) ;
140+ relationships [ i ] . setAttribute ( 'Target' , newTarget ) ;
141+ relationshipUpdated = true ;
142+ break ;
143+ }
144+ }
145+
146+ if ( ! relationshipUpdated ) {
147+ const newRel = relXml . createElement ( 'Relationship' ) ;
148+ newRel . setAttribute ( 'Id' , this . createdRid ) ;
149+ newRel . setAttribute ( 'Type' , 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject' ) ;
150+ newRel . setAttribute ( 'Target' , newTarget ) ;
151+ relXml . documentElement . appendChild ( newRel ) ;
152+ }
153+
154+ await XmlHelper . writeXmlToArchive ( this . targetArchive , targetRelFile , relXml ) ;
155+ }
156+
157+ private async updateSlideXml ( ) : Promise < void > {
158+ const slideXmlPath = `ppt/slides/slide${ this . targetSlideNumber } .xml` ;
159+ const slideXml = await XmlHelper . getXmlFromArchive ( this . targetArchive , slideXmlPath ) ;
160+
161+ const oleObjs = Array . from ( slideXml . getElementsByTagName ( 'p:oleObj' ) ) ;
162+ oleObjs . forEach ( ( oleObj ) => {
163+ if ( oleObj . getAttribute ( 'r:id' ) === this . sourceRid ) {
164+ oleObj . setAttribute ( 'r:id' , this . createdRid ) ;
165+ const oleObjPr = oleObj . getElementsByTagName ( 'p:oleObjPr' ) [ 0 ] ;
166+ if ( oleObjPr ) {
167+ const links = Array . from ( oleObjPr . getElementsByTagName ( 'a:link' ) ) ;
168+ links . forEach ( link => {
169+ link . setAttribute ( 'r:id' , this . createdRid ) ;
170+ } ) ;
171+ }
172+ }
173+ } ) ;
174+
175+ await XmlHelper . writeXmlToArchive ( this . targetArchive , slideXmlPath , slideXml ) ;
176+ }
177+
159178 private getContentType ( fileExtension : string ) : string {
160179 const contentTypes : { [ key : string ] : string } = {
161180 '.bin' : 'application/vnd.openxmlformats-officedocument.oleObject' ,
@@ -169,6 +188,44 @@ export class OLEObject extends Shape {
169188 return contentTypes [ fileExtension . toLowerCase ( ) ] || 'application/vnd.openxmlformats-officedocument.oleObject' ;
170189 }
171190
191+ private async removeOleObjectFile ( ) : Promise < void > {
192+ const fileExtension = this . getFileExtension ( this . oleObjectPath ) ;
193+ const fileName = `ppt/embeddings/oleObject${ this . createdRid } ${ fileExtension } ` ;
194+ await this . targetArchive . remove ( fileName ) ;
195+ }
196+
197+ private async removeFromContentTypes ( ) : Promise < void > {
198+ const contentTypesPath = '[Content_Types].xml' ;
199+ const contentTypesXml = await XmlHelper . getXmlFromArchive ( this . targetArchive , contentTypesPath ) ;
200+
201+ const types = contentTypesXml . getElementsByTagName ( 'Types' ) [ 0 ] ;
202+ const fileExtension = this . getFileExtension ( this . oleObjectPath ) ;
203+ const partName = `/ppt/embeddings/oleObject${ this . createdRid } ${ fileExtension } ` ;
204+ const overrideToRemove = Array . from ( types . getElementsByTagName ( 'Override' ) ) . find (
205+ ( override ) => override . getAttribute ( 'PartName' ) === partName
206+ ) ;
207+
208+ if ( overrideToRemove ) {
209+ types . removeChild ( overrideToRemove ) ;
210+ await XmlHelper . writeXmlToArchive ( this . targetArchive , contentTypesPath , contentTypesXml ) ;
211+ }
212+ }
213+
214+ private async removeFromSlideRels ( ) : Promise < void > {
215+ const targetRelFile = `ppt/${ this . targetType } s/_rels/${ this . targetType } ${ this . targetSlideNumber } .xml.rels` ;
216+ const relXml = await XmlHelper . getXmlFromArchive ( this . targetArchive , targetRelFile ) ;
217+ const relationships = relXml . getElementsByTagName ( 'Relationship' ) ;
218+
219+ for ( let i = 0 ; i < relationships . length ; i ++ ) {
220+ if ( relationships [ i ] . getAttribute ( 'Id' ) === this . createdRid ) {
221+ relationships [ i ] . parentNode . removeChild ( relationships [ i ] ) ;
222+ break ;
223+ }
224+ }
225+
226+ await XmlHelper . writeXmlToArchive ( this . targetArchive , targetRelFile , relXml ) ;
227+ }
228+
172229 static async getAllOnSlide (
173230 archive : IArchive ,
174231 relsPath : string ,
@@ -199,6 +256,5 @@ export class OLEObject extends Shape {
199256 oleObjects : Target [ ]
200257 ) : Promise < void > {
201258 await this . prepare ( targetTemplate , targetSlideNumber , oleObjects ) ;
202- await this . editTargetOleObjectRel ( ) ;
203259 }
204260}
0 commit comments