New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes #377, renders the html that can be manipulated with writer #399
Changes from 1 commit
98eb88c
11e1233
d35d4ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ package goquery | |
|
||
import ( | ||
"bytes" | ||
"io" | ||
|
||
"golang.org/x/net/html" | ||
) | ||
|
@@ -57,6 +58,19 @@ func nodeName(node *html.Node) string { | |
} | ||
} | ||
|
||
// Render renders the html of the first element from selector and writes it to the writer. | ||
// It behaves similar to OuterHtml but takes io.Writer as input. | ||
func Render(w io.Writer, s *Selection) error { | ||
if s.Length() == 0 { | ||
return nil | ||
} | ||
n := s.Get(0) | ||
if err := html.Render(w, n); err != nil { | ||
return err | ||
} | ||
return nil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh one more thing, this (lines 68-71) could be simplified to just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done! |
||
} | ||
|
||
// OuterHtml returns the outer HTML rendering of the first item in | ||
// the selection - that is, the HTML including the first element's | ||
// tag and attributes. | ||
|
@@ -66,12 +80,7 @@ func nodeName(node *html.Node) string { | |
// a property provided by the DOM). | ||
func OuterHtml(s *Selection) (string, error) { | ||
var buf bytes.Buffer | ||
|
||
if s.Length() == 0 { | ||
return "", nil | ||
} | ||
n := s.Get(0) | ||
if err := html.Render(&buf, n); err != nil { | ||
if err := Render(&buf, s); err != nil { | ||
return "", err | ||
} | ||
return buf.String(), nil | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,49 @@ var allNodes = `<!doctype html> | |
</body> | ||
</html>` | ||
|
||
func assertMatchNodes(t testing.TB, doc *Document) { | ||
t.Helper() | ||
|
||
n0 := doc.Nodes[0] | ||
nDT := n0.FirstChild | ||
sMeta := doc.Find("meta") | ||
sP := doc.Find("p") | ||
nP := sP.Get(0) | ||
nComment := nP.FirstChild | ||
nText := nComment.NextSibling | ||
sHeaders := doc.Find(".header") | ||
|
||
cases := []struct { | ||
node *html.Node | ||
sel *Selection | ||
want string | ||
}{ | ||
{nDT, nil, "<!DOCTYPE html>"}, // render makes DOCTYPE all caps | ||
{nil, sMeta, `<meta a="b"/>`}, // and auto-closes the meta | ||
{nil, sP, `<p><!-- this is a comment --> | ||
This is some text. | ||
</p>`}, | ||
{nComment, nil, "<!-- this is a comment -->"}, | ||
{nText, nil, ` | ||
This is some text. | ||
`}, | ||
{nil, sHeaders, `<h1 class="header"></h1>`}, | ||
} | ||
for i, c := range cases { | ||
if c.sel == nil { | ||
c.sel = newSingleSelection(c.node, doc) | ||
} | ||
got, err := OuterHtml(c.sel) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if got != c.want { | ||
t.Errorf("%d: want %q, got %q", i, c.want, got) | ||
} | ||
} | ||
} | ||
|
||
func TestNodeName(t *testing.T) { | ||
doc, err := NewDocumentFromReader(strings.NewReader(allNodes)) | ||
if err != nil { | ||
|
@@ -81,48 +124,18 @@ func TestNodeNameMultiSel(t *testing.T) { | |
} | ||
} | ||
|
||
func TestOuterHtml(t *testing.T) { | ||
func TestRender(t *testing.T) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yeah, given that this is exactly the same as |
||
doc, err := NewDocumentFromReader(strings.NewReader(allNodes)) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
assertMatchNodes(t, doc) | ||
} | ||
|
||
n0 := doc.Nodes[0] | ||
nDT := n0.FirstChild | ||
sMeta := doc.Find("meta") | ||
sP := doc.Find("p") | ||
nP := sP.Get(0) | ||
nComment := nP.FirstChild | ||
nText := nComment.NextSibling | ||
sHeaders := doc.Find(".header") | ||
|
||
cases := []struct { | ||
node *html.Node | ||
sel *Selection | ||
want string | ||
}{ | ||
{nDT, nil, "<!DOCTYPE html>"}, // render makes DOCTYPE all caps | ||
{nil, sMeta, `<meta a="b"/>`}, // and auto-closes the meta | ||
{nil, sP, `<p><!-- this is a comment --> | ||
This is some text. | ||
</p>`}, | ||
{nComment, nil, "<!-- this is a comment -->"}, | ||
{nText, nil, ` | ||
This is some text. | ||
`}, | ||
{nil, sHeaders, `<h1 class="header"></h1>`}, | ||
} | ||
for i, c := range cases { | ||
if c.sel == nil { | ||
c.sel = newSingleSelection(c.node, doc) | ||
} | ||
got, err := OuterHtml(c.sel) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if got != c.want { | ||
t.Errorf("%d: want %q, got %q", i, c.want, got) | ||
} | ||
func TestOuterHtml(t *testing.T) { | ||
doc, err := NewDocumentFromReader(strings.NewReader(allNodes)) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
assertMatchNodes(t, doc) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense! Done