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:
Kearwood (Kip) Gilbert 2014-07-21 11:19:00 -04:00
Родитель cbede6f09b
Коммит 0befdfe863
5 изменённых файлов: 105 добавлений и 81 удалений

Просмотреть файл

@ -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);
}
}