123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- package chromedp
- import (
- "context"
- "encoding/json"
- "github.com/chromedp/cdproto/runtime"
- )
- // CallAction are actions that calls a JavaScript function using
- // runtime.CallFunctionOn.
- type CallAction Action
- // CallFunctionOn is an action to call a JavaScript function, unmarshaling
- // the result of the function to res.
- //
- // The handling of res is the same as that of Evaluate.
- //
- // Do not call the following methods on runtime.CallFunctionOnParams:
- // - WithReturnByValue: it will be set depending on the type of res;
- // - WithArguments: pass the arguments with args instead.
- //
- // Note: any exception encountered will be returned as an error.
- func CallFunctionOn(functionDeclaration string, res interface{}, opt CallOption, args ...interface{}) CallAction {
- return ActionFunc(func(ctx context.Context) error {
- _, err := callFunctionOn(ctx, functionDeclaration, res, opt, args...)
- return err
- })
- }
- func callFunctionOn(ctx context.Context, functionDeclaration string, res interface{}, opt CallOption, args ...interface{}) (*runtime.RemoteObject, error) {
- // set up parameters
- p := runtime.CallFunctionOn(functionDeclaration).
- WithSilent(true)
- switch res.(type) {
- case **runtime.RemoteObject:
- default:
- p = p.WithReturnByValue(true)
- }
- // apply opt
- if opt != nil {
- p = opt(p)
- }
- // arguments
- if len(args) > 0 {
- ea := &errAppender{args: make([]*runtime.CallArgument, 0, len(args))}
- for _, arg := range args {
- ea.append(arg)
- }
- if ea.err != nil {
- return nil, ea.err
- }
- p = p.WithArguments(ea.args)
- }
- // call
- v, exp, err := p.Do(ctx)
- if err != nil {
- return nil, err
- }
- if exp != nil {
- return nil, exp
- }
- return v, parseRemoteObject(v, res)
- }
- // CallOption is a function to modify the runtime.CallFunctionOnParams
- // to provide more information.
- type CallOption = func(params *runtime.CallFunctionOnParams) *runtime.CallFunctionOnParams
- // errAppender is to help accumulating the arguments and simplifying error checks.
- //
- // see https://blog.golang.org/errors-are-values
- type errAppender struct {
- args []*runtime.CallArgument
- err error
- }
- // append method calls the json.Marshal method to marshal the value and appends it to the slice.
- // It records the first error for future reference.
- // As soon as an error occurs, the append method becomes a no-op but the error value is saved.
- func (ea *errAppender) append(v interface{}) {
- if ea.err != nil {
- return
- }
- var b []byte
- b, ea.err = json.Marshal(v)
- ea.args = append(ea.args, &runtime.CallArgument{Value: b})
- }
|