slate-react 0.93.0 → 0.94.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/editable.d.ts.map +1 -1
- package/dist/components/element.d.ts +1 -1
- package/dist/components/element.d.ts.map +1 -1
- package/dist/components/slate.d.ts.map +1 -1
- package/dist/components/text.d.ts.map +1 -1
- package/dist/hooks/use-children.d.ts +1 -1
- package/dist/hooks/use-children.d.ts.map +1 -1
- package/dist/hooks/use-mutation-observer.d.ts.map +1 -1
- package/dist/hooks/use-slate-static.d.ts +1 -1
- package/dist/hooks/use-slate-static.d.ts.map +1 -1
- package/dist/index.es.js +1940 -2076
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +2202 -2318
- package/dist/index.js.map +1 -1
- package/dist/plugin/react-editor.d.ts +75 -73
- package/dist/plugin/react-editor.d.ts.map +1 -1
- package/dist/slate-react.js +2894 -3010
- package/dist/slate-react.min.js +1 -1
- package/dist/utils/lines.d.ts.map +1 -1
- package/dist/utils/types.d.ts +2 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/package.json +2 -2
package/dist/index.es.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import getDirection from 'direction';
|
|
2
2
|
import debounce from 'lodash/debounce';
|
|
3
3
|
import throttle from 'lodash/throttle';
|
|
4
|
-
import React, {
|
|
4
|
+
import React, { createContext, useContext, useRef, useEffect, useLayoutEffect, useState, memo, forwardRef, useCallback, Component, useReducer, useMemo } from 'react';
|
|
5
5
|
import scrollIntoView from 'scroll-into-view-if-needed';
|
|
6
|
-
import {
|
|
6
|
+
import { Transforms, Element as Element$1, Editor, Scrubber, Range, Path, Point, Node, Text as Text$1 } from 'slate';
|
|
7
7
|
import { ResizeObserver } from '@juggle/resize-observer';
|
|
8
8
|
import { isKeyHotkey } from 'is-hotkey';
|
|
9
9
|
import ReactDOM from 'react-dom';
|
|
@@ -58,20 +58,51 @@ function _objectWithoutProperties(source, excluded) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
61
|
+
* A React context for sharing the editor object.
|
|
62
62
|
*/
|
|
63
|
-
|
|
63
|
+
|
|
64
|
+
var EditorContext = /*#__PURE__*/createContext(null);
|
|
64
65
|
/**
|
|
65
|
-
*
|
|
66
|
-
* want to be able to use them as keys in `WeakMap` objects.
|
|
66
|
+
* Get the current editor object from the React context.
|
|
67
67
|
*/
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
var useSlateStatic = () => {
|
|
70
|
+
var editor = useContext(EditorContext);
|
|
71
|
+
|
|
72
|
+
if (!editor) {
|
|
73
|
+
throw new Error("The `useSlateStatic` hook must be used inside the <Slate> component's context.");
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
return editor;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
var IS_REACT_VERSION_17_OR_ABOVE = parseInt(React.version.split('.')[0], 10) >= 17;
|
|
80
|
+
var IS_IOS = typeof navigator !== 'undefined' && typeof window !== 'undefined' && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
|
81
|
+
var IS_APPLE = typeof navigator !== 'undefined' && /Mac OS X/.test(navigator.userAgent);
|
|
82
|
+
var IS_ANDROID = typeof navigator !== 'undefined' && /Android/.test(navigator.userAgent);
|
|
83
|
+
var IS_FIREFOX = typeof navigator !== 'undefined' && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
|
|
84
|
+
var IS_SAFARI = typeof navigator !== 'undefined' && /Version\/[\d\.]+.*Safari/.test(navigator.userAgent); // "modern" Edge was released at 79.x
|
|
85
|
+
|
|
86
|
+
var IS_EDGE_LEGACY = typeof navigator !== 'undefined' && /Edge?\/(?:[0-6][0-9]|[0-7][0-8])(?:\.)/i.test(navigator.userAgent);
|
|
87
|
+
var IS_CHROME = typeof navigator !== 'undefined' && /Chrome/i.test(navigator.userAgent); // Native `beforeInput` events don't work well with react on Chrome 75
|
|
88
|
+
// and older, Chrome 76+ can use `beforeInput` though.
|
|
89
|
+
|
|
90
|
+
var IS_CHROME_LEGACY = typeof navigator !== 'undefined' && /Chrome?\/(?:[0-7][0-5]|[0-6][0-9])(?:\.)/i.test(navigator.userAgent);
|
|
91
|
+
var IS_ANDROID_CHROME_LEGACY = IS_ANDROID && typeof navigator !== 'undefined' && /Chrome?\/(?:[0-5]?\d)(?:\.)/i.test(navigator.userAgent); // Firefox did not support `beforeInput` until `v87`.
|
|
92
|
+
|
|
93
|
+
var IS_FIREFOX_LEGACY = typeof navigator !== 'undefined' && /^(?!.*Seamonkey)(?=.*Firefox\/(?:[0-7][0-9]|[0-8][0-6])(?:\.)).*/i.test(navigator.userAgent); // UC mobile browser
|
|
94
|
+
|
|
95
|
+
var IS_UC_MOBILE = typeof navigator !== 'undefined' && /.*UCBrowser/.test(navigator.userAgent); // Wechat browser
|
|
96
|
+
|
|
97
|
+
var IS_WECHATBROWSER = typeof navigator !== 'undefined' && /.*Wechat/.test(navigator.userAgent); // Check if DOM is available as React does internally.
|
|
98
|
+
// https://github.com/facebook/react/blob/master/packages/shared/ExecutionEnvironment.js
|
|
99
|
+
|
|
100
|
+
var CAN_USE_DOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined'); // COMPAT: Firefox/Edge Legacy don't support the `beforeinput` event
|
|
101
|
+
// Chrome Legacy doesn't support `beforeinput` correctly
|
|
102
|
+
|
|
103
|
+
var HAS_BEFORE_INPUT_SUPPORT = (!IS_CHROME_LEGACY || !IS_ANDROID_CHROME_LEGACY) && !IS_EDGE_LEGACY && // globalThis is undefined in older browsers
|
|
104
|
+
typeof globalThis !== 'undefined' && globalThis.InputEvent && // @ts-ignore The `getTargetRanges` property isn't recognized.
|
|
105
|
+
typeof globalThis.InputEvent.prototype.getTargetRanges === 'function';
|
|
75
106
|
|
|
76
107
|
/**
|
|
77
108
|
* Two weak maps that allow us rebuild a path given a node. They are populated
|
|
@@ -364,59 +395,128 @@ var isTrackedMutation = (editor, mutation, batch) => {
|
|
|
364
395
|
return isTrackedMutation(editor, parentMutation, batch);
|
|
365
396
|
};
|
|
366
397
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
var
|
|
371
|
-
|
|
372
|
-
|
|
398
|
+
/**
|
|
399
|
+
* An auto-incrementing identifier for keys.
|
|
400
|
+
*/
|
|
401
|
+
var n = 0;
|
|
402
|
+
/**
|
|
403
|
+
* A class that keeps track of a key string. We use a full class here because we
|
|
404
|
+
* want to be able to use them as keys in `WeakMap` objects.
|
|
405
|
+
*/
|
|
373
406
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
407
|
+
class Key {
|
|
408
|
+
constructor() {
|
|
409
|
+
this.id = "".concat(n++);
|
|
410
|
+
}
|
|
377
411
|
|
|
378
|
-
|
|
379
|
-
var IS_ANDROID_CHROME_LEGACY = IS_ANDROID && typeof navigator !== 'undefined' && /Chrome?\/(?:[0-5]?\d)(?:\.)/i.test(navigator.userAgent); // Firefox did not support `beforeInput` until `v87`.
|
|
412
|
+
}
|
|
380
413
|
|
|
381
|
-
var
|
|
414
|
+
var ReactEditor = {
|
|
415
|
+
androidPendingDiffs: editor => EDITOR_TO_PENDING_DIFFS.get(editor),
|
|
416
|
+
androidScheduleFlush: editor => {
|
|
417
|
+
var _EDITOR_TO_SCHEDULE_F;
|
|
382
418
|
|
|
383
|
-
|
|
419
|
+
(_EDITOR_TO_SCHEDULE_F = EDITOR_TO_SCHEDULE_FLUSH.get(editor)) === null || _EDITOR_TO_SCHEDULE_F === void 0 ? void 0 : _EDITOR_TO_SCHEDULE_F();
|
|
420
|
+
},
|
|
421
|
+
blur: editor => {
|
|
422
|
+
var el = ReactEditor.toDOMNode(editor, editor);
|
|
423
|
+
var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
|
424
|
+
IS_FOCUSED.set(editor, false);
|
|
384
425
|
|
|
385
|
-
|
|
386
|
-
|
|
426
|
+
if (root.activeElement === el) {
|
|
427
|
+
el.blur();
|
|
428
|
+
}
|
|
429
|
+
},
|
|
430
|
+
deselect: editor => {
|
|
431
|
+
var {
|
|
432
|
+
selection
|
|
433
|
+
} = editor;
|
|
434
|
+
var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
|
435
|
+
var domSelection = root.getSelection();
|
|
387
436
|
|
|
388
|
-
|
|
389
|
-
|
|
437
|
+
if (domSelection && domSelection.rangeCount > 0) {
|
|
438
|
+
domSelection.removeAllRanges();
|
|
439
|
+
}
|
|
390
440
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
441
|
+
if (selection) {
|
|
442
|
+
Transforms.deselect(editor);
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
findDocumentOrShadowRoot: editor => {
|
|
446
|
+
var el = ReactEditor.toDOMNode(editor, editor);
|
|
447
|
+
var root = el.getRootNode();
|
|
394
448
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return !!IS_COMPOSING.get(editor);
|
|
449
|
+
if ((root instanceof Document || root instanceof ShadowRoot) && root.getSelection != null) {
|
|
450
|
+
return root;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return el.ownerDocument;
|
|
401
454
|
},
|
|
455
|
+
findEventRange: (editor, event) => {
|
|
456
|
+
if ('nativeEvent' in event) {
|
|
457
|
+
event = event.nativeEvent;
|
|
458
|
+
}
|
|
402
459
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
460
|
+
var {
|
|
461
|
+
clientX: x,
|
|
462
|
+
clientY: y,
|
|
463
|
+
target
|
|
464
|
+
} = event;
|
|
408
465
|
|
|
409
|
-
if (
|
|
410
|
-
throw new Error(
|
|
466
|
+
if (x == null || y == null) {
|
|
467
|
+
throw new Error("Cannot resolve a Slate range from a DOM event: ".concat(event));
|
|
411
468
|
}
|
|
412
469
|
|
|
413
|
-
|
|
414
|
-
|
|
470
|
+
var node = ReactEditor.toSlateNode(editor, event.target);
|
|
471
|
+
var path = ReactEditor.findPath(editor, node); // If the drop target is inside a void node, move it into either the
|
|
472
|
+
// next or previous node, depending on which side the `x` and `y`
|
|
473
|
+
// coordinates are closest to.
|
|
415
474
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
475
|
+
if (Element$1.isElement(node) && Editor.isVoid(editor, node)) {
|
|
476
|
+
var rect = target.getBoundingClientRect();
|
|
477
|
+
var isPrev = editor.isInline(node) ? x - rect.left < rect.left + rect.width - x : y - rect.top < rect.top + rect.height - y;
|
|
478
|
+
var edge = Editor.point(editor, path, {
|
|
479
|
+
edge: isPrev ? 'start' : 'end'
|
|
480
|
+
});
|
|
481
|
+
var point = isPrev ? Editor.before(editor, edge) : Editor.after(editor, edge);
|
|
482
|
+
|
|
483
|
+
if (point) {
|
|
484
|
+
var _range = Editor.range(editor, point);
|
|
485
|
+
|
|
486
|
+
return _range;
|
|
487
|
+
}
|
|
488
|
+
} // Else resolve a range from the caret position where the drop occured.
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
var domRange;
|
|
492
|
+
var {
|
|
493
|
+
document
|
|
494
|
+
} = ReactEditor.getWindow(editor); // COMPAT: In Firefox, `caretRangeFromPoint` doesn't exist. (2016/07/25)
|
|
495
|
+
|
|
496
|
+
if (document.caretRangeFromPoint) {
|
|
497
|
+
domRange = document.caretRangeFromPoint(x, y);
|
|
498
|
+
} else {
|
|
499
|
+
var position = document.caretPositionFromPoint(x, y);
|
|
500
|
+
|
|
501
|
+
if (position) {
|
|
502
|
+
domRange = document.createRange();
|
|
503
|
+
domRange.setStart(position.offsetNode, position.offset);
|
|
504
|
+
domRange.setEnd(position.offsetNode, position.offset);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
if (!domRange) {
|
|
509
|
+
throw new Error("Cannot resolve a Slate range from a DOM event: ".concat(event));
|
|
510
|
+
} // Resolve a Slate range from the DOM range.
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
var range = ReactEditor.toSlateRange(editor, domRange, {
|
|
514
|
+
exactMatch: false,
|
|
515
|
+
suppressThrow: false
|
|
516
|
+
});
|
|
517
|
+
return range;
|
|
518
|
+
},
|
|
519
|
+
findKey: (editor, node) => {
|
|
420
520
|
var key = NODE_TO_KEY.get(node);
|
|
421
521
|
|
|
422
522
|
if (!key) {
|
|
@@ -426,11 +526,7 @@ var ReactEditor = {
|
|
|
426
526
|
|
|
427
527
|
return key;
|
|
428
528
|
},
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Find the path of Slate node.
|
|
432
|
-
*/
|
|
433
|
-
findPath(editor, node) {
|
|
529
|
+
findPath: (editor, node) => {
|
|
434
530
|
var path = [];
|
|
435
531
|
var child = node;
|
|
436
532
|
|
|
@@ -457,52 +553,7 @@ var ReactEditor = {
|
|
|
457
553
|
|
|
458
554
|
throw new Error("Unable to find the path for Slate node: ".concat(Scrubber.stringify(node)));
|
|
459
555
|
},
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Find the DOM node that implements DocumentOrShadowRoot for the editor.
|
|
463
|
-
*/
|
|
464
|
-
findDocumentOrShadowRoot(editor) {
|
|
465
|
-
var el = ReactEditor.toDOMNode(editor, editor);
|
|
466
|
-
var root = el.getRootNode();
|
|
467
|
-
|
|
468
|
-
if ((root instanceof Document || root instanceof ShadowRoot) && root.getSelection != null) {
|
|
469
|
-
return root;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
return el.ownerDocument;
|
|
473
|
-
},
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* Check if the editor is focused.
|
|
477
|
-
*/
|
|
478
|
-
isFocused(editor) {
|
|
479
|
-
return !!IS_FOCUSED.get(editor);
|
|
480
|
-
},
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* Check if the editor is in read-only mode.
|
|
484
|
-
*/
|
|
485
|
-
isReadOnly(editor) {
|
|
486
|
-
return !!IS_READ_ONLY.get(editor);
|
|
487
|
-
},
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Blur the editor.
|
|
491
|
-
*/
|
|
492
|
-
blur(editor) {
|
|
493
|
-
var el = ReactEditor.toDOMNode(editor, editor);
|
|
494
|
-
var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
|
495
|
-
IS_FOCUSED.set(editor, false);
|
|
496
|
-
|
|
497
|
-
if (root.activeElement === el) {
|
|
498
|
-
el.blur();
|
|
499
|
-
}
|
|
500
|
-
},
|
|
501
|
-
|
|
502
|
-
/**
|
|
503
|
-
* Focus the editor.
|
|
504
|
-
*/
|
|
505
|
-
focus(editor) {
|
|
556
|
+
focus: editor => {
|
|
506
557
|
var el = ReactEditor.toDOMNode(editor, editor);
|
|
507
558
|
var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
|
508
559
|
IS_FOCUSED.set(editor, true);
|
|
@@ -513,30 +564,16 @@ var ReactEditor = {
|
|
|
513
564
|
});
|
|
514
565
|
}
|
|
515
566
|
},
|
|
567
|
+
getWindow: editor => {
|
|
568
|
+
var window = EDITOR_TO_WINDOW.get(editor);
|
|
516
569
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
*/
|
|
520
|
-
deselect(editor) {
|
|
521
|
-
var {
|
|
522
|
-
selection
|
|
523
|
-
} = editor;
|
|
524
|
-
var root = ReactEditor.findDocumentOrShadowRoot(editor);
|
|
525
|
-
var domSelection = root.getSelection();
|
|
526
|
-
|
|
527
|
-
if (domSelection && domSelection.rangeCount > 0) {
|
|
528
|
-
domSelection.removeAllRanges();
|
|
570
|
+
if (!window) {
|
|
571
|
+
throw new Error('Unable to find a host window element for this editor');
|
|
529
572
|
}
|
|
530
573
|
|
|
531
|
-
|
|
532
|
-
Transforms.deselect(editor);
|
|
533
|
-
}
|
|
574
|
+
return window;
|
|
534
575
|
},
|
|
535
|
-
|
|
536
|
-
/**
|
|
537
|
-
* Check if a DOM node is within the editor.
|
|
538
|
-
*/
|
|
539
|
-
hasDOMNode(editor, target) {
|
|
576
|
+
hasDOMNode: function hasDOMNode(editor, target) {
|
|
540
577
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
541
578
|
var {
|
|
542
579
|
editable = false
|
|
@@ -563,39 +600,35 @@ var ReactEditor = {
|
|
|
563
600
|
// this is the core logic that lets you know you got the right editor.selection instead of null when editor is contenteditable="false"(readOnly)
|
|
564
601
|
targetEl.closest('[contenteditable="false"]') === editorEl || !!targetEl.getAttribute('data-slate-zero-width'));
|
|
565
602
|
},
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
603
|
+
hasEditableTarget: (editor, target) => isDOMNode(target) && ReactEditor.hasDOMNode(editor, target, {
|
|
604
|
+
editable: true
|
|
605
|
+
}),
|
|
606
|
+
hasRange: (editor, range) => {
|
|
607
|
+
var {
|
|
608
|
+
anchor,
|
|
609
|
+
focus
|
|
610
|
+
} = range;
|
|
611
|
+
return Editor.hasPath(editor, anchor.path) && Editor.hasPath(editor, focus.path);
|
|
572
612
|
},
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
insertFragmentData(editor, data) {
|
|
578
|
-
return editor.insertFragmentData(data);
|
|
613
|
+
hasSelectableTarget: (editor, target) => ReactEditor.hasEditableTarget(editor, target) || ReactEditor.isTargetInsideNonReadonlyVoid(editor, target),
|
|
614
|
+
hasTarget: (editor, target) => isDOMNode(target) && ReactEditor.hasDOMNode(editor, target),
|
|
615
|
+
insertData: (editor, data) => {
|
|
616
|
+
editor.insertData(data);
|
|
579
617
|
},
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
insertTextData(editor, data) {
|
|
585
|
-
return editor.insertTextData(data);
|
|
618
|
+
insertFragmentData: (editor, data) => editor.insertFragmentData(data),
|
|
619
|
+
insertTextData: (editor, data) => editor.insertTextData(data),
|
|
620
|
+
isComposing: editor => {
|
|
621
|
+
return !!IS_COMPOSING.get(editor);
|
|
586
622
|
},
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
623
|
+
isFocused: editor => !!IS_FOCUSED.get(editor),
|
|
624
|
+
isReadOnly: editor => !!IS_READ_ONLY.get(editor),
|
|
625
|
+
isTargetInsideNonReadonlyVoid: (editor, target) => {
|
|
626
|
+
if (IS_READ_ONLY.get(editor)) return false;
|
|
627
|
+
var slateNode = ReactEditor.hasTarget(editor, target) && ReactEditor.toSlateNode(editor, target);
|
|
628
|
+
return Element$1.isElement(slateNode) && Editor.isVoid(editor, slateNode);
|
|
593
629
|
},
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
* Find the native DOM element from a Slate node.
|
|
597
|
-
*/
|
|
598
|
-
toDOMNode(editor, node) {
|
|
630
|
+
setFragmentData: (editor, data, originEvent) => editor.setFragmentData(data, originEvent),
|
|
631
|
+
toDOMNode: (editor, node) => {
|
|
599
632
|
var KEY_TO_ELEMENT = EDITOR_TO_KEY_TO_ELEMENT.get(editor);
|
|
600
633
|
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));
|
|
601
634
|
|
|
@@ -605,11 +638,7 @@ var ReactEditor = {
|
|
|
605
638
|
|
|
606
639
|
return domNode;
|
|
607
640
|
},
|
|
608
|
-
|
|
609
|
-
/**
|
|
610
|
-
* Find a native DOM selection point from a Slate point.
|
|
611
|
-
*/
|
|
612
|
-
toDOMPoint(editor, point) {
|
|
641
|
+
toDOMPoint: (editor, point) => {
|
|
613
642
|
var [node] = Editor.node(editor, point.path);
|
|
614
643
|
var el = ReactEditor.toDOMNode(editor, node);
|
|
615
644
|
var domPoint; // If we're inside a void node, force the offset to 0, otherwise the zero
|
|
@@ -677,16 +706,7 @@ var ReactEditor = {
|
|
|
677
706
|
|
|
678
707
|
return domPoint;
|
|
679
708
|
},
|
|
680
|
-
|
|
681
|
-
/**
|
|
682
|
-
* Find a native DOM range from a Slate `range`.
|
|
683
|
-
*
|
|
684
|
-
* Notice: the returned range will always be ordinal regardless of the direction of Slate `range` due to DOM API limit.
|
|
685
|
-
*
|
|
686
|
-
* there is no way to create a reverse DOM Range using Range.setStart/setEnd
|
|
687
|
-
* according to https://dom.spec.whatwg.org/#concept-range-bp-set.
|
|
688
|
-
*/
|
|
689
|
-
toDOMRange(editor, range) {
|
|
709
|
+
toDOMRange: (editor, range) => {
|
|
690
710
|
var {
|
|
691
711
|
anchor,
|
|
692
712
|
focus
|
|
@@ -709,11 +729,7 @@ var ReactEditor = {
|
|
|
709
729
|
domRange.setEnd(endNode, isEndAtZeroWidth ? 1 : endOffset);
|
|
710
730
|
return domRange;
|
|
711
731
|
},
|
|
712
|
-
|
|
713
|
-
/**
|
|
714
|
-
* Find a Slate node from a native DOM `element`.
|
|
715
|
-
*/
|
|
716
|
-
toSlateNode(editor, domNode) {
|
|
732
|
+
toSlateNode: (editor, domNode) => {
|
|
717
733
|
var domEl = isDOMElement(domNode) ? domNode : domNode.parentElement;
|
|
718
734
|
|
|
719
735
|
if (domEl && !domEl.hasAttribute('data-slate-node')) {
|
|
@@ -728,79 +744,7 @@ var ReactEditor = {
|
|
|
728
744
|
|
|
729
745
|
return node;
|
|
730
746
|
},
|
|
731
|
-
|
|
732
|
-
/**
|
|
733
|
-
* Get the target range from a DOM `event`.
|
|
734
|
-
*/
|
|
735
|
-
findEventRange(editor, event) {
|
|
736
|
-
if ('nativeEvent' in event) {
|
|
737
|
-
event = event.nativeEvent;
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
var {
|
|
741
|
-
clientX: x,
|
|
742
|
-
clientY: y,
|
|
743
|
-
target
|
|
744
|
-
} = event;
|
|
745
|
-
|
|
746
|
-
if (x == null || y == null) {
|
|
747
|
-
throw new Error("Cannot resolve a Slate range from a DOM event: ".concat(event));
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
var node = ReactEditor.toSlateNode(editor, event.target);
|
|
751
|
-
var path = ReactEditor.findPath(editor, node); // If the drop target is inside a void node, move it into either the
|
|
752
|
-
// next or previous node, depending on which side the `x` and `y`
|
|
753
|
-
// coordinates are closest to.
|
|
754
|
-
|
|
755
|
-
if (Element$1.isElement(node) && Editor.isVoid(editor, node)) {
|
|
756
|
-
var rect = target.getBoundingClientRect();
|
|
757
|
-
var isPrev = editor.isInline(node) ? x - rect.left < rect.left + rect.width - x : y - rect.top < rect.top + rect.height - y;
|
|
758
|
-
var edge = Editor.point(editor, path, {
|
|
759
|
-
edge: isPrev ? 'start' : 'end'
|
|
760
|
-
});
|
|
761
|
-
var point = isPrev ? Editor.before(editor, edge) : Editor.after(editor, edge);
|
|
762
|
-
|
|
763
|
-
if (point) {
|
|
764
|
-
var _range = Editor.range(editor, point);
|
|
765
|
-
|
|
766
|
-
return _range;
|
|
767
|
-
}
|
|
768
|
-
} // Else resolve a range from the caret position where the drop occured.
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
var domRange;
|
|
772
|
-
var {
|
|
773
|
-
document
|
|
774
|
-
} = ReactEditor.getWindow(editor); // COMPAT: In Firefox, `caretRangeFromPoint` doesn't exist. (2016/07/25)
|
|
775
|
-
|
|
776
|
-
if (document.caretRangeFromPoint) {
|
|
777
|
-
domRange = document.caretRangeFromPoint(x, y);
|
|
778
|
-
} else {
|
|
779
|
-
var position = document.caretPositionFromPoint(x, y);
|
|
780
|
-
|
|
781
|
-
if (position) {
|
|
782
|
-
domRange = document.createRange();
|
|
783
|
-
domRange.setStart(position.offsetNode, position.offset);
|
|
784
|
-
domRange.setEnd(position.offsetNode, position.offset);
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
if (!domRange) {
|
|
789
|
-
throw new Error("Cannot resolve a Slate range from a DOM event: ".concat(event));
|
|
790
|
-
} // Resolve a Slate range from the DOM range.
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
var range = ReactEditor.toSlateRange(editor, domRange, {
|
|
794
|
-
exactMatch: false,
|
|
795
|
-
suppressThrow: false
|
|
796
|
-
});
|
|
797
|
-
return range;
|
|
798
|
-
},
|
|
799
|
-
|
|
800
|
-
/**
|
|
801
|
-
* Find a Slate point from a DOM selection's `domNode` and `domOffset`.
|
|
802
|
-
*/
|
|
803
|
-
toSlatePoint(editor, domPoint, options) {
|
|
747
|
+
toSlatePoint: (editor, domPoint, options) => {
|
|
804
748
|
var {
|
|
805
749
|
exactMatch,
|
|
806
750
|
suppressThrow
|
|
@@ -932,11 +876,7 @@ var ReactEditor = {
|
|
|
932
876
|
offset
|
|
933
877
|
};
|
|
934
878
|
},
|
|
935
|
-
|
|
936
|
-
/**
|
|
937
|
-
* Find a Slate range from a DOM range or selection.
|
|
938
|
-
*/
|
|
939
|
-
toSlateRange(editor, domRange, options) {
|
|
879
|
+
toSlateRange: (editor, domRange, options) => {
|
|
940
880
|
var {
|
|
941
881
|
exactMatch,
|
|
942
882
|
suppressThrow
|
|
@@ -1062,2199 +1002,2123 @@ var ReactEditor = {
|
|
|
1062
1002
|
}
|
|
1063
1003
|
|
|
1064
1004
|
return range;
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
hasRange(editor, range) {
|
|
1068
|
-
var {
|
|
1069
|
-
anchor,
|
|
1070
|
-
focus
|
|
1071
|
-
} = range;
|
|
1072
|
-
return Editor.hasPath(editor, anchor.path) && Editor.hasPath(editor, focus.path);
|
|
1073
|
-
},
|
|
1074
|
-
|
|
1075
|
-
/**
|
|
1076
|
-
* Check if the target is in the editor.
|
|
1077
|
-
*/
|
|
1078
|
-
hasTarget(editor, target) {
|
|
1079
|
-
return isDOMNode(target) && ReactEditor.hasDOMNode(editor, target);
|
|
1080
|
-
},
|
|
1081
|
-
|
|
1082
|
-
/**
|
|
1083
|
-
* Check if the target is editable and in the editor.
|
|
1084
|
-
*/
|
|
1085
|
-
hasEditableTarget(editor, target) {
|
|
1086
|
-
return isDOMNode(target) && ReactEditor.hasDOMNode(editor, target, {
|
|
1087
|
-
editable: true
|
|
1088
|
-
});
|
|
1089
|
-
},
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
1090
1007
|
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
return ReactEditor.hasEditableTarget(editor, target) || ReactEditor.isTargetInsideNonReadonlyVoid(editor, target);
|
|
1096
|
-
},
|
|
1008
|
+
/**
|
|
1009
|
+
* Check whether a text diff was applied in a way we can perform the pending action on /
|
|
1010
|
+
* recover the pending selection.
|
|
1011
|
+
*/
|
|
1097
1012
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
var slateNode = ReactEditor.hasTarget(editor, target) && ReactEditor.toSlateNode(editor, target);
|
|
1104
|
-
return Element$1.isElement(slateNode) && Editor.isVoid(editor, slateNode);
|
|
1105
|
-
},
|
|
1013
|
+
function verifyDiffState(editor, textDiff) {
|
|
1014
|
+
var {
|
|
1015
|
+
path,
|
|
1016
|
+
diff
|
|
1017
|
+
} = textDiff;
|
|
1106
1018
|
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
androidScheduleFlush(editor) {
|
|
1111
|
-
var _EDITOR_TO_SCHEDULE_F;
|
|
1019
|
+
if (!Editor.hasPath(editor, path)) {
|
|
1020
|
+
return false;
|
|
1021
|
+
}
|
|
1112
1022
|
|
|
1113
|
-
|
|
1114
|
-
},
|
|
1023
|
+
var node = Node.get(editor, path);
|
|
1115
1024
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
*/
|
|
1119
|
-
androidPendingDiffs(editor) {
|
|
1120
|
-
return EDITOR_TO_PENDING_DIFFS.get(editor);
|
|
1025
|
+
if (!Text$1.isText(node)) {
|
|
1026
|
+
return false;
|
|
1121
1027
|
}
|
|
1122
1028
|
|
|
1123
|
-
|
|
1029
|
+
if (diff.start !== node.text.length || diff.text.length === 0) {
|
|
1030
|
+
return node.text.slice(diff.start, diff.start + diff.text.length) === diff.text;
|
|
1031
|
+
}
|
|
1124
1032
|
|
|
1125
|
-
var
|
|
1126
|
-
_excluded2$1 = ["anchor", "focus"];
|
|
1127
|
-
var shallowCompare = (obj1, obj2) => Object.keys(obj1).length === Object.keys(obj2).length && Object.keys(obj1).every(key => obj2.hasOwnProperty(key) && obj1[key] === obj2[key]);
|
|
1033
|
+
var nextPath = Path.next(path);
|
|
1128
1034
|
|
|
1129
|
-
|
|
1130
|
-
|
|
1035
|
+
if (!Editor.hasPath(editor, nextPath)) {
|
|
1036
|
+
return false;
|
|
1037
|
+
}
|
|
1131
1038
|
|
|
1132
|
-
var
|
|
1039
|
+
var nextNode = Node.get(editor, nextPath);
|
|
1040
|
+
return Text$1.isText(nextNode) && nextNode.text.startsWith(diff.text);
|
|
1041
|
+
}
|
|
1042
|
+
function applyStringDiff(text) {
|
|
1043
|
+
for (var _len = arguments.length, diffs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
1044
|
+
diffs[_key - 1] = arguments[_key];
|
|
1045
|
+
}
|
|
1133
1046
|
|
|
1134
|
-
return
|
|
1135
|
-
}
|
|
1136
|
-
/**
|
|
1137
|
-
* Check if a list of decorator ranges are equal to another.
|
|
1138
|
-
*
|
|
1139
|
-
* PERF: this requires the two lists to also have the ranges inside them in the
|
|
1140
|
-
* same order, but this is an okay constraint for us since decorations are
|
|
1141
|
-
* kept in order, and the odd case where they aren't is okay to re-render for.
|
|
1142
|
-
*/
|
|
1047
|
+
return diffs.reduce((text, diff) => text.slice(0, diff.start) + diff.text + text.slice(diff.end), text);
|
|
1048
|
+
}
|
|
1143
1049
|
|
|
1050
|
+
function longestCommonPrefixLength(str, another) {
|
|
1051
|
+
var length = Math.min(str.length, another.length);
|
|
1144
1052
|
|
|
1145
|
-
var
|
|
1146
|
-
|
|
1147
|
-
|
|
1053
|
+
for (var i = 0; i < length; i++) {
|
|
1054
|
+
if (str.charAt(i) !== another.charAt(i)) {
|
|
1055
|
+
return i;
|
|
1056
|
+
}
|
|
1148
1057
|
}
|
|
1149
1058
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
var other = another[i];
|
|
1059
|
+
return length;
|
|
1060
|
+
}
|
|
1153
1061
|
|
|
1154
|
-
|
|
1155
|
-
|
|
1062
|
+
function longestCommonSuffixLength(str, another, max) {
|
|
1063
|
+
var length = Math.min(str.length, another.length, max);
|
|
1064
|
+
|
|
1065
|
+
for (var i = 0; i < length; i++) {
|
|
1066
|
+
if (str.charAt(str.length - i - 1) !== another.charAt(another.length - i - 1)) {
|
|
1067
|
+
return i;
|
|
1156
1068
|
}
|
|
1157
1069
|
}
|
|
1158
1070
|
|
|
1159
|
-
return
|
|
1160
|
-
}
|
|
1071
|
+
return length;
|
|
1072
|
+
}
|
|
1161
1073
|
/**
|
|
1162
|
-
*
|
|
1163
|
-
*
|
|
1164
|
-
* PERF: this requires the two lists to also have the ranges inside them in the
|
|
1165
|
-
* same order, but this is an okay constraint for us since decorations are
|
|
1166
|
-
* kept in order, and the odd case where they aren't is okay to re-render for.
|
|
1074
|
+
* Remove redundant changes from the diff so that it spans the minimal possible range
|
|
1167
1075
|
*/
|
|
1168
1076
|
|
|
1169
|
-
var isTextDecorationsEqual = (list, another) => {
|
|
1170
|
-
if (list.length !== another.length) {
|
|
1171
|
-
return false;
|
|
1172
|
-
}
|
|
1173
1077
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1078
|
+
function normalizeStringDiff(targetText, diff) {
|
|
1079
|
+
var {
|
|
1080
|
+
start,
|
|
1081
|
+
end,
|
|
1082
|
+
text
|
|
1083
|
+
} = diff;
|
|
1084
|
+
var removedText = targetText.slice(start, end);
|
|
1085
|
+
var prefixLength = longestCommonPrefixLength(removedText, text);
|
|
1086
|
+
var max = Math.min(removedText.length - prefixLength, text.length - prefixLength);
|
|
1087
|
+
var suffixLength = longestCommonSuffixLength(removedText, text, max);
|
|
1088
|
+
var normalized = {
|
|
1089
|
+
start: start + prefixLength,
|
|
1090
|
+
end: end - suffixLength,
|
|
1091
|
+
text: text.slice(prefixLength, text.length - suffixLength)
|
|
1092
|
+
};
|
|
1177
1093
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
}
|
|
1094
|
+
if (normalized.start === normalized.end && normalized.text.length === 0) {
|
|
1095
|
+
return null;
|
|
1181
1096
|
}
|
|
1182
1097
|
|
|
1183
|
-
return
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1098
|
+
return normalized;
|
|
1099
|
+
}
|
|
1186
1100
|
/**
|
|
1187
|
-
*
|
|
1101
|
+
* Return a string diff that is equivalent to applying b after a spanning the range of
|
|
1102
|
+
* both changes
|
|
1188
1103
|
*/
|
|
1189
1104
|
|
|
1190
|
-
|
|
1191
|
-
|
|
1105
|
+
function mergeStringDiffs(targetText, a, b) {
|
|
1106
|
+
var start = Math.min(a.start, b.start);
|
|
1107
|
+
var overlap = Math.max(0, Math.min(a.start + a.text.length, b.end) - b.start);
|
|
1108
|
+
var applied = applyStringDiff(targetText, a, b);
|
|
1109
|
+
var sliceEnd = Math.max(b.start + b.text.length, a.start + a.text.length + (a.start + a.text.length > b.start ? b.text.length : 0) - overlap);
|
|
1110
|
+
var text = applied.slice(start, sliceEnd);
|
|
1111
|
+
var end = Math.max(a.end, b.end - a.text.length + (a.end - a.start));
|
|
1112
|
+
return normalizeStringDiff(targetText, {
|
|
1113
|
+
start,
|
|
1114
|
+
end,
|
|
1115
|
+
text
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1192
1118
|
/**
|
|
1193
|
-
*
|
|
1119
|
+
* Get the slate range the text diff spans.
|
|
1194
1120
|
*/
|
|
1195
1121
|
|
|
1196
|
-
|
|
1122
|
+
function targetRange(textDiff) {
|
|
1197
1123
|
var {
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1124
|
+
path,
|
|
1125
|
+
diff
|
|
1126
|
+
} = textDiff;
|
|
1127
|
+
return {
|
|
1128
|
+
anchor: {
|
|
1129
|
+
path,
|
|
1130
|
+
offset: diff.start
|
|
1131
|
+
},
|
|
1132
|
+
focus: {
|
|
1133
|
+
path,
|
|
1134
|
+
offset: diff.end
|
|
1135
|
+
}
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Normalize a 'pending point' a.k.a a point based on the dom state before applying
|
|
1140
|
+
* the pending diffs. Since the pending diffs might have been inserted with different
|
|
1141
|
+
* marks we have to 'walk' the offset from the starting position to ensure we still
|
|
1142
|
+
* have a valid point inside the document
|
|
1143
|
+
*/
|
|
1216
1144
|
|
|
1145
|
+
function normalizePoint(editor, point) {
|
|
1146
|
+
var {
|
|
1147
|
+
path,
|
|
1148
|
+
offset
|
|
1149
|
+
} = point;
|
|
1217
1150
|
|
|
1218
|
-
if (
|
|
1219
|
-
return
|
|
1220
|
-
|
|
1221
|
-
isMarkPlaceholder: isMarkPlaceholder
|
|
1222
|
-
});
|
|
1223
|
-
} // COMPAT: If the text is empty, it's because it's on the edge of an inline
|
|
1224
|
-
// node, so we render a zero-width space so that the selection can be
|
|
1225
|
-
// inserted next to it still.
|
|
1151
|
+
if (!Editor.hasPath(editor, path)) {
|
|
1152
|
+
return null;
|
|
1153
|
+
}
|
|
1226
1154
|
|
|
1155
|
+
var leaf = Node.get(editor, path);
|
|
1227
1156
|
|
|
1228
|
-
if (leaf
|
|
1229
|
-
return
|
|
1230
|
-
|
|
1231
|
-
});
|
|
1232
|
-
} // COMPAT: Browsers will collapse trailing new lines at the end of blocks,
|
|
1233
|
-
// so we need to add an extra trailing new lines to prevent that.
|
|
1157
|
+
if (!Text$1.isText(leaf)) {
|
|
1158
|
+
return null;
|
|
1159
|
+
}
|
|
1234
1160
|
|
|
1161
|
+
var parentBlock = Editor.above(editor, {
|
|
1162
|
+
match: n => Element$1.isElement(n) && Editor.isBlock(editor, n),
|
|
1163
|
+
at: path
|
|
1164
|
+
});
|
|
1235
1165
|
|
|
1236
|
-
if (
|
|
1237
|
-
return
|
|
1238
|
-
isTrailing: true,
|
|
1239
|
-
text: leaf.text
|
|
1240
|
-
});
|
|
1166
|
+
if (!parentBlock) {
|
|
1167
|
+
return null;
|
|
1241
1168
|
}
|
|
1242
1169
|
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
* Leaf strings with text in them.
|
|
1249
|
-
*/
|
|
1170
|
+
while (offset > leaf.text.length) {
|
|
1171
|
+
var entry = Editor.next(editor, {
|
|
1172
|
+
at: path,
|
|
1173
|
+
match: Text$1.isText
|
|
1174
|
+
});
|
|
1250
1175
|
|
|
1176
|
+
if (!entry || !Path.isDescendant(entry[1], parentBlock[1])) {
|
|
1177
|
+
return null;
|
|
1178
|
+
}
|
|
1251
1179
|
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
} = props;
|
|
1257
|
-
var ref = useRef(null);
|
|
1180
|
+
offset -= leaf.text.length;
|
|
1181
|
+
leaf = entry[0];
|
|
1182
|
+
path = entry[1];
|
|
1183
|
+
}
|
|
1258
1184
|
|
|
1259
|
-
|
|
1260
|
-
|
|
1185
|
+
return {
|
|
1186
|
+
path,
|
|
1187
|
+
offset
|
|
1261
1188
|
};
|
|
1189
|
+
}
|
|
1190
|
+
/**
|
|
1191
|
+
* Normalize a 'pending selection' to ensure it's valid in the current document state.
|
|
1192
|
+
*/
|
|
1262
1193
|
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
// updating the DOM is not a one way dataflow anymore. What we need here is not reconciliation and diffing
|
|
1266
|
-
// with previous version of the virtual DOM, but rather diffing with the actual DOM element, and replace the DOM <span> content
|
|
1267
|
-
// exactly if and only if its current content does not match our current virtual DOM.
|
|
1268
|
-
// Otherwise the DOM TextNode would always be replaced by React as the user types, which interferes with native text features,
|
|
1269
|
-
// eg makes native spellcheck opt out from checking the text node.
|
|
1270
|
-
// useLayoutEffect: updating our span before browser paint
|
|
1271
|
-
|
|
1272
|
-
useIsomorphicLayoutEffect(() => {
|
|
1273
|
-
// null coalescing text to make sure we're not outputing "null" as a string in the extreme case it is nullish at runtime
|
|
1274
|
-
var textWithTrailing = getTextContent();
|
|
1194
|
+
function normalizeRange(editor, range) {
|
|
1195
|
+
var anchor = normalizePoint(editor, range.anchor);
|
|
1275
1196
|
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
// as this effectively replaces "specifying the text in the virtual DOM under the <span> below" on each render
|
|
1197
|
+
if (!anchor) {
|
|
1198
|
+
return null;
|
|
1199
|
+
}
|
|
1280
1200
|
|
|
1281
|
-
|
|
1282
|
-
|
|
1201
|
+
if (Range.isCollapsed(range)) {
|
|
1202
|
+
return {
|
|
1203
|
+
anchor,
|
|
1204
|
+
focus: anchor
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1283
1207
|
|
|
1284
|
-
|
|
1285
|
-
ref: ref
|
|
1286
|
-
}, initialText);
|
|
1287
|
-
};
|
|
1208
|
+
var focus = normalizePoint(editor, range.focus);
|
|
1288
1209
|
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
ref: ref
|
|
1293
|
-
}, props.children);
|
|
1294
|
-
}));
|
|
1295
|
-
/**
|
|
1296
|
-
* Leaf strings without text, render as zero-width strings.
|
|
1297
|
-
*/
|
|
1210
|
+
if (!focus) {
|
|
1211
|
+
return null;
|
|
1212
|
+
}
|
|
1298
1213
|
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
isLineBreak = false,
|
|
1303
|
-
isMarkPlaceholder = false
|
|
1304
|
-
} = props;
|
|
1305
|
-
var attributes = {
|
|
1306
|
-
'data-slate-zero-width': isLineBreak ? 'n' : 'z',
|
|
1307
|
-
'data-slate-length': length
|
|
1214
|
+
return {
|
|
1215
|
+
anchor,
|
|
1216
|
+
focus
|
|
1308
1217
|
};
|
|
1218
|
+
}
|
|
1219
|
+
function transformPendingPoint(editor, point, op) {
|
|
1220
|
+
var pendingDiffs = EDITOR_TO_PENDING_DIFFS.get(editor);
|
|
1221
|
+
var textDiff = pendingDiffs === null || pendingDiffs === void 0 ? void 0 : pendingDiffs.find(_ref => {
|
|
1222
|
+
var {
|
|
1223
|
+
path
|
|
1224
|
+
} = _ref;
|
|
1225
|
+
return Path.equals(path, point.path);
|
|
1226
|
+
});
|
|
1309
1227
|
|
|
1310
|
-
if (
|
|
1311
|
-
|
|
1228
|
+
if (!textDiff || point.offset <= textDiff.diff.start) {
|
|
1229
|
+
return Point.transform(point, op, {
|
|
1230
|
+
affinity: 'backward'
|
|
1231
|
+
});
|
|
1312
1232
|
}
|
|
1313
1233
|
|
|
1314
|
-
|
|
1315
|
-
|
|
1234
|
+
var {
|
|
1235
|
+
diff
|
|
1236
|
+
} = textDiff; // Point references location inside the diff => transform the point based on the location
|
|
1237
|
+
// the diff will be applied to and add the offset inside the diff.
|
|
1316
1238
|
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1239
|
+
if (point.offset <= diff.start + diff.text.length) {
|
|
1240
|
+
var _anchor = {
|
|
1241
|
+
path: point.path,
|
|
1242
|
+
offset: diff.start
|
|
1243
|
+
};
|
|
1320
1244
|
|
|
1321
|
-
var
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
*/
|
|
1245
|
+
var _transformed = Point.transform(_anchor, op, {
|
|
1246
|
+
affinity: 'backward'
|
|
1247
|
+
});
|
|
1325
1248
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1249
|
+
if (!_transformed) {
|
|
1250
|
+
return null;
|
|
1251
|
+
}
|
|
1328
1252
|
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1253
|
+
return {
|
|
1254
|
+
path: _transformed.path,
|
|
1255
|
+
offset: _transformed.offset + point.offset - diff.start
|
|
1256
|
+
};
|
|
1257
|
+
} // Point references location after the diff
|
|
1332
1258
|
|
|
1333
|
-
return editor;
|
|
1334
|
-
};
|
|
1335
1259
|
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1260
|
+
var anchor = {
|
|
1261
|
+
path: point.path,
|
|
1262
|
+
offset: point.offset - diff.text.length + diff.end - diff.start
|
|
1263
|
+
};
|
|
1264
|
+
var transformed = Point.transform(anchor, op, {
|
|
1265
|
+
affinity: 'backward'
|
|
1266
|
+
});
|
|
1339
1267
|
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
}
|
|
1268
|
+
if (!transformed) {
|
|
1269
|
+
return null;
|
|
1343
1270
|
}
|
|
1344
|
-
}
|
|
1345
1271
|
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
clearTimeout(timeoutRef.current);
|
|
1349
|
-
timeoutRef.current = null;
|
|
1272
|
+
if (op.type === 'split_node' && Path.equals(op.path, point.path) && anchor.offset < op.position && diff.start < op.position) {
|
|
1273
|
+
return transformed;
|
|
1350
1274
|
}
|
|
1275
|
+
|
|
1276
|
+
return {
|
|
1277
|
+
path: transformed.path,
|
|
1278
|
+
offset: transformed.offset + diff.text.length - diff.end + diff.start
|
|
1279
|
+
};
|
|
1351
1280
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
*/
|
|
1281
|
+
function transformPendingRange(editor, range, op) {
|
|
1282
|
+
var anchor = transformPendingPoint(editor, range.anchor, op);
|
|
1355
1283
|
|
|
1284
|
+
if (!anchor) {
|
|
1285
|
+
return null;
|
|
1286
|
+
}
|
|
1356
1287
|
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
text,
|
|
1362
|
-
parent,
|
|
1363
|
-
renderPlaceholder,
|
|
1364
|
-
renderLeaf = props => /*#__PURE__*/React.createElement(DefaultLeaf, Object.assign({}, props))
|
|
1365
|
-
} = props;
|
|
1366
|
-
var editor = useSlateStatic();
|
|
1367
|
-
var placeholderResizeObserver = useRef(null);
|
|
1368
|
-
var placeholderRef = useRef(null);
|
|
1369
|
-
var [showPlaceholder, setShowPlaceholder] = useState(false);
|
|
1370
|
-
var showPlaceholderTimeoutRef = useRef(null);
|
|
1371
|
-
var callbackPlaceholderRef = useCallback(placeholderEl => {
|
|
1372
|
-
disconnectPlaceholderResizeObserver(placeholderResizeObserver, placeholderEl == null);
|
|
1373
|
-
|
|
1374
|
-
if (placeholderEl == null) {
|
|
1375
|
-
var _leaf$onPlaceholderRe;
|
|
1376
|
-
|
|
1377
|
-
EDITOR_TO_PLACEHOLDER_ELEMENT.delete(editor);
|
|
1378
|
-
(_leaf$onPlaceholderRe = leaf.onPlaceholderResize) === null || _leaf$onPlaceholderRe === void 0 ? void 0 : _leaf$onPlaceholderRe.call(leaf, null);
|
|
1379
|
-
} else {
|
|
1380
|
-
EDITOR_TO_PLACEHOLDER_ELEMENT.set(editor, placeholderEl);
|
|
1381
|
-
|
|
1382
|
-
if (!placeholderResizeObserver.current) {
|
|
1383
|
-
// Create a new observer and observe the placeholder element.
|
|
1384
|
-
var ResizeObserver$1 = window.ResizeObserver || ResizeObserver;
|
|
1385
|
-
placeholderResizeObserver.current = new ResizeObserver$1(() => {
|
|
1386
|
-
var _leaf$onPlaceholderRe2;
|
|
1387
|
-
|
|
1388
|
-
(_leaf$onPlaceholderRe2 = leaf.onPlaceholderResize) === null || _leaf$onPlaceholderRe2 === void 0 ? void 0 : _leaf$onPlaceholderRe2.call(leaf, placeholderEl);
|
|
1389
|
-
});
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
placeholderResizeObserver.current.observe(placeholderEl);
|
|
1393
|
-
placeholderRef.current = placeholderEl;
|
|
1394
|
-
}
|
|
1395
|
-
}, [placeholderRef, leaf, editor]);
|
|
1396
|
-
var children = /*#__PURE__*/React.createElement(String, {
|
|
1397
|
-
isLast: isLast,
|
|
1398
|
-
leaf: leaf,
|
|
1399
|
-
parent: parent,
|
|
1400
|
-
text: text
|
|
1401
|
-
});
|
|
1402
|
-
var leafIsPlaceholder = leaf[PLACEHOLDER_SYMBOL];
|
|
1403
|
-
useEffect(() => {
|
|
1404
|
-
if (leafIsPlaceholder) {
|
|
1405
|
-
if (!showPlaceholderTimeoutRef.current) {
|
|
1406
|
-
// Delay the placeholder so it will not render in a selection
|
|
1407
|
-
showPlaceholderTimeoutRef.current = setTimeout(() => {
|
|
1408
|
-
setShowPlaceholder(true);
|
|
1409
|
-
showPlaceholderTimeoutRef.current = null;
|
|
1410
|
-
}, 300);
|
|
1411
|
-
}
|
|
1412
|
-
} else {
|
|
1413
|
-
clearTimeoutRef(showPlaceholderTimeoutRef);
|
|
1414
|
-
setShowPlaceholder(false);
|
|
1415
|
-
}
|
|
1416
|
-
|
|
1417
|
-
return () => clearTimeoutRef(showPlaceholderTimeoutRef);
|
|
1418
|
-
}, [leafIsPlaceholder, setShowPlaceholder]);
|
|
1419
|
-
|
|
1420
|
-
if (leafIsPlaceholder && showPlaceholder) {
|
|
1421
|
-
var placeholderProps = {
|
|
1422
|
-
children: leaf.placeholder,
|
|
1423
|
-
attributes: {
|
|
1424
|
-
'data-slate-placeholder': true,
|
|
1425
|
-
style: {
|
|
1426
|
-
position: 'absolute',
|
|
1427
|
-
pointerEvents: 'none',
|
|
1428
|
-
width: '100%',
|
|
1429
|
-
maxWidth: '100%',
|
|
1430
|
-
display: 'block',
|
|
1431
|
-
opacity: '0.333',
|
|
1432
|
-
userSelect: 'none',
|
|
1433
|
-
textDecoration: 'none',
|
|
1434
|
-
// Fixes https://github.com/udecode/plate/issues/2315
|
|
1435
|
-
WebkitUserModify: IS_SAFARI ? 'inherit' : undefined
|
|
1436
|
-
},
|
|
1437
|
-
contentEditable: false,
|
|
1438
|
-
ref: callbackPlaceholderRef
|
|
1439
|
-
}
|
|
1288
|
+
if (Range.isCollapsed(range)) {
|
|
1289
|
+
return {
|
|
1290
|
+
anchor,
|
|
1291
|
+
focus: anchor
|
|
1440
1292
|
};
|
|
1441
|
-
children = /*#__PURE__*/React.createElement(React.Fragment, null, renderPlaceholder(placeholderProps), children);
|
|
1442
|
-
} // COMPAT: Having the `data-` attributes on these leaf elements ensures that
|
|
1443
|
-
// in certain misbehaving browsers they aren't weirdly cloned/destroyed by
|
|
1444
|
-
// contenteditable behaviors. (2019/05/08)
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
var attributes = {
|
|
1448
|
-
'data-slate-leaf': true
|
|
1449
|
-
};
|
|
1450
|
-
return renderLeaf({
|
|
1451
|
-
attributes,
|
|
1452
|
-
children,
|
|
1453
|
-
leaf,
|
|
1454
|
-
text
|
|
1455
|
-
});
|
|
1456
|
-
};
|
|
1457
|
-
|
|
1458
|
-
var MemoizedLeaf = /*#__PURE__*/React.memo(Leaf, (prev, next) => {
|
|
1459
|
-
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];
|
|
1460
|
-
});
|
|
1461
|
-
var DefaultLeaf = props => {
|
|
1462
|
-
var {
|
|
1463
|
-
attributes,
|
|
1464
|
-
children
|
|
1465
|
-
} = props;
|
|
1466
|
-
return /*#__PURE__*/React.createElement("span", Object.assign({}, attributes), children);
|
|
1467
|
-
};
|
|
1468
|
-
|
|
1469
|
-
/**
|
|
1470
|
-
* Text.
|
|
1471
|
-
*/
|
|
1472
|
-
|
|
1473
|
-
var Text = props => {
|
|
1474
|
-
var {
|
|
1475
|
-
decorations,
|
|
1476
|
-
isLast,
|
|
1477
|
-
parent,
|
|
1478
|
-
renderPlaceholder,
|
|
1479
|
-
renderLeaf,
|
|
1480
|
-
text
|
|
1481
|
-
} = props;
|
|
1482
|
-
var editor = useSlateStatic();
|
|
1483
|
-
var ref = useRef(null);
|
|
1484
|
-
var leaves = Text$1.decorations(text, decorations);
|
|
1485
|
-
var key = ReactEditor.findKey(editor, text);
|
|
1486
|
-
var children = [];
|
|
1487
|
-
|
|
1488
|
-
for (var i = 0; i < leaves.length; i++) {
|
|
1489
|
-
var leaf = leaves[i];
|
|
1490
|
-
children.push( /*#__PURE__*/React.createElement(MemoizedLeaf, {
|
|
1491
|
-
isLast: isLast && i === leaves.length - 1,
|
|
1492
|
-
key: "".concat(key.id, "-").concat(i),
|
|
1493
|
-
renderPlaceholder: renderPlaceholder,
|
|
1494
|
-
leaf: leaf,
|
|
1495
|
-
text: text,
|
|
1496
|
-
parent: parent,
|
|
1497
|
-
renderLeaf: renderLeaf
|
|
1498
|
-
}));
|
|
1499
|
-
} // Update element-related weak maps with the DOM element ref.
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
var callbackRef = useCallback(span => {
|
|
1503
|
-
var KEY_TO_ELEMENT = EDITOR_TO_KEY_TO_ELEMENT.get(editor);
|
|
1504
|
-
|
|
1505
|
-
if (span) {
|
|
1506
|
-
KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.set(key, span);
|
|
1507
|
-
NODE_TO_ELEMENT.set(text, span);
|
|
1508
|
-
ELEMENT_TO_NODE.set(span, text);
|
|
1509
|
-
} else {
|
|
1510
|
-
KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.delete(key);
|
|
1511
|
-
NODE_TO_ELEMENT.delete(text);
|
|
1512
|
-
|
|
1513
|
-
if (ref.current) {
|
|
1514
|
-
ELEMENT_TO_NODE.delete(ref.current);
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
ref.current = span;
|
|
1519
|
-
}, [ref, editor, key, text]);
|
|
1520
|
-
return /*#__PURE__*/React.createElement("span", {
|
|
1521
|
-
"data-slate-node": "text",
|
|
1522
|
-
ref: callbackRef
|
|
1523
|
-
}, children);
|
|
1524
|
-
};
|
|
1525
|
-
|
|
1526
|
-
var MemoizedText = /*#__PURE__*/React.memo(Text, (prev, next) => {
|
|
1527
|
-
return next.parent === prev.parent && next.isLast === prev.isLast && next.renderLeaf === prev.renderLeaf && next.renderPlaceholder === prev.renderPlaceholder && next.text === prev.text && isTextDecorationsEqual(next.decorations, prev.decorations);
|
|
1528
|
-
});
|
|
1529
|
-
|
|
1530
|
-
/**
|
|
1531
|
-
* Element.
|
|
1532
|
-
*/
|
|
1533
|
-
|
|
1534
|
-
var Element = props => {
|
|
1535
|
-
var {
|
|
1536
|
-
decorations,
|
|
1537
|
-
element,
|
|
1538
|
-
renderElement = p => /*#__PURE__*/React.createElement(DefaultElement, Object.assign({}, p)),
|
|
1539
|
-
renderPlaceholder,
|
|
1540
|
-
renderLeaf,
|
|
1541
|
-
selection
|
|
1542
|
-
} = props;
|
|
1543
|
-
var editor = useSlateStatic();
|
|
1544
|
-
var readOnly = useReadOnly();
|
|
1545
|
-
var isInline = editor.isInline(element);
|
|
1546
|
-
var key = ReactEditor.findKey(editor, element);
|
|
1547
|
-
var ref = useCallback(ref => {
|
|
1548
|
-
// Update element-related weak maps with the DOM element ref.
|
|
1549
|
-
var KEY_TO_ELEMENT = EDITOR_TO_KEY_TO_ELEMENT.get(editor);
|
|
1550
|
-
|
|
1551
|
-
if (ref) {
|
|
1552
|
-
KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.set(key, ref);
|
|
1553
|
-
NODE_TO_ELEMENT.set(element, ref);
|
|
1554
|
-
ELEMENT_TO_NODE.set(ref, element);
|
|
1555
|
-
} else {
|
|
1556
|
-
KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.delete(key);
|
|
1557
|
-
NODE_TO_ELEMENT.delete(element);
|
|
1558
|
-
}
|
|
1559
|
-
}, [editor, key, element]);
|
|
1560
|
-
var children = useChildren({
|
|
1561
|
-
decorations,
|
|
1562
|
-
node: element,
|
|
1563
|
-
renderElement,
|
|
1564
|
-
renderPlaceholder,
|
|
1565
|
-
renderLeaf,
|
|
1566
|
-
selection
|
|
1567
|
-
}); // Attributes that the developer must mix into the element in their
|
|
1568
|
-
// custom node renderer component.
|
|
1569
|
-
|
|
1570
|
-
var attributes = {
|
|
1571
|
-
'data-slate-node': 'element',
|
|
1572
|
-
ref
|
|
1573
|
-
};
|
|
1574
|
-
|
|
1575
|
-
if (isInline) {
|
|
1576
|
-
attributes['data-slate-inline'] = true;
|
|
1577
|
-
} // If it's a block node with inline children, add the proper `dir` attribute
|
|
1578
|
-
// for text direction.
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
if (!isInline && Editor.hasInlines(editor, element)) {
|
|
1582
|
-
var text = Node.string(element);
|
|
1583
|
-
var dir = getDirection(text);
|
|
1584
|
-
|
|
1585
|
-
if (dir === 'rtl') {
|
|
1586
|
-
attributes.dir = dir;
|
|
1587
|
-
}
|
|
1588
|
-
} // If it's a void node, wrap the children in extra void-specific elements.
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
if (Editor.isVoid(editor, element)) {
|
|
1592
|
-
attributes['data-slate-void'] = true;
|
|
1593
|
-
|
|
1594
|
-
if (!readOnly && isInline) {
|
|
1595
|
-
attributes.contentEditable = false;
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
var Tag = isInline ? 'span' : 'div';
|
|
1599
|
-
var [[_text]] = Node.texts(element);
|
|
1600
|
-
children = /*#__PURE__*/React.createElement(Tag, {
|
|
1601
|
-
"data-slate-spacer": true,
|
|
1602
|
-
style: {
|
|
1603
|
-
height: '0',
|
|
1604
|
-
color: 'transparent',
|
|
1605
|
-
outline: 'none',
|
|
1606
|
-
position: 'absolute'
|
|
1607
|
-
}
|
|
1608
|
-
}, /*#__PURE__*/React.createElement(MemoizedText, {
|
|
1609
|
-
renderPlaceholder: renderPlaceholder,
|
|
1610
|
-
decorations: [],
|
|
1611
|
-
isLast: false,
|
|
1612
|
-
parent: element,
|
|
1613
|
-
text: _text
|
|
1614
|
-
}));
|
|
1615
|
-
NODE_TO_INDEX.set(_text, 0);
|
|
1616
|
-
NODE_TO_PARENT.set(_text, element);
|
|
1617
1293
|
}
|
|
1618
1294
|
|
|
1619
|
-
|
|
1620
|
-
attributes,
|
|
1621
|
-
children,
|
|
1622
|
-
element
|
|
1623
|
-
});
|
|
1624
|
-
};
|
|
1625
|
-
|
|
1626
|
-
var MemoizedElement = /*#__PURE__*/React.memo(Element, (prev, next) => {
|
|
1627
|
-
return prev.element === next.element && prev.renderElement === next.renderElement && prev.renderLeaf === next.renderLeaf && prev.renderPlaceholder === next.renderPlaceholder && isElementDecorationsEqual(prev.decorations, next.decorations) && (prev.selection === next.selection || !!prev.selection && !!next.selection && Range.equals(prev.selection, next.selection));
|
|
1628
|
-
});
|
|
1629
|
-
/**
|
|
1630
|
-
* The default element renderer.
|
|
1631
|
-
*/
|
|
1632
|
-
|
|
1633
|
-
var DefaultElement = props => {
|
|
1634
|
-
var {
|
|
1635
|
-
attributes,
|
|
1636
|
-
children,
|
|
1637
|
-
element
|
|
1638
|
-
} = props;
|
|
1639
|
-
var editor = useSlateStatic();
|
|
1640
|
-
var Tag = editor.isInline(element) ? 'span' : 'div';
|
|
1641
|
-
return /*#__PURE__*/React.createElement(Tag, Object.assign({}, attributes, {
|
|
1642
|
-
style: {
|
|
1643
|
-
position: 'relative'
|
|
1644
|
-
}
|
|
1645
|
-
}), children);
|
|
1646
|
-
};
|
|
1647
|
-
|
|
1648
|
-
/**
|
|
1649
|
-
* A React context for sharing the `decorate` prop of the editable.
|
|
1650
|
-
*/
|
|
1651
|
-
|
|
1652
|
-
var DecorateContext = /*#__PURE__*/createContext(() => []);
|
|
1653
|
-
/**
|
|
1654
|
-
* Get the current `decorate` prop of the editable.
|
|
1655
|
-
*/
|
|
1656
|
-
|
|
1657
|
-
var useDecorate = () => {
|
|
1658
|
-
return useContext(DecorateContext);
|
|
1659
|
-
};
|
|
1660
|
-
|
|
1661
|
-
/**
|
|
1662
|
-
* A React context for sharing the `selected` state of an element.
|
|
1663
|
-
*/
|
|
1664
|
-
|
|
1665
|
-
var SelectedContext = /*#__PURE__*/createContext(false);
|
|
1666
|
-
/**
|
|
1667
|
-
* Get the current `selected` state of an element.
|
|
1668
|
-
*/
|
|
1669
|
-
|
|
1670
|
-
var useSelected = () => {
|
|
1671
|
-
return useContext(SelectedContext);
|
|
1672
|
-
};
|
|
1295
|
+
var focus = transformPendingPoint(editor, range.focus, op);
|
|
1673
1296
|
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1297
|
+
if (!focus) {
|
|
1298
|
+
return null;
|
|
1299
|
+
}
|
|
1677
1300
|
|
|
1678
|
-
|
|
1301
|
+
return {
|
|
1302
|
+
anchor,
|
|
1303
|
+
focus
|
|
1304
|
+
};
|
|
1305
|
+
}
|
|
1306
|
+
function transformTextDiff(textDiff, op) {
|
|
1679
1307
|
var {
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
renderLeaf,
|
|
1685
|
-
selection
|
|
1686
|
-
} = props;
|
|
1687
|
-
var decorate = useDecorate();
|
|
1688
|
-
var editor = useSlateStatic();
|
|
1689
|
-
var path = ReactEditor.findPath(editor, node);
|
|
1690
|
-
var children = [];
|
|
1691
|
-
var isLeafBlock = Element$1.isElement(node) && !editor.isInline(node) && Editor.hasInlines(editor, node);
|
|
1308
|
+
path,
|
|
1309
|
+
diff,
|
|
1310
|
+
id
|
|
1311
|
+
} = textDiff;
|
|
1692
1312
|
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
var ds = decorate([n, p]);
|
|
1313
|
+
switch (op.type) {
|
|
1314
|
+
case 'insert_text':
|
|
1315
|
+
{
|
|
1316
|
+
if (!Path.equals(op.path, path) || op.offset >= diff.end) {
|
|
1317
|
+
return textDiff;
|
|
1318
|
+
}
|
|
1700
1319
|
|
|
1701
|
-
|
|
1702
|
-
|
|
1320
|
+
if (op.offset <= diff.start) {
|
|
1321
|
+
return {
|
|
1322
|
+
diff: {
|
|
1323
|
+
start: op.text.length + diff.start,
|
|
1324
|
+
end: op.text.length + diff.end,
|
|
1325
|
+
text: diff.text
|
|
1326
|
+
},
|
|
1327
|
+
id,
|
|
1328
|
+
path
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1703
1331
|
|
|
1704
|
-
|
|
1705
|
-
|
|
1332
|
+
return {
|
|
1333
|
+
diff: {
|
|
1334
|
+
start: diff.start,
|
|
1335
|
+
end: diff.end + op.text.length,
|
|
1336
|
+
text: diff.text
|
|
1337
|
+
},
|
|
1338
|
+
id,
|
|
1339
|
+
path
|
|
1340
|
+
};
|
|
1706
1341
|
}
|
|
1707
|
-
}
|
|
1708
|
-
|
|
1709
|
-
if (Element$1.isElement(n)) {
|
|
1710
|
-
children.push( /*#__PURE__*/React.createElement(SelectedContext.Provider, {
|
|
1711
|
-
key: "provider-".concat(key.id),
|
|
1712
|
-
value: !!sel
|
|
1713
|
-
}, /*#__PURE__*/React.createElement(MemoizedElement, {
|
|
1714
|
-
decorations: ds,
|
|
1715
|
-
element: n,
|
|
1716
|
-
key: key.id,
|
|
1717
|
-
renderElement: renderElement,
|
|
1718
|
-
renderPlaceholder: renderPlaceholder,
|
|
1719
|
-
renderLeaf: renderLeaf,
|
|
1720
|
-
selection: sel
|
|
1721
|
-
})));
|
|
1722
|
-
} else {
|
|
1723
|
-
children.push( /*#__PURE__*/React.createElement(MemoizedText, {
|
|
1724
|
-
decorations: ds,
|
|
1725
|
-
key: key.id,
|
|
1726
|
-
isLast: isLeafBlock && i === node.children.length - 1,
|
|
1727
|
-
parent: node,
|
|
1728
|
-
renderPlaceholder: renderPlaceholder,
|
|
1729
|
-
renderLeaf: renderLeaf,
|
|
1730
|
-
text: n
|
|
1731
|
-
}));
|
|
1732
|
-
}
|
|
1733
|
-
|
|
1734
|
-
NODE_TO_INDEX.set(n, i);
|
|
1735
|
-
NODE_TO_PARENT.set(n, node);
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
|
-
return children;
|
|
1739
|
-
};
|
|
1740
1342
|
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1343
|
+
case 'remove_text':
|
|
1344
|
+
{
|
|
1345
|
+
if (!Path.equals(op.path, path) || op.offset >= diff.end) {
|
|
1346
|
+
return textDiff;
|
|
1347
|
+
}
|
|
1744
1348
|
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1349
|
+
if (op.offset + op.text.length <= diff.start) {
|
|
1350
|
+
return {
|
|
1351
|
+
diff: {
|
|
1352
|
+
start: diff.start - op.text.length,
|
|
1353
|
+
end: diff.end - op.text.length,
|
|
1354
|
+
text: diff.text
|
|
1355
|
+
},
|
|
1356
|
+
id,
|
|
1357
|
+
path
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1749
1360
|
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1361
|
+
return {
|
|
1362
|
+
diff: {
|
|
1363
|
+
start: diff.start,
|
|
1364
|
+
end: diff.end - op.text.length,
|
|
1365
|
+
text: diff.text
|
|
1366
|
+
},
|
|
1367
|
+
id,
|
|
1368
|
+
path
|
|
1369
|
+
};
|
|
1370
|
+
}
|
|
1753
1371
|
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1372
|
+
case 'split_node':
|
|
1373
|
+
{
|
|
1374
|
+
if (!Path.equals(op.path, path) || op.position >= diff.end) {
|
|
1375
|
+
return {
|
|
1376
|
+
diff,
|
|
1377
|
+
id,
|
|
1378
|
+
path: Path.transform(path, op, {
|
|
1379
|
+
affinity: 'backward'
|
|
1380
|
+
})
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1758
1383
|
|
|
1759
|
-
|
|
1760
|
-
|
|
1384
|
+
if (op.position > diff.start) {
|
|
1385
|
+
return {
|
|
1386
|
+
diff: {
|
|
1387
|
+
start: diff.start,
|
|
1388
|
+
end: Math.min(op.position, diff.end),
|
|
1389
|
+
text: diff.text
|
|
1390
|
+
},
|
|
1391
|
+
id,
|
|
1392
|
+
path
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1761
1395
|
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1396
|
+
return {
|
|
1397
|
+
diff: {
|
|
1398
|
+
start: diff.start - op.position,
|
|
1399
|
+
end: diff.end - op.position,
|
|
1400
|
+
text: diff.text
|
|
1401
|
+
},
|
|
1402
|
+
id,
|
|
1403
|
+
path: Path.transform(path, op, {
|
|
1404
|
+
affinity: 'forward'
|
|
1405
|
+
})
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1765
1408
|
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1409
|
+
case 'merge_node':
|
|
1410
|
+
{
|
|
1411
|
+
if (!Path.equals(op.path, path)) {
|
|
1412
|
+
return {
|
|
1413
|
+
diff,
|
|
1414
|
+
id,
|
|
1415
|
+
path: Path.transform(path, op)
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1773
1418
|
|
|
1774
|
-
|
|
1775
|
-
|
|
1419
|
+
return {
|
|
1420
|
+
diff: {
|
|
1421
|
+
start: diff.start + op.position,
|
|
1422
|
+
end: diff.end + op.position,
|
|
1423
|
+
text: diff.text
|
|
1424
|
+
},
|
|
1425
|
+
id,
|
|
1426
|
+
path: Path.transform(path, op)
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1776
1429
|
}
|
|
1777
1430
|
|
|
1778
|
-
|
|
1779
|
-
};
|
|
1780
|
-
|
|
1781
|
-
var TRIPLE_CLICK = 3;
|
|
1782
|
-
|
|
1783
|
-
/**
|
|
1784
|
-
* Hotkey mappings for each platform.
|
|
1785
|
-
*/
|
|
1786
|
-
|
|
1787
|
-
var HOTKEYS = {
|
|
1788
|
-
bold: 'mod+b',
|
|
1789
|
-
compose: ['down', 'left', 'right', 'up', 'backspace', 'enter'],
|
|
1790
|
-
moveBackward: 'left',
|
|
1791
|
-
moveForward: 'right',
|
|
1792
|
-
moveWordBackward: 'ctrl+left',
|
|
1793
|
-
moveWordForward: 'ctrl+right',
|
|
1794
|
-
deleteBackward: 'shift?+backspace',
|
|
1795
|
-
deleteForward: 'shift?+delete',
|
|
1796
|
-
extendBackward: 'shift+left',
|
|
1797
|
-
extendForward: 'shift+right',
|
|
1798
|
-
italic: 'mod+i',
|
|
1799
|
-
insertSoftBreak: 'shift+enter',
|
|
1800
|
-
splitBlock: 'enter',
|
|
1801
|
-
undo: 'mod+z'
|
|
1802
|
-
};
|
|
1803
|
-
var APPLE_HOTKEYS = {
|
|
1804
|
-
moveLineBackward: 'opt+up',
|
|
1805
|
-
moveLineForward: 'opt+down',
|
|
1806
|
-
moveWordBackward: 'opt+left',
|
|
1807
|
-
moveWordForward: 'opt+right',
|
|
1808
|
-
deleteBackward: ['ctrl+backspace', 'ctrl+h'],
|
|
1809
|
-
deleteForward: ['ctrl+delete', 'ctrl+d'],
|
|
1810
|
-
deleteLineBackward: 'cmd+shift?+backspace',
|
|
1811
|
-
deleteLineForward: ['cmd+shift?+delete', 'ctrl+k'],
|
|
1812
|
-
deleteWordBackward: 'opt+shift?+backspace',
|
|
1813
|
-
deleteWordForward: 'opt+shift?+delete',
|
|
1814
|
-
extendLineBackward: 'opt+shift+up',
|
|
1815
|
-
extendLineForward: 'opt+shift+down',
|
|
1816
|
-
redo: 'cmd+shift+z',
|
|
1817
|
-
transposeCharacter: 'ctrl+t'
|
|
1818
|
-
};
|
|
1819
|
-
var WINDOWS_HOTKEYS = {
|
|
1820
|
-
deleteWordBackward: 'ctrl+shift?+backspace',
|
|
1821
|
-
deleteWordForward: 'ctrl+shift?+delete',
|
|
1822
|
-
redo: ['ctrl+y', 'ctrl+shift+z']
|
|
1823
|
-
};
|
|
1824
|
-
/**
|
|
1825
|
-
* Create a platform-aware hotkey checker.
|
|
1826
|
-
*/
|
|
1431
|
+
var newPath = Path.transform(path, op);
|
|
1827
1432
|
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
if (isGeneric && isGeneric(event)) return true;
|
|
1837
|
-
if (IS_APPLE && isApple && isApple(event)) return true;
|
|
1838
|
-
if (!IS_APPLE && isWindows && isWindows(event)) return true;
|
|
1839
|
-
return false;
|
|
1433
|
+
if (!newPath) {
|
|
1434
|
+
return null;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
return {
|
|
1438
|
+
diff,
|
|
1439
|
+
path: newPath,
|
|
1440
|
+
id
|
|
1840
1441
|
};
|
|
1841
|
-
}
|
|
1842
|
-
/**
|
|
1843
|
-
* Hotkeys.
|
|
1844
|
-
*/
|
|
1442
|
+
}
|
|
1845
1443
|
|
|
1444
|
+
function ownKeys$3(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; }
|
|
1846
1445
|
|
|
1847
|
-
var
|
|
1848
|
-
|
|
1849
|
-
isCompose: create('compose'),
|
|
1850
|
-
isMoveBackward: create('moveBackward'),
|
|
1851
|
-
isMoveForward: create('moveForward'),
|
|
1852
|
-
isDeleteBackward: create('deleteBackward'),
|
|
1853
|
-
isDeleteForward: create('deleteForward'),
|
|
1854
|
-
isDeleteLineBackward: create('deleteLineBackward'),
|
|
1855
|
-
isDeleteLineForward: create('deleteLineForward'),
|
|
1856
|
-
isDeleteWordBackward: create('deleteWordBackward'),
|
|
1857
|
-
isDeleteWordForward: create('deleteWordForward'),
|
|
1858
|
-
isExtendBackward: create('extendBackward'),
|
|
1859
|
-
isExtendForward: create('extendForward'),
|
|
1860
|
-
isExtendLineBackward: create('extendLineBackward'),
|
|
1861
|
-
isExtendLineForward: create('extendLineForward'),
|
|
1862
|
-
isItalic: create('italic'),
|
|
1863
|
-
isMoveLineBackward: create('moveLineBackward'),
|
|
1864
|
-
isMoveLineForward: create('moveLineForward'),
|
|
1865
|
-
isMoveWordBackward: create('moveWordBackward'),
|
|
1866
|
-
isMoveWordForward: create('moveWordForward'),
|
|
1867
|
-
isRedo: create('redo'),
|
|
1868
|
-
isSoftBreak: create('insertSoftBreak'),
|
|
1869
|
-
isSplitBlock: create('splitBlock'),
|
|
1870
|
-
isTransposeCharacter: create('transposeCharacter'),
|
|
1871
|
-
isUndo: create('undo')
|
|
1872
|
-
};
|
|
1446
|
+
function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$3(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
1447
|
+
// When using keyboard English association function, conpositionEnd triggered too fast, resulting in after `insertText` still maintain association state.
|
|
1873
1448
|
|
|
1874
|
-
var
|
|
1875
|
-
var bufferedMutations = [];
|
|
1449
|
+
var RESOLVE_DELAY = 25; // Time with no user interaction before the current user action is considered as done.
|
|
1876
1450
|
|
|
1877
|
-
|
|
1878
|
-
|
|
1451
|
+
var FLUSH_DELAY = 200; // Replace with `const debug = console.log` to debug
|
|
1452
|
+
|
|
1453
|
+
var debug = function debug() {}; // Type guard to check if a value is a DataTransfer
|
|
1454
|
+
|
|
1455
|
+
|
|
1456
|
+
var isDataTransfer = value => (value === null || value === void 0 ? void 0 : value.constructor.name) === 'DataTransfer';
|
|
1457
|
+
|
|
1458
|
+
function createAndroidInputManager(_ref) {
|
|
1459
|
+
var {
|
|
1460
|
+
editor,
|
|
1461
|
+
scheduleOnDOMSelectionChange,
|
|
1462
|
+
onDOMSelectionChange
|
|
1463
|
+
} = _ref;
|
|
1464
|
+
var flushing = false;
|
|
1465
|
+
var compositionEndTimeoutId = null;
|
|
1466
|
+
var flushTimeoutId = null;
|
|
1467
|
+
var actionTimeoutId = null;
|
|
1468
|
+
var idCounter = 0;
|
|
1469
|
+
var insertPositionHint = false;
|
|
1470
|
+
|
|
1471
|
+
var applyPendingSelection = () => {
|
|
1472
|
+
var pendingSelection = EDITOR_TO_PENDING_SELECTION.get(editor);
|
|
1473
|
+
EDITOR_TO_PENDING_SELECTION.delete(editor);
|
|
1474
|
+
|
|
1475
|
+
if (pendingSelection) {
|
|
1476
|
+
var {
|
|
1477
|
+
selection
|
|
1478
|
+
} = editor;
|
|
1479
|
+
var normalized = normalizeRange(editor, pendingSelection);
|
|
1480
|
+
|
|
1481
|
+
if (normalized && (!selection || !Range.equals(normalized, selection))) {
|
|
1482
|
+
Transforms.select(editor, normalized);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1879
1485
|
};
|
|
1880
1486
|
|
|
1881
|
-
var
|
|
1882
|
-
|
|
1487
|
+
var performAction = () => {
|
|
1488
|
+
var action = EDITOR_TO_PENDING_ACTION.get(editor);
|
|
1489
|
+
EDITOR_TO_PENDING_ACTION.delete(editor);
|
|
1490
|
+
|
|
1491
|
+
if (!action) {
|
|
1883
1492
|
return;
|
|
1884
1493
|
}
|
|
1885
1494
|
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
};
|
|
1495
|
+
if (action.at) {
|
|
1496
|
+
var target = Point.isPoint(action.at) ? normalizePoint(editor, action.at) : normalizeRange(editor, action.at);
|
|
1889
1497
|
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
if (mutation.type === 'characterData') {
|
|
1894
|
-
// We don't want to restore the DOM for characterData mutations
|
|
1895
|
-
// because this interrupts the composition.
|
|
1896
|
-
return;
|
|
1897
|
-
}
|
|
1498
|
+
if (!target) {
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1898
1501
|
|
|
1899
|
-
|
|
1900
|
-
mutation.target.insertBefore(node, mutation.nextSibling);
|
|
1901
|
-
});
|
|
1902
|
-
mutation.addedNodes.forEach(node => {
|
|
1903
|
-
mutation.target.removeChild(node);
|
|
1904
|
-
});
|
|
1905
|
-
}); // Clear buffered mutations to ensure we don't undo them twice
|
|
1502
|
+
var _targetRange = Editor.range(editor, target);
|
|
1906
1503
|
|
|
1907
|
-
|
|
1504
|
+
if (!editor.selection || !Range.equals(editor.selection, _targetRange)) {
|
|
1505
|
+
Transforms.select(editor, target);
|
|
1506
|
+
}
|
|
1908
1507
|
}
|
|
1909
|
-
}
|
|
1910
1508
|
|
|
1911
|
-
|
|
1912
|
-
registerMutations,
|
|
1913
|
-
restoreDOM,
|
|
1914
|
-
clear
|
|
1509
|
+
action.run();
|
|
1915
1510
|
};
|
|
1916
|
-
};
|
|
1917
1511
|
|
|
1918
|
-
var
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
}; // We have to use a class component here since we rely on `getSnapshotBeforeUpdate` which has no FC equivalent
|
|
1924
|
-
// to run code synchronously immediately before react commits the component update to the DOM.
|
|
1512
|
+
var flush = () => {
|
|
1513
|
+
if (flushTimeoutId) {
|
|
1514
|
+
clearTimeout(flushTimeoutId);
|
|
1515
|
+
flushTimeoutId = null;
|
|
1516
|
+
}
|
|
1925
1517
|
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
this.manager = null;
|
|
1931
|
-
this.mutationObserver = null;
|
|
1932
|
-
}
|
|
1518
|
+
if (actionTimeoutId) {
|
|
1519
|
+
clearTimeout(actionTimeoutId);
|
|
1520
|
+
actionTimeoutId = null;
|
|
1521
|
+
}
|
|
1933
1522
|
|
|
1934
|
-
|
|
1935
|
-
|
|
1523
|
+
if (!hasPendingDiffs() && !hasPendingAction()) {
|
|
1524
|
+
applyPendingSelection();
|
|
1525
|
+
return;
|
|
1526
|
+
}
|
|
1936
1527
|
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1528
|
+
if (!flushing) {
|
|
1529
|
+
flushing = true;
|
|
1530
|
+
setTimeout(() => flushing = false);
|
|
1531
|
+
}
|
|
1940
1532
|
|
|
1941
|
-
if (
|
|
1942
|
-
|
|
1533
|
+
if (hasPendingAction()) {
|
|
1534
|
+
flushing = 'action';
|
|
1943
1535
|
}
|
|
1944
1536
|
|
|
1945
|
-
|
|
1946
|
-
|
|
1537
|
+
var selectionRef = editor.selection && Editor.rangeRef(editor, editor.selection, {
|
|
1538
|
+
affinity: 'forward'
|
|
1539
|
+
});
|
|
1540
|
+
EDITOR_TO_USER_MARKS.set(editor, editor.marks);
|
|
1541
|
+
debug('flush', EDITOR_TO_PENDING_ACTION.get(editor), EDITOR_TO_PENDING_DIFFS.get(editor));
|
|
1542
|
+
var scheduleSelectionChange = hasPendingDiffs();
|
|
1543
|
+
var diff;
|
|
1947
1544
|
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
receivedUserInput
|
|
1951
|
-
} = this.props;
|
|
1952
|
-
var editor = this.context;
|
|
1953
|
-
this.manager = createRestoreDomManager(editor, receivedUserInput);
|
|
1954
|
-
this.mutationObserver = new MutationObserver(this.manager.registerMutations);
|
|
1955
|
-
this.observe();
|
|
1956
|
-
}
|
|
1545
|
+
while (diff = (_EDITOR_TO_PENDING_DI = EDITOR_TO_PENDING_DIFFS.get(editor)) === null || _EDITOR_TO_PENDING_DI === void 0 ? void 0 : _EDITOR_TO_PENDING_DI[0]) {
|
|
1546
|
+
var _EDITOR_TO_PENDING_DI, _EDITOR_TO_PENDING_DI2;
|
|
1957
1547
|
|
|
1958
|
-
|
|
1959
|
-
var _this$mutationObserve2, _this$mutationObserve3, _this$manager2;
|
|
1548
|
+
var pendingMarks = EDITOR_TO_PENDING_INSERTION_MARKS.get(editor);
|
|
1960
1549
|
|
|
1961
|
-
|
|
1550
|
+
if (pendingMarks !== undefined) {
|
|
1551
|
+
EDITOR_TO_PENDING_INSERTION_MARKS.delete(editor);
|
|
1552
|
+
editor.marks = pendingMarks;
|
|
1553
|
+
}
|
|
1962
1554
|
|
|
1963
|
-
|
|
1964
|
-
|
|
1555
|
+
if (pendingMarks && insertPositionHint === false) {
|
|
1556
|
+
insertPositionHint = null;
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
var range = targetRange(diff);
|
|
1560
|
+
|
|
1561
|
+
if (!editor.selection || !Range.equals(editor.selection, range)) {
|
|
1562
|
+
Transforms.select(editor, range);
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
if (diff.diff.text) {
|
|
1566
|
+
Editor.insertText(editor, diff.diff.text);
|
|
1567
|
+
} else {
|
|
1568
|
+
Editor.deleteFragment(editor);
|
|
1569
|
+
} // Remove diff only after we have applied it to account for it when transforming
|
|
1570
|
+
// pending ranges.
|
|
1571
|
+
|
|
1572
|
+
|
|
1573
|
+
EDITOR_TO_PENDING_DIFFS.set(editor, (_EDITOR_TO_PENDING_DI2 = EDITOR_TO_PENDING_DIFFS.get(editor)) === null || _EDITOR_TO_PENDING_DI2 === void 0 ? void 0 : _EDITOR_TO_PENDING_DI2.filter(_ref2 => {
|
|
1574
|
+
var {
|
|
1575
|
+
id
|
|
1576
|
+
} = _ref2;
|
|
1577
|
+
return id !== diff.id;
|
|
1578
|
+
}));
|
|
1579
|
+
|
|
1580
|
+
if (!verifyDiffState(editor, diff)) {
|
|
1581
|
+
scheduleSelectionChange = false;
|
|
1582
|
+
EDITOR_TO_PENDING_ACTION.delete(editor);
|
|
1583
|
+
EDITOR_TO_USER_MARKS.delete(editor);
|
|
1584
|
+
flushing = 'action'; // Ensure we don't restore the pending user (dom) selection
|
|
1585
|
+
// since the document and dom state do not match.
|
|
1586
|
+
|
|
1587
|
+
EDITOR_TO_PENDING_SELECTION.delete(editor);
|
|
1588
|
+
scheduleOnDOMSelectionChange.cancel();
|
|
1589
|
+
onDOMSelectionChange.cancel();
|
|
1590
|
+
selectionRef === null || selectionRef === void 0 ? void 0 : selectionRef.unref();
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
var selection = selectionRef === null || selectionRef === void 0 ? void 0 : selectionRef.unref();
|
|
1595
|
+
|
|
1596
|
+
if (selection && !EDITOR_TO_PENDING_SELECTION.get(editor) && (!editor.selection || !Range.equals(selection, editor.selection))) {
|
|
1597
|
+
Transforms.select(editor, selection);
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
if (hasPendingAction()) {
|
|
1601
|
+
performAction();
|
|
1602
|
+
return;
|
|
1603
|
+
} // COMPAT: The selectionChange event is fired after the action is performed,
|
|
1604
|
+
// so we have to manually schedule it to ensure we don't 'throw away' the selection
|
|
1605
|
+
// while rendering if we have pending changes.
|
|
1965
1606
|
|
|
1966
|
-
(_this$manager = this.manager) === null || _this$manager === void 0 ? void 0 : _this$manager.registerMutations(pendingMutations);
|
|
1967
|
-
}
|
|
1968
1607
|
|
|
1969
|
-
(
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
}
|
|
1608
|
+
if (scheduleSelectionChange) {
|
|
1609
|
+
scheduleOnDOMSelectionChange();
|
|
1610
|
+
}
|
|
1973
1611
|
|
|
1974
|
-
|
|
1975
|
-
|
|
1612
|
+
scheduleOnDOMSelectionChange.flush();
|
|
1613
|
+
onDOMSelectionChange.flush();
|
|
1614
|
+
applyPendingSelection();
|
|
1615
|
+
var userMarks = EDITOR_TO_USER_MARKS.get(editor);
|
|
1616
|
+
EDITOR_TO_USER_MARKS.delete(editor);
|
|
1976
1617
|
|
|
1977
|
-
(
|
|
1978
|
-
|
|
1979
|
-
|
|
1618
|
+
if (userMarks !== undefined) {
|
|
1619
|
+
editor.marks = userMarks;
|
|
1620
|
+
editor.onChange();
|
|
1621
|
+
}
|
|
1622
|
+
};
|
|
1980
1623
|
|
|
1981
|
-
|
|
1982
|
-
|
|
1624
|
+
var handleCompositionEnd = _event => {
|
|
1625
|
+
if (compositionEndTimeoutId) {
|
|
1626
|
+
clearTimeout(compositionEndTimeoutId);
|
|
1627
|
+
}
|
|
1983
1628
|
|
|
1984
|
-
|
|
1985
|
-
|
|
1629
|
+
compositionEndTimeoutId = setTimeout(() => {
|
|
1630
|
+
IS_COMPOSING.set(editor, false);
|
|
1631
|
+
flush();
|
|
1632
|
+
}, RESOLVE_DELAY);
|
|
1633
|
+
};
|
|
1986
1634
|
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
}
|
|
1635
|
+
var handleCompositionStart = _event => {
|
|
1636
|
+
IS_COMPOSING.set(editor, true);
|
|
1990
1637
|
|
|
1991
|
-
|
|
1638
|
+
if (compositionEndTimeoutId) {
|
|
1639
|
+
clearTimeout(compositionEndTimeoutId);
|
|
1640
|
+
compositionEndTimeoutId = null;
|
|
1641
|
+
}
|
|
1642
|
+
};
|
|
1992
1643
|
|
|
1993
|
-
|
|
1994
|
-
var
|
|
1995
|
-
|
|
1996
|
-
children
|
|
1997
|
-
} = _ref;
|
|
1998
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, children);
|
|
1999
|
-
};
|
|
1644
|
+
var updatePlaceholderVisibility = function updatePlaceholderVisibility() {
|
|
1645
|
+
var forceHide = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
1646
|
+
var placeholderElement = EDITOR_TO_PLACEHOLDER_ELEMENT.get(editor);
|
|
2000
1647
|
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
*/
|
|
1648
|
+
if (!placeholderElement) {
|
|
1649
|
+
return;
|
|
1650
|
+
}
|
|
2005
1651
|
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
} = textDiff;
|
|
1652
|
+
if (hasPendingDiffs() || forceHide) {
|
|
1653
|
+
placeholderElement.style.display = 'none';
|
|
1654
|
+
return;
|
|
1655
|
+
}
|
|
2011
1656
|
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
}
|
|
1657
|
+
placeholderElement.style.removeProperty('display');
|
|
1658
|
+
};
|
|
2015
1659
|
|
|
2016
|
-
var
|
|
1660
|
+
var storeDiff = (path, diff) => {
|
|
1661
|
+
var _EDITOR_TO_PENDING_DI3;
|
|
1662
|
+
var pendingDiffs = (_EDITOR_TO_PENDING_DI3 = EDITOR_TO_PENDING_DIFFS.get(editor)) !== null && _EDITOR_TO_PENDING_DI3 !== void 0 ? _EDITOR_TO_PENDING_DI3 : [];
|
|
1663
|
+
EDITOR_TO_PENDING_DIFFS.set(editor, pendingDiffs);
|
|
1664
|
+
var target = Node.leaf(editor, path);
|
|
1665
|
+
var idx = pendingDiffs.findIndex(change => Path.equals(change.path, path));
|
|
2017
1666
|
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
}
|
|
1667
|
+
if (idx < 0) {
|
|
1668
|
+
var normalized = normalizeStringDiff(target.text, diff);
|
|
2021
1669
|
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
1670
|
+
if (normalized) {
|
|
1671
|
+
pendingDiffs.push({
|
|
1672
|
+
path,
|
|
1673
|
+
diff,
|
|
1674
|
+
id: idCounter++
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
2025
1677
|
|
|
2026
|
-
|
|
1678
|
+
updatePlaceholderVisibility();
|
|
1679
|
+
return;
|
|
1680
|
+
}
|
|
2027
1681
|
|
|
2028
|
-
|
|
2029
|
-
return false;
|
|
2030
|
-
}
|
|
1682
|
+
var merged = mergeStringDiffs(target.text, pendingDiffs[idx].diff, diff);
|
|
2031
1683
|
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
diffs[_key - 1] = arguments[_key];
|
|
2038
|
-
}
|
|
1684
|
+
if (!merged) {
|
|
1685
|
+
pendingDiffs.splice(idx, 1);
|
|
1686
|
+
updatePlaceholderVisibility();
|
|
1687
|
+
return;
|
|
1688
|
+
}
|
|
2039
1689
|
|
|
2040
|
-
|
|
2041
|
-
|
|
1690
|
+
pendingDiffs[idx] = _objectSpread$3(_objectSpread$3({}, pendingDiffs[idx]), {}, {
|
|
1691
|
+
diff: merged
|
|
1692
|
+
});
|
|
1693
|
+
};
|
|
2042
1694
|
|
|
2043
|
-
function
|
|
2044
|
-
|
|
1695
|
+
var scheduleAction = function scheduleAction(run) {
|
|
1696
|
+
var {
|
|
1697
|
+
at
|
|
1698
|
+
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1699
|
+
insertPositionHint = false;
|
|
1700
|
+
EDITOR_TO_PENDING_SELECTION.delete(editor);
|
|
1701
|
+
scheduleOnDOMSelectionChange.cancel();
|
|
1702
|
+
onDOMSelectionChange.cancel();
|
|
2045
1703
|
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
return i;
|
|
1704
|
+
if (hasPendingAction()) {
|
|
1705
|
+
flush();
|
|
2049
1706
|
}
|
|
2050
|
-
}
|
|
2051
1707
|
|
|
2052
|
-
|
|
2053
|
-
|
|
1708
|
+
EDITOR_TO_PENDING_ACTION.set(editor, {
|
|
1709
|
+
at,
|
|
1710
|
+
run
|
|
1711
|
+
}); // COMPAT: When deleting before a non-contenteditable element chrome only fires a beforeinput,
|
|
1712
|
+
// (no input) and doesn't perform any dom mutations. Without a flush timeout we would never flush
|
|
1713
|
+
// in this case and thus never actually perform the action.
|
|
2054
1714
|
|
|
2055
|
-
|
|
2056
|
-
|
|
1715
|
+
actionTimeoutId = setTimeout(flush);
|
|
1716
|
+
};
|
|
2057
1717
|
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
1718
|
+
var handleDOMBeforeInput = event => {
|
|
1719
|
+
var _targetRange2;
|
|
1720
|
+
|
|
1721
|
+
if (flushTimeoutId) {
|
|
1722
|
+
clearTimeout(flushTimeoutId);
|
|
1723
|
+
flushTimeoutId = null;
|
|
2061
1724
|
}
|
|
2062
|
-
}
|
|
2063
1725
|
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
1726
|
+
var {
|
|
1727
|
+
inputType: type
|
|
1728
|
+
} = event;
|
|
1729
|
+
var targetRange = null;
|
|
1730
|
+
var data = event.dataTransfer || event.data || undefined;
|
|
2069
1731
|
|
|
1732
|
+
if (insertPositionHint !== false && type !== 'insertText' && type !== 'insertCompositionText') {
|
|
1733
|
+
insertPositionHint = false;
|
|
1734
|
+
}
|
|
2070
1735
|
|
|
2071
|
-
|
|
2072
|
-
var {
|
|
2073
|
-
start,
|
|
2074
|
-
end,
|
|
2075
|
-
text
|
|
2076
|
-
} = diff;
|
|
2077
|
-
var removedText = targetText.slice(start, end);
|
|
2078
|
-
var prefixLength = longestCommonPrefixLength(removedText, text);
|
|
2079
|
-
var max = Math.min(removedText.length - prefixLength, text.length - prefixLength);
|
|
2080
|
-
var suffixLength = longestCommonSuffixLength(removedText, text, max);
|
|
2081
|
-
var normalized = {
|
|
2082
|
-
start: start + prefixLength,
|
|
2083
|
-
end: end - suffixLength,
|
|
2084
|
-
text: text.slice(prefixLength, text.length - suffixLength)
|
|
2085
|
-
};
|
|
1736
|
+
var [nativeTargetRange] = event.getTargetRanges();
|
|
2086
1737
|
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
1738
|
+
if (nativeTargetRange) {
|
|
1739
|
+
targetRange = ReactEditor.toSlateRange(editor, nativeTargetRange, {
|
|
1740
|
+
exactMatch: false,
|
|
1741
|
+
suppressThrow: true
|
|
1742
|
+
});
|
|
1743
|
+
} // COMPAT: SelectionChange event is fired after the action is performed, so we
|
|
1744
|
+
// have to manually get the selection here to ensure it's up-to-date.
|
|
2090
1745
|
|
|
2091
|
-
return normalized;
|
|
2092
|
-
}
|
|
2093
|
-
/**
|
|
2094
|
-
* Return a string diff that is equivalent to applying b after a spanning the range of
|
|
2095
|
-
* both changes
|
|
2096
|
-
*/
|
|
2097
1746
|
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
var overlap = Math.max(0, Math.min(a.start + a.text.length, b.end) - b.start);
|
|
2101
|
-
var applied = applyStringDiff(targetText, a, b);
|
|
2102
|
-
var sliceEnd = Math.max(b.start + b.text.length, a.start + a.text.length + (a.start + a.text.length > b.start ? b.text.length : 0) - overlap);
|
|
2103
|
-
var text = applied.slice(start, sliceEnd);
|
|
2104
|
-
var end = Math.max(a.end, b.end - a.text.length + (a.end - a.start));
|
|
2105
|
-
return normalizeStringDiff(targetText, {
|
|
2106
|
-
start,
|
|
2107
|
-
end,
|
|
2108
|
-
text
|
|
2109
|
-
});
|
|
2110
|
-
}
|
|
2111
|
-
/**
|
|
2112
|
-
* Get the slate range the text diff spans.
|
|
2113
|
-
*/
|
|
1747
|
+
var window = ReactEditor.getWindow(editor);
|
|
1748
|
+
var domSelection = window.getSelection();
|
|
2114
1749
|
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
anchor: {
|
|
2122
|
-
path,
|
|
2123
|
-
offset: diff.start
|
|
2124
|
-
},
|
|
2125
|
-
focus: {
|
|
2126
|
-
path,
|
|
2127
|
-
offset: diff.end
|
|
1750
|
+
if (!targetRange && domSelection) {
|
|
1751
|
+
nativeTargetRange = domSelection;
|
|
1752
|
+
targetRange = ReactEditor.toSlateRange(editor, domSelection, {
|
|
1753
|
+
exactMatch: false,
|
|
1754
|
+
suppressThrow: true
|
|
1755
|
+
});
|
|
2128
1756
|
}
|
|
2129
|
-
};
|
|
2130
|
-
}
|
|
2131
|
-
/**
|
|
2132
|
-
* Normalize a 'pending point' a.k.a a point based on the dom state before applying
|
|
2133
|
-
* the pending diffs. Since the pending diffs might have been inserted with different
|
|
2134
|
-
* marks we have to 'walk' the offset from the starting position to ensure we still
|
|
2135
|
-
* have a valid point inside the document
|
|
2136
|
-
*/
|
|
2137
1757
|
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
1758
|
+
targetRange = (_targetRange2 = targetRange) !== null && _targetRange2 !== void 0 ? _targetRange2 : editor.selection;
|
|
1759
|
+
|
|
1760
|
+
if (!targetRange) {
|
|
1761
|
+
return;
|
|
1762
|
+
} // By default, the input manager tries to store text diffs so that we can
|
|
1763
|
+
// defer flushing them at a later point in time. We don't want to flush
|
|
1764
|
+
// for every input event as this can be expensive. However, there are some
|
|
1765
|
+
// scenarios where we cannot safely store the text diff and must instead
|
|
1766
|
+
// schedule an action to let Slate normalize the editor state.
|
|
2143
1767
|
|
|
2144
|
-
if (!Editor.hasPath(editor, path)) {
|
|
2145
|
-
return null;
|
|
2146
|
-
}
|
|
2147
1768
|
|
|
2148
|
-
|
|
1769
|
+
var canStoreDiff = true;
|
|
2149
1770
|
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
1771
|
+
if (type.startsWith('delete')) {
|
|
1772
|
+
if (Range.isExpanded(targetRange)) {
|
|
1773
|
+
var [_start, _end] = Range.edges(targetRange);
|
|
2153
1774
|
|
|
2154
|
-
|
|
2155
|
-
match: n => Element$1.isElement(n) && Editor.isBlock(editor, n),
|
|
2156
|
-
at: path
|
|
2157
|
-
});
|
|
1775
|
+
var _leaf = Node.leaf(editor, _start.path);
|
|
2158
1776
|
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
1777
|
+
if (_leaf.text.length === _start.offset && _end.offset === 0) {
|
|
1778
|
+
var next = Editor.next(editor, {
|
|
1779
|
+
at: _start.path,
|
|
1780
|
+
match: Text$1.isText
|
|
1781
|
+
});
|
|
2162
1782
|
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
1783
|
+
if (next && Path.equals(next[1], _end.path)) {
|
|
1784
|
+
targetRange = {
|
|
1785
|
+
anchor: _end,
|
|
1786
|
+
focus: _end
|
|
1787
|
+
};
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
2168
1791
|
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
1792
|
+
var direction = type.endsWith('Backward') ? 'backward' : 'forward';
|
|
1793
|
+
var [start, end] = Range.edges(targetRange);
|
|
1794
|
+
var [leaf, path] = Editor.leaf(editor, start.path);
|
|
1795
|
+
var diff = {
|
|
1796
|
+
text: '',
|
|
1797
|
+
start: start.offset,
|
|
1798
|
+
end: end.offset
|
|
1799
|
+
};
|
|
1800
|
+
var pendingDiffs = EDITOR_TO_PENDING_DIFFS.get(editor);
|
|
1801
|
+
var relevantPendingDiffs = pendingDiffs === null || pendingDiffs === void 0 ? void 0 : pendingDiffs.find(change => Path.equals(change.path, path));
|
|
1802
|
+
var diffs = relevantPendingDiffs ? [relevantPendingDiffs.diff, diff] : [diff];
|
|
1803
|
+
var text = applyStringDiff(leaf.text, ...diffs);
|
|
2172
1804
|
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
1805
|
+
if (text.length === 0) {
|
|
1806
|
+
// Text leaf will be removed, so we need to schedule an
|
|
1807
|
+
// action to remove it so that Slate can normalize instead
|
|
1808
|
+
// of storing as a diff
|
|
1809
|
+
canStoreDiff = false;
|
|
1810
|
+
}
|
|
2177
1811
|
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
1812
|
+
if (Range.isExpanded(targetRange)) {
|
|
1813
|
+
if (canStoreDiff && Path.equals(targetRange.anchor.path, targetRange.focus.path)) {
|
|
1814
|
+
var point = {
|
|
1815
|
+
path: targetRange.anchor.path,
|
|
1816
|
+
offset: start.offset
|
|
1817
|
+
};
|
|
1818
|
+
var range = Editor.range(editor, point, point);
|
|
1819
|
+
handleUserSelect(range);
|
|
1820
|
+
return storeDiff(targetRange.anchor.path, {
|
|
1821
|
+
text: '',
|
|
1822
|
+
end: end.offset,
|
|
1823
|
+
start: start.offset
|
|
1824
|
+
});
|
|
1825
|
+
}
|
|
2186
1826
|
|
|
2187
|
-
|
|
2188
|
-
|
|
1827
|
+
return scheduleAction(() => Editor.deleteFragment(editor, {
|
|
1828
|
+
direction
|
|
1829
|
+
}), {
|
|
1830
|
+
at: targetRange
|
|
1831
|
+
});
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
2189
1834
|
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
1835
|
+
switch (type) {
|
|
1836
|
+
case 'deleteByComposition':
|
|
1837
|
+
case 'deleteByCut':
|
|
1838
|
+
case 'deleteByDrag':
|
|
1839
|
+
{
|
|
1840
|
+
return scheduleAction(() => Editor.deleteFragment(editor), {
|
|
1841
|
+
at: targetRange
|
|
1842
|
+
});
|
|
1843
|
+
}
|
|
2193
1844
|
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
1845
|
+
case 'deleteContent':
|
|
1846
|
+
case 'deleteContentForward':
|
|
1847
|
+
{
|
|
1848
|
+
var {
|
|
1849
|
+
anchor
|
|
1850
|
+
} = targetRange;
|
|
2200
1851
|
|
|
2201
|
-
|
|
1852
|
+
if (canStoreDiff && Range.isCollapsed(targetRange)) {
|
|
1853
|
+
var targetNode = Node.leaf(editor, anchor.path);
|
|
2202
1854
|
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
1855
|
+
if (anchor.offset < targetNode.text.length) {
|
|
1856
|
+
return storeDiff(anchor.path, {
|
|
1857
|
+
text: '',
|
|
1858
|
+
start: anchor.offset,
|
|
1859
|
+
end: anchor.offset + 1
|
|
1860
|
+
});
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
2206
1863
|
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
}
|
|
2212
|
-
function transformPendingPoint(editor, point, op) {
|
|
2213
|
-
var pendingDiffs = EDITOR_TO_PENDING_DIFFS.get(editor);
|
|
2214
|
-
var textDiff = pendingDiffs === null || pendingDiffs === void 0 ? void 0 : pendingDiffs.find(_ref => {
|
|
2215
|
-
var {
|
|
2216
|
-
path
|
|
2217
|
-
} = _ref;
|
|
2218
|
-
return Path.equals(path, point.path);
|
|
2219
|
-
});
|
|
1864
|
+
return scheduleAction(() => Editor.deleteForward(editor), {
|
|
1865
|
+
at: targetRange
|
|
1866
|
+
});
|
|
1867
|
+
}
|
|
2220
1868
|
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
});
|
|
2225
|
-
}
|
|
1869
|
+
case 'deleteContentBackward':
|
|
1870
|
+
{
|
|
1871
|
+
var _nativeTargetRange;
|
|
2226
1872
|
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
1873
|
+
var {
|
|
1874
|
+
anchor: _anchor
|
|
1875
|
+
} = targetRange; // If we have a mismatch between the native and slate selection being collapsed
|
|
1876
|
+
// we are most likely deleting a zero-width placeholder and thus should perform it
|
|
1877
|
+
// as an action to ensure correct behavior (mostly happens with mark placeholders)
|
|
2231
1878
|
|
|
2232
|
-
|
|
2233
|
-
var _anchor = {
|
|
2234
|
-
path: point.path,
|
|
2235
|
-
offset: diff.start
|
|
2236
|
-
};
|
|
1879
|
+
var nativeCollapsed = isDOMSelection(nativeTargetRange) ? nativeTargetRange.isCollapsed : !!((_nativeTargetRange = nativeTargetRange) !== null && _nativeTargetRange !== void 0 && _nativeTargetRange.collapsed);
|
|
2237
1880
|
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
1881
|
+
if (canStoreDiff && nativeCollapsed && Range.isCollapsed(targetRange) && _anchor.offset > 0) {
|
|
1882
|
+
return storeDiff(_anchor.path, {
|
|
1883
|
+
text: '',
|
|
1884
|
+
start: _anchor.offset - 1,
|
|
1885
|
+
end: _anchor.offset
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
2241
1888
|
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
1889
|
+
return scheduleAction(() => Editor.deleteBackward(editor), {
|
|
1890
|
+
at: targetRange
|
|
1891
|
+
});
|
|
1892
|
+
}
|
|
2245
1893
|
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
1894
|
+
case 'deleteEntireSoftLine':
|
|
1895
|
+
{
|
|
1896
|
+
return scheduleAction(() => {
|
|
1897
|
+
Editor.deleteBackward(editor, {
|
|
1898
|
+
unit: 'line'
|
|
1899
|
+
});
|
|
1900
|
+
Editor.deleteForward(editor, {
|
|
1901
|
+
unit: 'line'
|
|
1902
|
+
});
|
|
1903
|
+
}, {
|
|
1904
|
+
at: targetRange
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
case 'deleteHardLineBackward':
|
|
1909
|
+
{
|
|
1910
|
+
return scheduleAction(() => Editor.deleteBackward(editor, {
|
|
1911
|
+
unit: 'block'
|
|
1912
|
+
}), {
|
|
1913
|
+
at: targetRange
|
|
1914
|
+
});
|
|
1915
|
+
}
|
|
2251
1916
|
|
|
1917
|
+
case 'deleteSoftLineBackward':
|
|
1918
|
+
{
|
|
1919
|
+
return scheduleAction(() => Editor.deleteBackward(editor, {
|
|
1920
|
+
unit: 'line'
|
|
1921
|
+
}), {
|
|
1922
|
+
at: targetRange
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
2252
1925
|
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
1926
|
+
case 'deleteHardLineForward':
|
|
1927
|
+
{
|
|
1928
|
+
return scheduleAction(() => Editor.deleteForward(editor, {
|
|
1929
|
+
unit: 'block'
|
|
1930
|
+
}), {
|
|
1931
|
+
at: targetRange
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
2260
1934
|
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
1935
|
+
case 'deleteSoftLineForward':
|
|
1936
|
+
{
|
|
1937
|
+
return scheduleAction(() => Editor.deleteForward(editor, {
|
|
1938
|
+
unit: 'line'
|
|
1939
|
+
}), {
|
|
1940
|
+
at: targetRange
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
2264
1943
|
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
1944
|
+
case 'deleteWordBackward':
|
|
1945
|
+
{
|
|
1946
|
+
return scheduleAction(() => Editor.deleteBackward(editor, {
|
|
1947
|
+
unit: 'word'
|
|
1948
|
+
}), {
|
|
1949
|
+
at: targetRange
|
|
1950
|
+
});
|
|
1951
|
+
}
|
|
2268
1952
|
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
}
|
|
2274
|
-
|
|
2275
|
-
|
|
1953
|
+
case 'deleteWordForward':
|
|
1954
|
+
{
|
|
1955
|
+
return scheduleAction(() => Editor.deleteForward(editor, {
|
|
1956
|
+
unit: 'word'
|
|
1957
|
+
}), {
|
|
1958
|
+
at: targetRange
|
|
1959
|
+
});
|
|
1960
|
+
}
|
|
2276
1961
|
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
1962
|
+
case 'insertLineBreak':
|
|
1963
|
+
{
|
|
1964
|
+
return scheduleAction(() => Editor.insertSoftBreak(editor), {
|
|
1965
|
+
at: targetRange
|
|
1966
|
+
});
|
|
1967
|
+
}
|
|
2280
1968
|
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
1969
|
+
case 'insertParagraph':
|
|
1970
|
+
{
|
|
1971
|
+
return scheduleAction(() => Editor.insertBreak(editor), {
|
|
1972
|
+
at: targetRange
|
|
1973
|
+
});
|
|
1974
|
+
}
|
|
2287
1975
|
|
|
2288
|
-
|
|
1976
|
+
case 'insertCompositionText':
|
|
1977
|
+
case 'deleteCompositionText':
|
|
1978
|
+
case 'insertFromComposition':
|
|
1979
|
+
case 'insertFromDrop':
|
|
1980
|
+
case 'insertFromPaste':
|
|
1981
|
+
case 'insertFromYank':
|
|
1982
|
+
case 'insertReplacementText':
|
|
1983
|
+
case 'insertText':
|
|
1984
|
+
{
|
|
1985
|
+
if (isDataTransfer(data)) {
|
|
1986
|
+
return scheduleAction(() => ReactEditor.insertData(editor, data), {
|
|
1987
|
+
at: targetRange
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
2289
1990
|
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
}
|
|
1991
|
+
var _text = data !== null && data !== void 0 ? data : ''; // COMPAT: If we are writing inside a placeholder, the ime inserts the text inside
|
|
1992
|
+
// the placeholder itself and thus includes the zero-width space inside edit events.
|
|
2293
1993
|
|
|
2294
|
-
return {
|
|
2295
|
-
anchor,
|
|
2296
|
-
focus
|
|
2297
|
-
};
|
|
2298
|
-
}
|
|
2299
|
-
function transformTextDiff(textDiff, op) {
|
|
2300
|
-
var {
|
|
2301
|
-
path,
|
|
2302
|
-
diff,
|
|
2303
|
-
id
|
|
2304
|
-
} = textDiff;
|
|
2305
1994
|
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
}
|
|
1995
|
+
if (EDITOR_TO_PENDING_INSERTION_MARKS.get(editor)) {
|
|
1996
|
+
_text = _text.replace('\uFEFF', '');
|
|
1997
|
+
} // Pastes from the Android clipboard will generate `insertText` events.
|
|
1998
|
+
// If the copied text contains any newlines, Android will append an
|
|
1999
|
+
// extra newline to the end of the copied text.
|
|
2312
2000
|
|
|
2313
|
-
if (op.offset <= diff.start) {
|
|
2314
|
-
return {
|
|
2315
|
-
diff: {
|
|
2316
|
-
start: op.text.length + diff.start,
|
|
2317
|
-
end: op.text.length + diff.end,
|
|
2318
|
-
text: diff.text
|
|
2319
|
-
},
|
|
2320
|
-
id,
|
|
2321
|
-
path
|
|
2322
|
-
};
|
|
2323
|
-
}
|
|
2324
2001
|
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
text: diff.text
|
|
2330
|
-
},
|
|
2331
|
-
id,
|
|
2332
|
-
path
|
|
2333
|
-
};
|
|
2334
|
-
}
|
|
2002
|
+
if (type === 'insertText' && /.*\n.*\n$/.test(_text)) {
|
|
2003
|
+
_text = _text.slice(0, -1);
|
|
2004
|
+
} // If the text includes a newline, split it at newlines and paste each component
|
|
2005
|
+
// string, with soft breaks in between each.
|
|
2335
2006
|
|
|
2336
|
-
case 'remove_text':
|
|
2337
|
-
{
|
|
2338
|
-
if (!Path.equals(op.path, path) || op.offset >= diff.end) {
|
|
2339
|
-
return textDiff;
|
|
2340
|
-
}
|
|
2341
2007
|
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
start: diff.start - op.text.length,
|
|
2346
|
-
end: diff.end - op.text.length,
|
|
2347
|
-
text: diff.text
|
|
2348
|
-
},
|
|
2349
|
-
id,
|
|
2350
|
-
path
|
|
2351
|
-
};
|
|
2352
|
-
}
|
|
2008
|
+
if (_text.includes('\n')) {
|
|
2009
|
+
return scheduleAction(() => {
|
|
2010
|
+
var parts = _text.split('\n');
|
|
2353
2011
|
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
text: diff.text
|
|
2359
|
-
},
|
|
2360
|
-
id,
|
|
2361
|
-
path
|
|
2362
|
-
};
|
|
2363
|
-
}
|
|
2012
|
+
parts.forEach((line, i) => {
|
|
2013
|
+
if (line) {
|
|
2014
|
+
Editor.insertText(editor, line);
|
|
2015
|
+
}
|
|
2364
2016
|
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
})
|
|
2374
|
-
};
|
|
2375
|
-
}
|
|
2017
|
+
if (i !== parts.length - 1) {
|
|
2018
|
+
Editor.insertSoftBreak(editor);
|
|
2019
|
+
}
|
|
2020
|
+
});
|
|
2021
|
+
}, {
|
|
2022
|
+
at: targetRange
|
|
2023
|
+
});
|
|
2024
|
+
}
|
|
2376
2025
|
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
start:
|
|
2381
|
-
end:
|
|
2382
|
-
text:
|
|
2383
|
-
}
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2026
|
+
if (Path.equals(targetRange.anchor.path, targetRange.focus.path)) {
|
|
2027
|
+
var [_start2, _end2] = Range.edges(targetRange);
|
|
2028
|
+
var _diff = {
|
|
2029
|
+
start: _start2.offset,
|
|
2030
|
+
end: _end2.offset,
|
|
2031
|
+
text: _text
|
|
2032
|
+
}; // COMPAT: Swiftkey has a weird bug where the target range of the 2nd word
|
|
2033
|
+
// inserted after a mark placeholder is inserted with an anchor offset off by 1.
|
|
2034
|
+
// So writing 'some text' will result in 'some ttext'. Luckily all 'normal' insert
|
|
2035
|
+
// text events are fired with the correct target ranges, only the final 'insertComposition'
|
|
2036
|
+
// isn't, so we can adjust the target range start offset if we are confident this is the
|
|
2037
|
+
// swiftkey insert causing the issue.
|
|
2388
2038
|
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
start: diff.start - op.position,
|
|
2392
|
-
end: diff.end - op.position,
|
|
2393
|
-
text: diff.text
|
|
2394
|
-
},
|
|
2395
|
-
id,
|
|
2396
|
-
path: Path.transform(path, op, {
|
|
2397
|
-
affinity: 'forward'
|
|
2398
|
-
})
|
|
2399
|
-
};
|
|
2400
|
-
}
|
|
2039
|
+
if (_text && insertPositionHint && type === 'insertCompositionText') {
|
|
2040
|
+
var hintPosition = insertPositionHint.start + insertPositionHint.text.search(/\S|$/);
|
|
2401
2041
|
|
|
2402
|
-
|
|
2403
|
-
{
|
|
2404
|
-
if (!Path.equals(op.path, path)) {
|
|
2405
|
-
return {
|
|
2406
|
-
diff,
|
|
2407
|
-
id,
|
|
2408
|
-
path: Path.transform(path, op)
|
|
2409
|
-
};
|
|
2410
|
-
}
|
|
2042
|
+
var diffPosition = _diff.start + _diff.text.search(/\S|$/);
|
|
2411
2043
|
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2044
|
+
if (diffPosition === hintPosition + 1 && _diff.end === insertPositionHint.start + insertPositionHint.text.length) {
|
|
2045
|
+
_diff.start -= 1;
|
|
2046
|
+
insertPositionHint = null;
|
|
2047
|
+
scheduleFlush();
|
|
2048
|
+
} else {
|
|
2049
|
+
insertPositionHint = false;
|
|
2050
|
+
}
|
|
2051
|
+
} else if (type === 'insertText') {
|
|
2052
|
+
if (insertPositionHint === null) {
|
|
2053
|
+
insertPositionHint = _diff;
|
|
2054
|
+
} else if (insertPositionHint && Range.isCollapsed(targetRange) && insertPositionHint.end + insertPositionHint.text.length === _start2.offset) {
|
|
2055
|
+
insertPositionHint = _objectSpread$3(_objectSpread$3({}, insertPositionHint), {}, {
|
|
2056
|
+
text: insertPositionHint.text + _text
|
|
2057
|
+
});
|
|
2058
|
+
} else {
|
|
2059
|
+
insertPositionHint = false;
|
|
2060
|
+
}
|
|
2061
|
+
} else {
|
|
2062
|
+
insertPositionHint = false;
|
|
2063
|
+
}
|
|
2423
2064
|
|
|
2424
|
-
|
|
2065
|
+
if (canStoreDiff) {
|
|
2066
|
+
storeDiff(_start2.path, _diff);
|
|
2067
|
+
return;
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2425
2070
|
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2071
|
+
return scheduleAction(() => Editor.insertText(editor, _text), {
|
|
2072
|
+
at: targetRange
|
|
2073
|
+
});
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
};
|
|
2429
2077
|
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
path: newPath,
|
|
2433
|
-
id
|
|
2078
|
+
var hasPendingAction = () => {
|
|
2079
|
+
return !!EDITOR_TO_PENDING_ACTION.get(editor);
|
|
2434
2080
|
};
|
|
2435
|
-
}
|
|
2436
2081
|
|
|
2437
|
-
|
|
2082
|
+
var hasPendingDiffs = () => {
|
|
2083
|
+
var _EDITOR_TO_PENDING_DI4;
|
|
2438
2084
|
|
|
2439
|
-
|
|
2440
|
-
|
|
2085
|
+
return !!((_EDITOR_TO_PENDING_DI4 = EDITOR_TO_PENDING_DIFFS.get(editor)) !== null && _EDITOR_TO_PENDING_DI4 !== void 0 && _EDITOR_TO_PENDING_DI4.length);
|
|
2086
|
+
};
|
|
2441
2087
|
|
|
2442
|
-
var
|
|
2088
|
+
var hasPendingChanges = () => {
|
|
2089
|
+
return hasPendingAction() || hasPendingDiffs();
|
|
2090
|
+
};
|
|
2443
2091
|
|
|
2444
|
-
var
|
|
2092
|
+
var isFlushing = () => {
|
|
2093
|
+
return flushing;
|
|
2094
|
+
};
|
|
2445
2095
|
|
|
2446
|
-
var
|
|
2096
|
+
var handleUserSelect = range => {
|
|
2097
|
+
EDITOR_TO_PENDING_SELECTION.set(editor, range);
|
|
2447
2098
|
|
|
2099
|
+
if (flushTimeoutId) {
|
|
2100
|
+
clearTimeout(flushTimeoutId);
|
|
2101
|
+
flushTimeoutId = null;
|
|
2102
|
+
}
|
|
2448
2103
|
|
|
2449
|
-
var
|
|
2104
|
+
var {
|
|
2105
|
+
selection
|
|
2106
|
+
} = editor;
|
|
2450
2107
|
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
scheduleOnDOMSelectionChange,
|
|
2455
|
-
onDOMSelectionChange
|
|
2456
|
-
} = _ref;
|
|
2457
|
-
var flushing = false;
|
|
2458
|
-
var compositionEndTimeoutId = null;
|
|
2459
|
-
var flushTimeoutId = null;
|
|
2460
|
-
var actionTimeoutId = null;
|
|
2461
|
-
var idCounter = 0;
|
|
2462
|
-
var insertPositionHint = false;
|
|
2108
|
+
if (!range) {
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2463
2111
|
|
|
2464
|
-
|
|
2465
|
-
var
|
|
2466
|
-
EDITOR_TO_PENDING_SELECTION.delete(editor);
|
|
2112
|
+
var pathChanged = !selection || !Path.equals(selection.anchor.path, range.anchor.path);
|
|
2113
|
+
var parentPathChanged = !selection || !Path.equals(selection.anchor.path.slice(0, -1), range.anchor.path.slice(0, -1));
|
|
2467
2114
|
|
|
2468
|
-
if (
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
} = editor;
|
|
2472
|
-
var normalized = normalizeRange(editor, pendingSelection);
|
|
2115
|
+
if (pathChanged && insertPositionHint || parentPathChanged) {
|
|
2116
|
+
insertPositionHint = false;
|
|
2117
|
+
}
|
|
2473
2118
|
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
}
|
|
2119
|
+
if (pathChanged || hasPendingDiffs()) {
|
|
2120
|
+
flushTimeoutId = setTimeout(flush, FLUSH_DELAY);
|
|
2477
2121
|
}
|
|
2478
2122
|
};
|
|
2479
2123
|
|
|
2480
|
-
var
|
|
2481
|
-
|
|
2482
|
-
|
|
2124
|
+
var handleInput = () => {
|
|
2125
|
+
if (hasPendingAction() || !hasPendingDiffs()) {
|
|
2126
|
+
flush();
|
|
2127
|
+
}
|
|
2128
|
+
};
|
|
2483
2129
|
|
|
2484
|
-
|
|
2485
|
-
|
|
2130
|
+
var handleKeyDown = _ => {
|
|
2131
|
+
// COMPAT: Swiftkey closes the keyboard when typing inside a empty node
|
|
2132
|
+
// directly next to a non-contenteditable element (= the placeholder).
|
|
2133
|
+
// The only event fired soon enough for us to allow hiding the placeholder
|
|
2134
|
+
// without swiftkey picking it up is the keydown event, so we have to hide it
|
|
2135
|
+
// here. See https://github.com/ianstormtaylor/slate/pull/4988#issuecomment-1201050535
|
|
2136
|
+
if (!hasPendingDiffs()) {
|
|
2137
|
+
updatePlaceholderVisibility(true);
|
|
2138
|
+
setTimeout(updatePlaceholderVisibility);
|
|
2486
2139
|
}
|
|
2140
|
+
};
|
|
2487
2141
|
|
|
2488
|
-
|
|
2489
|
-
|
|
2142
|
+
var scheduleFlush = () => {
|
|
2143
|
+
if (!hasPendingAction()) {
|
|
2144
|
+
actionTimeoutId = setTimeout(flush);
|
|
2145
|
+
}
|
|
2146
|
+
};
|
|
2490
2147
|
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2148
|
+
var handleDomMutations = mutations => {
|
|
2149
|
+
if (hasPendingDiffs() || hasPendingAction()) {
|
|
2150
|
+
return;
|
|
2151
|
+
}
|
|
2494
2152
|
|
|
2495
|
-
|
|
2153
|
+
if (mutations.some(mutation => isTrackedMutation(editor, mutation, mutations))) {
|
|
2154
|
+
var _EDITOR_TO_FORCE_REND;
|
|
2496
2155
|
|
|
2497
|
-
if
|
|
2498
|
-
|
|
2499
|
-
|
|
2156
|
+
// Cause a re-render to restore the dom state if we encounter tracked mutations without
|
|
2157
|
+
// a corresponding pending action.
|
|
2158
|
+
(_EDITOR_TO_FORCE_REND = EDITOR_TO_FORCE_RENDER.get(editor)) === null || _EDITOR_TO_FORCE_REND === void 0 ? void 0 : _EDITOR_TO_FORCE_REND();
|
|
2500
2159
|
}
|
|
2160
|
+
};
|
|
2501
2161
|
|
|
2502
|
-
|
|
2162
|
+
return {
|
|
2163
|
+
flush,
|
|
2164
|
+
scheduleFlush,
|
|
2165
|
+
hasPendingDiffs,
|
|
2166
|
+
hasPendingAction,
|
|
2167
|
+
hasPendingChanges,
|
|
2168
|
+
isFlushing,
|
|
2169
|
+
handleUserSelect,
|
|
2170
|
+
handleCompositionEnd,
|
|
2171
|
+
handleCompositionStart,
|
|
2172
|
+
handleDOMBeforeInput,
|
|
2173
|
+
handleKeyDown,
|
|
2174
|
+
handleDomMutations,
|
|
2175
|
+
handleInput
|
|
2503
2176
|
};
|
|
2177
|
+
}
|
|
2504
2178
|
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2179
|
+
function useIsMounted() {
|
|
2180
|
+
var isMountedRef = useRef(false);
|
|
2181
|
+
useEffect(() => {
|
|
2182
|
+
isMountedRef.current = true;
|
|
2183
|
+
return () => {
|
|
2184
|
+
isMountedRef.current = false;
|
|
2185
|
+
};
|
|
2186
|
+
}, []);
|
|
2187
|
+
return isMountedRef.current;
|
|
2188
|
+
}
|
|
2510
2189
|
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
}
|
|
2190
|
+
/**
|
|
2191
|
+
* Prevent warning on SSR by falling back to useEffect when DOM isn't available
|
|
2192
|
+
*/
|
|
2515
2193
|
|
|
2516
|
-
|
|
2517
|
-
applyPendingSelection();
|
|
2518
|
-
return;
|
|
2519
|
-
}
|
|
2194
|
+
var useIsomorphicLayoutEffect = CAN_USE_DOM ? useLayoutEffect : useEffect;
|
|
2520
2195
|
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2196
|
+
function useMutationObserver(node, callback, options) {
|
|
2197
|
+
var [mutationObserver] = useState(() => new MutationObserver(callback));
|
|
2198
|
+
useIsomorphicLayoutEffect(() => {
|
|
2199
|
+
// Discard mutations caused during render phase. This works due to react calling
|
|
2200
|
+
// useLayoutEffect synchronously after the render phase before the next tick.
|
|
2201
|
+
mutationObserver.takeRecords();
|
|
2202
|
+
});
|
|
2203
|
+
useEffect(() => {
|
|
2204
|
+
if (!node.current) {
|
|
2205
|
+
throw new Error('Failed to attach MutationObserver, `node` is undefined');
|
|
2524
2206
|
}
|
|
2525
2207
|
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2208
|
+
mutationObserver.observe(node.current, options);
|
|
2209
|
+
return () => mutationObserver.disconnect();
|
|
2210
|
+
}, [mutationObserver, node, options]);
|
|
2211
|
+
}
|
|
2529
2212
|
|
|
2530
|
-
|
|
2531
|
-
affinity: 'forward'
|
|
2532
|
-
});
|
|
2533
|
-
EDITOR_TO_USER_MARKS.set(editor, editor.marks);
|
|
2534
|
-
debug('flush', EDITOR_TO_PENDING_ACTION.get(editor), EDITOR_TO_PENDING_DIFFS.get(editor));
|
|
2535
|
-
var scheduleSelectionChange = hasPendingDiffs();
|
|
2536
|
-
var diff;
|
|
2213
|
+
var _excluded$3 = ["node"];
|
|
2537
2214
|
|
|
2538
|
-
|
|
2539
|
-
|
|
2215
|
+
function ownKeys$2(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; }
|
|
2216
|
+
|
|
2217
|
+
function _objectSpread$2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$2(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$2(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
2218
|
+
var MUTATION_OBSERVER_CONFIG$1 = {
|
|
2219
|
+
subtree: true,
|
|
2220
|
+
childList: true,
|
|
2221
|
+
characterData: true
|
|
2222
|
+
};
|
|
2223
|
+
var useAndroidInputManager = !IS_ANDROID ? () => null : _ref => {
|
|
2224
|
+
var {
|
|
2225
|
+
node
|
|
2226
|
+
} = _ref,
|
|
2227
|
+
options = _objectWithoutProperties(_ref, _excluded$3);
|
|
2228
|
+
|
|
2229
|
+
if (!IS_ANDROID) {
|
|
2230
|
+
return null;
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
var editor = useSlateStatic();
|
|
2234
|
+
var isMounted = useIsMounted();
|
|
2235
|
+
var [inputManager] = useState(() => createAndroidInputManager(_objectSpread$2({
|
|
2236
|
+
editor
|
|
2237
|
+
}, options)));
|
|
2238
|
+
useMutationObserver(node, inputManager.handleDomMutations, MUTATION_OBSERVER_CONFIG$1);
|
|
2239
|
+
EDITOR_TO_SCHEDULE_FLUSH.set(editor, inputManager.scheduleFlush);
|
|
2240
|
+
|
|
2241
|
+
if (isMounted) {
|
|
2242
|
+
inputManager.flush();
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
return inputManager;
|
|
2246
|
+
};
|
|
2247
|
+
|
|
2248
|
+
var _excluded$2 = ["anchor", "focus"],
|
|
2249
|
+
_excluded2$1 = ["anchor", "focus"];
|
|
2250
|
+
var shallowCompare = (obj1, obj2) => Object.keys(obj1).length === Object.keys(obj2).length && Object.keys(obj1).every(key => obj2.hasOwnProperty(key) && obj1[key] === obj2[key]);
|
|
2251
|
+
|
|
2252
|
+
var isDecorationFlagsEqual = (range, other) => {
|
|
2253
|
+
var rangeOwnProps = _objectWithoutProperties(range, _excluded$2);
|
|
2254
|
+
|
|
2255
|
+
var otherOwnProps = _objectWithoutProperties(other, _excluded2$1);
|
|
2256
|
+
|
|
2257
|
+
return range[PLACEHOLDER_SYMBOL] === other[PLACEHOLDER_SYMBOL] && shallowCompare(rangeOwnProps, otherOwnProps);
|
|
2258
|
+
};
|
|
2259
|
+
/**
|
|
2260
|
+
* Check if a list of decorator ranges are equal to another.
|
|
2261
|
+
*
|
|
2262
|
+
* PERF: this requires the two lists to also have the ranges inside them in the
|
|
2263
|
+
* same order, but this is an okay constraint for us since decorations are
|
|
2264
|
+
* kept in order, and the odd case where they aren't is okay to re-render for.
|
|
2265
|
+
*/
|
|
2266
|
+
|
|
2267
|
+
|
|
2268
|
+
var isElementDecorationsEqual = (list, another) => {
|
|
2269
|
+
if (list.length !== another.length) {
|
|
2270
|
+
return false;
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
for (var i = 0; i < list.length; i++) {
|
|
2274
|
+
var range = list[i];
|
|
2275
|
+
var other = another[i];
|
|
2276
|
+
|
|
2277
|
+
if (!Range.equals(range, other) || !isDecorationFlagsEqual(range, other)) {
|
|
2278
|
+
return false;
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
return true;
|
|
2283
|
+
};
|
|
2284
|
+
/**
|
|
2285
|
+
* Check if a list of decorator ranges are equal to another.
|
|
2286
|
+
*
|
|
2287
|
+
* PERF: this requires the two lists to also have the ranges inside them in the
|
|
2288
|
+
* same order, but this is an okay constraint for us since decorations are
|
|
2289
|
+
* kept in order, and the odd case where they aren't is okay to re-render for.
|
|
2290
|
+
*/
|
|
2540
2291
|
|
|
2541
|
-
|
|
2292
|
+
var isTextDecorationsEqual = (list, another) => {
|
|
2293
|
+
if (list.length !== another.length) {
|
|
2294
|
+
return false;
|
|
2295
|
+
}
|
|
2542
2296
|
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
}
|
|
2297
|
+
for (var i = 0; i < list.length; i++) {
|
|
2298
|
+
var range = list[i];
|
|
2299
|
+
var other = another[i]; // compare only offsets because paths doesn't matter for text
|
|
2547
2300
|
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2301
|
+
if (range.anchor.offset !== other.anchor.offset || range.focus.offset !== other.focus.offset || !isDecorationFlagsEqual(range, other)) {
|
|
2302
|
+
return false;
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2551
2305
|
|
|
2552
|
-
|
|
2306
|
+
return true;
|
|
2307
|
+
};
|
|
2553
2308
|
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2309
|
+
/**
|
|
2310
|
+
* Leaf content strings.
|
|
2311
|
+
*/
|
|
2557
2312
|
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2313
|
+
var String = props => {
|
|
2314
|
+
var {
|
|
2315
|
+
isLast,
|
|
2316
|
+
leaf,
|
|
2317
|
+
parent,
|
|
2318
|
+
text
|
|
2319
|
+
} = props;
|
|
2320
|
+
var editor = useSlateStatic();
|
|
2321
|
+
var path = ReactEditor.findPath(editor, text);
|
|
2322
|
+
var parentPath = Path.parent(path);
|
|
2323
|
+
var isMarkPlaceholder = leaf[MARK_PLACEHOLDER_SYMBOL] === true; // COMPAT: Render text inside void nodes with a zero-width space.
|
|
2324
|
+
// So the node can contain selection but the text is not visible.
|
|
2564
2325
|
|
|
2326
|
+
if (editor.isVoid(parent)) {
|
|
2327
|
+
return /*#__PURE__*/React.createElement(ZeroWidthString, {
|
|
2328
|
+
length: Node.string(parent).length
|
|
2329
|
+
});
|
|
2330
|
+
} // COMPAT: If this is the last text node in an empty block, render a zero-
|
|
2331
|
+
// width space that will convert into a line break when copying and pasting
|
|
2332
|
+
// to support expected plain text.
|
|
2565
2333
|
|
|
2566
|
-
EDITOR_TO_PENDING_DIFFS.set(editor, (_EDITOR_TO_PENDING_DI2 = EDITOR_TO_PENDING_DIFFS.get(editor)) === null || _EDITOR_TO_PENDING_DI2 === void 0 ? void 0 : _EDITOR_TO_PENDING_DI2.filter(_ref2 => {
|
|
2567
|
-
var {
|
|
2568
|
-
id
|
|
2569
|
-
} = _ref2;
|
|
2570
|
-
return id !== diff.id;
|
|
2571
|
-
}));
|
|
2572
2334
|
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2335
|
+
if (leaf.text === '' && parent.children[parent.children.length - 1] === text && !editor.isInline(parent) && Editor.string(editor, parentPath) === '') {
|
|
2336
|
+
return /*#__PURE__*/React.createElement(ZeroWidthString, {
|
|
2337
|
+
isLineBreak: true,
|
|
2338
|
+
isMarkPlaceholder: isMarkPlaceholder
|
|
2339
|
+
});
|
|
2340
|
+
} // COMPAT: If the text is empty, it's because it's on the edge of an inline
|
|
2341
|
+
// node, so we render a zero-width space so that the selection can be
|
|
2342
|
+
// inserted next to it still.
|
|
2579
2343
|
|
|
2580
|
-
EDITOR_TO_PENDING_SELECTION.delete(editor);
|
|
2581
|
-
scheduleOnDOMSelectionChange.cancel();
|
|
2582
|
-
onDOMSelectionChange.cancel();
|
|
2583
|
-
selectionRef === null || selectionRef === void 0 ? void 0 : selectionRef.unref();
|
|
2584
|
-
}
|
|
2585
|
-
}
|
|
2586
2344
|
|
|
2587
|
-
|
|
2345
|
+
if (leaf.text === '') {
|
|
2346
|
+
return /*#__PURE__*/React.createElement(ZeroWidthString, {
|
|
2347
|
+
isMarkPlaceholder: isMarkPlaceholder
|
|
2348
|
+
});
|
|
2349
|
+
} // COMPAT: Browsers will collapse trailing new lines at the end of blocks,
|
|
2350
|
+
// so we need to add an extra trailing new lines to prevent that.
|
|
2588
2351
|
|
|
2589
|
-
if (selection && !EDITOR_TO_PENDING_SELECTION.get(editor) && (!editor.selection || !Range.equals(selection, editor.selection))) {
|
|
2590
|
-
Transforms.select(editor, selection);
|
|
2591
|
-
}
|
|
2592
2352
|
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2353
|
+
if (isLast && leaf.text.slice(-1) === '\n') {
|
|
2354
|
+
return /*#__PURE__*/React.createElement(TextString, {
|
|
2355
|
+
isTrailing: true,
|
|
2356
|
+
text: leaf.text
|
|
2357
|
+
});
|
|
2358
|
+
}
|
|
2599
2359
|
|
|
2360
|
+
return /*#__PURE__*/React.createElement(TextString, {
|
|
2361
|
+
text: leaf.text
|
|
2362
|
+
});
|
|
2363
|
+
};
|
|
2364
|
+
/**
|
|
2365
|
+
* Leaf strings with text in them.
|
|
2366
|
+
*/
|
|
2600
2367
|
|
|
2601
|
-
if (scheduleSelectionChange) {
|
|
2602
|
-
scheduleOnDOMSelectionChange();
|
|
2603
|
-
}
|
|
2604
2368
|
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2369
|
+
var TextString = props => {
|
|
2370
|
+
var {
|
|
2371
|
+
text,
|
|
2372
|
+
isTrailing = false
|
|
2373
|
+
} = props;
|
|
2374
|
+
var ref = useRef(null);
|
|
2610
2375
|
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
editor.onChange();
|
|
2614
|
-
}
|
|
2376
|
+
var getTextContent = () => {
|
|
2377
|
+
return "".concat(text !== null && text !== void 0 ? text : '').concat(isTrailing ? '\n' : '');
|
|
2615
2378
|
};
|
|
2616
2379
|
|
|
2617
|
-
var
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
}, RESOLVE_DELAY);
|
|
2626
|
-
};
|
|
2380
|
+
var [initialText] = useState(getTextContent); // This is the actual text rendering boundary where we interface with the DOM
|
|
2381
|
+
// The text is not rendered as part of the virtual DOM, as since we handle basic character insertions natively,
|
|
2382
|
+
// updating the DOM is not a one way dataflow anymore. What we need here is not reconciliation and diffing
|
|
2383
|
+
// with previous version of the virtual DOM, but rather diffing with the actual DOM element, and replace the DOM <span> content
|
|
2384
|
+
// exactly if and only if its current content does not match our current virtual DOM.
|
|
2385
|
+
// Otherwise the DOM TextNode would always be replaced by React as the user types, which interferes with native text features,
|
|
2386
|
+
// eg makes native spellcheck opt out from checking the text node.
|
|
2387
|
+
// useLayoutEffect: updating our span before browser paint
|
|
2627
2388
|
|
|
2628
|
-
|
|
2629
|
-
|
|
2389
|
+
useIsomorphicLayoutEffect(() => {
|
|
2390
|
+
// null coalescing text to make sure we're not outputing "null" as a string in the extreme case it is nullish at runtime
|
|
2391
|
+
var textWithTrailing = getTextContent();
|
|
2630
2392
|
|
|
2631
|
-
if (
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
};
|
|
2393
|
+
if (ref.current && ref.current.textContent !== textWithTrailing) {
|
|
2394
|
+
ref.current.textContent = textWithTrailing;
|
|
2395
|
+
} // intentionally not specifying dependencies, so that this effect runs on every render
|
|
2396
|
+
// as this effectively replaces "specifying the text in the virtual DOM under the <span> below" on each render
|
|
2636
2397
|
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
var placeholderElement = EDITOR_TO_PLACEHOLDER_ELEMENT.get(editor);
|
|
2398
|
+
}); // We intentionally render a memoized <span> that only receives the initial text content when the component is mounted.
|
|
2399
|
+
// We defer to the layout effect above to update the `textContent` of the span element when needed.
|
|
2640
2400
|
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2401
|
+
return /*#__PURE__*/React.createElement(MemoizedText$1, {
|
|
2402
|
+
ref: ref
|
|
2403
|
+
}, initialText);
|
|
2404
|
+
};
|
|
2644
2405
|
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2406
|
+
var MemoizedText$1 = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, ref) => {
|
|
2407
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
2408
|
+
"data-slate-string": true,
|
|
2409
|
+
ref: ref
|
|
2410
|
+
}, props.children);
|
|
2411
|
+
}));
|
|
2412
|
+
/**
|
|
2413
|
+
* Leaf strings without text, render as zero-width strings.
|
|
2414
|
+
*/
|
|
2649
2415
|
|
|
2650
|
-
|
|
2416
|
+
var ZeroWidthString = props => {
|
|
2417
|
+
var {
|
|
2418
|
+
length = 0,
|
|
2419
|
+
isLineBreak = false,
|
|
2420
|
+
isMarkPlaceholder = false
|
|
2421
|
+
} = props;
|
|
2422
|
+
var attributes = {
|
|
2423
|
+
'data-slate-zero-width': isLineBreak ? 'n' : 'z',
|
|
2424
|
+
'data-slate-length': length
|
|
2651
2425
|
};
|
|
2652
2426
|
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
EDITOR_TO_PENDING_DIFFS.set(editor, pendingDiffs);
|
|
2657
|
-
var target = Node.leaf(editor, path);
|
|
2658
|
-
var idx = pendingDiffs.findIndex(change => Path.equals(change.path, path));
|
|
2659
|
-
|
|
2660
|
-
if (idx < 0) {
|
|
2661
|
-
var normalized = normalizeStringDiff(target.text, diff);
|
|
2662
|
-
|
|
2663
|
-
if (normalized) {
|
|
2664
|
-
pendingDiffs.push({
|
|
2665
|
-
path,
|
|
2666
|
-
diff,
|
|
2667
|
-
id: idCounter++
|
|
2668
|
-
});
|
|
2669
|
-
}
|
|
2427
|
+
if (isMarkPlaceholder) {
|
|
2428
|
+
attributes['data-slate-mark-placeholder'] = true;
|
|
2429
|
+
}
|
|
2670
2430
|
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
}
|
|
2431
|
+
return /*#__PURE__*/React.createElement("span", Object.assign({}, attributes), !IS_ANDROID || !isLineBreak ? '\uFEFF' : null, isLineBreak ? /*#__PURE__*/React.createElement("br", null) : null);
|
|
2432
|
+
};
|
|
2674
2433
|
|
|
2675
|
-
|
|
2434
|
+
function disconnectPlaceholderResizeObserver(placeholderResizeObserver, releaseObserver) {
|
|
2435
|
+
if (placeholderResizeObserver.current) {
|
|
2436
|
+
placeholderResizeObserver.current.disconnect();
|
|
2676
2437
|
|
|
2677
|
-
if (
|
|
2678
|
-
|
|
2679
|
-
updatePlaceholderVisibility();
|
|
2680
|
-
return;
|
|
2438
|
+
if (releaseObserver) {
|
|
2439
|
+
placeholderResizeObserver.current = null;
|
|
2681
2440
|
}
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2682
2443
|
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
insertPositionHint = false;
|
|
2693
|
-
EDITOR_TO_PENDING_SELECTION.delete(editor);
|
|
2694
|
-
scheduleOnDOMSelectionChange.cancel();
|
|
2695
|
-
onDOMSelectionChange.cancel();
|
|
2444
|
+
function clearTimeoutRef(timeoutRef) {
|
|
2445
|
+
if (timeoutRef.current) {
|
|
2446
|
+
clearTimeout(timeoutRef.current);
|
|
2447
|
+
timeoutRef.current = null;
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
/**
|
|
2451
|
+
* Individual leaves in a text node with unique formatting.
|
|
2452
|
+
*/
|
|
2696
2453
|
|
|
2697
|
-
if (hasPendingAction()) {
|
|
2698
|
-
flush();
|
|
2699
|
-
}
|
|
2700
2454
|
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2455
|
+
var Leaf = props => {
|
|
2456
|
+
var {
|
|
2457
|
+
leaf,
|
|
2458
|
+
isLast,
|
|
2459
|
+
text,
|
|
2460
|
+
parent,
|
|
2461
|
+
renderPlaceholder,
|
|
2462
|
+
renderLeaf = props => /*#__PURE__*/React.createElement(DefaultLeaf, Object.assign({}, props))
|
|
2463
|
+
} = props;
|
|
2464
|
+
var editor = useSlateStatic();
|
|
2465
|
+
var placeholderResizeObserver = useRef(null);
|
|
2466
|
+
var placeholderRef = useRef(null);
|
|
2467
|
+
var [showPlaceholder, setShowPlaceholder] = useState(false);
|
|
2468
|
+
var showPlaceholderTimeoutRef = useRef(null);
|
|
2469
|
+
var callbackPlaceholderRef = useCallback(placeholderEl => {
|
|
2470
|
+
disconnectPlaceholderResizeObserver(placeholderResizeObserver, placeholderEl == null);
|
|
2707
2471
|
|
|
2708
|
-
|
|
2709
|
-
|
|
2472
|
+
if (placeholderEl == null) {
|
|
2473
|
+
var _leaf$onPlaceholderRe;
|
|
2710
2474
|
|
|
2711
|
-
|
|
2712
|
-
|
|
2475
|
+
EDITOR_TO_PLACEHOLDER_ELEMENT.delete(editor);
|
|
2476
|
+
(_leaf$onPlaceholderRe = leaf.onPlaceholderResize) === null || _leaf$onPlaceholderRe === void 0 ? void 0 : _leaf$onPlaceholderRe.call(leaf, null);
|
|
2477
|
+
} else {
|
|
2478
|
+
EDITOR_TO_PLACEHOLDER_ELEMENT.set(editor, placeholderEl);
|
|
2713
2479
|
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2480
|
+
if (!placeholderResizeObserver.current) {
|
|
2481
|
+
// Create a new observer and observe the placeholder element.
|
|
2482
|
+
var ResizeObserver$1 = window.ResizeObserver || ResizeObserver;
|
|
2483
|
+
placeholderResizeObserver.current = new ResizeObserver$1(() => {
|
|
2484
|
+
var _leaf$onPlaceholderRe2;
|
|
2718
2485
|
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
var targetRange = null;
|
|
2723
|
-
var data = event.dataTransfer || event.data || undefined;
|
|
2486
|
+
(_leaf$onPlaceholderRe2 = leaf.onPlaceholderResize) === null || _leaf$onPlaceholderRe2 === void 0 ? void 0 : _leaf$onPlaceholderRe2.call(leaf, placeholderEl);
|
|
2487
|
+
});
|
|
2488
|
+
}
|
|
2724
2489
|
|
|
2725
|
-
|
|
2726
|
-
|
|
2490
|
+
placeholderResizeObserver.current.observe(placeholderEl);
|
|
2491
|
+
placeholderRef.current = placeholderEl;
|
|
2492
|
+
}
|
|
2493
|
+
}, [placeholderRef, leaf, editor]);
|
|
2494
|
+
var children = /*#__PURE__*/React.createElement(String, {
|
|
2495
|
+
isLast: isLast,
|
|
2496
|
+
leaf: leaf,
|
|
2497
|
+
parent: parent,
|
|
2498
|
+
text: text
|
|
2499
|
+
});
|
|
2500
|
+
var leafIsPlaceholder = leaf[PLACEHOLDER_SYMBOL];
|
|
2501
|
+
useEffect(() => {
|
|
2502
|
+
if (leafIsPlaceholder) {
|
|
2503
|
+
if (!showPlaceholderTimeoutRef.current) {
|
|
2504
|
+
// Delay the placeholder so it will not render in a selection
|
|
2505
|
+
showPlaceholderTimeoutRef.current = setTimeout(() => {
|
|
2506
|
+
setShowPlaceholder(true);
|
|
2507
|
+
showPlaceholderTimeoutRef.current = null;
|
|
2508
|
+
}, 300);
|
|
2509
|
+
}
|
|
2510
|
+
} else {
|
|
2511
|
+
clearTimeoutRef(showPlaceholderTimeoutRef);
|
|
2512
|
+
setShowPlaceholder(false);
|
|
2727
2513
|
}
|
|
2728
2514
|
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
if (nativeTargetRange) {
|
|
2732
|
-
targetRange = ReactEditor.toSlateRange(editor, nativeTargetRange, {
|
|
2733
|
-
exactMatch: false,
|
|
2734
|
-
suppressThrow: true
|
|
2735
|
-
});
|
|
2736
|
-
} // COMPAT: SelectionChange event is fired after the action is performed, so we
|
|
2737
|
-
// have to manually get the selection here to ensure it's up-to-date.
|
|
2515
|
+
return () => clearTimeoutRef(showPlaceholderTimeoutRef);
|
|
2516
|
+
}, [leafIsPlaceholder, setShowPlaceholder]);
|
|
2738
2517
|
|
|
2518
|
+
if (leafIsPlaceholder && showPlaceholder) {
|
|
2519
|
+
var placeholderProps = {
|
|
2520
|
+
children: leaf.placeholder,
|
|
2521
|
+
attributes: {
|
|
2522
|
+
'data-slate-placeholder': true,
|
|
2523
|
+
style: {
|
|
2524
|
+
position: 'absolute',
|
|
2525
|
+
pointerEvents: 'none',
|
|
2526
|
+
width: '100%',
|
|
2527
|
+
maxWidth: '100%',
|
|
2528
|
+
display: 'block',
|
|
2529
|
+
opacity: '0.333',
|
|
2530
|
+
userSelect: 'none',
|
|
2531
|
+
textDecoration: 'none',
|
|
2532
|
+
// Fixes https://github.com/udecode/plate/issues/2315
|
|
2533
|
+
WebkitUserModify: IS_SAFARI ? 'inherit' : undefined
|
|
2534
|
+
},
|
|
2535
|
+
contentEditable: false,
|
|
2536
|
+
ref: callbackPlaceholderRef
|
|
2537
|
+
}
|
|
2538
|
+
};
|
|
2539
|
+
children = /*#__PURE__*/React.createElement(React.Fragment, null, renderPlaceholder(placeholderProps), children);
|
|
2540
|
+
} // COMPAT: Having the `data-` attributes on these leaf elements ensures that
|
|
2541
|
+
// in certain misbehaving browsers they aren't weirdly cloned/destroyed by
|
|
2542
|
+
// contenteditable behaviors. (2019/05/08)
|
|
2739
2543
|
|
|
2740
|
-
var window = ReactEditor.getWindow(editor);
|
|
2741
|
-
var domSelection = window.getSelection();
|
|
2742
2544
|
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2545
|
+
var attributes = {
|
|
2546
|
+
'data-slate-leaf': true
|
|
2547
|
+
};
|
|
2548
|
+
return renderLeaf({
|
|
2549
|
+
attributes,
|
|
2550
|
+
children,
|
|
2551
|
+
leaf,
|
|
2552
|
+
text
|
|
2553
|
+
});
|
|
2554
|
+
};
|
|
2750
2555
|
|
|
2751
|
-
|
|
2556
|
+
var MemoizedLeaf = /*#__PURE__*/React.memo(Leaf, (prev, next) => {
|
|
2557
|
+
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];
|
|
2558
|
+
});
|
|
2559
|
+
var DefaultLeaf = props => {
|
|
2560
|
+
var {
|
|
2561
|
+
attributes,
|
|
2562
|
+
children
|
|
2563
|
+
} = props;
|
|
2564
|
+
return /*#__PURE__*/React.createElement("span", Object.assign({}, attributes), children);
|
|
2565
|
+
};
|
|
2752
2566
|
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
// defer flushing them at a later point in time. We don't want to flush
|
|
2757
|
-
// for every input event as this can be expensive. However, there are some
|
|
2758
|
-
// scenarios where we cannot safely store the text diff and must instead
|
|
2759
|
-
// schedule an action to let Slate normalize the editor state.
|
|
2567
|
+
/**
|
|
2568
|
+
* Text.
|
|
2569
|
+
*/
|
|
2760
2570
|
|
|
2571
|
+
var Text = props => {
|
|
2572
|
+
var {
|
|
2573
|
+
decorations,
|
|
2574
|
+
isLast,
|
|
2575
|
+
parent,
|
|
2576
|
+
renderPlaceholder,
|
|
2577
|
+
renderLeaf,
|
|
2578
|
+
text
|
|
2579
|
+
} = props;
|
|
2580
|
+
var editor = useSlateStatic();
|
|
2581
|
+
var ref = useRef(null);
|
|
2582
|
+
var leaves = Text$1.decorations(text, decorations);
|
|
2583
|
+
var key = ReactEditor.findKey(editor, text);
|
|
2584
|
+
var children = [];
|
|
2761
2585
|
|
|
2762
|
-
|
|
2586
|
+
for (var i = 0; i < leaves.length; i++) {
|
|
2587
|
+
var leaf = leaves[i];
|
|
2588
|
+
children.push( /*#__PURE__*/React.createElement(MemoizedLeaf, {
|
|
2589
|
+
isLast: isLast && i === leaves.length - 1,
|
|
2590
|
+
key: "".concat(key.id, "-").concat(i),
|
|
2591
|
+
renderPlaceholder: renderPlaceholder,
|
|
2592
|
+
leaf: leaf,
|
|
2593
|
+
text: text,
|
|
2594
|
+
parent: parent,
|
|
2595
|
+
renderLeaf: renderLeaf
|
|
2596
|
+
}));
|
|
2597
|
+
} // Update element-related weak maps with the DOM element ref.
|
|
2763
2598
|
|
|
2764
|
-
if (type.startsWith('delete')) {
|
|
2765
|
-
if (Range.isExpanded(targetRange)) {
|
|
2766
|
-
var [_start, _end] = Range.edges(targetRange);
|
|
2767
2599
|
|
|
2768
|
-
|
|
2600
|
+
var callbackRef = useCallback(span => {
|
|
2601
|
+
var KEY_TO_ELEMENT = EDITOR_TO_KEY_TO_ELEMENT.get(editor);
|
|
2769
2602
|
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2603
|
+
if (span) {
|
|
2604
|
+
KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.set(key, span);
|
|
2605
|
+
NODE_TO_ELEMENT.set(text, span);
|
|
2606
|
+
ELEMENT_TO_NODE.set(span, text);
|
|
2607
|
+
} else {
|
|
2608
|
+
KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.delete(key);
|
|
2609
|
+
NODE_TO_ELEMENT.delete(text);
|
|
2775
2610
|
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
anchor: _end,
|
|
2779
|
-
focus: _end
|
|
2780
|
-
};
|
|
2781
|
-
}
|
|
2782
|
-
}
|
|
2611
|
+
if (ref.current) {
|
|
2612
|
+
ELEMENT_TO_NODE.delete(ref.current);
|
|
2783
2613
|
}
|
|
2614
|
+
}
|
|
2784
2615
|
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
};
|
|
2793
|
-
var pendingDiffs = EDITOR_TO_PENDING_DIFFS.get(editor);
|
|
2794
|
-
var relevantPendingDiffs = pendingDiffs === null || pendingDiffs === void 0 ? void 0 : pendingDiffs.find(change => Path.equals(change.path, path));
|
|
2795
|
-
var diffs = relevantPendingDiffs ? [relevantPendingDiffs.diff, diff] : [diff];
|
|
2796
|
-
var text = applyStringDiff(leaf.text, ...diffs);
|
|
2797
|
-
|
|
2798
|
-
if (text.length === 0) {
|
|
2799
|
-
// Text leaf will be removed, so we need to schedule an
|
|
2800
|
-
// action to remove it so that Slate can normalize instead
|
|
2801
|
-
// of storing as a diff
|
|
2802
|
-
canStoreDiff = false;
|
|
2803
|
-
}
|
|
2616
|
+
ref.current = span;
|
|
2617
|
+
}, [ref, editor, key, text]);
|
|
2618
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
2619
|
+
"data-slate-node": "text",
|
|
2620
|
+
ref: callbackRef
|
|
2621
|
+
}, children);
|
|
2622
|
+
};
|
|
2804
2623
|
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
path: targetRange.anchor.path,
|
|
2809
|
-
offset: start.offset
|
|
2810
|
-
};
|
|
2811
|
-
var range = Editor.range(editor, point, point);
|
|
2812
|
-
handleUserSelect(range);
|
|
2813
|
-
return storeDiff(targetRange.anchor.path, {
|
|
2814
|
-
text: '',
|
|
2815
|
-
end: end.offset,
|
|
2816
|
-
start: start.offset
|
|
2817
|
-
});
|
|
2818
|
-
}
|
|
2624
|
+
var MemoizedText = /*#__PURE__*/React.memo(Text, (prev, next) => {
|
|
2625
|
+
return next.parent === prev.parent && next.isLast === prev.isLast && next.renderLeaf === prev.renderLeaf && next.renderPlaceholder === prev.renderPlaceholder && next.text === prev.text && isTextDecorationsEqual(next.decorations, prev.decorations);
|
|
2626
|
+
});
|
|
2819
2627
|
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2628
|
+
/**
|
|
2629
|
+
* Element.
|
|
2630
|
+
*/
|
|
2631
|
+
|
|
2632
|
+
var Element = props => {
|
|
2633
|
+
var {
|
|
2634
|
+
decorations,
|
|
2635
|
+
element,
|
|
2636
|
+
renderElement = p => /*#__PURE__*/React.createElement(DefaultElement, Object.assign({}, p)),
|
|
2637
|
+
renderPlaceholder,
|
|
2638
|
+
renderLeaf,
|
|
2639
|
+
selection
|
|
2640
|
+
} = props;
|
|
2641
|
+
var editor = useSlateStatic();
|
|
2642
|
+
var readOnly = useReadOnly();
|
|
2643
|
+
var isInline = editor.isInline(element);
|
|
2644
|
+
var key = ReactEditor.findKey(editor, element);
|
|
2645
|
+
var ref = useCallback(ref => {
|
|
2646
|
+
// Update element-related weak maps with the DOM element ref.
|
|
2647
|
+
var KEY_TO_ELEMENT = EDITOR_TO_KEY_TO_ELEMENT.get(editor);
|
|
2648
|
+
|
|
2649
|
+
if (ref) {
|
|
2650
|
+
KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.set(key, ref);
|
|
2651
|
+
NODE_TO_ELEMENT.set(element, ref);
|
|
2652
|
+
ELEMENT_TO_NODE.set(ref, element);
|
|
2653
|
+
} else {
|
|
2654
|
+
KEY_TO_ELEMENT === null || KEY_TO_ELEMENT === void 0 ? void 0 : KEY_TO_ELEMENT.delete(key);
|
|
2655
|
+
NODE_TO_ELEMENT.delete(element);
|
|
2826
2656
|
}
|
|
2657
|
+
}, [editor, key, element]);
|
|
2658
|
+
var children = useChildren({
|
|
2659
|
+
decorations,
|
|
2660
|
+
node: element,
|
|
2661
|
+
renderElement,
|
|
2662
|
+
renderPlaceholder,
|
|
2663
|
+
renderLeaf,
|
|
2664
|
+
selection
|
|
2665
|
+
}); // Attributes that the developer must mix into the element in their
|
|
2666
|
+
// custom node renderer component.
|
|
2827
2667
|
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
{
|
|
2833
|
-
return scheduleAction(() => Editor.deleteFragment(editor), {
|
|
2834
|
-
at: targetRange
|
|
2835
|
-
});
|
|
2836
|
-
}
|
|
2668
|
+
var attributes = {
|
|
2669
|
+
'data-slate-node': 'element',
|
|
2670
|
+
ref
|
|
2671
|
+
};
|
|
2837
2672
|
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
anchor
|
|
2843
|
-
} = targetRange;
|
|
2673
|
+
if (isInline) {
|
|
2674
|
+
attributes['data-slate-inline'] = true;
|
|
2675
|
+
} // If it's a block node with inline children, add the proper `dir` attribute
|
|
2676
|
+
// for text direction.
|
|
2844
2677
|
|
|
2845
|
-
if (canStoreDiff && Range.isCollapsed(targetRange)) {
|
|
2846
|
-
var targetNode = Node.leaf(editor, anchor.path);
|
|
2847
2678
|
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
start: anchor.offset,
|
|
2852
|
-
end: anchor.offset + 1
|
|
2853
|
-
});
|
|
2854
|
-
}
|
|
2855
|
-
}
|
|
2679
|
+
if (!isInline && Editor.hasInlines(editor, element)) {
|
|
2680
|
+
var text = Node.string(element);
|
|
2681
|
+
var dir = getDirection(text);
|
|
2856
2682
|
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2683
|
+
if (dir === 'rtl') {
|
|
2684
|
+
attributes.dir = dir;
|
|
2685
|
+
}
|
|
2686
|
+
} // If it's a void node, wrap the children in extra void-specific elements.
|
|
2861
2687
|
|
|
2862
|
-
case 'deleteContentBackward':
|
|
2863
|
-
{
|
|
2864
|
-
var _nativeTargetRange;
|
|
2865
2688
|
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
} = targetRange; // If we have a mismatch between the native and slate selection being collapsed
|
|
2869
|
-
// we are most likely deleting a zero-width placeholder and thus should perform it
|
|
2870
|
-
// as an action to ensure correct behavior (mostly happens with mark placeholders)
|
|
2689
|
+
if (Editor.isVoid(editor, element)) {
|
|
2690
|
+
attributes['data-slate-void'] = true;
|
|
2871
2691
|
|
|
2872
|
-
|
|
2692
|
+
if (!readOnly && isInline) {
|
|
2693
|
+
attributes.contentEditable = false;
|
|
2694
|
+
}
|
|
2873
2695
|
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2696
|
+
var Tag = isInline ? 'span' : 'div';
|
|
2697
|
+
var [[_text]] = Node.texts(element);
|
|
2698
|
+
children = /*#__PURE__*/React.createElement(Tag, {
|
|
2699
|
+
"data-slate-spacer": true,
|
|
2700
|
+
style: {
|
|
2701
|
+
height: '0',
|
|
2702
|
+
color: 'transparent',
|
|
2703
|
+
outline: 'none',
|
|
2704
|
+
position: 'absolute'
|
|
2705
|
+
}
|
|
2706
|
+
}, /*#__PURE__*/React.createElement(MemoizedText, {
|
|
2707
|
+
renderPlaceholder: renderPlaceholder,
|
|
2708
|
+
decorations: [],
|
|
2709
|
+
isLast: false,
|
|
2710
|
+
parent: element,
|
|
2711
|
+
text: _text
|
|
2712
|
+
}));
|
|
2713
|
+
NODE_TO_INDEX.set(_text, 0);
|
|
2714
|
+
NODE_TO_PARENT.set(_text, element);
|
|
2715
|
+
}
|
|
2881
2716
|
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2717
|
+
return renderElement({
|
|
2718
|
+
attributes,
|
|
2719
|
+
children,
|
|
2720
|
+
element
|
|
2721
|
+
});
|
|
2722
|
+
};
|
|
2886
2723
|
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
Editor.deleteForward(editor, {
|
|
2894
|
-
unit: 'line'
|
|
2895
|
-
});
|
|
2896
|
-
}, {
|
|
2897
|
-
at: targetRange
|
|
2898
|
-
});
|
|
2899
|
-
}
|
|
2724
|
+
var MemoizedElement = /*#__PURE__*/React.memo(Element, (prev, next) => {
|
|
2725
|
+
return prev.element === next.element && prev.renderElement === next.renderElement && prev.renderLeaf === next.renderLeaf && prev.renderPlaceholder === next.renderPlaceholder && isElementDecorationsEqual(prev.decorations, next.decorations) && (prev.selection === next.selection || !!prev.selection && !!next.selection && Range.equals(prev.selection, next.selection));
|
|
2726
|
+
});
|
|
2727
|
+
/**
|
|
2728
|
+
* The default element renderer.
|
|
2729
|
+
*/
|
|
2900
2730
|
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2731
|
+
var DefaultElement = props => {
|
|
2732
|
+
var {
|
|
2733
|
+
attributes,
|
|
2734
|
+
children,
|
|
2735
|
+
element
|
|
2736
|
+
} = props;
|
|
2737
|
+
var editor = useSlateStatic();
|
|
2738
|
+
var Tag = editor.isInline(element) ? 'span' : 'div';
|
|
2739
|
+
return /*#__PURE__*/React.createElement(Tag, Object.assign({}, attributes, {
|
|
2740
|
+
style: {
|
|
2741
|
+
position: 'relative'
|
|
2742
|
+
}
|
|
2743
|
+
}), children);
|
|
2744
|
+
};
|
|
2909
2745
|
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
unit: 'line'
|
|
2914
|
-
}), {
|
|
2915
|
-
at: targetRange
|
|
2916
|
-
});
|
|
2917
|
-
}
|
|
2746
|
+
/**
|
|
2747
|
+
* A React context for sharing the `decorate` prop of the editable.
|
|
2748
|
+
*/
|
|
2918
2749
|
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
}), {
|
|
2924
|
-
at: targetRange
|
|
2925
|
-
});
|
|
2926
|
-
}
|
|
2750
|
+
var DecorateContext = /*#__PURE__*/createContext(() => []);
|
|
2751
|
+
/**
|
|
2752
|
+
* Get the current `decorate` prop of the editable.
|
|
2753
|
+
*/
|
|
2927
2754
|
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
unit: 'line'
|
|
2932
|
-
}), {
|
|
2933
|
-
at: targetRange
|
|
2934
|
-
});
|
|
2935
|
-
}
|
|
2755
|
+
var useDecorate = () => {
|
|
2756
|
+
return useContext(DecorateContext);
|
|
2757
|
+
};
|
|
2936
2758
|
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
unit: 'word'
|
|
2941
|
-
}), {
|
|
2942
|
-
at: targetRange
|
|
2943
|
-
});
|
|
2944
|
-
}
|
|
2759
|
+
/**
|
|
2760
|
+
* A React context for sharing the `selected` state of an element.
|
|
2761
|
+
*/
|
|
2945
2762
|
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
}), {
|
|
2951
|
-
at: targetRange
|
|
2952
|
-
});
|
|
2953
|
-
}
|
|
2763
|
+
var SelectedContext = /*#__PURE__*/createContext(false);
|
|
2764
|
+
/**
|
|
2765
|
+
* Get the current `selected` state of an element.
|
|
2766
|
+
*/
|
|
2954
2767
|
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
at: targetRange
|
|
2959
|
-
});
|
|
2960
|
-
}
|
|
2768
|
+
var useSelected = () => {
|
|
2769
|
+
return useContext(SelectedContext);
|
|
2770
|
+
};
|
|
2961
2771
|
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2772
|
+
/**
|
|
2773
|
+
* Children.
|
|
2774
|
+
*/
|
|
2775
|
+
|
|
2776
|
+
var useChildren = props => {
|
|
2777
|
+
var {
|
|
2778
|
+
decorations,
|
|
2779
|
+
node,
|
|
2780
|
+
renderElement,
|
|
2781
|
+
renderPlaceholder,
|
|
2782
|
+
renderLeaf,
|
|
2783
|
+
selection
|
|
2784
|
+
} = props;
|
|
2785
|
+
var decorate = useDecorate();
|
|
2786
|
+
var editor = useSlateStatic();
|
|
2787
|
+
var path = ReactEditor.findPath(editor, node);
|
|
2788
|
+
var children = [];
|
|
2789
|
+
var isLeafBlock = Element$1.isElement(node) && !editor.isInline(node) && Editor.hasInlines(editor, node);
|
|
2968
2790
|
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
case 'insertText':
|
|
2977
|
-
{
|
|
2978
|
-
if (isDataTransfer(data)) {
|
|
2979
|
-
return scheduleAction(() => ReactEditor.insertData(editor, data), {
|
|
2980
|
-
at: targetRange
|
|
2981
|
-
});
|
|
2982
|
-
}
|
|
2791
|
+
for (var i = 0; i < node.children.length; i++) {
|
|
2792
|
+
var p = path.concat(i);
|
|
2793
|
+
var n = node.children[i];
|
|
2794
|
+
var key = ReactEditor.findKey(editor, n);
|
|
2795
|
+
var range = Editor.range(editor, p);
|
|
2796
|
+
var sel = selection && Range.intersection(range, selection);
|
|
2797
|
+
var ds = decorate([n, p]);
|
|
2983
2798
|
|
|
2984
|
-
|
|
2985
|
-
|
|
2799
|
+
for (var dec of decorations) {
|
|
2800
|
+
var d = Range.intersection(dec, range);
|
|
2986
2801
|
|
|
2802
|
+
if (d) {
|
|
2803
|
+
ds.push(d);
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2987
2806
|
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2807
|
+
if (Element$1.isElement(n)) {
|
|
2808
|
+
children.push( /*#__PURE__*/React.createElement(SelectedContext.Provider, {
|
|
2809
|
+
key: "provider-".concat(key.id),
|
|
2810
|
+
value: !!sel
|
|
2811
|
+
}, /*#__PURE__*/React.createElement(MemoizedElement, {
|
|
2812
|
+
decorations: ds,
|
|
2813
|
+
element: n,
|
|
2814
|
+
key: key.id,
|
|
2815
|
+
renderElement: renderElement,
|
|
2816
|
+
renderPlaceholder: renderPlaceholder,
|
|
2817
|
+
renderLeaf: renderLeaf,
|
|
2818
|
+
selection: sel
|
|
2819
|
+
})));
|
|
2820
|
+
} else {
|
|
2821
|
+
children.push( /*#__PURE__*/React.createElement(MemoizedText, {
|
|
2822
|
+
decorations: ds,
|
|
2823
|
+
key: key.id,
|
|
2824
|
+
isLast: isLeafBlock && i === node.children.length - 1,
|
|
2825
|
+
parent: node,
|
|
2826
|
+
renderPlaceholder: renderPlaceholder,
|
|
2827
|
+
renderLeaf: renderLeaf,
|
|
2828
|
+
text: n
|
|
2829
|
+
}));
|
|
2830
|
+
}
|
|
2993
2831
|
|
|
2832
|
+
NODE_TO_INDEX.set(n, i);
|
|
2833
|
+
NODE_TO_PARENT.set(n, node);
|
|
2834
|
+
}
|
|
2994
2835
|
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
} // If the text includes a newline, split it at newlines and paste each component
|
|
2998
|
-
// string, with soft breaks in between each.
|
|
2836
|
+
return children;
|
|
2837
|
+
};
|
|
2999
2838
|
|
|
2839
|
+
/**
|
|
2840
|
+
* A React context for sharing the `readOnly` state of the editor.
|
|
2841
|
+
*/
|
|
3000
2842
|
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
2843
|
+
var ReadOnlyContext = /*#__PURE__*/createContext(false);
|
|
2844
|
+
/**
|
|
2845
|
+
* Get the current `readOnly` state of the editor.
|
|
2846
|
+
*/
|
|
3004
2847
|
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
}
|
|
2848
|
+
var useReadOnly = () => {
|
|
2849
|
+
return useContext(ReadOnlyContext);
|
|
2850
|
+
};
|
|
3009
2851
|
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
}, {
|
|
3015
|
-
at: targetRange
|
|
3016
|
-
});
|
|
3017
|
-
}
|
|
2852
|
+
var SlateContext = /*#__PURE__*/createContext(null);
|
|
2853
|
+
/**
|
|
2854
|
+
* Get the current editor object from the React context.
|
|
2855
|
+
*/
|
|
3018
2856
|
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
var _diff = {
|
|
3022
|
-
start: _start2.offset,
|
|
3023
|
-
end: _end2.offset,
|
|
3024
|
-
text: _text
|
|
3025
|
-
}; // COMPAT: Swiftkey has a weird bug where the target range of the 2nd word
|
|
3026
|
-
// inserted after a mark placeholder is inserted with an anchor offset off by 1.
|
|
3027
|
-
// So writing 'some text' will result in 'some ttext'. Luckily all 'normal' insert
|
|
3028
|
-
// text events are fired with the correct target ranges, only the final 'insertComposition'
|
|
3029
|
-
// isn't, so we can adjust the target range start offset if we are confident this is the
|
|
3030
|
-
// swiftkey insert causing the issue.
|
|
2857
|
+
var useSlate = () => {
|
|
2858
|
+
var context = useContext(SlateContext);
|
|
3031
2859
|
|
|
3032
|
-
|
|
3033
|
-
|
|
2860
|
+
if (!context) {
|
|
2861
|
+
throw new Error("The `useSlate` hook must be used inside the <Slate> component's context.");
|
|
2862
|
+
}
|
|
3034
2863
|
|
|
3035
|
-
|
|
2864
|
+
var {
|
|
2865
|
+
editor
|
|
2866
|
+
} = context;
|
|
2867
|
+
return editor;
|
|
2868
|
+
};
|
|
2869
|
+
var useSlateWithV = () => {
|
|
2870
|
+
var context = useContext(SlateContext);
|
|
3036
2871
|
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
scheduleFlush();
|
|
3041
|
-
} else {
|
|
3042
|
-
insertPositionHint = false;
|
|
3043
|
-
}
|
|
3044
|
-
} else if (type === 'insertText') {
|
|
3045
|
-
if (insertPositionHint === null) {
|
|
3046
|
-
insertPositionHint = _diff;
|
|
3047
|
-
} else if (insertPositionHint && Range.isCollapsed(targetRange) && insertPositionHint.end + insertPositionHint.text.length === _start2.offset) {
|
|
3048
|
-
insertPositionHint = _objectSpread$3(_objectSpread$3({}, insertPositionHint), {}, {
|
|
3049
|
-
text: insertPositionHint.text + _text
|
|
3050
|
-
});
|
|
3051
|
-
} else {
|
|
3052
|
-
insertPositionHint = false;
|
|
3053
|
-
}
|
|
3054
|
-
} else {
|
|
3055
|
-
insertPositionHint = false;
|
|
3056
|
-
}
|
|
2872
|
+
if (!context) {
|
|
2873
|
+
throw new Error("The `useSlate` hook must be used inside the <Slate> component's context.");
|
|
2874
|
+
}
|
|
3057
2875
|
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
return;
|
|
3061
|
-
}
|
|
3062
|
-
}
|
|
2876
|
+
return context;
|
|
2877
|
+
};
|
|
3063
2878
|
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
2879
|
+
function useTrackUserInput() {
|
|
2880
|
+
var editor = useSlateStatic();
|
|
2881
|
+
var receivedUserInput = useRef(false);
|
|
2882
|
+
var animationFrameIdRef = useRef(0);
|
|
2883
|
+
var onUserInput = useCallback(() => {
|
|
2884
|
+
if (receivedUserInput.current) {
|
|
2885
|
+
return;
|
|
3068
2886
|
}
|
|
3069
|
-
};
|
|
3070
2887
|
|
|
3071
|
-
|
|
3072
|
-
|
|
2888
|
+
receivedUserInput.current = true;
|
|
2889
|
+
var window = ReactEditor.getWindow(editor);
|
|
2890
|
+
window.cancelAnimationFrame(animationFrameIdRef.current);
|
|
2891
|
+
animationFrameIdRef.current = window.requestAnimationFrame(() => {
|
|
2892
|
+
receivedUserInput.current = false;
|
|
2893
|
+
});
|
|
2894
|
+
}, [editor]);
|
|
2895
|
+
useEffect(() => () => cancelAnimationFrame(animationFrameIdRef.current), []);
|
|
2896
|
+
return {
|
|
2897
|
+
receivedUserInput,
|
|
2898
|
+
onUserInput
|
|
3073
2899
|
};
|
|
2900
|
+
}
|
|
3074
2901
|
|
|
3075
|
-
|
|
3076
|
-
var _EDITOR_TO_PENDING_DI4;
|
|
2902
|
+
var TRIPLE_CLICK = 3;
|
|
3077
2903
|
|
|
3078
|
-
|
|
3079
|
-
|
|
2904
|
+
/**
|
|
2905
|
+
* Hotkey mappings for each platform.
|
|
2906
|
+
*/
|
|
3080
2907
|
|
|
3081
|
-
|
|
3082
|
-
|
|
2908
|
+
var HOTKEYS = {
|
|
2909
|
+
bold: 'mod+b',
|
|
2910
|
+
compose: ['down', 'left', 'right', 'up', 'backspace', 'enter'],
|
|
2911
|
+
moveBackward: 'left',
|
|
2912
|
+
moveForward: 'right',
|
|
2913
|
+
moveWordBackward: 'ctrl+left',
|
|
2914
|
+
moveWordForward: 'ctrl+right',
|
|
2915
|
+
deleteBackward: 'shift?+backspace',
|
|
2916
|
+
deleteForward: 'shift?+delete',
|
|
2917
|
+
extendBackward: 'shift+left',
|
|
2918
|
+
extendForward: 'shift+right',
|
|
2919
|
+
italic: 'mod+i',
|
|
2920
|
+
insertSoftBreak: 'shift+enter',
|
|
2921
|
+
splitBlock: 'enter',
|
|
2922
|
+
undo: 'mod+z'
|
|
2923
|
+
};
|
|
2924
|
+
var APPLE_HOTKEYS = {
|
|
2925
|
+
moveLineBackward: 'opt+up',
|
|
2926
|
+
moveLineForward: 'opt+down',
|
|
2927
|
+
moveWordBackward: 'opt+left',
|
|
2928
|
+
moveWordForward: 'opt+right',
|
|
2929
|
+
deleteBackward: ['ctrl+backspace', 'ctrl+h'],
|
|
2930
|
+
deleteForward: ['ctrl+delete', 'ctrl+d'],
|
|
2931
|
+
deleteLineBackward: 'cmd+shift?+backspace',
|
|
2932
|
+
deleteLineForward: ['cmd+shift?+delete', 'ctrl+k'],
|
|
2933
|
+
deleteWordBackward: 'opt+shift?+backspace',
|
|
2934
|
+
deleteWordForward: 'opt+shift?+delete',
|
|
2935
|
+
extendLineBackward: 'opt+shift+up',
|
|
2936
|
+
extendLineForward: 'opt+shift+down',
|
|
2937
|
+
redo: 'cmd+shift+z',
|
|
2938
|
+
transposeCharacter: 'ctrl+t'
|
|
2939
|
+
};
|
|
2940
|
+
var WINDOWS_HOTKEYS = {
|
|
2941
|
+
deleteWordBackward: 'ctrl+shift?+backspace',
|
|
2942
|
+
deleteWordForward: 'ctrl+shift?+delete',
|
|
2943
|
+
redo: ['ctrl+y', 'ctrl+shift+z']
|
|
2944
|
+
};
|
|
2945
|
+
/**
|
|
2946
|
+
* Create a platform-aware hotkey checker.
|
|
2947
|
+
*/
|
|
2948
|
+
|
|
2949
|
+
var create = key => {
|
|
2950
|
+
var generic = HOTKEYS[key];
|
|
2951
|
+
var apple = APPLE_HOTKEYS[key];
|
|
2952
|
+
var windows = WINDOWS_HOTKEYS[key];
|
|
2953
|
+
var isGeneric = generic && isKeyHotkey(generic);
|
|
2954
|
+
var isApple = apple && isKeyHotkey(apple);
|
|
2955
|
+
var isWindows = windows && isKeyHotkey(windows);
|
|
2956
|
+
return event => {
|
|
2957
|
+
if (isGeneric && isGeneric(event)) return true;
|
|
2958
|
+
if (IS_APPLE && isApple && isApple(event)) return true;
|
|
2959
|
+
if (!IS_APPLE && isWindows && isWindows(event)) return true;
|
|
2960
|
+
return false;
|
|
3083
2961
|
};
|
|
2962
|
+
};
|
|
2963
|
+
/**
|
|
2964
|
+
* Hotkeys.
|
|
2965
|
+
*/
|
|
3084
2966
|
|
|
3085
|
-
var isFlushing = () => {
|
|
3086
|
-
return flushing;
|
|
3087
|
-
};
|
|
3088
2967
|
|
|
3089
|
-
|
|
3090
|
-
|
|
2968
|
+
var Hotkeys = {
|
|
2969
|
+
isBold: create('bold'),
|
|
2970
|
+
isCompose: create('compose'),
|
|
2971
|
+
isMoveBackward: create('moveBackward'),
|
|
2972
|
+
isMoveForward: create('moveForward'),
|
|
2973
|
+
isDeleteBackward: create('deleteBackward'),
|
|
2974
|
+
isDeleteForward: create('deleteForward'),
|
|
2975
|
+
isDeleteLineBackward: create('deleteLineBackward'),
|
|
2976
|
+
isDeleteLineForward: create('deleteLineForward'),
|
|
2977
|
+
isDeleteWordBackward: create('deleteWordBackward'),
|
|
2978
|
+
isDeleteWordForward: create('deleteWordForward'),
|
|
2979
|
+
isExtendBackward: create('extendBackward'),
|
|
2980
|
+
isExtendForward: create('extendForward'),
|
|
2981
|
+
isExtendLineBackward: create('extendLineBackward'),
|
|
2982
|
+
isExtendLineForward: create('extendLineForward'),
|
|
2983
|
+
isItalic: create('italic'),
|
|
2984
|
+
isMoveLineBackward: create('moveLineBackward'),
|
|
2985
|
+
isMoveLineForward: create('moveLineForward'),
|
|
2986
|
+
isMoveWordBackward: create('moveWordBackward'),
|
|
2987
|
+
isMoveWordForward: create('moveWordForward'),
|
|
2988
|
+
isRedo: create('redo'),
|
|
2989
|
+
isSoftBreak: create('insertSoftBreak'),
|
|
2990
|
+
isSplitBlock: create('splitBlock'),
|
|
2991
|
+
isTransposeCharacter: create('transposeCharacter'),
|
|
2992
|
+
isUndo: create('undo')
|
|
2993
|
+
};
|
|
3091
2994
|
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
flushTimeoutId = null;
|
|
3095
|
-
}
|
|
2995
|
+
var createRestoreDomManager = (editor, receivedUserInput) => {
|
|
2996
|
+
var bufferedMutations = [];
|
|
3096
2997
|
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
2998
|
+
var clear = () => {
|
|
2999
|
+
bufferedMutations = [];
|
|
3000
|
+
};
|
|
3100
3001
|
|
|
3101
|
-
|
|
3002
|
+
var registerMutations = mutations => {
|
|
3003
|
+
if (!receivedUserInput.current) {
|
|
3102
3004
|
return;
|
|
3103
3005
|
}
|
|
3104
3006
|
|
|
3105
|
-
var
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
if (pathChanged && insertPositionHint || parentPathChanged) {
|
|
3109
|
-
insertPositionHint = false;
|
|
3110
|
-
}
|
|
3111
|
-
|
|
3112
|
-
if (pathChanged || hasPendingDiffs()) {
|
|
3113
|
-
flushTimeoutId = setTimeout(flush, FLUSH_DELAY);
|
|
3114
|
-
}
|
|
3007
|
+
var trackedMutations = mutations.filter(mutation => isTrackedMutation(editor, mutation, mutations));
|
|
3008
|
+
bufferedMutations.push(...trackedMutations);
|
|
3115
3009
|
};
|
|
3116
3010
|
|
|
3117
|
-
|
|
3118
|
-
if (
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3011
|
+
function restoreDOM() {
|
|
3012
|
+
if (bufferedMutations.length > 0) {
|
|
3013
|
+
bufferedMutations.reverse().forEach(mutation => {
|
|
3014
|
+
if (mutation.type === 'characterData') {
|
|
3015
|
+
// We don't want to restore the DOM for characterData mutations
|
|
3016
|
+
// because this interrupts the composition.
|
|
3017
|
+
return;
|
|
3018
|
+
}
|
|
3122
3019
|
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
updatePlaceholderVisibility(true);
|
|
3131
|
-
setTimeout(updatePlaceholderVisibility);
|
|
3132
|
-
}
|
|
3133
|
-
};
|
|
3020
|
+
mutation.removedNodes.forEach(node => {
|
|
3021
|
+
mutation.target.insertBefore(node, mutation.nextSibling);
|
|
3022
|
+
});
|
|
3023
|
+
mutation.addedNodes.forEach(node => {
|
|
3024
|
+
mutation.target.removeChild(node);
|
|
3025
|
+
});
|
|
3026
|
+
}); // Clear buffered mutations to ensure we don't undo them twice
|
|
3134
3027
|
|
|
3135
|
-
|
|
3136
|
-
if (!hasPendingAction()) {
|
|
3137
|
-
actionTimeoutId = setTimeout(flush);
|
|
3028
|
+
clear();
|
|
3138
3029
|
}
|
|
3139
|
-
}
|
|
3030
|
+
}
|
|
3140
3031
|
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3032
|
+
return {
|
|
3033
|
+
registerMutations,
|
|
3034
|
+
restoreDOM,
|
|
3035
|
+
clear
|
|
3036
|
+
};
|
|
3037
|
+
};
|
|
3145
3038
|
|
|
3146
|
-
|
|
3147
|
-
|
|
3039
|
+
var MUTATION_OBSERVER_CONFIG = {
|
|
3040
|
+
subtree: true,
|
|
3041
|
+
childList: true,
|
|
3042
|
+
characterData: true,
|
|
3043
|
+
characterDataOldValue: true
|
|
3044
|
+
}; // We have to use a class component here since we rely on `getSnapshotBeforeUpdate` which has no FC equivalent
|
|
3045
|
+
// to run code synchronously immediately before react commits the component update to the DOM.
|
|
3148
3046
|
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3047
|
+
class RestoreDOMComponent extends Component {
|
|
3048
|
+
constructor() {
|
|
3049
|
+
super(...arguments);
|
|
3050
|
+
this.context = null;
|
|
3051
|
+
this.manager = null;
|
|
3052
|
+
this.mutationObserver = null;
|
|
3053
|
+
}
|
|
3154
3054
|
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
scheduleFlush,
|
|
3158
|
-
hasPendingDiffs,
|
|
3159
|
-
hasPendingAction,
|
|
3160
|
-
hasPendingChanges,
|
|
3161
|
-
isFlushing,
|
|
3162
|
-
handleUserSelect,
|
|
3163
|
-
handleCompositionEnd,
|
|
3164
|
-
handleCompositionStart,
|
|
3165
|
-
handleDOMBeforeInput,
|
|
3166
|
-
handleKeyDown,
|
|
3167
|
-
handleDomMutations,
|
|
3168
|
-
handleInput
|
|
3169
|
-
};
|
|
3170
|
-
}
|
|
3055
|
+
observe() {
|
|
3056
|
+
var _this$mutationObserve;
|
|
3171
3057
|
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
isMountedRef.current = true;
|
|
3176
|
-
return () => {
|
|
3177
|
-
isMountedRef.current = false;
|
|
3178
|
-
};
|
|
3179
|
-
}, []);
|
|
3180
|
-
return isMountedRef.current;
|
|
3181
|
-
}
|
|
3058
|
+
var {
|
|
3059
|
+
node
|
|
3060
|
+
} = this.props;
|
|
3182
3061
|
|
|
3183
|
-
function useMutationObserver(node, callback, options) {
|
|
3184
|
-
var [mutationObserver] = useState(() => new MutationObserver(callback));
|
|
3185
|
-
useIsomorphicLayoutEffect(() => {
|
|
3186
|
-
// Discard mutations caused during render phase. This works due to react calling
|
|
3187
|
-
// useLayoutEffect synchronously after the render phase before the next tick.
|
|
3188
|
-
mutationObserver.takeRecords();
|
|
3189
|
-
});
|
|
3190
|
-
useEffect(() => {
|
|
3191
3062
|
if (!node.current) {
|
|
3192
3063
|
throw new Error('Failed to attach MutationObserver, `node` is undefined');
|
|
3193
3064
|
}
|
|
3194
3065
|
|
|
3195
|
-
mutationObserver.observe(node.current,
|
|
3196
|
-
|
|
3197
|
-
}, [mutationObserver, node, options]);
|
|
3198
|
-
}
|
|
3066
|
+
(_this$mutationObserve = this.mutationObserver) === null || _this$mutationObserve === void 0 ? void 0 : _this$mutationObserve.observe(node.current, MUTATION_OBSERVER_CONFIG);
|
|
3067
|
+
}
|
|
3199
3068
|
|
|
3200
|
-
|
|
3069
|
+
componentDidMount() {
|
|
3070
|
+
var {
|
|
3071
|
+
receivedUserInput
|
|
3072
|
+
} = this.props;
|
|
3073
|
+
var editor = this.context;
|
|
3074
|
+
this.manager = createRestoreDomManager(editor, receivedUserInput);
|
|
3075
|
+
this.mutationObserver = new MutationObserver(this.manager.registerMutations);
|
|
3076
|
+
this.observe();
|
|
3077
|
+
}
|
|
3201
3078
|
|
|
3202
|
-
|
|
3079
|
+
getSnapshotBeforeUpdate() {
|
|
3080
|
+
var _this$mutationObserve2, _this$mutationObserve3, _this$manager2;
|
|
3203
3081
|
|
|
3204
|
-
|
|
3205
|
-
var MUTATION_OBSERVER_CONFIG = {
|
|
3206
|
-
subtree: true,
|
|
3207
|
-
childList: true,
|
|
3208
|
-
characterData: true
|
|
3209
|
-
};
|
|
3210
|
-
var useAndroidInputManager = !IS_ANDROID ? () => null : _ref => {
|
|
3211
|
-
var {
|
|
3212
|
-
node
|
|
3213
|
-
} = _ref,
|
|
3214
|
-
options = _objectWithoutProperties(_ref, _excluded$2);
|
|
3082
|
+
var pendingMutations = (_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 ? void 0 : _this$mutationObserve2.takeRecords();
|
|
3215
3083
|
|
|
3216
|
-
|
|
3084
|
+
if (pendingMutations !== null && pendingMutations !== void 0 && pendingMutations.length) {
|
|
3085
|
+
var _this$manager;
|
|
3086
|
+
|
|
3087
|
+
(_this$manager = this.manager) === null || _this$manager === void 0 ? void 0 : _this$manager.registerMutations(pendingMutations);
|
|
3088
|
+
}
|
|
3089
|
+
|
|
3090
|
+
(_this$mutationObserve3 = this.mutationObserver) === null || _this$mutationObserve3 === void 0 ? void 0 : _this$mutationObserve3.disconnect();
|
|
3091
|
+
(_this$manager2 = this.manager) === null || _this$manager2 === void 0 ? void 0 : _this$manager2.restoreDOM();
|
|
3217
3092
|
return null;
|
|
3218
3093
|
}
|
|
3219
3094
|
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
var [inputManager] = useState(() => createAndroidInputManager(_objectSpread$2({
|
|
3223
|
-
editor
|
|
3224
|
-
}, options)));
|
|
3225
|
-
useMutationObserver(node, inputManager.handleDomMutations, MUTATION_OBSERVER_CONFIG);
|
|
3226
|
-
EDITOR_TO_SCHEDULE_FLUSH.set(editor, inputManager.scheduleFlush);
|
|
3095
|
+
componentDidUpdate() {
|
|
3096
|
+
var _this$manager3;
|
|
3227
3097
|
|
|
3228
|
-
|
|
3229
|
-
|
|
3098
|
+
(_this$manager3 = this.manager) === null || _this$manager3 === void 0 ? void 0 : _this$manager3.clear();
|
|
3099
|
+
this.observe();
|
|
3230
3100
|
}
|
|
3231
3101
|
|
|
3232
|
-
|
|
3233
|
-
|
|
3102
|
+
componentWillUnmount() {
|
|
3103
|
+
var _this$mutationObserve4;
|
|
3234
3104
|
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
return;
|
|
3242
|
-
}
|
|
3105
|
+
(_this$mutationObserve4 = this.mutationObserver) === null || _this$mutationObserve4 === void 0 ? void 0 : _this$mutationObserve4.disconnect();
|
|
3106
|
+
}
|
|
3107
|
+
|
|
3108
|
+
render() {
|
|
3109
|
+
return this.props.children;
|
|
3110
|
+
}
|
|
3243
3111
|
|
|
3244
|
-
receivedUserInput.current = true;
|
|
3245
|
-
var window = ReactEditor.getWindow(editor);
|
|
3246
|
-
window.cancelAnimationFrame(animationFrameIdRef.current);
|
|
3247
|
-
animationFrameIdRef.current = window.requestAnimationFrame(() => {
|
|
3248
|
-
receivedUserInput.current = false;
|
|
3249
|
-
});
|
|
3250
|
-
}, [editor]);
|
|
3251
|
-
useEffect(() => () => cancelAnimationFrame(animationFrameIdRef.current), []);
|
|
3252
|
-
return {
|
|
3253
|
-
receivedUserInput,
|
|
3254
|
-
onUserInput
|
|
3255
|
-
};
|
|
3256
3112
|
}
|
|
3257
3113
|
|
|
3114
|
+
RestoreDOMComponent.contextType = EditorContext;
|
|
3115
|
+
var RestoreDOM = IS_ANDROID ? RestoreDOMComponent : _ref => {
|
|
3116
|
+
var {
|
|
3117
|
+
children
|
|
3118
|
+
} = _ref;
|
|
3119
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, children);
|
|
3120
|
+
};
|
|
3121
|
+
|
|
3258
3122
|
var _excluded$1 = ["autoFocus", "decorate", "onDOMBeforeInput", "placeholder", "readOnly", "renderElement", "renderLeaf", "renderPlaceholder", "scrollSelectionIntoView", "style", "as", "disableDefaultStyles"],
|
|
3259
3123
|
_excluded2 = ["text"];
|
|
3260
3124
|
|