From b30ee5e90d73636bc021608a17e079595b074152 Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Mon, 11 Jun 2012 13:57:35 -0700 Subject: [PATCH] Properly dirty intrinsic widths when doing things that change inflation. (Bug 759755, patch 3) r=roc --- dom/base/nsDOMWindowUtils.cpp | 3 ++- layout/base/nsPresShell.cpp | 2 ++ layout/generic/nsHTMLReflowState.cpp | 38 ++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 8ff97106420..c9b9dd61aaf 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -282,7 +282,8 @@ MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext) if (shell) { nsIFrame *rootFrame = shell->GetRootFrame(); if (rootFrame) { - shell->FrameNeedsReflow(rootFrame, nsIPresShell::eResize, + shell->FrameNeedsReflow(rootFrame, + nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY); } } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 34ad2f26211..cfe911b6878 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -2516,6 +2516,8 @@ PresShell::FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty, if (aIntrinsicDirty == eStyleChange) { // Mark all descendants dirty (using an nsTArray stack rather than // recursion). + // Note that nsHTMLReflowState::InitResizeFlags has some similar + // code; see comments there for how and why it differs. nsAutoTArray stack; stack.AppendElement(subtreeRoot); diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index ec8ed32904a..956a6311391 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -403,6 +403,44 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT } else { frame->AddStateBits(NS_FRAME_IS_DIRTY); } + + // Mark intrinsic widths on all descendants dirty. We need to do + // this (1) since we're changing the size of text and need to + // clear text runs on text frames and (2) since we actually are + // changing some intrinsic widths, but only those that live inside + // of containers. + + // It makes sense to do this for descendants but not ancestors + // (which is unusual) because we're only changing the unusual + // inflation-dependent intrinsic widths (i.e., ones computed with + // nsPresContext::mInflationDisabledForShrinkWrap set to false), + // which should never affect anything outside of their inflation + // flow root (or, for that matter, even their inflation + // container). + + // This is also different from what PresShell::FrameNeedsReflow + // does because it doesn't go through placeholders. It doesn't + // need to because we're actually doing something that cares about + // frame tree geometry (the width on an ancestor) rather than + // style. + + nsAutoTArray stack; + stack.AppendElement(frame); + + do { + nsIFrame *f = stack.ElementAt(stack.Length() - 1); + stack.RemoveElementAt(stack.Length() - 1); + + nsIFrame::ChildListIterator lists(f); + for (; !lists.IsDone(); lists.Next()) { + nsFrameList::Enumerator childFrames(lists.CurrentList()); + for (; !childFrames.AtEnd(); childFrames.Next()) { + nsIFrame* kid = childFrames.get(); + kid->MarkIntrinsicWidthsDirty(); + stack.AppendElement(kid); + } + } + } while (stack.Length() != 0); } }