Ghost/ghost/admin/app/services/lazy-loader.js

85 lines
2.5 KiB
JavaScript
Raw Normal View History

import RSVP from 'rsvp';
import Service, {inject as service} from '@ember/service';
import config from 'ghost-admin/config/environment';
export default Service.extend({
ajax: service(),
ghostPaths: service(),
// This is needed so we can disable it in unit tests
testing: undefined,
scriptPromises: null,
init() {
this._super(...arguments);
this.scriptPromises = {};
if (this.testing === undefined) {
this.testing = config.environment === 'test';
}
},
loadScript(key, url) {
if (this.testing) {
return RSVP.resolve();
}
if (this.scriptPromises[key]) {
return this.scriptPromises[key];
}
let scriptPromise = new RSVP.Promise((resolve, reject) => {
let {adminRoot} = this.ghostPaths;
let script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = `${adminRoot}${url}`;
let el = document.getElementsByTagName('script')[0];
el.parentNode.insertBefore(script, el);
script.addEventListener('load', () => {
resolve();
});
script.addEventListener('error', () => {
reject(new Error(`${url} failed to load`));
});
});
this.scriptPromises[key] = scriptPromise;
return scriptPromise;
},
loadStyle(key, url, alternate = false) {
if (this.testing || document.querySelector(`#${key}-styles`)) {
return RSVP.resolve();
}
return new RSVP.Promise((resolve, reject) => {
let link = document.createElement('link');
link.id = `${key}-styles`;
link.rel = alternate ? 'alternate stylesheet' : 'stylesheet';
link.href = `${this.ghostPaths.adminRoot}${url}`;
link.onload = () => {
if (alternate) {
// If stylesheet is alternate and we disable the stylesheet before injecting into the DOM,
// the onload handler never gets called. Thus, we should disable the link after it has finished loading
link.disabled = true;
}
resolve();
};
link.onerror = reject;
if (alternate) {
link.title = key;
}
document.querySelector('head').appendChild(link);
});
}
});