Bug 1824236 - Stop using XUL layout for scrollbars. r=jwatt
This rewrites scrollbar layout to work with regular reflow rather than box layout. Overall it's about the same amount of code (mostly because nsScrollbarFrame::Reflow is sorta hand-rolled), but it cleans up a bit and it is progress towards removing XUL layout altogether, without getting into much deeper refactoring. This also blocks some other performance improvements and refactorings I want to make in this code. We make some assumptions to simplify the code that to some extent were made already before, both explicitly and by virtue of using XUL layout. In particular, we assume that scrollbar / slider / thumb has no border or padding and that the writing-mode is horizontal ltr. Differential Revision: https://phabricator.services.mozilla.com/D173489
This commit is contained in:
@@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1697769
|
|||||||
|
|
||||||
<hbox height="300" align="center">
|
<hbox height="300" align="center">
|
||||||
<vbox width="30" align="center">
|
<vbox width="30" align="center">
|
||||||
<scrollbar id="scrollbar" orient="vertical" curpos="0" maxpos="500" height="300" />
|
<scrollbar id="scrollbar" orient="vertical" curpos="0" maxpos="500" style="height: 300px" />
|
||||||
</vbox>
|
</vbox>
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div style="height: 20000px; background-color: green"></div>
|
<div style="height: 20000px; background-color: green"></div>
|
||||||
<script type="application/javascript">
|
<script>
|
||||||
const utils = SpecialPowers.getDOMWindowUtils(window);
|
const utils = SpecialPowers.getDOMWindowUtils(window);
|
||||||
|
|
||||||
async function test() {
|
async function test() {
|
||||||
|
|||||||
@@ -222,8 +222,8 @@ nsIFrame* NS_NewSliderFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
|||||||
|
|
||||||
nsIFrame* NS_NewScrollbarFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
nsIFrame* NS_NewScrollbarFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
||||||
|
|
||||||
nsIFrame* NS_NewScrollbarButtonFrame(PresShell* aPresShell,
|
nsIFrame* NS_NewScrollbarButtonFrame(PresShell*, ComputedStyle*);
|
||||||
ComputedStyle* aStyle);
|
nsIFrame* NS_NewSimpleXULLeafFrame(PresShell*, ComputedStyle*);
|
||||||
|
|
||||||
nsIFrame* NS_NewXULImageFrame(PresShell*, ComputedStyle*);
|
nsIFrame* NS_NewXULImageFrame(PresShell*, ComputedStyle*);
|
||||||
nsIFrame* NS_NewImageFrameForContentProperty(PresShell*, ComputedStyle*);
|
nsIFrame* NS_NewImageFrameForContentProperty(PresShell*, ComputedStyle*);
|
||||||
@@ -4145,8 +4145,11 @@ nsCSSFrameConstructor::FindXULTagData(const Element& aElement,
|
|||||||
SIMPLE_XUL_CREATE(editor, NS_NewSubDocumentFrame),
|
SIMPLE_XUL_CREATE(editor, NS_NewSubDocumentFrame),
|
||||||
SIMPLE_XUL_CREATE(browser, NS_NewSubDocumentFrame),
|
SIMPLE_XUL_CREATE(browser, NS_NewSubDocumentFrame),
|
||||||
SIMPLE_XUL_CREATE(splitter, NS_NewSplitterFrame),
|
SIMPLE_XUL_CREATE(splitter, NS_NewSplitterFrame),
|
||||||
SIMPLE_XUL_CREATE(slider, NS_NewSliderFrame),
|
|
||||||
SIMPLE_XUL_CREATE(scrollbar, NS_NewScrollbarFrame),
|
SIMPLE_XUL_CREATE(scrollbar, NS_NewScrollbarFrame),
|
||||||
|
SIMPLE_XUL_CREATE(slider, NS_NewSliderFrame),
|
||||||
|
SIMPLE_XUL_CREATE(thumb, NS_NewSimpleXULLeafFrame),
|
||||||
|
SIMPLE_XUL_CREATE(scrollcorner, NS_NewSimpleXULLeafFrame),
|
||||||
|
SIMPLE_XUL_CREATE(resizer, NS_NewSimpleXULLeafFrame),
|
||||||
SIMPLE_XUL_CREATE(scrollbarbutton, NS_NewScrollbarButtonFrame),
|
SIMPLE_XUL_CREATE(scrollbarbutton, NS_NewScrollbarButtonFrame),
|
||||||
{nsGkAtoms::panel, kPopupData},
|
{nsGkAtoms::panel, kPopupData},
|
||||||
{nsGkAtoms::menupopup, kPopupData},
|
{nsGkAtoms::menupopup, kPopupData},
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ FRAME_CLASSES = [
|
|||||||
Frame("nsRubyFrame", "Ruby", NOT_LEAF),
|
Frame("nsRubyFrame", "Ruby", NOT_LEAF),
|
||||||
Frame("nsRubyTextContainerFrame", "RubyTextContainer", NOT_LEAF),
|
Frame("nsRubyTextContainerFrame", "RubyTextContainer", NOT_LEAF),
|
||||||
Frame("nsRubyTextFrame", "RubyText", NOT_LEAF),
|
Frame("nsRubyTextFrame", "RubyText", NOT_LEAF),
|
||||||
Frame("nsScrollbarButtonFrame", "Box", NOT_LEAF),
|
Frame("SimpleXULLeafFrame", "SimpleXULLeaf", LEAF),
|
||||||
|
Frame("nsScrollbarButtonFrame", "SimpleXULLeaf", LEAF),
|
||||||
Frame("nsScrollbarFrame", "Scrollbar", NOT_LEAF),
|
Frame("nsScrollbarFrame", "Scrollbar", NOT_LEAF),
|
||||||
Frame("nsSearchControlFrame", "SearchControl", LEAF),
|
Frame("nsSearchControlFrame", "SearchControl", LEAF),
|
||||||
Frame("nsSelectsAreaFrame", "Block", NOT_LEAF),
|
Frame("nsSelectsAreaFrame", "Block", NOT_LEAF),
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "nsIScrollableFrame.h"
|
#include "nsIScrollableFrame.h"
|
||||||
#include "PresShell.h"
|
#include "PresShell.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
|
#include "nsScrollbarFrame.h"
|
||||||
#include "nsRefreshDriver.h"
|
#include "nsRefreshDriver.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsStyledElement.h"
|
#include "nsStyledElement.h"
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
||||||
class="reftest-wait">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<script>
|
|
||||||
|
|
||||||
var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
||||||
|
|
||||||
function boom()
|
|
||||||
{
|
|
||||||
var hbox = document.getElementById("hbox");
|
|
||||||
var checkbox = document.createElementNS(XUL_NS, "checkbox");
|
|
||||||
|
|
||||||
hbox.appendChild(checkbox);
|
|
||||||
|
|
||||||
document.documentElement.removeAttribute("class");
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body onload="setTimeout(boom, 30)">
|
|
||||||
|
|
||||||
<xul:scrollbar><span><xul:hbox id="hbox"/></span></xul:scrollbar>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -75,7 +75,6 @@ load 368568.html
|
|||||||
load 368752.html
|
load 368752.html
|
||||||
load 368860-1.html
|
load 368860-1.html
|
||||||
load 368863-1.html
|
load 368863-1.html
|
||||||
load 369038-1.xhtml
|
|
||||||
load 369150-1.html
|
load 369150-1.html
|
||||||
load 369150-2.html
|
load 369150-2.html
|
||||||
load 369227-1.xhtml
|
load 369227-1.xhtml
|
||||||
|
|||||||
@@ -397,35 +397,6 @@ void nsHTMLScrollFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) {
|
|||||||
ReloadChildFrames();
|
ReloadChildFrames();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetScrollbarMetrics(nsBoxLayoutState& aState, nsIFrame* aBox,
|
|
||||||
nsSize* aMin, nsSize* aPref) {
|
|
||||||
NS_ASSERTION(aState.GetRenderingContext(),
|
|
||||||
"Must have rendering context in layout state for size "
|
|
||||||
"computations");
|
|
||||||
|
|
||||||
if (aMin) {
|
|
||||||
*aMin = aBox->GetXULMinSize(aState);
|
|
||||||
nsIFrame::AddXULMargin(aBox, *aMin);
|
|
||||||
if (aMin->width < 0) {
|
|
||||||
aMin->width = 0;
|
|
||||||
}
|
|
||||||
if (aMin->height < 0) {
|
|
||||||
aMin->height = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aPref) {
|
|
||||||
*aPref = aBox->GetXULPrefSize(aState);
|
|
||||||
nsIFrame::AddXULMargin(aBox, *aPref);
|
|
||||||
if (aPref->width < 0) {
|
|
||||||
aPref->width = 0;
|
|
||||||
}
|
|
||||||
if (aPref->height < 0) {
|
|
||||||
aPref->height = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
HTML scrolling implementation
|
HTML scrolling implementation
|
||||||
|
|
||||||
@@ -460,7 +431,6 @@ struct MOZ_STACK_CLASS ScrollReflowInput {
|
|||||||
// === Filled in by the constructor. Members in this section shouldn't change
|
// === Filled in by the constructor. Members in this section shouldn't change
|
||||||
// their values after the constructor. ===
|
// their values after the constructor. ===
|
||||||
const ReflowInput& mReflowInput;
|
const ReflowInput& mReflowInput;
|
||||||
nsBoxLayoutState mBoxState;
|
|
||||||
ShowScrollbar mHScrollbar;
|
ShowScrollbar mHScrollbar;
|
||||||
// If the horizontal scrollbar is allowed (even if mHScrollbar ==
|
// If the horizontal scrollbar is allowed (even if mHScrollbar ==
|
||||||
// ShowScrollbar::Never) provided that it is for scrolling the visual viewport
|
// ShowScrollbar::Never) provided that it is for scrolling the visual viewport
|
||||||
@@ -505,9 +475,9 @@ struct MOZ_STACK_CLASS ScrollReflowInput {
|
|||||||
|
|
||||||
ScrollReflowInput(nsHTMLScrollFrame* aFrame, const ReflowInput& aReflowInput);
|
ScrollReflowInput(nsHTMLScrollFrame* aFrame, const ReflowInput& aReflowInput);
|
||||||
|
|
||||||
nscoord VScrollbarMinHeight() const { return mVScrollbarMinSize.height; }
|
nscoord VScrollbarMinHeight() const { return mVScrollbarPrefSize.height; }
|
||||||
nscoord VScrollbarPrefWidth() const { return mVScrollbarPrefSize.width; }
|
nscoord VScrollbarPrefWidth() const { return mVScrollbarPrefSize.width; }
|
||||||
nscoord HScrollbarMinWidth() const { return mHScrollbarMinSize.width; }
|
nscoord HScrollbarMinWidth() const { return mHScrollbarPrefSize.width; }
|
||||||
nscoord HScrollbarPrefHeight() const { return mHScrollbarPrefSize.height; }
|
nscoord HScrollbarPrefHeight() const { return mHScrollbarPrefSize.height; }
|
||||||
|
|
||||||
// Returns the sizes occupied by the scrollbar gutters. If aShowVScroll or
|
// Returns the sizes occupied by the scrollbar gutters. If aShowVScroll or
|
||||||
@@ -515,6 +485,9 @@ struct MOZ_STACK_CLASS ScrollReflowInput {
|
|||||||
// included.
|
// included.
|
||||||
nsMargin ScrollbarGutter(bool aShowVScrollbar, bool aShowHScrollbar,
|
nsMargin ScrollbarGutter(bool aShowVScrollbar, bool aShowHScrollbar,
|
||||||
bool aScrollbarOnRight) const {
|
bool aScrollbarOnRight) const {
|
||||||
|
if (mOverlayScrollbars) {
|
||||||
|
return mScrollbarGutter;
|
||||||
|
}
|
||||||
nsMargin gutter = mScrollbarGutter;
|
nsMargin gutter = mScrollbarGutter;
|
||||||
if (aShowVScrollbar && gutter.right == 0 && gutter.left == 0) {
|
if (aShowVScrollbar && gutter.right == 0 && gutter.left == 0) {
|
||||||
const nscoord w = VScrollbarPrefWidth();
|
const nscoord w = VScrollbarPrefWidth();
|
||||||
@@ -531,13 +504,14 @@ struct MOZ_STACK_CLASS ScrollReflowInput {
|
|||||||
return gutter;
|
return gutter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OverlayScrollbars() const { return mOverlayScrollbars; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Filled in by the constructor. Put variables here to keep them unchanged
|
// Filled in by the constructor. Put variables here to keep them unchanged
|
||||||
// after initializing them in the constructor.
|
// after initializing them in the constructor.
|
||||||
nsSize mVScrollbarMinSize;
|
|
||||||
nsSize mVScrollbarPrefSize;
|
nsSize mVScrollbarPrefSize;
|
||||||
nsSize mHScrollbarMinSize;
|
|
||||||
nsSize mHScrollbarPrefSize;
|
nsSize mHScrollbarPrefSize;
|
||||||
|
bool mOverlayScrollbars = false;
|
||||||
// The scrollbar gutter sizes resolved from the scrollbar-gutter and
|
// The scrollbar gutter sizes resolved from the scrollbar-gutter and
|
||||||
// scrollbar-width property.
|
// scrollbar-width property.
|
||||||
nsMargin mScrollbarGutter;
|
nsMargin mScrollbarGutter;
|
||||||
@@ -546,55 +520,35 @@ struct MOZ_STACK_CLASS ScrollReflowInput {
|
|||||||
ScrollReflowInput::ScrollReflowInput(nsHTMLScrollFrame* aFrame,
|
ScrollReflowInput::ScrollReflowInput(nsHTMLScrollFrame* aFrame,
|
||||||
const ReflowInput& aReflowInput)
|
const ReflowInput& aReflowInput)
|
||||||
: mReflowInput(aReflowInput),
|
: mReflowInput(aReflowInput),
|
||||||
// mBoxState is just used for scrollbars so we don't need to
|
|
||||||
// worry about the reflow depth here
|
|
||||||
mBoxState(aReflowInput.mFrame->PresContext(),
|
|
||||||
aReflowInput.mRenderingContext),
|
|
||||||
mComputedBorder(aReflowInput.ComputedPhysicalBorderPadding() -
|
mComputedBorder(aReflowInput.ComputedPhysicalBorderPadding() -
|
||||||
aReflowInput.ComputedPhysicalPadding()),
|
aReflowInput.ComputedPhysicalPadding()),
|
||||||
mScrollbarGutterFromLastReflow(aFrame->GetWritingMode()) {
|
mScrollbarGutterFromLastReflow(aFrame->GetWritingMode()) {
|
||||||
ScrollStyles styles = aFrame->GetScrollStyles();
|
ScrollStyles styles = aFrame->GetScrollStyles();
|
||||||
mHScrollbar = ShouldShowScrollbar(styles.mHorizontal);
|
mHScrollbar = ShouldShowScrollbar(styles.mHorizontal);
|
||||||
mVScrollbar = ShouldShowScrollbar(styles.mVertical);
|
mVScrollbar = ShouldShowScrollbar(styles.mVertical);
|
||||||
|
mOverlayScrollbars = aFrame->UsesOverlayScrollbars();
|
||||||
|
|
||||||
if (nsIFrame* hScrollbarBox = aFrame->GetScrollbarBox(false)) {
|
if (nsScrollbarFrame* scrollbar = aFrame->GetScrollbarBox(false)) {
|
||||||
nsScrollbarFrame* scrollbar = do_QueryFrame(hScrollbarBox);
|
|
||||||
scrollbar->SetScrollbarMediatorContent(mReflowInput.mFrame->GetContent());
|
scrollbar->SetScrollbarMediatorContent(mReflowInput.mFrame->GetContent());
|
||||||
|
mHScrollbarPrefSize = scrollbar->ScrollbarMinSize();
|
||||||
GetScrollbarMetrics(mBoxState, hScrollbarBox, &mHScrollbarMinSize,
|
// A zero minimum size is a bug with non-overlay scrollbars. That means
|
||||||
&mHScrollbarPrefSize);
|
// we'll always try to place the scrollbar, even if it will ultimately not
|
||||||
|
// fit, see bug 1809630. XUL collapsing is the exception because the
|
||||||
// A zero minimum size is a bug with non-overlay scrollbars. That
|
|
||||||
// means we'll always try to place the scrollbar, even if it will ultimately
|
|
||||||
// not fit, see bug 1809630. XUL collapsing is the exception because the
|
|
||||||
// front-end uses it.
|
// front-end uses it.
|
||||||
MOZ_ASSERT(aFrame->PresContext()->UseOverlayScrollbars() ||
|
MOZ_ASSERT(scrollbar->IsXULCollapsed() ||
|
||||||
hScrollbarBox->IsXULCollapsed() ||
|
(mHScrollbarPrefSize.width && mHScrollbarPrefSize.height),
|
||||||
(mHScrollbarMinSize.width && mHScrollbarMinSize.height),
|
"Shouldn't have a zero horizontal scrollbar-size");
|
||||||
"Shouldn't have a zero horizontal min-scrollbar-size");
|
|
||||||
MOZ_ASSERT(mHScrollbarPrefSize.width >= mHScrollbarMinSize.width &&
|
|
||||||
mHScrollbarPrefSize.height >= mHScrollbarMinSize.height,
|
|
||||||
"Scrollbar pref size should be >= min size");
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mHScrollbar = ShowScrollbar::Never;
|
mHScrollbar = ShowScrollbar::Never;
|
||||||
mHScrollbarAllowedForScrollingVVInsideLV = false;
|
mHScrollbarAllowedForScrollingVVInsideLV = false;
|
||||||
}
|
}
|
||||||
if (nsIFrame* vScrollbarBox = aFrame->GetScrollbarBox(true)) {
|
if (nsScrollbarFrame* scrollbar = aFrame->GetScrollbarBox(true)) {
|
||||||
nsScrollbarFrame* scrollbar = do_QueryFrame(vScrollbarBox);
|
|
||||||
scrollbar->SetScrollbarMediatorContent(mReflowInput.mFrame->GetContent());
|
scrollbar->SetScrollbarMediatorContent(mReflowInput.mFrame->GetContent());
|
||||||
|
mVScrollbarPrefSize = scrollbar->ScrollbarMinSize();
|
||||||
GetScrollbarMetrics(mBoxState, vScrollbarBox, &mVScrollbarMinSize,
|
|
||||||
&mVScrollbarPrefSize);
|
|
||||||
|
|
||||||
// See above.
|
// See above.
|
||||||
MOZ_ASSERT(aFrame->PresContext()->UseOverlayScrollbars() ||
|
MOZ_ASSERT(scrollbar->IsXULCollapsed() ||
|
||||||
vScrollbarBox->IsXULCollapsed() ||
|
(mVScrollbarPrefSize.width && mVScrollbarPrefSize.height),
|
||||||
(mVScrollbarMinSize.width && mVScrollbarMinSize.height),
|
"Shouldn't have a zero vertical scrollbar-size");
|
||||||
"Shouldn't have a zero vertical min-size");
|
|
||||||
MOZ_ASSERT(mVScrollbarPrefSize.width >= mVScrollbarMinSize.width &&
|
|
||||||
mVScrollbarPrefSize.height >= mVScrollbarMinSize.height,
|
|
||||||
"Scrollbar pref size should be >= min size");
|
|
||||||
} else {
|
} else {
|
||||||
mVScrollbar = ShowScrollbar::Never;
|
mVScrollbar = ShowScrollbar::Never;
|
||||||
mVScrollbarAllowedForScrollingVVInsideLV = false;
|
mVScrollbarAllowedForScrollingVVInsideLV = false;
|
||||||
@@ -615,7 +569,8 @@ ScrollReflowInput::ScrollReflowInput(nsHTMLScrollFrame* aFrame,
|
|||||||
mVScrollbar = ShowScrollbar::Never;
|
mVScrollbar = ShowScrollbar::Never;
|
||||||
mVScrollbarAllowedForScrollingVVInsideLV = false;
|
mVScrollbarAllowedForScrollingVVInsideLV = false;
|
||||||
} else if (const auto& scrollbarGutterStyle =
|
} else if (const auto& scrollbarGutterStyle =
|
||||||
scrollbarStyle->StyleDisplay()->mScrollbarGutter) {
|
scrollbarStyle->StyleDisplay()->mScrollbarGutter;
|
||||||
|
scrollbarGutterStyle && !mOverlayScrollbars) {
|
||||||
const auto stable =
|
const auto stable =
|
||||||
bool(scrollbarGutterStyle & StyleScrollbarGutter::STABLE);
|
bool(scrollbarGutterStyle & StyleScrollbarGutter::STABLE);
|
||||||
const auto bothEdges =
|
const auto bothEdges =
|
||||||
@@ -789,7 +744,7 @@ bool nsHTMLScrollFrame::TryLayout(ScrollReflowInput& aState,
|
|||||||
"TryLayout scrolledRect:%s overflowRect:%s scrollportSize:%s\n",
|
"TryLayout scrolledRect:%s overflowRect:%s scrollportSize:%s\n",
|
||||||
ToString(scrolledRect).c_str(), ToString(overflowRect).c_str(),
|
ToString(scrolledRect).c_str(), ToString(overflowRect).c_str(),
|
||||||
ToString(scrollPortSize).c_str());
|
ToString(scrollPortSize).c_str());
|
||||||
nscoord oneDevPixel = aState.mBoxState.PresContext()->DevPixelsToAppUnits(1);
|
nscoord oneDevPixel = PresContext()->DevPixelsToAppUnits(1);
|
||||||
|
|
||||||
bool showHScrollbar = aAssumeHScroll;
|
bool showHScrollbar = aAssumeHScroll;
|
||||||
bool showVScrollbar = aAssumeVScroll;
|
bool showVScrollbar = aAssumeVScroll;
|
||||||
@@ -853,6 +808,7 @@ bool nsHTMLScrollFrame::TryLayout(ScrollReflowInput& aState,
|
|||||||
|
|
||||||
if (mIsRoot && gfxPlatform::UseDesktopZoomingScrollbars()) {
|
if (mIsRoot && gfxPlatform::UseDesktopZoomingScrollbars()) {
|
||||||
bool vvChanged = true;
|
bool vvChanged = true;
|
||||||
|
const bool overlay = aState.OverlayScrollbars();
|
||||||
// This loop can run at most twice since we can only add a scrollbar once.
|
// This loop can run at most twice since we can only add a scrollbar once.
|
||||||
// At this point we've already decided that this layout is consistent so we
|
// At this point we've already decided that this layout is consistent so we
|
||||||
// will return true. Scrollbars added here never take up layout space even
|
// will return true. Scrollbars added here never take up layout space even
|
||||||
@@ -863,9 +819,12 @@ bool nsHTMLScrollFrame::TryLayout(ScrollReflowInput& aState,
|
|||||||
if (!aState.mShowHScrollbar &&
|
if (!aState.mShowHScrollbar &&
|
||||||
aState.mHScrollbarAllowedForScrollingVVInsideLV) {
|
aState.mHScrollbarAllowedForScrollingVVInsideLV) {
|
||||||
if (ScrollPort().width >= visualViewportSize.width + oneDevPixel &&
|
if (ScrollPort().width >= visualViewportSize.width + oneDevPixel &&
|
||||||
visualViewportSize.width >= aState.HScrollbarMinWidth()) {
|
(overlay ||
|
||||||
|
visualViewportSize.width >= aState.HScrollbarMinWidth())) {
|
||||||
vvChanged = true;
|
vvChanged = true;
|
||||||
visualViewportSize.height -= aState.HScrollbarPrefHeight();
|
if (!overlay) {
|
||||||
|
visualViewportSize.height -= aState.HScrollbarPrefHeight();
|
||||||
|
}
|
||||||
aState.mShowHScrollbar = true;
|
aState.mShowHScrollbar = true;
|
||||||
aState.mOnlyNeedHScrollbarToScrollVVInsideLV = true;
|
aState.mOnlyNeedHScrollbarToScrollVVInsideLV = true;
|
||||||
ROOT_SCROLLBAR_LOG("TryLayout added H scrollbar for VV, VV now %s\n",
|
ROOT_SCROLLBAR_LOG("TryLayout added H scrollbar for VV, VV now %s\n",
|
||||||
@@ -876,9 +835,12 @@ bool nsHTMLScrollFrame::TryLayout(ScrollReflowInput& aState,
|
|||||||
if (!aState.mShowVScrollbar &&
|
if (!aState.mShowVScrollbar &&
|
||||||
aState.mVScrollbarAllowedForScrollingVVInsideLV) {
|
aState.mVScrollbarAllowedForScrollingVVInsideLV) {
|
||||||
if (ScrollPort().height >= visualViewportSize.height + oneDevPixel &&
|
if (ScrollPort().height >= visualViewportSize.height + oneDevPixel &&
|
||||||
visualViewportSize.height >= aState.VScrollbarMinHeight()) {
|
(overlay ||
|
||||||
|
visualViewportSize.height >= aState.VScrollbarMinHeight())) {
|
||||||
vvChanged = true;
|
vvChanged = true;
|
||||||
visualViewportSize.width -= aState.VScrollbarPrefWidth();
|
if (!overlay) {
|
||||||
|
visualViewportSize.width -= aState.VScrollbarPrefWidth();
|
||||||
|
}
|
||||||
aState.mShowVScrollbar = true;
|
aState.mShowVScrollbar = true;
|
||||||
aState.mOnlyNeedVScrollbarToScrollVVInsideLV = true;
|
aState.mOnlyNeedVScrollbarToScrollVVInsideLV = true;
|
||||||
ROOT_SCROLLBAR_LOG("TryLayout added V scrollbar for VV, VV now %s\n",
|
ROOT_SCROLLBAR_LOG("TryLayout added V scrollbar for VV, VV now %s\n",
|
||||||
@@ -1239,13 +1201,17 @@ void nsHTMLScrollFrame::PlaceScrollArea(ScrollReflowInput& aState,
|
|||||||
nscoord nsHTMLScrollFrame::IntrinsicScrollbarGutterSizeAtInlineEdges(
|
nscoord nsHTMLScrollFrame::IntrinsicScrollbarGutterSizeAtInlineEdges(
|
||||||
gfxContext* aRenderingContext) {
|
gfxContext* aRenderingContext) {
|
||||||
const bool isVerticalWM = GetWritingMode().IsVertical();
|
const bool isVerticalWM = GetWritingMode().IsVertical();
|
||||||
nsIFrame* inlineEndScrollbarBox =
|
nsScrollbarFrame* inlineEndScrollbarBox =
|
||||||
isVerticalWM ? mHScrollbarBox : mVScrollbarBox;
|
isVerticalWM ? mHScrollbarBox : mVScrollbarBox;
|
||||||
if (!inlineEndScrollbarBox) {
|
if (!inlineEndScrollbarBox) {
|
||||||
// No scrollbar box frame means no intrinsic size.
|
// No scrollbar box frame means no intrinsic size.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PresContext()->UseOverlayScrollbars()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const auto* styleForScrollbar = nsLayoutUtils::StyleForScrollbar(this);
|
const auto* styleForScrollbar = nsLayoutUtils::StyleForScrollbar(this);
|
||||||
if (styleForScrollbar->StyleUIReset()->ScrollbarWidth() ==
|
if (styleForScrollbar->StyleUIReset()->ScrollbarWidth() ==
|
||||||
StyleScrollbarWidth::None) {
|
StyleScrollbarWidth::None) {
|
||||||
@@ -1268,9 +1234,7 @@ nscoord nsHTMLScrollFrame::IntrinsicScrollbarGutterSizeAtInlineEdges(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No need to worry about reflow depth here since it's just for scrollbars.
|
// No need to worry about reflow depth here since it's just for scrollbars.
|
||||||
nsBoxLayoutState bls(PresContext(), aRenderingContext, 0);
|
nsSize scrollbarPrefSize = inlineEndScrollbarBox->ScrollbarMinSize();
|
||||||
nsSize scrollbarPrefSize;
|
|
||||||
GetScrollbarMetrics(bls, inlineEndScrollbarBox, nullptr, &scrollbarPrefSize);
|
|
||||||
const nscoord scrollbarSize =
|
const nscoord scrollbarSize =
|
||||||
isVerticalWM ? scrollbarPrefSize.height : scrollbarPrefSize.width;
|
isVerticalWM ? scrollbarPrefSize.height : scrollbarPrefSize.width;
|
||||||
const auto bothEdges =
|
const auto bothEdges =
|
||||||
@@ -1608,7 +1572,7 @@ void nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
const nsRect insideBorderArea(
|
const nsRect insideBorderArea(
|
||||||
nsPoint(state.mComputedBorder.left, state.mComputedBorder.top),
|
nsPoint(state.mComputedBorder.left, state.mComputedBorder.top),
|
||||||
layoutSize);
|
layoutSize);
|
||||||
LayoutScrollbars(state.mBoxState, insideBorderArea, oldScrollPort);
|
LayoutScrollbars(state, insideBorderArea, oldScrollPort);
|
||||||
} else {
|
} else {
|
||||||
mSkippedScrollbarLayout = true;
|
mSkippedScrollbarLayout = true;
|
||||||
}
|
}
|
||||||
@@ -1638,7 +1602,7 @@ void nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
// Note that we need to do this after the
|
// Note that we need to do this after the
|
||||||
// UpdateVisualViewportSizeForPotentialScrollbarChange call above because that
|
// UpdateVisualViewportSizeForPotentialScrollbarChange call above because that
|
||||||
// is what updates the visual viewport size and we need it to be up to date.
|
// is what updates the visual viewport size and we need it to be up to date.
|
||||||
if (mIsRoot && !UsesOverlayScrollbars() &&
|
if (mIsRoot && !state.OverlayScrollbars() &&
|
||||||
(didHaveHScrollbar != state.mShowHScrollbar ||
|
(didHaveHScrollbar != state.mShowHScrollbar ||
|
||||||
didHaveVScrollbar != state.mShowVScrollbar ||
|
didHaveVScrollbar != state.mShowVScrollbar ||
|
||||||
didOnlyHScrollbar != mOnlyNeedHScrollbarToScrollVVInsideLV ||
|
didOnlyHScrollbar != mOnlyNeedHScrollbarToScrollVVInsideLV ||
|
||||||
@@ -1878,7 +1842,7 @@ void nsHTMLScrollFrame::ScrollByWhole(nsScrollbarFrame* aScrollbar,
|
|||||||
void nsHTMLScrollFrame::ScrollByLine(nsScrollbarFrame* aScrollbar,
|
void nsHTMLScrollFrame::ScrollByLine(nsScrollbarFrame* aScrollbar,
|
||||||
int32_t aDirection,
|
int32_t aDirection,
|
||||||
ScrollSnapFlags aSnapFlags) {
|
ScrollSnapFlags aSnapFlags) {
|
||||||
bool isHorizontal = aScrollbar->IsXULHorizontal();
|
bool isHorizontal = aScrollbar->IsHorizontal();
|
||||||
nsIntPoint delta;
|
nsIntPoint delta;
|
||||||
if (isHorizontal) {
|
if (isHorizontal) {
|
||||||
const double kScrollMultiplier =
|
const double kScrollMultiplier =
|
||||||
@@ -1916,7 +1880,7 @@ void nsHTMLScrollFrame::RepeatButtonScroll(nsScrollbarFrame* aScrollbar) {
|
|||||||
void nsHTMLScrollFrame::ThumbMoved(nsScrollbarFrame* aScrollbar,
|
void nsHTMLScrollFrame::ThumbMoved(nsScrollbarFrame* aScrollbar,
|
||||||
nscoord aOldPos, nscoord aNewPos) {
|
nscoord aOldPos, nscoord aNewPos) {
|
||||||
MOZ_ASSERT(aScrollbar != nullptr);
|
MOZ_ASSERT(aScrollbar != nullptr);
|
||||||
bool isHorizontal = aScrollbar->IsXULHorizontal();
|
bool isHorizontal = aScrollbar->IsHorizontal();
|
||||||
nsPoint current = GetScrollPosition();
|
nsPoint current = GetScrollPosition();
|
||||||
nsPoint dest = current;
|
nsPoint dest = current;
|
||||||
if (isHorizontal) {
|
if (isHorizontal) {
|
||||||
@@ -1953,7 +1917,7 @@ void nsHTMLScrollFrame::ScrollByUnit(nsScrollbarFrame* aScrollbar,
|
|||||||
ScrollUnit aUnit,
|
ScrollUnit aUnit,
|
||||||
ScrollSnapFlags aSnapFlags) {
|
ScrollSnapFlags aSnapFlags) {
|
||||||
MOZ_ASSERT(aScrollbar != nullptr);
|
MOZ_ASSERT(aScrollbar != nullptr);
|
||||||
bool isHorizontal = aScrollbar->IsXULHorizontal();
|
bool isHorizontal = aScrollbar->IsHorizontal();
|
||||||
nsIntPoint delta;
|
nsIntPoint delta;
|
||||||
if (isHorizontal) {
|
if (isHorizontal) {
|
||||||
delta.x = aDirection;
|
delta.x = aDirection;
|
||||||
@@ -5468,10 +5432,12 @@ void nsHTMLScrollFrame::ReloadChildFrames() {
|
|||||||
if (value.LowerCaseEqualsLiteral("horizontal")) {
|
if (value.LowerCaseEqualsLiteral("horizontal")) {
|
||||||
NS_ASSERTION(!mHScrollbarBox,
|
NS_ASSERTION(!mHScrollbarBox,
|
||||||
"Found multiple horizontal scrollbars?");
|
"Found multiple horizontal scrollbars?");
|
||||||
mHScrollbarBox = frame;
|
mHScrollbarBox = do_QueryFrame(frame);
|
||||||
|
MOZ_ASSERT(mHScrollbarBox, "Not a scrollbar?");
|
||||||
} else {
|
} else {
|
||||||
NS_ASSERTION(!mVScrollbarBox, "Found multiple vertical scrollbars?");
|
NS_ASSERTION(!mVScrollbarBox, "Found multiple vertical scrollbars?");
|
||||||
mVScrollbarBox = frame;
|
mVScrollbarBox = do_QueryFrame(frame);
|
||||||
|
MOZ_ASSERT(mVScrollbarBox, "Not a scrollbar?");
|
||||||
}
|
}
|
||||||
} else if (content->IsXULElement(nsGkAtoms::resizer)) {
|
} else if (content->IsXULElement(nsGkAtoms::resizer)) {
|
||||||
NS_ASSERTION(!mResizerBox, "Found multiple resizers");
|
NS_ASSERTION(!mResizerBox, "Found multiple resizers");
|
||||||
@@ -5817,7 +5783,9 @@ void nsHTMLScrollFrame::CurPosAttributeChangedInternal(nsIContent* aContent,
|
|||||||
//
|
//
|
||||||
// In cases 2 and 3 we do not need to scroll because we're just
|
// In cases 2 and 3 we do not need to scroll because we're just
|
||||||
// updating our scrollbar.
|
// updating our scrollbar.
|
||||||
if (mFrameIsUpdatingScrollbar) return;
|
if (mFrameIsUpdatingScrollbar) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsRect scrollRange = GetVisualScrollRange();
|
nsRect scrollRange = GetVisualScrollRange();
|
||||||
|
|
||||||
@@ -6530,12 +6498,39 @@ static void AdjustOverlappingScrollbars(nsRect& aVRect, nsRect& aHRect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsHTMLScrollFrame::LayoutScrollbars(nsBoxLayoutState& aState,
|
void nsHTMLScrollFrame::LayoutScrollbarPartAtRect(
|
||||||
|
const ScrollReflowInput& aState, ReflowInput& aKidReflowInput,
|
||||||
|
const nsRect& aRect) {
|
||||||
|
nsPresContext* pc = PresContext();
|
||||||
|
nsIFrame* kid = aKidReflowInput.mFrame;
|
||||||
|
const auto wm = kid->GetWritingMode();
|
||||||
|
ReflowOutput desiredSize(wm);
|
||||||
|
MOZ_ASSERT(!wm.IsVertical(),
|
||||||
|
"Scrollbar parts should have writing-mode: initial");
|
||||||
|
MOZ_ASSERT(!wm.IsInlineReversed(),
|
||||||
|
"Scrollbar parts should have writing-mode: initial");
|
||||||
|
// XXX Maybe get a meaningful container size or something. Shouldn't matter
|
||||||
|
// given our asserts above.
|
||||||
|
const nsSize containerSize;
|
||||||
|
aKidReflowInput.SetComputedISize(aRect.Width());
|
||||||
|
aKidReflowInput.SetComputedBSize(aRect.Height());
|
||||||
|
|
||||||
|
const LogicalPoint pos(wm, aRect.TopLeft(), containerSize);
|
||||||
|
const auto flags = ReflowChildFlags::Default;
|
||||||
|
nsReflowStatus status;
|
||||||
|
ReflowOutput kidDesiredSize(wm);
|
||||||
|
ReflowChild(kid, pc, kidDesiredSize, aKidReflowInput, wm, pos, containerSize,
|
||||||
|
flags, status);
|
||||||
|
FinishReflowChild(kid, pc, kidDesiredSize, &aKidReflowInput, wm, pos,
|
||||||
|
containerSize, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsHTMLScrollFrame::LayoutScrollbars(ScrollReflowInput& aState,
|
||||||
const nsRect& aInsideBorderArea,
|
const nsRect& aInsideBorderArea,
|
||||||
const nsRect& aOldScrollPort) {
|
const nsRect& aOldScrollPort) {
|
||||||
NS_ASSERTION(!mSuppressScrollbarUpdate, "This should have been suppressed");
|
NS_ASSERTION(!mSuppressScrollbarUpdate, "This should have been suppressed");
|
||||||
|
|
||||||
bool scrollbarOnLeft = !IsScrollbarOnRight();
|
const bool scrollbarOnLeft = !IsScrollbarOnRight();
|
||||||
const bool overlayScrollbars = UsesOverlayScrollbars();
|
const bool overlayScrollbars = UsesOverlayScrollbars();
|
||||||
const bool overlayScrollBarsOnRoot = overlayScrollbars && mIsRoot;
|
const bool overlayScrollBarsOnRoot = overlayScrollbars && mIsRoot;
|
||||||
const bool showVScrollbar = mVScrollbarBox && mHasVerticalScrollbar;
|
const bool showVScrollbar = mVScrollbarBox && mHasVerticalScrollbar;
|
||||||
@@ -6550,7 +6545,6 @@ void nsHTMLScrollFrame::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||||||
nsPresContext* presContext = mScrolledFrame->PresContext();
|
nsPresContext* presContext = mScrolledFrame->PresContext();
|
||||||
nsRect vRect;
|
nsRect vRect;
|
||||||
if (showVScrollbar) {
|
if (showVScrollbar) {
|
||||||
MOZ_ASSERT(mVScrollbarBox->IsXULBoxFrame(), "Must be a box frame!");
|
|
||||||
vRect.height =
|
vRect.height =
|
||||||
overlayScrollBarsOnRoot ? compositionSize.height : mScrollPort.height;
|
overlayScrollBarsOnRoot ? compositionSize.height : mScrollPort.height;
|
||||||
vRect.y = mScrollPort.y;
|
vRect.y = mScrollPort.y;
|
||||||
@@ -6561,67 +6555,46 @@ void nsHTMLScrollFrame::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||||||
vRect.width = aInsideBorderArea.XMost() - mScrollPort.XMost();
|
vRect.width = aInsideBorderArea.XMost() - mScrollPort.XMost();
|
||||||
vRect.x = mScrollPort.x + compositionSize.width;
|
vRect.x = mScrollPort.x + compositionSize.width;
|
||||||
}
|
}
|
||||||
|
if (overlayScrollbars || mOnlyNeedVScrollbarToScrollVVInsideLV) {
|
||||||
// For overlay scrollbars the margin returned from this GetXULMargin call
|
const nscoord width = aState.VScrollbarPrefWidth();
|
||||||
// is a negative margin that moves the scrollbar from just outside the
|
|
||||||
// scrollport (and hence not visible) to just inside the scrollport (and
|
|
||||||
// hence visible). For non-overlay scrollbars it is a 0 margin.
|
|
||||||
nsMargin margin;
|
|
||||||
mVScrollbarBox->GetXULMargin(margin);
|
|
||||||
|
|
||||||
if (!overlayScrollbars && mOnlyNeedVScrollbarToScrollVVInsideLV) {
|
|
||||||
// There is no space reserved for the layout scrollbar, it is currently
|
// There is no space reserved for the layout scrollbar, it is currently
|
||||||
// not visible because it is positioned just outside the scrollport. But
|
// not visible because it is positioned just outside the scrollport. But
|
||||||
// we know that it needs to be made visible so we shift it back in.
|
// we know that it needs to be made visible so we shift it back in.
|
||||||
nsSize vScrollbarPrefSize(0, 0);
|
vRect.width += width;
|
||||||
GetScrollbarMetrics(aState, mVScrollbarBox, nullptr, &vScrollbarPrefSize);
|
|
||||||
if (scrollbarOnLeft) {
|
if (scrollbarOnLeft) {
|
||||||
margin.right -= vScrollbarPrefSize.width;
|
vRect.x += width;
|
||||||
} else {
|
} else {
|
||||||
margin.left -= vScrollbarPrefSize.width;
|
vRect.x -= width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vRect.Deflate(margin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect hRect;
|
nsRect hRect;
|
||||||
if (showHScrollbar) {
|
if (showHScrollbar) {
|
||||||
MOZ_ASSERT(mHScrollbarBox->IsXULBoxFrame(), "Must be a box frame!");
|
|
||||||
hRect.width =
|
hRect.width =
|
||||||
overlayScrollBarsOnRoot ? compositionSize.width : mScrollPort.width;
|
overlayScrollBarsOnRoot ? compositionSize.width : mScrollPort.width;
|
||||||
hRect.x = mScrollPort.x;
|
hRect.x = mScrollPort.x;
|
||||||
hRect.height = aInsideBorderArea.YMost() - mScrollPort.YMost();
|
hRect.height = aInsideBorderArea.YMost() - mScrollPort.YMost();
|
||||||
hRect.y = mScrollPort.y + compositionSize.height;
|
hRect.y = mScrollPort.y + compositionSize.height;
|
||||||
|
|
||||||
// For overlay scrollbars the margin returned from this GetXULMargin call
|
if (overlayScrollbars || mOnlyNeedHScrollbarToScrollVVInsideLV) {
|
||||||
// is a negative margin that moves the scrollbar from just outside the
|
const nscoord height = aState.HScrollbarPrefHeight();
|
||||||
// scrollport (and hence not visible) to just inside the scrollport (and
|
hRect.height += height;
|
||||||
// hence visible). For non-overlay scrollbars it is a 0 margin.
|
|
||||||
nsMargin margin;
|
|
||||||
mHScrollbarBox->GetXULMargin(margin);
|
|
||||||
|
|
||||||
if (!overlayScrollbars && mOnlyNeedHScrollbarToScrollVVInsideLV) {
|
|
||||||
// There is no space reserved for the layout scrollbar, it is currently
|
// There is no space reserved for the layout scrollbar, it is currently
|
||||||
// not visible because it is positioned just outside the scrollport. But
|
// not visible because it is positioned just outside the scrollport. But
|
||||||
// we know that it needs to be made visible so we shift it back in.
|
// we know that it needs to be made visible so we shift it back in.
|
||||||
nsSize hScrollbarPrefSize(0, 0);
|
hRect.y -= height;
|
||||||
GetScrollbarMetrics(aState, mHScrollbarBox, nullptr, &hScrollbarPrefSize);
|
|
||||||
margin.top -= hScrollbarPrefSize.height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hRect.Deflate(margin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool hasVisualOnlyScrollbarsOnBothDirections =
|
const bool hasVisualOnlyScrollbarsOnBothDirections =
|
||||||
!overlayScrollbars && showHScrollbar &&
|
!overlayScrollbars && showHScrollbar &&
|
||||||
mOnlyNeedHScrollbarToScrollVVInsideLV && showVScrollbar &&
|
mOnlyNeedHScrollbarToScrollVVInsideLV && showVScrollbar &&
|
||||||
mOnlyNeedVScrollbarToScrollVVInsideLV;
|
mOnlyNeedVScrollbarToScrollVVInsideLV;
|
||||||
|
nsPresContext* pc = PresContext();
|
||||||
|
|
||||||
// place the scrollcorner
|
// place the scrollcorner
|
||||||
if (mScrollCornerBox) {
|
if (mScrollCornerBox) {
|
||||||
MOZ_ASSERT(mScrollCornerBox->IsXULBoxFrame(), "Must be a box frame!");
|
|
||||||
|
|
||||||
nsRect r(0, 0, 0, 0);
|
nsRect r(0, 0, 0, 0);
|
||||||
if (scrollbarOnLeft) {
|
if (scrollbarOnLeft) {
|
||||||
// scrollbar (if any) on left
|
// scrollbar (if any) on left
|
||||||
@@ -6653,20 +6626,25 @@ void nsHTMLScrollFrame::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||||||
r.y = mScrollPort.YMost() - r.height;
|
r.y = mScrollPort.YMost() - r.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsBoxFrame::LayoutChildAt(aState, mScrollCornerBox, r);
|
ReflowInput scrollCornerRI(
|
||||||
|
pc, aState.mReflowInput, mScrollCornerBox,
|
||||||
|
LogicalSize(mScrollCornerBox->GetWritingMode(), r.Size()));
|
||||||
|
LayoutScrollbarPartAtRect(aState, scrollCornerRI, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mResizerBox) {
|
if (mResizerBox) {
|
||||||
// If a resizer is present, get its size.
|
// If a resizer is present, get its size.
|
||||||
//
|
//
|
||||||
// TODO(emilio): Should this really account for scrollbar-width?
|
// TODO(emilio): Should this really account for scrollbar-width?
|
||||||
nsPresContext* pc = aState.PresContext();
|
|
||||||
auto scrollbarWidth = nsLayoutUtils::StyleForScrollbar(this)
|
auto scrollbarWidth = nsLayoutUtils::StyleForScrollbar(this)
|
||||||
->StyleUIReset()
|
->StyleUIReset()
|
||||||
->ScrollbarWidth();
|
->ScrollbarWidth();
|
||||||
auto scrollbarSize = pc->Theme()->GetScrollbarSize(pc, scrollbarWidth,
|
auto scrollbarSize = pc->Theme()->GetScrollbarSize(pc, scrollbarWidth,
|
||||||
nsITheme::Overlay::No);
|
nsITheme::Overlay::No);
|
||||||
nsSize resizerMinSize = mResizerBox->GetXULMinSize(aState);
|
ReflowInput resizerRI(pc, aState.mReflowInput, mResizerBox,
|
||||||
|
LogicalSize(mResizerBox->GetWritingMode()));
|
||||||
|
nsSize resizerMinSize = {resizerRI.ComputedMinWidth(),
|
||||||
|
resizerRI.ComputedMinHeight()};
|
||||||
|
|
||||||
nsRect r;
|
nsRect r;
|
||||||
nscoord vScrollbarWidth = pc->DevPixelsToAppUnits(scrollbarSize);
|
nscoord vScrollbarWidth = pc->DevPixelsToAppUnits(scrollbarSize);
|
||||||
@@ -6680,7 +6658,7 @@ void nsHTMLScrollFrame::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||||||
std::max(std::max(r.height, hScrollbarHeight), resizerMinSize.height);
|
std::max(std::max(r.height, hScrollbarHeight), resizerMinSize.height);
|
||||||
r.y = aInsideBorderArea.YMost() - r.height;
|
r.y = aInsideBorderArea.YMost() - r.height;
|
||||||
|
|
||||||
nsBoxFrame::LayoutChildAt(aState, mResizerBox, r);
|
LayoutScrollbarPartAtRect(aState, resizerRI, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that AdjustScrollbarRectForResizer has to be called after the
|
// Note that AdjustScrollbarRectForResizer has to be called after the
|
||||||
@@ -6702,10 +6680,16 @@ void nsHTMLScrollFrame::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||||||
AdjustOverlappingScrollbars(vRect, hRect);
|
AdjustOverlappingScrollbars(vRect, hRect);
|
||||||
}
|
}
|
||||||
if (mVScrollbarBox) {
|
if (mVScrollbarBox) {
|
||||||
nsBoxFrame::LayoutChildAt(aState, mVScrollbarBox, vRect);
|
ReflowInput vScrollbarRI(
|
||||||
|
pc, aState.mReflowInput, mVScrollbarBox,
|
||||||
|
LogicalSize(mVScrollbarBox->GetWritingMode(), vRect.Size()));
|
||||||
|
LayoutScrollbarPartAtRect(aState, vScrollbarRI, vRect);
|
||||||
}
|
}
|
||||||
if (mHScrollbarBox) {
|
if (mHScrollbarBox) {
|
||||||
nsBoxFrame::LayoutChildAt(aState, mHScrollbarBox, hRect);
|
ReflowInput hScrollbarRI(
|
||||||
|
pc, aState.mReflowInput, mHScrollbarBox,
|
||||||
|
LogicalSize(mHScrollbarBox->GetWritingMode(), hRect.Size()));
|
||||||
|
LayoutScrollbarPartAtRect(aState, hScrollbarRI, hRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// may need to update fixed position children of the viewport,
|
// may need to update fixed position children of the viewport,
|
||||||
@@ -6720,7 +6704,7 @@ void nsHTMLScrollFrame::LayoutScrollbars(nsBoxLayoutState& aState,
|
|||||||
// post reflow callback to modify scrollbar attributes
|
// post reflow callback to modify scrollbar attributes
|
||||||
mUpdateScrollbarAttributes = true;
|
mUpdateScrollbarAttributes = true;
|
||||||
if (!mPostedReflowCallback) {
|
if (!mPostedReflowCallback) {
|
||||||
aState.PresShell()->PostReflowCallback(this);
|
PresShell()->PostReflowCallback(this);
|
||||||
mPostedReflowCallback = true;
|
mPostedReflowCallback = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ class nsHTMLScrollFrame : public nsContainerFrame,
|
|||||||
nscoord aNewPos) final;
|
nscoord aNewPos) final;
|
||||||
void ScrollbarReleased(nsScrollbarFrame* aScrollbar) final;
|
void ScrollbarReleased(nsScrollbarFrame* aScrollbar) final;
|
||||||
void VisibilityChanged(bool aVisible) final {}
|
void VisibilityChanged(bool aVisible) final {}
|
||||||
nsIFrame* GetScrollbarBox(bool aVertical) final {
|
nsScrollbarFrame* GetScrollbarBox(bool aVertical) final {
|
||||||
return aVertical ? mVScrollbarBox : mHScrollbarBox;
|
return aVertical ? mVScrollbarBox : mHScrollbarBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,10 +717,13 @@ class nsHTMLScrollFrame : public nsContainerFrame,
|
|||||||
void AdjustScrollbarRectForResizer(
|
void AdjustScrollbarRectForResizer(
|
||||||
nsIFrame* aFrame, nsPresContext* aPresContext, nsRect& aRect,
|
nsIFrame* aFrame, nsPresContext* aPresContext, nsRect& aRect,
|
||||||
bool aHasResizer, mozilla::layers::ScrollDirection aDirection);
|
bool aHasResizer, mozilla::layers::ScrollDirection aDirection);
|
||||||
void LayoutScrollbars(nsBoxLayoutState& aState,
|
void LayoutScrollbars(ScrollReflowInput& aState,
|
||||||
const nsRect& aInsideBorderArea,
|
const nsRect& aInsideBorderArea,
|
||||||
const nsRect& aOldScrollPort);
|
const nsRect& aOldScrollPort);
|
||||||
|
|
||||||
|
void LayoutScrollbarPartAtRect(const ScrollReflowInput&,
|
||||||
|
ReflowInput& aKidReflowInput, const nsRect&);
|
||||||
|
|
||||||
bool IsAlwaysActive() const;
|
bool IsAlwaysActive() const;
|
||||||
void MarkRecentlyScrolled();
|
void MarkRecentlyScrolled();
|
||||||
void MarkNotRecentlyScrolled();
|
void MarkNotRecentlyScrolled();
|
||||||
@@ -783,8 +786,8 @@ class nsHTMLScrollFrame : public nsContainerFrame,
|
|||||||
RefPtr<ScrollEndEvent> mScrollEndEvent;
|
RefPtr<ScrollEndEvent> mScrollEndEvent;
|
||||||
nsRevocableEventPtr<AsyncScrollPortEvent> mAsyncScrollPortEvent;
|
nsRevocableEventPtr<AsyncScrollPortEvent> mAsyncScrollPortEvent;
|
||||||
nsRevocableEventPtr<ScrolledAreaEvent> mScrolledAreaEvent;
|
nsRevocableEventPtr<ScrolledAreaEvent> mScrolledAreaEvent;
|
||||||
nsIFrame* mHScrollbarBox;
|
nsScrollbarFrame* mHScrollbarBox;
|
||||||
nsIFrame* mVScrollbarBox;
|
nsScrollbarFrame* mVScrollbarBox;
|
||||||
nsIFrame* mScrolledFrame;
|
nsIFrame* mScrolledFrame;
|
||||||
nsIFrame* mScrollCornerBox;
|
nsIFrame* mScrollCornerBox;
|
||||||
nsIFrame* mResizerBox;
|
nsIFrame* mResizerBox;
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ void nsInlineFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
|
|||||||
DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
|
DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
|
||||||
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
|
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
|
||||||
|
|
||||||
if (nullptr == aReflowInput.mLineLayout) {
|
if (!aReflowInput.mLineLayout) {
|
||||||
NS_ERROR("must have non-null aReflowInput.mLineLayout");
|
NS_ERROR("must have non-null aReflowInput.mLineLayout");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,24 +21,15 @@
|
|||||||
-moz-font-smoothing-background-color: initial;
|
-moz-font-smoothing-background-color: initial;
|
||||||
-moz-min-font-size-ratio: initial;
|
-moz-min-font-size-ratio: initial;
|
||||||
-moz-box-collapse: initial;
|
-moz-box-collapse: initial;
|
||||||
|
-moz-box-layout: initial;
|
||||||
/* -moz-box-layout: initial; is not included in 'all' but it's not needed,
|
|
||||||
* because we explicitly specify it below for the top level scrollbar parts
|
|
||||||
* (and it inherits through to the rest).
|
|
||||||
*/
|
|
||||||
|
|
||||||
math-depth: initial;
|
math-depth: initial;
|
||||||
/* As long as inert implies pointer-events: none as it does now, we're
|
/* As long as inert implies pointer-events: none as it does now, we're
|
||||||
* good. */
|
* good. */
|
||||||
-moz-inert: initial;
|
-moz-inert: initial;
|
||||||
|
|
||||||
/* Using initial is not sufficient for direction, since its initial value can
|
/* direction: initial is not sufficient, since its initial value can depend
|
||||||
* depend on the document's language.
|
* on the document's language. But we specify ltr explicitly below */
|
||||||
*
|
|
||||||
* LTR is what we want for all scrollbar parts anyway, so that e.g. we don't
|
|
||||||
* reverse the rendering of a horizontal scrollbar.
|
|
||||||
*/
|
|
||||||
direction: ltr;
|
|
||||||
|
|
||||||
/* Similarly for font properties, whose initial values depend on the
|
/* Similarly for font properties, whose initial values depend on the
|
||||||
* document's language. Scrollbar parts don't have any text or rely on
|
* document's language. Scrollbar parts don't have any text or rely on
|
||||||
@@ -69,16 +60,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
scrollbar, scrollbarbutton, scrollcorner, slider, thumb, resizer {
|
scrollbar, scrollbarbutton, scrollcorner, slider, thumb, resizer {
|
||||||
/* Force legacy XUL layout for now on scrollbars / resizers and descendants,
|
/* We need a display value that doesn't get blockified to preserve the
|
||||||
* as nsHTMLScrollFrame relies on that (and nsScrollbarFrame is a XUL frame
|
* scrollbar sizing asserts. In practice it doesn't matter since these get
|
||||||
* anyways).
|
* special frames */
|
||||||
*
|
display: block;
|
||||||
* TODO: Eventually we should rewrite scrollbars so that they don't use XUL
|
|
||||||
* layout.
|
|
||||||
*/
|
|
||||||
-moz-box-layout: legacy;
|
|
||||||
display: -moz-box;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
/* Our scrollbar layout uses physical coordinates, we wouldn't want an
|
||||||
|
* horizontal scrollbar to flip in rtl for example. */
|
||||||
|
direction: ltr;
|
||||||
|
writing-mode: initial;
|
||||||
|
|
||||||
-moz-user-focus: ignore;
|
-moz-user-focus: ignore;
|
||||||
/* Prevent -moz-user-modify declaration from designmode.css having an effect. */
|
/* Prevent -moz-user-modify declaration from designmode.css having an effect. */
|
||||||
-moz-user-modify: initial;
|
-moz-user-modify: initial;
|
||||||
@@ -96,11 +88,6 @@ resizer {
|
|||||||
appearance: auto;
|
appearance: auto;
|
||||||
-moz-default-appearance: resizer;
|
-moz-default-appearance: resizer;
|
||||||
|
|
||||||
/* native resizer should never flip on its own;
|
|
||||||
we will flip it (or the SVG background) with CSS transform below. */
|
|
||||||
direction: ltr;
|
|
||||||
writing-mode: initial;
|
|
||||||
|
|
||||||
background: url("chrome://global/skin/icons/resizer.svg") no-repeat;
|
background: url("chrome://global/skin/icons/resizer.svg") no-repeat;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
cursor: se-resize;
|
cursor: se-resize;
|
||||||
@@ -147,14 +134,10 @@ resizer[dir="topright"] {
|
|||||||
thumb {
|
thumb {
|
||||||
appearance: auto;
|
appearance: auto;
|
||||||
-moz-default-appearance: scrollbarthumb-horizontal;
|
-moz-default-appearance: scrollbarthumb-horizontal;
|
||||||
-moz-box-flex: 1;
|
|
||||||
-moz-box-align: center;
|
|
||||||
-moz-box-pack: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thumb[orient="vertical"] {
|
thumb[orient="vertical"] {
|
||||||
-moz-default-appearance: scrollbarthumb-vertical;
|
-moz-default-appearance: scrollbarthumb-vertical;
|
||||||
-moz-box-orient: vertical;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollbar[disabled="true"] thumb {
|
scrollbar[disabled="true"] thumb {
|
||||||
@@ -175,7 +158,6 @@ scrollbar {
|
|||||||
|
|
||||||
scrollbar[orient="vertical"] {
|
scrollbar[orient="vertical"] {
|
||||||
-moz-default-appearance: scrollbar-vertical;
|
-moz-default-appearance: scrollbar-vertical;
|
||||||
-moz-box-orient: vertical;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollbar[root="true"] {
|
scrollbar[root="true"] {
|
||||||
@@ -197,12 +179,10 @@ scrollbar[root="true"] {
|
|||||||
slider {
|
slider {
|
||||||
appearance: auto;
|
appearance: auto;
|
||||||
-moz-default-appearance: scrollbartrack-horizontal;
|
-moz-default-appearance: scrollbartrack-horizontal;
|
||||||
-moz-box-flex: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
slider[orient="vertical"] {
|
slider[orient="vertical"] {
|
||||||
-moz-default-appearance: scrollbartrack-vertical;
|
-moz-default-appearance: scrollbartrack-vertical;
|
||||||
-moz-box-orient: vertical;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollbarbutton {
|
scrollbarbutton {
|
||||||
|
|||||||
@@ -13,18 +13,21 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1367568
|
|||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug 1367568</a>
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug 1367568</a>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<!-- Some fixed-width divs that we shouldn't have to reflow when the viewport
|
<!-- Some fixed-width divs that we shouldn't have to reflow when the viewport
|
||||||
changes: -->
|
changes. More than 5 so that our leeway for scrollbar parts doesn't
|
||||||
<div style="width: 100px">
|
accidentally cause the test to pass -->
|
||||||
fixed-width
|
<div style="width: 100px">fixed-width <div>(child)</div></div>
|
||||||
<div>(child)</div>
|
<div style="width: 100px">fixed-width <div>(child)</div></div>
|
||||||
</div>
|
<div style="width: 100px">fixed-width <div>(child)</div></div>
|
||||||
|
<div style="width: 100px">fixed-width <div>(child)</div></div>
|
||||||
|
<div style="width: 100px">fixed-width <div>(child)</div></div>
|
||||||
|
<div style="width: 100px">fixed-width <div>(child)</div></div>
|
||||||
<div style="position: absolute; width: 150px">
|
<div style="position: absolute; width: 150px">
|
||||||
abs-fixed-width
|
abs-fixed-width
|
||||||
<div>(child)</div>
|
<div>(child)</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script type="application/javascript">
|
<script>
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/** Test for Bug 1367568 **/
|
/** Test for Bug 1367568 **/
|
||||||
@@ -77,9 +80,11 @@ function main() {
|
|||||||
ok(count > 0,
|
ok(count > 0,
|
||||||
"Should reflow some frames when 'width' & 'height' change");
|
"Should reflow some frames when 'width' & 'height' change");
|
||||||
|
|
||||||
|
const scrollbarsHaveButtons = navigator.platform.includes("Win");
|
||||||
|
// This is to allow for reflowing scrollbar parts themselves.
|
||||||
|
const scrollbarReflows = scrollbarsHaveButtons ? 5 : 2;
|
||||||
// Expected maximum number of frames reflowed for "overflow" changes
|
// Expected maximum number of frames reflowed for "overflow" changes
|
||||||
// (+2 is to allow for reflowing scrollbars themselves):
|
const expectedMax = count + scrollbarReflows;
|
||||||
const expectedMax = count + 2;
|
|
||||||
|
|
||||||
// Shared ending for messages in all ok() checks below:
|
// Shared ending for messages in all ok() checks below:
|
||||||
const messageSuffix =
|
const messageSuffix =
|
||||||
|
|||||||
37
layout/xul/SimpleXULLeafFrame.cpp
Normal file
37
layout/xul/SimpleXULLeafFrame.cpp
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "SimpleXULLeafFrame.h"
|
||||||
|
#include "mozilla/PresShell.h"
|
||||||
|
|
||||||
|
nsIFrame* NS_NewSimpleXULLeafFrame(mozilla::PresShell* aPresShell,
|
||||||
|
mozilla::ComputedStyle* aStyle) {
|
||||||
|
return new (aPresShell)
|
||||||
|
mozilla::SimpleXULLeafFrame(aStyle, aPresShell->GetPresContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
NS_IMPL_FRAMEARENA_HELPERS(SimpleXULLeafFrame)
|
||||||
|
|
||||||
|
void SimpleXULLeafFrame::Reflow(nsPresContext* aPresContext,
|
||||||
|
ReflowOutput& aDesiredSize,
|
||||||
|
const ReflowInput& aReflowInput,
|
||||||
|
nsReflowStatus& aStatus) {
|
||||||
|
MarkInReflow();
|
||||||
|
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
|
||||||
|
const auto wm = GetWritingMode();
|
||||||
|
const auto& bp = aReflowInput.ComputedLogicalBorderPadding(wm);
|
||||||
|
aDesiredSize.ISize(wm) = bp.IStartEnd(wm) + aReflowInput.ComputedISize();
|
||||||
|
aDesiredSize.BSize(wm) =
|
||||||
|
bp.BStartEnd(wm) + (aReflowInput.ComputedBSize() == NS_UNCONSTRAINEDSIZE
|
||||||
|
? aReflowInput.ComputedMinBSize()
|
||||||
|
: aReflowInput.ComputedBSize());
|
||||||
|
aDesiredSize.SetOverflowAreasToDesiredBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
46
layout/xul/SimpleXULLeafFrame.h
Normal file
46
layout/xul/SimpleXULLeafFrame.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
// A simple frame class for XUL frames that are leafs on the tree but need
|
||||||
|
// background / border painting, and for some reason or another need special
|
||||||
|
// code (like event handling code) which we haven't ported to the DOM.
|
||||||
|
//
|
||||||
|
// This should generally not be used for new frame classes.
|
||||||
|
|
||||||
|
#ifndef mozilla_SimpleXULLeafFrame_h
|
||||||
|
#define mozilla_SimpleXULLeafFrame_h
|
||||||
|
|
||||||
|
#include "nsLeafFrame.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
// Shared class for thumb and scrollbar buttons.
|
||||||
|
class SimpleXULLeafFrame : public nsLeafFrame {
|
||||||
|
public:
|
||||||
|
NS_DECL_FRAMEARENA_HELPERS(SimpleXULLeafFrame)
|
||||||
|
|
||||||
|
// TODO: Look at appearance instead maybe?
|
||||||
|
nscoord GetIntrinsicISize() override { return 0; }
|
||||||
|
nscoord GetIntrinsicBSize() override { return 0; }
|
||||||
|
|
||||||
|
void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
|
||||||
|
const ReflowInput& aReflowInput,
|
||||||
|
nsReflowStatus& aStatus) override;
|
||||||
|
explicit SimpleXULLeafFrame(ComputedStyle* aStyle,
|
||||||
|
nsPresContext* aPresContext, ClassID aClassID)
|
||||||
|
: nsLeafFrame(aStyle, aPresContext, aClassID) {}
|
||||||
|
|
||||||
|
explicit SimpleXULLeafFrame(ComputedStyle* aStyle,
|
||||||
|
nsPresContext* aPresContext)
|
||||||
|
: SimpleXULLeafFrame(aStyle, aPresContext, kClassID) {}
|
||||||
|
|
||||||
|
friend nsIFrame* NS_NewSimpleXULLeafFrame(mozilla::PresShell* aPresShell,
|
||||||
|
ComputedStyle* aStyle);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -34,6 +34,7 @@ UNIFIED_SOURCES += [
|
|||||||
"nsTextBoxFrame.cpp",
|
"nsTextBoxFrame.cpp",
|
||||||
"nsXULPopupManager.cpp",
|
"nsXULPopupManager.cpp",
|
||||||
"nsXULTooltipListener.cpp",
|
"nsXULTooltipListener.cpp",
|
||||||
|
"SimpleXULLeafFrame.cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
DIRS += ["tree"]
|
DIRS += ["tree"]
|
||||||
|
|||||||
@@ -884,34 +884,3 @@ nsresult nsBoxFrame::LayoutChildAt(nsBoxLayoutState& aState, nsIFrame* aBox,
|
|||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent, nsPoint& aPoint) {
|
|
||||||
LayoutDeviceIntPoint refPoint;
|
|
||||||
bool res = GetEventPoint(aEvent, refPoint);
|
|
||||||
aPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, refPoint,
|
|
||||||
RelativeTo{this});
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nsBoxFrame::GetEventPoint(WidgetGUIEvent* aEvent,
|
|
||||||
LayoutDeviceIntPoint& aPoint) {
|
|
||||||
NS_ENSURE_TRUE(aEvent, false);
|
|
||||||
|
|
||||||
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
|
|
||||||
if (touchEvent) {
|
|
||||||
// return false if there is more than one touch on the page, or if
|
|
||||||
// we can't find a touch point
|
|
||||||
if (touchEvent->mTouches.Length() != 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dom::Touch* touch = touchEvent->mTouches.SafeElementAt(0);
|
|
||||||
if (!touch) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
aPoint = touch->mRefPoint;
|
|
||||||
} else {
|
|
||||||
aPoint = aEvent->mRefPoint;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -154,14 +154,6 @@ class nsBoxFrame : public nsContainerFrame {
|
|||||||
|
|
||||||
nsCOMPtr<nsBoxLayout> mLayoutManager;
|
nsCOMPtr<nsBoxLayout> mLayoutManager;
|
||||||
|
|
||||||
// Get the point associated with this event. Returns true if a single valid
|
|
||||||
// point was found. Otherwise false.
|
|
||||||
bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, nsPoint& aPoint);
|
|
||||||
// Gets the event coordinates relative to the widget offset associated with
|
|
||||||
// this frame. Return true if a single valid point was found.
|
|
||||||
bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent,
|
|
||||||
mozilla::LayoutDeviceIntPoint& aPoint);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CacheAttributes();
|
void CacheAttributes();
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class nsIScrollbarMediator : public nsQueryFrame {
|
|||||||
* Obtain the frame for the horizontal or vertical scrollbar, or null
|
* Obtain the frame for the horizontal or vertical scrollbar, or null
|
||||||
* if there is no such box.
|
* if there is no such box.
|
||||||
*/
|
*/
|
||||||
virtual nsIFrame* GetScrollbarBox(bool aVertical) = 0;
|
virtual nsScrollbarFrame* GetScrollbarBox(bool aVertical) = 0;
|
||||||
/**
|
/**
|
||||||
* Show or hide scrollbars on 2 fingers touch.
|
* Show or hide scrollbars on 2 fingers touch.
|
||||||
* Subclasses should call their ScrollbarActivity's corresponding methods.
|
* Subclasses should call their ScrollbarActivity's corresponding methods.
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ nsIFrame* NS_NewScrollbarButtonFrame(PresShell* aPresShell,
|
|||||||
return new (aPresShell)
|
return new (aPresShell)
|
||||||
nsScrollbarButtonFrame(aStyle, aPresShell->GetPresContext());
|
nsScrollbarButtonFrame(aStyle, aPresShell->GetPresContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarButtonFrame)
|
NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarButtonFrame)
|
||||||
|
|
||||||
nsresult nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext,
|
nsresult nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
@@ -79,7 +78,7 @@ nsresult nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
return SimpleXULLeafFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext,
|
bool nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext,
|
||||||
@@ -270,5 +269,5 @@ void nsScrollbarButtonFrame::DestroyFrom(nsIFrame* aDestructRoot,
|
|||||||
// Ensure our repeat service isn't going... it's possible that a scrollbar can
|
// Ensure our repeat service isn't going... it's possible that a scrollbar can
|
||||||
// disappear out from under you while you're in the process of scrolling.
|
// disappear out from under you while you're in the process of scrolling.
|
||||||
StopRepeat();
|
StopRepeat();
|
||||||
nsBoxFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
|
SimpleXULLeafFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,25 +14,26 @@
|
|||||||
#ifndef nsScrollbarButtonFrame_h___
|
#ifndef nsScrollbarButtonFrame_h___
|
||||||
#define nsScrollbarButtonFrame_h___
|
#define nsScrollbarButtonFrame_h___
|
||||||
|
|
||||||
|
#include "SimpleXULLeafFrame.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "nsBoxFrame.h"
|
#include "nsLeafFrame.h"
|
||||||
#include "nsRepeatService.h"
|
#include "nsRepeatService.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class PresShell;
|
class PresShell;
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
class nsScrollbarButtonFrame final : public nsBoxFrame {
|
class nsScrollbarButtonFrame final : public mozilla::SimpleXULLeafFrame {
|
||||||
public:
|
public:
|
||||||
NS_DECL_FRAMEARENA_HELPERS(nsScrollbarButtonFrame)
|
NS_DECL_FRAMEARENA_HELPERS(nsScrollbarButtonFrame)
|
||||||
|
|
||||||
explicit nsScrollbarButtonFrame(ComputedStyle* aStyle,
|
explicit nsScrollbarButtonFrame(ComputedStyle* aStyle,
|
||||||
nsPresContext* aPresContext)
|
nsPresContext* aPresContext)
|
||||||
: nsBoxFrame(aStyle, aPresContext, kClassID), mCursorOnThis(false) {}
|
: mozilla::SimpleXULLeafFrame(aStyle, aPresContext, kClassID) {}
|
||||||
|
|
||||||
// Overrides
|
// Overrides
|
||||||
virtual void DestroyFrom(nsIFrame* aDestructRoot,
|
void DestroyFrom(nsIFrame* aDestructRoot,
|
||||||
PostDestroyData& aPostDestroyData) override;
|
PostDestroyData& aPostDestroyData) override;
|
||||||
|
|
||||||
friend nsIFrame* NS_NewScrollbarButtonFrame(mozilla::PresShell* aPresShell,
|
friend nsIFrame* NS_NewScrollbarButtonFrame(mozilla::PresShell* aPresShell,
|
||||||
ComputedStyle* aStyle);
|
ComputedStyle* aStyle);
|
||||||
@@ -79,7 +80,7 @@ class nsScrollbarButtonFrame final : public nsBoxFrame {
|
|||||||
static_cast<nsScrollbarButtonFrame*>(aData)->Notify();
|
static_cast<nsScrollbarButtonFrame*>(aData)->Notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mCursorOnThis;
|
bool mCursorOnThis = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "nsIScrollbarMediator.h"
|
#include "nsIScrollbarMediator.h"
|
||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
|
#include "nsLayoutUtils.h"
|
||||||
#include "mozilla/LookAndFeel.h"
|
#include "mozilla/LookAndFeel.h"
|
||||||
#include "mozilla/PresShell.h"
|
#include "mozilla/PresShell.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
@@ -44,11 +45,11 @@ NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarFrame)
|
|||||||
NS_QUERYFRAME_HEAD(nsScrollbarFrame)
|
NS_QUERYFRAME_HEAD(nsScrollbarFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsScrollbarFrame)
|
NS_QUERYFRAME_ENTRY(nsScrollbarFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
|
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||||
|
|
||||||
void nsScrollbarFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
void nsScrollbarFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
||||||
nsIFrame* aPrevInFlow) {
|
nsIFrame* aPrevInFlow) {
|
||||||
nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
|
nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
|
||||||
|
|
||||||
// We want to be a reflow root since we use reflows to move the
|
// We want to be a reflow root since we use reflows to move the
|
||||||
// slider. Any reflow inside the scrollbar frame will be a reflow to
|
// slider. Any reflow inside the scrollbar frame will be a reflow to
|
||||||
@@ -64,42 +65,112 @@ void nsScrollbarFrame::DestroyFrom(nsIFrame* aDestructRoot,
|
|||||||
aPostDestroyData.AddAnonymousContent(mSlider.forget());
|
aPostDestroyData.AddAnonymousContent(mSlider.forget());
|
||||||
aPostDestroyData.AddAnonymousContent(mUpBottomButton.forget());
|
aPostDestroyData.AddAnonymousContent(mUpBottomButton.forget());
|
||||||
aPostDestroyData.AddAnonymousContent(mDownBottomButton.forget());
|
aPostDestroyData.AddAnonymousContent(mDownBottomButton.forget());
|
||||||
nsBoxFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
|
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsScrollbarFrame::Reflow(nsPresContext* aPresContext,
|
void nsScrollbarFrame::Reflow(nsPresContext* aPresContext,
|
||||||
ReflowOutput& aDesiredSize,
|
ReflowOutput& aDesiredSize,
|
||||||
const ReflowInput& aReflowInput,
|
const ReflowInput& aReflowInput,
|
||||||
nsReflowStatus& aStatus) {
|
nsReflowStatus& aStatus) {
|
||||||
|
MarkInReflow();
|
||||||
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
|
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
|
||||||
|
|
||||||
nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowInput, aStatus);
|
// We always take all the space we're given, and our track size in the other
|
||||||
|
// axis.
|
||||||
|
const bool horizontal = IsHorizontal();
|
||||||
|
const auto wm = GetWritingMode();
|
||||||
|
const auto minSize = aReflowInput.ComputedMinSize();
|
||||||
|
|
||||||
// nsGfxScrollFrame may have told us to shrink to nothing. If so, make sure
|
aDesiredSize.ISize(wm) = aReflowInput.ComputedISize();
|
||||||
// our desired size agrees.
|
aDesiredSize.BSize(wm) = [&] {
|
||||||
if (aReflowInput.AvailableWidth() == 0) {
|
if (aReflowInput.ComputedBSize() != NS_UNCONSTRAINEDSIZE) {
|
||||||
aDesiredSize.Width() = 0;
|
return aReflowInput.ComputedBSize();
|
||||||
}
|
}
|
||||||
if (aReflowInput.AvailableHeight() == 0) {
|
// We don't want to change our size during incremental reflow, see the
|
||||||
aDesiredSize.Height() = 0;
|
// reflow root comment in init.
|
||||||
|
if (!aReflowInput.mParentReflowInput) {
|
||||||
|
return GetLogicalSize(wm).BSize(wm);
|
||||||
|
}
|
||||||
|
return minSize.BSize(wm);
|
||||||
|
}();
|
||||||
|
|
||||||
|
const nsSize containerSize = aDesiredSize.PhysicalSize();
|
||||||
|
const LogicalSize totalAvailSize = aDesiredSize.Size(wm);
|
||||||
|
LogicalPoint nextKidPos(wm);
|
||||||
|
|
||||||
|
MOZ_ASSERT(!wm.IsVertical());
|
||||||
|
const bool movesInInlineDirection = horizontal;
|
||||||
|
|
||||||
|
// Layout our kids left to right / top to bottom.
|
||||||
|
for (nsIFrame* kid : mFrames) {
|
||||||
|
MOZ_ASSERT(!kid->GetWritingMode().IsOrthogonalTo(wm),
|
||||||
|
"We don't expect orthogonal scrollbar parts");
|
||||||
|
const bool isSlider = kid->GetContent() == mSlider;
|
||||||
|
LogicalSize availSize = totalAvailSize;
|
||||||
|
{
|
||||||
|
// Assume we'll consume the same size before and after the slider. This is
|
||||||
|
// not a technically correct assumption if we have weird scrollbar button
|
||||||
|
// setups, but those will be going away, see bug 1824254.
|
||||||
|
const int32_t factor = isSlider ? 2 : 1;
|
||||||
|
if (movesInInlineDirection) {
|
||||||
|
availSize.ISize(wm) =
|
||||||
|
std::max(0, totalAvailSize.ISize(wm) - nextKidPos.I(wm) * factor);
|
||||||
|
} else {
|
||||||
|
availSize.BSize(wm) =
|
||||||
|
std::max(0, totalAvailSize.BSize(wm) - nextKidPos.B(wm) * factor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReflowInput kidRI(aPresContext, aReflowInput, kid, availSize);
|
||||||
|
if (isSlider) {
|
||||||
|
// We want for the slider to take all the remaining available space.
|
||||||
|
kidRI.SetComputedISize(availSize.ISize(wm));
|
||||||
|
kidRI.SetComputedBSize(availSize.BSize(wm));
|
||||||
|
} else if (movesInInlineDirection) {
|
||||||
|
// Otherwise we want all the space in the axis we're not advancing in, and
|
||||||
|
// the default / minimum size on the other axis.
|
||||||
|
kidRI.SetComputedBSize(availSize.BSize(wm));
|
||||||
|
} else {
|
||||||
|
kidRI.SetComputedISize(availSize.ISize(wm));
|
||||||
|
}
|
||||||
|
|
||||||
|
ReflowOutput kidDesiredSize(wm);
|
||||||
|
nsReflowStatus status;
|
||||||
|
const auto flags = ReflowChildFlags::Default;
|
||||||
|
ReflowChild(kid, aPresContext, kidDesiredSize, kidRI, wm, nextKidPos,
|
||||||
|
containerSize, flags, status);
|
||||||
|
// We haven't seen the slider yet, we can advance
|
||||||
|
FinishReflowChild(kid, aPresContext, kidDesiredSize, &kidRI, wm, nextKidPos,
|
||||||
|
containerSize, flags);
|
||||||
|
if (movesInInlineDirection) {
|
||||||
|
nextKidPos.I(wm) += kidDesiredSize.ISize(wm);
|
||||||
|
} else {
|
||||||
|
nextKidPos.B(wm) += kidDesiredSize.BSize(wm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aDesiredSize.SetOverflowAreasToDesiredBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsScrollbarFrame::AttributeChanged(int32_t aNameSpaceID,
|
nsresult nsScrollbarFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||||
nsAtom* aAttribute,
|
nsAtom* aAttribute,
|
||||||
int32_t aModType) {
|
int32_t aModType) {
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
||||||
|
|
||||||
// Update value in our children
|
// Update value in our children
|
||||||
UpdateChildrenAttributeValue(aAttribute, true);
|
UpdateChildrenAttributeValue(aAttribute, true);
|
||||||
|
|
||||||
// if the current position changes, notify any nsGfxScrollFrame
|
// if the current position changes, notify any nsGfxScrollFrame
|
||||||
// parent we may have
|
// parent we may have
|
||||||
if (aAttribute != nsGkAtoms::curpos) return rv;
|
if (aAttribute != nsGkAtoms::curpos) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
nsIScrollableFrame* scrollable = do_QueryFrame(GetParent());
|
nsIScrollableFrame* scrollable = do_QueryFrame(GetParent());
|
||||||
if (!scrollable) return rv;
|
if (!scrollable) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> content(mContent);
|
nsCOMPtr<nsIContent> content(mContent);
|
||||||
scrollable->CurPosAttributeChanged(content);
|
scrollable->CurPosAttributeChanged(content);
|
||||||
@@ -164,47 +235,34 @@ nsIScrollbarMediator* nsScrollbarFrame::GetScrollbarMediator() {
|
|||||||
return sbm;
|
return sbm;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsScrollbarFrame::GetXULMargin(nsMargin& aMargin) {
|
bool nsScrollbarFrame::IsHorizontal() const {
|
||||||
aMargin.SizeTo(0, 0, 0, 0);
|
auto appearance = StyleDisplay()->EffectiveAppearance();
|
||||||
|
MOZ_ASSERT(appearance == StyleAppearance::ScrollbarHorizontal ||
|
||||||
|
appearance == StyleAppearance::ScrollbarVertical);
|
||||||
|
return appearance == StyleAppearance::ScrollbarHorizontal;
|
||||||
|
}
|
||||||
|
|
||||||
const bool overlayScrollbars = PresContext()->UseOverlayScrollbars();
|
nsSize nsScrollbarFrame::ScrollbarMinSize() const {
|
||||||
|
nsPresContext* pc = PresContext();
|
||||||
|
const LayoutDeviceIntSize widget =
|
||||||
|
pc->Theme()->GetMinimumWidgetSize(pc, const_cast<nsScrollbarFrame*>(this),
|
||||||
|
StyleDisplay()->EffectiveAppearance());
|
||||||
|
return LayoutDeviceIntSize::ToAppUnits(widget, pc->AppUnitsPerDevPixel());
|
||||||
|
}
|
||||||
|
|
||||||
const bool horizontal = IsXULHorizontal();
|
StyleScrollbarWidth nsScrollbarFrame::ScrollbarWidth() const {
|
||||||
bool didSetMargin = false;
|
return nsLayoutUtils::StyleForScrollbar(this)
|
||||||
|
->StyleUIReset()
|
||||||
|
->ScrollbarWidth();
|
||||||
|
}
|
||||||
|
|
||||||
if (overlayScrollbars) {
|
nscoord nsScrollbarFrame::ScrollbarTrackSize() const {
|
||||||
nsSize minSize;
|
nsPresContext* pc = PresContext();
|
||||||
bool widthSet = false;
|
auto overlay = pc->UseOverlayScrollbars() ? nsITheme::Overlay::Yes
|
||||||
bool heightSet = false;
|
: nsITheme::Overlay::No;
|
||||||
AddXULMinSize(this, minSize, widthSet, heightSet);
|
return LayoutDevicePixel::ToAppUnits(
|
||||||
if (horizontal) {
|
pc->Theme()->GetScrollbarSize(pc, ScrollbarWidth(), overlay),
|
||||||
if (heightSet) {
|
pc->AppUnitsPerDevPixel());
|
||||||
aMargin.top = -minSize.height;
|
|
||||||
didSetMargin = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (widthSet) {
|
|
||||||
aMargin.left = -minSize.width;
|
|
||||||
didSetMargin = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!didSetMargin) {
|
|
||||||
DebugOnly<nsresult> rv = nsIFrame::GetXULMargin(aMargin);
|
|
||||||
// TODO(emilio): Should probably not be fallible, it's not like anybody
|
|
||||||
// cares about the return value anyway.
|
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "nsIFrame::GetXULMargin can't really fail");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!horizontal) {
|
|
||||||
nsIScrollbarMediator* scrollFrame = GetScrollbarMediator();
|
|
||||||
if (scrollFrame && !scrollFrame->IsScrollbarOnRight()) {
|
|
||||||
std::swap(aMargin.left, aMargin.right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsScrollbarFrame::SetIncrementToLine(int32_t aDirection) {
|
void nsScrollbarFrame::SetIncrementToLine(int32_t aDirection) {
|
||||||
@@ -358,8 +416,7 @@ static already_AddRefed<Element> MakeScrollbarButton(
|
|||||||
nsresult nsScrollbarFrame::CreateAnonymousContent(
|
nsresult nsScrollbarFrame::CreateAnonymousContent(
|
||||||
nsTArray<ContentInfo>& aElements) {
|
nsTArray<ContentInfo>& aElements) {
|
||||||
nsNodeInfoManager* nodeInfoManager = mContent->NodeInfo()->NodeInfoManager();
|
nsNodeInfoManager* nodeInfoManager = mContent->NodeInfo()->NodeInfoManager();
|
||||||
|
Element* el = GetContent()->AsElement();
|
||||||
Element* el(GetContent()->AsElement());
|
|
||||||
|
|
||||||
// If there are children already in the node, don't create any anonymous
|
// If there are children already in the node, don't create any anonymous
|
||||||
// content (this only apply to crashtests/369038-1.xhtml)
|
// content (this only apply to crashtests/369038-1.xhtml)
|
||||||
@@ -368,7 +425,7 @@ nsresult nsScrollbarFrame::CreateAnonymousContent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString orient;
|
nsAutoString orient;
|
||||||
el->GetAttr(kNameSpaceID_None, nsGkAtoms::orient, orient);
|
el->GetAttr(nsGkAtoms::orient, orient);
|
||||||
bool vertical = orient.EqualsLiteral("vertical");
|
bool vertical = orient.EqualsLiteral("vertical");
|
||||||
|
|
||||||
RefPtr<dom::NodeInfo> sbbNodeInfo =
|
RefPtr<dom::NodeInfo> sbbNodeInfo =
|
||||||
@@ -451,12 +508,12 @@ nsresult nsScrollbarFrame::CreateAnonymousContent(
|
|||||||
|
|
||||||
void nsScrollbarFrame::UpdateChildrenAttributeValue(nsAtom* aAttribute,
|
void nsScrollbarFrame::UpdateChildrenAttributeValue(nsAtom* aAttribute,
|
||||||
bool aNotify) {
|
bool aNotify) {
|
||||||
Element* el(GetContent()->AsElement());
|
Element* el = GetContent()->AsElement();
|
||||||
|
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
el->GetAttr(kNameSpaceID_None, aAttribute, value);
|
el->GetAttr(aAttribute, value);
|
||||||
|
|
||||||
if (!el->HasAttr(kNameSpaceID_None, aAttribute)) {
|
if (!el->HasAttr(aAttribute)) {
|
||||||
if (mUpTopButton) {
|
if (mUpTopButton) {
|
||||||
mUpTopButton->UnsetAttr(kNameSpaceID_None, aAttribute, aNotify);
|
mUpTopButton->UnsetAttr(kNameSpaceID_None, aAttribute, aNotify);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/ScrollTypes.h"
|
#include "mozilla/ScrollTypes.h"
|
||||||
|
#include "nsContainerFrame.h"
|
||||||
#include "nsIAnonymousContentCreator.h"
|
#include "nsIAnonymousContentCreator.h"
|
||||||
#include "nsBoxFrame.h"
|
|
||||||
|
|
||||||
class nsIScrollbarMediator;
|
class nsIScrollbarMediator;
|
||||||
|
|
||||||
@@ -28,13 +28,13 @@ class Element;
|
|||||||
nsIFrame* NS_NewScrollbarFrame(mozilla::PresShell* aPresShell,
|
nsIFrame* NS_NewScrollbarFrame(mozilla::PresShell* aPresShell,
|
||||||
mozilla::ComputedStyle* aStyle);
|
mozilla::ComputedStyle* aStyle);
|
||||||
|
|
||||||
class nsScrollbarFrame final : public nsBoxFrame,
|
class nsScrollbarFrame final : public nsContainerFrame,
|
||||||
public nsIAnonymousContentCreator {
|
public nsIAnonymousContentCreator {
|
||||||
using Element = mozilla::dom::Element;
|
using Element = mozilla::dom::Element;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit nsScrollbarFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
|
explicit nsScrollbarFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
|
||||||
: nsBoxFrame(aStyle, aPresContext, kClassID),
|
: nsContainerFrame(aStyle, aPresContext, kClassID),
|
||||||
mSmoothScroll(false),
|
mSmoothScroll(false),
|
||||||
mScrollUnit(mozilla::ScrollUnit::DEVICE_PIXELS),
|
mScrollUnit(mozilla::ScrollUnit::DEVICE_PIXELS),
|
||||||
mDirection(0),
|
mDirection(0),
|
||||||
@@ -51,14 +51,14 @@ class nsScrollbarFrame final : public nsBoxFrame,
|
|||||||
NS_DECL_FRAMEARENA_HELPERS(nsScrollbarFrame)
|
NS_DECL_FRAMEARENA_HELPERS(nsScrollbarFrame)
|
||||||
|
|
||||||
#ifdef DEBUG_FRAME_DUMP
|
#ifdef DEBUG_FRAME_DUMP
|
||||||
virtual nsresult GetFrameName(nsAString& aResult) const override {
|
nsresult GetFrameName(nsAString& aResult) const override {
|
||||||
return MakeFrameName(u"ScrollbarFrame"_ns, aResult);
|
return MakeFrameName(u"ScrollbarFrame"_ns, aResult);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// nsIFrame overrides
|
// nsIFrame overrides
|
||||||
virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
|
nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
|
||||||
int32_t aModType) override;
|
int32_t aModType) override;
|
||||||
|
|
||||||
NS_IMETHOD HandlePress(nsPresContext* aPresContext,
|
NS_IMETHOD HandlePress(nsPresContext* aPresContext,
|
||||||
mozilla::WidgetGUIEvent* aEvent,
|
mozilla::WidgetGUIEvent* aEvent,
|
||||||
@@ -78,32 +78,24 @@ class nsScrollbarFrame final : public nsBoxFrame,
|
|||||||
mozilla::WidgetGUIEvent* aEvent,
|
mozilla::WidgetGUIEvent* aEvent,
|
||||||
nsEventStatus* aEventStatus) override;
|
nsEventStatus* aEventStatus) override;
|
||||||
|
|
||||||
virtual void DestroyFrom(nsIFrame* aDestructRoot,
|
mozilla::StyleScrollbarWidth ScrollbarWidth() const;
|
||||||
PostDestroyData& aPostDestroyData) override;
|
nscoord ScrollbarTrackSize() const;
|
||||||
|
nsSize ScrollbarMinSize() const;
|
||||||
|
bool IsHorizontal() const;
|
||||||
|
|
||||||
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
|
void DestroyFrom(nsIFrame* aDestructRoot,
|
||||||
nsIFrame* aPrevInFlow) override;
|
PostDestroyData& aPostDestroyData) override;
|
||||||
|
|
||||||
virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
|
void Init(nsIContent* aContent, nsContainerFrame* aParent,
|
||||||
const ReflowInput& aReflowInput,
|
nsIFrame* aPrevInFlow) override;
|
||||||
nsReflowStatus& aStatus) override;
|
|
||||||
|
void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
|
||||||
|
const ReflowInput& aReflowInput,
|
||||||
|
nsReflowStatus& aStatus) override;
|
||||||
|
|
||||||
void SetScrollbarMediatorContent(nsIContent* aMediator);
|
void SetScrollbarMediatorContent(nsIContent* aMediator);
|
||||||
nsIScrollbarMediator* GetScrollbarMediator();
|
nsIScrollbarMediator* GetScrollbarMediator();
|
||||||
|
|
||||||
// nsBox methods
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Treat scrollbars as clipping their children; overflowing children
|
|
||||||
* will not be allowed to set an overflow rect on this
|
|
||||||
* frame. This means that when the scroll code decides to hide a
|
|
||||||
* scrollframe by setting its height or width to zero, that will
|
|
||||||
* hide the children too.
|
|
||||||
*/
|
|
||||||
virtual bool DoesClipChildrenInBothAxes() override { return true; }
|
|
||||||
|
|
||||||
virtual nsresult GetXULMargin(nsMargin& aMargin) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The following three methods set the value of mIncrement when a
|
* The following three methods set the value of mIncrement when a
|
||||||
* scrollbar button is pressed.
|
* scrollbar button is pressed.
|
||||||
@@ -111,6 +103,7 @@ class nsScrollbarFrame final : public nsBoxFrame,
|
|||||||
void SetIncrementToLine(int32_t aDirection);
|
void SetIncrementToLine(int32_t aDirection);
|
||||||
void SetIncrementToPage(int32_t aDirection);
|
void SetIncrementToPage(int32_t aDirection);
|
||||||
void SetIncrementToWhole(int32_t aDirection);
|
void SetIncrementToWhole(int32_t aDirection);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If aImplementsScrollByUnit is Yes then this uses mSmoothScroll,
|
* If aImplementsScrollByUnit is Yes then this uses mSmoothScroll,
|
||||||
* mScrollUnit, and mDirection and calls ScrollByUnit on the
|
* mScrollUnit, and mDirection and calls ScrollByUnit on the
|
||||||
@@ -127,10 +120,9 @@ class nsScrollbarFrame final : public nsBoxFrame,
|
|||||||
int32_t GetIncrement() { return mIncrement; }
|
int32_t GetIncrement() { return mIncrement; }
|
||||||
|
|
||||||
// nsIAnonymousContentCreator
|
// nsIAnonymousContentCreator
|
||||||
virtual nsresult CreateAnonymousContent(
|
nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
|
||||||
nsTArray<ContentInfo>& aElements) override;
|
void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
|
||||||
virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
|
uint32_t aFilter) override;
|
||||||
uint32_t aFilter) override;
|
|
||||||
|
|
||||||
void UpdateChildrenAttributeValue(nsAtom* aAttribute, bool aNotify);
|
void UpdateChildrenAttributeValue(nsAtom* aAttribute, bool aNotify);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@
|
|||||||
#define nsSliderFrame_h__
|
#define nsSliderFrame_h__
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "nsIFrame.h"
|
||||||
#include "nsRepeatService.h"
|
#include "nsRepeatService.h"
|
||||||
#include "nsBoxFrame.h"
|
#include "nsBoxFrame.h"
|
||||||
#include "nsAtom.h"
|
#include "nsAtom.h"
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
#include "nsIDOMEventListener.h"
|
#include "nsIDOMEventListener.h"
|
||||||
|
|
||||||
class nsITimer;
|
class nsITimer;
|
||||||
|
class nsScrollbarFrame;
|
||||||
class nsSliderFrame;
|
class nsSliderFrame;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@@ -34,7 +36,7 @@ class nsSliderMediator final : public nsIDOMEventListener {
|
|||||||
|
|
||||||
explicit nsSliderMediator(nsSliderFrame* aSlider) { mSlider = aSlider; }
|
explicit nsSliderMediator(nsSliderFrame* aSlider) { mSlider = aSlider; }
|
||||||
|
|
||||||
virtual void SetSlider(nsSliderFrame* aSlider) { mSlider = aSlider; }
|
void SetSlider(nsSliderFrame* aSlider) { mSlider = aSlider; }
|
||||||
|
|
||||||
NS_DECL_NSIDOMEVENTLISTENER
|
NS_DECL_NSIDOMEVENTLISTENER
|
||||||
|
|
||||||
@@ -42,7 +44,7 @@ class nsSliderMediator final : public nsIDOMEventListener {
|
|||||||
virtual ~nsSliderMediator() = default;
|
virtual ~nsSliderMediator() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
class nsSliderFrame final : public nsBoxFrame {
|
class nsSliderFrame final : public nsContainerFrame {
|
||||||
public:
|
public:
|
||||||
NS_DECL_FRAMEARENA_HELPERS(nsSliderFrame)
|
NS_DECL_FRAMEARENA_HELPERS(nsSliderFrame)
|
||||||
NS_DECL_QUERYFRAME
|
NS_DECL_QUERYFRAME
|
||||||
@@ -53,36 +55,44 @@ class nsSliderFrame final : public nsBoxFrame {
|
|||||||
explicit nsSliderFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
|
explicit nsSliderFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
|
||||||
virtual ~nsSliderFrame();
|
virtual ~nsSliderFrame();
|
||||||
|
|
||||||
|
// Get the point associated with this event. Returns true if a single valid
|
||||||
|
// point was found. Otherwise false.
|
||||||
|
bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, nsPoint& aPoint);
|
||||||
|
// Gets the event coordinates relative to the widget associated with this
|
||||||
|
// frame. Return true if a single valid point was found.
|
||||||
|
bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent,
|
||||||
|
mozilla::LayoutDeviceIntPoint& aPoint);
|
||||||
|
|
||||||
#ifdef DEBUG_FRAME_DUMP
|
#ifdef DEBUG_FRAME_DUMP
|
||||||
virtual nsresult GetFrameName(nsAString& aResult) const override {
|
nsresult GetFrameName(nsAString& aResult) const override {
|
||||||
return MakeFrameName(u"SliderFrame"_ns, aResult);
|
return MakeFrameName(u"SliderFrame"_ns, aResult);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override;
|
void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
|
||||||
virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override;
|
const ReflowInput& aReflowInput,
|
||||||
virtual nsSize GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState) override;
|
nsReflowStatus& aStatus) override;
|
||||||
NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override;
|
|
||||||
|
|
||||||
// nsIFrame overrides
|
// nsIFrame overrides
|
||||||
virtual void DestroyFrom(nsIFrame* aDestructRoot,
|
void DestroyFrom(nsIFrame* aDestructRoot,
|
||||||
PostDestroyData& aPostDestroyData) override;
|
PostDestroyData& aPostDestroyData) override;
|
||||||
|
|
||||||
virtual void BuildDisplayListForChildren(
|
void BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) override;
|
const nsDisplayListSet& aLists) override;
|
||||||
|
|
||||||
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
void BuildDisplayListForThumb(nsDisplayListBuilder* aBuilder,
|
||||||
const nsDisplayListSet& aLists) override;
|
nsIFrame* aThumb,
|
||||||
|
const nsDisplayListSet& aLists);
|
||||||
|
|
||||||
virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
|
nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
|
||||||
int32_t aModType) override;
|
int32_t aModType) override;
|
||||||
|
|
||||||
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
|
void Init(nsIContent* aContent, nsContainerFrame* aParent,
|
||||||
nsIFrame* asPrevInFlow) override;
|
nsIFrame* aPrevInFlow) override;
|
||||||
|
|
||||||
virtual nsresult HandleEvent(nsPresContext* aPresContext,
|
nsresult HandleEvent(nsPresContext* aPresContext,
|
||||||
mozilla::WidgetGUIEvent* aEvent,
|
mozilla::WidgetGUIEvent* aEvent,
|
||||||
nsEventStatus* aEventStatus) override;
|
nsEventStatus* aEventStatus) override;
|
||||||
|
|
||||||
// nsContainerFrame overrides
|
// nsContainerFrame overrides
|
||||||
void SetInitialChildList(ChildListID aListID,
|
void SetInitialChildList(ChildListID aListID,
|
||||||
@@ -91,7 +101,7 @@ class nsSliderFrame final : public nsBoxFrame {
|
|||||||
void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
|
void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
|
||||||
const nsLineList::iterator* aPrevFrameLine,
|
const nsLineList::iterator* aPrevFrameLine,
|
||||||
nsFrameList&& aFrameList) override;
|
nsFrameList&& aFrameList) override;
|
||||||
virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
|
void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
|
||||||
|
|
||||||
nsresult StartDrag(mozilla::dom::Event* aEvent);
|
nsresult StartDrag(mozilla::dom::Event* aEvent);
|
||||||
nsresult StopDrag();
|
nsresult StopDrag();
|
||||||
@@ -105,7 +115,6 @@ class nsSliderFrame final : public nsBoxFrame {
|
|||||||
static int32_t GetPageIncrement(nsIContent* content);
|
static int32_t GetPageIncrement(nsIContent* content);
|
||||||
static int32_t GetIntegerAttribute(nsIContent* content, nsAtom* atom,
|
static int32_t GetIntegerAttribute(nsIContent* content, nsAtom* atom,
|
||||||
int32_t defaultValue);
|
int32_t defaultValue);
|
||||||
void EnsureOrient();
|
|
||||||
|
|
||||||
NS_IMETHOD HandlePress(nsPresContext* aPresContext,
|
NS_IMETHOD HandlePress(nsPresContext* aPresContext,
|
||||||
mozilla::WidgetGUIEvent* aEvent,
|
mozilla::WidgetGUIEvent* aEvent,
|
||||||
@@ -150,7 +159,7 @@ class nsSliderFrame final : public nsBoxFrame {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool GetScrollToClick();
|
bool GetScrollToClick();
|
||||||
nsIFrame* GetScrollbar();
|
nsScrollbarFrame* Scrollbar();
|
||||||
bool ShouldScrollForEvent(mozilla::WidgetGUIEvent* aEvent);
|
bool ShouldScrollForEvent(mozilla::WidgetGUIEvent* aEvent);
|
||||||
bool ShouldScrollToClickForEvent(mozilla::WidgetGUIEvent* aEvent);
|
bool ShouldScrollToClickForEvent(mozilla::WidgetGUIEvent* aEvent);
|
||||||
bool IsEventOverThumb(mozilla::WidgetGUIEvent* aEvent);
|
bool IsEventOverThumb(mozilla::WidgetGUIEvent* aEvent);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0;'>
|
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0;'>
|
||||||
<resizer dir='bottomright' flex='1' style="width: 150px; height: 150px; appearance: none; margin: 0; border: 0; padding: 0;"/>
|
<resizer dir='bottomright' flex='1' style="min-width: 150px; min-height: 150px; appearance: none; margin: 0; border: 0; padding: 0;"/>
|
||||||
</window>
|
</window>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; min-width: 120px; max-width: 480px; min-height: 110px; max-height: 470px'>
|
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; min-width: 120px; max-width: 480px; min-height: 110px; max-height: 470px'>
|
||||||
<resizer dir='bottomright' flex='1' style='width: 150px; height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
<resizer dir='bottomright' flex='1' style='min-width: 150px; min-height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
||||||
</window>
|
</window>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; min-width: 180px; min-height: 210px;'>
|
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; min-width: 180px; min-height: 210px;'>
|
||||||
<resizer dir='bottomright' flex='1' style='width: 150px; height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
<resizer dir='bottomright' flex='1' style='min-width: 150px; min-height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
||||||
</window>
|
</window>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; max-width: 125px; max-height: 140px'>
|
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; max-width: 125px; max-height: 140px'>
|
||||||
<resizer dir='bottomright' flex='1' style='width: 150px; height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
<resizer dir='bottomright' flex='1' style='min-width: 150px; min-height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
||||||
</window>
|
</window>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; min-width: 240px; min-height: 220px'>
|
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; min-width: 240px; min-height: 220px'>
|
||||||
<resizer dir='bottomright' flex='1' style='width: 150px; height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
<resizer dir='bottomright' flex='1' style='min-width: 150px; min-height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
||||||
</window>
|
</window>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; min-width: 215px; min-height: 235px' width='190' height='220'>
|
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; min-width: 215px; min-height: 235px' width='190' height='220'>
|
||||||
<resizer dir='bottomright' flex='1' style='width: 150px; height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
<resizer dir='bottomright' flex='1' style='min-width: 150px; min-height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
||||||
</window>
|
</window>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; max-width: 125px; max-height: 95px'>
|
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; max-width: 125px; max-height: 95px'>
|
||||||
<resizer dir='bottomright' flex='1' style='width: 150px; height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
<resizer dir='bottomright' flex='1' style='min-width: 150px; min-height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
||||||
</window>
|
</window>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; min-width: 210px'>
|
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; min-width: 210px'>
|
||||||
<resizer dir='bottomright' flex='1' style='width: 150px; height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
<resizer dir='bottomright' flex='1' style='min-width: 150px; min-height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
||||||
</window>
|
</window>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; max-width: 128px'>
|
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; max-width: 128px'>
|
||||||
<resizer dir='bottomright' flex='1' style='width: 150px; height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
<resizer dir='bottomright' flex='1' style='min-width: 150px; min-height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
||||||
</window>
|
</window>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
<?xml-stylesheet href='chrome://global/skin' type='text/css'?>
|
||||||
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; max-width: 195px; min-height: 180px' width='230' height='120'>
|
<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' align='start' pack='start' style='-moz-appearance: none; margin: 0; padding: 0; border: 0; max-width: 195px; min-height: 180px' width='230' height='120'>
|
||||||
<resizer dir='bottomright' flex='1' style='width: 150px; height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
<resizer dir='bottomright' flex='1' style='min-width: 150px; min-height: 150px; appearance: none; margin: 0; border: 0; padding: 0;'/>
|
||||||
</window>
|
</window>
|
||||||
|
|||||||
@@ -644,9 +644,8 @@ static void FindScrollParts(nsIFrame* aCurrFrame,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsScrollbarFrame* sf = do_QueryFrame(aCurrFrame);
|
if (nsScrollbarFrame* sf = do_QueryFrame(aCurrFrame)) {
|
||||||
if (sf) {
|
if (!sf->IsHorizontal()) {
|
||||||
if (!aCurrFrame->IsXULHorizontal()) {
|
|
||||||
if (!aResult->mVScrollbar) {
|
if (!aResult->mVScrollbar) {
|
||||||
aResult->mVScrollbar = sf;
|
aResult->mVScrollbar = sf;
|
||||||
}
|
}
|
||||||
@@ -671,20 +670,17 @@ static void FindScrollParts(nsIFrame* aCurrFrame,
|
|||||||
nsTreeBodyFrame::ScrollParts nsTreeBodyFrame::GetScrollParts() {
|
nsTreeBodyFrame::ScrollParts nsTreeBodyFrame::GetScrollParts() {
|
||||||
ScrollParts result = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
|
ScrollParts result = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
|
||||||
XULTreeElement* tree = GetBaseElement();
|
XULTreeElement* tree = GetBaseElement();
|
||||||
nsIFrame* treeFrame = tree ? tree->GetPrimaryFrame() : nullptr;
|
if (nsIFrame* treeFrame = tree ? tree->GetPrimaryFrame() : nullptr) {
|
||||||
if (treeFrame) {
|
|
||||||
// The way we do this, searching through the entire frame subtree, is pretty
|
// The way we do this, searching through the entire frame subtree, is pretty
|
||||||
// dumb! We should know where these frames are.
|
// dumb! We should know where these frames are.
|
||||||
FindScrollParts(treeFrame, &result);
|
FindScrollParts(treeFrame, &result);
|
||||||
if (result.mHScrollbar) {
|
if (result.mHScrollbar) {
|
||||||
result.mHScrollbar->SetScrollbarMediatorContent(GetContent());
|
result.mHScrollbar->SetScrollbarMediatorContent(GetContent());
|
||||||
nsIFrame* f = do_QueryFrame(result.mHScrollbar);
|
result.mHScrollbarContent = result.mHScrollbar->GetContent()->AsElement();
|
||||||
result.mHScrollbarContent = f->GetContent()->AsElement();
|
|
||||||
}
|
}
|
||||||
if (result.mVScrollbar) {
|
if (result.mVScrollbar) {
|
||||||
result.mVScrollbar->SetScrollbarMediatorContent(GetContent());
|
result.mVScrollbar->SetScrollbarMediatorContent(GetContent());
|
||||||
nsIFrame* f = do_QueryFrame(result.mVScrollbar);
|
result.mVScrollbarContent = result.mVScrollbar->GetContent()->AsElement();
|
||||||
result.mVScrollbarContent = f->GetContent()->AsElement();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -3820,7 +3816,7 @@ void nsTreeBodyFrame::RepeatButtonScroll(nsScrollbarFrame* aScrollbar) {
|
|||||||
} else if (increment > 0) {
|
} else if (increment > 0) {
|
||||||
direction = 1;
|
direction = 1;
|
||||||
}
|
}
|
||||||
bool isHorizontal = aScrollbar->IsXULHorizontal();
|
bool isHorizontal = aScrollbar->IsHorizontal();
|
||||||
|
|
||||||
AutoWeakFrame weakFrame(this);
|
AutoWeakFrame weakFrame(this);
|
||||||
if (isHorizontal) {
|
if (isHorizontal) {
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class nsTreeBodyFrame final : public nsLeafBoxFrame,
|
|||||||
nscoord aNewPos) override;
|
nscoord aNewPos) override;
|
||||||
virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) override {}
|
virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) override {}
|
||||||
virtual void VisibilityChanged(bool aVisible) override { Invalidate(); }
|
virtual void VisibilityChanged(bool aVisible) override { Invalidate(); }
|
||||||
virtual nsIFrame* GetScrollbarBox(bool aVertical) override {
|
nsScrollbarFrame* GetScrollbarBox(bool aVertical) override {
|
||||||
ScrollParts parts = GetScrollParts();
|
ScrollParts parts = GetScrollParts();
|
||||||
return aVertical ? parts.mVScrollbar : parts.mHScrollbar;
|
return aVertical ? parts.mVScrollbar : parts.mHScrollbar;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,13 +15,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1048178
|
|||||||
target="_blank">Mozilla Bug 1048178</a>
|
target="_blank">Mozilla Bug 1048178</a>
|
||||||
|
|
||||||
<hbox>
|
<hbox>
|
||||||
<scrollbar id="scroller"
|
<scrollbar id="scroller"
|
||||||
orient="horizontal"
|
orient="horizontal"
|
||||||
curpos="0"
|
curpos="0"
|
||||||
maxpos="500"
|
maxpos="500"
|
||||||
pageincrement="500"
|
pageincrement="500"
|
||||||
width="500"
|
style="width: 500px; margin:0"/>
|
||||||
style="margin:0"/>
|
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|
||||||
<!-- test code goes here -->
|
<!-- test code goes here -->
|
||||||
@@ -45,7 +44,7 @@ var scrollbarTester = {
|
|||||||
this.mouseup(x, y, 2);
|
this.mouseup(x, y, 2);
|
||||||
this.mouseup(x, y, 0);
|
this.mouseup(x, y, 0);
|
||||||
|
|
||||||
var newPos = this.getPos(); // sould be '500'
|
var newPos = this.getPos(); // should be '500'
|
||||||
|
|
||||||
this.mousedown(x, y, 0);
|
this.mousedown(x, y, 0);
|
||||||
this.mousemove(x-1, y, 0);
|
this.mousemove(x-1, y, 0);
|
||||||
|
|||||||
@@ -13,13 +13,12 @@
|
|||||||
<body xmlns="http://www.w3.org/1999/xhtml"/>
|
<body xmlns="http://www.w3.org/1999/xhtml"/>
|
||||||
|
|
||||||
<hbox>
|
<hbox>
|
||||||
<scrollbar orient="horizontal"
|
<scrollbar orient="horizontal"
|
||||||
id="scroller"
|
id="scroller"
|
||||||
curpos="0"
|
curpos="0"
|
||||||
maxpos="600"
|
maxpos="600"
|
||||||
pageincrement="400"
|
pageincrement="400"
|
||||||
width="500"
|
style="width: 500px; margin: 0"/>
|
||||||
style="margin:0"/>
|
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|
||||||
<!-- test code goes here -->
|
<!-- test code goes here -->
|
||||||
|
|||||||
Reference in New Issue
Block a user