events.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  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. OffsetX float64 `js:"offsetX"`
  253. OffsetY float64 `js:"offsetY"`
  254. ScreenX int `js:"screenX"`
  255. ScreenY int `js:"screenY"`
  256. ShiftKey bool `js:"shiftKey"`
  257. }
  258. func (ev *MouseEvent) RelatedTarget() Element {
  259. return wrapElement(ev.Get("relatedTarget"))
  260. }
  261. func (ev *MouseEvent) ModifierState(mod string) bool {
  262. return ev.Call("getModifierState", mod).Bool()
  263. }
  264. type MutationEvent struct{ *BasicEvent }
  265. type OfflineAudioCompletionEvent struct{ *BasicEvent }
  266. type PageTransitionEvent struct{ *BasicEvent }
  267. type PointerEvent struct{ *MouseEvent }
  268. type PopStateEvent struct{ *BasicEvent }
  269. type ProgressEvent struct{ *BasicEvent }
  270. type RelatedEvent struct{ *BasicEvent }
  271. type RTCPeerConnectionIceEvent struct{ *BasicEvent }
  272. type SensorEvent struct{ *BasicEvent }
  273. type StorageEvent struct{ *BasicEvent }
  274. type SVGEvent struct{ *BasicEvent }
  275. type SVGZoomEvent struct{ *BasicEvent }
  276. type TimeEvent struct{ *BasicEvent }
  277. // TouchEvent represents an event sent when the state of contacts with a touch-sensitive
  278. // surface changes. This surface can be a touch screen or trackpad, for example. The event
  279. // can describe one or more points of contact with the screen and includes support for
  280. // detecting movement, addition and removal of contact points, and so forth.
  281. //
  282. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent.
  283. type TouchEvent struct {
  284. *BasicEvent
  285. AltKey bool `js:"altKey"`
  286. CtrlKey bool `js:"ctrlKey"`
  287. MetaKey bool `js:"metaKey"`
  288. ShiftKey bool `js:"shiftKey"`
  289. }
  290. // ChangedTouches lists all individual points of contact whose states changed between
  291. // the previous touch event and this one.
  292. //
  293. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/changedTouches.
  294. func (ev *TouchEvent) ChangedTouches() []*Touch {
  295. return touchListToTouches(ev.Get("changedTouches"))
  296. }
  297. // TargetTouches lists all points of contact that are both currently in contact with the
  298. // touch surface and were also started on the same element that is the target of the event.
  299. //
  300. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/targetTouches.
  301. func (ev *TouchEvent) TargetTouches() []*Touch {
  302. return touchListToTouches(ev.Get("targetTouches"))
  303. }
  304. // Touches lists all current points of contact with the surface, regardless of target
  305. // or changed status.
  306. //
  307. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches.
  308. func (ev *TouchEvent) Touches() []*Touch {
  309. return touchListToTouches(ev.Get("touches"))
  310. }
  311. func touchListToTouches(tl *js.Object) []*Touch {
  312. out := make([]*Touch, tl.Length())
  313. for i := range out {
  314. out[i] = &Touch{Object: tl.Index(i)}
  315. }
  316. return out
  317. }
  318. // Touch represents a single contact point on a touch-sensitive device. The contact point
  319. // is commonly a finger or stylus and the device may be a touchscreen or trackpad.
  320. //
  321. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/Touch.
  322. type Touch struct {
  323. *js.Object
  324. Identifier int `js:"identifier"`
  325. ScreenX float64 `js:"screenX"`
  326. ScreenY float64 `js:"screenY"`
  327. ClientX float64 `js:"clientX"`
  328. ClientY float64 `js:"clientY"`
  329. PageX float64 `js:"pageX"`
  330. PageY float64 `js:"pageY"`
  331. RadiusX float64 `js:"radiusX"`
  332. RadiusY float64 `js:"radiusY"`
  333. RotationAngle float64 `js:"rotationAngle"`
  334. Force float64 `js:"force"`
  335. }
  336. // Target returns the Element on which the touch point started when it was first placed
  337. // on the surface, even if the touch point has since moved outside the interactive area
  338. // of that element or even been removed from the document.
  339. //
  340. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/Touch/target.
  341. func (t *Touch) Target() Element {
  342. return wrapElement(t.Get("target"))
  343. }
  344. type TrackEvent struct{ *BasicEvent }
  345. type TransitionEvent struct{ *BasicEvent }
  346. type UIEvent struct{ *BasicEvent }
  347. type UserProximityEvent struct{ *BasicEvent }
  348. const (
  349. DeltaPixel = 0
  350. DeltaLine = 1
  351. DeltaPage = 2
  352. )
  353. type WheelEvent struct {
  354. *MouseEvent
  355. DeltaX float64 `js:"deltaX"`
  356. DeltaY float64 `js:"deltaY"`
  357. DeltaZ float64 `js:"deltaZ"`
  358. DeltaMode int `js:"deltaMode"`
  359. }
  360. type EventTarget interface {
  361. // AddEventListener adds a new event listener and returns the
  362. // wrapper function it generated. If using RemoveEventListener,
  363. // that wrapper has to be used.
  364. AddEventListener(typ string, useCapture bool, listener func(Event)) func(*js.Object)
  365. RemoveEventListener(typ string, useCapture bool, listener func(*js.Object))
  366. DispatchEvent(event Event) bool
  367. }