| Index: examples/js/README.md
|
| diff --git a/examples/js/README.md b/examples/js/README.md
|
| index 3b951c4bd19af75f7a77f9dd7d88095a6895061d..6e757af06e95a57f3bfc8c8f8324956830d5bf74 100644
|
| --- a/examples/js/README.md
|
| +++ b/examples/js/README.md
|
| @@ -5,3 +5,176 @@ hello.js, world.js - A minimal application that connects to another.
|
|
|
| wget.js - Uses the network service to load a URL.
|
|
|
| +
|
| +--- Running Mojo Applications ---
|
| +
|
| +A Mojo application written in JavaScript is launched with mojo_shell like this:
|
| +
|
| + mojo_shell <js-application-url>
|
| +
|
| +Where js-application-url is either a file or an http URL that names a JS source
|
| +file. The JS file itself 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
|
| +
|
| +Following the shebang should be a single AMD module called "main" whose value
|
| +is an Application class. The JS content handler will create an instance of the
|
| +Application and make it the client of the Mojo shell. The JS content handler 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.
|
| +
|
| +The overall structure of a JS Mojo application is this:
|
| +
|
| + #!mojo:js_content_handler
|
| +
|
| + define("main", [<list of modules this application depends on>],
|
| + function(<one parameter per dependent module>) {
|
| + function Application(appShell, url) {
|
| + }
|
| +
|
| + Application.prototype.initialize = function(args) {
|
| + }
|
| +
|
| + Application.prototype.acceptConnection = function(url, spHandle) {
|
| + }
|
| +
|
| + return 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 the application's class. 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.
|
| +
|
| +url - the URL this application was loaded from as a String.
|
| +
|
| +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.
|
| +
|
| +
|
| +--- Mojo Application Structure ---
|
| +
|
| +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.
|
| +
|
| +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.
|
| +
|
| +The JS Shell class simplifies connecting to applications and services. It's a
|
| +wrapper for the Application's appShell argument.
|
| +
|
| +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:
|
| +
|
| + define("main", [
|
| + "mojo/services/public/interfaces/network/network_service.mojom",
|
| + "mojo/services/public/js/shell",
|
| + ]
|
| + function(netModule, shellModule) {
|
| + function Application(appShell, url) {
|
| + this.shell = new shellModule.Shell(appShell);
|
| + }
|
| +
|
| + Application.prototype.initialize = function(args) {
|
| + var netService = this.shell.connectToService(
|
| + "mojo:network_service", netModule.NetworkService);
|
| +
|
| + }
|
| + ...
|
| + return Application;
|
| + });
|
| +
|
| +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
|
| +used to provide or connect to a service. For example (from
|
| +network_service.mojom.js):
|
| +
|
| + var NetworkService = {
|
| + name: 'mojo::NetworkService', // Fully qualified Mojo interface name.
|
| + proxyClass: NetworkServiceProxy,
|
| + stubClass: NetworkServiceStub,
|
| + // ...
|
| + };
|
| +
|
| +The 'proxyClass' is used to access another application's NetworkService and the
|
| +'stubClass' is used to create an implementation of NetworkService.
|
| +
|
| +In the netService case above the Shell connects to the Mojo application at
|
| +"mojo:network_service", then connects its service called
|
| +'NetworkService.name' with an instance of 'NetworkService.proxyClass'. The proxy
|
| +instance is returned.
|
| +
|
| +
|
| +--- Interface Parameters ---
|
| +
|
| +Mojo functions with interface valued parameters allow one to request a service
|
| +from a service or to provide a service to a service. The
|
| +indirect_service example demonstrates this.
|
| +
|
| +The NetworkService CreateURLLoader() method has an interface request parameter:
|
| +
|
| + interface NetworkService {
|
| + CreateURLLoader(URLLoader& loader); // Return a URLLoader to the caller.
|
| + ...
|
| + }
|
| +
|
| +Interface request parameters can be specified as an instance of the interface's
|
| +proxy class. Ordinary interface parameters can be specified as an instance of
|
| +the interface's stub class. The stub class constructor has an optional delegate
|
| +parameter that defines the stub's implementation.
|
| +
|
| +Here's an example of an interface request parameter taken from wget.js:
|
| +
|
| + var urlLoader = new loader.URLLoader.proxyClass;
|
| + netService.createURLLoader(urlLoader); // interface& parameter
|
| +
|
| + var urlRequest = new loader.URLRequest({
|
| + url: "http://www.cnn.com",
|
| + method: "GET",
|
| + auto_follow_redirects: true
|
| + });
|
| +
|
| + urlLoader.start(urlRequest).then(function(result) {
|
| + // ..Do something with result.response
|
| + });
|
| +
|
| +
|
| +--- 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.
|
| +
|
| +interface EchoService {
|
| + EchoString(string? value) => (string? value);
|
| +};
|
| +
|
| +The response is delivered to the function caller asynchronously. In C++ the
|
| +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"}.
|
| +
|
| +Similarly, the implementation of a Mojo interface functions that specify a
|
| +response, must return a Promise. The implementation of EchoString() could
|
| +be written like this:
|
| +
|
| + MyEchoStringImpl.prototype.EchoString = function(s) {
|
| + return Promise.resolve({value: s});
|
| + };
|
|
|