makestatic-parse-html
Version:
Parses HTML files to an abstract syntax tree
104 lines (92 loc) • 2.7 kB
JavaScript
function querySelector (query) {
const select = require('css-select')
const adapter = require('./lib/adapter')
return select.selectOne(query, this.result, {adapter: adapter})
}
function querySelectorAll (query) {
const select = require('css-select')
const adapter = require('./lib/adapter')
return select(query, this.result, {adapter: adapter})
}
function parseFragment (...args) {
const parser = require('parse5')
return parser.parseFragment(...args)
}
function decorate (ast) {
ast.querySelector = querySelector.bind(ast)
ast.querySelectorAll = querySelectorAll.bind(ast)
ast.parseFragment = parseFragment
Object.defineProperty(ast, 'adapter', {
enumerable: false,
get: () => {
return require('./lib/adapter')
}
})
}
/**
* Parses HTML files to abstract syntax trees.
*
* @class ParseHtml
*
* @see http://inikulin.github.io/parse5/ Parse5
* @see https://github.com/fb55/css-select Css Select
*/
class ParseHtml {
/**
* Parse a file to an abstract syntax tree, the AST is assigned to
* `file.ast.html`.
*
* This implementation assigns a `seal` function to the file so that when
* the file content is updated it will correspond to the current state of
* the AST.
*
* The generated AST is decorated with `querySelector` and `querySelectorAll`
* functions so that you can query the AST for desired nodes.
*
* It also adds an `adapter` getter that allows access to the static DOM
* adapter function.
*
* @function sources
* @member ParseHtml
* @param {Object} file the current file.
* @param {Object} context the processing context.
* @param {Object} [options] options for `postcss`.
*/
sources (file, context, options = {}) {
const parser = require('parse5')
const ast = new context.TreeAdapter(
(adapter, content) => {
return parser.parse(content, options)
},
(adapter, result) => {
return parser.serialize(result)
},
(adapter, node, iterator, it) => {
if (Array.isArray(node.childNodes)) {
let i, child
for (i = 0; i < node.childNodes.length; i++) {
child = node.childNodes[i]
const res = iterator(child, i)
if (res === false) {
break
}
// recurse
it(adapter, child, iterator, it)
}
}
},
file.content,
decorate
)
file.ast.html = ast
file.seal = ast.getSeal()
decorate(ast)
}
static get test () {
return /\.(sgr|jade|ejs|html)$/
}
static get exclude () {
return [/google[a-z0-9]+\.html$/i]
}
}
module.exports = ParseHtml