mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 811403 (Part 1) - Take scrollbars into account for viewport units if 'overflow: scroll' is set. r=dbaron
This commit is contained in:
parent
47f0c99c37
commit
81c3ba6eb9
@ -38,6 +38,7 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "CSSCalc.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsRenderingContext.h"
|
||||
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
|
||||
@ -229,6 +230,51 @@ GetMetricsFor(nsPresContext* aPresContext,
|
||||
return fm.forget();
|
||||
}
|
||||
|
||||
|
||||
static nsSize CalcViewportUnitsScale(nsPresContext* aPresContext)
|
||||
{
|
||||
// The caller is making use of viewport units, so notify the pres context
|
||||
// that it will need to rebuild the rule tree if the size of the viewport
|
||||
// changes.
|
||||
aPresContext->SetUsesViewportUnits(true);
|
||||
|
||||
// The default (when we have 'overflow: auto' on the root element, or
|
||||
// trivially for 'overflow: hidden' since we never have scrollbars in that
|
||||
// case) is to define the scale of the viewport units without considering
|
||||
// scrollbars.
|
||||
nsSize viewportSize(aPresContext->GetVisibleArea().Size());
|
||||
|
||||
// Check for 'overflow: scroll' styles on the root scroll frame. If we find
|
||||
// any, the standard requires us to take scrollbars into account.
|
||||
nsIScrollableFrame* scrollFrame =
|
||||
aPresContext->PresShell()->GetRootScrollFrameAsScrollable();
|
||||
if (scrollFrame) {
|
||||
nsPresContext::ScrollbarStyles styles(scrollFrame->GetScrollbarStyles());
|
||||
|
||||
if (styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL ||
|
||||
styles.mVertical == NS_STYLE_OVERFLOW_SCROLL) {
|
||||
// Gather scrollbar size information.
|
||||
nsRefPtr<nsRenderingContext> context =
|
||||
aPresContext->PresShell()->GetReferenceRenderingContext();
|
||||
nsMargin sizes(scrollFrame->GetDesiredScrollbarSizes(aPresContext, context));
|
||||
|
||||
if (styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL) {
|
||||
// 'overflow-x: scroll' means we must consider the horizontal scrollbar,
|
||||
// which affects the scale of viewport height units.
|
||||
viewportSize.height -= sizes.TopBottom();
|
||||
}
|
||||
|
||||
if (styles.mVertical == NS_STYLE_OVERFLOW_SCROLL) {
|
||||
// 'overflow-y: scroll' means we must consider the vertical scrollbar,
|
||||
// which affects the scale of viewport width units.
|
||||
viewportSize.width -= sizes.LeftRight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return viewportSize;
|
||||
}
|
||||
|
||||
static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
nscoord aFontSize,
|
||||
const nsStyleFont* aStyleFont,
|
||||
@ -286,22 +332,18 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
// for an increased cost to dynamic changes to the viewport size
|
||||
// when viewport units are in use.
|
||||
case eCSSUnit_ViewportWidth: {
|
||||
aPresContext->SetUsesViewportUnits(true);
|
||||
return ScaleCoord(aValue, 0.01f * aPresContext->GetVisibleArea().width);
|
||||
return ScaleCoord(aValue, 0.01f * CalcViewportUnitsScale(aPresContext).width);
|
||||
}
|
||||
case eCSSUnit_ViewportHeight: {
|
||||
aPresContext->SetUsesViewportUnits(true);
|
||||
return ScaleCoord(aValue, 0.01f * aPresContext->GetVisibleArea().height);
|
||||
return ScaleCoord(aValue, 0.01f * CalcViewportUnitsScale(aPresContext).height);
|
||||
}
|
||||
case eCSSUnit_ViewportMin: {
|
||||
aPresContext->SetUsesViewportUnits(true);
|
||||
nsSize viewportSize = aPresContext->GetVisibleArea().Size();
|
||||
return ScaleCoord(aValue, 0.01f * min(viewportSize.width, viewportSize.height));
|
||||
nsSize vuScale(CalcViewportUnitsScale(aPresContext));
|
||||
return ScaleCoord(aValue, 0.01f * min(vuScale.width, vuScale.height));
|
||||
}
|
||||
case eCSSUnit_ViewportMax: {
|
||||
aPresContext->SetUsesViewportUnits(true);
|
||||
nsSize viewportSize = aPresContext->GetVisibleArea().Size();
|
||||
return ScaleCoord(aValue, 0.01f * max(viewportSize.width, viewportSize.height));
|
||||
nsSize vuScale(CalcViewportUnitsScale(aPresContext));
|
||||
return ScaleCoord(aValue, 0.01f * max(vuScale.width, vuScale.height));
|
||||
}
|
||||
// While we could deal with 'rem' units correctly by simply not
|
||||
// caching any data that uses them in the rule tree, it's valuable
|
||||
|
Loading…
Reference in New Issue
Block a user