events.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  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. func (ev *ClipboardEvent) ClipboardData() *DataTransfer {
  190. return &DataTransfer{Object: ev.Get("clipboardData")}
  191. }
  192. type CloseEvent struct {
  193. *BasicEvent
  194. Code int `js:"code"`
  195. Reason string `js:"reason"`
  196. WasClean bool `js:"wasClean"`
  197. }
  198. type CompositionEvent struct{ *BasicEvent }
  199. type CSSFontFaceLoadEvent struct{ *BasicEvent }
  200. type CustomEvent struct{ *BasicEvent }
  201. type DeviceLightEvent struct{ *BasicEvent }
  202. type DeviceMotionEvent struct{ *BasicEvent }
  203. type DeviceOrientationEvent struct{ *BasicEvent }
  204. type DeviceProximityEvent struct{ *BasicEvent }
  205. type DOMTransactionEvent struct{ *BasicEvent }
  206. type DragEvent struct{ *BasicEvent }
  207. type EditingBeforeInputEvent struct{ *BasicEvent }
  208. type ErrorEvent struct{ *BasicEvent }
  209. type FocusEvent struct{ *BasicEvent }
  210. func (ev *FocusEvent) RelatedTarget() Element {
  211. return wrapElement(ev.Get("relatedTarget"))
  212. }
  213. type GamepadEvent struct{ *BasicEvent }
  214. type HashChangeEvent struct{ *BasicEvent }
  215. type IDBVersionChangeEvent struct{ *BasicEvent }
  216. const (
  217. KeyLocationStandard = 0
  218. KeyLocationLeft = 1
  219. KeyLocationRight = 2
  220. KeyLocationNumpad = 3
  221. )
  222. type KeyboardEvent struct {
  223. *BasicEvent
  224. AltKey bool `js:"altKey"`
  225. CharCode int `js:"charCode"`
  226. Code string `js:"code"`
  227. CtrlKey bool `js:"ctrlKey"`
  228. Key string `js:"key"`
  229. KeyIdentifier string `js:"keyIdentifier"`
  230. KeyCode int `js:"keyCode"`
  231. Locale string `js:"locale"`
  232. Location int `js:"location"`
  233. KeyLocation int `js:"keyLocation"`
  234. MetaKey bool `js:"metaKey"`
  235. Repeat bool `js:"repeat"`
  236. ShiftKey bool `js:"shiftKey"`
  237. }
  238. func (ev *KeyboardEvent) ModifierState(mod string) bool {
  239. return ev.Call("getModifierState", mod).Bool()
  240. }
  241. type MediaStreamEvent struct{ *BasicEvent }
  242. type MessageEvent struct {
  243. *BasicEvent
  244. Data *js.Object `js:"data"`
  245. }
  246. type MouseEvent struct {
  247. *UIEvent
  248. AltKey bool `js:"altKey"`
  249. Button int `js:"button"`
  250. Buttons int `js:"buttons"`
  251. ClientX int `js:"clientX"`
  252. ClientY int `js:"clientY"`
  253. CtrlKey bool `js:"ctrlKey"`
  254. MetaKey bool `js:"metaKey"`
  255. MovementX int `js:"movementX"`
  256. MovementY int `js:"movementY"`
  257. OffsetX float64 `js:"offsetX"`
  258. OffsetY float64 `js:"offsetY"`
  259. ScreenX int `js:"screenX"`
  260. ScreenY int `js:"screenY"`
  261. ShiftKey bool `js:"shiftKey"`
  262. }
  263. func (ev *MouseEvent) RelatedTarget() Element {
  264. return wrapElement(ev.Get("relatedTarget"))
  265. }
  266. func (ev *MouseEvent) ModifierState(mod string) bool {
  267. return ev.Call("getModifierState", mod).Bool()
  268. }
  269. type MutationEvent struct{ *BasicEvent }
  270. type OfflineAudioCompletionEvent struct{ *BasicEvent }
  271. type PageTransitionEvent struct{ *BasicEvent }
  272. type PointerEvent struct{ *MouseEvent }
  273. type PopStateEvent struct{ *BasicEvent }
  274. type ProgressEvent struct{ *BasicEvent }
  275. type RelatedEvent struct{ *BasicEvent }
  276. type RTCPeerConnectionIceEvent struct{ *BasicEvent }
  277. type SensorEvent struct{ *BasicEvent }
  278. type StorageEvent struct{ *BasicEvent }
  279. type SVGEvent struct{ *BasicEvent }
  280. type SVGZoomEvent struct{ *BasicEvent }
  281. type TimeEvent struct{ *BasicEvent }
  282. // TouchEvent represents an event sent when the state of contacts with a touch-sensitive
  283. // surface changes. This surface can be a touch screen or trackpad, for example. The event
  284. // can describe one or more points of contact with the screen and includes support for
  285. // detecting movement, addition and removal of contact points, and so forth.
  286. //
  287. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent.
  288. type TouchEvent struct {
  289. *BasicEvent
  290. AltKey bool `js:"altKey"`
  291. CtrlKey bool `js:"ctrlKey"`
  292. MetaKey bool `js:"metaKey"`
  293. ShiftKey bool `js:"shiftKey"`
  294. }
  295. // ChangedTouches lists all individual points of contact whose states changed between
  296. // the previous touch event and this one.
  297. //
  298. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/changedTouches.
  299. func (ev *TouchEvent) ChangedTouches() []*Touch {
  300. return touchListToTouches(ev.Get("changedTouches"))
  301. }
  302. // TargetTouches lists all points of contact that are both currently in contact with the
  303. // touch surface and were also started on the same element that is the target of the event.
  304. //
  305. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/targetTouches.
  306. func (ev *TouchEvent) TargetTouches() []*Touch {
  307. return touchListToTouches(ev.Get("targetTouches"))
  308. }
  309. // Touches lists all current points of contact with the surface, regardless of target
  310. // or changed status.
  311. //
  312. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches.
  313. func (ev *TouchEvent) Touches() []*Touch {
  314. return touchListToTouches(ev.Get("touches"))
  315. }
  316. func touchListToTouches(tl *js.Object) []*Touch {
  317. out := make([]*Touch, tl.Length())
  318. for i := range out {
  319. out[i] = &Touch{Object: tl.Index(i)}
  320. }
  321. return out
  322. }
  323. // Touch represents a single contact point on a touch-sensitive device. The contact point
  324. // is commonly a finger or stylus and the device may be a touchscreen or trackpad.
  325. //
  326. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/Touch.
  327. type Touch struct {
  328. *js.Object
  329. Identifier int `js:"identifier"`
  330. ScreenX float64 `js:"screenX"`
  331. ScreenY float64 `js:"screenY"`
  332. ClientX float64 `js:"clientX"`
  333. ClientY float64 `js:"clientY"`
  334. PageX float64 `js:"pageX"`
  335. PageY float64 `js:"pageY"`
  336. RadiusX float64 `js:"radiusX"`
  337. RadiusY float64 `js:"radiusY"`
  338. RotationAngle float64 `js:"rotationAngle"`
  339. Force float64 `js:"force"`
  340. }
  341. // Target returns the Element on which the touch point started when it was first placed
  342. // on the surface, even if the touch point has since moved outside the interactive area
  343. // of that element or even been removed from the document.
  344. //
  345. // Reference: https://developer.mozilla.org/en-US/docs/Web/API/Touch/target.
  346. func (t *Touch) Target() Element {
  347. return wrapElement(t.Get("target"))
  348. }
  349. type TrackEvent struct{ *BasicEvent }
  350. type TransitionEvent struct{ *BasicEvent }
  351. type UIEvent struct{ *BasicEvent }
  352. type UserProximityEvent struct{ *BasicEvent }
  353. const (
  354. DeltaPixel = 0
  355. DeltaLine = 1
  356. DeltaPage = 2
  357. )
  358. type WheelEvent struct {
  359. *MouseEvent
  360. DeltaX float64 `js:"deltaX"`
  361. DeltaY float64 `js:"deltaY"`
  362. DeltaZ float64 `js:"deltaZ"`
  363. DeltaMode int `js:"deltaMode"`
  364. }
  365. type EventTarget interface {
  366. // AddEventListener adds a new event listener and returns the
  367. // wrapper function it generated. If using RemoveEventListener,
  368. // that wrapper has to be used.
  369. AddEventListener(typ string, useCapture bool, listener func(Event)) func(*js.Object)
  370. RemoveEventListener(typ string, useCapture bool, listener func(*js.Object))
  371. DispatchEvent(event Event) bool
  372. }