UNPKG

1.15 kBJavaScriptView Raw
1import { blank } from '../utils/object';
2
3let shouldSkip;
4let shouldAbort;
5
6export default function walk ( ast, { enter, leave }) {
7 shouldAbort = false;
8 visit( ast, null, enter, leave );
9}
10
11let context = {
12 skip: () => shouldSkip = true,
13 abort: () => shouldAbort = true
14};
15
16let childKeys = blank();
17
18let toString = Object.prototype.toString;
19
20function isArray ( thing ) {
21 return toString.call( thing ) === '[object Array]';
22}
23
24function visit ( node, parent, enter, leave ) {
25 if ( !node || shouldAbort ) return;
26
27 if ( enter ) {
28 shouldSkip = false;
29 enter.call( context, node, parent );
30 if ( shouldSkip || shouldAbort ) return;
31 }
32
33 let keys = childKeys[ node.type ] || (
34 childKeys[ node.type ] = Object.keys( node ).filter( key => typeof node[ key ] === 'object' )
35 );
36
37 let key, value, i, j;
38
39 i = keys.length;
40 while ( i-- ) {
41 key = keys[i];
42 value = node[ key ];
43
44 if ( isArray( value ) ) {
45 j = value.length;
46 while ( j-- ) {
47 visit( value[j], node, enter, leave );
48 }
49 }
50
51 else if ( value && value.type ) {
52 visit( value, node, enter, leave );
53 }
54 }
55
56 if ( leave && !shouldAbort ) {
57 leave( node, parent );
58 }
59}