fgnass / domino Goto Github PK
View Code? Open in Web Editor NEWServer-side DOM implementation based on Mozilla's dom.js
License: BSD 2-Clause "Simplified" License
Server-side DOM implementation based on Mozilla's dom.js
License: BSD 2-Clause "Simplified" License
I want to strip out unneeded DOM elements. One of the things I want to remove are for example span elements that have an inline style of "display:none". To my surprise the 'span[style*="display:none"]' selector does not work, see also the first code block. This behavior seems to be style attribute specific since if I have a slightly different DOM structure and look for a different attribute domino's querySelectorAll does find it (see second code block).
Block 1: Selecting based on attribute with a specific style value does not work:
it('style="display:none"', function() {
var doc = domino.createDocument('<html><body><span style="display:none">foo</span></body></html>');
var nodes = doc.querySelectorAll(
//'span[style]' // works
//'span[style="display:none"]' // does not work
'span[style*="display:none"]' // does not work
);
assert.equal(nodes.length, 1);
});
Block 2: All the options here using a different (e.g. foo) attribute work fine:
it('foo="display:none"', function() {
var doc = domino.createDocument('<html><body><span foo="display:none">foo</span></body></html>');
var nodes = doc.querySelectorAll(
//'span[foo="display:none"]' // does work
'span[foo*="display:none"]' // does work
);
assert.equal(nodes.length, 1);
});
I got the following error:
/path/to/node_modules/domino/lib/CSSStyleDeclaration.js:110
if (value.indexOf(";") !== -1) return;
^
TypeError: Object 0 has no method 'indexOf'
at Object.<anonymous> (/home/nevermind/experiment/crawler/node_modules/domino/lib/CSSStyleDeclaration.js:110:15)
at Object.<anonymous> (/home/nevermind/experiment/crawler/node_modules/domino/lib/CSSStyleDeclaration.js:260:12)
at eval at <anonymous> (/home/nevermind/experiment/crawler/jsdom.js:82:8)
at eval at <anonymous> (/home/nevermind/experiment/crawler/jsdom.js:82:8)
at Object.<anonymous> (eval at <anonymous> (/home/nevermind/experiment/crawler/jsdom.js:82:8))
at Object.<anonymous> (/home/nevermind/experiment/crawler/jsdom.js:82:3)
at IncomingMessage.<anonymous> (/home/nevermind/experiment/crawler/jsdom.js:39:15)
at IncomingMessage.emit (events.js:88:20)
at HTTPParser.onMessageComplete (http.js:137:23)
at Socket.ondata (http.js:1147:24)
And according to the source code, seems like when the value have been set which isn't a string object caused the error above.
setProperty: { value: function(property, value, priority) {
property = property.toLowerCase();
if (value === null || value === undefined) {
value = "";
}
Hello,
I am using Koa2 ctx.body = doc
which will fail with the error msg
TypeError: Converting circular structure to JSON
I used the example from your Readme:
var domino = require('domino');
var domimpl = domino.createDOMImplementation();
var doc = domimpl.createHTMLDocument();
Using a simple ctx.body="<html></html>"
works fine.
I am using node v7.7.3
and Koa2.
Is this behavior known - and is it possible to work around this using Koa2 ?
(of cause: maybe I am using your work in a wrong way - please give me a hint 😄 )
Anyways: Thanks for publishing/sharing your work!
The symptoms are the same as #79, but this is using 1.0.27. So theoretically that should be already fixed.
const domino = require('domino');
const document = domino.createDocument(`<body><a href="foo's">bar</a></body>`);
document.querySelectorAll("a[href=foo's]");
TypeError: combinators[op] is not a function
at compile (./node_modules/domino/lib/select.js:674:32)
at find (./node_modules/domino/lib/select.js:826:14)
at module.exports.exports (./node_modules/domino/lib/select.js:872:10)
at Object.create.querySelectorAll.value (./node_modules/domino/lib/Document.js:682:17)
at repl:1:5
at REPLServer.defaultEval (repl.js:262:27)
at bound (domain.js:287:14)
at REPLServer.runBound [as eval] (domain.js:300:12)
at REPLServer.<anonymous> (repl.js:431:12)
at emitOne (events.js:82:20)
If I double the single-quotes then I don't get this error but then it also doesn't find what I'm looking for.
npm list domino
...
└── [email protected]
Travis has noticed that the new 400k attribute test case is very slow (>10 min) on node 0.6. It runs fine on node 0.4, 0.7, 0.8, 0.9, 0.10, and 0.11, finishing all tests within 30 seconds.
The Document importNode method doesn't pass the deep parameter to the Node cloneNode method.
I have been read the source code, and noticed that the default url "about:blank" in Window seems cannot be changed by passing some argument or someway else to generate the proper location object.
Is that ever been considered as a future feature?
Now I'm manually load the ./lib/Location module to generate a new object to replace it.
Hi,
Is domino handles correctly solo tags ? In any case I tested, the next tag is parsed as a child of the solo tag. For example, an unit test:
exports.soloTag = function () {
var root1 = domino.createWindow('<?xml version="1.0" encoding="UTF-8"?><root><foo /><bar>42</bar></root>')
.document.documentElement.childNodes[1].firstChild;
var root2 = domino.createWindow('<?xml version="1.0" encoding="UTF-8"?><root><foo></foo><bar>42</bar></root>')
.document.documentElement.childNodes[1].firstChild;
root1.childNodes.length.should.equal(root2.childNodes.length);
};
In the first case, le childNodes
length is 1 because domino sets bar
as a child of foo
. In second case, the parsing is correct.
Thanks,
Vincent
When using getElementsByTagName() on an element with no children, the result contains matching siblings (and children of siblings).
Related to gh #31.
Hi, I'm trying to have a couple of test of domino, and when I use this module to parse a html which contains duplicated element id, domino try to warn me about that, then the following error occurred:
/path/to/node_modules/domino/lib/Document.js:521
warn('Duplicate element id ' + id)
^
ReferenceError: warn is not defined
at Object.addId (/home/nevermind/experiment/crawler/node_modules/domino/lib/Document.js:521:7)
at root (/home/nevermind/experiment/crawler/node_modules/domino/lib/Document.js:648:29)
at recursivelyRoot (/home/nevermind/experiment/crawler/node_modules/domino/lib/Document.js:667:3)
at Object.<anonymous> (/home/nevermind/experiment/crawler/node_modules/domino/lib/Document.js:491:5)
at HTMLInputElement.insert (/home/nevermind/experiment/crawler/node_modules/domino/lib/Node.js:394:37)
at HTMLFormElement.<anonymous> (/home/nevermind/experiment/crawler/node_modules/domino/lib/Node.js:97:11)
at insertElement (/home/nevermind/experiment/crawler/node_modules/domino/lib/HTMLParser.js:2517:17)
at insertHTMLElement (/home/nevermind/experiment/crawler/node_modules/domino/lib/HTMLParser.js:2500:5)
at in_body_mode (/home/nevermind/experiment/crawler/node_modules/domino/lib/HTMLParser.js:5608:19)
at insertToken (/home/nevermind/experiment/crawler/node_modules/domino/lib/HTMLParser.js:2418:7)
Would above messages helpful? Or I have to offer more informations?
While parsing some XML documents, I noticed that domino is having trouble parsing tags that use short notation like:
<some>
<one/>
<two>AAA</two>
</some>
In this case it would have trouble with one
. Is there a setting that allows me to tell domino that I am parsing XML? Or maybe XHTML?
Accoding to MDC and WHATWG, there should be a document.location
attribute mirroring window.location
. Quoting the latter:
The
location
attribute of theDocument
interface must return theLocation
object for thatDocument
object's global object, if it has a browsing context, and null otherwise.
I found out that GWT-compiled code needs this.
I deployed yesterday's changes in the mobile content service this morning, but reverted shortly thereafter because of a flood of these:
TypeError: Cannot convert object to primitive value at Object.create._serialize.value (/srv/deployment/mobileapps/deploy/node_modules/domino/lib/CSSStyleDeclaration.js:55:23) at Object.create.setProperty.value (/srv/deployment/mobileapps/deploy/node_modules/domino/lib/CSSStyleDeclaration.js:134:10) at Object.defineProperty.set (/srv/deployment/mobileapps/deploy/node_modules/domino/lib/CSSStyleDeclaration.js:265:12) at Object.hideIPA (/srv/deployment/mobileapps/deploy/src/lib/transformations/hideIPA.js:45:34) at runAllSectionsTransforms (/srv/deployment/mobileapps/deploy/src/lib/transforms.js:242:13) at Object.runParsoidDomTransforms (/srv/deployment/mobileapps/deploy/src/lib/transforms.js:263:5) at Request.<anonymous> (/srv/deployment/mobileapps/deploy/src/lib/parsoid-access.js:181:24) at Request.tryCatcher (/srv/deployment/mobileapps/deploy/node_modules/bluebird/js/release/util.js:11:23) at Promise._settlePromiseFromHandler (/srv/deployment/mobileapps/deploy/node_modules/bluebird/js/release/promise.js:491:31) at Promise._settlePromise (/srv/deployment/mobileapps/deploy/node_modules/bluebird/js/release/promise.js:548:18) at Promise._settlePromise0 (/srv/deployment/mobileapps/deploy/node_modules/bluebird/js/release/promise.js:593:10) at Promise._settlePromises (/srv/deployment/mobileapps/deploy/node_modules/bluebird/js/release/promise.js:676:18) at Promise._fulfill (/srv/deployment/mobileapps/deploy/node_modules/bluebird/js/release/promise.js:617:18) at Promise._resolveCallback (/srv/deployment/mobileapps/deploy/node_modules/bluebird/js/release/promise.js:418:57) at Promise._settlePromiseFromHandler (/srv/deployment/mobileapps/deploy/node_modules/bluebird/js/release/promise.js:504:17) at Promise._settlePromise (/srv/deployment/mobileapps/deploy/node_modules/bluebird/js/release/promise.js:548:18)
Suppose you have an anchor element within another anchor element. This is not valid HTML, because anchors cannot be nested. However, domino builds a DOM where those elements are siblings.
var domino = require('domino'),
window, document, childNodes, i;
window = domino.createWindow('<a href="http://www.example.com"><a href="http://www.example.com">Link</a> within a link</a>');
document = window.document;
childNodes = document.body.childNodes;
for(i=0; i<childNodes.length; i++) {
console.log(childNodes[i].nodeName); // prints A, A, #text, expected: A
}
I don't know if detecting those errors is the responsibility of a parser or if it should be handled by a validator. Either way, the current result is wrong. As far as I know, e.g. WebKit (as used in PhantomJS) builds a DOM with nested anchors. This is not valid of course, but at least it represents the input. I personally would prefer that domino does it the same way as PhantomJS (because I use both in a current project where it would be good that both DOMs are identical).
I had to comment out some lines in order to get this working:
// Add a mapping from id to n for n.ownerDocument
addId: { value: function addId(id, n) {
var val = this.byId[id];
if (!val) {
this.byId[id] = n;
}
else {
//warn('Duplicate element id ' + id);
if (!Array.isArray(val)) {
val = [val];
this.byId[id] = val;
}
val.push(n);
//val.sort(documentOrder);
}
}},
Errors:
warn('Duplicate element id ' + id);
^
ReferenceError: warn is not defined
at Object.addId (/var/node/pagetty/development/node_modules/domino/lib/Document.js:521:7)
at root (/var/node/pagetty/development/node_modules/domino/lib/Document.js:648:29)
at recursivelyRoot (/var/node/pagetty/development/node_modules/domino/lib/Document.js:667:3)
at Object. (/var/node/pagetty/development/node_modules/domino/lib/Document.js:491:5)
at HTMLDivElement.insert (/var/node/pagetty/development/node_modules/domino/lib/Node.js:394:37)
at HTMLDivElement. (/var/node/pagetty/development/node_modules/domino/lib/Node.js:97:11)
at insertElement (/var/node/pagetty/development/node_modules/domino/lib/HTMLParser.js:2517:17)
at insertHTMLElement (/var/node/pagetty/development/node_modules/domino/lib/HTMLParser.js:2500:5)
at in_body_mode (/var/node/pagetty/development/node_modules/domino/lib/HTMLParser.js:5463:9)
at insertToken (/var/node/pagetty/development/node_modules/domino/lib/HTMLParser.js:2418:7)
val.sort(documentOrder);
^
ReferenceError: documentOrder is not defined
at Object.addId (/var/node/pagetty/development/node_modules/domino/lib/Document.js:527:16)
at root (/var/node/pagetty/development/node_modules/domino/lib/Document.js:648:29)
at recursivelyRoot (/var/node/pagetty/development/node_modules/domino/lib/Document.js:667:3)
at Object. (/var/node/pagetty/development/node_modules/domino/lib/Document.js:491:5)
at HTMLDivElement.insert (/var/node/pagetty/development/node_modules/domino/lib/Node.js:394:37)
at HTMLDivElement. (/var/node/pagetty/development/node_modules/domino/lib/Node.js:97:11)
at insertElement (/var/node/pagetty/development/node_modules/domino/lib/HTMLParser.js:2517:17)
at insertHTMLElement (/var/node/pagetty/development/node_modules/domino/lib/HTMLParser.js:2500:5)
at in_body_mode (/var/node/pagetty/development/node_modules/domino/lib/HTMLParser.js:5463:9)
at insertToken (/var/node/pagetty/development/node_modules/domino/lib/HTMLParser.js:2418:7)
It appears an element's .attributes
property isn't a list-like object, but is instead a mapping. It does have a .length
property, but you can't index the attributes. Example:
var domino = require("domino");
var assert = require("assert");
var window = domino.createWindow('<a id="test">test</a>');
var el = window.document.getElementById("test");
// This succeeds:
assert(el.attributes.length == 1);
// The rest fail:
assert(el.attributes[0].name == "id");
assert(el.attributes[0].value == "test");
assert(el.attributes[0].nodeName == "id");
assert(el.attributes[0].nodeValue == "test");
// I believe currently el.attributes.id == "test", but it shouldn't:
assert(el.attributes.id === undefined);
The HTML5 serialization spec at http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#serializing-html-fragments states that:
If current node is a pre, textarea, or listing element, and the first child node of the element, if any, is a Text node whose character data has as its first character a U+000A LINE FEED (LF) character, then append a U+000A LINE FEED (LF) character."
Currently domino always appends a newline after pre/textarea/listing. Patch forthcoming.
domino = require('domino');
window = domino.createWindow('');
frag = window.document.createDocumentFragment()
frag.querySelector // Undefined
I'm writing a filmalbum using domino to scrape information from the sites. Domino seems to break on certain sites
scraping Black Hawk Down http://www.imdb.com/title/tt0367710/
undefined:1
f%20Combat%3A%20Making%20\'Black%20Hawk%20Down'%20(Video%202002)%20-%20http%3A
^
SyntaxError: Unexpected token %
at EventHandlerBuilder.build (D:\Projects\Filmalbum\node_modules\domino\lib\htmlelts.
js:56:55)
at Object.EventHandlerChangeHandler [as onchange] (D:\Projects\Filmalbum\node_modules
\domino\lib\htmlelts.js:62:63)
at Object.value (D:\Projects\Filmalbum\node_modules\domino\lib\Element.js:727:12)
at HTMLAnchorElement._setAttribute (D:\Projects\Filmalbum\node_modules\domino\lib\Ele
ment.js:407:16)
at createHTMLElt (D:\Projects\Filmalbum\node_modules\domino\lib\HTMLParser.js:2486:13
)
at insertHTMLElement (D:\Projects\Filmalbum\node_modules\domino\lib\HTMLParser.js:250
1:15)
at in_body_mode (D:\Projects\Filmalbum\node_modules\domino\lib\HTMLParser.js:5565:18)
at in_cell_mode (D:\Projects\Filmalbum\node_modules\domino\lib\HTMLParser.js:6368:5)
at insertToken (D:\Projects\Filmalbum\node_modules\domino\lib\HTMLParser.js:2420:7)
at emitTag (D:\Projects\Filmalbum\node_modules\domino\lib\HTMLParser.js:2367:7)
request("http://www.imdb.com/title/tt0367710/", function(error, response, body) {
var window = domino.createWindow(body)
, $ = Zepto(window);
scrapeIMDbInformation({title: "Black Hawk Dawn"}, $);
});
I know, this is the wrong url, but this keeps breaking my program. Here is another breaking url: http://www.imdb.com/title/tt1267446/
I will eventually get around this by finding out the right urls (they seem not to break). But this should still be fixed.
Running Windows 7 x64 NodeJS v0.8.12 Domino v1.0.5
/home/nevermind/experiment/crawler/node_modules/domino/lib/Document.js:527
val.sort(documentOrder);
^
ReferenceError: documentOrder is not defined
at Object.addId (/home/nevermind/experiment/crawler/node_modules/domino/lib/Document.js:527:16)
at root (/home/nevermind/experiment/crawler/node_modules/domino/lib/Document.js:648:29)
at recursivelyRoot (/home/nevermind/experiment/crawler/node_modules/domino/lib/Document.js:667:3)
at Object. (/home/nevermind/experiment/crawler/node_modules/domino/lib/Document.js:491:5)
at HTMLInputElement.insert (/home/nevermind/experiment/crawler/node_modules/domino/lib/Node.js:394:37)
at HTMLFormElement. (/home/nevermind/experiment/crawler/node_modules/domino/lib/Node.js:97:11)
at insertElement (/home/nevermind/experiment/crawler/node_modules/domino/lib/HTMLParser.js:2517:17)
at insertHTMLElement (/home/nevermind/experiment/crawler/node_modules/domino/lib/HTMLParser.js:2500:5)
at in_body_mode (/home/nevermind/experiment/crawler/node_modules/domino/lib/HTMLParser.js:5608:19)
at insertToken (/home/nevermind/experiment/crawler/node_modules/domino/lib/HTMLParser.js:2418:7)
Seems that the variable documentOrder doesn't exist anywhere.
After I commented these line it works fine. But the content of object window.location still seems not right…
Hi, I'm trying to run code in domino for server-side rendering of an existing app that uses "instanceof" .
Up to now I've been testing with jsdom in Node.js.
I'd like to do my rendering in Nashorn and I wanted to try Domino since it doesn't seems to be tightly bound to Node.js, however the following code (I guess it's valid for all elements) :
var btn = document.createElement("BUTTON");
console.log(btn instanceof HTMLElement);
returns false
where it returns true
in browsers or in jsdom (at least in Node.js).
I also had to manually run the htmlelts.js in order to have the "HTMLElement" class available.
JQuery added code that relies on window having the functions of time:
setTimeout, clearTimeout, setInterval, clearInterval
window.setTimeout is missing in JQuery when I rely on domino in nodejs.
Could you please add these to domino, so they will be defined in window object and my project based on JQUery and domino is functioning again?
Thx.
Any enthusiasm for adding support for MutationObserver? In the Living Standard, part of the full W3C Recommendation for DOM4, and implemented in almost every browser already.
Also, I'd find pretty useful.
I'd be happy to help out and try to work on this myself, but I haven't dug into the Domino source much, so some pointers in the right direction (assuming you'd be happy to include this) would be helpful.
I'm not having much luck using querySelectorAll
on documents. For example, modifying the example from the readme slightly produces weird results:
var domino = require('domino');
var window = domino.createWindow('<div><h1>Hello world</h1><p>Hi there.</p></div>');
var document = window.document;
// Expected: 1, Actual: 0
console.log(document.querySelectorAll('div').length);
// Outputs 1 -- behaves as expected
console.log(document.body.querySelectorAll('div').length);
Note that the same issue happens with getElementsByTagName
.
Continuing with the example above, we get some more weird behavior even with sibling elements:
// Outputs 1 as expected
console.log(document.body.querySelector('h1').length);
// Outputs 0, expected 1
console.log(document.body.querySelector('p').length);
We're running into a (relatively infrequent) error in the mobileapps service that traces back to domino.
Example request:
https://de.wikipedia.org/api/rest_v1/page/mobile-sections/Verallgemeinerter_Laplace-Operator
Stack trace (from local machine):
TypeError: Cannot read property 'type' of undefined
at TokenStreamBase.LA (/Users/mholloway/mobileapps/node_modules/domino/lib/cssparser.js:810:29)
at TokenStreamBase.advance (/Users/mholloway/mobileapps/node_modules/domino/lib/cssparser.js:683:20)
at Parser.additions._readDeclarations (/Users/mholloway/mobileapps/node_modules/domino/lib/cssparser.js:3402:42)
at Parser.additions.parseStyleAttribute (/Users/mholloway/mobileapps/node_modules/domino/lib/cssparser.js:3581:22)
at parseStyles (/Users/mholloway/mobileapps/node_modules/domino/lib/CSSStyleDeclaration.js:23:10)
at Object.create._parsed.get (/Users/mholloway/mobileapps/node_modules/domino/lib/CSSStyleDeclaration.js:38:28)
at Object.create.setProperty.value (/Users/mholloway/mobileapps/node_modules/domino/lib/CSSStyleDeclaration.js:126:22)
at Object.defineProperty.set (/Users/mholloway/mobileapps/node_modules/domino/lib/CSSStyleDeclaration.js:304:12)
at Object.setMathFormulaImageMaxWidth (/Users/mholloway/mobileapps/lib/transformations/setMathFormulaImageMaxWidth.js:17:40)
at Object.transforms.addRequiredMarkup (/Users/mholloway/mobileapps/lib/transforms.js:233:33)
at Request.<anonymous> (/Users/mholloway/mobileapps/lib/parsoid-access.js:153:24)
at Request.tryCatcher (/Users/mholloway/mobileapps/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/Users/mholloway/mobileapps/node_modules/bluebird/js/release/promise.js:504:31)
at Promise._settlePromise (/Users/mholloway/mobileapps/node_modules/bluebird/js/release/promise.js:561:18)
at Promise._settlePromise0 (/Users/mholloway/mobileapps/node_modules/bluebird/js/release/promise.js:606:10)
at Promise._settlePromises (/Users/mholloway/mobileapps/node_modules/bluebird/js/release/promise.js:685:18)
The line in the mobileapps service triggering this error is here:
https://github.com/wikimedia/mediawiki-services-mobileapps/blob/master/lib/transformations/setMathFormulaImageMaxWidth.js#L17
The HTML5 spec doesn't specify a serialization algorithm guaranteed to round-trip anymore.
See whatwg/html#944
var domino = require('domino'),
window, document, heading;
window = domino.createWindow("<h1>First</h1><h1>Second</h1>");
document = window.document;
heading = document.body.querySelector('h1');
// Expect 0, result 1
console.log(heading.querySelectorAll('h1').length);
Looks like QSA is getting run on document.body
instead of heading
. This is with Node 0.10.5
I'm on domino version 1.0.27
:
cxlt@Durindana:janus-stdlib#master± node --version
v6.9.1
cxlt@Durindana:janus-stdlib#master± node
> var window = require('domino').createWindow('<input type="checkbox"/>')
undefined
> var input = window.document.querySelector('input')
undefined
> input.checked
false
> input.checked = true
true
> input.checked
true
> input.checked = false
false
> input.checked
true
> delete input.checked
true
> input.checked
true
Originally, I was using jQuery .prop('checked', someBoolean)
with domino which also failed, but this bare case doesn't work either.
I'm happy to take a look and submit a PR if you have a pointer on where to start.
document.body = ...
currently causes a nyi exception. This doesn't look like it should be that difficult to implement?
The latest version on node is 1.0.8, while the github sources specify 1.0.7 in the package.json. The released 1.0.8 don't include the recent patches, which mediawiki's parsoid project would like to have. Could we get a new 1.0.9 release of domino, which corresponds to a git tag pushed to github? Thanks.
Is there API docs someplace?
We have an implementation of TreeWalker
but not NodeIterator
.
It'd be really useful to be able to build document fragments, not only whole HTML documents. Is that possible? This is a feature that's common in parse-side libraries, like Parse5, which leads me to think it's not a spec issue, just that it hasn't been implemented yet.
More specifically, it'd be useful to be able to do something like:
var doc = domino.createDocumentFragment("<div></div>");
doc.childNodes[0].innerHTML = "Hi";
console.log(doc.documentElement.outerHTML); // "<div>Hi</div>";
Currently, if you try to do this (with createDocument
) you get extra , and tags wrapped around your content.
Is that possible? I'd be happy to have a go at implementing it, if you can point me in the right direction.
I got the following error:
/path/to/node_modules/domino/lib/CSSStyleDeclaration.js:21
s = s.replace(/^;/, '');
^
TypeError: Cannot call method 'replace' of null
at parseStyles (/home/nevermind/experiment/crawler/node_modules/domino/lib/CSSStyleDeclaration.js:21:9)
at Object.<anonymous> (/home/nevermind/experiment/crawler/node_modules/domino/lib/CSSStyleDeclaration.js:35:28)
at Object.<anonymous> (/home/nevermind/experiment/crawler/node_modules/domino/lib/CSSStyleDeclaration.js:118:22)
at Object.<anonymous> (/home/nevermind/experiment/crawler/node_modules/domino/lib/CSSStyleDeclaration.js:258:12)
at eval at <anonymous> (/home/nevermind/experiment/crawler/jsdom.js:82:8)
at eval at <anonymous> (/home/nevermind/experiment/crawler/jsdom.js:82:8)
at Object.<anonymous> (eval at <anonymous> (/home/nevermind/experiment/crawler/jsdom.js:82:8))
at Object.<anonymous> (/home/nevermind/experiment/crawler/jsdom.js:82:3)
at IncomingMessage.<anonymous> (/home/nevermind/experiment/crawler/jsdom.js:39:15)
at IncomingMessage.emit (events.js:88:20)
Again, according to the source code, seems like when the value have been set which isn't a string object caused the error above.
function parseStyles(s) {
var parser = new parserlib.css.Parser();
var result = {};
parser.addListener("property", function(e) {
if (e.invalid) return; // Skip errors
result[e.property.text] = e.value.text;
if (e.important) result.important[name] = e.important;
});
s = s.replace(/^;/, '');
parser.parseStyleAttribute(s);
return result;
}
This issue & #4 are caused when I'm trying to load the plugin jquery.1.6.2 into the window object.
While trying to get GWT-compiled code to execute in a domino environment, I noticed that it attempts to perform an open
/write
/close
cycle on a document, which isn't (properly) supported by domino:
domino = require("domino");
html = "<!DOCTYPE html><html><head></head><body></body></html>";
document = domino.createDocument(html);
console.log(!!document.body); // prints true
document.open();
document.write(html);
document.close();
console.log(!!document.body); // prints false
It would seem that even if document.write
during page load is unsupported, it should be possible to support the above, e.g. by caching all content received during write
and parsing it during close
.
Would you be happy to accept SVG element support? I'm trying to render HTML pages including inline SVG, and I can't right now, as none of the elements exist. Specifically, I want to be able to use libraries like Leaflet and D3 to render server-side, and they get upset because they can't detect SVG support. Leaflet for example checks for d.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect
, but createElementNS only returns HTML elements.
I've found somebody else's implementation of this on top of Domino en route too (blog post, old fork), which suggests this might be quite a popular addition. It'd be great to pull some of those changes back into Domino itself, and it looks like getting D3 working there only requires some very small additions.
(Sorry, I know I also asked about Mutation Observers a while back too, and I haven't got to actually implementing those yet either. They're on the list though, I'll get there, promise!)
Not sure if it's out of scope for the project, but I ran into an issue with an automated headless test that is accessing document.styleSheets
. This is needed since it's the only way to get at the stylesheet.rules
, etc properties (which I'm guessing isn't supported either).
Filing this as a reminder,
> document.querySelector("#cite_note-13.3F_It_Can't_Be!-3");
TypeError: combinators[op] is not a function
at compile (./domino/lib/select.js:653:32)
at find (./domino/lib/select.js:804:14)
at module.exports.exports (./domino/lib/select.js:850:10)
at Object.create.querySelector.value (./domino/lib/Document.js:650:12)
at repl:1:10
at REPLServer.defaultEval (repl.js:252:27)
at bound (domain.js:287:14)
at REPLServer.runBound [as eval] (domain.js:300:12)
at REPLServer.<anonymous> (repl.js:417:12)
at emitOne (events.js:82:20)
Chrome throws an Uncaught DOMException: Failed to execute 'querySelector' on 'Document': '#cite_note-13.3F_It_Can't_Be!-3' is not a valid selector.
First off, thank you so much for putting this module together; it’s exactly what I wanted jsdom to be! My one pedantic little issue is that when given a full document, the parser seems to discard the whitespace of its outermost elements. It also replaces the doctype declaration.
For example, if you pass this document…
<!doctype html>
<html>
<head>
<title>A title</title>
</head>
<body>
<h1>A heading</h1>
</body>
</html>
…into domino.createDocument…
var read = require('fs').readFileSync
var document = require('domino').createDocument
var html = read('./input.html')
console.log(document(html).outerHTML)
…the output is:
<!DOCTYPE html><html><head>
<title>A title</title>
</head>
<body>
<h1>A heading</h1>
</body></html>
I think it would be ideal if the output matched the input.
Should we release a 1.0.10? The node 0.10.0 fixes seem like reason enough to do a new release.
I'm having issues iterating over the list of attributes on an element. Here's sample code:
domino = require('domino');
window = domino.createWindow("<h1 lang='en'>Hello</h1>");
h1 = window.document.body.firstChild;
// Outputs 1
console.log(h1.attributes.length);
// Returns undefined, expected an object
console.log(h1.attributes[0]);
While trying to get GWT-compiled code to execute in a domino environment, I noticed that the iframe
element is lacking some required properties. It should provide a contentWindow
and an associated contentDocument
. These could be set up by domino.createWindow
, but I think it would be better if there were some kind of configurable factory, so that users could add additional steps, e.g. turning the window into a vm context, modifying the navigator
property or installing a mutationHandler
.
For unset style attributes, the expected return value of CSSStyleDeclaration.getPropertyValue()
is an empty string, not undefined. getPropertyPriority()
appears to be written to handle this case correctly.
const domino = require('domino')
const document = domino.createDocument('<a href=/></a>')
document.querySelector('a').style.getPropertyValue('background')
// ^ should return '' but returns undefined instead
domino/lib/CSSStyleDeclaration.js
Line 99 in c8fbfff
Hi, this issue happend when there's some script source not in the same domain.
Like now I'm in http://abc.com, but the script is at http://ijk.com/some.js, and when I access its src like
console.log(window.document.getElementsByTagName('script')[2].src)
Then I got errors here.
Actually they are all in the same block, so I post these together.
/path/to/domino/lib/URL.js:18
var pos = S.lastIndexOf(match[4], ":");
^
ReferenceError: S is not defined
/path/to/domino/lib/URL.js:19
this.host = substring(match[4], 0, pos);
^
ReferenceError: substring is not defined
/path/to/domino/lib/URL.js:20
this.port = substring(match[4], pos+1);
^
ReferenceError: substring is not defined
Maybe there should be some utilities been required in this module, but I can't find it though, now I modified it, and not sure if I made any other mistakes. Hope I can have some solutions here.
The original:
var pos = S.lastIndexOf(match[4], ":");
this.host = substring(match[4], 0, pos);
this.port = substring(match[4], pos+1);
Modified:
var pos = match[4].lastIndexOf(':');
this.host = match[4].substring(0, pos);
this.port = match[4].substring(pos+1);
As indicated in the spec section linked from this project's README. The Attr interface in DOM4 is supposed to have a .nodeValue
and a .textContent
property as legacy aliases of the .value
property, but these are not supported in this library:
var domino = require('domino');
var document = domino.createDocument('<h1 class="hello">Hello world</h1>');
var h1 = document.querySelector('h1');
var classAttr = h1.attributes.item(0);
console.log('value is:' + classAttr.value);
console.log('nodeValue is:' + classAttr.nodeValue);
console.log('textContent is:' + classAttr.textContent);
I noticed that the following fails:
var div = document.createElement('div');
div.appendChild(document.createTextNode(123)); // <-- giving it a number, not a string
div.innerHTML; // <-- throws an error
This is because Domino's createTextNode does not coerce the argument into a string, although browsers seem to do so. Thus the text node's data is a number, which the innerHTML logic doesn't expect.
Is this coercion a part of the official DOM spec, or just something nice that browsers do?
Would you accept a PR to enable coercion, or are there reasons not to implement it? I was just going to change createTextNode
from
return new Text(this, data);
into
return new Text(this, ''+data);
https://developer.mozilla.org/en/docs/Web/API/Node/contains
It seems that this is part of the DOM Living Standard, but it's implemented in ancient browsers like IE5 (!) so I was a bit surprised to see that it was missing from Domino.
Typing "document.ELEMENT_NODE" into the webkit JavaScript console confirms that the node type properties are inherited from Node. But Node.js adds the properties to Node, not Node.prototype, so they are not inherited by Document (or any of the other subclasses).
Node.prototype should get a copy of the node type properties, as well as Node.
Hey all, I'm seeing a fair number of these errors generated by requests involving Chinese language scripts:
TypeError: Cannot set property 'text-decoration' of undefined
at Parser.(/Users/mholloway/mobileapps/node_modules/domino/lib/CSSStyleDeclaration.js:20:56)
at Parser.EventTarget.fire (/Users/mholloway/mobileapps/node_modules/domino/lib/cssparser.js:91:30)
at Parser.additions._declaration (/Users/mholloway/mobileapps/node_modules/domino/lib/cssparser.js:2615:26)
at Parser.additions._readDeclarations (/Users/mholloway/mobileapps/node_modules/domino/lib/cssparser.js:3123:41)
at Parser.additions.parseStyleAttribute (/Users/mholloway/mobileapps/node_modules/domino/lib/cssparser.js:3344:22)
at parseStyles (/Users/mholloway/mobileapps/node_modules/domino/lib/CSSStyleDeclaration.js:23:10)
at Object.create._parsed.get (/Users/mholloway/mobileapps/node_modules/domino/lib/CSSStyleDeclaration.js:36:28)
at Object.create.getPropertyValue.value (/Users/mholloway/mobileapps/node_modules/domino/lib/CSSStyleDeclaration.js:87:16)
at Object.defineProperty.get (/Users/mholloway/mobileapps/node_modules/domino/lib/CSSStyleDeclaration.js:258:19)
at Object.hideIPA (/Users/mholloway/mobileapps/lib/transformations/hideIPA.js:25:29)
[...]
Basically, order of elements arriving gets mangled up.
var dom = require('domino'),
window = dom.createDocument('<h2>h2</h2><h3>h3</h3><h3></h3><h2></h2><h3></h3>');
window.querySelectorAll('h2, h3').forEach(function(el){
console.log(el.tagName);
});
Expected: H2, H3, H3, H2, H3
Actual: H2, H2, H3, H3, H3
similarly, any comma separated selectors do the same:
var dom = require('domino'),
window = dom.createDocument('<h2 class="one">h2</h2><h3 class="two">h3</h3><h3 class="one"></h3><h2></h2><h3></h3>');
window.querySelectorAll('.one, .two').forEach(function(el){
console.log(el.className);
});
Output: one, one, two
Expected: one, two, one
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.