Manual code review by an actual human.

This commit is contained in:
2025-10-24 20:53:49 +02:00
parent dc801fb26b
commit c34a1a033e
3 changed files with 18 additions and 46 deletions

View File

@@ -220,13 +220,12 @@ func (e *ContentEngine) hasInsertrAddClass(node *html.Node) bool {
} }
// addContentAttributes adds data-content-id attribute only // addContentAttributes adds data-content-id attribute only
// HTML-first approach: no content-type attribute needed
func (e *ContentEngine) addContentAttributes(node *html.Node, contentID string) { func (e *ContentEngine) addContentAttributes(node *html.Node, contentID string) {
// Add data-content-id attribute // Add data-content-id attribute
e.setAttribute(node, "data-content-id", contentID) e.setAttribute(node, "data-content-id", contentID)
} }
// setAttribute sets an attribute on an HTML node // setAttribute sets an attribute on a HTML node
func (e *ContentEngine) setAttribute(node *html.Node, key, value string) { func (e *ContentEngine) setAttribute(node *html.Node, key, value string) {
// Remove existing attribute if it exists // Remove existing attribute if it exists
for i, attr := range node.Attr { for i, attr := range node.Attr {
@@ -262,10 +261,8 @@ func (e *ContentEngine) addClass(node *html.Node, className string) {
} }
// Check if class already exists // Check if class already exists
for _, class := range classes { if slices.Contains(classes, className) {
if class == className { return
return // Class already exists
}
} }
// Add new class // Add new class
@@ -314,7 +311,7 @@ func (e *ContentEngine) removeClass(node *html.Node, className string) {
// Update or remove class attribute // Update or remove class attribute
if len(newClasses) == 0 { if len(newClasses) == 0 {
// Remove class attribute entirely if no classes remain // Remove class attribute entirely if no classes remain
node.Attr = append(node.Attr[:classIndex], node.Attr[classIndex+1:]...) node.Attr = slices.Delete(node.Attr, classIndex, classIndex+1)
} else { } else {
// Update class attribute with remaining classes // Update class attribute with remaining classes
node.Attr[classIndex].Val = strings.Join(newClasses, " ") node.Attr[classIndex].Val = strings.Join(newClasses, " ")
@@ -338,6 +335,7 @@ func (e *ContentEngine) injectContent(elements []ProcessedElement, siteID string
elem.Content = contentItem.HTMLContent elem.Content = contentItem.HTMLContent
// Update injector siteID for this operation // Update injector siteID for this operation
// HACK: I do not like this. Injector refactor?
e.injector.siteID = siteID e.injector.siteID = siteID
e.injector.injectHTMLContent(elem.Node, contentItem.HTMLContent) e.injector.injectHTMLContent(elem.Node, contentItem.HTMLContent)
} }
@@ -360,6 +358,7 @@ func (e *ContentEngine) extractHTMLContent(node *html.Node) string {
} }
// extractOriginalTemplate extracts the outer HTML of the element (including the element itself) // extractOriginalTemplate extracts the outer HTML of the element (including the element itself)
// HACK: Rename
func (e *ContentEngine) extractOriginalTemplate(node *html.Node) string { func (e *ContentEngine) extractOriginalTemplate(node *html.Node) string {
var buf strings.Builder var buf strings.Builder
if err := html.Render(&buf, node); err != nil { if err := html.Render(&buf, node); err != nil {
@@ -418,13 +417,11 @@ func (e *ContentEngine) hasClass(n *html.Node, className string) bool {
for _, attr := range n.Attr { for _, attr := range n.Attr {
if attr.Key == "class" { if attr.Key == "class" {
classes := strings.Fields(attr.Val) classes := strings.Fields(attr.Val)
for _, class := range classes { if slices.Contains(classes, className) {
if class == className {
return true return true
} }
} }
} }
}
return false return false
} }

View File

@@ -62,7 +62,7 @@ func (e *ContentEngine) ProcessDirectory(inputDir, outputDir, siteID string, mod
}) })
} }
// writeHTMLDocument writes an HTML document to a file // writeHTMLDocument writes a HTML document to a file
func writeHTMLDocument(outputPath string, doc *html.Node) error { func writeHTMLDocument(outputPath string, doc *html.Node) error {
// Create output directory // Create output directory
if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil { if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil {

View File

@@ -7,9 +7,8 @@ import (
"slices" "slices"
) )
// GetClasses extracts CSS classes from an HTML node
func GetClasses(node *html.Node) []string { func GetClasses(node *html.Node) []string {
classAttr := getAttribute(node, "class") classAttr := GetAttribute(node, "class")
if classAttr == "" { if classAttr == "" {
return []string{} return []string{}
} }
@@ -23,8 +22,8 @@ func ContainsClass(classes []string, target string) bool {
return slices.Contains(classes, target) return slices.Contains(classes, target)
} }
// getAttribute gets an attribute value from an HTML node // GetAttribute gets an attribute value from an HTML node
func getAttribute(node *html.Node, key string) string { func GetAttribute(node *html.Node, key string) string {
for _, attr := range node.Attr { for _, attr := range node.Attr {
if attr.Key == key { if attr.Key == key {
return attr.Val return attr.Val
@@ -76,9 +75,9 @@ var blockingElements = map[string]bool{
"dl": true, "dl": true,
} }
// hasEditableContent checks if a node contains content that can be safely edited // HasEditableContent checks if a node contains content that can be safely edited
// This includes text and safe inline formatting elements // This includes text and safe inline formatting elements
func hasEditableContent(node *html.Node) bool { func HasEditableContent(node *html.Node) bool {
if node.Type != html.ElementNode { if node.Type != html.ElementNode {
return false return false
} }
@@ -129,16 +128,15 @@ func isContainer(node *html.Node) bool {
"main": true, "main": true,
"aside": true, "aside": true,
"nav": true, "nav": true,
"ul": true, // Phase 3: Lists are containers "ul": true,
"ol": true, "ol": true,
} }
return containerTags[node.Data] return containerTags[node.Data]
} }
// findViableChildren finds all descendant elements that should get .insertr class // FindViableChildren finds all descendant elements that should get .insertr class
// Phase 3: Recursive traversal with block/inline classification and boundary respect func FindViableChildren(node *html.Node) []*html.Node {
func findViableChildren(node *html.Node) []*html.Node {
var viable []*html.Node var viable []*html.Node
traverseForViableElements(node, &viable) traverseForViableElements(node, &viable)
return viable return viable
@@ -266,12 +264,7 @@ func isDeferredElement(node *html.Node) bool {
// hasInsertrClass checks if node has class="insertr" // hasInsertrClass checks if node has class="insertr"
func hasInsertrClass(node *html.Node) bool { func hasInsertrClass(node *html.Node) bool {
classes := GetClasses(node) classes := GetClasses(node)
for _, class := range classes { return slices.Contains(classes, "insertr")
if class == "insertr" {
return true
}
}
return false
} }
// isSelfClosing checks if an element is typically self-closing // isSelfClosing checks if an element is typically self-closing
@@ -331,23 +324,6 @@ func findElementWithContent(node *html.Node, targetTag, targetContent string) *h
return nil return nil
} }
// GetAttribute gets an attribute value from an HTML node (exported version)
func GetAttribute(node *html.Node, key string) string {
return getAttribute(node, key)
}
// HasEditableContent checks if a node has editable content (exported version)
func HasEditableContent(node *html.Node) bool {
return hasEditableContent(node)
}
// FindViableChildren finds viable children for editing (exported version)
func FindViableChildren(node *html.Node) []*html.Node {
return findViableChildren(node)
}
// Text extraction utility functions
// ExtractTextContent extracts all text content from an HTML node recursively // ExtractTextContent extracts all text content from an HTML node recursively
func ExtractTextContent(node *html.Node) string { func ExtractTextContent(node *html.Node) string {
var text strings.Builder var text strings.Builder
@@ -355,7 +331,6 @@ func ExtractTextContent(node *html.Node) string {
return strings.TrimSpace(text.String()) return strings.TrimSpace(text.String())
} }
// extractTextRecursiveUnified is the internal unified implementation
func extractTextRecursiveUnified(node *html.Node, text *strings.Builder) { func extractTextRecursiveUnified(node *html.Node, text *strings.Builder) {
if node.Type == html.TextNode { if node.Type == html.TextNode {
text.WriteString(node.Data) text.WriteString(node.Data)