Bug 1172171 - If dom.event.scrollend.enabled is true, fire a scrollend event every time APZ stops scrolling or zooming. draft
authorMarkus Stange <mstange@themasta.com>
Tue, 12 Jan 2016 18:18:58 +0100
changeset 320870 9a2938aedd032dfb2b7058d575a15199f5409ac5
parent 320869 0e1f50f9451effe51c304eaa7f5b3b58db7bc170
child 512837 f483db0d2bc6b0f77dcfc74597511449317b5eaf
push id9310
push usermstange@themasta.com
push dateTue, 12 Jan 2016 17:19:40 +0000
bugs1172171
milestone46.0a1
Bug 1172171 - If dom.event.scrollend.enabled is true, fire a scrollend event every time APZ stops scrolling or zooming.
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
modules/libpref/init/all.js
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3883,16 +3883,27 @@ ScrollFrameHelper::FireScrollPortEvent()
                                                      mVerticalOverflow) ?
     eScrollPortOverflow : eScrollPortUnderflow, nullptr);
   event.orient = orient;
   return EventDispatcher::Dispatch(mOuter->GetContent(),
                                    mOuter->PresContext(), &event);
 }
 
 void
+ScrollFrameHelper::FireScrollEndEvent()
+{
+  if (Preferences::GetBool("dom.event.scrollend.enabled", false)) {
+    nsContentUtils::DispatchTrustedEvent(mOuter->GetContent()->OwnerDoc(),
+                                         mOuter->GetContent(),
+                                         NS_LITERAL_STRING("scrollend"),
+                                         true, false);
+  }
+}
+
+void
 ScrollFrameHelper::ReloadChildFrames()
 {
   mScrolledFrame = nullptr;
   mHScrollbarBox = nullptr;
   mVScrollbarBox = nullptr;
   mScrollCornerBox = nullptr;
   mResizerBox = nullptr;
 
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -63,16 +63,17 @@ public:
   // reload our child frame list.
   // We need this if a scrollbar frame is recreated.
   void ReloadChildFrames();
 
   nsresult CreateAnonymousContent(
     nsTArray<nsIAnonymousContentCreator::ContentInfo>& aElements);
   void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter);
   nsresult FireScrollPortEvent();
+  void FireScrollEndEvent();
   void PostOverflowEvent();
   void Destroy();
 
   void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                         const nsRect&           aDirtyRect,
                         const nsDisplayListSet& aLists);
 
   void AppendScrollPartsTo(nsDisplayListBuilder*   aBuilder,
@@ -345,16 +346,19 @@ public:
   bool ShouldClampScrollPosition() const;
 
   bool IsAlwaysActive() const;
   void MarkRecentlyScrolled();
   void MarkNotRecentlyScrolled();
   nsExpirationState* GetExpirationState() { return &mActivityExpirationState; }
 
   void SetTransformingByAPZ(bool aTransforming) {
+    if (mTransformingByAPZ && !aTransforming) {
+      FireScrollEndEvent();
+    }
     mTransformingByAPZ = aTransforming;
     if (!mozilla::css::TextOverflow::HasClippedOverflow(mOuter)) {
       // If the block has some text-overflow stuff we should kick off a paint
       // because we have special behaviour for it when APZ scrolling is active.
       mOuter->SchedulePaint();
     }
     // Update windowed plugin visibility in response to apz scrolling events.
     NotifyPluginFrames(aTransforming ? BEGIN_APZ : END_APZ);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1104,16 +1104,18 @@ pref("privacy.trackingprotection.pbmode.
 pref("dom.event.contextmenu.enabled",       true);
 pref("dom.event.clipboardevents.enabled",   true);
 #if defined(XP_WIN) && !defined(RELEASE_BUILD) || defined(MOZ_WIDGET_GTK) && !defined(RELEASE_BUILD)
 pref("dom.event.highrestimestamp.enabled",  true);
 #else
 pref("dom.event.highrestimestamp.enabled",  false);
 #endif
 
+pref("dom.event.scrollend.enabled",         false);
+
 pref("dom.webcomponents.enabled",           false);
 
 pref("javascript.enabled",                  true);
 pref("javascript.options.strict",           false);
 #ifdef DEBUG
 pref("javascript.options.strict.debug",     false);
 #endif
 pref("javascript.options.baselinejit",      true);