Skip to content

Commit e1271ee

Browse files
committed
Merge branch 'glebtv-setHtml'
2 parents 3cb3b86 + f5c5de8 commit e1271ee

File tree

3 files changed

+86
-2
lines changed

3 files changed

+86
-2
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Please note that because of the net/html dependency, goquery requires Go1.1+.
1313
$ go get github.com/PuerkitoBio/goquery
1414

1515
(optional) To run unit tests:
16-
16+
1717
$ cd $GOPATH/src/github.com/PuerkitoBio/goquery
1818
$ go test
1919

@@ -26,6 +26,7 @@ Please note that because of the net/html dependency, goquery requires Go1.1+.
2626

2727
**Note that goquery's API is now stable, and will not break.**
2828

29+
* **2017-02-12 (v1.1.0)** : Add `SetHtml` and `SetText` (thanks to @glebtv).
2930
* **2016-12-29 (v1.0.2)** : Optimize allocations for `Selection.Text` (thanks to @radovskyb).
3031
* **2016-08-28 (v1.0.1)** : Optimize performance for large documents.
3132
* **2016-07-27 (v1.0.0)** : Tag version 1.0.0.
@@ -85,7 +86,7 @@ import (
8586
)
8687

8788
func ExampleScrape() {
88-
doc, err := goquery.NewDocument("http://metalsucks.net")
89+
doc, err := goquery.NewDocument("http://metalsucks.net")
8990
if err != nil {
9091
log.Fatal(err)
9192
}

manipulation.go

+23
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,17 @@ func (s *Selection) ReplaceWithNodes(ns ...*html.Node) *Selection {
270270
return s.Remove()
271271
}
272272

273+
// Set the html content of each element in the selection to specified html string.
274+
func (s *Selection) SetHtml(html string) *Selection {
275+
return setHtmlNodes(s, parseHtml(html)...)
276+
}
277+
278+
// Set the content of each element in the selection to specified content. The
279+
// provided text string is escaped.
280+
func (s *Selection) SetText(text string) *Selection {
281+
return s.SetHtml(html.EscapeString(text))
282+
}
283+
273284
// Unwrap removes the parents of the set of matched elements, leaving the matched
274285
// elements (and their siblings, if any) in their place.
275286
// It returns the original selection.
@@ -481,6 +492,18 @@ func parseHtml(h string) []*html.Node {
481492
return nodes
482493
}
483494

495+
func setHtmlNodes(s *Selection, ns ...*html.Node) *Selection {
496+
for _, n := range s.Nodes {
497+
for c := n.FirstChild; c != nil; c = n.FirstChild {
498+
n.RemoveChild(c)
499+
}
500+
for _, c := range ns {
501+
n.AppendChild(cloneNode(c))
502+
}
503+
}
504+
return s
505+
}
506+
484507
// Get the first child that is an ElementNode
485508
func getFirstChildEl(n *html.Node) *html.Node {
486509
c := n.FirstChild

manipulation_test.go

+60
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,66 @@ func TestReplaceWithHtml(t *testing.T) {
278278
printSel(t, doc.Selection)
279279
}
280280

281+
func TestSetHtml(t *testing.T) {
282+
doc := Doc2Clone()
283+
q := doc.Find("#main, #foot")
284+
q.SetHtml(`<div id="replace">test</div>`)
285+
286+
assertLength(t, doc.Find("#replace").Nodes, 2)
287+
assertLength(t, doc.Find("#main, #foot").Nodes, 2)
288+
289+
if q.Text() != "testtest" {
290+
t.Errorf("Expected text to be %v, found %v", "testtest", q.Text())
291+
}
292+
293+
printSel(t, doc.Selection)
294+
}
295+
296+
func TestSetHtmlNoMatch(t *testing.T) {
297+
doc := Doc2Clone()
298+
q := doc.Find("#notthere")
299+
q.SetHtml(`<div id="replace">test</div>`)
300+
301+
assertLength(t, doc.Find("#replace").Nodes, 0)
302+
303+
printSel(t, doc.Selection)
304+
}
305+
306+
func TestSetHtmlEmpty(t *testing.T) {
307+
doc := Doc2Clone()
308+
q := doc.Find("#main")
309+
q.SetHtml(``)
310+
311+
assertLength(t, doc.Find("#main").Nodes, 1)
312+
assertLength(t, doc.Find("#main").Children().Nodes, 0)
313+
printSel(t, doc.Selection)
314+
}
315+
316+
func TestSetText(t *testing.T) {
317+
doc := Doc2Clone()
318+
q := doc.Find("#main, #foot")
319+
repl := "<div id=\"replace\">test</div>"
320+
q.SetText(repl)
321+
322+
assertLength(t, doc.Find("#replace").Nodes, 0)
323+
assertLength(t, doc.Find("#main, #foot").Nodes, 2)
324+
325+
if q.Text() != (repl + repl) {
326+
t.Errorf("Expected text to be %v, found %v", (repl + repl), q.Text())
327+
}
328+
329+
h, err := q.Html()
330+
if err != nil {
331+
t.Errorf("Error: %v", err)
332+
}
333+
esc := "&lt;div id=&#34;replace&#34;&gt;test&lt;/div&gt;"
334+
if h != esc {
335+
t.Errorf("Expected html to be %v, found %v", esc, h)
336+
}
337+
338+
printSel(t, doc.Selection)
339+
}
340+
281341
func TestReplaceWithSelection(t *testing.T) {
282342
doc := Doc2Clone()
283343
sel := doc.Find("#nf6").ReplaceWithSelection(doc.Find("#nf5"))

0 commit comments

Comments
 (0)