slate-react 0.71.0 → 0.71.1-20211141648

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/index.js CHANGED
@@ -319,7 +319,7 @@ var IS_FOCUSED = new WeakMap();
319
319
  */
320
320
 
321
321
  var EDITOR_TO_ON_CHANGE = new WeakMap();
322
- var EDITOR_TO_RESTORE_DOM = new WeakMap();
322
+ var NODE_TO_RESTORE_DOM = new WeakMap();
323
323
  /**
324
324
  * Symbols.
325
325
  */
@@ -476,6 +476,42 @@ var isDecoratorRangeListEqual = function isDecoratorRangeListEqual(list, another
476
476
  return true;
477
477
  };
478
478
 
479
+ function useContentKey(node) {
480
+ var contentKeyRef = React.useRef(0);
481
+ var updateAnimationFrameRef = React.useRef(null);
482
+
483
+ var _useState = React.useState(0),
484
+ _useState2 = _slicedToArray(_useState, 2),
485
+ setForceRerenderCounter = _useState2[1];
486
+
487
+ React.useEffect(function () {
488
+ NODE_TO_RESTORE_DOM.set(node, function () {
489
+ // Update is already queued and node hasn't re-render yet
490
+ if (updateAnimationFrameRef.current) {
491
+ return;
492
+ }
493
+
494
+ updateAnimationFrameRef.current = requestAnimationFrame(function () {
495
+ setForceRerenderCounter(function (state) {
496
+ return state + 1;
497
+ });
498
+ updateAnimationFrameRef.current = null;
499
+ });
500
+ contentKeyRef.current++;
501
+ });
502
+ return function () {
503
+ NODE_TO_RESTORE_DOM["delete"](node);
504
+ };
505
+ }, [node]); // Node was restored => clear scheduled update
506
+
507
+ if (updateAnimationFrameRef.current) {
508
+ cancelAnimationFrame(updateAnimationFrameRef.current);
509
+ updateAnimationFrameRef.current = null;
510
+ }
511
+
512
+ return contentKeyRef.current;
513
+ }
514
+
479
515
  /**
480
516
  * Text.
481
517
  */
@@ -519,9 +555,11 @@ var Text = function Text(props) {
519
555
  NODE_TO_ELEMENT["delete"](text);
520
556
  }
521
557
  });
558
+ var contentKey = IS_ANDROID ? useContentKey(text) : undefined;
522
559
  return /*#__PURE__*/React__default['default'].createElement("span", {
523
560
  "data-slate-node": "text",
524
- ref: ref
561
+ ref: ref,
562
+ key: contentKey
525
563
  }, children);
526
564
  };
527
565
 
@@ -625,11 +663,20 @@ var Element = function Element(props) {
625
663
  NODE_TO_ELEMENT["delete"](element);
626
664
  }
627
665
  });
628
- return renderElement({
666
+ var content = renderElement({
629
667
  attributes: attributes,
630
668
  children: children,
631
669
  element: element
632
670
  });
671
+
672
+ if (IS_ANDROID) {
673
+ var contentKey = useContentKey(element);
674
+ return /*#__PURE__*/React__default['default'].createElement(React.Fragment, {
675
+ key: contentKey
676
+ }, content);
677
+ }
678
+
679
+ return content;
633
680
  };
634
681
 
635
682
  var MemoizedElement = /*#__PURE__*/React__default['default'].memo(Element, function (prev, next) {
@@ -3268,19 +3315,6 @@ var isRemoveLeafNodes = function isRemoveLeafNodes(_, _ref7) {
3268
3315
  return removedNodes.length > 0 && addedNodes.length === 0 && characterDataMutations.length > 0;
3269
3316
  };
3270
3317
 
3271
- function restoreDOM(editor) {
3272
- try {
3273
- var onRestoreDOM = EDITOR_TO_RESTORE_DOM.get(editor);
3274
-
3275
- if (onRestoreDOM) {
3276
- onRestoreDOM();
3277
- }
3278
- } catch (err) {
3279
- // eslint-disable-next-line no-console
3280
- console.error(err);
3281
- }
3282
- }
3283
-
3284
3318
  function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
3285
3319
 
3286
3320
  function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen); }
@@ -3311,15 +3345,17 @@ function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) {
3311
3345
  * - Line breaks
3312
3346
  *
3313
3347
  * @param editor
3348
+ * @param restoreDOM
3314
3349
  */
3315
3350
 
3316
3351
 
3317
- var AndroidInputManager = function AndroidInputManager(editor) {
3352
+ var AndroidInputManager = function AndroidInputManager(editor, restoreDOM) {
3318
3353
  var _this = this;
3319
3354
 
3320
3355
  _classCallCheck(this, AndroidInputManager);
3321
3356
 
3322
3357
  this.editor = editor;
3358
+ this.restoreDOM = restoreDOM;
3323
3359
  /**
3324
3360
  * Handle MutationObserver flush
3325
3361
  *
@@ -3334,7 +3370,7 @@ var AndroidInputManager = function AndroidInputManager(editor) {
3334
3370
  // eslint-disable-next-line no-console
3335
3371
  console.error(err); // Failed to reconcile mutations, restore DOM to its previous state
3336
3372
 
3337
- restoreDOM(_this.editor);
3373
+ _this.restoreDOM();
3338
3374
  }
3339
3375
  };
3340
3376
  /**
@@ -3402,10 +3438,9 @@ var AndroidInputManager = function AndroidInputManager(editor) {
3402
3438
 
3403
3439
  this.insertBreak = function () {
3404
3440
  var selection = _this.editor.selection;
3405
- slate.Editor.insertBreak(_this.editor); // To-do: Need a more granular solution to restoring only a specific portion
3406
- // of the document. Restoring the entire document is expensive.
3441
+ slate.Editor.insertBreak(_this.editor);
3407
3442
 
3408
- restoreDOM(_this.editor);
3443
+ _this.restoreDOM();
3409
3444
 
3410
3445
  if (selection) {
3411
3446
  // Compat: Move selection to the newly inserted block if it has not moved
@@ -3430,7 +3465,7 @@ var AndroidInputManager = function AndroidInputManager(editor) {
3430
3465
  slate.Editor.insertText(_this.editor, text);
3431
3466
  }
3432
3467
 
3433
- restoreDOM(_this.editor);
3468
+ _this.restoreDOM();
3434
3469
  };
3435
3470
  /**
3436
3471
  * Handle `backspace` that merges blocks
@@ -3440,7 +3475,8 @@ var AndroidInputManager = function AndroidInputManager(editor) {
3440
3475
  this.deleteBackward = function () {
3441
3476
  slate.Editor.deleteBackward(_this.editor);
3442
3477
  ReactEditor.focus(_this.editor);
3443
- restoreDOM(_this.editor);
3478
+
3479
+ _this.restoreDOM();
3444
3480
  };
3445
3481
  /**
3446
3482
  * Handle mutations that remove specific leaves
@@ -3461,7 +3497,8 @@ var AndroidInputManager = function AndroidInputManager(editor) {
3461
3497
  slate.Transforms["delete"](_this.editor, {
3462
3498
  at: path
3463
3499
  });
3464
- restoreDOM(_this.editor);
3500
+
3501
+ _this.restoreDOM();
3465
3502
  }
3466
3503
  }
3467
3504
  } catch (err) {
@@ -3472,6 +3509,7 @@ var AndroidInputManager = function AndroidInputManager(editor) {
3472
3509
  };
3473
3510
 
3474
3511
  this.editor = editor;
3512
+ this.restoreDOM = restoreDOM;
3475
3513
  };
3476
3514
 
3477
3515
  function useMutationObserver(node, callback, options) {
@@ -3497,6 +3535,72 @@ function useMutationObserver(node, callback, options) {
3497
3535
  });
3498
3536
  }
3499
3537
 
3538
+ var MUTATION_OBSERVER_CONFIG$1 = {
3539
+ childList: true,
3540
+ characterData: true,
3541
+ subtree: true
3542
+ };
3543
+
3544
+ function findClosestKnowSlateNode(domNode) {
3545
+ var _domEl;
3546
+
3547
+ var domEl = isDOMElement(domNode) ? domNode : domNode.parentElement;
3548
+
3549
+ if (domEl && !domEl.hasAttribute('data-slate-node')) {
3550
+ domEl = domEl.closest("[data-slate-node]");
3551
+ }
3552
+
3553
+ var slateNode = domEl && ELEMENT_TO_NODE.get(domEl);
3554
+
3555
+ if (slateNode) {
3556
+ return slateNode;
3557
+ } // Unknown dom element with a slate-slate-node attribute => the IME
3558
+ // most likely duplicated the node so we have to restore the parent
3559
+
3560
+
3561
+ return (_domEl = domEl) !== null && _domEl !== void 0 && _domEl.parentElement ? findClosestKnowSlateNode(domEl.parentElement) : null;
3562
+ }
3563
+
3564
+ function useRestoreDom(node, receivedUserInput) {
3565
+ var editor = useSlateStatic();
3566
+ var mutatedNodes = React.useRef(new Set());
3567
+ var handleDOMMutation = React.useCallback(function (mutations) {
3568
+ if (!receivedUserInput.current) {
3569
+ return;
3570
+ }
3571
+
3572
+ mutations.forEach(function (_ref) {
3573
+ var target = _ref.target;
3574
+ var slateNode = findClosestKnowSlateNode(target);
3575
+
3576
+ if (!slateNode) {
3577
+ return;
3578
+ }
3579
+
3580
+ return mutatedNodes.current.add(slateNode);
3581
+ });
3582
+ }, []);
3583
+ useMutationObserver(node, handleDOMMutation, MUTATION_OBSERVER_CONFIG$1); // Clear mutated nodes on every render
3584
+
3585
+ mutatedNodes.current.clear();
3586
+ var restore = React.useCallback(function () {
3587
+ var mutated = Array.from(mutatedNodes.current.values()); // Filter out child nodes of nodes that will be restored anyway
3588
+
3589
+ var nodesToRestore = mutated.filter(function (n) {
3590
+ return !mutated.some(function (m) {
3591
+ return slate.Path.isParent(ReactEditor.findPath(editor, m), ReactEditor.findPath(editor, n));
3592
+ });
3593
+ });
3594
+ nodesToRestore.forEach(function (n) {
3595
+ var _NODE_TO_RESTORE_DOM$;
3596
+
3597
+ (_NODE_TO_RESTORE_DOM$ = NODE_TO_RESTORE_DOM.get(n)) === null || _NODE_TO_RESTORE_DOM$ === void 0 ? void 0 : _NODE_TO_RESTORE_DOM$();
3598
+ });
3599
+ mutatedNodes.current.clear();
3600
+ }, []);
3601
+ return restore;
3602
+ }
3603
+
3500
3604
  function useTrackUserInput() {
3501
3605
  var editor = useSlateStatic();
3502
3606
  var receivedUserInput = React.useRef(false);
@@ -3537,16 +3641,14 @@ var MUTATION_OBSERVER_CONFIG = {
3537
3641
  function useAndroidInputManager(node) {
3538
3642
  var editor = useSlateStatic();
3539
3643
 
3540
- var _useState = React.useState(function () {
3541
- return new AndroidInputManager(editor);
3542
- }),
3543
- _useState2 = _slicedToArray(_useState, 1),
3544
- inputManager = _useState2[0];
3545
-
3546
3644
  var _useTrackUserInput = useTrackUserInput(),
3547
3645
  receivedUserInput = _useTrackUserInput.receivedUserInput,
3548
3646
  onUserInput = _useTrackUserInput.onUserInput;
3549
3647
 
3648
+ var restoreDom = useRestoreDom(node, receivedUserInput);
3649
+ var inputManager = React.useMemo(function () {
3650
+ return new AndroidInputManager(editor, restoreDom);
3651
+ }, [restoreDom, editor]);
3550
3652
  var timeoutId = React.useRef(null);
3551
3653
  var isReconciling = React.useRef(false);
3552
3654
  var flush = React.useCallback(function (mutations) {
@@ -3614,17 +3716,7 @@ var AndroidEditable = function AndroidEditable(props) {
3614
3716
  latestElement: null
3615
3717
  };
3616
3718
  }, []);
3617
-
3618
- var _useState = React.useState(0),
3619
- _useState2 = _slicedToArray(_useState, 2),
3620
- contentKey = _useState2[0],
3621
- setContentKey = _useState2[1];
3622
-
3623
- var onRestoreDOM = React.useCallback(function () {
3624
- setContentKey(function (prev) {
3625
- return prev + 1;
3626
- });
3627
- }, [contentKey]); // Whenever the editor updates...
3719
+ var contentKey = useContentKey(editor); // Whenever the editor updates...
3628
3720
 
3629
3721
  useIsomorphicLayoutEffect(function () {
3630
3722
  // Update element-related weak maps with the DOM element ref.
@@ -3635,10 +3727,8 @@ var AndroidEditable = function AndroidEditable(props) {
3635
3727
  EDITOR_TO_ELEMENT.set(editor, ref.current);
3636
3728
  NODE_TO_ELEMENT.set(editor, ref.current);
3637
3729
  ELEMENT_TO_NODE.set(ref.current, editor);
3638
- EDITOR_TO_RESTORE_DOM.set(editor, onRestoreDOM);
3639
3730
  } else {
3640
3731
  NODE_TO_ELEMENT["delete"](editor);
3641
- EDITOR_TO_RESTORE_DOM["delete"](editor);
3642
3732
  }
3643
3733
 
3644
3734
  try {