Bug 1535788 - Make the Document own the StyleSet. r=heycam

This is the last step to be able to call matchMedia on display: none iframes.

This is green, except for some startup preference query tests that I'm going to
address in a blocking bug (making LangGroupFontPrefs global, basically).

The setup is similar to the ShadowRoot one, except we don't eagerly keep the
StyleSet around up-to-date, we only fill it if it ever had a pres context.

Differential Revision: https://phabricator.services.mozilla.com/D23903

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2019-04-03 07:02:00 +00:00
parent 2b587a5803
commit d8e2990d8a
24 changed files with 301 additions and 422 deletions

View File

@ -45,6 +45,7 @@
#include "nsIObserver.h"
#include "nsIBaseWindow.h"
#include "nsILayoutHistoryState.h"
#include "nsLayoutStylesheetCache.h"
#include "mozilla/css/Loader.h"
#include "mozilla/css/ImageLoader.h"
#include "nsDocShell.h"
@ -1220,6 +1221,7 @@ Document::Document(const char* aContentType)
mInXBLUpdate(false),
mNeedsReleaseAfterStackRefCntRelease(false),
mStyleSetFilled(false),
mQuirkSheetAdded(false),
mSSApplicableStateNotificationPending(false),
mMayHaveTitleElement(false),
mDOMLoadingSet(false),
@ -1649,10 +1651,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
cb.NoteXPCOMChild(ToSupports(tmp));
}
for (auto iter = tmp->mIdentifierMap.ConstIter(); !iter.Done(); iter.Next()) {
iter.Get()->Traverse(&cb);
}
tmp->mExternalResourceMap.Traverse(&cb);
// Traverse all Document pointer members.
@ -1666,7 +1664,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParser)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScriptGlobalObject)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListenerManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStyleSheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheetSetList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScriptLoader)
@ -1708,7 +1705,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrototypeDocument)
// Traverse all our nsCOMArrays.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages)
for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) {
@ -1814,8 +1810,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
tmp->mListenerManager = nullptr;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStyleSheets)
if (tmp->mStyleSheetSetList) {
tmp->mStyleSheetSetList->Disconnect();
tmp->mStyleSheetSetList = nullptr;
@ -1835,7 +1829,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
// assume that *most* cycles you actually want to break somewhere
// else, and not unlink an awful lot here.
tmp->mIdentifierMap.Clear();
tmp->mExpandoAndGeneration.OwnerUnlinked();
if (tmp->mAnimationController) {
@ -1913,6 +1906,8 @@ nsresult Document::Init() {
mFeaturePolicy = new FeaturePolicy(this);
mFeaturePolicy->SetDefaultOrigin(NodePrincipal());
mStyleSet = MakeUnique<ServoStyleSet>(*this);
mozilla::HoldJSObjects(this);
return NS_OK;
@ -2205,15 +2200,12 @@ already_AddRefed<nsIPrincipal> Document::MaybeDowngradePrincipal(
}
void Document::RemoveDocStyleSheetsFromStyleSets() {
MOZ_ASSERT(mStyleSetFilled);
// The stylesheets should forget us
for (StyleSheet* sheet : Reversed(mStyleSheets)) {
sheet->ClearAssociatedDocumentOrShadowRoot();
if (sheet->IsApplicable()) {
RefPtr<PresShell> presShell = GetPresShell();
if (presShell) {
presShell->StyleSet()->RemoveDocStyleSheet(sheet);
}
mStyleSet->RemoveDocStyleSheet(sheet);
}
// XXX Tell observers?
}
@ -2224,12 +2216,8 @@ void Document::RemoveStyleSheetsFromStyleSets(
// The stylesheets should forget us
for (StyleSheet* sheet : Reversed(aSheets)) {
sheet->ClearAssociatedDocumentOrShadowRoot();
if (sheet->IsApplicable()) {
RefPtr<PresShell> presShell = GetPresShell();
if (presShell) {
presShell->StyleSet()->RemoveStyleSheet(aType, sheet);
}
if (mStyleSetFilled && sheet->IsApplicable()) {
mStyleSet->RemoveStyleSheet(aType, sheet);
}
// XXX Tell observers?
}
@ -2255,8 +2243,6 @@ void Document::ResetStylesheetsToURI(nsIURI* aURI) {
RemoveStyleSheetsFromStyleSets(*sheetService->AuthorStyleSheets(),
SheetType::Doc);
}
mStyleSetFilled = false;
}
// Release all the sheets
@ -2281,11 +2267,13 @@ void Document::ResetStylesheetsToURI(nsIURI* aURI) {
mStyleAttrStyleSheet = new nsHTMLCSSStyleSheet();
}
// Now set up our style sets
if (PresShell* presShell = GetPresShell()) {
FillStyleSet(presShell->StyleSet());
if (presShell->StyleSet()->StyleSheetsHaveChanged()) {
presShell->ApplicableStylesChanged();
if (mStyleSetFilled) {
FillStyleSetDocumentSheets();
if (mStyleSet->StyleSheetsHaveChanged()) {
if (PresShell* presShell = GetPresShell()) {
presShell->ApplicableStylesChanged();
}
}
}
}
@ -2298,34 +2286,126 @@ static void AppendSheetsToStyleSet(ServoStyleSet* aStyleSet,
}
}
void Document::FillStyleSet(ServoStyleSet* aStyleSet) {
MOZ_ASSERT(aStyleSet, "Must have a style set");
MOZ_ASSERT(aStyleSet->SheetCount(SheetType::Doc) == 0,
"Style set already has document sheets?");
void Document::FillStyleSetUserAndUASheets() {
// Make sure this does the same thing as PresShell::Add{User,Agent}Sheet wrt
// ordering.
// The document will fill in the document sheets when we create the presshell
auto cache = nsLayoutStylesheetCache::Singleton();
nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
MOZ_ASSERT(sheetService,
"should never be creating a StyleSet after the style sheet "
"service has gone");
for (StyleSheet* sheet : *sheetService->UserStyleSheets()) {
mStyleSet->AppendStyleSheet(SheetType::User, sheet);
}
StyleSheet* sheet = IsInChromeDocShell() ? cache->GetUserChromeSheet()
: cache->GetUserContentSheet();
if (sheet) {
mStyleSet->AppendStyleSheet(SheetType::User, sheet);
}
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->UASheet());
if (MOZ_LIKELY(NodeInfoManager()->MathMLEnabled())) {
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->MathMLSheet());
}
if (MOZ_LIKELY(NodeInfoManager()->SVGEnabled())) {
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->SVGSheet());
}
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->HTMLSheet());
if (nsLayoutUtils::ShouldUseNoFramesSheet(this)) {
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->NoFramesSheet());
}
if (nsLayoutUtils::ShouldUseNoScriptSheet(this)) {
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->NoScriptSheet());
}
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->CounterStylesSheet());
// Load the minimal XUL rules for scrollbars and a few other XUL things
// that non-XUL (typically HTML) documents commonly use.
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->MinimalXULSheet());
// Only load the full XUL sheet if we'll need it.
if (LoadsFullXULStyleSheetUpFront()) {
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->XULSheet());
}
MOZ_ASSERT(!mQuirkSheetAdded);
if (mCompatMode == eCompatibility_NavQuirks) {
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->QuirkSheet());
mQuirkSheetAdded = true;
}
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->FormsSheet());
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->ScrollbarsSheet());
mStyleSet->AppendStyleSheet(SheetType::Agent, cache->PluginProblemSheet());
for (StyleSheet* sheet : *sheetService->AgentStyleSheets()) {
mStyleSet->AppendStyleSheet(SheetType::Agent, sheet);
}
}
void Document::FillStyleSet() {
MOZ_ASSERT(!mStyleSetFilled);
FillStyleSetUserAndUASheets();
FillStyleSetDocumentSheets();
mStyleSetFilled = true;
}
void Document::FillStyleSetDocumentSheets() {
MOZ_ASSERT(mStyleSet->SheetCount(SheetType::Doc) == 0,
"Style set already has document sheets?");
for (StyleSheet* sheet : Reversed(mStyleSheets)) {
if (sheet->IsApplicable()) {
aStyleSet->AddDocStyleSheet(sheet, this);
mStyleSet->AddDocStyleSheet(sheet, this);
}
}
if (nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance()) {
nsTArray<RefPtr<StyleSheet>>& sheets = *sheetService->AuthorStyleSheets();
for (StyleSheet* sheet : sheets) {
aStyleSet->AppendStyleSheet(SheetType::Doc, sheet);
}
nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
for (StyleSheet* sheet : *sheetService->AuthorStyleSheets()) {
mStyleSet->AppendStyleSheet(SheetType::Doc, sheet);
}
AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAgentSheet],
AppendSheetsToStyleSet(mStyleSet.get(), mAdditionalSheets[eAgentSheet],
SheetType::Agent);
AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eUserSheet],
AppendSheetsToStyleSet(mStyleSet.get(), mAdditionalSheets[eUserSheet],
SheetType::User);
AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAuthorSheet],
AppendSheetsToStyleSet(mStyleSet.get(), mAdditionalSheets[eAuthorSheet],
SheetType::Doc);
}
mStyleSetFilled = true;
void Document::CompatibilityModeChanged() {
MOZ_ASSERT(IsHTMLOrXHTML());
CSSLoader()->SetCompatibilityMode(mCompatMode);
mStyleSet->CompatibilityModeChanged();
if (!mStyleSetFilled) {
MOZ_ASSERT(!mQuirkSheetAdded);
return;
}
if (mQuirkSheetAdded == NeedsQuirksSheet()) {
return;
}
auto cache = nsLayoutStylesheetCache::Singleton();
StyleSheet* sheet = cache->QuirkSheet();
if (mQuirkSheetAdded) {
mStyleSet->RemoveStyleSheet(SheetType::Agent, sheet);
} else {
mStyleSet->AppendStyleSheet(SheetType::Agent, sheet);
}
mQuirkSheetAdded = !mQuirkSheetAdded;
if (PresShell* presShell = GetPresShell()) {
presShell->ApplicableStylesChanged();
}
}
static void WarnIfSandboxIneffective(nsIDocShell* aDocShell,
@ -3590,19 +3670,29 @@ static inline void AssertNoStaleServoDataIn(nsINode& aSubtreeRoot) {
}
already_AddRefed<PresShell> Document::CreatePresShell(
nsPresContext* aContext, nsViewManager* aViewManager,
UniquePtr<ServoStyleSet> aStyleSet) {
NS_ASSERTION(!mPresShell, "We have a presshell already!");
nsPresContext* aContext, nsViewManager* aViewManager) {
MOZ_ASSERT(!mPresShell, "We have a presshell already!");
NS_ENSURE_FALSE(GetBFCacheEntry(), nullptr);
FillStyleSet(aStyleSet.get());
AssertNoStaleServoDataIn(*this);
RefPtr<PresShell> presShell = new PresShell;
// Note: we don't hold a ref to the shell (it holds a ref to us)
mPresShell = presShell;
presShell->Init(this, aContext, aViewManager, std::move(aStyleSet));
bool hadStyleSheets = mStyleSetFilled;
if (!hadStyleSheets) {
FillStyleSet();
}
presShell->Init(this, aContext, aViewManager);
if (hadStyleSheets) {
// Gaining a shell causes changes in how media queries are evaluated, so
// invalidate that.
aContext->MediaFeatureValuesChanged({MediaFeatureChange::kAllChanges});
}
// Make sure to never paint if we belong to an invisible DocShell.
nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
@ -3705,6 +3795,8 @@ void Document::DeletePresShell() {
presContext->RefreshDriver()->CancelPendingFullscreenEvents(this);
}
mStyleSet->ShellDetachedFromDocument();
// When our shell goes away, request that all our images be immediately
// discarded, so we don't carry around decoded image data for a document we
// no longer intend to paint.
@ -3719,7 +3811,6 @@ void Document::DeletePresShell() {
PresShell* oldPresShell = mPresShell;
mPresShell = nullptr;
UpdateFrameRequestCallbackSchedulingState(oldPresShell);
mStyleSetFilled = false;
ClearStaleServoData();
AssertNoStaleServoDataIn(*this);
@ -3913,9 +4004,11 @@ void Document::RemoveChildNode(nsIContent* aKid, bool aNotify) {
}
void Document::AddStyleSheetToStyleSets(StyleSheet* aSheet) {
if (PresShell* presShell = GetPresShell()) {
presShell->StyleSet()->AddDocStyleSheet(aSheet, this);
presShell->ApplicableStylesChanged();
if (mStyleSetFilled) {
mStyleSet->AddDocStyleSheet(aSheet, this);
if (PresShell* presShell = GetPresShell()) {
presShell->ApplicableStylesChanged();
}
}
}
@ -3953,9 +4046,11 @@ void Document::NotifyStyleSheetRemoved(StyleSheet* aSheet,
}
void Document::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet) {
if (PresShell* presShell = GetPresShell()) {
presShell->StyleSet()->RemoveDocStyleSheet(aSheet);
presShell->ApplicableStylesChanged();
if (mStyleSetFilled) {
mStyleSet->RemoveDocStyleSheet(aSheet);
if (PresShell* presShell = GetPresShell()) {
presShell->ApplicableStylesChanged();
}
}
}
@ -4135,10 +4230,12 @@ nsresult Document::AddAdditionalStyleSheet(additionalSheetType aType,
mAdditionalSheets[aType].AppendElement(aSheet);
if (PresShell* presShell = GetPresShell()) {
if (mStyleSetFilled) {
SheetType type = ConvertAdditionalSheetType(aType);
presShell->StyleSet()->AppendStyleSheet(type, aSheet);
presShell->ApplicableStylesChanged();
mStyleSet->AppendStyleSheet(type, aSheet);
if (PresShell* presShell = GetPresShell()) {
presShell->ApplicableStylesChanged();
}
}
// Passing false, so documet.styleSheets.length will not be affected by
@ -4160,10 +4257,12 @@ void Document::RemoveAdditionalStyleSheet(additionalSheetType aType,
if (!mIsGoingAway) {
MOZ_ASSERT(sheetRef->IsApplicable());
if (PresShell* presShell = GetPresShell()) {
if (mStyleSetFilled) {
SheetType type = ConvertAdditionalSheetType(aType);
presShell->StyleSet()->RemoveStyleSheet(type, sheetRef);
presShell->ApplicableStylesChanged();
mStyleSet->RemoveStyleSheet(type, sheetRef);
if (PresShell* presShell = GetPresShell()) {
presShell->ApplicableStylesChanged();
}
}
}
@ -11668,8 +11767,7 @@ void Document::FlushUserFontSet() {
if (gfxPlatform::GetPlatform()->DownloadableFontsEnabled()) {
nsTArray<nsFontFaceRuleContainer> rules;
PresShell* presShell = GetPresShell();
if (presShell && !presShell->StyleSet()->AppendFontFaceRules(rules)) {
if (mStyleSetFilled && !mStyleSet->AppendFontFaceRules(rules)) {
return;
}
@ -11687,6 +11785,7 @@ void Document::FlushUserFontSet() {
// reflect that we're modifying @font-face rules. (However,
// without a reflow, nothing will happen to start any downloads
// that are needed.)
PresShell* presShell = GetPresShell();
if (changed && presShell) {
if (nsPresContext* presContext = presShell->GetPresContext()) {
presContext->UserFontSetUpdated();

View File

@ -1244,9 +1244,8 @@ class Document : public nsINode,
* method is responsible for calling BeginObservingDocument() on the
* presshell if the presshell should observe document mutations.
*/
already_AddRefed<PresShell> CreatePresShell(
nsPresContext* aContext, nsViewManager* aViewManager,
UniquePtr<ServoStyleSet> aStyleSet);
already_AddRefed<PresShell> CreatePresShell(nsPresContext* aContext,
nsViewManager* aViewManager);
void DeletePresShell();
PresShell* GetPresShell() const {
@ -1631,6 +1630,14 @@ class Document : public nsINode,
// Get the "head" element in the sense of document.head.
HTMLSharedElement* GetHead();
ServoStyleSet* StyleSetForPresShellOrMediaQueryEvaluation() const {
return mStyleSet.get();
}
// Whether we filled the style set with any style sheet. Only meant to be used
// from DocumentOrShadowRoot::Traverse.
bool StyleSetFilled() const { return mStyleSetFilled; }
/**
* Accessors to the collection of stylesheets owned by this document.
* Style sheets are ordered, most significant last.
@ -3784,7 +3791,14 @@ class Document : public nsINode,
void RemoveStyleSheetsFromStyleSets(
const nsTArray<RefPtr<StyleSheet>>& aSheets, SheetType aType);
void ResetStylesheetsToURI(nsIURI* aURI);
void FillStyleSet(ServoStyleSet* aStyleSet);
void FillStyleSet();
void FillStyleSetUserAndUASheets();
void FillStyleSetDocumentSheets();
void CompatibilityModeChanged();
bool NeedsQuirksSheet() const {
// SVG documents never load quirk.css.
return mCompatMode == eCompatibility_NavQuirks && !IsSVGDocument();
}
void AddStyleSheetToStyleSets(StyleSheet* aSheet);
void RemoveStyleSheetFromStyleSets(StyleSheet* aSheet);
void NotifyStyleSheetAdded(StyleSheet* aSheet, bool aDocumentSheet);
@ -3808,6 +3822,7 @@ class Document : public nsINode,
// Lazy-initialization to have mDocGroup initialized in prior to the
// SelectorCaches.
UniquePtr<SelectorCache> mSelectorCache;
UniquePtr<ServoStyleSet> mStyleSet;
protected:
friend class nsDocumentOnStack;
@ -4165,10 +4180,12 @@ class Document : public nsINode,
bool mNeedsReleaseAfterStackRefCntRelease : 1;
// Whether we have filled our pres shell's style set with the document's
// additional sheets and sheets from the nsStyleSheetService.
// Whether we have filled our style set with all the stylesheets.
bool mStyleSetFilled : 1;
// Whether we have a quirks mode stylesheet in the style set.
bool mQuirkSheetAdded : 1;
// Keeps track of whether we have a pending
// 'style-sheet-applicable-state-changed' notification.
bool mSSApplicableStateNotificationPending : 1;

View File

@ -588,6 +588,29 @@ nsRadioGroupStruct* DocumentOrShadowRoot::GetOrCreateRadioGroup(
void DocumentOrShadowRoot::Traverse(DocumentOrShadowRoot* tmp,
nsCycleCollectionTraversalCallback& cb) {
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStyleSheets)
for (StyleSheet* sheet : tmp->mStyleSheets) {
if (!sheet->IsApplicable()) {
continue;
}
// The style set or mServoStyles keep more references to it if the sheet is
// applicable.
if (tmp->mKind == Kind::ShadowRoot) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mServoStyles->sheets[i]");
cb.NoteXPCOMChild(sheet);
} else if (tmp->AsNode().AsDocument()->StyleSetFilled()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(
cb, "mStyleSet->mStyleSheets[SheetType::Author][i]");
cb.NoteXPCOMChild(sheet);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(
cb, "mStyleSet->mRawSet.stylist.stylesheets.author[i]");
cb.NoteXPCOMChild(sheet);
}
}
for (auto iter = tmp->mIdentifierMap.ConstIter(); !iter.Done(); iter.Next()) {
iter.Get()->Traverse(&cb);
}
for (auto iter = tmp->mRadioGroups.Iter(); !iter.Done(); iter.Next()) {
nsRadioGroupStruct* radioGroup = iter.UserData();
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(
@ -604,6 +627,8 @@ void DocumentOrShadowRoot::Traverse(DocumentOrShadowRoot* tmp,
}
void DocumentOrShadowRoot::Unlink(DocumentOrShadowRoot* tmp) {
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStyleSheets)
tmp->mIdentifierMap.Clear();
tmp->mRadioGroups.Clear();
}

View File

@ -30,19 +30,6 @@ using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_CLASS(ShadowRoot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ShadowRoot, DocumentFragment)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
for (StyleSheet* sheet : tmp->mStyleSheets) {
// mServoStyles keeps another reference to it if applicable.
if (sheet->IsApplicable()) {
MOZ_ASSERT(tmp->mServoStyles);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mServoStyles->sheets[i]");
cb.NoteXPCOMChild(sheet);
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStyleSheets)
for (auto iter = tmp->mIdentifierMap.ConstIter(); !iter.Done(); iter.Next()) {
iter.Get()->Traverse(&cb);
}
DocumentOrShadowRoot::Traverse(tmp, cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -50,8 +37,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ShadowRoot)
if (tmp->GetHost()) {
tmp->GetHost()->RemoveMutationObserver(tmp);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStyleSheets)
tmp->mIdentifierMap.Clear();
DocumentOrShadowRoot::Unlink(tmp);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(DocumentFragment)

View File

@ -20,6 +20,7 @@
#include "SVGObserverUtils.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "nsIPresShellInlines.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIFrame.h"

View File

@ -509,7 +509,7 @@ nsresult nsHTMLDocument::StartDocumentLoad(const char* aCommand,
if (!viewSource && xhtml) {
// We're parsing XHTML as XML, remember that.
mType = eXHTML;
mCompatMode = eCompatibility_FullStandards;
SetCompatibilityMode(eCompatibility_FullStandards);
loadAsHtml5 = false;
}
@ -528,8 +528,6 @@ nsresult nsHTMLDocument::StartDocumentLoad(const char* aCommand,
}
}
CSSLoader()->SetCompatibilityMode(mCompatMode);
nsresult rv = Document::StartDocumentLoad(aCommand, aChannel, aLoadGroup,
aContainer, aDocListener, aReset);
if (NS_FAILED(rv)) {
@ -782,10 +780,7 @@ void nsHTMLDocument::SetCompatibilityMode(nsCompatibility aMode) {
return;
}
mCompatMode = aMode;
CSSLoader()->SetCompatibilityMode(mCompatMode);
if (nsPresContext* pc = GetPresContext()) {
pc->CompatibilityModeChanged();
}
CompatibilityModeChanged();
}
bool nsHTMLDocument::UseWidthDeviceWidthFallbackViewport() const {

View File

@ -27,6 +27,7 @@
#include "nsIHTMLObjectResizer.h"
#include "nsStubMutationObserver.h"
#include "nsINode.h"
#include "nsIPresShellInlines.h"
#include "nsISupportsImpl.h"
#include "nsISupportsUtils.h"
#include "nsLiteralString.h"

View File

@ -897,7 +897,6 @@ PresShell::~PresShell() {
MOZ_ASSERT(mAllocatedPointers.IsEmpty(),
"Some pres arena objects were not freed");
mStyleSet = nullptr;
mFrameManager = nullptr;
mFrameConstructor = nullptr;
@ -911,8 +910,7 @@ PresShell::~PresShell() {
* calls AddRef() on us.
*/
void PresShell::Init(Document* aDocument, nsPresContext* aPresContext,
nsViewManager* aViewManager,
UniquePtr<ServoStyleSet> aStyleSet) {
nsViewManager* aViewManager) {
MOZ_ASSERT(aDocument, "null ptr");
MOZ_ASSERT(aPresContext, "null ptr");
MOZ_ASSERT(aViewManager, "null ptr");
@ -944,16 +942,7 @@ void PresShell::Init(Document* aDocument, nsPresContext* aPresContext,
mPresContext = aPresContext;
mPresContext->AttachShell(this);
// Now we can initialize the style set. Make sure to set the member before
// calling Init, since various subroutines need to find the style set off
// the PresContext during initialization.
mStyleSet = std::move(aStyleSet);
mStyleSet->Init(aPresContext);
// Notify our prescontext that it now has a compatibility mode. Note that
// this MUST happen after we set up our style set but before we create any
// frames.
mPresContext->CompatibilityModeChanged();
mPresContext->DeviceContext()->InitFontCache();
// Add the preference style sheet.
UpdatePreferenceStyles();
@ -1276,8 +1265,7 @@ void PresShell::Destroy() {
// release our pref style sheet, if we have one still
//
// FIXME(emilio): Why do we need to do this? The stylist is getting nixed with
// us anyway.
// TODO(emilio): Should we move the preference sheet tracking to the Document?
RemovePreferenceStyles();
mIsDestroying = true;
@ -1310,7 +1298,6 @@ void PresShell::Destroy() {
mViewManager = nullptr;
}
mStyleSet->BeginShutdown();
nsRefreshDriver* rd = GetPresContext()->RefreshDriver();
// This shell must be removed from the document before the frame
@ -1361,9 +1348,6 @@ void PresShell::Destroy() {
weakFrame->Clear(this);
}
// Let the style set do its cleanup.
mStyleSet->Shutdown();
if (mPresContext) {
// We hold a reference to the pres context, and it holds a weak link back
// to us. To avoid the pres context having a dangling reference, set its
@ -1410,8 +1394,8 @@ nsRefreshDriver* nsIPresShell::GetRefreshDriver() const {
}
void nsIPresShell::SetAuthorStyleDisabled(bool aStyleDisabled) {
if (aStyleDisabled != mStyleSet->GetAuthorStyleDisabled()) {
mStyleSet->SetAuthorStyleDisabled(aStyleDisabled);
if (aStyleDisabled != StyleSet()->GetAuthorStyleDisabled()) {
StyleSet()->SetAuthorStyleDisabled(aStyleDisabled);
ApplicableStylesChanged();
nsCOMPtr<nsIObserverService> observerService =
@ -1424,7 +1408,7 @@ void nsIPresShell::SetAuthorStyleDisabled(bool aStyleDisabled) {
}
bool nsIPresShell::GetAuthorStyleDisabled() const {
return mStyleSet->GetAuthorStyleDisabled();
return StyleSet()->GetAuthorStyleDisabled();
}
void nsIPresShell::UpdatePreferenceStyles() {
@ -1463,13 +1447,13 @@ void nsIPresShell::UpdatePreferenceStyles() {
// it to be modifiable from devtools and similar, see bugs 1239336 and
// 1436782. I think it conceptually should be a user sheet, and could be
// without too much trouble I'd think.
mStyleSet->AppendStyleSheet(SheetType::Agent, newPrefSheet);
StyleSet()->AppendStyleSheet(SheetType::Agent, newPrefSheet);
mPrefStyleSheet = newPrefSheet;
}
void nsIPresShell::RemovePreferenceStyles() {
if (mPrefStyleSheet) {
mStyleSet->RemoveStyleSheet(SheetType::Agent, mPrefStyleSheet);
StyleSet()->RemoveStyleSheet(SheetType::Agent, mPrefStyleSheet);
mPrefStyleSheet = nullptr;
}
}
@ -1496,14 +1480,14 @@ void nsIPresShell::AddUserSheet(StyleSheet* aSheet) {
// Assert that all of userSheets (except for the last, new element) matches up
// with what's in the style set.
for (size_t i = 0; i < index; ++i) {
MOZ_ASSERT(mStyleSet->StyleSheetAt(SheetType::User, i) == userSheets[i]);
MOZ_ASSERT(StyleSet()->StyleSheetAt(SheetType::User, i) == userSheets[i]);
}
if (index == static_cast<size_t>(mStyleSet->SheetCount(SheetType::User))) {
mStyleSet->AppendStyleSheet(SheetType::User, aSheet);
if (index == static_cast<size_t>(StyleSet()->SheetCount(SheetType::User))) {
StyleSet()->AppendStyleSheet(SheetType::User, aSheet);
} else {
StyleSheet* ref = mStyleSet->StyleSheetAt(SheetType::User, index);
mStyleSet->InsertStyleSheetBefore(SheetType::User, aSheet, ref);
StyleSheet* ref = StyleSet()->StyleSheetAt(SheetType::User, index);
StyleSet()->InsertStyleSheetBefore(SheetType::User, aSheet, ref);
}
ApplicableStylesChanged();
@ -1512,7 +1496,7 @@ void nsIPresShell::AddUserSheet(StyleSheet* aSheet) {
void nsIPresShell::AddAgentSheet(StyleSheet* aSheet) {
// Make sure this does what nsDocumentViewer::CreateStyleSet does
// wrt ordering.
mStyleSet->AppendStyleSheet(SheetType::Agent, aSheet);
StyleSet()->AppendStyleSheet(SheetType::Agent, aSheet);
ApplicableStylesChanged();
}
@ -1521,16 +1505,17 @@ void nsIPresShell::AddAuthorSheet(StyleSheet* aSheet) {
// ones added with the StyleSheetService.
StyleSheet* firstAuthorSheet = mDocument->GetFirstAdditionalAuthorSheet();
if (firstAuthorSheet) {
mStyleSet->InsertStyleSheetBefore(SheetType::Doc, aSheet, firstAuthorSheet);
StyleSet()->InsertStyleSheetBefore(SheetType::Doc, aSheet,
firstAuthorSheet);
} else {
mStyleSet->AppendStyleSheet(SheetType::Doc, aSheet);
StyleSet()->AppendStyleSheet(SheetType::Doc, aSheet);
}
ApplicableStylesChanged();
}
void nsIPresShell::RemoveSheet(SheetType aType, StyleSheet* aSheet) {
mStyleSet->RemoveStyleSheet(aType, aSheet);
StyleSet()->RemoveStyleSheet(aType, aSheet);
ApplicableStylesChanged();
}
@ -4089,7 +4074,7 @@ void PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush aFlush) {
if (MOZ_LIKELY(!mIsDestroying)) {
// Now that we have flushed media queries, update the rules before looking
// up @font-face / @counter-style / @font-feature-values rules.
mStyleSet->UpdateStylistIfNeeded();
StyleSet()->UpdateStylistIfNeeded();
// Flush any pending update of the user font set, since that could
// cause style changes (for updating ex/ch units, and to cause a
@ -4234,7 +4219,7 @@ void PresShell::DocumentStatesChanged(Document* aDocument,
MOZ_ASSERT(!aStateMask.IsEmpty());
if (mDidInitialize) {
mStyleSet->InvalidateStyleForDocumentStateChanges(aStateMask);
StyleSet()->InvalidateStyleForDocumentStateChanges(aStateMask);
}
if (aStateMask.HasState(NS_DOCUMENT_STATE_WINDOW_INACTIVE)) {
@ -5904,7 +5889,7 @@ class nsAutoNotifyDidPaint {
};
void nsIPresShell::RecordShadowStyleChange(ShadowRoot& aShadowRoot) {
mStyleSet->RecordShadowStyleChange(aShadowRoot);
StyleSet()->RecordShadowStyleChange(aShadowRoot);
ApplicableStylesChanged();
}
@ -8798,14 +8783,14 @@ bool PresShell::IsDisplayportSuppressed() {
nsresult PresShell::GetAgentStyleSheets(nsTArray<RefPtr<StyleSheet>>& aSheets) {
aSheets.Clear();
int32_t sheetCount = mStyleSet->SheetCount(SheetType::Agent);
int32_t sheetCount = StyleSet()->SheetCount(SheetType::Agent);
if (!aSheets.SetCapacity(sheetCount, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (int32_t i = 0; i < sheetCount; ++i) {
StyleSheet* sheet = mStyleSet->StyleSheetAt(SheetType::Agent, i);
StyleSheet* sheet = StyleSet()->StyleSheetAt(SheetType::Agent, i);
aSheets.AppendElement(sheet);
}
@ -8814,15 +8799,15 @@ nsresult PresShell::GetAgentStyleSheets(nsTArray<RefPtr<StyleSheet>>& aSheets) {
nsresult PresShell::SetAgentStyleSheets(
const nsTArray<RefPtr<StyleSheet>>& aSheets) {
return mStyleSet->ReplaceSheets(SheetType::Agent, aSheets);
return StyleSet()->ReplaceSheets(SheetType::Agent, aSheets);
}
nsresult PresShell::AddOverrideStyleSheet(StyleSheet* aSheet) {
return mStyleSet->AppendStyleSheet(SheetType::Override, aSheet);
return StyleSet()->AppendStyleSheet(SheetType::Override, aSheet);
}
nsresult PresShell::RemoveOverrideStyleSheet(StyleSheet* aSheet) {
return mStyleSet->RemoveStyleSheet(SheetType::Override, aSheet);
return StyleSet()->RemoveStyleSheet(SheetType::Override, aSheet);
}
static void FreezeElement(nsISupports* aSupports, void* /* unused */) {
@ -9835,42 +9820,6 @@ FindTopFrame(nsIFrame* aRoot)
#ifdef DEBUG
static void CopySheetsIntoClone(ServoStyleSet* aSet, ServoStyleSet* aClone) {
int32_t i, n = aSet->SheetCount(SheetType::Override);
for (i = 0; i < n; i++) {
StyleSheet* ss = aSet->StyleSheetAt(SheetType::Override, i);
if (ss) aClone->AppendStyleSheet(SheetType::Override, ss);
}
// The document expects to insert document stylesheets itself
# if 0
n = aSet->SheetCount(SheetType::Doc);
for (i = 0; i < n; i++) {
StyleSheet* ss = aSet->StyleSheetAt(SheetType::Doc, i);
if (ss)
aClone->AddDocStyleSheet(ss, mDocument);
}
# endif
n = aSet->SheetCount(SheetType::User);
for (i = 0; i < n; i++) {
StyleSheet* ss = aSet->StyleSheetAt(SheetType::User, i);
if (ss) aClone->AppendStyleSheet(SheetType::User, ss);
}
n = aSet->SheetCount(SheetType::Agent);
for (i = 0; i < n; i++) {
StyleSheet* ss = aSet->StyleSheetAt(SheetType::Agent, i);
if (ss) aClone->AppendStyleSheet(SheetType::Agent, ss);
}
}
UniquePtr<ServoStyleSet> nsIPresShell::CloneStyleSet(ServoStyleSet* aSet) {
auto clone = MakeUnique<ServoStyleSet>();
CopySheetsIntoClone(aSet, clone.get());
return clone;
}
// After an incremental reflow, we verify the correctness by doing a
// full reflow into a fresh frame tree.
bool nsIPresShell::VerifyIncrementalReflow() {
@ -9917,13 +9866,9 @@ bool nsIPresShell::VerifyIncrementalReflow() {
// presentation context.
cx->SetVisibleArea(mPresContext->GetVisibleArea());
// Create a new presentation shell to view the document. Use the
// exact same style information that this document has.
UniquePtr<ServoStyleSet> newSet = CloneStyleSet(StyleSet());
RefPtr<PresShell> presShell =
mDocument->CreatePresShell(cx, vm, std::move(newSet));
RefPtr<PresShell> presShell = mDocument->CreatePresShell(cx, vm);
NS_ENSURE_TRUE(presShell, false);
// Note that after we create the shell, we must make sure to destroy it
presShell->SetVerifyReflowEnable(
false); // turn off verify reflow while we're
@ -10003,9 +9948,9 @@ void PresShell::ListComputedStyles(FILE* out, int32_t aIndent) {
}
void PresShell::ListStyleSheets(FILE* out, int32_t aIndent) {
int32_t sheetCount = mStyleSet->SheetCount(SheetType::Doc);
int32_t sheetCount = StyleSet()->SheetCount(SheetType::Doc);
for (int32_t i = 0; i < sheetCount; ++i) {
mStyleSet->StyleSheetAt(SheetType::Doc, i)->List(out, aIndent);
StyleSet()->StyleSheetAt(SheetType::Doc, i)->List(out, aIndent);
fputs("\n", out);
}
}
@ -10909,10 +10854,6 @@ nsresult nsIPresShell::HasRuleProcessorUsedByMultipleStyleSets(
void nsIPresShell::NotifyStyleSheetServiceSheetAdded(StyleSheet* aSheet,
uint32_t aSheetType) {
if (!mStyleSet) {
return;
}
switch (aSheetType) {
case nsIStyleSheetService::AGENT_SHEET:
AddAgentSheet(aSheet);
@ -10931,10 +10872,6 @@ void nsIPresShell::NotifyStyleSheetServiceSheetAdded(StyleSheet* aSheet,
void nsIPresShell::NotifyStyleSheetServiceSheetRemoved(StyleSheet* aSheet,
uint32_t aSheetType) {
if (!mStyleSet) {
return;
}
RemoveSheet(ToSheetType(aSheetType), aSheet);
}

View File

@ -64,6 +64,7 @@ class PresShell final : public nsIPresShell,
public nsIObserver,
public nsSupportsWeakReference {
typedef layers::FocusTarget FocusTarget;
typedef dom::Element Element;
public:
PresShell();
@ -73,8 +74,7 @@ class PresShell final : public nsIPresShell,
static bool AccessibleCaretEnabled(nsIDocShell* aDocShell);
void Init(Document* aDocument, nsPresContext* aPresContext,
nsViewManager* aViewManager, UniquePtr<ServoStyleSet> aStyleSet);
void Init(Document*, nsPresContext*, nsViewManager*);
void Destroy() override;
NS_IMETHOD GetSelectionFromScript(RawSelectionType aRawSelectionType,

View File

@ -726,12 +726,8 @@ nsresult nsDocumentViewer::InitPresentationStuff(bool aDoInitialReflow) {
NS_ASSERTION(!mPresShell, "Someone should have destroyed the presshell!");
// Create the style set...
UniquePtr<ServoStyleSet> styleSet = CreateStyleSet(mDocument);
// Now make the shell for the document
mPresShell = mDocument->CreatePresShell(mPresContext, mViewManager,
std::move(styleSet));
mPresShell = mDocument->CreatePresShell(mPresContext, mViewManager);
if (!mPresShell) {
return NS_ERROR_FAILURE;
}
@ -2291,81 +2287,6 @@ nsDocumentViewer::RequestWindowClose(bool* aCanClose) {
return NS_OK;
}
UniquePtr<ServoStyleSet> nsDocumentViewer::CreateStyleSet(Document* aDocument) {
// Make sure this does the same thing as PresShell::Add{User,Agent}Sheet wrt
// ordering.
// The document will fill in the document sheets when we create the presshell
auto cache = nsLayoutStylesheetCache::Singleton();
nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
MOZ_ASSERT(sheetService,
"should never be creating a StyleSet after the style sheet "
"service has gone");
auto styleSet = MakeUnique<ServoStyleSet>();
// User sheets
for (StyleSheet* sheet : *sheetService->UserStyleSheets()) {
styleSet->AppendStyleSheet(SheetType::User, sheet);
}
StyleSheet* sheet = nsContentUtils::IsInChromeDocshell(aDocument)
? cache->GetUserChromeSheet()
: cache->GetUserContentSheet();
if (sheet) {
styleSet->AppendStyleSheet(SheetType::User, sheet);
}
// Agent sheets
styleSet->AppendStyleSheet(SheetType::Agent, cache->UASheet());
if (MOZ_LIKELY(mDocument->NodeInfoManager()->MathMLEnabled())) {
styleSet->AppendStyleSheet(SheetType::Agent, cache->MathMLSheet());
}
if (MOZ_LIKELY(mDocument->NodeInfoManager()->SVGEnabled())) {
styleSet->AppendStyleSheet(SheetType::Agent, cache->SVGSheet());
}
styleSet->AppendStyleSheet(SheetType::Agent, cache->HTMLSheet());
// We don't add quirk.css here; nsPresContext::CompatibilityModeChanged will
// append it if needed.
if (nsLayoutUtils::ShouldUseNoFramesSheet(aDocument)) {
styleSet->AppendStyleSheet(SheetType::Agent, cache->NoFramesSheet());
}
if (nsLayoutUtils::ShouldUseNoScriptSheet(aDocument)) {
styleSet->AppendStyleSheet(SheetType::Agent, cache->NoScriptSheet());
}
styleSet->AppendStyleSheet(SheetType::Agent, cache->CounterStylesSheet());
// Load the minimal XUL rules for scrollbars and a few other XUL things
// that non-XUL (typically HTML) documents commonly use.
styleSet->AppendStyleSheet(SheetType::Agent, cache->MinimalXULSheet());
// Only load the full XUL sheet if we'll need it.
if (aDocument->LoadsFullXULStyleSheetUpFront()) {
styleSet->AppendStyleSheet(SheetType::Agent, cache->XULSheet());
}
styleSet->AppendStyleSheet(SheetType::Agent, cache->FormsSheet());
styleSet->AppendStyleSheet(SheetType::Agent, cache->ScrollbarsSheet());
styleSet->AppendStyleSheet(SheetType::Agent, cache->PluginProblemSheet());
for (StyleSheet* sheet : *sheetService->AgentStyleSheets()) {
styleSet->AppendStyleSheet(SheetType::Agent, sheet);
}
return styleSet;
}
NS_IMETHODIMP
nsDocumentViewer::ClearHistoryEntry() {
if (mDocument) {

View File

@ -39,12 +39,6 @@ class nsIDocumentViewerPrint : public nsISupports {
virtual void SetIsPrintPreview(bool aIsPrintPreview) = 0;
virtual bool GetIsPrintPreview() = 0;
// The style set returned by CreateStyleSet is in the middle of an
// update batch so that the caller can add sheets to it if needed.
// Callers should call EndUpdate() on it when ready to use.
virtual mozilla::UniquePtr<mozilla::ServoStyleSet> CreateStyleSet(
mozilla::dom::Document* aDocument) = 0;
/**
* This is used by nsPagePrintTimer to make nsDocumentViewer::Destroy()
* a no-op until printing is finished. That prevents the nsDocumentViewer
@ -82,8 +76,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentViewerPrint,
bool GetIsPrinting() override; \
void SetIsPrintPreview(bool aIsPrintPreview) override; \
bool GetIsPrintPreview() override; \
mozilla::UniquePtr<mozilla::ServoStyleSet> CreateStyleSet( \
mozilla::dom::Document* aDocument) override; \
void IncrementDestroyBlockedCount() override; \
void DecrementDestroyBlockedCount() override; \
void OnDonePrinting() override; \

View File

@ -272,7 +272,7 @@ class nsIPresShell : public nsStubDocumentObserver {
}
#endif
mozilla::ServoStyleSet* StyleSet() const { return mStyleSet.get(); }
inline mozilla::ServoStyleSet* StyleSet() const;
nsCSSFrameConstructor* FrameConstructor() const {
return mFrameConstructor.get();
@ -1778,8 +1778,6 @@ class nsIPresShell : public nsStubDocumentObserver {
FrameMetrics::ScrollOffsetUpdateType aUpdateType);
#ifdef DEBUG
mozilla::UniquePtr<mozilla::ServoStyleSet> CloneStyleSet(
mozilla::ServoStyleSet*);
bool VerifyIncrementalReflow();
void DoVerifyReflow();
void VerifyHasDirtyRootAncestor(nsIFrame* aFrame);
@ -1857,9 +1855,8 @@ class nsIPresShell : public nsStubDocumentObserver {
// we must share ownership.
RefPtr<Document> mDocument;
RefPtr<nsPresContext> mPresContext;
// mStyleSet owns it but we maintain a ref, may be null
// The document's style set owns it but we maintain a ref, may be null.
RefPtr<mozilla::StyleSheet> mPrefStyleSheet;
mozilla::UniquePtr<mozilla::ServoStyleSet> mStyleSet;
mozilla::UniquePtr<nsCSSFrameConstructor> mFrameConstructor;
nsViewManager* mViewManager; // [WEAK] docViewer owns it so I don't have to
nsPresArena<8192> mFrameArena;

View File

@ -9,6 +9,7 @@
#include "mozilla/PresShell.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Element.h"
void nsIPresShell::SetNeedLayoutFlush() {
mNeedLayoutFlush = true;
@ -54,6 +55,10 @@ void nsIPresShell::SetNeedThrottledAnimationFlush() {
}
}
mozilla::ServoStyleSet* nsIPresShell::StyleSet() const {
return mDocument->StyleSetForPresShellOrMediaQueryEvaluation();
}
namespace mozilla {
/* static */

View File

@ -847,44 +847,6 @@ nsRootPresContext* nsPresContext::GetRootPresContext() {
return pc->IsRoot() ? static_cast<nsRootPresContext*>(pc) : nullptr;
}
void nsPresContext::CompatibilityModeChanged() {
if (!mShell) {
return;
}
ServoStyleSet* styleSet = mShell->StyleSet();
styleSet->CompatibilityModeChanged();
mShell->EnsureStyleFlush();
if (mDocument->IsSVGDocument()) {
// SVG documents never load quirk.css.
return;
}
bool needsQuirkSheet = CompatibilityMode() == eCompatibility_NavQuirks;
if (mQuirkSheetAdded == needsQuirkSheet) {
return;
}
auto cache = nsLayoutStylesheetCache::Singleton();
StyleSheet* sheet = cache->QuirkSheet();
if (needsQuirkSheet) {
// quirk.css needs to come after html.css; we just keep it at the end.
DebugOnly<nsresult> rv =
styleSet->AppendStyleSheet(SheetType::Agent, sheet);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "failed to insert quirk.css");
} else {
DebugOnly<nsresult> rv =
styleSet->RemoveStyleSheet(SheetType::Agent, sheet);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "failed to remove quirk.css");
}
mQuirkSheetAdded = needsQuirkSheet;
mShell->ApplicableStylesChanged();
}
// Helper function for setting Anim Mode on image
static void SetImgAnimModeOnImgReq(imgIRequest* aImgReq, uint16_t aMode) {
if (aImgReq) {

View File

@ -294,11 +294,6 @@ class nsPresContext : public nsISupports,
*/
nsCompatibility CompatibilityMode() const;
/**
* Notify the context that the document's compatibility mode has changed
*/
void CompatibilityModeChanged();
/**
* Access the image animation mode for this context
*/

View File

@ -4,18 +4,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsIPresContextInlines_h
#define nsIPresContextInlines_h
#ifndef nsPresContextInlines_h
#define nsPresContextInlines_h
#include "mozilla/PresShell.h"
#include "nsCSSFrameConstructor.h"
inline mozilla::ServoStyleSet* nsPresContext::StyleSet() const {
return GetPresShell()->StyleSet();
return mDocument->StyleSetForPresShellOrMediaQueryEvaluation();
}
inline nsCSSFrameConstructor* nsPresContext::FrameConstructor() {
return PresShell()->FrameConstructor();
}
#endif // #ifndef nsIPresContextInlines_h
#endif // #ifndef nsPresContextInlines_h

View File

@ -24,6 +24,7 @@
#include "nsNetUtil.h"
#include "nsIConsoleService.h"
#include "nsIObserverService.h"
#include "nsIPresShellInlines.h"
#include "nsLayoutStatics.h"
#include "nsLayoutUtils.h"

View File

@ -18,6 +18,7 @@
#include "nsIContentInlines.h"
#include "mozilla/dom/Document.h"
#include "nsIDOMWindow.h"
#include "nsIPresShellInlines.h"
#include "nsXBLBinding.h"
#include "nsXBLPrototypeBinding.h"
#include "nsIMutableArray.h"

View File

@ -2235,11 +2235,8 @@ nsresult nsPrintJob::ReflowPrintObject(const UniquePtr<nsPrintObject>& aPO) {
rv = aPO->mViewManager->Init(printData->mPrintDC);
NS_ENSURE_SUCCESS(rv, rv);
UniquePtr<ServoStyleSet> styleSet =
mDocViewerPrint->CreateStyleSet(aPO->mDocument);
aPO->mPresShell = aPO->mDocument->CreatePresShell(
aPO->mPresContext, aPO->mViewManager, std::move(styleSet));
aPO->mPresShell =
aPO->mDocument->CreatePresShell(aPO->mPresContext, aPO->mViewManager);
if (!aPO->mPresShell) {
return NS_ERROR_FAILURE;
}

View File

@ -369,8 +369,9 @@ Loader::Loader()
Loader::Loader(DocGroup* aDocGroup) : Loader() { mDocGroup = aDocGroup; }
Loader::Loader(Document* aDocument) : Loader() {
MOZ_ASSERT(aDocument, "We should get a valid document from the caller!");
mDocument = aDocument;
MOZ_ASSERT(mDocument, "We should get a valid document from the caller!");
mCompatMode = aDocument->GetCompatibilityMode();
}
Loader::~Loader() {

View File

@ -44,6 +44,8 @@ enum class MediaFeatureChangeReason {
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(MediaFeatureChangeReason)
struct MediaFeatureChange {
static const auto kAllChanges = static_cast<MediaFeatureChangeReason>(~0);
RestyleHint mRestyleHint;
nsChangeHint mChangeHint;
MediaFeatureChangeReason mReason;

View File

@ -92,12 +92,15 @@ class MOZ_RAII AutoPrepareTraversal {
} // namespace mozilla
ServoStyleSet::ServoStyleSet()
: mDocument(nullptr),
ServoStyleSet::ServoStyleSet(Document& aDocument)
: mDocument(&aDocument),
mAuthorStyleDisabled(false),
mStylistState(StylistState::NotDirty),
mUserFontSetUpdateGeneration(0),
mNeedsRestyleAfterEnsureUniqueInner(false) {}
mNeedsRestyleAfterEnsureUniqueInner(false) {
PreferenceSheet::EnsureInitialized();
mRawSet.reset(Servo_StyleSet_Init(&aDocument));
}
ServoStyleSet::~ServoStyleSet() {
for (auto& sheetArray : mSheets) {
@ -108,41 +111,10 @@ ServoStyleSet::~ServoStyleSet() {
}
nsPresContext* ServoStyleSet::GetPresContext() {
if (!mDocument) {
return nullptr;
}
return mDocument->GetPresContext();
}
void ServoStyleSet::Init(nsPresContext* aPresContext) {
mDocument = aPresContext->Document();
MOZ_ASSERT(GetPresContext() == aPresContext);
mRawSet.reset(Servo_StyleSet_Init(aPresContext));
aPresContext->DeviceContext()->InitFontCache();
// Now that we have an mRawSet, go ahead and notify about whatever stylesheets
// we have so far.
for (auto& sheetArray : mSheets) {
for (auto& sheet : sheetArray) {
// There's no guarantee this will create a list on the servo side whose
// ordering matches the list that would have been created had all those
// sheets been appended/prepended/etc after we had mRawSet. That's okay
// because Servo only needs to maintain relative ordering within a sheet
// type, which this preserves.
MOZ_ASSERT(sheet->RawContents(),
"We should only append non-null raw sheets.");
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), sheet);
}
}
// We added prefilled stylesheets into mRawSet, so the stylist is dirty.
// The Stylist should be updated later when necessary.
SetStylistStyleSheetsDirty();
void ServoStyleSet::ShellAttachedToDocument() {
// We may have Shadow DOM style changes that we weren't notified about because
// the document didn't have a shell, if the ShadowRoot was created in a
// display: none iframe.
@ -165,11 +137,10 @@ void EnumerateShadowRoots(const Document& aDoc, const Functor& aCb) {
}
}
void ServoStyleSet::Shutdown() {
void ServoStyleSet::ShellDetachedFromDocument() {
// Make sure we drop our cached styles before the presshell arena starts going
// away.
ClearNonInheritingComputedStyles();
mRawSet = nullptr;
mStyleRuleMap = nullptr;
}
@ -630,13 +601,11 @@ nsresult ServoStyleSet::AppendStyleSheet(SheetType aType, StyleSheet* aSheet) {
RemoveSheetOfType(aType, aSheet);
AppendSheetOfType(aType, aSheet);
if (mRawSet) {
// Maintain a mirrored list of sheets on the servo side.
// Servo will remove aSheet from its original position as part of the call
// to Servo_StyleSet_AppendStyleSheet.
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), aSheet);
SetStylistStyleSheetsDirty();
}
// Maintain a mirrored list of sheets on the servo side.
// Servo will remove aSheet from its original position as part of the call
// to Servo_StyleSet_AppendStyleSheet.
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), aSheet);
SetStylistStyleSheetsDirty();
if (mStyleRuleMap) {
mStyleRuleMap->SheetAdded(*aSheet);
@ -650,11 +619,10 @@ nsresult ServoStyleSet::RemoveStyleSheet(SheetType aType, StyleSheet* aSheet) {
MOZ_ASSERT(IsCSSSheetType(aType));
RemoveSheetOfType(aType, aSheet);
if (mRawSet) {
// Maintain a mirrored list of sheets on the servo side.
Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), aSheet);
SetStylistStyleSheetsDirty();
}
// Maintain a mirrored list of sheets on the servo side.
Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), aSheet);
SetStylistStyleSheetsDirty();
if (mStyleRuleMap) {
mStyleRuleMap->SheetRemoved(*aSheet);
@ -675,20 +643,16 @@ nsresult ServoStyleSet::ReplaceSheets(
// Remove all the existing sheets first.
for (const auto& sheet : mSheets[aType]) {
sheet->DropStyleSet(this);
if (mRawSet) {
Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), sheet);
}
Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), sheet);
}
mSheets[aType].Clear();
// Add in all the new sheets.
for (auto& sheet : aNewSheets) {
AppendSheetOfType(aType, sheet);
if (mRawSet) {
MOZ_ASSERT(sheet->RawContents(),
"Raw sheet should be in place before replacement.");
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), sheet);
}
MOZ_ASSERT(sheet->RawContents(),
"Raw sheet should be in place before replacement.");
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), sheet);
}
// Just don't bother calling SheetRemoved / SheetAdded, and recreate the rule
@ -714,12 +678,10 @@ nsresult ServoStyleSet::InsertStyleSheetBefore(SheetType aType,
RemoveSheetOfType(aType, aNewSheet);
InsertSheetOfType(aType, aNewSheet, aReferenceSheet);
if (mRawSet) {
// Maintain a mirrored list of sheets on the servo side.
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), aNewSheet,
aReferenceSheet);
SetStylistStyleSheetsDirty();
}
// Maintain a mirrored list of sheets on the servo side.
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), aNewSheet,
aReferenceSheet);
SetStylistStyleSheetsDirty();
if (mStyleRuleMap) {
mStyleRuleMap->SheetAdded(*aNewSheet);
@ -772,20 +734,16 @@ nsresult ServoStyleSet::AddDocStyleSheet(StyleSheet* aSheet,
StyleSheet* beforeSheet = mSheets[SheetType::Doc][index];
InsertSheetOfType(SheetType::Doc, aSheet, beforeSheet);
if (mRawSet) {
// Maintain a mirrored list of sheets on the servo side.
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), aSheet, beforeSheet);
SetStylistStyleSheetsDirty();
}
// Maintain a mirrored list of sheets on the servo side.
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), aSheet, beforeSheet);
SetStylistStyleSheetsDirty();
} else {
// This case is append.
AppendSheetOfType(SheetType::Doc, aSheet);
if (mRawSet) {
// Maintain a mirrored list of sheets on the servo side.
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), aSheet);
SetStylistStyleSheetsDirty();
}
// Maintain a mirrored list of sheets on the servo side.
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), aSheet);
SetStylistStyleSheetsDirty();
}
if (mStyleRuleMap) {
@ -970,10 +928,6 @@ void ServoStyleSet::StyleNewSubtree(Element* aRoot) {
}
void ServoStyleSet::MarkOriginsDirty(OriginFlags aChangedOrigins) {
if (MOZ_UNLIKELY(!mRawSet)) {
return;
}
SetStylistStyleSheetsDirty();
Servo_StyleSet_NoteStyleSheetsChanged(mRawSet.get(), aChangedOrigins);
}

View File

@ -95,12 +95,11 @@ class ServoStyleSet {
static ServoStyleSet* Current() { return sInServoTraversal; }
ServoStyleSet();
explicit ServoStyleSet(dom::Document&);
~ServoStyleSet();
void Init(nsPresContext* aPresContext);
void BeginShutdown() {}
void Shutdown();
void ShellAttachedToDocument();
void ShellDetachedFromDocument();
// Called when a rules in a stylesheet in this set, or a child sheet of that,
// are mutated from CSSOM.
@ -505,10 +504,8 @@ class ServoStyleSet {
void RemoveSheetOfType(SheetType aType, StyleSheet* aSheet);
// The owner document of this style set. Null if this is an XBL style set.
//
// TODO(emilio): This should become a DocumentOrShadowRoot, and be owned by it
// directly instead of the shell, eventually.
// The owner document of this style set. Never null, and always outlives the
// StyleSet.
dom::Document* mDocument;
const nsPresContext* GetPresContext() const {

View File

@ -3517,14 +3517,8 @@ pub extern "C" fn Servo_ComputedValues_GetStyleRuleList(
}))
}
/// See the comment in `Device` to see why it's ok to pass an owned reference to
/// the pres context (hint: the context outlives the StyleSet, that holds the
/// device alive).
#[no_mangle]
pub extern "C" fn Servo_StyleSet_Init(
pres_context: &structs::nsPresContext,
) -> *mut RawServoStyleSet {
let doc = pres_context.mDocument.mRawPtr;
pub extern "C" fn Servo_StyleSet_Init(doc: &structs::Document) -> *mut RawServoStyleSet {
let data = Box::new(PerDocumentStyleData::new(doc));
Box::into_raw(data) as *mut RawServoStyleSet
}