diff --git a/DESIGN.md b/DESIGN.md
index 86bbd7e61..894980f79 100644
--- a/DESIGN.md
+++ b/DESIGN.md
@@ -165,8 +165,22 @@ pub struct WebUIFragmentSignal {
pub value: String,
/// Determines if the value should be rendered as raw content.
pub raw: bool,
+ /// Whether the signal is inside an HTML raw-text context such as `"),
+ ],
+ },
+ );
+ let protocol = WebUIProtocol::new(fragments);
+ let state = test_json!({"tokens": "--accent:red"});
+ let output = render_with_webui_plugin(&protocol, &state);
+
+ assert!(output.contains(""));
+ assert!(!output.contains(""));
+ assert!(!output.contains(""));
}
}
diff --git a/crates/webui-parser/src/lib.rs b/crates/webui-parser/src/lib.rs
index 40fa6ecff..c5dd69e18 100644
--- a/crates/webui-parser/src/lib.rs
+++ b/crates/webui-parser/src/lib.rs
@@ -160,6 +160,29 @@ fn boundary_parent_scope(name: &str) -> Option<&'static str> {
}
}
+#[inline]
+fn is_html_text_only_scope(scope: Option<&str>) -> bool {
+ // Explicit allowlist of the raw-text/RCDATA scopes returned by
+ // `boundary_parent_scope`, so a new scope value must be deliberately
+ // added here to become text-only rather than silently defaulting to it.
+ // ` inert content` and "component host content" are
+ // intentionally excluded: both parse normal (escaped) child content.
+ matches!(
+ scope,
+ Some(
+ " raw-text content"
+ | " text content"
+ | "