From 2abc4101489203437473aff7aaa03c5bc30fe720 Mon Sep 17 00:00:00 2001 From: Andrew Stone Date: Fri, 24 Oct 2014 11:46:53 -0400 Subject: [PATCH] manipulation: Add Before*() functions. --- manipulation.go | 37 +++++++++++++++++++++++++++++++++++++ manipulation_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/manipulation.go b/manipulation.go index 152d9d0..fc404b6 100644 --- a/manipulation.go +++ b/manipulation.go @@ -164,6 +164,43 @@ func (s *Selection) AppendNodes(ns ...*html.Node) *Selection { }) } +// From the root document, apply the selector, and insert the matched elements +// before each element in the set of matched elements. +// This follows the same rules as Selection.After(). +func (s *Selection) Before(selector string) *Selection { + return s.BeforeSelector(cascadia.MustCompile(selector)) +} + +// From the root document, apply the cascadia selector, and insert the matched +// elements before each element in the set of matched elements. +// This follows the same rules as Selection.After(). +func (s *Selection) BeforeSelector(cs cascadia.Selector) *Selection { + return s.BeforeNodes(cs.MatchAll(s.document.rootNode)...) +} + +// Insert the elements in the selection before each element in the set of matched +// elements. +// This follows the same rules as Selection.After(). +func (s *Selection) BeforeSelection(sel *Selection) *Selection { + return s.BeforeNodes(sel.Nodes...) +} + +// Parse the html and insert it before the set of matched elements +// This follows the same rules as Selection.After(). +func (s *Selection) BeforeHtml(html string) *Selection { + return s.BeforeSelection(parseHtml(html)) +} + +// Insert the nodes before each element in the set of matched elements. +// This follows the same rules as Selection.After(). +func (s *Selection) BeforeNodes(ns ...*html.Node) *Selection { + return s.manipulateNodes(ns, false, func(sn *html.Node, n *html.Node) { + if sn.Parent != nil { + sn.Parent.InsertBefore(n, sn) + } + }) +} + // Create a deep copy of the set of matched nodes. The new nodes will not be // attached to the document. func (s *Selection) Clone() *Selection { diff --git a/manipulation_test.go b/manipulation_test.go index 227e3f4..61caa6b 100644 --- a/manipulation_test.go +++ b/manipulation_test.go @@ -79,6 +79,41 @@ func TestAppendHtml(t *testing.T) { AssertLength(t, doc.Find("strong").Nodes, 14) } + +func TestBefore(t *testing.T) { + doc := Doc2Clone() + doc.Find("#main").Before("#nf6") + + AssertLength(t, doc.Find("#main #nf6").Nodes, 0) + AssertLength(t, doc.Find("#foot #nf6").Nodes, 0) + AssertLength(t, doc.Find("body > #nf6:first-child").Nodes, 1) +} + +func TestBeforeWithRemoved(t *testing.T) { + doc := Doc2Clone() + s := doc.Find("#main").Remove() + s.Before("#nf6") + + AssertLength(t, s.Find("#nf6").Nodes, 0) + AssertLength(t, doc.Find("#nf6").Nodes, 0) +} + +func TestBeforeSelection(t *testing.T) { + doc := Doc2Clone() + doc.Find("#main").BeforeSelection(doc.Find("#nf1, #nf2")) + + AssertLength(t, doc.Find("#main #nf1, #main #nf2").Nodes, 0) + AssertLength(t, doc.Find("#foot #nf1, #foot #nf2").Nodes, 0) + AssertLength(t, doc.Find("body > #nf1:first-child, #nf1 + #nf2").Nodes, 2) +} + +func TestBeforeHtml(t *testing.T) { + doc := Doc2Clone() + doc.Find("#main").BeforeHtml("new node") + + AssertLength(t, doc.Find("body > strong:first-child").Nodes, 1) +} + func TestEmpty(t *testing.T) { doc := Doc2Clone() s := doc.Find("#main").Empty()