summaryrefslogtreecommitdiffstats
path: root/dom
diff options
context:
space:
mode:
Diffstat (limited to 'dom')
-rw-r--r--dom/base/Element.cpp5
-rw-r--r--dom/base/Element.h21
-rw-r--r--dom/base/crashtests/crashtests.list2
-rw-r--r--dom/base/nsGkAtomList.h1
-rw-r--r--dom/base/nsIContent.h2
-rw-r--r--dom/base/nsINode.cpp1
-rw-r--r--dom/base/nsINode.h49
-rw-r--r--dom/svg/nsSVGClass.cpp4
-rw-r--r--dom/xul/nsXULElement.cpp4
9 files changed, 68 insertions, 21 deletions
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<const nsSVGElement*>(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<nsIHTMLCollection>
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<uintptr_t>(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<void*>(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),
@@ -1212,6 +1231,15 @@ public:
}
/**
+ * 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.
*/
bool IsInNativeAnonymousSubtree() const
@@ -1343,10 +1371,11 @@ public:
protected:
nsIURI* GetExplicitBaseURI() const {
- if (HasExplicitBaseURI()) {
- return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));
+ if (!HasProperties()) {
+ return nullptr;
}
- return nullptr;
+
+ return static_cast<nsIURI*>(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
diff --git a/dom/svg/nsSVGClass.cpp b/dom/svg/nsSVGClass.cpp
index 6b64c3be7..c5a825be4 100644
--- a/dom/svg/nsSVGClass.cpp
+++ b/dom/svg/nsSVGClass.cpp
@@ -70,7 +70,7 @@ nsSVGClass::SetBaseValue(const nsAString& aValue,
{
NS_ASSERTION(aSVGElement, "Null element passed to SetBaseValue");
- aSVGElement->SetFlags(NODE_MAY_HAVE_CLASS);
+ aSVGElement->SetMayHaveClass();
if (aDoSetAttr) {
aSVGElement->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, aValue, true);
}
@@ -106,7 +106,7 @@ nsSVGClass::SetAnimValue(const nsAString& aValue, nsSVGElement *aSVGElement)
mAnimVal = new nsString();
}
*mAnimVal = aValue;
- aSVGElement->SetFlags(NODE_MAY_HAVE_CLASS);
+ aSVGElement->SetMayHaveClass();
aSVGElement->DidAnimateClass();
}
diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp
index bc9215086..c7a539370 100644
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -204,7 +204,7 @@ nsXULElement::Create(nsXULPrototypeElement* aPrototype, mozilla::dom::NodeInfo *
element->SetHasID();
}
if (aPrototype->mHasClassAttribute) {
- element->SetFlags(NODE_MAY_HAVE_CLASS);
+ element->SetMayHaveClass();
}
if (aPrototype->mHasStyleAttribute) {
element->SetMayHaveStyle();
@@ -374,7 +374,7 @@ nsXULElement::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const
element->SetHasID();
}
if (originalName->Equals(nsGkAtoms::_class)) {
- element->SetFlags(NODE_MAY_HAVE_CLASS);
+ element->SetMayHaveClass();
}
if (originalName->Equals(nsGkAtoms::style)) {
element->SetMayHaveStyle();