/tryocaml/js_of_ocaml-patched/lib/js.ml

http://github.com/cago/tryocaml · OCaml · 353 lines · 282 code · 44 blank · 27 comment · 26 complexity · 384ec191b1f7262ca6c39d221c4e76c5 MD5 · raw file

  1. (* Js_of_ocaml library
  2. * http://www.ocsigen.org/js_of_ocaml/
  3. * Copyright (C) 2010 Jérôme Vouillon
  4. * Laboratoire PPS - CNRS Université Paris Diderot
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation, with linking exception;
  9. * either version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. *)
  20. type +'a t
  21. module Unsafe = struct
  22. external variable : string -> 'a = "caml_js_var"
  23. external constant : string -> 'a = "caml_js_const"
  24. type any
  25. external inject : 'a -> any = "%identity"
  26. external coerce : _ t -> _ t = "%identity"
  27. external get : 'a -> 'b -> 'c = "caml_js_get"
  28. external set : 'a -> 'b -> 'c -> unit = "caml_js_set"
  29. external call : 'a -> 'b -> any array -> 'c = "caml_js_call"
  30. external fun_call : 'a -> any array -> 'b = "caml_js_fun_call"
  31. external meth_call : 'a -> string -> any array -> 'b = "caml_js_meth_call"
  32. external new_obj : 'a -> any array -> 'b = "caml_js_new"
  33. external equals : 'a -> 'b -> bool = "caml_js_equals"
  34. external pure_expr : (unit -> 'a) -> 'a = "caml_js_pure_expr"
  35. external eval_string : string -> 'a = "caml_js_eval_string"
  36. end
  37. (****)
  38. type 'a opt = 'a
  39. type 'a optdef = 'a
  40. let null : 'a opt = Unsafe.constant "null"
  41. external some : 'a -> 'a opt = "%identity"
  42. let undefined : 'a optdef = Unsafe.constant "undefined"
  43. external def : 'a -> 'a optdef = "%identity"
  44. module type OPT = sig
  45. type 'a t
  46. val empty : 'a t
  47. val return : 'a -> 'a t
  48. val map : 'a t -> ('a -> 'b) -> 'b t
  49. val bind : 'a t -> ('a -> 'b t) -> 'b t
  50. val test : 'a t -> bool
  51. val iter : 'a t -> ('a -> unit) -> unit
  52. val case : 'a t -> (unit -> 'b) -> ('a -> 'b) -> 'b
  53. val get : 'a t -> (unit -> 'a) -> 'a
  54. val option : 'a option -> 'a t
  55. val to_option : 'a t -> 'a option
  56. end
  57. module Opt : OPT with type 'a t = 'a opt = struct
  58. type 'a t = 'a opt
  59. let empty = null
  60. let return = some
  61. let map x f = if Unsafe.equals x null then null else some (f x)
  62. let bind x f = if Unsafe.equals x null then null else f x
  63. let test x = not (Unsafe.equals x null)
  64. let iter x f = if not (Unsafe.equals x null) then f x
  65. let case x f g = if Unsafe.equals x null then f () else g x
  66. let get x f = if Unsafe.equals x null then f () else x
  67. let option x = match x with None -> empty | Some x -> return x
  68. let to_option x = case x (fun () -> None) (fun x -> Some x)
  69. end
  70. module Optdef : OPT with type 'a t = 'a optdef = struct
  71. type 'a t = 'a opt
  72. let empty = undefined
  73. let return = def
  74. let map x f = if x == undefined then undefined else some (f x)
  75. let bind x f = if x == undefined then undefined else f x
  76. let test x = x != undefined
  77. let iter x f = if x != undefined then f x
  78. let case x f g = if x == undefined then f () else g x
  79. let get x f = if x == undefined then f () else x
  80. let option x = match x with None -> empty | Some x -> return x
  81. let to_option x = case x (fun () -> None) (fun x -> Some x)
  82. end
  83. (****)
  84. let coerce x f g = Opt.get (f x) (fun () -> g x)
  85. let coerce_opt x f g = Opt.get (Opt.bind x f) (fun () -> g x)
  86. (****)
  87. type +'a meth
  88. type +'a gen_prop
  89. type 'a readonly_prop = <get : 'a> gen_prop
  90. type 'a writeonly_prop = <set : 'a -> unit> gen_prop
  91. type 'a prop = <get : 'a; set : 'a -> unit> gen_prop
  92. type 'a optdef_prop = <get : 'a optdef; set : 'a -> unit> gen_prop
  93. type float_prop = <get : float t; set : float -> unit> gen_prop
  94. type +'a constr
  95. (****)
  96. type (-'a, +'b) meth_callback
  97. type 'a callback = (unit, 'a) meth_callback
  98. external wrap_callback : ('a -> 'b) -> ('c, 'a -> 'b) meth_callback = "caml_js_wrap_callback"
  99. external wrap_meth_callback : ('a -> 'b -> 'c) -> ('a, 'b -> 'c) meth_callback = "caml_js_wrap_meth_callback"
  100. (****)
  101. let _true = Unsafe.constant "true"
  102. let _false = Unsafe.constant "false"
  103. type match_result_handle
  104. type string_array
  105. class type js_string = object
  106. method toString : js_string t meth
  107. method valueOf : js_string t meth
  108. method charAt : int -> js_string t meth
  109. method charCodeAt : int -> float t meth (* This may return NaN... *)
  110. method concat : js_string t -> js_string t meth
  111. method concat_2 : js_string t -> js_string t -> js_string t meth
  112. method concat_3 :
  113. js_string t -> js_string t -> js_string t -> js_string t meth
  114. method concat_4 :
  115. js_string t -> js_string t -> js_string t -> js_string t ->
  116. js_string t meth
  117. method indexOf : js_string t -> int meth
  118. method indexOf_from : js_string t -> int -> int meth
  119. method lastIndexOf : js_string t -> int meth
  120. method lastIndexOf_from : js_string t -> int -> int meth
  121. method localeCompare : js_string t -> float t meth
  122. method _match : regExp t -> match_result_handle t opt meth
  123. method replace : regExp t -> js_string t -> js_string t meth
  124. method replace_string : js_string t -> js_string t -> js_string t meth
  125. method search : regExp t -> int meth
  126. method slice : int -> int -> js_string t meth
  127. method slice_end : int -> js_string t meth
  128. method split : js_string t -> string_array t meth
  129. method split_limited : js_string t -> int -> string_array t meth
  130. method split_regExp : regExp t -> string_array t meth
  131. method split_regExpLimited : regExp t -> int -> string_array t meth
  132. method substring : int -> int -> js_string t meth
  133. method substring_toEnd : int -> js_string t meth
  134. method toLowerCase : js_string t meth
  135. method toLocaleLowerCase : js_string t meth
  136. method toUpperCase : js_string t meth
  137. method toLocaleUpperCase : js_string t meth
  138. method length : int readonly_prop
  139. end
  140. and regExp = object
  141. method exec : js_string t -> match_result_handle t opt meth
  142. method test : js_string t -> bool t meth
  143. method toString : js_string t meth
  144. method source : js_string t readonly_prop
  145. method global : bool t readonly_prop
  146. method ignoreCase : bool t readonly_prop
  147. method multiline : bool t readonly_prop
  148. method lastIndex : int prop
  149. end
  150. let regExp = Unsafe.variable "RegExp"
  151. let regExp_copy = regExp
  152. let regExp_withFlags = regExp
  153. class type ['a] js_array = object
  154. method toString : js_string t meth
  155. method toLocaleString : js_string t meth
  156. method concat : 'a js_array t -> 'a js_array t meth
  157. method join : js_string t -> js_string t meth
  158. method pop : 'a optdef meth
  159. method push : 'a -> int meth
  160. method push_2 : 'a -> 'a -> int meth
  161. method push_3 : 'a -> 'a -> 'a -> int meth
  162. method push_4 : 'a -> 'a -> 'a -> 'a -> int meth
  163. method reverse : 'a js_array t meth
  164. method shift : 'a optdef meth
  165. method slice : int -> int -> 'a js_array t meth
  166. method slice_end : int -> 'a js_array t meth
  167. method sort : ('a -> 'a -> float) callback -> 'a js_array t meth
  168. method sort_asStrings : 'a js_array t meth
  169. method splice : int -> int -> 'a js_array t meth
  170. method splice_1 : int -> int -> 'a -> 'a js_array t meth
  171. method splice_2 : int -> int -> 'a -> 'a -> 'a js_array t meth
  172. method splice_3 : int -> int -> 'a -> 'a -> 'a -> 'a js_array t meth
  173. method splice_4 : int -> int -> 'a -> 'a -> 'a -> 'a -> 'a js_array t meth
  174. method unshift : 'a -> int meth
  175. method unshift_2 : 'a -> 'a -> int meth
  176. method unshift_3 : 'a -> 'a -> 'a -> int meth
  177. method unshift_4 : 'a -> 'a -> 'a -> 'a -> int meth
  178. method length : int prop
  179. end
  180. let array_constructor = Unsafe.variable "Array"
  181. let array_empty = array_constructor
  182. let array_length = array_constructor
  183. let array_get : 'a #js_array t -> int -> 'a optdef = Unsafe.get
  184. let array_set : 'a #js_array t -> int -> 'a -> unit = Unsafe.set
  185. class type match_result = object
  186. inherit [js_string t] js_array
  187. method index : int readonly_prop
  188. method input : js_string t readonly_prop
  189. end
  190. let str_array : string_array t -> js_string t js_array t = Unsafe.coerce
  191. let match_result : match_result_handle t -> match_result t =
  192. Unsafe.coerce
  193. class type number = object
  194. method toString : js_string t meth
  195. method toString_radix : int -> js_string t meth
  196. method toLocaleString : js_string t meth
  197. method toFixed : int -> js_string t meth
  198. method toExponential : js_string t meth
  199. method toExponential_digits : int -> js_string t meth
  200. method toPrecision : int -> js_string meth t
  201. end
  202. external number_of_float : float -> number t = "caml_js_from_float"
  203. external float_of_number : number t -> float = "caml_js_to_float"
  204. class type date = object
  205. method toString : js_string t meth
  206. method toDateString : js_string t meth
  207. method toTimeString : js_string t meth
  208. method toLocaleString : js_string t meth
  209. method toLocaleDateString : js_string t meth
  210. method toLocaleTimeString : js_string t meth
  211. method valueOf : float t meth
  212. method getTime : float t meth
  213. method getFullYear : int meth
  214. method getUTCFullYear : int meth
  215. method getMonth : int meth
  216. method getUTCMonth : int meth
  217. method getDate : int meth
  218. method getUTCDate : int meth
  219. method getDay : int meth
  220. method getUTCDay : int meth
  221. method getHours : int meth
  222. method getUTCHours : int meth
  223. method getMinutes : int meth
  224. method getUTCMinutes : int meth
  225. method getSeconds : int meth
  226. method getUTCSeconds : int meth
  227. method getMilliseconds : int meth
  228. method getUTCMilliseconds : int meth
  229. method getTimezoneOffset : int meth
  230. method setTime : float -> float t meth
  231. method setFullYear : int -> float t meth
  232. method setUTCFullYear : int -> float t meth
  233. method setMonth : int -> float t meth
  234. method setUTCMonth : int -> float t meth
  235. method setDate : int -> float t meth
  236. method setUTCDate : int -> float t meth
  237. method setDay : int -> float t meth
  238. method setUTCDay : int -> float t meth
  239. method setHours : int -> float t meth
  240. method setUTCHours : int -> float t meth
  241. method setMinutes : int -> float t meth
  242. method setUTCMinutes : int -> float t meth
  243. method setSeconds : int -> float t meth
  244. method setUTCSeconds : int -> float t meth
  245. method setMilliseconds : int -> float t meth
  246. method setUTCMilliseconds : int -> float t meth
  247. method toUTCString : js_string t meth
  248. method toISOString : js_string t meth
  249. method toJSON : 'a -> js_string t meth
  250. end
  251. class type date_constr = object
  252. method parse : js_string t -> float t meth
  253. method _UTC_month : int -> int -> float t meth
  254. method _UTC_day : int -> int -> float t meth
  255. method _UTC_hour : int -> int -> int -> int -> float t meth
  256. method _UTC_min : int -> int -> int -> int -> int -> float t meth
  257. method _UTC_sec : int -> int -> int -> int -> int -> int -> float t meth
  258. method _UTC_ms :
  259. int -> int -> int -> int -> int -> int -> int -> float t meth
  260. (*
  261. method now : float t meth
  262. *)
  263. end
  264. let date_constr = Unsafe.variable "Date"
  265. let date : date_constr t = date_constr
  266. let date_now : date t constr = date_constr
  267. let date_fromTimeValue : (float -> date t) constr = date_constr
  268. let date_month : (int -> int -> date t) constr = date_constr
  269. let date_day : (int -> int -> int -> date t) constr = date_constr
  270. let date_hour : (int -> int -> int -> int -> date t) constr = date_constr
  271. let date_min : (int -> int -> int -> int -> int -> date t) constr = date_constr
  272. let date_sec : (int -> int -> int -> int -> int -> int -> date t) constr =
  273. date_constr
  274. let date_ms :
  275. (int -> int -> int -> int -> int -> int -> int -> date t) constr =
  276. date_constr
  277. class type math = object
  278. method random : float t meth
  279. end
  280. let math = Unsafe.variable "Math"
  281. let decodeURI (s : js_string t) : js_string t =
  282. Unsafe.fun_call (Unsafe.variable "decodeURI") [|Unsafe.inject s|]
  283. let decodeURIComponent (s : js_string t) : js_string t =
  284. Unsafe.fun_call (Unsafe.variable "decodeURIComponent") [|Unsafe.inject s|]
  285. let encodeURI (s : js_string t) : js_string t =
  286. Unsafe.fun_call (Unsafe.variable "encodeURI") [|Unsafe.inject s|]
  287. let encodeURIComponent (s : js_string t) : js_string t =
  288. Unsafe.fun_call (Unsafe.variable "encodeURIComponent") [|Unsafe.inject s|]
  289. let escape (s : js_string t) : js_string t =
  290. Unsafe.fun_call (Unsafe.variable "escape") [|Unsafe.inject s|]
  291. let unescape (s : js_string t) : js_string t =
  292. Unsafe.fun_call (Unsafe.variable "unescape") [|Unsafe.inject s|]
  293. external bool : bool -> bool t = "caml_js_from_bool"
  294. external to_bool : bool t -> bool = "caml_js_to_bool"
  295. external string : string -> js_string t = "caml_js_from_string"
  296. external to_string : js_string t -> string = "caml_js_to_string"
  297. external float : float -> float t = "caml_js_from_float"
  298. external to_float : float t -> float = "caml_js_to_float"
  299. external array : 'a array -> 'a js_array t = "caml_js_from_array"
  300. external to_array : 'a js_array t -> 'a array = "caml_js_to_array"
  301. external bytestring : string -> js_string t = "caml_js_from_byte_string"
  302. external to_bytestring : js_string t -> string = "caml_js_to_byte_string"
  303. external typeof : < .. > t -> js_string t = "caml_js_typeof"
  304. external instanceof : 'a -> 'b -> bool = "caml_js_instanceof"
  305. let _ =
  306. Printexc.register_printer
  307. (fun e ->
  308. if instanceof e array_constructor then None
  309. else Some (to_string (Unsafe.meth_call (Obj.magic e) "toString" [||])))