Files
gerrit/polygerrit-ui/app/scripts/import-href.js
Dmitrii Filippov b51a20dfd8 Add files with polymer helper methods.
The bundled-polymer.js is a replacement for the
polymer-bridges/polymer/polymer.html file. The polymer.html file loads
other scripts to setup different global variables. Because polygerrit
code still uses global variables (like Polymer.importHref and other),
we must setup this global variables after conversion to es6 modules.

The bundled-polymer.js imports all scripts in the same order as the
polymer.html does and must be imported in all es6-modules instead
of the polymer.html file.

The import-href.js is a replacement for the
polymer-bridges/polymer/lib/utils/import-href.html file. The html
file contains code inside <script>...</script> and can't be imported
in es6 modules.

Change-Id: I321be93b03cd5a5995af5ac5a5d263dd7c9a39ef
2020-03-17 10:08:18 +00:00

109 lines
3.8 KiB
JavaScript

/**
* @license
* Copyright (C) 2020 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 file is a replacement for the
// polymer-bridges/polymer/lib/utils/import-href.html file. The html
// file contains code inside <script>...</script> and can't be imported
// in es6 modules.
// run a callback when HTMLImports are ready or immediately if
// this api is not available.
function whenImportsReady(cb) {
if (window.HTMLImports) {
HTMLImports.whenReady(cb);
} else {
cb();
}
}
/**
* Convenience method for importing an HTML document imperatively.
*
* This method creates a new `<link rel="import">` element with
* the provided URL and appends it to the document to start loading.
* In the `onload` callback, the `import` property of the `link`
* element will contain the imported document contents.
*
* @memberof Polymer
* @param {string} href URL to document to load.
* @param {?function(!Event):void=} onload Callback to notify when an import successfully
* loaded.
* @param {?function(!ErrorEvent):void=} onerror Callback to notify when an import
* unsuccessfully loaded.
* @param {boolean=} optAsync True if the import should be loaded `async`.
* Defaults to `false`.
* @return {!HTMLLinkElement} The link element for the URL to be loaded.
*/
export function importHref(href, onload, onerror, optAsync) {
let link = /** @type {HTMLLinkElement} */
(document.head.querySelector('link[href="' + href + '"][import-href]'));
if (!link) {
link = /** @type {HTMLLinkElement} */ (document.createElement('link'));
link.rel = 'import';
link.href = href;
link.setAttribute('import-href', '');
}
// always ensure link has `async` attribute if user specified one,
// even if it was previously not async. This is considered less confusing.
if (optAsync) {
link.setAttribute('async', '');
}
// NOTE: the link may now be in 3 states: (1) pending insertion,
// (2) inflight, (3) already loaded. In each case, we need to add
// event listeners to process callbacks.
const cleanup = function() {
link.removeEventListener('load', loadListener);
link.removeEventListener('error', errorListener);
};
const loadListener = function(event) {
cleanup();
// In case of a successful load, cache the load event on the link so
// that it can be used to short-circuit this method in the future when
// it is called with the same href param.
link.__dynamicImportLoaded = true;
if (onload) {
whenImportsReady(() => {
onload(event);
});
}
};
const errorListener = function(event) {
cleanup();
// In case of an error, remove the link from the document so that it
// will be automatically created again the next time `importHref` is
// called.
if (link.parentNode) {
link.parentNode.removeChild(link);
}
if (onerror) {
whenImportsReady(() => {
onerror(event);
});
}
};
link.addEventListener('load', loadListener);
link.addEventListener('error', errorListener);
if (link.parentNode == null) {
document.head.appendChild(link);
// if the link already loaded, dispatch a fake load event
// so that listeners are called and get a proper event argument.
} else if (link.__dynamicImportLoaded) {
link.dispatchEvent(new Event('load'));
}
return link;
}