summaryrefslogtreecommitdiff
path: root/node_modules/posthtml/lib/api.js
diff options
context:
space:
mode:
authorShipwreckt <me@shipwreckt.co.uk>2025-10-31 20:02:14 +0000
committerShipwreckt <me@shipwreckt.co.uk>2025-10-31 20:02:14 +0000
commit7a52ddeba2a68388b544f529d2d92104420f77b0 (patch)
tree15ddd47457a2cb4a96060747437d36474e4f6b4e /node_modules/posthtml/lib/api.js
parent53d6ae2b5568437afa5e4995580a3fb679b7b91b (diff)
Changed from static to 11ty!
Diffstat (limited to 'node_modules/posthtml/lib/api.js')
-rw-r--r--node_modules/posthtml/lib/api.js145
1 files changed, 145 insertions, 0 deletions
diff --git a/node_modules/posthtml/lib/api.js b/node_modules/posthtml/lib/api.js
new file mode 100644
index 0000000..e929cfb
--- /dev/null
+++ b/node_modules/posthtml/lib/api.js
@@ -0,0 +1,145 @@
+'use strict'
+
+/**
+ * # API
+ *
+ * @author Ivan Voischev (@voischev),
+ * Anton Winogradov (@awinogradov),
+ * Alexej Yaroshevich (@zxqfox),
+ * Vasiliy (@Yeti-or)
+ *
+ * @namespace tree
+ */
+function Api () {
+ this.walk = walk
+ this.match = match
+}
+
+/**
+ * Walks the tree and passes all nodes via a callback
+ *
+ * @memberof tree
+ *
+ * @param {Function} cb Callback
+ * @return {Function} Callback(node)
+ *
+ *@example
+ * ```js
+ * export const walk = (tree) => {
+ * tree.walk((node) => {
+ * let classes = node.attrs && node.attrs.class.split(' ') || []
+ *
+ * if (classes.includes(className)) return cb(node)
+ * return node
+ * })
+ * }
+ * ```
+ */
+function walk (cb) {
+ return traverse(this, cb)
+}
+
+/**
+ * Matches an expression to search for nodes in the tree
+ *
+ * @memberof tree
+ *
+ * @param {String|RegExp|Object|Array} expression - Matcher(s) to search
+ * @param {Function} cb Callback
+ *
+ * @return {Function} Callback(node)
+ *
+ * @example
+ * ```js
+ * export const match = (tree) => {
+ * // Single matcher
+ * tree.match({ tag: 'custom-tag' }, (node) => {
+ * let tag = node.tag
+ *
+ * Object.assign(node, { tag: 'div', attrs: {class: tag} })
+ *
+ * return node
+ * })
+ * // Multiple matchers
+ * tree.match([{ tag: 'b' }, { tag: 'strong' }], (node) => {
+ * let style = 'font-weight: bold;'
+ *
+ * node.tag = 'span'
+ *
+ * node.attrs
+ * ? ( node.attrs.style
+ * ? ( node.attrs.style += style )
+ * : node.attrs.style = style
+ * )
+ * : node.attrs = { style: style }
+ *
+ * return node
+ * })
+ * }
+ * ```
+ */
+function match (expression, cb) {
+ return Array.isArray(expression)
+ ? traverse(this, node => {
+ for (let i = 0; i < expression.length; i++) {
+ if (compare(expression[i], node)) return cb(node)
+ }
+
+ return node
+ })
+ : traverse(this, node => {
+ if (compare(expression, node)) return cb(node)
+
+ return node
+ })
+}
+
+module.exports = Api
+module.exports.match = match
+module.exports.walk = walk
+
+/** @private */
+function traverse (tree, cb) {
+ if (Array.isArray(tree)) {
+ for (let i = 0; i < tree.length; i++) {
+ tree[i] = traverse(cb(tree[i]), cb)
+ }
+ } else if (
+ tree &&
+ typeof tree === 'object' &&
+ Object.prototype.hasOwnProperty.call(tree, 'content')
+ ) traverse(tree.content, cb)
+
+ return tree
+}
+
+/** @private */
+function compare (expected, actual) {
+ if (expected instanceof RegExp) {
+ if (typeof actual === 'object') return false
+ if (typeof actual === 'string') return expected.test(actual)
+ }
+
+ if (typeof expected !== typeof actual) return false
+ if (typeof expected !== 'object' || expected === null) {
+ return expected === actual
+ }
+
+ if (Array.isArray(expected)) {
+ return expected.every(exp => [].some.call(actual, act => compare(exp, act)))
+ }
+
+ return Object.keys(expected).every(key => {
+ const ao = actual[key]
+ const eo = expected[key]
+
+ if (typeof eo === 'object' && eo !== null && ao !== null) {
+ return compare(eo, ao)
+ }
+ if (typeof eo === 'boolean') {
+ return eo !== (ao == null)
+ }
+
+ return ao === eo
+ })
+}