pptx-glimpse 3.1.0 → 3.2.0
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/dist/browser.cjs +4473 -3223
- package/dist/browser.d.cts +36 -4
- package/dist/browser.d.ts +36 -4
- package/dist/browser.js +410 -8
- package/dist/{chunk-NMAO44T7.js → chunk-CX4ZDTKK.js} +4631 -3773
- package/dist/{chunk-XGCLQP2P.js → chunk-KELC7JQK.js} +1 -1
- package/dist/{chunk-ZZKN4U5J.js → chunk-KY3SYR3V.js} +1 -1
- package/dist/cli.cjs +784 -718
- package/dist/cli.js +2 -2
- package/dist/index.cjs +784 -718
- package/dist/index.js +3 -3
- package/package.json +4 -4
package/dist/browser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
collectUsedFonts
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KY3SYR3V.js";
|
|
4
4
|
import {
|
|
5
5
|
DEFAULT_OUTPUT_WIDTH,
|
|
6
6
|
addConnector,
|
|
@@ -10,22 +10,27 @@ import {
|
|
|
10
10
|
asPartPath,
|
|
11
11
|
asRelationshipId,
|
|
12
12
|
asSourceNodeId,
|
|
13
|
+
clearParagraphProperties,
|
|
13
14
|
clearTextRunProperties,
|
|
14
15
|
convertPptxToSvg,
|
|
15
16
|
deleteShape,
|
|
16
17
|
deleteSlide,
|
|
17
18
|
duplicateSlide,
|
|
18
19
|
findShapeNodeBySourceHandle,
|
|
20
|
+
moveSlide,
|
|
19
21
|
readPptx,
|
|
20
22
|
renderPptxSourceModelToSvg,
|
|
21
23
|
replaceImageBytes,
|
|
22
24
|
replaceParagraphPlainText,
|
|
23
25
|
replaceTextRunPlainText,
|
|
26
|
+
setParagraphProperties,
|
|
27
|
+
setShapeFill,
|
|
28
|
+
setShapeOutline,
|
|
24
29
|
setTextRunProperties,
|
|
25
30
|
unsafeBrandAssertion,
|
|
26
31
|
updateShapeTransform,
|
|
27
32
|
writePptx
|
|
28
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-CX4ZDTKK.js";
|
|
29
34
|
import {
|
|
30
35
|
DEFAULT_FONT_MAPPING,
|
|
31
36
|
clearFontCache,
|
|
@@ -2542,6 +2547,23 @@ var pptxTextBodySchema = new Schema({
|
|
|
2542
2547
|
}
|
|
2543
2548
|
}
|
|
2544
2549
|
});
|
|
2550
|
+
var EDITABLE_PARAGRAPH_PROPERTIES = [
|
|
2551
|
+
"align",
|
|
2552
|
+
"level",
|
|
2553
|
+
"bullet"
|
|
2554
|
+
];
|
|
2555
|
+
var AUTO_NUM_SCHEMES = [
|
|
2556
|
+
"arabicPeriod",
|
|
2557
|
+
"arabicParenR",
|
|
2558
|
+
"romanUcPeriod",
|
|
2559
|
+
"romanLcPeriod",
|
|
2560
|
+
"alphaUcPeriod",
|
|
2561
|
+
"alphaLcPeriod",
|
|
2562
|
+
"alphaLcParenR",
|
|
2563
|
+
"alphaUcParenR",
|
|
2564
|
+
"arabicPlain"
|
|
2565
|
+
];
|
|
2566
|
+
var AUTO_NUM_SCHEME_SET = new Set(AUTO_NUM_SCHEMES);
|
|
2545
2567
|
function textBodyToProseMirrorDocJson(textBody) {
|
|
2546
2568
|
assertSupportedTextBody(textBody);
|
|
2547
2569
|
return {
|
|
@@ -2607,8 +2629,12 @@ function proseMirrorDocJsonToEditorCommands(originalTextBody, docJson) {
|
|
|
2607
2629
|
(editedParagraph, paragraphIndex) => {
|
|
2608
2630
|
const originalParagraph = originalTextBody.paragraphs[paragraphIndex];
|
|
2609
2631
|
if (originalParagraph === void 0) return [];
|
|
2632
|
+
const paragraphPropertyCommands = paragraphPropertiesToEditorCommands(
|
|
2633
|
+
originalParagraph,
|
|
2634
|
+
editedParagraph
|
|
2635
|
+
);
|
|
2610
2636
|
if (paragraphRunHandlesMatch(originalParagraph, editedParagraph)) {
|
|
2611
|
-
|
|
2637
|
+
const textRunCommands = editedParagraph.runs.flatMap(
|
|
2612
2638
|
(editedRun, runIndex) => {
|
|
2613
2639
|
const originalRun = originalParagraph.runs[runIndex];
|
|
2614
2640
|
if (originalRun === void 0 || editedRun.text === originalRun.text) return [];
|
|
@@ -2626,6 +2652,7 @@ function proseMirrorDocJsonToEditorCommands(originalTextBody, docJson) {
|
|
|
2626
2652
|
];
|
|
2627
2653
|
}
|
|
2628
2654
|
);
|
|
2655
|
+
return [...paragraphPropertyCommands, ...textRunCommands];
|
|
2629
2656
|
}
|
|
2630
2657
|
if (editedParagraph.handle === void 0) {
|
|
2631
2658
|
throw new Error(
|
|
@@ -2633,6 +2660,7 @@ function proseMirrorDocJsonToEditorCommands(originalTextBody, docJson) {
|
|
|
2633
2660
|
);
|
|
2634
2661
|
}
|
|
2635
2662
|
return [
|
|
2663
|
+
...paragraphPropertyCommands,
|
|
2636
2664
|
{
|
|
2637
2665
|
kind: "replaceParagraphPlainText",
|
|
2638
2666
|
handle: editedParagraph.handle,
|
|
@@ -2648,10 +2676,14 @@ function validateProseMirrorDocJson(docJson) {
|
|
|
2648
2676
|
}
|
|
2649
2677
|
function paragraphJsonToSourceParagraph(originalParagraph, paragraphJson) {
|
|
2650
2678
|
const groups = collectRunGroups(paragraphJson, originalParagraph);
|
|
2679
|
+
const properties = paragraphPropertiesFromJson(
|
|
2680
|
+
originalParagraph?.properties,
|
|
2681
|
+
paragraphJson.attrs?.properties
|
|
2682
|
+
);
|
|
2651
2683
|
return {
|
|
2652
|
-
...originalParagraph ?? {},
|
|
2653
2684
|
runs: groups.map(sourceRunFromGroup),
|
|
2654
|
-
...originalParagraph?.
|
|
2685
|
+
...originalParagraph?.rawSidecars !== void 0 ? { rawSidecars: originalParagraph.rawSidecars } : {},
|
|
2686
|
+
...properties !== void 0 ? { properties } : {},
|
|
2655
2687
|
...originalParagraph?.handle !== void 0 ? { handle: originalParagraph.handle } : sourceHandleFromUnknown(paragraphJson.attrs?.handle) !== void 0 ? { handle: sourceHandleFromUnknown(paragraphJson.attrs?.handle) } : {}
|
|
2656
2688
|
};
|
|
2657
2689
|
}
|
|
@@ -2701,6 +2733,107 @@ function paragraphRunHandlesMatch(originalParagraph, editedParagraph) {
|
|
|
2701
2733
|
function paragraphPlainText(paragraph) {
|
|
2702
2734
|
return paragraph.runs.map((run) => run.text).join("");
|
|
2703
2735
|
}
|
|
2736
|
+
function paragraphPropertiesToEditorCommands(originalParagraph, editedParagraph) {
|
|
2737
|
+
if (editedParagraph.handle === void 0) {
|
|
2738
|
+
if (paragraphEditablePropertiesEqual(originalParagraph.properties, editedParagraph.properties)) {
|
|
2739
|
+
return [];
|
|
2740
|
+
}
|
|
2741
|
+
throw new Error("proseMirrorDocJsonToEditorCommands: changed paragraph has no source handle");
|
|
2742
|
+
}
|
|
2743
|
+
const set = {};
|
|
2744
|
+
const clear = [];
|
|
2745
|
+
if (!stableValueEqual(originalParagraph.properties?.align, editedParagraph.properties?.align)) {
|
|
2746
|
+
if (editedParagraph.properties?.align === void 0) clear.push("align");
|
|
2747
|
+
else set.align = editedParagraph.properties.align;
|
|
2748
|
+
}
|
|
2749
|
+
if (!stableValueEqual(originalParagraph.properties?.level, editedParagraph.properties?.level)) {
|
|
2750
|
+
if (editedParagraph.properties?.level === void 0) clear.push("level");
|
|
2751
|
+
else set.level = editedParagraph.properties.level;
|
|
2752
|
+
}
|
|
2753
|
+
if (!stableValueEqual(originalParagraph.properties?.bullet, editedParagraph.properties?.bullet)) {
|
|
2754
|
+
if (editedParagraph.properties?.bullet === void 0) clear.push("bullet");
|
|
2755
|
+
else set.bullet = editedParagraph.properties.bullet;
|
|
2756
|
+
}
|
|
2757
|
+
const commands = [];
|
|
2758
|
+
if (clear.length > 0) {
|
|
2759
|
+
commands.push({
|
|
2760
|
+
kind: "clearParagraphProperties",
|
|
2761
|
+
handle: editedParagraph.handle,
|
|
2762
|
+
properties: clear
|
|
2763
|
+
});
|
|
2764
|
+
}
|
|
2765
|
+
if (Object.keys(set).length > 0) {
|
|
2766
|
+
commands.push({
|
|
2767
|
+
kind: "setParagraphProperties",
|
|
2768
|
+
handle: editedParagraph.handle,
|
|
2769
|
+
properties: set
|
|
2770
|
+
});
|
|
2771
|
+
}
|
|
2772
|
+
return commands;
|
|
2773
|
+
}
|
|
2774
|
+
function paragraphPropertiesFromJson(originalProperties, value) {
|
|
2775
|
+
if (!isRecord(value)) return originalProperties;
|
|
2776
|
+
const next = { ...originalProperties ?? {} };
|
|
2777
|
+
for (const property of EDITABLE_PARAGRAPH_PROPERTIES) {
|
|
2778
|
+
if (!Object.prototype.hasOwnProperty.call(value, property)) {
|
|
2779
|
+
delete next[property];
|
|
2780
|
+
continue;
|
|
2781
|
+
}
|
|
2782
|
+
const propertyValue = value[property];
|
|
2783
|
+
if (propertyValue === null || propertyValue === void 0) {
|
|
2784
|
+
delete next[property];
|
|
2785
|
+
} else if (property === "align") {
|
|
2786
|
+
next.align = paragraphAlignFromUnknown(propertyValue);
|
|
2787
|
+
} else if (property === "level") {
|
|
2788
|
+
next.level = paragraphLevelFromUnknown(propertyValue);
|
|
2789
|
+
} else {
|
|
2790
|
+
next.bullet = paragraphBulletFromUnknown(propertyValue);
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
return Object.keys(next).length > 0 ? next : void 0;
|
|
2794
|
+
}
|
|
2795
|
+
function paragraphAlignFromUnknown(value) {
|
|
2796
|
+
if (value === "left" || value === "center" || value === "right" || value === "justify") {
|
|
2797
|
+
return value;
|
|
2798
|
+
}
|
|
2799
|
+
throw new Error("ProseMirror paragraph properties align must be left, center, right, or justify");
|
|
2800
|
+
}
|
|
2801
|
+
function paragraphLevelFromUnknown(value) {
|
|
2802
|
+
if (typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 8) {
|
|
2803
|
+
return value;
|
|
2804
|
+
}
|
|
2805
|
+
throw new Error("ProseMirror paragraph properties level must be an integer from 0 to 8");
|
|
2806
|
+
}
|
|
2807
|
+
function paragraphBulletFromUnknown(value) {
|
|
2808
|
+
if (!isRecord(value) || typeof value.type !== "string") {
|
|
2809
|
+
throw new Error("ProseMirror paragraph properties bullet must be an object");
|
|
2810
|
+
}
|
|
2811
|
+
if (value.type === "none") return { type: "none" };
|
|
2812
|
+
if (value.type === "char") {
|
|
2813
|
+
if (typeof value.char !== "string" || value.char.length === 0) {
|
|
2814
|
+
throw new Error("ProseMirror paragraph properties bullet.char must be a non-empty string");
|
|
2815
|
+
}
|
|
2816
|
+
return { type: "char", char: value.char };
|
|
2817
|
+
}
|
|
2818
|
+
if (value.type === "autoNum") {
|
|
2819
|
+
if (!isAutoNumScheme(value.scheme)) {
|
|
2820
|
+
throw new Error("ProseMirror paragraph properties bullet.scheme is unsupported");
|
|
2821
|
+
}
|
|
2822
|
+
if (typeof value.startAt !== "number" || !Number.isInteger(value.startAt) || value.startAt < 1) {
|
|
2823
|
+
throw new Error("ProseMirror paragraph properties bullet.startAt must be positive");
|
|
2824
|
+
}
|
|
2825
|
+
return { type: "autoNum", scheme: value.scheme, startAt: value.startAt };
|
|
2826
|
+
}
|
|
2827
|
+
throw new Error("ProseMirror paragraph properties bullet.type is unsupported");
|
|
2828
|
+
}
|
|
2829
|
+
function isAutoNumScheme(value) {
|
|
2830
|
+
return typeof value === "string" && AUTO_NUM_SCHEME_SET.has(value);
|
|
2831
|
+
}
|
|
2832
|
+
function paragraphEditablePropertiesEqual(left, right) {
|
|
2833
|
+
return EDITABLE_PARAGRAPH_PROPERTIES.every(
|
|
2834
|
+
(property) => stableValueEqual(left?.[property], right?.[property])
|
|
2835
|
+
);
|
|
2836
|
+
}
|
|
2704
2837
|
function parsePptxTextBodyProseMirrorDocJson(value) {
|
|
2705
2838
|
if (!isRecord(value) || value.type !== "doc") {
|
|
2706
2839
|
throw new Error("ProseMirror text body doc JSON must be a doc node");
|
|
@@ -2708,7 +2841,7 @@ function parsePptxTextBodyProseMirrorDocJson(value) {
|
|
|
2708
2841
|
if (value.content !== void 0 && readArray(value.content, isParagraphJson) === void 0) {
|
|
2709
2842
|
throw new Error("ProseMirror text body doc JSON content must contain paragraph nodes");
|
|
2710
2843
|
}
|
|
2711
|
-
const content = readArray(value.content, isParagraphJson);
|
|
2844
|
+
const content = readArray(value.content, isParagraphJson)?.map(normalizeParagraphJson);
|
|
2712
2845
|
return {
|
|
2713
2846
|
type: "doc",
|
|
2714
2847
|
...content !== void 0 ? { content } : {}
|
|
@@ -2721,6 +2854,13 @@ function isParagraphJson(value) {
|
|
|
2721
2854
|
}
|
|
2722
2855
|
return value.attrs === void 0 || isRecord(value.attrs);
|
|
2723
2856
|
}
|
|
2857
|
+
function normalizeParagraphJson(value) {
|
|
2858
|
+
return {
|
|
2859
|
+
type: "paragraph",
|
|
2860
|
+
...value.attrs !== void 0 ? { attrs: value.attrs } : {},
|
|
2861
|
+
...value.content !== void 0 ? { content: value.content } : {}
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2724
2864
|
function isTextJson(value) {
|
|
2725
2865
|
if (!isRecord(value) || value.type !== "text" || typeof value.text !== "string") return false;
|
|
2726
2866
|
if (value.marks === void 0) return true;
|
|
@@ -2758,6 +2898,22 @@ function sourceHandleKey(handle) {
|
|
|
2758
2898
|
handle.orderingSlot ?? ""
|
|
2759
2899
|
].join("\0");
|
|
2760
2900
|
}
|
|
2901
|
+
function stableValueEqual(left, right) {
|
|
2902
|
+
if (Object.is(left, right)) return true;
|
|
2903
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
2904
|
+
if (!Array.isArray(left) || !Array.isArray(right)) return false;
|
|
2905
|
+
if (left.length !== right.length) return false;
|
|
2906
|
+
return left.every((value, index) => stableValueEqual(value, right[index]));
|
|
2907
|
+
}
|
|
2908
|
+
if (isRecord(left) || isRecord(right)) {
|
|
2909
|
+
if (!isRecord(left) || !isRecord(right)) return false;
|
|
2910
|
+
const leftKeys = Object.keys(left).sort();
|
|
2911
|
+
const rightKeys = Object.keys(right).sort();
|
|
2912
|
+
if (!stableValueEqual(leftKeys, rightKeys)) return false;
|
|
2913
|
+
return leftKeys.every((key) => stableValueEqual(left[key], right[key]));
|
|
2914
|
+
}
|
|
2915
|
+
return false;
|
|
2916
|
+
}
|
|
2761
2917
|
function isRecord(value) {
|
|
2762
2918
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2763
2919
|
}
|
|
@@ -2871,12 +3027,20 @@ function applyCommandToDocument(document, command) {
|
|
|
2871
3027
|
return setTextRunPropertiesCommand(document, command);
|
|
2872
3028
|
case "clearTextRunProperties":
|
|
2873
3029
|
return clearTextRunPropertiesCommand(document, command);
|
|
3030
|
+
case "setParagraphProperties":
|
|
3031
|
+
return setParagraphPropertiesCommand(document, command);
|
|
3032
|
+
case "clearParagraphProperties":
|
|
3033
|
+
return clearParagraphPropertiesCommand(document, command);
|
|
2874
3034
|
case "moveShape":
|
|
2875
3035
|
return moveShape(document, command);
|
|
2876
3036
|
case "resizeShape":
|
|
2877
3037
|
return resizeShape(document, command);
|
|
2878
3038
|
case "setShapeTransform":
|
|
2879
3039
|
return setShapeTransform(document, command);
|
|
3040
|
+
case "setShapeFill":
|
|
3041
|
+
return setShapeFillCommand(document, command);
|
|
3042
|
+
case "setShapeOutline":
|
|
3043
|
+
return setShapeOutlineCommand(document, command);
|
|
2880
3044
|
case "addTextBox":
|
|
2881
3045
|
return addTextBoxCommand(document, command);
|
|
2882
3046
|
case "addConnector":
|
|
@@ -2889,6 +3053,8 @@ function applyCommandToDocument(document, command) {
|
|
|
2889
3053
|
return addEmptySlideFromLayout(document, command);
|
|
2890
3054
|
case "duplicateSlide":
|
|
2891
3055
|
return duplicateSlide(document, command.handle);
|
|
3056
|
+
case "moveSlide":
|
|
3057
|
+
return moveSlide(document, command.handle, command);
|
|
2892
3058
|
case "deleteSlide":
|
|
2893
3059
|
return deleteSlide(document, command.handle);
|
|
2894
3060
|
}
|
|
@@ -2961,6 +3127,22 @@ function clearTextRunPropertiesCommand(document, command) {
|
|
|
2961
3127
|
}
|
|
2962
3128
|
return clearTextRunProperties(document, command.handle, command.properties);
|
|
2963
3129
|
}
|
|
3130
|
+
function setParagraphPropertiesCommand(document, command) {
|
|
3131
|
+
requireNonEmptyParagraphPropertySet(command.properties, "setParagraphProperties");
|
|
3132
|
+
validateParagraphPropertySet(command.properties, "setParagraphProperties");
|
|
3133
|
+
return setParagraphProperties(document, command.handle, command.properties);
|
|
3134
|
+
}
|
|
3135
|
+
function clearParagraphPropertiesCommand(document, command) {
|
|
3136
|
+
if (command.properties.length === 0) {
|
|
3137
|
+
throw new Error("clearParagraphProperties: properties must contain at least one property name");
|
|
3138
|
+
}
|
|
3139
|
+
for (const property of command.properties) {
|
|
3140
|
+
if (!EDITABLE_PARAGRAPH_PROPERTY_SET.has(property)) {
|
|
3141
|
+
throw new Error(`clearParagraphProperties: unsupported paragraph property '${property}'`);
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
return clearParagraphProperties(document, command.handle, command.properties);
|
|
3145
|
+
}
|
|
2964
3146
|
function moveShape(document, command) {
|
|
2965
3147
|
requireFiniteEmu(command.offsetX, "moveShape", "offsetX");
|
|
2966
3148
|
requireFiniteEmu(command.offsetY, "moveShape", "offsetY");
|
|
@@ -2996,6 +3178,14 @@ function setShapeTransform(document, command) {
|
|
|
2996
3178
|
height: command.height
|
|
2997
3179
|
});
|
|
2998
3180
|
}
|
|
3181
|
+
function setShapeFillCommand(document, command) {
|
|
3182
|
+
validateShapeFill(command.fill, "setShapeFill");
|
|
3183
|
+
return setShapeFill(document, command.handle, command.fill);
|
|
3184
|
+
}
|
|
3185
|
+
function setShapeOutlineCommand(document, command) {
|
|
3186
|
+
validateShapeOutline(command.outline, "setShapeOutline");
|
|
3187
|
+
return setShapeOutline(document, command.handle, command.outline);
|
|
3188
|
+
}
|
|
2999
3189
|
var EDITABLE_TEXT_RUN_PROPERTIES = [
|
|
3000
3190
|
"bold",
|
|
3001
3191
|
"italic",
|
|
@@ -3005,6 +3195,24 @@ var EDITABLE_TEXT_RUN_PROPERTIES = [
|
|
|
3005
3195
|
"typeface"
|
|
3006
3196
|
];
|
|
3007
3197
|
var EDITABLE_TEXT_RUN_PROPERTY_SET = new Set(EDITABLE_TEXT_RUN_PROPERTIES);
|
|
3198
|
+
var EDITABLE_PARAGRAPH_PROPERTIES2 = [
|
|
3199
|
+
"align",
|
|
3200
|
+
"level",
|
|
3201
|
+
"bullet"
|
|
3202
|
+
];
|
|
3203
|
+
var EDITABLE_PARAGRAPH_PROPERTY_SET = new Set(EDITABLE_PARAGRAPH_PROPERTIES2);
|
|
3204
|
+
var PARAGRAPH_ALIGN_VALUES = /* @__PURE__ */ new Set(["left", "center", "right", "justify"]);
|
|
3205
|
+
var AUTO_NUM_SCHEMES2 = /* @__PURE__ */ new Set([
|
|
3206
|
+
"arabicPeriod",
|
|
3207
|
+
"arabicParenR",
|
|
3208
|
+
"romanUcPeriod",
|
|
3209
|
+
"romanLcPeriod",
|
|
3210
|
+
"alphaUcPeriod",
|
|
3211
|
+
"alphaLcPeriod",
|
|
3212
|
+
"alphaLcParenR",
|
|
3213
|
+
"alphaUcParenR",
|
|
3214
|
+
"arabicPlain"
|
|
3215
|
+
]);
|
|
3008
3216
|
function requireNonEmptyPropertySet(properties, commandName) {
|
|
3009
3217
|
if (Object.values(properties).every((value) => value === void 0)) {
|
|
3010
3218
|
throw new Error(`${commandName}: properties must contain at least one defined property`);
|
|
@@ -3034,11 +3242,72 @@ function validateTextRunPropertySet(properties, commandName) {
|
|
|
3034
3242
|
}
|
|
3035
3243
|
}
|
|
3036
3244
|
}
|
|
3245
|
+
function requireNonEmptyParagraphPropertySet(properties, commandName) {
|
|
3246
|
+
if (Object.values(properties).every((value) => value === void 0)) {
|
|
3247
|
+
throw new Error(`${commandName}: properties must contain at least one defined property`);
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
function validateParagraphPropertySet(properties, commandName) {
|
|
3251
|
+
for (const property of Object.keys(properties)) {
|
|
3252
|
+
if (!EDITABLE_PARAGRAPH_PROPERTY_SET.has(property)) {
|
|
3253
|
+
throw new Error(`${commandName}: unsupported paragraph property '${property}'`);
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
if (properties.align !== void 0 && !PARAGRAPH_ALIGN_VALUES.has(properties.align)) {
|
|
3257
|
+
throw new Error(`${commandName}: align must be left, center, right, or justify`);
|
|
3258
|
+
}
|
|
3259
|
+
if (properties.level !== void 0 && (!Number.isInteger(properties.level) || properties.level < 0 || properties.level > 8)) {
|
|
3260
|
+
throw new Error(`${commandName}: level must be an integer from 0 to 8`);
|
|
3261
|
+
}
|
|
3262
|
+
if (properties.bullet !== void 0) {
|
|
3263
|
+
validateParagraphBullet(properties.bullet, commandName);
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
function validateParagraphBullet(bullet, commandName) {
|
|
3267
|
+
if (bullet.type === "none") return;
|
|
3268
|
+
if (bullet.type === "char") {
|
|
3269
|
+
if (bullet.char.length === 0) {
|
|
3270
|
+
throw new Error(`${commandName}: bullet.char must be a non-empty string`);
|
|
3271
|
+
}
|
|
3272
|
+
return;
|
|
3273
|
+
}
|
|
3274
|
+
if (bullet.type === "autoNum") {
|
|
3275
|
+
if (!AUTO_NUM_SCHEMES2.has(bullet.scheme)) {
|
|
3276
|
+
throw new Error(`${commandName}: unsupported bullet auto-numbering scheme`);
|
|
3277
|
+
}
|
|
3278
|
+
if (!Number.isInteger(bullet.startAt) || bullet.startAt < 1) {
|
|
3279
|
+
throw new Error(`${commandName}: bullet.startAt must be a positive integer`);
|
|
3280
|
+
}
|
|
3281
|
+
return;
|
|
3282
|
+
}
|
|
3283
|
+
throw new Error(`${commandName}: unsupported bullet type`);
|
|
3284
|
+
}
|
|
3037
3285
|
function requireBooleanOrUndefined(value, commandName, fieldName) {
|
|
3038
3286
|
if (value !== void 0 && typeof value !== "boolean") {
|
|
3039
3287
|
throw new Error(`${commandName}: ${fieldName} must be a boolean value`);
|
|
3040
3288
|
}
|
|
3041
3289
|
}
|
|
3290
|
+
function validateShapeOutline(outline, commandName) {
|
|
3291
|
+
if (outline.width === void 0 && outline.fill === void 0) {
|
|
3292
|
+
throw new Error(`${commandName}: outline must set width or fill`);
|
|
3293
|
+
}
|
|
3294
|
+
if (outline.width !== void 0) {
|
|
3295
|
+
requirePositiveFiniteEmu(outline.width, commandName, "width");
|
|
3296
|
+
}
|
|
3297
|
+
if (outline.fill !== void 0) validateShapeFill(outline.fill, commandName);
|
|
3298
|
+
}
|
|
3299
|
+
function validateShapeFill(fill, commandName) {
|
|
3300
|
+
if (fill.kind === "none") return;
|
|
3301
|
+
if (fill.kind !== "solid") {
|
|
3302
|
+
throw new Error(`${commandName}: only solid and none fills are supported`);
|
|
3303
|
+
}
|
|
3304
|
+
if (fill.color.kind !== "srgb") {
|
|
3305
|
+
throw new Error(`${commandName}: only srgb solid fill colors are supported`);
|
|
3306
|
+
}
|
|
3307
|
+
if (!/^[0-9A-Fa-f]{6}$/.test(fill.color.hex)) {
|
|
3308
|
+
throw new Error(`${commandName}: color.hex must be a 6-digit hex value`);
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3042
3311
|
function requireEditableShapeTransform(document, handle, commandName) {
|
|
3043
3312
|
const shape = findShapeNodeBySourceHandle(document, handle);
|
|
3044
3313
|
if (shape === void 0) {
|
|
@@ -3067,8 +3336,12 @@ function normalizeEditorEdits(document) {
|
|
|
3067
3336
|
if (edits === void 0) return document;
|
|
3068
3337
|
const seenTextRuns = /* @__PURE__ */ new Set();
|
|
3069
3338
|
const seenTextRunProperties = /* @__PURE__ */ new Map();
|
|
3339
|
+
const seenParagraphProperties = /* @__PURE__ */ new Map();
|
|
3070
3340
|
const seenParagraphs = /* @__PURE__ */ new Set();
|
|
3071
3341
|
const seenShapeTransforms = /* @__PURE__ */ new Set();
|
|
3342
|
+
const seenShapeFills = /* @__PURE__ */ new Set();
|
|
3343
|
+
const seenShapeOutlineProperties = /* @__PURE__ */ new Map();
|
|
3344
|
+
const normalizedShapeOutlineEdits = /* @__PURE__ */ new Map();
|
|
3072
3345
|
const normalizedReversed = [];
|
|
3073
3346
|
let changed = false;
|
|
3074
3347
|
for (let index = edits.length - 1; index >= 0; index -= 1) {
|
|
@@ -3101,6 +3374,16 @@ function normalizeEditorEdits(document) {
|
|
|
3101
3374
|
normalizedReversed.push(normalized);
|
|
3102
3375
|
continue;
|
|
3103
3376
|
}
|
|
3377
|
+
if (edit.kind === "updateParagraphProperties") {
|
|
3378
|
+
const normalized = normalizeParagraphPropertiesEdit(edit, seenParagraphProperties);
|
|
3379
|
+
if (normalized === void 0) {
|
|
3380
|
+
changed = true;
|
|
3381
|
+
continue;
|
|
3382
|
+
}
|
|
3383
|
+
if (!editorEditsEqual(normalized, edit)) changed = true;
|
|
3384
|
+
normalizedReversed.push(normalized);
|
|
3385
|
+
continue;
|
|
3386
|
+
}
|
|
3104
3387
|
if (edit.kind === "replaceParagraphPlainText") {
|
|
3105
3388
|
const key = editHandleNodeKey(edit);
|
|
3106
3389
|
if (seenParagraphs.has(key)) {
|
|
@@ -3117,6 +3400,32 @@ function normalizeEditorEdits(document) {
|
|
|
3117
3400
|
}
|
|
3118
3401
|
seenShapeTransforms.add(key);
|
|
3119
3402
|
}
|
|
3403
|
+
if (edit.kind === "updateShapeFill") {
|
|
3404
|
+
const key = editHandleNodeKey(edit);
|
|
3405
|
+
if (seenShapeFills.has(key)) {
|
|
3406
|
+
changed = true;
|
|
3407
|
+
continue;
|
|
3408
|
+
}
|
|
3409
|
+
seenShapeFills.add(key);
|
|
3410
|
+
}
|
|
3411
|
+
if (edit.kind === "updateShapeOutline") {
|
|
3412
|
+
const normalized = normalizeShapeOutlineEdit(
|
|
3413
|
+
edit,
|
|
3414
|
+
seenShapeOutlineProperties,
|
|
3415
|
+
normalizedShapeOutlineEdits
|
|
3416
|
+
);
|
|
3417
|
+
if (normalized === void 0) {
|
|
3418
|
+
changed = true;
|
|
3419
|
+
continue;
|
|
3420
|
+
}
|
|
3421
|
+
if (normalized.merged) {
|
|
3422
|
+
changed = true;
|
|
3423
|
+
continue;
|
|
3424
|
+
}
|
|
3425
|
+
if (!editorEditsEqual(normalized.edit, edit)) changed = true;
|
|
3426
|
+
normalizedReversed.push(normalized.edit);
|
|
3427
|
+
continue;
|
|
3428
|
+
}
|
|
3120
3429
|
normalizedReversed.push(edit);
|
|
3121
3430
|
}
|
|
3122
3431
|
if (!changed && normalizedReversed.length === edits.length) return document;
|
|
@@ -3193,6 +3502,67 @@ function normalizeTextRunPropertiesEdit(edit, seenTextRunProperties) {
|
|
|
3193
3502
|
};
|
|
3194
3503
|
return normalized;
|
|
3195
3504
|
}
|
|
3505
|
+
function normalizeParagraphPropertiesEdit(edit, seenParagraphProperties) {
|
|
3506
|
+
const key = editHandleNodeKey(edit);
|
|
3507
|
+
let seenProperties = seenParagraphProperties.get(key);
|
|
3508
|
+
if (seenProperties === void 0) {
|
|
3509
|
+
seenProperties = /* @__PURE__ */ new Set();
|
|
3510
|
+
seenParagraphProperties.set(key, seenProperties);
|
|
3511
|
+
}
|
|
3512
|
+
const set = {};
|
|
3513
|
+
if (edit.set?.align !== void 0 && !seenProperties.has("align")) {
|
|
3514
|
+
seenProperties.add("align");
|
|
3515
|
+
set.align = edit.set.align;
|
|
3516
|
+
}
|
|
3517
|
+
if (edit.set?.level !== void 0 && !seenProperties.has("level")) {
|
|
3518
|
+
seenProperties.add("level");
|
|
3519
|
+
set.level = edit.set.level;
|
|
3520
|
+
}
|
|
3521
|
+
if (edit.set?.bullet !== void 0 && !seenProperties.has("bullet")) {
|
|
3522
|
+
seenProperties.add("bullet");
|
|
3523
|
+
set.bullet = edit.set.bullet;
|
|
3524
|
+
}
|
|
3525
|
+
const clear = (edit.clear ?? []).filter((property) => !seenProperties.has(property));
|
|
3526
|
+
for (const property of clear) seenProperties.add(property);
|
|
3527
|
+
if (clear.length === 0 && Object.keys(set).length === 0) return void 0;
|
|
3528
|
+
const normalized = {
|
|
3529
|
+
kind: "updateParagraphProperties",
|
|
3530
|
+
handle: edit.handle,
|
|
3531
|
+
...Object.keys(set).length > 0 ? { set } : {},
|
|
3532
|
+
...clear.length > 0 ? { clear } : {}
|
|
3533
|
+
};
|
|
3534
|
+
return normalized;
|
|
3535
|
+
}
|
|
3536
|
+
function normalizeShapeOutlineEdit(edit, seenShapeOutlineProperties, normalizedShapeOutlineEdits) {
|
|
3537
|
+
const key = editHandleNodeKey(edit);
|
|
3538
|
+
let seenProperties = seenShapeOutlineProperties.get(key);
|
|
3539
|
+
if (seenProperties === void 0) {
|
|
3540
|
+
seenProperties = /* @__PURE__ */ new Set();
|
|
3541
|
+
seenShapeOutlineProperties.set(key, seenProperties);
|
|
3542
|
+
}
|
|
3543
|
+
const outline = {};
|
|
3544
|
+
if (edit.outline.width !== void 0 && !seenProperties.has("width")) {
|
|
3545
|
+
seenProperties.add("width");
|
|
3546
|
+
outline.width = edit.outline.width;
|
|
3547
|
+
}
|
|
3548
|
+
if (edit.outline.fill !== void 0 && !seenProperties.has("fill")) {
|
|
3549
|
+
seenProperties.add("fill");
|
|
3550
|
+
outline.fill = edit.outline.fill;
|
|
3551
|
+
}
|
|
3552
|
+
if (Object.keys(outline).length === 0) return void 0;
|
|
3553
|
+
const existing = normalizedShapeOutlineEdits.get(key);
|
|
3554
|
+
if (existing !== void 0) {
|
|
3555
|
+
existing.outline = { ...outline, ...existing.outline };
|
|
3556
|
+
return { merged: true };
|
|
3557
|
+
}
|
|
3558
|
+
const normalized = {
|
|
3559
|
+
kind: "updateShapeOutline",
|
|
3560
|
+
handle: edit.handle,
|
|
3561
|
+
outline
|
|
3562
|
+
};
|
|
3563
|
+
normalizedShapeOutlineEdits.set(key, normalized);
|
|
3564
|
+
return { edit: normalized, merged: false };
|
|
3565
|
+
}
|
|
3196
3566
|
|
|
3197
3567
|
// src/browser-editor.ts
|
|
3198
3568
|
var EMU_PER_INCH = 914400;
|
|
@@ -3205,6 +3575,12 @@ var DEFAULT_TEXT_BOX_BOUNDS_PX = {
|
|
|
3205
3575
|
height: 72
|
|
3206
3576
|
};
|
|
3207
3577
|
var DEFAULT_TEXT_BOX_TEXT = "New text box";
|
|
3578
|
+
var DEFAULT_CONNECTOR_BOUNDS_PX = {
|
|
3579
|
+
x: 144,
|
|
3580
|
+
y: 144,
|
|
3581
|
+
width: 288,
|
|
3582
|
+
height: 96
|
|
3583
|
+
};
|
|
3208
3584
|
var IMAGE_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
3209
3585
|
var IMAGE_ACCEPT_BY_CONTENT_TYPE = {
|
|
3210
3586
|
"image/png": "image/png,.png",
|
|
@@ -3302,6 +3678,32 @@ var BrowserPptxEditorSession = class _BrowserPptxEditorSession {
|
|
|
3302
3678
|
await this.renderCurrentSlides();
|
|
3303
3679
|
return this.response(result.warnings);
|
|
3304
3680
|
}
|
|
3681
|
+
async addConnector(slideNumber = 1, options = {}) {
|
|
3682
|
+
const slide = this.#session.document.slides[slideNumber - 1];
|
|
3683
|
+
if (slide?.handle === void 0) {
|
|
3684
|
+
throw new Error("addConnector: slide handle was not found in PptxSourceModel source");
|
|
3685
|
+
}
|
|
3686
|
+
const existingShapeKeys = new Set(slide.shapes.map(shapeSourceKey));
|
|
3687
|
+
const result = this.#session.apply({
|
|
3688
|
+
kind: "addConnector",
|
|
3689
|
+
slideHandle: slide.handle,
|
|
3690
|
+
preset: "straightConnector1",
|
|
3691
|
+
offsetX: pxToEmu(options.x ?? DEFAULT_CONNECTOR_BOUNDS_PX.x),
|
|
3692
|
+
offsetY: pxToEmu(options.y ?? DEFAULT_CONNECTOR_BOUNDS_PX.y),
|
|
3693
|
+
width: pxToEmu(options.width ?? DEFAULT_CONNECTOR_BOUNDS_PX.width),
|
|
3694
|
+
height: pxToEmu(options.height ?? DEFAULT_CONNECTOR_BOUNDS_PX.height),
|
|
3695
|
+
outline: {
|
|
3696
|
+
tailEnd: { type: "triangle", width: "med", length: "med" }
|
|
3697
|
+
},
|
|
3698
|
+
...options.name !== void 0 ? { name: options.name } : {}
|
|
3699
|
+
});
|
|
3700
|
+
if (!result.ok) {
|
|
3701
|
+
throw new Error(result.message);
|
|
3702
|
+
}
|
|
3703
|
+
this.#selectNewShape(slideNumber, existingShapeKeys);
|
|
3704
|
+
await this.renderCurrentSlides();
|
|
3705
|
+
return this.response(result.warnings);
|
|
3706
|
+
}
|
|
3305
3707
|
async deleteShape(handle) {
|
|
3306
3708
|
const result = this.#session.apply({ kind: "deleteShape", handle });
|
|
3307
3709
|
if (!result.ok) {
|
|
@@ -3414,10 +3816,10 @@ function isEditableTransformShape(shape) {
|
|
|
3414
3816
|
return !shape.rawSidecars?.some((sidecar) => sidecar.node.name === "mc:AlternateContent");
|
|
3415
3817
|
}
|
|
3416
3818
|
function isDeletableShape(shape, slideShapes) {
|
|
3417
|
-
if (shape.kind !== "shape" || shape.handle?.nodeId === void 0) {
|
|
3819
|
+
if (shape.kind !== "shape" && shape.kind !== "connector" || shape.handle?.nodeId === void 0) {
|
|
3418
3820
|
return false;
|
|
3419
3821
|
}
|
|
3420
|
-
if (isShapeReferencedByConnector(shape, slideShapes)) {
|
|
3822
|
+
if (shape.kind === "shape" && isShapeReferencedByConnector(shape, slideShapes)) {
|
|
3421
3823
|
return false;
|
|
3422
3824
|
}
|
|
3423
3825
|
return !shape.rawSidecars?.some((sidecar) => sidecar.node.name === "mc:AlternateContent");
|