@atlaskit/editor-plugin-show-diff 9.0.1 → 9.0.3
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,23 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 9.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`9301f162e76d2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9301f162e76d2) -
|
|
8
|
+
EDITOR-7470: Fix mid-word punctuation in diffs splitting word boundaries.
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 9.0.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [`b3d1adf5a46c7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b3d1adf5a46c7) -
|
|
16
|
+
Fix word-boundary diff cutoff when a granular textblock diff runs inside a paragraph that contains
|
|
17
|
+
non-text inline nodes (hardBreak, mention, emoji, date, etc.). Previously the expansion logic
|
|
18
|
+
indexed into `parent.textContent`, which strips those nodes, so doc positions in the body could
|
|
19
|
+
land mid-word and pull untouched neighbouring words into the diff range.
|
|
20
|
+
|
|
3
21
|
## 9.0.1
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -20,15 +20,48 @@ 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.
|
|
26
56
|
*
|
|
27
|
-
* A "word character" is any
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
57
|
+
* A "word character" is any Unicode letter/number or underscore. Punctuation is
|
|
58
|
+
* treated as part of the same token only when it is sandwiched between two
|
|
59
|
+
* non-whitespace characters, so contractions like "You'll", accented words like
|
|
60
|
+
* "l'été", and punctuation-joined tokens like "deep-sea" or "foo/bar" stay
|
|
61
|
+
* intact without treating standalone punctuation as a general word character.
|
|
62
|
+
* Expansion stops at whitespace, standalone punctuation, the boundary of any
|
|
63
|
+
* non-text inline node (hardBreak, mention, emoji, date, etc.), or the
|
|
64
|
+
* textblock edges.
|
|
32
65
|
*
|
|
33
66
|
* If `from` and `to` resolve into different parent nodes, or if the
|
|
34
67
|
* parent is not a textblock, the range is returned unchanged.
|
|
@@ -55,24 +88,48 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
55
88
|
}
|
|
56
89
|
}
|
|
57
90
|
var parent = $from.parent;
|
|
58
|
-
var text = parent.textContent;
|
|
59
91
|
var parentStart = $from.start(); // absolute position of the first character in the textblock
|
|
60
92
|
|
|
61
|
-
//
|
|
93
|
+
// Per-offset view of the textblock so we don't conflate the inline
|
|
94
|
+
// positions of non-text nodes (hardBreak, mention, emoji, date, etc.)
|
|
95
|
+
// with the characters returned by `parent.textContent`.
|
|
96
|
+
var chars = buildCharsByOffset(parent);
|
|
97
|
+
|
|
98
|
+
// Convert absolute doc positions to zero-based content offsets.
|
|
62
99
|
var fromIdx = from - parentStart;
|
|
63
100
|
var toIdx = to - parentStart;
|
|
64
101
|
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
102
|
+
// Base word chars are Unicode letters/numbers/underscore. Punctuation only
|
|
103
|
+
// counts when it is surrounded by non-whitespace characters, e.g. in
|
|
104
|
+
// "You'll", "deep-sea", or "foo/bar". `null` still behaves like a hard
|
|
105
|
+
// boundary because only string neighbors qualify.
|
|
106
|
+
var isWordCharAt = function isWordCharAt(idx) {
|
|
107
|
+
if (idx < 0 || idx >= chars.length) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
var ch = chars[idx];
|
|
111
|
+
if (typeof ch !== 'string') {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
var prev = chars[idx - 1];
|
|
115
|
+
var next = chars[idx + 1];
|
|
116
|
+
return (
|
|
117
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
118
|
+
/(?:[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])/.test(ch) ||
|
|
119
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
120
|
+
/(?:[!-#%-\*,-\/:;\?@\[-\]_\{\}\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])/.test(ch) && typeof prev === 'string' && typeof next === 'string' &&
|
|
121
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
122
|
+
!/[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/.test(prev) &&
|
|
123
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
124
|
+
!/[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/.test(next)
|
|
125
|
+
);
|
|
69
126
|
};
|
|
70
127
|
|
|
71
128
|
// Detect whether the position sits mid-word: there is a word character
|
|
72
129
|
// on both sides of the position (or, for a non-empty range, on the
|
|
73
130
|
// outer side of each endpoint).
|
|
74
131
|
var isMidWord = function isMidWord(idx) {
|
|
75
|
-
return idx > 0 && idx <
|
|
132
|
+
return idx > 0 && idx < chars.length && isWordCharAt(idx - 1) && isWordCharAt(idx);
|
|
76
133
|
};
|
|
77
134
|
|
|
78
135
|
// For a zero-width range (pure insertion / deletion point), only expand
|
|
@@ -86,10 +143,10 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
86
143
|
};
|
|
87
144
|
}
|
|
88
145
|
// Expand both directions from the mid-word point.
|
|
89
|
-
while (fromIdx > 0 &&
|
|
146
|
+
while (fromIdx > 0 && isWordCharAt(fromIdx - 1)) {
|
|
90
147
|
fromIdx--;
|
|
91
148
|
}
|
|
92
|
-
while (toIdx <
|
|
149
|
+
while (toIdx < chars.length && isWordCharAt(toIdx)) {
|
|
93
150
|
toIdx++;
|
|
94
151
|
}
|
|
95
152
|
return {
|
|
@@ -102,16 +159,16 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
102
159
|
|
|
103
160
|
// Expand left only if `from` is truly mid-word: the character at `from`
|
|
104
161
|
// (inside the range) and the character before `from` are both word chars.
|
|
105
|
-
if (fromIdx > 0 && fromIdx <
|
|
106
|
-
while (fromIdx > 0 &&
|
|
162
|
+
if (fromIdx > 0 && fromIdx < chars.length && isWordCharAt(fromIdx) && isWordCharAt(fromIdx - 1)) {
|
|
163
|
+
while (fromIdx > 0 && isWordCharAt(fromIdx - 1)) {
|
|
107
164
|
fromIdx--;
|
|
108
165
|
}
|
|
109
166
|
}
|
|
110
167
|
|
|
111
168
|
// Expand right only if `to` is truly mid-word: the character just before
|
|
112
169
|
// `to` (last char of the range) and the character at `to` are both word chars.
|
|
113
|
-
if (toIdx > 0 && toIdx <
|
|
114
|
-
while (toIdx <
|
|
170
|
+
if (toIdx > 0 && toIdx < chars.length && isWordCharAt(toIdx - 1) && isWordCharAt(toIdx)) {
|
|
171
|
+
while (toIdx < chars.length && isWordCharAt(toIdx)) {
|
|
115
172
|
toIdx++;
|
|
116
173
|
}
|
|
117
174
|
}
|
|
@@ -4,15 +4,48 @@ 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.
|
|
10
40
|
*
|
|
11
|
-
* A "word character" is any
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
41
|
+
* A "word character" is any Unicode letter/number or underscore. Punctuation is
|
|
42
|
+
* treated as part of the same token only when it is sandwiched between two
|
|
43
|
+
* non-whitespace characters, so contractions like "You'll", accented words like
|
|
44
|
+
* "l'été", and punctuation-joined tokens like "deep-sea" or "foo/bar" stay
|
|
45
|
+
* intact without treating standalone punctuation as a general word character.
|
|
46
|
+
* Expansion stops at whitespace, standalone punctuation, the boundary of any
|
|
47
|
+
* non-text inline node (hardBreak, mention, emoji, date, etc.), or the
|
|
48
|
+
* textblock edges.
|
|
16
49
|
*
|
|
17
50
|
* If `from` and `to` resolve into different parent nodes, or if the
|
|
18
51
|
* parent is not a textblock, the range is returned unchanged.
|
|
@@ -39,21 +72,47 @@ const expandToWordBoundaries = (doc, from, to) => {
|
|
|
39
72
|
}
|
|
40
73
|
}
|
|
41
74
|
const parent = $from.parent;
|
|
42
|
-
const text = parent.textContent;
|
|
43
75
|
const parentStart = $from.start(); // absolute position of the first character in the textblock
|
|
44
76
|
|
|
45
|
-
//
|
|
77
|
+
// Per-offset view of the textblock so we don't conflate the inline
|
|
78
|
+
// positions of non-text nodes (hardBreak, mention, emoji, date, etc.)
|
|
79
|
+
// with the characters returned by `parent.textContent`.
|
|
80
|
+
const chars = buildCharsByOffset(parent);
|
|
81
|
+
|
|
82
|
+
// Convert absolute doc positions to zero-based content offsets.
|
|
46
83
|
let fromIdx = from - parentStart;
|
|
47
84
|
let toIdx = to - parentStart;
|
|
48
85
|
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
|
|
86
|
+
// Base word chars are Unicode letters/numbers/underscore. Punctuation only
|
|
87
|
+
// counts when it is surrounded by non-whitespace characters, e.g. in
|
|
88
|
+
// "You'll", "deep-sea", or "foo/bar". `null` still behaves like a hard
|
|
89
|
+
// boundary because only string neighbors qualify.
|
|
90
|
+
const isWordCharAt = idx => {
|
|
91
|
+
if (idx < 0 || idx >= chars.length) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
const ch = chars[idx];
|
|
95
|
+
if (typeof ch !== 'string') {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
const prev = chars[idx - 1];
|
|
99
|
+
const next = chars[idx + 1];
|
|
100
|
+
return (
|
|
101
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
102
|
+
/[\p{L}\p{N}_]/u.test(ch) ||
|
|
103
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
104
|
+
/\p{P}/u.test(ch) && typeof prev === 'string' && typeof next === 'string' &&
|
|
105
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
106
|
+
!/\s/u.test(prev) &&
|
|
107
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
108
|
+
!/\s/u.test(next)
|
|
109
|
+
);
|
|
110
|
+
};
|
|
52
111
|
|
|
53
112
|
// Detect whether the position sits mid-word: there is a word character
|
|
54
113
|
// on both sides of the position (or, for a non-empty range, on the
|
|
55
114
|
// outer side of each endpoint).
|
|
56
|
-
const isMidWord = idx => idx > 0 && idx <
|
|
115
|
+
const isMidWord = idx => idx > 0 && idx < chars.length && isWordCharAt(idx - 1) && isWordCharAt(idx);
|
|
57
116
|
|
|
58
117
|
// For a zero-width range (pure insertion / deletion point), only expand
|
|
59
118
|
// if the point is mid-word — i.e. both the char before and after are
|
|
@@ -66,10 +125,10 @@ const expandToWordBoundaries = (doc, from, to) => {
|
|
|
66
125
|
};
|
|
67
126
|
}
|
|
68
127
|
// Expand both directions from the mid-word point.
|
|
69
|
-
while (fromIdx > 0 &&
|
|
128
|
+
while (fromIdx > 0 && isWordCharAt(fromIdx - 1)) {
|
|
70
129
|
fromIdx--;
|
|
71
130
|
}
|
|
72
|
-
while (toIdx <
|
|
131
|
+
while (toIdx < chars.length && isWordCharAt(toIdx)) {
|
|
73
132
|
toIdx++;
|
|
74
133
|
}
|
|
75
134
|
return {
|
|
@@ -82,16 +141,16 @@ const expandToWordBoundaries = (doc, from, to) => {
|
|
|
82
141
|
|
|
83
142
|
// Expand left only if `from` is truly mid-word: the character at `from`
|
|
84
143
|
// (inside the range) and the character before `from` are both word chars.
|
|
85
|
-
if (fromIdx > 0 && fromIdx <
|
|
86
|
-
while (fromIdx > 0 &&
|
|
144
|
+
if (fromIdx > 0 && fromIdx < chars.length && isWordCharAt(fromIdx) && isWordCharAt(fromIdx - 1)) {
|
|
145
|
+
while (fromIdx > 0 && isWordCharAt(fromIdx - 1)) {
|
|
87
146
|
fromIdx--;
|
|
88
147
|
}
|
|
89
148
|
}
|
|
90
149
|
|
|
91
150
|
// Expand right only if `to` is truly mid-word: the character just before
|
|
92
151
|
// `to` (last char of the range) and the character at `to` are both word chars.
|
|
93
|
-
if (toIdx > 0 && toIdx <
|
|
94
|
-
while (toIdx <
|
|
152
|
+
if (toIdx > 0 && toIdx < chars.length && isWordCharAt(toIdx - 1) && isWordCharAt(toIdx)) {
|
|
153
|
+
while (toIdx < chars.length && isWordCharAt(toIdx)) {
|
|
95
154
|
toIdx++;
|
|
96
155
|
}
|
|
97
156
|
}
|
|
@@ -13,15 +13,48 @@ 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.
|
|
19
49
|
*
|
|
20
|
-
* A "word character" is any
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
50
|
+
* A "word character" is any Unicode letter/number or underscore. Punctuation is
|
|
51
|
+
* treated as part of the same token only when it is sandwiched between two
|
|
52
|
+
* non-whitespace characters, so contractions like "You'll", accented words like
|
|
53
|
+
* "l'été", and punctuation-joined tokens like "deep-sea" or "foo/bar" stay
|
|
54
|
+
* intact without treating standalone punctuation as a general word character.
|
|
55
|
+
* Expansion stops at whitespace, standalone punctuation, the boundary of any
|
|
56
|
+
* non-text inline node (hardBreak, mention, emoji, date, etc.), or the
|
|
57
|
+
* textblock edges.
|
|
25
58
|
*
|
|
26
59
|
* If `from` and `to` resolve into different parent nodes, or if the
|
|
27
60
|
* parent is not a textblock, the range is returned unchanged.
|
|
@@ -48,24 +81,48 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
48
81
|
}
|
|
49
82
|
}
|
|
50
83
|
var parent = $from.parent;
|
|
51
|
-
var text = parent.textContent;
|
|
52
84
|
var parentStart = $from.start(); // absolute position of the first character in the textblock
|
|
53
85
|
|
|
54
|
-
//
|
|
86
|
+
// Per-offset view of the textblock so we don't conflate the inline
|
|
87
|
+
// positions of non-text nodes (hardBreak, mention, emoji, date, etc.)
|
|
88
|
+
// with the characters returned by `parent.textContent`.
|
|
89
|
+
var chars = buildCharsByOffset(parent);
|
|
90
|
+
|
|
91
|
+
// Convert absolute doc positions to zero-based content offsets.
|
|
55
92
|
var fromIdx = from - parentStart;
|
|
56
93
|
var toIdx = to - parentStart;
|
|
57
94
|
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
95
|
+
// Base word chars are Unicode letters/numbers/underscore. Punctuation only
|
|
96
|
+
// counts when it is surrounded by non-whitespace characters, e.g. in
|
|
97
|
+
// "You'll", "deep-sea", or "foo/bar". `null` still behaves like a hard
|
|
98
|
+
// boundary because only string neighbors qualify.
|
|
99
|
+
var isWordCharAt = function isWordCharAt(idx) {
|
|
100
|
+
if (idx < 0 || idx >= chars.length) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
var ch = chars[idx];
|
|
104
|
+
if (typeof ch !== 'string') {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
var prev = chars[idx - 1];
|
|
108
|
+
var next = chars[idx + 1];
|
|
109
|
+
return (
|
|
110
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
111
|
+
/(?:[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])/.test(ch) ||
|
|
112
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
113
|
+
/(?:[!-#%-\*,-\/:;\?@\[-\]_\{\}\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])/.test(ch) && typeof prev === 'string' && typeof next === 'string' &&
|
|
114
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
115
|
+
!/[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/.test(prev) &&
|
|
116
|
+
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
117
|
+
!/[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/.test(next)
|
|
118
|
+
);
|
|
62
119
|
};
|
|
63
120
|
|
|
64
121
|
// Detect whether the position sits mid-word: there is a word character
|
|
65
122
|
// on both sides of the position (or, for a non-empty range, on the
|
|
66
123
|
// outer side of each endpoint).
|
|
67
124
|
var isMidWord = function isMidWord(idx) {
|
|
68
|
-
return idx > 0 && idx <
|
|
125
|
+
return idx > 0 && idx < chars.length && isWordCharAt(idx - 1) && isWordCharAt(idx);
|
|
69
126
|
};
|
|
70
127
|
|
|
71
128
|
// For a zero-width range (pure insertion / deletion point), only expand
|
|
@@ -79,10 +136,10 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
79
136
|
};
|
|
80
137
|
}
|
|
81
138
|
// Expand both directions from the mid-word point.
|
|
82
|
-
while (fromIdx > 0 &&
|
|
139
|
+
while (fromIdx > 0 && isWordCharAt(fromIdx - 1)) {
|
|
83
140
|
fromIdx--;
|
|
84
141
|
}
|
|
85
|
-
while (toIdx <
|
|
142
|
+
while (toIdx < chars.length && isWordCharAt(toIdx)) {
|
|
86
143
|
toIdx++;
|
|
87
144
|
}
|
|
88
145
|
return {
|
|
@@ -95,16 +152,16 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
|
|
|
95
152
|
|
|
96
153
|
// Expand left only if `from` is truly mid-word: the character at `from`
|
|
97
154
|
// (inside the range) and the character before `from` are both word chars.
|
|
98
|
-
if (fromIdx > 0 && fromIdx <
|
|
99
|
-
while (fromIdx > 0 &&
|
|
155
|
+
if (fromIdx > 0 && fromIdx < chars.length && isWordCharAt(fromIdx) && isWordCharAt(fromIdx - 1)) {
|
|
156
|
+
while (fromIdx > 0 && isWordCharAt(fromIdx - 1)) {
|
|
100
157
|
fromIdx--;
|
|
101
158
|
}
|
|
102
159
|
}
|
|
103
160
|
|
|
104
161
|
// Expand right only if `to` is truly mid-word: the character just before
|
|
105
162
|
// `to` (last char of the range) and the character at `to` are both word chars.
|
|
106
|
-
if (toIdx > 0 && toIdx <
|
|
107
|
-
while (toIdx <
|
|
163
|
+
if (toIdx > 0 && toIdx < chars.length && isWordCharAt(toIdx - 1) && isWordCharAt(toIdx)) {
|
|
164
|
+
while (toIdx < chars.length && isWordCharAt(toIdx)) {
|
|
108
165
|
toIdx++;
|
|
109
166
|
}
|
|
110
167
|
}
|
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.3",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -35,7 +35,7 @@
|
|
|
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": "^89.
|
|
38
|
+
"@atlaskit/tmp-editor-statsig": "^89.1.0",
|
|
39
39
|
"@atlaskit/tokens": "^13.1.0",
|
|
40
40
|
"@babel/runtime": "^7.0.0",
|
|
41
41
|
"lodash": "^4.17.21",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@atlaskit/adf-utils": "^19.32.0",
|
|
47
47
|
"@atlaskit/button": "^23.11.0",
|
|
48
48
|
"@atlaskit/css": "^0.19.0",
|
|
49
|
-
"@atlaskit/editor-core": "^220.
|
|
49
|
+
"@atlaskit/editor-core": "^220.1.0",
|
|
50
50
|
"@atlaskit/editor-json-transformer": "^8.33.0",
|
|
51
51
|
"@atlaskit/form": "^15.5.0",
|
|
52
52
|
"@atlaskit/primitives": "^19.0.0",
|
|
@@ -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.6.0",
|
|
63
63
|
"react": "^18.2.0"
|
|
64
64
|
},
|
|
65
65
|
"techstack": {
|