|
1 | 1 | import { blockToNode } from "../api/nodeConversions/blockToNode.js";
|
2 | 2 | import type { BlockNoteEditor } from "../editor/BlockNoteEditor.js";
|
| 3 | +import { COLORS_DEFAULT } from "../editor/defaultColors.js"; |
3 | 4 | import type {
|
4 | 5 | BlockNoDefaults,
|
5 | 6 | BlockSchema,
|
@@ -55,14 +56,17 @@ export function createDefaultBlockDOMOutputSpec(
|
55 | 56 |
|
56 | 57 | // Function used to convert default blocks to HTML. It uses the corresponding
|
57 | 58 | // node's `renderHTML` method to do the conversion by using a default
|
58 |
| -// `DOMSerializer`. |
| 59 | +// `DOMSerializer`. The `external` flag is used to modify the resulting HTML for |
| 60 | +// external use. This just involves changing props being rendered from `data-*` |
| 61 | +// attributes to inline styles. |
59 | 62 | export const defaultBlockToHTML = <
|
60 | 63 | BSchema extends BlockSchema,
|
61 | 64 | I extends InlineContentSchema,
|
62 | 65 | S extends StyleSchema
|
63 | 66 | >(
|
64 | 67 | block: BlockNoDefaults<BSchema, I, S>,
|
65 |
| - editor: BlockNoteEditor<BSchema, I, S> |
| 68 | + editor: BlockNoteEditor<BSchema, I, S>, |
| 69 | + external = false |
66 | 70 | ): {
|
67 | 71 | dom: HTMLElement;
|
68 | 72 | contentDOM?: HTMLElement;
|
@@ -90,6 +94,74 @@ export const defaultBlockToHTML = <
|
90 | 94 | );
|
91 | 95 | }
|
92 | 96 |
|
| 97 | + // When exporting to external HTML, we convert from `data-*` attributes to |
| 98 | + // inline styles properties which can be understood by external applications. |
| 99 | + // |
| 100 | + // Note: This is a bit hacky to do this here as we're just hardcoding this for |
| 101 | + // props on default blocks. We should revisit this when we migrate internal |
| 102 | + // blocks to use the custom blocks API. |
| 103 | + if (external) { |
| 104 | + const dom = renderSpec.dom as HTMLElement; |
| 105 | + |
| 106 | + if (dom.hasAttribute("data-background-color")) { |
| 107 | + const backgroundColor = dom.getAttribute("data-background-color")!; |
| 108 | + |
| 109 | + // If the background color is one of the default colors, we set the |
| 110 | + // color's hex code from the default theme, as this will look nicer than |
| 111 | + // using regular CSS colors. For example, instead of |
| 112 | + // `background-color: red`, we use `background-color: #fbe4e4`. |
| 113 | + if (backgroundColor in COLORS_DEFAULT) { |
| 114 | + const cssVariableName = |
| 115 | + `--blocknote-background-${backgroundColor}` as any; |
| 116 | + |
| 117 | + dom.style.setProperty( |
| 118 | + cssVariableName, |
| 119 | + COLORS_DEFAULT[backgroundColor as keyof typeof COLORS_DEFAULT] |
| 120 | + .background |
| 121 | + ); |
| 122 | + dom.style.backgroundColor = `var(${cssVariableName})`; |
| 123 | + } else { |
| 124 | + dom.style.backgroundColor = backgroundColor; |
| 125 | + } |
| 126 | + |
| 127 | + dom.removeAttribute("data-background-color"); |
| 128 | + } |
| 129 | + |
| 130 | + if (dom.hasAttribute("data-text-color")) { |
| 131 | + const textColor = dom.getAttribute("data-text-color")!; |
| 132 | + |
| 133 | + // If the text color is one of the default colors, we set the color's hex |
| 134 | + // code from the default theme, as this will look nicer than using regular |
| 135 | + // CSS colors. For example, instead of `color: red`, we use |
| 136 | + // `color: #e03e3e`. |
| 137 | + if (textColor in COLORS_DEFAULT) { |
| 138 | + const cssVariableName = `--blocknote-text-${textColor}` as any; |
| 139 | + |
| 140 | + dom.style.setProperty( |
| 141 | + cssVariableName, |
| 142 | + COLORS_DEFAULT[textColor as keyof typeof COLORS_DEFAULT].text |
| 143 | + ); |
| 144 | + dom.style.color = `var(${cssVariableName})`; |
| 145 | + } else { |
| 146 | + dom.style.color = textColor; |
| 147 | + } |
| 148 | + |
| 149 | + dom.removeAttribute("data-text-color"); |
| 150 | + } |
| 151 | + |
| 152 | + if (dom.hasAttribute("data-text-alignment")) { |
| 153 | + dom.style.textAlign = dom.getAttribute("data-text-alignment")!; |
| 154 | + dom.removeAttribute("data-text-alignment"); |
| 155 | + } |
| 156 | + |
| 157 | + // We also remove the `data-level` attribute for heading blocks, as this |
| 158 | + // information can be inferred from whether a `h1`, `h2`, or `h3 tag is |
| 159 | + // used. |
| 160 | + if (dom.hasAttribute("data-level")) { |
| 161 | + dom.removeAttribute("data-level"); |
| 162 | + } |
| 163 | + } |
| 164 | + |
93 | 165 | return renderSpec as {
|
94 | 166 | dom: HTMLElement;
|
95 | 167 | contentDOM?: HTMLElement;
|
|
0 commit comments