From 84bb5ae4c019e1b2b732df612fd87bb5844a78d6 Mon Sep 17 00:00:00 2001 From: Mohamed Mansour Date: Fri, 21 Aug 2026 23:50:29 -0700 Subject: [PATCH 1/4] fix: preserve siblings around raw HTML updates Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0807f5af-f9d9-45ad-b7d2-907084c53ea0 --- DESIGN.md | 48 ++- crates/webui-handler/src/lib.rs | 17 +- crates/webui-handler/src/plugin/mod.rs | 54 ++- crates/webui-handler/src/plugin/webui.rs | 103 ++++- crates/webui-parser/src/lib.rs | 69 +++- crates/webui-parser/src/plugin/webui.rs | 48 ++- crates/webui-protocol/proto/webui.proto | 3 + crates/webui-protocol/src/gen_webui.rs | 4 + crates/webui-protocol/src/lib.rs | 33 +- crates/webui-test-utils/src/lib.rs | 28 +- docs/guide/concepts/plugins/index.md | 19 +- packages/webui-framework/README.md | 32 +- .../src/element/markers.test.ts | 29 ++ .../webui-framework/src/element/markers.ts | 63 ++- packages/webui-framework/src/element/types.ts | 17 +- .../src/hydration-mismatch.test.ts | 6 +- .../webui-framework/src/template-element.ts | 288 ++++++++++--- .../fixtures/raw-html-conditional/element.ts | 45 ++ .../raw-html-conditional.spec.ts | 386 +++++++++++++++++- .../raw-html-conditional/src/index.html | 1 + .../test-raw-html-keyed-repeat.html | 7 + .../src/test-raw-html/test-raw-html.html | 23 +- .../fixtures/raw-html-conditional/state.json | 28 +- .../tests/fixtures/raw-html-light/element.ts | 12 + .../raw-html-light/raw-html-light.spec.ts | 119 ++++++ .../fixtures/raw-html-light/src/index.html | 10 + .../test-raw-html-light.html | 15 + .../tests/fixtures/raw-html-light/state.json | 5 + .../fixtures/raw-html-light/webui.config.json | 3 + 29 files changed, 1389 insertions(+), 126 deletions(-) create mode 100644 packages/webui-framework/tests/fixtures/raw-html-conditional/src/test-raw-html-keyed-repeat/test-raw-html-keyed-repeat.html create mode 100644 packages/webui-framework/tests/fixtures/raw-html-light/element.ts create mode 100644 packages/webui-framework/tests/fixtures/raw-html-light/raw-html-light.spec.ts create mode 100644 packages/webui-framework/tests/fixtures/raw-html-light/src/index.html create mode 100644 packages/webui-framework/tests/fixtures/raw-html-light/src/test-raw-html-light/test-raw-html-light.html create mode 100644 packages/webui-framework/tests/fixtures/raw-html-light/state.json create mode 100644 packages/webui-framework/tests/fixtures/raw-html-light/webui.config.json diff --git a/DESIGN.md b/DESIGN.md index 86bbd7e61..4d8fe04c1 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -165,6 +165,9 @@ 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..96469d93e 100644 --- a/crates/webui-parser/src/lib.rs +++ b/crates/webui-parser/src/lib.rs @@ -160,6 +160,14 @@ fn boundary_parent_scope(name: &str) -> Option<&'static str> { } } +#[inline] +fn is_html_text_only_scope(scope: Option<&str>) -> bool { + matches!( + scope, + Some(value) if value != "component host content" && value != "