Index: examples/js/users-guide.md |
diff --git a/examples/js/README.md b/examples/js/users-guide.md |
similarity index 68% |
copy from examples/js/README.md |
copy to examples/js/users-guide.md |
index 7006327a6f4193f6cac616d1f013e2ea3bf9ba50..0152d832405890d51cc74e05ef15b701b3338422 100644 |
--- a/examples/js/README.md |
+++ b/examples/js/users-guide.md |
@@ -1,17 +1,10 @@ |
-JavaScript Mojo Example Applications |
-===================== |
- |
-hello.js, world.js - A minimal application that connects to another. |
- |
-wget.js - Uses the network service to load a URL. |
- |
-cube.js - A JS version of examples/sample_app. |
- |
---- Running Mojo Applications --- |
+# Running Mojo Applications |
A Mojo application written in JavaScript is launched with mojo_shell like this: |
- mojo_shell <js-application-url> |
+``` |
+ mojo_shell <js-application-url> |
+``` |
Where js-application-url is a URL understood by the shell. For example |
a file or an http URL that names a JS source file. The JS file itself |
@@ -19,7 +12,9 @@ must begin with a Mojo "shebang" that specifies the Mojo URL of the JS |
content handler. In other words, the first line of the JS source file |
must be: |
- #!mojo:js_content_handler |
+```javascript |
+#!mojo:js_content_handler |
+``` |
Following the shebang should be a single AMD module called "main" whose value |
is an Application subclass. The JS content handler will create an instance of |
@@ -28,6 +23,19 @@ is itself a Mojo application and it's responsible for creating an instance of V8 |
and loading the "main" JS module and all of the modules the main module |
depends on. |
+## JavaScript Classes |
+ |
+The JS content handler depends on the ECMAScript6 ("Harmony") classes feature. |
+ |
+As of January 2015 Chrome enables Harmony classes by default. |
+ |
+ |
+# The JS Application Class |
+ |
+Mojo JS applications are defined with the Application class. The |
+Application class handles incoming requests for services and provides |
+services of its own. |
+ |
This is the overall structure of a JS Mojo application: |
```javascript |
@@ -36,17 +44,18 @@ This is the overall structure of a JS Mojo application: |
define("main", ["mojo/services/public/js/application", |
<list of other modules that this application depends on> |
], |
- function(appModule, <one parameter per dependent module>) { |
- class MyApplication extends appModule.Application { |
- constructor(appShell, url) { |
- super(appShell, url); // Initializes this.shell, this.url. |
- // MyApplication initializations here. |
- } |
- |
- initialize(args) { |
- } |
- |
- acceptConnection(url, serviceProvider) { |
+ function(application, <one parameter per dependent module>) { |
+ class MyApplication extends application.Application { |
+ constructor(appShell, url) { |
+ super(appShell, url); // Initializes this.shell, this.url. |
+ // MyApplication initializations here. |
+ } |
+ |
+ initialize(args) { |
+ } |
+ |
+ acceptConnection(url, serviceProvider) { |
+ } |
} |
} |
@@ -56,16 +65,16 @@ define("main", ["mojo/services/public/js/application", |
The hello.js example is little more than this basic skeleton. |
-The JS content handler loads the "main" module and makes an instance of its |
-value, which must be an Application subclass. The application's constructor is |
-passed two arguments: |
+The JS content handler loads the "main" module and constructs an |
+instance of its value, which must be an Application subclass. The |
+application's constructor is passed two arguments: |
-appShell - a pointer to the Mojo shell. Typically this will be wrapped by a |
- Shell object, see below. |
+* `appShell` - a pointer to the Mojo shell. Typically this will be wrapped by a |
+ JS Shell object, see below. |
-url - the URL this application was loaded from as a String. |
+* `url` - the URL this application was loaded from as a String. |
-The (inherited) Application class constructor initializes the shell and url |
+The inherited Application class constructor initializes the shell and url |
properties. It's unlikely that you'll want to use the appShell argument |
directly. |
@@ -73,57 +82,58 @@ The initialize() and acceptConnection() methods are defined by application.mojom |
and they're needed because the JS content handler makes the JS application the |
Mojo shell's client. |
+The intiailize() method is called once, after the constructor has run |
+and before any calls to acceptConnection(). The value of its parameter |
+is argument list specified for this application with |
+mojo_shell. Arguments can be specified using the mojo_shell |
+`--args-for` command line argument or by just adding them after the |
+application's URL and enclosing the entire expression in quotes. |
---- JavaScript Classes --- |
- |
-The JS content handler depends on the ECMAScript6 ("Harmony") classes feature. |
- |
- |
- |
---- Mojo Application Structure --- |
+``` |
+ mojo_shell '<js-application-url> arg1 arg2' |
+``` |
+See the wget.js for an example of command-line argument use. |
-Mojo applications can connect to services provided by other applications and |
-they can provide services of their own. A service is an implementation of a Mojo |
-interface that was defined as part of a Mojo module in a ".mojom" file. |
+The acceptConnection() method is called each time another application connects |
+to this one. The first call corresponds the mojo_shell's initial connection. |
+The serviceProvider parameter is a JS ServiceProvider, see the "Requesting |
+and Providing Services" section below. |
-To implement a service you'll need the JS "bindings" for the Mojo interface. The |
-bindings are generated by the build system and end up in files whose name is the |
-same as the '.mojom' file with a '.js' suffix. It's often helpful to look at the |
-generated 'mojom.js' files. |
+## JS Bindings |
-The JS Shell class simplifies connecting to applications and services. It's a |
-wrapper for the Application's appShell argument. The Application constructor |
-creates a Shell and assigns it to |this.shell|. |
+To use or implement a service you'll need the JS "bindings" for the |
+Mojo interface. The bindings are generated by the build system and end |
+up in files whose name is the same as the '.mojom' file with a '.js' |
+suffix. It's often helpful to look at the generated '.mojom.js' files. |
-The Shell's connectToService() method returns a "proxy" to a service provided by |
-another application. |
The JS bindings for a Mojo interface's API are delivered as a JS module whose |
name is based on the '.mojom' file's path. For example, to use the Mojo network |
service you need the JS module based on network_service.mojom: |
```javascript |
-define("main", [ |
- "mojo/services/network/public/interfaces/network_service.mojom", |
- "mojo/services/public/js/application", |
-] |
- function(netModule, appModule) { |
- class MyApplication extends appModule.Application { |
- initialize(args) { |
- var netService = this.shell.connectToService( |
- "mojo:network_service", netModule.NetworkService); |
- // Use netService's NetworkService methods. |
+ define("main", [ |
+ "mojo/services/network/public/interfaces/network_service.mojom", |
+ "mojo/services/public/js/application", |
+ ] |
+ function(net, application) { |
+ class MyApplication extends application.Application { |
+ initialize(args) { |
+ var netService = this.shell.connectToService( |
+ "mojo:network_service", net.NetworkService); |
+ // Use netService's NetworkService methods. |
+ } |
+ ... |
} |
... |
} |
- |
return MyApplication; |
}); |
``` |
The first connectToService() parameter is the Mojo URL for the network service |
application and the second is the JS "interface" object for NetworkService. The |
-JS interface object's properties identify the (generated) JS bindings classes |
+JS interface object's properties identify the generated JS bindings classes |
used to provide or connect to a service. For example (from |
network_service.mojom.js): |
@@ -139,13 +149,22 @@ var NetworkService = { |
The 'proxyClass' is used to access another application's NetworkService and the |
'stubClass' is used to create an implementation of NetworkService. |
+## The JS Shell Class |
+ |
+The JS Shell class simplifies connecting to applications and services. It's a |
+wrapper for the Application's appShell argument. The Application constructor |
+creates a Shell and assigns it to `this.shell`. |
+ |
+The Shell's connectToService() method returns a "proxy" to a service provided by |
+another application. |
+ |
In the netService case above the Shell connects to the Mojo application at |
"mojo:network_service", then connects to its service called |
-'NetworkService.name' with an instance of 'NetworkService.proxyClass'. The proxy |
+NetworkService.name with an instance of NetworkService.proxyClass. The proxy |
instance is returned. The netService proxy can be used immediately. |
---- Mojo Responses are Promises --- |
+## Mojo Responses are Promises |
Mojo functions can return zero or more values called a "response". For example |
the EchoString function below returns a string or null. |
@@ -161,7 +180,7 @@ caller provides a Callback object whose Run() method has one argument for |
each response parameter. In JS, Mojo functions that specify a response return |
a Promise object. The Promise resolves to an object with one property per |
response parameter. In the EchoString case that would be something like |
-{value: "foo"}. |
+`{value: "foo"}`. |
Similarly, the implementation of a Mojo interface functions that specify a |
response, must return a Promise. The implementation of EchoString() could |
@@ -173,7 +192,11 @@ MyEchoStringImpl.prototype.EchoString = function(s) { |
}; |
``` |
-- Applications can request and provide services |
+## Requesting and Providing Services |
+ |
+Mojo applications can connect to services provided by other applications and |
+they can provide services of their own. A service is an implementation of a Mojo |
+interface that was defined as part of a Mojo module in a ".mojom" file. |
When an application starts, its initialize() method runs and then its |
acceptConnection() method runs. The acceptConnection() method |
@@ -224,7 +247,7 @@ interface EchoService { |
}; |
``` |
--- Requesting a service using the Application's Shell |
+### Requesting a Service Using the Application's Shell |
Given the URL of a Mojo application that implements the EchoService we |
can use the application's shell to get an EchoService proxy. Here's a |
@@ -253,7 +276,7 @@ define("main", [ |
``` |
--- Providing a service |
+### Providing a Service |
A complete application that unconditionally provides the EchoService |
looks like this: |
@@ -292,14 +315,14 @@ function will be called. The caller will be able to run the |
echoString() method and will get its response via a Promise. |
--- Final note |
+## Final note |
An initiator's serviceProvider object can be retained and used to |
request or provide services at any time, not just from within |
application's acceptConnection() method. |
---- Interface Parameters --- |
+# Interface Parameters |
The caller and callee use cases that follow are in terms of the following mojom: |
@@ -318,22 +341,21 @@ interface I { |
} |
``` |
--- In General |
+## Stubs and Proxies |
-From a user's point of view, the bindings are in terms of the (remote) |
-proxy class and the (local) stub class's implementation delegate |
-(internally, that's the stub class's delegate$ property). The |
-bindings will add/use a local$ property on proxy objects which points |
-to the stub class's implementation delegate. They also manage remote$ |
-property on the implementation delegate whose value is the proxy. |
+TODO: briefly introduce message pipes. |
+TODO: explain what stubs and proxies are, explain what's meant by "local" and "remote". |
+TODO: explain the StubBindings and ProxyBindings functions. |
+TODO: support creating a proxy from a handle new MyProxy(someHandle); |
+TODO: explain the Connection object and how it relates to this stuff. |
-All that implies: |
+From a user's point of view, the bindings are in terms of the (remote) |
+proxy class and the (local) stub class. Properties are added to instances |
+of these classes using functions called StubBindings and ProxyBindings. |
-fooImpl.remote$.local$ == fooImpl (the stub class's delegate) |
-fooProxy.local$.remote$ == fooProxy |
--- Callers |
+## Callers |
Assuming that we have a proxy for interface I, iProxy. |
@@ -341,23 +363,30 @@ An iProxy.provideFoo() call implies that we have an implementation of |
Foo, and want a proxy for Bar (Foo's client). |
```javascript |
-var myFooImpl; |
-provideFoo(myFooImpl); |
-myFooImpl.remote$; // A Bar proxy initialized by provideFoo(), undefined if Foo has no client. |
+var barProxy; |
+iProxy.provideFoo(function(remote) { |
+ barProxy = remote; |
+ return myFooImpl; |
+}); |
``` |
An iProxy.requestFoo() call implies that we have an implementation of |
Bar and want a proxy for Foo (Bar's client). |
```javascript |
-var myBarImpl; // If Foo has no client then this is just {}. |
-requestFoo(myBarImpl); |
-myBarImpl.remote$; // A Foo proxy initialized by requestFoo. |
+var fooProxy; |
+iProxy.requestFoo(function(remote) { |
+ fooProxy = remote; |
+ return myBarImpl; |
+}); |
``` |
+In the requestFoo() case, if no client were defined for Bar the function |
+parameter need not return anything. |
+ |
The wget.js example includes a request for the URLLoader service. |
--- Callees |
+## Callees |
An implementation of provideFoo(Foo foo) implies that we have an |
implementation of Bar (Foo's client) and want a proxy to the Foo |
@@ -365,7 +394,7 @@ that has been passed to us. |
```javascript |
void provideFoo(fooProxy) { |
- fooProxy.local$ = myBarImpl; // sets myFooImpl.remote$ = fooProxy |
+ ProxyBindings(fooProxy).setLocalDelegate(myMyBarImpl); |
} |
``` |
@@ -375,7 +404,6 @@ that's been passed to us. |
```javascript |
void requestFoo(barProxy) { |
- barProxy.local$ = myFooImpl; // sets myFooImpl.remote$ = barProxy |
+ ProxyBindings(barProxy).setLocallocalDelegate(myFooImpl); |
} |
``` |
- |