├── .gitignore ├── .merlin ├── Makefile ├── README.md ├── _tags ├── ajax_tutorial ├── ajax_info.txt ├── cd_catalog.xml ├── ex1.html ├── ex1.js ├── ex1b.html ├── ex1b.js ├── ex2.html ├── ex2.js ├── ex5.html └── ex5.js ├── myocamlbuild.ml ├── public ├── example.js ├── global_features ├── global_features.KO ├── global_features.OK ├── index.html ├── jsonExample.html └── jsonExample.js └── src ├── ex1.ml ├── ex1b.ml ├── ex2.ml ├── ex5.ml ├── example.ml └── jsonExample.ml /.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | *.docdir 3 | *.byte 4 | *.native 5 | -------------------------------------------------------------------------------- /.merlin: -------------------------------------------------------------------------------- 1 | S . 2 | B _build 3 | PKG js_of_ocaml 4 | EXT js 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | ocamlbuild -use-ocamlfind -plugin-tag 'package(js_of_ocaml.ocamlbuild)' \ 3 | src/example.js 4 | ocamlbuild -use-ocamlfind -plugin-tag 'package(js_of_ocaml.ocamlbuild)' \ 5 | src/ex1.js 6 | ocamlbuild -use-ocamlfind -plugin-tag 'package(js_of_ocaml.ocamlbuild)' \ 7 | src/ex1b.js 8 | ocamlbuild -use-ocamlfind -plugin-tag 'package(js_of_ocaml.ocamlbuild)' \ 9 | src/ex2.js 10 | ocamlbuild -use-ocamlfind -plugin-tag 'package(js_of_ocaml.ocamlbuild)' \ 11 | src/ex5.js 12 | ocamlbuild -use-ocamlfind -plugin-tag 'package(js_of_ocaml.ocamlbuild)' \ 13 | src/jsonExample.js 14 | 15 | clean: 16 | ocamlbuild -clean 17 | 18 | .PHONY: build clean 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | js_of_ocaml example 2 | =================== 3 | 4 | Setting up 5 | ---------- 6 | 7 | opam install js_of_ocaml 8 | 9 | Building 10 | -------- 11 | 12 | make build 13 | 14 | -------------------------------------------------------------------------------- /_tags: -------------------------------------------------------------------------------- 1 | true: warn(@5@8@10@11@12@14@23@24@26@29@40), bin_annot, debug 2 | 3 | : syntax(camlp4o), package(js_of_ocaml), package(js_of_ocaml.syntax) 4 | -------------------------------------------------------------------------------- /ajax_tutorial/ajax_info.txt: -------------------------------------------------------------------------------- 1 |

AJAX is not a new programming language.

2 |

AJAX is a technique for creating fast and dynamic web pages.

-------------------------------------------------------------------------------- /ajax_tutorial/cd_catalog.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Empire Burlesque 5 | Bob Dylan 6 | USA 7 | Columbia 8 | 10.90 9 | 1985 10 | 11 | 12 | Hide your heart 13 | Bonnie Tyler 14 | UK 15 | CBS Records 16 | 9.90 17 | 1988 18 | 19 | 20 | Greatest Hits 21 | Dolly Parton 22 | USA 23 | RCA 24 | 9.90 25 | 1982 26 | 27 | 28 | Still got the blues 29 | Gary Moore 30 | UK 31 | Virgin records 32 | 10.20 33 | 1990 34 | 35 | 36 | Eros 37 | Eros Ramazzotti 38 | EU 39 | BMG 40 | 9.90 41 | 1997 42 | 43 | 44 | One night only 45 | Bee Gees 46 | UK 47 | Polydor 48 | 10.90 49 | 1998 50 | 51 | 52 | Sylvias Mother 53 | Dr.Hook 54 | UK 55 | CBS 56 | 8.10 57 | 1973 58 | 59 | 60 | Maggie May 61 | Rod Stewart 62 | UK 63 | Pickwick 64 | 8.50 65 | 1990 66 | 67 | 68 | Romanza 69 | Andrea Bocelli 70 | EU 71 | Polydor 72 | 10.80 73 | 1996 74 | 75 | 76 | When a man loves a woman 77 | Percy Sledge 78 | USA 79 | Atlantic 80 | 8.70 81 | 1987 82 | 83 | 84 | Black angel 85 | Savage Rose 86 | EU 87 | Mega 88 | 10.90 89 | 1995 90 | 91 | 92 | 1999 Grammy Nominees 93 | Many 94 | USA 95 | Grammy 96 | 10.20 97 | 1999 98 | 99 | 100 | For the good times 101 | Kenny Rogers 102 | UK 103 | Mucik Master 104 | 8.70 105 | 1995 106 | 107 | 108 | Big Willie style 109 | Will Smith 110 | USA 111 | Columbia 112 | 9.90 113 | 1997 114 | 115 | 116 | Tupelo Honey 117 | Van Morrison 118 | UK 119 | Polydor 120 | 8.20 121 | 1971 122 | 123 | 124 | Soulsville 125 | Jorn Hoel 126 | Norway 127 | WEA 128 | 7.90 129 | 1996 130 | 131 | 132 | The very best of 133 | Cat Stevens 134 | UK 135 | Island 136 | 8.90 137 | 1990 138 | 139 | 140 | Stop 141 | Sam Brown 142 | UK 143 | A and M 144 | 8.90 145 | 1988 146 | 147 | 148 | Bridge of Spies 149 | T'Pau 150 | UK 151 | Siren 152 | 7.90 153 | 1987 154 | 155 | 156 | Private Dancer 157 | Tina Turner 158 | UK 159 | Capitol 160 | 8.90 161 | 1983 162 | 163 | 164 | Midt om natten 165 | Kim Larsen 166 | EU 167 | Medley 168 | 7.80 169 | 1983 170 | 171 | 172 | Pavarotti Gala Concert 173 | Luciano Pavarotti 174 | UK 175 | DECCA 176 | 9.90 177 | 1991 178 | 179 | 180 | The dock of the bay 181 | Otis Redding 182 | USA 183 | Atlantic 184 | 7.90 185 | 1987 186 | 187 | 188 | Picture book 189 | Simply Red 190 | EU 191 | Elektra 192 | 7.20 193 | 1985 194 | 195 | 196 | Red 197 | The Communards 198 | UK 199 | London 200 | 7.80 201 | 1987 202 | 203 | 204 | Unchain my heart 205 | Joe Cocker 206 | USA 207 | EMI 208 | 8.20 209 | 1987 210 | 211 | 212 | -------------------------------------------------------------------------------- /ajax_tutorial/ex1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Let AJAX change this text

8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ajax_tutorial/ex1.js: -------------------------------------------------------------------------------- 1 | ../_build/src/ex1.js -------------------------------------------------------------------------------- /ajax_tutorial/ex1b.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ajax_tutorial/ex1b.js: -------------------------------------------------------------------------------- 1 | ../_build/src/ex1b.js -------------------------------------------------------------------------------- /ajax_tutorial/ex2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

My CD Collection:

8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ajax_tutorial/ex2.js: -------------------------------------------------------------------------------- 1 | ../_build/src/ex2.js -------------------------------------------------------------------------------- /ajax_tutorial/ex5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /ajax_tutorial/ex5.js: -------------------------------------------------------------------------------- 1 | ../_build/src/ex5.js -------------------------------------------------------------------------------- /myocamlbuild.ml: -------------------------------------------------------------------------------- 1 | let () = Ocamlbuild_plugin.dispatch Ocamlbuild_js_of_ocaml.dispatcher 2 | -------------------------------------------------------------------------------- /public/example.js: -------------------------------------------------------------------------------- 1 | ../_build/src/example.js -------------------------------------------------------------------------------- /public/global_features: -------------------------------------------------------------------------------- 1 | global_features.OK -------------------------------------------------------------------------------- /public/global_features.KO: -------------------------------------------------------------------------------- 1 | {"KO":"Error: invalid request"} 2 | -------------------------------------------------------------------------------- /public/global_features.OK: -------------------------------------------------------------------------------- 1 | {"OK":{"main_page":"page1","pages":{"page1":{"enabled":true,"explanation":""},"page2":{"enabled":false,"explanation":"disabled for now"}}}} 2 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | js_of_ocaml example 5 | 6 | 7 | 8 |

Hi

9 | 10 | 11 | -------------------------------------------------------------------------------- /public/jsonExample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /public/jsonExample.js: -------------------------------------------------------------------------------- 1 | ../_build/src/jsonExample.js -------------------------------------------------------------------------------- /src/ex1.ml: -------------------------------------------------------------------------------- 1 | let loadXMLDoc () = 2 | let xmlhttp = XmlHttpRequest.create () in 3 | let onreadystatechange () = 4 | match xmlhttp##readyState, xmlhttp##status with 5 | | XmlHttpRequest.DONE, 200 -> 6 | (Dom_html.getElementById "myDiv")##innerHTML <- xmlhttp##responseText 7 | | _ -> () 8 | in 9 | xmlhttp##onreadystatechange <- Js.wrap_callback onreadystatechange; 10 | xmlhttp##_open (Js.string "GET", Js.string "ajax_info.txt", Js._true); 11 | xmlhttp##send (Js.null) 12 | 13 | let () = Js.Unsafe.global##loadXMLDoc <- Js.wrap_callback loadXMLDoc 14 | -------------------------------------------------------------------------------- /src/ex1b.ml: -------------------------------------------------------------------------------- 1 | let onload _ = 2 | let doc = Dom_html.document in 3 | let div = Dom_html.createDiv doc in 4 | let h2 = Dom_html.createH2 doc in 5 | let button = Dom_html.createButton ~_type:(Js.string "button") doc in 6 | h2##textContent <- Js.some (Js.string "Let AJAX change this text"); 7 | button##textContent <- Js.some (Js.string "Change Content"); 8 | let _ = 9 | let state = ref false in 10 | Lwt_js_events.clicks button 11 | (fun _ev _ -> 12 | state := not !state; 13 | if !state then 14 | Lwt.bind (XmlHttpRequest.get "ajax_info.txt") 15 | (fun {XmlHttpRequest.content; _} -> div##innerHTML <- Js.string content; Lwt.return ()) 16 | else begin 17 | div##innerHTML <- Js.string ""; 18 | Dom.appendChild div h2; 19 | Lwt.return() 20 | end) 21 | in 22 | Dom.appendChild div h2; 23 | Dom.appendChild doc##body div; 24 | Dom.appendChild doc##body button; 25 | Js._false 26 | 27 | let () = 28 | Dom_html.window##onload <- Dom_html.handler onload 29 | -------------------------------------------------------------------------------- /src/ex2.ml: -------------------------------------------------------------------------------- 1 | let loadXMLDoc () = 2 | let xmlhttp = XmlHttpRequest.create () in 3 | let onreadystatechange () = 4 | match xmlhttp##readyState, xmlhttp##status with 5 | | XmlHttpRequest.DONE, 200 -> 6 | let xmlDoc = xmlhttp##responseXML in 7 | let buf = Buffer.create 16 in 8 | let iter f x = Js.Opt.iter x f in 9 | iter 10 | (fun xmlDoc -> 11 | let elts = xmlDoc##getElementsByTagName (Js.string "ARTIST") in 12 | for i = 0 to elts##length - 1 do 13 | iter 14 | (fun elt -> 15 | iter 16 | (fun elt -> 17 | iter 18 | (fun elt -> 19 | Buffer.add_string buf (Js.to_string elt); 20 | Buffer.add_string buf "
") 21 | elt##nodeValue) 22 | elt##firstChild) 23 | (elts##item (i)) 24 | done) 25 | xmlDoc; 26 | (Dom_html.getElementById "myDiv")##innerHTML <- Js.string (Buffer.contents buf) 27 | | _ -> () 28 | in 29 | xmlhttp##onreadystatechange <- Js.wrap_callback onreadystatechange; 30 | xmlhttp##_open (Js.string "GET", Js.string "cd_catalog.xml", Js._true); 31 | xmlhttp##send (Js.null) 32 | 33 | let () = Js.Unsafe.global##loadXMLDoc <- Js.wrap_callback loadXMLDoc 34 | -------------------------------------------------------------------------------- /src/ex5.ml: -------------------------------------------------------------------------------- 1 | let loadXMLDoc () = 2 | let xmlhttp = XmlHttpRequest.create () in 3 | let onreadystatechange () = 4 | match xmlhttp##readyState, xmlhttp##status with 5 | | XmlHttpRequest.DONE, 200 -> 6 | let xmlDoc = xmlhttp##responseXML in 7 | let buf = Buffer.create 16 in 8 | Buffer.add_string buf ""; 9 | begin match Js.Opt.to_option xmlDoc with 10 | | None -> () 11 | | Some xmlDoc -> 12 | let elts = xmlDoc##getElementsByTagName (Js.string "CD") in 13 | let f elt = 14 | let td cat = 15 | let case f x = Js.Opt.case x (fun () -> " ") f in 16 | let cell = 17 | case 18 | (fun hd -> case (fun hd -> case Js.to_string hd##nodeValue) hd##firstChild) 19 | ((elt##getElementsByTagName (Js.string cat))##item (0)) 20 | in 21 | Buffer.add_string buf ""; 24 | in 25 | Buffer.add_string buf ""; 26 | td "TITLE"; 27 | td "ARTIST"; 28 | Buffer.add_string buf ""; 29 | in 30 | List.iter f (Dom.list_of_nodeList elts) 31 | end; 32 | Buffer.add_string buf "
TitleArtist
"; 22 | Buffer.add_string buf cell; 23 | Buffer.add_string buf "
"; 33 | (Dom_html.getElementById "txtCDInfo")##innerHTML <- Js.string (Buffer.contents buf) 34 | | _ -> () 35 | in 36 | xmlhttp##onreadystatechange <- Js.wrap_callback onreadystatechange; 37 | xmlhttp##_open (Js.string "GET", Js.string "cd_catalog.xml", Js._true); 38 | xmlhttp##send (Js.null) 39 | 40 | let () = Js.Unsafe.global##loadXMLDoc <- Js.wrap_callback loadXMLDoc 41 | -------------------------------------------------------------------------------- /src/example.ml: -------------------------------------------------------------------------------- 1 | let () = 2 | Dom_html.window##alert (Js.string "hello, world") 3 | -------------------------------------------------------------------------------- /src/jsonExample.ml: -------------------------------------------------------------------------------- 1 | class type page_status = 2 | object 3 | method enabled: bool Js.t Js.readonly_prop 4 | method explanation: string Js.readonly_prop 5 | end 6 | 7 | class type global_features = 8 | object 9 | method main_page_: string Js.readonly_prop 10 | method pages: < .. > Js.t Js.readonly_prop 11 | end 12 | 13 | type 'a response = 14 | | OK of 'a Js.t 15 | | KO of string 16 | 17 | let get_response x = 18 | let x = Json.unsafe_input (Js.string x) in 19 | let resp = (Js.Unsafe.coerce x)##_OK in 20 | if Js.Optdef.test resp then OK resp 21 | else KO (Js.Unsafe.coerce x)##_KO 22 | 23 | let onload _ = 24 | let doc = Dom_html.document in 25 | let div = Dom_html.createDiv doc in 26 | let global_pages = 27 | [ "page1"; 28 | "page2"; 29 | "page3"; 30 | "page4"; 31 | ] 32 | in 33 | let _ = 34 | let form_arg = `Fields (ref ["data", `String (Json.output (jsnew Js.array_empty ()))]) in 35 | Lwt.bind 36 | (XmlHttpRequest.perform_raw_url 37 | ~content_type:"application/json; charset=UTF-8" 38 | ~headers:["Accept", "application/json, text/javascript, */*; q=0.01"; 39 | "X-Requested-With", "XMLHttpRequest"] 40 | ~form_arg 41 | "global_features") 42 | (fun {XmlHttpRequest.content; _} -> 43 | let buf = Buffer.create 64 in 44 | Buffer.add_string buf (Printf.sprintf "JSON response:%s
" content); 45 | begin match get_response content with 46 | | OK (gf:global_features Js.t) -> 47 | Buffer.add_string buf (Printf.sprintf "Main page: %s
" gf##main_page_); 48 | Buffer.add_string buf ""; 49 | Buffer.add_string buf ""; 50 | let f internal_name = 51 | Buffer.add_string buf ""; 52 | Buffer.add_string buf (Printf.sprintf "" internal_name); 53 | begin match Js.Optdef.to_option (Js.Unsafe.get (gf##pages) (Js.string internal_name)) with 54 | | None -> Buffer.add_string buf (Printf.sprintf "") 55 | | Some (status:page_status Js.t) -> 56 | Buffer.add_string buf (Printf.sprintf "" (Js.to_bool status##enabled) status##explanation) 57 | end; 58 | Buffer.add_string buf ""; 59 | in 60 | List.iter f global_pages; 61 | Buffer.add_string buf "
Internal nameEnabledExplanation
%sN/AN/A%b%s
" 62 | | KO msg -> 63 | Buffer.add_string buf msg; 64 | Buffer.add_string buf "
"; 65 | end; 66 | div##innerHTML <- Js.string (Buffer.contents buf); 67 | Lwt.return ()) 68 | in 69 | Dom.appendChild doc##body div; 70 | Js._false 71 | 72 | let () = 73 | Dom_html.window##onload <- Dom_html.handler onload 74 | --------------------------------------------------------------------------------