119
Ocsigen Vincent Balat Epita — 12 mars 2014

Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Ocsigen

Vincent Balat

Epita — 12 mars 2014

Page 2: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Affilia on

Ocsigen est logiciel libre issu d'un projet de recherche (Univ Paris Diderot,CNRS et Inria).

.....

2 projets ANR

Collabora ons avec UPMC, Inria Sophia An polis et Université Paris Nord.

Page 3: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

L'évolu on du Web

Page 4: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

L'évolu on du Web

Page 5: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

L'évolu on du Web

Page 6: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

L'évolu on du Web

Page 7: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

L'évolu on du Web

Page 8: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

L'évolu on du Web

Page 9: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

L'évolu on du Web

1992 1997 2002 2007

Yahoo mail

CaraMail

linuxfr

Amazon

Slashdot

phpBBWikipedia

Twitter

Farmville

Google+

Angry birds

Google documents

Pearltrees

Mindmeister

Pivotal Tracker

Facebook

PHP JSPServlets

ASP Ruby on rails

HTML5

JavascriptFlash

Page 10: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Qu'est-ce qu'Ocsigen ?

.Un framework Web pour :..

.

les applica ons HTML5 avec beaucoup d'interac ons client / serveur

les sites Web tradi onnels (signets, bouton back, liens, etc)

Les deux ensemble (le programme client ne s'arrête pas pendant la naviga on)

Ocsigen est distribué sous licence LGPL

Page 11: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Exemple

.

. h p://ocsigen.org/graffi

Page 12: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Exemple :une applica on de dessin

Page 13: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Exemple :une applica on de dessin collabora ve

Page 14: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Le code de Graffi en en er

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

� Court

.

� Un seul code

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

� côté server

.

� code partagé

.

� code client , compilé vers JS

Page 15: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Le code de Graffi en en er

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

� Court

.

� Un seul code

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

� côté server

.

� code partagé

.

� code client , compilé vers JS

Page 16: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Le code de Graffi en en er

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

� Court

.

� Un seul code

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

� côté server

.

� code partagé

.

� code client , compilé vers JS

Page 17: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Le code de Graffi en en er

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

� Court

.

� Un seul code

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

� côté server

.

� code partagé

.

� code client , compilé vers JS

Page 18: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Une applica on Web client/servercomme un seul programmeAvantages :

Même language

Mêmes structures de données — pas besoin de conversions

Code partagé

Générer des por ons de la page soit sur le server (indexa on...) soitle client (mises à jour)

Appels de fonc ons distants

U liser des variables serveur depuis le côté client

Page 19: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Les buts d'Ocsigen.Expressivité..

.

Expressivité du langage lui-même

Concepts de haut niveau adaptés aux besoins des développeurs Web.

.Securité..

.

Garan es de sécurité offertes par le langage ou par Ocsigen(pas d'injec on de code possible,...)

.Améliorer la fiabilité, Réduire le temps de débogage..

.

Grâce à un langage compilé, avec un typage sta que puissant

Le HTML respecte les recommanda ons du W3C (Vérifié à la

compila on !)

URLs générées dynamiquement⇒ pas de liens morts

Page 20: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Plan

OCaml

Applica ons Web client-serveur

Programmer l'interac on Web tradi onelle

Générer du HTML

Conclusion

Page 21: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

...

OCaml

Applica ons Web client-serveur

Programmer l'interac on Web tradi onelle

Générer du HTML

Conclusion

Page 22: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Le langage

OCaml

Très expressif: fonc onnel, orienté objet, modules paramétrés …

Système de types très riche (typage sta que !)

Langage compilé (rapide)

Syntaxe extensible

Nombreuses bibliothèques et bindings

Communauté d'u lisateurs, u lisateurs industriels

Page 23: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Quelques u lisateurs d'OCaml

Jane Street Capital Transac ons financièresXen -- Citrix 15% des machines virtuelles, dont AmazonAirbusOCaml Labs (Cambridge UK)Ocamlpro (Paris)La plupart des prouveurs de programmesMicroso (F#), Dassault,...Facebook...

Page 24: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Influence du typagesur le temps de développement

Development time

Complexity of the program

Page 25: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

js_of_ocaml

Un compilateur d'OCaml vers JS.

Page 26: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

js_of_ocaml

Un compilateur de bytecode OCamlvers JS.

Page 27: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

js_of_ocaml

Un compilateur de bytecode OCamlvers JS.

Très facile à u liserPossibilité d'u liser des bibliothèques déjà compilées (même non libres)

Page 28: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

js_of_ocaml

Un compilateur de bytecode OCamlvers JS.

Rapide !

Page 29: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

js_of_ocaml

Un compilateur de bytecode OCamlvers JS.

Concis !

Page 30: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Js_of_ocaml : Appeler des fonc ons JS

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

let draw ctx (color, size, (x1, y1), (x2, y2)) =ctx##strokeStyle <- color;ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1);ctx##lineTo(float x2, float y2);ctx##stroke()

.

Dessiner des lignes

Page 31: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Js_of_ocaml : Appeler des fonc ons JS

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

let draw ctx (color, size, (x1, y1), (x2, y2)) =ctx##strokeStyle <- color;ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1);ctx##lineTo(float x2, float y2);ctx##stroke()

.

Dessiner des lignes

Page 32: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

O'Closure: un bindingpour la bibliothèque de widgets GoogleClosure

Page 33: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

...

OCaml

Applica ons Web client-serveur

Programmer l'interac on Web tradi onelle

Générer du HTML

Conclusion

Page 34: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 35: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 36: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 37: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 38: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 39: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 40: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 41: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 42: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 43: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 44: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 45: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 46: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 47: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 48: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 49: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 50: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 51: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Structure

..

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

open, constantes, type

.

Ini alisa on de l'appl

.

Bus

.

fonc on draw

.

Service

..

Service

.

HTML5 page

.

Code spécifique à la page

.

Canvas

.

Slider

.

Pale e de couleurs

.

Fonc onde calcul des coordonnéeset envoi au serveur

.

Réac ons aux évé. serveur

.

Évé. souris

Page 52: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Ex de com. client-serveur : le bus

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

let b =Eliom_bus.create ~name:"graff" Json.t<messages>

.

Eliom_bus.write %b v

.

Lwt_stream.iter (draw ctx) (Eliom_bus.stream %b)

Page 53: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Ex de com. client-serveur : le bus

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

let b =Eliom_bus.create ~name:"graff" Json.t<messages>

.

Eliom_bus.write %b v

.

Lwt_stream.iter (draw ctx) (Eliom_bus.stream %b)

Page 54: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Ex de com. client-serveur : le bus

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

let b =Eliom_bus.create ~name:"graff" Json.t<messages>

.

Eliom_bus.write %b v

.

Lwt_stream.iter (draw ctx) (Eliom_bus.stream %b)

Page 55: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Bus client-server

......

b

. call write. listen on bus b

Page 56: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Bus client-server

......

b

. call write. listen on bus b

Page 57: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Bus client-server

......

b

. call write

. listen on bus b

Page 58: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Bus client-server

......

b

. call write

. listen on bus b

Page 59: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Bus client-server

......

b

. call write

. listen on bus b

Page 60: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

...

OCaml

Applica ons Web client-serveur

Programmer l'interac on Web tradi onelle

Générer du HTML

Conclusion

Page 61: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Services

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

..

let main_service = register_service~path:[""]~get_params:unit(fun () () -> ... )

.

HTML

Fichier

Redirec on

Ac on

Applica on

Page 62: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Services

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

..

let main_service = register_service~path:[""]~get_params:unit(fun () () -> ... )

.

HTML

Fichier

Redirec on

Ac on

Applica on

Page 63: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Programmer l'interac on Web tradi onelleavec les services d'Ocsigen

...1 Les services sont des valeurs de première classe

...2 Liens et formulaires sont vérifiés sta quement

...3 Les données générées sont vérifiés sta quement

...4 Créa on dynamique de nouveaux services

...5 Mécanisme puissant d'iden fica on de services, basé sur :L'URL ou un iden fiant de service (comme paramètre)Le méthode HTTP (GET or POST)Le nom des paramètresLa session (navigateur)L'onglet qui fait la requête…

Page 64: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Services

service : (GET and POST parameters) −→ page

..

Ocsigen vérifie la présence des paramètreset les traduit automa quement vers des types OCaml

(integers, booleans,... et même des ensembles ou listes !)

Page 65: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Liens et formulaires

..Les services sont des valeurs de première classe

<a> ne prend pas l'URL comme paramètre,mais le service !

..⇒ Pas de liens cassés !

..

Conformité des formulaires par rapport aux servicesvérifiée à la compila on

Page 66: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Liens et formulaires

..Les services sont des valeurs de première classe

<a> ne prend pas l'URL comme paramètre,mais le service !

..⇒ Pas de liens cassés !

..

Conformité des formulaires par rapport aux servicesvérifiée à la compila on

Page 67: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Liens et formulaires

..Les services sont des valeurs de première classe

<a> ne prend pas l'URL comme paramètre,mais le service !

..⇒ Pas de liens cassés !

..

Conformité des formulaires par rapport aux servicesvérifiée à la compila on

Page 68: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Mécanisme d'iden fica on de services

..Ocsigen choisit le service automa quement

en fonc on :

De l'URL et/ou d'un paramètre interne

De la méthode HTTP (GET ou POST)

Du nom des paramètres

La session de l'u lisateur

−→ Le programmeur choisit le style d'iden fica on dont il a besoin.

Page 69: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Mécanisme d'iden fica on de services

Exemple : connec on d'u lisateur depuis n'importe quelle page

..

h p ://.../

.

h p ://.../aaa/bbb

.

...

.

pwd

.

login

.

pwd

.

login

.

h p ://.../

.

h p ://.../aaa/bbb

.

...

.

Hello Paul

.

Hello Paul

Page 70: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Mécanisme d'iden fica on de services

Exemple : connec on d'u lisateur depuis n'importe quelle page

..

h p ://.../

.

h p ://.../aaa/bbb

.

...

.

pwd

.

login

.

pwd

.

login

.

h p ://.../

.

h p ://.../aaa/bbb

.

...

.

Hello Paul

.

Hello Paul

L'ac on de « se connecter » est un service caché disponible pour toutes lesURLs.

Page 71: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Mécanisme d'iden fica on de services

Exemple : connec on d'u lisateur depuis n'importe quelle page

..

h p ://.../

.

h p ://.../aaa/bbb

.

...

.

pwd

.

login

.

pwd

.

login

.

h p ://.../

.

h p ://.../aaa/bbb

.

...

.

Hello Paul

.

Hello Paul

L'ac on de « se connecter » est un service caché disponible pour toutes lesURLs.

Page 72: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Deux sortes d'interac on WebExemple : réserver un billet d'avion

.

..

Je veux réserver un billetLisbonne -- Moscou

.

.

Le site propose plusieurs choix

..

Dans une autre fenêtre,Je veux réserver un billet

San Francisco -- Antananarivo

.

.

Encore une fois, plusieurs choix

.

.

Je retourne à la première fenêtre

.

Je veux con nuer avec le premierbillet !

.Les deux fenêtres évoluent indépendamment.Mais le panier est partagépar les deux fenêtres

Page 73: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Deux sortes d'interac on WebExemple : réserver un billet d'avion

...

Je veux réserver un billetLisbonne -- Moscou

.

.

Le site propose plusieurs choix

..

Dans une autre fenêtre,Je veux réserver un billet

San Francisco -- Antananarivo

.

.

Encore une fois, plusieurs choix

.

.

Je retourne à la première fenêtre

.

Je veux con nuer avec le premierbillet !

.Les deux fenêtres évoluent indépendamment.Mais le panier est partagépar les deux fenêtres

Page 74: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Deux sortes d'interac on WebExemple : réserver un billet d'avion

.

..

Je veux réserver un billetLisbonne -- Moscou

..

Le site propose plusieurs choix

..

Dans une autre fenêtre,Je veux réserver un billet

San Francisco -- Antananarivo

.

.

Encore une fois, plusieurs choix

.

.

Je retourne à la première fenêtre

.

Je veux con nuer avec le premierbillet !

.Les deux fenêtres évoluent indépendamment.Mais le panier est partagépar les deux fenêtres

Page 75: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Deux sortes d'interac on WebExemple : réserver un billet d'avion

.

..

Je veux réserver un billetLisbonne -- Moscou

.

.

Le site propose plusieurs choix

..

Dans une autre fenêtre,Je veux réserver un billet

San Francisco -- Antananarivo

.

.

Encore une fois, plusieurs choix

.

.

Je retourne à la première fenêtre

.

Je veux con nuer avec le premierbillet !

.Les deux fenêtres évoluent indépendamment.Mais le panier est partagépar les deux fenêtres

Page 76: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Deux sortes d'interac on WebExemple : réserver un billet d'avion

.

..

Je veux réserver un billetLisbonne -- Moscou

.

.

Le site propose plusieurs choix

..

Dans une autre fenêtre,Je veux réserver un billet

San Francisco -- Antananarivo

..

Encore une fois, plusieurs choix

.

.

Je retourne à la première fenêtre

.

Je veux con nuer avec le premierbillet !

.Les deux fenêtres évoluent indépendamment.Mais le panier est partagépar les deux fenêtres

Page 77: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Deux sortes d'interac on WebExemple : réserver un billet d'avion

.

..

Je veux réserver un billetLisbonne -- Moscou

.

.

Le site propose plusieurs choix

..

Dans une autre fenêtre,Je veux réserver un billet

San Francisco -- Antananarivo

.

.

Encore une fois, plusieurs choix

..

Je retourne à la première fenêtre

.

Je veux con nuer avec le premierbillet !

.Les deux fenêtres évoluent indépendamment.Mais le panier est partagépar les deux fenêtres

Page 78: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Deux sortes d'interac on WebExemple : réserver un billet d'avion

.

..

Je veux réserver un billetLisbonne -- Moscou

.

.

Le site propose plusieurs choix

..

Dans une autre fenêtre,Je veux réserver un billet

San Francisco -- Antananarivo

.

.

Encore une fois, plusieurs choix

..

Je retourne à la première fenêtre

.

Je veux con nuer avec le premierbillet !

.Les deux fenêtres évoluent indépendamment.Mais le panier est partagépar les deux fenêtres

Page 79: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Deux sortes d'interac on WebExemple : réserver un billet d'avion

.

..

Je veux réserver un billetLisbonne -- Moscou

.

.

Le site propose plusieurs choix

..

Dans une autre fenêtre,Je veux réserver un billet

San Francisco -- Antananarivo

.

.

Encore une fois, plusieurs choix

.

.

Je retourne à la première fenêtre

.

Je veux con nuer avec le premierbillet !

.Les deux fenêtres évoluent indépendamment

.Mais le panier est partagépar les deux fenêtres

Page 80: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Deux sortes d'interac on WebExemple : réserver un billet d'avion

.

..

Je veux réserver un billetLisbonne -- Moscou

.

.

Le site propose plusieurs choix

..

Dans une autre fenêtre,Je veux réserver un billet

San Francisco -- Antananarivo

.

.

Encore une fois, plusieurs choix

.

.

Je retourne à la première fenêtre

.

Je veux con nuer avec le premierbillet !

.Les deux fenêtres évoluent indépendamment

.Mais le panier est partagépar les deux fenêtres

Page 81: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Solu ons

..

Panier :

.

Sessions

−→ « État » côté serveur pour un navigateur−→ Ges on automa ques des cookies de session−→ Possibilité de créer des services de session !

..

Pages dépendant d'interac ons précédentes :

.

Créa on dynamique de services

−→ L'histoire de l'interac on est gardée automa quement en mémoire(côté serveur)

−→ Vous pouvez retourner dans le passé (bouton ``back'')ou changer de fenêtre de navigateur

Page 82: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Solu ons

..

Panier :

.

Sessions

−→ « État » côté serveur pour un navigateur−→ Ges on automa ques des cookies de session−→ Possibilité de créer des services de session !

..

Pages dépendant d'interac ons précédentes :

.

Créa on dynamique de services

−→ L'histoire de l'interac on est gardée automa quement en mémoire(côté serveur)

−→ Vous pouvez retourner dans le passé (bouton ``back'')ou changer de fenêtre de navigateur

Page 83: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Solu ons

..

Panier :

.

Sessions

−→ « État » côté serveur pour un navigateur−→ Ges on automa ques des cookies de session−→ Possibilité de créer des services de session !

..

Pages dépendant d'interac ons précédentes :

.

Créa on dynamique de services

−→ L'histoire de l'interac on est gardée automa quement en mémoire(côté serveur)

−→ Vous pouvez retourner dans le passé (bouton ``back'')ou changer de fenêtre de navigateur

Page 84: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Sessions revisitéesDonnées de session sauvegardées dans des références avec une portée(scope).

..

Portée :Site

Session de navigateur (cookie)

..

Les services ont aussi une portée.

Page 85: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Sessions revisitéesÉtat côté serveur mis en œuvre grâce à des références avec une portée(scope).

..

Portée :Site

Session de navigateur (cookie)

Processus client (onglet)

Exemple : Si vous avez plusieurs instances d'un jeu dans plusieurs onglets,le score est une référence de portée « onglet ».

..

Les services ont aussi une portée.

Page 86: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Sessions revisitéesÉtat côté serveur mis en œuvre grâce à des références avec une portée(scope).

..

Portée :Site

Groupes de sessions (u lisateur)

Session de navigateur (cookie)

Processus client (onglet)

Exemple : partager le panier entre plusieurs terminaux !

..

Les services ont aussi une portée.

Page 87: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Sessions revisitéesÉtat côté serveur mis en œuvre grâce à des références avec une portée(scope).

..

Portée :Site

Groupes de sessions (u lisateur)

Session de navigateur (cookie)

Processus client (onglet)

Requête

Garder de l'informa on pendant la généra on d'une page.

..

Les services ont aussi une portée.

Page 88: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Sessions revisitéesÉtat côté serveur mis en œuvre grâce à des références avec une portée(scope).

..

Portée :Site

Groupes de sessions (u lisateur)

Session de navigateur (cookie)

Processus client (onglet)

Requête

..

Les services ont aussi une portée.

Page 89: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Web 1.0 + Web 2.0 = ?

..

Avec Ocsigen, le programme côté client ne s'arrête pas quandvous cliquez sur un lien !

−→ Les applica ons Ocsigen client-server sont 100% compa blesavec l'interac on Web tradi onnelle (signets, bouton back) !

−→ Vous pouvez garder un état côté client.−→ Certaines por ons de la page peuvent rester

après avoirchangé de page.−→ La musique ou les vidéos ne s'arrêtent pas.

Exemple : Site de streaming vidéo(con nuer sa naviga on pour choisir d'autres albums sans arrêter la musique)

Page 90: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Web 1.0 + Web 2.0 = ?

..

Avec Ocsigen, le programme côté client ne s'arrête pas quandvous cliquez sur un lien !

−→ Les applica ons Ocsigen client-server sont 100% compa blesavec l'interac on Web tradi onnelle (signets, bouton back) !

−→ Vous pouvez garder un état côté client.−→ Certaines por ons de la page peuvent rester

après avoirchangé de page.−→ La musique ou les vidéos ne s'arrêtent pas.

Exemple : Site de streaming vidéo(con nuer sa naviga on pour choisir d'autres albums sans arrêter la musique)

Page 91: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Web 1.0 + Web 2.0 = ?

..

Avec Ocsigen, le programme côté client ne s'arrête pas quandvous cliquez sur un lien !

−→ Les applica ons Ocsigen client-server sont 100% compa blesavec l'interac on Web tradi onnelle (signets, bouton back) !

−→ Vous pouvez garder un état côté client.−→ Certaines por ons de la page peuvent rester

après avoirchangé de page.−→ La musique ou les vidéos ne s'arrêtent pas.

Exemple : Site de streaming vidéo(con nuer sa naviga on pour choisir d'autres albums sans arrêter la musique)

Page 92: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

...

OCaml

Applica ons Web client-serveur

Programmer l'interac on Web tradi onelle

Générer du HTML

Conclusion

Page 93: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Généra on de HTML

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

(html(head

(title (pcdata "Graffiti"))[link ~rel :[ `Stylesheet ] ~href :(uri_of_string"./css/style.css") () ;script ~a :[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "") ;])

(body [h1 [pcdata "Graffiti"]])))

Page 94: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Généra on de HTML

...

{shared{open Eliom_pervasivesopen HTML5.Mlet width = 700let height = 400type messages = (string * int * (int * int) * (int * int)) deriving (Json)

}}

.

module My_appl = Eliom_output.Eliom_appl (structlet application_name = "graffiti"

end)

let b = Eliom_bus.create ~name:"graff" Json.t<messages>

.

{client{open Event_arrowslet draw ctx (color, size, (x1, y1), (x2, y2)) =

ctx##strokeStyle <- (Js.string color);ctx##lineWidth <- float size;ctx##beginPath();ctx##moveTo(float x1, float y1); ctx##lineTo(float x2, float y2);ctx##stroke()

}}

.

let main_service = My_appl.register_service ~path:[""] ~get_params:Eliom_parameters.unit(fun () () -> Eliom_services.onload

.

{{ let canvas = Dom_html.createCanvas Dom_html.document inlet ctx = canvas##getContext (Dom_html._2d_) incanvas##width <- width; canvas##height <- height;ctx##lineCap <- Js.string "round";Dom.appendChild Dom_html.document##body canvas;

let slider = jsnew Goog.Ui.slider(Js.null) inslider##setMinimum(1.); slider##setMaximum(80.);slider##render(Js.some Dom_html.document##body);

let pSmall = jsnew Goog.Ui.hsvPalette(Js.null, Js.null, Js.some (Js.string "goog-hsv-palette-sm")) in

pSmall##render(Js.some Dom_html.document##body);

let x = ref 0 and y = ref 0 inlet set_coord ev =

let x0, y0 = Dom_html.elementClientPosition canvas inx := ev##clientX - x0; y := ev##clientY - y0 in

let compute_line ev =let oldx = !x and oldy = !y inset_coord ev;let color = Js.to_string (pSmall##getColor()) inlet size = int_of_float (Js.to_float (slider##getValue())) in(color, size, (oldx, oldy), (!x, !y))

inlet (b : messages Eliom_bus.t) = %b inlet line ev =

let v = compute_line ev inlet _ = Eliom_bus.write b v indraw ctx v

inignore (Lwt_stream.iter (draw ctx) (Eliom_bus.stream b));ignore (run (mousedowns canvas

(arr (fun ev -> set_coord ev; line ev)>>> first [mousemoves Dom_html.document (arr line);

mouseup Dom_html.document >>> (arr line)])) ());}};

.

Lwt.return(html

(head(title (pcdata "Graffiti"))[link ~rel:[ `Stylesheet ] ~href:(uri_of_string"./css/style.css") ();script ~a:[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "");])

(body [h1 [pcdata "Graffiti"]])))

.

(html(head

(title (pcdata "Graffiti"))[link ~rel :[ `Stylesheet ] ~href :(uri_of_string"./css/style.css") () ;script ~a :[a_src (uri_of_string "./graffiti_oclosure.js")] (pcdata "") ;])

(body [h1 [pcdata "Graffiti"]])))

Page 95: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Générer du HTML

..

La validité du HTML est vérifiée à la compila on !

Page 96: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

..

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</html>

.

3

.

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</hmtl>

.

8

.

<html><head><title>Hello</title></head><body><title>Hello</title></body>

</html>

.8

.

_ rejetés à la compila on !

Page 97: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

..

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</html>

.

3

.

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</hmtl>

.

8

.

<html><head><title>Hello</title></head><body><title>Hello</title></body>

</html>

.8

.

_ rejetés à la compila on !

Page 98: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

..

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</html>

.

3

.

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</hmtl>

.

8

.

<html><head><title>Hello</title></head><body><title>Hello</title></body>

</html>

.8

.

_ rejetés à la compila on !

Page 99: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

..

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</html>

.

3

.

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</hmtl>

.

8

.

<html><head><title>Hello</title></head><body><title>Hello</title></body>

</html>

.8

.

_ rejetés à la compila on !

Page 100: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

..

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</html>

.

3

.

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</hmtl>

.

8

.

<html><head><title>Hello</title></head><body><title>Hello</title></body>

</html>

.8

.

_ rejetés à la compila on !

Page 101: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

..

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</html>

.

3

.

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</hmtl>

.

8

.

<html><head><title>Hello</title></head><body><title>Hello</title></body>

</html>

.8

.

_ rejetés à la compila on !

Page 102: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

..

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</html>

.

3

.

<html><head><title>Hello</title></head><body><h1>Hello</h1></body>

</hmtl>

.

8

.

<html><head><title>Hello</title></head><body><title>Hello</title></body>

</html>

.8

.

_ rejetés à la compila on !

Page 103: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

Les programmes pouvant générer des pages invalides sont rejetés par le compilateur !

..

f : () → block list

<body> f() </body>

.

3

.

<p> f() </p>

.

8

Page 104: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

Les programmes pouvant générer des pages invalides sont rejetés par le compilateur !

..

f : () → block list

<body> f() </body>

.

3

.

<p> f() </p>

.

8

Page 105: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

Les programmes pouvant générer des pages invalides sont rejetés par le compilateur !

..

f : () → block list

<body> f() </body>

.

3

.

<p> f() </p>

.

8

Page 106: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Produire du HTML valide

Les programmes pouvant générer des pages invalides sont rejetés par le compilateur !

..

f : () → block list

<body> f() </body>

.

3

.

<p> f() </p>

.

8

Page 107: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

...

OCaml

Applica ons Web client-serveur

Programmer l'interac on Web tradi onelle

Générer du HTML

Conclusion

Page 108: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Beaucoup de fonc onnalités uniques

..

Iden fica on de services sophis quée

.

Typages des liens, formulaires, paramètres

.

Typage du HTML

.

Services dynamiques

.

Services de session

.

Portée

.

Programma on client-server unifiée

.

Persistence du programme client

Page 109: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Beaucoup de fonc onnalités uniques

..

Iden fica on de services sophis quée

.

Typages des liens, formulaires, paramètres

.

Typage du HTML

.

Services dynamiques

.

Services de session

.

Portée

.

Programma on client-server unifiée

.

Persistence du programme client

Page 110: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Beaucoup de fonc onnalités uniques

..

Iden fica on de services sophis quée

.

Typages des liens, formulaires, paramètres

.

Typage du HTML

.

Services dynamiques

.

Services de session

.

Portée

.

Programma on client-server unifiée

.

Persistence du programme client

Page 111: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Beaucoup de fonc onnalités uniques

..

Iden fica on de services sophis quée

.

Typages des liens, formulaires, paramètres

.

Typage du HTML

.

Services dynamiques

.

Services de session

.

Portée

.

Programma on client-server unifiée

.

Persistence du programme client

Page 112: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Beaucoup de fonc onnalités uniques

..

Iden fica on de services sophis quée

.

Typages des liens, formulaires, paramètres

.

Typage du HTML

.

Services dynamiques

.

Services de session

.

Portée

.

Programma on client-server unifiée

.

Persistence du programme client

Page 113: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Beaucoup de fonc onnalités uniques

..

Iden fica on de services sophis quée

.

Typages des liens, formulaires, paramètres

.

Typage du HTML

.

Services dynamiques

.

Services de session

.

Portée

.

Programma on client-server unifiée

.

Persistence du programme client

Page 114: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Beaucoup de fonc onnalités uniques

..

Iden fica on de services sophis quée

.

Typages des liens, formulaires, paramètres

.

Typage du HTML

.

Services dynamiques

.

Services de session

.

Portée

.

Programma on client-server unifiée

.

Persistence du programme client

Page 115: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Beaucoup de fonc onnalités uniques

..

Iden fica on de services sophis quée

.

Typages des liens, formulaires, paramètres

.

Typage du HTML

.

Services dynamiques

.

Services de session

.

Portée

.

Programma on client-server unifiée

.

Persistence du programme client

Page 116: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Beaucoup de fonc onnalités uniques

..

Iden fica on de services sophis quée

.

Typages des liens, formulaires, paramètres

.

Typage du HTML

.

Services dynamiques

.

Services de session

.

Portée

.

Programma on client-server unifiée

.

Persistence du programme client

Page 117: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Users

Some companies and open source projects :BeSport, NYU CGSB Genomics Core, Pumgrana, Facebook, Life.tl,

Ashima Arts, Metaweb/Freebase, Hypios, Ocamlcore, Ocamlpro, Baoug,Nleyten...

Page 118: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Quelques-uns de nos projets

Page 119: Ocsigen - École pour l'informatique et les techniques ... · Qu'est-cequ'Ocsigen?. UnframeworkWebpour:.. lesapplicaonsHTML5 avecbeaucoupd'interacons client/serveur lessitesWebtradionnels

Le projet

..ocsigen.org

Logiciel libre --- Version 4.0 ce mois-ci !

Auteurs et contributeurs :Vincent Balat, Jérôme Vouillon, Pierre Chambart, Grégoire Henry, Benedikt Becker, RaphaëlProust, Benjamin Canou, Boris Yakobowski, Jérémie DiminoCharly Chevalier, Gabriel Radanne, Jacques-Pascal Deplaix, Stéphane Glondu, Gabriel Kerneis, ArnaudParant, Christophe Lecointe, Denis Berthod, Gabriel Cardoso, Piero Furiesi, Jaap Boender, ThorstenOhl, Gabriel Scherer, Séverine Maingaud, Simon Castellan, Jean-Henri Granarolo, Archibald Pon er,Nataliya Guts, Cécile Herbelin, Charles Oran, Jérôme Velleine, Pierre Clairambault …