mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-30 00:55:00 +00:00
b750ce38b8
Builds a DOM tree (jsdom) from the tokens and then serializes that using document.innerHTML. This is all very experimental, so don't be surprised by rough edges.
96 lines
2.4 KiB
JavaScript
96 lines
2.4 KiB
JavaScript
var HTML5 = require('../html5');
|
|
var events = require('events');
|
|
|
|
function error(msg) {
|
|
return {type: 'SerializeError', data: msg};
|
|
}
|
|
|
|
function empty_tag(node) {
|
|
if(node.hasChildNodes()) return error(_("Void element has children"));
|
|
return {type: 'EmptyTag', name: node.tagName, data: node.attributes, namespace: node.namespace};
|
|
}
|
|
|
|
function start_tag(node) {
|
|
return {type: 'StartTag', name: node.tagName, data: node.attributes, namespace: node.namespace};
|
|
}
|
|
|
|
function end_tag(node) {
|
|
return {type: 'EndTag', name: node.tagName, namespace: node.namespace };
|
|
}
|
|
|
|
function text(data, target) {
|
|
if(m = new RegExp("^[" + HTML5.SPACE_CHARACTERS + "]+").exec(data)) {
|
|
target.emit('token', {type: 'SpaceCharacters', data: m[0]});
|
|
data = data.slice(m[0].length, data.length);
|
|
if(data.length == 0) return;
|
|
}
|
|
|
|
if(m = new RegExp("["+HTML5.SPACE_CHARACTERS + "]+$").exec(data)) {
|
|
target.emit('token', {type: 'Characters', data: data.slice(0, m.length)});
|
|
target.emit('token', {type: 'SpaceCharacters', data: data.slice(m.index, data.length)});
|
|
} else {
|
|
target.emit('token', {type: 'Characters', data: data});
|
|
}
|
|
}
|
|
|
|
function comment(data) {
|
|
return {type: 'Comment', data: data};
|
|
}
|
|
|
|
function doctype(node) {
|
|
return {type: 'Doctype', name: node.nodeName, publicId: node.publicId, systemId: node.systemId, correct: node.correct};
|
|
}
|
|
|
|
function unknown(node) {
|
|
return error(_("unknown node: ")+ JSON.stringify(node));
|
|
}
|
|
|
|
function _(str) {
|
|
return str;
|
|
}
|
|
|
|
HTML5.TreeWalker = function(document, dest) {
|
|
if(dest instanceof Function) this.addListener('token', dest);
|
|
walk(document, this);
|
|
};
|
|
|
|
function walk(node, dest) {
|
|
switch(node.nodeType) {
|
|
case node.DOCUMENT_FRAGMENT_NODE:
|
|
case node.DOCUMENT_NODE:
|
|
for(var child = 0; child < node.childNodes.length; ++child) {
|
|
walk(node.childNodes[child], dest);
|
|
}
|
|
break;
|
|
|
|
case node.ELEMENT_NODE:
|
|
if(HTML5.VOID_ELEMENTS.indexOf(node.tagName.toLowerCase()) != -1) {
|
|
dest.emit('token', empty_tag(node));
|
|
} else {
|
|
dest.emit('token', start_tag(node));
|
|
for(var child = 0; child < node.childNodes.length; ++child) {
|
|
walk(node.childNodes[child], dest);
|
|
}
|
|
dest.emit('token', end_tag(node));
|
|
}
|
|
break;
|
|
|
|
case node.TEXT_NODE:
|
|
text(node.nodeValue, dest);
|
|
break;
|
|
|
|
case node.COMMENT_NODE:
|
|
dest.emit('token', comment(node.nodeValue));
|
|
break;
|
|
|
|
case node.DOCUMENT_TYPE_NODE:
|
|
dest.emit('token', doctype(node));
|
|
break;
|
|
|
|
default:
|
|
dest.emit('token', unknown(node));
|
|
}
|
|
}
|
|
|
|
HTML5.TreeWalker.prototype = new events.EventEmitter;
|