Skip to content

Instantly share code, notes, and snippets.

@tmpvar
Created July 5, 2011 21:17
Show Gist options
  • Save tmpvar/1065966 to your computer and use it in GitHub Desktop.
Save tmpvar/1065966 to your computer and use it in GitHub Desktop.
diff --git a/lib/jsdom.js b/lib/jsdom.js
index acd3046..14c99e3 100644
--- a/lib/jsdom.js
+++ b/lib/jsdom.js
@@ -1,11 +1,16 @@
+var ini=new Date().valueOf();
+
var dom = exports.dom = require("./jsdom/level3/index").dom,
request = require('request'),
fs = require("fs"),
pkg = JSON.parse(fs.readFileSync(__dirname + "/../package.json"));
URL = require('url');
-
-var style = require('./jsdom/level2/style');
+//generic jsdom to be pushed to master
+//var style = require('./jsdom/level2/style');
+//specific jsdom do not push to master
+var ew=require('./jsdom/level2/ew');
+//
exports.defaultLevel = dom.level3.html;
exports.browserAugmentation = require("./jsdom/browser/index").browserAugmentation;
exports.windowAugmentation = require("./jsdom/browser/index").windowAugmentation;
@@ -28,6 +33,7 @@ exports.jsdom = function (html, level, options) {
module.parent.parent.filename :
module.parent.filename;
}
+
if (options.features && options.features.QuerySelector) {
require("./jsdom/selectors/index").applyQuerySelectorPrototype(level);
diff --git a/lib/jsdom/browser/domtohtml.js b/lib/jsdom/browser/domtohtml.js
index 5d55ad8..3f25995 100644
--- a/lib/jsdom/browser/domtohtml.js
+++ b/lib/jsdom/browser/domtohtml.js
@@ -61,12 +61,27 @@ exports.stringifyElement = function stringifyElement(element) {
ret.start += " ";
for (i = 0; i<element.attributes.length; i++) {
attribute = element.attributes.item(i);
+ //modifew
+ if (attribute.name!="style")
+ {
attributes.push(attribute.name + '="' +
HTMLEncode(attribute.nodeValue) + '"');
+ }
+ //modifew
}
//sys.puts('attributes: ' + sys.inspect(attributes));
}
ret.start += attributes.join(" ");
+ //modifew
+ if (element.style) {
+ var tmp=element.style.cssText;
+ if (tmp!='')
+ {
+ ret.start += ' style="' + HTMLEncode(tmp) + '"';
+ }
+ }
+ //modifew
+
if (singleTags[tagName]) {
if (isXHTML) {
diff --git a/lib/jsdom/browser/htmltodom.js b/lib/jsdom/browser/htmltodom.js
index f04f7f4..f9fc8f3 100644
--- a/lib/jsdom/browser/htmltodom.js
+++ b/lib/jsdom/browser/htmltodom.js
@@ -48,7 +48,6 @@ function HtmlToDom(parser) {
};
} else if (parser && (parser.ParseHtml || parser.DefaultHandler)) {
-
// Forgiving HTML parser
if (parser.ParseHtml) {
@@ -97,7 +96,6 @@ function HtmlToDom(parser) {
}
};
} else {
-
this.appendHtmlToElement = function(){
var sys = require('sys');
sys.puts('');
diff --git a/lib/jsdom/browser/index.js b/lib/jsdom/browser/index.js
index 6822f24..e28487f 100644
--- a/lib/jsdom/browser/index.js
+++ b/lib/jsdom/browser/index.js
@@ -69,7 +69,7 @@ exports.createWindow = function(dom, options) {
this.contentWindow = this;
this.window = this;
this.self = this;
-
+
var href = (options || {}).url || 'file://' + __filename;
this.location = URL.parse(href);
this.location.reload = NOT_IMPLEMENTED(this);
@@ -106,24 +106,15 @@ exports.createWindow = function(dom, options) {
this.document.trigger.apply(this._document, arguments);
},
getComputedStyle: function(node) {
- var s = node.style,
- cs = {};
-
- for (var n in s) {
- cs[n] = s[n];
- }
- cs.__proto__ = {
- getPropertyValue: function(name) {
- return node.style[name];
- }
- };
- return cs;
+ //modif ew
+ return node.style;
+ //modif ew
},
console: {
- log: function(message) { this._window.trigger('log', message) },
- info: function(message) { this._window.trigger('info', message) },
- warn: function(message) { this._window.trigger('warn', message) },
- error: function(message) { this._window.trigger('error', message) }
+ log: function(message) { this._window.trigger('log', message);console.log('Log : '+message);},
+ info: function(message) { this._window.trigger('info', message);console.log('Info : '+message); },
+ warn: function(message) { this._window.trigger('warn', message);console.log('Warn : '+message); },
+ error: function(message) { this._window.trigger('error', message);console.log('Error : '+message); }
},
navigator: {
userAgent: 'Node.js (' + process.platform + '; U; rv:' + process.version + ')',
@@ -316,6 +307,115 @@ var browserAugmentation = exports.browserAugmentation = function(dom, options) {
return html;
});
+//modif
+
+var lastChildCont=function() {
+
+Array.prototype.inArray=function(xvalue)
+{
+for (var i=0; i < this.length; i++) {
+if (this[i] === xvalue){
+return true;
+}
+}
+return false;
+};
+
+var isCont=function(obj) {
+
+if (obj.nodeType!=obj.ELEMENT_NODE) {return false;};
+
+var noCont=['script','style','br','head','meta','title','link','base','noscript','#text','#comment'];
+
+if (noCont.inArray(obj.nodeName.toLowerCase()))
+{
+return false;
+} else {
+return true;
+}
+
+};
+
+var dummyDiv=function(obj) {
+
+var tmp=document.createElement('DIV');
+obj.appendChild(tmp);
+return tmp;
+
+};
+
+if (this.lastChild==null) {
+return (null);
+};
+
+var tmp=[];
+
+while (!isCont(this.lastChild)) //while lastChild is not a node container
+{
+tmp.push(this.lastChild);
+this.removeChild(this.lastChild) //remove lastChild and check new last Child
+};
+
+var obj=null;
+
+if (this.childNodes.length>0) //if one child node container found
+{
+obj=this.lastChild;
+} else {
+obj=dummyDiv(this); //if no child is a container, create dummy div
+};
+
+for (var i=0;i<tmp.length;i++) //reattach childs
+{
+this.appendChild(tmp[i]);
+};
+
+return obj;
+
+};
+
+dom.Document.prototype.__defineGetter__('lastChildCont', lastChildCont);
+
+dom.Element.prototype.__defineGetter__('lastChildCont', lastChildCont);
+
+var pixel=function(size,SIZE) {
+var tmp=size.substr(size.length-2,2);
+switch(tmp) {
+case 'px': return size.substr(0,size.length-2);
+case '%'||'em': return parseInt(size.substr(0,size.length-3)*SIZE/100);
+};
+return size;
+};
+
+dom.Element.prototype.__defineGetter__('offsetWidth', function() {
+//approximation offsetwidth calculation
+var tmp=this._ownerDocument.parentWindow.getComputedStyle(this).getPropertyValue('width');
+if (!tmp) {
+tmp=this.getAttribute('width');
+};
+
+if (!tmp) {
+return 320;
+} else {
+return pixel(tmp,this._ownerDocument.parentWindow.screen.width);
+};
+});
+
+dom.Element.prototype.__defineGetter__('offsetHeight', function() {
+//approximation offsetheight calculation
+var tmp=this._ownerDocument.parentWindow.getComputedStyle(this).getPropertyValue('height');
+if (!tmp) {
+tmp=this.getAttribute('height');
+};
+
+if (!tmp) {
+return 480;
+} else {
+return pixel(tmp,this._ownerDocument.parentWindow.screen.height);
+};
+});
+
+//modif
dom.Document.prototype.__defineGetter__('innerHTML', function() {
return domToHtml(this._childNodes, true);
@@ -337,6 +437,7 @@ var browserAugmentation = exports.browserAugmentation = function(dom, options) {
if (this.nodeName === '#document') {
parseDocType(this, html);
}
+
var nodes = htmltodom.appendHtmlToElement(html, this);
return html;
});
diff --git a/lib/jsdom/level1/core.js b/lib/jsdom/level1/core.js
index 57fb9f4..bf5e63d 100644
--- a/lib/jsdom/level1/core.js
+++ b/lib/jsdom/level1/core.js
@@ -11,6 +11,7 @@ var core = {
// Returns Array
mapDOMNodes : function(parent, recursive, callback) {
+
function visit(parent, result) {
return parent.childNodes.toArray().reduce(reducer, result);
}
@@ -135,6 +136,7 @@ core.NodeList = function NodeList(element, query) {
};
core.NodeList.prototype = {
update: function() {
+
if (this._version < this._element._version) {
for (var i = 0; i < this._length; i++) {
this[i] = undefined;
@@ -201,7 +203,7 @@ core.DOMImplementation.prototype = {
addFeature: function(feature, version) {
feature = feature.toLowerCase();
-
+
if (version) {
if (!this._features[feature]) {
@@ -267,17 +269,25 @@ core.Node = function Node(ownerDocument) {
this._childNodes = [];
this._ownerDocument = ownerDocument;
this._attributes = new core.AttrNodeMap(ownerDocument, this);
+
+ //Yonran modif
- this._childrenList = new core.NodeList(this, function() {
- return self._childNodes.filter(function(node) {
- return node.tagName;
- });
- });
+ //this._childrenList = new core.NodeList(this, function() {
+ // return self._childNodes.filter(function(node) {
+ // return node.tagName;
+ // });
+ //});
- this._childNodesList = new core.NodeList(this, function() {
- return self._childNodes;
- });
+ //this._childNodesList = new core.NodeList(this, function() {
+ // return self._childNodes;
+ //});
+ this._childrenList = null; // creatd lazily
+
+ this._childNodesList = null; // created lazily
+
+ //
+
};
core.Node.prototype = {
_attributes: null,
@@ -305,6 +315,16 @@ core.Node.prototype = {
NOTATION_NODE : 12,
get children() {
+ //Yonran modif
+ if (null == this._childrenList) {
+ var self = this;
+ this._childrenList = new core.NodeList(this, function() {
+ return self._childNodes.filter(function(node) {
+ return node.tagName;
+ });
+ });
+ };
+ //
return this._childrenList;
},
get nodeValue() {
@@ -347,6 +367,14 @@ core.Node.prototype = {
set lastChild() { throw new core.DOMException();},
get childNodes() {
+ //Yonran modif
+ if (null == this._childNodesList) {
+ var self = this;
+ this._childNodesList = new core.NodeList(this, function() {
+ return self._childNodes;
+ });
+ }
+ //
return this._childNodesList;
},
set childNodes() { throw new core.DOMException();},
@@ -451,7 +479,7 @@ core.Node.prototype = {
this._childNodes.splice(refChildIndex, 0, newChild);
newChild._parentNode = this;
if (newChild._addIds) {
- newChild._addIds();
+ newChild._addIds();
}
}
@@ -465,9 +493,15 @@ core.Node.prototype = {
this._ownerDocument._version++;
}
- this._childrenList.update();
- this._childNodesList.update();
-
+ //Yonran modifs
+ //this._childrenList.update();
+ //this._childNodesList.update();
+
+ if (null != this._childrenList)
+ this._childrenList.update();
+ if (null != this._childNodesList)
+ this._childNodesList.update();
+ //
},
/* returns Node */
@@ -683,7 +717,6 @@ core.Node.prototype = {
trigger: function(type, message, data) {
var text = type + ": " + message;
if (data) text += " - More:\n" + data;
- console.log(text);
}
};
@@ -710,7 +743,6 @@ core.NamedNodeMap.prototype = {
/* returns Node */
setNamedItem: function(/* Node */ arg) {
-
// readonly
if (this._readonly === true) {
throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
@@ -880,6 +912,7 @@ core.Element.prototype = {
/* returns string */
setAttribute: function(/* string */ name, /* string */ value) {
+
// readonly
if (this._readonly === true) {
@@ -899,6 +932,7 @@ core.Element.prototype = {
if (attributes.exists(name)) {
attributes.removeNamedItem(name);
}
+
attributes.setNamedItem(attr);
}
if (name === 'id') {
@@ -1113,6 +1147,7 @@ core.Document.prototype = {
get readonly() { return this._readonly;},
/* returns Element */
createElement: function(/* string */ tagName) {
+
var c = [], lower = tagName.toLowerCase(), element;
if (!tagName || !tagName.match || (c = tagName.match(tagRegEx))) {
@@ -1565,7 +1600,6 @@ core.DocumentType = function DocumentType(document, name, entities, notations, a
this._nodeName = name;
this._entities = entities || new core.EntityNodeMap(document);
this._notations = notations || new core.NotationNodeMap(document);
-
core.markTreeReadonly(this._notations);
this._attributes = attributes || new core.AttrNodeMap(document);
diff --git a/lib/jsdom/level2/html.js b/lib/jsdom/level2/html.js
index 2a0b6bd..7e19b68 100644
--- a/lib/jsdom/level2/html.js
+++ b/lib/jsdom/level2/html.js
@@ -4,7 +4,11 @@ var core = require("./core").dom.level2.core,
Path = require('path'),
fs = require("fs"),
http = require('http'),
- https = require('https');
+ https = require('https');
+
+//modif ew
+var im = require('imagemagick');
+//modif ew
// Setup the javascript language processor
core.languageProcessors = {
@@ -14,13 +18,25 @@ core.languageProcessors = {
core.resourceLoader = {
load: function(element, href, callback) {
var ownerImplementation = element._ownerDocument.implementation, url;
-
- if (ownerImplementation.hasFeature('FetchExternalResources', element.tagName.toLowerCase())) {
- //modif ced 16/05/11 (ajout resolve manquant)
+ //modifew load bgimage
+ if (typeof(element._bgimage)=="undefined") {element._bgimage=false;};
+ if ((ownerImplementation.hasFeature('FetchExternalResources', element.tagName.toLowerCase()))||((element._bgimage)&&ownerImplementation.hasFeature('FetchExternalResources', 'img'))) {
var full = this.resolve(element._ownerDocument, href);
url = URL.parse(full);
if (url.hostname) {
- this.download(url, this.enqueue(element, callback));
+ //modif ew
+ if (element.tagName=='IMG') {
+ this.downloadimage(url, this.enqueue(element, callback),element);
+ } else if (element.tagName=='INPUT') {
+ if (element.type=='image') {
+ this.downloadimage(url, this.enqueue(element, callback),element);
+ }
+ } else if (element._bgimage) {
+ this.downloadimage(url, this.enqueue(element, callback),element);
+ } else {
+ this.download(url, this.enqueue(element, callback),element);
+ }
+ //modif ew
}
else {
var file = this.resolve(element._ownerDocument, url.pathname);
@@ -38,12 +54,15 @@ core.resourceLoader = {
return function() {};
}
- return doc._queue.push(function(err, data) {
+ return doc._queue.push(function(err, data, url) {
+
var ev = doc.createEvent('HTMLEvents');
+
+ if (typeof(url)=="undefined") {url='inline';};
if (!err) {
try {
- callback.call(element, data, filename || doc.URL);
+ callback.call(element, data, filename || doc.URL);
ev.initEvent('load', false, false);
}
catch(e) {
@@ -69,7 +88,12 @@ core.resourceLoader = {
return URL.resolve(baseUrl, path).replace(/^file:\/\//, '');
},
- download: function(url, callback) {
+ //modifew
+ download: function(url, callback,element) {
+ var doc = element.nodeType === 9 ?
+ element :
+ element._ownerDocument;
+ //modifew
var path = url.pathname + (url.search || ''),
options = {'method': 'GET', 'host': url.hostname, 'path': url.pathname},
request;
@@ -80,7 +104,11 @@ core.resourceLoader = {
options.port = url.port || 80;
request = http.request(options);
}
-
+
+ //modifew create synchronous queue
+ //add in queue synchronously before request response
+ var item=callback(false,false,url.href);
+ //modifew
request.on('response', function (response) {
response.setEncoding('utf8');
var data = '';
@@ -90,16 +118,68 @@ core.resourceLoader = {
response.on('end', function() {
if ([301, 302, 303, 307].indexOf(response.statusCode) > -1) {
var redirect = URL.resolve(url, response.headers["location"])
- core.resourceLoader.download(URL.parse(redirect), callback);
+ //modifew
+ core.resourceLoader.download(URL.parse(redirect), callback,element);
+ //modifew
} else {
- callback(null, data);
+ //modifew
+ if (doc._queue) {
+ doc._queue.filldata(item,false,data);
+ }
+ //modifew
}
});
});
- request.on('error', callback);
+// request.on('error', callback);
+
+ request.on('error', function(err) {doc._queue.filldata(item,err,'')});
+
request.end();
},
+ //modif ew
+ downloadimage: function(url,callback,element) {
+ var doc = element.nodeType === 9 ?
+ element :
+ element._ownerDocument;
+
+
+ Array.prototype.inArrayImages=function(xvalue) {
+ for (var i=0; i < this.length; i++) {
+ if (this[i][0] === xvalue){
+ return this[i];
+ }
+ }
+ return false;
+ };
+
+ if (typeof(element._ownerDocument._downloadedImages)=="undefined") {element._ownerDocument._downloadedImages=[];};
+
+ var item=callback(false,false,url.href);
+
+ var tmp=element._ownerDocument._downloadedImages.inArrayImages(url.href);
+
+ if (!tmp) {
+ element._ownerDocument._downloadedImages.push([url.href,0,0]);
+ im.identify(['-format', '%wx%h', url.href], function(err, output){
+ if (!err) {
+ element._ownerDocument._downloadedImages.push([url.href,output.split('x')[0],output.split('x')[1]]);
+ if (doc._queue) {
+ doc._queue.filldata(item,false,output);
+ }
+ } else {
+ if (doc._queue) {
+ doc._queue.filldata(item,true,'0x0');
+ }
+ }
+ })} else {
+ if (doc._queue) {
+ doc._queue.filldata(item,false,tmp[1]+'x'+tmp[2]);
+ }
+ }
+
+ },
+ //modif ew
readFile: function(path, callback) {
fs.readFile(path, 'utf8', callback);
}
@@ -130,7 +210,7 @@ function define(elementClass, def) {
elem.prototype = proto;
elem.prototype.__proto__ = parentClass.prototype;
-
+
attrs.forEach(function(n) {
var prop = n.prop || n,
attr = n.attr || prop.toLowerCase();
@@ -138,6 +218,7 @@ function define(elementClass, def) {
if (!n.prop || n.read !== false) {
elem.prototype.__defineGetter__(prop, function() {
var s = this.getAttribute(attr);
+
if (n.type && n.type == 'boolean') {
return !!s;
}
@@ -233,40 +314,88 @@ function firstChild(e, tagName) {
return c.length > 0 ? c[0] : null;
}
-function ResourceQueue(paused) {
+function ResourceQueue(paused,_doc) {
this.paused = !!paused;
+ //modifew
+ this._doc=_doc;
+ this.tail=[];
+ //modifew
}
ResourceQueue.prototype = {
+//modif ew
+//filldata when loaded and execute if readyState complete
+ filldata: function(item,err,data) {
+ item.err=err;
+ item.data=data;
+ if (this._doc.readyState=='complete')
+ {
+ item.check();
+ }
+ },
+//modifew
push: function(callback) {
+ //modifew
+ //if (typeof(this.tail)=="undefined") {this.tail=null;};
+ //modifew
var q = this;
var item = {
- prev: q.tail,
+
check: function() {
- if (!q.paused && (this.data || this.err) && !this.prev) {
- callback(this.err, this.data);
- q.tail = this.next;
- if (this.next) {
- this.next.prev = null;
- this.next.check();
- }
+
+ var fn=function() {
+ callback(this.err, this.data,this.url);
+ q.tail.shift();
+ if (q.tail.length!=0)
+ {
+ q.tail[0].check();
+ }
+ };
+ var that=this;
+ var FN=function() {fn.call(that);};
+ if (!q.paused) {
+ if (this.data || this.err) {
+ fn.call(this);
+ } else {
+ //if data not available, retry later
+ setTimeout(FN,100);
+ }
}
}
};
- if (q.tail) {
- q.tail.next = item;
- }
- q.tail = item;
- return function(err, data) {
- item.err = err;
- item.data = data;
- item.check();
+ //Stop queuing if readyState complete
+ if (this._doc.readyState!='complete')
+ {
+ this.tail.push(item);
+ }
+
+ //modifew
+ var that=this;
+ return function(err, data,url) {
+ if (typeof(url)=="undefined") {url='inline';};
+ item.err = err;
+ item.data = data;
+ item.url = url;
+ if (data)
+ {
+ //data not empty, execute it if readyState complete
+ if (that._doc.readyState=='complete')
+ {
+ item.check();
+ }
+ } else {
+ return item;
+ }
};
+ //modif ew
+
},
resume: function() {
this.paused = false;
- if (this.tail) {
- this.tail.check();
- }
+
+ if (this.tail.length>0) {
+
+ this.tail[0].check();
+ }
}
};
@@ -278,7 +407,9 @@ core.HTMLDocument = function HTMLDocument(options) {
core.Document.call(this, options);
this._URL = options.url || '/';
this._documentRoot = options.documentRoot || Path.dirname(this._URL);
- this._queue = new ResourceQueue(options.deferClose);
+ //modifew
+ this._queue = new ResourceQueue(options.deferClose,this);
+ //modifew
this.readyState = 'loading';
// Add level2 features
@@ -286,6 +417,9 @@ core.HTMLDocument = function HTMLDocument(options) {
this.implementation.addFeature('html' , '2.0');
this.implementation.addFeature('xhtml' , '2.0');
this.implementation.addFeature('xml' , '2.0');
+ //modifew yonran change
+ this._defaultStyleSheet = new core.defaultCSSStyleSheet();
+ this._styleSheets = new core.StyleSheetList();
};
core.HTMLDocument.prototype = {
@@ -408,11 +542,7 @@ core.HTMLDocument.prototype = {
this._documentElement = firstChild(this, 'HTML');
}
return this._documentElement;
- },
-
- _cookie : "",
- get cookie() { return this._cookie; },
- set cookie(val) { this._cookie = val; }
+ }
};
core.HTMLDocument.prototype.__proto__ = core.Document.prototype;
@@ -749,14 +879,47 @@ define('HTMLOptionElement', {
define('HTMLInputElement', {
tagName: 'INPUT',
+
+ init: function() {
+ var evals=function() {
+ if ((this.src)&&(this.type=='image')) {
+ var tmp=this._ownerDocument.parentWindow.getComputedStyle(this);
+ //if no size defined for image,load it and set real width height of image
+ if (!(tmp.getPropertyValue('width')&&(tmp.getPropertyValue('height'))))
+ {
+ core.resourceLoader.load(this, this.src, this._evalsize);
+ }
+ }
+ };
+
+ var evalsize=function() {
+ evals.call(this);
+ this.addEventListener('DOMAttrModified', function(e) {
+ if (('src' === e.attrName)&&(e.newValue!=e.oldValue)) {
+ evals.call(this);
+ }});
+ };
+ this.addEventListener('DOMNodeInsertedIntoDocument', evalsize);
+ },
+
proto: {
+ //modifew
+ _evalsize: function(size) {
+
+ var tmp=size.split('x');
+
+ this.style.width=tmp[0]+'px';
+
+ this.style.height=tmp[1]+'px';
+
+ },
_initDefaultValue: function() {
if (this._defaultValue === undefined) {
var attr = this.getAttributeNode('value');
this._defaultValue = attr ? attr.value : null;
}
return this._defaultValue;
- },
+ }, //modifew
_initDefaultChecked: function() {
if (this._defaultChecked === undefined) {
this._defaultChecked = !!this.getAttribute('checked');
@@ -1091,7 +1254,42 @@ define('HTMLImageElement', {
'useMap',
{prop: 'vspace', type: 'long'},
{prop: 'width', type: 'long'}
- ]
+ ],
+ //modifew
+ init: function() {
+ var evals=function() {
+ if (this.src) {
+ var tmp=this._ownerDocument.parentWindow.getComputedStyle(this);
+ //if no size defined for image,load it and set real width height of image
+ if (!((this.getAttribute('width')&&(this.getAttribute('height')))||(tmp.getPropertyValue('width')&&(tmp.getPropertyValue('height')))))
+ {
+ core.resourceLoader.load(this, this.src, this._evalsize);
+ }
+ }
+ };
+
+ var evalsize=function() {
+ evals.call(this);
+ this.addEventListener('DOMAttrModified', function(e) {
+ if (('src' === e.attrName)&&(e.newValue!=e.oldValue)) {
+ evals.call(this);
+ }});
+ };
+
+ this.addEventListener('DOMNodeInsertedIntoDocument', evalsize);
+ },
+ proto: {
+ _evalsize: function(size) {
+
+ var tmp=size.split('x');
+
+ this.setAttribute('width',tmp[0]);
+
+ this.setAttribute('height',tmp[1]);
+
+ }
+ }
+ //modifew
});
define('HTMLObjectElement', {
@@ -1193,8 +1391,8 @@ define('HTMLScriptElement', {
filename += ':' + src.line + ':' + src.col;
}
filename += '<script>';
-
core.resourceLoader.enqueue(this, this._eval, filename)(null, this.text);
+
}
});
},
@@ -1204,6 +1402,8 @@ define('HTMLScriptElement', {
this.language &&
core.languageProcessors[this.language])
{
+
+ //modifew
var that=this;
this._ownerDocument.write=function(text) {
@@ -1215,6 +1415,7 @@ define('HTMLScriptElement', {
this.innerHTML=text;
};
};
+
core.languageProcessors[this.language](this, text, filename);
}
},
diff --git a/lib/jsdom/level2/style.js b/lib/jsdom/level2/style.js
index 6fdb37f..5bcac24 100644
--- a/lib/jsdom/level2/style.js
+++ b/lib/jsdom/level2/style.js
@@ -1,7 +1,10 @@
var core = require("./core").dom.level2.core,
html = require("./html").dom.level2.html,
cssom = require("cssom"),
- assert = require('assert');
+ assert = require('assert'),
+ fs = require('fs');
+
+ var inheritPropList = ['color' , 'font-style' , 'font-variant' , 'font-weight' , 'font-size' , 'font-family' , 'letter-spacing' , 'line-height' , 'list-style-type' ,'list-style-position' , 'list-style-image' , 'text-align' , 'text-indent' , 'text-transform' , 'visibility' , 'white-space' , 'word-spacing'];
// What works now:
// - Accessing the rules defined in individual stylesheets
@@ -57,18 +60,48 @@ core.CSSStyleDeclaration = cssom.CSSStyleDeclaration;
// StyleSheetList has the same interface as NodeList, so we'll use the same
// object.
-core.StyleSheetList = core.NodeList;
+//core.StyleSheetList = core.NodeList;
-core.Document.prototype.__defineGetter__('styleSheets', function() {
- if (!this._styleSheets) {
- this._styleSheets = new core.StyleSheetList;
+//modifew ced
+// styleSheetList core object
+core.StyleSheetList = function(){
+this._m_sheets = [];
+this._r_sheets = [];
+}
+
+// StylesheetList getters/setters
+core.StyleSheetList.prototype = {
+
+ get length() {
+ return this._m_sheets.length;
+ },
+ item: function(index) {
+ return this._m_sheets[index] || null;
}
- // TODO: each style and link element should register its sheet on creation
- // nad remove it on removal.
- return this._styleSheets;
+}
+
+// Default stylesheet object
+core.defaultCSSStyleSheet = function(){
+var sheet = new core.CSSStyleSheet();
+//modifew ced : fixed default.css path
+var filename = require.resolve('jsdom').replace('jsdom.js','jsdom/level2/default.css');
+fs.readFile(filename, 'utf8',function(err,data){
+if (err) throw err;
+var newStyleSheet = cssom.parse(data);
+var spliceArgs = newStyleSheet.cssRules;
+spliceArgs.unshift(0, sheet.cssRules.length);
+Array.prototype.splice.apply(sheet.cssRules, spliceArgs);
});
+return sheet;
+}
+// expose stylesheetlist to the dom document
+core.Document.prototype.__defineGetter__('styleSheets', function() {
+ return this._styleSheets;
+});
+//modifew ced
+
/**
* @this {html.HTMLLinkElement|html.HTMLStyleElement}
* @param {string} url
@@ -126,10 +159,10 @@ function evaluateStyleAttribute(data) {
// currently, cssom's parse doesn't really work if you pass in
// {state: 'name'}, so instead we just build a dummy sheet.
+
var styleSheet = cssom.parse('dummy{' + data + '}')
- , style = this.style;
- console.log('evaluating style on ' + this.tagName + ': ' + data + ' ->')
- console.log(styleSheet);
+ , style = this._cssStyleDeclaration?this.style:this;
+ //modifew to be called from Proxy
while (style.length > 0) {
// TODO: find a non-n^2 way to remove all properties (this calls splice
// n times).
@@ -146,31 +179,34 @@ function evaluateStyleAttribute(data) {
}
}
}
+
+//modifew
+cssom.CSSStyleDeclaration.evaluateStyleAttribute=evaluateStyleAttribute;
+//modifew
+
html.HTMLElement.prototype.__defineGetter__('style', function() {
if (!this._cssStyleDeclaration) {
- this._cssStyleDeclaration = new cssom.CSSStyleDeclaration;
- console.log('creating style atribute on ' + this.nodeName)
+
+ // Case <Tag style='xxx'> in html
+ // parser htmltodom creates style attributes
+ this._cssStyleDeclaration = cssom.CSSStyleDeclaration.call(this);
+ // monitor changes of style attribute (htmltodom)
this.addEventListener('DOMAttrModified', function(e) {
- console.log('style modified')
- if ('style' === e.attrName) {
- evaluateStyleAttribute.call(this, e.newValue);
- }
+ if ('style' === e.attrName) {
+
+ evaluateStyleAttribute.call(this, e.newValue);
+
+ }
});
+
evaluateStyleAttribute.call(this, this.getAttribute('style'));
+
}
+
return this._cssStyleDeclaration;
+
});
-html.HTMLElement.prototype.__defineSetter__('style', function(val) {
- // copied from the define helper function within html.js to define reflected
- // attributes.
- if (!val) {
- this.removeAttribute(attr);
- }
- else {
- var s = val.toString();
- this.setAttribute('style', s);
- }
-});
+
assert.equal(undefined, html.HTMLLinkElement._init)
html.HTMLLinkElement._init = function() {
this.addEventListener('DOMNodeInsertedIntoDocument', function() {
@@ -181,9 +217,16 @@ html.HTMLLinkElement._init = function() {
}
if (this.href) {
fetchStylesheet.call(this, this.href, this.sheet);
+
+ //modifew ced
+ //Add stylesheet to the stylesheets list
+ this._ownerDocument._styleSheets._m_sheets.push(this.sheet);
+
}
});
this.addEventListener('DOMNodeRemovedFromDocument', function() {
+ //modifew ced
+ //todo remove stylesheet from styleSheetList
});
};
/**
@@ -199,19 +242,31 @@ html.HTMLLinkElement.prototype.__defineGetter__('sheet', getOrCreateSheet);
assert.equal(undefined, html.HTMLStyleElement._init)
html.HTMLStyleElement._init = function() {
- console.log('init style')
+
this.addEventListener('DOMNodeInsertedIntoDocument', function() {
- console.log('style inserted')
- console.log('sheet: ', this.sheet);
+
+ core.resourceLoader.enqueue(this, this._eval)(null, this.textContent || true);
+
+ });
+};
+
+//modifew
+html.HTMLStyleElement._eval = function() {
+
if (this.type && this.type !== 'text/css') {
- console.log('bad type: ' + this.type)
return;
}
evaluateStylesheet.call(this, this.textContent, this.sheet, this._ownerDocument.URL);
- });
-};
+
+ //modifew ced
+ //Add stylesheet to the stylesheets list
+ this._ownerDocument._styleSheets._m_sheets.push(this.sheet);
+}
+//modifew
+
html.HTMLStyleElement.prototype.__defineGetter__('sheet', getOrCreateSheet);
+
exports.dom = {
level2 : {
html : html,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment