From 12782399535cfee02df692947baf54d9a0a15810 Mon Sep 17 00:00:00 2001 From: thatcher Date: Fri, 19 Feb 2010 09:47:36 -0500 Subject: [PATCH] finally got frame/mutli-window scoping reintegrated so polluting scripts can only affect local global scope --- .gitignore | 3 +- dist/env.js | 189 +++++++++++-------------- dist/env.rhino.js | 259 +++++++++++++++++++---------------- dist/event.js | 8 +- dist/html.js | 61 +++------ dist/parser.js | 26 ++-- dist/platform/core.js | 50 ++++--- dist/platform/rhino.js | 70 +++++++++- dist/window.js | 32 ++--- dist/xhr.js | 12 +- src/event/mutationevent.js | 8 +- src/html/document.js | 61 +++------ src/parser/domparser.js | 2 +- src/parser/htmldocument.js | 24 ++-- src/platform/core/html.js | 34 ++--- src/platform/core/window.js | 14 +- src/platform/core/xhr.js | 2 +- src/platform/rhino/html.js | 15 ++ src/platform/rhino/window.js | 51 ++++++- src/platform/rhino/xhr.js | 4 +- src/window/frame.js | 2 +- src/window/window.js | 30 ++-- src/xhr/location.js | 10 +- src/xhr/xmlhttprequest.js | 2 +- test/specs/parser/spec.js | 39 +++++- test/specs/platform/rhino.js | 35 ++--- test/specs/window/index.html | 6 +- test/specs/window/spec.js | 116 ++++++++++++---- test/specs/xhr/spec.js | 2 +- 29 files changed, 658 insertions(+), 509 deletions(-) diff --git a/.gitignore b/.gitignore index 22f3d75d..b9205951 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ jshost htmlparser/gwt* htmlparser/html5 htmlparser/build -local_settings.js \ No newline at end of file +local_settings.js +java_pid* \ No newline at end of file diff --git a/dist/env.js b/dist/env.js index 4d4098e8..7490d76f 100644 --- a/dist/env.js +++ b/dist/env.js @@ -89,7 +89,9 @@ Envjs.scriptTypes = { * @param {Object} script * @param {Object} e */ -Envjs.onScriptLoadError = function(script, e){}; +Envjs.onScriptLoadError = function(script, e){ + console.log('error loading script %s %s', script, e); +}; /** @@ -98,17 +100,8 @@ Envjs.onScriptLoadError = function(script, e){}; */ Envjs.loadInlineScript = function(script){ var tmpFile; - try{ - if(Envjs.DEBUG_ENABLED){ - // - Envjs.writeToTempFile(script.text, 'js') ; - Envjs.load(tmpFile); - }else{ - eval(script.text); - } - }catch(e){ - Envjs.onScriptLoadError(script, e); - } + tmpFile = Envjs.writeToTempFile(script.text, 'js') ; + load(tmpFile); }; @@ -123,13 +116,10 @@ Envjs.loadLocalScript = function(script){ src, i, base, - filename, - // SMP: see also the note in html/document.js about script.type - script_type = script.type === null ? - "text/javascript" : script.type; + filename; - if(script_type){ - types = script_type?script_type.split(";"):[]; + if(script.type){ + types = script.type.split(";"); for(i=0;i 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); - event = doc.createEvent('HTMLEvents'); - event.initEvent("load", false, false); - node.dispatchEvent( event, false ); - } - }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); - } - break; case 'iframe': - node.contentDocument = new HTMLDocument(new DOMImplementation()); - node.contentWindow = { document: node.contentDocument }; + node.contentWindow = { }; + node.contentDocument = new HTMLDocument(new DOMImplementation(), node.contentWindow); + node.contentWindow.document = node.contentDocument node.contentDocument.addEventListener('DOMContentLoaded', function(){ event = node.contentDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); @@ -5159,14 +5124,26 @@ Aspect.around({ }); try{ if (node.src && node.src.length > 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); + //console.log("getting content document for (i)frame from %s", node.src); + Envjs.loadFrame(node, Envjs.uri(node.src)); event = node.contentDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); node.dispatchEvent( event, false ); + }else{ + //I dont like this being here: + //TODO: better mix-in strategy so the try/catch isnt required + try{ + if(Window){ + Envjs.loadFrame(node); + //console.log('src/html/document.js: triggering frame load'); + event = node.contentDocument.createEvent('HTMLEvents'); + event.initEvent("load", false, false); + node.dispatchEvent( event, false ); + } + }catch(e){} } }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); + console.log('error loading html element %s %e', node, e.toString()); } break; case 'link': @@ -8785,7 +8762,7 @@ XMLParser.parseDocument = function(xmlstring, xmldoc, mimetype){ var __fragmentCache__ = {}; HTMLParser.parseDocument = function(htmlstring, htmldoc){ - console.log('HTMLParser.parseDocument %s', htmldoc.async); + //console.log('HTMLParser.parseDocument %s', htmldoc.async); htmldoc.parsing = true; Envjs.parseHtmlDocument(htmlstring, htmldoc, htmldoc.async, null, null); //Envjs.wait(-1); @@ -8909,7 +8886,9 @@ var __elementPopped__ = function(ns, name, node){ case '[object XMLDocument]': return; case '[object HTMLDocument]': - switch(ns){ + switch(node.namespaceURI){ + case "http://n.validator.nu/placeholder/": + return; case null: case "": case "http://www.w3.org/1999/xhtml": @@ -8917,7 +8896,7 @@ var __elementPopped__ = function(ns, name, node){ case 'script': try{ okay = Envjs.loadLocalScript(node, null); - //console.log('loaded script? %s %s', node.uuid, okay); + // console.log('loaded script? %s %s', node.uuid, okay); // only fire event if we actually had something to load if (node.src && node.src.length > 0){ event = doc.createEvent('HTMLEvents'); @@ -8929,26 +8908,16 @@ var __elementPopped__ = function(ns, name, node){ } return; case 'frame': - try{ - if (node.src && node.src.length > 0){ - //console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); - event = doc.createEvent('HTMLEvents'); - event.initEvent("load", false, false); - node.dispatchEvent( event, false ); - } - }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); - } - return; case 'iframe': try{ if (node.src && node.src.length > 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); + //console.log("getting content document for (i)frame from %s", node.src); + Envjs.loadFrame(node, Envjs.uri(node.src)); event = node.ownerDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); node.dispatchEvent( event, false ); + }else{ + //console.log('src/parser/htmldocument: triggering frame load (no src)'); } }catch(e){ console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); @@ -9558,19 +9527,19 @@ Location = function(url, doc, history){ var _this = this, xhr; - console.log('assigning %s',url); + //console.log('assigning %s',url); $url = url; //we can only assign if this Location is associated with a document if($document){ - console.log("fetching %s (async? %s)", url, $document.async); + //console.log("fetching %s (async? %s)", url, $document.async); xhr = new XMLHttpRequest(); xhr.open("GET", url, $document.async); if($document.toString()=="[object HTMLDocument]"){ //tell the xhr to not parse the document as XML - console.log("loading html document"); + //console.log("loading html document"); xhr.onreadystatechange = function(){ - console.log("readyState %s", xhr.readyState); + //console.log("readyState %s", xhr.readyState); if(xhr.readyState === 4){ __exchangeHTMLDocument__($document, xhr.responseText, url); } @@ -9613,7 +9582,7 @@ var __exchangeHTMLDocument__ = function(doc, text, url){ HTMLParser.parseDocument(text, doc); }catch(e){ console.log('parsererror %s', e); - doc = new HTMLDocument(new DOMImplementation()); + doc = new HTMLDocument(new DOMImplementation(), doc.ownerWindow); html = doc.createElement('html'); head = doc.createElement('head'); title = doc.createElement('title'); @@ -9685,7 +9654,7 @@ XMLHttpRequest.prototype = { this.readyState = 1; this.async = (async === false)?false:true; this.method = method || "GET"; - this.url = Envjs.location(url); + this.url = Envjs.uri(url); this.onreadystatechange(); }, setRequestHeader: function(header, value){ @@ -9843,7 +9812,7 @@ __extend__(HTMLFrameElement.prototype,{ this.setAttribute('src', value); if (this.parentNode && value && value.length > 0){ //console.log('loading frame %s', value); - Envjs.loadFrame(this, Envjs.location(value)); + Envjs.loadFrame(this, Envjs.uri(value)); //console.log('event frame load %s', value); event = this.ownerDocument.createEvent('HTMLEvents'); @@ -10053,7 +10022,6 @@ Screen = function(__window__){ }; }; - //These descriptions of window properties are taken loosely David Flanagan's //'JavaScript - The Definitive Guide' (O'Reilly) @@ -10065,14 +10033,15 @@ Screen = function(__window__){ */ Window = function(scope, parent, opener){ + __initStandardObjects__(scope, parent); + // the window property is identical to the self property and to this obj var proxy = new Envjs.proxy(scope, parent); scope.__proxy__ = proxy; scope.__defineGetter__('window', function(){ - return proxy; + return scope; }); - - __initStandardObjects__(scope, parent); + var $uuid = new Date().getTime()+'-'+Math.floor(Math.random()*1000000000000000); __windows__[$uuid] = scope; @@ -10087,7 +10056,7 @@ Window = function(scope, parent, opener){ $htmlImplementation.errorChecking = false; // read only reference to the Document object - var $document = new HTMLDocument($htmlImplementation); + var $document = new HTMLDocument($htmlImplementation, scope); //The version of this application var $version = "0.1"; @@ -10188,12 +10157,7 @@ Window = function(scope, parent, opener){ }, */ get frames(){ - // A read-only array of window objects - if(HTMLCollection){ - return new HTMLCollection($document.getElementsByTagName('frame')); - }else{ - return __setArray__({}, []); - } + return new HTMLCollection($document.getElementsByTagName('frame')); }, get length(){ // should be frames.length, @@ -10218,7 +10182,7 @@ Window = function(scope, parent, opener){ return $location; }, set location(uri){ - uri = Envjs.location(uri); + uri = Envjs.uri(uri); //new Window(this, this.parent, this.opener); if($location.href == uri){ $location.reload(); @@ -10313,7 +10277,7 @@ Window = function(scope, parent, opener){ if(name) _window.name = name; _window.document.async = false; - _window.location.assign(Envjs.location(url)); + _window.location.assign(Envjs.uri(url)); return _window; }, close: function(){ @@ -10329,7 +10293,10 @@ Window = function(scope, parent, opener){ Envjs.prompt(message, defaultMsg); }, onload: function(){}, - onunload: function(){} + onunload: function(){}, + get uuid(){ + return $uuid; + } }); }; @@ -10347,7 +10314,7 @@ var __top__ = function(_scope){ var __windows__ = {}; var __initStandardObjects__ = function(scope, parent){ - + var __Array__; if(!scope.Array){ __Array__ = function(){ @@ -10392,7 +10359,7 @@ var __initStandardObjects__ = function(scope, parent){ return __Number__; }); } - + }; //finally pre-supply the window with the window-like environment diff --git a/dist/env.rhino.js b/dist/env.rhino.js index 723e888f..e65324a3 100644 --- a/dist/env.rhino.js +++ b/dist/env.rhino.js @@ -89,7 +89,9 @@ Envjs.scriptTypes = { * @param {Object} script * @param {Object} e */ -Envjs.onScriptLoadError = function(script, e){}; +Envjs.onScriptLoadError = function(script, e){ + console.log('error loading script %s %s', script, e); +}; /** @@ -98,17 +100,8 @@ Envjs.onScriptLoadError = function(script, e){}; */ Envjs.loadInlineScript = function(script){ var tmpFile; - try{ - if(Envjs.DEBUG_ENABLED){ - // - Envjs.writeToTempFile(script.text, 'js') ; - Envjs.load(tmpFile); - }else{ - eval(script.text); - } - }catch(e){ - Envjs.onScriptLoadError(script, e); - } + tmpFile = Envjs.writeToTempFile(script.text, 'js') ; + load(tmpFile); }; @@ -123,13 +116,10 @@ Envjs.loadLocalScript = function(script){ src, i, base, - filename, - // SMP: see also the note in html/document.js about script.type - script_type = script.type === null ? - "text/javascript" : script.type; + filename; - if(script_type){ - types = script_type?script_type.split(";"):[]; + if(script.type){ + types = script.type.split(";"); for(i=0;i 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); - event = doc.createEvent('HTMLEvents'); - event.initEvent("load", false, false); - node.dispatchEvent( event, false ); - } - }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); - } - break; case 'iframe': - node.contentDocument = new HTMLDocument(new DOMImplementation()); - node.contentWindow = { document: node.contentDocument }; + node.contentWindow = { }; + node.contentDocument = new HTMLDocument(new DOMImplementation(), node.contentWindow); + node.contentWindow.document = node.contentDocument node.contentDocument.addEventListener('DOMContentLoaded', function(){ event = node.contentDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); @@ -5581,14 +5608,26 @@ Aspect.around({ }); try{ if (node.src && node.src.length > 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); + //console.log("getting content document for (i)frame from %s", node.src); + Envjs.loadFrame(node, Envjs.uri(node.src)); event = node.contentDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); node.dispatchEvent( event, false ); + }else{ + //I dont like this being here: + //TODO: better mix-in strategy so the try/catch isnt required + try{ + if(Window){ + Envjs.loadFrame(node); + //console.log('src/html/document.js: triggering frame load'); + event = node.contentDocument.createEvent('HTMLEvents'); + event.initEvent("load", false, false); + node.dispatchEvent( event, false ); + } + }catch(e){} } }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); + console.log('error loading html element %s %e', node, e.toString()); } break; case 'link': @@ -9207,7 +9246,7 @@ XMLParser.parseDocument = function(xmlstring, xmldoc, mimetype){ var __fragmentCache__ = {}; HTMLParser.parseDocument = function(htmlstring, htmldoc){ - console.log('HTMLParser.parseDocument %s', htmldoc.async); + //console.log('HTMLParser.parseDocument %s', htmldoc.async); htmldoc.parsing = true; Envjs.parseHtmlDocument(htmlstring, htmldoc, htmldoc.async, null, null); //Envjs.wait(-1); @@ -9331,7 +9370,9 @@ var __elementPopped__ = function(ns, name, node){ case '[object XMLDocument]': return; case '[object HTMLDocument]': - switch(ns){ + switch(node.namespaceURI){ + case "http://n.validator.nu/placeholder/": + return; case null: case "": case "http://www.w3.org/1999/xhtml": @@ -9339,7 +9380,7 @@ var __elementPopped__ = function(ns, name, node){ case 'script': try{ okay = Envjs.loadLocalScript(node, null); - //console.log('loaded script? %s %s', node.uuid, okay); + // console.log('loaded script? %s %s', node.uuid, okay); // only fire event if we actually had something to load if (node.src && node.src.length > 0){ event = doc.createEvent('HTMLEvents'); @@ -9351,26 +9392,16 @@ var __elementPopped__ = function(ns, name, node){ } return; case 'frame': - try{ - if (node.src && node.src.length > 0){ - //console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); - event = doc.createEvent('HTMLEvents'); - event.initEvent("load", false, false); - node.dispatchEvent( event, false ); - } - }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); - } - return; case 'iframe': try{ if (node.src && node.src.length > 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); + //console.log("getting content document for (i)frame from %s", node.src); + Envjs.loadFrame(node, Envjs.uri(node.src)); event = node.ownerDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); node.dispatchEvent( event, false ); + }else{ + //console.log('src/parser/htmldocument: triggering frame load (no src)'); } }catch(e){ console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); @@ -9980,19 +10011,19 @@ Location = function(url, doc, history){ var _this = this, xhr; - console.log('assigning %s',url); + //console.log('assigning %s',url); $url = url; //we can only assign if this Location is associated with a document if($document){ - console.log("fetching %s (async? %s)", url, $document.async); + //console.log("fetching %s (async? %s)", url, $document.async); xhr = new XMLHttpRequest(); xhr.open("GET", url, $document.async); if($document.toString()=="[object HTMLDocument]"){ //tell the xhr to not parse the document as XML - console.log("loading html document"); + //console.log("loading html document"); xhr.onreadystatechange = function(){ - console.log("readyState %s", xhr.readyState); + //console.log("readyState %s", xhr.readyState); if(xhr.readyState === 4){ __exchangeHTMLDocument__($document, xhr.responseText, url); } @@ -10035,7 +10066,7 @@ var __exchangeHTMLDocument__ = function(doc, text, url){ HTMLParser.parseDocument(text, doc); }catch(e){ console.log('parsererror %s', e); - doc = new HTMLDocument(new DOMImplementation()); + doc = new HTMLDocument(new DOMImplementation(), doc.ownerWindow); html = doc.createElement('html'); head = doc.createElement('head'); title = doc.createElement('title'); @@ -10107,7 +10138,7 @@ XMLHttpRequest.prototype = { this.readyState = 1; this.async = (async === false)?false:true; this.method = method || "GET"; - this.url = Envjs.location(url); + this.url = Envjs.uri(url); this.onreadystatechange(); }, setRequestHeader: function(header, value){ @@ -10265,7 +10296,7 @@ __extend__(HTMLFrameElement.prototype,{ this.setAttribute('src', value); if (this.parentNode && value && value.length > 0){ //console.log('loading frame %s', value); - Envjs.loadFrame(this, Envjs.location(value)); + Envjs.loadFrame(this, Envjs.uri(value)); //console.log('event frame load %s', value); event = this.ownerDocument.createEvent('HTMLEvents'); @@ -10475,7 +10506,6 @@ Screen = function(__window__){ }; }; - //These descriptions of window properties are taken loosely David Flanagan's //'JavaScript - The Definitive Guide' (O'Reilly) @@ -10487,14 +10517,15 @@ Screen = function(__window__){ */ Window = function(scope, parent, opener){ + __initStandardObjects__(scope, parent); + // the window property is identical to the self property and to this obj var proxy = new Envjs.proxy(scope, parent); scope.__proxy__ = proxy; scope.__defineGetter__('window', function(){ - return proxy; + return scope; }); - - __initStandardObjects__(scope, parent); + var $uuid = new Date().getTime()+'-'+Math.floor(Math.random()*1000000000000000); __windows__[$uuid] = scope; @@ -10509,7 +10540,7 @@ Window = function(scope, parent, opener){ $htmlImplementation.errorChecking = false; // read only reference to the Document object - var $document = new HTMLDocument($htmlImplementation); + var $document = new HTMLDocument($htmlImplementation, scope); //The version of this application var $version = "0.1"; @@ -10610,12 +10641,7 @@ Window = function(scope, parent, opener){ }, */ get frames(){ - // A read-only array of window objects - if(HTMLCollection){ - return new HTMLCollection($document.getElementsByTagName('frame')); - }else{ - return __setArray__({}, []); - } + return new HTMLCollection($document.getElementsByTagName('frame')); }, get length(){ // should be frames.length, @@ -10640,7 +10666,7 @@ Window = function(scope, parent, opener){ return $location; }, set location(uri){ - uri = Envjs.location(uri); + uri = Envjs.uri(uri); //new Window(this, this.parent, this.opener); if($location.href == uri){ $location.reload(); @@ -10735,7 +10761,7 @@ Window = function(scope, parent, opener){ if(name) _window.name = name; _window.document.async = false; - _window.location.assign(Envjs.location(url)); + _window.location.assign(Envjs.uri(url)); return _window; }, close: function(){ @@ -10751,7 +10777,10 @@ Window = function(scope, parent, opener){ Envjs.prompt(message, defaultMsg); }, onload: function(){}, - onunload: function(){} + onunload: function(){}, + get uuid(){ + return $uuid; + } }); }; @@ -10769,7 +10798,7 @@ var __top__ = function(_scope){ var __windows__ = {}; var __initStandardObjects__ = function(scope, parent){ - + var __Array__; if(!scope.Array){ __Array__ = function(){ @@ -10814,7 +10843,7 @@ var __initStandardObjects__ = function(scope, parent){ return __Number__; }); } - + }; //finally pre-supply the window with the window-like environment diff --git a/dist/event.js b/dist/event.js index 15bfe565..d55d07b5 100644 --- a/dist/event.js +++ b/dist/event.js @@ -717,9 +717,9 @@ KeyboardEvent.DOM_KEY_LOCATION_JOYSTICK = 5; //We dont fire mutation events until someone has registered for them var __supportedMutations__ = /DOMSubtreeModified|DOMNodeInserted|DOMNodeRemoved|DOMAttrModified|DOMCharacterDataModified/; -/*var __fireMutationEvents__ = Aspect.before({ - target: this, - method:__addEventListener__ +var __fireMutationEvents__ = Aspect.before({ + target: EventTarget, + method: 'addEventListener' }, function(target, type){ if(type && type.match(__supportedMutations__)){ //unweaving removes the __addEventListener__ aspect @@ -749,7 +749,7 @@ var __supportedMutations__ = /DOMSubtreeModified|DOMNodeInserted|DOMNodeRemoved| return node; }); } -});*/ +}); /** * @name MutationEvent diff --git a/dist/html.js b/dist/html.js index 24c3a007..ba91d226 100644 --- a/dist/html.js +++ b/dist/html.js @@ -103,11 +103,11 @@ function __setArray__( target, array ) { * * @extends Document */ -HTMLDocument = function(implementation, parentWindow, referrer) { +HTMLDocument = function(implementation, ownerWindow, referrer) { Document.apply(this, arguments); this.referrer = referrer; this.baseURI = "about:blank"; - this.parentWindow = parentWindow; + this.ownerWindow = ownerWindow; }; HTMLDocument.prototype = new Document; @@ -388,19 +388,6 @@ var __stubHTMLDocument__ = function(doc){ } }; -// These two methods are enough to cover all dom 2 manipulations -/*Aspect.around({ - target: Node, - method:"removeChild" -}, function(invocation){ - var event, - node = invocation.arguments[0]; - event = node.ownerDocument.createEvent('MutationEvents'); - event.initEvent('DOMNodeRemoved', true, false, node.parentNode, null, null, null, null); - node.dispatchEvent(event, false); - return invocation.proceed(); - -});*/ Aspect.around({ target: Node, method:"appendChild" @@ -441,33 +428,15 @@ Aspect.around({ node.dispatchEvent( event, false ); } }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); + console.log('error loading html element %s %e', node, e.toString()); } } break; case 'frame': - node.contentDocument = new HTMLDocument(new DOMImplementation()); - node.contentWindow = { document: node.contentDocument }; - node.contentDocument.addEventListener('DOMContentLoaded', function(){ - event = node.contentDocument.createEvent('HTMLEvents'); - event.initEvent("load", false, false); - node.dispatchEvent( event, false ); - }); - try{ - if (node.src && node.src.length > 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); - event = doc.createEvent('HTMLEvents'); - event.initEvent("load", false, false); - node.dispatchEvent( event, false ); - } - }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); - } - break; case 'iframe': - node.contentDocument = new HTMLDocument(new DOMImplementation()); - node.contentWindow = { document: node.contentDocument }; + node.contentWindow = { }; + node.contentDocument = new HTMLDocument(new DOMImplementation(), node.contentWindow); + node.contentWindow.document = node.contentDocument node.contentDocument.addEventListener('DOMContentLoaded', function(){ event = node.contentDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); @@ -475,14 +444,26 @@ Aspect.around({ }); try{ if (node.src && node.src.length > 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); + //console.log("getting content document for (i)frame from %s", node.src); + Envjs.loadFrame(node, Envjs.uri(node.src)); event = node.contentDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); node.dispatchEvent( event, false ); + }else{ + //I dont like this being here: + //TODO: better mix-in strategy so the try/catch isnt required + try{ + if(Window){ + Envjs.loadFrame(node); + //console.log('src/html/document.js: triggering frame load'); + event = node.contentDocument.createEvent('HTMLEvents'); + event.initEvent("load", false, false); + node.dispatchEvent( event, false ); + } + }catch(e){} } }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); + console.log('error loading html element %s %e', node, e.toString()); } break; case 'link': diff --git a/dist/parser.js b/dist/parser.js index 28264320..0e8de007 100644 --- a/dist/parser.js +++ b/dist/parser.js @@ -605,7 +605,7 @@ XMLParser.parseDocument = function(xmlstring, xmldoc, mimetype){ var __fragmentCache__ = {}; HTMLParser.parseDocument = function(htmlstring, htmldoc){ - console.log('HTMLParser.parseDocument %s', htmldoc.async); + //console.log('HTMLParser.parseDocument %s', htmldoc.async); htmldoc.parsing = true; Envjs.parseHtmlDocument(htmlstring, htmldoc, htmldoc.async, null, null); //Envjs.wait(-1); @@ -729,7 +729,9 @@ var __elementPopped__ = function(ns, name, node){ case '[object XMLDocument]': return; case '[object HTMLDocument]': - switch(ns){ + switch(node.namespaceURI){ + case "http://n.validator.nu/placeholder/": + return; case null: case "": case "http://www.w3.org/1999/xhtml": @@ -737,7 +739,7 @@ var __elementPopped__ = function(ns, name, node){ case 'script': try{ okay = Envjs.loadLocalScript(node, null); - //console.log('loaded script? %s %s', node.uuid, okay); + // console.log('loaded script? %s %s', node.uuid, okay); // only fire event if we actually had something to load if (node.src && node.src.length > 0){ event = doc.createEvent('HTMLEvents'); @@ -749,26 +751,16 @@ var __elementPopped__ = function(ns, name, node){ } return; case 'frame': - try{ - if (node.src && node.src.length > 0){ - //console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); - event = doc.createEvent('HTMLEvents'); - event.initEvent("load", false, false); - node.dispatchEvent( event, false ); - } - }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); - } - return; case 'iframe': try{ if (node.src && node.src.length > 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); + //console.log("getting content document for (i)frame from %s", node.src); + Envjs.loadFrame(node, Envjs.uri(node.src)); event = node.ownerDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); node.dispatchEvent( event, false ); + }else{ + //console.log('src/parser/htmldocument: triggering frame load (no src)'); } }catch(e){ console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); diff --git a/dist/platform/core.js b/dist/platform/core.js index e23924f1..2ed5b756 100644 --- a/dist/platform/core.js +++ b/dist/platform/core.js @@ -89,7 +89,9 @@ Envjs.scriptTypes = { * @param {Object} script * @param {Object} e */ -Envjs.onScriptLoadError = function(script, e){}; +Envjs.onScriptLoadError = function(script, e){ + console.log('error loading script %s %s', script, e); +}; /** @@ -98,17 +100,8 @@ Envjs.onScriptLoadError = function(script, e){}; */ Envjs.loadInlineScript = function(script){ var tmpFile; - try{ - if(Envjs.DEBUG_ENABLED){ - // - Envjs.writeToTempFile(script.text, 'js') ; - Envjs.load(tmpFile); - }else{ - eval(script.text); - } - }catch(e){ - Envjs.onScriptLoadError(script, e); - } + tmpFile = Envjs.writeToTempFile(script.text, 'js') ; + load(tmpFile); }; @@ -123,13 +116,10 @@ Envjs.loadLocalScript = function(script){ src, i, base, - filename, - // SMP: see also the note in html/document.js about script.type - script_type = script.type === null ? - "text/javascript" : script.type; + filename; - if(script_type){ - types = script_type?script_type.split(";"):[]; + if(script.type){ + types = script.type.split(";"); for(i=0;i 0){ //console.log('loading frame %s', value); - Envjs.loadFrame(this, Envjs.location(value)); + Envjs.loadFrame(this, Envjs.uri(value)); //console.log('event frame load %s', value); event = this.ownerDocument.createEvent('HTMLEvents'); @@ -262,7 +262,6 @@ Screen = function(__window__){ }; }; - //These descriptions of window properties are taken loosely David Flanagan's //'JavaScript - The Definitive Guide' (O'Reilly) @@ -274,14 +273,15 @@ Screen = function(__window__){ */ Window = function(scope, parent, opener){ + __initStandardObjects__(scope, parent); + // the window property is identical to the self property and to this obj var proxy = new Envjs.proxy(scope, parent); scope.__proxy__ = proxy; scope.__defineGetter__('window', function(){ - return proxy; + return scope; }); - - __initStandardObjects__(scope, parent); + var $uuid = new Date().getTime()+'-'+Math.floor(Math.random()*1000000000000000); __windows__[$uuid] = scope; @@ -296,7 +296,7 @@ Window = function(scope, parent, opener){ $htmlImplementation.errorChecking = false; // read only reference to the Document object - var $document = new HTMLDocument($htmlImplementation); + var $document = new HTMLDocument($htmlImplementation, scope); //The version of this application var $version = "0.1"; @@ -397,12 +397,7 @@ Window = function(scope, parent, opener){ }, */ get frames(){ - // A read-only array of window objects - if(HTMLCollection){ - return new HTMLCollection($document.getElementsByTagName('frame')); - }else{ - return __setArray__({}, []); - } + return new HTMLCollection($document.getElementsByTagName('frame')); }, get length(){ // should be frames.length, @@ -427,7 +422,7 @@ Window = function(scope, parent, opener){ return $location; }, set location(uri){ - uri = Envjs.location(uri); + uri = Envjs.uri(uri); //new Window(this, this.parent, this.opener); if($location.href == uri){ $location.reload(); @@ -522,7 +517,7 @@ Window = function(scope, parent, opener){ if(name) _window.name = name; _window.document.async = false; - _window.location.assign(Envjs.location(url)); + _window.location.assign(Envjs.uri(url)); return _window; }, close: function(){ @@ -538,7 +533,10 @@ Window = function(scope, parent, opener){ Envjs.prompt(message, defaultMsg); }, onload: function(){}, - onunload: function(){} + onunload: function(){}, + get uuid(){ + return $uuid; + } }); }; @@ -556,7 +554,7 @@ var __top__ = function(_scope){ var __windows__ = {}; var __initStandardObjects__ = function(scope, parent){ - + var __Array__; if(!scope.Array){ __Array__ = function(){ @@ -601,7 +599,7 @@ var __initStandardObjects__ = function(scope, parent){ return __Number__; }); } - + }; //finally pre-supply the window with the window-like environment diff --git a/dist/xhr.js b/dist/xhr.js index 4ab571e0..2cb46906 100644 --- a/dist/xhr.js +++ b/dist/xhr.js @@ -529,19 +529,19 @@ Location = function(url, doc, history){ var _this = this, xhr; - console.log('assigning %s',url); + //console.log('assigning %s',url); $url = url; //we can only assign if this Location is associated with a document if($document){ - console.log("fetching %s (async? %s)", url, $document.async); + //console.log("fetching %s (async? %s)", url, $document.async); xhr = new XMLHttpRequest(); xhr.open("GET", url, $document.async); if($document.toString()=="[object HTMLDocument]"){ //tell the xhr to not parse the document as XML - console.log("loading html document"); + //console.log("loading html document"); xhr.onreadystatechange = function(){ - console.log("readyState %s", xhr.readyState); + //console.log("readyState %s", xhr.readyState); if(xhr.readyState === 4){ __exchangeHTMLDocument__($document, xhr.responseText, url); } @@ -584,7 +584,7 @@ var __exchangeHTMLDocument__ = function(doc, text, url){ HTMLParser.parseDocument(text, doc); }catch(e){ console.log('parsererror %s', e); - doc = new HTMLDocument(new DOMImplementation()); + doc = new HTMLDocument(new DOMImplementation(), doc.ownerWindow); html = doc.createElement('html'); head = doc.createElement('head'); title = doc.createElement('title'); @@ -656,7 +656,7 @@ XMLHttpRequest.prototype = { this.readyState = 1; this.async = (async === false)?false:true; this.method = method || "GET"; - this.url = Envjs.location(url); + this.url = Envjs.uri(url); this.onreadystatechange(); }, setRequestHeader: function(header, value){ diff --git a/src/event/mutationevent.js b/src/event/mutationevent.js index 2422042b..7868b8ff 100644 --- a/src/event/mutationevent.js +++ b/src/event/mutationevent.js @@ -2,9 +2,9 @@ //We dont fire mutation events until someone has registered for them var __supportedMutations__ = /DOMSubtreeModified|DOMNodeInserted|DOMNodeRemoved|DOMAttrModified|DOMCharacterDataModified/; -/*var __fireMutationEvents__ = Aspect.before({ - target: this, - method:__addEventListener__ +var __fireMutationEvents__ = Aspect.before({ + target: EventTarget, + method: 'addEventListener' }, function(target, type){ if(type && type.match(__supportedMutations__)){ //unweaving removes the __addEventListener__ aspect @@ -34,7 +34,7 @@ var __supportedMutations__ = /DOMSubtreeModified|DOMNodeInserted|DOMNodeRemoved| return node; }); } -});*/ +}); /** * @name MutationEvent diff --git a/src/html/document.js b/src/html/document.js index d49fd518..5caf7015 100644 --- a/src/html/document.js +++ b/src/html/document.js @@ -7,11 +7,11 @@ * * @extends Document */ -HTMLDocument = function(implementation, parentWindow, referrer) { +HTMLDocument = function(implementation, ownerWindow, referrer) { Document.apply(this, arguments); this.referrer = referrer; this.baseURI = "about:blank"; - this.parentWindow = parentWindow; + this.ownerWindow = ownerWindow; }; HTMLDocument.prototype = new Document; @@ -292,19 +292,6 @@ var __stubHTMLDocument__ = function(doc){ } }; -// These two methods are enough to cover all dom 2 manipulations -/*Aspect.around({ - target: Node, - method:"removeChild" -}, function(invocation){ - var event, - node = invocation.arguments[0]; - event = node.ownerDocument.createEvent('MutationEvents'); - event.initEvent('DOMNodeRemoved', true, false, node.parentNode, null, null, null, null); - node.dispatchEvent(event, false); - return invocation.proceed(); - -});*/ Aspect.around({ target: Node, method:"appendChild" @@ -345,33 +332,15 @@ Aspect.around({ node.dispatchEvent( event, false ); } }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); + console.log('error loading html element %s %e', node, e.toString()); } } break; case 'frame': - node.contentDocument = new HTMLDocument(new DOMImplementation()); - node.contentWindow = { document: node.contentDocument }; - node.contentDocument.addEventListener('DOMContentLoaded', function(){ - event = node.contentDocument.createEvent('HTMLEvents'); - event.initEvent("load", false, false); - node.dispatchEvent( event, false ); - }); - try{ - if (node.src && node.src.length > 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); - event = doc.createEvent('HTMLEvents'); - event.initEvent("load", false, false); - node.dispatchEvent( event, false ); - } - }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); - } - break; case 'iframe': - node.contentDocument = new HTMLDocument(new DOMImplementation()); - node.contentWindow = { document: node.contentDocument }; + node.contentWindow = { }; + node.contentDocument = new HTMLDocument(new DOMImplementation(), node.contentWindow); + node.contentWindow.document = node.contentDocument node.contentDocument.addEventListener('DOMContentLoaded', function(){ event = node.contentDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); @@ -379,14 +348,26 @@ Aspect.around({ }); try{ if (node.src && node.src.length > 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); + //console.log("getting content document for (i)frame from %s", node.src); + Envjs.loadFrame(node, Envjs.uri(node.src)); event = node.contentDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); node.dispatchEvent( event, false ); + }else{ + //I dont like this being here: + //TODO: better mix-in strategy so the try/catch isnt required + try{ + if(Window){ + Envjs.loadFrame(node); + //console.log('src/html/document.js: triggering frame load'); + event = node.contentDocument.createEvent('HTMLEvents'); + event.initEvent("load", false, false); + node.dispatchEvent( event, false ); + } + }catch(e){} } }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); + console.log('error loading html element %s %e', node, e.toString()); } break; case 'link': diff --git a/src/parser/domparser.js b/src/parser/domparser.js index e8a352ca..3d4c58c9 100644 --- a/src/parser/domparser.js +++ b/src/parser/domparser.js @@ -53,7 +53,7 @@ XMLParser.parseDocument = function(xmlstring, xmldoc, mimetype){ var __fragmentCache__ = {}; HTMLParser.parseDocument = function(htmlstring, htmldoc){ - console.log('HTMLParser.parseDocument %s', htmldoc.async); + //console.log('HTMLParser.parseDocument %s', htmldoc.async); htmldoc.parsing = true; Envjs.parseHtmlDocument(htmlstring, htmldoc, htmldoc.async, null, null); //Envjs.wait(-1); diff --git a/src/parser/htmldocument.js b/src/parser/htmldocument.js index 27b80d4b..e861f977 100644 --- a/src/parser/htmldocument.js +++ b/src/parser/htmldocument.js @@ -32,7 +32,9 @@ var __elementPopped__ = function(ns, name, node){ case '[object XMLDocument]': return; case '[object HTMLDocument]': - switch(ns){ + switch(node.namespaceURI){ + case "http://n.validator.nu/placeholder/": + return; case null: case "": case "http://www.w3.org/1999/xhtml": @@ -40,7 +42,7 @@ var __elementPopped__ = function(ns, name, node){ case 'script': try{ okay = Envjs.loadLocalScript(node, null); - //console.log('loaded script? %s %s', node.uuid, okay); + // console.log('loaded script? %s %s', node.uuid, okay); // only fire event if we actually had something to load if (node.src && node.src.length > 0){ event = doc.createEvent('HTMLEvents'); @@ -52,26 +54,16 @@ var __elementPopped__ = function(ns, name, node){ } return; case 'frame': - try{ - if (node.src && node.src.length > 0){ - //console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); - event = doc.createEvent('HTMLEvents'); - event.initEvent("load", false, false); - node.dispatchEvent( event, false ); - } - }catch(e){ - console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); - } - return; case 'iframe': try{ if (node.src && node.src.length > 0){ - console.log("getting content document for (i)frame from %s", node.src); - Envjs.loadFrame(node, Envjs.location(node.src)); + //console.log("getting content document for (i)frame from %s", node.src); + Envjs.loadFrame(node, Envjs.uri(node.src)); event = node.ownerDocument.createEvent('HTMLEvents'); event.initEvent("load", false, false); node.dispatchEvent( event, false ); + }else{ + //console.log('src/parser/htmldocument: triggering frame load (no src)'); } }catch(e){ console.log('error loading html element %s %s %s %e', ns, name, node, e.toString()); diff --git a/src/platform/core/html.js b/src/platform/core/html.js index fa505195..b6d643bb 100644 --- a/src/platform/core/html.js +++ b/src/platform/core/html.js @@ -14,7 +14,9 @@ Envjs.scriptTypes = { * @param {Object} script * @param {Object} e */ -Envjs.onScriptLoadError = function(script, e){}; +Envjs.onScriptLoadError = function(script, e){ + console.log('error loading script %s %s', script, e); +}; /** @@ -23,17 +25,8 @@ Envjs.onScriptLoadError = function(script, e){}; */ Envjs.loadInlineScript = function(script){ var tmpFile; - try{ - if(Envjs.DEBUG_ENABLED){ - // - Envjs.writeToTempFile(script.text, 'js') ; - Envjs.load(tmpFile); - }else{ - eval(script.text); - } - }catch(e){ - Envjs.onScriptLoadError(script, e); - } + tmpFile = Envjs.writeToTempFile(script.text, 'js') ; + load(tmpFile); }; @@ -48,13 +41,10 @@ Envjs.loadLocalScript = function(script){ src, i, base, - filename, - // SMP: see also the note in html/document.js about script.type - script_type = script.type === null ? - "text/javascript" : script.type; + filename; - if(script_type){ - types = script_type?script_type.split(";"):[]; + if(script.type){ + types = script.type.split(";"); for(i=0;i 0){ //console.log('loading frame %s', value); - Envjs.loadFrame(this, Envjs.location(value)); + Envjs.loadFrame(this, Envjs.uri(value)); //console.log('event frame load %s', value); event = this.ownerDocument.createEvent('HTMLEvents'); diff --git a/src/window/window.js b/src/window/window.js index bcb68e7b..f07e30c1 100644 --- a/src/window/window.js +++ b/src/window/window.js @@ -1,4 +1,3 @@ - //These descriptions of window properties are taken loosely David Flanagan's //'JavaScript - The Definitive Guide' (O'Reilly) @@ -10,14 +9,15 @@ */ Window = function(scope, parent, opener){ + __initStandardObjects__(scope, parent); + // the window property is identical to the self property and to this obj var proxy = new Envjs.proxy(scope, parent); scope.__proxy__ = proxy; scope.__defineGetter__('window', function(){ - return proxy; + return scope; }); - - __initStandardObjects__(scope, parent); + var $uuid = new Date().getTime()+'-'+Math.floor(Math.random()*1000000000000000); __windows__[$uuid] = scope; @@ -32,7 +32,7 @@ Window = function(scope, parent, opener){ $htmlImplementation.errorChecking = false; // read only reference to the Document object - var $document = new HTMLDocument($htmlImplementation); + var $document = new HTMLDocument($htmlImplementation, scope); //The version of this application var $version = "0.1"; @@ -133,12 +133,7 @@ Window = function(scope, parent, opener){ }, */ get frames(){ - // A read-only array of window objects - if(HTMLCollection){ - return new HTMLCollection($document.getElementsByTagName('frame')); - }else{ - return __setArray__({}, []); - } + return new HTMLCollection($document.getElementsByTagName('frame')); }, get length(){ // should be frames.length, @@ -163,7 +158,7 @@ Window = function(scope, parent, opener){ return $location; }, set location(uri){ - uri = Envjs.location(uri); + uri = Envjs.uri(uri); //new Window(this, this.parent, this.opener); if($location.href == uri){ $location.reload(); @@ -258,7 +253,7 @@ Window = function(scope, parent, opener){ if(name) _window.name = name; _window.document.async = false; - _window.location.assign(Envjs.location(url)); + _window.location.assign(Envjs.uri(url)); return _window; }, close: function(){ @@ -274,7 +269,10 @@ Window = function(scope, parent, opener){ Envjs.prompt(message, defaultMsg); }, onload: function(){}, - onunload: function(){} + onunload: function(){}, + get uuid(){ + return $uuid; + } }); }; @@ -292,7 +290,7 @@ var __top__ = function(_scope){ var __windows__ = {}; var __initStandardObjects__ = function(scope, parent){ - + var __Array__; if(!scope.Array){ __Array__ = function(){ @@ -337,7 +335,7 @@ var __initStandardObjects__ = function(scope, parent){ return __Number__; }); } - + }; //finally pre-supply the window with the window-like environment diff --git a/src/xhr/location.js b/src/xhr/location.js index ecaef018..c6709723 100644 --- a/src/xhr/location.js +++ b/src/xhr/location.js @@ -116,19 +116,19 @@ Location = function(url, doc, history){ var _this = this, xhr; - console.log('assigning %s',url); + //console.log('assigning %s',url); $url = url; //we can only assign if this Location is associated with a document if($document){ - console.log("fetching %s (async? %s)", url, $document.async); + //console.log("fetching %s (async? %s)", url, $document.async); xhr = new XMLHttpRequest(); xhr.open("GET", url, $document.async); if($document.toString()=="[object HTMLDocument]"){ //tell the xhr to not parse the document as XML - console.log("loading html document"); + //console.log("loading html document"); xhr.onreadystatechange = function(){ - console.log("readyState %s", xhr.readyState); + //console.log("readyState %s", xhr.readyState); if(xhr.readyState === 4){ __exchangeHTMLDocument__($document, xhr.responseText, url); } @@ -171,7 +171,7 @@ var __exchangeHTMLDocument__ = function(doc, text, url){ HTMLParser.parseDocument(text, doc); }catch(e){ console.log('parsererror %s', e); - doc = new HTMLDocument(new DOMImplementation()); + doc = new HTMLDocument(new DOMImplementation(), doc.ownerWindow); html = doc.createElement('html'); head = doc.createElement('head'); title = doc.createElement('title'); diff --git a/src/xhr/xmlhttprequest.js b/src/xhr/xmlhttprequest.js index 2f931e8d..7bfbcb04 100644 --- a/src/xhr/xmlhttprequest.js +++ b/src/xhr/xmlhttprequest.js @@ -29,7 +29,7 @@ XMLHttpRequest.prototype = { this.readyState = 1; this.async = (async === false)?false:true; this.method = method || "GET"; - this.url = Envjs.location(url); + this.url = Envjs.uri(url); this.onreadystatechange(); }, setRequestHeader: function(header, value){ diff --git a/test/specs/parser/spec.js b/test/specs/parser/spec.js index 676f7699..29e8bc11 100644 --- a/test/specs/parser/spec.js +++ b/test/specs/parser/spec.js @@ -172,15 +172,21 @@ test('HTMLElement.innerHTML', function(){ }); -test('HTMLParser.parseDocument', function(){ +test('HTMLParser.parseDocument / simple content', function(){ //one of the easiest way to test the HTMLParser is using frames and //writing the document directly - expect(1); + expect(4); var iframe = document.createElement("iframe"); document.body.appendChild(iframe); iframe.addEventListener('load', function(){ + var doc; ok(true, 'frame loaded'); + + doc = iframe.contentDocument; + ok(doc, 'frame has contentDocument'); + equals(doc+'', '[object HTMLDocument]', 'doc is HTMLDocument') + equals(doc.body.innerHTML,'

this is a pig

', 'innerHTML'); document.body.removeChild( iframe ); start(); }, false); @@ -193,3 +199,32 @@ test('HTMLParser.parseDocument', function(){ }); +test('HTMLParser.parseDocument / malformed content', function(){ + //one of the easiest way to test the HTMLParser is using frames and + //writing the document directly + expect(4); + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + + iframe.addEventListener('load', function(){ + var doc; + ok(true, 'frame loaded'); + + doc = iframe.contentDocument; + ok(doc, 'frame has contentDocument'); + equals(doc+'', '[object HTMLDocument]', 'doc is HTMLDocument') + equals(doc.body.innerHTML,'

this is a pig

', 'innerHTML'); + document.body.removeChild( iframe ); + start(); + }, false); + + var doc = iframe.contentDocument; + doc.open(); + doc.write("

this is a pig"); + doc.close(); + stop(); + +}); + + + diff --git a/test/specs/platform/rhino.js b/test/specs/platform/rhino.js index 14432b73..97c2c9e4 100644 --- a/test/specs/platform/rhino.js +++ b/test/specs/platform/rhino.js @@ -21,32 +21,33 @@ test('Envjs Platform Interfaces Available', function(){ var document = null, path = 'specs/env/spec.html'; -test('Envjs.location', function(){ +test('Envjs.uri', function(){ + var uri; - location = Envjs.location('specs/env/spec.html', 'http://envjs.com/abc123/'); - ok(location, 'Able to create Location'); - equals(location, 'http://envjs.com/abc123/'+path, 'location'); - equals(location.toString(), 'http://envjs.com/abc123/'+path, 'location'); + uri = Envjs.uri('specs/env/spec.html', 'http://envjs.com/abc123/'); + ok(uri, 'Able to create uri'); + equals(uri, 'http://envjs.com/abc123/'+path, 'uri'); + equals(uri.toString(), 'http://envjs.com/abc123/'+path, 'uri'); document = {baseURI:'http://envjs.com/'}; - location = Envjs.location('specs/env/spec.html'); - ok(location, 'Able to create Location'); - equals(location, 'http://envjs.com/specs/env/spec.html', 'location'); - equals(location.toString(), 'http://envjs.com/specs/env/spec.html', 'location'); + uri = Envjs.uri('specs/env/spec.html'); + ok(uri, 'Able to create uri'); + equals(uri, 'http://envjs.com/specs/env/spec.html', 'uri'); + equals(uri.toString(), 'http://envjs.com/specs/env/spec.html', 'uri'); - location = Envjs.location('specs/env/spec.html', 'http://envjs.com/'); - ok(location, 'Able to create Location'); - equals(location, 'http://envjs.com/specs/env/spec.html', 'location'); - equals(location.toString(), 'http://envjs.com/specs/env/spec.html', 'location'); + uri = Envjs.uri('specs/env/spec.html', 'http://envjs.com/'); + ok(uri, 'Able to create uri'); + equals(uri, 'http://envjs.com/specs/env/spec.html', 'uri'); + equals(uri.toString(), 'http://envjs.com/specs/env/spec.html', 'uri'); document = null; - location = Envjs.location('http://envjs.com/specs/env/spec.html'); - ok(location, 'Able to create Location'); - equals(location, 'http://envjs.com/specs/env/spec.html', 'location'); - equals(location.toString(), 'http://envjs.com/specs/env/spec.html', 'location'); + uri = Envjs.uri('http://envjs.com/specs/env/spec.html'); + ok(uri, 'Able to create uri'); + equals(uri, 'http://envjs.com/specs/env/spec.html', 'uri'); + equals(uri.toString(), 'http://envjs.com/specs/env/spec.html', 'uri'); }); diff --git a/test/specs/window/index.html b/test/specs/window/index.html index 6f789b42..420f3979 100644 --- a/test/specs/window/index.html +++ b/test/specs/window/index.html @@ -12,9 +12,11 @@ type="text/javascript" > - diff --git a/test/specs/window/spec.js b/test/specs/window/spec.js index 382dd6e5..26132524 100644 --- a/test/specs/window/spec.js +++ b/test/specs/window/spec.js @@ -213,36 +213,6 @@ test('window.screen', function(){ }); -test('frame proxy', function(){ - - var frame, - doc; - - expect(7); - frame = document.createElement('iframe'); - frame.width = '100%'; - frame.height = '380px'; - frame.frameBorder = '0'; - frame.addEventListener('load', function(){ - - equals(frame.contentWindow.parent, window, '.contentWindow.parent'); - equals(frame.contentWindow.top, window, '.contentWindow.top'); - - ok(frame.contentWindow.Array !== window.Array, '.Array'); - ok(new window.Array(), 'new Array'); - ok(new frame.contentWindow.Array(), 'new Array'); - - doc = frame.contentDocument; - equals(doc.title, 'Envjs Proxy Spec', '.contentDocument.title'); - equals(doc.toString(), '[object HTMLDocument]', '.contentDocument.toString()'); - start(); - - }, false); - frame.src = '../frame/proxy.html'; - document.body.appendChild(frame); - stop(); -}); - test('window.addEventListener / window.dispatchEvent multiple listeners', function(){ expect(36); @@ -307,3 +277,89 @@ test('window.addEventListener / window.dispatchEvent multiple listeners', functi window.dispatchEvent(event); }); + +test('HTMLParser.parseDocument / non-polluting script', function(){ + //one of the easiest way to test the HTMLParser is using frames and + //writing the document directly + expect(4); + var iframe = document.createElement("iframe"), + doc, + win; + + document.body.appendChild(iframe); + doc = iframe.contentDocument; + win = iframe.contentWindow; + + doc.open(); + doc.write("hello"); + doc.close(); + ok(doc, 'frame has contentDocument'); + equals(doc+'', '[object HTMLDocument]', 'doc is HTMLDocument'); + equals(win.ABABABABAB, 123, 'script evaluated in frame context'); + try{ + ABABABABAB; + ok(false, 'script not evaluated top window context: '+ABABABABAB); + }catch(e){ + ok(true, 'script not evaluated top window context'); + } + document.body.removeChild( iframe ); +}); + +test('HTMLParser.parseDocument / polluting script', function(){ + //one of the easiest way to test the HTMLParser is using frames and + //writing the document directly + expect(4); + var iframe = document.createElement("iframe"), + doc, + win; + + document.body.appendChild(iframe); + doc = iframe.contentDocument; + win = iframe.contentWindow; + + doc.open(); + doc.write("hello"); + doc.close(); + ok(doc, 'frame has contentDocument'); + equals(doc+'', '[object HTMLDocument]', 'doc is HTMLDocument'); + equals(win.ABABABABAB, 123, 'script evaluated in frame context'); + try{ + ABABABABAB; + ok(false, 'script not evaluated top window context: '+ABABABABAB); + }catch(e){ + ok(true, 'script not evaluated top window context'); + } + document.body.removeChild( iframe ); +}); + + + +test('frame proxy', function(){ + + var frame, + doc; + + expect(7); + frame = document.createElement('iframe'); + frame.width = '100%'; + frame.height = '380px'; + frame.frameBorder = '0'; + frame.addEventListener('load', function(){ + + equals(frame.contentWindow.parent, window, '.contentWindow.parent'); + equals(frame.contentWindow.top, window, '.contentWindow.top'); + + ok(frame.contentWindow.Array !== window.Array, '.Array'); + ok(new window.Array(), 'new Array'); + ok(new frame.contentWindow.Array(), 'new Array'); + + doc = frame.contentDocument; + equals(doc.title, 'Envjs Proxy Spec', '.contentDocument.title'); + equals(doc.toString(), '[object HTMLDocument]', '.contentDocument.toString()'); + start(); + + }, false); + frame.src = '../frame/proxy.html'; + document.body.appendChild(frame); + stop(); +}); diff --git a/test/specs/xhr/spec.js b/test/specs/xhr/spec.js index 2aa47939..b55aeca4 100644 --- a/test/specs/xhr/spec.js +++ b/test/specs/xhr/spec.js @@ -18,7 +18,7 @@ try{ document = new HTMLDocument(new DOMImplementation()); console.log('mocking global document location.'); - location = new Location(Envjs.location(expected_path, SETTINGS.AJAX_BASE), document); + location = new Location(Envjs.uri(expected_path, SETTINGS.AJAX_BASE), document); document.baseURI = location.href; location.reload(); }