Skip to content

Commit

Permalink
Use new parse5 streaming interface
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Mayr authored and Sebmaster committed Jan 26, 2016
1 parent 65bf5f5 commit 7d4c68a
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 119 deletions.
1 change: 0 additions & 1 deletion .jscsrc
Expand Up @@ -35,7 +35,6 @@
"node_modules",
"benchmark/browser-bundle.js",
"test/worker-bundle.js",
"lib/jsdom/browser/htmltodom.js",
"lib/jsdom/browser/default-stylesheet.js",
"lib/jsdom/level2/style.js",
"lib/jsdom/level3/xpath.js",
Expand Down
208 changes: 156 additions & 52 deletions lib/jsdom/browser/documentAdapter.js
@@ -1,73 +1,177 @@
"use strict";

const attributes = require("../living/attributes");
const DocumentType = require("../living/generated/DocumentType");
const idlUtils = require("../living/generated/utils");

// Tree traversing
exports.getFirstChild = function (node) {
return node.childNodes[0];
};
module.exports = function (document, fragment) {
const exports = {};

// Node construction
exports.createDocument = function () {
return document;
};

exports.createDocumentFragment = function () {
return document.createDocumentFragment();
};

exports.createElement = function (tagName, namespaceURI, attrs) {
const elem = document._createElementWithCorrectElementInterface(tagName, namespaceURI);
if (tagName === "script" && !fragment) {
elem._parserInserted = true;
elem._nonBlocking = false;
}

elem._localName = tagName;
elem._namespaceURI = namespaceURI || null;
for (let i = 0; i < attrs.length; ++i) {
attributes.setAttributeValue(elem, attrs[i].name, attrs[i].value,
attrs[i].prefix || null, attrs[i].namespace || null);
}
return elem;
};

exports.createCommentNode = function (data) {
return document.createComment(data);
};

// Tree mutation
exports.appendChild = function (parentNode, newNode) {
parentNode.appendChild(newNode);
};

exports.insertBefore = function (parentNode, newNode, referenceNode) {
parentNode.insertBefore(newNode, referenceNode);
};

exports.setTemplateContent = function (templateElement, contentElement) {
templateElement.content = contentElement;
};

exports.setDocumentType = function (doc, name, publicId, systemId) {
const doctypeNode = doc.doctype;
if (doctypeNode) {
doctypeNode.parentNode.removeChild(doctypeNode);
}
const newType = DocumentType.createImpl([], { core: document.defaultView, ownerDocument: doc, name, publicId, systemId });
exports.appendChild(doc, newType);
};

exports.setQuirksMode = function (doc) {
doc._mode = "quirks";
};

exports.isQuirksMode = function (doc) {
return doc._mode === "quirks";
};

exports.detachNode = function (node) {
if (node.parentNode) {
node.parentNode.removeChild(node);
}
};

exports.insertText = function (parentNode, text) {
const lastChild = parentNode.lastChild;
if (lastChild && lastChild.nodeName === "#text") {
lastChild.nodeValue += text;
} else {
exports.appendChild(parentNode, document.createTextNode(text));
}
};

exports.insertTextBefore = function (parentNode, text, referenceNode) {
const prevNode = referenceNode.previousSibling;
if (prevNode && prevNode.nodeName === "#text") {
prevNode.nodeValue += text;
} else {
exports.insertBefore(parentNode, document.createTextNode(text), referenceNode);
}
};

exports.adoptAttributes = function (recipientNode, attrs) {
for (let i = 0; i < attrs.length; ++i) {
if (recipientNode.hasAttribute(attrs[i].name)) {
recipientNode.attributes.setNamedItemNS(attrs[i]);
}
}
};

// Tree traversing
exports.getFirstChild = function (node) {
return idlUtils.implForWrapper(node.childNodes[0]);
};

exports.getChildNodes = function (node) {
// parse5 treats template elements specially, assuming you return an array whose single item is the document fragment
const children = node._templateContents ? [node._templateContents] : [];
if (children.length === 0) {
exports.getChildNodes = function (node) {
const impls = [];
for (let i = 0; i < node.childNodes.length; ++i) {
children.push(idlUtils.implForWrapper(node.childNodes[i]));
impls.push(idlUtils.implForWrapper(node.childNodes[i]));
}
}
return children;
};
return impls;
};

exports.getParentNode = function (node) {
return node.parentNode;
};
exports.getParentNode = function (node) {
return node.parentNode;
};

exports.getAttrList = function (node) {
return node.attributes;
};
exports.getAttrList = function (node) {
return node.attributes;
};

// Node data
exports.getTagName = function (element) {
return element.tagName.toLowerCase();
};
// Node data
exports.getTagName = function (element) {
if (!element.tagName) {
return null;
}

exports.getNamespaceURI = function (element) {
return element.namespaceURI || "http://www.w3.org/1999/xhtml";
};
return element.tagName.toLowerCase();
};

exports.getTextNodeContent = function (textNode) {
return textNode.nodeValue;
};
exports.getNamespaceURI = function (element) {
return element.namespaceURI || "http://www.w3.org/1999/xhtml";
};

exports.getCommentNodeContent = function (commentNode) {
return commentNode.nodeValue;
};
exports.getTextNodeContent = function (textNode) {
return textNode.nodeValue;
};

exports.getDocumentTypeNodeName = function (doctypeNode) {
return doctypeNode.name;
};
exports.getCommentNodeContent = function (commentNode) {
return commentNode.nodeValue;
};

exports.getDocumentTypeNodePublicId = function (doctypeNode) {
return doctypeNode.publicId || null;
};
exports.getDocumentTypeNodeName = function (doctypeNode) {
return doctypeNode.name;
};

exports.getDocumentTypeNodeSystemId = function (doctypeNode) {
return doctypeNode.systemId || null;
};
exports.getDocumentTypeNodePublicId = function (doctypeNode) {
return doctypeNode.publicId || null;
};

// Node types
exports.isTextNode = function (node) {
return node.nodeName === "#text";
};
exports.getDocumentTypeNodeSystemId = function (doctypeNode) {
return doctypeNode.systemId || null;
};

exports.isCommentNode = function (node) {
return node.nodeName === "#comment";
};
exports.getTemplateContent = function (node) {
return node.content;
};

exports.isDocumentTypeNode = function (node) {
return node.nodeType === 10;
};
// Node types
exports.isTextNode = function (node) {
return node.nodeName === "#text";
};

exports.isCommentNode = function (node) {
return node.nodeName === "#comment";
};

exports.isDocumentTypeNode = function (node) {
return node.nodeType === 10;
};

exports.isElementNode = function (node) {
return Boolean(node.tagName);
};

exports.isElementNode = function (node) {
return Boolean(node.tagName);
return exports;
};
8 changes: 3 additions & 5 deletions lib/jsdom/browser/domtohtml.js
@@ -1,18 +1,16 @@
"use strict";
const parse5 = require("parse5");
const documentAdapter = require("./documentAdapter");
const adapter = require("./documentAdapter.js")(null); // don't need a doc for serialization
const NODE_TYPE = require("../living/node-type");
const idlUtils = require("../living/generated/utils");

const serializer = new parse5.TreeSerializer(documentAdapter);

exports.domToHtml = function (iterable) {
let ret = "";
for (const node of iterable) {
if (node.nodeType === NODE_TYPE.DOCUMENT_NODE) {
ret += serializer.serialize(node);
ret += parse5.serialize(node, { treeAdapter: adapter });
} else {
ret += serializer.serialize({ childNodes: [idlUtils.wrapperForImpl(node)] });
ret += parse5.serialize({ childNodes: [idlUtils.wrapperForImpl(node)] }, { treeAdapter: adapter });
}
}
return ret;
Expand Down

0 comments on commit 7d4c68a

Please sign in to comment.