1 | import React, { useLayoutEffect, useEffect, useRef, useState, Fragment, useContext, createContext, useMemo, useCallback } from 'react';
|
2 | import { Path, Node, Editor, Text as Text$1, Range, Element as Element$1, Transforms } from 'slate';
|
3 | import getDirection from 'direction';
|
4 | import debounce from 'lodash/debounce';
|
5 | import throttle from 'lodash/throttle';
|
6 | import scrollIntoView from 'scroll-into-view-if-needed';
|
7 | import { isKeyHotkey } from 'is-hotkey';
|
8 | import ReactDOM from 'react-dom';
|
9 |
|
10 | function _defineProperty(obj, key, value) {
|
11 | if (key in obj) {
|
12 | Object.defineProperty(obj, key, {
|
13 | value: value,
|
14 | enumerable: true,
|
15 | configurable: true,
|
16 | writable: true
|
17 | });
|
18 | } else {
|
19 | obj[key] = value;
|
20 | }
|
21 |
|
22 | return obj;
|
23 | }
|
24 |
|
25 | function _objectWithoutPropertiesLoose(source, excluded) {
|
26 | if (source == null) return {};
|
27 | var target = {};
|
28 | var sourceKeys = Object.keys(source);
|
29 | var key, i;
|
30 |
|
31 | for (i = 0; i < sourceKeys.length; i++) {
|
32 | key = sourceKeys[i];
|
33 | if (excluded.indexOf(key) >= 0) continue;
|
34 | target[key] = source[key];
|
35 | }
|
36 |
|
37 | return target;
|
38 | }
|
39 |
|
40 | function _objectWithoutProperties(source, excluded) {
|
41 | if (source == null) return {};
|
42 | var target = _objectWithoutPropertiesLoose(source, excluded);
|
43 | var key, i;
|
44 |
|
45 | if (Object.getOwnPropertySymbols) {
|
46 | var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
|
47 |
|
48 | for (i = 0; i < sourceSymbolKeys.length; i++) {
|
49 | key = sourceSymbolKeys[i];
|
50 | if (excluded.indexOf(key) >= 0) continue;
|
51 | if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
52 | target[key] = source[key];
|
53 | }
|
54 | }
|
55 |
|
56 | return target;
|
57 | }
|
58 |
|
59 | var IS_IOS = typeof navigator !== 'undefined' && typeof window !== 'undefined' && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
60 | var IS_APPLE = typeof navigator !== 'undefined' && /Mac OS X/.test(navigator.userAgent);
|
61 | var IS_ANDROID = typeof navigator !== 'undefined' && /Android/.test(navigator.userAgent);
|
62 | var IS_FIREFOX = typeof navigator !== 'undefined' && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
|
63 | var IS_SAFARI = typeof navigator !== 'undefined' && /Version\/[\d\.]+.*Safari/.test(navigator.userAgent);
|
64 |
|
65 | var IS_EDGE_LEGACY = typeof navigator !== 'undefined' && /Edge?\/(?:[0-6][0-9]|[0-7][0-8])/i.test(navigator.userAgent);
|
66 | var IS_CHROME = typeof navigator !== 'undefined' && /Chrome/i.test(navigator.userAgent);
|
67 |
|
68 |
|
69 | var IS_CHROME_LEGACY = typeof navigator !== 'undefined' && /Chrome?\/(?:[0-7][0-5]|[0-6][0-9])/i.test(navigator.userAgent);
|
70 |
|
71 | var IS_FIREFOX_LEGACY = typeof navigator !== 'undefined' && /^(?!.*Seamonkey)(?=.*Firefox\/(?:[0-7][0-9]|[0-8][0-6])).*/i.test(navigator.userAgent);
|
72 |
|
73 | var IS_QQBROWSER = typeof navigator !== 'undefined' && /.*QQBrowser/.test(navigator.userAgent);
|
74 |
|
75 | var IS_UC_MOBILE = typeof navigator !== 'undefined' && /.*UCBrowser/.test(navigator.userAgent);
|
76 |
|
77 | var IS_WECHATBROWSER = typeof navigator !== 'undefined' && /.*Wechat/.test(navigator.userAgent);
|
78 |
|
79 |
|
80 | var CAN_USE_DOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
|
81 |
|
82 |
|
83 | var HAS_BEFORE_INPUT_SUPPORT = !IS_CHROME_LEGACY && !IS_EDGE_LEGACY &&
|
84 | typeof globalThis !== 'undefined' && globalThis.InputEvent &&
|
85 | typeof globalThis.InputEvent.prototype.getTargetRanges === 'function';
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 | var useIsomorphicLayoutEffect = CAN_USE_DOM ? useLayoutEffect : useEffect;
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | var String = props => {
|
98 | var {
|
99 | isLast,
|
100 | leaf,
|
101 | parent,
|
102 | text
|
103 | } = props;
|
104 | var editor = useSlateStatic();
|
105 | var path = ReactEditor.findPath(editor, text);
|
106 | var parentPath = Path.parent(path);
|
107 |
|
108 |
|
109 | if (editor.isVoid(parent)) {
|
110 | return React.createElement(ZeroWidthString, {
|
111 | length: Node.string(parent).length
|
112 | });
|
113 | }
|
114 |
|
115 |
|
116 |
|
117 |
|
118 | if (leaf.text === '' && parent.children[parent.children.length - 1] === text && !editor.isInline(parent) && Editor.string(editor, parentPath) === '') {
|
119 | return React.createElement(ZeroWidthString, {
|
120 | isLineBreak: true
|
121 | });
|
122 | }
|
123 |
|
124 |
|
125 |
|
126 |
|
127 | if (leaf.text === '') {
|
128 | return React.createElement(ZeroWidthString, null);
|
129 | }
|
130 |
|
131 |
|
132 |
|
133 | if (isLast && leaf.text.slice(-1) === '\n') {
|
134 | return React.createElement(TextString, {
|
135 | isTrailing: true,
|
136 | text: leaf.text
|
137 | });
|
138 | }
|
139 |
|
140 | return React.createElement(TextString, {
|
141 | text: leaf.text
|
142 | });
|
143 | };
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 | var TextString = props => {
|
150 | var {
|
151 | text,
|
152 | isTrailing = false
|
153 | } = props;
|
154 | var ref = useRef(null);
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 | useIsomorphicLayoutEffect(() => {
|
164 |
|
165 | var textWithTrailing = "".concat(text !== null && text !== void 0 ? text : '').concat(isTrailing ? '\n' : '');
|
166 |
|
167 | if (ref.current && ref.current.textContent !== textWithTrailing) {
|
168 | ref.current.textContent = textWithTrailing;
|
169 | }
|
170 |
|
171 |
|
172 | });
|
173 |
|
174 | return React.createElement("span", {
|
175 | "data-slate-string": true,
|
176 | ref: ref
|
177 | });
|
178 | };
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 | var ZeroWidthString = props => {
|
185 | var {
|
186 | length = 0,
|
187 | isLineBreak = false
|
188 | } = props;
|
189 | return React.createElement("span", {
|
190 | "data-slate-zero-width": isLineBreak ? 'n' : 'z',
|
191 | "data-slate-length": length
|
192 | }, '\uFEFF', isLineBreak ? React.createElement("br", null) : null);
|
193 | };
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 | var NODE_TO_INDEX = new WeakMap();
|
200 | var NODE_TO_PARENT = new WeakMap();
|
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 | var EDITOR_TO_WINDOW = new WeakMap();
|
207 | var EDITOR_TO_ELEMENT = new WeakMap();
|
208 | var ELEMENT_TO_NODE = new WeakMap();
|
209 | var NODE_TO_ELEMENT = new WeakMap();
|
210 | var NODE_TO_KEY = new WeakMap();
|
211 | var EDITOR_TO_KEY_TO_ELEMENT = new WeakMap();
|
212 |
|
213 |
|
214 |
|
215 |
|
216 | var IS_READ_ONLY = new WeakMap();
|
217 | var IS_FOCUSED = new WeakMap();
|
218 | var IS_COMPOSING = new WeakMap();
|
219 | var IS_ON_COMPOSITION_END = new WeakMap();
|
220 |
|
221 |
|
222 |
|
223 |
|
224 | var EDITOR_ON_COMPOSITION_TEXT = new WeakMap();
|
225 |
|
226 |
|
227 |
|
228 |
|
229 | var EDITOR_TO_ON_CHANGE = new WeakMap();
|
230 | var NODE_TO_RESTORE_DOM = new WeakMap();
|
231 |
|
232 |
|
233 |
|
234 |
|
235 | var PLACEHOLDER_SYMBOL = Symbol('placeholder');
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 | var Leaf = props => {
|
242 | var {
|
243 | leaf,
|
244 | isLast,
|
245 | text,
|
246 | parent,
|
247 | renderPlaceholder,
|
248 | renderLeaf = props => React.createElement(DefaultLeaf, Object.assign({}, props))
|
249 | } = props;
|
250 | var placeholderRef = useRef(null);
|
251 | useEffect(() => {
|
252 | var placeholderEl = placeholderRef === null || placeholderRef === void 0 ? void 0 : placeholderRef.current;
|
253 | var editorEl = document.querySelector('[data-slate-editor="true"]');
|
254 |
|
255 | if (!placeholderEl || !editorEl) {
|
256 | return;
|
257 | }
|
258 |
|
259 | editorEl.style.minHeight = "".concat(placeholderEl.clientHeight, "px");
|
260 | return () => {
|
261 | editorEl.style.minHeight = 'auto';
|
262 | };
|
263 | }, [placeholderRef, leaf]);
|
264 | var children = React.createElement(String, {
|
265 | isLast: isLast,
|
266 | leaf: leaf,
|
267 | parent: parent,
|
268 | text: text
|
269 | });
|
270 |
|
271 | if (leaf[PLACEHOLDER_SYMBOL]) {
|
272 | var placeholderProps = {
|
273 | children: leaf.placeholder,
|
274 | attributes: {
|
275 | 'data-slate-placeholder': true,
|
276 | style: {
|
277 | position: 'absolute',
|
278 | pointerEvents: 'none',
|
279 | width: '100%',
|
280 | maxWidth: '100%',
|
281 | display: 'block',
|
282 | opacity: '0.333',
|
283 | userSelect: 'none',
|
284 | textDecoration: 'none'
|
285 | },
|
286 | contentEditable: false,
|
287 | ref: placeholderRef
|
288 | }
|
289 | };
|
290 | children = React.createElement(React.Fragment, null, renderPlaceholder(placeholderProps), children);
|
291 | }
|
292 |
|
293 |
|
294 |
|
295 |
|
296 | var attributes = {
|
297 | 'data-slate-leaf': true
|
298 | };
|
299 | return renderLeaf({
|
300 | attributes,
|
301 | children,
|
302 | leaf,
|
303 | text
|
304 | });
|
305 | };
|
306 |
|
307 | var MemoizedLeaf = React.memo(Leaf, (prev, next) => {
|
308 | return next.parent === prev.parent && next.isLast === prev.isLast && next.renderLeaf === prev.renderLeaf && next.renderPlaceholder === prev.renderPlaceholder && next.text === prev.text && Text$1.equals(next.leaf, prev.leaf) && next.leaf[PLACEHOLDER_SYMBOL] === prev.leaf[PLACEHOLDER_SYMBOL];
|
309 | });
|
310 | var DefaultLeaf = props => {
|
311 | var {
|
312 | attributes,
|
313 | children
|
314 | } = props;
|
315 | return React.createElement("span", Object.assign({}, attributes), children);
|
316 | };
|
317 |
|
318 | var _excluded$3 = ["anchor", "focus"],
|
319 | _excluded2 = ["anchor", "focus"];
|
320 | var shallowCompare = (obj1, obj2) => Object.keys(obj1).length === Object.keys(obj2).length && Object.keys(obj1).every(key => obj2.hasOwnProperty(key) && obj1[key] === obj2[key]);
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 |
|
329 | var isDecoratorRangeListEqual = (list, another) => {
|
330 | if (list.length !== another.length) {
|
331 | return false;
|
332 | }
|
333 |
|
334 | for (var i = 0; i < list.length; i++) {
|
335 | var range = list[i];
|
336 | var other = another[i];
|
337 |
|
338 | var rangeOwnProps = _objectWithoutProperties(range, _excluded$3);
|
339 |
|
340 | var otherOwnProps = _objectWithoutProperties(other, _excluded2);
|
341 |
|
342 | if (!Range.equals(range, other) || range[PLACEHOLDER_SYMBOL] !== other[PLACEHOLDER_SYMBOL] || !shallowCompare(rangeOwnProps, otherOwnProps)) {
|
343 | return false;
|
344 | }
|
345 | }
|
346 |
|
347 | return true;
|
348 | };
|
349 |
|
350 | function useContentKey(node) {
|
351 | var contentKeyRef = useRef(0);
|
352 | var updateAnimationFrameRef = useRef(null);
|
353 | var [, setForceRerenderCounter] = useState(0);
|
354 | useEffect(() => {
|
355 | NODE_TO_RESTORE_DOM.set(node, () => {
|
356 |
|
357 | if (updateAnimationFrameRef.current) {
|
358 | return;
|
359 | }
|
360 |
|
361 | updateAnimationFrameRef.current = requestAnimationFrame(() => {
|
362 | setForceRerenderCounter(state => state + 1);
|
363 | updateAnimationFrameRef.current = null;
|
364 | });
|
365 | contentKeyRef.current++;
|
366 | });
|
367 | return () => {
|
368 | NODE_TO_RESTORE_DOM.delete(node);
|
369 | };
|
370 | }, [node]);
|
371 |
|
372 | if (updateAnimationFrameRef.current) {
|
373 | cancelAnimationFrame(updateAnimationFrameRef.current);
|
374 | updateAnimationFrameRef.current = null;
|
375 | }
|
376 |
|
377 | return contentKeyRef.current;
|
378 | }
|
379 |
|
380 |
|
381 |
|
382 |
|
383 |
|
384 | var Text = props => {
|
385 | var {
|
386 | decorations,
|
387 | isLast,
|
388 | parent,
|
389 | renderPlaceholder,
|
390 | renderLeaf,
|
391 | text
|
392 | } = props;
|
393 | var editor = useSlateStatic();
|
394 | var ref = useRef(null);
|
395 | var leaves = Text$1.decorations(text, decorations);
|
396 | var key = ReactEditor.findKey(editor, text);
|
397 | var children = [];
|
398 |
|
399 | for (var i = 0; i < leaves.length; i++) {
|
400 | var leaf = leaves[i];
|
401 | children.push( React.createElement(MemoizedLeaf, {
|
402 | isLast: isLast && i === leaves.length - 1,
|
403 | key: "".concat(key.id, "-").concat(i),
|
404 | renderPlaceholder: renderPlaceholder,
|
405 | leaf: leaf,
|
406 | text: text,
|
407 | parent: parent,
|
408 | renderLeaf: renderLeaf
|
409 | }));
|
410 | }
|
411 |
|
412 |
|
413 | useIsomorphicLayoutEffect(() => {
|
414 | var KEY_TO_ELEMENT = EDITOR_TO_KEY_TO_ELEMENT.get(editor);
|
415 |
|
416 | if (ref.current) {
|
417 | KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.set(key, ref.current);
|
418 | NODE_TO_ELEMENT.set(text, ref.current);
|
419 | ELEMENT_TO_NODE.set(ref.current, text);
|
420 | } else {
|
421 | KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.delete(key);
|
422 | NODE_TO_ELEMENT.delete(text);
|
423 | }
|
424 | });
|
425 | var contentKey = IS_ANDROID ? useContentKey(text) : undefined;
|
426 | return React.createElement("span", {
|
427 | "data-slate-node": "text",
|
428 | ref: ref,
|
429 | key: contentKey
|
430 | }, children);
|
431 | };
|
432 |
|
433 | var MemoizedText = React.memo(Text, (prev, next) => {
|
434 | return next.parent === prev.parent && next.isLast === prev.isLast && next.renderLeaf === prev.renderLeaf && next.text === prev.text && isDecoratorRangeListEqual(next.decorations, prev.decorations);
|
435 | });
|
436 |
|
437 |
|
438 |
|
439 |
|
440 |
|
441 | var Element = props => {
|
442 | var {
|
443 | decorations,
|
444 | element,
|
445 | renderElement = p => React.createElement(DefaultElement, Object.assign({}, p)),
|
446 | renderPlaceholder,
|
447 | renderLeaf,
|
448 | selection
|
449 | } = props;
|
450 | var ref = useRef(null);
|
451 | var editor = useSlateStatic();
|
452 | var readOnly = useReadOnly();
|
453 | var isInline = editor.isInline(element);
|
454 | var key = ReactEditor.findKey(editor, element);
|
455 | var children = useChildren({
|
456 | decorations,
|
457 | node: element,
|
458 | renderElement,
|
459 | renderPlaceholder,
|
460 | renderLeaf,
|
461 | selection
|
462 | });
|
463 |
|
464 |
|
465 | var attributes = {
|
466 | 'data-slate-node': 'element',
|
467 | ref
|
468 | };
|
469 |
|
470 | if (isInline) {
|
471 | attributes['data-slate-inline'] = true;
|
472 | }
|
473 |
|
474 |
|
475 |
|
476 | if (!isInline && Editor.hasInlines(editor, element)) {
|
477 | var text = Node.string(element);
|
478 | var dir = getDirection(text);
|
479 |
|
480 | if (dir === 'rtl') {
|
481 | attributes.dir = dir;
|
482 | }
|
483 | }
|
484 |
|
485 |
|
486 | if (Editor.isVoid(editor, element)) {
|
487 | attributes['data-slate-void'] = true;
|
488 |
|
489 | if (!readOnly && isInline) {
|
490 | attributes.contentEditable = false;
|
491 | }
|
492 |
|
493 | var Tag = isInline ? 'span' : 'div';
|
494 | var [[_text]] = Node.texts(element);
|
495 | children = readOnly ? null : React.createElement(Tag, {
|
496 | "data-slate-spacer": true,
|
497 | style: {
|
498 | height: '0',
|
499 | color: 'transparent',
|
500 | outline: 'none',
|
501 | position: 'absolute'
|
502 | }
|
503 | }, React.createElement(MemoizedText, {
|
504 | renderPlaceholder: renderPlaceholder,
|
505 | decorations: [],
|
506 | isLast: false,
|
507 | parent: element,
|
508 | text: _text
|
509 | }));
|
510 | NODE_TO_INDEX.set(_text, 0);
|
511 | NODE_TO_PARENT.set(_text, element);
|
512 | }
|
513 |
|
514 |
|
515 | useIsomorphicLayoutEffect(() => {
|
516 | var KEY_TO_ELEMENT = EDITOR_TO_KEY_TO_ELEMENT.get(editor);
|
517 |
|
518 | if (ref.current) {
|
519 | KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.set(key, ref.current);
|
520 | NODE_TO_ELEMENT.set(element, ref.current);
|
521 | ELEMENT_TO_NODE.set(ref.current, element);
|
522 | } else {
|
523 | KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.delete(key);
|
524 | NODE_TO_ELEMENT.delete(element);
|
525 | }
|
526 | });
|
527 | var content = renderElement({
|
528 | attributes,
|
529 | children,
|
530 | element
|
531 | });
|
532 |
|
533 | if (IS_ANDROID) {
|
534 | var contentKey = useContentKey(element);
|
535 | return React.createElement(Fragment, {
|
536 | key: contentKey
|
537 | }, content);
|
538 | }
|
539 |
|
540 | return content;
|
541 | };
|
542 |
|
543 | var MemoizedElement = React.memo(Element, (prev, next) => {
|
544 | return prev.element === next.element && prev.renderElement === next.renderElement && prev.renderLeaf === next.renderLeaf && isDecoratorRangeListEqual(prev.decorations, next.decorations) && (prev.selection === next.selection || !!prev.selection && !!next.selection && Range.equals(prev.selection, next.selection));
|
545 | });
|
546 |
|
547 |
|
548 |
|
549 |
|
550 | var DefaultElement = props => {
|
551 | var {
|
552 | attributes,
|
553 | children,
|
554 | element
|
555 | } = props;
|
556 | var editor = useSlateStatic();
|
557 | var Tag = editor.isInline(element) ? 'span' : 'div';
|
558 | return React.createElement(Tag, Object.assign({}, attributes, {
|
559 | style: {
|
560 | position: 'relative'
|
561 | }
|
562 | }), children);
|
563 | };
|
564 |
|
565 |
|
566 |
|
567 |
|
568 |
|
569 | var EditorContext = createContext(null);
|
570 |
|
571 |
|
572 |
|
573 |
|
574 | var useSlateStatic = () => {
|
575 | var editor = useContext(EditorContext);
|
576 |
|
577 | if (!editor) {
|
578 | throw new Error("The `useSlateStatic` hook must be used inside the <Slate> component's context.");
|
579 | }
|
580 |
|
581 | return editor;
|
582 | };
|
583 |
|
584 |
|
585 |
|
586 |
|
587 |
|
588 | var DecorateContext = createContext(() => []);
|
589 |
|
590 |
|
591 |
|
592 |
|
593 | var useDecorate = () => {
|
594 | return useContext(DecorateContext);
|
595 | };
|
596 |
|
597 |
|
598 |
|
599 |
|
600 |
|
601 | var SelectedContext = createContext(false);
|
602 |
|
603 |
|
604 |
|
605 |
|
606 | var useSelected = () => {
|
607 | return useContext(SelectedContext);
|
608 | };
|
609 |
|
610 |
|
611 |
|
612 |
|
613 |
|
614 | var useChildren = props => {
|
615 | var {
|
616 | decorations,
|
617 | node,
|
618 | renderElement,
|
619 | renderPlaceholder,
|
620 | renderLeaf,
|
621 | selection
|
622 | } = props;
|
623 | var decorate = useDecorate();
|
624 | var editor = useSlateStatic();
|
625 | var path = ReactEditor.findPath(editor, node);
|
626 | var children = [];
|
627 | var isLeafBlock = Element$1.isElement(node) && !editor.isInline(node) && Editor.hasInlines(editor, node);
|
628 |
|
629 | for (var i = 0; i < node.children.length; i++) {
|
630 | var p = path.concat(i);
|
631 | var n = node.children[i];
|
632 | var key = ReactEditor.findKey(editor, n);
|
633 | var range = Editor.range(editor, p);
|
634 | var sel = selection && Range.intersection(range, selection);
|
635 | var ds = decorate([n, p]);
|
636 |
|
637 | for (var dec of decorations) {
|
638 | var d = Range.intersection(dec, range);
|
639 |
|
640 | if (d) {
|
641 | ds.push(d);
|
642 | }
|
643 | }
|
644 |
|
645 | if (Element$1.isElement(n)) {
|
646 | children.push( React.createElement(SelectedContext.Provider, {
|
647 | key: "provider-".concat(key.id),
|
648 | value: !!sel
|
649 | }, React.createElement(MemoizedElement, {
|
650 | decorations: ds,
|
651 | element: n,
|
652 | key: key.id,
|
653 | renderElement: renderElement,
|
654 | renderPlaceholder: renderPlaceholder,
|
655 | renderLeaf: renderLeaf,
|
656 | selection: sel
|
657 | })));
|
658 | } else {
|
659 | children.push( React.createElement(MemoizedText, {
|
660 | decorations: ds,
|
661 | key: key.id,
|
662 | isLast: isLeafBlock && i === node.children.length - 1,
|
663 | parent: node,
|
664 | renderPlaceholder: renderPlaceholder,
|
665 | renderLeaf: renderLeaf,
|
666 | text: n
|
667 | }));
|
668 | }
|
669 |
|
670 | NODE_TO_INDEX.set(n, i);
|
671 | NODE_TO_PARENT.set(n, node);
|
672 | }
|
673 |
|
674 | return children;
|
675 | };
|
676 |
|
677 |
|
678 |
|
679 |
|
680 |
|
681 | var HOTKEYS = {
|
682 | bold: 'mod+b',
|
683 | compose: ['down', 'left', 'right', 'up', 'backspace', 'enter'],
|
684 | moveBackward: 'left',
|
685 | moveForward: 'right',
|
686 | moveWordBackward: 'ctrl+left',
|
687 | moveWordForward: 'ctrl+right',
|
688 | deleteBackward: 'shift?+backspace',
|
689 | deleteForward: 'shift?+delete',
|
690 | extendBackward: 'shift+left',
|
691 | extendForward: 'shift+right',
|
692 | italic: 'mod+i',
|
693 | splitBlock: 'shift?+enter',
|
694 | undo: 'mod+z'
|
695 | };
|
696 | var APPLE_HOTKEYS = {
|
697 | moveLineBackward: 'opt+up',
|
698 | moveLineForward: 'opt+down',
|
699 | moveWordBackward: 'opt+left',
|
700 | moveWordForward: 'opt+right',
|
701 | deleteBackward: ['ctrl+backspace', 'ctrl+h'],
|
702 | deleteForward: ['ctrl+delete', 'ctrl+d'],
|
703 | deleteLineBackward: 'cmd+shift?+backspace',
|
704 | deleteLineForward: ['cmd+shift?+delete', 'ctrl+k'],
|
705 | deleteWordBackward: 'opt+shift?+backspace',
|
706 | deleteWordForward: 'opt+shift?+delete',
|
707 | extendLineBackward: 'opt+shift+up',
|
708 | extendLineForward: 'opt+shift+down',
|
709 | redo: 'cmd+shift+z',
|
710 | transposeCharacter: 'ctrl+t'
|
711 | };
|
712 | var WINDOWS_HOTKEYS = {
|
713 | deleteWordBackward: 'ctrl+shift?+backspace',
|
714 | deleteWordForward: 'ctrl+shift?+delete',
|
715 | redo: ['ctrl+y', 'ctrl+shift+z']
|
716 | };
|
717 |
|
718 |
|
719 |
|
720 |
|
721 | var create = key => {
|
722 | var generic = HOTKEYS[key];
|
723 | var apple = APPLE_HOTKEYS[key];
|
724 | var windows = WINDOWS_HOTKEYS[key];
|
725 | var isGeneric = generic && isKeyHotkey(generic);
|
726 | var isApple = apple && isKeyHotkey(apple);
|
727 | var isWindows = windows && isKeyHotkey(windows);
|
728 | return event => {
|
729 | if (isGeneric && isGeneric(event)) return true;
|
730 | if (IS_APPLE && isApple && isApple(event)) return true;
|
731 | if (!IS_APPLE && isWindows && isWindows(event)) return true;
|
732 | return false;
|
733 | };
|
734 | };
|
735 |
|
736 |
|
737 |
|
738 |
|
739 |
|
740 | var Hotkeys = {
|
741 | isBold: create('bold'),
|
742 | isCompose: create('compose'),
|
743 | isMoveBackward: create('moveBackward'),
|
744 | isMoveForward: create('moveForward'),
|
745 | isDeleteBackward: create('deleteBackward'),
|
746 | isDeleteForward: create('deleteForward'),
|
747 | isDeleteLineBackward: create('deleteLineBackward'),
|
748 | isDeleteLineForward: create('deleteLineForward'),
|
749 | isDeleteWordBackward: create('deleteWordBackward'),
|
750 | isDeleteWordForward: create('deleteWordForward'),
|
751 | isExtendBackward: create('extendBackward'),
|
752 | isExtendForward: create('extendForward'),
|
753 | isExtendLineBackward: create('extendLineBackward'),
|
754 | isExtendLineForward: create('extendLineForward'),
|
755 | isItalic: create('italic'),
|
756 | isMoveLineBackward: create('moveLineBackward'),
|
757 | isMoveLineForward: create('moveLineForward'),
|
758 | isMoveWordBackward: create('moveWordBackward'),
|
759 | isMoveWordForward: create('moveWordForward'),
|
760 | isRedo: create('redo'),
|
761 | isSplitBlock: create('splitBlock'),
|
762 | isTransposeCharacter: create('transposeCharacter'),
|
763 | isUndo: create('undo')
|
764 | };
|
765 |
|
766 |
|
767 |
|
768 |
|
769 |
|
770 | var ReadOnlyContext = createContext(false);
|
771 |
|
772 |
|
773 |
|
774 |
|
775 | var useReadOnly = () => {
|
776 | return useContext(ReadOnlyContext);
|
777 | };
|
778 |
|
779 |
|
780 |
|
781 |
|
782 |
|
783 |
|
784 | var SlateContext = createContext(null);
|
785 |
|
786 |
|
787 |
|
788 |
|
789 | var useSlate = () => {
|
790 | var context = useContext(SlateContext);
|
791 |
|
792 | if (!context) {
|
793 | throw new Error("The `useSlate` hook must be used inside the <Slate> component's context.");
|
794 | }
|
795 |
|
796 | var [editor] = context;
|
797 | return editor;
|
798 | };
|
799 |
|
800 |
|
801 |
|
802 |
|
803 |
|
804 |
|
805 |
|
806 |
|
807 | var getDefaultView = value => {
|
808 | return value && value.ownerDocument && value.ownerDocument.defaultView || null;
|
809 | };
|
810 |
|
811 |
|
812 |
|
813 |
|
814 | var isDOMComment = value => {
|
815 | return isDOMNode(value) && value.nodeType === 8;
|
816 | };
|
817 |
|
818 |
|
819 |
|
820 |
|
821 | var isDOMElement = value => {
|
822 | return isDOMNode(value) && value.nodeType === 1;
|
823 | };
|
824 |
|
825 |
|
826 |
|
827 |
|
828 | var isDOMNode = value => {
|
829 | var window = getDefaultView(value);
|
830 | return !!window && value instanceof window.Node;
|
831 | };
|
832 |
|
833 |
|
834 |
|
835 |
|
836 | var isDOMSelection = value => {
|
837 | var window = value && value.anchorNode && getDefaultView(value.anchorNode);
|
838 | return !!window && value instanceof window.Selection;
|
839 | };
|
840 |
|
841 |
|
842 |
|
843 |
|
844 | var isDOMText = value => {
|
845 | return isDOMNode(value) && value.nodeType === 3;
|
846 | };
|
847 |
|
848 |
|
849 |
|
850 |
|
851 | var isPlainTextOnlyPaste = event => {
|
852 | return event.clipboardData && event.clipboardData.getData('text/plain') !== '' && event.clipboardData.types.length === 1;
|
853 | };
|
854 |
|
855 |
|
856 |
|
857 |
|
858 | var normalizeDOMPoint = domPoint => {
|
859 | var [node, offset] = domPoint;
|
860 |
|
861 |
|
862 | if (isDOMElement(node) && node.childNodes.length) {
|
863 | var isLast = offset === node.childNodes.length;
|
864 | var index = isLast ? offset - 1 : offset;
|
865 | [node, index] = getEditableChildAndIndex(node, index, isLast ? 'backward' : 'forward');
|
866 |
|
867 | isLast = index < offset;
|
868 |
|
869 |
|
870 | while (isDOMElement(node) && node.childNodes.length) {
|
871 | var i = isLast ? node.childNodes.length - 1 : 0;
|
872 | node = getEditableChild(node, i, isLast ? 'backward' : 'forward');
|
873 | }
|
874 |
|
875 |
|
876 | offset = isLast && node.textContent != null ? node.textContent.length : 0;
|
877 | }
|
878 |
|
879 |
|
880 | return [node, offset];
|
881 | };
|
882 |
|
883 |
|
884 |
|
885 |
|
886 | var hasShadowRoot = () => {
|
887 | return !!(window.document.activeElement && window.document.activeElement.shadowRoot);
|
888 | };
|
889 |
|
890 |
|
891 |
|
892 |
|
893 |
|
894 | var getEditableChildAndIndex = (parent, index, direction) => {
|
895 | var {
|
896 | childNodes
|
897 | } = parent;
|
898 | var child = childNodes[index];
|
899 | var i = index;
|
900 | var triedForward = false;
|
901 | var triedBackward = false;
|
902 |
|
903 |
|
904 | while (isDOMComment(child) || isDOMElement(child) && child.childNodes.length === 0 || isDOMElement(child) && child.getAttribute('contenteditable') === 'false') {
|
905 | if (triedForward && triedBackward) {
|
906 | break;
|
907 | }
|
908 |
|
909 | if (i >= childNodes.length) {
|
910 | triedForward = true;
|
911 | i = index - 1;
|
912 | direction = 'backward';
|
913 | continue;
|
914 | }
|
915 |
|
916 | if (i < 0) {
|
917 | triedBackward = true;
|
918 | i = index + 1;
|
919 | direction = 'forward';
|
920 | continue;
|
921 | }
|
922 |
|
923 | child = childNodes[i];
|
924 | index = i;
|
925 | i += direction === 'forward' ? 1 : -1;
|
926 | }
|
927 |
|
928 | return [child, index];
|
929 | };
|
930 |
|
931 |
|
932 |
|
933 |
|
934 |
|
935 | var getEditableChild = (parent, index, direction) => {
|
936 | var [child] = getEditableChildAndIndex(parent, index, direction);
|
937 | return child;
|
938 | };
|
939 |
|
940 |
|
941 |
|
942 |
|
943 |
|
944 |
|
945 |
|
946 | var getPlainText = domNode => {
|
947 | var text = '';
|
948 |
|
949 | if (isDOMText(domNode) && domNode.nodeValue) {
|
950 | return domNode.nodeValue;
|
951 | }
|
952 |
|
953 | if (isDOMElement(domNode)) {
|
954 | for (var childNode of Array.from(domNode.childNodes)) {
|
955 | text += getPlainText(childNode);
|
956 | }
|
957 |
|
958 | var display = getComputedStyle(domNode).getPropertyValue('display');
|
959 |
|
960 | if (display === 'block' || display === 'list' || domNode.tagName === 'BR') {
|
961 | text += '\n';
|
962 | }
|
963 | }
|
964 |
|
965 | return text;
|
966 | };
|
967 |
|
968 |
|
969 |
|
970 |
|
971 | var catchSlateFragment = /data-slate-fragment="(.+?)"/m;
|
972 | var getSlateFragmentAttribute = dataTransfer => {
|
973 | var htmlData = dataTransfer.getData('text/html');
|
974 | var [, fragment] = htmlData.match(catchSlateFragment) || [];
|
975 | return fragment;
|
976 | };
|
977 |
|
978 |
|
979 |
|
980 |
|
981 |
|
982 | var getClipboardData = dataTransfer => {
|
983 | if (!dataTransfer.getData('application/x-slate-fragment')) {
|
984 | var fragment = getSlateFragmentAttribute(dataTransfer);
|
985 |
|
986 | if (fragment) {
|
987 | var clipboardData = new DataTransfer();
|
988 | dataTransfer.types.forEach(type => {
|
989 | clipboardData.setData(type, dataTransfer.getData(type));
|
990 | });
|
991 | clipboardData.setData('application/x-slate-fragment', fragment);
|
992 | return clipboardData;
|
993 | }
|
994 | }
|
995 |
|
996 | return dataTransfer;
|
997 | };
|
998 |
|
999 | var _excluded$2 = ["autoFocus", "decorate", "onDOMBeforeInput", "placeholder", "readOnly", "renderElement", "renderLeaf", "renderPlaceholder", "scrollSelectionIntoView", "style", "as"];
|
1000 |
|
1001 | function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
1002 |
|
1003 | function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
1004 |
|
1005 | var Children = props => React.createElement(React.Fragment, null, useChildren(props));
|
1006 |
|
1007 |
|
1008 |
|
1009 |
|
1010 |
|
1011 | var Editable$1 = props => {
|
1012 | var {
|
1013 | autoFocus,
|
1014 | decorate = defaultDecorate,
|
1015 | onDOMBeforeInput: propsOnDOMBeforeInput,
|
1016 | placeholder,
|
1017 | readOnly = false,
|
1018 | renderElement,
|
1019 | renderLeaf,
|
1020 | renderPlaceholder = props => React.createElement(DefaultPlaceholder, Object.assign({}, props)),
|
1021 | scrollSelectionIntoView = defaultScrollSelectionIntoView,
|
1022 | style = {},
|
1023 | as: Component = 'div'
|
1024 | } = props,
|
1025 | attributes = _objectWithoutProperties(props, _excluded$2);
|
1026 |
|
1027 | var editor = useSlate();
|
1028 |
|
1029 | var [isComposing, setIsComposing] = useState(false);
|
1030 | var ref = useRef(null);
|
1031 | var deferredOperations = useRef([]);
|
1032 |
|
1033 | IS_READ_ONLY.set(editor, readOnly);
|
1034 |
|
1035 | var state = useMemo(() => ({
|
1036 | isComposing: false,
|
1037 | hasInsertPrefixInCompositon: false,
|
1038 | isDraggingInternally: false,
|
1039 | isUpdatingSelection: false,
|
1040 | latestElement: null
|
1041 | }), []);
|
1042 |
|
1043 | useIsomorphicLayoutEffect(() => {
|
1044 |
|
1045 | var window;
|
1046 |
|
1047 | if (ref.current && (window = getDefaultView(ref.current))) {
|
1048 | EDITOR_TO_WINDOW.set(editor, window);
|
1049 | EDITOR_TO_ELEMENT.set(editor, ref.current);
|
1050 | NODE_TO_ELEMENT.set(editor, ref.current);
|
1051 | ELEMENT_TO_NODE.set(ref.current, editor);
|
1052 | } else {
|
1053 | NODE_TO_ELEMENT.delete(editor);
|
1054 | }
|
1055 |
|
1056 |
|
1057 | var {
|
1058 | selection
|
1059 | } = editor;
|
1060 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
1061 | var domSelection = root.getSelection();
|
1062 |
|
1063 | if (state.isComposing || !domSelection || !ReactEditor.isFocused(editor)) {
|
1064 | return;
|
1065 | }
|
1066 |
|
1067 | var hasDomSelection = domSelection.type !== 'None';
|
1068 |
|
1069 | if (!selection && !hasDomSelection) {
|
1070 | return;
|
1071 | }
|
1072 |
|
1073 |
|
1074 | var editorElement = EDITOR_TO_ELEMENT.get(editor);
|
1075 | var hasDomSelectionInEditor = false;
|
1076 |
|
1077 | if (editorElement.contains(domSelection.anchorNode) && editorElement.contains(domSelection.focusNode)) {
|
1078 | hasDomSelectionInEditor = true;
|
1079 | }
|
1080 |
|
1081 |
|
1082 | if (hasDomSelection && hasDomSelectionInEditor && selection) {
|
1083 | var slateRange = ReactEditor.toSlateRange(editor, domSelection, {
|
1084 | exactMatch: true,
|
1085 |
|
1086 |
|
1087 | suppressThrow: true
|
1088 | });
|
1089 |
|
1090 | if (slateRange && Range.equals(slateRange, selection)) {
|
1091 | return;
|
1092 | }
|
1093 | }
|
1094 |
|
1095 |
|
1096 |
|
1097 |
|
1098 |
|
1099 | if (selection && !ReactEditor.hasRange(editor, selection)) {
|
1100 | editor.selection = ReactEditor.toSlateRange(editor, domSelection, {
|
1101 | exactMatch: false,
|
1102 | suppressThrow: false
|
1103 | });
|
1104 | return;
|
1105 | }
|
1106 |
|
1107 |
|
1108 | state.isUpdatingSelection = true;
|
1109 | var newDomRange = selection && hasDomSelectionInEditor && ReactEditor.toDOMRange(editor, selection);
|
1110 |
|
1111 | if (newDomRange) {
|
1112 | if (Range.isBackward(selection)) {
|
1113 | domSelection.setBaseAndExtent(newDomRange.endContainer, newDomRange.endOffset, newDomRange.startContainer, newDomRange.startOffset);
|
1114 | } else {
|
1115 | domSelection.setBaseAndExtent(newDomRange.startContainer, newDomRange.startOffset, newDomRange.endContainer, newDomRange.endOffset);
|
1116 | }
|
1117 |
|
1118 | scrollSelectionIntoView(editor, newDomRange);
|
1119 | } else {
|
1120 | domSelection.removeAllRanges();
|
1121 | }
|
1122 |
|
1123 | setTimeout(() => {
|
1124 |
|
1125 |
|
1126 | if (newDomRange && IS_FIREFOX) {
|
1127 | var el = ReactEditor.toDOMNode(editor, editor);
|
1128 | el.focus();
|
1129 | }
|
1130 |
|
1131 | state.isUpdatingSelection = false;
|
1132 | });
|
1133 | });
|
1134 |
|
1135 |
|
1136 | useEffect(() => {
|
1137 | if (ref.current && autoFocus) {
|
1138 | ref.current.focus();
|
1139 | }
|
1140 | }, [autoFocus]);
|
1141 |
|
1142 |
|
1143 |
|
1144 |
|
1145 |
|
1146 | var onDOMSelectionChange = useCallback(throttle(() => {
|
1147 | if (!state.isComposing && !state.isUpdatingSelection && !state.isDraggingInternally) {
|
1148 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
1149 | var {
|
1150 | activeElement
|
1151 | } = root;
|
1152 | var el = ReactEditor.toDOMNode(editor, editor);
|
1153 | var domSelection = root.getSelection();
|
1154 |
|
1155 | if (activeElement === el) {
|
1156 | state.latestElement = activeElement;
|
1157 | IS_FOCUSED.set(editor, true);
|
1158 | } else {
|
1159 | IS_FOCUSED.delete(editor);
|
1160 | }
|
1161 |
|
1162 | if (!domSelection) {
|
1163 | return Transforms.deselect(editor);
|
1164 | }
|
1165 |
|
1166 | var {
|
1167 | anchorNode,
|
1168 | focusNode
|
1169 | } = domSelection;
|
1170 | var anchorNodeSelectable = hasEditableTarget(editor, anchorNode) || isTargetInsideNonReadonlyVoid(editor, anchorNode);
|
1171 | var focusNodeSelectable = hasEditableTarget(editor, focusNode) || isTargetInsideNonReadonlyVoid(editor, focusNode);
|
1172 |
|
1173 | if (anchorNodeSelectable && focusNodeSelectable) {
|
1174 | var range = ReactEditor.toSlateRange(editor, domSelection, {
|
1175 | exactMatch: false,
|
1176 | suppressThrow: false
|
1177 | });
|
1178 | Transforms.select(editor, range);
|
1179 | }
|
1180 | }
|
1181 | }, 100), [readOnly]);
|
1182 | var scheduleOnDOMSelectionChange = useMemo(() => debounce(onDOMSelectionChange, 0), [onDOMSelectionChange]);
|
1183 |
|
1184 |
|
1185 |
|
1186 |
|
1187 | var onDOMBeforeInput = useCallback(event => {
|
1188 | if (!readOnly && hasEditableTarget(editor, event.target) && !isDOMEventHandled(event, propsOnDOMBeforeInput)) {
|
1189 |
|
1190 |
|
1191 |
|
1192 | scheduleOnDOMSelectionChange.flush();
|
1193 | var {
|
1194 | selection
|
1195 | } = editor;
|
1196 | var {
|
1197 | inputType: type
|
1198 | } = event;
|
1199 | var data = event.dataTransfer || event.data || undefined;
|
1200 |
|
1201 |
|
1202 | if (type === 'insertCompositionText' || type === 'deleteCompositionText') {
|
1203 | return;
|
1204 | }
|
1205 |
|
1206 | var native = false;
|
1207 |
|
1208 | if (type === 'insertText' && selection && Range.isCollapsed(selection) &&
|
1209 |
|
1210 |
|
1211 | event.data && event.data.length === 1 && /[a-z ]/i.test(event.data) &&
|
1212 |
|
1213 |
|
1214 | selection.anchor.offset !== 0) {
|
1215 | native = true;
|
1216 |
|
1217 |
|
1218 | if (editor.marks) {
|
1219 | native = false;
|
1220 | }
|
1221 |
|
1222 |
|
1223 |
|
1224 | var {
|
1225 | anchor
|
1226 | } = selection;
|
1227 | var inline = Editor.above(editor, {
|
1228 | at: anchor,
|
1229 | match: n => Editor.isInline(editor, n),
|
1230 | mode: 'highest'
|
1231 | });
|
1232 |
|
1233 | if (inline) {
|
1234 | var [, inlinePath] = inline;
|
1235 |
|
1236 | if (Editor.isEnd(editor, selection.anchor, inlinePath)) {
|
1237 | native = false;
|
1238 | }
|
1239 | }
|
1240 | }
|
1241 |
|
1242 | if (!native) {
|
1243 | event.preventDefault();
|
1244 | }
|
1245 |
|
1246 |
|
1247 |
|
1248 |
|
1249 | if (!type.startsWith('delete') || type.startsWith('deleteBy')) {
|
1250 | var [targetRange] = event.getTargetRanges();
|
1251 |
|
1252 | if (targetRange) {
|
1253 | var range = ReactEditor.toSlateRange(editor, targetRange, {
|
1254 | exactMatch: false,
|
1255 | suppressThrow: false
|
1256 | });
|
1257 |
|
1258 | if (!selection || !Range.equals(selection, range)) {
|
1259 | Transforms.select(editor, range);
|
1260 | }
|
1261 | }
|
1262 | }
|
1263 |
|
1264 |
|
1265 |
|
1266 | if (selection && Range.isExpanded(selection) && type.startsWith('delete')) {
|
1267 | var direction = type.endsWith('Backward') ? 'backward' : 'forward';
|
1268 | Editor.deleteFragment(editor, {
|
1269 | direction
|
1270 | });
|
1271 | return;
|
1272 | }
|
1273 |
|
1274 | switch (type) {
|
1275 | case 'deleteByComposition':
|
1276 | case 'deleteByCut':
|
1277 | case 'deleteByDrag':
|
1278 | {
|
1279 | Editor.deleteFragment(editor);
|
1280 | break;
|
1281 | }
|
1282 |
|
1283 | case 'deleteContent':
|
1284 | case 'deleteContentForward':
|
1285 | {
|
1286 | Editor.deleteForward(editor);
|
1287 | break;
|
1288 | }
|
1289 |
|
1290 | case 'deleteContentBackward':
|
1291 | {
|
1292 | Editor.deleteBackward(editor);
|
1293 | break;
|
1294 | }
|
1295 |
|
1296 | case 'deleteEntireSoftLine':
|
1297 | {
|
1298 | Editor.deleteBackward(editor, {
|
1299 | unit: 'line'
|
1300 | });
|
1301 | Editor.deleteForward(editor, {
|
1302 | unit: 'line'
|
1303 | });
|
1304 | break;
|
1305 | }
|
1306 |
|
1307 | case 'deleteHardLineBackward':
|
1308 | {
|
1309 | Editor.deleteBackward(editor, {
|
1310 | unit: 'block'
|
1311 | });
|
1312 | break;
|
1313 | }
|
1314 |
|
1315 | case 'deleteSoftLineBackward':
|
1316 | {
|
1317 | Editor.deleteBackward(editor, {
|
1318 | unit: 'line'
|
1319 | });
|
1320 | break;
|
1321 | }
|
1322 |
|
1323 | case 'deleteHardLineForward':
|
1324 | {
|
1325 | Editor.deleteForward(editor, {
|
1326 | unit: 'block'
|
1327 | });
|
1328 | break;
|
1329 | }
|
1330 |
|
1331 | case 'deleteSoftLineForward':
|
1332 | {
|
1333 | Editor.deleteForward(editor, {
|
1334 | unit: 'line'
|
1335 | });
|
1336 | break;
|
1337 | }
|
1338 |
|
1339 | case 'deleteWordBackward':
|
1340 | {
|
1341 | Editor.deleteBackward(editor, {
|
1342 | unit: 'word'
|
1343 | });
|
1344 | break;
|
1345 | }
|
1346 |
|
1347 | case 'deleteWordForward':
|
1348 | {
|
1349 | Editor.deleteForward(editor, {
|
1350 | unit: 'word'
|
1351 | });
|
1352 | break;
|
1353 | }
|
1354 |
|
1355 | case 'insertLineBreak':
|
1356 | case 'insertParagraph':
|
1357 | {
|
1358 | Editor.insertBreak(editor);
|
1359 | break;
|
1360 | }
|
1361 |
|
1362 | case 'insertFromComposition':
|
1363 | case 'insertFromDrop':
|
1364 | case 'insertFromPaste':
|
1365 | case 'insertFromYank':
|
1366 | case 'insertReplacementText':
|
1367 | case 'insertText':
|
1368 | {
|
1369 | if (type === 'insertFromComposition') {
|
1370 |
|
1371 |
|
1372 |
|
1373 |
|
1374 |
|
1375 | state.isComposing && setIsComposing(false);
|
1376 | state.isComposing = false;
|
1377 | }
|
1378 |
|
1379 |
|
1380 |
|
1381 |
|
1382 | if ((data === null || data === void 0 ? void 0 : data.constructor.name) === 'DataTransfer') {
|
1383 | ReactEditor.insertData(editor, data);
|
1384 | } else if (typeof data === 'string') {
|
1385 |
|
1386 |
|
1387 | if (native) {
|
1388 | deferredOperations.current.push(() => Editor.insertText(editor, data));
|
1389 | } else {
|
1390 | Editor.insertText(editor, data);
|
1391 | }
|
1392 | }
|
1393 |
|
1394 | break;
|
1395 | }
|
1396 | }
|
1397 | }
|
1398 | }, [readOnly, propsOnDOMBeforeInput]);
|
1399 |
|
1400 |
|
1401 |
|
1402 |
|
1403 | useIsomorphicLayoutEffect(() => {
|
1404 | if (ref.current && HAS_BEFORE_INPUT_SUPPORT) {
|
1405 |
|
1406 | ref.current.addEventListener('beforeinput', onDOMBeforeInput);
|
1407 | }
|
1408 |
|
1409 | return () => {
|
1410 | if (ref.current && HAS_BEFORE_INPUT_SUPPORT) {
|
1411 |
|
1412 | ref.current.removeEventListener('beforeinput', onDOMBeforeInput);
|
1413 | }
|
1414 | };
|
1415 | }, [onDOMBeforeInput]);
|
1416 |
|
1417 |
|
1418 |
|
1419 |
|
1420 |
|
1421 | useIsomorphicLayoutEffect(() => {
|
1422 | var window = ReactEditor.getWindow(editor);
|
1423 | window.document.addEventListener('selectionchange', scheduleOnDOMSelectionChange);
|
1424 | return () => {
|
1425 | window.document.removeEventListener('selectionchange', scheduleOnDOMSelectionChange);
|
1426 | };
|
1427 | }, [scheduleOnDOMSelectionChange]);
|
1428 | var decorations = decorate([editor, []]);
|
1429 |
|
1430 | if (placeholder && editor.children.length === 1 && Array.from(Node.texts(editor)).length === 1 && Node.string(editor) === '' && !isComposing) {
|
1431 | var start = Editor.start(editor, []);
|
1432 | decorations.push({
|
1433 | [PLACEHOLDER_SYMBOL]: true,
|
1434 | placeholder,
|
1435 | anchor: start,
|
1436 | focus: start
|
1437 | });
|
1438 | }
|
1439 |
|
1440 | return React.createElement(ReadOnlyContext.Provider, {
|
1441 | value: readOnly
|
1442 | }, React.createElement(DecorateContext.Provider, {
|
1443 | value: decorate
|
1444 | }, React.createElement(Component, Object.assign({
|
1445 | role: readOnly ? undefined : 'textbox'
|
1446 | }, attributes, {
|
1447 |
|
1448 |
|
1449 |
|
1450 |
|
1451 |
|
1452 | spellCheck: HAS_BEFORE_INPUT_SUPPORT || !CAN_USE_DOM ? attributes.spellCheck : false,
|
1453 | autoCorrect: HAS_BEFORE_INPUT_SUPPORT || !CAN_USE_DOM ? attributes.autoCorrect : 'false',
|
1454 | autoCapitalize: HAS_BEFORE_INPUT_SUPPORT || !CAN_USE_DOM ? attributes.autoCapitalize : 'false',
|
1455 | "data-slate-editor": true,
|
1456 | "data-slate-node": "value",
|
1457 |
|
1458 | contentEditable: !readOnly,
|
1459 |
|
1460 |
|
1461 |
|
1462 | zindex: -1,
|
1463 | suppressContentEditableWarning: true,
|
1464 | ref: ref,
|
1465 | style: _objectSpread$1({
|
1466 |
|
1467 | position: 'relative',
|
1468 |
|
1469 | outline: 'none',
|
1470 |
|
1471 | whiteSpace: 'pre-wrap',
|
1472 |
|
1473 | wordWrap: 'break-word'
|
1474 | }, style),
|
1475 | onBeforeInput: useCallback(event => {
|
1476 |
|
1477 |
|
1478 |
|
1479 | if (!HAS_BEFORE_INPUT_SUPPORT && !readOnly && !isEventHandled(event, attributes.onBeforeInput) && hasEditableTarget(editor, event.target)) {
|
1480 | event.preventDefault();
|
1481 |
|
1482 | if (!state.isComposing) {
|
1483 | var text = event.data;
|
1484 | Editor.insertText(editor, text);
|
1485 | }
|
1486 | }
|
1487 | }, [readOnly]),
|
1488 | onInput: useCallback(event => {
|
1489 |
|
1490 |
|
1491 |
|
1492 |
|
1493 | for (var op of deferredOperations.current) {
|
1494 | op();
|
1495 | }
|
1496 |
|
1497 | deferredOperations.current = [];
|
1498 | }, []),
|
1499 | onBlur: useCallback(event => {
|
1500 | if (readOnly || state.isUpdatingSelection || !hasEditableTarget(editor, event.target) || isEventHandled(event, attributes.onBlur)) {
|
1501 | return;
|
1502 | }
|
1503 |
|
1504 |
|
1505 |
|
1506 |
|
1507 |
|
1508 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
1509 |
|
1510 | if (state.latestElement === root.activeElement) {
|
1511 | return;
|
1512 | }
|
1513 |
|
1514 | var {
|
1515 | relatedTarget
|
1516 | } = event;
|
1517 | var el = ReactEditor.toDOMNode(editor, editor);
|
1518 |
|
1519 |
|
1520 |
|
1521 | if (relatedTarget === el) {
|
1522 | return;
|
1523 | }
|
1524 |
|
1525 |
|
1526 |
|
1527 | if (isDOMElement(relatedTarget) && relatedTarget.hasAttribute('data-slate-spacer')) {
|
1528 | return;
|
1529 | }
|
1530 |
|
1531 |
|
1532 |
|
1533 |
|
1534 | if (relatedTarget != null && isDOMNode(relatedTarget) && ReactEditor.hasDOMNode(editor, relatedTarget)) {
|
1535 | var node = ReactEditor.toSlateNode(editor, relatedTarget);
|
1536 |
|
1537 | if (Element$1.isElement(node) && !editor.isVoid(node)) {
|
1538 | return;
|
1539 | }
|
1540 | }
|
1541 |
|
1542 |
|
1543 |
|
1544 |
|
1545 | if (IS_SAFARI) {
|
1546 | var domSelection = root.getSelection();
|
1547 | domSelection === null || domSelection === void 0 ? void 0 : domSelection.removeAllRanges();
|
1548 | }
|
1549 |
|
1550 | IS_FOCUSED.delete(editor);
|
1551 | }, [readOnly, attributes.onBlur]),
|
1552 | onClick: useCallback(event => {
|
1553 | if (!readOnly && hasTarget(editor, event.target) && !isEventHandled(event, attributes.onClick) && isDOMNode(event.target)) {
|
1554 | var node = ReactEditor.toSlateNode(editor, event.target);
|
1555 | var path = ReactEditor.findPath(editor, node);
|
1556 |
|
1557 |
|
1558 |
|
1559 |
|
1560 | if (Editor.hasPath(editor, path)) {
|
1561 | var lookupNode = Node.get(editor, path);
|
1562 |
|
1563 | if (lookupNode === node) {
|
1564 | var _start = Editor.start(editor, path);
|
1565 |
|
1566 | var end = Editor.end(editor, path);
|
1567 | var startVoid = Editor.void(editor, {
|
1568 | at: _start
|
1569 | });
|
1570 | var endVoid = Editor.void(editor, {
|
1571 | at: end
|
1572 | });
|
1573 |
|
1574 | if (startVoid && endVoid && Path.equals(startVoid[1], endVoid[1])) {
|
1575 | var range = Editor.range(editor, _start);
|
1576 | Transforms.select(editor, range);
|
1577 | }
|
1578 | }
|
1579 | }
|
1580 | }
|
1581 | }, [readOnly, attributes.onClick]),
|
1582 | onCompositionEnd: useCallback(event => {
|
1583 | if (hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onCompositionEnd)) {
|
1584 | state.isComposing && setIsComposing(false);
|
1585 | state.isComposing = false;
|
1586 |
|
1587 |
|
1588 |
|
1589 |
|
1590 | if (!IS_SAFARI && !IS_FIREFOX_LEGACY && !IS_IOS && !IS_QQBROWSER && !IS_WECHATBROWSER && !IS_UC_MOBILE && event.data) {
|
1591 | Editor.insertText(editor, event.data);
|
1592 | }
|
1593 |
|
1594 | if (editor.selection && Range.isCollapsed(editor.selection)) {
|
1595 | var leafPath = editor.selection.anchor.path;
|
1596 | var currentTextNode = Node.leaf(editor, leafPath);
|
1597 |
|
1598 | if (state.hasInsertPrefixInCompositon) {
|
1599 | state.hasInsertPrefixInCompositon = false;
|
1600 | Editor.withoutNormalizing(editor, () => {
|
1601 |
|
1602 | var text = currentTextNode.text.replace(/^\uFEFF/, '');
|
1603 | Transforms.delete(editor, {
|
1604 | distance: currentTextNode.text.length,
|
1605 | reverse: true
|
1606 | });
|
1607 | Editor.insertText(editor, text);
|
1608 | });
|
1609 | }
|
1610 | }
|
1611 | }
|
1612 | }, [attributes.onCompositionEnd]),
|
1613 | onCompositionUpdate: useCallback(event => {
|
1614 | if (hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onCompositionUpdate)) {
|
1615 | !state.isComposing && setIsComposing(true);
|
1616 | state.isComposing = true;
|
1617 | }
|
1618 | }, [attributes.onCompositionUpdate]),
|
1619 | onCompositionStart: useCallback(event => {
|
1620 | if (hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onCompositionStart)) {
|
1621 | var {
|
1622 | selection,
|
1623 | marks
|
1624 | } = editor;
|
1625 |
|
1626 | if (selection) {
|
1627 | if (Range.isExpanded(selection)) {
|
1628 | Editor.deleteFragment(editor);
|
1629 | return;
|
1630 | }
|
1631 |
|
1632 | var inline = Editor.above(editor, {
|
1633 | match: n => Editor.isInline(editor, n),
|
1634 | mode: 'highest'
|
1635 | });
|
1636 |
|
1637 | if (inline) {
|
1638 | var [, inlinePath] = inline;
|
1639 |
|
1640 | if (Editor.isEnd(editor, selection.anchor, inlinePath)) {
|
1641 | var point = Editor.after(editor, inlinePath);
|
1642 | Transforms.setSelection(editor, {
|
1643 | anchor: point,
|
1644 | focus: point
|
1645 | });
|
1646 | }
|
1647 | }
|
1648 |
|
1649 |
|
1650 |
|
1651 |
|
1652 | if (marks) {
|
1653 | state.hasInsertPrefixInCompositon = true;
|
1654 | Transforms.insertNodes(editor, _objectSpread$1({
|
1655 | text: '\uFEFF'
|
1656 | }, marks), {
|
1657 | select: true
|
1658 | });
|
1659 | }
|
1660 | }
|
1661 | }
|
1662 | }, [attributes.onCompositionStart]),
|
1663 | onCopy: useCallback(event => {
|
1664 | if (hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onCopy)) {
|
1665 | event.preventDefault();
|
1666 | ReactEditor.setFragmentData(editor, event.clipboardData, 'copy');
|
1667 | }
|
1668 | }, [attributes.onCopy]),
|
1669 | onCut: useCallback(event => {
|
1670 | if (!readOnly && hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onCut)) {
|
1671 | event.preventDefault();
|
1672 | ReactEditor.setFragmentData(editor, event.clipboardData, 'cut');
|
1673 | var {
|
1674 | selection
|
1675 | } = editor;
|
1676 |
|
1677 | if (selection) {
|
1678 | if (Range.isExpanded(selection)) {
|
1679 | Editor.deleteFragment(editor);
|
1680 | } else {
|
1681 | var node = Node.parent(editor, selection.anchor.path);
|
1682 |
|
1683 | if (Editor.isVoid(editor, node)) {
|
1684 | Transforms.delete(editor);
|
1685 | }
|
1686 | }
|
1687 | }
|
1688 | }
|
1689 | }, [readOnly, attributes.onCut]),
|
1690 | onDragOver: useCallback(event => {
|
1691 | if (hasTarget(editor, event.target) && !isEventHandled(event, attributes.onDragOver)) {
|
1692 |
|
1693 |
|
1694 |
|
1695 | var node = ReactEditor.toSlateNode(editor, event.target);
|
1696 |
|
1697 | if (Editor.isVoid(editor, node)) {
|
1698 | event.preventDefault();
|
1699 | }
|
1700 | }
|
1701 | }, [attributes.onDragOver]),
|
1702 | onDragStart: useCallback(event => {
|
1703 | if (!readOnly && hasTarget(editor, event.target) && !isEventHandled(event, attributes.onDragStart)) {
|
1704 | var node = ReactEditor.toSlateNode(editor, event.target);
|
1705 | var path = ReactEditor.findPath(editor, node);
|
1706 | var voidMatch = Editor.isVoid(editor, node) || Editor.void(editor, {
|
1707 | at: path,
|
1708 | voids: true
|
1709 | });
|
1710 |
|
1711 |
|
1712 | if (voidMatch) {
|
1713 | var range = Editor.range(editor, path);
|
1714 | Transforms.select(editor, range);
|
1715 | }
|
1716 |
|
1717 | state.isDraggingInternally = true;
|
1718 | ReactEditor.setFragmentData(editor, event.dataTransfer, 'drag');
|
1719 | }
|
1720 | }, [readOnly, attributes.onDragStart]),
|
1721 | onDrop: useCallback(event => {
|
1722 | if (!readOnly && hasTarget(editor, event.target) && !isEventHandled(event, attributes.onDrop)) {
|
1723 | event.preventDefault();
|
1724 |
|
1725 | var draggedRange = editor.selection;
|
1726 |
|
1727 | var range = ReactEditor.findEventRange(editor, event);
|
1728 | var data = event.dataTransfer;
|
1729 | Transforms.select(editor, range);
|
1730 |
|
1731 | if (state.isDraggingInternally) {
|
1732 | if (draggedRange && !Range.equals(draggedRange, range) && !Editor.void(editor, {
|
1733 | at: range,
|
1734 | voids: true
|
1735 | })) {
|
1736 | Transforms.delete(editor, {
|
1737 | at: draggedRange
|
1738 | });
|
1739 | }
|
1740 |
|
1741 | state.isDraggingInternally = false;
|
1742 | }
|
1743 |
|
1744 | ReactEditor.insertData(editor, data);
|
1745 |
|
1746 |
|
1747 | if (!ReactEditor.isFocused(editor)) {
|
1748 | ReactEditor.focus(editor);
|
1749 | }
|
1750 | }
|
1751 | }, [readOnly, attributes.onDrop]),
|
1752 | onDragEnd: useCallback(event => {
|
1753 |
|
1754 |
|
1755 |
|
1756 | if (!readOnly && state.isDraggingInternally && hasTarget(editor, event.target) && !isEventHandled(event, attributes.onDragEnd)) {
|
1757 | state.isDraggingInternally = false;
|
1758 | }
|
1759 | }, [readOnly, attributes.onDragEnd]),
|
1760 | onFocus: useCallback(event => {
|
1761 | if (!readOnly && !state.isUpdatingSelection && hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onFocus)) {
|
1762 | var el = ReactEditor.toDOMNode(editor, editor);
|
1763 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
1764 | state.latestElement = root.activeElement;
|
1765 |
|
1766 |
|
1767 |
|
1768 | if (IS_FIREFOX && event.target !== el) {
|
1769 | el.focus();
|
1770 | return;
|
1771 | }
|
1772 |
|
1773 | IS_FOCUSED.set(editor, true);
|
1774 | }
|
1775 | }, [readOnly, attributes.onFocus]),
|
1776 | onKeyDown: useCallback(event => {
|
1777 | if (!readOnly && !state.isComposing && hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onKeyDown)) {
|
1778 | var {
|
1779 | nativeEvent
|
1780 | } = event;
|
1781 | var {
|
1782 | selection
|
1783 | } = editor;
|
1784 | var element = editor.children[selection !== null ? selection.focus.path[0] : 0];
|
1785 | var isRTL = getDirection(Node.string(element)) === 'rtl';
|
1786 |
|
1787 |
|
1788 |
|
1789 |
|
1790 | if (Hotkeys.isRedo(nativeEvent)) {
|
1791 | event.preventDefault();
|
1792 | var maybeHistoryEditor = editor;
|
1793 |
|
1794 | if (typeof maybeHistoryEditor.redo === 'function') {
|
1795 | maybeHistoryEditor.redo();
|
1796 | }
|
1797 |
|
1798 | return;
|
1799 | }
|
1800 |
|
1801 | if (Hotkeys.isUndo(nativeEvent)) {
|
1802 | event.preventDefault();
|
1803 | var _maybeHistoryEditor = editor;
|
1804 |
|
1805 | if (typeof _maybeHistoryEditor.undo === 'function') {
|
1806 | _maybeHistoryEditor.undo();
|
1807 | }
|
1808 |
|
1809 | return;
|
1810 | }
|
1811 |
|
1812 |
|
1813 |
|
1814 |
|
1815 |
|
1816 | if (Hotkeys.isMoveLineBackward(nativeEvent)) {
|
1817 | event.preventDefault();
|
1818 | Transforms.move(editor, {
|
1819 | unit: 'line',
|
1820 | reverse: true
|
1821 | });
|
1822 | return;
|
1823 | }
|
1824 |
|
1825 | if (Hotkeys.isMoveLineForward(nativeEvent)) {
|
1826 | event.preventDefault();
|
1827 | Transforms.move(editor, {
|
1828 | unit: 'line'
|
1829 | });
|
1830 | return;
|
1831 | }
|
1832 |
|
1833 | if (Hotkeys.isExtendLineBackward(nativeEvent)) {
|
1834 | event.preventDefault();
|
1835 | Transforms.move(editor, {
|
1836 | unit: 'line',
|
1837 | edge: 'focus',
|
1838 | reverse: true
|
1839 | });
|
1840 | return;
|
1841 | }
|
1842 |
|
1843 | if (Hotkeys.isExtendLineForward(nativeEvent)) {
|
1844 | event.preventDefault();
|
1845 | Transforms.move(editor, {
|
1846 | unit: 'line',
|
1847 | edge: 'focus'
|
1848 | });
|
1849 | return;
|
1850 | }
|
1851 |
|
1852 |
|
1853 |
|
1854 |
|
1855 |
|
1856 |
|
1857 | if (Hotkeys.isMoveBackward(nativeEvent)) {
|
1858 | event.preventDefault();
|
1859 |
|
1860 | if (selection && Range.isCollapsed(selection)) {
|
1861 | Transforms.move(editor, {
|
1862 | reverse: !isRTL
|
1863 | });
|
1864 | } else {
|
1865 | Transforms.collapse(editor, {
|
1866 | edge: 'start'
|
1867 | });
|
1868 | }
|
1869 |
|
1870 | return;
|
1871 | }
|
1872 |
|
1873 | if (Hotkeys.isMoveForward(nativeEvent)) {
|
1874 | event.preventDefault();
|
1875 |
|
1876 | if (selection && Range.isCollapsed(selection)) {
|
1877 | Transforms.move(editor, {
|
1878 | reverse: isRTL
|
1879 | });
|
1880 | } else {
|
1881 | Transforms.collapse(editor, {
|
1882 | edge: 'end'
|
1883 | });
|
1884 | }
|
1885 |
|
1886 | return;
|
1887 | }
|
1888 |
|
1889 | if (Hotkeys.isMoveWordBackward(nativeEvent)) {
|
1890 | event.preventDefault();
|
1891 |
|
1892 | if (selection && Range.isExpanded(selection)) {
|
1893 | Transforms.collapse(editor, {
|
1894 | edge: 'focus'
|
1895 | });
|
1896 | }
|
1897 |
|
1898 | Transforms.move(editor, {
|
1899 | unit: 'word',
|
1900 | reverse: !isRTL
|
1901 | });
|
1902 | return;
|
1903 | }
|
1904 |
|
1905 | if (Hotkeys.isMoveWordForward(nativeEvent)) {
|
1906 | event.preventDefault();
|
1907 |
|
1908 | if (selection && Range.isExpanded(selection)) {
|
1909 | Transforms.collapse(editor, {
|
1910 | edge: 'focus'
|
1911 | });
|
1912 | }
|
1913 |
|
1914 | Transforms.move(editor, {
|
1915 | unit: 'word',
|
1916 | reverse: isRTL
|
1917 | });
|
1918 | return;
|
1919 | }
|
1920 |
|
1921 |
|
1922 |
|
1923 |
|
1924 | if (!HAS_BEFORE_INPUT_SUPPORT) {
|
1925 |
|
1926 |
|
1927 | if (Hotkeys.isBold(nativeEvent) || Hotkeys.isItalic(nativeEvent) || Hotkeys.isTransposeCharacter(nativeEvent)) {
|
1928 | event.preventDefault();
|
1929 | return;
|
1930 | }
|
1931 |
|
1932 | if (Hotkeys.isSplitBlock(nativeEvent)) {
|
1933 | event.preventDefault();
|
1934 | Editor.insertBreak(editor);
|
1935 | return;
|
1936 | }
|
1937 |
|
1938 | if (Hotkeys.isDeleteBackward(nativeEvent)) {
|
1939 | event.preventDefault();
|
1940 |
|
1941 | if (selection && Range.isExpanded(selection)) {
|
1942 | Editor.deleteFragment(editor, {
|
1943 | direction: 'backward'
|
1944 | });
|
1945 | } else {
|
1946 | Editor.deleteBackward(editor);
|
1947 | }
|
1948 |
|
1949 | return;
|
1950 | }
|
1951 |
|
1952 | if (Hotkeys.isDeleteForward(nativeEvent)) {
|
1953 | event.preventDefault();
|
1954 |
|
1955 | if (selection && Range.isExpanded(selection)) {
|
1956 | Editor.deleteFragment(editor, {
|
1957 | direction: 'forward'
|
1958 | });
|
1959 | } else {
|
1960 | Editor.deleteForward(editor);
|
1961 | }
|
1962 |
|
1963 | return;
|
1964 | }
|
1965 |
|
1966 | if (Hotkeys.isDeleteLineBackward(nativeEvent)) {
|
1967 | event.preventDefault();
|
1968 |
|
1969 | if (selection && Range.isExpanded(selection)) {
|
1970 | Editor.deleteFragment(editor, {
|
1971 | direction: 'backward'
|
1972 | });
|
1973 | } else {
|
1974 | Editor.deleteBackward(editor, {
|
1975 | unit: 'line'
|
1976 | });
|
1977 | }
|
1978 |
|
1979 | return;
|
1980 | }
|
1981 |
|
1982 | if (Hotkeys.isDeleteLineForward(nativeEvent)) {
|
1983 | event.preventDefault();
|
1984 |
|
1985 | if (selection && Range.isExpanded(selection)) {
|
1986 | Editor.deleteFragment(editor, {
|
1987 | direction: 'forward'
|
1988 | });
|
1989 | } else {
|
1990 | Editor.deleteForward(editor, {
|
1991 | unit: 'line'
|
1992 | });
|
1993 | }
|
1994 |
|
1995 | return;
|
1996 | }
|
1997 |
|
1998 | if (Hotkeys.isDeleteWordBackward(nativeEvent)) {
|
1999 | event.preventDefault();
|
2000 |
|
2001 | if (selection && Range.isExpanded(selection)) {
|
2002 | Editor.deleteFragment(editor, {
|
2003 | direction: 'backward'
|
2004 | });
|
2005 | } else {
|
2006 | Editor.deleteBackward(editor, {
|
2007 | unit: 'word'
|
2008 | });
|
2009 | }
|
2010 |
|
2011 | return;
|
2012 | }
|
2013 |
|
2014 | if (Hotkeys.isDeleteWordForward(nativeEvent)) {
|
2015 | event.preventDefault();
|
2016 |
|
2017 | if (selection && Range.isExpanded(selection)) {
|
2018 | Editor.deleteFragment(editor, {
|
2019 | direction: 'forward'
|
2020 | });
|
2021 | } else {
|
2022 | Editor.deleteForward(editor, {
|
2023 | unit: 'word'
|
2024 | });
|
2025 | }
|
2026 |
|
2027 | return;
|
2028 | }
|
2029 | } else {
|
2030 | if (IS_CHROME || IS_SAFARI) {
|
2031 |
|
2032 |
|
2033 | if (selection && (Hotkeys.isDeleteBackward(nativeEvent) || Hotkeys.isDeleteForward(nativeEvent)) && Range.isCollapsed(selection)) {
|
2034 | var currentNode = Node.parent(editor, selection.anchor.path);
|
2035 |
|
2036 | if (Element$1.isElement(currentNode) && Editor.isVoid(editor, currentNode) && Editor.isInline(editor, currentNode)) {
|
2037 | event.preventDefault();
|
2038 | Editor.deleteBackward(editor, {
|
2039 | unit: 'block'
|
2040 | });
|
2041 | return;
|
2042 | }
|
2043 | }
|
2044 | }
|
2045 | }
|
2046 | }
|
2047 | }, [readOnly, attributes.onKeyDown]),
|
2048 | onPaste: useCallback(event => {
|
2049 | if (!readOnly && hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onPaste)) {
|
2050 |
|
2051 |
|
2052 |
|
2053 |
|
2054 | if (!HAS_BEFORE_INPUT_SUPPORT || isPlainTextOnlyPaste(event.nativeEvent)) {
|
2055 | event.preventDefault();
|
2056 | ReactEditor.insertData(editor, event.clipboardData);
|
2057 | }
|
2058 | }
|
2059 | }, [readOnly, attributes.onPaste])
|
2060 | }), React.createElement(Children, {
|
2061 | decorations: decorations,
|
2062 | node: editor,
|
2063 | renderElement: renderElement,
|
2064 | renderPlaceholder: renderPlaceholder,
|
2065 | renderLeaf: renderLeaf,
|
2066 | selection: editor.selection
|
2067 | }))));
|
2068 | };
|
2069 |
|
2070 |
|
2071 |
|
2072 |
|
2073 | var DefaultPlaceholder = _ref => {
|
2074 | var {
|
2075 | attributes,
|
2076 | children
|
2077 | } = _ref;
|
2078 | return React.createElement("span", Object.assign({}, attributes), children);
|
2079 | };
|
2080 |
|
2081 |
|
2082 |
|
2083 |
|
2084 | var defaultDecorate = () => [];
|
2085 |
|
2086 |
|
2087 |
|
2088 |
|
2089 | var defaultScrollSelectionIntoView = (editor, domRange) => {
|
2090 |
|
2091 |
|
2092 | if (!editor.selection || editor.selection && Range.isCollapsed(editor.selection)) {
|
2093 | var leafEl = domRange.startContainer.parentElement;
|
2094 | leafEl.getBoundingClientRect = domRange.getBoundingClientRect.bind(domRange);
|
2095 | scrollIntoView(leafEl, {
|
2096 | scrollMode: 'if-needed'
|
2097 | });
|
2098 | delete leafEl.getBoundingClientRect;
|
2099 | }
|
2100 | };
|
2101 |
|
2102 |
|
2103 |
|
2104 |
|
2105 | var hasTarget = (editor, target) => {
|
2106 | return isDOMNode(target) && ReactEditor.hasDOMNode(editor, target);
|
2107 | };
|
2108 |
|
2109 |
|
2110 |
|
2111 |
|
2112 | var hasEditableTarget = (editor, target) => {
|
2113 | return isDOMNode(target) && ReactEditor.hasDOMNode(editor, target, {
|
2114 | editable: true
|
2115 | });
|
2116 | };
|
2117 |
|
2118 |
|
2119 |
|
2120 |
|
2121 | var isTargetInsideNonReadonlyVoid = (editor, target) => {
|
2122 | if (IS_READ_ONLY.get(editor)) return false;
|
2123 | var slateNode = hasTarget(editor, target) && ReactEditor.toSlateNode(editor, target);
|
2124 | return Editor.isVoid(editor, slateNode);
|
2125 | };
|
2126 |
|
2127 |
|
2128 |
|
2129 |
|
2130 | var isEventHandled = (event, handler) => {
|
2131 | if (!handler) {
|
2132 | return false;
|
2133 | }
|
2134 |
|
2135 |
|
2136 |
|
2137 | var shouldTreatEventAsHandled = handler(event);
|
2138 |
|
2139 | if (shouldTreatEventAsHandled != null) {
|
2140 | return shouldTreatEventAsHandled;
|
2141 | }
|
2142 |
|
2143 | return event.isDefaultPrevented() || event.isPropagationStopped();
|
2144 | };
|
2145 |
|
2146 |
|
2147 |
|
2148 |
|
2149 | var isDOMEventHandled = (event, handler) => {
|
2150 | if (!handler) {
|
2151 | return false;
|
2152 | }
|
2153 |
|
2154 |
|
2155 |
|
2156 | var shouldTreatEventAsHandled = handler(event);
|
2157 |
|
2158 | if (shouldTreatEventAsHandled != null) {
|
2159 | return shouldTreatEventAsHandled;
|
2160 | }
|
2161 |
|
2162 | return event.defaultPrevented;
|
2163 | };
|
2164 |
|
2165 |
|
2166 |
|
2167 |
|
2168 |
|
2169 |
|
2170 |
|
2171 |
|
2172 |
|
2173 |
|
2174 | function getDiffStart(prev, next) {
|
2175 | var length = Math.min(prev.length, next.length);
|
2176 |
|
2177 | for (var i = 0; i < length; i++) {
|
2178 | if (prev.charAt(i) !== next.charAt(i)) return i;
|
2179 | }
|
2180 |
|
2181 | if (prev.length !== next.length) return length;
|
2182 | return null;
|
2183 | }
|
2184 |
|
2185 |
|
2186 |
|
2187 |
|
2188 |
|
2189 |
|
2190 |
|
2191 |
|
2192 |
|
2193 |
|
2194 |
|
2195 |
|
2196 | function getDiffEnd(prev, next, max) {
|
2197 | var prevLength = prev.length;
|
2198 | var nextLength = next.length;
|
2199 | var length = Math.min(prevLength, nextLength, max);
|
2200 |
|
2201 | for (var i = 0; i < length; i++) {
|
2202 | var prevChar = prev.charAt(prevLength - i - 1);
|
2203 | var nextChar = next.charAt(nextLength - i - 1);
|
2204 | if (prevChar !== nextChar) return i;
|
2205 | }
|
2206 |
|
2207 | if (prev.length !== next.length) return length;
|
2208 | return null;
|
2209 | }
|
2210 |
|
2211 |
|
2212 |
|
2213 |
|
2214 |
|
2215 |
|
2216 |
|
2217 |
|
2218 |
|
2219 |
|
2220 |
|
2221 |
|
2222 |
|
2223 |
|
2224 | function getDiffOffsets(prev, next) {
|
2225 | if (prev === next) return null;
|
2226 | var start = getDiffStart(prev, next);
|
2227 | if (start === null) return null;
|
2228 | var maxEnd = Math.min(prev.length - start, next.length - start);
|
2229 | var end = getDiffEnd(prev, next, maxEnd);
|
2230 | if (end === null) return null;
|
2231 | return {
|
2232 | start,
|
2233 | end
|
2234 | };
|
2235 | }
|
2236 |
|
2237 |
|
2238 |
|
2239 |
|
2240 |
|
2241 |
|
2242 |
|
2243 |
|
2244 |
|
2245 | function sliceText(text, offsets) {
|
2246 | return text.slice(offsets.start, text.length - offsets.end);
|
2247 | }
|
2248 |
|
2249 |
|
2250 |
|
2251 |
|
2252 |
|
2253 |
|
2254 |
|
2255 |
|
2256 |
|
2257 |
|
2258 |
|
2259 | function diffText(prev, next) {
|
2260 | if (prev === undefined || next === undefined) return null;
|
2261 | var offsets = getDiffOffsets(prev, next);
|
2262 | if (offsets == null) return null;
|
2263 | var insertText = sliceText(next, offsets);
|
2264 | var removeText = sliceText(prev, offsets);
|
2265 | return {
|
2266 | start: offsets.start,
|
2267 | end: prev.length - offsets.end,
|
2268 | insertText,
|
2269 | removeText
|
2270 | };
|
2271 | }
|
2272 | function combineInsertedText(insertedText) {
|
2273 | return insertedText.reduce((acc, _ref) => {
|
2274 | var {
|
2275 | text
|
2276 | } = _ref;
|
2277 | return "".concat(acc).concat(text.insertText);
|
2278 | }, '');
|
2279 | }
|
2280 | function getTextInsertion(editor, domNode) {
|
2281 | var node = ReactEditor.toSlateNode(editor, domNode);
|
2282 |
|
2283 | if (!Text$1.isText(node)) {
|
2284 | return undefined;
|
2285 | }
|
2286 |
|
2287 | var prevText = node.text;
|
2288 | var nextText = domNode.textContent;
|
2289 |
|
2290 | if (nextText.endsWith('\n')) {
|
2291 | nextText = nextText.slice(0, nextText.length - 1);
|
2292 | }
|
2293 |
|
2294 |
|
2295 | if (nextText !== prevText) {
|
2296 | var textDiff = diffText(prevText, nextText);
|
2297 |
|
2298 | if (textDiff !== null) {
|
2299 | var textPath = ReactEditor.findPath(editor, node);
|
2300 | return {
|
2301 | text: textDiff,
|
2302 | path: textPath
|
2303 | };
|
2304 | }
|
2305 | }
|
2306 |
|
2307 | return undefined;
|
2308 | }
|
2309 | function normalizeTextInsertionRange(editor, range, _ref2) {
|
2310 | var {
|
2311 | path,
|
2312 | text
|
2313 | } = _ref2;
|
2314 | var insertionRange = {
|
2315 | anchor: {
|
2316 | path,
|
2317 | offset: text.start
|
2318 | },
|
2319 | focus: {
|
2320 | path,
|
2321 | offset: text.end
|
2322 | }
|
2323 | };
|
2324 |
|
2325 | if (!range || !Range.isCollapsed(range)) {
|
2326 | return insertionRange;
|
2327 | }
|
2328 |
|
2329 | var {
|
2330 | insertText,
|
2331 | removeText
|
2332 | } = text;
|
2333 | var isSingleCharacterInsertion = insertText.length === 1 || removeText.length === 1;
|
2334 | |
2335 |
|
2336 |
|
2337 |
|
2338 |
|
2339 |
|
2340 |
|
2341 |
|
2342 |
|
2343 |
|
2344 |
|
2345 |
|
2346 |
|
2347 |
|
2348 |
|
2349 |
|
2350 |
|
2351 |
|
2352 |
|
2353 |
|
2354 | if (isSingleCharacterInsertion && Path.equals(range.anchor.path, path)) {
|
2355 | var [_text] = Array.from(Editor.nodes(editor, {
|
2356 | at: range,
|
2357 | match: Text$1.isText
|
2358 | }));
|
2359 |
|
2360 | if (_text) {
|
2361 | var [node] = _text;
|
2362 | var {
|
2363 | anchor
|
2364 | } = range;
|
2365 | var characterBeforeAnchor = node.text[anchor.offset - 1];
|
2366 | var characterAfterAnchor = node.text[anchor.offset];
|
2367 |
|
2368 | if (insertText.length === 1 && insertText === characterAfterAnchor) {
|
2369 |
|
2370 | return range;
|
2371 | }
|
2372 |
|
2373 | if (removeText.length === 1 && removeText === characterBeforeAnchor) {
|
2374 |
|
2375 | return {
|
2376 | anchor: {
|
2377 | path,
|
2378 | offset: anchor.offset - 1
|
2379 | },
|
2380 | focus: {
|
2381 | path,
|
2382 | offset: anchor.offset
|
2383 | }
|
2384 | };
|
2385 | }
|
2386 | }
|
2387 | }
|
2388 |
|
2389 | return insertionRange;
|
2390 | }
|
2391 |
|
2392 |
|
2393 |
|
2394 |
|
2395 | var n = 0;
|
2396 |
|
2397 |
|
2398 |
|
2399 |
|
2400 |
|
2401 | class Key {
|
2402 | constructor() {
|
2403 | this.id = "".concat(n++);
|
2404 | }
|
2405 |
|
2406 | }
|
2407 |
|
2408 | var ReactEditor = {
|
2409 | |
2410 |
|
2411 |
|
2412 | getWindow(editor) {
|
2413 | var window = EDITOR_TO_WINDOW.get(editor);
|
2414 |
|
2415 | if (!window) {
|
2416 | throw new Error('Unable to find a host window element for this editor');
|
2417 | }
|
2418 |
|
2419 | return window;
|
2420 | },
|
2421 |
|
2422 | |
2423 |
|
2424 |
|
2425 | findKey(editor, node) {
|
2426 | var key = NODE_TO_KEY.get(node);
|
2427 |
|
2428 | if (!key) {
|
2429 | key = new Key();
|
2430 | NODE_TO_KEY.set(node, key);
|
2431 | }
|
2432 |
|
2433 | return key;
|
2434 | },
|
2435 |
|
2436 | |
2437 |
|
2438 |
|
2439 | findPath(editor, node) {
|
2440 | var path = [];
|
2441 | var child = node;
|
2442 |
|
2443 | while (true) {
|
2444 | var parent = NODE_TO_PARENT.get(child);
|
2445 |
|
2446 | if (parent == null) {
|
2447 | if (Editor.isEditor(child)) {
|
2448 | return path;
|
2449 | } else {
|
2450 | break;
|
2451 | }
|
2452 | }
|
2453 |
|
2454 | var i = NODE_TO_INDEX.get(child);
|
2455 |
|
2456 | if (i == null) {
|
2457 | break;
|
2458 | }
|
2459 |
|
2460 | path.unshift(i);
|
2461 | child = parent;
|
2462 | }
|
2463 |
|
2464 | throw new Error("Unable to find the path for Slate node: ".concat(JSON.stringify(node)));
|
2465 | },
|
2466 |
|
2467 | |
2468 |
|
2469 |
|
2470 | findDocumentOrShadowRoot(editor) {
|
2471 | var el = ReactEditor.toDOMNode(editor, editor);
|
2472 | var root = el.getRootNode();
|
2473 |
|
2474 | if ((root instanceof Document || root instanceof ShadowRoot) && root.getSelection != null) {
|
2475 | return root;
|
2476 | }
|
2477 |
|
2478 | return el.ownerDocument;
|
2479 | },
|
2480 |
|
2481 | |
2482 |
|
2483 |
|
2484 | isFocused(editor) {
|
2485 | return !!IS_FOCUSED.get(editor);
|
2486 | },
|
2487 |
|
2488 | |
2489 |
|
2490 |
|
2491 | isReadOnly(editor) {
|
2492 | return !!IS_READ_ONLY.get(editor);
|
2493 | },
|
2494 |
|
2495 | |
2496 |
|
2497 |
|
2498 | blur(editor) {
|
2499 | var el = ReactEditor.toDOMNode(editor, editor);
|
2500 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
2501 | IS_FOCUSED.set(editor, false);
|
2502 |
|
2503 | if (root.activeElement === el) {
|
2504 | el.blur();
|
2505 | }
|
2506 | },
|
2507 |
|
2508 | |
2509 |
|
2510 |
|
2511 | focus(editor) {
|
2512 | var el = ReactEditor.toDOMNode(editor, editor);
|
2513 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
2514 | IS_FOCUSED.set(editor, true);
|
2515 |
|
2516 | if (root.activeElement !== el) {
|
2517 | el.focus({
|
2518 | preventScroll: true
|
2519 | });
|
2520 | }
|
2521 | },
|
2522 |
|
2523 | |
2524 |
|
2525 |
|
2526 | deselect(editor) {
|
2527 | ReactEditor.toDOMNode(editor, editor);
|
2528 | var {
|
2529 | selection
|
2530 | } = editor;
|
2531 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
2532 | var domSelection = root.getSelection();
|
2533 |
|
2534 | if (domSelection && domSelection.rangeCount > 0) {
|
2535 | domSelection.removeAllRanges();
|
2536 | }
|
2537 |
|
2538 | if (selection) {
|
2539 | Transforms.deselect(editor);
|
2540 | }
|
2541 | },
|
2542 |
|
2543 | |
2544 |
|
2545 |
|
2546 | hasDOMNode(editor, target) {
|
2547 | var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
2548 | var {
|
2549 | editable = false
|
2550 | } = options;
|
2551 | var editorEl = ReactEditor.toDOMNode(editor, editor);
|
2552 | var targetEl;
|
2553 |
|
2554 |
|
2555 |
|
2556 |
|
2557 | try {
|
2558 | targetEl = isDOMElement(target) ? target : target.parentElement;
|
2559 | } catch (err) {
|
2560 | if (!err.message.includes('Permission denied to access property "nodeType"')) {
|
2561 | throw err;
|
2562 | }
|
2563 | }
|
2564 |
|
2565 | if (!targetEl) {
|
2566 | return false;
|
2567 | }
|
2568 |
|
2569 | return targetEl.closest("[data-slate-editor]") === editorEl && (!editable || targetEl.isContentEditable ? true : typeof targetEl.isContentEditable === 'boolean' &&
|
2570 |
|
2571 | targetEl.closest('[contenteditable="false"]') === editorEl || !!targetEl.getAttribute('data-slate-zero-width'));
|
2572 | },
|
2573 |
|
2574 | |
2575 |
|
2576 |
|
2577 | insertData(editor, data) {
|
2578 | editor.insertData(data);
|
2579 | },
|
2580 |
|
2581 | |
2582 |
|
2583 |
|
2584 | insertFragmentData(editor, data) {
|
2585 | return editor.insertFragmentData(data);
|
2586 | },
|
2587 |
|
2588 | |
2589 |
|
2590 |
|
2591 | insertTextData(editor, data) {
|
2592 | return editor.insertTextData(data);
|
2593 | },
|
2594 |
|
2595 | |
2596 |
|
2597 |
|
2598 | setFragmentData(editor, data, originEvent) {
|
2599 | editor.setFragmentData(data, originEvent);
|
2600 | },
|
2601 |
|
2602 | |
2603 |
|
2604 |
|
2605 | toDOMNode(editor, node) {
|
2606 | var KEY_TO_ELEMENT = EDITOR_TO_KEY_TO_ELEMENT.get(editor);
|
2607 | var domNode = Editor.isEditor(node) ? EDITOR_TO_ELEMENT.get(editor) : KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.get(ReactEditor.findKey(editor, node));
|
2608 |
|
2609 | if (!domNode) {
|
2610 | throw new Error("Cannot resolve a DOM node from Slate node: ".concat(JSON.stringify(node)));
|
2611 | }
|
2612 |
|
2613 | return domNode;
|
2614 | },
|
2615 |
|
2616 | |
2617 |
|
2618 |
|
2619 | toDOMPoint(editor, point) {
|
2620 | var [node] = Editor.node(editor, point.path);
|
2621 | var el = ReactEditor.toDOMNode(editor, node);
|
2622 | var domPoint;
|
2623 |
|
2624 |
|
2625 | if (Editor.void(editor, {
|
2626 | at: point
|
2627 | })) {
|
2628 | point = {
|
2629 | path: point.path,
|
2630 | offset: 0
|
2631 | };
|
2632 | }
|
2633 |
|
2634 |
|
2635 |
|
2636 |
|
2637 | var selector = "[data-slate-string], [data-slate-zero-width]";
|
2638 | var texts = Array.from(el.querySelectorAll(selector));
|
2639 | var start = 0;
|
2640 |
|
2641 | for (var text of texts) {
|
2642 | var domNode = text.childNodes[0];
|
2643 |
|
2644 | if (domNode == null || domNode.textContent == null) {
|
2645 | continue;
|
2646 | }
|
2647 |
|
2648 | var {
|
2649 | length
|
2650 | } = domNode.textContent;
|
2651 | var attr = text.getAttribute('data-slate-length');
|
2652 | var trueLength = attr == null ? length : parseInt(attr, 10);
|
2653 | var end = start + trueLength;
|
2654 |
|
2655 | if (point.offset <= end) {
|
2656 | var offset = Math.min(length, Math.max(0, point.offset - start));
|
2657 | domPoint = [domNode, offset];
|
2658 | break;
|
2659 | }
|
2660 |
|
2661 | start = end;
|
2662 | }
|
2663 |
|
2664 | if (!domPoint) {
|
2665 | throw new Error("Cannot resolve a DOM point from Slate point: ".concat(JSON.stringify(point)));
|
2666 | }
|
2667 |
|
2668 | return domPoint;
|
2669 | },
|
2670 |
|
2671 | |
2672 |
|
2673 |
|
2674 |
|
2675 |
|
2676 |
|
2677 |
|
2678 |
|
2679 | toDOMRange(editor, range) {
|
2680 | var {
|
2681 | anchor,
|
2682 | focus
|
2683 | } = range;
|
2684 | var isBackward = Range.isBackward(range);
|
2685 | var domAnchor = ReactEditor.toDOMPoint(editor, anchor);
|
2686 | var domFocus = Range.isCollapsed(range) ? domAnchor : ReactEditor.toDOMPoint(editor, focus);
|
2687 | var window = ReactEditor.getWindow(editor);
|
2688 | var domRange = window.document.createRange();
|
2689 | var [startNode, startOffset] = isBackward ? domFocus : domAnchor;
|
2690 | var [endNode, endOffset] = isBackward ? domAnchor : domFocus;
|
2691 |
|
2692 |
|
2693 |
|
2694 | var startEl = isDOMElement(startNode) ? startNode : startNode.parentElement;
|
2695 | var isStartAtZeroWidth = !!startEl.getAttribute('data-slate-zero-width');
|
2696 | var endEl = isDOMElement(endNode) ? endNode : endNode.parentElement;
|
2697 | var isEndAtZeroWidth = !!endEl.getAttribute('data-slate-zero-width');
|
2698 | domRange.setStart(startNode, isStartAtZeroWidth ? 1 : startOffset);
|
2699 | domRange.setEnd(endNode, isEndAtZeroWidth ? 1 : endOffset);
|
2700 | return domRange;
|
2701 | },
|
2702 |
|
2703 | |
2704 |
|
2705 |
|
2706 | toSlateNode(editor, domNode) {
|
2707 | var domEl = isDOMElement(domNode) ? domNode : domNode.parentElement;
|
2708 |
|
2709 | if (domEl && !domEl.hasAttribute('data-slate-node')) {
|
2710 | domEl = domEl.closest("[data-slate-node]");
|
2711 | }
|
2712 |
|
2713 | var node = domEl ? ELEMENT_TO_NODE.get(domEl) : null;
|
2714 |
|
2715 | if (!node) {
|
2716 | throw new Error("Cannot resolve a Slate node from DOM node: ".concat(domEl));
|
2717 | }
|
2718 |
|
2719 | return node;
|
2720 | },
|
2721 |
|
2722 | |
2723 |
|
2724 |
|
2725 | findEventRange(editor, event) {
|
2726 | if ('nativeEvent' in event) {
|
2727 | event = event.nativeEvent;
|
2728 | }
|
2729 |
|
2730 | var {
|
2731 | clientX: x,
|
2732 | clientY: y,
|
2733 | target
|
2734 | } = event;
|
2735 |
|
2736 | if (x == null || y == null) {
|
2737 | throw new Error("Cannot resolve a Slate range from a DOM event: ".concat(event));
|
2738 | }
|
2739 |
|
2740 | var node = ReactEditor.toSlateNode(editor, event.target);
|
2741 | var path = ReactEditor.findPath(editor, node);
|
2742 |
|
2743 |
|
2744 |
|
2745 | if (Editor.isVoid(editor, node)) {
|
2746 | var rect = target.getBoundingClientRect();
|
2747 | var isPrev = editor.isInline(node) ? x - rect.left < rect.left + rect.width - x : y - rect.top < rect.top + rect.height - y;
|
2748 | var edge = Editor.point(editor, path, {
|
2749 | edge: isPrev ? 'start' : 'end'
|
2750 | });
|
2751 | var point = isPrev ? Editor.before(editor, edge) : Editor.after(editor, edge);
|
2752 |
|
2753 | if (point) {
|
2754 | var _range = Editor.range(editor, point);
|
2755 |
|
2756 | return _range;
|
2757 | }
|
2758 | }
|
2759 |
|
2760 |
|
2761 | var domRange;
|
2762 | var {
|
2763 | document
|
2764 | } = ReactEditor.getWindow(editor);
|
2765 |
|
2766 | if (document.caretRangeFromPoint) {
|
2767 | domRange = document.caretRangeFromPoint(x, y);
|
2768 | } else {
|
2769 | var position = document.caretPositionFromPoint(x, y);
|
2770 |
|
2771 | if (position) {
|
2772 | domRange = document.createRange();
|
2773 | domRange.setStart(position.offsetNode, position.offset);
|
2774 | domRange.setEnd(position.offsetNode, position.offset);
|
2775 | }
|
2776 | }
|
2777 |
|
2778 | if (!domRange) {
|
2779 | throw new Error("Cannot resolve a Slate range from a DOM event: ".concat(event));
|
2780 | }
|
2781 |
|
2782 |
|
2783 | var range = ReactEditor.toSlateRange(editor, domRange, {
|
2784 | exactMatch: false,
|
2785 | suppressThrow: false
|
2786 | });
|
2787 | return range;
|
2788 | },
|
2789 |
|
2790 | |
2791 |
|
2792 |
|
2793 | toSlatePoint(editor, domPoint, options) {
|
2794 | var {
|
2795 | exactMatch,
|
2796 | suppressThrow
|
2797 | } = options;
|
2798 | var [nearestNode, nearestOffset] = exactMatch ? domPoint : normalizeDOMPoint(domPoint);
|
2799 | var parentNode = nearestNode.parentNode;
|
2800 | var textNode = null;
|
2801 | var offset = 0;
|
2802 |
|
2803 | if (parentNode) {
|
2804 | var _domNode$textContent;
|
2805 |
|
2806 | var voidNode = parentNode.closest('[data-slate-void="true"]');
|
2807 | var leafNode = parentNode.closest('[data-slate-leaf]');
|
2808 | var domNode = null;
|
2809 |
|
2810 |
|
2811 | if (leafNode) {
|
2812 | textNode = leafNode.closest('[data-slate-node="text"]');
|
2813 | var window = ReactEditor.getWindow(editor);
|
2814 | var range = window.document.createRange();
|
2815 | range.setStart(textNode, 0);
|
2816 | range.setEnd(nearestNode, nearestOffset);
|
2817 | var contents = range.cloneContents();
|
2818 | var removals = [...Array.prototype.slice.call(contents.querySelectorAll('[data-slate-zero-width]')), ...Array.prototype.slice.call(contents.querySelectorAll('[contenteditable=false]'))];
|
2819 | removals.forEach(el => {
|
2820 | el.parentNode.removeChild(el);
|
2821 | });
|
2822 |
|
2823 |
|
2824 |
|
2825 |
|
2826 |
|
2827 | offset = contents.textContent.length;
|
2828 | domNode = textNode;
|
2829 | } else if (voidNode) {
|
2830 |
|
2831 |
|
2832 | leafNode = voidNode.querySelector('[data-slate-leaf]');
|
2833 |
|
2834 | if (!leafNode) {
|
2835 | offset = 1;
|
2836 | } else {
|
2837 | textNode = leafNode.closest('[data-slate-node="text"]');
|
2838 | domNode = leafNode;
|
2839 | offset = domNode.textContent.length;
|
2840 | domNode.querySelectorAll('[data-slate-zero-width]').forEach(el => {
|
2841 | offset -= el.textContent.length;
|
2842 | });
|
2843 | }
|
2844 | }
|
2845 |
|
2846 | if (domNode && offset === domNode.textContent.length && (parentNode.hasAttribute('data-slate-zero-width') || IS_FIREFOX && (_domNode$textContent = domNode.textContent) !== null && _domNode$textContent !== void 0 && _domNode$textContent.endsWith('\n\n'))) {
|
2847 | offset--;
|
2848 | }
|
2849 | }
|
2850 |
|
2851 | if (!textNode) {
|
2852 | if (suppressThrow) {
|
2853 | return null;
|
2854 | }
|
2855 |
|
2856 | throw new Error("Cannot resolve a Slate point from DOM point: ".concat(domPoint));
|
2857 | }
|
2858 |
|
2859 |
|
2860 |
|
2861 |
|
2862 | var slateNode = ReactEditor.toSlateNode(editor, textNode);
|
2863 | var path = ReactEditor.findPath(editor, slateNode);
|
2864 | return {
|
2865 | path,
|
2866 | offset
|
2867 | };
|
2868 | },
|
2869 |
|
2870 | |
2871 |
|
2872 |
|
2873 | toSlateRange(editor, domRange, options) {
|
2874 | var {
|
2875 | exactMatch,
|
2876 | suppressThrow
|
2877 | } = options;
|
2878 | var el = isDOMSelection(domRange) ? domRange.anchorNode : domRange.startContainer;
|
2879 | var anchorNode;
|
2880 | var anchorOffset;
|
2881 | var focusNode;
|
2882 | var focusOffset;
|
2883 | var isCollapsed;
|
2884 |
|
2885 | if (el) {
|
2886 | if (isDOMSelection(domRange)) {
|
2887 | anchorNode = domRange.anchorNode;
|
2888 | anchorOffset = domRange.anchorOffset;
|
2889 | focusNode = domRange.focusNode;
|
2890 | focusOffset = domRange.focusOffset;
|
2891 |
|
2892 |
|
2893 |
|
2894 |
|
2895 | if (IS_CHROME && hasShadowRoot()) {
|
2896 | isCollapsed = domRange.anchorNode === domRange.focusNode && domRange.anchorOffset === domRange.focusOffset;
|
2897 | } else {
|
2898 | isCollapsed = domRange.isCollapsed;
|
2899 | }
|
2900 | } else {
|
2901 | anchorNode = domRange.startContainer;
|
2902 | anchorOffset = domRange.startOffset;
|
2903 | focusNode = domRange.endContainer;
|
2904 | focusOffset = domRange.endOffset;
|
2905 | isCollapsed = domRange.collapsed;
|
2906 | }
|
2907 | }
|
2908 |
|
2909 | if (anchorNode == null || focusNode == null || anchorOffset == null || focusOffset == null) {
|
2910 | throw new Error("Cannot resolve a Slate range from DOM range: ".concat(domRange));
|
2911 | }
|
2912 |
|
2913 | var anchor = ReactEditor.toSlatePoint(editor, [anchorNode, anchorOffset], {
|
2914 | exactMatch,
|
2915 | suppressThrow
|
2916 | });
|
2917 |
|
2918 | if (!anchor) {
|
2919 | return null;
|
2920 | }
|
2921 |
|
2922 | var focus = isCollapsed ? anchor : ReactEditor.toSlatePoint(editor, [focusNode, focusOffset], {
|
2923 | exactMatch,
|
2924 | suppressThrow
|
2925 | });
|
2926 |
|
2927 | if (!focus) {
|
2928 | return null;
|
2929 | }
|
2930 |
|
2931 | var range = {
|
2932 | anchor: anchor,
|
2933 | focus: focus
|
2934 | };
|
2935 |
|
2936 |
|
2937 |
|
2938 |
|
2939 | if (Range.isExpanded(range) && Range.isForward(range) && isDOMElement(focusNode) && Editor.void(editor, {
|
2940 | at: range.focus,
|
2941 | mode: 'highest'
|
2942 | })) {
|
2943 | range = Editor.unhangRange(editor, range, {
|
2944 | voids: true
|
2945 | });
|
2946 | }
|
2947 |
|
2948 | return range;
|
2949 | },
|
2950 |
|
2951 | hasRange(editor, range) {
|
2952 | var {
|
2953 | anchor,
|
2954 | focus
|
2955 | } = range;
|
2956 | return Editor.hasPath(editor, anchor.path) && Editor.hasPath(editor, focus.path);
|
2957 | }
|
2958 |
|
2959 | };
|
2960 |
|
2961 | function gatherMutationData(editor, mutations) {
|
2962 | var addedNodes = [];
|
2963 | var removedNodes = [];
|
2964 | var insertedText = [];
|
2965 | var characterDataMutations = [];
|
2966 | mutations.forEach(mutation => {
|
2967 | switch (mutation.type) {
|
2968 | case 'childList':
|
2969 | {
|
2970 | if (mutation.addedNodes.length) {
|
2971 | mutation.addedNodes.forEach(addedNode => {
|
2972 | addedNodes.push(addedNode);
|
2973 | });
|
2974 | }
|
2975 |
|
2976 | mutation.removedNodes.forEach(removedNode => {
|
2977 | removedNodes.push(removedNode);
|
2978 | });
|
2979 | break;
|
2980 | }
|
2981 |
|
2982 | case 'characterData':
|
2983 | {
|
2984 | characterDataMutations.push(mutation);
|
2985 |
|
2986 | var {
|
2987 | parentNode
|
2988 | } = mutation.target;
|
2989 |
|
2990 | if (!parentNode) {
|
2991 | return;
|
2992 | }
|
2993 |
|
2994 | var textInsertion = getTextInsertion(editor, parentNode);
|
2995 |
|
2996 | if (!textInsertion) {
|
2997 | return;
|
2998 | }
|
2999 |
|
3000 |
|
3001 | if (insertedText.some(_ref => {
|
3002 | var {
|
3003 | path
|
3004 | } = _ref;
|
3005 | return Path.equals(path, textInsertion.path);
|
3006 | })) {
|
3007 | return;
|
3008 | }
|
3009 |
|
3010 |
|
3011 | insertedText.push(textInsertion);
|
3012 | }
|
3013 | }
|
3014 | });
|
3015 | return {
|
3016 | addedNodes,
|
3017 | removedNodes,
|
3018 | insertedText,
|
3019 | characterDataMutations
|
3020 | };
|
3021 | }
|
3022 |
|
3023 |
|
3024 |
|
3025 |
|
3026 |
|
3027 |
|
3028 |
|
3029 |
|
3030 |
|
3031 |
|
3032 | var isLineBreak = (editor, _ref2) => {
|
3033 | var {
|
3034 | addedNodes
|
3035 | } = _ref2;
|
3036 | var {
|
3037 | selection
|
3038 | } = editor;
|
3039 | var parentNode = selection ? Node.parent(editor, selection.anchor.path) : null;
|
3040 | var parentDOMNode = parentNode ? ReactEditor.toDOMNode(editor, parentNode) : null;
|
3041 |
|
3042 | if (!parentDOMNode) {
|
3043 | return false;
|
3044 | }
|
3045 |
|
3046 | return addedNodes.some(addedNode => addedNode instanceof HTMLElement && addedNode.tagName === (parentDOMNode === null || parentDOMNode === void 0 ? void 0 : parentDOMNode.tagName));
|
3047 | };
|
3048 |
|
3049 |
|
3050 |
|
3051 |
|
3052 |
|
3053 |
|
3054 | var isDeletion = (_, _ref3) => {
|
3055 | var {
|
3056 | removedNodes
|
3057 | } = _ref3;
|
3058 | return removedNodes.length > 0;
|
3059 | };
|
3060 |
|
3061 |
|
3062 |
|
3063 |
|
3064 |
|
3065 | var isReplaceExpandedSelection = (_ref4, _ref5) => {
|
3066 | var {
|
3067 | selection
|
3068 | } = _ref4;
|
3069 | var {
|
3070 | removedNodes
|
3071 | } = _ref5;
|
3072 | return selection ? Range.isExpanded(selection) && removedNodes.length > 0 : false;
|
3073 | };
|
3074 |
|
3075 |
|
3076 |
|
3077 |
|
3078 | var isTextInsertion = (_, _ref6) => {
|
3079 | var {
|
3080 | insertedText
|
3081 | } = _ref6;
|
3082 | return insertedText.length > 0;
|
3083 | };
|
3084 |
|
3085 |
|
3086 |
|
3087 |
|
3088 | var isRemoveLeafNodes = (_, _ref7) => {
|
3089 | var {
|
3090 | addedNodes,
|
3091 | characterDataMutations,
|
3092 | removedNodes
|
3093 | } = _ref7;
|
3094 | return removedNodes.length > 0 && addedNodes.length === 0 && characterDataMutations.length > 0;
|
3095 | };
|
3096 |
|
3097 |
|
3098 |
|
3099 |
|
3100 |
|
3101 |
|
3102 |
|
3103 |
|
3104 |
|
3105 |
|
3106 |
|
3107 |
|
3108 |
|
3109 |
|
3110 |
|
3111 |
|
3112 |
|
3113 |
|
3114 |
|
3115 |
|
3116 |
|
3117 |
|
3118 |
|
3119 |
|
3120 |
|
3121 |
|
3122 | class AndroidInputManager {
|
3123 | constructor(editor, restoreDOM) {
|
3124 | this.editor = editor;
|
3125 | this.restoreDOM = restoreDOM;
|
3126 | |
3127 |
|
3128 |
|
3129 |
|
3130 |
|
3131 |
|
3132 | this.flush = mutations => {
|
3133 |
|
3134 | try {
|
3135 | this.reconcileMutations(mutations);
|
3136 | } catch (err) {
|
3137 |
|
3138 | console.error(err);
|
3139 |
|
3140 | this.restoreDOM();
|
3141 | }
|
3142 | };
|
3143 | |
3144 |
|
3145 |
|
3146 |
|
3147 |
|
3148 |
|
3149 |
|
3150 | this.reconcileMutations = mutations => {
|
3151 | var mutationData = gatherMutationData(this.editor, mutations);
|
3152 | var {
|
3153 | insertedText,
|
3154 | removedNodes
|
3155 | } = mutationData;
|
3156 |
|
3157 | if (isReplaceExpandedSelection(this.editor, mutationData)) {
|
3158 | var text = combineInsertedText(insertedText);
|
3159 | this.replaceExpandedSelection(text);
|
3160 | } else if (isLineBreak(this.editor, mutationData)) {
|
3161 | this.insertBreak();
|
3162 | } else if (isRemoveLeafNodes(this.editor, mutationData)) {
|
3163 | this.removeLeafNodes(removedNodes);
|
3164 | } else if (isDeletion(this.editor, mutationData)) {
|
3165 | this.deleteBackward();
|
3166 | } else if (isTextInsertion(this.editor, mutationData)) {
|
3167 | this.insertText(insertedText);
|
3168 | }
|
3169 | };
|
3170 | |
3171 |
|
3172 |
|
3173 |
|
3174 |
|
3175 | this.insertText = insertedText => {
|
3176 | var {
|
3177 | selection
|
3178 | } = this.editor;
|
3179 |
|
3180 |
|
3181 | if (IS_COMPOSING.get(this.editor) || IS_ON_COMPOSITION_END.get(this.editor)) {
|
3182 | EDITOR_ON_COMPOSITION_TEXT.set(this.editor, insertedText);
|
3183 | IS_ON_COMPOSITION_END.set(this.editor, false);
|
3184 | return;
|
3185 | }
|
3186 |
|
3187 |
|
3188 | insertedText.forEach(insertion => {
|
3189 | var text = insertion.text.insertText;
|
3190 | var at = normalizeTextInsertionRange(this.editor, selection, insertion);
|
3191 | Transforms.setSelection(this.editor, at);
|
3192 | Editor.insertText(this.editor, text);
|
3193 | });
|
3194 | };
|
3195 | |
3196 |
|
3197 |
|
3198 |
|
3199 |
|
3200 | this.insertBreak = () => {
|
3201 | var {
|
3202 | selection
|
3203 | } = this.editor;
|
3204 | Editor.insertBreak(this.editor);
|
3205 | this.restoreDOM();
|
3206 |
|
3207 | if (selection) {
|
3208 |
|
3209 | setTimeout(() => {
|
3210 | if (this.editor.selection && Range.equals(selection, this.editor.selection)) {
|
3211 | Transforms.move(this.editor);
|
3212 | }
|
3213 | }, 100);
|
3214 | }
|
3215 | };
|
3216 | |
3217 |
|
3218 |
|
3219 |
|
3220 |
|
3221 | this.replaceExpandedSelection = text => {
|
3222 |
|
3223 | Editor.deleteFragment(this.editor);
|
3224 |
|
3225 | if (text.length) {
|
3226 |
|
3227 | Editor.insertText(this.editor, text);
|
3228 | }
|
3229 |
|
3230 | this.restoreDOM();
|
3231 | };
|
3232 | |
3233 |
|
3234 |
|
3235 |
|
3236 |
|
3237 | this.deleteBackward = () => {
|
3238 | Editor.deleteBackward(this.editor);
|
3239 | ReactEditor.focus(this.editor);
|
3240 | this.restoreDOM();
|
3241 | };
|
3242 | |
3243 |
|
3244 |
|
3245 |
|
3246 |
|
3247 | this.removeLeafNodes = nodes => {
|
3248 | for (var node of nodes) {
|
3249 | var slateNode = ReactEditor.toSlateNode(this.editor, node);
|
3250 |
|
3251 | if (slateNode) {
|
3252 | var path = ReactEditor.findPath(this.editor, slateNode);
|
3253 | Transforms.delete(this.editor, {
|
3254 | at: path
|
3255 | });
|
3256 | this.restoreDOM();
|
3257 | }
|
3258 | }
|
3259 | };
|
3260 |
|
3261 | this.editor = editor;
|
3262 | this.restoreDOM = restoreDOM;
|
3263 | }
|
3264 |
|
3265 | }
|
3266 |
|
3267 | function useMutationObserver(node, callback, options) {
|
3268 | var [mutationObserver] = useState(() => new MutationObserver(callback));
|
3269 | useIsomorphicLayoutEffect(() => {
|
3270 |
|
3271 | mutationObserver.disconnect();
|
3272 | });
|
3273 | useEffect(() => {
|
3274 | if (!node.current) {
|
3275 | throw new Error('Failed to attach MutationObserver, `node` is undefined');
|
3276 | }
|
3277 |
|
3278 |
|
3279 | mutationObserver.observe(node.current, options);
|
3280 |
|
3281 | return mutationObserver.disconnect.bind(mutationObserver);
|
3282 | });
|
3283 | }
|
3284 |
|
3285 | var MUTATION_OBSERVER_CONFIG$1 = {
|
3286 | childList: true,
|
3287 | characterData: true,
|
3288 | subtree: true
|
3289 | };
|
3290 |
|
3291 | function findClosestKnowSlateNode(domNode) {
|
3292 | var _domEl;
|
3293 |
|
3294 | var domEl = isDOMElement(domNode) ? domNode : domNode.parentElement;
|
3295 |
|
3296 | if (domEl && !domEl.hasAttribute('data-slate-node')) {
|
3297 | domEl = domEl.closest("[data-slate-node]");
|
3298 | }
|
3299 |
|
3300 | var slateNode = domEl && ELEMENT_TO_NODE.get(domEl);
|
3301 |
|
3302 | if (slateNode) {
|
3303 | return slateNode;
|
3304 | }
|
3305 |
|
3306 |
|
3307 |
|
3308 | return (_domEl = domEl) !== null && _domEl !== void 0 && _domEl.parentElement ? findClosestKnowSlateNode(domEl.parentElement) : null;
|
3309 | }
|
3310 |
|
3311 | function useRestoreDom(node, receivedUserInput) {
|
3312 | var editor = useSlateStatic();
|
3313 | var mutatedNodes = useRef(new Set());
|
3314 | var handleDOMMutation = useCallback(mutations => {
|
3315 | if (!receivedUserInput.current) {
|
3316 | return;
|
3317 | }
|
3318 |
|
3319 | mutations.forEach(_ref => {
|
3320 | var {
|
3321 | target
|
3322 | } = _ref;
|
3323 | var slateNode = findClosestKnowSlateNode(target);
|
3324 |
|
3325 | if (!slateNode) {
|
3326 | return;
|
3327 | }
|
3328 |
|
3329 | return mutatedNodes.current.add(slateNode);
|
3330 | });
|
3331 | }, []);
|
3332 | useMutationObserver(node, handleDOMMutation, MUTATION_OBSERVER_CONFIG$1);
|
3333 |
|
3334 | mutatedNodes.current.clear();
|
3335 | var restore = useCallback(() => {
|
3336 | var mutated = Array.from(mutatedNodes.current.values());
|
3337 |
|
3338 | var nodesToRestore = mutated.filter(n => !mutated.some(m => Path.isParent(ReactEditor.findPath(editor, m), ReactEditor.findPath(editor, n))));
|
3339 | nodesToRestore.forEach(n => {
|
3340 | var _NODE_TO_RESTORE_DOM$;
|
3341 |
|
3342 | (_NODE_TO_RESTORE_DOM$ = NODE_TO_RESTORE_DOM.get(n)) === null || _NODE_TO_RESTORE_DOM$ === void 0 ? void 0 : _NODE_TO_RESTORE_DOM$();
|
3343 | });
|
3344 | mutatedNodes.current.clear();
|
3345 | }, []);
|
3346 | return restore;
|
3347 | }
|
3348 |
|
3349 | function useTrackUserInput() {
|
3350 | var editor = useSlateStatic();
|
3351 | var receivedUserInput = useRef(false);
|
3352 | var animationFrameRef = useRef(null);
|
3353 | var onUserInput = useCallback(() => {
|
3354 | if (receivedUserInput.current === false) {
|
3355 | var window = ReactEditor.getWindow(editor);
|
3356 | receivedUserInput.current = true;
|
3357 |
|
3358 | if (animationFrameRef.current) {
|
3359 | window.cancelAnimationFrame(animationFrameRef.current);
|
3360 | }
|
3361 |
|
3362 | animationFrameRef.current = window.requestAnimationFrame(() => {
|
3363 | receivedUserInput.current = false;
|
3364 | animationFrameRef.current = null;
|
3365 | });
|
3366 | }
|
3367 | }, []);
|
3368 | useEffect(() => {
|
3369 |
|
3370 | if (receivedUserInput.current) {
|
3371 | receivedUserInput.current = false;
|
3372 | }
|
3373 | });
|
3374 | return {
|
3375 | receivedUserInput,
|
3376 | onUserInput
|
3377 | };
|
3378 | }
|
3379 |
|
3380 | var MUTATION_OBSERVER_CONFIG = {
|
3381 | childList: true,
|
3382 | characterData: true,
|
3383 | characterDataOldValue: true,
|
3384 | subtree: true
|
3385 | };
|
3386 | function useAndroidInputManager(node) {
|
3387 | var editor = useSlateStatic();
|
3388 | var {
|
3389 | receivedUserInput,
|
3390 | onUserInput
|
3391 | } = useTrackUserInput();
|
3392 | var restoreDom = useRestoreDom(node, receivedUserInput);
|
3393 | var inputManager = useMemo(() => new AndroidInputManager(editor, restoreDom), [restoreDom, editor]);
|
3394 | var timeoutId = useRef(null);
|
3395 | var isReconciling = useRef(false);
|
3396 | var flush = useCallback(mutations => {
|
3397 | if (!receivedUserInput.current) {
|
3398 | return;
|
3399 | }
|
3400 |
|
3401 | isReconciling.current = true;
|
3402 | inputManager.flush(mutations);
|
3403 |
|
3404 | if (timeoutId.current) {
|
3405 | clearTimeout(timeoutId.current);
|
3406 | }
|
3407 |
|
3408 | timeoutId.current = setTimeout(() => {
|
3409 | isReconciling.current = false;
|
3410 | timeoutId.current = null;
|
3411 | }, 250);
|
3412 | }, []);
|
3413 | useMutationObserver(node, flush, MUTATION_OBSERVER_CONFIG);
|
3414 | return {
|
3415 | isReconciling,
|
3416 | onUserInput
|
3417 | };
|
3418 | }
|
3419 |
|
3420 | var _excluded$1 = ["autoFocus", "decorate", "onDOMBeforeInput", "placeholder", "readOnly", "renderElement", "renderLeaf", "renderPlaceholder", "style", "as"];
|
3421 |
|
3422 | function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
3423 |
|
3424 | function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
3425 |
|
3426 |
|
3427 |
|
3428 |
|
3429 |
|
3430 |
|
3431 | var RESOLVE_DELAY = 20;
|
3432 | var AndroidEditable = props => {
|
3433 | var {
|
3434 | autoFocus,
|
3435 | decorate = defaultDecorate,
|
3436 | onDOMBeforeInput: propsOnDOMBeforeInput,
|
3437 | placeholder,
|
3438 | readOnly = false,
|
3439 | renderElement,
|
3440 | renderLeaf,
|
3441 | renderPlaceholder = props => React.createElement(DefaultPlaceholder, Object.assign({}, props)),
|
3442 | style = {},
|
3443 | as: Component = 'div'
|
3444 | } = props,
|
3445 | attributes = _objectWithoutProperties(props, _excluded$1);
|
3446 |
|
3447 | var editor = useSlate();
|
3448 |
|
3449 | var [isComposing, setIsComposing] = useState(false);
|
3450 | var ref = useRef(null);
|
3451 | var inputManager = useAndroidInputManager(ref);
|
3452 |
|
3453 | IS_READ_ONLY.set(editor, readOnly);
|
3454 |
|
3455 | var state = useMemo(() => ({
|
3456 | isComposing: false,
|
3457 | isUpdatingSelection: false,
|
3458 | latestElement: null
|
3459 | }), []);
|
3460 | var contentKey = useContentKey(editor);
|
3461 |
|
3462 | useIsomorphicLayoutEffect(() => {
|
3463 |
|
3464 | var window;
|
3465 |
|
3466 | if (ref.current && (window = getDefaultView(ref.current))) {
|
3467 | EDITOR_TO_WINDOW.set(editor, window);
|
3468 | EDITOR_TO_ELEMENT.set(editor, ref.current);
|
3469 | NODE_TO_ELEMENT.set(editor, ref.current);
|
3470 | ELEMENT_TO_NODE.set(ref.current, editor);
|
3471 | } else {
|
3472 | NODE_TO_ELEMENT.delete(editor);
|
3473 | }
|
3474 |
|
3475 | try {
|
3476 |
|
3477 | var {
|
3478 | selection
|
3479 | } = editor;
|
3480 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
3481 | var domSelection = root.getSelection();
|
3482 |
|
3483 | if (state.isComposing || !domSelection || !ReactEditor.isFocused(editor)) {
|
3484 | return;
|
3485 | }
|
3486 |
|
3487 | var hasDomSelection = domSelection.type !== 'None';
|
3488 |
|
3489 | if (!selection && !hasDomSelection) {
|
3490 | return;
|
3491 | }
|
3492 |
|
3493 |
|
3494 | var editorElement = EDITOR_TO_ELEMENT.get(editor);
|
3495 | var hasDomSelectionInEditor = false;
|
3496 |
|
3497 | if (editorElement.contains(domSelection.anchorNode) && editorElement.contains(domSelection.focusNode)) {
|
3498 | hasDomSelectionInEditor = true;
|
3499 | }
|
3500 |
|
3501 |
|
3502 | if (hasDomSelection && hasDomSelectionInEditor && selection) {
|
3503 | var slateRange = ReactEditor.toSlateRange(editor, domSelection, {
|
3504 | exactMatch: true,
|
3505 | suppressThrow: true
|
3506 | });
|
3507 |
|
3508 | if (slateRange && Range.equals(slateRange, selection)) {
|
3509 | return;
|
3510 | }
|
3511 | }
|
3512 |
|
3513 |
|
3514 |
|
3515 |
|
3516 |
|
3517 | if (selection && !ReactEditor.hasRange(editor, selection)) {
|
3518 | editor.selection = ReactEditor.toSlateRange(editor, domSelection, {
|
3519 | exactMatch: false,
|
3520 | suppressThrow: false
|
3521 | });
|
3522 | return;
|
3523 | }
|
3524 |
|
3525 |
|
3526 | var el = ReactEditor.toDOMNode(editor, editor);
|
3527 | state.isUpdatingSelection = true;
|
3528 | var newDomRange = selection && ReactEditor.toDOMRange(editor, selection);
|
3529 |
|
3530 | if (newDomRange) {
|
3531 | if (Range.isBackward(selection)) {
|
3532 | domSelection.setBaseAndExtent(newDomRange.endContainer, newDomRange.endOffset, newDomRange.startContainer, newDomRange.startOffset);
|
3533 | } else {
|
3534 | domSelection.setBaseAndExtent(newDomRange.startContainer, newDomRange.startOffset, newDomRange.endContainer, newDomRange.endOffset);
|
3535 | }
|
3536 |
|
3537 | var leafEl = newDomRange.startContainer.parentElement;
|
3538 | leafEl.getBoundingClientRect = newDomRange.getBoundingClientRect.bind(newDomRange);
|
3539 | scrollIntoView(leafEl, {
|
3540 | scrollMode: 'if-needed',
|
3541 | boundary: el
|
3542 | });
|
3543 |
|
3544 | delete leafEl.getBoundingClientRect;
|
3545 | } else {
|
3546 | domSelection.removeAllRanges();
|
3547 | }
|
3548 |
|
3549 | setTimeout(() => {
|
3550 | state.isUpdatingSelection = false;
|
3551 | });
|
3552 | } catch (_unused) {
|
3553 |
|
3554 | state.isUpdatingSelection = false;
|
3555 | }
|
3556 | });
|
3557 |
|
3558 |
|
3559 | useEffect(() => {
|
3560 | if (ref.current && autoFocus) {
|
3561 | ref.current.focus();
|
3562 | }
|
3563 | }, [autoFocus]);
|
3564 |
|
3565 |
|
3566 |
|
3567 |
|
3568 |
|
3569 | var onDOMSelectionChange = useCallback(throttle(() => {
|
3570 | try {
|
3571 | if (!state.isComposing && !state.isUpdatingSelection && !inputManager.isReconciling.current) {
|
3572 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
3573 | var {
|
3574 | activeElement
|
3575 | } = root;
|
3576 | var el = ReactEditor.toDOMNode(editor, editor);
|
3577 | var domSelection = root.getSelection();
|
3578 |
|
3579 | if (activeElement === el) {
|
3580 | state.latestElement = activeElement;
|
3581 | IS_FOCUSED.set(editor, true);
|
3582 | } else {
|
3583 | IS_FOCUSED.delete(editor);
|
3584 | }
|
3585 |
|
3586 | if (!domSelection) {
|
3587 | return Transforms.deselect(editor);
|
3588 | }
|
3589 |
|
3590 | var {
|
3591 | anchorNode,
|
3592 | focusNode
|
3593 | } = domSelection;
|
3594 | var anchorNodeSelectable = hasEditableTarget(editor, anchorNode) || isTargetInsideNonReadonlyVoid(editor, anchorNode);
|
3595 | var focusNodeSelectable = hasEditableTarget(editor, focusNode) || isTargetInsideNonReadonlyVoid(editor, focusNode);
|
3596 |
|
3597 | if (anchorNodeSelectable && focusNodeSelectable) {
|
3598 | var range = ReactEditor.toSlateRange(editor, domSelection, {
|
3599 | exactMatch: false,
|
3600 | suppressThrow: false
|
3601 | });
|
3602 | Transforms.select(editor, range);
|
3603 | } else {
|
3604 | Transforms.deselect(editor);
|
3605 | }
|
3606 | }
|
3607 | } catch (_unused2) {
|
3608 | }
|
3609 | }, 100), [readOnly]);
|
3610 | var scheduleOnDOMSelectionChange = useMemo(() => debounce(onDOMSelectionChange, 0), [onDOMSelectionChange]);
|
3611 |
|
3612 |
|
3613 |
|
3614 |
|
3615 | var onDOMBeforeInput = useCallback(event => {
|
3616 | if (!readOnly && hasEditableTarget(editor, event.target) && !isDOMEventHandled(event, propsOnDOMBeforeInput)) {
|
3617 |
|
3618 |
|
3619 |
|
3620 | scheduleOnDOMSelectionChange.flush();
|
3621 | inputManager.onUserInput();
|
3622 | }
|
3623 | }, [readOnly, propsOnDOMBeforeInput]);
|
3624 |
|
3625 |
|
3626 |
|
3627 | useIsomorphicLayoutEffect(() => {
|
3628 | var node = ref.current;
|
3629 |
|
3630 | node === null || node === void 0 ? void 0 : node.addEventListener('beforeinput', onDOMBeforeInput);
|
3631 |
|
3632 | return () => node === null || node === void 0 ? void 0 : node.removeEventListener('beforeinput', onDOMBeforeInput);
|
3633 | }, [contentKey, propsOnDOMBeforeInput]);
|
3634 |
|
3635 |
|
3636 |
|
3637 |
|
3638 |
|
3639 | useIsomorphicLayoutEffect(() => {
|
3640 | var window = ReactEditor.getWindow(editor);
|
3641 | window.document.addEventListener('selectionchange', scheduleOnDOMSelectionChange);
|
3642 | return () => {
|
3643 | window.document.removeEventListener('selectionchange', scheduleOnDOMSelectionChange);
|
3644 | };
|
3645 | }, [scheduleOnDOMSelectionChange]);
|
3646 | var decorations = decorate([editor, []]);
|
3647 |
|
3648 | if (placeholder && editor.children.length === 1 && Array.from(Node.texts(editor)).length === 1 && Node.string(editor) === '' && !isComposing) {
|
3649 | var start = Editor.start(editor, []);
|
3650 | decorations.push({
|
3651 | [PLACEHOLDER_SYMBOL]: true,
|
3652 | placeholder,
|
3653 | anchor: start,
|
3654 | focus: start
|
3655 | });
|
3656 | }
|
3657 |
|
3658 | return React.createElement(ReadOnlyContext.Provider, {
|
3659 | value: readOnly
|
3660 | }, React.createElement(DecorateContext.Provider, {
|
3661 | value: decorate
|
3662 | }, React.createElement(Component, Object.assign({
|
3663 | key: contentKey,
|
3664 | role: readOnly ? undefined : 'textbox'
|
3665 | }, attributes, {
|
3666 | spellCheck: attributes.spellCheck,
|
3667 | autoCorrect: attributes.autoCorrect,
|
3668 | autoCapitalize: attributes.autoCapitalize,
|
3669 | "data-slate-editor": true,
|
3670 | "data-slate-node": "value",
|
3671 | contentEditable: readOnly ? undefined : true,
|
3672 | suppressContentEditableWarning: true,
|
3673 | ref: ref,
|
3674 | style: _objectSpread({
|
3675 |
|
3676 | position: 'relative',
|
3677 |
|
3678 | outline: 'none',
|
3679 |
|
3680 | whiteSpace: 'pre-wrap',
|
3681 |
|
3682 | wordWrap: 'break-word'
|
3683 | }, style),
|
3684 | onCopy: useCallback(event => {
|
3685 | if (hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onCopy)) {
|
3686 | event.preventDefault();
|
3687 | ReactEditor.setFragmentData(editor, event.clipboardData, 'copy');
|
3688 | }
|
3689 | }, [attributes.onCopy]),
|
3690 | onCut: useCallback(event => {
|
3691 | if (!readOnly && hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onCut)) {
|
3692 | event.preventDefault();
|
3693 | ReactEditor.setFragmentData(editor, event.clipboardData, 'cut');
|
3694 | var {
|
3695 | selection
|
3696 | } = editor;
|
3697 |
|
3698 | if (selection) {
|
3699 | if (Range.isExpanded(selection)) {
|
3700 | Editor.deleteFragment(editor);
|
3701 | } else {
|
3702 | var node = Node.parent(editor, selection.anchor.path);
|
3703 |
|
3704 | if (Editor.isVoid(editor, node)) {
|
3705 | Transforms.delete(editor);
|
3706 | }
|
3707 | }
|
3708 | }
|
3709 | }
|
3710 | }, [readOnly, attributes.onCut]),
|
3711 | onFocus: useCallback(event => {
|
3712 | if (!readOnly && !state.isUpdatingSelection && hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onFocus)) {
|
3713 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
3714 | state.latestElement = root.activeElement;
|
3715 | IS_FOCUSED.set(editor, true);
|
3716 | }
|
3717 | }, [readOnly, attributes.onFocus]),
|
3718 | onBlur: useCallback(event => {
|
3719 | if (readOnly || state.isUpdatingSelection || !hasEditableTarget(editor, event.target) || isEventHandled(event, attributes.onBlur)) {
|
3720 | return;
|
3721 | }
|
3722 |
|
3723 |
|
3724 |
|
3725 |
|
3726 |
|
3727 | var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
3728 |
|
3729 | if (state.latestElement === root.activeElement) {
|
3730 | return;
|
3731 | }
|
3732 |
|
3733 | var {
|
3734 | relatedTarget
|
3735 | } = event;
|
3736 | var el = ReactEditor.toDOMNode(editor, editor);
|
3737 |
|
3738 |
|
3739 |
|
3740 | if (relatedTarget === el) {
|
3741 | return;
|
3742 | }
|
3743 |
|
3744 |
|
3745 |
|
3746 | if (isDOMElement(relatedTarget) && relatedTarget.hasAttribute('data-slate-spacer')) {
|
3747 | return;
|
3748 | }
|
3749 |
|
3750 |
|
3751 |
|
3752 |
|
3753 | if (relatedTarget != null && isDOMNode(relatedTarget) && ReactEditor.hasDOMNode(editor, relatedTarget)) {
|
3754 | var node = ReactEditor.toSlateNode(editor, relatedTarget);
|
3755 |
|
3756 | if (Element$1.isElement(node) && !editor.isVoid(node)) {
|
3757 | return;
|
3758 | }
|
3759 | }
|
3760 |
|
3761 | IS_FOCUSED.delete(editor);
|
3762 | }, [readOnly, attributes.onBlur]),
|
3763 | onClick: useCallback(event => {
|
3764 | if (!readOnly && hasTarget(editor, event.target) && !isEventHandled(event, attributes.onClick) && isDOMNode(event.target)) {
|
3765 | var node = ReactEditor.toSlateNode(editor, event.target);
|
3766 | var path = ReactEditor.findPath(editor, node);
|
3767 |
|
3768 |
|
3769 |
|
3770 |
|
3771 | if (Editor.hasPath(editor, path)) {
|
3772 | var lookupNode = Node.get(editor, path);
|
3773 |
|
3774 | if (lookupNode === node) {
|
3775 | var _start = Editor.start(editor, path);
|
3776 |
|
3777 | var end = Editor.end(editor, path);
|
3778 | var startVoid = Editor.void(editor, {
|
3779 | at: _start
|
3780 | });
|
3781 | var endVoid = Editor.void(editor, {
|
3782 | at: end
|
3783 | });
|
3784 |
|
3785 | if (startVoid && endVoid && Path.equals(startVoid[1], endVoid[1])) {
|
3786 | var range = Editor.range(editor, _start);
|
3787 | Transforms.select(editor, range);
|
3788 | }
|
3789 | }
|
3790 | }
|
3791 | }
|
3792 | }, [readOnly, attributes.onClick]),
|
3793 | onCompositionEnd: useCallback(event => {
|
3794 | if (hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onCompositionEnd)) {
|
3795 | scheduleOnDOMSelectionChange.flush();
|
3796 | setTimeout(() => {
|
3797 | state.isComposing && setIsComposing(false);
|
3798 | state.isComposing = false;
|
3799 | IS_COMPOSING.set(editor, false);
|
3800 | IS_ON_COMPOSITION_END.set(editor, true);
|
3801 | var insertedText = EDITOR_ON_COMPOSITION_TEXT.get(editor) || [];
|
3802 |
|
3803 |
|
3804 | if (!insertedText.length) {
|
3805 | return;
|
3806 | }
|
3807 |
|
3808 | EDITOR_ON_COMPOSITION_TEXT.set(editor, []);
|
3809 | var {
|
3810 | selection
|
3811 | } = editor;
|
3812 | insertedText.forEach(insertion => {
|
3813 | var text = insertion.text.insertText;
|
3814 | var at = normalizeTextInsertionRange(editor, selection, insertion);
|
3815 | Transforms.setSelection(editor, at);
|
3816 | Editor.insertText(editor, text);
|
3817 | });
|
3818 | }, RESOLVE_DELAY);
|
3819 | }
|
3820 | }, [attributes.onCompositionEnd]),
|
3821 | onCompositionUpdate: useCallback(event => {
|
3822 | if (hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onCompositionUpdate)) {
|
3823 | !state.isComposing && setIsComposing(true);
|
3824 | state.isComposing = true;
|
3825 | IS_COMPOSING.set(editor, true);
|
3826 | }
|
3827 | }, [attributes.onCompositionUpdate]),
|
3828 | onCompositionStart: useCallback(event => {
|
3829 | if (hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onCompositionStart)) {
|
3830 | !state.isComposing && setIsComposing(true);
|
3831 | state.isComposing = true;
|
3832 | IS_COMPOSING.set(editor, true);
|
3833 | }
|
3834 | }, [attributes.onCompositionStart]),
|
3835 | onPaste: useCallback(event => {
|
3836 |
|
3837 | event.clipboardData = getClipboardData(event.clipboardData);
|
3838 |
|
3839 | if (hasEditableTarget(editor, event.target) && !isEventHandled(event, attributes.onPaste) && !readOnly) {
|
3840 | event.preventDefault();
|
3841 | ReactEditor.insertData(editor, event.clipboardData);
|
3842 | }
|
3843 | }, [readOnly, attributes.onPaste])
|
3844 | }), useChildren({
|
3845 | decorations,
|
3846 | node: editor,
|
3847 | renderElement,
|
3848 | renderPlaceholder,
|
3849 | renderLeaf,
|
3850 | selection: editor.selection
|
3851 | }))));
|
3852 | };
|
3853 |
|
3854 |
|
3855 |
|
3856 |
|
3857 |
|
3858 | var FocusedContext = createContext(false);
|
3859 |
|
3860 |
|
3861 |
|
3862 |
|
3863 | var useFocused = () => {
|
3864 | return useContext(FocusedContext);
|
3865 | };
|
3866 |
|
3867 | var _excluded = ["editor", "children", "onChange", "value"];
|
3868 |
|
3869 |
|
3870 |
|
3871 |
|
3872 |
|
3873 | var Slate = props => {
|
3874 | var {
|
3875 | editor,
|
3876 | children,
|
3877 | onChange,
|
3878 | value
|
3879 | } = props,
|
3880 | rest = _objectWithoutProperties(props, _excluded);
|
3881 |
|
3882 | var [context, setContext] = React.useState(() => {
|
3883 | if (!Node.isNodeList(value)) {
|
3884 | throw new Error("[Slate] value is invalid! Expected a list of elements" + "but got: ".concat(JSON.stringify(value)));
|
3885 | }
|
3886 |
|
3887 | if (!Editor.isEditor(editor)) {
|
3888 | throw new Error("[Slate] editor is invalid! you passed:" + "".concat(JSON.stringify(editor)));
|
3889 | }
|
3890 |
|
3891 | editor.children = value;
|
3892 | Object.assign(editor, rest);
|
3893 | return [editor];
|
3894 | });
|
3895 | var onContextChange = useCallback(() => {
|
3896 | onChange(editor.children);
|
3897 | setContext([editor]);
|
3898 | }, [onChange]);
|
3899 | EDITOR_TO_ON_CHANGE.set(editor, onContextChange);
|
3900 | useEffect(() => {
|
3901 | return () => {
|
3902 | EDITOR_TO_ON_CHANGE.set(editor, () => {});
|
3903 | };
|
3904 | }, []);
|
3905 | var [isFocused, setIsFocused] = useState(ReactEditor.isFocused(editor));
|
3906 | useEffect(() => {
|
3907 | setIsFocused(ReactEditor.isFocused(editor));
|
3908 | });
|
3909 | useIsomorphicLayoutEffect(() => {
|
3910 | var fn = () => {
|
3911 | setTimeout(() => {
|
3912 | setIsFocused(ReactEditor.isFocused(editor));
|
3913 | }, 0);
|
3914 | };
|
3915 |
|
3916 | document.addEventListener('focus', fn, true);
|
3917 | document.addEventListener('blur', fn, true);
|
3918 | return () => {
|
3919 | document.removeEventListener('focus', fn, true);
|
3920 | document.removeEventListener('blur', fn, true);
|
3921 | };
|
3922 | }, []);
|
3923 | return React.createElement(SlateContext.Provider, {
|
3924 | value: context
|
3925 | }, React.createElement(EditorContext.Provider, {
|
3926 | value: editor
|
3927 | }, React.createElement(FocusedContext.Provider, {
|
3928 | value: isFocused
|
3929 | }, children)));
|
3930 | };
|
3931 |
|
3932 |
|
3933 |
|
3934 |
|
3935 |
|
3936 |
|
3937 | var useEditor = () => {
|
3938 | var editor = useContext(EditorContext);
|
3939 |
|
3940 | if (!editor) {
|
3941 | throw new Error("The `useEditor` hook must be used inside the <Slate> component's context.");
|
3942 | }
|
3943 |
|
3944 | return editor;
|
3945 | };
|
3946 |
|
3947 |
|
3948 |
|
3949 |
|
3950 |
|
3951 | var doRectsIntersect = (rect, compareRect) => {
|
3952 | var middle = (compareRect.top + compareRect.bottom) / 2;
|
3953 | return rect.top <= middle && rect.bottom >= middle;
|
3954 | };
|
3955 |
|
3956 | var areRangesSameLine = (editor, range1, range2) => {
|
3957 | var rect1 = ReactEditor.toDOMRange(editor, range1).getBoundingClientRect();
|
3958 | var rect2 = ReactEditor.toDOMRange(editor, range2).getBoundingClientRect();
|
3959 | return doRectsIntersect(rect1, rect2) && doRectsIntersect(rect2, rect1);
|
3960 | };
|
3961 |
|
3962 |
|
3963 |
|
3964 |
|
3965 |
|
3966 |
|
3967 |
|
3968 |
|
3969 |
|
3970 |
|
3971 | var findCurrentLineRange = (editor, parentRange) => {
|
3972 | var parentRangeBoundary = Editor.range(editor, Range.end(parentRange));
|
3973 | var positions = Array.from(Editor.positions(editor, {
|
3974 | at: parentRange
|
3975 | }));
|
3976 | var left = 0;
|
3977 | var right = positions.length;
|
3978 | var middle = Math.floor(right / 2);
|
3979 |
|
3980 | if (areRangesSameLine(editor, Editor.range(editor, positions[left]), parentRangeBoundary)) {
|
3981 | return Editor.range(editor, positions[left], parentRangeBoundary);
|
3982 | }
|
3983 |
|
3984 | if (positions.length < 2) {
|
3985 | return Editor.range(editor, positions[positions.length - 1], parentRangeBoundary);
|
3986 | }
|
3987 |
|
3988 | while (middle !== positions.length && middle !== left) {
|
3989 | if (areRangesSameLine(editor, Editor.range(editor, positions[middle]), parentRangeBoundary)) {
|
3990 | right = middle;
|
3991 | } else {
|
3992 | left = middle;
|
3993 | }
|
3994 |
|
3995 | middle = Math.floor((left + right) / 2);
|
3996 | }
|
3997 |
|
3998 | return Editor.range(editor, positions[right], parentRangeBoundary);
|
3999 | };
|
4000 |
|
4001 |
|
4002 |
|
4003 |
|
4004 |
|
4005 |
|
4006 |
|
4007 |
|
4008 |
|
4009 |
|
4010 | var withReact = editor => {
|
4011 | var e = editor;
|
4012 | var {
|
4013 | apply,
|
4014 | onChange,
|
4015 | deleteBackward
|
4016 | } = e;
|
4017 |
|
4018 |
|
4019 | EDITOR_TO_KEY_TO_ELEMENT.set(e, new WeakMap());
|
4020 |
|
4021 | e.deleteBackward = unit => {
|
4022 | if (unit !== 'line') {
|
4023 | return deleteBackward(unit);
|
4024 | }
|
4025 |
|
4026 | if (editor.selection && Range.isCollapsed(editor.selection)) {
|
4027 | var parentBlockEntry = Editor.above(editor, {
|
4028 | match: n => Editor.isBlock(editor, n),
|
4029 | at: editor.selection
|
4030 | });
|
4031 |
|
4032 | if (parentBlockEntry) {
|
4033 | var [, parentBlockPath] = parentBlockEntry;
|
4034 | var parentElementRange = Editor.range(editor, parentBlockPath, editor.selection.anchor);
|
4035 | var currentLineRange = findCurrentLineRange(e, parentElementRange);
|
4036 |
|
4037 | if (!Range.isCollapsed(currentLineRange)) {
|
4038 | Transforms.delete(editor, {
|
4039 | at: currentLineRange
|
4040 | });
|
4041 | }
|
4042 | }
|
4043 | }
|
4044 | };
|
4045 |
|
4046 | e.apply = op => {
|
4047 | var matches = [];
|
4048 |
|
4049 | switch (op.type) {
|
4050 | case 'insert_text':
|
4051 | case 'remove_text':
|
4052 | case 'set_node':
|
4053 | {
|
4054 | for (var [node, path] of Editor.levels(e, {
|
4055 | at: op.path
|
4056 | })) {
|
4057 | var key = ReactEditor.findKey(e, node);
|
4058 | matches.push([path, key]);
|
4059 | }
|
4060 |
|
4061 | break;
|
4062 | }
|
4063 |
|
4064 | case 'insert_node':
|
4065 | case 'remove_node':
|
4066 | case 'merge_node':
|
4067 | case 'split_node':
|
4068 | {
|
4069 | for (var [_node, _path] of Editor.levels(e, {
|
4070 | at: Path.parent(op.path)
|
4071 | })) {
|
4072 | var _key = ReactEditor.findKey(e, _node);
|
4073 |
|
4074 | matches.push([_path, _key]);
|
4075 | }
|
4076 |
|
4077 | break;
|
4078 | }
|
4079 |
|
4080 | case 'move_node':
|
4081 | {
|
4082 | for (var [_node2, _path2] of Editor.levels(e, {
|
4083 | at: Path.common(Path.parent(op.path), Path.parent(op.newPath))
|
4084 | })) {
|
4085 | var _key2 = ReactEditor.findKey(e, _node2);
|
4086 |
|
4087 | matches.push([_path2, _key2]);
|
4088 | }
|
4089 |
|
4090 | break;
|
4091 | }
|
4092 | }
|
4093 |
|
4094 | apply(op);
|
4095 |
|
4096 | for (var [_path3, _key3] of matches) {
|
4097 | var [_node3] = Editor.node(e, _path3);
|
4098 | NODE_TO_KEY.set(_node3, _key3);
|
4099 | }
|
4100 | };
|
4101 |
|
4102 | e.setFragmentData = data => {
|
4103 | var {
|
4104 | selection
|
4105 | } = e;
|
4106 |
|
4107 | if (!selection) {
|
4108 | return;
|
4109 | }
|
4110 |
|
4111 | var [start, end] = Range.edges(selection);
|
4112 | var startVoid = Editor.void(e, {
|
4113 | at: start.path
|
4114 | });
|
4115 | var endVoid = Editor.void(e, {
|
4116 | at: end.path
|
4117 | });
|
4118 |
|
4119 | if (Range.isCollapsed(selection) && !startVoid) {
|
4120 | return;
|
4121 | }
|
4122 |
|
4123 |
|
4124 |
|
4125 | var domRange = ReactEditor.toDOMRange(e, selection);
|
4126 | var contents = domRange.cloneContents();
|
4127 | var attach = contents.childNodes[0];
|
4128 |
|
4129 | contents.childNodes.forEach(node => {
|
4130 | if (node.textContent && node.textContent.trim() !== '') {
|
4131 | attach = node;
|
4132 | }
|
4133 | });
|
4134 |
|
4135 |
|
4136 |
|
4137 | if (endVoid) {
|
4138 | var [voidNode] = endVoid;
|
4139 | var r = domRange.cloneRange();
|
4140 | var domNode = ReactEditor.toDOMNode(e, voidNode);
|
4141 | r.setEndAfter(domNode);
|
4142 | contents = r.cloneContents();
|
4143 | }
|
4144 |
|
4145 |
|
4146 |
|
4147 |
|
4148 |
|
4149 | if (startVoid) {
|
4150 | attach = contents.querySelector('[data-slate-spacer]');
|
4151 | }
|
4152 |
|
4153 |
|
4154 |
|
4155 | Array.from(contents.querySelectorAll('[data-slate-zero-width]')).forEach(zw => {
|
4156 | var isNewline = zw.getAttribute('data-slate-zero-width') === 'n';
|
4157 | zw.textContent = isNewline ? '\n' : '';
|
4158 | });
|
4159 |
|
4160 |
|
4161 |
|
4162 | if (isDOMText(attach)) {
|
4163 | var span = attach.ownerDocument.createElement('span');
|
4164 |
|
4165 |
|
4166 | span.style.whiteSpace = 'pre';
|
4167 | span.appendChild(attach);
|
4168 | contents.appendChild(span);
|
4169 | attach = span;
|
4170 | }
|
4171 |
|
4172 | var fragment = e.getFragment();
|
4173 | var string = JSON.stringify(fragment);
|
4174 | var encoded = window.btoa(encodeURIComponent(string));
|
4175 | attach.setAttribute('data-slate-fragment', encoded);
|
4176 | data.setData('application/x-slate-fragment', encoded);
|
4177 |
|
4178 | var div = contents.ownerDocument.createElement('div');
|
4179 | div.appendChild(contents);
|
4180 | div.setAttribute('hidden', 'true');
|
4181 | contents.ownerDocument.body.appendChild(div);
|
4182 | data.setData('text/html', div.innerHTML);
|
4183 | data.setData('text/plain', getPlainText(div));
|
4184 | contents.ownerDocument.body.removeChild(div);
|
4185 | return data;
|
4186 | };
|
4187 |
|
4188 | e.insertData = data => {
|
4189 | if (!e.insertFragmentData(data)) {
|
4190 | e.insertTextData(data);
|
4191 | }
|
4192 | };
|
4193 |
|
4194 | e.insertFragmentData = data => {
|
4195 | |
4196 |
|
4197 |
|
4198 | var fragment = data.getData('application/x-slate-fragment') || getSlateFragmentAttribute(data);
|
4199 |
|
4200 | if (fragment) {
|
4201 | var decoded = decodeURIComponent(window.atob(fragment));
|
4202 | var parsed = JSON.parse(decoded);
|
4203 | e.insertFragment(parsed);
|
4204 | return true;
|
4205 | }
|
4206 |
|
4207 | return false;
|
4208 | };
|
4209 |
|
4210 | e.insertTextData = data => {
|
4211 | var text = data.getData('text/plain');
|
4212 |
|
4213 | if (text) {
|
4214 | var lines = text.split(/\r\n|\r|\n/);
|
4215 | var split = false;
|
4216 |
|
4217 | for (var line of lines) {
|
4218 | if (split) {
|
4219 | Transforms.splitNodes(e, {
|
4220 | always: true
|
4221 | });
|
4222 | }
|
4223 |
|
4224 | e.insertText(line);
|
4225 | split = true;
|
4226 | }
|
4227 |
|
4228 | return true;
|
4229 | }
|
4230 |
|
4231 | return false;
|
4232 | };
|
4233 |
|
4234 | e.onChange = () => {
|
4235 |
|
4236 |
|
4237 |
|
4238 |
|
4239 | ReactDOM.unstable_batchedUpdates(() => {
|
4240 | var onContextChange = EDITOR_TO_ON_CHANGE.get(e);
|
4241 |
|
4242 | if (onContextChange) {
|
4243 | onContextChange();
|
4244 | }
|
4245 |
|
4246 | onChange();
|
4247 | });
|
4248 | };
|
4249 |
|
4250 | return e;
|
4251 | };
|
4252 |
|
4253 |
|
4254 | var Editable = IS_ANDROID ? AndroidEditable : Editable$1;
|
4255 |
|
4256 | export { AndroidEditable, Editable$1 as DefaultEditable, DefaultElement, DefaultLeaf, DefaultPlaceholder, Editable, ReactEditor, Slate, useEditor, useFocused, useReadOnly, useSelected, useSlate, useSlateStatic, withReact };
|
4257 |
|