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