Skip to content

Commit

Permalink
fix script elements, supporting both load and error events
Browse files Browse the repository at this point in the history
  • Loading branch information
smparkes committed Nov 8, 2009
1 parent 5a71614 commit c690b80
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 59 deletions.
15 changes: 9 additions & 6 deletions dist/env.js
Expand Up @@ -5171,22 +5171,22 @@ __extend__(HTMLDocument.prototype, {
});

var __elementPopped__ = function(ns, name, node){
//print('Element Popped: '+ns+" "+name+ " " );
// print('Element Popped: '+ns+" "+name+ " "+ node+" " +node.type+" "+node.nodeName);
var doc = __ownerDocument__(node);
var type = ( node.type === null ) ? "text/javascript" : node.type;
try{
if(node.nodeName.toLowerCase() == 'script' && node.type !== undefined){
if(node.nodeName.toLowerCase() == 'script' && type == "text/javascript"){
//$env.debug("element popped: script\n"+node.xml);
// unless we're parsing in a window context, don't execute scripts
if (doc.parentWindow){
//p.replaceEntities = true;
$env.loadLocalScript(node, null);

var okay = $env.loadLocalScript(node, null);
// only fire event if we actually had something to load
if (node.src && node.src.length > 0){
var event = doc.createEvent();
event.initEvent("load");
event.initEvent( okay ? "load" : "error" );
node.dispatchEvent( event, false );
}
}
}
}
else if (node.nodeName.toLowerCase() == 'frame' ||
Expand Down Expand Up @@ -7136,6 +7136,9 @@ __extend__(HTMLScriptElement.prototype, {
},
onload: function(event){
__eval__(this.getAttribute('onload')||'', this);
},
onerror: function(event){
__eval__(this.getAttribute('onerror')||'', this);
}
});

Expand Down
42 changes: 26 additions & 16 deletions dist/env.rhino.js
Expand Up @@ -144,15 +144,12 @@ var Envjs = function(){
var types, type, src, i, base,
docWrites = [],
write = document.write,
writeln = document.writeln;
//temporarily replace document write becuase the function
//has a different meaning during parsing
/*document.write = function(text){
docWrites.push(text);
};*/
writeln = document.writeln,
okay = true;
var script_type = script.type === null ? "text/javascript" : script.type;
try{
if(script.type){
types = script.type?script.type.split(";"):[];
if(script_type){
types = script_type?script_type.split(";"):[];
for(i=0;i<types.length;i++){
if($env.scriptTypes[types[i]]){
if(script.src){
Expand All @@ -167,7 +164,11 @@ var Envjs = function(){
}
}
base = "" + window.location;
load($env.location(script.src.match(/([^\?#]*)/)[1], base ));
try {
load($env.location(script.src.match(/([^\?#]*)/)[1], base ));
} catch(e) {
okay = false;
}
//lets you register a function to execute
//after the script is loaded
if($env.afterScriptLoad){
Expand All @@ -181,18 +182,23 @@ var Envjs = function(){
$env.loadInlineScript(script);
}
}else{
if(!script.src && script.type == "text/javascript"){
if(!script.src && script_type == "text/javascript"){
$env.loadInlineScript(script);
} else {
// load prohbited ...
okay = false;
}
}
}
}else{
// SMP this branch is probably dead ...
//anonymous type and anonymous src means inline
if(!script.src){
$env.loadInlineScript(script);
}
}
}catch(e){
okay = false;
$env.error("Error loading script.", e);
$env.onScriptLoadError(script);
}finally{
Expand All @@ -203,6 +209,7 @@ var Envjs = function(){
document.write = write;
document.writeln = writeln;*/
}
return okay;
};

$env.loadInlineScript = function(script){};
Expand Down Expand Up @@ -5791,22 +5798,22 @@ __extend__(HTMLDocument.prototype, {
});

var __elementPopped__ = function(ns, name, node){
//print('Element Popped: '+ns+" "+name+ " " );
// print('Element Popped: '+ns+" "+name+ " "+ node+" " +node.type+" "+node.nodeName);
var doc = __ownerDocument__(node);
var type = ( node.type === null ) ? "text/javascript" : node.type;
try{
if(node.nodeName.toLowerCase() == 'script' && node.type !== undefined){
if(node.nodeName.toLowerCase() == 'script' && type == "text/javascript"){
//$env.debug("element popped: script\n"+node.xml);
// unless we're parsing in a window context, don't execute scripts
if (doc.parentWindow){
//p.replaceEntities = true;
$env.loadLocalScript(node, null);

var okay = $env.loadLocalScript(node, null);
// only fire event if we actually had something to load
if (node.src && node.src.length > 0){
var event = doc.createEvent();
event.initEvent("load");
event.initEvent( okay ? "load" : "error" );
node.dispatchEvent( event, false );
}
}
}
}
else if (node.nodeName.toLowerCase() == 'frame' ||
Expand Down Expand Up @@ -7756,6 +7763,9 @@ __extend__(HTMLScriptElement.prototype, {
},
onload: function(event){
__eval__(this.getAttribute('onload')||'', this);
},
onerror: function(event){
__eval__(this.getAttribute('onerror')||'', this);
}
});

Expand Down
12 changes: 6 additions & 6 deletions src/html/document.js
Expand Up @@ -234,22 +234,22 @@ __extend__(HTMLDocument.prototype, {
});

var __elementPopped__ = function(ns, name, node){
//print('Element Popped: '+ns+" "+name+ " " );
// print('Element Popped: '+ns+" "+name+ " "+ node+" " +node.type+" "+node.nodeName);
var doc = __ownerDocument__(node);
var type = ( node.type === null ) ? "text/javascript" : node.type;
try{
if(node.nodeName.toLowerCase() == 'script' && node.type !== undefined){
if(node.nodeName.toLowerCase() == 'script' && type == "text/javascript"){
//$env.debug("element popped: script\n"+node.xml);
// unless we're parsing in a window context, don't execute scripts
if (doc.parentWindow){
//p.replaceEntities = true;
$env.loadLocalScript(node, null);

var okay = $env.loadLocalScript(node, null);
// only fire event if we actually had something to load
if (node.src && node.src.length > 0){
var event = doc.createEvent();
event.initEvent("load");
event.initEvent( okay ? "load" : "error" );
node.dispatchEvent( event, false );
}
}
}
}
else if (node.nodeName.toLowerCase() == 'frame' ||
Expand Down
3 changes: 3 additions & 0 deletions src/html/script.js
Expand Up @@ -65,6 +65,9 @@ __extend__(HTMLScriptElement.prototype, {
},
onload: function(event){
__eval__(this.getAttribute('onload')||'', this);
},
onerror: function(event){
__eval__(this.getAttribute('onerror')||'', this);
}
});

Expand Down
27 changes: 17 additions & 10 deletions src/platform/core.js
Expand Up @@ -139,15 +139,12 @@ var Envjs = function(){
var types, type, src, i, base,
docWrites = [],
write = document.write,
writeln = document.writeln;
//temporarily replace document write becuase the function
//has a different meaning during parsing
/*document.write = function(text){
docWrites.push(text);
};*/
writeln = document.writeln,
okay = true;
var script_type = script.type === null ? "text/javascript" : script.type;
try{
if(script.type){
types = script.type?script.type.split(";"):[];
if(script_type){
types = script_type?script_type.split(";"):[];
for(i=0;i<types.length;i++){
if($env.scriptTypes[types[i]]){
if(script.src){
Expand All @@ -162,7 +159,11 @@ var Envjs = function(){
}
}
base = "" + window.location;
load($env.location(script.src.match(/([^\?#]*)/)[1], base ));
try {
load($env.location(script.src.match(/([^\?#]*)/)[1], base ));
} catch(e) {
okay = false;
}
//lets you register a function to execute
//after the script is loaded
if($env.afterScriptLoad){
Expand All @@ -176,18 +177,23 @@ var Envjs = function(){
$env.loadInlineScript(script);
}
}else{
if(!script.src && script.type == "text/javascript"){
if(!script.src && script_type == "text/javascript"){
$env.loadInlineScript(script);
} else {
// load prohbited ...
okay = false;
}
}
}
}else{
// SMP this branch is probably dead ...
//anonymous type and anonymous src means inline
if(!script.src){
$env.loadInlineScript(script);
}
}
}catch(e){
okay = false;
$env.error("Error loading script.", e);
$env.onScriptLoadError(script);
}finally{
Expand All @@ -198,6 +204,7 @@ var Envjs = function(){
document.write = write;
document.writeln = writeln;*/
}
return okay;
};

$env.loadInlineScript = function(script){};
Expand Down
1 change: 1 addition & 0 deletions test/html/script.js
@@ -0,0 +1 @@
//
39 changes: 29 additions & 10 deletions test/index.html
@@ -1,4 +1,4 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr" id="html">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Expand Down Expand Up @@ -70,9 +70,10 @@ <h2 id="userAgent"></h2>
<iframe id="emptyiframe" name="emtpyiframe" style="display:none;"></iframe>

<script>
var usingEnvjsSpecificJar = false;
var usingEnvjsSpecificJar = false, rhino = false;
try {
usingEnvjsSpecificJar = whichJarFile == "envjs";
rhino = true;
} catch (e){;}
if (usingEnvjsSpecificJar){
eventFrameLoaded = eventFrameClicked = 0;
Expand Down Expand Up @@ -108,28 +109,46 @@ <h2 id="userAgent"></h2>
<script>
function onloadHandlerThatShouldntExecute(){
var t = document.createTextNode(
'Paragraph created by execution of script-onload *BAD* event handler.');
'Paragraph created by execution of script *BAD* event handler.');
var p = document.createElement('p');
p.setAttribute('id', 'pShouldntBeCreated');
p.appendChild(t);
document.getElementsByTagName('body')[0].appendChild(p);
}
</script>
<script onload="onloadHandlerThatShouldntExecute();">
function scriptOnloadEventHandler(tag){
function scriptEventHandler(tag){
var t = document.createTextNode(
'Paragraph created by execution of script-onload event handler.');
'Paragraph created by execution of script event handler.');
var p = document.createElement('p');
p.setAttribute('id', 'pCreatedByScriptOnload'+tag);
p.setAttribute('id', 'pCreatedByScript'+tag);
p.appendChild(t);
document.getElementsByTagName('body')[0].appendChild(p);
}
</script>
<script>
// Generic case: allow scripts (not on rhino, which can't detect failures)
if (!rhino) {
js_enabled = Envjs.scriptTypes["text/javascript"];
Envjs.scriptTypes["text/javascript"] = true;
}
</script>
<script src="html/missingScript.js"
onload="try{scriptOnloadEventHandler('A');}catch(e){;}" />
<script src="html/missingScript.js"
onload="try{scriptOnloadEventHandler('B');}catch(e){;}"></script>

onerror="try{scriptEventHandler('A');}catch(e){;}"
onload="try{scriptEventHandler('B');}catch(e){;}"></script>
<script>
// Rhino case: these will succeed anyway
if (rhino) {
js_enabled = Envjs.scriptTypes["text/javascript"];
Envjs.scriptTypes["text/javascript"] = true;
}
</script>
<script src="html/script.js"
onerror="try{scriptEventHandler('C');}catch(e){;}"
onload="try{scriptEventHandler('D');}catch(e){;}"></script>
<script>
Envjs.scriptTypes["text/javascript"] = js_enabled;
</script>

<dl id="dl" style="display:none;">
<div id="main" style="display: none;">
Expand Down
28 changes: 17 additions & 11 deletions test/unit/onload.js
Expand Up @@ -14,7 +14,7 @@ test("Execution of onload events in top-level document",
function() {

// top-level window-onload works, or test framework wouldn't run.....
expect(7);
expect(10);

var mtch = document.getElementById('pCreatedByBodyOnload').innerHTML.
match(/dynamically-generated paragraph/);
Expand Down Expand Up @@ -61,23 +61,29 @@ test("Execution of onload events in top-level document",
"img-onload handler executes when img.src assigned");
}catch(e){print(e);}

mtch = document.getElementById('pCreatedByScriptOnloadA').innerHTML.
match(/script-onload event handler/);
mtch = document.getElementById('pCreatedByScriptA').innerHTML.
match(/script event handler/);
try{ ok(mtch && mtch.length > 0,
"Got confirmation that script-onload handler executed, empty tag");
}catch(e){print(e);}
"Got confirmation that script-onerror handler executed");
}catch(e){print(e);}

try{ ok(!document.getElementById('pCreatedByScriptB'),
"Got confirmation that script-onload handler did not execute");
}catch(e){print(e);}

/* : script doesn't have onload in html5
mtch = document.getElementById('pCreatedByScriptOnloadB').innerHTML.
match(/script-onload event handler/);
mtch = document.getElementById('pCreatedByScriptD').innerHTML.
match(/script event handler/);
try{ ok(mtch && mtch.length > 0,
"Script-onload handler executed, with open/close tag pair");
"Got confirmation that script-onload handler executed");
}catch(e){print(e);}

try{ ok(!document.getElementById('pCreatedByScriptC'),
"Got confirmation that script-onerror handler did not execute");
}catch(e){print(e);}
*/

mtch = document.getElementById('pShouldntBeCreated');
try{ ok(!(mtch),
"Confirmed that script-onload handler that shouldn't execute actually didn't");
"Confirmed that script-onload handler that shouldn't execute actually didn't");
}catch(e){print(e);}
});

Expand Down

0 comments on commit c690b80

Please sign in to comment.