@atlaskit/editor-plugin-show-diff 16.1.1 → 17.0.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 +23 -0
- package/afm-products/tsconfig.json +3 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +67 -22
- package/dist/cjs/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +242 -26
- package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +71 -37
- package/dist/cjs/pm-plugins/decorations/colorSchemes/schemes.js +5 -1
- package/dist/cjs/pm-plugins/decorations/colorSchemes/types.js +0 -2
- package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +21 -14
- package/dist/cjs/pm-plugins/decorations/extractContributorTags.js +123 -43
- package/dist/cjs/pm-plugins/decorations/revealStyles.js +5 -1
- package/dist/cjs/pm-plugins/getScrollableDecorations.js +48 -19
- package/dist/cjs/pm-plugins/utils/baseNodeName.js +25 -0
- package/dist/cjs/pm-plugins/utils/taggableBlockNodes.js +37 -0
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +39 -2
- package/dist/es2019/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +196 -10
- package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +51 -19
- package/dist/es2019/pm-plugins/decorations/colorSchemes/schemes.js +3 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/types.js +0 -2
- package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +23 -14
- package/dist/es2019/pm-plugins/decorations/extractContributorTags.js +60 -7
- package/dist/es2019/pm-plugins/decorations/revealStyles.js +5 -1
- package/dist/es2019/pm-plugins/getScrollableDecorations.js +44 -19
- package/dist/es2019/pm-plugins/utils/baseNodeName.js +18 -0
- package/dist/es2019/pm-plugins/utils/taggableBlockNodes.js +28 -0
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +67 -22
- package/dist/esm/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +243 -26
- package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +71 -37
- package/dist/esm/pm-plugins/decorations/colorSchemes/schemes.js +5 -1
- package/dist/esm/pm-plugins/decorations/colorSchemes/types.js +0 -2
- package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +21 -14
- package/dist/esm/pm-plugins/decorations/extractContributorTags.js +123 -43
- package/dist/esm/pm-plugins/decorations/revealStyles.js +5 -1
- package/dist/esm/pm-plugins/getScrollableDecorations.js +48 -19
- package/dist/esm/pm-plugins/utils/baseNodeName.js +20 -0
- package/dist/esm/pm-plugins/utils/taggableBlockNodes.js +32 -0
- package/dist/types/pm-plugins/calculateDiff/simplifyChangesWithAttribution.d.ts +20 -1
- package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +4 -11
- package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +9 -8
- package/dist/types/pm-plugins/getScrollableDecorations.d.ts +2 -2
- package/dist/types/pm-plugins/utils/baseNodeName.d.ts +16 -0
- package/dist/types/pm-plugins/utils/taggableBlockNodes.d.ts +14 -0
- package/package.json +12 -11
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
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
|
-
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
3
|
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; } } }; }
|
|
6
4
|
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; } }
|
|
7
5
|
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; }
|
|
6
|
+
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; }
|
|
7
|
+
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; }
|
|
8
8
|
import { simplifyChanges } from 'prosemirror-changeset';
|
|
9
9
|
import { getAttributionKey } from '../decorations/colorSchemes/attributions';
|
|
10
10
|
import { optimizeChanges } from './optimizeChanges';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A change, plus the block nodes it owns when it is one piece of a split — a piece's own range no
|
|
14
|
+
* longer covers the container it opened. Absent on an unsplit change, which decorates the blocks
|
|
15
|
+
* inside its own range as before.
|
|
16
|
+
*/
|
|
17
|
+
|
|
11
18
|
var getAttributionIdentity = function getAttributionIdentity(change) {
|
|
12
19
|
var identities = new Set();
|
|
13
20
|
for (var _i = 0, _arr = [].concat(_toConsumableArray(change.deleted), _toConsumableArray(change.inserted)); _i < _arr.length; _i++) {
|
|
@@ -29,55 +36,265 @@ var byNewDocRange = function byNewDocRange(left, right) {
|
|
|
29
36
|
return left.fromB - right.fromB || left.toB - right.toB;
|
|
30
37
|
};
|
|
31
38
|
|
|
39
|
+
/** Union of the given ranges, with overlapping and touching ones merged. */
|
|
40
|
+
var mergeRanges = function mergeRanges(ranges) {
|
|
41
|
+
return _toConsumableArray(ranges).sort(function (left, right) {
|
|
42
|
+
return left.from - right.from;
|
|
43
|
+
}).reduce(function (merged, range) {
|
|
44
|
+
var last = merged[merged.length - 1];
|
|
45
|
+
if (last && range.from <= last.to) {
|
|
46
|
+
last.to = Math.max(last.to, range.to);
|
|
47
|
+
return merged;
|
|
48
|
+
}
|
|
49
|
+
return [].concat(_toConsumableArray(merged), [_objectSpread({}, range)]);
|
|
50
|
+
}, []);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** Whether `inner` sits wholly inside `outer` and covers less of the document. */
|
|
54
|
+
var isContained = function isContained(outer, inner) {
|
|
55
|
+
return inner.toB > inner.fromB && outer.fromB <= inner.fromB && inner.toB <= outer.toB && inner.toB - inner.fromB < outer.toB - outer.fromB;
|
|
56
|
+
};
|
|
57
|
+
|
|
32
58
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* Merging keeps every span from both sides, so the latest-writer rule still decides whose tag is
|
|
38
|
-
* shown. Ranges that merely touch are left alone, so an unattributed edit next to an attributed one
|
|
39
|
-
* is not credited to it.
|
|
59
|
+
* The block nodes in `change` whose opening position `ownsPosition` claims. Ownership is by opening
|
|
60
|
+
* position so a block another contributor added inside a container is not claimed by whoever opened
|
|
61
|
+
* the container. `undefined` for a range this document cannot resolve, which falls the piece back
|
|
62
|
+
* to decorating its own range.
|
|
40
63
|
*/
|
|
41
|
-
|
|
42
|
-
if (
|
|
43
|
-
return
|
|
64
|
+
var blockNodeRanges = function blockNodeRanges(doc, change, ownsPosition) {
|
|
65
|
+
if (!doc || change.from >= change.to || change.to > doc.content.size) {
|
|
66
|
+
return undefined;
|
|
44
67
|
}
|
|
68
|
+
var ranges = [];
|
|
69
|
+
doc.nodesBetween(change.from, change.to, function (node, pos) {
|
|
70
|
+
if (node.isBlock && ownsPosition(pos) && pos + node.nodeSize <= change.to) {
|
|
71
|
+
ranges.push({
|
|
72
|
+
from: pos,
|
|
73
|
+
to: pos + node.nodeSize
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
});
|
|
78
|
+
return ranges;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Splits a change whose spans name more than one contributor into one change per run of consecutive
|
|
83
|
+
* spans sharing a key.
|
|
84
|
+
*
|
|
85
|
+
* `prosemirror-changeset` merges contiguous inserted content into one change while keeping per-span
|
|
86
|
+
* data, so a panel inserted by one contributor and edited inside by another arrives as a single
|
|
87
|
+
* change holding every span — and the latest-writer rule credited all of it, panel included, to
|
|
88
|
+
* whoever wrote last (EDITOR-8932).
|
|
89
|
+
*/
|
|
90
|
+
var splitMixedIdentityChanges = function splitMixedIdentityChanges(changes, doc) {
|
|
91
|
+
return changes.flatMap(function (change) {
|
|
92
|
+
if (getAttributionIdentity(change).mergeable) {
|
|
93
|
+
return [change];
|
|
94
|
+
}
|
|
95
|
+
var runs = [];
|
|
96
|
+
var offset = change.fromB;
|
|
97
|
+
var _iterator = _createForOfIteratorHelper(change.inserted),
|
|
98
|
+
_step;
|
|
99
|
+
try {
|
|
100
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
101
|
+
var span = _step.value;
|
|
102
|
+
var key = getAttributionKey(span.data);
|
|
103
|
+
var last = runs[runs.length - 1];
|
|
104
|
+
if (last && last.key === key) {
|
|
105
|
+
last.to = offset + span.length;
|
|
106
|
+
last.spans.push(span);
|
|
107
|
+
} else {
|
|
108
|
+
runs.push({
|
|
109
|
+
key: key,
|
|
110
|
+
from: offset,
|
|
111
|
+
to: offset + span.length,
|
|
112
|
+
spans: [span]
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
offset += span.length;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// The offsets above are only positions if the spans partition the inserted range.
|
|
119
|
+
} catch (err) {
|
|
120
|
+
_iterator.e(err);
|
|
121
|
+
} finally {
|
|
122
|
+
_iterator.f();
|
|
123
|
+
}
|
|
124
|
+
if (runs.length < 2 || offset !== change.toB) {
|
|
125
|
+
return [change];
|
|
126
|
+
}
|
|
127
|
+
return runs.map(function (run, index) {
|
|
128
|
+
var owned = blockNodeRanges(doc, {
|
|
129
|
+
from: change.fromB,
|
|
130
|
+
to: change.toB
|
|
131
|
+
}, function (pos) {
|
|
132
|
+
return pos >= run.from && pos < run.to;
|
|
133
|
+
});
|
|
134
|
+
return _objectSpread(_objectSpread({}, change), {}, {
|
|
135
|
+
fromA: index === 0 ? change.fromA : change.toA,
|
|
136
|
+
fromB: run.from,
|
|
137
|
+
toB: run.to,
|
|
138
|
+
deleted: index === 0 ? change.deleted : [],
|
|
139
|
+
inserted: run.spans
|
|
140
|
+
}, owned ? {
|
|
141
|
+
blockNodeRangesB: owned
|
|
142
|
+
} : {});
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
};
|
|
45
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Subtracts every other author's contained change from a change's range, so both contributions
|
|
149
|
+
* survive. Applies when the contributors arrive as separate changes rather than as spans of one —
|
|
150
|
+
* the `step` diff type. A contained change by the same author, and one that only partially
|
|
151
|
+
* overlaps, are left for the collapse below.
|
|
152
|
+
*
|
|
153
|
+
* The leading fragment keeps the deleted side, so one deletion is not drawn once per fragment.
|
|
154
|
+
*/
|
|
155
|
+
var splitContainedChanges = function splitContainedChanges(changes, doc) {
|
|
156
|
+
return changes.flatMap(function (change) {
|
|
157
|
+
var _getAttributionIdenti = getAttributionIdentity(change),
|
|
158
|
+
key = _getAttributionIdenti.key;
|
|
159
|
+
var inner = mergeRanges(changes.filter(function (other) {
|
|
160
|
+
var otherKey = getAttributionIdentity(other).key;
|
|
161
|
+
return other !== change && key !== undefined && otherKey !== undefined && otherKey !== key && isContained(change, other);
|
|
162
|
+
}).map(function (_ref) {
|
|
163
|
+
var fromB = _ref.fromB,
|
|
164
|
+
toB = _ref.toB;
|
|
165
|
+
return {
|
|
166
|
+
from: fromB,
|
|
167
|
+
to: toB
|
|
168
|
+
};
|
|
169
|
+
}));
|
|
170
|
+
if (inner.length === 0) {
|
|
171
|
+
return [change];
|
|
172
|
+
}
|
|
173
|
+
var gaps = [];
|
|
174
|
+
var cursor = change.fromB;
|
|
175
|
+
var _iterator2 = _createForOfIteratorHelper(inner),
|
|
176
|
+
_step2;
|
|
177
|
+
try {
|
|
178
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
179
|
+
var _step2$value = _step2.value,
|
|
180
|
+
from = _step2$value.from,
|
|
181
|
+
to = _step2$value.to;
|
|
182
|
+
if (from > cursor) {
|
|
183
|
+
gaps.push({
|
|
184
|
+
from: cursor,
|
|
185
|
+
to: from
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
cursor = Math.max(cursor, to);
|
|
189
|
+
}
|
|
190
|
+
} catch (err) {
|
|
191
|
+
_iterator2.e(err);
|
|
192
|
+
} finally {
|
|
193
|
+
_iterator2.f();
|
|
194
|
+
}
|
|
195
|
+
if (change.toB > cursor) {
|
|
196
|
+
gaps.push({
|
|
197
|
+
from: cursor,
|
|
198
|
+
to: change.toB
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Subtracted end to end, so nothing is left to highlight — but the blocks are still owned.
|
|
203
|
+
var fragments = gaps.length > 0 ? gaps : [{
|
|
204
|
+
from: change.toB,
|
|
205
|
+
to: change.toB
|
|
206
|
+
}];
|
|
207
|
+
// The outer author's: every block in their range that no inner change opened.
|
|
208
|
+
var owned = blockNodeRanges(doc, {
|
|
209
|
+
from: change.fromB,
|
|
210
|
+
to: change.toB
|
|
211
|
+
}, function (pos) {
|
|
212
|
+
return !inner.some(function (_ref2) {
|
|
213
|
+
var from = _ref2.from,
|
|
214
|
+
to = _ref2.to;
|
|
215
|
+
return pos >= from && pos < to;
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
return fragments.map(function (fragment, index) {
|
|
219
|
+
return _objectSpread(_objectSpread({}, change), {}, {
|
|
220
|
+
fromA: index === 0 ? change.fromA : change.toA,
|
|
221
|
+
fromB: fragment.from,
|
|
222
|
+
toB: fragment.to,
|
|
223
|
+
deleted: index === 0 ? change.deleted : []
|
|
224
|
+
}, owned ? {
|
|
225
|
+
blockNodeRangesB: index === 0 ? owned : []
|
|
226
|
+
} : {});
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* The blocks a merged change owns. Both sides must name theirs, or the merge falls back to its own
|
|
233
|
+
* range — narrowing it could drop a block altogether.
|
|
234
|
+
*/
|
|
235
|
+
var mergeBlockNodeRanges = function mergeBlockNodeRanges(left, right) {
|
|
236
|
+
return left.blockNodeRangesB && right.blockNodeRangesB ? [].concat(_toConsumableArray(left.blockNodeRangesB), _toConsumableArray(right.blockNodeRangesB)) : undefined;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
/** Unions the changes whose new-document ranges strictly overlap, leaving touching ones alone. */
|
|
240
|
+
var collapse = function collapse(changes) {
|
|
46
241
|
// A zero-length new-document range paints no inline decoration, so it is kept aside rather than
|
|
47
242
|
// folded into a neighbouring insertion.
|
|
48
243
|
var emptyRanges = changes.filter(function (change) {
|
|
49
244
|
return change.toB <= change.fromB;
|
|
50
245
|
});
|
|
51
246
|
var collapsed = [];
|
|
52
|
-
var
|
|
247
|
+
var _iterator3 = _createForOfIteratorHelper(changes.filter(function (change) {
|
|
53
248
|
return change.toB > change.fromB;
|
|
54
249
|
}).sort(byNewDocRange)),
|
|
55
|
-
|
|
250
|
+
_step3;
|
|
56
251
|
try {
|
|
57
|
-
for (
|
|
58
|
-
var change =
|
|
252
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
253
|
+
var change = _step3.value;
|
|
59
254
|
var current = collapsed[collapsed.length - 1];
|
|
60
255
|
if (current && change.fromB < current.toB) {
|
|
61
|
-
|
|
256
|
+
var blockNodeRangesB = mergeBlockNodeRanges(current, change);
|
|
257
|
+
collapsed[collapsed.length - 1] = _objectSpread({
|
|
62
258
|
fromA: Math.min(current.fromA, change.fromA),
|
|
63
259
|
toA: Math.max(current.toA, change.toA),
|
|
64
260
|
fromB: Math.min(current.fromB, change.fromB),
|
|
65
261
|
toB: Math.max(current.toB, change.toB),
|
|
66
262
|
deleted: [].concat(_toConsumableArray(current.deleted), _toConsumableArray(change.deleted)),
|
|
67
263
|
inserted: [].concat(_toConsumableArray(current.inserted), _toConsumableArray(change.inserted))
|
|
68
|
-
}
|
|
264
|
+
}, blockNodeRangesB ? {
|
|
265
|
+
blockNodeRangesB: blockNodeRangesB
|
|
266
|
+
} : {});
|
|
69
267
|
} else {
|
|
70
268
|
collapsed.push(_objectSpread({}, change));
|
|
71
269
|
}
|
|
72
270
|
}
|
|
73
271
|
} catch (err) {
|
|
74
|
-
|
|
272
|
+
_iterator3.e(err);
|
|
75
273
|
} finally {
|
|
76
|
-
|
|
274
|
+
_iterator3.f();
|
|
77
275
|
}
|
|
78
276
|
return [].concat(collapsed, _toConsumableArray(emptyRanges)).sort(byNewDocRange);
|
|
79
277
|
};
|
|
80
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Collapses changes whose new-document ranges strictly overlap. Attribution runs are simplified
|
|
281
|
+
* independently, so runs either side of an unattributed step can come back covering the same
|
|
282
|
+
* characters — which stacks two inline decorations and renders one contributor tag per copy.
|
|
283
|
+
*
|
|
284
|
+
* Merging keeps every span from both sides, so the latest-writer rule still decides whose tag is
|
|
285
|
+
* shown. Ranges that merely touch are left alone, so an unattributed edit next to an attributed one
|
|
286
|
+
* is not credited to it.
|
|
287
|
+
*
|
|
288
|
+
* Contributors are separated first, by `splitMixedIdentityChanges` and `splitContainedChanges`.
|
|
289
|
+
* Both leave ranges that only touch, so they survive the collapse.
|
|
290
|
+
*
|
|
291
|
+
* Carries no gate of its own: the only caller reaches it through the attributed changeset, which
|
|
292
|
+
* already requires `confluence_ncs_step_diffing_version_history`.
|
|
293
|
+
*/
|
|
294
|
+
export var collapseOverlappingChanges = function collapseOverlappingChanges(changes, doc) {
|
|
295
|
+
return collapse(splitContainedChanges(splitMixedIdentityChanges(changes, doc), doc));
|
|
296
|
+
};
|
|
297
|
+
|
|
81
298
|
/**
|
|
82
299
|
* Simplifies and optimizes consecutive changes without crossing an attribution boundary.
|
|
83
300
|
* A change which already contains more than one identity is deliberately kept isolated.
|
|
@@ -107,12 +324,12 @@ export var simplifyChangesWithAttribution = function simplifyChangesWithAttribut
|
|
|
107
324
|
run = [];
|
|
108
325
|
runIdentity = undefined;
|
|
109
326
|
};
|
|
110
|
-
var
|
|
111
|
-
|
|
327
|
+
var _iterator4 = _createForOfIteratorHelper(changes),
|
|
328
|
+
_step4;
|
|
112
329
|
try {
|
|
113
|
-
for (
|
|
330
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
114
331
|
var _runIdentity;
|
|
115
|
-
var change =
|
|
332
|
+
var change = _step4.value;
|
|
116
333
|
var identity = getAttributionIdentity(change);
|
|
117
334
|
var canJoinRun = ((_runIdentity = runIdentity) === null || _runIdentity === void 0 ? void 0 : _runIdentity.mergeable) === true && identity.mergeable && runIdentity.key === identity.key;
|
|
118
335
|
if (run.length > 0 && !canJoinRun) {
|
|
@@ -125,9 +342,9 @@ export var simplifyChangesWithAttribution = function simplifyChangesWithAttribut
|
|
|
125
342
|
}
|
|
126
343
|
}
|
|
127
344
|
} catch (err) {
|
|
128
|
-
|
|
345
|
+
_iterator4.e(err);
|
|
129
346
|
} finally {
|
|
130
|
-
|
|
347
|
+
_iterator4.f();
|
|
131
348
|
}
|
|
132
349
|
flush();
|
|
133
350
|
return result;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
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
|
+
import { agentBrandColorSchemes } from '@atlaskit/agent-color/agent-brand-color-schemes';
|
|
4
5
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
5
6
|
import { getStandardDeletedTextDecorationStyle } from './getStandardDeletedTextDecorationStyle';
|
|
6
7
|
|
|
@@ -118,40 +119,48 @@ var textAccentMap = {
|
|
|
118
119
|
gray: "var(--ds-text-accent-gray, #505258)",
|
|
119
120
|
lime: "var(--ds-text-accent-lime, #4C6B1F)"
|
|
120
121
|
};
|
|
122
|
+
var getBrand = function getBrand(color) {
|
|
123
|
+
return Object.prototype.hasOwnProperty.call(agentBrandColorSchemes, color) ? agentBrandColorSchemes[color] : undefined;
|
|
124
|
+
};
|
|
121
125
|
function bgSubtlest(color) {
|
|
122
|
-
|
|
126
|
+
var _getBrand$background, _getBrand;
|
|
127
|
+
return (_getBrand$background = (_getBrand = getBrand(color)) === null || _getBrand === void 0 ? void 0 : _getBrand.background) !== null && _getBrand$background !== void 0 ? _getBrand$background : bgSubtlestMap[color];
|
|
123
128
|
}
|
|
124
129
|
function bgSubtlestPressed(color) {
|
|
125
|
-
|
|
130
|
+
var _getBrand$background2, _getBrand2;
|
|
131
|
+
return (_getBrand$background2 = (_getBrand2 = getBrand(color)) === null || _getBrand2 === void 0 ? void 0 : _getBrand2.background) !== null && _getBrand$background2 !== void 0 ? _getBrand$background2 : bgSubtlestPressedMap[color];
|
|
126
132
|
}
|
|
127
133
|
function bgSubtler(color) {
|
|
128
|
-
|
|
134
|
+
var _getBrand$border, _getBrand3;
|
|
135
|
+
return (_getBrand$border = (_getBrand3 = getBrand(color)) === null || _getBrand3 === void 0 ? void 0 : _getBrand3.border) !== null && _getBrand$border !== void 0 ? _getBrand$border : bgSubtlerMap[color];
|
|
129
136
|
}
|
|
130
137
|
function bgBolder(color) {
|
|
131
|
-
|
|
138
|
+
var _getBrand$bold, _getBrand4;
|
|
139
|
+
return (_getBrand$bold = (_getBrand4 = getBrand(color)) === null || _getBrand4 === void 0 ? void 0 : _getBrand4.bold) !== null && _getBrand$bold !== void 0 ? _getBrand$bold : bgBolderMap[color];
|
|
132
140
|
}
|
|
133
141
|
function bgSubtlerPressed(color) {
|
|
134
|
-
|
|
142
|
+
var _getBrand$background3, _getBrand5;
|
|
143
|
+
return (_getBrand$background3 = (_getBrand5 = getBrand(color)) === null || _getBrand5 === void 0 ? void 0 : _getBrand5.background) !== null && _getBrand$background3 !== void 0 ? _getBrand$background3 : bgSubtlerPressedMap[color];
|
|
135
144
|
}
|
|
136
145
|
function borderAccent(color) {
|
|
137
|
-
|
|
146
|
+
var _getBrand$border2, _getBrand6;
|
|
147
|
+
return (_getBrand$border2 = (_getBrand6 = getBrand(color)) === null || _getBrand6 === void 0 ? void 0 : _getBrand6.border) !== null && _getBrand$border2 !== void 0 ? _getBrand$border2 : borderAccentMap[color];
|
|
138
148
|
}
|
|
139
149
|
function textAccent(color) {
|
|
140
|
-
|
|
150
|
+
var _getBrand$accentText, _getBrand7;
|
|
151
|
+
return (_getBrand$accentText = (_getBrand7 = getBrand(color)) === null || _getBrand7 === void 0 ? void 0 : _getBrand7.accentText) !== null && _getBrand$accentText !== void 0 ? _getBrand$accentText : textAccentMap[color];
|
|
152
|
+
}
|
|
153
|
+
function deletedBackground(color) {
|
|
154
|
+
var _getBrand$emphasisBac, _getBrand8;
|
|
155
|
+
return (_getBrand$emphasisBac = (_getBrand8 = getBrand(color)) === null || _getBrand8 === void 0 ? void 0 : _getBrand8.emphasisBackground) !== null && _getBrand$emphasisBac !== void 0 ? _getBrand$emphasisBac : bgSubtlest(color);
|
|
141
156
|
}
|
|
142
157
|
|
|
143
|
-
/**
|
|
144
|
-
* Presentation tokens for a contributor tag in one diff colour.
|
|
145
|
-
*
|
|
146
|
-
* A `bolder` fill rather than the `subtlest` tint the highlight uses: the tag is a label on the
|
|
147
|
-
* change, and at tag size a tint reads as a second, weaker highlight sitting above the real one.
|
|
148
|
-
* `inverse` is the only text tone that reads on a bolder fill, and it needs no per-colour map —
|
|
149
|
-
* which is also why the tag carries no border: the fill alone bounds it.
|
|
150
|
-
*/
|
|
158
|
+
/** Contributor tags use a bold fill with a contrasting foreground, including branded schemes. */
|
|
151
159
|
export function getAccentTokens(color) {
|
|
160
|
+
var _getBrand$boldText, _getBrand9;
|
|
152
161
|
return {
|
|
153
162
|
background: bgBolder(color),
|
|
154
|
-
text: "var(--ds-text-inverse, #FFFFFF)"
|
|
163
|
+
text: (_getBrand$boldText = (_getBrand9 = getBrand(color)) === null || _getBrand9 === void 0 ? void 0 : _getBrand9.boldText) !== null && _getBrand$boldText !== void 0 ? _getBrand$boldText : "var(--ds-text-inverse, #FFFFFF)"
|
|
155
164
|
};
|
|
156
165
|
}
|
|
157
166
|
|
|
@@ -173,18 +182,23 @@ function deletedCellOutline(colors) {
|
|
|
173
182
|
// --- Inserted content styles ---
|
|
174
183
|
|
|
175
184
|
function insertedInlineBorderColor(colors) {
|
|
176
|
-
|
|
185
|
+
var _getBrand$border3, _getBrand0;
|
|
186
|
+
return colors.insertedInlineBorderTone === 'backgroundHovered' ? (_getBrand$border3 = (_getBrand0 = getBrand(colors.insertColor)) === null || _getBrand0 === void 0 ? void 0 : _getBrand0.border) !== null && _getBrand$border3 !== void 0 ? _getBrand$border3 : bgSubtlestHoveredMap[colors.insertColor] : borderAccent(colors.insertColor);
|
|
177
187
|
}
|
|
178
188
|
|
|
179
189
|
/** Inline inserted content — default state. */
|
|
180
190
|
export function buildInsertStyle(colors) {
|
|
181
|
-
|
|
182
|
-
|
|
191
|
+
var brand = getBrand(colors.insertColor);
|
|
192
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
193
|
+
background: bgSubtlest(colors.insertColor)
|
|
194
|
+
}, brand ? {
|
|
195
|
+
color: brand.text
|
|
196
|
+
} : {}), {}, {
|
|
183
197
|
textDecoration: 'underline',
|
|
184
198
|
textDecorationStyle: colors.insertUnderlineStyle,
|
|
185
199
|
textDecorationThickness: "var(--ds-space-025, 2px)",
|
|
186
200
|
textDecorationColor: borderAccent(colors.insertColor)
|
|
187
|
-
});
|
|
201
|
+
}));
|
|
188
202
|
}
|
|
189
203
|
|
|
190
204
|
/** Inline insert style for content within a block node (no background, underline only). */
|
|
@@ -199,11 +213,15 @@ export function buildInsertStyleInBlock(colors) {
|
|
|
199
213
|
|
|
200
214
|
/** Extended insert style — background + border-bottom underline. */
|
|
201
215
|
export function buildInsertStyleExtended(colors) {
|
|
202
|
-
|
|
203
|
-
|
|
216
|
+
var brand = getBrand(colors.insertColor);
|
|
217
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
218
|
+
background: bgSubtlest(colors.insertColor)
|
|
219
|
+
}, brand ? {
|
|
220
|
+
color: brand.text
|
|
221
|
+
} : {}), {}, {
|
|
204
222
|
borderBottom: "2px solid ".concat(insertedInlineBorderColor(colors)),
|
|
205
223
|
padding: "1px 0 2px"
|
|
206
|
-
});
|
|
224
|
+
}));
|
|
207
225
|
}
|
|
208
226
|
|
|
209
227
|
/** Extended insert style for content within a block node (border-bottom only, no background). */
|
|
@@ -216,27 +234,39 @@ export function buildInsertStyleInBlockExtended(colors) {
|
|
|
216
234
|
|
|
217
235
|
/** Active state of the extended insert style. */
|
|
218
236
|
export function buildInsertStyleExtendedActive(colors) {
|
|
219
|
-
|
|
220
|
-
|
|
237
|
+
var brand = getBrand(colors.insertColor);
|
|
238
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
239
|
+
background: bgSubtlerPressed(colors.insertActiveColor)
|
|
240
|
+
}, brand ? {
|
|
241
|
+
color: brand.text
|
|
242
|
+
} : {}), {}, {
|
|
221
243
|
borderBottom: "2px solid ".concat(borderAccent(colors.insertColor)),
|
|
222
244
|
padding: "1px 0 2px"
|
|
223
|
-
});
|
|
245
|
+
}));
|
|
224
246
|
}
|
|
225
247
|
|
|
226
248
|
/** Extended insert style without underline — background + padding only. */
|
|
227
249
|
export function buildInsertStyleExtendedNoUnderline(colors) {
|
|
228
|
-
|
|
229
|
-
|
|
250
|
+
var brand = getBrand(colors.insertColor);
|
|
251
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
252
|
+
background: bgSubtlest(colors.insertColor)
|
|
253
|
+
}, brand ? {
|
|
254
|
+
color: brand.text
|
|
255
|
+
} : {}), {}, {
|
|
230
256
|
padding: "1px 0 2px"
|
|
231
|
-
});
|
|
257
|
+
}));
|
|
232
258
|
}
|
|
233
259
|
|
|
234
260
|
/** Active state of the no-underline extended insert style. */
|
|
235
261
|
export function buildInsertStyleExtendedNoUnderlineActive(colors) {
|
|
236
|
-
|
|
237
|
-
|
|
262
|
+
var brand = getBrand(colors.insertColor);
|
|
263
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
264
|
+
background: bgSubtlerPressed(colors.insertActiveColor)
|
|
265
|
+
}, brand ? {
|
|
266
|
+
color: brand.text
|
|
267
|
+
} : {}), {}, {
|
|
238
268
|
padding: "1px 0 2px"
|
|
239
|
-
});
|
|
269
|
+
}));
|
|
240
270
|
}
|
|
241
271
|
|
|
242
272
|
/** No-underline extended insert style for block content (padding only). */
|
|
@@ -248,13 +278,17 @@ export function buildInsertStyleInBlockExtendedNoUnderline(_colors) {
|
|
|
248
278
|
|
|
249
279
|
/** Inline inserted content — active/focused state. */
|
|
250
280
|
export function buildInsertStyleActive(colors) {
|
|
251
|
-
|
|
252
|
-
|
|
281
|
+
var brand = getBrand(colors.insertColor);
|
|
282
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
283
|
+
background: bgSubtlerPressed(colors.insertActiveColor)
|
|
284
|
+
}, brand ? {
|
|
285
|
+
color: brand.text
|
|
286
|
+
} : {}), {}, {
|
|
253
287
|
textDecoration: 'underline',
|
|
254
288
|
textDecorationStyle: colors.insertUnderlineStyle,
|
|
255
289
|
textDecorationThickness: "var(--ds-space-025, 2px)",
|
|
256
290
|
textDecorationColor: textAccent(colors.insertActiveColor)
|
|
257
|
-
});
|
|
291
|
+
}));
|
|
258
292
|
}
|
|
259
293
|
|
|
260
294
|
// --- Deleted inline content styles ---
|
|
@@ -612,7 +646,7 @@ export function buildDeletedInlineContentStyleExtended(colors) {
|
|
|
612
646
|
// Under 'underline' emphasis the highlight stays on its resting tint — the same one hover paints —
|
|
613
647
|
// so only the border carries the emphasis.
|
|
614
648
|
var isUnderlineEmphasis = isActive && usesUnderlineEmphasis(colors);
|
|
615
|
-
var backgroundColor = isActive && !isUnderlineEmphasis && colors.deletedInlineBorderTone === 'background' ? bgSubtlerPressed(colors.deleteActiveColor) :
|
|
649
|
+
var backgroundColor = isActive && !isUnderlineEmphasis && colors.deletedInlineBorderTone === 'background' ? bgSubtlerPressed(colors.deleteActiveColor) : deletedBackground(colors.deleteColor);
|
|
616
650
|
var borderColor = isUnderlineEmphasis ? borderAccent(colors.deleteActiveColor) : colors.deletedInlineBorderTone === 'background' ? backgroundColor : borderAccent(colors.deleteColor);
|
|
617
651
|
return convertToInlineCss({
|
|
618
652
|
backgroundColor: backgroundColor,
|
|
@@ -822,7 +856,7 @@ export function getDeletedInlineRevealColors(colors) {
|
|
|
822
856
|
* paints at rest, so hovering restores the appearance rather than introducing a third one.
|
|
823
857
|
*/
|
|
824
858
|
export function getDeletedHighlightHoverColor(colors) {
|
|
825
|
-
return
|
|
859
|
+
return deletedBackground(colors.deleteColor);
|
|
826
860
|
}
|
|
827
861
|
|
|
828
862
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
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
|
+
import { agentBrandColorSchemes } from '@atlaskit/agent-color/agent-brand-color-schemes';
|
|
4
5
|
import { PARTICIPANT_COLOR_SCHEMES } from './types';
|
|
5
6
|
|
|
6
7
|
/** Green insertions, red deletions. */
|
|
@@ -78,9 +79,12 @@ var createAttributionScheme = function createAttributionScheme(color) {
|
|
|
78
79
|
var attributionColorSchemes = Object.fromEntries(PARTICIPANT_COLOR_SCHEMES.map(function (color) {
|
|
79
80
|
return [color, createAttributionScheme(color)];
|
|
80
81
|
}));
|
|
82
|
+
var brandSchemes = Object.fromEntries(Object.keys(agentBrandColorSchemes).map(function (scheme) {
|
|
83
|
+
return [scheme, createAttributionScheme(scheme)];
|
|
84
|
+
}));
|
|
81
85
|
|
|
82
86
|
/** Maps public schemes and attribution-only participant slots to their data objects. */
|
|
83
|
-
export var colorSchemeRegistry = _objectSpread(_objectSpread({}, attributionColorSchemes), {}, {
|
|
87
|
+
export var colorSchemeRegistry = _objectSpread(_objectSpread(_objectSpread({}, attributionColorSchemes), brandSchemes), {}, {
|
|
84
88
|
traditional: traditionalScheme,
|
|
85
89
|
standard: standardScheme
|
|
86
90
|
});
|
|
@@ -5,8 +5,6 @@ export var PARTICIPANT_COLOR_SCHEMES = ['red', 'blue', 'green', 'yellow', 'purpl
|
|
|
5
5
|
|
|
6
6
|
/** ADS accent hues used by the public and participant colour schemes. */
|
|
7
7
|
|
|
8
|
-
/** A public scheme or an attribution participant slot resolved internally for one change. */
|
|
9
|
-
|
|
10
8
|
/**
|
|
11
9
|
* A show-diff colour scheme. Colour fields are ADS hues that `factory.ts` expands into token paths;
|
|
12
10
|
* the rest encode structural differences no colour can express. Ring widths, padding, radius and
|
|
@@ -8,6 +8,7 @@ import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
|
8
8
|
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
9
9
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
10
10
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
11
|
+
import { isTaggableBlockNode } from '../utils/taggableBlockNodes';
|
|
11
12
|
import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildDeletedBlockNodeStyle, buildDeletedCellOverlayRoundedStyle, buildDeletedCellOverlayStyle, buildInsertedBlockNodeStyle } from './colorSchemes/factory';
|
|
12
13
|
import { colorSchemeRegistry, getLegacyColorScheme } from './colorSchemes/schemes';
|
|
13
14
|
import { createBlockIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
|
|
@@ -27,13 +28,6 @@ var UNSTYLED_NODES = ['mediaSingle', 'mediaGroup', 'table',
|
|
|
27
28
|
'heading', 'hardBreak', 'decisionList', 'taskList', 'bulletList', 'orderedList', 'layoutSection'];
|
|
28
29
|
var CELL_NODES = ['tableCell', 'tableHeader'];
|
|
29
30
|
|
|
30
|
-
/**
|
|
31
|
-
* Block nodes that host a contributor tag of their own — those whose whole box reads as one change.
|
|
32
|
-
* Lists and tables are excluded: they decorate per item and per cell, with no one-tag-per-block
|
|
33
|
-
* design yet. `blockCard` covers the datasource variant, which is the same node type.
|
|
34
|
-
*/
|
|
35
|
-
var TAGGABLE_BLOCK_NODES = new Set(['blockCard', 'blockquote', 'bodiedExtension', 'codeBlock', 'embedCard', 'expand', 'extension', 'media', 'multiBodiedExtension', 'panel', 'rule']);
|
|
36
|
-
|
|
37
31
|
/** Panels, rules and media can also sit in a table cell, which is out of scope for block tags. */
|
|
38
32
|
var isInsideTable = function isInsideTable(doc, pos) {
|
|
39
33
|
return findParentNodeClosestToPos(doc.resolve(pos), function (node) {
|
|
@@ -41,13 +35,23 @@ var isInsideTable = function isInsideTable(doc, pos) {
|
|
|
41
35
|
}) !== undefined;
|
|
42
36
|
};
|
|
43
37
|
|
|
44
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Whether this block can host a contributor tag of its own.
|
|
40
|
+
*
|
|
41
|
+
* The node type is resolved from the document rather than matched on `change.name`, so a schema
|
|
42
|
+
* variant is recognised as the type it varies — see `isTaggableBlockNode`. `from` is the node's own
|
|
43
|
+
* position, so `nodeAt` returns exactly the node being decorated.
|
|
44
|
+
*/
|
|
45
45
|
var canTagBlock = function canTagBlock(_ref) {
|
|
46
|
+
var _doc$nodeAt;
|
|
46
47
|
var diffType = _ref.diffType,
|
|
47
48
|
doc = _ref.doc,
|
|
48
|
-
from = _ref.from
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
from = _ref.from;
|
|
50
|
+
if (doc === undefined || !isExtendedEnabled(diffType)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
var nodeType = (_doc$nodeAt = doc.nodeAt(from)) === null || _doc$nodeAt === void 0 ? void 0 : _doc$nodeAt.type;
|
|
54
|
+
return nodeType !== undefined && isTaggableBlockNode(nodeType) && !isInsideTable(doc, from);
|
|
51
55
|
};
|
|
52
56
|
|
|
53
57
|
/** Positioning context for the cell overlay widget decorations. */
|
|
@@ -189,8 +193,7 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
189
193
|
var shouldTagBlock = showContributorTags && canTagBlock({
|
|
190
194
|
diffType: diffType,
|
|
191
195
|
doc: doc,
|
|
192
|
-
from: change.from
|
|
193
|
-
name: change.name
|
|
196
|
+
from: change.from
|
|
194
197
|
});
|
|
195
198
|
// Named so this block's own tag can position against it; see `createContributorTagWidget`.
|
|
196
199
|
var tagAnchorName = shouldTagBlock && isContributorTagWidgetEnabled() ? buildAnchorDecorationKey({
|
|
@@ -234,7 +237,9 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
234
237
|
key: 'cell-overlay-decoration'
|
|
235
238
|
}));
|
|
236
239
|
}
|
|
237
|
-
// isInserted is only read under the extended experience, so pass it unconditionally.
|
|
240
|
+
// isInserted is only read under the extended experience, so pass it unconditionally. `change.name`
|
|
241
|
+
// verbatim: base-name resolution stays in `canTagBlock`, which needs tags on, so a schema
|
|
242
|
+
// variant's legacy style is untouched — see `resolveBaseNodeName`.
|
|
238
243
|
var nodeStyle = getBlockNodeStyle({
|
|
239
244
|
nodeName: change.name,
|
|
240
245
|
colorScheme: colorScheme,
|
|
@@ -265,6 +270,8 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
265
270
|
})));
|
|
266
271
|
}
|
|
267
272
|
if (decorations.length === 0) {
|
|
273
|
+
// An unstyled node type (paragraph, heading, list, layout, …) emits no decoration at all, so
|
|
274
|
+
// there is nothing for a tag to hang off even when the node type would otherwise be taggable.
|
|
268
275
|
return decorations;
|
|
269
276
|
}
|
|
270
277
|
if (showIndicators && doc && isExtendedEnabled(diffType)) {
|