slate-vue3 0.0.37 → 0.0.39
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/README.md +1 -1
- package/dist/{index-CjnPdoJN.js → batch-dirty-paths-CZqHWmdq.js} +59 -33
- package/dist/core.js +96 -2616
- package/dist/create-editor-BP4gf1UN.js +2585 -0
- package/dist/dom.d.ts +4 -7
- package/dist/dom.js +44 -44
- package/dist/history.d.ts +3 -4
- package/dist/history.js +2 -2
- package/dist/{hotkeys-CFtX6lwM.js → hotkeys-1OnMQ7H6.js} +41 -41
- package/dist/hyperscript.d.ts +1753 -0
- package/dist/hyperscript.js +251 -0
- package/dist/index.d.ts +12 -24
- package/dist/index.js +3 -6
- package/package.json +7 -2
package/dist/core.js
CHANGED
|
@@ -1,2618 +1,98 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { O, q } from "./index-CjnPdoJN.js";
|
|
4
|
-
const PathRef = {
|
|
5
|
-
transform(ref, op) {
|
|
6
|
-
const { current, affinity } = ref;
|
|
7
|
-
if (current == null) {
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
const path2 = Path.transform(current, op, { affinity });
|
|
11
|
-
ref.current = path2;
|
|
12
|
-
if (path2 == null) {
|
|
13
|
-
ref.unref();
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
const PointRef = {
|
|
18
|
-
transform(ref, op) {
|
|
19
|
-
const { current, affinity } = ref;
|
|
20
|
-
if (current == null) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
const point2 = Point.transform(current, op, { affinity });
|
|
24
|
-
ref.current = point2;
|
|
25
|
-
if (point2 == null) {
|
|
26
|
-
ref.unref();
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
const RangeRef = {
|
|
31
|
-
transform(ref, op) {
|
|
32
|
-
const { current, affinity } = ref;
|
|
33
|
-
if (current == null) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
const path2 = Range.transform(current, op, { affinity });
|
|
37
|
-
ref.current = path2;
|
|
38
|
-
if (path2 == null) {
|
|
39
|
-
ref.unref();
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
const DIRTY_PATHS = new toRawWeakMap();
|
|
44
|
-
const DIRTY_PATH_KEYS = new toRawWeakMap();
|
|
45
|
-
const FLUSHING = new toRawWeakMap();
|
|
46
|
-
const NORMALIZING = new toRawWeakMap();
|
|
47
|
-
const PATH_REFS = new toRawWeakMap();
|
|
48
|
-
const POINT_REFS = new toRawWeakMap();
|
|
49
|
-
const RANGE_REFS = new toRawWeakMap();
|
|
50
|
-
const Location = {
|
|
51
|
-
isLocation(value) {
|
|
52
|
-
return Path.isPath(value) || Point.isPoint(value) || Range.isRange(value);
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
const Span = {
|
|
56
|
-
isSpan(value) {
|
|
57
|
-
return Array.isArray(value) && value.length === 2 && value.every(Path.isPath);
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const matchPath = (editor, path2) => {
|
|
61
|
-
const [node2] = Editor.node(editor, path2);
|
|
62
|
-
return (n) => n === node2;
|
|
63
|
-
};
|
|
64
|
-
const getCharacterDistance = (str, isRTL = false) => {
|
|
65
|
-
const isLTR = !isRTL;
|
|
66
|
-
const codepoints = isRTL ? codepointsIteratorRTL(str) : str;
|
|
67
|
-
let left = 0;
|
|
68
|
-
let right = 0;
|
|
69
|
-
let distance = 0;
|
|
70
|
-
let gb11 = null;
|
|
71
|
-
let gb12Or13 = null;
|
|
72
|
-
for (const char of codepoints) {
|
|
73
|
-
const code = char.codePointAt(0);
|
|
74
|
-
if (!code) break;
|
|
75
|
-
const type = getCodepointType(char, code);
|
|
76
|
-
[left, right] = isLTR ? [right, type] : [type, left];
|
|
77
|
-
if (intersects(
|
|
78
|
-
left,
|
|
79
|
-
2
|
|
80
|
-
/* ZWJ */
|
|
81
|
-
) && intersects(
|
|
82
|
-
right,
|
|
83
|
-
1024
|
|
84
|
-
/* ExtPict */
|
|
85
|
-
)) {
|
|
86
|
-
if (isLTR) {
|
|
87
|
-
gb11 = endsWithEmojiZWJ(str.substring(0, distance));
|
|
88
|
-
} else {
|
|
89
|
-
gb11 = endsWithEmojiZWJ(str.substring(0, str.length - distance));
|
|
90
|
-
}
|
|
91
|
-
if (!gb11) break;
|
|
92
|
-
}
|
|
93
|
-
if (intersects(
|
|
94
|
-
left,
|
|
95
|
-
4
|
|
96
|
-
/* RI */
|
|
97
|
-
) && intersects(
|
|
98
|
-
right,
|
|
99
|
-
4
|
|
100
|
-
/* RI */
|
|
101
|
-
)) {
|
|
102
|
-
if (gb12Or13 !== null) {
|
|
103
|
-
gb12Or13 = !gb12Or13;
|
|
104
|
-
} else {
|
|
105
|
-
if (isLTR) {
|
|
106
|
-
gb12Or13 = true;
|
|
107
|
-
} else {
|
|
108
|
-
gb12Or13 = endsWithOddNumberOfRIs(
|
|
109
|
-
str.substring(0, str.length - distance)
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
if (!gb12Or13) break;
|
|
114
|
-
}
|
|
115
|
-
if (left !== 0 && right !== 0 && isBoundaryPair(left, right)) {
|
|
116
|
-
break;
|
|
117
|
-
}
|
|
118
|
-
distance += char.length;
|
|
119
|
-
}
|
|
120
|
-
return distance || 1;
|
|
121
|
-
};
|
|
122
|
-
const SPACE = /\s/;
|
|
123
|
-
const PUNCTUATION = /[\u002B\u0021-\u0023\u0025-\u002A\u002C-\u002F\u003A\u003B\u003F\u0040\u005B-\u005D\u005F\u007B\u007D\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E3B\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\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]/;
|
|
124
|
-
const CHAMELEON = /['\u2018\u2019]/;
|
|
125
|
-
const getWordDistance = (text, isRTL = false) => {
|
|
126
|
-
let dist = 0;
|
|
127
|
-
let started = false;
|
|
128
|
-
while (text.length > 0) {
|
|
129
|
-
const charDist = getCharacterDistance(text, isRTL);
|
|
130
|
-
const [char, remaining] = splitByCharacterDistance(text, charDist, isRTL);
|
|
131
|
-
if (isWordCharacter(char, remaining, isRTL)) {
|
|
132
|
-
started = true;
|
|
133
|
-
dist += charDist;
|
|
134
|
-
} else if (!started) {
|
|
135
|
-
dist += charDist;
|
|
136
|
-
} else {
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
text = remaining;
|
|
140
|
-
}
|
|
141
|
-
return dist;
|
|
142
|
-
};
|
|
143
|
-
const splitByCharacterDistance = (str, dist, isRTL) => {
|
|
144
|
-
if (isRTL) {
|
|
145
|
-
const at = str.length - dist;
|
|
146
|
-
return [str.slice(at, str.length), str.slice(0, at)];
|
|
147
|
-
}
|
|
148
|
-
return [str.slice(0, dist), str.slice(dist)];
|
|
149
|
-
};
|
|
150
|
-
const isWordCharacter = (char, remaining, isRTL = false) => {
|
|
151
|
-
if (SPACE.test(char)) {
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
if (CHAMELEON.test(char)) {
|
|
155
|
-
const charDist = getCharacterDistance(remaining, isRTL);
|
|
156
|
-
const [nextChar, nextRemaining] = splitByCharacterDistance(
|
|
157
|
-
remaining,
|
|
158
|
-
charDist,
|
|
159
|
-
isRTL
|
|
160
|
-
);
|
|
161
|
-
if (isWordCharacter(nextChar, nextRemaining, isRTL)) {
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
if (PUNCTUATION.test(char)) {
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
return true;
|
|
169
|
-
};
|
|
170
|
-
const codepointsIteratorRTL = function* (str) {
|
|
171
|
-
const end2 = str.length - 1;
|
|
172
|
-
for (let i = 0; i < str.length; i++) {
|
|
173
|
-
const char1 = str.charAt(end2 - i);
|
|
174
|
-
if (isLowSurrogate(char1.charCodeAt(0))) {
|
|
175
|
-
const char2 = str.charAt(end2 - i - 1);
|
|
176
|
-
if (isHighSurrogate(char2.charCodeAt(0))) {
|
|
177
|
-
yield char2 + char1;
|
|
178
|
-
i++;
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
yield char1;
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
const isHighSurrogate = (charCode) => {
|
|
186
|
-
return charCode >= 55296 && charCode <= 56319;
|
|
187
|
-
};
|
|
188
|
-
const isLowSurrogate = (charCode) => {
|
|
189
|
-
return charCode >= 56320 && charCode <= 57343;
|
|
190
|
-
};
|
|
191
|
-
const reExtend = /^[\p{Gr_Ext}\p{EMod}]$/u;
|
|
192
|
-
const rePrepend = /^[\u0600-\u0605\u06DD\u070F\u0890-\u0891\u08E2\u0D4E\u{110BD}\u{110CD}\u{111C2}-\u{111C3}\u{1193F}\u{11941}\u{11A3A}\u{11A84}-\u{11A89}\u{11D46}]$/u;
|
|
193
|
-
const reSpacingMark = /^[\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E-\u094F\u0982-\u0983\u09BF-\u09C0\u09C7-\u09C8\u09CB-\u09CC\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB-\u0ACC\u0B02-\u0B03\u0B40\u0B47-\u0B48\u0B4B-\u0B4C\u0BBF\u0BC1-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0C01-\u0C03\u0C41-\u0C44\u0C82-\u0C83\u0CBE\u0CC0-\u0CC1\u0CC3-\u0CC4\u0CC7-\u0CC8\u0CCA-\u0CCB\u0D02-\u0D03\u0D3F-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D82-\u0D83\u0DD0-\u0DD1\u0DD8-\u0DDE\u0DF2-\u0DF3\u0E33\u0EB3\u0F3E-\u0F3F\u0F7F\u1031\u103B-\u103C\u1056-\u1057\u1084\u1715\u1734\u17B6\u17BE-\u17C5\u17C7-\u17C8\u1923-\u1926\u1929-\u192B\u1930-\u1931\u1933-\u1938\u1A19-\u1A1A\u1A55\u1A57\u1A6D-\u1A72\u1B04\u1B3B\u1B3D-\u1B41\u1B43-\u1B44\u1B82\u1BA1\u1BA6-\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1BF3\u1C24-\u1C2B\u1C34-\u1C35\u1CE1\u1CF7\uA823-\uA824\uA827\uA880-\uA881\uA8B4-\uA8C3\uA952-\uA953\uA983\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BE-\uA9C0\uAA2F-\uAA30\uAA33-\uAA34\uAA4D\uAAEB\uAAEE-\uAAEF\uAAF5\uABE3-\uABE4\uABE6-\uABE7\uABE9-\uABEA\uABEC\u{11000}\u{11002}\u{11082}\u{110B0}-\u{110B2}\u{110B7}-\u{110B8}\u{1112C}\u{11145}-\u{11146}\u{11182}\u{111B3}-\u{111B5}\u{111BF}-\u{111C0}\u{111CE}\u{1122C}-\u{1122E}\u{11232}-\u{11233}\u{11235}\u{112E0}-\u{112E2}\u{11302}-\u{11303}\u{1133F}\u{11341}-\u{11344}\u{11347}-\u{11348}\u{1134B}-\u{1134D}\u{11362}-\u{11363}\u{11435}-\u{11437}\u{11440}-\u{11441}\u{11445}\u{114B1}-\u{114B2}\u{114B9}\u{114BB}-\u{114BC}\u{114BE}\u{114C1}\u{115B0}-\u{115B1}\u{115B8}-\u{115BB}\u{115BE}\u{11630}-\u{11632}\u{1163B}-\u{1163C}\u{1163E}\u{116AC}\u{116AE}-\u{116AF}\u{116B6}\u{11726}\u{1182C}-\u{1182E}\u{11838}\u{11931}-\u{11935}\u{11937}-\u{11938}\u{1193D}\u{11940}\u{11942}\u{119D1}-\u{119D3}\u{119DC}-\u{119DF}\u{119E4}\u{11A39}\u{11A57}-\u{11A58}\u{11A97}\u{11C2F}\u{11C3E}\u{11CA9}\u{11CB1}\u{11CB4}\u{11D8A}-\u{11D8E}\u{11D93}-\u{11D94}\u{11D96}\u{11EF5}-\u{11EF6}\u{16F51}-\u{16F87}\u{16FF0}-\u{16FF1}\u{1D166}\u{1D16D}]$/u;
|
|
194
|
-
const reL = /^[\u1100-\u115F\uA960-\uA97C]$/u;
|
|
195
|
-
const reV = /^[\u1160-\u11A7\uD7B0-\uD7C6]$/u;
|
|
196
|
-
const reT = /^[\u11A8-\u11FF\uD7CB-\uD7FB]$/u;
|
|
197
|
-
const reLV = /^[\uAC00\uAC1C\uAC38\uAC54\uAC70\uAC8C\uACA8\uACC4\uACE0\uACFC\uAD18\uAD34\uAD50\uAD6C\uAD88\uADA4\uADC0\uADDC\uADF8\uAE14\uAE30\uAE4C\uAE68\uAE84\uAEA0\uAEBC\uAED8\uAEF4\uAF10\uAF2C\uAF48\uAF64\uAF80\uAF9C\uAFB8\uAFD4\uAFF0\uB00C\uB028\uB044\uB060\uB07C\uB098\uB0B4\uB0D0\uB0EC\uB108\uB124\uB140\uB15C\uB178\uB194\uB1B0\uB1CC\uB1E8\uB204\uB220\uB23C\uB258\uB274\uB290\uB2AC\uB2C8\uB2E4\uB300\uB31C\uB338\uB354\uB370\uB38C\uB3A8\uB3C4\uB3E0\uB3FC\uB418\uB434\uB450\uB46C\uB488\uB4A4\uB4C0\uB4DC\uB4F8\uB514\uB530\uB54C\uB568\uB584\uB5A0\uB5BC\uB5D8\uB5F4\uB610\uB62C\uB648\uB664\uB680\uB69C\uB6B8\uB6D4\uB6F0\uB70C\uB728\uB744\uB760\uB77C\uB798\uB7B4\uB7D0\uB7EC\uB808\uB824\uB840\uB85C\uB878\uB894\uB8B0\uB8CC\uB8E8\uB904\uB920\uB93C\uB958\uB974\uB990\uB9AC\uB9C8\uB9E4\uBA00\uBA1C\uBA38\uBA54\uBA70\uBA8C\uBAA8\uBAC4\uBAE0\uBAFC\uBB18\uBB34\uBB50\uBB6C\uBB88\uBBA4\uBBC0\uBBDC\uBBF8\uBC14\uBC30\uBC4C\uBC68\uBC84\uBCA0\uBCBC\uBCD8\uBCF4\uBD10\uBD2C\uBD48\uBD64\uBD80\uBD9C\uBDB8\uBDD4\uBDF0\uBE0C\uBE28\uBE44\uBE60\uBE7C\uBE98\uBEB4\uBED0\uBEEC\uBF08\uBF24\uBF40\uBF5C\uBF78\uBF94\uBFB0\uBFCC\uBFE8\uC004\uC020\uC03C\uC058\uC074\uC090\uC0AC\uC0C8\uC0E4\uC100\uC11C\uC138\uC154\uC170\uC18C\uC1A8\uC1C4\uC1E0\uC1FC\uC218\uC234\uC250\uC26C\uC288\uC2A4\uC2C0\uC2DC\uC2F8\uC314\uC330\uC34C\uC368\uC384\uC3A0\uC3BC\uC3D8\uC3F4\uC410\uC42C\uC448\uC464\uC480\uC49C\uC4B8\uC4D4\uC4F0\uC50C\uC528\uC544\uC560\uC57C\uC598\uC5B4\uC5D0\uC5EC\uC608\uC624\uC640\uC65C\uC678\uC694\uC6B0\uC6CC\uC6E8\uC704\uC720\uC73C\uC758\uC774\uC790\uC7AC\uC7C8\uC7E4\uC800\uC81C\uC838\uC854\uC870\uC88C\uC8A8\uC8C4\uC8E0\uC8FC\uC918\uC934\uC950\uC96C\uC988\uC9A4\uC9C0\uC9DC\uC9F8\uCA14\uCA30\uCA4C\uCA68\uCA84\uCAA0\uCABC\uCAD8\uCAF4\uCB10\uCB2C\uCB48\uCB64\uCB80\uCB9C\uCBB8\uCBD4\uCBF0\uCC0C\uCC28\uCC44\uCC60\uCC7C\uCC98\uCCB4\uCCD0\uCCEC\uCD08\uCD24\uCD40\uCD5C\uCD78\uCD94\uCDB0\uCDCC\uCDE8\uCE04\uCE20\uCE3C\uCE58\uCE74\uCE90\uCEAC\uCEC8\uCEE4\uCF00\uCF1C\uCF38\uCF54\uCF70\uCF8C\uCFA8\uCFC4\uCFE0\uCFFC\uD018\uD034\uD050\uD06C\uD088\uD0A4\uD0C0\uD0DC\uD0F8\uD114\uD130\uD14C\uD168\uD184\uD1A0\uD1BC\uD1D8\uD1F4\uD210\uD22C\uD248\uD264\uD280\uD29C\uD2B8\uD2D4\uD2F0\uD30C\uD328\uD344\uD360\uD37C\uD398\uD3B4\uD3D0\uD3EC\uD408\uD424\uD440\uD45C\uD478\uD494\uD4B0\uD4CC\uD4E8\uD504\uD520\uD53C\uD558\uD574\uD590\uD5AC\uD5C8\uD5E4\uD600\uD61C\uD638\uD654\uD670\uD68C\uD6A8\uD6C4\uD6E0\uD6FC\uD718\uD734\uD750\uD76C\uD788]$/u;
|
|
198
|
-
const reLVT = /^[\uAC01-\uAC1B\uAC1D-\uAC37\uAC39-\uAC53\uAC55-\uAC6F\uAC71-\uAC8B\uAC8D-\uACA7\uACA9-\uACC3\uACC5-\uACDF\uACE1-\uACFB\uACFD-\uAD17\uAD19-\uAD33\uAD35-\uAD4F\uAD51-\uAD6B\uAD6D-\uAD87\uAD89-\uADA3\uADA5-\uADBF\uADC1-\uADDB\uADDD-\uADF7\uADF9-\uAE13\uAE15-\uAE2F\uAE31-\uAE4B\uAE4D-\uAE67\uAE69-\uAE83\uAE85-\uAE9F\uAEA1-\uAEBB\uAEBD-\uAED7\uAED9-\uAEF3\uAEF5-\uAF0F\uAF11-\uAF2B\uAF2D-\uAF47\uAF49-\uAF63\uAF65-\uAF7F\uAF81-\uAF9B\uAF9D-\uAFB7\uAFB9-\uAFD3\uAFD5-\uAFEF\uAFF1-\uB00B\uB00D-\uB027\uB029-\uB043\uB045-\uB05F\uB061-\uB07B\uB07D-\uB097\uB099-\uB0B3\uB0B5-\uB0CF\uB0D1-\uB0EB\uB0ED-\uB107\uB109-\uB123\uB125-\uB13F\uB141-\uB15B\uB15D-\uB177\uB179-\uB193\uB195-\uB1AF\uB1B1-\uB1CB\uB1CD-\uB1E7\uB1E9-\uB203\uB205-\uB21F\uB221-\uB23B\uB23D-\uB257\uB259-\uB273\uB275-\uB28F\uB291-\uB2AB\uB2AD-\uB2C7\uB2C9-\uB2E3\uB2E5-\uB2FF\uB301-\uB31B\uB31D-\uB337\uB339-\uB353\uB355-\uB36F\uB371-\uB38B\uB38D-\uB3A7\uB3A9-\uB3C3\uB3C5-\uB3DF\uB3E1-\uB3FB\uB3FD-\uB417\uB419-\uB433\uB435-\uB44F\uB451-\uB46B\uB46D-\uB487\uB489-\uB4A3\uB4A5-\uB4BF\uB4C1-\uB4DB\uB4DD-\uB4F7\uB4F9-\uB513\uB515-\uB52F\uB531-\uB54B\uB54D-\uB567\uB569-\uB583\uB585-\uB59F\uB5A1-\uB5BB\uB5BD-\uB5D7\uB5D9-\uB5F3\uB5F5-\uB60F\uB611-\uB62B\uB62D-\uB647\uB649-\uB663\uB665-\uB67F\uB681-\uB69B\uB69D-\uB6B7\uB6B9-\uB6D3\uB6D5-\uB6EF\uB6F1-\uB70B\uB70D-\uB727\uB729-\uB743\uB745-\uB75F\uB761-\uB77B\uB77D-\uB797\uB799-\uB7B3\uB7B5-\uB7CF\uB7D1-\uB7EB\uB7ED-\uB807\uB809-\uB823\uB825-\uB83F\uB841-\uB85B\uB85D-\uB877\uB879-\uB893\uB895-\uB8AF\uB8B1-\uB8CB\uB8CD-\uB8E7\uB8E9-\uB903\uB905-\uB91F\uB921-\uB93B\uB93D-\uB957\uB959-\uB973\uB975-\uB98F\uB991-\uB9AB\uB9AD-\uB9C7\uB9C9-\uB9E3\uB9E5-\uB9FF\uBA01-\uBA1B\uBA1D-\uBA37\uBA39-\uBA53\uBA55-\uBA6F\uBA71-\uBA8B\uBA8D-\uBAA7\uBAA9-\uBAC3\uBAC5-\uBADF\uBAE1-\uBAFB\uBAFD-\uBB17\uBB19-\uBB33\uBB35-\uBB4F\uBB51-\uBB6B\uBB6D-\uBB87\uBB89-\uBBA3\uBBA5-\uBBBF\uBBC1-\uBBDB\uBBDD-\uBBF7\uBBF9-\uBC13\uBC15-\uBC2F\uBC31-\uBC4B\uBC4D-\uBC67\uBC69-\uBC83\uBC85-\uBC9F\uBCA1-\uBCBB\uBCBD-\uBCD7\uBCD9-\uBCF3\uBCF5-\uBD0F\uBD11-\uBD2B\uBD2D-\uBD47\uBD49-\uBD63\uBD65-\uBD7F\uBD81-\uBD9B\uBD9D-\uBDB7\uBDB9-\uBDD3\uBDD5-\uBDEF\uBDF1-\uBE0B\uBE0D-\uBE27\uBE29-\uBE43\uBE45-\uBE5F\uBE61-\uBE7B\uBE7D-\uBE97\uBE99-\uBEB3\uBEB5-\uBECF\uBED1-\uBEEB\uBEED-\uBF07\uBF09-\uBF23\uBF25-\uBF3F\uBF41-\uBF5B\uBF5D-\uBF77\uBF79-\uBF93\uBF95-\uBFAF\uBFB1-\uBFCB\uBFCD-\uBFE7\uBFE9-\uC003\uC005-\uC01F\uC021-\uC03B\uC03D-\uC057\uC059-\uC073\uC075-\uC08F\uC091-\uC0AB\uC0AD-\uC0C7\uC0C9-\uC0E3\uC0E5-\uC0FF\uC101-\uC11B\uC11D-\uC137\uC139-\uC153\uC155-\uC16F\uC171-\uC18B\uC18D-\uC1A7\uC1A9-\uC1C3\uC1C5-\uC1DF\uC1E1-\uC1FB\uC1FD-\uC217\uC219-\uC233\uC235-\uC24F\uC251-\uC26B\uC26D-\uC287\uC289-\uC2A3\uC2A5-\uC2BF\uC2C1-\uC2DB\uC2DD-\uC2F7\uC2F9-\uC313\uC315-\uC32F\uC331-\uC34B\uC34D-\uC367\uC369-\uC383\uC385-\uC39F\uC3A1-\uC3BB\uC3BD-\uC3D7\uC3D9-\uC3F3\uC3F5-\uC40F\uC411-\uC42B\uC42D-\uC447\uC449-\uC463\uC465-\uC47F\uC481-\uC49B\uC49D-\uC4B7\uC4B9-\uC4D3\uC4D5-\uC4EF\uC4F1-\uC50B\uC50D-\uC527\uC529-\uC543\uC545-\uC55F\uC561-\uC57B\uC57D-\uC597\uC599-\uC5B3\uC5B5-\uC5CF\uC5D1-\uC5EB\uC5ED-\uC607\uC609-\uC623\uC625-\uC63F\uC641-\uC65B\uC65D-\uC677\uC679-\uC693\uC695-\uC6AF\uC6B1-\uC6CB\uC6CD-\uC6E7\uC6E9-\uC703\uC705-\uC71F\uC721-\uC73B\uC73D-\uC757\uC759-\uC773\uC775-\uC78F\uC791-\uC7AB\uC7AD-\uC7C7\uC7C9-\uC7E3\uC7E5-\uC7FF\uC801-\uC81B\uC81D-\uC837\uC839-\uC853\uC855-\uC86F\uC871-\uC88B\uC88D-\uC8A7\uC8A9-\uC8C3\uC8C5-\uC8DF\uC8E1-\uC8FB\uC8FD-\uC917\uC919-\uC933\uC935-\uC94F\uC951-\uC96B\uC96D-\uC987\uC989-\uC9A3\uC9A5-\uC9BF\uC9C1-\uC9DB\uC9DD-\uC9F7\uC9F9-\uCA13\uCA15-\uCA2F\uCA31-\uCA4B\uCA4D-\uCA67\uCA69-\uCA83\uCA85-\uCA9F\uCAA1-\uCABB\uCABD-\uCAD7\uCAD9-\uCAF3\uCAF5-\uCB0F\uCB11-\uCB2B\uCB2D-\uCB47\uCB49-\uCB63\uCB65-\uCB7F\uCB81-\uCB9B\uCB9D-\uCBB7\uCBB9-\uCBD3\uCBD5-\uCBEF\uCBF1-\uCC0B\uCC0D-\uCC27\uCC29-\uCC43\uCC45-\uCC5F\uCC61-\uCC7B\uCC7D-\uCC97\uCC99-\uCCB3\uCCB5-\uCCCF\uCCD1-\uCCEB\uCCED-\uCD07\uCD09-\uCD23\uCD25-\uCD3F\uCD41-\uCD5B\uCD5D-\uCD77\uCD79-\uCD93\uCD95-\uCDAF\uCDB1-\uCDCB\uCDCD-\uCDE7\uCDE9-\uCE03\uCE05-\uCE1F\uCE21-\uCE3B\uCE3D-\uCE57\uCE59-\uCE73\uCE75-\uCE8F\uCE91-\uCEAB\uCEAD-\uCEC7\uCEC9-\uCEE3\uCEE5-\uCEFF\uCF01-\uCF1B\uCF1D-\uCF37\uCF39-\uCF53\uCF55-\uCF6F\uCF71-\uCF8B\uCF8D-\uCFA7\uCFA9-\uCFC3\uCFC5-\uCFDF\uCFE1-\uCFFB\uCFFD-\uD017\uD019-\uD033\uD035-\uD04F\uD051-\uD06B\uD06D-\uD087\uD089-\uD0A3\uD0A5-\uD0BF\uD0C1-\uD0DB\uD0DD-\uD0F7\uD0F9-\uD113\uD115-\uD12F\uD131-\uD14B\uD14D-\uD167\uD169-\uD183\uD185-\uD19F\uD1A1-\uD1BB\uD1BD-\uD1D7\uD1D9-\uD1F3\uD1F5-\uD20F\uD211-\uD22B\uD22D-\uD247\uD249-\uD263\uD265-\uD27F\uD281-\uD29B\uD29D-\uD2B7\uD2B9-\uD2D3\uD2D5-\uD2EF\uD2F1-\uD30B\uD30D-\uD327\uD329-\uD343\uD345-\uD35F\uD361-\uD37B\uD37D-\uD397\uD399-\uD3B3\uD3B5-\uD3CF\uD3D1-\uD3EB\uD3ED-\uD407\uD409-\uD423\uD425-\uD43F\uD441-\uD45B\uD45D-\uD477\uD479-\uD493\uD495-\uD4AF\uD4B1-\uD4CB\uD4CD-\uD4E7\uD4E9-\uD503\uD505-\uD51F\uD521-\uD53B\uD53D-\uD557\uD559-\uD573\uD575-\uD58F\uD591-\uD5AB\uD5AD-\uD5C7\uD5C9-\uD5E3\uD5E5-\uD5FF\uD601-\uD61B\uD61D-\uD637\uD639-\uD653\uD655-\uD66F\uD671-\uD68B\uD68D-\uD6A7\uD6A9-\uD6C3\uD6C5-\uD6DF\uD6E1-\uD6FB\uD6FD-\uD717\uD719-\uD733\uD735-\uD74F\uD751-\uD76B\uD76D-\uD787\uD789-\uD7A3]$/u;
|
|
199
|
-
const reExtPict = new RegExp("^\\p{ExtPict}$", "u");
|
|
200
|
-
const getCodepointType = (char, code) => {
|
|
201
|
-
let type = 2048;
|
|
202
|
-
if (char.search(reExtend) !== -1) {
|
|
203
|
-
type |= 1;
|
|
204
|
-
}
|
|
205
|
-
if (code === 8205) {
|
|
206
|
-
type |= 2;
|
|
207
|
-
}
|
|
208
|
-
if (code >= 127462 && code <= 127487) {
|
|
209
|
-
type |= 4;
|
|
210
|
-
}
|
|
211
|
-
if (char.search(rePrepend) !== -1) {
|
|
212
|
-
type |= 8;
|
|
213
|
-
}
|
|
214
|
-
if (char.search(reSpacingMark) !== -1) {
|
|
215
|
-
type |= 16;
|
|
216
|
-
}
|
|
217
|
-
if (char.search(reL) !== -1) {
|
|
218
|
-
type |= 32;
|
|
219
|
-
}
|
|
220
|
-
if (char.search(reV) !== -1) {
|
|
221
|
-
type |= 64;
|
|
222
|
-
}
|
|
223
|
-
if (char.search(reT) !== -1) {
|
|
224
|
-
type |= 128;
|
|
225
|
-
}
|
|
226
|
-
if (char.search(reLV) !== -1) {
|
|
227
|
-
type |= 256;
|
|
228
|
-
}
|
|
229
|
-
if (char.search(reLVT) !== -1) {
|
|
230
|
-
type |= 512;
|
|
231
|
-
}
|
|
232
|
-
if (char.search(reExtPict) !== -1) {
|
|
233
|
-
type |= 1024;
|
|
234
|
-
}
|
|
235
|
-
return type;
|
|
236
|
-
};
|
|
237
|
-
function intersects(x, y) {
|
|
238
|
-
return (x & y) !== 0;
|
|
239
|
-
}
|
|
240
|
-
const NonBoundaryPairs = [
|
|
241
|
-
// GB6
|
|
242
|
-
[
|
|
243
|
-
32,
|
|
244
|
-
32 | 64 | 256 | 512
|
|
245
|
-
/* LVT */
|
|
246
|
-
],
|
|
247
|
-
// GB7
|
|
248
|
-
[
|
|
249
|
-
256 | 64,
|
|
250
|
-
64 | 128
|
|
251
|
-
/* T */
|
|
252
|
-
],
|
|
253
|
-
// GB8
|
|
254
|
-
[
|
|
255
|
-
512 | 128,
|
|
256
|
-
128
|
|
257
|
-
/* T */
|
|
258
|
-
],
|
|
259
|
-
// GB9
|
|
260
|
-
[
|
|
261
|
-
2048,
|
|
262
|
-
1 | 2
|
|
263
|
-
/* ZWJ */
|
|
264
|
-
],
|
|
265
|
-
// GB9a
|
|
266
|
-
[
|
|
267
|
-
2048,
|
|
268
|
-
16
|
|
269
|
-
/* SpacingMark */
|
|
270
|
-
],
|
|
271
|
-
// GB9b
|
|
272
|
-
[
|
|
273
|
-
8,
|
|
274
|
-
2048
|
|
275
|
-
/* Any */
|
|
276
|
-
],
|
|
277
|
-
// GB11
|
|
278
|
-
[
|
|
279
|
-
2,
|
|
280
|
-
1024
|
|
281
|
-
/* ExtPict */
|
|
282
|
-
],
|
|
283
|
-
// GB12 and GB13
|
|
284
|
-
[
|
|
285
|
-
4,
|
|
286
|
-
4
|
|
287
|
-
/* RI */
|
|
288
|
-
]
|
|
289
|
-
];
|
|
290
|
-
function isBoundaryPair(left, right) {
|
|
291
|
-
return NonBoundaryPairs.findIndex(
|
|
292
|
-
(r) => intersects(left, r[0]) && intersects(right, r[1])
|
|
293
|
-
) === -1;
|
|
294
|
-
}
|
|
295
|
-
const endingEmojiZWJ = new RegExp("\\p{ExtPict}[\\p{Gr_Ext}\\p{EMod}]*\\u200D$", "u");
|
|
296
|
-
const endsWithEmojiZWJ = (str) => {
|
|
297
|
-
return str.search(endingEmojiZWJ) !== -1;
|
|
298
|
-
};
|
|
299
|
-
const endingRIs = new RegExp("\\p{RI}+$", "gu");
|
|
300
|
-
const endsWithOddNumberOfRIs = (str) => {
|
|
301
|
-
const match = str.match(endingRIs);
|
|
302
|
-
if (match === null) {
|
|
303
|
-
return false;
|
|
304
|
-
} else {
|
|
305
|
-
const numRIs = match[0].length / 2;
|
|
306
|
-
return numRIs % 2 === 1;
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
const BATCHING_DIRTY_PATHS = new toRawWeakMap();
|
|
310
|
-
const isBatchingDirtyPaths = (editor) => {
|
|
311
|
-
return BATCHING_DIRTY_PATHS.get(editor) || false;
|
|
312
|
-
};
|
|
313
|
-
const batchDirtyPaths = (editor, fn, update) => {
|
|
314
|
-
const value = BATCHING_DIRTY_PATHS.get(editor) || false;
|
|
315
|
-
BATCHING_DIRTY_PATHS.set(editor, true);
|
|
316
|
-
try {
|
|
317
|
-
fn();
|
|
318
|
-
update();
|
|
319
|
-
} finally {
|
|
320
|
-
BATCHING_DIRTY_PATHS.set(editor, value);
|
|
321
|
-
}
|
|
322
|
-
};
|
|
323
|
-
function updateDirtyPaths(editor, newDirtyPaths, transform) {
|
|
324
|
-
const oldDirtyPaths = DIRTY_PATHS.get(editor) || [];
|
|
325
|
-
const oldDirtyPathKeys = DIRTY_PATH_KEYS.get(editor) || /* @__PURE__ */ new Set();
|
|
326
|
-
let dirtyPaths;
|
|
327
|
-
let dirtyPathKeys;
|
|
328
|
-
const add = (path2) => {
|
|
329
|
-
if (path2) {
|
|
330
|
-
const key = path2.join(",");
|
|
331
|
-
if (!dirtyPathKeys.has(key)) {
|
|
332
|
-
dirtyPathKeys.add(key);
|
|
333
|
-
dirtyPaths.push(path2);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
};
|
|
337
|
-
if (transform) {
|
|
338
|
-
dirtyPaths = [];
|
|
339
|
-
dirtyPathKeys = /* @__PURE__ */ new Set();
|
|
340
|
-
for (const path2 of oldDirtyPaths) {
|
|
341
|
-
const newPath = transform(path2);
|
|
342
|
-
add(newPath);
|
|
343
|
-
}
|
|
344
|
-
} else {
|
|
345
|
-
dirtyPaths = oldDirtyPaths;
|
|
346
|
-
dirtyPathKeys = oldDirtyPathKeys;
|
|
347
|
-
}
|
|
348
|
-
for (const path2 of newDirtyPaths) {
|
|
349
|
-
add(path2);
|
|
350
|
-
}
|
|
351
|
-
DIRTY_PATHS.set(editor, dirtyPaths);
|
|
352
|
-
DIRTY_PATH_KEYS.set(editor, dirtyPathKeys);
|
|
353
|
-
}
|
|
354
|
-
const apply = (editor, op) => {
|
|
355
|
-
for (const ref of Editor.pathRefs(editor)) {
|
|
356
|
-
PathRef.transform(ref, op);
|
|
357
|
-
}
|
|
358
|
-
for (const ref of Editor.pointRefs(editor)) {
|
|
359
|
-
PointRef.transform(ref, op);
|
|
360
|
-
}
|
|
361
|
-
for (const ref of Editor.rangeRefs(editor)) {
|
|
362
|
-
RangeRef.transform(ref, op);
|
|
363
|
-
}
|
|
364
|
-
if (!isBatchingDirtyPaths(editor)) {
|
|
365
|
-
const transform = Path.operationCanTransformPath(op) ? (p) => Path.transform(p, op) : void 0;
|
|
366
|
-
updateDirtyPaths(editor, editor.getDirtyPaths(op), transform);
|
|
367
|
-
}
|
|
368
|
-
Transforms.transform(editor, op);
|
|
369
|
-
editor.operations.push(op);
|
|
370
|
-
Editor.normalize(editor, {
|
|
371
|
-
operation: op
|
|
372
|
-
});
|
|
373
|
-
if (op.type === "set_selection") {
|
|
374
|
-
editor.marks = null;
|
|
375
|
-
}
|
|
376
|
-
if (!FLUSHING.get(editor)) {
|
|
377
|
-
FLUSHING.set(editor, true);
|
|
378
|
-
Promise.resolve().then(() => {
|
|
379
|
-
FLUSHING.set(editor, false);
|
|
380
|
-
editor.onChange({ operation: op });
|
|
381
|
-
editor.operations = [];
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
|
-
};
|
|
385
|
-
const getDirtyPaths = (editor, op) => {
|
|
386
|
-
switch (op.type) {
|
|
387
|
-
case "insert_text":
|
|
388
|
-
case "remove_text":
|
|
389
|
-
case "set_node": {
|
|
390
|
-
const { path: path2 } = op;
|
|
391
|
-
return Path.levels(path2);
|
|
392
|
-
}
|
|
393
|
-
case "insert_node": {
|
|
394
|
-
const { node: node2, path: path2 } = op;
|
|
395
|
-
const levels2 = Path.levels(path2);
|
|
396
|
-
const descendants = Text.isText(node2) ? [] : Array.from(Node.nodes(node2), ([, p]) => path2.concat(p));
|
|
397
|
-
return [...levels2, ...descendants];
|
|
398
|
-
}
|
|
399
|
-
case "merge_node": {
|
|
400
|
-
const { path: path2 } = op;
|
|
401
|
-
const ancestors = Path.ancestors(path2);
|
|
402
|
-
const previousPath = Path.previous(path2);
|
|
403
|
-
return [...ancestors, previousPath];
|
|
404
|
-
}
|
|
405
|
-
case "move_node": {
|
|
406
|
-
const { path: path2, newPath } = op;
|
|
407
|
-
if (Path.equals(path2, newPath)) {
|
|
408
|
-
return [];
|
|
409
|
-
}
|
|
410
|
-
const oldAncestors = [];
|
|
411
|
-
const newAncestors = [];
|
|
412
|
-
for (const ancestor of Path.ancestors(path2)) {
|
|
413
|
-
const p = Path.transform(ancestor, op);
|
|
414
|
-
oldAncestors.push(p);
|
|
415
|
-
}
|
|
416
|
-
for (const ancestor of Path.ancestors(newPath)) {
|
|
417
|
-
const p = Path.transform(ancestor, op);
|
|
418
|
-
newAncestors.push(p);
|
|
419
|
-
}
|
|
420
|
-
const newParent = newAncestors[newAncestors.length - 1];
|
|
421
|
-
const newIndex = newPath[newPath.length - 1];
|
|
422
|
-
const resultPath = newParent.concat(newIndex);
|
|
423
|
-
return [...oldAncestors, ...newAncestors, resultPath];
|
|
424
|
-
}
|
|
425
|
-
case "remove_node": {
|
|
426
|
-
const { path: path2 } = op;
|
|
427
|
-
const ancestors = Path.ancestors(path2);
|
|
428
|
-
return [...ancestors];
|
|
429
|
-
}
|
|
430
|
-
case "split_node": {
|
|
431
|
-
const { path: path2 } = op;
|
|
432
|
-
const levels2 = Path.levels(path2);
|
|
433
|
-
const nextPath = Path.next(path2);
|
|
434
|
-
return [...levels2, nextPath];
|
|
435
|
-
}
|
|
436
|
-
default: {
|
|
437
|
-
return [];
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
const getFragment = (editor) => {
|
|
442
|
-
const { selection } = editor;
|
|
443
|
-
if (selection) {
|
|
444
|
-
return Node.fragment(editor, selection);
|
|
445
|
-
}
|
|
446
|
-
return [];
|
|
447
|
-
};
|
|
448
|
-
const normalizeNode = (editor, entry) => {
|
|
449
|
-
const [node2, path2] = entry;
|
|
450
|
-
if (Text.isText(node2)) {
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
if (Element.isElement(node2) && node2.children.length === 0) {
|
|
454
|
-
const child = { text: "" };
|
|
455
|
-
Transforms.insertNodes(editor, child, {
|
|
456
|
-
at: path2.concat(0),
|
|
457
|
-
voids: true
|
|
458
|
-
});
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
const shouldHaveInlines = Editor.isEditor(node2) ? false : Element.isElement(node2) && (editor.isInline(node2) || node2.children.length === 0 || Text.isText(node2.children[0]) || editor.isInline(node2.children[0]));
|
|
462
|
-
let n = 0;
|
|
463
|
-
for (let i = 0; i < node2.children.length; i++, n++) {
|
|
464
|
-
const currentNode = Node.get(editor, path2);
|
|
465
|
-
if (Text.isText(currentNode)) continue;
|
|
466
|
-
const child = currentNode.children[n];
|
|
467
|
-
if (child === void 0) continue;
|
|
468
|
-
const prev = currentNode.children[n - 1];
|
|
469
|
-
const isLast = i === node2.children.length - 1;
|
|
470
|
-
const isInlineOrText = Text.isText(child) || Element.isElement(child) && editor.isInline(child);
|
|
471
|
-
if (isInlineOrText !== shouldHaveInlines) {
|
|
472
|
-
if (isInlineOrText) {
|
|
473
|
-
Transforms.removeNodes(editor, { at: path2.concat(n), voids: true });
|
|
474
|
-
} else {
|
|
475
|
-
Transforms.unwrapNodes(editor, { at: path2.concat(n), voids: true });
|
|
476
|
-
}
|
|
477
|
-
n--;
|
|
478
|
-
} else if (Element.isElement(child)) {
|
|
479
|
-
if (editor.isInline(child)) {
|
|
480
|
-
if (prev == null || !Text.isText(prev)) {
|
|
481
|
-
const newChild = { text: "" };
|
|
482
|
-
Transforms.insertNodes(editor, newChild, {
|
|
483
|
-
at: path2.concat(n),
|
|
484
|
-
voids: true
|
|
485
|
-
});
|
|
486
|
-
n++;
|
|
487
|
-
} else if (isLast) {
|
|
488
|
-
const newChild = { text: "" };
|
|
489
|
-
Transforms.insertNodes(editor, newChild, {
|
|
490
|
-
at: path2.concat(n + 1),
|
|
491
|
-
voids: true
|
|
492
|
-
});
|
|
493
|
-
n++;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
} else {
|
|
497
|
-
if (!Text.isText(child) && !("children" in child)) {
|
|
498
|
-
const elementChild = child;
|
|
499
|
-
elementChild.children = [];
|
|
500
|
-
}
|
|
501
|
-
if (prev != null && Text.isText(prev)) {
|
|
502
|
-
if (Text.equals(child, prev, { loose: true })) {
|
|
503
|
-
Transforms.mergeNodes(editor, { at: path2.concat(n), voids: true });
|
|
504
|
-
n--;
|
|
505
|
-
} else if (prev.text === "") {
|
|
506
|
-
Transforms.removeNodes(editor, {
|
|
507
|
-
at: path2.concat(n - 1),
|
|
508
|
-
voids: true
|
|
509
|
-
});
|
|
510
|
-
n--;
|
|
511
|
-
} else if (child.text === "") {
|
|
512
|
-
Transforms.removeNodes(editor, {
|
|
513
|
-
at: path2.concat(n),
|
|
514
|
-
voids: true
|
|
515
|
-
});
|
|
516
|
-
n--;
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
};
|
|
522
|
-
const shouldNormalize = (editor, { iteration, initialDirtyPathsLength }) => {
|
|
523
|
-
const maxIterations = initialDirtyPathsLength * 42;
|
|
524
|
-
if (iteration > maxIterations) {
|
|
525
|
-
throw new Error(
|
|
526
|
-
`Could not completely normalize the editor after ${maxIterations} iterations! This is usually due to incorrect normalization logic that leaves a node in an invalid state.`
|
|
527
|
-
);
|
|
528
|
-
}
|
|
529
|
-
return true;
|
|
530
|
-
};
|
|
531
|
-
const above = (editor, options = {}) => {
|
|
532
|
-
const {
|
|
533
|
-
voids = false,
|
|
534
|
-
mode = "lowest",
|
|
535
|
-
at = editor.selection,
|
|
536
|
-
match
|
|
537
|
-
} = options;
|
|
538
|
-
if (!at) {
|
|
539
|
-
return;
|
|
540
|
-
}
|
|
541
|
-
const path2 = Editor.path(editor, at);
|
|
542
|
-
const reverse = mode === "lowest";
|
|
543
|
-
for (const [n, p] of Editor.levels(editor, {
|
|
544
|
-
at: path2,
|
|
545
|
-
voids,
|
|
546
|
-
match,
|
|
547
|
-
reverse
|
|
548
|
-
})) {
|
|
549
|
-
if (Text.isText(n)) continue;
|
|
550
|
-
if (Range.isRange(at)) {
|
|
551
|
-
if (Path.isAncestor(p, at.anchor.path) && Path.isAncestor(p, at.focus.path)) {
|
|
552
|
-
return [n, p];
|
|
553
|
-
}
|
|
554
|
-
} else {
|
|
555
|
-
if (!Path.equals(path2, p)) {
|
|
556
|
-
return [n, p];
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
};
|
|
561
|
-
const addMark = (editor, key, value) => {
|
|
562
|
-
const { selection } = editor;
|
|
563
|
-
if (selection) {
|
|
564
|
-
const match = (node2, path2) => {
|
|
565
|
-
if (!Text.isText(node2)) {
|
|
566
|
-
return false;
|
|
567
|
-
}
|
|
568
|
-
const [parentNode, parentPath] = Editor.parent(editor, path2);
|
|
569
|
-
return !editor.isVoid(parentNode) || editor.markableVoid(parentNode);
|
|
570
|
-
};
|
|
571
|
-
const expandedSelection = Range.isExpanded(selection);
|
|
572
|
-
let markAcceptingVoidSelected = false;
|
|
573
|
-
if (!expandedSelection) {
|
|
574
|
-
const [selectedNode, selectedPath] = Editor.node(editor, selection);
|
|
575
|
-
if (selectedNode && match(selectedNode, selectedPath)) {
|
|
576
|
-
const [parentNode] = Editor.parent(editor, selectedPath);
|
|
577
|
-
markAcceptingVoidSelected = parentNode && editor.markableVoid(parentNode);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
if (expandedSelection || markAcceptingVoidSelected) {
|
|
581
|
-
Transforms.setNodes(
|
|
582
|
-
editor,
|
|
583
|
-
{ [key]: value },
|
|
584
|
-
{
|
|
585
|
-
match,
|
|
586
|
-
split: true,
|
|
587
|
-
voids: true
|
|
588
|
-
}
|
|
589
|
-
);
|
|
590
|
-
} else {
|
|
591
|
-
const marks2 = {
|
|
592
|
-
...Editor.marks(editor) || {},
|
|
593
|
-
[key]: value
|
|
594
|
-
};
|
|
595
|
-
editor.marks = marks2;
|
|
596
|
-
if (!FLUSHING.get(editor)) {
|
|
597
|
-
editor.onChange();
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
};
|
|
602
|
-
const after = (editor, at, options = {}) => {
|
|
603
|
-
const anchor = Editor.point(editor, at, { edge: "end" });
|
|
604
|
-
const focus = Editor.end(editor, []);
|
|
605
|
-
const range2 = { anchor, focus };
|
|
606
|
-
const { distance = 1 } = options;
|
|
607
|
-
let d = 0;
|
|
608
|
-
let target;
|
|
609
|
-
for (const p of Editor.positions(editor, {
|
|
610
|
-
...options,
|
|
611
|
-
at: range2
|
|
612
|
-
})) {
|
|
613
|
-
if (d > distance) {
|
|
614
|
-
break;
|
|
615
|
-
}
|
|
616
|
-
if (d !== 0) {
|
|
617
|
-
target = p;
|
|
618
|
-
}
|
|
619
|
-
d++;
|
|
620
|
-
}
|
|
621
|
-
return target;
|
|
622
|
-
};
|
|
623
|
-
const before = (editor, at, options = {}) => {
|
|
624
|
-
const anchor = Editor.start(editor, []);
|
|
625
|
-
const focus = Editor.point(editor, at, { edge: "start" });
|
|
626
|
-
const range2 = { anchor, focus };
|
|
627
|
-
const { distance = 1 } = options;
|
|
628
|
-
let d = 0;
|
|
629
|
-
let target;
|
|
630
|
-
for (const p of Editor.positions(editor, {
|
|
631
|
-
...options,
|
|
632
|
-
at: range2,
|
|
633
|
-
reverse: true
|
|
634
|
-
})) {
|
|
635
|
-
if (d > distance) {
|
|
636
|
-
break;
|
|
637
|
-
}
|
|
638
|
-
if (d !== 0) {
|
|
639
|
-
target = p;
|
|
640
|
-
}
|
|
641
|
-
d++;
|
|
642
|
-
}
|
|
643
|
-
return target;
|
|
644
|
-
};
|
|
645
|
-
const deleteBackward = (editor, unit) => {
|
|
646
|
-
const { selection } = editor;
|
|
647
|
-
if (selection && Range.isCollapsed(selection)) {
|
|
648
|
-
Transforms.delete(editor, { unit, reverse: true });
|
|
649
|
-
}
|
|
650
|
-
};
|
|
651
|
-
const deleteForward = (editor, unit) => {
|
|
652
|
-
const { selection } = editor;
|
|
653
|
-
if (selection && Range.isCollapsed(selection)) {
|
|
654
|
-
Transforms.delete(editor, { unit });
|
|
655
|
-
}
|
|
656
|
-
};
|
|
657
|
-
const deleteFragment = (editor, { direction = "forward" } = {}) => {
|
|
658
|
-
const { selection } = editor;
|
|
659
|
-
if (selection && Range.isExpanded(selection)) {
|
|
660
|
-
Transforms.delete(editor, { reverse: direction === "backward" });
|
|
661
|
-
}
|
|
662
|
-
};
|
|
663
|
-
const edges = (editor, at) => {
|
|
664
|
-
return [Editor.start(editor, at), Editor.end(editor, at)];
|
|
665
|
-
};
|
|
666
|
-
const elementReadOnly = (editor, options = {}) => {
|
|
667
|
-
return Editor.above(editor, {
|
|
668
|
-
...options,
|
|
669
|
-
match: (n) => Element.isElement(n) && Editor.isElementReadOnly(editor, n)
|
|
670
|
-
});
|
|
671
|
-
};
|
|
672
|
-
const end = (editor, at) => {
|
|
673
|
-
return Editor.point(editor, at, { edge: "end" });
|
|
674
|
-
};
|
|
675
|
-
const first = (editor, at) => {
|
|
676
|
-
const path2 = Editor.path(editor, at, { edge: "start" });
|
|
677
|
-
return Editor.node(editor, path2);
|
|
678
|
-
};
|
|
679
|
-
const fragment = (editor, at) => {
|
|
680
|
-
const range2 = Editor.range(editor, at);
|
|
681
|
-
return Node.fragment(editor, range2);
|
|
682
|
-
};
|
|
683
|
-
const getVoid = (editor, options = {}) => {
|
|
684
|
-
return Editor.above(editor, {
|
|
685
|
-
...options,
|
|
686
|
-
match: (n) => Element.isElement(n) && Editor.isVoid(editor, n)
|
|
687
|
-
});
|
|
688
|
-
};
|
|
689
|
-
const hasBlocks = (editor, element) => {
|
|
690
|
-
return element.children.some(
|
|
691
|
-
(n) => Element.isElement(n) && Editor.isBlock(editor, n)
|
|
692
|
-
);
|
|
693
|
-
};
|
|
694
|
-
const hasInlines = (editor, element) => {
|
|
695
|
-
return element.children.some(
|
|
696
|
-
(n) => Text.isText(n) || Editor.isInline(editor, n)
|
|
697
|
-
);
|
|
698
|
-
};
|
|
699
|
-
const hasPath = (editor, path2) => {
|
|
700
|
-
return Node.has(editor, path2);
|
|
701
|
-
};
|
|
702
|
-
const hasTexts = (editor, element) => {
|
|
703
|
-
return element.children.every((n) => Text.isText(n));
|
|
704
|
-
};
|
|
705
|
-
const insertBreak = (editor) => {
|
|
706
|
-
Transforms.splitNodes(editor, { always: true });
|
|
707
|
-
};
|
|
708
|
-
const insertNode = (editor, node2, options) => {
|
|
709
|
-
Transforms.insertNodes(editor, node2, options);
|
|
710
|
-
};
|
|
711
|
-
const insertSoftBreak = (editor) => {
|
|
712
|
-
Transforms.splitNodes(editor, { always: true });
|
|
713
|
-
};
|
|
714
|
-
const insertText = (editor, text, options = {}) => {
|
|
715
|
-
const { selection, marks: marks2 } = editor;
|
|
716
|
-
if (selection) {
|
|
717
|
-
if (marks2) {
|
|
718
|
-
const node2 = { text, ...marks2 };
|
|
719
|
-
Transforms.insertNodes(editor, node2, {
|
|
720
|
-
at: options.at,
|
|
721
|
-
voids: options.voids
|
|
722
|
-
});
|
|
723
|
-
} else {
|
|
724
|
-
Transforms.insertText(editor, text, options);
|
|
725
|
-
}
|
|
726
|
-
editor.marks = null;
|
|
727
|
-
}
|
|
728
|
-
};
|
|
729
|
-
const isBlock = (editor, value) => {
|
|
730
|
-
return !editor.isInline(value);
|
|
731
|
-
};
|
|
732
|
-
const isEdge = (editor, point2, at) => {
|
|
733
|
-
return Editor.isStart(editor, point2, at) || Editor.isEnd(editor, point2, at);
|
|
734
|
-
};
|
|
735
|
-
const isEmpty = (editor, element) => {
|
|
736
|
-
const { children } = element;
|
|
737
|
-
const [first2] = children;
|
|
738
|
-
return children.length === 0 || children.length === 1 && Text.isText(first2) && first2.text === "" && !editor.isVoid(element);
|
|
739
|
-
};
|
|
740
|
-
const isEnd = (editor, point2, at) => {
|
|
741
|
-
const end2 = Editor.end(editor, at);
|
|
742
|
-
return Point.equals(point2, end2);
|
|
743
|
-
};
|
|
744
|
-
const isNormalizing = (editor) => {
|
|
745
|
-
const isNormalizing2 = NORMALIZING.get(editor);
|
|
746
|
-
return isNormalizing2 === void 0 ? true : isNormalizing2;
|
|
747
|
-
};
|
|
748
|
-
const isStart = (editor, point2, at) => {
|
|
749
|
-
if (point2.offset !== 0) {
|
|
750
|
-
return false;
|
|
751
|
-
}
|
|
752
|
-
const start2 = Editor.start(editor, at);
|
|
753
|
-
return Point.equals(point2, start2);
|
|
754
|
-
};
|
|
755
|
-
const last = (editor, at) => {
|
|
756
|
-
const path2 = Editor.path(editor, at, { edge: "end" });
|
|
757
|
-
return Editor.node(editor, path2);
|
|
758
|
-
};
|
|
759
|
-
const leaf = (editor, at, options = {}) => {
|
|
760
|
-
const path2 = Editor.path(editor, at, options);
|
|
761
|
-
const node2 = Node.leaf(editor, path2);
|
|
762
|
-
return [node2, path2];
|
|
763
|
-
};
|
|
764
|
-
function* levels(editor, options = {}) {
|
|
765
|
-
const { at = editor.selection, reverse = false, voids = false } = options;
|
|
766
|
-
let { match } = options;
|
|
767
|
-
if (match == null) {
|
|
768
|
-
match = () => true;
|
|
769
|
-
}
|
|
770
|
-
if (!at) {
|
|
771
|
-
return;
|
|
772
|
-
}
|
|
773
|
-
const levels2 = [];
|
|
774
|
-
const path2 = Editor.path(editor, at);
|
|
775
|
-
for (const [n, p] of Node.levels(editor, path2)) {
|
|
776
|
-
if (!match(n, p)) {
|
|
777
|
-
continue;
|
|
778
|
-
}
|
|
779
|
-
levels2.push([n, p]);
|
|
780
|
-
if (!voids && Element.isElement(n) && Editor.isVoid(editor, n)) {
|
|
781
|
-
break;
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
if (reverse) {
|
|
785
|
-
levels2.reverse();
|
|
786
|
-
}
|
|
787
|
-
yield* levels2;
|
|
788
|
-
}
|
|
789
|
-
const marks = (editor, options = {}) => {
|
|
790
|
-
const { marks: marks2, selection } = editor;
|
|
791
|
-
if (!selection) {
|
|
792
|
-
return null;
|
|
793
|
-
}
|
|
794
|
-
let { anchor, focus } = selection;
|
|
795
|
-
if (marks2) {
|
|
796
|
-
return marks2;
|
|
797
|
-
}
|
|
798
|
-
if (Range.isExpanded(selection)) {
|
|
799
|
-
const isBackward = Range.isBackward(selection);
|
|
800
|
-
if (isBackward) {
|
|
801
|
-
[focus, anchor] = [anchor, focus];
|
|
802
|
-
}
|
|
803
|
-
const isEnd2 = Editor.isEnd(editor, anchor, anchor.path);
|
|
804
|
-
if (isEnd2) {
|
|
805
|
-
const after2 = Editor.after(editor, anchor);
|
|
806
|
-
if (after2) {
|
|
807
|
-
anchor = after2;
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
const [match] = Editor.nodes(editor, {
|
|
811
|
-
match: Text.isText,
|
|
812
|
-
at: {
|
|
813
|
-
anchor,
|
|
814
|
-
focus
|
|
815
|
-
}
|
|
816
|
-
});
|
|
817
|
-
if (match) {
|
|
818
|
-
const [node22] = match;
|
|
819
|
-
const { text: text2, ...rest2 } = node22;
|
|
820
|
-
return rest2;
|
|
821
|
-
} else {
|
|
822
|
-
return {};
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
const { path: path2 } = anchor;
|
|
826
|
-
let [node2] = Editor.leaf(editor, path2);
|
|
827
|
-
if (anchor.offset === 0) {
|
|
828
|
-
const prev = Editor.previous(editor, { at: path2, match: Text.isText });
|
|
829
|
-
const markedVoid = Editor.above(editor, {
|
|
830
|
-
match: (n) => Element.isElement(n) && Editor.isVoid(editor, n) && editor.markableVoid(n)
|
|
831
|
-
});
|
|
832
|
-
if (!markedVoid) {
|
|
833
|
-
const block = Editor.above(editor, {
|
|
834
|
-
match: (n) => Element.isElement(n) && Editor.isBlock(editor, n)
|
|
835
|
-
});
|
|
836
|
-
if (prev && block) {
|
|
837
|
-
const [prevNode, prevPath] = prev;
|
|
838
|
-
const [, blockPath] = block;
|
|
839
|
-
if (Path.isAncestor(blockPath, prevPath)) {
|
|
840
|
-
node2 = prevNode;
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
const { text, ...rest } = node2;
|
|
846
|
-
return rest;
|
|
847
|
-
};
|
|
848
|
-
const next = (editor, options = {}) => {
|
|
849
|
-
const { mode = "lowest", voids = false } = options;
|
|
850
|
-
let { match, at = editor.selection } = options;
|
|
851
|
-
if (!at) {
|
|
852
|
-
return;
|
|
853
|
-
}
|
|
854
|
-
const pointAfterLocation = Editor.after(editor, at, { voids });
|
|
855
|
-
if (!pointAfterLocation) return;
|
|
856
|
-
const [, to] = Editor.last(editor, []);
|
|
857
|
-
const span = [pointAfterLocation.path, to];
|
|
858
|
-
if (Path.isPath(at) && at.length === 0) {
|
|
859
|
-
throw new Error(`Cannot get the next node from the root node!`);
|
|
860
|
-
}
|
|
861
|
-
if (match == null) {
|
|
862
|
-
if (Path.isPath(at)) {
|
|
863
|
-
const [parent2] = Editor.parent(editor, at);
|
|
864
|
-
match = (n) => parent2.children.includes(n);
|
|
865
|
-
} else {
|
|
866
|
-
match = () => true;
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
const [next2] = Editor.nodes(editor, { at: span, match, mode, voids });
|
|
870
|
-
return next2;
|
|
871
|
-
};
|
|
872
|
-
const node = (editor, at, options = {}) => {
|
|
873
|
-
const path2 = Editor.path(editor, at, options);
|
|
874
|
-
const node2 = Node.get(editor, path2);
|
|
875
|
-
return [node2, path2];
|
|
876
|
-
};
|
|
877
|
-
function* nodes(editor, options = {}) {
|
|
878
|
-
const {
|
|
879
|
-
at = editor.selection,
|
|
880
|
-
mode = "all",
|
|
881
|
-
universal = false,
|
|
882
|
-
reverse = false,
|
|
883
|
-
voids = false,
|
|
884
|
-
ignoreNonSelectable = false
|
|
885
|
-
} = options;
|
|
886
|
-
let { match } = options;
|
|
887
|
-
if (!match) {
|
|
888
|
-
match = () => true;
|
|
889
|
-
}
|
|
890
|
-
if (!at) {
|
|
891
|
-
return;
|
|
892
|
-
}
|
|
893
|
-
let from;
|
|
894
|
-
let to;
|
|
895
|
-
if (Span.isSpan(at)) {
|
|
896
|
-
from = at[0];
|
|
897
|
-
to = at[1];
|
|
898
|
-
} else {
|
|
899
|
-
const first2 = Editor.path(editor, at, { edge: "start" });
|
|
900
|
-
const last2 = Editor.path(editor, at, { edge: "end" });
|
|
901
|
-
from = reverse ? last2 : first2;
|
|
902
|
-
to = reverse ? first2 : last2;
|
|
903
|
-
}
|
|
904
|
-
const nodeEntries = Node.nodes(editor, {
|
|
905
|
-
reverse,
|
|
906
|
-
from,
|
|
907
|
-
to,
|
|
908
|
-
pass: ([node2]) => {
|
|
909
|
-
if (!Element.isElement(node2)) return false;
|
|
910
|
-
if (!voids && (Editor.isVoid(editor, node2) || Editor.isElementReadOnly(editor, node2)))
|
|
911
|
-
return true;
|
|
912
|
-
if (ignoreNonSelectable && !Editor.isSelectable(editor, node2)) return true;
|
|
913
|
-
return false;
|
|
914
|
-
}
|
|
915
|
-
});
|
|
916
|
-
const matches = [];
|
|
917
|
-
let hit;
|
|
918
|
-
for (const [node2, path2] of nodeEntries) {
|
|
919
|
-
if (ignoreNonSelectable && Element.isElement(node2) && !Editor.isSelectable(editor, node2)) {
|
|
920
|
-
continue;
|
|
921
|
-
}
|
|
922
|
-
const isLower = hit && Path.compare(path2, hit[1]) === 0;
|
|
923
|
-
if (mode === "highest" && isLower) {
|
|
924
|
-
continue;
|
|
925
|
-
}
|
|
926
|
-
if (!match(node2, path2)) {
|
|
927
|
-
if (universal && !isLower && Text.isText(node2)) {
|
|
928
|
-
return;
|
|
929
|
-
} else {
|
|
930
|
-
continue;
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
if (mode === "lowest" && isLower) {
|
|
934
|
-
hit = [node2, path2];
|
|
935
|
-
continue;
|
|
936
|
-
}
|
|
937
|
-
const emit = mode === "lowest" ? hit : [node2, path2];
|
|
938
|
-
if (emit) {
|
|
939
|
-
if (universal) {
|
|
940
|
-
matches.push(emit);
|
|
941
|
-
} else {
|
|
942
|
-
yield emit;
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
hit = [node2, path2];
|
|
946
|
-
}
|
|
947
|
-
if (mode === "lowest" && hit) {
|
|
948
|
-
if (universal) {
|
|
949
|
-
matches.push(hit);
|
|
950
|
-
} else {
|
|
951
|
-
yield hit;
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
if (universal) {
|
|
955
|
-
yield* matches;
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
const normalize = (editor, options = {}) => {
|
|
959
|
-
const { force = false, operation } = options;
|
|
960
|
-
const getDirtyPaths2 = (editor2) => {
|
|
961
|
-
return DIRTY_PATHS.get(editor2) || [];
|
|
962
|
-
};
|
|
963
|
-
const getDirtyPathKeys = (editor2) => {
|
|
964
|
-
return DIRTY_PATH_KEYS.get(editor2) || /* @__PURE__ */ new Set();
|
|
965
|
-
};
|
|
966
|
-
const popDirtyPath = (editor2) => {
|
|
967
|
-
const path2 = getDirtyPaths2(editor2).pop();
|
|
968
|
-
const key = path2.join(",");
|
|
969
|
-
getDirtyPathKeys(editor2).delete(key);
|
|
970
|
-
return path2;
|
|
971
|
-
};
|
|
972
|
-
if (!Editor.isNormalizing(editor)) {
|
|
973
|
-
return;
|
|
974
|
-
}
|
|
975
|
-
if (force) {
|
|
976
|
-
const allPaths = Array.from(Node.nodes(editor), ([, p]) => p);
|
|
977
|
-
const allPathKeys = new Set(allPaths.map((p) => p.join(",")));
|
|
978
|
-
DIRTY_PATHS.set(editor, allPaths);
|
|
979
|
-
DIRTY_PATH_KEYS.set(editor, allPathKeys);
|
|
980
|
-
}
|
|
981
|
-
if (getDirtyPaths2(editor).length === 0) {
|
|
982
|
-
return;
|
|
983
|
-
}
|
|
984
|
-
Editor.withoutNormalizing(editor, () => {
|
|
985
|
-
for (const dirtyPath of getDirtyPaths2(editor)) {
|
|
986
|
-
if (Node.has(editor, dirtyPath)) {
|
|
987
|
-
const entry = Editor.node(editor, dirtyPath);
|
|
988
|
-
const [node2, _] = entry;
|
|
989
|
-
if (Element.isElement(node2) && node2.children.length === 0) {
|
|
990
|
-
editor.normalizeNode(entry, { operation });
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
let dirtyPaths = getDirtyPaths2(editor);
|
|
995
|
-
const initialDirtyPathsLength = dirtyPaths.length;
|
|
996
|
-
let iteration = 0;
|
|
997
|
-
while (dirtyPaths.length !== 0) {
|
|
998
|
-
if (!editor.shouldNormalize({
|
|
999
|
-
dirtyPaths,
|
|
1000
|
-
iteration,
|
|
1001
|
-
initialDirtyPathsLength,
|
|
1002
|
-
operation
|
|
1003
|
-
})) {
|
|
1004
|
-
return;
|
|
1005
|
-
}
|
|
1006
|
-
const dirtyPath = popDirtyPath(editor);
|
|
1007
|
-
if (Node.has(editor, dirtyPath)) {
|
|
1008
|
-
const entry = Editor.node(editor, dirtyPath);
|
|
1009
|
-
editor.normalizeNode(entry, { operation });
|
|
1010
|
-
}
|
|
1011
|
-
iteration++;
|
|
1012
|
-
dirtyPaths = getDirtyPaths2(editor);
|
|
1013
|
-
}
|
|
1014
|
-
});
|
|
1015
|
-
};
|
|
1016
|
-
const parent = (editor, at, options = {}) => {
|
|
1017
|
-
const path2 = Editor.path(editor, at, options);
|
|
1018
|
-
const parentPath = Path.parent(path2);
|
|
1019
|
-
const entry = Editor.node(editor, parentPath);
|
|
1020
|
-
return entry;
|
|
1021
|
-
};
|
|
1022
|
-
const pathRef = (editor, path2, options = {}) => {
|
|
1023
|
-
const { affinity = "forward" } = options;
|
|
1024
|
-
const ref = {
|
|
1025
|
-
current: path2,
|
|
1026
|
-
affinity,
|
|
1027
|
-
unref() {
|
|
1028
|
-
const { current } = ref;
|
|
1029
|
-
const pathRefs2 = Editor.pathRefs(editor);
|
|
1030
|
-
pathRefs2.delete(ref);
|
|
1031
|
-
ref.current = null;
|
|
1032
|
-
return current;
|
|
1033
|
-
}
|
|
1034
|
-
};
|
|
1035
|
-
const refs = Editor.pathRefs(editor);
|
|
1036
|
-
refs.add(ref);
|
|
1037
|
-
return ref;
|
|
1038
|
-
};
|
|
1039
|
-
const pathRefs = (editor) => {
|
|
1040
|
-
let refs = PATH_REFS.get(editor);
|
|
1041
|
-
if (!refs) {
|
|
1042
|
-
refs = /* @__PURE__ */ new Set();
|
|
1043
|
-
PATH_REFS.set(editor, refs);
|
|
1044
|
-
}
|
|
1045
|
-
return refs;
|
|
1046
|
-
};
|
|
1047
|
-
const path = (editor, at, options = {}) => {
|
|
1048
|
-
const { depth, edge } = options;
|
|
1049
|
-
if (Path.isPath(at)) {
|
|
1050
|
-
if (edge === "start") {
|
|
1051
|
-
const [, firstPath] = Node.first(editor, at);
|
|
1052
|
-
at = firstPath;
|
|
1053
|
-
} else if (edge === "end") {
|
|
1054
|
-
const [, lastPath] = Node.last(editor, at);
|
|
1055
|
-
at = lastPath;
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
if (Range.isRange(at)) {
|
|
1059
|
-
if (edge === "start") {
|
|
1060
|
-
at = Range.start(at);
|
|
1061
|
-
} else if (edge === "end") {
|
|
1062
|
-
at = Range.end(at);
|
|
1063
|
-
} else {
|
|
1064
|
-
at = Path.common(at.anchor.path, at.focus.path);
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
if (Point.isPoint(at)) {
|
|
1068
|
-
at = at.path;
|
|
1069
|
-
}
|
|
1070
|
-
if (depth != null) {
|
|
1071
|
-
at = at.slice(0, depth);
|
|
1072
|
-
}
|
|
1073
|
-
return at;
|
|
1074
|
-
};
|
|
1075
|
-
const pointRef = (editor, point2, options = {}) => {
|
|
1076
|
-
const { affinity = "forward" } = options;
|
|
1077
|
-
const ref = {
|
|
1078
|
-
current: point2,
|
|
1079
|
-
affinity,
|
|
1080
|
-
unref() {
|
|
1081
|
-
const { current } = ref;
|
|
1082
|
-
const pointRefs2 = Editor.pointRefs(editor);
|
|
1083
|
-
pointRefs2.delete(ref);
|
|
1084
|
-
ref.current = null;
|
|
1085
|
-
return current;
|
|
1086
|
-
}
|
|
1087
|
-
};
|
|
1088
|
-
const refs = Editor.pointRefs(editor);
|
|
1089
|
-
refs.add(ref);
|
|
1090
|
-
return ref;
|
|
1091
|
-
};
|
|
1092
|
-
const pointRefs = (editor) => {
|
|
1093
|
-
let refs = POINT_REFS.get(editor);
|
|
1094
|
-
if (!refs) {
|
|
1095
|
-
refs = /* @__PURE__ */ new Set();
|
|
1096
|
-
POINT_REFS.set(editor, refs);
|
|
1097
|
-
}
|
|
1098
|
-
return refs;
|
|
1099
|
-
};
|
|
1100
|
-
const point = (editor, at, options = {}) => {
|
|
1101
|
-
const { edge = "start" } = options;
|
|
1102
|
-
if (Path.isPath(at)) {
|
|
1103
|
-
let path2;
|
|
1104
|
-
if (edge === "end") {
|
|
1105
|
-
const [, lastPath] = Node.last(editor, at);
|
|
1106
|
-
path2 = lastPath;
|
|
1107
|
-
} else {
|
|
1108
|
-
const [, firstPath] = Node.first(editor, at);
|
|
1109
|
-
path2 = firstPath;
|
|
1110
|
-
}
|
|
1111
|
-
const node2 = Node.get(editor, path2);
|
|
1112
|
-
if (!Text.isText(node2)) {
|
|
1113
|
-
throw new Error(
|
|
1114
|
-
`Cannot get the ${edge} point in the node at path [${at}] because it has no ${edge} text node.`
|
|
1115
|
-
);
|
|
1116
|
-
}
|
|
1117
|
-
return { path: path2, offset: edge === "end" ? node2.text.length : 0 };
|
|
1118
|
-
}
|
|
1119
|
-
if (Range.isRange(at)) {
|
|
1120
|
-
const [start2, end2] = Range.edges(at);
|
|
1121
|
-
return edge === "start" ? start2 : end2;
|
|
1122
|
-
}
|
|
1123
|
-
return at;
|
|
1124
|
-
};
|
|
1125
|
-
function* positions(editor, options = {}) {
|
|
1126
|
-
const {
|
|
1127
|
-
at = editor.selection,
|
|
1128
|
-
unit = "offset",
|
|
1129
|
-
reverse = false,
|
|
1130
|
-
voids = false,
|
|
1131
|
-
ignoreNonSelectable = false
|
|
1132
|
-
} = options;
|
|
1133
|
-
if (!at) {
|
|
1134
|
-
return;
|
|
1135
|
-
}
|
|
1136
|
-
const range2 = Editor.range(editor, at);
|
|
1137
|
-
const [start2, end2] = Range.edges(range2);
|
|
1138
|
-
const first2 = reverse ? end2 : start2;
|
|
1139
|
-
let isNewBlock = false;
|
|
1140
|
-
let blockText = "";
|
|
1141
|
-
let distance = 0;
|
|
1142
|
-
let leafTextRemaining = 0;
|
|
1143
|
-
let leafTextOffset = 0;
|
|
1144
|
-
for (const [node2, path2] of Editor.nodes(editor, {
|
|
1145
|
-
at,
|
|
1146
|
-
reverse,
|
|
1147
|
-
voids,
|
|
1148
|
-
ignoreNonSelectable
|
|
1149
|
-
})) {
|
|
1150
|
-
if (Element.isElement(node2)) {
|
|
1151
|
-
if (!voids && (editor.isVoid(node2) || editor.isElementReadOnly(node2))) {
|
|
1152
|
-
yield Editor.start(editor, path2);
|
|
1153
|
-
continue;
|
|
1154
|
-
}
|
|
1155
|
-
if (editor.isInline(node2)) continue;
|
|
1156
|
-
if (Editor.hasInlines(editor, node2)) {
|
|
1157
|
-
const e = Path.isAncestor(path2, end2.path) ? end2 : Editor.end(editor, path2);
|
|
1158
|
-
const s = Path.isAncestor(path2, start2.path) ? start2 : Editor.start(editor, path2);
|
|
1159
|
-
blockText = Editor.string(editor, { anchor: s, focus: e }, { voids });
|
|
1160
|
-
isNewBlock = true;
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
if (Text.isText(node2)) {
|
|
1164
|
-
const isFirst = Path.equals(path2, first2.path);
|
|
1165
|
-
if (isFirst) {
|
|
1166
|
-
leafTextRemaining = reverse ? first2.offset : node2.text.length - first2.offset;
|
|
1167
|
-
leafTextOffset = first2.offset;
|
|
1168
|
-
} else {
|
|
1169
|
-
leafTextRemaining = node2.text.length;
|
|
1170
|
-
leafTextOffset = reverse ? leafTextRemaining : 0;
|
|
1171
|
-
}
|
|
1172
|
-
if (isFirst || isNewBlock || unit === "offset") {
|
|
1173
|
-
yield { path: path2, offset: leafTextOffset };
|
|
1174
|
-
isNewBlock = false;
|
|
1175
|
-
}
|
|
1176
|
-
while (true) {
|
|
1177
|
-
if (distance === 0) {
|
|
1178
|
-
if (blockText === "") break;
|
|
1179
|
-
distance = calcDistance(blockText, unit, reverse);
|
|
1180
|
-
blockText = splitByCharacterDistance(blockText, distance, reverse)[1];
|
|
1181
|
-
}
|
|
1182
|
-
leafTextOffset = reverse ? leafTextOffset - distance : leafTextOffset + distance;
|
|
1183
|
-
leafTextRemaining = leafTextRemaining - distance;
|
|
1184
|
-
if (leafTextRemaining < 0) {
|
|
1185
|
-
distance = -leafTextRemaining;
|
|
1186
|
-
break;
|
|
1187
|
-
}
|
|
1188
|
-
distance = 0;
|
|
1189
|
-
yield { path: path2, offset: leafTextOffset };
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
function calcDistance(text, unit2, reverse2) {
|
|
1194
|
-
if (unit2 === "character") {
|
|
1195
|
-
return getCharacterDistance(text, reverse2);
|
|
1196
|
-
} else if (unit2 === "word") {
|
|
1197
|
-
return getWordDistance(text, reverse2);
|
|
1198
|
-
} else if (unit2 === "line" || unit2 === "block") {
|
|
1199
|
-
return text.length;
|
|
1200
|
-
}
|
|
1201
|
-
return 1;
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
const previous = (editor, options = {}) => {
|
|
1205
|
-
const { mode = "lowest", voids = false } = options;
|
|
1206
|
-
let { match, at = editor.selection } = options;
|
|
1207
|
-
if (!at) {
|
|
1208
|
-
return;
|
|
1209
|
-
}
|
|
1210
|
-
const pointBeforeLocation = Editor.before(editor, at, { voids });
|
|
1211
|
-
if (!pointBeforeLocation) {
|
|
1212
|
-
return;
|
|
1213
|
-
}
|
|
1214
|
-
const [, to] = Editor.first(editor, []);
|
|
1215
|
-
const span = [pointBeforeLocation.path, to];
|
|
1216
|
-
if (Path.isPath(at) && at.length === 0) {
|
|
1217
|
-
throw new Error(`Cannot get the previous node from the root node!`);
|
|
1218
|
-
}
|
|
1219
|
-
if (match == null) {
|
|
1220
|
-
if (Path.isPath(at)) {
|
|
1221
|
-
const [parent2] = Editor.parent(editor, at);
|
|
1222
|
-
match = (n) => parent2.children.includes(n);
|
|
1223
|
-
} else {
|
|
1224
|
-
match = () => true;
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
const [previous2] = Editor.nodes(editor, {
|
|
1228
|
-
reverse: true,
|
|
1229
|
-
at: span,
|
|
1230
|
-
match,
|
|
1231
|
-
mode,
|
|
1232
|
-
voids
|
|
1233
|
-
});
|
|
1234
|
-
return previous2;
|
|
1235
|
-
};
|
|
1236
|
-
const rangeRef = (editor, range2, options = {}) => {
|
|
1237
|
-
const { affinity = "forward" } = options;
|
|
1238
|
-
const ref = {
|
|
1239
|
-
current: range2,
|
|
1240
|
-
affinity,
|
|
1241
|
-
unref() {
|
|
1242
|
-
const { current } = ref;
|
|
1243
|
-
const rangeRefs2 = Editor.rangeRefs(editor);
|
|
1244
|
-
rangeRefs2.delete(ref);
|
|
1245
|
-
ref.current = null;
|
|
1246
|
-
return current;
|
|
1247
|
-
}
|
|
1248
|
-
};
|
|
1249
|
-
const refs = Editor.rangeRefs(editor);
|
|
1250
|
-
refs.add(ref);
|
|
1251
|
-
return ref;
|
|
1252
|
-
};
|
|
1253
|
-
const rangeRefs = (editor) => {
|
|
1254
|
-
let refs = RANGE_REFS.get(editor);
|
|
1255
|
-
if (!refs) {
|
|
1256
|
-
refs = /* @__PURE__ */ new Set();
|
|
1257
|
-
RANGE_REFS.set(editor, refs);
|
|
1258
|
-
}
|
|
1259
|
-
return refs;
|
|
1260
|
-
};
|
|
1261
|
-
const range = (editor, at, to) => {
|
|
1262
|
-
if (Range.isRange(at) && !to) {
|
|
1263
|
-
return at;
|
|
1264
|
-
}
|
|
1265
|
-
const start2 = Editor.start(editor, at);
|
|
1266
|
-
const end2 = Editor.end(editor, to || at);
|
|
1267
|
-
return { anchor: start2, focus: end2 };
|
|
1268
|
-
};
|
|
1269
|
-
const removeMark = (editor, key) => {
|
|
1270
|
-
const { selection } = editor;
|
|
1271
|
-
if (selection) {
|
|
1272
|
-
const match = (node2, path2) => {
|
|
1273
|
-
if (!Text.isText(node2)) {
|
|
1274
|
-
return false;
|
|
1275
|
-
}
|
|
1276
|
-
const [parentNode, parentPath] = Editor.parent(editor, path2);
|
|
1277
|
-
return !editor.isVoid(parentNode) || editor.markableVoid(parentNode);
|
|
1278
|
-
};
|
|
1279
|
-
const expandedSelection = Range.isExpanded(selection);
|
|
1280
|
-
let markAcceptingVoidSelected = false;
|
|
1281
|
-
if (!expandedSelection) {
|
|
1282
|
-
const [selectedNode, selectedPath] = Editor.node(editor, selection);
|
|
1283
|
-
if (selectedNode && match(selectedNode, selectedPath)) {
|
|
1284
|
-
const [parentNode] = Editor.parent(editor, selectedPath);
|
|
1285
|
-
markAcceptingVoidSelected = parentNode && editor.markableVoid(parentNode);
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1288
|
-
if (expandedSelection || markAcceptingVoidSelected) {
|
|
1289
|
-
Transforms.unsetNodes(editor, key, {
|
|
1290
|
-
match,
|
|
1291
|
-
split: true,
|
|
1292
|
-
voids: true
|
|
1293
|
-
});
|
|
1294
|
-
} else {
|
|
1295
|
-
const marks2 = { ...Editor.marks(editor) || {} };
|
|
1296
|
-
delete marks2[key];
|
|
1297
|
-
editor.marks = marks2;
|
|
1298
|
-
if (!FLUSHING.get(editor)) {
|
|
1299
|
-
editor.onChange();
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
}
|
|
1303
|
-
};
|
|
1304
|
-
const setNormalizing = (editor, isNormalizing2) => {
|
|
1305
|
-
NORMALIZING.set(editor, isNormalizing2);
|
|
1306
|
-
};
|
|
1307
|
-
const start = (editor, at) => {
|
|
1308
|
-
return Editor.point(editor, at, { edge: "start" });
|
|
1309
|
-
};
|
|
1310
|
-
const string = (editor, at, options = {}) => {
|
|
1311
|
-
const { voids = false } = options;
|
|
1312
|
-
const range2 = Editor.range(editor, at);
|
|
1313
|
-
const [start2, end2] = Range.edges(range2);
|
|
1314
|
-
let text = "";
|
|
1315
|
-
for (const [node2, path2] of Editor.nodes(editor, {
|
|
1316
|
-
at: range2,
|
|
1317
|
-
match: Text.isText,
|
|
1318
|
-
voids
|
|
1319
|
-
})) {
|
|
1320
|
-
let t = node2.text;
|
|
1321
|
-
if (Path.equals(path2, end2.path)) {
|
|
1322
|
-
t = t.slice(0, end2.offset);
|
|
1323
|
-
}
|
|
1324
|
-
if (Path.equals(path2, start2.path)) {
|
|
1325
|
-
t = t.slice(start2.offset);
|
|
1326
|
-
}
|
|
1327
|
-
text += t;
|
|
1328
|
-
}
|
|
1329
|
-
return text;
|
|
1330
|
-
};
|
|
1331
|
-
const unhangRange = (editor, range2, options = {}) => {
|
|
1332
|
-
const { voids = false } = options;
|
|
1333
|
-
let [start2, end2] = Range.edges(range2);
|
|
1334
|
-
if (start2.offset !== 0 || end2.offset !== 0 || Range.isCollapsed(range2) || Path.hasPrevious(end2.path)) {
|
|
1335
|
-
return range2;
|
|
1336
|
-
}
|
|
1337
|
-
const endBlock = Editor.above(editor, {
|
|
1338
|
-
at: end2,
|
|
1339
|
-
match: (n) => Element.isElement(n) && Editor.isBlock(editor, n),
|
|
1340
|
-
voids
|
|
1341
|
-
});
|
|
1342
|
-
const blockPath = endBlock ? endBlock[1] : [];
|
|
1343
|
-
const first2 = Editor.start(editor, start2);
|
|
1344
|
-
const before2 = { anchor: first2, focus: end2 };
|
|
1345
|
-
let skip = true;
|
|
1346
|
-
for (const [node2, path2] of Editor.nodes(editor, {
|
|
1347
|
-
at: before2,
|
|
1348
|
-
match: Text.isText,
|
|
1349
|
-
reverse: true,
|
|
1350
|
-
voids
|
|
1351
|
-
})) {
|
|
1352
|
-
if (skip) {
|
|
1353
|
-
skip = false;
|
|
1354
|
-
continue;
|
|
1355
|
-
}
|
|
1356
|
-
if (node2.text !== "" || Path.isBefore(path2, blockPath)) {
|
|
1357
|
-
end2 = { path: path2, offset: node2.text.length };
|
|
1358
|
-
break;
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
return { anchor: start2, focus: end2 };
|
|
1362
|
-
};
|
|
1363
|
-
const withoutNormalizing = (editor, fn) => {
|
|
1364
|
-
const value = Editor.isNormalizing(editor);
|
|
1365
|
-
Editor.setNormalizing(editor, false);
|
|
1366
|
-
try {
|
|
1367
|
-
fn();
|
|
1368
|
-
} finally {
|
|
1369
|
-
Editor.setNormalizing(editor, value);
|
|
1370
|
-
}
|
|
1371
|
-
Editor.normalize(editor);
|
|
1372
|
-
};
|
|
1373
|
-
const shouldMergeNodesRemovePrevNode = (editor, [prevNode, prevPath], [curNode, curNodePath]) => {
|
|
1374
|
-
return Element.isElement(prevNode) && Editor.isEmpty(editor, prevNode) || Text.isText(prevNode) && prevNode.text === "" && prevPath[prevPath.length - 1] !== 0;
|
|
1375
|
-
};
|
|
1376
|
-
const deleteText = (editor, options = {}) => {
|
|
1377
|
-
Editor.withoutNormalizing(editor, () => {
|
|
1378
|
-
const {
|
|
1379
|
-
reverse = false,
|
|
1380
|
-
unit = "character",
|
|
1381
|
-
distance = 1,
|
|
1382
|
-
voids = false
|
|
1383
|
-
} = options;
|
|
1384
|
-
let { at = cloneDeep(editor.selection), hanging = false } = options;
|
|
1385
|
-
if (!at) {
|
|
1386
|
-
return;
|
|
1387
|
-
}
|
|
1388
|
-
let isCollapsed = false;
|
|
1389
|
-
if (Range.isRange(at) && Range.isCollapsed(at)) {
|
|
1390
|
-
isCollapsed = true;
|
|
1391
|
-
at = at.anchor;
|
|
1392
|
-
}
|
|
1393
|
-
if (Point.isPoint(at)) {
|
|
1394
|
-
const furthestVoid = Editor.void(editor, { at, mode: "highest" });
|
|
1395
|
-
if (!voids && furthestVoid) {
|
|
1396
|
-
const [, voidPath] = furthestVoid;
|
|
1397
|
-
at = voidPath;
|
|
1398
|
-
} else {
|
|
1399
|
-
const opts = { unit, distance };
|
|
1400
|
-
const target = reverse ? Editor.before(editor, at, opts) || Editor.start(editor, []) : Editor.after(editor, at, opts) || Editor.end(editor, []);
|
|
1401
|
-
at = { anchor: at, focus: target };
|
|
1402
|
-
hanging = true;
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
if (Path.isPath(at)) {
|
|
1406
|
-
Transforms.removeNodes(editor, { at, voids });
|
|
1407
|
-
return;
|
|
1408
|
-
}
|
|
1409
|
-
if (Range.isCollapsed(at)) {
|
|
1410
|
-
return;
|
|
1411
|
-
}
|
|
1412
|
-
if (!hanging) {
|
|
1413
|
-
const [, end22] = Range.edges(at);
|
|
1414
|
-
const endOfDoc = Editor.end(editor, []);
|
|
1415
|
-
if (!Point.equals(end22, endOfDoc)) {
|
|
1416
|
-
at = Editor.unhangRange(editor, at, { voids });
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
let [start2, end2] = Range.edges(at);
|
|
1420
|
-
const startBlock = Editor.above(editor, {
|
|
1421
|
-
match: (n) => Element.isElement(n) && Editor.isBlock(editor, n),
|
|
1422
|
-
at: start2,
|
|
1423
|
-
voids
|
|
1424
|
-
});
|
|
1425
|
-
const endBlock = Editor.above(editor, {
|
|
1426
|
-
match: (n) => Element.isElement(n) && Editor.isBlock(editor, n),
|
|
1427
|
-
at: end2,
|
|
1428
|
-
voids
|
|
1429
|
-
});
|
|
1430
|
-
const isAcrossBlocks = startBlock && endBlock && !Path.equals(startBlock[1], endBlock[1]);
|
|
1431
|
-
const isSingleText = Path.equals(start2.path, end2.path);
|
|
1432
|
-
const startNonEditable = voids ? null : Editor.void(editor, { at: start2, mode: "highest" }) ?? Editor.elementReadOnly(editor, { at: start2, mode: "highest" });
|
|
1433
|
-
const endNonEditable = voids ? null : Editor.void(editor, { at: end2, mode: "highest" }) ?? Editor.elementReadOnly(editor, { at: end2, mode: "highest" });
|
|
1434
|
-
if (startNonEditable) {
|
|
1435
|
-
const before2 = Editor.before(editor, start2);
|
|
1436
|
-
if (before2 && startBlock && Path.isAncestor(startBlock[1], before2.path)) {
|
|
1437
|
-
start2 = before2;
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
if (endNonEditable) {
|
|
1441
|
-
const after2 = Editor.after(editor, end2);
|
|
1442
|
-
if (after2 && endBlock && Path.isAncestor(endBlock[1], after2.path)) {
|
|
1443
|
-
end2 = after2;
|
|
1444
|
-
}
|
|
1445
|
-
}
|
|
1446
|
-
const matches = [];
|
|
1447
|
-
let lastPath;
|
|
1448
|
-
for (const entry of Editor.nodes(editor, { at, voids })) {
|
|
1449
|
-
const [node2, path2] = entry;
|
|
1450
|
-
if (lastPath && Path.compare(path2, lastPath) === 0) {
|
|
1451
|
-
continue;
|
|
1452
|
-
}
|
|
1453
|
-
if (!voids && Element.isElement(node2) && (Editor.isVoid(editor, node2) || Editor.isElementReadOnly(editor, node2)) || !Path.isCommon(path2, start2.path) && !Path.isCommon(path2, end2.path)) {
|
|
1454
|
-
matches.push(entry);
|
|
1455
|
-
lastPath = path2;
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
const pathRefs2 = Array.from(matches, ([, p]) => Editor.pathRef(editor, p));
|
|
1459
|
-
const startRef = Editor.pointRef(editor, start2);
|
|
1460
|
-
const endRef = Editor.pointRef(editor, end2);
|
|
1461
|
-
let removedText = "";
|
|
1462
|
-
if (!isSingleText && !startNonEditable) {
|
|
1463
|
-
const point22 = startRef.current;
|
|
1464
|
-
const [node2] = Editor.leaf(editor, point22);
|
|
1465
|
-
const { path: path2 } = point22;
|
|
1466
|
-
const { offset } = start2;
|
|
1467
|
-
const text = node2.text.slice(offset);
|
|
1468
|
-
if (text.length > 0) {
|
|
1469
|
-
editor.apply({ type: "remove_text", path: path2, offset, text });
|
|
1470
|
-
removedText = text;
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
pathRefs2.reverse().map((r) => r.unref()).filter((r) => r !== null).forEach((p) => Transforms.removeNodes(editor, { at: p, voids }));
|
|
1474
|
-
if (!endNonEditable) {
|
|
1475
|
-
const point22 = endRef.current;
|
|
1476
|
-
const [node2] = Editor.leaf(editor, point22);
|
|
1477
|
-
const { path: path2 } = point22;
|
|
1478
|
-
const offset = isSingleText ? start2.offset : 0;
|
|
1479
|
-
const text = node2.text.slice(offset, end2.offset);
|
|
1480
|
-
if (text.length > 0) {
|
|
1481
|
-
editor.apply({ type: "remove_text", path: path2, offset, text });
|
|
1482
|
-
removedText = text;
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
if (!isSingleText && isAcrossBlocks && endRef.current && startRef.current) {
|
|
1486
|
-
Transforms.mergeNodes(editor, {
|
|
1487
|
-
at: endRef.current,
|
|
1488
|
-
hanging: true,
|
|
1489
|
-
voids
|
|
1490
|
-
});
|
|
1491
|
-
}
|
|
1492
|
-
if (isCollapsed && reverse && unit === "character" && removedText.length > 1 && removedText.match(/[\u0E00-\u0E7F]+/)) {
|
|
1493
|
-
Transforms.insertText(
|
|
1494
|
-
editor,
|
|
1495
|
-
removedText.slice(0, removedText.length - distance)
|
|
1496
|
-
);
|
|
1497
|
-
}
|
|
1498
|
-
const startUnref = startRef.unref();
|
|
1499
|
-
const endUnref = endRef.unref();
|
|
1500
|
-
const point2 = reverse ? startUnref || endUnref : endUnref || startUnref;
|
|
1501
|
-
if (options.at == null && point2) {
|
|
1502
|
-
Transforms.select(editor, point2);
|
|
1503
|
-
}
|
|
1504
|
-
});
|
|
1505
|
-
};
|
|
1506
|
-
const insertFragment = (editor, fragment2, options = {}) => {
|
|
1507
|
-
Editor.withoutNormalizing(editor, () => {
|
|
1508
|
-
const { hanging = false, voids = false } = options;
|
|
1509
|
-
let { at = getDefaultInsertLocation(editor), batchDirty = true } = options;
|
|
1510
|
-
if (!fragment2.length) {
|
|
1511
|
-
return;
|
|
1512
|
-
}
|
|
1513
|
-
if (Range.isRange(at)) {
|
|
1514
|
-
if (!hanging) {
|
|
1515
|
-
at = Editor.unhangRange(editor, at, { voids });
|
|
1516
|
-
}
|
|
1517
|
-
if (Range.isCollapsed(at)) {
|
|
1518
|
-
at = at.anchor;
|
|
1519
|
-
} else {
|
|
1520
|
-
const [, end2] = Range.edges(at);
|
|
1521
|
-
if (!voids && Editor.void(editor, { at: end2 })) {
|
|
1522
|
-
return;
|
|
1523
|
-
}
|
|
1524
|
-
const pointRef2 = Editor.pointRef(editor, end2);
|
|
1525
|
-
Transforms.delete(editor, { at });
|
|
1526
|
-
at = pointRef2.unref();
|
|
1527
|
-
}
|
|
1528
|
-
} else if (Path.isPath(at)) {
|
|
1529
|
-
at = Editor.start(editor, at);
|
|
1530
|
-
}
|
|
1531
|
-
if (!voids && Editor.void(editor, { at })) {
|
|
1532
|
-
return;
|
|
1533
|
-
}
|
|
1534
|
-
const inlineElementMatch = Editor.above(editor, {
|
|
1535
|
-
at,
|
|
1536
|
-
match: (n) => Element.isElement(n) && Editor.isInline(editor, n),
|
|
1537
|
-
mode: "highest",
|
|
1538
|
-
voids
|
|
1539
|
-
});
|
|
1540
|
-
if (inlineElementMatch) {
|
|
1541
|
-
const [, inlinePath2] = inlineElementMatch;
|
|
1542
|
-
if (Editor.isEnd(editor, at, inlinePath2)) {
|
|
1543
|
-
const after2 = Editor.after(editor, inlinePath2);
|
|
1544
|
-
at = after2;
|
|
1545
|
-
} else if (Editor.isStart(editor, at, inlinePath2)) {
|
|
1546
|
-
const before2 = Editor.before(editor, inlinePath2);
|
|
1547
|
-
at = before2;
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
const blockMatch = Editor.above(editor, {
|
|
1551
|
-
match: (n) => Element.isElement(n) && Editor.isBlock(editor, n),
|
|
1552
|
-
at,
|
|
1553
|
-
voids
|
|
1554
|
-
});
|
|
1555
|
-
const [, blockPath] = blockMatch;
|
|
1556
|
-
const isBlockStart = Editor.isStart(editor, at, blockPath);
|
|
1557
|
-
const isBlockEnd = Editor.isEnd(editor, at, blockPath);
|
|
1558
|
-
const isBlockEmpty = isBlockStart && isBlockEnd;
|
|
1559
|
-
const mergeStart = !isBlockStart || isBlockStart && isBlockEnd;
|
|
1560
|
-
const mergeEnd = !isBlockEnd;
|
|
1561
|
-
const [, firstPath] = Node.first({ children: fragment2 }, []);
|
|
1562
|
-
const [, lastPath] = Node.last({ children: fragment2 }, []);
|
|
1563
|
-
const matches = [];
|
|
1564
|
-
const matcher = ([n, p]) => {
|
|
1565
|
-
const isRoot = p.length === 0;
|
|
1566
|
-
if (isRoot) {
|
|
1567
|
-
return false;
|
|
1568
|
-
}
|
|
1569
|
-
if (isBlockEmpty) {
|
|
1570
|
-
return true;
|
|
1571
|
-
}
|
|
1572
|
-
if (mergeStart && Path.isAncestor(p, firstPath) && Element.isElement(n) && !editor.isVoid(n) && !editor.isInline(n)) {
|
|
1573
|
-
return false;
|
|
1574
|
-
}
|
|
1575
|
-
if (mergeEnd && Path.isAncestor(p, lastPath) && Element.isElement(n) && !editor.isVoid(n) && !editor.isInline(n)) {
|
|
1576
|
-
return false;
|
|
1577
|
-
}
|
|
1578
|
-
return true;
|
|
1579
|
-
};
|
|
1580
|
-
for (const entry of Node.nodes({ children: fragment2 }, { pass: matcher })) {
|
|
1581
|
-
if (matcher(entry)) {
|
|
1582
|
-
matches.push(entry);
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
|
-
const starts = [];
|
|
1586
|
-
const middles = [];
|
|
1587
|
-
const ends = [];
|
|
1588
|
-
let starting = true;
|
|
1589
|
-
let hasBlocks2 = false;
|
|
1590
|
-
for (const [node2] of matches) {
|
|
1591
|
-
if (Element.isElement(node2) && !editor.isInline(node2)) {
|
|
1592
|
-
starting = false;
|
|
1593
|
-
hasBlocks2 = true;
|
|
1594
|
-
middles.push(node2);
|
|
1595
|
-
} else if (starting) {
|
|
1596
|
-
starts.push(node2);
|
|
1597
|
-
} else {
|
|
1598
|
-
ends.push(node2);
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
const [inlineMatch] = Editor.nodes(editor, {
|
|
1602
|
-
at,
|
|
1603
|
-
match: (n) => Text.isText(n) || Editor.isInline(editor, n),
|
|
1604
|
-
mode: "highest",
|
|
1605
|
-
voids
|
|
1606
|
-
});
|
|
1607
|
-
const [, inlinePath] = inlineMatch;
|
|
1608
|
-
const isInlineStart = Editor.isStart(editor, at, inlinePath);
|
|
1609
|
-
const isInlineEnd = Editor.isEnd(editor, at, inlinePath);
|
|
1610
|
-
const middleRef = Editor.pathRef(
|
|
1611
|
-
editor,
|
|
1612
|
-
isBlockEnd && !ends.length ? Path.next(blockPath) : blockPath
|
|
1613
|
-
);
|
|
1614
|
-
const endRef = Editor.pathRef(
|
|
1615
|
-
editor,
|
|
1616
|
-
isInlineEnd ? Path.next(inlinePath) : inlinePath
|
|
1617
|
-
);
|
|
1618
|
-
Transforms.splitNodes(editor, {
|
|
1619
|
-
at,
|
|
1620
|
-
match: (n) => hasBlocks2 ? Element.isElement(n) && Editor.isBlock(editor, n) : Text.isText(n) || Editor.isInline(editor, n),
|
|
1621
|
-
mode: hasBlocks2 ? "lowest" : "highest",
|
|
1622
|
-
always: hasBlocks2 && (!isBlockStart || starts.length > 0) && (!isBlockEnd || ends.length > 0),
|
|
1623
|
-
voids
|
|
1624
|
-
});
|
|
1625
|
-
const startRef = Editor.pathRef(
|
|
1626
|
-
editor,
|
|
1627
|
-
!isInlineStart || isInlineStart && isInlineEnd ? Path.next(inlinePath) : inlinePath
|
|
1628
|
-
);
|
|
1629
|
-
Transforms.insertNodes(editor, starts, {
|
|
1630
|
-
at: startRef.current,
|
|
1631
|
-
match: (n) => Text.isText(n) || Editor.isInline(editor, n),
|
|
1632
|
-
mode: "highest",
|
|
1633
|
-
voids,
|
|
1634
|
-
batchDirty
|
|
1635
|
-
});
|
|
1636
|
-
if (isBlockEmpty && !starts.length && middles.length && !ends.length) {
|
|
1637
|
-
Transforms.delete(editor, { at: blockPath, voids });
|
|
1638
|
-
}
|
|
1639
|
-
Transforms.insertNodes(editor, middles, {
|
|
1640
|
-
at: middleRef.current,
|
|
1641
|
-
match: (n) => Element.isElement(n) && Editor.isBlock(editor, n),
|
|
1642
|
-
mode: "lowest",
|
|
1643
|
-
voids,
|
|
1644
|
-
batchDirty
|
|
1645
|
-
});
|
|
1646
|
-
Transforms.insertNodes(editor, ends, {
|
|
1647
|
-
at: endRef.current,
|
|
1648
|
-
match: (n) => Text.isText(n) || Editor.isInline(editor, n),
|
|
1649
|
-
mode: "highest",
|
|
1650
|
-
voids,
|
|
1651
|
-
batchDirty
|
|
1652
|
-
});
|
|
1653
|
-
if (!options.at) {
|
|
1654
|
-
let path2;
|
|
1655
|
-
if (ends.length > 0 && endRef.current) {
|
|
1656
|
-
path2 = Path.previous(endRef.current);
|
|
1657
|
-
} else if (middles.length > 0 && middleRef.current) {
|
|
1658
|
-
path2 = Path.previous(middleRef.current);
|
|
1659
|
-
} else if (startRef.current) {
|
|
1660
|
-
path2 = Path.previous(startRef.current);
|
|
1661
|
-
}
|
|
1662
|
-
if (path2) {
|
|
1663
|
-
const end2 = Editor.end(editor, path2);
|
|
1664
|
-
Transforms.select(editor, end2);
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
startRef.unref();
|
|
1668
|
-
middleRef.unref();
|
|
1669
|
-
endRef.unref();
|
|
1670
|
-
});
|
|
1671
|
-
};
|
|
1672
|
-
const collapse = (editor, options = {}) => {
|
|
1673
|
-
const { edge = "anchor" } = options;
|
|
1674
|
-
const { selection } = editor;
|
|
1675
|
-
if (!selection) {
|
|
1676
|
-
return;
|
|
1677
|
-
} else if (edge === "anchor") {
|
|
1678
|
-
Transforms.select(editor, selection.anchor);
|
|
1679
|
-
} else if (edge === "focus") {
|
|
1680
|
-
Transforms.select(editor, selection.focus);
|
|
1681
|
-
} else if (edge === "start") {
|
|
1682
|
-
const [start2] = Range.edges(selection);
|
|
1683
|
-
Transforms.select(editor, start2);
|
|
1684
|
-
} else if (edge === "end") {
|
|
1685
|
-
const [, end2] = Range.edges(selection);
|
|
1686
|
-
Transforms.select(editor, end2);
|
|
1687
|
-
}
|
|
1688
|
-
};
|
|
1689
|
-
const deselect = (editor) => {
|
|
1690
|
-
const { selection } = editor;
|
|
1691
|
-
if (selection) {
|
|
1692
|
-
editor.apply({
|
|
1693
|
-
type: "set_selection",
|
|
1694
|
-
properties: selection,
|
|
1695
|
-
newProperties: null
|
|
1696
|
-
});
|
|
1697
|
-
}
|
|
1698
|
-
};
|
|
1699
|
-
const move = (editor, options = {}) => {
|
|
1700
|
-
const { selection } = editor;
|
|
1701
|
-
const { distance = 1, unit = "character", reverse = false } = options;
|
|
1702
|
-
let { edge = null } = options;
|
|
1703
|
-
if (!selection) {
|
|
1704
|
-
return;
|
|
1705
|
-
}
|
|
1706
|
-
if (edge === "start") {
|
|
1707
|
-
edge = Range.isBackward(selection) ? "focus" : "anchor";
|
|
1708
|
-
}
|
|
1709
|
-
if (edge === "end") {
|
|
1710
|
-
edge = Range.isBackward(selection) ? "anchor" : "focus";
|
|
1711
|
-
}
|
|
1712
|
-
const { anchor, focus } = selection;
|
|
1713
|
-
const opts = { distance, unit, ignoreNonSelectable: true };
|
|
1714
|
-
const props = {};
|
|
1715
|
-
if (edge == null || edge === "anchor") {
|
|
1716
|
-
const point2 = reverse ? Editor.before(editor, anchor, opts) : Editor.after(editor, anchor, opts);
|
|
1717
|
-
if (point2) {
|
|
1718
|
-
props.anchor = point2;
|
|
1719
|
-
}
|
|
1720
|
-
}
|
|
1721
|
-
if (edge == null || edge === "focus") {
|
|
1722
|
-
const point2 = reverse ? Editor.before(editor, focus, opts) : Editor.after(editor, focus, opts);
|
|
1723
|
-
if (point2) {
|
|
1724
|
-
props.focus = point2;
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
|
-
Transforms.setSelection(editor, props);
|
|
1728
|
-
};
|
|
1729
|
-
const select = (editor, target) => {
|
|
1730
|
-
const { selection } = editor;
|
|
1731
|
-
target = Editor.range(editor, target);
|
|
1732
|
-
if (selection) {
|
|
1733
|
-
Transforms.setSelection(editor, target);
|
|
1734
|
-
return;
|
|
1735
|
-
}
|
|
1736
|
-
if (!Range.isRange(target)) {
|
|
1737
|
-
throw new Error(
|
|
1738
|
-
`When setting the selection and the current selection is \`null\` you must provide at least an \`anchor\` and \`focus\`, but you passed: ${Scrubber.stringify(
|
|
1739
|
-
target
|
|
1740
|
-
)}`
|
|
1741
|
-
);
|
|
1742
|
-
}
|
|
1743
|
-
editor.apply({
|
|
1744
|
-
type: "set_selection",
|
|
1745
|
-
properties: selection,
|
|
1746
|
-
newProperties: target
|
|
1747
|
-
});
|
|
1748
|
-
};
|
|
1749
|
-
const setPoint = (editor, props, options = {}) => {
|
|
1750
|
-
const { selection } = editor;
|
|
1751
|
-
let { edge = "both" } = options;
|
|
1752
|
-
if (!selection) {
|
|
1753
|
-
return;
|
|
1754
|
-
}
|
|
1755
|
-
if (edge === "start") {
|
|
1756
|
-
edge = Range.isBackward(selection) ? "focus" : "anchor";
|
|
1757
|
-
}
|
|
1758
|
-
if (edge === "end") {
|
|
1759
|
-
edge = Range.isBackward(selection) ? "anchor" : "focus";
|
|
1760
|
-
}
|
|
1761
|
-
const { anchor, focus } = selection;
|
|
1762
|
-
const point2 = edge === "anchor" ? anchor : focus;
|
|
1763
|
-
Transforms.setSelection(editor, {
|
|
1764
|
-
[edge === "anchor" ? "anchor" : "focus"]: { ...point2, ...props }
|
|
1765
|
-
});
|
|
1766
|
-
};
|
|
1767
|
-
const setSelection = (editor, props) => {
|
|
1768
|
-
const { selection } = editor;
|
|
1769
|
-
const oldProps = {};
|
|
1770
|
-
const newProps = {};
|
|
1771
|
-
if (!selection) {
|
|
1772
|
-
return;
|
|
1773
|
-
}
|
|
1774
|
-
for (const k in props) {
|
|
1775
|
-
if (k === "anchor" && props.anchor != null && !Point.equals(props.anchor, selection.anchor) || k === "focus" && props.focus != null && !Point.equals(props.focus, selection.focus) || k !== "anchor" && k !== "focus" && props[k] !== selection[k]) {
|
|
1776
|
-
oldProps[k] = selection[k];
|
|
1777
|
-
newProps[k] = props[k];
|
|
1778
|
-
}
|
|
1779
|
-
}
|
|
1780
|
-
if (Object.keys(oldProps).length > 0) {
|
|
1781
|
-
editor.apply({
|
|
1782
|
-
type: "set_selection",
|
|
1783
|
-
properties: oldProps,
|
|
1784
|
-
newProperties: newProps
|
|
1785
|
-
});
|
|
1786
|
-
}
|
|
1787
|
-
};
|
|
1788
|
-
const insertNodes = (editor, nodes2, options = {}) => {
|
|
1789
|
-
Editor.withoutNormalizing(editor, () => {
|
|
1790
|
-
const {
|
|
1791
|
-
hanging = false,
|
|
1792
|
-
voids = false,
|
|
1793
|
-
mode = "lowest",
|
|
1794
|
-
batchDirty = true
|
|
1795
|
-
} = options;
|
|
1796
|
-
let { at, match, select: select2 } = options;
|
|
1797
|
-
if (Node.isNode(nodes2)) {
|
|
1798
|
-
nodes2 = [nodes2];
|
|
1799
|
-
}
|
|
1800
|
-
if (nodes2.length === 0) {
|
|
1801
|
-
return;
|
|
1802
|
-
}
|
|
1803
|
-
const [node2] = nodes2;
|
|
1804
|
-
if (!at) {
|
|
1805
|
-
at = getDefaultInsertLocation(editor);
|
|
1806
|
-
if (select2 !== false) {
|
|
1807
|
-
select2 = true;
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
|
-
if (select2 == null) {
|
|
1811
|
-
select2 = false;
|
|
1812
|
-
}
|
|
1813
|
-
if (Range.isRange(at)) {
|
|
1814
|
-
if (!hanging) {
|
|
1815
|
-
at = Editor.unhangRange(editor, at, { voids });
|
|
1816
|
-
}
|
|
1817
|
-
if (Range.isCollapsed(at)) {
|
|
1818
|
-
at = at.anchor;
|
|
1819
|
-
} else {
|
|
1820
|
-
const [, end2] = Range.edges(at);
|
|
1821
|
-
const pointRef2 = Editor.pointRef(editor, end2);
|
|
1822
|
-
Transforms.delete(editor, { at });
|
|
1823
|
-
at = pointRef2.unref();
|
|
1824
|
-
}
|
|
1825
|
-
}
|
|
1826
|
-
if (Point.isPoint(at)) {
|
|
1827
|
-
if (match == null) {
|
|
1828
|
-
if (Text.isText(node2)) {
|
|
1829
|
-
match = (n) => Text.isText(n);
|
|
1830
|
-
} else if (editor.isInline(node2)) {
|
|
1831
|
-
match = (n) => Text.isText(n) || Editor.isInline(editor, n);
|
|
1832
|
-
} else {
|
|
1833
|
-
match = (n) => Element.isElement(n) && Editor.isBlock(editor, n);
|
|
1834
|
-
}
|
|
1835
|
-
}
|
|
1836
|
-
const [entry] = Editor.nodes(editor, {
|
|
1837
|
-
at: at.path,
|
|
1838
|
-
match,
|
|
1839
|
-
mode,
|
|
1840
|
-
voids
|
|
1841
|
-
});
|
|
1842
|
-
if (entry) {
|
|
1843
|
-
const [, matchPath2] = entry;
|
|
1844
|
-
const pathRef2 = Editor.pathRef(editor, matchPath2);
|
|
1845
|
-
const isAtEnd = Editor.isEnd(editor, at, matchPath2);
|
|
1846
|
-
Transforms.splitNodes(editor, { at, match, mode, voids });
|
|
1847
|
-
const path2 = pathRef2.unref();
|
|
1848
|
-
at = isAtEnd ? Path.next(path2) : path2;
|
|
1849
|
-
} else {
|
|
1850
|
-
return;
|
|
1851
|
-
}
|
|
1852
|
-
}
|
|
1853
|
-
const parentPath = Path.parent(at);
|
|
1854
|
-
let index = at[at.length - 1];
|
|
1855
|
-
if (!voids && Editor.void(editor, { at: parentPath })) {
|
|
1856
|
-
return;
|
|
1857
|
-
}
|
|
1858
|
-
if (batchDirty) {
|
|
1859
|
-
const batchedOps = [];
|
|
1860
|
-
const newDirtyPaths = Path.levels(parentPath);
|
|
1861
|
-
batchDirtyPaths(
|
|
1862
|
-
editor,
|
|
1863
|
-
() => {
|
|
1864
|
-
for (const node22 of nodes2) {
|
|
1865
|
-
const path2 = parentPath.concat(index);
|
|
1866
|
-
index++;
|
|
1867
|
-
const op = {
|
|
1868
|
-
type: "insert_node",
|
|
1869
|
-
path: path2,
|
|
1870
|
-
node: node22
|
|
1871
|
-
};
|
|
1872
|
-
editor.apply(op);
|
|
1873
|
-
at = Path.next(at);
|
|
1874
|
-
batchedOps.push(op);
|
|
1875
|
-
if (!Text.isText) {
|
|
1876
|
-
newDirtyPaths.push(path2);
|
|
1877
|
-
} else {
|
|
1878
|
-
newDirtyPaths.push(
|
|
1879
|
-
...Array.from(Node.nodes(node22), ([, p]) => path2.concat(p))
|
|
1880
|
-
);
|
|
1881
|
-
}
|
|
1882
|
-
}
|
|
1883
|
-
},
|
|
1884
|
-
() => {
|
|
1885
|
-
updateDirtyPaths(editor, newDirtyPaths, (p) => {
|
|
1886
|
-
let newPath = p;
|
|
1887
|
-
for (const op of batchedOps) {
|
|
1888
|
-
if (Path.operationCanTransformPath(op)) {
|
|
1889
|
-
newPath = Path.transform(newPath, op);
|
|
1890
|
-
if (!newPath) {
|
|
1891
|
-
return null;
|
|
1892
|
-
}
|
|
1893
|
-
}
|
|
1894
|
-
}
|
|
1895
|
-
return newPath;
|
|
1896
|
-
});
|
|
1897
|
-
}
|
|
1898
|
-
);
|
|
1899
|
-
} else {
|
|
1900
|
-
for (const node22 of nodes2) {
|
|
1901
|
-
const path2 = parentPath.concat(index);
|
|
1902
|
-
index++;
|
|
1903
|
-
editor.apply({ type: "insert_node", path: path2, node: node22 });
|
|
1904
|
-
at = Path.next(at);
|
|
1905
|
-
}
|
|
1906
|
-
}
|
|
1907
|
-
at = Path.previous(at);
|
|
1908
|
-
if (select2) {
|
|
1909
|
-
const point2 = Editor.end(editor, at);
|
|
1910
|
-
if (point2) {
|
|
1911
|
-
Transforms.select(editor, point2);
|
|
1912
|
-
}
|
|
1913
|
-
}
|
|
1914
|
-
});
|
|
1915
|
-
};
|
|
1916
|
-
const liftNodes = (editor, options = {}) => {
|
|
1917
|
-
Editor.withoutNormalizing(editor, () => {
|
|
1918
|
-
const { at = editor.selection, mode = "lowest", voids = false } = options;
|
|
1919
|
-
let { match } = options;
|
|
1920
|
-
if (match == null) {
|
|
1921
|
-
match = Path.isPath(at) ? matchPath(editor, at) : (n) => Element.isElement(n) && Editor.isBlock(editor, n);
|
|
1922
|
-
}
|
|
1923
|
-
if (!at) {
|
|
1924
|
-
return;
|
|
1925
|
-
}
|
|
1926
|
-
const matches = Editor.nodes(editor, { at, match, mode, voids });
|
|
1927
|
-
const pathRefs2 = Array.from(matches, ([, p]) => Editor.pathRef(editor, p));
|
|
1928
|
-
for (const pathRef2 of pathRefs2) {
|
|
1929
|
-
const path2 = pathRef2.unref();
|
|
1930
|
-
if (path2.length < 2) {
|
|
1931
|
-
throw new Error(
|
|
1932
|
-
`Cannot lift node at a path [${path2}] because it has a depth of less than \`2\`.`
|
|
1933
|
-
);
|
|
1934
|
-
}
|
|
1935
|
-
const parentNodeEntry = Editor.node(editor, Path.parent(path2));
|
|
1936
|
-
const [parent2, parentPath] = parentNodeEntry;
|
|
1937
|
-
const index = path2[path2.length - 1];
|
|
1938
|
-
const { length } = parent2.children;
|
|
1939
|
-
if (length === 1) {
|
|
1940
|
-
const toPath = Path.next(parentPath);
|
|
1941
|
-
Transforms.moveNodes(editor, { at: path2, to: toPath, voids });
|
|
1942
|
-
Transforms.removeNodes(editor, { at: parentPath, voids });
|
|
1943
|
-
} else if (index === 0) {
|
|
1944
|
-
Transforms.moveNodes(editor, { at: path2, to: parentPath, voids });
|
|
1945
|
-
} else if (index === length - 1) {
|
|
1946
|
-
const toPath = Path.next(parentPath);
|
|
1947
|
-
Transforms.moveNodes(editor, { at: path2, to: toPath, voids });
|
|
1948
|
-
} else {
|
|
1949
|
-
const splitPath = Path.next(path2);
|
|
1950
|
-
const toPath = Path.next(parentPath);
|
|
1951
|
-
Transforms.splitNodes(editor, { at: splitPath, voids });
|
|
1952
|
-
Transforms.moveNodes(editor, { at: path2, to: toPath, voids });
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
});
|
|
1956
|
-
};
|
|
1957
|
-
const hasSingleChildNest = (editor, node2) => {
|
|
1958
|
-
if (Element.isElement(node2)) {
|
|
1959
|
-
const element = node2;
|
|
1960
|
-
if (Editor.isVoid(editor, node2)) {
|
|
1961
|
-
return true;
|
|
1962
|
-
} else if (element.children.length === 1) {
|
|
1963
|
-
return hasSingleChildNest(editor, element.children[0]);
|
|
1964
|
-
} else {
|
|
1965
|
-
return false;
|
|
1966
|
-
}
|
|
1967
|
-
} else if (Editor.isEditor(node2)) {
|
|
1968
|
-
return false;
|
|
1969
|
-
} else {
|
|
1970
|
-
return true;
|
|
1971
|
-
}
|
|
1972
|
-
};
|
|
1973
|
-
const mergeNodes = (editor, options = {}) => {
|
|
1974
|
-
Editor.withoutNormalizing(editor, () => {
|
|
1975
|
-
let { match, at = editor.selection } = options;
|
|
1976
|
-
const { hanging = false, voids = false, mode = "lowest" } = options;
|
|
1977
|
-
if (!at) {
|
|
1978
|
-
return;
|
|
1979
|
-
}
|
|
1980
|
-
if (match == null) {
|
|
1981
|
-
if (Path.isPath(at)) {
|
|
1982
|
-
const [parent2] = Editor.parent(editor, at);
|
|
1983
|
-
match = (n) => parent2.children.includes(n);
|
|
1984
|
-
} else {
|
|
1985
|
-
match = (n) => Element.isElement(n) && Editor.isBlock(editor, n);
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
if (!hanging && Range.isRange(at)) {
|
|
1989
|
-
at = Editor.unhangRange(editor, at, { voids });
|
|
1990
|
-
}
|
|
1991
|
-
if (Range.isRange(at)) {
|
|
1992
|
-
if (Range.isCollapsed(at)) {
|
|
1993
|
-
at = at.anchor;
|
|
1994
|
-
} else {
|
|
1995
|
-
const [, end2] = Range.edges(at);
|
|
1996
|
-
const pointRef2 = Editor.pointRef(editor, end2);
|
|
1997
|
-
Transforms.delete(editor, { at });
|
|
1998
|
-
at = pointRef2.unref();
|
|
1999
|
-
if (options.at == null) {
|
|
2000
|
-
Transforms.select(editor, at);
|
|
2001
|
-
}
|
|
2002
|
-
}
|
|
2003
|
-
}
|
|
2004
|
-
const [current] = Editor.nodes(editor, { at, match, voids, mode });
|
|
2005
|
-
const prev = Editor.previous(editor, { at, match, voids, mode });
|
|
2006
|
-
if (!current || !prev) {
|
|
2007
|
-
return;
|
|
2008
|
-
}
|
|
2009
|
-
const [node2, path2] = current;
|
|
2010
|
-
const [prevNode, prevPath] = prev;
|
|
2011
|
-
if (path2.length === 0 || prevPath.length === 0) {
|
|
2012
|
-
return;
|
|
2013
|
-
}
|
|
2014
|
-
const newPath = Path.next(prevPath);
|
|
2015
|
-
const commonPath = Path.common(path2, prevPath);
|
|
2016
|
-
const isPreviousSibling = Path.isSibling(path2, prevPath);
|
|
2017
|
-
const levels2 = Array.from(Editor.levels(editor, { at: path2 }), ([n]) => n).slice(commonPath.length).slice(0, -1);
|
|
2018
|
-
const emptyAncestor = Editor.above(editor, {
|
|
2019
|
-
at: path2,
|
|
2020
|
-
mode: "highest",
|
|
2021
|
-
match: (n) => levels2.includes(n) && hasSingleChildNest(editor, n)
|
|
2022
|
-
});
|
|
2023
|
-
const emptyRef = emptyAncestor && Editor.pathRef(editor, emptyAncestor[1]);
|
|
2024
|
-
let properties;
|
|
2025
|
-
let position;
|
|
2026
|
-
if (Text.isText(node2) && Text.isText(prevNode)) {
|
|
2027
|
-
const { text, ...rest } = node2;
|
|
2028
|
-
position = prevNode.text.length;
|
|
2029
|
-
properties = rest;
|
|
2030
|
-
} else if (Element.isElement(node2) && Element.isElement(prevNode)) {
|
|
2031
|
-
const { children, ...rest } = node2;
|
|
2032
|
-
position = prevNode.children.length;
|
|
2033
|
-
properties = rest;
|
|
2034
|
-
} else {
|
|
2035
|
-
throw new Error(
|
|
2036
|
-
`Cannot merge the node at path [${path2}] with the previous sibling because it is not the same kind: ${Scrubber.stringify(
|
|
2037
|
-
node2
|
|
2038
|
-
)} ${Scrubber.stringify(prevNode)}`
|
|
2039
|
-
);
|
|
2040
|
-
}
|
|
2041
|
-
if (!isPreviousSibling) {
|
|
2042
|
-
Transforms.moveNodes(editor, { at: path2, to: newPath, voids });
|
|
2043
|
-
}
|
|
2044
|
-
if (emptyRef) {
|
|
2045
|
-
Transforms.removeNodes(editor, { at: emptyRef.current, voids });
|
|
2046
|
-
}
|
|
2047
|
-
if (Editor.shouldMergeNodesRemovePrevNode(editor, prev, current)) {
|
|
2048
|
-
Transforms.removeNodes(editor, { at: prevPath, voids });
|
|
2049
|
-
} else {
|
|
2050
|
-
editor.apply({
|
|
2051
|
-
type: "merge_node",
|
|
2052
|
-
path: newPath,
|
|
2053
|
-
position,
|
|
2054
|
-
properties
|
|
2055
|
-
});
|
|
2056
|
-
}
|
|
2057
|
-
if (emptyRef) {
|
|
2058
|
-
emptyRef.unref();
|
|
2059
|
-
}
|
|
2060
|
-
});
|
|
2061
|
-
};
|
|
2062
|
-
const moveNodes = (editor, options) => {
|
|
2063
|
-
Editor.withoutNormalizing(editor, () => {
|
|
2064
|
-
const {
|
|
2065
|
-
to,
|
|
2066
|
-
at = editor.selection,
|
|
2067
|
-
mode = "lowest",
|
|
2068
|
-
voids = false
|
|
2069
|
-
} = options;
|
|
2070
|
-
let { match } = options;
|
|
2071
|
-
if (!at) {
|
|
2072
|
-
return;
|
|
2073
|
-
}
|
|
2074
|
-
if (match == null) {
|
|
2075
|
-
match = Path.isPath(at) ? matchPath(editor, at) : (n) => Element.isElement(n) && Editor.isBlock(editor, n);
|
|
2076
|
-
}
|
|
2077
|
-
const toRef = Editor.pathRef(editor, to);
|
|
2078
|
-
const targets = Editor.nodes(editor, { at, match, mode, voids });
|
|
2079
|
-
const pathRefs2 = Array.from(targets, ([, p]) => Editor.pathRef(editor, p));
|
|
2080
|
-
for (const pathRef2 of pathRefs2) {
|
|
2081
|
-
const path2 = pathRef2.unref();
|
|
2082
|
-
const newPath = toRef.current;
|
|
2083
|
-
if (path2.length !== 0) {
|
|
2084
|
-
editor.apply({ type: "move_node", path: path2, newPath });
|
|
2085
|
-
}
|
|
2086
|
-
if (toRef.current && Path.isSibling(newPath, path2) && Path.isAfter(newPath, path2)) {
|
|
2087
|
-
toRef.current = Path.next(toRef.current);
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
toRef.unref();
|
|
2091
|
-
});
|
|
2092
|
-
};
|
|
2093
|
-
const removeNodes = (editor, options = {}) => {
|
|
2094
|
-
Editor.withoutNormalizing(editor, () => {
|
|
2095
|
-
const { hanging = false, voids = false, mode = "lowest" } = options;
|
|
2096
|
-
let { at = editor.selection, match } = options;
|
|
2097
|
-
if (!at) {
|
|
2098
|
-
return;
|
|
2099
|
-
}
|
|
2100
|
-
if (match == null) {
|
|
2101
|
-
match = Path.isPath(at) ? matchPath(editor, at) : (n) => Element.isElement(n) && Editor.isBlock(editor, n);
|
|
2102
|
-
}
|
|
2103
|
-
if (!hanging && Range.isRange(at)) {
|
|
2104
|
-
at = Editor.unhangRange(editor, at, { voids });
|
|
2105
|
-
}
|
|
2106
|
-
const depths = Editor.nodes(editor, { at, match, mode, voids });
|
|
2107
|
-
const pathRefs2 = Array.from(depths, ([, p]) => Editor.pathRef(editor, p));
|
|
2108
|
-
for (const pathRef2 of pathRefs2) {
|
|
2109
|
-
const path2 = pathRef2.unref();
|
|
2110
|
-
if (path2) {
|
|
2111
|
-
const [node2] = Editor.node(editor, path2);
|
|
2112
|
-
editor.apply({ type: "remove_node", path: path2, node: node2 });
|
|
2113
|
-
}
|
|
2114
|
-
}
|
|
2115
|
-
});
|
|
2116
|
-
};
|
|
2117
|
-
const setNodes = (editor, props, options = {}) => {
|
|
2118
|
-
Editor.withoutNormalizing(editor, () => {
|
|
2119
|
-
let { match, at = cloneDeep(editor.selection), compare, merge } = options;
|
|
2120
|
-
const {
|
|
2121
|
-
hanging = false,
|
|
2122
|
-
mode = "lowest",
|
|
2123
|
-
split = false,
|
|
2124
|
-
voids = false
|
|
2125
|
-
} = options;
|
|
2126
|
-
if (!at) {
|
|
2127
|
-
return;
|
|
2128
|
-
}
|
|
2129
|
-
if (match == null) {
|
|
2130
|
-
match = Path.isPath(at) ? matchPath(editor, at) : (n) => Element.isElement(n) && Editor.isBlock(editor, n);
|
|
2131
|
-
}
|
|
2132
|
-
if (!hanging && Range.isRange(at)) {
|
|
2133
|
-
at = Editor.unhangRange(editor, at, { voids });
|
|
2134
|
-
}
|
|
2135
|
-
if (split && Range.isRange(at)) {
|
|
2136
|
-
if (Range.isCollapsed(at) && Editor.leaf(editor, at.anchor)[0].text.length > 0) {
|
|
2137
|
-
return;
|
|
2138
|
-
}
|
|
2139
|
-
const rangeRef2 = Editor.rangeRef(editor, at, { affinity: "inward" });
|
|
2140
|
-
const [start2, end2] = Range.edges(at);
|
|
2141
|
-
const splitMode = mode === "lowest" ? "lowest" : "highest";
|
|
2142
|
-
const endAtEndOfNode = Editor.isEnd(editor, end2, end2.path);
|
|
2143
|
-
Transforms.splitNodes(editor, {
|
|
2144
|
-
at: end2,
|
|
2145
|
-
match,
|
|
2146
|
-
mode: splitMode,
|
|
2147
|
-
voids,
|
|
2148
|
-
always: !endAtEndOfNode
|
|
2149
|
-
});
|
|
2150
|
-
const startAtStartOfNode = Editor.isStart(editor, start2, start2.path);
|
|
2151
|
-
Transforms.splitNodes(editor, {
|
|
2152
|
-
at: start2,
|
|
2153
|
-
match,
|
|
2154
|
-
mode: splitMode,
|
|
2155
|
-
voids,
|
|
2156
|
-
always: !startAtStartOfNode
|
|
2157
|
-
});
|
|
2158
|
-
at = rangeRef2.unref();
|
|
2159
|
-
if (options.at == null) {
|
|
2160
|
-
Transforms.select(editor, at);
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
if (!compare) {
|
|
2164
|
-
compare = (prop, nodeProp) => prop !== nodeProp;
|
|
2165
|
-
}
|
|
2166
|
-
for (const [node2, path2] of Editor.nodes(editor, {
|
|
2167
|
-
at,
|
|
2168
|
-
match,
|
|
2169
|
-
mode,
|
|
2170
|
-
voids
|
|
2171
|
-
})) {
|
|
2172
|
-
const properties = {};
|
|
2173
|
-
const newProperties = {};
|
|
2174
|
-
if (path2.length === 0) {
|
|
2175
|
-
continue;
|
|
2176
|
-
}
|
|
2177
|
-
let hasChanges = false;
|
|
2178
|
-
for (const k in props) {
|
|
2179
|
-
if (k === "children" || k === "text") {
|
|
2180
|
-
continue;
|
|
2181
|
-
}
|
|
2182
|
-
if (compare(props[k], node2[k])) {
|
|
2183
|
-
hasChanges = true;
|
|
2184
|
-
if (node2.hasOwnProperty(k))
|
|
2185
|
-
properties[k] = node2[k];
|
|
2186
|
-
if (merge) {
|
|
2187
|
-
if (props[k] != null)
|
|
2188
|
-
newProperties[k] = merge(
|
|
2189
|
-
node2[k],
|
|
2190
|
-
props[k]
|
|
2191
|
-
);
|
|
2192
|
-
} else {
|
|
2193
|
-
if (props[k] != null)
|
|
2194
|
-
newProperties[k] = props[k];
|
|
2195
|
-
}
|
|
2196
|
-
}
|
|
2197
|
-
}
|
|
2198
|
-
if (hasChanges) {
|
|
2199
|
-
editor.apply({
|
|
2200
|
-
type: "set_node",
|
|
2201
|
-
path: path2,
|
|
2202
|
-
properties,
|
|
2203
|
-
newProperties
|
|
2204
|
-
});
|
|
2205
|
-
}
|
|
2206
|
-
}
|
|
2207
|
-
});
|
|
2208
|
-
};
|
|
2209
|
-
const deleteRange = (editor, range2) => {
|
|
2210
|
-
if (Range.isCollapsed(range2)) {
|
|
2211
|
-
return range2.anchor;
|
|
2212
|
-
} else {
|
|
2213
|
-
const [, end2] = Range.edges(range2);
|
|
2214
|
-
const pointRef2 = Editor.pointRef(editor, end2);
|
|
2215
|
-
Transforms.delete(editor, { at: range2 });
|
|
2216
|
-
return pointRef2.unref();
|
|
2217
|
-
}
|
|
2218
|
-
};
|
|
2219
|
-
const splitNodes = (editor, options = {}) => {
|
|
2220
|
-
Editor.withoutNormalizing(editor, () => {
|
|
2221
|
-
const { mode = "lowest", voids = false } = options;
|
|
2222
|
-
let { match, at = cloneDeep(editor.selection), height = 0, always = false } = options;
|
|
2223
|
-
if (match == null) {
|
|
2224
|
-
match = (n) => Element.isElement(n) && Editor.isBlock(editor, n);
|
|
2225
|
-
}
|
|
2226
|
-
if (Range.isRange(at)) {
|
|
2227
|
-
at = deleteRange(editor, at);
|
|
2228
|
-
}
|
|
2229
|
-
if (Path.isPath(at)) {
|
|
2230
|
-
const path2 = at;
|
|
2231
|
-
const point2 = Editor.point(editor, path2);
|
|
2232
|
-
const [parent2] = Editor.parent(editor, path2);
|
|
2233
|
-
match = (n) => n === parent2;
|
|
2234
|
-
height = point2.path.length - path2.length + 1;
|
|
2235
|
-
at = point2;
|
|
2236
|
-
always = true;
|
|
2237
|
-
}
|
|
2238
|
-
if (!at) {
|
|
2239
|
-
return;
|
|
2240
|
-
}
|
|
2241
|
-
const beforeRef = Editor.pointRef(editor, at, {
|
|
2242
|
-
affinity: "backward"
|
|
2243
|
-
});
|
|
2244
|
-
let afterRef;
|
|
2245
|
-
try {
|
|
2246
|
-
const [highest] = Editor.nodes(editor, { at, match, mode, voids });
|
|
2247
|
-
if (!highest) {
|
|
2248
|
-
return;
|
|
2249
|
-
}
|
|
2250
|
-
const voidMatch = Editor.void(editor, { at, mode: "highest" });
|
|
2251
|
-
const nudge = 0;
|
|
2252
|
-
if (!voids && voidMatch) {
|
|
2253
|
-
const [voidNode, voidPath] = voidMatch;
|
|
2254
|
-
if (Element.isElement(voidNode) && editor.isInline(voidNode)) {
|
|
2255
|
-
let after2 = Editor.after(editor, voidPath);
|
|
2256
|
-
if (!after2) {
|
|
2257
|
-
const text = { text: "" };
|
|
2258
|
-
const afterPath = Path.next(voidPath);
|
|
2259
|
-
Transforms.insertNodes(editor, text, { at: afterPath, voids });
|
|
2260
|
-
after2 = Editor.point(editor, afterPath);
|
|
2261
|
-
}
|
|
2262
|
-
at = after2;
|
|
2263
|
-
always = true;
|
|
2264
|
-
}
|
|
2265
|
-
const siblingHeight = at.path.length - voidPath.length;
|
|
2266
|
-
height = siblingHeight + 1;
|
|
2267
|
-
always = true;
|
|
2268
|
-
}
|
|
2269
|
-
afterRef = Editor.pointRef(editor, at);
|
|
2270
|
-
const depth = at.path.length - height;
|
|
2271
|
-
const [, highestPath] = highest;
|
|
2272
|
-
const lowestPath = at.path.slice(0, depth);
|
|
2273
|
-
let position = height === 0 ? at.offset : at.path[depth] + nudge;
|
|
2274
|
-
for (const [node2, path2] of Editor.levels(editor, {
|
|
2275
|
-
at: lowestPath,
|
|
2276
|
-
reverse: true,
|
|
2277
|
-
voids
|
|
2278
|
-
})) {
|
|
2279
|
-
let split = false;
|
|
2280
|
-
if (path2.length < highestPath.length || path2.length === 0 || !voids && Element.isElement(node2) && Editor.isVoid(editor, node2)) {
|
|
2281
|
-
break;
|
|
2282
|
-
}
|
|
2283
|
-
const point2 = beforeRef.current;
|
|
2284
|
-
const isEnd2 = Editor.isEnd(editor, point2, path2);
|
|
2285
|
-
if (always || !beforeRef || !Editor.isEdge(editor, point2, path2)) {
|
|
2286
|
-
split = true;
|
|
2287
|
-
const properties = Node.extractProps(node2);
|
|
2288
|
-
editor.apply({
|
|
2289
|
-
type: "split_node",
|
|
2290
|
-
path: path2,
|
|
2291
|
-
position,
|
|
2292
|
-
properties
|
|
2293
|
-
});
|
|
2294
|
-
}
|
|
2295
|
-
position = path2[path2.length - 1] + (split || isEnd2 ? 1 : 0);
|
|
2296
|
-
}
|
|
2297
|
-
if (options.at == null) {
|
|
2298
|
-
const point2 = afterRef.current || Editor.end(editor, []);
|
|
2299
|
-
Transforms.select(editor, point2);
|
|
2300
|
-
}
|
|
2301
|
-
} finally {
|
|
2302
|
-
beforeRef.unref();
|
|
2303
|
-
afterRef == null ? void 0 : afterRef.unref();
|
|
2304
|
-
}
|
|
2305
|
-
});
|
|
2306
|
-
};
|
|
2307
|
-
const unsetNodes = (editor, props, options = {}) => {
|
|
2308
|
-
if (!Array.isArray(props)) {
|
|
2309
|
-
props = [props];
|
|
2310
|
-
}
|
|
2311
|
-
const obj = {};
|
|
2312
|
-
for (const key of props) {
|
|
2313
|
-
obj[key] = null;
|
|
2314
|
-
}
|
|
2315
|
-
Transforms.setNodes(editor, obj, options);
|
|
2316
|
-
};
|
|
2317
|
-
const unwrapNodes = (editor, options = {}) => {
|
|
2318
|
-
Editor.withoutNormalizing(editor, () => {
|
|
2319
|
-
const { mode = "lowest", split = false, voids = false } = options;
|
|
2320
|
-
let { at = cloneDeep(editor.selection), match } = options;
|
|
2321
|
-
if (!at) {
|
|
2322
|
-
return;
|
|
2323
|
-
}
|
|
2324
|
-
if (match == null) {
|
|
2325
|
-
match = Path.isPath(at) ? matchPath(editor, at) : (n) => Element.isElement(n) && Editor.isBlock(editor, n);
|
|
2326
|
-
}
|
|
2327
|
-
if (Path.isPath(at)) {
|
|
2328
|
-
at = Editor.range(editor, at);
|
|
2329
|
-
}
|
|
2330
|
-
const rangeRef2 = Range.isRange(at) ? Editor.rangeRef(editor, at) : null;
|
|
2331
|
-
const matches = Editor.nodes(editor, { at, match, mode, voids });
|
|
2332
|
-
const pathRefs2 = Array.from(
|
|
2333
|
-
matches,
|
|
2334
|
-
([, p]) => Editor.pathRef(editor, p)
|
|
2335
|
-
// unwrapNode will call liftNode which does not support splitting the node when nested.
|
|
2336
|
-
// If we do not reverse the order and call it from top to the bottom, it will remove all blocks
|
|
2337
|
-
// that wrap target node. So we reverse the order.
|
|
2338
|
-
).reverse();
|
|
2339
|
-
for (const pathRef2 of pathRefs2) {
|
|
2340
|
-
const path2 = pathRef2.unref();
|
|
2341
|
-
const [node2] = Editor.node(editor, path2);
|
|
2342
|
-
let range2 = Editor.range(editor, path2);
|
|
2343
|
-
if (split && rangeRef2) {
|
|
2344
|
-
range2 = Range.intersection(rangeRef2.current, range2);
|
|
2345
|
-
}
|
|
2346
|
-
Transforms.liftNodes(editor, {
|
|
2347
|
-
at: range2,
|
|
2348
|
-
match: (n) => Element.isAncestor(node2) && node2.children.includes(n),
|
|
2349
|
-
voids
|
|
2350
|
-
});
|
|
2351
|
-
}
|
|
2352
|
-
if (rangeRef2) {
|
|
2353
|
-
rangeRef2.unref();
|
|
2354
|
-
}
|
|
2355
|
-
});
|
|
2356
|
-
};
|
|
2357
|
-
const wrapNodes = (editor, element, options = {}) => {
|
|
2358
|
-
Editor.withoutNormalizing(editor, () => {
|
|
2359
|
-
const { mode = "lowest", split = false, voids = false } = options;
|
|
2360
|
-
let { match, at = cloneDeep(editor.selection) } = options;
|
|
2361
|
-
if (!at) {
|
|
2362
|
-
return;
|
|
2363
|
-
}
|
|
2364
|
-
if (match == null) {
|
|
2365
|
-
if (Path.isPath(at)) {
|
|
2366
|
-
match = matchPath(editor, at);
|
|
2367
|
-
} else if (editor.isInline(element)) {
|
|
2368
|
-
match = (n) => Element.isElement(n) && Editor.isInline(editor, n) || Text.isText(n);
|
|
2369
|
-
} else {
|
|
2370
|
-
match = (n) => Element.isElement(n) && Editor.isBlock(editor, n);
|
|
2371
|
-
}
|
|
2372
|
-
}
|
|
2373
|
-
if (split && Range.isRange(at)) {
|
|
2374
|
-
const [start2, end2] = Range.edges(at);
|
|
2375
|
-
const rangeRef2 = Editor.rangeRef(editor, at, {
|
|
2376
|
-
affinity: "inward"
|
|
2377
|
-
});
|
|
2378
|
-
Transforms.splitNodes(editor, { at: end2, match, voids });
|
|
2379
|
-
Transforms.splitNodes(editor, { at: start2, match, voids });
|
|
2380
|
-
at = rangeRef2.unref();
|
|
2381
|
-
if (options.at == null) {
|
|
2382
|
-
Transforms.select(editor, at);
|
|
2383
|
-
}
|
|
2384
|
-
}
|
|
2385
|
-
const roots = Array.from(
|
|
2386
|
-
Editor.nodes(editor, {
|
|
2387
|
-
at,
|
|
2388
|
-
match: editor.isInline(element) ? (n) => Element.isElement(n) && Editor.isBlock(editor, n) : (n) => Editor.isEditor(n),
|
|
2389
|
-
mode: "lowest",
|
|
2390
|
-
voids
|
|
2391
|
-
})
|
|
2392
|
-
);
|
|
2393
|
-
for (const [, rootPath] of roots) {
|
|
2394
|
-
const a = Range.isRange(at) ? Range.intersection(at, Editor.range(editor, rootPath)) : at;
|
|
2395
|
-
if (!a) {
|
|
2396
|
-
continue;
|
|
2397
|
-
}
|
|
2398
|
-
const matches = Array.from(
|
|
2399
|
-
Editor.nodes(editor, { at: a, match, mode, voids })
|
|
2400
|
-
);
|
|
2401
|
-
if (matches.length > 0) {
|
|
2402
|
-
const [first2] = matches;
|
|
2403
|
-
const last2 = matches[matches.length - 1];
|
|
2404
|
-
const [, firstPath] = first2;
|
|
2405
|
-
const [, lastPath] = last2;
|
|
2406
|
-
if (firstPath.length === 0 && lastPath.length === 0) {
|
|
2407
|
-
continue;
|
|
2408
|
-
}
|
|
2409
|
-
const commonPath = Path.equals(firstPath, lastPath) ? Path.parent(firstPath) : Path.common(firstPath, lastPath);
|
|
2410
|
-
const range2 = Editor.range(editor, firstPath, lastPath);
|
|
2411
|
-
const commonNodeEntry = Editor.node(editor, commonPath);
|
|
2412
|
-
const [commonNode] = commonNodeEntry;
|
|
2413
|
-
const depth = commonPath.length + 1;
|
|
2414
|
-
const wrapperPath = Path.next(lastPath.slice(0, depth));
|
|
2415
|
-
const wrapper = { ...element, children: [] };
|
|
2416
|
-
Transforms.insertNodes(editor, wrapper, { at: wrapperPath, voids });
|
|
2417
|
-
Transforms.moveNodes(editor, {
|
|
2418
|
-
at: range2,
|
|
2419
|
-
match: (n) => Element.isAncestor(commonNode) && commonNode.children.includes(n),
|
|
2420
|
-
to: wrapperPath.concat(0),
|
|
2421
|
-
voids
|
|
2422
|
-
});
|
|
2423
|
-
}
|
|
2424
|
-
}
|
|
2425
|
-
});
|
|
2426
|
-
};
|
|
2427
|
-
const createEditor = (children) => {
|
|
2428
|
-
const editor = reactive({
|
|
2429
|
-
children,
|
|
2430
|
-
operations: [],
|
|
2431
|
-
selection: null,
|
|
2432
|
-
marks: null,
|
|
2433
|
-
isElementReadOnly: () => false,
|
|
2434
|
-
isInline: () => false,
|
|
2435
|
-
isSelectable: () => true,
|
|
2436
|
-
isVoid: () => false,
|
|
2437
|
-
markableVoid: () => false,
|
|
2438
|
-
onChange: () => {
|
|
2439
|
-
},
|
|
2440
|
-
// Core
|
|
2441
|
-
apply: (...args) => apply(editor, ...args),
|
|
2442
|
-
// Editor
|
|
2443
|
-
addMark: (...args) => addMark(editor, ...args),
|
|
2444
|
-
deleteBackward: (...args) => deleteBackward(editor, ...args),
|
|
2445
|
-
deleteForward: (...args) => deleteForward(editor, ...args),
|
|
2446
|
-
deleteFragment: (...args) => deleteFragment(editor, ...args),
|
|
2447
|
-
getFragment: (...args) => getFragment(editor, ...args),
|
|
2448
|
-
insertBreak: (...args) => insertBreak(editor, ...args),
|
|
2449
|
-
insertSoftBreak: (...args) => insertSoftBreak(editor, ...args),
|
|
2450
|
-
insertFragment: (...args) => insertFragment(editor, ...args),
|
|
2451
|
-
insertNode: (...args) => insertNode(editor, ...args),
|
|
2452
|
-
insertText: (...args) => insertText(editor, ...args),
|
|
2453
|
-
normalizeNode: (...args) => normalizeNode(editor, ...args),
|
|
2454
|
-
removeMark: (...args) => removeMark(editor, ...args),
|
|
2455
|
-
getDirtyPaths: (...args) => getDirtyPaths(editor, ...args),
|
|
2456
|
-
shouldNormalize: (...args) => shouldNormalize(editor, ...args),
|
|
2457
|
-
// Editor interface
|
|
2458
|
-
above: (...args) => above(editor, ...args),
|
|
2459
|
-
after: (...args) => after(editor, ...args),
|
|
2460
|
-
before: (...args) => before(editor, ...args),
|
|
2461
|
-
collapse: (...args) => collapse(editor, ...args),
|
|
2462
|
-
delete: (...args) => deleteText(editor, ...args),
|
|
2463
|
-
deselect: (...args) => deselect(editor, ...args),
|
|
2464
|
-
edges: (...args) => edges(editor, ...args),
|
|
2465
|
-
elementReadOnly: (...args) => elementReadOnly(editor, ...args),
|
|
2466
|
-
end: (...args) => end(editor, ...args),
|
|
2467
|
-
first: (...args) => first(editor, ...args),
|
|
2468
|
-
fragment: (...args) => fragment(editor, ...args),
|
|
2469
|
-
getMarks: (...args) => marks(editor, ...args),
|
|
2470
|
-
hasBlocks: (...args) => hasBlocks(editor, ...args),
|
|
2471
|
-
hasInlines: (...args) => hasInlines(editor, ...args),
|
|
2472
|
-
hasPath: (...args) => hasPath(editor, ...args),
|
|
2473
|
-
hasTexts: (...args) => hasTexts(editor, ...args),
|
|
2474
|
-
insertNodes: (...args) => insertNodes(editor, ...args),
|
|
2475
|
-
isBlock: (...args) => isBlock(editor, ...args),
|
|
2476
|
-
isEdge: (...args) => isEdge(editor, ...args),
|
|
2477
|
-
isEmpty: (...args) => isEmpty(editor, ...args),
|
|
2478
|
-
isEnd: (...args) => isEnd(editor, ...args),
|
|
2479
|
-
isNormalizing: (...args) => isNormalizing(editor, ...args),
|
|
2480
|
-
isStart: (...args) => isStart(editor, ...args),
|
|
2481
|
-
last: (...args) => last(editor, ...args),
|
|
2482
|
-
leaf: (...args) => leaf(editor, ...args),
|
|
2483
|
-
levels: (...args) => levels(editor, ...args),
|
|
2484
|
-
liftNodes: (...args) => liftNodes(editor, ...args),
|
|
2485
|
-
mergeNodes: (...args) => mergeNodes(editor, ...args),
|
|
2486
|
-
move: (...args) => move(editor, ...args),
|
|
2487
|
-
moveNodes: (...args) => moveNodes(editor, ...args),
|
|
2488
|
-
next: (...args) => next(editor, ...args),
|
|
2489
|
-
node: (...args) => node(editor, ...args),
|
|
2490
|
-
nodes: (...args) => nodes(editor, ...args),
|
|
2491
|
-
normalize: (...args) => normalize(editor, ...args),
|
|
2492
|
-
parent: (...args) => parent(editor, ...args),
|
|
2493
|
-
path: (...args) => path(editor, ...args),
|
|
2494
|
-
pathRef: (...args) => pathRef(editor, ...args),
|
|
2495
|
-
pathRefs: (...args) => pathRefs(editor, ...args),
|
|
2496
|
-
point: (...args) => point(editor, ...args),
|
|
2497
|
-
pointRef: (...args) => pointRef(editor, ...args),
|
|
2498
|
-
pointRefs: (...args) => pointRefs(editor, ...args),
|
|
2499
|
-
positions: (...args) => positions(editor, ...args),
|
|
2500
|
-
previous: (...args) => previous(editor, ...args),
|
|
2501
|
-
range: (...args) => range(editor, ...args),
|
|
2502
|
-
rangeRef: (...args) => rangeRef(editor, ...args),
|
|
2503
|
-
rangeRefs: (...args) => rangeRefs(editor, ...args),
|
|
2504
|
-
removeNodes: (...args) => removeNodes(editor, ...args),
|
|
2505
|
-
select: (...args) => select(editor, ...args),
|
|
2506
|
-
setNodes: (...args) => setNodes(editor, ...args),
|
|
2507
|
-
setNormalizing: (...args) => setNormalizing(editor, ...args),
|
|
2508
|
-
setPoint: (...args) => setPoint(editor, ...args),
|
|
2509
|
-
setSelection: (...args) => setSelection(editor, ...args),
|
|
2510
|
-
splitNodes: (...args) => splitNodes(editor, ...args),
|
|
2511
|
-
start: (...args) => start(editor, ...args),
|
|
2512
|
-
string: (...args) => string(editor, ...args),
|
|
2513
|
-
unhangRange: (...args) => unhangRange(editor, ...args),
|
|
2514
|
-
unsetNodes: (...args) => unsetNodes(editor, ...args),
|
|
2515
|
-
unwrapNodes: (...args) => unwrapNodes(editor, ...args),
|
|
2516
|
-
void: (...args) => getVoid(editor, ...args),
|
|
2517
|
-
withoutNormalizing: (...args) => withoutNormalizing(editor, ...args),
|
|
2518
|
-
wrapNodes: (...args) => wrapNodes(editor, ...args),
|
|
2519
|
-
shouldMergeNodesRemovePrevNode: (...args) => shouldMergeNodesRemovePrevNode(editor, ...args)
|
|
2520
|
-
});
|
|
2521
|
-
return editor;
|
|
2522
|
-
};
|
|
1
|
+
import { a6, a8, a9, aa, a7, d, e, f, a, h, al, c, i, j, k, ar, am, l, m, o, p, q, g, b, r, t, u, v, w, x, as, y, ab, z, A, B, C, D, E, F, G, H, I, J, ac, K, ad, an, ae, L, M, N, O, n, P, S, Q, R, V, T, U, W, X, _, Y, Z, $, af, ao, ag, a0, ap, aq, a5, s, ah, a1, a2, a3, ai, aj, a4, ak } from "./create-editor-BP4gf1UN.js";
|
|
2
|
+
import { E as E2, a as a10, N as N2, O as O2, P as P2, b as b2, R as R2, S as S2, T as T2, c as c2, i as i2 } from "./batch-dirty-paths-CZqHWmdq.js";
|
|
2523
3
|
export {
|
|
2524
|
-
Editor,
|
|
2525
|
-
Element,
|
|
2526
|
-
Location,
|
|
2527
|
-
Node,
|
|
2528
|
-
|
|
2529
|
-
Path,
|
|
2530
|
-
PathRef,
|
|
2531
|
-
Point,
|
|
2532
|
-
PointRef,
|
|
2533
|
-
Range,
|
|
2534
|
-
RangeRef,
|
|
2535
|
-
Scrubber,
|
|
2536
|
-
Span,
|
|
2537
|
-
Text,
|
|
2538
|
-
Transforms,
|
|
2539
|
-
above,
|
|
2540
|
-
addMark,
|
|
2541
|
-
after,
|
|
2542
|
-
apply,
|
|
2543
|
-
before,
|
|
2544
|
-
collapse,
|
|
2545
|
-
createEditor,
|
|
2546
|
-
deleteBackward,
|
|
2547
|
-
deleteForward,
|
|
2548
|
-
deleteFragment,
|
|
2549
|
-
deleteText,
|
|
2550
|
-
deselect,
|
|
2551
|
-
edges,
|
|
2552
|
-
elementReadOnly,
|
|
2553
|
-
end,
|
|
2554
|
-
first,
|
|
2555
|
-
fragment,
|
|
2556
|
-
getDirtyPaths,
|
|
2557
|
-
getFragment,
|
|
2558
|
-
getVoid,
|
|
2559
|
-
hasBlocks,
|
|
2560
|
-
hasInlines,
|
|
2561
|
-
hasPath,
|
|
2562
|
-
hasTexts,
|
|
2563
|
-
insertBreak,
|
|
2564
|
-
insertFragment,
|
|
2565
|
-
insertNode,
|
|
2566
|
-
insertNodes,
|
|
2567
|
-
insertSoftBreak,
|
|
2568
|
-
insertText,
|
|
2569
|
-
isBlock,
|
|
2570
|
-
isEdge,
|
|
2571
|
-
|
|
2572
|
-
isEmpty,
|
|
2573
|
-
isEnd,
|
|
2574
|
-
isNormalizing,
|
|
2575
|
-
isStart,
|
|
2576
|
-
last,
|
|
2577
|
-
leaf,
|
|
2578
|
-
levels,
|
|
2579
|
-
liftNodes,
|
|
2580
|
-
marks,
|
|
2581
|
-
mergeNodes,
|
|
2582
|
-
move,
|
|
2583
|
-
moveNodes,
|
|
2584
|
-
next,
|
|
2585
|
-
node,
|
|
2586
|
-
nodes,
|
|
2587
|
-
normalize,
|
|
2588
|
-
normalizeNode,
|
|
2589
|
-
parent,
|
|
2590
|
-
path,
|
|
2591
|
-
pathRef,
|
|
2592
|
-
pathRefs,
|
|
2593
|
-
point,
|
|
2594
|
-
pointRef,
|
|
2595
|
-
pointRefs,
|
|
2596
|
-
positions,
|
|
2597
|
-
previous,
|
|
2598
|
-
range,
|
|
2599
|
-
rangeRef,
|
|
2600
|
-
rangeRefs,
|
|
2601
|
-
removeMark,
|
|
2602
|
-
removeNodes,
|
|
2603
|
-
select,
|
|
2604
|
-
setNodes,
|
|
2605
|
-
setNormalizing,
|
|
2606
|
-
setPoint,
|
|
2607
|
-
setSelection,
|
|
2608
|
-
shouldMergeNodesRemovePrevNode,
|
|
2609
|
-
shouldNormalize,
|
|
2610
|
-
splitNodes,
|
|
2611
|
-
start,
|
|
2612
|
-
string,
|
|
2613
|
-
unhangRange,
|
|
2614
|
-
unsetNodes,
|
|
2615
|
-
unwrapNodes,
|
|
2616
|
-
withoutNormalizing,
|
|
2617
|
-
wrapNodes
|
|
4
|
+
E2 as Editor,
|
|
5
|
+
a10 as Element,
|
|
6
|
+
a6 as Location,
|
|
7
|
+
N2 as Node,
|
|
8
|
+
O2 as Operation,
|
|
9
|
+
P2 as Path,
|
|
10
|
+
a8 as PathRef,
|
|
11
|
+
b2 as Point,
|
|
12
|
+
a9 as PointRef,
|
|
13
|
+
R2 as Range,
|
|
14
|
+
aa as RangeRef,
|
|
15
|
+
S2 as Scrubber,
|
|
16
|
+
a7 as Span,
|
|
17
|
+
T2 as Text,
|
|
18
|
+
c2 as Transforms,
|
|
19
|
+
d as above,
|
|
20
|
+
e as addMark,
|
|
21
|
+
f as after,
|
|
22
|
+
a as apply,
|
|
23
|
+
h as before,
|
|
24
|
+
al as collapse,
|
|
25
|
+
c as createEditor,
|
|
26
|
+
i as deleteBackward,
|
|
27
|
+
j as deleteForward,
|
|
28
|
+
k as deleteFragment,
|
|
29
|
+
ar as deleteText,
|
|
30
|
+
am as deselect,
|
|
31
|
+
l as edges,
|
|
32
|
+
m as elementReadOnly,
|
|
33
|
+
o as end,
|
|
34
|
+
p as first,
|
|
35
|
+
q as fragment,
|
|
36
|
+
g as getDirtyPaths,
|
|
37
|
+
b as getFragment,
|
|
38
|
+
r as getVoid,
|
|
39
|
+
t as hasBlocks,
|
|
40
|
+
u as hasInlines,
|
|
41
|
+
v as hasPath,
|
|
42
|
+
w as hasTexts,
|
|
43
|
+
x as insertBreak,
|
|
44
|
+
as as insertFragment,
|
|
45
|
+
y as insertNode,
|
|
46
|
+
ab as insertNodes,
|
|
47
|
+
z as insertSoftBreak,
|
|
48
|
+
A as insertText,
|
|
49
|
+
B as isBlock,
|
|
50
|
+
C as isEdge,
|
|
51
|
+
i2 as isEditor,
|
|
52
|
+
D as isEmpty,
|
|
53
|
+
E as isEnd,
|
|
54
|
+
F as isNormalizing,
|
|
55
|
+
G as isStart,
|
|
56
|
+
H as last,
|
|
57
|
+
I as leaf,
|
|
58
|
+
J as levels,
|
|
59
|
+
ac as liftNodes,
|
|
60
|
+
K as marks,
|
|
61
|
+
ad as mergeNodes,
|
|
62
|
+
an as move,
|
|
63
|
+
ae as moveNodes,
|
|
64
|
+
L as next,
|
|
65
|
+
M as node,
|
|
66
|
+
N as nodes,
|
|
67
|
+
O as normalize,
|
|
68
|
+
n as normalizeNode,
|
|
69
|
+
P as parent,
|
|
70
|
+
S as path,
|
|
71
|
+
Q as pathRef,
|
|
72
|
+
R as pathRefs,
|
|
73
|
+
V as point,
|
|
74
|
+
T as pointRef,
|
|
75
|
+
U as pointRefs,
|
|
76
|
+
W as positions,
|
|
77
|
+
X as previous,
|
|
78
|
+
_ as range,
|
|
79
|
+
Y as rangeRef,
|
|
80
|
+
Z as rangeRefs,
|
|
81
|
+
$ as removeMark,
|
|
82
|
+
af as removeNodes,
|
|
83
|
+
ao as select,
|
|
84
|
+
ag as setNodes,
|
|
85
|
+
a0 as setNormalizing,
|
|
86
|
+
ap as setPoint,
|
|
87
|
+
aq as setSelection,
|
|
88
|
+
a5 as shouldMergeNodesRemovePrevNode,
|
|
89
|
+
s as shouldNormalize,
|
|
90
|
+
ah as splitNodes,
|
|
91
|
+
a1 as start,
|
|
92
|
+
a2 as string,
|
|
93
|
+
a3 as unhangRange,
|
|
94
|
+
ai as unsetNodes,
|
|
95
|
+
aj as unwrapNodes,
|
|
96
|
+
a4 as withoutNormalizing,
|
|
97
|
+
ak as wrapNodes
|
|
2618
98
|
};
|