diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index bd17b8554587..c406c2ba3420 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -269,6 +269,76 @@ void nsGenericHTMLElement::GetAccessKeyLabel(nsString& aLabel) { } } +// https://html.spec.whatwg.org/#dom-hidden +void nsGenericHTMLElement::GetHidden( + Nullable& aHidden) const { + OwningBooleanOrUnrestrictedDoubleOrString value; + // 1. If the hidden attribute is in the hidden until found state, then + // return "until-found". + nsAutoString result; + if (GetAttr(kNameSpaceID_None, nsGkAtoms::hidden, result)) { + if (StaticPrefs::dom_hidden_until_found_enabled() && + result.LowerCaseEqualsLiteral("until-found")) { + value.SetStringLiteral(u"until-found"); + } else { + // 2. If the hidden attribute is set, then return true. + value.SetAsBoolean() = true; + } + } else { + // 3. Return false. + value.SetAsBoolean() = false; + } + + aHidden.SetValue(value); +} + +// https://html.spec.whatwg.org/#dom-hidden +void nsGenericHTMLElement::SetHidden( + const Nullable& aHidden, + ErrorResult& aRv) { + // 4. Otherwise, if the given value is null, then remove the hidden attribute. + if (aHidden.IsNull()) { + return UnsetAttr(nsGkAtoms::hidden, aRv); + } + bool isHidden = true; + const auto& value = aHidden.Value(); + // 1. If the given value is a string that is an ASCII case-insensitive match + // for "until-found", then set the hidden attribute to "until-found". + if (value.IsString()) { + const nsAString& stringValue = value.GetAsString(); + // 3. Otherwise, if the given value is the empty string, then remove the + // hidden attribute. + if (stringValue.IsEmpty()) { + isHidden = false; + } else if (StaticPrefs::dom_hidden_until_found_enabled() && + stringValue.LowerCaseEqualsLiteral("until-found")) { + return SetAttr(nsGkAtoms::hidden, u"until-found"_ns, aRv); + } + } + // 2. Otherwise, if the given value is false, then remove the hidden + // attribute. + else if (value.IsBoolean()) { + if (!value.GetAsBoolean()) { + isHidden = false; + } + } + // 5. Otherwise, if the given value is 0, then remove the hidden attribute. + // 6. Otherwise, if the given value is NaN, then remove the hidden attribute. + else if (value.IsUnrestrictedDouble()) { + double d = value.GetAsUnrestrictedDouble(); + if (d == 0.0 || std::isnan(d)) { + isHidden = false; + } + } + + // 7. Otherwise, set the hidden attribute to the empty string. + if (isHidden) { + aRv = SetAttr(kNameSpaceID_None, nsGkAtoms::hidden, u""_ns, true); + } else { + aRv = UnsetAttr(kNameSpaceID_None, nsGkAtoms::hidden, true); + } +} + static bool IsOffsetParent(nsIFrame* aFrame) { LayoutFrameType frameType = aFrame->Type(); diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h index 66ec09e6daf0..43276ff6840c 100644 --- a/dom/html/nsGenericHTMLElement.h +++ b/dom/html/nsGenericHTMLElement.h @@ -14,6 +14,7 @@ #include "nsContentCreatorFunctions.h" #include "nsStyledElement.h" #include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/dom/HTMLElementBinding.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/DOMRect.h" #include "mozilla/dom/ValidityState.h" @@ -95,10 +96,16 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase { void SetPopover(const nsAString& aPopover, mozilla::ErrorResult& aError) { SetOrRemoveNullableStringAttr(nsGkAtoms::popover, aPopover, aError); } - bool Hidden() const { return GetBoolAttr(nsGkAtoms::hidden); } - void SetHidden(bool aHidden, mozilla::ErrorResult& aError) { - SetHTMLBoolAttr(nsGkAtoms::hidden, aHidden, aError); - } + + void GetHidden(mozilla::dom::Nullable< + mozilla::dom::OwningBooleanOrUnrestrictedDoubleOrString>& + aHidden) const; + + void SetHidden( + const mozilla::dom::Nullable< + mozilla::dom::BooleanOrUnrestrictedDoubleOrString>& aHidden, + mozilla::ErrorResult& aRv); + bool Inert() const { return GetBoolAttr(nsGkAtoms::inert); } void SetInert(bool aInert, mozilla::ErrorResult& aError) { SetHTMLBoolAttr(nsGkAtoms::inert, aInert, aError); diff --git a/dom/webidl/HTMLElement.webidl b/dom/webidl/HTMLElement.webidl index c0922f7b7a98..a112fec8e899 100644 --- a/dom/webidl/HTMLElement.webidl +++ b/dom/webidl/HTMLElement.webidl @@ -33,7 +33,7 @@ interface HTMLElement : Element { // user interaction [CEReactions, SetterThrows, Pure] - attribute boolean hidden; + attribute (boolean or unrestricted double or DOMString)? hidden; [CEReactions, SetterThrows, Pure] attribute boolean inert; [NeedsCallerType] diff --git a/testing/web-platform/meta/html/editing/the-hidden-attribute/__dir__.ini b/testing/web-platform/meta/html/editing/the-hidden-attribute/__dir__.ini new file mode 100644 index 000000000000..a15e737e44c3 --- /dev/null +++ b/testing/web-platform/meta/html/editing/the-hidden-attribute/__dir__.ini @@ -0,0 +1 @@ +prefs: [dom.hidden_until_found.enabled:true] \ No newline at end of file diff --git a/testing/web-platform/meta/html/editing/the-hidden-attribute/hidden-idl.html.ini b/testing/web-platform/meta/html/editing/the-hidden-attribute/hidden-idl.html.ini deleted file mode 100644 index 3e5a92d47b2f..000000000000 --- a/testing/web-platform/meta/html/editing/the-hidden-attribute/hidden-idl.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[hidden-idl.html] - [div.hidden = "until-found"] - expected: FAIL - - [div.hidden = "UNTIL-FOUND"] - expected: FAIL - - [div.hidden = "UnTiL-FoUnD"] - expected: FAIL diff --git a/testing/web-platform/meta/html/editing/the-hidden-attribute/hidden-until-found-007.html.ini b/testing/web-platform/meta/html/editing/the-hidden-attribute/hidden-until-found-007.html.ini deleted file mode 100644 index ea525afbaf24..000000000000 --- a/testing/web-platform/meta/html/editing/the-hidden-attribute/hidden-until-found-007.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[hidden-until-found-007.html] - expected: FAIL diff --git a/testing/web-platform/meta/html/editing/the-hidden-attribute/hidden-until-found-idl.html.ini b/testing/web-platform/meta/html/editing/the-hidden-attribute/hidden-until-found-idl.html.ini deleted file mode 100644 index 1505f47bcd43..000000000000 --- a/testing/web-platform/meta/html/editing/the-hidden-attribute/hidden-until-found-idl.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[hidden-until-found-idl.html] - [element.hidden should return "until-found" regardless of uppercase letters.] - expected: FAIL diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py index e060f6cd2009..26af767ade95 100644 --- a/xpcom/ds/StaticAtoms.py +++ b/xpcom/ds/StaticAtoms.py @@ -1302,6 +1302,7 @@ STATIC_ATOMS = [ Atom("u", "u"), Atom("ul", "ul"), Atom("unparsedEntityUri", "unparsed-entity-uri"), + Atom("untilFound", "until-found"), Atom("up", "up"), Atom("update", "update"), Atom("upperFirst", "upper-first"),