Comparing version 0.2.1 to 0.2.2
@@ -374,1 +374,20 @@ | ||
}; | ||
//TODO: move the following into level2/html once applyDocumentFeatures is moved | ||
//into a separate module | ||
var framePrototype = require("./jsdom/level2/index").dom.level2.html.HTMLFrameElement.prototype; | ||
var oldSetAttribute = framePrototype.setAttribute; | ||
framePrototype.setAttribute = function(name, value) { | ||
oldSetAttribute.apply(this, arguments); | ||
if(name === 'src') { | ||
exports.applyDocumentFeatures(this._contentDocument, this._ownerDocument.implementation._features); | ||
//if doc.__scriptContext is present, use it (this happens when a script in the browser | ||
//dynamically creates and appends a frame/iframe to the document): this ensures script | ||
//running in the frame/iframe can access window.parent properly | ||
var doc = this._ownerDocument, parent = doc.__scriptContext || doc.parentWindow, | ||
contentWindow = this._contentDocument.parentWindow; | ||
contentWindow.parent = parent; | ||
contentWindow.top = parent.top; | ||
} | ||
}; |
@@ -7,16 +7,16 @@ //Make configurable from docType?? | ||
var singleTags = { | ||
area: 1, | ||
base: 1, | ||
basefont: 1, | ||
br: 1, | ||
col: 1, | ||
frame: 1, | ||
hr: 1, | ||
img: 1, | ||
input: 1, | ||
isindex: 1, | ||
link: 1, | ||
meta: 1, | ||
param: 1, | ||
embed: 1 | ||
area: 1, | ||
base: 1, | ||
basefont: 1, | ||
br: 1, | ||
col: 1, | ||
frame: 1, | ||
hr: 1, | ||
img: 1, | ||
input: 1, | ||
isindex: 1, | ||
link: 1, | ||
meta: 1, | ||
param: 1, | ||
embed: 1 | ||
}; | ||
@@ -28,7 +28,7 @@ | ||
singleTag: (function() { | ||
var tags = []; | ||
for (var i in singleTags) { | ||
tags.push(i); | ||
} | ||
return new RegExp('<' + tags.join('|<'), 'i'); | ||
var tags = []; | ||
for (var i in singleTags) { | ||
tags.push(i); | ||
} | ||
return new RegExp('<' + tags.join('|<'), 'i'); | ||
})() | ||
@@ -38,3 +38,3 @@ }; | ||
var uncanon = function(str, letter) { | ||
return '-' + letter.toLowerCase(); | ||
return '-' + letter.toLowerCase(); | ||
}; | ||
@@ -44,71 +44,67 @@ | ||
var styleIgnore = { | ||
top: 1, | ||
left: 1, | ||
length : 1, | ||
_importants : 1 | ||
var styleIgnore = { | ||
top: 1, | ||
left: 1, | ||
length : 1, | ||
_importants : 1 | ||
}; | ||
exports.stringifyElement = function stringifyElement(element) { | ||
//sys.puts('Stringify HTML for: ' + element); | ||
var tagName = element.tagName.toLowerCase(), | ||
ret = { | ||
var tagName = element.tagName.toLowerCase(), | ||
ret = { | ||
start: "<" + tagName, | ||
end:'' | ||
}, attributes = [], i, | ||
attribute = null; | ||
}, | ||
attributes = [], | ||
i, | ||
attribute = null; | ||
//sys.puts('Checking Attributes: ' + element._attributes.length); | ||
//sys.puts(sys.inspect(element)); | ||
if (element.attributes.length) { | ||
ret.start += " "; | ||
for (i = 0; i<element.attributes.length; i++) { | ||
attribute = element.attributes.item(i); | ||
attributes.push(attribute.name + '="' + | ||
HTMLEncode(attribute.nodeValue) + '"'); | ||
} | ||
//sys.puts('Checking Attributes: ' + element._attributes.length); | ||
//sys.puts(sys.inspect(element)); | ||
if (element.attributes.length) { | ||
ret.start += " "; | ||
for (i = 0; i<element.attributes.length; i++) { | ||
attribute = element.attributes.item(i); | ||
attributes.push(attribute.name + '="' + | ||
HTMLEncode(attribute.nodeValue) + '"'); | ||
} | ||
ret.start += attributes.join(" "); | ||
} | ||
ret.start += attributes.join(" "); | ||
if (element.style) { | ||
var | ||
styleAttrs = [], | ||
keys = Object.keys(element.style), | ||
i, key, | ||
l=keys.length; | ||
for (i=0; i<l; i++) { | ||
key = keys[i]; | ||
value = element.style[key]; | ||
if (element.style) { | ||
var styleAttrs = [], | ||
keys = Object.keys(element.style), | ||
key, value, | ||
l = keys.length; | ||
for (i=0; i<l; i++) { | ||
key = keys[i]; | ||
value = element.style[key]; | ||
if (!styleIgnore[key] && typeof value !== 'function') { | ||
var use = true; | ||
if (i === 'position' && value === 'static') { | ||
use = false; | ||
} | ||
if (element.style[i] === '') { | ||
use = false; | ||
} | ||
if (use) { | ||
styleAttrs.push(key.replace(expr.upperCaseChars, uncanon) + ': ' + | ||
HTMLEncode(value)); | ||
} | ||
} | ||
if (!styleIgnore[key] && | ||
typeof value !== 'function' && | ||
!/^\d+$/.test(key) && // Skip the integral keys that specify the order of the CSS properties | ||
(key !== 'position' || value !== 'static') && | ||
element.style[i] !== '') { | ||
styleAttrs.push(key.replace(expr.upperCaseChars, uncanon) + ': ' + | ||
HTMLEncode(value)); | ||
} | ||
if (styleAttrs.length) { | ||
ret.start += ' style="' + styleAttrs.join('; ') + '"'; | ||
} | ||
} | ||
if (styleAttrs.length) { | ||
ret.start += ' style="' + styleAttrs.join('; ') + '"'; | ||
} | ||
} | ||
if (singleTags[tagName]) { | ||
if (isXHTML) { | ||
ret.start += "/"; | ||
} | ||
ret.start += ">"; | ||
ret.end = ''; | ||
} else { | ||
ret.start += ">"; | ||
ret.end = "</" + tagName + ">"; | ||
if (singleTags[tagName]) { | ||
if (isXHTML) { | ||
ret.start += "/"; | ||
} | ||
return ret; | ||
ret.start += ">"; | ||
ret.end = ''; | ||
} else { | ||
ret.start += ">"; | ||
ret.end = "</" + tagName + ">"; | ||
} | ||
return ret; | ||
}; | ||
@@ -122,3 +118,3 @@ | ||
} | ||
var dt = '<!DOCTYPE ' + doctype.name; | ||
@@ -130,3 +126,3 @@ if (doctype.publicId) { | ||
if (!doctype.publicId && doctype.systemId) { | ||
dt += ' SYSTEM ' | ||
dt += ' SYSTEM '; | ||
} | ||
@@ -154,4 +150,3 @@ if (doctype.systemId) { | ||
if (node.nodeType && | ||
node.nodeType === node.ENTITY_REFERENCE_NODE) | ||
{ | ||
node.nodeType === node.ENTITY_REFERENCE_NODE) { | ||
node = node._entity; | ||
@@ -204,3 +199,2 @@ } | ||
} | ||
//require('sys').puts(require('sys').inspect(ret)); | ||
return ret; | ||
@@ -207,0 +201,0 @@ }; |
@@ -10,3 +10,3 @@ var sys = require('sys'), | ||
jsdom = require('../../jsdom'), | ||
vm = require('vm'); | ||
Contextify = require('contextify'); | ||
@@ -97,7 +97,2 @@ function NOT_IMPLEMENTED(target) { | ||
function DOMWindow(options) { | ||
this.frames = [this]; | ||
this.contentWindow = this; | ||
this.window = this; | ||
this.self = this; | ||
var href = (options || {}).url || 'file://' + __filename; | ||
@@ -139,21 +134,12 @@ this.location = URL.parse(href); | ||
__proto__: dom, | ||
get document() { | ||
return this._document; | ||
}, | ||
set document(value) { | ||
this._document = value; | ||
if (value) { | ||
value.parentWindow = this; | ||
} | ||
}, | ||
close : function() { | ||
if (this._document) { | ||
if (this._document.body) { | ||
this._document.body.innerHTML = ""; | ||
if (this.document) { | ||
if (this.document.body) { | ||
this.document.body.innerHTML = ""; | ||
} | ||
if (this._document.close) { | ||
this._document.close(); | ||
if (this.document.close) { | ||
this.document.close(); | ||
} | ||
delete this._document; | ||
delete this.document; | ||
} | ||
@@ -163,5 +149,3 @@ | ||
if (this.__scriptContext) { | ||
delete this.__scriptContext; | ||
} | ||
this.window = this.self = this.parent = this.top = null; | ||
}, | ||
@@ -236,5 +220,7 @@ getComputedStyle: function(node) { | ||
// This is the last chance we have to properly update the window | ||
// so turn it into a context now. | ||
window = vm.createContext(window); | ||
Contextify(window); | ||
var global = window.getGlobal(); | ||
window.frames = [global]; | ||
window.window = window.contentWindow = window.self = window.parent = window.top = global; | ||
return window; | ||
@@ -408,3 +394,3 @@ }; | ||
var DOC_HTML5 = /<!doctype html>/i, | ||
DOC_TYPE = /<!DOCTYPE (\w(.|\n)*)">/i; | ||
DOC_TYPE = /<!DOCTYPE (\w(.|\n)*)">/i, | ||
DOC_TYPE_START = '<!DOCTYPE ', | ||
@@ -445,4 +431,4 @@ DOC_TYPE_END = '">'; | ||
doctype = doctype[1].split(' "'); | ||
var _id1 = doctype.pop().replace(/"/g, ''), | ||
_id2 = doctype.pop().replace(/"/g, ''); | ||
var _id1 = doctype.length ? doctype.pop().replace(/"/g, '') : '', | ||
_id2 = doctype.length ? doctype.pop().replace(/"/g, '') : ''; | ||
@@ -520,3 +506,4 @@ if (_id1.indexOf('-//') !== -1) { | ||
if (!this._parentWindow) { | ||
this._parentWindow = exports.windowAugmentation(dom, {document: this, url: this.URL}); | ||
var window = exports.windowAugmentation(dom, {document: this, url: this.URL}); | ||
this._parentWindow = window.getGlobal(); | ||
} | ||
@@ -527,3 +514,3 @@ return this._parentWindow; | ||
dom.Document.prototype.__defineSetter__('parentWindow', function(window) { | ||
this._parentWindow = window; | ||
this._parentWindow = window.getGlobal(); | ||
}); | ||
@@ -530,0 +517,0 @@ |
@@ -149,3 +149,3 @@ /* | ||
update: function() { | ||
if (this._version < this._element._version) { | ||
if (this._element && this._version < this._element._version) { | ||
for (var i = 0; i < this._length; i++) { | ||
@@ -164,7 +164,7 @@ this[i] = undefined; | ||
toArray: function() { | ||
return this.update(); | ||
return this.update() || []; | ||
}, | ||
get length() { | ||
this.update(); | ||
return this._length; | ||
return this._length || 0; | ||
}, | ||
@@ -171,0 +171,0 @@ item: function(index) { |
@@ -267,11 +267,10 @@ var core = require("./core").dom.level2.core, | ||
check: function() { | ||
if (!q.paused && !this.prev && | ||
((this.data !== null && this.data !== undefined) || | ||
(this.err !== null && this.err !== undefined))) { | ||
if (!q.paused && !this.prev && this.fired){ | ||
callback(this.err, this.data); | ||
q.tail = this.next; | ||
if (this.next) { | ||
this.next.prev = null; | ||
this.next.check(); | ||
} | ||
}else{//q.tail===this | ||
q.tail = null; | ||
} | ||
} | ||
@@ -285,2 +284,3 @@ } | ||
return function(err, data) { | ||
item.fired = 1; | ||
item.err = err; | ||
@@ -292,6 +292,13 @@ item.data = data; | ||
resume: function() { | ||
if(!this.paused){ | ||
return; | ||
} | ||
this.paused = false; | ||
if (this.tail) { | ||
this.tail.check(); | ||
var head = this.tail; | ||
while(head && head.prev){ | ||
head = head.prev; | ||
} | ||
if(head){ | ||
head.check(); | ||
} | ||
} | ||
@@ -1598,10 +1605,12 @@ }; | ||
if (this._contentDocument) { | ||
this._contentDocument.parentWindow.close(); | ||
delete this._contentDocument; // TODO: better cleanup | ||
} | ||
var url = core.resourceLoader.resolve(this._ownerDocument, value); | ||
this._contentDocument = new core.HTMLDocument({ | ||
url: value, | ||
url: url, | ||
documentRoot: this._ownerDocument._documentRoot | ||
}); | ||
core.resourceLoader.load(this, value, function(html, filename) { | ||
core.resourceLoader.load(this, url, function(html, filename) { | ||
this._contentDocument.write(html); | ||
@@ -1608,0 +1617,0 @@ this._contentDocument.close(); |
@@ -1,9 +0,6 @@ | ||
var vm = require('vm'); | ||
exports.javascript = function(element, code, filename) { | ||
if (element.ownerDocument && element.ownerDocument.parentWindow) { | ||
var window = element.ownerDocument.parentWindow; | ||
var doc = element.ownerDocument, window = doc && doc.parentWindow; | ||
if (window) { | ||
try { | ||
vm.createScript(code, filename).runInContext(window); | ||
window.run(code, filename); | ||
} catch (e) { | ||
@@ -10,0 +7,0 @@ element.trigger( |
{ | ||
"name": "jsdom", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "A javascript implementation of the W3C DOM", | ||
@@ -77,3 +77,3 @@ "keywords": [ | ||
{ | ||
"name" : "Robin", | ||
"name" : "Robin Zhong", | ||
"email" : "fbzhong@gmail.com" | ||
@@ -88,2 +88,5 @@ }, | ||
"email" : "liucougar@gmail.com" | ||
}, | ||
{ | ||
"name" : "Brian McDaniel (http://github.com/brianmcd)" | ||
} | ||
@@ -111,5 +114,6 @@ ], | ||
"dependencies": { | ||
"htmlparser": ">=1.7.0", | ||
"request" : ">=1.0.0", | ||
"cssom" : ">=0.2.0" | ||
"htmlparser" : ">=1.7.0", | ||
"request" : ">=1.0.0", | ||
"cssom" : ">=0.2.0", | ||
"contextify" : ">=0.0.1" | ||
}, | ||
@@ -116,0 +120,0 @@ "devDependencies" : { |
@@ -275,2 +275,60 @@ var path = require("path"); | ||
load_mutiple_resources_with_defer_close: function(test) { | ||
var html = '<html><head></head><body>\ | ||
<frame src="../level2/html/files/iframe.html"></frame>\ | ||
<frame src="../level2/html/files/iframe.html"></frame>\ | ||
<frame src="../level2/html/files/iframe.html"></frame>\ | ||
</body></html>'; | ||
var doc = jsdom.jsdom(html, null, {features: {FetchExternalResources: ['frame'], ProcessExternalResources: ['frame']}, | ||
deferClose:true}); | ||
test.ok(doc._queue.paused, 'resource queue should be paused'); | ||
var check_handle, timeout_handle = setTimeout(function() { | ||
doc.onload=null; | ||
doc.parentWindow.close(); | ||
if(check_handle) { | ||
clearTimeout(check_handle); | ||
} | ||
test.ok(false, "timed out when waiting for onload to fire"); | ||
test.done(); | ||
}, 1000); //1 second timeout | ||
function check() { | ||
var q = doc._queue, h = q.tail, count=0; | ||
check_handle = null; | ||
while(h){ | ||
if(h.fired) { | ||
count++; | ||
h = h.prev; | ||
} else { | ||
check_handle = setTimeout(check, 50); | ||
return; | ||
} | ||
} | ||
test.equal(count, 3, 'there should be 3 resources in the resource queue'); | ||
doc.close(); | ||
} | ||
check_handle = setTimeout(check, 50); | ||
doc.onload = function() { | ||
clearTimeout(timeout_handle); | ||
test.done(); | ||
}; | ||
}, | ||
resource_queue: function(test) { | ||
//ResourceQueue is not exported, so grab it from a doc | ||
var doc = jsdom.jsdom(), q = doc._queue, counter = 0, increment=function() {counter++;}; | ||
var queueHandles = [q.push(increment), q.push(increment)]; | ||
queueHandles[0](null, true); | ||
queueHandles.push(q.push(increment)); | ||
queueHandles[1](null, true); | ||
queueHandles[2](null, true); | ||
test.strictEqual(counter, 3); | ||
test.strictEqual(q.tail, null); | ||
test.done(); | ||
}, | ||
understand_file_protocol: function(test) { | ||
@@ -396,4 +454,4 @@ var html = '\ | ||
test.strictEqual(window.results[2], true, "this should equal window.window"); | ||
//TODO: issue 250 | ||
//test.strictEqual(window.results[3], true, "this should equal document.parentWindow"); | ||
test.strictEqual(window.results[3], true, "this should equal document.parentWindow"); | ||
test.strictEqual(window.document.parentWindow, window, "outside window context, document.parentWindow should be window as well"); | ||
test.done(); | ||
@@ -424,2 +482,39 @@ }, | ||
frame_parent: function(test) { | ||
var window = jsdom.jsdom('<html><head><script>aGlobal=1;\ | ||
var iframe = document.createElement("iframe");\ | ||
iframe.src = "' + __dirname + '/files/iframe.html";\ | ||
document.body.appendChild(iframe);</script></head>\ | ||
<body></body></html>',null, {features:{FetchExternalResources: ['script','iframe'], | ||
ProcessExternalResources: ['script','iframe']}}).createWindow(); | ||
window.iframe.onload = function(){ | ||
test.strictEqual(window.DONE, 1); | ||
test.strictEqual(window.PARENT_IS_TOP, true); | ||
//insert a script tag to make sure the global set in the iframe is visible | ||
//in the parent window context | ||
var doc = window.document, script = doc.createElement('script'); | ||
script.textContent = 'results=[aGlobal, DONE, PARENT_IS_TOP]'; | ||
doc.body.appendChild(script); | ||
//the script is executed asynchronously after insertion to the document, | ||
//so setTimeout is needed | ||
setTimeout(function(){ | ||
test.deepEqual(window.results, [1, 1, true]); | ||
test.done(); | ||
},0); | ||
}; | ||
}, | ||
frame_src_relative_to_parent_doc: function(test) { | ||
var window = jsdom.jsdom('<html><body>\ | ||
<iframe src="./files/iframe.html"></iframe>\ | ||
</body></html>',null, {url:__dirname+"/test.html", features:{FetchExternalResources: ['script','iframe'], | ||
ProcessExternalResources: ['script','iframe']}}).createWindow(); | ||
window.document.onload = function(){ | ||
test.strictEqual(window.LOADED_FRAME, 1); | ||
test.strictEqual(window.PARENT_IS_TOP, true); | ||
test.done(); | ||
}; | ||
}, | ||
url_resolution: function(test) { | ||
@@ -785,4 +880,39 @@ var html = '\ | ||
}); | ||
}, | ||
timer_executes_in_context : function (test) { | ||
jsdom.env('<a />', [__dirname + '/files/timer_in_context.js'], function (errors, window) { | ||
setTimeout(function () { | ||
test.ok(window.x == 1); | ||
test.done(); | ||
}, 1); | ||
}); | ||
}, | ||
// see: https://github.com/tmpvar/jsdom/issues/259 | ||
issue_259 : function(test) { | ||
try { | ||
jsdom.jsdom('<!DOCTYPE svg>\n<svg version="1.1"></svg>'); | ||
} catch (e) { | ||
console.log(e); | ||
test.ok(false, 'Incomplete doctype should not throw an error'); | ||
} | ||
test.done(); | ||
}, | ||
issues_230_259 : function(test) { | ||
var instr = '<html><body style="color: #ffffff; foo: bar"></body></html>'; | ||
var doc = jsdom.html(instr); | ||
test.ok(doc.outerHTML.match(/0: *color/) === null); | ||
test.done(); | ||
}, | ||
// see: https://github.com/tmpvar/jsdom/issues/262 | ||
issues_262 : function(test) { | ||
var document = jsdom.html('<html><body></body></html>'); | ||
var a = document.createElement('a'); | ||
a.style.width = '100%'; | ||
test.ok(a.getAttribute('style').match(/^\s*width\s*:\s*100%\s*;?\s*$/)); | ||
test.done(); | ||
} | ||
}; |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
33748442
298
141583
13
4
+ Addedcontextify@>=0.0.1
+ Addedbindings@1.5.0(transitive)
+ Addedcontextify@1.0.0(transitive)
+ Addedfile-uri-to-path@1.0.0(transitive)
+ Addednan@2.20.0(transitive)