@atlaskit/editor-plugin-show-diff 22.0.6 → 23.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +43 -4
- package/dist/cjs/pm-plugins/calculateDiff/diffBySteps.js +28 -1
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +41 -3
- package/dist/es2019/pm-plugins/calculateDiff/diffBySteps.js +26 -1
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +43 -4
- package/dist/esm/pm-plugins/calculateDiff/diffBySteps.js +28 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 23.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`608de54a73de3`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/608de54a73de3) -
|
|
8
|
+
Behind platform_editor_ai_show_diff_patch_2, the step diff now diffs a replaced isolating node
|
|
9
|
+
(table cell or header, layout column, expand, bodied extension, …; tables excluded) granularly
|
|
10
|
+
instead of marking the whole node as changed, so a replaceNode suggestion on a cell no longer
|
|
11
|
+
shows a cell overlay on top of its inline changes. Block decorations now only apply to blocks
|
|
12
|
+
fully inside a change, so hiding deleted diffs no longer hides a block the change only starts
|
|
13
|
+
inside (along with its unchanged text and the suggested content).
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
|
|
16
|
+
## 23.0.0
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
|
|
3
22
|
## 22.0.6
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -177,8 +177,29 @@ var isInsideTable = function isInsideTable(tables, pos) {
|
|
|
177
177
|
return pos >= tFrom && pos < tTo;
|
|
178
178
|
});
|
|
179
179
|
};
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Where a block's content ends, excluding the run of close tokens that ends it: the block's own,
|
|
183
|
+
* then its last child's, and so on down to the last textblock. A change that keeps those trailing
|
|
184
|
+
* close tokens unchanged (because the other side ends in the same structure, e.g.
|
|
185
|
+
* `…</p></li></ul>`) still covers all of the block's content.
|
|
186
|
+
*/
|
|
187
|
+
var endBeforeTrailingCloseTokens = function endBeforeTrailingCloseTokens(node, pos) {
|
|
188
|
+
var end = pos + node.nodeSize;
|
|
189
|
+
var current = node;
|
|
190
|
+
while (current && !current.isLeaf) {
|
|
191
|
+
end -= 1;
|
|
192
|
+
if (current.isTextblock) {
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
current = current.lastChild;
|
|
196
|
+
}
|
|
197
|
+
return end;
|
|
198
|
+
};
|
|
180
199
|
var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration(_ref5) {
|
|
181
|
-
var
|
|
200
|
+
var _ref5$allowTrailingCl = _ref5.allowTrailingCloseTokens,
|
|
201
|
+
allowTrailingCloseTokens = _ref5$allowTrailingCl === void 0 ? false : _ref5$allowTrailingCl,
|
|
202
|
+
attributionKey = _ref5.attributionKey,
|
|
182
203
|
doc = _ref5.doc,
|
|
183
204
|
from = _ref5.from,
|
|
184
205
|
to = _ref5.to,
|
|
@@ -245,8 +266,23 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
|
|
|
245
266
|
// re-render. Blocks outside the table keep their normal decorations.
|
|
246
267
|
var coarseTables = coarseTableCellsOnly ? tableRanges(doc, from, to) : [];
|
|
247
268
|
// nodesBetween visits ancestors that start before the changed range.
|
|
248
|
-
// Only fully contained blocks should mark existing list bullets as new.
|
|
249
|
-
|
|
269
|
+
// Only fully contained blocks should mark existing list bullets as new. Under patch 2 this also
|
|
270
|
+
// keeps the clean view from hiding a block the change only starts inside: that block holds
|
|
271
|
+
// unchanged text and the deleted-content widget, so `display: none` on it hid the whole diff.
|
|
272
|
+
var requireContainedBlocks = (0, _unsafeExpValNoExposure.UNSAFE_expValNoExposure)('platform_editor_ai_review_moment', 'isEnabled', false) === true || (0, _fg.fg)('platform_editor_ai_show_diff_patch_2');
|
|
273
|
+
// Under patch 2, a block whose content the change covers but whose trailing close tokens it does
|
|
274
|
+
// not (e.g. the last list item when both sides end in a list) is decorated like its siblings.
|
|
275
|
+
// Otherwise the clean view hides its text but leaves the block, e.g. an empty bullet.
|
|
276
|
+
var relaxTrailingCloseTokens = allowTrailingCloseTokens && (0, _fg.fg)('platform_editor_ai_show_diff_patch_2');
|
|
277
|
+
var isContained = function isContained(node, pos) {
|
|
278
|
+
if (requireContainedBlocks && pos < from) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
if (pos + node.nodeSize <= to) {
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
return relaxTrailingCloseTokens && pos >= from && endBeforeTrailingCloseTokens(node, pos) <= to;
|
|
285
|
+
};
|
|
250
286
|
// Iterate over the document nodes within the range
|
|
251
287
|
doc.nodesBetween(from, to, function (node, pos) {
|
|
252
288
|
if (coarseTableCellsOnly && isInsideTable(coarseTables, pos)) {
|
|
@@ -255,7 +291,7 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
|
|
|
255
291
|
return;
|
|
256
292
|
}
|
|
257
293
|
}
|
|
258
|
-
if (node.isBlock && (
|
|
294
|
+
if (node.isBlock && isContained(node, pos)) {
|
|
259
295
|
var _nodeEnd = pos + node.nodeSize;
|
|
260
296
|
var _isActive = isRangeActive(activeIndexPos, pos, _nodeEnd, attributionKey);
|
|
261
297
|
decorations.push.apply(decorations, (0, _toConsumableArray2.default)((0, _createBlockChangedDecoration.createBlockChangedDecoration)({
|
|
@@ -714,6 +750,9 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
|
|
|
714
750
|
})));
|
|
715
751
|
}
|
|
716
752
|
decorations.push.apply(decorations, (0, _toConsumableArray2.default)(calculateNodesForBlockDecoration({
|
|
753
|
+
// A deleted widget placed below anchors at the change's end, inside the very block
|
|
754
|
+
// this would let the decoration claim.
|
|
755
|
+
allowTrailingCloseTokens: !isDeletedWidgetBelow,
|
|
717
756
|
attributionKey: attributionKey,
|
|
718
757
|
doc: tr.doc,
|
|
719
758
|
from: change.fromB,
|
|
@@ -11,6 +11,7 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
|
|
|
11
11
|
var _prosemirrorChangeset = require("prosemirror-changeset");
|
|
12
12
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
13
13
|
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
14
|
+
var _fg = require("@atlaskit/platform-feature-flags/fg");
|
|
14
15
|
var _attributions = require("../decorations/colorSchemes/attributions");
|
|
15
16
|
var _charsByOffset = require("../utils/charsByOffset");
|
|
16
17
|
var _attrAwareTokenEncoder = require("./attrAwareTokenEncoder");
|
|
@@ -23,6 +24,16 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
23
24
|
var WORD_CHAR_REGEX = /(?:[0-9A-Z_a-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088F\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5C\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDC-\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C8A\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7DC\uA7F1-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDDC0-\uDDF3\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD40-\uDD59\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDD40-\uDD65\uDD6F-\uDD85\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDEC2-\uDEC7\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE3F\uDE40\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61\uDF80-\uDF89\uDF8B\uDF8E\uDF90-\uDFB5\uDFB7\uDFD1\uDFD3]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDED0-\uDEE3\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8\uDFC0-\uDFE0\uDFF0-\uDFF9]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDDB0-\uDDDB\uDDE0-\uDDE9\uDEE0-\uDEF2\uDF02\uDF04-\uDF10\uDF12-\uDF33\uDF50-\uDF59\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD80E\uD80F\uD81C-\uD822\uD840-\uD868\uD86A-\uD86D\uD86F-\uD872\uD874-\uD879\uD880-\uD883\uD885-\uD88C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F\uDC41-\uDC46\uDC60-\uDFFF]|\uD810[\uDC00-\uDFFA]|\uD811[\uDC00-\uDE46]|\uD818[\uDD00-\uDD1D\uDD30-\uDD39]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDD40-\uDD6C\uDD70-\uDD79\uDE40-\uDE96\uDEA0-\uDEB8\uDEBB-\uDED3\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3\uDFF2-\uDFF6]|\uD823[\uDC00-\uDCD5\uDCFF-\uDD1E\uDD80-\uDDF2]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD32\uDD50-\uDD52\uDD55\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD833[\uDCF0-\uDCF9]|\uD834[\uDEC0-\uDED3\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E\uDF25-\uDF2A]|\uD838[\uDC30-\uDC6D\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDCD0-\uDCEB\uDCF0-\uDCF9\uDDD0-\uDDED\uDDF0-\uDDFA\uDEC0-\uDEDE\uDEE0-\uDEE2\uDEE4\uDEE5\uDEE7-\uDEED\uDEF0-\uDEF4\uDEFE\uDEFF\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEAD\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0\uDFF0-\uDFFF]|\uD87B[\uDC00-\uDE5D]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A\uDF50-\uDFFF]|\uD88D[\uDC00-\uDC79])/;
|
|
24
25
|
var PUNCTUATION_REGEX = /(?:[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B4E\u1B4F\u1B5A-\u1B60\u1B7D-\u1B7F\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDD6E\uDEAD\uDED0\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9\uDFD4\uDFD5\uDFD7\uDFD8]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09\uDFE1]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDD6D-\uDD6F\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD839\uDDFF|\uD83A[\uDD5E\uDD5F])/;
|
|
25
26
|
var WHITESPACE_REGEX = /[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Whether a same-type replacement of `node` is diffed granularly rather than as a whole node.
|
|
30
|
+
* `isolating` nodes (table cells, layout columns, expands, bodied extensions, …) keep edits inside
|
|
31
|
+
* their boundary, so replacing one wholesale is an edit of its content, not a new node. Tables are
|
|
32
|
+
* excluded: `groupDeletedColumnChanges` relies on a replaced table being one whole-table change.
|
|
33
|
+
*/
|
|
34
|
+
var isGranularIsolatingNode = function isGranularIsolatingNode(node) {
|
|
35
|
+
return !!node.type.spec.isolating && node.type.spec.tableRole !== 'table';
|
|
36
|
+
};
|
|
26
37
|
var mapPosition = function mapPosition(mapping, pos) {
|
|
27
38
|
return mapping.map(pos);
|
|
28
39
|
};
|
|
@@ -225,6 +236,8 @@ var mergeOverlappingByNewDocRange = function mergeOverlappingByNewDocRange(chang
|
|
|
225
236
|
* - The replaced slice is not open
|
|
226
237
|
* - The replaced slice has only one child
|
|
227
238
|
* - The replacing slice has only one child
|
|
239
|
+
* - Both children are the same textblock type, or (behind `platform_editor_ai_show_diff_patch_2`)
|
|
240
|
+
* the same isolating, non-table node type whose text content differs
|
|
228
241
|
* - The replaced slice and replacing slice have the same text content
|
|
229
242
|
* - The replaced slice and replacing slice have the same child marks (if text content is equal)
|
|
230
243
|
*/
|
|
@@ -243,13 +256,27 @@ var shouldCheckGranularDiff = function shouldCheckGranularDiff(step, before, fro
|
|
|
243
256
|
}
|
|
244
257
|
var replacedNode = replacedSlice.content.firstChild;
|
|
245
258
|
var replacingNode = replacingSlice.content.firstChild;
|
|
246
|
-
if ((replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.type.name) !== (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.type.name)
|
|
259
|
+
if ((replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.type.name) !== (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.type.name)) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Replacing a whole isolating node (e.g. an AI `replaceNode` on a table cell) would otherwise
|
|
264
|
+
// report the entire node as changed, painting a cell overlay over content that was only
|
|
265
|
+
// edited inside it. Diff its content granularly instead, so only the inner edits are decorated.
|
|
266
|
+
var isIsolatingNode = (0, _fg.fg)('platform_editor_ai_show_diff_patch_2') && replacedNode !== null && isGranularIsolatingNode(replacedNode);
|
|
267
|
+
if (!(replacedNode !== null && replacedNode !== void 0 && replacedNode.type.isTextblock) && !isIsolatingNode) {
|
|
247
268
|
return false;
|
|
248
269
|
}
|
|
249
270
|
if (!_model.Mark.sameSet((_replacedNode$marks = replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.marks) !== null && _replacedNode$marks !== void 0 ? _replacedNode$marks : [], (_replacingNode$marks = replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.marks) !== null && _replacingNode$marks !== void 0 ? _replacingNode$marks : [])) {
|
|
250
271
|
return false;
|
|
251
272
|
}
|
|
252
273
|
var isTextContentEqual = (replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.textContent) === (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.textContent);
|
|
274
|
+
|
|
275
|
+
// `hasSameChildMarks` only compares an isolating node's direct (block) children, so it cannot
|
|
276
|
+
// vouch for one with unchanged text. Keep the existing whole-node fallback for that case.
|
|
277
|
+
if (isIsolatingNode) {
|
|
278
|
+
return !isTextContentEqual;
|
|
279
|
+
}
|
|
253
280
|
return !isTextContentEqual || isTextContentEqual && hasSameChildMarks(replacedNode, replacingNode);
|
|
254
281
|
};
|
|
255
282
|
var diffBySteps = exports.diffBySteps = function diffBySteps(originalDoc, steps, stepAttributions) {
|
|
@@ -157,7 +157,27 @@ const tableRanges = (doc, from, to) => {
|
|
|
157
157
|
return ranges;
|
|
158
158
|
};
|
|
159
159
|
const isInsideTable = (tables, pos) => tables.some(([tFrom, tTo]) => pos >= tFrom && pos < tTo);
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Where a block's content ends, excluding the run of close tokens that ends it: the block's own,
|
|
163
|
+
* then its last child's, and so on down to the last textblock. A change that keeps those trailing
|
|
164
|
+
* close tokens unchanged (because the other side ends in the same structure, e.g.
|
|
165
|
+
* `…</p></li></ul>`) still covers all of the block's content.
|
|
166
|
+
*/
|
|
167
|
+
const endBeforeTrailingCloseTokens = (node, pos) => {
|
|
168
|
+
let end = pos + node.nodeSize;
|
|
169
|
+
let current = node;
|
|
170
|
+
while (current && !current.isLeaf) {
|
|
171
|
+
end -= 1;
|
|
172
|
+
if (current.isTextblock) {
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
current = current.lastChild;
|
|
176
|
+
}
|
|
177
|
+
return end;
|
|
178
|
+
};
|
|
160
179
|
const calculateNodesForBlockDecoration = ({
|
|
180
|
+
allowTrailingCloseTokens = false,
|
|
161
181
|
attributionKey,
|
|
162
182
|
doc,
|
|
163
183
|
from,
|
|
@@ -213,8 +233,23 @@ const calculateNodesForBlockDecoration = ({
|
|
|
213
233
|
// re-render. Blocks outside the table keep their normal decorations.
|
|
214
234
|
const coarseTables = coarseTableCellsOnly ? tableRanges(doc, from, to) : [];
|
|
215
235
|
// nodesBetween visits ancestors that start before the changed range.
|
|
216
|
-
// Only fully contained blocks should mark existing list bullets as new.
|
|
217
|
-
|
|
236
|
+
// Only fully contained blocks should mark existing list bullets as new. Under patch 2 this also
|
|
237
|
+
// keeps the clean view from hiding a block the change only starts inside: that block holds
|
|
238
|
+
// unchanged text and the deleted-content widget, so `display: none` on it hid the whole diff.
|
|
239
|
+
const requireContainedBlocks = UNSAFE_expValNoExposure('platform_editor_ai_review_moment', 'isEnabled', false) === true || fg('platform_editor_ai_show_diff_patch_2');
|
|
240
|
+
// Under patch 2, a block whose content the change covers but whose trailing close tokens it does
|
|
241
|
+
// not (e.g. the last list item when both sides end in a list) is decorated like its siblings.
|
|
242
|
+
// Otherwise the clean view hides its text but leaves the block, e.g. an empty bullet.
|
|
243
|
+
const relaxTrailingCloseTokens = allowTrailingCloseTokens && fg('platform_editor_ai_show_diff_patch_2');
|
|
244
|
+
const isContained = (node, pos) => {
|
|
245
|
+
if (requireContainedBlocks && pos < from) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
if (pos + node.nodeSize <= to) {
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
return relaxTrailingCloseTokens && pos >= from && endBeforeTrailingCloseTokens(node, pos) <= to;
|
|
252
|
+
};
|
|
218
253
|
// Iterate over the document nodes within the range
|
|
219
254
|
doc.nodesBetween(from, to, (node, pos) => {
|
|
220
255
|
if (coarseTableCellsOnly && isInsideTable(coarseTables, pos)) {
|
|
@@ -223,7 +258,7 @@ const calculateNodesForBlockDecoration = ({
|
|
|
223
258
|
return;
|
|
224
259
|
}
|
|
225
260
|
}
|
|
226
|
-
if (node.isBlock && (
|
|
261
|
+
if (node.isBlock && isContained(node, pos)) {
|
|
227
262
|
const nodeEnd = pos + node.nodeSize;
|
|
228
263
|
const isActive = isRangeActive(activeIndexPos, pos, nodeEnd, attributionKey);
|
|
229
264
|
decorations.push(...createBlockChangedDecoration({
|
|
@@ -640,6 +675,9 @@ const calculateDiffDecorationsInner = ({
|
|
|
640
675
|
}));
|
|
641
676
|
}
|
|
642
677
|
decorations.push(...calculateNodesForBlockDecoration({
|
|
678
|
+
// A deleted widget placed below anchors at the change's end, inside the very block
|
|
679
|
+
// this would let the decoration claim.
|
|
680
|
+
allowTrailingCloseTokens: !isDeletedWidgetBelow,
|
|
643
681
|
attributionKey,
|
|
644
682
|
doc: tr.doc,
|
|
645
683
|
from: change.fromB,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { simplifyChanges, ChangeSet } from 'prosemirror-changeset';
|
|
2
2
|
import { Mark } from '@atlaskit/editor-prosemirror/model';
|
|
3
3
|
import { Mapping, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
4
|
+
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
4
5
|
import { getAttributionKey } from '../decorations/colorSchemes/attributions';
|
|
5
6
|
import { buildCharsByOffset } from '../utils/charsByOffset';
|
|
6
7
|
import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
|
|
@@ -8,6 +9,14 @@ import { optimizeChanges } from './optimizeChanges';
|
|
|
8
9
|
const WORD_CHAR_REGEX = /[\p{L}\p{N}_]/u;
|
|
9
10
|
const PUNCTUATION_REGEX = /\p{P}/u;
|
|
10
11
|
const WHITESPACE_REGEX = /\s/u;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Whether a same-type replacement of `node` is diffed granularly rather than as a whole node.
|
|
15
|
+
* `isolating` nodes (table cells, layout columns, expands, bodied extensions, …) keep edits inside
|
|
16
|
+
* their boundary, so replacing one wholesale is an edit of its content, not a new node. Tables are
|
|
17
|
+
* excluded: `groupDeletedColumnChanges` relies on a replaced table being one whole-table change.
|
|
18
|
+
*/
|
|
19
|
+
const isGranularIsolatingNode = node => !!node.type.spec.isolating && node.type.spec.tableRole !== 'table';
|
|
11
20
|
const mapPosition = (mapping, pos) => mapping.map(pos);
|
|
12
21
|
|
|
13
22
|
/**
|
|
@@ -196,6 +205,8 @@ const mergeOverlappingByNewDocRange = changes => {
|
|
|
196
205
|
* - The replaced slice is not open
|
|
197
206
|
* - The replaced slice has only one child
|
|
198
207
|
* - The replacing slice has only one child
|
|
208
|
+
* - Both children are the same textblock type, or (behind `platform_editor_ai_show_diff_patch_2`)
|
|
209
|
+
* the same isolating, non-table node type whose text content differs
|
|
199
210
|
* - The replaced slice and replacing slice have the same text content
|
|
200
211
|
* - The replaced slice and replacing slice have the same child marks (if text content is equal)
|
|
201
212
|
*/
|
|
@@ -214,13 +225,27 @@ const shouldCheckGranularDiff = (step, before, from, to) => {
|
|
|
214
225
|
}
|
|
215
226
|
const replacedNode = replacedSlice.content.firstChild;
|
|
216
227
|
const replacingNode = replacingSlice.content.firstChild;
|
|
217
|
-
if ((replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.type.name) !== (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.type.name)
|
|
228
|
+
if ((replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.type.name) !== (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.type.name)) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Replacing a whole isolating node (e.g. an AI `replaceNode` on a table cell) would otherwise
|
|
233
|
+
// report the entire node as changed, painting a cell overlay over content that was only
|
|
234
|
+
// edited inside it. Diff its content granularly instead, so only the inner edits are decorated.
|
|
235
|
+
const isIsolatingNode = fg('platform_editor_ai_show_diff_patch_2') && replacedNode !== null && isGranularIsolatingNode(replacedNode);
|
|
236
|
+
if (!(replacedNode !== null && replacedNode !== void 0 && replacedNode.type.isTextblock) && !isIsolatingNode) {
|
|
218
237
|
return false;
|
|
219
238
|
}
|
|
220
239
|
if (!Mark.sameSet((_replacedNode$marks = replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.marks) !== null && _replacedNode$marks !== void 0 ? _replacedNode$marks : [], (_replacingNode$marks = replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.marks) !== null && _replacingNode$marks !== void 0 ? _replacingNode$marks : [])) {
|
|
221
240
|
return false;
|
|
222
241
|
}
|
|
223
242
|
const isTextContentEqual = (replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.textContent) === (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.textContent);
|
|
243
|
+
|
|
244
|
+
// `hasSameChildMarks` only compares an isolating node's direct (block) children, so it cannot
|
|
245
|
+
// vouch for one with unchanged text. Keep the existing whole-node fallback for that case.
|
|
246
|
+
if (isIsolatingNode) {
|
|
247
|
+
return !isTextContentEqual;
|
|
248
|
+
}
|
|
224
249
|
return !isTextContentEqual || isTextContentEqual && hasSameChildMarks(replacedNode, replacingNode);
|
|
225
250
|
};
|
|
226
251
|
export const diffBySteps = (originalDoc, steps, stepAttributions) => {
|
|
@@ -170,8 +170,29 @@ var isInsideTable = function isInsideTable(tables, pos) {
|
|
|
170
170
|
return pos >= tFrom && pos < tTo;
|
|
171
171
|
});
|
|
172
172
|
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Where a block's content ends, excluding the run of close tokens that ends it: the block's own,
|
|
176
|
+
* then its last child's, and so on down to the last textblock. A change that keeps those trailing
|
|
177
|
+
* close tokens unchanged (because the other side ends in the same structure, e.g.
|
|
178
|
+
* `…</p></li></ul>`) still covers all of the block's content.
|
|
179
|
+
*/
|
|
180
|
+
var endBeforeTrailingCloseTokens = function endBeforeTrailingCloseTokens(node, pos) {
|
|
181
|
+
var end = pos + node.nodeSize;
|
|
182
|
+
var current = node;
|
|
183
|
+
while (current && !current.isLeaf) {
|
|
184
|
+
end -= 1;
|
|
185
|
+
if (current.isTextblock) {
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
current = current.lastChild;
|
|
189
|
+
}
|
|
190
|
+
return end;
|
|
191
|
+
};
|
|
173
192
|
var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration(_ref5) {
|
|
174
|
-
var
|
|
193
|
+
var _ref5$allowTrailingCl = _ref5.allowTrailingCloseTokens,
|
|
194
|
+
allowTrailingCloseTokens = _ref5$allowTrailingCl === void 0 ? false : _ref5$allowTrailingCl,
|
|
195
|
+
attributionKey = _ref5.attributionKey,
|
|
175
196
|
doc = _ref5.doc,
|
|
176
197
|
from = _ref5.from,
|
|
177
198
|
to = _ref5.to,
|
|
@@ -238,8 +259,23 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
|
|
|
238
259
|
// re-render. Blocks outside the table keep their normal decorations.
|
|
239
260
|
var coarseTables = coarseTableCellsOnly ? tableRanges(doc, from, to) : [];
|
|
240
261
|
// nodesBetween visits ancestors that start before the changed range.
|
|
241
|
-
// Only fully contained blocks should mark existing list bullets as new.
|
|
242
|
-
|
|
262
|
+
// Only fully contained blocks should mark existing list bullets as new. Under patch 2 this also
|
|
263
|
+
// keeps the clean view from hiding a block the change only starts inside: that block holds
|
|
264
|
+
// unchanged text and the deleted-content widget, so `display: none` on it hid the whole diff.
|
|
265
|
+
var requireContainedBlocks = UNSAFE_expValNoExposure('platform_editor_ai_review_moment', 'isEnabled', false) === true || fg('platform_editor_ai_show_diff_patch_2');
|
|
266
|
+
// Under patch 2, a block whose content the change covers but whose trailing close tokens it does
|
|
267
|
+
// not (e.g. the last list item when both sides end in a list) is decorated like its siblings.
|
|
268
|
+
// Otherwise the clean view hides its text but leaves the block, e.g. an empty bullet.
|
|
269
|
+
var relaxTrailingCloseTokens = allowTrailingCloseTokens && fg('platform_editor_ai_show_diff_patch_2');
|
|
270
|
+
var isContained = function isContained(node, pos) {
|
|
271
|
+
if (requireContainedBlocks && pos < from) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
if (pos + node.nodeSize <= to) {
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
return relaxTrailingCloseTokens && pos >= from && endBeforeTrailingCloseTokens(node, pos) <= to;
|
|
278
|
+
};
|
|
243
279
|
// Iterate over the document nodes within the range
|
|
244
280
|
doc.nodesBetween(from, to, function (node, pos) {
|
|
245
281
|
if (coarseTableCellsOnly && isInsideTable(coarseTables, pos)) {
|
|
@@ -248,7 +284,7 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
|
|
|
248
284
|
return;
|
|
249
285
|
}
|
|
250
286
|
}
|
|
251
|
-
if (node.isBlock && (
|
|
287
|
+
if (node.isBlock && isContained(node, pos)) {
|
|
252
288
|
var _nodeEnd = pos + node.nodeSize;
|
|
253
289
|
var _isActive = isRangeActive(activeIndexPos, pos, _nodeEnd, attributionKey);
|
|
254
290
|
decorations.push.apply(decorations, _toConsumableArray(createBlockChangedDecoration({
|
|
@@ -707,6 +743,9 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
|
|
|
707
743
|
})));
|
|
708
744
|
}
|
|
709
745
|
decorations.push.apply(decorations, _toConsumableArray(calculateNodesForBlockDecoration({
|
|
746
|
+
// A deleted widget placed below anchors at the change's end, inside the very block
|
|
747
|
+
// this would let the decoration claim.
|
|
748
|
+
allowTrailingCloseTokens: !isDeletedWidgetBelow,
|
|
710
749
|
attributionKey: attributionKey,
|
|
711
750
|
doc: tr.doc,
|
|
712
751
|
from: change.fromB,
|
|
@@ -9,6 +9,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
9
9
|
import { simplifyChanges, ChangeSet } from 'prosemirror-changeset';
|
|
10
10
|
import { Mark } from '@atlaskit/editor-prosemirror/model';
|
|
11
11
|
import { Mapping, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
12
|
+
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
12
13
|
import { getAttributionKey } from '../decorations/colorSchemes/attributions';
|
|
13
14
|
import { buildCharsByOffset } from '../utils/charsByOffset';
|
|
14
15
|
import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
|
|
@@ -16,6 +17,16 @@ import { optimizeChanges } from './optimizeChanges';
|
|
|
16
17
|
var WORD_CHAR_REGEX = /(?:[0-9A-Z_a-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088F\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5C\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDC-\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C8A\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7DC\uA7F1-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDDC0-\uDDF3\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD40-\uDD59\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDD40-\uDD65\uDD6F-\uDD85\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDEC2-\uDEC7\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE3F\uDE40\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61\uDF80-\uDF89\uDF8B\uDF8E\uDF90-\uDFB5\uDFB7\uDFD1\uDFD3]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDED0-\uDEE3\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8\uDFC0-\uDFE0\uDFF0-\uDFF9]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDDB0-\uDDDB\uDDE0-\uDDE9\uDEE0-\uDEF2\uDF02\uDF04-\uDF10\uDF12-\uDF33\uDF50-\uDF59\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD80E\uD80F\uD81C-\uD822\uD840-\uD868\uD86A-\uD86D\uD86F-\uD872\uD874-\uD879\uD880-\uD883\uD885-\uD88C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F\uDC41-\uDC46\uDC60-\uDFFF]|\uD810[\uDC00-\uDFFA]|\uD811[\uDC00-\uDE46]|\uD818[\uDD00-\uDD1D\uDD30-\uDD39]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDD40-\uDD6C\uDD70-\uDD79\uDE40-\uDE96\uDEA0-\uDEB8\uDEBB-\uDED3\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3\uDFF2-\uDFF6]|\uD823[\uDC00-\uDCD5\uDCFF-\uDD1E\uDD80-\uDDF2]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD32\uDD50-\uDD52\uDD55\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD833[\uDCF0-\uDCF9]|\uD834[\uDEC0-\uDED3\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E\uDF25-\uDF2A]|\uD838[\uDC30-\uDC6D\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDCD0-\uDCEB\uDCF0-\uDCF9\uDDD0-\uDDED\uDDF0-\uDDFA\uDEC0-\uDEDE\uDEE0-\uDEE2\uDEE4\uDEE5\uDEE7-\uDEED\uDEF0-\uDEF4\uDEFE\uDEFF\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEAD\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0\uDFF0-\uDFFF]|\uD87B[\uDC00-\uDE5D]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A\uDF50-\uDFFF]|\uD88D[\uDC00-\uDC79])/;
|
|
17
18
|
var PUNCTUATION_REGEX = /(?:[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B4E\u1B4F\u1B5A-\u1B60\u1B7D-\u1B7F\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDD6E\uDEAD\uDED0\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9\uDFD4\uDFD5\uDFD7\uDFD8]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09\uDFE1]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDD6D-\uDD6F\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD839\uDDFF|\uD83A[\uDD5E\uDD5F])/;
|
|
18
19
|
var WHITESPACE_REGEX = /[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Whether a same-type replacement of `node` is diffed granularly rather than as a whole node.
|
|
23
|
+
* `isolating` nodes (table cells, layout columns, expands, bodied extensions, …) keep edits inside
|
|
24
|
+
* their boundary, so replacing one wholesale is an edit of its content, not a new node. Tables are
|
|
25
|
+
* excluded: `groupDeletedColumnChanges` relies on a replaced table being one whole-table change.
|
|
26
|
+
*/
|
|
27
|
+
var isGranularIsolatingNode = function isGranularIsolatingNode(node) {
|
|
28
|
+
return !!node.type.spec.isolating && node.type.spec.tableRole !== 'table';
|
|
29
|
+
};
|
|
19
30
|
var mapPosition = function mapPosition(mapping, pos) {
|
|
20
31
|
return mapping.map(pos);
|
|
21
32
|
};
|
|
@@ -218,6 +229,8 @@ var mergeOverlappingByNewDocRange = function mergeOverlappingByNewDocRange(chang
|
|
|
218
229
|
* - The replaced slice is not open
|
|
219
230
|
* - The replaced slice has only one child
|
|
220
231
|
* - The replacing slice has only one child
|
|
232
|
+
* - Both children are the same textblock type, or (behind `platform_editor_ai_show_diff_patch_2`)
|
|
233
|
+
* the same isolating, non-table node type whose text content differs
|
|
221
234
|
* - The replaced slice and replacing slice have the same text content
|
|
222
235
|
* - The replaced slice and replacing slice have the same child marks (if text content is equal)
|
|
223
236
|
*/
|
|
@@ -236,13 +249,27 @@ var shouldCheckGranularDiff = function shouldCheckGranularDiff(step, before, fro
|
|
|
236
249
|
}
|
|
237
250
|
var replacedNode = replacedSlice.content.firstChild;
|
|
238
251
|
var replacingNode = replacingSlice.content.firstChild;
|
|
239
|
-
if ((replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.type.name) !== (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.type.name)
|
|
252
|
+
if ((replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.type.name) !== (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.type.name)) {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Replacing a whole isolating node (e.g. an AI `replaceNode` on a table cell) would otherwise
|
|
257
|
+
// report the entire node as changed, painting a cell overlay over content that was only
|
|
258
|
+
// edited inside it. Diff its content granularly instead, so only the inner edits are decorated.
|
|
259
|
+
var isIsolatingNode = fg('platform_editor_ai_show_diff_patch_2') && replacedNode !== null && isGranularIsolatingNode(replacedNode);
|
|
260
|
+
if (!(replacedNode !== null && replacedNode !== void 0 && replacedNode.type.isTextblock) && !isIsolatingNode) {
|
|
240
261
|
return false;
|
|
241
262
|
}
|
|
242
263
|
if (!Mark.sameSet((_replacedNode$marks = replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.marks) !== null && _replacedNode$marks !== void 0 ? _replacedNode$marks : [], (_replacingNode$marks = replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.marks) !== null && _replacingNode$marks !== void 0 ? _replacingNode$marks : [])) {
|
|
243
264
|
return false;
|
|
244
265
|
}
|
|
245
266
|
var isTextContentEqual = (replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.textContent) === (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.textContent);
|
|
267
|
+
|
|
268
|
+
// `hasSameChildMarks` only compares an isolating node's direct (block) children, so it cannot
|
|
269
|
+
// vouch for one with unchanged text. Keep the existing whole-node fallback for that case.
|
|
270
|
+
if (isIsolatingNode) {
|
|
271
|
+
return !isTextContentEqual;
|
|
272
|
+
}
|
|
246
273
|
return !isTextContentEqual || isTextContentEqual && hasSameChildMarks(replacedNode, replacingNode);
|
|
247
274
|
};
|
|
248
275
|
export var diffBySteps = function diffBySteps(originalDoc, steps, stepAttributions) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "23.0.1",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -29,17 +29,17 @@
|
|
|
29
29
|
"@atlaskit/agent-color": "^1.0.0",
|
|
30
30
|
"@atlaskit/avatar": "^30.0.0",
|
|
31
31
|
"@atlaskit/custom-steps": "^1.1.0",
|
|
32
|
-
"@atlaskit/editor-plugin-accessibility-utils": "^
|
|
33
|
-
"@atlaskit/editor-plugin-analytics": "^
|
|
34
|
-
"@atlaskit/editor-plugin-limited-mode": "^
|
|
35
|
-
"@atlaskit/editor-plugin-user-intent": "^
|
|
32
|
+
"@atlaskit/editor-plugin-accessibility-utils": "^25.0.0",
|
|
33
|
+
"@atlaskit/editor-plugin-analytics": "^25.0.0",
|
|
34
|
+
"@atlaskit/editor-plugin-limited-mode": "^22.0.0",
|
|
35
|
+
"@atlaskit/editor-plugin-user-intent": "^23.0.0",
|
|
36
36
|
"@atlaskit/editor-prosemirror": "^9.0.0",
|
|
37
37
|
"@atlaskit/editor-shared-styles": "^4.3.0",
|
|
38
38
|
"@atlaskit/editor-tables": "^3.2.0",
|
|
39
39
|
"@atlaskit/platform-feature-experiments": "^0.3.0",
|
|
40
40
|
"@atlaskit/platform-feature-flags": "^2.2.0",
|
|
41
41
|
"@atlaskit/primitives": "^22.5.0",
|
|
42
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
42
|
+
"@atlaskit/tmp-editor-statsig": "^225.0.0",
|
|
43
43
|
"@atlaskit/tokens": "^20.3.0",
|
|
44
44
|
"@babel/runtime": "^7.0.0",
|
|
45
45
|
"@compiled/react": "^1.0.2",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@atlaskit/button": "^25.4.0",
|
|
54
54
|
"@atlaskit/css": "^1.1.0",
|
|
55
55
|
"@atlaskit/dropdown-menu": "^21.0.0",
|
|
56
|
-
"@atlaskit/editor-core": "^
|
|
56
|
+
"@atlaskit/editor-core": "^235.0.0",
|
|
57
57
|
"@atlaskit/editor-json-transformer": "^10.0.0",
|
|
58
58
|
"@atlaskit/editor-plugins": "^16.2.0",
|
|
59
59
|
"@atlaskit/form": "^18.1.0",
|
|
@@ -63,15 +63,15 @@
|
|
|
63
63
|
"@atlaskit/util-data-test": "^19.1.0",
|
|
64
64
|
"@atlassian/confluence-presets": "workspace:^",
|
|
65
65
|
"@atlassian/content-reconciliation": "^0.1.3506",
|
|
66
|
-
"@atlassian/editor-ai-injected-editors": "^
|
|
67
|
-
"@atlassian/editor-plugin-ai": "^
|
|
66
|
+
"@atlassian/editor-ai-injected-editors": "^39.0.0",
|
|
67
|
+
"@atlassian/editor-plugin-ai": "^79.0.0",
|
|
68
68
|
"@atlassian/structured-docs-types": "workspace:^",
|
|
69
69
|
"react": "^19.2.0",
|
|
70
70
|
"react-dom": "^19.2.0",
|
|
71
71
|
"react-intl": "^7.0.0"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
|
-
"@atlaskit/editor-common": "^
|
|
74
|
+
"@atlaskit/editor-common": "^129.1.0",
|
|
75
75
|
"react": "^18.2.0 || ^19.2.0",
|
|
76
76
|
"react-dom": "^18.2.0 || ^19.2.0",
|
|
77
77
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|