@webiny/lexical-editor 6.3.0 → 6.4.0-beta.1

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 (252) hide show
  1. package/commands/image.js +2 -1
  2. package/commands/image.js.map +1 -1
  3. package/commands/index.js +0 -2
  4. package/commands/list.js +4 -3
  5. package/commands/list.js.map +1 -1
  6. package/commands/quote.js +2 -1
  7. package/commands/quote.js.map +1 -1
  8. package/commands/toolbar.js +2 -1
  9. package/commands/toolbar.js.map +1 -1
  10. package/commands/typography.js +2 -1
  11. package/commands/typography.js.map +1 -1
  12. package/components/Editor/EnsureHeadingTagPlugin.js +8 -15
  13. package/components/Editor/EnsureHeadingTagPlugin.js.map +1 -1
  14. package/components/Editor/RichTextEditor.js +82 -121
  15. package/components/Editor/RichTextEditor.js.map +1 -1
  16. package/components/Editor/normalizeInputValue.js +11 -13
  17. package/components/Editor/normalizeInputValue.js.map +1 -1
  18. package/components/LexicalEditorConfig/LexicalEditorConfig.js +24 -15
  19. package/components/LexicalEditorConfig/LexicalEditorConfig.js.map +1 -1
  20. package/components/LexicalEditorConfig/components/Node.js +21 -26
  21. package/components/LexicalEditorConfig/components/Node.js.map +1 -1
  22. package/components/LexicalEditorConfig/components/Plugin.js +21 -26
  23. package/components/LexicalEditorConfig/components/Plugin.js.map +1 -1
  24. package/components/LexicalEditorConfig/components/ToolbarElement.js +21 -26
  25. package/components/LexicalEditorConfig/components/ToolbarElement.js.map +1 -1
  26. package/components/LexicalHtmlRenderer.js +35 -40
  27. package/components/LexicalHtmlRenderer.js.map +1 -1
  28. package/components/Toolbar/StaticToolbar.js +11 -16
  29. package/components/Toolbar/StaticToolbar.js.map +1 -1
  30. package/components/ToolbarActions/BoldAction.js +16 -19
  31. package/components/ToolbarActions/BoldAction.js.map +1 -1
  32. package/components/ToolbarActions/BulletListAction.js +24 -32
  33. package/components/ToolbarActions/BulletListAction.js.map +1 -1
  34. package/components/ToolbarActions/CodeHighlightAction.js +16 -19
  35. package/components/ToolbarActions/CodeHighlightAction.js.map +1 -1
  36. package/components/ToolbarActions/FontColorAction.js +32 -38
  37. package/components/ToolbarActions/FontColorAction.js.map +1 -1
  38. package/components/ToolbarActions/ImageAction.js +28 -30
  39. package/components/ToolbarActions/ImageAction.js.map +1 -1
  40. package/components/ToolbarActions/ItalicAction.js +16 -19
  41. package/components/ToolbarActions/ItalicAction.js.map +1 -1
  42. package/components/ToolbarActions/LinkAction.js +25 -30
  43. package/components/ToolbarActions/LinkAction.js.map +1 -1
  44. package/components/ToolbarActions/NumberedListAction.js +28 -37
  45. package/components/ToolbarActions/NumberedListAction.js.map +1 -1
  46. package/components/ToolbarActions/QuoteAction.js +22 -27
  47. package/components/ToolbarActions/QuoteAction.js.map +1 -1
  48. package/components/ToolbarActions/TextAlignmentAction.js +38 -50
  49. package/components/ToolbarActions/TextAlignmentAction.js.map +1 -1
  50. package/components/ToolbarActions/TypographyAction.js +69 -99
  51. package/components/ToolbarActions/TypographyAction.js.map +1 -1
  52. package/components/ToolbarActions/UnderlineAction.js +16 -19
  53. package/components/ToolbarActions/UnderlineAction.js.map +1 -1
  54. package/context/FontColorActionContext.js +3 -2
  55. package/context/FontColorActionContext.js.map +1 -1
  56. package/context/RichTextEditorContext.js +26 -29
  57. package/context/RichTextEditorContext.js.map +1 -1
  58. package/context/SharedHistoryContext.js +11 -15
  59. package/context/SharedHistoryContext.js.map +1 -1
  60. package/context/TextAlignmentActionContextProps.js +3 -2
  61. package/context/TextAlignmentActionContextProps.js.map +1 -1
  62. package/context/TypographyActionContext.js +3 -2
  63. package/context/TypographyActionContext.js.map +1 -1
  64. package/exports/admin/lexical.js +2 -20
  65. package/hooks/index.js +0 -2
  66. package/hooks/useCurrentElement.js +18 -21
  67. package/hooks/useCurrentElement.js.map +1 -1
  68. package/hooks/useCurrentSelection.js +39 -48
  69. package/hooks/useCurrentSelection.js.map +1 -1
  70. package/hooks/useFontColorPicker.js +5 -6
  71. package/hooks/useFontColorPicker.js.map +1 -1
  72. package/hooks/useIsMounted.js +7 -8
  73. package/hooks/useIsMounted.js.map +1 -1
  74. package/hooks/useRichTextEditor.js +5 -6
  75. package/hooks/useRichTextEditor.js.map +1 -1
  76. package/hooks/useTextAlignmentAction.js +5 -6
  77. package/hooks/useTextAlignmentAction.js.map +1 -1
  78. package/hooks/useTypographyAction.js +5 -6
  79. package/hooks/useTypographyAction.js.map +1 -1
  80. package/images/icons/chat-square-quote.js +19 -0
  81. package/images/icons/chat-square-quote.js.map +1 -0
  82. package/images/icons/chevron-down.js +18 -0
  83. package/images/icons/chevron-down.js.map +1 -0
  84. package/images/icons/code.js +17 -0
  85. package/images/icons/code.js.map +1 -0
  86. package/images/icons/font-color.js +17 -0
  87. package/images/icons/font-color.js.map +1 -0
  88. package/images/icons/indent.js +18 -0
  89. package/images/icons/indent.js.map +1 -0
  90. package/images/icons/insert-image.js +20 -0
  91. package/images/icons/insert-image.js.map +1 -0
  92. package/images/icons/justify.js +19 -0
  93. package/images/icons/justify.js.map +1 -0
  94. package/images/icons/link.js +19 -0
  95. package/images/icons/link.js.map +1 -0
  96. package/images/icons/list-ol.js +20 -0
  97. package/images/icons/list-ol.js.map +1 -0
  98. package/images/icons/list-ul.js +18 -0
  99. package/images/icons/list-ul.js.map +1 -0
  100. package/images/icons/outdent.js +18 -0
  101. package/images/icons/outdent.js.map +1 -0
  102. package/images/icons/pencil-fill.js +17 -0
  103. package/images/icons/pencil-fill.js.map +1 -0
  104. package/images/icons/text-center.js +18 -0
  105. package/images/icons/text-center.js.map +1 -0
  106. package/images/icons/text-left.js +18 -0
  107. package/images/icons/text-left.js.map +1 -0
  108. package/images/icons/text-paragraph.js +18 -0
  109. package/images/icons/text-paragraph.js.map +1 -0
  110. package/images/icons/text-right.js +18 -0
  111. package/images/icons/text-right.js.map +1 -0
  112. package/images/icons/type-bold.js +17 -0
  113. package/images/icons/type-bold.js.map +1 -0
  114. package/images/icons/type-h1.js +17 -0
  115. package/images/icons/type-h1.js.map +1 -0
  116. package/images/icons/type-h2.js +17 -0
  117. package/images/icons/type-h2.js.map +1 -0
  118. package/images/icons/type-h3.js +17 -0
  119. package/images/icons/type-h3.js.map +1 -0
  120. package/images/icons/type-h4.js +17 -0
  121. package/images/icons/type-h4.js.map +1 -0
  122. package/images/icons/type-h5.js +17 -0
  123. package/images/icons/type-h5.js.map +1 -0
  124. package/images/icons/type-h6.js +17 -0
  125. package/images/icons/type-h6.js.map +1 -0
  126. package/images/icons/type-italic.js +17 -0
  127. package/images/icons/type-italic.js.map +1 -0
  128. package/images/icons/type-strikethrough.js +17 -0
  129. package/images/icons/type-strikethrough.js.map +1 -0
  130. package/images/icons/type-underline.js +17 -0
  131. package/images/icons/type-underline.js.map +1 -0
  132. package/images/icons/unlink_icon.js +27 -0
  133. package/images/icons/unlink_icon.js.map +1 -0
  134. package/index.js +5 -18
  135. package/package.json +7 -7
  136. package/plugins/BlurEventPlugin/BlurEventPlugin.js +11 -14
  137. package/plugins/BlurEventPlugin/BlurEventPlugin.js.map +1 -1
  138. package/plugins/CodeHighlightPlugin/CodeHighlightPlugin.js +7 -8
  139. package/plugins/CodeHighlightPlugin/CodeHighlightPlugin.js.map +1 -1
  140. package/plugins/CodeHighlightPlugin/index.js +0 -2
  141. package/plugins/FloatingLinkEditorPlugin/FloatingLinkEditor.js +16 -24
  142. package/plugins/FloatingLinkEditorPlugin/FloatingLinkEditor.js.map +1 -1
  143. package/plugins/FloatingLinkEditorPlugin/FloatingLinkEditorController.js +37 -51
  144. package/plugins/FloatingLinkEditorPlugin/FloatingLinkEditorController.js.map +1 -1
  145. package/plugins/FloatingLinkEditorPlugin/FloatingLinkEditorPlugin.js +6 -5
  146. package/plugins/FloatingLinkEditorPlugin/FloatingLinkEditorPlugin.js.map +1 -1
  147. package/plugins/FloatingLinkEditorPlugin/index.js +0 -2
  148. package/plugins/FloatingLinkEditorPlugin/isChildOfLinkEditor.js +6 -9
  149. package/plugins/FloatingLinkEditorPlugin/isChildOfLinkEditor.js.map +1 -1
  150. package/plugins/FloatingLinkEditorPlugin/types.js +0 -3
  151. package/plugins/FloatingLinkEditorPlugin/useFloatingLinkEditor.js +101 -108
  152. package/plugins/FloatingLinkEditorPlugin/useFloatingLinkEditor.js.map +1 -1
  153. package/plugins/FontColorPlugin/FontColorPlugin.js +14 -19
  154. package/plugins/FontColorPlugin/FontColorPlugin.js.map +1 -1
  155. package/plugins/FontColorPlugin/applyColorToNode.js +5 -4
  156. package/plugins/FontColorPlugin/applyColorToNode.js.map +1 -1
  157. package/plugins/FontColorPlugin/applyColorToSelection.js +42 -60
  158. package/plugins/FontColorPlugin/applyColorToSelection.js.map +1 -1
  159. package/plugins/ImagesPlugin/ImagesPlugin.js +79 -121
  160. package/plugins/ImagesPlugin/ImagesPlugin.js.map +1 -1
  161. package/plugins/LinkPlugin/LinkPlugin.js +46 -52
  162. package/plugins/LinkPlugin/LinkPlugin.js.map +1 -1
  163. package/plugins/ListPLugin/ListPlugin.js +44 -52
  164. package/plugins/ListPLugin/ListPlugin.js.map +1 -1
  165. package/plugins/QuoteNodePlugin/QuoteNodePlugin.js +18 -19
  166. package/plugins/QuoteNodePlugin/QuoteNodePlugin.js.map +1 -1
  167. package/plugins/StateHandlingPlugin.js +55 -64
  168. package/plugins/StateHandlingPlugin.js.map +1 -1
  169. package/plugins/TypographyPlugin/TypographyPlugin.js +13 -20
  170. package/plugins/TypographyPlugin/TypographyPlugin.js.map +1 -1
  171. package/static/svg/chat-square-quote.123cfa24.svg +1 -0
  172. package/static/svg/chevron-down.d9636921.svg +1 -0
  173. package/static/svg/code.912b1f4d.svg +1 -0
  174. package/static/svg/font-color.4f0c0de5.svg +1 -0
  175. package/static/svg/indent.4d78e483.svg +3 -0
  176. package/static/svg/insert-image.354465f1.svg +4 -0
  177. package/static/svg/justify.dab42aec.svg +3 -0
  178. package/static/svg/link.b774de25.svg +1 -0
  179. package/static/svg/list-ol.d64946f3.svg +1 -0
  180. package/static/svg/list-ul.1d54da3f.svg +1 -0
  181. package/static/svg/outdent.5c13ff16.svg +3 -0
  182. package/static/svg/pencil-fill.94cb216b.svg +1 -0
  183. package/static/svg/text-center.a411e780.svg +1 -0
  184. package/static/svg/text-left.54f41f4e.svg +1 -0
  185. package/static/svg/text-paragraph.61674422.svg +1 -0
  186. package/static/svg/text-right.9288b7a2.svg +1 -0
  187. package/static/svg/type-bold.7e3e270b.svg +1 -0
  188. package/static/svg/type-h1.f292ffe1.svg +1 -0
  189. package/static/svg/type-h2.a9d1aa48.svg +1 -0
  190. package/static/svg/type-h3.4a29ff88.svg +1 -0
  191. package/static/svg/type-h4.7f48750c.svg +1 -0
  192. package/static/svg/type-h5.14b4ac56.svg +1 -0
  193. package/static/svg/type-h6.4e9dfe2d.svg +1 -0
  194. package/static/svg/type-italic.d8e45748.svg +1 -0
  195. package/static/svg/type-strikethrough.2694a816.svg +1 -0
  196. package/static/svg/type-underline.104a0ed5.svg +1 -0
  197. package/static/svg/unlink_icon.074ceed3.svg +1 -0
  198. package/types.js +0 -8
  199. package/ui/ContentEditable.js +6 -14
  200. package/ui/ContentEditable.js.map +1 -1
  201. package/ui/Divider.js +6 -5
  202. package/ui/Divider.js.map +1 -1
  203. package/ui/DropDown.js +146 -176
  204. package/ui/DropDown.js.map +1 -1
  205. package/ui/ImageResizer.js +173 -204
  206. package/ui/ImageResizer.js.map +1 -1
  207. package/ui/LinkPreview.js +61 -84
  208. package/ui/LinkPreview.js.map +1 -1
  209. package/ui/Placeholder.js +9 -20
  210. package/ui/Placeholder.js.map +1 -1
  211. package/ui/TextInput.js +17 -30
  212. package/ui/TextInput.js.map +1 -1
  213. package/ui/ToolbarActionDialog.js +64 -73
  214. package/ui/ToolbarActionDialog.js.map +1 -1
  215. package/utils/canUseDOM.js +2 -1
  216. package/utils/canUseDOM.js.map +1 -1
  217. package/utils/files.js +9 -8
  218. package/utils/files.js.map +1 -1
  219. package/utils/getDOMRangeRect.js +10 -20
  220. package/utils/getDOMRangeRect.js.map +1 -1
  221. package/utils/getSelectedNode.js +9 -20
  222. package/utils/getSelectedNode.js.map +1 -1
  223. package/utils/getTransparentImage.js +2 -3
  224. package/utils/getTransparentImage.js.map +1 -1
  225. package/utils/insertImage.js +9 -11
  226. package/utils/insertImage.js.map +1 -1
  227. package/utils/isAnchorLink.js +2 -3
  228. package/utils/isAnchorLink.js.map +1 -1
  229. package/utils/isChildOfFloatingToolbar.js +6 -9
  230. package/utils/isChildOfFloatingToolbar.js.map +1 -1
  231. package/utils/isHTMLElement.js +3 -9
  232. package/utils/isHTMLElement.js.map +1 -1
  233. package/utils/isValidJSON.js +9 -10
  234. package/utils/isValidJSON.js.map +1 -1
  235. package/utils/isValidLexicalData.js +17 -20
  236. package/utils/isValidLexicalData.js.map +1 -1
  237. package/utils/point.js +32 -45
  238. package/utils/point.js.map +1 -1
  239. package/utils/rect.js +92 -125
  240. package/utils/rect.js.map +1 -1
  241. package/utils/sanitizeUrl.js +8 -21
  242. package/utils/sanitizeUrl.js.map +1 -1
  243. package/utils/setFloatingElemPosition.js +23 -27
  244. package/utils/setFloatingElemPosition.js.map +1 -1
  245. package/commands/index.js.map +0 -1
  246. package/exports/admin/lexical.js.map +0 -1
  247. package/hooks/index.js.map +0 -1
  248. package/index.js.map +0 -1
  249. package/plugins/CodeHighlightPlugin/index.js.map +0 -1
  250. package/plugins/FloatingLinkEditorPlugin/index.js.map +0 -1
  251. package/plugins/FloatingLinkEditorPlugin/types.js.map +0 -1
  252. package/types.js.map +0 -1
@@ -1,66 +1,48 @@
1
1
  import { TextNode } from "lexical";
2
2
  import { applyColorToNode } from "./applyColorToNode.js";
3
- export function applyColorToSelection(selection, color) {
4
- // Basic variables
5
- const textNodes = selection.getNodes().filter(node => node instanceof TextNode);
6
- const selectedTextNodesLength = textNodes.length;
7
- const startEndPoints = selection.getStartEndPoints();
8
- if (startEndPoints === null) {
9
- return;
10
- }
11
- const [anchor, focus] = startEndPoints;
12
- const lastIndex = selectedTextNodesLength - 1;
13
- const firstNode = textNodes[0];
14
- const lastNode = textNodes[lastIndex];
15
- const firstNodeText = firstNode.getTextContent();
16
- const firstNodeTextLength = firstNodeText.length;
17
- const focusOffset = focus.offset;
18
- const anchorOffset = anchor.offset;
19
- const isBefore = anchor.isBefore(focus);
20
- const startOffset = isBefore ? anchorOffset : focusOffset;
21
- const endOffset = isBefore ? focusOffset : anchorOffset;
22
-
23
- // No actual text is selected, so do nothing.
24
- if (startOffset === endOffset) {
25
- return;
26
- }
27
-
28
- // Only one node is selected.
29
- if (selectedTextNodesLength === 1) {
30
- // The entire node is selected.
31
- if (startOffset === 0 && endOffset === firstNodeTextLength) {
32
- const fontColorNode = applyColorToNode(firstNode, color);
33
- fontColorNode.select(startOffset, endOffset);
34
- return;
35
- }
36
-
37
- // The node is partially selected, so split it into two nodes and style the selected part.
38
- const splitNodes = firstNode.splitText(startOffset, endOffset);
39
- const replacement = startOffset === 0 ? splitNodes[0] : splitNodes[1];
40
- const fontColorNode = applyColorToNode(replacement, color);
41
- fontColorNode.select(0, endOffset - startOffset);
42
- return;
43
- }
44
-
45
- // Several nodes are selected.
46
- textNodes.forEach(textNode => {
47
- // First node is partially selected.
48
- if (textNode === firstNode && startOffset > 0) {
49
- const [, toColor] = textNode.splitText(startOffset);
50
- applyColorToNode(toColor, color);
51
- return;
52
- }
53
-
54
- // Last node is partially selected.
55
- if (textNode === lastNode && lastNode.getTextContent().length !== endOffset) {
56
- const [toColor] = textNode.splitText(endOffset);
57
- applyColorToNode(toColor, color);
58
- return;
3
+ function applyColorToSelection(selection, color) {
4
+ const textNodes = selection.getNodes().filter((node)=>node instanceof TextNode);
5
+ const selectedTextNodesLength = textNodes.length;
6
+ const startEndPoints = selection.getStartEndPoints();
7
+ if (null === startEndPoints) return;
8
+ const [anchor, focus] = startEndPoints;
9
+ const lastIndex = selectedTextNodesLength - 1;
10
+ const firstNode = textNodes[0];
11
+ const lastNode = textNodes[lastIndex];
12
+ const firstNodeText = firstNode.getTextContent();
13
+ const firstNodeTextLength = firstNodeText.length;
14
+ const focusOffset = focus.offset;
15
+ const anchorOffset = anchor.offset;
16
+ const isBefore = anchor.isBefore(focus);
17
+ const startOffset = isBefore ? anchorOffset : focusOffset;
18
+ const endOffset = isBefore ? focusOffset : anchorOffset;
19
+ if (startOffset === endOffset) return;
20
+ if (1 === selectedTextNodesLength) {
21
+ if (0 === startOffset && endOffset === firstNodeTextLength) {
22
+ const fontColorNode = applyColorToNode(firstNode, color);
23
+ fontColorNode.select(startOffset, endOffset);
24
+ return;
25
+ }
26
+ const splitNodes = firstNode.splitText(startOffset, endOffset);
27
+ const replacement = 0 === startOffset ? splitNodes[0] : splitNodes[1];
28
+ const fontColorNode = applyColorToNode(replacement, color);
29
+ fontColorNode.select(0, endOffset - startOffset);
30
+ return;
59
31
  }
60
-
61
- // Colorize the whole node.
62
- applyColorToNode(textNode, color);
63
- });
32
+ textNodes.forEach((textNode)=>{
33
+ if (textNode === firstNode && startOffset > 0) {
34
+ const [, toColor] = textNode.splitText(startOffset);
35
+ applyColorToNode(toColor, color);
36
+ return;
37
+ }
38
+ if (textNode === lastNode && lastNode.getTextContent().length !== endOffset) {
39
+ const [toColor] = textNode.splitText(endOffset);
40
+ applyColorToNode(toColor, color);
41
+ return;
42
+ }
43
+ applyColorToNode(textNode, color);
44
+ });
64
45
  }
46
+ export { applyColorToSelection };
65
47
 
66
48
  //# sourceMappingURL=applyColorToSelection.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["TextNode","applyColorToNode","applyColorToSelection","selection","color","textNodes","getNodes","filter","node","selectedTextNodesLength","length","startEndPoints","getStartEndPoints","anchor","focus","lastIndex","firstNode","lastNode","firstNodeText","getTextContent","firstNodeTextLength","focusOffset","offset","anchorOffset","isBefore","startOffset","endOffset","fontColorNode","select","splitNodes","splitText","replacement","forEach","textNode","toColor"],"sources":["applyColorToSelection.ts"],"sourcesContent":["import type { RangeSelection } from \"lexical\";\nimport { TextNode } from \"lexical\";\nimport type { ThemeColorValue } from \"@webiny/lexical-nodes\";\nimport { applyColorToNode } from \"~/plugins/FontColorPlugin/applyColorToNode.js\";\n\nexport function applyColorToSelection(selection: RangeSelection, color: ThemeColorValue) {\n // Basic variables\n const textNodes = selection.getNodes().filter(node => node instanceof TextNode) as TextNode[];\n\n const selectedTextNodesLength = textNodes.length;\n const startEndPoints = selection.getStartEndPoints();\n\n if (startEndPoints === null) {\n return;\n }\n\n const [anchor, focus] = startEndPoints;\n\n const lastIndex = selectedTextNodesLength - 1;\n const firstNode = textNodes[0];\n const lastNode = textNodes[lastIndex];\n const firstNodeText = firstNode.getTextContent();\n const firstNodeTextLength = firstNodeText.length;\n const focusOffset = focus.offset;\n const anchorOffset = anchor.offset;\n const isBefore = anchor.isBefore(focus);\n const startOffset = isBefore ? anchorOffset : focusOffset;\n const endOffset = isBefore ? focusOffset : anchorOffset;\n\n // No actual text is selected, so do nothing.\n if (startOffset === endOffset) {\n return;\n }\n\n // Only one node is selected.\n if (selectedTextNodesLength === 1) {\n // The entire node is selected.\n if (startOffset === 0 && endOffset === firstNodeTextLength) {\n const fontColorNode = applyColorToNode(firstNode, color);\n fontColorNode.select(startOffset, endOffset);\n return;\n }\n\n // The node is partially selected, so split it into two nodes and style the selected part.\n const splitNodes = firstNode.splitText(startOffset, endOffset);\n const replacement = startOffset === 0 ? splitNodes[0] : splitNodes[1];\n const fontColorNode = applyColorToNode(replacement, color);\n fontColorNode.select(0, endOffset - startOffset);\n\n return;\n }\n\n // Several nodes are selected.\n textNodes.forEach(textNode => {\n // First node is partially selected.\n if (textNode === firstNode && startOffset > 0) {\n const [, toColor] = textNode.splitText(startOffset);\n applyColorToNode(toColor, color);\n\n return;\n }\n\n // Last node is partially selected.\n if (textNode === lastNode && lastNode.getTextContent().length !== endOffset) {\n const [toColor] = textNode.splitText(endOffset);\n applyColorToNode(toColor, color);\n return;\n }\n\n // Colorize the whole node.\n applyColorToNode(textNode, color);\n });\n}\n"],"mappings":"AACA,SAASA,QAAQ,QAAQ,SAAS;AAElC,SAASC,gBAAgB;AAEzB,OAAO,SAASC,qBAAqBA,CAACC,SAAyB,EAAEC,KAAsB,EAAE;EACrF;EACA,MAAMC,SAAS,GAAGF,SAAS,CAACG,QAAQ,CAAC,CAAC,CAACC,MAAM,CAACC,IAAI,IAAIA,IAAI,YAAYR,QAAQ,CAAe;EAE7F,MAAMS,uBAAuB,GAAGJ,SAAS,CAACK,MAAM;EAChD,MAAMC,cAAc,GAAGR,SAAS,CAACS,iBAAiB,CAAC,CAAC;EAEpD,IAAID,cAAc,KAAK,IAAI,EAAE;IACzB;EACJ;EAEA,MAAM,CAACE,MAAM,EAAEC,KAAK,CAAC,GAAGH,cAAc;EAEtC,MAAMI,SAAS,GAAGN,uBAAuB,GAAG,CAAC;EAC7C,MAAMO,SAAS,GAAGX,SAAS,CAAC,CAAC,CAAC;EAC9B,MAAMY,QAAQ,GAAGZ,SAAS,CAACU,SAAS,CAAC;EACrC,MAAMG,aAAa,GAAGF,SAAS,CAACG,cAAc,CAAC,CAAC;EAChD,MAAMC,mBAAmB,GAAGF,aAAa,CAACR,MAAM;EAChD,MAAMW,WAAW,GAAGP,KAAK,CAACQ,MAAM;EAChC,MAAMC,YAAY,GAAGV,MAAM,CAACS,MAAM;EAClC,MAAME,QAAQ,GAAGX,MAAM,CAACW,QAAQ,CAACV,KAAK,CAAC;EACvC,MAAMW,WAAW,GAAGD,QAAQ,GAAGD,YAAY,GAAGF,WAAW;EACzD,MAAMK,SAAS,GAAGF,QAAQ,GAAGH,WAAW,GAAGE,YAAY;;EAEvD;EACA,IAAIE,WAAW,KAAKC,SAAS,EAAE;IAC3B;EACJ;;EAEA;EACA,IAAIjB,uBAAuB,KAAK,CAAC,EAAE;IAC/B;IACA,IAAIgB,WAAW,KAAK,CAAC,IAAIC,SAAS,KAAKN,mBAAmB,EAAE;MACxD,MAAMO,aAAa,GAAG1B,gBAAgB,CAACe,SAAS,EAAEZ,KAAK,CAAC;MACxDuB,aAAa,CAACC,MAAM,CAACH,WAAW,EAAEC,SAAS,CAAC;MAC5C;IACJ;;IAEA;IACA,MAAMG,UAAU,GAAGb,SAAS,CAACc,SAAS,CAACL,WAAW,EAAEC,SAAS,CAAC;IAC9D,MAAMK,WAAW,GAAGN,WAAW,KAAK,CAAC,GAAGI,UAAU,CAAC,CAAC,CAAC,GAAGA,UAAU,CAAC,CAAC,CAAC;IACrE,MAAMF,aAAa,GAAG1B,gBAAgB,CAAC8B,WAAW,EAAE3B,KAAK,CAAC;IAC1DuB,aAAa,CAACC,MAAM,CAAC,CAAC,EAAEF,SAAS,GAAGD,WAAW,CAAC;IAEhD;EACJ;;EAEA;EACApB,SAAS,CAAC2B,OAAO,CAACC,QAAQ,IAAI;IAC1B;IACA,IAAIA,QAAQ,KAAKjB,SAAS,IAAIS,WAAW,GAAG,CAAC,EAAE;MAC3C,MAAM,GAAGS,OAAO,CAAC,GAAGD,QAAQ,CAACH,SAAS,CAACL,WAAW,CAAC;MACnDxB,gBAAgB,CAACiC,OAAO,EAAE9B,KAAK,CAAC;MAEhC;IACJ;;IAEA;IACA,IAAI6B,QAAQ,KAAKhB,QAAQ,IAAIA,QAAQ,CAACE,cAAc,CAAC,CAAC,CAACT,MAAM,KAAKgB,SAAS,EAAE;MACzE,MAAM,CAACQ,OAAO,CAAC,GAAGD,QAAQ,CAACH,SAAS,CAACJ,SAAS,CAAC;MAC/CzB,gBAAgB,CAACiC,OAAO,EAAE9B,KAAK,CAAC;MAChC;IACJ;;IAEA;IACAH,gBAAgB,CAACgC,QAAQ,EAAE7B,KAAK,CAAC;EACrC,CAAC,CAAC;AACN","ignoreList":[]}
1
+ {"version":3,"file":"plugins/FontColorPlugin/applyColorToSelection.js","sources":["../../../src/plugins/FontColorPlugin/applyColorToSelection.ts"],"sourcesContent":["import type { RangeSelection } from \"lexical\";\nimport { TextNode } from \"lexical\";\nimport type { ThemeColorValue } from \"@webiny/lexical-nodes\";\nimport { applyColorToNode } from \"~/plugins/FontColorPlugin/applyColorToNode.js\";\n\nexport function applyColorToSelection(selection: RangeSelection, color: ThemeColorValue) {\n // Basic variables\n const textNodes = selection.getNodes().filter(node => node instanceof TextNode) as TextNode[];\n\n const selectedTextNodesLength = textNodes.length;\n const startEndPoints = selection.getStartEndPoints();\n\n if (startEndPoints === null) {\n return;\n }\n\n const [anchor, focus] = startEndPoints;\n\n const lastIndex = selectedTextNodesLength - 1;\n const firstNode = textNodes[0];\n const lastNode = textNodes[lastIndex];\n const firstNodeText = firstNode.getTextContent();\n const firstNodeTextLength = firstNodeText.length;\n const focusOffset = focus.offset;\n const anchorOffset = anchor.offset;\n const isBefore = anchor.isBefore(focus);\n const startOffset = isBefore ? anchorOffset : focusOffset;\n const endOffset = isBefore ? focusOffset : anchorOffset;\n\n // No actual text is selected, so do nothing.\n if (startOffset === endOffset) {\n return;\n }\n\n // Only one node is selected.\n if (selectedTextNodesLength === 1) {\n // The entire node is selected.\n if (startOffset === 0 && endOffset === firstNodeTextLength) {\n const fontColorNode = applyColorToNode(firstNode, color);\n fontColorNode.select(startOffset, endOffset);\n return;\n }\n\n // The node is partially selected, so split it into two nodes and style the selected part.\n const splitNodes = firstNode.splitText(startOffset, endOffset);\n const replacement = startOffset === 0 ? splitNodes[0] : splitNodes[1];\n const fontColorNode = applyColorToNode(replacement, color);\n fontColorNode.select(0, endOffset - startOffset);\n\n return;\n }\n\n // Several nodes are selected.\n textNodes.forEach(textNode => {\n // First node is partially selected.\n if (textNode === firstNode && startOffset > 0) {\n const [, toColor] = textNode.splitText(startOffset);\n applyColorToNode(toColor, color);\n\n return;\n }\n\n // Last node is partially selected.\n if (textNode === lastNode && lastNode.getTextContent().length !== endOffset) {\n const [toColor] = textNode.splitText(endOffset);\n applyColorToNode(toColor, color);\n return;\n }\n\n // Colorize the whole node.\n applyColorToNode(textNode, color);\n });\n}\n"],"names":["applyColorToSelection","selection","color","textNodes","node","TextNode","selectedTextNodesLength","startEndPoints","anchor","focus","lastIndex","firstNode","lastNode","firstNodeText","firstNodeTextLength","focusOffset","anchorOffset","isBefore","startOffset","endOffset","fontColorNode","applyColorToNode","splitNodes","replacement","textNode","toColor"],"mappings":";;AAKO,SAASA,sBAAsBC,SAAyB,EAAEC,KAAsB;IAEnF,MAAMC,YAAYF,UAAU,QAAQ,GAAG,MAAM,CAACG,CAAAA,OAAQA,gBAAgBC;IAEtE,MAAMC,0BAA0BH,UAAU,MAAM;IAChD,MAAMI,iBAAiBN,UAAU,iBAAiB;IAElD,IAAIM,AAAmB,SAAnBA,gBACA;IAGJ,MAAM,CAACC,QAAQC,MAAM,GAAGF;IAExB,MAAMG,YAAYJ,0BAA0B;IAC5C,MAAMK,YAAYR,SAAS,CAAC,EAAE;IAC9B,MAAMS,WAAWT,SAAS,CAACO,UAAU;IACrC,MAAMG,gBAAgBF,UAAU,cAAc;IAC9C,MAAMG,sBAAsBD,cAAc,MAAM;IAChD,MAAME,cAAcN,MAAM,MAAM;IAChC,MAAMO,eAAeR,OAAO,MAAM;IAClC,MAAMS,WAAWT,OAAO,QAAQ,CAACC;IACjC,MAAMS,cAAcD,WAAWD,eAAeD;IAC9C,MAAMI,YAAYF,WAAWF,cAAcC;IAG3C,IAAIE,gBAAgBC,WAChB;IAIJ,IAAIb,AAA4B,MAA5BA,yBAA+B;QAE/B,IAAIY,AAAgB,MAAhBA,eAAqBC,cAAcL,qBAAqB;YACxD,MAAMM,gBAAgBC,iBAAiBV,WAAWT;YAClDkB,cAAc,MAAM,CAACF,aAAaC;YAClC;QACJ;QAGA,MAAMG,aAAaX,UAAU,SAAS,CAACO,aAAaC;QACpD,MAAMI,cAAcL,AAAgB,MAAhBA,cAAoBI,UAAU,CAAC,EAAE,GAAGA,UAAU,CAAC,EAAE;QACrE,MAAMF,gBAAgBC,iBAAiBE,aAAarB;QACpDkB,cAAc,MAAM,CAAC,GAAGD,YAAYD;QAEpC;IACJ;IAGAf,UAAU,OAAO,CAACqB,CAAAA;QAEd,IAAIA,aAAab,aAAaO,cAAc,GAAG;YAC3C,MAAM,GAAGO,QAAQ,GAAGD,SAAS,SAAS,CAACN;YACvCG,iBAAiBI,SAASvB;YAE1B;QACJ;QAGA,IAAIsB,aAAaZ,YAAYA,SAAS,cAAc,GAAG,MAAM,KAAKO,WAAW;YACzE,MAAM,CAACM,QAAQ,GAAGD,SAAS,SAAS,CAACL;YACrCE,iBAAiBI,SAASvB;YAC1B;QACJ;QAGAmB,iBAAiBG,UAAUtB;IAC/B;AACJ"}
@@ -1,148 +1,106 @@
1
1
  "use client";
2
-
3
- /**
4
- * Copyright (c) Meta Platforms, Inc. and affiliates.
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE file in the root directory of this source tree.
8
- *
9
- */
10
2
  import { useEffect } from "react";
11
- import { $createRangeSelection, $getSelection, $isNodeSelection, $setSelection, mergeRegister, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_HIGH, COMMAND_PRIORITY_LOW, DRAGOVER_COMMAND, DRAGSTART_COMMAND, DROP_COMMAND } from "lexical";
3
+ import { $createRangeSelection, $getSelection, $isNodeSelection, $setSelection, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_HIGH, COMMAND_PRIORITY_LOW, DRAGOVER_COMMAND, DRAGSTART_COMMAND, DROP_COMMAND, mergeRegister } from "lexical";
12
4
  import { $isImageNode, ImageNode } from "@webiny/lexical-nodes";
13
5
  import { INSERT_IMAGE_COMMAND } from "../../commands/index.js";
14
6
  import { CAN_USE_DOM } from "../../utils/canUseDOM.js";
15
7
  import { insertImage } from "../../utils/insertImage.js";
16
8
  import { useRichTextEditor } from "../../hooks/index.js";
17
- const getDOMSelection = targetWindow => CAN_USE_DOM ? (targetWindow || window).getSelection() : null;
18
- export function ImagesPlugin({
19
- captionsEnabled
20
- }) {
21
- const {
22
- editor
23
- } = useRichTextEditor();
24
- useEffect(() => {
25
- if (!editor.hasNodes([ImageNode])) {
26
- throw new Error("ImagesPlugin: ImageNode not registered in the editor!");
27
- }
28
- return mergeRegister(editor.registerCommand(INSERT_IMAGE_COMMAND, payload => insertImage(payload), COMMAND_PRIORITY_EDITOR), editor.registerCommand(DRAGSTART_COMMAND, event => {
29
- return onDragStart(event);
30
- }, COMMAND_PRIORITY_HIGH), editor.registerCommand(DRAGOVER_COMMAND, event => {
31
- return onDragover(event);
32
- }, COMMAND_PRIORITY_LOW), editor.registerCommand(DROP_COMMAND, event => {
33
- return onDrop(event, editor);
34
- }, COMMAND_PRIORITY_HIGH));
35
- }, [captionsEnabled, editor]);
36
- return null;
9
+ const getDOMSelection = (targetWindow)=>CAN_USE_DOM ? (targetWindow || window).getSelection() : null;
10
+ function ImagesPlugin({ captionsEnabled }) {
11
+ const { editor } = useRichTextEditor();
12
+ useEffect(()=>{
13
+ if (!editor.hasNodes([
14
+ ImageNode
15
+ ])) throw new Error("ImagesPlugin: ImageNode not registered in the editor!");
16
+ return mergeRegister(editor.registerCommand(INSERT_IMAGE_COMMAND, (payload)=>insertImage(payload), COMMAND_PRIORITY_EDITOR), editor.registerCommand(DRAGSTART_COMMAND, (event)=>onDragStart(event), COMMAND_PRIORITY_HIGH), editor.registerCommand(DRAGOVER_COMMAND, (event)=>onDragover(event), COMMAND_PRIORITY_LOW), editor.registerCommand(DROP_COMMAND, (event)=>onDrop(event, editor), COMMAND_PRIORITY_HIGH));
17
+ }, [
18
+ captionsEnabled,
19
+ editor
20
+ ]);
21
+ return null;
37
22
  }
38
23
  function getDragImage() {
39
- if (!document) {
40
- return undefined;
41
- }
42
- const TRANSPARENT_IMAGE = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
43
- const img = document.createElement("img");
44
- img.src = TRANSPARENT_IMAGE;
45
- return img;
24
+ if (!document) return;
25
+ const TRANSPARENT_IMAGE = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
26
+ const img = document.createElement("img");
27
+ img.src = TRANSPARENT_IMAGE;
28
+ return img;
46
29
  }
47
30
  function onDragStart(event) {
48
- const node = getImageNodeInSelection();
49
- if (!node) {
50
- return false;
51
- }
52
- const dataTransfer = event.dataTransfer;
53
- const dragImage = getDragImage();
54
- if (!dataTransfer || !dragImage) {
55
- return false;
56
- }
57
- dataTransfer.setData("text/plain", "_");
58
- dataTransfer.setDragImage(dragImage, 0, 0);
59
- dataTransfer.setData("application/x-lexical-drag", JSON.stringify({
60
- data: {
61
- id: node.__id,
62
- altText: node.__altText,
63
- height: node.__height,
64
- key: node.getKey(),
65
- maxWidth: node.__maxWidth,
66
- src: node.__src,
67
- width: node.__width
68
- },
69
- type: "image"
70
- }));
71
- return true;
31
+ const node = getImageNodeInSelection();
32
+ if (!node) return false;
33
+ const dataTransfer = event.dataTransfer;
34
+ const dragImage = getDragImage();
35
+ if (!dataTransfer || !dragImage) return false;
36
+ dataTransfer.setData("text/plain", "_");
37
+ dataTransfer.setDragImage(dragImage, 0, 0);
38
+ dataTransfer.setData("application/x-lexical-drag", JSON.stringify({
39
+ data: {
40
+ id: node.__id,
41
+ altText: node.__altText,
42
+ height: node.__height,
43
+ key: node.getKey(),
44
+ maxWidth: node.__maxWidth,
45
+ src: node.__src,
46
+ width: node.__width
47
+ },
48
+ type: "image"
49
+ }));
50
+ return true;
72
51
  }
73
52
  function onDragover(event) {
74
- const node = getImageNodeInSelection();
75
- if (!node) {
76
- return false;
77
- }
78
- if (!canDropImage(event)) {
79
- event.preventDefault();
80
- }
81
- return true;
53
+ const node = getImageNodeInSelection();
54
+ if (!node) return false;
55
+ if (!canDropImage(event)) event.preventDefault();
56
+ return true;
82
57
  }
83
58
  function onDrop(event, editor) {
84
- const node = getImageNodeInSelection();
85
- if (!node) {
86
- return false;
87
- }
88
- const data = getDragImageData(event);
89
- if (!data) {
90
- return false;
91
- }
92
- event.preventDefault();
93
- if (canDropImage(event)) {
94
- const range = getDragSelection(event);
95
- node.remove();
96
- const rangeSelection = $createRangeSelection();
97
- if (range !== null && range !== undefined) {
98
- rangeSelection.applyDOMRange(range);
59
+ const node = getImageNodeInSelection();
60
+ if (!node) return false;
61
+ const data = getDragImageData(event);
62
+ if (!data) return false;
63
+ event.preventDefault();
64
+ if (canDropImage(event)) {
65
+ const range = getDragSelection(event);
66
+ node.remove();
67
+ const rangeSelection = $createRangeSelection();
68
+ if (null != range) rangeSelection.applyDOMRange(range);
69
+ $setSelection(rangeSelection);
70
+ editor.dispatchCommand(INSERT_IMAGE_COMMAND, data);
99
71
  }
100
- $setSelection(rangeSelection);
101
- editor.dispatchCommand(INSERT_IMAGE_COMMAND, data);
102
- }
103
- return true;
72
+ return true;
104
73
  }
105
74
  function getImageNodeInSelection() {
106
- const selection = $getSelection();
107
- if (!$isNodeSelection(selection)) {
108
- return null;
109
- }
110
- const nodes = selection.getNodes();
111
- const node = nodes[0];
112
- return $isImageNode(node) ? node : null;
75
+ const selection = $getSelection();
76
+ if (!$isNodeSelection(selection)) return null;
77
+ const nodes = selection.getNodes();
78
+ const node = nodes[0];
79
+ return $isImageNode(node) ? node : null;
113
80
  }
114
81
  function getDragImageData(event) {
115
- const dragData = event.dataTransfer?.getData("application/x-lexical-drag");
116
- if (!dragData) {
117
- return null;
118
- }
119
- const {
120
- type,
121
- data
122
- } = JSON.parse(dragData);
123
- if (type !== "image") {
124
- return null;
125
- }
126
- return data;
82
+ const dragData = event.dataTransfer?.getData("application/x-lexical-drag");
83
+ if (!dragData) return null;
84
+ const { type, data } = JSON.parse(dragData);
85
+ if ("image" !== type) return null;
86
+ return data;
127
87
  }
128
88
  function canDropImage(event) {
129
- const target = event.target;
130
- return !!(target && target instanceof HTMLElement && !target.closest("code, span.editor-image") && target.parentElement && target.parentElement.closest("div.ContentEditable__root"));
89
+ const target = event.target;
90
+ return !!(target && target instanceof HTMLElement && !target.closest("code, span.editor-image") && target.parentElement && target.parentElement.closest("div.ContentEditable__root"));
131
91
  }
132
92
  function getDragSelection(event) {
133
- let range;
134
- const target = event.target;
135
- const targetWindow = target == null ? null : target.nodeType === 9 ? target.defaultView : target.ownerDocument.defaultView;
136
- const domSelection = getDOMSelection(targetWindow);
137
- if (document.caretRangeFromPoint) {
138
- range = document.caretRangeFromPoint(event.clientX, event.clientY);
139
- } else if (event.rangeParent && domSelection !== null) {
140
- domSelection.collapse(event.rangeParent, event.rangeOffset || 0);
141
- range = domSelection.getRangeAt(0);
142
- } else {
143
- throw Error(`Cannot get the selection when dragging`);
144
- }
145
- return range;
93
+ let range;
94
+ const target = event.target;
95
+ const targetWindow = null == target ? null : 9 === target.nodeType ? target.defaultView : target.ownerDocument.defaultView;
96
+ const domSelection = getDOMSelection(targetWindow);
97
+ if (document.caretRangeFromPoint) range = document.caretRangeFromPoint(event.clientX, event.clientY);
98
+ else if (event.rangeParent && null !== domSelection) {
99
+ domSelection.collapse(event.rangeParent, event.rangeOffset || 0);
100
+ range = domSelection.getRangeAt(0);
101
+ } else throw Error("Cannot get the selection when dragging");
102
+ return range;
146
103
  }
104
+ export { ImagesPlugin };
147
105
 
148
106
  //# sourceMappingURL=ImagesPlugin.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","$createRangeSelection","$getSelection","$isNodeSelection","$setSelection","mergeRegister","COMMAND_PRIORITY_EDITOR","COMMAND_PRIORITY_HIGH","COMMAND_PRIORITY_LOW","DRAGOVER_COMMAND","DRAGSTART_COMMAND","DROP_COMMAND","$isImageNode","ImageNode","INSERT_IMAGE_COMMAND","CAN_USE_DOM","insertImage","useRichTextEditor","getDOMSelection","targetWindow","window","getSelection","ImagesPlugin","captionsEnabled","editor","hasNodes","Error","registerCommand","payload","event","onDragStart","onDragover","onDrop","getDragImage","document","undefined","TRANSPARENT_IMAGE","img","createElement","src","node","getImageNodeInSelection","dataTransfer","dragImage","setData","setDragImage","JSON","stringify","data","id","__id","altText","__altText","height","__height","key","getKey","maxWidth","__maxWidth","__src","width","__width","type","canDropImage","preventDefault","getDragImageData","range","getDragSelection","remove","rangeSelection","applyDOMRange","dispatchCommand","selection","nodes","getNodes","dragData","getData","parse","target","HTMLElement","closest","parentElement","nodeType","defaultView","ownerDocument","domSelection","caretRangeFromPoint","clientX","clientY","rangeParent","collapse","rangeOffset","getRangeAt"],"sources":["ImagesPlugin.tsx"],"sourcesContent":["\"use client\";\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\nimport { useEffect } from \"react\";\nimport type { LexicalEditor } from \"lexical\";\nimport {\n $createRangeSelection,\n $getSelection,\n $isNodeSelection,\n $setSelection,\n mergeRegister,\n COMMAND_PRIORITY_EDITOR,\n COMMAND_PRIORITY_HIGH,\n COMMAND_PRIORITY_LOW,\n DRAGOVER_COMMAND,\n DRAGSTART_COMMAND,\n DROP_COMMAND\n} from \"lexical\";\nimport { $isImageNode, ImageNode } from \"@webiny/lexical-nodes\";\nimport type { ImagePayload } from \"~/commands/index.js\";\nimport { INSERT_IMAGE_COMMAND } from \"~/commands/index.js\";\nimport { CAN_USE_DOM } from \"~/utils/canUseDOM.js\";\nimport { insertImage } from \"~/utils/insertImage.js\";\nimport { useRichTextEditor } from \"~/hooks/index.js\";\n\nexport type InsertImagePayload = Readonly<ImagePayload>;\n\nconst getDOMSelection = (targetWindow: Window | null): Selection | null =>\n CAN_USE_DOM ? (targetWindow || window).getSelection() : null;\n\nexport function ImagesPlugin({\n captionsEnabled\n}: {\n captionsEnabled?: boolean;\n}): React.JSX.Element | null {\n const { editor } = useRichTextEditor();\n\n useEffect(() => {\n if (!editor.hasNodes([ImageNode])) {\n throw new Error(\"ImagesPlugin: ImageNode not registered in the editor!\");\n }\n\n return mergeRegister(\n editor.registerCommand<InsertImagePayload>(\n INSERT_IMAGE_COMMAND,\n payload => insertImage(payload),\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<DragEvent>(\n DRAGSTART_COMMAND,\n event => {\n return onDragStart(event);\n },\n COMMAND_PRIORITY_HIGH\n ),\n editor.registerCommand<DragEvent>(\n DRAGOVER_COMMAND,\n event => {\n return onDragover(event);\n },\n COMMAND_PRIORITY_LOW\n ),\n editor.registerCommand<DragEvent>(\n DROP_COMMAND,\n event => {\n return onDrop(event, editor);\n },\n COMMAND_PRIORITY_HIGH\n )\n );\n }, [captionsEnabled, editor]);\n\n return null;\n}\n\nfunction getDragImage() {\n if (!document) {\n return undefined;\n }\n\n const TRANSPARENT_IMAGE =\n \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n const img = document.createElement(\"img\");\n img.src = TRANSPARENT_IMAGE;\n return img;\n}\n\nfunction onDragStart(event: DragEvent): boolean {\n const node = getImageNodeInSelection();\n if (!node) {\n return false;\n }\n const dataTransfer = event.dataTransfer;\n const dragImage = getDragImage();\n if (!dataTransfer || !dragImage) {\n return false;\n }\n dataTransfer.setData(\"text/plain\", \"_\");\n dataTransfer.setDragImage(dragImage, 0, 0);\n dataTransfer.setData(\n \"application/x-lexical-drag\",\n JSON.stringify({\n data: {\n id: node.__id,\n altText: node.__altText,\n height: node.__height,\n key: node.getKey(),\n maxWidth: node.__maxWidth,\n src: node.__src,\n width: node.__width\n },\n type: \"image\"\n })\n );\n\n return true;\n}\n\nfunction onDragover(event: DragEvent): boolean {\n const node = getImageNodeInSelection();\n if (!node) {\n return false;\n }\n if (!canDropImage(event)) {\n event.preventDefault();\n }\n return true;\n}\n\nfunction onDrop(event: DragEvent, editor: LexicalEditor): boolean {\n const node = getImageNodeInSelection();\n if (!node) {\n return false;\n }\n const data = getDragImageData(event);\n if (!data) {\n return false;\n }\n event.preventDefault();\n if (canDropImage(event)) {\n const range = getDragSelection(event);\n node.remove();\n const rangeSelection = $createRangeSelection();\n if (range !== null && range !== undefined) {\n rangeSelection.applyDOMRange(range);\n }\n $setSelection(rangeSelection);\n editor.dispatchCommand(INSERT_IMAGE_COMMAND, data);\n }\n return true;\n}\n\nfunction getImageNodeInSelection(): ImageNode | null {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) {\n return null;\n }\n const nodes = selection.getNodes();\n const node = nodes[0];\n return $isImageNode(node) ? node : null;\n}\n\nfunction getDragImageData(event: DragEvent): null | InsertImagePayload {\n const dragData = event.dataTransfer?.getData(\"application/x-lexical-drag\");\n if (!dragData) {\n return null;\n }\n const { type, data } = JSON.parse(dragData);\n if (type !== \"image\") {\n return null;\n }\n\n return data;\n}\n\ndeclare global {\n interface DragEvent {\n rangeOffset?: number;\n rangeParent?: Node;\n }\n}\n\nfunction canDropImage(event: DragEvent): boolean {\n const target = event.target;\n return !!(\n target &&\n target instanceof HTMLElement &&\n !target.closest(\"code, span.editor-image\") &&\n target.parentElement &&\n target.parentElement.closest(\"div.ContentEditable__root\")\n );\n}\n\nfunction getDragSelection(event: DragEvent): Range | null | undefined {\n let range;\n const target = event.target as null | Element | Document;\n const targetWindow =\n target == null\n ? null\n : target.nodeType === 9\n ? (target as Document).defaultView\n : (target as Element).ownerDocument.defaultView;\n const domSelection = getDOMSelection(targetWindow);\n if (document.caretRangeFromPoint) {\n range = document.caretRangeFromPoint(event.clientX, event.clientY);\n } else if (event.rangeParent && domSelection !== null) {\n domSelection.collapse(event.rangeParent, event.rangeOffset || 0);\n range = domSelection.getRangeAt(0);\n } else {\n throw Error(`Cannot get the selection when dragging`);\n }\n\n return range;\n}\n"],"mappings":"AAAA,YAAY;;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,SAAS,QAAQ,OAAO;AAEjC,SACIC,qBAAqB,EACrBC,aAAa,EACbC,gBAAgB,EAChBC,aAAa,EACbC,aAAa,EACbC,uBAAuB,EACvBC,qBAAqB,EACrBC,oBAAoB,EACpBC,gBAAgB,EAChBC,iBAAiB,EACjBC,YAAY,QACT,SAAS;AAChB,SAASC,YAAY,EAAEC,SAAS,QAAQ,uBAAuB;AAE/D,SAASC,oBAAoB;AAC7B,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,iBAAiB;AAI1B,MAAMC,eAAe,GAAIC,YAA2B,IAChDJ,WAAW,GAAG,CAACI,YAAY,IAAIC,MAAM,EAAEC,YAAY,CAAC,CAAC,GAAG,IAAI;AAEhE,OAAO,SAASC,YAAYA,CAAC;EACzBC;AAGJ,CAAC,EAA4B;EACzB,MAAM;IAAEC;EAAO,CAAC,GAAGP,iBAAiB,CAAC,CAAC;EAEtCjB,SAAS,CAAC,MAAM;IACZ,IAAI,CAACwB,MAAM,CAACC,QAAQ,CAAC,CAACZ,SAAS,CAAC,CAAC,EAAE;MAC/B,MAAM,IAAIa,KAAK,CAAC,uDAAuD,CAAC;IAC5E;IAEA,OAAOrB,aAAa,CAChBmB,MAAM,CAACG,eAAe,CAClBb,oBAAoB,EACpBc,OAAO,IAAIZ,WAAW,CAACY,OAAO,CAAC,EAC/BtB,uBACJ,CAAC,EACDkB,MAAM,CAACG,eAAe,CAClBjB,iBAAiB,EACjBmB,KAAK,IAAI;MACL,OAAOC,WAAW,CAACD,KAAK,CAAC;IAC7B,CAAC,EACDtB,qBACJ,CAAC,EACDiB,MAAM,CAACG,eAAe,CAClBlB,gBAAgB,EAChBoB,KAAK,IAAI;MACL,OAAOE,UAAU,CAACF,KAAK,CAAC;IAC5B,CAAC,EACDrB,oBACJ,CAAC,EACDgB,MAAM,CAACG,eAAe,CAClBhB,YAAY,EACZkB,KAAK,IAAI;MACL,OAAOG,MAAM,CAACH,KAAK,EAAEL,MAAM,CAAC;IAChC,CAAC,EACDjB,qBACJ,CACJ,CAAC;EACL,CAAC,EAAE,CAACgB,eAAe,EAAEC,MAAM,CAAC,CAAC;EAE7B,OAAO,IAAI;AACf;AAEA,SAASS,YAAYA,CAAA,EAAG;EACpB,IAAI,CAACC,QAAQ,EAAE;IACX,OAAOC,SAAS;EACpB;EAEA,MAAMC,iBAAiB,GACnB,gFAAgF;EACpF,MAAMC,GAAG,GAAGH,QAAQ,CAACI,aAAa,CAAC,KAAK,CAAC;EACzCD,GAAG,CAACE,GAAG,GAAGH,iBAAiB;EAC3B,OAAOC,GAAG;AACd;AAEA,SAASP,WAAWA,CAACD,KAAgB,EAAW;EAC5C,MAAMW,IAAI,GAAGC,uBAAuB,CAAC,CAAC;EACtC,IAAI,CAACD,IAAI,EAAE;IACP,OAAO,KAAK;EAChB;EACA,MAAME,YAAY,GAAGb,KAAK,CAACa,YAAY;EACvC,MAAMC,SAAS,GAAGV,YAAY,CAAC,CAAC;EAChC,IAAI,CAACS,YAAY,IAAI,CAACC,SAAS,EAAE;IAC7B,OAAO,KAAK;EAChB;EACAD,YAAY,CAACE,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC;EACvCF,YAAY,CAACG,YAAY,CAACF,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;EAC1CD,YAAY,CAACE,OAAO,CAChB,4BAA4B,EAC5BE,IAAI,CAACC,SAAS,CAAC;IACXC,IAAI,EAAE;MACFC,EAAE,EAAET,IAAI,CAACU,IAAI;MACbC,OAAO,EAAEX,IAAI,CAACY,SAAS;MACvBC,MAAM,EAAEb,IAAI,CAACc,QAAQ;MACrBC,GAAG,EAAEf,IAAI,CAACgB,MAAM,CAAC,CAAC;MAClBC,QAAQ,EAAEjB,IAAI,CAACkB,UAAU;MACzBnB,GAAG,EAAEC,IAAI,CAACmB,KAAK;MACfC,KAAK,EAAEpB,IAAI,CAACqB;IAChB,CAAC;IACDC,IAAI,EAAE;EACV,CAAC,CACL,CAAC;EAED,OAAO,IAAI;AACf;AAEA,SAAS/B,UAAUA,CAACF,KAAgB,EAAW;EAC3C,MAAMW,IAAI,GAAGC,uBAAuB,CAAC,CAAC;EACtC,IAAI,CAACD,IAAI,EAAE;IACP,OAAO,KAAK;EAChB;EACA,IAAI,CAACuB,YAAY,CAAClC,KAAK,CAAC,EAAE;IACtBA,KAAK,CAACmC,cAAc,CAAC,CAAC;EAC1B;EACA,OAAO,IAAI;AACf;AAEA,SAAShC,MAAMA,CAACH,KAAgB,EAAEL,MAAqB,EAAW;EAC9D,MAAMgB,IAAI,GAAGC,uBAAuB,CAAC,CAAC;EACtC,IAAI,CAACD,IAAI,EAAE;IACP,OAAO,KAAK;EAChB;EACA,MAAMQ,IAAI,GAAGiB,gBAAgB,CAACpC,KAAK,CAAC;EACpC,IAAI,CAACmB,IAAI,EAAE;IACP,OAAO,KAAK;EAChB;EACAnB,KAAK,CAACmC,cAAc,CAAC,CAAC;EACtB,IAAID,YAAY,CAAClC,KAAK,CAAC,EAAE;IACrB,MAAMqC,KAAK,GAAGC,gBAAgB,CAACtC,KAAK,CAAC;IACrCW,IAAI,CAAC4B,MAAM,CAAC,CAAC;IACb,MAAMC,cAAc,GAAGpE,qBAAqB,CAAC,CAAC;IAC9C,IAAIiE,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAK/B,SAAS,EAAE;MACvCkC,cAAc,CAACC,aAAa,CAACJ,KAAK,CAAC;IACvC;IACA9D,aAAa,CAACiE,cAAc,CAAC;IAC7B7C,MAAM,CAAC+C,eAAe,CAACzD,oBAAoB,EAAEkC,IAAI,CAAC;EACtD;EACA,OAAO,IAAI;AACf;AAEA,SAASP,uBAAuBA,CAAA,EAAqB;EACjD,MAAM+B,SAAS,GAAGtE,aAAa,CAAC,CAAC;EACjC,IAAI,CAACC,gBAAgB,CAACqE,SAAS,CAAC,EAAE;IAC9B,OAAO,IAAI;EACf;EACA,MAAMC,KAAK,GAAGD,SAAS,CAACE,QAAQ,CAAC,CAAC;EAClC,MAAMlC,IAAI,GAAGiC,KAAK,CAAC,CAAC,CAAC;EACrB,OAAO7D,YAAY,CAAC4B,IAAI,CAAC,GAAGA,IAAI,GAAG,IAAI;AAC3C;AAEA,SAASyB,gBAAgBA,CAACpC,KAAgB,EAA6B;EACnE,MAAM8C,QAAQ,GAAG9C,KAAK,CAACa,YAAY,EAAEkC,OAAO,CAAC,4BAA4B,CAAC;EAC1E,IAAI,CAACD,QAAQ,EAAE;IACX,OAAO,IAAI;EACf;EACA,MAAM;IAAEb,IAAI;IAAEd;EAAK,CAAC,GAAGF,IAAI,CAAC+B,KAAK,CAACF,QAAQ,CAAC;EAC3C,IAAIb,IAAI,KAAK,OAAO,EAAE;IAClB,OAAO,IAAI;EACf;EAEA,OAAOd,IAAI;AACf;AASA,SAASe,YAAYA,CAAClC,KAAgB,EAAW;EAC7C,MAAMiD,MAAM,GAAGjD,KAAK,CAACiD,MAAM;EAC3B,OAAO,CAAC,EACJA,MAAM,IACNA,MAAM,YAAYC,WAAW,IAC7B,CAACD,MAAM,CAACE,OAAO,CAAC,yBAAyB,CAAC,IAC1CF,MAAM,CAACG,aAAa,IACpBH,MAAM,CAACG,aAAa,CAACD,OAAO,CAAC,2BAA2B,CAAC,CAC5D;AACL;AAEA,SAASb,gBAAgBA,CAACtC,KAAgB,EAA4B;EAClE,IAAIqC,KAAK;EACT,MAAMY,MAAM,GAAGjD,KAAK,CAACiD,MAAmC;EACxD,MAAM3D,YAAY,GACd2D,MAAM,IAAI,IAAI,GACR,IAAI,GACJA,MAAM,CAACI,QAAQ,KAAK,CAAC,GAClBJ,MAAM,CAAcK,WAAW,GAC/BL,MAAM,CAAaM,aAAa,CAACD,WAAW;EACzD,MAAME,YAAY,GAAGnE,eAAe,CAACC,YAAY,CAAC;EAClD,IAAIe,QAAQ,CAACoD,mBAAmB,EAAE;IAC9BpB,KAAK,GAAGhC,QAAQ,CAACoD,mBAAmB,CAACzD,KAAK,CAAC0D,OAAO,EAAE1D,KAAK,CAAC2D,OAAO,CAAC;EACtE,CAAC,MAAM,IAAI3D,KAAK,CAAC4D,WAAW,IAAIJ,YAAY,KAAK,IAAI,EAAE;IACnDA,YAAY,CAACK,QAAQ,CAAC7D,KAAK,CAAC4D,WAAW,EAAE5D,KAAK,CAAC8D,WAAW,IAAI,CAAC,CAAC;IAChEzB,KAAK,GAAGmB,YAAY,CAACO,UAAU,CAAC,CAAC,CAAC;EACtC,CAAC,MAAM;IACH,MAAMlE,KAAK,CAAC,wCAAwC,CAAC;EACzD;EAEA,OAAOwC,KAAK;AAChB","ignoreList":[]}
1
+ {"version":3,"file":"plugins/ImagesPlugin/ImagesPlugin.js","sources":["../../../src/plugins/ImagesPlugin/ImagesPlugin.tsx"],"sourcesContent":["\"use client\";\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\nimport { useEffect } from \"react\";\nimport type { LexicalEditor } from \"lexical\";\nimport {\n $createRangeSelection,\n $getSelection,\n $isNodeSelection,\n $setSelection,\n mergeRegister,\n COMMAND_PRIORITY_EDITOR,\n COMMAND_PRIORITY_HIGH,\n COMMAND_PRIORITY_LOW,\n DRAGOVER_COMMAND,\n DRAGSTART_COMMAND,\n DROP_COMMAND\n} from \"lexical\";\nimport { $isImageNode, ImageNode } from \"@webiny/lexical-nodes\";\nimport type { ImagePayload } from \"~/commands/index.js\";\nimport { INSERT_IMAGE_COMMAND } from \"~/commands/index.js\";\nimport { CAN_USE_DOM } from \"~/utils/canUseDOM.js\";\nimport { insertImage } from \"~/utils/insertImage.js\";\nimport { useRichTextEditor } from \"~/hooks/index.js\";\n\nexport type InsertImagePayload = Readonly<ImagePayload>;\n\nconst getDOMSelection = (targetWindow: Window | null): Selection | null =>\n CAN_USE_DOM ? (targetWindow || window).getSelection() : null;\n\nexport function ImagesPlugin({\n captionsEnabled\n}: {\n captionsEnabled?: boolean;\n}): React.JSX.Element | null {\n const { editor } = useRichTextEditor();\n\n useEffect(() => {\n if (!editor.hasNodes([ImageNode])) {\n throw new Error(\"ImagesPlugin: ImageNode not registered in the editor!\");\n }\n\n return mergeRegister(\n editor.registerCommand<InsertImagePayload>(\n INSERT_IMAGE_COMMAND,\n payload => insertImage(payload),\n COMMAND_PRIORITY_EDITOR\n ),\n editor.registerCommand<DragEvent>(\n DRAGSTART_COMMAND,\n event => {\n return onDragStart(event);\n },\n COMMAND_PRIORITY_HIGH\n ),\n editor.registerCommand<DragEvent>(\n DRAGOVER_COMMAND,\n event => {\n return onDragover(event);\n },\n COMMAND_PRIORITY_LOW\n ),\n editor.registerCommand<DragEvent>(\n DROP_COMMAND,\n event => {\n return onDrop(event, editor);\n },\n COMMAND_PRIORITY_HIGH\n )\n );\n }, [captionsEnabled, editor]);\n\n return null;\n}\n\nfunction getDragImage() {\n if (!document) {\n return undefined;\n }\n\n const TRANSPARENT_IMAGE =\n \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n const img = document.createElement(\"img\");\n img.src = TRANSPARENT_IMAGE;\n return img;\n}\n\nfunction onDragStart(event: DragEvent): boolean {\n const node = getImageNodeInSelection();\n if (!node) {\n return false;\n }\n const dataTransfer = event.dataTransfer;\n const dragImage = getDragImage();\n if (!dataTransfer || !dragImage) {\n return false;\n }\n dataTransfer.setData(\"text/plain\", \"_\");\n dataTransfer.setDragImage(dragImage, 0, 0);\n dataTransfer.setData(\n \"application/x-lexical-drag\",\n JSON.stringify({\n data: {\n id: node.__id,\n altText: node.__altText,\n height: node.__height,\n key: node.getKey(),\n maxWidth: node.__maxWidth,\n src: node.__src,\n width: node.__width\n },\n type: \"image\"\n })\n );\n\n return true;\n}\n\nfunction onDragover(event: DragEvent): boolean {\n const node = getImageNodeInSelection();\n if (!node) {\n return false;\n }\n if (!canDropImage(event)) {\n event.preventDefault();\n }\n return true;\n}\n\nfunction onDrop(event: DragEvent, editor: LexicalEditor): boolean {\n const node = getImageNodeInSelection();\n if (!node) {\n return false;\n }\n const data = getDragImageData(event);\n if (!data) {\n return false;\n }\n event.preventDefault();\n if (canDropImage(event)) {\n const range = getDragSelection(event);\n node.remove();\n const rangeSelection = $createRangeSelection();\n if (range !== null && range !== undefined) {\n rangeSelection.applyDOMRange(range);\n }\n $setSelection(rangeSelection);\n editor.dispatchCommand(INSERT_IMAGE_COMMAND, data);\n }\n return true;\n}\n\nfunction getImageNodeInSelection(): ImageNode | null {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) {\n return null;\n }\n const nodes = selection.getNodes();\n const node = nodes[0];\n return $isImageNode(node) ? node : null;\n}\n\nfunction getDragImageData(event: DragEvent): null | InsertImagePayload {\n const dragData = event.dataTransfer?.getData(\"application/x-lexical-drag\");\n if (!dragData) {\n return null;\n }\n const { type, data } = JSON.parse(dragData);\n if (type !== \"image\") {\n return null;\n }\n\n return data;\n}\n\ndeclare global {\n interface DragEvent {\n rangeOffset?: number;\n rangeParent?: Node;\n }\n}\n\nfunction canDropImage(event: DragEvent): boolean {\n const target = event.target;\n return !!(\n target &&\n target instanceof HTMLElement &&\n !target.closest(\"code, span.editor-image\") &&\n target.parentElement &&\n target.parentElement.closest(\"div.ContentEditable__root\")\n );\n}\n\nfunction getDragSelection(event: DragEvent): Range | null | undefined {\n let range;\n const target = event.target as null | Element | Document;\n const targetWindow =\n target == null\n ? null\n : target.nodeType === 9\n ? (target as Document).defaultView\n : (target as Element).ownerDocument.defaultView;\n const domSelection = getDOMSelection(targetWindow);\n if (document.caretRangeFromPoint) {\n range = document.caretRangeFromPoint(event.clientX, event.clientY);\n } else if (event.rangeParent && domSelection !== null) {\n domSelection.collapse(event.rangeParent, event.rangeOffset || 0);\n range = domSelection.getRangeAt(0);\n } else {\n throw Error(`Cannot get the selection when dragging`);\n }\n\n return range;\n}\n"],"names":["getDOMSelection","targetWindow","CAN_USE_DOM","window","ImagesPlugin","captionsEnabled","editor","useRichTextEditor","useEffect","ImageNode","Error","mergeRegister","INSERT_IMAGE_COMMAND","payload","insertImage","COMMAND_PRIORITY_EDITOR","DRAGSTART_COMMAND","event","onDragStart","COMMAND_PRIORITY_HIGH","DRAGOVER_COMMAND","onDragover","COMMAND_PRIORITY_LOW","DROP_COMMAND","onDrop","getDragImage","document","TRANSPARENT_IMAGE","img","node","getImageNodeInSelection","dataTransfer","dragImage","JSON","canDropImage","data","getDragImageData","range","getDragSelection","rangeSelection","$createRangeSelection","$setSelection","selection","$getSelection","$isNodeSelection","nodes","$isImageNode","dragData","type","target","HTMLElement","domSelection"],"mappings":"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"}
@@ -1,58 +1,52 @@
1
1
  import { useEffect } from "react";
2
- import { $getSelection, $isElementNode, $isRangeSelection, mergeRegister, COMMAND_PRIORITY_LOW, PASTE_COMMAND } from "lexical";
2
+ import { $getSelection, $isElementNode, $isRangeSelection, COMMAND_PRIORITY_LOW, PASTE_COMMAND, mergeRegister } from "lexical";
3
3
  import { LinkNode, TOGGLE_LINK_COMMAND, toggleLink } from "@webiny/lexical-nodes";
4
4
  import { useRichTextEditor } from "../../hooks/index.js";
5
- export function LinkPlugin({
6
- validateUrl
7
- }) {
8
- const {
9
- editor
10
- } = useRichTextEditor();
11
- useEffect(() => {
12
- if (!editor.hasNodes([LinkNode])) {
13
- throw new Error("LinkPlugin: LinkNode not registered in the editor!");
14
- }
15
- const commands = [editor.registerCommand(TOGGLE_LINK_COMMAND, payload => {
16
- if (payload === null) {
17
- toggleLink(payload);
18
- return true;
19
- } else if (typeof payload === "string") {
20
- if (validateUrl === undefined || validateUrl(payload)) {
21
- toggleLink(payload);
22
- return true;
23
- }
24
- return false;
25
- } else {
26
- const {
27
- url,
28
- ...attrs
29
- } = payload;
30
- toggleLink(url, attrs);
31
- return true;
32
- }
33
- }, COMMAND_PRIORITY_LOW)];
34
- if (validateUrl !== undefined) {
35
- commands.push(editor.registerCommand(PASTE_COMMAND, event => {
36
- const selection = $getSelection();
37
- if (!$isRangeSelection(selection) || selection.isCollapsed() || !(event instanceof ClipboardEvent) || event.clipboardData == null) {
38
- return false;
39
- }
40
- const clipboardText = event.clipboardData.getData("text");
41
- if (!validateUrl(clipboardText)) {
42
- return false;
43
- }
44
- // If we select nodes that are elements then avoid applying the link.
45
- if (!selection.getNodes().some(node => $isElementNode(node))) {
46
- editor.dispatchCommand(TOGGLE_LINK_COMMAND, clipboardText);
47
- event.preventDefault();
48
- return true;
49
- }
50
- return false;
51
- }, COMMAND_PRIORITY_LOW));
52
- }
53
- return mergeRegister(...commands);
54
- }, [editor, validateUrl]);
55
- return null;
5
+ function LinkPlugin({ validateUrl }) {
6
+ const { editor } = useRichTextEditor();
7
+ useEffect(()=>{
8
+ if (!editor.hasNodes([
9
+ LinkNode
10
+ ])) throw new Error("LinkPlugin: LinkNode not registered in the editor!");
11
+ const commands = [
12
+ editor.registerCommand(TOGGLE_LINK_COMMAND, (payload)=>{
13
+ if (null === payload) {
14
+ toggleLink(payload);
15
+ return true;
16
+ }
17
+ if ("string" == typeof payload) {
18
+ if (void 0 === validateUrl || validateUrl(payload)) {
19
+ toggleLink(payload);
20
+ return true;
21
+ }
22
+ return false;
23
+ }
24
+ {
25
+ const { url, ...attrs } = payload;
26
+ toggleLink(url, attrs);
27
+ return true;
28
+ }
29
+ }, COMMAND_PRIORITY_LOW)
30
+ ];
31
+ if (void 0 !== validateUrl) commands.push(editor.registerCommand(PASTE_COMMAND, (event)=>{
32
+ const selection = $getSelection();
33
+ if (!$isRangeSelection(selection) || selection.isCollapsed() || !(event instanceof ClipboardEvent) || null == event.clipboardData) return false;
34
+ const clipboardText = event.clipboardData.getData("text");
35
+ if (!validateUrl(clipboardText)) return false;
36
+ if (!selection.getNodes().some((node)=>$isElementNode(node))) {
37
+ editor.dispatchCommand(TOGGLE_LINK_COMMAND, clipboardText);
38
+ event.preventDefault();
39
+ return true;
40
+ }
41
+ return false;
42
+ }, COMMAND_PRIORITY_LOW));
43
+ return mergeRegister(...commands);
44
+ }, [
45
+ editor,
46
+ validateUrl
47
+ ]);
48
+ return null;
56
49
  }
50
+ export { LinkPlugin };
57
51
 
58
52
  //# sourceMappingURL=LinkPlugin.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","$getSelection","$isElementNode","$isRangeSelection","mergeRegister","COMMAND_PRIORITY_LOW","PASTE_COMMAND","LinkNode","TOGGLE_LINK_COMMAND","toggleLink","useRichTextEditor","LinkPlugin","validateUrl","editor","hasNodes","Error","commands","registerCommand","payload","undefined","url","attrs","push","event","selection","isCollapsed","ClipboardEvent","clipboardData","clipboardText","getData","getNodes","some","node","dispatchCommand","preventDefault"],"sources":["LinkPlugin.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport {\n $getSelection,\n $isElementNode,\n $isRangeSelection,\n mergeRegister,\n COMMAND_PRIORITY_LOW,\n PASTE_COMMAND\n} from \"lexical\";\nimport { LinkNode, TOGGLE_LINK_COMMAND, toggleLink } from \"@webiny/lexical-nodes\";\nimport { useRichTextEditor } from \"~/hooks/index.js\";\n\ntype Props = {\n validateUrl?: (url: string) => boolean;\n};\n\nexport function LinkPlugin({ validateUrl }: Props): null {\n const { editor } = useRichTextEditor();\n\n useEffect(() => {\n if (!editor.hasNodes([LinkNode])) {\n throw new Error(\"LinkPlugin: LinkNode not registered in the editor!\");\n }\n\n const commands = [\n editor.registerCommand(\n TOGGLE_LINK_COMMAND,\n payload => {\n if (payload === null) {\n toggleLink(payload);\n return true;\n } else if (typeof payload === \"string\") {\n if (validateUrl === undefined || validateUrl(payload)) {\n toggleLink(payload);\n return true;\n }\n return false;\n } else {\n const { url, ...attrs } = payload;\n toggleLink(url, attrs);\n return true;\n }\n },\n COMMAND_PRIORITY_LOW\n )\n ];\n\n if (validateUrl !== undefined) {\n commands.push(\n editor.registerCommand(\n PASTE_COMMAND,\n event => {\n const selection = $getSelection();\n if (\n !$isRangeSelection(selection) ||\n selection.isCollapsed() ||\n !(event instanceof ClipboardEvent) ||\n event.clipboardData == null\n ) {\n return false;\n }\n const clipboardText = event.clipboardData.getData(\"text\");\n if (!validateUrl(clipboardText)) {\n return false;\n }\n // If we select nodes that are elements then avoid applying the link.\n if (!selection.getNodes().some(node => $isElementNode(node))) {\n editor.dispatchCommand(TOGGLE_LINK_COMMAND, clipboardText);\n event.preventDefault();\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_LOW\n )\n );\n }\n\n return mergeRegister(...commands);\n }, [editor, validateUrl]);\n\n return null;\n}\n"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;AACjC,SACIC,aAAa,EACbC,cAAc,EACdC,iBAAiB,EACjBC,aAAa,EACbC,oBAAoB,EACpBC,aAAa,QACV,SAAS;AAChB,SAASC,QAAQ,EAAEC,mBAAmB,EAAEC,UAAU,QAAQ,uBAAuB;AACjF,SAASC,iBAAiB;AAM1B,OAAO,SAASC,UAAUA,CAAC;EAAEC;AAAmB,CAAC,EAAQ;EACrD,MAAM;IAAEC;EAAO,CAAC,GAAGH,iBAAiB,CAAC,CAAC;EAEtCV,SAAS,CAAC,MAAM;IACZ,IAAI,CAACa,MAAM,CAACC,QAAQ,CAAC,CAACP,QAAQ,CAAC,CAAC,EAAE;MAC9B,MAAM,IAAIQ,KAAK,CAAC,oDAAoD,CAAC;IACzE;IAEA,MAAMC,QAAQ,GAAG,CACbH,MAAM,CAACI,eAAe,CAClBT,mBAAmB,EACnBU,OAAO,IAAI;MACP,IAAIA,OAAO,KAAK,IAAI,EAAE;QAClBT,UAAU,CAACS,OAAO,CAAC;QACnB,OAAO,IAAI;MACf,CAAC,MAAM,IAAI,OAAOA,OAAO,KAAK,QAAQ,EAAE;QACpC,IAAIN,WAAW,KAAKO,SAAS,IAAIP,WAAW,CAACM,OAAO,CAAC,EAAE;UACnDT,UAAU,CAACS,OAAO,CAAC;UACnB,OAAO,IAAI;QACf;QACA,OAAO,KAAK;MAChB,CAAC,MAAM;QACH,MAAM;UAAEE,GAAG;UAAE,GAAGC;QAAM,CAAC,GAAGH,OAAO;QACjCT,UAAU,CAACW,GAAG,EAAEC,KAAK,CAAC;QACtB,OAAO,IAAI;MACf;IACJ,CAAC,EACDhB,oBACJ,CAAC,CACJ;IAED,IAAIO,WAAW,KAAKO,SAAS,EAAE;MAC3BH,QAAQ,CAACM,IAAI,CACTT,MAAM,CAACI,eAAe,CAClBX,aAAa,EACbiB,KAAK,IAAI;QACL,MAAMC,SAAS,GAAGvB,aAAa,CAAC,CAAC;QACjC,IACI,CAACE,iBAAiB,CAACqB,SAAS,CAAC,IAC7BA,SAAS,CAACC,WAAW,CAAC,CAAC,IACvB,EAAEF,KAAK,YAAYG,cAAc,CAAC,IAClCH,KAAK,CAACI,aAAa,IAAI,IAAI,EAC7B;UACE,OAAO,KAAK;QAChB;QACA,MAAMC,aAAa,GAAGL,KAAK,CAACI,aAAa,CAACE,OAAO,CAAC,MAAM,CAAC;QACzD,IAAI,CAACjB,WAAW,CAACgB,aAAa,CAAC,EAAE;UAC7B,OAAO,KAAK;QAChB;QACA;QACA,IAAI,CAACJ,SAAS,CAACM,QAAQ,CAAC,CAAC,CAACC,IAAI,CAACC,IAAI,IAAI9B,cAAc,CAAC8B,IAAI,CAAC,CAAC,EAAE;UAC1DnB,MAAM,CAACoB,eAAe,CAACzB,mBAAmB,EAAEoB,aAAa,CAAC;UAC1DL,KAAK,CAACW,cAAc,CAAC,CAAC;UACtB,OAAO,IAAI;QACf;QACA,OAAO,KAAK;MAChB,CAAC,EACD7B,oBACJ,CACJ,CAAC;IACL;IAEA,OAAOD,aAAa,CAAC,GAAGY,QAAQ,CAAC;EACrC,CAAC,EAAE,CAACH,MAAM,EAAED,WAAW,CAAC,CAAC;EAEzB,OAAO,IAAI;AACf","ignoreList":[]}
1
+ {"version":3,"file":"plugins/LinkPlugin/LinkPlugin.js","sources":["../../../src/plugins/LinkPlugin/LinkPlugin.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport {\n $getSelection,\n $isElementNode,\n $isRangeSelection,\n mergeRegister,\n COMMAND_PRIORITY_LOW,\n PASTE_COMMAND\n} from \"lexical\";\nimport { LinkNode, TOGGLE_LINK_COMMAND, toggleLink } from \"@webiny/lexical-nodes\";\nimport { useRichTextEditor } from \"~/hooks/index.js\";\n\ntype Props = {\n validateUrl?: (url: string) => boolean;\n};\n\nexport function LinkPlugin({ validateUrl }: Props): null {\n const { editor } = useRichTextEditor();\n\n useEffect(() => {\n if (!editor.hasNodes([LinkNode])) {\n throw new Error(\"LinkPlugin: LinkNode not registered in the editor!\");\n }\n\n const commands = [\n editor.registerCommand(\n TOGGLE_LINK_COMMAND,\n payload => {\n if (payload === null) {\n toggleLink(payload);\n return true;\n } else if (typeof payload === \"string\") {\n if (validateUrl === undefined || validateUrl(payload)) {\n toggleLink(payload);\n return true;\n }\n return false;\n } else {\n const { url, ...attrs } = payload;\n toggleLink(url, attrs);\n return true;\n }\n },\n COMMAND_PRIORITY_LOW\n )\n ];\n\n if (validateUrl !== undefined) {\n commands.push(\n editor.registerCommand(\n PASTE_COMMAND,\n event => {\n const selection = $getSelection();\n if (\n !$isRangeSelection(selection) ||\n selection.isCollapsed() ||\n !(event instanceof ClipboardEvent) ||\n event.clipboardData == null\n ) {\n return false;\n }\n const clipboardText = event.clipboardData.getData(\"text\");\n if (!validateUrl(clipboardText)) {\n return false;\n }\n // If we select nodes that are elements then avoid applying the link.\n if (!selection.getNodes().some(node => $isElementNode(node))) {\n editor.dispatchCommand(TOGGLE_LINK_COMMAND, clipboardText);\n event.preventDefault();\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_LOW\n )\n );\n }\n\n return mergeRegister(...commands);\n }, [editor, validateUrl]);\n\n return null;\n}\n"],"names":["LinkPlugin","validateUrl","editor","useRichTextEditor","useEffect","LinkNode","Error","commands","TOGGLE_LINK_COMMAND","payload","toggleLink","undefined","url","attrs","COMMAND_PRIORITY_LOW","PASTE_COMMAND","event","selection","$getSelection","$isRangeSelection","ClipboardEvent","clipboardText","node","$isElementNode","mergeRegister"],"mappings":";;;;AAgBO,SAASA,WAAW,EAAEC,WAAW,EAAS;IAC7C,MAAM,EAAEC,MAAM,EAAE,GAAGC;IAEnBC,UAAU;QACN,IAAI,CAACF,OAAO,QAAQ,CAAC;YAACG;SAAS,GAC3B,MAAM,IAAIC,MAAM;QAGpB,MAAMC,WAAW;YACbL,OAAO,eAAe,CAClBM,qBACAC,CAAAA;gBACI,IAAIA,AAAY,SAAZA,SAAkB;oBAClBC,WAAWD;oBACX,OAAO;gBACX;gBAAO,IAAI,AAAmB,YAAnB,OAAOA,SAAsB;oBACpC,IAAIR,AAAgBU,WAAhBV,eAA6BA,YAAYQ,UAAU;wBACnDC,WAAWD;wBACX,OAAO;oBACX;oBACA,OAAO;gBACX;gBAAO;oBACH,MAAM,EAAEG,GAAG,EAAE,GAAGC,OAAO,GAAGJ;oBAC1BC,WAAWE,KAAKC;oBAChB,OAAO;gBACX;YACJ,GACAC;SAEP;QAED,IAAIb,AAAgBU,WAAhBV,aACAM,SAAS,IAAI,CACTL,OAAO,eAAe,CAClBa,eACAC,CAAAA;YACI,MAAMC,YAAYC;YAClB,IACI,CAACC,kBAAkBF,cACnBA,UAAU,WAAW,MACrB,CAAED,CAAAA,iBAAiBI,cAAa,KAChCJ,AAAuB,QAAvBA,MAAM,aAAa,EAEnB,OAAO;YAEX,MAAMK,gBAAgBL,MAAM,aAAa,CAAC,OAAO,CAAC;YAClD,IAAI,CAACf,YAAYoB,gBACb,OAAO;YAGX,IAAI,CAACJ,UAAU,QAAQ,GAAG,IAAI,CAACK,CAAAA,OAAQC,eAAeD,QAAQ;gBAC1DpB,OAAO,eAAe,CAACM,qBAAqBa;gBAC5CL,MAAM,cAAc;gBACpB,OAAO;YACX;YACA,OAAO;QACX,GACAF;QAKZ,OAAOU,iBAAiBjB;IAC5B,GAAG;QAACL;QAAQD;KAAY;IAExB,OAAO;AACX"}