Bug 1026047, add IsInComposedDoc()/GetComposedDoc() and IsInUncomposedDoc()/GetUncomposedDoc() to make it more clear whether Shadow DOM is being handled, r=bz
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Thu, 03 Jul 2014 20:02:07 +0300
changeset 192231 fb7bb4b37e0f
parent 192230 558b30253cbe
child 192232 72447c230e0e
push id27077
push userryanvm@gmail.com
push dateThu, 03 Jul 2014 21:03:59 +0000
treeherdermozilla-central@06e9a27a6fcc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1026047
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1026047, add IsInComposedDoc()/GetComposedDoc() and IsInUncomposedDoc()/GetUncomposedDoc() to make it more clear whether Shadow DOM is being handled, r=bz
content/base/public/nsIContent.h
content/base/public/nsINode.h
content/base/src/Element.cpp
content/base/src/FragmentOrElement.cpp
content/base/src/ShadowRoot.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsINode.cpp
content/base/src/nsStyleLinkElement.cpp
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -237,17 +237,17 @@ public:
    */
   bool IsInAnonymousSubtree() const
   {
     NS_ASSERTION(!IsInNativeAnonymousSubtree() || GetBindingParent() ||
                  (!IsInDoc() &&
                   static_cast<nsIContent*>(SubtreeRoot())->IsInNativeAnonymousSubtree()),
                  "Must have binding parent when in native anonymous subtree which is in document.\n"
                  "Native anonymous subtree which is not in document must have native anonymous root.");
-    return IsInNativeAnonymousSubtree() || (!HasFlag(NODE_IS_IN_SHADOW_TREE) && GetBindingParent() != nullptr);
+    return IsInNativeAnonymousSubtree() || (!IsInShadowTree() && GetBindingParent() != nullptr);
   }
 
   /**
    * Return true iff this node is in an HTML document (in the HTML5 sense of
    * the term, i.e. not in an XHTML/XML document).
    */
   inline bool IsInHTMLDocument() const;
 
@@ -878,20 +878,20 @@ public:
    * there is a scroll frame that contains the frame being scrolled). This
    * frame is always the first continuation.
    *
    * In the case of absolutely positioned elements and floated elements, this
    * frame is the out of flow frame, not the placeholder.
    */
   nsIFrame* GetPrimaryFrame() const
   {
-    return (IsInDoc() || HasFlag(NODE_IS_IN_SHADOW_TREE)) ? mPrimaryFrame : nullptr;
+    return (IsInDoc() || IsInShadowTree()) ? mPrimaryFrame : nullptr;
   }
   void SetPrimaryFrame(nsIFrame* aFrame) {
-    MOZ_ASSERT(IsInDoc() || HasFlag(NODE_IS_IN_SHADOW_TREE), "This will end badly!");
+    MOZ_ASSERT(IsInDoc() || IsInShadowTree(), "This will end badly!");
     NS_PRECONDITION(!aFrame || !mPrimaryFrame || aFrame == mPrimaryFrame,
                     "Losing track of existing primary frame");
     mPrimaryFrame = aFrame;
   }
 
   nsresult LookupNamespaceURIInternal(const nsAString& aNamespacePrefix,
                                       nsAString& aNamespaceURI) const;
 
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -271,18 +271,18 @@ private:
 // Categories of node properties
 // 0 is global.
 #define DOM_USER_DATA         1
 #define DOM_USER_DATA_HANDLER 2
 #define SMIL_MAPPED_ATTR_ANIMVAL 3
 
 // IID for the nsINode interface
 #define NS_INODE_IID \
-{ 0x77a62cd0, 0xb34f, 0x42cb, \
-  { 0x94, 0x52, 0xae, 0xb2, 0x4d, 0x93, 0x2c, 0xb4 } }
+{ 0x3bd80589, 0xa6f4, 0x4a57, \
+  { 0xab, 0x38, 0xa0, 0x5b, 0x77, 0x4c, 0x3e, 0xa8 } }
 
 /**
  * An internal interface that abstracts some DOMNode-related parts that both
  * nsIContent and nsIDocument share.  An instance of this interface has a list
  * of nsIContent children and provides access to them.
  */
 class nsINode : public mozilla::dom::EventTarget
 {
@@ -505,43 +505,76 @@ public:
    */
   nsINode *OwnerDocAsNode() const;
 
   /**
    * Returns true if the content has an ancestor that is a document.
    *
    * @return whether this content is in a document tree
    */
+  bool IsInUncomposedDoc() const
+  {
+    return GetBoolFlag(IsInDocument);
+  }
+
+  /**
+   * @deprecated
+   */
   bool IsInDoc() const
   {
-    return GetBoolFlag(IsInDocument);
+    return IsInUncomposedDoc();
   }
 
   /**
    * Get the document that this content is currently in, if any. This will be
    * null if the content has no ancestor that is a document.
    *
    * @return the current document
    */
+
+  nsIDocument* GetUncomposedDoc() const
+  {
+    return IsInUncomposedDoc() ? OwnerDoc() : nullptr;
+  }
+
+  /**
+   * @deprecated
+   */
   nsIDocument *GetCurrentDoc() const
   {
-    return IsInDoc() ? OwnerDoc() : nullptr;
+    return GetUncomposedDoc();
   }
 
   /**
    * This method gets the current doc of the node hosting this content
    * or the current doc of this content if it is not being hosted. This
    * method walks through ShadowRoot boundaries until it reach the host
    * that is located in the root of the "tree of trees" (see Shadow DOM
    * spec) and returns the current doc for that host.
    */
+  nsIDocument* GetComposedDoc() const
+  {
+    return IsInShadowTree() ?
+      GetComposedDocInternal() : GetUncomposedDoc();
+  }
+
+  /**
+   * @deprecated
+   */
   nsIDocument* GetCrossShadowCurrentDoc() const
   {
-    return HasFlag(NODE_IS_IN_SHADOW_TREE) ?
-      GetCrossShadowCurrentDocInternal() : GetCurrentDoc();
+    return GetComposedDoc();
+  }
+
+  /**
+   * Returns true if GetComposedDoc() would return a non-null value.
+   */
+  bool IsInComposedDoc() const
+  {
+    return IsInUncomposedDoc() || (IsInShadowTree() && GetComposedDocInternal());
   }
 
   /**
    * The values returned by this function are the ones defined for
    * nsIDOMNode.nodeType
    */
   uint16_t NodeType() const
   {
@@ -1015,16 +1048,21 @@ public:
 
   // True for native anonymous content and for XBL content if the binging
   // has chromeOnlyContent="true".
   bool ChromeOnlyAccess() const
   {
     return HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE | NODE_CHROME_ONLY_ACCESS);
   }
 
+  bool IsInShadowTree() const
+  {
+    return HasFlag(NODE_IS_IN_SHADOW_TREE);
+  }
+
   /**
    * Returns true if |this| node is the common ancestor of the start/end
    * nodes of a Range in a Selection or a descendant of such a common ancestor.
    * This node is definitely not selected when |false| is returned, but it may
    * or may not be selected when |true| is returned.
    */
   bool IsSelectionDescendant() const
   {
@@ -1198,17 +1236,17 @@ public:
    */
   bool Contains(const nsINode* aOther) const;
   nsresult Contains(nsIDOMNode* aOther, bool* aReturn);
 
   bool UnoptimizableCCNode() const;
 
 private:
 
-  nsIDocument* GetCrossShadowCurrentDocInternal() const;
+  nsIDocument* GetComposedDocInternal() const;
 
   nsIContent* GetNextNodeImpl(const nsINode* aRoot,
                               const bool aSkipChildren) const
   {
     // Can't use nsContentUtils::ContentIsDescendantOf here, since we
     // can't include it here.
 #ifdef DEBUG
     if (aRoot) {
@@ -1520,17 +1558,17 @@ protected:
   bool HandlingClick() const { return GetBoolFlag(NodeHandlingClick); }
   void SetHandlingClick() { SetBoolFlag(NodeHandlingClick); }
   void ClearHandlingClick() { ClearBoolFlag(NodeHandlingClick); }
 
   void SetSubtreeRootPointer(nsINode* aSubtreeRoot)
   {
     NS_ASSERTION(aSubtreeRoot, "aSubtreeRoot can never be null!");
     NS_ASSERTION(!(IsNodeOfType(eCONTENT) && IsInDoc()) &&
-                 !HasFlag(NODE_IS_IN_SHADOW_TREE), "Shouldn't be here!");
+                 !IsInShadowTree(), "Shouldn't be here!");
     mSubtreeRoot = aSubtreeRoot;
   }
 
   void ClearSubtreeRootPointer()
   {
     mSubtreeRoot = nullptr;
   }
 
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -746,17 +746,17 @@ Element::GetClientRects()
 
 
 //----------------------------------------------------------------------
 
 void
 Element::AddToIdTable(nsIAtom* aId)
 {
   NS_ASSERTION(HasID(), "Node doesn't have an ID?");
-  if (HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+  if (IsInShadowTree()) {
     ShadowRoot* containingShadow = GetContainingShadow();
     containingShadow->AddToIdTable(this, aId);
   } else {
     nsIDocument* doc = GetCurrentDoc();
     if (doc && (!IsInAnonymousSubtree() || doc->IsXUL())) {
       doc->AddToIdTable(this, aId);
     }
   }
@@ -765,17 +765,17 @@ Element::AddToIdTable(nsIAtom* aId)
 void
 Element::RemoveFromIdTable()
 {
   if (!HasID()) {
     return;
   }
 
   nsIAtom* id = DoGetID();
-  if (HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+  if (IsInShadowTree()) {
     ShadowRoot* containingShadow = GetContainingShadow();
     // Check for containingShadow because it may have
     // been deleted during unlinking.
     if (containingShadow) {
       containingShadow->RemoveFromIdTable(this, id);
     }
   } else {
     nsIDocument* doc = GetCurrentDoc();
@@ -1227,17 +1227,17 @@ Element::BindToTree(nsIDocument* aDocume
                "non-native anonymous parent!");
   if (aParent) {
     if (aParent->IsInNativeAnonymousSubtree()) {
       SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
     }
     if (aParent->HasFlag(NODE_CHROME_ONLY_ACCESS)) {
       SetFlags(NODE_CHROME_ONLY_ACCESS);
     }
-    if (aParent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+    if (aParent->IsInShadowTree()) {
       ClearSubtreeRootPointer();
       SetFlags(NODE_IS_IN_SHADOW_TREE);
     }
     ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
     if (parentContainingShadow) {
       DOMSlots()->mContainingShadow = parentContainingShadow;
     }
   }
@@ -1286,17 +1286,17 @@ Element::BindToTree(nsIDocument* aDocume
     }
 
     // Unset this flag since we now really are in a document.
     UnsetFlags(NODE_FORCE_XBL_BINDINGS |
                // And clear the lazy frame construction bits.
                NODE_NEEDS_FRAME | NODE_DESCENDANTS_NEED_FRAMES |
                // And the restyle bits
                ELEMENT_ALL_RESTYLE_FLAGS);
-  } else if (!HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+  } else if (!IsInShadowTree()) {
     // If we're not in the doc and not in a shadow tree,
     // update our subtree pointer.
     SetSubtreeRootPointer(aParent->SubtreeRoot());
   }
 
   // Propagate scoped style sheet tracking bit.
   if (mParent->IsContent()) {
     nsIContent* parent;
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -166,17 +166,17 @@ nsIContent::GetFlattenedTreeParent() con
   }
 
   if (!parent) {
     parent = GetParent();
   }
 
   // Shadow roots never shows up in the flattened tree. Return the host
   // instead.
-  if (parent && parent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+  if (parent && parent->IsInShadowTree()) {
     ShadowRoot* parentShadowRoot = ShadowRoot::FromNode(parent);
     if (parentShadowRoot) {
       return parentShadowRoot->GetHost();
     }
   }
 
   return parent;
 }
--- a/content/base/src/ShadowRoot.cpp
+++ b/content/base/src/ShadowRoot.cpp
@@ -107,17 +107,17 @@ JSObject*
 ShadowRoot::WrapObject(JSContext* aCx)
 {
   return mozilla::dom::ShadowRootBinding::Wrap(aCx, this);
 }
 
 ShadowRoot*
 ShadowRoot::FromNode(nsINode* aNode)
 {
-  if (aNode->HasFlag(NODE_IS_IN_SHADOW_TREE) && !aNode->GetParentNode()) {
+  if (aNode->IsInShadowTree() && !aNode->GetParentNode()) {
     MOZ_ASSERT(aNode->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE,
                "ShadowRoot is a document fragment.");
     return static_cast<ShadowRoot*>(aNode);
   }
 
   return nullptr;
 }
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -4524,17 +4524,17 @@ nsContentUtils::IsInSameAnonymousTree(co
     return aContent->GetBindingParent() == nullptr;
   }
 
   const nsIContent* nodeAsContent = static_cast<const nsIContent*>(aNode);
 
   // For nodes in a shadow tree, it is insufficient to simply compare
   // the binding parent because a node may host multiple ShadowRoots,
   // thus nodes in different shadow tree may have the same binding parent.
-  if (aNode->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+  if (aNode->IsInShadowTree()) {
     return nodeAsContent->GetContainingShadow() ==
       aContent->GetContainingShadow();
   }
 
   return nodeAsContent->GetBindingParent() == aContent->GetBindingParent();
 }
 
 class AnonymousContentDestroyer : public nsRunnable {
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -486,17 +486,17 @@ nsGenericDOMDataNode::BindToTree(nsIDocu
                  "non-native anonymous parent!");
     DataSlots()->mBindingParent = aBindingParent; // Weak, so no addref happens.
     if (aParent->IsInNativeAnonymousSubtree()) {
       SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
     }
     if (aParent->HasFlag(NODE_CHROME_ONLY_ACCESS)) {
       SetFlags(NODE_CHROME_ONLY_ACCESS);
     }
-    if (aParent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+    if (aParent->IsInShadowTree()) {
       ClearSubtreeRootPointer();
       SetFlags(NODE_IS_IN_SHADOW_TREE);
     }
     ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
     if (parentContainingShadow) {
       DataSlots()->mContainingShadow = parentContainingShadow;
     }
   }
@@ -523,17 +523,17 @@ nsGenericDOMDataNode::BindToTree(nsIDocu
 
     // XXX See the comment in Element::BindToTree
     SetInDocument();
     if (mText.IsBidi()) {
       aDocument->SetBidiEnabled();
     }
     // Clear the lazy frame construction bits.
     UnsetFlags(NODE_NEEDS_FRAME | NODE_DESCENDANTS_NEED_FRAMES);
-  } else if (!HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+  } else if (!IsInShadowTree()) {
     // If we're not in the doc and not in a shadow tree,
     // update our subtree pointer.
     SetSubtreeRootPointer(aParent->SubtreeRoot());
   }
 
   nsNodeUtils::ParentChainChanged(this);
 
   UpdateEditableState(false);
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -379,17 +379,17 @@ nsINode::ChildNodes()
 
 void
 nsINode::GetTextContentInternal(nsAString& aTextContent)
 {
   SetDOMStringToNull(aTextContent);
 }
 
 nsIDocument*
-nsINode::GetCrossShadowCurrentDocInternal() const
+nsINode::GetComposedDocInternal() const
 {
   MOZ_ASSERT(HasFlag(NODE_IS_IN_SHADOW_TREE) && IsContent(),
              "Should only be caled on nodes in the shadow tree.");
 
   // Cross ShadowRoot boundary.
   ShadowRoot* containingShadow = AsContent()->GetContainingShadow();
   return containingShadow->GetHost()->GetCrossShadowCurrentDoc();
 }
--- a/content/base/src/nsStyleLinkElement.cpp
+++ b/content/base/src/nsStyleLinkElement.cpp
@@ -338,17 +338,17 @@ nsStyleLinkElement::DoUpdateStyleSheet(n
       nsresult rv = oldURI->Equals(uri, &equal);
       if (NS_SUCCEEDED(rv) && equal) {
         return NS_OK; // We already loaded this stylesheet
       }
     }
   }
 
   if (mStyleSheet) {
-    if (thisContent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+    if (thisContent->IsInShadowTree()) {
       ShadowRoot* containingShadow = thisContent->GetContainingShadow();
       containingShadow->RemoveSheet(mStyleSheet);
     } else {
       doc->BeginUpdate(UPDATE_STYLE);
       doc->RemoveStyleSheet(mStyleSheet);
       doc->EndUpdate(UPDATE_STYLE);
     }
 
@@ -438,17 +438,17 @@ nsStyleLinkElement::UpdateStyleSheetScop
                                nullptr;
 
   if (oldScopeElement == newScopeElement) {
     return;
   }
 
   nsIDocument* document = thisContent->GetOwnerDocument();
 
-  if (thisContent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+  if (thisContent->IsInShadowTree()) {
     ShadowRoot* containingShadow = thisContent->GetContainingShadow();
     containingShadow->RemoveSheet(mStyleSheet);
 
     mStyleSheet->SetScopeElement(newScopeElement);
 
     containingShadow->InsertSheet(mStyleSheet, thisContent);
   } else {
     document->BeginUpdate(UPDATE_STYLE);