Pass plugins via context instead of using Redux store
This commit is contained in:
parent
d22a4da057
commit
986e36c137
@ -1,5 +1,4 @@
|
||||
export const SWITCH_VISUAL_MODE = 'SWITCH_VISUAL_MODE';
|
||||
export const REGISTER_COMPONENT = 'REGISTER_COMPONENT';
|
||||
|
||||
export function switchVisualMode(useVisualMode) {
|
||||
return {
|
||||
@ -7,10 +6,3 @@ export function switchVisualMode(useVisualMode) {
|
||||
payload: useVisualMode
|
||||
};
|
||||
}
|
||||
|
||||
export function registerComponent(options) {
|
||||
return {
|
||||
type: REGISTER_COMPONENT,
|
||||
payload: options
|
||||
};
|
||||
}
|
||||
|
10
src/index.js
10
src/index.js
@ -14,7 +14,7 @@ const store = configureStore();
|
||||
// Create an enhanced history that syncs navigation events with the store
|
||||
syncHistory(store);
|
||||
|
||||
initPluginAPI(store);
|
||||
const Plugin = initPluginAPI();
|
||||
|
||||
const el = document.createElement('div');
|
||||
el.id = 'root';
|
||||
@ -22,8 +22,10 @@ document.body.appendChild(el);
|
||||
|
||||
render((
|
||||
<Provider store={store}>
|
||||
<Router history={history}>
|
||||
{routes}
|
||||
</Router>
|
||||
<Plugin>
|
||||
<Router history={history}>
|
||||
{routes}
|
||||
</Router>
|
||||
</Plugin>
|
||||
</Provider>
|
||||
), el);
|
||||
|
@ -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 requiredEditorComponentProperties = ['label', 'fields', 'detect', 'fromBlock', 'toBlock'];
|
||||
const plugins = { editor: List() };
|
||||
|
||||
const checkConfigKeys = (config, requiredProps) => {
|
||||
for (var i = requiredProps.length; i--;) {
|
||||
if (!config.hasOwnProperty(requiredProps[i])) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const wrap = (func) => function() {
|
||||
func.apply(null, arguments);
|
||||
};
|
||||
const catchesNothing = /.^/;
|
||||
const EditorComponent = Record({
|
||||
id: null,
|
||||
label: 'unnamed component',
|
||||
icon: 'exclamation-triangle',
|
||||
fields: [],
|
||||
pattern: catchesNothing,
|
||||
fromBlock: function(match) { return {}; },
|
||||
toBlock: function(attributes) { return 'Plugin'; },
|
||||
toPreview: function(attributes) { return 'Plugin'; }
|
||||
});
|
||||
|
||||
function CMS() {
|
||||
this.registerEditorComponent = (config) => {
|
||||
if (checkConfigKeys(config, requiredEditorComponentProperties)) {
|
||||
const configObj = {
|
||||
label: config.label || 'unnamed',
|
||||
icon: config.icon || 'exclamation-triangle',
|
||||
fields: config.fields,
|
||||
detect: wrap(config.detect),
|
||||
fromBlock: wrap(config.fromBlock),
|
||||
toBlock: wrap(config.toBlock),
|
||||
toPreview: config.toPreview ? wrap(config.toPreview) : wrap(config.toBlock)
|
||||
};
|
||||
storeRef.dispatch(registerComponent(configObj));
|
||||
} else {
|
||||
const label = config.label || 'unnamed';
|
||||
window.console && console.error(`The provided component configuration for ${label} is incorrect.`);
|
||||
}
|
||||
const configObj = new EditorComponent({
|
||||
id: config.id || config.label.replace(/[^A-Z0-9]+/ig, '_'),
|
||||
label: config.label,
|
||||
icon: config.icon,
|
||||
fields: config.fields,
|
||||
pattern: config.pattern,
|
||||
fromBlock: _.isFunction(config.fromBlock) ? config.fromBlock.bind(null) : null,
|
||||
toBlock: _.isFunction(config.toBlock) ? config.toBlock.bind(null) : null,
|
||||
toPreview: _.isFunction(config.toPreview) ? config.toPreview.bind(null) : config.toBlock.bind(null)
|
||||
});
|
||||
|
||||
plugins.editor = plugins.editor.push(configObj);
|
||||
};
|
||||
}
|
||||
|
||||
export const initPluginAPI = (store) => {
|
||||
storeRef = store;
|
||||
window.CMS = new CMS();
|
||||
|
||||
class Plugin extends Component {
|
||||
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;
|
||||
};
|
||||
|
@ -1,12 +1,10 @@
|
||||
import { Map, List } from 'immutable';
|
||||
import { SWITCH_VISUAL_MODE, REGISTER_COMPONENT } from '../actions/editor';
|
||||
import { Map } from 'immutable';
|
||||
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) {
|
||||
case SWITCH_VISUAL_MODE:
|
||||
return state.setIn(['useVisualMode'], action.payload);
|
||||
case REGISTER_COMPONENT:
|
||||
return state.updateIn(['registeredComponents'], list => list.push(action.payload));
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user