зеркало из https://github.com/mozilla/gecko-dev.git
Bug 844178 - Make RecomputePosition adjust the CB size as ViewportFrame::Reflow does. r=tn
This commit is contained in:
Родитель
5671b1d883
Коммит
b00ebc0531
|
@ -92,6 +92,7 @@
|
|||
#include "nsAnimationManager.h"
|
||||
#include "nsTransitionManager.h"
|
||||
#include "nsSVGIntegrationUtils.h"
|
||||
#include "nsViewportFrame.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
|
@ -12453,7 +12454,7 @@ nsCSSFrameConstructor::RecomputePosition(nsIFrame* aFrame)
|
|||
|
||||
// Construct a bogus parent reflow state so that there's a usable
|
||||
// containing block reflow state.
|
||||
nsIFrame *parentFrame = aFrame->GetParent();
|
||||
nsIFrame* parentFrame = aFrame->GetParent();
|
||||
nsSize parentSize = parentFrame->GetSize();
|
||||
|
||||
nsFrameState savedState = parentFrame->GetStateBits();
|
||||
|
@ -12477,7 +12478,10 @@ nsCSSFrameConstructor::RecomputePosition(nsIFrame* aFrame)
|
|||
nsSize availSize(parentSize.width, NS_INTRINSICSIZE);
|
||||
|
||||
nsSize size = aFrame->GetSize();
|
||||
nsSize cbSize = aFrame->GetContainingBlock()->GetSize();
|
||||
ViewportFrame* viewport = do_QueryFrame(parentFrame);
|
||||
nsSize cbSize = viewport ?
|
||||
viewport->AdjustReflowStateAsContainingBlock(&parentReflowState).Size()
|
||||
: aFrame->GetContainingBlock()->GetSize();
|
||||
const nsMargin& parentBorder =
|
||||
parentReflowState.mStyleBorder->GetComputedBorder();
|
||||
cbSize -= nsSize(parentBorder.LeftRight(), parentBorder.TopBottom());
|
||||
|
|
|
@ -28,6 +28,9 @@ NS_NewViewportFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
|||
}
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(ViewportFrame)
|
||||
NS_QUERYFRAME_HEAD(ViewportFrame)
|
||||
NS_QUERYFRAME_ENTRY(ViewportFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||
|
||||
void
|
||||
ViewportFrame::Init(nsIContent* aContent,
|
||||
|
@ -132,13 +135,9 @@ ViewportFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
|
|||
nsPoint
|
||||
ViewportFrame::AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const
|
||||
{
|
||||
// Calculate how much room is available for fixed frames. That means
|
||||
// determining if the viewport is scrollable and whether the vertical and/or
|
||||
// horizontal scrollbars are visible
|
||||
|
||||
// Get our prinicpal child frame and see if we're scrollable
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
nsIScrollableFrame *scrollingFrame = do_QueryFrame(kidFrame);
|
||||
nsIScrollableFrame* scrollingFrame = do_QueryFrame(kidFrame);
|
||||
|
||||
if (scrollingFrame) {
|
||||
nsMargin scrollbars = scrollingFrame->GetActualScrollbarSizes();
|
||||
|
@ -152,6 +151,32 @@ ViewportFrame::AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) c
|
|||
return nsPoint(0, 0);
|
||||
}
|
||||
|
||||
nsRect
|
||||
ViewportFrame::AdjustReflowStateAsContainingBlock(nsHTMLReflowState* aReflowState) const
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsPoint offset =
|
||||
#endif
|
||||
AdjustReflowStateForScrollbars(aReflowState);
|
||||
|
||||
NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
|
||||
(offset.x == 0 && offset.y == 0),
|
||||
"We don't handle correct positioning of fixed frames with "
|
||||
"scrollbars in odd positions");
|
||||
|
||||
// If a scroll position clamping scroll-port size has been set, layout
|
||||
// fixed position elements to this size instead of the computed size.
|
||||
nsRect rect(0, 0, aReflowState->ComputedWidth(), aReflowState->ComputedHeight());
|
||||
nsIPresShell* ps = PresContext()->PresShell();
|
||||
if (ps->IsScrollPositionClampingScrollPortSizeSet()) {
|
||||
rect.SizeTo(ps->GetScrollPositionClampingScrollPortSize());
|
||||
}
|
||||
|
||||
// Make sure content document fixed-position margins are respected.
|
||||
rect.Deflate(ps->GetContentDocumentFixedPositionMargins());
|
||||
return rect;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ViewportFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
|
@ -238,28 +263,7 @@ ViewportFrame::Reflow(nsPresContext* aPresContext,
|
|||
reflowState.SetComputedHeight(aDesiredSize.height);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsPoint offset =
|
||||
#endif
|
||||
AdjustReflowStateForScrollbars(&reflowState);
|
||||
|
||||
NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
|
||||
(offset.x == 0 && offset.y == 0),
|
||||
"We don't handle correct positioning of fixed frames with "
|
||||
"scrollbars in odd positions");
|
||||
|
||||
// If a scroll position clamping scroll-port size has been set, layout
|
||||
// fixed position elements to this size instead of the computed size.
|
||||
nsRect rect(0, 0, reflowState.ComputedWidth(), reflowState.ComputedHeight());
|
||||
if (aPresContext->PresShell()->IsScrollPositionClampingScrollPortSizeSet()) {
|
||||
nsSize size = aPresContext->PresShell()->
|
||||
GetScrollPositionClampingScrollPortSize();
|
||||
rect.width = size.width;
|
||||
rect.height = size.height;
|
||||
}
|
||||
|
||||
// Make sure content document fixed-position margins are respected.
|
||||
rect.Deflate(aPresContext->PresShell()->GetContentDocumentFixedPositionMargins());
|
||||
nsRect rect = AdjustReflowStateAsContainingBlock(&reflowState);
|
||||
|
||||
// Just reflow all the fixed-pos frames.
|
||||
rv = GetAbsoluteContainingBlock()->Reflow(this, aPresContext, reflowState, aStatus,
|
||||
|
|
|
@ -24,6 +24,8 @@ class nsPresContext;
|
|||
*/
|
||||
class ViewportFrame : public nsContainerFrame {
|
||||
public:
|
||||
NS_DECL_QUERYFRAME_TARGET(ViewportFrame)
|
||||
NS_DECL_QUERYFRAME
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
||||
typedef nsContainerFrame Super;
|
||||
|
@ -68,6 +70,14 @@ public:
|
|||
*/
|
||||
virtual nsIAtom* GetType() const MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Adjust aReflowState to account for scrollbars and pres shell
|
||||
* GetScrollPositionClampingScrollPortSizeSet and
|
||||
* GetContentDocumentFixedPositionMargins adjustments.
|
||||
* @return the rect to use as containing block rect
|
||||
*/
|
||||
nsRect AdjustReflowStateAsContainingBlock(nsHTMLReflowState* aReflowState) const;
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
@ -76,6 +86,13 @@ private:
|
|||
virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const { return kFixedList; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Calculate how much room is available for fixed frames. That means
|
||||
* determining if the viewport is scrollable and whether the vertical and/or
|
||||
* horizontal scrollbars are visible. Adjust the computed width/height and
|
||||
* available width for aReflowState accordingly.
|
||||
* @return the current scroll position, or 0,0 if not scrollable
|
||||
*/
|
||||
nsPoint AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html><head>
|
||||
<meta charset="utf-8">
|
||||
<title>Testcase for bug 844178</title>
|
||||
<style type="text/css">
|
||||
|
||||
html,body {
|
||||
color:black; background-color:white; font-size:16px; padding:0; margin:0;
|
||||
}
|
||||
|
||||
body {
|
||||
position: fixed;
|
||||
right: 5px;
|
||||
top: 100px;
|
||||
width: 100px;
|
||||
height: 10px;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
:root { overflow:scroll; }
|
||||
|
||||
span {
|
||||
background:lime;
|
||||
display:inline-block;
|
||||
width:100px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body><span>Hello</span></body>
|
||||
</html>
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html class="reftest-wait"><head>
|
||||
<meta charset="utf-8">
|
||||
<title>Testcase for bug 844178</title>
|
||||
<style type="text/css">
|
||||
|
||||
html,body {
|
||||
color:black; background-color:white; font-size:16px; padding:0; margin:0;
|
||||
}
|
||||
|
||||
body {
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
top: 100px;
|
||||
width: 100px;
|
||||
height: 10px;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
:root { overflow:scroll; }
|
||||
|
||||
span {
|
||||
background:lime;
|
||||
display:inline-block;
|
||||
width:100px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
function doTest() {
|
||||
document.body.style.right='5px';
|
||||
document.body.offsetHeight;
|
||||
document.documentElement.removeAttribute('class');
|
||||
}
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
</script>
|
||||
</head>
|
||||
<body><span>Hello</span></body>
|
||||
</html>
|
|
@ -1749,6 +1749,7 @@ skip-if(B2G) == 818276-1.html 818276-1-ref.html
|
|||
== 827799-1.html about:blank
|
||||
== 836844-1.html 836844-1-ref.html
|
||||
== 841192-1.html 841192-1-ref.html
|
||||
== 844178.html 844178-ref.html
|
||||
== 846144-1.html 846144-1-ref.html
|
||||
== 847850-1.html 847850-1-ref.html
|
||||
== 848421-1.html 848421-1-ref.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче