slate-react 0.115.0 → 0.116.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.
Files changed (50) hide show
  1. package/dist/chunking/children-helper.d.ts +61 -0
  2. package/dist/chunking/children-helper.d.ts.map +1 -0
  3. package/dist/chunking/chunk-tree-helper.d.ts +160 -0
  4. package/dist/chunking/chunk-tree-helper.d.ts.map +1 -0
  5. package/dist/chunking/get-chunk-tree-for-node.d.ts +16 -0
  6. package/dist/chunking/get-chunk-tree-for-node.d.ts.map +1 -0
  7. package/dist/chunking/index.d.ts +3 -0
  8. package/dist/chunking/index.d.ts.map +1 -0
  9. package/dist/chunking/reconcile-children.d.ts +19 -0
  10. package/dist/chunking/reconcile-children.d.ts.map +1 -0
  11. package/dist/chunking/types.d.ts +44 -0
  12. package/dist/chunking/types.d.ts.map +1 -0
  13. package/dist/components/chunk-tree.d.ts +13 -0
  14. package/dist/components/chunk-tree.d.ts.map +1 -0
  15. package/dist/components/editable.d.ts +13 -0
  16. package/dist/components/editable.d.ts.map +1 -1
  17. package/dist/components/element.d.ts +4 -4
  18. package/dist/components/element.d.ts.map +1 -1
  19. package/dist/components/leaf.d.ts.map +1 -1
  20. package/dist/components/slate.d.ts.map +1 -1
  21. package/dist/components/text.d.ts +1 -1
  22. package/dist/components/text.d.ts.map +1 -1
  23. package/dist/hooks/use-children.d.ts +4 -4
  24. package/dist/hooks/use-children.d.ts.map +1 -1
  25. package/dist/hooks/use-decorations.d.ts +18 -0
  26. package/dist/hooks/use-decorations.d.ts.map +1 -0
  27. package/dist/hooks/use-element.d.ts +12 -0
  28. package/dist/hooks/use-element.d.ts.map +1 -0
  29. package/dist/hooks/use-generic-selector.d.ts +20 -0
  30. package/dist/hooks/use-generic-selector.d.ts.map +1 -0
  31. package/dist/hooks/use-selected.d.ts +0 -5
  32. package/dist/hooks/use-selected.d.ts.map +1 -1
  33. package/dist/hooks/use-slate-selector.d.ts +30 -15
  34. package/dist/hooks/use-slate-selector.d.ts.map +1 -1
  35. package/dist/hooks/use-slate.d.ts +7 -14
  36. package/dist/hooks/use-slate.d.ts.map +1 -1
  37. package/dist/index.d.ts +2 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.es.js +1154 -232
  40. package/dist/index.es.js.map +1 -1
  41. package/dist/index.js +1328 -343
  42. package/dist/index.js.map +1 -1
  43. package/dist/plugin/react-editor.d.ts +7 -0
  44. package/dist/plugin/react-editor.d.ts.map +1 -1
  45. package/dist/plugin/with-react.d.ts.map +1 -1
  46. package/dist/slate-react.js +1385 -346
  47. package/dist/slate-react.min.js +1 -1
  48. package/package.json +5 -4
  49. package/dist/hooks/use-decorate.d.ts +0 -11
  50. package/dist/hooks/use-decorate.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -224,8 +224,8 @@ var useSlateStatic = function useSlateStatic() {
224
224
  // eslint-disable-next-line no-redeclare
225
225
  var ReactEditor = slateDom.DOMEditor;
226
226
 
227
- function ownKeys$6(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
228
- function _objectSpread$6(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$6(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$6(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
227
+ function ownKeys$7(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
228
+ function _objectSpread$7(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$7(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$7(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
229
229
  // https://github.com/facebook/draft-js/blob/main/src/component/handlers/composition/DraftEditorCompositionHandler.js#L41
230
230
  // When using keyboard English association function, conpositionEnd triggered too fast, resulting in after `insertText` still maintain association state.
231
231
  var RESOLVE_DELAY = 25;
@@ -421,7 +421,7 @@ function createAndroidInputManager(_ref) {
421
421
  updatePlaceholderVisibility();
422
422
  return;
423
423
  }
424
- pendingDiffs[idx] = _objectSpread$6(_objectSpread$6({}, pendingDiffs[idx]), {}, {
424
+ pendingDiffs[idx] = _objectSpread$7(_objectSpread$7({}, pendingDiffs[idx]), {}, {
425
425
  diff: merged
426
426
  });
427
427
  };
@@ -776,7 +776,7 @@ function createAndroidInputManager(_ref) {
776
776
  if (insertPositionHint === null) {
777
777
  insertPositionHint = _diff;
778
778
  } else if (insertPositionHint && slate.Range.isCollapsed(targetRange) && insertPositionHint.end + insertPositionHint.text.length === _start2.offset) {
779
- insertPositionHint = _objectSpread$6(_objectSpread$6({}, insertPositionHint), {}, {
779
+ insertPositionHint = _objectSpread$7(_objectSpread$7({}, insertPositionHint), {}, {
780
780
  text: insertPositionHint.text + _text
781
781
  });
782
782
  } else {
@@ -920,8 +920,8 @@ function useMutationObserver(node, callback, options) {
920
920
  }
921
921
 
922
922
  var _excluded$2 = ["node"];
923
- function ownKeys$5(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
924
- function _objectSpread$5(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$5(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$5(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
923
+ function ownKeys$6(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
924
+ function _objectSpread$6(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$6(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$6(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
925
925
  var MUTATION_OBSERVER_CONFIG$1 = {
926
926
  subtree: true,
927
927
  childList: true,
@@ -938,7 +938,7 @@ var useAndroidInputManager = !slateDom.IS_ANDROID ? function () {
938
938
  var editor = useSlateStatic();
939
939
  var isMounted = useIsMounted();
940
940
  var _useState = React.useState(function () {
941
- return createAndroidInputManager(_objectSpread$5({
941
+ return createAndroidInputManager(_objectSpread$6({
942
942
  editor: editor
943
943
  }, options));
944
944
  }),
@@ -952,8 +952,8 @@ var useAndroidInputManager = !slateDom.IS_ANDROID ? function () {
952
952
  return inputManager;
953
953
  };
954
954
 
955
- function ownKeys$4(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
956
- function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$4(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$4(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
955
+ function ownKeys$5(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
956
+ function _objectSpread$5(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$5(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$5(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
957
957
  /**
958
958
  * Leaf content strings.
959
959
  */
@@ -1070,11 +1070,11 @@ var ZeroWidthString = function ZeroWidthString(props) {
1070
1070
  // be because accepting an IME suggestion when at the start of a block (no
1071
1071
  // preceding \uFEFF) removes one or more DOM elements that `toSlateRange`
1072
1072
  // depends on. (https://github.com/ianstormtaylor/slate/issues/5703)
1073
- return /*#__PURE__*/React.createElement("span", _objectSpread$4({}, attributes), !slateDom.IS_ANDROID || !isLineBreak ? "\uFEFF" : null, isLineBreak ? /*#__PURE__*/React.createElement("br", null) : null);
1073
+ return /*#__PURE__*/React.createElement("span", _objectSpread$5({}, attributes), !slateDom.IS_ANDROID || !isLineBreak ? "\uFEFF" : null, isLineBreak ? /*#__PURE__*/React.createElement("br", null) : null);
1074
1074
  };
1075
1075
 
1076
- function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1077
- function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1076
+ function ownKeys$4(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1077
+ function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$4(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$4(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1078
1078
  // Delay the placeholder on Android to prevent the keyboard from closing.
1079
1079
  // (https://github.com/ianstormtaylor/slate/pull/5368)
1080
1080
  var PLACEHOLDER_DELAY = slateDom.IS_ANDROID ? 300 : 0;
@@ -1092,6 +1092,9 @@ function clearTimeoutRef(timeoutRef) {
1092
1092
  timeoutRef.current = null;
1093
1093
  }
1094
1094
  }
1095
+ var defaultRenderLeaf = function defaultRenderLeaf(props) {
1096
+ return /*#__PURE__*/React.createElement(DefaultLeaf, _objectSpread$4({}, props));
1097
+ };
1095
1098
  /**
1096
1099
  * Individual leaves in a text node with unique formatting.
1097
1100
  */
@@ -1102,9 +1105,7 @@ var Leaf = function Leaf(props) {
1102
1105
  parent = props.parent,
1103
1106
  renderPlaceholder = props.renderPlaceholder,
1104
1107
  _props$renderLeaf = props.renderLeaf,
1105
- renderLeaf = _props$renderLeaf === void 0 ? function (props) {
1106
- return /*#__PURE__*/React.createElement(DefaultLeaf, _objectSpread$3({}, props));
1107
- } : _props$renderLeaf,
1108
+ renderLeaf = _props$renderLeaf === void 0 ? defaultRenderLeaf : _props$renderLeaf,
1108
1109
  leafPosition = props.leafPosition;
1109
1110
  var editor = useSlateStatic();
1110
1111
  var placeholderResizeObserver = React.useRef(null);
@@ -1202,27 +1203,198 @@ var MemoizedLeaf = /*#__PURE__*/React.memo(Leaf, function (prev, next) {
1202
1203
  var DefaultLeaf = function DefaultLeaf(props) {
1203
1204
  var attributes = props.attributes,
1204
1205
  children = props.children;
1205
- return /*#__PURE__*/React.createElement("span", _objectSpread$3({}, attributes), children);
1206
+ return /*#__PURE__*/React.createElement("span", _objectSpread$4({}, attributes), children);
1206
1207
  };
1207
1208
 
1208
- function ownKeys$2(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1209
- function _objectSpread$2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$2(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$2(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1209
+ var arrayWithoutHoles = createCommonjsModule(function (module) {
1210
+ function _arrayWithoutHoles(arr) {
1211
+ if (Array.isArray(arr)) return arrayLikeToArray(arr);
1212
+ }
1213
+ module.exports = _arrayWithoutHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;
1214
+ });
1215
+
1216
+ unwrapExports(arrayWithoutHoles);
1217
+
1218
+ var iterableToArray = createCommonjsModule(function (module) {
1219
+ function _iterableToArray(iter) {
1220
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
1221
+ }
1222
+ module.exports = _iterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
1223
+ });
1224
+
1225
+ unwrapExports(iterableToArray);
1226
+
1227
+ var nonIterableSpread = createCommonjsModule(function (module) {
1228
+ function _nonIterableSpread() {
1229
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1230
+ }
1231
+ module.exports = _nonIterableSpread, module.exports.__esModule = true, module.exports["default"] = module.exports;
1232
+ });
1233
+
1234
+ unwrapExports(nonIterableSpread);
1235
+
1236
+ var toConsumableArray = createCommonjsModule(function (module) {
1237
+ function _toConsumableArray(arr) {
1238
+ return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();
1239
+ }
1240
+ module.exports = _toConsumableArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
1241
+ });
1242
+
1243
+ var _toConsumableArray = unwrapExports(toConsumableArray);
1244
+
1245
+ /**
1246
+ * Create a selector that updates when an `update` function is called, and
1247
+ * which only causes the component to render when the result of `selector`
1248
+ * differs from the previous result according to `equalityFn`.
1249
+ *
1250
+ * If `selector` is memoized using `useCallback`, then it will only be called
1251
+ * when it changes or when `update` is called. Otherwise, `selector` will be
1252
+ * called every time the component renders.
1253
+ *
1254
+ * @example
1255
+ * const [state, update] = useGenericSelector(selector, equalityFn)
1256
+ *
1257
+ * useIsomorphicLayoutEffect(() => {
1258
+ * return addEventListener(update)
1259
+ * }, [addEventListener, update])
1260
+ *
1261
+ * return state
1262
+ */
1263
+ function useGenericSelector(selector, equalityFn) {
1264
+ var _useReducer = React.useReducer(function (s) {
1265
+ return s + 1;
1266
+ }, 0),
1267
+ _useReducer2 = _slicedToArray(_useReducer, 2),
1268
+ forceRender = _useReducer2[1];
1269
+ var latestSubscriptionCallbackError = React.useRef();
1270
+ var latestSelector = React.useRef(function () {
1271
+ return null;
1272
+ });
1273
+ var latestSelectedState = React.useRef(null);
1274
+ var selectedState;
1275
+ try {
1276
+ if (selector !== latestSelector.current || latestSubscriptionCallbackError.current) {
1277
+ var selectorResult = selector();
1278
+ if (equalityFn(latestSelectedState.current, selectorResult)) {
1279
+ selectedState = latestSelectedState.current;
1280
+ } else {
1281
+ selectedState = selectorResult;
1282
+ }
1283
+ } else {
1284
+ selectedState = latestSelectedState.current;
1285
+ }
1286
+ } catch (err) {
1287
+ if (latestSubscriptionCallbackError.current && isError(err)) {
1288
+ err.message += "\nThe error may be correlated with this previous error:\n".concat(latestSubscriptionCallbackError.current.stack, "\n\n");
1289
+ }
1290
+ throw err;
1291
+ }
1292
+ latestSelector.current = selector;
1293
+ latestSelectedState.current = selectedState;
1294
+ latestSubscriptionCallbackError.current = undefined;
1295
+ var update = React.useCallback(function () {
1296
+ try {
1297
+ var newSelectedState = latestSelector.current();
1298
+ if (equalityFn(latestSelectedState.current, newSelectedState)) {
1299
+ return;
1300
+ }
1301
+ latestSelectedState.current = newSelectedState;
1302
+ } catch (err) {
1303
+ // we ignore all errors here, since when the component
1304
+ // is re-rendered, the selectors are called again, and
1305
+ // will throw again, if neither props nor store state
1306
+ // changed
1307
+ if (err instanceof Error) {
1308
+ latestSubscriptionCallbackError.current = err;
1309
+ } else {
1310
+ latestSubscriptionCallbackError.current = new Error(String(err));
1311
+ }
1312
+ }
1313
+ forceRender();
1314
+ // don't rerender on equalityFn change since we want to be able to define it inline
1315
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1316
+ }, []);
1317
+ return [selectedState, update];
1318
+ }
1319
+ function isError(error) {
1320
+ return error instanceof Error;
1321
+ }
1322
+
1323
+ /**
1324
+ * A React context for sharing the `decorate` prop of the editable and
1325
+ * subscribing to changes on this prop.
1326
+ */
1327
+ var DecorateContext = /*#__PURE__*/React.createContext({});
1328
+ var useDecorations = function useDecorations(node, parentDecorations) {
1329
+ var editor = useSlateStatic();
1330
+ var _useContext = React.useContext(DecorateContext),
1331
+ decorate = _useContext.decorate,
1332
+ addEventListener = _useContext.addEventListener;
1333
+ // Not memoized since we want nodes to be decorated on each render
1334
+ var selector = function selector() {
1335
+ var path = ReactEditor.findPath(editor, node);
1336
+ return decorate([node, path]);
1337
+ };
1338
+ var equalityFn = slate.Text.isText(node) ? slateDom.isTextDecorationsEqual : slateDom.isElementDecorationsEqual;
1339
+ var _useGenericSelector = useGenericSelector(selector, equalityFn),
1340
+ _useGenericSelector2 = _slicedToArray(_useGenericSelector, 2),
1341
+ decorations = _useGenericSelector2[0],
1342
+ update = _useGenericSelector2[1];
1343
+ useIsomorphicLayoutEffect(function () {
1344
+ var unsubscribe = addEventListener(update);
1345
+ update();
1346
+ return unsubscribe;
1347
+ }, [addEventListener, update]);
1348
+ return React.useMemo(function () {
1349
+ return [].concat(_toConsumableArray(decorations), _toConsumableArray(parentDecorations));
1350
+ }, [decorations, parentDecorations]);
1351
+ };
1352
+ var useDecorateContext = function useDecorateContext(decorateProp) {
1353
+ var eventListeners = React.useRef(new Set());
1354
+ var latestDecorate = React.useRef(decorateProp);
1355
+ useIsomorphicLayoutEffect(function () {
1356
+ latestDecorate.current = decorateProp;
1357
+ eventListeners.current.forEach(function (listener) {
1358
+ return listener();
1359
+ });
1360
+ }, [decorateProp]);
1361
+ var decorate = React.useCallback(function (entry) {
1362
+ return latestDecorate.current(entry);
1363
+ }, []);
1364
+ var addEventListener = React.useCallback(function (callback) {
1365
+ eventListeners.current.add(callback);
1366
+ return function () {
1367
+ eventListeners.current["delete"](callback);
1368
+ };
1369
+ }, []);
1370
+ return React.useMemo(function () {
1371
+ return {
1372
+ decorate: decorate,
1373
+ addEventListener: addEventListener
1374
+ };
1375
+ }, [decorate, addEventListener]);
1376
+ };
1377
+
1378
+ function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1379
+ function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1380
+ var defaultRenderText = function defaultRenderText(props) {
1381
+ return /*#__PURE__*/React.createElement(DefaultText, _objectSpread$3({}, props));
1382
+ };
1210
1383
  /**
1211
1384
  * Text.
1212
1385
  */
1213
1386
  var Text = function Text(props) {
1214
- var decorations = props.decorations,
1387
+ var parentDecorations = props.decorations,
1215
1388
  isLast = props.isLast,
1216
1389
  parent = props.parent,
1217
1390
  renderPlaceholder = props.renderPlaceholder,
1218
1391
  renderLeaf = props.renderLeaf,
1219
1392
  _props$renderText = props.renderText,
1220
- renderText = _props$renderText === void 0 ? function (props) {
1221
- return /*#__PURE__*/React.createElement(DefaultText, _objectSpread$2({}, props));
1222
- } : _props$renderText,
1393
+ renderText = _props$renderText === void 0 ? defaultRenderText : _props$renderText,
1223
1394
  text = props.text;
1224
1395
  var editor = useSlateStatic();
1225
1396
  var ref = React.useRef(null);
1397
+ var decorations = useDecorations(text, parentDecorations);
1226
1398
  var decoratedLeaves = slate.Text.decorations(text, decorations);
1227
1399
  var key = ReactEditor.findKey(editor, text);
1228
1400
  var children = [];
@@ -1273,28 +1445,30 @@ var MemoizedText = /*#__PURE__*/React.memo(Text, function (prev, next) {
1273
1445
  var DefaultText = function DefaultText(props) {
1274
1446
  var attributes = props.attributes,
1275
1447
  children = props.children;
1276
- return /*#__PURE__*/React.createElement("span", _objectSpread$2({}, attributes), children);
1448
+ return /*#__PURE__*/React.createElement("span", _objectSpread$3({}, attributes), children);
1277
1449
  };
1278
1450
 
1279
- function ownKeys$1(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1280
- function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$1(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$1(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1451
+ function ownKeys$2(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1452
+ function _objectSpread$2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$2(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$2(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1453
+ var defaultRenderElement = function defaultRenderElement(props) {
1454
+ return /*#__PURE__*/React.createElement(DefaultElement, _objectSpread$2({}, props));
1455
+ };
1281
1456
  /**
1282
1457
  * Element.
1283
1458
  */
1284
1459
  var Element = function Element(props) {
1285
- var decorations = props.decorations,
1460
+ var parentDecorations = props.decorations,
1286
1461
  element = props.element,
1287
1462
  _props$renderElement = props.renderElement,
1288
- renderElement = _props$renderElement === void 0 ? function (p) {
1289
- return /*#__PURE__*/React.createElement(DefaultElement, _objectSpread$1({}, p));
1290
- } : _props$renderElement,
1463
+ renderElement = _props$renderElement === void 0 ? defaultRenderElement : _props$renderElement,
1464
+ renderChunk = props.renderChunk,
1291
1465
  renderPlaceholder = props.renderPlaceholder,
1292
1466
  renderLeaf = props.renderLeaf,
1293
- renderText = props.renderText,
1294
- selection = props.selection;
1467
+ renderText = props.renderText;
1295
1468
  var editor = useSlateStatic();
1296
1469
  var readOnly = useReadOnly();
1297
1470
  var isInline = editor.isInline(element);
1471
+ var decorations = useDecorations(element, parentDecorations);
1298
1472
  var key = ReactEditor.findKey(editor, element);
1299
1473
  var ref = React.useCallback(function (ref) {
1300
1474
  // Update element-related weak maps with the DOM element ref.
@@ -1312,10 +1486,10 @@ var Element = function Element(props) {
1312
1486
  decorations: decorations,
1313
1487
  node: element,
1314
1488
  renderElement: renderElement,
1489
+ renderChunk: renderChunk,
1315
1490
  renderPlaceholder: renderPlaceholder,
1316
1491
  renderLeaf: renderLeaf,
1317
- renderText: renderText,
1318
- selection: selection
1492
+ renderText: renderText
1319
1493
  });
1320
1494
  // Attributes that the developer must mix into the element in their
1321
1495
  // custom node renderer component.
@@ -1371,7 +1545,7 @@ var Element = function Element(props) {
1371
1545
  });
1372
1546
  };
1373
1547
  var MemoizedElement = /*#__PURE__*/React.memo(Element, function (prev, next) {
1374
- return prev.element === next.element && prev.renderElement === next.renderElement && prev.renderText === next.renderText && prev.renderLeaf === next.renderLeaf && prev.renderPlaceholder === next.renderPlaceholder && slateDom.isElementDecorationsEqual(prev.decorations, next.decorations) && (prev.selection === next.selection || !!prev.selection && !!next.selection && slate.Range.equals(prev.selection, next.selection));
1548
+ return prev.element === next.element && prev.renderElement === next.renderElement && prev.renderChunk === next.renderChunk && prev.renderText === next.renderText && prev.renderLeaf === next.renderLeaf && prev.renderPlaceholder === next.renderPlaceholder && slateDom.isElementDecorationsEqual(prev.decorations, next.decorations);
1375
1549
  });
1376
1550
  /**
1377
1551
  * The default element renderer.
@@ -1382,40 +1556,830 @@ var DefaultElement = function DefaultElement(props) {
1382
1556
  element = props.element;
1383
1557
  var editor = useSlateStatic();
1384
1558
  var Tag = editor.isInline(element) ? 'span' : 'div';
1385
- return /*#__PURE__*/React.createElement(Tag, _objectSpread$1(_objectSpread$1({}, attributes), {}, {
1559
+ return /*#__PURE__*/React.createElement(Tag, _objectSpread$2(_objectSpread$2({}, attributes), {}, {
1386
1560
  style: {
1387
1561
  position: 'relative'
1388
1562
  }
1389
1563
  }), children);
1390
1564
  };
1391
1565
 
1566
+ var classCallCheck = createCommonjsModule(function (module) {
1567
+ function _classCallCheck(instance, Constructor) {
1568
+ if (!(instance instanceof Constructor)) {
1569
+ throw new TypeError("Cannot call a class as a function");
1570
+ }
1571
+ }
1572
+ module.exports = _classCallCheck, module.exports.__esModule = true, module.exports["default"] = module.exports;
1573
+ });
1574
+
1575
+ var _classCallCheck = unwrapExports(classCallCheck);
1576
+
1577
+ var createClass = createCommonjsModule(function (module) {
1578
+ function _defineProperties(target, props) {
1579
+ for (var i = 0; i < props.length; i++) {
1580
+ var descriptor = props[i];
1581
+ descriptor.enumerable = descriptor.enumerable || false;
1582
+ descriptor.configurable = true;
1583
+ if ("value" in descriptor) descriptor.writable = true;
1584
+ Object.defineProperty(target, toPropertyKey(descriptor.key), descriptor);
1585
+ }
1586
+ }
1587
+ function _createClass(Constructor, protoProps, staticProps) {
1588
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
1589
+ if (staticProps) _defineProperties(Constructor, staticProps);
1590
+ Object.defineProperty(Constructor, "prototype", {
1591
+ writable: false
1592
+ });
1593
+ return Constructor;
1594
+ }
1595
+ module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports;
1596
+ });
1597
+
1598
+ var _createClass = unwrapExports(createClass);
1599
+
1392
1600
  /**
1393
- * A React context for sharing the `decorate` prop of the editable.
1601
+ * Traverse and modify a chunk tree
1394
1602
  */
1395
- var DecorateContext = /*#__PURE__*/React.createContext(function () {
1396
- return [];
1397
- });
1603
+ var ChunkTreeHelper = /*#__PURE__*/function () {
1604
+ function ChunkTreeHelper(chunkTree, _ref) {
1605
+ var chunkSize = _ref.chunkSize,
1606
+ debug = _ref.debug;
1607
+ _classCallCheck(this, ChunkTreeHelper);
1608
+ /**
1609
+ * The root of the chunk tree
1610
+ */
1611
+ _defineProperty(this, "root", void 0);
1612
+ /**
1613
+ * The ideal size of a chunk
1614
+ */
1615
+ _defineProperty(this, "chunkSize", void 0);
1616
+ /**
1617
+ * Whether debug mode is enabled
1618
+ *
1619
+ * If enabled, the pointer state will be checked for internal consistency
1620
+ * after each mutating operation.
1621
+ */
1622
+ _defineProperty(this, "debug", void 0);
1623
+ /**
1624
+ * Whether the traversal has reached the end of the chunk tree
1625
+ *
1626
+ * When this is true, the pointerChunk and pointerIndex point to the last
1627
+ * top-level node in the chunk tree, although pointerNode returns null.
1628
+ */
1629
+ _defineProperty(this, "reachedEnd", void 0);
1630
+ /**
1631
+ * The chunk containing the current node
1632
+ */
1633
+ _defineProperty(this, "pointerChunk", void 0);
1634
+ /**
1635
+ * The index of the current node within pointerChunk
1636
+ *
1637
+ * Can be -1 to indicate that the pointer is before the start of the tree.
1638
+ */
1639
+ _defineProperty(this, "pointerIndex", void 0);
1640
+ /**
1641
+ * Similar to a Slate path; tracks the path of pointerChunk relative to the
1642
+ * root.
1643
+ *
1644
+ * Used to move the pointer from the current chunk to the parent chunk more
1645
+ * efficiently.
1646
+ */
1647
+ _defineProperty(this, "pointerIndexStack", void 0);
1648
+ /**
1649
+ * Indexing the current chunk's children has a slight time cost, which adds up
1650
+ * when traversing very large trees, so the current node is cached.
1651
+ *
1652
+ * A value of undefined means that the current node is not cached. This
1653
+ * property must be set to undefined whenever the pointer is moved, unless
1654
+ * the pointer is guaranteed to point to the same node that it did previously.
1655
+ */
1656
+ _defineProperty(this, "cachedPointerNode", void 0);
1657
+ this.root = chunkTree;
1658
+ this.chunkSize = chunkSize;
1659
+ // istanbul ignore next
1660
+ this.debug = debug !== null && debug !== void 0 ? debug : false;
1661
+ this.pointerChunk = chunkTree;
1662
+ this.pointerIndex = -1;
1663
+ this.pointerIndexStack = [];
1664
+ this.reachedEnd = false;
1665
+ this.validateState();
1666
+ }
1667
+ /**
1668
+ * Move the pointer to the next leaf in the chunk tree
1669
+ */
1670
+ _createClass(ChunkTreeHelper, [{
1671
+ key: "readLeaf",
1672
+ value: function readLeaf() {
1673
+ // istanbul ignore next
1674
+ if (this.reachedEnd) return null;
1675
+ // Get the next sibling or aunt node
1676
+ while (true) {
1677
+ if (this.pointerIndex + 1 < this.pointerSiblings.length) {
1678
+ this.pointerIndex++;
1679
+ this.cachedPointerNode = undefined;
1680
+ break;
1681
+ } else if (this.pointerChunk.type === 'root') {
1682
+ this.reachedEnd = true;
1683
+ return null;
1684
+ } else {
1685
+ this.exitChunk();
1686
+ }
1687
+ }
1688
+ this.validateState();
1689
+ // If the next sibling or aunt is a chunk, descend into it
1690
+ this.enterChunkUntilLeaf(false);
1691
+ return this.pointerNode;
1692
+ }
1693
+ /**
1694
+ * Move the pointer to the previous leaf in the chunk tree
1695
+ */
1696
+ }, {
1697
+ key: "returnToPreviousLeaf",
1698
+ value: function returnToPreviousLeaf() {
1699
+ // If we were at the end of the tree, descend into the end of the last
1700
+ // chunk in the tree
1701
+ if (this.reachedEnd) {
1702
+ this.reachedEnd = false;
1703
+ this.enterChunkUntilLeaf(true);
1704
+ return;
1705
+ }
1706
+ // Get the previous sibling or aunt node
1707
+ while (true) {
1708
+ if (this.pointerIndex >= 1) {
1709
+ this.pointerIndex--;
1710
+ this.cachedPointerNode = undefined;
1711
+ break;
1712
+ } else if (this.pointerChunk.type === 'root') {
1713
+ this.pointerIndex = -1;
1714
+ return;
1715
+ } else {
1716
+ this.exitChunk();
1717
+ }
1718
+ }
1719
+ this.validateState();
1720
+ // If the previous sibling or aunt is a chunk, descend into it
1721
+ this.enterChunkUntilLeaf(true);
1722
+ }
1723
+ /**
1724
+ * Insert leaves before the current leaf, leaving the pointer unchanged
1725
+ */
1726
+ }, {
1727
+ key: "insertBefore",
1728
+ value: function insertBefore(leaves) {
1729
+ this.returnToPreviousLeaf();
1730
+ this.insertAfter(leaves);
1731
+ this.readLeaf();
1732
+ }
1733
+ /**
1734
+ * Insert leaves after the current leaf, leaving the pointer on the last
1735
+ * inserted leaf
1736
+ *
1737
+ * The insertion algorithm first checks for any chunk we're currently at the
1738
+ * end of that can receive additional leaves. Next, it tries to insert leaves
1739
+ * at the starts of any subsequent chunks.
1740
+ *
1741
+ * Any remaining leaves are passed to rawInsertAfter to be chunked and
1742
+ * inserted at the highest possible level.
1743
+ */
1744
+ }, {
1745
+ key: "insertAfter",
1746
+ value: function insertAfter(leaves) {
1747
+ // istanbul ignore next
1748
+ if (leaves.length === 0) return;
1749
+ var beforeDepth = 0;
1750
+ var afterDepth = 0;
1751
+ // While at the end of a chunk, insert any leaves that will fit, and then
1752
+ // exit the chunk
1753
+ while (this.pointerChunk.type === 'chunk' && this.pointerIndex === this.pointerSiblings.length - 1) {
1754
+ var remainingCapacity = this.chunkSize - this.pointerSiblings.length;
1755
+ var toInsertCount = Math.min(remainingCapacity, leaves.length);
1756
+ if (toInsertCount > 0) {
1757
+ var leavesToInsert = leaves.splice(0, toInsertCount);
1758
+ this.rawInsertAfter(leavesToInsert, beforeDepth);
1759
+ }
1760
+ this.exitChunk();
1761
+ beforeDepth++;
1762
+ }
1763
+ if (leaves.length === 0) return;
1764
+ // Save the pointer so that we can come back here after inserting leaves
1765
+ // into the starts of subsequent blocks
1766
+ var rawInsertPointer = this.savePointer();
1767
+ // If leaves are inserted into the start of a subsequent block, then we
1768
+ // eventually need to restore the pointer to the last such inserted leaf
1769
+ var finalPointer = null;
1770
+ // Move the pointer into the chunk containing the next leaf, if it exists
1771
+ if (this.readLeaf()) {
1772
+ // While at the start of a chunk, insert any leaves that will fit, and
1773
+ // then exit the chunk
1774
+ while (this.pointerChunk.type === 'chunk' && this.pointerIndex === 0) {
1775
+ var _remainingCapacity = this.chunkSize - this.pointerSiblings.length;
1776
+ var _toInsertCount = Math.min(_remainingCapacity, leaves.length);
1777
+ if (_toInsertCount > 0) {
1778
+ var _leavesToInsert = leaves.splice(-_toInsertCount, _toInsertCount);
1779
+ // Insert the leaves at the start of the chunk
1780
+ this.pointerIndex = -1;
1781
+ this.cachedPointerNode = undefined;
1782
+ this.rawInsertAfter(_leavesToInsert, afterDepth);
1783
+ // If this is the first batch of insertions at the start of a
1784
+ // subsequent chunk, set the final pointer to the last inserted leaf
1785
+ if (!finalPointer) {
1786
+ finalPointer = this.savePointer();
1787
+ }
1788
+ }
1789
+ this.exitChunk();
1790
+ afterDepth++;
1791
+ }
1792
+ }
1793
+ this.restorePointer(rawInsertPointer);
1794
+ // If there are leaves left to insert, insert them between the end of the
1795
+ // previous chunk and the start of the first subsequent chunk, or wherever
1796
+ // the pointer ended up after the first batch of insertions
1797
+ var minDepth = Math.max(beforeDepth, afterDepth);
1798
+ this.rawInsertAfter(leaves, minDepth);
1799
+ if (finalPointer) {
1800
+ this.restorePointer(finalPointer);
1801
+ }
1802
+ this.validateState();
1803
+ }
1804
+ /**
1805
+ * Remove the current node and decrement the pointer, deleting any ancestor
1806
+ * chunk that becomes empty as a result
1807
+ */
1808
+ }, {
1809
+ key: "remove",
1810
+ value: function remove() {
1811
+ this.pointerSiblings.splice(this.pointerIndex--, 1);
1812
+ this.cachedPointerNode = undefined;
1813
+ if (this.pointerSiblings.length === 0 && this.pointerChunk.type === 'chunk') {
1814
+ this.exitChunk();
1815
+ this.remove();
1816
+ } else {
1817
+ this.invalidateChunk();
1818
+ }
1819
+ this.validateState();
1820
+ }
1821
+ /**
1822
+ * Add the current chunk and all ancestor chunks to the list of modified
1823
+ * chunks
1824
+ */
1825
+ }, {
1826
+ key: "invalidateChunk",
1827
+ value: function invalidateChunk() {
1828
+ for (var c = this.pointerChunk; c.type === 'chunk'; c = c.parent) {
1829
+ this.root.modifiedChunks.add(c);
1830
+ }
1831
+ }
1832
+ /**
1833
+ * Whether the pointer is at the start of the tree
1834
+ */
1835
+ }, {
1836
+ key: "atStart",
1837
+ get: function get() {
1838
+ return this.pointerChunk.type === 'root' && this.pointerIndex === -1;
1839
+ }
1840
+ /**
1841
+ * The siblings of the current node
1842
+ */
1843
+ }, {
1844
+ key: "pointerSiblings",
1845
+ get: function get() {
1846
+ return this.pointerChunk.children;
1847
+ }
1848
+ /**
1849
+ * Get the current node (uncached)
1850
+ *
1851
+ * If the pointer is at the start or end of the document, returns null.
1852
+ *
1853
+ * Usually, the current node is a chunk leaf, although it can be a chunk
1854
+ * while insertions are in progress.
1855
+ */
1856
+ }, {
1857
+ key: "getPointerNode",
1858
+ value: function getPointerNode() {
1859
+ if (this.reachedEnd || this.pointerIndex === -1) {
1860
+ return null;
1861
+ }
1862
+ return this.pointerSiblings[this.pointerIndex];
1863
+ }
1864
+ /**
1865
+ * Cached getter for the current node
1866
+ */
1867
+ }, {
1868
+ key: "pointerNode",
1869
+ get: function get() {
1870
+ if (this.cachedPointerNode !== undefined) return this.cachedPointerNode;
1871
+ var pointerNode = this.getPointerNode();
1872
+ this.cachedPointerNode = pointerNode;
1873
+ return pointerNode;
1874
+ }
1875
+ /**
1876
+ * Get the path of a chunk relative to the root, returning null if the chunk
1877
+ * is not connected to the root
1878
+ */
1879
+ }, {
1880
+ key: "getChunkPath",
1881
+ value: function getChunkPath(chunk) {
1882
+ var path = [];
1883
+ for (var c = chunk; c.type === 'chunk'; c = c.parent) {
1884
+ var index = c.parent.children.indexOf(c);
1885
+ // istanbul ignore next
1886
+ if (index === -1) {
1887
+ return null;
1888
+ }
1889
+ path.unshift(index);
1890
+ }
1891
+ return path;
1892
+ }
1893
+ /**
1894
+ * Save the current pointer to be restored later
1895
+ */
1896
+ }, {
1897
+ key: "savePointer",
1898
+ value: function savePointer() {
1899
+ if (this.atStart) return 'start';
1900
+ // istanbul ignore next
1901
+ if (!this.pointerNode) {
1902
+ throw new Error('Cannot save pointer when pointerNode is null');
1903
+ }
1904
+ return {
1905
+ chunk: this.pointerChunk,
1906
+ node: this.pointerNode
1907
+ };
1908
+ }
1909
+ /**
1910
+ * Restore the pointer to a previous state
1911
+ */
1912
+ }, {
1913
+ key: "restorePointer",
1914
+ value: function restorePointer(savedPointer) {
1915
+ if (savedPointer === 'start') {
1916
+ this.pointerChunk = this.root;
1917
+ this.pointerIndex = -1;
1918
+ this.pointerIndexStack = [];
1919
+ this.reachedEnd = false;
1920
+ this.cachedPointerNode = undefined;
1921
+ return;
1922
+ }
1923
+ // Since nodes may have been inserted or removed prior to the saved
1924
+ // pointer since it was saved, the index and index stack must be
1925
+ // recomputed. This is slow, but this is fine since restoring a pointer is
1926
+ // not a frequent operation.
1927
+ var chunk = savedPointer.chunk,
1928
+ node = savedPointer.node;
1929
+ var index = chunk.children.indexOf(node);
1930
+ // istanbul ignore next
1931
+ if (index === -1) {
1932
+ throw new Error('Cannot restore point because saved node is no longer in saved chunk');
1933
+ }
1934
+ var indexStack = this.getChunkPath(chunk);
1935
+ // istanbul ignore next
1936
+ if (!indexStack) {
1937
+ throw new Error('Cannot restore point because saved chunk is no longer connected to root');
1938
+ }
1939
+ this.pointerChunk = chunk;
1940
+ this.pointerIndex = index;
1941
+ this.pointerIndexStack = indexStack;
1942
+ this.reachedEnd = false;
1943
+ this.cachedPointerNode = node;
1944
+ this.validateState();
1945
+ }
1946
+ /**
1947
+ * Assuming the current node is a chunk, move the pointer into that chunk
1948
+ *
1949
+ * @param end If true, place the pointer on the last node of the chunk.
1950
+ * Otherwise, place the pointer on the first node.
1951
+ */
1952
+ }, {
1953
+ key: "enterChunk",
1954
+ value: function enterChunk(end) {
1955
+ var _this$pointerNode;
1956
+ // istanbul ignore next
1957
+ if (((_this$pointerNode = this.pointerNode) === null || _this$pointerNode === void 0 ? void 0 : _this$pointerNode.type) !== 'chunk') {
1958
+ throw new Error('Cannot enter non-chunk');
1959
+ }
1960
+ this.pointerIndexStack.push(this.pointerIndex);
1961
+ this.pointerChunk = this.pointerNode;
1962
+ this.pointerIndex = end ? this.pointerSiblings.length - 1 : 0;
1963
+ this.cachedPointerNode = undefined;
1964
+ this.validateState();
1965
+ // istanbul ignore next
1966
+ if (this.pointerChunk.children.length === 0) {
1967
+ throw new Error('Cannot enter empty chunk');
1968
+ }
1969
+ }
1970
+ /**
1971
+ * Assuming the current node is a chunk, move the pointer into that chunk
1972
+ * repeatedly until the current node is a leaf
1973
+ *
1974
+ * @param end If true, place the pointer on the last node of the chunk.
1975
+ * Otherwise, place the pointer on the first node.
1976
+ */
1977
+ }, {
1978
+ key: "enterChunkUntilLeaf",
1979
+ value: function enterChunkUntilLeaf(end) {
1980
+ while (((_this$pointerNode2 = this.pointerNode) === null || _this$pointerNode2 === void 0 ? void 0 : _this$pointerNode2.type) === 'chunk') {
1981
+ var _this$pointerNode2;
1982
+ this.enterChunk(end);
1983
+ }
1984
+ }
1985
+ /**
1986
+ * Move the pointer to the parent chunk
1987
+ */
1988
+ }, {
1989
+ key: "exitChunk",
1990
+ value: function exitChunk() {
1991
+ // istanbul ignore next
1992
+ if (this.pointerChunk.type === 'root') {
1993
+ throw new Error('Cannot exit root');
1994
+ }
1995
+ var previousPointerChunk = this.pointerChunk;
1996
+ this.pointerChunk = previousPointerChunk.parent;
1997
+ this.pointerIndex = this.pointerIndexStack.pop();
1998
+ this.cachedPointerNode = undefined;
1999
+ this.validateState();
2000
+ }
2001
+ /**
2002
+ * Insert leaves immediately after the current node, leaving the pointer on
2003
+ * the last inserted leaf
2004
+ *
2005
+ * Leaves are chunked according to the number of nodes already in the parent
2006
+ * plus the number of nodes being inserted, or the minimum depth if larger
2007
+ */
2008
+ }, {
2009
+ key: "rawInsertAfter",
2010
+ value: function rawInsertAfter(leaves, minDepth) {
2011
+ var _this = this,
2012
+ _this$pointerSiblings;
2013
+ if (leaves.length === 0) return;
2014
+ var groupIntoChunks = function groupIntoChunks(leaves, parent, perChunk) {
2015
+ if (perChunk === 1) return leaves;
2016
+ var chunks = [];
2017
+ for (var i = 0; i < _this.chunkSize; i++) {
2018
+ var chunkNodes = leaves.slice(i * perChunk, (i + 1) * perChunk);
2019
+ if (chunkNodes.length === 0) break;
2020
+ var chunk = {
2021
+ type: 'chunk',
2022
+ key: new slateDom.Key(),
2023
+ parent: parent,
2024
+ children: []
2025
+ };
2026
+ chunk.children = groupIntoChunks(chunkNodes, chunk, perChunk / _this.chunkSize);
2027
+ chunks.push(chunk);
2028
+ }
2029
+ return chunks;
2030
+ };
2031
+ // Determine the chunking depth based on the number of existing nodes in
2032
+ // the chunk and the number of nodes being inserted
2033
+ var newTotal = this.pointerSiblings.length + leaves.length;
2034
+ var depthForTotal = 0;
2035
+ for (var i = this.chunkSize; i < newTotal; i *= this.chunkSize) {
2036
+ depthForTotal++;
2037
+ }
2038
+ // A depth of 0 means no chunking
2039
+ var depth = Math.max(depthForTotal, minDepth);
2040
+ var perTopLevelChunk = Math.pow(this.chunkSize, depth);
2041
+ var chunks = groupIntoChunks(leaves, this.pointerChunk, perTopLevelChunk);
2042
+ (_this$pointerSiblings = this.pointerSiblings).splice.apply(_this$pointerSiblings, [this.pointerIndex + 1, 0].concat(_toConsumableArray(chunks)));
2043
+ this.pointerIndex += chunks.length;
2044
+ this.cachedPointerNode = undefined;
2045
+ this.invalidateChunk();
2046
+ this.validateState();
2047
+ }
2048
+ /**
2049
+ * If debug mode is enabled, ensure that the state is internally consistent
2050
+ */
2051
+ // istanbul ignore next
2052
+ }, {
2053
+ key: "validateState",
2054
+ value: function validateState() {
2055
+ if (!this.debug) return;
2056
+ var validateDescendant = function validateDescendant(node) {
2057
+ if (node.type === 'chunk') {
2058
+ var parent = node.parent,
2059
+ children = node.children;
2060
+ if (!parent.children.includes(node)) {
2061
+ throw new Error("Debug: Chunk ".concat(node.key.id, " has an incorrect parent property"));
2062
+ }
2063
+ children.forEach(validateDescendant);
2064
+ }
2065
+ };
2066
+ this.root.children.forEach(validateDescendant);
2067
+ if (this.cachedPointerNode !== undefined && this.cachedPointerNode !== this.getPointerNode()) {
2068
+ throw new Error('Debug: The cached pointer is incorrect and has not been invalidated');
2069
+ }
2070
+ var actualIndexStack = this.getChunkPath(this.pointerChunk);
2071
+ if (!actualIndexStack) {
2072
+ throw new Error('Debug: The pointer chunk is not connected to the root');
2073
+ }
2074
+ if (!slate.Path.equals(this.pointerIndexStack, actualIndexStack)) {
2075
+ throw new Error("Debug: The cached index stack [".concat(this.pointerIndexStack.join(', '), "] does not match the path of the pointer chunk [").concat(actualIndexStack.join(', '), "]"));
2076
+ }
2077
+ }
2078
+ }]);
2079
+ return ChunkTreeHelper;
2080
+ }();
2081
+
2082
+ /**
2083
+ * Traverse an array of children, providing helpers useful for reconciling the
2084
+ * children array with a chunk tree
2085
+ */
2086
+ var ChildrenHelper = /*#__PURE__*/function () {
2087
+ function ChildrenHelper(editor, children) {
2088
+ _classCallCheck(this, ChildrenHelper);
2089
+ _defineProperty(this, "editor", void 0);
2090
+ _defineProperty(this, "children", void 0);
2091
+ /**
2092
+ * Sparse array of Slate node keys, each index corresponding to an index in
2093
+ * the children array
2094
+ *
2095
+ * Fetching the key for a Slate node is expensive, so we cache them here.
2096
+ */
2097
+ _defineProperty(this, "cachedKeys", void 0);
2098
+ /**
2099
+ * The index of the next node to be read in the children array
2100
+ */
2101
+ _defineProperty(this, "pointerIndex", void 0);
2102
+ this.editor = editor;
2103
+ this.children = children;
2104
+ this.cachedKeys = new Array(children.length);
2105
+ this.pointerIndex = 0;
2106
+ }
2107
+ /**
2108
+ * Read a given number of nodes, advancing the pointer by that amount
2109
+ */
2110
+ _createClass(ChildrenHelper, [{
2111
+ key: "read",
2112
+ value: function read(n) {
2113
+ // PERF: If only one child was requested (the most common case), use array
2114
+ // indexing instead of slice
2115
+ if (n === 1) {
2116
+ return [this.children[this.pointerIndex++]];
2117
+ }
2118
+ var slicedChildren = this.remaining(n);
2119
+ this.pointerIndex += n;
2120
+ return slicedChildren;
2121
+ }
2122
+ /**
2123
+ * Get the remaining children without advancing the pointer
2124
+ *
2125
+ * @param [maxChildren] Limit the number of children returned.
2126
+ */
2127
+ }, {
2128
+ key: "remaining",
2129
+ value: function remaining(maxChildren) {
2130
+ if (maxChildren === undefined) {
2131
+ return this.children.slice(this.pointerIndex);
2132
+ }
2133
+ return this.children.slice(this.pointerIndex, this.pointerIndex + maxChildren);
2134
+ }
2135
+ /**
2136
+ * Whether all children have been read
2137
+ */
2138
+ }, {
2139
+ key: "reachedEnd",
2140
+ get: function get() {
2141
+ return this.pointerIndex >= this.children.length;
2142
+ }
2143
+ /**
2144
+ * Determine whether a node with a given key appears in the unread part of the
2145
+ * children array, and return its index relative to the current pointer if so
2146
+ *
2147
+ * Searching for the node object itself using indexOf is most efficient, but
2148
+ * will fail to locate nodes that have been modified. In this case, nodes
2149
+ * should be identified by their keys instead.
2150
+ *
2151
+ * Searching an array of keys using indexOf is very inefficient since fetching
2152
+ * the keys for all children in advance is very slow. Insead, if the node
2153
+ * search fails to return a value, fetch the keys of each remaining child one
2154
+ * by one and compare it to the known key.
2155
+ */
2156
+ }, {
2157
+ key: "lookAhead",
2158
+ value: function lookAhead(node, key) {
2159
+ var elementResult = this.children.indexOf(node, this.pointerIndex);
2160
+ if (elementResult > -1) return elementResult - this.pointerIndex;
2161
+ for (var i = this.pointerIndex; i < this.children.length; i++) {
2162
+ var candidateNode = this.children[i];
2163
+ var candidateKey = this.findKey(candidateNode, i);
2164
+ if (candidateKey === key) return i - this.pointerIndex;
2165
+ }
2166
+ return -1;
2167
+ }
2168
+ /**
2169
+ * Convert an array of Slate nodes to an array of chunk leaves, each
2170
+ * containing the node and its key
2171
+ */
2172
+ }, {
2173
+ key: "toChunkLeaves",
2174
+ value: function toChunkLeaves(nodes, startIndex) {
2175
+ var _this = this;
2176
+ return nodes.map(function (node, i) {
2177
+ return {
2178
+ type: 'leaf',
2179
+ node: node,
2180
+ key: _this.findKey(node, startIndex + i),
2181
+ index: startIndex + i
2182
+ };
2183
+ });
2184
+ }
2185
+ /**
2186
+ * Get the key for a Slate node, cached using the node's index
2187
+ */
2188
+ }, {
2189
+ key: "findKey",
2190
+ value: function findKey(node, index) {
2191
+ var cachedKey = this.cachedKeys[index];
2192
+ if (cachedKey) return cachedKey;
2193
+ var key = ReactEditor.findKey(this.editor, node);
2194
+ this.cachedKeys[index] = key;
2195
+ return key;
2196
+ }
2197
+ }]);
2198
+ return ChildrenHelper;
2199
+ }();
2200
+
1398
2201
  /**
1399
- * Get the current `decorate` prop of the editable.
2202
+ * Update the chunk tree to match the children array, inserting, removing and
2203
+ * updating differing nodes
1400
2204
  */
1401
- var useDecorate = function useDecorate() {
1402
- return React.useContext(DecorateContext);
2205
+ var reconcileChildren = function reconcileChildren(editor, _ref) {
2206
+ var chunkTree = _ref.chunkTree,
2207
+ children = _ref.children,
2208
+ chunkSize = _ref.chunkSize,
2209
+ _ref$rerenderChildren = _ref.rerenderChildren,
2210
+ rerenderChildren = _ref$rerenderChildren === void 0 ? [] : _ref$rerenderChildren,
2211
+ onInsert = _ref.onInsert,
2212
+ onUpdate = _ref.onUpdate,
2213
+ onIndexChange = _ref.onIndexChange,
2214
+ debug = _ref.debug;
2215
+ chunkTree.modifiedChunks.clear();
2216
+ var chunkTreeHelper = new ChunkTreeHelper(chunkTree, {
2217
+ chunkSize: chunkSize,
2218
+ debug: debug
2219
+ });
2220
+ var childrenHelper = new ChildrenHelper(editor, children);
2221
+ var treeLeaf;
2222
+ // Read leaves from the tree one by one, each one representing a single Slate
2223
+ // node. Each leaf from the tree is compared to the current node in the
2224
+ // children array to determine whether nodes have been inserted, removed or
2225
+ // updated.
2226
+ var _loop = function _loop() {
2227
+ // Check where the tree node appears in the children array. In the most
2228
+ // common case (where no insertions or removals have occurred), this will be
2229
+ // 0. If the node has been removed, this will be -1. If new nodes have been
2230
+ // inserted before the node, or if the node has been moved to a later
2231
+ // position in the same children array, this will be a positive number.
2232
+ var lookAhead = childrenHelper.lookAhead(treeLeaf.node, treeLeaf.key);
2233
+ // If the node was moved, we want to remove it and insert it later, rather
2234
+ // then re-inserting all intermediate nodes before it.
2235
+ var wasMoved = lookAhead > 0 && chunkTree.movedNodeKeys.has(treeLeaf.key);
2236
+ // If the tree leaf was moved or removed, remove it
2237
+ if (lookAhead === -1 || wasMoved) {
2238
+ chunkTreeHelper.remove();
2239
+ return 1; // continue
2240
+ }
2241
+ // Get the matching Slate node and any nodes that may have been inserted
2242
+ // prior to it. Insert these into the chunk tree.
2243
+ var insertedChildrenStartIndex = childrenHelper.pointerIndex;
2244
+ var insertedChildren = childrenHelper.read(lookAhead + 1);
2245
+ var matchingChild = insertedChildren.pop();
2246
+ if (insertedChildren.length) {
2247
+ var _leavesToInsert = childrenHelper.toChunkLeaves(insertedChildren, insertedChildrenStartIndex);
2248
+ chunkTreeHelper.insertBefore(_leavesToInsert);
2249
+ insertedChildren.forEach(function (node, relativeIndex) {
2250
+ onInsert === null || onInsert === void 0 || onInsert(node, insertedChildrenStartIndex + relativeIndex);
2251
+ });
2252
+ }
2253
+ var matchingChildIndex = childrenHelper.pointerIndex - 1;
2254
+ // Make sure the chunk tree contains the most recent version of the Slate
2255
+ // node
2256
+ if (treeLeaf.node !== matchingChild) {
2257
+ treeLeaf.node = matchingChild;
2258
+ chunkTreeHelper.invalidateChunk();
2259
+ onUpdate === null || onUpdate === void 0 || onUpdate(matchingChild, matchingChildIndex);
2260
+ }
2261
+ // Update the index if it has changed
2262
+ if (treeLeaf.index !== matchingChildIndex) {
2263
+ treeLeaf.index = matchingChildIndex;
2264
+ onIndexChange === null || onIndexChange === void 0 || onIndexChange(matchingChild, matchingChildIndex);
2265
+ }
2266
+ // Manually invalidate chunks containing specific children that we want to
2267
+ // re-render
2268
+ if (rerenderChildren.includes(matchingChildIndex)) {
2269
+ chunkTreeHelper.invalidateChunk();
2270
+ }
2271
+ };
2272
+ while (treeLeaf = chunkTreeHelper.readLeaf()) {
2273
+ if (_loop()) continue;
2274
+ }
2275
+ // If there are still Slate nodes remaining from the children array that were
2276
+ // not matched to nodes in the tree, insert them at the end of the tree
2277
+ if (!childrenHelper.reachedEnd) {
2278
+ var remainingChildren = childrenHelper.remaining();
2279
+ var leavesToInsert = childrenHelper.toChunkLeaves(remainingChildren, childrenHelper.pointerIndex);
2280
+ // Move the pointer back to the final leaf in the tree, or the start of the
2281
+ // tree if the tree is currently empty
2282
+ chunkTreeHelper.returnToPreviousLeaf();
2283
+ chunkTreeHelper.insertAfter(leavesToInsert);
2284
+ remainingChildren.forEach(function (node, relativeIndex) {
2285
+ onInsert === null || onInsert === void 0 || onInsert(node, childrenHelper.pointerIndex + relativeIndex);
2286
+ });
2287
+ }
2288
+ chunkTree.movedNodeKeys.clear();
1403
2289
  };
1404
2290
 
2291
+ function ownKeys$1(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2292
+ function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$1(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$1(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2293
+ var KEY_TO_CHUNK_TREE = new WeakMap();
1405
2294
  /**
1406
- * A React context for sharing the `selected` state of an element.
2295
+ * Get or create the chunk tree for a Slate node
2296
+ *
2297
+ * If the reconcile option is provided, the chunk tree will be updated to
2298
+ * match the current children of the node. The children are chunked
2299
+ * automatically using the given chunk size.
1407
2300
  */
1408
- var SelectedContext = /*#__PURE__*/React.createContext(false);
2301
+ var getChunkTreeForNode = function getChunkTreeForNode(editor, node) {
2302
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
2303
+ var key = ReactEditor.findKey(editor, node);
2304
+ var chunkTree = KEY_TO_CHUNK_TREE.get(key);
2305
+ if (!chunkTree) {
2306
+ chunkTree = {
2307
+ type: 'root',
2308
+ movedNodeKeys: new Set(),
2309
+ modifiedChunks: new Set(),
2310
+ children: []
2311
+ };
2312
+ KEY_TO_CHUNK_TREE.set(key, chunkTree);
2313
+ }
2314
+ if (options.reconcile) {
2315
+ reconcileChildren(editor, _objectSpread$1({
2316
+ chunkTree: chunkTree,
2317
+ children: node.children
2318
+ }, options.reconcile));
2319
+ }
2320
+ return chunkTree;
2321
+ };
2322
+
2323
+ var defaultRenderChunk = function defaultRenderChunk(_ref) {
2324
+ var children = _ref.children;
2325
+ return children;
2326
+ };
2327
+ var ChunkAncestor = function ChunkAncestor(props) {
2328
+ var root = props.root,
2329
+ ancestor = props.ancestor,
2330
+ renderElement = props.renderElement,
2331
+ _props$renderChunk = props.renderChunk,
2332
+ renderChunk = _props$renderChunk === void 0 ? defaultRenderChunk : _props$renderChunk;
2333
+ return ancestor.children.map(function (chunkNode) {
2334
+ if (chunkNode.type === 'chunk') {
2335
+ var key = chunkNode.key.id;
2336
+ var renderedChunk = renderChunk({
2337
+ highest: ancestor === root,
2338
+ lowest: chunkNode.children.some(function (c) {
2339
+ return c.type === 'leaf';
2340
+ }),
2341
+ attributes: {
2342
+ 'data-slate-chunk': true
2343
+ },
2344
+ children: /*#__PURE__*/React.createElement(MemoizedChunk, {
2345
+ root: root,
2346
+ ancestor: chunkNode,
2347
+ renderElement: renderElement,
2348
+ renderChunk: renderChunk
2349
+ })
2350
+ });
2351
+ return /*#__PURE__*/React.createElement(React.Fragment, {
2352
+ key: key
2353
+ }, renderedChunk);
2354
+ }
2355
+ // Only blocks containing no inlines are chunked
2356
+ var element = chunkNode.node;
2357
+ return renderElement(element, chunkNode.index, chunkNode.key);
2358
+ });
2359
+ };
2360
+ var ChunkTree = ChunkAncestor;
2361
+ var MemoizedChunk = /*#__PURE__*/React.memo(ChunkAncestor, function (prev, next) {
2362
+ return prev.root === next.root && prev.renderElement === next.renderElement && prev.renderChunk === next.renderChunk && !next.root.modifiedChunks.has(next.ancestor);
2363
+ });
2364
+
2365
+ var ElementContext = /*#__PURE__*/React.createContext(null);
1409
2366
  /**
1410
- * Get the current `selected` state of an element.
2367
+ * Get the current element.
1411
2368
  */
1412
- var useSelected = function useSelected() {
1413
- return React.useContext(SelectedContext);
2369
+ var useElement = function useElement() {
2370
+ var context = React.useContext(ElementContext);
2371
+ if (!context) {
2372
+ throw new Error('The `useElement` hook must be used inside `renderElement`.');
2373
+ }
2374
+ return context;
2375
+ };
2376
+ /**
2377
+ * Get the current element, or return null if not inside `renderElement`.
2378
+ */
2379
+ var useElementIf = function useElementIf() {
2380
+ return React.useContext(ElementContext);
1414
2381
  };
1415
2382
 
1416
- 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; } } }; }
1417
- 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); }
1418
- function _arrayLikeToArray$1(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
1419
2383
  /**
1420
2384
  * Children.
1421
2385
  */
@@ -1423,68 +2387,113 @@ var useChildren = function useChildren(props) {
1423
2387
  var decorations = props.decorations,
1424
2388
  node = props.node,
1425
2389
  renderElement = props.renderElement,
2390
+ renderChunk = props.renderChunk,
1426
2391
  renderPlaceholder = props.renderPlaceholder,
1427
2392
  renderText = props.renderText,
1428
- renderLeaf = props.renderLeaf,
1429
- selection = props.selection;
1430
- var decorate = useDecorate();
2393
+ renderLeaf = props.renderLeaf;
1431
2394
  var editor = useSlateStatic();
1432
2395
  slateDom.IS_NODE_MAP_DIRTY.set(editor, false);
1433
- var path = ReactEditor.findPath(editor, node);
1434
- var children = [];
1435
- var isLeafBlock = slate.Element.isElement(node) && !editor.isInline(node) && slate.Editor.hasInlines(editor, node);
1436
- for (var i = 0; i < node.children.length; i++) {
1437
- var p = path.concat(i);
1438
- var n = node.children[i];
2396
+ var isEditor = slate.Editor.isEditor(node);
2397
+ var isBlock = !isEditor && slate.Element.isElement(node) && !editor.isInline(node);
2398
+ var isLeafBlock = isBlock && slate.Editor.hasInlines(editor, node);
2399
+ var chunkSize = isLeafBlock ? null : editor.getChunkSize(node);
2400
+ var chunking = !!chunkSize;
2401
+ var _useDecorationsByChil = useDecorationsByChild(editor, node, decorations),
2402
+ decorationsByChild = _useDecorationsByChil.decorationsByChild,
2403
+ childrenToRedecorate = _useDecorationsByChil.childrenToRedecorate;
2404
+ // Update the index and parent of each child.
2405
+ // PERF: If chunking is enabled, this is done while traversing the chunk tree
2406
+ // instead to eliminate unnecessary weak map operations.
2407
+ if (!chunking) {
2408
+ node.children.forEach(function (n, i) {
2409
+ slateDom.NODE_TO_INDEX.set(n, i);
2410
+ slateDom.NODE_TO_PARENT.set(n, node);
2411
+ });
2412
+ }
2413
+ var renderElementComponent = React.useCallback(function (n, i, cachedKey) {
2414
+ var key = cachedKey !== null && cachedKey !== void 0 ? cachedKey : ReactEditor.findKey(editor, n);
2415
+ return /*#__PURE__*/React.createElement(ElementContext.Provider, {
2416
+ key: "provider-".concat(key.id),
2417
+ value: n
2418
+ }, /*#__PURE__*/React.createElement(MemoizedElement, {
2419
+ decorations: decorationsByChild[i],
2420
+ element: n,
2421
+ key: key.id,
2422
+ renderElement: renderElement,
2423
+ renderChunk: renderChunk,
2424
+ renderPlaceholder: renderPlaceholder,
2425
+ renderLeaf: renderLeaf,
2426
+ renderText: renderText
2427
+ }));
2428
+ }, [editor, decorationsByChild, renderElement, renderChunk, renderPlaceholder, renderLeaf, renderText]);
2429
+ var renderTextComponent = function renderTextComponent(n, i) {
1439
2430
  var key = ReactEditor.findKey(editor, n);
1440
- var range = slate.Editor.range(editor, p);
1441
- var sel = selection && slate.Range.intersection(range, selection);
1442
- var ds = decorate([n, p]);
1443
- var _iterator = _createForOfIteratorHelper$1(decorations),
1444
- _step;
1445
- try {
1446
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
1447
- var dec = _step.value;
1448
- var d = slate.Range.intersection(dec, range);
1449
- if (d) {
1450
- ds.push(d);
1451
- }
2431
+ return /*#__PURE__*/React.createElement(MemoizedText, {
2432
+ decorations: decorationsByChild[i],
2433
+ key: key.id,
2434
+ isLast: i === node.children.length - 1,
2435
+ parent: node,
2436
+ renderPlaceholder: renderPlaceholder,
2437
+ renderLeaf: renderLeaf,
2438
+ renderText: renderText,
2439
+ text: n
2440
+ });
2441
+ };
2442
+ if (!chunking) {
2443
+ return node.children.map(function (n, i) {
2444
+ return slate.Text.isText(n) ? renderTextComponent(n, i) : renderElementComponent(n, i);
2445
+ });
2446
+ }
2447
+ var chunkTree = getChunkTreeForNode(editor, node, {
2448
+ reconcile: {
2449
+ chunkSize: chunkSize,
2450
+ rerenderChildren: childrenToRedecorate,
2451
+ onInsert: function onInsert(n, i) {
2452
+ slateDom.NODE_TO_INDEX.set(n, i);
2453
+ slateDom.NODE_TO_PARENT.set(n, node);
2454
+ },
2455
+ onUpdate: function onUpdate(n, i) {
2456
+ slateDom.NODE_TO_INDEX.set(n, i);
2457
+ slateDom.NODE_TO_PARENT.set(n, node);
2458
+ },
2459
+ onIndexChange: function onIndexChange(n, i) {
2460
+ slateDom.NODE_TO_INDEX.set(n, i);
1452
2461
  }
1453
- } catch (err) {
1454
- _iterator.e(err);
1455
- } finally {
1456
- _iterator.f();
1457
- }
1458
- if (slate.Element.isElement(n)) {
1459
- children.push( /*#__PURE__*/React.createElement(SelectedContext.Provider, {
1460
- key: "provider-".concat(key.id),
1461
- value: !!sel
1462
- }, /*#__PURE__*/React.createElement(MemoizedElement, {
1463
- decorations: ds,
1464
- element: n,
1465
- key: key.id,
1466
- renderElement: renderElement,
1467
- renderPlaceholder: renderPlaceholder,
1468
- renderLeaf: renderLeaf,
1469
- renderText: renderText,
1470
- selection: sel
1471
- })));
1472
- } else {
1473
- children.push( /*#__PURE__*/React.createElement(MemoizedText, {
1474
- decorations: ds,
1475
- key: key.id,
1476
- isLast: isLeafBlock && i === node.children.length - 1,
1477
- parent: node,
1478
- renderPlaceholder: renderPlaceholder,
1479
- renderLeaf: renderLeaf,
1480
- renderText: renderText,
1481
- text: n
1482
- }));
1483
2462
  }
1484
- slateDom.NODE_TO_INDEX.set(n, i);
1485
- slateDom.NODE_TO_PARENT.set(n, node);
2463
+ });
2464
+ return /*#__PURE__*/React.createElement(ChunkTree, {
2465
+ root: chunkTree,
2466
+ ancestor: chunkTree,
2467
+ renderElement: renderElementComponent,
2468
+ renderChunk: renderChunk
2469
+ });
2470
+ };
2471
+ var useDecorationsByChild = function useDecorationsByChild(editor, node, decorations) {
2472
+ var decorationsByChild = slateDom.splitDecorationsByChild(editor, node, decorations);
2473
+ // The value we return is a mutable array of `DecoratedRange[]` arrays. This
2474
+ // lets us avoid passing an immutable array of decorations for each child into
2475
+ // `ChunkTree` using props. Each `DecoratedRange[]` is only updated if the
2476
+ // decorations at that index have changed, which speeds up the equality check
2477
+ // for the `decorations` prop in the memoized `Element` and `Text` components.
2478
+ var mutableDecorationsByChild = React.useRef(decorationsByChild).current;
2479
+ // Track the list of child indices whose decorations have changed, so that we
2480
+ // can tell the chunk tree to re-render these children.
2481
+ var childrenToRedecorate = [];
2482
+ // Resize the mutable array to match the latest result
2483
+ mutableDecorationsByChild.length = decorationsByChild.length;
2484
+ for (var i = 0; i < decorationsByChild.length; i++) {
2485
+ var _mutableDecorationsBy;
2486
+ var _decorations = decorationsByChild[i];
2487
+ var previousDecorations = (_mutableDecorationsBy = mutableDecorationsByChild[i]) !== null && _mutableDecorationsBy !== void 0 ? _mutableDecorationsBy : null;
2488
+ if (!slateDom.isElementDecorationsEqual(previousDecorations, _decorations)) {
2489
+ mutableDecorationsByChild[i] = _decorations;
2490
+ childrenToRedecorate.push(i);
2491
+ }
1486
2492
  }
1487
- return children;
2493
+ return {
2494
+ decorationsByChild: mutableDecorationsByChild,
2495
+ childrenToRedecorate: childrenToRedecorate
2496
+ };
1488
2497
  };
1489
2498
 
1490
2499
  /**
@@ -1498,24 +2507,153 @@ var useReadOnly = function useReadOnly() {
1498
2507
  return React.useContext(ReadOnlyContext);
1499
2508
  };
1500
2509
 
1501
- var SlateContext = /*#__PURE__*/React.createContext(null);
1502
2510
  /**
1503
- * Get the current editor object from the React context.
2511
+ * A React context for sharing the editor selector context in a way to control
2512
+ * re-renders.
1504
2513
  */
1505
- var useSlate = function useSlate() {
1506
- var context = React.useContext(SlateContext);
2514
+ var SlateSelectorContext = /*#__PURE__*/React.createContext({});
2515
+ var refEquality = function refEquality(a, b) {
2516
+ return a === b;
2517
+ };
2518
+ /**
2519
+ * Use redux style selectors to prevent re-rendering on every keystroke.
2520
+ *
2521
+ * Bear in mind re-rendering can only prevented if the returned value is a value
2522
+ * type or for reference types (e.g. objects and arrays) add a custom equality
2523
+ * function.
2524
+ *
2525
+ * If `selector` is memoized using `useCallback`, then it will only be called
2526
+ * when it or the editor state changes. Otherwise, `selector` will be called
2527
+ * every time the component renders.
2528
+ *
2529
+ * @example
2530
+ * const isSelectionActive = useSlateSelector(editor => Boolean(editor.selection))
2531
+ */
2532
+ function useSlateSelector(selector) {
2533
+ var equalityFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : refEquality;
2534
+ var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
2535
+ deferred = _ref.deferred;
2536
+ var context = React.useContext(SlateSelectorContext);
1507
2537
  if (!context) {
2538
+ throw new Error("The `useSlateSelector` hook must be used inside the <Slate> component's context.");
2539
+ }
2540
+ var addEventListener = context.addEventListener;
2541
+ var editor = useSlateStatic();
2542
+ var genericSelector = React.useCallback(function () {
2543
+ return selector(editor);
2544
+ }, [editor, selector]);
2545
+ var _useGenericSelector = useGenericSelector(genericSelector, equalityFn),
2546
+ _useGenericSelector2 = _slicedToArray(_useGenericSelector, 2),
2547
+ selectedState = _useGenericSelector2[0],
2548
+ update = _useGenericSelector2[1];
2549
+ useIsomorphicLayoutEffect(function () {
2550
+ var unsubscribe = addEventListener(update, {
2551
+ deferred: deferred
2552
+ });
2553
+ update();
2554
+ return unsubscribe;
2555
+ }, [addEventListener, update, deferred]);
2556
+ return selectedState;
2557
+ }
2558
+ /**
2559
+ * Create selector context with editor updating on every editor change
2560
+ */
2561
+ function useSelectorContext() {
2562
+ var eventListeners = React.useRef(new Set());
2563
+ var deferredEventListeners = React.useRef(new Set());
2564
+ var onChange = React.useCallback(function () {
2565
+ eventListeners.current.forEach(function (listener) {
2566
+ return listener();
2567
+ });
2568
+ }, []);
2569
+ var flushDeferred = React.useCallback(function () {
2570
+ deferredEventListeners.current.forEach(function (listener) {
2571
+ return listener();
2572
+ });
2573
+ deferredEventListeners.current.clear();
2574
+ }, []);
2575
+ var addEventListener = React.useCallback(function (callbackProp) {
2576
+ var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
2577
+ _ref2$deferred = _ref2.deferred,
2578
+ deferred = _ref2$deferred === void 0 ? false : _ref2$deferred;
2579
+ var callback = deferred ? function () {
2580
+ return deferredEventListeners.current.add(callbackProp);
2581
+ } : callbackProp;
2582
+ eventListeners.current.add(callback);
2583
+ return function () {
2584
+ eventListeners.current["delete"](callback);
2585
+ };
2586
+ }, []);
2587
+ var selectorContext = React.useMemo(function () {
2588
+ return {
2589
+ addEventListener: addEventListener,
2590
+ flushDeferred: flushDeferred
2591
+ };
2592
+ }, [addEventListener, flushDeferred]);
2593
+ return {
2594
+ selectorContext: selectorContext,
2595
+ onChange: onChange
2596
+ };
2597
+ }
2598
+ function useFlushDeferredSelectorsOnRender() {
2599
+ var _useContext = React.useContext(SlateSelectorContext),
2600
+ flushDeferred = _useContext.flushDeferred;
2601
+ useIsomorphicLayoutEffect(flushDeferred);
2602
+ }
2603
+
2604
+ /**
2605
+ * Get the current editor object and re-render whenever it changes.
2606
+ */
2607
+ var useSlate = function useSlate() {
2608
+ var _useContext = React.useContext(SlateSelectorContext),
2609
+ addEventListener = _useContext.addEventListener;
2610
+ var _useReducer = React.useReducer(function (s) {
2611
+ return s + 1;
2612
+ }, 0),
2613
+ _useReducer2 = _slicedToArray(_useReducer, 2),
2614
+ forceRender = _useReducer2[1];
2615
+ if (!addEventListener) {
1508
2616
  throw new Error("The `useSlate` hook must be used inside the <Slate> component's context.");
1509
2617
  }
1510
- var editor = context.editor;
1511
- return editor;
2618
+ useIsomorphicLayoutEffect(function () {
2619
+ return addEventListener(forceRender);
2620
+ }, [addEventListener]);
2621
+ return useSlateStatic();
1512
2622
  };
1513
- var useSlateWithV = function useSlateWithV() {
1514
- var context = React.useContext(SlateContext);
1515
- if (!context) {
1516
- throw new Error("The `useSlate` hook must be used inside the <Slate> component's context.");
2623
+ var EDITOR_TO_V = new WeakMap();
2624
+ var getEditorVersionRef = function getEditorVersionRef(editor) {
2625
+ var v = EDITOR_TO_V.get(editor);
2626
+ if (v) {
2627
+ return v;
1517
2628
  }
1518
- return context;
2629
+ v = {
2630
+ current: 0
2631
+ };
2632
+ EDITOR_TO_V.set(editor, v);
2633
+ // Register the `onChange` handler exactly once per editor
2634
+ var onChange = editor.onChange;
2635
+ editor.onChange = function (options) {
2636
+ v.current++;
2637
+ onChange(options);
2638
+ };
2639
+ return v;
2640
+ };
2641
+ /**
2642
+ * Get the current editor object and its version, which increments on every
2643
+ * change.
2644
+ *
2645
+ * @deprecated The `v` counter is no longer used except for this hook, and may
2646
+ * be removed in a future version.
2647
+ */
2648
+ var useSlateWithV = function useSlateWithV() {
2649
+ var editor = useSlate();
2650
+ var vRef = React.useMemo(function () {
2651
+ return getEditorVersionRef(editor);
2652
+ }, [editor]);
2653
+ return {
2654
+ editor: editor,
2655
+ v: vRef.current
2656
+ };
1519
2657
  };
1520
2658
 
1521
2659
  function useTrackUserInput() {
@@ -1544,40 +2682,6 @@ function useTrackUserInput() {
1544
2682
  };
1545
2683
  }
1546
2684
 
1547
- var classCallCheck = createCommonjsModule(function (module) {
1548
- function _classCallCheck(instance, Constructor) {
1549
- if (!(instance instanceof Constructor)) {
1550
- throw new TypeError("Cannot call a class as a function");
1551
- }
1552
- }
1553
- module.exports = _classCallCheck, module.exports.__esModule = true, module.exports["default"] = module.exports;
1554
- });
1555
-
1556
- var _classCallCheck = unwrapExports(classCallCheck);
1557
-
1558
- var createClass = createCommonjsModule(function (module) {
1559
- function _defineProperties(target, props) {
1560
- for (var i = 0; i < props.length; i++) {
1561
- var descriptor = props[i];
1562
- descriptor.enumerable = descriptor.enumerable || false;
1563
- descriptor.configurable = true;
1564
- if ("value" in descriptor) descriptor.writable = true;
1565
- Object.defineProperty(target, toPropertyKey(descriptor.key), descriptor);
1566
- }
1567
- }
1568
- function _createClass(Constructor, protoProps, staticProps) {
1569
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
1570
- if (staticProps) _defineProperties(Constructor, staticProps);
1571
- Object.defineProperty(Constructor, "prototype", {
1572
- writable: false
1573
- });
1574
- return Constructor;
1575
- }
1576
- module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports;
1577
- });
1578
-
1579
- var _createClass = unwrapExports(createClass);
1580
-
1581
2685
  var assertThisInitialized = createCommonjsModule(function (module) {
1582
2686
  function _assertThisInitialized(self) {
1583
2687
  if (self === void 0) {
@@ -1653,42 +2757,6 @@ module.exports = _getPrototypeOf, module.exports.__esModule = true, module.expor
1653
2757
 
1654
2758
  var _getPrototypeOf = unwrapExports(getPrototypeOf);
1655
2759
 
1656
- var arrayWithoutHoles = createCommonjsModule(function (module) {
1657
- function _arrayWithoutHoles(arr) {
1658
- if (Array.isArray(arr)) return arrayLikeToArray(arr);
1659
- }
1660
- module.exports = _arrayWithoutHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;
1661
- });
1662
-
1663
- unwrapExports(arrayWithoutHoles);
1664
-
1665
- var iterableToArray = createCommonjsModule(function (module) {
1666
- function _iterableToArray(iter) {
1667
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
1668
- }
1669
- module.exports = _iterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
1670
- });
1671
-
1672
- unwrapExports(iterableToArray);
1673
-
1674
- var nonIterableSpread = createCommonjsModule(function (module) {
1675
- function _nonIterableSpread() {
1676
- throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1677
- }
1678
- module.exports = _nonIterableSpread, module.exports.__esModule = true, module.exports["default"] = module.exports;
1679
- });
1680
-
1681
- unwrapExports(nonIterableSpread);
1682
-
1683
- var toConsumableArray = createCommonjsModule(function (module) {
1684
- function _toConsumableArray(arr) {
1685
- return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();
1686
- }
1687
- module.exports = _toConsumableArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
1688
- });
1689
-
1690
- var _toConsumableArray = unwrapExports(toConsumableArray);
1691
-
1692
2760
  var createRestoreDomManager = function createRestoreDomManager(editor, receivedUserInput) {
1693
2761
  var bufferedMutations = [];
1694
2762
  var clear = function clear() {
@@ -1825,7 +2893,7 @@ var useComposing = function useComposing() {
1825
2893
  return React.useContext(ComposingContext);
1826
2894
  };
1827
2895
 
1828
- var _excluded$1 = ["autoFocus", "decorate", "onDOMBeforeInput", "placeholder", "readOnly", "renderElement", "renderLeaf", "renderText", "renderPlaceholder", "scrollSelectionIntoView", "style", "as", "disableDefaultStyles"],
2896
+ var _excluded$1 = ["autoFocus", "decorate", "onDOMBeforeInput", "placeholder", "readOnly", "renderElement", "renderChunk", "renderLeaf", "renderText", "renderPlaceholder", "scrollSelectionIntoView", "style", "as", "disableDefaultStyles"],
1829
2897
  _excluded2 = ["text"];
1830
2898
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(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; } } }; }
1831
2899
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(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(o, minLen); }
@@ -1850,6 +2918,7 @@ var Editable = /*#__PURE__*/React.forwardRef(function (props, forwardedRef) {
1850
2918
  _props$readOnly = props.readOnly,
1851
2919
  readOnly = _props$readOnly === void 0 ? false : _props$readOnly,
1852
2920
  renderElement = props.renderElement,
2921
+ renderChunk = props.renderChunk,
1853
2922
  renderLeaf = props.renderLeaf,
1854
2923
  renderText = props.renderText,
1855
2924
  _props$renderPlacehol = props.renderPlaceholder,
@@ -1898,6 +2967,11 @@ var Editable = /*#__PURE__*/React.forwardRef(function (props, forwardedRef) {
1898
2967
  }, []);
1899
2968
  // The autoFocus TextareaHTMLAttribute doesn't do anything on a div, so it
1900
2969
  // needs to be manually focused.
2970
+ //
2971
+ // If this stops working in Firefox, make sure nothing is causing this
2972
+ // component to re-render during the initial mount. If the DOM selection is
2973
+ // set by `useIsomorphicLayoutEffect` before `onDOMSelectionChange` updates
2974
+ // `editor.selection`, the DOM selection can be removed accidentally.
1901
2975
  React.useEffect(function () {
1902
2976
  if (ref.current && autoFocus) {
1903
2977
  ref.current.focus();
@@ -2449,6 +3523,7 @@ var Editable = /*#__PURE__*/React.forwardRef(function (props, forwardedRef) {
2449
3523
  };
2450
3524
  }, [scheduleOnDOMSelectionChange, state]);
2451
3525
  var decorations = decorate([editor, []]);
3526
+ var decorateContext = useDecorateContext(decorate);
2452
3527
  var showPlaceholder = placeholder && editor.children.length === 1 && Array.from(slate.Node.texts(editor)).length === 1 && slate.Node.string(editor) === '' && !isComposing;
2453
3528
  var placeHolderResizeHandler = React.useCallback(function (placeholderEl) {
2454
3529
  if (placeholderEl && showPlaceholder) {
@@ -2505,12 +3580,13 @@ var Editable = /*#__PURE__*/React.forwardRef(function (props, forwardedRef) {
2505
3580
  slateDom.EDITOR_TO_PENDING_INSERTION_MARKS["delete"](editor);
2506
3581
  });
2507
3582
  });
3583
+ useFlushDeferredSelectorsOnRender();
2508
3584
  return /*#__PURE__*/React.createElement(ReadOnlyContext.Provider, {
2509
3585
  value: readOnly
2510
3586
  }, /*#__PURE__*/React.createElement(ComposingContext.Provider, {
2511
3587
  value: isComposing
2512
3588
  }, /*#__PURE__*/React.createElement(DecorateContext.Provider, {
2513
- value: decorate
3589
+ value: decorateContext
2514
3590
  }, /*#__PURE__*/React.createElement(RestoreDOM, {
2515
3591
  node: ref,
2516
3592
  receivedUserInput: receivedUserInput
@@ -3096,10 +4172,10 @@ var Editable = /*#__PURE__*/React.forwardRef(function (props, forwardedRef) {
3096
4172
  decorations: decorations,
3097
4173
  node: editor,
3098
4174
  renderElement: renderElement,
4175
+ renderChunk: renderChunk,
3099
4176
  renderPlaceholder: renderPlaceholder,
3100
4177
  renderLeaf: renderLeaf,
3101
- renderText: renderText,
3102
- selection: editor.selection
4178
+ renderText: renderText
3103
4179
  }))))));
3104
4180
  });
3105
4181
  /**
@@ -3196,130 +4272,6 @@ var useFocused = function useFocused() {
3196
4272
  return React.useContext(FocusedContext);
3197
4273
  };
3198
4274
 
3199
- function isError(error) {
3200
- return error instanceof Error;
3201
- }
3202
- /**
3203
- * A React context for sharing the editor selector context in a way to control rerenders
3204
- */
3205
- var SlateSelectorContext = /*#__PURE__*/React.createContext({});
3206
- var refEquality = function refEquality(a, b) {
3207
- return a === b;
3208
- };
3209
- /**
3210
- * use redux style selectors to prevent rerendering on every keystroke.
3211
- * Bear in mind rerendering can only prevented if the returned value is a value type or for reference types (e.g. objects and arrays) add a custom equality function.
3212
- *
3213
- * Example:
3214
- * ```
3215
- * const isSelectionActive = useSlateSelector(editor => Boolean(editor.selection));
3216
- * ```
3217
- */
3218
- function useSlateSelector(selector) {
3219
- var equalityFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : refEquality;
3220
- var _useReducer = React.useReducer(function (s) {
3221
- return s + 1;
3222
- }, 0),
3223
- _useReducer2 = _slicedToArray(_useReducer, 2),
3224
- forceRender = _useReducer2[1];
3225
- var context = React.useContext(SlateSelectorContext);
3226
- if (!context) {
3227
- throw new Error("The `useSlateSelector` hook must be used inside the <Slate> component's context.");
3228
- }
3229
- var getSlate = context.getSlate,
3230
- addEventListener = context.addEventListener;
3231
- var latestSubscriptionCallbackError = React.useRef();
3232
- var latestSelector = React.useRef(function () {
3233
- return null;
3234
- });
3235
- var latestSelectedState = React.useRef(null);
3236
- var selectedState;
3237
- try {
3238
- if (selector !== latestSelector.current || latestSubscriptionCallbackError.current) {
3239
- var selectorResult = selector(getSlate());
3240
- if (equalityFn(latestSelectedState.current, selectorResult)) {
3241
- selectedState = latestSelectedState.current;
3242
- } else {
3243
- selectedState = selectorResult;
3244
- }
3245
- } else {
3246
- selectedState = latestSelectedState.current;
3247
- }
3248
- } catch (err) {
3249
- if (latestSubscriptionCallbackError.current && isError(err)) {
3250
- err.message += "\nThe error may be correlated with this previous error:\n".concat(latestSubscriptionCallbackError.current.stack, "\n\n");
3251
- }
3252
- throw err;
3253
- }
3254
- useIsomorphicLayoutEffect(function () {
3255
- latestSelector.current = selector;
3256
- latestSelectedState.current = selectedState;
3257
- latestSubscriptionCallbackError.current = undefined;
3258
- });
3259
- useIsomorphicLayoutEffect(function () {
3260
- function checkForUpdates() {
3261
- try {
3262
- var newSelectedState = latestSelector.current(getSlate());
3263
- if (equalityFn(newSelectedState, latestSelectedState.current)) {
3264
- return;
3265
- }
3266
- latestSelectedState.current = newSelectedState;
3267
- } catch (err) {
3268
- // we ignore all errors here, since when the component
3269
- // is re-rendered, the selectors are called again, and
3270
- // will throw again, if neither props nor store state
3271
- // changed
3272
- if (err instanceof Error) {
3273
- latestSubscriptionCallbackError.current = err;
3274
- } else {
3275
- latestSubscriptionCallbackError.current = new Error(String(err));
3276
- }
3277
- }
3278
- forceRender();
3279
- }
3280
- var unsubscribe = addEventListener(checkForUpdates);
3281
- checkForUpdates();
3282
- return function () {
3283
- return unsubscribe();
3284
- };
3285
- },
3286
- // don't rerender on equalityFn change since we want to be able to define it inline
3287
- [addEventListener, getSlate]);
3288
- return selectedState;
3289
- }
3290
- /**
3291
- * Create selector context with editor updating on every editor change
3292
- */
3293
- function useSelectorContext(editor) {
3294
- var eventListeners = React.useRef([]).current;
3295
- var slateRef = React.useRef({
3296
- editor: editor
3297
- }).current;
3298
- var onChange = React.useCallback(function (editor) {
3299
- slateRef.editor = editor;
3300
- eventListeners.forEach(function (listener) {
3301
- return listener(editor);
3302
- });
3303
- }, [eventListeners, slateRef]);
3304
- var selectorContext = React.useMemo(function () {
3305
- return {
3306
- getSlate: function getSlate() {
3307
- return slateRef.editor;
3308
- },
3309
- addEventListener: function addEventListener(callback) {
3310
- eventListeners.push(callback);
3311
- return function () {
3312
- eventListeners.splice(eventListeners.indexOf(callback), 1);
3313
- };
3314
- }
3315
- };
3316
- }, [eventListeners, slateRef]);
3317
- return {
3318
- selectorContext: selectorContext,
3319
- onChange: onChange
3320
- };
3321
- }
3322
-
3323
4275
  var REACT_MAJOR_VERSION = parseInt(React.version.split('.')[0], 10);
3324
4276
 
3325
4277
  var _excluded = ["editor", "children", "onChange", "onSelectionChange", "onValueChange", "initialValue"];
@@ -3335,24 +4287,18 @@ var Slate = function Slate(props) {
3335
4287
  onValueChange = props.onValueChange,
3336
4288
  initialValue = props.initialValue,
3337
4289
  rest = _objectWithoutProperties(props, _excluded);
3338
- var _React$useState = React.useState(function () {
3339
- if (!slate.Node.isNodeList(initialValue)) {
3340
- throw new Error("[Slate] initialValue is invalid! Expected a list of elements but got: ".concat(slate.Scrubber.stringify(initialValue)));
3341
- }
3342
- if (!slate.Editor.isEditor(editor)) {
3343
- throw new Error("[Slate] editor is invalid! You passed: ".concat(slate.Scrubber.stringify(editor)));
3344
- }
3345
- editor.children = initialValue;
3346
- Object.assign(editor, rest);
3347
- return {
3348
- v: 0,
3349
- editor: editor
3350
- };
3351
- }),
3352
- _React$useState2 = _slicedToArray(_React$useState, 2),
3353
- context = _React$useState2[0],
3354
- setContext = _React$useState2[1];
3355
- var _useSelectorContext = useSelectorContext(editor),
4290
+ // Run once on first mount, but before `useEffect` or render
4291
+ React.useState(function () {
4292
+ if (!slate.Node.isNodeList(initialValue)) {
4293
+ throw new Error("[Slate] initialValue is invalid! Expected a list of elements but got: ".concat(slate.Scrubber.stringify(initialValue)));
4294
+ }
4295
+ if (!slate.Editor.isEditor(editor)) {
4296
+ throw new Error("[Slate] editor is invalid! You passed: ".concat(slate.Scrubber.stringify(editor)));
4297
+ }
4298
+ editor.children = initialValue;
4299
+ Object.assign(editor, rest);
4300
+ });
4301
+ var _useSelectorContext = useSelectorContext(),
3356
4302
  selectorContext = _useSelectorContext.selectorContext,
3357
4303
  handleSelectorChange = _useSelectorContext.onChange;
3358
4304
  var onContextChange = React.useCallback(function (options) {
@@ -3367,13 +4313,7 @@ var Slate = function Slate(props) {
3367
4313
  default:
3368
4314
  onValueChange === null || onValueChange === void 0 || onValueChange(editor.children);
3369
4315
  }
3370
- setContext(function (prevContext) {
3371
- return {
3372
- v: prevContext.v + 1,
3373
- editor: editor
3374
- };
3375
- });
3376
- handleSelectorChange(editor);
4316
+ handleSelectorChange();
3377
4317
  }, [editor, handleSelectorChange, onChange, onSelectionChange, onValueChange]);
3378
4318
  React.useEffect(function () {
3379
4319
  slateDom.EDITOR_TO_ON_CHANGE.set(editor, onContextChange);
@@ -3413,13 +4353,11 @@ var Slate = function Slate(props) {
3413
4353
  }, []);
3414
4354
  return /*#__PURE__*/React.createElement(SlateSelectorContext.Provider, {
3415
4355
  value: selectorContext
3416
- }, /*#__PURE__*/React.createElement(SlateContext.Provider, {
3417
- value: context
3418
4356
  }, /*#__PURE__*/React.createElement(EditorContext.Provider, {
3419
- value: context.editor
4357
+ value: editor
3420
4358
  }, /*#__PURE__*/React.createElement(FocusedContext.Provider, {
3421
4359
  value: isFocused
3422
- }, children))));
4360
+ }, children)));
3423
4361
  };
3424
4362
 
3425
4363
  /**
@@ -3434,6 +4372,31 @@ var useEditor = function useEditor() {
3434
4372
  return editor;
3435
4373
  };
3436
4374
 
4375
+ /**
4376
+ * Get the current `selected` state of an element.
4377
+ */
4378
+ var useSelected = function useSelected() {
4379
+ var element = useElementIf();
4380
+ // Breaking the rules of hooks is fine here since `!element` will remain true
4381
+ // or false for the entire lifetime of the component this hook is called from.
4382
+ // TODO: Decide if we want to throw an error instead when calling
4383
+ // `useSelected` outside of an element (potentially a breaking change).
4384
+ if (!element) return false;
4385
+ // eslint-disable-next-line react-hooks/rules-of-hooks
4386
+ var selector = React.useCallback(function (editor) {
4387
+ if (!editor.selection) return false;
4388
+ var path = ReactEditor.findPath(editor, element);
4389
+ var range = slate.Editor.range(editor, path);
4390
+ return !!slate.Range.intersection(range, editor.selection);
4391
+ }, [element]);
4392
+ // eslint-disable-next-line react-hooks/rules-of-hooks
4393
+ return useSlateSelector(selector, undefined, {
4394
+ // Defer the selector until after `Editable` has rendered so that the path
4395
+ // will be accurate.
4396
+ deferred: true
4397
+ });
4398
+ };
4399
+
3437
4400
  /**
3438
4401
  * Get the current slate selection.
3439
4402
  * Only triggers a rerender when the selection actually changes
@@ -3462,7 +4425,11 @@ var withReact = function withReact(editor) {
3462
4425
  var e = editor;
3463
4426
  e = slateDom.withDOM(e, clipboardFormatKey);
3464
4427
  var _e = e,
3465
- onChange = _e.onChange;
4428
+ onChange = _e.onChange,
4429
+ apply = _e.apply;
4430
+ e.getChunkSize = function () {
4431
+ return null;
4432
+ };
3466
4433
  e.onChange = function (options) {
3467
4434
  // COMPAT: React < 18 doesn't batch `setState` hook calls, which means
3468
4435
  // that the children and selection can get out of sync for one render
@@ -3476,6 +4443,22 @@ var withReact = function withReact(editor) {
3476
4443
  onChange(options);
3477
4444
  });
3478
4445
  };
4446
+ // On move_node, if the chunking optimization is enabled for the parent of the
4447
+ // node being moved, add the moved node to the movedNodeKeys set of the
4448
+ // parent's chunk tree.
4449
+ e.apply = function (operation) {
4450
+ if (operation.type === 'move_node') {
4451
+ var parent = slate.Node.parent(e, operation.path);
4452
+ var chunking = !!e.getChunkSize(parent);
4453
+ if (chunking) {
4454
+ var node = slate.Node.get(e, operation.path);
4455
+ var chunkTree = getChunkTreeForNode(e, parent);
4456
+ var key = ReactEditor.findKey(e, node);
4457
+ chunkTree.movedNodeKeys.add(key);
4458
+ }
4459
+ }
4460
+ apply(operation);
4461
+ };
3479
4462
  return e;
3480
4463
  };
3481
4464
 
@@ -3496,6 +4479,8 @@ exports.ReactEditor = ReactEditor;
3496
4479
  exports.Slate = Slate;
3497
4480
  exports.useComposing = useComposing;
3498
4481
  exports.useEditor = useEditor;
4482
+ exports.useElement = useElement;
4483
+ exports.useElementIf = useElementIf;
3499
4484
  exports.useFocused = useFocused;
3500
4485
  exports.useReadOnly = useReadOnly;
3501
4486
  exports.useSelected = useSelected;