124aa3c4 by Adam Heath

Add a 'contains' pseudo-class, used to match against text children of a

node.
1 parent ea13aa94
......@@ -96,6 +96,14 @@ const compileMatcher = (ast: AST, selector: string): MatcherProducer => {
}
}
const getNodeText = (node) => {
if (node.type === TEXT_NODE) return node.value
if (node.type !== ELEMENT_NODE) return ''
const { children } = node
if (children.length === 0) return ''
return children.map(getNodeText).join('')
}
const getAttrValueMatch = (value: string, operator: string = '=', caseSensitive: boolean): AttrValueMatch => {
if (value === undefined) return (attrValue) => attrValue !== undefined
if (value[ 0 ] === '"' || value[ 0 ] === '\'') value = value.substring(1, value.length - 1)
......@@ -267,6 +275,13 @@ const compileMatcher = (ast: AST, selector: string): MatcherProducer => {
return nthChildMatcher(context, node, parent, pos + 1, debug || parent?.name === 'body')
}
}
case 'contains': {
const contentValueMatch = getAttrValueMatch(ast.argument, '*=', false)
return (context, node, parent, i, debug) => {
const nodeText = getNodeText(node)
return contentValueMatch(nodeText)
}
}
default:
console.error('pseudo-class', nodeUtil.inspect({ selector, ast }, { depth: null, colors: true }))
throw new Error(`Unknown pseudo-class: ${ast.name}`)
......