Bug 704063. Add an unprefixed version of requestAnimationFrame. r=roc, sr=smaug
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 25 Apr 2013 11:13:21 -0400
changeset 140818 1a7dac116295392baded40c0ac56e7eeabfd3536
parent 140817 bff1304042580269e13440fc5ca83fe06fb12d1e
child 140819 c759d3eb1118e75caa76524a830140a7222915db
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, smaug
bugs704063
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 704063. Add an unprefixed version of requestAnimationFrame. r=roc, sr=smaug
content/base/test/Makefile.in
content/base/test/test_bug704063.html
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/interfaces/base/nsIDOMWindow.idl
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -252,16 +252,17 @@ MOCHITEST_FILES_A = \
 		file_bug782342.txt \
 		test_bug782342.html \
 		test_bug282547.html \
 		bug282547.sjs \
 		test_domparser_null_char.html \
 		test_bug811701.html \
 		test_bug811701.xhtml \
 		test_bug820909.html \
+		test_bug704063.html \
 		$(NULL)
 
 MOCHITEST_FILES_B = \
 		test_bug459424.html \
 		bug461735-redirect1.sjs \
 		bug461735-redirect2.sjs \
 		bug461735-post-redirect.js \
 		test_bug513194.html \
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug704063.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug </title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug  **/
+  SimpleTest.waitForExplicitFinish();
+  var unprefixedRan = false;
+  var prefixedRan = false;
+  function unprefixed(time) {
+    is(prefixedRan, true, "We were called second");
+    unprefixedRan = true;
+    ok(Math.abs(time - performance.now()) < 3600000,
+       "An hour really shouldn't have passed here");
+    ok(Math.abs(time - Date.now()) > 3600000,
+       "More than an hour should have passed since 1970");
+  }
+  function prefixed(time) {
+    is(unprefixedRan, false, "Prefixed was called first");
+    prefixedRan = true;
+    ok(Math.abs(time - Date.now()) < 3600000,
+       "Our time should be comparable to Date.now()");
+    ok(Math.abs(time - performance.now()) > 3600000,
+       "Our time should not be comparable to performance.now()");
+  }
+  function prefixed2() {
+    ok(prefixedRan, "We should be after the other prefixed call");
+    ok(unprefixedRan, "We should be after the unprefixed call");
+    SimpleTest.finish();
+  }
+
+  window.onload = function() {
+    window.mozRequestAnimationFrame(prefixed);
+    window.requestAnimationFrame(unprefixed);
+    window.mozRequestAnimationFrame(prefixed2);
+  }
+
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -226,16 +226,17 @@
 #include "nsDOMEventTargetHelper.h"
 #include "nsIAppsService.h"
 #include "prrng.h"
 #include "nsSandboxFlags.h"
 #include "TimeChangeObserver.h"
 #include "nsPISocketTransportService.h"
 #include "mozilla/dom/AudioContext.h"
 #include "mozilla/dom/FunctionBinding.h"
+#include "mozilla/dom/WindowBinding.h"
 
 #ifdef MOZ_WEBSPEECH
 #include "mozilla/dom/SpeechSynthesis.h"
 #endif
 
 // Apple system headers seem to have a check() macro.  <sigh>
 #ifdef check
 #undef check
@@ -4324,30 +4325,61 @@ nsGlobalWindow::GetMozPaintCount(uint64_
 
 NS_IMETHODIMP
 nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback,
                                          int32_t *aHandle)
 {
   FORWARD_TO_INNER(MozRequestAnimationFrame, (aCallback, aHandle),
                    NS_ERROR_NOT_INITIALIZED);
 
+  if (!aCallback) {
+    if (mDoc) {
+      mDoc->WarnOnceAbout(nsIDocument::eMozBeforePaint);
+    }
+    return NS_ERROR_XPC_BAD_CONVERT_JS;
+  }
+
+  nsIDocument::FrameRequestCallbackHolder holder(aCallback);
+  return RequestAnimationFrame(holder, aHandle);
+}
+
+nsresult
+nsGlobalWindow::RequestAnimationFrame(const nsIDocument::FrameRequestCallbackHolder& aCallback,
+                                      int32_t* aHandle)
+{
+  MOZ_ASSERT(IsInnerWindow());
+
   if (!mDoc) {
-    return NS_OK;
-  }
-
-  if (!aCallback) {
-    mDoc->WarnOnceAbout(nsIDocument::eMozBeforePaint);
-    return NS_ERROR_XPC_BAD_CONVERT_JS;
+    *aHandle = 0;
+    return NS_OK;
   }
 
   if (mJSObject)
     js::NotifyAnimationActivity(mJSObject);
 
-  nsIDocument::FrameRequestCallbackHolder holder(aCallback);
-  return mDoc->ScheduleFrameRequestCallback(holder, aHandle);
+  return mDoc->ScheduleFrameRequestCallback(aCallback, aHandle);
+}
+
+NS_IMETHODIMP
+nsGlobalWindow::RequestAnimationFrame(const JS::Value& aCallback,
+                                      JSContext* cx,
+                                      int32_t* aHandle)
+{
+  FORWARD_TO_INNER(RequestAnimationFrame, (aCallback, cx, aHandle),
+                   NS_ERROR_NOT_INITIALIZED);
+
+  if (!aCallback.isObject() || !JS_ObjectIsCallable(cx, &aCallback.toObject())) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  nsRefPtr<FrameRequestCallback> callback =
+    new FrameRequestCallback(&aCallback.toObject());
+
+  nsIDocument::FrameRequestCallbackHolder holder(callback);
+  return RequestAnimationFrame(holder, aHandle);
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::MozCancelRequestAnimationFrame(int32_t aHandle)
 {
   return MozCancelAnimationFrame(aHandle);
 }
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -56,16 +56,17 @@
 #include "nsIDOMTouchEvent.h"
 #include "nsIInlineEventHandlers.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsIIdleObserver.h"
 #include "nsIDOMWakeLock.h"
 #ifdef MOZ_GAMEPAD
 #include "nsDOMGamepad.h"
 #endif
+#include "nsIDocument.h"
 
 #include "mozilla/dom/EventTarget.h"
 
 // JS includes
 #include "jsapi.h"
 
 #ifdef MOZ_B2G
 #include "nsIDOMWindowB2G.h"
@@ -1024,16 +1025,19 @@ protected:
   // Helper for getComputedStyle and getDefaultComputedStyle
   nsresult GetComputedStyleHelper(nsIDOMElement* aElt,
                                   const nsAString& aPseudoElt,
                                   bool aDefaultStylesOnly,
                                   nsIDOMCSSStyleDeclaration** aReturn);
 
   void PreloadLocalStorage();
 
+  nsresult RequestAnimationFrame(const nsIDocument::FrameRequestCallbackHolder& aCallback,
+                                 int32_t* aHandle);
+
   // When adding new member variables, be careful not to create cycles
   // through JavaScript.  If there is any chance that a member variable
   // could own objects that are implemented in JavaScript, then those
   // objects will keep the global object (this object) alive.  To prevent
   // these cycles, ownership of such members must be released in
   // |CleanUp| and |DetachFromDocShell|.
 
   // This member is also used on both inner and outer windows, but
--- a/dom/interfaces/base/nsIDOMWindow.idl
+++ b/dom/interfaces/base/nsIDOMWindow.idl
@@ -20,17 +20,17 @@ interface nsIVariant;
  * The nsIDOMWindow interface is the primary interface for a DOM
  * window object. It represents a single window object that may
  * contain child windows if the document in the window contains a
  * HTML frameset document or if the document contains iframe elements.
  *
  * @see <http://www.whatwg.org/html/#window>
  */
 
-[scriptable, uuid(67af2eda-4a0d-4a08-8a97-81b8fd46f1f4)]
+[scriptable, uuid(5928408e-aca6-4681-ab62-024ac6b13888)]
 interface nsIDOMWindow : nsISupports
 {
   // the current browsing context
   readonly attribute nsIDOMWindow                       window;
 
   /* [replaceable] self */
   readonly attribute nsIDOMWindow                       self;
 
@@ -438,16 +438,19 @@ interface nsIDOMWindow : nsISupports
   /**
    * Request a refresh of this browser window.
    *
    * @see <http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/RequestAnimationFrame/Overview.html>
    */
   // Argument is optional only so we can warn when it's null
   long
     mozRequestAnimationFrame([optional] in nsIFrameRequestCallback aCallback);
+  // jsval because we want a WebIDL callback here
+  [implicit_jscontext]
+  long requestAnimationFrame(in jsval aCallback);
 
   /**
    * Cancel a refresh callback.
    */
   void mozCancelAnimationFrame(in long aHandle);
   // Backwards-compat shim for now to make Google maps work
   void mozCancelRequestAnimationFrame(in long aHandle);