feat(codemod-html-defaults): codemod removing redundant native HTML attribute defaults - #294
Open
smndhm wants to merge 3 commits into
Open
feat(codemod-html-defaults): codemod removing redundant native HTML attribute defaults#294smndhm wants to merge 3 commits into
smndhm wants to merge 3 commits into
Conversation
…ML attribute defaults New package @dume/codemod-html-defaults: a CLI + library that removes native HTML attributes whose literal value is already the WHATWG spec default (<input type="text">, <form method="get">, <script type="text/javascript">, ...). - Defaults sourced from html-enumerated-attributes (WHATWG missing value defaults as state equivalence classes) plus a spec-linked supplementary table for non-enumerated cases (script/style/link type), cross-checked against jsdom's WHATWG reflection in tests. - Contextual defaults are never applied flatly: target/_self requires a full document without <base target>, link[type] requires rel="stylesheet", and button[type="submit"] is only reported, never removed. - Never touches dynamic bindings/interpolations, boolean attributes, empty values, custom elements, foreign (SVG) content, or start tags with duplicate attributes; edits are byte-preserving outside removed ranges so HTML-shaped templates (Nunjucks) are safe. - Dry-run by default with a per-attribute report, --write to apply, idempotent; functional no-op on form submission behavior proven in tests, not just snapshots. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QjF61pCbakF8bMW4XaaFeW
🦋 Changeset detectedLatest commit: 7893919 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Adopt the conventional codemod test layout: each tests/fixtures/<name>.input.<ext> is transformed and compared byte for byte to its <name>.expected.<ext> sibling, with an idempotence check on every expected file. Fixtures cover a full document, a form, the <base target> conditional, a Nunjucks template, and a no-changes corpus (booleans, dynamic values, SVG, custom elements, duplicate attributes). Fixtures are excluded from prettier so the pairs stay byte-exact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QjF61pCbakF8bMW4XaaFeW
Add @dume/codemod-html-defaults/codemod, a default-exported transform(root) -> string | null step matching the codemod:ast-grep workflow contract, so the package can slot into an existing rollout alongside other workflow scripts. It reuses the parse5 engine untouched, returns null for untouched files, logs one line per changed file and reports conditional skips as info lines. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QjF61pCbakF8bMW4XaaFeW
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.
New package
@dume/codemod-html-defaults: a CLI + library that removes native HTML attributes whose literal value is already the WHATWG spec default — e.g.<input type="text">→<input>,<form method="get">→<form>,<script type="text/javascript">→<script>.Usage
Runs are idempotent, and edits are byte-preserving outside the removed attribute ranges (parse5 + source locations), so HTML-shaped templates like the Nunjucks files in
apps/articlesare safe.Where the defaults come from (nothing from memory)
html-enumerated-attributes(MIT, unified collective), which encodes the WHATWG missing value defaults as state equivalence classes. A value is removable only when it belongs to the same state group as the missing value default.src/defaults.tsfor the non-enumerated cases (script[type],style[type],link[type]), cross-checked withhtml-minifier-terser's redundant-attribute handling.input.type === 'text',form.method === 'get',button.type === 'submit', …).Conditional defaults — never applied flatly
button[type="submit"]: never removed in v1, only reported (behavior depends on form association; explicit types are often kept for readability).target="_self"ona/area/form: removed only in a full document with no<base target>; fragments are always skipped (a partial may be included under a layout with<base>);targeton<base>itself is never touched.link[type="text/css"]: removed only when the element's staticrelcontains thestylesheettoken.Never touched
Dynamic values (
{{ }},{% %},<%= %>,${}) and binding attribute names (:type,v-bind:,ng-*), boolean attributes and empty values, custom elements, foreign (SVG/MathML) content, and start tags containing duplicate attributes.Verification
apps/: 7 files scanned, 0 changes (repo already clean;type="module"correctly untouched).pnpm lint,manypkg checkand the package'svite buildall pass. Note:slides#buildfails in turbo onmaintoo (marp-cli browser discovery, environment issue) — unrelated to this change.A changeset is included for the initial 1.0.0 release.
🤖 Generated with Claude Code
https://claude.ai/code/session_01QjF61pCbakF8bMW4XaaFeW
Generated by Claude Code