Query XPath

Developer tools have nice helpers – $x (Firefox) and $x (Chrome) – but DOM interface is archaic:

nodes = document.evaluate('(//text())[last()]', document)
// XPathResult
for (let node of nodes) {}
Uncaught TypeError: nodes is not iterable
[...nodes]
Uncaught TypeError: object is not iterable
 (cannot read property Symbol(Symbol.iterator))

Bring it to modern era with iterator:

XPathResult.prototype[Symbol.iterator] = function *() {
  let next;
  while (next = this.iterateNext()) {
    yield next;
  }
}
for (let node of nodes) {}
[...nodes].forEach

Align with query selector API:

document.propertyOwner('querySelectorAll')
// Document {…}
document.documentElement.propertyOwner('querySelectorAll')
// Element {…}
Document.prototype.queryXPathAll = function(expression, ...args) {
  this.evaluate(expression, this, args)
}
Element.prototype.queryXPathAll = function(expression, ...args) {
  this.ownerDocument.evaluate(expression, this, args)
}

(Document.prototype has a separate function because document.ownerDocument !== document)