From ec3cb2e8bd70d0a4a5fe0e2b0a7a0c43f6859830 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 4 Sep 2025 11:04:50 -0300 Subject: [PATCH 1/6] fix: parse heading elements as html when inserting textual content --- packages/super-editor/src/core/commands/insertContentAt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/super-editor/src/core/commands/insertContentAt.js b/packages/super-editor/src/core/commands/insertContentAt.js index 5bdeeafe58..ba86de8b71 100644 --- a/packages/super-editor/src/core/commands/insertContentAt.js +++ b/packages/super-editor/src/core/commands/insertContentAt.js @@ -60,7 +60,7 @@ export const insertContentAt = // If the original input is plainly textual, prefer insertText regardless of how parsing represents it. const forceTextInsert = - typeof value === 'string' || + (typeof value === 'string' && !/^[^<]+<\/h[1-6]>$/.test(value)) || (Array.isArray(value) && value.every((v) => typeof v === 'string' || (v && typeof v.text === 'string'))) || (value && typeof value === 'object' && typeof value.text === 'string'); From 242090372444eb4963295f29e81d214626d8388c Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 4 Sep 2025 11:06:54 -0300 Subject: [PATCH 2/6] fix: correctly assign linked style for heading nodes --- packages/super-editor/src/extensions/heading/heading.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/super-editor/src/extensions/heading/heading.js b/packages/super-editor/src/extensions/heading/heading.js index d576452808..0d365399c0 100644 --- a/packages/super-editor/src/extensions/heading/heading.js +++ b/packages/super-editor/src/extensions/heading/heading.js @@ -73,13 +73,20 @@ export const Heading = Node.create({ return attrs.sdBlockId ? { 'data-sd-block-id': attrs.sdBlockId } : {}; }, }, + + /** + * @private + * @category Attribute + * @param {string} [styleId] - Style ID assigned according to heading level + */ + styleId: {}, }; }, parseDOM() { return this.options.levels.map((level) => ({ tag: `h${level}`, - attrs: { level }, + attrs: { level, styleId: `Heading${level}` }, })); }, From 8f220480e33f5110de7f08411eeb08c1c42756fe Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 4 Sep 2025 11:08:25 -0300 Subject: [PATCH 3/6] fix: unset default browser styles for headings --- .../superdoc/src/assets/styles/layout/global.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/superdoc/src/assets/styles/layout/global.css b/packages/superdoc/src/assets/styles/layout/global.css index 4c8c759386..10b7e63a10 100644 --- a/packages/superdoc/src/assets/styles/layout/global.css +++ b/packages/superdoc/src/assets/styles/layout/global.css @@ -15,6 +15,18 @@ pointer-events: none; } +.super-editor h1, +.super-editor h2, +.super-editor h3, +.super-editor h4, +.super-editor h5, +.super-editor h6 { + font-size: unset; + font-weight: unset; + margin: 0; + padding: 0; +} + .super-editor p { padding: 0; margin: 0; From 316898c8543742e13ec30b9b928cfc1d72d8aaaf Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 4 Sep 2025 14:08:50 -0300 Subject: [PATCH 4/6] fix: render heading nodes as p elements --- packages/super-editor/src/extensions/heading/heading.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/super-editor/src/extensions/heading/heading.js b/packages/super-editor/src/extensions/heading/heading.js index 0d365399c0..13c2aba345 100644 --- a/packages/super-editor/src/extensions/heading/heading.js +++ b/packages/super-editor/src/extensions/heading/heading.js @@ -90,10 +90,8 @@ export const Heading = Node.create({ })); }, - renderDOM({ node, htmlAttributes }) { - const hasLevel = this.options.levels.includes(node.attrs.level); - const level = hasLevel ? node.attrs.level : this.options.levels[0]; - return [`h${level}`, Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0]; + renderDOM({ htmlAttributes }) { + return [`p`, Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes), 0]; }, addCommands() { From 1add7343a5313cacc3f37285c1598f329d0e412b Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 4 Sep 2025 17:37:44 -0300 Subject: [PATCH 5/6] test: simulate inserting a heading html string as content --- .../src/core/commands/insertContentAt.test.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/super-editor/src/core/commands/insertContentAt.test.js b/packages/super-editor/src/core/commands/insertContentAt.test.js index f24ac08e20..4f378cd60b 100644 --- a/packages/super-editor/src/core/commands/insertContentAt.test.js +++ b/packages/super-editor/src/core/commands/insertContentAt.test.js @@ -69,6 +69,32 @@ describe('insertContentAt', () => { expect(selectionToInsertionEnd).toHaveBeenCalledWith(tr, tr.steps.length - 1, -1); }); + it('inserts a styled paragraph node when given an html heading string', () => { + const value = '

Hello world

'; + + debugger; + const tr = makeTr(); + const editor = makeEditor(); + const node = { + type: { name: 'paragraph' }, + isText: false, + isBlock: true, + marks: [], + check: vi.fn(), + }; + + createNodeFromContent.mockImplementation(() => node); + + const cmd = insertContentAt(5, value, { updateSelection: true }); + const result = cmd({ tr, dispatch: true, editor }); + + expect(result).toBe(true); + expect(createNodeFromContent).toHaveBeenCalled(); + expect(tr.replaceWith).toHaveBeenCalledWith(4, 6, node); + expect(tr.insertText).not.toHaveBeenCalled(); + expect(selectionToInsertionEnd).toHaveBeenCalledWith(tr, tr.steps.length - 1, -1); + }); + it('applies input rules meta when applyInputRules=true (text case)', () => { const value = 'abc'; createNodeFromContent.mockImplementation(() => ({ From 00e01337e4da7fb08ca92d7c78acc9f4eab5191a Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 4 Sep 2025 17:52:01 -0300 Subject: [PATCH 6/6] fix: adjust build command --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 0ddd1c7b31..704b046e80 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "watch:super-editor": "npm run build:watch --workspace=packages/super-editor", "build:superdoc": "npm run build --workspace=packages/superdoc", "build:super-editor": "npm run build --workspace=packages/super-editor", - "build": "npm run build:super-editor && npm run build:superdoc", + "build:ooxml-inspector": "npm run build --workspace=packages/ooxml-inspector", + "build": "npm run build:ooxml-inspector && npm run build:super-editor && npm run build:superdoc", "release:superdoc": "npm run release --workspace=packages/superdoc", "release:next": "npm run release:next --workspace=packages/superdoc", "clean:packages": "rm -rf ./packages/*/dist",