diff --git a/src/utils/page-content.ts b/src/utils/page-content.ts index 40a229b..3f0e54e 100644 --- a/src/utils/page-content.ts +++ b/src/utils/page-content.ts @@ -96,13 +96,18 @@ export function selectSource(page: PageWithContent): PageSource { const editor = page.editor || ''; const rawHtml = typeof page.raw_html === 'string' ? page.raw_html : ''; - if (editor === 'markdown' && typeof page.markdown === 'string') { - // Stay on the markdown path even when the page is still empty, otherwise - // the first append to a fresh markdown page would switch its editor type. - // Only an inconsistent page (no markdown but stored HTML) falls back. - if (page.markdown.trim().length > 0 || rawHtml.trim().length === 0) { - return { writeField: 'markdown', source: page.markdown, editor }; - } + const markdown = typeof page.markdown === 'string' ? page.markdown : ''; + + // BookStack clears `markdown` whenever HTML is saved, so a non-empty one is the + // page's source even when `editor` says otherwise: API-created pages report "wysiwyg". + if (markdown.trim().length > 0) { + return { writeField: 'markdown', source: markdown, editor }; + } + + // Stay on the markdown path for an empty markdown page, otherwise the first + // append to a fresh one would switch its editor type. + if (editor === 'markdown' && typeof page.markdown === 'string' && rawHtml.trim().length === 0) { + return { writeField: 'markdown', source: page.markdown, editor }; } const source = rawHtml.length > 0 ? rawHtml : page.html || ''; diff --git a/tests/unit/page-content.test.ts b/tests/unit/page-content.test.ts index d8d2e6b..369ce28 100644 --- a/tests/unit/page-content.test.ts +++ b/tests/unit/page-content.test.ts @@ -85,6 +85,15 @@ describe('selectSource', () => { expect(result.source).toBe('# Heading\n\nBody'); }); + it('writes markdown when the page holds markdown under a wysiwyg editor label', () => { + // Pages created through the API with `markdown` report editor "wysiwyg". Writing html + // there would wipe the markdown source that other API clients read back. + const result = selectSource({ ...basePage, editor: 'wysiwyg', markdown: '# Heading' }); + + expect(result.writeField).toBe('markdown'); + expect(result.source).toBe('# Heading'); + }); + it('falls back to the rendered html when raw_html is absent', () => { const { raw_html: _omitted, ...withoutRaw } = basePage; const result = selectSource(withoutRaw as PageWithContent);