Anakunda / XPathLib

// ==UserScript==
// ==UserLibrary==
// @name         XPathLib
// @namespace    https://openuserjs.org/users/Anakunda
// @version      1.3
// @author       Anakunda
// @license      GPL-3.0-or-later
// @copyright    2021, Anakunda (https://openuserjs.org/users/Anakunda)
// @exclude      *
// ==/UserScript==
// ==/UserLibrary==

function evaluate(xpath, resultType = XPathResult.FIRST_ORDERED_NODE_TYPE, root = document, context = root.body) {
  return root.evaluate(xpath, context, null, resultType, null);
}

function findNode(xpath, root = document, context = root.body) {
  var result = evaluate(xpath, XPathResult.FIRST_ORDERED_NODE_TYPE, root, context);
  return result.resultType == XPathResult.FIRST_ORDERED_NODE_TYPE ? result.singleNodeValue : null;
}

function findNodes(xpath, root = document, context = root.body) {
  var result = evaluate(xpath, XPathResult.ORDERED_NODE_ITERATOR_TYPE, root, context);
  return result.resultType == XPathResult.ORDERED_NODE_ITERATOR_TYPE ? result : null;
}

function findSnapshot(xpath, root = document, context = root.body) {
  var result = evaluate(xpath, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, root, context);
  return result.resultType == XPathResult.ORDERED_NODE_SNAPSHOT_TYPE ? result : null;
}

function findString(xpath, root = document, context = root.body) {
  var result = evaluate(xpath, XPathResult.STRING_TYPE, root, context);
  return result.resultType == XPathResult.STRING_TYPE ? result.stringValue : null;
}

function findNumber(xpath, root = document, context = root.body) {
  var result = evaluate(xpath, XPathResult.NUMBER_TYPE, root, context);
  return result.resultType == XPathResult.NUMBER_TYPE ? result.numberValue : null;
}

function findBoolean(xpath, root = document, context = root.body) {
  var result = evaluate(xpath, XPathResult.BOOLEAN_TYPE, root, context);
  return result.resultType == XPathResult.BOOLEAN_TYPE ? result.booleanValue : null;
}

function findAny(xpath, root = document, context = root.body) {
  return evaluate(xpath, XPathResult.ANY_TYPE, root, context);
}

Document.prototype.findNode = function(xpath, root = this) {
  var result = this.evaluate(xpath, root, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
  return result.resultType == XPathResult.FIRST_ORDERED_NODE_TYPE ? result.singleNodeValue : null;
};

Document.prototype.findNodes = function(xpath, root = this) {
  var result = this.evaluate(xpath, root, null, XPathResult.ORDERED_NODE_ITERATOR_TYPEORDERED_NODE_ITERATOR_TYPE, null);
  return result.resultType == XPathResult.ORDERED_NODE_ITERATOR_TYPEORDERED_NODE_ITERATOR_TYPE ? result : null;
};

Document.prototype.findSnapshot = function(xpath, root = this) {
  var result = this.evaluate(xpath, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  return result.resultType == XPathResult.ORDERED_NODE_SNAPSHOT_TYPE ? result : null;
};

Document.prototype.findString = function(xpath, root = this) {
  var result = this.evaluate(xpath, root, null, XPathResult.STRING_TYPE, null);
  return result.resultType == XPathResult.STRING_TYPE ? result.stringValue : null;
};

Document.prototype.findNumber = function(xpath, root = this) {
  var result = this.evaluate(xpath, root, null, XPathResult.NUMBER_TYPE, null);
  return result.resultType == XPathResult.NUMBER_TYPE ? result.numberValue : null;
};

Document.prototype.findBoolean = function(xpath, root = null) {
  var result = this.evaluate(xpath, root || this, null, XPathResult.BOOLEAN_TYPE, null);
  return result.resultType == XPathResult.BOOLEAN_TYPE ? result.booleanValue : null;
};

Document.prototype.findAny = function(xpath, root = null) {
  return this.evaluate(xpath, root || this, null, XPathResult.ANY_TYPE, null);
};


//////////////////////////////////////////////////////////////////////////
////////////////////////////// SAFE PADDING //////////////////////////////
//////////////////////////////////////////////////////////////////////////