зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1022818 - Part 2: Implement Smooth Scrolling. r=bz
- Updated ScrollTo method in nsGlobalWindow to accept a mozilla::dom::ScrollOptions parameter to select between the instant and smooth MSD motion. - Updated WebIDL binding boilerplate scrolling functions in nsGlobalWindow to pass the correct value of mozilla::dom::ScrollBehavior to the implementation and functions, activating smooth scrolling. - These functions will need to be updated again to support the scroll-behavior CSS property in Bug 1010538.
This commit is contained in:
Родитель
cbede6f09b
Коммит
0befdfe863
|
@ -608,12 +608,17 @@ Element::ScrollIntoView(bool aTop, const ScrollOptions &aOptions)
|
|||
int16_t vpercent = aTop ? nsIPresShell::SCROLL_TOP :
|
||||
nsIPresShell::SCROLL_BOTTOM;
|
||||
|
||||
uint32_t flags = nsIPresShell::SCROLL_OVERFLOW_HIDDEN;
|
||||
if (aOptions.mBehavior == ScrollBehavior::Smooth) {
|
||||
flags |= nsIPresShell::SCROLL_SMOOTH;
|
||||
}
|
||||
|
||||
presShell->ScrollContentIntoView(this,
|
||||
nsIPresShell::ScrollAxis(
|
||||
vpercent,
|
||||
nsIPresShell::SCROLL_ALWAYS),
|
||||
nsIPresShell::ScrollAxis(),
|
||||
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
|
||||
flags);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -7225,32 +7225,33 @@ void
|
|||
nsGlobalWindow::Scroll(int32_t aXScroll, int32_t aYScroll,
|
||||
const ScrollOptions& aOptions)
|
||||
{
|
||||
ScrollTo(CSSIntPoint(aXScroll, aYScroll));
|
||||
ScrollTo(CSSIntPoint(aXScroll, aYScroll), aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::ScrollTo(int32_t aXScroll, int32_t aYScroll,
|
||||
const ScrollOptions& aOptions)
|
||||
{
|
||||
ScrollTo(CSSIntPoint(aXScroll, aYScroll));
|
||||
ScrollTo(CSSIntPoint(aXScroll, aYScroll), aOptions);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::Scroll(int32_t aXScroll, int32_t aYScroll)
|
||||
{
|
||||
ScrollTo(CSSIntPoint(aXScroll, aYScroll));
|
||||
ScrollTo(CSSIntPoint(aXScroll, aYScroll), ScrollOptions());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::ScrollTo(int32_t aXScroll, int32_t aYScroll)
|
||||
{
|
||||
ScrollTo(CSSIntPoint(aXScroll, aYScroll));
|
||||
ScrollTo(CSSIntPoint(aXScroll, aYScroll), ScrollOptions());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::ScrollTo(const CSSIntPoint& aScroll)
|
||||
nsGlobalWindow::ScrollTo(const CSSIntPoint& aScroll,
|
||||
const ScrollOptions& aOptions)
|
||||
{
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
nsIScrollableFrame *sf = GetScrollFrame();
|
||||
|
@ -7271,7 +7272,86 @@ nsGlobalWindow::ScrollTo(const CSSIntPoint& aScroll)
|
|||
if (scroll.y > maxpx) {
|
||||
scroll.y = maxpx;
|
||||
}
|
||||
sf->ScrollToCSSPixels(scroll);
|
||||
|
||||
sf->ScrollToCSSPixels(scroll,
|
||||
aOptions.mBehavior == ScrollBehavior::Smooth
|
||||
? nsIScrollableFrame::SMOOTH_MSD
|
||||
: nsIScrollableFrame::INSTANT);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::ScrollBy(int32_t aXScrollDif, int32_t aYScrollDif)
|
||||
{
|
||||
ScrollBy(aXScrollDif, aYScrollDif, ScrollOptions());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::ScrollBy(int32_t aXScrollDif, int32_t aYScrollDif,
|
||||
const ScrollOptions& aOptions)
|
||||
{
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
nsIScrollableFrame *sf = GetScrollFrame();
|
||||
|
||||
if (sf) {
|
||||
CSSIntPoint scrollPos =
|
||||
sf->GetScrollPositionCSSPixels() + CSSIntPoint(aXScrollDif, aYScrollDif);
|
||||
// It seems like it would make more sense for ScrollBy to use
|
||||
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
|
||||
// Perhaps Web content does too.
|
||||
ScrollTo(scrollPos, aOptions);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::ScrollByLines(int32_t numLines)
|
||||
{
|
||||
ScrollByLines(numLines, ScrollOptions());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::ScrollByLines(int32_t numLines,
|
||||
const ScrollOptions& aOptions)
|
||||
{
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
nsIScrollableFrame *sf = GetScrollFrame();
|
||||
if (sf) {
|
||||
// It seems like it would make more sense for ScrollByLines to use
|
||||
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
|
||||
// Perhaps Web content does too.
|
||||
sf->ScrollBy(nsIntPoint(0, numLines), nsIScrollableFrame::LINES,
|
||||
aOptions.mBehavior == ScrollBehavior::Smooth
|
||||
? nsIScrollableFrame::SMOOTH_MSD
|
||||
: nsIScrollableFrame::INSTANT);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::ScrollByPages(int32_t numPages)
|
||||
{
|
||||
ScrollByPages(numPages, ScrollOptions());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::ScrollByPages(int32_t numPages,
|
||||
const ScrollOptions& aOptions)
|
||||
{
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
nsIScrollableFrame *sf = GetScrollFrame();
|
||||
if (sf) {
|
||||
// It seems like it would make more sense for ScrollByPages to use
|
||||
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
|
||||
// Perhaps Web content does too.
|
||||
sf->ScrollBy(nsIntPoint(0, numPages), nsIScrollableFrame::PAGES,
|
||||
aOptions.mBehavior == ScrollBehavior::Smooth
|
||||
? nsIScrollableFrame::SMOOTH_MSD
|
||||
: nsIScrollableFrame::INSTANT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7291,77 +7371,6 @@ nsGlobalWindow::MozRequestOverfill(OverfillCallback& aCallback,
|
|||
aError.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::ScrollBy(int32_t aXScrollDif, int32_t aYScrollDif,
|
||||
const ScrollOptions& aOptions)
|
||||
{
|
||||
ScrollBy(aXScrollDif, aYScrollDif);
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::ScrollByLines(int32_t numLines,
|
||||
const ScrollOptions& aOptions)
|
||||
{
|
||||
ScrollByLines(numLines);
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::ScrollByPages(int32_t numPages,
|
||||
const ScrollOptions& aOptions)
|
||||
{
|
||||
ScrollByPages(numPages);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::ScrollBy(int32_t aXScrollDif, int32_t aYScrollDif)
|
||||
{
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
nsIScrollableFrame *sf = GetScrollFrame();
|
||||
|
||||
if (sf) {
|
||||
CSSIntPoint scrollPos =
|
||||
sf->GetScrollPositionCSSPixels() + CSSIntPoint(aXScrollDif, aYScrollDif);
|
||||
// It seems like it would make more sense for ScrollBy to use
|
||||
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
|
||||
// Perhaps Web content does too.
|
||||
ScrollTo(scrollPos);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::ScrollByLines(int32_t numLines)
|
||||
{
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
nsIScrollableFrame *sf = GetScrollFrame();
|
||||
if (sf) {
|
||||
// It seems like it would make more sense for ScrollByLines to use
|
||||
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
|
||||
// Perhaps Web content does too.
|
||||
sf->ScrollBy(nsIntPoint(0, numLines), nsIScrollableFrame::LINES,
|
||||
nsIScrollableFrame::INSTANT);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::ScrollByPages(int32_t numPages)
|
||||
{
|
||||
FlushPendingNotifications(Flush_Layout);
|
||||
nsIScrollableFrame *sf = GetScrollFrame();
|
||||
if (sf) {
|
||||
// It seems like it would make more sense for ScrollByPages to use
|
||||
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
|
||||
// Perhaps Web content does too.
|
||||
sf->ScrollBy(nsIntPoint(0, numPages), nsIScrollableFrame::PAGES,
|
||||
nsIScrollableFrame::INSTANT);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::ClearTimeout(int32_t aHandle, ErrorResult& aError)
|
||||
{
|
||||
|
|
|
@ -1322,7 +1322,8 @@ public:
|
|||
mozilla::ErrorResult& aError);
|
||||
nsRect GetInnerScreenRect();
|
||||
|
||||
void ScrollTo(const mozilla::CSSIntPoint& aScroll);
|
||||
void ScrollTo(const mozilla::CSSIntPoint& aScroll,
|
||||
const mozilla::dom::ScrollOptions& aOptions);
|
||||
|
||||
bool IsFrame()
|
||||
{
|
||||
|
|
|
@ -681,6 +681,10 @@ public:
|
|||
* If SCROLL_NO_PARENT_FRAMES is set then we only scroll
|
||||
* nodes in this document, not in any parent documents which
|
||||
* contain this document in a iframe or the like.
|
||||
* If SCROLL_SMOOTH is set and CSSOM-VIEW scroll-behavior
|
||||
* is enabled, we will scroll smoothly using
|
||||
* nsIScrollableFrame::ScrollMode::SMOOTH_MSD; otherwise,
|
||||
* nsIScrollableFrame::ScrollMode::INSTANT will be used.
|
||||
*/
|
||||
virtual nsresult ScrollContentIntoView(nsIContent* aContent,
|
||||
ScrollAxis aVertical,
|
||||
|
@ -690,7 +694,8 @@ public:
|
|||
enum {
|
||||
SCROLL_FIRST_ANCESTOR_ONLY = 0x01,
|
||||
SCROLL_OVERFLOW_HIDDEN = 0x02,
|
||||
SCROLL_NO_PARENT_FRAMES = 0x04
|
||||
SCROLL_NO_PARENT_FRAMES = 0x04,
|
||||
SCROLL_SMOOTH = 0x08
|
||||
};
|
||||
/**
|
||||
* Scrolls the view of the document so that the given area of a frame
|
||||
|
|
|
@ -3519,7 +3519,11 @@ static void ScrollToShowRect(nsIFrame* aFrame,
|
|||
// If we don't need to scroll, then don't try since it might cancel
|
||||
// a current smooth scroll operation.
|
||||
if (needToScroll) {
|
||||
aFrameAsScrollable->ScrollTo(scrollPt, nsIScrollableFrame::INSTANT, &allowedRange);
|
||||
nsIScrollableFrame::ScrollMode scrollMode = nsIScrollableFrame::INSTANT;
|
||||
if (gfxPrefs::ScrollBehaviorEnabled() && aFlags & nsIPresShell::SCROLL_SMOOTH) {
|
||||
scrollMode = nsIScrollableFrame::SMOOTH_MSD;
|
||||
}
|
||||
aFrameAsScrollable->ScrollTo(scrollPt, scrollMode, &allowedRange);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче