framework7
Version:
Full featured mobile HTML framework for building iOS & Android apps
125 lines (123 loc) • 4.35 kB
JavaScript
import { getWindow, getDocument } from 'ssr-window';
import { id } from '../../shared/utils.js';
import $ from '../../shared/dom7.js';
const fetchedModules = [];
function loadModule(moduleToLoad) {
const Framework7 = this;
const window = getWindow();
const document = getDocument();
return new Promise((resolve, reject) => {
const app = Framework7.instance;
let modulePath;
let moduleObj;
let moduleFunc;
if (!moduleToLoad) {
reject(new Error('Framework7: Lazy module must be specified'));
return;
}
function install(module) {
Framework7.use(module);
if (app) {
app.useModuleParams(module, app.params);
app.useModule(module);
}
}
if (typeof moduleToLoad === 'string') {
const matchNamePattern = moduleToLoad.match(/([a-z0-9-]*)/i);
if (moduleToLoad.indexOf('.') < 0 && matchNamePattern && matchNamePattern[0].length === moduleToLoad.length) {
if (!app || app && !app.params.lazyModulesPath) {
reject(new Error('Framework7: "lazyModulesPath" app parameter must be specified to fetch module by name'));
return;
}
modulePath = `${app.params.lazyModulesPath}/${moduleToLoad}/${moduleToLoad}.lazy.js`;
} else {
modulePath = moduleToLoad;
}
} else if (typeof moduleToLoad === 'function') {
moduleFunc = moduleToLoad;
} else {
// considering F7-Plugin object
moduleObj = moduleToLoad;
}
if (moduleFunc) {
const module = moduleFunc(Framework7, false);
if (!module) {
reject(new Error("Framework7: Can't find Framework7 component in specified component function"));
return;
}
// Check if it was added
if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
resolve();
return;
}
// Install It
install(module);
resolve();
}
if (moduleObj) {
const module = moduleObj;
if (!module) {
reject(new Error("Framework7: Can't find Framework7 component in specified component"));
return;
}
// Check if it was added
if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
resolve();
return;
}
// Install It
install(module);
resolve();
}
if (modulePath) {
if (fetchedModules.indexOf(modulePath) >= 0) {
resolve();
return;
}
fetchedModules.push(modulePath);
const scriptLoad = new Promise((resolveScript, rejectScript) => {
fetch(modulePath).then(res => res.text()).then(scriptContent => {
const callbackId = id();
const callbackLoadName = `f7_component_loader_callback_${callbackId}`;
const scriptEl = document.createElement('script');
scriptEl.innerHTML = `window.${callbackLoadName} = function (Framework7, Framework7AutoInstallComponent) {return ${scriptContent.trim()}}`;
$('head').append(scriptEl);
const componentLoader = window[callbackLoadName];
delete window[callbackLoadName];
$(scriptEl).remove();
const module = componentLoader(Framework7, false);
if (!module) {
rejectScript(new Error(`Framework7: Can't find Framework7 component in ${modulePath} file`));
return;
}
// Check if it was added
if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
resolveScript();
return;
}
// Install It
install(module);
resolveScript();
}).catch(err => {
rejectScript(err);
});
});
const styleLoad = new Promise(resolveStyle => {
fetch(modulePath.replace('.lazy.js', app.rtl ? '.rtl.css' : '.css').replace('.js', app.rtl ? '.rtl.css' : '.css')).then(res => res.text()).then(styleContent => {
const styleEl = document.createElement('style');
styleEl.innerHTML = styleContent;
$('head').append(styleEl);
resolveStyle();
}).catch(() => {
resolveStyle();
});
});
Promise.all([scriptLoad, styleLoad]).then(() => {
resolve();
}).catch(err => {
reject(err);
});
}
});
}
export default loadModule;