@a3s-lab/office 0.38.1 → 0.40.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/README.md +18 -4
- package/dist/{0~7240.js → 0~2330.js} +897 -641
- package/dist/0~5024.js +240 -240
- package/dist/0~7828.js +51 -29
- package/dist/0~document-editor.js +1 -0
- package/dist/0~presentation-editor.js +264 -118
- package/dist/0~work-docx-export.js +1023 -922
- package/dist/0~work-docx-import.js +13 -4
- package/dist/0~work-office-diagnostics.js +96 -94
- package/dist/0~work-pptx-import.js +1 -1
- package/dist/0~work-presentation-transition.js +38 -0
- package/dist/4121.js +42 -9
- package/dist/4174.js +497 -233
- package/dist/4560.js +124 -9
- package/dist/internal/features/work/editors/presentation-animation-panel.d.ts +9 -7
- package/dist/internal/features/work/editors/presentation-command-types.d.ts +10 -10
- package/dist/internal/features/work/editors/presentation-slide-canvas.d.ts +6 -4
- package/dist/internal/features/work/editors/use-presentation-animation-commands.d.ts +7 -7
- package/dist/internal/features/work/work-document-format-change-tracking.d.ts +1 -1
- package/dist/internal/features/work/work-document-numbering-change-tracking.d.ts +7 -0
- package/dist/internal/features/work/work-document-numbering-changes.d.ts +29 -0
- package/dist/internal/features/work/work-docx-import.d.ts +7 -5
- package/dist/internal/features/work/work-docx-list-export.d.ts +1 -0
- package/dist/internal/features/work/work-docx-numbering-change-export.d.ts +13 -0
- package/dist/internal/features/work/work-docx-numbering-change-import.d.ts +17 -0
- package/dist/internal/features/work/work-presentation-animation.d.ts +6 -2
- package/dist/internal/features/work/work-presentation-clipboard.d.ts +0 -5
- package/dist/internal/features/work/work-types.d.ts +8 -4
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +162 -26
- package/package.json +8 -5
- package/dist/0~5809.js +0 -123
package/dist/0~7828.js
CHANGED
|
@@ -3,7 +3,8 @@ import { directChildren, xmlNamespacePrefix, parseXml, firstDescendant, descenda
|
|
|
3
3
|
import { normalizePresentationChartDataLabelPosition, normalizePresentationChartDataLabels, normalizePresentationChartSeriesStyle } from "./0~work-presentation-charts.js";
|
|
4
4
|
import { parseXlsxChartSeriesStyle, xlsxChartSeriesMarkerXml, parseXlsxTrendline, isSupportedXlsxChartLegend, isSupportedXlsxChartPlotLayout, isSupportedXlsxChartSeriesFormatting, parseXlsxChartPlotLayout, parseXlsxChartLegend, xlsxChartSeriesShapePropertiesXml, parseXlsxErrorBars } from "./4166.js";
|
|
5
5
|
import { workSpreadsheetChartSupportsErrorBars, workSpreadsheetChartSupportsGrouping, normalizeWorkSpreadsheetChartSmoothLines, workSpreadsheetChartSupportsSeriesAnalysis, normalizeWorkSpreadsheetChartSeriesStyle, normalizeWorkSpreadsheetErrorBars, normalizeWorkSpreadsheetChartOverlap, workSpreadsheetChartUsesNumericXAxis, workSpreadsheetChartSupportsBarSpacing, normalizeWorkSpreadsheetChartLegendOverlay, normalizeWorkSpreadsheetChartGapWidth, normalizeWorkSpreadsheetChartGrouping, workSpreadsheetChartSupportsTrendlines, workSpreadsheetChartSupportsSmoothLines, normalizeWorkSpreadsheetTrendline } from "./8715.js";
|
|
6
|
-
import { normalizeWorkSlideAnimation,
|
|
6
|
+
import { normalizeWorkSlideAnimation, workSlideAnimationClass, workSlideAnimationSequenceIssue } from "./4560.js";
|
|
7
|
+
import { createWorkSlideTransition } from "./0~work-presentation-transition.js";
|
|
7
8
|
const PRESENTATION_NAMESPACE = 'http://schemas.openxmlformats.org/presentationml/2006/main';
|
|
8
9
|
const DRAWING_NAMESPACE = 'http://schemas.openxmlformats.org/drawingml/2006/main';
|
|
9
10
|
const OFFICE_RELATIONSHIPS_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
|
|
@@ -922,7 +923,7 @@ function readPptxAnimations(document, elementIdByPptxShapeId) {
|
|
|
922
923
|
]
|
|
923
924
|
};
|
|
924
925
|
const animations = [];
|
|
925
|
-
const
|
|
926
|
+
const animatedClasses = new Set();
|
|
926
927
|
const effectNodes = pptxDescendants(timing, 'cTn').filter((node)=>[
|
|
927
928
|
'clickEffect',
|
|
928
929
|
'withEffect',
|
|
@@ -933,18 +934,20 @@ function readPptxAnimations(document, elementIdByPptxShapeId) {
|
|
|
933
934
|
message: "Only the first 256 object animation timing records on a slide are inspected and imported."
|
|
934
935
|
});
|
|
935
936
|
for (const node of effectNodes.slice(0, 256)){
|
|
936
|
-
|
|
937
|
+
const presetClass = attribute(node, 'presetClass');
|
|
938
|
+
if ('entr' !== presetClass && 'exit' !== presetClass) {
|
|
937
939
|
diagnostics.push({
|
|
938
940
|
code: 'pptx.animation.class',
|
|
939
|
-
message: 'An emphasis,
|
|
941
|
+
message: 'An emphasis, motion-path, or malformed animation remains in the source PPTX only.'
|
|
940
942
|
});
|
|
941
943
|
continue;
|
|
942
944
|
}
|
|
945
|
+
const animationClass = 'exit' === presetClass ? 'exit' : 'entrance';
|
|
943
946
|
const targets = Array.from(new Set(pptxDescendants(node, 'spTgt').map((target)=>attribute(target, 'spid')?.trim()).filter((target)=>Boolean(target))));
|
|
944
947
|
if (1 !== targets.length) {
|
|
945
948
|
diagnostics.push({
|
|
946
949
|
code: 'pptx.animation.target',
|
|
947
|
-
message: 'An
|
|
950
|
+
message: 'An object animation with a missing or ambiguous target was ignored.'
|
|
948
951
|
});
|
|
949
952
|
continue;
|
|
950
953
|
}
|
|
@@ -952,22 +955,23 @@ function readPptxAnimations(document, elementIdByPptxShapeId) {
|
|
|
952
955
|
if (!elementId) {
|
|
953
956
|
diagnostics.push({
|
|
954
957
|
code: 'pptx.animation.target',
|
|
955
|
-
message: 'An
|
|
958
|
+
message: 'An object animation points to an unavailable slide object and was ignored.'
|
|
956
959
|
});
|
|
957
960
|
continue;
|
|
958
961
|
}
|
|
959
|
-
|
|
962
|
+
const animatedClass = `${elementId}\u0000${animationClass}`;
|
|
963
|
+
if (animatedClasses.has(animatedClass)) {
|
|
960
964
|
diagnostics.push({
|
|
961
965
|
code: 'pptx.animation.duplicate-target',
|
|
962
|
-
message:
|
|
966
|
+
message: `Only the first supported ${animationClass} animation for an object is editable; additional effects remain in the source PPTX only.`
|
|
963
967
|
});
|
|
964
968
|
continue;
|
|
965
969
|
}
|
|
966
|
-
const effectResult = readPptxAnimationEffect(node);
|
|
970
|
+
const effectResult = readPptxAnimationEffect(node, animationClass);
|
|
967
971
|
if (!effectResult.effect) {
|
|
968
972
|
diagnostics.push({
|
|
969
973
|
code: 'pptx.animation.effect',
|
|
970
|
-
message: 'An entrance animation uses an unsupported or malformed effect and remains in the source PPTX only.'
|
|
974
|
+
message: 'An entrance or exit animation uses an unsupported or malformed effect and remains in the source PPTX only.'
|
|
971
975
|
});
|
|
972
976
|
continue;
|
|
973
977
|
}
|
|
@@ -985,12 +989,22 @@ function readPptxAnimations(document, elementIdByPptxShapeId) {
|
|
|
985
989
|
delayMs: timingResult.delayMs,
|
|
986
990
|
direction: effectResult.direction
|
|
987
991
|
});
|
|
992
|
+
if ('overlapping-target' === workSlideAnimationSequenceIssue([
|
|
993
|
+
...animations,
|
|
994
|
+
animation
|
|
995
|
+
])) {
|
|
996
|
+
diagnostics.push({
|
|
997
|
+
code: 'pptx.animation.overlap',
|
|
998
|
+
message: 'Overlapping animations for one object in one playback cue remain in the source PPTX only.'
|
|
999
|
+
});
|
|
1000
|
+
continue;
|
|
1001
|
+
}
|
|
988
1002
|
animations.push(animation);
|
|
989
|
-
|
|
1003
|
+
animatedClasses.add(animatedClass);
|
|
990
1004
|
}
|
|
991
1005
|
if (!effectNodes.length) diagnostics.push({
|
|
992
1006
|
code: 'pptx.animation.structure',
|
|
993
|
-
message: 'The slide timing tree does not contain a supported object
|
|
1007
|
+
message: 'The slide timing tree does not contain a supported object animation sequence and remains in the source PPTX only.'
|
|
994
1008
|
});
|
|
995
1009
|
return {
|
|
996
1010
|
animations,
|
|
@@ -1041,30 +1055,35 @@ function clonePptxAnimationElement(document, source) {
|
|
|
1041
1055
|
for (const child of Array.from(source.childNodes))element.append(child instanceof Element ? clonePptxAnimationElement(document, child) : document.createTextNode(child.textContent ?? ''));
|
|
1042
1056
|
return element;
|
|
1043
1057
|
}
|
|
1044
|
-
function readPptxAnimationEffect(node) {
|
|
1058
|
+
function readPptxAnimationEffect(node, animationClass) {
|
|
1045
1059
|
const presetId = attribute(node, 'presetID');
|
|
1046
1060
|
const animationEffects = pptxDescendants(node, 'animEffect');
|
|
1061
|
+
const expectedTransition = 'exit' === animationClass ? 'out' : 'in';
|
|
1062
|
+
if (animationEffects.some((effect)=>{
|
|
1063
|
+
const transition = attribute(effect, 'transition');
|
|
1064
|
+
return null !== transition && transition !== expectedTransition;
|
|
1065
|
+
})) return {};
|
|
1047
1066
|
const filters = animationEffects.map((effect)=>attribute(effect, 'filter')?.trim()).filter((filter)=>Boolean(filter));
|
|
1048
1067
|
const attributes = new Set(pptxDescendants(node, 'attrName').map((name)=>name.textContent?.trim()));
|
|
1049
1068
|
if (filters.some((filter)=>'fade' === filter)) return {
|
|
1050
|
-
effect: 'fade'
|
|
1069
|
+
effect: 'exit' === animationClass ? 'fade-out' : 'fade'
|
|
1051
1070
|
};
|
|
1052
1071
|
for (const filter of filters){
|
|
1053
1072
|
const direction = directionFromPptxSlideFilter(filter);
|
|
1054
1073
|
if (direction) return {
|
|
1055
|
-
effect: 'fly-in',
|
|
1074
|
+
effect: 'exit' === animationClass ? 'fly-out' : 'fly-in',
|
|
1056
1075
|
direction
|
|
1057
1076
|
};
|
|
1058
1077
|
}
|
|
1059
1078
|
if ('23' === presetId || pptxDescendants(node, 'animScale').length > 0 || attributes.has('ppt_w') && attributes.has('ppt_h')) return {
|
|
1060
|
-
effect: 'zoom'
|
|
1079
|
+
effect: 'exit' === animationClass ? 'zoom-out' : 'zoom'
|
|
1061
1080
|
};
|
|
1062
1081
|
if ('2' === presetId && (attributes.has('ppt_x') || attributes.has('ppt_y'))) return {
|
|
1063
|
-
effect: 'fly-in',
|
|
1082
|
+
effect: 'exit' === animationClass ? 'fly-out' : 'fly-in',
|
|
1064
1083
|
direction: directionFromPptxMotion(node)
|
|
1065
1084
|
};
|
|
1066
1085
|
if ('1' === presetId && pptxDescendants(node, 'set').length > 0 && 0 === animationEffects.length && 0 === pptxDescendants(node, 'anim').length && 0 === pptxDescendants(node, 'animScale').length) return {
|
|
1067
|
-
effect: 'appear'
|
|
1086
|
+
effect: 'exit' === animationClass ? 'disappear' : 'appear'
|
|
1068
1087
|
};
|
|
1069
1088
|
return {};
|
|
1070
1089
|
}
|
|
@@ -1131,7 +1150,7 @@ function pptxAnimationTimingXml(targets) {
|
|
|
1131
1150
|
const delay = group.automatic ? '0' : 'indefinite';
|
|
1132
1151
|
return `<p:par><p:cTn id="${outerId}" fill="hold"><p:stCondLst><p:cond delay="${delay}"/></p:stCondLst><p:childTnLst>${wrappers}</p:childTnLst></p:cTn></p:par>`;
|
|
1133
1152
|
}).join('');
|
|
1134
|
-
const builds = targets.map(({ spid })=>`<p:bldP spid="${spid}" grpId="0" animBg="1"/>`).join('');
|
|
1153
|
+
const builds = Array.from(new Set(targets.map(({ spid })=>spid))).map((spid)=>`<p:bldP spid="${spid}" grpId="0" animBg="1"/>`).join('');
|
|
1135
1154
|
return `<p:timing xmlns:p="${PRESENTATIONML_NAMESPACE}"><p:tnLst><p:par><p:cTn id="${rootId}" dur="indefinite" restart="never" nodeType="tmRoot"><p:childTnLst><p:seq concurrent="1" nextAc="seek"><p:cTn id="${mainSequenceId}" dur="indefinite" nodeType="mainSeq"><p:childTnLst>${groupXml}</p:childTnLst></p:cTn><p:prevCondLst><p:cond evt="onPrev" delay="0"><p:tgtEl><p:sldTgt/></p:tgtEl></p:cond></p:prevCondLst><p:nextCondLst><p:cond evt="onNext" delay="0"><p:tgtEl><p:sldTgt/></p:tgtEl></p:cond></p:nextCondLst></p:seq></p:childTnLst></p:cTn></p:par></p:tnLst><p:bldLst>${builds}</p:bldLst></p:timing>`;
|
|
1136
1155
|
}
|
|
1137
1156
|
function pptxAnimationGroups(animations) {
|
|
@@ -1156,36 +1175,39 @@ function pptxAnimationGroups(animations) {
|
|
|
1156
1175
|
}
|
|
1157
1176
|
function pptxAnimationEffectXml(target, nextId) {
|
|
1158
1177
|
const animation = normalizeWorkSlideAnimation(target.animation);
|
|
1178
|
+
const animationClass = workSlideAnimationClass(animation.effect);
|
|
1159
1179
|
const preset = pptxAnimationPreset(animation);
|
|
1160
1180
|
const leafId = nextId();
|
|
1161
1181
|
const visibilityId = nextId();
|
|
1162
|
-
const
|
|
1182
|
+
const visibilityDelay = 'exit' === animationClass ? Math.max(0, animation.durationMs - 1) : 0;
|
|
1183
|
+
const visibility = `<p:set><p:cBhvr><p:cTn id="${visibilityId}" dur="1" fill="hold"><p:stCondLst><p:cond delay="${visibilityDelay}"/></p:stCondLst></p:cTn><p:tgtEl><p:spTgt spid="${target.spid}"/></p:tgtEl><p:attrNameLst><p:attrName>style.visibility</p:attrName></p:attrNameLst></p:cBhvr><p:to><p:strVal val="${'exit' === animationClass ? 'hidden' : 'visible'}"/></p:to></p:set>`;
|
|
1163
1184
|
const behavior = pptxAnimationBehaviorXml(animation, target.spid, nextId);
|
|
1164
|
-
return `<p:par><p:cTn id="${leafId}" presetID="${preset.id}" presetClass="entr" presetSubtype="${preset.subtype}" fill="hold" nodeType="${pptxAnimationNodeType(animation.trigger)}" dur="${animation.durationMs}"><p:stCondLst><p:cond delay="${animation.delayMs}"/></p:stCondLst><p:childTnLst>${visibility}${behavior}</p:childTnLst></p:cTn></p:par>`;
|
|
1185
|
+
return `<p:par><p:cTn id="${leafId}" presetID="${preset.id}" presetClass="${'exit' === animationClass ? 'exit' : 'entr'}" presetSubtype="${preset.subtype}" fill="hold" nodeType="${pptxAnimationNodeType(animation.trigger)}" dur="${animation.durationMs}"><p:stCondLst><p:cond delay="${animation.delayMs}"/></p:stCondLst><p:childTnLst>${visibility}${behavior}</p:childTnLst></p:cTn></p:par>`;
|
|
1165
1186
|
}
|
|
1166
1187
|
function pptxAnimationBehaviorXml(animation, spid, nextId) {
|
|
1167
|
-
|
|
1168
|
-
if ('
|
|
1188
|
+
const animationClass = workSlideAnimationClass(animation.effect);
|
|
1189
|
+
if ('appear' === animation.effect || 'disappear' === animation.effect) return '';
|
|
1190
|
+
if ('zoom' === animation.effect || 'zoom-out' === animation.effect) return [
|
|
1169
1191
|
'ppt_w',
|
|
1170
1192
|
'ppt_h'
|
|
1171
1193
|
].map((attributeName)=>{
|
|
1172
1194
|
const id = nextId();
|
|
1173
|
-
return `<p:anim calcMode="lin" valueType="num"><p:cBhvr><p:cTn id="${id}" dur="${animation.durationMs}" fill="hold"/><p:tgtEl><p:spTgt spid="${spid}"/></p:tgtEl><p:attrNameLst><p:attrName>${attributeName}</p:attrName></p:attrNameLst></p:cBhvr><p:tavLst><p:tav tm="0"><p:val><p:fltVal val="0"/></p:val></p:tav><p:tav tm="100000"><p:val><p:strVal val="#${attributeName}"/></p:val></p:tav></p:tavLst></p:anim
|
|
1195
|
+
return `<p:anim calcMode="lin" valueType="num"><p:cBhvr><p:cTn id="${id}" dur="${animation.durationMs}" fill="hold"/><p:tgtEl><p:spTgt spid="${spid}"/></p:tgtEl><p:attrNameLst><p:attrName>${attributeName}</p:attrName></p:attrNameLst></p:cBhvr>` + ('exit' === animationClass ? `<p:tavLst><p:tav tm="0"><p:val><p:strVal val="#${attributeName}"/></p:val></p:tav><p:tav tm="100000"><p:val><p:fltVal val="0"/></p:val></p:tav></p:tavLst></p:anim>` : `<p:tavLst><p:tav tm="0"><p:val><p:fltVal val="0"/></p:val></p:tav><p:tav tm="100000"><p:val><p:strVal val="#${attributeName}"/></p:val></p:tav></p:tavLst></p:anim>`);
|
|
1174
1196
|
}).join('');
|
|
1175
1197
|
const id = nextId();
|
|
1176
|
-
const filter = 'fade' === animation.effect ? 'fade' : pptxSlideFilter(animation.direction ?? 'left');
|
|
1177
|
-
return `<p:animEffect transition="in" filter="${filter}"><p:cBhvr><p:cTn id="${id}" dur="${animation.durationMs}"/><p:tgtEl><p:spTgt spid="${spid}"/></p:tgtEl></p:cBhvr></p:animEffect>`;
|
|
1198
|
+
const filter = 'fade' === animation.effect || 'fade-out' === animation.effect ? 'fade' : pptxSlideFilter(animation.direction ?? 'left');
|
|
1199
|
+
return `<p:animEffect transition="${'exit' === animationClass ? 'out' : 'in'}" filter="${filter}"><p:cBhvr><p:cTn id="${id}" dur="${animation.durationMs}"/><p:tgtEl><p:spTgt spid="${spid}"/></p:tgtEl></p:cBhvr></p:animEffect>`;
|
|
1178
1200
|
}
|
|
1179
1201
|
function pptxAnimationPreset(animation) {
|
|
1180
|
-
if ('appear' === animation.effect) return {
|
|
1202
|
+
if ('appear' === animation.effect || 'disappear' === animation.effect) return {
|
|
1181
1203
|
id: 1,
|
|
1182
1204
|
subtype: 0
|
|
1183
1205
|
};
|
|
1184
|
-
if ('fade' === animation.effect) return {
|
|
1206
|
+
if ('fade' === animation.effect || 'fade-out' === animation.effect) return {
|
|
1185
1207
|
id: 10,
|
|
1186
1208
|
subtype: 0
|
|
1187
1209
|
};
|
|
1188
|
-
if ('zoom' === animation.effect) return {
|
|
1210
|
+
if ('zoom' === animation.effect || 'zoom-out' === animation.effect) return {
|
|
1189
1211
|
id: 23,
|
|
1190
1212
|
subtype: 16
|
|
1191
1213
|
};
|
|
@@ -1170,6 +1170,7 @@ function documentChangeKindLabel(kind) {
|
|
|
1170
1170
|
if ('insertion' === kind) return '插入';
|
|
1171
1171
|
if ('formatting' === kind) return '格式';
|
|
1172
1172
|
if ('paragraph-formatting' === kind) return '段落格式';
|
|
1173
|
+
if ('numbering' === kind) return '编号格式';
|
|
1173
1174
|
return '删除';
|
|
1174
1175
|
}
|
|
1175
1176
|
function documentChangeWindowKey(change) {
|