tmpvar/jsdom — Issue #403: Insertion point issue for document.write
Author: otakustay
Created: 2012-02-17 06:53:39+00:00
State: open

`document.write` is a complex method in HTML parsing and script execution, and jsdom seems totally messed it up, here are some examples, each of them illustrates a corresponding issue.

All of the examples uses the same node script below:

var jsdom = require('jsdom');
var fs = require('fs');
var html = fs.readFileSync('content.htm').toString();

jsdom.defaultDocumentFeatures = {
FetchExternalResources: ['script', 'link'],
ProcessExternalResources: ['script'],
MutationEvents: '2.0',
QuerySelector: true
};

var document = jsdom.jsdom(html);

printTree(document.documentElement);

function printTree(root) {
var output = [];

dumpTree(root, 0, output);

console.log(output.join('\n'));
}

function dumpTree(element, indent, output) {
var content = element.nodeName.toLowerCase();
if (element.id) {
content += '#' + element.id;
}
else if (element.className) {
content += '.' + element.className;
}
else if (element.type) {
content += '[type=' + element.type + ']';
}

output.push(Array(indent + 1).join(' ') + content);

for (var i = 0; i < element.children.length; i++) {
dumpTree(element.children[i], indent + 4, output);
}
}

This code would read the **content.htm** file as a HTML string, pass it to `jsdom.jsdom` method, and then print the `documentElement` **as** a tree (using indent and line break).

1.
**content.htm**:

Hello World

This HTML in jsdom would output:

html

Actually, the `documentElement.innerHTML` only contains `"abc"`, it seems that `document.write()` would discard current document and open a new one, although `document.write()` is called in an *inline* `` and `

` and ``, this code runs quite well.

**NOTE**:

From the 2nd example, I ommited all line breaks (\n) in **content.htm**, but in order to clearly display what is in **content.htm**, here I still put line breaks (\n), for test purpose you should remove all line breaks (\n) yourself.

2.
**content.htm**

Hello World

This HTML in jsdom would output:
html
head
title
body
script

This is nice and seems no problem, but when I print `documentElement.innerHTML`, I found something like this:

It seems `document.write()` removes everything in the `

Footer here

In this example, I put 2 extra `

` elements after the `

This example is the most interesting one to me, since the `document.write()` always **writes** its content to **the last element in document order**, it writes `document.write("

Paragraph

");` to the `