Skip to content

Instantly share code, notes, and snippets.

@mattfysh
Created October 8, 2022 01:44
Show Gist options
  • Save mattfysh/92e160e5f2a4cf7d569f3c2bf012c217 to your computer and use it in GitHub Desktop.
Save mattfysh/92e160e5f2a4cf7d569f3c2bf012c217 to your computer and use it in GitHub Desktop.
xpath compatibility with parse5 and htmlparser2 tree
import { parse } from 'parse5'
import { adapter } from 'parse5-htmlparser2-tree-adapter'
import xpath from 'xpath'
const html = '...'
const selector = '...'
const doc = parse(html, { treeAdapter: adapter })
const htmlEl = doc.childNodes.find(c => c.name === 'html')
const result = xpath.select1(selector, htmlEl)
import { compareDocumentPosition } from 'domutils'
import ds from 'dom-serializer'
import { Node, Element, AnyNode } from 'domhandler'
;(Node.prototype as any).compareDocumentPosition = function (other: AnyNode) {
return compareDocumentPosition(this, other)
}
Element.prototype.toString = function () {
return ds(this)
}
Object.defineProperty(Node.prototype, 'nodeName', {
get: function () {
return this.name
},
})
Object.defineProperty(Node.prototype, 'localName', {
get: function () {
return this.name
},
})
const origAttributes = Object.getOwnPropertyDescriptor(
Element.prototype,
'attributes'
)?.get
if (origAttributes) {
Object.defineProperty(Element.prototype, 'attributes', {
get: function (...args) {
// eslint-disable-next-line prefer-rest-params
const attrs = origAttributes.call(this, ...args)
attrs.item = (idx: number) => {
const el = attrs[idx]
return { ...el, nodeType: 2, localName: el.name }
}
return attrs
},
})
} else {
console.warn(
'[WARN] Unable to patch DOM: Element.attributes property descriptor not found'
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment