Bug 1358993 - (Part 2) Add ServoStyleSheet::ReparseSheet function to collect reusable style sheets and clean up the child sheets of the parent sheet.
MozReview-Commit-ID: CKqKFenXvVs
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -9,16 +9,17 @@
#include "mozilla/css/Rule.h"
#include "mozilla/StyleBackendType.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoMediaList.h"
#include "mozilla/ServoCSSRuleList.h"
#include "mozilla/css/GroupRule.h"
#include "mozilla/dom/CSSRuleList.h"
#include "mozilla/dom/MediaList.h"
+#include "nsIStyleSheetLinkingElement.h"
#include "Loader.h"
#include "mozAutoDocUpdate.h"
#include "nsIDOMCSSStyleSheet.h"
using namespace mozilla::dom;
@@ -174,16 +175,68 @@ ServoStyleSheet::ParseSheet(css::Loader*
void
ServoStyleSheet::LoadFailed()
{
Inner()->mSheet = Servo_StyleSheet_Empty(mParsingMode).Consume();
Inner()->mURLData = URLExtraData::Dummy();
}
+nsresult
+ServoStyleSheet::ReparseSheet(const nsAString& aInput)
+{
+ // TODO(kuoe0): Bug 1367996 - Need to call document notification
+ // (StyleRuleAdded() and StyleRuleRemoved()) like what we do in
+ // CSSStyleSheet::ReparseSheet().
+
+ if (!mInner->mComplete) {
+ return NS_ERROR_DOM_INVALID_ACCESS_ERR;
+ }
+
+ RefPtr<css::Loader> loader;
+ if (mDocument) {
+ loader = mDocument->CSSLoader();
+ NS_ASSERTION(loader, "Document with no CSS loader!");
+ } else {
+ loader = new css::Loader(StyleBackendType::Servo, nullptr);
+ }
+
+ // cache child sheets to reuse
+ css::LoaderReusableStyleSheets reusableSheets;
+ for (StyleSheet* child = GetFirstChild(); child; child = child->mNext) {
+ if (child->GetOriginalURI()) {
+ reusableSheets.AddReusableSheet(child);
+ }
+ }
+
+ // clean up child sheets list
+ for (StyleSheet* child = GetFirstChild(); child; ) {
+ StyleSheet* next = child->mNext;
+ child->mParent = nullptr;
+ child->SetAssociatedDocument(nullptr, NotOwnedByDocument);
+ child->mNext = nullptr;
+ child = next;
+ }
+ Inner()->mFirstChild = nullptr;
+
+ uint32_t lineNumber = 1;
+ if (mOwningNode) {
+ nsCOMPtr<nsIStyleSheetLinkingElement> link = do_QueryInterface(mOwningNode);
+ if (link) {
+ lineNumber = link->GetLineNumber();
+ }
+ }
+
+ nsresult rv = ParseSheet(loader, aInput, mInner->mSheetURI, mInner->mBaseURI,
+ mInner->mPrincipal, lineNumber,
+ eCompatibility_FullStandards, &reusableSheets);
+ NS_ENSURE_SUCCESS(rv, rv);
+ return NS_OK;
+}
+
// nsICSSLoaderObserver implementation
NS_IMETHODIMP
ServoStyleSheet::StyleSheetLoaded(StyleSheet* aSheet,
bool aWasAlternate,
nsresult aStatus)
{
MOZ_ASSERT(aSheet->IsServo(),
"why we were called back with a CSSStyleSheet?");
--- a/layout/style/ServoStyleSheet.h
+++ b/layout/style/ServoStyleSheet.h
@@ -90,16 +90,18 @@ public:
/**
* Called instead of ParseSheet to initialize the Servo stylesheet object
* for a failed load. Either ParseSheet or LoadFailed must be called before
* adding a ServoStyleSheet to a ServoStyleSet.
*/
void LoadFailed();
+ nsresult ReparseSheet(const nsAString& aInput);
+
const RawServoStyleSheet* RawSheet() const {
return Inner()->mSheet;
}
void SetSheetForImport(const RawServoStyleSheet* aSheet) {
MOZ_ASSERT(!Inner()->mSheet);
Inner()->mSheet = aSheet;
}