@@ -5,46 +5,38 @@ import { fileURLToPath } from 'node:url';
55test . use ( { config : { toolbar : 'full' , showSelection : true } } ) ;
66const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) ) ;
77
8- // SD-2767 Wave 3 coverage gap: a table whose `w:bidiVisual` comes from the
9- // style cascade (NOT inline on the table itself). The fixture defines a
10- // custom table style with `w:bidiVisual` set, and the table references that
11- // style via `w:tblStyle` with no inline `w:bidiVisual` override.
8+ // SD-3171 Word-parity contract: `w:bidiVisual` visually flips cell order ONLY
9+ // when set inline on the table itself. Word does NOT visually flip cells when
10+ // the only source of `w:bidiVisual` is a style cascade.
1211//
13- // Per ECMA-376 §17.4.1, `w:bidiVisual` flips the visual order of cells:
14- // logical first cell renders on the visual right, logical last on the
15- // visual left. The style cascade must resolve this the same way as inline
16- // `w:bidiVisual` would.
12+ // Verified empirically: opening this fixture in Word shows
13+ // `Document.Tables(1).TableDirection === 1` (wdTableDirectionLtr) and renders
14+ // cells in logical order A B C. SuperDoc must match.
1715//
18- // Word confirms `Document.Tables(1).TableDirection === 1` (wdTableDirectionRtl)
19- // when opening this fixture, even though `document.xml` has no inline
20- // `w:bidiVisual`. SuperDoc must match.
21-
22- test ( 'RTL bidiVisual table inherited from a table style renders logical first cell on the visual right' , async ( {
23- superdoc,
24- } ) => {
16+ // History: PR #3350 originally asserted this fixture renders C B A (cells
17+ // visually flipped). That pinned SuperDoc's own pre-SD-3171 behavior, not
18+ // Word's. The flip came from pm-adapter's SD-3138 Phase 1B cascade path that
19+ // fell through from inline to style-resolved `bidiVisual`. SD-3171 removes
20+ // that fallback so style-cascade `bidiVisual` is ignored for visual direction.
21+ // The companion test rtl-inline-bidivisual.spec.ts pins the positive control
22+ // (inline `bidiVisual` still flips cells).
23+
24+ test ( 'table with style-derived bidiVisual renders cells in logical order (Word-parity)' , async ( { superdoc } ) => {
2525 await superdoc . loadDocument ( path . resolve ( __dirname , 'fixtures/rtl-style-derived-bidivisual.docx' ) ) ;
2626 await superdoc . waitForStable ( ) ;
2727
2828 // Fixture: 1x3 table, logical cells A B C, style-set `bidiVisual`.
29- // Expected visual order (right to left): A B C.
30- // Expected visual order (left to right): C B A.
29+ // Expected visual order (left to right): A B C.
3130 const cellLayout = await superdoc . page . evaluate ( ( ) => {
3231 const fragment = document . querySelector ( '.superdoc-table-fragment' ) ;
3332 if ( ! fragment ) return null ;
3433 const fragRect = fragment . getBoundingClientRect ( ) ;
35-
36- // Find all rendered cells. The painter positions cells absolutely within
37- // the fragment with left offsets that reflect their visual order.
3834 const cells = Array . from ( fragment . children ) . filter ( ( el ) => ( el as HTMLElement ) . style ?. position === 'absolute' ) ;
3935 if ( cells . length === 0 ) return null ;
40-
4136 return cells
4237 . map ( ( cell ) => {
4338 const rect = ( cell as HTMLElement ) . getBoundingClientRect ( ) ;
44- return {
45- text : ( cell . textContent ?? '' ) . trim ( ) ,
46- relLeft : rect . left - fragRect . left ,
47- } ;
39+ return { text : ( cell . textContent ?? '' ) . trim ( ) , relLeft : rect . left - fragRect . left } ;
4840 } )
4941 . filter ( ( c ) => c . text === 'A' || c . text === 'B' || c . text === 'C' )
5042 . sort ( ( a , b ) => a . relLeft - b . relLeft ) ;
@@ -53,11 +45,7 @@ test('RTL bidiVisual table inherited from a table style renders logical first ce
5345 expect ( cellLayout ) . not . toBeNull ( ) ;
5446 if ( ! cellLayout ) return ;
5547
56- // Three cells found, in left-to-right visual order.
5748 expect ( cellLayout ) . toHaveLength ( 3 ) ;
58-
59- // RTL via style cascade: visual L-to-R order should be C, B, A.
60- // If the style cascade is direction-blind, cells would render A, B, C and
61- // this assertion would fail.
62- expect ( cellLayout . map ( ( c ) => c . text ) ) . toEqual ( [ 'C' , 'B' , 'A' ] ) ;
49+ // SD-3171: style-cascade `bidiVisual` does not visually flip cells. Match Word.
50+ expect ( cellLayout . map ( ( c ) => c . text ) ) . toEqual ( [ 'A' , 'B' , 'C' ] ) ;
6351} ) ;
0 commit comments