Skip to content

Commit 8aa1509

Browse files
authored
fix(converter): preserve explicit w:bidiVisual w:val="0" on export (SD-3142) (#3284)
bidiVisual-translator.decode used a one-off pattern that dropped rightToLeft: false on export. Switch to the shared createSingleBooleanPropertyHandler used by w:bidi (paragraph), which distinguishes missing (omit) from explicit false (emit w:val="0"). Per ECMA-376 section 17.4.1 + 17.17.4, w:bidiVisual w:val="0" is an explicit-false that can override a style-cascade true. Dropping it on export silently flips the table visual direction on the next open when the referenced table style sets bidiVisual true. Tests: - rightToLeft: true -> bare w:bidiVisual element - rightToLeft: false -> w:bidiVisual w:val="0" (new — round-trip preservation) - missing -> omit the element - existing encode coverage retained.
1 parent c6fbcf8 commit 8aa1509

2 files changed

Lines changed: 18 additions & 10 deletions

File tree

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { NodeTranslator } from '@translator';
2-
import { parseBoolean } from '@converter/v3/handlers/utils';
2+
import { createSingleBooleanPropertyHandler } from '@converter/v3/handlers/utils';
33

44
/**
55
* The NodeTranslator instance for the bidiVisual element.
6+
*
7+
* SD-3142: use the shared boolean handler so an explicit `w:val="0"` survives
8+
* the round trip as `<w:bidiVisual w:val="0"/>`. Per ECMA-376 §17.4.1 +
9+
* §17.17.4, explicit-false can override a style-cascade true; dropping it on
10+
* export silently flips the table visual direction on the next open.
11+
*
612
* @type {import('@translator').NodeTranslator}
713
* @see {@link https://ecma-international.org/publications-and-standards/standards/ecma-376/} "Fundamentals And Markup Language Reference", page 373
814
*/
9-
export const translator = NodeTranslator.from({
10-
xmlName: 'w:bidiVisual',
11-
sdNodeOrKeyName: 'rightToLeft',
12-
encode: ({ nodes }) => parseBoolean(nodes[0].attributes?.['w:val'] ?? '1'),
13-
decode: ({ node }) => (node.attrs.rightToLeft ? { attributes: {} } : undefined),
14-
});
15+
export const translator = NodeTranslator.from(createSingleBooleanPropertyHandler('w:bidiVisual', 'rightToLeft'));

packages/super-editor/src/editors/v1/core/super-converter/v3/handlers/w/bidiVisual/bidiVisual-translator.test.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,20 @@ describe('w:bidiVisual translator', () => {
1717
});
1818

1919
describe('decode', () => {
20-
it('creates a w:bidiVisual element if rightToLeft is true', () => {
20+
it('creates a bare w:bidiVisual element when rightToLeft is true', () => {
2121
const { attributes: result } = translator.decode({ node: { attrs: { rightToLeft: true } } });
2222
expect(result).toEqual({});
2323
});
2424

25-
it('returns undefined if rightToLeft is false or missing', () => {
26-
expect(translator.decode({ node: { attrs: { rightToLeft: false } } })).toBeUndefined();
25+
// SD-3142: explicit false (from `<w:bidiVisual w:val="0"/>`) is a real
26+
// signal per §17.4.1 + §17.17.4 and can override a style-cascade true.
27+
// Drop it on export and the style cascade wins on the next open.
28+
it('emits w:val="0" when rightToLeft is explicit false', () => {
29+
const { attributes: result } = translator.decode({ node: { attrs: { rightToLeft: false } } });
30+
expect(result).toEqual({ 'w:val': '0' });
31+
});
32+
33+
it('returns undefined when rightToLeft is missing (omit the element)', () => {
2734
expect(translator.decode({ node: { attrs: {} } })).toBeUndefined();
2835
});
2936
});

0 commit comments

Comments
 (0)