Commit ec5db77
authored
fix(super-editor): import <w:temporary/> and lock appearance default contract (SD-3111) (#3295)
* fix(super-editor): import <w:temporary/> and lock appearance default contract (SD-3111)
Two narrow gaps, both about the import contract for content-control
properties:
1. <w:temporary/> was being dropped on import.
Word emits it (ECMA-376 §17.5.2.43), our exporter preserves it on
round-trip, the editor's node-attrs typedef carries it, the
sdt-info-builder maps it to ContentControlInfo.properties.temporary
— but handle-structured-content-node.js never read it from sdtPr.
So properties.temporary was always undefined, even for parts where
the source XML said true.
Fix: new extractTemporary helper applies Word's toggle conventions
(empty element = true; w:val "true"/"1" = true; "false"/"0" = false).
When the element is absent, the attr is NOT stamped — so consumers
can distinguish "absent from source" from "explicit false."
2. The appearance default contract was implicit.
ECMA-376 lets the source XML omit <w15:appearance>, and Word's
effective default is boundingBox. SuperDoc correctly returns
undefined when the source omits the element (resolveAppearance
validates against the three spec values). But the public type
JSDoc said nothing about this, so consumers building UI on top
of appearance could not tell whether undefined meant "data
missing" or "Word default applies."
Fix: JSDoc on ContentControlProperties.appearance now spells out
all four states explicitly, including 'undefined → treat as
boundingBox.' Same treatment for temporary's 'undefined → treat
as false.' No runtime behavior change — pure contract lock.
Tests:
- 7 new w:temporary parsing cases (empty toggle, w:val true/1/false/0,
absent twice, absent-doesn't-stamp).
- Existing info-builder tests already cover the attr-to-properties
mapping; they still pass.
Verified:
- super-editor v3/w/sdt suite: 134/134
- @superdoc/document-api: 1398/1398
Out of scope:
- The exporter side already round-trips <w:temporary/> (per ticket
description). Not modified.
- The appearance default behavior is unchanged — only the JSDoc that
documents it.
* wip(document-api): tighten temporary JSDoc wording per review (SD-3111)
The previous wording 'Word removes the SDT once the user fills it in'
paraphrases user-visible behavior but isn't quite the spec's framing.
Updated to 'When enabled, Word treats the content control as temporary
and may remove the SDT wrapper after the user edits/fills the control.'
No runtime change.
* fix(super-editor): route extractTemporary through shared ST_OnOff parser (SD-3111)
Codex bot review caught a real bug: my hand-rolled ST_OnOff check in
extractTemporary only recognized '0' and 'false' as off tokens, but
the project's shared ST_OnOff convention (token-sets.ts:27) also
accepts 'off'. So <w:temporary w:val="off"/> incorrectly returned
true, contradicting the source XML's explicit "not temporary".
Replaced with parseStrictStOnOff from the same utils.js other
ST_OnOff importers use. Gets: 'true'/'1'/'on' → true,
'false'/'0'/'off' → false, invalid tokens → undefined (with the
import-diagnostic side effect for consistency with other ST_OnOff
properties).
Strict ECMA-376 §22.9.2.7 lists only 1|0|true|false, but the project
deliberately accepts on/off for Word-in-the-wild robustness — same
convention bold/italic/strike already follow.
Three new tests:
- <w:temporary w:val="on"/> → true
- <w:temporary w:val="off"/> → false (the bug)
- invalid token → undefined
Verified:
- 32/32 in handle-structured-content-node.test.js
- 137/137 across the SDT handler suite1 parent 6e02c1c commit ec5db77
3 files changed
Lines changed: 112 additions & 1 deletion
File tree
- packages
- document-api/src/content-controls
- super-editor/src/editors/v1/core/super-converter/v3/handlers/w/sdt/helpers
Lines changed: 29 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
127 | 144 | | |
128 | 145 | | |
129 | 146 | | |
130 | 147 | | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
131 | 160 | | |
132 | 161 | | |
133 | 162 | | |
| |||
Lines changed: 25 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
| |||
56 | 57 | | |
57 | 58 | | |
58 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
59 | 78 | | |
60 | 79 | | |
61 | 80 | | |
| |||
84 | 103 | | |
85 | 104 | | |
86 | 105 | | |
87 | | - | |
| 106 | + | |
88 | 107 | | |
89 | 108 | | |
| 109 | + | |
90 | 110 | | |
91 | 111 | | |
92 | 112 | | |
| |||
117 | 137 | | |
118 | 138 | | |
119 | 139 | | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
120 | 144 | | |
121 | 145 | | |
122 | 146 | | |
| |||
Lines changed: 58 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
225 | 225 | | |
226 | 226 | | |
227 | 227 | | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
228 | 286 | | |
229 | 287 | | |
230 | 288 | | |
| |||
0 commit comments