Bug 1319255 part 2. Stop doing casts to HTMLContentElement* simply based on tag. r=wchen
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 22 Nov 2016 22:41:51 -0500
changeset 323908 93d4161c74bf02acb1273e221b7373825db2eeea
parent 323907 1bacb29753244e767ec0f4eaddb61726ba2f284a
child 323909 03acde1081c3280af1c70ef6d7f57243b720ce87
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewerswchen
bugs1319255
milestone53.0a1
Bug 1319255 part 2. Stop doing casts to HTMLContentElement* simply based on tag. r=wchen
dom/base/ChildIterator.cpp
dom/base/ShadowRoot.cpp
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsINode.h
dom/html/HTMLContentElement.cpp
dom/html/HTMLContentElement.h
--- a/dom/base/ChildIterator.cpp
+++ b/dom/base/ChildIterator.cpp
@@ -55,17 +55,17 @@ GetMatchedNodesForPoint(nsIContent* aCon
 {
   if (aContent->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
     // XBL case
     return MatchedNodes(static_cast<XBLChildrenElement*>(aContent));
   }
 
   // Web components case
   MOZ_ASSERT(aContent->IsHTMLElement(nsGkAtoms::content));
-  return MatchedNodes(static_cast<HTMLContentElement*>(aContent));
+  return MatchedNodes(HTMLContentElement::FromContent(aContent));
 }
 
 nsIContent*
 ExplicitChildIterator::GetNextChild()
 {
   // If we're already in the inserted-children array, look there first
   if (mIndexInInserted) {
     MOZ_ASSERT(mChild);
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -590,20 +590,21 @@ ShadowRoot::IsPooledNode(nsIContent* aCo
       nsContentUtils::IsInSameAnonymousTree(aContainer, aContent)) {
     // Children of the host will end up in the pool. We check to ensure
     // that the content is in the same anonymous tree as the container
     // because anonymous content may report its container as the host
     // but it may not be in the host's child list.
     return true;
   }
 
-  if (aContainer && aContainer->IsHTMLElement(nsGkAtoms::content)) {
+  if (aContainer) {
     // Fallback content will end up in pool if its parent is a child of the host.
-    HTMLContentElement* content = static_cast<HTMLContentElement*>(aContainer);
-    return content->IsInsertionPoint() && content->MatchedNodes().IsEmpty() &&
+    HTMLContentElement* content = HTMLContentElement::FromContent(aContainer);
+    return content && content->IsInsertionPoint() &&
+           content->MatchedNodes().IsEmpty() &&
            aContainer->GetParentNode() == aHost;
   }
 
   return false;
 }
 
 void
 ShadowRoot::AttributeChanged(nsIDocument* aDocument,
@@ -635,17 +636,17 @@ ShadowRoot::ContentAppended(nsIDocument*
   }
 
   // Watch for new nodes added to the pool because the node
   // may need to be added to an insertion point.
   nsIContent* currentChild = aFirstNewContent;
   while (currentChild) {
     // Add insertion point to destination insertion points of fallback content.
     if (nsContentUtils::IsContentInsertionPoint(aContainer)) {
-      HTMLContentElement* content = static_cast<HTMLContentElement*>(aContainer);
+      HTMLContentElement* content = HTMLContentElement::FromContent(aContainer);
       if (content->MatchedNodes().IsEmpty()) {
         currentChild->DestInsertionPoints().AppendElement(aContainer);
       }
     }
 
     if (IsPooledNode(currentChild, aContainer, mPoolHost)) {
       DistributeSingleNode(currentChild);
     }
@@ -666,17 +667,17 @@ ShadowRoot::ContentInserted(nsIDocument*
     return;
   }
 
   // Watch for new nodes added to the pool because the node
   // may need to be added to an insertion point.
   if (IsPooledNode(aChild, aContainer, mPoolHost)) {
     // Add insertion point to destination insertion points of fallback content.
     if (nsContentUtils::IsContentInsertionPoint(aContainer)) {
-      HTMLContentElement* content = static_cast<HTMLContentElement*>(aContainer);
+      HTMLContentElement* content = HTMLContentElement::FromContent(aContainer);
       if (content->MatchedNodes().IsEmpty()) {
         aChild->DestInsertionPoints().AppendElement(aContainer);
       }
     }
 
     DistributeSingleNode(aChild);
   }
 }
@@ -692,17 +693,17 @@ ShadowRoot::ContentRemoved(nsIDocument* 
     DistributeAllNodes();
     mInsertionPointChanged = false;
     return;
   }
 
   // Clear destination insertion points for removed
   // fallback content.
   if (nsContentUtils::IsContentInsertionPoint(aContainer)) {
-    HTMLContentElement* content = static_cast<HTMLContentElement*>(aContainer);
+    HTMLContentElement* content = HTMLContentElement::FromContent(aContainer);
     if (content->MatchedNodes().IsEmpty()) {
       aChild->DestInsertionPoints().Clear();
     }
   }
 
   // Watch for node that is removed from the pool because
   // it may need to be removed from an insertion point.
   if (IsPooledNode(aChild, aContainer, mPoolHost)) {
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -7058,29 +7058,27 @@ nsContentUtils::GetHTMLEditor(nsPresCont
     return nullptr;
 
   nsCOMPtr<nsIEditor> editor;
   docShell->GetEditor(getter_AddRefs(editor));
   return editor;
 }
 
 bool
-nsContentUtils::IsContentInsertionPoint(const nsIContent* aContent)
+nsContentUtils::IsContentInsertionPoint(nsIContent* aContent)
 {
   // Check if the content is a XBL insertion point.
   if (aContent->IsActiveChildrenElement()) {
     return true;
   }
 
   // Check if the content is a web components content insertion point.
-  if (aContent->IsHTMLElement(nsGkAtoms::content)) {
-    return static_cast<const HTMLContentElement*>(aContent)->IsInsertionPoint();
-  }
-
-  return false;
+  HTMLContentElement* contentElement =
+    HTMLContentElement::FromContent(aContent);
+  return contentElement && contentElement->IsInsertionPoint();
 }
 
 // static
 bool
 nsContentUtils::HasDistributedChildren(nsIContent* aContent)
 {
   if (!aContent) {
     return false;
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2407,17 +2407,17 @@ public:
    * Returns whether a content is an insertion point for XBL
    * bindings or web components ShadowRoot. In web components,
    * this corresponds to a <content> element that participates
    * in node distribution. In XBL this corresponds to an
    * <xbl:children> element in anonymous content.
    *
    * @param aContent The content to test for being an insertion point.
    */
-  static bool IsContentInsertionPoint(const nsIContent* aContent);
+  static bool IsContentInsertionPoint(nsIContent* aContent);
 
 
   /**
    * Returns whether the children of the provided content are
    * nodes that are distributed to Shadow DOM insertion points.
    */
   static bool HasDistributedChildren(nsIContent* aContent);
 
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -1324,16 +1324,20 @@ public:
    * in HTMLInputElement with number type as increasing / decreasing its value.
    */
   virtual bool IsNodeApzAwareInternal() const;
 
   // HTML elements named <shadow> may or may not be HTMLShadowElement.  This is
   // a way to ask an element whether it's an HTMLShadowElement.
   virtual bool IsHTMLShadowElement() const { return false; }
 
+  // Elements named <content> may or may not be HTMLContentElement.  This is a
+  // way to ask an element whether it's an HTMLContentElement.
+  virtual bool IsHTMLContentElement() const { return false; }
+
 protected:
   nsIURI* GetExplicitBaseURI() const {
     if (HasExplicitBaseURI()) {
       return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));
     }
     return nullptr;
   }
 
--- a/dom/html/HTMLContentElement.cpp
+++ b/dom/html/HTMLContentElement.cpp
@@ -61,17 +61,17 @@ HTMLContentElement::BindToTree(nsIDocume
                                                  aBindingParent,
                                                  aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   ShadowRoot* containingShadow = GetContainingShadow();
   if (containingShadow && !oldContainingShadow) {
     nsINode* parentNode = nsINode::GetParentNode();
     while (parentNode && parentNode != containingShadow) {
-      if (parentNode->IsHTMLElement(nsGkAtoms::content)) {
+      if (parentNode->IsHTMLContentElement()) {
         // Content element in fallback content is not an insertion point.
         return NS_OK;
       }
       parentNode = parentNode->GetParentNode();
     }
 
     // If the content element is being inserted into a ShadowRoot,
     // add this element to the list of insertion points.
--- a/dom/html/HTMLContentElement.h
+++ b/dom/html/HTMLContentElement.h
@@ -18,24 +18,33 @@ namespace dom {
 
 class DistributedContentList;
 
 class HTMLContentElement final : public nsGenericHTMLElement
 {
 public:
   explicit HTMLContentElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLContentElement, content)
-
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLContentElement,
                                            nsGenericHTMLElement)
 
+  static HTMLContentElement* FromContent(nsIContent* aContent)
+  {
+    if (aContent->IsHTMLContentElement()) {
+      return static_cast<HTMLContentElement*>(aContent);
+    }
+
+    return nullptr;
+  }
+
+  virtual bool IsHTMLContentElement() const override { return true; }
+
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
 
   virtual nsIDOMNode* AsDOMNode() override { return this; }
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) override;