/** * @license * Copyright (C) 2016 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'; const HLJS_PATH = 'bower_components/highlightjs/highlight.min.js'; const DARK_THEME_PATH = 'styles/themes/dark-theme.html'; Polymer({ is: 'gr-lib-loader', properties: { _hljsState: { type: Object, // NOTE: intended singleton. value: { configured: false, loading: false, callbacks: [], }, }, }, /** * Get the HLJS library. Returns a promise that resolves with a reference to * the library after it's been loaded. The promise resolves immediately if * it's already been loaded. * @return {!Promise} */ getHLJS() { return new Promise((resolve, reject) => { // If the lib is totally loaded, resolve immediately. if (this._getHighlightLib()) { resolve(this._getHighlightLib()); return; } // If the library is not currently being loaded, then start loading it. if (!this._hljsState.loading) { this._hljsState.loading = true; this._loadScript(this._getHLJSUrl()) .then(this._onHLJSLibLoaded.bind(this)).catch(reject); } this._hljsState.callbacks.push(resolve); }); }, /** * Loads the dark theme document. Returns a promise that resolves with a * custom-style DOM element. * @return {!Promise} */ getDarkTheme() { return new Promise((resolve, reject) => { this.importHref(this._getLibRoot() + DARK_THEME_PATH, () => { const module = document.createElement('style', 'custom-style'); module.setAttribute('include', 'dark-theme'); resolve(module); }); }); }, /** * Execute callbacks awaiting the HLJS lib load. */ _onHLJSLibLoaded() { const lib = this._getHighlightLib(); this._hljsState.loading = false; for (const cb of this._hljsState.callbacks) { cb(lib); } this._hljsState.callbacks = []; }, /** * Get the HLJS library, assuming it has been loaded. Configure the library * if it hasn't already been configured. * @return {!Object} */ _getHighlightLib() { const lib = window.hljs; if (lib && !this._hljsState.configured) { this._hljsState.configured = true; lib.configure({classPrefix: 'gr-diff gr-syntax gr-syntax-'}); } return lib; }, /** * Get the resource path used to load the application. If the application * was loaded through a CDN, then this will be the path to CDN resources. * @return {string} */ _getLibRoot() { if (window.STATIC_RESOURCE_PATH) { return window.STATIC_RESOURCE_PATH + '/'; } return '/'; }, /** * Load and execute a JS file from the lib root. * @param {string} src The path to the JS file without the lib root. * @return {Promise} a promise that resolves when the script's onload * executes. */ _loadScript(src) { return new Promise((resolve, reject) => { const script = document.createElement('script'); if (!src) { reject(new Error('Unable to load blank script url.')); return; } script.src = src; script.onload = resolve; script.onerror = reject; Polymer.dom(document.head).appendChild(script); }); }, _getHLJSUrl() { const root = this._getLibRoot(); if (!root) { return null; } return root + HLJS_PATH; }, }); })();