-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy patheventhandler.go
More file actions
105 lines (89 loc) · 2.62 KB
/
eventhandler.go
File metadata and controls
105 lines (89 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package jaws
import (
"errors"
"fmt"
"reflect"
"github.com/linkdata/jaws/lib/what"
)
// ErrEventHandlerPanic is returned when an event handler panics.
var ErrEventHandlerPanic errEventHandlerPanic
type errEventHandlerPanic struct {
Type reflect.Type
Value any
}
func (e errEventHandlerPanic) Error() string {
return fmt.Sprintf("jaws: %v panic: %v", e.Type, e.Value)
}
func (errEventHandlerPanic) Is(target error) bool {
return target == ErrEventHandlerPanic
}
func (e errEventHandlerPanic) Unwrap() error {
if err, ok := e.Value.(error); ok {
return err
}
return nil
}
// InputHandler handles input events sent from the browser.
type InputHandler interface {
JawsInput(e *Element, val string) (err error)
}
type errEventUnhandled struct{}
func (errEventUnhandled) Error() string {
return "event unhandled"
}
// ErrEventUnhandled returned by JawsInput(), JawsClick() or
// JawsContextMenu() causes the next available handler to be invoked.
var ErrEventUnhandled = errEventUnhandled{}
// InputFn is the signature of an input handling function to be called when JaWS receives
// an input, hook or set message from Javascript via the WebSocket connection.
type InputFn = func(e *Element, val string) (err error)
func callInputHandler(obj any, e *Element, val string) (err error) {
if h, ok := obj.(InputHandler); ok {
return h.JawsInput(e, val)
}
if fn, ok := obj.(InputFn); ok {
return fn(e, val)
}
return ErrEventUnhandled
}
func callEventHandler(obj any, e *Element, wht what.What, val string) (err error) {
err = ErrEventUnhandled
switch wht {
case what.Click, what.ContextMenu:
var clk Click
var ok bool
if clk, _, ok = parseClickData(val); ok {
if wht == what.Click {
if h, ok := obj.(ClickHandler); ok {
err = h.JawsClick(e, clk)
}
} else if h, ok := obj.(ContextMenuHandler); ok {
err = h.JawsContextMenu(e, clk)
}
}
case what.Input, what.Hook, what.Set:
err = callInputHandler(obj, e, val)
}
return
}
func callEventHandlers(ui any, e *Element, wht what.What, val string) (err error) {
for i := len(e.handlers) - 1; i >= 0; i-- {
if err = callEventHandler(e.handlers[i], e, wht, val); !errors.Is(err, ErrEventUnhandled) {
return
}
}
return callEventHandler(ui, e, wht, val)
}
// CallEventHandlers calls the event handlers for the given Element.
// Recovers from panics in user-provided handlers, returning them as errors.
func CallEventHandlers(ui any, e *Element, wht what.What, val string) (err error) {
defer func() {
if x := recover(); x != nil {
err = errEventHandlerPanic{
Type: reflect.TypeOf(ui),
Value: x,
}
}
}()
return callEventHandlers(ui, e, wht, val)
}