'use strict' module.exports = visitParents var convert = require('unist-util-is/convert') var CONTINUE = true var SKIP = 'skip' var EXIT = false visitParents.CONTINUE = CONTINUE visitParents.SKIP = SKIP visitParents.EXIT = EXIT function visitParents(tree, test, visitor, reverse) { var is if (typeof test === 'function' && typeof visitor !== 'function') { reverse = visitor visitor = test test = null } is = convert(test) one(tree, null, []) // Visit a single node. function one(node, index, parents) { var result = [] var subresult if (!test || is(node, index, parents[parents.length - 1] || null)) { result = toResult(visitor(node, parents)) if (result[0] === EXIT) { return result } } if (node.children && result[0] !== SKIP) { subresult = toResult(all(node.children, parents.concat(node))) return subresult[0] === EXIT ? subresult : result } return result } // Visit children in `parent`. function all(children, parents) { var min = -1 var step = reverse ? -1 : 1 var index = (reverse ? children.length : min) + step var result while (index > min && index < children.length) { result = one(children[index], index, parents) if (result[0] === EXIT) { return result } index = typeof result[1] === 'number' ? result[1] : index + step } } } function toResult(value) { if (value !== null && typeof value === 'object' && 'length' in value) { return value } if (typeof value === 'number') { return [CONTINUE, value] } return [value] }