11
11
12
12
/* eslint-env commonjs */
13
13
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
+
14
84
/**
15
85
* Test.
16
86
*
17
- * @typedef {Function } findBefore ~test
87
+ * @typedef {Function } is ~test
18
88
* @param {Node } node - Node to test.
19
89
* @param {number } index - Position of `node` in `parent`.
20
90
* @param {Node } parent - Parent of `node`.
21
91
* @return {boolean? } - Whether this iteration passes.
22
92
*/
23
93
24
94
/**
25
- * Utility to return true for the first node .
95
+ * Utility to return true.
26
96
*
27
- * @type {findBefore ~test }
97
+ * @type {is ~test }
28
98
*/
29
99
function first ( ) {
30
100
return true ;
@@ -35,7 +105,7 @@ function first() {
35
105
* a given node’s type for said string.
36
106
*
37
107
* @param {string } test - Node type to test.
38
- * @return {findBefore ~test } - Tester.
108
+ * @return {is ~test } - Tester.
39
109
*/
40
110
function typeFactory ( test ) {
41
111
return function ( node ) {
@@ -48,47 +118,58 @@ function typeFactory(test) {
48
118
* a given node for strict equality.
49
119
*
50
120
* @param {Node } test - Node to test.
51
- * @return {findBefore ~test } - Tester.
121
+ * @return {is ~test } - Tester.
52
122
*/
53
123
function nodeFactory ( test ) {
54
124
return function ( node ) {
55
- return Boolean ( node && node === test ) ;
125
+ return node === test ;
56
126
}
57
127
}
58
128
59
129
/**
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
62
132
*
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.
69
169
*/
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 ;
92
173
93
174
if ( typeof test === 'string' ) {
94
175
test = typeFactory ( test ) ;
@@ -100,22 +181,33 @@ function findBefore(parent, index, test) {
100
181
throw new Error ( 'Expected function, string, or node as test' ) ;
101
182
}
102
183
103
- while ( index -- ) {
104
- child = children [ index ] ;
184
+ if ( ! node || ! node . type ) {
185
+ throw new Error ( 'Expected node' ) ;
186
+ }
105
187
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' ) ;
109
193
}
110
194
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 ) ) ;
112
204
}
113
205
114
206
/*
115
207
* Expose.
116
208
*/
117
209
118
- module . exports = findBefore ;
210
+ module . exports = is ;
119
211
120
212
} , { } ] } , { } , [ 1 ] ) ( 1 )
121
213
} ) ;
0 commit comments