зеркало из https://github.com/mozilla/gecko-dev.git
Bug 508725 - Part 7: Optimize restyling when a scoped style sheet changes. r=dbaron
This commit is contained in:
Родитель
f83b36df21
Коммит
0cdf2690f0
|
@ -1424,6 +1424,9 @@ protected:
|
|||
// re-use old pixels.
|
||||
RenderFlags mRenderFlags;
|
||||
|
||||
// Indicates that the whole document must be restyled. Changes to scoped
|
||||
// style sheets are recorded in mChangedScopeStyleRoots rather than here
|
||||
// in mStylesHaveChanged.
|
||||
bool mStylesHaveChanged : 1;
|
||||
bool mDidInitialize : 1;
|
||||
bool mIsDestroying : 1;
|
||||
|
@ -1447,6 +1450,15 @@ protected:
|
|||
bool mSuppressInterruptibleReflows : 1;
|
||||
bool mScrollPositionClampingScrollPortSizeSet : 1;
|
||||
|
||||
// List of subtrees rooted at style scope roots that need to be restyled.
|
||||
// When a change to a scoped style sheet is made, we add the style scope
|
||||
// root to this array rather than setting mStylesHaveChanged = true, since
|
||||
// we know we don't need to restyle the whole document. However, if in the
|
||||
// same update block we have already had other changes that require
|
||||
// the whole document to be restyled (i.e., mStylesHaveChanged is already
|
||||
// true), then we don't bother adding the scope root here.
|
||||
nsAutoTArray<nsRefPtr<mozilla::dom::Element>,1> mChangedScopeStyleRoots;
|
||||
|
||||
static nsIContent* gKeyDownTarget;
|
||||
|
||||
// Cached font inflation values. This is done to prevent changing of font
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMXULDocument.h"
|
||||
#include "nsCSSStyleSheet.h" // XXX for UA sheet loading hack, can this go away please?
|
||||
#include "nsCSSStyleSheet.h"
|
||||
#include "nsIDOMCSSStyleSheet.h" // for Pref-related rule management (bugs 22963,20760,31816)
|
||||
#include "nsAnimationManager.h"
|
||||
#include "nsINameSpaceManager.h" // for Pref-related rule management (bugs 22963,20760,31816)
|
||||
|
@ -2419,7 +2419,7 @@ PresShell::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
|
|||
|
||||
if (aUpdateType & UPDATE_STYLE) {
|
||||
mStyleSet->EndUpdate();
|
||||
if (mStylesHaveChanged)
|
||||
if (mStylesHaveChanged || !mChangedScopeStyleRoots.IsEmpty())
|
||||
ReconstructStyleData();
|
||||
}
|
||||
|
||||
|
@ -4170,6 +4170,15 @@ PresShell::ReconstructFrames(void)
|
|||
void
|
||||
nsIPresShell::ReconstructStyleDataInternal()
|
||||
{
|
||||
nsAutoTArray<nsRefPtr<mozilla::dom::Element>,1> scopeRoots;
|
||||
mChangedScopeStyleRoots.SwapElements(scopeRoots);
|
||||
|
||||
if (mStylesHaveChanged) {
|
||||
// If we need to restyle everything, no need to restyle individual
|
||||
// scoped style roots.
|
||||
scopeRoots.Clear();
|
||||
}
|
||||
|
||||
mStylesHaveChanged = false;
|
||||
|
||||
if (mIsDestroying) {
|
||||
|
@ -4193,7 +4202,19 @@ nsIPresShell::ReconstructStyleDataInternal()
|
|||
return;
|
||||
}
|
||||
|
||||
mFrameConstructor->PostRestyleEvent(root, eRestyle_Subtree, NS_STYLE_HINT_NONE);
|
||||
if (scopeRoots.IsEmpty()) {
|
||||
// If scopeRoots is empty, we know that mStylesHaveChanged was true at
|
||||
// the beginning of this function, and that we need to restyle the whole
|
||||
// document.
|
||||
mFrameConstructor->PostRestyleEvent(root, eRestyle_Subtree,
|
||||
NS_STYLE_HINT_NONE);
|
||||
} else {
|
||||
for (uint32_t i = 0; i < scopeRoots.Length(); i++) {
|
||||
Element* scopeRoot = scopeRoots[i];
|
||||
mFrameConstructor->PostRestyleEvent(scopeRoot, eRestyle_Subtree,
|
||||
NS_STYLE_HINT_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4202,6 +4223,24 @@ nsIPresShell::ReconstructStyleDataExternal()
|
|||
ReconstructStyleDataInternal();
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::RecordStyleSheetChange(nsIStyleSheet* aStyleSheet)
|
||||
{
|
||||
if (mStylesHaveChanged)
|
||||
return;
|
||||
|
||||
nsRefPtr<nsCSSStyleSheet> cssStyleSheet = do_QueryObject(aStyleSheet);
|
||||
if (cssStyleSheet) {
|
||||
Element* scopeElement = cssStyleSheet->GetScopeElement();
|
||||
if (scopeElement) {
|
||||
mChangedScopeStyleRoots.AppendElement(scopeElement);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mStylesHaveChanged = true;
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::StyleSheetAdded(nsIDocument *aDocument,
|
||||
nsIStyleSheet* aStyleSheet,
|
||||
|
@ -4211,7 +4250,7 @@ PresShell::StyleSheetAdded(nsIDocument *aDocument,
|
|||
NS_PRECONDITION(aStyleSheet, "Must have a style sheet!");
|
||||
|
||||
if (aStyleSheet->IsApplicable() && aStyleSheet->HasRules()) {
|
||||
mStylesHaveChanged = true;
|
||||
RecordStyleSheetChange(aStyleSheet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4224,7 +4263,7 @@ PresShell::StyleSheetRemoved(nsIDocument *aDocument,
|
|||
NS_PRECONDITION(aStyleSheet, "Must have a style sheet!");
|
||||
|
||||
if (aStyleSheet->IsApplicable() && aStyleSheet->HasRules()) {
|
||||
mStylesHaveChanged = true;
|
||||
RecordStyleSheetChange(aStyleSheet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4234,7 +4273,7 @@ PresShell::StyleSheetApplicableStateChanged(nsIDocument *aDocument,
|
|||
bool aApplicable)
|
||||
{
|
||||
if (aStyleSheet->HasRules()) {
|
||||
mStylesHaveChanged = true;
|
||||
RecordStyleSheetChange(aStyleSheet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4244,7 +4283,7 @@ PresShell::StyleRuleChanged(nsIDocument *aDocument,
|
|||
nsIStyleRule* aOldStyleRule,
|
||||
nsIStyleRule* aNewStyleRule)
|
||||
{
|
||||
mStylesHaveChanged = true;
|
||||
RecordStyleSheetChange(aStyleSheet);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4252,7 +4291,7 @@ PresShell::StyleRuleAdded(nsIDocument *aDocument,
|
|||
nsIStyleSheet* aStyleSheet,
|
||||
nsIStyleRule* aStyleRule)
|
||||
{
|
||||
mStylesHaveChanged = true;
|
||||
RecordStyleSheetChange(aStyleSheet);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4260,7 +4299,7 @@ PresShell::StyleRuleRemoved(nsIDocument *aDocument,
|
|||
nsIStyleSheet* aStyleSheet,
|
||||
nsIStyleRule* aStyleRule)
|
||||
{
|
||||
mStylesHaveChanged = true;
|
||||
RecordStyleSheetChange(aStyleSheet);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
|
|
@ -440,6 +440,8 @@ protected:
|
|||
void ShowEventTargetDebug();
|
||||
#endif
|
||||
|
||||
void RecordStyleSheetChange(nsIStyleSheet* aStyleSheet);
|
||||
|
||||
/**
|
||||
* methods that manage rules that are used to implement the associated preferences
|
||||
* - initially created for bugs 31816, 20760, 22963
|
||||
|
|
Загрузка…
Ссылка в новой задаче