• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5'use strict';
6
7if ((typeof mojo !== 'undefined') && mojo.bindingsLibraryInitialized) {
8  throw new Error('The Mojo bindings library has been initialized.');
9}
10
11var mojo = mojo || {};
12mojo.bindingsLibraryInitialized = true;
13
14mojo.internal = mojo.internal || {};
15
16mojo.config = mojo.config || {};
17if (typeof mojo.config.global === 'undefined') {
18  mojo.config.global = this;
19}
20
21if (typeof mojo.config.autoLoadMojomDeps === 'undefined') {
22  // Whether to automatically load mojom dependencies.
23  // For example, if foo.mojom imports bar.mojom, |autoLoadMojomDeps| set to
24  // true means that loading foo.mojom.js will insert a <script> tag to load
25  // bar.mojom.js, if it hasn't been loaded.
26  //
27  // The URL of bar.mojom.js is determined by the relative path of bar.mojom
28  // (relative to the position of foo.mojom at build time) and the URL of
29  // foo.mojom.js. For exmple, if at build time the two mojom files are
30  // located at:
31  //   a/b/c/foo.mojom
32  //   a/b/d/bar.mojom
33  // and the URL of foo.mojom.js is:
34  //   http://example.org/scripts/b/c/foo.mojom.js
35  // then the URL of bar.mojom.js will be:
36  //   http://example.org/scripts/b/d/bar.mojom.js
37  //
38  // If you would like bar.mojom.js to live at a different location, you need
39  // to turn off |autoLoadMojomDeps| before loading foo.mojom.js, and manually
40  // load bar.mojom.js yourself. Similarly, you need to turn off the option if
41  // you merge bar.mojom.js and foo.mojom.js into a single file.
42  //
43  // Performance tip: Avoid loading the same mojom.js file multiple times.
44  // Assume that |autoLoadMojomDeps| is set to true,
45  //
46  // <!--
47  // (This comment tag is necessary on IOS to avoid interpreting the closing
48  // script tags in the example.)
49  //
50  // No duplicate loading; recommended:
51  // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script>
52  //
53  // No duplicate loading, although unnecessary:
54  // <script src="http://example.org/scripts/b/d/bar.mojom.js"></script>
55  // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script>
56  //
57  // Load bar.mojom.js twice; should be avoided:
58  // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script>
59  // <script src="http://example.org/scripts/b/d/bar.mojom.js"></script>
60  //
61  // -->
62  mojo.config.autoLoadMojomDeps = true;
63}
64
65(function() {
66  var internal = mojo.internal;
67  var config = mojo.config;
68
69  var LoadState = {
70    PENDING_LOAD: 1,
71    LOADED: 2
72  };
73
74  var mojomRegistry = new Map();
75
76  function exposeNamespace(namespace) {
77    var current = config.global;
78    var parts = namespace.split('.');
79
80    for (var part; parts.length && (part = parts.shift());) {
81      if (!current[part]) {
82        current[part] = {};
83      }
84      current = current[part];
85    }
86
87    return current;
88  }
89
90  function isMojomPendingLoad(id) {
91    return mojomRegistry.get(id) === LoadState.PENDING_LOAD;
92  }
93
94  function isMojomLoaded(id) {
95    return mojomRegistry.get(id) === LoadState.LOADED;
96  }
97
98  function markMojomPendingLoad(id) {
99    if (isMojomLoaded(id)) {
100      throw new Error('The following mojom file has been loaded: ' + id);
101    }
102
103    mojomRegistry.set(id, LoadState.PENDING_LOAD);
104  }
105
106  function markMojomLoaded(id) {
107    mojomRegistry.set(id, LoadState.LOADED);
108  }
109
110  function loadMojomIfNecessary(id, relativePath) {
111    if (mojomRegistry.has(id)) {
112      return;
113    }
114
115    if (config.global.document === undefined) {
116      throw new Error(
117          'Mojom dependency autoloading is not implemented in workers. ' +
118          'Please see config variable mojo.config.autoLoadMojomDeps for more ' +
119          'details.');
120    }
121
122    markMojomPendingLoad(id);
123    var url = new URL(relativePath, document.currentScript.src).href;
124    config.global.document.write('<script type="text/javascript" src="' +
125                                 url + '"><' + '/script>');
126  }
127
128  internal.exposeNamespace = exposeNamespace;
129  internal.isMojomPendingLoad = isMojomPendingLoad;
130  internal.isMojomLoaded = isMojomLoaded;
131  internal.markMojomPendingLoad = markMojomPendingLoad;
132  internal.markMojomLoaded = markMojomLoaded;
133  internal.loadMojomIfNecessary = loadMojomIfNecessary;
134})();
135