Skip to content

fix: [#2379] HTMLElement.hidden reflects the enumerated until-found state - #2380

Open
marciomazza wants to merge 1 commit into
capricorn86:masterfrom
marciomazza:fix/hidden-until-found
Open

fix: [#2379] HTMLElement.hidden reflects the enumerated until-found state#2380
marciomazza wants to merge 1 commit into
capricorn86:masterfrom
marciomazza:fix/hidden-until-found

Conversation

@marciomazza

Copy link
Copy Markdown

Description

Resolves #2379

HTMLElement.hidden models the hidden attribute as a strict boolean, but it is an enumerated
attribute since hidden-until-found landed in HTML. An element with hidden="until-found" reads
back as true, and assigning 'until-found' writes hidden="" — the until-found state is
invisible and unsettable through the property.

const el = new Window().document.createElement('div');
el.setAttribute('hidden', 'until-found');
el.hidden;                    // happy-dom: true — real browsers: "until-found"
el.hidden = 'until-found';
el.getAttribute('hidden');    // happy-dom: "" — real browsers: "until-found"

Root cause: the getter returns getAttribute('hidden') !== null and the setter only branches on
truthiness, so it never distinguishes the until-found keyword.

Fix: the getter/setter type becomes boolean | string; the getter returns 'until-found' when
the attribute's value is that keyword (ASCII case-insensitive), true for any other value,
false when absent; the setter writes hidden="until-found" for that keyword, hidden="" for
other truthy values, and removes the attribute for falsy ones.

Deliberate: el.hidden = undefined removes the attribute rather than writing "" (outside the
declared type anyway); the keyword check uses toLowerCase(), not strict ASCII case-folding, to
match the repo's convention for other reflected enums (contentEditable, etc.). This is
attribute reflection only — it does not implement the find-in-page reveal / beforematch
behavior, which is not meaningful in a headless DOM.

Tests

Added 7 tests: getter returns false when absent, 'until-found' for the keyword,
case-insensitively, true otherwise; setter sets the until-found state, removes the attribute
for falsy values including '', and sets plain hidden for other strings. Full npm test passes.

AI

I used Claude Code to write this, over multiple iterations. I guided and reviewed
it myself at every step.

Before submitting the PR, please make sure you do the following:

  • Read the contributing guidelines.
  • It's really useful if your PR references an issue where it is discussed ahead of time.
  • Please check Allow edits by maintainers to make review process faster. Note that this option is not available for repositories that are owned by Github organizations.

Tests

  • Make sure to add tests for your changes. Run your test in a real browser to make sure that the test tests what a real browser would do (e.g. by running the code in the browser console).
    • Ran the repro in Chrome 152 console: el.hidden is "until-found" (typeof string) for hidden="until-found"; el.hidden = 'until-found' keeps the attribute "until-found"; = true writes ""; = false removes it. Matches the fixed behavior.
  • Run the tests with npm test locally to make sure that all tests pass before submitting the PR.

Title

  • The title of the pull request should be in the format of "type: [#issue] description". The type can be feat, fix, chore or BREAKING CHANGE. The issue is optional and can be omitted if the pull request does not relate to an issue.
  • The title should be concise and descriptive. The title will be used when generating release notes. Make sure that the title is easily understood by users of the library.

AI tools

  • Please disclose in the PR description that you used AI tools to generate code. This is important for transparency and to ensure that the generated code meets the quality standards of the project.

@marciomazza
marciomazza force-pushed the fix/hidden-until-found branch from f243dfd to 53d5531 Compare September 8, 2026 13:42
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.

HTMLElement.hidden is a plain boolean, so hidden="until-found" is lost

1 participant