Split monolithic engine.go (776 lines) into specialized files: - engine.go: Core orchestration (142 lines, 82% reduction) - collection.go: Collection processing and management (445 lines) - content.go: Content injection and extraction (152 lines) - discovery.go: Element discovery and DOM traversal (85 lines) Benefits: - Single responsibility principle applied to each file - Better code organization and navigation - Improved testability of individual components - Easier team development and code reviews - Maintained full API compatibility with no breaking changes
85 lines
2.5 KiB
Go
85 lines
2.5 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 hasInsertrClass(n) {
|
|
if isContainer(n) {
|
|
// Container element - mark for transformation
|
|
containersToTransform = append(containersToTransform, n)
|
|
} else {
|
|
// Regular element - add directly
|
|
insertrElements = append(insertrElements, InsertrElement{
|
|
Node: n,
|
|
})
|
|
}
|
|
}
|
|
if e.hasInsertrAddClass(n) {
|
|
// Collection element - add directly (no container transformation for collections)
|
|
collectionElements = append(collectionElements, CollectionElement{
|
|
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)
|
|
}
|
|
}
|