Bug 1352763 part 3 - Have ServoStyleSheet also implement nsICSSLoaderObserver. r?heycam
MozReview-Commit-ID: 1Z6jAmQ9CY6
--- 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;
}