From fe91b4c76eb99b157ff2be22b9218050af6131aa Mon Sep 17 00:00:00 2001 From: Martin Ek Date: Sat, 8 Oct 2016 17:38:47 -0400 Subject: [PATCH] Refactor plugin retrieval (#695) * plugins: refactor props decorators * plugins: add missing plugin functions to notifier * plugins: refactor reducer decorators * bug: make sure reduceTermGroups are added from plugins --- app/plugins.js | 13 +++- lib/utils/plugins.js | 180 +++++++++++-------------------------------- 2 files changed, 54 insertions(+), 139 deletions(-) diff --git a/app/plugins.js b/app/plugins.js index 9d39df47..70fc925a 100644 --- a/app/plugins.js +++ b/app/plugins.js @@ -20,11 +20,18 @@ const path = resolve(homedir(), '.hyper_plugins'); const localPath = resolve(homedir(), '.hyper_plugins', 'local'); const availableExtensions = new Set([ 'onApp', 'onWindow', 'onUnload', 'middleware', - 'reduceUI', 'reduceSessions', 'decorateMenu', - 'decorateTerm', 'decorateHyper', 'decorateTab', + 'reduceUI', 'reduceSessions', 'reduceTermGroups', + 'decorateMenu', 'decorateTerm', 'decorateHyper', 'decorateHyperTerm', // for backwards compatibility with hyperterm + 'decorateTab', 'decorateNotification', 'decorateNotifications', - 'decorateTabs', 'decorateConfig', 'decorateEnv' + 'decorateTabs', 'decorateConfig', 'decorateEnv', + 'decorateTermGroup', 'getTermProps', + 'getTabProps', 'getTabsProps', 'getTermGroupProps', + 'mapHyperTermState', 'mapTermsState', + 'mapHeaderState', 'mapNotificationsState', + 'mapHyperTermDispatch', 'mapTermsDispatch', + 'mapHeaderDispatch', 'mapNotificationsDispatch' ]); // init plugin directories if not present diff --git a/lib/utils/plugins.js b/lib/utils/plugins.js index a31db75f..b0a76b9d 100644 --- a/lib/utils/plugins.js +++ b/lib/utils/plugins.js @@ -35,6 +35,8 @@ let tabPropsDecorators; let tabsPropsDecorators; let termPropsDecorators; let termGroupPropsDecorators; +let propsDecorators; +let reducersDecorators; // the fs locations where usr plugins are stored const {path, localPath} = plugins.getBasePaths(); @@ -78,6 +80,19 @@ const loadModules = () => { termPropsDecorators = []; termGroupPropsDecorators = []; + propsDecorators = { + getTermProps: termPropsDecorators, + getTabProps: tabPropsDecorators, + getTabsProps: tabsPropsDecorators, + getTermGroupProps: termGroupPropsDecorators + }; + + reducersDecorators = { + reduceUI: uiReducers, + reduceSessions: sessionsReducers, + reduceTermGroups: termGroupsReducers + }; + modules = paths.plugins.concat(paths.localPlugins) .map(path => { let mod; @@ -123,6 +138,10 @@ const loadModules = () => { sessionsReducers.push(mod.reduceSessions); } + if (mod.reduceTermGroups) { + termGroupsReducers.push(mod.reduceTermGroups); + } + if (mod.mapTermsState) { connectors.Terms.state.push(mod.mapTermsState); } @@ -191,10 +210,11 @@ export function reload() { decorated = {}; } -export function getTermGroupProps(uid, parentProps, props) { +function getProps(name, props, ...fnArgs) { + const decorators = propsDecorators[name]; let props_; - termPropsDecorators.forEach(fn => { + decorators.forEach(fn => { let ret_; if (!props_) { @@ -202,109 +222,38 @@ export function getTermGroupProps(uid, parentProps, props) { } try { - ret_ = fn(uid, parentProps, props_); + ret_ = fn(...fnArgs, props_); } catch (err) { console.error(err.stack); - notify('Plugin error', `${fn._pluginName}: Error occurred in \`getTermGroupProps\`. Check Developer Tools for details.`); + notify('Plugin error', `${fn._pluginName}: Error occurred in \`${name}\`. Check Developer Tools for details.`); return; } if (!ret_ || typeof ret_ !== 'object') { - notify('Plugin error', `${fn._pluginName}: Invalid return value of \`getTermGroupProps\` (object expected).`); + notify('Plugin error', `${fn._pluginName}: Invalid return value of \`${name}\` (object expected).`); return; } - props = ret_; + props_ = ret_; }); return props_ || props; } +export function getTermGroupProps(uid, parentProps, props) { + return getProps('getTermGroupProps', props, uid, parentProps); +} + export function getTermProps(uid, parentProps, props) { - let props_; - - termPropsDecorators.forEach(fn => { - let ret_; - - if (!props_) { - props_ = Object.assign({}, props); - } - - try { - ret_ = fn(uid, parentProps, props_); - } catch (err) { - console.error(err.stack); - notify('Plugin error', `${fn._pluginName}: Error occurred in \`getTermProps\`. Check Developer Tools for details.`); - return; - } - - if (!ret_ || typeof ret_ !== 'object') { - notify('Plugin error', `${fn._pluginName}: Invalid return value of \`getTermProps\` (object expected).`); - return; - } - - props = ret_; - }); - - return props_ || props; + return getProps('getTermProps', props, uid, parentProps); } export function getTabsProps(parentProps, props) { - let props_; - - tabsPropsDecorators.forEach(fn => { - let ret_; - - if (!props_) { - props_ = Object.assign({}, props); - } - - try { - ret_ = fn(parentProps, props_); - } catch (err) { - console.error(err.stack); - notify('Plugin error', `${fn._pluginName}: Error occurred in \`getTabsProps\`. Check Developer Tools for details.`); - return; - } - - if (!ret_ || typeof ret_ !== 'object') { - notify('Plugin error', `${fn._pluginName}: Invalid return value of \`getTabsProps\` (object expected).`); - return; - } - - props_ = ret_; - }); - - return props_ || props; + return getProps('getTabsProps', props, parentProps); } export function getTabProps(tab, parentProps, props) { - let props_; - - tabPropsDecorators.forEach(fn => { - let ret_; - - if (!props_) { - props_ = Object.assign({}, props); - } - - try { - ret_ = fn(tab, parentProps, props_); - } catch (err) { - console.error(err.stack); - notify('Plugin error', `${fn._pluginName}: Error occurred in \`getTabProps\`. Check Developer Tools for details.`); - return; - } - - if (!ret_ || typeof ret_ !== 'object') { - notify('Plugin error', `${fn._pluginName}: Invalid return value of \`getTabProps\` (object expected).`); - return; - } - - props_ = ret_; - }); - - return props_ || props; + return getProps('getTabProps', props, tab, parentProps); } // connects + decorates a class @@ -363,23 +312,24 @@ export function connect(stateFn, dispatchFn, c, d = {}) { }; } -export function decorateTermGroupsReducer(fn) { +function decorateReducer(name, fn) { + const reducers = reducersDecorators[name]; return (state, action) => { let state_ = fn(state, action); - termGroupsReducers.forEach(pluginReducer => { + reducers.forEach(pluginReducer => { let state__; try { state__ = pluginReducer(state_, action); } catch (err) { console.error(err.stack); - notify('Plugin error', `${fn._pluginName}: Error occurred in \`reduceTermGroups\`. Check Developer Tools for details.`); + notify('Plugin error', `${fn._pluginName}: Error occurred in \`${name}\`. Check Developer Tools for details.`); return; } if (!state__ || typeof state__ !== 'object') { - notify('Plugin error', `${fn._pluginName}: Invalid return value of \`reduceTermGroups\`.`); + notify('Plugin error', `${fn._pluginName}: Invalid return value of \`${name}\`.`); return; } @@ -390,58 +340,16 @@ export function decorateTermGroupsReducer(fn) { }; } +export function decorateTermGroupsReducer(fn) { + return decorateReducer('reduceTermGroups', fn); +} + export function decorateUIReducer(fn) { - return (state, action) => { - let state_ = fn(state, action); - - uiReducers.forEach(pluginReducer => { - let state__; - - try { - state__ = pluginReducer(state_, action); - } catch (err) { - console.error(err.stack); - notify('Plugin error', `${fn._pluginName}: Error occurred in \`reduceUI\`. Check Developer Tools for details.`); - return; - } - - if (!state__ || typeof state__ !== 'object') { - notify('Plugin error', `${fn._pluginName}: Invalid return value of \`reduceUI\`.`); - return; - } - - state_ = state__; - }); - - return state_; - }; + return decorateReducer('reduceUI', fn); } export function decorateSessionsReducer(fn) { - return (state, action) => { - let state_ = fn(state, action); - - sessionsReducers.forEach(pluginReducer => { - let state__; - - try { - state__ = pluginReducer(state_, action); - } catch (err) { - console.error(err.stack); - notify('Plugin error', `${fn._pluginName}: Error occurred in \`reduceSessions\`. Check Developer Tools for details.`); - return; - } - - if (!state__ || typeof state__ !== 'object') { - notify('Plugin error', `${fn._pluginName}: Invalid return value of \`reduceSessions\`.`); - return; - } - - state_ = state__; - }); - - return state_; - }; + return decorateReducer('reduceSessions', fn); } // redux middleware generator