mirror of
https://github.com/MontFerret/ferret.git
synced 2025-04-11 11:42:13 +02:00
Added scroll options (#471)
* Added scroll options * Updated dependencies * Updates after code review * Updates after review * Added comments
This commit is contained in:
parent
64fc010e6e
commit
c9dfb79641
@ -442,20 +442,20 @@ func (doc *HTMLDocument) WaitForStyleBySelectorAll(ctx context.Context, selector
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) ScrollTop(ctx context.Context) error {
|
func (doc *HTMLDocument) ScrollTop(ctx context.Context, options drivers.ScrollOptions) error {
|
||||||
return doc.input.ScrollTop(ctx)
|
return doc.input.ScrollTop(ctx, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) ScrollBottom(ctx context.Context) error {
|
func (doc *HTMLDocument) ScrollBottom(ctx context.Context, options drivers.ScrollOptions) error {
|
||||||
return doc.input.ScrollBottom(ctx)
|
return doc.input.ScrollBottom(ctx, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) ScrollBySelector(ctx context.Context, selector values.String) error {
|
func (doc *HTMLDocument) ScrollBySelector(ctx context.Context, selector values.String, options drivers.ScrollOptions) error {
|
||||||
return doc.input.ScrollIntoViewBySelector(ctx, selector.String())
|
return doc.input.ScrollIntoViewBySelector(ctx, selector.String(), options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) ScrollByXY(ctx context.Context, x, y values.Float) error {
|
func (doc *HTMLDocument) ScrollByXY(ctx context.Context, x, y values.Float, options drivers.ScrollOptions) error {
|
||||||
return doc.input.ScrollByXY(ctx, float64(x), float64(y))
|
return doc.input.ScrollByXY(ctx, float64(x), float64(y), options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) logError(err error) *zerolog.Event {
|
func (doc *HTMLDocument) logError(err error) *zerolog.Event {
|
||||||
|
@ -1101,8 +1101,8 @@ func (el *HTMLElement) SelectBySelector(ctx context.Context, selector values.Str
|
|||||||
return el.input.SelectBySelector(ctx, el.id.NodeID, selector.String(), value)
|
return el.input.SelectBySelector(ctx, el.id.NodeID, selector.String(), value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (el *HTMLElement) ScrollIntoView(ctx context.Context) error {
|
func (el *HTMLElement) ScrollIntoView(ctx context.Context, options drivers.ScrollOptions) error {
|
||||||
return el.input.ScrollIntoView(ctx, el.id.ObjectID)
|
return el.input.ScrollIntoView(ctx, el.id.ObjectID, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (el *HTMLElement) Focus(ctx context.Context) error {
|
func (el *HTMLElement) Focus(ctx context.Context) error {
|
||||||
|
@ -52,37 +52,41 @@ func (m *Manager) Mouse() *Mouse {
|
|||||||
return m.mouse
|
return m.mouse
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) ScrollTop(ctx context.Context) error {
|
func (m *Manager) ScrollTop(ctx context.Context, options drivers.ScrollOptions) error {
|
||||||
return m.exec.Eval(ctx, templates.ScrollTop())
|
return m.exec.Eval(ctx, templates.ScrollTop(options))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) ScrollBottom(ctx context.Context) error {
|
func (m *Manager) ScrollBottom(ctx context.Context, options drivers.ScrollOptions) error {
|
||||||
return m.exec.Eval(ctx, templates.ScrollBottom())
|
return m.exec.Eval(ctx, templates.ScrollBottom(options))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) ScrollIntoView(ctx context.Context, objectID runtime.RemoteObjectID) error {
|
func (m *Manager) ScrollIntoView(ctx context.Context, objectID runtime.RemoteObjectID, options drivers.ScrollOptions) error {
|
||||||
return m.exec.EvalWithArguments(
|
return m.exec.EvalWithArguments(
|
||||||
ctx,
|
ctx,
|
||||||
templates.ScrollIntoView(),
|
templates.ScrollIntoView(options),
|
||||||
runtime.CallArgument{
|
runtime.CallArgument{
|
||||||
ObjectID: &objectID,
|
ObjectID: &objectID,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) ScrollIntoViewBySelector(ctx context.Context, selector string) error {
|
func (m *Manager) ScrollIntoViewBySelector(ctx context.Context, selector string, options drivers.ScrollOptions) error {
|
||||||
return m.exec.Eval(ctx, templates.ScrollIntoViewBySelector(selector))
|
return m.exec.Eval(ctx, templates.ScrollIntoViewBySelector(selector, options))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) ScrollByXY(ctx context.Context, x, y float64) error {
|
func (m *Manager) ScrollByXY(ctx context.Context, x, y float64, options drivers.ScrollOptions) error {
|
||||||
return m.exec.Eval(
|
return m.exec.Eval(
|
||||||
ctx,
|
ctx,
|
||||||
templates.Scroll(eval.ParamFloat(x), eval.ParamFloat(y)),
|
templates.Scroll(eval.ParamFloat(x), eval.ParamFloat(y), options),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) Focus(ctx context.Context, objectID runtime.RemoteObjectID) error {
|
func (m *Manager) Focus(ctx context.Context, objectID runtime.RemoteObjectID) error {
|
||||||
err := m.ScrollIntoView(ctx, objectID)
|
err := m.ScrollIntoView(ctx, objectID, drivers.ScrollOptions{
|
||||||
|
Behavior: drivers.ScrollBehaviorAuto,
|
||||||
|
Block: drivers.ScrollVerticalAlignmentCenter,
|
||||||
|
Inline: drivers.ScrollHorizontalAlignmentCenter,
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -92,7 +96,11 @@ func (m *Manager) Focus(ctx context.Context, objectID runtime.RemoteObjectID) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) FocusBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string) error {
|
func (m *Manager) FocusBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string) error {
|
||||||
err := m.ScrollIntoViewBySelector(ctx, selector)
|
err := m.ScrollIntoViewBySelector(ctx, selector, drivers.ScrollOptions{
|
||||||
|
Behavior: drivers.ScrollBehaviorAuto,
|
||||||
|
Block: drivers.ScrollVerticalAlignmentCenter,
|
||||||
|
Inline: drivers.ScrollHorizontalAlignmentCenter,
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -120,7 +128,7 @@ func (m *Manager) BlurBySelector(ctx context.Context, parentObjectID runtime.Rem
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) MoveMouse(ctx context.Context, objectID runtime.RemoteObjectID) error {
|
func (m *Manager) MoveMouse(ctx context.Context, objectID runtime.RemoteObjectID) error {
|
||||||
if err := m.ScrollIntoView(ctx, objectID); err != nil {
|
if err := m.ScrollIntoView(ctx, objectID, drivers.ScrollOptions{}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +142,7 @@ func (m *Manager) MoveMouse(ctx context.Context, objectID runtime.RemoteObjectID
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) MoveMouseBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string) error {
|
func (m *Manager) MoveMouseBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string) error {
|
||||||
if err := m.ScrollIntoViewBySelector(ctx, selector); err != nil {
|
if err := m.ScrollIntoViewBySelector(ctx, selector, drivers.ScrollOptions{}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +162,7 @@ func (m *Manager) MoveMouseBySelector(ctx context.Context, parentNodeID dom.Node
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) MoveMouseByXY(ctx context.Context, x, y float64) error {
|
func (m *Manager) MoveMouseByXY(ctx context.Context, x, y float64) error {
|
||||||
if err := m.ScrollByXY(ctx, x, y); err != nil {
|
if err := m.ScrollByXY(ctx, x, y, drivers.ScrollOptions{}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +170,11 @@ func (m *Manager) MoveMouseByXY(ctx context.Context, x, y float64) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) Click(ctx context.Context, objectID runtime.RemoteObjectID, count int) error {
|
func (m *Manager) Click(ctx context.Context, objectID runtime.RemoteObjectID, count int) error {
|
||||||
if err := m.ScrollIntoView(ctx, objectID); err != nil {
|
if err := m.ScrollIntoView(ctx, objectID, drivers.ScrollOptions{
|
||||||
|
Behavior: drivers.ScrollBehaviorAuto,
|
||||||
|
Block: drivers.ScrollVerticalAlignmentCenter,
|
||||||
|
Inline: drivers.ScrollHorizontalAlignmentCenter,
|
||||||
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +194,11 @@ func (m *Manager) Click(ctx context.Context, objectID runtime.RemoteObjectID, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) ClickBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string, count int) error {
|
func (m *Manager) ClickBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string, count int) error {
|
||||||
if err := m.ScrollIntoViewBySelector(ctx, selector); err != nil {
|
if err := m.ScrollIntoViewBySelector(ctx, selector, drivers.ScrollOptions{
|
||||||
|
Behavior: drivers.ScrollBehaviorAuto,
|
||||||
|
Block: drivers.ScrollVerticalAlignmentCenter,
|
||||||
|
Inline: drivers.ScrollHorizontalAlignmentCenter,
|
||||||
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +224,11 @@ func (m *Manager) ClickBySelector(ctx context.Context, parentNodeID dom.NodeID,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) ClickBySelectorAll(ctx context.Context, parentNodeID dom.NodeID, selector string, count int) error {
|
func (m *Manager) ClickBySelectorAll(ctx context.Context, parentNodeID dom.NodeID, selector string, count int) error {
|
||||||
if err := m.ScrollIntoViewBySelector(ctx, selector); err != nil {
|
if err := m.ScrollIntoViewBySelector(ctx, selector, drivers.ScrollOptions{
|
||||||
|
Behavior: drivers.ScrollBehaviorAuto,
|
||||||
|
Block: drivers.ScrollVerticalAlignmentCenter,
|
||||||
|
Inline: drivers.ScrollHorizontalAlignmentCenter,
|
||||||
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +260,11 @@ func (m *Manager) ClickBySelectorAll(ctx context.Context, parentNodeID dom.NodeI
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) Type(ctx context.Context, objectID runtime.RemoteObjectID, params TypeParams) error {
|
func (m *Manager) Type(ctx context.Context, objectID runtime.RemoteObjectID, params TypeParams) error {
|
||||||
err := m.ScrollIntoView(ctx, objectID)
|
err := m.ScrollIntoView(ctx, objectID, drivers.ScrollOptions{
|
||||||
|
Behavior: drivers.ScrollBehaviorAuto,
|
||||||
|
Block: drivers.ScrollVerticalAlignmentCenter,
|
||||||
|
Inline: drivers.ScrollHorizontalAlignmentCenter,
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -273,7 +297,11 @@ func (m *Manager) Type(ctx context.Context, objectID runtime.RemoteObjectID, par
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) TypeBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string, params TypeParams) error {
|
func (m *Manager) TypeBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string, params TypeParams) error {
|
||||||
err := m.ScrollIntoViewBySelector(ctx, selector)
|
err := m.ScrollIntoViewBySelector(ctx, selector, drivers.ScrollOptions{
|
||||||
|
Behavior: drivers.ScrollBehaviorAuto,
|
||||||
|
Block: drivers.ScrollVerticalAlignmentCenter,
|
||||||
|
Inline: drivers.ScrollHorizontalAlignmentCenter,
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -312,7 +340,11 @@ func (m *Manager) TypeBySelector(ctx context.Context, parentNodeID dom.NodeID, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) Clear(ctx context.Context, objectID runtime.RemoteObjectID) error {
|
func (m *Manager) Clear(ctx context.Context, objectID runtime.RemoteObjectID) error {
|
||||||
err := m.ScrollIntoView(ctx, objectID)
|
err := m.ScrollIntoView(ctx, objectID, drivers.ScrollOptions{
|
||||||
|
Behavior: drivers.ScrollBehaviorAuto,
|
||||||
|
Block: drivers.ScrollVerticalAlignmentCenter,
|
||||||
|
Inline: drivers.ScrollHorizontalAlignmentCenter,
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -334,7 +366,11 @@ func (m *Manager) Clear(ctx context.Context, objectID runtime.RemoteObjectID) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) ClearBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string) error {
|
func (m *Manager) ClearBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string) error {
|
||||||
err := m.ScrollIntoViewBySelector(ctx, selector)
|
err := m.ScrollIntoViewBySelector(ctx, selector, drivers.ScrollOptions{
|
||||||
|
Behavior: drivers.ScrollBehaviorAuto,
|
||||||
|
Block: drivers.ScrollVerticalAlignmentCenter,
|
||||||
|
Inline: drivers.ScrollHorizontalAlignmentCenter,
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -19,11 +19,23 @@ const (
|
|||||||
};
|
};
|
||||||
`
|
`
|
||||||
|
|
||||||
|
scrollTemplate = `
|
||||||
|
window.scrollTo({
|
||||||
|
left: %s,
|
||||||
|
top: %s,
|
||||||
|
behavior: %s,
|
||||||
|
block: %s,
|
||||||
|
inline: %s
|
||||||
|
});
|
||||||
|
`
|
||||||
|
|
||||||
scrollTopTemplate = `
|
scrollTopTemplate = `
|
||||||
window.scrollTo({
|
window.scrollTo({
|
||||||
left: 0,
|
left: 0,
|
||||||
top: 0,
|
top: 0,
|
||||||
behavior: 'instant'
|
behavior: %s,
|
||||||
|
block: %s,
|
||||||
|
inline: %s
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -31,7 +43,9 @@ const (
|
|||||||
window.scrollTo({
|
window.scrollTo({
|
||||||
left: 0,
|
left: 0,
|
||||||
top: window.document.body.scrollHeight,
|
top: window.document.body.scrollHeight,
|
||||||
behavior: 'instant'
|
behavior: %s,
|
||||||
|
block: %s,
|
||||||
|
inline: %s
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -42,53 +56,82 @@ const (
|
|||||||
|
|
||||||
if (!isInViewport(el)) {
|
if (!isInViewport(el)) {
|
||||||
el.scrollIntoView({
|
el.scrollIntoView({
|
||||||
block: 'center',
|
behavior: %s,
|
||||||
inline: 'center',
|
block: %s,
|
||||||
behavior: 'instant'
|
inline: %s
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
)
|
|
||||||
|
|
||||||
func Scroll(x, y string) string {
|
scrollIntoViewBySelectorTemplate = `
|
||||||
return fmt.Sprintf(`
|
|
||||||
window.scrollBy(%s, %s);
|
|
||||||
`, x, y)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ScrollTop() string {
|
|
||||||
return scrollTopTemplate
|
|
||||||
}
|
|
||||||
|
|
||||||
func ScrollBottom() string {
|
|
||||||
return scrollBottomTemplate
|
|
||||||
}
|
|
||||||
|
|
||||||
func ScrollIntoView() string {
|
|
||||||
return scrollIntoViewTemplate
|
|
||||||
}
|
|
||||||
|
|
||||||
func ScrollIntoViewBySelector(selector string) string {
|
|
||||||
return fmt.Sprintf(`
|
|
||||||
const el = document.querySelector('%s');
|
const el = document.querySelector('%s');
|
||||||
|
|
||||||
if (el == null) {
|
if (el == null) {
|
||||||
throw new Error('%s');
|
throw new Error('%s');
|
||||||
}
|
}
|
||||||
|
|
||||||
%s
|
` + isElementInViewportTemplate + `
|
||||||
|
|
||||||
if (!isInViewport(el)) {
|
if (!isInViewport(el)) {
|
||||||
el.scrollIntoView({
|
el.scrollIntoView({
|
||||||
block: 'center',
|
behavior: %s,
|
||||||
inline: 'center',
|
block: %s,
|
||||||
behavior: 'instant'
|
inline: %s
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
`, selector, drivers.ErrNotFound, isElementInViewportTemplate)
|
`
|
||||||
|
)
|
||||||
|
|
||||||
|
func Scroll(x, y string, options drivers.ScrollOptions) string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
scrollTemplate,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
options.Behavior,
|
||||||
|
options.Block,
|
||||||
|
options.Inline,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ScrollTop(options drivers.ScrollOptions) string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
scrollTopTemplate,
|
||||||
|
options.Behavior,
|
||||||
|
options.Block,
|
||||||
|
options.Inline,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ScrollBottom(options drivers.ScrollOptions) string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
scrollBottomTemplate,
|
||||||
|
options.Behavior,
|
||||||
|
options.Block,
|
||||||
|
options.Inline,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ScrollIntoView(options drivers.ScrollOptions) string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
scrollIntoViewTemplate,
|
||||||
|
options.Behavior,
|
||||||
|
options.Block,
|
||||||
|
options.Inline,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ScrollIntoViewBySelector(selector string, options drivers.ScrollOptions) string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
scrollIntoViewBySelectorTemplate,
|
||||||
|
selector,
|
||||||
|
drivers.ErrNotFound,
|
||||||
|
options.Behavior,
|
||||||
|
options.Block,
|
||||||
|
options.Inline,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -207,19 +207,19 @@ func (doc *HTMLDocument) GetParentDocument(_ context.Context) (drivers.HTMLDocum
|
|||||||
return doc.parent, nil
|
return doc.parent, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) ScrollTop(_ context.Context) error {
|
func (doc *HTMLDocument) ScrollTop(_ context.Context, _ drivers.ScrollOptions) error {
|
||||||
return core.ErrNotSupported
|
return core.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) ScrollBottom(_ context.Context) error {
|
func (doc *HTMLDocument) ScrollBottom(_ context.Context, _ drivers.ScrollOptions) error {
|
||||||
return core.ErrNotSupported
|
return core.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) ScrollBySelector(_ context.Context, _ values.String) error {
|
func (doc *HTMLDocument) ScrollBySelector(_ context.Context, _ values.String, _ drivers.ScrollOptions) error {
|
||||||
return core.ErrNotSupported
|
return core.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) ScrollByXY(_ context.Context, _, _ values.Float) error {
|
func (doc *HTMLDocument) ScrollByXY(_ context.Context, _, _ values.Float, _ drivers.ScrollOptions) error {
|
||||||
return core.ErrNotSupported
|
return core.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,7 +525,7 @@ func (el *HTMLElement) SelectBySelector(_ context.Context, _ values.String, _ *v
|
|||||||
return nil, core.ErrNotSupported
|
return nil, core.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (el *HTMLElement) ScrollIntoView(_ context.Context) error {
|
func (el *HTMLElement) ScrollIntoView(_ context.Context, _ drivers.ScrollOptions) error {
|
||||||
return core.ErrNotSupported
|
return core.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
127
pkg/drivers/scroll.go
Normal file
127
pkg/drivers/scroll.go
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
package drivers
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// ScrollBehavior defines the transition animation.
|
||||||
|
// In HTML specification, default value is auto, but in Ferret it's instant.
|
||||||
|
// More details here https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
|
||||||
|
type ScrollBehavior int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ScrollBehaviorInstant ScrollBehavior = 0
|
||||||
|
ScrollBehaviorSmooth ScrollBehavior = 1
|
||||||
|
ScrollBehaviorAuto ScrollBehavior = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewScrollBehavior(value string) ScrollBehavior {
|
||||||
|
switch strings.ToLower(value) {
|
||||||
|
case "instant":
|
||||||
|
return ScrollBehaviorInstant
|
||||||
|
case "smooth":
|
||||||
|
return ScrollBehaviorSmooth
|
||||||
|
default:
|
||||||
|
return ScrollBehaviorAuto
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b ScrollBehavior) String() string {
|
||||||
|
switch b {
|
||||||
|
case ScrollBehaviorInstant:
|
||||||
|
return "instant"
|
||||||
|
case ScrollBehaviorSmooth:
|
||||||
|
return "smooth"
|
||||||
|
default:
|
||||||
|
return "auto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScrollVerticalAlignment defines vertical alignment after scrolling.
|
||||||
|
// In HTML specification, default value is start, but in Ferret it's center.
|
||||||
|
// More details here https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
|
||||||
|
type ScrollVerticalAlignment int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ScrollVerticalAlignmentCenter ScrollVerticalAlignment = 0
|
||||||
|
ScrollVerticalAlignmentStart ScrollVerticalAlignment = 1
|
||||||
|
ScrollVerticalAlignmentEnd ScrollVerticalAlignment = 2
|
||||||
|
ScrollVerticalAlignmentNearest ScrollVerticalAlignment = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewScrollVerticalAlignment(value string) ScrollVerticalAlignment {
|
||||||
|
switch strings.ToLower(value) {
|
||||||
|
case "center":
|
||||||
|
return ScrollVerticalAlignmentCenter
|
||||||
|
case "start":
|
||||||
|
return ScrollVerticalAlignmentStart
|
||||||
|
case "end":
|
||||||
|
return ScrollVerticalAlignmentEnd
|
||||||
|
case "nearest":
|
||||||
|
return ScrollVerticalAlignmentNearest
|
||||||
|
default:
|
||||||
|
return ScrollVerticalAlignmentCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a ScrollVerticalAlignment) String() string {
|
||||||
|
switch a {
|
||||||
|
case ScrollVerticalAlignmentCenter:
|
||||||
|
return "center"
|
||||||
|
case ScrollVerticalAlignmentStart:
|
||||||
|
return "start"
|
||||||
|
case ScrollVerticalAlignmentEnd:
|
||||||
|
return "end"
|
||||||
|
case ScrollVerticalAlignmentNearest:
|
||||||
|
return "nearest"
|
||||||
|
default:
|
||||||
|
return "center"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScrollHorizontalAlignment defines horizontal alignment after scrolling.
|
||||||
|
// In HTML specification, default value is nearest, but in Ferret it's center.
|
||||||
|
// More details here https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
|
||||||
|
type ScrollHorizontalAlignment int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ScrollHorizontalAlignmentCenter ScrollHorizontalAlignment = 0
|
||||||
|
ScrollHorizontalAlignmentStart ScrollHorizontalAlignment = 1
|
||||||
|
ScrollHorizontalAlignmentEnd ScrollHorizontalAlignment = 2
|
||||||
|
ScrollHorizontalAlignmentNearest ScrollHorizontalAlignment = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewScrollHorizontalAlignment(value string) ScrollHorizontalAlignment {
|
||||||
|
switch strings.ToLower(value) {
|
||||||
|
case "center":
|
||||||
|
return ScrollHorizontalAlignmentCenter
|
||||||
|
case "start":
|
||||||
|
return ScrollHorizontalAlignmentStart
|
||||||
|
case "end":
|
||||||
|
return ScrollHorizontalAlignmentEnd
|
||||||
|
case "nearest":
|
||||||
|
return ScrollHorizontalAlignmentNearest
|
||||||
|
default:
|
||||||
|
return ScrollHorizontalAlignmentCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a ScrollHorizontalAlignment) String() string {
|
||||||
|
switch a {
|
||||||
|
case ScrollHorizontalAlignmentCenter:
|
||||||
|
return "center"
|
||||||
|
case ScrollHorizontalAlignmentNearest:
|
||||||
|
return "nearest"
|
||||||
|
case ScrollHorizontalAlignmentStart:
|
||||||
|
return "start"
|
||||||
|
case ScrollHorizontalAlignmentEnd:
|
||||||
|
return "end"
|
||||||
|
default:
|
||||||
|
return "center"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScrollOptions defines how scroll animation should be performed.
|
||||||
|
type ScrollOptions struct {
|
||||||
|
Behavior ScrollBehavior
|
||||||
|
Block ScrollVerticalAlignment
|
||||||
|
Inline ScrollHorizontalAlignment
|
||||||
|
}
|
@ -111,7 +111,7 @@ type (
|
|||||||
|
|
||||||
SelectBySelector(ctx context.Context, selector values.String, value *values.Array) (*values.Array, error)
|
SelectBySelector(ctx context.Context, selector values.String, value *values.Array) (*values.Array, error)
|
||||||
|
|
||||||
ScrollIntoView(ctx context.Context) error
|
ScrollIntoView(ctx context.Context, options ScrollOptions) error
|
||||||
|
|
||||||
Focus(ctx context.Context) error
|
Focus(ctx context.Context) error
|
||||||
|
|
||||||
@ -147,13 +147,13 @@ type (
|
|||||||
|
|
||||||
GetChildDocuments(ctx context.Context) (*values.Array, error)
|
GetChildDocuments(ctx context.Context) (*values.Array, error)
|
||||||
|
|
||||||
ScrollTop(ctx context.Context) error
|
ScrollTop(ctx context.Context, options ScrollOptions) error
|
||||||
|
|
||||||
ScrollBottom(ctx context.Context) error
|
ScrollBottom(ctx context.Context, options ScrollOptions) error
|
||||||
|
|
||||||
ScrollBySelector(ctx context.Context, selector values.String) error
|
ScrollBySelector(ctx context.Context, selector values.String, options ScrollOptions) error
|
||||||
|
|
||||||
ScrollByXY(ctx context.Context, x, y values.Float) error
|
ScrollByXY(ctx context.Context, x, y values.Float, options ScrollOptions) error
|
||||||
|
|
||||||
MoveMouseByXY(ctx context.Context, x, y values.Float) error
|
MoveMouseByXY(ctx context.Context, x, y values.Float) error
|
||||||
|
|
||||||
|
@ -105,3 +105,35 @@ func waitTimeout(ctx context.Context, value values.Int) (context.Context, contex
|
|||||||
time.Duration(value)*time.Millisecond,
|
time.Duration(value)*time.Millisecond,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toScrollOptions(value core.Value) (drivers.ScrollOptions, error) {
|
||||||
|
result := drivers.ScrollOptions{}
|
||||||
|
|
||||||
|
err := core.ValidateType(value, types.Object)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
obj := value.(*values.Object)
|
||||||
|
|
||||||
|
behavior, exists := obj.Get("behavior")
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
result.Behavior = drivers.NewScrollBehavior(behavior.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
block, exists := obj.Get("block")
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
result.Block = drivers.NewScrollVerticalAlignment(block.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
inline, exists := obj.Get("inline")
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
result.Inline = drivers.NewScrollHorizontalAlignment(inline.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
@ -10,8 +10,9 @@ import (
|
|||||||
|
|
||||||
// SCROLL_BOTTOM scrolls the document's window to its bottom.
|
// SCROLL_BOTTOM scrolls the document's window to its bottom.
|
||||||
// @param doc (HTMLDocument) - Target document.
|
// @param doc (HTMLDocument) - Target document.
|
||||||
|
// @param options (ScrollOptions) - Scroll options. Optional.
|
||||||
func ScrollBottom(ctx context.Context, args ...core.Value) (core.Value, error) {
|
func ScrollBottom(ctx context.Context, args ...core.Value) (core.Value, error) {
|
||||||
err := core.ValidateArgs(args, 1, 1)
|
err := core.ValidateArgs(args, 1, 2)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return values.None, err
|
return values.None, err
|
||||||
@ -23,5 +24,15 @@ func ScrollBottom(ctx context.Context, args ...core.Value) (core.Value, error) {
|
|||||||
return values.None, err
|
return values.None, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return values.None, doc.ScrollBottom(ctx)
|
var opts drivers.ScrollOptions
|
||||||
|
|
||||||
|
if len(args) > 1 {
|
||||||
|
opts, err = toScrollOptions(args[1])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return values.None, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return values.None, doc.ScrollBottom(ctx, opts)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package html
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/MontFerret/ferret/pkg/drivers"
|
"github.com/MontFerret/ferret/pkg/drivers"
|
||||||
"github.com/MontFerret/ferret/pkg/runtime/core"
|
"github.com/MontFerret/ferret/pkg/runtime/core"
|
||||||
"github.com/MontFerret/ferret/pkg/runtime/values"
|
"github.com/MontFerret/ferret/pkg/runtime/values"
|
||||||
@ -11,44 +13,90 @@ import (
|
|||||||
|
|
||||||
// SCROLL_ELEMENT scrolls an element on.
|
// SCROLL_ELEMENT scrolls an element on.
|
||||||
// @param docOrEl (HTMLDocument|HTMLElement) - Target document or element.
|
// @param docOrEl (HTMLDocument|HTMLElement) - Target document or element.
|
||||||
// @param selector (String, options) - If document is passed, this param must represent an element selector.
|
// @param selector (String) - If document is passed, this param must represent an element selector.
|
||||||
|
// @param options (ScrollOptions) - Scroll options. Optional.
|
||||||
func ScrollInto(ctx context.Context, args ...core.Value) (core.Value, error) {
|
func ScrollInto(ctx context.Context, args ...core.Value) (core.Value, error) {
|
||||||
err := core.ValidateArgs(args, 1, 2)
|
err := core.ValidateArgs(args, 1, 3)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return values.None, err
|
return values.None, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) == 2 {
|
var doc drivers.HTMLDocument
|
||||||
doc, err := drivers.ToDocument(args[0])
|
var el drivers.HTMLElement
|
||||||
|
var selector values.String
|
||||||
|
var opts drivers.ScrollOptions
|
||||||
|
|
||||||
|
if len(args) == 3 {
|
||||||
|
if err = core.ValidateType(args[1], types.String); err != nil {
|
||||||
|
return values.None, errors.Wrap(err, "selector")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = core.ValidateType(args[2], types.Object); err != nil {
|
||||||
|
return values.None, errors.Wrap(err, "options")
|
||||||
|
}
|
||||||
|
|
||||||
|
doc, err = drivers.ToDocument(args[0])
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return values.None, errors.Wrap(err, "document")
|
||||||
|
}
|
||||||
|
|
||||||
|
selector = values.ToString(args[1])
|
||||||
|
o, err := toScrollOptions(args[2])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return values.None, errors.Wrap(err, "options")
|
||||||
|
}
|
||||||
|
|
||||||
|
opts = o
|
||||||
|
} else if len(args) == 2 {
|
||||||
|
if err = core.ValidateType(args[1], types.String, types.Object); err != nil {
|
||||||
return values.None, err
|
return values.None, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = core.ValidateType(args[1], types.String)
|
if args[1].Type() == types.String {
|
||||||
|
doc, err = drivers.ToDocument(args[0])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return values.None, errors.Wrap(err, "document")
|
||||||
|
}
|
||||||
|
|
||||||
|
selector = values.ToString(args[1])
|
||||||
|
} else {
|
||||||
|
el, err = drivers.ToElement(args[0])
|
||||||
|
o, err := toScrollOptions(args[1])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return values.None, errors.Wrap(err, "options")
|
||||||
|
}
|
||||||
|
|
||||||
|
opts = o
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
el, err = drivers.ToElement(args[0])
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return values.None, err
|
return values.None, errors.Wrap(err, "element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if doc != nil {
|
||||||
|
if selector != values.EmptyString {
|
||||||
|
return values.None, doc.ScrollBySelector(ctx, selector, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
selector := args[1].(values.String)
|
return values.None, doc.GetElement().ScrollIntoView(ctx, opts)
|
||||||
|
|
||||||
return values.None, doc.ScrollBySelector(ctx, selector)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = core.ValidateType(args[0], drivers.HTMLElementType)
|
if el != nil {
|
||||||
|
return values.None, el.ScrollIntoView(ctx, opts)
|
||||||
if err != nil {
|
|
||||||
return values.None, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetElement
|
return values.None, core.TypeError(
|
||||||
el, err := drivers.ToElement(args[0])
|
args[0].Type(),
|
||||||
|
drivers.HTMLPageType,
|
||||||
if err != nil {
|
drivers.HTMLDocumentType,
|
||||||
return values.None, err
|
drivers.HTMLElementType,
|
||||||
}
|
)
|
||||||
|
|
||||||
return values.None, el.ScrollIntoView(ctx)
|
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,9 @@ import (
|
|||||||
|
|
||||||
// SCROLL_TOP scrolls the document's window to its top.
|
// SCROLL_TOP scrolls the document's window to its top.
|
||||||
// @param doc (HTMLDocument) - Target document.
|
// @param doc (HTMLDocument) - Target document.
|
||||||
|
// @param options (ScrollOptions) - Scroll options. Optional.
|
||||||
func ScrollTop(ctx context.Context, args ...core.Value) (core.Value, error) {
|
func ScrollTop(ctx context.Context, args ...core.Value) (core.Value, error) {
|
||||||
err := core.ValidateArgs(args, 1, 1)
|
err := core.ValidateArgs(args, 1, 2)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return values.None, err
|
return values.None, err
|
||||||
@ -23,5 +24,15 @@ func ScrollTop(ctx context.Context, args ...core.Value) (core.Value, error) {
|
|||||||
return values.None, err
|
return values.None, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return values.None, doc.ScrollTop(ctx)
|
var opts drivers.ScrollOptions
|
||||||
|
|
||||||
|
if len(args) > 1 {
|
||||||
|
opts, err = toScrollOptions(args[1])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return values.None, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return values.None, doc.ScrollTop(ctx, opts)
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,9 @@ import (
|
|||||||
// @param doc (HTMLDocument) - HTML document.
|
// @param doc (HTMLDocument) - HTML document.
|
||||||
// @param x (Int|Float) - X coordinate.
|
// @param x (Int|Float) - X coordinate.
|
||||||
// @param y (Int|Float) - Y coordinate.
|
// @param y (Int|Float) - Y coordinate.
|
||||||
|
// @param options (ScrollOptions) - Scroll options. Optional.
|
||||||
func ScrollXY(ctx context.Context, args ...core.Value) (core.Value, error) {
|
func ScrollXY(ctx context.Context, args ...core.Value) (core.Value, error) {
|
||||||
err := core.ValidateArgs(args, 3, 3)
|
err := core.ValidateArgs(args, 3, 4)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return values.None, err
|
return values.None, err
|
||||||
@ -41,5 +42,15 @@ func ScrollXY(ctx context.Context, args ...core.Value) (core.Value, error) {
|
|||||||
x := values.ToFloat(args[1])
|
x := values.ToFloat(args[1])
|
||||||
y := values.ToFloat(args[2])
|
y := values.ToFloat(args[2])
|
||||||
|
|
||||||
return values.None, doc.ScrollByXY(ctx, x, y)
|
var opts drivers.ScrollOptions
|
||||||
|
|
||||||
|
if len(args) > 3 {
|
||||||
|
opts, err = toScrollOptions(args[3])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return values.None, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return values.None, doc.ScrollByXY(ctx, x, y, opts)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user