@atlaskit/editor-plugin-show-diff 8.4.5 → 8.4.7

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 (29) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/pm-plugins/areDocsEqualByBlockStructureAndText.js +6 -10
  3. package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +13 -20
  4. package/dist/cjs/pm-plugins/calculateDiff/diffBySteps.js +141 -4
  5. package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +13 -27
  6. package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +12 -34
  7. package/dist/cjs/pm-plugins/decorations/utils/getAttrChangeRanges.js +30 -32
  8. package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +5 -9
  9. package/dist/cjs/pm-plugins/main.js +13 -18
  10. package/dist/cjs/showDiffPlugin.js +1 -3
  11. package/dist/es2019/pm-plugins/areDocsEqualByBlockStructureAndText.js +6 -10
  12. package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +13 -20
  13. package/dist/es2019/pm-plugins/calculateDiff/diffBySteps.js +137 -4
  14. package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +15 -27
  15. package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +10 -32
  16. package/dist/es2019/pm-plugins/decorations/utils/getAttrChangeRanges.js +24 -26
  17. package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +6 -10
  18. package/dist/es2019/pm-plugins/main.js +13 -18
  19. package/dist/es2019/showDiffPlugin.js +1 -3
  20. package/dist/esm/pm-plugins/areDocsEqualByBlockStructureAndText.js +6 -10
  21. package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +13 -20
  22. package/dist/esm/pm-plugins/calculateDiff/diffBySteps.js +141 -4
  23. package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +14 -27
  24. package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +12 -34
  25. package/dist/esm/pm-plugins/decorations/utils/getAttrChangeRanges.js +30 -32
  26. package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +6 -10
  27. package/dist/esm/pm-plugins/main.js +13 -18
  28. package/dist/esm/showDiffPlugin.js +1 -3
  29. package/package.json +7 -14
@@ -1,9 +1,8 @@
1
1
  import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
2
2
  import { trackChangesMessages } from '@atlaskit/editor-common/messages';
3
- import { fg } from '@atlaskit/platform-feature-flags';
4
3
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
5
4
  import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlock, editingStyle, editingStyleActive, editingStyleNode, addedCellOverlayStyle, deletedCellOverlayStyle } from '../colorSchemes/standard';
6
- import { deletedTraditionalBlockOutline, deletedTraditionalBlockOutlineActive, deletedTraditionalBlockOutlineNew, deletedTraditionalBlockOutlineRounded, deletedTraditionalBlockOutlineRoundedActive, deletedTraditionalBlockOutlineRoundedNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, deletedTraditionalStyleQuoteNodeActive, traditionalInsertStyle, traditionalInsertStyleActive, traditionalStyleNode, traditionalStyleNodeActive, traditionalStyleNodeNew, traditionalAddedCellOverlayStyle, traditionalAddedCellOverlayStyleNew, deletedTraditionalCellOverlayStyle } from '../colorSchemes/traditional';
5
+ import { deletedTraditionalBlockOutlineActive, deletedTraditionalBlockOutlineNew, deletedTraditionalBlockOutlineRoundedActive, deletedTraditionalBlockOutlineRoundedNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, deletedTraditionalStyleQuoteNodeActive, traditionalInsertStyle, traditionalInsertStyleActive, traditionalStyleNodeActive, traditionalStyleNodeNew, traditionalAddedCellOverlayStyleNew, deletedTraditionalCellOverlayStyle } from '../colorSchemes/traditional';
7
6
  const lozengeStyle = convertToInlineCss({
8
7
  display: 'inline-flex',
9
8
  boxSizing: 'border-box',
@@ -77,10 +76,7 @@ const getChangedNodeStyle = (nodeName, colorScheme, isInserted = false, isActive
77
76
  return undefined;
78
77
  }
79
78
  if (isTraditional) {
80
- if (fg('platform_editor_show_diff_scroll_navigation')) {
81
- return isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew;
82
- }
83
- return isActive ? traditionalStyleNodeActive : traditionalStyleNode;
79
+ return isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew;
84
80
  }
85
81
  return editingStyleNode;
86
82
  }
@@ -93,13 +89,13 @@ const getChangedNodeStyle = (nodeName, colorScheme, isInserted = false, isActive
93
89
  case 'expand':
94
90
  case 'decisionList':
95
91
  if (isTraditional) {
96
- return isActive ? deletedTraditionalBlockOutlineActive : fg('platform_editor_show_diff_scroll_navigation') ? deletedTraditionalBlockOutlineNew : deletedTraditionalBlockOutline;
92
+ return isActive ? deletedTraditionalBlockOutlineActive : deletedTraditionalBlockOutlineNew;
97
93
  }
98
94
  return isActive ? deletedBlockOutlineActive : deletedBlockOutline;
99
95
  case 'panel':
100
96
  case 'codeBlock':
101
97
  if (isTraditional) {
102
- return isActive ? deletedTraditionalBlockOutlineRoundedActive : fg('platform_editor_show_diff_scroll_navigation') ? deletedTraditionalBlockOutlineRoundedNew : deletedTraditionalBlockOutlineRounded;
98
+ return isActive ? deletedTraditionalBlockOutlineRoundedActive : deletedTraditionalBlockOutlineRoundedNew;
103
99
  }
104
100
  return isActive ? deletedBlockOutlineRoundedActive : deletedBlockOutlineRounded;
105
101
  default:
@@ -142,7 +138,7 @@ const maybeAddDeletedOutlineNewClass = ({
142
138
  if (name !== 'mediaSingle' && name !== 'embedCard') {
143
139
  return;
144
140
  }
145
- if (colorScheme === 'traditional' && !isActive && fg('platform_editor_show_diff_scroll_navigation')) {
141
+ if (colorScheme === 'traditional' && !isActive) {
146
142
  nodeView.classList.add('show-diff-deleted-outline-new');
147
143
  }
148
144
  };
@@ -167,7 +163,7 @@ const applyCellOverlayStyles = ({
167
163
  }) => {
168
164
  element.querySelectorAll('td, th').forEach(cell => {
169
165
  const overlay = document.createElement('span');
170
- const overlayStyle = colorScheme === 'traditional' ? isInserted ? fg('platform_editor_show_diff_scroll_navigation') ? traditionalAddedCellOverlayStyleNew : traditionalAddedCellOverlayStyle : deletedTraditionalCellOverlayStyle : isInserted ? addedCellOverlayStyle : deletedCellOverlayStyle;
166
+ const overlayStyle = colorScheme === 'traditional' ? isInserted ? traditionalAddedCellOverlayStyleNew : deletedTraditionalCellOverlayStyle : isInserted ? addedCellOverlayStyle : deletedCellOverlayStyle;
171
167
  overlay.setAttribute('style', overlayStyle);
172
168
  cell.appendChild(overlay);
173
169
  });
@@ -3,7 +3,6 @@ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
3
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
4
4
  import { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
5
5
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
6
- import { fg } from '@atlaskit/platform-feature-flags';
7
6
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
8
7
  import { calculateDiffDecorations } from './calculateDiff/calculateDiffDecorations';
9
8
  import { enforceCustomStepRegisters } from './enforceCustomStepRegisters';
@@ -12,9 +11,7 @@ import { NodeViewSerializer } from './NodeViewSerializer';
12
11
  import { scrollToActiveDecoration, scrollToFirstDecoration } from './scrollToDiff';
13
12
  export const showDiffPluginKey = new PluginKey('showDiffPlugin');
14
13
  export const createPlugin = (config, getIntl, api) => {
15
- if (fg('platform_editor_show_diff_equality_fallback')) {
16
- enforceCustomStepRegisters();
17
- }
14
+ enforceCustomStepRegisters();
18
15
  const nodeViewSerializer = new NodeViewSerializer({});
19
16
  const setNodeViewSerializer = editorView => {
20
17
  nodeViewSerializer.init({
@@ -58,7 +55,7 @@ export const createPlugin = (config, getIntl, api) => {
58
55
  nodeViewSerializer,
59
56
  colorScheme: config === null || config === void 0 ? void 0 : config.colorScheme,
60
57
  intl: getIntl(),
61
- activeIndexPos: fg('platform_editor_show_diff_scroll_navigation') ? newPluginState.activeIndexPos : undefined,
58
+ activeIndexPos: newPluginState.activeIndexPos,
62
59
  api,
63
60
  ...(expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? {
64
61
  isInverted: (_newPluginState = newPluginState) === null || _newPluginState === void 0 ? void 0 : _newPluginState.isInverted,
@@ -85,7 +82,7 @@ export const createPlugin = (config, getIntl, api) => {
85
82
  hideDeletedDiffs: false
86
83
  } : {})
87
84
  };
88
- } else if (((meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_NEXT' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_PREVIOUS') && fg('platform_editor_show_diff_scroll_navigation')) {
85
+ } else if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_NEXT' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_PREVIOUS') {
89
86
  // Update the active index in plugin state and recalculate decorations
90
87
  const decorations = getScrollableDecorations(currentPluginState.decorations, newState.doc);
91
88
  if (decorations.length > 0) {
@@ -175,19 +172,17 @@ export const createPlugin = (config, getIntl, api) => {
175
172
  }
176
173
 
177
174
  // Check for any potential scroll side-effects
178
- if (fg('platform_editor_show_diff_scroll_navigation')) {
179
- const activeIndexChanged = (pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex) !== undefined && pluginState.activeIndex !== previousActiveIndex;
180
- previousActiveIndex = pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex;
181
- if ((pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex) !== undefined && activeIndexChanged) {
182
- var _cancelPendingScrollT2, _api$expand, _api$expand$commands;
183
- (_cancelPendingScrollT2 = cancelPendingScrollToDecoration) === null || _cancelPendingScrollT2 === void 0 ? void 0 : _cancelPendingScrollT2();
184
- const scrollableDecorations = getScrollableDecorations(pluginState.decorations, view.state.doc);
185
- const activeDecoration = scrollableDecorations[pluginState.activeIndex];
186
- if (activeDecoration && api !== null && api !== void 0 && (_api$expand = api.expand) !== null && _api$expand !== void 0 && (_api$expand$commands = _api$expand.commands) !== null && _api$expand$commands !== void 0 && _api$expand$commands.toggleExpandRange && fg('platform_editor_show_diff_scroll_navigation')) {
187
- api === null || api === void 0 ? void 0 : api.core.actions.execute(api.expand.commands.toggleExpandRange(activeDecoration.from, activeDecoration.to, true));
188
- }
189
- cancelPendingScrollToDecoration = scrollToActiveDecoration(view, scrollableDecorations, pluginState.activeIndex);
175
+ const activeIndexChanged = (pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex) !== undefined && pluginState.activeIndex !== previousActiveIndex;
176
+ previousActiveIndex = pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex;
177
+ if ((pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex) !== undefined && activeIndexChanged) {
178
+ var _cancelPendingScrollT2, _api$expand, _api$expand$commands;
179
+ (_cancelPendingScrollT2 = cancelPendingScrollToDecoration) === null || _cancelPendingScrollT2 === void 0 ? void 0 : _cancelPendingScrollT2();
180
+ const scrollableDecorations = getScrollableDecorations(pluginState.decorations, view.state.doc);
181
+ const activeDecoration = scrollableDecorations[pluginState.activeIndex];
182
+ if (activeDecoration && api !== null && api !== void 0 && (_api$expand = api.expand) !== null && _api$expand !== void 0 && (_api$expand$commands = _api$expand.commands) !== null && _api$expand$commands !== void 0 && _api$expand$commands.toggleExpandRange) {
183
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(api.expand.commands.toggleExpandRange(activeDecoration.from, activeDecoration.to, true));
190
184
  }
185
+ cancelPendingScrollToDecoration = scrollToActiveDecoration(view, scrollableDecorations, pluginState.activeIndex);
191
186
  }
192
187
  },
193
188
  destroy() {
@@ -1,4 +1,3 @@
1
- import { fg } from '@atlaskit/platform-feature-flags';
2
1
  import { getScrollableDecorations } from './pm-plugins/getScrollableDecorations';
3
2
  import { createPlugin, showDiffPluginKey } from './pm-plugins/main';
4
3
  export const showDiffPlugin = ({
@@ -47,7 +46,6 @@ export const showDiffPlugin = ({
47
46
  }];
48
47
  },
49
48
  getSharedState: editorState => {
50
- var _pluginState$decorati;
51
49
  if (!editorState) {
52
50
  return {
53
51
  isDisplayingChanges: false,
@@ -55,7 +53,7 @@ export const showDiffPlugin = ({
55
53
  };
56
54
  }
57
55
  const pluginState = showDiffPluginKey.getState(editorState);
58
- const decorationCount = fg('platform_editor_show_diff_scroll_navigation') ? getScrollableDecorations(pluginState === null || pluginState === void 0 ? void 0 : pluginState.decorations, editorState.doc) : (pluginState === null || pluginState === void 0 ? void 0 : (_pluginState$decorati = pluginState.decorations) === null || _pluginState$decorati === void 0 ? void 0 : _pluginState$decorati.find()) || [];
56
+ const decorationCount = getScrollableDecorations(pluginState === null || pluginState === void 0 ? void 0 : pluginState.decorations, editorState.doc);
59
57
  return {
60
58
  isDisplayingChanges: decorationCount.length > 0,
61
59
  activeIndex: pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex,
@@ -1,5 +1,4 @@
1
1
  import { Transform } from '@atlaskit/editor-prosemirror/transform';
2
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
3
2
 
4
3
  /**
5
4
  * Returns a copy of the document with all marks removed from all text.
@@ -42,13 +41,10 @@ export function areDocsEqualByBlockStructureAndText(doc1, doc2) {
42
41
  if (doc1.textContent !== doc2.textContent) {
43
42
  return false;
44
43
  }
45
- if (expValEquals('platform_editor_show_diff_improvements', 'isEnabled', true)) {
46
- // Strip marks before comparing so that mark-driven text fragmentation
47
- // (e.g. annotation mark reordering producing different childCounts) does not
48
- // cause false inequalities.
49
- var stripped1 = stripMarks(doc1);
50
- var stripped2 = stripMarks(doc2);
51
- return doc1.nodeSize === doc2.nodeSize && isBlockStructureEqual(stripped1, stripped2);
52
- }
53
- return doc1.nodeSize === doc2.nodeSize && isBlockStructureEqual(doc1, doc2);
44
+ // Strip marks before comparing so that mark-driven text fragmentation
45
+ // (e.g. annotation mark reordering producing different childCounts) does not
46
+ // cause false inequalities.
47
+ var stripped1 = stripMarks(doc1);
48
+ var stripped2 = stripMarks(doc2);
49
+ return doc1.nodeSize === doc2.nodeSize && isBlockStructureEqual(stripped1, stripped2);
54
50
  }
@@ -12,7 +12,6 @@ import memoizeOne from 'memoize-one';
12
12
  import { ChangeSet, simplifyChanges } from 'prosemirror-changeset';
13
13
  import { areNodesEqualIgnoreAttrs } from '@atlaskit/editor-common/utils/document';
14
14
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
15
- import { fg } from '@atlaskit/platform-feature-flags';
16
15
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
17
16
  import { areDocsEqualByBlockStructureAndText } from '../areDocsEqualByBlockStructureAndText';
18
17
  import { createBlockChangedDecoration } from '../decorations/createBlockChangedDecoration';
@@ -125,25 +124,19 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
125
124
  _iterator.f();
126
125
  }
127
126
  if (!areNodesEqualIgnoreAttrs(steppedDoc, tr.doc)) {
128
- var recoveredViaContentEquality = fg('platform_editor_show_diff_equality_fallback') ? areDocsEqualByBlockStructureAndText(steppedDoc, tr.doc) : undefined;
129
- if (expValEquals('platform_editor_are_nodes_equal_ignore_mark_order', 'isEnabled', true)) {
130
- var _api$analytics;
131
- api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
132
- eventType: 'track',
133
- action: 'nodesNotEqual',
134
- actionSubject: 'showDiff',
135
- attributes: {
136
- docSizeEqual: steppedDoc.nodeSize === tr.doc.nodeSize,
137
- colorScheme: colorScheme,
138
- recoveredViaContentEquality: recoveredViaContentEquality
139
- }
140
- });
141
- }
142
- if (fg('platform_editor_show_diff_equality_fallback')) {
143
- if (!recoveredViaContentEquality) {
144
- return DecorationSet.empty;
127
+ var _api$analytics;
128
+ var recoveredViaContentEquality = areDocsEqualByBlockStructureAndText(steppedDoc, tr.doc);
129
+ api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
130
+ eventType: 'track',
131
+ action: 'nodesNotEqual',
132
+ actionSubject: 'showDiff',
133
+ attributes: {
134
+ docSizeEqual: steppedDoc.nodeSize === tr.doc.nodeSize,
135
+ colorScheme: colorScheme,
136
+ recoveredViaContentEquality: recoveredViaContentEquality
145
137
  }
146
- } else {
138
+ });
139
+ if (!recoveredViaContentEquality) {
147
140
  return DecorationSet.empty;
148
141
  }
149
142
  }
@@ -215,7 +208,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
215
208
  }));
216
209
  });
217
210
  getAttrChangeRanges(tr.doc, attrSteps).forEach(function (change) {
218
- if (expValEquals('platform_editor_show_diff_improvements', 'isEnabled', true) && change.isInline) {
211
+ if (change.isInline) {
219
212
  // Inline nodes (e.g. date) need an inline decoration rather than a block decoration
220
213
  var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
221
214
  decorations.push(createInlineChangedDecoration({
@@ -13,6 +13,107 @@ var mapPosition = function mapPosition(mapping, pos) {
13
13
  return mapping.map(pos);
14
14
  };
15
15
 
16
+ /**
17
+ * Given a ProseMirror doc and a position range [from, to], expand
18
+ * both endpoints outward to the nearest word boundaries.
19
+ *
20
+ * A "word character" is any non-whitespace, non-punctuation character, plus hyphen.
21
+ * This covers accented/Unicode letters (e.g. é, ñ, ü) while still stopping at
22
+ * commas, periods, and other punctuation. Hyphens are explicitly included so that
23
+ * hyphenated words (e.g. "deep-sea") are treated as a single word.
24
+ * Expansion stops at whitespace, punctuation (excluding hyphen), or the textblock edges.
25
+ *
26
+ * If `from` and `to` resolve into different parent nodes, or if the
27
+ * parent is not a textblock, the range is returned unchanged.
28
+ */
29
+ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
30
+ var $from = doc.resolve(from);
31
+
32
+ // Only expand inside a textblock.
33
+ if (!$from.parent.isTextblock) {
34
+ return {
35
+ from: from,
36
+ to: to
37
+ };
38
+ }
39
+
40
+ // When `from !== to`, verify both ends are in the same textblock.
41
+ if (from !== to) {
42
+ var $to = doc.resolve(to);
43
+ if ($from.parent !== $to.parent) {
44
+ return {
45
+ from: from,
46
+ to: to
47
+ };
48
+ }
49
+ }
50
+ var parent = $from.parent;
51
+ var text = parent.textContent;
52
+ var parentStart = $from.start(); // absolute position of the first character in the textblock
53
+
54
+ // Convert absolute doc positions to zero-based string indices.
55
+ var fromIdx = from - parentStart;
56
+ var toIdx = to - parentStart;
57
+
58
+ // any non whitespace and non punctuation chars
59
+ // @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
60
+ var isWordChar = function isWordChar(ch) {
61
+ return /(?:[\x2D0-9A-Z_a-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088F\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5C\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDC-\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C8A\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7DC\uA7F1-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDDC0-\uDDF3\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD40-\uDD59\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDD40-\uDD65\uDD6F-\uDD85\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDEC2-\uDEC7\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE3F\uDE40\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61\uDF80-\uDF89\uDF8B\uDF8E\uDF90-\uDFB5\uDFB7\uDFD1\uDFD3]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDED0-\uDEE3\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8\uDFC0-\uDFE0\uDFF0-\uDFF9]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDDB0-\uDDDB\uDDE0-\uDDE9\uDEE0-\uDEF2\uDF02\uDF04-\uDF10\uDF12-\uDF33\uDF50-\uDF59\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD80E\uD80F\uD81C-\uD822\uD840-\uD868\uD86A-\uD86D\uD86F-\uD872\uD874-\uD879\uD880-\uD883\uD885-\uD88C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F\uDC41-\uDC46\uDC60-\uDFFF]|\uD810[\uDC00-\uDFFA]|\uD811[\uDC00-\uDE46]|\uD818[\uDD00-\uDD1D\uDD30-\uDD39]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDD40-\uDD6C\uDD70-\uDD79\uDE40-\uDE96\uDEA0-\uDEB8\uDEBB-\uDED3\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3\uDFF2-\uDFF6]|\uD823[\uDC00-\uDCD5\uDCFF-\uDD1E\uDD80-\uDDF2]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD32\uDD50-\uDD52\uDD55\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD833[\uDCF0-\uDCF9]|\uD834[\uDEC0-\uDED3\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E\uDF25-\uDF2A]|\uD838[\uDC30-\uDC6D\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDCD0-\uDCEB\uDCF0-\uDCF9\uDDD0-\uDDED\uDDF0-\uDDFA\uDEC0-\uDEDE\uDEE0-\uDEE2\uDEE4\uDEE5\uDEE7-\uDEED\uDEF0-\uDEF4\uDEFE\uDEFF\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEAD\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0\uDFF0-\uDFFF]|\uD87B[\uDC00-\uDE5D]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A\uDF50-\uDFFF]|\uD88D[\uDC00-\uDC79])/.test(ch);
62
+ };
63
+
64
+ // Detect whether the position sits mid-word: there is a word character
65
+ // on both sides of the position (or, for a non-empty range, on the
66
+ // outer side of each endpoint).
67
+ var isMidWord = function isMidWord(idx) {
68
+ return idx > 0 && idx < text.length && isWordChar(text[idx - 1]) && isWordChar(text[idx]);
69
+ };
70
+
71
+ // For a zero-width range (pure insertion / deletion point), only expand
72
+ // if the point is mid-word — i.e. both the char before and after are
73
+ // word characters. Otherwise the point is already at a word boundary.
74
+ if (from === to) {
75
+ if (!isMidWord(fromIdx)) {
76
+ return {
77
+ from: from,
78
+ to: to
79
+ };
80
+ }
81
+ // Expand both directions from the mid-word point.
82
+ while (fromIdx > 0 && isWordChar(text[fromIdx - 1])) {
83
+ fromIdx--;
84
+ }
85
+ while (toIdx < text.length && isWordChar(text[toIdx])) {
86
+ toIdx++;
87
+ }
88
+ return {
89
+ from: parentStart + fromIdx,
90
+ to: parentStart + toIdx
91
+ };
92
+ }
93
+
94
+ // Non-empty range: expand each endpoint outward if it is mid-word.
95
+
96
+ // Expand left only if `from` is truly mid-word: the character at `from`
97
+ // (inside the range) and the character before `from` are both word chars.
98
+ if (fromIdx > 0 && fromIdx < text.length && isWordChar(text[fromIdx]) && isWordChar(text[fromIdx - 1])) {
99
+ while (fromIdx > 0 && isWordChar(text[fromIdx - 1])) {
100
+ fromIdx--;
101
+ }
102
+ }
103
+
104
+ // Expand right only if `to` is truly mid-word: the character just before
105
+ // `to` (last char of the range) and the character at `to` are both word chars.
106
+ if (toIdx > 0 && toIdx < text.length && isWordChar(text[toIdx - 1]) && isWordChar(text[toIdx])) {
107
+ while (toIdx < text.length && isWordChar(text[toIdx])) {
108
+ toIdx++;
109
+ }
110
+ }
111
+ return {
112
+ from: parentStart + fromIdx,
113
+ to: parentStart + toIdx
114
+ };
115
+ };
116
+
16
117
  /**
17
118
  * Compare marks between two nodes
18
119
  * We have to check each child because adding a mark splits text into multiple nodes
@@ -179,10 +280,46 @@ export var diffBySteps = function diffBySteps(originalDoc, steps) {
179
280
  try {
180
281
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
181
282
  var granularChange = _step3.value;
182
- var granularFromA = mapPosition(beforeStepToOriginal, granularChange.fromA);
183
- var granularToA = mapPosition(beforeStepToOriginal, granularChange.toA);
184
- var granularFromB = mapPosition(afterStepToFinal, granularChange.fromB);
185
- var granularToB = mapPosition(afterStepToFinal, granularChange.toB);
283
+ // Expand each granular change to the nearest word boundaries in
284
+ // both the pre-step doc (A-side) and the post-step doc (B-side).
285
+ // This ensures that a mid-word edit like "sanitised" → "sanitized"
286
+ // shows as deleting the whole original word and inserting the whole
287
+ // new word, rather than a single-character swap.
288
+ var expandedA = expandToWordBoundaries(rangedStep.before, granularChange.fromA, granularChange.toA);
289
+ var expandedB = expandToWordBoundaries(rangedStep.doc, granularChange.fromB, granularChange.toB);
290
+
291
+ // When one side expanded further than the other (e.g. a space
292
+ // was inserted mid-word: "altogether" → "all together"), the
293
+ // less-expanded side must grow to match — otherwise the renderer
294
+ // shows a partial word as plain text next to a deletion/insertion.
295
+ // We compare left and right deltas independently so partial
296
+ // expansion on one side doesn't prevent the other side from
297
+ // being pulled out further.
298
+ var aLeftDelta = granularChange.fromA - expandedA.from;
299
+ var aRightDelta = expandedA.to - granularChange.toA;
300
+ var bLeftDelta = granularChange.fromB - expandedB.from;
301
+ var bRightDelta = expandedB.to - granularChange.toB;
302
+ var finalA = expandedA;
303
+ var finalB = expandedB;
304
+
305
+ // If A expanded further on either side, nudge B outward
306
+ // by the excess and re-expand to snap to word boundaries.
307
+ if (aLeftDelta > bLeftDelta || aRightDelta > bRightDelta) {
308
+ var extraLeft = Math.max(0, aLeftDelta - bLeftDelta);
309
+ var extraRight = Math.max(0, aRightDelta - bRightDelta);
310
+ finalB = expandToWordBoundaries(rangedStep.doc, Math.max(expandedB.from - extraLeft, 0), expandedB.to + extraRight);
311
+ }
312
+
313
+ // If B expanded further on either side, nudge A outward.
314
+ if (bLeftDelta > aLeftDelta || bRightDelta > aRightDelta) {
315
+ var _extraLeft = Math.max(0, bLeftDelta - aLeftDelta);
316
+ var _extraRight = Math.max(0, bRightDelta - aRightDelta);
317
+ finalA = expandToWordBoundaries(rangedStep.before, Math.max(expandedA.from - _extraLeft, 0), expandedA.to + _extraRight);
318
+ }
319
+ var granularFromA = mapPosition(beforeStepToOriginal, finalA.from);
320
+ var granularToA = mapPosition(beforeStepToOriginal, finalA.to);
321
+ var granularFromB = mapPosition(afterStepToFinal, finalB.from);
322
+ var granularToB = mapPosition(afterStepToFinal, finalB.to);
186
323
  changes.push({
187
324
  fromA: granularFromA,
188
325
  toA: granularToA,
@@ -1,10 +1,8 @@
1
- import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
1
  import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
3
2
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
4
- import { fg } from '@atlaskit/platform-feature-flags';
5
3
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
4
  import { standardDecorationMarkerVariable, editingStyleQuoteNode, editingStyleRuleNode, editingStyleCardBlockNode, editingStyleNode, deletedContentStyleNew, deletedStyleQuoteNode, addedCellOverlayStyle, deletedCellOverlayStyle } from './colorSchemes/standard';
7
- import { traditionalDecorationMarkerVariable, traditionalDecorationMarkerVariableActive, traditionalDecorationMarkerVariableNew, traditionalDeletedDecorationMarkerVariable, traditionalDeletedDecorationMarkerVariableActive, traditionalDeletedDecorationMarkerVariableNew, traditionalStyleQuoteNode, traditionalStyleQuoteNodeActive, traditionalStyleQuoteNodeNew, traditionalStyleRuleNode, traditionalStyleRuleNodeActive, traditionalStyleRuleNodeNew, traditionalStyleCardBlockNode, traditionalStyleCardBlockNodeActive, traditionalStyleCardBlockNodeNew, traditionalStyleNode, traditionalStyleNodeActive, traditionalStyleNodeNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, traditionalAddedCellOverlayStyle, deletedTraditionalCellOverlayStyle } from './colorSchemes/traditional';
5
+ import { traditionalDecorationMarkerVariableActive, traditionalDecorationMarkerVariableNew, traditionalDeletedDecorationMarkerVariableActive, traditionalDeletedDecorationMarkerVariableNew, traditionalStyleQuoteNodeActive, traditionalStyleQuoteNodeNew, traditionalStyleRuleNodeActive, traditionalStyleRuleNodeNew, traditionalStyleCardBlockNodeActive, traditionalStyleCardBlockNodeNew, traditionalStyleNodeActive, traditionalStyleNodeNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, traditionalAddedCellOverlayStyle, deletedTraditionalCellOverlayStyle } from './colorSchemes/traditional';
8
6
  var displayNoneStyle = convertToInlineCss({
9
7
  display: 'none'
10
8
  });
@@ -28,7 +26,7 @@ var getBlockNodeStyle = function getBlockNodeStyle(_ref) {
28
26
  // Handle table separately to avoid border issues
29
27
  'tableRow', 'paragraph',
30
28
  // Paragraph and heading nodes do not need special styling
31
- 'heading', 'hardBreak', 'decisionList', 'taskList'].concat(_toConsumableArray(expValEquals('platform_editor_show_diff_improvements', 'isEnabled', true) ? [] : ['taskItem']), ['bulletList', 'orderedList', 'layoutSection']).includes(nodeName)) {
29
+ 'heading', 'hardBreak', 'decisionList', 'taskList', 'bulletList', 'orderedList', 'layoutSection'].includes(nodeName)) {
32
30
  // Layout nodes do not need special styling
33
31
  return undefined;
34
32
  }
@@ -45,51 +43,51 @@ var getBlockNodeStyle = function getBlockNodeStyle(_ref) {
45
43
  if (['extension', 'embedCard', 'listItem'].includes(nodeName)) {
46
44
  if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
47
45
  if (isInserted) {
48
- return isTraditional && isActive ? traditionalDecorationMarkerVariableActive : isTraditional ? fg('platform_editor_show_diff_scroll_navigation') ? traditionalDecorationMarkerVariableNew : traditionalDecorationMarkerVariable : standardDecorationMarkerVariable;
46
+ return isTraditional && isActive ? traditionalDecorationMarkerVariableActive : isTraditional ? traditionalDecorationMarkerVariableNew : standardDecorationMarkerVariable;
49
47
  } else {
50
- return isTraditional && isActive ? traditionalDeletedDecorationMarkerVariableActive : isTraditional ? fg('platform_editor_show_diff_scroll_navigation') ? traditionalDeletedDecorationMarkerVariableNew : traditionalDeletedDecorationMarkerVariable : deletedContentStyleNew;
48
+ return isTraditional && isActive ? traditionalDeletedDecorationMarkerVariableActive : isTraditional ? traditionalDeletedDecorationMarkerVariableNew : deletedContentStyleNew;
51
49
  }
52
50
  }
53
- return isTraditional && isActive ? traditionalDecorationMarkerVariableActive : isTraditional ? fg('platform_editor_show_diff_scroll_navigation') ? traditionalDecorationMarkerVariableNew : traditionalDecorationMarkerVariable : standardDecorationMarkerVariable;
51
+ return isTraditional && isActive ? traditionalDecorationMarkerVariableActive : isTraditional ? traditionalDecorationMarkerVariableNew : standardDecorationMarkerVariable;
54
52
  }
55
53
  if (nodeName === 'blockquote') {
56
54
  if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
57
55
  if (isInserted) {
58
- return isTraditional ? isActive ? traditionalStyleQuoteNodeActive : fg('platform_editor_show_diff_scroll_navigation') ? traditionalStyleQuoteNodeNew : traditionalStyleQuoteNode : editingStyleQuoteNode;
56
+ return isTraditional ? isActive ? traditionalStyleQuoteNodeActive : traditionalStyleQuoteNodeNew : editingStyleQuoteNode;
59
57
  } else {
60
58
  return isTraditional ? deletedTraditionalStyleQuoteNode : deletedStyleQuoteNode;
61
59
  }
62
60
  }
63
- return isTraditional ? isActive ? traditionalStyleQuoteNodeActive : fg('platform_editor_show_diff_scroll_navigation') ? traditionalStyleQuoteNodeNew : traditionalStyleQuoteNode : editingStyleQuoteNode;
61
+ return isTraditional ? isActive ? traditionalStyleQuoteNodeActive : traditionalStyleQuoteNodeNew : editingStyleQuoteNode;
64
62
  }
65
63
  if (nodeName === 'rule') {
66
64
  if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
67
65
  if (isInserted) {
68
- return isTraditional ? isActive ? traditionalStyleRuleNodeActive : fg('platform_editor_show_diff_scroll_navigation') ? traditionalStyleRuleNodeNew : traditionalStyleRuleNode : editingStyleRuleNode;
66
+ return isTraditional ? isActive ? traditionalStyleRuleNodeActive : traditionalStyleRuleNodeNew : editingStyleRuleNode;
69
67
  } else {
70
68
  return isTraditional ? getDeletedTraditionalInlineStyle(false) : deletedContentStyleNew;
71
69
  }
72
70
  }
73
- return isTraditional ? isActive ? traditionalStyleRuleNodeActive : fg('platform_editor_show_diff_scroll_navigation') ? traditionalStyleRuleNodeNew : traditionalStyleRuleNode : editingStyleRuleNode;
71
+ return isTraditional ? isActive ? traditionalStyleRuleNodeActive : traditionalStyleRuleNodeNew : editingStyleRuleNode;
74
72
  }
75
73
  if (nodeName === 'blockCard') {
76
74
  if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
77
75
  if (isInserted) {
78
- return isTraditional ? isActive ? traditionalStyleCardBlockNodeActive : fg('platform_editor_show_diff_scroll_navigation') ? traditionalStyleCardBlockNodeNew : traditionalStyleCardBlockNode : editingStyleCardBlockNode;
76
+ return isTraditional ? isActive ? traditionalStyleCardBlockNodeActive : traditionalStyleCardBlockNodeNew : editingStyleCardBlockNode;
79
77
  } else {
80
78
  return isTraditional ? getDeletedTraditionalInlineStyle(false) : deletedContentStyleNew;
81
79
  }
82
80
  }
83
- return isTraditional ? isActive ? traditionalStyleCardBlockNodeActive : fg('platform_editor_show_diff_scroll_navigation') ? traditionalStyleCardBlockNodeNew : traditionalStyleCardBlockNode : editingStyleCardBlockNode;
81
+ return isTraditional ? isActive ? traditionalStyleCardBlockNodeActive : traditionalStyleCardBlockNodeNew : editingStyleCardBlockNode;
84
82
  }
85
83
  if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
86
84
  if (isInserted) {
87
- return isTraditional ? isActive ? traditionalStyleNodeActive : fg('platform_editor_show_diff_scroll_navigation') ? traditionalStyleNodeNew : traditionalStyleNode : editingStyleNode;
85
+ return isTraditional ? isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew : editingStyleNode;
88
86
  } else {
89
87
  return isTraditional ? getDeletedTraditionalInlineStyle(false) : deletedContentStyleNew;
90
88
  }
91
89
  }
92
- return isTraditional ? isActive ? traditionalStyleNodeActive : fg('platform_editor_show_diff_scroll_navigation') ? traditionalStyleNodeNew : traditionalStyleNode : editingStyleNode;
90
+ return isTraditional ? isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew : editingStyleNode;
93
91
  };
94
92
 
95
93
  /**
@@ -144,18 +142,7 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
144
142
  });
145
143
  }
146
144
  var className = getNodeClass(change.name);
147
- if (fg('platform_editor_show_diff_scroll_navigation')) {
148
- if (style || className) {
149
- decorations.push(Decoration.node(change.from, change.to, {
150
- style: style,
151
- 'data-testid': 'show-diff-changed-decoration-node',
152
- class: className
153
- }, {
154
- key: 'diff-block',
155
- nodeName: change.name
156
- }));
157
- }
158
- } else {
145
+ if (style || className) {
159
146
  decorations.push(Decoration.node(change.from, change.to, {
160
147
  style: style,
161
148
  'data-testid': 'show-diff-changed-decoration-node',
@@ -4,7 +4,6 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
4
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
5
  import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
6
6
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
7
- import { fg } from '@atlaskit/platform-feature-flags';
8
7
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
9
8
  import { editingStyle, editingStyleActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleUnbounded, deletedInlineContentBackground } from './colorSchemes/standard';
10
9
  import { traditionalInsertStyle, traditionalInsertStyleActive, getDeletedTraditionalInlineStyle, deletedTraditionalContentStyleUnbounded, deletedTraditionalContentStyleUnboundedActive } from './colorSchemes/traditional';
@@ -49,21 +48,6 @@ var getDeletedContentStyle = function getDeletedContentStyle(colorScheme) {
49
48
  return expValEquals('platform_editor_enghealth_a11y_jan_fixes', 'isEnabled', true) ? deletedContentStyleNew : deletedContentStyle;
50
49
  };
51
50
 
52
- /**
53
- * Wraps content with deleted styling without opacity (for use when content is a direct child of dom)
54
- */
55
- var createDeletedStyleWrapperWithoutOpacity = function createDeletedStyleWrapperWithoutOpacity(colorScheme, isActive) {
56
- var wrapper = document.createElement('span');
57
- if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
58
- wrapper.setAttribute('style',
59
- // Merge into existing styles when cleaning up
60
- getDeletedContentStyle(colorScheme, isActive) + deletedInlineContentBackground);
61
- } else {
62
- wrapper.setAttribute('style', getDeletedContentStyle(colorScheme, isActive));
63
- }
64
- return wrapper;
65
- };
66
-
67
51
  /**
68
52
  * CSS backgrounds don't work when applied to a wrapper around a paragraph, so
69
53
  * the wrapper needs to be injected inside the node around the child content
@@ -124,7 +108,7 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
124
108
  _ref2$isInserted = _ref2.isInserted,
125
109
  isInserted = _ref2$isInserted === void 0 ? false : _ref2$isInserted;
126
110
  var slice = doc.slice(change.fromA, change.toA);
127
- var shouldSkipDeletedEmptyParagraphDecoration = !isInserted && (slice === null || slice === void 0 || (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.childCount) === 1 && (slice === null || slice === void 0 || (_slice$content2 = slice.content) === null || _slice$content2 === void 0 || (_slice$content2 = _slice$content2.firstChild) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.type.name) === 'paragraph' && (slice === null || slice === void 0 || (_slice$content3 = slice.content) === null || _slice$content3 === void 0 || (_slice$content3 = _slice$content3.firstChild) === null || _slice$content3 === void 0 ? void 0 : _slice$content3.content.size) === 0 && fg('platform_editor_show_diff_scroll_navigation');
111
+ var shouldSkipDeletedEmptyParagraphDecoration = !isInserted && (slice === null || slice === void 0 || (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.childCount) === 1 && (slice === null || slice === void 0 || (_slice$content2 = slice.content) === null || _slice$content2 === void 0 || (_slice$content2 = _slice$content2.firstChild) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.type.name) === 'paragraph' && (slice === null || slice === void 0 || (_slice$content3 = slice.content) === null || _slice$content3 === void 0 || (_slice$content3 = _slice$content3.firstChild) === null || _slice$content3 === void 0 ? void 0 : _slice$content3.content.size) === 0;
128
112
  // Widget decoration used for deletions as the content is not in the document
129
113
  // and we want to display the deleted content with a style.
130
114
  var safeInsertPos = findSafeInsertPos(newDoc, change.fromB, slice);
@@ -247,24 +231,18 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
247
231
  } else {
248
232
  var fallbackNode = fallbackSerialization();
249
233
  if (fallbackNode) {
250
- if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) || fg('platform_editor_show_diff_scroll_navigation')) {
251
- if (fallbackNode instanceof HTMLElement) {
252
- var injectedNode = injectInnerWrapper({
253
- node: fallbackNode,
254
- colorScheme: colorScheme,
255
- isActive: isActive,
256
- isInserted: isInserted
257
- });
258
- dom.append(injectedNode);
259
- } else {
260
- var _wrapper2 = createContentWrapper(colorScheme, isActive, isInserted);
261
- _wrapper2.append(fallbackNode);
262
- dom.append(_wrapper2);
263
- }
234
+ if (fallbackNode instanceof HTMLElement) {
235
+ var injectedNode = injectInnerWrapper({
236
+ node: fallbackNode,
237
+ colorScheme: colorScheme,
238
+ isActive: isActive,
239
+ isInserted: isInserted
240
+ });
241
+ dom.append(injectedNode);
264
242
  } else {
265
- var _wrapper3 = createDeletedStyleWrapperWithoutOpacity(colorScheme, isActive);
266
- _wrapper3.append(fallbackNode);
267
- dom.append(_wrapper3);
243
+ var _wrapper2 = createContentWrapper(colorScheme, isActive, isInserted);
244
+ _wrapper2.append(fallbackNode);
245
+ dom.append(_wrapper2);
268
246
  }
269
247
  }
270
248
  }