| /** |
| * @license |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * This defines the Gerrit instance. All methods directly attached to Gerrit |
| * should be defined or linked here. |
| */ |
| |
| (function(window) { |
| 'use strict'; |
| |
| /** |
| * Hash of loaded and installed plugins, name to Plugin object. |
| */ |
| const _plugins = {}; |
| |
| /** |
| * Array of plugin URLs to be loaded, name to url. |
| */ |
| let _pluginsPending = {}; |
| |
| let _pluginsInstalled = []; |
| |
| let _pluginsPendingCount = -1; |
| |
| const UNKNOWN_PLUGIN = 'unknown'; |
| const PRELOADED_PROTOCOL = 'preloaded:'; |
| |
| const PLUGIN_LOADING_TIMEOUT_MS = 10000; |
| |
| let _reporting; |
| const getReporting = () => { |
| if (!_reporting) { |
| _reporting = document.createElement('gr-reporting'); |
| } |
| return _reporting; |
| }; |
| |
| // Import utils methods |
| const { |
| getPluginNameFromUrl, |
| send, |
| getRestAPI, |
| } = window._apiUtils; |
| |
| const API_VERSION = '0.1'; |
| |
| /** |
| * Trigger the preinstalls for bundled plugins. |
| * This needs to happen before Gerrit as plugin bundle overrides the Gerrit. |
| */ |
| function flushPreinstalls() { |
| if (window.Gerrit.flushPreinstalls) { |
| window.Gerrit.flushPreinstalls(); |
| } |
| } |
| flushPreinstalls(); |
| |
| window.Gerrit = window.Gerrit || {}; |
| const Gerrit = window.Gerrit; |
| |
| let _resolveAllPluginsLoaded = null; |
| let _allPluginsPromise = null; |
| |
| Gerrit._endpoints = new GrPluginEndpoints(); |
| |
| // Provide reset plugins function to clear installed plugins between tests. |
| const app = document.querySelector('#app'); |
| if (!app) { |
| // No gr-app found (running tests) |
| const { |
| testOnly_resetInternalState, |
| } = window._apiUtils; |
| Gerrit._testOnly_installPreloadedPlugins = installPreloadedPlugins; |
| Gerrit._testOnly_flushPreinstalls = flushPreinstalls; |
| Gerrit._testOnly_resetPlugins = () => { |
| _allPluginsPromise = null; |
| _pluginsInstalled = []; |
| _pluginsPending = {}; |
| _pluginsPendingCount = -1; |
| _reporting = null; |
| _resolveAllPluginsLoaded = null; |
| testOnly_resetInternalState(); |
| Gerrit._endpoints = new GrPluginEndpoints(); |
| for (const k of Object.keys(_plugins)) { |
| delete _plugins[k]; |
| } |
| }; |
| } |
| |
| /** |
| * @deprecated Use plugin.styles().css(rulesStr) instead. Please, consult |
| * the documentation how to replace it accordingly. |
| */ |
| Gerrit.css = function(rulesStr) { |
| console.warn('Gerrit.css(rulesStr) is deprecated!', |
| 'Use plugin.styles().css(rulesStr)'); |
| if (!Gerrit._customStyleSheet) { |
| const styleEl = document.createElement('style'); |
| document.head.appendChild(styleEl); |
| Gerrit._customStyleSheet = styleEl.sheet; |
| } |
| |
| const name = '__pg_js_api_class_' + |
| Gerrit._customStyleSheet.cssRules.length; |
| Gerrit._customStyleSheet.insertRule('.' + name + '{' + rulesStr + '}', 0); |
| return name; |
| }; |
| |
| Gerrit.install = function(callback, opt_version, opt_src) { |
| // HTML import polyfill adds __importElement pointing to the import tag. |
| const script = document.currentScript && |
| (document.currentScript.__importElement || document.currentScript); |
| |
| let src = opt_src || (script && script.src); |
| if (!src || src.startsWith('data:')) { |
| src = script && script.baseURI; |
| } |
| const name = getPluginNameFromUrl(src); |
| |
| if (opt_version && opt_version !== API_VERSION) { |
| Gerrit._pluginInstallError(`Plugin ${name} install error: only version ` + |
| API_VERSION + ' is supported in PolyGerrit. ' + opt_version + |
| ' was given.'); |
| return; |
| } |
| |
| const existingPlugin = _plugins[name]; |
| const plugin = existingPlugin || new Plugin(src); |
| try { |
| callback(plugin); |
| if (name) { |
| _plugins[name] = plugin; |
| } |
| if (!existingPlugin) { |
| Gerrit._pluginInstalled(src); |
| } |
| } catch (e) { |
| Gerrit._pluginInstallError(`${e.name}: ${e.message}`); |
| } |
| }; |
| |
| Gerrit.getLoggedIn = function() { |
| console.warn('Gerrit.getLoggedIn() is deprecated! ' + |
| 'Use plugin.restApi().getLoggedIn()'); |
| return document.createElement('gr-rest-api-interface').getLoggedIn(); |
| }; |
| |
| Gerrit.get = function(url, callback) { |
| console.warn('.get() is deprecated! Use plugin.restApi().get()'); |
| send('GET', url, callback); |
| }; |
| |
| Gerrit.post = function(url, payload, callback) { |
| console.warn('.post() is deprecated! Use plugin.restApi().post()'); |
| send('POST', url, callback, payload); |
| }; |
| |
| Gerrit.put = function(url, payload, callback) { |
| console.warn('.put() is deprecated! Use plugin.restApi().put()'); |
| send('PUT', url, callback, payload); |
| }; |
| |
| Gerrit.delete = function(url, opt_callback) { |
| console.warn('.delete() is deprecated! Use plugin.restApi().delete()'); |
| return getRestAPI().send('DELETE', url).then(response => { |
| if (response.status !== 204) { |
| return response.text().then(text => { |
| if (text) { |
| return Promise.reject(text); |
| } else { |
| return Promise.reject(response.status); |
| } |
| }); |
| } |
| if (opt_callback) { |
| opt_callback(response); |
| } |
| return response; |
| }); |
| }; |
| |
| Gerrit.awaitPluginsLoaded = function() { |
| if (!_allPluginsPromise) { |
| if (Gerrit._arePluginsLoaded()) { |
| _allPluginsPromise = Promise.resolve(); |
| } else { |
| let timeoutId; |
| _allPluginsPromise = |
| Promise.race([ |
| new Promise(resolve => _resolveAllPluginsLoaded = resolve), |
| new Promise(resolve => timeoutId = setTimeout( |
| Gerrit._pluginLoadingTimeout, PLUGIN_LOADING_TIMEOUT_MS)), |
| ]).then(() => clearTimeout(timeoutId)); |
| } |
| } |
| return _allPluginsPromise; |
| }; |
| |
| Gerrit._pluginLoadingTimeout = function() { |
| console.error(`Failed to load plugins: ${Object.keys(_pluginsPending)}`); |
| Gerrit._setPluginsPending([]); |
| }; |
| |
| Gerrit._setPluginsPending = function(plugins) { |
| _pluginsPending = plugins.reduce((o, url) => { |
| // TODO(viktard): Remove guard (@see Issue 8962) |
| o[getPluginNameFromUrl(url) || UNKNOWN_PLUGIN] = url; |
| return o; |
| }, {}); |
| Gerrit._setPluginsCount(Object.keys(_pluginsPending).length); |
| }; |
| |
| Gerrit._setPluginsCount = function(count) { |
| _pluginsPendingCount = count; |
| if (Gerrit._arePluginsLoaded()) { |
| getReporting().pluginsLoaded(_pluginsInstalled); |
| if (_resolveAllPluginsLoaded) { |
| _resolveAllPluginsLoaded(); |
| } |
| } |
| }; |
| |
| Gerrit._pluginInstallError = function(message) { |
| document.dispatchEvent(new CustomEvent('show-alert', { |
| detail: { |
| message: `Plugin install error: ${message}`, |
| }, |
| })); |
| console.info(`Plugin install error: ${message}`); |
| Gerrit._setPluginsCount(_pluginsPendingCount - 1); |
| }; |
| |
| Gerrit._pluginInstalled = function(url) { |
| const name = getPluginNameFromUrl(url) || UNKNOWN_PLUGIN; |
| if (!_pluginsPending[name]) { |
| console.warn(`Unexpected plugin ${name} installed from ${url}.`); |
| } else { |
| delete _pluginsPending[name]; |
| _pluginsInstalled.push(name); |
| Gerrit._setPluginsCount(_pluginsPendingCount - 1); |
| getReporting().pluginLoaded(name); |
| console.log(`Plugin ${name} installed.`); |
| } |
| }; |
| |
| Gerrit._arePluginsLoaded = function() { |
| return _pluginsPendingCount === 0; |
| }; |
| |
| Gerrit._getPluginScreenName = function(pluginName, screenName) { |
| return `${pluginName}-screen-${screenName}`; |
| }; |
| |
| Gerrit._isPluginPreloaded = function(url) { |
| const name = getPluginNameFromUrl(url); |
| if (name && Gerrit._preloadedPlugins) { |
| return name in Gerrit._preloadedPlugins; |
| } else { |
| return false; |
| } |
| }; |
| |
| function installPreloadedPlugins() { |
| if (!Gerrit._preloadedPlugins) { return; } |
| for (const name in Gerrit._preloadedPlugins) { |
| if (!Gerrit._preloadedPlugins.hasOwnProperty(name)) { continue; } |
| const callback = Gerrit._preloadedPlugins[name]; |
| Gerrit.install(callback, API_VERSION, PRELOADED_PROTOCOL + name); |
| } |
| } |
| |
| // Preloaded plugins should be installed after Gerrit.install() is set, |
| // since plugin preloader substitutes Gerrit.install() temporarily. |
| installPreloadedPlugins(); |
| })(window); |