1+ 'use strict' ;
2+
3+ Object . defineProperty ( exports , "__esModule" , {
4+ value : true
5+ } ) ;
6+ exports . isPromise = undefined ;
7+ exports . default = reactTreeWalker ;
8+
9+ var _react = require ( 'react' ) ;
10+
11+ // Lifted from https://github.com/sindresorhus/p-reduce
12+ // Thanks @sindresorhus !
13+ var pReduce = function pReduce ( iterable , reducer , initVal ) {
14+ return new Promise ( function ( resolve , reject ) {
15+ var iterator = iterable [ Symbol . iterator ] ( ) ;
16+ var i = 0 ;
17+
18+ var next = function next ( total ) {
19+ var el = iterator . next ( ) ;
20+
21+ if ( el . done ) {
22+ resolve ( total ) ;
23+ return ;
24+ }
25+
26+ Promise . all ( [ total , el . value ] ) . then ( function ( value ) {
27+ // eslint-disable-next-line no-plusplus
28+ next ( reducer ( value [ 0 ] , value [ 1 ] , i ++ ) ) ;
29+ } ) . catch ( reject ) ;
30+ } ;
31+
32+ next ( initVal ) ;
33+ } ) ;
34+ } ;
35+
36+ // Lifted from https://github.com/sindresorhus/p-map-series
37+ // Thanks @sindresorhus !
38+ /* eslint-disable no-console */
39+
40+ // Inspired by the awesome work done by the Apollo team.
41+ // See https://github.com/apollostack/react-apollo/blob/master/src/server.ts
42+ // This version has been adapted to be promise based.
43+
44+ // eslint-disable-next-line import/no-extraneous-dependencies
45+ var pMapSeries = function pMapSeries ( iterable , iterator ) {
46+ var ret = [ ] ;
47+
48+ return pReduce ( iterable , function ( a , b , i ) {
49+ return Promise . resolve ( iterator ( b , i ) ) . then ( function ( val ) {
50+ ret . push ( val ) ;
51+ } ) ;
52+ } ) . then ( function ( ) {
53+ return ret ;
54+ } ) ;
55+ } ;
56+
57+ var isPromise = exports . isPromise = function isPromise ( x ) {
58+ return x != null && typeof x . then === 'function' ;
59+ } ;
60+
61+ // Recurse an React Element tree, running visitor on each element.
62+ // If visitor returns `false`, don't call the element's render function
63+ // or recurse into its child elements
64+ function reactTreeWalker ( element , visitor , context ) {
65+ return new Promise ( function ( resolve ) {
66+ var doVisit = function doVisit ( getChildren , visitorResult , childContext , isChildren ) {
67+ var doTraverse = function doTraverse ( shouldContinue ) {
68+ if ( ! shouldContinue ) {
69+ // We recieved a false, which indicates a desire to stop traversal.
70+ resolve ( ) ;
71+ }
72+
73+ var child = getChildren ( ) ;
74+ var theChildContext = typeof childContext === 'function' ? childContext ( ) : childContext ;
75+
76+ if ( child == null ) {
77+ // If no children then we can't traverse. We've reached the leaf.
78+ resolve ( ) ;
79+ } else if ( isChildren ) {
80+ // If its a react Children collection we need to breadth-first
81+ // traverse each of them.
82+ var mapper = function mapper ( aChild ) {
83+ return aChild ? reactTreeWalker ( aChild , visitor , theChildContext ) : undefined ;
84+ } ;
85+ // pMapSeries allows us to do depth-first traversal. Thanks @sindresorhus!
86+ pMapSeries ( _react . Children . map ( child , function ( cur ) {
87+ return cur ;
88+ } ) , mapper ) . then ( resolve ) ;
89+ } else {
90+ // Otherwise we pass the individual child to the next recursion.
91+ reactTreeWalker ( child , visitor , theChildContext ) . then ( resolve ) ;
92+ }
93+ } ;
94+
95+ if ( visitorResult === false ) {
96+ // Visitor returned false, indicating a desire to not traverse.
97+ resolve ( ) ;
98+ } else if ( isPromise ( visitorResult ) ) {
99+ // We need to execute the result and pass it's result through to our
100+ // continuer.
101+ visitorResult . then ( doTraverse ) . catch ( function ( e ) {
102+ console . log ( 'Error occurred in Promise based visitor result provided to react-tree-walker.' ) ;
103+ if ( e ) {
104+ console . log ( e ) ;
105+ if ( e . stack ) {
106+ console . log ( e . stack ) ;
107+ }
108+ }
109+ } ) ;
110+ } else {
111+ doTraverse ( true ) ;
112+ }
113+ } ;
114+
115+ // Is this element a Component?
116+ if ( typeof element . type === 'function' ) {
117+ var Component = element . type ;
118+ var props = Object . assign ( { } , Component . defaultProps , element . props ) ;
119+
120+ // Is this a class component? (http://bit.ly/2j9Ifk3)
121+ var isReactClassComponent = Component . prototype && ( Component . prototype . isReactComponent || Component . prototype . isPureReactComponent ) ;
122+
123+ if ( isReactClassComponent ) {
124+ // React class component
125+
126+ var instance = new Component ( props , context ) ;
127+
128+ // In case the user doesn't pass these to super in the constructor
129+ instance . props = instance . props || props ;
130+ instance . context = instance . context || context ;
131+
132+ // Make the setState synchronous.
133+ instance . setState = function ( newState ) {
134+ instance . state = Object . assign ( { } , instance . state , newState ) ;
135+ } ;
136+
137+ doVisit ( function ( ) {
138+ // Call componentWillMount if it exists.
139+ if ( instance . componentWillMount ) {
140+ instance . componentWillMount ( ) ;
141+ }
142+
143+ return instance . render ( ) ;
144+ } , visitor ( element , instance , context ) , function ( ) {
145+ return (
146+ // Ensure the child context is initialised if it is available. We will
147+ // need to pass it down the tree.
148+ instance . getChildContext ? Object . assign ( { } , context , instance . getChildContext ( ) ) : context
149+ ) ;
150+ } ) ;
151+ } else {
152+ // Stateless Functional Component
153+ doVisit ( function ( ) {
154+ return Component ( props , context ) ;
155+ } , visitor ( element , null , context ) , context ) ;
156+ }
157+ } else {
158+ // This must be a basic element, such as a string or dom node.
159+ doVisit ( function ( ) {
160+ return element . props && element . props . children ? element . props . children : undefined ;
161+ } , visitor ( element , null , context ) , context , true ) ;
162+ }
163+ } ) ;
164+ }
0 commit comments