@lofcz/pptxtojson 2.2.2 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/index.cjs +162 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +29 -0
- package/dist/index.js +162 -1
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -343,12 +343,41 @@ export interface SlideTransition {
|
|
|
343
343
|
direction: string | null
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
+
export type AnimationTrigger = 'onClick' | 'withPrevious' | 'afterPrevious'
|
|
347
|
+
export type AnimationClass = 'entr' | 'exit' | 'emph' | 'path' | 'verb' | 'mediacall'
|
|
348
|
+
export type SlideBuildType = 'paragraph' | 'diagram' | 'graphic' | 'oleChart'
|
|
349
|
+
|
|
350
|
+
export interface SlideAnimation {
|
|
351
|
+
/** cNvPr id of the target shape (`p:spTgt@spid`) */
|
|
352
|
+
spid: string
|
|
353
|
+
trigger: AnimationTrigger
|
|
354
|
+
class: AnimationClass
|
|
355
|
+
presetId: number
|
|
356
|
+
presetSubtype: number
|
|
357
|
+
/** Duration in milliseconds */
|
|
358
|
+
duration: number
|
|
359
|
+
/** Delay in milliseconds before the effect starts */
|
|
360
|
+
delay: number
|
|
361
|
+
/** `p:animEffect@filter` when present (fade, wipe, barn, …) */
|
|
362
|
+
filter?: string
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export interface SlideBuild {
|
|
366
|
+
spid: string
|
|
367
|
+
type: SlideBuildType
|
|
368
|
+
animBg?: boolean
|
|
369
|
+
}
|
|
370
|
+
|
|
346
371
|
export interface Slide {
|
|
347
372
|
fill: Fill
|
|
348
373
|
elements: Element[]
|
|
349
374
|
layoutElements: Element[]
|
|
350
375
|
note: string
|
|
351
376
|
transition?: SlideTransition | null
|
|
377
|
+
/** Click / withPrevious / afterPrevious effects in presenter order */
|
|
378
|
+
animations: SlideAnimation[]
|
|
379
|
+
/** `p:bldLst` paragraph / graphic / diagram builds */
|
|
380
|
+
builds: SlideBuild[]
|
|
352
381
|
}
|
|
353
382
|
|
|
354
383
|
export interface Options {
|
package/dist/index.js
CHANGED
|
@@ -9431,6 +9431,164 @@ function parseTransition(transitionNode) {
|
|
|
9431
9431
|
}
|
|
9432
9432
|
return transition;
|
|
9433
9433
|
}
|
|
9434
|
+
const PRESET_CLASSES = new Set([
|
|
9435
|
+
'entr',
|
|
9436
|
+
'exit',
|
|
9437
|
+
'emph',
|
|
9438
|
+
'path',
|
|
9439
|
+
'verb',
|
|
9440
|
+
'mediacall'
|
|
9441
|
+
]);
|
|
9442
|
+
const NODE_TYPE_TO_TRIGGER = {
|
|
9443
|
+
clickEffect: 'onClick',
|
|
9444
|
+
withEffect: 'withPrevious',
|
|
9445
|
+
afterEffect: 'afterPrevious',
|
|
9446
|
+
clickPar: 'onClick',
|
|
9447
|
+
withGroup: 'withPrevious',
|
|
9448
|
+
afterGroup: 'afterPrevious',
|
|
9449
|
+
interactiveSeq: 'onClick'
|
|
9450
|
+
};
|
|
9451
|
+
function asArray(value) {
|
|
9452
|
+
if (null == value) return [];
|
|
9453
|
+
return Array.isArray(value) ? value : [
|
|
9454
|
+
value
|
|
9455
|
+
];
|
|
9456
|
+
}
|
|
9457
|
+
function parseMs(value) {
|
|
9458
|
+
if (null == value || '' === value || 'indefinite' === value) return null;
|
|
9459
|
+
const ms = parseInt(value, 10);
|
|
9460
|
+
return Number.isFinite(ms) ? ms : null;
|
|
9461
|
+
}
|
|
9462
|
+
function findTimingNode(content) {
|
|
9463
|
+
if (!content) return null;
|
|
9464
|
+
return getTextByPathList(content, [
|
|
9465
|
+
'p:sld',
|
|
9466
|
+
'p:timing'
|
|
9467
|
+
]) || getTextByPathList(content, [
|
|
9468
|
+
'p:sld',
|
|
9469
|
+
'mc:AlternateContent',
|
|
9470
|
+
'mc:Choice',
|
|
9471
|
+
'p:timing'
|
|
9472
|
+
]) || getTextByPathList(content, [
|
|
9473
|
+
'p:sld',
|
|
9474
|
+
'mc:AlternateContent',
|
|
9475
|
+
'mc:Fallback',
|
|
9476
|
+
'p:timing'
|
|
9477
|
+
]);
|
|
9478
|
+
}
|
|
9479
|
+
function collectSpids(node, out = []) {
|
|
9480
|
+
if (!node || 'object' != typeof node) return out;
|
|
9481
|
+
const spid = node.attrs?.spid;
|
|
9482
|
+
if (null != spid && '' !== spid) out.push(String(spid));
|
|
9483
|
+
for (const key of Object.keys(node))if ('attrs' !== key && 'value' !== key) for (const child of asArray(node[key]))collectSpids(child, out);
|
|
9484
|
+
return out;
|
|
9485
|
+
}
|
|
9486
|
+
function collectDuration(node) {
|
|
9487
|
+
let found = null;
|
|
9488
|
+
const walk = (n)=>{
|
|
9489
|
+
if (!n || 'object' != typeof n) return;
|
|
9490
|
+
const ms = parseMs(n.attrs?.dur);
|
|
9491
|
+
if (null != ms && ms >= 0) found = ms;
|
|
9492
|
+
for (const key of Object.keys(n))if ('attrs' !== key && 'value' !== key) for (const child of asArray(n[key]))walk(child);
|
|
9493
|
+
};
|
|
9494
|
+
walk(node);
|
|
9495
|
+
return found;
|
|
9496
|
+
}
|
|
9497
|
+
function collectFilter(node) {
|
|
9498
|
+
let filter = '';
|
|
9499
|
+
const walk = (n)=>{
|
|
9500
|
+
if (!n || 'object' != typeof n) return;
|
|
9501
|
+
if (n.attrs?.filter) filter = n.attrs.filter;
|
|
9502
|
+
for (const key of Object.keys(n))if ('attrs' !== key && 'value' !== key) for (const child of asArray(n[key]))walk(child);
|
|
9503
|
+
};
|
|
9504
|
+
walk(node);
|
|
9505
|
+
return filter;
|
|
9506
|
+
}
|
|
9507
|
+
function collectDelay(node, inherited = 0) {
|
|
9508
|
+
const fromAttr = parseMs(node?.attrs?.delay);
|
|
9509
|
+
if (null != fromAttr && fromAttr >= 0) return fromAttr;
|
|
9510
|
+
const condRoot = node?.['p:stCondLst'];
|
|
9511
|
+
for (const cond of asArray(condRoot?.['p:cond'] || condRoot)){
|
|
9512
|
+
const fromCond = parseMs(cond?.attrs?.delay);
|
|
9513
|
+
if (null != fromCond && fromCond >= 0) return fromCond;
|
|
9514
|
+
}
|
|
9515
|
+
return inherited;
|
|
9516
|
+
}
|
|
9517
|
+
function collectEffects(node, inheritedTrigger = 'onClick', inheritedDelay = 0, results = []) {
|
|
9518
|
+
if (!node || 'object' != typeof node) return results;
|
|
9519
|
+
const attrs = node.attrs || {};
|
|
9520
|
+
const trigger = NODE_TYPE_TO_TRIGGER[attrs.nodeType] || inheritedTrigger;
|
|
9521
|
+
const delay = collectDelay(node, inheritedDelay);
|
|
9522
|
+
if (attrs.presetClass && PRESET_CLASSES.has(attrs.presetClass)) {
|
|
9523
|
+
const spids = [
|
|
9524
|
+
...new Set(collectSpids(node))
|
|
9525
|
+
];
|
|
9526
|
+
const duration = collectDuration(node);
|
|
9527
|
+
const filter = collectFilter(node);
|
|
9528
|
+
const effectTrigger = NODE_TYPE_TO_TRIGGER[attrs.nodeType] || trigger;
|
|
9529
|
+
for (const spid of spids){
|
|
9530
|
+
const animation = {
|
|
9531
|
+
spid,
|
|
9532
|
+
trigger: effectTrigger,
|
|
9533
|
+
class: attrs.presetClass,
|
|
9534
|
+
presetId: parseInt(attrs.presetID || '0', 10) || 0,
|
|
9535
|
+
presetSubtype: parseInt(attrs.presetSubtype || '0', 10) || 0,
|
|
9536
|
+
duration: null != duration ? duration : 1000,
|
|
9537
|
+
delay
|
|
9538
|
+
};
|
|
9539
|
+
if (filter) animation.filter = filter;
|
|
9540
|
+
results.push(animation);
|
|
9541
|
+
}
|
|
9542
|
+
return results;
|
|
9543
|
+
}
|
|
9544
|
+
for (const key of Object.keys(node))if ('attrs' !== key && 'value' !== key) for (const child of asArray(node[key]))collectEffects(child, trigger, delay, results);
|
|
9545
|
+
return results;
|
|
9546
|
+
}
|
|
9547
|
+
function parseBuildList(timing) {
|
|
9548
|
+
const bldLst = timing?.['p:bldLst'];
|
|
9549
|
+
if (!bldLst) return [];
|
|
9550
|
+
const kinds = [
|
|
9551
|
+
[
|
|
9552
|
+
'p:bldP',
|
|
9553
|
+
'paragraph'
|
|
9554
|
+
],
|
|
9555
|
+
[
|
|
9556
|
+
'p:bldDgm',
|
|
9557
|
+
'diagram'
|
|
9558
|
+
],
|
|
9559
|
+
[
|
|
9560
|
+
'p:bldGraphic',
|
|
9561
|
+
'graphic'
|
|
9562
|
+
],
|
|
9563
|
+
[
|
|
9564
|
+
'p:bldOleChart',
|
|
9565
|
+
'oleChart'
|
|
9566
|
+
]
|
|
9567
|
+
];
|
|
9568
|
+
const builds = [];
|
|
9569
|
+
for (const [tag, type] of kinds)for (const node of asArray(bldLst[tag])){
|
|
9570
|
+
const spid = node?.attrs?.spid;
|
|
9571
|
+
if (null == spid || '' === spid) continue;
|
|
9572
|
+
const item = {
|
|
9573
|
+
spid: String(spid),
|
|
9574
|
+
type
|
|
9575
|
+
};
|
|
9576
|
+
if (node.attrs?.animBg === '1' || node.attrs?.animBg === 'true') item.animBg = true;
|
|
9577
|
+
builds.push(item);
|
|
9578
|
+
}
|
|
9579
|
+
return builds;
|
|
9580
|
+
}
|
|
9581
|
+
function parseTiming(slideContent) {
|
|
9582
|
+
const timing = findTimingNode(slideContent);
|
|
9583
|
+
if (!timing) return {
|
|
9584
|
+
animations: [],
|
|
9585
|
+
builds: []
|
|
9586
|
+
};
|
|
9587
|
+
return {
|
|
9588
|
+
animations: collectEffects(timing),
|
|
9589
|
+
builds: parseBuildList(timing)
|
|
9590
|
+
};
|
|
9591
|
+
}
|
|
9434
9592
|
async function loadDiagramFile(warpObj, filename, transformDrawing = false) {
|
|
9435
9593
|
if (!filename) return null;
|
|
9436
9594
|
const cacheKey = `${transformDrawing ? 'drawing:' : 'xml:'}${filename}`;
|
|
@@ -9944,6 +10102,7 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
|
|
|
9944
10102
|
if (!transitionNode) transitionNode = findTransitionNode(slideLayoutContent, 'p:sldLayout');
|
|
9945
10103
|
if (!transitionNode) transitionNode = findTransitionNode(slideMasterContent, 'p:sldMaster');
|
|
9946
10104
|
const transition = parseTransition(transitionNode);
|
|
10105
|
+
const { animations, builds } = parseTiming(slideContent);
|
|
9947
10106
|
const showMasterSpOnSlide = getTextByPathList(slideContent, [
|
|
9948
10107
|
'p:sld',
|
|
9949
10108
|
'attrs',
|
|
@@ -9957,7 +10116,9 @@ async function processSingleSlide(zip, sldFileName, themeContent, defaultTextSty
|
|
|
9957
10116
|
layoutElements,
|
|
9958
10117
|
note,
|
|
9959
10118
|
transition,
|
|
9960
|
-
hideBackground
|
|
10119
|
+
hideBackground,
|
|
10120
|
+
animations,
|
|
10121
|
+
builds
|
|
9961
10122
|
};
|
|
9962
10123
|
}
|
|
9963
10124
|
function getHyperlinkFromCNvPr(cNvPr, warpObj) {
|