feat: add NewDocumentFromReaderWithOptions
goquery calls html.Parse, so callers cannot reach the parse options that golang.org/x/net/html has since grown. The one that matters is ParseOptionEnableScripting(false): with scripting assumed enabled the contents of a noscript element are parsed as raw text and no selector can reach inside it. Add a constructor taking html.ParseOption values. Existing constructors are untouched. Refs #139
This commit is contained in:
1 parent
8592be9b0e
commit
3701788802
2 files changed
+55
No files matched your search
@@ -56,6 +56,24 @@ func NewDocumentFromReader(r io.Reader) (*Document, error) {
|
|||||||
return newDocument(root, nil), nil
|
return newDocument(root, nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDocumentFromReaderWithOptions is like NewDocumentFromReader, with the
|
||||||
|
// parse options of the html package.
|
||||||
|
//
|
||||||
|
// The option that usually matters is html.ParseOptionEnableScripting(false),
|
||||||
|
// which makes <noscript> content reachable by selectors:
|
||||||
|
//
|
||||||
|
// doc, err := goquery.NewDocumentFromReaderWithOptions(r,
|
||||||
|
// html.ParseOptionEnableScripting(false))
|
||||||
|
//
|
||||||
|
// The options apply to this parse only.
|
||||||
|
func NewDocumentFromReaderWithOptions(r io.Reader, opts ...html.ParseOption) (*Document, error) {
|
||||||
|
root, e := html.ParseWithOptions(r, opts...)
|
||||||
|
if e != nil {
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
return newDocument(root, nil), nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewDocumentFromResponse is another Document constructor that takes an http response as argument.
|
// NewDocumentFromResponse is another Document constructor that takes an http response as argument.
|
||||||
// It loads the specified response's document, parses it, and stores the root Document
|
// It loads the specified response's document, parses it, and stores the root Document
|
||||||
// node, ready to be manipulated. The response's body is closed on return.
|
// node, ready to be manipulated. The response's body is closed on return.
|
||||||
|
|||||||
@@ -253,3 +253,40 @@ func TestSingle(t *testing.T) {
|
|||||||
t.Fatalf("want %q, got %q", "142", text)
|
t.Fatalf("want %q, got %q", "142", text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewDocumentFromReaderWithOptions(t *testing.T) {
|
||||||
|
const doc = `<html><body><p>before</p><noscript><a href="http://example.org">click this link</a></noscript></body></html>`
|
||||||
|
|
||||||
|
// With scripting on, <noscript> content is raw text no selector can reach.
|
||||||
|
d, e := NewDocumentFromReader(strings.NewReader(doc))
|
||||||
|
if e != nil {
|
||||||
|
t.Fatal(e)
|
||||||
|
}
|
||||||
|
if _, ok := d.Find("noscript a").Attr("href"); ok {
|
||||||
|
t.Error("expected no match inside noscript with scripting enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
d, e = NewDocumentFromReaderWithOptions(strings.NewReader(doc), html.ParseOptionEnableScripting(false))
|
||||||
|
if e != nil {
|
||||||
|
t.Fatal(e)
|
||||||
|
}
|
||||||
|
href, ok := d.Find("noscript a").Attr("href")
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("expected a match inside noscript with scripting disabled")
|
||||||
|
}
|
||||||
|
if href != "http://example.org" {
|
||||||
|
t.Errorf("got href %q, want %q", href, "http://example.org")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewDocumentFromReaderWithOptionsNoOptions(t *testing.T) {
|
||||||
|
const doc = `<html><body><p class="x">hi</p></body></html>`
|
||||||
|
|
||||||
|
d, e := NewDocumentFromReaderWithOptions(strings.NewReader(doc))
|
||||||
|
if e != nil {
|
||||||
|
t.Fatal(e)
|
||||||
|
}
|
||||||
|
if got := d.Find("p.x").Text(); got != "hi" {
|
||||||
|
t.Errorf("got %q, want %q", got, "hi")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user