roosterjs-content-model-core 9.30.0 → 9.32.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.
@@ -17,6 +17,12 @@ var addUndoSnapshot = function (core, canUndoByBackspace, entityStates) {
17
17
  var lifecycle = core.lifecycle, physicalRoot = core.physicalRoot, logicalRoot = core.logicalRoot, undo = core.undo;
18
18
  var snapshot = null;
19
19
  if (!lifecycle.shadowEditFragment) {
20
+ // Give plugins the chance to add additional state to the snapshot
21
+ var beforeAddUndoSnapshotEvent = {
22
+ eventType: 'beforeAddUndoSnapshot',
23
+ additionalState: {},
24
+ };
25
+ core.api.triggerEvent(core, beforeAddUndoSnapshotEvent, false);
20
26
  // Need to create snapshot selection before retrieve innerHTML since HTML can be changed during creating selection when normalize table
21
27
  var selection = (0, createSnapshotSelection_1.createSnapshotSelection)(core);
22
28
  var html = physicalRoot.innerHTML;
@@ -53,6 +59,7 @@ var addUndoSnapshot = function (core, canUndoByBackspace, entityStates) {
53
59
  }
54
60
  snapshot = {
55
61
  html: html,
62
+ additionalState: beforeAddUndoSnapshotEvent.additionalState,
56
63
  entityStates: entityStates,
57
64
  isDarkMode: !!lifecycle.isDarkMode,
58
65
  selection: selection,
@@ -1 +1 @@
1
- {"version":3,"file":"addUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/addUndoSnapshot/addUndoSnapshot.ts"],"names":[],"mappings":";;;AAAA,2EAA0F;AAM1F,qEAAoE;AACpE,qCAAoC;AAEpC;;;;;;;;GAQG;AACI,IAAM,eAAe,GAAoB,UAAC,IAAI,EAAE,kBAAkB,EAAE,YAAY;IAC3E,IAAA,SAAS,GAAsC,IAAI,UAA1C,EAAE,YAAY,GAAwB,IAAI,aAA5B,EAAE,WAAW,GAAW,IAAI,YAAf,EAAE,IAAI,GAAK,IAAI,KAAT,CAAU;IAC5D,IAAI,QAAQ,GAAoB,IAAI,CAAC;IAErC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;QAC/B,uIAAuI;QACvI,IAAM,SAAS,GAAG,IAAA,iDAAuB,EAAC,IAAI,CAAC,CAAC;QAChD,IAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC;QAEpC,gHAAgH;QAChH,IAAI,WAAW,KAAK,YAAY,EAAE;YAC9B,IAAM,aAAa,GAAG,IAAA,sDAAwB,EAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5E,IAAI,CAAC,YAAY,IAAI,aAAa,EAAE;gBAChC,IAAM,YAAY,GAAG,IAAA,+CAAiB,EAAC,aAAa,CAAC,CAAC;gBACtD,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,EAAE,EAAE;oBAC5C,IAAM,OAAK,GAAyB;wBAChC,SAAS,EAAE,iBAAiB;wBAC5B,SAAS,EAAE,qBAAqB;wBAChC,MAAM,EAAE;4BACJ,IAAI,EAAE,YAAY,CAAC,UAAU;4BAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;4BACnB,OAAO,EAAE,aAAa;4BACtB,UAAU,EAAE,YAAY,CAAC,UAAU;yBACtC;wBACD,KAAK,EAAE,SAAS;qBACnB,CAAC;oBAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,CAAC;oBAE1C,8CAA8C;oBAC9C,IAAI,OAAK,CAAC,KAAK,EAAE;wBACb,YAAY,GAAG;4BACX;gCACI,IAAI,EAAE,YAAY,CAAC,UAAU;gCAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;gCACnB,KAAK,EAAE,OAAK,CAAC,KAAK;6BACrB;yBACJ,CAAC;qBACL;iBACJ;aACJ;SACJ;QAED,QAAQ,GAAG;YACP,IAAI,MAAA;YACJ,YAAY,cAAA;YACZ,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU;YAClC,SAAS,WAAA;SACZ,CAAC;QAEF,IAAI,WAAW,KAAK,YAAY,EAAE;YAC9B,QAAQ,CAAC,eAAe,GAAG,IAAA,iBAAO,EAAC,WAAW,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;SACpE;QAED,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAClE,IAAI,CAAC,gBAAgB,CAAC,aAAa,GAAG,KAAK,CAAC;KAC/C;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC;AA3DW,QAAA,eAAe,mBA2D1B","sourcesContent":["import { findClosestEntityWrapper, parseEntityFormat } from 'roosterjs-content-model-dom';\nimport type {\n AddUndoSnapshot,\n EntityOperationEvent,\n Snapshot,\n} from 'roosterjs-content-model-types';\nimport { createSnapshotSelection } from './createSnapshotSelection';\nimport { getPath } from './getPath';\n\n/**\n * @internal\n * Add an undo snapshot to current undo snapshot stack\n * @param core The EditorCore object\n * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).\n * @param entityStates @optional Entity states related to this snapshot.\n * Each entity state will cause an EntityOperation event with operation = EntityOperation.UpdateEntityState\n * when undo/redo to this snapshot\n */\nexport const addUndoSnapshot: AddUndoSnapshot = (core, canUndoByBackspace, entityStates) => {\n const { lifecycle, physicalRoot, logicalRoot, undo } = core;\n let snapshot: Snapshot | null = null;\n\n if (!lifecycle.shadowEditFragment) {\n // Need to create snapshot selection before retrieve innerHTML since HTML can be changed during creating selection when normalize table\n const selection = createSnapshotSelection(core);\n const html = physicalRoot.innerHTML;\n\n // Give plugins the chance to share entity states to include in the snapshot if the logical root is in an entity\n if (logicalRoot !== physicalRoot) {\n const entityWrapper = findClosestEntityWrapper(logicalRoot, core.domHelper);\n if (!entityStates && entityWrapper) {\n const entityFormat = parseEntityFormat(entityWrapper);\n if (entityFormat.entityType && entityFormat.id) {\n const event = <EntityOperationEvent>{\n eventType: 'entityOperation',\n operation: 'snapshotEntityState',\n entity: {\n type: entityFormat.entityType,\n id: entityFormat.id,\n wrapper: entityWrapper,\n isReadonly: entityFormat.isReadonly,\n },\n state: undefined,\n };\n\n core.api.triggerEvent(core, event, false);\n\n // Copy out any entity states from the plugins\n if (event.state) {\n entityStates = [\n {\n type: entityFormat.entityType,\n id: entityFormat.id,\n state: event.state,\n },\n ];\n }\n }\n }\n }\n\n snapshot = {\n html,\n entityStates,\n isDarkMode: !!lifecycle.isDarkMode,\n selection,\n };\n\n if (logicalRoot !== physicalRoot) {\n snapshot.logicalRootPath = getPath(logicalRoot, 0, physicalRoot);\n }\n\n undo.snapshotsManager.addSnapshot(snapshot, !!canUndoByBackspace);\n undo.snapshotsManager.hasNewContent = false;\n }\n\n return snapshot;\n};\n"]}
1
+ {"version":3,"file":"addUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/addUndoSnapshot/addUndoSnapshot.ts"],"names":[],"mappings":";;;AAAA,2EAA0F;AAO1F,qEAAoE;AACpE,qCAAoC;AAEpC;;;;;;;;GAQG;AACI,IAAM,eAAe,GAAoB,UAAC,IAAI,EAAE,kBAAkB,EAAE,YAAY;IAC3E,IAAA,SAAS,GAAsC,IAAI,UAA1C,EAAE,YAAY,GAAwB,IAAI,aAA5B,EAAE,WAAW,GAAW,IAAI,YAAf,EAAE,IAAI,GAAK,IAAI,KAAT,CAAU;IAC5D,IAAI,QAAQ,GAAoB,IAAI,CAAC;IAErC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;QAC/B,kEAAkE;QAClE,IAAM,0BAA0B,GAA+B;YAC3D,SAAS,EAAE,uBAAuB;YAClC,eAAe,EAAE,EAAE;SACtB,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,0BAA0B,EAAE,KAAK,CAAC,CAAC;QAE/D,uIAAuI;QACvI,IAAM,SAAS,GAAG,IAAA,iDAAuB,EAAC,IAAI,CAAC,CAAC;QAChD,IAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC;QAEpC,gHAAgH;QAChH,IAAI,WAAW,KAAK,YAAY,EAAE;YAC9B,IAAM,aAAa,GAAG,IAAA,sDAAwB,EAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5E,IAAI,CAAC,YAAY,IAAI,aAAa,EAAE;gBAChC,IAAM,YAAY,GAAG,IAAA,+CAAiB,EAAC,aAAa,CAAC,CAAC;gBACtD,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,EAAE,EAAE;oBAC5C,IAAM,OAAK,GAAyB;wBAChC,SAAS,EAAE,iBAAiB;wBAC5B,SAAS,EAAE,qBAAqB;wBAChC,MAAM,EAAE;4BACJ,IAAI,EAAE,YAAY,CAAC,UAAU;4BAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;4BACnB,OAAO,EAAE,aAAa;4BACtB,UAAU,EAAE,YAAY,CAAC,UAAU;yBACtC;wBACD,KAAK,EAAE,SAAS;qBACnB,CAAC;oBAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,CAAC;oBAE1C,8CAA8C;oBAC9C,IAAI,OAAK,CAAC,KAAK,EAAE;wBACb,YAAY,GAAG;4BACX;gCACI,IAAI,EAAE,YAAY,CAAC,UAAU;gCAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;gCACnB,KAAK,EAAE,OAAK,CAAC,KAAK;6BACrB;yBACJ,CAAC;qBACL;iBACJ;aACJ;SACJ;QAED,QAAQ,GAAG;YACP,IAAI,MAAA;YACJ,eAAe,EAAE,0BAA0B,CAAC,eAAe;YAC3D,YAAY,cAAA;YACZ,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU;YAClC,SAAS,WAAA;SACZ,CAAC;QAEF,IAAI,WAAW,KAAK,YAAY,EAAE;YAC9B,QAAQ,CAAC,eAAe,GAAG,IAAA,iBAAO,EAAC,WAAW,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;SACpE;QAED,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAClE,IAAI,CAAC,gBAAgB,CAAC,aAAa,GAAG,KAAK,CAAC;KAC/C;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC;AAnEW,QAAA,eAAe,mBAmE1B","sourcesContent":["import { findClosestEntityWrapper, parseEntityFormat } from 'roosterjs-content-model-dom';\nimport type {\n AddUndoSnapshot,\n EntityOperationEvent,\n Snapshot,\n BeforeAddUndoSnapshotEvent,\n} from 'roosterjs-content-model-types';\nimport { createSnapshotSelection } from './createSnapshotSelection';\nimport { getPath } from './getPath';\n\n/**\n * @internal\n * Add an undo snapshot to current undo snapshot stack\n * @param core The EditorCore object\n * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).\n * @param entityStates @optional Entity states related to this snapshot.\n * Each entity state will cause an EntityOperation event with operation = EntityOperation.UpdateEntityState\n * when undo/redo to this snapshot\n */\nexport const addUndoSnapshot: AddUndoSnapshot = (core, canUndoByBackspace, entityStates) => {\n const { lifecycle, physicalRoot, logicalRoot, undo } = core;\n let snapshot: Snapshot | null = null;\n\n if (!lifecycle.shadowEditFragment) {\n // Give plugins the chance to add additional state to the snapshot\n const beforeAddUndoSnapshotEvent: BeforeAddUndoSnapshotEvent = {\n eventType: 'beforeAddUndoSnapshot',\n additionalState: {},\n };\n core.api.triggerEvent(core, beforeAddUndoSnapshotEvent, false);\n\n // Need to create snapshot selection before retrieve innerHTML since HTML can be changed during creating selection when normalize table\n const selection = createSnapshotSelection(core);\n const html = physicalRoot.innerHTML;\n\n // Give plugins the chance to share entity states to include in the snapshot if the logical root is in an entity\n if (logicalRoot !== physicalRoot) {\n const entityWrapper = findClosestEntityWrapper(logicalRoot, core.domHelper);\n if (!entityStates && entityWrapper) {\n const entityFormat = parseEntityFormat(entityWrapper);\n if (entityFormat.entityType && entityFormat.id) {\n const event = <EntityOperationEvent>{\n eventType: 'entityOperation',\n operation: 'snapshotEntityState',\n entity: {\n type: entityFormat.entityType,\n id: entityFormat.id,\n wrapper: entityWrapper,\n isReadonly: entityFormat.isReadonly,\n },\n state: undefined,\n };\n\n core.api.triggerEvent(core, event, false);\n\n // Copy out any entity states from the plugins\n if (event.state) {\n entityStates = [\n {\n type: entityFormat.entityType,\n id: entityFormat.id,\n state: event.state,\n },\n ];\n }\n }\n }\n }\n\n snapshot = {\n html,\n additionalState: beforeAddUndoSnapshotEvent.additionalState,\n entityStates,\n isDarkMode: !!lifecycle.isDarkMode,\n selection,\n };\n\n if (logicalRoot !== physicalRoot) {\n snapshot.logicalRootPath = getPath(logicalRoot, 0, physicalRoot);\n }\n\n undo.snapshotsManager.addSnapshot(snapshot, !!canUndoByBackspace);\n undo.snapshotsManager.hasNewContent = false;\n }\n\n return snapshot;\n};\n"]}
@@ -25,6 +25,7 @@ var restoreUndoSnapshot = function (core, snapshot) {
25
25
  (0, restoreSnapshotColors_1.restoreSnapshotColors)(core, snapshot);
26
26
  var event_1 = {
27
27
  eventType: 'contentChanged',
28
+ additionalState: snapshot.additionalState,
28
29
  entityStates: snapshot.entityStates,
29
30
  source: roosterjs_content_model_dom_1.ChangeSource.SetContent,
30
31
  };
@@ -1 +1 @@
1
- {"version":3,"file":"restoreUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts"],"names":[],"mappings":";;;AAAA,2EAA2D;AAC3D,iEAAgE;AAChE,6DAA4D;AAC5D,2EAA0E;AAC1E,uEAAsE;AAGtE;;;;;GAKG;AACI,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,QAAQ;IACnE,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;QACI,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,QAAQ,CAAC,IAAI;KAC5B,EACD,IAAI,CAAC,aAAa,CACrB,CAAC;IAEF,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAE7B,IAAA,yCAAmB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpC,IAAA,uDAA0B,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC3C,IAAA,mDAAwB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACzC,IAAA,6CAAqB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEtC,IAAM,OAAK,GAAwB;YAC/B,SAAS,EAAE,gBAAgB;YAC3B,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,MAAM,EAAE,0CAAY,CAAC,UAAU;SAClC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;KAC3D;YAAS;QACN,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;KACjC;AACL,CAAC,CAAC;AA5BW,QAAA,mBAAmB,uBA4B9B","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { restoreSnapshotColors } from './restoreSnapshotColors';\nimport { restoreSnapshotHTML } from './restoreSnapshotHTML';\nimport { restoreSnapshotLogicalRoot } from './restoreSnapshotLogicalRoot';\nimport { restoreSnapshotSelection } from './restoreSnapshotSelection';\nimport type { ContentChangedEvent, RestoreUndoSnapshot } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Restore an undo snapshot into editor\n * @param core The editor core object\n * @param step Steps to move, can be 0, positive or negative\n */\nexport const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {\n core.api.triggerEvent(\n core,\n {\n eventType: 'beforeSetContent',\n newContent: snapshot.html,\n },\n true /*broadcast*/\n );\n\n try {\n core.undo.isRestoring = true;\n\n restoreSnapshotHTML(core, snapshot);\n restoreSnapshotLogicalRoot(core, snapshot);\n restoreSnapshotSelection(core, snapshot);\n restoreSnapshotColors(core, snapshot);\n\n const event: ContentChangedEvent = {\n eventType: 'contentChanged',\n entityStates: snapshot.entityStates,\n source: ChangeSource.SetContent,\n };\n\n core.api.triggerEvent(core, event, false /*broadcast*/);\n } finally {\n core.undo.isRestoring = false;\n }\n};\n"]}
1
+ {"version":3,"file":"restoreUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts"],"names":[],"mappings":";;;AAAA,2EAA2D;AAC3D,iEAAgE;AAChE,6DAA4D;AAC5D,2EAA0E;AAC1E,uEAAsE;AAGtE;;;;;GAKG;AACI,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,QAAQ;IACnE,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;QACI,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,QAAQ,CAAC,IAAI;KAC5B,EACD,IAAI,CAAC,aAAa,CACrB,CAAC;IAEF,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAE7B,IAAA,yCAAmB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpC,IAAA,uDAA0B,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC3C,IAAA,mDAAwB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACzC,IAAA,6CAAqB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEtC,IAAM,OAAK,GAAwB;YAC/B,SAAS,EAAE,gBAAgB;YAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,MAAM,EAAE,0CAAY,CAAC,UAAU;SAClC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;KAC3D;YAAS;QACN,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;KACjC;AACL,CAAC,CAAC;AA7BW,QAAA,mBAAmB,uBA6B9B","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { restoreSnapshotColors } from './restoreSnapshotColors';\nimport { restoreSnapshotHTML } from './restoreSnapshotHTML';\nimport { restoreSnapshotLogicalRoot } from './restoreSnapshotLogicalRoot';\nimport { restoreSnapshotSelection } from './restoreSnapshotSelection';\nimport type { ContentChangedEvent, RestoreUndoSnapshot } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Restore an undo snapshot into editor\n * @param core The editor core object\n * @param step Steps to move, can be 0, positive or negative\n */\nexport const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {\n core.api.triggerEvent(\n core,\n {\n eventType: 'beforeSetContent',\n newContent: snapshot.html,\n },\n true /*broadcast*/\n );\n\n try {\n core.undo.isRestoring = true;\n\n restoreSnapshotHTML(core, snapshot);\n restoreSnapshotLogicalRoot(core, snapshot);\n restoreSnapshotSelection(core, snapshot);\n restoreSnapshotColors(core, snapshot);\n\n const event: ContentChangedEvent = {\n eventType: 'contentChanged',\n additionalState: snapshot.additionalState,\n entityStates: snapshot.entityStates,\n source: ChangeSource.SetContent,\n };\n\n core.api.triggerEvent(core, event, false /*broadcast*/);\n } finally {\n core.undo.isRestoring = false;\n }\n};\n"]}
@@ -45,6 +45,8 @@ var SnapshotsManagerImpl = /** @class */ (function () {
45
45
  var currentSnapshot = this.snapshots.snapshots[this.snapshots.currentIndex];
46
46
  var isSameSnapshot = currentSnapshot &&
47
47
  currentSnapshot.html == snapshot.html &&
48
+ !currentSnapshot.additionalState &&
49
+ !snapshot.additionalState &&
48
50
  !currentSnapshot.entityStates &&
49
51
  !snapshot.entityStates;
50
52
  var addSnapshot = !currentSnapshot || shouldAddSnapshot(currentSnapshot, snapshot);
@@ -110,6 +112,11 @@ function createSnapshotsManager(snapshots) {
110
112
  exports.createSnapshotsManager = createSnapshotsManager;
111
113
  function shouldAddSnapshot(currentSnapshot, snapshot) {
112
114
  return (currentSnapshot.html !== snapshot.html ||
115
+ (currentSnapshot.additionalState &&
116
+ snapshot.additionalState &&
117
+ JSON.stringify(currentSnapshot.additionalState) !==
118
+ JSON.stringify(snapshot.additionalState)) ||
119
+ (!currentSnapshot.additionalState && snapshot.additionalState) ||
113
120
  (currentSnapshot.entityStates &&
114
121
  snapshot.entityStates &&
115
122
  currentSnapshot.entityStates !== snapshot.entityStates) ||
@@ -1 +1 @@
1
- {"version":3,"file":"SnapshotsManagerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/undo/SnapshotsManagerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Snapshot, Snapshots, SnapshotsManager } from 'roosterjs-content-model-types';\n\n// Max stack size that cannot be exceeded. When exceeded, old undo history will be dropped\n// to keep size under limit. This is kept at 10MB\nconst MAX_SIZE_LIMIT = 1e7;\n\nclass SnapshotsManagerImpl implements SnapshotsManager {\n private snapshots: Snapshots;\n private hasNewContentValue: boolean = false;\n\n constructor(snapshots?: Snapshots) {\n this.snapshots = snapshots ?? {\n snapshots: [],\n totalSize: 0,\n currentIndex: -1,\n autoCompleteIndex: -1,\n maxSize: MAX_SIZE_LIMIT,\n };\n }\n\n get hasNewContent(): boolean {\n return this.hasNewContentValue;\n }\n\n set hasNewContent(value: boolean) {\n this.hasNewContentValue = value;\n }\n\n canMove(step: number): boolean {\n const newIndex = this.snapshots.currentIndex + step;\n return newIndex >= 0 && newIndex < this.snapshots.snapshots.length;\n }\n\n move(step: number): Snapshot | null {\n let result: Snapshot | null = null;\n\n if (this.canMove(step)) {\n this.snapshots.currentIndex += step;\n this.snapshots.autoCompleteIndex = -1;\n result = this.snapshots.snapshots[this.snapshots.currentIndex];\n }\n\n this.snapshots.onChanged?.('move');\n\n return result;\n }\n\n addSnapshot(snapshot: Snapshot, isAutoCompleteSnapshot: boolean): void {\n const currentSnapshot = this.snapshots.snapshots[this.snapshots.currentIndex];\n const isSameSnapshot =\n currentSnapshot &&\n currentSnapshot.html == snapshot.html &&\n !currentSnapshot.entityStates &&\n !snapshot.entityStates;\n const addSnapshot = !currentSnapshot || shouldAddSnapshot(currentSnapshot, snapshot);\n\n if (this.snapshots.currentIndex < 0 || addSnapshot) {\n this.clearRedo();\n this.snapshots.snapshots.push(snapshot);\n this.snapshots.currentIndex++;\n this.snapshots.totalSize += this.getSnapshotLength(snapshot);\n\n let removeCount = 0;\n while (\n removeCount < this.snapshots.snapshots.length &&\n this.snapshots.totalSize > this.snapshots.maxSize\n ) {\n this.snapshots.totalSize -= this.getSnapshotLength(\n this.snapshots.snapshots[removeCount]\n );\n removeCount++;\n }\n\n if (removeCount > 0) {\n this.snapshots.snapshots.splice(0, removeCount);\n this.snapshots.currentIndex -= removeCount;\n\n if (this.snapshots.autoCompleteIndex >= 0) {\n this.snapshots.autoCompleteIndex -= removeCount;\n }\n }\n\n if (isAutoCompleteSnapshot) {\n this.snapshots.autoCompleteIndex = this.snapshots.currentIndex;\n }\n } else if (isSameSnapshot) {\n // replace the currentSnapshot's metadata so the selection is updated\n this.snapshots.snapshots.splice(this.snapshots.currentIndex, 1, snapshot);\n }\n\n this.snapshots.onChanged?.('add');\n }\n\n clearRedo(): void {\n if (this.canMove(1)) {\n let removedSize = 0;\n for (\n let i = this.snapshots.currentIndex + 1;\n i < this.snapshots.snapshots.length;\n i++\n ) {\n removedSize += this.getSnapshotLength(this.snapshots.snapshots[i]);\n }\n\n this.snapshots.snapshots.splice(this.snapshots.currentIndex + 1);\n this.snapshots.totalSize -= removedSize;\n this.snapshots.autoCompleteIndex = -1;\n\n this.snapshots.onChanged?.('clear');\n }\n }\n\n canUndoAutoComplete(): boolean {\n return (\n this.snapshots.autoCompleteIndex >= 0 &&\n this.snapshots.currentIndex - this.snapshots.autoCompleteIndex == 1\n );\n }\n\n private getSnapshotLength(snapshot: Snapshot) {\n return snapshot.html?.length ?? 0;\n }\n}\n\n/**\n * @internal\n * Create a new instance of Undo Snapshots Manager\n * @param snapshots @optional Snapshots object for storing undo snapshots. If not passed, default implementation will be used\n */\nexport function createSnapshotsManager(snapshots?: Snapshots): SnapshotsManager {\n return new SnapshotsManagerImpl(snapshots);\n}\n\nfunction shouldAddSnapshot(currentSnapshot: Snapshot, snapshot: Snapshot) {\n return (\n currentSnapshot.html !== snapshot.html ||\n (currentSnapshot.entityStates &&\n snapshot.entityStates &&\n currentSnapshot.entityStates !== snapshot.entityStates) ||\n (!currentSnapshot.entityStates && snapshot.entityStates)\n );\n}\n"]}
1
+ {"version":3,"file":"SnapshotsManagerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/undo/SnapshotsManagerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Snapshot, Snapshots, SnapshotsManager } from 'roosterjs-content-model-types';\n\n// Max stack size that cannot be exceeded. When exceeded, old undo history will be dropped\n// to keep size under limit. This is kept at 10MB\nconst MAX_SIZE_LIMIT = 1e7;\n\nclass SnapshotsManagerImpl implements SnapshotsManager {\n private snapshots: Snapshots;\n private hasNewContentValue: boolean = false;\n\n constructor(snapshots?: Snapshots) {\n this.snapshots = snapshots ?? {\n snapshots: [],\n totalSize: 0,\n currentIndex: -1,\n autoCompleteIndex: -1,\n maxSize: MAX_SIZE_LIMIT,\n };\n }\n\n get hasNewContent(): boolean {\n return this.hasNewContentValue;\n }\n\n set hasNewContent(value: boolean) {\n this.hasNewContentValue = value;\n }\n\n canMove(step: number): boolean {\n const newIndex = this.snapshots.currentIndex + step;\n return newIndex >= 0 && newIndex < this.snapshots.snapshots.length;\n }\n\n move(step: number): Snapshot | null {\n let result: Snapshot | null = null;\n\n if (this.canMove(step)) {\n this.snapshots.currentIndex += step;\n this.snapshots.autoCompleteIndex = -1;\n result = this.snapshots.snapshots[this.snapshots.currentIndex];\n }\n\n this.snapshots.onChanged?.('move');\n\n return result;\n }\n\n addSnapshot(snapshot: Snapshot, isAutoCompleteSnapshot: boolean): void {\n const currentSnapshot = this.snapshots.snapshots[this.snapshots.currentIndex];\n const isSameSnapshot =\n currentSnapshot &&\n currentSnapshot.html == snapshot.html &&\n !currentSnapshot.additionalState &&\n !snapshot.additionalState &&\n !currentSnapshot.entityStates &&\n !snapshot.entityStates;\n const addSnapshot = !currentSnapshot || shouldAddSnapshot(currentSnapshot, snapshot);\n\n if (this.snapshots.currentIndex < 0 || addSnapshot) {\n this.clearRedo();\n this.snapshots.snapshots.push(snapshot);\n this.snapshots.currentIndex++;\n this.snapshots.totalSize += this.getSnapshotLength(snapshot);\n\n let removeCount = 0;\n while (\n removeCount < this.snapshots.snapshots.length &&\n this.snapshots.totalSize > this.snapshots.maxSize\n ) {\n this.snapshots.totalSize -= this.getSnapshotLength(\n this.snapshots.snapshots[removeCount]\n );\n removeCount++;\n }\n\n if (removeCount > 0) {\n this.snapshots.snapshots.splice(0, removeCount);\n this.snapshots.currentIndex -= removeCount;\n\n if (this.snapshots.autoCompleteIndex >= 0) {\n this.snapshots.autoCompleteIndex -= removeCount;\n }\n }\n\n if (isAutoCompleteSnapshot) {\n this.snapshots.autoCompleteIndex = this.snapshots.currentIndex;\n }\n } else if (isSameSnapshot) {\n // replace the currentSnapshot's metadata so the selection is updated\n this.snapshots.snapshots.splice(this.snapshots.currentIndex, 1, snapshot);\n }\n\n this.snapshots.onChanged?.('add');\n }\n\n clearRedo(): void {\n if (this.canMove(1)) {\n let removedSize = 0;\n for (\n let i = this.snapshots.currentIndex + 1;\n i < this.snapshots.snapshots.length;\n i++\n ) {\n removedSize += this.getSnapshotLength(this.snapshots.snapshots[i]);\n }\n\n this.snapshots.snapshots.splice(this.snapshots.currentIndex + 1);\n this.snapshots.totalSize -= removedSize;\n this.snapshots.autoCompleteIndex = -1;\n\n this.snapshots.onChanged?.('clear');\n }\n }\n\n canUndoAutoComplete(): boolean {\n return (\n this.snapshots.autoCompleteIndex >= 0 &&\n this.snapshots.currentIndex - this.snapshots.autoCompleteIndex == 1\n );\n }\n\n private getSnapshotLength(snapshot: Snapshot) {\n return snapshot.html?.length ?? 0;\n }\n}\n\n/**\n * @internal\n * Create a new instance of Undo Snapshots Manager\n * @param snapshots @optional Snapshots object for storing undo snapshots. If not passed, default implementation will be used\n */\nexport function createSnapshotsManager(snapshots?: Snapshots): SnapshotsManager {\n return new SnapshotsManagerImpl(snapshots);\n}\n\nfunction shouldAddSnapshot(currentSnapshot: Snapshot, snapshot: Snapshot) {\n return (\n currentSnapshot.html !== snapshot.html ||\n (currentSnapshot.additionalState &&\n snapshot.additionalState &&\n JSON.stringify(currentSnapshot.additionalState) !==\n JSON.stringify(snapshot.additionalState)) ||\n (!currentSnapshot.additionalState && snapshot.additionalState) ||\n (currentSnapshot.entityStates &&\n snapshot.entityStates &&\n currentSnapshot.entityStates !== snapshot.entityStates) ||\n (!currentSnapshot.entityStates && snapshot.entityStates)\n );\n}\n"]}
@@ -15,6 +15,12 @@ define(["require", "exports", "roosterjs-content-model-dom", "./createSnapshotSe
15
15
  var lifecycle = core.lifecycle, physicalRoot = core.physicalRoot, logicalRoot = core.logicalRoot, undo = core.undo;
16
16
  var snapshot = null;
17
17
  if (!lifecycle.shadowEditFragment) {
18
+ // Give plugins the chance to add additional state to the snapshot
19
+ var beforeAddUndoSnapshotEvent = {
20
+ eventType: 'beforeAddUndoSnapshot',
21
+ additionalState: {},
22
+ };
23
+ core.api.triggerEvent(core, beforeAddUndoSnapshotEvent, false);
18
24
  // Need to create snapshot selection before retrieve innerHTML since HTML can be changed during creating selection when normalize table
19
25
  var selection = (0, createSnapshotSelection_1.createSnapshotSelection)(core);
20
26
  var html = physicalRoot.innerHTML;
@@ -51,6 +57,7 @@ define(["require", "exports", "roosterjs-content-model-dom", "./createSnapshotSe
51
57
  }
52
58
  snapshot = {
53
59
  html: html,
60
+ additionalState: beforeAddUndoSnapshotEvent.additionalState,
54
61
  entityStates: entityStates,
55
62
  isDarkMode: !!lifecycle.isDarkMode,
56
63
  selection: selection,
@@ -1 +1 @@
1
- {"version":3,"file":"addUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/addUndoSnapshot/addUndoSnapshot.ts"],"names":[],"mappings":";;;;IASA;;;;;;;;OAQG;IACI,IAAM,eAAe,GAAoB,UAAC,IAAI,EAAE,kBAAkB,EAAE,YAAY;QAC3E,IAAA,SAAS,GAAsC,IAAI,UAA1C,EAAE,YAAY,GAAwB,IAAI,aAA5B,EAAE,WAAW,GAAW,IAAI,YAAf,EAAE,IAAI,GAAK,IAAI,KAAT,CAAU;QAC5D,IAAI,QAAQ,GAAoB,IAAI,CAAC;QAErC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;YAC/B,uIAAuI;YACvI,IAAM,SAAS,GAAG,IAAA,iDAAuB,EAAC,IAAI,CAAC,CAAC;YAChD,IAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC;YAEpC,gHAAgH;YAChH,IAAI,WAAW,KAAK,YAAY,EAAE;gBAC9B,IAAM,aAAa,GAAG,IAAA,sDAAwB,EAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC5E,IAAI,CAAC,YAAY,IAAI,aAAa,EAAE;oBAChC,IAAM,YAAY,GAAG,IAAA,+CAAiB,EAAC,aAAa,CAAC,CAAC;oBACtD,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,EAAE,EAAE;wBAC5C,IAAM,OAAK,GAAyB;4BAChC,SAAS,EAAE,iBAAiB;4BAC5B,SAAS,EAAE,qBAAqB;4BAChC,MAAM,EAAE;gCACJ,IAAI,EAAE,YAAY,CAAC,UAAU;gCAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;gCACnB,OAAO,EAAE,aAAa;gCACtB,UAAU,EAAE,YAAY,CAAC,UAAU;6BACtC;4BACD,KAAK,EAAE,SAAS;yBACnB,CAAC;wBAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,CAAC;wBAE1C,8CAA8C;wBAC9C,IAAI,OAAK,CAAC,KAAK,EAAE;4BACb,YAAY,GAAG;gCACX;oCACI,IAAI,EAAE,YAAY,CAAC,UAAU;oCAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;oCACnB,KAAK,EAAE,OAAK,CAAC,KAAK;iCACrB;6BACJ,CAAC;yBACL;qBACJ;iBACJ;aACJ;YAED,QAAQ,GAAG;gBACP,IAAI,MAAA;gBACJ,YAAY,cAAA;gBACZ,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU;gBAClC,SAAS,WAAA;aACZ,CAAC;YAEF,IAAI,WAAW,KAAK,YAAY,EAAE;gBAC9B,QAAQ,CAAC,eAAe,GAAG,IAAA,iBAAO,EAAC,WAAW,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;aACpE;YAED,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC;YAClE,IAAI,CAAC,gBAAgB,CAAC,aAAa,GAAG,KAAK,CAAC;SAC/C;QAED,OAAO,QAAQ,CAAC;IACpB,CAAC,CAAC;IA3DW,QAAA,eAAe,mBA2D1B","sourcesContent":["import { findClosestEntityWrapper, parseEntityFormat } from 'roosterjs-content-model-dom';\nimport type {\n AddUndoSnapshot,\n EntityOperationEvent,\n Snapshot,\n} from 'roosterjs-content-model-types';\nimport { createSnapshotSelection } from './createSnapshotSelection';\nimport { getPath } from './getPath';\n\n/**\n * @internal\n * Add an undo snapshot to current undo snapshot stack\n * @param core The EditorCore object\n * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).\n * @param entityStates @optional Entity states related to this snapshot.\n * Each entity state will cause an EntityOperation event with operation = EntityOperation.UpdateEntityState\n * when undo/redo to this snapshot\n */\nexport const addUndoSnapshot: AddUndoSnapshot = (core, canUndoByBackspace, entityStates) => {\n const { lifecycle, physicalRoot, logicalRoot, undo } = core;\n let snapshot: Snapshot | null = null;\n\n if (!lifecycle.shadowEditFragment) {\n // Need to create snapshot selection before retrieve innerHTML since HTML can be changed during creating selection when normalize table\n const selection = createSnapshotSelection(core);\n const html = physicalRoot.innerHTML;\n\n // Give plugins the chance to share entity states to include in the snapshot if the logical root is in an entity\n if (logicalRoot !== physicalRoot) {\n const entityWrapper = findClosestEntityWrapper(logicalRoot, core.domHelper);\n if (!entityStates && entityWrapper) {\n const entityFormat = parseEntityFormat(entityWrapper);\n if (entityFormat.entityType && entityFormat.id) {\n const event = <EntityOperationEvent>{\n eventType: 'entityOperation',\n operation: 'snapshotEntityState',\n entity: {\n type: entityFormat.entityType,\n id: entityFormat.id,\n wrapper: entityWrapper,\n isReadonly: entityFormat.isReadonly,\n },\n state: undefined,\n };\n\n core.api.triggerEvent(core, event, false);\n\n // Copy out any entity states from the plugins\n if (event.state) {\n entityStates = [\n {\n type: entityFormat.entityType,\n id: entityFormat.id,\n state: event.state,\n },\n ];\n }\n }\n }\n }\n\n snapshot = {\n html,\n entityStates,\n isDarkMode: !!lifecycle.isDarkMode,\n selection,\n };\n\n if (logicalRoot !== physicalRoot) {\n snapshot.logicalRootPath = getPath(logicalRoot, 0, physicalRoot);\n }\n\n undo.snapshotsManager.addSnapshot(snapshot, !!canUndoByBackspace);\n undo.snapshotsManager.hasNewContent = false;\n }\n\n return snapshot;\n};\n"]}
1
+ {"version":3,"file":"addUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/addUndoSnapshot/addUndoSnapshot.ts"],"names":[],"mappings":";;;;IAUA;;;;;;;;OAQG;IACI,IAAM,eAAe,GAAoB,UAAC,IAAI,EAAE,kBAAkB,EAAE,YAAY;QAC3E,IAAA,SAAS,GAAsC,IAAI,UAA1C,EAAE,YAAY,GAAwB,IAAI,aAA5B,EAAE,WAAW,GAAW,IAAI,YAAf,EAAE,IAAI,GAAK,IAAI,KAAT,CAAU;QAC5D,IAAI,QAAQ,GAAoB,IAAI,CAAC;QAErC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;YAC/B,kEAAkE;YAClE,IAAM,0BAA0B,GAA+B;gBAC3D,SAAS,EAAE,uBAAuB;gBAClC,eAAe,EAAE,EAAE;aACtB,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,0BAA0B,EAAE,KAAK,CAAC,CAAC;YAE/D,uIAAuI;YACvI,IAAM,SAAS,GAAG,IAAA,iDAAuB,EAAC,IAAI,CAAC,CAAC;YAChD,IAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC;YAEpC,gHAAgH;YAChH,IAAI,WAAW,KAAK,YAAY,EAAE;gBAC9B,IAAM,aAAa,GAAG,IAAA,sDAAwB,EAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC5E,IAAI,CAAC,YAAY,IAAI,aAAa,EAAE;oBAChC,IAAM,YAAY,GAAG,IAAA,+CAAiB,EAAC,aAAa,CAAC,CAAC;oBACtD,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,EAAE,EAAE;wBAC5C,IAAM,OAAK,GAAyB;4BAChC,SAAS,EAAE,iBAAiB;4BAC5B,SAAS,EAAE,qBAAqB;4BAChC,MAAM,EAAE;gCACJ,IAAI,EAAE,YAAY,CAAC,UAAU;gCAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;gCACnB,OAAO,EAAE,aAAa;gCACtB,UAAU,EAAE,YAAY,CAAC,UAAU;6BACtC;4BACD,KAAK,EAAE,SAAS;yBACnB,CAAC;wBAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,CAAC;wBAE1C,8CAA8C;wBAC9C,IAAI,OAAK,CAAC,KAAK,EAAE;4BACb,YAAY,GAAG;gCACX;oCACI,IAAI,EAAE,YAAY,CAAC,UAAU;oCAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;oCACnB,KAAK,EAAE,OAAK,CAAC,KAAK;iCACrB;6BACJ,CAAC;yBACL;qBACJ;iBACJ;aACJ;YAED,QAAQ,GAAG;gBACP,IAAI,MAAA;gBACJ,eAAe,EAAE,0BAA0B,CAAC,eAAe;gBAC3D,YAAY,cAAA;gBACZ,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU;gBAClC,SAAS,WAAA;aACZ,CAAC;YAEF,IAAI,WAAW,KAAK,YAAY,EAAE;gBAC9B,QAAQ,CAAC,eAAe,GAAG,IAAA,iBAAO,EAAC,WAAW,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;aACpE;YAED,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC;YAClE,IAAI,CAAC,gBAAgB,CAAC,aAAa,GAAG,KAAK,CAAC;SAC/C;QAED,OAAO,QAAQ,CAAC;IACpB,CAAC,CAAC;IAnEW,QAAA,eAAe,mBAmE1B","sourcesContent":["import { findClosestEntityWrapper, parseEntityFormat } from 'roosterjs-content-model-dom';\nimport type {\n AddUndoSnapshot,\n EntityOperationEvent,\n Snapshot,\n BeforeAddUndoSnapshotEvent,\n} from 'roosterjs-content-model-types';\nimport { createSnapshotSelection } from './createSnapshotSelection';\nimport { getPath } from './getPath';\n\n/**\n * @internal\n * Add an undo snapshot to current undo snapshot stack\n * @param core The EditorCore object\n * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).\n * @param entityStates @optional Entity states related to this snapshot.\n * Each entity state will cause an EntityOperation event with operation = EntityOperation.UpdateEntityState\n * when undo/redo to this snapshot\n */\nexport const addUndoSnapshot: AddUndoSnapshot = (core, canUndoByBackspace, entityStates) => {\n const { lifecycle, physicalRoot, logicalRoot, undo } = core;\n let snapshot: Snapshot | null = null;\n\n if (!lifecycle.shadowEditFragment) {\n // Give plugins the chance to add additional state to the snapshot\n const beforeAddUndoSnapshotEvent: BeforeAddUndoSnapshotEvent = {\n eventType: 'beforeAddUndoSnapshot',\n additionalState: {},\n };\n core.api.triggerEvent(core, beforeAddUndoSnapshotEvent, false);\n\n // Need to create snapshot selection before retrieve innerHTML since HTML can be changed during creating selection when normalize table\n const selection = createSnapshotSelection(core);\n const html = physicalRoot.innerHTML;\n\n // Give plugins the chance to share entity states to include in the snapshot if the logical root is in an entity\n if (logicalRoot !== physicalRoot) {\n const entityWrapper = findClosestEntityWrapper(logicalRoot, core.domHelper);\n if (!entityStates && entityWrapper) {\n const entityFormat = parseEntityFormat(entityWrapper);\n if (entityFormat.entityType && entityFormat.id) {\n const event = <EntityOperationEvent>{\n eventType: 'entityOperation',\n operation: 'snapshotEntityState',\n entity: {\n type: entityFormat.entityType,\n id: entityFormat.id,\n wrapper: entityWrapper,\n isReadonly: entityFormat.isReadonly,\n },\n state: undefined,\n };\n\n core.api.triggerEvent(core, event, false);\n\n // Copy out any entity states from the plugins\n if (event.state) {\n entityStates = [\n {\n type: entityFormat.entityType,\n id: entityFormat.id,\n state: event.state,\n },\n ];\n }\n }\n }\n }\n\n snapshot = {\n html,\n additionalState: beforeAddUndoSnapshotEvent.additionalState,\n entityStates,\n isDarkMode: !!lifecycle.isDarkMode,\n selection,\n };\n\n if (logicalRoot !== physicalRoot) {\n snapshot.logicalRootPath = getPath(logicalRoot, 0, physicalRoot);\n }\n\n undo.snapshotsManager.addSnapshot(snapshot, !!canUndoByBackspace);\n undo.snapshotsManager.hasNewContent = false;\n }\n\n return snapshot;\n};\n"]}
@@ -21,6 +21,7 @@ define(["require", "exports", "roosterjs-content-model-dom", "./restoreSnapshotC
21
21
  (0, restoreSnapshotColors_1.restoreSnapshotColors)(core, snapshot);
22
22
  var event_1 = {
23
23
  eventType: 'contentChanged',
24
+ additionalState: snapshot.additionalState,
24
25
  entityStates: snapshot.entityStates,
25
26
  source: roosterjs_content_model_dom_1.ChangeSource.SetContent,
26
27
  };
@@ -1 +1 @@
1
- {"version":3,"file":"restoreUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts"],"names":[],"mappings":";;;;IAOA;;;;;OAKG;IACI,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,QAAQ;QACnE,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;YACI,SAAS,EAAE,kBAAkB;YAC7B,UAAU,EAAE,QAAQ,CAAC,IAAI;SAC5B,EACD,IAAI,CAAC,aAAa,CACrB,CAAC;QAEF,IAAI;YACA,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YAE7B,IAAA,yCAAmB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACpC,IAAA,uDAA0B,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC3C,IAAA,mDAAwB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACzC,IAAA,6CAAqB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAEtC,IAAM,OAAK,GAAwB;gBAC/B,SAAS,EAAE,gBAAgB;gBAC3B,YAAY,EAAE,QAAQ,CAAC,YAAY;gBACnC,MAAM,EAAE,0CAAY,CAAC,UAAU;aAClC,CAAC;YAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;SAC3D;gBAAS;YACN,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;SACjC;IACL,CAAC,CAAC;IA5BW,QAAA,mBAAmB,uBA4B9B","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { restoreSnapshotColors } from './restoreSnapshotColors';\nimport { restoreSnapshotHTML } from './restoreSnapshotHTML';\nimport { restoreSnapshotLogicalRoot } from './restoreSnapshotLogicalRoot';\nimport { restoreSnapshotSelection } from './restoreSnapshotSelection';\nimport type { ContentChangedEvent, RestoreUndoSnapshot } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Restore an undo snapshot into editor\n * @param core The editor core object\n * @param step Steps to move, can be 0, positive or negative\n */\nexport const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {\n core.api.triggerEvent(\n core,\n {\n eventType: 'beforeSetContent',\n newContent: snapshot.html,\n },\n true /*broadcast*/\n );\n\n try {\n core.undo.isRestoring = true;\n\n restoreSnapshotHTML(core, snapshot);\n restoreSnapshotLogicalRoot(core, snapshot);\n restoreSnapshotSelection(core, snapshot);\n restoreSnapshotColors(core, snapshot);\n\n const event: ContentChangedEvent = {\n eventType: 'contentChanged',\n entityStates: snapshot.entityStates,\n source: ChangeSource.SetContent,\n };\n\n core.api.triggerEvent(core, event, false /*broadcast*/);\n } finally {\n core.undo.isRestoring = false;\n }\n};\n"]}
1
+ {"version":3,"file":"restoreUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts"],"names":[],"mappings":";;;;IAOA;;;;;OAKG;IACI,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,QAAQ;QACnE,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;YACI,SAAS,EAAE,kBAAkB;YAC7B,UAAU,EAAE,QAAQ,CAAC,IAAI;SAC5B,EACD,IAAI,CAAC,aAAa,CACrB,CAAC;QAEF,IAAI;YACA,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YAE7B,IAAA,yCAAmB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACpC,IAAA,uDAA0B,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC3C,IAAA,mDAAwB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACzC,IAAA,6CAAqB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAEtC,IAAM,OAAK,GAAwB;gBAC/B,SAAS,EAAE,gBAAgB;gBAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;gBACzC,YAAY,EAAE,QAAQ,CAAC,YAAY;gBACnC,MAAM,EAAE,0CAAY,CAAC,UAAU;aAClC,CAAC;YAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;SAC3D;gBAAS;YACN,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;SACjC;IACL,CAAC,CAAC;IA7BW,QAAA,mBAAmB,uBA6B9B","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { restoreSnapshotColors } from './restoreSnapshotColors';\nimport { restoreSnapshotHTML } from './restoreSnapshotHTML';\nimport { restoreSnapshotLogicalRoot } from './restoreSnapshotLogicalRoot';\nimport { restoreSnapshotSelection } from './restoreSnapshotSelection';\nimport type { ContentChangedEvent, RestoreUndoSnapshot } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Restore an undo snapshot into editor\n * @param core The editor core object\n * @param step Steps to move, can be 0, positive or negative\n */\nexport const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {\n core.api.triggerEvent(\n core,\n {\n eventType: 'beforeSetContent',\n newContent: snapshot.html,\n },\n true /*broadcast*/\n );\n\n try {\n core.undo.isRestoring = true;\n\n restoreSnapshotHTML(core, snapshot);\n restoreSnapshotLogicalRoot(core, snapshot);\n restoreSnapshotSelection(core, snapshot);\n restoreSnapshotColors(core, snapshot);\n\n const event: ContentChangedEvent = {\n eventType: 'contentChanged',\n additionalState: snapshot.additionalState,\n entityStates: snapshot.entityStates,\n source: ChangeSource.SetContent,\n };\n\n core.api.triggerEvent(core, event, false /*broadcast*/);\n } finally {\n core.undo.isRestoring = false;\n }\n};\n"]}
@@ -46,6 +46,8 @@ define(["require", "exports"], function (require, exports) {
46
46
  var currentSnapshot = this.snapshots.snapshots[this.snapshots.currentIndex];
47
47
  var isSameSnapshot = currentSnapshot &&
48
48
  currentSnapshot.html == snapshot.html &&
49
+ !currentSnapshot.additionalState &&
50
+ !snapshot.additionalState &&
49
51
  !currentSnapshot.entityStates &&
50
52
  !snapshot.entityStates;
51
53
  var addSnapshot = !currentSnapshot || shouldAddSnapshot(currentSnapshot, snapshot);
@@ -111,6 +113,11 @@ define(["require", "exports"], function (require, exports) {
111
113
  exports.createSnapshotsManager = createSnapshotsManager;
112
114
  function shouldAddSnapshot(currentSnapshot, snapshot) {
113
115
  return (currentSnapshot.html !== snapshot.html ||
116
+ (currentSnapshot.additionalState &&
117
+ snapshot.additionalState &&
118
+ JSON.stringify(currentSnapshot.additionalState) !==
119
+ JSON.stringify(snapshot.additionalState)) ||
120
+ (!currentSnapshot.additionalState && snapshot.additionalState) ||
114
121
  (currentSnapshot.entityStates &&
115
122
  snapshot.entityStates &&
116
123
  currentSnapshot.entityStates !== snapshot.entityStates) ||
@@ -1 +1 @@
1
- {"version":3,"file":"SnapshotsManagerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/undo/SnapshotsManagerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Snapshot, Snapshots, SnapshotsManager } from 'roosterjs-content-model-types';\n\n// Max stack size that cannot be exceeded. When exceeded, old undo history will be dropped\n// to keep size under limit. This is kept at 10MB\nconst MAX_SIZE_LIMIT = 1e7;\n\nclass SnapshotsManagerImpl implements SnapshotsManager {\n private snapshots: Snapshots;\n private hasNewContentValue: boolean = false;\n\n constructor(snapshots?: Snapshots) {\n this.snapshots = snapshots ?? {\n snapshots: [],\n totalSize: 0,\n currentIndex: -1,\n autoCompleteIndex: -1,\n maxSize: MAX_SIZE_LIMIT,\n };\n }\n\n get hasNewContent(): boolean {\n return this.hasNewContentValue;\n }\n\n set hasNewContent(value: boolean) {\n this.hasNewContentValue = value;\n }\n\n canMove(step: number): boolean {\n const newIndex = this.snapshots.currentIndex + step;\n return newIndex >= 0 && newIndex < this.snapshots.snapshots.length;\n }\n\n move(step: number): Snapshot | null {\n let result: Snapshot | null = null;\n\n if (this.canMove(step)) {\n this.snapshots.currentIndex += step;\n this.snapshots.autoCompleteIndex = -1;\n result = this.snapshots.snapshots[this.snapshots.currentIndex];\n }\n\n this.snapshots.onChanged?.('move');\n\n return result;\n }\n\n addSnapshot(snapshot: Snapshot, isAutoCompleteSnapshot: boolean): void {\n const currentSnapshot = this.snapshots.snapshots[this.snapshots.currentIndex];\n const isSameSnapshot =\n currentSnapshot &&\n currentSnapshot.html == snapshot.html &&\n !currentSnapshot.entityStates &&\n !snapshot.entityStates;\n const addSnapshot = !currentSnapshot || shouldAddSnapshot(currentSnapshot, snapshot);\n\n if (this.snapshots.currentIndex < 0 || addSnapshot) {\n this.clearRedo();\n this.snapshots.snapshots.push(snapshot);\n this.snapshots.currentIndex++;\n this.snapshots.totalSize += this.getSnapshotLength(snapshot);\n\n let removeCount = 0;\n while (\n removeCount < this.snapshots.snapshots.length &&\n this.snapshots.totalSize > this.snapshots.maxSize\n ) {\n this.snapshots.totalSize -= this.getSnapshotLength(\n this.snapshots.snapshots[removeCount]\n );\n removeCount++;\n }\n\n if (removeCount > 0) {\n this.snapshots.snapshots.splice(0, removeCount);\n this.snapshots.currentIndex -= removeCount;\n\n if (this.snapshots.autoCompleteIndex >= 0) {\n this.snapshots.autoCompleteIndex -= removeCount;\n }\n }\n\n if (isAutoCompleteSnapshot) {\n this.snapshots.autoCompleteIndex = this.snapshots.currentIndex;\n }\n } else if (isSameSnapshot) {\n // replace the currentSnapshot's metadata so the selection is updated\n this.snapshots.snapshots.splice(this.snapshots.currentIndex, 1, snapshot);\n }\n\n this.snapshots.onChanged?.('add');\n }\n\n clearRedo(): void {\n if (this.canMove(1)) {\n let removedSize = 0;\n for (\n let i = this.snapshots.currentIndex + 1;\n i < this.snapshots.snapshots.length;\n i++\n ) {\n removedSize += this.getSnapshotLength(this.snapshots.snapshots[i]);\n }\n\n this.snapshots.snapshots.splice(this.snapshots.currentIndex + 1);\n this.snapshots.totalSize -= removedSize;\n this.snapshots.autoCompleteIndex = -1;\n\n this.snapshots.onChanged?.('clear');\n }\n }\n\n canUndoAutoComplete(): boolean {\n return (\n this.snapshots.autoCompleteIndex >= 0 &&\n this.snapshots.currentIndex - this.snapshots.autoCompleteIndex == 1\n );\n }\n\n private getSnapshotLength(snapshot: Snapshot) {\n return snapshot.html?.length ?? 0;\n }\n}\n\n/**\n * @internal\n * Create a new instance of Undo Snapshots Manager\n * @param snapshots @optional Snapshots object for storing undo snapshots. If not passed, default implementation will be used\n */\nexport function createSnapshotsManager(snapshots?: Snapshots): SnapshotsManager {\n return new SnapshotsManagerImpl(snapshots);\n}\n\nfunction shouldAddSnapshot(currentSnapshot: Snapshot, snapshot: Snapshot) {\n return (\n currentSnapshot.html !== snapshot.html ||\n (currentSnapshot.entityStates &&\n snapshot.entityStates &&\n currentSnapshot.entityStates !== snapshot.entityStates) ||\n (!currentSnapshot.entityStates && snapshot.entityStates)\n );\n}\n"]}
1
+ {"version":3,"file":"SnapshotsManagerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/undo/SnapshotsManagerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Snapshot, Snapshots, SnapshotsManager } from 'roosterjs-content-model-types';\n\n// Max stack size that cannot be exceeded. When exceeded, old undo history will be dropped\n// to keep size under limit. This is kept at 10MB\nconst MAX_SIZE_LIMIT = 1e7;\n\nclass SnapshotsManagerImpl implements SnapshotsManager {\n private snapshots: Snapshots;\n private hasNewContentValue: boolean = false;\n\n constructor(snapshots?: Snapshots) {\n this.snapshots = snapshots ?? {\n snapshots: [],\n totalSize: 0,\n currentIndex: -1,\n autoCompleteIndex: -1,\n maxSize: MAX_SIZE_LIMIT,\n };\n }\n\n get hasNewContent(): boolean {\n return this.hasNewContentValue;\n }\n\n set hasNewContent(value: boolean) {\n this.hasNewContentValue = value;\n }\n\n canMove(step: number): boolean {\n const newIndex = this.snapshots.currentIndex + step;\n return newIndex >= 0 && newIndex < this.snapshots.snapshots.length;\n }\n\n move(step: number): Snapshot | null {\n let result: Snapshot | null = null;\n\n if (this.canMove(step)) {\n this.snapshots.currentIndex += step;\n this.snapshots.autoCompleteIndex = -1;\n result = this.snapshots.snapshots[this.snapshots.currentIndex];\n }\n\n this.snapshots.onChanged?.('move');\n\n return result;\n }\n\n addSnapshot(snapshot: Snapshot, isAutoCompleteSnapshot: boolean): void {\n const currentSnapshot = this.snapshots.snapshots[this.snapshots.currentIndex];\n const isSameSnapshot =\n currentSnapshot &&\n currentSnapshot.html == snapshot.html &&\n !currentSnapshot.additionalState &&\n !snapshot.additionalState &&\n !currentSnapshot.entityStates &&\n !snapshot.entityStates;\n const addSnapshot = !currentSnapshot || shouldAddSnapshot(currentSnapshot, snapshot);\n\n if (this.snapshots.currentIndex < 0 || addSnapshot) {\n this.clearRedo();\n this.snapshots.snapshots.push(snapshot);\n this.snapshots.currentIndex++;\n this.snapshots.totalSize += this.getSnapshotLength(snapshot);\n\n let removeCount = 0;\n while (\n removeCount < this.snapshots.snapshots.length &&\n this.snapshots.totalSize > this.snapshots.maxSize\n ) {\n this.snapshots.totalSize -= this.getSnapshotLength(\n this.snapshots.snapshots[removeCount]\n );\n removeCount++;\n }\n\n if (removeCount > 0) {\n this.snapshots.snapshots.splice(0, removeCount);\n this.snapshots.currentIndex -= removeCount;\n\n if (this.snapshots.autoCompleteIndex >= 0) {\n this.snapshots.autoCompleteIndex -= removeCount;\n }\n }\n\n if (isAutoCompleteSnapshot) {\n this.snapshots.autoCompleteIndex = this.snapshots.currentIndex;\n }\n } else if (isSameSnapshot) {\n // replace the currentSnapshot's metadata so the selection is updated\n this.snapshots.snapshots.splice(this.snapshots.currentIndex, 1, snapshot);\n }\n\n this.snapshots.onChanged?.('add');\n }\n\n clearRedo(): void {\n if (this.canMove(1)) {\n let removedSize = 0;\n for (\n let i = this.snapshots.currentIndex + 1;\n i < this.snapshots.snapshots.length;\n i++\n ) {\n removedSize += this.getSnapshotLength(this.snapshots.snapshots[i]);\n }\n\n this.snapshots.snapshots.splice(this.snapshots.currentIndex + 1);\n this.snapshots.totalSize -= removedSize;\n this.snapshots.autoCompleteIndex = -1;\n\n this.snapshots.onChanged?.('clear');\n }\n }\n\n canUndoAutoComplete(): boolean {\n return (\n this.snapshots.autoCompleteIndex >= 0 &&\n this.snapshots.currentIndex - this.snapshots.autoCompleteIndex == 1\n );\n }\n\n private getSnapshotLength(snapshot: Snapshot) {\n return snapshot.html?.length ?? 0;\n }\n}\n\n/**\n * @internal\n * Create a new instance of Undo Snapshots Manager\n * @param snapshots @optional Snapshots object for storing undo snapshots. If not passed, default implementation will be used\n */\nexport function createSnapshotsManager(snapshots?: Snapshots): SnapshotsManager {\n return new SnapshotsManagerImpl(snapshots);\n}\n\nfunction shouldAddSnapshot(currentSnapshot: Snapshot, snapshot: Snapshot) {\n return (\n currentSnapshot.html !== snapshot.html ||\n (currentSnapshot.additionalState &&\n snapshot.additionalState &&\n JSON.stringify(currentSnapshot.additionalState) !==\n JSON.stringify(snapshot.additionalState)) ||\n (!currentSnapshot.additionalState && snapshot.additionalState) ||\n (currentSnapshot.entityStates &&\n snapshot.entityStates &&\n currentSnapshot.entityStates !== snapshot.entityStates) ||\n (!currentSnapshot.entityStates && snapshot.entityStates)\n );\n}\n"]}
@@ -14,6 +14,12 @@ export var addUndoSnapshot = function (core, canUndoByBackspace, entityStates) {
14
14
  var lifecycle = core.lifecycle, physicalRoot = core.physicalRoot, logicalRoot = core.logicalRoot, undo = core.undo;
15
15
  var snapshot = null;
16
16
  if (!lifecycle.shadowEditFragment) {
17
+ // Give plugins the chance to add additional state to the snapshot
18
+ var beforeAddUndoSnapshotEvent = {
19
+ eventType: 'beforeAddUndoSnapshot',
20
+ additionalState: {},
21
+ };
22
+ core.api.triggerEvent(core, beforeAddUndoSnapshotEvent, false);
17
23
  // Need to create snapshot selection before retrieve innerHTML since HTML can be changed during creating selection when normalize table
18
24
  var selection = createSnapshotSelection(core);
19
25
  var html = physicalRoot.innerHTML;
@@ -50,6 +56,7 @@ export var addUndoSnapshot = function (core, canUndoByBackspace, entityStates) {
50
56
  }
51
57
  snapshot = {
52
58
  html: html,
59
+ additionalState: beforeAddUndoSnapshotEvent.additionalState,
53
60
  entityStates: entityStates,
54
61
  isDarkMode: !!lifecycle.isDarkMode,
55
62
  selection: selection,
@@ -1 +1 @@
1
- {"version":3,"file":"addUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/addUndoSnapshot/addUndoSnapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAM1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;;;GAQG;AACH,MAAM,CAAC,IAAM,eAAe,GAAoB,UAAC,IAAI,EAAE,kBAAkB,EAAE,YAAY;IAC3E,IAAA,SAAS,GAAsC,IAAI,UAA1C,EAAE,YAAY,GAAwB,IAAI,aAA5B,EAAE,WAAW,GAAW,IAAI,YAAf,EAAE,IAAI,GAAK,IAAI,KAAT,CAAU;IAC5D,IAAI,QAAQ,GAAoB,IAAI,CAAC;IAErC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;QAC/B,uIAAuI;QACvI,IAAM,SAAS,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;QAChD,IAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC;QAEpC,gHAAgH;QAChH,IAAI,WAAW,KAAK,YAAY,EAAE;YAC9B,IAAM,aAAa,GAAG,wBAAwB,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5E,IAAI,CAAC,YAAY,IAAI,aAAa,EAAE;gBAChC,IAAM,YAAY,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;gBACtD,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,EAAE,EAAE;oBAC5C,IAAM,OAAK,GAAyB;wBAChC,SAAS,EAAE,iBAAiB;wBAC5B,SAAS,EAAE,qBAAqB;wBAChC,MAAM,EAAE;4BACJ,IAAI,EAAE,YAAY,CAAC,UAAU;4BAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;4BACnB,OAAO,EAAE,aAAa;4BACtB,UAAU,EAAE,YAAY,CAAC,UAAU;yBACtC;wBACD,KAAK,EAAE,SAAS;qBACnB,CAAC;oBAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,CAAC;oBAE1C,8CAA8C;oBAC9C,IAAI,OAAK,CAAC,KAAK,EAAE;wBACb,YAAY,GAAG;4BACX;gCACI,IAAI,EAAE,YAAY,CAAC,UAAU;gCAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;gCACnB,KAAK,EAAE,OAAK,CAAC,KAAK;6BACrB;yBACJ,CAAC;qBACL;iBACJ;aACJ;SACJ;QAED,QAAQ,GAAG;YACP,IAAI,MAAA;YACJ,YAAY,cAAA;YACZ,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU;YAClC,SAAS,WAAA;SACZ,CAAC;QAEF,IAAI,WAAW,KAAK,YAAY,EAAE;YAC9B,QAAQ,CAAC,eAAe,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;SACpE;QAED,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAClE,IAAI,CAAC,gBAAgB,CAAC,aAAa,GAAG,KAAK,CAAC;KAC/C;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC","sourcesContent":["import { findClosestEntityWrapper, parseEntityFormat } from 'roosterjs-content-model-dom';\nimport type {\n AddUndoSnapshot,\n EntityOperationEvent,\n Snapshot,\n} from 'roosterjs-content-model-types';\nimport { createSnapshotSelection } from './createSnapshotSelection';\nimport { getPath } from './getPath';\n\n/**\n * @internal\n * Add an undo snapshot to current undo snapshot stack\n * @param core The EditorCore object\n * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).\n * @param entityStates @optional Entity states related to this snapshot.\n * Each entity state will cause an EntityOperation event with operation = EntityOperation.UpdateEntityState\n * when undo/redo to this snapshot\n */\nexport const addUndoSnapshot: AddUndoSnapshot = (core, canUndoByBackspace, entityStates) => {\n const { lifecycle, physicalRoot, logicalRoot, undo } = core;\n let snapshot: Snapshot | null = null;\n\n if (!lifecycle.shadowEditFragment) {\n // Need to create snapshot selection before retrieve innerHTML since HTML can be changed during creating selection when normalize table\n const selection = createSnapshotSelection(core);\n const html = physicalRoot.innerHTML;\n\n // Give plugins the chance to share entity states to include in the snapshot if the logical root is in an entity\n if (logicalRoot !== physicalRoot) {\n const entityWrapper = findClosestEntityWrapper(logicalRoot, core.domHelper);\n if (!entityStates && entityWrapper) {\n const entityFormat = parseEntityFormat(entityWrapper);\n if (entityFormat.entityType && entityFormat.id) {\n const event = <EntityOperationEvent>{\n eventType: 'entityOperation',\n operation: 'snapshotEntityState',\n entity: {\n type: entityFormat.entityType,\n id: entityFormat.id,\n wrapper: entityWrapper,\n isReadonly: entityFormat.isReadonly,\n },\n state: undefined,\n };\n\n core.api.triggerEvent(core, event, false);\n\n // Copy out any entity states from the plugins\n if (event.state) {\n entityStates = [\n {\n type: entityFormat.entityType,\n id: entityFormat.id,\n state: event.state,\n },\n ];\n }\n }\n }\n }\n\n snapshot = {\n html,\n entityStates,\n isDarkMode: !!lifecycle.isDarkMode,\n selection,\n };\n\n if (logicalRoot !== physicalRoot) {\n snapshot.logicalRootPath = getPath(logicalRoot, 0, physicalRoot);\n }\n\n undo.snapshotsManager.addSnapshot(snapshot, !!canUndoByBackspace);\n undo.snapshotsManager.hasNewContent = false;\n }\n\n return snapshot;\n};\n"]}
1
+ {"version":3,"file":"addUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/addUndoSnapshot/addUndoSnapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAO1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;;;GAQG;AACH,MAAM,CAAC,IAAM,eAAe,GAAoB,UAAC,IAAI,EAAE,kBAAkB,EAAE,YAAY;IAC3E,IAAA,SAAS,GAAsC,IAAI,UAA1C,EAAE,YAAY,GAAwB,IAAI,aAA5B,EAAE,WAAW,GAAW,IAAI,YAAf,EAAE,IAAI,GAAK,IAAI,KAAT,CAAU;IAC5D,IAAI,QAAQ,GAAoB,IAAI,CAAC;IAErC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;QAC/B,kEAAkE;QAClE,IAAM,0BAA0B,GAA+B;YAC3D,SAAS,EAAE,uBAAuB;YAClC,eAAe,EAAE,EAAE;SACtB,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,0BAA0B,EAAE,KAAK,CAAC,CAAC;QAE/D,uIAAuI;QACvI,IAAM,SAAS,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;QAChD,IAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC;QAEpC,gHAAgH;QAChH,IAAI,WAAW,KAAK,YAAY,EAAE;YAC9B,IAAM,aAAa,GAAG,wBAAwB,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5E,IAAI,CAAC,YAAY,IAAI,aAAa,EAAE;gBAChC,IAAM,YAAY,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;gBACtD,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,EAAE,EAAE;oBAC5C,IAAM,OAAK,GAAyB;wBAChC,SAAS,EAAE,iBAAiB;wBAC5B,SAAS,EAAE,qBAAqB;wBAChC,MAAM,EAAE;4BACJ,IAAI,EAAE,YAAY,CAAC,UAAU;4BAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;4BACnB,OAAO,EAAE,aAAa;4BACtB,UAAU,EAAE,YAAY,CAAC,UAAU;yBACtC;wBACD,KAAK,EAAE,SAAS;qBACnB,CAAC;oBAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,CAAC;oBAE1C,8CAA8C;oBAC9C,IAAI,OAAK,CAAC,KAAK,EAAE;wBACb,YAAY,GAAG;4BACX;gCACI,IAAI,EAAE,YAAY,CAAC,UAAU;gCAC7B,EAAE,EAAE,YAAY,CAAC,EAAE;gCACnB,KAAK,EAAE,OAAK,CAAC,KAAK;6BACrB;yBACJ,CAAC;qBACL;iBACJ;aACJ;SACJ;QAED,QAAQ,GAAG;YACP,IAAI,MAAA;YACJ,eAAe,EAAE,0BAA0B,CAAC,eAAe;YAC3D,YAAY,cAAA;YACZ,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU;YAClC,SAAS,WAAA;SACZ,CAAC;QAEF,IAAI,WAAW,KAAK,YAAY,EAAE;YAC9B,QAAQ,CAAC,eAAe,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;SACpE;QAED,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAClE,IAAI,CAAC,gBAAgB,CAAC,aAAa,GAAG,KAAK,CAAC;KAC/C;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC","sourcesContent":["import { findClosestEntityWrapper, parseEntityFormat } from 'roosterjs-content-model-dom';\nimport type {\n AddUndoSnapshot,\n EntityOperationEvent,\n Snapshot,\n BeforeAddUndoSnapshotEvent,\n} from 'roosterjs-content-model-types';\nimport { createSnapshotSelection } from './createSnapshotSelection';\nimport { getPath } from './getPath';\n\n/**\n * @internal\n * Add an undo snapshot to current undo snapshot stack\n * @param core The EditorCore object\n * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).\n * @param entityStates @optional Entity states related to this snapshot.\n * Each entity state will cause an EntityOperation event with operation = EntityOperation.UpdateEntityState\n * when undo/redo to this snapshot\n */\nexport const addUndoSnapshot: AddUndoSnapshot = (core, canUndoByBackspace, entityStates) => {\n const { lifecycle, physicalRoot, logicalRoot, undo } = core;\n let snapshot: Snapshot | null = null;\n\n if (!lifecycle.shadowEditFragment) {\n // Give plugins the chance to add additional state to the snapshot\n const beforeAddUndoSnapshotEvent: BeforeAddUndoSnapshotEvent = {\n eventType: 'beforeAddUndoSnapshot',\n additionalState: {},\n };\n core.api.triggerEvent(core, beforeAddUndoSnapshotEvent, false);\n\n // Need to create snapshot selection before retrieve innerHTML since HTML can be changed during creating selection when normalize table\n const selection = createSnapshotSelection(core);\n const html = physicalRoot.innerHTML;\n\n // Give plugins the chance to share entity states to include in the snapshot if the logical root is in an entity\n if (logicalRoot !== physicalRoot) {\n const entityWrapper = findClosestEntityWrapper(logicalRoot, core.domHelper);\n if (!entityStates && entityWrapper) {\n const entityFormat = parseEntityFormat(entityWrapper);\n if (entityFormat.entityType && entityFormat.id) {\n const event = <EntityOperationEvent>{\n eventType: 'entityOperation',\n operation: 'snapshotEntityState',\n entity: {\n type: entityFormat.entityType,\n id: entityFormat.id,\n wrapper: entityWrapper,\n isReadonly: entityFormat.isReadonly,\n },\n state: undefined,\n };\n\n core.api.triggerEvent(core, event, false);\n\n // Copy out any entity states from the plugins\n if (event.state) {\n entityStates = [\n {\n type: entityFormat.entityType,\n id: entityFormat.id,\n state: event.state,\n },\n ];\n }\n }\n }\n }\n\n snapshot = {\n html,\n additionalState: beforeAddUndoSnapshotEvent.additionalState,\n entityStates,\n isDarkMode: !!lifecycle.isDarkMode,\n selection,\n };\n\n if (logicalRoot !== physicalRoot) {\n snapshot.logicalRootPath = getPath(logicalRoot, 0, physicalRoot);\n }\n\n undo.snapshotsManager.addSnapshot(snapshot, !!canUndoByBackspace);\n undo.snapshotsManager.hasNewContent = false;\n }\n\n return snapshot;\n};\n"]}
@@ -22,6 +22,7 @@ export var restoreUndoSnapshot = function (core, snapshot) {
22
22
  restoreSnapshotColors(core, snapshot);
23
23
  var event_1 = {
24
24
  eventType: 'contentChanged',
25
+ additionalState: snapshot.additionalState,
25
26
  entityStates: snapshot.entityStates,
26
27
  source: ChangeSource.SetContent,
27
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"restoreUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAGtE;;;;;GAKG;AACH,MAAM,CAAC,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,QAAQ;IACnE,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;QACI,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,QAAQ,CAAC,IAAI;KAC5B,EACD,IAAI,CAAC,aAAa,CACrB,CAAC;IAEF,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAE7B,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpC,0BAA0B,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC3C,wBAAwB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACzC,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEtC,IAAM,OAAK,GAAwB;YAC/B,SAAS,EAAE,gBAAgB;YAC3B,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,MAAM,EAAE,YAAY,CAAC,UAAU;SAClC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;KAC3D;YAAS;QACN,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;KACjC;AACL,CAAC,CAAC","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { restoreSnapshotColors } from './restoreSnapshotColors';\nimport { restoreSnapshotHTML } from './restoreSnapshotHTML';\nimport { restoreSnapshotLogicalRoot } from './restoreSnapshotLogicalRoot';\nimport { restoreSnapshotSelection } from './restoreSnapshotSelection';\nimport type { ContentChangedEvent, RestoreUndoSnapshot } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Restore an undo snapshot into editor\n * @param core The editor core object\n * @param step Steps to move, can be 0, positive or negative\n */\nexport const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {\n core.api.triggerEvent(\n core,\n {\n eventType: 'beforeSetContent',\n newContent: snapshot.html,\n },\n true /*broadcast*/\n );\n\n try {\n core.undo.isRestoring = true;\n\n restoreSnapshotHTML(core, snapshot);\n restoreSnapshotLogicalRoot(core, snapshot);\n restoreSnapshotSelection(core, snapshot);\n restoreSnapshotColors(core, snapshot);\n\n const event: ContentChangedEvent = {\n eventType: 'contentChanged',\n entityStates: snapshot.entityStates,\n source: ChangeSource.SetContent,\n };\n\n core.api.triggerEvent(core, event, false /*broadcast*/);\n } finally {\n core.undo.isRestoring = false;\n }\n};\n"]}
1
+ {"version":3,"file":"restoreUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAGtE;;;;;GAKG;AACH,MAAM,CAAC,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,QAAQ;IACnE,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;QACI,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,QAAQ,CAAC,IAAI;KAC5B,EACD,IAAI,CAAC,aAAa,CACrB,CAAC;IAEF,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAE7B,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpC,0BAA0B,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC3C,wBAAwB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACzC,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEtC,IAAM,OAAK,GAAwB;YAC/B,SAAS,EAAE,gBAAgB;YAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,MAAM,EAAE,YAAY,CAAC,UAAU;SAClC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;KAC3D;YAAS;QACN,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;KACjC;AACL,CAAC,CAAC","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { restoreSnapshotColors } from './restoreSnapshotColors';\nimport { restoreSnapshotHTML } from './restoreSnapshotHTML';\nimport { restoreSnapshotLogicalRoot } from './restoreSnapshotLogicalRoot';\nimport { restoreSnapshotSelection } from './restoreSnapshotSelection';\nimport type { ContentChangedEvent, RestoreUndoSnapshot } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Restore an undo snapshot into editor\n * @param core The editor core object\n * @param step Steps to move, can be 0, positive or negative\n */\nexport const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {\n core.api.triggerEvent(\n core,\n {\n eventType: 'beforeSetContent',\n newContent: snapshot.html,\n },\n true /*broadcast*/\n );\n\n try {\n core.undo.isRestoring = true;\n\n restoreSnapshotHTML(core, snapshot);\n restoreSnapshotLogicalRoot(core, snapshot);\n restoreSnapshotSelection(core, snapshot);\n restoreSnapshotColors(core, snapshot);\n\n const event: ContentChangedEvent = {\n eventType: 'contentChanged',\n additionalState: snapshot.additionalState,\n entityStates: snapshot.entityStates,\n source: ChangeSource.SetContent,\n };\n\n core.api.triggerEvent(core, event, false /*broadcast*/);\n } finally {\n core.undo.isRestoring = false;\n }\n};\n"]}
@@ -42,6 +42,8 @@ var SnapshotsManagerImpl = /** @class */ (function () {
42
42
  var currentSnapshot = this.snapshots.snapshots[this.snapshots.currentIndex];
43
43
  var isSameSnapshot = currentSnapshot &&
44
44
  currentSnapshot.html == snapshot.html &&
45
+ !currentSnapshot.additionalState &&
46
+ !snapshot.additionalState &&
45
47
  !currentSnapshot.entityStates &&
46
48
  !snapshot.entityStates;
47
49
  var addSnapshot = !currentSnapshot || shouldAddSnapshot(currentSnapshot, snapshot);
@@ -106,6 +108,11 @@ export function createSnapshotsManager(snapshots) {
106
108
  }
107
109
  function shouldAddSnapshot(currentSnapshot, snapshot) {
108
110
  return (currentSnapshot.html !== snapshot.html ||
111
+ (currentSnapshot.additionalState &&
112
+ snapshot.additionalState &&
113
+ JSON.stringify(currentSnapshot.additionalState) !==
114
+ JSON.stringify(snapshot.additionalState)) ||
115
+ (!currentSnapshot.additionalState && snapshot.additionalState) ||
109
116
  (currentSnapshot.entityStates &&
110
117
  snapshot.entityStates &&
111
118
  currentSnapshot.entityStates !== snapshot.entityStates) ||
@@ -1 +1 @@
1
- {"version":3,"file":"SnapshotsManagerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/undo/SnapshotsManagerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Snapshot, Snapshots, SnapshotsManager } from 'roosterjs-content-model-types';\n\n// Max stack size that cannot be exceeded. When exceeded, old undo history will be dropped\n// to keep size under limit. This is kept at 10MB\nconst MAX_SIZE_LIMIT = 1e7;\n\nclass SnapshotsManagerImpl implements SnapshotsManager {\n private snapshots: Snapshots;\n private hasNewContentValue: boolean = false;\n\n constructor(snapshots?: Snapshots) {\n this.snapshots = snapshots ?? {\n snapshots: [],\n totalSize: 0,\n currentIndex: -1,\n autoCompleteIndex: -1,\n maxSize: MAX_SIZE_LIMIT,\n };\n }\n\n get hasNewContent(): boolean {\n return this.hasNewContentValue;\n }\n\n set hasNewContent(value: boolean) {\n this.hasNewContentValue = value;\n }\n\n canMove(step: number): boolean {\n const newIndex = this.snapshots.currentIndex + step;\n return newIndex >= 0 && newIndex < this.snapshots.snapshots.length;\n }\n\n move(step: number): Snapshot | null {\n let result: Snapshot | null = null;\n\n if (this.canMove(step)) {\n this.snapshots.currentIndex += step;\n this.snapshots.autoCompleteIndex = -1;\n result = this.snapshots.snapshots[this.snapshots.currentIndex];\n }\n\n this.snapshots.onChanged?.('move');\n\n return result;\n }\n\n addSnapshot(snapshot: Snapshot, isAutoCompleteSnapshot: boolean): void {\n const currentSnapshot = this.snapshots.snapshots[this.snapshots.currentIndex];\n const isSameSnapshot =\n currentSnapshot &&\n currentSnapshot.html == snapshot.html &&\n !currentSnapshot.entityStates &&\n !snapshot.entityStates;\n const addSnapshot = !currentSnapshot || shouldAddSnapshot(currentSnapshot, snapshot);\n\n if (this.snapshots.currentIndex < 0 || addSnapshot) {\n this.clearRedo();\n this.snapshots.snapshots.push(snapshot);\n this.snapshots.currentIndex++;\n this.snapshots.totalSize += this.getSnapshotLength(snapshot);\n\n let removeCount = 0;\n while (\n removeCount < this.snapshots.snapshots.length &&\n this.snapshots.totalSize > this.snapshots.maxSize\n ) {\n this.snapshots.totalSize -= this.getSnapshotLength(\n this.snapshots.snapshots[removeCount]\n );\n removeCount++;\n }\n\n if (removeCount > 0) {\n this.snapshots.snapshots.splice(0, removeCount);\n this.snapshots.currentIndex -= removeCount;\n\n if (this.snapshots.autoCompleteIndex >= 0) {\n this.snapshots.autoCompleteIndex -= removeCount;\n }\n }\n\n if (isAutoCompleteSnapshot) {\n this.snapshots.autoCompleteIndex = this.snapshots.currentIndex;\n }\n } else if (isSameSnapshot) {\n // replace the currentSnapshot's metadata so the selection is updated\n this.snapshots.snapshots.splice(this.snapshots.currentIndex, 1, snapshot);\n }\n\n this.snapshots.onChanged?.('add');\n }\n\n clearRedo(): void {\n if (this.canMove(1)) {\n let removedSize = 0;\n for (\n let i = this.snapshots.currentIndex + 1;\n i < this.snapshots.snapshots.length;\n i++\n ) {\n removedSize += this.getSnapshotLength(this.snapshots.snapshots[i]);\n }\n\n this.snapshots.snapshots.splice(this.snapshots.currentIndex + 1);\n this.snapshots.totalSize -= removedSize;\n this.snapshots.autoCompleteIndex = -1;\n\n this.snapshots.onChanged?.('clear');\n }\n }\n\n canUndoAutoComplete(): boolean {\n return (\n this.snapshots.autoCompleteIndex >= 0 &&\n this.snapshots.currentIndex - this.snapshots.autoCompleteIndex == 1\n );\n }\n\n private getSnapshotLength(snapshot: Snapshot) {\n return snapshot.html?.length ?? 0;\n }\n}\n\n/**\n * @internal\n * Create a new instance of Undo Snapshots Manager\n * @param snapshots @optional Snapshots object for storing undo snapshots. If not passed, default implementation will be used\n */\nexport function createSnapshotsManager(snapshots?: Snapshots): SnapshotsManager {\n return new SnapshotsManagerImpl(snapshots);\n}\n\nfunction shouldAddSnapshot(currentSnapshot: Snapshot, snapshot: Snapshot) {\n return (\n currentSnapshot.html !== snapshot.html ||\n (currentSnapshot.entityStates &&\n snapshot.entityStates &&\n currentSnapshot.entityStates !== snapshot.entityStates) ||\n (!currentSnapshot.entityStates && snapshot.entityStates)\n );\n}\n"]}
1
+ {"version":3,"file":"SnapshotsManagerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/undo/SnapshotsManagerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Snapshot, Snapshots, SnapshotsManager } from 'roosterjs-content-model-types';\n\n// Max stack size that cannot be exceeded. When exceeded, old undo history will be dropped\n// to keep size under limit. This is kept at 10MB\nconst MAX_SIZE_LIMIT = 1e7;\n\nclass SnapshotsManagerImpl implements SnapshotsManager {\n private snapshots: Snapshots;\n private hasNewContentValue: boolean = false;\n\n constructor(snapshots?: Snapshots) {\n this.snapshots = snapshots ?? {\n snapshots: [],\n totalSize: 0,\n currentIndex: -1,\n autoCompleteIndex: -1,\n maxSize: MAX_SIZE_LIMIT,\n };\n }\n\n get hasNewContent(): boolean {\n return this.hasNewContentValue;\n }\n\n set hasNewContent(value: boolean) {\n this.hasNewContentValue = value;\n }\n\n canMove(step: number): boolean {\n const newIndex = this.snapshots.currentIndex + step;\n return newIndex >= 0 && newIndex < this.snapshots.snapshots.length;\n }\n\n move(step: number): Snapshot | null {\n let result: Snapshot | null = null;\n\n if (this.canMove(step)) {\n this.snapshots.currentIndex += step;\n this.snapshots.autoCompleteIndex = -1;\n result = this.snapshots.snapshots[this.snapshots.currentIndex];\n }\n\n this.snapshots.onChanged?.('move');\n\n return result;\n }\n\n addSnapshot(snapshot: Snapshot, isAutoCompleteSnapshot: boolean): void {\n const currentSnapshot = this.snapshots.snapshots[this.snapshots.currentIndex];\n const isSameSnapshot =\n currentSnapshot &&\n currentSnapshot.html == snapshot.html &&\n !currentSnapshot.additionalState &&\n !snapshot.additionalState &&\n !currentSnapshot.entityStates &&\n !snapshot.entityStates;\n const addSnapshot = !currentSnapshot || shouldAddSnapshot(currentSnapshot, snapshot);\n\n if (this.snapshots.currentIndex < 0 || addSnapshot) {\n this.clearRedo();\n this.snapshots.snapshots.push(snapshot);\n this.snapshots.currentIndex++;\n this.snapshots.totalSize += this.getSnapshotLength(snapshot);\n\n let removeCount = 0;\n while (\n removeCount < this.snapshots.snapshots.length &&\n this.snapshots.totalSize > this.snapshots.maxSize\n ) {\n this.snapshots.totalSize -= this.getSnapshotLength(\n this.snapshots.snapshots[removeCount]\n );\n removeCount++;\n }\n\n if (removeCount > 0) {\n this.snapshots.snapshots.splice(0, removeCount);\n this.snapshots.currentIndex -= removeCount;\n\n if (this.snapshots.autoCompleteIndex >= 0) {\n this.snapshots.autoCompleteIndex -= removeCount;\n }\n }\n\n if (isAutoCompleteSnapshot) {\n this.snapshots.autoCompleteIndex = this.snapshots.currentIndex;\n }\n } else if (isSameSnapshot) {\n // replace the currentSnapshot's metadata so the selection is updated\n this.snapshots.snapshots.splice(this.snapshots.currentIndex, 1, snapshot);\n }\n\n this.snapshots.onChanged?.('add');\n }\n\n clearRedo(): void {\n if (this.canMove(1)) {\n let removedSize = 0;\n for (\n let i = this.snapshots.currentIndex + 1;\n i < this.snapshots.snapshots.length;\n i++\n ) {\n removedSize += this.getSnapshotLength(this.snapshots.snapshots[i]);\n }\n\n this.snapshots.snapshots.splice(this.snapshots.currentIndex + 1);\n this.snapshots.totalSize -= removedSize;\n this.snapshots.autoCompleteIndex = -1;\n\n this.snapshots.onChanged?.('clear');\n }\n }\n\n canUndoAutoComplete(): boolean {\n return (\n this.snapshots.autoCompleteIndex >= 0 &&\n this.snapshots.currentIndex - this.snapshots.autoCompleteIndex == 1\n );\n }\n\n private getSnapshotLength(snapshot: Snapshot) {\n return snapshot.html?.length ?? 0;\n }\n}\n\n/**\n * @internal\n * Create a new instance of Undo Snapshots Manager\n * @param snapshots @optional Snapshots object for storing undo snapshots. If not passed, default implementation will be used\n */\nexport function createSnapshotsManager(snapshots?: Snapshots): SnapshotsManager {\n return new SnapshotsManagerImpl(snapshots);\n}\n\nfunction shouldAddSnapshot(currentSnapshot: Snapshot, snapshot: Snapshot) {\n return (\n currentSnapshot.html !== snapshot.html ||\n (currentSnapshot.additionalState &&\n snapshot.additionalState &&\n JSON.stringify(currentSnapshot.additionalState) !==\n JSON.stringify(snapshot.additionalState)) ||\n (!currentSnapshot.additionalState && snapshot.additionalState) ||\n (currentSnapshot.entityStates &&\n snapshot.entityStates &&\n currentSnapshot.entityStates !== snapshot.entityStates) ||\n (!currentSnapshot.entityStates && snapshot.entityStates)\n );\n}\n"]}
package/package.json CHANGED
@@ -3,10 +3,10 @@
3
3
  "description": "Core editor for roosterjs",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.1",
6
- "roosterjs-content-model-dom": "^9.30.0",
7
- "roosterjs-content-model-types": "^9.30.0"
6
+ "roosterjs-content-model-dom": "^9.32.0",
7
+ "roosterjs-content-model-types": "^9.32.0"
8
8
  },
9
- "version": "9.30.0",
9
+ "version": "9.32.0",
10
10
  "main": "./lib/index.js",
11
11
  "typings": "./lib/index.d.ts",
12
12
  "module": "./lib-mjs/index.js",