events.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. package dom
  2. import (
  3. "time"
  4. "github.com/gopherjs/gopherjs/js"
  5. )
  6. func WrapEvent(o *js.Object) Event {
  7. return wrapEvent(o)
  8. }
  9. func wrapEvent(o *js.Object) Event {
  10. if o == nil || o == js.Undefined {
  11. return nil
  12. }
  13. ev := &BasicEvent{o}
  14. c := o.Get("constructor")
  15. switch c {
  16. case js.Global.Get("AnimationEvent"):
  17. return &AnimationEvent{ev}
  18. case js.Global.Get("AudioProcessingEvent"):
  19. return &AudioProcessingEvent{ev}
  20. case js.Global.Get("BeforeInputEvent"):
  21. return &BeforeInputEvent{ev}
  22. case js.Global.Get("BeforeUnloadEvent"):
  23. return &BeforeUnloadEvent{ev}
  24. case js.Global.Get("BlobEvent"):
  25. return &BlobEvent{ev}
  26. case js.Global.Get("ClipboardEvent"):
  27. return &ClipboardEvent{ev}
  28. case js.Global.Get("CloseEvent"):
  29. return &CloseEvent{BasicEvent: ev}
  30. case js.Global.Get("CompositionEvent"):
  31. return &CompositionEvent{ev}
  32. case js.Global.Get("CSSFontFaceLoadEvent"):
  33. return &CSSFontFaceLoadEvent{ev}
  34. case js.Global.Get("CustomEvent"):
  35. return &CustomEvent{ev}
  36. case js.Global.Get("DeviceLightEvent"):
  37. return &DeviceLightEvent{ev}
  38. case js.Global.Get("DeviceMotionEvent"):
  39. return &DeviceMotionEvent{ev}
  40. case js.Global.Get("DeviceOrientationEvent"):
  41. return &DeviceOrientationEvent{ev}
  42. case js.Global.Get("DeviceProximityEvent"):
  43. return &DeviceProximityEvent{ev}
  44. case js.Global.Get("DOMTransactionEvent"):
  45. return &DOMTransactionEvent{ev}
  46. case js.Global.Get("DragEvent"):
  47. return &DragEvent{ev}
  48. case js.Global.Get("EditingBeforeInputEvent"):
  49. return &EditingBeforeInputEvent{ev}
  50. case js.Global.Get("ErrorEvent"):
  51. return &ErrorEvent{ev}
  52. case js.Global.Get("FocusEvent"):
  53. return &FocusEvent{ev}
  54. case js.Global.Get("GamepadEvent"):
  55. return &GamepadEvent{ev}
  56. case js.Global.Get("HashChangeEvent"):
  57. return &HashChangeEvent{ev}
  58. case js.Global.Get("IDBVersionChangeEvent"):
  59. return &IDBVersionChangeEvent{ev}
  60. case js.Global.Get("KeyboardEvent"):
  61. return &KeyboardEvent{BasicEvent: ev}
  62. case js.Global.Get("MediaStreamEvent"):
  63. return &MediaStreamEvent{ev}
  64. case js.Global.Get("MessageEvent"):
  65. return &MessageEvent{BasicEvent: ev}
  66. case js.Global.Get("MouseEvent"):
  67. return &MouseEvent{UIEvent: &UIEvent{ev}}
  68. case js.Global.Get("MutationEvent"):
  69. return &MutationEvent{ev}
  70. case js.Global.Get("OfflineAudioCompletionEvent"):
  71. return &OfflineAudioCompletionEvent{ev}
  72. case js.Global.Get("PageTransitionEvent"):
  73. return &PageTransitionEvent{ev}
  74. case js.Global.Get("PointerEvent"):
  75. return &PointerEvent{&MouseEvent{UIEvent: &UIEvent{ev}}}
  76. case js.Global.Get("PopStateEvent"):
  77. return &PopStateEvent{ev}
  78. case js.Global.Get("ProgressEvent"):
  79. return &ProgressEvent{ev}
  80. case js.Global.Get("RelatedEvent"):
  81. return &RelatedEvent{ev}
  82. case js.Global.Get("RTCPeerConnectionIceEvent"):
  83. return &RTCPeerConnectionIceEvent{ev}
  84. case js.Global.Get("SensorEvent"):
  85. return &SensorEvent{ev}
  86. case js.Global.Get("StorageEvent"):
  87. return &StorageEvent{ev}
  88. case js.Global.Get("SVGEvent"):
  89. return &SVGEvent{ev}
  90. case js.Global.Get("SVGZoomEvent"):
  91. return &SVGZoomEvent{ev}
  92. case js.Global.Get("TimeEvent"):
  93. return &TimeEvent{ev}
  94. case js.Global.Get("TouchEvent"):
  95. return &TouchEvent{BasicEvent: ev}
  96. case js.Global.Get("TrackEvent"):
  97. return &TrackEvent{ev}
  98. case js.Global.Get("TransitionEvent"):
  99. return &TransitionEvent{ev}
  100. case js.Global.Get("UIEvent"):
  101. return &UIEvent{ev}
  102. case js.Global.Get("UserProximityEvent"):
  103. return &UserProximityEvent{ev}
  104. case js.Global.Get("WheelEvent"):
  105. return &WheelEvent{MouseEvent: &MouseEvent{UIEvent: &UIEvent{ev}}}
  106. default:
  107. return ev
  108. }
  109. }
  110. const (
  111. EvPhaseNone = 0
  112. EvPhaseCapturing = 1
  113. EvPhaseAtTarget = 2
  114. EvPhaseBubbling = 3
  115. )
  116. type Event interface {
  117. Bubbles() bool
  118. Cancelable() bool
  119. CurrentTarget() Element
  120. DefaultPrevented() bool
  121. EventPhase() int
  122. Target() Element
  123. Timestamp() time.Time
  124. Type() string
  125. PreventDefault()
  126. StopImmediatePropagation()
  127. StopPropagation()
  128. Underlying() *js.Object
  129. }
  130. // Type BasicEvent implements the Event interface and is embedded by
  131. // concrete event types.
  132. type BasicEvent struct{ *js.Object }
  133. type EventOptions struct {
  134. Bubbles bool
  135. Cancelable bool
  136. }
  137. func CreateEvent(typ string, opts EventOptions) *BasicEvent {
  138. var event = js.Global.Get("Event").New(typ, js.M{
  139. "bubbles": opts.Bubbles,
  140. "cancelable": opts.Cancelable,
  141. })
  142. return &BasicEvent{event}
  143. }
  144. func (ev *BasicEvent) Bubbles() bool {
  145. return ev.Get("bubbles").Bool()
  146. }
  147. func (ev *BasicEvent) Cancelable() bool {
  148. return ev.Get("cancelable").Bool()
  149. }
  150. func (ev *BasicEvent) CurrentTarget() Element {
  151. return wrapElement(ev.Get("currentTarget"))
  152. }
  153. func (ev *BasicEvent) DefaultPrevented() bool {
  154. return ev.Get("defaultPrevented").Bool()
  155. }
  156. func (ev *BasicEvent) EventPhase() int {
  157. return ev.Get("eventPhase").Int()
  158. }
  159. func (ev *BasicEvent) Target() Element {
  160. return wrapElement(ev.Get("target"))
  161. }
  162. func (ev *BasicEvent) Timestamp() time.Time {
  163. ms := ev.Get("timeStamp").Int()
  164. s := ms / 1000
  165. ns := (ms % 1000 * 1e6)
  166. return time.Unix(int64(s), int64(ns))
  167. }
  168. func (ev *BasicEvent) Type() string {
  169. return ev.Get("type").String()
  170. }
  171. func (ev *BasicEvent) PreventDefault() {
  172. ev.Call("preventDefault")
  173. }
  174. func (ev *BasicEvent) StopImmediatePropagation() {
  175. ev.Call("stopImmediatePropagation")
  176. }
  177. func (ev *BasicEvent) StopPropagation() {
  178. ev.Call("stopPropagation")
  179. }
  180. func (ev *BasicEvent) Underlying() *js.Object {
  181. return ev.Object
  182. }
  183. type AnimationEvent struct{ *BasicEvent }
  184. type AudioProcessingEvent struct{ *BasicEvent }
  185. type BeforeInputEvent struct{ *BasicEvent }
  186. type BeforeUnloadEvent struct{ *BasicEvent }
  187. type BlobEvent struct{ *BasicEvent }
  188. type ClipboardEvent struct{ *BasicEvent }
  189. type CloseEvent struct {
  190. *BasicEvent
  191. Code int `js:"code"`
  192. Reason string `js:"reason"`
  193. WasClean bool `js:"wasClean"`
  194. }
  195. type CompositionEvent struct{ *BasicEvent }
  196. type CSSFontFaceLoadEvent struct{ *BasicEvent }
  197. type CustomEvent struct{ *BasicEvent }
  198. type DeviceLightEvent struct{ *BasicEvent }
  199. type DeviceMotionEvent struct{ *BasicEvent }
  200. type DeviceOrientationEvent struct{ *BasicEvent }
  201. type DeviceProximityEvent struct{ *BasicEvent }
  202. type DOMTransactionEvent struct{ *BasicEvent }
  203. type DragEvent struct{ *BasicEvent }
  204. type EditingBeforeInputEvent struct{ *BasicEvent }
  205. type ErrorEvent struct{ *BasicEvent }
  206. type FocusEvent struct{ *BasicEvent }
  207. func (ev *FocusEvent) RelatedTarget() Element {
  208. return wrapElement(ev.Get("relatedTarget"))
  209. }
  210. type GamepadEvent struct{ *BasicEvent }
  211. type HashChangeEvent struct{ *BasicEvent }
  212. type IDBVersionChangeEvent struct{ *BasicEvent }
  213. const (
  214. KeyLocationStandard = 0
  215. KeyLocationLeft = 1
  216. KeyLocationRight = 2
  217. KeyLocationNumpad = 3
  218. )
  219. type KeyboardEvent struct {
  220. *BasicEvent
  221. AltKey bool `js:"altKey"`
  222. CharCode int `js:"charCode"`
  223. CtrlKey bool `js:"ctrlKey"`
  224. Key string `js:"key"`
  225. KeyIdentifier string `js:"keyIdentifier"`
  226. KeyCode int `js:"keyCode"`
  227. Locale string `js:"locale"`
  228. Location int `js:"location"`
  229. KeyLocation int `js:"keyLocation"`
  230. MetaKey bool `js:"metaKey"`
  231. Repeat bool `js:"repeat"`
  232. ShiftKey bool `js:"shiftKey"`
  233. }
  234. func (ev *KeyboardEvent) ModifierState(mod string) bool {
  235. return ev.Call("getModifierState", mod).Bool()
  236. }
  237. type MediaStreamEvent struct{ *BasicEvent }
  238. type MessageEvent struct {
  239. *BasicEvent
  240. Data *js.Object `js:"data"`
  241. }
  242. type MouseEvent struct {
  243. *UIEvent
  244. AltKey bool `js:"altKey"`
  245. Button int `js:"button"`
  246. ClientX int `js:"clientX"`
  247. ClientY int `js:"clientY"`
  248. CtrlKey bool `js:"ctrlKey"`
  249. MetaKey bool `js:"metaKey"`
  250. MovementX int `js:"movementX"`
  251. MovementY int `js:"movementY"`
  252. ScreenX int `js:"screenX"`
  253. ScreenY int `js:"screenY"`
  254. ShiftKey bool `js:"shiftKey"`
  255. }
  256. func (ev *MouseEvent) RelatedTarget() Element {
  257. return wrapElement(ev.Get("relatedTarget"))
  258. }
  259. func (ev *MouseEvent) ModifierState(mod string) bool {
  260. return ev.Call("getModifierState", mod).Bool()
  261. }
  262. type MutationEvent struct{ *BasicEvent }
  263. type OfflineAudioCompletionEvent struct{ *BasicEvent }
  264. type PageTransitionEvent struct{ *BasicEvent }
  265. type PointerEvent struct{ *MouseEvent }
  266. type PopStateEvent struct{ *BasicEvent }
  267. type ProgressEvent struct{ *BasicEvent }
  268. type RelatedEvent struct{ *BasicEvent }
  269. type RTCPeerConnectionIceEvent struct{ *BasicEvent }
  270. type SensorEvent struct{ *BasicEvent }
  271. type StorageEvent struct{ *BasicEvent }
  272. type SVGEvent struct{ *BasicEvent }
  273. type SVGZoomEvent struct{ *BasicEvent }
  274. type TimeEvent struct{ *BasicEvent }
  275. // TouchEvent represents an event sent when the state of contacts with a touch-sensitive
  276. // surface changes. This surface can be a touch screen or trackpad, for example. The event
  277. // can describe one or more points of contact with the screen and includes support for
  278. // detecting movement, addition and removal of contact points, and so forth.
  279. //
  280. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent.
  281. type TouchEvent struct {
  282. *BasicEvent
  283. AltKey bool `js:"altKey"`
  284. CtrlKey bool `js:"ctrlKey"`
  285. MetaKey bool `js:"metaKey"`
  286. ShiftKey bool `js:"shiftKey"`
  287. }
  288. // ChangedTouches lists all individual points of contact whose states changed between
  289. // the previous touch event and this one.
  290. //
  291. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/changedTouches.
  292. func (ev *TouchEvent) ChangedTouches() []*Touch {
  293. return touchListToTouches(ev.Get("changedTouches"))
  294. }
  295. // TargetTouches lists all points of contact that are both currently in contact with the
  296. // touch surface and were also started on the same element that is the target of the event.
  297. //
  298. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/targetTouches.
  299. func (ev *TouchEvent) TargetTouches() []*Touch {
  300. return touchListToTouches(ev.Get("targetTouches"))
  301. }
  302. // Touches lists all current points of contact with the surface, regardless of target
  303. // or changed status.
  304. //
  305. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches.
  306. func (ev *TouchEvent) Touches() []*Touch {
  307. return touchListToTouches(ev.Get("touches"))
  308. }
  309. func touchListToTouches(tl *js.Object) []*Touch {
  310. out := make([]*Touch, tl.Length())
  311. for i := range out {
  312. out[i] = &Touch{Object: tl.Index(i)}
  313. }
  314. return out
  315. }
  316. // Touch represents a single contact point on a touch-sensitive device. The contact point
  317. // is commonly a finger or stylus and the device may be a touchscreen or trackpad.
  318. //
  319. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/Touch.
  320. type Touch struct {
  321. *js.Object
  322. Identifier int `js:"identifier"`
  323. ScreenX float64 `js:"screenX"`
  324. ScreenY float64 `js:"screenY"`
  325. ClientX float64 `js:"clientX"`
  326. ClientY float64 `js:"clientY"`
  327. PageX float64 `js:"pageX"`
  328. PageY float64 `js:"pageY"`
  329. RadiusX float64 `js:"radiusX"`
  330. RadiusY float64 `js:"radiusY"`
  331. RotationAngle float64 `js:"rotationAngle"`
  332. Force float64 `js:"force"`
  333. }
  334. // Target returns the Element on which the touch point started when it was first placed
  335. // on the surface, even if the touch point has since moved outside the interactive area
  336. // of that element or even been removed from the document.
  337. //
  338. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/Touch/target.
  339. func (t *Touch) Target() Element {
  340. return wrapElement(t.Get("target"))
  341. }
  342. type TrackEvent struct{ *BasicEvent }
  343. type TransitionEvent struct{ *BasicEvent }
  344. type UIEvent struct{ *BasicEvent }
  345. type UserProximityEvent struct{ *BasicEvent }
  346. const (
  347. DeltaPixel = 0
  348. DeltaLine = 1
  349. DeltaPage = 2
  350. )
  351. type WheelEvent struct {
  352. *MouseEvent
  353. DeltaX float64 `js:"deltaX"`
  354. DeltaY float64 `js:"deltaY"`
  355. DeltaZ float64 `js:"deltaZ"`
  356. DeltaMode int `js:"deltaMode"`
  357. }
  358. type EventTarget interface {
  359. // AddEventListener adds a new event listener and returns the
  360. // wrapper function it generated. If using RemoveEventListener,
  361. // that wrapper has to be used.
  362. AddEventListener(typ string, useCapture bool, listener func(Event)) func(*js.Object)
  363. RemoveEventListener(typ string, useCapture bool, listener func(*js.Object))
  364. DispatchEvent(event Event) bool
  365. }