Commit 3d21f6a3 authored by Ken Rockot's avatar Ken Rockot Committed by Commit Bot

Mojo: Introduce Mojo JS bindings modules

This CL introduces generated mojom.m.js modules for mojom JS bindings,
allowing most JS bindings consumers to import bindings with the
convenience and efficiency afforded by JS modules.

These modules can be used as-is by Component Extensions, Web Platform
Tests, and Blink Web Tests. A follow-up change will introduce a slight
variation on these modules to support consumption by WebUI pages.

Bug: 1004256
Change-Id: Ic2b4a6bcadf68023d2078bf065befafce3ccb19b
Tbr: sky@chromium.org
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2451589
Commit-Queue: Ken Rockot <rockot@google.com>
Reviewed-by: default avatarOksana Zhuravlova <oksamyt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815471}
parent faea5c30
...@@ -1052,6 +1052,7 @@ if (!is_ios) { ...@@ -1052,6 +1052,7 @@ if (!is_ios) {
":layout_test_data_mojo_bindings", ":layout_test_data_mojo_bindings",
":layout_test_data_mojo_bindings_lite", ":layout_test_data_mojo_bindings_lite",
"//content/shell:content_shell", "//content/shell:content_shell",
"//content/test:mojo_bindings_web_test_mojom_js_data_deps",
"//content/test:mojo_web_test_bindings_js_data_deps", "//content/test:mojo_web_test_bindings_js_data_deps",
"//device/bluetooth/public/mojom:fake_bluetooth_interfaces_js_data_deps", "//device/bluetooth/public/mojom:fake_bluetooth_interfaces_js_data_deps",
"//device/vr/public/mojom:mojom_js_data_deps", "//device/vr/public/mojom:mojom_js_data_deps",
......
...@@ -799,6 +799,14 @@ mojom("test_interfaces") { ...@@ -799,6 +799,14 @@ mojom("test_interfaces") {
sources = [ "echo.mojom" ] sources = [ "echo.mojom" ]
} }
mojom("mojo_bindings_web_test_mojom") {
testonly = true
sources = [
"data/mojo_bindings_web_test.test-mojom",
"data/mojo_bindings_web_test_types.test-mojom",
]
}
if (is_android) { if (is_android) {
static_library("android_test_message_pump_support") { static_library("android_test_message_pump_support") {
testonly = true testonly = true
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module mojo_bindings_test.mojom;
// NOTE: This import exists to exercise automatic dependency loading in
// generated JS modules.
import "content/test/data/mojo_bindings_web_test_types.test-mojom";
// An interface whose definition covers various types of message signatures in
// order to exercise the lite JS mojom bindings.
interface TestMessageTarget {
enum NestedEnum {
kFoo,
kBar,
};
// Zero arguments, no reply.
Poke();
// Zero-argument request, zero-argument reply.
Ping() => ();
// Request and reply both with arguments.
Repeat(string? message, array<int32>? numbers)
=> (string? message, array<int32>? numbers);
Echo(NestedEnum nested) => (NestedEnum nested);
Deconstruct(TestStruct test_struct)
=> (int32 x, int32 y,
// Using TestStruct.StructEnum causes a compile failure. Use
// int32 instead.
// TODO(crbug.com/1011660): Change |z| to TestStruct.StructEnum.
int32 z);
Flatten(array<TestStruct> values) => (array<int32> values);
FlattenUnions(array<TestUnion> unions) => (array<int32> x, array<int32> s);
RequestSubinterface(pending_receiver<Subinterface> receiver,
pending_remote<SubinterfaceClient> client);
};
interface Subinterface {
Push(int32 value);
Flush();
};
interface SubinterfaceClient {
DidFlush(array<int32> values);
};
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module mojo_bindings_test.mojom;
struct TestStruct {
enum StructEnum {
kZero = 0,
kOne = 1,
};
const int32 kStructConst = 2;
int32 x;
int32 y = kStructConst;
StructEnum z = StructEnum.kOne;
const bool isValid = false;
};
union TestUnion {
int32 x;
TestStruct s;
};
...@@ -49,21 +49,68 @@ action("bindings") { ...@@ -49,21 +49,68 @@ action("bindings") {
deps = [ "//mojo/public/interfaces/bindings:bindings_js__generator" ] deps = [ "//mojo/public/interfaces/bindings:bindings_js__generator" ]
} }
bindings_lite_sources = [ template("concatenate_files") {
"bindings_lite.js", action(target_name) {
"interface_support.js", script = "//mojo/public/tools/bindings/concatenate-files.py"
] inputs = invoker.inputs
output = "$target_gen_dir/${invoker.output}"
outputs = [ output ]
args = rebase_path(inputs, root_build_dir) +
[ rebase_path(output, root_build_dir) ]
if (defined(invoker.deps)) {
deps = invoker.deps
}
}
}
concatenate_files("generate_mojo_internal_js") {
inputs = [
"mojo_internal_preamble.js.part",
"bindings_lite.js",
]
output = "mojo_internal.js"
}
bindings_lite_compiled_file = "$target_gen_dir/mojo_bindings_lite.js" concatenate_files("generate_interface_support_js") {
inputs = [
"interface_support_preamble.js.part",
"interface_support.js",
]
output = "interface_support.js"
}
js_library("bindings_lite_sources") { js_library("bindings_lite_sources") {
sources = [ "compile_preamble.js" ] + bindings_lite_sources sources = [
"$target_gen_dir/interface_support.js",
"$target_gen_dir/mojo_internal.js",
"compile_preamble.js",
]
deps = [ "//mojo/public/interfaces/bindings:bindings_js_library_for_compile" ] deps = [ "//mojo/public/interfaces/bindings:bindings_js_library_for_compile" ]
extra_deps = [
":generate_interface_support_js",
":generate_mojo_internal_js",
]
}
# All generated mojom JS modules consume the API defined by this module. The
# uncompiled source is simply a concatenation of the various pieces listed
# below.
concatenate_files("bindings_uncompiled_module") {
inputs = [
"bindings_module_preamble.js.part",
"bindings_lite.js",
"$root_gen_dir/mojo/public/interfaces/bindings/interface_control_messages.mojom-lite.js",
"interface_support.js",
"bindings_uncompiled_module_export.js.part",
]
output = "bindings_uncompiled.m.js"
deps = [ "//mojo/public/interfaces/bindings:bindings_js_library" ]
} }
if (enable_mojom_closure_compile || enable_js_type_check) { if (enable_mojom_closure_compile || enable_js_type_check) {
js_binary("bindings_lite") { js_binary("bindings_lite") {
outputs = [ bindings_lite_compiled_file ] outputs = [ "$target_gen_dir/mojo_bindings_lite.js" ]
sources = []
deps = [ ":bindings_lite_sources" ] deps = [ ":bindings_lite_sources" ]
externs_list = [ externs_list = [
"$externs_path/mojo_core.js", "$externs_path/mojo_core.js",
...@@ -78,18 +125,58 @@ if (enable_mojom_closure_compile || enable_js_type_check) { ...@@ -78,18 +125,58 @@ if (enable_mojom_closure_compile || enable_js_type_check) {
"isolation_mode=IIFE", "isolation_mode=IIFE",
] ]
} }
concatenate_files("bindings_compiled_module") {
inputs = [
"$target_gen_dir/mojo_bindings_lite.js",
"bindings_module_export.js.part",
]
output = "bindings_compiled.m.js"
deps = [ ":bindings_lite" ]
}
copy("bindings_module") {
sources = [ "$target_gen_dir/bindings_compiled.m.js" ]
outputs = [ "$target_gen_dir/bindings.m.js" ]
deps = [ ":bindings_compiled_module" ]
}
} else { } else {
action("bindings_lite") { action("bindings_lite") {
all_sources = bindings_lite_sources + [ "$root_gen_dir/mojo/public/interfaces/bindings/interface_control_messages.mojom-lite.js" ] inputs = [
"$target_gen_dir/mojo_internal.js",
"$root_gen_dir/mojo/public/interfaces/bindings/interface_control_messages.mojom-lite-for-compile.js",
"$target_gen_dir/interface_support.js",
]
script = "//mojo/public/tools/bindings/concatenate_and_replace_closure_exports.py" script = "//mojo/public/tools/bindings/concatenate_and_replace_closure_exports.py"
sources = all_sources sources = inputs
outputs = [ bindings_lite_compiled_file ] outputs = [ "$target_gen_dir/mojo_bindings_lite.js" ]
args = rebase_path(all_sources, root_build_dir) + args =
[ rebase_path(bindings_lite_compiled_file, root_build_dir) ] rebase_path(inputs, root_build_dir) +
deps = [ "//mojo/public/interfaces/bindings:bindings_js__generator" ] [ rebase_path("$target_gen_dir/mojo_bindings_lite.js", root_build_dir) ]
deps = [
":generate_interface_support_js",
":generate_mojo_internal_js",
"//mojo/public/interfaces/bindings:bindings_js__generator",
]
}
copy("bindings_module") {
sources = [ "$target_gen_dir/bindings_uncompiled.m.js" ]
outputs = [ "$target_gen_dir/bindings.m.js" ]
deps = [ ":bindings_uncompiled_module" ]
} }
} }
# This is the library target used in the dependency tree of any JS libraries
# or binaries compiling against mojom JS bindings. This library is functionally
# equivalent to the bindings.m.js generated by the ":bindings_module" target and
# used at runtime by all consumers, except that this module includes all type
# annotations and is suitable for Closure compilation and type checking.
js_library("bindings_uncompiled.m") {
sources = [ "$target_gen_dir/bindings_uncompiled.m.js" ]
extra_deps = [ ":bindings_uncompiled_module" ]
}
grit("resources") { grit("resources") {
source = "mojo_bindings_resources.grd" source = "mojo_bindings_resources.grd"
......
// Copyright 2018 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
'use strict';
goog.provide('mojo.internal');
// "self" is always defined as opposed to "this", which isn't defined in
// modules, or "window", which isn't defined in workers.
/** @const {!Object} */
mojo.internal.globalScope = self;
/**
* This is effectively the same as goog.provide, but it's made available under
* the mojo.internal namespace to avoid potential collisions in certain
* compilation environments.
*
* @param {string} namespace
* @export
*/
mojo.internal.exportModule = function(namespace) {
let current = mojo.internal.globalScope;
const parts = namespace.split('.');
for (let part; parts.length && (part = parts.shift());) {
if (!current[part])
current[part] = {};
current = current[part];
}
};
/** @const {number} */ /** @const {number} */
mojo.internal.kArrayHeaderSize = 8; mojo.internal.kArrayHeaderSize = 8;
......
const mojoTmp = self['mojo'];
delete self['mojo'];
export const mojo = mojoTmp;
const mojo = {
internal: { interfaceSupport: {} },
interfaceControl: {}
};
// Copyright 2018 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
'use strict';
goog.require('mojo.interfaceControl.RUN_MESSAGE_ID');
goog.require('mojo.interfaceControl.RunResponseMessageParamsSpec');
goog.require('mojo.internal');
goog.provide('mojo.internal.interfaceSupport');
/** /**
* Handles incoming interface control messages on a remote or router endpoint. * Handles incoming interface control messages on a remote or router endpoint.
......
'use strict';
goog.require('mojo.interfaceControl.RUN_MESSAGE_ID');
goog.require('mojo.interfaceControl.RunResponseMessageParamsSpec');
goog.require('mojo.internal');
goog.provide('mojo.internal.interfaceSupport');
'use strict';
goog.provide('mojo.internal');
// "self" is always defined as opposed to "this", which isn't defined in
// modules, or "window", which isn't defined in workers.
/** @const {!Object} */
mojo.internal.globalScope = self;
/**
* This is effectively the same as goog.provide, but it's made available under
* the mojo.internal namespace to avoid potential collisions in certain
* compilation environments.
*
* @param {string} namespace
* @export
*/
mojo.internal.exportModule = function(namespace) {
let current = mojo.internal.globalScope;
const parts = namespace.split('.');
for (let part; parts.length && (part = parts.shift());) {
if (!current[part])
current[part] = {};
current = current[part];
}
};
...@@ -69,11 +69,16 @@ action("precompile_templates") { ...@@ -69,11 +69,16 @@ action("precompile_templates") {
"$mojom_generator_root/generators/js_templates/fuzzing.tmpl", "$mojom_generator_root/generators/js_templates/fuzzing.tmpl",
"$mojom_generator_root/generators/js_templates/interface_definition.tmpl", "$mojom_generator_root/generators/js_templates/interface_definition.tmpl",
"$mojom_generator_root/generators/js_templates/lite/enum_definition.tmpl", "$mojom_generator_root/generators/js_templates/lite/enum_definition.tmpl",
"$mojom_generator_root/generators/js_templates/lite/enum_definition_for_module.tmpl",
"$mojom_generator_root/generators/js_templates/lite/interface_definition.tmpl", "$mojom_generator_root/generators/js_templates/lite/interface_definition.tmpl",
"$mojom_generator_root/generators/js_templates/lite/interface_definition_for_module.tmpl",
"$mojom_generator_root/generators/js_templates/lite/module_definition.tmpl", "$mojom_generator_root/generators/js_templates/lite/module_definition.tmpl",
"$mojom_generator_root/generators/js_templates/lite/mojom-lite.js.tmpl", "$mojom_generator_root/generators/js_templates/lite/mojom-lite.js.tmpl",
"$mojom_generator_root/generators/js_templates/lite/mojom.m.js.tmpl",
"$mojom_generator_root/generators/js_templates/lite/struct_definition.tmpl", "$mojom_generator_root/generators/js_templates/lite/struct_definition.tmpl",
"$mojom_generator_root/generators/js_templates/lite/struct_definition_for_module.tmpl",
"$mojom_generator_root/generators/js_templates/lite/union_definition.tmpl", "$mojom_generator_root/generators/js_templates/lite/union_definition.tmpl",
"$mojom_generator_root/generators/js_templates/lite/union_definition_for_module.tmpl",
"$mojom_generator_root/generators/js_templates/module.amd.tmpl", "$mojom_generator_root/generators/js_templates/module.amd.tmpl",
"$mojom_generator_root/generators/js_templates/module_definition.tmpl", "$mojom_generator_root/generators/js_templates/module_definition.tmpl",
"$mojom_generator_root/generators/js_templates/struct_definition.tmpl", "$mojom_generator_root/generators/js_templates/struct_definition.tmpl",
......
{%- macro enum_def(enum_spec_parent, enum_parent, enum) -%} {%- macro enum_def(enum) -%}
{# TODO: Less generic enum annotations would be nice. We do it this way because
the bindings generator is still too stupid to generate the right integral
constants directly. #}
{%- set enum_name = enum|lite_closure_type -%}
{% if generate_closure_exports -%}
goog.provide('{{enum_name}}');
goog.provide('{{enum_spec_parent}}.{{enum.name}}Spec');
{%- endif %}
/** /**
* @const { {$: !mojo.internal.MojomType} } * @const { {$: !mojo.internal.MojomType} }
* @export
*/ */
{{enum_spec_parent}}.{{enum.name}}Spec = { $: mojo.internal.Enum() }; export const {{enum|type_in_js_module}}Spec = { $: mojo.internal.Enum() };
/** /**
* @enum {number} * @enum {number}
* @export
*/ */
{{enum_name}} = { export const {{enum|type_in_js_module}} = {
{# Set up the enum here, but fill out the values later. #} {# Set up the enum here, but fill out the values later. #}
{%- for field in enum.fields %} {%- for field in enum.fields %}
{{field.name}}: {{field.numeric_value}}, {{field.name}}: {{field.numeric_value}},
......
{% macro generateMethodAnnotation(method) %} {% macro generateMethodAnnotation(method) %}
/** /**
{%- for param in method.parameters %} {%- for param in method.parameters %}
* @param { {{param.kind|lite_closure_type_with_nullability}} } {{param.name|sanitize_identifier}} * @param { {{param.kind|type_in_js_module_with_nullability}} } {{param.name|sanitize_identifier}}
{%- endfor -%} {%- endfor -%}
{%- if method.response_parameters != None %} {%- if method.response_parameters != None %}
{%- if method.response_parameters|length == 0 %} {%- if method.response_parameters|length == 0 %}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
{%- else %} {%- else %}
* @return {!Promise<{ * @return {!Promise<{
{%- for response_parameter in method.response_parameters %} {%- for response_parameter in method.response_parameters %}
{{response_parameter.name}}: {{response_parameter.kind|lite_closure_type_with_nullability}}, {{response_parameter.name}}: {{response_parameter.kind|type_in_js_module_with_nullability}},
{%- endfor %} {%- endfor %}
* }>} * }>}
{%- endif %} {%- endif %}
...@@ -17,20 +17,10 @@ ...@@ -17,20 +17,10 @@
*/ */
{% endmacro %} {% endmacro %}
{% if generate_closure_exports -%}
goog.provide('{{module.namespace}}.{{interface.name}}');
goog.provide('{{module.namespace}}.{{interface.name}}Receiver');
goog.provide('{{module.namespace}}.{{interface.name}}CallbackRouter');
goog.provide('{{module.namespace}}.{{interface.name}}Interface');
goog.provide('{{module.namespace}}.{{interface.name}}Remote');
goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
{% endif %}
/** /**
* @implements {mojo.internal.interfaceSupport.PendingReceiver} * @implements {mojo.internal.interfaceSupport.PendingReceiver}
* @export
*/ */
{{module.namespace}}.{{interface.name}}PendingReceiver = class { export const {{interface.name}}PendingReceiver = class {
/** @param {!MojoHandle} handle */ /** @param {!MojoHandle} handle */
constructor(handle) { constructor(handle) {
/** @public {!MojoHandle} */ /** @public {!MojoHandle} */
...@@ -38,9 +28,8 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver'); ...@@ -38,9 +28,8 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
} }
}; };
{% if generate_closure_exports -%}
/** @interface */ /** @interface */
{{module.namespace}}.{{interface.name}}Interface = class { export const {{interface.name}}Interface = class {
{%- for method in interface.methods %} {%- for method in interface.methods %}
{{generateMethodAnnotation(method)}} {{generateMethodAnnotation(method)}}
{{method.name}}( {{method.name}}(
...@@ -50,25 +39,23 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver'); ...@@ -50,25 +39,23 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
) {} ) {}
{%- endfor %} {%- endfor %}
}; };
{%- endif %}
/** /**
* @export * @implements { {{interface.name}}Interface }
* @implements { {{module.namespace}}.{{interface.name}}Interface }
*/ */
{{module.namespace}}.{{interface.name}}Remote = class { export const {{interface.name}}Remote = class {
/** @param {MojoHandle=} opt_handle */ /** @param {MojoHandle=} opt_handle */
constructor(opt_handle) { constructor(opt_handle) {
/** /**
* @private {!mojo.internal.interfaceSupport.InterfaceRemoteBase<!{{module.namespace}}.{{interface.name}}PendingReceiver>} * @private {!mojo.internal.interfaceSupport.InterfaceRemoteBase<!{{interface.name}}PendingReceiver>}
*/ */
this.proxy = this.proxy =
new mojo.internal.interfaceSupport.InterfaceRemoteBase( new mojo.internal.interfaceSupport.InterfaceRemoteBase(
{{module.namespace}}.{{interface.name}}PendingReceiver, {{interface.name}}PendingReceiver,
opt_handle); opt_handle);
/** /**
* @public {!mojo.internal.interfaceSupport.InterfaceRemoteBaseWrapper<!{{module.namespace}}.{{interface.name}}PendingReceiver>} * @public {!mojo.internal.interfaceSupport.InterfaceRemoteBaseWrapper<!{{interface.name}}PendingReceiver>}
*/ */
this.$ = new mojo.internal.interfaceSupport.InterfaceRemoteBaseWrapper(this.proxy); this.$ = new mojo.internal.interfaceSupport.InterfaceRemoteBaseWrapper(this.proxy);
...@@ -91,9 +78,9 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver'); ...@@ -91,9 +78,9 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
this.proxy.sendMessage( this.proxy.sendMessage(
{%- endif %} {%- endif %}
{{method.ordinal}}, {{method.ordinal}},
{{module.namespace}}.{{interface_message_id}}_ParamsSpec.$, {{interface_message_id}}_ParamsSpec.$,
{%- if method.response_parameters != None %} {%- if method.response_parameters != None %}
{{module.namespace}}.{{interface_message_id}}_ResponseParamsSpec.$, {{interface_message_id}}_ResponseParamsSpec.$,
{%- else %} {%- else %}
null, null,
{%- endif %} {%- endif %}
...@@ -110,20 +97,18 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver'); ...@@ -110,20 +97,18 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
* An object which receives request messages for the {{interface.name}} * An object which receives request messages for the {{interface.name}}
* mojom interface. Must be constructed over an object which implements that * mojom interface. Must be constructed over an object which implements that
* interface. * interface.
*
* @export
*/ */
{{module.namespace}}.{{interface.name}}Receiver = class { export const {{interface.name}}Receiver = class {
/** /**
* @param {!{{module.namespace}}.{{interface.name}}Interface } impl * @param {!{{interface.name}}Interface } impl
*/ */
constructor(impl) { constructor(impl) {
/** @private {!mojo.internal.interfaceSupport.InterfaceReceiverHelperInternal<!{{module.namespace}}.{{interface.name}}Remote>} */ /** @private {!mojo.internal.interfaceSupport.InterfaceReceiverHelperInternal<!{{interface.name}}Remote>} */
this.helper_internal_ = new mojo.internal.interfaceSupport.InterfaceReceiverHelperInternal( this.helper_internal_ = new mojo.internal.interfaceSupport.InterfaceReceiverHelperInternal(
{{module.namespace}}.{{interface.name}}Remote); {{interface.name}}Remote);
/** /**
* @public {!mojo.internal.interfaceSupport.InterfaceReceiverHelper<!{{module.namespace}}.{{interface.name}}Remote>} * @public {!mojo.internal.interfaceSupport.InterfaceReceiverHelper<!{{interface.name}}Remote>}
*/ */
this.$ = new mojo.internal.interfaceSupport.InterfaceReceiverHelper(this.helper_internal_); this.$ = new mojo.internal.interfaceSupport.InterfaceReceiverHelper(this.helper_internal_);
...@@ -132,9 +117,9 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver'); ...@@ -132,9 +117,9 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
interface.mojom_name ~ "_" ~ method.mojom_name %} interface.mojom_name ~ "_" ~ method.mojom_name %}
this.helper_internal_.registerHandler( this.helper_internal_.registerHandler(
{{method.ordinal}}, {{method.ordinal}},
{{module.namespace}}.{{interface_message_id}}_ParamsSpec.$, {{interface_message_id}}_ParamsSpec.$,
{%- if method.response_parameters != None %} {%- if method.response_parameters != None %}
{{module.namespace}}.{{interface_message_id}}_ResponseParamsSpec.$, {{interface_message_id}}_ResponseParamsSpec.$,
{%- else %} {%- else %}
null, null,
{%- endif %} {%- endif %}
...@@ -145,10 +130,7 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver'); ...@@ -145,10 +130,7 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
} }
}; };
/** export const {{interface.name}} = class {
* @export
*/
{{module.namespace}}.{{interface.name}} = class {
/** /**
* @return {!string} * @return {!string}
*/ */
...@@ -161,23 +143,20 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver'); ...@@ -161,23 +143,20 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
* The browser must have an interface request binder registered for this * The browser must have an interface request binder registered for this
* interface and accessible to the calling document's frame. * interface and accessible to the calling document's frame.
* *
* @return {!{{module.namespace}}.{{interface.name}}Remote} * @return {!{{interface.name}}Remote}
* @export
*/ */
static getRemote() { static getRemote() {
let remote = new {{module.namespace}}.{{interface.name}}Remote; let remote = new {{interface.name}}Remote;
Mojo.bindInterface({{module.namespace}}.{{interface.name}}.$interfaceName, Mojo.bindInterface("{{mojom_namespace}}.{{interface.name}}",
remote.$.bindNewPipeAndPassReceiver().handle); remote.$.bindNewPipeAndPassReceiver().handle);
return remote; return remote;
} }
}; };
{#--- Enums #} {#--- Enums #}
{% from "lite/enum_definition.tmpl" import enum_def with context %} {% from "lite/enum_definition_for_module.tmpl" import enum_def with context %}
{%- for enum in interface.enums %} {%- for enum in interface.enums %}
{{ enum_def("%s.%s"|format(module.namespace, interface.name), {{enum_def(enum)}}
"%s.%s"|format(module.namespace, interface.name),
enum) }}
{%- endfor %} {%- endfor %}
/** /**
...@@ -185,16 +164,14 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver'); ...@@ -185,16 +164,14 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
* mojom interface and dispatches them as callbacks. One callback receiver exists * mojom interface and dispatches them as callbacks. One callback receiver exists
* on this object for each message defined in the mojom interface, and each * on this object for each message defined in the mojom interface, and each
* receiver can have any number of listeners added to it. * receiver can have any number of listeners added to it.
*
* @export
*/ */
{{module.namespace}}.{{interface.name}}CallbackRouter = class { export const {{interface.name}}CallbackRouter = class {
constructor() { constructor() {
this.helper_internal_ = new mojo.internal.interfaceSupport.InterfaceReceiverHelperInternal( this.helper_internal_ = new mojo.internal.interfaceSupport.InterfaceReceiverHelperInternal(
{{module.namespace}}.{{interface.name}}Remote); {{interface.name}}Remote);
/** /**
* @public {!mojo.internal.interfaceSupport.InterfaceReceiverHelper<!{{module.namespace}}.{{interface.name}}Remote>} * @public {!mojo.internal.interfaceSupport.InterfaceReceiverHelper<!{{interface.name}}Remote>}
*/ */
this.$ = new mojo.internal.interfaceSupport.InterfaceReceiverHelper(this.helper_internal_); this.$ = new mojo.internal.interfaceSupport.InterfaceReceiverHelper(this.helper_internal_);
...@@ -211,9 +188,9 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver'); ...@@ -211,9 +188,9 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
this.helper_internal_.registerHandler( this.helper_internal_.registerHandler(
{{method.ordinal}}, {{method.ordinal}},
{{module.namespace}}.{{interface_message_id}}_ParamsSpec.$, {{interface_message_id}}_ParamsSpec.$,
{%- if method.response_parameters != None %} {%- if method.response_parameters != None %}
{{module.namespace}}.{{interface_message_id}}_ResponseParamsSpec.$, {{interface_message_id}}_ResponseParamsSpec.$,
this.{{method.name}}.createReceiverHandler(true /* expectsResponse */)); this.{{method.name}}.createReceiverHandler(true /* expectsResponse */));
{%- else %} {%- else %}
null, null,
...@@ -227,7 +204,6 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver'); ...@@ -227,7 +204,6 @@ goog.provide('{{module.namespace}}.{{interface.name}}PendingReceiver');
/** /**
* @param {number} id An ID returned by a prior call to addListener. * @param {number} id An ID returned by a prior call to addListener.
* @return {boolean} True iff the identified listener was found and removed. * @return {boolean} True iff the identified listener was found and removed.
* @export
*/ */
removeListener(id) { removeListener(id) {
return this.router_.removeListener(id); return this.router_.removeListener(id);
......
...@@ -11,7 +11,7 @@ goog.require('mojo.internal.interfaceSupport'); ...@@ -11,7 +11,7 @@ goog.require('mojo.internal.interfaceSupport');
{% for kind in module.imported_kinds.values() %} {% for kind in module.imported_kinds.values() %}
goog.require('{{kind|lite_js_import_name}}'); goog.require('{{kind|lite_js_import_name}}');
{%- endfor %} {%- endfor %}
{% else %} {% elif not for_bindings_internals %}
mojo.internal.exportModule('{{module.namespace}}'); mojo.internal.exportModule('{{module.namespace}}');
{% endif %} {% endif %}
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
{% if not for_bindings_internals -%}
import {mojo} from '{{bindings_library_path}}';
{%- endif %}
{% for path, kinds in js_module_imports.items() -%}
import {
{%- for kind in kinds %}
{{kind.mojom_name}} as {{kind|name_in_js_module}},
{{kind.mojom_name}}Spec as {{kind|name_in_js_module}}Spec
{%- if not loop.last -%}, {% endif -%}
{%- endfor %}
} from '{{path}}';
{% endfor -%}
{#--- Constants #}
{%- for constant in module.constants %}
/**
* @const { {{constant.kind|type_in_js_module_with_nullability}} }
*/
export const {{constant.name}} =
{{constant.value|expression_to_text_lite}};
{% endfor -%}
{#--- Enums #}
{%- from "lite/enum_definition_for_module.tmpl" import enum_def with context %}
{%- for enum in enums %}
{{enum_def(enum)}}
{% endfor -%}
{#--- Interfaces #}
{%- for interface in interfaces %}
{% include "lite/interface_definition_for_module.tmpl" %}
{%- endfor %}
{#--- Struct and Union forward declarations #}
{% for struct in structs %}
/**
* @const { {$:!mojo.internal.MojomType}}
*/
export const {{struct.name}}Spec =
{ $: /** @type {!mojo.internal.MojomType} */ ({}) };
{% endfor %}
{%- for union in unions %}
/**
* @const { {$:!mojo.internal.MojomType} }
*/
export const {{union.name}}Spec =
{ $: /** @type {!mojo.internal.MojomType} */ ({}) };
{% endfor %}
{#--- Struct definitions #}
{% for struct in structs %}
{%- include "lite/struct_definition_for_module.tmpl" %}
{% endfor -%}
{#--- Union definitions #}
{% for union in unions %}
{%- include "lite/union_definition_for_module.tmpl" %}
{% endfor %}
{% for constant in struct.constants %} {% for constant in struct.constants %}
/** /**
* @const { {{constant.kind|lite_closure_type_with_nullability}} } * @const { {{constant.kind|type_in_js_module_with_nullability}} }
* @export
*/ */
{{module.namespace}}.{{struct.name}}_{{constant.name}} = export const {{struct.name}}_{{constant.name}} =
{{constant.value|expression_to_text_lite}}; {{constant.value|expression_to_text_lite}};
{% endfor %} {% endfor %}
{%- from "lite/enum_definition.tmpl" import enum_def with context %} {%- from "lite/enum_definition_for_module.tmpl" import enum_def with context %}
{% for enum in struct.enums %} {% for enum in struct.enums %}
{{enum_def("%s.%sSpec"|format(module.namespace, struct.name), {{enum_def(enum)}}
"%s.%s"|format(module.namespace, struct.name), enum)}}
{% endfor %} {% endfor %}
mojo.internal.Struct( mojo.internal.Struct(
{{module.namespace}}.{{struct.name}}Spec.$, {{struct.name}}Spec.$,
'{{struct.name}}', '{{struct.name}}',
{{struct.packed|payload_size}}, {{struct.packed|payload_size}},
[ [
...@@ -23,8 +21,8 @@ mojo.internal.Struct( ...@@ -23,8 +21,8 @@ mojo.internal.Struct(
'{{packed_field.field.name}}', {{packed_field.offset}}, '{{packed_field.field.name}}', {{packed_field.offset}},
{% if packed_field.field.kind|is_bool_kind %}{{packed_field.bit}} {% if packed_field.field.kind|is_bool_kind %}{{packed_field.bit}}
{%- else %}0{% endif %}, {%- else %}0{% endif %},
{{packed_field.field.kind|lite_js_type}}, {{packed_field.field.kind|spec_type_in_js_module}},
{{packed_field.field|lite_default_value}}, {{packed_field.field|default_value_in_js_module}},
{%- if packed_field.field.kind.is_nullable %} {%- if packed_field.field.kind.is_nullable %}
true /* nullable */), true /* nullable */),
{%- else %} {%- else %}
...@@ -34,21 +32,18 @@ mojo.internal.Struct( ...@@ -34,21 +32,18 @@ mojo.internal.Struct(
]); ]);
{% if generate_struct_deserializers %} {% if generate_struct_deserializers %}
{{module.namespace}}.{{struct.name}}_Deserialize = export const {{struct.name}}_Deserialize =
mojo.internal.createStructDeserializer({{module.namespace}}.{{struct.name}}Spec.$); mojo.internal.createStructDeserializer({{struct.name}}Spec.$);
{% endif %} {% endif %}
{% if generate_closure_exports -%} /**
goog.provide('{{module.namespace}}.{{struct.name}}'); * @record
*/
/** @record */ export const {{struct.name}} = class {
{{module.namespace}}.{{struct.name}} = class {
constructor() { constructor() {
{%- for packed_field in struct.packed.packed_fields %} {%- for packed_field in struct.packed.packed_fields %}
/** @export { {{packed_field.field.kind|lite_closure_field_type}} } */ /** @type { {{packed_field.field.kind|field_type_in_js_module}} } */
this.{{packed_field.field.name}}; this.{{packed_field.field.name}};
{%- endfor %} {%- endfor %}
} }
}; };
{%- endif %}
{% if generate_closure_exports -%}
goog.provide('{{module.namespace}}.{{union.name}}');
{% endif %}
mojo.internal.Union( mojo.internal.Union(
{{module.namespace}}.{{union.name}}Spec.$, '{{union.name}}', {{union.name}}Spec.$, '{{union.name}}',
{ {
{%- for field in union.fields %} {%- for field in union.fields %}
'{{field.name}}': { '{{field.name}}': {
'ordinal': {{field.ordinal}}, 'ordinal': {{field.ordinal}},
'type': {{field.kind|lite_js_type}}, 'type': {{field.kind|spec_type_in_js_module}},
{%- if field.kind.is_nullable %} {%- if field.kind.is_nullable %}
'nullable': true, 'nullable': true,
{%- endif %} {%- endif %}
...@@ -19,8 +15,8 @@ mojo.internal.Union( ...@@ -19,8 +15,8 @@ mojo.internal.Union(
/** /**
* @typedef { { * @typedef { {
{%- for field in union.fields %} {%- for field in union.fields %}
* {{field.name}}: ({{field.kind|lite_closure_type_with_nullability}}|undefined), * {{field.name}}: ({{field.kind|type_in_js_module_with_nullability}}|undefined),
{%- endfor %} {%- endfor %}
* } } * } }
*/ */
{{module.namespace}}.{{union.name}}; export const {{union.name}} = {};
...@@ -1551,6 +1551,7 @@ template("mojom") { ...@@ -1551,6 +1551,7 @@ template("mojom") {
outputs += [ outputs += [
"$root_gen_dir/$base_path.js", "$root_gen_dir/$base_path.js",
"$root_gen_dir/$base_path.externs.js", "$root_gen_dir/$base_path.externs.js",
"$root_gen_dir/$base_path.m.js",
"$root_gen_dir/$base_path-lite.js", "$root_gen_dir/$base_path-lite.js",
"$root_gen_dir/$base_path.html", "$root_gen_dir/$base_path.html",
"$root_gen_dir/$base_path-lite-for-compile.js", "$root_gen_dir/$base_path-lite-for-compile.js",
...@@ -1603,13 +1604,19 @@ template("mojom") { ...@@ -1603,13 +1604,19 @@ template("mojom") {
foreach(base_path, output_file_base_paths) { foreach(base_path, output_file_base_paths) {
data += [ data += [
"$root_gen_dir/${base_path}.js", "$root_gen_dir/${base_path}.js",
"$root_gen_dir/${base_path}.m.js",
"$root_gen_dir/${base_path}-lite.js", "$root_gen_dir/${base_path}-lite.js",
] ]
} }
deps += [ ":$generator_js_target_name" ] deps += [ ":$generator_js_target_name" ]
} }
data_deps = [] if (defined(invoker.disallow_native_types) &&
invoker.disallow_native_types) {
data_deps = []
} else {
data_deps = [ "//mojo/public/js:bindings_module" ]
}
foreach(d, all_deps) { foreach(d, all_deps) {
full_name = get_label_info(d, "label_no_toolchain") full_name = get_label_info(d, "label_no_toolchain")
data_deps += [ "${full_name}_js_data_deps" ] data_deps += [ "${full_name}_js_data_deps" ]
...@@ -1665,6 +1672,34 @@ template("mojom") { ...@@ -1665,6 +1672,34 @@ template("mojom") {
group(js_library_for_compile_target_name) { group(js_library_for_compile_target_name) {
} }
} }
js_modules_target_name = "${target_name}_js_modules"
if (sources_list != []) {
js_library(js_modules_target_name) {
extra_public_deps = [ ":$generator_js_target_name" ]
sources = []
foreach(base_path, output_file_base_paths) {
sources += [ "$root_gen_dir/${base_path}.m.js" ]
}
externs_list = [
"${externs_path}/mojo_core.js",
"${externs_path}/pending.js",
]
if (defined(invoker.disallow_native_types) &&
invoker.disallow_native_types) {
deps = []
} else {
deps = [ "//mojo/public/js:bindings_uncompiled.m" ]
}
foreach(d, all_deps) {
full_name = get_label_info(d, "label_no_toolchain")
deps += [ "${full_name}_js_modules" ]
}
}
} else {
group(js_modules_target_name) {
}
}
} }
if ((generate_fuzzing || !defined(invoker.cpp_only) || !invoker.cpp_only) && if ((generate_fuzzing || !defined(invoker.cpp_only) || !invoker.cpp_only) &&
use_typescript_for_target) { use_typescript_for_target) {
......
This diff is collapsed.
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./bindings-tests.js" type="module"></script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment