summaryrefslogtreecommitdiffstats
path: root/devtools/server/tests/mochitest/test_Debugger.Source.prototype.element.html
blob: 3cbc223539d3091615348091003b3a2ad8b99fca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=941876

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>
<body>
<pre id="test">
<script>

Components.utils.import("resource://gre/modules/jsdebugger.jsm");
addDebuggerToGlobal(this);

window.onload = function () {
  SimpleTest.waitForExplicitFinish();

  var log = '';
  var doc, dieter, ulrich, isolde, albrecht;
  var dbg, iframeDO, DOFor;

  // Create an iframe to debug.
  // We can't use a data: URL here, because we want to test script elements
  // that refer to the JavaScript via 'src' attributes, and data: documents
  // can't refer to those. So we use a separate HTML document.
  var iframe = document.createElement("iframe");
  iframe.src = "Debugger.Source.prototype.element.html";
  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 = franzDebuggerHandler;
    iframeDO = dbg.addDebuggee(iframe.contentWindow);
    DOFor = iframeDO.makeDebuggeeValue.bind(iframeDO);

    // Send a click event to heidi.
    doc = iframe.contentWindow.document;
    doc.getElementById('heidi').dispatchEvent(new Event('click'));
  }

  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.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.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");

    // Try a dynamically inserted inline script element.
    ulrich = doc.createElement('script');
    ulrich.text = 'debugger;'
    dbg.onDebuggerStatement = ulrichDebuggerHandler;
    doc.body.appendChild(ulrich);
  }

  function ulrichDebuggerHandler(frame) {
    log += 'u';

    // The top frame should be ulrich's text.
    ok(frame.script.source.element === DOFor(ulrich),
       "top frame belongs to ulrich");
    ok(frame.script.source.elementAttributeName === undefined,
       "top frame is not on an attribute of ulrich");

    // Try a dynamically inserted out-of-line script element.
    isolde = doc.createElement('script');
    isolde.setAttribute('src', 'Debugger.Source.prototype.element-2.js');
    isolde.setAttribute('id', 'idolde, my dear');
    dbg.onDebuggerStatement = isoldeDebuggerHandler;
    doc.body.appendChild(isolde);
  }

  function isoldeDebuggerHandler(frame) {
    log += 'i';

    // The top frame should belong to isolde.
    ok(frame.script.source.element === DOFor(isolde),
       "top frame belongs to isolde");
    info("frame.script.source.element is: " + uneval(frame.script.source.element));
    if (typeof frame.script.source.element.unsafeDereference() == 'object') {
       info("   toString: " + frame.script.source.element.unsafeDereference());
       info("   id: " + frame.script.source.element.unsafeDereference().id);
    }

    ok(frame.script.source.elementAttributeName === undefined,
       "top frame source is not an attribute of isolde");
    info("frame.script.source.elementAttributeName is: " +
         uneval(frame.script.source.elementAttributeName));

    // Try a dynamically created div element with a handler.
    dieter = doc.createElement('div');
    dieter.setAttribute('id', 'dieter');
    dieter.setAttribute('ondrag', 'debugger;');
    dbg.onDebuggerStatement = dieterDebuggerHandler;
    dieter.dispatchEvent(new Event('drag'));
 }

 function dieterDebuggerHandler(frame) {
    log += 'd';

    // The top frame should belong to dieter's ondrag handler.
    ok(frame.script.source.element === DOFor(dieter),
       "second event's handler belongs to dieter");
    ok(frame.script.source.elementAttributeName === 'ondrag',
       "second event's handler is on dieter's 'ondrag' element");

    // Try sending an 'onresize' event to the window.
    //
    // Note that we only want Debugger to see the events we send, not any
    // genuine resize events accidentally generated by the test harness (see bug
    // 1162067). So we mark our events as cancelable; that seems to be the only
    // bit chrome can fiddle on an Event that content code will see and that
    // won't affect propagation. Then, the content event only runs its
    // 'debugger' statement when the event is cancelable. It's a kludge.
    dbg.onDebuggerStatement = resizeDebuggerHandler;
    iframe.contentWindow.dispatchEvent(new Event('resize', { cancelable: true }));
  }

  function resizeDebuggerHandler(frame) {
    log += 'e';

    // The top frame should belong to the body's 'onresize' handler, even
    // though we sent the message to the window and it was handled.
    ok(frame.script.source.element === DOFor(doc.body),
       "onresize event handler belongs to body element");
    ok(frame.script.source.elementAttributeName === 'onresize',
       "onresize event handler is on body element's 'onresize' attribute");

    // In SVG, the event and the attribute that holds that event's handler
    // have different names. Debugger.Source.prototype.elementAttributeName
    // should report (as one might infer) the attribute name, not the event
    // name.
    albrecht = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
    albrecht.setAttribute('onload', 'debugger;');
    dbg.onDebuggerStatement = SVGLoadHandler;
    albrecht.dispatchEvent(new Event("SVGLoad"));
  }

  function SVGLoadHandler(frame) {
    log += 's';

    // The top frame's source should be on albrecht's 'onload' attribute.
    ok(frame.script.source.element === DOFor(albrecht),
       "SVGLoad event handler belongs to albrecht");
    ok(frame.script.source.elementAttributeName === 'onload',
       "SVGLoad event handler is on albrecht's 'onload' attribute");

    ok(log === 'lfuides', "all tests actually ran");
    SimpleTest.finish();
  }
}

</script>
</pre>
</body>
</html>