@contentful/field-editor-rich-text 3.14.3 → 3.15.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.
- package/dist/cjs/ContentfulEditorProvider.js +8 -8
- package/dist/cjs/RichTextEditor.js +22 -20
- package/dist/cjs/RichTextEditor.styles.js +2 -1
- package/dist/cjs/SdkProvider.js +7 -5
- package/dist/cjs/SyncEditorChanges.js +15 -6
- package/dist/cjs/Toolbar/_tests_/toolbar.test.js +17 -15
- package/dist/cjs/Toolbar/components/EmbedEntityWidget.js +14 -10
- package/dist/cjs/Toolbar/components/EmbeddedEntityDropdownButton.js +10 -8
- package/dist/cjs/Toolbar/components/StickyToolbarWrapper.js +2 -2
- package/dist/cjs/Toolbar/index.js +33 -30
- package/dist/cjs/__fixtures__/FakeSdk.js +3 -3
- package/dist/cjs/__fixtures__/asset/index.js +10 -10
- package/dist/cjs/__fixtures__/content-type/index.js +1 -1
- package/dist/cjs/__fixtures__/entry/index.js +7 -7
- package/dist/cjs/__fixtures__/fixtures.js +8 -6
- package/dist/cjs/__fixtures__/locale/index.js +2 -2
- package/dist/cjs/__fixtures__/space/index.js +1 -1
- package/dist/cjs/constants/Schema.js +1 -0
- package/dist/cjs/dialogs/HypelinkDialog/HyperlinkDialog.js +43 -38
- package/dist/cjs/dialogs/openRichTextDialog.js +6 -4
- package/dist/cjs/dialogs/renderRichTextDialog.js +6 -4
- package/dist/cjs/helpers/__tests__/removeInternalMarks.test.js +10 -10
- package/dist/cjs/helpers/callbacks.js +3 -3
- package/dist/cjs/helpers/config.js +2 -2
- package/dist/cjs/helpers/editor.js +53 -44
- package/dist/cjs/helpers/environment.js +3 -3
- package/dist/cjs/helpers/formatDateAndTime.js +5 -4
- package/dist/cjs/helpers/getAllowedResourcesForNodeType.js +22 -5
- package/dist/cjs/helpers/getLinkedContentTypeIdsForNodeType.js +29 -5
- package/dist/cjs/helpers/nodeFactory.js +6 -6
- package/dist/cjs/helpers/sdkNavigatorSlideIn.js +14 -6
- package/dist/cjs/helpers/sdkNavigatorSlideIn.spec.js +3 -2
- package/dist/cjs/helpers/toSlateValue.js +14 -3
- package/dist/cjs/helpers/transformers.js +5 -5
- package/dist/cjs/helpers/validations.js +12 -9
- package/dist/cjs/index.js +7 -5
- package/dist/cjs/internal/constants.js +4 -2
- package/dist/cjs/internal/hooks.js +8 -6
- package/dist/cjs/internal/misc.js +15 -12
- package/dist/cjs/internal/queries.js +115 -108
- package/dist/cjs/internal/transforms.js +51 -48
- package/dist/cjs/internal/types/editor.js +3 -1
- package/dist/cjs/plugins/Break/createExitBreakPlugin.test.js +4 -3
- package/dist/cjs/plugins/Break/createResetNodePlugin.js +1 -0
- package/dist/cjs/plugins/Break/createSoftBreakPlugin.test.js +3 -3
- package/dist/cjs/plugins/CommandPalette/components/CommandList.js +35 -33
- package/dist/cjs/plugins/CommandPalette/components/CommandList.styles.js +1 -1
- package/dist/cjs/plugins/CommandPalette/components/CommandPrompt.js +7 -5
- package/dist/cjs/plugins/CommandPalette/hooks/useCommandList.js +7 -3
- package/dist/cjs/plugins/CommandPalette/onKeyDown.js +6 -1
- package/dist/cjs/plugins/CommandPalette/onKeyDown.spec.js +6 -4
- package/dist/cjs/plugins/CommandPalette/useCommands.js +3 -3
- package/dist/cjs/plugins/CommandPalette/utils/fetchEntries.js +2 -0
- package/dist/cjs/plugins/CommandPalette/utils/trimLeadingSlash.js +6 -1
- package/dist/cjs/plugins/DragAndDrop/index.js +9 -1
- package/dist/cjs/plugins/EmbeddedEntityBlock/LinkedEntityBlock.js +10 -8
- package/dist/cjs/plugins/EmbeddedEntityBlock/index.js +3 -3
- package/dist/cjs/plugins/EmbeddedEntityInline/FetchingWrappedInlineEntryCard.js +19 -17
- package/dist/cjs/plugins/EmbeddedEntityInline/LinkedEntityInline.js +9 -7
- package/dist/cjs/plugins/EmbeddedResourceBlock/LinkedResourceBlock.js +5 -5
- package/dist/cjs/plugins/EmbeddedResourceInline/FetchingWrappedResourceInlineCard.js +17 -13
- package/dist/cjs/plugins/EmbeddedResourceInline/LinkedResourceInline.js +5 -5
- package/dist/cjs/plugins/Heading/__tests__/createHeadingPlugin.test.js +32 -32
- package/dist/cjs/plugins/Heading/components/Heading.js +13 -10
- package/dist/cjs/plugins/Heading/components/ToolbarHeadingButton.js +19 -11
- package/dist/cjs/plugins/Heading/createHeadingPlugin.js +7 -2
- package/dist/cjs/plugins/Hr/index.js +19 -14
- package/dist/cjs/plugins/Hyperlink/HyperlinkModal.js +32 -28
- package/dist/cjs/plugins/Hyperlink/__tests__/createHyperlinkPlugin.test.js +8 -8
- package/dist/cjs/plugins/Hyperlink/components/EntityHyperlink.js +8 -6
- package/dist/cjs/plugins/Hyperlink/components/ResourceHyperlink.js +8 -6
- package/dist/cjs/plugins/Hyperlink/components/ToolbarHyperlinkButton.js +6 -4
- package/dist/cjs/plugins/Hyperlink/components/UrlHyperlink.js +7 -5
- package/dist/cjs/plugins/Hyperlink/components/styles.js +1 -1
- package/dist/cjs/plugins/Hyperlink/createHyperlinkPlugin.js +10 -4
- package/dist/cjs/plugins/Hyperlink/useEntityInfo.js +6 -3
- package/dist/cjs/plugins/Hyperlink/useResourceEntityInfo.js +7 -5
- package/dist/cjs/plugins/Hyperlink/utils.js +6 -14
- package/dist/cjs/plugins/List/__tests__/createListPlugin.test.js +13 -13
- package/dist/cjs/plugins/List/__tests__/insertListBreak.test.js +29 -25
- package/dist/cjs/plugins/List/__tests__/insertListFragment.test.js +22 -22
- package/dist/cjs/plugins/List/components/List.js +9 -7
- package/dist/cjs/plugins/List/components/ListItem.js +6 -4
- package/dist/cjs/plugins/List/components/ToolbarListButton.js +7 -5
- package/dist/cjs/plugins/List/createListPlugin.js +4 -0
- package/dist/cjs/plugins/List/insertListBreak.js +13 -4
- package/dist/cjs/plugins/List/insertListFragment.js +18 -5
- package/dist/cjs/plugins/List/onKeyDownList.js +7 -4
- package/dist/cjs/plugins/List/transforms/insertListItem.js +17 -2
- package/dist/cjs/plugins/List/transforms/moveListItemDown.js +8 -2
- package/dist/cjs/plugins/List/transforms/moveListItems.js +7 -2
- package/dist/cjs/plugins/List/transforms/moveListItems.test.js +15 -14
- package/dist/cjs/plugins/List/transforms/toggleList.js +8 -3
- package/dist/cjs/plugins/List/transforms/toggleList.spec.js +28 -28
- package/dist/cjs/plugins/List/transforms/unwrapList.js +7 -2
- package/dist/cjs/plugins/List/utils.js +12 -11
- package/dist/cjs/plugins/List/withList.js +6 -2
- package/dist/cjs/plugins/Marks/Bold.js +9 -7
- package/dist/cjs/plugins/Marks/Code.js +15 -7
- package/dist/cjs/plugins/Marks/Italic.js +9 -7
- package/dist/cjs/plugins/Marks/Subscript.js +10 -8
- package/dist/cjs/plugins/Marks/Superscript.js +10 -8
- package/dist/cjs/plugins/Marks/Underline.js +6 -4
- package/dist/cjs/plugins/Marks/components/MarkToolbarButton.js +9 -7
- package/dist/cjs/plugins/Marks/helpers.js +5 -5
- package/dist/cjs/plugins/Normalizer/baseRules.js +2 -0
- package/dist/cjs/plugins/Normalizer/createNormalizerPlugin.test.js +12 -12
- package/dist/cjs/plugins/Normalizer/utils.js +4 -3
- package/dist/cjs/plugins/Normalizer/withNormalizer.js +23 -3
- package/dist/cjs/plugins/Paragraph/Paragraph.js +6 -4
- package/dist/cjs/plugins/Paragraph/__tests__/createParagraphPlugin.test.js +32 -32
- package/dist/cjs/plugins/Paragraph/createParagraphPlugin.js +3 -2
- package/dist/cjs/plugins/PasteHTML/createPasteHTMLPlugin.js +9 -6
- package/dist/cjs/plugins/PasteHTML/utils/__tests__/sanitizeHTML.test.js +2 -0
- package/dist/cjs/plugins/PasteHTML/utils/sanitizeAnchors.js +9 -0
- package/dist/cjs/plugins/PasteHTML/utils/sanitizeHTML.js +17 -2
- package/dist/cjs/plugins/PasteHTML/utils/sanitizeSheets.js +13 -1
- package/dist/cjs/plugins/Quote/__test__/createQuotePlugin.test.js +21 -21
- package/dist/cjs/plugins/Quote/components/Quote.js +6 -4
- package/dist/cjs/plugins/Quote/components/ToolbarQuoteButton.js +6 -4
- package/dist/cjs/plugins/Quote/createQuotePlugin.js +1 -0
- package/dist/cjs/plugins/Quote/toggleQuote.js +5 -5
- package/dist/cjs/plugins/Quote/withQuote.js +4 -2
- package/dist/cjs/plugins/SelectOnBackspace/createSelectOnBackspacePlugin.js +1 -0
- package/dist/cjs/plugins/Table/__tests__/createTablePlugin.test.js +22 -22
- package/dist/cjs/plugins/Table/__tests__/helpers.test.js +4 -4
- package/dist/cjs/plugins/Table/actions/addColumn.js +5 -4
- package/dist/cjs/plugins/Table/actions/addRow.js +6 -3
- package/dist/cjs/plugins/Table/components/Cell.js +7 -5
- package/dist/cjs/plugins/Table/components/HeaderCell.js +7 -5
- package/dist/cjs/plugins/Table/components/Row.js +6 -4
- package/dist/cjs/plugins/Table/components/Table.js +8 -6
- package/dist/cjs/plugins/Table/components/TableActions.js +19 -16
- package/dist/cjs/plugins/Table/components/ToolbarButton.js +7 -4
- package/dist/cjs/plugins/Table/createTablePlugin.js +11 -1
- package/dist/cjs/plugins/Table/helpers.js +16 -12
- package/dist/cjs/plugins/Table/insertTableFragment.js +15 -2
- package/dist/cjs/plugins/Table/onKeyDownTable.js +10 -2
- package/dist/cjs/plugins/Table/tableTracking.js +6 -6
- package/dist/cjs/plugins/Text/__tests__/createTextPlugin.test.js +19 -17
- package/dist/cjs/plugins/Text/createTextPlugin.js +22 -5
- package/dist/cjs/plugins/Tracking/createTrackingPlugin.js +5 -4
- package/dist/cjs/plugins/Tracking/utils.js +6 -3
- package/dist/cjs/plugins/Voids/createVoidsPlugin.js +5 -0
- package/dist/cjs/plugins/Voids/transformVoid.js +1 -0
- package/dist/cjs/plugins/index.js +15 -3
- package/dist/cjs/plugins/shared/EmbeddedBlockToolbarIcon.js +12 -10
- package/dist/cjs/plugins/shared/EmbeddedBlockUtil.js +16 -6
- package/dist/cjs/plugins/shared/EmbeddedInlineToolbarIcon.js +10 -8
- package/dist/cjs/plugins/shared/EmbeddedInlineUtil.js +9 -5
- package/dist/cjs/plugins/shared/FetchingWrappedAssetCard.js +13 -11
- package/dist/cjs/plugins/shared/FetchingWrappedEntryCard.js +14 -12
- package/dist/cjs/plugins/shared/FetchingWrappedResourceCard.js +14 -11
- package/dist/cjs/plugins/shared/LinkedBlockWrapper.js +8 -4
- package/dist/cjs/plugins/shared/LinkedInlineWrapper.js +10 -6
- package/dist/cjs/plugins/shared/ResourceNewBadge.js +5 -3
- package/dist/cjs/plugins/shared/ToolbarButton.js +8 -6
- package/dist/cjs/plugins/shared/__tests__/FetchingWrappedAssetCard.test.js +10 -5
- package/dist/cjs/plugins/shared/__tests__/FetchingWrappedEntryCard.test.js +11 -6
- package/dist/cjs/plugins/shared/__tests__/FetchingWrappedResourceCard.test.js +15 -13
- package/dist/cjs/plugins/shared/utils.js +20 -3
- package/dist/cjs/test-utils/assertOutput.js +1 -0
- package/dist/cjs/test-utils/hyperscript.d.js +1 -0
- package/dist/cjs/test-utils/randomId.js +3 -1
- package/dist/cjs/test-utils/validation.js +8 -5
- package/dist/esm/ContentfulEditorProvider.js +4 -1
- package/dist/esm/RichTextEditor.js +13 -13
- package/dist/esm/RichTextEditor.styles.js +1 -0
- package/dist/esm/SdkProvider.js +2 -2
- package/dist/esm/SyncEditorChanges.js +18 -3
- package/dist/esm/Toolbar/_tests_/toolbar.test.js +12 -12
- package/dist/esm/Toolbar/components/EmbedEntityWidget.js +10 -8
- package/dist/esm/Toolbar/components/EmbeddedEntityDropdownButton.js +6 -6
- package/dist/esm/Toolbar/components/StickyToolbarWrapper.js +1 -1
- package/dist/esm/Toolbar/index.js +28 -27
- package/dist/esm/__fixtures__/FakeSdk.js +3 -3
- package/dist/esm/constants/Schema.js +1 -0
- package/dist/esm/dialogs/HypelinkDialog/HyperlinkDialog.js +34 -31
- package/dist/esm/dialogs/openRichTextDialog.js +2 -2
- package/dist/esm/dialogs/renderRichTextDialog.js +2 -2
- package/dist/esm/helpers/__tests__/removeInternalMarks.test.js +10 -10
- package/dist/esm/helpers/callbacks.js +1 -1
- package/dist/esm/helpers/config.js +9 -1
- package/dist/esm/helpers/editor.js +22 -6
- package/dist/esm/helpers/extractNodes.js +3 -1
- package/dist/esm/helpers/formatDateAndTime.js +11 -2
- package/dist/esm/helpers/getAllowedResourcesForNodeType.js +19 -2
- package/dist/esm/helpers/getLinkedContentTypeIdsForNodeType.js +26 -2
- package/dist/esm/helpers/sdkNavigatorSlideIn.js +20 -6
- package/dist/esm/helpers/sdkNavigatorSlideIn.spec.js +1 -0
- package/dist/esm/helpers/toSlateValue.js +17 -3
- package/dist/esm/helpers/validations.js +5 -1
- package/dist/esm/internal/misc.js +23 -2
- package/dist/esm/internal/queries.js +11 -2
- package/dist/esm/internal/transforms.js +14 -3
- package/dist/esm/internal/types/editor.js +3 -1
- package/dist/esm/plugins/Break/createExitBreakPlugin.test.js +4 -3
- package/dist/esm/plugins/Break/createResetNodePlugin.js +1 -0
- package/dist/esm/plugins/Break/createSoftBreakPlugin.test.js +3 -3
- package/dist/esm/plugins/CommandPalette/components/CommandList.js +30 -30
- package/dist/esm/plugins/CommandPalette/components/CommandPrompt.js +2 -2
- package/dist/esm/plugins/CommandPalette/createCommandPalettePlugin.js +11 -1
- package/dist/esm/plugins/CommandPalette/hooks/useCommandList.js +2 -0
- package/dist/esm/plugins/CommandPalette/onKeyDown.js +5 -0
- package/dist/esm/plugins/CommandPalette/onKeyDown.spec.js +2 -2
- package/dist/esm/plugins/CommandPalette/useCommands.js +3 -3
- package/dist/esm/plugins/CommandPalette/utils/fetchEntries.js +2 -0
- package/dist/esm/plugins/CommandPalette/utils/trimLeadingSlash.js +6 -1
- package/dist/esm/plugins/DragAndDrop/index.js +9 -1
- package/dist/esm/plugins/EmbeddedEntityBlock/LinkedEntityBlock.js +6 -6
- package/dist/esm/plugins/EmbeddedEntityInline/FetchingWrappedInlineEntryCard.js +14 -14
- package/dist/esm/plugins/EmbeddedEntityInline/LinkedEntityInline.js +5 -5
- package/dist/esm/plugins/EmbeddedResourceBlock/LinkedResourceBlock.js +4 -4
- package/dist/esm/plugins/EmbeddedResourceInline/FetchingWrappedResourceInlineCard.js +13 -11
- package/dist/esm/plugins/EmbeddedResourceInline/LinkedResourceInline.js +4 -4
- package/dist/esm/plugins/Heading/__tests__/createHeadingPlugin.test.js +32 -32
- package/dist/esm/plugins/Heading/components/Heading.js +8 -7
- package/dist/esm/plugins/Heading/components/ToolbarHeadingButton.js +14 -8
- package/dist/esm/plugins/Heading/createHeadingPlugin.js +6 -1
- package/dist/esm/plugins/Hr/index.js +8 -5
- package/dist/esm/plugins/Hyperlink/HyperlinkModal.js +25 -23
- package/dist/esm/plugins/Hyperlink/__tests__/createHyperlinkPlugin.test.js +8 -8
- package/dist/esm/plugins/Hyperlink/components/EntityHyperlink.js +4 -4
- package/dist/esm/plugins/Hyperlink/components/ResourceHyperlink.js +4 -4
- package/dist/esm/plugins/Hyperlink/components/ToolbarHyperlinkButton.js +2 -2
- package/dist/esm/plugins/Hyperlink/components/UrlHyperlink.js +3 -3
- package/dist/esm/plugins/Hyperlink/createHyperlinkPlugin.js +5 -1
- package/dist/esm/plugins/Hyperlink/useEntityInfo.js +6 -3
- package/dist/esm/plugins/Hyperlink/useResourceEntityInfo.js +3 -3
- package/dist/esm/plugins/Hyperlink/utils.js +2 -7
- package/dist/esm/plugins/List/__tests__/createListPlugin.test.js +13 -13
- package/dist/esm/plugins/List/__tests__/insertListBreak.test.js +29 -25
- package/dist/esm/plugins/List/__tests__/insertListFragment.test.js +22 -22
- package/dist/esm/plugins/List/components/List.js +1 -1
- package/dist/esm/plugins/List/components/ListItem.js +1 -1
- package/dist/esm/plugins/List/components/ToolbarListButton.js +3 -3
- package/dist/esm/plugins/List/createListPlugin.js +4 -0
- package/dist/esm/plugins/List/insertListBreak.js +13 -4
- package/dist/esm/plugins/List/insertListFragment.js +18 -5
- package/dist/esm/plugins/List/onKeyDownList.js +5 -2
- package/dist/esm/plugins/List/transforms/insertListItem.js +20 -3
- package/dist/esm/plugins/List/transforms/moveListItemDown.js +8 -2
- package/dist/esm/plugins/List/transforms/moveListItems.js +7 -2
- package/dist/esm/plugins/List/transforms/moveListItems.test.js +15 -14
- package/dist/esm/plugins/List/transforms/toggleList.js +8 -3
- package/dist/esm/plugins/List/transforms/toggleList.spec.js +28 -28
- package/dist/esm/plugins/List/transforms/unwrapList.js +7 -2
- package/dist/esm/plugins/List/utils.js +7 -2
- package/dist/esm/plugins/List/withList.js +6 -2
- package/dist/esm/plugins/Marks/Bold.js +2 -2
- package/dist/esm/plugins/Marks/Code.js +8 -2
- package/dist/esm/plugins/Marks/Italic.js +2 -2
- package/dist/esm/plugins/Marks/Subscript.js +2 -2
- package/dist/esm/plugins/Marks/Superscript.js +2 -2
- package/dist/esm/plugins/Marks/Underline.js +2 -2
- package/dist/esm/plugins/Marks/components/MarkToolbarButton.js +4 -4
- package/dist/esm/plugins/Marks/helpers.js +1 -1
- package/dist/esm/plugins/Normalizer/baseRules.js +4 -0
- package/dist/esm/plugins/Normalizer/createNormalizerPlugin.test.js +12 -12
- package/dist/esm/plugins/Normalizer/utils.js +1 -0
- package/dist/esm/plugins/Normalizer/withNormalizer.js +22 -2
- package/dist/esm/plugins/Paragraph/Paragraph.js +1 -1
- package/dist/esm/plugins/Paragraph/__tests__/createParagraphPlugin.test.js +32 -32
- package/dist/esm/plugins/Paragraph/createParagraphPlugin.js +2 -1
- package/dist/esm/plugins/PasteHTML/createPasteHTMLPlugin.js +9 -3
- package/dist/esm/plugins/PasteHTML/utils/__tests__/sanitizeHTML.test.js +2 -0
- package/dist/esm/plugins/PasteHTML/utils/sanitizeAnchors.js +27 -1
- package/dist/esm/plugins/PasteHTML/utils/sanitizeHTML.js +17 -2
- package/dist/esm/plugins/PasteHTML/utils/sanitizeSheets.js +13 -1
- package/dist/esm/plugins/Quote/__test__/createQuotePlugin.test.js +21 -21
- package/dist/esm/plugins/Quote/components/Quote.js +1 -1
- package/dist/esm/plugins/Quote/components/ToolbarQuoteButton.js +2 -2
- package/dist/esm/plugins/Quote/createQuotePlugin.js +1 -0
- package/dist/esm/plugins/Quote/shouldResetQuote.js +6 -1
- package/dist/esm/plugins/Quote/toggleQuote.js +1 -1
- package/dist/esm/plugins/Quote/withQuote.js +4 -2
- package/dist/esm/plugins/SelectOnBackspace/createSelectOnBackspacePlugin.js +1 -0
- package/dist/esm/plugins/Table/__tests__/createTablePlugin.test.js +22 -22
- package/dist/esm/plugins/Table/__tests__/helpers.test.js +4 -4
- package/dist/esm/plugins/Table/actions/addColumn.js +2 -1
- package/dist/esm/plugins/Table/actions/addRow.js +3 -0
- package/dist/esm/plugins/Table/components/Cell.js +2 -2
- package/dist/esm/plugins/Table/components/HeaderCell.js +2 -2
- package/dist/esm/plugins/Table/components/Row.js +1 -1
- package/dist/esm/plugins/Table/components/Table.js +3 -3
- package/dist/esm/plugins/Table/components/TableActions.js +12 -11
- package/dist/esm/plugins/Table/components/ToolbarButton.js +3 -2
- package/dist/esm/plugins/Table/createTablePlugin.js +11 -1
- package/dist/esm/plugins/Table/helpers.js +10 -1
- package/dist/esm/plugins/Table/insertTableFragment.js +15 -2
- package/dist/esm/plugins/Table/onKeyDownTable.js +10 -2
- package/dist/esm/plugins/Table/tableTracking.js +6 -6
- package/dist/esm/plugins/Text/__tests__/createTextPlugin.test.js +19 -17
- package/dist/esm/plugins/Text/createTextPlugin.js +22 -5
- package/dist/esm/plugins/Tracking/createTrackingPlugin.js +2 -1
- package/dist/esm/plugins/Tracking/utils.js +1 -0
- package/dist/esm/plugins/Voids/createVoidsPlugin.js +5 -0
- package/dist/esm/plugins/Voids/transformVoid.js +4 -1
- package/dist/esm/plugins/index.js +12 -0
- package/dist/esm/plugins/shared/EmbeddedBlockToolbarIcon.js +5 -5
- package/dist/esm/plugins/shared/EmbeddedBlockUtil.js +15 -5
- package/dist/esm/plugins/shared/EmbeddedInlineToolbarIcon.js +5 -5
- package/dist/esm/plugins/shared/EmbeddedInlineUtil.js +8 -4
- package/dist/esm/plugins/shared/FetchingWrappedAssetCard.js +8 -8
- package/dist/esm/plugins/shared/FetchingWrappedEntryCard.js +9 -9
- package/dist/esm/plugins/shared/FetchingWrappedResourceCard.js +9 -8
- package/dist/esm/plugins/shared/LinkedBlockWrapper.js +7 -3
- package/dist/esm/plugins/shared/LinkedInlineWrapper.js +5 -3
- package/dist/esm/plugins/shared/ResourceNewBadge.js +1 -1
- package/dist/esm/plugins/shared/ToolbarButton.js +3 -3
- package/dist/esm/plugins/shared/__tests__/FetchingWrappedAssetCard.test.js +5 -2
- package/dist/esm/plugins/shared/__tests__/FetchingWrappedEntryCard.test.js +5 -2
- package/dist/esm/plugins/shared/__tests__/FetchingWrappedResourceCard.test.js +8 -8
- package/dist/esm/plugins/shared/utils.js +9 -0
- package/dist/esm/test-utils/assertOutput.js +1 -0
- package/dist/esm/test-utils/hyperscript.d.js +1 -0
- package/dist/esm/test-utils/jsx.js +5 -1
- package/dist/esm/test-utils/randomId.js +3 -1
- package/dist/esm/test-utils/setEmptyDataAttribute.js +4 -1
- package/dist/esm/test-utils/validation.js +7 -4
- package/dist/types/plugins/Hyperlink/utils.d.ts +0 -1
- package/dist/types/plugins/shared/utils.d.ts +1 -0
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BLOCKS, INLINES } from '@contentful/rich-text-types';
|
|
1
|
+
/** @jsx jsx */ import { BLOCKS, INLINES } from '@contentful/rich-text-types';
|
|
2
2
|
import { transformWrapIn } from '../../helpers/transformers';
|
|
3
3
|
import { jsx, createTestEditor, mockPlugin, assertOutput } from '../../test-utils';
|
|
4
4
|
import { createNormalizerPlugin } from './createNormalizerPlugin';
|
|
@@ -12,15 +12,15 @@ describe('Normalizer', ()=>{
|
|
|
12
12
|
];
|
|
13
13
|
let input;
|
|
14
14
|
beforeEach(()=>{
|
|
15
|
-
input = jsx("editor", null, jsx("hul", null, jsx("hli", null, jsx("hembed", {
|
|
15
|
+
input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hul", null, /*#__PURE__*/ jsx("hli", null, /*#__PURE__*/ jsx("hembed", {
|
|
16
16
|
type: "Entry",
|
|
17
17
|
id: "embedded-entry"
|
|
18
|
-
}), jsx("hp", null, "List item"))));
|
|
18
|
+
}), /*#__PURE__*/ jsx("hp", null, "List item"))));
|
|
19
19
|
});
|
|
20
|
-
const expected = jsx("editor", null, jsx("hul", null, jsx("hli", null, jsx("hp", null, "List item"))));
|
|
20
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hul", null, /*#__PURE__*/ jsx("hli", null, /*#__PURE__*/ jsx("hp", null, "List item"))));
|
|
21
21
|
describe('rule.match', ()=>{
|
|
22
22
|
it('matches elements of type "plugin.type" by default', ()=>{
|
|
23
|
-
const { editor
|
|
23
|
+
const { editor } = createTestEditor({
|
|
24
24
|
input,
|
|
25
25
|
plugins: [
|
|
26
26
|
mockPlugin({
|
|
@@ -50,14 +50,14 @@ describe('Normalizer', ()=>{
|
|
|
50
50
|
});
|
|
51
51
|
describe('rule.transform', ()=>{
|
|
52
52
|
it('works with conditional transformation', ()=>{
|
|
53
|
-
const { editor
|
|
54
|
-
input: jsx("editor", null, jsx("hul", null, jsx("hli", null, jsx("hembed", {
|
|
53
|
+
const { editor } = createTestEditor({
|
|
54
|
+
input: /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hul", null, /*#__PURE__*/ jsx("hli", null, /*#__PURE__*/ jsx("hembed", {
|
|
55
55
|
type: "Entry",
|
|
56
56
|
id: "embedded-entry"
|
|
57
|
-
}), jsx("hinline", {
|
|
57
|
+
}), /*#__PURE__*/ jsx("hinline", {
|
|
58
58
|
type: "Entry",
|
|
59
59
|
id: "inline-entry"
|
|
60
|
-
}), jsx("hp", null, "List item")))),
|
|
60
|
+
}), /*#__PURE__*/ jsx("hp", null, "List item")))),
|
|
61
61
|
plugins: [
|
|
62
62
|
mockPlugin({
|
|
63
63
|
isElement: true,
|
|
@@ -78,16 +78,16 @@ describe('Normalizer', ()=>{
|
|
|
78
78
|
});
|
|
79
79
|
assertOutput({
|
|
80
80
|
editor,
|
|
81
|
-
expected: jsx("editor", null, jsx("hul", null, jsx("hli", null, jsx("hp", null, jsx("hinline", {
|
|
81
|
+
expected: /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hul", null, /*#__PURE__*/ jsx("hli", null, /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("hinline", {
|
|
82
82
|
type: "Entry",
|
|
83
83
|
id: "inline-entry"
|
|
84
|
-
})), jsx("hp", null, "List item"))))
|
|
84
|
+
})), /*#__PURE__*/ jsx("hp", null, "List item"))))
|
|
85
85
|
});
|
|
86
86
|
});
|
|
87
87
|
});
|
|
88
88
|
describe('rule.validChildren', ()=>{
|
|
89
89
|
it('supports custom functions', ()=>{
|
|
90
|
-
const { editor
|
|
90
|
+
const { editor } = createTestEditor({
|
|
91
91
|
input,
|
|
92
92
|
plugins: [
|
|
93
93
|
mockPlugin({
|
|
@@ -5,6 +5,7 @@ export const createValidatorFromTypes = (types)=>(_, [node])=>{
|
|
|
5
5
|
return isElement(node) && types.includes(node.type);
|
|
6
6
|
};
|
|
7
7
|
export const createTransformerFromObject = (transforms)=>{
|
|
8
|
+
// A default transformer must always be provided
|
|
8
9
|
const fallback = transforms['default'];
|
|
9
10
|
if (!fallback) {
|
|
10
11
|
throw new NormalizerError('A default transformer MUST be provided');
|
|
@@ -6,25 +6,35 @@ import { baseRules } from './baseRules';
|
|
|
6
6
|
import { NormalizerError, createValidatorFromTypes, createTransformerFromObject } from './utils';
|
|
7
7
|
export const withNormalizer = (editor)=>{
|
|
8
8
|
const rules = baseRules;
|
|
9
|
+
// Derive normalization rules from other plugin's configurations
|
|
9
10
|
for (const p of editor.plugins){
|
|
10
|
-
const { normalizer: _rules
|
|
11
|
+
const { normalizer: _rules } = p;
|
|
11
12
|
if (!_rules) {
|
|
12
13
|
continue;
|
|
13
14
|
}
|
|
14
15
|
for (const _rule of _rules){
|
|
16
|
+
// Clone to avoid mutation bugs
|
|
15
17
|
const rule = {
|
|
16
18
|
..._rule
|
|
17
19
|
};
|
|
18
20
|
if (!rule.match && !p.isElement) {
|
|
19
21
|
throw new NormalizerError('rule.match MUST be defined in a non-element plugin');
|
|
20
22
|
}
|
|
23
|
+
// By default we filter elements with given plugin type
|
|
21
24
|
if (!rule.match) {
|
|
22
25
|
rule.match = {
|
|
23
26
|
type: getPluginType(editor, p.key)
|
|
24
27
|
};
|
|
25
28
|
}
|
|
29
|
+
// Conditional transformation e.g.
|
|
30
|
+
// {
|
|
31
|
+
// [BLOCKS.EMBEDDED_ASSET]: transformLift,
|
|
32
|
+
// default?: transformRemove
|
|
33
|
+
// }
|
|
34
|
+
//
|
|
26
35
|
if (isPlainObject(rule.transform)) {
|
|
27
36
|
if ('validNode' in rule) {
|
|
37
|
+
// I can't think of a use case. Disabled to prevent misuse
|
|
28
38
|
throw new NormalizerError('conditional transformations are not supported in validNode rules');
|
|
29
39
|
}
|
|
30
40
|
rule.transform = createTransformerFromObject({
|
|
@@ -32,33 +42,43 @@ export const withNormalizer = (editor)=>{
|
|
|
32
42
|
...rule.transform
|
|
33
43
|
});
|
|
34
44
|
}
|
|
45
|
+
// By default all invalid nodes are removed.
|
|
35
46
|
if (!rule.transform) {
|
|
36
47
|
rule.transform = transformRemove;
|
|
37
48
|
}
|
|
49
|
+
// Convert Types array syntax to a validator function
|
|
38
50
|
if ('validChildren' in rule && Array.isArray(rule.validChildren)) {
|
|
39
51
|
rule.validChildren = createValidatorFromTypes(rule.validChildren);
|
|
40
52
|
}
|
|
41
53
|
rules.push(rule);
|
|
42
54
|
}
|
|
43
55
|
}
|
|
56
|
+
// Wrap transformer in a withoutNormalizing() call to avoid unnecessary
|
|
57
|
+
// normalization cycles.
|
|
44
58
|
const _transform = (tr, entry)=>{
|
|
45
59
|
withoutNormalizing(editor, ()=>{
|
|
46
60
|
tr(editor, entry);
|
|
47
61
|
});
|
|
48
62
|
};
|
|
49
|
-
const { normalizeNode
|
|
63
|
+
const { normalizeNode } = editor;
|
|
64
|
+
// @ts-expect-error
|
|
50
65
|
editor.normalizeNode = (entry)=>{
|
|
51
66
|
const [node, path] = entry;
|
|
52
67
|
const children = getChildren(entry);
|
|
68
|
+
// The order of validNode rules Vs validChildren doesn't matter. Slate
|
|
69
|
+
// will always perform normalization in a depth-first fashion.
|
|
53
70
|
for (const rule of rules){
|
|
54
71
|
if (!matchNode(node, path, rule.match)) {
|
|
55
72
|
continue;
|
|
56
73
|
}
|
|
74
|
+
// Normalize node
|
|
57
75
|
if ('validNode' in rule && !rule.validNode(editor, entry)) {
|
|
58
76
|
_transform(rule.transform, entry);
|
|
59
77
|
return;
|
|
60
78
|
}
|
|
79
|
+
// Normalize node.children
|
|
61
80
|
if ('validChildren' in rule) {
|
|
81
|
+
// It can not be an array since we enforced it earlier
|
|
62
82
|
const isValidChild = rule.validChildren;
|
|
63
83
|
const invalidChildEntry = children.find((entry)=>!isValidChild(editor, entry));
|
|
64
84
|
if (invalidChildEntry) {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { assertOutput, jsx } from '../../../test-utils';
|
|
1
|
+
/* eslint-disable react/no-unknown-property */ /** @jsx jsx */ import { assertOutput, jsx } from '../../../test-utils';
|
|
2
2
|
describe('normalization', ()=>{
|
|
3
3
|
it('can contain inline entries & hyperlinks', ()=>{
|
|
4
|
-
const input = jsx("editor", null, jsx("hp", null, "some text before", jsx("hinline", {
|
|
4
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some text before", /*#__PURE__*/ jsx("hinline", {
|
|
5
5
|
type: "Entry",
|
|
6
6
|
id: "inline-entry"
|
|
7
|
-
}), jsx("hlink", {
|
|
7
|
+
}), /*#__PURE__*/ jsx("hlink", {
|
|
8
8
|
uri: "https://contentful.com"
|
|
9
|
-
}), jsx("hlink", {
|
|
9
|
+
}), /*#__PURE__*/ jsx("hlink", {
|
|
10
10
|
entry: "entry-id"
|
|
11
|
-
}), jsx("hlink", {
|
|
11
|
+
}), /*#__PURE__*/ jsx("hlink", {
|
|
12
12
|
resource: "resource-urn"
|
|
13
|
-
}), jsx("hlink", {
|
|
13
|
+
}), /*#__PURE__*/ jsx("hlink", {
|
|
14
14
|
asset: "asset-id"
|
|
15
15
|
}), "some text after"));
|
|
16
16
|
assertOutput({
|
|
@@ -19,20 +19,20 @@ describe('normalization', ()=>{
|
|
|
19
19
|
});
|
|
20
20
|
});
|
|
21
21
|
it('wraps orphaned text nodes in a paragraph', ()=>{
|
|
22
|
-
const input = jsx("editor", null, jsx("hp", null, "valid text"), jsx("hh1", null, "valid text"), jsx("htable", null, jsx("htr", null, jsx("htd", null, "invalid text"))));
|
|
23
|
-
const expected = jsx("editor", null, jsx("hp", null, "valid text"), jsx("hh1", null, "valid text"), jsx("htable", null, jsx("htr", null, jsx("htd", null, jsx("hp", null, "invalid text")))), jsx("hp", null, jsx("htext", null)));
|
|
22
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "valid text"), /*#__PURE__*/ jsx("hh1", null, "valid text"), /*#__PURE__*/ jsx("htable", null, /*#__PURE__*/ jsx("htr", null, /*#__PURE__*/ jsx("htd", null, "invalid text"))));
|
|
23
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "valid text"), /*#__PURE__*/ jsx("hh1", null, "valid text"), /*#__PURE__*/ jsx("htable", null, /*#__PURE__*/ jsx("htr", null, /*#__PURE__*/ jsx("htd", null, /*#__PURE__*/ jsx("hp", null, "invalid text")))), /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("htext", null)));
|
|
24
24
|
assertOutput({
|
|
25
25
|
input,
|
|
26
26
|
expected
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
it('unwraps nested paragraphs', ()=>{
|
|
30
|
-
const input = jsx("editor", null, jsx("hp", null, "some", jsx("hp", null, jsx("htext", {
|
|
30
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some", /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("htext", {
|
|
31
31
|
bold: true,
|
|
32
32
|
italic: true,
|
|
33
33
|
underline: true
|
|
34
34
|
}, "paragraph")), "text"));
|
|
35
|
-
const expected = jsx("editor", null, jsx("hp", null, "some", jsx("htext", {
|
|
35
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some", /*#__PURE__*/ jsx("htext", {
|
|
36
36
|
bold: true,
|
|
37
37
|
italic: true,
|
|
38
38
|
underline: true
|
|
@@ -44,76 +44,76 @@ describe('normalization', ()=>{
|
|
|
44
44
|
});
|
|
45
45
|
describe('lifts other invalid children', ()=>{
|
|
46
46
|
it('block void elements', ()=>{
|
|
47
|
-
const input = jsx("editor", null, jsx("hp", null, jsx("hembed", {
|
|
47
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("hembed", {
|
|
48
48
|
type: "Asset",
|
|
49
49
|
id: "1"
|
|
50
|
-
}), " start"), jsx("hp", null, "end ", jsx("hembed", {
|
|
50
|
+
}), " start"), /*#__PURE__*/ jsx("hp", null, "end ", /*#__PURE__*/ jsx("hembed", {
|
|
51
51
|
type: "Asset",
|
|
52
52
|
id: "2"
|
|
53
|
-
})), jsx("hp", null, "in ", jsx("hembed", {
|
|
53
|
+
})), /*#__PURE__*/ jsx("hp", null, "in ", /*#__PURE__*/ jsx("hembed", {
|
|
54
54
|
type: "Asset",
|
|
55
55
|
id: "3"
|
|
56
|
-
}), " between"), jsx("hp", null, jsx("hembed", {
|
|
56
|
+
}), " between"), /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("hembed", {
|
|
57
57
|
type: "Entry",
|
|
58
58
|
id: "1"
|
|
59
|
-
}), " start"), jsx("hp", null, "end ", jsx("hembed", {
|
|
59
|
+
}), " start"), /*#__PURE__*/ jsx("hp", null, "end ", /*#__PURE__*/ jsx("hembed", {
|
|
60
60
|
type: "Entry",
|
|
61
61
|
id: "2"
|
|
62
|
-
})), jsx("hp", null, "in ", jsx("hembed", {
|
|
62
|
+
})), /*#__PURE__*/ jsx("hp", null, "in ", /*#__PURE__*/ jsx("hembed", {
|
|
63
63
|
type: "Entry",
|
|
64
64
|
id: "3"
|
|
65
|
-
}), " between"), jsx("hp", null, jsx("hhr", null), " start"), jsx("hp", null, "end ", jsx("hhr", null)), jsx("hp", null, "in ", jsx("hhr", null), " between"));
|
|
66
|
-
const expected = jsx("editor", null, jsx("hembed", {
|
|
65
|
+
}), " between"), /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("hhr", null), " start"), /*#__PURE__*/ jsx("hp", null, "end ", /*#__PURE__*/ jsx("hhr", null)), /*#__PURE__*/ jsx("hp", null, "in ", /*#__PURE__*/ jsx("hhr", null), " between"));
|
|
66
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hembed", {
|
|
67
67
|
type: "Asset",
|
|
68
68
|
id: "1"
|
|
69
|
-
}), jsx("hp", null, " start"), jsx("hp", null, "end "), jsx("hembed", {
|
|
69
|
+
}), /*#__PURE__*/ jsx("hp", null, " start"), /*#__PURE__*/ jsx("hp", null, "end "), /*#__PURE__*/ jsx("hembed", {
|
|
70
70
|
type: "Asset",
|
|
71
71
|
id: "2"
|
|
72
|
-
}), jsx("hp", null, "in "), jsx("hembed", {
|
|
72
|
+
}), /*#__PURE__*/ jsx("hp", null, "in "), /*#__PURE__*/ jsx("hembed", {
|
|
73
73
|
type: "Asset",
|
|
74
74
|
id: "3"
|
|
75
|
-
}), jsx("hp", null, " between"), jsx("hembed", {
|
|
75
|
+
}), /*#__PURE__*/ jsx("hp", null, " between"), /*#__PURE__*/ jsx("hembed", {
|
|
76
76
|
type: "Entry",
|
|
77
77
|
id: "1"
|
|
78
|
-
}), jsx("hp", null, " start"), jsx("hp", null, "end "), jsx("hembed", {
|
|
78
|
+
}), /*#__PURE__*/ jsx("hp", null, " start"), /*#__PURE__*/ jsx("hp", null, "end "), /*#__PURE__*/ jsx("hembed", {
|
|
79
79
|
type: "Entry",
|
|
80
80
|
id: "2"
|
|
81
|
-
}), jsx("hp", null, "in "), jsx("hembed", {
|
|
81
|
+
}), /*#__PURE__*/ jsx("hp", null, "in "), /*#__PURE__*/ jsx("hembed", {
|
|
82
82
|
type: "Entry",
|
|
83
83
|
id: "3"
|
|
84
|
-
}), jsx("hp", null, " between"), jsx("hhr", null), jsx("hp", null, " start"), jsx("hp", null, "end "), jsx("hhr", null), jsx("hp", null, "in "), jsx("hhr", null), jsx("hp", null, " between"));
|
|
84
|
+
}), /*#__PURE__*/ jsx("hp", null, " between"), /*#__PURE__*/ jsx("hhr", null), /*#__PURE__*/ jsx("hp", null, " start"), /*#__PURE__*/ jsx("hp", null, "end "), /*#__PURE__*/ jsx("hhr", null), /*#__PURE__*/ jsx("hp", null, "in "), /*#__PURE__*/ jsx("hhr", null), /*#__PURE__*/ jsx("hp", null, " between"));
|
|
85
85
|
assertOutput({
|
|
86
86
|
input,
|
|
87
87
|
expected
|
|
88
88
|
});
|
|
89
89
|
});
|
|
90
90
|
it('handles heading', ()=>{
|
|
91
|
-
const input = jsx("editor", null, jsx("hp", null, "some", jsx("hh1", null, "heading"), "text"));
|
|
92
|
-
const expected = jsx("editor", null, jsx("hp", null, "some"), jsx("hh1", null, "heading"), jsx("hp", null, "text"));
|
|
91
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some", /*#__PURE__*/ jsx("hh1", null, "heading"), "text"));
|
|
92
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some"), /*#__PURE__*/ jsx("hh1", null, "heading"), /*#__PURE__*/ jsx("hp", null, "text"));
|
|
93
93
|
assertOutput({
|
|
94
94
|
input,
|
|
95
95
|
expected
|
|
96
96
|
});
|
|
97
97
|
});
|
|
98
98
|
it('handles quotes', ()=>{
|
|
99
|
-
const input = jsx("editor", null, jsx("hp", null, "some", jsx("hquote", null, jsx("hp", null, "quote")), "text"));
|
|
100
|
-
const expected = jsx("editor", null, jsx("hp", null, "some"), jsx("hquote", null, jsx("hp", null, "quote")), jsx("hp", null, "text"));
|
|
99
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some", /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "quote")), "text"));
|
|
100
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some"), /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "quote")), /*#__PURE__*/ jsx("hp", null, "text"));
|
|
101
101
|
assertOutput({
|
|
102
102
|
input,
|
|
103
103
|
expected
|
|
104
104
|
});
|
|
105
105
|
});
|
|
106
106
|
it('handles lists', ()=>{
|
|
107
|
-
const input = jsx("editor", null, jsx("hp", null, "some", jsx("hul", null, jsx("hli", null, jsx("hp", null, "list item"))), "text"));
|
|
108
|
-
const expected = jsx("editor", null, jsx("hp", null, "some"), jsx("hul", null, jsx("hli", null, jsx("hp", null, "list item"))), jsx("hp", null, "text"));
|
|
107
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some", /*#__PURE__*/ jsx("hul", null, /*#__PURE__*/ jsx("hli", null, /*#__PURE__*/ jsx("hp", null, "list item"))), "text"));
|
|
108
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some"), /*#__PURE__*/ jsx("hul", null, /*#__PURE__*/ jsx("hli", null, /*#__PURE__*/ jsx("hp", null, "list item"))), /*#__PURE__*/ jsx("hp", null, "text"));
|
|
109
109
|
assertOutput({
|
|
110
110
|
input,
|
|
111
111
|
expected
|
|
112
112
|
});
|
|
113
113
|
});
|
|
114
114
|
it('handles tables', ()=>{
|
|
115
|
-
const input = jsx("editor", null, jsx("hp", null, "some", jsx("htable", null, jsx("htr", null, jsx("htd", null, jsx("hp", null, "cell 1")), jsx("htd", null, jsx("hp", null, "cell 2")))), "text"));
|
|
116
|
-
const expected = jsx("editor", null, jsx("hp", null, "some"), jsx("htable", null, jsx("htr", null, jsx("htd", null, jsx("hp", null, "cell 1")), jsx("htd", null, jsx("hp", null, "cell 2")))), jsx("hp", null, "text"));
|
|
115
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some", /*#__PURE__*/ jsx("htable", null, /*#__PURE__*/ jsx("htr", null, /*#__PURE__*/ jsx("htd", null, /*#__PURE__*/ jsx("hp", null, "cell 1")), /*#__PURE__*/ jsx("htd", null, /*#__PURE__*/ jsx("hp", null, "cell 2")))), "text"));
|
|
116
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, "some"), /*#__PURE__*/ jsx("htable", null, /*#__PURE__*/ jsx("htr", null, /*#__PURE__*/ jsx("htd", null, /*#__PURE__*/ jsx("hp", null, "cell 1")), /*#__PURE__*/ jsx("htd", null, /*#__PURE__*/ jsx("hp", null, "cell 2")))), /*#__PURE__*/ jsx("hp", null, "text"));
|
|
117
117
|
assertOutput({
|
|
118
118
|
input,
|
|
119
119
|
expected
|
|
@@ -5,7 +5,7 @@ import { isInlineOrText, toggleElement } from '../../helpers/editor';
|
|
|
5
5
|
import { transformUnwrap, transformLift } from '../../helpers/transformers';
|
|
6
6
|
import { Paragraph } from './Paragraph';
|
|
7
7
|
import { isEmbedElement, isEmptyElement } from './utils';
|
|
8
|
-
const buildParagraphKeyDownHandler = (editor, { options: { hotkey
|
|
8
|
+
const buildParagraphKeyDownHandler = (editor, { options: { hotkey } })=>(event)=>{
|
|
9
9
|
if (editor.selection && hotkey && isHotkey(hotkey, event)) {
|
|
10
10
|
toggleElement(editor, {
|
|
11
11
|
activeType: BLOCKS.PARAGRAPH,
|
|
@@ -26,6 +26,7 @@ export const createParagraphPlugin = ()=>{
|
|
|
26
26
|
onKeyDown: buildParagraphKeyDownHandler
|
|
27
27
|
},
|
|
28
28
|
softBreak: [
|
|
29
|
+
// create a new line with SHIFT+Enter inside a paragraph
|
|
29
30
|
{
|
|
30
31
|
hotkey: 'shift+enter',
|
|
31
32
|
query: {
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { KEY_DESERIALIZE_HTML } from '@udecode/plate-common';
|
|
2
2
|
import { sanitizeHTML } from './utils/sanitizeHTML';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Get x-slate-fragment attribute from data-slate-fragment
|
|
5
|
+
*/ const catchSlateFragment = /data-slate-fragment="(.+?)"/m;
|
|
4
6
|
export const getSlateFragmentAttribute = (dataTransfer)=>{
|
|
5
7
|
const htmlData = dataTransfer.getData('text/html');
|
|
6
8
|
const [, fragment] = htmlData.match(catchSlateFragment) || [];
|
|
7
9
|
return fragment;
|
|
8
10
|
};
|
|
9
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Get the x-slate-fragment attribute that exist in text/html data
|
|
13
|
+
* and append it to the DataTransfer object
|
|
14
|
+
*/ export const ensureXSlateFragment = (dataTransfer)=>{
|
|
10
15
|
if (!dataTransfer.getData('application/x-slate-fragment')) {
|
|
11
16
|
const fragment = getSlateFragmentAttribute(dataTransfer);
|
|
12
17
|
if (fragment) {
|
|
@@ -23,7 +28,7 @@ export const ensureXSlateFragment = (dataTransfer)=>{
|
|
|
23
28
|
export const createPasteHTMLPlugin = ()=>({
|
|
24
29
|
key: 'PasteHTMLPlugin',
|
|
25
30
|
withOverrides: (editor)=>{
|
|
26
|
-
const { insertData
|
|
31
|
+
const { insertData } = editor;
|
|
27
32
|
editor.insertData = (data)=>insertData(ensureXSlateFragment(data));
|
|
28
33
|
return editor;
|
|
29
34
|
},
|
|
@@ -33,6 +38,7 @@ export const createPasteHTMLPlugin = ()=>({
|
|
|
33
38
|
editor: {
|
|
34
39
|
insertData: {
|
|
35
40
|
format: 'text/html',
|
|
41
|
+
// Perform custom content transformation *before* pasting
|
|
36
42
|
transformData: sanitizeHTML
|
|
37
43
|
}
|
|
38
44
|
}
|
|
@@ -2,6 +2,7 @@ import { sanitizeHTML } from '../sanitizeHTML';
|
|
|
2
2
|
describe('HTML Sanitization', ()=>{
|
|
3
3
|
it('removes unsupported elements from <a>', ()=>{
|
|
4
4
|
const cases = [
|
|
5
|
+
// Supported
|
|
5
6
|
{
|
|
6
7
|
input: '<h1><a href="#">Link in h1</a></h1>',
|
|
7
8
|
output: 'unchanged'
|
|
@@ -30,6 +31,7 @@ describe('HTML Sanitization', ()=>{
|
|
|
30
31
|
input: '<a href="#"><u>u in Link</u></a>',
|
|
31
32
|
output: 'unchanged'
|
|
32
33
|
},
|
|
34
|
+
// Unsupported. Should be unwrapped
|
|
33
35
|
{
|
|
34
36
|
input: '<a href="#"><h1>h1 in Link</h1><h2>this is h2</h2></a>',
|
|
35
37
|
output: '<a href="#">h1 in Link this is h2</a>'
|
|
@@ -12,20 +12,46 @@ const wrapSpaceAround = (el)=>{
|
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
14
|
const unwrap = (el)=>{
|
|
15
|
+
// add a spacer to avoid the content being cramped together with
|
|
16
|
+
// the element siblings after it's unwrapped. It may not always
|
|
17
|
+
// be desired but it should be easy to adjust by the end user.
|
|
15
18
|
wrapSpaceAround(el);
|
|
16
19
|
el.replaceWith(...Array.from(el.childNodes));
|
|
17
20
|
};
|
|
18
|
-
|
|
21
|
+
/**
|
|
22
|
+
* In HTML it's a valid structure to have a block element inside a link
|
|
23
|
+
*
|
|
24
|
+
* e.g: <a href="..."><h1> My link </h1><h2>is fancy</h2></a>
|
|
25
|
+
*
|
|
26
|
+
* However, that's not supported in Slate. There are generally two ways to
|
|
27
|
+
* handle this:
|
|
28
|
+
*
|
|
29
|
+
* a) Unwrap inner blocks while preserving the content.
|
|
30
|
+
* e.g. <a href="...">My link is fancy</a>
|
|
31
|
+
*
|
|
32
|
+
* b) Break the link into multiple elements with having each block
|
|
33
|
+
* element as a wrapper for an anchor with the same URL
|
|
34
|
+
* e.g. <h1><a href="...">My link</a></h1>
|
|
35
|
+
* and <h2><a href="...">is fancy</a></h2>
|
|
36
|
+
*
|
|
37
|
+
* We take approach (a) in here.
|
|
38
|
+
*/ export const sanitizeAnchors = (doc)=>{
|
|
19
39
|
const unsupportedTagSelector = `a :not(${[
|
|
40
|
+
// Bold
|
|
20
41
|
'b',
|
|
21
42
|
'strong',
|
|
43
|
+
// Code
|
|
22
44
|
'code',
|
|
23
45
|
'pre',
|
|
46
|
+
// Italic
|
|
24
47
|
'em',
|
|
25
48
|
'i',
|
|
49
|
+
// Super/subscript
|
|
26
50
|
'sub',
|
|
27
51
|
'sup',
|
|
52
|
+
// Underline
|
|
28
53
|
'u',
|
|
54
|
+
// Other
|
|
29
55
|
'span'
|
|
30
56
|
].join(',')})`;
|
|
31
57
|
doc.querySelectorAll(unsupportedTagSelector).forEach(unwrap);
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { sanitizeAnchors } from './sanitizeAnchors';
|
|
2
2
|
import { sanitizeSheets } from './sanitizeSheets';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Remove all <style> tags
|
|
5
|
+
*/ const stripStyleTags = (doc)=>{
|
|
4
6
|
doc.querySelectorAll('style').forEach((e)=>{
|
|
5
7
|
e.remove();
|
|
6
8
|
});
|
|
7
9
|
return doc;
|
|
8
10
|
};
|
|
9
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Remove all <meta /> tags
|
|
13
|
+
*/ const stripMetaTags = (doc)=>{
|
|
10
14
|
doc.querySelectorAll('meta').forEach((el)=>el.remove());
|
|
11
15
|
return doc;
|
|
12
16
|
};
|
|
17
|
+
// Attention: Order is important
|
|
13
18
|
const transformers = [
|
|
14
19
|
stripStyleTags,
|
|
15
20
|
sanitizeSheets,
|
|
@@ -24,17 +29,27 @@ function removeTableWrappers(table) {
|
|
|
24
29
|
}
|
|
25
30
|
}
|
|
26
31
|
export const sanitizeHTML = (html)=>{
|
|
32
|
+
// Parse the HTML string and pipe it through our transformers
|
|
27
33
|
const doc = transformers.reduce((value, cb)=>cb(value), new DOMParser().parseFromString(html, 'text/html'));
|
|
28
34
|
const replacers = [
|
|
35
|
+
// remove whitespaces between some tags, as this can lead to unwanted behaviour:
|
|
36
|
+
// - table -> empty table cells
|
|
37
|
+
// - list -> leading whitespaces
|
|
29
38
|
(innerHtml)=>innerHtml.replace(/<(\/)?(table|thead|tbody|tr|td|th|caption|col|colgroup|ol|ul|li)(.*)>\s+<(\/)?(table|thead|tbody|tr|td|th|caption|col|colgroup|ol|ul|li)/g, '<$1$2$3><$4$5'),
|
|
39
|
+
// remove empty elements before the ending block element tag
|
|
30
40
|
(innerHtml)=>innerHtml.replace(/(?:<[^>^/]*>)\s*(?:<\/[^>]*>)<\/(div|p|table|thead|tbody|tr|td|th|caption|col|colgroup|ol|ul|li)/g, '</$1'),
|
|
41
|
+
// remove whitespaces before the ending block element tag
|
|
31
42
|
(innerHTML)=>innerHTML.replace(/\s*<\/(div|p|table|thead|tbody|tr|td|th|caption|col|colgroup|ol|ul|li)/g, '</$1')
|
|
32
43
|
];
|
|
33
44
|
let previous;
|
|
34
45
|
do {
|
|
46
|
+
// save previous first before doing modifications
|
|
35
47
|
previous = doc.body.innerHTML;
|
|
36
48
|
doc.body.innerHTML = replacers.reduce((innerHTML, replacer)=>replacer(innerHTML), doc.body.innerHTML);
|
|
37
49
|
}while (doc.body.innerHTML !== previous)
|
|
50
|
+
// Removing the div container wrappers from tables
|
|
51
|
+
// The div container including attributes and possible linebreaks inside wil be removed
|
|
52
|
+
// TODO: can be removed with plate >= 20
|
|
38
53
|
doc.querySelectorAll('table').forEach(removeTableWrappers);
|
|
39
54
|
return doc.body.innerHTML;
|
|
40
55
|
};
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Remove empty spreadsheets columns/rows for performance reasons.
|
|
3
|
+
*/ export const sanitizeSheets = (doc)=>{
|
|
4
|
+
// Ensure we are inside a spreadsheet i.e. not pasting
|
|
5
|
+
// a table from within the editor
|
|
2
6
|
const supported = [
|
|
7
|
+
// Google Sheets
|
|
3
8
|
'google-sheets-html-origin',
|
|
9
|
+
// MS Excel
|
|
4
10
|
'meta[content="Excel.Sheet"]',
|
|
5
11
|
'meta[content*="Microsoft Excel"]'
|
|
6
12
|
];
|
|
@@ -12,17 +18,23 @@ export const sanitizeSheets = (doc)=>{
|
|
|
12
18
|
};
|
|
13
19
|
const tables = Array.from(doc.querySelectorAll('table'));
|
|
14
20
|
for (const table of tables){
|
|
21
|
+
// Remove empty columns first!
|
|
15
22
|
table.querySelectorAll('tr').forEach((row)=>{
|
|
16
23
|
isEmptyElement(row) && row.remove();
|
|
17
24
|
});
|
|
18
25
|
const rows = Array.from(table.querySelectorAll('tr'));
|
|
26
|
+
// CSS :nth-of-type index starts from 1
|
|
19
27
|
let colIndex = 1;
|
|
28
|
+
// eslint-disable-next-line -- TODO: explain this disable
|
|
20
29
|
while(true){
|
|
21
30
|
const cells = rows.map((row)=>row.querySelector(`th:nth-of-type(${colIndex}), td:nth-of-type(${colIndex})`)).filter((cell)=>!!cell);
|
|
31
|
+
// No more columns
|
|
22
32
|
if (cells.length === 0) {
|
|
23
33
|
break;
|
|
24
34
|
}
|
|
25
35
|
const isEmpty = cells.every((cell)=>isEmptyElement(cell));
|
|
36
|
+
// Don't increment on deletion because columns will be shifted
|
|
37
|
+
// left anyway. Incrementing may result in skipping
|
|
26
38
|
if (!isEmpty) {
|
|
27
39
|
colIndex += 1;
|
|
28
40
|
continue;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { assertOutput, jsx } from '../../../test-utils';
|
|
1
|
+
/* eslint-disable react/no-unknown-property */ /** @jsx jsx */ import { assertOutput, jsx } from '../../../test-utils';
|
|
2
2
|
describe('normalization', ()=>{
|
|
3
3
|
it('can contain inline entries & hyperlinks', ()=>{
|
|
4
|
-
const input = jsx("editor", null, jsx("hquote", null, jsx("hp", null, "some text before", jsx("hinline", {
|
|
4
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "some text before", /*#__PURE__*/ jsx("hinline", {
|
|
5
5
|
type: "Entry",
|
|
6
6
|
id: "inline-entry"
|
|
7
|
-
}), jsx("hlink", {
|
|
7
|
+
}), /*#__PURE__*/ jsx("hlink", {
|
|
8
8
|
uri: "https://contentful.com"
|
|
9
|
-
}), jsx("hlink", {
|
|
9
|
+
}), /*#__PURE__*/ jsx("hlink", {
|
|
10
10
|
entry: "entry-id"
|
|
11
|
-
}), jsx("hlink", {
|
|
11
|
+
}), /*#__PURE__*/ jsx("hlink", {
|
|
12
12
|
resource: "resource-urn"
|
|
13
|
-
}), jsx("hlink", {
|
|
13
|
+
}), /*#__PURE__*/ jsx("hlink", {
|
|
14
14
|
asset: "asset-id"
|
|
15
15
|
}), "some text after")));
|
|
16
16
|
assertOutput({
|
|
@@ -19,16 +19,16 @@ describe('normalization', ()=>{
|
|
|
19
19
|
});
|
|
20
20
|
});
|
|
21
21
|
it('unwraps nested quotes', ()=>{
|
|
22
|
-
const input = jsx("editor", null, jsx("hquote", null, jsx("hp", null, "some"), jsx("hquote", null, jsx("hp", null, jsx("htext", {
|
|
22
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "some"), /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("htext", {
|
|
23
23
|
bold: true,
|
|
24
24
|
italic: true,
|
|
25
25
|
underline: true
|
|
26
|
-
}, "paragraph"))), jsx("hp", null, "text")));
|
|
27
|
-
const expected = jsx("editor", null, jsx("hquote", null, jsx("hp", null, "some"), jsx("hp", null, jsx("htext", {
|
|
26
|
+
}, "paragraph"))), /*#__PURE__*/ jsx("hp", null, "text")));
|
|
27
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "some"), /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("htext", {
|
|
28
28
|
bold: true,
|
|
29
29
|
italic: true,
|
|
30
30
|
underline: true
|
|
31
|
-
}, "paragraph")), jsx("hp", null, "text")), jsx("hp", null, jsx("htext", null)));
|
|
31
|
+
}, "paragraph")), /*#__PURE__*/ jsx("hp", null, "text")), /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("htext", null)));
|
|
32
32
|
assertOutput({
|
|
33
33
|
input,
|
|
34
34
|
expected
|
|
@@ -36,37 +36,37 @@ describe('normalization', ()=>{
|
|
|
36
36
|
});
|
|
37
37
|
describe('lifts other invalid children', ()=>{
|
|
38
38
|
it('block void elements', ()=>{
|
|
39
|
-
const input = jsx("editor", null, jsx("hquote", null, jsx("hp", null, "this"), jsx("hembed", {
|
|
39
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "this"), /*#__PURE__*/ jsx("hembed", {
|
|
40
40
|
type: "Asset",
|
|
41
41
|
id: "1"
|
|
42
|
-
}), jsx("hp", null, "is"), jsx("hembed", {
|
|
42
|
+
}), /*#__PURE__*/ jsx("hp", null, "is"), /*#__PURE__*/ jsx("hembed", {
|
|
43
43
|
type: "Entry",
|
|
44
44
|
id: "1"
|
|
45
|
-
}), jsx("hp", null, "a blockquote"), jsx("hhr", null), jsx("hh1", null, "Heading 1")));
|
|
46
|
-
const expected = jsx("editor", null, jsx("hquote", null, jsx("hp", null, "this")), jsx("hembed", {
|
|
45
|
+
}), /*#__PURE__*/ jsx("hp", null, "a blockquote"), /*#__PURE__*/ jsx("hhr", null), /*#__PURE__*/ jsx("hh1", null, "Heading 1")));
|
|
46
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "this")), /*#__PURE__*/ jsx("hembed", {
|
|
47
47
|
type: "Asset",
|
|
48
48
|
id: "1"
|
|
49
|
-
}), jsx("hquote", null, jsx("hp", null, "is")), jsx("hembed", {
|
|
49
|
+
}), /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "is")), /*#__PURE__*/ jsx("hembed", {
|
|
50
50
|
type: "Entry",
|
|
51
51
|
id: "1"
|
|
52
|
-
}), jsx("hquote", null, jsx("hp", null, "a blockquote")), jsx("hhr", null), jsx("hh1", null, "Heading 1"), jsx("hp", null, jsx("text", null)));
|
|
52
|
+
}), /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "a blockquote")), /*#__PURE__*/ jsx("hhr", null), /*#__PURE__*/ jsx("hh1", null, "Heading 1"), /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("text", null)));
|
|
53
53
|
assertOutput({
|
|
54
54
|
input,
|
|
55
55
|
expected
|
|
56
56
|
});
|
|
57
57
|
});
|
|
58
58
|
it('handles lists', ()=>{
|
|
59
|
-
const input = jsx("editor", null, jsx("hquote", null, jsx("hp", null, "some", jsx("hul", null, jsx("hli", null, jsx("hp", null, "list item"))), "text")));
|
|
60
|
-
const expected = jsx("editor", null, jsx("hquote", null, jsx("hp", null, "some")), jsx("hul", null, jsx("hli", null, jsx("hp", null, "list item"))), jsx("hquote", null, jsx("hp", null, "text")), jsx("hp", null, jsx("text", null)));
|
|
59
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "some", /*#__PURE__*/ jsx("hul", null, /*#__PURE__*/ jsx("hli", null, /*#__PURE__*/ jsx("hp", null, "list item"))), "text")));
|
|
60
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "some")), /*#__PURE__*/ jsx("hul", null, /*#__PURE__*/ jsx("hli", null, /*#__PURE__*/ jsx("hp", null, "list item"))), /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "text")), /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("text", null)));
|
|
61
61
|
assertOutput({
|
|
62
62
|
input,
|
|
63
63
|
expected
|
|
64
64
|
});
|
|
65
65
|
});
|
|
66
66
|
it('handles tables', ()=>{
|
|
67
|
-
const table = jsx("htable", null, jsx("htr", null, jsx("htd", null, jsx("hp", null, "cell 1")), jsx("htd", null, jsx("hp", null, "cell 2"))));
|
|
68
|
-
const input = jsx("editor", null, jsx("hquote", null, jsx("hp", null, "some", table, "text")));
|
|
69
|
-
const expected = jsx("editor", null, jsx("hquote", null, jsx("hp", null, "some")), table, jsx("hquote", null, jsx("hp", null, "text")), jsx("hp", null, jsx("text", null)));
|
|
67
|
+
const table = /*#__PURE__*/ jsx("htable", null, /*#__PURE__*/ jsx("htr", null, /*#__PURE__*/ jsx("htd", null, /*#__PURE__*/ jsx("hp", null, "cell 1")), /*#__PURE__*/ jsx("htd", null, /*#__PURE__*/ jsx("hp", null, "cell 2"))));
|
|
68
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "some", table, "text")));
|
|
69
|
+
const expected = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "some")), table, /*#__PURE__*/ jsx("hquote", null, /*#__PURE__*/ jsx("hp", null, "text")), /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("text", null)));
|
|
70
70
|
assertOutput({
|
|
71
71
|
input,
|
|
72
72
|
expected
|