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 323832 1bacb29753244e767ec0f4eaddb61726ba2f284a
parent 323831 26096b7866bb2550e95e4a317fac4c31539991c9
child 323833 93d4161c74bf02acb1273e221b7373825db2eeea
push id84252
push userbzbarsky@mozilla.com
push dateWed, 23 Nov 2016 03:42:04 +0000
treeherdermozilla-inbound@03acde1081c3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswchen
bugs1319255
milestone53.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 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;