1111
1212/* eslint-env commonjs */
1313
14+ /*
15+ * Dependencies.
16+ */
17+
18+ var is = require ( 'unist-util-is' ) ;
19+
20+ /**
21+ * Find a node before `index` in `parent` which passes
22+ * `test`.
23+ *
24+ * @param {Node } parent - Parent to search in.
25+ * @param {number|Node } index - (Position of) node to
26+ * search before.
27+ * @param {* } test - See `wooorm/unist-util-is`.
28+ * @return {Node? } - A child node of `parent` which passes
29+ * `test`.
30+ */
31+ function findBefore ( parent , index , test ) {
32+ var children ;
33+ var child ;
34+
35+ if ( ! parent || ! parent . type || ! parent . children ) {
36+ throw new Error ( 'Expected parent node' ) ;
37+ }
38+
39+ children = parent . children ;
40+
41+ if ( index && index . type ) {
42+ index = children . indexOf ( index ) ;
43+ }
44+
45+ if ( isNaN ( index ) || index < 0 || index === Infinity ) {
46+ throw new Error ( 'Expected positive finite index or child node' ) ;
47+ }
48+
49+ /* Performance. */
50+ if ( index > children . length ) {
51+ index = children . length ;
52+ }
53+
54+ while ( index -- ) {
55+ child = children [ index ] ;
56+
57+ if ( is ( test , child , index , parent ) ) {
58+ return child ;
59+ }
60+ }
61+
62+ return null ;
63+ }
64+
65+ /*
66+ * Expose.
67+ */
68+
69+ module . exports = findBefore ;
70+
71+ } , { "unist-util-is" :2 } ] , 2 :[ function ( require , module , exports ) {
72+ /**
73+ * @author Titus Wormer
74+ * @copyright 2015 Titus Wormer
75+ * @license MIT
76+ * @module unist:util:is
77+ * @fileoverview Utility to check if a node passes a test.
78+ */
79+
80+ 'use strict' ;
81+
82+ /* eslint-env commonjs */
83+
1484/**
1585 * Test.
1686 *
17- * @typedef {Function } findBefore ~test
87+ * @typedef {Function } is ~test
1888 * @param {Node } node - Node to test.
1989 * @param {number } index - Position of `node` in `parent`.
2090 * @param {Node } parent - Parent of `node`.
2191 * @return {boolean? } - Whether this iteration passes.
2292 */
2393
2494/**
25- * Utility to return true for the first node .
95+ * Utility to return true.
2696 *
27- * @type {findBefore ~test }
97+ * @type {is ~test }
2898 */
2999function first ( ) {
30100 return true ;
@@ -35,7 +105,7 @@ function first() {
35105 * a given node’s type for said string.
36106 *
37107 * @param {string } test - Node type to test.
38- * @return {findBefore ~test } - Tester.
108+ * @return {is ~test } - Tester.
39109 */
40110function typeFactory ( test ) {
41111 return function ( node ) {
@@ -48,47 +118,58 @@ function typeFactory(test) {
48118 * a given node for strict equality.
49119 *
50120 * @param {Node } test - Node to test.
51- * @return {findBefore ~test } - Tester.
121+ * @return {is ~test } - Tester.
52122 */
53123function nodeFactory ( test ) {
54124 return function ( node ) {
55- return Boolean ( node && node === test ) ;
125+ return node === test ;
56126 }
57127}
58128
59129/**
60- * Find a node before `index` in `parent` which passes
61- * `test`.
130+ * Assert if `test` passes for `node`.
131+ * When a `parent` node is known the `index` of node
62132 *
63- * @param {Node } parent - Parent to search in.
64- * @param {number|Node } index - (Position of) node to
65- * search before.
66- * @param {string|Node|findBefore~test } test - Tester.
67- * @return {Node? } - A child node of `parent` which passes
68- * `test`.
133+ * @example
134+ * is(null, {type: 'strong'}); // true
135+ *
136+ * @example
137+ * is('strong', {type: 'strong'}); // true
138+ * is('emphasis', {type: 'strong'}); // false
139+ *
140+ * @example
141+ * var node = {type: 'strong'};
142+ * is(node, node) // true
143+ * is(node, {type: 'strong'}) // false
144+ *
145+ * @example
146+ * var node = {type: 'strong'};
147+ * var parent = {type: 'paragraph', children: [node]};
148+ * function test(node, n) {return n === 5};
149+ * is(test, {type: 'strong'}); // false
150+ * is(test, {type: 'strong'}, 4, parent); // false
151+ * is(test, {type: 'strong'}, 5, parent); // true
152+ *
153+ * @example
154+ * var node = {type: 'strong'};
155+ * var parent = {type: 'paragraph', children: [node]};
156+ * is('strong'); // throws
157+ * is('strong', node, 0) // throws
158+ * is('strong', node, null, parent) // throws
159+ * is('strong', node, 0, {type: 'paragraph'}) // throws
160+ * is('strong', node, -1, parent) // throws
161+ * is('strong', node, Infinity, parent) // throws
162+ *
163+ * @param {(string|Node|is~test)? } test - Tester.
164+ * @param {Node } node - Node to test.
165+ * @param {number? } [index] - Position of `node` in `parent`.
166+ * @param {Node? } [parent] - Parent of `node`.
167+ * @param {* } [context] - Context to invoke `test` with.
168+ * @return {boolean } - Whether `test` passes.
69169 */
70- function findBefore ( parent , index , test ) {
71- var children ;
72- var child ;
73-
74- if ( ! parent || ! parent . type || ! parent . children ) {
75- throw new Error ( 'Expected parent node' ) ;
76- }
77-
78- children = parent . children ;
79-
80- if ( index && index . type ) {
81- index = children . indexOf ( index ) ;
82- }
83-
84- if ( isNaN ( index ) || index < 0 || index === Infinity ) {
85- throw new Error ( 'Expected positive finite index or child node' ) ;
86- }
87-
88- /* Performance. */
89- if ( index > children . length ) {
90- index = children . length ;
91- }
170+ function is ( test , node , index , parent , context ) {
171+ var hasParent = parent !== null && parent !== undefined ;
172+ var hasIndex = index !== null && index !== undefined ;
92173
93174 if ( typeof test === 'string' ) {
94175 test = typeFactory ( test ) ;
@@ -100,22 +181,33 @@ function findBefore(parent, index, test) {
100181 throw new Error ( 'Expected function, string, or node as test' ) ;
101182 }
102183
103- while ( index -- ) {
104- child = children [ index ] ;
184+ if ( ! node || ! node . type ) {
185+ throw new Error ( 'Expected node' ) ;
186+ }
105187
106- if ( test ( child , index , parent ) ) {
107- return child ;
108- }
188+ if (
189+ hasIndex &&
190+ ( typeof index !== 'number' || index < 0 || index === Infinity )
191+ ) {
192+ throw new Error ( 'Expected positive finite index or child node' ) ;
109193 }
110194
111- return null ;
195+ if ( hasParent && ( ! parent || ! parent . type || ! parent . children ) ) {
196+ throw new Error ( 'Expected parent node' ) ;
197+ }
198+
199+ if ( hasParent !== hasIndex ) {
200+ throw new Error ( 'Expected both parent and index' ) ;
201+ }
202+
203+ return Boolean ( test . call ( context , node , index , parent ) ) ;
112204}
113205
114206/*
115207 * Expose.
116208 */
117209
118- module . exports = findBefore ;
210+ module . exports = is ;
119211
120212} , { } ] } , { } , [ 1 ] ) ( 1 )
121213} ) ;
0 commit comments