Refactor engine into focused files to improve maintainability
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
This commit is contained in:
84
internal/engine/discovery.go
Normal file
84
internal/engine/discovery.go
Normal file
@@ -0,0 +1,84 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user