1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-22 15:02:51 +02:00

Add handler "onBeforeChange" (#219)

* Add handler "onReceiveState"

* Change onReceiveChange to onBeforeChange and call it before onChange as well

* Dont'call props.onBeforeChange since it's added to CorePlugin

* Update documentation for onBeforeChange
This commit is contained in:
Samy Pessé
2016-08-04 22:11:23 +02:00
committed by Ian Storm Taylor
parent 2d63957246
commit f25c5d9a64
3 changed files with 44 additions and 11 deletions

View File

@@ -23,7 +23,7 @@ When the editor needs to resolve a plugin-related handler, it will loop through
- [`renderNode`](#rendernode)
- [Other Properties](#other-properties)
- [`onChange`](#onchange)
- [`onBeforeChange`](#onbeforechange)
## Conventions
@@ -293,3 +293,10 @@ The `onChange` handler isn't a native browser event handler. Instead, it is invo
Unlike the native event handlers, results from the `onChange` handler **are cummulative**! This means that every plugin in the stack that defines an `onChange` handler will have its handler resolved for every change the editor makes; the editor will not return early after the first plugin's handler is called.
This allows you to stack up changes across the entire plugin stack.
### `onBeforeChange`
`Function onBeforeChange(state: State) => State || Void`
The `onBeforeChange` handler isn't a native browser event handler. Instead, it is invoked whenever the editor receives a new state and before propagating a new state to `onChange`. Returning a new state will update the editor's state before rendering, continuing down the plugin stack.
Like `onChange`, `onBeforeChange` is cummulative.

View File

@@ -51,6 +51,7 @@ class Editor extends React.Component {
static propTypes = {
className: React.PropTypes.string,
onBeforeChange: React.PropTypes.func,
onChange: React.PropTypes.func.isRequired,
onDocumentChange: React.PropTypes.func,
onSelectionChange: React.PropTypes.func,
@@ -90,7 +91,7 @@ class Editor extends React.Component {
this.tmp = {}
this.state = {}
this.state.plugins = this.resolvePlugins(props)
this.state.state = props.state
this.state.state = this.onBeforeChange(props.state)
// Mix in the event handlers.
for (const method of EVENT_HANDLERS) {
@@ -107,7 +108,7 @@ class Editor extends React.Component {
*/
componentWillReceiveProps = (props) => {
this.state.state = props.state
this.state.state = this.onBeforeChange(props.state)
if (props.plugins != this.props.plugins) {
this.setState({ plugins: this.resolvePlugins(props) })
@@ -159,6 +160,8 @@ class Editor extends React.Component {
onChange = (state) => {
if (state == this.state.state) return
state = this.onBeforeChange(state)
for (const plugin of this.state.plugins) {
if (!plugin.onChange) continue
const newState = plugin.onChange(state, this)
@@ -179,6 +182,26 @@ class Editor extends React.Component {
}
}
/**
* When the editor receives a new 'state'
*
* @param {State} state
* @return {State} newState
*/
onBeforeChange = (state) => {
if (state == this.state.state) return
for (const plugin of this.state.plugins) {
if (!plugin.onBeforeChange) continue
const newState = plugin.onBeforeChange(state, this)
if (newState == null) continue
state = newState
}
return state
}
/**
* When an event by `name` fires, pass it through the plugins, and update the
* state if one of them chooses to.

View File

@@ -21,6 +21,7 @@ const debug = Debug('slate:core')
* @property {Element} placeholder
* @property {String} placeholderClassName
* @property {Object} placeholderStyle
* @property {Function} onBeforeChange
* @return {Object}
*/
@@ -28,7 +29,8 @@ function Plugin(options = {}) {
const {
placeholder,
placeholderClassName,
placeholderStyle
placeholderStyle,
onBeforeChange
} = options
/**
@@ -612,6 +614,7 @@ function Plugin(options = {}) {
*/
return {
onBeforeChange,
onBeforeInput,
onBlur,
onCopy,