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

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');
@@ -951,14 +952,22 @@ function FetchingWrappedEntryCard(props) {
951
952
  var onEntityFetchComplete = props.onEntityFetchComplete;
952
953
  React.useEffect(function () {
953
954
  if (!entry || entry === 'failed') return;
955
+ var subscribed = true;
954
956
  fieldEditorShared.entityHelpers.getEntryImage({
955
957
  entry: entry,
956
958
  contentType: contentType,
957
959
  localeCode: props.locale,
958
960
  defaultLocaleCode: defaultLocaleCode
959
- }, getOrLoadAsset).then(setFile)["catch"](function () {
960
- return setFile(null);
961
+ }, getOrLoadAsset)["catch"](function () {
962
+ return null;
963
+ }).then(function (file) {
964
+ if (subscribed) {
965
+ setFile(file);
966
+ }
961
967
  });
968
+ return function () {
969
+ subscribed = false;
970
+ };
962
971
  }, [entry, contentType, props.locale, defaultLocaleCode, props.sdk, file, getOrLoadAsset]);
963
972
  React.useEffect(function () {
964
973
  getOrLoadEntry(props.entryId);
@@ -3723,6 +3732,329 @@ function ListItem(props) {
3723
3732
  }), props.children);
3724
3733
  }
3725
3734
 
3735
+ /**
3736
+ * Credit: Modified version of Plate's list plugin
3737
+ * See: https://github.com/udecode/plate/blob/main/packages/nodes/list
3738
+ */
3739
+ var moveListItemDown = function moveListItemDown(editor, _ref) {
3740
+ var list = _ref.list,
3741
+ listItem = _ref.listItem;
3742
+ var listNode = list[0];
3743
+ var listItemPath = listItem[1];
3744
+ var previousListItemPath;
3745
+
3746
+ try {
3747
+ previousListItemPath = slate.Path.previous(listItemPath);
3748
+ } catch (e) {
3749
+ return;
3750
+ } // Previous sibling is the new parent
3751
+
3752
+
3753
+ var previousSiblingItem = slate.Editor.node(editor, previousListItemPath);
3754
+
3755
+ if (previousSiblingItem) {
3756
+ var previousPath = previousSiblingItem[1];
3757
+ var subList = Array.from(slate.Node.children(editor, previousPath)).find(function (_ref2) {
3758
+ var n = _ref2[0];
3759
+ return plateCore.match(n, {
3760
+ type: plateList.getListTypes(editor)
3761
+ });
3762
+ });
3763
+ var newPath = slate.Path.next(plateCore.getLastChildPath(subList != null ? subList : previousSiblingItem));
3764
+ slate.Editor.withoutNormalizing(editor, function () {
3765
+ if (!subList) {
3766
+ // Create new sub-list
3767
+ plateCore.wrapNodes(editor, {
3768
+ type: listNode.type,
3769
+ children: [],
3770
+ data: {}
3771
+ }, {
3772
+ at: listItemPath
3773
+ });
3774
+ } // Move the current item to the sub-list
3775
+
3776
+
3777
+ slate.Transforms.moveNodes(editor, {
3778
+ at: listItemPath,
3779
+ to: newPath
3780
+ });
3781
+ });
3782
+ }
3783
+ };
3784
+
3785
+ /**
3786
+ * Credit: Modified version of Plate's list plugin
3787
+ * See: https://github.com/udecode/plate/blob/main/packages/nodes/list
3788
+ */
3789
+ var moveListItems = function moveListItems(editor, _temp) {
3790
+ var _editor$selection;
3791
+
3792
+ var _ref = _temp === void 0 ? {} : _temp,
3793
+ _ref$increase = _ref.increase,
3794
+ increase = _ref$increase === void 0 ? true : _ref$increase,
3795
+ _ref$at = _ref.at,
3796
+ at = _ref$at === void 0 ? (_editor$selection = editor.selection) != null ? _editor$selection : undefined : _ref$at;
3797
+
3798
+ var _nodes = plateCore.getNodes(editor, {
3799
+ at: at,
3800
+ match: {
3801
+ type: plateCore.getPluginType(editor, plateList.ELEMENT_LIC)
3802
+ }
3803
+ }); // Get the selected lic
3804
+
3805
+
3806
+ var lics = Array.from(_nodes);
3807
+ if (!lics.length) return;
3808
+ var highestLicPaths = [];
3809
+ var highestLicPathRefs = []; // Filter out the nested lic, we just need to move the highest ones
3810
+
3811
+ lics.forEach(function (lic) {
3812
+ var licPath = lic[1];
3813
+ var liPath = slate.Path.parent(licPath);
3814
+ var isAncestor = highestLicPaths.some(function (path) {
3815
+ var highestLiPath = slate.Path.parent(path);
3816
+ return slate.Path.isAncestor(highestLiPath, liPath);
3817
+ });
3818
+
3819
+ if (!isAncestor) {
3820
+ highestLicPaths.push(licPath);
3821
+ highestLicPathRefs.push(slate.Editor.pathRef(editor, licPath));
3822
+ }
3823
+ });
3824
+ var licPathRefsToMove = increase ? highestLicPathRefs : highestLicPathRefs.reverse();
3825
+ slate.Editor.withoutNormalizing(editor, function () {
3826
+ licPathRefsToMove.forEach(function (licPathRef) {
3827
+ var licPath = licPathRef.unref();
3828
+ if (!licPath) return;
3829
+ var liEntry = plateList.getListItemEntry(editor, {
3830
+ at: licPath
3831
+ });
3832
+
3833
+ if (!liEntry) {
3834
+ return;
3835
+ }
3836
+
3837
+ if (increase) {
3838
+ moveListItemDown(editor, liEntry);
3839
+ } else if (plateList.isListNested(editor, liEntry.list[1])) {
3840
+ plateList.moveListItemUp(editor, liEntry);
3841
+ }
3842
+ });
3843
+ });
3844
+ };
3845
+
3846
+ /**
3847
+ * Credit: Modified version of Plate's list plugin
3848
+ * See: https://github.com/udecode/plate/blob/main/packages/nodes/list
3849
+ */
3850
+ var listTypes = [Contentful.BLOCKS.UL_LIST, Contentful.BLOCKS.OL_LIST];
3851
+ var unwrapList = function unwrapList(editor, _temp) {
3852
+ var _ref = _temp === void 0 ? {} : _temp,
3853
+ at = _ref.at;
3854
+
3855
+ slate.Editor.withoutNormalizing(editor, function () {
3856
+ do {
3857
+ plateCore.unwrapNodes(editor, {
3858
+ at: at,
3859
+ match: {
3860
+ type: Contentful.BLOCKS.LIST_ITEM
3861
+ },
3862
+ split: true
3863
+ });
3864
+ plateCore.unwrapNodes(editor, {
3865
+ at: at,
3866
+ match: {
3867
+ type: listTypes
3868
+ },
3869
+ split: true
3870
+ });
3871
+ } while (plateCore.getAbove(editor, {
3872
+ match: {
3873
+ type: listTypes,
3874
+ at: at
3875
+ }
3876
+ }));
3877
+ });
3878
+ };
3879
+
3880
+ var listTypes$1 = [Contentful.BLOCKS.UL_LIST, Contentful.BLOCKS.OL_LIST];
3881
+ var toggleList = function toggleList(editor, _ref) {
3882
+ var type = _ref.type;
3883
+ return slate.Editor.withoutNormalizing(editor, function () {
3884
+ if (!editor.selection) {
3885
+ return;
3886
+ }
3887
+
3888
+ if (plateCore.isCollapsed(editor.selection) || !plateCore.isRangeAcrossBlocks(editor)) {
3889
+ // selection is collapsed
3890
+ var res = plateList.getListItemEntry(editor);
3891
+
3892
+ if (res) {
3893
+ var list = res.list;
3894
+
3895
+ if (list[0].type !== type) {
3896
+ plateCore.setNodes(editor, {
3897
+ type: type
3898
+ }, {
3899
+ at: editor.selection,
3900
+ match: function match(n) {
3901
+ return listTypes$1.includes(n.type);
3902
+ },
3903
+ mode: 'lowest'
3904
+ });
3905
+ } else {
3906
+ unwrapList(editor);
3907
+ }
3908
+ } else {
3909
+ var _list = {
3910
+ type: type,
3911
+ children: [],
3912
+ data: {}
3913
+ };
3914
+ plateCore.wrapNodes(editor, _list);
3915
+ var nodes = [].concat(plateCore.getNodes(editor, {
3916
+ match: {
3917
+ type: plateCore.getPluginType(editor, plateCore.ELEMENT_DEFAULT)
3918
+ }
3919
+ }));
3920
+ var listItem = {
3921
+ type: Contentful.BLOCKS.LIST_ITEM,
3922
+ children: [],
3923
+ data: {}
3924
+ };
3925
+
3926
+ for (var _iterator = _createForOfIteratorHelperLoose(nodes), _step; !(_step = _iterator()).done;) {
3927
+ var _step$value = _step.value,
3928
+ path = _step$value[1];
3929
+ plateCore.wrapNodes(editor, listItem, {
3930
+ at: path
3931
+ });
3932
+ }
3933
+ }
3934
+ } else {
3935
+ // selection is a range
3936
+ var _Range$edges = slate.Range.edges(editor.selection),
3937
+ startPoint = _Range$edges[0],
3938
+ endPoint = _Range$edges[1];
3939
+
3940
+ var commonEntry = slate.Node.common(editor, startPoint.path, endPoint.path);
3941
+
3942
+ if (listTypes$1.includes(commonEntry[0].type) || commonEntry[0].type === Contentful.BLOCKS.LIST_ITEM) {
3943
+ if (commonEntry[0].type !== type) {
3944
+ var startList = plateCore.findNode(editor, {
3945
+ at: slate.Range.start(editor.selection),
3946
+ match: {
3947
+ type: listTypes$1
3948
+ },
3949
+ mode: 'lowest'
3950
+ });
3951
+ var endList = plateCore.findNode(editor, {
3952
+ at: slate.Range.end(editor.selection),
3953
+ match: {
3954
+ type: listTypes$1
3955
+ },
3956
+ mode: 'lowest'
3957
+ });
3958
+
3959
+ if (!startList || !endList) {
3960
+ return;
3961
+ }
3962
+
3963
+ var rangeLength = Math.min(startList[1].length, endList[1].length);
3964
+ plateCore.setNodes(editor, {
3965
+ type: type
3966
+ }, {
3967
+ at: editor.selection,
3968
+ match: function match(n, path) {
3969
+ return listTypes$1.includes(n.type) && path.length >= rangeLength;
3970
+ },
3971
+ mode: 'all'
3972
+ });
3973
+ } else {
3974
+ unwrapList(editor);
3975
+ }
3976
+ } else {
3977
+ var rootPathLength = commonEntry[1].length;
3978
+
3979
+ var _nodes = Array.from(plateCore.getNodes(editor, {
3980
+ mode: 'all'
3981
+ })).filter(function (_ref2) {
3982
+ var path = _ref2[1];
3983
+ return path.length === rootPathLength + 1;
3984
+ }).reverse();
3985
+
3986
+ _nodes.forEach(function (n) {
3987
+ if (listTypes$1.includes(n[0].type)) {
3988
+ plateCore.setNodes(editor, {
3989
+ type: type
3990
+ }, {
3991
+ at: n[1]
3992
+ });
3993
+ } else {
3994
+ plateCore.setNodes(editor, {
3995
+ type: plateCore.getPluginType(editor, plateList.ELEMENT_LIC)
3996
+ }, {
3997
+ at: n[1]
3998
+ });
3999
+ var _listItem = {
4000
+ type: Contentful.BLOCKS.LIST_ITEM,
4001
+ children: [],
4002
+ data: {}
4003
+ };
4004
+ plateCore.wrapNodes(editor, _listItem, {
4005
+ at: n[1]
4006
+ });
4007
+ var _list2 = {
4008
+ type: type,
4009
+ children: [],
4010
+ data: {}
4011
+ };
4012
+ plateCore.wrapNodes(editor, _list2, {
4013
+ at: n[1]
4014
+ });
4015
+ }
4016
+ });
4017
+ }
4018
+ }
4019
+ });
4020
+ };
4021
+
4022
+ var onKeyDownList = function onKeyDownList(editor, _ref) {
4023
+ var type = _ref.type,
4024
+ hotkey = _ref.options.hotkey;
4025
+ return function (e) {
4026
+ if (e.key === 'Tab' && editor.selection) {
4027
+ var listSelected = plateCore.getAbove(editor, {
4028
+ at: editor.selection,
4029
+ match: {
4030
+ type: type
4031
+ }
4032
+ });
4033
+
4034
+ if (listSelected) {
4035
+ e.preventDefault();
4036
+ moveListItems(editor, {
4037
+ increase: !e.shiftKey
4038
+ });
4039
+ return;
4040
+ }
4041
+ }
4042
+
4043
+ if (!hotkey) return;
4044
+ var hotkeys = castArray(hotkey);
4045
+
4046
+ for (var _iterator = _createForOfIteratorHelperLoose(hotkeys), _step; !(_step = _iterator()).done;) {
4047
+ var _hotkey = _step.value;
4048
+
4049
+ if (isHotkey(_hotkey)(e)) {
4050
+ toggleList(editor, {
4051
+ type: type
4052
+ });
4053
+ }
4054
+ }
4055
+ };
4056
+ };
4057
+
3726
4058
  var isList = function isList(node) {
3727
4059
  return [Contentful.BLOCKS.OL_LIST, Contentful.BLOCKS.UL_LIST].includes(node.type);
3728
4060
  };
@@ -4104,40 +4436,6 @@ var insertListFragment = function insertListFragment(editor) {
4104
4436
  };
4105
4437
  };
4106
4438
 
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
- });
4139
- };
4140
-
4141
4439
  /**
4142
4440
  * Credit: Modified version of Plate's list plugin
4143
4441
  * See: https://github.com/udecode/plate/blob/main/packages/nodes/list
@@ -4247,12 +4545,18 @@ var createListPlugin = function createListPlugin() {
4247
4545
  overrideByKey: (_overrideByKey = {}, _overrideByKey[plateList.ELEMENT_UL] = {
4248
4546
  type: Contentful.BLOCKS.UL_LIST,
4249
4547
  component: ListUL,
4548
+ handlers: {
4549
+ onKeyDown: onKeyDownList
4550
+ },
4250
4551
  // The withList is added on ELEMENT_UL plugin in upstream code
4251
4552
  // so we need to override it here
4252
4553
  withOverrides: withList
4253
4554
  }, _overrideByKey[plateList.ELEMENT_OL] = {
4254
4555
  type: Contentful.BLOCKS.OL_LIST,
4255
- component: ListOL
4556
+ component: ListOL,
4557
+ handlers: {
4558
+ onKeyDown: onKeyDownList
4559
+ }
4256
4560
  }, _overrideByKey[plateList.ELEMENT_LIC] = {
4257
4561
  type: Contentful.BLOCKS.PARAGRAPH
4258
4562
  }, _overrideByKey[plateList.ELEMENT_LI] = {
@@ -4276,148 +4580,6 @@ var createListPlugin = function createListPlugin() {
4276
4580
  });
4277
4581
  };
4278
4582
 
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
4583
  function ToolbarListButton(props) {
4422
4584
  var sdk = useSdkContext();
4423
4585
  var editor = useContentfulEditor();
@@ -6219,6 +6381,80 @@ var disableCorePlugins = {
6219
6381
  eventEditor: true
6220
6382
  };
6221
6383
 
6384
+ /**
6385
+ * For legacy reasons, a document may not have any content at all
6386
+ * e.g:
6387
+ *
6388
+ * {nodeType: document, data: {}, content: []}
6389
+ *
6390
+ * Rendering such document will break the Slate editor
6391
+ */
6392
+
6393
+ var hasContent = function hasContent(doc) {
6394
+ if (!doc) {
6395
+ return false;
6396
+ }
6397
+
6398
+ return doc.content.length > 0;
6399
+ };
6400
+ /*
6401
+ Plate api doesn't allow to modify (easily) the editor value programmatically
6402
+ after the editor instance is created
6403
+
6404
+ This function is inspired to https://github.com/udecode/plate/issues/1269#issuecomment-1057643622
6405
+ */
6406
+
6407
+ var setEditorContent = function setEditorContent(editor, nodes) {
6408
+ // Replaces editor content while keeping change history
6409
+ slate.Editor.withoutNormalizing(editor, function () {
6410
+ var children = [].concat(editor.children);
6411
+ children.forEach(function (node) {
6412
+ return editor.apply({
6413
+ type: 'remove_node',
6414
+ path: [0],
6415
+ node: node
6416
+ });
6417
+ });
6418
+
6419
+ if (nodes) {
6420
+ var nodesArray = slate.Node.isNode(nodes) ? [nodes] : nodes;
6421
+ nodesArray.forEach(function (node, i) {
6422
+ return editor.apply({
6423
+ type: 'insert_node',
6424
+ path: [i],
6425
+ node: node
6426
+ });
6427
+ });
6428
+ }
6429
+
6430
+ var point = slate.Editor.end(editor, []);
6431
+
6432
+ if (point) {
6433
+ slate.Transforms.select(editor, point);
6434
+ }
6435
+ });
6436
+ };
6437
+ /**
6438
+ * Converts a contenful rich text document to the corresponding slate editor
6439
+ * value
6440
+ */
6441
+
6442
+ var documentToEditorValue = function documentToEditorValue(doc) {
6443
+ return contentfulSlateJSAdapter.toSlatejsDocument({
6444
+ document: hasContent(doc) ? doc : Contentful.EMPTY_DOCUMENT,
6445
+ // TODO: get rid of schema, https://github.com/contentful/field-editors/pull/1065#discussion_r826723248
6446
+ schema: schema
6447
+ });
6448
+ };
6449
+ var normalizeEditorValue = function normalizeEditorValue(value, options) {
6450
+ var editor = plateCore.createPlateEditor(options);
6451
+ editor.children = value;
6452
+ slate.Editor.normalize(editor, {
6453
+ force: true
6454
+ });
6455
+ return editor.children;
6456
+ };
6457
+
6222
6458
  var STYLE_EDITOR_BORDER = "1px solid " + tokens.gray400;
6223
6459
  var styles$j = {
6224
6460
  root: /*#__PURE__*/emotion.css({
@@ -6315,7 +6551,17 @@ var EmbedEntityWidget = function EmbedEntityWidget(_ref) {
6315
6551
  setCanAccessAssets = _useState2[1];
6316
6552
 
6317
6553
  React__default.useEffect(function () {
6318
- sdk.access.can('read', 'Asset').then(setCanAccessAssets);
6554
+ var subscribed = true;
6555
+ sdk.access.can('read', 'Asset').then(function (can) {
6556
+ if (!subscribed) {
6557
+ return;
6558
+ }
6559
+
6560
+ setCanAccessAssets(can);
6561
+ });
6562
+ return function () {
6563
+ subscribed = false;
6564
+ };
6319
6565
  }, [sdk]);
6320
6566
  var inlineEntryEmbedEnabled = isNodeTypeEnabled(sdk.field, Contentful.INLINES.EMBEDDED_ENTRY);
6321
6567
  var blockEntryEmbedEnabled = isNodeTypeEnabled(sdk.field, Contentful.BLOCKS.EMBEDDED_ENTRY) && canInsertBlocks;
@@ -6470,50 +6716,6 @@ var StickyToolbarWrapper = function StickyToolbarWrapper(_ref) {
6470
6716
  }, children);
6471
6717
  };
6472
6718
 
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
6719
  /**
6518
6720
  * Returns whether a given operation is relevant enough to trigger a save.
6519
6721
  */
@@ -6527,8 +6729,10 @@ var isRelevantOperation = function isRelevantOperation(op) {
6527
6729
  };
6528
6730
 
6529
6731
  var useOnValueChanged = function useOnValueChanged(_ref) {
6530
- var editor = _ref.editor,
6531
- handler = _ref.handler;
6732
+ var editorId = _ref.editorId,
6733
+ handler = _ref.handler,
6734
+ skip = _ref.skip,
6735
+ onSkip = _ref.onSkip;
6532
6736
  var onChange = React.useMemo(function () {
6533
6737
  return debounce(function (document) {
6534
6738
  handler == null ? void 0 : handler(contentfulSlateJSAdapter.toContentfulDocument({
@@ -6538,45 +6742,84 @@ var useOnValueChanged = function useOnValueChanged(_ref) {
6538
6742
  }, 500);
6539
6743
  }, [handler]);
6540
6744
  return React.useCallback(function (value) {
6541
- var operations = editor.operations.filter(isRelevantOperation);
6745
+ var editor = plateCore.getPlateSelectors(editorId).editor();
6746
+
6747
+ if (!editor) {
6748
+ throw new Error('Editor change callback called but editor not defined. Editor id: ' + editorId);
6749
+ }
6750
+
6751
+ var operations = editor == null ? void 0 : editor.operations.filter(isRelevantOperation);
6542
6752
 
6543
6753
  if (operations.length > 0) {
6754
+ if (skip) {
6755
+ onSkip == null ? void 0 : onSkip();
6756
+ return;
6757
+ }
6758
+
6544
6759
  onChange(value);
6545
6760
  }
6546
- }, [editor, onChange]);
6761
+ }, [editorId, onChange, skip, onSkip]);
6547
6762
  };
6548
6763
 
6549
6764
  var _excluded = ["sdk", "isInitiallyDisabled", "onAction"];
6550
6765
  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);
6766
+ var id = getContentfulEditorId(props.sdk);
6554
6767
  var plugins = React__default.useMemo(function () {
6555
6768
  var _props$onAction;
6556
6769
 
6557
6770
  return getPlugins(props.sdk, (_props$onAction = props.onAction) != null ? _props$onAction : noop);
6558
6771
  }, [props.sdk, props.onAction]);
6559
- var initialValue = useNormalizedSlateValue({
6560
- id: id,
6561
- incomingDoc: props.value,
6562
- plugins: plugins
6563
- });
6772
+
6773
+ var _useState = React.useState(true),
6774
+ isFirstRender = _useState[0],
6775
+ setIsFirstRender = _useState[1];
6776
+
6777
+ var _useState2 = React.useState(false),
6778
+ pendingExternalUpdate = _useState2[0],
6779
+ setPendingExternalUpdate = _useState2[1];
6780
+
6564
6781
  var onValueChanged = useOnValueChanged({
6565
- editor: editor,
6566
- handler: props.onChange
6782
+ editorId: id,
6783
+ handler: props.onChange,
6784
+ skip: pendingExternalUpdate || isFirstRender,
6785
+ onSkip: function onSkip() {
6786
+ return setPendingExternalUpdate(false);
6787
+ }
6567
6788
  });
6789
+ React.useEffect(function () {
6790
+ /*
6791
+ This effect is called when the value prop changes. Normally
6792
+ this happens when the value is changed outside of the editor,
6793
+ like in snapshots restoration or remote updates
6794
+ Plate won't update the displayed value on its own, see:
6795
+ - https://github.com/ianstormtaylor/slate/pull/4540
6796
+ - https://github.com/udecode/plate/issues/1169
6797
+ The content is forcely set to the new value and it's ensured
6798
+ the change listener isn't invoked
6799
+ */
6800
+ setIsFirstRender(false);
6801
+ var editor = plateCore.getPlateSelectors(id).editor();
6802
+
6803
+ if (!editor) {
6804
+ return;
6805
+ }
6806
+
6807
+ setPendingExternalUpdate(true);
6808
+ setEditorContent(editor, documentToEditorValue(props.value));
6809
+ }, [props.value, id]);
6568
6810
  var classNames = emotion.cx(styles$j.editor, props.minHeight !== undefined ? emotion.css({
6569
6811
  minHeight: props.minHeight
6570
6812
  }) : undefined, props.isDisabled ? styles$j.disabled : styles$j.enabled, props.isToolbarHidden && styles$j.hiddenToolbar);
6571
6813
  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]);
6814
+ if (!isFirstRender) {
6815
+ return;
6816
+ }
6817
+
6818
+ plateCore.getPlateActions(id).value(normalizeEditorValue(documentToEditorValue(props.value), {
6819
+ plugins: plugins,
6820
+ disableCorePlugins: disableCorePlugins
6821
+ }));
6822
+ }, [isFirstRender, plugins, id, props.value]);
6580
6823
  return /*#__PURE__*/React__default.createElement(SdkProvider, {
6581
6824
  sdk: props.sdk
6582
6825
  }, /*#__PURE__*/React__default.createElement(ContentfulEditorIdProvider, {
@@ -6586,7 +6829,6 @@ var ConnectedRichTextEditor = function ConnectedRichTextEditor(props) {
6586
6829
  "data-test-id": "rich-text-editor"
6587
6830
  }, /*#__PURE__*/React__default.createElement(plateCore.Plate, {
6588
6831
  id: id,
6589
- initialValue: initialValue,
6590
6832
  plugins: plugins,
6591
6833
  disableCorePlugins: disableCorePlugins,
6592
6834
  editableProps: {
@@ -6610,6 +6852,7 @@ var RichTextEditor = function RichTextEditor(props) {
6610
6852
  var isEmptyValue = React.useCallback(function (value) {
6611
6853
  return !value || deepEquals(value, Contentful.EMPTY_DOCUMENT);
6612
6854
  }, []);
6855
+ var id = getContentfulEditorId(props.sdk);
6613
6856
  return /*#__PURE__*/React__default.createElement(fieldEditorReference.EntityProvider, {
6614
6857
  sdk: sdk
6615
6858
  }, /*#__PURE__*/React__default.createElement(fieldEditorShared.FieldConnector, {
@@ -6621,10 +6864,9 @@ var RichTextEditor = function RichTextEditor(props) {
6621
6864
  }, function (_ref) {
6622
6865
  var lastRemoteValue = _ref.lastRemoteValue,
6623
6866
  disabled = _ref.disabled,
6624
- setValue = _ref.setValue,
6625
- externalReset = _ref.externalReset;
6867
+ setValue = _ref.setValue;
6626
6868
  return /*#__PURE__*/React__default.createElement(ConnectedRichTextEditor, Object.assign({}, otherProps, {
6627
- key: "rich-text-editor-" + externalReset,
6869
+ key: "rich-text-editor-" + id,
6628
6870
  value: lastRemoteValue,
6629
6871
  sdk: sdk,
6630
6872
  onAction: onAction,