@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.
Files changed (32) hide show
  1. package/README.md +18 -4
  2. package/dist/{0~7240.js → 0~2330.js} +897 -641
  3. package/dist/0~5024.js +240 -240
  4. package/dist/0~7828.js +51 -29
  5. package/dist/0~document-editor.js +1 -0
  6. package/dist/0~presentation-editor.js +264 -118
  7. package/dist/0~work-docx-export.js +1023 -922
  8. package/dist/0~work-docx-import.js +13 -4
  9. package/dist/0~work-office-diagnostics.js +96 -94
  10. package/dist/0~work-pptx-import.js +1 -1
  11. package/dist/0~work-presentation-transition.js +38 -0
  12. package/dist/4121.js +42 -9
  13. package/dist/4174.js +497 -233
  14. package/dist/4560.js +124 -9
  15. package/dist/internal/features/work/editors/presentation-animation-panel.d.ts +9 -7
  16. package/dist/internal/features/work/editors/presentation-command-types.d.ts +10 -10
  17. package/dist/internal/features/work/editors/presentation-slide-canvas.d.ts +6 -4
  18. package/dist/internal/features/work/editors/use-presentation-animation-commands.d.ts +7 -7
  19. package/dist/internal/features/work/work-document-format-change-tracking.d.ts +1 -1
  20. package/dist/internal/features/work/work-document-numbering-change-tracking.d.ts +7 -0
  21. package/dist/internal/features/work/work-document-numbering-changes.d.ts +29 -0
  22. package/dist/internal/features/work/work-docx-import.d.ts +7 -5
  23. package/dist/internal/features/work/work-docx-list-export.d.ts +1 -0
  24. package/dist/internal/features/work/work-docx-numbering-change-export.d.ts +13 -0
  25. package/dist/internal/features/work/work-docx-numbering-change-import.d.ts +17 -0
  26. package/dist/internal/features/work/work-presentation-animation.d.ts +6 -2
  27. package/dist/internal/features/work/work-presentation-clipboard.d.ts +0 -5
  28. package/dist/internal/features/work/work-types.d.ts +8 -4
  29. package/dist/office-kernel.wasm +0 -0
  30. package/dist/styles.css +162 -26
  31. package/package.json +8 -5
  32. package/dist/0~5809.js +0 -123
@@ -19,14 +19,14 @@ import { officePresenceColorStyle, office_text_field_OfficeTextArea, stepOfficeZ
19
19
  import { useOfficeTaskPaneEscape, normalizeOfficeFontFamily, OfficeCheckbox, CommittedOfficeNumberField, useOfficeTaskPaneModal, officeFontFamilyLabel, useOfficeDialog, officeFontFamilies, CollectionState, createOfficeKernelClient, OfficeNumberField, handleOfficeTaskPaneKeyDown } from "./0~7048.js";
20
20
  import { WorkspaceContextMenu, isWorkspaceContextMenuKeyboardEvent, WorkOfficeZoomControls, WorkOfficeStatusBar, WorkOfficeRibbon, workspaceContextMenuPosition, OfficeSelect, WorkOfficeRibbonGroup, WorkOfficePreviewBar, WorkOfficeRibbonButton } from "./0~9073.js";
21
21
  import { presentationAgentProposalTargets, SpreadsheetChartSeriesStyleEditor, applyPresentationAgentProposalChanges, normalizeOptionalOfficeNumber, SpreadsheetErrorBarEditor, useOfficeHistory, presentationNotesProposalTarget, presentationAgentSelection, SpreadsheetTrendlineEditor, presentationAgentMenuItems } from "./0~3539.js";
22
- import { slideTransitionDurationMilliseconds, workSlideAnimationIndex, workSlideAnimationForElement, remapWorkSlideAnimations, createWorkSlideTransition, workSlideTransitionsEqual, workSlideAnimationCues, initialWorkSlideAnimationCueIndex, normalizeWorkSlideAnimation, createWorkSlideAnimation, removeWorkSlideAnimationsForElements } from "./0~5809.js";
22
+ import { readOfficePresentationCollaboration as readWorkOfficePresentationCollaboration, workSlideAnimationIndex, workSlideAnimationForElement, remapWorkSlideAnimations, createOfficePresentationCollaborationBinding as createWorkOfficePresentationCollaborationBinding, workSlideAnimationEffectMatchesClass, workSlideAnimationCues, workSlideAnimationSequenceIssue, initialWorkSlideAnimationCueIndex, normalizeWorkSlideAnimation, workSlideAnimationClass, removeWorkSlideAnimationsForElements, createWorkSlideAnimation } from "./4560.js";
23
23
  import { createOfficeEditorExtension, useOfficeEditorRuntime, useOfficeEditorKeyboardShortcuts } from "./0~3557.js";
24
24
  import { isOfficeShortcutBlocked, OfficeColorPicker, isOfficeCompositionKeyboardEvent } from "./0~3635.js";
25
+ import { slideTransitionDurationMilliseconds, createWorkSlideTransition, workSlideTransitionsEqual } from "./0~work-presentation-transition.js";
25
26
  import { ControlledEditorComposition } from "./0~controlled-editor-composition.js";
26
27
  import { normalizeDocumentHref, DOCUMENT_LINK_VALIDATION_MESSAGE } from "./0~work-document-links.js";
27
28
  import { showToast } from "./6489.js";
28
29
  import { scaledPresentationVisuals } from "./0~work-presentation-visual-scale.js";
29
- import { readOfficePresentationCollaboration as readWorkOfficePresentationCollaboration, createOfficePresentationCollaborationBinding as createWorkOfficePresentationCollaborationBinding } from "./4560.js";
30
30
  import { useOfficeEditorInitialFocus, useOfficeCollaborationLocationNavigator } from "./432.js";
31
31
  var presentation_editor_namespaceObject = {};
32
32
  __webpack_require__.r(presentation_editor_namespaceObject);
@@ -1735,21 +1735,21 @@ function createPresentationEditorExtensions() {
1735
1735
  createOfficeEditorExtension({
1736
1736
  name: 'presentationAnimations',
1737
1737
  addCommands: ()=>({
1738
- moveEntranceAnimation: {
1739
- canExecute: ({ animations }, direction)=>animations.canMoveEntranceAnimation(direction),
1740
- execute: ({ animations }, direction)=>animations.moveEntranceAnimation(direction)
1738
+ moveAnimation: {
1739
+ canExecute: ({ animations }, animationClass, direction)=>animations.canMoveAnimation(animationClass, direction),
1740
+ execute: ({ animations }, animationClass, direction)=>animations.moveAnimation(animationClass, direction)
1741
1741
  },
1742
1742
  previewAnimations: {
1743
1743
  canExecute: ({ animations })=>animations.canPreviewAnimations,
1744
1744
  execute: ({ animations })=>animations.previewAnimations()
1745
1745
  },
1746
- setEntranceAnimation: {
1747
- canExecute: ({ animations })=>animations.canSetEntranceAnimation,
1748
- execute: ({ animations }, effect)=>animations.setEntranceAnimation(effect)
1746
+ setAnimation: {
1747
+ canExecute: ({ animations })=>animations.canSetAnimation,
1748
+ execute: ({ animations }, animationClass, effect)=>animations.setAnimation(animationClass, effect)
1749
1749
  },
1750
- updateEntranceAnimation: {
1751
- canExecute: ({ animations })=>animations.canUpdateEntranceAnimation,
1752
- execute: ({ animations }, patch)=>animations.updateEntranceAnimation(patch)
1750
+ updateAnimation: {
1751
+ canExecute: ({ animations }, animationClass, patch)=>animations.canUpdateAnimation(animationClass, patch),
1752
+ execute: ({ animations }, animationClass, patch)=>animations.updateAnimation(animationClass, patch)
1753
1753
  }
1754
1754
  })
1755
1755
  }),
@@ -2479,12 +2479,12 @@ function presentationCommandsWithObjectFocus(commands, restoreFocus) {
2479
2479
  distributeElements: afterSuccessfulCommand(commands.distributeElements),
2480
2480
  duplicateSlide: afterSuccessfulCommand(commands.duplicateSlide),
2481
2481
  groupElements: afterSuccessfulCommand(commands.groupElements),
2482
- moveEntranceAnimation: afterSuccessfulCommand(commands.moveEntranceAnimation),
2482
+ moveAnimation: afterSuccessfulCommand(commands.moveAnimation),
2483
2483
  pasteSelection: afterSuccessfulCommand(commands.pasteSelection),
2484
2484
  redo: afterSuccessfulCommand(commands.redo),
2485
2485
  reorderElement: afterSuccessfulCommand(commands.reorderElement),
2486
2486
  setTransition: afterSuccessfulCommand(commands.setTransition),
2487
- setEntranceAnimation: afterSuccessfulCommand(commands.setEntranceAnimation),
2487
+ setAnimation: afterSuccessfulCommand(commands.setAnimation),
2488
2488
  setViewMode: afterSuccessfulCommand(commands.setViewMode),
2489
2489
  toggleBold: afterSuccessfulCommand(commands.toggleBold),
2490
2490
  toggleItalic: afterSuccessfulCommand(commands.toggleItalic),
@@ -2492,7 +2492,7 @@ function presentationCommandsWithObjectFocus(commands, restoreFocus) {
2492
2492
  undo: afterSuccessfulCommand(commands.undo),
2493
2493
  ungroupElements: afterSuccessfulCommand(commands.ungroupElements),
2494
2494
  updateElement: afterSuccessfulCommand(commands.updateElement),
2495
- updateEntranceAnimation: afterSuccessfulCommand(commands.updateEntranceAnimation)
2495
+ updateAnimation: afterSuccessfulCommand(commands.updateAnimation)
2496
2496
  };
2497
2497
  }
2498
2498
  function presentationChartAnalysisBounds(chart, xValues) {
@@ -3644,7 +3644,10 @@ function SlideElementPreview({ animationPlayback, element, origin, showPlacehold
3644
3644
  className: `work-slide-element ${element.type} ${origin} ${showPlaceholder && element.placeholder ? 'placeholder' : ''}`.trim(),
3645
3645
  "data-slide-preview-element-id": element.id,
3646
3646
  "data-slide-element-origin": origin,
3647
- "data-slide-animation-effect": animationPlayback?.animation.effect,
3647
+ "data-slide-animation-effect": animationPlayback?.animations.at(-1)?.animation.effect,
3648
+ "data-slide-animation-effects": animationPlayback?.animations.map(({ animation })=>animation.effect).join(' '),
3649
+ "data-slide-animation-final-visibility": animationPlayback ? animationPlayback.finallyVisible ? 'visible' : 'hidden' : void 0,
3650
+ "data-slide-animation-initial-visibility": animationPlayback ? animationPlayback.initiallyVisible ? 'visible' : 'hidden' : void 0,
3648
3651
  "data-slide-animation-state": animationPlayback?.state,
3649
3652
  style: {
3650
3653
  ...slideElementStyle(element),
@@ -3716,26 +3719,58 @@ function slideElementStyle(element) {
3716
3719
  };
3717
3720
  }
3718
3721
  function slideAnimationPlayback(animations, activeCueIndex) {
3722
+ const cues = workSlideAnimationCues(animations);
3719
3723
  const playback = new Map();
3720
- for (const [cueIndex, cue] of workSlideAnimationCues(animations).entries())for (const item of cue.items)playback.set(item.animation.elementId, {
3721
- animation: item.animation,
3722
- startOffsetMs: item.startOffsetMs,
3723
- state: cueIndex < activeCueIndex ? 'finished' : cueIndex === activeCueIndex ? 'playing' : 'pending'
3724
- });
3724
+ for (const animation of animations ?? []){
3725
+ if (playback.has(animation.elementId)) continue;
3726
+ const visible = 'exit' === workSlideAnimationClass(animation.effect);
3727
+ playback.set(animation.elementId, {
3728
+ animations: [],
3729
+ finallyVisible: visible,
3730
+ initiallyVisible: visible,
3731
+ state: visible ? 'visible' : 'hidden'
3732
+ });
3733
+ }
3734
+ if (activeCueIndex < 0) return playback;
3735
+ for (const [cueIndex, cue] of cues.entries()){
3736
+ if (cueIndex > activeCueIndex) break;
3737
+ for (const item of cue.items){
3738
+ const state = playback.get(item.animation.elementId);
3739
+ if (!state) continue;
3740
+ const finallyVisible = 'entrance' === workSlideAnimationClass(item.animation.effect);
3741
+ if (cueIndex < activeCueIndex) {
3742
+ state.finallyVisible = finallyVisible;
3743
+ state.initiallyVisible = finallyVisible;
3744
+ state.state = finallyVisible ? 'visible' : 'hidden';
3745
+ continue;
3746
+ }
3747
+ if (!state.animations.length) state.initiallyVisible = state.finallyVisible;
3748
+ state.animations.push(item);
3749
+ state.finallyVisible = finallyVisible;
3750
+ state.state = 'playing';
3751
+ }
3752
+ }
3725
3753
  return playback;
3726
3754
  }
3727
3755
  function slideElementAnimationStyle(playback) {
3728
- if (!playback) return {};
3729
- const direction = playback.animation.direction ?? 'left';
3730
- const translateX = 'left' === direction ? '-18%' : 'right' === direction ? '18%' : '0';
3731
- const translateY = 'up' === direction ? '-18%' : 'down' === direction ? '18%' : '0';
3756
+ if (!playback?.animations.length) return {};
3732
3757
  return {
3733
- '--work-slide-animation-delay': `${playback.startOffsetMs}ms`,
3734
- '--work-slide-animation-duration': `${playback.animation.durationMs}ms`,
3735
- '--work-slide-animation-translate-x': translateX,
3736
- '--work-slide-animation-translate-y': translateY
3758
+ animationDelay: playback.animations.map(({ startOffsetMs })=>`${startOffsetMs}ms`).join(', '),
3759
+ animationDuration: playback.animations.map(({ animation })=>`${animation.durationMs}ms`).join(', '),
3760
+ animationFillMode: 'forwards',
3761
+ animationName: playback.animations.map(({ animation })=>slideAnimationName(animation)).join(', '),
3762
+ animationTimingFunction: playback.animations.map(({ animation })=>slideAnimationTimingFunction(animation)).join(', ')
3737
3763
  };
3738
3764
  }
3765
+ function slideAnimationName(animation) {
3766
+ if ('fly-in' === animation.effect || 'fly-out' === animation.effect) return `work-slide-animation-${animation.effect}-${animation.direction ?? 'left'}`;
3767
+ return `work-slide-animation-${animation.effect}`;
3768
+ }
3769
+ function slideAnimationTimingFunction(animation) {
3770
+ if ('appear' === animation.effect) return 'steps(1, start)';
3771
+ if ('disappear' === animation.effect) return 'steps(1, end)';
3772
+ return 'cubic-bezier(0.16, 1, 0.3, 1)';
3773
+ }
3739
3774
  function slideTextStyle(element) {
3740
3775
  return {
3741
3776
  color: element.color,
@@ -4754,51 +4789,111 @@ function commonRunValue(runs, getValue, fallback) {
4754
4789
  const values = runs.map((run)=>getValue(run) ?? fallback);
4755
4790
  return values.every((value)=>value === values[0]) ? values[0] : fallback;
4756
4791
  }
4757
- function PresentationAnimationPanel({ animation, canMove, canPreview, editable, onMove, onPreview, onSetEffect, onUpdate }) {
4792
+ function PresentationAnimationPanel({ animations, canMove, canPreview, canUpdate, editable, elementId, onMove, onPreview, onSetEffect, onUpdate }) {
4793
+ const defaultClass = animations.entrance ? 'entrance' : animations.exit ? 'exit' : 'entrance';
4794
+ const [selection, setSelection] = useState({
4795
+ animationClass: defaultClass,
4796
+ elementId
4797
+ });
4798
+ const animationClass = selection.elementId === elementId ? selection.animationClass : defaultClass;
4799
+ const animation = animations[animationClass];
4800
+ const flyEffect = animation?.effect === 'fly-in' || animation?.effect === 'fly-out';
4801
+ const effectOptions = 'entrance' === animationClass ? [
4802
+ {
4803
+ value: 'none',
4804
+ label: '无'
4805
+ },
4806
+ {
4807
+ value: 'appear',
4808
+ label: '出现'
4809
+ },
4810
+ {
4811
+ value: 'fade',
4812
+ label: '淡入'
4813
+ },
4814
+ {
4815
+ value: 'fly-in',
4816
+ label: '飞入'
4817
+ },
4818
+ {
4819
+ value: 'zoom',
4820
+ label: '缩放'
4821
+ }
4822
+ ] : [
4823
+ {
4824
+ value: 'none',
4825
+ label: '无'
4826
+ },
4827
+ {
4828
+ value: 'disappear',
4829
+ label: '消失'
4830
+ },
4831
+ {
4832
+ value: 'fade-out',
4833
+ label: '淡出'
4834
+ },
4835
+ {
4836
+ value: 'fly-out',
4837
+ label: '飞出'
4838
+ },
4839
+ {
4840
+ value: 'zoom-out',
4841
+ label: '缩小'
4842
+ }
4843
+ ];
4758
4844
  return /*#__PURE__*/ jsxs(Fragment, {
4759
4845
  children: [
4760
4846
  /*#__PURE__*/ jsx(WorkOfficeRibbonGroup, {
4761
- label: "入场动画",
4847
+ label: "对象动画",
4762
4848
  children: /*#__PURE__*/ jsxs("fieldset", {
4763
4849
  className: "work-presentation-animation-options",
4850
+ "data-animation-class": animationClass,
4764
4851
  children: [
4765
4852
  /*#__PURE__*/ jsx("legend", {
4766
4853
  className: "sr-only",
4767
- children: "对象入场动画设置"
4854
+ children: "对象动画设置"
4768
4855
  }),
4769
4856
  /*#__PURE__*/ jsxs("div", {
4770
- className: "work-office-field effect",
4857
+ className: "work-office-field animation-class",
4771
4858
  children: [
4772
4859
  /*#__PURE__*/ jsx("span", {
4773
- children: "效果"
4860
+ children: "类型"
4774
4861
  }),
4775
4862
  /*#__PURE__*/ jsx(OfficeSelect, {
4776
- ariaLabel: "对象入场动画效果",
4863
+ ariaLabel: "对象动画类型",
4777
4864
  disabled: !editable,
4778
- value: animation?.effect ?? 'none',
4865
+ value: animationClass,
4779
4866
  options: [
4780
4867
  {
4781
- value: 'none',
4782
- label: ''
4783
- },
4784
- {
4785
- value: 'appear',
4786
- label: '出现'
4787
- },
4788
- {
4789
- value: 'fade',
4790
- label: '淡入'
4791
- },
4792
- {
4793
- value: 'fly-in',
4794
- label: '飞入'
4868
+ value: 'entrance',
4869
+ label: '进入',
4870
+ meta: '让对象出现'
4795
4871
  },
4796
4872
  {
4797
- value: 'zoom',
4798
- label: '缩放'
4873
+ value: 'exit',
4874
+ label: '退出',
4875
+ meta: '让对象消失'
4799
4876
  }
4800
4877
  ],
4801
- onValueChange: (effect)=>onSetEffect('none' === effect ? void 0 : effect)
4878
+ onValueChange: (nextClass)=>setSelection({
4879
+ animationClass: nextClass,
4880
+ elementId
4881
+ })
4882
+ })
4883
+ ]
4884
+ }),
4885
+ /*#__PURE__*/ jsxs("div", {
4886
+ className: "work-office-field effect",
4887
+ children: [
4888
+ /*#__PURE__*/ jsx("span", {
4889
+ children: "效果"
4890
+ }),
4891
+ /*#__PURE__*/ jsx(OfficeSelect, {
4892
+ ariaLabel: "对象动画效果",
4893
+ disabled: !editable,
4894
+ value: animation?.effect ?? 'none',
4895
+ options: effectOptions,
4896
+ onValueChange: (effect)=>onSetEffect(animationClass, 'none' === effect ? void 0 : effect)
4802
4897
  })
4803
4898
  ]
4804
4899
  }),
@@ -4809,57 +4904,66 @@ function PresentationAnimationPanel({ animation, canMove, canPreview, editable,
4809
4904
  children: "开始"
4810
4905
  }),
4811
4906
  /*#__PURE__*/ jsx(OfficeSelect, {
4812
- ariaLabel: "对象入场动画触发方式",
4907
+ ariaLabel: "对象动画触发方式",
4813
4908
  disabled: !animation,
4814
4909
  value: animation?.trigger ?? 'on-click',
4815
4910
  options: [
4816
4911
  {
4817
4912
  value: 'on-click',
4818
- label: '单击时'
4913
+ label: '单击时',
4914
+ disabled: Boolean(animation) && !canUpdate(animationClass, {
4915
+ trigger: 'on-click'
4916
+ })
4819
4917
  },
4820
4918
  {
4821
4919
  value: 'with-previous',
4822
- label: '与上一动画同时'
4920
+ label: '与上一动画同时',
4921
+ disabled: Boolean(animation) && !canUpdate(animationClass, {
4922
+ trigger: 'with-previous'
4923
+ })
4823
4924
  },
4824
4925
  {
4825
4926
  value: 'after-previous',
4826
- label: '上一动画之后'
4927
+ label: '上一动画之后',
4928
+ disabled: Boolean(animation) && !canUpdate(animationClass, {
4929
+ trigger: 'after-previous'
4930
+ })
4827
4931
  }
4828
4932
  ],
4829
- onValueChange: (trigger)=>onUpdate({
4933
+ onValueChange: (trigger)=>onUpdate(animationClass, {
4830
4934
  trigger: trigger
4831
4935
  })
4832
4936
  })
4833
4937
  ]
4834
4938
  }),
4835
- animation?.effect === 'fly-in' && /*#__PURE__*/ jsxs("div", {
4939
+ flyEffect && /*#__PURE__*/ jsxs("div", {
4836
4940
  className: "work-office-field direction",
4837
4941
  children: [
4838
4942
  /*#__PURE__*/ jsx("span", {
4839
4943
  children: "方向"
4840
4944
  }),
4841
4945
  /*#__PURE__*/ jsx(OfficeSelect, {
4842
- ariaLabel: "对象飞入方向",
4946
+ ariaLabel: "对象动画方向",
4843
4947
  value: animation.direction ?? 'left',
4844
4948
  options: [
4845
4949
  {
4846
4950
  value: 'left',
4847
- label: '从左侧'
4951
+ label: 'entrance' === animationClass ? '从左侧' : '向左侧'
4848
4952
  },
4849
4953
  {
4850
4954
  value: 'right',
4851
- label: '从右侧'
4955
+ label: 'entrance' === animationClass ? '从右侧' : '向右侧'
4852
4956
  },
4853
4957
  {
4854
4958
  value: 'up',
4855
- label: '从上方'
4959
+ label: 'entrance' === animationClass ? '从上方' : '向上方'
4856
4960
  },
4857
4961
  {
4858
4962
  value: 'down',
4859
- label: '从下方'
4963
+ label: 'entrance' === animationClass ? '从下方' : '向下方'
4860
4964
  }
4861
4965
  ],
4862
- onValueChange: (direction)=>onUpdate({
4966
+ onValueChange: (direction)=>onUpdate(animationClass, {
4863
4967
  direction: direction
4864
4968
  })
4865
4969
  })
@@ -4875,27 +4979,39 @@ function PresentationAnimationPanel({ animation, canMove, canPreview, editable,
4875
4979
  children: [
4876
4980
  /*#__PURE__*/ jsx(AnimationTimingField, {
4877
4981
  animationId: animation?.id,
4878
- ariaLabel: "对象入场动画持续秒数",
4982
+ ariaLabel: "对象动画持续秒数",
4879
4983
  disabled: !animation,
4880
4984
  label: "持续",
4881
4985
  maximumMs: 60000,
4882
4986
  minimumMs: 100,
4883
4987
  valueMs: animation?.durationMs ?? 500,
4884
- onCommit: (durationMs)=>onUpdate({
4988
+ onCommit: (durationMs)=>{
4989
+ if (!canUpdate(animationClass, {
4885
4990
  durationMs
4886
- })
4991
+ })) return false;
4992
+ onUpdate(animationClass, {
4993
+ durationMs
4994
+ });
4995
+ return true;
4996
+ }
4887
4997
  }),
4888
4998
  /*#__PURE__*/ jsx(AnimationTimingField, {
4889
4999
  animationId: animation?.id,
4890
- ariaLabel: "对象入场动画延迟秒数",
5000
+ ariaLabel: "对象动画延迟秒数",
4891
5001
  disabled: !animation,
4892
5002
  label: "延迟",
4893
5003
  maximumMs: 60000,
4894
5004
  minimumMs: 0,
4895
5005
  valueMs: animation?.delayMs ?? 0,
4896
- onCommit: (delayMs)=>onUpdate({
5006
+ onCommit: (delayMs)=>{
5007
+ if (!canUpdate(animationClass, {
4897
5008
  delayMs
4898
- })
5009
+ })) return false;
5010
+ onUpdate(animationClass, {
5011
+ delayMs
5012
+ });
5013
+ return true;
5014
+ }
4899
5015
  })
4900
5016
  ]
4901
5017
  })
@@ -4906,8 +5022,8 @@ function PresentationAnimationPanel({ animation, canMove, canPreview, editable,
4906
5022
  /*#__PURE__*/ jsx(WorkOfficeRibbonButton, {
4907
5023
  label: "提前对象动画",
4908
5024
  visibleLabel: "提前",
4909
- disabled: !canMove(-1),
4910
- onClick: ()=>onMove(-1),
5025
+ disabled: !canMove(animationClass, -1),
5026
+ onClick: ()=>onMove(animationClass, -1),
4911
5027
  children: /*#__PURE__*/ jsx(ArrowUp, {
4912
5028
  size: 19
4913
5029
  })
@@ -4915,8 +5031,8 @@ function PresentationAnimationPanel({ animation, canMove, canPreview, editable,
4915
5031
  /*#__PURE__*/ jsx(WorkOfficeRibbonButton, {
4916
5032
  label: "推后对象动画",
4917
5033
  visibleLabel: "推后",
4918
- disabled: !canMove(1),
4919
- onClick: ()=>onMove(1),
5034
+ disabled: !canMove(animationClass, 1),
5035
+ onClick: ()=>onMove(animationClass, 1),
4920
5036
  children: /*#__PURE__*/ jsx(ArrowDown, {
4921
5037
  size: 19
4922
5038
  })
@@ -4947,8 +5063,9 @@ function AnimationTimingField({ animationId, ariaLabel, disabled, label, maximum
4947
5063
  ]);
4948
5064
  const commit = (value)=>{
4949
5065
  const next = normalizedAnimationMilliseconds(value, valueMs, minimumMs, maximumMs);
4950
- setDraft(animationSecondsDraft(next));
4951
- if (next !== valueMs) onCommit(next);
5066
+ if (next === valueMs) return void setDraft(animationSecondsDraft(next));
5067
+ const accepted = onCommit(next);
5068
+ setDraft(animationSecondsDraft(false === accepted ? valueMs : next));
4952
5069
  };
4953
5070
  return /*#__PURE__*/ jsxs("div", {
4954
5071
  className: "work-office-field seconds",
@@ -5364,7 +5481,8 @@ function PresentationToolbar({ selectedSlide, selectedElement, selectedUnitCount
5364
5481
  });
5365
5482
  const [fontSizeDraft, setFontSizeDraft] = useState(selectedFontSize);
5366
5483
  const fontFamilyValue = presentationFontFamilyValue(selectedElement?.fontFamily);
5367
- const selectedAnimation = workSlideAnimationForElement(selectedSlide, selectedElement?.id);
5484
+ const selectedEntranceAnimation = workSlideAnimationForElement(selectedSlide, selectedElement?.id, 'entrance');
5485
+ const selectedExitAnimation = workSlideAnimationForElement(selectedSlide, selectedElement?.id, 'exit');
5368
5486
  useEffect(()=>{
5369
5487
  const previous = selectedFontSizeRef.current;
5370
5488
  const elementId = selectedElement?.id ?? null;
@@ -5786,14 +5904,19 @@ function PresentationToolbar({ selectedSlide, selectedElement, selectedUnitCount
5786
5904
  onApplyToAll: commands.applyTransitionToAll
5787
5905
  }),
5788
5906
  animations: /*#__PURE__*/ jsx(PresentationAnimationPanel, {
5789
- animation: selectedAnimation,
5790
- canMove: can.moveEntranceAnimation,
5907
+ animations: {
5908
+ entrance: selectedEntranceAnimation,
5909
+ exit: selectedExitAnimation
5910
+ },
5911
+ canMove: can.moveAnimation,
5791
5912
  canPreview: can.previewAnimations(),
5792
- editable: can.setEntranceAnimation(selectedAnimation?.effect),
5793
- onMove: commands.moveEntranceAnimation,
5913
+ canUpdate: can.updateAnimation,
5914
+ editable: can.setAnimation('entrance', selectedEntranceAnimation?.effect),
5915
+ elementId: selectedElement?.id,
5916
+ onMove: commands.moveAnimation,
5794
5917
  onPreview: commands.previewAnimations,
5795
- onSetEffect: commands.setEntranceAnimation,
5796
- onUpdate: commands.updateEntranceAnimation
5918
+ onSetEffect: commands.setAnimation,
5919
+ onUpdate: commands.updateAnimation
5797
5920
  }),
5798
5921
  slideshow: /*#__PURE__*/ jsxs(WorkOfficeRibbonGroup, {
5799
5922
  label: "开始放映",
@@ -7002,15 +7125,9 @@ function usePresentationClipboard({ content, mode, targetId, selectedSlide, sele
7002
7125
  showToast('没有可粘贴的演示内容。', 'info');
7003
7126
  return true;
7004
7127
  }
7005
- if ('element' === clipboard.payload.kind || 'elements' === clipboard.payload.kind) {
7128
+ if ('elements' === clipboard.payload.kind) {
7006
7129
  if (!targetId) return false;
7007
- const sourceElements = 'element' === clipboard.payload.kind ? [
7008
- clipboard.payload.element
7009
- ] : clipboard.payload.elements;
7010
- const sourceAnimations = 'element' === clipboard.payload.kind ? clipboard.payload.animation ? [
7011
- clipboard.payload.animation
7012
- ] : [] : clipboard.payload.animations ?? [];
7013
- const pasted = clonePresentationElementsAndAnimationsForPaste(sourceElements, sourceAnimations, clipboard.offset);
7130
+ const pasted = clonePresentationElementsAndAnimationsForPaste(clipboard.payload.elements, clipboard.payload.animations ?? [], clipboard.offset);
7014
7131
  if ('slide' === mode && !canAppendSlideAnimations(content, targetId, pasted.animations)) {
7015
7132
  showToast('对象动画数量已达到每张幻灯片 256 条的上限。', 'info');
7016
7133
  return true;
@@ -7205,10 +7322,9 @@ function use_presentation_clipboard_structuredCopy(value) {
7205
7322
  }
7206
7323
  function usePresentationAnimationCommands({ content, onChange, selectedElementId, selectedSlide }) {
7207
7324
  const selectedElementExists = Boolean(selectedElementId && selectedSlide.elements.some((element)=>element.id === selectedElementId));
7208
- const selectedAnimation = workSlideAnimationForElement(selectedSlide, selectedElementId);
7209
- const setEntranceAnimation = useCallback((effect)=>{
7325
+ const setAnimation = useCallback((animationClass, effect)=>{
7210
7326
  if (!selectedElementId || !selectedElementExists) return false;
7211
- const current = workSlideAnimationForElement(selectedSlide, selectedElementId);
7327
+ const current = workSlideAnimationForElement(selectedSlide, selectedElementId, animationClass);
7212
7328
  if (!effect) {
7213
7329
  if (!current) return false;
7214
7330
  updateSlide(content, selectedSlide.id, (slide)=>{
@@ -7220,6 +7336,7 @@ function usePresentationAnimationCommands({ content, onChange, selectedElementId
7220
7336
  }, onChange);
7221
7337
  return true;
7222
7338
  }
7339
+ if (!workSlideAnimationEffectMatchesClass(effect, animationClass)) return false;
7223
7340
  if (current?.effect === effect) return false;
7224
7341
  if (!current && (selectedSlide.animations?.length ?? 0) >= 256) return false;
7225
7342
  updateSlide(content, selectedSlide.id, (slide)=>{
@@ -7243,13 +7360,31 @@ function usePresentationAnimationCommands({ content, onChange, selectedElementId
7243
7360
  selectedElementId,
7244
7361
  selectedSlide
7245
7362
  ]);
7246
- const updateEntranceAnimation = useCallback((patch)=>{
7363
+ const canUpdateAnimation = useCallback((animationClass, patch)=>{
7364
+ const selectedAnimation = workSlideAnimationForElement(selectedSlide, selectedElementId, animationClass);
7247
7365
  if (!selectedAnimation) return false;
7248
7366
  const next = normalizeWorkSlideAnimation({
7249
7367
  ...selectedAnimation,
7250
7368
  ...patch,
7251
7369
  id: selectedAnimation.id,
7252
- elementId: selectedAnimation.elementId
7370
+ elementId: selectedAnimation.elementId,
7371
+ effect: selectedAnimation.effect
7372
+ });
7373
+ const animations = selectedSlide.animations?.map((animation)=>animation.id === selectedAnimation.id ? next : animation);
7374
+ return void 0 === workSlideAnimationSequenceIssue(animations);
7375
+ }, [
7376
+ selectedElementId,
7377
+ selectedSlide
7378
+ ]);
7379
+ const updateAnimation = useCallback((animationClass, patch)=>{
7380
+ const selectedAnimation = workSlideAnimationForElement(selectedSlide, selectedElementId, animationClass);
7381
+ if (!selectedAnimation || !canUpdateAnimation(animationClass, patch)) return false;
7382
+ const next = normalizeWorkSlideAnimation({
7383
+ ...selectedAnimation,
7384
+ ...patch,
7385
+ id: selectedAnimation.id,
7386
+ elementId: selectedAnimation.elementId,
7387
+ effect: selectedAnimation.effect
7253
7388
  });
7254
7389
  if (animationsEqual(selectedAnimation, next)) return false;
7255
7390
  updateSlide(content, selectedSlide.id, (slide)=>({
@@ -7258,21 +7393,32 @@ function usePresentationAnimationCommands({ content, onChange, selectedElementId
7258
7393
  }), onChange);
7259
7394
  return true;
7260
7395
  }, [
7396
+ canUpdateAnimation,
7261
7397
  content,
7262
7398
  onChange,
7263
- selectedAnimation,
7264
- selectedSlide.id
7399
+ selectedElementId,
7400
+ selectedSlide
7265
7401
  ]);
7266
- const canMoveEntranceAnimation = useCallback((direction)=>{
7402
+ const canMoveAnimation = useCallback((animationClass, direction)=>{
7403
+ const selectedAnimation = workSlideAnimationForElement(selectedSlide, selectedElementId, animationClass);
7267
7404
  const index = workSlideAnimationIndex(selectedSlide, selectedAnimation?.id);
7268
7405
  const target = index + direction;
7269
- return index >= 0 && target >= 0 && target < (selectedSlide.animations?.length ?? 0);
7406
+ if (index < 0 || target < 0 || target >= (selectedSlide.animations?.length ?? 0)) return false;
7407
+ const animations = [
7408
+ ...selectedSlide.animations ?? []
7409
+ ];
7410
+ [animations[index], animations[target]] = [
7411
+ animations[target],
7412
+ animations[index]
7413
+ ];
7414
+ return void 0 === workSlideAnimationSequenceIssue(animations);
7270
7415
  }, [
7271
- selectedAnimation?.id,
7416
+ selectedElementId,
7272
7417
  selectedSlide
7273
7418
  ]);
7274
- const moveEntranceAnimation = useCallback((direction)=>{
7275
- if (!selectedAnimation || !canMoveEntranceAnimation(direction)) return false;
7419
+ const moveAnimation = useCallback((animationClass, direction)=>{
7420
+ const selectedAnimation = workSlideAnimationForElement(selectedSlide, selectedElementId, animationClass);
7421
+ if (!selectedAnimation || !canMoveAnimation(animationClass, direction)) return false;
7276
7422
  updateSlide(content, selectedSlide.id, (slide)=>{
7277
7423
  const animations = [
7278
7424
  ...slide.animations ?? []
@@ -7290,19 +7436,19 @@ function usePresentationAnimationCommands({ content, onChange, selectedElementId
7290
7436
  }, onChange);
7291
7437
  return true;
7292
7438
  }, [
7293
- canMoveEntranceAnimation,
7439
+ canMoveAnimation,
7294
7440
  content,
7295
7441
  onChange,
7296
- selectedAnimation,
7297
- selectedSlide.id
7442
+ selectedElementId,
7443
+ selectedSlide
7298
7444
  ]);
7299
7445
  return {
7300
- canMoveEntranceAnimation,
7301
- canSetEntranceAnimation: selectedElementExists,
7302
- canUpdateEntranceAnimation: Boolean(selectedAnimation),
7303
- moveEntranceAnimation,
7304
- setEntranceAnimation,
7305
- updateEntranceAnimation
7446
+ canMoveAnimation,
7447
+ canSetAnimation: selectedElementExists,
7448
+ canUpdateAnimation,
7449
+ moveAnimation,
7450
+ setAnimation,
7451
+ updateAnimation
7306
7452
  };
7307
7453
  }
7308
7454
  function animationsEqual(left, right) {
@@ -8862,14 +9008,14 @@ function PresentationEditingSurface({ initialSlide, autoFocus = true, collaborat
8862
9008
  const presentationExtensions = useMemo(createPresentationEditorExtensions, []);
8863
9009
  const presentationEditor = useOfficeEditorRuntime({
8864
9010
  animations: {
8865
- canMoveEntranceAnimation: (direction)=>'slide' === designMode && presentationAnimations.canMoveEntranceAnimation(direction),
9011
+ canMoveAnimation: (animationClass, direction)=>'slide' === designMode && presentationAnimations.canMoveAnimation(animationClass, direction),
8866
9012
  canPreviewAnimations: 'slide' === designMode && Boolean(selectedSlide.animations?.length),
8867
- canSetEntranceAnimation: 'slide' === designMode && presentationAnimations.canSetEntranceAnimation,
8868
- canUpdateEntranceAnimation: 'slide' === designMode && presentationAnimations.canUpdateEntranceAnimation,
8869
- moveEntranceAnimation: presentationAnimations.moveEntranceAnimation,
9013
+ canSetAnimation: 'slide' === designMode && presentationAnimations.canSetAnimation,
9014
+ canUpdateAnimation: (animationClass, patch)=>'slide' === designMode && presentationAnimations.canUpdateAnimation(animationClass, patch),
9015
+ moveAnimation: presentationAnimations.moveAnimation,
8870
9016
  previewAnimations: ()=>startPresentationSlideshow('current'),
8871
- setEntranceAnimation: presentationAnimations.setEntranceAnimation,
8872
- updateEntranceAnimation: presentationAnimations.updateEntranceAnimation
9017
+ setAnimation: presentationAnimations.setAnimation,
9018
+ updateAnimation: presentationAnimations.updateAnimation
8873
9019
  },
8874
9020
  clipboard: {
8875
9021
  canCopySelection: selectedElements.length > 0 || 'slide' === designMode && Boolean(selectedSlide),