Bug 1437790: No need to reframe synchronously on chrome-flush-skin-caches. r=xidorn

Instead, just post the reframe, and process them normally on the next style
flush.

The assertion happens because the observer is triggered due to a doc ltr -> rtl
change, which triggers style invalidation. There's nothing processing the
restyles resulting from that invalidation before we hackily go into frame
construction from there, and thus we assert that the styles aren't up-to-date.

MozReview-Commit-ID: GnOKFqmtTnq

--HG--
extra : rebase_source : 94adefa065465ab1427f3ba3081c575f5e712ccf
This commit is contained in:
Emilio Cobos Álvarez 2018-02-13 10:38:30 +01:00
Родитель a9b38c85c2
Коммит 574cebf768
1 изменённых файлов: 20 добавлений и 37 удалений

Просмотреть файл

@ -9211,14 +9211,14 @@ PresShell::WindowSizeMoveDone()
*/
// Return value says whether to walk children.
typedef bool (* frameWalkerFn)(nsIFrame *aFrame, void *aClosure);
typedef bool (*frameWalkerFn)(nsIFrame* aFrame);
static bool
ReResolveMenusAndTrees(nsIFrame *aFrame, void *aClosure)
ReResolveMenusAndTrees(nsIFrame* aFrame)
{
// Trees have a special style cache that needs to be flushed when
// the theme changes.
nsTreeBodyFrame *treeBody = do_QueryFrame(aFrame);
nsTreeBodyFrame* treeBody = do_QueryFrame(aFrame);
if (treeBody)
treeBody->ClearStyleAndImageCaches();
@ -9233,22 +9233,24 @@ ReResolveMenusAndTrees(nsIFrame *aFrame, void *aClosure)
}
static bool
ReframeImageBoxes(nsIFrame *aFrame, void *aClosure)
ReframeImageBoxes(nsIFrame* aFrame)
{
nsStyleChangeList *list = static_cast<nsStyleChangeList*>(aClosure);
if (aFrame->IsImageBoxFrame()) {
list->AppendChange(aFrame, aFrame->GetContent(),
nsChangeHint_ReconstructFrame);
aFrame->PresContext()->RestyleManager()->PostRestyleEvent(
aFrame->GetContent()->AsElement(),
nsRestyleHint(0),
nsChangeHint_ReconstructFrame);
return false; // don't walk descendants
}
return true; // walk descendants
}
static void
WalkFramesThroughPlaceholders(nsPresContext *aPresContext, nsIFrame *aFrame,
frameWalkerFn aFunc, void *aClosure)
WalkFramesThroughPlaceholders(nsPresContext* aPresContext,
nsIFrame* aFrame,
frameWalkerFn aFunc)
{
bool walkChildren = (*aFunc)(aFrame, aClosure);
bool walkChildren = (*aFunc)(aFrame);
if (!walkChildren)
return;
@ -9262,7 +9264,7 @@ WalkFramesThroughPlaceholders(nsPresContext *aPresContext, nsIFrame *aFrame,
// out-of-flows of placeholders.
WalkFramesThroughPlaceholders(aPresContext,
nsPlaceholderFrame::GetRealFrameFor(child),
aFunc, aClosure);
aFunc);
}
}
}
@ -9281,37 +9283,18 @@ PresShell::Observe(nsISupports* aSubject,
#ifdef MOZ_XUL
if (!nsCRT::strcmp(aTopic, "chrome-flush-skin-caches")) {
nsIFrame *rootFrame = mFrameConstructor->GetRootFrame();
// Need to null-check because "chrome-flush-skin-caches" can happen
// at interesting times during startup.
if (rootFrame) {
if (nsIFrame* rootFrame = mFrameConstructor->GetRootFrame()) {
NS_ASSERTION(mViewManager, "View manager must exist");
AutoWeakFrame weakRoot(rootFrame);
// Have to make sure that the content notifications are flushed before we
// start messing with the frame model; otherwise we can get content doubling.
mDocument->FlushPendingNotifications(FlushType::ContentAndNotify);
WalkFramesThroughPlaceholders(
mPresContext, rootFrame, ReResolveMenusAndTrees);
if (weakRoot.IsAlive()) {
WalkFramesThroughPlaceholders(mPresContext, rootFrame,
&ReResolveMenusAndTrees, nullptr);
// Because "chrome:" URL equality is messy, reframe image box
// frames (hack!).
nsStyleChangeList changeList(mPresContext->StyleSet()->BackendType());
WalkFramesThroughPlaceholders(mPresContext, rootFrame,
ReframeImageBoxes, &changeList);
// Mark ourselves as not safe to flush while we're doing frame
// construction.
{
nsAutoScriptBlocker scriptBlocker;
++mChangeNestCount;
RestyleManager* restyleManager = mPresContext->RestyleManager();
restyleManager->ProcessRestyledFrames(changeList);
restyleManager->FlushOverflowChangedTracker();
--mChangeNestCount;
}
}
// Because "chrome:" URL equality is messy, reframe image box
// frames (hack!).
WalkFramesThroughPlaceholders(
mPresContext, rootFrame, ReframeImageBoxes);
}
return NS_OK;
}