Bug 978657: Provide introductionType information for HTML and XUL <script> elements. r=smaug

This commit is contained in:
Jim Blandy 2014-03-12 13:10:02 -07:00
parent 1bd3fd7475
commit 4141d7c0f0
5 changed files with 94 additions and 14 deletions

View File

@ -1006,6 +1006,7 @@ nsScriptLoader::FillCompileOptionsForRequest(nsScriptLoadRequest *aRequest,
// aRequest ended up getting script data from, as the script filename.
nsContentUtils::GetWrapperSafeScriptFilename(mDocument, aRequest->mURI, aRequest->mURL);
aOptions->setIntroductionType("scriptElement");
aOptions->setFileAndLine(aRequest->mURL.get(), aRequest->mLineNo);
aOptions->setVersion(JSVersion(aRequest->mJSVersion));
aOptions->setCompileAndGo(JS_IsGlobalObject(aScopeChain));

View File

@ -2643,7 +2643,8 @@ nsXULPrototypeScript::Compile(const char16_t* aText,
// Ok, compile it to create a prototype script object!
NS_ENSURE_TRUE(JSVersion(mLangVersion) != JSVERSION_UNKNOWN, NS_OK);
JS::CompileOptions options(cx);
options.setFileAndLine(urlspec.get(), aLineNo)
options.setIntroductionType("scriptElement")
.setFileAndLine(urlspec.get(), aLineNo)
.setVersion(JSVersion(mLangVersion));
// If the script was inline, tell the JS parser to save source for
// Function.prototype.toSource(). If it's out of line, we retrieve the

View File

@ -293,5 +293,11 @@ function runNextTest() {
SimpleTest.finish()
return;
}
_tests.shift()();
var fn = _tests.shift();
try {
fn();
} catch (ex) {
info("Test function " + (fn.name ? "'" + fn.name + "' " : "") +
"threw an exception: " + ex);
}
}

View File

@ -81,7 +81,7 @@ window.onload = function () {
// information. (In the future, we certainly could point at the call
// that inserted the script element into the document; if that happens,
// we can update this test.)
ok(frame2.script.source.introductionType === undefined,
ok(frame2.script.source.introductionType === 'scriptElement',
"older frame has no introduction type");
ok(frame2.script.source.introductionScript === undefined,
"older frame has no introduction script");

View File

@ -20,7 +20,6 @@ JavaScrip appearing in an inline event handler attribute.
Components.utils.import("resource://gre/modules/jsdebugger.jsm");
addDebuggerToGlobal(this);
var log = ''
var dbg;
var iframeDO, doc;
var Tootles, TootlesDO;
@ -33,12 +32,13 @@ window.onload = function () {
addTest(function setup() {
// Create an iframe to debug.
var iframe = document.createElement("iframe");
iframe.src = "data:text/html,<div id='Tootles' onclick='debugger;'>Auddie</div>";
iframe.src = "data:text/html," +
"<div id='Tootles' onclick='debugger;'>I'm a DIV!</div>" +
"<script id='Auddie'>function auddie() { debugger; }<\/script>";
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;
@ -60,16 +60,14 @@ addTest(function ClickOnTootles() {
Tootles.dispatchEvent(new Event('click'));
function TootlesClickDebugger(frame) {
log += 'TC';
// some sanity checks
ok(frame.script.source.element === TootlesDO,
"top frame source belongs to element 'Tootles'");
ok(frame.script.source.elementAttributeName === 'onclick',
is(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',
is(frame.script.source.introductionType, 'eventHandler',
"top frame source's introductionType is 'eventHandler'");
runNextTest();
@ -86,16 +84,14 @@ addTest(function DragTootles() {
Tootles.dispatchEvent(new Event('drag'));
function TootlesDragDebugger(frame) {
log += 'TD';
// sanity checks
ok(frame.script.source.element === TootlesDO,
"top frame source belongs to element 'Tootles'");
ok(frame.script.source.elementAttributeName === 'ondrag',
is(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',
is(frame.script.source.introductionType, 'eventHandler',
"top frame source's introductionType is 'eventHandler'");
runNextTest();
@ -103,6 +99,82 @@ addTest(function DragTootles() {
});
// Check the introduction type of an in-markup script element.
addTest(function checkAuddie() {
var fnDO = iframeDO.getOwnPropertyDescriptor('auddie').value;
var AuddieDO = iframeDO.makeDebuggeeValue(doc.getElementById('Auddie'));
ise(fnDO.class, 'Function',
"Script element 'Auddie' defined function 'auddie'.");
ok(fnDO.script.source.element === AuddieDO,
"Function auddie's script belongs to script element 'Auddie'");
is(fnDO.script.source.elementAttributeName, undefined,
"Function auddie's script doesn't belong to any attribute of 'Auddie'");
is(fnDO.script.source.introductionType, 'scriptElement',
"Function auddie's script's source was introduced by a script element");
runNextTest();
});
// Check the introduction type of a dynamically inserted script element.
addTest(function InsertRover() {
dbg.onDebuggerStatement = RoverDebugger;
var rover = doc.createElement('script');
var roverDO = iframeDO.makeDebuggeeValue(rover);
rover.text = 'debugger;';
doc.body.appendChild(rover);
function RoverDebugger(frame) {
// sanity checks
ok(frame.script.source.element === roverDO,
"Rover script belongs to Rover");
ok(frame.script.source.elementAttributeName === undefined,
"Rover script doesn't belong to an attribute of Rover");
// Check the introduction type.
ok(frame.script.source.introductionType === 'scriptElement',
"Rover script's introduction type is 'scriptElement'");
runNextTest();
}
});
// Create a XUL document with a script element, and check its introduction type.
addTest(function XULDocumentScript() {
var xulFrame = document.createElement('iframe');
xulFrame.src = "data:application/vnd.mozilla.xul+xml;charset=utf-8," +
"<?xml version=\"1.0\"?>" +
"<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'>" +
"<script id='xulie'>function xulScriptFunc() { debugger; }<\/script>" +
"</window>";
xulFrame.onload = xulLoaded;
info("Appending iframe containing XUL document");
document.body.appendChild(xulFrame);
function xulLoaded() {
info("Loaded XUL document");
var xulFrameDO = dbg.addDebuggee(xulFrame.contentWindow);
var xulDoc = xulFrame.contentWindow.document;
var xulieDO = xulFrameDO.makeDebuggeeValue(xulDoc.getElementById('xulie'));
var xulFnDO = xulFrameDO.getOwnPropertyDescriptor('xulScriptFunc').value;
ise(typeof xulFnDO, 'object', "XUL script element defined 'xulScriptFunc'");
ise(xulFnDO.class, 'Function',
"XUL global 'xulScriptFunc' is indeed a function");
// A XUL document's script elements' code gets shared amongst all
// instantiations of the document, so there's no specific DOM element
// we can attribute the code to.
ise(xulFnDO.script.source.element, undefined,
"XUL script code should not be attributed to any individual element");
ise(xulFnDO.script.source.introductionType, 'scriptElement',
"xulScriptFunc's introduction type is 'scriptElement'");
runNextTest();
}
});
</script>
</pre>
</body>