fix: systematic element matching bug in enhancement pipeline
- Problem: Element ID collisions between similar elements (logo h1 vs hero h1) causing content to be injected into wrong elements - Root cause: Enhancer used naive tag+class matching instead of parser's sophisticated semantic analysis for element identification Systematic solution: - Enhanced parser architecture with exported utilities (GetClasses, ContainsClass) - Added FindElementInDocument() with content-based semantic matching - Replaced naive findAndInjectNodes() with parser-based element matching - Removed code duplication between parser and enhancer packages Backend improvements: - Moved ID generation to backend for single source of truth - Added ElementContext struct for frontend-backend communication - Updated API handlers to support context-based content ID generation Frontend improvements: - Enhanced getElementMetadata() to extract semantic context - Updated save flow to handle both enhanced and non-enhanced elements - Improved API client to use backend-generated content IDs Result: - Unique content IDs: navbar-logo-200530 vs hero-title-a1de7b - Precise element matching using content validation - Single source of truth for DOM utilities in parser package - Eliminated 40+ lines of duplicate code while fixing core bug
This commit is contained in:
@@ -28,7 +28,9 @@ func (g *IDGenerator) Generate(node *html.Node) string {
|
||||
contentHash := g.getContentHash(node)
|
||||
|
||||
baseID := g.createBaseID(context, purpose, contentHash)
|
||||
return g.ensureUnique(baseID)
|
||||
finalID := g.ensureUnique(baseID)
|
||||
|
||||
return finalID
|
||||
}
|
||||
|
||||
// getSemanticContext determines the semantic context from parent elements
|
||||
@@ -36,11 +38,11 @@ func (g *IDGenerator) getSemanticContext(node *html.Node) string {
|
||||
// Walk up the tree to find semantic containers
|
||||
parent := node.Parent
|
||||
for parent != nil && parent.Type == html.ElementNode {
|
||||
classes := getClasses(parent)
|
||||
classes := GetClasses(parent)
|
||||
|
||||
// Check for common semantic section classes
|
||||
for _, class := range []string{"hero", "services", "nav", "navbar", "footer", "about", "contact", "testimonial"} {
|
||||
if containsClass(classes, class) {
|
||||
if ContainsClass(classes, class) {
|
||||
return class
|
||||
}
|
||||
}
|
||||
@@ -68,7 +70,7 @@ func (g *IDGenerator) getSemanticContext(node *html.Node) string {
|
||||
// getPurpose determines the purpose/role of the element
|
||||
func (g *IDGenerator) getPurpose(node *html.Node) string {
|
||||
tag := strings.ToLower(node.Data)
|
||||
classes := getClasses(node)
|
||||
classes := GetClasses(node)
|
||||
|
||||
// Check for specific CSS classes that indicate purpose
|
||||
for _, class := range classes {
|
||||
|
||||
Reference in New Issue
Block a user