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