@contentful/field-editor-rich-text 3.12.7 → 3.14.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 (70) hide show
  1. package/dist/cjs/Toolbar/components/EmbedEntityWidget.js +6 -0
  2. package/dist/cjs/Toolbar/index.js +2 -1
  3. package/dist/cjs/constants/Schema.js +14 -0
  4. package/dist/cjs/helpers/{newEntitySelectorConfigFromRichTextField.js → config.js} +19 -5
  5. package/dist/cjs/helpers/editor.js +1 -0
  6. package/dist/cjs/plugins/DragAndDrop/index.js +4 -2
  7. package/dist/cjs/plugins/EmbeddedEntityInline/index.js +21 -4
  8. package/dist/cjs/plugins/EmbeddedResourceInline/FetchingWrappedResourceInlineCard.js +102 -0
  9. package/dist/cjs/plugins/EmbeddedResourceInline/LinkedResourceInline.js +51 -0
  10. package/dist/cjs/plugins/EmbeddedResourceInline/index.js +56 -0
  11. package/dist/cjs/plugins/Heading/__tests__/createHeadingPlugin.test.js +2 -0
  12. package/dist/cjs/plugins/Hyperlink/HyperlinkModal.js +63 -8
  13. package/dist/cjs/plugins/Hyperlink/__tests__/createHyperlinkPlugin.test.js +3 -1
  14. package/dist/cjs/plugins/Hyperlink/components/ResourceHyperlink.js +93 -0
  15. package/dist/cjs/plugins/Hyperlink/createHyperlinkPlugin.js +29 -1
  16. package/dist/cjs/plugins/Hyperlink/useResourceEntityInfo.js +71 -0
  17. package/dist/cjs/plugins/Hyperlink/utils.js +5 -2
  18. package/dist/cjs/plugins/Paragraph/__tests__/createParagraphPlugin.test.js +2 -0
  19. package/dist/cjs/plugins/Quote/__test__/createQuotePlugin.test.js +2 -0
  20. package/dist/cjs/plugins/index.js +2 -0
  21. package/dist/cjs/plugins/shared/EmbeddedBlockToolbarIcon.js +2 -4
  22. package/dist/cjs/plugins/shared/EmbeddedBlockUtil.js +3 -4
  23. package/dist/cjs/plugins/shared/EmbeddedInlineToolbarIcon.js +11 -6
  24. package/dist/cjs/plugins/shared/EmbeddedInlineUtil.js +66 -27
  25. package/dist/cjs/plugins/shared/ResourceNewBadge.js +57 -0
  26. package/dist/cjs/test-utils/jsx.js +11 -0
  27. package/dist/esm/Toolbar/components/EmbedEntityWidget.js +6 -0
  28. package/dist/esm/Toolbar/index.js +2 -1
  29. package/dist/esm/constants/Schema.js +14 -0
  30. package/dist/esm/helpers/{newEntitySelectorConfigFromRichTextField.js → config.js} +8 -2
  31. package/dist/esm/helpers/editor.js +1 -0
  32. package/dist/esm/plugins/DragAndDrop/index.js +4 -2
  33. package/dist/esm/plugins/EmbeddedEntityInline/index.js +22 -5
  34. package/dist/esm/plugins/EmbeddedResourceInline/FetchingWrappedResourceInlineCard.js +53 -0
  35. package/dist/esm/plugins/EmbeddedResourceInline/LinkedResourceInline.js +36 -0
  36. package/dist/esm/plugins/EmbeddedResourceInline/index.js +46 -0
  37. package/dist/esm/plugins/Heading/__tests__/createHeadingPlugin.test.js +2 -0
  38. package/dist/esm/plugins/Hyperlink/HyperlinkModal.js +63 -8
  39. package/dist/esm/plugins/Hyperlink/__tests__/createHyperlinkPlugin.test.js +3 -1
  40. package/dist/esm/plugins/Hyperlink/components/ResourceHyperlink.js +44 -0
  41. package/dist/esm/plugins/Hyperlink/createHyperlinkPlugin.js +29 -1
  42. package/dist/esm/plugins/Hyperlink/useResourceEntityInfo.js +22 -0
  43. package/dist/esm/plugins/Hyperlink/utils.js +2 -2
  44. package/dist/esm/plugins/Paragraph/__tests__/createParagraphPlugin.test.js +2 -0
  45. package/dist/esm/plugins/Quote/__test__/createQuotePlugin.test.js +2 -0
  46. package/dist/esm/plugins/index.js +2 -0
  47. package/dist/esm/plugins/shared/EmbeddedBlockToolbarIcon.js +3 -5
  48. package/dist/esm/plugins/shared/EmbeddedBlockUtil.js +1 -2
  49. package/dist/esm/plugins/shared/EmbeddedInlineToolbarIcon.js +12 -7
  50. package/dist/esm/plugins/shared/EmbeddedInlineUtil.js +64 -25
  51. package/dist/esm/plugins/shared/ResourceNewBadge.js +8 -0
  52. package/dist/esm/test-utils/jsx.js +11 -0
  53. package/dist/types/constants/Schema.d.ts +10 -0
  54. package/dist/types/helpers/config.d.ts +33 -0
  55. package/dist/types/helpers/editor.d.ts +1 -1
  56. package/dist/types/plugins/EmbeddedResourceInline/FetchingWrappedResourceInlineCard.d.ts +13 -0
  57. package/dist/types/plugins/EmbeddedResourceInline/LinkedResourceInline.d.ts +13 -0
  58. package/dist/types/plugins/EmbeddedResourceInline/index.d.ts +3 -0
  59. package/dist/types/plugins/Hyperlink/HyperlinkModal.d.ts +2 -1
  60. package/dist/types/plugins/Hyperlink/components/ResourceHyperlink.d.ts +20 -0
  61. package/dist/types/plugins/Hyperlink/useResourceEntityInfo.d.ts +7 -0
  62. package/dist/types/plugins/Hyperlink/utils.d.ts +1 -0
  63. package/dist/types/plugins/shared/EmbeddedInlineToolbarIcon.d.ts +2 -1
  64. package/dist/types/plugins/shared/EmbeddedInlineUtil.d.ts +3 -17
  65. package/dist/types/plugins/shared/ResourceNewBadge.d.ts +2 -0
  66. package/package.json +2 -2
  67. package/dist/cjs/helpers/newResourceEntitySelectorConfigFromRichTextField.js +0 -21
  68. package/dist/esm/helpers/newResourceEntitySelectorConfigFromRichTextField.js +0 -6
  69. package/dist/types/helpers/newEntitySelectorConfigFromRichTextField.d.ts +0 -14
  70. package/dist/types/helpers/newResourceEntitySelectorConfigFromRichTextField.d.ts +0 -16
@@ -14,6 +14,7 @@ const _ishotkey = _interop_require_default(require("is-hotkey"));
14
14
  const _editor = require("../../helpers/editor");
15
15
  const _transformers = require("../../helpers/transformers");
16
16
  const _EntityHyperlink = require("./components/EntityHyperlink");
17
+ const _ResourceHyperlink = require("./components/ResourceHyperlink");
17
18
  const _UrlHyperlink = require("./components/UrlHyperlink");
18
19
  const _HyperlinkModal = require("./HyperlinkModal");
19
20
  const _utils = require("./utils");
@@ -64,6 +65,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
64
65
  const isAnchor = (element)=>element.nodeName === 'A' && !!element.getAttribute('href') && element.getAttribute('href') !== '#';
65
66
  const isEntryAnchor = (element)=>element.nodeName === 'A' && element.getAttribute('data-link-type') === 'Entry';
66
67
  const isAssetAnchor = (element)=>element.nodeName === 'A' && element.getAttribute('data-link-type') === 'Asset';
68
+ const isResourceAnchor = (element)=>element.nodeName === 'A' && element.getAttribute('data-resource-link-type') === 'Contentful:Entry';
67
69
  const buildHyperlinkEventHandler = (sdk)=>(editor, { options: { hotkey } })=>{
68
70
  return (event)=>{
69
71
  if (!editor.selection) {
@@ -85,6 +87,14 @@ const getNodeOfType = (type)=>(el, node)=>({
85
87
  children: node.children,
86
88
  data: type === _richtexttypes.INLINES.HYPERLINK ? {
87
89
  uri: el.getAttribute('href')
90
+ } : type === _richtexttypes.INLINES.RESOURCE_HYPERLINK ? {
91
+ target: {
92
+ sys: {
93
+ urn: el.getAttribute('data-resource-link-urn'),
94
+ linkType: el.getAttribute('data-resource-link-type'),
95
+ type: 'ResourceLink'
96
+ }
97
+ }
88
98
  } : {
89
99
  target: {
90
100
  sys: {
@@ -143,6 +153,23 @@ const createHyperlinkPlugin = (sdk)=>{
143
153
  getNode: getNodeOfType(_richtexttypes.INLINES.ENTRY_HYPERLINK)
144
154
  }
145
155
  },
156
+ {
157
+ ...common,
158
+ key: _richtexttypes.INLINES.RESOURCE_HYPERLINK,
159
+ type: _richtexttypes.INLINES.RESOURCE_HYPERLINK,
160
+ component: _ResourceHyperlink.ResourceHyperlink,
161
+ deserializeHtml: {
162
+ rules: [
163
+ {
164
+ validNodeName: [
165
+ 'A'
166
+ ]
167
+ }
168
+ ],
169
+ query: (el)=>isResourceAnchor(el),
170
+ getNode: getNodeOfType(_richtexttypes.INLINES.RESOURCE_HYPERLINK)
171
+ }
172
+ },
146
173
  {
147
174
  ...common,
148
175
  key: _richtexttypes.INLINES.ASSET_HYPERLINK,
@@ -167,7 +194,8 @@ const createHyperlinkPlugin = (sdk)=>{
167
194
  type: [
168
195
  _richtexttypes.INLINES.HYPERLINK,
169
196
  _richtexttypes.INLINES.ASSET_HYPERLINK,
170
- _richtexttypes.INLINES.ENTRY_HYPERLINK
197
+ _richtexttypes.INLINES.ENTRY_HYPERLINK,
198
+ _richtexttypes.INLINES.RESOURCE_HYPERLINK
171
199
  ]
172
200
  },
173
201
  validNode: _utils.hasText,
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "useResourceEntityInfo", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return useResourceEntityInfo;
9
+ }
10
+ });
11
+ const _react = _interop_require_wildcard(require("react"));
12
+ const _fieldeditorreference = require("@contentful/field-editor-reference");
13
+ const _utils = require("./utils");
14
+ function _getRequireWildcardCache(nodeInterop) {
15
+ if (typeof WeakMap !== "function") return null;
16
+ var cacheBabelInterop = new WeakMap();
17
+ var cacheNodeInterop = new WeakMap();
18
+ return (_getRequireWildcardCache = function(nodeInterop) {
19
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
20
+ })(nodeInterop);
21
+ }
22
+ function _interop_require_wildcard(obj, nodeInterop) {
23
+ if (!nodeInterop && obj && obj.__esModule) {
24
+ return obj;
25
+ }
26
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
27
+ return {
28
+ default: obj
29
+ };
30
+ }
31
+ var cache = _getRequireWildcardCache(nodeInterop);
32
+ if (cache && cache.has(obj)) {
33
+ return cache.get(obj);
34
+ }
35
+ var newObj = {};
36
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
37
+ for(var key in obj){
38
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
39
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
40
+ if (desc && (desc.get || desc.set)) {
41
+ Object.defineProperty(newObj, key, desc);
42
+ } else {
43
+ newObj[key] = obj[key];
44
+ }
45
+ }
46
+ }
47
+ newObj.default = obj;
48
+ if (cache) {
49
+ cache.set(obj, newObj);
50
+ }
51
+ return newObj;
52
+ }
53
+ function useResourceEntityInfo({ onEntityFetchComplete , target }) {
54
+ const { data , error , status } = (0, _fieldeditorreference.useResource)(target.sys.linkType, target.sys.urn);
55
+ _react.useEffect(()=>{
56
+ if (status === 'success') {
57
+ onEntityFetchComplete?.();
58
+ }
59
+ }, [
60
+ status,
61
+ onEntityFetchComplete
62
+ ]);
63
+ if (status === 'loading') {
64
+ return `Loading entry...`;
65
+ }
66
+ if (!data || error) {
67
+ return `Entry missing or inaccessible`;
68
+ }
69
+ const title = (0, _utils.truncateTitle)(data.resource.fields[data.contentType.displayField]?.[data.defaultLocaleCode], 40) || 'Untitled';
70
+ return `${data.contentType.name}: ${title} (Space: ${data.space.name} – Env.: ${data.resource.sys.environment.sys.id})`;
71
+ }
@@ -12,6 +12,9 @@ _export(exports, {
12
12
  hasText: function() {
13
13
  return hasText;
14
14
  },
15
+ truncateTitle: function() {
16
+ return truncateTitle;
17
+ },
15
18
  getEntityInfo: function() {
16
19
  return getEntityInfo;
17
20
  }
@@ -23,7 +26,7 @@ const hasText = (editor, entry)=>{
23
26
  const [node, path] = entry;
24
27
  return !(0, _platecommon.isAncestorEmpty)(editor, node) && (0, _queries.getText)(editor, path).trim() !== '';
25
28
  };
26
- function truncate(str, length) {
29
+ function truncateTitle(str, length) {
27
30
  if (typeof str === 'string' && str.length > length) {
28
31
  return str && str.substr(0, length + 1).replace(/(\s+\S(?=\S)|\s*)\.?.$/, '…');
29
32
  }
@@ -34,7 +37,7 @@ function getEntityInfo(data) {
34
37
  return '';
35
38
  }
36
39
  const { entityTitle , contentTypeName , entityStatus , jobs } = data;
37
- const title = truncate(entityTitle, 60) || 'Untitled';
40
+ const title = truncateTitle(entityTitle, 60) || 'Untitled';
38
41
  const scheduledActions = jobs.length > 0 ? (0, _fieldeditorreference.getScheduleTooltipContent)({
39
42
  job: jobs[0],
40
43
  jobsCount: jobs.length
@@ -12,6 +12,8 @@ describe('normalization', ()=>{
12
12
  uri: "https://contentful.com"
13
13
  }), (0, _testutils.jsx)("hlink", {
14
14
  entry: "entry-id"
15
+ }), (0, _testutils.jsx)("hlink", {
16
+ resource: "resource-urn"
15
17
  }), (0, _testutils.jsx)("hlink", {
16
18
  asset: "asset-id"
17
19
  }), "some text after"));
@@ -12,6 +12,8 @@ describe('normalization', ()=>{
12
12
  uri: "https://contentful.com"
13
13
  }), (0, _testutils.jsx)("hlink", {
14
14
  entry: "entry-id"
15
+ }), (0, _testutils.jsx)("hlink", {
16
+ resource: "resource-urn"
15
17
  }), (0, _testutils.jsx)("hlink", {
16
18
  asset: "asset-id"
17
19
  }), "some text after")));
@@ -24,6 +24,7 @@ const _DragAndDrop = require("./DragAndDrop");
24
24
  const _EmbeddedEntityBlock = require("./EmbeddedEntityBlock");
25
25
  const _EmbeddedEntityInline = require("./EmbeddedEntityInline");
26
26
  const _EmbeddedResourceBlock = require("./EmbeddedResourceBlock");
27
+ const _EmbeddedResourceInline = require("./EmbeddedResourceInline");
27
28
  const _Heading = require("./Heading");
28
29
  const _Hr = require("./Hr");
29
30
  const _Hyperlink = require("./Hyperlink");
@@ -57,6 +58,7 @@ const getPlugins = (sdk, onAction, restrictedMarks)=>[
57
58
  (0, _EmbeddedResourceBlock.createEmbeddedResourceBlockPlugin)(sdk),
58
59
  (0, _Hyperlink.createHyperlinkPlugin)(sdk),
59
60
  (0, _EmbeddedEntityInline.createEmbeddedEntityInlinePlugin)(sdk),
61
+ (0, _EmbeddedResourceInline.createEmbeddedResourceInlinePlugin)(sdk),
60
62
  (0, _Marks.createMarksPlugin)(),
61
63
  (0, _TrailingParagraph.createTrailingParagraphPlugin)(),
62
64
  (0, _Text.createTextPlugin)(restrictedMarks),
@@ -24,6 +24,7 @@ const _emotion = require("emotion");
24
24
  const _ContentfulEditorProvider = require("../../ContentfulEditorProvider");
25
25
  const _SdkProvider = require("../../SdkProvider");
26
26
  const _EmbeddedBlockUtil = require("../shared/EmbeddedBlockUtil");
27
+ const _ResourceNewBadge = require("./ResourceNewBadge");
27
28
  function _getRequireWildcardCache(nodeInterop) {
28
29
  if (typeof WeakMap !== "function") return null;
29
30
  var cacheBabelInterop = new WeakMap();
@@ -97,10 +98,7 @@ function EmbeddedBlockToolbarIcon({ isDisabled , nodeType , onClose }) {
97
98
  as: type === 'Asset' ? _f36icons.AssetIcon : _f36icons.EmbeddedEntryBlockIcon,
98
99
  className: `rich-text__embedded-entry-list-icon ${styles.icon}`,
99
100
  variant: "secondary"
100
- }), _react.createElement("span", null, type, nodeType == _richtexttypes.BLOCKS.EMBEDDED_RESOURCE && _react.createElement(_react.Fragment, null, ' ', "(different space)", ' ', _react.createElement(_f36components.Badge, {
101
- variant: "primary-filled",
102
- size: "small"
103
- }, "new")))));
101
+ }), _react.createElement("span", null, type, nodeType == _richtexttypes.BLOCKS.EMBEDDED_RESOURCE && _react.createElement(_ResourceNewBadge.ResourceNewBadge, null))));
104
102
  }
105
103
  function getEntityTypeFromNodeType(nodeType) {
106
104
  const words = nodeType.toLowerCase().split('-');
@@ -21,9 +21,8 @@ _export(exports, {
21
21
  });
22
22
  const _richtexttypes = require("@contentful/rich-text-types");
23
23
  const _ishotkey = _interop_require_default(require("is-hotkey"));
24
+ const _config = require("../../helpers/config");
24
25
  const _editor = require("../../helpers/editor");
25
- const _newEntitySelectorConfigFromRichTextField = _interop_require_default(require("../../helpers/newEntitySelectorConfigFromRichTextField"));
26
- const _newResourceEntitySelectorConfigFromRichTextField = _interop_require_default(require("../../helpers/newResourceEntitySelectorConfigFromRichTextField"));
27
26
  const _sdkNavigatorSlideIn = require("../../helpers/sdkNavigatorSlideIn");
28
27
  const _internal = require("../../internal");
29
28
  function _interop_require_default(obj) {
@@ -59,7 +58,7 @@ async function selectEntityAndInsert(nodeType, sdk, editor, logAction) {
59
58
  nodeType
60
59
  });
61
60
  const { field , dialogs } = sdk;
62
- const baseConfig = (0, _newEntitySelectorConfigFromRichTextField.default)(field, nodeType);
61
+ const baseConfig = (0, _config.newEntitySelectorConfigFromRichTextField)(field, nodeType);
63
62
  const selectEntity = baseConfig.entityType === 'Asset' ? dialogs.selectSingleAsset : dialogs.selectSingleEntry;
64
63
  const config = {
65
64
  ...baseConfig,
@@ -93,7 +92,7 @@ async function selectResourceEntityAndInsert(sdk, editor, logAction) {
93
92
  nodeType: _richtexttypes.BLOCKS.EMBEDDED_RESOURCE
94
93
  });
95
94
  const { field , dialogs } = sdk;
96
- const config = (0, _newResourceEntitySelectorConfigFromRichTextField.default)(field, _richtexttypes.BLOCKS.EMBEDDED_RESOURCE);
95
+ const config = (0, _config.newResourceEntitySelectorConfigFromRichTextField)(field, _richtexttypes.BLOCKS.EMBEDDED_RESOURCE);
97
96
  const { selection } = editor;
98
97
  const entity = await dialogs.selectSingleResourceEntry(config);
99
98
  if (!entity) {
@@ -18,6 +18,7 @@ const _ContentfulEditorProvider = require("../../ContentfulEditorProvider");
18
18
  const _editor = require("../../helpers/editor");
19
19
  const _SdkProvider = require("../../SdkProvider");
20
20
  const _EmbeddedInlineUtil = require("../shared/EmbeddedInlineUtil");
21
+ const _ResourceNewBadge = require("./ResourceNewBadge");
21
22
  function _interop_require_default(obj) {
22
23
  return obj && obj.__esModule ? obj : {
23
24
  default: obj
@@ -75,20 +76,24 @@ const styles = {
75
76
  }
76
77
  })
77
78
  };
78
- function EmbeddedInlineToolbarIcon(props) {
79
+ function EmbeddedInlineToolbarIcon({ onClose , nodeType , isDisabled }) {
79
80
  const editor = (0, _ContentfulEditorProvider.useContentfulEditor)();
80
81
  const sdk = (0, _SdkProvider.useSdkContext)();
81
82
  async function handleClick(event) {
82
83
  event.preventDefault();
83
84
  if (!editor) return;
84
- props.onClose();
85
- await (0, _EmbeddedInlineUtil.selectEntityAndInsert)(editor, sdk, editor.tracking.onToolbarAction);
85
+ onClose();
86
+ if (nodeType === _richtexttypes.INLINES.EMBEDDED_RESOURCE) {
87
+ await (0, _EmbeddedInlineUtil.selectResourceEntityAndInsert)(editor, sdk, editor.tracking.onToolbarAction);
88
+ } else {
89
+ await (0, _EmbeddedInlineUtil.selectEntityAndInsert)(editor, sdk, editor.tracking.onToolbarAction);
90
+ }
86
91
  (0, _editor.moveToTheNextChar)(editor);
87
92
  }
88
93
  return _react.createElement(_f36components.Menu.Item, {
89
- disabled: props.isDisabled,
94
+ disabled: isDisabled,
90
95
  className: "rich-text__entry-link-block-button",
91
- testId: `toolbar-toggle-${_richtexttypes.INLINES.EMBEDDED_ENTRY}`,
96
+ testId: `toolbar-toggle-${nodeType}`,
92
97
  onClick: handleClick
93
98
  }, _react.createElement(_f36components.Flex, {
94
99
  alignItems: "center",
@@ -96,5 +101,5 @@ function EmbeddedInlineToolbarIcon(props) {
96
101
  }, _react.createElement(_f36icons.EmbeddedEntryInlineIcon, {
97
102
  variant: "secondary",
98
103
  className: `rich-text__embedded-entry-list-icon ${styles.icon}`
99
- }), _react.createElement("span", null, "Inline entry")));
104
+ }), _react.createElement("span", null, "Inline entry", nodeType == _richtexttypes.INLINES.EMBEDDED_RESOURCE && _react.createElement(_ResourceNewBadge.ResourceNewBadge, null))));
100
105
  }
@@ -15,14 +15,14 @@ _export(exports, {
15
15
  selectEntityAndInsert: function() {
16
16
  return selectEntityAndInsert;
17
17
  },
18
- createInlineEntryNode: function() {
19
- return createInlineEntryNode;
18
+ selectResourceEntityAndInsert: function() {
19
+ return selectResourceEntityAndInsert;
20
20
  }
21
21
  });
22
22
  const _richtexttypes = require("@contentful/rich-text-types");
23
23
  const _ishotkey = _interop_require_default(require("is-hotkey"));
24
+ const _config = require("../../helpers/config");
24
25
  const _editor = require("../../helpers/editor");
25
- const _newEntitySelectorConfigFromRichTextField = _interop_require_default(require("../../helpers/newEntitySelectorConfigFromRichTextField"));
26
26
  const _sdkNavigatorSlideIn = require("../../helpers/sdkNavigatorSlideIn");
27
27
  const _transforms = require("../../internal/transforms");
28
28
  function _interop_require_default(obj) {
@@ -30,22 +30,56 @@ function _interop_require_default(obj) {
30
30
  default: obj
31
31
  };
32
32
  }
33
- function getWithEmbeddedEntryInlineEvents(sdk) {
33
+ function getWithEmbeddedEntryInlineEvents(nodeType, sdk) {
34
34
  return function withEmbeddedEntryInlineEvents(editor, { options: { hotkey } }) {
35
35
  return function handleEvent(event) {
36
36
  if (!editor) return;
37
37
  if (hotkey && (0, _ishotkey.default)(hotkey, event)) {
38
- selectEntityAndInsert(editor, sdk, editor.tracking.onShortcutAction);
38
+ if (nodeType === _richtexttypes.INLINES.EMBEDDED_RESOURCE) {
39
+ selectResourceEntityAndInsert(editor, sdk, editor.tracking.onShortcutAction);
40
+ } else {
41
+ selectEntityAndInsert(editor, sdk, editor.tracking.onShortcutAction);
42
+ }
39
43
  }
40
44
  };
41
45
  };
42
46
  }
47
+ const getLink = (nodeType, entity)=>{
48
+ if (nodeType === _richtexttypes.INLINES.EMBEDDED_RESOURCE) {
49
+ return {
50
+ urn: entity.sys.urn,
51
+ type: 'ResourceLink',
52
+ linkType: 'Contentful:Entry'
53
+ };
54
+ }
55
+ return {
56
+ id: entity.sys.id,
57
+ type: 'Link',
58
+ linkType: entity.sys.type
59
+ };
60
+ };
61
+ const createInlineEntryNode = (nodeType, entity)=>{
62
+ return {
63
+ type: nodeType,
64
+ children: [
65
+ {
66
+ text: ''
67
+ }
68
+ ],
69
+ data: {
70
+ target: {
71
+ sys: getLink(nodeType, entity)
72
+ }
73
+ }
74
+ };
75
+ };
43
76
  async function selectEntityAndInsert(editor, sdk, logAction) {
77
+ const nodeType = _richtexttypes.INLINES.EMBEDDED_ENTRY;
44
78
  logAction('openCreateEmbedDialog', {
45
- nodeType: _richtexttypes.INLINES.EMBEDDED_ENTRY
79
+ nodeType
46
80
  });
47
81
  const config = {
48
- ...(0, _newEntitySelectorConfigFromRichTextField.default)(sdk.field, _richtexttypes.INLINES.EMBEDDED_ENTRY),
82
+ ...(0, _config.newEntitySelectorConfigFromRichTextField)(sdk.field, nodeType),
49
83
  withCreate: true
50
84
  };
51
85
  const { selection } = editor;
@@ -53,13 +87,13 @@ async function selectEntityAndInsert(editor, sdk, logAction) {
53
87
  const entry = await sdk.dialogs.selectSingleEntry(config);
54
88
  if (!entry) {
55
89
  logAction('cancelCreateEmbedDialog', {
56
- nodeType: _richtexttypes.INLINES.EMBEDDED_ENTRY
90
+ nodeType
57
91
  });
58
92
  } else {
59
93
  (0, _transforms.select)(editor, selection);
60
- (0, _transforms.insertNodes)(editor, createInlineEntryNode(entry.sys.id));
94
+ (0, _transforms.insertNodes)(editor, createInlineEntryNode(nodeType, entry));
61
95
  logAction('insert', {
62
- nodeType: _richtexttypes.INLINES.EMBEDDED_ENTRY
96
+ nodeType
63
97
  });
64
98
  }
65
99
  rteSlide.onActive(()=>{
@@ -67,22 +101,27 @@ async function selectEntityAndInsert(editor, sdk, logAction) {
67
101
  (0, _editor.focus)(editor);
68
102
  });
69
103
  }
70
- function createInlineEntryNode(id) {
71
- return {
72
- type: _richtexttypes.INLINES.EMBEDDED_ENTRY,
73
- children: [
74
- {
75
- text: ''
76
- }
77
- ],
78
- data: {
79
- target: {
80
- sys: {
81
- id,
82
- type: 'Link',
83
- linkType: 'Entry'
84
- }
85
- }
86
- }
104
+ async function selectResourceEntityAndInsert(editor, sdk, logAction) {
105
+ const nodeType = _richtexttypes.INLINES.EMBEDDED_RESOURCE;
106
+ logAction('openCreateEmbedDialog', {
107
+ nodeType
108
+ });
109
+ const { dialogs , field } = sdk;
110
+ const config = {
111
+ ...(0, _config.newResourceEntitySelectorConfigFromRichTextField)(field, nodeType),
112
+ withCreate: true
87
113
  };
114
+ const { selection } = editor;
115
+ const entry = await dialogs.selectSingleResourceEntry(config);
116
+ if (!entry) {
117
+ logAction('cancelCreateEmbedDialog', {
118
+ nodeType
119
+ });
120
+ } else {
121
+ (0, _transforms.select)(editor, selection);
122
+ (0, _transforms.insertNodes)(editor, createInlineEntryNode(nodeType, entry));
123
+ logAction('insert', {
124
+ nodeType
125
+ });
126
+ }
88
127
  }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "ResourceNewBadge", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ResourceNewBadge;
9
+ }
10
+ });
11
+ const _react = _interop_require_wildcard(require("react"));
12
+ const _f36components = require("@contentful/f36-components");
13
+ function _getRequireWildcardCache(nodeInterop) {
14
+ if (typeof WeakMap !== "function") return null;
15
+ var cacheBabelInterop = new WeakMap();
16
+ var cacheNodeInterop = new WeakMap();
17
+ return (_getRequireWildcardCache = function(nodeInterop) {
18
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
19
+ })(nodeInterop);
20
+ }
21
+ function _interop_require_wildcard(obj, nodeInterop) {
22
+ if (!nodeInterop && obj && obj.__esModule) {
23
+ return obj;
24
+ }
25
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
26
+ return {
27
+ default: obj
28
+ };
29
+ }
30
+ var cache = _getRequireWildcardCache(nodeInterop);
31
+ if (cache && cache.has(obj)) {
32
+ return cache.get(obj);
33
+ }
34
+ var newObj = {};
35
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
36
+ for(var key in obj){
37
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
38
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
39
+ if (desc && (desc.get || desc.set)) {
40
+ Object.defineProperty(newObj, key, desc);
41
+ } else {
42
+ newObj[key] = obj[key];
43
+ }
44
+ }
45
+ }
46
+ newObj.default = obj;
47
+ if (cache) {
48
+ cache.set(obj, newObj);
49
+ }
50
+ return newObj;
51
+ }
52
+ const ResourceNewBadge = ()=>{
53
+ return _react.createElement(_react.Fragment, null, ' ', "(different space)", ' ', _react.createElement(_f36components.Badge, {
54
+ variant: "primary-filled",
55
+ size: "small"
56
+ }, "new"));
57
+ };
@@ -29,6 +29,13 @@ const createSysLink = (linkType, id)=>({
29
29
  linkType
30
30
  }
31
31
  });
32
+ const createSysResourceLink = (urn)=>({
33
+ sys: {
34
+ urn,
35
+ type: 'ResourceLink',
36
+ linkType: 'Contentful:Entry'
37
+ }
38
+ });
32
39
  const createHyperlink = (_, attrs, children)=>{
33
40
  const data = {};
34
41
  let type = _richtexttypes.INLINES.HYPERLINK;
@@ -44,6 +51,10 @@ const createHyperlink = (_, attrs, children)=>{
44
51
  type = _richtexttypes.INLINES.ENTRY_HYPERLINK;
45
52
  data.target = createSysLink('Entry', attrs.entry);
46
53
  }
54
+ if (attrs.resource) {
55
+ type = _richtexttypes.INLINES.RESOURCE_HYPERLINK;
56
+ data.target = createSysResourceLink(attrs.resource);
57
+ }
47
58
  children = children.map((child)=>typeof child === 'string' ? {
48
59
  text: child
49
60
  } : child);
@@ -14,6 +14,7 @@ export const EmbedEntityWidget = ({ isDisabled , canInsertBlocks })=>{
14
14
  const onCloseEntityDropdown = ()=>setEmbedDropdownOpen(false);
15
15
  const onToggleEntityDropdown = ()=>setEmbedDropdownOpen(!isEmbedDropdownOpen);
16
16
  const inlineEntryEmbedEnabled = isNodeTypeEnabled(sdk.field, INLINES.EMBEDDED_ENTRY);
17
+ const inlineResourceEmbedEnabled = isNodeTypeEnabled(sdk.field, INLINES.EMBEDDED_RESOURCE);
17
18
  const blockEntryEmbedEnabled = isNodeTypeEnabled(sdk.field, BLOCKS.EMBEDDED_ENTRY) && canInsertBlocks;
18
19
  const blockResourceEmbedEnabled = isNodeTypeEnabled(sdk.field, BLOCKS.EMBEDDED_RESOURCE) && canInsertBlocks;
19
20
  const blockAssetEmbedEnabled = isNodeTypeEnabled(sdk.field, BLOCKS.EMBEDDED_ASSET) && canInsertBlocks;
@@ -26,6 +27,11 @@ export const EmbedEntityWidget = ({ isDisabled , canInsertBlocks })=>{
26
27
  nodeType: BLOCKS.EMBEDDED_RESOURCE,
27
28
  onClose: onCloseEntityDropdown
28
29
  }), inlineEntryEmbedEnabled && React.createElement(EmbeddedInlineToolbarIcon, {
30
+ nodeType: INLINES.EMBEDDED_ENTRY,
31
+ isDisabled: !!isDisabled || isLinkActive(editor),
32
+ onClose: onCloseEntityDropdown
33
+ }), inlineResourceEmbedEnabled && React.createElement(EmbeddedInlineToolbarIcon, {
34
+ nodeType: INLINES.EMBEDDED_RESOURCE,
29
35
  isDisabled: !!isDisabled || isLinkActive(editor),
30
36
  onClose: onCloseEntityDropdown
31
37
  }), blockAssetEmbedEnabled && React.createElement(EmbeddedBlockToolbarIcon, {
@@ -151,7 +151,8 @@ function getValidationInfo(field) {
151
151
  const isAnyHyperlinkEnabled = someWithValidation([
152
152
  INLINES.HYPERLINK,
153
153
  INLINES.ASSET_HYPERLINK,
154
- INLINES.ENTRY_HYPERLINK
154
+ INLINES.ENTRY_HYPERLINK,
155
+ INLINES.RESOURCE_HYPERLINK
155
156
  ], isNodeTypeEnabled);
156
157
  const isAnyBlockFormattingEnabled = someWithValidation([
157
158
  BLOCKS.UL_LIST,
@@ -144,6 +144,17 @@ export default {
144
144
  }
145
145
  ]
146
146
  },
147
+ [INLINES.RESOURCE_HYPERLINK]: {
148
+ nodes: [
149
+ {
150
+ match: [
151
+ {
152
+ object: 'text'
153
+ }
154
+ ]
155
+ }
156
+ ]
157
+ },
147
158
  [INLINES.ASSET_HYPERLINK]: {
148
159
  nodes: [
149
160
  {
@@ -157,6 +168,9 @@ export default {
157
168
  },
158
169
  [INLINES.EMBEDDED_ENTRY]: {
159
170
  isVoid: true
171
+ },
172
+ [INLINES.EMBEDDED_RESOURCE]: {
173
+ isVoid: true
160
174
  }
161
175
  }
162
176
  };
@@ -1,11 +1,12 @@
1
+ import getAllowedResourcesForNodeType from './getAllowedResourcesForNodeType';
1
2
  import getLinkedContentTypeIdsForNodeType from './getLinkedContentTypeIdsForNodeType';
2
- export default function newEntitySelectorConfigFromRichTextField(field, nodeType) {
3
+ export const newEntitySelectorConfigFromRichTextField = (field, nodeType)=>{
3
4
  return {
4
5
  entityType: getEntityTypeFromRichTextNode(nodeType),
5
6
  locale: field.locale || null,
6
7
  contentTypes: getLinkedContentTypeIdsForNodeType(field, nodeType)
7
8
  };
8
- }
9
+ };
9
10
  function getEntityTypeFromRichTextNode(nodeType) {
10
11
  const words = nodeType.split('-');
11
12
  if (words.indexOf('entry') !== -1) {
@@ -16,3 +17,8 @@ function getEntityTypeFromRichTextNode(nodeType) {
16
17
  }
17
18
  throw new Error(`RichText node type \`${nodeType}\` has no associated \`entityType\``);
18
19
  }
20
+ export const newResourceEntitySelectorConfigFromRichTextField = (field, nodeType)=>{
21
+ return {
22
+ allowedResources: getAllowedResourcesForNodeType(field, nodeType)
23
+ };
24
+ };
@@ -6,6 +6,7 @@ import { IS_SAFARI } from './environment';
6
6
  export const LINK_TYPES = [
7
7
  INLINES.HYPERLINK,
8
8
  INLINES.ENTRY_HYPERLINK,
9
+ INLINES.RESOURCE_HYPERLINK,
9
10
  INLINES.ASSET_HYPERLINK
10
11
  ];
11
12
  const LIST_TYPES = [
@@ -6,11 +6,13 @@ export function createDragAndDropPlugin() {
6
6
  BLOCKS.EMBEDDED_ASSET,
7
7
  BLOCKS.EMBEDDED_RESOURCE,
8
8
  BLOCKS.HR,
9
- INLINES.EMBEDDED_ENTRY
9
+ INLINES.EMBEDDED_ENTRY,
10
+ INLINES.EMBEDDED_RESOURCE
10
11
  ];
11
12
  const ON_DROP_ALLOWED_TYPES = {
12
13
  TABLE: [
13
- INLINES.EMBEDDED_ENTRY
14
+ INLINES.EMBEDDED_ENTRY,
15
+ INLINES.EMBEDDED_RESOURCE
14
16
  ]
15
17
  };
16
18
  return {