Bug 1290218 Part 8: Implement ServoStyleSheet Clone.
MozReview-Commit-ID: Y2KcoMjhbn
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -9931,18 +9931,18 @@ nsIDocument::CreateStaticClone(nsIDocShe
int32_t sheetsCount = GetNumberOfStyleSheets();
for (int32_t i = 0; i < sheetsCount; ++i) {
RefPtr<StyleSheet> sheet = GetStyleSheetAt(i);
if (sheet) {
if (sheet->IsApplicable()) {
// XXXheycam Need to make ServoStyleSheet cloning work.
if (sheet->IsGecko()) {
- RefPtr<CSSStyleSheet> clonedSheet =
- sheet->AsGecko()->Clone(nullptr, nullptr, clonedDoc, nullptr);
+ RefPtr<StyleSheet> clonedSheet =
+ sheet->Clone(nullptr, nullptr, clonedDoc, nullptr);
NS_WARNING_ASSERTION(clonedSheet,
"Cloning a stylesheet didn't work!");
if (clonedSheet) {
clonedDoc->AddStyleSheet(clonedSheet);
}
} else {
NS_ERROR("stylo: ServoStyleSheet doesn't support cloning");
}
@@ -9951,18 +9951,18 @@ nsIDocument::CreateStaticClone(nsIDocShe
}
// Iterate backwards to maintain order
for (StyleSheet* sheet : Reversed(thisAsDoc->mOnDemandBuiltInUASheets)) {
if (sheet) {
if (sheet->IsApplicable()) {
// XXXheycam Need to make ServoStyleSheet cloning work.
if (sheet->IsGecko()) {
- RefPtr<CSSStyleSheet> clonedSheet =
- sheet->AsGecko()->Clone(nullptr, nullptr, clonedDoc, nullptr);
+ RefPtr<StyleSheet> clonedSheet =
+ sheet->Clone(nullptr, nullptr, clonedDoc, nullptr);
NS_WARNING_ASSERTION(clonedSheet,
"Cloning a stylesheet didn't work!");
if (clonedSheet) {
clonedDoc->AddOnDemandBuiltInUASheet(clonedSheet);
}
} else {
NS_ERROR("stylo: ServoStyleSheet doesn't support cloning");
}
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -648,27 +648,27 @@ CSSStyleSheet::AppendAllChildSheets(nsTA
{
for (StyleSheet* child = GetFirstChild(); child;
child = child->mNext) {
aArray.AppendElement(child->AsGecko());
}
}
-already_AddRefed<CSSStyleSheet>
-CSSStyleSheet::Clone(CSSStyleSheet* aCloneParent,
+already_AddRefed<StyleSheet>
+CSSStyleSheet::Clone(StyleSheet* aCloneParent,
css::ImportRule* aCloneOwnerRule,
nsIDocument* aCloneDocument,
nsINode* aCloneOwningNode) const
{
- RefPtr<CSSStyleSheet> clone = new CSSStyleSheet(*this,
- aCloneParent,
- aCloneOwnerRule,
- aCloneDocument,
- aCloneOwningNode);
+ RefPtr<StyleSheet> clone = new CSSStyleSheet(*this,
+ static_cast<CSSStyleSheet*>(aCloneParent),
+ aCloneOwnerRule,
+ aCloneDocument,
+ aCloneOwningNode);
return clone.forget();
}
#ifdef DEBUG
static void
ListRules(const nsCOMArray<css::Rule>& aRules, FILE* aOut, int32_t aIndent)
{
for (int32_t index = aRules.Count() - 1; index >= 0; --index) {
--- a/layout/style/CSSStyleSheet.h
+++ b/layout/style/CSSStyleSheet.h
@@ -35,19 +35,17 @@ class nsMediaQueryResultCacheKey;
class nsStyleSet;
class nsPresContext;
class nsXMLNameSpaceMap;
namespace mozilla {
class CSSStyleSheet;
namespace css {
-class Rule;
class GroupRule;
-class ImportRule;
} // namespace css
namespace dom {
class CSSRuleList;
} // namespace dom
// -------------------------------
// CSS Style Sheet Inner Data Container
//
@@ -124,20 +122,20 @@ public:
css::ImportRule* GetOwnerRule() const { return mOwnerRule; }
// Workaround overloaded-virtual warning in GCC.
using StyleSheet::GetOwnerRule;
nsXMLNameSpaceMap* GetNameSpaceMap() const {
return Inner()->mNameSpaceMap;
}
- already_AddRefed<CSSStyleSheet> Clone(CSSStyleSheet* aCloneParent,
- css::ImportRule* aCloneOwnerRule,
- nsIDocument* aCloneDocument,
- nsINode* aCloneOwningNode) const;
+ virtual already_AddRefed<StyleSheet> Clone(StyleSheet* aCloneParent,
+ css::ImportRule* aCloneOwnerRule,
+ nsIDocument* aCloneDocument,
+ nsINode* aCloneOwningNode) const final;
bool IsModified() const final { return mDirty; }
void SetModifiedByChildRule() {
NS_ASSERTION(mDirty,
"sheet must be marked dirty before handing out child rules");
DidDirty();
}
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -1212,18 +1212,18 @@ Loader::CreateSheet(nsIURI* aURI,
}
NS_ASSERTION(!sheet->AsGecko()->IsModified() ||
!sheet->AsGecko()->IsComplete(),
"Unexpected modified complete sheet");
NS_ASSERTION(sheet->AsGecko()->IsComplete() ||
aSheetState != eSheetComplete,
"Sheet thinks it's not complete while we think it is");
- RefPtr<CSSStyleSheet> clonedSheet =
- sheet->AsGecko()->Clone(nullptr, nullptr, nullptr, nullptr);
+ RefPtr<StyleSheet> clonedSheet =
+ sheet->Clone(nullptr, nullptr, nullptr, nullptr);
*aSheet = Move(clonedSheet);
if (*aSheet && fromCompleteSheets &&
!sheet->AsGecko()->GetOwnerNode() &&
!sheet->AsGecko()->GetParentSheet()) {
// The sheet we're cloning isn't actually referenced by
// anyone. Replace it in the cache, so that if our CSSOM is
// later modified we don't end up with two copies of our inner
// hanging around.
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -34,16 +34,26 @@ ServoStyleSheet::ServoStyleSheet(css::Sh
net::ReferrerPolicy aReferrerPolicy,
const dom::SRIMetadata& aIntegrity)
: StyleSheet(StyleBackendType::Servo, aParsingMode)
{
mInner = new ServoStyleSheetInner(aCORSMode, aReferrerPolicy, aIntegrity);
mInner->AddSheet(this);
}
+ServoStyleSheet::ServoStyleSheet(const ServoStyleSheet& aCopy,
+ ServoStyleSheet* aParentToUse,
+ css::ImportRule* aOwnerRuleToUse,
+ nsIDocument* aDocumentToUse,
+ nsINode* aOwningNodeToUse)
+ : StyleSheet(aCopy, aDocumentToUse, aOwningNodeToUse)
+{
+ mParent = aParentToUse;
+}
+
ServoStyleSheet::~ServoStyleSheet()
{
UnparentChildren();
DropRuleList();
}
// QueryInterface implementation for ServoStyleSheet
@@ -116,16 +126,30 @@ ServoStyleSheet::DropRuleList()
css::Rule*
ServoStyleSheet::GetDOMOwnerRule() const
{
NS_ERROR("stylo: Don't know how to get DOM owner rule for ServoStyleSheet");
return nullptr;
}
+already_AddRefed<StyleSheet>
+ServoStyleSheet::Clone(StyleSheet* aCloneParent,
+ css::ImportRule* aCloneOwnerRule,
+ nsIDocument* aCloneDocument,
+ nsINode* aCloneOwningNode) const
+{
+ RefPtr<StyleSheet> clone = new ServoStyleSheet(*this,
+ static_cast<ServoStyleSheet*>(aCloneParent),
+ aCloneOwnerRule,
+ aCloneDocument,
+ aCloneOwningNode);
+ return clone.forget();
+}
+
CSSRuleList*
ServoStyleSheet::GetCssRulesInternal(ErrorResult& aRv)
{
if (!mRuleList) {
RefPtr<ServoCssRules> rawRules =
Servo_StyleSheet_GetRules(Inner()->mSheet).Consume();
mRuleList = new ServoCSSRuleList(this, rawRules.forget());
}
--- a/layout/style/ServoStyleSheet.h
+++ b/layout/style/ServoStyleSheet.h
@@ -15,17 +15,16 @@
#include "nsStringFwd.h"
namespace mozilla {
class ServoCSSRuleList;
namespace css {
class Loader;
-class Rule;
}
// -------------------------------
// Servo Style Sheet Inner Data Container
//
struct ServoStyleSheetInner : public StyleSheetInfo
{
@@ -81,16 +80,21 @@ public:
// version.
css::Rule* GetDOMOwnerRule() const final;
void WillDirty() {}
void DidDirty() {}
bool IsModified() const final { return false; }
+ virtual already_AddRefed<StyleSheet> Clone(StyleSheet* aCloneParent,
+ css::ImportRule* aCloneOwnerRule,
+ nsIDocument* aCloneDocument,
+ nsINode* aCloneOwningNode) const final;
+
protected:
virtual ~ServoStyleSheet();
ServoStyleSheetInner* Inner() const
{
return static_cast<ServoStyleSheetInner*>(mInner);
}
@@ -98,16 +102,22 @@ protected:
dom::CSSRuleList* GetCssRulesInternal(ErrorResult& aRv);
uint32_t InsertRuleInternal(const nsAString& aRule,
uint32_t aIndex, ErrorResult& aRv);
void DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv);
void EnabledStateChangedInternal() {}
private:
+ ServoStyleSheet(const ServoStyleSheet& aCopy,
+ ServoStyleSheet* aParentToUse,
+ css::ImportRule* aOwnerRuleToUse,
+ nsIDocument* aDocumentToUse,
+ nsINode* aOwningNodeToUse);
+
void DropRuleList();
RefPtr<ServoCSSRuleList> mRuleList;
friend class StyleSheet;
};
} // namespace mozilla
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -31,16 +31,17 @@ class ServoStyleSheet;
struct StyleSheetInfo;
namespace dom {
class CSSRuleList;
class SRIMetadata;
} // namespace dom
namespace css {
+class ImportRule;
class Rule;
}
/**
* Superclass for data common to CSSStyleSheet and ServoStyleSheet.
*/
class StyleSheet : public nsIDOMCSSStyleSheet
, public nsWrapperCache
@@ -103,16 +104,21 @@ public:
* Whether the sheet is applicable. A sheet that is not applicable
* should never be inserted into a style set. A sheet may not be
* applicable for a variety of reasons including being disabled and
* being incomplete.
*/
inline bool IsApplicable() const;
inline bool HasRules() const;
+ virtual already_AddRefed<StyleSheet> Clone(StyleSheet* aCloneParent,
+ css::ImportRule* aCloneOwnerRule,
+ nsIDocument* aCloneDocument,
+ nsINode* aCloneOwningNode) const = 0;
+
virtual bool IsModified() const = 0;
// style sheet owner info
enum DocumentAssociationMode {
// OwnedByDocument means mDocument owns us (possibly via a chain of other
// stylesheets).
OwnedByDocument,
// NotOwnedByDocument means we're owned by something that might have a
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -263,19 +263,19 @@ ImportRule::ImportRule(nsMediaList* aMed
ImportRule::ImportRule(const ImportRule& aCopy)
: Rule(aCopy),
mURLSpec(aCopy.mURLSpec)
{
// Whether or not an @import rule has a null sheet is a permanent
// property of that @import rule, since it is null only if the target
// sheet failed security checks.
if (aCopy.mChildSheet) {
- RefPtr<CSSStyleSheet> sheet =
+ RefPtr<StyleSheet> sheet =
aCopy.mChildSheet->Clone(nullptr, this, nullptr, nullptr);
- SetSheet(sheet);
+ SetSheet(static_cast<CSSStyleSheet*>(sheet.get()));
// SetSheet sets mMedia appropriately
} else {
// We better just copy mMedia from aCopy, since we have nowhere else to get
// one.
mMedia = aCopy.mMedia;
}
}