Skip to content

feat: strip template and style comments in parser and support legal comments#326

Open
mohamedmansour wants to merge 7 commits into
mainfrom
mmansour/strip-template-comments
Open

feat: strip template and style comments in parser and support legal comments#326
mohamedmansour wants to merge 7 commits into
mainfrom
mmansour/strip-template-comments

Conversation

@mohamedmansour
Copy link
Copy Markdown
Contributor

@mohamedmansour mohamedmansour commented Jun 5, 2026

Summary

Strips all comments in styles and templates but allows the preservation of legal comments. This fixes CSR hydration comment bleed from component templates while keeping the existing CSS signal-fragment escape hatch for dynamic CSS inside <style> tags.

What changed and why

HTML comments

  • Strip HTML comment nodes from parser output and WebUI compiled-template metadata.
  • Ignore bindings, directives, event attributes, and boolean attributes inside HTML comments.

HTML comments are authoring notes. Treating comment bodies as template syntax caused hidden {{...}}, @event, and ?attr examples to leak into CSR-created components as visible text or hydration metadata.

CSS comments and CSS signal fragments

  • Strip regular CSS block comments and line comments using tree-sitter CSS comment nodes.
  • Preserve legal CSS comments by default when legal_comments / --legal-comments is inline.
  • Support none to strip all non-signal comments, including legal comments.
  • Keep /*{{...}}*/ and /*{{{...}}}*/ as valid CSS signal fragments in <style> tags.

CSS comments need syntax-aware handling so token extraction ignores commented var(...) usages and output does not keep authoring comments. CSS signal fragments are a deliberate WebUI escape hatch: dynamic CSS must be wrapped as a CSS comment so raw handlebars are not interpreted as normal CSS text.

Parser and plugin architecture

  • Added shared comment-policy helpers for legal comment detection, CSS line comment detection, range stripping, and exact CSS signal-comment parsing.
  • Reused that shared CSS signal-comment parser from both HtmlParser and the WebUI compiled-template metadata generator.

SSR/parser output and CSR metadata need the same comment semantics. The WebUI plugin has its own metadata compiler, so it still emits plugin-specific metadata, but it now shares the recognition rule with parser core to avoid drift.

Public API and CLI

  • Added LegalComments and made ParserOptions::try_new(...) take the legal-comment mode explicitly.
  • Added legal_comments to Rust BuildOptions and Node JsBuildOptions.
  • Added --legal-comments <inline|none> to webui build and webui serve.

Comment preservation is build output behavior, so it needs to be explicit and consistent across Rust, Node, and CLI entry points. We intentionally did not keep a compatibility constructor so new parser options require callers to choose the policy.

Tests and benchmarks

  • Added Rust regression tests for stripped HTML comments, CSS comment stripping, legal comment preservation, CSS signal comments, WebUI metadata behavior, Node build option parity, and overlapping range stripping.
  • Updated parser benchmarks to keep complex attribute bindings by registering benchmark custom elements instead of weakening :config/:data to normal attributes.

The bug spans parser output and CSR metadata, so tests cover both paths. Benchmarks should continue measuring complex attribute parsing, not avoid it.

Micro-benchmarks

Compared HEAD against origin/main with the same microsoft-webui-parser Criterion benchmark harness.

Metric Result
Arithmetic average delta -3.38%
Geomean delta -3.45%
Benchmarks improved 21 / 21
Benchmarks regressed 0 / 21

Selected mean-time deltas:

Benchmark origin/main HEAD Delta
parser_parse_reuse/reuse/attributes_100 910.06 µs 898.29 µs -1.29%
parser_parse_reuse/reuse/styles_40 421.89 µs 415.96 µs -1.41%
parser_css_strategy/external_css 1.153 ms 1.132 ms -1.77%
parser_css_strategy/inline_css 1.150 ms 1.127 ms -2.01%
parser_realistic/parse/todo_app 205.36 µs 195.16 µs -4.97%
parser_realistic/parse/dashboard 250.11 µs 213.46 µs -14.65%

Validation

  • cargo test -p microsoft-webui-parser -p microsoft-webui-node
  • cd docs && pnpm build
  • cargo bench -p microsoft-webui-parser --bench parser_bench -- --test
  • cargo xtask check

Closes #323

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes CSR hydration “comment bleed” by stripping HTML comments from parser output and compiled template metadata, and adds a configurable CSS legal-comment preservation policy (inline default, none to strip all). The new --legal-comments option is wired through Rust core APIs, the CLI, Node bindings, and corresponding DESIGN/docs updates.

Changes:

  • Strip HTML comment nodes during parsing so bindings/directives inside comments never produce fragments or hydration metadata.
  • Strip CSS block/line comments during CSS parsing while optionally preserving “legal” comments (inline vs none) end-to-end via a new LegalComments option.
  • Propagate the new option through webui (Rust), webui-cli, and webui-node, with updated DESIGN and docs.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
docs/guide/integrations/node.md Documents legalComments option in Node build API.
docs/guide/concepts/css-tokens.md Updates token guidance to reflect comment stripping.
docs/guide/cli/index.md Adds --legal-comments to build/serve docs and explains comment handling.
docs/ai.md Updates AI reference for CLI flag and token injection guidance.
DESIGN.md Specifies LegalComments behavior and comment-handling contract.
crates/webui/src/lib.rs Exposes LegalComments via BuildOptions and adds tests around CSS comment stripping/preservation.
crates/webui/README.md Updates public Rust usage example and explains LegalComments.
crates/webui-parser/src/plugin/webui.rs Ensures compiled-template metadata ignores bindings inside comments and strips comments in <style>.
crates/webui-parser/src/lib.rs Implements HTML/CSS comment stripping in parser/component-template processing; threads LegalComments.
crates/webui-parser/src/css_parser.rs Adds one-pass token+definition extraction with removable-comment stripping and comment-range helpers.
crates/webui-parser/src/component_registry.rs Applies CSS comment policy during component CSS registration/token extraction.
crates/webui-parser/src/comment_policy.rs Adds shared helpers for comment classification and range stripping.
crates/webui-parser/benches/parser_bench.rs Adjusts benchmark templates to updated attribute patterns.
crates/webui-node/src/lib.rs Adds legal_comments option parsing/wiring in N-API build path + tests.
crates/webui-cli/src/commands/serve.rs Updates CLI tests/fixtures to include new build option field.
crates/webui-cli/src/commands/common.rs Adds --legal-comments CLI argument and wires into BuildOptions.
crates/webui-cli/src/commands/build.rs Updates CLI tests/fixtures to include new build option field.

Comment thread crates/webui-parser/src/comment_policy.rs
mohamedmansour and others added 3 commits June 5, 2026 21:17
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mohamedmansour mohamedmansour force-pushed the mmansour/strip-template-comments branch from 521f249 to 9ad838d Compare June 6, 2026 04:19
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mohamedmansour and others added 3 commits June 5, 2026 21:36
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mohamedmansour mohamedmansour changed the title fix: strip template comments in parser feat: strip template and style comments in parser and support legal comments Jun 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

webui-framework: comment bodies leak into the rendered page on CSR hydration

2 participants