1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
= Ppx syntax extension for Js_of_ocaml
To migrate from the camlp4 extension, it is advised to use
[[https://github.com/janestreet/camlp4-to-ppx|camlp4-to-ppx]]
which provides built-in support for Js_of_ocaml syntax.
A ppx rewriter (syntax extension) is available for manipulating object properties,
invoking methods and creating objects.
The syntax and typing rules are as follows:
* Getting a property
{{{
obj : <m : u Js.prop> Js.t
--------------------------
obj##.m : u
}}}
* Setting a property
{{{
obj : <m : u Js.prop> Js.t
e : u
--------------------------
obj##.m := e : unit
}}}
* Invoking a method
{{{
obj : <m : t_1 -> ... -> t_n -> u Js.meth; ..> Js.t
e_i : t_i (1 <= i <= n)
----------------------------------------------------
obj##m e_1 ... e_n : u
}}}
For easier chaining, the following alternative syntax is also possible: [ obj##(m e_1 ... e_n) ].
Beware, partial application is not allowed.
* Using an object constructor
{{{
constr : (t_1 -> ... -> t_n -> u Js.t) Js.constr
e_i : t_i (1 <= i <= n)
------------------------------------------------
new%js constr e1 ... en : u Js.t
}}}
[ constr ] here must be an identifier. For constructors
that are not identifiers, bind them first:
<<code language="ocaml"|
let a = Js.Unsafe.global##.A in
new%js a
>>
* Creating a literal object
<<code language="ocaml"|
object%js (self) (* Equivalent of this *)
val x1 = 3 (* read-only prop *)
val x2 = 3 [@@readonly] (* read-only prop *)
val mutable y1 = 4 (* read/write prop *)
val y2 = 4 [@@readwrite] (* read/write prop *)
val z = 5 [@@writeonly] (* write-only prop *)
val t1 = Js.undefined [@@jsoo.optdef] (* optdef prop *)
method foo i = self##.y1 := self##.x1 + i
end
>>
Properties are defined with the [val] keyword. [mutable] makes the
property writable. Properties can be annotated with attributes to change the
default semantic.
Attributes can be one of [readwrite], [readonly], [writeonly],
[optdef].
[self] can be any identifier and will be bind
to [this] in javascript.
In this case, the object has the following type:
<<code language="ocaml"|
< foo : int -> unit Js.meth;
t1 : 'a Js.optdef_prop;
x1 : int Js.readonly_prop;
x2 : int Js.readonly_prop;
y1 : int Js.prop;
y2 : int Js.prop;
z : int Js.writeonly_prop >
Js.t
>>
|