Skip to content

Commit 36a2407

Browse files
committed
refactor(shape): separate cleanup helper; improve visual type recognition
1 parent 8fec90e commit 36a2407

File tree

13 files changed

+603
-392
lines changed

13 files changed

+603
-392
lines changed

__tests__/add-shape-types.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Automizer, { XmlElement, XmlHelper } from '../src/index';
22
import { ModifyShapeHelper } from '../src';
3+
import { vd } from '../src/helper/general-helper';
34

45
test('add all implemented shape types to an empty slide', async () => {
56
const automizer = new Automizer({
@@ -33,10 +34,15 @@ test('add all implemented shape types to an empty slide', async () => {
3334
expect(type).toBe('table');
3435
});
3536

37+
slide.addElement('collection', 1, 'Textfield (Native)', (element: XmlElement) => {
38+
const type = ModifyShapeHelper.getElementVisualType(element);
39+
expect(type).toBe('textBox');
40+
});
41+
3642
slide.addElement('collection', 1, 'Textfield', (element: XmlElement) => {
3743
// XmlHelper.dump(element)
3844
const type = ModifyShapeHelper.getElementVisualType(element);
39-
expect(type).toBe('textField');
45+
expect(type).toBe('textBox');
4046
});
4147

4248
slide.addElement(
@@ -69,6 +75,12 @@ test('add all implemented shape types to an empty slide', async () => {
6975
const type = ModifyShapeHelper.getElementVisualType(element);
7076
expect(type).toBe('svgImage');
7177
});
78+
79+
slide.addElement('collection', 1, 'Image filled rectangle', (element: XmlElement) => {
80+
const type = ModifyShapeHelper.getElementVisualType(element);
81+
// ToDo: SVG image breaks in the output if embedded in a vectorShape
82+
expect(type).toBe('svgImage');
83+
});
7284
});
7385

7486
await pres.write(`add-shape-types.test.pptx`);
8 KB
Binary file not shown.

__tests__/read-shape-type.test.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Automizer, { XmlElement, XmlHelper } from '../src/index';
22
import { ModifyShapeHelper } from '../src';
3+
import { ElementVisualType } from '../src/types/xml-types';
34

45
test('read shape type info', async () => {
56
const automizer = new Automizer({
@@ -21,46 +22,56 @@ test('read shape type info', async () => {
2122
},
2223
);
2324

25+
slide.modifyElement('VecorShape (Rectangle)', (element: XmlElement) => {
26+
// XmlHelper.dump(element);
27+
const type = ModifyShapeHelper.getElementVisualType(element);
28+
expect(type).toBe<ElementVisualType>('rectangle');
29+
});
30+
2431
slide.modifyElement('Line (Arrow)', (element: XmlElement) => {
2532
const type = ModifyShapeHelper.getElementVisualType(element);
26-
expect(type).toBe('vectorLine');
33+
expect(type).toBe<ElementVisualType>('vectorLine');
2734
});
2835

2936
slide.modifyElement('Table', (element: XmlElement) => {
3037
const type = ModifyShapeHelper.getElementVisualType(element);
31-
expect(type).toBe('table');
38+
expect(type).toBe<ElementVisualType>('table');
3239
});
3340

3441
slide.modifyElement('Textfield', (element: XmlElement) => {
3542
// XmlHelper.dump(element)
3643
const type = ModifyShapeHelper.getElementVisualType(element);
37-
expect(type).toBe('textField');
44+
expect(type).toBe<ElementVisualType>('textBox');
45+
});
46+
47+
slide.modifyElement('Textfield (Native)', (element: XmlElement) => {
48+
const type = ModifyShapeHelper.getElementVisualType(element);
49+
expect(type).toBe<ElementVisualType>('textBox');
3850
});
3951

4052
slide.modifyElement('SmartArt (Diagram)', (element: XmlElement) => {
4153
const type = ModifyShapeHelper.getElementVisualType(element);
42-
expect(type).toBe('smartArt');
54+
expect(type).toBe<ElementVisualType>('smartArt');
4355
});
4456

4557
slide.modifyElement('Image', (element: XmlElement) => {
4658
const type = ModifyShapeHelper.getElementVisualType(element);
47-
expect(type).toBe('picture');
59+
expect(type).toBe<ElementVisualType>('picture');
4860
});
4961

5062
slide.modifyElement('Chart', (element: XmlElement) => {
5163
const type = ModifyShapeHelper.getElementVisualType(element);
52-
expect(type).toBe('chart');
64+
expect(type).toBe<ElementVisualType>('chart');
5365
});
5466

5567
slide.modifyElement('Pictogram', (element: XmlElement) => {
5668
const type = ModifyShapeHelper.getElementVisualType(element);
57-
expect(type).toBe('svgImage');
69+
expect(type).toBe<ElementVisualType>('svgImage');
5870
});
5971

6072
slide.modifyElement('SVG Image', (element: XmlElement) => {
61-
// XmlHelper.dump(element);
6273
const type = ModifyShapeHelper.getElementVisualType(element);
63-
expect(type).toBe('svgImage');
74+
expect(type).toBe<ElementVisualType>('svgImage');
6475
});
6576
});
6677

src/classes/has-shapes.ts

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export default class HasShapes {
135135
unsupportedTags = [
136136
'p:custDataLst',
137137
// exclude bullet images
138-
// 'a:buBlip',
138+
'a:buBlip',
139139
// 'p:oleObj',
140140
// 'mc:AlternateContent',
141141
// 'a14:imgProps',
@@ -405,9 +405,8 @@ export default class HasShapes {
405405
* Try to convert a given slide's creationId to corresponding slide number.
406406
* Used if automizer is run with useCreationIds: true
407407
* @internal
408-
* @param PresTemplate
409-
* @slideNumber SourceSlideIdentifier
410-
* @returns number
408+
* @param template
409+
* @param slideIdentifier
411410
*/
412411
getSlideNumber(
413412
template: PresTemplate,
@@ -436,19 +435,47 @@ export default class HasShapes {
436435
return slideIdentifier as number;
437436
}
438437

438+
/**
439+
* Processes and updates the list of imported elements by ensuring their uniqueness based on a generated hash.
440+
* If duplicate elements are found, their callbacks are merged.
441+
*
442+
* @return {Promise<void>} Resolves when the process of identifying and updating unique imported elements is complete.
443+
*/
444+
async getUniqueImportedElements(): Promise<ImportElement[]> {
445+
for (const element of this.importElements) {
446+
const info = await this.getElementInfo(element);
447+
const selector = XmlSlideHelper.getSelector(info.sourceElement)
448+
const eleHash = JSON.stringify(selector)
449+
const alreadyImported = this.importElements.find(
450+
(ele) => ele.info?.hash === eleHash,
451+
);
452+
if (alreadyImported) {
453+
alreadyImported.info.callback = GeneralHelper.arrayify(
454+
alreadyImported.info.callback,
455+
);
456+
const pushCallbacks = GeneralHelper.arrayify(element.callback);
457+
if(pushCallbacks.length) {
458+
alreadyImported.info.callback.push(...pushCallbacks);
459+
}
460+
} else {
461+
info.hash = eleHash;
462+
element.info = info;
463+
}
464+
}
465+
466+
return this.importElements.filter(ele => {
467+
return ele.info
468+
})
469+
}
470+
439471
/**
440472
* Imported selected elements while merging multiple element modifications
441473
* @internal
442474
*/
443475
async importedSelectedElements(): Promise<void> {
444-
await this.getUniqueImportedElements();
445-
446-
for (const element of this.importElements) {
447-
if (!element.info) {
448-
// Element has already been modified, skipping...
449-
continue;
450-
}
476+
const importElements = await this.getUniqueImportedElements();
451477

478+
for (const element of importElements) {
452479
const info = element.info;
453480
switch (info?.type) {
454481
case ElementType.Chart:
@@ -502,35 +529,6 @@ export default class HasShapes {
502529
}
503530
}
504531

505-
/**
506-
* Processes and updates the list of imported elements by ensuring their uniqueness based on a generated hash.
507-
* If duplicate elements are found, their callbacks are merged.
508-
*
509-
* @return {Promise<void>} Resolves when the process of identifying and updating unique imported elements is complete.
510-
*/
511-
async getUniqueImportedElements(): Promise<void> {
512-
for (const element of this.importElements) {
513-
const info = await this.getElementInfo(element);
514-
const eleHash =
515-
516-
XmlHelper.createHashFromXmlElement(info.sourceElement, element);
517-
518-
const alreadyImported = this.importElements.find(
519-
(ele) => ele.info?.hash === eleHash,
520-
);
521-
if (alreadyImported) {
522-
alreadyImported.callback = GeneralHelper.arrayify(
523-
alreadyImported.callback,
524-
);
525-
const pushCallbacks = GeneralHelper.arrayify(element.callback);
526-
alreadyImported.callback.push(...pushCallbacks);
527-
} else {
528-
info.hash = eleHash;
529-
element.info = info;
530-
}
531-
}
532-
}
533-
534532
/**
535533
* Gets element info
536534
* @internal

src/classes/slide.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ export class Slide extends HasShapes implements ISlide {
132132
* @returns Promise<this> - Returns the slide instance for method chaining
133133
*/
134134
mergeIntoSlideLayout(targetLayout: number | string): this {
135+
// Disabling concurring cleanup function for this slide:
136+
this.cleanupPlaceholders = false
137+
135138
this.useSlideLayout(targetLayout)
136139

137140
this.prepare(async (_) => {

0 commit comments

Comments
 (0)