Skip to content

Conversation

@vipul0425
Copy link
Contributor

What?

Closes #74148

Why?

Boolean attributes were being ignored during navigation via the iAPI router.

How?

This PR adds checks for boolean attributes and ensures they are preserved in the VDOM.

Testing Instructions

  1. Create a new test page.
  2. Add a Query Loop to that test page. It should be Custom query type, taget Posts, and show 1 item per page (to force pagination; a single item is enough to demonstrate the issue).
  3. Enable enhanced pagination on the Query Loop (disable "Reload full page" under the Advanced panel).
  4. Configure the Post Template such that it has a Details block, that Details block has contents to be shown when the details block is expanded, and that the Details block is configured to "Open by default". You can also add other blocks with such attributes like video and turn on autoplay.
  5. Publish the page, and review the rendered results. Verify the Details block expanded on first load, as well as on any pagination operations.

Screenshots or screencast

Screen.Recording.2025-12-25.at.2.54.10.PM.mov

@github-actions
Copy link

Warning: Type of PR label mismatch

To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.

  • Required label: Any label starting with [Type].
  • Labels found: .

Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task.

@github-actions github-actions bot added the [Package] Interactivity /packages/interactivity label Dec 25, 2025
@github-actions
Copy link

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @claycarpenter.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: claycarpenter.

Co-authored-by: vipul0425 <vipulgupta003@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Comment on lines +17 to +29
const booleanAttributes: readonly string[] = [
'open',
'checked',
'disabled',
'hidden',
'selected',
'readonly',
'required',
'autoplay',
'controls',
'loop',
'muted',
];
Copy link
Member

Choose a reason for hiding this comment

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

I'm still getting introduced to the iAPI code, which is not being straightforward, but something is not right with me with that list of “boolean attributes.”

The first thing that comes to my mind is to simply check for each element if they are of boolean type, instead of having to list the dozens of potential boolean types that could be useful for any use case.

Anyway, I would like to hear from @luisherranz

Copy link
Contributor

Choose a reason for hiding this comment

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

Hi @SirLouen 👋 I'm taking a look at this PR and the related issue.

It's true that we could check if a given attribute is of boolean type, although that comparison is not straightforward. Some attributes don't directly translate to their corresponding property (e.g., readonlyreadOnly, novalidatenoValidate, etc.) So, we would have to rely on a "list" for this, either all boolean attributes or the corresponding prop if they have a different name.

Copy link
Contributor

Choose a reason for hiding this comment

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

Regarding the list of all boolean attributes, this is what I get from Claude Opus 4.5:

Full Reference

Attribute Element(s) JavaScript Property MDN Link
allowfullscreen <iframe> allowFullscreen MDN
async <script> async MDN
autofocus Form elements, <dialog> autofocus MDN
autoplay <audio>, <video> autoplay MDN
checked <input> checked MDN
controls <audio>, <video> controls MDN
default <track> default MDN
defer <script> defer MDN
disabled Form elements, <link> disabled MDN
formnovalidate <button>, <input> formNoValidate MDN
hidden Global hidden MDN
inert Global inert MDN
ismap <img> isMap MDN
itemscope Global itemScope MDN
loop <audio>, <video> loop MDN
multiple <input>, <select> multiple MDN
muted <audio>, <video> muted MDN
nomodule <script> noModule MDN
novalidate <form> noValidate MDN
open <details>, <dialog> open MDN
playsinline <video> playsInline MDN
readonly <input>, <textarea> readOnly MDN
required <input>, <select>, <textarea> required MDN
reversed <ol> reversed MDN
selected <option> selected MDN
shadowrootclonable <template> shadowRootClonable MDN
shadowrootdelegatesfocus <template> shadowRootDelegatesFocus MDN
shadowrootserializable <template> shadowRootSerializable MDN

Attributes with Different HTML/DOM Names

HTML Attribute DOM Property MDN Link
allowfullscreen allowFullscreen MDN
formnovalidate formNoValidate MDN
ismap isMap MDN
itemscope itemScope MDN
nomodule noModule MDN
novalidate noValidate MDN
playsinline playsInline MDN
readonly readOnly MDN
shadowrootclonable shadowRootClonable MDN
shadowrootdelegatesfocus shadowRootDelegatesFocus MDN
shadowrootserializable shadowRootSerializable MDN

Copy link
Member

Choose a reason for hiding this comment

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

This is unmaintainable. The list may grow over time. Do you really think there isn't a more generalizable way to target them? For example, camelcase testing or something like that?

Copy link
Contributor

@DAreRodz DAreRodz Jan 7, 2026

Choose a reason for hiding this comment

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

Yeah, the list is quite long. 🤔 I agree that camelcase testing would be more approachable. Still, we would need a list of attributes that have their equivalent DOM prop in camelcase, right? This would have the same maintainability problem, given that the list could also grow over time.

Copy link
Member

@SirLouen SirLouen Jan 8, 2026

Choose a reason for hiding this comment

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

Yes, its almost impossible to achieve this

I've asked GPT for some ideas, and after reviewing and several iterations I got to this conclusion

Long story short:

  1. Gets all the elements from DOM
  2. Check against each element if the attribute is boolean by creating the element and adding the attribute and testing it
  3. There are some elements like async that are false by default and others like autofocus are true so it test in the two conditions
  4. Finally, it returns the result.

Conclusion: This is crazy low-performing and not viable. There could be some caching in between to slightly improve the overall performance.

Definitely the most performant way is still, to maintain a list. So at this point I wonder if there could be another implementation without having to necessarily check if it's boolean (or maybe just stick to the boolean elements we have in the inspector controls).

Copy link
Member

Choose a reason for hiding this comment

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

Preact checks the name in the element, and if it doesn't exist (because there's a camel case mismatch), it falls back to setAttribute.

`open` in `details` // true
// Preact uses elem[attr] = value;

`readonly` in `input` // false because it's readOnly, not readonly
// Preact uses elem.setAttribute(attr, value);

elem.setAttribute(attr, value) works fine when the element is boolean and the value is an empty string (""), so we don't have to worry about that case.

We can simply do this to match what Preact is doing underneath:

if (attributeValue === "" && typeof elementNode[attributeName] === "boolean") {
  props[attributeName] = elementNode[attributeName];
} else {
  props[attributeName] = attributeValue;
}

Alternative PR:

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice! Thanks, @luisherranz, that's a much better approach. I should have paid more attention to the internal nuances of Preact's diffing algorithm. 😅

@vipul0425, @SirLouen, I think we can close this PR in favor of #74446.

Copy link
Member

Choose a reason for hiding this comment

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

I had a hunch that there had to be a better solution. I'm not into preact so I would have never figured out. Time to close this 👍

@DAreRodz
Copy link
Contributor

DAreRodz commented Jan 8, 2026

Closed in favor of #74446.

@DAreRodz DAreRodz closed this Jan 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Interactivity /packages/interactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Details element missing open attribute after enhancement pagination content update

4 participants