Consolidate DOM manipulation utilities to eliminate code duplication
- Move addClass and setAttribute from ContentEngine/Injector to utils.go - Remove duplicate hasInsertrClass implementation - Add RemoveClass and HasClass utilities for completeness - Eliminates 74+ lines of exact duplication across files
This commit is contained in:
@@ -106,7 +106,7 @@ func (e *ContentEngine) ProcessContent(input ContentInput) (*ContentResult, erro
|
||||
collectionID := e.idGenerator.Generate(collectionElem.Node, input.FilePath)
|
||||
|
||||
// Add data-collection-id attribute to the collection container
|
||||
e.setAttribute(collectionElem.Node, "data-collection-id", collectionID)
|
||||
SetAttribute(collectionElem.Node, "data-collection-id", collectionID)
|
||||
|
||||
// Process collection during enhancement or content injection
|
||||
if input.Mode == Enhancement || input.Mode == ContentInjection {
|
||||
@@ -161,7 +161,7 @@ func (e *ContentEngine) findEditableElements(doc *html.Node) ([]InsertrElement,
|
||||
// First pass: find all .insertr and .insertr-add elements
|
||||
e.walkNodes(doc, func(n *html.Node) {
|
||||
if n.Type == html.ElementNode {
|
||||
if e.hasInsertrClass(n) {
|
||||
if hasInsertrClass(n) {
|
||||
if isContainer(n) {
|
||||
// Container element - mark for transformation
|
||||
containersToTransform = append(containersToTransform, n)
|
||||
@@ -189,7 +189,7 @@ func (e *ContentEngine) findEditableElements(doc *html.Node) ([]InsertrElement,
|
||||
// Find viable children and add .insertr class to them
|
||||
viableChildren := FindViableChildren(container)
|
||||
for _, child := range viableChildren {
|
||||
e.addClass(child, "insertr")
|
||||
AddClass(child, "insertr")
|
||||
insertrElements = append(insertrElements, InsertrElement{
|
||||
Node: child,
|
||||
})
|
||||
@@ -207,12 +207,6 @@ func (e *ContentEngine) walkNodes(n *html.Node, fn func(*html.Node)) {
|
||||
}
|
||||
}
|
||||
|
||||
// hasInsertrClass checks if node has class="insertr"
|
||||
func (e *ContentEngine) hasInsertrClass(node *html.Node) bool {
|
||||
classes := GetClasses(node)
|
||||
return slices.Contains(classes, "insertr")
|
||||
}
|
||||
|
||||
// hasInsertrAddClass checks if node has class="insertr-add" (collection)
|
||||
func (e *ContentEngine) hasInsertrAddClass(node *html.Node) bool {
|
||||
classes := GetClasses(node)
|
||||
@@ -222,63 +216,7 @@ func (e *ContentEngine) hasInsertrAddClass(node *html.Node) bool {
|
||||
// addContentAttributes adds data-content-id attribute only
|
||||
func (e *ContentEngine) addContentAttributes(node *html.Node, contentID string) {
|
||||
// Add data-content-id attribute
|
||||
e.setAttribute(node, "data-content-id", contentID)
|
||||
}
|
||||
|
||||
// setAttribute sets an attribute on a HTML node
|
||||
func (e *ContentEngine) setAttribute(node *html.Node, key, value string) {
|
||||
// Remove existing attribute if it exists
|
||||
for i, attr := range node.Attr {
|
||||
if attr.Key == key {
|
||||
node.Attr[i].Val = value
|
||||
return
|
||||
}
|
||||
}
|
||||
// Add new attribute
|
||||
node.Attr = append(node.Attr, html.Attribute{
|
||||
Key: key,
|
||||
Val: value,
|
||||
})
|
||||
}
|
||||
|
||||
// addClass safely adds a class to an HTML node
|
||||
func (e *ContentEngine) addClass(node *html.Node, className string) {
|
||||
var classAttr *html.Attribute
|
||||
var classIndex int = -1
|
||||
|
||||
// Find existing class attribute
|
||||
for idx, attr := range node.Attr {
|
||||
if attr.Key == "class" {
|
||||
classAttr = &attr
|
||||
classIndex = idx
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var classes []string
|
||||
if classAttr != nil {
|
||||
classes = strings.Fields(classAttr.Val)
|
||||
}
|
||||
|
||||
// Check if class already exists
|
||||
if slices.Contains(classes, className) {
|
||||
return
|
||||
}
|
||||
|
||||
// Add new class
|
||||
classes = append(classes, className)
|
||||
newClassValue := strings.Join(classes, " ")
|
||||
|
||||
if classIndex >= 0 {
|
||||
// Update existing class attribute
|
||||
node.Attr[classIndex].Val = newClassValue
|
||||
} else {
|
||||
// Add new class attribute
|
||||
node.Attr = append(node.Attr, html.Attribute{
|
||||
Key: "class",
|
||||
Val: newClassValue,
|
||||
})
|
||||
}
|
||||
SetAttribute(node, "data-content-id", contentID)
|
||||
}
|
||||
|
||||
// removeClass safely removes a class from an HTML node
|
||||
@@ -367,7 +305,7 @@ func (e *ContentEngine) extractOriginalTemplate(node *html.Node) string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// extractCleanTemplate extracts a clean template without data-content-id attributes and with placeholder content
|
||||
// extractCleanTemplate extracts a clean template without data-content-id attributes and with placeholder content. Used for collection template variants.
|
||||
func (e *ContentEngine) extractCleanTemplate(node *html.Node) string {
|
||||
// Clone the node to avoid modifying the original
|
||||
clonedNode := e.cloneNode(node)
|
||||
@@ -406,7 +344,7 @@ func (e *ContentEngine) extractCleanTemplate(node *html.Node) string {
|
||||
func (e *ContentEngine) removeAttribute(n *html.Node, key string) {
|
||||
for i, attr := range n.Attr {
|
||||
if attr.Key == key {
|
||||
n.Attr = append(n.Attr[:i], n.Attr[i+1:]...)
|
||||
n.Attr = slices.Delete(n.Attr, i, i+1)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -605,7 +543,7 @@ func (e *ContentEngine) reconstructCollectionItems(collectionNode *html.Node, co
|
||||
|
||||
// Inject data-item-id attribute for collection item identification
|
||||
if structuralChild.Type == html.ElementNode {
|
||||
e.setAttribute(structuralChild, "data-item-id", item.ItemID)
|
||||
SetAttribute(structuralChild, "data-item-id", item.ItemID)
|
||||
}
|
||||
|
||||
collectionNode.AppendChild(structuralChild)
|
||||
@@ -665,7 +603,7 @@ func (e *ContentEngine) generateStructuralTemplateFromChild(childElement *html.N
|
||||
if n.Type == html.ElementNode && e.hasClass(n, "insertr") {
|
||||
if entryIndex < len(contentEntries) {
|
||||
// Set the data-content-id attribute
|
||||
e.setAttribute(n, "data-content-id", contentEntries[entryIndex].ID)
|
||||
SetAttribute(n, "data-content-id", contentEntries[entryIndex].ID)
|
||||
|
||||
// Clear content - this will be hydrated during reconstruction
|
||||
for child := n.FirstChild; child != nil; {
|
||||
|
||||
Reference in New Issue
Block a user