chromium/mojo/public/js/BUILD.gn

# Copyright 2014 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/python.gni")
import("//mojo/public/tools/bindings/mojom.gni")
import("//third_party/closure_compiler/closure_args.gni")
import("//third_party/closure_compiler/compile_js.gni")
import("//third_party/node/node.gni")
import("//tools/grit/grit_rule.gni")
import("//ui/webui/webui_features.gni")

interfaces_bindings_gen_dir = "$root_gen_dir/mojo/public/interfaces/bindings"

action("bindings") {
  bindings_js_files = [
    # This must be the first file in the list, because it initializes global
    # variable |mojo| that the others need to refer to.
    "base.js",

    "bindings.js",
    "interface_types.js",
    "lib/buffer.js",
    "lib/codec.js",
    "lib/connector.js",
    "lib/control_message_handler.js",
    "lib/control_message_proxy.js",
    "lib/interface_endpoint_client.js",
    "lib/interface_endpoint_handle.js",
    "lib/pipe_control_message_handler.js",
    "lib/pipe_control_message_proxy.js",
    "lib/router.js",
    "lib/unicode.js",
    "lib/validator.js",

    # These two needs to refer to codec.js.
    "$interfaces_bindings_gen_dir/interface_control_messages.mojom.js",
    "$interfaces_bindings_gen_dir/pipe_control_messages.mojom.js",
  ]
  compiled_file = "$target_gen_dir/mojo_bindings.js"

  # TODO(yzshen): Eventually we would like to use Closure Compiler to minify the
  # bindings instead of simply concatenating the files.
  script = "//mojo/public/tools/bindings/concatenate-files.py"

  sources = bindings_js_files
  outputs = [ compiled_file ]

  args = rebase_path(bindings_js_files, root_build_dir)
  args += [ rebase_path(compiled_file, root_build_dir) ]

  deps = [ "//mojo/public/interfaces/bindings:bindings_js__generator" ]
}

template("concatenate_files") {
  action(target_name) {
    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
    }
  }
}

template("minify_file") {
  node(target_name) {
    script = "//mojo/public/tools/bindings/minify_with_terser.py"
    inputs = [ invoker.input ]
    outputs = [ invoker.output ]

    args = [
      "--input",
      rebase_path(invoker.input, root_build_dir),
      "--output",
      rebase_path(invoker.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"
}

concatenate_files("generate_interface_support_js") {
  inputs = [
    "interface_support_preamble.js.part",
    "interface_support.js",
  ]
  output = "interface_support.js"
}

if (generate_mojom_closure_libraries) {
  js_library("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" ]
    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_uncompiled_module_preamble.js.part",
    "bindings_lite.js",
    "$root_gen_dir/mojo/public/interfaces/bindings/interface_control_messages.mojom-lite.js",
    "$root_gen_dir/mojo/public/interfaces/bindings/pipe_control_messages.mojom-lite.js",
    "interface_support.js",
    "bindings_uncompiled_module_export.js.part",
  ]
  output = "bindings_uncompiled.js"
  deps = [ "//mojo/public/interfaces/bindings:bindings_js__generator" ]
}

if (generate_mojom_closure_libraries) {
  js_binary("bindings_lite") {
    outputs = [ "$target_gen_dir/mojo_bindings_lite.js" ]
    sources = []
    deps = [ ":bindings_lite_sources" ]
    externs_list = [ "$externs_path/mojo_core.js" ]
    closure_flags = strict_error_checking_closure_args + [
                      "compilation_level=ADVANCED_OPTIMIZATIONS",
                      "language_in=ECMASCRIPT_2017",
                      "language_out=ECMASCRIPT_2015",
                      "generate_exports",
                      "export_local_property_definitions",
                      "isolation_mode=IIFE",
                    ]
  }

  concatenate_files("bindings_compiled_module") {
    inputs = [
      "bindings_module_preamble.js.part",
      "$target_gen_dir/mojo_bindings_lite.js",
      "bindings_module_export.js.part",
    ]
    output = "bindings_compiled.js"
    deps = [ ":bindings_lite" ]
  }

  copy("bindings_module") {
    sources = [ "$target_gen_dir/bindings_compiled.js" ]
    outputs = [ "$target_gen_dir/bindings.js" ]
    deps = [ ":bindings_compiled_module" ]
  }
} else {
  action("bindings_lite") {
    inputs = [
      "$target_gen_dir/mojo_internal.js",
      "$root_gen_dir/mojo/public/interfaces/bindings/interface_control_messages.mojom-lite-for-compile.js",
      "$root_gen_dir/mojo/public/interfaces/bindings/pipe_control_messages.mojom-lite-for-compile.js",
      "$target_gen_dir/interface_support.js",
    ]
    script = "//mojo/public/tools/bindings/concatenate_and_replace_closure_exports.py"
    sources = inputs
    outputs = [ "$target_gen_dir/mojo_bindings_lite.js" ]
    args =
        rebase_path(inputs, root_build_dir) +
        [ 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",
    ]
  }

  if (optimize_webui) {
    minify_file("bindings_module") {
      input = "$target_gen_dir/bindings_uncompiled.js"
      output = "$target_gen_dir/bindings.js"
      deps = [ ":bindings_uncompiled_module" ]
    }
  } else {
    copy("bindings_module") {
      sources = [ "$target_gen_dir/bindings_uncompiled.js" ]
      outputs = [ "$target_gen_dir/bindings.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.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") {
  sources = [ "$target_gen_dir/bindings_uncompiled.js" ]
  extra_deps = [ ":bindings_uncompiled_module" ]
}

grit("resources") {
  source = "mojo_bindings_resources.grd"

  outputs = [
    "grit/mojo_bindings_resources.h",
    "grit/mojo_bindings_resources_map.cc",
    "grit/mojo_bindings_resources_map.h",
    "mojo_bindings_resources.pak",
  ]

  deps = [
    ":bindings",
    ":bindings_lite",
    ":bindings_module",
    "//mojo/public/mojom/base:base_js",
  ]
}

group("tests") {
  deps = [ "//mojo/public/js/test:compile_test" ]
}