@strapi/content-manager 5.52.2 → 5.53.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.
- package/dist/admin/history/components/VersionInputRenderer.js +5 -1
- package/dist/admin/history/components/VersionInputRenderer.js.map +1 -1
- package/dist/admin/history/components/VersionInputRenderer.mjs +5 -1
- package/dist/admin/history/components/VersionInputRenderer.mjs.map +1 -1
- package/dist/admin/hooks/usePersistentQueryParams.js +10 -2
- package/dist/admin/hooks/usePersistentQueryParams.js.map +1 -1
- package/dist/admin/hooks/usePersistentQueryParams.mjs +11 -3
- package/dist/admin/hooks/usePersistentQueryParams.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.js +25 -16
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.mjs +25 -16
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +29 -11
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +29 -11
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.js +3 -3
- package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.mjs +4 -4
- package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/Relations.js +11 -2
- package/dist/admin/pages/ListView/components/TableCells/Relations.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/Relations.mjs +11 -2
- package/dist/admin/pages/ListView/components/TableCells/Relations.mjs.map +1 -1
- package/dist/admin/src/utils/relations.d.ts +4 -3
- package/dist/admin/translations/cs.json.js +1 -0
- package/dist/admin/translations/cs.json.js.map +1 -1
- package/dist/admin/translations/cs.json.mjs +1 -0
- package/dist/admin/translations/cs.json.mjs.map +1 -1
- package/dist/admin/translations/de.json.js +1 -0
- package/dist/admin/translations/de.json.js.map +1 -1
- package/dist/admin/translations/de.json.mjs +1 -0
- package/dist/admin/translations/de.json.mjs.map +1 -1
- package/dist/admin/translations/en.json.js +1 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +1 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/translations/fr.json.js +1 -0
- package/dist/admin/translations/fr.json.js.map +1 -1
- package/dist/admin/translations/fr.json.mjs +1 -0
- package/dist/admin/translations/fr.json.mjs.map +1 -1
- package/dist/admin/translations/ja.json.js +1 -0
- package/dist/admin/translations/ja.json.js.map +1 -1
- package/dist/admin/translations/ja.json.mjs +1 -0
- package/dist/admin/translations/ja.json.mjs.map +1 -1
- package/dist/admin/translations/ko.json.js +1 -0
- package/dist/admin/translations/ko.json.js.map +1 -1
- package/dist/admin/translations/ko.json.mjs +1 -0
- package/dist/admin/translations/ko.json.mjs.map +1 -1
- package/dist/admin/translations/nl.json.js +1 -0
- package/dist/admin/translations/nl.json.js.map +1 -1
- package/dist/admin/translations/nl.json.mjs +1 -0
- package/dist/admin/translations/nl.json.mjs.map +1 -1
- package/dist/admin/translations/pl.json.js +1 -0
- package/dist/admin/translations/pl.json.js.map +1 -1
- package/dist/admin/translations/pl.json.mjs +1 -0
- package/dist/admin/translations/pl.json.mjs.map +1 -1
- package/dist/admin/translations/sk.json.js +1 -0
- package/dist/admin/translations/sk.json.js.map +1 -1
- package/dist/admin/translations/sk.json.mjs +1 -0
- package/dist/admin/translations/sk.json.mjs.map +1 -1
- package/dist/admin/utils/relations.js +9 -4
- package/dist/admin/utils/relations.js.map +1 -1
- package/dist/admin/utils/relations.mjs +9 -4
- package/dist/admin/utils/relations.mjs.map +1 -1
- package/dist/server/services/permission-checker.js +0 -4
- package/dist/server/services/permission-checker.js.map +1 -1
- package/dist/server/services/permission-checker.mjs +0 -4
- package/dist/server/services/permission-checker.mjs.map +1 -1
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -4
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts +2 -2
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -32,6 +32,28 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
|
32
32
|
const isLinkNode = (element)=>{
|
|
33
33
|
return element.type === 'link';
|
|
34
34
|
};
|
|
35
|
+
const ALLOWED_LINK_PROTOCOLS = new Set([
|
|
36
|
+
'http:',
|
|
37
|
+
'https:',
|
|
38
|
+
'ftp:',
|
|
39
|
+
'mailto:',
|
|
40
|
+
'tel:'
|
|
41
|
+
]);
|
|
42
|
+
const isValidLink = (link)=>{
|
|
43
|
+
try {
|
|
44
|
+
const url = new URL(link.startsWith('/') ? `https://strapi.io${link}` : link);
|
|
45
|
+
return ALLOWED_LINK_PROTOCOLS.has(url.protocol);
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const isValidAbsoluteLink = (link)=>{
|
|
51
|
+
try {
|
|
52
|
+
return ALLOWED_LINK_PROTOCOLS.has(new URL(link).protocol);
|
|
53
|
+
} catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
35
57
|
const removeLink = (editor)=>{
|
|
36
58
|
slate.Transforms.unwrapNodes(editor, {
|
|
37
59
|
match: (node)=>!slate.Editor.isEditor(node) && slate.Element.isElement(node) && node.type === 'link'
|
|
@@ -129,23 +151,14 @@ const LinkContent = /*#__PURE__*/ React__namespace.forwardRef(({ link, children,
|
|
|
129
151
|
const [linkTarget, setLinkTarget] = React__namespace.useState(link.target);
|
|
130
152
|
const linkInputRef = React__namespace.useRef(null);
|
|
131
153
|
const isLastInsertedLink = editor.lastInsertedLinkPath ? !slate.Path.equals(path, editor.lastInsertedLinkPath) : true;
|
|
132
|
-
const
|
|
154
|
+
const isSaveDisabled = !isValidLink(linkUrl);
|
|
133
155
|
const onLinkChange = (e)=>{
|
|
134
|
-
setIsSaveDisabled(false);
|
|
135
156
|
setLinkUrl(e.target.value);
|
|
136
|
-
try {
|
|
137
|
-
// eslint-disable-next-line no-new
|
|
138
|
-
new URL(e.target.value?.startsWith('/') ? `https://strapi.io${e.target.value}` : e.target.value);
|
|
139
|
-
} catch {
|
|
140
|
-
setIsSaveDisabled(true);
|
|
141
|
-
}
|
|
142
157
|
};
|
|
143
158
|
const onLinkRelChange = (e)=>{
|
|
144
|
-
setIsSaveDisabled(false);
|
|
145
159
|
setLinRel(e.target.value);
|
|
146
160
|
};
|
|
147
161
|
const onLinkTargetChange = (e)=>{
|
|
148
|
-
setIsSaveDisabled(false);
|
|
149
162
|
setLinkTarget(e.target.value);
|
|
150
163
|
};
|
|
151
164
|
const handleSave = (e)=>{
|
|
@@ -187,7 +200,7 @@ const LinkContent = /*#__PURE__*/ React__namespace.forwardRef(({ link, children,
|
|
|
187
200
|
...attributes,
|
|
188
201
|
ref: forwardedRef,
|
|
189
202
|
tag: "a",
|
|
190
|
-
href: link.url,
|
|
203
|
+
href: isValidLink(link.url) ? link.url : undefined,
|
|
191
204
|
rel: link.rel,
|
|
192
205
|
target: link.target,
|
|
193
206
|
onClick: ()=>setPopoverOpen(true),
|
|
@@ -425,17 +438,13 @@ const withLinks = (editor)=>{
|
|
|
425
438
|
editor.insertData = (data)=>{
|
|
426
439
|
const pastedText = data.getData('text/plain');
|
|
427
440
|
if (pastedText) {
|
|
428
|
-
|
|
429
|
-
// eslint-disable-next-line no-new
|
|
430
|
-
new URL(pastedText);
|
|
441
|
+
if (isValidAbsoluteLink(pastedText)) {
|
|
431
442
|
// Do not show link popup on copy-paste a link, so do not save its path
|
|
432
443
|
editor.shouldSaveLinkPath = false;
|
|
433
444
|
insertLink(editor, {
|
|
434
445
|
url: pastedText
|
|
435
446
|
});
|
|
436
447
|
return;
|
|
437
|
-
} catch {
|
|
438
|
-
// continue normal data insertion
|
|
439
448
|
}
|
|
440
449
|
}
|
|
441
450
|
insertData(data);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.js","sources":["../../../../../../../../admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Field, Flex, Popover } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport {\n BaseEditor,\n Editor,\n Element,\n Path,\n Point,\n Range,\n Transforms,\n Element as SlateElement,\n Node,\n} from 'slate';\nimport { type RenderElementProps, ReactEditor } from 'slate-react';\nimport { styled } from 'styled-components';\n\nimport { type BlocksStore, useBlocksEditorContext } from '../BlocksEditor';\nimport { type Block } from '../utils/types';\n\nimport type { Schema } from '@strapi/types';\n\nconst isLinkNode = (element: Element): element is Schema.Attribute.LinkInlineNode => {\n return element.type === 'link';\n};\n\nconst removeLink = (editor: Editor) => {\n Transforms.unwrapNodes(editor, {\n match: (node) => !Editor.isEditor(node) && SlateElement.isElement(node) && node.type === 'link',\n });\n};\n\nconst insertLink = (editor: Editor, { url }: { url: string }) => {\n if (editor.selection) {\n // We want to remove all link on the selection\n const linkNodes = Array.from(\n Editor.nodes(editor, {\n at: editor.selection,\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n })\n );\n\n linkNodes.forEach(([, path]) => {\n Transforms.unwrapNodes(editor, { at: path });\n });\n\n if (Range.isCollapsed(editor.selection)) {\n const link: Block<'link'> = {\n type: 'link',\n url: url ?? '',\n children: [{ type: 'text', text: url }],\n rel: '',\n target: '',\n };\n\n Transforms.insertNodes(editor, link);\n } else {\n Transforms.wrapNodes(editor, { type: 'link', url: url ?? '' } as Block<'link'>, {\n split: true,\n });\n }\n }\n};\n\nconst editLink = (\n editor: Editor,\n link: { url: string; text: string; rel: string; target: string }\n) => {\n const { url, text, rel, target } = link;\n\n if (!editor.selection) {\n return;\n }\n\n const linkEntry = Editor.above(editor, {\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n });\n\n if (linkEntry) {\n const [, linkPath] = linkEntry;\n Transforms.setNodes(editor, { url, rel, target }, { at: linkPath });\n\n // If link text is different, we remove the old text and insert the new one\n if (text !== '' && text !== Editor.string(editor, linkPath)) {\n const linkNodeChildrens = Array.from(Node.children(editor, linkPath, { reverse: true }));\n\n linkNodeChildrens.forEach(([, childPath]) => {\n Transforms.removeNodes(editor, { at: childPath });\n });\n\n Transforms.insertNodes(editor, [{ type: 'text', text }], { at: linkPath.concat(0) });\n }\n }\n};\n\nconst StyledLink = styled(Box)`\n text-decoration: none;\n`;\n\nconst RemoveButton = styled(Button)<{ $visible: boolean }>`\n visibility: ${(props) => (props.$visible ? 'visible' : 'hidden')};\n`;\n\ninterface LinkContentProps extends RenderElementProps {\n link: Block<'link'>;\n}\n\nconst LinkContent = React.forwardRef<HTMLAnchorElement, LinkContentProps>(\n ({ link, children, attributes }, forwardedRef) => {\n const { formatMessage } = useIntl();\n const { editor } = useBlocksEditorContext('Link');\n const path = ReactEditor.findPath(editor, link);\n const [popoverOpen, setPopoverOpen] = React.useState(\n editor.lastInsertedLinkPath ? Path.equals(path, editor.lastInsertedLinkPath) : false\n );\n const elementText = link.children.map((child) => child.text).join('');\n const [linkText, setLinkText] = React.useState(elementText);\n const [linkUrl, setLinkUrl] = React.useState(link.url);\n const [linkRel, setLinRel] = React.useState(link.rel);\n const [linkTarget, setLinkTarget] = React.useState(link.target);\n const linkInputRef = React.useRef<HTMLInputElement>(null);\n const isLastInsertedLink = editor.lastInsertedLinkPath\n ? !Path.equals(path, editor.lastInsertedLinkPath)\n : true;\n const [isSaveDisabled, setIsSaveDisabled] = React.useState(false);\n\n const onLinkChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setIsSaveDisabled(false);\n setLinkUrl(e.target.value);\n\n try {\n // eslint-disable-next-line no-new\n new URL(\n e.target.value?.startsWith('/') ? `https://strapi.io${e.target.value}` : e.target.value\n );\n } catch {\n setIsSaveDisabled(true);\n }\n };\n\n const onLinkRelChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setIsSaveDisabled(false);\n setLinRel(e.target.value);\n };\n\n const onLinkTargetChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setIsSaveDisabled(false);\n setLinkTarget(e.target.value);\n };\n\n const handleSave: React.FormEventHandler = (e) => {\n e.stopPropagation();\n\n // If the selection is collapsed, we select the parent node because we want all the link to be replaced)\n if (editor.selection && Range.isCollapsed(editor.selection)) {\n const [, parentPath] = Editor.parent(editor, editor.selection.focus?.path);\n Transforms.select(editor, parentPath);\n }\n\n editLink(editor, { url: linkUrl, text: linkText, rel: linkRel, target: linkTarget });\n setPopoverOpen(false);\n editor.lastInsertedLinkPath = null;\n ReactEditor.focus(editor);\n };\n\n const handleClose = () => {\n if (link.url === '') {\n removeLink(editor);\n }\n\n setPopoverOpen(false);\n ReactEditor.focus(editor);\n };\n\n React.useEffect(() => {\n // Focus on the link input element when the popover opens\n if (popoverOpen) linkInputRef.current?.focus();\n }, [popoverOpen]);\n\n const inputNotDirty =\n !linkText ||\n !linkUrl ||\n (link.url &&\n link.url === linkUrl &&\n elementText &&\n elementText === linkText &&\n link.rel === linkRel &&\n link.target === linkTarget);\n\n return (\n <Popover.Root open={popoverOpen}>\n <Popover.Trigger>\n <StyledLink\n {...attributes}\n ref={forwardedRef}\n tag=\"a\"\n href={link.url}\n rel={link.rel}\n target={link.target}\n onClick={() => setPopoverOpen(true)}\n color=\"primary600\"\n >\n {children}\n </StyledLink>\n </Popover.Trigger>\n <Popover.Content onPointerDownOutside={handleClose}>\n <Flex padding={4} direction=\"column\" gap={4}>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.text',\n defaultMessage: 'Text',\n })}\n </Field.Label>\n <Field.Input\n name=\"text\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.text.placeholder',\n defaultMessage: 'Enter link text',\n })}\n value={linkText}\n onChange={(e) => {\n setLinkText(e.target.value);\n }}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link',\n defaultMessage: 'Link',\n })}\n </Field.Label>\n <Field.Input\n ref={linkInputRef}\n name=\"url\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.placeholder',\n defaultMessage: 'Paste link',\n })}\n value={linkUrl}\n onChange={onLinkChange}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link.rel',\n defaultMessage: 'Rel (optional)',\n })}\n </Field.Label>\n <Field.Input\n name=\"rel\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.rel.placeholder',\n defaultMessage: 'noopener, nofollow, noreferrer',\n })}\n value={linkRel}\n onChange={onLinkRelChange}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link.target',\n defaultMessage: 'Target (optional)',\n })}\n </Field.Label>\n <Field.Input\n name=\"target\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.target.placeholder',\n defaultMessage: '_blank, _self, _parent, _top',\n })}\n value={linkTarget}\n onChange={onLinkTargetChange}\n />\n </Flex>\n </Field.Root>\n <Flex justifyContent=\"space-between\" width={{ initial: '100%', medium: '368px' }}>\n <RemoveButton\n variant=\"danger-light\"\n onClick={() => removeLink(editor)}\n $visible={isLastInsertedLink}\n >\n {formatMessage({\n id: 'components.Blocks.popover.remove',\n defaultMessage: 'Remove',\n })}\n </RemoveButton>\n <Flex gap={2}>\n <Button variant=\"tertiary\" onClick={handleClose}>\n {formatMessage({\n id: 'global.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n <Button disabled={Boolean(inputNotDirty) || isSaveDisabled} onClick={handleSave}>\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n </Flex>\n </Flex>\n </Flex>\n </Popover.Content>\n </Popover.Root>\n );\n }\n);\n\nconst Link = React.forwardRef<HTMLAnchorElement, RenderElementProps>((props, forwardedRef) => {\n if (!isLinkNode(props.element)) {\n return null;\n }\n\n // LinkContent uses React hooks that rely on props.element being a link. If the type guard above\n // doesn't pass, those hooks would be called conditionnally, which is not allowed.\n // Hence the need for a separate component.\n return <LinkContent {...props} link={props.element} ref={forwardedRef} />;\n});\n\nconst withLinks = (editor: Editor) => {\n const { isInline, apply, insertText, insertData } = editor;\n\n // Links are inline elements, so we need to override the isInline method for slate\n editor.isInline = (element) => {\n return element.type === 'link' ? true : isInline(element);\n };\n\n // We keep a track of the last inserted link path\n // So we can show the popover on the link component if that link is the last one inserted\n editor.lastInsertedLinkPath = null;\n\n // We intercept the apply method, so everytime we insert a new link, we save its path\n editor.apply = (operation) => {\n if (operation.type === 'insert_node') {\n if (\n !Editor.isEditor(operation.node) &&\n operation.node.type === 'link' &&\n editor.shouldSaveLinkPath\n ) {\n editor.lastInsertedLinkPath = operation.path;\n }\n } else if (operation.type === 'move_node') {\n // We need to update the last inserted link path when link is moved\n // If link is the first word in the paragraph we dont need to update the path\n if (\n Path.hasPrevious(operation.path) &&\n editor.lastInsertedLinkPath &&\n editor.shouldSaveLinkPath\n ) {\n editor.lastInsertedLinkPath = Path.transform(editor.lastInsertedLinkPath, operation);\n }\n }\n\n apply(operation);\n };\n\n editor.insertText = (text) => {\n // When selection is at the end of a link and user types a space, we want to break the link\n if (editor.selection && Range.isCollapsed(editor.selection) && text === ' ') {\n const linksInSelection = Array.from(\n Editor.nodes(editor, {\n at: editor.selection,\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n })\n );\n\n const selectionIsInLink = editor.selection && linksInSelection.length > 0;\n const selectionIsAtEndOfLink =\n selectionIsInLink &&\n Point.equals(editor.selection.anchor, Editor.end(editor, linksInSelection[0][1]));\n\n if (selectionIsAtEndOfLink) {\n Transforms.insertNodes(\n editor,\n { text: ' ', type: 'text' },\n { at: Path.next(linksInSelection[0][1]), select: true }\n );\n\n return;\n }\n }\n\n insertText(text);\n };\n\n // Add data as a clickable link if its a valid URL\n editor.insertData = (data) => {\n const pastedText = data.getData('text/plain');\n\n if (pastedText) {\n try {\n // eslint-disable-next-line no-new\n new URL(pastedText);\n // Do not show link popup on copy-paste a link, so do not save its path\n editor.shouldSaveLinkPath = false;\n insertLink(editor, { url: pastedText });\n return;\n } catch {\n // continue normal data insertion\n }\n }\n\n insertData(data);\n };\n\n return editor;\n};\n\nconst linkBlocks: Pick<BlocksStore, 'link'> = {\n link: {\n renderElement: (props) => (\n <Link element={props.element} attributes={props.attributes}>\n {props.children}\n </Link>\n ),\n // No handleConvert here, links are created via the link button in the toolbar\n matchNode: (node) => node.type === 'link',\n isInBlocksSelector: false,\n plugin: withLinks,\n isDraggable: () => false,\n },\n};\n\nexport interface LinkEditor extends BaseEditor {\n lastInsertedLinkPath: Path | null;\n shouldSaveLinkPath: boolean;\n}\n\nexport { linkBlocks, insertLink };\n"],"names":["isLinkNode","element","type","removeLink","editor","Transforms","unwrapNodes","match","node","Editor","isEditor","SlateElement","isElement","insertLink","url","selection","linkNodes","Array","from","nodes","at","forEach","path","Range","isCollapsed","link","children","text","rel","target","insertNodes","wrapNodes","split","editLink","linkEntry","above","linkPath","setNodes","string","linkNodeChildrens","Node","reverse","childPath","removeNodes","concat","StyledLink","styled","Box","RemoveButton","Button","props","$visible","LinkContent","React","forwardRef","attributes","forwardedRef","formatMessage","useIntl","useBlocksEditorContext","ReactEditor","findPath","popoverOpen","setPopoverOpen","useState","lastInsertedLinkPath","Path","equals","elementText","map","child","join","linkText","setLinkText","linkUrl","setLinkUrl","linkRel","setLinRel","linkTarget","setLinkTarget","linkInputRef","useRef","isLastInsertedLink","isSaveDisabled","setIsSaveDisabled","onLinkChange","e","value","URL","startsWith","onLinkRelChange","onLinkTargetChange","handleSave","stopPropagation","parentPath","parent","focus","select","handleClose","useEffect","current","inputNotDirty","_jsxs","Popover","Root","open","_jsx","Trigger","ref","tag","href","onClick","color","Content","onPointerDownOutside","Flex","padding","direction","gap","Field","width","initial","medium","alignItems","Label","id","defaultMessage","Input","name","placeholder","onChange","justifyContent","variant","disabled","Boolean","Link","withLinks","isInline","apply","insertText","insertData","operation","shouldSaveLinkPath","hasPrevious","transform","linksInSelection","selectionIsInLink","length","selectionIsAtEndOfLink","Point","anchor","end","next","data","pastedText","getData","linkBlocks","renderElement","matchNode","isInBlocksSelector","plugin","isDraggable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Link.js","sources":["../../../../../../../../admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Field, Flex, Popover } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport {\n BaseEditor,\n Editor,\n Element,\n Path,\n Point,\n Range,\n Transforms,\n Element as SlateElement,\n Node,\n} from 'slate';\nimport { type RenderElementProps, ReactEditor } from 'slate-react';\nimport { styled } from 'styled-components';\n\nimport { type BlocksStore, useBlocksEditorContext } from '../BlocksEditor';\nimport { type Block } from '../utils/types';\n\nimport type { Schema } from '@strapi/types';\n\nconst isLinkNode = (element: Element): element is Schema.Attribute.LinkInlineNode => {\n return element.type === 'link';\n};\n\nconst ALLOWED_LINK_PROTOCOLS = new Set(['http:', 'https:', 'ftp:', 'mailto:', 'tel:']);\n\nconst isValidLink = (link: string) => {\n try {\n const url = new URL(link.startsWith('/') ? `https://strapi.io${link}` : link);\n\n return ALLOWED_LINK_PROTOCOLS.has(url.protocol);\n } catch {\n return false;\n }\n};\n\nconst isValidAbsoluteLink = (link: string) => {\n try {\n return ALLOWED_LINK_PROTOCOLS.has(new URL(link).protocol);\n } catch {\n return false;\n }\n};\n\nconst removeLink = (editor: Editor) => {\n Transforms.unwrapNodes(editor, {\n match: (node) => !Editor.isEditor(node) && SlateElement.isElement(node) && node.type === 'link',\n });\n};\n\nconst insertLink = (editor: Editor, { url }: { url: string }) => {\n if (editor.selection) {\n // We want to remove all link on the selection\n const linkNodes = Array.from(\n Editor.nodes(editor, {\n at: editor.selection,\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n })\n );\n\n linkNodes.forEach(([, path]) => {\n Transforms.unwrapNodes(editor, { at: path });\n });\n\n if (Range.isCollapsed(editor.selection)) {\n const link: Block<'link'> = {\n type: 'link',\n url: url ?? '',\n children: [{ type: 'text', text: url }],\n rel: '',\n target: '',\n };\n\n Transforms.insertNodes(editor, link);\n } else {\n Transforms.wrapNodes(editor, { type: 'link', url: url ?? '' } as Block<'link'>, {\n split: true,\n });\n }\n }\n};\n\nconst editLink = (\n editor: Editor,\n link: { url: string; text: string; rel: string; target: string }\n) => {\n const { url, text, rel, target } = link;\n\n if (!editor.selection) {\n return;\n }\n\n const linkEntry = Editor.above(editor, {\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n });\n\n if (linkEntry) {\n const [, linkPath] = linkEntry;\n Transforms.setNodes(editor, { url, rel, target }, { at: linkPath });\n\n // If link text is different, we remove the old text and insert the new one\n if (text !== '' && text !== Editor.string(editor, linkPath)) {\n const linkNodeChildrens = Array.from(Node.children(editor, linkPath, { reverse: true }));\n\n linkNodeChildrens.forEach(([, childPath]) => {\n Transforms.removeNodes(editor, { at: childPath });\n });\n\n Transforms.insertNodes(editor, [{ type: 'text', text }], { at: linkPath.concat(0) });\n }\n }\n};\n\nconst StyledLink = styled(Box)`\n text-decoration: none;\n`;\n\nconst RemoveButton = styled(Button)<{ $visible: boolean }>`\n visibility: ${(props) => (props.$visible ? 'visible' : 'hidden')};\n`;\n\ninterface LinkContentProps extends RenderElementProps {\n link: Block<'link'>;\n}\n\nconst LinkContent = React.forwardRef<HTMLAnchorElement, LinkContentProps>(\n ({ link, children, attributes }, forwardedRef) => {\n const { formatMessage } = useIntl();\n const { editor } = useBlocksEditorContext('Link');\n const path = ReactEditor.findPath(editor, link);\n const [popoverOpen, setPopoverOpen] = React.useState(\n editor.lastInsertedLinkPath ? Path.equals(path, editor.lastInsertedLinkPath) : false\n );\n const elementText = link.children.map((child) => child.text).join('');\n const [linkText, setLinkText] = React.useState(elementText);\n const [linkUrl, setLinkUrl] = React.useState(link.url);\n const [linkRel, setLinRel] = React.useState(link.rel);\n const [linkTarget, setLinkTarget] = React.useState(link.target);\n const linkInputRef = React.useRef<HTMLInputElement>(null);\n const isLastInsertedLink = editor.lastInsertedLinkPath\n ? !Path.equals(path, editor.lastInsertedLinkPath)\n : true;\n const isSaveDisabled = !isValidLink(linkUrl);\n\n const onLinkChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setLinkUrl(e.target.value);\n };\n\n const onLinkRelChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setLinRel(e.target.value);\n };\n\n const onLinkTargetChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setLinkTarget(e.target.value);\n };\n\n const handleSave: React.FormEventHandler = (e) => {\n e.stopPropagation();\n\n // If the selection is collapsed, we select the parent node because we want all the link to be replaced)\n if (editor.selection && Range.isCollapsed(editor.selection)) {\n const [, parentPath] = Editor.parent(editor, editor.selection.focus?.path);\n Transforms.select(editor, parentPath);\n }\n\n editLink(editor, { url: linkUrl, text: linkText, rel: linkRel, target: linkTarget });\n setPopoverOpen(false);\n editor.lastInsertedLinkPath = null;\n ReactEditor.focus(editor);\n };\n\n const handleClose = () => {\n if (link.url === '') {\n removeLink(editor);\n }\n\n setPopoverOpen(false);\n ReactEditor.focus(editor);\n };\n\n React.useEffect(() => {\n // Focus on the link input element when the popover opens\n if (popoverOpen) linkInputRef.current?.focus();\n }, [popoverOpen]);\n\n const inputNotDirty =\n !linkText ||\n !linkUrl ||\n (link.url &&\n link.url === linkUrl &&\n elementText &&\n elementText === linkText &&\n link.rel === linkRel &&\n link.target === linkTarget);\n\n return (\n <Popover.Root open={popoverOpen}>\n <Popover.Trigger>\n <StyledLink\n {...attributes}\n ref={forwardedRef}\n tag=\"a\"\n href={isValidLink(link.url) ? link.url : undefined}\n rel={link.rel}\n target={link.target}\n onClick={() => setPopoverOpen(true)}\n color=\"primary600\"\n >\n {children}\n </StyledLink>\n </Popover.Trigger>\n <Popover.Content onPointerDownOutside={handleClose}>\n <Flex padding={4} direction=\"column\" gap={4}>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.text',\n defaultMessage: 'Text',\n })}\n </Field.Label>\n <Field.Input\n name=\"text\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.text.placeholder',\n defaultMessage: 'Enter link text',\n })}\n value={linkText}\n onChange={(e) => {\n setLinkText(e.target.value);\n }}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link',\n defaultMessage: 'Link',\n })}\n </Field.Label>\n <Field.Input\n ref={linkInputRef}\n name=\"url\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.placeholder',\n defaultMessage: 'Paste link',\n })}\n value={linkUrl}\n onChange={onLinkChange}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link.rel',\n defaultMessage: 'Rel (optional)',\n })}\n </Field.Label>\n <Field.Input\n name=\"rel\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.rel.placeholder',\n defaultMessage: 'noopener, nofollow, noreferrer',\n })}\n value={linkRel}\n onChange={onLinkRelChange}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link.target',\n defaultMessage: 'Target (optional)',\n })}\n </Field.Label>\n <Field.Input\n name=\"target\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.target.placeholder',\n defaultMessage: '_blank, _self, _parent, _top',\n })}\n value={linkTarget}\n onChange={onLinkTargetChange}\n />\n </Flex>\n </Field.Root>\n <Flex justifyContent=\"space-between\" width={{ initial: '100%', medium: '368px' }}>\n <RemoveButton\n variant=\"danger-light\"\n onClick={() => removeLink(editor)}\n $visible={isLastInsertedLink}\n >\n {formatMessage({\n id: 'components.Blocks.popover.remove',\n defaultMessage: 'Remove',\n })}\n </RemoveButton>\n <Flex gap={2}>\n <Button variant=\"tertiary\" onClick={handleClose}>\n {formatMessage({\n id: 'global.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n <Button disabled={Boolean(inputNotDirty) || isSaveDisabled} onClick={handleSave}>\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n </Flex>\n </Flex>\n </Flex>\n </Popover.Content>\n </Popover.Root>\n );\n }\n);\n\nconst Link = React.forwardRef<HTMLAnchorElement, RenderElementProps>((props, forwardedRef) => {\n if (!isLinkNode(props.element)) {\n return null;\n }\n\n // LinkContent uses React hooks that rely on props.element being a link. If the type guard above\n // doesn't pass, those hooks would be called conditionnally, which is not allowed.\n // Hence the need for a separate component.\n return <LinkContent {...props} link={props.element} ref={forwardedRef} />;\n});\n\nconst withLinks = (editor: Editor) => {\n const { isInline, apply, insertText, insertData } = editor;\n\n // Links are inline elements, so we need to override the isInline method for slate\n editor.isInline = (element) => {\n return element.type === 'link' ? true : isInline(element);\n };\n\n // We keep a track of the last inserted link path\n // So we can show the popover on the link component if that link is the last one inserted\n editor.lastInsertedLinkPath = null;\n\n // We intercept the apply method, so everytime we insert a new link, we save its path\n editor.apply = (operation) => {\n if (operation.type === 'insert_node') {\n if (\n !Editor.isEditor(operation.node) &&\n operation.node.type === 'link' &&\n editor.shouldSaveLinkPath\n ) {\n editor.lastInsertedLinkPath = operation.path;\n }\n } else if (operation.type === 'move_node') {\n // We need to update the last inserted link path when link is moved\n // If link is the first word in the paragraph we dont need to update the path\n if (\n Path.hasPrevious(operation.path) &&\n editor.lastInsertedLinkPath &&\n editor.shouldSaveLinkPath\n ) {\n editor.lastInsertedLinkPath = Path.transform(editor.lastInsertedLinkPath, operation);\n }\n }\n\n apply(operation);\n };\n\n editor.insertText = (text) => {\n // When selection is at the end of a link and user types a space, we want to break the link\n if (editor.selection && Range.isCollapsed(editor.selection) && text === ' ') {\n const linksInSelection = Array.from(\n Editor.nodes(editor, {\n at: editor.selection,\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n })\n );\n\n const selectionIsInLink = editor.selection && linksInSelection.length > 0;\n const selectionIsAtEndOfLink =\n selectionIsInLink &&\n Point.equals(editor.selection.anchor, Editor.end(editor, linksInSelection[0][1]));\n\n if (selectionIsAtEndOfLink) {\n Transforms.insertNodes(\n editor,\n { text: ' ', type: 'text' },\n { at: Path.next(linksInSelection[0][1]), select: true }\n );\n\n return;\n }\n }\n\n insertText(text);\n };\n\n // Add data as a clickable link if its a valid URL\n editor.insertData = (data) => {\n const pastedText = data.getData('text/plain');\n\n if (pastedText) {\n if (isValidAbsoluteLink(pastedText)) {\n // Do not show link popup on copy-paste a link, so do not save its path\n editor.shouldSaveLinkPath = false;\n insertLink(editor, { url: pastedText });\n return;\n }\n }\n\n insertData(data);\n };\n\n return editor;\n};\n\nconst linkBlocks: Pick<BlocksStore, 'link'> = {\n link: {\n renderElement: (props) => (\n <Link element={props.element} attributes={props.attributes}>\n {props.children}\n </Link>\n ),\n // No handleConvert here, links are created via the link button in the toolbar\n matchNode: (node) => node.type === 'link',\n isInBlocksSelector: false,\n plugin: withLinks,\n isDraggable: () => false,\n },\n};\n\nexport interface LinkEditor extends BaseEditor {\n lastInsertedLinkPath: Path | null;\n shouldSaveLinkPath: boolean;\n}\n\nexport { linkBlocks, insertLink };\n"],"names":["isLinkNode","element","type","ALLOWED_LINK_PROTOCOLS","Set","isValidLink","link","url","URL","startsWith","has","protocol","isValidAbsoluteLink","removeLink","editor","Transforms","unwrapNodes","match","node","Editor","isEditor","SlateElement","isElement","insertLink","selection","linkNodes","Array","from","nodes","at","forEach","path","Range","isCollapsed","children","text","rel","target","insertNodes","wrapNodes","split","editLink","linkEntry","above","linkPath","setNodes","string","linkNodeChildrens","Node","reverse","childPath","removeNodes","concat","StyledLink","styled","Box","RemoveButton","Button","props","$visible","LinkContent","React","forwardRef","attributes","forwardedRef","formatMessage","useIntl","useBlocksEditorContext","ReactEditor","findPath","popoverOpen","setPopoverOpen","useState","lastInsertedLinkPath","Path","equals","elementText","map","child","join","linkText","setLinkText","linkUrl","setLinkUrl","linkRel","setLinRel","linkTarget","setLinkTarget","linkInputRef","useRef","isLastInsertedLink","isSaveDisabled","onLinkChange","e","value","onLinkRelChange","onLinkTargetChange","handleSave","stopPropagation","parentPath","parent","focus","select","handleClose","useEffect","current","inputNotDirty","_jsxs","Popover","Root","open","_jsx","Trigger","ref","tag","href","undefined","onClick","color","Content","onPointerDownOutside","Flex","padding","direction","gap","Field","width","initial","medium","alignItems","Label","id","defaultMessage","Input","name","placeholder","onChange","justifyContent","variant","disabled","Boolean","Link","withLinks","isInline","apply","insertText","insertData","operation","shouldSaveLinkPath","hasPrevious","transform","linksInSelection","selectionIsInLink","length","selectionIsAtEndOfLink","Point","anchor","end","next","data","pastedText","getData","linkBlocks","renderElement","matchNode","isInBlocksSelector","plugin","isDraggable"],"mappings":"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"}
|
|
@@ -10,6 +10,28 @@ import { useBlocksEditorContext } from '../BlocksEditor.mjs';
|
|
|
10
10
|
const isLinkNode = (element)=>{
|
|
11
11
|
return element.type === 'link';
|
|
12
12
|
};
|
|
13
|
+
const ALLOWED_LINK_PROTOCOLS = new Set([
|
|
14
|
+
'http:',
|
|
15
|
+
'https:',
|
|
16
|
+
'ftp:',
|
|
17
|
+
'mailto:',
|
|
18
|
+
'tel:'
|
|
19
|
+
]);
|
|
20
|
+
const isValidLink = (link)=>{
|
|
21
|
+
try {
|
|
22
|
+
const url = new URL(link.startsWith('/') ? `https://strapi.io${link}` : link);
|
|
23
|
+
return ALLOWED_LINK_PROTOCOLS.has(url.protocol);
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const isValidAbsoluteLink = (link)=>{
|
|
29
|
+
try {
|
|
30
|
+
return ALLOWED_LINK_PROTOCOLS.has(new URL(link).protocol);
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
13
35
|
const removeLink = (editor)=>{
|
|
14
36
|
Transforms.unwrapNodes(editor, {
|
|
15
37
|
match: (node)=>!Editor.isEditor(node) && Element.isElement(node) && node.type === 'link'
|
|
@@ -107,23 +129,14 @@ const LinkContent = /*#__PURE__*/ React.forwardRef(({ link, children, attributes
|
|
|
107
129
|
const [linkTarget, setLinkTarget] = React.useState(link.target);
|
|
108
130
|
const linkInputRef = React.useRef(null);
|
|
109
131
|
const isLastInsertedLink = editor.lastInsertedLinkPath ? !Path.equals(path, editor.lastInsertedLinkPath) : true;
|
|
110
|
-
const
|
|
132
|
+
const isSaveDisabled = !isValidLink(linkUrl);
|
|
111
133
|
const onLinkChange = (e)=>{
|
|
112
|
-
setIsSaveDisabled(false);
|
|
113
134
|
setLinkUrl(e.target.value);
|
|
114
|
-
try {
|
|
115
|
-
// eslint-disable-next-line no-new
|
|
116
|
-
new URL(e.target.value?.startsWith('/') ? `https://strapi.io${e.target.value}` : e.target.value);
|
|
117
|
-
} catch {
|
|
118
|
-
setIsSaveDisabled(true);
|
|
119
|
-
}
|
|
120
135
|
};
|
|
121
136
|
const onLinkRelChange = (e)=>{
|
|
122
|
-
setIsSaveDisabled(false);
|
|
123
137
|
setLinRel(e.target.value);
|
|
124
138
|
};
|
|
125
139
|
const onLinkTargetChange = (e)=>{
|
|
126
|
-
setIsSaveDisabled(false);
|
|
127
140
|
setLinkTarget(e.target.value);
|
|
128
141
|
};
|
|
129
142
|
const handleSave = (e)=>{
|
|
@@ -165,7 +178,7 @@ const LinkContent = /*#__PURE__*/ React.forwardRef(({ link, children, attributes
|
|
|
165
178
|
...attributes,
|
|
166
179
|
ref: forwardedRef,
|
|
167
180
|
tag: "a",
|
|
168
|
-
href: link.url,
|
|
181
|
+
href: isValidLink(link.url) ? link.url : undefined,
|
|
169
182
|
rel: link.rel,
|
|
170
183
|
target: link.target,
|
|
171
184
|
onClick: ()=>setPopoverOpen(true),
|
|
@@ -403,17 +416,13 @@ const withLinks = (editor)=>{
|
|
|
403
416
|
editor.insertData = (data)=>{
|
|
404
417
|
const pastedText = data.getData('text/plain');
|
|
405
418
|
if (pastedText) {
|
|
406
|
-
|
|
407
|
-
// eslint-disable-next-line no-new
|
|
408
|
-
new URL(pastedText);
|
|
419
|
+
if (isValidAbsoluteLink(pastedText)) {
|
|
409
420
|
// Do not show link popup on copy-paste a link, so do not save its path
|
|
410
421
|
editor.shouldSaveLinkPath = false;
|
|
411
422
|
insertLink(editor, {
|
|
412
423
|
url: pastedText
|
|
413
424
|
});
|
|
414
425
|
return;
|
|
415
|
-
} catch {
|
|
416
|
-
// continue normal data insertion
|
|
417
426
|
}
|
|
418
427
|
}
|
|
419
428
|
insertData(data);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.mjs","sources":["../../../../../../../../admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Field, Flex, Popover } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport {\n BaseEditor,\n Editor,\n Element,\n Path,\n Point,\n Range,\n Transforms,\n Element as SlateElement,\n Node,\n} from 'slate';\nimport { type RenderElementProps, ReactEditor } from 'slate-react';\nimport { styled } from 'styled-components';\n\nimport { type BlocksStore, useBlocksEditorContext } from '../BlocksEditor';\nimport { type Block } from '../utils/types';\n\nimport type { Schema } from '@strapi/types';\n\nconst isLinkNode = (element: Element): element is Schema.Attribute.LinkInlineNode => {\n return element.type === 'link';\n};\n\nconst removeLink = (editor: Editor) => {\n Transforms.unwrapNodes(editor, {\n match: (node) => !Editor.isEditor(node) && SlateElement.isElement(node) && node.type === 'link',\n });\n};\n\nconst insertLink = (editor: Editor, { url }: { url: string }) => {\n if (editor.selection) {\n // We want to remove all link on the selection\n const linkNodes = Array.from(\n Editor.nodes(editor, {\n at: editor.selection,\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n })\n );\n\n linkNodes.forEach(([, path]) => {\n Transforms.unwrapNodes(editor, { at: path });\n });\n\n if (Range.isCollapsed(editor.selection)) {\n const link: Block<'link'> = {\n type: 'link',\n url: url ?? '',\n children: [{ type: 'text', text: url }],\n rel: '',\n target: '',\n };\n\n Transforms.insertNodes(editor, link);\n } else {\n Transforms.wrapNodes(editor, { type: 'link', url: url ?? '' } as Block<'link'>, {\n split: true,\n });\n }\n }\n};\n\nconst editLink = (\n editor: Editor,\n link: { url: string; text: string; rel: string; target: string }\n) => {\n const { url, text, rel, target } = link;\n\n if (!editor.selection) {\n return;\n }\n\n const linkEntry = Editor.above(editor, {\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n });\n\n if (linkEntry) {\n const [, linkPath] = linkEntry;\n Transforms.setNodes(editor, { url, rel, target }, { at: linkPath });\n\n // If link text is different, we remove the old text and insert the new one\n if (text !== '' && text !== Editor.string(editor, linkPath)) {\n const linkNodeChildrens = Array.from(Node.children(editor, linkPath, { reverse: true }));\n\n linkNodeChildrens.forEach(([, childPath]) => {\n Transforms.removeNodes(editor, { at: childPath });\n });\n\n Transforms.insertNodes(editor, [{ type: 'text', text }], { at: linkPath.concat(0) });\n }\n }\n};\n\nconst StyledLink = styled(Box)`\n text-decoration: none;\n`;\n\nconst RemoveButton = styled(Button)<{ $visible: boolean }>`\n visibility: ${(props) => (props.$visible ? 'visible' : 'hidden')};\n`;\n\ninterface LinkContentProps extends RenderElementProps {\n link: Block<'link'>;\n}\n\nconst LinkContent = React.forwardRef<HTMLAnchorElement, LinkContentProps>(\n ({ link, children, attributes }, forwardedRef) => {\n const { formatMessage } = useIntl();\n const { editor } = useBlocksEditorContext('Link');\n const path = ReactEditor.findPath(editor, link);\n const [popoverOpen, setPopoverOpen] = React.useState(\n editor.lastInsertedLinkPath ? Path.equals(path, editor.lastInsertedLinkPath) : false\n );\n const elementText = link.children.map((child) => child.text).join('');\n const [linkText, setLinkText] = React.useState(elementText);\n const [linkUrl, setLinkUrl] = React.useState(link.url);\n const [linkRel, setLinRel] = React.useState(link.rel);\n const [linkTarget, setLinkTarget] = React.useState(link.target);\n const linkInputRef = React.useRef<HTMLInputElement>(null);\n const isLastInsertedLink = editor.lastInsertedLinkPath\n ? !Path.equals(path, editor.lastInsertedLinkPath)\n : true;\n const [isSaveDisabled, setIsSaveDisabled] = React.useState(false);\n\n const onLinkChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setIsSaveDisabled(false);\n setLinkUrl(e.target.value);\n\n try {\n // eslint-disable-next-line no-new\n new URL(\n e.target.value?.startsWith('/') ? `https://strapi.io${e.target.value}` : e.target.value\n );\n } catch {\n setIsSaveDisabled(true);\n }\n };\n\n const onLinkRelChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setIsSaveDisabled(false);\n setLinRel(e.target.value);\n };\n\n const onLinkTargetChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setIsSaveDisabled(false);\n setLinkTarget(e.target.value);\n };\n\n const handleSave: React.FormEventHandler = (e) => {\n e.stopPropagation();\n\n // If the selection is collapsed, we select the parent node because we want all the link to be replaced)\n if (editor.selection && Range.isCollapsed(editor.selection)) {\n const [, parentPath] = Editor.parent(editor, editor.selection.focus?.path);\n Transforms.select(editor, parentPath);\n }\n\n editLink(editor, { url: linkUrl, text: linkText, rel: linkRel, target: linkTarget });\n setPopoverOpen(false);\n editor.lastInsertedLinkPath = null;\n ReactEditor.focus(editor);\n };\n\n const handleClose = () => {\n if (link.url === '') {\n removeLink(editor);\n }\n\n setPopoverOpen(false);\n ReactEditor.focus(editor);\n };\n\n React.useEffect(() => {\n // Focus on the link input element when the popover opens\n if (popoverOpen) linkInputRef.current?.focus();\n }, [popoverOpen]);\n\n const inputNotDirty =\n !linkText ||\n !linkUrl ||\n (link.url &&\n link.url === linkUrl &&\n elementText &&\n elementText === linkText &&\n link.rel === linkRel &&\n link.target === linkTarget);\n\n return (\n <Popover.Root open={popoverOpen}>\n <Popover.Trigger>\n <StyledLink\n {...attributes}\n ref={forwardedRef}\n tag=\"a\"\n href={link.url}\n rel={link.rel}\n target={link.target}\n onClick={() => setPopoverOpen(true)}\n color=\"primary600\"\n >\n {children}\n </StyledLink>\n </Popover.Trigger>\n <Popover.Content onPointerDownOutside={handleClose}>\n <Flex padding={4} direction=\"column\" gap={4}>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.text',\n defaultMessage: 'Text',\n })}\n </Field.Label>\n <Field.Input\n name=\"text\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.text.placeholder',\n defaultMessage: 'Enter link text',\n })}\n value={linkText}\n onChange={(e) => {\n setLinkText(e.target.value);\n }}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link',\n defaultMessage: 'Link',\n })}\n </Field.Label>\n <Field.Input\n ref={linkInputRef}\n name=\"url\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.placeholder',\n defaultMessage: 'Paste link',\n })}\n value={linkUrl}\n onChange={onLinkChange}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link.rel',\n defaultMessage: 'Rel (optional)',\n })}\n </Field.Label>\n <Field.Input\n name=\"rel\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.rel.placeholder',\n defaultMessage: 'noopener, nofollow, noreferrer',\n })}\n value={linkRel}\n onChange={onLinkRelChange}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link.target',\n defaultMessage: 'Target (optional)',\n })}\n </Field.Label>\n <Field.Input\n name=\"target\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.target.placeholder',\n defaultMessage: '_blank, _self, _parent, _top',\n })}\n value={linkTarget}\n onChange={onLinkTargetChange}\n />\n </Flex>\n </Field.Root>\n <Flex justifyContent=\"space-between\" width={{ initial: '100%', medium: '368px' }}>\n <RemoveButton\n variant=\"danger-light\"\n onClick={() => removeLink(editor)}\n $visible={isLastInsertedLink}\n >\n {formatMessage({\n id: 'components.Blocks.popover.remove',\n defaultMessage: 'Remove',\n })}\n </RemoveButton>\n <Flex gap={2}>\n <Button variant=\"tertiary\" onClick={handleClose}>\n {formatMessage({\n id: 'global.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n <Button disabled={Boolean(inputNotDirty) || isSaveDisabled} onClick={handleSave}>\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n </Flex>\n </Flex>\n </Flex>\n </Popover.Content>\n </Popover.Root>\n );\n }\n);\n\nconst Link = React.forwardRef<HTMLAnchorElement, RenderElementProps>((props, forwardedRef) => {\n if (!isLinkNode(props.element)) {\n return null;\n }\n\n // LinkContent uses React hooks that rely on props.element being a link. If the type guard above\n // doesn't pass, those hooks would be called conditionnally, which is not allowed.\n // Hence the need for a separate component.\n return <LinkContent {...props} link={props.element} ref={forwardedRef} />;\n});\n\nconst withLinks = (editor: Editor) => {\n const { isInline, apply, insertText, insertData } = editor;\n\n // Links are inline elements, so we need to override the isInline method for slate\n editor.isInline = (element) => {\n return element.type === 'link' ? true : isInline(element);\n };\n\n // We keep a track of the last inserted link path\n // So we can show the popover on the link component if that link is the last one inserted\n editor.lastInsertedLinkPath = null;\n\n // We intercept the apply method, so everytime we insert a new link, we save its path\n editor.apply = (operation) => {\n if (operation.type === 'insert_node') {\n if (\n !Editor.isEditor(operation.node) &&\n operation.node.type === 'link' &&\n editor.shouldSaveLinkPath\n ) {\n editor.lastInsertedLinkPath = operation.path;\n }\n } else if (operation.type === 'move_node') {\n // We need to update the last inserted link path when link is moved\n // If link is the first word in the paragraph we dont need to update the path\n if (\n Path.hasPrevious(operation.path) &&\n editor.lastInsertedLinkPath &&\n editor.shouldSaveLinkPath\n ) {\n editor.lastInsertedLinkPath = Path.transform(editor.lastInsertedLinkPath, operation);\n }\n }\n\n apply(operation);\n };\n\n editor.insertText = (text) => {\n // When selection is at the end of a link and user types a space, we want to break the link\n if (editor.selection && Range.isCollapsed(editor.selection) && text === ' ') {\n const linksInSelection = Array.from(\n Editor.nodes(editor, {\n at: editor.selection,\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n })\n );\n\n const selectionIsInLink = editor.selection && linksInSelection.length > 0;\n const selectionIsAtEndOfLink =\n selectionIsInLink &&\n Point.equals(editor.selection.anchor, Editor.end(editor, linksInSelection[0][1]));\n\n if (selectionIsAtEndOfLink) {\n Transforms.insertNodes(\n editor,\n { text: ' ', type: 'text' },\n { at: Path.next(linksInSelection[0][1]), select: true }\n );\n\n return;\n }\n }\n\n insertText(text);\n };\n\n // Add data as a clickable link if its a valid URL\n editor.insertData = (data) => {\n const pastedText = data.getData('text/plain');\n\n if (pastedText) {\n try {\n // eslint-disable-next-line no-new\n new URL(pastedText);\n // Do not show link popup on copy-paste a link, so do not save its path\n editor.shouldSaveLinkPath = false;\n insertLink(editor, { url: pastedText });\n return;\n } catch {\n // continue normal data insertion\n }\n }\n\n insertData(data);\n };\n\n return editor;\n};\n\nconst linkBlocks: Pick<BlocksStore, 'link'> = {\n link: {\n renderElement: (props) => (\n <Link element={props.element} attributes={props.attributes}>\n {props.children}\n </Link>\n ),\n // No handleConvert here, links are created via the link button in the toolbar\n matchNode: (node) => node.type === 'link',\n isInBlocksSelector: false,\n plugin: withLinks,\n isDraggable: () => false,\n },\n};\n\nexport interface LinkEditor extends BaseEditor {\n lastInsertedLinkPath: Path | null;\n shouldSaveLinkPath: boolean;\n}\n\nexport { linkBlocks, insertLink };\n"],"names":["isLinkNode","element","type","removeLink","editor","Transforms","unwrapNodes","match","node","Editor","isEditor","SlateElement","isElement","insertLink","url","selection","linkNodes","Array","from","nodes","at","forEach","path","Range","isCollapsed","link","children","text","rel","target","insertNodes","wrapNodes","split","editLink","linkEntry","above","linkPath","setNodes","string","linkNodeChildrens","Node","reverse","childPath","removeNodes","concat","StyledLink","styled","Box","RemoveButton","Button","props","$visible","LinkContent","React","forwardRef","attributes","forwardedRef","formatMessage","useIntl","useBlocksEditorContext","ReactEditor","findPath","popoverOpen","setPopoverOpen","useState","lastInsertedLinkPath","Path","equals","elementText","map","child","join","linkText","setLinkText","linkUrl","setLinkUrl","linkRel","setLinRel","linkTarget","setLinkTarget","linkInputRef","useRef","isLastInsertedLink","isSaveDisabled","setIsSaveDisabled","onLinkChange","e","value","URL","startsWith","onLinkRelChange","onLinkTargetChange","handleSave","stopPropagation","parentPath","parent","focus","select","handleClose","useEffect","current","inputNotDirty","_jsxs","Popover","Root","open","_jsx","Trigger","ref","tag","href","onClick","color","Content","onPointerDownOutside","Flex","padding","direction","gap","Field","width","initial","medium","alignItems","Label","id","defaultMessage","Input","name","placeholder","onChange","justifyContent","variant","disabled","Boolean","Link","withLinks","isInline","apply","insertText","insertData","operation","shouldSaveLinkPath","hasPrevious","transform","linksInSelection","selectionIsInLink","length","selectionIsAtEndOfLink","Point","anchor","end","next","data","pastedText","getData","linkBlocks","renderElement","matchNode","isInBlocksSelector","plugin","isDraggable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Link.mjs","sources":["../../../../../../../../admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Field, Flex, Popover } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport {\n BaseEditor,\n Editor,\n Element,\n Path,\n Point,\n Range,\n Transforms,\n Element as SlateElement,\n Node,\n} from 'slate';\nimport { type RenderElementProps, ReactEditor } from 'slate-react';\nimport { styled } from 'styled-components';\n\nimport { type BlocksStore, useBlocksEditorContext } from '../BlocksEditor';\nimport { type Block } from '../utils/types';\n\nimport type { Schema } from '@strapi/types';\n\nconst isLinkNode = (element: Element): element is Schema.Attribute.LinkInlineNode => {\n return element.type === 'link';\n};\n\nconst ALLOWED_LINK_PROTOCOLS = new Set(['http:', 'https:', 'ftp:', 'mailto:', 'tel:']);\n\nconst isValidLink = (link: string) => {\n try {\n const url = new URL(link.startsWith('/') ? `https://strapi.io${link}` : link);\n\n return ALLOWED_LINK_PROTOCOLS.has(url.protocol);\n } catch {\n return false;\n }\n};\n\nconst isValidAbsoluteLink = (link: string) => {\n try {\n return ALLOWED_LINK_PROTOCOLS.has(new URL(link).protocol);\n } catch {\n return false;\n }\n};\n\nconst removeLink = (editor: Editor) => {\n Transforms.unwrapNodes(editor, {\n match: (node) => !Editor.isEditor(node) && SlateElement.isElement(node) && node.type === 'link',\n });\n};\n\nconst insertLink = (editor: Editor, { url }: { url: string }) => {\n if (editor.selection) {\n // We want to remove all link on the selection\n const linkNodes = Array.from(\n Editor.nodes(editor, {\n at: editor.selection,\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n })\n );\n\n linkNodes.forEach(([, path]) => {\n Transforms.unwrapNodes(editor, { at: path });\n });\n\n if (Range.isCollapsed(editor.selection)) {\n const link: Block<'link'> = {\n type: 'link',\n url: url ?? '',\n children: [{ type: 'text', text: url }],\n rel: '',\n target: '',\n };\n\n Transforms.insertNodes(editor, link);\n } else {\n Transforms.wrapNodes(editor, { type: 'link', url: url ?? '' } as Block<'link'>, {\n split: true,\n });\n }\n }\n};\n\nconst editLink = (\n editor: Editor,\n link: { url: string; text: string; rel: string; target: string }\n) => {\n const { url, text, rel, target } = link;\n\n if (!editor.selection) {\n return;\n }\n\n const linkEntry = Editor.above(editor, {\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n });\n\n if (linkEntry) {\n const [, linkPath] = linkEntry;\n Transforms.setNodes(editor, { url, rel, target }, { at: linkPath });\n\n // If link text is different, we remove the old text and insert the new one\n if (text !== '' && text !== Editor.string(editor, linkPath)) {\n const linkNodeChildrens = Array.from(Node.children(editor, linkPath, { reverse: true }));\n\n linkNodeChildrens.forEach(([, childPath]) => {\n Transforms.removeNodes(editor, { at: childPath });\n });\n\n Transforms.insertNodes(editor, [{ type: 'text', text }], { at: linkPath.concat(0) });\n }\n }\n};\n\nconst StyledLink = styled(Box)`\n text-decoration: none;\n`;\n\nconst RemoveButton = styled(Button)<{ $visible: boolean }>`\n visibility: ${(props) => (props.$visible ? 'visible' : 'hidden')};\n`;\n\ninterface LinkContentProps extends RenderElementProps {\n link: Block<'link'>;\n}\n\nconst LinkContent = React.forwardRef<HTMLAnchorElement, LinkContentProps>(\n ({ link, children, attributes }, forwardedRef) => {\n const { formatMessage } = useIntl();\n const { editor } = useBlocksEditorContext('Link');\n const path = ReactEditor.findPath(editor, link);\n const [popoverOpen, setPopoverOpen] = React.useState(\n editor.lastInsertedLinkPath ? Path.equals(path, editor.lastInsertedLinkPath) : false\n );\n const elementText = link.children.map((child) => child.text).join('');\n const [linkText, setLinkText] = React.useState(elementText);\n const [linkUrl, setLinkUrl] = React.useState(link.url);\n const [linkRel, setLinRel] = React.useState(link.rel);\n const [linkTarget, setLinkTarget] = React.useState(link.target);\n const linkInputRef = React.useRef<HTMLInputElement>(null);\n const isLastInsertedLink = editor.lastInsertedLinkPath\n ? !Path.equals(path, editor.lastInsertedLinkPath)\n : true;\n const isSaveDisabled = !isValidLink(linkUrl);\n\n const onLinkChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setLinkUrl(e.target.value);\n };\n\n const onLinkRelChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setLinRel(e.target.value);\n };\n\n const onLinkTargetChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setLinkTarget(e.target.value);\n };\n\n const handleSave: React.FormEventHandler = (e) => {\n e.stopPropagation();\n\n // If the selection is collapsed, we select the parent node because we want all the link to be replaced)\n if (editor.selection && Range.isCollapsed(editor.selection)) {\n const [, parentPath] = Editor.parent(editor, editor.selection.focus?.path);\n Transforms.select(editor, parentPath);\n }\n\n editLink(editor, { url: linkUrl, text: linkText, rel: linkRel, target: linkTarget });\n setPopoverOpen(false);\n editor.lastInsertedLinkPath = null;\n ReactEditor.focus(editor);\n };\n\n const handleClose = () => {\n if (link.url === '') {\n removeLink(editor);\n }\n\n setPopoverOpen(false);\n ReactEditor.focus(editor);\n };\n\n React.useEffect(() => {\n // Focus on the link input element when the popover opens\n if (popoverOpen) linkInputRef.current?.focus();\n }, [popoverOpen]);\n\n const inputNotDirty =\n !linkText ||\n !linkUrl ||\n (link.url &&\n link.url === linkUrl &&\n elementText &&\n elementText === linkText &&\n link.rel === linkRel &&\n link.target === linkTarget);\n\n return (\n <Popover.Root open={popoverOpen}>\n <Popover.Trigger>\n <StyledLink\n {...attributes}\n ref={forwardedRef}\n tag=\"a\"\n href={isValidLink(link.url) ? link.url : undefined}\n rel={link.rel}\n target={link.target}\n onClick={() => setPopoverOpen(true)}\n color=\"primary600\"\n >\n {children}\n </StyledLink>\n </Popover.Trigger>\n <Popover.Content onPointerDownOutside={handleClose}>\n <Flex padding={4} direction=\"column\" gap={4}>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.text',\n defaultMessage: 'Text',\n })}\n </Field.Label>\n <Field.Input\n name=\"text\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.text.placeholder',\n defaultMessage: 'Enter link text',\n })}\n value={linkText}\n onChange={(e) => {\n setLinkText(e.target.value);\n }}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link',\n defaultMessage: 'Link',\n })}\n </Field.Label>\n <Field.Input\n ref={linkInputRef}\n name=\"url\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.placeholder',\n defaultMessage: 'Paste link',\n })}\n value={linkUrl}\n onChange={onLinkChange}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link.rel',\n defaultMessage: 'Rel (optional)',\n })}\n </Field.Label>\n <Field.Input\n name=\"rel\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.rel.placeholder',\n defaultMessage: 'noopener, nofollow, noreferrer',\n })}\n value={linkRel}\n onChange={onLinkRelChange}\n />\n </Flex>\n </Field.Root>\n <Field.Root width={{ initial: '100%', medium: '368px' }}>\n <Flex direction=\"column\" gap={1} alignItems=\"stretch\">\n <Field.Label>\n {formatMessage({\n id: 'components.Blocks.popover.link.target',\n defaultMessage: 'Target (optional)',\n })}\n </Field.Label>\n <Field.Input\n name=\"target\"\n placeholder={formatMessage({\n id: 'components.Blocks.popover.link.target.placeholder',\n defaultMessage: '_blank, _self, _parent, _top',\n })}\n value={linkTarget}\n onChange={onLinkTargetChange}\n />\n </Flex>\n </Field.Root>\n <Flex justifyContent=\"space-between\" width={{ initial: '100%', medium: '368px' }}>\n <RemoveButton\n variant=\"danger-light\"\n onClick={() => removeLink(editor)}\n $visible={isLastInsertedLink}\n >\n {formatMessage({\n id: 'components.Blocks.popover.remove',\n defaultMessage: 'Remove',\n })}\n </RemoveButton>\n <Flex gap={2}>\n <Button variant=\"tertiary\" onClick={handleClose}>\n {formatMessage({\n id: 'global.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n <Button disabled={Boolean(inputNotDirty) || isSaveDisabled} onClick={handleSave}>\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n </Flex>\n </Flex>\n </Flex>\n </Popover.Content>\n </Popover.Root>\n );\n }\n);\n\nconst Link = React.forwardRef<HTMLAnchorElement, RenderElementProps>((props, forwardedRef) => {\n if (!isLinkNode(props.element)) {\n return null;\n }\n\n // LinkContent uses React hooks that rely on props.element being a link. If the type guard above\n // doesn't pass, those hooks would be called conditionnally, which is not allowed.\n // Hence the need for a separate component.\n return <LinkContent {...props} link={props.element} ref={forwardedRef} />;\n});\n\nconst withLinks = (editor: Editor) => {\n const { isInline, apply, insertText, insertData } = editor;\n\n // Links are inline elements, so we need to override the isInline method for slate\n editor.isInline = (element) => {\n return element.type === 'link' ? true : isInline(element);\n };\n\n // We keep a track of the last inserted link path\n // So we can show the popover on the link component if that link is the last one inserted\n editor.lastInsertedLinkPath = null;\n\n // We intercept the apply method, so everytime we insert a new link, we save its path\n editor.apply = (operation) => {\n if (operation.type === 'insert_node') {\n if (\n !Editor.isEditor(operation.node) &&\n operation.node.type === 'link' &&\n editor.shouldSaveLinkPath\n ) {\n editor.lastInsertedLinkPath = operation.path;\n }\n } else if (operation.type === 'move_node') {\n // We need to update the last inserted link path when link is moved\n // If link is the first word in the paragraph we dont need to update the path\n if (\n Path.hasPrevious(operation.path) &&\n editor.lastInsertedLinkPath &&\n editor.shouldSaveLinkPath\n ) {\n editor.lastInsertedLinkPath = Path.transform(editor.lastInsertedLinkPath, operation);\n }\n }\n\n apply(operation);\n };\n\n editor.insertText = (text) => {\n // When selection is at the end of a link and user types a space, we want to break the link\n if (editor.selection && Range.isCollapsed(editor.selection) && text === ' ') {\n const linksInSelection = Array.from(\n Editor.nodes(editor, {\n at: editor.selection,\n match: (node) => !Editor.isEditor(node) && node.type === 'link',\n })\n );\n\n const selectionIsInLink = editor.selection && linksInSelection.length > 0;\n const selectionIsAtEndOfLink =\n selectionIsInLink &&\n Point.equals(editor.selection.anchor, Editor.end(editor, linksInSelection[0][1]));\n\n if (selectionIsAtEndOfLink) {\n Transforms.insertNodes(\n editor,\n { text: ' ', type: 'text' },\n { at: Path.next(linksInSelection[0][1]), select: true }\n );\n\n return;\n }\n }\n\n insertText(text);\n };\n\n // Add data as a clickable link if its a valid URL\n editor.insertData = (data) => {\n const pastedText = data.getData('text/plain');\n\n if (pastedText) {\n if (isValidAbsoluteLink(pastedText)) {\n // Do not show link popup on copy-paste a link, so do not save its path\n editor.shouldSaveLinkPath = false;\n insertLink(editor, { url: pastedText });\n return;\n }\n }\n\n insertData(data);\n };\n\n return editor;\n};\n\nconst linkBlocks: Pick<BlocksStore, 'link'> = {\n link: {\n renderElement: (props) => (\n <Link element={props.element} attributes={props.attributes}>\n {props.children}\n </Link>\n ),\n // No handleConvert here, links are created via the link button in the toolbar\n matchNode: (node) => node.type === 'link',\n isInBlocksSelector: false,\n plugin: withLinks,\n isDraggable: () => false,\n },\n};\n\nexport interface LinkEditor extends BaseEditor {\n lastInsertedLinkPath: Path | null;\n shouldSaveLinkPath: boolean;\n}\n\nexport { linkBlocks, insertLink };\n"],"names":["isLinkNode","element","type","ALLOWED_LINK_PROTOCOLS","Set","isValidLink","link","url","URL","startsWith","has","protocol","isValidAbsoluteLink","removeLink","editor","Transforms","unwrapNodes","match","node","Editor","isEditor","SlateElement","isElement","insertLink","selection","linkNodes","Array","from","nodes","at","forEach","path","Range","isCollapsed","children","text","rel","target","insertNodes","wrapNodes","split","editLink","linkEntry","above","linkPath","setNodes","string","linkNodeChildrens","Node","reverse","childPath","removeNodes","concat","StyledLink","styled","Box","RemoveButton","Button","props","$visible","LinkContent","React","forwardRef","attributes","forwardedRef","formatMessage","useIntl","useBlocksEditorContext","ReactEditor","findPath","popoverOpen","setPopoverOpen","useState","lastInsertedLinkPath","Path","equals","elementText","map","child","join","linkText","setLinkText","linkUrl","setLinkUrl","linkRel","setLinRel","linkTarget","setLinkTarget","linkInputRef","useRef","isLastInsertedLink","isSaveDisabled","onLinkChange","e","value","onLinkRelChange","onLinkTargetChange","handleSave","stopPropagation","parentPath","parent","focus","select","handleClose","useEffect","current","inputNotDirty","_jsxs","Popover","Root","open","_jsx","Trigger","ref","tag","href","undefined","onClick","color","Content","onPointerDownOutside","Flex","padding","direction","gap","Field","width","initial","medium","alignItems","Label","id","defaultMessage","Input","name","placeholder","onChange","justifyContent","variant","disabled","Boolean","Link","withLinks","isInline","apply","insertText","insertData","operation","shouldSaveLinkPath","hasPrevious","transform","linksInSelection","selectionIsInLink","length","selectionIsAtEndOfLink","Point","anchor","end","next","data","pastedText","getData","linkBlocks","renderElement","matchNode","isInBlocksSelector","plugin","isDraggable"],"mappings":"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"}
|
|
@@ -111,6 +111,10 @@ const EMPTY_RELATION_RESULTS = [];
|
|
|
111
111
|
// Use the documentId from the actual document, not the params (meta)
|
|
112
112
|
const documentId = currentDocument.document?.documentId;
|
|
113
113
|
const { formatMessage } = reactIntl.useIntl();
|
|
114
|
+
const emptyLabel = formatMessage({
|
|
115
|
+
id: 'content-manager.containers.empty-label',
|
|
116
|
+
defaultMessage: 'Untitled'
|
|
117
|
+
});
|
|
114
118
|
const isMorph = props.attribute.relation.toLowerCase().includes('morph');
|
|
115
119
|
const isDisabled = isMorph || disabled;
|
|
116
120
|
// @ts-expect-error – `targetModel` exists on supported non-morph relations (morph is disabled).
|
|
@@ -178,7 +182,8 @@ const EMPTY_RELATION_RESULTS = [];
|
|
|
178
182
|
const ctx = {
|
|
179
183
|
field: field.value,
|
|
180
184
|
href: `../${collections.COLLECTION_TYPES}/${targetModel}`,
|
|
181
|
-
mainField: props.mainField
|
|
185
|
+
mainField: props.mainField,
|
|
186
|
+
emptyLabel
|
|
182
187
|
};
|
|
183
188
|
/**
|
|
184
189
|
* Tidy up our data.
|
|
@@ -193,9 +198,11 @@ const EMPTY_RELATION_RESULTS = [];
|
|
|
193
198
|
*/ const connectItems = (field.value?.connect ?? []).map((rel)=>{
|
|
194
199
|
const urlLocaleParam = rel.locale ? `?plugins[i18n][locale]=${rel.locale}` : '';
|
|
195
200
|
if (rel.href) return rel;
|
|
201
|
+
const mainFieldValue = props.mainField ? rel[props.mainField.name] : undefined;
|
|
202
|
+
const hasEmptyMainField = mainFieldValue === '' || mainFieldValue === null;
|
|
196
203
|
return {
|
|
197
204
|
...rel,
|
|
198
|
-
label: rel.label ?? relations$1.getRelationLabel(rel, props.mainField),
|
|
205
|
+
label: hasEmptyMainField ? relations$1.getRelationLabel(rel, props.mainField, emptyLabel) : rel.label ?? relations$1.getRelationLabel(rel, props.mainField, emptyLabel),
|
|
199
206
|
href: `../${collections.COLLECTION_TYPES}/${targetModel}/${rel.documentId}${urlLocaleParam}`
|
|
200
207
|
};
|
|
201
208
|
});
|
|
@@ -214,7 +221,8 @@ const EMPTY_RELATION_RESULTS = [];
|
|
|
214
221
|
serverData,
|
|
215
222
|
field.value,
|
|
216
223
|
targetModel,
|
|
217
|
-
props.mainField
|
|
224
|
+
props.mainField,
|
|
225
|
+
emptyLabel
|
|
218
226
|
]);
|
|
219
227
|
const handleDisconnect = useHandleDisconnect(props.name, 'RelationsField');
|
|
220
228
|
const handleConnect = React__namespace.useCallback((relation)=>{
|
|
@@ -233,7 +241,7 @@ const EMPTY_RELATION_RESULTS = [];
|
|
|
233
241
|
*/ __temp_key__: fractionalIndexing.generateNKeysBetween(lastItemInList?.__temp_key__ ?? null, null, 1)[0],
|
|
234
242
|
// Fallback to `id` if there is no `mainField` value, which will overwrite the above `id` property with the exact same data.
|
|
235
243
|
[props.mainField?.name ?? 'documentId']: relation[props.mainField?.name ?? 'documentId'],
|
|
236
|
-
label: relations$1.getRelationLabel(relation, props.mainField),
|
|
244
|
+
label: relations$1.getRelationLabel(relation, props.mainField, emptyLabel),
|
|
237
245
|
href: `../${collections.COLLECTION_TYPES}/${targetModel}/${relation.documentId}?${relation.locale ? `plugins[i18n][locale]=${relation.locale}` : ''}`
|
|
238
246
|
};
|
|
239
247
|
if (ONE_WAY_RELATIONS.includes(props.attribute.relation)) {
|
|
@@ -250,6 +258,7 @@ const EMPTY_RELATION_RESULTS = [];
|
|
|
250
258
|
]);
|
|
251
259
|
}
|
|
252
260
|
}, [
|
|
261
|
+
emptyLabel,
|
|
253
262
|
field,
|
|
254
263
|
handleDisconnect,
|
|
255
264
|
onChangeRelationField,
|
|
@@ -337,12 +346,12 @@ const EMPTY_RELATION_RESULTS = [];
|
|
|
337
346
|
/**
|
|
338
347
|
* @description Adds a label and href to the relation object we use this to render
|
|
339
348
|
* a better UI where we can link to the relation and display a human-readable label.
|
|
340
|
-
*/ const addLabelAndHref = ({ mainField, href })=>(relations)=>relations.map((relation)=>{
|
|
349
|
+
*/ const addLabelAndHref = ({ mainField, href, emptyLabel })=>(relations)=>relations.map((relation)=>{
|
|
341
350
|
return {
|
|
342
351
|
...relation,
|
|
343
352
|
// Fallback to `id` if there is no `mainField` value, which will overwrite the above `documentId` property with the exact same data.
|
|
344
353
|
[mainField?.name ?? 'documentId']: relation[mainField?.name ?? 'documentId'],
|
|
345
|
-
label: relations$1.getRelationLabel(relation, mainField),
|
|
354
|
+
label: relations$1.getRelationLabel(relation, mainField, emptyLabel),
|
|
346
355
|
href: `${href}/${relation.documentId}?${relation.locale ? `plugins[i18n][locale]=${relation.locale}` : ''}`
|
|
347
356
|
};
|
|
348
357
|
});
|
|
@@ -497,6 +506,10 @@ const MemoizedRelationsComboboxInput = /*#__PURE__*/ React__namespace.memo(Relat
|
|
|
497
506
|
const RelationModalWithContext = ({ relation, name, placeholder, hasNextPage, isLoadingSearchRelations, isLoadingPermissions, handleChange, mainField, setSearchParams, fieldValue, data, ...props })=>{
|
|
498
507
|
const [textValue, setTextValue] = React__namespace.useState('');
|
|
499
508
|
const { formatMessage } = reactIntl.useIntl();
|
|
509
|
+
const emptyLabel = formatMessage({
|
|
510
|
+
id: 'content-manager.containers.empty-label',
|
|
511
|
+
defaultMessage: 'Untitled'
|
|
512
|
+
});
|
|
500
513
|
const canCreate = DocumentRBAC.useDocumentRBAC('RelationModalWrapper', (state)=>state.canCreate);
|
|
501
514
|
const fieldRef = strapiAdmin.useFocusInputField(name);
|
|
502
515
|
const componentUID = ComponentContext.useComponent('RelationsField', (state)=>state.uid);
|
|
@@ -586,7 +599,7 @@ const RelationModalWithContext = ({ relation, name, placeholder, hasNextPage, is
|
|
|
586
599
|
},
|
|
587
600
|
...props,
|
|
588
601
|
children: options?.map((opt)=>{
|
|
589
|
-
const textValue = relations$1.getRelationLabel(opt, mainField);
|
|
602
|
+
const textValue = relations$1.getRelationLabel(opt, mainField, emptyLabel);
|
|
590
603
|
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.ComboboxOption, {
|
|
591
604
|
value: opt.id.toString(),
|
|
592
605
|
textValue: textValue,
|
|
@@ -879,6 +892,10 @@ const ListItem = /*#__PURE__*/ React__namespace.memo(({ data, index, style })=>{
|
|
|
879
892
|
const { ariaDescribedBy, canDrag = false, disabled = false, handleCancel, handleDisconnect, handleDropItem, handleGrabItem, handleMoveItem, name, relations, targetModel, documentParams, mainField } = data;
|
|
880
893
|
const isDesktop = strapiAdmin.useIsDesktop();
|
|
881
894
|
const { formatMessage } = reactIntl.useIntl();
|
|
895
|
+
const emptyLabel = formatMessage({
|
|
896
|
+
id: 'content-manager.containers.empty-label',
|
|
897
|
+
defaultMessage: 'Untitled'
|
|
898
|
+
});
|
|
882
899
|
const { href, id, label: originalLabel, status: originalStatus, documentId, apiData, locale } = relations[index];
|
|
883
900
|
/**
|
|
884
901
|
* The code above attempts to retrieve the updated value of a relation that has not yet been saved.
|
|
@@ -894,7 +911,7 @@ const ListItem = /*#__PURE__*/ React__namespace.memo(({ data, index, style })=>{
|
|
|
894
911
|
}, {
|
|
895
912
|
skip: !isTemporary
|
|
896
913
|
});
|
|
897
|
-
const label = isTemporary && document ? relations$1.getRelationLabel(document, mainField) : originalLabel;
|
|
914
|
+
const label = isTemporary && document ? relations$1.getRelationLabel(document, mainField, emptyLabel) : originalLabel;
|
|
898
915
|
const status = isTemporary && document ? document?.status : originalStatus;
|
|
899
916
|
const [{ handlerId, isDragging, handleKeyDown }, relationRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop.useDragAndDrop(canDrag && !disabled, {
|
|
900
917
|
type: `${dragAndDrop.ItemTypes.RELATION}_${name}`,
|
|
@@ -918,18 +935,19 @@ const ListItem = /*#__PURE__*/ React__namespace.memo(({ data, index, style })=>{
|
|
|
918
935
|
dragPreviewRef
|
|
919
936
|
]);
|
|
920
937
|
const safeDocumentId = documentId ?? apiData?.documentId;
|
|
921
|
-
const
|
|
938
|
+
const relationLocale = locale ?? apiData?.locale;
|
|
922
939
|
const documentMeta = React__namespace.useMemo(()=>({
|
|
923
940
|
documentId: safeDocumentId,
|
|
924
941
|
model: targetModel,
|
|
925
942
|
collectionType: RelationModal.getCollectionType(href),
|
|
926
943
|
params: {
|
|
927
|
-
locale:
|
|
944
|
+
locale: relationLocale ?? documentParams?.locale ?? null
|
|
928
945
|
}
|
|
929
946
|
}), [
|
|
930
947
|
safeDocumentId,
|
|
931
948
|
href,
|
|
932
|
-
|
|
949
|
+
relationLocale,
|
|
950
|
+
documentParams,
|
|
933
951
|
targetModel
|
|
934
952
|
]);
|
|
935
953
|
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
|