@squiz/formatted-text-editor 2.6.5 → 2.6.6

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 (36) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/lib/EditorToolbar/Tools/Link/Form/LinkForm.d.ts +3 -2
  3. package/lib/EditorToolbar/Tools/Link/Form/LinkForm.js +18 -4
  4. package/lib/EditorToolbar/Tools/Link/LinkButton.js +11 -7
  5. package/lib/EditorToolbar/Tools/Link/LinkModal.js +8 -4
  6. package/lib/EditorToolbar/Tools/Link/RemoveLinkButton.js +2 -2
  7. package/lib/Extensions/Extensions.d.ts +2 -1
  8. package/lib/Extensions/Extensions.js +3 -0
  9. package/lib/Extensions/FetchUrlExtension/FetchUrlExtension.d.ts +1 -0
  10. package/lib/Extensions/FetchUrlExtension/FetchUrlExtension.js +10 -0
  11. package/lib/Extensions/LinkExtension/AssetLinkExtension.js +1 -1
  12. package/lib/Extensions/LinkExtension/DamLinkExtension.d.ts +29 -0
  13. package/lib/Extensions/LinkExtension/DamLinkExtension.js +111 -0
  14. package/lib/Extensions/LinkExtension/LinkExtension.js +1 -1
  15. package/lib/ui/Fields/MatrixAsset/MatrixAsset.d.ts +16 -2
  16. package/lib/ui/Fields/MatrixAsset/MatrixAsset.js +71 -20
  17. package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.js +10 -0
  18. package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.js +13 -0
  19. package/package.json +2 -2
  20. package/src/EditorToolbar/Tools/Link/Form/LinkForm.tsx +26 -7
  21. package/src/EditorToolbar/Tools/Link/LinkButton.spec.tsx +74 -1
  22. package/src/EditorToolbar/Tools/Link/LinkButton.tsx +19 -8
  23. package/src/EditorToolbar/Tools/Link/LinkModal.tsx +10 -5
  24. package/src/EditorToolbar/Tools/Link/RemoveLinkButton.tsx +4 -3
  25. package/src/Extensions/Extensions.ts +3 -0
  26. package/src/Extensions/FetchUrlExtension/FetchUrlExtension.ts +14 -0
  27. package/src/Extensions/LinkExtension/AssetLinkExtension.ts +1 -1
  28. package/src/Extensions/LinkExtension/DamLinkExtension.spec.ts +110 -0
  29. package/src/Extensions/LinkExtension/DamLinkExtension.ts +137 -0
  30. package/src/Extensions/LinkExtension/LinkExtension.ts +1 -1
  31. package/src/ui/Fields/MatrixAsset/MatrixAsset.tsx +83 -26
  32. package/src/utils/converters/mocks/squizNodeJson.mock.ts +48 -0
  33. package/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.spec.ts +63 -0
  34. package/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.ts +10 -0
  35. package/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.ts +12 -0
  36. package/src/utils/getMarkNamesByGroup.spec.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 2.6.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 25036af: Squiz Link support for DAM assets
8
+ - Updated dependencies [25036af]
9
+ - @squiz/dx-json-schema-lib@1.81.4
10
+
3
11
  ## 2.6.5
4
12
 
5
13
  ### Patch Changes
@@ -2,14 +2,15 @@ import { ReactElement } from 'react';
2
2
  import { SubmitHandler } from 'react-hook-form';
3
3
  import { FromToProps } from 'remirror';
4
4
  import { UpdateLinkProps } from '../../../../Extensions/LinkExtension/LinkExtension';
5
- import { UpdateAssetLinkProps } from '../../../../Extensions/LinkExtension/AssetLinkExtension';
6
5
  import { MarkName } from '../../../../Extensions/Extensions';
7
6
  import { DeepPartial } from '../../../../types';
7
+ import { UpdateAssetLinkProps } from '../../../../Extensions/LinkExtension/AssetLinkExtension';
8
+ import { UpdateDAMLinkProps } from '../../../../Extensions/LinkExtension/DamLinkExtension';
8
9
  export type LinkFormData = {
9
10
  linkType: MarkName;
10
11
  text: string;
11
12
  link: UpdateLinkProps['attrs'];
12
- assetLink: UpdateAssetLinkProps['attrs'];
13
+ assetLink: Partial<UpdateDAMLinkProps['attrs'] & UpdateAssetLinkProps['attrs']>;
13
14
  range: FromToProps;
14
15
  };
15
16
  export type FormProps = {
@@ -25,7 +25,7 @@ const LinkForm = ({ data, onSubmit }) => {
25
25
  const linkType = watch('linkType') || Extensions_1.MarkName.AssetLink;
26
26
  return (react_1.default.createElement("form", { className: "squiz-fte-form", onSubmit: handleSubmit(onSubmit) },
27
27
  react_1.default.createElement("div", { className: "squiz-fte-form-group mb-4" },
28
- react_1.default.createElement(Tabs_1.Tabs, { value: linkType, options: linkTypeOptions, onChange: (value) => setValue('linkType', value) })),
28
+ react_1.default.createElement(Tabs_1.Tabs, { value: linkType === Extensions_1.MarkName.DAMLink ? Extensions_1.MarkName.AssetLink : linkType, options: linkTypeOptions, onChange: (value) => setValue('linkType', value) })),
29
29
  linkType === Extensions_1.MarkName.Link && (react_1.default.createElement(react_1.default.Fragment, null,
30
30
  react_1.default.createElement("div", { className: (0, clsx_1.default)('squiz-fte-form-group mb-2') },
31
31
  react_1.default.createElement(Input_1.Input, { label: "URL", required: true, error: errors?.link?.href?.message, ...register('link.href', {
@@ -45,11 +45,25 @@ const LinkForm = ({ data, onSubmit }) => {
45
45
  react_1.default.createElement(Input_1.Input, { label: "Title", error: errors?.link?.title?.message, ...register('link.title') })),
46
46
  react_1.default.createElement("div", { className: (0, clsx_1.default)('squiz-fte-form-group mb-2') },
47
47
  react_1.default.createElement(Checkbox_1.Checkbox, { label: "Open link in new window", onChange: (value) => setValue('link.target', value), defaultChecked: data?.link?.target === common_1.LinkTarget.Blank, unchecked: common_1.LinkTarget.Self, checked: common_1.LinkTarget.Blank })))),
48
- linkType === Extensions_1.MarkName.AssetLink && (react_1.default.createElement(react_1.default.Fragment, null,
48
+ (linkType === Extensions_1.MarkName.AssetLink || linkType === Extensions_1.MarkName.DAMLink) && (react_1.default.createElement(react_1.default.Fragment, null,
49
49
  react_1.default.createElement("div", { className: (0, clsx_1.default)('squiz-fte-form-group mb-2') },
50
50
  react_1.default.createElement(react_hook_form_1.Controller, { control: control, name: "assetLink", rules: {
51
- validate: (0, validation_1.hasProperties)('An asset must be selected', ['matrixIdentifier', 'matrixAssetId']),
52
- }, render: ({ field: { onChange, value }, fieldState: { error } }) => (react_1.default.createElement(MatrixAsset_1.MatrixAsset, { modalTitle: "Insert link", value: value, onChange: onChange, error: error?.message })) })),
51
+ validate: (value) => {
52
+ if (value?.damObjectId || value?.damSystemIdentifier) {
53
+ return value.damObjectId && value.damSystemIdentifier ? true : 'A DAM asset must be selected';
54
+ }
55
+ return value?.matrixAssetId && value?.matrixIdentifier ? true : 'An asset must be selected';
56
+ },
57
+ }, render: ({ field: { onChange, value }, fieldState: { error } }) => (react_1.default.createElement(MatrixAsset_1.MatrixAsset, { modalTitle: "Insert link", value: value, onChange: (newValue) => {
58
+ onChange(newValue);
59
+ const updated = newValue.target.value;
60
+ if (updated.damSystemIdentifier && updated.damObjectId) {
61
+ setValue('linkType', Extensions_1.MarkName.DAMLink);
62
+ }
63
+ else {
64
+ setValue('linkType', Extensions_1.MarkName.AssetLink);
65
+ }
66
+ }, error: error?.message })) })),
53
67
  react_1.default.createElement("div", { className: (0, clsx_1.default)('squiz-fte-form-group mb-2') },
54
68
  react_1.default.createElement(Input_1.Input, { label: "Text", required: true, error: errors?.text?.message, ...register('text', {
55
69
  required: 'Text is required',
@@ -35,7 +35,7 @@ const Extensions_1 = require("../../../Extensions/Extensions");
35
35
  const getShortcutSymbol_1 = require("../../../utils/getShortcutSymbol");
36
36
  const LinkButton = ({ inPopover = false }) => {
37
37
  const [showModal, setShowModal] = (0, react_1.useState)(false);
38
- const { updateLink, updateAssetLink } = (0, react_2.useCommands)();
38
+ const { updateLink, updateAssetLink, updateDAMLink } = (0, react_2.useCommands)();
39
39
  const active = (0, react_2.useActive)();
40
40
  // If the image tool is active, disable the link tool as they shouldn't work at the same time
41
41
  const disabled = active.image() || active.codeBlock();
@@ -50,11 +50,15 @@ const LinkButton = ({ inPopover = false }) => {
50
50
  return true;
51
51
  }, []);
52
52
  const handleSubmit = (data) => {
53
- if (data.linkType === Extensions_1.MarkName.AssetLink) {
54
- updateAssetLink({ text: data.text, attrs: data.assetLink, range: data.range });
55
- }
56
- else {
57
- updateLink({ text: data.text, attrs: data.link, range: data.range });
53
+ switch (data.linkType) {
54
+ case Extensions_1.MarkName.AssetLink:
55
+ updateAssetLink({ text: data.text, attrs: data.assetLink, range: data.range });
56
+ break;
57
+ case Extensions_1.MarkName.DAMLink:
58
+ updateDAMLink({ text: data.text, attrs: data.assetLink, range: data.range });
59
+ break;
60
+ default:
61
+ updateLink({ text: data.text, attrs: data.link, range: data.range });
58
62
  }
59
63
  setShowModal(false);
60
64
  };
@@ -65,7 +69,7 @@ const LinkButton = ({ inPopover = false }) => {
65
69
  (0, react_2.useKeymap)('Mod-k', disabled ? () => true : handleShortcut);
66
70
  }
67
71
  return (react_1.default.createElement(react_1.default.Fragment, null,
68
- react_1.default.createElement(Button_1.default, { handleOnClick: handleClick, isActive: active.link() || active.assetLink(), icon: react_1.default.createElement(InsertLinkRounded_1.default, null), label: `Link (${(0, getShortcutSymbol_1.getShortcutSymbol)()}+K)`, isDisabled: disabled }),
72
+ react_1.default.createElement(Button_1.default, { handleOnClick: handleClick, isActive: active.link() || active.assetLink() || active.DAMLink(), icon: react_1.default.createElement(InsertLinkRounded_1.default, null), label: `Link (${(0, getShortcutSymbol_1.getShortcutSymbol)()}+K)`, isDisabled: disabled }),
69
73
  showModal && react_1.default.createElement(LinkModal_1.default, { onCancel: () => setShowModal(false), onSubmit: handleSubmit })));
70
74
  };
71
75
  exports.default = LinkButton;
@@ -12,13 +12,17 @@ const hooks_1 = require("../../../hooks");
12
12
  const Extensions_1 = require("../../../Extensions/Extensions");
13
13
  const LinkModal = ({ onCancel, onSubmit }) => {
14
14
  const { helpers, view: { state }, } = (0, react_2.useRemirrorContext)();
15
- const { selection, marks } = (0, hooks_1.useExpandedSelection)([Extensions_1.MarkName.Link, Extensions_1.MarkName.AssetLink]);
15
+ const { selection, marks } = (0, hooks_1.useExpandedSelection)([Extensions_1.MarkName.Link, Extensions_1.MarkName.AssetLink, Extensions_1.MarkName.DAMLink]);
16
16
  const selectedText = helpers.getTextBetween(selection.from, selection.to, state.doc);
17
17
  const data = {
18
- linkType: marks[0]?.type?.name === Extensions_1.MarkName.Link ? Extensions_1.MarkName.Link : Extensions_1.MarkName.AssetLink,
18
+ assetLink: { ...marks.find((m) => m.type.name === Extensions_1.MarkName.DAMLink || m.type.name === Extensions_1.MarkName.AssetLink)?.attrs },
19
+ link: { ...marks.find((m) => m.type.name === 'link')?.attrs },
19
20
  text: selectedText,
20
- link: { ...marks.find((mark) => mark.type.name === 'link')?.attrs },
21
- assetLink: { ...marks.find((mark) => mark.type.name === Extensions_1.MarkName.AssetLink)?.attrs },
21
+ linkType: marks.find((m) => m.type.name === Extensions_1.MarkName.DAMLink)
22
+ ? Extensions_1.MarkName.DAMLink
23
+ : marks[0]?.type.name === Extensions_1.MarkName.Link
24
+ ? Extensions_1.MarkName.Link
25
+ : Extensions_1.MarkName.AssetLink,
22
26
  range: { from: selection.from, to: selection.to },
23
27
  };
24
28
  return (react_1.default.createElement(FormModal_1.default, { title: "Link", icon: react_1.default.createElement(InsertLinkRounded_1.default, null), onCancel: onCancel },
@@ -34,9 +34,9 @@ const getShortcutSymbol_1 = require("../../../utils/getShortcutSymbol");
34
34
  const RemoveLinkButton = ({ inPopover = false }) => {
35
35
  const chain = (0, react_2.useChainedCommands)();
36
36
  const active = (0, react_2.useActive)();
37
- const disabled = !active.link() && !active.assetLink();
37
+ const disabled = !active.link() && !active.assetLink() && !active.DAMLink();
38
38
  const handleClick = () => {
39
- chain.removeLink().removeAssetLink().focus().run();
39
+ chain.removeLink().removeAssetLink().removeDAMLink().focus().run();
40
40
  };
41
41
  const handleShortcut = (0, react_1.useCallback)(() => {
42
42
  handleClick();
@@ -13,6 +13,7 @@ export declare enum NodeName {
13
13
  }
14
14
  export declare enum MarkName {
15
15
  Link = "link",
16
- AssetLink = "assetLink"
16
+ AssetLink = "assetLink",
17
+ DAMLink = "DAMLink"
17
18
  }
18
19
  export declare const createExtensions: (context: EditorContextOptions, enableDecorations?: boolean) => () => Extension[];
@@ -15,6 +15,7 @@ const UnsupportedNodeExtension_1 = require("./UnsuportedExtension/UnsupportedNod
15
15
  const FetchUrlExtension_1 = require("./FetchUrlExtension/FetchUrlExtension");
16
16
  const extension_react_tables_1 = require("@remirror/extension-react-tables");
17
17
  const extension_react_component_1 = require("@remirror/extension-react-component");
18
+ const DamLinkExtension_1 = require("./LinkExtension/DamLinkExtension");
18
19
  var NodeName;
19
20
  (function (NodeName) {
20
21
  NodeName["Image"] = "image";
@@ -31,6 +32,7 @@ var MarkName;
31
32
  (function (MarkName) {
32
33
  MarkName["Link"] = "link";
33
34
  MarkName["AssetLink"] = "assetLink";
35
+ MarkName["DAMLink"] = "DAMLink";
34
36
  })(MarkName = exports.MarkName || (exports.MarkName = {}));
35
37
  const createExtensions = (context, enableDecorations = true) => {
36
38
  return () => {
@@ -53,6 +55,7 @@ const createExtensions = (context, enableDecorations = true) => {
53
55
  matrixDomain: context.matrix.matrixDomain,
54
56
  }),
55
57
  new DAMImageExtension_1.DAMImageExtension(),
58
+ new DamLinkExtension_1.DAMLinkExtension(),
56
59
  new LinkExtension_1.LinkExtension(),
57
60
  new AssetLinkExtension_1.AssetLinkExtension({
58
61
  matrixDomain: context.matrix.matrixDomain,
@@ -8,5 +8,6 @@ export declare class FetchUrlExtension extends PlainExtension<FetchUrlOptions> {
8
8
  get name(): string;
9
9
  onView(view: EditorView): Dispose | void;
10
10
  private findAssetLinkMark;
11
+ private findDAMLinkMark;
11
12
  private fetchAndReplace;
12
13
  }
@@ -38,6 +38,13 @@ let FetchUrlExtension = class FetchUrlExtension extends core_1.PlainExtension {
38
38
  tr.addMark(pos, pos + node.nodeSize, updatedMark);
39
39
  }));
40
40
  }
41
+ const damLinkMark = this.findDAMLinkMark(node.marks);
42
+ if (node.type.name === 'text' && damLinkMark) {
43
+ promises.push(this.fetchAndReplace(damLinkMark.attrs, (url) => {
44
+ const updatedMark = damLinkMark.type.create({ ...damLinkMark.attrs, href: url });
45
+ tr.addMark(pos, pos + node.nodeSize, updatedMark);
46
+ }));
47
+ }
41
48
  });
42
49
  if (promises.length) {
43
50
  Promise.all(promises).then(() => {
@@ -48,6 +55,9 @@ let FetchUrlExtension = class FetchUrlExtension extends core_1.PlainExtension {
48
55
  findAssetLinkMark(marks) {
49
56
  return marks.find((mark) => mark.type.name === Extensions_1.MarkName.AssetLink && mark.attrs.href === '');
50
57
  }
58
+ findDAMLinkMark(marks) {
59
+ return marks.find((mark) => mark.type.name === Extensions_1.MarkName.DAMLink && mark.attrs.href === '');
60
+ }
51
61
  fetchAndReplace(nodeAttrs, onFetched) {
52
62
  return this.options
53
63
  .fetchUrl(nodeAttrs)
@@ -19,7 +19,7 @@ let AssetLinkExtension = class AssetLinkExtension extends core_1.MarkExtension {
19
19
  createMarkSpec(extra, override) {
20
20
  return {
21
21
  inclusive: false,
22
- excludes: [this.name, Extensions_1.MarkName.Link].join(' '),
22
+ excludes: [this.name, Extensions_1.MarkName.Link, Extensions_1.MarkName.DAMLink].join(' '),
23
23
  ...override,
24
24
  attrs: {
25
25
  ...extra.defaults(),
@@ -0,0 +1,29 @@
1
+ import { ApplySchemaAttributes, FromToProps, MarkExtensionSpec, MarkSpecOverride } from 'remirror';
2
+ import { CommandFunction, MarkExtension } from '@remirror/core';
3
+ import { LinkTarget } from './common';
4
+ export type DAMLinkAttributes = {
5
+ damObjectId: string;
6
+ damSystemIdentifier: string;
7
+ damSystemType: string;
8
+ damAdditional?: {
9
+ variant: string;
10
+ };
11
+ target: LinkTarget;
12
+ href: string;
13
+ url: string;
14
+ };
15
+ export type DAMLinkOptions = {
16
+ defaultTarget?: LinkTarget;
17
+ supportedTargets?: LinkTarget[];
18
+ };
19
+ export type UpdateDAMLinkProps = {
20
+ text: string;
21
+ attrs: Partial<DAMLinkAttributes>;
22
+ range: FromToProps;
23
+ };
24
+ export declare class DAMLinkExtension extends MarkExtension<DAMLinkOptions> {
25
+ get name(): string;
26
+ createMarkSpec(extra: ApplySchemaAttributes, override: MarkSpecOverride): MarkExtensionSpec;
27
+ updateDAMLink({ text, attrs, range }: UpdateDAMLinkProps): CommandFunction;
28
+ removeDAMLink(): CommandFunction;
29
+ }
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.DAMLinkExtension = void 0;
10
+ const remirror_1 = require("remirror");
11
+ const core_1 = require("@remirror/core");
12
+ const common_1 = require("./common");
13
+ const CommandsExtension_1 = require("../CommandsExtension/CommandsExtension");
14
+ const Extensions_1 = require("../Extensions");
15
+ let DAMLinkExtension = class DAMLinkExtension extends core_1.MarkExtension {
16
+ get name() {
17
+ return Extensions_1.MarkName.DAMLink;
18
+ }
19
+ createMarkSpec(extra, override) {
20
+ return {
21
+ inclusive: false,
22
+ excludes: [this.name, Extensions_1.MarkName.Link, Extensions_1.MarkName.AssetLink].join(' '),
23
+ ...override,
24
+ attrs: {
25
+ ...extra.defaults(),
26
+ damObjectId: {},
27
+ damSystemIdentifier: {},
28
+ damSystemType: {},
29
+ damAdditional: { default: undefined },
30
+ href: { default: '' },
31
+ target: { default: this.options.defaultTarget },
32
+ },
33
+ parseDOM: [
34
+ {
35
+ tag: 'a[data-dam-object-id]',
36
+ getAttrs: (node) => {
37
+ if (!(0, remirror_1.isElementDomNode)(node)) {
38
+ return false;
39
+ }
40
+ const damObjectId = node.getAttribute('data-dam-object-id');
41
+ const damSystemIdentifier = node.getAttribute('data-dam-system-identifier');
42
+ const damSystemType = node.getAttribute('data-dam-system-type');
43
+ let damAdditional = node.getAttribute('data-dam-additional') || undefined;
44
+ if (!damObjectId || !damSystemIdentifier || !damSystemType) {
45
+ return false;
46
+ }
47
+ if (damAdditional) {
48
+ damAdditional = JSON.parse(damAdditional);
49
+ }
50
+ return {
51
+ ...extra.parse(node),
52
+ damObjectId,
53
+ damSystemIdentifier,
54
+ damSystemType,
55
+ damAdditional,
56
+ target: (0, common_1.validateTarget)(node.getAttribute('target'), this.options.supportedTargets, this.options.defaultTarget),
57
+ href: node.getAttribute('href') || '',
58
+ };
59
+ },
60
+ },
61
+ ],
62
+ toDOM: (node) => {
63
+ const { damObjectId, damSystemIdentifier, damSystemType, damAdditional, target, href, ...rest } = (0, core_1.omitExtraAttributes)(node.attrs, extra);
64
+ const rel = 'noopener noreferrer nofollow';
65
+ return [
66
+ 'a',
67
+ {
68
+ ...extra.dom(node),
69
+ ...rest,
70
+ rel,
71
+ href,
72
+ target: (0, common_1.validateTarget)(target, this.options.supportedTargets, this.options.defaultTarget),
73
+ 'data-dam-object-id': damObjectId,
74
+ 'data-dam-system-identifier': damSystemIdentifier,
75
+ 'data-dam-system-type': damSystemType,
76
+ 'data-dam-additional': damAdditional ? JSON.stringify(damAdditional) : undefined,
77
+ },
78
+ 0,
79
+ ];
80
+ },
81
+ };
82
+ }
83
+ updateDAMLink({ text, attrs, range }) {
84
+ return this.store.getExtension(CommandsExtension_1.CommandsExtension).updateMark({
85
+ attrs: { ...attrs, href: attrs.url },
86
+ text,
87
+ range,
88
+ mark: this.type,
89
+ removeMark: !attrs.damObjectId,
90
+ });
91
+ }
92
+ removeDAMLink() {
93
+ return (0, core_1.removeMark)({ type: this.type });
94
+ }
95
+ };
96
+ __decorate([
97
+ (0, core_1.command)()
98
+ ], DAMLinkExtension.prototype, "updateDAMLink", null);
99
+ __decorate([
100
+ (0, core_1.command)()
101
+ ], DAMLinkExtension.prototype, "removeDAMLink", null);
102
+ DAMLinkExtension = __decorate([
103
+ (0, core_1.extension)({
104
+ defaultOptions: {
105
+ defaultTarget: common_1.LinkTarget.Self,
106
+ supportedTargets: [common_1.LinkTarget.Self, common_1.LinkTarget.Blank],
107
+ },
108
+ defaultPriority: remirror_1.ExtensionPriority.High,
109
+ })
110
+ ], DAMLinkExtension);
111
+ exports.DAMLinkExtension = DAMLinkExtension;
@@ -19,7 +19,7 @@ let LinkExtension = class LinkExtension extends core_1.MarkExtension {
19
19
  createMarkSpec(extra, override) {
20
20
  return {
21
21
  inclusive: false,
22
- excludes: [this.name, Extensions_1.MarkName.AssetLink].join(' '),
22
+ excludes: [this.name, Extensions_1.MarkName.AssetLink, Extensions_1.MarkName.DAMLink].join(' '),
23
23
  ...override,
24
24
  attrs: {
25
25
  ...extra.defaults(),
@@ -1,11 +1,25 @@
1
1
  import React from 'react';
2
2
  import { InputContainerProps } from '../InputContainer/InputContainer';
3
+ import { LinkTarget } from '../../../Extensions/LinkExtension/common';
3
4
  type MatrixAssetValue = {
4
5
  matrixIdentifier?: string;
5
6
  matrixAssetId?: string;
7
+ matrixDomain?: string;
8
+ };
9
+ type DAMAssetValue = {
10
+ damSystemIdentifier?: string;
11
+ damObjectId?: string;
12
+ damSystemType?: string;
13
+ damAdditional?: {
14
+ variant: string;
15
+ };
16
+ };
17
+ export type ResourceBrowserSelectorValue = MatrixAssetValue & DAMAssetValue & {
6
18
  url?: string;
19
+ target?: LinkTarget;
20
+ subType?: 'matrix' | 'dam';
7
21
  };
8
- export type MatrixAssetProps<T extends MatrixAssetValue> = Omit<InputContainerProps, 'children'> & {
22
+ export type ResourceBrowserSelectorProps<T extends ResourceBrowserSelectorValue> = Omit<InputContainerProps, 'children'> & {
9
23
  modalTitle: string;
10
24
  allowedTypes?: string[];
11
25
  value?: T | null;
@@ -15,5 +29,5 @@ export type MatrixAssetProps<T extends MatrixAssetValue> = Omit<InputContainerPr
15
29
  };
16
30
  }) => void;
17
31
  };
18
- export declare const MatrixAsset: <T extends MatrixAssetValue>({ modalTitle, allowedTypes, value, onChange, ...props }: MatrixAssetProps<T>) => React.JSX.Element;
32
+ export declare const MatrixAsset: <T extends ResourceBrowserSelectorValue>({ modalTitle, allowedTypes, value, onChange, ...props }: ResourceBrowserSelectorProps<T>) => React.JSX.Element;
19
33
  export {};
@@ -1,30 +1,81 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
4
24
  };
5
25
  Object.defineProperty(exports, "__esModule", { value: true });
6
26
  exports.MatrixAsset = void 0;
7
- const react_1 = __importDefault(require("react"));
27
+ const react_1 = __importStar(require("react"));
8
28
  const resource_browser_1 = require("@squiz/resource-browser");
9
29
  const InputContainer_1 = require("../InputContainer/InputContainer");
10
30
  const MatrixAsset = ({ modalTitle, allowedTypes, value, onChange, ...props }) => {
31
+ const convertFormDataToResourceBrowserValue = (0, react_1.useCallback)((value) => {
32
+ if (value && value.damSystemIdentifier && value.damObjectId) {
33
+ return {
34
+ sourceId: value.damSystemIdentifier,
35
+ resourceId: value.damObjectId,
36
+ variant: value.damAdditional?.variant,
37
+ };
38
+ }
39
+ if (value && value.matrixIdentifier && value.matrixAssetId) {
40
+ return {
41
+ sourceId: value.matrixIdentifier,
42
+ resourceId: value.matrixAssetId,
43
+ };
44
+ }
45
+ return null;
46
+ }, []);
47
+ const handleResourceChange = (0, react_1.useCallback)((resource) => {
48
+ let onChangeData = {
49
+ ...value,
50
+ matrixIdentifier: undefined,
51
+ matrixAssetId: undefined,
52
+ damSystemIdentifier: undefined,
53
+ damObjectId: undefined,
54
+ damSystemType: undefined,
55
+ damAdditional: undefined,
56
+ };
57
+ if (resource?.source?.type === 'dam') {
58
+ const damResource = resource;
59
+ onChangeData = {
60
+ ...onChangeData,
61
+ damSystemIdentifier: resource.source.id,
62
+ damObjectId: resource.id,
63
+ damSystemType: resource.source.configuration.externalType,
64
+ damAdditional: damResource.variant ? { variant: damResource.variant } : undefined,
65
+ url: resource.url,
66
+ };
67
+ }
68
+ if (resource?.source.type === 'matrix') {
69
+ onChangeData = {
70
+ ...onChangeData,
71
+ matrixIdentifier: resource?.source?.id,
72
+ matrixAssetId: resource?.id,
73
+ url: resource?.url,
74
+ };
75
+ }
76
+ onChange({ target: { value: onChangeData } });
77
+ }, [value]);
11
78
  return (react_1.default.createElement(InputContainer_1.InputContainer, { ...props },
12
- react_1.default.createElement(resource_browser_1.ResourceBrowser, { modalTitle: modalTitle, allowedTypes: allowedTypes, value: value && value.matrixIdentifier && value.matrixAssetId
13
- ? {
14
- sourceId: value.matrixIdentifier,
15
- resourceId: value.matrixAssetId,
16
- }
17
- : null, onChange: (resource) => {
18
- onChange({
19
- target: {
20
- value: {
21
- ...value,
22
- matrixIdentifier: resource?.source?.id,
23
- matrixAssetId: resource?.id,
24
- url: resource?.url,
25
- },
26
- },
27
- });
28
- } })));
79
+ react_1.default.createElement(resource_browser_1.ResourceBrowser, { modalTitle: modalTitle, allowedTypes: allowedTypes, value: convertFormDataToResourceBrowserValue(value), onChange: handleResourceChange })));
29
80
  };
30
81
  exports.MatrixAsset = MatrixAsset;
@@ -216,6 +216,16 @@ const transformMark = (mark, node) => {
216
216
  matrixAssetId: mark.attrs.matrixAssetId,
217
217
  children: [],
218
218
  });
219
+ case 'DAMLink':
220
+ return wrapNodeIfNeeded(node, {
221
+ type: 'link-to-dam-asset',
222
+ target: mark.attrs.target,
223
+ damSystemType: mark.attrs.damSystemType,
224
+ damSystemIdentifier: mark.attrs.damSystemIdentifier,
225
+ damObjectId: mark.attrs.damObjectId,
226
+ damAdditional: mark.attrs.damAdditional,
227
+ children: [],
228
+ });
219
229
  }
220
230
  throw new Error(`Unsupported mark "${mark.type.name}" was applied to node.`);
221
231
  };
@@ -8,6 +8,7 @@ const getNodeType = (node) => {
8
8
  'link-to-matrix-asset': Extensions_1.NodeName.Text,
9
9
  'matrix-image': Extensions_1.NodeName.AssetImage,
10
10
  'dam-image': Extensions_1.NodeName.DAMImage,
11
+ 'link-to-dam-asset': Extensions_1.NodeName.Text,
11
12
  text: 'text',
12
13
  };
13
14
  const tagMap = {
@@ -125,6 +126,18 @@ const getNodeMarks = (node) => {
125
126
  },
126
127
  });
127
128
  }
129
+ else if (node.type === 'link-to-dam-asset') {
130
+ marks.push({
131
+ type: Extensions_1.MarkName.DAMLink,
132
+ attrs: {
133
+ damSystemType: node.damSystemType,
134
+ damSystemIdentifier: node.damSystemIdentifier,
135
+ damObjectId: node.damObjectId,
136
+ damAdditional: node.damAdditional ? JSON.stringify(node.damAdditional) : undefined,
137
+ target: node.target,
138
+ },
139
+ });
140
+ }
128
141
  else if (node.type === 'tag' && node.tag === 'strong') {
129
142
  marks.push({ type: 'bold' });
130
143
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squiz/formatted-text-editor",
3
- "version": "2.6.5",
3
+ "version": "2.6.6",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "private": false,
@@ -25,7 +25,7 @@
25
25
  "@mui/icons-material": "5.15.18",
26
26
  "@remirror/extension-react-tables": "^2.2.21",
27
27
  "@remirror/react": "2.0.35",
28
- "@squiz/dx-json-schema-lib": "^1.80.1",
28
+ "@squiz/dx-json-schema-lib": "^1.81.4",
29
29
  "@squiz/dxp-content-tools-modal": "^0.4.0",
30
30
  "clsx": "2.1.1",
31
31
  "react-hook-form": "7.51.4",