events.go 12 KB

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