@atlaskit/editor-plugin-show-diff 6.2.5 → 6.2.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 +8 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +1 -2
- package/dist/cjs/pm-plugins/decorations/colorSchemes/standard.js +19 -1
- package/dist/cjs/pm-plugins/decorations/colorSchemes/traditional.js +18 -2
- package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +13 -10
- package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +83 -14
- package/dist/cjs/pm-plugins/getScrollableDecorations.js +132 -0
- package/dist/cjs/pm-plugins/main.js +12 -25
- package/dist/cjs/pm-plugins/scrollToActiveDecoration.js +50 -9
- package/dist/cjs/showDiffPlugin.js +2 -1
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +1 -2
- package/dist/es2019/pm-plugins/decorations/colorSchemes/standard.js +18 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/traditional.js +17 -1
- package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +13 -9
- package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +80 -18
- package/dist/es2019/pm-plugins/getScrollableDecorations.js +117 -0
- package/dist/es2019/pm-plugins/main.js +11 -22
- package/dist/es2019/pm-plugins/scrollToActiveDecoration.js +50 -10
- package/dist/es2019/showDiffPlugin.js +3 -2
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +1 -2
- package/dist/esm/pm-plugins/decorations/colorSchemes/standard.js +18 -0
- package/dist/esm/pm-plugins/decorations/colorSchemes/traditional.js +17 -1
- package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +13 -10
- package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +85 -16
- package/dist/esm/pm-plugins/getScrollableDecorations.js +124 -0
- package/dist/esm/pm-plugins/main.js +11 -24
- package/dist/esm/pm-plugins/scrollToActiveDecoration.js +50 -9
- package/dist/esm/showDiffPlugin.js +3 -2
- package/dist/types/pm-plugins/decorations/colorSchemes/standard.d.ts +4 -0
- package/dist/types/pm-plugins/decorations/colorSchemes/traditional.d.ts +3 -0
- package/dist/types/pm-plugins/decorations/createNodeChangedDecorationWidget.d.ts +5 -2
- package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeView.d.ts +2 -1
- package/dist/types/pm-plugins/getScrollableDecorations.d.ts +27 -0
- package/dist/types/pm-plugins/main.d.ts +0 -2
- package/dist/types/pm-plugins/scrollToActiveDecoration.d.ts +4 -2
- package/dist/types-ts4.5/pm-plugins/decorations/colorSchemes/standard.d.ts +4 -0
- package/dist/types-ts4.5/pm-plugins/decorations/colorSchemes/traditional.d.ts +3 -0
- package/dist/types-ts4.5/pm-plugins/decorations/createNodeChangedDecorationWidget.d.ts +5 -2
- package/dist/types-ts4.5/pm-plugins/decorations/utils/wrapBlockNodeView.d.ts +2 -1
- package/dist/types-ts4.5/pm-plugins/getScrollableDecorations.d.ts +27 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +0 -2
- package/dist/types-ts4.5/pm-plugins/scrollToActiveDecoration.d.ts +4 -2
- package/package.json +2 -2
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True if `fragment` contains at least one inline node (text, hardBreak, emoji, mention, etc.).
|
|
3
|
+
* Block-only subtrees (e.g. empty paragraphs, block cards with no inline children) return false.
|
|
4
|
+
*/
|
|
5
|
+
function fragmentContainsInlineContent(fragment) {
|
|
6
|
+
for (let i = 0; i < fragment.childCount; i++) {
|
|
7
|
+
const node = fragment.child(i);
|
|
8
|
+
if (node.isInline) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
if (node.content.size > 0 && fragmentContainsInlineContent(node.content)) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Returns true when an inline decoration's [from, to) range can actually show in the document:
|
|
20
|
+
* positions are valid, and the slice contains at least one inline node ProseMirror would paint
|
|
21
|
+
* (not only empty block wrappers or block-only structure).
|
|
22
|
+
*/
|
|
23
|
+
export function isInlineDiffDecorationRenderableInDoc(doc, from, to) {
|
|
24
|
+
try {
|
|
25
|
+
const slice = doc.slice(from, to);
|
|
26
|
+
return fragmentContainsInlineContent(slice.content);
|
|
27
|
+
} catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Checks if range1 is fully contained within range2
|
|
34
|
+
*/
|
|
35
|
+
function isRangeFullyInside(range1Start, range1End, range2Start, range2End) {
|
|
36
|
+
return range2Start <= range1Start && range1End <= range2End;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Gets scrollable decorations from a DecorationSet, filtering out overlapping decorations
|
|
41
|
+
* and applying various rules for diff visualization.
|
|
42
|
+
*
|
|
43
|
+
* Rules:
|
|
44
|
+
* 1. Only includes diff-inline, diff-widget-* and diff-block decorations
|
|
45
|
+
* 2. Excludes listItem diff-block decorations (never scrollable)
|
|
46
|
+
* 3. Deduplicates diff-block decorations with same from, to and nodeName
|
|
47
|
+
* 4. When `doc` is passed: excludes diff-inline decorations whose range has no inline content
|
|
48
|
+
* (invalid positions, or block-only slices with no text/atoms — e.g. empty blocks)
|
|
49
|
+
* 5. Excludes diff-inline decorations that are fully contained within a diff-block
|
|
50
|
+
* 6. Excludes diff-block decorations that are fully contained within a diff-inline
|
|
51
|
+
* 7. Results are sorted by from position, then by to position
|
|
52
|
+
*
|
|
53
|
+
* @param set - The DecorationSet to extract scrollable decorations from
|
|
54
|
+
* @param doc - Current document; when set, diff-inline ranges are validated against this doc
|
|
55
|
+
* @returns Array of scrollable decorations, sorted and deduplicated
|
|
56
|
+
*/
|
|
57
|
+
export const getScrollableDecorations = (set, doc) => {
|
|
58
|
+
if (!set) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const seenBlockKeys = new Set();
|
|
62
|
+
const allDecorations = set.find(undefined, undefined, spec => {
|
|
63
|
+
var _spec$key;
|
|
64
|
+
return spec.key === 'diff-inline' || ((_spec$key = spec.key) === null || _spec$key === void 0 ? void 0 : _spec$key.startsWith('diff-widget')) || spec.key === 'diff-block';
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// First pass: filter out listItem blocks and deduplicates blocks
|
|
68
|
+
const filtered = allDecorations.filter(dec => {
|
|
69
|
+
var _dec$spec, _dec$spec$nodeName, _dec$spec3;
|
|
70
|
+
if (((_dec$spec = dec.spec) === null || _dec$spec === void 0 ? void 0 : _dec$spec.key) === 'diff-block') {
|
|
71
|
+
var _dec$spec2;
|
|
72
|
+
// Skip listItem blocks as they are not scrollable
|
|
73
|
+
if (((_dec$spec2 = dec.spec) === null || _dec$spec2 === void 0 ? void 0 : _dec$spec2.nodeName) === 'listItem') return false;
|
|
74
|
+
}
|
|
75
|
+
const key = `${dec.from}-${dec.to}-${(_dec$spec$nodeName = (_dec$spec3 = dec.spec) === null || _dec$spec3 === void 0 ? void 0 : _dec$spec3.nodeName) !== null && _dec$spec$nodeName !== void 0 ? _dec$spec$nodeName : ''}`;
|
|
76
|
+
// Skip blocks that have already been seen
|
|
77
|
+
if (seenBlockKeys.has(key)) return false;
|
|
78
|
+
seenBlockKeys.add(key);
|
|
79
|
+
return true;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Separate decorations by type for easier processing
|
|
83
|
+
const blocks = filtered.filter(d => {
|
|
84
|
+
var _d$spec;
|
|
85
|
+
return ((_d$spec = d.spec) === null || _d$spec === void 0 ? void 0 : _d$spec.key) === 'diff-block';
|
|
86
|
+
});
|
|
87
|
+
const rawInlines = filtered.filter(d => {
|
|
88
|
+
var _d$spec2;
|
|
89
|
+
return ((_d$spec2 = d.spec) === null || _d$spec2 === void 0 ? void 0 : _d$spec2.key) === 'diff-inline';
|
|
90
|
+
});
|
|
91
|
+
const inlines = doc !== undefined ? rawInlines.filter(d => isInlineDiffDecorationRenderableInDoc(doc, d.from, d.to)) : rawInlines;
|
|
92
|
+
const widgets = filtered.filter(d => {
|
|
93
|
+
var _d$spec3, _d$spec3$key;
|
|
94
|
+
return (_d$spec3 = d.spec) === null || _d$spec3 === void 0 ? void 0 : (_d$spec3$key = _d$spec3.key) === null || _d$spec3$key === void 0 ? void 0 : _d$spec3$key.startsWith('diff-widget');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Second pass: exclude overlapping decorations
|
|
98
|
+
// Rules:
|
|
99
|
+
// - If an inline is fully inside a block, exclude the block (inline takes priority)
|
|
100
|
+
// - If a block is fully inside an inline, exclude the block (inline takes priority)
|
|
101
|
+
const nonOverlappingBlocks = blocks.filter(block => {
|
|
102
|
+
// Exclude block if:
|
|
103
|
+
// 1. It's fully contained within any inline, OR
|
|
104
|
+
// 2. It fully contains any inline
|
|
105
|
+
return !inlines.some(inline => isRangeFullyInside(block.from, block.to, inline.from, inline.to) ||
|
|
106
|
+
// block inside inline
|
|
107
|
+
isRangeFullyInside(inline.from, inline.to, block.from, block.to) // inline inside block
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Combine all non-overlapping decorations
|
|
112
|
+
const result = [...nonOverlappingBlocks, ...inlines, ...widgets];
|
|
113
|
+
|
|
114
|
+
// Sort by from position, then by to position
|
|
115
|
+
result.sort((a, b) => a.from === b.from ? a.to - b.to : a.from - b.from);
|
|
116
|
+
return result;
|
|
117
|
+
};
|
|
@@ -7,29 +7,10 @@ import { fg } from '@atlaskit/platform-feature-flags';
|
|
|
7
7
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
8
8
|
import { calculateDiffDecorations } from './calculateDiff/calculateDiffDecorations';
|
|
9
9
|
import { enforceCustomStepRegisters } from './enforceCustomStepRegisters';
|
|
10
|
+
import { getScrollableDecorations } from './getScrollableDecorations';
|
|
10
11
|
import { NodeViewSerializer } from './NodeViewSerializer';
|
|
11
12
|
import { scrollToActiveDecoration } from './scrollToActiveDecoration';
|
|
12
13
|
export const showDiffPluginKey = new PluginKey('showDiffPlugin');
|
|
13
|
-
export const getScrollableDecorations = set => {
|
|
14
|
-
var _set$find;
|
|
15
|
-
const seenBlockKeys = new Set();
|
|
16
|
-
return ((_set$find = set === null || set === void 0 ? void 0 : set.find(undefined, undefined, spec => {
|
|
17
|
-
var _spec$key;
|
|
18
|
-
return spec.key === 'diff-inline' || ((_spec$key = spec.key) === null || _spec$key === void 0 ? void 0 : _spec$key.startsWith('diff-widget')) || spec.key === 'diff-block';
|
|
19
|
-
})) !== null && _set$find !== void 0 ? _set$find : []).filter(dec => {
|
|
20
|
-
var _dec$spec;
|
|
21
|
-
if (((_dec$spec = dec.spec) === null || _dec$spec === void 0 ? void 0 : _dec$spec.key) === 'diff-block') {
|
|
22
|
-
var _dec$spec2, _dec$spec$nodeName, _dec$spec3;
|
|
23
|
-
// Skip listItem blocks as they are not scrollable
|
|
24
|
-
if (((_dec$spec2 = dec.spec) === null || _dec$spec2 === void 0 ? void 0 : _dec$spec2.nodeName) === 'listItem') return false;
|
|
25
|
-
const key = `${dec.from}-${dec.to}-${(_dec$spec$nodeName = (_dec$spec3 = dec.spec) === null || _dec$spec3 === void 0 ? void 0 : _dec$spec3.nodeName) !== null && _dec$spec$nodeName !== void 0 ? _dec$spec$nodeName : ''}`;
|
|
26
|
-
// Skip blocks that have already been seen
|
|
27
|
-
if (seenBlockKeys.has(key)) return false;
|
|
28
|
-
seenBlockKeys.add(key);
|
|
29
|
-
}
|
|
30
|
-
return true;
|
|
31
|
-
}).sort((a, b) => a.from === b.from ? a.to - b.to : a.from - b.from);
|
|
32
|
-
};
|
|
33
14
|
export const createPlugin = (config, getIntl, api) => {
|
|
34
15
|
if (fg('platform_editor_show_diff_equality_fallback')) {
|
|
35
16
|
enforceCustomStepRegisters();
|
|
@@ -103,7 +84,7 @@ export const createPlugin = (config, getIntl, api) => {
|
|
|
103
84
|
};
|
|
104
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') && fg('platform_editor_show_diff_scroll_navigation')) {
|
|
105
86
|
// Update the active index in plugin state and recalculate decorations
|
|
106
|
-
const decorations = getScrollableDecorations(currentPluginState.decorations);
|
|
87
|
+
const decorations = getScrollableDecorations(currentPluginState.decorations, newState.doc);
|
|
107
88
|
if (decorations.length > 0) {
|
|
108
89
|
var _currentPluginState$a;
|
|
109
90
|
// Initialize to -1 if undefined so that the first "next" scroll takes us to index 0 (first change).
|
|
@@ -161,6 +142,7 @@ export const createPlugin = (config, getIntl, api) => {
|
|
|
161
142
|
setNodeViewSerializer(editorView);
|
|
162
143
|
let isFirst = true;
|
|
163
144
|
let previousActiveIndex;
|
|
145
|
+
let cancelPendingScrollToDecoration = null;
|
|
164
146
|
return {
|
|
165
147
|
update(view) {
|
|
166
148
|
// If we're using configuration to show diffs we initialise here once we setup the editor view
|
|
@@ -179,9 +161,16 @@ export const createPlugin = (config, getIntl, api) => {
|
|
|
179
161
|
const activeIndexChanged = (pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex) !== undefined && pluginState.activeIndex !== previousActiveIndex;
|
|
180
162
|
previousActiveIndex = pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex;
|
|
181
163
|
if ((pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex) !== undefined && activeIndexChanged) {
|
|
182
|
-
|
|
164
|
+
var _cancelPendingScrollT;
|
|
165
|
+
(_cancelPendingScrollT = cancelPendingScrollToDecoration) === null || _cancelPendingScrollT === void 0 ? void 0 : _cancelPendingScrollT();
|
|
166
|
+
cancelPendingScrollToDecoration = scrollToActiveDecoration(view, getScrollableDecorations(pluginState.decorations, view.state.doc), pluginState.activeIndex);
|
|
183
167
|
}
|
|
184
168
|
}
|
|
169
|
+
},
|
|
170
|
+
destroy() {
|
|
171
|
+
var _cancelPendingScrollT2;
|
|
172
|
+
(_cancelPendingScrollT2 = cancelPendingScrollToDecoration) === null || _cancelPendingScrollT2 === void 0 ? void 0 : _cancelPendingScrollT2();
|
|
173
|
+
cancelPendingScrollToDecoration = null;
|
|
185
174
|
}
|
|
186
175
|
};
|
|
187
176
|
},
|
|
@@ -1,26 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extra space above the scrolled-to element so it does not sit flush under the
|
|
3
|
+
* viewport edge (helps with sticky table headers, toolbars, etc.).
|
|
4
|
+
*
|
|
5
|
+
* Implemented with `scroll-margin-top` so we still use the browser’s native
|
|
6
|
+
* `scrollIntoView`, which scrolls every relevant scrollport (nested containers
|
|
7
|
+
* and the window). A single manual `scrollTop` on one ancestor often misses
|
|
8
|
+
* outer scroll or mis-identifies the active scroll container.
|
|
9
|
+
*/
|
|
10
|
+
const SCROLL_TOP_MARGIN_PX = 100;
|
|
11
|
+
|
|
1
12
|
/**
|
|
2
13
|
* Scrolls to the current position/selection of the document. It does the same as scrollIntoView()
|
|
3
14
|
* but without requiring the focus on the editor, thus it can be called at any time.
|
|
4
15
|
*/
|
|
5
|
-
function scrollToSelection(
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
function scrollToSelection(node) {
|
|
17
|
+
const element = node instanceof Element ? node : (node === null || node === void 0 ? void 0 : node.parentElement) instanceof Element ? node.parentElement : null;
|
|
18
|
+
if (!(element instanceof HTMLElement)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// scroll-margin is included in scroll-into-view math; it does not change layout.
|
|
23
|
+
const previousScrollMarginTop = element.style.scrollMarginTop;
|
|
24
|
+
element.style.scrollMarginTop = `${SCROLL_TOP_MARGIN_PX}px`;
|
|
25
|
+
try {
|
|
26
|
+
element.scrollIntoView({
|
|
11
27
|
behavior: 'smooth',
|
|
12
|
-
block: '
|
|
28
|
+
block: 'start'
|
|
13
29
|
});
|
|
30
|
+
} finally {
|
|
31
|
+
element.style.scrollMarginTop = previousScrollMarginTop;
|
|
14
32
|
}
|
|
15
33
|
}
|
|
16
34
|
|
|
17
35
|
/**
|
|
18
|
-
*
|
|
36
|
+
* Schedules scrolling to the decoration at the given index after the next frame.
|
|
37
|
+
*
|
|
38
|
+
* @returns A function that cancels the scheduled `requestAnimationFrame` if it has not run yet.
|
|
19
39
|
*/
|
|
20
40
|
export const scrollToActiveDecoration = (view, decorations, activeIndex) => {
|
|
21
41
|
const decoration = decorations[activeIndex];
|
|
22
42
|
if (!decoration) {
|
|
23
|
-
return;
|
|
43
|
+
return () => {};
|
|
24
44
|
}
|
|
25
|
-
|
|
45
|
+
let rafId = requestAnimationFrame(() => {
|
|
46
|
+
var _decoration$spec;
|
|
47
|
+
rafId = null;
|
|
48
|
+
if (((_decoration$spec = decoration.spec) === null || _decoration$spec === void 0 ? void 0 : _decoration$spec.key) === 'diff-widget-active') {
|
|
49
|
+
var _decoration$type;
|
|
50
|
+
// @ts-expect-error - decoration.type is not typed public API
|
|
51
|
+
const widgetDom = decoration === null || decoration === void 0 ? void 0 : (_decoration$type = decoration.type) === null || _decoration$type === void 0 ? void 0 : _decoration$type.toDOM;
|
|
52
|
+
scrollToSelection(widgetDom);
|
|
53
|
+
} else {
|
|
54
|
+
var _view$domAtPos;
|
|
55
|
+
const targetNode = view.nodeDOM(decoration === null || decoration === void 0 ? void 0 : decoration.from);
|
|
56
|
+
const node = targetNode instanceof Element ? targetNode : (_view$domAtPos = view.domAtPos(decoration === null || decoration === void 0 ? void 0 : decoration.from)) === null || _view$domAtPos === void 0 ? void 0 : _view$domAtPos.node;
|
|
57
|
+
scrollToSelection(node);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
return () => {
|
|
61
|
+
if (rafId !== null) {
|
|
62
|
+
cancelAnimationFrame(rafId);
|
|
63
|
+
rafId = null;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
26
66
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
-
import {
|
|
2
|
+
import { getScrollableDecorations } from './pm-plugins/getScrollableDecorations';
|
|
3
|
+
import { createPlugin, showDiffPluginKey } from './pm-plugins/main';
|
|
3
4
|
export const showDiffPlugin = ({
|
|
4
5
|
api,
|
|
5
6
|
config
|
|
@@ -54,7 +55,7 @@ export const showDiffPlugin = ({
|
|
|
54
55
|
};
|
|
55
56
|
}
|
|
56
57
|
const pluginState = showDiffPluginKey.getState(editorState);
|
|
57
|
-
const decorationCount = fg('platform_editor_show_diff_scroll_navigation') ? getScrollableDecorations(pluginState === null || pluginState === void 0 ? void 0 : pluginState.decorations) : (pluginState === null || pluginState === void 0 ? void 0 : (_pluginState$decorati = pluginState.decorations) === null || _pluginState$decorati === void 0 ? void 0 : _pluginState$decorati.find()) || [];
|
|
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()) || [];
|
|
58
59
|
return {
|
|
59
60
|
isDisplayingChanges: decorationCount.length > 0,
|
|
60
61
|
activeIndex: pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex,
|
|
@@ -167,7 +167,6 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
|
|
|
167
167
|
}))));
|
|
168
168
|
}
|
|
169
169
|
if (change.deleted.length > 0) {
|
|
170
|
-
var _isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.fromB === activeIndexPos.to;
|
|
171
170
|
var decoration = createNodeChangedDecorationWidget(_objectSpread({
|
|
172
171
|
change: change,
|
|
173
172
|
doc: originalDoc,
|
|
@@ -175,7 +174,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
|
|
|
175
174
|
colorScheme: colorScheme,
|
|
176
175
|
newDoc: tr.doc,
|
|
177
176
|
intl: intl,
|
|
178
|
-
|
|
177
|
+
activeIndexPos: activeIndexPos
|
|
179
178
|
}, expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) && {
|
|
180
179
|
isInserted: !isInserted
|
|
181
180
|
}));
|
|
@@ -59,14 +59,32 @@ export var deletedStyleQuoteNodeWithLozenge = convertToInlineCss({
|
|
|
59
59
|
boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-gray, #7D818A)"),
|
|
60
60
|
borderRadius: "var(--ds-radius-small, 4px)"
|
|
61
61
|
});
|
|
62
|
+
|
|
63
|
+
/** Stronger outline when this deleted block decoration is the active scroll target */
|
|
64
|
+
export var deletedStyleQuoteNodeWithLozengeActive = convertToInlineCss({
|
|
65
|
+
marginTop: "var(--ds-space-150, 12px)",
|
|
66
|
+
paddingTop: "var(--ds-space-025, 2px)",
|
|
67
|
+
paddingBottom: "var(--ds-space-025, 2px)",
|
|
68
|
+
paddingLeft: "var(--ds-space-025, 2px)",
|
|
69
|
+
boxShadow: "0 0 0 2px ".concat("var(--ds-border-accent-red, #E2483D)"),
|
|
70
|
+
borderRadius: "var(--ds-radius-small, 4px)"
|
|
71
|
+
});
|
|
62
72
|
export var deletedBlockOutline = convertToInlineCss({
|
|
63
73
|
boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-gray, #7D818A)"),
|
|
64
74
|
borderRadius: "var(--ds-radius-small, 4px)"
|
|
65
75
|
});
|
|
76
|
+
export var deletedBlockOutlineActive = convertToInlineCss({
|
|
77
|
+
boxShadow: "0 0 0 2px ".concat("var(--ds-border-accent-red, #E2483D)"),
|
|
78
|
+
borderRadius: "var(--ds-radius-small, 4px)"
|
|
79
|
+
});
|
|
66
80
|
export var deletedBlockOutlineRounded = convertToInlineCss({
|
|
67
81
|
boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-gray, #7D818A)"),
|
|
68
82
|
borderRadius: "calc(".concat("var(--ds-radius-xsmall, 2px)", " + 1px)")
|
|
69
83
|
});
|
|
84
|
+
export var deletedBlockOutlineRoundedActive = convertToInlineCss({
|
|
85
|
+
boxShadow: "0 0 0 2px ".concat("var(--ds-border-accent-red, #E2483D)"),
|
|
86
|
+
borderRadius: "calc(".concat("var(--ds-radius-xsmall, 2px)", " + 1px)")
|
|
87
|
+
});
|
|
70
88
|
export var deletedRowStyle = convertToInlineCss({
|
|
71
89
|
color: "var(--ds-text-accent-gray, #505258)",
|
|
72
90
|
textDecoration: 'line-through',
|
|
@@ -44,7 +44,7 @@ export var deletedTraditionalContentStyleUnboundedActive = convertToInlineCss({
|
|
|
44
44
|
top: '50%',
|
|
45
45
|
width: '100%',
|
|
46
46
|
display: 'inline-block',
|
|
47
|
-
borderTop: "
|
|
47
|
+
borderTop: "2px solid ".concat("var(--ds-border-accent-red, #E2483D)"),
|
|
48
48
|
pointerEvents: 'none',
|
|
49
49
|
zIndex: 1
|
|
50
50
|
});
|
|
@@ -56,14 +56,30 @@ export var deletedTraditionalStyleQuoteNode = convertToInlineCss({
|
|
|
56
56
|
boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-red, #E2483D)"),
|
|
57
57
|
borderRadius: "var(--ds-radius-small, 4px)"
|
|
58
58
|
});
|
|
59
|
+
export var deletedTraditionalStyleQuoteNodeActive = convertToInlineCss({
|
|
60
|
+
marginTop: "var(--ds-space-150, 12px)",
|
|
61
|
+
paddingTop: "var(--ds-space-025, 2px)",
|
|
62
|
+
paddingBottom: "var(--ds-space-025, 2px)",
|
|
63
|
+
paddingLeft: "var(--ds-space-025, 2px)",
|
|
64
|
+
boxShadow: "0 0 0 2px ".concat("var(--ds-border-accent-red, #E2483D)"),
|
|
65
|
+
borderRadius: "var(--ds-radius-small, 4px)"
|
|
66
|
+
});
|
|
59
67
|
export var deletedTraditionalBlockOutline = convertToInlineCss({
|
|
60
68
|
boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-red, #E2483D)"),
|
|
61
69
|
borderRadius: "var(--ds-radius-small, 4px)"
|
|
62
70
|
});
|
|
71
|
+
export var deletedTraditionalBlockOutlineActive = convertToInlineCss({
|
|
72
|
+
boxShadow: "0 0 0 2px ".concat("var(--ds-border-accent-red, #E2483D)"),
|
|
73
|
+
borderRadius: "var(--ds-radius-small, 4px)"
|
|
74
|
+
});
|
|
63
75
|
export var deletedTraditionalBlockOutlineRounded = convertToInlineCss({
|
|
64
76
|
boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-red, #E2483D)"),
|
|
65
77
|
borderRadius: "calc(".concat("var(--ds-radius-xsmall, 2px)", " + 1px)")
|
|
66
78
|
});
|
|
79
|
+
export var deletedTraditionalBlockOutlineRoundedActive = convertToInlineCss({
|
|
80
|
+
boxShadow: "0 0 0 2px ".concat("var(--ds-border-accent-red, #E2483D)"),
|
|
81
|
+
borderRadius: "calc(".concat("var(--ds-radius-xsmall, 2px)", " + 1px)")
|
|
82
|
+
});
|
|
67
83
|
export var deletedTraditionalRowStyle = convertToInlineCss({
|
|
68
84
|
textDecorationColor: "var(--ds-border-accent-red, #E2483D)",
|
|
69
85
|
textDecoration: 'line-through',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
2
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
3
3
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
4
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
5
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
5
6
|
import { editingStyle, editingStyleActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleNewActive, deletedContentStyleUnbounded } from './colorSchemes/standard';
|
|
6
7
|
import { traditionalInsertStyle, traditionalInsertStyleActive, deletedTraditionalContentStyle, deletedTraditionalContentStyleActive, deletedTraditionalContentStyleUnbounded, deletedTraditionalContentStyleUnboundedActive } from './colorSchemes/traditional';
|
|
@@ -79,13 +80,13 @@ var createContentWrapper = function createContentWrapper(colorScheme) {
|
|
|
79
80
|
} else {
|
|
80
81
|
wrapper.setAttribute('style', "".concat(baseStyle).concat(getDeletedContentStyle(colorScheme, isActive)));
|
|
81
82
|
var strikethrough = document.createElement('span');
|
|
82
|
-
strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colorScheme));
|
|
83
|
+
strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colorScheme, isActive));
|
|
83
84
|
wrapper.append(strikethrough);
|
|
84
85
|
}
|
|
85
86
|
} else {
|
|
86
87
|
wrapper.setAttribute('style', "".concat(baseStyle).concat(getDeletedContentStyle(colorScheme, isActive)));
|
|
87
88
|
var _strikethrough = document.createElement('span');
|
|
88
|
-
_strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colorScheme));
|
|
89
|
+
_strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colorScheme, isActive));
|
|
89
90
|
wrapper.append(_strikethrough);
|
|
90
91
|
}
|
|
91
92
|
return wrapper;
|
|
@@ -96,18 +97,23 @@ var createContentWrapper = function createContentWrapper(colorScheme) {
|
|
|
96
97
|
* that is not in the current document.
|
|
97
98
|
*/
|
|
98
99
|
export var createNodeChangedDecorationWidget = function createNodeChangedDecorationWidget(_ref2) {
|
|
100
|
+
var _slice$content, _slice$content2, _slice$content3;
|
|
99
101
|
var change = _ref2.change,
|
|
100
102
|
doc = _ref2.doc,
|
|
101
103
|
nodeViewSerializer = _ref2.nodeViewSerializer,
|
|
102
104
|
colorScheme = _ref2.colorScheme,
|
|
103
105
|
newDoc = _ref2.newDoc,
|
|
104
106
|
intl = _ref2.intl,
|
|
105
|
-
|
|
106
|
-
isActive = _ref2$isActive === void 0 ? false : _ref2$isActive,
|
|
107
|
+
activeIndexPos = _ref2.activeIndexPos,
|
|
107
108
|
_ref2$isInserted = _ref2.isInserted,
|
|
108
109
|
isInserted = _ref2$isInserted === void 0 ? false : _ref2$isInserted;
|
|
109
110
|
var slice = doc.slice(change.fromA, change.toA);
|
|
110
|
-
|
|
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 && fg('platform_editor_show_diff_scroll_navigation');
|
|
112
|
+
// Widget decoration used for deletions as the content is not in the document
|
|
113
|
+
// and we want to display the deleted content with a style.
|
|
114
|
+
var safeInsertPos = findSafeInsertPos(newDoc, change.fromB, slice);
|
|
115
|
+
var isActive = activeIndexPos && safeInsertPos === activeIndexPos.from && safeInsertPos === activeIndexPos.to;
|
|
116
|
+
if (slice.content.content.length === 0 || shouldSkipDeletedEmptyParagraphDecoration) {
|
|
111
117
|
return;
|
|
112
118
|
}
|
|
113
119
|
var isTableCellContent = slice.content.content.some(function () {
|
|
@@ -215,6 +221,7 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
215
221
|
targetNode: node,
|
|
216
222
|
colorScheme: colorScheme,
|
|
217
223
|
intl: intl,
|
|
224
|
+
isActive: isActive,
|
|
218
225
|
isInserted: isInserted
|
|
219
226
|
});
|
|
220
227
|
}
|
|
@@ -224,7 +231,7 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
224
231
|
} else {
|
|
225
232
|
var fallbackNode = fallbackSerialization();
|
|
226
233
|
if (fallbackNode) {
|
|
227
|
-
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
234
|
+
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) || fg('platform_editor_show_diff_scroll_navigation')) {
|
|
228
235
|
if (fallbackNode instanceof HTMLElement) {
|
|
229
236
|
var injectedNode = injectInnerWrapper({
|
|
230
237
|
node: fallbackNode,
|
|
@@ -247,10 +254,6 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
247
254
|
}
|
|
248
255
|
});
|
|
249
256
|
dom.setAttribute('data-testid', 'show-diff-deleted-decoration');
|
|
250
|
-
|
|
251
|
-
// Widget decoration used for deletions as the content is not in the document
|
|
252
|
-
// and we want to display the deleted content with a style.
|
|
253
|
-
var safeInsertPos = findSafeInsertPos(newDoc, change.fromB, slice);
|
|
254
257
|
var decorations = [];
|
|
255
258
|
decorations.push(Decoration.widget(safeInsertPos, dom, {
|
|
256
259
|
key: "diff-widget-".concat(isActive ? 'active' : 'inactive')
|