Skip to content

Commit

Permalink
fixed some sidecases with scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
tmpvar committed Feb 16, 2011
1 parent 0e72da6 commit 197624f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 56 deletions.
98 changes: 52 additions & 46 deletions lib/jsdom.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,29 +159,27 @@ exports.jQueryify = exports.jsdom.jQueryify = function (window /* path [optional


exports.env = exports.jsdom.env = function() {

var
args = Array.prototype.slice.call(arguments),
config = exports.env.processArguments(args),
callback = config.done,
processHTML = function(err, html) {
html += '';

html += '';
if(err) {
return callback(err);
}

config.code = config.code || [];

if (typeof config.code === 'string') {
config.code = [config.code];
config.scripts = config.scripts || [];
if (typeof config.scripts === 'string') {
config.scripts = [config.scripts];
}

var
window = exports.html(html).createWindow(),
features = window.document.implementation._features,
docsLoaded = 0,
totalDocs = config.code.length;
totalDocs = config.scripts.length;
readyState = null,
errors = null;

Expand All @@ -193,32 +191,36 @@ exports.env = exports.jsdom.env = function() {
window.document.implementation.addFeature('ProcessExternalResources', ['script']);
window.document.implementation.addFeature('MutationEvents', ['1.0']);

config.code.forEach(function(src) {
var
script = window.document.createElement('script'),
scriptComplete = function() {
docsLoaded++;
if (docsLoaded >= totalDocs) {
window.document.implementation._features = features;
callback(errors, window);
if (config.scripts.length > 0) {
config.scripts.forEach(function(src) {
var
script = window.document.createElement('script'),
scriptComplete = function() {
docsLoaded++;
if (docsLoaded >= totalDocs) {
window.document.implementation._features = features;
callback(errors, window);
}
}
}

script.onload = function() {
scriptComplete()
};
script.onload = function() {
scriptComplete()
};

script.onerror = function(e) {
if (!errors) {
errors = [];
}
errors.push(e.error);
scriptComplete();
};
script.onerror = function(e) {
if (!errors) {
errors = [];
}
errors.push(e.error);
scriptComplete();
};

script.src = src;
window.document.documentElement.appendChild(script);
});
script.src = src;
window.document.documentElement.appendChild(script);
});
} else {
callback(errors, window);
}
};

config.html += '';
Expand All @@ -244,7 +246,7 @@ exports.env = exports.jsdom.env = function() {
Since jsdom.env() is a helper for quickly and easily setting up a
window with scripts and such already loaded into it, the arguments
should be fairly flexible. Here are the requirements
1) collect `html` (url, string, or file on disk) (STRING)
2) load `code` into the window (array of scripts) (ARRAY)
3) callback when resources are `done` (FUNCTION)
Expand All @@ -254,18 +256,22 @@ exports.env = exports.jsdom.env = function() {
+ if there is one argument it had better be an object with atleast
a `html` and `done` property (other properties are gravy)
+
+ arguments above are pulled out of the arguments and put into the
config object that is returned
*/
exports.env.processArguments = function(args) {

if (!args || !args.length || args.length < 1) {
throw new Error('No arguments passed to jsdom.env().');
}

var
required = ['html', 'done'],
props = {
'html' : true,
'done' : true,
'scripts' : false,
'config' : false
},
propKeys = Object.keys(props),
config = {
code : []
},
Expand All @@ -277,21 +283,21 @@ exports.env.processArguments = function(args) {
args.forEach(function(v) {
var type = typeof v;
if (!v) {
return
return;
}
if (type === 'string' || v + '' === v) {
config.html = v;
} else if (type === 'object') {
// Array
if (v.length && v[0]) {
config.code = v;
config.scripts = v;
} else {
// apply missing required properties if appropriate
required.forEach(function(req) {
if (v &&
typeof v[req] !== 'undefined' &&
typeof config[req === 'undefined'])
{
propKeys.forEach(function(req) {

if (typeof v[req] !== 'undefined' &&
typeof config[req] === 'undefined') {

config[req] = v[req];
delete v[req];
}
Expand All @@ -304,11 +310,11 @@ exports.env.processArguments = function(args) {
});
}

required.forEach(function(req) {
if (typeof config[req] === 'undefined') {
propKeys.forEach(function(req) {
var required = props[req];
if (required && typeof config[req] === 'undefined') {
throw new Error("jsdom.env requires a '" + req + "' argument");
}
})

});
return config;
};
22 changes: 12 additions & 10 deletions test/jsdom/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ exports.tests = {
env_with_absolute_file : function() {
jsdom.env({
html : path.join(__dirname, 'files', 'env.html'),
code : [
scripts : [
path.join(__dirname, '..', '..', 'example', 'jquery', 'jquery.js')
],
done : function(errors, window) {
Expand All @@ -85,9 +85,9 @@ exports.tests = {
env_with_non_existant_script : function() {
var html = "<html><body><p>hello world!</p></body></html>";
jsdom.env({
html : html,
code : ['path/to/invalid.js', 'another/invalid.js'],
done : function(errors, window) {
html : html,
scripts : ['path/to/invalid.js', 'another/invalid.js'],
done : function(errors, window) {
assertNotNull("error should not be null", errors);
assertEquals("errors is an array", errors.length, 2)
assertNotNull("window should be valid", window.location);
Expand All @@ -113,9 +113,9 @@ exports.tests = {
server.listen(64000);

jsdom.env({
html : "http://127.0.0.1:64000/html",
code : "http://127.0.0.1:64000/js",
done : function(errors, window) {
html : "http://127.0.0.1:64000/html",
scripts : "http://127.0.0.1:64000/js",
done : function(errors, window) {
server.close();
assertNull("error should not be null", errors);
assertNotNull("window should be valid", window.location);
Expand Down Expand Up @@ -171,13 +171,15 @@ exports.tests = {

env_processArguments_object_and_callback : function() {
var config = jsdom.env.processArguments([{
html : ""
html : "",
scripts : ['path/to/some.js', 'another/path/to.js']
},
function() {}
]);

assertNotNull("has done", config.done);
assertNotNull("has html", config.html);
assertEquals('has code', 2, config.scripts.length);
},

env_processArguments_all_args_no_config : function() {
Expand All @@ -189,7 +191,7 @@ exports.tests = {

assertNotNull("has done", config.done);
assertNotNull("has html", config.html);
assertEquals('script length should be 1', 1, config.code.length);
assertEquals('script length should be 1', 1, config.scripts.length);
},

env_processArguments_all_args_with_config : function() {
Expand All @@ -202,7 +204,7 @@ exports.tests = {

assertNotNull("has done", config.done);
assertNotNull("has html", config.html);
assertEquals('script length should be 1', 1, config.code.length);
assertEquals('script length should be 1', 1, config.scripts.length);
assertNotNull("has config.features", config.config.features);
},

Expand Down

0 comments on commit 197624f

Please sign in to comment.