mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-07-31 04:20:26 +02:00
first stab at plugin rendering (#629)
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
"immutable": "^3.8.1",
|
"immutable": "^3.8.1",
|
||||||
"is-empty": "^1.0.0",
|
"is-empty": "^1.0.0",
|
||||||
"keycode": "^2.1.2",
|
"keycode": "^2.1.2",
|
||||||
|
"react-portal": "^3.0.0",
|
||||||
"type-of": "^2.0.1"
|
"type-of": "^2.0.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
@@ -59,7 +60,6 @@
|
|||||||
"react-dom": "^15.4.2",
|
"react-dom": "^15.4.2",
|
||||||
"react-frame-aware-selection-plugin": "^1.0.0",
|
"react-frame-aware-selection-plugin": "^1.0.0",
|
||||||
"react-frame-component": "^0.6.2",
|
"react-frame-component": "^0.6.2",
|
||||||
"react-portal": "^3.0.0",
|
|
||||||
"react-router": "^2.5.1",
|
"react-router": "^2.5.1",
|
||||||
"read-metadata": "^1.0.0",
|
"read-metadata": "^1.0.0",
|
||||||
"read-yaml-promise": "^1.0.2",
|
"read-yaml-promise": "^1.0.2",
|
||||||
|
@@ -36,6 +36,7 @@ class Content extends React.Component {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
autoCorrect: React.PropTypes.bool.isRequired,
|
autoCorrect: React.PropTypes.bool.isRequired,
|
||||||
|
children: React.PropTypes.object.isRequired,
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
editor: React.PropTypes.object.isRequired,
|
editor: React.PropTypes.object.isRequired,
|
||||||
onBeforeInput: React.PropTypes.func.isRequired,
|
onBeforeInput: React.PropTypes.func.isRequired,
|
||||||
@@ -755,6 +756,7 @@ class Content extends React.Component {
|
|||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import Content from './content'
|
import Content from './content'
|
||||||
import Debug from 'debug'
|
import Debug from 'debug'
|
||||||
|
import Portal from 'react-portal'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Stack from '../models/stack'
|
import Stack from '../models/stack'
|
||||||
import State from '../models/state'
|
import State from '../models/state'
|
||||||
@@ -238,7 +239,9 @@ class Editor extends React.Component {
|
|||||||
|
|
||||||
render = () => {
|
render = () => {
|
||||||
const { props, state } = this
|
const { props, state } = this
|
||||||
|
const { stack } = state
|
||||||
const handlers = {}
|
const handlers = {}
|
||||||
|
const children = stack.render(state.state, this)
|
||||||
|
|
||||||
for (const property of EVENT_HANDLERS) {
|
for (const property of EVENT_HANDLERS) {
|
||||||
handlers[property] = this[property]
|
handlers[property] = this[property]
|
||||||
@@ -260,7 +263,9 @@ class Editor extends React.Component {
|
|||||||
style={props.style}
|
style={props.style}
|
||||||
tabIndex={props.tabIndex}
|
tabIndex={props.tabIndex}
|
||||||
role={props.role}
|
role={props.role}
|
||||||
/>
|
>
|
||||||
|
{children.map((child, i) => <Portal key={i} isOpened>{child}</Portal>)}
|
||||||
|
</Content>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ const debug = Debug('slate:stack')
|
|||||||
* @type {Array}
|
* @type {Array}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const EVENT_METHODS = [
|
const EVENT_HANDLER_METHODS = [
|
||||||
'onBeforeInput',
|
'onBeforeInput',
|
||||||
'onBlur',
|
'onBlur',
|
||||||
'onCopy',
|
'onCopy',
|
||||||
@@ -36,20 +36,20 @@ const EVENT_METHODS = [
|
|||||||
* @type {Array}
|
* @type {Array}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ACCUMULATOR_METHODS = [
|
const STATE_ACCUMULATOR_METHODS = [
|
||||||
'onBeforeChange',
|
'onBeforeChange',
|
||||||
'onChange',
|
'onChange',
|
||||||
]
|
]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All the runnable methods.
|
* Methods that accumulate an array.
|
||||||
*
|
*
|
||||||
* @type {Array}
|
* @type {Array}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const RUNNABLE_METHODS = []
|
const ARRAY_ACCUMULATOR_METHODS = [
|
||||||
.concat(EVENT_METHODS)
|
'render'
|
||||||
.concat(ACCUMULATOR_METHODS)
|
]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default properties.
|
* Default properties.
|
||||||
@@ -95,17 +95,19 @@ class Stack extends new Record(DEFAULTS) {
|
|||||||
return 'stack'
|
return 'stack'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
}
|
||||||
* Run a `method` in the stack with `state`.
|
|
||||||
*
|
|
||||||
* @param {String} method
|
|
||||||
* @param {State} state
|
|
||||||
* @param {Editor} editor
|
|
||||||
* @param {Mixed} ...args
|
|
||||||
* @return {State}
|
|
||||||
*/
|
|
||||||
|
|
||||||
run(method, state, editor, ...args) {
|
/**
|
||||||
|
* Mix in the event handler methods.
|
||||||
|
*
|
||||||
|
* @param {State} state
|
||||||
|
* @param {Editor} editor
|
||||||
|
* @param {Mixed} ...args
|
||||||
|
* @return {State|Null}
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (const method of EVENT_HANDLER_METHODS) {
|
||||||
|
Stack.prototype[method] = function (state, editor, ...args) {
|
||||||
debug(method)
|
debug(method)
|
||||||
|
|
||||||
if (method == 'onChange') {
|
if (method == 'onChange') {
|
||||||
@@ -115,32 +117,76 @@ class Stack extends new Record(DEFAULTS) {
|
|||||||
for (const plugin of this.plugins) {
|
for (const plugin of this.plugins) {
|
||||||
if (!plugin[method]) continue
|
if (!plugin[method]) continue
|
||||||
const next = plugin[method](...args, state, editor)
|
const next = plugin[method](...args, state, editor)
|
||||||
|
if (next == null) continue
|
||||||
if (next == null) {
|
assertState(next)
|
||||||
continue
|
return next
|
||||||
} else if (next instanceof State) {
|
|
||||||
state = next
|
|
||||||
if (!ACCUMULATOR_METHODS.includes(method)) break
|
|
||||||
} else {
|
|
||||||
throw new Error(`A plugin returned an unexpected state value: ${next}`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mix in the runnable methods.
|
* Mix in the state accumulator methods.
|
||||||
|
*
|
||||||
|
* @param {State} state
|
||||||
|
* @param {Editor} editor
|
||||||
|
* @param {Mixed} ...args
|
||||||
|
* @return {State|Null}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (const method of RUNNABLE_METHODS) {
|
for (const method of STATE_ACCUMULATOR_METHODS) {
|
||||||
Stack.prototype[method] = function (...args) {
|
Stack.prototype[method] = function (state, editor, ...args) {
|
||||||
return this.run(method, ...args)
|
debug(method)
|
||||||
|
|
||||||
|
for (const plugin of this.plugins) {
|
||||||
|
if (!plugin[method]) continue
|
||||||
|
const next = plugin[method](...args, state, editor)
|
||||||
|
if (next == null) continue
|
||||||
|
assertState(next)
|
||||||
|
state = next
|
||||||
|
}
|
||||||
|
|
||||||
|
return state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mix in the array accumulator methods.
|
||||||
|
*
|
||||||
|
* @param {State} state
|
||||||
|
* @param {Editor} editor
|
||||||
|
* @param {Mixed} ...args
|
||||||
|
* @return {Array}
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (const method of ARRAY_ACCUMULATOR_METHODS) {
|
||||||
|
Stack.prototype[method] = function (state, editor, ...args) {
|
||||||
|
debug(method)
|
||||||
|
const array = []
|
||||||
|
|
||||||
|
for (const plugin of this.plugins) {
|
||||||
|
if (!plugin[method]) continue
|
||||||
|
const next = plugin[method](...args, state, editor)
|
||||||
|
if (next == null) continue
|
||||||
|
array.push(next)
|
||||||
|
}
|
||||||
|
|
||||||
|
return array
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert that a `value` is a state object.
|
||||||
|
*
|
||||||
|
* @param {Mixed} value
|
||||||
|
*/
|
||||||
|
|
||||||
|
function assertState(value) {
|
||||||
|
if (value instanceof State) return
|
||||||
|
throw new Error(`A plugin returned an unexpected state value: ${value}`)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve a schema from a set of `plugins`.
|
* Resolve a schema from a set of `plugins`.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user