diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index a57ec5af0c75..5d90627d5c36 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -1155,6 +1155,7 @@ CustomElementRegistry::Upgrade(Element* aElement, // Step 8. data->mState = CustomElementData::State::eCustom; + aElement->SetDefined(true); // Step 9. aElement->SetCustomElementDefinition(aDefinition); diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index e7ec9caf3767..1f5b6262fa2a 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -4284,18 +4284,18 @@ void Element::SetCustomElementData(CustomElementData* aData) { SetHasCustomElementData(); + + if (aData->mState != CustomElementData::State::eCustom) { + SetDefined(false); + } + nsExtendedDOMSlots *slots = ExtendedDOMSlots(); MOZ_ASSERT(!slots->mCustomElementData, "Custom element data may not be changed once set."); #if DEBUG - nsAtom* name = NodeInfo()->NameAtom(); - nsAtom* type = aData->GetCustomElementType(); - if (NodeInfo()->NamespaceID() == kNameSpaceID_XHTML) { - if (nsContentUtils::IsCustomElementName(name, kNameSpaceID_XHTML)) { - MOZ_ASSERT(type == name); - } else { - MOZ_ASSERT(type != name); - } - } else { // kNameSpaceID_XUL + // We assert only XUL usage, since web may pass whatever as 'is' value + if (NodeInfo()->NamespaceID() == kNameSpaceID_XUL) { + nsAtom* name = NodeInfo()->NameAtom(); + nsAtom* type = aData->GetCustomElementType(); // Check to see if the tag name is a dashed name. if (nsContentUtils::IsNameWithDash(name)) { // Assert that a tag name with dashes is always an autonomous custom diff --git a/dom/base/Element.h b/dom/base/Element.h index df40a40319d7..4334392a140b 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -150,7 +150,7 @@ public: #ifdef MOZILLA_INTERNAL_API explicit Element(already_AddRefed& aNodeInfo) : FragmentOrElement(aNodeInfo), - mState(NS_EVENT_STATE_MOZ_READONLY) + mState(NS_EVENT_STATE_MOZ_READONLY | NS_EVENT_STATE_DEFINED) { MOZ_ASSERT(mNodeInfo->NodeType() == ELEMENT_NODE, "Bad NodeType in aNodeInfo"); @@ -553,6 +553,14 @@ public: */ void SetCustomElementDefinition(CustomElementDefinition* aDefinition); + void SetDefined(bool aSet) + { + if (aSet) { + AddStates(NS_EVENT_STATE_DEFINED); + } else { + RemoveStates(NS_EVENT_STATE_DEFINED); + } + } protected: /** * Method to get the _intrinsic_ content state of this element. This is the diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 6bd142a847a9..acd09e37b505 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -9924,9 +9924,6 @@ nsContentUtils::NewXULOrHTMLElement(Element** aResult, mozilla::dom::NodeInfo* a int32_t tag = eHTMLTag_unknown; bool isCustomElementName = false; if (nodeInfo->NamespaceEquals(kNameSpaceID_XHTML)) { - if (aIsAtom && !nsContentUtils::IsNameWithDash(aIsAtom)) { - aIsAtom = nullptr; - } tag = nsHTMLTags::CaseSensitiveAtomTagToId(name); isCustomElementName = (tag == eHTMLTag_userdefined && nsContentUtils::IsCustomElementName(name, kNameSpaceID_XHTML)); @@ -10042,6 +10039,7 @@ nsContentUtils::NewXULOrHTMLElement(Element** aResult, mozilla::dom::NodeInfo* a } else { NS_IF_ADDREF(*aResult = nsXULElement::Construct(nodeInfo.forget())); } + (*aResult)->SetDefined(false); } return NS_OK; } diff --git a/dom/events/EventStates.h b/dom/events/EventStates.h index 27f5a1280f6a..dcb4daab4ea7 100644 --- a/dom/events/EventStates.h +++ b/dom/events/EventStates.h @@ -243,7 +243,8 @@ private: #define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(21) // Content is optional (and can be required). #define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(22) -// Free bit NS_DEFINE_EVENT_STATE_MACRO(23) +// Element is either a defined custom element or uncustomized element. +#define NS_EVENT_STATE_DEFINED NS_DEFINE_EVENT_STATE_MACRO(23) // Link has been visited. #define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(24) // Link hasn't been visited. @@ -354,6 +355,7 @@ private: DISABLED_STATES | \ REQUIRED_STATES | \ NS_EVENT_STATE_ACTIVE | \ + NS_EVENT_STATE_DEFINED | \ NS_EVENT_STATE_DRAGOVER | \ NS_EVENT_STATE_FOCUS | \ NS_EVENT_STATE_FOCUSRING | \ diff --git a/servo/components/style/element_state.rs b/servo/components/style/element_state.rs index 0960ca3d4e11..c57cf4febe6a 100644 --- a/servo/components/style/element_state.rs +++ b/servo/components/style/element_state.rs @@ -71,7 +71,8 @@ bitflags! { const IN_OPTIONAL_STATE = 1 << 22; /// const IN_READ_WRITE_STATE = 1 << 22; - /// There is a free bit at 23. + /// + const IN_DEFINED_STATE = 1 << 23; /// const IN_VISITED_STATE = 1 << 24; /// diff --git a/servo/components/style/gecko/non_ts_pseudo_class_list.rs b/servo/components/style/gecko/non_ts_pseudo_class_list.rs index b02e21fbf8a8..56e62b6de4bc 100644 --- a/servo/components/style/gecko/non_ts_pseudo_class_list.rs +++ b/servo/components/style/gecko/non_ts_pseudo_class_list.rs @@ -47,6 +47,7 @@ macro_rules! apply_non_ts_list { ("visited", Visited, visited, IN_VISITED_STATE, _), ("active", Active, active, IN_ACTIVE_STATE, _), ("checked", Checked, checked, IN_CHECKED_STATE, _), + ("defined", Defined, defined, IN_DEFINED_STATE, _), ("disabled", Disabled, disabled, IN_DISABLED_STATE, _), ("enabled", Enabled, enabled, IN_ENABLED_STATE, _), ("focus", Focus, focus, IN_FOCUS_STATE, _), diff --git a/servo/components/style/gecko/selector_parser.rs b/servo/components/style/gecko/selector_parser.rs index 57a98a89238b..7dfc9aa1bbc0 100644 --- a/servo/components/style/gecko/selector_parser.rs +++ b/servo/components/style/gecko/selector_parser.rs @@ -187,6 +187,9 @@ impl NonTSPseudoClass { NonTSPseudoClass::Fullscreen => unsafe { mozilla::StaticPrefs_sVarCache_full_screen_api_unprefix_enabled }, + NonTSPseudoClass::Defined => unsafe { + structs::nsContentUtils_sIsCustomElementsEnabled + }, // Otherwise, a pseudo-class is enabled in content when it // doesn't have any enabled flag. _ => !self.has_any_flag( diff --git a/servo/components/style/gecko/wrapper.rs b/servo/components/style/gecko/wrapper.rs index ffac86e974f7..47205f7378bb 100644 --- a/servo/components/style/gecko/wrapper.rs +++ b/servo/components/style/gecko/wrapper.rs @@ -2124,6 +2124,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { { use selectors::matching::*; match *pseudo_class { + NonTSPseudoClass::Defined | NonTSPseudoClass::Focus | NonTSPseudoClass::Enabled | NonTSPseudoClass::Disabled | diff --git a/testing/web-platform/meta/custom-elements/Document-createElement.html.ini b/testing/web-platform/meta/custom-elements/Document-createElement.html.ini index e82f6c98943a..3917b1d99302 100644 --- a/testing/web-platform/meta/custom-elements/Document-createElement.html.ini +++ b/testing/web-platform/meta/custom-elements/Document-createElement.html.ini @@ -7,6 +7,3 @@ [document.createElement must not report a NotSupportedError when the element is adopted back from a the document of an iframe during construction] expected: FAIL - - [document.createElement must create an instance of autonomous custom elements when it has is attribute] - expected: FAIL diff --git a/testing/web-platform/meta/custom-elements/pseudo-class-defined.html.ini b/testing/web-platform/meta/custom-elements/pseudo-class-defined.html.ini deleted file mode 100644 index 489ff955dcb6..000000000000 --- a/testing/web-platform/meta/custom-elements/pseudo-class-defined.html.ini +++ /dev/null @@ -1,119 +0,0 @@ -[pseudo-class-defined.html] - max-asserts: 4 - [
should be :defined] - expected: FAIL - - [createElement("div") should be :defined] - expected: FAIL - - [createElementNS("http://www.w3.org/1999/xhtml", "div") should be :defined] - expected: FAIL - - [createElementNS("http://www.w3.org/2000/svg", "div") should be :defined] - expected: FAIL - - [Without browsing context: createElement("div") should be :defined] - expected: FAIL - - [Without browsing context: createElementNS("http://www.w3.org/1999/xhtml", "div") should be :defined] - expected: FAIL - - [Without browsing context: createElementNS("http://www.w3.org/2000/svg", "div") should be :defined] - expected: FAIL - - [ should not be :defined] - expected: FAIL - - [createElement("a-a") should not be :defined] - expected: FAIL - - [createElementNS("http://www.w3.org/1999/xhtml", "a-a") should not be :defined] - expected: FAIL - - [createElementNS("http://www.w3.org/2000/svg", "a-a") should be :defined] - expected: FAIL - - [Upgraded createElement("a-a") should be :defined] - expected: FAIL - - [Upgraded createElementNS("http://www.w3.org/1999/xhtml", "a-a") should be :defined] - expected: FAIL - - [Without browsing context: createElement("a-a") should not be :defined] - expected: FAIL - - [Without browsing context: createElementNS("http://www.w3.org/1999/xhtml", "a-a") should not be :defined] - expected: FAIL - - [Without browsing context: createElementNS("http://www.w3.org/2000/svg", "a-a") should be :defined] - expected: FAIL - - [ should be :defined] - expected: FAIL - - [createElement("font-face") should be :defined] - expected: FAIL - - [createElementNS("http://www.w3.org/1999/xhtml", "font-face") should be :defined] - expected: FAIL - - [createElementNS("http://www.w3.org/2000/svg", "font-face") should be :defined] - expected: FAIL - - [Without browsing context: createElement("font-face") should be :defined] - expected: FAIL - - [Without browsing context: createElementNS("http://www.w3.org/1999/xhtml", "font-face") should be :defined] - expected: FAIL - - [Without browsing context: createElementNS("http://www.w3.org/2000/svg", "font-face") should be :defined] - expected: FAIL - - [ should not be :defined] - expected: FAIL - - [createElement("abbr", { is: "my-abbr" }) should not be :defined] - expected: FAIL - - [createElementNS("http://www.w3.org/1999/xhtml", "abbr", { is: "my-abbr" }) should not be :defined] - expected: FAIL - - [createElementNS("http://www.w3.org/2000/svg", "abbr", { is: "my-abbr" }) should be :defined] - expected: FAIL - - [Upgraded createElement("abbr", { is: "my-abbr" }) should be :defined] - expected: FAIL - - [Upgraded createElementNS("http://www.w3.org/1999/xhtml", "abbr", { is: "my-abbr" }) should be :defined] - expected: FAIL - - [Without browsing context: createElement("abbr", { is: "my-abbr" }) should not be :defined] - expected: FAIL - - [Without browsing context: createElementNS("http://www.w3.org/1999/xhtml", "abbr", { is: "my-abbr" }) should not be :defined] - expected: FAIL - - [Without browsing context: createElementNS("http://www.w3.org/2000/svg", "abbr", { is: "my-abbr" }) should be :defined] - expected: FAIL - - [

should not be :defined] - expected: FAIL - - [createElement("p", { is: "" }) should not be :defined] - expected: FAIL - - [createElementNS("http://www.w3.org/1999/xhtml", "p", { is: "" }) should not be :defined] - expected: FAIL - - [createElementNS("http://www.w3.org/2000/svg", "p", { is: "" }) should be :defined] - expected: FAIL - - [Without browsing context: createElement("p", { is: "" }) should not be :defined] - expected: FAIL - - [Without browsing context: createElementNS("http://www.w3.org/1999/xhtml", "p", { is: "" }) should not be :defined] - expected: FAIL - - [Without browsing context: createElementNS("http://www.w3.org/2000/svg", "p", { is: "" }) should be :defined] - expected: FAIL -