Bug 1319255 part 1. Stop doing casts to HTMLShadowElement* simply based on tag. r=wchen
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 22 Nov 2016 22:41:51 -0500
changeset 323907 1bacb29753244e767ec0f4eaddb61726ba2f284a
parent 323906 26096b7866bb2550e95e4a317fac4c31539991c9
child 323908 93d4161c74bf02acb1273e221b7373825db2eeea
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewerswchen
bugs1319255
milestone53.0a1
Bug 1319255 part 1. Stop doing casts to HTMLShadowElement* simply based on tag. r=wchen
dom/base/ChildIterator.cpp
dom/base/ShadowRoot.cpp
dom/base/nsINode.h
dom/html/HTMLShadowElement.h
--- a/dom/base/ChildIterator.cpp
+++ b/dom/base/ChildIterator.cpp
@@ -110,17 +110,17 @@ ExplicitChildIterator::GetNextChild()
   // Iterate until we find a non-insertion point, or an insertion point with
   // content.
   while (mChild) {
     // If the current child being iterated is a shadow insertion point then
     // the iterator needs to go into the projected ShadowRoot.
     if (ShadowRoot::IsShadowInsertionPoint(mChild)) {
       // Look for the next child in the projected ShadowRoot for the <shadow>
       // element.
-      HTMLShadowElement* shadowElem = static_cast<HTMLShadowElement*>(mChild);
+      HTMLShadowElement* shadowElem = HTMLShadowElement::FromContent(mChild);
       ShadowRoot* projectedShadow = shadowElem->GetOlderShadowRoot();
       if (projectedShadow) {
         mShadowIterator = new ExplicitChildIterator(projectedShadow);
         nsIContent* nextChild = mShadowIterator->GetNextChild();
         if (nextChild) {
           return nextChild;
         }
         mShadowIterator = nullptr;
@@ -265,17 +265,17 @@ ExplicitChildIterator::GetPreviousChild(
   }
 
   // Iterate until we find a non-insertion point, or an insertion point with
   // content.
   while (mChild) {
     if (ShadowRoot::IsShadowInsertionPoint(mChild)) {
       // If the current child being iterated is a shadow insertion point then
       // the iterator needs to go into the projected ShadowRoot.
-      HTMLShadowElement* shadowElem = static_cast<HTMLShadowElement*>(mChild);
+      HTMLShadowElement* shadowElem = HTMLShadowElement::FromContent(mChild);
       ShadowRoot* projectedShadow = shadowElem->GetOlderShadowRoot();
       if (projectedShadow) {
         // Create a ExplicitChildIterator that begins iterating from the end.
         mShadowIterator = new ExplicitChildIterator(projectedShadow, false);
         nsIContent* previousChild = mShadowIterator->GetPreviousChild();
         if (previousChild) {
           return previousChild;
         }
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -557,21 +557,22 @@ ShadowRoot::ChangePoolHost(nsIContent* a
   if (mPoolHost) {
     mPoolHost->AddMutationObserver(this);
   }
 }
 
 bool
 ShadowRoot::IsShadowInsertionPoint(nsIContent* aContent)
 {
-  if (aContent && aContent->IsHTMLElement(nsGkAtoms::shadow)) {
-    HTMLShadowElement* shadowElem = static_cast<HTMLShadowElement*>(aContent);
-    return shadowElem->IsInsertionPoint();
+  if (!aContent) {
+    return false;
   }
-  return false;
+
+  HTMLShadowElement* shadowElem = HTMLShadowElement::FromContent(aContent);
+  return shadowElem && shadowElem->IsInsertionPoint();
 }
 
 /**
  * Returns whether the web components pool population algorithm
  * on the host would contain |aContent|. This function ignores
  * insertion points in the pool, thus should only be used to
  * test nodes that have not yet been distributed.
  */
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -1320,16 +1320,20 @@ public:
    * to let APZC be aware of it. It's used when the node may handle the apz
    * aware events and may do preventDefault to stop APZC to do default actions.
    *
    * For example, instead of scrolling page by APZ, we handle mouse wheel event
    * 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; }
+
 protected:
   nsIURI* GetExplicitBaseURI() const {
     if (HasExplicitBaseURI()) {
       return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));
     }
     return nullptr;
   }
 
--- a/dom/html/HTMLShadowElement.h
+++ b/dom/html/HTMLShadowElement.h
@@ -13,28 +13,37 @@ namespace mozilla {
 namespace dom {
 
 class HTMLShadowElement final : public nsGenericHTMLElement,
                                 public nsStubMutationObserver
 {
 public:
   explicit HTMLShadowElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLShadowElement, shadow)
-
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLShadowElement,
                                            nsGenericHTMLElement)
 
+  static HTMLShadowElement* FromContent(nsIContent* aContent)
+  {
+    if (aContent->IsHTMLShadowElement()) {
+      return static_cast<HTMLShadowElement*>(aContent);
+    }
+
+    return nullptr;
+  }
+
+  virtual bool IsHTMLShadowElement() const override { return true; }
+
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) override;
 
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) override;