1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-02-24 01:02:31 +01:00

223 lines
8.8 KiB
Markdown
Raw Normal View History

2016-07-12 10:33:35 -07:00
2016-07-12 10:36:55 -07:00
# Plugins
2016-07-12 10:33:35 -07:00
Plugins can be attached to an editor to alter its behavior in different ways. Plugins are just simple Javascript objects, containing a set of properties that control different behaviors—event handling, change handling, rendering, etc.
Each editor has a "middleware stack" of plugins, which has a specific order.
When the editor needs to resolve a plugin-related handler, it will loop through its plugin stack, searching for the first plugin that successfully returns a value. After receiving that value, the editor will **not** continue to search the remaining plugins; it returns early.
- [Conventions](#conventions)
2016-07-12 11:20:14 -07:00
- [Event Handler Properties](#event-handle-properties)
- [`onBeforeInput`](#onbeforeinput)
2016-07-27 22:45:25 -07:00
- [`onBlur`](#onblur)
- [`onCopy`](#oncopy)
- [`onCut`](#oncut)
2016-07-22 17:15:46 -07:00
- [`onDrop`](#ondrop)
2016-07-12 11:20:14 -07:00
- [`onKeyDown`](#onkeydown)
- [`onPaste`](#onpaste)
2016-07-27 22:45:25 -07:00
- [`onSelect`](#onselect)
2016-07-12 10:33:35 -07:00
- [Other Properties](#other-properties)
2016-07-12 11:20:14 -07:00
- [`onChange`](#onchange)
- [`onBeforeChange`](#onbeforechange)
2016-08-14 15:58:41 -07:00
- [`schema`](#schema)
2016-07-12 10:33:35 -07:00
2016-08-14 14:38:27 -07:00
2016-07-12 10:33:35 -07:00
## Conventions
A plugin should always export a function that takes options. This way even if it doesn't take any options now, it won't be a breaking API change to take more options in the future. So a basic plugin might look like this:
```js
export default MySlatePlugin(options) {
return {
// Return properties that describe your logic here...
}
}
```
## Event Handler Properties
```js
{
onBeforeInput: Function,
2016-07-27 22:45:25 -07:00
onBlur: Function,
onCopy: Function,
onCut: Function,
2016-07-22 17:15:46 -07:00
onDrop: Function,
2016-07-12 10:33:35 -07:00
onKeyDown: Function,
2016-07-27 22:45:25 -07:00
onPaste: Function,
onSelect: Function
2016-07-12 10:33:35 -07:00
}
```
2016-07-27 22:45:25 -07:00
All of the event handler properties are passed the same React `event` object you are used to from React's event handlers. They are also passed a `data` object with Slate-specific information relating to the event, the current `state` of the editor, and the `editor` instance itself.
2016-07-12 10:36:55 -07:00
Each event handler can choose to return a new `state` object, in which case the editor's state will be updated. If nothing is returned, the editor will simply continue resolving the plugin stack.
### `onBeforeInput`
2016-07-27 22:45:25 -07:00
`Function onBeforeInput(event: Event, data: Object, state: State, editor: Editor) => State || Void`
2016-07-12 10:33:35 -07:00
2016-07-27 22:45:25 -07:00
This handler is called right before a string of text is inserted into the `contenteditable` element.
2016-07-12 10:33:35 -07:00
2016-07-12 10:36:55 -07:00
Make sure to `event.preventDefault()` if you do not want the default insertion behavior to occur! If no other plugin handles this event, it will be handled by the [Core plugin](./core.md).
2016-07-12 10:33:35 -07:00
2016-07-27 22:45:25 -07:00
### `onBlur`
`Function onBlur(event: Event, data: Object, state: State, editor: Editor) => State || Void`
This handler is called when the editor's `contenteditable` element is blurred.
If no other plugin handles this event, it will be handled by the [Core plugin](./core.md).
### `onCopy`
`Function onCopy(event: Event, data: Object, state: State, editor: Editor) => State || Void`
This handler is called when the editor's `contenteditable` element is blurred.
The `data` object contains a `type` string and associated data for that type. Right now the only type supported is `"fragment"`:
```js
{
type: 'fragment',
fragment: Document
}
```
If no other plugin handles this event, it will be handled by the [Core plugin](./core.md).
### `onCut`
`Function onCut(event: Event, data: Object, state: State, editor: Editor) => State || Void`
This handler is equivalent to the `onCopy` handler.
If no other plugin handles this event, it will be handled by the [Core plugin](./core.md).
2016-07-22 17:15:46 -07:00
### `onDrop`
2016-07-27 22:45:25 -07:00
`Function onDrop(event: Event, data: Object, state: State, editor: Editor) => State || Void`
2016-07-22 17:15:46 -07:00
This handler is called when the user drops content into the `contenteditable` element. The event is already prevented by default, so you must define a state change to have any affect occur.
2016-07-27 22:45:25 -07:00
The `data` object is a convenience object created to standardize the drop metadata across browsers. Every data object has a `type` property, can be one of `text`, `html` or `files`, and a `target` property which is a [`Selection`](../models/selection.md) indicating where the drop occured. Depending on the type, it's structure will be:
2016-07-22 17:15:46 -07:00
```js
{
type: 'text',
target: Selection,
text: String
}
{
type: 'html',
target: Selection,
text: String,
html: String
}
{
type: 'files',
target: Selection,
files: FileList
}
```
If no other plugin handles this event, it will be handled by the [Core plugin](./core.md).
### `onKeyDown`
2016-07-27 23:14:50 -07:00
`Function onKeyDown(event: Event, data: Object, state: State, editor: Editor) => State || Void`
2016-07-12 10:33:35 -07:00
2016-07-27 23:14:50 -07:00
This handler is called when any key is pressed in the `contenteditable` element, before any action is taken.
2016-08-25 22:59:36 -04:00
The `data` object contains the `key` which is a string name of the key that was pressed, as well as it's `code`. It also contains a series of helpful utility properties for determining hotkey logic. For example, `isCtrl` which is true if the `control` key was pressed, or
2016-07-27 23:14:50 -07:00
```js
{
key: String,
code: Number,
isAlt: Boolean,
isCmd: Boolean,
isCtrl: Boolean,
isLine: Boolean,
isMeta: Boolean,
isMod: Boolean,
2016-08-11 18:55:12 -07:00
isModAlt: Boolean,
2016-07-27 23:14:50 -07:00
isShift: Boolean,
isWord: Boolean
}
```
2017-01-29 19:28:57 -08:00
The `isMod` boolean is `true` if the `control` key was pressed on Windows or the `command` key was pressed on Mac _without_ the `alt/option` key also being pressed. This is a convenience for adding hotkeys like `command+b`.
2016-08-11 18:55:12 -07:00
2016-08-25 22:59:36 -04:00
The `isModAlt` boolean is `true` if the `control` key was pressed on Windows or the `command` key was pressed on Mac _and_ the `alt/option` key was also being pressed. This is a convenience for secondary hotkeys like `command+option+1`.
2016-07-27 23:14:50 -07:00
2016-08-25 22:59:36 -04:00
The `isLine` and `isWord` booleans represent whether the "line modifier" or "word modifier" hotkeys are pressed when deleteing or moving the cursor. For example, on a Mac `option + right` moves the cursor to the right one word at a time.
2016-07-12 10:33:35 -07:00
2016-07-12 10:36:55 -07:00
Make sure to `event.preventDefault()` if you do not want the default insertion behavior to occur! If no other plugin handles this event, it will be handled by the [Core plugin](./core.md).
2016-07-12 10:33:35 -07:00
2016-07-12 11:17:59 -07:00
### `onPaste`
2016-07-27 23:14:50 -07:00
`Function onPaste(event: Event, data: Object, state: State, editor: Editor) => State || Void`
2016-07-12 10:33:35 -07:00
This handler is called when the user pastes content into the `contenteditable` element. The event is already prevented by default, so you must define a state change to have any affect occur.
2016-07-27 23:14:50 -07:00
The `data` object is a convenience object created to standardize the paste metadata across browsers. Every data object has a `type` property, which can be one of `text`, `html` or `files`. Depending on the type, it's structure will be:
2016-07-12 10:33:35 -07:00
```js
{
type: 'text',
text: String
}
{
type: 'html',
text: String,
html: String
}
{
type: 'files',
files: FileList
}
```
2016-07-12 10:36:55 -07:00
If no other plugin handles this event, it will be handled by the [Core plugin](./core.md).
2016-07-12 10:33:35 -07:00
2016-07-27 22:45:25 -07:00
### `onSelect`
2016-07-27 23:14:50 -07:00
`Function onSelect(event: Event, data: Object, state: State, editor: Editor => State || Void`
2016-07-27 22:45:25 -07:00
This handler is called whenever the native DOM selection changes.
2016-07-27 22:45:25 -07:00
The `data` object contains a State [`Selection`](../models/selection.md) object representing the new selection.
2016-07-27 22:45:25 -07:00
If no other plugin handles this event, it will be handled by the [Core plugin](./core.md).
_Note: This is **not** Slate's internal selection representation (although it mirrors it). If you want to get notified when Slate's selection changes, use the [`onSelectionChange`](../components/editor.md#onselectionchange) property of the `<Editor>`. This handler is instead meant to give you lower-level access to the DOM selection handling._
2016-07-12 10:33:35 -07:00
## Other Properties
```js
{
onChange: Function
}
```
### `onChange`
`Function onChange(state: State) => State || Void`
2016-07-12 10:33:35 -07:00
The `onChange` handler isn't a native browser event handler. Instead, it is invoked whenever the editor state changes. Returning a new state will update the editor's state, continuing down the plugin stack.
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.
2016-08-14 15:58:41 -07:00
### `schema`
`Object`
The `schema` property allows you to define a set of rules that will be added to the editor's schema. The rules from each of the schemas returned by the plugins are collected into a single schema for the editor, and the rules are applied in the same order as the plugin stack.