Bug 751012. When saving frame state, make sure to walk through placeholders so we save the state of out-of-flow descendants properly. Also make sure to walk the continuations and special siblings of the root frame that we're saving state for. r=roc

This commit is contained in:
Boris Zbarsky 2012-05-09 21:27:47 -04:00
parent 68b4c38d08
commit 15639de868
8 changed files with 139 additions and 23 deletions

View File

@ -8825,29 +8825,21 @@ nsCSSFrameConstructor::GetInsertionPoint(nsIFrame* aParentFrame,
// Capture state for the frame tree rooted at the frame associated with the
// content object, aContent
nsresult
void
nsCSSFrameConstructor::CaptureStateForFramesOf(nsIContent* aContent,
nsILayoutHistoryState* aHistoryState)
{
if (!aHistoryState) {
return;
}
nsIFrame* frame = aContent->GetPrimaryFrame();
if (frame == mRootElementFrame) {
frame = mFixedContainingBlock;
}
if (frame) {
CaptureStateFor(frame, aHistoryState);
for ( ; frame;
frame = nsLayoutUtils::GetNextContinuationOrSpecialSibling(frame)) {
CaptureFrameState(frame, aHistoryState);
}
return NS_OK;
}
// Capture state for the frame tree rooted at aFrame.
nsresult
nsCSSFrameConstructor::CaptureStateFor(nsIFrame* aFrame,
nsILayoutHistoryState* aHistoryState)
{
if (aFrame && aHistoryState) {
CaptureFrameState(aFrame, aHistoryState);
}
return NS_OK;
}
nsresult

View File

@ -1708,12 +1708,8 @@ private:
// Capture state for the frame tree rooted at the frame associated with the
// content object, aContent
nsresult CaptureStateForFramesOf(nsIContent* aContent,
nsILayoutHistoryState* aHistoryState);
// Capture state for the frame tree rooted at aFrame.
nsresult CaptureStateFor(nsIFrame* aFrame,
nsILayoutHistoryState* aHistoryState);
void CaptureStateForFramesOf(nsIContent* aContent,
nsILayoutHistoryState* aHistoryState);
//----------------------------------------

View File

@ -1786,7 +1786,15 @@ nsFrameManager::CaptureFrameState(nsIFrame* aFrame,
for (; !lists.IsDone(); lists.Next()) {
nsFrameList::Enumerator childFrames(lists.CurrentList());
for (; !childFrames.AtEnd(); childFrames.Next()) {
CaptureFrameState(childFrames.get(), aState);
nsIFrame* child = childFrames.get();
if (child->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
// We'll pick it up when we get to its placeholder
continue;
}
// Make sure to walk through placeholders as needed, so that we
// save state for out-of-flows which may not be our descendants
// themselves but whose placeholders are our descendants.
CaptureFrameState(nsPlaceholderFrame::GetRealFrameFor(child), aState);
}
}
}

View File

@ -162,7 +162,10 @@ public:
/*
* Capture/restore frame state for the frame subtree rooted at aFrame.
* aState is the document state storage object onto which each frame
* stores its state.
* stores its state. Callers of CaptureFrameState are responsible for
* traversing next continuations of special siblings of aFrame as
* needed; this method will only work with actual frametree descendants
* of aFrame.
*/
NS_HIDDEN_(void) CaptureFrameState(nsIFrame* aFrame,

View File

@ -0,0 +1,37 @@
<!doctype html>
<body style="position: relative">
<div id="container" style="position: relative; height: 300px">
<div style="position:absolute; top: 0; left: 0">
<textarea rows="6">
You should be seeing the "Should see me" text.
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
Should see me.
</textarea>
</div>
</div>
<script>
var textarea = document.querySelector("textarea");
textarea.scrollTop = textarea.scrollHeight
document.getElementById("container").style.overflow = "hidden";
</script>
</body>

View File

@ -0,0 +1,37 @@
<!doctype html>
<body style="position: relative">
<div id="container" style="height: 300px">
<div style="position:absolute; top: 0; left: 0">
<textarea rows="6">
You should be seeing the "Should see me" text.
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
Should see me.
</textarea>
</div>
</div>
<script>
var textarea = document.querySelector("textarea");
textarea.scrollTop = textarea.scrollHeight
document.getElementById("container").style.overflow = "hidden";
</script>
</body>

View File

@ -0,0 +1,41 @@
<!doctype html>
<body style="position: relative;">
<div style="-moz-column-count: 2; height: 300px">
<div id="container" style="height: 600px">
<!-- Make sure the abs-pos div's placeholder is not in the first continuation -->
<div style="height: 400px"></div>
<div style="position:absolute; top: 0; left: 0">
<textarea rows="6">
You should be seeing the "Should see me" text.
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
Should see me.
</textarea>
</div>
</div>
</div>
<script>
var textarea = document.querySelector("textarea");
textarea.scrollTop = textarea.scrollHeight
document.getElementById("container").style.overflow = "hidden";
</script>
</body>

View File

@ -1701,3 +1701,5 @@ needs-focus == 731726-1.html 731726-1-ref.html
== 745934-1.html 745934-1-ref.html
== 748803-1.html 748803-1-ref.html
== 750551-1.html 750551-1-ref.html
== 751012-1a.html 751012-1-ref.html
== 751012-1b.html 751012-1-ref.html