okam-core
Version:
The extension for small program framework
202 lines (173 loc) • 5.53 kB
JavaScript
/**
* @file Create App/Page/Component instance
* @author sparklewhy@gmail.com
*/
;
import {mixin, isFunction} from '../util/index';
import {normalizeOkamProps} from './props';
import {appGlobal} from '../na/index';
let pluginCache = {
usedExtensions: Object.create(null),
installedPlugins: [],
baseClasses: Object.create(null)
};
const APP_TYPE = 'app';
const COMPONENT_TYPE = 'comp';
const PAGE_TYPE = 'page';
/**
* Initialize the extensions
*
* @inner
* @param {string} type the type to initialize
* @param {Object} instance the instance to init
* @param {Object} base the instance base to inherit
* @return {Object}
*/
function initExtensions(type, instance, base) {
let cache = pluginCache;
if (process.env.APP_TYPE === 'quick') {
if (!appGlobal.okamPluginCache) {
appGlobal.okamPluginCache = pluginCache;
}
cache = appGlobal.okamPluginCache;
}
let existedBase = cache.baseClasses[type];
if (!existedBase) {
let plugins = cache.usedExtensions[type];
let args = [{}];
plugins && Array.prototype.push.apply(args, plugins);
args.push(base);
existedBase = mixin.apply(this, args);
cache.baseClasses[type] = existedBase;
}
return mixin.apply(this, [instance, existedBase]);
}
/**
* Add extension
*
* @inner
* @param {string} type the extension type
* @param {Object} extension the extension
*/
function addExtension(type, extension) {
if (!extension) {
return;
}
let cache = pluginCache;
if (process.env.APP_TYPE === 'quick') {
cache = appGlobal.okamPluginCache;
}
let existedExtensions = cache.usedExtensions[type];
/* istanbul ignore next */
if (!existedExtensions) {
existedExtensions = cache.usedExtensions[type] = [];
}
existedExtensions.push(extension);
}
/**
* Initialize the component data
*
* @inner
* @param {Object} instance the instance to init
* @param {?Object} options the component init extra options information
* @param {boolean} isPage whether is page component
*/
function initComponentData(instance, options, isPage) {
let data = instance.data;
if (isFunction(data)) {
instance.data = instance.data();
}
instance.$init && instance.$init(isPage, options);
}
/**
* Clear the base class cache
*/
export function clearBaseCache() {
pluginCache = {
usedExtensions: {},
installedPlugins: [],
baseClasses: {}
};
}
/**
* Use the given plugin
*
* @param {Object} plugin the plugin definition
* {
* init(pluginOpts) {}, // plugin init api
* app: {}, // the app extension
* component: {}, // the component extension
* page: {}, // the page extension
* }
* @param {Object} pluginOpts the plugin options
* @return {boolean} return true if install successfully
*/
export function use(plugin, pluginOpts) {
let cache = pluginCache;
// for quick app, should using global cache to avoid the cache missing
if (process.env.APP_TYPE === 'quick' && !appGlobal.okamPluginCache) {
appGlobal.okamPluginCache = pluginCache;
}
if (cache.installedPlugins.indexOf(plugin) > -1) {
return false;
}
typeof plugin.init === 'function'
&& plugin.init(pluginOpts);
let {component, page, app} = plugin;
if (component) {
addExtension(COMPONENT_TYPE, component);
addExtension(PAGE_TYPE, component);
}
addExtension(PAGE_TYPE, page);
addExtension(APP_TYPE, app);
cache.installedPlugins.push(plugin);
return true;
}
/**
* Create App instance
*
* @param {Object} instance the instance to init app
* @param {Object} base the app base
* @param {Object=} options the extra init options
* @return {Object}
*/
export function createApp(instance, base, options) {
let appInfo = initExtensions(APP_TYPE, instance, base);
options && (appInfo.$appOptions = () => options);
return appInfo;
}
/**
* Create page instance
*
* @param {Object} instance the instance to init page
* @param {Object} base the page base
* @param {Function} normalize used to normalize the page definition
* @param {Object=} options the extra init options
* @param {Object=} options.refs the component reference used in the component, the
* reference information is defined in the template
* @return {Object}
*/
export function createPage(instance, base, normalize, options) {
let pageInfo = initExtensions(PAGE_TYPE, instance, base);
initComponentData(pageInfo, options, true);
normalize && (pageInfo = normalize(pageInfo));
return pageInfo;
}
/**
* Create component instance
*
* @param {Object} instance the instance to init component
* @param {Object} base the component base
* @param {Function} normalize used to normalize the component definition
* @param {Object=} options the extra init options
* @param {Object=} options.refs the component reference used in the component, the
* reference information is defined in the template
* @return {Object}
*/
export function createComponent(instance, base, normalize, options) {
let componentInfo = initExtensions(COMPONENT_TYPE, instance, base);
componentInfo.props = normalizeOkamProps(componentInfo.props);
initComponentData(componentInfo, options, false);
normalize && (componentInfo = normalize(componentInfo));
return componentInfo;
}