@@ -65,9 +65,7 @@ function child(query, node, index, parent, state) {
6565 return
6666 }
6767
68- walkIterator ( query , node , state )
69- . each ( )
70- . done ( )
68+ indexedSearch ( query , node , state )
7169}
7270
7371function nextSibling ( query , node , index , parent , state ) {
@@ -76,11 +74,7 @@ function nextSibling(query, node, index, parent, state) {
7674 return
7775 }
7876
79- walkIterator ( query , parent , state )
80- . prefillTypeIndex ( 0 , ++ index )
81- . each ( index , ++ index )
82- . prefillTypeIndex ( index )
83- . done ( )
77+ indexedSearch ( query , parent , state , index + 1 , true )
8478}
8579
8680function subsequentSibling ( query , node , index , parent , state ) {
@@ -89,132 +83,116 @@ function subsequentSibling(query, node, index, parent, state) {
8983 return
9084 }
9185
92- walkIterator ( query , parent , state )
93- . prefillTypeIndex ( 0 , ++ index )
94- . each ( index )
95- . done ( )
86+ indexedSearch ( query , parent , state , index + 1 )
9687}
9788
9889// Handles `typeIndex` and `typeCount` properties for every walker.
99- function walkIterator ( query , parent , state ) {
100- var nodes = parent . children
101- var typeIndex = state . index ? createTypeIndex ( ) : null
90+ function indexedSearch ( query , parent , state , from , firstElementOnly ) {
91+ var needsIndex = state . index
92+ var children = parent . children
93+ var length = children . length
10294 var delayed = [ ]
103-
104- return {
105- prefillTypeIndex : rangeDefaults ( prefillTypeIndex ) ,
106- each : rangeDefaults ( each ) ,
107- done : done
95+ var index = 0
96+ var types = { }
97+ var elements = 0
98+ var handle = needsIndex ? delay : add
99+ var child
100+
101+ // Start looking at `from`
102+ if ( from === undefined ) {
103+ from = 0
108104 }
109105
110- function done ( ) {
111- var length = delayed . length
112- var index = - 1
106+ // Exit if there are no further nodes.
107+ if ( from >= length ) {
108+ return
109+ }
113110
114- while ( ++ index < length ) {
115- delayed [ index ] ( )
111+ // If we need to index for types, do so for all elements before `from`.
112+ if ( needsIndex ) {
113+ while ( index < from ) {
114+ child = children [ index ]
116115
117- if ( state . one && state . found ) {
118- break
116+ if ( child . type === 'element' ) {
117+ count ( child . tagName )
119118 }
120- }
121119
122- return this
123- }
124-
125- function prefillTypeIndex ( start , end ) {
126- if ( typeIndex ) {
127- while ( start < end ) {
128- typeIndex ( nodes [ start ] )
129- start ++
130- }
120+ index ++
131121 }
132-
133- return this
134122 }
135123
136- function each ( start , end ) {
137- var child = nodes [ start ]
138- var index
139- var elementIndex
140-
141- if ( start >= end ) {
142- return this
143- }
124+ index = from
144125
145- if ( typeIndex ) {
146- elementIndex = typeIndex . elements
147- index = typeIndex ( child )
148- delayed . push ( delay )
149- } else {
150- pushNode ( )
151- }
126+ while ( index < length ) {
127+ child = children [ index ]
152128
153- // Stop if we’re looking for one node and it’s already found .
154- if ( state . one && state . found ) {
155- return this
156- }
129+ // Only check elements .
130+ // Check either all elements, or only check the first sibling
131+ if ( child . type === 'element' ) {
132+ handle ( child , index )
157133
158- return each . call ( this , start + 1 , end )
134+ // Stop if we’re looking for one node and it’s already found.
135+ if ( state . one && state . found ) {
136+ return
137+ }
159138
160- function delay ( ) {
161- state . typeIndex = index
162- state . elementIndex = elementIndex
163- state . typeCount = typeIndex . count ( child )
164- state . elementCount = typeIndex . elements
165- pushNode ( )
139+ if ( firstElementOnly ) {
140+ break
141+ }
166142 }
167143
168- function pushNode ( ) {
169- var exit = enter ( state , child )
170- state . iterator ( query , child , start , parent , state )
171- exit ( )
172- }
144+ index ++
173145 }
174146
175- function rangeDefaults ( iterator ) {
176- return rangeDefault
147+ if ( needsIndex ) {
148+ index = - 1
149+ length = delayed . length
177150
178- function rangeDefault ( start , end ) {
179- if ( start === null || start === undefined || start < 0 ) {
180- start = 0
181- }
151+ while ( ++ index < length ) {
152+ delayed [ index ] ( )
182153
183- if ( end === null || end === undefined || end > nodes . length ) {
184- end = nodes . length
154+ // Stop if we’re looking for one node and it’s already found.
155+ if ( state . one && state . found ) {
156+ // To do: maybe return?
157+ return
185158 }
186-
187- return iterator . call ( this , start , end )
188159 }
189160 }
190- }
191-
192- function createTypeIndex ( ) {
193- var counts = { }
194161
195- index . count = count
196- index . elements = 0
162+ function delay ( node , childIndex ) {
163+ var name = node . tagName
164+ var elementsBefore = elements
165+ var elementsByTypeBefore = own . call ( types , name ) ? types [ name ] : 0
197166
198- return index
167+ count ( name )
199168
200- function index ( node ) {
201- var type = node . tagName
169+ delayed . push ( fn )
202170
203- if ( ! type ) {
204- return 0
205- }
171+ function fn ( ) {
172+ // Before counting further elements:
173+ state . elementIndex = elementsBefore
174+ state . typeIndex = elementsByTypeBefore
206175
207- index . elements ++
176+ // After counting all elements.
177+ state . elementCount = elements
178+ state . typeCount = types [ name ]
208179
209- if ( ! own . call ( counts , type ) ) {
210- counts [ type ] = 0
180+ add ( node , childIndex )
211181 }
182+ }
212183
213- // Note: ++ needs is intended to be postfixed!
214- return counts [ type ] ++
184+ function add ( node , childIndex ) {
185+ var exit = enter ( state , node )
186+ state . iterator ( query , node , childIndex , parent , state )
187+ exit ( )
215188 }
216189
217- function count ( node ) {
218- return own . call ( counts , node . tagName ) ? counts [ node . tagName ] : 0
190+ function count ( name ) {
191+ if ( ! own . call ( types , name ) ) {
192+ types [ name ] = 0
193+ }
194+
195+ elements ++
196+ types [ name ] ++
219197 }
220198}
0 commit comments