@atlaskit/editor-plugin-show-diff 14.3.2 → 14.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/afm-cc/tsconfig.json +18 -0
- package/afm-products/tsconfig.json +18 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +47 -26
- package/dist/cjs/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +61 -9
- package/dist/cjs/pm-plugins/decorations/colorSchemes/attributions.js +77 -20
- package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +10 -0
- package/dist/cjs/pm-plugins/decorations/colorSchemes/types.js +2 -0
- package/dist/cjs/pm-plugins/decorations/createAnchorDecorationWidgets.js +52 -7
- package/dist/cjs/pm-plugins/decorations/createContributorTagWidget.js +172 -0
- package/dist/cjs/pm-plugins/decorations/createInlineChangedDecoration.js +37 -5
- package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +40 -7
- package/dist/cjs/pm-plugins/decorations/decorationKeys.js +31 -5
- package/dist/cjs/pm-plugins/decorations/extractContributorTags.js +128 -0
- package/dist/cjs/pm-plugins/main.js +57 -6
- package/dist/cjs/pm-plugins/resolveDiffContributors.js +143 -0
- package/dist/cjs/showDiffPlugin.js +21 -6
- package/dist/cjs/ui/ContributorTag/ContributorTag.compiled.css +29 -0
- package/dist/cjs/ui/ContributorTag/ContributorTag.js +383 -0
- package/dist/cjs/ui/ContributorTag/ContributorTagWidget.js +50 -0
- package/dist/cjs/ui/ContributorTag/messages.js +24 -0
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +48 -27
- package/dist/es2019/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +39 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/attributions.js +53 -11
- package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +9 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/types.js +2 -0
- package/dist/es2019/pm-plugins/decorations/createAnchorDecorationWidgets.js +43 -1
- package/dist/es2019/pm-plugins/decorations/createContributorTagWidget.js +163 -0
- package/dist/es2019/pm-plugins/decorations/createInlineChangedDecoration.js +38 -5
- package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +38 -6
- package/dist/es2019/pm-plugins/decorations/decorationKeys.js +30 -2
- package/dist/es2019/pm-plugins/decorations/extractContributorTags.js +101 -0
- package/dist/es2019/pm-plugins/main.js +52 -3
- package/dist/es2019/pm-plugins/resolveDiffContributors.js +128 -0
- package/dist/es2019/showDiffPlugin.js +20 -5
- package/dist/es2019/ui/ContributorTag/ContributorTag.compiled.css +29 -0
- package/dist/es2019/ui/ContributorTag/ContributorTag.js +312 -0
- package/dist/es2019/ui/ContributorTag/ContributorTagWidget.js +43 -0
- package/dist/es2019/ui/ContributorTag/messages.js +18 -0
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +49 -28
- package/dist/esm/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +60 -8
- package/dist/esm/pm-plugins/decorations/colorSchemes/attributions.js +77 -19
- package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +9 -0
- package/dist/esm/pm-plugins/decorations/colorSchemes/types.js +2 -0
- package/dist/esm/pm-plugins/decorations/createAnchorDecorationWidgets.js +51 -6
- package/dist/esm/pm-plugins/decorations/createContributorTagWidget.js +166 -0
- package/dist/esm/pm-plugins/decorations/createInlineChangedDecoration.js +37 -5
- package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +40 -7
- package/dist/esm/pm-plugins/decorations/decorationKeys.js +30 -5
- package/dist/esm/pm-plugins/decorations/extractContributorTags.js +122 -0
- package/dist/esm/pm-plugins/main.js +57 -6
- package/dist/esm/pm-plugins/resolveDiffContributors.js +137 -0
- package/dist/esm/showDiffPlugin.js +21 -6
- package/dist/esm/ui/ContributorTag/ContributorTag.compiled.css +29 -0
- package/dist/esm/ui/ContributorTag/ContributorTag.js +375 -0
- package/dist/esm/ui/ContributorTag/ContributorTagWidget.js +43 -0
- package/dist/esm/ui/ContributorTag/messages.js +18 -0
- package/dist/types/entry-points/show-diff-plugin-type.d.ts +1 -1
- package/dist/types/pm-plugins/calculateDiff/calculateDiffDecorations.d.ts +7 -1
- package/dist/types/pm-plugins/calculateDiff/simplifyChangesWithAttribution.d.ts +10 -0
- package/dist/types/pm-plugins/decorations/colorSchemes/attributions.d.ts +24 -2
- package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +7 -1
- package/dist/types/pm-plugins/decorations/colorSchemes/schemes.d.ts +1 -2
- package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +2 -1
- package/dist/types/pm-plugins/decorations/createAnchorDecorationWidgets.d.ts +14 -0
- package/dist/types/pm-plugins/decorations/createContributorTagWidget.d.ts +55 -0
- package/dist/types/pm-plugins/decorations/createInlineChangedDecoration.d.ts +5 -1
- package/dist/types/pm-plugins/decorations/createNodeChangedDecorationWidget.d.ts +5 -1
- package/dist/types/pm-plugins/decorations/decorationKeys.d.ts +28 -3
- package/dist/types/pm-plugins/decorations/extractContributorTags.d.ts +9 -0
- package/dist/types/pm-plugins/main.d.ts +8 -2
- package/dist/types/pm-plugins/resolveDiffContributors.d.ts +7 -0
- package/dist/types/showDiffPluginType.d.ts +65 -2
- package/dist/types/ui/ContributorTag/ContributorTag.d.ts +37 -0
- package/dist/types/ui/ContributorTag/ContributorTagWidget.d.ts +22 -0
- package/dist/types/ui/ContributorTag/messages.d.ts +6 -0
- package/package.json +16 -7
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
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
|
+
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
|
+
import { createElement } from 'react';
|
|
5
|
+
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
6
|
+
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
7
|
+
import { ContributorTagWidget } from '../../ui/ContributorTag/ContributorTagWidget';
|
|
8
|
+
import { clampAnchorPosIntoCell } from './createAnchorDecorationWidgets';
|
|
9
|
+
import { buildContributorTagDecorationSpec, DecorationFamily } from './decorationKeys';
|
|
10
|
+
|
|
11
|
+
/** Marks the host element of one tag, so a tag can be found in the document by its own diff. */
|
|
12
|
+
export var CONTRIBUTOR_TAG_HOST_ATTRIBUTE = 'data-contributor-tag-host';
|
|
13
|
+
|
|
14
|
+
// Contributor tags only render behind this gate — see `areAttributionColorGatesEnabled`.
|
|
15
|
+
var isContributorTagWidgetEnabled = function isContributorTagWidgetEnabled() {
|
|
16
|
+
return fg('confluence_ncs_step_diffing_version_history');
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Everything a tag needs to mount itself into the document, plumbed down from the plugin. Absent in
|
|
21
|
+
* unit tests that build decorations directly: the hosts are still emitted, they just stay empty.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** A mounted tag, so whoever emitted the host can take it down again. */
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Unique per mount rather than per diff, because ProseMirror draws a replacement widget before it
|
|
28
|
+
* destroys the widget being replaced: on a shared key the outgoing widget's `destroy` would
|
|
29
|
+
* unregister the incoming widget's portal.
|
|
30
|
+
*/
|
|
31
|
+
var nextContributorTagPortalId = 0;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Renders the tag into `host` through the editor's portal provider, the way the rest of the editor
|
|
35
|
+
* mounts React into decorations. The tag resolves its own model from plugin state, so a redraw of
|
|
36
|
+
* the host re-parents the tag instead of stranding it, and `isActive` changes arrive as a re-render.
|
|
37
|
+
*/
|
|
38
|
+
export var mountContributorTag = function mountContributorTag(_ref) {
|
|
39
|
+
var diffId = _ref.diffId,
|
|
40
|
+
host = _ref.host,
|
|
41
|
+
mountContext = _ref.mountContext;
|
|
42
|
+
if (!mountContext) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
var api = mountContext.api,
|
|
46
|
+
getEditorRoot = mountContext.getEditorRoot,
|
|
47
|
+
portalProviderAPI = mountContext.portalProviderAPI;
|
|
48
|
+
var key = "".concat(DecorationFamily.contributorTag, "-").concat(diffId, "-").concat(nextContributorTagPortalId++);
|
|
49
|
+
portalProviderAPI.render(function () {
|
|
50
|
+
return /*#__PURE__*/createElement(ContributorTagWidget, {
|
|
51
|
+
api: api,
|
|
52
|
+
diffId: diffId,
|
|
53
|
+
getEditorRoot: getEditorRoot
|
|
54
|
+
});
|
|
55
|
+
}, host, key);
|
|
56
|
+
return {
|
|
57
|
+
key: key,
|
|
58
|
+
portalProviderAPI: portalProviderAPI
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
export var unmountContributorTag = function unmountContributorTag(mount) {
|
|
62
|
+
mount === null || mount === void 0 || mount.portalProviderAPI.remove(mount.key);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* A zero-size inline host for one contributor tag. `position: relative` makes it the containing
|
|
67
|
+
* block of the absolutely positioned tag, so the tag sits on the change with no measurement.
|
|
68
|
+
*/
|
|
69
|
+
var buildContributorTagHost = function buildContributorTagHost(diffId) {
|
|
70
|
+
var host = document.createElement('span');
|
|
71
|
+
host.setAttribute(CONTRIBUTOR_TAG_HOST_ATTRIBUTE, diffId);
|
|
72
|
+
host.style.setProperty('position', 'relative');
|
|
73
|
+
return host;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The host for a tag on deleted content, which renders inside its own widget decoration rather than
|
|
78
|
+
* needing one of its own. Unmount with `unmountContributorTag` from that widget's `destroy`.
|
|
79
|
+
*/
|
|
80
|
+
export var createContributorTagHost = function createContributorTagHost(diffId, mountContext) {
|
|
81
|
+
if (!isContributorTagWidgetEnabled()) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
var host = buildContributorTagHost(diffId);
|
|
85
|
+
return {
|
|
86
|
+
host: host,
|
|
87
|
+
mount: mountContributorTag({
|
|
88
|
+
diffId: diffId,
|
|
89
|
+
host: host,
|
|
90
|
+
mountContext: mountContext
|
|
91
|
+
})
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The start of the inline content that `[from, to)` actually highlights.
|
|
97
|
+
*
|
|
98
|
+
* `from` is not sufficient: a range can begin at the tail of one paragraph and only cover text in a
|
|
99
|
+
* later block, and ProseMirror clips `Decoration.inline` to the content it can paint — so a host
|
|
100
|
+
* left at `from` would sit lines away from the highlight.
|
|
101
|
+
*/
|
|
102
|
+
var resolveInlineContentStart = function resolveInlineContentStart(doc, from, to) {
|
|
103
|
+
var edge;
|
|
104
|
+
doc.nodesBetween(from, to, function (node, nodePos) {
|
|
105
|
+
if (!node.isTextblock) {
|
|
106
|
+
return edge === undefined;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// The slice of this block the range actually covers; empty means nothing paintable.
|
|
110
|
+
var contentFrom = Math.max(nodePos + 1, from);
|
|
111
|
+
var contentTo = Math.min(nodePos + 1 + node.content.size, to);
|
|
112
|
+
if (contentTo > contentFrom && edge === undefined) {
|
|
113
|
+
edge = contentFrom;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Textblocks have no block children to descend into.
|
|
117
|
+
return false;
|
|
118
|
+
});
|
|
119
|
+
return edge !== null && edge !== void 0 ? edge : from;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* A widget hosting the contributor tag of one inline diff range, placed on the first character the
|
|
124
|
+
* range highlights.
|
|
125
|
+
*
|
|
126
|
+
* The tag is mounted in `toDOM` and taken down in `destroy`, so it lives exactly as long as the host
|
|
127
|
+
* element ProseMirror drew it into — see `mountContributorTag`.
|
|
128
|
+
*/
|
|
129
|
+
export var createContributorTagWidget = function createContributorTagWidget(_ref2) {
|
|
130
|
+
var doc = _ref2.doc,
|
|
131
|
+
from = _ref2.from,
|
|
132
|
+
to = _ref2.to,
|
|
133
|
+
diffId = _ref2.diffId,
|
|
134
|
+
mountContext = _ref2.mountContext;
|
|
135
|
+
if (!isContributorTagWidgetEnabled()) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Reassigned when ProseMirror redraws this decoration, which it may do more than once for the
|
|
140
|
+
// same `Decoration` instance.
|
|
141
|
+
var mount;
|
|
142
|
+
return Decoration.widget(
|
|
143
|
+
// Keep the host out of the table row's grid (EDITOR-8442).
|
|
144
|
+
clampAnchorPosIntoCell(doc, resolveInlineContentStart(doc, from, to), 1), function () {
|
|
145
|
+
var host = buildContributorTagHost(diffId);
|
|
146
|
+
mount = mountContributorTag({
|
|
147
|
+
diffId: diffId,
|
|
148
|
+
host: host,
|
|
149
|
+
mountContext: mountContext
|
|
150
|
+
});
|
|
151
|
+
return host;
|
|
152
|
+
}, _objectSpread(_objectSpread({}, buildContributorTagDecorationSpec(diffId)), {}, {
|
|
153
|
+
side: 1,
|
|
154
|
+
// The tag is chrome: it inherits no surrounding mark, and its own events are not the
|
|
155
|
+
// document's to handle.
|
|
156
|
+
marks: [],
|
|
157
|
+
ignoreSelection: true,
|
|
158
|
+
stopEvent: function stopEvent() {
|
|
159
|
+
return true;
|
|
160
|
+
},
|
|
161
|
+
destroy: function destroy() {
|
|
162
|
+
unmountContributorTag(mount);
|
|
163
|
+
mount = undefined;
|
|
164
|
+
}
|
|
165
|
+
}));
|
|
166
|
+
};
|
|
@@ -9,6 +9,7 @@ import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
|
9
9
|
import { buildAtomicInlineChangedCSSVariables, buildDeletedInlineContentStyleExtended, buildDeletedInlineStyle, buildDeletedInlineStyleStandard, buildInsertStyle, buildInsertStyleActive, buildInsertStyleExtended, buildInsertStyleExtendedActive, buildInsertStyleExtendedNoUnderline, buildInsertStyleExtendedNoUnderlineActive } from './colorSchemes/factory';
|
|
10
10
|
import { colorSchemeRegistry, getLegacyColorScheme } from './colorSchemes/schemes';
|
|
11
11
|
import { createInlineIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
|
|
12
|
+
import { createContributorTagWidget } from './createContributorTagWidget';
|
|
12
13
|
import { getAtomicInlineNodeClassNameLegacy, resolveInlineChangedStyleLegacy } from './createInlineChangedDecoration.styles.legacy';
|
|
13
14
|
import { buildDiffDecorationSpec } from './decorationKeys';
|
|
14
15
|
var displayNoneStyle = convertToInlineCss({
|
|
@@ -102,7 +103,8 @@ export var getAtomicInlineChangedAttrs = function getAtomicInlineChangedAttrs(in
|
|
|
102
103
|
*/
|
|
103
104
|
|
|
104
105
|
export var createInlineChangedDecoration = function createInlineChangedDecoration(_ref2) {
|
|
105
|
-
var
|
|
106
|
+
var attributionKey = _ref2.attributionKey,
|
|
107
|
+
change = _ref2.change,
|
|
106
108
|
colorScheme = _ref2.colorScheme,
|
|
107
109
|
_ref2$isActive = _ref2.isActive,
|
|
108
110
|
isActive = _ref2$isActive === void 0 ? false : _ref2$isActive,
|
|
@@ -112,6 +114,8 @@ export var createInlineChangedDecoration = function createInlineChangedDecoratio
|
|
|
112
114
|
isAtomicInlineNode = _ref2$isAtomicInlineN === void 0 ? false : _ref2$isAtomicInlineN,
|
|
113
115
|
_ref2$shouldHideDelet = _ref2.shouldHideDeleted,
|
|
114
116
|
shouldHideDeleted = _ref2$shouldHideDelet === void 0 ? false : _ref2$shouldHideDelet,
|
|
117
|
+
_ref2$showContributor = _ref2.showContributorTags,
|
|
118
|
+
showContributorTags = _ref2$showContributor === void 0 ? false : _ref2$showContributor,
|
|
115
119
|
_ref2$showIndicators = _ref2.showIndicators,
|
|
116
120
|
showIndicators = _ref2$showIndicators === void 0 ? false : _ref2$showIndicators,
|
|
117
121
|
doc = _ref2.doc,
|
|
@@ -122,15 +126,23 @@ export var createInlineChangedDecoration = function createInlineChangedDecoratio
|
|
|
122
126
|
_ref2$hasDeletedWidge = _ref2.hasDeletedWidget,
|
|
123
127
|
hasDeletedWidget = _ref2$hasDeletedWidge === void 0 ? false : _ref2$hasDeletedWidge,
|
|
124
128
|
_ref2$isDeletedWidget = _ref2.isDeletedWidgetBelow,
|
|
125
|
-
isDeletedWidgetBelow = _ref2$isDeletedWidget === void 0 ? false : _ref2$isDeletedWidget
|
|
126
|
-
|
|
129
|
+
isDeletedWidgetBelow = _ref2$isDeletedWidget === void 0 ? false : _ref2$isDeletedWidget,
|
|
130
|
+
tagMountContext = _ref2.tagMountContext;
|
|
131
|
+
// Derived from the range so it survives a recalculation: stepping to the next/previous change
|
|
132
|
+
// rebuilds decorations without touching the doc, and a fresh id would change the React key and the
|
|
133
|
+
// tag host's key, remounting every tag mid-step. Random ids are kept when tags are off.
|
|
134
|
+
var diffId = showContributorTags ? "inline-".concat(change.fromB, "-").concat(change.toB) : crypto.randomUUID();
|
|
127
135
|
if (shouldHideDeleted) {
|
|
128
136
|
return [Decoration.inline(change.fromB, change.toB, {
|
|
129
137
|
style: displayNoneStyle
|
|
130
138
|
}, buildDiffDecorationSpec({
|
|
139
|
+
// No attribution: this decoration paints nothing and emits no tag host, so a tag
|
|
140
|
+
// resolved from it would have nowhere to render.
|
|
141
|
+
colorScheme: colorScheme,
|
|
131
142
|
decorationType: 'inline',
|
|
132
143
|
diffId: diffId,
|
|
133
|
-
isActive: isActive
|
|
144
|
+
isActive: isActive,
|
|
145
|
+
isInserted: isInserted
|
|
134
146
|
}))];
|
|
135
147
|
}
|
|
136
148
|
var colors = getColorScheme(colorScheme);
|
|
@@ -150,10 +162,15 @@ export var createInlineChangedDecoration = function createInlineChangedDecoratio
|
|
|
150
162
|
class: atomicInlineAttrs.className
|
|
151
163
|
}), {}, {
|
|
152
164
|
'data-testid': 'show-diff-changed-decoration'
|
|
165
|
+
}, showContributorTags && {
|
|
166
|
+
'data-diff-id': diffId
|
|
153
167
|
}), buildDiffDecorationSpec({
|
|
168
|
+
attributionKey: attributionKey,
|
|
169
|
+
colorScheme: colorScheme,
|
|
154
170
|
decorationType: 'inline',
|
|
155
171
|
diffId: diffId,
|
|
156
|
-
isActive: isActive
|
|
172
|
+
isActive: isActive,
|
|
173
|
+
isInserted: isInserted
|
|
157
174
|
}))];
|
|
158
175
|
if (showIndicators && doc && isExtendedEnabled(diffType)) {
|
|
159
176
|
// For paragraphs, fromB/toB land on the outer block
|
|
@@ -190,5 +207,20 @@ export var createInlineChangedDecoration = function createInlineChangedDecoratio
|
|
|
190
207
|
diffId: diffId
|
|
191
208
|
})));
|
|
192
209
|
}
|
|
210
|
+
|
|
211
|
+
// Built from the raw change range, not the anchors above: a tag lines up with the changed text,
|
|
212
|
+
// while the bar's anchors are held on a block boundary when a deleted widget renders beside them.
|
|
213
|
+
if (showContributorTags && doc && isExtendedEnabled(diffType)) {
|
|
214
|
+
var tagWidget = createContributorTagWidget({
|
|
215
|
+
doc: doc,
|
|
216
|
+
from: change.fromB,
|
|
217
|
+
to: change.toB,
|
|
218
|
+
diffId: diffId,
|
|
219
|
+
mountContext: tagMountContext
|
|
220
|
+
});
|
|
221
|
+
if (tagWidget) {
|
|
222
|
+
decorations.push(tagWidget);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
193
225
|
return decorations;
|
|
194
226
|
};
|
|
@@ -6,6 +6,7 @@ import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
|
6
6
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
7
7
|
import { createLeftAnchorWidget } from './createAnchorDecorationWidgets';
|
|
8
8
|
import { createChangedRowDecorationWidgets } from './createChangedRowDecorationWidgets';
|
|
9
|
+
import { createContributorTagHost, unmountContributorTag } from './createContributorTagWidget';
|
|
9
10
|
import { buildDiffDecorationSpec, buildAnchorDecorationKey } from './decorationKeys';
|
|
10
11
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
11
12
|
import { wrapBlockNodeView, injectInnerWrapper, createContentWrapper } from './utils/wrapBlockNodeView';
|
|
@@ -91,7 +92,8 @@ var createTableCellContentWidgets = function createTableCellContentWidgets(_ref)
|
|
|
91
92
|
*/
|
|
92
93
|
export var createNodeChangedDecorationWidget = function createNodeChangedDecorationWidget(_ref2) {
|
|
93
94
|
var _slice$content, _slice$content2, _slice$content3, _$safeInsertPos$nodeB, _slice$content$firstC, _newDoc$firstChild, _slice$content$firstC2;
|
|
94
|
-
var
|
|
95
|
+
var attributionKey = _ref2.attributionKey,
|
|
96
|
+
change = _ref2.change,
|
|
95
97
|
doc = _ref2.doc,
|
|
96
98
|
nodeViewSerializer = _ref2.nodeViewSerializer,
|
|
97
99
|
colorScheme = _ref2.colorScheme,
|
|
@@ -100,13 +102,16 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
100
102
|
activeIndexPos = _ref2.activeIndexPos,
|
|
101
103
|
_ref2$isInserted = _ref2.isInserted,
|
|
102
104
|
isInserted = _ref2$isInserted === void 0 ? false : _ref2$isInserted,
|
|
105
|
+
_ref2$showContributor = _ref2.showContributorTags,
|
|
106
|
+
showContributorTags = _ref2$showContributor === void 0 ? false : _ref2$showContributor,
|
|
103
107
|
_ref2$showIndicators = _ref2.showIndicators,
|
|
104
108
|
showIndicators = _ref2$showIndicators === void 0 ? false : _ref2$showIndicators,
|
|
105
109
|
_ref2$placeBelow = _ref2.placeBelow,
|
|
106
110
|
placeBelow = _ref2$placeBelow === void 0 ? false : _ref2$placeBelow,
|
|
107
111
|
diffType = _ref2.diffType,
|
|
108
112
|
_ref2$hideAddedDiffsU = _ref2.hideAddedDiffsUnderline,
|
|
109
|
-
hideAddedDiffsUnderline = _ref2$hideAddedDiffsU === void 0 ? false : _ref2$hideAddedDiffsU
|
|
113
|
+
hideAddedDiffsUnderline = _ref2$hideAddedDiffsU === void 0 ? false : _ref2$hideAddedDiffsU,
|
|
114
|
+
tagMountContext = _ref2.tagMountContext;
|
|
110
115
|
var slice = doc.slice(change.fromA, change.toA);
|
|
111
116
|
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;
|
|
112
117
|
// Widget decoration used for deletions as the content is not in the document
|
|
@@ -204,7 +209,9 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
204
209
|
subtree: true
|
|
205
210
|
});
|
|
206
211
|
}
|
|
207
|
-
|
|
212
|
+
// Derived from the deleted range so it survives a recalculation — see the same reasoning in
|
|
213
|
+
// `createInlineChangedDecoration`.
|
|
214
|
+
var diffId = showContributorTags ? "widget-".concat(change.fromA, "-").concat(change.toA) : crypto.randomUUID();
|
|
208
215
|
var decorations = [];
|
|
209
216
|
var replacementNode = newDoc.nodeAt(change.fromB);
|
|
210
217
|
var firstReplacedNode = slice.content.firstChild;
|
|
@@ -327,23 +334,47 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
327
334
|
}
|
|
328
335
|
});
|
|
329
336
|
dom.setAttribute('data-testid', 'show-diff-deleted-decoration');
|
|
337
|
+
|
|
338
|
+
// Needed even when the indicator bar is off, because a contributor tag also anchors against the
|
|
339
|
+
// widget.
|
|
340
|
+
if ((showIndicators || showContributorTags) && isExtendedEnabled(diffType)) {
|
|
341
|
+
dom.style.setProperty('anchor-name', "--".concat(buildAnchorDecorationKey({
|
|
342
|
+
diffId: diffId
|
|
343
|
+
})));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Taken down in the widget's `destroy` below: `dom` is rebuilt on every recalculation, so the tag
|
|
347
|
+
// mounted into it must not outlive the copy ProseMirror is drawing.
|
|
348
|
+
var tagMount;
|
|
349
|
+
if (showContributorTags) {
|
|
350
|
+
// Lets the contributor tag find the deleted content on hover.
|
|
351
|
+
dom.setAttribute('data-diff-id', diffId);
|
|
352
|
+
|
|
353
|
+
// Hosted at the start of the deleted run rather than on `dom` itself: `dom` is inline, so once
|
|
354
|
+
// the deleted content wraps its box is the union of its line fragments.
|
|
355
|
+
var tagHost = createContributorTagHost(diffId, tagMountContext);
|
|
356
|
+
if (tagHost) {
|
|
357
|
+
dom.prepend(tagHost.host);
|
|
358
|
+
tagMount = tagHost.mount;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
330
361
|
if (showIndicators && isExtendedEnabled(diffType)) {
|
|
331
362
|
var leftAnchor = createLeftAnchorWidget({
|
|
332
363
|
doc: newDoc,
|
|
333
364
|
from: safeInsertPos,
|
|
334
365
|
diffId: diffId
|
|
335
366
|
});
|
|
336
|
-
dom.style.setProperty('anchor-name', "--".concat(buildAnchorDecorationKey({
|
|
337
|
-
diffId: diffId
|
|
338
|
-
})));
|
|
339
367
|
if (leftAnchor) {
|
|
340
368
|
decorations.push(leftAnchor);
|
|
341
369
|
}
|
|
342
370
|
}
|
|
343
371
|
decorations.push(Decoration.widget(safeInsertPos, dom, _objectSpread(_objectSpread(_objectSpread({}, buildDiffDecorationSpec(_objectSpread({
|
|
372
|
+
attributionKey: attributionKey,
|
|
373
|
+
colorScheme: colorScheme,
|
|
344
374
|
decorationType: 'widget',
|
|
345
375
|
diffId: diffId,
|
|
346
376
|
isActive: isActive,
|
|
377
|
+
isInserted: isInserted,
|
|
347
378
|
diffType: diffType
|
|
348
379
|
}, isExtendedEnabled(diffType) && {
|
|
349
380
|
// placeBelow anchors at the end of the new content, so render on the
|
|
@@ -354,7 +385,9 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
354
385
|
}), {}, {
|
|
355
386
|
destroy: function destroy() {
|
|
356
387
|
var _constrainMediaObserv2;
|
|
357
|
-
|
|
388
|
+
(_constrainMediaObserv2 = constrainMediaObserver) === null || _constrainMediaObserv2 === void 0 || _constrainMediaObserv2.disconnect();
|
|
389
|
+
unmountContributorTag(tagMount);
|
|
390
|
+
tagMount = undefined;
|
|
358
391
|
}
|
|
359
392
|
})));
|
|
360
393
|
|
|
@@ -3,14 +3,14 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
3
3
|
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; }
|
|
4
4
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
5
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
6
|
-
|
|
7
6
|
/**
|
|
8
7
|
* Decoration families produced by the show-diff plugin.
|
|
9
8
|
* Each family owns its own key space and spec shape.
|
|
10
9
|
*/
|
|
11
10
|
export var DecorationFamily = {
|
|
12
11
|
diff: 'diff',
|
|
13
|
-
anchor: 'anchor'
|
|
12
|
+
anchor: 'anchor',
|
|
13
|
+
contributorTag: 'contributor-tag'
|
|
14
14
|
};
|
|
15
15
|
export var AnchorTypeKey = {
|
|
16
16
|
from: 'from',
|
|
@@ -18,6 +18,12 @@ export var AnchorTypeKey = {
|
|
|
18
18
|
left: 'left',
|
|
19
19
|
docMargin: 'doc-margin'
|
|
20
20
|
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The host widget one contributor tag renders into. Its own family, so the tag never reaches the
|
|
24
|
+
* consumers that read diff decorations — change counting, navigation and `getDeletedWidgets`.
|
|
25
|
+
*/
|
|
26
|
+
|
|
21
27
|
/**
|
|
22
28
|
* The diff-decoration kinds produced by the show-diff plugin. Each value is
|
|
23
29
|
* the leading segment of the generated key, so a diff decoration's kind can be
|
|
@@ -51,13 +57,16 @@ export var buildDiffDecorationKey = function buildDiffDecorationKey(_ref2) {
|
|
|
51
57
|
return isActive !== undefined ? "".concat(decorationKeyPrefix, "-").concat(isActive ? 'active' : 'inactive') : decorationKeyPrefix;
|
|
52
58
|
};
|
|
53
59
|
export var buildDiffDecorationSpec = function buildDiffDecorationSpec(_ref3) {
|
|
54
|
-
var
|
|
60
|
+
var attributionKey = _ref3.attributionKey,
|
|
61
|
+
colorScheme = _ref3.colorScheme,
|
|
62
|
+
decorationType = _ref3.decorationType,
|
|
55
63
|
diffId = _ref3.diffId,
|
|
56
64
|
isActive = _ref3.isActive,
|
|
65
|
+
isInserted = _ref3.isInserted,
|
|
57
66
|
nodeName = _ref3.nodeName,
|
|
58
67
|
side = _ref3.side,
|
|
59
68
|
diffType = _ref3.diffType;
|
|
60
|
-
return _objectSpread(_objectSpread({
|
|
69
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
61
70
|
decorationFamily: DecorationFamily.diff,
|
|
62
71
|
decorationType: decorationType,
|
|
63
72
|
diffId: diffId,
|
|
@@ -67,7 +76,15 @@ export var buildDiffDecorationSpec = function buildDiffDecorationSpec(_ref3) {
|
|
|
67
76
|
isActive: isActive,
|
|
68
77
|
diffType: diffType
|
|
69
78
|
})
|
|
70
|
-
},
|
|
79
|
+
}, attributionKey ? {
|
|
80
|
+
attributionKey: attributionKey
|
|
81
|
+
} : {}), attributionKey && isActive !== undefined ? {
|
|
82
|
+
isActive: isActive
|
|
83
|
+
} : {}), attributionKey && isInserted !== undefined ? {
|
|
84
|
+
isInserted: isInserted
|
|
85
|
+
} : {}), attributionKey && colorScheme ? {
|
|
86
|
+
colorScheme: colorScheme
|
|
87
|
+
} : {}), nodeName ? {
|
|
71
88
|
nodeName: nodeName
|
|
72
89
|
} : {}), side !== undefined ? {
|
|
73
90
|
side: side
|
|
@@ -101,6 +118,14 @@ export function buildAnchorDecorationSpec(_ref4) {
|
|
|
101
118
|
side: side
|
|
102
119
|
} : {});
|
|
103
120
|
}
|
|
121
|
+
export var buildContributorTagDecorationSpec = function buildContributorTagDecorationSpec(diffId) {
|
|
122
|
+
return {
|
|
123
|
+
decorationFamily: DecorationFamily.contributorTag,
|
|
124
|
+
diffId: diffId,
|
|
125
|
+
// Stable across recalculations, so ProseMirror keeps the host element the tag is portalled into.
|
|
126
|
+
key: "".concat(DecorationFamily.contributorTag, "-").concat(diffId)
|
|
127
|
+
};
|
|
128
|
+
};
|
|
104
129
|
export var isDiffDecorationSpec = function isDiffDecorationSpec(spec) {
|
|
105
130
|
return Boolean(spec && _typeof(spec) === 'object' && 'decorationFamily' in spec && spec.decorationFamily === DecorationFamily.diff);
|
|
106
131
|
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
3
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
4
|
+
var _excluded = ["connectedToKey"];
|
|
5
|
+
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; }
|
|
6
|
+
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; }
|
|
7
|
+
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; } } }; }
|
|
8
|
+
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; } }
|
|
9
|
+
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; }
|
|
10
|
+
import { isDiffDecoration, isDiffDecorationSpec } from './decorationKeys';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Diff kinds that expose an anchor a tag can be pinned to: `inline` is added/changed content,
|
|
14
|
+
* `widget` is deleted content. Block diffs carry no attribution.
|
|
15
|
+
*/
|
|
16
|
+
var TAGGABLE_DECORATION_TYPES = new Set(['inline', 'widget']);
|
|
17
|
+
|
|
18
|
+
/** The connection is an internal key, so it is dropped on the way to the tag. */
|
|
19
|
+
var toTagContributor = function toTagContributor(_ref) {
|
|
20
|
+
var _connectedToKey = _ref.connectedToKey,
|
|
21
|
+
tagContributor = _objectWithoutProperties(_ref, _excluded);
|
|
22
|
+
return tagContributor;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Whether a deleted-content widget belongs to the same change as an inline decoration. A replacement
|
|
26
|
+
* renders both — the inserted text inline, the deleted text as a widget anchored to one end of that
|
|
27
|
+
* inline range — and the two must not each claim a tag.
|
|
28
|
+
*/
|
|
29
|
+
var isSameChange = function isSameChange(widget, inline) {
|
|
30
|
+
return widget.spec.attributionKey === inline.spec.attributionKey && widget.from >= inline.from && widget.from <= inline.to;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* One model per diff decoration whose attribution resolves to a supplied contributor; anything
|
|
35
|
+
* unattributed, untaggable or unresolved is skipped. A replacement's two decorations are collapsed
|
|
36
|
+
* into the single inline tag — see `isSameChange`.
|
|
37
|
+
*/
|
|
38
|
+
export var extractContributorTags = function extractContributorTags(decorations, contributors) {
|
|
39
|
+
if (!contributors) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
var targets = [];
|
|
43
|
+
var _iterator = _createForOfIteratorHelper(decorations.find(undefined, undefined, isDiffDecorationSpec)),
|
|
44
|
+
_step;
|
|
45
|
+
try {
|
|
46
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
47
|
+
var decoration = _step.value;
|
|
48
|
+
if (!isDiffDecoration(decoration)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
var spec = decoration.spec;
|
|
52
|
+
if (!spec.attributionKey || !TAGGABLE_DECORATION_TYPES.has(spec.decorationType)) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
var contributor = contributors[spec.attributionKey];
|
|
56
|
+
if (!contributor) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
targets.push({
|
|
60
|
+
contributor: contributor,
|
|
61
|
+
decoration: decoration
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// The inline decoration keeps the tag: it captions content still in the document.
|
|
66
|
+
} catch (err) {
|
|
67
|
+
_iterator.e(err);
|
|
68
|
+
} finally {
|
|
69
|
+
_iterator.f();
|
|
70
|
+
}
|
|
71
|
+
var inlineTargets = targets.filter(function (_ref2) {
|
|
72
|
+
var decoration = _ref2.decoration;
|
|
73
|
+
return decoration.spec.decorationType === 'inline';
|
|
74
|
+
});
|
|
75
|
+
var linkedDiffIds = new Map();
|
|
76
|
+
var folded = new Set();
|
|
77
|
+
var _loop = function _loop() {
|
|
78
|
+
var _linkedDiffIds$get;
|
|
79
|
+
var target = _targets[_i];
|
|
80
|
+
if (target.decoration.spec.decorationType !== 'widget') {
|
|
81
|
+
return 0; // continue
|
|
82
|
+
}
|
|
83
|
+
var host = inlineTargets.find(function (_ref3) {
|
|
84
|
+
var decoration = _ref3.decoration;
|
|
85
|
+
return isSameChange(target.decoration, decoration);
|
|
86
|
+
});
|
|
87
|
+
if (!host) {
|
|
88
|
+
return 0; // continue
|
|
89
|
+
}
|
|
90
|
+
folded.add(target);
|
|
91
|
+
var hostDiffId = host.decoration.spec.diffId;
|
|
92
|
+
linkedDiffIds.set(hostDiffId, [].concat(_toConsumableArray((_linkedDiffIds$get = linkedDiffIds.get(hostDiffId)) !== null && _linkedDiffIds$get !== void 0 ? _linkedDiffIds$get : []), [target.decoration.spec.diffId]));
|
|
93
|
+
},
|
|
94
|
+
_ret;
|
|
95
|
+
for (var _i = 0, _targets = targets; _i < _targets.length; _i++) {
|
|
96
|
+
_ret = _loop();
|
|
97
|
+
if (_ret === 0) continue;
|
|
98
|
+
}
|
|
99
|
+
return targets.filter(function (target) {
|
|
100
|
+
return !folded.has(target);
|
|
101
|
+
}).map(function (_ref4) {
|
|
102
|
+
var contributor = _ref4.contributor,
|
|
103
|
+
spec = _ref4.decoration.spec;
|
|
104
|
+
var connected = contributor.connectedToKey ? contributors[contributor.connectedToKey] : undefined;
|
|
105
|
+
var connectedContributor = connected ? toTagContributor(connected) : undefined;
|
|
106
|
+
var linked = linkedDiffIds.get(spec.diffId);
|
|
107
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
108
|
+
contributor: toTagContributor(contributor),
|
|
109
|
+
diffId: spec.diffId
|
|
110
|
+
}, connectedContributor ? {
|
|
111
|
+
connectedContributor: connectedContributor
|
|
112
|
+
} : {}), spec.colorScheme ? {
|
|
113
|
+
colorScheme: spec.colorScheme
|
|
114
|
+
} : {}), spec.isActive !== undefined ? {
|
|
115
|
+
isActive: spec.isActive
|
|
116
|
+
} : {}), spec.isInserted !== undefined ? {
|
|
117
|
+
isInserted: spec.isInserted
|
|
118
|
+
} : {}), linked ? {
|
|
119
|
+
linkedDiffIds: linked
|
|
120
|
+
} : {});
|
|
121
|
+
});
|
|
122
|
+
};
|