Bug 1169512 - Add and remove quirk.css rather than enable and disable a clone of it. r=jwatt

This commit is contained in:
Cameron McCormack 2015-06-26 13:49:58 +10:00
parent e08c9983e4
commit 47cfbf336f
6 changed files with 38 additions and 77 deletions

View File

@ -2298,22 +2298,6 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument,
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
}
// Make sure to clone the quirk sheet so that it can be usefully
// enabled/disabled as needed.
nsRefPtr<CSSStyleSheet> quirkClone;
CSSStyleSheet* quirkSheet;
if (!nsLayoutStylesheetCache::UASheet() ||
!(quirkSheet = nsLayoutStylesheetCache::QuirkSheet()) ||
!(quirkClone = quirkSheet->Clone(nullptr, nullptr, nullptr, nullptr)) ||
!sheet) {
delete styleSet;
return NS_ERROR_OUT_OF_MEMORY;
}
// quirk.css needs to come after the regular UA sheet (or more precisely,
// after the html.css and so forth that the UA sheet imports).
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, quirkClone);
styleSet->SetQuirkStyleSheet(quirkClone);
if (aDocument->LoadsFullXULStyleSheetUpFront()) {
// nsXULElement::BindToTree loads xul.css on-demand if we don't load it
// up-front here.
@ -2349,6 +2333,9 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument,
}
}
// We don't add quirk.css here; nsPresContext::CompatibilityModeChanged will
// append it if needed.
sheet = nsLayoutStylesheetCache::HTMLSheet();
if (sheet) {
styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);

View File

@ -1354,12 +1354,40 @@ nsPresContext::GetDisplayRootPresContext()
void
nsPresContext::CompatibilityModeChanged()
{
if (!mShell)
if (!mShell) {
return;
}
// enable/disable the QuirkSheet
mShell->StyleSet()->
EnableQuirkStyleSheet(CompatibilityMode() == eCompatibility_NavQuirks);
nsIDocument* doc = mShell->GetDocument();
if (!doc) {
return;
}
if (doc->IsSVGDocument()) {
// SVG documents never load quirk.css.
return;
}
bool needsQuirkSheet = CompatibilityMode() == eCompatibility_NavQuirks;
if (mQuirkSheetAdded == needsQuirkSheet) {
return;
}
nsStyleSet* styleSet = mShell->StyleSet();
CSSStyleSheet* sheet = nsLayoutStylesheetCache::QuirkSheet();
if (needsQuirkSheet) {
// quirk.css needs to come after html.css; we just keep it at the end.
DebugOnly<nsresult> rv =
styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "failed to insert quirk.css");
} else {
DebugOnly<nsresult> rv =
styleSet->RemoveStyleSheet(nsStyleSet::eAgentSheet, sheet);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "failed to remove quirk.css");
}
mQuirkSheetAdded = needsQuirkSheet;
}
// Helper function for setting Anim Mode on image

View File

@ -1399,6 +1399,9 @@ protected:
unsigned mHasWarnedAboutPositionedTableParts : 1;
// Have we added quirk.css to the style set?
unsigned mQuirkSheetAdded : 1;
#ifdef RESTYLE_LOGGING
// Should we output debug information about restyling for this document?
bool mRestyleLoggingEnabled;

View File

@ -161,13 +161,6 @@ public:
*/
mozilla::dom::Element* GetScopeElement() const { return mScopeElement; }
#ifdef DEBUG
void AssertQuirksChangeOK() {
NS_ASSERTION(!mRuleCascades, "can't toggle quirks style sheet without "
"clearing rule cascades");
}
#endif
#ifdef XP_WIN
// Cached theme identifier for the moz-windows-theme media query.
static uint8_t GetWindowsThemeIdentifier();

View File

@ -260,16 +260,6 @@ nsStyleSet::EndReconstruct()
GCRuleTrees();
}
void
nsStyleSet::SetQuirkStyleSheet(nsIStyleSheet* aQuirkStyleSheet)
{
NS_ASSERTION(aQuirkStyleSheet, "Must have quirk sheet if this is called");
NS_ASSERTION(!mQuirkStyleSheet, "Multiple calls to SetQuirkStyleSheet?");
NS_ASSERTION(mSheets[eAgentSheet].IndexOf(aQuirkStyleSheet) != -1,
"Quirk style sheet not one of our agent sheets?");
mQuirkStyleSheet = aQuirkStyleSheet;
}
typedef nsDataHashtable<nsPtrHashKey<nsINode>, uint32_t> ScopeDepthCache;
// Returns the depth of a style scope element, with 1 being the depth of
@ -680,35 +670,6 @@ nsStyleSet::EndUpdate()
return NS_OK;
}
void
nsStyleSet::EnableQuirkStyleSheet(bool aEnable)
{
if (!mQuirkStyleSheet) {
// SVG-as-an-image doesn't load this sheet
return;
}
#ifdef DEBUG
bool oldEnabled;
{
nsCOMPtr<nsIDOMCSSStyleSheet> domSheet =
do_QueryInterface(mQuirkStyleSheet);
domSheet->GetDisabled(&oldEnabled);
oldEnabled = !oldEnabled;
}
#endif
mQuirkStyleSheet->SetEnabled(aEnable);
#ifdef DEBUG
// This should always be OK, since SetEnabled should call
// ClearRuleCascades.
// Note that we can hit this codepath multiple times when document.open()
// (potentially implied) happens multiple times.
if (mRuleProcessors[eAgentSheet] && aEnable != oldEnabled) {
static_cast<nsCSSRuleProcessor*>(static_cast<nsIStyleRuleProcessor*>(
mRuleProcessors[eAgentSheet]))->AssertQuirksChangeOK();
}
#endif
}
template<class T>
static bool
EnumRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData)

View File

@ -94,9 +94,6 @@ class nsStyleSet
nsRuleNode* GetRuleTree() { return mRuleTree; }
// enable / disable the Quirk style sheet
void EnableQuirkStyleSheet(bool aEnable);
// get a style context for a non-pseudo frame.
already_AddRefed<nsStyleContext>
ResolveStyleFor(mozilla::dom::Element* aElement,
@ -363,11 +360,6 @@ class nsStyleSet
return mInReconstruct;
}
// Let the style set know that a particular sheet is the quirks sheet. This
// sheet must already have been added to the UA sheets. The pointer must not
// be null. This should only be called once for a given style set.
void SetQuirkStyleSheet(nsIStyleSheet* aQuirkStyleSheet);
// Return whether the rule tree has cached data such that we need to
// do dynamic change handling for changes that change the results of
// media queries or require rebuilding all style data.
@ -478,9 +470,6 @@ class nsStyleSet
// Rule processors for HTML5 scoped style sheets, one per scope.
nsTArray<nsCOMPtr<nsIStyleRuleProcessor> > mScopedDocSheetRuleProcessors;
// cached instance for enabling/disabling
nsCOMPtr<nsIStyleSheet> mQuirkStyleSheet;
nsRefPtr<nsBindingManager> mBindingManager;
nsRuleNode* mRuleTree; // This is the root of our rule tree. It is a