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:
jvoisin
2026-06-05 22:51:00 +02:00
parent 88920eaad4
commit a7a9c2dced
+29 -30
View File
@@ -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
}