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)
}
}