From 5ada460517ae52c20ad22acf4e9a67f2c86d3390 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Thu, 24 Apr 2025 13:00:51 +0200 Subject: [PATCH 1/4] Made default props on default blocks get rendered to inline styles for lossy HTML --- .../html/util/serializeBlocksExternalHTML.ts | 20 +++++++++++++ .../core/src/blocks/defaultBlockHelpers.ts | 28 +++++++++++++++++-- packages/core/src/schema/blocks/internal.ts | 3 +- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/packages/core/src/api/exporters/html/util/serializeBlocksExternalHTML.ts b/packages/core/src/api/exporters/html/util/serializeBlocksExternalHTML.ts index 4c57dcccd..851caf2dd 100644 --- a/packages/core/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +++ b/packages/core/src/api/exporters/html/util/serializeBlocksExternalHTML.ts @@ -142,6 +142,15 @@ function serializeBlock< if (ret.dom.classList.contains("bn-block-content")) { if (!listType) { + // TODO: This is specifically for default blocks, as default props get + // rendered out to inline styles instead of `data-*` attributes for + // external HTML. Will need to revisit this when we convert default + // blocks to use the custom block API. + const style = ret.dom.getAttribute("style"); + if (style) { + (ret.dom.firstChild! as HTMLElement).setAttribute("style", style); + } + for (const attr of blockContentDataAttributes) { (ret.dom.firstChild! as HTMLElement).setAttribute( attr.name, @@ -177,9 +186,20 @@ function serializeBlock< fragment.append(list); } const li = doc.createElement("li"); + + // TODO: This is specifically for default blocks, as default props get + // rendered out to inline styles instead of `data-*` attributes for + // external HTML. Will need to revisit this when we convert default + // blocks to use the custom block API. + const style = ret.dom.getAttribute("style"); + if (style) { + li.setAttribute("style", style); + } + for (const attr of blockContentDataAttributes) { li.setAttribute(attr.name, attr.value); } + li.append(elementFragment); fragment.lastChild!.appendChild(li); } else { diff --git a/packages/core/src/blocks/defaultBlockHelpers.ts b/packages/core/src/blocks/defaultBlockHelpers.ts index fbba956c8..295f06d70 100644 --- a/packages/core/src/blocks/defaultBlockHelpers.ts +++ b/packages/core/src/blocks/defaultBlockHelpers.ts @@ -55,14 +55,17 @@ export function createDefaultBlockDOMOutputSpec( // Function used to convert default blocks to HTML. It uses the corresponding // node's `renderHTML` method to do the conversion by using a default -// `DOMSerializer`. +// `DOMSerializer`. The `external` flag is used to modify the resulting HTML for +// external use. This just involves changing props being rendered from `data-*` +// attributes to inline styles. export const defaultBlockToHTML = < BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema >( block: BlockNoDefaults, - editor: BlockNoteEditor + editor: BlockNoteEditor, + external = false ): { dom: HTMLElement; contentDOM?: HTMLElement; @@ -90,6 +93,27 @@ export const defaultBlockToHTML = < ); } + // TODO: This is obviously pretty hacky - will need to revisit this when we + // convert default blocks to use the custom block API. + if (external) { + const dom = renderSpec.dom as HTMLElement; + + if (dom.hasAttribute("data-background-color")) { + dom.style.backgroundColor = dom.getAttribute("data-background-color")!; + dom.removeAttribute("data-background-color"); + } + + if (dom.hasAttribute("data-text-color")) { + dom.style.color = dom.getAttribute("data-text-color")!; + dom.removeAttribute("data-text-color"); + } + + if (dom.hasAttribute("data-text-alignment")) { + dom.style.textAlign = dom.getAttribute("data-text-alignment")!; + dom.removeAttribute("data-text-alignment"); + } + } + return renderSpec as { dom: HTMLElement; contentDOM?: HTMLElement; diff --git a/packages/core/src/schema/blocks/internal.ts b/packages/core/src/schema/blocks/internal.ts index 9669f3db9..bbbb75b44 100644 --- a/packages/core/src/schema/blocks/internal.ts +++ b/packages/core/src/schema/blocks/internal.ts @@ -267,7 +267,8 @@ export function createBlockSpecFromStronglyTypedTiptapNode< node, requiredExtensions, toInternalHTML: defaultBlockToHTML, - toExternalHTML: defaultBlockToHTML, + toExternalHTML: (block, editor) => + defaultBlockToHTML(block, editor, true), // parse: () => undefined, // parse rules are in node already } ); From f98ac806e83bdbb021f82badcbec0158b9642419 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Thu, 24 Apr 2025 15:53:51 +0200 Subject: [PATCH 2/4] Updated unit test snapshots --- .../ServerBlockNoteEditor.test.ts.snap | 2 +- .../text/html/basicBlocksWithProps.html | 4 ++-- .../__snapshots__/html/complex/misc.html | 4 ++-- .../__snapshots__/html/paragraph/styled.html | 6 +----- .../html/contextParagraph/basic.html | 2 +- .../html/customParagraph/basic.html | 2 +- .../html/customParagraph/lineBreaks.html | 2 +- .../html/customParagraph/nested.html | 6 +++--- .../html/customParagraph/styled.html | 1 + .../html/simpleCustomParagraph/basic.html | 6 +++++- .../html/simpleCustomParagraph/nested.html | 18 +++++++++++++++--- .../html/simpleCustomParagraph/styled.html | 1 + 12 files changed, 34 insertions(+), 20 deletions(-) diff --git a/packages/server-util/src/context/__snapshots__/ServerBlockNoteEditor.test.ts.snap b/packages/server-util/src/context/__snapshots__/ServerBlockNoteEditor.test.ts.snap index 7a991c453..f46f75260 100644 --- a/packages/server-util/src/context/__snapshots__/ServerBlockNoteEditor.test.ts.snap +++ b/packages/server-util/src/context/__snapshots__/ServerBlockNoteEditor.test.ts.snap @@ -2,7 +2,7 @@ exports[`Test ServerBlockNoteEditor > converts to HTML (blocksToFullHTML) 1`] = `"

Heading 2

Paragraph

list item

Example

Caption

Example

Caption

"`; -exports[`Test ServerBlockNoteEditor > converts to and from HTML (blocksToHTMLLossy) 1`] = `"

Heading 2

Paragraph

  • list item

Example
Caption
Example

Caption

"`; +exports[`Test ServerBlockNoteEditor > converts to and from HTML (blocksToHTMLLossy) 1`] = `"

Heading 2

Paragraph

  • list item

Example
Caption
Example

Caption

"`; exports[`Test ServerBlockNoteEditor > converts to and from HTML (blocksToHTMLLossy) 2`] = ` [ diff --git a/tests/src/unit/core/clipboard/copy/__snapshots__/text/html/basicBlocksWithProps.html b/tests/src/unit/core/clipboard/copy/__snapshots__/text/html/basicBlocksWithProps.html index 76545d350..ee9982245 100644 --- a/tests/src/unit/core/clipboard/copy/__snapshots__/text/html/basicBlocksWithProps.html +++ b/tests/src/unit/core/clipboard/copy/__snapshots__/text/html/basicBlocksWithProps.html @@ -1,4 +1,4 @@ -

Paragraph 1

+

Paragraph 1

Heading 1

  1. @@ -6,7 +6,7 @@

    Heading 1

    -
  • +
  • Bullet List Item 1

  • diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/html/complex/misc.html b/tests/src/unit/core/formatConversion/export/__snapshots__/html/complex/misc.html index 0df8a1834..c0ad01bcb 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/html/complex/misc.html +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/html/complex/misc.html @@ -1,4 +1,4 @@ -

    +

    Heading @@ -6,7 +6,7 @@

    Paragraph

    +

    Paragraph

    • diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/html/paragraph/styled.html b/tests/src/unit/core/formatConversion/export/__snapshots__/html/paragraph/styled.html index 65e55c08b..0768a9c8c 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/html/paragraph/styled.html +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/html/paragraph/styled.html @@ -1,8 +1,4 @@ -

      +

      Plain Red Text Blue Background diff --git a/tests/src/unit/react/formatConversion/export/__snapshots__/html/contextParagraph/basic.html b/tests/src/unit/react/formatConversion/export/__snapshots__/html/contextParagraph/basic.html index ca43744a1..f7b852f0f 100644 --- a/tests/src/unit/react/formatConversion/export/__snapshots__/html/contextParagraph/basic.html +++ b/tests/src/unit/react/formatConversion/export/__snapshots__/html/contextParagraph/basic.html @@ -1 +1 @@ -

      React Context Paragraph
      \ No newline at end of file +
      React Context Paragraph
      \ No newline at end of file diff --git a/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/basic.html b/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/basic.html index 2971f1105..ff100b250 100644 --- a/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/basic.html +++ b/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/basic.html @@ -1 +1 @@ -

      Hello World

      \ No newline at end of file +

      Hello World

      \ No newline at end of file diff --git a/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/lineBreaks.html b/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/lineBreaks.html index 2971f1105..ff100b250 100644 --- a/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/lineBreaks.html +++ b/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/lineBreaks.html @@ -1 +1 @@ -

      Hello World

      \ No newline at end of file +

      Hello World

      \ No newline at end of file diff --git a/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/nested.html b/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/nested.html index 6b2e1554c..863e2204e 100644 --- a/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/nested.html +++ b/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/nested.html @@ -1,3 +1,3 @@ -

      Hello World

      -

      Hello World

      -

      Hello World

      \ No newline at end of file +

      Hello World

      +

      Hello World

      +

      Hello World

      \ No newline at end of file diff --git a/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/styled.html b/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/styled.html index 7e7e60707..962c4cea9 100644 --- a/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/styled.html +++ b/tests/src/unit/react/formatConversion/export/__snapshots__/html/customParagraph/styled.html @@ -1,5 +1,6 @@

      React Custom Paragraph

      \ No newline at end of file +

      React Custom Paragraph

      \ No newline at end of file diff --git a/tests/src/unit/react/formatConversion/export/__snapshots__/html/simpleCustomParagraph/nested.html b/tests/src/unit/react/formatConversion/export/__snapshots__/html/simpleCustomParagraph/nested.html index 68e209191..677ec39d3 100644 --- a/tests/src/unit/react/formatConversion/export/__snapshots__/html/simpleCustomParagraph/nested.html +++ b/tests/src/unit/react/formatConversion/export/__snapshots__/html/simpleCustomParagraph/nested.html @@ -1,3 +1,15 @@ -

      Custom React Paragraph

      -

      Nested React Custom Paragraph 1

      -

      Nested React Custom Paragraph 2

      \ No newline at end of file +

      Custom React Paragraph

      +

      Nested React Custom Paragraph 1

      +

      Nested React Custom Paragraph 2

      \ No newline at end of file diff --git a/tests/src/unit/react/formatConversion/export/__snapshots__/html/simpleCustomParagraph/styled.html b/tests/src/unit/react/formatConversion/export/__snapshots__/html/simpleCustomParagraph/styled.html index aff3d3abc..4d0b88207 100644 --- a/tests/src/unit/react/formatConversion/export/__snapshots__/html/simpleCustomParagraph/styled.html +++ b/tests/src/unit/react/formatConversion/export/__snapshots__/html/simpleCustomParagraph/styled.html @@ -1,6 +1,7 @@

      Date: Fri, 25 Apr 2025 14:03:11 +0200 Subject: [PATCH 3/4] Implemented PR feedback --- .../html/util/serializeBlocksExternalHTML.ts | 28 +- .../core/src/blocks/defaultBlockHelpers.ts | 56 ++- packages/core/src/blocks/defaultProps.ts | 18 + .../text/html/basicBlocksWithProps.html | 8 +- .../__snapshots__/html/complex/misc.html | 6 +- .../__snapshots__/html/paragraph/styled.html | 4 +- .../html/backgroundColorProp.json | 23 +- .../html/backgroundColorStyle.json | 16 +- .../__snapshots__/html/textColorProp.json | 23 +- .../__snapshots__/html/textColorStyle.json | 16 +- .../parse/parseTestInstances.ts | 464 +++++++++--------- 11 files changed, 341 insertions(+), 321 deletions(-) diff --git a/packages/core/src/api/exporters/html/util/serializeBlocksExternalHTML.ts b/packages/core/src/api/exporters/html/util/serializeBlocksExternalHTML.ts index c3084bbae..a39c2d7b9 100644 --- a/packages/core/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +++ b/packages/core/src/api/exporters/html/util/serializeBlocksExternalHTML.ts @@ -144,15 +144,19 @@ function serializeBlock< // We wrap the output in an `li` element for list items, and so we want to // add the attributes to that element instead as it is the "root". if (!listType) { - // TODO: This is specifically for default blocks, as default props get - // rendered out to inline styles instead of `data-*` attributes for - // external HTML. Will need to revisit this when we convert default - // blocks to use the custom block API. + // Copies the styles and prop-related attributes from the `blockContent` + // element onto its first child, as the `blockContent` element is omitted + // from external HTML. This is so prop data is preserved via `data-*` + // attributes or inline styles. + // + // The styles are specifically for default props on default blocks, as + // they get converted from `data-*` attributes for external HTML. Will + // need to revisit this when we convert default blocks to use the custom + // block API. const style = ret.dom.getAttribute("style"); if (style) { (ret.dom.firstChild! as HTMLElement).setAttribute("style", style); } - for (const attr of blockContentDataAttributes) { (ret.dom.firstChild! as HTMLElement).setAttribute( attr.name, @@ -189,15 +193,19 @@ function serializeBlock< } const li = doc.createElement("li"); - // TODO: This is specifically for default blocks, as default props get - // rendered out to inline styles instead of `data-*` attributes for - // external HTML. Will need to revisit this when we convert default - // blocks to use the custom block API. + // Copies the styles and prop-related attributes from the `blockContent` + // element onto its first child, as the `blockContent` element is omitted + // from external HTML. This is so prop data is preserved via `data-*` + // attributes or inline styles. + // + // The styles are specifically for default props on default blocks, as + // they get converted from `data-*` attributes for external HTML. Will + // need to revisit this when we convert default blocks to use the custom + // block API. const style = ret.dom.getAttribute("style"); if (style) { li.setAttribute("style", style); } - for (const attr of blockContentDataAttributes) { li.setAttribute(attr.name, attr.value); } diff --git a/packages/core/src/blocks/defaultBlockHelpers.ts b/packages/core/src/blocks/defaultBlockHelpers.ts index 295f06d70..b8220e310 100644 --- a/packages/core/src/blocks/defaultBlockHelpers.ts +++ b/packages/core/src/blocks/defaultBlockHelpers.ts @@ -1,5 +1,6 @@ import { blockToNode } from "../api/nodeConversions/blockToNode.js"; import type { BlockNoteEditor } from "../editor/BlockNoteEditor.js"; +import { COLORS_DEFAULT } from "../editor/defaultColors.js"; import type { BlockNoDefaults, BlockSchema, @@ -93,18 +94,58 @@ export const defaultBlockToHTML = < ); } - // TODO: This is obviously pretty hacky - will need to revisit this when we - // convert default blocks to use the custom block API. + // When exporting to external HTML, we convert from `data-*` attributes to + // inline styles properties which can be understood by external applications. + // + // Note: This is a bit hacky to do this here as we're just hardcoding this for + // props on default blocks. We should revisit this when we migrate internal + // blocks to use the custom blocks API. if (external) { const dom = renderSpec.dom as HTMLElement; if (dom.hasAttribute("data-background-color")) { - dom.style.backgroundColor = dom.getAttribute("data-background-color")!; + const backgroundColor = dom.getAttribute("data-background-color")!; + + // If the background color is one of the default colors, we set the + // color's hex code from the default theme, as this will look nicer than + // using regular CSS colors. For example, instead of + // `background-color: red`, we use `background-color: #fbe4e4`. + if (backgroundColor in COLORS_DEFAULT) { + const cssVariableName = + `--blocknote-background-${backgroundColor}` as any; + + dom.style.setProperty( + cssVariableName, + COLORS_DEFAULT[backgroundColor as keyof typeof COLORS_DEFAULT] + .background + ); + dom.style.backgroundColor = `var(${cssVariableName})`; + } else { + dom.style.backgroundColor = backgroundColor; + } + dom.removeAttribute("data-background-color"); } if (dom.hasAttribute("data-text-color")) { - dom.style.color = dom.getAttribute("data-text-color")!; + const textColor = dom.getAttribute("data-text-color")!; + + // If the text color is one of the default colors, we set the color's hex + // code from the default theme, as this will look nicer than using regular + // CSS colors. For example, instead of `color: red`, we use + // `color: #e03e3e`. + if (textColor in COLORS_DEFAULT) { + const cssVariableName = `--blocknote-text-${textColor}` as any; + + dom.style.setProperty( + cssVariableName, + COLORS_DEFAULT[textColor as keyof typeof COLORS_DEFAULT].text + ); + dom.style.color = `var(${cssVariableName})`; + } else { + dom.style.color = textColor; + } + dom.removeAttribute("data-text-color"); } @@ -112,6 +153,13 @@ export const defaultBlockToHTML = < dom.style.textAlign = dom.getAttribute("data-text-alignment")!; dom.removeAttribute("data-text-alignment"); } + + // We also remove the `data-level` attribute for heading blocks, as this + // information can be inferred from whether a `h1`, `h2`, or `h3 tag is + // used. + if (dom.hasAttribute("data-level")) { + dom.removeAttribute("data-level"); + } } return renderSpec as { diff --git a/packages/core/src/blocks/defaultProps.ts b/packages/core/src/blocks/defaultProps.ts index a524b19a9..44193cd01 100644 --- a/packages/core/src/blocks/defaultProps.ts +++ b/packages/core/src/blocks/defaultProps.ts @@ -30,6 +30,16 @@ const getBackgroundColorAttribute = ( } if (element.style.backgroundColor) { + // Check if `element.style.backgroundColor` matches the string: + // `var(--blocknote-background-)`. If it does, return the color + // name only. Otherwise, return `element.style.backgroundColor`. + const match = element.style.backgroundColor.match( + /var\(--blocknote-background-(.+)\)/ + ); + if (match) { + return match[1]; + } + return element.style.backgroundColor; } @@ -54,6 +64,14 @@ const getTextColorAttribute = (attributeName = "textColor"): Attribute => ({ } if (element.style.color) { + // Check if `element.style.color` matches the string: + // `var(--blocknote-text-)`. If it does, return the color name + // only. Otherwise, return `element.style.color`. + const match = element.style.color.match(/var\(--blocknote-text-(.+)\)/); + if (match) { + return match[1]; + } + return element.style.color; } diff --git a/tests/src/unit/core/clipboard/copy/__snapshots__/text/html/basicBlocksWithProps.html b/tests/src/unit/core/clipboard/copy/__snapshots__/text/html/basicBlocksWithProps.html index ee9982245..5c496bbf0 100644 --- a/tests/src/unit/core/clipboard/copy/__snapshots__/text/html/basicBlocksWithProps.html +++ b/tests/src/unit/core/clipboard/copy/__snapshots__/text/html/basicBlocksWithProps.html @@ -1,12 +1,14 @@ -

      Paragraph 1

      -

      Heading 1

      +

      Paragraph 1

      +

      Heading 1

      1. Numbered List Item 1

        -
      • +
      • Bullet List Item 1

      • diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/html/complex/misc.html b/tests/src/unit/core/formatConversion/export/__snapshots__/html/complex/misc.html index c0ad01bcb..a5fd6fe7e 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/html/complex/misc.html +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/html/complex/misc.html @@ -1,4 +1,4 @@ -

        +

        Heading @@ -6,7 +6,9 @@

        2

        -

        Paragraph

        +

        Paragraph

        • diff --git a/tests/src/unit/core/formatConversion/export/__snapshots__/html/paragraph/styled.html b/tests/src/unit/core/formatConversion/export/__snapshots__/html/paragraph/styled.html index 0768a9c8c..032aa7b89 100644 --- a/tests/src/unit/core/formatConversion/export/__snapshots__/html/paragraph/styled.html +++ b/tests/src/unit/core/formatConversion/export/__snapshots__/html/paragraph/styled.html @@ -1,4 +1,6 @@ -

          +

          Plain Red Text Blue Background diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/backgroundColorProp.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/backgroundColorProp.json index f2ebc5ed9..15f5d0729 100644 --- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/backgroundColorProp.json +++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/backgroundColorProp.json @@ -4,30 +4,13 @@ "content": [ { "styles": {}, - "text": "Red Background", + "text": "Blue Background", "type": "text", }, ], "id": "1", "props": { - "backgroundColor": "red", - "textAlignment": "left", - "textColor": "default", - }, - "type": "paragraph", - }, - { - "children": [], - "content": [ - { - "styles": {}, - "text": "Green Background", - "type": "text", - }, - ], - "id": "2", - "props": { - "backgroundColor": "green", + "backgroundColor": "blue", "textAlignment": "left", "textColor": "default", }, @@ -42,7 +25,7 @@ "type": "text", }, ], - "id": "3", + "id": "2", "props": { "backgroundColor": "blue", "textAlignment": "left", diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/backgroundColorStyle.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/backgroundColorStyle.json index 0f1dfc15e..8afe915ba 100644 --- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/backgroundColorStyle.json +++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/backgroundColorStyle.json @@ -4,21 +4,9 @@ "content": [ { "styles": { - "backgroundColor": "red", - }, - "text": "Red Background", - "type": "text", - }, - { - "styles": {}, - "text": " ", - "type": "text", - }, - { - "styles": { - "backgroundColor": "green", + "backgroundColor": "blue", }, - "text": "Green Background", + "text": "Blue Background", "type": "text", }, { diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/textColorProp.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/textColorProp.json index 7480fcab3..4211362bf 100644 --- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/textColorProp.json +++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/textColorProp.json @@ -4,7 +4,7 @@ "content": [ { "styles": {}, - "text": "Red Paragraph", + "text": "Blue Text", "type": "text", }, ], @@ -12,7 +12,7 @@ "props": { "backgroundColor": "default", "textAlignment": "left", - "textColor": "red", + "textColor": "blue", }, "type": "paragraph", }, @@ -21,28 +21,11 @@ "content": [ { "styles": {}, - "text": "Green Paragraph", + "text": "Blue Text", "type": "text", }, ], "id": "2", - "props": { - "backgroundColor": "default", - "textAlignment": "left", - "textColor": "green", - }, - "type": "paragraph", - }, - { - "children": [], - "content": [ - { - "styles": {}, - "text": "Blue Paragraph", - "type": "text", - }, - ], - "id": "3", "props": { "backgroundColor": "default", "textAlignment": "left", diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/textColorStyle.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/textColorStyle.json index faeeee527..e78e1a4b3 100644 --- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/textColorStyle.json +++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/textColorStyle.json @@ -4,21 +4,9 @@ "content": [ { "styles": { - "textColor": "red", - }, - "text": "Red Text", - "type": "text", - }, - { - "styles": {}, - "text": " ", - "type": "text", - }, - { - "styles": { - "textColor": "green", + "textColor": "blue", }, - "text": "Green Text", + "text": "Blue Text", "type": "text", }, { diff --git a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts index 375bfd098..fb65ccccd 100644 --- a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts +++ b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts @@ -20,11 +20,11 @@ export const parseTestInstancesHTML: TestInstance< testCase: { name: "basicBlockTypes", content: `

          Heading 1

          -

          Heading 2

          -

          Heading 3

          -

          Paragraph

          -
          Image Caption
          -

          None Bold Italic Underline Strikethrough All

          `, +

          Heading 2

          +

          Heading 3

          +

          Paragraph

          +
          Image Caption
          +

          None Bold Italic Underline Strikethrough All

          `, }, executeTest: testParseHTML, }, @@ -32,82 +32,82 @@ export const parseTestInstancesHTML: TestInstance< testCase: { name: "lists", content: `
            -
          • First
          • -
          • Second
          • -
          • Third
          • -
          • - - Fourth -
          • -
          • - - Fifth -
          • -
          • Five Parent -
              -
            • Child 1
            • -
            • Child 2
            • -
            • - - Child 3 -
            • -
            • - - Child 4 -
            • -
            -
          • -
          `, - }, - executeTest: testParseHTML, - }, - { - testCase: { - name: "nestedLists", - content: `
            -
          • Bullet List Item
          • -
          • Bullet List Item -
              -
            • Nested Bullet List Item
            • -
            • Nested Bullet List Item
            • -
            -
          • -
          • Bullet List Item
          • -
          -
            -
          1. Numbered List Item
          2. -
          3. Numbered List Item -
              -
            1. Nested Numbered List Item
            2. -
            3. Nested Numbered List Item
            4. -
            -
          4. -
          5. Numbered List Item
          6. -
          -
            +
          • First
          • +
          • Second
          • +
          • Third
          • - Check List Item + Fourth
          • - Check List Item + Fifth +
          • +
          • Five Parent
              +
            • Child 1
            • +
            • Child 2
            • - Nested Check List Item + Child 3
            • - Nested Check List Item + Child 4
          • -
          • - - Nested Check List Item -
          • -
          `, +
        `, + }, + executeTest: testParseHTML, + }, + { + testCase: { + name: "nestedLists", + content: `
          +
        • Bullet List Item
        • +
        • Bullet List Item +
            +
          • Nested Bullet List Item
          • +
          • Nested Bullet List Item
          • +
          +
        • +
        • Bullet List Item
        • +
        +
          +
        1. Numbered List Item
        2. +
        3. Numbered List Item +
            +
          1. Nested Numbered List Item
          2. +
          3. Nested Numbered List Item
          4. +
          +
        4. +
        5. Numbered List Item
        6. +
        +
          +
        • + + Check List Item +
        • +
        • + + Check List Item +
            +
          • + + Nested Check List Item +
          • +
          • + + Nested Check List Item +
          • +
          +
        • +
        • + + Nested Check List Item +
        • +
        `, }, executeTest: testParseHTML, }, @@ -115,67 +115,67 @@ export const parseTestInstancesHTML: TestInstance< testCase: { name: "nestedListsWithParagraphs", content: `
          -
        • -

          Bullet List Item

          -
        • -
        • -

          Bullet List Item

          -
            -
          • -

            Nested Bullet List Item

            -
          • -
          • -

            Nested Bullet List Item

            -
          • -
          -
        • -
        • -

          Bullet List Item

          -
        • -
        -
          -
        1. -

          Numbered List Item

          -
        2. -
        3. -

          Numbered List Item

          -
            -
          1. -

            Nested Numbered List Item

            -
          2. -
          3. -

            Nested Numbered List Item

            -
          4. -
          -
        4. -
        5. -

          Numbered List Item

          -
        6. -
        -
          -
        • - -

          Checked List Item

          -
        • -
        • - -

          Checked List Item

          -
            -
          • - -

            Nested Checked List Item

            -
          • -
          • - -

            Nested Checked List Item

            -
          • -
          -
        • -
        • - -

          Checked List Item

          -
        • -
        `, +
      • +

        Bullet List Item

        +
      • +
      • +

        Bullet List Item

        +
          +
        • +

          Nested Bullet List Item

          +
        • +
        • +

          Nested Bullet List Item

          +
        • +
        +
      • +
      • +

        Bullet List Item

        +
      • +
      +
        +
      1. +

        Numbered List Item

        +
      2. +
      3. +

        Numbered List Item

        +
          +
        1. +

          Nested Numbered List Item

          +
        2. +
        3. +

          Nested Numbered List Item

          +
        4. +
        +
      4. +
      5. +

        Numbered List Item

        +
      6. +
      +
        +
      • + +

        Checked List Item

        +
      • +
      • + +

        Checked List Item

        +
          +
        • + +

          Nested Checked List Item

          +
        • +
        • + +

          Nested Checked List Item

          +
        • +
        +
      • +
      • + +

        Checked List Item

        +
      • +
      `, }, executeTest: testParseHTML, }, @@ -183,49 +183,49 @@ export const parseTestInstancesHTML: TestInstance< testCase: { name: "mixedNestedLists", content: `
        -
      • Bullet List Item
      • -
      • Bullet List Item -
          -
        1. Nested Numbered List Item
        2. -
        3. Nested Numbered List Item
        4. -
        -
      • -
      • Bullet List Item
      • -
      -
        -
      1. Numbered List Item
      2. -
      3. Numbered List Item -
          -
        • - - Nested Check List Item -
        • -
        • - - Nested Check List Item -
        • -
        -
      4. -
      5. Numbered List Item
      6. -
      -
        -
      • - - Check List Item -
      • -
      • - - Check List Item -
          -
        • Nested Bullet List Item
        • -
        • Nested Bullet List Item
        • -
        -
      • -
      • - - Nested Check List Item -
      • -
      `, +
    • Bullet List Item
    • +
    • Bullet List Item +
        +
      1. Nested Numbered List Item
      2. +
      3. Nested Numbered List Item
      4. +
      +
    • +
    • Bullet List Item
    • +
    +
      +
    1. Numbered List Item
    2. +
    3. Numbered List Item +
        +
      • + + Nested Check List Item +
      • +
      • + + Nested Check List Item +
      • +
      +
    4. +
    5. Numbered List Item
    6. +
    +
      +
    • + + Check List Item +
    • +
    • + + Check List Item +
        +
      • Nested Bullet List Item
      • +
      • Nested Bullet List Item
      • +
      +
    • +
    • + + Nested Check List Item +
    • +
    `, }, executeTest: testParseHTML, }, @@ -233,16 +233,16 @@ export const parseTestInstancesHTML: TestInstance< testCase: { name: "divs", content: `
    Single Div
    -
    - Div -
    Nested Div
    -
    Nested Div
    -
    -
    Single Div 2
    -
    -
    Nested Div
    -
    Nested Div
    -
    `, +
    + Div +
    Nested Div
    +
    Nested Div
    +
    +
    Single Div 2
    +
    +
    Nested Div
    +
    Nested Div
    +
    `, }, executeTest: testParseHTML, }, @@ -257,8 +257,8 @@ export const parseTestInstancesHTML: TestInstance< testCase: { name: "imageInParagraph", content: `

    - -

    `, + +

    `, }, executeTest: testParseHTML, }, @@ -266,9 +266,9 @@ export const parseTestInstancesHTML: TestInstance< testCase: { name: "fakeImageCaption", content: `
    - -

    Image Caption

    -
    `, + +

    Image Caption

    + `, }, executeTest: testParseHTML, }, @@ -276,27 +276,27 @@ export const parseTestInstancesHTML: TestInstance< testCase: { name: "deepNestedContent", content: `
    - Outer 1 Div Before -
    - Outer 2 Div Before + Outer 1 Div Before
    - Outer 3 Div Before + Outer 2 Div Before
    - Outer 4 Div Before -

    Heading 1

    -

    Heading 2

    -

    Heading 3

    -

    Paragraph

    -
    Image Caption
    -

    Bold Italic Underline Strikethrough All

    - Outer 4 Div After + Outer 3 Div Before +
    + Outer 4 Div Before +

    Heading 1

    +

    Heading 2

    +

    Heading 3

    +

    Paragraph

    +
    Image Caption
    +

    Bold Italic Underline Strikethrough All

    + Outer 4 Div After +
    + Outer 3 Div After
    - Outer 3 Div After + Outer 2 Div After
    - Outer 2 Div After -
    - Outer 1 Div After -
    `, + Outer 1 Div After + `, }, executeTest: testParseHTML, }, @@ -304,10 +304,10 @@ export const parseTestInstancesHTML: TestInstance< testCase: { name: "inlineContentAndNestedBlocks", content: `
    - None Bold Italic Underline Strikethrough All -
    Nested Div
    -

    Nested Paragraph

    -
    `, + None Bold Italic Underline Strikethrough All +
    Nested Div
    +

    Nested Paragraph

    + `, }, executeTest: testParseHTML, }, @@ -315,21 +315,21 @@ export const parseTestInstancesHTML: TestInstance< testCase: { name: "twoTables", content: ` - - - - - - -
    -

    Company

    -
    -

    Example Company Inc.

    -

    -

    Name: [Company Representative]

    -

    -

    Title: Chief Executive Officer

    -
    + + +

    Company

    + + + + +

    Example Company Inc.

    +

    +

    Name: [Company Representative]

    +

    +

    Title: Chief Executive Officer

    + + + @@ -543,14 +543,14 @@ With Hard Break

    { testCase: { name: "textColorStyle", - content: `

    Red Text Green Text Blue Text

    `, + content: `

    Blue Text Blue Text

    `, }, executeTest: testParseHTML, }, { testCase: { name: "backgroundColorStyle", - content: `

    Red Background Green Background Blue Background

    `, + content: `

    Blue Background Blue Background

    `, }, executeTest: testParseHTML, }, @@ -558,9 +558,9 @@ With Hard Break

    testCase: { name: "orderedListStart", content: `
      -
    1. List Item 2
    2. -
    3. List Item 3
    4. -
    5. List Item 4
    6. +
    7. List Item 2
    8. +
    9. List Item 3
    10. +
    11. List Item 4
    `, }, executeTest: testParseHTML, @@ -582,18 +582,16 @@ With Hard Break

    { testCase: { name: "textColorProp", - content: `

    Red Paragraph

    -

    Green Paragraph

    -

    Blue Paragraph

    `, + content: `

    Blue Text

    +

    Blue Text

    `, }, executeTest: testParseHTML, }, { testCase: { name: "backgroundColorProp", - content: `

    Red Background

    -

    Green Background

    -

    Blue Background

    `, + content: `

    Blue Background

    +

    Blue Background

    `, }, executeTest: testParseHTML, }, From 7185eb19e6e5ebe1b447fa2f4fb00286fde4c2d5 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Fri, 25 Apr 2025 14:29:56 +0200 Subject: [PATCH 4/4] Small fix --- .../context/__snapshots__/ServerBlockNoteEditor.test.ts.snap | 2 +- .../formatConversion/parse/__snapshots__/html/twoTables.json | 2 +- .../src/unit/core/formatConversion/parse/parseTestInstances.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/server-util/src/context/__snapshots__/ServerBlockNoteEditor.test.ts.snap b/packages/server-util/src/context/__snapshots__/ServerBlockNoteEditor.test.ts.snap index f46f75260..c31fa3130 100644 --- a/packages/server-util/src/context/__snapshots__/ServerBlockNoteEditor.test.ts.snap +++ b/packages/server-util/src/context/__snapshots__/ServerBlockNoteEditor.test.ts.snap @@ -2,7 +2,7 @@ exports[`Test ServerBlockNoteEditor > converts to HTML (blocksToFullHTML) 1`] = `"

    Heading 2

    Paragraph

    list item

    Example

    Caption

    Example

    Caption

    "`; -exports[`Test ServerBlockNoteEditor > converts to and from HTML (blocksToHTMLLossy) 1`] = `"

    Heading 2

    Paragraph

    • list item

    Example
    Caption
    Example

    Caption

    "`; +exports[`Test ServerBlockNoteEditor > converts to and from HTML (blocksToHTMLLossy) 1`] = `"

    Heading 2

    Paragraph

    • list item

    Example
    Caption
    Example

    Caption

    "`; exports[`Test ServerBlockNoteEditor > converts to and from HTML (blocksToHTMLLossy) 2`] = ` [ diff --git a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/twoTables.json b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/twoTables.json index 3ffbb3ead..1def7a8e3 100644 --- a/tests/src/unit/core/formatConversion/parse/__snapshots__/html/twoTables.json +++ b/tests/src/unit/core/formatConversion/parse/__snapshots__/html/twoTables.json @@ -45,7 +45,7 @@ { "styles": {}, "text": " - + Name: [Company Representative] Title: Chief Executive Officer", "type": "text", diff --git a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts index fb65ccccd..2ec30e07d 100644 --- a/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts +++ b/tests/src/unit/core/formatConversion/parse/parseTestInstances.ts @@ -550,7 +550,7 @@ With Hard Break

    { testCase: { name: "backgroundColorStyle", - content: `

    Blue Background Blue Background

    `, + content: `

    Blue Background Blue Background

    `, }, executeTest: testParseHTML, },