@@ -25,6 +25,7 @@ import {
2525 ElementInfo ,
2626 RelationshipAttribute ,
2727 SlideListAttribute ,
28+ TemplateSlideInfo ,
2829 XmlDocument ,
2930 XmlElement ,
3031} from '../types/xml-types' ;
@@ -175,14 +176,18 @@ export default class HasShapes {
175176
176177 /**
177178 * Asynchronously retrieves all elements from the slide.
178- * @params filterTags Use an array of strings to filter parent tags (e.g. 'sp')
179+ * @param filterTags Use an array of strings to filter parent tags (e.g. 'sp')
180+ * @param slideInfo Use placeholder position from layout as fallback
179181 * @returns {Promise<ElementInfo[]> } A promise that resolves to an array of ElementInfo objects.
180182 */
181- async getAllElements ( filterTags ?: string [ ] ) : Promise < ElementInfo [ ] > {
183+ async getAllElements (
184+ filterTags ?: string [ ] ,
185+ slideInfo ?: TemplateSlideInfo ,
186+ ) : Promise < ElementInfo [ ] > {
182187 const xmlSlideHelper = await this . getSlideHelper ( ) ;
183188
184189 // Get all ElementInfo objects
185- return xmlSlideHelper . getAllElements ( filterTags ) ;
190+ return xmlSlideHelper . getAllElements ( filterTags , slideInfo ) ;
186191 }
187192
188193 /**
@@ -218,8 +223,17 @@ export default class HasShapes {
218223 this . sourcePath ,
219224 ) ;
220225
226+ const sourceLayoutId = await XmlRelationshipHelper . getSlideLayoutNumber (
227+ this . sourceTemplate . archive ,
228+ this . sourceNumber ,
229+ ) ;
230+
221231 // Initialize the XmlSlideHelper
222- return new XmlSlideHelper ( slideXml , this ) ;
232+ return new XmlSlideHelper ( slideXml , {
233+ sourceArchive : this . sourceTemplate . archive ,
234+ slideNumber : this . sourceNumber ,
235+ sourceLayoutId
236+ } ) ;
223237 } catch ( error ) {
224238 // Log the error message
225239 throw new Error ( error . message ) ;
@@ -352,29 +366,53 @@ export default class HasShapes {
352366 } ) ;
353367 }
354368
355- getAlreadyModifiedElement ( selector : FindElementSelector ) {
356- // Check if an element with the same selector is already imported in modify mode
357- const existingElement = this . importElements . find ( ( element ) => {
369+ /**
370+ * Checks if an element with the same selector has already been imported or modified.
371+ * This function helps to apply placeholder modifications properly.
372+ *
373+ * @param {FindElementSelector } selector - The selector used to identify an element.
374+ * Can be a string or an object with name and optional creationId/nameIdx.
375+ * @returns {ImportElement|undefined } The existing element if found, otherwise undefined.
376+ */
377+ getAlreadyModifiedElement (
378+ selector : FindElementSelector ,
379+ ) : ImportElement | undefined {
380+ // Search through previously imported/modified elements
381+ return this . importElements . find ( ( element ) => {
382+ // Skip comparison if either selector is not an object
358383 if (
359384 typeof selector !== 'object' ||
360385 typeof element . selector !== 'object'
361386 ) {
362- return ;
387+ return false ;
363388 }
364389
390+ // Case 1: Element without creationId - match by name and nameIdx
365391 if ( ! selector . creationId ) {
366- // Match by name and nameIdx only if the shape has no creationId
367- return selector . name === element . selector . name && selector . nameIdx === element . selector . nameIdx ;
368- } else if ( selector . creationId && element . selector ?. creationId ) {
369- const creaId1 = selector . creationId . replace ( '{' , '' ) . replace ( '}' , '' ) ;
370- const creaId2 = element . selector . creationId
371- . replace ( '{' , '' )
372- . replace ( '}' , '' ) ;
373-
374- return selector . name === element . selector . name && creaId1 === creaId2 ;
392+ return (
393+ selector . name === element . selector . name &&
394+ selector . nameIdx === element . selector . nameIdx
395+ ) ;
375396 }
397+
398+ // Case 2: Element with creationId - match by name and normalized creationId
399+ if ( selector . creationId && element . selector ?. creationId ) {
400+ // Normalize creationIds by removing curly braces
401+ const normalizedSelectorId = selector . creationId . replace ( / { | } / g, '' ) ;
402+ const normalizedElementId = element . selector . creationId . replace (
403+ / { | } / g,
404+ '' ,
405+ ) ;
406+
407+ return (
408+ selector . name === element . selector . name &&
409+ normalizedSelectorId === normalizedElementId
410+ ) ;
411+ }
412+
413+ // No match found for this element
414+ return false ;
376415 } ) ;
377- return existingElement ;
378416 }
379417
380418 /**
@@ -565,7 +603,7 @@ export default class HasShapes {
565603 selector : selector ,
566604 } ) ;
567605 } else {
568- if ( selector . creationId ) {
606+ if ( selector . creationId ) {
569607 strategies . push ( {
570608 mode : 'findByElementCreationId' ,
571609 selector : selector . creationId ,
@@ -575,7 +613,7 @@ export default class HasShapes {
575613 strategies . push ( {
576614 mode : 'findByElementName' ,
577615 selector : selector . name ,
578- nameIdx : selector . nameIdx
616+ nameIdx : selector . nameIdx ,
579617 } ) ;
580618 }
581619
0 commit comments