plugin architecture

This commit is contained in:
Cássio Zen 2016-08-17 09:52:17 -03:00
parent dea734ec21
commit a0a24ebf72
5 changed files with 59 additions and 7 deletions

View File

@ -74,11 +74,11 @@
"json-loader": "^0.5.4",
"localforage": "^1.4.2",
"lodash": "^4.13.1",
"markup-it": "git+https://github.com/cassiozen/markup-it.git",
"markup-it": "git+https://github.com/GitbookIO/markup-it.git",
"pluralize": "^3.0.0",
"prismjs": "^1.5.1",
"react-portal": "^2.2.1",
"selection-position": "^1.0.0",
"slate": "^0.12.2"
"slate": "^0.13.5"
}
}

View File

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

View File

@ -5,6 +5,7 @@ import { Router } from 'react-router';
import configureStore from './store/configureStore';
import routes from './routing/routes';
import history, { syncHistory } from './routing/history';
import { initPluginAPI } from './plugins';
import 'file?name=index.html!../example/index.html';
import './index.css';
@ -13,6 +14,8 @@ const store = configureStore();
// Create an enhanced history that syncs navigation events with the store
syncHistory(store);
initPluginAPI(store);
const el = document.createElement('div');
el.id = 'root';
document.body.appendChild(el);

40
src/plugins/index.js Normal file
View File

@ -0,0 +1,40 @@
import { registerComponent } from '../actions/editor';
let storeRef;
const requiredEditorComponentProperties = ['label', 'fields', 'detect', 'fromBlock', 'toBlock'];
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);
};
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.`);
}
};
}
export const initPluginAPI = (store) => {
storeRef = store;
window.CMS = new CMS();
};

View File

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