Files
insertr/internal/engine/discovery.go
Joakim 448b66a974 Fix critical enhancement hanging bug caused by nil context in content injection
Replace nil context with context.Background() in content.go to prevent database operations from hanging indefinitely. Clean up outdated documentation files and add current project structure analysis.
2025-10-26 21:26:48 +01:00

97 lines
2.9 KiB
Go

package engine
import (
"golang.org/x/net/html"
)
// InsertrElement represents an insertr element found in HTML
type InsertrElement struct {
Node *html.Node
}
// findEditableElements finds all editable elements (.insertr and .insertr-add)
func (e *ContentEngine) findEditableElements(doc *html.Node) ([]InsertrElement, []CollectionElement) {
// Phase 1: Pure discovery
insertrElements, collectionElements, containers := e.discoverElements(doc)
// Phase 2: Container expansion (separate concern)
expandedElements := e.expandContainers(containers)
insertrElements = append(insertrElements, expandedElements...)
return insertrElements, collectionElements
}
// discoverElements performs pure element discovery without transformation
func (e *ContentEngine) discoverElements(doc *html.Node) ([]InsertrElement, []CollectionElement, []*html.Node) {
var insertrElements []InsertrElement
var collectionElements []CollectionElement
var containersToTransform []*html.Node
// Walk the document and categorize elements
e.walkNodes(doc, func(n *html.Node) {
if n.Type == html.ElementNode {
if e.hasInsertrAddClass(n) {
// Collection element
if hasInsertrClass(n) {
// Handle .insertr.insertr-add combination:
// Remove .insertr from container, add .insertr to viable children
RemoveClass(n, "insertr")
viableChildren := FindViableChildren(n)
for _, child := range viableChildren {
if !hasInsertrClass(child) {
AddClass(child, "insertr")
}
}
}
// Add as collection (collections take precedence)
collectionElements = append(collectionElements, CollectionElement{
Node: n,
})
} else if hasInsertrClass(n) {
// Regular insertr element (only if not a collection)
if isContainer(n) {
// Container element - mark for transformation
containersToTransform = append(containersToTransform, n)
} else {
// Regular element - add directly
insertrElements = append(insertrElements, InsertrElement{
Node: n,
})
}
}
}
})
return insertrElements, collectionElements, containersToTransform
}
// expandContainers transforms container elements by removing .insertr from containers
// and adding .insertr to their viable children
func (e *ContentEngine) expandContainers(containers []*html.Node) []InsertrElement {
var expandedElements []InsertrElement
for _, container := range containers {
// Remove .insertr class from container
RemoveClass(container, "insertr")
// Find viable children and add .insertr class to them
viableChildren := FindViableChildren(container)
for _, child := range viableChildren {
AddClass(child, "insertr")
expandedElements = append(expandedElements, InsertrElement{
Node: child,
})
}
}
return expandedElements
}
// walkNodes walks through all nodes in the document
func (e *ContentEngine) walkNodes(n *html.Node, fn func(*html.Node)) {
fn(n)
for c := n.FirstChild; c != nil; c = c.NextSibling {
e.walkNodes(c, fn)
}
}