mirror of
https://github.com/wavetermdev/wails.git
synced 2026-08-05 13:53:43 -07:00
Improved window parameter handling
This commit is contained in:
@@ -308,7 +308,7 @@ func (b *Bindings) getMethods(value interface{}, isPlugin bool) ([]*BoundMethod,
|
||||
var errorType = reflect.TypeFor[error]()
|
||||
|
||||
// Call will attempt to call this bound method with the given args
|
||||
func (b *BoundMethod) Call(ctx context.Context, args []json.RawMessage) (returnValue interface{}, err error) {
|
||||
func (b *BoundMethod) Call(ctx context.Context, window Window, args []json.RawMessage) (returnValue interface{}, err error) {
|
||||
// Use a defer statement to capture panics
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@@ -333,14 +333,8 @@ func (b *BoundMethod) Call(ctx context.Context, args []json.RawMessage) (returnV
|
||||
argCount++
|
||||
}
|
||||
|
||||
if argCount != len(b.Inputs) {
|
||||
err = fmt.Errorf("%s expects %d arguments, received %d", b.Name, len(b.Inputs), argCount)
|
||||
return
|
||||
}
|
||||
|
||||
// Convert inputs to values of appropriate type
|
||||
|
||||
callArgs := make([]reflect.Value, argCount)
|
||||
callArgs := make([]reflect.Value, len(b.Inputs))
|
||||
base := 0
|
||||
|
||||
if b.needsContext {
|
||||
@@ -348,6 +342,23 @@ func (b *BoundMethod) Call(ctx context.Context, args []json.RawMessage) (returnV
|
||||
base++
|
||||
}
|
||||
|
||||
firstArgIsWindow := len(b.Inputs) > 0 && b.Inputs[0].ReflectType == reflect.TypeFor[Window]()
|
||||
secondArgIsWindow := len(b.Inputs) > 1 && b.Inputs[1].ReflectType == reflect.TypeFor[Window]()
|
||||
if secondArgIsWindow && !b.needsContext {
|
||||
return nil, fmt.Errorf("second argument is a Window but first argument is not a context")
|
||||
}
|
||||
if firstArgIsWindow || (b.needsContext && secondArgIsWindow) {
|
||||
// Create a reflect.Value from the window interface
|
||||
callArgs[base] = reflect.ValueOf(window)
|
||||
base++
|
||||
argCount++
|
||||
}
|
||||
|
||||
if argCount != len(b.Inputs) {
|
||||
err = fmt.Errorf("%s expects %d arguments, received %d", b.Name, len(b.Inputs), argCount)
|
||||
return
|
||||
}
|
||||
|
||||
// Iterate over given arguments
|
||||
for index, arg := range args {
|
||||
value := reflect.New(b.Inputs[base+index].ReflectType)
|
||||
|
||||
@@ -52,6 +52,27 @@ func (t *TestService) Slice(a []int) []int {
|
||||
return a
|
||||
}
|
||||
|
||||
func (t *TestService) WithWindow(window application.Window, s string) string {
|
||||
_ = window
|
||||
return s
|
||||
}
|
||||
|
||||
func (t *TestService) WithContext(ctx context.Context, s string) string {
|
||||
_ = ctx
|
||||
return s
|
||||
}
|
||||
|
||||
func (t *TestService) WithContextAndWindow(ctx context.Context, window application.Window, s string) string {
|
||||
_ = ctx
|
||||
_ = window
|
||||
return s
|
||||
}
|
||||
|
||||
func (t *TestService) WithBadWindow(s string, window application.Window) string {
|
||||
_ = window
|
||||
return s
|
||||
}
|
||||
|
||||
func newArgs(jsonArgs ...string) []json.RawMessage {
|
||||
args := []json.RawMessage{}
|
||||
|
||||
@@ -64,11 +85,12 @@ func newArgs(jsonArgs ...string) []json.RawMessage {
|
||||
func TestBoundMethodCall(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
method string
|
||||
args []json.RawMessage
|
||||
err error
|
||||
expected interface{}
|
||||
name string
|
||||
method string
|
||||
args []json.RawMessage
|
||||
wantWindow bool
|
||||
err error
|
||||
expected interface{}
|
||||
}{
|
||||
{
|
||||
name: "nil",
|
||||
@@ -154,10 +176,41 @@ func TestBoundMethodCall(t *testing.T) {
|
||||
err: nil,
|
||||
expected: []int{1, 2, 3},
|
||||
},
|
||||
{
|
||||
name: "with window",
|
||||
method: "WithWindow",
|
||||
args: newArgs(`"foo"`),
|
||||
wantWindow: true,
|
||||
err: nil,
|
||||
expected: "foo",
|
||||
},
|
||||
{
|
||||
name: "with context",
|
||||
method: "WithContext",
|
||||
args: newArgs(`"foo"`),
|
||||
err: nil,
|
||||
expected: "foo",
|
||||
},
|
||||
{
|
||||
name: "with context and window",
|
||||
method: "WithContextAndWindow",
|
||||
args: newArgs(`"foo"`),
|
||||
wantWindow: true,
|
||||
err: nil,
|
||||
expected: "foo",
|
||||
},
|
||||
{
|
||||
name: "with bad window",
|
||||
method: "WithBadWindow",
|
||||
args: newArgs(`"foo"`),
|
||||
wantWindow: true,
|
||||
err: errors.New("second argument is a Window but first argument is not a context"),
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
// init globalApplication
|
||||
_ = application.New(application.Options{})
|
||||
app := application.New(application.Options{})
|
||||
|
||||
bindings, err := application.NewBindings(
|
||||
[]any{
|
||||
@@ -180,8 +233,12 @@ func TestBoundMethodCall(t *testing.T) {
|
||||
if method == nil {
|
||||
t.Fatalf("bound method not found: %s", callOptions.Name())
|
||||
}
|
||||
var window application.Window
|
||||
if tt.wantWindow {
|
||||
window = app.NewWebviewWindow()
|
||||
}
|
||||
|
||||
result, err := method.Call(context.TODO(), tt.args)
|
||||
result, err := method.Call(context.TODO(), window, tt.args)
|
||||
if tt.err != err && (tt.err == nil || err == nil || !strings.Contains(err.Error(), tt.err.Error())) {
|
||||
t.Fatalf("error: %v, expected error: %v", err, tt.err)
|
||||
}
|
||||
|
||||
@@ -104,14 +104,7 @@ func (m *MessageProcessor) processCallMethod(method int, rw http.ResponseWriter,
|
||||
m.l.Unlock()
|
||||
}()
|
||||
|
||||
// Check if the first bound method parameter is a Window interface
|
||||
if len(boundMethod.Inputs) > 0 {
|
||||
if boundMethod.Inputs[0].ReflectType.String() == "application.Window" {
|
||||
// Prepend the options.Args with the current window
|
||||
options.Args = append([]interface{}{window}, options.Args...)
|
||||
}
|
||||
}
|
||||
result, err := boundMethod.Call(ctx, options.Args)
|
||||
result, err := boundMethod.Call(ctx, window, options.Args)
|
||||
if err != nil {
|
||||
m.callErrorCallback(window, "Error calling method: %s", callID, err)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user