Skip to content

hidden="until-found" is minified to bare hidden, which changes behavior #292

Open

Description

@oddharsh

The HTML spec defines hidden as an enumerated attribute with two states (spec). hidden="until-found" collapses the element but leaves it reachable: find-in-page and fragment navigation can reveal it, and it fires beforematch when they do. minify-html rewrites it to bare hidden, which the browser never reveals, so minifying changes what the page does.

Repro

@minify-html/node 0.18.1, default options:

import m from "@minify-html/node";
m.minify(Buffer.from('<p hidden="until-found" id=a>x</p>'), {}).toString();
// actual:   '<p hidden id=a>x'
// expected: '<p hidden=until-found id=a>x'

Any value collapses the same way ("bogus" and "" included). No option keeps it.

Cause

minify-html-common/html-data_2023013104.0.0.json marks hidden as {"boolean": true} on every element. minify-html/src/minify/attr.rs then drops the value of any boolean attribute, whatever it is:

if is_boolean || value_raw.is_empty() {
  return AttrMinified::NoValue;
};

Main (697c04a) has the same code.

Possible fixes

  1. Special-case hidden: keep the value when it's until-found (ASCII case-insensitive). Every other value, the empty string included, maps to the plain hidden state, so collapsing those stays safe.
  2. More general: collapse a boolean attribute only when its value is empty or matches the attribute name, case-insensitively. The spec allows only those two values on a true boolean attribute. Any other value means the input either isn't plain boolean or isn't valid, and keeping it is the safe choice. This would also cover the next boolean that grows a second state.

I can send a PR for either; tell me which you prefer.

Context

We hit this on a live page: a demo's target element has shipped as bare hidden since the demo went live, so find-in-page never revealed it. We now swap the value through a placeholder attribute before minifying and restore it afterwards, the approach #219 describes. #81 was an earlier case where html-data's attribute table disagreed with browsers.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions