mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-19 13:41:19 +02:00
update docs
This commit is contained in:
@@ -40,7 +40,6 @@
|
||||
|
||||
- [Html](./reference/serializers/html.md)
|
||||
- [Plain](./reference/serializers/plain.md)
|
||||
- [Raw](./reference/serializers/raw.md)
|
||||
|
||||
|
||||
## Plugin Reference
|
||||
|
@@ -22,7 +22,6 @@ This is the full reference documentation for all of the pieces of Slate, broken
|
||||
- **Serializers**
|
||||
- [Html](./serializers/html.md)
|
||||
- [Plain](./serializers/plain.md)
|
||||
- [Raw](./serializers/raw.md)
|
||||
- **Plugins**
|
||||
- [Plugins](./plugins/plugin.md)
|
||||
- [Core](./plugins/core.md)
|
||||
|
@@ -21,8 +21,11 @@ Block nodes may contain nested block nodes, inline nodes, and text nodes—just
|
||||
- [Static Methods](#static-methods)
|
||||
- [`Block.create`](#blockcreate)
|
||||
- [`Block.createList`](#blockcreatelist)
|
||||
- [`Block.fromJSON`](#blockfromjson)
|
||||
- [`Block.isBlock`](#blockisblock)
|
||||
- [Node Methods](#node-methods)
|
||||
- [Instance Methods](#instance-methods)
|
||||
- [`toJSON`](#tojson)
|
||||
|
||||
|
||||
## Properties
|
||||
@@ -90,11 +93,25 @@ Create a block from a plain Javascript object of `properties`.
|
||||
|
||||
Create a list of block nodes from a plain Javascript `array`.
|
||||
|
||||
### `Block.isBlock`
|
||||
`Block.isBlock(maybeBlock: Any) => Boolean`
|
||||
### `Block.fromJSON`
|
||||
`Block.fromJSON(object: Object) => Block`
|
||||
|
||||
Create a block from a JSON `object`.
|
||||
|
||||
### `Block.isBlock`
|
||||
`Block.isBlock(value: Any) => Boolean`
|
||||
|
||||
Returns a boolean if the passed in `value` is a `Block`.
|
||||
|
||||
Returns a boolean if the passed in argument is a `Block`.
|
||||
|
||||
## Node Methods
|
||||
|
||||
Blocks implement the [`Node`](./node.md) interface. For information about all of the node methods, see the [`Node` reference](./node.md).
|
||||
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `toJSON`
|
||||
`toJSON() => Object`
|
||||
|
||||
Returns a JSON representation of the block.
|
||||
|
@@ -15,7 +15,10 @@ Characters are how Slate associates [`Marks`](./mark.md) with a range of text, f
|
||||
- [Static Methods](#static-methods)
|
||||
- [`Character.create`](#charactercreate)
|
||||
- [`Character.createList`](#charactercreatelist)
|
||||
- [`Character.fromJSON`](#characterfromjson)
|
||||
- [`Character.isCharacter`](#characterischaracter)
|
||||
- [Instance Methods](#instance-methods)
|
||||
- [`toJSON`](#tojson)
|
||||
|
||||
|
||||
## Properties
|
||||
@@ -50,7 +53,20 @@ Create a character from a plain Javascript object of `properties`.
|
||||
|
||||
Create a list of characters from a plain Javascript `array`.
|
||||
|
||||
### `Character.fromJSON`
|
||||
`Character.fromJSON(object: Object) => Character`
|
||||
|
||||
Create a character from a JSON `object`.
|
||||
|
||||
### `Character.isCharacter`
|
||||
`Character.isCharacter(maybeCharacter: Any) => Boolean`
|
||||
|
||||
Returns a boolean if the passed in argument is a `Character`.
|
||||
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `toJSON`
|
||||
`toJSON() => Object`
|
||||
|
||||
Returns a JSON representation of the character.
|
||||
|
@@ -11,6 +11,7 @@ A data object can have any properties associated with it.
|
||||
|
||||
- [Static Methods](#static-methods)
|
||||
- [`Data.create`](#datacreate)
|
||||
- [`Data.fromJSON`](#datafromjson)
|
||||
|
||||
|
||||
## Static Methods
|
||||
@@ -19,3 +20,8 @@ A data object can have any properties associated with it.
|
||||
`Data.create(properties: Object) => Data`
|
||||
|
||||
Create a data object from a plain Javascript object of `properties`.
|
||||
|
||||
### `Data.fromJSON`
|
||||
`Data.fromJSON(object: Object) => Data`
|
||||
|
||||
Create a data object from a JSON `object`.
|
||||
|
@@ -19,8 +19,11 @@ In some places, you'll see mention of "fragments", which are also `Document` obj
|
||||
- [`text`](#text)
|
||||
- [Static Methods](#static-methods)
|
||||
- [`Document.create`](#documentcreate)
|
||||
- [`Document.fromJSON`](#documentfromjson)
|
||||
- [`Document.isDocument`](#documentisdocument)
|
||||
- [Node Methods](#node-methods)
|
||||
- [Instance Methods](#instance-methods)
|
||||
- [`toJSON`](#tojson)
|
||||
|
||||
|
||||
## Properties
|
||||
@@ -62,6 +65,11 @@ A concatenated string of all of the descendant [`Text`](./text.md) nodes of this
|
||||
|
||||
Create a block from a plain Javascript object of `properties`.
|
||||
|
||||
### `Document.fromJSON`
|
||||
`Document.fromJSON(object: Object) => Document`
|
||||
|
||||
Create a document from a JSON `object`.
|
||||
|
||||
### `Document.isDocument`
|
||||
`Document.isDocument(maybeDocument: Any) => Boolean`
|
||||
|
||||
@@ -71,3 +79,11 @@ Returns a boolean if the passed in argument is a `Document`.
|
||||
## Node Methods
|
||||
|
||||
Documents implement the [`Node`](./node.md) interface. For information about all of the node methods, see the [`Node` reference](./node.md).
|
||||
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `toJSON`
|
||||
`toJSON() => Object`
|
||||
|
||||
Returns a JSON representation of the document.
|
||||
|
@@ -21,8 +21,11 @@ Inline nodes may contain nested inline nodes and text nodes—just like in the D
|
||||
- [Static Methods](#static-methods)
|
||||
- [`Inline.create`](#inlinecreate)
|
||||
- [`Inline.createList`](#inlinecreatelist)
|
||||
- [`Inline.fromJSON`](#inlinefromjson)
|
||||
- [`Inline.isInline`](#inlineisinline)
|
||||
- [Node Methods](#node-methods)
|
||||
- [Instance Methods](#instance-methods)
|
||||
- [`toJSON`](#tojson)
|
||||
|
||||
|
||||
## Properties
|
||||
@@ -90,6 +93,11 @@ Create a block from a plain Javascript object of `properties`.
|
||||
|
||||
Create a list of inline nodes from a plain Javascript `array`.
|
||||
|
||||
### `Inline.fromJSON`
|
||||
`Inline.fromJSON(object: Object) => Inline`
|
||||
|
||||
Create an inline from a JSON `object`.
|
||||
|
||||
### `Inline.isInline`
|
||||
`Inline.isInline(maybeInline: Any) => Boolean`
|
||||
|
||||
@@ -99,3 +107,11 @@ Returns a boolean if the passed in argument is a `Inline`.
|
||||
## Node Methods
|
||||
|
||||
Inlines implement the [`Node`](./node.md) interface. For information about all of the node methods, see the [`Node` reference](./node.md).
|
||||
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `toJSON`
|
||||
`toJSON() => Object`
|
||||
|
||||
Returns a JSON representation of the inline.
|
||||
|
@@ -5,7 +5,7 @@
|
||||
import { Mark } from 'slate'
|
||||
```
|
||||
|
||||
A formatting mark that can be associated with [`Characters`](./character.md). Marks are how Slate represents rich formatting like **bold** or _italic_.
|
||||
A formatting mark that can be associated with [`Characters`](./mark.md). Marks are how Slate represents rich formatting like **bold** or _italic_.
|
||||
|
||||
- [Properties](#properties)
|
||||
- [`data`](#data)
|
||||
@@ -13,7 +13,10 @@ A formatting mark that can be associated with [`Characters`](./character.md). Ma
|
||||
- [Static Methods](#static-methods)
|
||||
- [`Mark.create`](#markcreate)
|
||||
- [`Mark.createSet`](#markcreateset)
|
||||
- [`Mark.fromJSON`](#markfromjson)
|
||||
- [`Mark.isMark`](#markismark)
|
||||
- [Instance Methods](#instance-methods)
|
||||
- [`toJSON`](#tojson)
|
||||
|
||||
|
||||
## Properties
|
||||
@@ -48,7 +51,20 @@ Create a mark from a plain Javascript object of `properties`.
|
||||
|
||||
Create a set of marks from a plain Javascript `array`.
|
||||
|
||||
### `Mark.fromJSON`
|
||||
`Mark.fromJSON(object: Object) => Mark`
|
||||
|
||||
Create a mark from a JSON `object`.
|
||||
|
||||
### `Mark.isMark`
|
||||
`Mark.isMark(maybeMark: Any) => Boolean`
|
||||
|
||||
Returns a boolean if the passed in argument is a `Mark`.
|
||||
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `toJSON`
|
||||
`toJSON() => Object`
|
||||
|
||||
Returns a JSON representation of the mark.
|
||||
|
@@ -29,7 +29,10 @@ Often times, you don't need to specifically know which point is the "anchor" and
|
||||
- [`startOffset`](#startoffset)
|
||||
- [Static Methods](#static-methods)
|
||||
- [`Selection.create`](#selectioncreate)
|
||||
- [`Selection.fromJSON`](#selectionfromjson)
|
||||
- [`Selection.isSelection`](#selectionisselection)
|
||||
- [Instance Methods](#instance-methods)
|
||||
- [`toJSON`](#tojson)
|
||||
- [Checking Methods](#checking-methods)
|
||||
- [`has{Edge}AtEndOf`](#hasedgeatendof)
|
||||
- [`has{Edge}AtStartOf`](#hasedgeatstartof)
|
||||
@@ -122,12 +125,25 @@ A few convenience properties for accessing the first and last point of the selec
|
||||
|
||||
Create a new `Selection` instance with `properties`.
|
||||
|
||||
### `Selection.fromJSON`
|
||||
`Selection.fromJSON(object: Object) => Selection`
|
||||
|
||||
Create a selection from a JSON `object`.
|
||||
|
||||
### `Selection.isSelection`
|
||||
`Selection.isSelection(maybeSelection: Any) => Boolean`
|
||||
|
||||
Returns a boolean if the passed in argument is a `Selection`.
|
||||
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `toJSON`
|
||||
`toJSON() => Object`
|
||||
|
||||
Returns a JSON representation of the selection.
|
||||
|
||||
|
||||
## Checking Methods
|
||||
|
||||
### `has{Edge}AtStartOf`
|
||||
|
@@ -37,9 +37,11 @@ For convenience, in addition to changes, many of the [`Selection`](./selection.m
|
||||
- [`isEmpty`](#isEmpty)
|
||||
- [Static Methods](#static-methods)
|
||||
- [`State.create`](#statecreate)
|
||||
- [`State.fromJSON`](#statefromjson)
|
||||
- [`State.isState`](#stateisstate)
|
||||
- [Methods](#methods)
|
||||
- [Instance Methods](#instance-methods)
|
||||
- [`change`](#change)
|
||||
- [`toJSON`](#tojson)
|
||||
|
||||
|
||||
## Properties
|
||||
@@ -178,15 +180,25 @@ Whether the current selection is empty.
|
||||
|
||||
Create a new `State` instance with `properties`.
|
||||
|
||||
### `State.fromJSON`
|
||||
`State.fromJSON(object: Object) => State`
|
||||
|
||||
Create a state from a JSON `object`.
|
||||
|
||||
### `State.isState`
|
||||
`State.isState(maybeState: Any) => Boolean`
|
||||
|
||||
Returns a boolean if the passed in argument is a `State`.
|
||||
|
||||
|
||||
## Methods
|
||||
## Instance Methods
|
||||
|
||||
### `change`
|
||||
`change() => Change`
|
||||
|
||||
Create a new [`Change`](./change.md) that acts on the current state.
|
||||
|
||||
### `toJSON`
|
||||
`toJSON() => Object`
|
||||
|
||||
Returns a JSON representation of the state.
|
||||
|
@@ -15,9 +15,10 @@ A text node in a Slate [`Document`](./document.md). Text nodes are always the bo
|
||||
- [`text`](#text)
|
||||
- [Static Methods](#static-methods)
|
||||
- [`Text.create`](#textcreate)
|
||||
- [`Text.createFromString`](#textcreatefromstring)
|
||||
- [`Text.createFromRanges`](#textcreatefromranges)
|
||||
- [`Text.fromJSON`](#textfromjson)
|
||||
- [`Text.isText`](#textistext)
|
||||
- [Instance Methods](#instance-methods)
|
||||
- [`toJSON`](#tojson)
|
||||
|
||||
## Properties
|
||||
|
||||
@@ -58,17 +59,20 @@ A concatenated string of all of the characters in the text node.
|
||||
|
||||
Create a text from a plain Javascript object of `properties`.
|
||||
|
||||
### `Text.createFromRanges`
|
||||
`Text.createFromRanges(ranges: List<Range>) => Text`
|
||||
### `Text.fromJSON`
|
||||
`Text.fromJSON(object: Object) => Text`
|
||||
|
||||
Create a text from a list of text ranges.
|
||||
|
||||
### `Text.createFromString`
|
||||
`Text.createFromString(text: String, marks: Set) => Text`
|
||||
|
||||
Create a text from a plain `String` and a set of marks.
|
||||
Create a text from a JSON `object`.
|
||||
|
||||
### `Text.isText`
|
||||
`Text.isText(maybeText: Any) => Boolean`
|
||||
|
||||
Returns a boolean if the passed in argument is a `Text`.
|
||||
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `toJSON`
|
||||
`toJSON() => Object`
|
||||
|
||||
Returns a JSON representation of the text.
|
||||
|
@@ -12,7 +12,7 @@ For an example of the `Html` serializer in action, check out the [`paste-html` e
|
||||
- [Example](#example)
|
||||
- [Properties](#properties)
|
||||
- [`rules`](#rules)
|
||||
- [`defaultBlockType`](#defaultblocktype)
|
||||
- [`defaultBlock`](#defaultblock)
|
||||
- [`parseHtml`](#parsehtml)
|
||||
- [Methods](#methods)
|
||||
- [`deserialize`](#deserialize)
|
||||
@@ -44,10 +44,10 @@ new Html({
|
||||
|
||||
An array of rules to initialize the `Html` serializer with, defining your schema.
|
||||
|
||||
### `defaultBlockType`
|
||||
`String|Object`
|
||||
### `defaultBlock`
|
||||
`String|Object|Block`
|
||||
|
||||
A default block type for blocks which do not match any rule. Can be a string such as `paragraph` or an object with a `type` attribute such as `{ type: 'paragraph' }`.
|
||||
A set of properties to use for blocks which do not match any rule. Can be a string such as `'paragraph'` or an object with a `type` attribute such as `{ type: 'paragraph' }`, or even a [`Block`](../models/block.md).
|
||||
|
||||
### `parseHtml`
|
||||
`Function`
|
||||
@@ -61,7 +61,7 @@ A function to parse an HTML string and return a DOM object. Defaults to using th
|
||||
|
||||
Deserialize an HTML `string` into a [`State`](../models/state.md). How the string is deserialized will be determined by the rules that the `Html` serializer was constructed with.
|
||||
|
||||
If you pass `toRaw: true` as an option, the return value will be a [`Raw`](./raw.md) JSON object instead of a [`State`](../models/state.md) object.
|
||||
If you pass `toJSON: true` as an option, the return value will be a JSON object instead of a [`State`](../models/state.md) object.
|
||||
|
||||
### `Html.serialize`
|
||||
`Html.serialize(state: State, [options: Object]) => String || Array`
|
||||
@@ -90,8 +90,6 @@ Each rule must define two properties:
|
||||
|
||||
The `deserialize` function receives a DOM element and should return a plain Javascript object representing the deserialized state, or nothing if the rule in question doesn't know how to deserialize the object, in which case the next rule in the stack will be attempted.
|
||||
|
||||
The returned object is almost exactly equivalent to the objects returned by the [`Raw`](./raw.md) serializer, except an extra `kind: 'mark'` is added to account for the ability to nest marks.
|
||||
|
||||
The object should be one of:
|
||||
|
||||
```js
|
||||
|
@@ -29,7 +29,7 @@ Check out http://slatejs.org for examples!
|
||||
|
||||
Deserialize a plain text `string` into a [`State`](../models/state.md). A series of blocks will be created by splitting the input string on `\n` characters. Each block is given a type of `'line'`.
|
||||
|
||||
If you pass `toRaw: true` as an option, the return value will be a [`Raw`](./raw.md) JSON object instead of a [`State`](../models/state.md) object.
|
||||
If you pass `toJSON: true` as an option, the return value will be a JSON object instead of a [`State`](../models/state.md) object.
|
||||
|
||||
### `Plain.serialize`
|
||||
`Plain.serialize(state: State) => String`
|
||||
|
@@ -1,144 +0,0 @@
|
||||
|
||||
# `Raw`
|
||||
|
||||
```js
|
||||
import { Raw } from 'slate'
|
||||
```
|
||||
|
||||
The raw JSON serialized that ships by default with Slate. It converts a [`State`](../models/state.md) into a JSON object.
|
||||
|
||||
In the raw format, text is represented as "ranges", which are a more compact way to represent the formatting applied to characters than the immutable model Slate uses internally.
|
||||
|
||||
When saving the data to size-sensitive places, the raw serializer can be told to omit properties that aren't _strictly_ required to deserialize later, reducing the serialized data's size. For example, if the dictionary of [`Data`](../models/data.md) for a [`Node`](../models/node.md) is empty, it will be omitted.
|
||||
|
||||
- [Example](#example)
|
||||
- [Static Methods](#methods)
|
||||
- [`Raw.deserialize`](#rawdeserialize)
|
||||
- [`Raw.serialize`](#rawserialize)
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
```json
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"kind": "block",
|
||||
"type": "paragraph",
|
||||
"nodes": [
|
||||
{
|
||||
"kind": "text",
|
||||
"ranges": [
|
||||
{
|
||||
"text": "The Slate editor gives you "
|
||||
},
|
||||
{
|
||||
"text": "complete",
|
||||
"marks": [
|
||||
{
|
||||
"type": "italic"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "control over the logic you can add. For example, it's fairly common to want to add markdown-like shortcuts to editors. So that, when you start a line with \"> \" you get a blockquote that looks like this:"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "block",
|
||||
"type": "block-quote",
|
||||
"nodes": [
|
||||
{
|
||||
"kind": "text",
|
||||
"ranges": [
|
||||
{
|
||||
"text": "A wise quote."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "block",
|
||||
"type": "paragraph",
|
||||
"nodes": [
|
||||
{
|
||||
"kind": "text",
|
||||
"ranges": [
|
||||
{
|
||||
"text": "Order when you start a line with \"## \" you get a level-two heading, like this:"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "block",
|
||||
"type": "heading-two",
|
||||
"nodes": [
|
||||
{
|
||||
"kind": "text",
|
||||
"ranges": [
|
||||
{
|
||||
"text": "Try it out at "
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "inline",
|
||||
"type": "link",
|
||||
"data": {
|
||||
"href": "http://slatejs.org"
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"kind": "text",
|
||||
"ranges": [
|
||||
{
|
||||
"text": "http://slatejs.org"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"ranges": [
|
||||
{
|
||||
"text": "!"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Methods
|
||||
|
||||
### `Raw.deserialize`
|
||||
`Raw.deserialize(object: Object, [options: Object]) => State`
|
||||
|
||||
Deserialize a raw JSON `object` into a [`State`](../models/state.md).
|
||||
|
||||
You must pass the `terse: true` option if you want to deserialize a state that was previously serialized with `terse: true`.
|
||||
|
||||
If you are serializing directly for storage in a database, or in other scenarios where you know the state will not be tampered with, you can pass in a `normalize: false` option which will greatly speed up the deserialization time, since it doesn't need to ensure that the state is fully normalized.
|
||||
|
||||
### `Raw.serialize`
|
||||
`Raw.serialize(state: State, [options: Object]) => Object`
|
||||
|
||||
Serialize a `state` into a raw JSON object.
|
||||
|
||||
#### Options
|
||||
|
||||
* `terse` (Boolean, default `false`) — if you pass the `terse: true` option, the serialized format will omit properties that aren't _strictly_ required to deserialize later, reducing the serialized data's size. For example, if the dictionary of [`Data`](../models/data.md) for a [`Node`](../models/node.md) is empty, it will be omitted.
|
||||
* `preserveKeys` (Boolean, default `false`) — set to `true` to preserve the keys on nodes in the serialized document and selection.
|
||||
* `preserveSelection` (Boolean, default `false`) — set to `true` to add the [`Selection`](../models/selection.md) (`state.selection`) to the serialized output.
|
||||
* `preserveStateData` (Boolean, default `false`) — set to `true` to add the `state.data` to the serialized output.
|
@@ -24,54 +24,62 @@ Slate exposes a set of modules that you'll use to build your editor. The most im
|
||||
import { Editor } from 'slate'
|
||||
```
|
||||
|
||||
In addition to rendering the editor, you need to give Slate a "initial state" to render as content.
|
||||
|
||||
To keep things simple, we'll use the `Raw` serializer that ships with Slate to create a new initial state that just contains a single paragraph block with some text in it:
|
||||
In addition to rendering the editor, you need to give Slate a "initial state" to render as content. We'll use the `State` model that ships with Slate to create a new initial state that just contains a single paragraph block with some text in it:
|
||||
|
||||
```js
|
||||
// Import the "raw" serializer that ships with Slate.
|
||||
import { Editor, Raw } from 'slate'
|
||||
// Import the `State` model.
|
||||
import { Editor, State } from 'slate'
|
||||
|
||||
// Create our initial state...
|
||||
const initialState = Raw.deserialize({
|
||||
nodes: [
|
||||
{
|
||||
kind: 'block',
|
||||
type: 'paragraph',
|
||||
nodes: [
|
||||
{
|
||||
kind: 'text',
|
||||
text: 'A line of text in a paragraph.'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}, { terse: true })
|
||||
const initialState = State.fromJSON({
|
||||
document: {
|
||||
nodes: [
|
||||
{
|
||||
kind: 'block',
|
||||
type: 'paragraph',
|
||||
nodes: [
|
||||
{
|
||||
kind: 'text',
|
||||
ranges: [
|
||||
{
|
||||
text: 'A line of text in a paragraph.'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The `terse: true` option there isn't important for now, but if you're curious about it you can check out the [`Raw` serializer reference](../reference/serializers/raw.md).
|
||||
|
||||
And now that we've our initial state, we define our `App` and pass it into Slate's `Editor` component, like so:
|
||||
|
||||
```js
|
||||
// Import React!
|
||||
import React from 'react'
|
||||
import { Editor, Raw } from 'slate'
|
||||
import { Editor, State } from 'slate'
|
||||
|
||||
const initialState = Raw.deserialize({
|
||||
nodes: [
|
||||
{
|
||||
kind: 'block',
|
||||
type: 'paragraph',
|
||||
nodes: [
|
||||
{
|
||||
kind: 'text',
|
||||
text: 'A line of text in a paragraph.'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}, { terse: true })
|
||||
const initialState = State.fromJSON({
|
||||
document: {
|
||||
nodes: [
|
||||
{
|
||||
kind: 'block',
|
||||
type: 'paragraph',
|
||||
nodes: [
|
||||
{
|
||||
kind: 'text',
|
||||
ranges: [
|
||||
{
|
||||
text: 'A line of text in a paragraph.'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// Define our app...
|
||||
class App extends React.Component {
|
||||
@@ -99,7 +107,7 @@ class App extends React.Component {
|
||||
}
|
||||
```
|
||||
|
||||
You'll notice that the `onChange` handler passed into the `Editor` component just updates the app's state with the newest editor state. That way, when it re-renders the editor, the new state is reflected with your changes.
|
||||
You'll notice that the `onChange` handler passed into the `Editor` component just updates the app's state with the newest changed state. That way, when it re-renders the editor, the new state is reflected with your changes.
|
||||
|
||||
And that's it!
|
||||
|
||||
@@ -109,22 +117,3 @@ That's the most basic example of Slate. If you render that onto the page, you sh
|
||||
<p align="center"><strong>Next:</strong><br/><a href="./adding-event-handlers.md">Adding Event Handlers</a></p>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -5,9 +5,7 @@
|
||||
|
||||
# Saving and Loading HTML Content
|
||||
|
||||
In the previous guide, we looked at how to serialize the Slate editor's content and save it for later. But we only covered the [`Plain`](../reference/serializers/plain.md) and [`Raw`](../reference/serializers/raw.md) serialization techniques.
|
||||
|
||||
What if you want to save the content as HTML? It's a slightly more involved process, but this guide will show you how to do it.
|
||||
In the previous guide, we looked at how to serialize the Slate editor's content and save it for later. What if you want to save the content as HTML? It's a slightly more involved process, but this guide will show you how to do it.
|
||||
|
||||
Let's start with a basic editor:
|
||||
|
||||
@@ -66,8 +64,6 @@ const rules = [
|
||||
]
|
||||
```
|
||||
|
||||
If you've worked with the [`Raw`](../reference/serializers/raw.md) serializer before, the return value of the `deserialize` should look familiar! It's just the same raw JSON format.
|
||||
|
||||
The `el` argument that the `deserialize` function receives is just a DOM element. And the `next` argument is a function that will deserialize any element(s) we pass it, which is how you recurse through each node's children.
|
||||
|
||||
A quick note on `el.tagName` -- in browser environments, Slate uses the native `DOMParser` to parse HTML, which returns uppercase tag names. In server-side or node environments, we recommend [providing parse5](https://docs.slatejs.org/reference/serializers/html.html#parsehtml) to parse HTML; however, parse5 returns lowercase tag names due to some subtle complexities in specifications. Consequentially, we recommend using case-insensitive tag comparisons, so your code just works everywhere without having to worry about the parser implementation.
|
||||
|
@@ -9,17 +9,36 @@ Now that you've learned the basics of how to add functionality to the Slate edit
|
||||
|
||||
In this guide, we'll show you how to add logic to save your Slate content to a database for storage and retrieval later.
|
||||
|
||||
Let's start with a basic, plain text rendering editor:
|
||||
Let's start with a basic editor:
|
||||
|
||||
```js
|
||||
import { Editor, Plain } from 'slate'
|
||||
import { Editor, State } from 'slate'
|
||||
|
||||
const initialContent = 'The initial string of content!'
|
||||
const initialState = State.fromJSON({
|
||||
document: {
|
||||
nodes: [
|
||||
{
|
||||
kind: 'block',
|
||||
type: 'paragraph',
|
||||
nodes: [
|
||||
{
|
||||
kind: 'text',
|
||||
ranges: [
|
||||
{
|
||||
text: 'A line of text in a paragraph.'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
class App extends React.Component {
|
||||
|
||||
state = {
|
||||
state: Plain.deserialize(initialContent)
|
||||
state: initialState
|
||||
}
|
||||
|
||||
onChange = ({ state }) => {
|
||||
@@ -38,26 +57,43 @@ class App extends React.Component {
|
||||
}
|
||||
```
|
||||
|
||||
That will render a basic Slate editor on your page, and when you type things will change. But if you refresh the page, everything will be reverted back to its original stage.
|
||||
That will render a basic Slate editor on your page, and when you type things will change. But if you refresh the page, everything will be reverted back to its original state—nothing saves!
|
||||
|
||||
What we need to do is save the changes you make somewhere. For this example, we'll just be using [Local Storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), but it will give you an idea for where you'd need to add your own database hooks.
|
||||
|
||||
So, in our `onChange` handler, we need to save the `state`. But the `state` argument that `onChange` receives is an immutable object, so we can't just save it as-is. We need to serialize it to a format we understand first.
|
||||
|
||||
In this case, we're already using the [`Plain`](../reference/serializers/plain.md) serializer to create our initial state, so let's use it to serialize our saved state as well, like so:
|
||||
So, in our `onChange` handler, we need to save the `state`. But the `state` argument that `onChange` receives is an immutable object, so we can't just save it as-is. We need to serialize it to a format we understand first, like JSON!
|
||||
|
||||
```js
|
||||
const initialContent = 'The initial string of content!'
|
||||
const initialState = State.fromJSON({
|
||||
document: {
|
||||
nodes: [
|
||||
{
|
||||
kind: 'block',
|
||||
type: 'paragraph',
|
||||
nodes: [
|
||||
{
|
||||
kind: 'text',
|
||||
ranges: [
|
||||
{
|
||||
text: 'A line of text in a paragraph.'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
class App extends React.Component {
|
||||
|
||||
state = {
|
||||
state: Plain.deserialize(initialContent)
|
||||
state: initialState
|
||||
}
|
||||
|
||||
onChange = ({ state }) => {
|
||||
// Save the state to Local Storage.
|
||||
const content = Plain.serialize(state)
|
||||
const content = JSON.stringify(state.toJSON())
|
||||
localStorage.setItem('content', content)
|
||||
|
||||
this.setState({ state })
|
||||
@@ -75,25 +111,42 @@ class App extends React.Component {
|
||||
}
|
||||
```
|
||||
|
||||
Now whenever you edit the page, if you look in Local Storage, you should see the content string changing.
|
||||
Now whenever you edit the page, if you look in Local Storage, you should see the `content` value changing.
|
||||
|
||||
But... if you refresh the page, everything is still reset. That's because we need to make sure the initial state is pulled from that same Local Storage location, like so:
|
||||
|
||||
```js
|
||||
// Update the initial content to be pulled from Local Storage if it exists.
|
||||
const initialContent = (
|
||||
localStorage.getItem('content') ||
|
||||
'The initial string of content!'
|
||||
)
|
||||
const existingState = JSON.parse(localStorage.getItem('content'))
|
||||
const initialState = State.fromJSON(existingState || {
|
||||
document: {
|
||||
nodes: [
|
||||
{
|
||||
kind: 'block',
|
||||
type: 'paragraph',
|
||||
nodes: [
|
||||
{
|
||||
kind: 'text',
|
||||
ranges: [
|
||||
{
|
||||
text: 'A line of text in a paragraph.'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
class App extends React.Component {
|
||||
|
||||
state = {
|
||||
state: Plain.deserialize(initialContent)
|
||||
state: initialState
|
||||
}
|
||||
|
||||
onChange = ({ state }) => {
|
||||
const content = Plain.serialize(state)
|
||||
const content = JSON.stringify(state.toJSON())
|
||||
localStorage.setItem('content', content)
|
||||
|
||||
this.setState({ state })
|
||||
@@ -116,20 +169,38 @@ Now you should be able to save changes across refreshes!
|
||||
However, if you inspect the change handler, you'll notice that it's actually saving the Local Storage value on _every_ change to the editor, even when only the selection changes! This is because `onChange` is called for _every_ change. For Local Storage this doesn't really matter, but if you're saving things to a database via HTTP request this would result in a lot of unnecessary requests. You can fix this by checking against the previous `document` value.
|
||||
|
||||
```js
|
||||
const initialContent = (
|
||||
localStorage.getItem('content') ||
|
||||
'The initial string of content!'
|
||||
)
|
||||
const existingState = JSON.parse(localStorage.getItem('content'))
|
||||
const initialState = State.fromJSON(existingState || {
|
||||
document: {
|
||||
nodes: [
|
||||
{
|
||||
kind: 'block',
|
||||
type: 'paragraph',
|
||||
nodes: [
|
||||
{
|
||||
kind: 'text',
|
||||
ranges: [
|
||||
{
|
||||
text: 'A line of text in a paragraph.'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
class App extends React.Component {
|
||||
|
||||
state = {
|
||||
state: Plain.deserialize(initialContent)
|
||||
state: initialState
|
||||
}
|
||||
|
||||
onChange = ({ state }) => {
|
||||
// Check to see if the document has changed before saving.
|
||||
if (state.document != this.state.state.document) {
|
||||
const content = Plain.serialize(state)
|
||||
const content = JSON.stringify(state.toJSON())
|
||||
localStorage.setItem('content', content)
|
||||
}
|
||||
|
||||
@@ -150,32 +221,26 @@ class App extends React.Component {
|
||||
|
||||
Now you're content will be saved only when the content itself changes!
|
||||
|
||||
Success. But we're only saving plain text strings here. If you're working with rich text, you'll need to serialize the `state` object differently. Instead, you can use the `Raw` serializer, and save things in Local Storage as JSON strings, like so:
|
||||
Success—you've got JSON in your database.
|
||||
|
||||
But what if you want something other than JSON? Well, you'd need to serialize your state differently. For example, if you want to save your content as plain text instead of JSON, you can use the `Plain` serializer that ships with Slate, like so:
|
||||
|
||||
```js
|
||||
const initialContent = (
|
||||
JSON.parse(localStorage.getItem('content')) ||
|
||||
{
|
||||
nodes: [
|
||||
{
|
||||
kind: 'block',
|
||||
type: 'paragraph'
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
// Switch to using the Plain serializer.
|
||||
import { Editor, Plain } from 'slate'
|
||||
|
||||
const existingState = localStorage.getItem('content')
|
||||
const initialState = Plain.deserialize(existingState || 'A string of plain text.')
|
||||
|
||||
class App extends React.Component {
|
||||
|
||||
state = {
|
||||
state: Raw.deserialize(initialContent, {terse: true})
|
||||
state: initialState
|
||||
}
|
||||
|
||||
onChange = ({ state }) => {
|
||||
if (state.document != this.state.state.document) {
|
||||
// Switch to using the Raw serializer.
|
||||
const content = JSON.stringify(Raw.serialize(state))
|
||||
const content = Plain.serialize(state)
|
||||
localStorage.setItem('content', content)
|
||||
}
|
||||
|
||||
@@ -194,9 +259,9 @@ class App extends React.Component {
|
||||
}
|
||||
```
|
||||
|
||||
That works! Now you can preserve any formatting that the user added.
|
||||
That works! Now you're working with plain text.
|
||||
|
||||
However, sometimes you may not want to use the raw JSON representation that Slate understands, and you may want something slightly more standardized, like good old fashioned HTML. In that case, check out the next guide...
|
||||
However, sometimes you may want something a bit more custom, and a bit more complex... good old fashioned HTML. In that case, check out the next guide...
|
||||
|
||||
|
||||
<br/>
|
||||
|
Reference in New Issue
Block a user