104 lines
2.4 KiB
JavaScript
104 lines
2.4 KiB
JavaScript
'use strict';
|
|
|
|
var htmlparser = require('htmlparser2');
|
|
var isObject = require('isobject');
|
|
|
|
/**
|
|
* @see https://github.com/fb55/htmlparser2/wiki/Parser-options
|
|
*/
|
|
var defaultOptions = {lowerCaseTags: false, lowerCaseAttributeNames: false};
|
|
|
|
/**
|
|
* Parse html to PostHTMLTree
|
|
* @param {String} html
|
|
* @param {Object} [options=defaultOptions]
|
|
* @return {PostHTMLTree}
|
|
*/
|
|
function postHTMLParser(html, options) {
|
|
var bufArray = [],
|
|
results = [];
|
|
|
|
bufArray.last = function() {
|
|
return this[this.length - 1];
|
|
};
|
|
|
|
var parser = new htmlparser.Parser({
|
|
onprocessinginstruction: function(name, data) {
|
|
if (name.toLowerCase() === '!doctype') {
|
|
results.push('<' + data + '>');
|
|
}
|
|
},
|
|
oncomment: function(data) {
|
|
var comment = '<!--' + data + '-->',
|
|
last = bufArray.last();
|
|
|
|
if (!last) {
|
|
results.push(comment);
|
|
return;
|
|
}
|
|
|
|
last.content || (last.content = []);
|
|
last.content.push(comment);
|
|
},
|
|
onopentag: function(tag, attrs) {
|
|
var buf = { tag: tag };
|
|
|
|
if (Object.keys(attrs).length) {
|
|
buf.attrs = attrs;
|
|
}
|
|
|
|
bufArray.push(buf);
|
|
},
|
|
onclosetag: function() {
|
|
var buf = bufArray.pop();
|
|
|
|
if (!bufArray.length) {
|
|
results.push(buf);
|
|
return;
|
|
}
|
|
|
|
var last = bufArray.last();
|
|
if (!Array.isArray(last.content)) {
|
|
last.content = [];
|
|
}
|
|
|
|
last.content.push(buf);
|
|
},
|
|
ontext: function(text) {
|
|
var last = bufArray.last();
|
|
if (!last) {
|
|
results.push(text);
|
|
return;
|
|
}
|
|
|
|
last.content || (last.content = []);
|
|
last.content.push(text);
|
|
}
|
|
}, options || defaultOptions);
|
|
|
|
parser.write(html);
|
|
parser.end();
|
|
|
|
return results;
|
|
}
|
|
|
|
function parserWrapper() {
|
|
var option;
|
|
|
|
function parser(html) {
|
|
var opt = option || defaultOptions;
|
|
return postHTMLParser(html, opt);
|
|
}
|
|
|
|
if (arguments.length === 1 && isObject(arguments[0])) {
|
|
option = arguments[0];
|
|
return parser;
|
|
}
|
|
|
|
option = arguments[1];
|
|
return parser(arguments[0]);
|
|
}
|
|
|
|
module.exports = parserWrapper;
|
|
module.exports.defaultOptions = defaultOptions;
|