|  | /** | 
|  | * @license | 
|  | * Copyright (C) 2017 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. | 
|  | */ | 
|  | (function() { | 
|  | 'use strict'; | 
|  |  | 
|  | Polymer({ | 
|  | is: 'gr-plugin-host', | 
|  | _legacyUndefinedCheck: true, | 
|  |  | 
|  | properties: { | 
|  | config: { | 
|  | type: Object, | 
|  | observer: '_configChanged', | 
|  | }, | 
|  | }, | 
|  |  | 
|  | behaviors: [ | 
|  | Gerrit.BaseUrlBehavior, | 
|  | ], | 
|  |  | 
|  | _configChanged(config) { | 
|  | const plugins = config.plugin; | 
|  | const htmlPlugins = (plugins.html_resource_paths || []) | 
|  | .map(p => this._urlFor(p)) | 
|  | .filter(p => !Gerrit._isPluginPreloaded(p)); | 
|  | const jsPlugins = | 
|  | this._handleMigrations(plugins.js_resource_paths || [], htmlPlugins) | 
|  | .map(p => this._urlFor(p)) | 
|  | .filter(p => !Gerrit._isPluginPreloaded(p)); | 
|  | const shouldLoadTheme = config.default_theme && | 
|  | !Gerrit._isPluginPreloaded('preloaded:gerrit-theme'); | 
|  | const defaultTheme = | 
|  | shouldLoadTheme ? this._urlFor(config.default_theme) : null; | 
|  | const pluginsPending = | 
|  | [].concat(jsPlugins, htmlPlugins, defaultTheme || []); | 
|  | Gerrit._setPluginsPending(pluginsPending); | 
|  | if (defaultTheme) { | 
|  | // Make theme first to be first to load. | 
|  | // Load sync to work around rare theme loading race condition. | 
|  | this._importHtmlPlugins([defaultTheme], true); | 
|  | } | 
|  | this._loadJsPlugins(jsPlugins); | 
|  | this._importHtmlPlugins(htmlPlugins); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * Omit .js plugins that have .html counterparts. | 
|  | * For example, if plugin provides foo.js and foo.html, skip foo.js. | 
|  | */ | 
|  | _handleMigrations(jsPlugins, htmlPlugins) { | 
|  | return jsPlugins.filter(url => { | 
|  | const counterpart = url.replace(/\.js$/, '.html'); | 
|  | return !htmlPlugins.includes(counterpart); | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @suppress {checkTypes} | 
|  | * States that it expects no more than 3 parameters, but that's not true. | 
|  | * @todo (beckysiegel) check Polymer annotations and submit change. | 
|  | * @param {Array} plugins | 
|  | * @param {boolean=} opt_sync | 
|  | */ | 
|  | _importHtmlPlugins(plugins, opt_sync) { | 
|  | const async = !opt_sync; | 
|  | for (const url of plugins) { | 
|  | // onload (second param) needs to be a function. When null or undefined | 
|  | // were passed, plugins were not loaded correctly. | 
|  | this.importHref( | 
|  | this._urlFor(url), () => {}, | 
|  | Gerrit._pluginInstallError.bind(null, `${url} import error`), | 
|  | async); | 
|  | } | 
|  | }, | 
|  |  | 
|  | _loadJsPlugins(plugins) { | 
|  | for (const url of plugins) { | 
|  | this._createScriptTag(this._urlFor(url)); | 
|  | } | 
|  | }, | 
|  |  | 
|  | _createScriptTag(url) { | 
|  | const el = document.createElement('script'); | 
|  | el.defer = true; | 
|  | el.src = url; | 
|  | el.onerror = Gerrit._pluginInstallError.bind(null, `${url} load error`); | 
|  | return document.body.appendChild(el); | 
|  | }, | 
|  |  | 
|  | _urlFor(pathOrUrl) { | 
|  | if (!pathOrUrl) { | 
|  | return pathOrUrl; | 
|  | } | 
|  | if (pathOrUrl.startsWith('preloaded:') || | 
|  | pathOrUrl.startsWith('http')) { | 
|  | // Plugins are loaded from another domain or preloaded. | 
|  | return pathOrUrl; | 
|  | } | 
|  | if (!pathOrUrl.startsWith('/')) { | 
|  | pathOrUrl = '/' + pathOrUrl; | 
|  | } | 
|  | return window.location.origin + this.getBaseUrl() + pathOrUrl; | 
|  | }, | 
|  | }); | 
|  | })(); |