Revising ScrollIntoView Action
- Rewrote ScrollIntoView to be consistent with other query actions
This commit is contained in:
parent
f85f3777fa
commit
bf1d5ecfbc
7
input.go
7
input.go
|
@ -2,6 +2,7 @@ package chromedp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/knq/chromedp/cdp"
|
"github.com/knq/chromedp/cdp"
|
||||||
|
@ -51,11 +52,15 @@ func MouseClickXY(x, y int64, opts ...MouseOption) Action {
|
||||||
|
|
||||||
// MouseClickNode dispatches a mouse left button click event at the center of a
|
// MouseClickNode dispatches a mouse left button click event at the center of a
|
||||||
// specified node.
|
// specified node.
|
||||||
|
//
|
||||||
|
// Note that the window will be scrolled if the node is not within the window's
|
||||||
|
// viewport.
|
||||||
func MouseClickNode(n *cdp.Node, opts ...MouseOption) Action {
|
func MouseClickNode(n *cdp.Node, opts ...MouseOption) Action {
|
||||||
return ActionFunc(func(ctxt context.Context, h cdp.Handler) error {
|
return ActionFunc(func(ctxt context.Context, h cdp.Handler) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
err = ScrollIntoNode(n).Do(ctxt, h)
|
var pos []int
|
||||||
|
err = EvaluateAsDevTools(fmt.Sprintf(scrollIntoViewJS, n.FullXPath()), &pos).Do(ctxt, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,16 @@ import (
|
||||||
"github.com/knq/chromedp/cdp/input"
|
"github.com/knq/chromedp/cdp/input"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// inViewportJS is a javascript snippet that will get the specified node
|
||||||
|
// position relative to the viewport and returns true if the specified node
|
||||||
|
// is within the window's viewport.
|
||||||
|
inViewportJS = `(function(a) {
|
||||||
|
var r = a[0].getBoundingClientRect();
|
||||||
|
return r.top >= 0 && r.left >= 0 && r.bottom <= window.innerHeight && r.right <= window.innerWidth;
|
||||||
|
})($x('%s'))`
|
||||||
|
)
|
||||||
|
|
||||||
func TestMouseClickXY(t *testing.T) {
|
func TestMouseClickXY(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -145,7 +155,7 @@ func TestMouseClickOffscreenNode(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var ok bool
|
var ok bool
|
||||||
err = c.Run(defaultContext, EvaluateAsDevTools(fmt.Sprintf(isOnViewJS, nodes[0].FullXPath()), &ok))
|
err = c.Run(defaultContext, EvaluateAsDevTools(fmt.Sprintf(inViewportJS, nodes[0].FullXPath()), &ok))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("got error: %v", err)
|
t.Fatalf("got error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
25
nav.go
25
nav.go
|
@ -3,7 +3,6 @@ package chromedp
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/knq/chromedp/cdp"
|
"github.com/knq/chromedp/cdp"
|
||||||
"github.com/knq/chromedp/cdp/page"
|
"github.com/knq/chromedp/cdp/page"
|
||||||
|
@ -131,27 +130,3 @@ func Title(title *string) Action {
|
||||||
|
|
||||||
return EvaluateAsDevTools(`document.title`, title)
|
return EvaluateAsDevTools(`document.title`, title)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScrollIntoNode scrolls the window to the specified node.
|
|
||||||
func ScrollIntoNode(n *cdp.Node, opts ...QueryOption) Action {
|
|
||||||
return ActionFunc(func(ctxt context.Context, h cdp.Handler) error {
|
|
||||||
var res bool
|
|
||||||
err := EvaluateAsDevTools(fmt.Sprintf(isOnViewJS, n.FullXPath()), &res).Do(ctxt, h)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if res {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = EvaluateAsDevTools(fmt.Sprintf(scrollIntoViewJS, n.FullXPath()), &res).Do(ctxt, h)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !res {
|
|
||||||
return fmt.Errorf("could not scroll into node %d", n.NodeID)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
22
query.go
22
query.go
|
@ -492,3 +492,25 @@ func MatchedStyle(sel interface{}, style **css.GetMatchedStylesForNodeReturns, o
|
||||||
return nil
|
return nil
|
||||||
}, opts...)
|
}, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScrollIntoView scrolls the window to the first node matching the selector.
|
||||||
|
func ScrollIntoView(sel interface{}, opts ...QueryOption) Action {
|
||||||
|
return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error {
|
||||||
|
if len(nodes) < 1 {
|
||||||
|
return fmt.Errorf("selector `%s` did not return any nodes", sel)
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var pos []int
|
||||||
|
err = EvaluateAsDevTools(fmt.Sprintf(scrollIntoViewJS, nodes[0].FullXPath()), &pos).Do(ctxt, h)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if pos == nil {
|
||||||
|
return fmt.Errorf("could not scroll into node %d", nodes[0].NodeID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}, opts...)
|
||||||
|
}
|
||||||
|
|
30
util.go
30
util.go
|
@ -30,7 +30,7 @@ const (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
})($x("%s/node()"))`
|
})($x('%s/node()'))`
|
||||||
|
|
||||||
// blurJS is a javscript snippet that blurs the specified element.
|
// blurJS is a javscript snippet that blurs the specified element.
|
||||||
blurJS = `(function(a) {
|
blurJS = `(function(a) {
|
||||||
|
@ -38,26 +38,6 @@ const (
|
||||||
return true;
|
return true;
|
||||||
})($x('%s'))`
|
})($x('%s'))`
|
||||||
|
|
||||||
// isOnViewJS is a javascript snippet that will get the specified node
|
|
||||||
// position relative to the viewport and returns true or false depending
|
|
||||||
// on if the specified node is on view port.
|
|
||||||
isOnViewJS = `(function(a) {
|
|
||||||
var rect = a[0].getBoundingClientRect();
|
|
||||||
return (
|
|
||||||
rect.top >= 0 &&
|
|
||||||
rect.left >= 0 &&
|
|
||||||
rect.bottom <= window.innerHeight &&
|
|
||||||
rect.right <= window.innerWidth
|
|
||||||
);
|
|
||||||
})($x('%s'))`
|
|
||||||
|
|
||||||
// scrollIntoViewJS is a javascript snippet that scrolls the window to the
|
|
||||||
// specified node.
|
|
||||||
scrollIntoViewJS = `(function(a) {
|
|
||||||
a[0].scrollIntoView(true);
|
|
||||||
return true
|
|
||||||
})($x('%s'))`
|
|
||||||
|
|
||||||
// scrollJS is a javascript snippet that scrolls the window to the
|
// scrollJS is a javascript snippet that scrolls the window to the
|
||||||
// specified x, y coordinates and then returns the actual window x/y after
|
// specified x, y coordinates and then returns the actual window x/y after
|
||||||
// execution.
|
// execution.
|
||||||
|
@ -66,6 +46,14 @@ const (
|
||||||
return [window.scrollX, window.scrollY];
|
return [window.scrollX, window.scrollY];
|
||||||
})(%d, %d)`
|
})(%d, %d)`
|
||||||
|
|
||||||
|
// scrollIntoViewJS is a javascript snippet that scrolls the specified node
|
||||||
|
// into the window's viewport (if needed), returning the actual window x/y
|
||||||
|
// after execution.
|
||||||
|
scrollIntoViewJS = `(function(a) {
|
||||||
|
a[0].scrollIntoViewIfNeeded(true);
|
||||||
|
return [window.scrollX, window.scrollY];
|
||||||
|
})($x('%s'))`
|
||||||
|
|
||||||
// submitJS is a javascript snippet that will call the containing form's
|
// submitJS is a javascript snippet that will call the containing form's
|
||||||
// submit function, returning true or false if the call was successful.
|
// submit function, returning true or false if the call was successful.
|
||||||
submitJS = `(function(a) {
|
submitJS = `(function(a) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user