@atlaskit/editor-plugin-show-diff 25.0.4 → 25.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/cjs/pm-plugins/NodeViewSerializer.js +2 -1
- package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +7 -2
- package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +42 -3
- package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +26 -5
- package/dist/es2019/pm-plugins/NodeViewSerializer.js +2 -1
- package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +7 -1
- package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +42 -3
- package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +26 -5
- package/dist/esm/pm-plugins/NodeViewSerializer.js +2 -1
- package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +7 -2
- package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +42 -3
- package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +26 -5
- package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +3 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 25.0.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`8843fc489d5a6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8843fc489d5a6) -
|
|
8
|
+
EDITOR-9591 Behind platform_editor_ai_show_diff_patch_2, highlight inserted inline nodes as a
|
|
9
|
+
whole instead of the text inside them, and only outline an inserted atomic inline node (date,
|
|
10
|
+
emoji, mention, status) when its attributes are the only change
|
|
11
|
+
(platform_editor_show_diff_deleted_nodeview_content)
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
|
|
14
|
+
## 25.0.5
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
|
|
3
20
|
## 25.0.4
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -112,7 +112,8 @@ var NodeViewSerializer = exports.NodeViewSerializer = /*#__PURE__*/function () {
|
|
|
112
112
|
if (childNode) {
|
|
113
113
|
// Give inserted atomic children the same box-shadow
|
|
114
114
|
// highlight an in-place attribute change already gets (`getAtomicInlineChangedAttrs`).
|
|
115
|
-
|
|
115
|
+
// Disabled under patch_2: the outline also landed on atomic children inserted alongside text.
|
|
116
|
+
if (isInserted && !(0, _fg.fg)('platform_editor_ai_show_diff_patch_2') && (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_show_diff_deleted_nodeview_content') && (0, _getAttrChangeRanges.isInlineAttrChangeNodeName)(child.type.name) && childNode instanceof HTMLElement) {
|
|
116
117
|
var _getAtomicInlineChang = (0, _createInlineChangedDecoration.getAtomicInlineChangedAttrs)(child.type.name, colorScheme),
|
|
117
118
|
className = _getAtomicInlineChang.className,
|
|
118
119
|
styleSuffix = _getAtomicInlineChang.styleSuffix;
|
|
@@ -1164,11 +1164,16 @@ function buildDeletedWrappedBlockOutline(colors, _ref) {
|
|
|
1164
1164
|
* decoration span and read by the `.show-diff-atomic-inline-changed-*` selectors in
|
|
1165
1165
|
* EditorContentContainer, on the decorated element or a descendant, so it must inherit. Being
|
|
1166
1166
|
* inline it beats the stylesheet's fallback, making the plugin the only source of the colour.
|
|
1167
|
+
*
|
|
1168
|
+
* Under patch_2 it also reserves the 2px ring either side, since the ring takes up no space and
|
|
1169
|
+
* otherwise paints over an adjacent inline diff.
|
|
1167
1170
|
*/
|
|
1168
1171
|
function buildAtomicInlineChangedCSSVariables(colors) {
|
|
1169
|
-
return (0, _cssHelper.convertToInlineCss)({
|
|
1172
|
+
return (0, _cssHelper.convertToInlineCss)(_objectSpread({
|
|
1170
1173
|
'--show-diff-atomic-inline-changed-border-color': borderAccent(colors.insertColor)
|
|
1171
|
-
})
|
|
1174
|
+
}, (0, _fg.fg)('platform_editor_ai_show_diff_patch_2') && {
|
|
1175
|
+
marginInline: "var(--ds-space-025, 2px)"
|
|
1176
|
+
}));
|
|
1172
1177
|
}
|
|
1173
1178
|
|
|
1174
1179
|
/** Hands editor-core the same strike line the widget path uses, via a custom property. */
|
|
@@ -7,19 +7,24 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.createNodeChangedDecorationWidget = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
10
|
+
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
|
|
10
11
|
var _fg = require("@atlaskit/platform-feature-flags/fg");
|
|
11
12
|
var _baseNodeName = require("../utils/baseNodeName");
|
|
12
13
|
var _emptyTextBlocks = require("../utils/emptyTextBlocks");
|
|
13
14
|
var _isEmptyParagraphSlice = require("../utils/isEmptyParagraphSlice");
|
|
15
|
+
var _factory = require("./colorSchemes/factory");
|
|
16
|
+
var _schemes = require("./colorSchemes/schemes");
|
|
14
17
|
var _createAnchorDecorationWidgets = require("./createAnchorDecorationWidgets");
|
|
15
18
|
var _createChangedRowDecorationWidgets = require("./createChangedRowDecorationWidgets");
|
|
16
19
|
var _createContributorTagWidget = require("./createContributorTagWidget");
|
|
20
|
+
var _createInlineChangedDecoration = require("./createInlineChangedDecoration");
|
|
17
21
|
var _decorationKeys = require("./decorationKeys");
|
|
18
22
|
var _absorbFirstChildMarginReset = require("./utils/absorbFirstChildMarginReset");
|
|
19
23
|
var _createDeletedLineBreakWidget = require("./utils/createDeletedLineBreakWidget");
|
|
20
24
|
var _createMarginAbsorber = require("./utils/createMarginAbsorber");
|
|
21
25
|
var _createNodeShapedMarginSpacer = require("./utils/createNodeShapedMarginSpacer");
|
|
22
26
|
var _findSafeInsertPos = require("./utils/findSafeInsertPos");
|
|
27
|
+
var _getAttrChangeRanges = require("./utils/getAttrChangeRanges");
|
|
23
28
|
var _safeResolve = require("./utils/safeResolve");
|
|
24
29
|
var _tableDiffMode = require("./utils/tableDiffMode");
|
|
25
30
|
var _wrapBlockNodeView = require("./utils/wrapBlockNodeView");
|
|
@@ -120,6 +125,32 @@ var createTableCellContentWidgets = function createTableCellContentWidgets(_ref)
|
|
|
120
125
|
return decorations;
|
|
121
126
|
};
|
|
122
127
|
|
|
128
|
+
/**
|
|
129
|
+
* The node name when `change` only swapped one atomic inline node (date, emoji, mention, status)
|
|
130
|
+
* for another of the same type, i.e. an attribute change rather than content added or removed
|
|
131
|
+
* around it.
|
|
132
|
+
*/
|
|
133
|
+
var getAtomicInlineAttrOnlyNodeName = function getAtomicInlineAttrOnlyNodeName(change, doc, newDoc) {
|
|
134
|
+
var nodeA = doc.nodeAt(change.fromA);
|
|
135
|
+
var nodeB = newDoc.nodeAt(change.fromB);
|
|
136
|
+
if (!nodeA || !nodeB || nodeA.type !== nodeB.type || nodeA.nodeSize !== change.toA - change.fromA || nodeB.nodeSize !== change.toB - change.fromB) {
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
var nodeName = nodeA.type.name;
|
|
140
|
+
return (0, _getAttrChangeRanges.isInlineAttrChangeNodeName)(nodeName) ? nodeName : undefined;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/** Wraps an inserted atomic inline node view in the outline an in-place attribute change gets. */
|
|
144
|
+
var createAtomicInlineOutline = function createAtomicInlineOutline(nodeName, nodeView, colorScheme) {
|
|
145
|
+
var outlineWrapper = document.createElement('span');
|
|
146
|
+
outlineWrapper.className = (0, _createInlineChangedDecoration.getAtomicInlineChangedAttrs)(nodeName, colorScheme).className;
|
|
147
|
+
// Set in both cohorts of `platform_editor_show_diff_color_scheme_refactor`: being inline it beats
|
|
148
|
+
// the stylesheet's purple/green table, so editor-core's rings follow the change's scheme too.
|
|
149
|
+
outlineWrapper.setAttribute('style', (0, _factory.buildAtomicInlineChangedCSSVariables)(_schemes.colorSchemeRegistry[colorScheme !== null && colorScheme !== void 0 ? colorScheme : 'standard']));
|
|
150
|
+
outlineWrapper.append(nodeView);
|
|
151
|
+
return outlineWrapper;
|
|
152
|
+
};
|
|
153
|
+
|
|
123
154
|
/**
|
|
124
155
|
* This function is used to create a decoration widget to show content
|
|
125
156
|
* that is not in the current document.
|
|
@@ -391,9 +422,17 @@ var createNodeChangedDecorationWidget = exports.createNodeChangedDecorationWidge
|
|
|
391
422
|
nodeView.style.setProperty('anchor-name', "--".concat(contributorTagAnchorName));
|
|
392
423
|
}
|
|
393
424
|
if (node.isInline) {
|
|
394
|
-
var
|
|
395
|
-
|
|
396
|
-
|
|
425
|
+
var attrOnlyNodeName = isInserted && (0, _fg.fg)('platform_editor_ai_show_diff_patch_2') && (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_show_diff_deleted_nodeview_content') ? getAtomicInlineAttrOnlyNodeName(change, doc, newDoc) : undefined;
|
|
426
|
+
if (attrOnlyNodeName) {
|
|
427
|
+
// Only the node's attributes changed, so outline it as an in-place attribute change
|
|
428
|
+
// does, in place of the highlight. Its own wrapper keeps the outline clear of the node
|
|
429
|
+
// view's styles.
|
|
430
|
+
dom.append(createAtomicInlineOutline(attrOnlyNodeName, nodeView, colorScheme));
|
|
431
|
+
} else {
|
|
432
|
+
var wrapper = (0, _wrapBlockNodeView.createContentWrapper)(colorScheme, isActive, isInserted, reveal);
|
|
433
|
+
wrapper.append(nodeView);
|
|
434
|
+
dom.append(wrapper);
|
|
435
|
+
}
|
|
397
436
|
} else {
|
|
398
437
|
// Handle all block nodes with unified function
|
|
399
438
|
(0, _wrapBlockNodeView.wrapBlockNodeView)({
|
|
@@ -294,7 +294,28 @@ var applyTextLikeBlockNodeStyles = function applyTextLikeBlockNodeStyles(_ref8)
|
|
|
294
294
|
element.setAttribute('style', "".concat(currentStyle).concat(nodeSpecificStyle));
|
|
295
295
|
}
|
|
296
296
|
var contentStyle = (0, _wrapBlockNodeViewStyles.getChangedContentStyle)(colorScheme, isActive, isInserted, hideAddedDiffsUnderline);
|
|
297
|
-
|
|
297
|
+
|
|
298
|
+
// Under patch_2, an inserted inline node view (a date, a status lozenge) is highlighted as a whole
|
|
299
|
+
// rather than the text inside it, so the highlight sits behind the node. Rejecting it skips its
|
|
300
|
+
// subtree, so this stays a single walk.
|
|
301
|
+
var highlightInlineNodesWhole = isInserted && (0, _fg.fg)('platform_editor_ai_show_diff_patch_2');
|
|
302
|
+
// `applyInlineLeafNodeStyles` styles the block's direct inline children itself.
|
|
303
|
+
var handlesDirectInlineChildren = highlightInlineLeafNodes && targetNode.type.inlineContent;
|
|
304
|
+
var inlineNodesToWrap = [];
|
|
305
|
+
var walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, {
|
|
306
|
+
acceptNode: function acceptNode(node) {
|
|
307
|
+
if (node instanceof Text) {
|
|
308
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
309
|
+
}
|
|
310
|
+
if (highlightInlineNodesWhole && node instanceof HTMLElement && node.dataset.prosemirrorNodeInline === 'true') {
|
|
311
|
+
if (!(handlesDirectInlineChildren && node.parentElement === element)) {
|
|
312
|
+
inlineNodesToWrap.push(node);
|
|
313
|
+
}
|
|
314
|
+
return NodeFilter.FILTER_REJECT;
|
|
315
|
+
}
|
|
316
|
+
return NodeFilter.FILTER_SKIP;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
298
319
|
var textNodesToWrap = [];
|
|
299
320
|
var currentNode = walker.nextNode();
|
|
300
321
|
while (currentNode) {
|
|
@@ -303,13 +324,13 @@ var applyTextLikeBlockNodeStyles = function applyTextLikeBlockNodeStyles(_ref8)
|
|
|
303
324
|
}
|
|
304
325
|
currentNode = walker.nextNode();
|
|
305
326
|
}
|
|
306
|
-
textNodesToWrap.forEach(function (
|
|
327
|
+
[].concat(textNodesToWrap, inlineNodesToWrap).forEach(function (node) {
|
|
307
328
|
var contentWrapper = document.createElement('span');
|
|
308
329
|
contentWrapper.setAttribute('style', contentStyle);
|
|
309
|
-
|
|
310
|
-
contentWrapper.append(
|
|
330
|
+
node.replaceWith(contentWrapper);
|
|
331
|
+
contentWrapper.append(node);
|
|
311
332
|
});
|
|
312
|
-
if (
|
|
333
|
+
if (handlesDirectInlineChildren) {
|
|
313
334
|
applyInlineLeafNodeStyles({
|
|
314
335
|
element: element,
|
|
315
336
|
targetNode: targetNode,
|
|
@@ -95,7 +95,8 @@ export class NodeViewSerializer {
|
|
|
95
95
|
if (childNode) {
|
|
96
96
|
// Give inserted atomic children the same box-shadow
|
|
97
97
|
// highlight an in-place attribute change already gets (`getAtomicInlineChangedAttrs`).
|
|
98
|
-
|
|
98
|
+
// Disabled under patch_2: the outline also landed on atomic children inserted alongside text.
|
|
99
|
+
if (isInserted && !fg('platform_editor_ai_show_diff_patch_2') && isExperimentEnabled('platform_editor_show_diff_deleted_nodeview_content') && isInlineAttrChangeNodeName(child.type.name) && childNode instanceof HTMLElement) {
|
|
99
100
|
const {
|
|
100
101
|
className,
|
|
101
102
|
styleSuffix
|
|
@@ -1085,10 +1085,16 @@ export function buildDeletedWrappedBlockOutline(colors, {
|
|
|
1085
1085
|
* decoration span and read by the `.show-diff-atomic-inline-changed-*` selectors in
|
|
1086
1086
|
* EditorContentContainer, on the decorated element or a descendant, so it must inherit. Being
|
|
1087
1087
|
* inline it beats the stylesheet's fallback, making the plugin the only source of the colour.
|
|
1088
|
+
*
|
|
1089
|
+
* Under patch_2 it also reserves the 2px ring either side, since the ring takes up no space and
|
|
1090
|
+
* otherwise paints over an adjacent inline diff.
|
|
1088
1091
|
*/
|
|
1089
1092
|
export function buildAtomicInlineChangedCSSVariables(colors) {
|
|
1090
1093
|
return convertToInlineCss({
|
|
1091
|
-
'--show-diff-atomic-inline-changed-border-color': borderAccent(colors.insertColor)
|
|
1094
|
+
'--show-diff-atomic-inline-changed-border-color': borderAccent(colors.insertColor),
|
|
1095
|
+
...(fg('platform_editor_ai_show_diff_patch_2') && {
|
|
1096
|
+
marginInline: "var(--ds-space-025, 2px)"
|
|
1097
|
+
})
|
|
1092
1098
|
});
|
|
1093
1099
|
}
|
|
1094
1100
|
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
2
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
2
3
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
3
4
|
import { resolveBaseNodeName } from '../utils/baseNodeName';
|
|
4
5
|
import { countEmptyTextBlockOnlySlice } from '../utils/emptyTextBlocks';
|
|
5
6
|
import { isEmptyParagraphSlice } from '../utils/isEmptyParagraphSlice';
|
|
7
|
+
import { buildAtomicInlineChangedCSSVariables } from './colorSchemes/factory';
|
|
8
|
+
import { colorSchemeRegistry } from './colorSchemes/schemes';
|
|
6
9
|
import { clampAnchorPosIntoCell, createAnchorNameSpan, createLeftAnchorWidget } from './createAnchorDecorationWidgets';
|
|
7
10
|
import { createChangedRowDecorationWidgets } from './createChangedRowDecorationWidgets';
|
|
8
11
|
import { createContributorTagHost, resolveHoistedCodeBlockAnchor, unmountContributorTag } from './createContributorTagWidget';
|
|
12
|
+
import { getAtomicInlineChangedAttrs } from './createInlineChangedDecoration';
|
|
9
13
|
import { AnchorTypeKey, buildContributorTagDecorationSpec, buildDiffDecorationSpec, buildAnchorDecorationKey, scrollMarginTopValue } from './decorationKeys';
|
|
10
14
|
import { absorbFirstChildMarginReset } from './utils/absorbFirstChildMarginReset';
|
|
11
15
|
import { createDeletedLineBreakDecoration } from './utils/createDeletedLineBreakWidget';
|
|
12
16
|
import { createMarginAbsorber } from './utils/createMarginAbsorber';
|
|
13
17
|
import { createNodeShapedMarginSpacer } from './utils/createNodeShapedMarginSpacer';
|
|
14
18
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
19
|
+
import { isInlineAttrChangeNodeName } from './utils/getAttrChangeRanges';
|
|
15
20
|
import { safeResolve } from './utils/safeResolve';
|
|
16
21
|
import { getTableDiffMode } from './utils/tableDiffMode';
|
|
17
22
|
import { wrapBlockNodeView, createRemovedLozenge, injectInnerWrapper, createContentWrapper } from './utils/wrapBlockNodeView';
|
|
@@ -112,6 +117,32 @@ const createTableCellContentWidgets = ({
|
|
|
112
117
|
return decorations;
|
|
113
118
|
};
|
|
114
119
|
|
|
120
|
+
/**
|
|
121
|
+
* The node name when `change` only swapped one atomic inline node (date, emoji, mention, status)
|
|
122
|
+
* for another of the same type, i.e. an attribute change rather than content added or removed
|
|
123
|
+
* around it.
|
|
124
|
+
*/
|
|
125
|
+
const getAtomicInlineAttrOnlyNodeName = (change, doc, newDoc) => {
|
|
126
|
+
const nodeA = doc.nodeAt(change.fromA);
|
|
127
|
+
const nodeB = newDoc.nodeAt(change.fromB);
|
|
128
|
+
if (!nodeA || !nodeB || nodeA.type !== nodeB.type || nodeA.nodeSize !== change.toA - change.fromA || nodeB.nodeSize !== change.toB - change.fromB) {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
const nodeName = nodeA.type.name;
|
|
132
|
+
return isInlineAttrChangeNodeName(nodeName) ? nodeName : undefined;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/** Wraps an inserted atomic inline node view in the outline an in-place attribute change gets. */
|
|
136
|
+
const createAtomicInlineOutline = (nodeName, nodeView, colorScheme) => {
|
|
137
|
+
const outlineWrapper = document.createElement('span');
|
|
138
|
+
outlineWrapper.className = getAtomicInlineChangedAttrs(nodeName, colorScheme).className;
|
|
139
|
+
// Set in both cohorts of `platform_editor_show_diff_color_scheme_refactor`: being inline it beats
|
|
140
|
+
// the stylesheet's purple/green table, so editor-core's rings follow the change's scheme too.
|
|
141
|
+
outlineWrapper.setAttribute('style', buildAtomicInlineChangedCSSVariables(colorSchemeRegistry[colorScheme !== null && colorScheme !== void 0 ? colorScheme : 'standard']));
|
|
142
|
+
outlineWrapper.append(nodeView);
|
|
143
|
+
return outlineWrapper;
|
|
144
|
+
};
|
|
145
|
+
|
|
115
146
|
/**
|
|
116
147
|
* This function is used to create a decoration widget to show content
|
|
117
148
|
* that is not in the current document.
|
|
@@ -377,9 +408,17 @@ export const createNodeChangedDecorationWidget = ({
|
|
|
377
408
|
nodeView.style.setProperty('anchor-name', `--${contributorTagAnchorName}`);
|
|
378
409
|
}
|
|
379
410
|
if (node.isInline) {
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
411
|
+
const attrOnlyNodeName = isInserted && fg('platform_editor_ai_show_diff_patch_2') && isExperimentEnabled('platform_editor_show_diff_deleted_nodeview_content') ? getAtomicInlineAttrOnlyNodeName(change, doc, newDoc) : undefined;
|
|
412
|
+
if (attrOnlyNodeName) {
|
|
413
|
+
// Only the node's attributes changed, so outline it as an in-place attribute change
|
|
414
|
+
// does, in place of the highlight. Its own wrapper keeps the outline clear of the node
|
|
415
|
+
// view's styles.
|
|
416
|
+
dom.append(createAtomicInlineOutline(attrOnlyNodeName, nodeView, colorScheme));
|
|
417
|
+
} else {
|
|
418
|
+
const wrapper = createContentWrapper(colorScheme, isActive, isInserted, reveal);
|
|
419
|
+
wrapper.append(nodeView);
|
|
420
|
+
dom.append(wrapper);
|
|
421
|
+
}
|
|
383
422
|
} else {
|
|
384
423
|
// Handle all block nodes with unified function
|
|
385
424
|
wrapBlockNodeView({
|
|
@@ -284,7 +284,28 @@ const applyTextLikeBlockNodeStyles = ({
|
|
|
284
284
|
element.setAttribute('style', `${currentStyle}${nodeSpecificStyle}`);
|
|
285
285
|
}
|
|
286
286
|
const contentStyle = getChangedContentStyle(colorScheme, isActive, isInserted, hideAddedDiffsUnderline);
|
|
287
|
-
|
|
287
|
+
|
|
288
|
+
// Under patch_2, an inserted inline node view (a date, a status lozenge) is highlighted as a whole
|
|
289
|
+
// rather than the text inside it, so the highlight sits behind the node. Rejecting it skips its
|
|
290
|
+
// subtree, so this stays a single walk.
|
|
291
|
+
const highlightInlineNodesWhole = isInserted && fg('platform_editor_ai_show_diff_patch_2');
|
|
292
|
+
// `applyInlineLeafNodeStyles` styles the block's direct inline children itself.
|
|
293
|
+
const handlesDirectInlineChildren = highlightInlineLeafNodes && targetNode.type.inlineContent;
|
|
294
|
+
const inlineNodesToWrap = [];
|
|
295
|
+
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, {
|
|
296
|
+
acceptNode: node => {
|
|
297
|
+
if (node instanceof Text) {
|
|
298
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
299
|
+
}
|
|
300
|
+
if (highlightInlineNodesWhole && node instanceof HTMLElement && node.dataset.prosemirrorNodeInline === 'true') {
|
|
301
|
+
if (!(handlesDirectInlineChildren && node.parentElement === element)) {
|
|
302
|
+
inlineNodesToWrap.push(node);
|
|
303
|
+
}
|
|
304
|
+
return NodeFilter.FILTER_REJECT;
|
|
305
|
+
}
|
|
306
|
+
return NodeFilter.FILTER_SKIP;
|
|
307
|
+
}
|
|
308
|
+
});
|
|
288
309
|
const textNodesToWrap = [];
|
|
289
310
|
let currentNode = walker.nextNode();
|
|
290
311
|
while (currentNode) {
|
|
@@ -293,13 +314,13 @@ const applyTextLikeBlockNodeStyles = ({
|
|
|
293
314
|
}
|
|
294
315
|
currentNode = walker.nextNode();
|
|
295
316
|
}
|
|
296
|
-
textNodesToWrap.forEach(
|
|
317
|
+
[...textNodesToWrap, ...inlineNodesToWrap].forEach(node => {
|
|
297
318
|
const contentWrapper = document.createElement('span');
|
|
298
319
|
contentWrapper.setAttribute('style', contentStyle);
|
|
299
|
-
|
|
300
|
-
contentWrapper.append(
|
|
320
|
+
node.replaceWith(contentWrapper);
|
|
321
|
+
contentWrapper.append(node);
|
|
301
322
|
});
|
|
302
|
-
if (
|
|
323
|
+
if (handlesDirectInlineChildren) {
|
|
303
324
|
applyInlineLeafNodeStyles({
|
|
304
325
|
element,
|
|
305
326
|
targetNode,
|
|
@@ -105,7 +105,8 @@ export var NodeViewSerializer = /*#__PURE__*/function () {
|
|
|
105
105
|
if (childNode) {
|
|
106
106
|
// Give inserted atomic children the same box-shadow
|
|
107
107
|
// highlight an in-place attribute change already gets (`getAtomicInlineChangedAttrs`).
|
|
108
|
-
|
|
108
|
+
// Disabled under patch_2: the outline also landed on atomic children inserted alongside text.
|
|
109
|
+
if (isInserted && !fg('platform_editor_ai_show_diff_patch_2') && isExperimentEnabled('platform_editor_show_diff_deleted_nodeview_content') && isInlineAttrChangeNodeName(child.type.name) && childNode instanceof HTMLElement) {
|
|
109
110
|
var _getAtomicInlineChang = getAtomicInlineChangedAttrs(child.type.name, colorScheme),
|
|
110
111
|
className = _getAtomicInlineChang.className,
|
|
111
112
|
styleSuffix = _getAtomicInlineChang.styleSuffix;
|
|
@@ -1088,11 +1088,16 @@ export function buildDeletedWrappedBlockOutline(colors, _ref) {
|
|
|
1088
1088
|
* decoration span and read by the `.show-diff-atomic-inline-changed-*` selectors in
|
|
1089
1089
|
* EditorContentContainer, on the decorated element or a descendant, so it must inherit. Being
|
|
1090
1090
|
* inline it beats the stylesheet's fallback, making the plugin the only source of the colour.
|
|
1091
|
+
*
|
|
1092
|
+
* Under patch_2 it also reserves the 2px ring either side, since the ring takes up no space and
|
|
1093
|
+
* otherwise paints over an adjacent inline diff.
|
|
1091
1094
|
*/
|
|
1092
1095
|
export function buildAtomicInlineChangedCSSVariables(colors) {
|
|
1093
|
-
return convertToInlineCss({
|
|
1096
|
+
return convertToInlineCss(_objectSpread({
|
|
1094
1097
|
'--show-diff-atomic-inline-changed-border-color': borderAccent(colors.insertColor)
|
|
1095
|
-
})
|
|
1098
|
+
}, fg('platform_editor_ai_show_diff_patch_2') && {
|
|
1099
|
+
marginInline: "var(--ds-space-025, 2px)"
|
|
1100
|
+
}));
|
|
1096
1101
|
}
|
|
1097
1102
|
|
|
1098
1103
|
/** Hands editor-core the same strike line the widget path uses, via a custom property. */
|
|
@@ -2,19 +2,24 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
2
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
3
|
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; }
|
|
4
4
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
5
6
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
6
7
|
import { resolveBaseNodeName } from '../utils/baseNodeName';
|
|
7
8
|
import { countEmptyTextBlockOnlySlice } from '../utils/emptyTextBlocks';
|
|
8
9
|
import { isEmptyParagraphSlice } from '../utils/isEmptyParagraphSlice';
|
|
10
|
+
import { buildAtomicInlineChangedCSSVariables } from './colorSchemes/factory';
|
|
11
|
+
import { colorSchemeRegistry } from './colorSchemes/schemes';
|
|
9
12
|
import { clampAnchorPosIntoCell, createAnchorNameSpan, createLeftAnchorWidget } from './createAnchorDecorationWidgets';
|
|
10
13
|
import { createChangedRowDecorationWidgets } from './createChangedRowDecorationWidgets';
|
|
11
14
|
import { createContributorTagHost, resolveHoistedCodeBlockAnchor, unmountContributorTag } from './createContributorTagWidget';
|
|
15
|
+
import { getAtomicInlineChangedAttrs } from './createInlineChangedDecoration';
|
|
12
16
|
import { AnchorTypeKey, buildContributorTagDecorationSpec, buildDiffDecorationSpec, buildAnchorDecorationKey, scrollMarginTopValue } from './decorationKeys';
|
|
13
17
|
import { absorbFirstChildMarginReset } from './utils/absorbFirstChildMarginReset';
|
|
14
18
|
import { createDeletedLineBreakDecoration } from './utils/createDeletedLineBreakWidget';
|
|
15
19
|
import { createMarginAbsorber } from './utils/createMarginAbsorber';
|
|
16
20
|
import { createNodeShapedMarginSpacer } from './utils/createNodeShapedMarginSpacer';
|
|
17
21
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
22
|
+
import { isInlineAttrChangeNodeName } from './utils/getAttrChangeRanges';
|
|
18
23
|
import { safeResolve } from './utils/safeResolve';
|
|
19
24
|
import { getTableDiffMode } from './utils/tableDiffMode';
|
|
20
25
|
import { wrapBlockNodeView, createRemovedLozenge, injectInnerWrapper, createContentWrapper } from './utils/wrapBlockNodeView';
|
|
@@ -114,6 +119,32 @@ var createTableCellContentWidgets = function createTableCellContentWidgets(_ref)
|
|
|
114
119
|
return decorations;
|
|
115
120
|
};
|
|
116
121
|
|
|
122
|
+
/**
|
|
123
|
+
* The node name when `change` only swapped one atomic inline node (date, emoji, mention, status)
|
|
124
|
+
* for another of the same type, i.e. an attribute change rather than content added or removed
|
|
125
|
+
* around it.
|
|
126
|
+
*/
|
|
127
|
+
var getAtomicInlineAttrOnlyNodeName = function getAtomicInlineAttrOnlyNodeName(change, doc, newDoc) {
|
|
128
|
+
var nodeA = doc.nodeAt(change.fromA);
|
|
129
|
+
var nodeB = newDoc.nodeAt(change.fromB);
|
|
130
|
+
if (!nodeA || !nodeB || nodeA.type !== nodeB.type || nodeA.nodeSize !== change.toA - change.fromA || nodeB.nodeSize !== change.toB - change.fromB) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
var nodeName = nodeA.type.name;
|
|
134
|
+
return isInlineAttrChangeNodeName(nodeName) ? nodeName : undefined;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/** Wraps an inserted atomic inline node view in the outline an in-place attribute change gets. */
|
|
138
|
+
var createAtomicInlineOutline = function createAtomicInlineOutline(nodeName, nodeView, colorScheme) {
|
|
139
|
+
var outlineWrapper = document.createElement('span');
|
|
140
|
+
outlineWrapper.className = getAtomicInlineChangedAttrs(nodeName, colorScheme).className;
|
|
141
|
+
// Set in both cohorts of `platform_editor_show_diff_color_scheme_refactor`: being inline it beats
|
|
142
|
+
// the stylesheet's purple/green table, so editor-core's rings follow the change's scheme too.
|
|
143
|
+
outlineWrapper.setAttribute('style', buildAtomicInlineChangedCSSVariables(colorSchemeRegistry[colorScheme !== null && colorScheme !== void 0 ? colorScheme : 'standard']));
|
|
144
|
+
outlineWrapper.append(nodeView);
|
|
145
|
+
return outlineWrapper;
|
|
146
|
+
};
|
|
147
|
+
|
|
117
148
|
/**
|
|
118
149
|
* This function is used to create a decoration widget to show content
|
|
119
150
|
* that is not in the current document.
|
|
@@ -385,9 +416,17 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
385
416
|
nodeView.style.setProperty('anchor-name', "--".concat(contributorTagAnchorName));
|
|
386
417
|
}
|
|
387
418
|
if (node.isInline) {
|
|
388
|
-
var
|
|
389
|
-
|
|
390
|
-
|
|
419
|
+
var attrOnlyNodeName = isInserted && fg('platform_editor_ai_show_diff_patch_2') && isExperimentEnabled('platform_editor_show_diff_deleted_nodeview_content') ? getAtomicInlineAttrOnlyNodeName(change, doc, newDoc) : undefined;
|
|
420
|
+
if (attrOnlyNodeName) {
|
|
421
|
+
// Only the node's attributes changed, so outline it as an in-place attribute change
|
|
422
|
+
// does, in place of the highlight. Its own wrapper keeps the outline clear of the node
|
|
423
|
+
// view's styles.
|
|
424
|
+
dom.append(createAtomicInlineOutline(attrOnlyNodeName, nodeView, colorScheme));
|
|
425
|
+
} else {
|
|
426
|
+
var wrapper = createContentWrapper(colorScheme, isActive, isInserted, reveal);
|
|
427
|
+
wrapper.append(nodeView);
|
|
428
|
+
dom.append(wrapper);
|
|
429
|
+
}
|
|
391
430
|
} else {
|
|
392
431
|
// Handle all block nodes with unified function
|
|
393
432
|
wrapBlockNodeView({
|
|
@@ -287,7 +287,28 @@ var applyTextLikeBlockNodeStyles = function applyTextLikeBlockNodeStyles(_ref8)
|
|
|
287
287
|
element.setAttribute('style', "".concat(currentStyle).concat(nodeSpecificStyle));
|
|
288
288
|
}
|
|
289
289
|
var contentStyle = getChangedContentStyle(colorScheme, isActive, isInserted, hideAddedDiffsUnderline);
|
|
290
|
-
|
|
290
|
+
|
|
291
|
+
// Under patch_2, an inserted inline node view (a date, a status lozenge) is highlighted as a whole
|
|
292
|
+
// rather than the text inside it, so the highlight sits behind the node. Rejecting it skips its
|
|
293
|
+
// subtree, so this stays a single walk.
|
|
294
|
+
var highlightInlineNodesWhole = isInserted && fg('platform_editor_ai_show_diff_patch_2');
|
|
295
|
+
// `applyInlineLeafNodeStyles` styles the block's direct inline children itself.
|
|
296
|
+
var handlesDirectInlineChildren = highlightInlineLeafNodes && targetNode.type.inlineContent;
|
|
297
|
+
var inlineNodesToWrap = [];
|
|
298
|
+
var walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, {
|
|
299
|
+
acceptNode: function acceptNode(node) {
|
|
300
|
+
if (node instanceof Text) {
|
|
301
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
302
|
+
}
|
|
303
|
+
if (highlightInlineNodesWhole && node instanceof HTMLElement && node.dataset.prosemirrorNodeInline === 'true') {
|
|
304
|
+
if (!(handlesDirectInlineChildren && node.parentElement === element)) {
|
|
305
|
+
inlineNodesToWrap.push(node);
|
|
306
|
+
}
|
|
307
|
+
return NodeFilter.FILTER_REJECT;
|
|
308
|
+
}
|
|
309
|
+
return NodeFilter.FILTER_SKIP;
|
|
310
|
+
}
|
|
311
|
+
});
|
|
291
312
|
var textNodesToWrap = [];
|
|
292
313
|
var currentNode = walker.nextNode();
|
|
293
314
|
while (currentNode) {
|
|
@@ -296,13 +317,13 @@ var applyTextLikeBlockNodeStyles = function applyTextLikeBlockNodeStyles(_ref8)
|
|
|
296
317
|
}
|
|
297
318
|
currentNode = walker.nextNode();
|
|
298
319
|
}
|
|
299
|
-
textNodesToWrap.forEach(function (
|
|
320
|
+
[].concat(textNodesToWrap, inlineNodesToWrap).forEach(function (node) {
|
|
300
321
|
var contentWrapper = document.createElement('span');
|
|
301
322
|
contentWrapper.setAttribute('style', contentStyle);
|
|
302
|
-
|
|
303
|
-
contentWrapper.append(
|
|
323
|
+
node.replaceWith(contentWrapper);
|
|
324
|
+
contentWrapper.append(node);
|
|
304
325
|
});
|
|
305
|
-
if (
|
|
326
|
+
if (handlesDirectInlineChildren) {
|
|
306
327
|
applyInlineLeafNodeStyles({
|
|
307
328
|
element: element,
|
|
308
329
|
targetNode: targetNode,
|
|
@@ -227,6 +227,9 @@ export declare function buildDeletedWrappedBlockOutline(colors: DiffColorScheme,
|
|
|
227
227
|
* decoration span and read by the `.show-diff-atomic-inline-changed-*` selectors in
|
|
228
228
|
* EditorContentContainer, on the decorated element or a descendant, so it must inherit. Being
|
|
229
229
|
* inline it beats the stylesheet's fallback, making the plugin the only source of the colour.
|
|
230
|
+
*
|
|
231
|
+
* Under patch_2 it also reserves the 2px ring either side, since the ring takes up no space and
|
|
232
|
+
* otherwise paints over an adjacent inline diff.
|
|
230
233
|
*/
|
|
231
234
|
export declare function buildAtomicInlineChangedCSSVariables(colors: DiffColorScheme): string;
|
|
232
235
|
/** Hands editor-core the same strike line the widget path uses, via a custom property. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "25.0.
|
|
3
|
+
"version": "25.0.6",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"@atlaskit/platform-feature-experiments": "^0.3.0",
|
|
40
40
|
"@atlaskit/platform-feature-flags": "^2.2.0",
|
|
41
41
|
"@atlaskit/primitives": "^22.5.0",
|
|
42
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
43
|
-
"@atlaskit/tokens": "^20.
|
|
42
|
+
"@atlaskit/tmp-editor-statsig": "^240.0.0",
|
|
43
|
+
"@atlaskit/tokens": "^20.6.0",
|
|
44
44
|
"@babel/runtime": "^7.0.0",
|
|
45
45
|
"@compiled/react": "^1.0.2",
|
|
46
46
|
"bind-event-listener": "^3.0.0",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"@atlassian/confluence-presets": "workspace:^",
|
|
65
65
|
"@atlassian/content-reconciliation": "^0.1.3506",
|
|
66
66
|
"@atlassian/editor-ai-injected-editors": "^41.0.0",
|
|
67
|
-
"@atlassian/editor-plugin-ai": "^81.
|
|
67
|
+
"@atlassian/editor-plugin-ai": "^81.2.0",
|
|
68
68
|
"@atlassian/structured-docs-types": "workspace:^",
|
|
69
69
|
"react": "^19.2.0",
|
|
70
70
|
"react-dom": "^19.2.0",
|