mirror of
https://github.com/PuerkitoBio/goquery.git
synced 2026-10-19 16:15:33 +00:00
cleanup: extract cachedParse helper for parse-result reuse
WrapHtml, WrapInnerHtml, and eachNodeHtml each open-coded the same lookup-or-parse-and-store sequence against a map[string][]*html.Node keyed by the context node's name. Extract that 4-line sequence into a tiny cachedParseHtmlWithContext(cache, htmlStr, context) helper; each call site becomes a linear, closure-free loop and the only duplicated bit (the cache lookup) lives in one place.
This commit is contained in:
+29
-30
@@ -382,20 +382,14 @@ func (s *Selection) WrapSelection(sel *Selection) *Selection {
|
||||
//
|
||||
// It returns the original set of elements.
|
||||
func (s *Selection) WrapHtml(htmlStr string) *Selection {
|
||||
nodesMap := make(map[string][]*html.Node)
|
||||
for _, context := range s.Nodes {
|
||||
var parent *html.Node
|
||||
if context.Parent != nil {
|
||||
parent = context.Parent
|
||||
} else {
|
||||
cache := make(map[string][]*html.Node)
|
||||
for _, n := range s.Nodes {
|
||||
parent := n.Parent
|
||||
if parent == nil {
|
||||
parent = &html.Node{Type: html.ElementNode}
|
||||
}
|
||||
nodes, found := nodesMap[nodeName(parent)]
|
||||
if !found {
|
||||
nodes = parseHtmlWithContext(htmlStr, parent)
|
||||
nodesMap[nodeName(parent)] = nodes
|
||||
}
|
||||
newSingleSelection(context, s.document).wrapAllNodes(cloneNodes(nodes)...)
|
||||
nodes := cachedParseHtmlWithContext(cache, htmlStr, parent)
|
||||
newSingleSelection(n, s.document).wrapAllNodes(cloneNodes(nodes)...)
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -530,14 +524,10 @@ func (s *Selection) WrapInnerSelection(sel *Selection) *Selection {
|
||||
//
|
||||
// It returns the original set of elements.
|
||||
func (s *Selection) WrapInnerHtml(htmlStr string) *Selection {
|
||||
nodesMap := make(map[string][]*html.Node)
|
||||
for _, context := range s.Nodes {
|
||||
nodes, found := nodesMap[nodeName(context)]
|
||||
if !found {
|
||||
nodes = parseHtmlWithContext(htmlStr, context)
|
||||
nodesMap[nodeName(context)] = nodes
|
||||
}
|
||||
newSingleSelection(context, s.document).wrapInnerNodes(cloneNodes(nodes)...)
|
||||
cache := make(map[string][]*html.Node)
|
||||
for _, n := range s.Nodes {
|
||||
nodes := cachedParseHtmlWithContext(cache, htmlStr, n)
|
||||
newSingleSelection(n, s.document).wrapInnerNodes(cloneNodes(nodes)...)
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -662,10 +652,9 @@ func (s *Selection) manipulateNodes(ns []*html.Node, reverse bool,
|
||||
// isParent can be used to indicate that the elements of the selection should be treated as the parent for the parsed html.
|
||||
// A cache is used to avoid parsing the html multiple times should the elements of the selection result in the same context.
|
||||
func (s *Selection) eachNodeHtml(htmlStr string, isParent bool, mergeFn func(n *html.Node, nodes []*html.Node)) *Selection {
|
||||
// cache to avoid parsing the html for the same context multiple times
|
||||
nodeCache := make(map[string][]*html.Node)
|
||||
var context *html.Node
|
||||
cache := make(map[string][]*html.Node)
|
||||
for _, n := range s.Nodes {
|
||||
var context *html.Node
|
||||
if isParent {
|
||||
context = n.Parent
|
||||
} else {
|
||||
@@ -674,14 +663,24 @@ func (s *Selection) eachNodeHtml(htmlStr string, isParent bool, mergeFn func(n *
|
||||
}
|
||||
context = n
|
||||
}
|
||||
if context != nil {
|
||||
nodes, found := nodeCache[nodeName(context)]
|
||||
if !found {
|
||||
nodes = parseHtmlWithContext(htmlStr, context)
|
||||
nodeCache[nodeName(context)] = nodes
|
||||
}
|
||||
mergeFn(n, cloneNodes(nodes))
|
||||
if context == nil {
|
||||
continue
|
||||
}
|
||||
nodes := cachedParseHtmlWithContext(cache, htmlStr, context)
|
||||
mergeFn(n, cloneNodes(nodes))
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// cachedParseHtmlWithContext returns parseHtmlWithContext(htmlStr, context), reusing a prior
|
||||
// result when context's nodeName has already been seen. Callers pass their own
|
||||
// cache map so the cache lifetime matches the caller's loop scope.
|
||||
func cachedParseHtmlWithContext(cache map[string][]*html.Node, htmlStr string, context *html.Node) []*html.Node {
|
||||
key := nodeName(context)
|
||||
if nodes, ok := cache[key]; ok {
|
||||
return nodes
|
||||
}
|
||||
nodes := parseHtmlWithContext(htmlStr, context)
|
||||
cache[key] = nodes
|
||||
return nodes
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user