Skip to content

feat(html): add normalizeUrlAttributes and widen two attribute rewrites - #12

Open
anurag6569201 wants to merge 1 commit into
qa/agent-webpack-webpack/pr-12-21960/basefrom
qa/agent-webpack-webpack/pr-12-21960/head
Open

anurag6569201 wants to merge 1 commit into
qa/agent-webpack-webpack/pr-12-21960/basefrom
qa/agent-webpack-webpack/pr-12-21960/head

Conversation

@anurag6569201

Copy link
Copy Markdown

Summary

Grew out of reviewing webpack#21730 by @aryanraj45, whose four proposed switches are mostly on main already; this lands what is still missing and two bugs found while checking. normalizeUrlAttributes gates the whitespace trim around a URL value — the one rewrite of that family with no way to turn it off, though it changes the string getAttribute hands back like its three siblings. collapseBooleanAttributes gains the "all" tier lib/html/htmlMinify.js's own TODO asked for: true still rewrites only the spelling the spec canonicalizes, "all" any value, including the checked="false" that already means checked.

Two things were broken rather than missing. sortTokenLists silently did nothing whenever normalizeListAttributes was off, though its own description calls it separate. And a style attribute needs no switch of its own — it is an embedded body, so a renderer answering with the list it was given keeps it — but that worked only synchronously: where the answer is deferred, an answer nothing beats was read as no answer and the built-in's text stood, which is the path webpack's own minimizer takes.

Neither new option is here for bytes: over the 68,253 documents in web-platform-tests, "all" changes 27 files (184 bytes) and the URL trim fires on 38 (114 bytes). They exist so a consumer that compares those bytes has a way out, which is why the rest of the family exists.

What kind of change does this PR introduce?

feat

Did you add tests for your changes?

Yes — a SourceProcessor — attribute rewrites as switches block in test/HtmlSyntax.unittest.js, and two config cases, minimize-collapse-boolean-attributes-all and minimize-sort-token-lists-alone; minimize-transforms-off gained the new switch. Every added line and branch arm is covered.

Does this PR introduce a breaking change?

No. Both options default to what webpack already did, and the two fixes only make an option and a renderer's answer take effect where they were dropped.

If relevant, what needs to be documented once your changes are merged or what have you already documented?

The normalizeUrlAttributes option and collapseBooleanAttributes's "all" tier, plus the note added to sortTokenLists that it applies whatever normalizeListAttributes says.

Use of AI

Claude Code was used to compare webpack#21730 against main, to write this change and its tests, and to verify it: the wpt measurement above, yarn lint in full, the html unit and config suites, and syntax-equivalence over the wpt corpus were all run locally. I reviewed every change.


Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added normalizeUrlAttributes to trim surrounding whitespace from URL attributes when enabled.
    • Added collapseBooleanAttributes: "all" to collapse boolean attribute values into bare attributes.
    • Token lists are sorted even when list normalization is disabled.
  • Bug Fixes
    • Improved deferred inline-style handling while preserving original syntax when no custom transformation is applied.
  • Documentation
    • Updated HTML minimization option descriptions and configuration schema.

Source merge-base: a03c24a180ed6ebfa5b38b23cf1148a4cc3378c7
Source head: eaddc87476c00d02e7bb6e05c9b5c9529d8dee4b

@shipwright-agent

Copy link
Copy Markdown

⛔ Shipwright · Blocked

Recommendation: do not merge PR #12 · Tier T2
Checks: 0 total · 0 needing attention

Next step: resolve the blocking findings before merge.

Findings (6)

  • CRITICAL The new 'collapseBooleanAttributes: "all"' mode rewrites any value on a boolean attribute to the bare name, including 'checked="false"' and 'defer="no"'. · lib/html/syntax.js:11046
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • CRITICAL 'normalizeUrlAttributes' is enabled by default and trims ASCII whitespace around URL-valued attributes. · lib/html/syntax.js:10435
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • HIGH The conditional expression introduced for 'tokenListOn' mixes '_transforms.normalizeListAttributes', '_sortTokenLists', and 'DOM_TOKEN_LIST_ATTRIBUTES.has(name)' with a ternary and · lib/html/syntax.js:10412
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • HIGH The deferred embedded style handling now computes 'delimiter' as 'open[valueStart - tagStart - 1]' and builds 'asWritten' from raw source offsets. · lib/html/syntax.js:11087
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • HIGH The generated schema changes 'collapseBooleanAttributes' from 'simpleType: "boolean"' to 'simpleType: "string"' while also adding an enum branch. · schemas/WebpackOptions.check.js:12055
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • LOW The new test 'minimize-collapse-boolean-attributes-all/index.js' contains a tautological assertion ('expect(true).toBe(true)') and relies entirely on snapshot/afterExecute checks. · test/configCases/html/minimize-collapse-boolean-attributes-all/index.js:3
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

Fireworks usage: 41,045 input · 794 output · 41,839 total tokens · $0.0096 · 15s · 0 fix iteration(s)

Open the Shipwright check for full evidence and the audit bundle. Use /shipwright rerun to verify again.

Comment thread lib/html/syntax.js
if (COMMA_LIST_ATTRIBUTES.has(name)) return _normalizeCommaList(raw);
}
const urlOn = URL_ATTRIBUTES.get(name);
const urlOn = _transforms.normalizeUrlAttributes

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shipwright · CRITICAL

'normalizeUrlAttributes' is enabled by default and trims ASCII whitespace around URL-valued attributes.

Impact: 'normalizeUrlAttributes' is enabled by default and trims ASCII whitespace around URL-valued attributes. The change assumes URL resolution always skips surrounding whitespace, but this is not universally true for all URL attributes, custom elements, or non-browser consumers. Trimming can alter 'getAttribute' results and potentially change how URLs are parsed by downstream systems, creating a security-relevant behavio…

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

Comment thread lib/html/syntax.js
? writeStyle(declarations !== null ? declarations : value)
: _writeAttribute(attributeName, value, rawValue, spellable);

// Offered whatever the built-in made of it: a list already at its

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shipwright · HIGH

The deferred embedded style handling now computes 'delimiter' as 'open[valueStart - tagStart - 1]' and builds 'asWritten' from raw source offsets.

Impact: The deferred embedded style handling now computes 'delimiter' as 'open[valueStart - tagStart - 1]' and builds 'asWritten' from raw source offsets. If 'valueStart' or 'tagStart' is at the beginning of the buffer, or the attribute is unquoted, this indexing can read the wrong character or produce an invalid reconstructed attribute. The previous code did not perform this raw-offset reconstruction, so this is a new fail…

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

@@ -0,0 +1,6 @@
import "./page.html";

it("should write a boolean attribute bare whatever its value said", () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shipwright · LOW

The new test 'minimize-collapse-boolean-attributes-all/index.js' contains a tautological assertion ('expect(true).toBe(true)') and relies entirely on snapshot/afterExecute checks.

Impact: The new test 'minimize-collapse-boolean-attributes-all/index.js' contains a tautological assertion ('expect(true).toBe(true)') and relies entirely on snapshot/afterExecute checks. This makes the test's intent opaque to a new contributor and provides no direct behavioral assertion in the test body.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

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.

1 participant