max / makeover-webview
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+29 insertions,
-1 deletion
| @@ -475,12 +475,17 @@ | |||
| 475 | 475 | // upgrade needs a selector that survives `Emit`'s class prefixing. | |
| 476 | 476 | // Without the mark, a described editor is a plain box and the four | |
| 477 | 477 | // hand-written MNW editors have nothing to convert onto. | |
| 478 | + | // | |
| 479 | + | // `data-format` and not `data-value`: this names the shape of the | |
| 480 | + | // value, and `facet` already spends `data-facet-value` on carrying an | |
| 481 | + | // actual one. Two attributes a letter apart meaning opposite things is | |
| 482 | + | // how a renderer's own vocabulary starts drifting. | |
| 478 | 483 | kind if kind.multiline() => { | |
| 479 | 484 | out.push_str("<textarea class=\""); | |
| 480 | 485 | push_class(out, "field", opts); | |
| 481 | 486 | out.push('"'); | |
| 482 | 487 | if matches!(kind, FieldKind::Rich) { | |
| 483 | - | out.push_str(" data-value=\"markdown\""); | |
| 488 | + | out.push_str(" data-format=\"markdown\""); | |
| 484 | 489 | } | |
| 485 | 490 | push_control_attributes(out, field, &id, field.name); | |
| 486 | 491 | placeholder(out); | |
| @@ -1124,6 +1129,29 @@ | |||
| 1124 | 1129 | assert!(html.contains(">two\nlines</textarea>"), "{html}"); | |
| 1125 | 1130 | } | |
| 1126 | 1131 | ||
| 1132 | + | #[test] | |
| 1133 | + | fn a_markdown_field_is_a_textarea_that_says_what_its_value_is() { | |
| 1134 | + | // The mark is the whole difference. Without it a described editor is a | |
| 1135 | + | // plain box, and an enhancement looking for editors to upgrade has | |
| 1136 | + | // nothing to find -- which is the state MNW's four hand-written section | |
| 1137 | + | // editors would have had to keep living in. | |
| 1138 | + | let filling = Filling::of(Value::Text("# Heading")); | |
| 1139 | + | let html = field_html(&field(FieldKind::Rich), &filling, &Emit::default()); | |
| 1140 | + | assert!(html.contains("<textarea"), "{html}"); | |
| 1141 | + | assert!(html.contains(r#"data-format="markdown""#), "{html}"); | |
| 1142 | + | assert!(html.contains("># Heading</textarea>"), "{html}"); | |
| 1143 | + | ||
| 1144 | + | // A plain textarea claims nothing about its value, so the marker has to | |
| 1145 | + | // be absent rather than present-and-different. | |
| 1146 | + | let plain = field_html(&field(FieldKind::Textarea), &filling, &Emit::default()); | |
| 1147 | + | assert!(!plain.contains("data-format"), "{plain}"); | |
| 1148 | + | ||
| 1149 | + | // And it is not an input: the catch-all in `input_type` would have | |
| 1150 | + | // degraded it to a single-line text box, which is the wrong shape for | |
| 1151 | + | // markdown rather than a lossless fallback. | |
| 1152 | + | assert!(!html.contains("<input"), "{html}"); | |
| 1153 | + | } | |
| 1154 | + | ||
| 1127 | 1155 | #[test] | |
| 1128 | 1156 | fn the_class_prefix_reaches_the_markup_as_well_as_the_stylesheet() { | |
| 1129 | 1157 | let opts = Emit { |