Reviewers: ihab.awad,

Description:
Fixes <https://code.google.com/p/google-caja/issues/detail?id=1741>.

Please review this at https://codereview.appspot.com/12926048/

Affected files:
  M     src/com/google/caja/plugin/domado.js
  M     tests/com/google/caja/plugin/test-domado-events-guest.html
  M     tests/com/google/caja/plugin/test-scan-guest.js


Index: tests/com/google/caja/plugin/test-domado-events-guest.html
===================================================================
--- tests/com/google/caja/plugin/test-domado-events-guest.html (revision 5562) +++ tests/com/google/caja/plugin/test-domado-events-guest.html (working copy)
@@ -457,6 +457,52 @@
   });
 </script>

+<p class="testcontainer" id="testRequestAnimationFrame">
+  requestAnimationFrame<br>
+</p>
+<script type="text/javascript">
+ var hasRAF = directAccess.evalInHostFrame('!!window.requestAnimationFrame');
+  jsunitRegisterIf(hasRAF,
+                   'testRequestAnimationFrame',
+                   function testRequestAnimationFrame() {
+ // We use the same cancel-wrapper as setTimeout does, so not bothering to
+    // test cancel matching, just that the functionality works.
+
+    var frame1Ran = 0;
+    var frame2Ran = 0;
+    var frame2Time = -1;
+    var frame3Ran = 0;
+    function r1f(time) { frame1Ran++; }
+    function r2f(time) { frame2Ran++; frame2Time = time; }
+    function r3f(time) {
+      assertEquals('2 before 3', 2, frame2Ran);
+      assertEquals('same time as previous callback', frame2Time, time);
+      frame3Ran++;
+    }
+
+    var r1 = requestAnimationFrame(r1f);
+    var r21 = requestAnimationFrame(r2f);
+    var r22 = requestAnimationFrame(r2f);  // spec'd to queue duplicate
+    var r3 = requestAnimationFrame(jsunitCallback(r3f));
+
+    var cr = cancelAnimationFrame(r1);
+    assertEquals('cancel return value', undefined, cr);
+    cancelAnimationFrame(undefined);  // should not fail
+
+    var t0 = Date.now();
+    setTimeout(jsunitCallback(function final() {
+      assertEquals('final #1', 0, frame1Ran);
+      assertEquals('final #2', 2, frame2Ran);
+      assertEquals('final #3', 1, frame3Ran);
+      requestAnimationFrame(function(time) {
+        assertTrue('timing (' + frame2Time + ' ' + time + ')',
+            frame2Time < time);
+        pass('testRequestAnimationFrame');
+      });
+    }), 200);
+  });
+</script>
+
 <p class="clickme testcontainer" id="testInnerhtmlOnclick">
   do not click yet
 </p>
Index: tests/com/google/caja/plugin/test-scan-guest.js
===================================================================
--- tests/com/google/caja/plugin/test-scan-guest.js     (revision 5562)
+++ tests/com/google/caja/plugin/test-scan-guest.js     (working copy)
@@ -20,6 +20,7 @@
  *
  * @requires JSON, WeakMap, Proxy, document, console, location,
  *     setTimeout, clearTimeout, setInterval, clearInterval,
+ *     requestAnimationFrame, cancelAnimationFrame,
  *     cajaVM, directAccess, inES5Mode, getUrlParam,
  *     assertTrue, assertEquals, pass, jsunitFail,
  *     Event, HTMLInputElement, HTMLMediaElement, HTMLTableRowElement,
@@ -1352,6 +1353,10 @@
     argsByIdentity(clearTimeout, genCall());
     argsByIdentity(setInterval, G.none);
     argsByIdentity(clearInterval, genCall());
+    if (window.requestAnimationFrame) {
+      argsByIdentity(requestAnimationFrame, genCall(genString));
+      argsByIdentity(cancelAnimationFrame, genCall());
+    }
     argsByIdentity(isNaN, genCall(genSmallInteger));
     argsByIdentity(parseInt, genCall(genString));
     argsByIdentity(parseFloat, genCall(genString));
Index: src/com/google/caja/plugin/domado.js
===================================================================
--- src/com/google/caja/plugin/domado.js        (revision 5562)
+++ src/com/google/caja/plugin/domado.js        (working copy)
@@ -1437,7 +1437,7 @@
      * This is safe even if accessed across frame since the same
      * map is never used with more than one version of setTimeout.
      */
-    function tameSetAndClear(target, set, clear, setName, clearName) {
+ function tameSetAndClear(target, set, clear, setName, clearName, passArg) {
       var ids = new WeakMap();
       makeFunctionAccessible(set);
       makeFunctionAccessible(clear);
@@ -1457,9 +1457,9 @@
           //   * Passing a string-like object which gets taken as code.
           //   * Non-standard arguments to the callback.
           //   * Non-standard effects of callback's return value.
-          var actionWrapper = function() {
-            action();
-          };
+          var actionWrapper = passArg
+            ? function(time) { action(+time); }  // requestAnimationFrame
+            : function() { action(); };
           id = set(actionWrapper, delayMillis | 0);
         } else {
           id = undefined;
@@ -7023,12 +7023,20 @@
           TameWindow.prototype,
function (code, millis) { return window.setTimeout(code, millis); },
           function (id) { return window.clearTimeout(id); },
-          'setTimeout', 'clearTimeout');
+          'setTimeout', 'clearTimeout', false);
       tameSetAndClear(
           TameWindow.prototype,
function (code, millis) { return window.setInterval(code, millis); },
           function (id) { return window.clearInterval(id); },
-          'setInterval', 'clearInterval');
+          'setInterval', 'clearInterval', false);
+      if (window.requestAnimationFrame) {
+        tameSetAndClear(
+            TameWindow.prototype,
+            function (code) {  // no time arg
+                return window.requestAnimationFrame(code); },
+            function (id) { return window.cancelAnimationFrame(id); },
+            'requestAnimationFrame', 'cancelAnimationFrame', true);
+      }
       var noopWindowFunctionProp = Props.markPropMaker(function(env) {
         var prop = env.prop;
         var notify = true;


--

--- You received this message because you are subscribed to the Google Groups "Google Caja Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to