@atlaskit/editor-plugin-show-diff 9.0.0 → 9.0.2
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
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 9.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`b3d1adf5a46c7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b3d1adf5a46c7) -
|
|
8
|
+
Fix word-boundary diff cutoff when a granular textblock diff runs inside a paragraph that contains
|
|
9
|
+
non-text inline nodes (hardBreak, mention, emoji, date, etc.). Previously the expansion logic
|
|
10
|
+
indexed into `parent.textContent`, which strips those nodes, so doc positions in the body could
|
|
11
|
+
land mid-word and pull untouched neighbouring words into the diff range.
|
|
12
|
+
|
|
13
|
+
## 9.0.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 9.0.0
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -20,6 +20,36 @@ var mapPosition = function mapPosition(mapping, pos) {
|
|
|
20
20
|
return mapping.map(pos);
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Build a per-content-offset view of the textblock's characters.
|
|
25
|
+
*
|
|
26
|
+
* Returns an array `chars` whose length is `parent.content.size`. For every
|
|
27
|
+
* offset that lies inside a text node, `chars[offset]` is the character at
|
|
28
|
+
* that offset; for every offset that lies inside (or on the edge of) a
|
|
29
|
+
* non-text inline node — hardBreak, mention, emoji, date, etc. — the entry
|
|
30
|
+
* is `null`.
|
|
31
|
+
*
|
|
32
|
+
* Using doc positions to index `parent.textContent` is wrong because
|
|
33
|
+
* `textContent` strips non-text inline nodes, so every such node shifts the
|
|
34
|
+
* lookup off by its size. This per-offset view restores a 1:1 mapping between
|
|
35
|
+
* doc positions inside the textblock and the character (or "no character",
|
|
36
|
+
* i.e. a hard word boundary) at that position.
|
|
37
|
+
*/
|
|
38
|
+
var buildCharsByOffset = function buildCharsByOffset(parent) {
|
|
39
|
+
var chars = new Array(parent.content.size).fill(null);
|
|
40
|
+
parent.content.forEach(function (child, offset) {
|
|
41
|
+
var _child$text;
|
|
42
|
+
if (!child.isText) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
var text = (_child$text = child.text) !== null && _child$text !== void 0 ? _child$text : '';
|
|
46
|
+
for (var i = 0; i < text.length; i++) {
|
|
47
|
+
chars[offset + i] = text[i];
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return chars;
|
|
51
|
+
};
|
|
52
|
+
|
|
23
53
|
/**
|
|
24
54
|
* Given a ProseMirror doc and a position range [from, to], expand
|
|
25
55
|
* both endpoints outward to the nearest word boundaries.
|
|
@@ -28,7 +58,9 @@ var mapPosition = function mapPosition(mapping, pos) {
|
|
|
28
58
|
* This covers accented/Unicode letters (e.g. é, ñ, ü) while still stopping at
|
|
29
59
|
* commas, periods, and other punctuation. Hyphens are explicitly included so that
|
|
30
60
|
* hyphenated words (e.g. "deep-sea") are treated as a single word.
|
|
31
|
-
* Expansion stops at whitespace, punctuation (excluding hyphen),
|
|
61
|
+
* Expansion stops at whitespace, punctuation (excluding hyphen), the boundary of
|
|
62
|
+
* any non-text inline node (hardBreak, mention, emoji, date, etc.), or the
|
|
63
|
+
* textblock edges.
|
|
32
64
|
*
|
|
33
65
|
* If `from` and `to` resolve into different parent nodes, or if the
|
|
34
66
|
* parent is not a textblock, the range is returned unchanged.
|
|
@@ -55,24 +87,32 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
55
87
|
}
|
|
56
88
|
}
|
|
57
89
|
var parent = $from.parent;
|
|
58
|
-
var text = parent.textContent;
|
|
59
90
|
var parentStart = $from.start(); // absolute position of the first character in the textblock
|
|
60
91
|
|
|
61
|
-
//
|
|
92
|
+
// Per-offset view of the textblock so we don't conflate the inline
|
|
93
|
+
// positions of non-text nodes (hardBreak, mention, emoji, date, etc.)
|
|
94
|
+
// with the characters returned by `parent.textContent`.
|
|
95
|
+
var chars = buildCharsByOffset(parent);
|
|
96
|
+
|
|
97
|
+
// Convert absolute doc positions to zero-based content offsets.
|
|
62
98
|
var fromIdx = from - parentStart;
|
|
63
99
|
var toIdx = to - parentStart;
|
|
64
100
|
|
|
65
|
-
// any non whitespace and non punctuation chars
|
|
66
|
-
//
|
|
101
|
+
// any non whitespace and non punctuation chars. `null` represents a
|
|
102
|
+
// position inside (or at the edge of) a non-text inline node, which
|
|
103
|
+
// always counts as a hard word boundary.
|
|
67
104
|
var isWordChar = function isWordChar(ch) {
|
|
68
|
-
return
|
|
105
|
+
return (
|
|
106
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
107
|
+
typeof ch === 'string' && /(?:[\x2D0-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])/.test(ch)
|
|
108
|
+
);
|
|
69
109
|
};
|
|
70
110
|
|
|
71
111
|
// Detect whether the position sits mid-word: there is a word character
|
|
72
112
|
// on both sides of the position (or, for a non-empty range, on the
|
|
73
113
|
// outer side of each endpoint).
|
|
74
114
|
var isMidWord = function isMidWord(idx) {
|
|
75
|
-
return idx > 0 && idx <
|
|
115
|
+
return idx > 0 && idx < chars.length && isWordChar(chars[idx - 1]) && isWordChar(chars[idx]);
|
|
76
116
|
};
|
|
77
117
|
|
|
78
118
|
// For a zero-width range (pure insertion / deletion point), only expand
|
|
@@ -86,10 +126,10 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
86
126
|
};
|
|
87
127
|
}
|
|
88
128
|
// Expand both directions from the mid-word point.
|
|
89
|
-
while (fromIdx > 0 && isWordChar(
|
|
129
|
+
while (fromIdx > 0 && isWordChar(chars[fromIdx - 1])) {
|
|
90
130
|
fromIdx--;
|
|
91
131
|
}
|
|
92
|
-
while (toIdx <
|
|
132
|
+
while (toIdx < chars.length && isWordChar(chars[toIdx])) {
|
|
93
133
|
toIdx++;
|
|
94
134
|
}
|
|
95
135
|
return {
|
|
@@ -102,16 +142,16 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
102
142
|
|
|
103
143
|
// Expand left only if `from` is truly mid-word: the character at `from`
|
|
104
144
|
// (inside the range) and the character before `from` are both word chars.
|
|
105
|
-
if (fromIdx > 0 && fromIdx <
|
|
106
|
-
while (fromIdx > 0 && isWordChar(
|
|
145
|
+
if (fromIdx > 0 && fromIdx < chars.length && isWordChar(chars[fromIdx]) && isWordChar(chars[fromIdx - 1])) {
|
|
146
|
+
while (fromIdx > 0 && isWordChar(chars[fromIdx - 1])) {
|
|
107
147
|
fromIdx--;
|
|
108
148
|
}
|
|
109
149
|
}
|
|
110
150
|
|
|
111
151
|
// Expand right only if `to` is truly mid-word: the character just before
|
|
112
152
|
// `to` (last char of the range) and the character at `to` are both word chars.
|
|
113
|
-
if (toIdx > 0 && toIdx <
|
|
114
|
-
while (toIdx <
|
|
153
|
+
if (toIdx > 0 && toIdx < chars.length && isWordChar(chars[toIdx - 1]) && isWordChar(chars[toIdx])) {
|
|
154
|
+
while (toIdx < chars.length && isWordChar(chars[toIdx])) {
|
|
115
155
|
toIdx++;
|
|
116
156
|
}
|
|
117
157
|
}
|
|
@@ -4,6 +4,36 @@ import { Mapping, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
|
4
4
|
import { optimizeChanges } from './optimizeChanges';
|
|
5
5
|
const mapPosition = (mapping, pos) => mapping.map(pos);
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Build a per-content-offset view of the textblock's characters.
|
|
9
|
+
*
|
|
10
|
+
* Returns an array `chars` whose length is `parent.content.size`. For every
|
|
11
|
+
* offset that lies inside a text node, `chars[offset]` is the character at
|
|
12
|
+
* that offset; for every offset that lies inside (or on the edge of) a
|
|
13
|
+
* non-text inline node — hardBreak, mention, emoji, date, etc. — the entry
|
|
14
|
+
* is `null`.
|
|
15
|
+
*
|
|
16
|
+
* Using doc positions to index `parent.textContent` is wrong because
|
|
17
|
+
* `textContent` strips non-text inline nodes, so every such node shifts the
|
|
18
|
+
* lookup off by its size. This per-offset view restores a 1:1 mapping between
|
|
19
|
+
* doc positions inside the textblock and the character (or "no character",
|
|
20
|
+
* i.e. a hard word boundary) at that position.
|
|
21
|
+
*/
|
|
22
|
+
const buildCharsByOffset = parent => {
|
|
23
|
+
const chars = new Array(parent.content.size).fill(null);
|
|
24
|
+
parent.content.forEach((child, offset) => {
|
|
25
|
+
var _child$text;
|
|
26
|
+
if (!child.isText) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const text = (_child$text = child.text) !== null && _child$text !== void 0 ? _child$text : '';
|
|
30
|
+
for (let i = 0; i < text.length; i++) {
|
|
31
|
+
chars[offset + i] = text[i];
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return chars;
|
|
35
|
+
};
|
|
36
|
+
|
|
7
37
|
/**
|
|
8
38
|
* Given a ProseMirror doc and a position range [from, to], expand
|
|
9
39
|
* both endpoints outward to the nearest word boundaries.
|
|
@@ -12,7 +42,9 @@ const mapPosition = (mapping, pos) => mapping.map(pos);
|
|
|
12
42
|
* This covers accented/Unicode letters (e.g. é, ñ, ü) while still stopping at
|
|
13
43
|
* commas, periods, and other punctuation. Hyphens are explicitly included so that
|
|
14
44
|
* hyphenated words (e.g. "deep-sea") are treated as a single word.
|
|
15
|
-
* Expansion stops at whitespace, punctuation (excluding hyphen),
|
|
45
|
+
* Expansion stops at whitespace, punctuation (excluding hyphen), the boundary of
|
|
46
|
+
* any non-text inline node (hardBreak, mention, emoji, date, etc.), or the
|
|
47
|
+
* textblock edges.
|
|
16
48
|
*
|
|
17
49
|
* If `from` and `to` resolve into different parent nodes, or if the
|
|
18
50
|
* parent is not a textblock, the range is returned unchanged.
|
|
@@ -39,21 +71,28 @@ const expandToWordBoundaries = (doc, from, to) => {
|
|
|
39
71
|
}
|
|
40
72
|
}
|
|
41
73
|
const parent = $from.parent;
|
|
42
|
-
const text = parent.textContent;
|
|
43
74
|
const parentStart = $from.start(); // absolute position of the first character in the textblock
|
|
44
75
|
|
|
45
|
-
//
|
|
76
|
+
// Per-offset view of the textblock so we don't conflate the inline
|
|
77
|
+
// positions of non-text nodes (hardBreak, mention, emoji, date, etc.)
|
|
78
|
+
// with the characters returned by `parent.textContent`.
|
|
79
|
+
const chars = buildCharsByOffset(parent);
|
|
80
|
+
|
|
81
|
+
// Convert absolute doc positions to zero-based content offsets.
|
|
46
82
|
let fromIdx = from - parentStart;
|
|
47
83
|
let toIdx = to - parentStart;
|
|
48
84
|
|
|
49
|
-
// any non whitespace and non punctuation chars
|
|
85
|
+
// any non whitespace and non punctuation chars. `null` represents a
|
|
86
|
+
// position inside (or at the edge of) a non-text inline node, which
|
|
87
|
+
// always counts as a hard word boundary.
|
|
88
|
+
const isWordChar = ch =>
|
|
50
89
|
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
51
|
-
|
|
90
|
+
typeof ch === 'string' && /[\p{L}\p{N}_-]/u.test(ch);
|
|
52
91
|
|
|
53
92
|
// Detect whether the position sits mid-word: there is a word character
|
|
54
93
|
// on both sides of the position (or, for a non-empty range, on the
|
|
55
94
|
// outer side of each endpoint).
|
|
56
|
-
const isMidWord = idx => idx > 0 && idx <
|
|
95
|
+
const isMidWord = idx => idx > 0 && idx < chars.length && isWordChar(chars[idx - 1]) && isWordChar(chars[idx]);
|
|
57
96
|
|
|
58
97
|
// For a zero-width range (pure insertion / deletion point), only expand
|
|
59
98
|
// if the point is mid-word — i.e. both the char before and after are
|
|
@@ -66,10 +105,10 @@ const expandToWordBoundaries = (doc, from, to) => {
|
|
|
66
105
|
};
|
|
67
106
|
}
|
|
68
107
|
// Expand both directions from the mid-word point.
|
|
69
|
-
while (fromIdx > 0 && isWordChar(
|
|
108
|
+
while (fromIdx > 0 && isWordChar(chars[fromIdx - 1])) {
|
|
70
109
|
fromIdx--;
|
|
71
110
|
}
|
|
72
|
-
while (toIdx <
|
|
111
|
+
while (toIdx < chars.length && isWordChar(chars[toIdx])) {
|
|
73
112
|
toIdx++;
|
|
74
113
|
}
|
|
75
114
|
return {
|
|
@@ -82,16 +121,16 @@ const expandToWordBoundaries = (doc, from, to) => {
|
|
|
82
121
|
|
|
83
122
|
// Expand left only if `from` is truly mid-word: the character at `from`
|
|
84
123
|
// (inside the range) and the character before `from` are both word chars.
|
|
85
|
-
if (fromIdx > 0 && fromIdx <
|
|
86
|
-
while (fromIdx > 0 && isWordChar(
|
|
124
|
+
if (fromIdx > 0 && fromIdx < chars.length && isWordChar(chars[fromIdx]) && isWordChar(chars[fromIdx - 1])) {
|
|
125
|
+
while (fromIdx > 0 && isWordChar(chars[fromIdx - 1])) {
|
|
87
126
|
fromIdx--;
|
|
88
127
|
}
|
|
89
128
|
}
|
|
90
129
|
|
|
91
130
|
// Expand right only if `to` is truly mid-word: the character just before
|
|
92
131
|
// `to` (last char of the range) and the character at `to` are both word chars.
|
|
93
|
-
if (toIdx > 0 && toIdx <
|
|
94
|
-
while (toIdx <
|
|
132
|
+
if (toIdx > 0 && toIdx < chars.length && isWordChar(chars[toIdx - 1]) && isWordChar(chars[toIdx])) {
|
|
133
|
+
while (toIdx < chars.length && isWordChar(chars[toIdx])) {
|
|
95
134
|
toIdx++;
|
|
96
135
|
}
|
|
97
136
|
}
|
|
@@ -13,6 +13,36 @@ var mapPosition = function mapPosition(mapping, pos) {
|
|
|
13
13
|
return mapping.map(pos);
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Build a per-content-offset view of the textblock's characters.
|
|
18
|
+
*
|
|
19
|
+
* Returns an array `chars` whose length is `parent.content.size`. For every
|
|
20
|
+
* offset that lies inside a text node, `chars[offset]` is the character at
|
|
21
|
+
* that offset; for every offset that lies inside (or on the edge of) a
|
|
22
|
+
* non-text inline node — hardBreak, mention, emoji, date, etc. — the entry
|
|
23
|
+
* is `null`.
|
|
24
|
+
*
|
|
25
|
+
* Using doc positions to index `parent.textContent` is wrong because
|
|
26
|
+
* `textContent` strips non-text inline nodes, so every such node shifts the
|
|
27
|
+
* lookup off by its size. This per-offset view restores a 1:1 mapping between
|
|
28
|
+
* doc positions inside the textblock and the character (or "no character",
|
|
29
|
+
* i.e. a hard word boundary) at that position.
|
|
30
|
+
*/
|
|
31
|
+
var buildCharsByOffset = function buildCharsByOffset(parent) {
|
|
32
|
+
var chars = new Array(parent.content.size).fill(null);
|
|
33
|
+
parent.content.forEach(function (child, offset) {
|
|
34
|
+
var _child$text;
|
|
35
|
+
if (!child.isText) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
var text = (_child$text = child.text) !== null && _child$text !== void 0 ? _child$text : '';
|
|
39
|
+
for (var i = 0; i < text.length; i++) {
|
|
40
|
+
chars[offset + i] = text[i];
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return chars;
|
|
44
|
+
};
|
|
45
|
+
|
|
16
46
|
/**
|
|
17
47
|
* Given a ProseMirror doc and a position range [from, to], expand
|
|
18
48
|
* both endpoints outward to the nearest word boundaries.
|
|
@@ -21,7 +51,9 @@ var mapPosition = function mapPosition(mapping, pos) {
|
|
|
21
51
|
* This covers accented/Unicode letters (e.g. é, ñ, ü) while still stopping at
|
|
22
52
|
* commas, periods, and other punctuation. Hyphens are explicitly included so that
|
|
23
53
|
* hyphenated words (e.g. "deep-sea") are treated as a single word.
|
|
24
|
-
* Expansion stops at whitespace, punctuation (excluding hyphen),
|
|
54
|
+
* Expansion stops at whitespace, punctuation (excluding hyphen), the boundary of
|
|
55
|
+
* any non-text inline node (hardBreak, mention, emoji, date, etc.), or the
|
|
56
|
+
* textblock edges.
|
|
25
57
|
*
|
|
26
58
|
* If `from` and `to` resolve into different parent nodes, or if the
|
|
27
59
|
* parent is not a textblock, the range is returned unchanged.
|
|
@@ -48,24 +80,32 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
48
80
|
}
|
|
49
81
|
}
|
|
50
82
|
var parent = $from.parent;
|
|
51
|
-
var text = parent.textContent;
|
|
52
83
|
var parentStart = $from.start(); // absolute position of the first character in the textblock
|
|
53
84
|
|
|
54
|
-
//
|
|
85
|
+
// Per-offset view of the textblock so we don't conflate the inline
|
|
86
|
+
// positions of non-text nodes (hardBreak, mention, emoji, date, etc.)
|
|
87
|
+
// with the characters returned by `parent.textContent`.
|
|
88
|
+
var chars = buildCharsByOffset(parent);
|
|
89
|
+
|
|
90
|
+
// Convert absolute doc positions to zero-based content offsets.
|
|
55
91
|
var fromIdx = from - parentStart;
|
|
56
92
|
var toIdx = to - parentStart;
|
|
57
93
|
|
|
58
|
-
// any non whitespace and non punctuation chars
|
|
59
|
-
//
|
|
94
|
+
// any non whitespace and non punctuation chars. `null` represents a
|
|
95
|
+
// position inside (or at the edge of) a non-text inline node, which
|
|
96
|
+
// always counts as a hard word boundary.
|
|
60
97
|
var isWordChar = function isWordChar(ch) {
|
|
61
|
-
return
|
|
98
|
+
return (
|
|
99
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
100
|
+
typeof ch === 'string' && /(?:[\x2D0-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])/.test(ch)
|
|
101
|
+
);
|
|
62
102
|
};
|
|
63
103
|
|
|
64
104
|
// Detect whether the position sits mid-word: there is a word character
|
|
65
105
|
// on both sides of the position (or, for a non-empty range, on the
|
|
66
106
|
// outer side of each endpoint).
|
|
67
107
|
var isMidWord = function isMidWord(idx) {
|
|
68
|
-
return idx > 0 && idx <
|
|
108
|
+
return idx > 0 && idx < chars.length && isWordChar(chars[idx - 1]) && isWordChar(chars[idx]);
|
|
69
109
|
};
|
|
70
110
|
|
|
71
111
|
// For a zero-width range (pure insertion / deletion point), only expand
|
|
@@ -79,10 +119,10 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
79
119
|
};
|
|
80
120
|
}
|
|
81
121
|
// Expand both directions from the mid-word point.
|
|
82
|
-
while (fromIdx > 0 && isWordChar(
|
|
122
|
+
while (fromIdx > 0 && isWordChar(chars[fromIdx - 1])) {
|
|
83
123
|
fromIdx--;
|
|
84
124
|
}
|
|
85
|
-
while (toIdx <
|
|
125
|
+
while (toIdx < chars.length && isWordChar(chars[toIdx])) {
|
|
86
126
|
toIdx++;
|
|
87
127
|
}
|
|
88
128
|
return {
|
|
@@ -95,16 +135,16 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
95
135
|
|
|
96
136
|
// Expand left only if `from` is truly mid-word: the character at `from`
|
|
97
137
|
// (inside the range) and the character before `from` are both word chars.
|
|
98
|
-
if (fromIdx > 0 && fromIdx <
|
|
99
|
-
while (fromIdx > 0 && isWordChar(
|
|
138
|
+
if (fromIdx > 0 && fromIdx < chars.length && isWordChar(chars[fromIdx]) && isWordChar(chars[fromIdx - 1])) {
|
|
139
|
+
while (fromIdx > 0 && isWordChar(chars[fromIdx - 1])) {
|
|
100
140
|
fromIdx--;
|
|
101
141
|
}
|
|
102
142
|
}
|
|
103
143
|
|
|
104
144
|
// Expand right only if `to` is truly mid-word: the character just before
|
|
105
145
|
// `to` (last char of the range) and the character at `to` are both word chars.
|
|
106
|
-
if (toIdx > 0 && toIdx <
|
|
107
|
-
while (toIdx <
|
|
146
|
+
if (toIdx > 0 && toIdx < chars.length && isWordChar(chars[toIdx - 1]) && isWordChar(chars[toIdx])) {
|
|
147
|
+
while (toIdx < chars.length && isWordChar(chars[toIdx])) {
|
|
108
148
|
toIdx++;
|
|
109
149
|
}
|
|
110
150
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.2",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"atlaskit:src": "src/index.ts",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@atlaskit/adf-schema": "^52.
|
|
31
|
+
"@atlaskit/adf-schema": "^52.16.0",
|
|
32
32
|
"@atlaskit/custom-steps": "^0.17.0",
|
|
33
33
|
"@atlaskit/editor-plugin-analytics": "^11.0.0",
|
|
34
34
|
"@atlaskit/editor-plugin-expand": "^12.0.0",
|
|
35
35
|
"@atlaskit/editor-prosemirror": "^7.3.0",
|
|
36
36
|
"@atlaskit/editor-tables": "^2.10.0",
|
|
37
37
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
38
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
38
|
+
"@atlaskit/tmp-editor-statsig": "^89.0.0",
|
|
39
39
|
"@atlaskit/tokens": "^13.1.0",
|
|
40
40
|
"@babel/runtime": "^7.0.0",
|
|
41
41
|
"lodash": "^4.17.21",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"react-intl": "^6.6.2"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
|
-
"@atlaskit/editor-common": "^115.
|
|
62
|
+
"@atlaskit/editor-common": "^115.5.0",
|
|
63
63
|
"react": "^18.2.0"
|
|
64
64
|
},
|
|
65
65
|
"techstack": {
|