mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 10:35:48 +00:00
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;
|