summaryrefslogtreecommitdiff
path: root/mojo/public/js/new_bindings/base.js
blob: db72d489db6ec016817ec1557a11812f33836b31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright 2017 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.

'use strict';

if (mojo && mojo.internal) {
  throw new Error('The Mojo bindings library has been initialized.');
}

var mojo = mojo || {};
mojo.internal = {};
mojo.internal.global = this;
mojo.config = {
  // Whether to automatically load mojom dependencies.
  // For example, if foo.mojom imports bar.mojom, |autoLoadMojomDeps| set to
  // true means that loading foo.mojom.js will insert a <script> tag to load
  // bar.mojom.js, if it hasn't been loaded.
  //
  // The URL of bar.mojom.js is determined by the relative path of bar.mojom
  // (relative to the position of foo.mojom at build time) and the URL of
  // foo.mojom.js. For exmple, if at build time the two mojom files are
  // located at:
  //   a/b/c/foo.mojom
  //   a/b/d/bar.mojom
  // and the URL of foo.mojom.js is:
  //   http://example.org/scripts/b/c/foo.mojom.js
  // then the URL of bar.mojom.js will be:
  //   http://example.org/scripts/b/d/bar.mojom.js
  //
  // If you would like bar.mojom.js to live at a different location, you need
  // to turn off |autoLoadMojomDeps| before loading foo.mojom.js, and manually
  // load bar.mojom.js yourself. Similarly, you need to turn off the option if
  // you merge bar.mojom.js and foo.mojom.js into a single file.
  //
  // Performance tip: Avoid loading the same mojom.js file multiple times.
  // Assume that |autoLoadMojomDeps| is set to true:
  // <!-- No duplicate loading; recommended. -->
  // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script>
  //
  // <!-- No duplicate loading, although unnecessary. -->
  // <script src="http://example.org/scripts/b/d/bar.mojom.js"></script>
  // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script>
  //
  // <!-- Load bar.mojom.js twice; should be avoided. -->
  // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script>
  // <script src="http://example.org/scripts/b/d/bar.mojom.js"></script>
  autoLoadMojomDeps: true
};

(function() {
  var internal = mojo.internal;

  var LoadState = {
    PENDING_LOAD: 1,
    LOADED: 2
  };

  var mojomRegistry = new Map();

  function exposeNamespace(namespace) {
    var current = internal.global;
    var parts = namespace.split('.');

    for (var part; parts.length && (part = parts.shift());) {
      if (!current[part]) {
        current[part] = {};
      }
      current = current[part];
    }

    return current;
  }

  function isMojomPendingLoad(id) {
    return mojomRegistry.get(id) === LoadState.PENDING_LOAD;
  }

  function isMojomLoaded(id) {
    return mojomRegistry.get(id) === LoadState.LOADED;
  }

  function markMojomPendingLoad(id) {
    if (isMojomLoaded(id)) {
      throw new Error('The following mojom file has been loaded: ' + id);
    }

    mojomRegistry.set(id, LoadState.PENDING_LOAD);
  }

  function markMojomLoaded(id) {
    mojomRegistry.set(id, LoadState.LOADED);
  }

  function loadMojomIfNecessary(id, url) {
    if (mojomRegistry.has(id)) {
      return;
    }

    markMojomPendingLoad(id);
    internal.global.document.write('<script type="text/javascript" src="' +
                                   url + '"></script>');
  }

  internal.exposeNamespace = exposeNamespace;
  internal.isMojomPendingLoad = isMojomPendingLoad;
  internal.isMojomLoaded = isMojomLoaded;
  internal.markMojomPendingLoad = markMojomPendingLoad;
  internal.markMojomLoaded = markMojomLoaded;
  internal.loadMojomIfNecessary = loadMojomIfNecessary;
})();