Bug 935203: Provide introductionType information for JS code appearing in event handlers. r=bz
authorJim Blandy <jimb@mozilla.com>
Mon, 24 Feb 2014 15:31:47 -0800
changeset 170644 684a53eafa313de2749dc9d3e3b4485936cfd527
parent 170643 7bfc35e8d2b571a0c6a49368990495a578e4b3a3
child 170645 b157f5d0c2352769ef7fa073ec3a6a7abaaed991
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersbz
bugs935203
milestone30.0a1
Bug 935203: Provide introductionType information for JS code appearing in event handlers. r=bz
dom/events/nsEventListenerManager.cpp
toolkit/devtools/server/tests/mochitest/chrome.ini
toolkit/devtools/server/tests/mochitest/test_Debugger.Source.prototype.element.html
toolkit/devtools/server/tests/mochitest/test_Debugger.Source.prototype.introductionType.html
--- a/dom/events/nsEventListenerManager.cpp
+++ b/dom/events/nsEventListenerManager.cpp
@@ -864,17 +864,18 @@ nsEventListenerManager::CompileEventHand
     uint32_t argCount;
     const char **argNames;
     nsContentUtils::GetEventArgNames(aElement->GetNameSpaceID(),
                                      aListenerStruct->mTypeAtom,
                                      &argCount, &argNames);
 
     JSAutoCompartment ac(cx, context->GetWindowProxy());
     JS::CompileOptions options(cx);
-    options.setFileAndLine(url.get(), lineNo)
+    options.setIntroductionType("eventHandler")
+           .setFileAndLine(url.get(), lineNo)
            .setVersion(SCRIPTVERSION_DEFAULT);
 
     JS::Rooted<JS::Value> targetVal(cx);
     // Go ahead and wrap into the current compartment of cx directly.
     JS::Rooted<JSObject*> wrapScope(cx, JS::CurrentGlobalOrNull(cx));
     if (WrapNewBindingObject(cx, wrapScope, aElement, &targetVal)) {
       MOZ_ASSERT(targetVal.isObject());
 
--- a/toolkit/devtools/server/tests/mochitest/chrome.ini
+++ b/toolkit/devtools/server/tests/mochitest/chrome.ini
@@ -7,16 +7,17 @@ support-files =
   nonchrome_unsafeDereference.html
   inspector_getImageData.html
   large-image.jpg
   small-image.gif
   Debugger.Source.prototype.element.js
   Debugger.Source.prototype.element-2.js
   Debugger.Source.prototype.element.html
 
+[test_Debugger.Source.prototype.introductionType.html]
 [test_Debugger.Source.prototype.element.html]
 [test_Debugger.Script.prototype.global.html]
 [test_connection-manager.html]
 [test_device.html]
 [test_inspector-changeattrs.html]
 [test_inspector-changevalue.html]
 [test_inspector-hide.html]
 [test_inspector-insert.html]
--- a/toolkit/devtools/server/tests/mochitest/test_Debugger.Source.prototype.element.html
+++ b/toolkit/devtools/server/tests/mochitest/test_Debugger.Source.prototype.element.html
@@ -1,14 +1,14 @@
 <!DOCTYPE HTML>
 <html>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=941876
 
-Debugger.Source.prototype.element and .attributeName should report the DOM
+Debugger.Source.prototype.element and .elementAttributeName should report the DOM
 element to which code is attached (if any), and how.
 -->
 <head>
   <meta charset="utf-8">
   <title>Debugger.Source.prototype.element should return owning element</title>
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
 </head>
@@ -52,23 +52,23 @@ window.onload = function () {
 
   function franzDebuggerHandler(frame) {
     log += 'f';
 
     // The top stack frame should be franz, belonging to the script element.
     ok(frame.callee.displayName === 'franz', 'top frame is franz');
     ok(frame.script.source.element === DOFor(doc.getElementById('franz')),
        'top frame source belongs to element franz');
-    ok(frame.script.source.attributeName === undefined,
+    ok(frame.script.source.elementAttributeName === undefined,
        "top frame source doesn't belong to an attribute");
 
     // The second stack frame should belong to heinrich.
     ok(frame.older.script.source.element === DOFor(doc.getElementById('heinrich')),
        "second frame source belongs to element heinrich");
-    ok(frame.older.script.source.attributeName === undefined,
+    ok(frame.older.script.source.elementAttributeName === undefined,
        "second frame source doesn't belong to an attribute");
 
     // The next stack frame should belong to heidi's onclick handler.
     ok(frame.older.older.script.source.element === DOFor(doc.getElementById('heidi')),
        'third frame source belongs to element heidi');
     ok(frame.older.older.script.source.elementAttributeName === 'onclick',
        "third frame source belongs to 'onclick' attribute");
 
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/server/tests/mochitest/test_Debugger.Source.prototype.introductionType.html
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=935203
+
+Debugger.Source.prototype.introductionType should return 'eventHandler' for
+JavaScrip appearing in an inline event handler attribute.
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Debugger.Source.prototype.introductionType should identify event handlers</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+</head>
+<body>
+<pre id="test">
+<script>
+
+Components.utils.import("resource://gre/modules/jsdebugger.jsm");
+addDebuggerToGlobal(this);
+
+window.onload = function () {
+  SimpleTest.waitForExplicitFinish();
+
+  var log = ''
+  var dbg;
+  var iframeDO, doc;
+  var Tootles, TootlesDO;
+
+  // Create an iframe to debug.
+  var iframe = document.createElement("iframe");
+  iframe.src = "data:text/html,<div id='Tootles' onclick='debugger;'>Auddie</div>";
+  iframe.onload = onLoadHandler;
+  document.body.appendChild(iframe);
+
+  function onLoadHandler() {
+    log += 'l';
+    // Now that the iframe's window has been created, we can add
+    // it as a debuggee.
+    dbg = new Debugger;
+    dbg.onDebuggerStatement = TootlesClickDebugger;
+    iframeDO = dbg.addDebuggee(iframe.contentWindow);
+    doc = iframe.contentWindow.document;
+
+    Tootles = doc.getElementById('Tootles');
+    TootlesDO = iframeDO.makeDebuggeeValue(Tootles);
+
+    // Send a click event to Tootles.
+    Tootles.dispatchEvent(new Event('click'));
+  }
+
+  function TootlesClickDebugger(frame) {
+    log += 'TC';
+    ok(frame.script.source.element === TootlesDO,
+       "top frame source belongs to element 'Tootles'");
+    ok(frame.script.source.elementAttributeName === 'onclick',
+       "top frame source belongs to 'onclick' attribute");
+    // And, the actual point of this test:
+    ok(frame.script.source.introductionType === 'eventHandler',
+       "top frame source's introductionType is 'eventHandler'");
+
+    // Dynamically assign some text as a handler, and invoke that handler.
+    dbg.onDebuggerStatement = TootlesDragDebugger;
+    Tootles.setAttribute('ondrag', 'debugger;');
+    Tootles.dispatchEvent(new Event('drag'));
+  }
+
+  function TootlesDragDebugger(frame) {
+    log += 'TD';
+    ok(frame.script.source.element === TootlesDO,
+       "top frame source belongs to element 'Tootles'");
+    ok(frame.script.source.elementAttributeName === 'ondrag',
+       "top frame source belongs to 'ondrag' attribute");
+    // And, the actual point of this test:
+    ok(frame.script.source.introductionType === 'eventHandler',
+       "top frame source's introductionType is 'eventHandler'");
+
+    ok(log === 'lTCTD', "All tests ran.");
+    SimpleTest.finish();
+  }
+}
+</script>
+</pre>
+</body>
+</html>