@contentful/field-editor-rich-text 2.0.0-next.21 → 2.0.0-next.24

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.
@@ -28,6 +28,7 @@ var tokens = _interopDefault(require('@contentful/f36-tokens'));
28
28
  var find = _interopDefault(require('lodash/find'));
29
29
  var flow = _interopDefault(require('lodash/flow'));
30
30
  var plateList = require('@udecode/plate-list');
31
+ var castArray = _interopDefault(require('lodash/castArray'));
31
32
  var plateBasicMarks = require('@udecode/plate-basic-marks');
32
33
  var isPlainObject = _interopDefault(require('is-plain-obj'));
33
34
  var plateParagraph = require('@udecode/plate-paragraph');
@@ -426,10 +427,12 @@ function isBlockSelected(editor, type) {
426
427
  function isRootLevel(path) {
427
428
  return path.length === 1;
428
429
  }
429
- function getNodeEntryFromSelection(editor, nodeTypeOrTypes) {
430
- if (!editor.selection) return [];
430
+ function getNodeEntryFromSelection(editor, nodeTypeOrTypes, path) {
431
+ var _path, _editor$selection;
432
+
433
+ path = (_path = path) != null ? _path : (_editor$selection = editor.selection) == null ? void 0 : _editor$selection.focus.path;
434
+ if (!path) return [];
431
435
  var nodeTypes = Array.isArray(nodeTypeOrTypes) ? nodeTypeOrTypes : [nodeTypeOrTypes];
432
- var path = editor.selection.focus.path;
433
436
 
434
437
  for (var i = 0; i < path.length; i++) {
435
438
  var nodeEntry = slate.Editor.node(editor, path.slice(0, i + 1));
@@ -588,18 +591,18 @@ function getAncestorPathFromSelection(editor) {
588
591
  });
589
592
  }
590
593
  var isAtEndOfTextSelection = function isAtEndOfTextSelection(editor) {
591
- var _editor$selection, _editor$selection2;
594
+ var _editor$selection2, _editor$selection3;
592
595
 
593
- return ((_editor$selection = editor.selection) == null ? void 0 : _editor$selection.focus.offset) === plateCore.getText(editor, (_editor$selection2 = editor.selection) == null ? void 0 : _editor$selection2.focus.path).length;
596
+ return ((_editor$selection2 = editor.selection) == null ? void 0 : _editor$selection2.focus.offset) === plateCore.getText(editor, (_editor$selection3 = editor.selection) == null ? void 0 : _editor$selection3.focus.path).length;
594
597
  };
595
598
  function currentSelectionStartsTableCell(editor) {
596
- var _editor$selection3;
599
+ var _editor$selection4;
597
600
 
598
601
  var _getNodeEntryFromSele2 = getNodeEntryFromSelection(editor, [Contentful.BLOCKS.TABLE_CELL, Contentful.BLOCKS.TABLE_HEADER_CELL]),
599
602
  tableCellNode = _getNodeEntryFromSele2[0],
600
603
  path = _getNodeEntryFromSele2[1];
601
604
 
602
- return !!tableCellNode && (!plateCore.getText(editor, path) || ((_editor$selection3 = editor.selection) == null ? void 0 : _editor$selection3.focus.offset) === 0);
605
+ return !!tableCellNode && (!plateCore.getText(editor, path) || ((_editor$selection4 = editor.selection) == null ? void 0 : _editor$selection4.focus.offset) === 0);
603
606
  }
604
607
  /**
605
608
  * This traversal strategy is unfortunately necessary because Slate doesn't
@@ -951,14 +954,22 @@ function FetchingWrappedEntryCard(props) {
951
954
  var onEntityFetchComplete = props.onEntityFetchComplete;
952
955
  React.useEffect(function () {
953
956
  if (!entry || entry === 'failed') return;
957
+ var subscribed = true;
954
958
  fieldEditorShared.entityHelpers.getEntryImage({
955
959
  entry: entry,
956
960
  contentType: contentType,
957
961
  localeCode: props.locale,
958
962
  defaultLocaleCode: defaultLocaleCode
959
- }, getOrLoadAsset).then(setFile)["catch"](function () {
960
- return setFile(null);
963
+ }, getOrLoadAsset)["catch"](function () {
964
+ return null;
965
+ }).then(function (file) {
966
+ if (subscribed) {
967
+ setFile(file);
968
+ }
961
969
  });
970
+ return function () {
971
+ subscribed = false;
972
+ };
962
973
  }, [entry, contentType, props.locale, defaultLocaleCode, props.sdk, file, getOrLoadAsset]);
963
974
  React.useEffect(function () {
964
975
  getOrLoadEntry(props.entryId);
@@ -1053,7 +1064,14 @@ function FetchingWrappedEntryCard(props) {
1053
1064
 
1054
1065
  var styles$3 = {
1055
1066
  root: /*#__PURE__*/emotion.css({
1056
- marginBottom: '1.25rem !important'
1067
+ marginBottom: '1.25rem !important',
1068
+ display: 'block'
1069
+ }),
1070
+ container: /*#__PURE__*/emotion.css({
1071
+ // The next 2 properties ensure Entity card won't be aligned above
1072
+ // a list item marker (i.e. bullet)
1073
+ display: 'inline-block',
1074
+ verticalAlign: 'text-top'
1057
1075
  })
1058
1076
  };
1059
1077
  function LinkedEntityBlock(props) {
@@ -1094,7 +1112,8 @@ function LinkedEntityBlock(props) {
1094
1112
  }), /*#__PURE__*/React__default.createElement("div", {
1095
1113
  // COMPAT: This makes copy & paste work for Chromium/Blink browsers and Safari
1096
1114
  contentEditable: HAS_BEFORE_INPUT_SUPPORT ? false : undefined,
1097
- draggable: HAS_BEFORE_INPUT_SUPPORT ? true : undefined
1115
+ draggable: HAS_BEFORE_INPUT_SUPPORT ? true : undefined,
1116
+ className: styles$3.container
1098
1117
  }, entityType === 'Entry' && /*#__PURE__*/React__default.createElement(FetchingWrappedEntryCard, {
1099
1118
  sdk: sdk,
1100
1119
  entryId: entityId,
@@ -3197,29 +3216,31 @@ function HyperlinkModal(props) {
3197
3216
  testId: "confirm-cta"
3198
3217
  }, props.linkType ? 'Update' : 'Insert'))));
3199
3218
  }
3200
- function addOrEditLink(_x, _x2, _x3) {
3219
+ function addOrEditLink(_x, _x2, _x3, _x4) {
3201
3220
  return _addOrEditLink.apply(this, arguments);
3202
3221
  }
3203
3222
 
3204
3223
  function _addOrEditLink() {
3205
- _addOrEditLink = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(editor, sdk, logAction) {
3224
+ _addOrEditLink = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(editor, sdk, logAction, targetPath) {
3206
3225
  var _target$sys$linkType;
3207
3226
 
3208
- var linkType, linkText, linkTarget, linkEntity, _getNodeEntryFromSele, node, path, selectionBeforeBlur, currentLinkText, isEditing, data, text, url, type, target;
3227
+ var selectionBeforeBlur, linkType, linkText, linkTarget, linkEntity, _getNodeEntryFromSele, node, path, selectionAfterFocus, currentLinkText, isEditing, data, text, url, type, target;
3209
3228
 
3210
3229
  return runtime_1.wrap(function _callee3$(_context3) {
3211
3230
  while (1) {
3212
3231
  switch (_context3.prev = _context3.next) {
3213
3232
  case 0:
3214
- if (editor.selection) {
3215
- _context3.next = 2;
3233
+ selectionBeforeBlur = editor.selection ? _extends({}, editor.selection) : undefined;
3234
+
3235
+ if (!(!targetPath && !selectionBeforeBlur)) {
3236
+ _context3.next = 3;
3216
3237
  break;
3217
3238
  }
3218
3239
 
3219
3240
  return _context3.abrupt("return");
3220
3241
 
3221
- case 2:
3222
- _getNodeEntryFromSele = getNodeEntryFromSelection(editor, LINK_TYPES), node = _getNodeEntryFromSele[0], path = _getNodeEntryFromSele[1];
3242
+ case 3:
3243
+ _getNodeEntryFromSele = getNodeEntryFromSelection(editor, LINK_TYPES, targetPath), node = _getNodeEntryFromSele[0], path = _getNodeEntryFromSele[1];
3223
3244
 
3224
3245
  if (node && path) {
3225
3246
  linkType = node.type;
@@ -3228,11 +3249,11 @@ function _addOrEditLink() {
3228
3249
  linkEntity = node.data.target;
3229
3250
  }
3230
3251
 
3231
- selectionBeforeBlur = _extends({}, editor.selection);
3232
- currentLinkText = linkText || slate.Editor.string(editor, editor.selection);
3252
+ selectionAfterFocus = targetPath != null ? targetPath : selectionBeforeBlur;
3253
+ currentLinkText = linkText || (editor.selection ? slate.Editor.string(editor, editor.selection) : '');
3233
3254
  isEditing = Boolean(node && path);
3234
3255
  logAction(isEditing ? 'openEditHyperlinkDialog' : 'openCreateHyperlinkDialog');
3235
- _context3.next = 10;
3256
+ _context3.next = 11;
3236
3257
  return fieldEditorShared.ModalDialogLauncher.openDialog({
3237
3258
  title: isEditing ? 'Edit hyperlink' : 'Insert hyperlink',
3238
3259
  width: 'large',
@@ -3251,20 +3272,21 @@ function _addOrEditLink() {
3251
3272
  });
3252
3273
  });
3253
3274
 
3254
- case 10:
3275
+ case 11:
3255
3276
  data = _context3.sent;
3277
+ slate.Transforms.select(editor, selectionAfterFocus);
3256
3278
 
3257
3279
  if (data) {
3258
- _context3.next = 14;
3280
+ _context3.next = 17;
3259
3281
  break;
3260
3282
  }
3261
3283
 
3284
+ focus(editor);
3262
3285
  logAction(isEditing ? 'cancelEditHyperlinkDialog' : 'cancelCreateHyperlinkDialog');
3263
3286
  return _context3.abrupt("return");
3264
3287
 
3265
- case 14:
3288
+ case 17:
3266
3289
  text = data.linkText, url = data.linkTarget, type = data.linkType, target = data.linkEntity;
3267
- slate.Transforms.select(editor, selectionBeforeBlur);
3268
3290
  slate.Editor.withoutNormalizing(editor, function () {
3269
3291
  insertLink(editor, {
3270
3292
  text: text,
@@ -3280,7 +3302,7 @@ function _addOrEditLink() {
3280
3302
  });
3281
3303
  focus(editor);
3282
3304
 
3283
- case 19:
3305
+ case 21:
3284
3306
  case "end":
3285
3307
  return _context3.stop();
3286
3308
  }
@@ -3534,7 +3556,11 @@ function EntityHyperlink(props) {
3534
3556
  event.preventDefault();
3535
3557
  event.stopPropagation();
3536
3558
  if (!editor) return;
3537
- addOrEditLink(editor, sdk, editor.tracking.onViewportAction);
3559
+ var p = Slate.ReactEditor.toSlatePoint(editor, [event.target, 0], {
3560
+ exactMatch: false,
3561
+ suppressThrow: false
3562
+ });
3563
+ addOrEditLink(editor, sdk, editor.tracking.onViewportAction, p.path);
3538
3564
  }
3539
3565
 
3540
3566
  return /*#__PURE__*/React.createElement(f36Components.Tooltip, {
@@ -3562,7 +3588,11 @@ function UrlHyperlink(props) {
3562
3588
  event.preventDefault();
3563
3589
  event.stopPropagation();
3564
3590
  if (!editor) return;
3565
- addOrEditLink(editor, sdk, editor.tracking.onViewportAction);
3591
+ var p = Slate.ReactEditor.toSlatePoint(editor, [event.target, 0], {
3592
+ exactMatch: false,
3593
+ suppressThrow: false
3594
+ });
3595
+ addOrEditLink(editor, sdk, editor.tracking.onViewportAction, p.path);
3566
3596
  }
3567
3597
 
3568
3598
  return /*#__PURE__*/React.createElement(f36Components.Tooltip, {
@@ -3723,245 +3753,586 @@ function ListItem(props) {
3723
3753
  }), props.children);
3724
3754
  }
3725
3755
 
3726
- var isList = function isList(node) {
3727
- return [Contentful.BLOCKS.OL_LIST, Contentful.BLOCKS.UL_LIST].includes(node.type);
3728
- };
3729
-
3730
- var hasListAsDirectParent = function hasListAsDirectParent(editor, _ref) {
3731
- var path = _ref[1];
3732
-
3733
- var _ref2 = plateCore.getParent(editor, path) || [],
3734
- parentNode = _ref2[0];
3735
-
3736
- return isList(parentNode);
3737
- };
3738
-
3739
- var getNearestListAncestor = function getNearestListAncestor(editor, path) {
3740
- return plateCore.getAbove(editor, {
3741
- at: path,
3742
- mode: 'lowest',
3743
- match: isList
3744
- }) || [];
3745
- };
3746
3756
  /**
3747
- * Places orphaned list items in a list. If there's a list somewhere
3748
- * in the node's ancestors, defaults to that list type, else places
3749
- * the list item in an unordered list.
3757
+ * Credit: Modified version of Plate's list plugin
3758
+ * See: https://github.com/udecode/plate/blob/main/packages/nodes/list
3750
3759
  */
3760
+ var moveListItemDown = function moveListItemDown(editor, _ref) {
3761
+ var list = _ref.list,
3762
+ listItem = _ref.listItem;
3763
+ var listNode = list[0];
3764
+ var listItemPath = listItem[1];
3765
+ var previousListItemPath;
3751
3766
 
3767
+ try {
3768
+ previousListItemPath = slate.Path.previous(listItemPath);
3769
+ } catch (e) {
3770
+ return;
3771
+ } // Previous sibling is the new parent
3752
3772
 
3753
- var normalizeOrphanedListItem = function normalizeOrphanedListItem(editor, _ref3) {
3754
- var path = _ref3[1];
3755
-
3756
- var _getNearestListAncest = getNearestListAncestor(editor, path),
3757
- parentList = _getNearestListAncest[0];
3758
-
3759
- var parentListType = parentList == null ? void 0 : parentList.type;
3760
- slate.Transforms.wrapNodes(editor, {
3761
- type: parentListType || Contentful.BLOCKS.UL_LIST,
3762
- children: [],
3763
- data: {}
3764
- }, {
3765
- at: path
3766
- });
3767
- };
3768
- var isNonEmptyListItem = function isNonEmptyListItem(editor, _ref4) {
3769
- var path = _ref4[1];
3770
- var listItemChildren = Array.from(slate.Node.children(editor, path));
3771
- return listItemChildren.length !== 0;
3772
- };
3773
- var firstNodeIsNotList = function firstNodeIsNotList(_editor, _ref5) {
3774
- var node = _ref5[0];
3775
-
3776
- if (node.children.length === 1) {
3777
- var firstNode = node.children[0];
3778
- return !slate.Text.isText(firstNode) && !isList(firstNode);
3779
- }
3780
-
3781
- return true;
3782
- };
3783
- var insertParagraphAsChild = function insertParagraphAsChild(editor, _ref6) {
3784
- var path = _ref6[1];
3785
- slate.Transforms.insertNodes(editor, [{
3786
- type: Contentful.BLOCKS.PARAGRAPH,
3787
- data: {},
3788
- children: [{
3789
- text: ''
3790
- }]
3791
- }], {
3792
- at: path.concat([0])
3793
- });
3794
- };
3795
- var replaceNodeWithListItems = function replaceNodeWithListItems(editor, entry) {
3796
- var node = entry[0],
3797
- path = entry[1];
3798
- slate.Transforms.removeNodes(editor, {
3799
- at: path
3800
- });
3801
- slate.Transforms.insertNodes(editor, node.children[0].children, {
3802
- at: path
3803
- });
3804
- };
3805
- var isListTypeActive = function isListTypeActive(editor, type) {
3806
- // Lists can be nested. Here, we take the list type at the lowest level
3807
- var listNode = plateCore.getBlockAbove(editor, {
3808
- match: {
3809
- type: [Contentful.BLOCKS.OL_LIST, Contentful.BLOCKS.UL_LIST]
3810
- },
3811
- mode: 'lowest'
3812
- });
3813
- return (listNode == null ? void 0 : listNode[0].type) === type;
3814
- };
3815
3773
 
3816
- /**
3817
- * Build a new list item node while preserving marks
3818
- */
3774
+ var previousSiblingItem = slate.Editor.node(editor, previousListItemPath);
3819
3775
 
3820
- var emptyListItemNode = function emptyListItemNode(editor, withChildren) {
3821
- if (withChildren === void 0) {
3822
- withChildren = false;
3823
- }
3776
+ if (previousSiblingItem) {
3777
+ var previousPath = previousSiblingItem[1];
3778
+ var subList = Array.from(slate.Node.children(editor, previousPath)).find(function (_ref2) {
3779
+ var n = _ref2[0];
3780
+ return plateCore.match(n, {
3781
+ type: plateList.getListTypes(editor)
3782
+ });
3783
+ });
3784
+ var newPath = slate.Path.next(plateCore.getLastChildPath(subList != null ? subList : previousSiblingItem));
3785
+ slate.Editor.withoutNormalizing(editor, function () {
3786
+ if (!subList) {
3787
+ // Create new sub-list
3788
+ plateCore.wrapNodes(editor, {
3789
+ type: listNode.type,
3790
+ children: [],
3791
+ data: {}
3792
+ }, {
3793
+ at: listItemPath
3794
+ });
3795
+ } // Move the current item to the sub-list
3824
3796
 
3825
- var children = [];
3826
3797
 
3827
- if (withChildren) {
3828
- var marks = slate.Editor.marks(editor) || {};
3829
- children = [{
3830
- type: Contentful.BLOCKS.PARAGRAPH,
3831
- data: {},
3832
- children: [_extends({
3833
- text: ''
3834
- }, marks)]
3835
- }];
3798
+ slate.Transforms.moveNodes(editor, {
3799
+ at: listItemPath,
3800
+ to: newPath
3801
+ });
3802
+ });
3836
3803
  }
3837
-
3838
- return {
3839
- type: Contentful.BLOCKS.LIST_ITEM,
3840
- data: {},
3841
- children: children
3842
- };
3843
3804
  };
3805
+
3844
3806
  /**
3845
- * Insert list item if selection is in li>p.
3807
+ * Credit: Modified version of Plate's list plugin
3808
+ * See: https://github.com/udecode/plate/blob/main/packages/nodes/list
3846
3809
  */
3810
+ var moveListItems = function moveListItems(editor, _temp) {
3811
+ var _editor$selection;
3847
3812
 
3813
+ var _ref = _temp === void 0 ? {} : _temp,
3814
+ _ref$increase = _ref.increase,
3815
+ increase = _ref$increase === void 0 ? true : _ref$increase,
3816
+ _ref$at = _ref.at,
3817
+ at = _ref$at === void 0 ? (_editor$selection = editor.selection) != null ? _editor$selection : undefined : _ref$at;
3848
3818
 
3849
- var insertListItem = function insertListItem(editor) {
3850
- if (!editor.selection) {
3851
- return false;
3852
- } // Naming it paragraph for simplicity but can be a heading as well
3853
-
3854
-
3855
- var paragraph = plateCore.getAbove(editor, {
3819
+ var _nodes = plateCore.getNodes(editor, {
3820
+ at: at,
3856
3821
  match: {
3857
- type: Contentful.TEXT_CONTAINERS
3822
+ type: plateCore.getPluginType(editor, plateList.ELEMENT_LIC)
3858
3823
  }
3859
- });
3860
-
3861
- if (!paragraph) {
3862
- return false;
3863
- }
3864
-
3865
- var paragraphPath = paragraph[1];
3866
- var listItem = plateCore.getParent(editor, paragraphPath);
3867
-
3868
- if (!listItem) {
3869
- return false;
3870
- }
3824
+ }); // Get the selected lic
3871
3825
 
3872
- var listItemNode = listItem[0],
3873
- listItemPath = listItem[1];
3874
3826
 
3875
- if (listItemNode.type !== Contentful.BLOCKS.LIST_ITEM) {
3876
- return false;
3877
- } // We are in a li>p (or heading)
3827
+ var lics = Array.from(_nodes);
3828
+ if (!lics.length) return;
3829
+ var highestLicPaths = [];
3830
+ var highestLicPathRefs = []; // Filter out the nested lic, we just need to move the highest ones
3878
3831
 
3832
+ lics.forEach(function (lic) {
3833
+ var licPath = lic[1];
3834
+ var liPath = slate.Path.parent(licPath);
3835
+ var isAncestor = highestLicPaths.some(function (path) {
3836
+ var highestLiPath = slate.Path.parent(path);
3837
+ return slate.Path.isAncestor(highestLiPath, liPath);
3838
+ });
3879
3839
 
3840
+ if (!isAncestor) {
3841
+ highestLicPaths.push(licPath);
3842
+ highestLicPathRefs.push(slate.Editor.pathRef(editor, licPath));
3843
+ }
3844
+ });
3845
+ var licPathRefsToMove = increase ? highestLicPathRefs : highestLicPathRefs.reverse();
3880
3846
  slate.Editor.withoutNormalizing(editor, function () {
3881
- if (!editor.selection) {
3882
- return;
3883
- } // Check the cursor position in the current paragraph
3884
-
3885
-
3886
- var isAtStart = plateCore.isSelectionAtBlockStart(editor);
3887
- var isAtEnd = plateCore.isSelectionAtBlockEnd(editor);
3888
- var isAtStartOfListItem = isAtStart && plateCore.isFirstChild(paragraphPath);
3889
- var shouldSplit = !isAtStart && !isAtEnd; // Split the current paragraph content if necessary
3890
-
3891
- if (shouldSplit) {
3892
- slate.Transforms.splitNodes(editor);
3893
- } // Insert the new li
3894
-
3895
-
3896
- var newListItemPath = isAtStartOfListItem ? listItemPath : slate.Path.next(listItemPath);
3897
- plateCore.insertNodes(editor, // Add an empty paragraph to the new li if We will not move some
3898
- // paragraphs over there.
3899
- emptyListItemNode(editor, !shouldSplit), {
3900
- at: newListItemPath
3901
- }); // Move children *after* selection to the new li
3902
-
3903
- var fromPath = isAtStart ? paragraphPath : slate.Path.next(paragraphPath);
3904
- var fromStartIndex = fromPath[fromPath.length - 1] || 0; // On split we don't add paragraph to the new li so we move
3905
- // content to the very beginning. Otherwise, account for the empty
3906
- // paragraph at the beginning by moving the content after
3907
-
3908
- var toPath = newListItemPath.concat([shouldSplit ? 0 : 1]);
3909
-
3910
- if (!isAtStartOfListItem) {
3911
- plateCore.moveChildren(editor, {
3912
- at: listItemPath,
3913
- to: toPath,
3914
- fromStartIndex: fromStartIndex
3847
+ licPathRefsToMove.forEach(function (licPathRef) {
3848
+ var licPath = licPathRef.unref();
3849
+ if (!licPath) return;
3850
+ var liEntry = plateList.getListItemEntry(editor, {
3851
+ at: licPath
3915
3852
  });
3916
- } // Move cursor to the start of the new li
3917
3853
 
3854
+ if (!liEntry) {
3855
+ return;
3856
+ }
3918
3857
 
3919
- slate.Transforms.select(editor, newListItemPath);
3920
- slate.Transforms.collapse(editor, {
3921
- edge: 'start'
3858
+ if (increase) {
3859
+ moveListItemDown(editor, liEntry);
3860
+ } else if (plateList.isListNested(editor, liEntry.list[1])) {
3861
+ plateList.moveListItemUp(editor, liEntry);
3862
+ }
3922
3863
  });
3923
- }); // Returning True skips processing other editor.insertBreak handlers
3924
-
3925
- return true;
3864
+ });
3926
3865
  };
3927
3866
 
3928
3867
  /**
3929
- * Credit: Copied & modified version from Plate's list plugin to support
3930
- * list items with multiple children.
3931
- *
3868
+ * Credit: Modified version of Plate's list plugin
3932
3869
  * See: https://github.com/udecode/plate/blob/main/packages/nodes/list
3933
3870
  */
3871
+ var listTypes = [Contentful.BLOCKS.UL_LIST, Contentful.BLOCKS.OL_LIST];
3872
+ var unwrapList = function unwrapList(editor, _temp) {
3873
+ var _ref = _temp === void 0 ? {} : _temp,
3874
+ at = _ref.at;
3934
3875
 
3935
- var listBreak = function listBreak(editor) {
3936
- if (!editor.selection) return false;
3937
- var res = plateList.getListItemEntry(editor, {});
3938
- var moved; // If selection is in a li
3939
-
3940
- if (res) {
3941
- var list = res.list,
3942
- listItem = res.listItem;
3943
- var childNode = listItem[0].children[0]; // If selected li is empty, move it up.
3944
-
3945
- if (plateCore.isBlockAboveEmpty(editor) && listItem[0].children.length === 1 && Contentful.TEXT_CONTAINERS.includes(childNode.type)) {
3946
- moved = plateList.moveListItemUp(editor, {
3947
- list: list,
3948
- listItem: listItem
3949
- });
3950
- if (moved) return true;
3951
- }
3952
- }
3953
-
3954
- var didReset = plateResetNode.onKeyDownResetNode(editor, plateCore.mockPlugin({
3955
- options: {
3956
- rules: [{
3957
- types: [plateCore.getPluginType(editor, plateList.ELEMENT_LI)],
3958
- defaultType: plateCore.getPluginType(editor, plateCore.ELEMENT_DEFAULT),
3959
- predicate: function predicate() {
3960
- return !moved && plateCore.isBlockAboveEmpty(editor);
3876
+ slate.Editor.withoutNormalizing(editor, function () {
3877
+ do {
3878
+ plateCore.unwrapNodes(editor, {
3879
+ at: at,
3880
+ match: {
3881
+ type: Contentful.BLOCKS.LIST_ITEM
3961
3882
  },
3962
- onReset: function onReset(_editor) {
3963
- return plateList.unwrapList(_editor);
3964
- }
3883
+ split: true
3884
+ });
3885
+ plateCore.unwrapNodes(editor, {
3886
+ at: at,
3887
+ match: {
3888
+ type: listTypes
3889
+ },
3890
+ split: true
3891
+ });
3892
+ } while (plateCore.getAbove(editor, {
3893
+ match: {
3894
+ type: listTypes,
3895
+ at: at
3896
+ }
3897
+ }));
3898
+ });
3899
+ };
3900
+
3901
+ var listTypes$1 = [Contentful.BLOCKS.UL_LIST, Contentful.BLOCKS.OL_LIST];
3902
+ var toggleList = function toggleList(editor, _ref) {
3903
+ var type = _ref.type;
3904
+ return slate.Editor.withoutNormalizing(editor, function () {
3905
+ if (!editor.selection) {
3906
+ return;
3907
+ }
3908
+
3909
+ if (plateCore.isCollapsed(editor.selection) || !plateCore.isRangeAcrossBlocks(editor)) {
3910
+ // selection is collapsed
3911
+ var res = plateList.getListItemEntry(editor);
3912
+
3913
+ if (res) {
3914
+ var list = res.list;
3915
+
3916
+ if (list[0].type !== type) {
3917
+ plateCore.setNodes(editor, {
3918
+ type: type
3919
+ }, {
3920
+ at: editor.selection,
3921
+ match: function match(n) {
3922
+ return listTypes$1.includes(n.type);
3923
+ },
3924
+ mode: 'lowest'
3925
+ });
3926
+ } else {
3927
+ unwrapList(editor);
3928
+ }
3929
+ } else {
3930
+ var _list = {
3931
+ type: type,
3932
+ children: [],
3933
+ data: {}
3934
+ };
3935
+ plateCore.wrapNodes(editor, _list);
3936
+ var nodes = [].concat(plateCore.getNodes(editor, {
3937
+ match: {
3938
+ type: plateCore.getPluginType(editor, plateCore.ELEMENT_DEFAULT)
3939
+ }
3940
+ }));
3941
+ var listItem = {
3942
+ type: Contentful.BLOCKS.LIST_ITEM,
3943
+ children: [],
3944
+ data: {}
3945
+ };
3946
+
3947
+ for (var _iterator = _createForOfIteratorHelperLoose(nodes), _step; !(_step = _iterator()).done;) {
3948
+ var _step$value = _step.value,
3949
+ path = _step$value[1];
3950
+ plateCore.wrapNodes(editor, listItem, {
3951
+ at: path
3952
+ });
3953
+ }
3954
+ }
3955
+ } else {
3956
+ // selection is a range
3957
+ var _Range$edges = slate.Range.edges(editor.selection),
3958
+ startPoint = _Range$edges[0],
3959
+ endPoint = _Range$edges[1];
3960
+
3961
+ var commonEntry = slate.Node.common(editor, startPoint.path, endPoint.path);
3962
+
3963
+ if (listTypes$1.includes(commonEntry[0].type) || commonEntry[0].type === Contentful.BLOCKS.LIST_ITEM) {
3964
+ if (commonEntry[0].type !== type) {
3965
+ var startList = plateCore.findNode(editor, {
3966
+ at: slate.Range.start(editor.selection),
3967
+ match: {
3968
+ type: listTypes$1
3969
+ },
3970
+ mode: 'lowest'
3971
+ });
3972
+ var endList = plateCore.findNode(editor, {
3973
+ at: slate.Range.end(editor.selection),
3974
+ match: {
3975
+ type: listTypes$1
3976
+ },
3977
+ mode: 'lowest'
3978
+ });
3979
+
3980
+ if (!startList || !endList) {
3981
+ return;
3982
+ }
3983
+
3984
+ var rangeLength = Math.min(startList[1].length, endList[1].length);
3985
+ plateCore.setNodes(editor, {
3986
+ type: type
3987
+ }, {
3988
+ at: editor.selection,
3989
+ match: function match(n, path) {
3990
+ return listTypes$1.includes(n.type) && path.length >= rangeLength;
3991
+ },
3992
+ mode: 'all'
3993
+ });
3994
+ } else {
3995
+ unwrapList(editor);
3996
+ }
3997
+ } else {
3998
+ var rootPathLength = commonEntry[1].length;
3999
+
4000
+ var _nodes = Array.from(plateCore.getNodes(editor, {
4001
+ mode: 'all'
4002
+ })).filter(function (_ref2) {
4003
+ var path = _ref2[1];
4004
+ return path.length === rootPathLength + 1;
4005
+ }).reverse();
4006
+
4007
+ _nodes.forEach(function (n) {
4008
+ if (listTypes$1.includes(n[0].type)) {
4009
+ plateCore.setNodes(editor, {
4010
+ type: type
4011
+ }, {
4012
+ at: n[1]
4013
+ });
4014
+ } else {
4015
+ plateCore.setNodes(editor, {
4016
+ type: plateCore.getPluginType(editor, plateList.ELEMENT_LIC)
4017
+ }, {
4018
+ at: n[1]
4019
+ });
4020
+ var _listItem = {
4021
+ type: Contentful.BLOCKS.LIST_ITEM,
4022
+ children: [],
4023
+ data: {}
4024
+ };
4025
+ plateCore.wrapNodes(editor, _listItem, {
4026
+ at: n[1]
4027
+ });
4028
+ var _list2 = {
4029
+ type: type,
4030
+ children: [],
4031
+ data: {}
4032
+ };
4033
+ plateCore.wrapNodes(editor, _list2, {
4034
+ at: n[1]
4035
+ });
4036
+ }
4037
+ });
4038
+ }
4039
+ }
4040
+ });
4041
+ };
4042
+
4043
+ var onKeyDownList = function onKeyDownList(editor, _ref) {
4044
+ var type = _ref.type,
4045
+ hotkey = _ref.options.hotkey;
4046
+ return function (e) {
4047
+ if (e.key === 'Tab' && editor.selection) {
4048
+ var listSelected = plateCore.getAbove(editor, {
4049
+ at: editor.selection,
4050
+ match: {
4051
+ type: type
4052
+ }
4053
+ });
4054
+
4055
+ if (listSelected) {
4056
+ e.preventDefault();
4057
+ moveListItems(editor, {
4058
+ increase: !e.shiftKey
4059
+ });
4060
+ return;
4061
+ }
4062
+ }
4063
+
4064
+ if (!hotkey) return;
4065
+ var hotkeys = castArray(hotkey);
4066
+
4067
+ for (var _iterator = _createForOfIteratorHelperLoose(hotkeys), _step; !(_step = _iterator()).done;) {
4068
+ var _hotkey = _step.value;
4069
+
4070
+ if (isHotkey(_hotkey)(e)) {
4071
+ toggleList(editor, {
4072
+ type: type
4073
+ });
4074
+ }
4075
+ }
4076
+ };
4077
+ };
4078
+
4079
+ var isList = function isList(node) {
4080
+ return [Contentful.BLOCKS.OL_LIST, Contentful.BLOCKS.UL_LIST].includes(node.type);
4081
+ };
4082
+
4083
+ var hasListAsDirectParent = function hasListAsDirectParent(editor, _ref) {
4084
+ var path = _ref[1];
4085
+
4086
+ var _ref2 = plateCore.getParent(editor, path) || [],
4087
+ parentNode = _ref2[0];
4088
+
4089
+ return isList(parentNode);
4090
+ };
4091
+
4092
+ var getNearestListAncestor = function getNearestListAncestor(editor, path) {
4093
+ return plateCore.getAbove(editor, {
4094
+ at: path,
4095
+ mode: 'lowest',
4096
+ match: isList
4097
+ }) || [];
4098
+ };
4099
+ /**
4100
+ * Places orphaned list items in a list. If there's a list somewhere
4101
+ * in the node's ancestors, defaults to that list type, else places
4102
+ * the list item in an unordered list.
4103
+ */
4104
+
4105
+
4106
+ var normalizeOrphanedListItem = function normalizeOrphanedListItem(editor, _ref3) {
4107
+ var path = _ref3[1];
4108
+
4109
+ var _getNearestListAncest = getNearestListAncestor(editor, path),
4110
+ parentList = _getNearestListAncest[0];
4111
+
4112
+ var parentListType = parentList == null ? void 0 : parentList.type;
4113
+ slate.Transforms.wrapNodes(editor, {
4114
+ type: parentListType || Contentful.BLOCKS.UL_LIST,
4115
+ children: [],
4116
+ data: {}
4117
+ }, {
4118
+ at: path
4119
+ });
4120
+ };
4121
+ var isNonEmptyListItem = function isNonEmptyListItem(editor, _ref4) {
4122
+ var path = _ref4[1];
4123
+ var listItemChildren = Array.from(slate.Node.children(editor, path));
4124
+ return listItemChildren.length !== 0;
4125
+ };
4126
+ var firstNodeIsNotList = function firstNodeIsNotList(_editor, _ref5) {
4127
+ var node = _ref5[0];
4128
+
4129
+ if (node.children.length === 1) {
4130
+ var firstNode = node.children[0];
4131
+ return !slate.Text.isText(firstNode) && !isList(firstNode);
4132
+ }
4133
+
4134
+ return true;
4135
+ };
4136
+ var insertParagraphAsChild = function insertParagraphAsChild(editor, _ref6) {
4137
+ var path = _ref6[1];
4138
+ slate.Transforms.insertNodes(editor, [{
4139
+ type: Contentful.BLOCKS.PARAGRAPH,
4140
+ data: {},
4141
+ children: [{
4142
+ text: ''
4143
+ }]
4144
+ }], {
4145
+ at: path.concat([0])
4146
+ });
4147
+ };
4148
+ var replaceNodeWithListItems = function replaceNodeWithListItems(editor, entry) {
4149
+ var node = entry[0],
4150
+ path = entry[1];
4151
+ slate.Transforms.removeNodes(editor, {
4152
+ at: path
4153
+ });
4154
+ slate.Transforms.insertNodes(editor, node.children[0].children, {
4155
+ at: path
4156
+ });
4157
+ };
4158
+ var isListTypeActive = function isListTypeActive(editor, type) {
4159
+ var selection = editor.selection;
4160
+
4161
+ if (!selection) {
4162
+ return false;
4163
+ }
4164
+
4165
+ if (slate.Range.isExpanded(selection)) {
4166
+ var _Range$edges = slate.Range.edges(selection),
4167
+ start = _Range$edges[0],
4168
+ end = _Range$edges[1];
4169
+
4170
+ var node = slate.Node.common(editor, start.path, end.path);
4171
+
4172
+ if (node[0].type === type) {
4173
+ return true;
4174
+ }
4175
+ } // Lists can be nested. Here, we take the list type at the lowest level
4176
+
4177
+
4178
+ var listNode = plateCore.getBlockAbove(editor, {
4179
+ match: {
4180
+ type: [Contentful.BLOCKS.OL_LIST, Contentful.BLOCKS.UL_LIST]
4181
+ },
4182
+ mode: 'lowest'
4183
+ });
4184
+ return (listNode == null ? void 0 : listNode[0].type) === type;
4185
+ };
4186
+
4187
+ /**
4188
+ * Build a new list item node while preserving marks
4189
+ */
4190
+
4191
+ var emptyListItemNode = function emptyListItemNode(editor, withChildren) {
4192
+ if (withChildren === void 0) {
4193
+ withChildren = false;
4194
+ }
4195
+
4196
+ var children = [];
4197
+
4198
+ if (withChildren) {
4199
+ var marks = slate.Editor.marks(editor) || {};
4200
+ children = [{
4201
+ type: Contentful.BLOCKS.PARAGRAPH,
4202
+ data: {},
4203
+ children: [_extends({
4204
+ text: ''
4205
+ }, marks)]
4206
+ }];
4207
+ }
4208
+
4209
+ return {
4210
+ type: Contentful.BLOCKS.LIST_ITEM,
4211
+ data: {},
4212
+ children: children
4213
+ };
4214
+ };
4215
+ /**
4216
+ * Insert list item if selection is in li>p.
4217
+ */
4218
+
4219
+
4220
+ var insertListItem = function insertListItem(editor) {
4221
+ if (!editor.selection) {
4222
+ return false;
4223
+ } // Naming it paragraph for simplicity but can be a heading as well
4224
+
4225
+
4226
+ var paragraph = plateCore.getAbove(editor, {
4227
+ match: {
4228
+ type: Contentful.TEXT_CONTAINERS
4229
+ }
4230
+ });
4231
+
4232
+ if (!paragraph) {
4233
+ return false;
4234
+ }
4235
+
4236
+ var paragraphPath = paragraph[1];
4237
+ var listItem = plateCore.getParent(editor, paragraphPath);
4238
+
4239
+ if (!listItem) {
4240
+ return false;
4241
+ }
4242
+
4243
+ var listItemNode = listItem[0],
4244
+ listItemPath = listItem[1];
4245
+
4246
+ if (listItemNode.type !== Contentful.BLOCKS.LIST_ITEM) {
4247
+ return false;
4248
+ } // We are in a li>p (or heading)
4249
+
4250
+
4251
+ slate.Editor.withoutNormalizing(editor, function () {
4252
+ if (!editor.selection) {
4253
+ return;
4254
+ } // Check the cursor position in the current paragraph
4255
+
4256
+
4257
+ var isAtStart = plateCore.isSelectionAtBlockStart(editor);
4258
+ var isAtEnd = plateCore.isSelectionAtBlockEnd(editor);
4259
+ var isAtStartOfListItem = isAtStart && plateCore.isFirstChild(paragraphPath);
4260
+ var shouldSplit = !isAtStart && !isAtEnd; // Split the current paragraph content if necessary
4261
+
4262
+ if (shouldSplit) {
4263
+ slate.Transforms.splitNodes(editor);
4264
+ } // Insert the new li
4265
+
4266
+
4267
+ var newListItemPath = isAtStartOfListItem ? listItemPath : slate.Path.next(listItemPath);
4268
+ plateCore.insertNodes(editor, // Add an empty paragraph to the new li if We will not move some
4269
+ // paragraphs over there.
4270
+ emptyListItemNode(editor, !shouldSplit), {
4271
+ at: newListItemPath
4272
+ }); // Move children *after* selection to the new li
4273
+
4274
+ var fromPath = isAtStart ? paragraphPath : slate.Path.next(paragraphPath);
4275
+ var fromStartIndex = fromPath[fromPath.length - 1] || 0; // On split we don't add paragraph to the new li so we move
4276
+ // content to the very beginning. Otherwise, account for the empty
4277
+ // paragraph at the beginning by moving the content after
4278
+
4279
+ var toPath = newListItemPath.concat([shouldSplit ? 0 : 1]);
4280
+
4281
+ if (!isAtStartOfListItem) {
4282
+ plateCore.moveChildren(editor, {
4283
+ at: listItemPath,
4284
+ to: toPath,
4285
+ fromStartIndex: fromStartIndex
4286
+ });
4287
+ } // Move cursor to the start of the new li
4288
+
4289
+
4290
+ slate.Transforms.select(editor, newListItemPath);
4291
+ slate.Transforms.collapse(editor, {
4292
+ edge: 'start'
4293
+ });
4294
+ }); // Returning True skips processing other editor.insertBreak handlers
4295
+
4296
+ return true;
4297
+ };
4298
+
4299
+ /**
4300
+ * Credit: Copied & modified version from Plate's list plugin to support
4301
+ * list items with multiple children.
4302
+ *
4303
+ * See: https://github.com/udecode/plate/blob/main/packages/nodes/list
4304
+ */
4305
+
4306
+ var listBreak = function listBreak(editor) {
4307
+ if (!editor.selection) return false;
4308
+ var res = plateList.getListItemEntry(editor, {});
4309
+ var moved; // If selection is in a li
4310
+
4311
+ if (res) {
4312
+ var list = res.list,
4313
+ listItem = res.listItem;
4314
+ var childNode = listItem[0].children[0]; // If selected li is empty, move it up.
4315
+
4316
+ if (plateCore.isBlockAboveEmpty(editor) && listItem[0].children.length === 1 && Contentful.TEXT_CONTAINERS.includes(childNode.type)) {
4317
+ moved = plateList.moveListItemUp(editor, {
4318
+ list: list,
4319
+ listItem: listItem
4320
+ });
4321
+ if (moved) return true;
4322
+ }
4323
+ }
4324
+
4325
+ var didReset = plateResetNode.onKeyDownResetNode(editor, plateCore.mockPlugin({
4326
+ options: {
4327
+ rules: [{
4328
+ types: [plateCore.getPluginType(editor, plateList.ELEMENT_LI)],
4329
+ defaultType: plateCore.getPluginType(editor, plateCore.ELEMENT_DEFAULT),
4330
+ predicate: function predicate() {
4331
+ return !moved && plateCore.isBlockAboveEmpty(editor);
4332
+ },
4333
+ onReset: function onReset(_editor) {
4334
+ return plateList.unwrapList(_editor);
4335
+ }
3965
4336
  }]
3966
4337
  }
3967
4338
  }))(plateResetNode.SIMULATE_BACKSPACE);
@@ -4092,50 +4463,16 @@ var insertListFragment = function insertListFragment(editor) {
4092
4463
  select: true
4093
4464
  });
4094
4465
  return slate.Transforms.insertNodes(editor, blocks, {
4095
- at: editor.selection,
4096
- select: true
4097
- });
4098
- }
4099
-
4100
- var filtered = isListRoot(fragment[0]) ? [{
4101
- text: ''
4102
- }].concat(fragment) : fragment;
4103
- return insertFragment(filtered);
4104
- };
4105
- };
4106
-
4107
- /**
4108
- * Credit: Modified version of Plate's list plugin
4109
- * See: https://github.com/udecode/plate/blob/main/packages/nodes/list
4110
- */
4111
- var listTypes = [Contentful.BLOCKS.UL_LIST, Contentful.BLOCKS.OL_LIST];
4112
- var unwrapList = function unwrapList(editor, _temp) {
4113
- var _ref = _temp === void 0 ? {} : _temp,
4114
- at = _ref.at;
4115
-
4116
- slate.Editor.withoutNormalizing(editor, function () {
4117
- do {
4118
- plateCore.unwrapNodes(editor, {
4119
- at: at,
4120
- match: {
4121
- type: Contentful.BLOCKS.LIST_ITEM
4122
- },
4123
- split: true
4124
- });
4125
- plateCore.unwrapNodes(editor, {
4126
- at: at,
4127
- match: {
4128
- type: listTypes
4129
- },
4130
- split: true
4131
- });
4132
- } while (plateCore.getAbove(editor, {
4133
- match: {
4134
- type: listTypes,
4135
- at: at
4136
- }
4137
- }));
4138
- });
4466
+ at: editor.selection,
4467
+ select: true
4468
+ });
4469
+ }
4470
+
4471
+ var filtered = isListRoot(fragment[0]) ? [{
4472
+ text: ''
4473
+ }].concat(fragment) : fragment;
4474
+ return insertFragment(filtered);
4475
+ };
4139
4476
  };
4140
4477
 
4141
4478
  /**
@@ -4247,12 +4584,18 @@ var createListPlugin = function createListPlugin() {
4247
4584
  overrideByKey: (_overrideByKey = {}, _overrideByKey[plateList.ELEMENT_UL] = {
4248
4585
  type: Contentful.BLOCKS.UL_LIST,
4249
4586
  component: ListUL,
4587
+ handlers: {
4588
+ onKeyDown: onKeyDownList
4589
+ },
4250
4590
  // The withList is added on ELEMENT_UL plugin in upstream code
4251
4591
  // so we need to override it here
4252
4592
  withOverrides: withList
4253
4593
  }, _overrideByKey[plateList.ELEMENT_OL] = {
4254
4594
  type: Contentful.BLOCKS.OL_LIST,
4255
- component: ListOL
4595
+ component: ListOL,
4596
+ handlers: {
4597
+ onKeyDown: onKeyDownList
4598
+ }
4256
4599
  }, _overrideByKey[plateList.ELEMENT_LIC] = {
4257
4600
  type: Contentful.BLOCKS.PARAGRAPH
4258
4601
  }, _overrideByKey[plateList.ELEMENT_LI] = {
@@ -4276,148 +4619,6 @@ var createListPlugin = function createListPlugin() {
4276
4619
  });
4277
4620
  };
4278
4621
 
4279
- var listTypes$1 = [Contentful.BLOCKS.UL_LIST, Contentful.BLOCKS.OL_LIST];
4280
- var toggleList = function toggleList(editor, _ref) {
4281
- var type = _ref.type;
4282
- return slate.Editor.withoutNormalizing(editor, function () {
4283
- if (!editor.selection) {
4284
- return;
4285
- }
4286
-
4287
- if (plateCore.isCollapsed(editor.selection) || !plateCore.isRangeAcrossBlocks(editor)) {
4288
- // selection is collapsed
4289
- var res = plateList.getListItemEntry(editor);
4290
-
4291
- if (res) {
4292
- var list = res.list;
4293
-
4294
- if (list[0].type !== type) {
4295
- plateCore.setNodes(editor, {
4296
- type: type
4297
- }, {
4298
- at: editor.selection,
4299
- match: function match(n) {
4300
- return listTypes$1.includes(n.type);
4301
- },
4302
- mode: 'lowest'
4303
- });
4304
- } else {
4305
- unwrapList(editor);
4306
- }
4307
- } else {
4308
- var _list = {
4309
- type: type,
4310
- children: [],
4311
- data: {}
4312
- };
4313
- plateCore.wrapNodes(editor, _list);
4314
- var nodes = [].concat(plateCore.getNodes(editor, {
4315
- match: {
4316
- type: plateCore.getPluginType(editor, plateCore.ELEMENT_DEFAULT)
4317
- }
4318
- }));
4319
- var listItem = {
4320
- type: Contentful.BLOCKS.LIST_ITEM,
4321
- children: [],
4322
- data: {}
4323
- };
4324
-
4325
- for (var _iterator = _createForOfIteratorHelperLoose(nodes), _step; !(_step = _iterator()).done;) {
4326
- var _step$value = _step.value,
4327
- path = _step$value[1];
4328
- plateCore.wrapNodes(editor, listItem, {
4329
- at: path
4330
- });
4331
- }
4332
- }
4333
- } else {
4334
- // selection is a range
4335
- var _Range$edges = slate.Range.edges(editor.selection),
4336
- startPoint = _Range$edges[0],
4337
- endPoint = _Range$edges[1];
4338
-
4339
- var commonEntry = slate.Node.common(editor, startPoint.path, endPoint.path);
4340
-
4341
- if (listTypes$1.includes(commonEntry[0].type) || commonEntry[0].type === Contentful.BLOCKS.LIST_ITEM) {
4342
- if (commonEntry[0].type !== type) {
4343
- var startList = plateCore.findNode(editor, {
4344
- at: slate.Range.start(editor.selection),
4345
- match: {
4346
- type: listTypes$1
4347
- },
4348
- mode: 'lowest'
4349
- });
4350
- var endList = plateCore.findNode(editor, {
4351
- at: slate.Range.end(editor.selection),
4352
- match: {
4353
- type: listTypes$1
4354
- },
4355
- mode: 'lowest'
4356
- });
4357
-
4358
- if (!startList || !endList) {
4359
- return;
4360
- }
4361
-
4362
- var rangeLength = Math.min(startList[1].length, endList[1].length);
4363
- plateCore.setNodes(editor, {
4364
- type: type
4365
- }, {
4366
- at: editor.selection,
4367
- match: function match(n, path) {
4368
- return listTypes$1.includes(n.type) && path.length >= rangeLength;
4369
- },
4370
- mode: 'all'
4371
- });
4372
- } else {
4373
- unwrapList(editor);
4374
- }
4375
- } else {
4376
- var rootPathLength = commonEntry[1].length;
4377
-
4378
- var _nodes = Array.from(plateCore.getNodes(editor, {
4379
- mode: 'all'
4380
- })).filter(function (_ref2) {
4381
- var path = _ref2[1];
4382
- return path.length === rootPathLength + 1;
4383
- }).reverse();
4384
-
4385
- _nodes.forEach(function (n) {
4386
- if (listTypes$1.includes(n[0].type)) {
4387
- plateCore.setNodes(editor, {
4388
- type: type
4389
- }, {
4390
- at: n[1]
4391
- });
4392
- } else {
4393
- plateCore.setNodes(editor, {
4394
- type: plateCore.getPluginType(editor, plateList.ELEMENT_LIC)
4395
- }, {
4396
- at: n[1]
4397
- });
4398
- var _listItem = {
4399
- type: Contentful.BLOCKS.LIST_ITEM,
4400
- children: [],
4401
- data: {}
4402
- };
4403
- plateCore.wrapNodes(editor, _listItem, {
4404
- at: n[1]
4405
- });
4406
- var _list2 = {
4407
- type: type,
4408
- children: [],
4409
- data: {}
4410
- };
4411
- plateCore.wrapNodes(editor, _list2, {
4412
- at: n[1]
4413
- });
4414
- }
4415
- });
4416
- }
4417
- }
4418
- });
4419
- };
4420
-
4421
4622
  function ToolbarListButton(props) {
4422
4623
  var sdk = useSdkContext();
4423
4624
  var editor = useContentfulEditor();
@@ -6219,6 +6420,80 @@ var disableCorePlugins = {
6219
6420
  eventEditor: true
6220
6421
  };
6221
6422
 
6423
+ /**
6424
+ * For legacy reasons, a document may not have any content at all
6425
+ * e.g:
6426
+ *
6427
+ * {nodeType: document, data: {}, content: []}
6428
+ *
6429
+ * Rendering such document will break the Slate editor
6430
+ */
6431
+
6432
+ var hasContent = function hasContent(doc) {
6433
+ if (!doc) {
6434
+ return false;
6435
+ }
6436
+
6437
+ return doc.content.length > 0;
6438
+ };
6439
+ /*
6440
+ Plate api doesn't allow to modify (easily) the editor value programmatically
6441
+ after the editor instance is created
6442
+
6443
+ This function is inspired to https://github.com/udecode/plate/issues/1269#issuecomment-1057643622
6444
+ */
6445
+
6446
+ var setEditorContent = function setEditorContent(editor, nodes) {
6447
+ // Replaces editor content while keeping change history
6448
+ slate.Editor.withoutNormalizing(editor, function () {
6449
+ var children = [].concat(editor.children);
6450
+ children.forEach(function (node) {
6451
+ return editor.apply({
6452
+ type: 'remove_node',
6453
+ path: [0],
6454
+ node: node
6455
+ });
6456
+ });
6457
+
6458
+ if (nodes) {
6459
+ var nodesArray = slate.Node.isNode(nodes) ? [nodes] : nodes;
6460
+ nodesArray.forEach(function (node, i) {
6461
+ return editor.apply({
6462
+ type: 'insert_node',
6463
+ path: [i],
6464
+ node: node
6465
+ });
6466
+ });
6467
+ }
6468
+
6469
+ var point = slate.Editor.end(editor, []);
6470
+
6471
+ if (point) {
6472
+ slate.Transforms.select(editor, point);
6473
+ }
6474
+ });
6475
+ };
6476
+ /**
6477
+ * Converts a contenful rich text document to the corresponding slate editor
6478
+ * value
6479
+ */
6480
+
6481
+ var documentToEditorValue = function documentToEditorValue(doc) {
6482
+ return contentfulSlateJSAdapter.toSlatejsDocument({
6483
+ document: hasContent(doc) ? doc : Contentful.EMPTY_DOCUMENT,
6484
+ // TODO: get rid of schema, https://github.com/contentful/field-editors/pull/1065#discussion_r826723248
6485
+ schema: schema
6486
+ });
6487
+ };
6488
+ var normalizeEditorValue = function normalizeEditorValue(value, options) {
6489
+ var editor = plateCore.createPlateEditor(options);
6490
+ editor.children = value;
6491
+ slate.Editor.normalize(editor, {
6492
+ force: true
6493
+ });
6494
+ return editor.children;
6495
+ };
6496
+
6222
6497
  var STYLE_EDITOR_BORDER = "1px solid " + tokens.gray400;
6223
6498
  var styles$j = {
6224
6499
  root: /*#__PURE__*/emotion.css({
@@ -6315,7 +6590,17 @@ var EmbedEntityWidget = function EmbedEntityWidget(_ref) {
6315
6590
  setCanAccessAssets = _useState2[1];
6316
6591
 
6317
6592
  React__default.useEffect(function () {
6318
- sdk.access.can('read', 'Asset').then(setCanAccessAssets);
6593
+ var subscribed = true;
6594
+ sdk.access.can('read', 'Asset').then(function (can) {
6595
+ if (!subscribed) {
6596
+ return;
6597
+ }
6598
+
6599
+ setCanAccessAssets(can);
6600
+ });
6601
+ return function () {
6602
+ subscribed = false;
6603
+ };
6319
6604
  }, [sdk]);
6320
6605
  var inlineEntryEmbedEnabled = isNodeTypeEnabled(sdk.field, Contentful.INLINES.EMBEDDED_ENTRY);
6321
6606
  var blockEntryEmbedEnabled = isNodeTypeEnabled(sdk.field, Contentful.BLOCKS.EMBEDDED_ENTRY) && canInsertBlocks;
@@ -6470,50 +6755,6 @@ var StickyToolbarWrapper = function StickyToolbarWrapper(_ref) {
6470
6755
  }, children);
6471
6756
  };
6472
6757
 
6473
- /**
6474
- * For legacy reasons, a document may not have any content at all
6475
- * e.g:
6476
- *
6477
- * {nodeType: document, data: {}, content: []}
6478
- *
6479
- * Rendering such document will break the Slate editor
6480
- */
6481
-
6482
- var hasContent = function hasContent(doc) {
6483
- if (!doc) {
6484
- return false;
6485
- }
6486
-
6487
- return doc.content.length > 0;
6488
- };
6489
-
6490
- var useNormalizedSlateValue = function useNormalizedSlateValue(_ref) {
6491
- var id = _ref.id,
6492
- incomingDoc = _ref.incomingDoc,
6493
- plugins = _ref.plugins;
6494
- return React.useMemo(function () {
6495
- var editor = plateCore.createPlateEditor({
6496
- id: id,
6497
- plugins: plugins,
6498
- disableCorePlugins: disableCorePlugins
6499
- });
6500
- var doc = contentfulSlateJSAdapter.toSlatejsDocument({
6501
- document: hasContent(incomingDoc) ? incomingDoc : Contentful.EMPTY_DOCUMENT,
6502
- schema: schema
6503
- }); // Sets editor value & kicks normalization
6504
-
6505
- editor.children = doc;
6506
- slate.Editor.normalize(editor, {
6507
- force: true
6508
- }); // TODO: return the editor itself to avoid recompiling & initializing all
6509
- // of the plugins again. It's currently not possible due to a bug in Plate
6510
- // with initialValues
6511
- // See: https://slate-js.slack.com/archives/C013QHXSCG1/p1645112799942819
6512
-
6513
- return editor.children;
6514
- }, [id, plugins, incomingDoc]);
6515
- };
6516
-
6517
6758
  /**
6518
6759
  * Returns whether a given operation is relevant enough to trigger a save.
6519
6760
  */
@@ -6527,8 +6768,10 @@ var isRelevantOperation = function isRelevantOperation(op) {
6527
6768
  };
6528
6769
 
6529
6770
  var useOnValueChanged = function useOnValueChanged(_ref) {
6530
- var editor = _ref.editor,
6531
- handler = _ref.handler;
6771
+ var editorId = _ref.editorId,
6772
+ handler = _ref.handler,
6773
+ skip = _ref.skip,
6774
+ onSkip = _ref.onSkip;
6532
6775
  var onChange = React.useMemo(function () {
6533
6776
  return debounce(function (document) {
6534
6777
  handler == null ? void 0 : handler(contentfulSlateJSAdapter.toContentfulDocument({
@@ -6538,45 +6781,84 @@ var useOnValueChanged = function useOnValueChanged(_ref) {
6538
6781
  }, 500);
6539
6782
  }, [handler]);
6540
6783
  return React.useCallback(function (value) {
6541
- var operations = editor.operations.filter(isRelevantOperation);
6784
+ var editor = plateCore.getPlateSelectors(editorId).editor();
6785
+
6786
+ if (!editor) {
6787
+ throw new Error('Editor change callback called but editor not defined. Editor id: ' + editorId);
6788
+ }
6789
+
6790
+ var operations = editor == null ? void 0 : editor.operations.filter(isRelevantOperation);
6542
6791
 
6543
6792
  if (operations.length > 0) {
6793
+ if (skip) {
6794
+ onSkip == null ? void 0 : onSkip();
6795
+ return;
6796
+ }
6797
+
6544
6798
  onChange(value);
6545
6799
  }
6546
- }, [editor, onChange]);
6800
+ }, [editorId, onChange, skip, onSkip]);
6547
6801
  };
6548
6802
 
6549
6803
  var _excluded = ["sdk", "isInitiallyDisabled", "onAction"];
6550
6804
  var ConnectedRichTextEditor = function ConnectedRichTextEditor(props) {
6551
- var id = getContentfulEditorId(props.sdk); // TODO: remove in favor of getting the editor from useNormalizedSlateValue after upgrading to Plate v10
6552
-
6553
- var editor = useContentfulEditor(id);
6805
+ var id = getContentfulEditorId(props.sdk);
6554
6806
  var plugins = React__default.useMemo(function () {
6555
6807
  var _props$onAction;
6556
6808
 
6557
6809
  return getPlugins(props.sdk, (_props$onAction = props.onAction) != null ? _props$onAction : noop);
6558
6810
  }, [props.sdk, props.onAction]);
6559
- var initialValue = useNormalizedSlateValue({
6560
- id: id,
6561
- incomingDoc: props.value,
6562
- plugins: plugins
6563
- });
6811
+
6812
+ var _useState = React.useState(true),
6813
+ isFirstRender = _useState[0],
6814
+ setIsFirstRender = _useState[1];
6815
+
6816
+ var _useState2 = React.useState(false),
6817
+ pendingExternalUpdate = _useState2[0],
6818
+ setPendingExternalUpdate = _useState2[1];
6819
+
6564
6820
  var onValueChanged = useOnValueChanged({
6565
- editor: editor,
6566
- handler: props.onChange
6821
+ editorId: id,
6822
+ handler: props.onChange,
6823
+ skip: pendingExternalUpdate || isFirstRender,
6824
+ onSkip: function onSkip() {
6825
+ return setPendingExternalUpdate(false);
6826
+ }
6567
6827
  });
6828
+ React.useEffect(function () {
6829
+ /*
6830
+ This effect is called when the value prop changes. Normally
6831
+ this happens when the value is changed outside of the editor,
6832
+ like in snapshots restoration or remote updates
6833
+ Plate won't update the displayed value on its own, see:
6834
+ - https://github.com/ianstormtaylor/slate/pull/4540
6835
+ - https://github.com/udecode/plate/issues/1169
6836
+ The content is forcely set to the new value and it's ensured
6837
+ the change listener isn't invoked
6838
+ */
6839
+ setIsFirstRender(false);
6840
+ var editor = plateCore.getPlateSelectors(id).editor();
6841
+
6842
+ if (!editor) {
6843
+ return;
6844
+ }
6845
+
6846
+ setPendingExternalUpdate(true);
6847
+ setEditorContent(editor, documentToEditorValue(props.value));
6848
+ }, [props.value, id]);
6568
6849
  var classNames = emotion.cx(styles$j.editor, props.minHeight !== undefined ? emotion.css({
6569
6850
  minHeight: props.minHeight
6570
6851
  }) : undefined, props.isDisabled ? styles$j.disabled : styles$j.enabled, props.isToolbarHidden && styles$j.hiddenToolbar);
6571
6852
  React.useEffect(function () {
6572
- // Ensure the plate state is cleared after the component unmounts
6573
- // This prevent new editors for the same field to display old outdated values
6574
- // Typical scenario: coming back to the entry editor after restoring a previous entry version
6575
- plateCore.getPlateActions(id).enabled(true);
6576
- return function () {
6577
- return plateCore.getPlateActions(id).enabled(false);
6578
- };
6579
- }, [id]);
6853
+ if (!isFirstRender) {
6854
+ return;
6855
+ }
6856
+
6857
+ plateCore.getPlateActions(id).value(normalizeEditorValue(documentToEditorValue(props.value), {
6858
+ plugins: plugins,
6859
+ disableCorePlugins: disableCorePlugins
6860
+ }));
6861
+ }, [isFirstRender, plugins, id, props.value]);
6580
6862
  return /*#__PURE__*/React__default.createElement(SdkProvider, {
6581
6863
  sdk: props.sdk
6582
6864
  }, /*#__PURE__*/React__default.createElement(ContentfulEditorIdProvider, {
@@ -6586,7 +6868,6 @@ var ConnectedRichTextEditor = function ConnectedRichTextEditor(props) {
6586
6868
  "data-test-id": "rich-text-editor"
6587
6869
  }, /*#__PURE__*/React__default.createElement(plateCore.Plate, {
6588
6870
  id: id,
6589
- initialValue: initialValue,
6590
6871
  plugins: plugins,
6591
6872
  disableCorePlugins: disableCorePlugins,
6592
6873
  editableProps: {
@@ -6610,6 +6891,7 @@ var RichTextEditor = function RichTextEditor(props) {
6610
6891
  var isEmptyValue = React.useCallback(function (value) {
6611
6892
  return !value || deepEquals(value, Contentful.EMPTY_DOCUMENT);
6612
6893
  }, []);
6894
+ var id = getContentfulEditorId(props.sdk);
6613
6895
  return /*#__PURE__*/React__default.createElement(fieldEditorReference.EntityProvider, {
6614
6896
  sdk: sdk
6615
6897
  }, /*#__PURE__*/React__default.createElement(fieldEditorShared.FieldConnector, {
@@ -6621,10 +6903,9 @@ var RichTextEditor = function RichTextEditor(props) {
6621
6903
  }, function (_ref) {
6622
6904
  var lastRemoteValue = _ref.lastRemoteValue,
6623
6905
  disabled = _ref.disabled,
6624
- setValue = _ref.setValue,
6625
- externalReset = _ref.externalReset;
6906
+ setValue = _ref.setValue;
6626
6907
  return /*#__PURE__*/React__default.createElement(ConnectedRichTextEditor, Object.assign({}, otherProps, {
6627
- key: "rich-text-editor-" + externalReset,
6908
+ key: "rich-text-editor-" + id,
6628
6909
  value: lastRemoteValue,
6629
6910
  sdk: sdk,
6630
6911
  onAction: onAction,