diff --git a/internal/merge.go b/internal/merge.go index 5c98061..9b5240e 100644 --- a/internal/merge.go +++ b/internal/merge.go @@ -121,7 +121,25 @@ func merge(base, doc *html.Node) (out *html.Node) { n.Parent.RemoveChild(n) } - _ = main // TODO + // if neither has main, just merge the bodies + // if doc has main but base doesn't, just merge the bodies + // if base has main but doc doesn't, merge doc body into base main + // if both have main, merge doc main(s) into base main and then merge the bodies + if main == nil { + reparentBefore(body, newBody, footer) + } else if findRec(newBody, atom.Main) == nil { + reparentBefore(main, newBody, footer) + } else { + for { + n := findRec(newBody, atom.Main) + if n == nil { + break + } + reparentChildren(main, n) + n.Parent.RemoveChild(n) + } + reparentBefore(body, newBody, footer) + } return out } @@ -145,6 +163,21 @@ func reparentChildren(dst, src *html.Node) { } } +// reparentBefore reparents all of src's child nodes to dst, inserting them before the given element. +func reparentBefore(dst, src, locus *html.Node) { + if src == nil { + return + } + for { + child := src.FirstChild + if child == nil { + break + } + src.RemoveChild(child) + dst.InsertBefore(child, locus) + } +} + func find(elem *html.Node, tagName atom.Atom) *html.Node { if elem != nil { for n := elem.FirstChild; n != nil; n = n.NextSibling { diff --git a/internal/merge_test.go b/internal/merge_test.go index 408bf6f..593d934 100644 --- a/internal/merge_test.go +++ b/internal/merge_test.go @@ -17,13 +17,15 @@ const pageText = ` This is a title

Title

-

Body text +

Body text

` const mergeText = ` This is a title

Title

+ +

Body text

`