@@ -3,8 +3,6 @@ package GoHtml
33import (
44 "iter"
55 "strings"
6-
7- "github.com/emirpasic/gods/stacks/linkedliststack"
86)
97
108// GetElementByTagName returns the first node that match with the given tagName by advancing from the node.
@@ -136,75 +134,32 @@ func (node *Node) QueryAll(query string) NodeList {
136134QuerySearch tokenizes the query string and search for nodes that matches with the right most query token. After matching right most query it proceeds to match nodes parents nodes for left over tokens and then passed that node to (yield/range). QuerySearch search the whole node tree for matches unless yield get canceled or range iterator get cancel.
137135*/
138136func QuerySearch (node * Node , query string ) iter.Seq [* Node ] {
137+ traverser := NewTraverser (node )
139138 return func (yield func (node * Node ) bool ) {
140139 queryTokens := TokenizeQuery (query )
141-
142- parentNodeStack := make ([]* Node , 0 , 2 )
143- stack := linkedliststack .New ()
144- type stackFrame struct {
145- //len should contain the length of the parentNodeStack at the stack push time.
146- len int
147- node * Node
148- }
149- stack .Push (stackFrame {
150- len : len (parentNodeStack ),
151- node : node ,
152- })
153-
154- for stack .Size () > 0 {
155- val , _ := stack .Pop ()
156- sf := val .(stackFrame )
157-
158- if sf .len <= len (parentNodeStack ) {
159- parentNodeStack = parentNodeStack [:sf .len ]
140+ iter := traverser .Walkthrough
141+ for node := range iter {
142+ i := matchFromRightMostQueryToken (node , queryTokens , len (queryTokens )- 1 )
143+ if i == len (queryTokens )- 1 {
144+ continue
160145 }
161-
162- classList := NewClassList ()
163- classList .DecodeFrom (sf .node )
164- i := matchFromRightMostQueryToken (sf .node , classList , queryTokens , len (queryTokens )- 1 )
165- if i < len (queryTokens )- 1 {
166- for j := len (parentNodeStack ) - 1 ; j >= 0 && i >= 0 ; j -- {
167- node := parentNodeStack [j ]
168- classList := NewClassList ()
169- classList .DecodeFrom (node )
170- i = matchFromRightMostQueryToken (node , classList , queryTokens , i - 1 )
171- }
172-
173- if i < 0 && ! yield (sf .node ) {
174- return
175- }
176- }
177-
178- if sf .node .GetNextNode () != nil {
179- stack .Push (stackFrame {
180- len : len (parentNodeStack ),
181- node : sf .node .GetNextNode (),
182- })
146+ parentNode := node .GetParent ()
147+ for parentNode != nil && i >= 0 {
148+ i = matchFromRightMostQueryToken (parentNode , queryTokens , i )
149+ parentNode = parentNode .GetParent ()
183150 }
184-
185- if sf .node .GetChildNode () != nil {
186- childNode := sf .node .GetChildNode ()
187- parentNodeStack = append (parentNodeStack , sf .node )
188- stack .Push (stackFrame {
189- len : len (parentNodeStack ),
190- node : childNode ,
191- })
151+ if i < 0 && ! yield (node ){
152+ return
192153 }
193154 }
194- }
195- }
196155
197- func pop (slice []* Node ) (* Node , []* Node ) {
198- if len (slice ) > 0 {
199- res := slice [len (slice )- 1 ]
200- slice = slice [:len (slice )- 1 ]
201- return res , slice
202156 }
203- return nil , slice
204157}
205158
206159// matchFromRightMostQueryToken tries to match query tokens from right to left and return the index at which point query token last matched.
207- func matchFromRightMostQueryToken (node * Node , classList ClassList , queryTokens []QueryToken , i int ) int {
160+ func matchFromRightMostQueryToken (node * Node , queryTokens []QueryToken , i int ) int {
161+ classList := NewClassList ()
162+ classList .DecodeFrom (node )
208163 checked := make (map [string ]struct {})
209164outer:
210165 for i >= 0 {
0 commit comments