-
Notifications
You must be signed in to change notification settings - Fork 43
JavaScript FFI
As of the Dalry release, Links supports a Javascript "foreign function interface", allowing JS functions to be called from Links web applications.
As an example, consider the following JavaScript code.
function _setTitle(s) {
document.title = s;
}
function _alertBox(s) {
alert(s);
}
var setTitle = LINKS.kify(_setTitle);
var alertBox = LINKS.kify(_alertBox);
_setTitle(s)
and _alertBox(s)
are direct-style functions. To fit in with the Links CPS calling convention, setTitle
and alertBox
should wrap the underscored direct-style functions in a call to LINKS.kify
.
Now, we can write some Links code!
module Test {
alien javascript "/js/test.js" {
setTitle : (String) ~%~> ();
alertBox : (String) ~%~> ();
}
}
fun mainPage(_) {
var _ = spawnClient {
Test.setTitle("Hello!");
Test.alertBox("Hola!")
};
page
<html><body><h1>Hi!</h1></body></html>
}
fun main() {
addRoute("/", mainPage);
addStaticRoute("/js", "js", [("js", "text/javascript")]);
servePages()
}
main()
Here, we define a module Test
containing the following alien
block:
alien javascript "/js/test.js" {
setTitle : (String) ~%~> ();
alertBox : (String) ~%~> ();
}
The block begins with the language (currently only javascript
is supported), and a URL to the JavaScript file. Next, the block contains two lines containing the names and types for the foreign functions. This will bring them into scope, allowing them to be used in the remainder of the application.
For example, when the mainPage
is run:
fun mainPage(_) {
var _ = spawnClient {
Test.setTitle("Hello!");
Test.alertBox("Hola!")
};
page
<html><body><h1>Hi!</h1></body></html>
}
a process will be spawned on the client which calls setTitle
and alertBox
in the Javascript.
Finally, to ensure that the JS file is served by the server, it's important to call addStaticRoute
to make the js
directory available:
addStaticRoute("/js", "js", [("js", "text/javascript")]);
Alien blocks are actually syntactic sugar. Sometimes, it may be concise to just use the following form:
alien javascript "/js/test.js" setTitle : (String) ~> ()
...to be continued