Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'android'
- Manifest: devtools/server/tests/chrome/chrome.toml
<!DOCTYPE HTML>
<html>
<!--
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>
</head>
<body>
<pre id="test">
<script>
"use strict";
const {addSandboxedDebuggerToGlobal} = ChromeUtils.importESModule("resource://gre/modules/jsdebugger.sys.mjs");
addSandboxedDebuggerToGlobal(globalThis);
window.onload = function() {
SimpleTest.waitForExplicitFinish();
let log = "";
let doc, dieter, ulrich, isolde, albrecht;
let dbg, iframeDO;
// 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.
const 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);
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.elementAttributeName === undefined,
"top frame source doesn't belong to an attribute");
// The second stack frame should belong to 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.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.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";
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.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.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.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.elementAttributeName === "onload",
"SVGLoad event handler is on albrecht's 'onload' attribute");
ok(log === "lfuides", "all tests actually ran");
SimpleTest.finish();
}
};
</script>
</pre>
</body>
</html>