@squiz/formatted-text-editor 0.0.0-rbv2-20240530041851
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/.eslintrc.json +41 -0
- package/CHANGELOG.md +155 -0
- package/README.md +74 -0
- package/build.js +21 -0
- package/coverage/clover.xml +1544 -0
- package/coverage/coverage-final.json +74 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +911 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov-report/src/Editor/Editor.tsx.html +436 -0
- package/coverage/lcov-report/src/Editor/EditorContext.ts.html +145 -0
- package/coverage/lcov-report/src/Editor/index.html +131 -0
- package/coverage/lcov-report/src/EditorToolbar/FloatingToolbar.tsx.html +271 -0
- package/coverage/lcov-report/src/EditorToolbar/Toolbar.tsx.html +265 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Bold/BoldButton.tsx.html +178 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Bold/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.tsx.html +229 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/ClearFormatting/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.tsx.html +187 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/HorizontalLine/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Image/Form/ImageForm.tsx.html +688 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Image/Form/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Image/ImageButton.tsx.html +301 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Image/ImageModal.tsx.html +181 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Image/index.html +131 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Italic/ItalicButton.tsx.html +178 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Italic/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Link/Form/LinkForm.tsx.html +508 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Link/Form/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Link/LinkButton.tsx.html +286 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Link/LinkModal.tsx.html +196 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Link/RemoveLinkButton.tsx.html +211 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Link/index.html +146 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Lists/ListButtons.tsx.html +127 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Lists/OrderedList/OrderedListButton.tsx.html +175 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Lists/OrderedList/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Lists/UnorderedList/UnorderedListButton.tsx.html +175 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Lists/UnorderedList/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Lists/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Redo/RedoButton.tsx.html +178 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Redo/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Table/TableButton.tsx.html +181 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Table/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.tsx.html +178 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextAlign/CenterAlign/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.tsx.html +178 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextAlign/JustifyAlign/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.tsx.html +178 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextAlign/LeftAlign/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.tsx.html +178 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextAlign/RightAlign/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextAlign/TextAlignButtons.tsx.html +148 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextAlign/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.tsx.html +181 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextType/CodeBlock/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextType/Heading/HeadingButton.tsx.html +241 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextType/Heading/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.tsx.html +160 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextType/Paragraph/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.tsx.html +181 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextType/Preformatted/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextType/TextTypeDropdown.tsx.html +247 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/TextType/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Underline/UnderlineButton.tsx.html +178 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Underline/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Undo/UndoButton.tsx.html +178 -0
- package/coverage/lcov-report/src/EditorToolbar/Tools/Undo/index.html +116 -0
- package/coverage/lcov-report/src/EditorToolbar/index.html +146 -0
- package/coverage/lcov-report/src/EditorToolbar/index.ts.html +91 -0
- package/coverage/lcov-report/src/Extensions/ClearFormattingExtension/ClearFormattingExtension.ts.html +256 -0
- package/coverage/lcov-report/src/Extensions/ClearFormattingExtension/index.html +116 -0
- package/coverage/lcov-report/src/Extensions/CodeBlockExtension/CodeBlockExtension.ts.html +187 -0
- package/coverage/lcov-report/src/Extensions/CodeBlockExtension/index.html +116 -0
- package/coverage/lcov-report/src/Extensions/CommandsExtension/CommandsExtension.ts.html +247 -0
- package/coverage/lcov-report/src/Extensions/CommandsExtension/index.html +116 -0
- package/coverage/lcov-report/src/Extensions/Extensions.ts.html +349 -0
- package/coverage/lcov-report/src/Extensions/FetchUrlExtension/FetchUrlExtension.ts.html +289 -0
- package/coverage/lcov-report/src/Extensions/FetchUrlExtension/index.html +116 -0
- package/coverage/lcov-report/src/Extensions/ImageExtension/AssetImageExtension.ts.html +412 -0
- package/coverage/lcov-report/src/Extensions/ImageExtension/ImageExtension.ts.html +142 -0
- package/coverage/lcov-report/src/Extensions/ImageExtension/index.html +131 -0
- package/coverage/lcov-report/src/Extensions/LinkExtension/AssetLinkExtension.ts.html +466 -0
- package/coverage/lcov-report/src/Extensions/LinkExtension/LinkExtension.ts.html +400 -0
- package/coverage/lcov-report/src/Extensions/LinkExtension/common.ts.html +115 -0
- package/coverage/lcov-report/src/Extensions/LinkExtension/index.html +146 -0
- package/coverage/lcov-report/src/Extensions/PreformattedExtension/PreformattedExtension.ts.html +340 -0
- package/coverage/lcov-report/src/Extensions/PreformattedExtension/index.html +116 -0
- package/coverage/lcov-report/src/Extensions/UnsuportedExtension/UnsupportedNodeExtension.tsx.html +325 -0
- package/coverage/lcov-report/src/Extensions/UnsuportedExtension/index.html +116 -0
- package/coverage/lcov-report/src/Extensions/index.html +116 -0
- package/coverage/lcov-report/src/hooks/index.html +161 -0
- package/coverage/lcov-report/src/hooks/index.ts.html +91 -0
- package/coverage/lcov-report/src/hooks/useExpandedSelection.ts.html +217 -0
- package/coverage/lcov-report/src/hooks/useExtensionNames.ts.html +130 -0
- package/coverage/lcov-report/src/hooks/useFocus.ts.html +268 -0
- package/coverage/lcov-report/src/index.html +116 -0
- package/coverage/lcov-report/src/index.ts.html +112 -0
- package/coverage/lcov-report/src/ui/Button/Button.tsx.html +190 -0
- package/coverage/lcov-report/src/ui/Button/index.html +116 -0
- package/coverage/lcov-report/src/ui/CollapseBox/CollapseBox.tsx.html +193 -0
- package/coverage/lcov-report/src/ui/CollapseBox/index.html +116 -0
- package/coverage/lcov-report/src/ui/Fields/Checkbox/Checkbox.tsx.html +232 -0
- package/coverage/lcov-report/src/ui/Fields/Checkbox/index.html +116 -0
- package/coverage/lcov-report/src/ui/Fields/Input/Input.tsx.html +160 -0
- package/coverage/lcov-report/src/ui/Fields/Input/index.html +116 -0
- package/coverage/lcov-report/src/ui/Fields/InputContainer/InputContainer.tsx.html +172 -0
- package/coverage/lcov-report/src/ui/Fields/InputContainer/index.html +116 -0
- package/coverage/lcov-report/src/ui/Fields/MatrixAsset/MatrixAsset.tsx.html +256 -0
- package/coverage/lcov-report/src/ui/Fields/MatrixAsset/index.html +116 -0
- package/coverage/lcov-report/src/ui/Fields/Select/Select.tsx.html +283 -0
- package/coverage/lcov-report/src/ui/Fields/Select/index.html +116 -0
- package/coverage/lcov-report/src/ui/Modal/FormModal.tsx.html +136 -0
- package/coverage/lcov-report/src/ui/Modal/Modal.tsx.html +397 -0
- package/coverage/lcov-report/src/ui/Modal/index.html +131 -0
- package/coverage/lcov-report/src/ui/Tabs/Tabs.tsx.html +208 -0
- package/coverage/lcov-report/src/ui/Tabs/index.html +116 -0
- package/coverage/lcov-report/src/ui/ToolbarDropdown/ToolbarDropdown.tsx.html +211 -0
- package/coverage/lcov-report/src/ui/ToolbarDropdown/index.html +116 -0
- package/coverage/lcov-report/src/ui/ToolbarDropdownButton/ToolbarDropdownButton.tsx.html +184 -0
- package/coverage/lcov-report/src/ui/ToolbarDropdownButton/index.html +116 -0
- package/coverage/lcov-report/src/utils/converters/htmlToSquizNode/htmlToSquizNode.ts.html +166 -0
- package/coverage/lcov-report/src/utils/converters/htmlToSquizNode/index.html +116 -0
- package/coverage/lcov-report/src/utils/converters/mocks/index.html +116 -0
- package/coverage/lcov-report/src/utils/converters/mocks/squizNodeJson.mock.ts.html +895 -0
- package/coverage/lcov-report/src/utils/converters/remirrorNodeToSquizNode/index.html +116 -0
- package/coverage/lcov-report/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.ts.html +976 -0
- package/coverage/lcov-report/src/utils/converters/squizNodeToRemirrorNode/index.html +116 -0
- package/coverage/lcov-report/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.ts.html +748 -0
- package/coverage/lcov-report/src/utils/createToolbarPositioner.ts.html +469 -0
- package/coverage/lcov-report/src/utils/getCursorRect.ts.html +100 -0
- package/coverage/lcov-report/src/utils/getMarkNamesByGroup.ts.html +106 -0
- package/coverage/lcov-report/src/utils/getNodeNamesByGroup.ts.html +106 -0
- package/coverage/lcov-report/src/utils/getShortcutSymbol.ts.html +97 -0
- package/coverage/lcov-report/src/utils/index.html +206 -0
- package/coverage/lcov-report/src/utils/undefinedIfEmpty.ts.html +94 -0
- package/coverage/lcov-report/src/utils/validation.ts.html +133 -0
- package/coverage/lcov.info +2737 -0
- package/cypress/e2e/bold.spec.cy.ts +18 -0
- package/cypress/global.d.ts +9 -0
- package/cypress/support/commands.ts +130 -0
- package/cypress/support/e2e.ts +20 -0
- package/cypress/tsconfig.json +8 -0
- package/cypress.config.ts +7 -0
- package/demo/App.tsx +107 -0
- package/demo/AppContext.tsx +70 -0
- package/demo/index.html +13 -0
- package/demo/index.scss +33 -0
- package/demo/main.tsx +12 -0
- package/demo/public/favicon-dxp.svg +3 -0
- package/demo/resources.json +204 -0
- package/demo/sources.json +27 -0
- package/demo/vite-env.d.ts +1 -0
- package/file-transformer.js +1 -0
- package/jest.bootstrap.ts +3 -0
- package/jest.config.ts +27 -0
- package/lib/Editor/Editor.d.ts +16 -0
- package/lib/Editor/Editor.js +85 -0
- package/lib/Editor/EditorContext.d.ts +10 -0
- package/lib/Editor/EditorContext.js +16 -0
- package/lib/EditorToolbar/FloatingToolbar.d.ts +2 -0
- package/lib/EditorToolbar/FloatingToolbar.js +76 -0
- package/lib/EditorToolbar/Toolbar.d.ts +7 -0
- package/lib/EditorToolbar/Toolbar.js +47 -0
- package/lib/EditorToolbar/Tools/Bold/BoldButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Bold/BoldButton.js +23 -0
- package/lib/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.js +57 -0
- package/lib/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.js +25 -0
- package/lib/EditorToolbar/Tools/Image/Form/ImageForm.d.ts +18 -0
- package/lib/EditorToolbar/Tools/Image/Form/ImageForm.js +143 -0
- package/lib/EditorToolbar/Tools/Image/ImageButton.d.ts +6 -0
- package/lib/EditorToolbar/Tools/Image/ImageButton.js +76 -0
- package/lib/EditorToolbar/Tools/Image/ImageModal.d.ts +9 -0
- package/lib/EditorToolbar/Tools/Image/ImageModal.js +24 -0
- package/lib/EditorToolbar/Tools/Italic/ItalicButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Italic/ItalicButton.js +23 -0
- package/lib/EditorToolbar/Tools/Link/Form/LinkForm.d.ts +19 -0
- package/lib/EditorToolbar/Tools/Link/Form/LinkForm.js +63 -0
- package/lib/EditorToolbar/Tools/Link/LinkButton.d.ts +6 -0
- package/lib/EditorToolbar/Tools/Link/LinkButton.js +71 -0
- package/lib/EditorToolbar/Tools/Link/LinkModal.d.ts +9 -0
- package/lib/EditorToolbar/Tools/Link/LinkModal.js +27 -0
- package/lib/EditorToolbar/Tools/Link/RemoveLinkButton.d.ts +4 -0
- package/lib/EditorToolbar/Tools/Link/RemoveLinkButton.js +54 -0
- package/lib/EditorToolbar/Tools/Lists/ListButtons.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Lists/ListButtons.js +14 -0
- package/lib/EditorToolbar/Tools/Lists/OrderedList/OrderedListButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Lists/OrderedList/OrderedListButton.js +22 -0
- package/lib/EditorToolbar/Tools/Lists/UnorderedList/UnorderedListButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Lists/UnorderedList/UnorderedListButton.js +22 -0
- package/lib/EditorToolbar/Tools/Redo/RedoButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Redo/RedoButton.js +22 -0
- package/lib/EditorToolbar/Tools/Table/TableButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Table/TableButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextAlign/TextAlignButtons.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextAlign/TextAlignButtons.js +21 -0
- package/lib/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextType/Heading/HeadingButton.d.ts +6 -0
- package/lib/EditorToolbar/Tools/TextType/Heading/HeadingButton.js +37 -0
- package/lib/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.js +21 -0
- package/lib/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextType/TextTypeDropdown.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextType/TextTypeDropdown.js +46 -0
- package/lib/EditorToolbar/Tools/Underline/UnderlineButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Underline/UnderlineButton.js +23 -0
- package/lib/EditorToolbar/Tools/Undo/UndoButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Undo/UndoButton.js +22 -0
- package/lib/EditorToolbar/index.d.ts +2 -0
- package/lib/EditorToolbar/index.js +18 -0
- package/lib/Extensions/ClearFormattingExtension/ClearFormattingExtension.d.ts +5 -0
- package/lib/Extensions/ClearFormattingExtension/ClearFormattingExtension.js +63 -0
- package/lib/Extensions/CodeBlockExtension/CodeBlockExtension.d.ts +5 -0
- package/lib/Extensions/CodeBlockExtension/CodeBlockExtension.js +30 -0
- package/lib/Extensions/CommandsExtension/CommandsExtension.d.ts +20 -0
- package/lib/Extensions/CommandsExtension/CommandsExtension.js +52 -0
- package/lib/Extensions/Extensions.d.ts +17 -0
- package/lib/Extensions/Extensions.js +73 -0
- package/lib/Extensions/FetchUrlExtension/FetchUrlExtension.d.ts +12 -0
- package/lib/Extensions/FetchUrlExtension/FetchUrlExtension.js +63 -0
- package/lib/Extensions/ImageExtension/AssetImageExtension.d.ts +17 -0
- package/lib/Extensions/ImageExtension/AssetImageExtension.js +91 -0
- package/lib/Extensions/ImageExtension/ImageExtension.d.ts +7 -0
- package/lib/Extensions/ImageExtension/ImageExtension.js +18 -0
- package/lib/Extensions/LinkExtension/AssetLinkExtension.d.ts +27 -0
- package/lib/Extensions/LinkExtension/AssetLinkExtension.js +101 -0
- package/lib/Extensions/LinkExtension/LinkExtension.d.ts +23 -0
- package/lib/Extensions/LinkExtension/LinkExtension.js +87 -0
- package/lib/Extensions/LinkExtension/common.d.ts +7 -0
- package/lib/Extensions/LinkExtension/common.js +14 -0
- package/lib/Extensions/PreformattedExtension/PreformattedExtension.d.ts +12 -0
- package/lib/Extensions/PreformattedExtension/PreformattedExtension.js +76 -0
- package/lib/Extensions/UnsuportedExtension/UnsupportedNodeExtension.d.ts +10 -0
- package/lib/Extensions/UnsuportedExtension/UnsupportedNodeExtension.js +76 -0
- package/lib/hooks/index.d.ts +2 -0
- package/lib/hooks/index.js +18 -0
- package/lib/hooks/useExpandedSelection.d.ts +23 -0
- package/lib/hooks/useExpandedSelection.js +37 -0
- package/lib/hooks/useExtensionNames.d.ts +1 -0
- package/lib/hooks/useExtensionNames.js +16 -0
- package/lib/hooks/useFocus.d.ts +8 -0
- package/lib/hooks/useFocus.js +43 -0
- package/lib/index.css +1525 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +16 -0
- package/lib/types.d.ts +7 -0
- package/lib/types.js +2 -0
- package/lib/ui/Button/Button.d.ts +12 -0
- package/lib/ui/Button/Button.js +13 -0
- package/lib/ui/CollapseBox/CollapseBox.d.ts +7 -0
- package/lib/ui/CollapseBox/CollapseBox.js +48 -0
- package/lib/ui/Fields/Checkbox/Checkbox.d.ts +9 -0
- package/lib/ui/Fields/Checkbox/Checkbox.js +47 -0
- package/lib/ui/Fields/Input/Input.d.ts +3 -0
- package/lib/ui/Fields/Input/Input.js +33 -0
- package/lib/ui/Fields/InputContainer/InputContainer.d.ts +9 -0
- package/lib/ui/Fields/InputContainer/InputContainer.js +16 -0
- package/lib/ui/Fields/MatrixAsset/MatrixAsset.d.ts +19 -0
- package/lib/ui/Fields/MatrixAsset/MatrixAsset.js +30 -0
- package/lib/ui/Modal/FormModal.d.ts +5 -0
- package/lib/ui/Modal/FormModal.js +39 -0
- package/lib/ui/Modal/Modal.d.ts +11 -0
- package/lib/ui/Modal/Modal.js +79 -0
- package/lib/ui/Tabs/Tabs.d.ts +11 -0
- package/lib/ui/Tabs/Tabs.js +46 -0
- package/lib/ui/ToolbarDropdown/ToolbarDropdown.d.ts +7 -0
- package/lib/ui/ToolbarDropdown/ToolbarDropdown.js +48 -0
- package/lib/ui/ToolbarDropdownButton/ToolbarDropdownButton.d.ts +11 -0
- package/lib/ui/ToolbarDropdownButton/ToolbarDropdownButton.js +15 -0
- package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.d.ts +5 -0
- package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.js +23 -0
- package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.props.d.ts +3 -0
- package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.props.js +2 -0
- package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.d.ts +11 -0
- package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.js +229 -0
- package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.d.ts +9 -0
- package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.js +205 -0
- package/lib/utils/createToolbarPositioner.d.ts +18 -0
- package/lib/utils/createToolbarPositioner.js +96 -0
- package/lib/utils/getCursorRect.d.ts +2 -0
- package/lib/utils/getCursorRect.js +7 -0
- package/lib/utils/getMarkNamesByGroup.d.ts +2 -0
- package/lib/utils/getMarkNamesByGroup.js +9 -0
- package/lib/utils/getNodeNamesByGroup.d.ts +2 -0
- package/lib/utils/getNodeNamesByGroup.js +9 -0
- package/lib/utils/getShortcutSymbol.d.ts +1 -0
- package/lib/utils/getShortcutSymbol.js +8 -0
- package/lib/utils/undefinedIfEmpty.d.ts +1 -0
- package/lib/utils/undefinedIfEmpty.js +7 -0
- package/lib/utils/validation.d.ts +3 -0
- package/lib/utils/validation.js +16 -0
- package/package.json +83 -0
- package/postcss.config.js +12 -0
- package/src/Editor/Editor.spec.tsx +465 -0
- package/src/Editor/Editor.tsx +117 -0
- package/src/Editor/EditorContext.spec.tsx +25 -0
- package/src/Editor/EditorContext.ts +20 -0
- package/src/Editor/_editor.scss +430 -0
- package/src/EditorToolbar/FloatingToolbar.spec.tsx +49 -0
- package/src/EditorToolbar/FloatingToolbar.tsx +62 -0
- package/src/EditorToolbar/Toolbar.tsx +60 -0
- package/src/EditorToolbar/Tools/Bold/BoldButton.spec.tsx +19 -0
- package/src/EditorToolbar/Tools/Bold/BoldButton.tsx +31 -0
- package/src/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.spec.tsx +34 -0
- package/src/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.tsx +48 -0
- package/src/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.spec.tsx +23 -0
- package/src/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.tsx +34 -0
- package/src/EditorToolbar/Tools/Image/Form/ImageForm.spec.tsx +117 -0
- package/src/EditorToolbar/Tools/Image/Form/ImageForm.tsx +201 -0
- package/src/EditorToolbar/Tools/Image/ImageButton.spec.tsx +385 -0
- package/src/EditorToolbar/Tools/Image/ImageButton.tsx +72 -0
- package/src/EditorToolbar/Tools/Image/ImageModal.spec.tsx +123 -0
- package/src/EditorToolbar/Tools/Image/ImageModal.tsx +32 -0
- package/src/EditorToolbar/Tools/Italic/ItalicButton.spec.tsx +19 -0
- package/src/EditorToolbar/Tools/Italic/ItalicButton.tsx +31 -0
- package/src/EditorToolbar/Tools/Link/Form/LinkForm.spec.tsx +79 -0
- package/src/EditorToolbar/Tools/Link/Form/LinkForm.tsx +141 -0
- package/src/EditorToolbar/Tools/Link/LinkButton.spec.tsx +402 -0
- package/src/EditorToolbar/Tools/Link/LinkButton.tsx +67 -0
- package/src/EditorToolbar/Tools/Link/LinkModal.tsx +37 -0
- package/src/EditorToolbar/Tools/Link/RemoveLinkButton.spec.tsx +143 -0
- package/src/EditorToolbar/Tools/Link/RemoveLinkButton.tsx +42 -0
- package/src/EditorToolbar/Tools/Lists/ListButtons.tsx +14 -0
- package/src/EditorToolbar/Tools/Lists/OrderedList/OrderListButton.spec.tsx +39 -0
- package/src/EditorToolbar/Tools/Lists/OrderedList/OrderedListButton.tsx +30 -0
- package/src/EditorToolbar/Tools/Lists/UnorderedList/UnorderedList.spec.tsx +19 -0
- package/src/EditorToolbar/Tools/Lists/UnorderedList/UnorderedListButton.tsx +30 -0
- package/src/EditorToolbar/Tools/Redo/RedoButton.spec.tsx +59 -0
- package/src/EditorToolbar/Tools/Redo/RedoButton.tsx +31 -0
- package/src/EditorToolbar/Tools/Table/TableButton.spec.tsx +25 -0
- package/src/EditorToolbar/Tools/Table/TableButton.tsx +32 -0
- package/src/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.spec.tsx +39 -0
- package/src/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.tsx +31 -0
- package/src/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.spec.tsx +39 -0
- package/src/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.tsx +31 -0
- package/src/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.spec.tsx +39 -0
- package/src/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.tsx +31 -0
- package/src/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.spec.tsx +39 -0
- package/src/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.tsx +31 -0
- package/src/EditorToolbar/Tools/TextAlign/TextAlignButtons.tsx +21 -0
- package/src/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.spec.tsx +47 -0
- package/src/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.tsx +32 -0
- package/src/EditorToolbar/Tools/TextType/Heading/HeadingButton.spec.tsx +56 -0
- package/src/EditorToolbar/Tools/TextType/Heading/HeadingButton.tsx +52 -0
- package/src/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.spec.tsx +30 -0
- package/src/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.tsx +25 -0
- package/src/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.spec.tsx +47 -0
- package/src/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.tsx +32 -0
- package/src/EditorToolbar/Tools/TextType/TextTypeDropdown.spec.tsx +51 -0
- package/src/EditorToolbar/Tools/TextType/TextTypeDropdown.tsx +54 -0
- package/src/EditorToolbar/Tools/Underline/Underline.spec.tsx +19 -0
- package/src/EditorToolbar/Tools/Underline/UnderlineButton.tsx +31 -0
- package/src/EditorToolbar/Tools/Undo/UndoButton.spec.tsx +70 -0
- package/src/EditorToolbar/Tools/Undo/UndoButton.tsx +31 -0
- package/src/EditorToolbar/_floating-toolbar.scss +9 -0
- package/src/EditorToolbar/_toolbar.scss +37 -0
- package/src/EditorToolbar/index.ts +2 -0
- package/src/Extensions/ClearFormattingExtension/ClearFormattingExtension.ts +57 -0
- package/src/Extensions/CodeBlockExtension/CodeBlockExtension.ts +34 -0
- package/src/Extensions/CommandsExtension/CommandsExtension.ts +54 -0
- package/src/Extensions/Extensions.ts +88 -0
- package/src/Extensions/FetchUrlExtension/FetchUrlExtension.ts +68 -0
- package/src/Extensions/ImageExtension/AssetImageExtension.spec.ts +77 -0
- package/src/Extensions/ImageExtension/AssetImageExtension.ts +109 -0
- package/src/Extensions/ImageExtension/ImageExtension.ts +19 -0
- package/src/Extensions/LinkExtension/AssetLinkExtension.spec.ts +106 -0
- package/src/Extensions/LinkExtension/AssetLinkExtension.ts +127 -0
- package/src/Extensions/LinkExtension/LinkExtension.spec.ts +68 -0
- package/src/Extensions/LinkExtension/LinkExtension.ts +105 -0
- package/src/Extensions/LinkExtension/common.ts +10 -0
- package/src/Extensions/PreformattedExtension/PreformattedExtension.spec.ts +43 -0
- package/src/Extensions/PreformattedExtension/PreformattedExtension.ts +85 -0
- package/src/Extensions/UnsuportedExtension/UnsupportedNodeExtension.spec.ts +137 -0
- package/src/Extensions/UnsuportedExtension/UnsupportedNodeExtension.tsx +80 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useExpandedSelection.ts +44 -0
- package/src/hooks/useExtensionNames.ts +15 -0
- package/src/hooks/useFocus.ts +61 -0
- package/src/index.scss +24 -0
- package/src/index.ts +9 -0
- package/src/types.ts +10 -0
- package/src/ui/Button/Button.spec.tsx +44 -0
- package/src/ui/Button/Button.tsx +35 -0
- package/src/ui/Button/_button.scss +37 -0
- package/src/ui/CollapseBox/CollapseBox.spec.tsx +49 -0
- package/src/ui/CollapseBox/CollapseBox.tsx +36 -0
- package/src/ui/CollapseBox/_collapseBox.scss +23 -0
- package/src/ui/Fields/Checkbox/Checkbox.spec.tsx +50 -0
- package/src/ui/Fields/Checkbox/Checkbox.tsx +49 -0
- package/src/ui/Fields/Checkbox/_checkbox.scss +26 -0
- package/src/ui/Fields/Input/Input.spec.tsx +49 -0
- package/src/ui/Fields/Input/Input.tsx +25 -0
- package/src/ui/Fields/InputContainer/InputContainer.spec.tsx +18 -0
- package/src/ui/Fields/InputContainer/InputContainer.tsx +29 -0
- package/src/ui/Fields/MatrixAsset/MatrixAsset.spec.tsx +121 -0
- package/src/ui/Fields/MatrixAsset/MatrixAsset.tsx +57 -0
- package/src/ui/Fields/Select/Select.spec.tsx +30 -0
- package/src/ui/Fields/Select/Select.tsx +66 -0
- package/src/ui/Modal/FormModal.spec.tsx +21 -0
- package/src/ui/Modal/FormModal.tsx +17 -0
- package/src/ui/Modal/Modal.spec.tsx +136 -0
- package/src/ui/Modal/Modal.tsx +104 -0
- package/src/ui/Modal/_modal.scss +24 -0
- package/src/ui/Tabs/Tabs.spec.tsx +44 -0
- package/src/ui/Tabs/Tabs.tsx +41 -0
- package/src/ui/ToolbarDropdown/ToolbarDropdown.spec.tsx +80 -0
- package/src/ui/ToolbarDropdown/ToolbarDropdown.tsx +42 -0
- package/src/ui/ToolbarDropdown/_toolbar-dropdown.scss +32 -0
- package/src/ui/ToolbarDropdownButton/ToolbarDropdownButton.spec.tsx +48 -0
- package/src/ui/ToolbarDropdownButton/ToolbarDropdownButton.tsx +33 -0
- package/src/ui/ToolbarDropdownButton/_toolbar-dropdown-button.scss +25 -0
- package/src/ui/_forms.scss +32 -0
- package/src/ui/_typography.scss +95 -0
- package/src/utils/converters/htmlToSquizNode/htmlToSquizNode.props.ts +3 -0
- package/src/utils/converters/htmlToSquizNode/htmlToSquizNode.spec.ts +179 -0
- package/src/utils/converters/htmlToSquizNode/htmlToSquizNode.ts +27 -0
- package/src/utils/converters/mocks/squizNodeJson.mock.ts +270 -0
- package/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.spec.ts +1058 -0
- package/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.ts +297 -0
- package/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.spec.ts +878 -0
- package/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.ts +221 -0
- package/src/utils/createToolbarPositioner.ts +128 -0
- package/src/utils/getCursorRect.ts +5 -0
- package/src/utils/getMarkNamesByGroup.spec.ts +20 -0
- package/src/utils/getMarkNamesByGroup.ts +7 -0
- package/src/utils/getNodeNamesByGroup.spec.ts +37 -0
- package/src/utils/getNodeNamesByGroup.ts +7 -0
- package/src/utils/getShortcutSymbol.spec.ts +27 -0
- package/src/utils/getShortcutSymbol.ts +4 -0
- package/src/utils/undefinedIfEmpty.spec.ts +12 -0
- package/src/utils/undefinedIfEmpty.ts +3 -0
- package/src/utils/validation.spec.ts +22 -0
- package/src/utils/validation.ts +16 -0
- package/tailwind.config.cjs +87 -0
- package/tests/index.ts +4 -0
- package/tests/mockResourceBrowserContext.tsx +99 -0
- package/tests/renderWithContext.tsx +75 -0
- package/tests/renderWithEditor.tsx +123 -0
- package/tests/select.ts +16 -0
- package/tsconfig.json +22 -0
- package/vite.config.ts +27 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { useCommands, useActive, useChainedCommands } from '@remirror/react';
|
3
|
+
import { UnderlineExtension } from '@remirror/extension-underline';
|
4
|
+
import Button from '../../../ui/Button/Button';
|
5
|
+
import FormatUnderlinedRoundedIcon from '@mui/icons-material/FormatUnderlinedRounded';
|
6
|
+
import { getShortcutSymbol } from '../../../utils/getShortcutSymbol';
|
7
|
+
|
8
|
+
const UnderlineButton = () => {
|
9
|
+
const { toggleUnderline } = useCommands();
|
10
|
+
const chain = useChainedCommands();
|
11
|
+
|
12
|
+
const active = useActive<UnderlineExtension>();
|
13
|
+
const enabled = toggleUnderline.enabled();
|
14
|
+
const handleSelect = () => {
|
15
|
+
if (toggleUnderline.enabled()) {
|
16
|
+
chain.toggleUnderline().focus().run();
|
17
|
+
}
|
18
|
+
};
|
19
|
+
|
20
|
+
return (
|
21
|
+
<Button
|
22
|
+
handleOnClick={handleSelect}
|
23
|
+
isDisabled={!enabled}
|
24
|
+
isActive={active.underline()}
|
25
|
+
icon={<FormatUnderlinedRoundedIcon />}
|
26
|
+
label={`Underline (${getShortcutSymbol()}+U)`}
|
27
|
+
/>
|
28
|
+
);
|
29
|
+
};
|
30
|
+
|
31
|
+
export default UnderlineButton;
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import '@testing-library/jest-dom';
|
2
|
+
import { render, screen, fireEvent, act } from '@testing-library/react';
|
3
|
+
import Editor from '../../../Editor/Editor';
|
4
|
+
import React from 'react';
|
5
|
+
import { renderWithEditor } from '../../../../tests';
|
6
|
+
import UndoButton from './UndoButton';
|
7
|
+
|
8
|
+
describe('Undo button', () => {
|
9
|
+
it('Renders the undo button', () => {
|
10
|
+
render(<Editor />);
|
11
|
+
expect(screen.getByRole('button', { name: 'Undo (Ctrl+Z)' })).toBeInTheDocument();
|
12
|
+
});
|
13
|
+
|
14
|
+
it('Renders a disabled button if you have not made any changes yet', () => {
|
15
|
+
render(<Editor />);
|
16
|
+
const undo = screen.getByRole('button', { name: 'Undo (Ctrl+Z)' });
|
17
|
+
expect(undo).toBeDisabled();
|
18
|
+
});
|
19
|
+
|
20
|
+
it('Enables the button when you perform an action', () => {
|
21
|
+
const { baseElement } = render(<Editor />);
|
22
|
+
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeFalsy();
|
23
|
+
|
24
|
+
const leftAlignButton = baseElement.querySelector('button[title="Align left"]') as HTMLButtonElement;
|
25
|
+
expect(leftAlignButton).toBeTruthy();
|
26
|
+
|
27
|
+
fireEvent.click(leftAlignButton);
|
28
|
+
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeTruthy();
|
29
|
+
const undo = screen.getByRole('button', { name: 'Undo (Ctrl+Z)' });
|
30
|
+
expect(undo).not.toBeDisabled();
|
31
|
+
});
|
32
|
+
|
33
|
+
it('Reverts this action when clicked', () => {
|
34
|
+
const { baseElement } = render(<Editor />);
|
35
|
+
|
36
|
+
// perform some action
|
37
|
+
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeFalsy();
|
38
|
+
const leftAlignButton = baseElement.querySelector('button[title="Align left"]') as HTMLButtonElement;
|
39
|
+
expect(leftAlignButton).toBeTruthy();
|
40
|
+
fireEvent.click(leftAlignButton);
|
41
|
+
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeTruthy();
|
42
|
+
|
43
|
+
// Check that this enables the undo button
|
44
|
+
const undo = screen.getByRole('button', { name: 'Undo (Ctrl+Z)' });
|
45
|
+
expect(undo).not.toBeDisabled();
|
46
|
+
|
47
|
+
// Click the undo button and check that this has reverted the previous action
|
48
|
+
fireEvent.click(undo);
|
49
|
+
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeFalsy();
|
50
|
+
});
|
51
|
+
|
52
|
+
it('Reverts text content changes', async () => {
|
53
|
+
const { editor, getJsonContent } = await renderWithEditor(<UndoButton />, { content: 'Initial content...' });
|
54
|
+
|
55
|
+
await act(() => editor.jumpTo('end'));
|
56
|
+
await act(() => editor.paste(' with some updated content.'));
|
57
|
+
expect(getJsonContent()).toEqual({
|
58
|
+
type: 'paragraph',
|
59
|
+
attrs: expect.any(Object),
|
60
|
+
content: [{ type: 'text', text: 'Initial content... with some updated content.' }],
|
61
|
+
});
|
62
|
+
|
63
|
+
fireEvent.click(screen.getByRole('button', { name: 'Undo (Ctrl+Z)' }));
|
64
|
+
expect(getJsonContent()).toEqual({
|
65
|
+
type: 'paragraph',
|
66
|
+
attrs: expect.any(Object),
|
67
|
+
content: [{ type: 'text', text: 'Initial content...' }],
|
68
|
+
});
|
69
|
+
});
|
70
|
+
});
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { useCommands, useHelpers } from '@remirror/react';
|
3
|
+
import { HistoryExtension } from 'remirror/extensions';
|
4
|
+
import Button from '../../../ui/Button/Button';
|
5
|
+
import UndoRoundedIcon from '@mui/icons-material/UndoRounded';
|
6
|
+
import { getShortcutSymbol } from '../../../utils/getShortcutSymbol';
|
7
|
+
|
8
|
+
const UndoButton = () => {
|
9
|
+
const { undo } = useCommands<HistoryExtension>();
|
10
|
+
const { undoDepth } = useHelpers<HistoryExtension>(true);
|
11
|
+
|
12
|
+
const handleSelect = () => {
|
13
|
+
if (undo.enabled()) {
|
14
|
+
undo();
|
15
|
+
}
|
16
|
+
};
|
17
|
+
|
18
|
+
const enabled = undoDepth() > 0;
|
19
|
+
|
20
|
+
return (
|
21
|
+
<Button
|
22
|
+
handleOnClick={handleSelect}
|
23
|
+
isDisabled={!enabled}
|
24
|
+
isActive={false}
|
25
|
+
icon={<UndoRoundedIcon />}
|
26
|
+
label={`Undo (${getShortcutSymbol()}+Z)`}
|
27
|
+
/>
|
28
|
+
);
|
29
|
+
};
|
30
|
+
|
31
|
+
export default UndoButton;
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/// This class is excluded from the scope of squiz-fte-scope as it is outside of the scoped element
|
2
|
+
.squiz-fte-scope__floating-popover {
|
3
|
+
@extend .editor-toolbar;
|
4
|
+
@apply bg-white border-gray-200 p-1 shadow rounded-md border flex;
|
5
|
+
|
6
|
+
.MuiDivider-root {
|
7
|
+
@apply my-0;
|
8
|
+
}
|
9
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
.editor-toolbar {
|
2
|
+
@apply bg-transparent rounded-t;
|
3
|
+
|
4
|
+
&__tools {
|
5
|
+
@apply border-gray-200 border-b-2 border-solid p-1 w-full flex flex-wrap justify-items-center;
|
6
|
+
|
7
|
+
> *:not(:first-child, .MuiDivider-root) {
|
8
|
+
margin: 0 0 0 2px;
|
9
|
+
}
|
10
|
+
|
11
|
+
.MuiDivider-root {
|
12
|
+
@apply my-0 mx-1 border;
|
13
|
+
margin-right: 2px;
|
14
|
+
height: auto;
|
15
|
+
}
|
16
|
+
|
17
|
+
.squiz-fte-btn {
|
18
|
+
@apply p-1 font-bold;
|
19
|
+
~ .squiz-fte-btn {
|
20
|
+
margin-left: 2px;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
.header-toolbar {
|
27
|
+
transition-duration: 0.3s;
|
28
|
+
transition-property: max-height, opacity;
|
29
|
+
transition-timing-function: ease-out;
|
30
|
+
opacity: 0;
|
31
|
+
max-height: 0;
|
32
|
+
|
33
|
+
&.show-toolbar {
|
34
|
+
opacity: 1;
|
35
|
+
max-height: 108px; // this should mean at least 3 icons can git vertically if needed
|
36
|
+
}
|
37
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import { command, extension, PlainExtension, CommandFunction, Mark, ExtensionTag } from '@remirror/core';
|
2
|
+
import { getNodeNamesByGroup } from '../../utils/getNodeNamesByGroup';
|
3
|
+
import { getMarkNamesByGroup } from '../../utils/getMarkNamesByGroup';
|
4
|
+
|
5
|
+
@extension({})
|
6
|
+
export class ClearFormattingExtension extends PlainExtension {
|
7
|
+
get name() {
|
8
|
+
return 'clearFormatting' as const;
|
9
|
+
}
|
10
|
+
|
11
|
+
@command()
|
12
|
+
clearFormatting(): CommandFunction {
|
13
|
+
return ({ dispatch, tr, state }) => {
|
14
|
+
const { empty, ranges } = state.selection;
|
15
|
+
const schema = state.schema;
|
16
|
+
|
17
|
+
const formattingNodes = getNodeNamesByGroup(schema, ExtensionTag.FormattingNode);
|
18
|
+
const formattingMarks = getMarkNamesByGroup(schema, ExtensionTag.FormattingMark);
|
19
|
+
let isChanged = false;
|
20
|
+
|
21
|
+
ranges.forEach(({ $from, $to }) => {
|
22
|
+
// Check if there is a selection or not, if no selection use the doc content size as the range
|
23
|
+
state.doc.nodesBetween(empty ? 0 : $from.pos, empty ? state.doc.content.size : $to.pos, (node, pos) => {
|
24
|
+
// Clear marks (bold, italic, etc)
|
25
|
+
node.marks.forEach((mark: Mark) => {
|
26
|
+
if (formattingMarks.includes(mark.type.name)) {
|
27
|
+
tr.removeMark(pos, pos + node.nodeSize, mark);
|
28
|
+
isChanged = true;
|
29
|
+
}
|
30
|
+
});
|
31
|
+
|
32
|
+
// Leave non-foramtting nodes as-is
|
33
|
+
if (!formattingNodes.includes(node.type.name)) {
|
34
|
+
return;
|
35
|
+
}
|
36
|
+
|
37
|
+
// Clear node attributes & set to paragraph by default
|
38
|
+
if (node.type.name === schema.nodes.paragraph.name) {
|
39
|
+
const { nodeTextAlignment } = node.attrs;
|
40
|
+
|
41
|
+
if (nodeTextAlignment && nodeTextAlignment !== 'left') {
|
42
|
+
tr.setNodeAttribute(pos, 'nodeTextAlignment', null);
|
43
|
+
isChanged = true;
|
44
|
+
}
|
45
|
+
} else {
|
46
|
+
tr.setNodeMarkup(pos, schema.nodes.paragraph, null, node.marks);
|
47
|
+
isChanged = true;
|
48
|
+
}
|
49
|
+
});
|
50
|
+
});
|
51
|
+
|
52
|
+
dispatch?.(tr);
|
53
|
+
|
54
|
+
return isChanged;
|
55
|
+
};
|
56
|
+
}
|
57
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import { CodeBlockExtension } from '@remirror/extension-code-block';
|
2
|
+
import { NodeViewMethod, ProsemirrorNode } from 'remirror';
|
3
|
+
|
4
|
+
export class ExtendedCodeBlockExtension extends CodeBlockExtension {
|
5
|
+
createNodeViews(): NodeViewMethod {
|
6
|
+
return (node: ProsemirrorNode) => {
|
7
|
+
const { language } = node.attrs;
|
8
|
+
|
9
|
+
// This is the pre container for the code block
|
10
|
+
const dom = document.createElement('pre');
|
11
|
+
dom.setAttribute('spellcheck', 'false');
|
12
|
+
dom.classList.add(`code-block`);
|
13
|
+
|
14
|
+
// This is the actual code content in the code block
|
15
|
+
const contentDOM = document.createElement('code');
|
16
|
+
contentDOM.setAttribute('data-code-block-language', language);
|
17
|
+
|
18
|
+
// Divider between code block and pre container
|
19
|
+
const dividerElement = document.createElement('div');
|
20
|
+
dividerElement.classList.add('block-divider');
|
21
|
+
|
22
|
+
// The material icon to use
|
23
|
+
const codeIcon = document.createElement('svg');
|
24
|
+
codeIcon.classList.add('material-symbols-rounded');
|
25
|
+
codeIcon.textContent = 'code';
|
26
|
+
|
27
|
+
dom.append(codeIcon);
|
28
|
+
dom.append(dividerElement);
|
29
|
+
dom.append(contentDOM);
|
30
|
+
|
31
|
+
return { dom, contentDOM };
|
32
|
+
};
|
33
|
+
}
|
34
|
+
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { PlainExtension } from '@remirror/core';
|
2
|
+
import { command, CommandFunction, FromToProps, getTextSelection, MarkType } from 'remirror';
|
3
|
+
import { Attrs } from 'prosemirror-model';
|
4
|
+
|
5
|
+
export class CommandsExtension extends PlainExtension {
|
6
|
+
get name(): string {
|
7
|
+
return 'squizCommands' as const;
|
8
|
+
}
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Updates the attributes of a specific mark for the current selection.
|
12
|
+
* Optionally, if text is provided it will replace the current selection.
|
13
|
+
* The cursor will be place at the end of the selection after changes.
|
14
|
+
*
|
15
|
+
* @param {object} options
|
16
|
+
*/
|
17
|
+
@command()
|
18
|
+
updateMark(options: {
|
19
|
+
mark: MarkType;
|
20
|
+
attrs?: Attrs;
|
21
|
+
text?: string;
|
22
|
+
removeMark?: boolean;
|
23
|
+
range: FromToProps;
|
24
|
+
}): CommandFunction {
|
25
|
+
return (props) => {
|
26
|
+
const { tr, dispatch, view } = props;
|
27
|
+
const { mark, attrs, text, removeMark, range } = options;
|
28
|
+
|
29
|
+
const selectedText = tr.doc.textBetween(range.from, range.to);
|
30
|
+
|
31
|
+
if (text !== undefined && text !== selectedText) {
|
32
|
+
// update the text in the editor if it was updated, update the range to cover the length of the new text.
|
33
|
+
tr.insertText(text, range.from, range.to);
|
34
|
+
range.to = range.from + text.length;
|
35
|
+
}
|
36
|
+
|
37
|
+
// apply the link, or remove it if no URL was provided.
|
38
|
+
if (removeMark) {
|
39
|
+
tr.removeMark(range.from, range.to, mark);
|
40
|
+
} else {
|
41
|
+
tr.addMark(range.from, range.to, mark.create(attrs));
|
42
|
+
}
|
43
|
+
|
44
|
+
// move the cursor to the end of the link and re-focus the editor.
|
45
|
+
tr.setSelection(getTextSelection({ from: range.to, to: range.to }, tr.doc));
|
46
|
+
|
47
|
+
// apply the transaction.
|
48
|
+
dispatch?.(tr);
|
49
|
+
view?.focus();
|
50
|
+
|
51
|
+
return true;
|
52
|
+
};
|
53
|
+
}
|
54
|
+
}
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import {
|
2
|
+
BoldExtension,
|
3
|
+
DocExtension,
|
4
|
+
HeadingExtension,
|
5
|
+
ItalicExtension,
|
6
|
+
NodeFormattingExtension,
|
7
|
+
ParagraphExtension,
|
8
|
+
UnderlineExtension,
|
9
|
+
HistoryExtension,
|
10
|
+
OrderedListExtension,
|
11
|
+
BulletListExtension,
|
12
|
+
ListItemExtension,
|
13
|
+
PlaceholderExtension,
|
14
|
+
HorizontalRuleExtension,
|
15
|
+
TextExtension,
|
16
|
+
HardBreakExtension,
|
17
|
+
} from 'remirror/extensions';
|
18
|
+
import { Extension } from '@remirror/core';
|
19
|
+
import { PreformattedExtension } from './PreformattedExtension/PreformattedExtension';
|
20
|
+
import { AssetLinkExtension } from './LinkExtension/AssetLinkExtension';
|
21
|
+
import { LinkExtension } from './LinkExtension/LinkExtension';
|
22
|
+
import { ImageExtension } from './ImageExtension/ImageExtension';
|
23
|
+
import { CommandsExtension } from './CommandsExtension/CommandsExtension';
|
24
|
+
import { EditorContextOptions } from '../Editor/EditorContext';
|
25
|
+
import { AssetImageExtension } from './ImageExtension/AssetImageExtension';
|
26
|
+
import { ExtendedCodeBlockExtension } from './CodeBlockExtension/CodeBlockExtension';
|
27
|
+
import { ClearFormattingExtension } from './ClearFormattingExtension/ClearFormattingExtension';
|
28
|
+
import { UnsupportedNodeExtension } from './UnsuportedExtension/UnsupportedNodeExtension';
|
29
|
+
import { FetchUrlExtension } from './FetchUrlExtension/FetchUrlExtension';
|
30
|
+
import { TableExtension } from '@remirror/extension-react-tables';
|
31
|
+
import { ReactComponentExtension } from '@remirror/extension-react-component';
|
32
|
+
|
33
|
+
export enum NodeName {
|
34
|
+
Image = 'image',
|
35
|
+
CodeBlock = 'codeBlock',
|
36
|
+
AssetImage = 'assetImage',
|
37
|
+
Text = 'text',
|
38
|
+
TableControllerCell = 'tableControllerCell',
|
39
|
+
tableCell = 'tableCell',
|
40
|
+
hardBreak = 'hardBreak',
|
41
|
+
Unsupported = 'unsupportedNode',
|
42
|
+
}
|
43
|
+
|
44
|
+
export enum MarkName {
|
45
|
+
Link = 'link',
|
46
|
+
AssetLink = 'assetLink',
|
47
|
+
}
|
48
|
+
|
49
|
+
export const createExtensions = (context: EditorContextOptions) => {
|
50
|
+
return (): Extension[] => {
|
51
|
+
return [
|
52
|
+
new CommandsExtension(),
|
53
|
+
new BoldExtension(),
|
54
|
+
new DocExtension(),
|
55
|
+
new HeadingExtension(),
|
56
|
+
new ItalicExtension(),
|
57
|
+
new NodeFormattingExtension({ indents: [] }),
|
58
|
+
new ParagraphExtension(),
|
59
|
+
new HardBreakExtension(),
|
60
|
+
new PreformattedExtension(),
|
61
|
+
new ExtendedCodeBlockExtension({ defaultWrap: true }),
|
62
|
+
new UnderlineExtension(),
|
63
|
+
new HistoryExtension(),
|
64
|
+
new ImageExtension(),
|
65
|
+
new ImageExtension({ preferPastedTextContent: false }),
|
66
|
+
new AssetImageExtension({
|
67
|
+
matrixDomain: context.matrix.matrixDomain,
|
68
|
+
}),
|
69
|
+
new LinkExtension(),
|
70
|
+
new AssetLinkExtension({
|
71
|
+
matrixDomain: context.matrix.matrixDomain,
|
72
|
+
}),
|
73
|
+
new UnsupportedNodeExtension(),
|
74
|
+
new ClearFormattingExtension(),
|
75
|
+
new BulletListExtension(),
|
76
|
+
new ListItemExtension(),
|
77
|
+
new OrderedListExtension(),
|
78
|
+
new HorizontalRuleExtension(),
|
79
|
+
new PlaceholderExtension(),
|
80
|
+
new FetchUrlExtension({
|
81
|
+
fetchUrl: context.resolveNodeToUrl,
|
82
|
+
}),
|
83
|
+
new TextExtension(),
|
84
|
+
new TableExtension(),
|
85
|
+
new ReactComponentExtension(),
|
86
|
+
];
|
87
|
+
};
|
88
|
+
};
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import { extension, PlainExtension, Mark } from '@remirror/core';
|
2
|
+
import { Dispose, EditorView } from '@remirror/core-types';
|
3
|
+
import { MarkName, NodeName } from '../Extensions';
|
4
|
+
import { ResolveNodeToUrl, ResolveNodeType } from '../../types';
|
5
|
+
|
6
|
+
export type FetchUrlOptions = {
|
7
|
+
fetchUrl?: ResolveNodeToUrl;
|
8
|
+
};
|
9
|
+
@extension<FetchUrlOptions>({
|
10
|
+
defaultOptions: {
|
11
|
+
fetchUrl: () => Promise.resolve(''),
|
12
|
+
},
|
13
|
+
})
|
14
|
+
export class FetchUrlExtension extends PlainExtension<FetchUrlOptions> {
|
15
|
+
get name() {
|
16
|
+
return 'fetchUrl';
|
17
|
+
}
|
18
|
+
|
19
|
+
// Implement the `onView` lifecycle method to scan for `[fetch]` and replace attributes
|
20
|
+
onView(view: EditorView): Dispose | void {
|
21
|
+
const { state } = view;
|
22
|
+
const { tr } = state;
|
23
|
+
|
24
|
+
const promises: Promise<void>[] = [];
|
25
|
+
|
26
|
+
state.doc.descendants((node, pos) => {
|
27
|
+
if (node.type.name === NodeName.AssetImage && node.attrs.src === '') {
|
28
|
+
promises.push(
|
29
|
+
this.fetchAndReplace(node.attrs, (url: string) => {
|
30
|
+
const newNode = state.schema.nodes[NodeName.AssetImage].create({ ...node.attrs, src: url });
|
31
|
+
tr.replaceWith(pos, pos + node.nodeSize, newNode);
|
32
|
+
}),
|
33
|
+
);
|
34
|
+
}
|
35
|
+
|
36
|
+
const assetLinkMark = this.findAssetLinkMark(node.marks as Mark[]);
|
37
|
+
if (node.type.name === 'text' && assetLinkMark) {
|
38
|
+
promises.push(
|
39
|
+
this.fetchAndReplace(assetLinkMark.attrs, (url: string) => {
|
40
|
+
const updatedMark = assetLinkMark.type.create({ ...assetLinkMark.attrs, href: url });
|
41
|
+
tr.addMark(pos, pos + node.nodeSize, updatedMark);
|
42
|
+
}),
|
43
|
+
);
|
44
|
+
}
|
45
|
+
});
|
46
|
+
|
47
|
+
if (promises.length) {
|
48
|
+
Promise.all(promises).then(() => {
|
49
|
+
view.dispatch(tr);
|
50
|
+
});
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
private findAssetLinkMark(marks: Mark[]): Mark | undefined {
|
55
|
+
return marks.find((mark) => mark.type.name === MarkName.AssetLink && mark.attrs.href === '');
|
56
|
+
}
|
57
|
+
|
58
|
+
private fetchAndReplace(nodeAttrs: ResolveNodeType, onFetched: (url: string) => void): Promise<void> {
|
59
|
+
return this.options
|
60
|
+
.fetchUrl(nodeAttrs)
|
61
|
+
.then((url: string) => {
|
62
|
+
onFetched(url);
|
63
|
+
})
|
64
|
+
.catch((error) => {
|
65
|
+
console.error('Error fetching URL:', error);
|
66
|
+
});
|
67
|
+
}
|
68
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import { renderWithEditor } from '../../../tests';
|
2
|
+
|
3
|
+
describe('AssetImageExtension', () => {
|
4
|
+
it('Parses HTML content representing an asset image', async () => {
|
5
|
+
const { getJsonContent } = await renderWithEditor(null, {
|
6
|
+
content: `<img
|
7
|
+
src="https://my-matrix.squiz.net/?a=this-is-actually-ignored"
|
8
|
+
data-matrix-asset-id="123"
|
9
|
+
data-matrix-identifier="matrix-api-identifier"
|
10
|
+
data-matrix-domain="https://matrix-domain.squiz.net" />`,
|
11
|
+
});
|
12
|
+
|
13
|
+
expect(getJsonContent()).toEqual({
|
14
|
+
type: 'paragraph',
|
15
|
+
attrs: expect.any(Object),
|
16
|
+
content: [
|
17
|
+
{
|
18
|
+
type: 'assetImage',
|
19
|
+
attrs: {
|
20
|
+
matrixAssetId: '123',
|
21
|
+
matrixDomain: 'https://matrix-domain.squiz.net',
|
22
|
+
matrixIdentifier: 'matrix-api-identifier',
|
23
|
+
src: 'https://default-resource/',
|
24
|
+
},
|
25
|
+
},
|
26
|
+
],
|
27
|
+
});
|
28
|
+
});
|
29
|
+
|
30
|
+
it('Resolves to a regular image if HTML content is missing some of the expected attributes', async () => {
|
31
|
+
const { getJsonContent } = await renderWithEditor(null, {
|
32
|
+
content: '<img src="https://my-matrix.squiz.net/?a=123" data-matrix-asset-id="123" />',
|
33
|
+
});
|
34
|
+
|
35
|
+
expect(getJsonContent()).toEqual({
|
36
|
+
type: 'paragraph',
|
37
|
+
attrs: expect.any(Object),
|
38
|
+
content: [
|
39
|
+
{
|
40
|
+
type: 'image',
|
41
|
+
attrs: expect.objectContaining({
|
42
|
+
src: 'https://my-matrix.squiz.net/?a=123',
|
43
|
+
}),
|
44
|
+
},
|
45
|
+
],
|
46
|
+
});
|
47
|
+
});
|
48
|
+
|
49
|
+
it('Outputs expected HTML', async () => {
|
50
|
+
const { getHtmlContent } = await renderWithEditor(null, {
|
51
|
+
content: {
|
52
|
+
type: 'paragraph',
|
53
|
+
content: [
|
54
|
+
{
|
55
|
+
type: 'assetImage',
|
56
|
+
attrs: {
|
57
|
+
matrixAssetId: '123',
|
58
|
+
matrixDomain: 'https://matrix-domain.squiz.net',
|
59
|
+
matrixIdentifier: 'matrix-api-identifier',
|
60
|
+
},
|
61
|
+
},
|
62
|
+
],
|
63
|
+
},
|
64
|
+
});
|
65
|
+
|
66
|
+
expect(getHtmlContent()).toEqual(
|
67
|
+
'<img ' +
|
68
|
+
'src="https://default-resource/" ' +
|
69
|
+
'data-matrix-asset-id="123" ' +
|
70
|
+
'data-matrix-identifier="matrix-api-identifier" ' +
|
71
|
+
'data-matrix-domain="https://matrix-domain.squiz.net" ' +
|
72
|
+
'draggable="true">' +
|
73
|
+
'<img class="ProseMirror-separator" alt="">' +
|
74
|
+
'<br class="ProseMirror-trailingBreak">',
|
75
|
+
);
|
76
|
+
});
|
77
|
+
});
|
@@ -0,0 +1,109 @@
|
|
1
|
+
import {
|
2
|
+
ApplySchemaAttributes,
|
3
|
+
command,
|
4
|
+
extension,
|
5
|
+
ExtensionPriority,
|
6
|
+
ExtensionTag,
|
7
|
+
isElementDomNode,
|
8
|
+
NodeExtension,
|
9
|
+
NodeExtensionSpec,
|
10
|
+
NodeSpecOverride,
|
11
|
+
omitExtraAttributes,
|
12
|
+
CommandFunction,
|
13
|
+
} from '@remirror/core';
|
14
|
+
import { getTextSelection } from 'remirror';
|
15
|
+
import { NodeName } from '../Extensions';
|
16
|
+
|
17
|
+
export type AssetImageOptions = {
|
18
|
+
matrixDomain?: string;
|
19
|
+
};
|
20
|
+
|
21
|
+
export type AssetImageAttributes = {
|
22
|
+
matrixAssetId: string;
|
23
|
+
matrixIdentifier: string;
|
24
|
+
matrixDomain: string;
|
25
|
+
url: string;
|
26
|
+
};
|
27
|
+
|
28
|
+
@extension<AssetImageOptions>({
|
29
|
+
defaultOptions: {
|
30
|
+
matrixDomain: '',
|
31
|
+
},
|
32
|
+
defaultPriority: ExtensionPriority.High,
|
33
|
+
})
|
34
|
+
export class AssetImageExtension extends NodeExtension<AssetImageOptions> {
|
35
|
+
get name() {
|
36
|
+
return NodeName.AssetImage as const;
|
37
|
+
}
|
38
|
+
|
39
|
+
createTags() {
|
40
|
+
return [ExtensionTag.InlineNode, ExtensionTag.Media];
|
41
|
+
}
|
42
|
+
|
43
|
+
createNodeSpec(extra: ApplySchemaAttributes, override: NodeSpecOverride): NodeExtensionSpec {
|
44
|
+
return {
|
45
|
+
inline: true,
|
46
|
+
draggable: true,
|
47
|
+
selectable: true,
|
48
|
+
...override,
|
49
|
+
attrs: {
|
50
|
+
...extra.defaults(),
|
51
|
+
matrixAssetId: {},
|
52
|
+
matrixIdentifier: {},
|
53
|
+
matrixDomain: { default: this.options.matrixDomain },
|
54
|
+
src: { default: '' },
|
55
|
+
},
|
56
|
+
parseDOM: [
|
57
|
+
{
|
58
|
+
tag: 'img[data-matrix-asset-id]',
|
59
|
+
getAttrs: (node) => {
|
60
|
+
if (!isElementDomNode(node)) {
|
61
|
+
return false;
|
62
|
+
}
|
63
|
+
|
64
|
+
const matrixAssetId = node.getAttribute('data-matrix-asset-id');
|
65
|
+
const matrixIdentifier = node.getAttribute('data-matrix-identifier');
|
66
|
+
const matrixDomain = node.getAttribute('data-matrix-domain');
|
67
|
+
|
68
|
+
if (!matrixAssetId || !matrixIdentifier || !matrixDomain) {
|
69
|
+
return false;
|
70
|
+
}
|
71
|
+
|
72
|
+
return {
|
73
|
+
...extra.parse(node),
|
74
|
+
matrixAssetId,
|
75
|
+
matrixIdentifier,
|
76
|
+
matrixDomain,
|
77
|
+
};
|
78
|
+
},
|
79
|
+
},
|
80
|
+
],
|
81
|
+
toDOM: (node) => {
|
82
|
+
const { matrixAssetId, matrixIdentifier, matrixDomain, src, ...rest } = omitExtraAttributes(node.attrs, extra);
|
83
|
+
return [
|
84
|
+
'img',
|
85
|
+
{
|
86
|
+
...extra.dom(node),
|
87
|
+
...rest,
|
88
|
+
src,
|
89
|
+
'data-matrix-asset-id': matrixAssetId,
|
90
|
+
'data-matrix-identifier': matrixIdentifier,
|
91
|
+
'data-matrix-domain': matrixDomain,
|
92
|
+
},
|
93
|
+
];
|
94
|
+
},
|
95
|
+
};
|
96
|
+
}
|
97
|
+
|
98
|
+
@command()
|
99
|
+
insertAssetImage(attrs: AssetImageAttributes): CommandFunction {
|
100
|
+
return ({ tr, dispatch }) => {
|
101
|
+
const { from, to } = getTextSelection(tr.selection, tr.doc);
|
102
|
+
const node = this.type.create({ ...attrs, src: attrs.url });
|
103
|
+
|
104
|
+
dispatch?.(tr.replaceRangeWith(from, to, node));
|
105
|
+
|
106
|
+
return true;
|
107
|
+
};
|
108
|
+
}
|
109
|
+
}
|