(un)safely casting a Mouse.t

I’m using jsoo-react + Brr, and running into the following issue:


    let onMouseDown (e : React.Event.Mouse.t) =

      // how to convert React.Event.Mouse.t to Brr.Ev.Mouse.t

      let start_x = Brr.Ev.Mouse.client_x e in
      let start_y = Brr.Ev.Mouse.client_y e in


The function takes a React.Event.Mouse.t because it is passed to an onMouseDown in jsoo-react .

However, the Brr.Ev.Mouse.* functions want a Brr.Ev.Mouse.t

Is there a way to tell jsoo/OCaml: trust me, this is a Brr.Ev.Mouse.t ?

It looks like React.Event.Mouse has those functions, might be easier to use those: jsoo-react/event.mli at 57f42ebf664235e01af136a789a24e57d05f884f · ml-in-barcelona/jsoo-react · GitHub

Failing that, you can probably rely on the fact that both libraries are wrapping the Javascript object and so you can just change the type using something like:

let brr_e : Brr.Ev.Mouse.t Brr.Ev.t = Brr.Ev.of_jv (Jv.repr e) in
let e = Brr.Ev.as_type brr_e in
...

Thanks, I was not aware these functions existed.

Two weird things:

  1. I must be using an outdated version of jsoo-react, as my (local) file looks different.

  2. For whatever reason, when I put the cursor on ‘React.Event.Mouse.t’ and hit goto-def, it jumps me to CommonApi.t , rather than Mouse.t ; I now (after you pointing it out) see the client_x client_y defined on Mouse.t now, but it threw me off as it jumped me into CommonApi.

module CommonApi = struct
  include
    [%js:
    type tag = Ojs.t
    type t = Ojs.t

    val t_of_js : Ojs.t -> t
    val t_to_js : t -> Ojs.t
    val bubbles : Ojs.t -> bool [@@js.get "bubbles"]
    val cancelable : t -> bool [@@js.get "cancelable"]
    val current_target : t -> Ojs.t [@@js.get "currentTarget"]
    (* Should return Dom.eventTarget *)

    val default_prevented : t -> bool [@@js.get "defaultPrevented"]
    val event_phase : t -> int [@@js.get "eventPhase"]
    val is_trusted : t -> bool [@@js.get "isTrusted"]
    val native_event : t -> Ojs.t [@@js.get "nativeEvent"]
    (* Should return Dom.event *)

    val prevent_default : t -> unit [@@js.call "preventDefault"]
    val is_default_prevented : t -> bool [@@js.call "isDefaultPrevented"]
    val stop_propagation : t -> unit [@@js.call "stopPropagation"]
    val is_propagation_stopped : t -> bool [@@js.call "isPropagationStopped"]
    val target : t -> Ojs.t [@@js.get "target"]
    (* Should return Dom.eventTarget *)

    val time_stamp : t -> float [@@js.get "timeStamp"]
    val type_ : t -> string [@@js.get "type"]
    val persist : t -> unit [@@js.call "persist"]]
end

module Synthetic = CommonApi

(* Cast any event type to the general synthetic type. This is safe, since synthetic is more general *)
external to_synthetic_event : 'a synthetic -> Synthetic.t = "%identity"

module Clipboard = struct
  include CommonApi
  include [%js: val clipboard_data : t -> Ojs.t [@@js.get "clipboardData"]]

  (* Should return Dom.dataTransfer *)
end

module Composition = struct
  include CommonApi
  include [%js: val data : t -> string [@@js.get "data"]]
end

module Keyboard = struct
  include CommonApi

  include
    [%js:
    val alt_key : t -> bool [@@js.get "altKey"]
    val char_code : t -> int [@@js.get "charCode"]
    val ctrl_key : t -> bool [@@js.get "ctrlKey"]
    val get_modifier_state : t -> string -> bool [@@js.call "getModifierState"]
    val key : t -> string [@@js.get "key"]
    val key_code : t -> int [@@js.get "keyCode"]
    val locale : t -> string [@@js.get "locale"]
    val location : t -> int [@@js.get "location"]
    val meta_key : t -> bool [@@js.get "metaKey"]
    val repeat : t -> bool [@@js.get "repeat"]
    val shift_key : t -> bool [@@js.get "shiftKey"]
    val which : t -> int [@@js.get "which"]]
end

module Focus = struct
  include CommonApi

  include
    [%js:
    val related_target : t -> Ojs.t option [@@js.get "relatedTarget"]]

  (* Should return Dom.eventTarget *)
end

module Form = struct
  include CommonApi
end

module Mouse = struct
  include CommonApi

  include
    [%js:
    val alt_key : t -> bool [@@js.get "altKey"]
    val button : t -> int [@@js.get "button"]
    val buttons : t -> int [@@js.get "buttons"]
    val client_x : t -> int [@@js.get "clientX"]
    val client_y : t -> int [@@js.get "clientY"]
    val ctrl_key : t -> bool [@@js.get "ctrlKey"]
    val get_modifier_state : t -> string -> bool [@@js.call "getModifierState"]
    val meta_key : t -> bool [@@js.get "metaKey"]
    val page_x : t -> int [@@js.get "pageX"]
    val page_y : t -> int [@@js.get "pageY"]
    val related_target : t -> Ojs.t option [@@js.get "relatedTarget"]

    (* Should return Dom.eventTarget *)

    val screen_x : t -> int [@@js.get "screenX"]
    val screen_y : t -> int [@@js.get "screenY"]
    val shift_key : t -> bool [@@js.get "shiftKey"]]
end