Bug 1352763 part 3 - Have ServoStyleSheet also implement nsICSSLoaderObserver. r=heycam
authorXidorn Quan <me@upsuper.org>
Mon, 03 Apr 2017 19:55:06 +1000
changeset 350968 3de3d7d4725eefe688e76e2f5a00388b41041dd8
parent 350967 baffb5defe2f1627aeb76a91d4adbc1ac590a431
child 350969 4487ef34d11058888d6335f28cd049efc0861db6
push id88767
push userkwierso@gmail.com
push dateMon, 03 Apr 2017 21:51:16 +0000
treeherdermozilla-inbound@a31c259f06ac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1352763
milestone55.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 1352763 part 3 - Have ServoStyleSheet also implement nsICSSLoaderObserver. r=heycam MozReview-Commit-ID: 1Z6jAmQ9CY6
layout/style/CSSStyleSheet.cpp
layout/style/CSSStyleSheet.h
layout/style/Loader.cpp
layout/style/ServoCSSRuleList.cpp
layout/style/ServoCSSRuleList.h
layout/style/ServoStyleSheet.cpp
layout/style/ServoStyleSheet.h
layout/style/StyleSheet.cpp
layout/style/StyleSheet.h
layout/style/StyleSheetInlines.h
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -26,17 +26,16 @@
 #include "nsTArray.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "mozilla/dom/CSSRuleList.h"
 #include "nsIDOMMediaList.h"
 #include "nsIDOMNode.h"
 #include "nsError.h"
 #include "nsCSSParser.h"
 #include "mozilla/css/Loader.h"
-#include "nsICSSLoaderObserver.h"
 #include "nsNameSpaceManager.h"
 #include "nsXMLNameSpaceMap.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "mozAutoDocUpdate.h"
 #include "nsRuleNode.h"
 #include "nsMediaFeatures.h"
@@ -437,18 +436,17 @@ CSSStyleSheet::TraverseInner(nsCycleColl
     }
   }
 
   StyleSheet::TraverseInner(cb);
 }
 
 // QueryInterface implementation for CSSStyleSheet
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(CSSStyleSheet)
-  NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, StyleSheet)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMCSSStyleSheet)
   if (aIID.Equals(NS_GET_IID(CSSStyleSheet)))
     foundInterface = reinterpret_cast<nsISupports*>(this);
   else
 NS_INTERFACE_MAP_END_INHERITING(StyleSheet)
 
 NS_IMPL_ADDREF_INHERITED(CSSStyleSheet, StyleSheet)
 NS_IMPL_RELEASE_INHERITED(CSSStyleSheet, StyleSheet)
 
--- a/layout/style/CSSStyleSheet.h
+++ b/layout/style/CSSStyleSheet.h
@@ -14,17 +14,16 @@
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInfo.h"
 #include "mozilla/css/SheetParsingMode.h"
 
 #include "nscore.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
-#include "nsICSSLoaderObserver.h"
 #include "nsTArrayForwardDeclare.h"
 #include "nsString.h"
 #include "mozilla/CORSMode.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/net/ReferrerPolicy.h"
 #include "mozilla/dom/SRIMetadata.h"
 
 class CSSRuleListImpl;
@@ -82,17 +81,16 @@ struct CSSStyleSheetInner : public Style
 // CID for the CSSStyleSheet class
 // 7985c7ac-9ddc-444d-9899-0c86ec122f54
 #define NS_CSS_STYLE_SHEET_IMPL_CID     \
 { 0x7985c7ac, 0x9ddc, 0x444d, \
   { 0x98, 0x99, 0x0c, 0x86, 0xec, 0x12, 0x2f, 0x54 } }
 
 
 class CSSStyleSheet final : public StyleSheet
-                          , public nsICSSLoaderObserver
 {
 public:
   typedef net::ReferrerPolicy ReferrerPolicy;
   CSSStyleSheet(css::SheetParsingMode aParsingMode,
                 CORSMode aCORSMode, ReferrerPolicy aReferrerPolicy);
   CSSStyleSheet(css::SheetParsingMode aParsingMode,
                 CORSMode aCORSMode, ReferrerPolicy aReferrerPolicy,
                 const dom::SRIMetadata& aIntegrity);
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -2264,20 +2264,17 @@ Loader::LoadChildSheet(StyleSheet* aPare
     }
 
     NS_ASSERTION(parentData->mSheet == aParentSheet,
                  "Unexpected call to LoadChildSheet");
   } else {
     LOG(("  No parent load; must be CSSOM"));
     // No parent load data, so the sheet will need to be notified when
     // we finish, if it can be, if we do the load asynchronously.
-    // XXXheycam ServoStyleSheet doesn't implement nsICSSLoaderObserver yet.
-    MOZ_ASSERT(aParentSheet->IsGecko(),
-               "stylo: ServoStyleSheets don't support child sheet loading yet");
-    observer = aParentSheet->AsGecko();
+    observer = aParentSheet;
   }
 
   // Now that we know it's safe to load this (passes security check and not a
   // loop) do so.
   RefPtr<StyleSheet> sheet;
   RefPtr<CSSStyleSheet> reusableSheet;
   StyleSheetState state;
   if (aReusableSheets && aReusableSheets->FindReusableStyleSheet(aURL, reusableSheet)) {
--- a/layout/style/ServoCSSRuleList.cpp
+++ b/layout/style/ServoCSSRuleList.cpp
@@ -180,14 +180,24 @@ ServoCSSRuleList::DeleteRule(uint32_t aI
     if (rule > kMaxRuleType) {
       DropRule(already_AddRefed<css::Rule>(CastToPtr(rule)));
     }
     mRules.RemoveElementAt(aIndex);
   }
   return rv;
 }
 
+uint16_t
+ServoCSSRuleList::GetRuleType(uint32_t aIndex) const
+{
+  uintptr_t rule = mRules[aIndex];
+  if (rule <= kMaxRuleType) {
+    return rule;
+  }
+  return CastToPtr(rule)->Type();
+}
+
 ServoCSSRuleList::~ServoCSSRuleList()
 {
   DropAllRules();
 }
 
 } // namespace mozilla
--- a/layout/style/ServoCSSRuleList.h
+++ b/layout/style/ServoCSSRuleList.h
@@ -37,16 +37,18 @@ public:
   uint32_t Length() final { return mRules.Length(); }
 
   void DropReference();
 
   css::Rule* GetRule(uint32_t aIndex);
   nsresult InsertRule(const nsAString& aRule, uint32_t aIndex);
   nsresult DeleteRule(uint32_t aIndex);
 
+  uint16_t GetRuleType(uint32_t aIndex) const;
+
 private:
   virtual ~ServoCSSRuleList();
 
   // XXX Is it possible to have an address lower than or equal to 255?
   //     Is it possible to have more than 255 CSS rule types?
   static const uintptr_t kMaxRuleType = UINT8_MAX;
 
   static uintptr_t CastToUint(css::Rule* aPtr) {
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -108,16 +108,41 @@ ServoStyleSheet::ParseSheet(css::Loader*
 }
 
 void
 ServoStyleSheet::LoadFailed()
 {
   Inner()->mSheet = Servo_StyleSheet_Empty(mParsingMode).Consume();
 }
 
+// nsICSSLoaderObserver implementation
+NS_IMETHODIMP
+ServoStyleSheet::StyleSheetLoaded(StyleSheet* aSheet,
+                                  bool aWasAlternate,
+                                  nsresult aStatus)
+{
+  MOZ_ASSERT(aSheet->IsServo(),
+             "why we were called back with a CSSStyleSheet?");
+
+  ServoStyleSheet* sheet = aSheet->AsServo();
+  if (sheet->GetParentSheet() == nullptr) {
+    return NS_OK; // ignore if sheet has been detached already
+  }
+  NS_ASSERTION(this == sheet->GetParentSheet(),
+               "We are being notified of a sheet load for a sheet that is not our child!");
+
+  if (mDocument && NS_SUCCEEDED(aStatus)) {
+    mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
+    NS_WARNING("stylo: Import rule object not implemented");
+    mDocument->StyleRuleAdded(this, nullptr);
+  }
+
+  return NS_OK;
+}
+
 void
 ServoStyleSheet::DropRuleList()
 {
   if (mRuleList) {
     mRuleList->DropReference();
     mRuleList = nullptr;
   }
 }
@@ -162,19 +187,19 @@ ServoStyleSheet::InsertRuleInternal(cons
   // Ensure mRuleList is constructed.
   GetCssRulesInternal(aRv);
 
   mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
   aRv = mRuleList->InsertRule(aRule, aIndex);
   if (aRv.Failed()) {
     return 0;
   }
+  // XXX If the inserted rule is an import rule, we should only notify
+  // the document if its associated child stylesheet has been loaded.
   if (mDocument) {
-    // XXX When we support @import rules, we should not notify here,
-    // but rather when the sheet the rule is importing is loaded.
     // XXX We may not want to get the rule when stylesheet change event
     // is not enabled.
     mDocument->StyleRuleAdded(this, mRuleList->GetRule(aIndex));
   }
   return aIndex;
 }
 
 void
--- a/layout/style/ServoStyleSheet.h
+++ b/layout/style/ServoStyleSheet.h
@@ -85,16 +85,20 @@ public:
 
   bool IsModified() const final { return false; }
 
   virtual already_AddRefed<StyleSheet> Clone(StyleSheet* aCloneParent,
     css::ImportRule* aCloneOwnerRule,
     nsIDocument* aCloneDocument,
     nsINode* aCloneOwningNode) const final;
 
+  // nsICSSLoaderObserver interface
+  NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet, bool aWasAlternate,
+                              nsresult aStatus) final;
+
 protected:
   virtual ~ServoStyleSheet();
 
   ServoStyleSheetInner* Inner() const
   {
     return static_cast<ServoStyleSheetInner*>(mInner);
   }
 
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -113,16 +113,17 @@ StyleSheet::TraverseInner(nsCycleCollect
     cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, childSheet));
     childSheet = childSheet->mNext;
   }
 }
 
 // QueryInterface implementation for StyleSheet
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(StyleSheet)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
   NS_INTERFACE_MAP_ENTRY(nsIDOMStyleSheet)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleSheet)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(StyleSheet)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(StyleSheet)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(StyleSheet)
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -9,16 +9,17 @@
 
 #include "mozilla/css/SheetParsingMode.h"
 #include "mozilla/dom/CSSStyleSheetBinding.h"
 #include "mozilla/net/ReferrerPolicy.h"
 #include "mozilla/StyleBackendType.h"
 #include "mozilla/CORSMode.h"
 #include "mozilla/ServoUtils.h"
 
+#include "nsICSSLoaderObserver.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsWrapperCache.h"
 
 class nsIDocument;
 class nsINode;
 class nsIPrincipal;
 class nsCSSRuleProcessor;
 
@@ -40,28 +41,30 @@ class GroupRule;
 class ImportRule;
 class Rule;
 }
 
 /**
  * Superclass for data common to CSSStyleSheet and ServoStyleSheet.
  */
 class StyleSheet : public nsIDOMCSSStyleSheet
+                 , public nsICSSLoaderObserver
                  , public nsWrapperCache
 {
 protected:
   StyleSheet(StyleBackendType aType, css::SheetParsingMode aParsingMode);
   StyleSheet(const StyleSheet& aCopy,
              nsIDocument* aDocumentToUse,
              nsINode* aOwningNodeToUse);
   virtual ~StyleSheet();
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(StyleSheet)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(StyleSheet,
+                                                         nsIDOMCSSStyleSheet)
 
   void SetOwningNode(nsINode* aOwningNode)
   {
     mOwningNode = aOwningNode;
   }
 
   css::SheetParsingMode ParsingMode() { return mParsingMode; }
   mozilla::dom::CSSStyleSheetParsingMode ParsingModeDOM();
--- a/layout/style/StyleSheetInlines.h
+++ b/layout/style/StyleSheetInlines.h
@@ -84,17 +84,17 @@ StyleSheet::GetParentStyleSheet() const
 }
 
 dom::ParentObject
 StyleSheet::GetParentObject() const
 {
   if (mOwningNode) {
     return dom::ParentObject(mOwningNode);
   }
-  return dom::ParentObject(GetParentSheet());
+  return dom::ParentObject(static_cast<nsIDOMCSSStyleSheet*>(mParent), mParent);
 }
 
 nsIPrincipal*
 StyleSheet::Principal() const
 {
   return SheetInfo().mPrincipal;
 }