Bug 1335303 - Add a virtual method to avoid QI to nsIMozBrowserFrame. r=smaug
authorBobby Holley <bobbyholley@gmail.com>
Thu, 02 Feb 2017 13:47:58 -0800
changeset 388238 321ea09ee89727e768443d6979c69a32a1ae3bef
parent 388237 9f080fde040f4d7f26ab112a98a03da13f2013a9
child 388239 fadf7c2a257fbd6ae3f68bde9a9c679b15e391e2
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1335303
milestone54.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 1335303 - Add a virtual method to avoid QI to nsIMozBrowserFrame. r=smaug
dom/base/Element.h
dom/html/nsGenericHTMLFrameElement.h
layout/style/nsCSSPseudoClasses.cpp
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -39,16 +39,17 @@
 #include "mozilla/dom/WindowBinding.h"
 #include "mozilla/dom/ElementBinding.h"
 #include "mozilla/dom/Nullable.h"
 #include "Units.h"
 #include "DOMIntersectionObserver.h"
 
 class nsIFrame;
 class nsIDOMMozNamedAttrMap;
+class nsIMozBrowserFrame;
 class nsIURI;
 class nsIScrollableFrame;
 class nsAttrValueOrString;
 class nsContentList;
 class nsDOMTokenList;
 struct nsRect;
 class nsFocusManager;
 class nsGlobalWindow;
@@ -335,16 +336,26 @@ public:
   virtual bool IsLabelable() const;
 
   /**
    * Returns if the element is interactive content as per HTML specification.
    */
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const;
 
   /**
+   * Returns |this| as an nsIMozBrowserFrame* if the element is a frame or
+   * iframe element.
+   *
+   * We have this method, rather than using QI, so that we can use it during
+   * the servo traversal, where we can't QI DOM nodes because of non-thread-safe
+   * refcounts.
+   */
+  virtual nsIMozBrowserFrame* GetAsMozBrowserFrame() { return nullptr; }
+
+  /**
    * Is the attribute named stored in the mapped attributes?
    *
    * // XXXbz we use this method in HasAttributeDependentStyle, so svg
    *    returns true here even though it stores nothing in the mapped
    *    attributes.
    */
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
--- a/dom/html/nsGenericHTMLFrameElement.h
+++ b/dom/html/nsGenericHTMLFrameElement.h
@@ -66,16 +66,18 @@ public:
                                 const nsAttrValue* aValue,
                                 bool aNotify) override;
   virtual void DestroyContent() override;
 
   nsresult CopyInnerTo(mozilla::dom::Element* aDest);
 
   virtual int32_t TabIndexDefault() override;
 
+  virtual nsIMozBrowserFrame* GetAsMozBrowserFrame() override { return this; }
+
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsGenericHTMLFrameElement,
                                            nsGenericHTMLElement)
 
   void SwapFrameLoaders(mozilla::dom::HTMLIFrameElement& aOtherLoaderOwner,
                         mozilla::ErrorResult& aError);
 
   void SwapFrameLoaders(nsXULElement& aOtherLoaderOwner,
                         mozilla::ErrorResult& aError);
--- a/layout/style/nsCSSPseudoClasses.cpp
+++ b/layout/style/nsCSSPseudoClasses.cpp
@@ -143,16 +143,16 @@ nsCSSPseudoClasses::MatchesElement(Type 
       if (!aElement->IsHTMLElement(nsGkAtoms::table)) {
         return Some(false);
       }
       const nsAttrValue *val = aElement->GetParsedAttr(nsGkAtoms::border);
       return Some(val && (val->Type() != nsAttrValue::eInteger ||
                           val->GetIntegerValue() != 0));
     }
     case CSSPseudoClassType::mozBrowserFrame: {
-      nsCOMPtr<nsIMozBrowserFrame> browserFrame =
-        do_QueryInterface(const_cast<Element*>(aElement));
+      nsIMozBrowserFrame* browserFrame =
+        const_cast<Element*>(aElement)->GetAsMozBrowserFrame();
       return Some(browserFrame && browserFrame->GetReallyIsBrowser());
     }
     default:
       return Nothing();
   }
 }