109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/*
209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Copyright (C) 2014 Google Inc. All rights reserved.
309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * modification, are permitted provided that the following conditions are
609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * met:
709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
1009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
1109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
1209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * in the documentation and/or other materials provided with the
1309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * distribution.
1409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
1509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
1609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * this software without specific prior written permission.
1709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
1809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
3009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
319e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)// This gets all concatenated module descriptors in the release mode.
329e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)var allDescriptors = [];
337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivar applicationDescriptor;
349e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)var _loadedScripts = {};
35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)/**
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) * @param {string} url
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) * @return {string}
39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) */
40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)function loadResource(url)
41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    var xhr = new XMLHttpRequest();
43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    xhr.open("GET", url, false);
44c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    try {
45c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        xhr.send(null);
46c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    } catch (e) {
47c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        console.error(url + " -> " + new Error().stack);
48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        throw e;
49c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // xhr.status === 0 if loading from bundle.
517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return xhr.status < 400 ? xhr.responseText : "";
52c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
54e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
55e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)/**
56e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) * http://tools.ietf.org/html/rfc3986#section-5.2.4
57e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) * @param {string} path
58e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) * @return {string}
59e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) */
60e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)function normalizePath(path)
61e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
62e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if (path.indexOf("..") === -1 && path.indexOf('.') === -1)
63e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        return path;
64e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
65e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    var normalizedSegments = [];
66e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    var segments = path.split("/");
67e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    for (var i = 0; i < segments.length; i++) {
68e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        var segment = segments[i];
69e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (segment === ".")
70e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            continue;
71e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        else if (segment === "..")
72e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            normalizedSegments.pop();
73e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        else if (segment)
74e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            normalizedSegments.push(segment);
75e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    }
76e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    var normalizedPath = normalizedSegments.join("/");
77e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if (normalizedPath[normalizedPath.length - 1] === "/")
78e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        return normalizedPath;
79e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if (path[0] === "/" && normalizedPath)
80e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        normalizedPath = "/" + normalizedPath;
81e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if ((path[path.length - 1] === "/") || (segments[segments.length - 1] === ".") || (segments[segments.length - 1] === ".."))
82e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        normalizedPath = normalizedPath + "/";
83e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
84e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    return normalizedPath;
85e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
86e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
87c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)/**
88c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) * @param {string} scriptName
89c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) */
909e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)function loadScript(scriptName)
91c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
92c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    var sourceURL = self._importScriptPathPrefix + scriptName;
93e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    var schemaIndex = sourceURL.indexOf("://") + 3;
94e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    sourceURL = sourceURL.substring(0, schemaIndex) + normalizePath(sourceURL.substring(schemaIndex));
959e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (_loadedScripts[sourceURL])
96c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return;
979e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    _loadedScripts[sourceURL] = true;
98c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    var scriptSource = loadResource(sourceURL);
997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!scriptSource) {
1007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        console.error("Empty response arrived for script '" + sourceURL + "'");
1017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
1027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
103c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    var oldPrefix = self._importScriptPathPrefix;
104c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    self._importScriptPathPrefix += scriptName.substring(0, scriptName.lastIndexOf("/") + 1);
105c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    try {
106c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        self.eval(scriptSource + "\n//# sourceURL=" + sourceURL);
107c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    } finally {
108c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        self._importScriptPathPrefix = oldPrefix;
109c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
111c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)(function() {
1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var baseUrl = self.location ? self.location.origin + self.location.pathname : "";
114c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    self._importScriptPathPrefix = baseUrl.substring(0, baseUrl.lastIndexOf("/") + 1);
115c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)})();
116c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/**
11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @constructor
11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
1209e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)var Runtime = function()
12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
123c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @type {!Array.<!Runtime.Module>}
12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._modules = [];
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
127c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @type {!Object.<string, !Runtime.Module>}
12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._modulesMap = {};
13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
131c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @type {!Array.<!Runtime.Extension>}
13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._extensions = [];
13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
135d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    /**
136d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)     * @type {!Object.<string, !function(new:Object)>}
137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)     */
138d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    this._cachedTypeClasses = {};
13909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
14009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
141c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @type {!Object.<string, !Runtime.ModuleDescriptor>}
14209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
14309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._descriptorsMap = {};
1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1459e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    for (var i = 0; i < allDescriptors.length; ++i)
1469e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        this._descriptorsMap[allDescriptors[i]["name"]] = allDescriptors[i];
1479e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)}
1489e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
1499e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)/**
1507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @type {!Object.<string, string>}
1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci */
1527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime._queryParamsObject = { __proto__: null };
1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci/**
1559e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) * @return {boolean}
1569e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) */
1579e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)Runtime.isReleaseMode = function()
1589e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles){
1599e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return !!allDescriptors.length;
1609e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)}
1619e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
1629e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)/**
1639e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) * @param {string} moduleName
1649e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) * @param {string} workerName
1659e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) * @return {!SharedWorker}
1669e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) */
1679e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)Runtime.startSharedWorker = function(moduleName, workerName)
1689e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles){
1699e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (Runtime.isReleaseMode())
170e407fbf339543f622b6e9e8e40881204bde53b6bBen Murdoch        return new SharedWorker(moduleName + "_module.js", workerName);
1719e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
1729e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    var content = loadResource(moduleName + "/module.json");
1739e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (!content)
1749e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        throw new Error("Worker is not defined: " + moduleName + " " + new Error().stack);
1759e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    var scripts = JSON.parse(content)["scripts"];
1769e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (scripts.length !== 1)
1779e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        throw Error("Runtime.startSharedWorker supports modules with only one script!");
1789e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return new SharedWorker(moduleName + "/" + scripts[0], workerName);
17909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
18009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
181e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)/**
182e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) * @param {string} moduleName
183e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) * @return {!Worker}
184e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) */
185e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)Runtime.startWorker = function(moduleName)
186e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
1879e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (Runtime.isReleaseMode())
188e407fbf339543f622b6e9e8e40881204bde53b6bBen Murdoch        return new Worker(moduleName + "_module.js");
1899e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
1909e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    var content = loadResource(moduleName + "/module.json");
1919e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (!content)
1929e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        throw new Error("Worker is not defined: " + moduleName + " " + new Error().stack);
1939e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    var message = [];
1949e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    var scripts = JSON.parse(content)["scripts"];
1959e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    for (var i = 0; i < scripts.length; ++i) {
1969e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        var url = self._importScriptPathPrefix + moduleName + "/" + scripts[i];
1979e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        var parts = url.split("://");
1989e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        url = parts.length === 1 ? url : parts[0] + "://" + normalizePath(parts[1]);
1999e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        message.push({
2009e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            source: loadResource(moduleName + "/" + scripts[i]),
2019e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            url: url
2029e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        });
2039e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    }
2049e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
2059e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    /**
2069e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)     * @suppress {checkTypes}
2079e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)     */
2089e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    var loader = function() {
2099e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        self.onmessage = function(event) {
2109e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            self.onmessage = null;
2119e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            var scripts = event.data;
2129e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            for (var i = 0; i < scripts.length; ++i) {
2139e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                var source = scripts[i]["source"];
2149e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                self.eval(source + "\n//# sourceURL=" + scripts[i]["url"]);
2159e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            }
2169e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        };
2179e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    };
2189e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
2199e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    var blob = new Blob(["(" + loader.toString() + ")()\n//# sourceURL=" + moduleName], { type: "text/javascript" });
2209e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    var workerURL = window.URL.createObjectURL(blob);
2219e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    try {
2229e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        var worker = new Worker(workerURL);
2239e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        worker.postMessage(message);
2249e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return worker;
2259e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    } finally {
2269e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        window.URL.revokeObjectURL(workerURL);
2279e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    }
228e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
229e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
2307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci/**
2317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @param {string} appName
2327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci */
2337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime.startApplication = function(appName)
2347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
2357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    console.timeStamp("Runtime.startApplication");
2367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var experiments = Runtime._experimentsSetting();
2377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var allDescriptorsByName = {};
2397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    for (var i = 0; Runtime.isReleaseMode() && i < allDescriptors.length; ++i) {
2407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        var d = allDescriptors[i];
2417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        allDescriptorsByName[d["name"]] = d;
2427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var moduleDescriptors = applicationDescriptor || Runtime._parseJsonURL(appName + ".json");
2447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var allModules = [];
2457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var coreModuleNames = [];
2467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    moduleDescriptors.forEach(populateModules);
2477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
2497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {!Object} desc
2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
2517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    function populateModules(desc)
2527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
2537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!isActive(desc))
2547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return;
2557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        var name = desc.name;
2567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        var moduleJSON = allDescriptorsByName[name];
2577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!moduleJSON) {
2587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            moduleJSON = Runtime._parseJsonURL(name + "/module.json");
2597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            moduleJSON["name"] = name;
2607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
2617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        allModules.push(moduleJSON);
2627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (desc["type"] === "autostart")
2637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            coreModuleNames.push(name);
2647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
2677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {!Object} descriptor
2687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @return {boolean}
2697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
2707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    function isActive(descriptor)
2717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
2727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        var activatorExperiment = descriptor["experiment"];
2737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (activatorExperiment) {
2747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            var shouldBePresent = activatorExperiment.charAt(0) !== "!";
2757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (!shouldBePresent)
2767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                activatorExperiment = activatorExperiment.substr(1);
2777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (!!experiments[activatorExperiment] !== shouldBePresent)
2787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                return false;
2797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
2807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return descriptor["type"] !== "worker";
2817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Runtime._initializeApplication(allModules);
2847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    self.runtime.loadAutoStartModules(coreModuleNames);
2857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
2867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci/**
2887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @param {string} name
2897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @return {?string}
2907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci */
2917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime.queryParam = function(name)
2927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
2937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return Runtime._queryParamsObject[name] || null;
2947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
2957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci/**
2977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @return {!Object}
2987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci */
2997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime._experimentsSetting = function()
3007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    try {
3027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return /** @type {!Object} */ (JSON.parse(self.localStorage && self.localStorage["experiments"] ? self.localStorage["experiments"] : "{}"));
3037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    } catch (e) {
3047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        console.error("Failed to parse localStorage['experiments']");
3057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return {};
3067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
3077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci/**
3107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @param {!Array.<!Runtime.ModuleDescriptor>} descriptors
3117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci */
3127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime._initializeApplication = function(descriptors)
3137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    self.runtime = new Runtime();
3157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var names = [];
3167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    for (var i = 0; i < descriptors.length; ++i) {
3177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        var name = descriptors[i]["name"];
3187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        self.runtime._descriptorsMap[name] = descriptors[i];
3197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        names.push(name);
3207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
3217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    self.runtime._registerModules(names);
3227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci/**
3257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @param {string} url
3267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @return {*}
3277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci */
3287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime._parseJsonURL = function(url)
3297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var json = loadResource(url);
3317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!json)
3327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        throw new Error("Resource not found at " + url + " " + new Error().stack);
3337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return JSON.parse(json);
3347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
336c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Runtime.prototype = {
33709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
33809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @param {!Array.<string>} configuration
33909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
3407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    _registerModules: function(configuration)
34109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
34209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (var i = 0; i < configuration.length; ++i)
343e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            this._registerModule(configuration[i]);
34409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
34509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
34609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
34709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @param {string} moduleName
34809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
349e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    _registerModule: function(moduleName)
35009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
351323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (!this._descriptorsMap[moduleName]) {
352323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            var content = loadResource(moduleName + "/module.json");
353323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            if (!content)
354323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                throw new Error("Module is not defined: " + moduleName + " " + new Error().stack);
3557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
356c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            var module = /** @type {!Runtime.ModuleDescriptor} */ (self.eval("(" + content + ")"));
357323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            module["name"] = moduleName;
358323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            this._descriptorsMap[moduleName] = module;
359323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        }
360c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        var module = new Runtime.Module(this, this._descriptorsMap[moduleName]);
36109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        this._modules.push(module);
36209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        this._modulesMap[moduleName] = module;
36309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
36409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
36509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
36609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @param {string} moduleName
36709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
36809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    loadModule: function(moduleName)
36909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
37009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        this._modulesMap[moduleName]._load();
37109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
37209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
37309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
3747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {!Array.<string>} moduleNames
3757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
3767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    loadAutoStartModules: function(moduleNames)
3777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
3787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        for (var i = 0; i < moduleNames.length; ++i) {
3797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (Runtime.isReleaseMode())
3807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                self.runtime._modulesMap[moduleNames[i]]._loaded = true;
3817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            else
3827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                self.runtime.loadModule(moduleNames[i]);
3837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
3847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
3857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
387c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @param {!Runtime.Extension} extension
388323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)     * @param {?function(function(new:Object)):boolean} predicate
389323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)     * @return {boolean}
390323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)     */
391323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    _checkExtensionApplicability: function(extension, predicate)
392323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    {
393323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (!predicate)
394323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            return false;
395323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        var contextTypes = /** @type {!Array.<string>|undefined} */ (extension.descriptor().contextTypes);
396323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (!contextTypes)
397323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            return true;
398323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        for (var i = 0; i < contextTypes.length; ++i) {
399323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            var contextType = this._resolve(contextTypes[i]);
400323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            var isMatching = !!contextType && predicate(contextType);
401323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            if (isMatching)
402323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                return true;
403323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        }
404323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        return false;
405323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    },
406323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
407323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    /**
408c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @param {!Runtime.Extension} extension
409323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)     * @param {?Object} context
410323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)     * @return {boolean}
411323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)     */
412323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    isExtensionApplicableToContext: function(extension, context)
413323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    {
414323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (!context)
415323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            return true;
416323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        return this._checkExtensionApplicability(extension, isInstanceOf);
417323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
418323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        /**
419323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)         * @param {!Function} targetType
420323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)         * @return {boolean}
421323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)         */
422323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        function isInstanceOf(targetType)
423323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        {
424323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            return context instanceof targetType;
425323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        }
426323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    },
427323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
428323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    /**
429c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @param {!Runtime.Extension} extension
430c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @param {!Array.<!Function>=} currentContextTypes
431323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)     * @return {boolean}
432323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)     */
433323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    isExtensionApplicableToContextTypes: function(extension, currentContextTypes)
434323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    {
435323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (!extension.descriptor().contextTypes)
436323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            return true;
437323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
438c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // FIXME: Remove this workaround once Set is available natively.
439c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        for (var i = 0; i < currentContextTypes.length; ++i)
440c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            currentContextTypes[i]["__applicable"] = true;
441c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        var result = this._checkExtensionApplicability(extension, currentContextTypes ? isContextTypeKnown : null);
442c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        for (var i = 0; i < currentContextTypes.length; ++i)
443c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            delete currentContextTypes[i]["__applicable"];
444c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return result;
445323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
446323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        /**
447323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)         * @param {!Function} targetType
448323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)         * @return {boolean}
449323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)         */
450323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        function isContextTypeKnown(targetType)
451323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        {
452c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return !!targetType["__applicable"];
453323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        }
454323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    },
455323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
456323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    /**
457197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch     * @param {*} type
45809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @param {?Object=} context
459c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @return {!Array.<!Runtime.Extension>}
46009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
46109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    extensions: function(type, context)
46209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
46309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        /**
464c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)         * @param {!Runtime.Extension} extension
46509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)         * @return {boolean}
46609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)         */
46709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        function filter(extension)
46809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        {
469d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (extension._type !== type && extension._typeClass() !== type)
47009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                return false;
4717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            var activatorExperiment = extension.descriptor()["experiment"];
4727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (activatorExperiment && !Runtime.experiments.isEnabled(activatorExperiment))
4737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                return false;
47409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return !context || extension.isApplicable(context);
47509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
47609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return this._extensions.filter(filter);
47709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
47809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
47909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
480197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch     * @param {*} type
48109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @param {?Object=} context
482c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @return {?Runtime.Extension}
48309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
48409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    extension: function(type, context)
48509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
48609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return this.extensions(type, context)[0] || null;
48709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
48809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
48909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
490197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch     * @param {*} type
49109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @param {?Object=} context
49209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @return {!Array.<!Object>}
49309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
49409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    instances: function(type, context)
49509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
49609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        /**
497c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)         * @param {!Runtime.Extension} extension
49809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)         * @return {?Object}
49909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)         */
50009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        function instantiate(extension)
50109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        {
50209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return extension.instance();
50309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
50409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return this.extensions(type, context).filter(instantiate).map(instantiate);
50509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
50609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
50709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
508197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch     * @param {*} type
509f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)     * @param {?Object=} context
51009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @return {?Object}
51109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
51209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    instance: function(type, context)
51309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
51409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        var extension = this.extension(type, context);
51509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return extension ? extension.instance() : null;
51609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
51709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
51809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
51909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @param {string|!Function} type
52009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @param {string} nameProperty
52109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @param {string} orderProperty
52209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @return {function(string, string):number}
52309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
52409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    orderComparator: function(type, nameProperty, orderProperty)
52509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
52609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        var extensions = this.extensions(type);
52709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        var orderForName = {};
52809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (var i = 0; i < extensions.length; ++i) {
52909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            var descriptor = extensions[i].descriptor();
53009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            orderForName[descriptor[nameProperty]] = descriptor[orderProperty];
53109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
53209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
53309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        /**
53409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)         * @param {string} name1
53509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)         * @param {string} name2
53609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)         * @return {number}
53709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)         */
53809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        function result(name1, name2)
53909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        {
54009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (name1 in orderForName && name2 in orderForName)
54109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                return orderForName[name1] - orderForName[name2];
54209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (name1 in orderForName)
54309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                return -1;
54409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (name2 in orderForName)
54509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                return 1;
546c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return compare(name1, name2);
547c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
548c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
549c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        /**
550c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)         * @param {string} left
551c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)         * @param {string} right
552c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)         * @return {number}
553c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)         */
554c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        function compare(left, right)
555c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        {
556c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (left > right)
557c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)              return 1;
558c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (left < right)
559c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                return -1;
560c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return 0;
56109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
56209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return result;
563d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    },
564d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
565d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    /**
566d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)     * @return {?function(new:Object)}
567d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)     */
568323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    _resolve: function(typeName)
569d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
570d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!this._cachedTypeClasses[typeName]) {
571323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            var path = typeName.split(".");
57210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            var object = window;
57310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            for (var i = 0; object && (i < path.length); ++i)
57410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                object = object[path[i]];
57510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            if (object)
57610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                this._cachedTypeClasses[typeName] = /** @type function(new:Object) */(object);
577d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
578d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return this._cachedTypeClasses[typeName];
57909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
58009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
58109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
58209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/**
58309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @constructor
58409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
585c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Runtime.ModuleDescriptor = function()
58609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
58709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
58809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @type {string}
58909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
59009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this.name;
59109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
59209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
593c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @type {!Array.<!Runtime.ExtensionDescriptor>}
59409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
59509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this.extensions;
59609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
59709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
5985d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)     * @type {!Array.<string>|undefined}
599f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu     */
600f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    this.dependencies;
601f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
602f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    /**
60309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @type {!Array.<string>}
60409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
60509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this.scripts;
60609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
60709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
60809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/**
60909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @constructor
61009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
611c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Runtime.ExtensionDescriptor = function()
61209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
61309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
61409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @type {string}
61509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
61609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this.type;
61709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
61809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
61909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @type {string|undefined}
62009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
62109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this.className;
62209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
62309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
62409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @type {!Array.<string>|undefined}
62509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
62609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this.contextTypes;
62709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
62809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
62909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/**
63009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @constructor
631c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) * @param {!Runtime} manager
632c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) * @param {!Runtime.ModuleDescriptor} descriptor
63309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
634c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Runtime.Module = function(manager, descriptor)
63509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
63609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._manager = manager;
63709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._descriptor = descriptor;
63809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._name = descriptor.name;
6397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var extensions = /** @type {?Array.<!Runtime.ExtensionDescriptor>} */ (descriptor.extensions);
64009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    for (var i = 0; extensions && i < extensions.length; ++i)
641c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        this._manager._extensions.push(new Runtime.Extension(this, extensions[i]));
64209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._loaded = false;
64309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
64409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
645c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Runtime.Module.prototype = {
64609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
64709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @return {string}
64809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
64909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    name: function()
65009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
65109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return this._name;
65209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
65309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
65409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    _load: function()
65509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
65609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (this._loaded)
65709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return;
65809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
65909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (this._isLoading) {
66009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            var oldStackTraceLimit = Error.stackTraceLimit;
66109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            Error.stackTraceLimit = 50;
66209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            console.assert(false, "Module " + this._name + " is loaded from itself: " + new Error().stack);
66309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            Error.stackTraceLimit = oldStackTraceLimit;
66409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return;
66509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
66609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
66709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        this._isLoading = true;
668f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        var dependencies = this._descriptor.dependencies;
669f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        for (var i = 0; dependencies && i < dependencies.length; ++i)
670f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            this._manager.loadModule(dependencies[i]);
6719e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        if (this._descriptor.scripts) {
6729e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            if (Runtime.isReleaseMode()) {
673e407fbf339543f622b6e9e8e40881204bde53b6bBen Murdoch                loadScript(this._name + "_module.js");
6749e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            } else {
6759e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                var scripts = this._descriptor.scripts;
6769e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                for (var i = 0; i < scripts.length; ++i)
6779e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                    loadScript(this._name + "/" + scripts[i]);
6789e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            }
6799e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        }
68009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        this._isLoading = false;
68109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        this._loaded = true;
68209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
68309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
68409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
68509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/**
68609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @constructor
687c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) * @param {!Runtime.Module} module
688c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) * @param {!Runtime.ExtensionDescriptor} descriptor
68909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
690c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Runtime.Extension = function(module, descriptor)
69109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
69209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._module = module;
69309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._descriptor = descriptor;
69409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
69509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._type = descriptor.type;
696c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    this._hasTypeClass = this._type.charAt(0) === "@";
69709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
69809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
69909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @type {?string}
70009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
70109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    this._className = descriptor.className || null;
70209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
70309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
704c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Runtime.Extension.prototype = {
70509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
70609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @return {!Object}
70709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
70809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    descriptor: function()
70909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
71009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return this._descriptor;
71109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
71209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
71309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
714c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)     * @return {!Runtime.Module}
71509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
71609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    module: function()
71709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
71809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return this._module;
71909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
72009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
72109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
722d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)     * @return {?function(new:Object)}
723d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)     */
724d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    _typeClass: function()
725d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    {
726d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!this._hasTypeClass)
727d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return null;
728323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        return this._module._manager._resolve(this._type.substring(1));
729d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    },
730d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
731d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    /**
73209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @param {?Object} context
73309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @return {boolean}
73409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
73509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    isApplicable: function(context)
73609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
737323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        return this._module._manager.isExtensionApplicableToContext(this, context);
73809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    },
73909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
74009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    /**
74109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     * @return {?Object}
74209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)     */
74309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    instance: function()
74409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    {
74509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (!this._className)
74609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return null;
74709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
74809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (!this._instance) {
74909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            this._module._load();
75009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
75109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            var constructorFunction = window.eval(this._className);
75209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!(constructorFunction instanceof Function))
75309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                return null;
75409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
75509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            this._instance = new constructorFunction();
75609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
75709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return this._instance;
75809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
75909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
76009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
76109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/**
7627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @constructor
7637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci */
7647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime.ExperimentsSupport = function()
7657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
7667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    this._supportEnabled = Runtime.queryParam("experiments") !== null;
7677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    this._experiments = [];
7687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    this._experimentNames = {};
7697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    this._enabledTransiently = {};
7707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
7717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
7727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime.ExperimentsSupport.prototype = {
7737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
7747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @return {!Array.<!Runtime.Experiment>}
7757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
7767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    allExperiments: function()
7777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
7787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return this._experiments.slice();
7797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
7807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
7817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
7827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @return {boolean}
7837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
7847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    supportEnabled: function()
7857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
7867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return this._supportEnabled;
7877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
7887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
7897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
7907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {!Object} value
7917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
7927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    _setExperimentsSetting: function(value)
7937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
7947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!self.localStorage)
7957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return;
7967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        self.localStorage["experiments"] = JSON.stringify(value);
7977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
7987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
7997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
8007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {string} experimentName
8017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {string} experimentTitle
8027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {boolean=} hidden
8037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
8047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    register: function(experimentName, experimentTitle, hidden)
8057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
8067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        console.assert(!this._experimentNames[experimentName], "Duplicate registration of experiment " + experimentName);
8077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        this._experimentNames[experimentName] = true;
8087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        this._experiments.push(new Runtime.Experiment(this, experimentName, experimentTitle, !!hidden));
8097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
8107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
8117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
8127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {string} experimentName
8137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @return {boolean}
8147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
8157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    isEnabled: function(experimentName)
8167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
8177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        this._checkExperiment(experimentName);
8187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
8197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (this._enabledTransiently[experimentName])
8207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return true;
8217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!this.supportEnabled())
8227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return false;
8237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
8247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return !!Runtime._experimentsSetting()[experimentName];
8257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
8267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
8277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
8287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {string} experimentName
8297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {boolean} enabled
8307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
8317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    setEnabled: function(experimentName, enabled)
8327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
8337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        this._checkExperiment(experimentName);
8347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!enabled)
8357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            delete this._enabledTransiently[experimentName];
8367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        var experimentsSetting = Runtime._experimentsSetting();
8377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        experimentsSetting[experimentName] = enabled;
8387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        this._setExperimentsSetting(experimentsSetting);
8397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
8407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
8417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
8427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {!Array.<string>} experimentNames
8437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
8447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    setDefaultExperiments: function(experimentNames)
8457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
8467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        for (var i = 0; i < experimentNames.length; ++i) {
8477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            this._checkExperiment(experimentNames[i]);
8487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            this._enabledTransiently[experimentNames[i]] = true;
8497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
8507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
8517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
8527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
8537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {string} experimentName
8547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
8557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    enableForTest: function(experimentName)
8567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
8577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        this._checkExperiment(experimentName);
8587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        this._enabledTransiently[experimentName] = true;
8597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
8607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
8617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    cleanUpStaleExperiments: function()
8627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
8637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        var experimentsSetting = Runtime._experimentsSetting();
8647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        var cleanedUpExperimentSetting = {};
8657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        for (var i = 0; i < this._experiments.length; ++i) {
8667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            var experimentName = this._experiments[i].name;
8677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (experimentsSetting[experimentName])
8687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                cleanedUpExperimentSetting[experimentName] = true;
8697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
8707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        this._setExperimentsSetting(cleanedUpExperimentSetting);
8717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
8727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
8737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
8747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {string} experimentName
8757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
8767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    _checkExperiment: function(experimentName)
8777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
8787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        console.assert(this._experimentNames[experimentName], "Unknown experiment " + experimentName);
8797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
8807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
8817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
8827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci/**
8837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @constructor
8847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @param {!Runtime.ExperimentsSupport} experiments
8857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @param {string} name
8867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @param {string} title
8877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci * @param {boolean} hidden
888197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch */
8897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime.Experiment = function(experiments, name, title, hidden)
8907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
8917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    this.name = name;
8927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    this.title = title;
8937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    this.hidden = hidden;
8947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    this._experiments = experiments;
8957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
8967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
8977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime.Experiment.prototype = {
8987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
8997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @return {boolean}
9007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
9017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    isEnabled: function()
9027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
9037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return this._experiments.isEnabled(this.name);
9047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    },
9057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
9067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    /**
9077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     * @param {boolean} enabled
9087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci     */
9097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    setEnabled: function(enabled)
9107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
9117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        this._experiments.setEnabled(this.name, enabled);
9127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
9137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
9147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
9157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{(function parseQueryParameters()
9167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
9177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var queryParams = location.search;
9187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!queryParams)
9197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
9207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var params = queryParams.substring(1).split("&");
9217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    for (var i = 0; i < params.length; ++i) {
9227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        var pair = params[i].split("=");
9237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        Runtime._queryParamsObject[pair[0]] = pair[1];
9247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
9257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
9267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Patch settings from the URL param (for tests).
9277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    var settingsParam = Runtime.queryParam("settings");
9287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (settingsParam) {
9297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        try {
9307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            var settings = JSON.parse(window.decodeURI(settingsParam));
9317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            for (var key in settings)
9327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                window.localStorage[key] = settings[key];
9337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        } catch(e) {
9347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            // Ignore malformed settings.
9357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
9367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
9377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci})();}
9387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
9397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// This must be constructed after the query parameters have been parsed.
9407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciRuntime.experiments = new Runtime.ExperimentsSupport();
9417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
9427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci/** @type {!Runtime} */
943c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)var runtime;
944