Created
December 11, 2018 09:39
-
-
Save nelsonsilva/d5ef46b8269a55941a9e0e100e1c9eea to your computer and use it in GitHub Desktop.
import-href.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
@license | |
Copyright (c) 2017 The Polymer Project Authors. All rights reserved. | |
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt | |
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | |
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt | |
Code distributed by Google as part of the polymer project is also | |
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt | |
*/ | |
// 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. | |
* | |
* @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 const importHref = function(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. | |
let cleanup = function() { | |
link.removeEventListener('load', loadListener); | |
link.removeEventListener('error', errorListener); | |
}; | |
let 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); | |
}); | |
} | |
}; | |
let 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; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment