Commit fa9c3e9
authored
fix(super-editor): preserve per-script fonts and inline keys metadata (SD-2517) (#2768)
* fix(super-editor): preserve per-script font in mark round-trip (SD-2517)
decodeRPrFromMarks was flattening all font scripts (ascii, eastAsia,
hAnsi, cs) to the ascii font value, ignoring the eastAsiaFontFamily
attribute already preserved on the mark during encode. This caused
getInlineRunProperties to falsely classify fontFamily as an inline
override (mark says eastAsia=Arial, style says eastAsia=Times New Roman),
which polluted runPropertiesInlineKeys and made the exporter emit
w:rFonts on heading runs that should inherit from the paragraph style.
The fix adds an eastAsiaFontFamily case to decodeRPrFromMarks so the
per-script font data survives the mark round-trip. With correct data,
the existing inline/style comparison works without heuristics.
* fix(super-editor): preserve per-script fonts and inline keys metadata (SD-2517)
Zero-edit round-trip was injecting 197 w:rFonts into heading runs.
Root cause: decodeRPrFromMarks flattened all font scripts (eastAsia, cs)
to the ascii font value. This made getInlineRunProperties falsely classify
fontFamily as inline (mark says cs=Arial, style says cs=Times New Roman),
polluting runPropertiesInlineKeys and causing the exporter to emit w:rFonts
on runs that should inherit from the paragraph style.
Two fixes applied together:
1. Mark round-trip fidelity (styles.js): Encode and decode eastAsiaFontFamily
and csFontFamily as separate mark attributes so per-script fonts survive
the mark round-trip per ECMA-376 §17.3.2.26.
2. Plugin inline keys guard (calculateInlineRunPropertiesPlugin.js): When the
importer set runPropertiesInlineKeys to [] (nothing inline), don't add
mark-derived keys unless the user genuinely applied new formatting
(detected via hasNewInlineProps). This handles remaining edge cases where
theme font resolution (hAnsiTheme) still causes false positives.
* fix(super-editor): register per-script font attrs on textStyle mark (SD-2517)
Address review findings:
- Register eastAsiaFontFamily and csFontFamily as global attributes on
the textStyle mark via FontFamily extension. Without schema registration,
ProseMirror dropped these attrs during Mark.fromJSON(), making the
per-script font decode paths unreachable (Codex review finding).
- Strip csFontFamily from visual mark attrs in resolveFontFamily alongside
eastAsiaFontFamily. Both are round-trip metadata, not CSS properties
(Opus review finding: csFontFamily leaked to DOM).
- Replace IIFE with plain const for overrideKeys in computeSegmentKeys
(DX finding from both reviewers).
Result: 468 → 153 rFonts (vs 183 without schema registration).
* test(super-editor): add resolveFontFamily tests for csFontFamily stripping (SD-2517)
Cover the new csFontFamily handling in resolveFontFamily:
- csFontFamily stripped from visual attrs for non-EA text
- both eastAsiaFontFamily and csFontFamily stripped together
- attrs returned unchanged when no per-script fonts present
* fix(super-editor): preserve importer-set inline keys when plugin drops them (SD-2517)
The calculateInlineRunPropertiesPlugin was dropping inline keys that the
importer explicitly set (e.g. fontFamily from w:rPr) when the plugin's
getInlineRunProperties comparison falsely classified them as matching the
style. This caused 118 runs to lose their explicit w:rFonts on export.
When the importer set non-empty runPropertiesInlineKeys, restore any
keys the plugin dropped back into runProperties from the original node
attrs. The importer saw explicit w:rPr in the XML — that decision is
authoritative over the plugin's mark-based recomputation.
Result: INPUT 271 rFonts → BEFORE 468 → AFTER 275 (near-perfect, +4 from
per-script encode edge cases, 0 injection).
* test(behavior): add SD-2517 round-trip regression test
End-to-end behavior test that loads a DOCX with localized Portuguese
heading styles, exports without edits, and verifies the rFonts count
didn't increase (the 197-injection regression).1 parent 25a6b41 commit fa9c3e9
File tree
11 files changed
+334
-21
lines changed- packages/super-editor/src/editors/v1
- core/super-converter
- v3/handlers/w/r/helpers
- extensions
- diffing
- font-family
- run
- types
- tests/behavior/tests/exporting
- fixtures
11 files changed
+334
-21
lines changedLines changed: 32 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
118 | 130 | | |
119 | 131 | | |
120 | 132 | | |
| |||
599 | 611 | | |
600 | 612 | | |
601 | 613 | | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
602 | 628 | | |
603 | 629 | | |
604 | 630 | | |
| |||
Lines changed: 48 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
538 | 538 | | |
539 | 539 | | |
540 | 540 | | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
541 | 589 | | |
Lines changed: 5 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
10 | 13 | | |
11 | 14 | | |
| 15 | + | |
12 | 16 | | |
13 | 17 | | |
14 | 18 | | |
| |||
Lines changed: 21 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
24 | 45 | | |
25 | 46 | | |
26 | 47 | | |
| |||
Lines changed: 3 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
243 | 243 | | |
244 | 244 | | |
245 | 245 | | |
| 246 | + | |
| 247 | + | |
246 | 248 | | |
247 | | - | |
| 249 | + | |
248 | 250 | | |
249 | 251 | | |
250 | 252 | | |
| |||
Lines changed: 12 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
60 | 72 | | |
61 | 73 | | |
62 | 74 | | |
| |||
Lines changed: 64 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
99 | 99 | | |
100 | 100 | | |
101 | 101 | | |
102 | | - | |
| 102 | + | |
103 | 103 | | |
104 | 104 | | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
105 | 108 | | |
106 | 109 | | |
107 | 110 | | |
108 | 111 | | |
109 | 112 | | |
110 | 113 | | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
111 | 149 | | |
112 | 150 | | |
113 | 151 | | |
114 | 152 | | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
120 | 173 | | |
121 | 174 | | |
122 | 175 | | |
123 | 176 | | |
124 | 177 | | |
125 | 178 | | |
126 | | - | |
127 | | - | |
| 179 | + | |
| 180 | + | |
128 | 181 | | |
129 | 182 | | |
130 | 183 | | |
131 | 184 | | |
132 | 185 | | |
133 | 186 | | |
134 | | - | |
135 | | - | |
| 187 | + | |
136 | 188 | | |
137 | 189 | | |
138 | 190 | | |
139 | 191 | | |
140 | | - | |
141 | | - | |
| 192 | + | |
| 193 | + | |
142 | 194 | | |
143 | 195 | | |
144 | 196 | | |
| |||
Lines changed: 98 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
759 | 759 | | |
760 | 760 | | |
761 | 761 | | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
762 | 860 | | |
0 commit comments