Pass plugins via context instead of using Redux store

This commit is contained in:
Cássio Zen 2016-08-18 09:09:54 -03:00
parent d22a4da057
commit 986e36c137
4 changed files with 58 additions and 48 deletions

View File

@ -1,5 +1,4 @@
export const SWITCH_VISUAL_MODE = 'SWITCH_VISUAL_MODE'; export const SWITCH_VISUAL_MODE = 'SWITCH_VISUAL_MODE';
export const REGISTER_COMPONENT = 'REGISTER_COMPONENT';
export function switchVisualMode(useVisualMode) { export function switchVisualMode(useVisualMode) {
return { return {
@ -7,10 +6,3 @@ export function switchVisualMode(useVisualMode) {
payload: useVisualMode payload: useVisualMode
}; };
} }
export function registerComponent(options) {
return {
type: REGISTER_COMPONENT,
payload: options
};
}

View File

@ -14,7 +14,7 @@ const store = configureStore();
// Create an enhanced history that syncs navigation events with the store // Create an enhanced history that syncs navigation events with the store
syncHistory(store); syncHistory(store);
initPluginAPI(store); const Plugin = initPluginAPI();
const el = document.createElement('div'); const el = document.createElement('div');
el.id = 'root'; el.id = 'root';
@ -22,8 +22,10 @@ document.body.appendChild(el);
render(( render((
<Provider store={store}> <Provider store={store}>
<Router history={history}> <Plugin>
{routes} <Router history={history}>
</Router> {routes}
</Router>
</Plugin>
</Provider> </Provider>
), el); ), el);

View File

@ -1,40 +1,58 @@
import { registerComponent } from '../actions/editor'; import { Component, PropTypes, Children } from 'react';
import { List, Record } from 'immutable';
import _ from 'lodash';
let storeRef; const plugins = { editor: List() };
const requiredEditorComponentProperties = ['label', 'fields', 'detect', 'fromBlock', 'toBlock'];
const checkConfigKeys = (config, requiredProps) => { const catchesNothing = /.^/;
for (var i = requiredProps.length; i--;) { const EditorComponent = Record({
if (!config.hasOwnProperty(requiredProps[i])) return false; id: null,
} label: 'unnamed component',
return true; icon: 'exclamation-triangle',
}; fields: [],
pattern: catchesNothing,
const wrap = (func) => function() { fromBlock: function(match) { return {}; },
func.apply(null, arguments); toBlock: function(attributes) { return 'Plugin'; },
}; toPreview: function(attributes) { return 'Plugin'; }
});
function CMS() { function CMS() {
this.registerEditorComponent = (config) => { this.registerEditorComponent = (config) => {
if (checkConfigKeys(config, requiredEditorComponentProperties)) { const configObj = new EditorComponent({
const configObj = { id: config.id || config.label.replace(/[^A-Z0-9]+/ig, '_'),
label: config.label || 'unnamed', label: config.label,
icon: config.icon || 'exclamation-triangle', icon: config.icon,
fields: config.fields, fields: config.fields,
detect: wrap(config.detect), pattern: config.pattern,
fromBlock: wrap(config.fromBlock), fromBlock: _.isFunction(config.fromBlock) ? config.fromBlock.bind(null) : null,
toBlock: wrap(config.toBlock), toBlock: _.isFunction(config.toBlock) ? config.toBlock.bind(null) : null,
toPreview: config.toPreview ? wrap(config.toPreview) : wrap(config.toBlock) toPreview: _.isFunction(config.toPreview) ? config.toPreview.bind(null) : config.toBlock.bind(null)
}; });
storeRef.dispatch(registerComponent(configObj));
} else { plugins.editor = plugins.editor.push(configObj);
const label = config.label || 'unnamed';
window.console && console.error(`The provided component configuration for ${label} is incorrect.`);
}
}; };
} }
export const initPluginAPI = (store) => {
storeRef = store; class Plugin extends Component {
window.CMS = new CMS(); getChildContext() {
return { plugins: plugins };
}
render() {
return Children.only(this.props.children);
}
}
Plugin.propTypes = {
children: PropTypes.element.isRequired
};
Plugin.childContextTypes = {
plugins: PropTypes.object
};
export const initPluginAPI = () => {
window.CMS = new CMS();
return Plugin;
}; };

View File

@ -1,12 +1,10 @@
import { Map, List } from 'immutable'; import { Map } from 'immutable';
import { SWITCH_VISUAL_MODE, REGISTER_COMPONENT } from '../actions/editor'; import { SWITCH_VISUAL_MODE } from '../actions/editor';
const editor = (state = Map({ useVisualMode: true, registeredComponents: List() }), action) => { const editor = (state = Map({ useVisualMode: true }), action) => {
switch (action.type) { switch (action.type) {
case SWITCH_VISUAL_MODE: case SWITCH_VISUAL_MODE:
return state.setIn(['useVisualMode'], action.payload); return state.setIn(['useVisualMode'], action.payload);
case REGISTER_COMPONENT:
return state.updateIn(['registeredComponents'], list => list.push(action.payload));
default: default:
return state; return state;
} }