From 4375774c901bac4bd1ecaa35b40f55397044b7e9 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Thu, 16 Apr 2020 16:37:28 -0400 Subject: Bug 1331322 - Allow tagging of pseudo-implementing native anonymous content with the pseudo type at creation time * Stop using a node bit for HasExplicitBaseURI * Move MAY_HAVE_CLASS to mBoolFlags * Add a flag to indicate that a node is native anonymous content * Allow tagging of pseudo-implementing native anonymous content with the pseudo type at creation time, and eliminate explicit style contexts in nsIAnonymousContentCreator::ContentInfo Tag #1375 --- dom/base/Element.cpp | 5 ++-- dom/base/Element.h | 21 +++++++++++++++- dom/base/crashtests/crashtests.list | 2 +- dom/base/nsGkAtomList.h | 1 + dom/base/nsIContent.h | 2 +- dom/base/nsINode.cpp | 1 - dom/base/nsINode.h | 49 +++++++++++++++++++++++++++++-------- 7 files changed, 64 insertions(+), 17 deletions(-) (limited to 'dom/base') diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 5a92853ae..91a3b63d7 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -166,8 +166,7 @@ nsIContent::DoGetID() const const nsAttrValue* Element::DoGetClasses() const { - MOZ_ASSERT(HasFlag(NODE_MAY_HAVE_CLASS), "Unexpected call"); - + MOZ_ASSERT(MayHaveClass(), "Unexpected call"); if (IsSVGElement()) { const nsAttrValue* animClass = static_cast(this)->GetAnimatedClassName(); @@ -2702,7 +2701,7 @@ Element::ParseAttribute(int32_t aNamespaceID, { if (aNamespaceID == kNameSpaceID_None) { if (aAttribute == nsGkAtoms::_class) { - SetFlags(NODE_MAY_HAVE_CLASS); + SetMayHaveClass(); // Result should have been preparsed above. return true; } diff --git a/dom/base/Element.h b/dom/base/Element.h index 1b29f0346..8139236aa 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -591,7 +591,7 @@ public: * guaranteed (e.g. we could have class=""). */ const nsAttrValue* GetClasses() const { - if (HasFlag(NODE_MAY_HAVE_CLASS)) { + if (MayHaveClass()) { return DoGetClasses(); } return nullptr; @@ -763,6 +763,25 @@ public: already_AddRefed GetElementsByClassName(const nsAString& aClassNames); + CSSPseudoElementType GetPseudoElementType() const { + if (!HasProperties()) { + return CSSPseudoElementType::NotPseudo; + } + nsresult rv = NS_OK; + auto raw = GetProperty(nsGkAtoms::pseudoProperty, &rv); + if (rv == NS_PROPTABLE_PROP_NOT_THERE) { + return CSSPseudoElementType::NotPseudo; + } + return CSSPseudoElementType(reinterpret_cast(raw)); + } + + void SetPseudoElementType(CSSPseudoElementType aPseudo) { + static_assert(sizeof(CSSPseudoElementType) <= sizeof(uintptr_t), + "Need to be able to store this in a void*"); + MOZ_ASSERT(aPseudo != CSSPseudoElementType::NotPseudo); + SetProperty(nsGkAtoms::pseudoProperty, reinterpret_cast(aPseudo)); + } + private: /** * Implement the algorithm specified at diff --git a/dom/base/crashtests/crashtests.list b/dom/base/crashtests/crashtests.list index 0fb597b30..d8b5e9625 100644 --- a/dom/base/crashtests/crashtests.list +++ b/dom/base/crashtests/crashtests.list @@ -193,7 +193,7 @@ load 930250.html load 942979.html load 973401.html load 978646.html -pref(dom.webcomponents.enabled,true) load 1024428-1.html +pref(dom.webcomponents.enabled,true) load 1024428-1.html # bug 1340009 load 1026714.html pref(dom.webcomponents.enabled,true) load 1027461-1.html pref(dom.webcomponents.enabled,true) load 1029710.html diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index 73a3a02b1..c7c1197b1 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -2162,6 +2162,7 @@ GK_ATOM(lockedStyleStates, "lockedStyleStates") GK_ATOM(apzCallbackTransform, "apzCallbackTransform") GK_ATOM(restylableAnonymousNode, "restylableAnonymousNode") GK_ATOM(paintRequestTime, "PaintRequestTime") +GK_ATOM(pseudoProperty, "PseudoProperty") // CSSPseudoElementType // Languages for lang-specific transforms GK_ATOM(Japanese, "ja") diff --git a/dom/base/nsIContent.h b/dom/base/nsIContent.h index 52f2ba5b2..ff0c57e8c 100644 --- a/dom/base/nsIContent.h +++ b/dom/base/nsIContent.h @@ -193,7 +193,7 @@ public: void SetIsNativeAnonymousRoot() { SetFlags(NODE_IS_ANONYMOUS_ROOT | NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE | - NODE_IS_NATIVE_ANONYMOUS_ROOT); + NODE_IS_NATIVE_ANONYMOUS_ROOT | NODE_IS_NATIVE_ANONYMOUS); } /** diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp index 0b56f519d..560ded6a9 100644 --- a/dom/base/nsINode.cpp +++ b/dom/base/nsINode.cpp @@ -1515,7 +1515,6 @@ nsINode::SetExplicitBaseURI(nsIURI* aURI) { nsresult rv = SetProperty(nsGkAtoms::baseURIProperty, aURI, ReleaseURI); if (NS_SUCCEEDED(rv)) { - SetHasExplicitBaseURI(); NS_ADDREF(aURI); } return rv; diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h index a0d972f80..0f882445f 100644 --- a/dom/base/nsINode.h +++ b/dom/base/nsINode.h @@ -126,9 +126,28 @@ enum { NODE_IS_EDITABLE = NODE_FLAG_BIT(7), - // For all Element nodes, NODE_MAY_HAVE_CLASS is guaranteed to be set if the - // node in fact has a class, but may be set even if it doesn't. - NODE_MAY_HAVE_CLASS = NODE_FLAG_BIT(8), + // This node was created by layout as native anonymous content. This + // generally corresponds to things created by nsIAnonymousContentCreator, + // though there are exceptions (svg:use content does not have this flag + // set, and any non-nsIAnonymousContentCreator callers of + // SetIsNativeAnonymousRoot also get this flag). + // + // One very important aspect here is that this node is not transitive over + // the subtree (if you want that, use NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE). + // If Gecko code somewhere attaches children to a node with this bit set, + // the children will not have the bit themselves unless the calling code sets + // it explicitly. This means that XBL content bound to NAC doesn't get this + // bit, nor do nodes inserted by editor. + // + // For now, this bit exists primarily to control style inheritance behavior, + // since the nodes for which we set it are often used to implement pseudo- + // elements, which need to inherit style from a script-visible element. + // + // A more general principle for this bit might be this: If the node is entirely + // a detail of layout, is not script-observable in any way, and other engines + // might accomplish the same task with a nodeless layout frame, then the node + // should have this bit set. + NODE_IS_NATIVE_ANONYMOUS = NODE_FLAG_BIT(8), // Whether the node participates in a shadow tree. NODE_IS_IN_SHADOW_TREE = NODE_FLAG_BIT(9), @@ -1211,6 +1230,15 @@ public: #endif } + /** + * Returns true if |this| is native anonymous (i.e. created by + * nsIAnonymousContentCreator); + */ + bool IsNativeAnonymous() const + { + return HasFlag(NODE_IS_NATIVE_ANONYMOUS); + } + /** * Returns true if |this| or any of its ancestors is native anonymous. */ @@ -1343,10 +1371,11 @@ public: protected: nsIURI* GetExplicitBaseURI() const { - if (HasExplicitBaseURI()) { - return static_cast(GetProperty(nsGkAtoms::baseURIProperty)); + if (!HasProperties()) { + return nullptr; } - return nullptr; + + return static_cast(GetProperty(nsGkAtoms::baseURIProperty)); } public: @@ -1549,6 +1578,8 @@ private: // cases lie for nsXMLElement, such as when the node has been moved between // documents with different id mappings. ElementHasID, + // Set if the element might have a class. + ElementMayHaveClass, // Set if the element might have inline style. ElementMayHaveStyle, // Set if the element has a name attribute set. @@ -1567,8 +1598,6 @@ private: // Maybe set if the node is a root of a subtree // which needs to be kept in the purple buffer. NodeIsPurpleRoot, - // Set if the node has an explicit base URI stored - NodeHasExplicitBaseURI, // Set if the element has some style states locked ElementHasLockedStyleStates, // Set if element has pointer locked @@ -1645,6 +1674,8 @@ public: { SetBoolFlag(NodeHasRenderingObservers, aValue); } bool IsContent() const { return GetBoolFlag(NodeIsContent); } bool HasID() const { return GetBoolFlag(ElementHasID); } + bool MayHaveClass() const { return GetBoolFlag(ElementMayHaveClass); } + void SetMayHaveClass() { SetBoolFlag(ElementMayHaveClass); } bool MayHaveStyle() const { return GetBoolFlag(ElementMayHaveStyle); } bool HasName() const { return GetBoolFlag(ElementHasName); } bool MayHaveContentEditableAttr() const @@ -1774,8 +1805,6 @@ protected: void ClearHasName() { ClearBoolFlag(ElementHasName); } void SetMayHaveContentEditableAttr() { SetBoolFlag(ElementMayHaveContentEditableAttr); } - bool HasExplicitBaseURI() const { return GetBoolFlag(NodeHasExplicitBaseURI); } - void SetHasExplicitBaseURI() { SetBoolFlag(NodeHasExplicitBaseURI); } void SetHasLockedStyleStates() { SetBoolFlag(ElementHasLockedStyleStates); } void ClearHasLockedStyleStates() { ClearBoolFlag(ElementHasLockedStyleStates); } bool HasLockedStyleStates() const -- cgit v1.2.3