'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 = '', 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;