Revision: 3610
Author: metaweta
Date: Sun Jul 26 00:01:26 2009
Log: Fix binding of $dis for event listeners
http://codereview.appspot.com/96153

Fixes issue 1089.

The keyword "this" gets rewritten to "thisNode___" in an onclick
attribute, but to "$dis" in a valija function.  We were invoking
valija event listeners with "$dis" bound to USELESS.

[email protected]

http://code.google.com/p/google-caja/source/detail?r=3610

Modified:
 /trunk/src/com/google/caja/plugin/domita.js
 /trunk/tests/com/google/caja/plugin/domita_test_untrusted.html

=======================================
--- /trunk/src/com/google/caja/plugin/domita.js Fri Jul 24 16:47:03 2009
+++ /trunk/src/com/google/caja/plugin/domita.js Sun Jul 26 00:01:26 2009
@@ -3788,12 +3788,11 @@
   if (___.startCallerStack) { ___.startCallerStack(); }
   imports.isProcessingEvent___ = true;
   try {
+    var node = imports.tameNode___(thisNode, true);
     return ___.callPub(
-        handler, 'call',
-        [___.USELESS,
-         imports.tameEvent___(event),
-         imports.tameNode___(thisNode, true)
-         ]);
+        handler,
+        'call',
+        [ node, imports.tameEvent___(event), node ]);
   } catch (ex) {
     if (ex && ex.cajitaStack___ && 'undefined' !== (typeof console)) {
       console.error('Event dispatch %s: %s',
=======================================
--- /trunk/tests/com/google/caja/plugin/domita_test_untrusted.html Thu Jul 23 15:06:08 2009 +++ /trunk/tests/com/google/caja/plugin/domita_test_untrusted.html Sun Jul 26 00:01:26 2009
@@ -349,6 +349,10 @@
  ><input id="test-focus-blur-1">
 </p>

+<p class="testcontainer" id="test-this-in-event-handlers"
+ ><input type="checkbox" id="test-this-in-event-handlers-1" />
+</p>
+
 <p class="testcontainer" id="test-document-body-appendChild"
>I should be the last element until something is appended to document.body</p>

@@ -2420,6 +2424,24 @@
   pass('test-table-elements');
 });

+jsunitRegister('testThisInEventHandlers',
+               function testThisInEventHandlers() {
+  var inp = document.getElementById('test-this-in-event-handlers-1');
+
+  // By declaring f() to be cajita, but supplying it as the 'call'
+  // property of the object passed to the event listener, we get
+  // access to the value the function is supposed to use for the
+  // 'this' keyword, even in cajita.
+  function f($dis, event, thisNode) {
+    "use cajita";
+    // In an event handler, "this" should be bound to the node.
+    assertEquals($dis, thisNode);
+    pass('test-this-in-event-handlers');
+  }
+  inp.addEventListener('click', {call: f}, false);
+  directAccess.click(inp);
+});
+
 jsunitRegister('testDocumentBodyAppendChild',
                function testDocumentBodyAppendChild() {
   var notWhitespaceRe = new RegExp('\\S');

Reply via email to