@atlaskit/editor-plugin-show-diff 3.1.5 → 3.2.1

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 (30) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/afm-cc/tsconfig.json +6 -0
  3. package/afm-jira/tsconfig.json +3 -0
  4. package/afm-products/tsconfig.json +3 -0
  5. package/dist/cjs/pm-plugins/calculateDiffDecorations.js +12 -7
  6. package/dist/cjs/pm-plugins/decorations.js +242 -10
  7. package/dist/cjs/pm-plugins/deletedRowsHandler.js +214 -0
  8. package/dist/cjs/pm-plugins/main.js +6 -5
  9. package/dist/cjs/showDiffPlugin.js +4 -3
  10. package/dist/es2019/pm-plugins/calculateDiffDecorations.js +12 -7
  11. package/dist/es2019/pm-plugins/decorations.js +238 -9
  12. package/dist/es2019/pm-plugins/deletedRowsHandler.js +185 -0
  13. package/dist/es2019/pm-plugins/main.js +4 -3
  14. package/dist/es2019/showDiffPlugin.js +4 -2
  15. package/dist/esm/pm-plugins/calculateDiffDecorations.js +12 -7
  16. package/dist/esm/pm-plugins/decorations.js +242 -10
  17. package/dist/esm/pm-plugins/deletedRowsHandler.js +207 -0
  18. package/dist/esm/pm-plugins/main.js +4 -3
  19. package/dist/esm/showDiffPlugin.js +4 -3
  20. package/dist/types/pm-plugins/calculateDiffDecorations.d.ts +3 -1
  21. package/dist/types/pm-plugins/decorations.d.ts +4 -2
  22. package/dist/types/pm-plugins/deletedRowsHandler.d.ts +30 -0
  23. package/dist/types/pm-plugins/main.d.ts +2 -1
  24. package/dist/types-ts4.5/pm-plugins/calculateDiffDecorations.d.ts +3 -1
  25. package/dist/types-ts4.5/pm-plugins/decorations.d.ts +4 -2
  26. package/dist/types-ts4.5/pm-plugins/deletedRowsHandler.d.ts +30 -0
  27. package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -1
  28. package/package.json +13 -3
  29. package/afm-post-office/tsconfig.json +0 -27
  30. package/afm-townsquare/tsconfig.json +0 -27
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaskit/editor-plugin-show-diff
2
2
 
3
+ ## 3.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`da2782d8dc1e7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/da2782d8dc1e7) -
8
+ Support table row diff displaying in the editor
9
+
10
+ ## 3.2.0
11
+
12
+ ### Minor Changes
13
+
14
+ - [`68caaf98e8f89`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/68caaf98e8f89) -
15
+ [ux] [EDITOR-1628] Added "Removed" Lozenge and gray border decorations to deleted block nodes in
16
+ show diff view
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies
21
+
3
22
  ## 3.1.5
4
23
 
5
24
  ### Patch Changes
@@ -17,6 +17,12 @@
17
17
  "../src/**/examples.*"
18
18
  ],
19
19
  "references": [
20
+ {
21
+ "path": "../../editor-tables/afm-cc/tsconfig.json"
22
+ },
23
+ {
24
+ "path": "../../../platform/feature-flags/afm-cc/tsconfig.json"
25
+ },
20
26
  {
21
27
  "path": "../../../design-system/tokens/afm-cc/tsconfig.json"
22
28
  },
@@ -17,6 +17,9 @@
17
17
  "../src/**/examples.*"
18
18
  ],
19
19
  "references": [
20
+ {
21
+ "path": "../../../platform/feature-flags/afm-jira/tsconfig.json"
22
+ },
20
23
  {
21
24
  "path": "../../../design-system/tokens/afm-jira/tsconfig.json"
22
25
  },
@@ -17,6 +17,9 @@
17
17
  "../src/**/examples.*"
18
18
  ],
19
19
  "references": [
20
+ {
21
+ "path": "../../../platform/feature-flags/afm-products/tsconfig.json"
22
+ },
20
23
  {
21
24
  "path": "../../../design-system/tokens/afm-products/tsconfig.json"
22
25
  },
@@ -95,7 +95,8 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref)
95
95
  var state = _ref.state,
96
96
  pluginState = _ref.pluginState,
97
97
  nodeViewSerializer = _ref.nodeViewSerializer,
98
- colourScheme = _ref.colourScheme;
98
+ colourScheme = _ref.colourScheme,
99
+ intl = _ref.intl;
99
100
  var originalDoc = pluginState.originalDoc,
100
101
  rawSteps = pluginState.steps;
101
102
  var steps = simplifySteps(rawSteps);
@@ -105,6 +106,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref)
105
106
  var tr = state.tr;
106
107
  var steppedDoc = originalDoc;
107
108
  var stepMaps = [];
109
+ var changeset = _prosemirrorChangeset.ChangeSet.create(originalDoc);
108
110
  var _iterator = _createForOfIteratorHelper(steps),
109
111
  _step;
110
112
  try {
@@ -114,6 +116,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref)
114
116
  if (result.failed === null && result.doc) {
115
117
  steppedDoc = result.doc;
116
118
  stepMaps.push(step.getMap());
119
+ changeset = changeset.addSteps(steppedDoc, [step.getMap()], step);
117
120
  }
118
121
  }
119
122
 
@@ -127,7 +130,6 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref)
127
130
  if (!(0, _document.areNodesEqualIgnoreAttrs)(steppedDoc, tr.doc)) {
128
131
  return _view.DecorationSet.empty;
129
132
  }
130
- var changeset = _prosemirrorChangeset.ChangeSet.create(originalDoc).addSteps(steppedDoc, stepMaps, tr.doc);
131
133
  var changes = (0, _prosemirrorChangeset.simplifyChanges)(changeset.changes, tr.doc);
132
134
  var optimizedChanges = optimizeChanges(changes);
133
135
  var decorations = [];
@@ -142,10 +144,11 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref)
142
144
  doc: originalDoc,
143
145
  nodeViewSerializer: nodeViewSerializer,
144
146
  colourScheme: colourScheme,
145
- newDoc: tr.doc
147
+ newDoc: tr.doc,
148
+ intl: intl
146
149
  });
147
150
  if (decoration) {
148
- decorations.push(decoration);
151
+ decorations.push.apply(decorations, (0, _toConsumableArray2.default)(decoration));
149
152
  }
150
153
  }
151
154
  });
@@ -165,12 +168,14 @@ function (_ref2, _ref3) {
165
168
  _ref4$ = _ref4[0],
166
169
  pluginState = _ref4$.pluginState,
167
170
  state = _ref4$.state,
168
- colourScheme = _ref4$.colourScheme;
171
+ colourScheme = _ref4$.colourScheme,
172
+ intl = _ref4$.intl;
169
173
  var _ref5 = (0, _slicedToArray2.default)(_ref3, 1),
170
174
  _ref5$ = _ref5[0],
171
175
  lastPluginState = _ref5$.pluginState,
172
176
  lastState = _ref5$.state,
173
- lastColourScheme = _ref5$.colourScheme;
177
+ lastColourScheme = _ref5$.colourScheme,
178
+ lastIntl = _ref5$.intl;
174
179
  var originalDocIsSame = lastPluginState.originalDoc && pluginState.originalDoc && pluginState.originalDoc.eq(lastPluginState.originalDoc);
175
- return (_ref6 = originalDocIsSame && (0, _isEqual.default)(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && colourScheme === lastColourScheme) !== null && _ref6 !== void 0 ? _ref6 : false;
180
+ return (_ref6 = originalDocIsSame && (0, _isEqual.default)(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && colourScheme === lastColourScheme && intl.locale === lastIntl.locale) !== null && _ref6 !== void 0 ? _ref6 : false;
176
181
  });
@@ -5,7 +5,10 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.createInlineChangedDecoration = exports.createDeletedContentDecoration = exports.createBlockChangedDecoration = void 0;
7
7
  var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
8
+ var _messages = require("@atlaskit/editor-common/messages");
8
9
  var _view = require("@atlaskit/editor-prosemirror/view");
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
11
+ var _deletedRowsHandler = require("./deletedRowsHandler");
9
12
  var _findSafeInsertPos = require("./findSafeInsertPos");
10
13
  var editingStyle = (0, _lazyNodeView.convertToInlineCss)({
11
14
  background: "var(--ds-background-accent-purple-subtlest, #F3F0FF)",
@@ -76,6 +79,59 @@ var getEditorStyleNode = function getEditorStyleNode(nodeName, colourScheme) {
76
79
  return colourScheme === 'traditional' ? traditionalStyleNode : editingStyleNode;
77
80
  }
78
81
  };
82
+ var getDeletedStyleNode = function getDeletedStyleNode(nodeName) {
83
+ switch (nodeName) {
84
+ case 'blockquote':
85
+ return deletedStyleQuoteNode;
86
+ case 'expand':
87
+ case 'decisionList':
88
+ return deletedBlockOutline;
89
+ case 'panel':
90
+ case 'codeBlock':
91
+ return deletedBlockOutlineRounded;
92
+ default:
93
+ return undefined;
94
+ }
95
+ };
96
+ var shouldShowRemovedLozenge = function shouldShowRemovedLozenge(nodeName) {
97
+ switch (nodeName) {
98
+ case 'expand':
99
+ case 'codeBlock':
100
+ case 'mediaSingle':
101
+ case 'panel':
102
+ case 'decisionList':
103
+ return true;
104
+ default:
105
+ return false;
106
+ }
107
+ };
108
+ var shouldFitContentWidth = function shouldFitContentWidth(nodeName) {
109
+ switch (nodeName) {
110
+ case 'mediaSingle':
111
+ case 'embedCard':
112
+ case 'blockCard':
113
+ return true;
114
+ default:
115
+ return false;
116
+ }
117
+ };
118
+ var shouldAddShowDiffDeletedNodeClass = function shouldAddShowDiffDeletedNodeClass(nodeName) {
119
+ switch (nodeName) {
120
+ case 'mediaSingle':
121
+ case 'embedCard':
122
+ return true;
123
+ default:
124
+ return false;
125
+ }
126
+ };
127
+
128
+ /**
129
+ * Checks if a node should apply deleted styles directly without wrapper
130
+ * to preserve natural block-level margins
131
+ */
132
+ var shouldApplyDeletedStylesDirectly = function shouldApplyDeletedStylesDirectly(nodeName) {
133
+ return nodeName === 'blockquote' || nodeName === 'heading';
134
+ };
79
135
  var editingStyleQuoteNode = (0, _lazyNodeView.convertToInlineCss)({
80
136
  borderLeft: "2px solid ".concat("var(--ds-border-accent-purple, #8270DB)")
81
137
  });
@@ -104,6 +160,18 @@ var traditionalStyleCardBlockNode = (0, _lazyNodeView.convertToInlineCss)({
104
160
  boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-green, #22A06B)"),
105
161
  borderRadius: "var(--ds-radius-medium, 6px)"
106
162
  });
163
+ var deletedStyleQuoteNode = (0, _lazyNodeView.convertToInlineCss)({
164
+ borderLeft: "2px solid ".concat("var(--ds-border-accent-gray, #758195)")
165
+ });
166
+ var deletedBlockOutline = (0, _lazyNodeView.convertToInlineCss)({
167
+ boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-gray, #758195)"),
168
+ borderRadius: "var(--ds-radius-small, 4px)"
169
+ });
170
+ var deletedBlockOutlineRounded = (0, _lazyNodeView.convertToInlineCss)({
171
+ boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-gray, #758195)"),
172
+ borderRadius: "calc(".concat("var(--ds-radius-xsmall, 2px)", " + 1px)")
173
+ });
174
+
107
175
  /**
108
176
  * Inline decoration used for insertions as the content already exists in the document
109
177
  *
@@ -146,35 +214,181 @@ var deletedTraditionalContentStyleUnbounded = (0, _lazyNodeView.convertToInlineC
146
214
  pointerEvents: 'none',
147
215
  zIndex: 1
148
216
  });
217
+ var lozengeStyle = (0, _lazyNodeView.convertToInlineCss)({
218
+ display: 'inline-flex',
219
+ boxSizing: 'border-box',
220
+ position: 'static',
221
+ blockSize: 'min-content',
222
+ borderRadius: "var(--ds-radius-small, 4px)",
223
+ overflow: 'hidden',
224
+ paddingInlineStart: "var(--ds-space-050, 4px)",
225
+ paddingInlineEnd: "var(--ds-space-050, 4px)",
226
+ backgroundColor: "var(--ds-background-accent-gray-subtler, #DCDFE4)",
227
+ font: "var(--ds-font-body-small, normal 400 11px/16px ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, \"Helvetica Neue\", sans-serif)",
228
+ fontWeight: "var(--ds-font-weight-bold, 700)",
229
+ textOverflow: 'ellipsis',
230
+ whiteSpace: 'nowrap',
231
+ color: "var(--ds-text-warning-inverse, #172B4D)"
232
+ });
149
233
  var getDeletedContentStyleUnbounded = function getDeletedContentStyleUnbounded(colourScheme) {
150
234
  return colourScheme === 'traditional' ? deletedTraditionalContentStyleUnbounded : deletedContentStyleUnbounded;
151
235
  };
152
236
  var getDeletedContentStyle = function getDeletedContentStyle(colourScheme) {
153
237
  return colourScheme === 'traditional' ? deletedTraditionalContentStyle : deletedContentStyle;
154
238
  };
239
+
240
+ /**
241
+ * Creates a "Removed" lozenge to be displayed at the top right corner of deleted block nodes
242
+ */
243
+ var createRemovedLozenge = function createRemovedLozenge(intl, nodeName) {
244
+ var container = document.createElement('span');
245
+ var borderTopRightRadius;
246
+ var borderTopLeftRadius;
247
+ if (['expand', 'decisionList'].includes(nodeName || '')) {
248
+ borderTopRightRadius = "var(--ds-radius-small, 4px)";
249
+ } else if (['panel', 'codeBlock'].includes(nodeName || '')) {
250
+ borderTopRightRadius = "calc(".concat("var(--ds-radius-xsmall, 2px)", " + 1px)");
251
+ } else if (nodeName === 'mediaSingle') {
252
+ borderTopLeftRadius = "var(--ds-radius-small, 4px)";
253
+ }
254
+ var containerStyle = (0, _lazyNodeView.convertToInlineCss)({
255
+ position: 'absolute',
256
+ top: nodeName === 'mediaSingle' ? "var(--ds-space-300, 24px)" : "var(--ds-space-0, 0px)",
257
+ right: nodeName === 'mediaSingle' ? undefined : "var(--ds-space-0, 0px)",
258
+ left: nodeName === 'mediaSingle' ? "var(--ds-space-0, 0px)" : undefined,
259
+ zIndex: 2,
260
+ pointerEvents: 'none',
261
+ display: 'flex',
262
+ overflow: 'hidden',
263
+ borderTopRightRadius: borderTopRightRadius,
264
+ borderTopLeftRadius: borderTopLeftRadius
265
+ });
266
+ container.setAttribute('style', containerStyle);
267
+ container.setAttribute('data-testid', 'show-diff-removed-lozenge');
268
+
269
+ // Create vanilla HTML lozenge element with Atlaskit Lozenge styling (visual refresh)
270
+ var lozengeElement = document.createElement('span');
271
+ lozengeElement.setAttribute('style', lozengeStyle);
272
+ lozengeElement.textContent = intl.formatMessage(_messages.trackChangesMessages.removed).toUpperCase();
273
+ container.appendChild(lozengeElement);
274
+ return container;
275
+ };
276
+
277
+ /**
278
+ * Wraps a block node in a container with relative positioning to support absolute positioned lozenge
279
+ */
280
+ var createBlockNodeWrapper = function createBlockNodeWrapper(nodeName) {
281
+ var wrapper = document.createElement('div');
282
+ var fitContent = shouldFitContentWidth(nodeName);
283
+ var baseStyle = (0, _lazyNodeView.convertToInlineCss)({
284
+ position: 'relative',
285
+ display: fitContent ? 'inline-block' : 'block',
286
+ width: fitContent ? 'fit-content' : undefined,
287
+ height: fitContent ? 'fit-content' : undefined,
288
+ opacity: 1
289
+ });
290
+ wrapper.setAttribute('style', baseStyle);
291
+ return wrapper;
292
+ };
293
+
294
+ /**
295
+ * Wraps content with deleted styling without opacity (for use when content is a direct child of dom)
296
+ */
297
+ var createDeletedStyleWrapperWithoutOpacity = function createDeletedStyleWrapperWithoutOpacity(colourScheme) {
298
+ var wrapper = document.createElement('span');
299
+ wrapper.setAttribute('style', getDeletedContentStyle(colourScheme));
300
+ return wrapper;
301
+ };
302
+
303
+ /**
304
+ * Applies deleted styles directly to an HTML element by merging with existing styles
305
+ */
306
+ var applyDeletedStylesToElement = function applyDeletedStylesToElement(element, targetNode, colourScheme) {
307
+ var currentStyle = element.getAttribute('style') || '';
308
+ var deletedContentStyle = getDeletedContentStyle(colourScheme);
309
+ var nodeSpecificStyle = getDeletedStyleNode(targetNode.type.name) || '';
310
+ element.setAttribute('style', "".concat(currentStyle).concat(deletedContentStyle).concat(nodeSpecificStyle));
311
+ };
312
+
313
+ /**
314
+ * Appends a block node with wrapper, lozenge, and appropriate styling
315
+ */
316
+ var appendBlockNodeWithWrapper = function appendBlockNodeWithWrapper(dom, nodeView, targetNode, colourScheme, intl) {
317
+ var blockWrapper = createBlockNodeWrapper(targetNode.type.name);
318
+ if (shouldShowRemovedLozenge(targetNode.type.name)) {
319
+ var lozenge = createRemovedLozenge(intl, targetNode.type.name);
320
+ blockWrapper.append(lozenge);
321
+ }
322
+
323
+ // Wrap the nodeView in a content wrapper that has the opacity style AND the box-shadow
324
+ // This keeps the lozenge at full opacity while the content AND border are faded
325
+ var contentWrapper = document.createElement('div');
326
+ var nodeStyle = getDeletedStyleNode(targetNode.type.name);
327
+ contentWrapper.setAttribute('style', "".concat(getDeletedContentStyle(colourScheme)).concat(nodeStyle || ''));
328
+ contentWrapper.append(nodeView);
329
+ blockWrapper.append(contentWrapper);
330
+ if (nodeView instanceof HTMLElement) {
331
+ if (shouldAddShowDiffDeletedNodeClass(targetNode.type.name)) {
332
+ nodeView.classList.add('show-diff-deleted-node');
333
+ }
334
+ }
335
+ dom.append(blockWrapper);
336
+ };
337
+
338
+ /**
339
+ * Handles all block node rendering with appropriate deleted styling.
340
+ * For blockquote and heading nodes, applies styles directly to preserve natural margins.
341
+ * For other block nodes, uses wrapper approach with optional lozenge.
342
+ */
343
+ var handleBlockNodeView = function handleBlockNodeView(dom, nodeView, targetNode, colourScheme, intl) {
344
+ if (shouldApplyDeletedStylesDirectly(targetNode.type.name) && nodeView instanceof HTMLElement) {
345
+ // Apply deleted styles directly to preserve natural block-level margins
346
+ applyDeletedStylesToElement(nodeView, targetNode, colourScheme);
347
+ dom.append(nodeView);
348
+ } else {
349
+ // Use wrapper approach for other block nodes
350
+ appendBlockNodeWithWrapper(dom, nodeView, targetNode, colourScheme, intl);
351
+ }
352
+ };
155
353
  var createDeletedContentDecoration = exports.createDeletedContentDecoration = function createDeletedContentDecoration(_ref) {
156
354
  var change = _ref.change,
157
355
  doc = _ref.doc,
158
356
  nodeViewSerializer = _ref.nodeViewSerializer,
159
357
  colourScheme = _ref.colourScheme,
160
- newDoc = _ref.newDoc;
358
+ newDoc = _ref.newDoc,
359
+ intl = _ref.intl;
161
360
  var slice = doc.slice(change.fromA, change.toA);
162
361
  if (slice.content.content.length === 0) {
163
362
  return;
164
363
  }
165
- var isTableContent = slice.content.content.some(function () {
364
+ var isTableCellContent = slice.content.content.some(function () {
166
365
  return slice.content.content.some(function (siblingNode) {
167
- return ['tableHeader', 'tableCell', 'tableRow'].includes(siblingNode.type.name);
366
+ return ['tableHeader', 'tableCell'].includes(siblingNode.type.name);
168
367
  });
169
368
  });
170
- if (isTableContent) {
369
+ var isTableRowContent = slice.content.content.some(function () {
370
+ return slice.content.content.some(function (siblingNode) {
371
+ return ['tableRow'].includes(siblingNode.type.name);
372
+ });
373
+ });
374
+ if (isTableCellContent) {
171
375
  return;
172
376
  }
377
+ if (isTableRowContent) {
378
+ if (!(0, _platformFeatureFlags.fg)('platform_editor_ai_aifc_patch_ga')) {
379
+ return;
380
+ }
381
+ var _handleDeletedRows = (0, _deletedRowsHandler.handleDeletedRows)([change], doc, newDoc, nodeViewSerializer, colourScheme),
382
+ decorations = _handleDeletedRows.decorations;
383
+ return decorations;
384
+ }
173
385
  var serializer = nodeViewSerializer;
174
386
 
175
387
  // For non-table content, use the existing span wrapper approach
176
388
  var dom = document.createElement('span');
177
- dom.setAttribute('style', getDeletedContentStyle(colourScheme));
389
+ if (!(0, _platformFeatureFlags.fg)('platform_editor_ai_aifc_patch_beta_2')) {
390
+ dom.setAttribute('style', getDeletedContentStyle(colourScheme));
391
+ }
178
392
 
179
393
  /*
180
394
  * The thinking is we separate out the fragment we got from doc.slice
@@ -186,8 +400,11 @@ var createDeletedContentDecoration = exports.createDeletedContentDecoration = fu
186
400
  // Create a wrapper for each node with strikethrough
187
401
  var createWrapperWithStrikethrough = function createWrapperWithStrikethrough() {
188
402
  var wrapper = document.createElement('span');
189
- wrapper.style.position = 'relative';
190
- wrapper.style.width = 'fit-content';
403
+ var baseStyle = (0, _lazyNodeView.convertToInlineCss)({
404
+ position: 'relative',
405
+ width: 'fit-content'
406
+ });
407
+ wrapper.setAttribute('style', "".concat(baseStyle).concat(getDeletedContentStyle(colourScheme)));
191
408
  var strikethrough = document.createElement('span');
192
409
  strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colourScheme));
193
410
  wrapper.append(strikethrough);
@@ -210,7 +427,13 @@ var createDeletedContentDecoration = exports.createDeletedContentDecoration = fu
210
427
  // Fallback to serializing the individual child node
211
428
  var serializedChild = serializer.serializeNode(childNode);
212
429
  if (serializedChild) {
213
- dom.append(serializedChild);
430
+ if ((0, _platformFeatureFlags.fg)('platform_editor_ai_aifc_patch_beta_2')) {
431
+ var _wrapper = createWrapperWithStrikethrough();
432
+ _wrapper.append(serializedChild);
433
+ dom.append(_wrapper);
434
+ } else {
435
+ dom.append(serializedChild);
436
+ }
214
437
  }
215
438
  }
216
439
  });
@@ -266,6 +489,9 @@ var createDeletedContentDecoration = exports.createDeletedContentDecoration = fu
266
489
  var wrapper = createWrapperWithStrikethrough();
267
490
  wrapper.append(nodeView);
268
491
  dom.append(wrapper);
492
+ } else if ((0, _platformFeatureFlags.fg)('platform_editor_ai_aifc_patch_beta_2')) {
493
+ // Handle all block nodes with unified function
494
+ handleBlockNodeView(dom, nodeView, targetNode, colourScheme, intl);
269
495
  } else {
270
496
  dom.append(nodeView);
271
497
  }
@@ -275,7 +501,13 @@ var createDeletedContentDecoration = exports.createDeletedContentDecoration = fu
275
501
  } else {
276
502
  var fallbackNode = fallbackSerialization();
277
503
  if (fallbackNode) {
278
- dom.append(fallbackNode);
504
+ if ((0, _platformFeatureFlags.fg)('platform_editor_ai_aifc_patch_beta_2')) {
505
+ var _wrapper2 = createDeletedStyleWrapperWithoutOpacity(colourScheme);
506
+ _wrapper2.append(fallbackNode);
507
+ dom.append(_wrapper2);
508
+ } else {
509
+ dom.append(fallbackNode);
510
+ }
279
511
  }
280
512
  }
281
513
  });
@@ -284,5 +516,5 @@ var createDeletedContentDecoration = exports.createDeletedContentDecoration = fu
284
516
  // Widget decoration used for deletions as the content is not in the document
285
517
  // and we want to display the deleted content with a style.
286
518
  var safeInsertPos = (0, _findSafeInsertPos.findSafeInsertPos)(newDoc, change.fromB, slice);
287
- return _view.Decoration.widget(safeInsertPos, dom, {});
519
+ return [_view.Decoration.widget(safeInsertPos, dom)];
288
520
  };
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.handleDeletedRows = exports.createDeletedRowsDecorations = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
+ var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
10
+ var _document = require("@atlaskit/editor-common/utils/document");
11
+ var _utils = require("@atlaskit/editor-prosemirror/utils");
12
+ var _view = require("@atlaskit/editor-prosemirror/view");
13
+ var _tableMap = require("@atlaskit/editor-tables/table-map");
14
+ var _findSafeInsertPos = require("./findSafeInsertPos");
15
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
16
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
17
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
18
+ var deletedRowStyle = (0, _lazyNodeView.convertToInlineCss)({
19
+ color: "var(--ds-text-accent-gray, #44546F)",
20
+ textDecoration: 'line-through',
21
+ opacity: 0.6,
22
+ display: 'table-row'
23
+ });
24
+ var deletedTraditionalRowStyle = (0, _lazyNodeView.convertToInlineCss)({
25
+ textDecorationColor: "var(--ds-border-accent-red, #E2483D)",
26
+ textDecoration: 'line-through',
27
+ opacity: 0.6,
28
+ display: 'table-row'
29
+ });
30
+ /**
31
+ * Extracts information about deleted table rows from a change
32
+ */
33
+ var extractDeletedRows = function extractDeletedRows(change, originalDoc, newDoc) {
34
+ var deletedRows = [];
35
+
36
+ // Find the table in the original document
37
+ var $fromPos = originalDoc.resolve(change.fromA);
38
+ var tableOld = (0, _utils.findParentNodeClosestToPos)($fromPos, function (node) {
39
+ return node.type.name === 'table';
40
+ });
41
+ if (!tableOld) {
42
+ return deletedRows;
43
+ }
44
+ var oldTableMap = _tableMap.TableMap.get(tableOld.node);
45
+
46
+ // Find the table in the new document at the insertion point
47
+ var $newPos = newDoc.resolve(change.fromB);
48
+ var tableNew = (0, _utils.findParentNodeClosestToPos)($newPos, function (node) {
49
+ return node.type.name === 'table';
50
+ });
51
+ if (!tableNew) {
52
+ return deletedRows;
53
+ }
54
+ var newTableMap = _tableMap.TableMap.get(tableNew.node);
55
+
56
+ // If no rows were deleted, return empty
57
+ if (oldTableMap.height <= newTableMap.height ||
58
+ // For now ignore if there are column deletions as well
59
+ oldTableMap.width !== newTableMap.width) {
60
+ return deletedRows;
61
+ }
62
+
63
+ // Find which rows were deleted by analyzing the change range
64
+ var changeStartInTable = change.fromA - tableOld.pos - 1;
65
+ var changeEndInTable = change.toA - tableOld.pos - 1;
66
+ var currentOffset = 0;
67
+ var rowIndex = 0;
68
+ tableOld.node.content.forEach(function (rowNode, index) {
69
+ var rowStart = currentOffset;
70
+ var rowEnd = currentOffset + rowNode.nodeSize;
71
+
72
+ // Check if this row overlaps with the deletion range
73
+ var rowOverlapsChange = rowStart >= changeStartInTable && rowStart < changeEndInTable || rowEnd > changeStartInTable && rowEnd <= changeEndInTable || rowStart < changeStartInTable && rowEnd > changeEndInTable;
74
+ if (rowOverlapsChange && rowNode.type.name === 'tableRow' && !isEmptyRow(rowNode)) {
75
+ var startOfRow = newTableMap.mapByRow.slice().reverse().find(function (row) {
76
+ return row[0] + tableNew.pos < change.fromB && change.fromB < row[row.length - 1] + tableNew.pos;
77
+ });
78
+ deletedRows.push({
79
+ rowIndex: rowIndex,
80
+ rowNode: rowNode,
81
+ fromA: tableOld.pos + 1 + rowStart,
82
+ toA: tableOld.pos + 1 + rowEnd,
83
+ fromB: startOfRow ? startOfRow[0] + tableNew.start : change.fromB
84
+ });
85
+ }
86
+ currentOffset += rowNode.nodeSize;
87
+ if (rowNode.type.name === 'tableRow') {
88
+ rowIndex++;
89
+ }
90
+ });
91
+
92
+ // Filter changes that never truly got deleted
93
+ return deletedRows.filter(function (deletedRow) {
94
+ return !tableNew.node.children.some(function (newRow) {
95
+ return (0, _document.areNodesEqualIgnoreAttrs)(newRow, deletedRow.rowNode);
96
+ });
97
+ });
98
+ };
99
+
100
+ /**
101
+ * Checks if a table row is empty (contains no meaningful content)
102
+ */
103
+ var isEmptyRow = function isEmptyRow(rowNode) {
104
+ var isEmpty = true;
105
+ rowNode.descendants(function (node) {
106
+ if (!isEmpty) {
107
+ return false;
108
+ }
109
+
110
+ // If we find any inline content with size > 0, the row is not empty
111
+ if (node.isInline && node.nodeSize > 0) {
112
+ isEmpty = false;
113
+ return false;
114
+ }
115
+
116
+ // If we find text content, the row is not empty
117
+ if (node.isText && node.text && node.text.trim() !== '') {
118
+ isEmpty = false;
119
+ return false;
120
+ }
121
+ return true;
122
+ });
123
+ return isEmpty;
124
+ };
125
+
126
+ /**
127
+ * Creates a DOM representation of a deleted table row
128
+ */
129
+ var createDeletedRowDOM = function createDeletedRowDOM(rowNode, nodeViewSerializer, colourScheme) {
130
+ var tr = document.createElement('tr');
131
+ tr.setAttribute('style', colourScheme === 'traditional' ? deletedTraditionalRowStyle : deletedRowStyle);
132
+ tr.setAttribute('data-testid', 'show-diff-deleted-row');
133
+
134
+ // Serialize each cell in the row
135
+ rowNode.content.forEach(function (cellNode) {
136
+ if (cellNode.type.name === 'tableCell' || cellNode.type.name === 'tableHeader') {
137
+ var nodeView = nodeViewSerializer.tryCreateNodeView(cellNode);
138
+ if (nodeView) {
139
+ tr.appendChild(nodeView);
140
+ } else {
141
+ // Fallback to fragment serialization
142
+ var serializedContent = nodeViewSerializer.serializeFragment(cellNode.content);
143
+ if (serializedContent) {
144
+ tr.appendChild(serializedContent);
145
+ }
146
+ }
147
+ }
148
+ });
149
+ return tr;
150
+ };
151
+
152
+ /**
153
+ * Expands a diff to include whole deleted rows when table rows are affected
154
+ */
155
+ var expandDiffForDeletedRows = function expandDiffForDeletedRows(changes, originalDoc, newDoc) {
156
+ var deletedRowInfo = [];
157
+ var _iterator = _createForOfIteratorHelper(changes),
158
+ _step;
159
+ try {
160
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
161
+ var change = _step.value;
162
+ // Check if this change affects table content
163
+ var deletedRows = extractDeletedRows(change, originalDoc, newDoc);
164
+ if (deletedRows.length > 0) {
165
+ deletedRowInfo.push.apply(deletedRowInfo, (0, _toConsumableArray2.default)(deletedRows));
166
+ }
167
+ }
168
+ } catch (err) {
169
+ _iterator.e(err);
170
+ } finally {
171
+ _iterator.f();
172
+ }
173
+ return deletedRowInfo;
174
+ };
175
+
176
+ /**
177
+ * Creates decorations for deleted table rows
178
+ */
179
+ var createDeletedRowsDecorations = exports.createDeletedRowsDecorations = function createDeletedRowsDecorations(_ref) {
180
+ var deletedRows = _ref.deletedRows,
181
+ originalDoc = _ref.originalDoc,
182
+ newDoc = _ref.newDoc,
183
+ nodeViewSerializer = _ref.nodeViewSerializer,
184
+ colourScheme = _ref.colourScheme;
185
+ return deletedRows.map(function (deletedRow) {
186
+ var rowDOM = createDeletedRowDOM(deletedRow.rowNode, nodeViewSerializer, colourScheme);
187
+
188
+ // Find safe insertion position for the deleted row
189
+ var safeInsertPos = (0, _findSafeInsertPos.findSafeInsertPos)(newDoc, deletedRow.fromB - 1,
190
+ // -1 to find the first safe position from the table
191
+ originalDoc.slice(deletedRow.fromA, deletedRow.toA));
192
+ return _view.Decoration.widget(safeInsertPos, rowDOM, {});
193
+ });
194
+ };
195
+
196
+ /**
197
+ * Main function to handle deleted rows - computes diff and creates decorations
198
+ */
199
+ var handleDeletedRows = exports.handleDeletedRows = function handleDeletedRows(changes, originalDoc, newDoc, nodeViewSerializer, colourScheme) {
200
+ // First, expand the changes to include complete deleted rows
201
+ var deletedRows = expandDiffForDeletedRows(changes.filter(function (change) {
202
+ return change.deleted.length > 0;
203
+ }), originalDoc, newDoc);
204
+ var allDecorations = createDeletedRowsDecorations({
205
+ deletedRows: deletedRows,
206
+ originalDoc: originalDoc,
207
+ newDoc: newDoc,
208
+ nodeViewSerializer: nodeViewSerializer,
209
+ colourScheme: colourScheme
210
+ });
211
+ return {
212
+ decorations: allDecorations
213
+ };
214
+ };