Skip to content

Commit 91a6d27

Browse files
committed
Needs Peer Review: Setup Image to work with JS and kick off a request per issue #189
1 parent e724406 commit 91a6d27

File tree

5 files changed

+204
-13
lines changed

5 files changed

+204
-13
lines changed

lib/jsdom/browser/index.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ exports.createWindow = function(dom, options) {
124124
this.clearInterval = stopTimer;
125125
this.clearTimeout = stopTimer;
126126
this.__stopAllTimers = stopAllTimers;
127+
this.Image = function Image() {
128+
return dom.Document.prototype.createElement.call(window.document, "IMG" );
129+
};
130+
127131
}
128132

129133
DOMWindow.prototype = {
@@ -233,12 +237,10 @@ exports.createWindow = function(dom, options) {
233237
screen : {
234238
width : 0,
235239
height : 0
236-
},
237-
Image : NOT_IMPLEMENTED()
240+
}
238241
};
239-
240242
var window = new DOMWindow(options);
241-
243+
242244
Contextify(window);
243245

244246
// We need to set up self references using Contextify's getGlobal() so that
@@ -546,6 +548,7 @@ var browserAugmentation = exports.browserAugmentation = function(dom, options) {
546548
return this.parentWindow;
547549
});
548550

551+
549552
dom._augmented = true;
550553
return dom;
551554
};

lib/jsdom/level2/html.js

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ core.languageProcessors = {
1515
core.resourceLoader = {
1616
load: function(element, href, callback) {
1717
var ownerImplementation = element._ownerDocument.implementation;
18-
18+
1919
if (ownerImplementation.hasFeature('FetchExternalResources', element.tagName.toLowerCase())) {
2020
var full = this.resolve(element._ownerDocument, href);
2121
url = URL.parse(full);
@@ -25,7 +25,7 @@ core.resourceLoader = {
2525
else {
2626
this.readFile(url.pathname, this.enqueue(element, callback, full));
2727
}
28-
}
28+
}
2929
},
3030
enqueue: function(element, callback, filename) {
3131
var loader = this,
@@ -36,7 +36,6 @@ core.resourceLoader = {
3636
if (!doc._queue) {
3737
return function() {};
3838
}
39-
4039
return doc._queue.push(function(err, data) {
4140
var ev = doc.createEvent('HTMLEvents');
4241

@@ -1146,6 +1145,34 @@ define('HTMLAnchorElement', {
11461145

11471146
define('HTMLImageElement', {
11481147
tagName: 'IMG',
1148+
init:function() {
1149+
this.addEventListener('DOMNodeInsertedIntoDocument', function() {
1150+
if(this.src && !this._loadedResource) {
1151+
// let core.resourceLoader.load check the state of
1152+
//FetchExternalResources
1153+
core.resourceLoader.load(this, this.src, this._eval);
1154+
}
1155+
1156+
}, false);
1157+
1158+
},
1159+
proto:{
1160+
_data:null,
1161+
_eval:function(data, filename) {
1162+
this.data=data;
1163+
this._loadedResource=true;
1164+
},
1165+
set data( _img_data ) {
1166+
this._data=new Buffer( _img_data );
1167+
},
1168+
get data() {
1169+
return this._data;
1170+
},
1171+
onload : function() {
1172+
},
1173+
onerror: function() {
1174+
}
1175+
},
11491176
attributes: [
11501177
'name',
11511178
'align',
@@ -1155,7 +1182,7 @@ define('HTMLImageElement', {
11551182
{prop: 'hspace', type: 'long'},
11561183
{prop: 'isMap', type: 'boolean'},
11571184
'longDesc',
1158-
'src',
1185+
{prop: 'src', attr: 'src', type:'string' },
11591186
'useMap',
11601187
{prop: 'vspace', type: 'long'},
11611188
{prop: 'width', type: 'long'}

test/level2/html.js

Lines changed: 135 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
var fs = require('fs');
2+
var request=require('request');
23
var jsdom = require("../../lib/jsdom");
34
var fileCache = {};
4-
var load = function(name) {
5-
var file = __dirname + "/html/files/" + name + ".html",
6-
contents = fileCache[file] || fs.readFileSync(file, 'utf8'),
7-
doc = jsdom.jsdom(null, null, {url: "file://" + file }),
8-
window = doc.createWindow();
95

6+
var load = function(name, opts) {
7+
var opts = opts || {},
8+
file = __dirname + "/html/files/" + name + ".html",
9+
contents = fileCache[file] || fs.readFileSync(file, 'utf8'),
10+
window, doc;
11+
12+
if(!opts.url) { opts.url="file://" + file; }
13+
doc = jsdom.jsdom(null, null, opts),
14+
window=doc.createWindow();
1015
doc.parent = window;
1116
window.loadComplete = function() {};
1217

@@ -19648,5 +19653,130 @@ exports.tests = {
1964819653
test.equal(preventDefault, false, 'preventDefault should be *false*');
1964919654
test.ok(performedDefault, 'performedDefault');
1965019655
test.done();
19656+
},
19657+
19658+
HTMLImageEl01:function(test) {
19659+
test.expect(0);
19660+
var doc=load("img");
19661+
// just a stub test, shouldn't throw any error
19662+
var imgs = doc.getElementsByTagName("img");
19663+
imgs[0].onload=function(e) {
19664+
test.equal(false, true, "Shouldnt fire");
19665+
}
19666+
test.done();
19667+
},
19668+
19669+
HTMLImageEl02:function(test) {
19670+
test.expect(4);
19671+
/*
19672+
*
19673+
* currently no convenience method for getting remote source
19674+
* and allowing its images to load (makes sense)
19675+
* for testing, we want to allow images
19676+
*
19677+
* Setup a raw request, parse the response into a window
19678+
*
19679+
* */
19680+
19681+
var img_enabled={
19682+
url:"http://nodejs.org",
19683+
features:{
19684+
FetchExternalResources:['img']
19685+
}
19686+
};
19687+
19688+
request({
19689+
uri:"http://nodejs.org"
19690+
}, function(err, response, body) {
19691+
var window = jsdom.html( body, null, img_enabled ).createWindow();
19692+
var has_image_feature = window.document.implementation.hasFeature('FetchExternalResources', 'img');
19693+
test.equal(has_image_feature, true, "window mutated to read images");
19694+
var imgs = window.document.getElementsByTagName("img");
19695+
imgs[0].onload=function(e) {
19696+
// hrm, 'this here is the process scope'
19697+
test.equal("logo.png", e.target.src, "totally useless test");
19698+
test.equal(Buffer.isBuffer(e.target.data), true, "Loaded image data");
19699+
test.done();
19700+
19701+
}
19702+
test.equal(imgs.length>0, true, "document has images");
19703+
19704+
});
19705+
},
19706+
19707+
HTMLImageEl03:function(test) {
19708+
test.expect(6);
19709+
var img_enabled={
19710+
features:{
19711+
FetchExternalResources:['img']
19712+
}
19713+
};
19714+
var doc=load("img", img_enabled);
19715+
var images=doc.getElementsByTagName("img");
19716+
var img = images[0];
19717+
test.equal(images.length>0, true, "Found images");
19718+
test.notEqual(img.getAttribute("src"), undefined, "src is defined");
19719+
test.equal(img.getAttribute("src"), img.src, "getAttribute value matches .src value");
19720+
test.equal(img.src, "./pix/dts.gif", "doc img src set to original value from html");
19721+
var img2=doc.createElement("img");
19722+
//./pix/dts.gif
19723+
img2.src="favicon.ico";
19724+
test.equal(img2.src, "favicon.ico", "newly created img tag src set");
19725+
test.equal(img2.getAttribute("src"), img2.src, "getAttribute value matches .src value");
19726+
doc.documentElement.appendChild(img2);
19727+
test.done();
19728+
},
19729+
19730+
HTMLImageEl04:function(test) {
19731+
var img_enabled={
19732+
features:{
19733+
FetchExternalResources:['script', 'img']
19734+
}
19735+
};
19736+
test.expect(4);
19737+
/* JS new Image() call */
19738+
var doc=load("img2", img_enabled);
19739+
var imgs = doc.getElementsByTagName("img");
19740+
test.equal(typeof imgs, "object", "response from getElementsByTagName for new Image is an object");
19741+
test.equal(typeof imgs.length, "number", "length property is a number");
19742+
test.equal(imgs.length>0, true, "doc has a standard image tag");
19743+
// this test calls http://localhost:8080/favicon.ico
19744+
//var images = doc.getElementsByTagName("img");
19745+
imgs[0].onload=function() {
19746+
//console.log(this);
19747+
test.equal(Buffer.isBuffer( imgs[0].data ), true, ".data is a Buffer" );
19748+
test.done();
19749+
}
19750+
},
19751+
19752+
HTMLImageEl05:function(test) {
19753+
var img_enabled={
19754+
features:{
19755+
FetchExternalResources:['img']
19756+
}
19757+
};
19758+
var doc=load("img3", img_enabled);
19759+
// this test calls http://localhost:8080/favicon.ico
19760+
var images = doc.getElementsByTagName("img");
19761+
test.equal(images.length>0, true, "document has appended images");
19762+
test.done();
19763+
},
19764+
HTMLImageEl06:function(test) {
19765+
var img_enabled={
19766+
features:{
19767+
FetchExternalResources:['script', 'img']
19768+
}
19769+
};
19770+
var window=jsdom.jsdom(null, null, img_enabled).createWindow();
19771+
var img = new window.Image();
19772+
test.equal(typeof img.onload, "function", "the created image object has an onload method");
19773+
img.onload=function() {
19774+
test.equal(Buffer.isBuffer( img.data ), true, ".data is a Buffer" );
19775+
test.done();
19776+
}
19777+
19778+
img.src="http://localhost/favicon.ico";
19779+
test.equal(img.src.length>0, true, "src property has a length");
19780+
window.document.body.appendChild(img);
1965119781
}
1965219782
}

test/level2/html/files/img2.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2+
<html>
3+
<head>
4+
</head>
5+
<body>
6+
<div id="name">
7+
8+
</div>
9+
<script language="javascript">
10+
var i = new Image();
11+
i.src = 'http://localhost/favicon.ico';
12+
//console.log(i.nodeName);
13+
document.getElementById("name").appendChild(i);
14+
var imgs = document.getElementsByTagName("img");
15+
</script>
16+
</body>
17+
</html>
18+

test/level2/html/files/img3.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2+
<HTML>
3+
<HEAD>
4+
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=utf-8">
5+
<TITLE>NIST DOM HTML Test - IMG3</TITLE>
6+
</HEAD>
7+
<BODY onload="parent.loadComplete()">
8+
<P>
9+
<IMG SRC="http://localhost/favicon.ico" />
10+
</P>
11+
</BODY>
12+
</HTML>
13+

0 commit comments

Comments
 (0)