Bug 1062406 - Part 1: Change x and y parameters of window.scroll* CSSOM-View DOM calls from double to unrestricted double. r=bz, a=lmandel
authorKearwood (Kip) Gilbert <kgilbert@mozilla.com>
Tue, 09 Sep 2014 12:02:00 +0200
changeset 224858 885dcc785dd4c2b219a4a7dfa132107b3f37c8df
parent 224857 8068c37eb8cbc238ddff9c8200f9c5c2d33fcd7b
child 224859 c143c4fb1627573f5a0244541de1cc2f010afddc
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, lmandel
bugs1062406
milestone34.0a2
Bug 1062406 - Part 1: Change x and y parameters of window.scroll* CSSOM-View DOM calls from double to unrestricted double. r=bz, a=lmandel - WebIDL updated so that x and y parameters of window.scroll, window.scrollTo, and window.ScrollBy are changed from "double" to "unrestricted double". - Implemented mozilla::ToZeroIfNonfinite - Updated nsGlobalWindow::Scroll, ScrollTo, and ScrollBy methods so that they replace non-finite numbers with 0.
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/webidl/Window.webidl
mfbt/FloatingPoint.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7201,27 +7201,33 @@ nsGlobalWindow::GetTopWindowRoot()
     return nullptr;
   }
 
   nsCOMPtr<nsPIWindowRoot> window = do_QueryInterface(piWin->GetChromeEventHandler());
   return window.forget();
 }
 
 void
-nsGlobalWindow::Scroll(int32_t aXScroll, int32_t aYScroll,
+nsGlobalWindow::Scroll(double aXScroll, double aYScroll,
                        const ScrollOptions& aOptions)
 {
-  ScrollTo(CSSIntPoint(aXScroll, aYScroll), aOptions);
-}
-
-void
-nsGlobalWindow::ScrollTo(int32_t aXScroll, int32_t aYScroll,
+  // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
+  CSSIntPoint scrollPos(mozilla::ToZeroIfNonfinite(aXScroll),
+                        mozilla::ToZeroIfNonfinite(aYScroll));
+  ScrollTo(scrollPos, aOptions);
+}
+
+void
+nsGlobalWindow::ScrollTo(double aXScroll, double aYScroll,
                          const ScrollOptions& aOptions)
 {
-  ScrollTo(CSSIntPoint(aXScroll, aYScroll), aOptions);
+  // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
+  CSSIntPoint scrollPos(mozilla::ToZeroIfNonfinite(aXScroll),
+                        mozilla::ToZeroIfNonfinite(aYScroll));
+  ScrollTo(scrollPos, aOptions);
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::Scroll(int32_t aXScroll, int32_t aYScroll)
 {
   ScrollTo(CSSIntPoint(aXScroll, aYScroll), ScrollOptions());
   return NS_OK;
 }
@@ -7268,29 +7274,30 @@ 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,
+nsGlobalWindow::ScrollBy(double aXScrollDif, double aYScrollDif,
                          const ScrollOptions& aOptions)
 {
   FlushPendingNotifications(Flush_Layout);
   nsIScrollableFrame *sf = GetScrollFrame();
 
   if (sf) {
-    CSSIntPoint scrollPos =
-      sf->GetScrollPositionCSSPixels() + CSSIntPoint(aXScrollDif, aYScrollDif);
+    // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
+    CSSIntPoint scrollDif(mozilla::ToZeroIfNonfinite(aXScrollDif),
+                          mozilla::ToZeroIfNonfinite(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);
+    ScrollTo(sf->GetScrollPositionCSSPixels() + scrollDif, aOptions);
   }
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::ScrollByLines(int32_t numLines)
 {
   ScrollByLines(numLines, ScrollOptions());
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -932,21 +932,21 @@ public:
                                                             mozilla::ErrorResult& aError);
   nsScreen* GetScreen(mozilla::ErrorResult& aError);
   void MoveTo(int32_t aXPos, int32_t aYPos, mozilla::ErrorResult& aError);
   void MoveBy(int32_t aXDif, int32_t aYDif, mozilla::ErrorResult& aError);
   void ResizeTo(int32_t aWidth, int32_t aHeight,
                 mozilla::ErrorResult& aError);
   void ResizeBy(int32_t aWidthDif, int32_t aHeightDif,
                 mozilla::ErrorResult& aError);
-  void Scroll(int32_t aXScroll, int32_t aYScroll,
+  void Scroll(double aXScroll, double aYScroll,
               const mozilla::dom::ScrollOptions& aOptions);
-  void ScrollTo(int32_t aXScroll, int32_t aYScroll,
+  void ScrollTo(double aXScroll, double aYScroll,
                 const mozilla::dom::ScrollOptions& aOptions);
-  void ScrollBy(int32_t aXScrollDif, int32_t aYScrollDif,
+  void ScrollBy(double aXScrollDif, double aYScrollDif,
                 const mozilla::dom::ScrollOptions& aOptions);
   void ScrollByLines(int32_t numLines,
                      const mozilla::dom::ScrollOptions& aOptions);
   void ScrollByPages(int32_t numPages,
                      const mozilla::dom::ScrollOptions& aOptions);
   int32_t GetInnerWidth(mozilla::ErrorResult& aError);
   void SetInnerWidth(int32_t aInnerWidth, mozilla::ErrorResult& aError);
   int32_t GetInnerHeight(mozilla::ErrorResult& aError);
--- a/dom/webidl/Window.webidl
+++ b/dom/webidl/Window.webidl
@@ -174,19 +174,19 @@ partial interface Window {
   [Throws] attribute long innerWidth;
   [Throws] attribute long innerHeight;
 
   // viewport scrolling
   //[Throws] readonly attribute double scrollX;
   //[Throws] readonly attribute double pageXOffset;
   //[Throws] readonly attribute double scrollY;
   //[Throws] readonly attribute double pageYOffset;
-  void scroll(double x, double y, optional ScrollOptions options);
-  void scrollTo(double x, double y, optional ScrollOptions options);
-  void scrollBy(double x, double y, optional ScrollOptions options);
+  void scroll(unrestricted double x, unrestricted double y, optional ScrollOptions options);
+  void scrollTo(unrestricted double x, unrestricted double y, optional ScrollOptions options);
+  void scrollBy(unrestricted double x, unrestricted double y, optional ScrollOptions options);
   [Replaceable, Throws] readonly attribute long scrollX;
   [Throws] readonly attribute long pageXOffset;
   [Replaceable, Throws] readonly attribute long scrollY;
   [Throws] readonly attribute long pageYOffset;
 
   // client
   //[Throws] readonly attribute double screenX;
   //[Throws] readonly attribute double screenY;
--- a/mfbt/FloatingPoint.h
+++ b/mfbt/FloatingPoint.h
@@ -183,16 +183,27 @@ IsNegativeZero(T aValue)
   /* Only the sign bit is set if the value is -0. */
   typedef FloatingPoint<T> Traits;
   typedef typename Traits::Bits Bits;
   Bits bits = BitwiseCast<Bits>(aValue);
   return bits == Traits::kSignBit;
 }
 
 /**
+ * Returns 0 if a float/double is NaN or infinite;
+ * otherwise, the float/double is returned.
+ */
+template<typename T>
+static MOZ_ALWAYS_INLINE T
+ToZeroIfNonfinite(T aValue)
+{
+  return IsFinite(aValue) ? aValue : 0;
+}
+
+/**
  * Returns the exponent portion of the float/double.
  *
  * Zero is not special-cased, so ExponentComponent(0.0) is
  * -int_fast16_t(Traits::kExponentBias).
  */
 template<typename T>
 static MOZ_ALWAYS_INLINE int_fast16_t
 ExponentComponent(T aValue)