Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/super-editor/src/core/super-converter/exporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,11 @@ export class DocxExporter {

#generate_xml_as_list(data, debug = false) {
const json = JSON.parse(JSON.stringify(data));
const declaration = this.converter.declaration.attributes;
const declaration = this.converter.declaration?.attributes ?? {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this same fallback object is copy-pasted in 11+ files across the converter. there's already a constants.js next door — move it there and import it?

import { DEFAULT_XML_DECLARATION } from './constants.js';
// ...
const declaration = this.converter.declaration?.attributes ?? DEFAULT_XML_DECLARATION.attributes;

version: '1.0',
encoding: 'UTF-8',
standalone: 'yes',
};
const xmlTag = `<?xml${Object.entries(declaration)
.map(([key, value]) => ` ${key}="${value}"`)
.join('')}?>`;
Expand Down
42 changes: 42 additions & 0 deletions packages/super-editor/src/tests/export/docxExporter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,48 @@ describe('DocxExporter', () => {
expect(xml).toContain('Format=&lt;&lt;NUM&gt;&gt;_&lt;&lt;VER&gt;&gt;');
});

describe('null declaration handling', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these two tests are the same except for null vs undefined. could be one test with it.each — less to read.

it('uses default XML declaration when converter.declaration is null', () => {
const exporter = new DocxExporter({ declaration: null });

const data = {
name: 'w:document',
attributes: {},
elements: [
{
name: 'w:t',
elements: [{ type: 'text', text: 'Hello' }],
},
],
};

const xml = exporter.schemaToXml(data);

expect(xml).toContain('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
expect(xml).toContain('<w:t>Hello</w:t>');
});

it('uses default XML declaration when converter.declaration is undefined', () => {
const exporter = new DocxExporter({});

const data = {
name: 'w:document',
attributes: {},
elements: [
{
name: 'w:t',
elements: [{ type: 'text', text: 'Hello' }],
},
],
};

const xml = exporter.schemaToXml(data);

expect(xml).toContain('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
expect(xml).toContain('<w:t>Hello</w:t>');
});
});

it('encodes all ampersands in text nodes including entity-like sequences', () => {
const exporter = new DocxExporter(createConverterStub());

Expand Down
Loading