Bug 1352763 part 3 - Have ServoStyleSheet also implement nsICSSLoaderObserver. r?heycam draft
authorXidorn Quan <me@upsuper.org>
Mon, 03 Apr 2017 19:55:06 +1000
changeset 554967 52a8f13edb283e1e6fbe2ff6ffa1dc8953580b91
parent 554966 f5a5f000d6b2876a05f8aca918db85d7cd4241d3
child 554968 be5460e95b5a1c919ca5b233fbe2faccc091dd34
push id52103
push userxquan@mozilla.com
push dateMon, 03 Apr 2017 11:21:25 +0000
reviewersheycam
bugs1352763
milestone55.0a1
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;
 }