From edcb3e4b1ea3293a7f5853e5ff009ee5cd0688c0 Mon Sep 17 00:00:00 2001 From: Andrew Stone Date: Wed, 4 Feb 2015 11:25:23 -0500 Subject: [PATCH] manipulation: Add Prepend*() Looks like I missed yet another manipulation function. --- manipulation.go | 39 +++++++++++++++++++++++++++++ manipulation_test.go | 58 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/manipulation.go b/manipulation.go index fdf045a..2e8b5e6 100644 --- a/manipulation.go +++ b/manipulation.go @@ -162,6 +162,45 @@ func (s *Selection) Empty() *Selection { return pushStack(s, nodes) } +// Prepend prepends the elements specified by the selector to each element in +// the set of matched elements, following the same rules as Append. +func (s *Selection) Prepend(selector string) *Selection { + return s.PrependMatcher(cascadia.MustCompile(selector)) +} + +// PrependMatcher prepends the elements specified by the matcher to each +// element in the set of matched elements. +// +// This follows the same rules as Selection.Append. +func (s *Selection) PrependMatcher(m Matcher) *Selection { + return s.PrependNodes(m.MatchAll(s.document.rootNode)...) +} + +// PrependSelection prepends the elements in the selection to each element in +// the set of matched elements. +// +// This follows the same rules as Selection.Append. +func (s *Selection) PrependSelection(sel *Selection) *Selection { + return s.PrependNodes(sel.Nodes...) +} + +// PrependHtml parses the html and prepends it to the set of matched elements. +func (s *Selection) PrependHtml(html string) *Selection { + return s.PrependNodes(parseHtml(html)...) +} + +// PrependNodes prepends the specified nodes to each node in the set of +// matched elements. +// +// This follows the same rules as Selection.Append. +func (s *Selection) PrependNodes(ns ...*html.Node) *Selection { + return s.manipulateNodes(ns, true, func(sn *html.Node, n *html.Node) { + // sn.FirstChild may be nil, in which case this functions like + // sn.AppendChild() + sn.InsertBefore(n, sn.FirstChild) + }) +} + // Remove removes the set of matched elements from the document. // It returns the same selection, now consisting of nodes not in the document. func (s *Selection) Remove() *Selection { diff --git a/manipulation_test.go b/manipulation_test.go index 0d900ce..f1c6e3e 100644 --- a/manipulation_test.go +++ b/manipulation_test.go @@ -160,6 +160,64 @@ func TestEmpty(t *testing.T) { printSel(t, doc.Selection) } +func TestPrepend(t *testing.T) { + doc := Doc2Clone() + doc.Find("#main").Prepend("#nf6") + + assertLength(t, doc.Find("#foot #nf6").Nodes, 0) + assertLength(t, doc.Find("#main #nf6:first-child").Nodes, 1) + printSel(t, doc.Selection) +} + +func TestPrependBody(t *testing.T) { + doc := Doc2Clone() + doc.Find("body").Prepend("#nf6") + + assertLength(t, doc.Find("#foot #nf6").Nodes, 0) + assertLength(t, doc.Find("#main #nf6").Nodes, 0) + assertLength(t, doc.Find("body > #nf6:first-child").Nodes, 1) + printSel(t, doc.Selection) +} + +func TestPrependSelection(t *testing.T) { + doc := Doc2Clone() + doc.Find("#main").PrependSelection(doc.Find("#nf1, #nf2")) + + assertLength(t, doc.Find("#foot #nf1").Nodes, 0) + assertLength(t, doc.Find("#foot #nf2").Nodes, 0) + assertLength(t, doc.Find("#main #nf1:first-child").Nodes, 1) + assertLength(t, doc.Find("#main #nf2:nth-child(2)").Nodes, 1) + printSel(t, doc.Selection) +} + +func TestPrependSelectionExisting(t *testing.T) { + doc := Doc2Clone() + doc.Find("#main").PrependSelection(doc.Find("#n5, #n6")) + + assertClass(t, doc.Find("#main :nth-child(1)"), "five") + assertClass(t, doc.Find("#main :nth-child(2)"), "six") + assertClass(t, doc.Find("#main :nth-child(5)"), "three") + assertClass(t, doc.Find("#main :nth-child(6)"), "four") + printSel(t, doc.Selection) +} + +func TestPrependClone(t *testing.T) { + doc := Doc2Clone() + doc.Find("#n1").PrependSelection(doc.Find("#nf1").Clone()) + + assertLength(t, doc.Find("#foot #nf1:first-child").Nodes, 1) + assertLength(t, doc.Find("#main #nf1:first-child").Nodes, 1) + printSel(t, doc.Selection) +} + +func TestPrependHtml(t *testing.T) { + doc := Doc2Clone() + doc.Find("div").PrependHtml("new node") + + assertLength(t, doc.Find("strong:first-child").Nodes, 14) + printSel(t, doc.Selection) +} + func TestRemove(t *testing.T) { doc := Doc2Clone() doc.Find("#nf1").Remove()