feat(fast-build): strip state-passing binding attrs from root custom elements#7403
Draft
feat(fast-build): strip state-passing binding attrs from root custom elements#7403
Conversation
…elements
When rendering entry HTML via render_entry_with_templates / render_entry_template_with_locator, root custom elements receive the full root state directly. Any attribute whose value is a pure {{expr}} double-brace binding was only needed to forward state via the attribute-based child state mechanism — with entry-level rendering that mechanism is bypassed, so these attributes are now stripped from the rendered HTML output.
Examples stripped: list="{{list}}", item_parent="{{item_parent}}", someData="{{someData}}"
Static attributes (id, class, disabled, etc.) are preserved.
Changes:
- attribute.rs: add is_state_passing_binding() and strip_entry_attrs() (strips client-only attrs + {{binding}} attrs)
- directive.rs: build_element_open_tag gains is_entry param; uses strip_entry_attrs when true
- wasm.rs: expose render_entry_with_templates WASM binding
- fast.js CLI: use render_entry_with_templates when templates are provided
- tests/custom_elements.rs: 4 new tests for entry-level attr stripping behaviour
- Regenerate attribute, binding, event fixture index.html files
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…s-on-root-elements
…ents; strip non-primitives
For entry-level root custom elements, {{binding}} attribute values are now resolved
from root state:
- Primitive (string/number/bool): rendered with resolved value, e.g. text="{{msg}}" → text="Hello world"
- Non-primitive (array/object/null): stripped — cannot be an HTML attribute value
Static attributes (no binding syntax) are passed through unchanged.
This is implemented via build_entry_element_open_tag in directive.rs which replaces
the earlier strip_entry_attrs approach. HTML escaping is applied to string values.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
📖 Description
When rendering the top-level entry HTML via
render_entry_with_templates/render_entry_template_with_locator, root custom elements receive the full root state directly. Before this change, any{{binding}}attribute on a root element was resolved and written into the rendered HTML — e.g.list="{{list}}"becamelist="[Array]"orsomeData="[Object]". These attributes existed solely to forward state through the old attribute-based child state mechanism; with entry-level rendering that mechanism is bypassed, making the attributes both redundant and noisy.This PR strips any attribute whose value is a pure
{{expr}}double-brace binding from root custom element opening tags in the rendered HTML output. Static attributes (id,class,disabled, etc.) are preserved.Additionally,
render_entry_with_templatesis now exposed as a WASM binding and the@microsoft/fast-buildCLI is updated to use it when templates are provided, so the fixture build tool uses entry-level semantics by default.📑 Test Plan
npm run build:fixtures -w @microsoft/fast-htmlregenerates correctly:attribute,binding, andeventfixtures no longer include resolved{{binding}}attrs on root elementscargo test— 182 tests across all suites)✅ Checklist
General
$ npm run change