Last active
January 8, 2017 03:43
-
-
Save imlinus/3dede2a3faf3445024547997fecc5df2 to your computer and use it in GitHub Desktop.
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
<html> | |
<head> | |
<script type="text/javascript"> | |
"use strict"; | |
(function() { | |
class ScriptAsync extends HTMLElement { | |
static get observedAttributes() { | |
return ['packages', 'oncomplete', 'locals']; | |
} | |
get packages() { return this.getAttribute('packages'); } | |
get oncomplete() { return this.getAttribute('oncomplete'); } | |
get locals() { return this.getAttribute('locals'); } | |
get api() { return 'http://api.jsdelivr.com/v1/jsdelivr/libraries'; } | |
get jsdelivr() { return 'https://cdn.jsdelivr.net'; } | |
constructor() { | |
super(); | |
this._counter = 0; | |
this._packages = []; | |
this._locals = undefined; | |
document.addEventListener("DOMContentLoaded", () => this.windowLoaded()); | |
} | |
attributeChangedCallback(name, oldValue, newValue) { | |
this._counter += 1; | |
if (this._counter === this.attributes.length) { | |
let packs = this.preparePackages(this.packages); | |
this.loadPackages(packs); | |
} | |
} | |
preparePackages(packs) { | |
packs.split(',').forEach(pack => { | |
let details = pack.split('@'); | |
this._packages.push({ | |
name: details[0], | |
version: details[1] | |
}) | |
}); | |
return this._packages; | |
}; | |
loadPackages(packages) { | |
let proms = [], | |
proms2 = []; | |
packages.forEach(pack => { | |
let promise = new Promise((resolve, reject) => { | |
let url = this.packageUrl(pack); | |
proms2.push(this.appendScript(url)); | |
resolve(pack); | |
}); | |
proms.push(promise); | |
}); | |
Promise.all(proms).then((packs) => { | |
packs.forEach(pack => console.info(`${pack.name}@${pack.version}`)); | |
Promise.all(proms2).then(() => { | |
if (this.locals) | |
this.locals.split(',').forEach(local => this.appendScript(this.locals)); | |
}); | |
}); | |
} | |
packageUrl(pack) { | |
pack.name = pack.name.replace(' ', '*'); | |
if (pack.version) { | |
let packInfo = this.getPackageVersion(pack.name, pack.version); | |
if (packInfo) { | |
return `${this.jsdelivr}/${packInfo.name}/${packInfo.version}/${packInfo.mainfile}`; | |
} | |
console.warn(`Can't find package for ${pack.name}@${pack.version}`); | |
return; | |
} else { | |
let packInfo = this.getPackageInfo(pack.name)[0]; | |
if (packInfo) { | |
pack.version = packInfo.lastversion; | |
return `${this.jsdelivr}/${packInfo.name}/${packInfo.lastversion}/${packInfo.mainfile}`; | |
} | |
console.warn(`Can't find package for ${pack.name}`); | |
return undefined; | |
} | |
} | |
getPackageInfo(packageName) { | |
let baseUri = `${this.api}?name=${packageName}&fields=name,lastversion,mainfile`; | |
return JSON.parse(this.httpsync(baseUri)); | |
} | |
getPackageVersion(packageName, version) { | |
let baseUri = `${this.api}?name=${packageName}&fields=name,assets`; | |
let json = JSON.parse(this.httpsync(baseUri)); | |
let foundPackage = undefined; | |
if (json.length > 0) { | |
json[0].assets.every((asset, index) => { | |
if (version === asset.version) { | |
console.info(`Found matching version for ${json[0].name}@${asset.version}`); | |
foundPackage = asset; | |
foundPackage.name = json[0].name; | |
return false; | |
} | |
return true; | |
}); | |
} | |
return foundPackage; | |
} | |
appendScript(filename) { | |
let pr = new Promise((resolve, reject) => { | |
if (filename) { | |
eval(this.httpsync(filename)); | |
} | |
resolve(filename); | |
}); | |
return pr; | |
} | |
httpsync(url) { | |
var xhrObj = new XMLHttpRequest(); | |
xhrObj.open('GET', url, false); | |
xhrObj.send(''); | |
return xhrObj.responseText; | |
} | |
callback(resolve, filename) { | |
resolve(); | |
} | |
windowLoaded() { | |
if (this.oncomplete) | |
eval(this.oncomplete); | |
} | |
} | |
customElements.define('script-async', ScriptAsync); | |
})(); | |
</script> | |
<script-async packages="modernizr,[email protected]" locals="assets/js/lib/TweenMax.min.js,assets/js/main.js" oncomplete="initCallBack()" ></script-async> | |
</head> | |
<body> | |
<h1>Hello, World.</h1> | |
<script type="text/javascript"> | |
function initCallback() { | |
console.log('Lets Go'); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment