mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-19 05:31:56 +02:00
Remove deprecations (#2113)
#### Is this adding or improving a _feature_ or fixing a _bug_? Debt. #### What's the new behavior? This removes almost all existing deprecations from previous API changes, to save on filesize and reduce complexity in the codebase going forward. It also changes from using the `slate-dev-logger` to using the Facebook-inspired `slate-dev-warning` which can be compiled out of production builds with [`babel-plugin-dev-expression`](https://github.com/4Catalyzer/babel-plugin-dev-expression) to save even further on file size. The only deprecations it keeps are in the `fromJSON` methods for data model changes like `.kind` and `.leaves` which may still may not have been migrated in databases, since this is a bigger pain point. #### Have you checked that...? * [x] The new code matches the existing patterns and styles. * [x] The tests pass with `yarn test`. * [x] The linter passes with `yarn lint`. (Fix errors with `yarn prettier`.) * [x] The relevant examples still work. (Run examples with `yarn watch`.) #### Does this fix any issues or need any specific reviewers? Fixes: #1922 Fixes: #2105 Fixes: #646 Fixes: #2109 Fixes: #2107 Fixes: #2018
This commit is contained in:
@@ -4,11 +4,10 @@ Since Slate is a monorepo with many packages that are versioned separately, we m
|
||||
|
||||
* [`slate`](./packages/slate/Changelog.md)
|
||||
* [`slate-base64-serializer`](./packages/slate-base64-serializer/Changelog.md)
|
||||
* [`slate-dev-logger`](./packages/slate-dev-logger/Changelog.md)
|
||||
* [`slate-dev-warning`](./packages/slate-dev-warning/Changelog.md)
|
||||
* [`slate-html-serializer`](./packages/slate-html-serializer/Changelog.md)
|
||||
* [`slate-hyperscript`](./packages/slate-hyperscript/Changelog.md)
|
||||
* [`slate-plain-serializer`](./packages/slate-plain-serializer/Changelog.md)
|
||||
* [`slate-prop-types`](./packages/slate-prop-types/Changelog.md)
|
||||
* [`slate-react`](./packages/slate-react/Changelog.md)
|
||||
* [`slate-schema-violations`](./packages/slate-schema-violations/Changelog.md)
|
||||
* [`slate-simulator`](./packages/slate-simulator/Changelog.md)
|
||||
|
@@ -15,19 +15,13 @@ const h = createHyperscript({
|
||||
code: 'code',
|
||||
list: 'list',
|
||||
item: 'item',
|
||||
image: {
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
},
|
||||
image: 'image',
|
||||
},
|
||||
inlines: {
|
||||
link: 'link',
|
||||
hashtag: 'hashtag',
|
||||
comment: 'comment',
|
||||
emoji: {
|
||||
type: 'emoji',
|
||||
isVoid: true,
|
||||
},
|
||||
emoji: 'emoji',
|
||||
},
|
||||
marks: {
|
||||
b: 'bold',
|
||||
|
@@ -11,12 +11,10 @@ const input = {
|
||||
nodes: Array.from(Array(100)).map(() => ({
|
||||
type: 'list',
|
||||
object: 'block',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: Array.from(Array(10)).map(() => ({
|
||||
type: 'list-item',
|
||||
object: 'block',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -32,7 +30,6 @@ const input = {
|
||||
{
|
||||
type: 'link',
|
||||
object: 'inline',
|
||||
isVoid: false,
|
||||
data: {
|
||||
id: 1,
|
||||
},
|
||||
|
@@ -32,6 +32,7 @@
|
||||
* [Block](./reference/slate/block.md)
|
||||
* [Change](./reference/slate/change.md)
|
||||
* [Data](./reference/slate/data.md)
|
||||
* [Decoration](./reference/slate/decoration.md)
|
||||
* [Document](./reference/slate/document.md)
|
||||
* [Inline](./reference/slate/inline.md)
|
||||
* [Mark](./reference//slate/mark.md)
|
||||
@@ -40,6 +41,7 @@
|
||||
* [Point](./reference/slate/point.md)
|
||||
* [Range](./reference/slate/range.md)
|
||||
* [Schema](./reference/slate/schema.md)
|
||||
* [Selection](./reference/slate/selection.md)
|
||||
* [Text](./reference/slate/text.md)
|
||||
* [Value](./reference/slate/value.md)
|
||||
* [setKeyGenerator](./reference/slate/utils.md)
|
||||
@@ -66,5 +68,4 @@
|
||||
* [`slate-hyperscript`](./reference/slate-hyperscript/index.md)
|
||||
* [`slate-plain-serializer`](./reference/slate-plain-serializer/index.md)
|
||||
* [`slate-prop-types`](./reference/slate-prop-types/index.md)
|
||||
* [`slate-schema-violations`](./reference/slate-schema-violations/index.md)
|
||||
* [`slate-simulator`](./reference/slate-simulator/index.md)
|
||||
|
@@ -4,11 +4,9 @@ Since Slate is a monorepo with many packages that are versioned separately, we m
|
||||
|
||||
* [`slate`](https://github.com/ianstormtaylor/slate/tree/master/packages/slate/Changelog.md)
|
||||
* [`slate-base64-serializer`](https://github.com/ianstormtaylor/slate/tree/master/packages/slate-base64-serializer/Changelog.md)
|
||||
* [`slate-dev-logger`](https://github.com/ianstormtaylor/slate/tree/master/packages/slate-dev-logger/Changelog.md)
|
||||
* [`slate-html-serializer`](https://github.com/ianstormtaylor/slate/tree/master/packages/slate-html-serializer/Changelog.md)
|
||||
* [`slate-hyperscript`](https://github.com/ianstormtaylor/slate/tree/master/packages/slate-hyperscript/Changelog.md)
|
||||
* [`slate-plain-serializer`](https://github.com/ianstormtaylor/slate/tree/master/packages/slate-plain-serializer/Changelog.md)
|
||||
* [`slate-prop-types`](https://github.com/ianstormtaylor/slate/tree/master/packages/slate-prop-types/Changelog.md)
|
||||
* [`slate-react`](https://github.com/ianstormtaylor/slate/tree/master/packages/slate-react/Changelog.md)
|
||||
* [`slate-schema-violations`](https://github.com/ianstormtaylor/slate/tree/master/packages/slate-schema-violations/Changelog.md)
|
||||
* [`slate-simulator`](https://github.com/ianstormtaylor/slate/tree/master/packages/slate-simulator/Changelog.md)
|
||||
|
@@ -9,7 +9,7 @@ These libraries are helpful when developing with Slate:
|
||||
* [`is-hotkey`](https://github.com/ianstormtaylor/is-hotkey) is a simple way to check whether an `onKeyDown` handler should fire for a given hotkey, handling cross-platform concerns like <kbd>cmd</kbd> vs. <kbd>ctrl</kbd> keys for you automatically.
|
||||
* [`react-broadcast`](https://github.com/ReactTraining/react-broadcast) works well when you need to have your custom node components re-render based on state that lives outside the `document`. It's the same pattern that `react-router` uses to update `<Link>` components.
|
||||
|
||||
## Tooling
|
||||
## Tools
|
||||
|
||||
These tools are helpful when developing with Slate:
|
||||
|
||||
|
@@ -28,7 +28,6 @@ change
|
||||
.moveToEndOfBlock()
|
||||
.insertBlock({
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
data: {
|
||||
src: 'http://placekitten.com/200/300',
|
||||
alt: 'Kittens',
|
||||
@@ -145,7 +144,7 @@ When a rule's validation fails, Slate passes a [`Change`](../reference/slate/cha
|
||||
|
||||
### 4. From Outside Slate
|
||||
|
||||
This is the fourth place you might want to make changes, and also the most dangerous. You should know that any changes you make outside of the Slate editor might not be seen by your plugins, might interact with the history in weird ways, and may not work with collaborative editing implements.
|
||||
This is the fourth place you might want to make changes, and also the most dangerous. You should know that any changes you make outside of the Slate editor might not be seen by your plugins (eg. if they register an `onChange` handler) and may not work with collaborative editing implements.
|
||||
|
||||
That said, if that's okay with you, you can make changes manually by using the `change()` method on a Slate [`Value`](../reference/slate/value.md). For example:
|
||||
|
||||
@@ -176,7 +175,6 @@ function insertParagraph(change) {
|
||||
function insertImage(change, src) {
|
||||
change.insertBlock({
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
data: { src },
|
||||
})
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ One of the main principles of Slate is that it tries to mirror the native DOM AP
|
||||
|
||||
If you think about it, this makes sense. Slate is kind of like a nicer implementation of `contenteditable`, which itself is built with the DOM. And people use the DOM to represent documents with rich-text-like structures all the time. Mirroring the DOM helps make the library familiar for new users, and it lets us reuse battle-tested patterns without having to reinvent them ourselves.
|
||||
|
||||
Because it mirrors the DOM, Slate's data model features a [`Document`](../reference/slate/document.md) with [`Block`](../reference/slate/block.md), [`Inline`](../reference/slate/inline.md) and [`Text`](../reference/slate/text.md) nodes. You can reference parts of the document with a [`Range`](../reference/slate/range.md). And there is a special range called a "selection" that represents the user's current cursor selection.
|
||||
Because it mirrors the DOM, Slate's data model features a [`Document`](../reference/slate/document.md) with [`Block`](../reference/slate/block.md), [`Inline`](../reference/slate/inline.md) and [`Text`](../reference/slate/text.md) nodes. You can reference parts of the document with a [`Range`](../reference/slate/range.md). And there is a special range-like object called a [`Selection`](../reference/slate/selection.md) that represents the user's current cursor selection.
|
||||
|
||||
## Immutable Objects
|
||||
|
||||
@@ -39,7 +39,7 @@ It is made up of a document filled with content, and a selection representing th
|
||||
|
||||
## Documents and Nodes
|
||||
|
||||
Slate documents are nested and recursive. This means that a document has block nodes, and those block nodes can have child block nodes—all the way down. This lets you model more complex nested behaviors like tables and figures with captions.
|
||||
Slate documents are nested and recursive. This means that a document has block nodes, and those block nodes can have child nodes—all the way down. This lets you model more complex nested behaviors like tables and figures with captions.
|
||||
|
||||
Unlike the DOM though, Slate enforces a few more restrictions on its documents. This reduces the complexity involved in manipulating them and prevents "impossible" situations from arising. These restrictions are:
|
||||
|
||||
@@ -49,15 +49,13 @@ Unlike the DOM though, Slate enforces a few more restrictions on its documents.
|
||||
|
||||
* **Inlines can only contain inline or text nodes.** This one is also for sanity and avoiding boilerplate. Once you've descended into an "inline" context, you can't have block nodes inside them.
|
||||
|
||||
* **Inlines can't contain no text.** Any inline node whose text is an empty string (`''`) will be automatically removed. This makes sense when you think about a user backspacing through an inline. When they delete that last character, they'd expect the inline to be removed. And when there are no characters, you can't really put your selection into the inline anymore. So Slate removes them from the document automatically, to simplify things.
|
||||
|
||||
* **Text nodes can't be adjacent to other text nodes.** Any two adjacent text nodes will automatically be merged into one. This prevents ambiguous cases where a cursor could be at the end of one text node or at the start of the next. However, you can have an inline node surrounded by two texts.
|
||||
|
||||
* **Blocks and inlines must always contain at least one text node.** This is to ensure that the user's cursor can always "enter" the nodes and to make sure that ranges can be created referencing them.
|
||||
|
||||
Slate enforces all of these restrictions for you automatically. Any time you [perform changes](./changes.md) to the document, Slate will check if the document is invalid, and if so, it will return it to a "normalized" value.
|
||||
|
||||
> 🙃 Fun fact: normalizing is actually based on the DOM's [`Node.normalize()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/normalize)!
|
||||
> 🙃 Fun fact: "normalizing" is actually based on the DOM's [`Node.normalize()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/normalize)!
|
||||
|
||||
In addition to documents, blocks and inlines, Slate introduces one other type of markup that the DOM doesn't have natively, the [`Mark`](../reference/slate/mark.md).
|
||||
|
||||
@@ -92,7 +90,7 @@ That all sounds pretty complex, but you don't have to think about it much, as lo
|
||||
|
||||
## Ranges, Points and "The Selection"
|
||||
|
||||
Just like in the DOM, you can reference a part of the document using a `Range`. And there's one special range that Slate keeps track of that refers to the user's current cursor selection, called the "selection".
|
||||
Just like in the DOM, you can reference a part of the document using a `Range`. And there's one special range that Slate keeps track of that refers to the user's current cursor selection, called the `Selection`.
|
||||
|
||||
Ranges are defined by two `Point`s, an "anchor" point and a "focus" point. The anchor is where the range starts, and the focus is where it ends. And each point is a combination of a "path" or "key" referencing a specific node, and an "offset". This ends up looking like this:
|
||||
|
||||
@@ -100,20 +98,11 @@ Ranges are defined by two `Point`s, an "anchor" point and a "focus" point. The a
|
||||
const range = Range.create({
|
||||
anchor: {
|
||||
key: 'node-a',
|
||||
offset: 0,
|
||||
},
|
||||
focus: {
|
||||
key: 'node-b',
|
||||
offset: 4,
|
||||
},
|
||||
})
|
||||
|
||||
const range = Range.create({
|
||||
anchor: {
|
||||
path: [0, 2, 1],
|
||||
offset: 0,
|
||||
},
|
||||
focus: {
|
||||
key: 'node-b',
|
||||
path: [0, 3, 2],
|
||||
offset: 4,
|
||||
},
|
||||
@@ -136,3 +125,41 @@ These `start` and `end` points are what most of your logic will be based on, sin
|
||||
One important thing to note is that the anchor and focus points of ranges **always reference the "leaf-most" text nodes** in a document. They never reference blocks or inlines, always their child text nodes. This is different than in the DOM API, but it makes dealing with ranges a _lot_ easier because there are less edge cases to handle.
|
||||
|
||||
> 📋 For more info, check out the [`Range` reference](../reference/slate/range.md).
|
||||
|
||||
The `Selection` model contains slightly more information than the simple `Range` model, because it needs to keep track of "focus" and "marks" for the user. For example:
|
||||
|
||||
```js
|
||||
const selection = Selection.create({
|
||||
anchor: {
|
||||
key: 'node-a',
|
||||
path: [0, 2, 1],
|
||||
offset: 0,
|
||||
},
|
||||
focus: {
|
||||
key: 'node-b',
|
||||
path: [0, 3, 2],
|
||||
offset: 4,
|
||||
},
|
||||
isFocused: true,
|
||||
marks: [{ type: 'bold' }],
|
||||
})
|
||||
```
|
||||
|
||||
However, keeping the `key` and `path` of ranges or selections in sync yourself is tedious. Instead, you can create selections using either and have the other automatically be inferred by the document. To do that, you use the `createRange` and `createSelection` methods:
|
||||
|
||||
```js
|
||||
const selection = document.createSelection({
|
||||
anchor: {
|
||||
key: 'node-a',
|
||||
offset: 0,
|
||||
},
|
||||
focus: {
|
||||
key: 'node-b',
|
||||
offset: 4,
|
||||
},
|
||||
isFocused: true,
|
||||
marks: [{ type: 'bold' }],
|
||||
})
|
||||
```
|
||||
|
||||
The resulting `selection` will have a both the `key` and `path` set for its points, with the `key` being used to look up the `path` in the document.
|
||||
|
@@ -24,7 +24,7 @@ const value = (
|
||||
</inline>{' '}
|
||||
editor!
|
||||
</block>
|
||||
<block type="image" data={{ src: 'https://...' }} isVoid />
|
||||
<block type="image" data={{ src: 'https://...' }} />
|
||||
</document>
|
||||
</value>
|
||||
)
|
||||
@@ -38,10 +38,7 @@ import { createHyperscript } from 'slate-hyperscript'
|
||||
const h = createHyperscript({
|
||||
blocks: {
|
||||
paragraph: 'paragraph',
|
||||
image: {
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
},
|
||||
image: 'image',
|
||||
},
|
||||
inlines: {
|
||||
link: 'link',
|
||||
@@ -83,6 +80,8 @@ The other export is a `createHyperscript` helper that you can use to create your
|
||||
blocks: Object,
|
||||
inlines: Object,
|
||||
marks: Object,
|
||||
decorations: Object,
|
||||
schema: Object,
|
||||
creators: Object,
|
||||
}
|
||||
```
|
||||
|
@@ -42,7 +42,7 @@ When the user pastes content into the editor, the core plugin handles all pastes
|
||||
|
||||
When the user makes a new selection in the DOM, the core plugin updates that selection in Slate's internal data model, re-rendering if it needs to.
|
||||
|
||||
### `render`
|
||||
### `renderEditor`
|
||||
|
||||
Renders all of the default contents of the editor!
|
||||
|
||||
|
@@ -136,7 +136,6 @@ If this function returns `true`, it can force updating the editor where otherwis
|
||||
renderMark: Function,
|
||||
renderNode: Function,
|
||||
renderPlaceholder: Function,
|
||||
renderPortal: Function,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -168,12 +167,6 @@ Render the placeholder that is shown when the editor has no `value`.
|
||||
|
||||
The `placeholder` prop that was passed to the editor can be found at `editor.props.placeholder`.
|
||||
|
||||
### `renderPortal`
|
||||
|
||||
`Function renderPortal(value: Value, editor: Editor) => ReactNode || Void`
|
||||
|
||||
Unlike the other renderProps, this one is mapped, so each plugin that returns something gets its own Portal. The return value is given as `children` to a `react-portal` `<Portal/>`.
|
||||
|
||||
## Other Properties
|
||||
|
||||
```js
|
||||
|
@@ -1,214 +0,0 @@
|
||||
# `slate-schema-violations`
|
||||
|
||||
```js
|
||||
import {
|
||||
CHILD_OBJECT_INVALID,
|
||||
CHILD_REQUIRED,
|
||||
CHILD_TYPE_INVALID,
|
||||
CHILD_UNKNOWN,
|
||||
FIRST_CHILD_OBJECT_INVALID,
|
||||
FIRST_CHILD_TYPE_INVALID,
|
||||
LAST_CHILD_OBJECT_INVALID,
|
||||
LAST_CHILD_TYPE_INVALID,
|
||||
NODE_DATA_INVALID,
|
||||
NODE_IS_VOID_INVALID,
|
||||
NODE_MARK_INVALID,
|
||||
NODE_TEXT_INVALID,
|
||||
PARENT_OBJECT_INVALID,
|
||||
PARENT_TYPE_INVALID,
|
||||
} from 'slate-schema-violations'
|
||||
```
|
||||
|
||||
A set of constants for the built-in violations in a Slate schema.
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
import React from 'react'
|
||||
import Types from 'slate-prop-types'
|
||||
|
||||
class Toolbar extends React.Component {
|
||||
|
||||
propTypes = {
|
||||
block: Types.block,
|
||||
schema: Types.schema.isRequired,
|
||||
value: Types.value.isRequired,
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Exports
|
||||
|
||||
### `CHILD_OBJECT_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
index: Number,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `object` property of a child node is invalid.
|
||||
|
||||
### `CHILD_REQUIRED`
|
||||
|
||||
```js
|
||||
{
|
||||
index: Number,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when a child node was required but none was found.
|
||||
|
||||
### `CHILD_TYPE_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
index: Number,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `type` property of a child node is invalid.
|
||||
|
||||
### `CHILD_UNKNOWN`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
index: Number,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when a child was not expected but one was found.
|
||||
|
||||
### `FIRST_CHILD_OBJECT_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `object` property of the first child node is invalid, when a specific `first` rule was defined in a schema.
|
||||
|
||||
### `FIRST_CHILD_TYPE_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `type` property of the first child node is invalid, when a specific `first` rule was defined in a schema.
|
||||
|
||||
### `LAST_CHILD_OBJECT_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `object` property of the last child node is invalid, when a specific `last` rule was defined in a schema.
|
||||
|
||||
### `LAST_CHILD_TYPE_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `type` property of the last child node is invalid, when a specific `last` rule was defined in a schema.
|
||||
|
||||
### `NODE_DATA_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
key: String,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
value: Mixed,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `data` property of a node contains an invalid entry.
|
||||
|
||||
### `NODE_IS_VOID_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `isVoid` property of a node is invalid.
|
||||
|
||||
### `NODE_MARK_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
mark: Mark,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when one of the marks in a node is invalid.
|
||||
|
||||
### `NODE_TEXT_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
text: String,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the text content of a node is invalid.
|
||||
|
||||
### `PARENT_OBJECT_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
node: Node,
|
||||
parent: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `object` property of the parent of a node is invalid, when a specific `parent` rule was defined in a schema.
|
||||
|
||||
### `PARENT_TYPE_INVALID`
|
||||
|
||||
```js
|
||||
{
|
||||
node: Node,
|
||||
parent: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `type` property of the parent of a node is invalid, when a specific `parent` rule was defined in a schema.
|
@@ -13,7 +13,6 @@ Block nodes may contain nested block nodes, inline nodes, and text nodes—just
|
||||
```js
|
||||
Block({
|
||||
data: Data,
|
||||
isVoid: Boolean,
|
||||
key: String,
|
||||
nodes: Immutable.List<Node>,
|
||||
type: String
|
||||
@@ -26,14 +25,6 @@ Block({
|
||||
|
||||
Arbitrary data associated with the node. Defaults to an empty `Map`.
|
||||
|
||||
### `isVoid`
|
||||
|
||||
`Boolean`
|
||||
|
||||
Whether the node is a "void" node, meaning that it has no child content (eg. images, videos, etc.). Defaults to `false`.
|
||||
|
||||
Note that even though a node may be "void", it will still contain a single, empty [`Text`](./text.md) node for consistency across other operations. However, when rendered by Slate that single [`Text`](./text.md) node will not be visible.
|
||||
|
||||
### `key`
|
||||
|
||||
`String`
|
||||
|
73
docs/reference/slate/decoration.md
Normal file
73
docs/reference/slate/decoration.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# `Decoration`
|
||||
|
||||
```js
|
||||
import { Decoration } from 'slate'
|
||||
```
|
||||
|
||||
A decoration is a range of the document that has a specific [`Mark`](./mark.md) dynamically applied to it based on its content or some other external state. It is not actually reflected in the document's structure itself. This can be useful for cases like syntax highlighting, or search result highlighting.
|
||||
|
||||
Decorations implement the [`Range`](./range.md) interface, but also contain a `mark`.
|
||||
|
||||
## Properties
|
||||
|
||||
```js
|
||||
Decoration({
|
||||
anchor: Point,
|
||||
focus: Point,
|
||||
mark: Mark,
|
||||
})
|
||||
```
|
||||
|
||||
### `mark`
|
||||
|
||||
`Mark`
|
||||
|
||||
The mark associated with the decoration.
|
||||
|
||||
### `object`
|
||||
|
||||
`String`
|
||||
|
||||
A string with a value of `'decoration'`.
|
||||
|
||||
## Static Methods
|
||||
|
||||
### `Decoration.create`
|
||||
|
||||
`Decoration.create(properties: Object) => Decoration`
|
||||
|
||||
Create a new `Decoration` instance with `properties`.
|
||||
|
||||
### `Decoration.createProperties`
|
||||
|
||||
`Decoration.createProperties(object: Object|Decoration) => Object`
|
||||
|
||||
Create a new dictionary of range properties from an `object`.
|
||||
|
||||
### `Decoration.fromJSON`
|
||||
|
||||
`Decoration.fromJSON(object: Object) => Decoration`
|
||||
|
||||
Create a range from a JSON `object`.
|
||||
|
||||
### `Decoration.isDecoration`
|
||||
|
||||
`Decoration.isDecoration(value: Any) => Boolean`
|
||||
|
||||
Check whether a `value` is a `Decoration`.
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `toJSON`
|
||||
|
||||
`toJSON() => Object`
|
||||
|
||||
Return a JSON representation of the range.
|
||||
|
||||
## Mutating Methods
|
||||
|
||||
### `setMark`
|
||||
|
||||
`setMark(mark: Mark) => Decoration`
|
||||
|
||||
Return a new decoration with a new `mark`.
|
@@ -13,7 +13,6 @@ Inline nodes may contain nested inline nodes and text nodes—just like in the D
|
||||
```js
|
||||
Inline({
|
||||
data: Data,
|
||||
isVoid: Boolean,
|
||||
key: String,
|
||||
nodes: Immutable.List<Node>,
|
||||
type: String
|
||||
@@ -26,14 +25,6 @@ Inline({
|
||||
|
||||
Arbitrary data associated with the node. Defaults to an empty `Map`.
|
||||
|
||||
### `isVoid`
|
||||
|
||||
`Boolean`
|
||||
|
||||
Whether the node is a "void" node, meaning that it has no child content (eg. emoji, icons, etc.). Defaults to `false`.
|
||||
|
||||
Note that even though a node may be "void", it will still contain a single, empty [`Text`](./text.md) node for consistency across other operations. However, when rendered by Slate that single [`Text`](./text.md) node will not be visible.
|
||||
|
||||
### `key`
|
||||
|
||||
`String`
|
||||
|
@@ -13,10 +13,10 @@ There are a handful of Slate operation types. The goal is to have the fewest pos
|
||||
```js
|
||||
{
|
||||
type: 'insert_text',
|
||||
path: Array,
|
||||
path: List,
|
||||
offset: Number,
|
||||
text: String,
|
||||
marks: Array,
|
||||
marks: List,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -27,7 +27,7 @@ Inserts a `text` string at `offset` into a text node at `path`, with optional `m
|
||||
```js
|
||||
{
|
||||
type: 'remove_text',
|
||||
path: Array,
|
||||
path: List,
|
||||
offset: Number,
|
||||
text: String,
|
||||
}
|
||||
@@ -42,10 +42,10 @@ Removes a string of `text` at `offset` into a text node at `path`.
|
||||
```js
|
||||
{
|
||||
type: 'add_mark',
|
||||
path: Array,
|
||||
path: List,
|
||||
offset: Number,
|
||||
length: Number,
|
||||
mark: Object,
|
||||
mark: Mark,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -56,10 +56,10 @@ Adds a `mark` to the text node at `path` starting at an `offset` and spanning `l
|
||||
```js
|
||||
{
|
||||
type: 'remove_mark',
|
||||
path: Array,
|
||||
path: List,
|
||||
offset: Number,
|
||||
length: Number,
|
||||
mark: Object,
|
||||
mark: Mark,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -70,10 +70,10 @@ Removes a `mark` from a text node at `path` starting at an `offset` and spanning
|
||||
```js
|
||||
{
|
||||
type: 'set_mark',
|
||||
path: Array,
|
||||
path: List,
|
||||
offset: Number,
|
||||
length: Number,
|
||||
mark: Object,
|
||||
mark: Mark,
|
||||
properties: Object,
|
||||
}
|
||||
```
|
||||
@@ -87,8 +87,8 @@ Set new `properties` on any marks that match an existing `mark` in a text node a
|
||||
```js
|
||||
{
|
||||
type: 'insert_node',
|
||||
path: Array,
|
||||
node: Object,
|
||||
path: List,
|
||||
node: Node,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -99,7 +99,7 @@ Insert a new `node` at `path`.
|
||||
```js
|
||||
{
|
||||
type: 'merge_node',
|
||||
path: Array,
|
||||
path: List,
|
||||
position: Number,
|
||||
properties: Object,
|
||||
}
|
||||
@@ -112,7 +112,7 @@ Merge the node at `path` with its previous sibling. The `position` refers to eit
|
||||
```js
|
||||
{
|
||||
type: 'move_node',
|
||||
path: Array,
|
||||
path: List,
|
||||
newPath: Array,
|
||||
}
|
||||
```
|
||||
@@ -124,8 +124,8 @@ Move the node at `path` to a `newPath`.
|
||||
```js
|
||||
{
|
||||
type: 'remove_node',
|
||||
path: Array,
|
||||
node: Object,
|
||||
path: List,
|
||||
node: Node,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -136,9 +136,9 @@ Remove the node at `path`.
|
||||
```js
|
||||
{
|
||||
type: 'set_node',
|
||||
path: Array,
|
||||
path: List,
|
||||
properties: Object,
|
||||
node: Object,
|
||||
node: Node,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -149,7 +149,7 @@ Set new `properties` on the node at `path`.
|
||||
```js
|
||||
{
|
||||
type: 'split_node',
|
||||
path: Array,
|
||||
path: List,
|
||||
position: Number,
|
||||
target: Number,
|
||||
properties: Object,
|
||||
@@ -166,7 +166,7 @@ Split the node at `path` at `position`. The `position` refers to either the inde
|
||||
{
|
||||
type: 'set_selection',
|
||||
properties: Object,
|
||||
selection: Object,
|
||||
selection: Selection,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -178,7 +178,7 @@ Set new `properties` on the selection.
|
||||
{
|
||||
type: 'set_value',
|
||||
properties: Object,
|
||||
value: Object,
|
||||
value: Value,
|
||||
}
|
||||
```
|
||||
|
||||
|
@@ -171,3 +171,9 @@ Return a new point with a new `offset`.
|
||||
`setPath(path: List|Array|Null) => Point`
|
||||
|
||||
Return a new point with a new `path`.
|
||||
|
||||
### `unset`
|
||||
|
||||
`unset() => Point`
|
||||
|
||||
Return a new point with the key, path, and offset all set to `null`.
|
||||
|
@@ -10,15 +10,14 @@ The "anchor" is the fixed point in a range, and the "focus" is the non-fixed poi
|
||||
|
||||
Often times, you don't need to specifically know which point is the "anchor" and which is the "focus", and you just need to know which comes first and last in the document. For these cases, there are many convenience equivalent properties and methods referring to the "start" and "end" points.
|
||||
|
||||
The `Range` model is also used as an interface and implemented by the [`Decoration`](./decoration.md) and [`Selection`](./selection.md) models.
|
||||
|
||||
## Properties
|
||||
|
||||
```js
|
||||
Range({
|
||||
anchor: Point,
|
||||
focus: Point,
|
||||
isAtomic: Boolean,
|
||||
isFocused: Boolean,
|
||||
marks: Set,
|
||||
})
|
||||
```
|
||||
|
||||
@@ -34,24 +33,6 @@ The range's anchor point.
|
||||
|
||||
The range's focus point.
|
||||
|
||||
### `isAtomic`
|
||||
|
||||
`Boolean`
|
||||
|
||||
Whether the range is atomic (for decorations only).
|
||||
|
||||
### `isFocused`
|
||||
|
||||
`Boolean`
|
||||
|
||||
Whether the range currently has focus.
|
||||
|
||||
### `marks`
|
||||
|
||||
`Set`
|
||||
|
||||
A set of marks associated with the range.
|
||||
|
||||
### `object`
|
||||
|
||||
`String`
|
||||
@@ -72,12 +53,6 @@ Either the `anchor` or the `focus` point, depending on which comes last in the d
|
||||
|
||||
Whether the range is backward. A range is considered "backward" when its focus point references a location earlier in the document than its anchor point.
|
||||
|
||||
### `isBlurred`
|
||||
|
||||
`Boolean`
|
||||
|
||||
The opposite of `isFocused`, for convenience.
|
||||
|
||||
### `isCollapsed`
|
||||
|
||||
`Boolean`
|
||||
@@ -224,24 +199,6 @@ Return a new range with a new `end` point.
|
||||
|
||||
Return a new range with a new `focus` point.
|
||||
|
||||
### `setIsAtomic`
|
||||
|
||||
`setIsAtomic(isAtomic: Boolean) => Range`
|
||||
|
||||
Return a new range with a new `isAtomic` value.
|
||||
|
||||
### `setIsFocused`
|
||||
|
||||
`setIsFocused(isFocused: Boolean) => Range`
|
||||
|
||||
Return a new range with a new `isFocused` value.
|
||||
|
||||
### `setMarks`
|
||||
|
||||
`setMarks(marks: Set|Null) => Range`
|
||||
|
||||
Return a new range with a new set of `marks`.
|
||||
|
||||
### `setProperties`
|
||||
|
||||
`setProperties(properties: Object|Range) => Range`
|
||||
@@ -253,3 +210,9 @@ Return a new range with new `properties` set.
|
||||
`setStart(start: Point) => Range`
|
||||
|
||||
Return a new range with a new `start` point.
|
||||
|
||||
### `unset`
|
||||
|
||||
`unset() => Range`
|
||||
|
||||
Return a new range with both of its point unset.
|
||||
|
@@ -134,7 +134,7 @@ Will validate the first child node against a [`match`](#match).
|
||||
}
|
||||
```
|
||||
|
||||
Will validate a node's `isVoid` property.
|
||||
Will determine whether the node is treated as a "void" node or not, making its content a black box that Slate doesn't control editing for.
|
||||
|
||||
### `last`
|
||||
|
||||
@@ -277,8 +277,177 @@ Returns a boolean if the passed in argument is a `Schema`.
|
||||
|
||||
Returns a JSON representation of the schema.
|
||||
|
||||
## Normalizing
|
||||
## Errors
|
||||
|
||||
When supplying your own `normalize` property for a schema rule, it will be called with `(change, error)`. The error `code` will be one of a set of potential code strings, and it will contain additional helpful properties depending on the type of error.
|
||||
|
||||
A set of the invalid violation strings are available as constants via the [`slate-schema-violations`](../slate-schema-violations/index.md) package.
|
||||
### `'child_object_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
index: Number,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `object` property of a child node is invalid.
|
||||
|
||||
### `'child_required'`
|
||||
|
||||
```js
|
||||
{
|
||||
index: Number,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when a child node was required but none was found.
|
||||
|
||||
### `'child_type_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
index: Number,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `type` property of a child node is invalid.
|
||||
|
||||
### `'child_unknown'`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
index: Number,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when a child was not expected but one was found.
|
||||
|
||||
### `'first_child_object_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `object` property of the first child node is invalid, when a specific `first` rule was defined in a schema.
|
||||
|
||||
### `'first_child_type_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `type` property of the first child node is invalid, when a specific `first` rule was defined in a schema.
|
||||
|
||||
### `'last_child_object_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `object` property of the last child node is invalid, when a specific `last` rule was defined in a schema.
|
||||
|
||||
### `'last_child_type_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
child: Node,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `type` property of the last child node is invalid, when a specific `last` rule was defined in a schema.
|
||||
|
||||
### `'node_data_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
key: String,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
value: Mixed,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `data` property of a node contains an invalid entry.
|
||||
|
||||
### `'node_is_void_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `isVoid` property of a node is invalid.
|
||||
|
||||
### `'node_mark_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
mark: Mark,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when one of the marks in a node is invalid.
|
||||
|
||||
### `'node_text_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
text: String,
|
||||
node: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the text content of a node is invalid.
|
||||
|
||||
### `'parent_object_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
node: Node,
|
||||
parent: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `object` property of the parent of a node is invalid, when a specific `parent` rule was defined in a schema.
|
||||
|
||||
### `'parent_type_invalid'`
|
||||
|
||||
```js
|
||||
{
|
||||
node: Node,
|
||||
parent: Node,
|
||||
rule: Object,
|
||||
}
|
||||
```
|
||||
|
||||
Raised when the `type` property of the parent of a node is invalid, when a specific `parent` rule was defined in a schema.
|
||||
|
92
docs/reference/slate/selection.md
Normal file
92
docs/reference/slate/selection.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# `Selection`
|
||||
|
||||
```js
|
||||
import { Selection } from 'slate'
|
||||
```
|
||||
|
||||
The user's current selection in a Slate [`Document`](./document.md). Selections implement the [`Range`](./range.md) interface, but also expose data about the current "focus" and the cursor current marks.
|
||||
|
||||
## Properties
|
||||
|
||||
```js
|
||||
Selection({
|
||||
anchor: Point,
|
||||
focus: Point,
|
||||
isFocused: Boolean,
|
||||
marks: Set,
|
||||
})
|
||||
```
|
||||
|
||||
### `isFocused`
|
||||
|
||||
`Boolean`
|
||||
|
||||
Whether the range currently has focus.
|
||||
|
||||
### `marks`
|
||||
|
||||
`Set`
|
||||
|
||||
A set of marks associated with the range.
|
||||
|
||||
### `object`
|
||||
|
||||
`String`
|
||||
|
||||
A string with a value of `'selection'`.
|
||||
|
||||
## Computed Properties
|
||||
|
||||
### `isBlurred`
|
||||
|
||||
`Boolean`
|
||||
|
||||
The opposite of `isFocused`, for convenience.
|
||||
|
||||
## Static Methods
|
||||
|
||||
### `Selection.create`
|
||||
|
||||
`Selection.create(properties: Object) => Selection`
|
||||
|
||||
Create a new `Selection` instance with `properties`.
|
||||
|
||||
### `Selection.createProperties`
|
||||
|
||||
`Selection.createProperties(object: Object|Selection) => Object`
|
||||
|
||||
Create a new dictionary of range properties from an `object`.
|
||||
|
||||
### `Selection.fromJSON`
|
||||
|
||||
`Selection.fromJSON(object: Object) => Selection`
|
||||
|
||||
Create a range from a JSON `object`.
|
||||
|
||||
### `Selection.isSelection`
|
||||
|
||||
`Selection.isSelection(value: Any) => Boolean`
|
||||
|
||||
Check whether a `value` is a `Selection`.
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `toJSON`
|
||||
|
||||
`toJSON() => Object`
|
||||
|
||||
Return a JSON representation of the range.
|
||||
|
||||
## Mutating Methods
|
||||
|
||||
### `setIsFocused`
|
||||
|
||||
`setIsFocused(isFocused: Boolean) => Selection`
|
||||
|
||||
Return a new range with a new `isFocused` value.
|
||||
|
||||
### `setMarks`
|
||||
|
||||
`setMarks(marks: Set|Null) => Selection`
|
||||
|
||||
Return a new range with a new set of `marks`.
|
@@ -1,22 +1,28 @@
|
||||
# Utils
|
||||
|
||||
```js
|
||||
import { resetKeyGenerator, setKeyGenerator } from 'slate'
|
||||
import { KeyUtils } from 'slate'
|
||||
```
|
||||
|
||||
Utility functions that ship with Slate that may be useful for certain use cases.
|
||||
|
||||
## Functions
|
||||
## Key Utils
|
||||
|
||||
### `resetKeyGenerator`
|
||||
### `KeyUtils.create`
|
||||
|
||||
`resetKeyGenerator() => Void`
|
||||
`create() => String`
|
||||
|
||||
Create a new key using the current key generator.
|
||||
|
||||
### `KeyUtils.resetGenerator`
|
||||
|
||||
`resetGenerator() => Void`
|
||||
|
||||
Resets Slate's internal key generating function to its default state. This is useful for server-side rendering, or anywhere you want to ensure fresh, deterministic creation of keys.
|
||||
|
||||
### `setKeyGenerator`
|
||||
### `KeyUtils.setGenerator`
|
||||
|
||||
`setKeyGenerator(generator: Function) => Void`
|
||||
`setGenerator(generator: Function) => Void`
|
||||
|
||||
Allows you to specify your own key generating function, instead of using Slate's built-in default generator which simply uses auto-incrementing number strings. (eg. `'0'`, `'1'`, `'2'`, ...)
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
import { Value } from 'slate'
|
||||
```
|
||||
|
||||
A `Value` is the top-level representation of data in Slate, containing both a [`Document`](./document.md) and a selection [`Range`](./range.md). It's what you need to pass into the Slate [`<Editor>`](../slate-react/editor.md) to render something onto the page.
|
||||
A `Value` is the top-level representation of data in Slate, containing both a [`Document`](./document.md) and a [`Selection`](./selection.md). It's what you need to pass into the Slate [`<Editor>`](../slate-react/editor.md) to render something onto the page.
|
||||
|
||||
All changes to the document and selection are also performed through the value object, so that they can stay in sync, and be propagated to its internal history of undo/redo value.
|
||||
|
||||
@@ -15,11 +15,11 @@ For convenience, in addition to changes, many of the selection and document prop
|
||||
```js
|
||||
Value({
|
||||
document: Document,
|
||||
selection: Range,
|
||||
selection: Selection,
|
||||
history: History,
|
||||
schema: Schema,
|
||||
data: Data,
|
||||
decorations: List<Ranges>|Null,
|
||||
decorations: List<Decoration>,
|
||||
})
|
||||
```
|
||||
|
||||
@@ -31,7 +31,7 @@ An object containing arbitrary data for the value.
|
||||
|
||||
### `decorations`
|
||||
|
||||
`List<Ranges>|Null`
|
||||
`List<Decoration>`
|
||||
|
||||
A list of ranges in the document with marks that aren't part of the content itself—like matches for the current search string.
|
||||
|
||||
@@ -61,7 +61,7 @@ An object representing the schema of the value's document.
|
||||
|
||||
### `selection`
|
||||
|
||||
`Range`
|
||||
`Selection`
|
||||
|
||||
The current selection of the value.
|
||||
|
||||
|
@@ -22,6 +22,20 @@ class Embeds extends React.Component {
|
||||
value: Value.fromJSON(initialValue),
|
||||
}
|
||||
|
||||
/**
|
||||
* The editor's schema.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
schema = {
|
||||
blocks: {
|
||||
video: {
|
||||
isVoid: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the app.
|
||||
*
|
||||
@@ -33,6 +47,7 @@ class Embeds extends React.Component {
|
||||
<Editor
|
||||
placeholder="Enter some text..."
|
||||
value={this.state.value}
|
||||
schema={this.schema}
|
||||
onChange={this.onChange}
|
||||
renderNode={this.renderNode}
|
||||
/>
|
||||
|
@@ -19,7 +19,6 @@
|
||||
{
|
||||
"object": "block",
|
||||
"type": "video",
|
||||
"isVoid": true,
|
||||
"data": {
|
||||
"video": "https://www.youtube.com/embed/FaHEusBG20c"
|
||||
}
|
||||
|
@@ -67,6 +67,20 @@ class Emojis extends React.Component {
|
||||
value: Value.fromJSON(initialValue),
|
||||
}
|
||||
|
||||
/**
|
||||
* The editor's schema.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
schema = {
|
||||
inlines: {
|
||||
emoji: {
|
||||
isVoid: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the app.
|
||||
*
|
||||
@@ -86,6 +100,7 @@ class Emojis extends React.Component {
|
||||
<Editor
|
||||
placeholder="Write some 😍👋🎉..."
|
||||
value={this.state.value}
|
||||
schema={this.schema}
|
||||
onChange={this.onChange}
|
||||
renderNode={this.renderNode}
|
||||
/>
|
||||
@@ -147,7 +162,6 @@ class Emojis extends React.Component {
|
||||
change
|
||||
.insertInline({
|
||||
type: 'emoji',
|
||||
isVoid: true,
|
||||
data: { code },
|
||||
})
|
||||
.moveToStartOfNextText()
|
||||
|
@@ -17,7 +17,6 @@
|
||||
{
|
||||
"object": "inline",
|
||||
"type": "emoji",
|
||||
"isVoid": true,
|
||||
"data": {
|
||||
"code": "😃"
|
||||
}
|
||||
@@ -39,7 +38,6 @@
|
||||
{
|
||||
"object": "inline",
|
||||
"type": "emoji",
|
||||
"isVoid": true,
|
||||
"data": {
|
||||
"code": "🍔"
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { Editor } from 'slate-react'
|
||||
import { Block, Value } from 'slate'
|
||||
import { CHILD_REQUIRED, CHILD_TYPE_INVALID } from 'slate-schema-violations'
|
||||
|
||||
import React from 'react'
|
||||
import initialValue from './value.json'
|
||||
@@ -19,11 +18,11 @@ const schema = {
|
||||
],
|
||||
normalize: (change, { code, node, child, index }) => {
|
||||
switch (code) {
|
||||
case CHILD_TYPE_INVALID: {
|
||||
case 'child_type_invalid': {
|
||||
const type = index === 0 ? 'title' : 'paragraph'
|
||||
return change.setNodeByKey(child.key, type)
|
||||
}
|
||||
case CHILD_REQUIRED: {
|
||||
case 'child_required': {
|
||||
const block = Block.create(index === 0 ? 'title' : 'paragraph')
|
||||
return change.insertNodeByKey(node.key, index, block)
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { Editor, getEventRange, getEventTransfer } from 'slate-react'
|
||||
import { Block, Value } from 'slate'
|
||||
import { LAST_CHILD_TYPE_INVALID } from 'slate-schema-violations'
|
||||
|
||||
import React from 'react'
|
||||
import initialValue from './value.json'
|
||||
@@ -48,13 +47,12 @@ function insertImage(change, src, target) {
|
||||
|
||||
change.insertBlock({
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
data: { src },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* A schema to enforce that there's always a paragraph as the last block.
|
||||
* The editor's schema.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
@@ -64,13 +62,18 @@ const schema = {
|
||||
last: { type: 'paragraph' },
|
||||
normalize: (change, { code, node, child }) => {
|
||||
switch (code) {
|
||||
case LAST_CHILD_TYPE_INVALID: {
|
||||
case 'last_child_type_invalid': {
|
||||
const paragraph = Block.create('paragraph')
|
||||
return change.insertNodeByKey(node.key, node.nodes.size, paragraph)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
blocks: {
|
||||
image: {
|
||||
isVoid: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -19,7 +19,6 @@
|
||||
{
|
||||
"object": "block",
|
||||
"type": "image",
|
||||
"isVoid": true,
|
||||
"data": {
|
||||
"src":
|
||||
"https://img.washingtonpost.com/wp-apps/imrs.php?src=https://img.washingtonpost.com/news/speaking-of-science/wp-content/uploads/sites/36/2015/10/as12-49-7278-1024x1024.jpg&w=1484"
|
||||
|
@@ -112,7 +112,6 @@ const RULES = [
|
||||
return {
|
||||
object: 'block',
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
nodes: next(el.childNodes),
|
||||
data: {
|
||||
src: el.getAttribute('src'),
|
||||
@@ -163,6 +162,20 @@ class PasteHtml extends React.Component {
|
||||
value: Value.fromJSON(initialValue),
|
||||
}
|
||||
|
||||
/**
|
||||
* The editor's schema.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
schema = {
|
||||
blocks: {
|
||||
image: {
|
||||
isVoid: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Render.
|
||||
*
|
||||
@@ -174,6 +187,7 @@ class PasteHtml extends React.Component {
|
||||
<Editor
|
||||
placeholder="Paste in some HTML..."
|
||||
value={this.state.value}
|
||||
schema={this.schema}
|
||||
onPaste={this.onPaste}
|
||||
onChange={this.onChange}
|
||||
renderNode={this.renderNode}
|
||||
|
@@ -89,8 +89,7 @@
|
||||
"slate": "*",
|
||||
"slate-html-serializer": "*",
|
||||
"slate-plain-serializer": "*",
|
||||
"slate-react": "*",
|
||||
"slate-schema-violations": "*"
|
||||
"slate-react": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"benchmark": "cross-env COMPARE=compare node --expose-gc ./tmp/benchmark/index.js",
|
||||
|
@@ -11,6 +11,5 @@ Slate's codebase is monorepo managed with [Lerna](https://lernajs.io/). It consi
|
||||
| [`slate-plain-serializer`](./slate-plain-serializer) | [](./slate-plain-serializer/package.json) | [](https://unpkg.com/slate-plain-serializer/dist/slate-plain-serializer.min.js) | A plain text serializer for Slate documents. |
|
||||
| [`slate-prop-types`](./slate-prop-types) | [](./slate-prop-types/package.json) | [](https://unpkg.com/slate-prop-types/dist/slate-prop-types.min.js) | React prop types for checking Slate values. |
|
||||
| [`slate-react`](./slate-react) | [](./slate-react/package.json) | [](https://unpkg.com/slate-react/dist/slate-react.min.js) | React components for rendering Slate editors. |
|
||||
| [`slate-schema-violations`](./slate-schema-violations) | [](./slate-schema-violations/package.json) | [](https://unpkg.com/slate-schema-violations/dist/slate-schema-violations.min.js) | Constants for the built-in schema violations. |
|
||||
| [`slate-simulator`](./slate-simulator) | [](./slate-simulator/package.json) | [](https://unpkg.com/slate-simulator/dist/slate-simulator.min.js) | A simulator for testing Slate editors and plugins. |
|
||||
| [`slate-hotkeys`](./slate-hotkeys) | [](./slate-hotkeys/package.json) | [](https://unpkg.com/slate-hotkeys/dist/slate-hotkeys.min.js) | Detect common keypresses in a platform-agnostic way |
|
||||
|
@@ -1 +0,0 @@
|
||||
This package contains the logger that Slate uses to log warnings and deprecations only when in development environments.
|
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "slate-dev-logger",
|
||||
"description": "INTERNAL: A simple, development-only logger for Slate.",
|
||||
"version": "0.1.43",
|
||||
"license": "MIT",
|
||||
"repository": "git://github.com/ianstormtaylor/slate.git",
|
||||
"main": "lib/slate-dev-logger.js",
|
||||
"module": "lib/slate-dev-logger.es.js",
|
||||
"umd": "dist/slate-dev-logger.js",
|
||||
"umdMin": "dist/slate-dev-logger.min.js",
|
||||
"files": [
|
||||
"dist/",
|
||||
"lib/"
|
||||
],
|
||||
"devDependencies": {
|
||||
"mocha": "^2.5.3"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rm -rf ./dist ./lib ./node_modules"
|
||||
}
|
||||
}
|
@@ -1,110 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
/**
|
||||
* Is deprecate interface forbidden?
|
||||
*/
|
||||
|
||||
const FORBID_DEPRECATE =
|
||||
process && process.env && process.env.FORBID_DEPRECATIONS
|
||||
|
||||
/**
|
||||
* Is warning scenarios forbidden?
|
||||
*/
|
||||
|
||||
const FORBID_WARNING = process && process.env && process.env.FORBID_WARNINGS
|
||||
|
||||
/**
|
||||
* Is in development?
|
||||
*
|
||||
* @type {Boolean}
|
||||
*/
|
||||
|
||||
const IS_DEV =
|
||||
typeof process !== 'undefined' &&
|
||||
process.env &&
|
||||
process.env.NODE_ENV !== 'production'
|
||||
|
||||
/**
|
||||
* Has console?
|
||||
*
|
||||
* @type {Boolean}
|
||||
*/
|
||||
|
||||
const HAS_CONSOLE =
|
||||
typeof console != 'undefined' &&
|
||||
typeof console.log == 'function' &&
|
||||
typeof console.warn == 'function' &&
|
||||
typeof console.error == 'function'
|
||||
|
||||
/**
|
||||
* Log a `message` at `level`.
|
||||
*
|
||||
* @param {String} level
|
||||
* @param {String} message
|
||||
* @param {Any} ...args
|
||||
*/
|
||||
|
||||
function log(level, message, ...args) {
|
||||
if (!IS_DEV) {
|
||||
return
|
||||
}
|
||||
|
||||
if (HAS_CONSOLE) {
|
||||
console[level](message, ...args)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an error `message`.
|
||||
*
|
||||
* @param {String} message
|
||||
* @param {Any} ...args
|
||||
*/
|
||||
|
||||
function error(message, ...args) {
|
||||
if (HAS_CONSOLE) {
|
||||
console.error(message, ...args)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a warning `message` in development only.
|
||||
*
|
||||
* @param {String} message
|
||||
* @param {Any} ...args
|
||||
*/
|
||||
|
||||
function warn(message, ...args) {
|
||||
const logger = FORBID_WARNING ? forbidden : log
|
||||
logger('warn', `Warning: ${message}`, ...args)
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a deprecation warning `message`, with helpful `version` number in
|
||||
* development only.
|
||||
*
|
||||
* @param {String} version
|
||||
* @param {String} message
|
||||
* @param {Any} ...args
|
||||
*/
|
||||
|
||||
function deprecate(version, message, ...args) {
|
||||
const logger = FORBID_DEPRECATE ? forbidden : log
|
||||
logger('warn', `Deprecation (${version}): ${message}`, ...args)
|
||||
}
|
||||
|
||||
function forbidden(level, message) {
|
||||
throw new Error(message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Export.
|
||||
*
|
||||
* @type {Function}
|
||||
*/
|
||||
|
||||
export default {
|
||||
deprecate,
|
||||
error,
|
||||
warn,
|
||||
}
|
1
packages/slate-dev-warning/Readme.md
Normal file
1
packages/slate-dev-warning/Readme.md
Normal file
@@ -0,0 +1 @@
|
||||
This package contains the warning logger that Slate uses to log warnings and deprecations only when in development environments.
|
21
packages/slate-dev-warning/package.json
Normal file
21
packages/slate-dev-warning/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "slate-dev-warning",
|
||||
"description": "INTERNAL: A simple, development-only warning helper for Slate.",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"repository": "git://github.com/ianstormtaylor/slate.git",
|
||||
"main": "lib/slate-dev-warning.js",
|
||||
"module": "lib/slate-dev-warning.es.js",
|
||||
"umd": "dist/slate-dev-warning.js",
|
||||
"umdMin": "dist/slate-dev-warning.min.js",
|
||||
"files": [
|
||||
"dist/",
|
||||
"lib/"
|
||||
],
|
||||
"devDependencies": {
|
||||
"mocha": "^2.5.3"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rm -rf ./dist ./lib ./node_modules"
|
||||
}
|
||||
}
|
19
packages/slate-dev-warning/src/index.js
Normal file
19
packages/slate-dev-warning/src/index.js
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* A `warning` helper, modeled after Facebook's and the `tiny-invariant` library.
|
||||
*
|
||||
* @param {Mixed} condition
|
||||
* @param {String} message
|
||||
*/
|
||||
|
||||
export default function warning(condition, message = '') {
|
||||
if (condition) return
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production'
|
||||
const log = console.warn || console.log // eslint-disable-line no-console
|
||||
|
||||
if (isProduction) {
|
||||
log('Warning')
|
||||
} else {
|
||||
log(`Warning: ${message}`)
|
||||
}
|
||||
}
|
@@ -4,6 +4,14 @@ This document maintains a list of changes to the `slate-html-serializer` package
|
||||
|
||||
---
|
||||
|
||||
### `0.7.0` — August 22, 2018
|
||||
|
||||
###### BREAKING
|
||||
|
||||
**Remove all previously deprecated code paths.** This helps to reduce some of the complexity in Slate by not having to handle these code paths anymore. And it helps to reduce file size. When upgrading, it's _highly_ recommended that you upgrade to the previous version first and ensure there are no deprecation warnings being logged, then upgrade to this version.
|
||||
|
||||
---
|
||||
|
||||
### `0.6.0` — March 22, 2018
|
||||
|
||||
###### BREAKING
|
||||
|
@@ -13,7 +13,6 @@
|
||||
"lib/"
|
||||
],
|
||||
"dependencies": {
|
||||
"slate-dev-logger": "^0.1.43",
|
||||
"type-of": "^2.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@@ -144,7 +144,6 @@ class Html {
|
||||
const block = {
|
||||
object: 'block',
|
||||
data: {},
|
||||
isVoid: false,
|
||||
...defaultBlock,
|
||||
nodes: [node],
|
||||
}
|
||||
@@ -159,7 +158,6 @@ class Html {
|
||||
{
|
||||
object: 'block',
|
||||
data: {},
|
||||
isVoid: false,
|
||||
...defaultBlock,
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -11,7 +11,6 @@ export const config = {
|
||||
return {
|
||||
object: 'block',
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ export const config = {
|
||||
return {
|
||||
object: 'inline',
|
||||
type: 'emoji',
|
||||
isVoid: true,
|
||||
nodes: next(el.childNodes),
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,6 @@ export const config = {
|
||||
return {
|
||||
object: 'inline',
|
||||
type: 'linebreak',
|
||||
isVoid: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,6 @@ export const config = {
|
||||
return {
|
||||
object: 'block',
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,23 +12,14 @@ const h = createHyperscript({
|
||||
paragraph: 'paragraph',
|
||||
quote: 'quote',
|
||||
code: 'code',
|
||||
image: {
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
},
|
||||
image: 'image',
|
||||
},
|
||||
inlines: {
|
||||
link: 'link',
|
||||
hashtag: 'hashtag',
|
||||
comment: 'comment',
|
||||
emoji: {
|
||||
type: 'emoji',
|
||||
isVoid: true,
|
||||
},
|
||||
linebreak: {
|
||||
type: 'linebreak',
|
||||
isVoid: true,
|
||||
},
|
||||
emoji: 'emoji',
|
||||
linebreak: 'linebreak',
|
||||
},
|
||||
marks: {
|
||||
b: 'bold',
|
||||
|
@@ -4,6 +4,14 @@ This document maintains a list of changes to the `slate-hyperscript` package wit
|
||||
|
||||
---
|
||||
|
||||
### `0.10.0` — August 22, 2018
|
||||
|
||||
###### BREAKING
|
||||
|
||||
**Remove all previously deprecated code paths.** This helps to reduce some of the complexity in Slate by not having to handle these code paths anymore. And it helps to reduce file size. When upgrading, it's _highly_ recommended that you upgrade to the previous version first and ensure there are no deprecation warnings being logged, then upgrade to this version.
|
||||
|
||||
---
|
||||
|
||||
### `0.9.0` — August 22, 2018
|
||||
|
||||
###### NEW
|
||||
|
@@ -13,9 +13,7 @@
|
||||
"lib/"
|
||||
],
|
||||
"dependencies": {
|
||||
"is-empty": "^1.0.0",
|
||||
"is-plain-object": "^2.0.4",
|
||||
"slate-dev-logger": "^0.1.43"
|
||||
"is-plain-object": "^2.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"slate": ">=0.37.0"
|
||||
|
@@ -7,7 +7,6 @@ import {
|
||||
Mark,
|
||||
Node,
|
||||
Point,
|
||||
Schema,
|
||||
Selection,
|
||||
Text,
|
||||
Value,
|
||||
@@ -173,7 +172,6 @@ const CREATORS = {
|
||||
|
||||
value(tagName, attributes, children) {
|
||||
const { data, normalize = true } = attributes
|
||||
const schema = Schema.create(attributes.schema || {})
|
||||
const document = children.find(Document.isDocument)
|
||||
let selection = children.find(Selection.isSelection) || Selection.create()
|
||||
let anchor
|
||||
@@ -263,7 +261,7 @@ const CREATORS = {
|
||||
}
|
||||
|
||||
let value = Value.fromJSON(
|
||||
{ data, document, selection, schema },
|
||||
{ data, document, selection, ...attributes },
|
||||
{ normalize }
|
||||
)
|
||||
|
||||
@@ -471,19 +469,19 @@ function resolveCreators(options) {
|
||||
}
|
||||
|
||||
Object.keys(blocks).map(key => {
|
||||
creators[key] = normalizeNode(key, blocks[key], 'block')
|
||||
creators[key] = normalizeNode(blocks[key], 'block')
|
||||
})
|
||||
|
||||
Object.keys(inlines).map(key => {
|
||||
creators[key] = normalizeNode(key, inlines[key], 'inline')
|
||||
creators[key] = normalizeNode(inlines[key], 'inline')
|
||||
})
|
||||
|
||||
Object.keys(marks).map(key => {
|
||||
creators[key] = normalizeMark(key, marks[key])
|
||||
creators[key] = normalizeMark(marks[key])
|
||||
})
|
||||
|
||||
Object.keys(decorations).map(key => {
|
||||
creators[key] = normalizeNode(key, decorations[key], 'decoration')
|
||||
creators[key] = normalizeNode(decorations[key], 'decoration')
|
||||
})
|
||||
|
||||
creators.value = (tagName, attributes = {}, children) => {
|
||||
@@ -495,15 +493,14 @@ function resolveCreators(options) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a node creator with `key` and `value`, of `object`.
|
||||
* Normalize a node creator of `value` and `object`.
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {Function|Object|String} value
|
||||
* @param {String} object
|
||||
* @return {Function}
|
||||
*/
|
||||
|
||||
function normalizeNode(key, value, object) {
|
||||
function normalizeNode(value, object) {
|
||||
if (typeof value == 'function') {
|
||||
return value
|
||||
}
|
||||
@@ -514,11 +511,11 @@ function normalizeNode(key, value, object) {
|
||||
|
||||
if (isPlainObject(value)) {
|
||||
return (tagName, attributes, children) => {
|
||||
const { key: attrKey, ...rest } = attributes
|
||||
const { key, ...rest } = attributes
|
||||
const attrs = {
|
||||
...value,
|
||||
object,
|
||||
key: attrKey,
|
||||
key,
|
||||
data: {
|
||||
...(value.data || {}),
|
||||
...rest,
|
||||
@@ -535,14 +532,13 @@ function normalizeNode(key, value, object) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a mark creator with `key` and `value`.
|
||||
* Normalize a mark creator of `value`.
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {Function|Object|String} value
|
||||
* @return {Function}
|
||||
*/
|
||||
|
||||
function normalizeMark(key, value) {
|
||||
function normalizeMark(value) {
|
||||
if (typeof value == 'function') {
|
||||
return value
|
||||
}
|
||||
|
@@ -33,7 +33,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -51,7 +50,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -37,7 +37,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -36,13 +36,11 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'ul',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
object: 'block',
|
||||
type: 'li',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -60,7 +58,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'li',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -37,7 +37,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -33,7 +33,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -51,7 +50,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -33,7 +33,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -51,7 +50,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -15,7 +15,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -28,7 +28,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -35,7 +35,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '3',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -53,7 +52,6 @@ export const output = {
|
||||
object: 'inline',
|
||||
key: '1',
|
||||
type: 'link',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -86,7 +84,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '7',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -104,7 +101,6 @@ export const output = {
|
||||
object: 'inline',
|
||||
key: '5',
|
||||
type: 'link',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -31,7 +31,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -51,7 +50,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '3',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -31,7 +31,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -51,7 +50,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '3',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -31,7 +31,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -51,7 +50,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '3',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -52,7 +51,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '3',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -72,7 +70,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '5',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -52,7 +51,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '3',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -72,7 +70,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '5',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -52,7 +51,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '3',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -72,7 +70,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '5',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -28,7 +28,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -28,7 +28,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -28,7 +28,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -34,7 +34,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '4',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -50,7 +49,6 @@ export const output = {
|
||||
object: 'inline',
|
||||
key: '1',
|
||||
type: 'link',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '4',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -50,7 +49,6 @@ export const output = {
|
||||
object: 'inline',
|
||||
key: '1',
|
||||
type: 'link',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '4',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -50,7 +49,6 @@ export const output = {
|
||||
object: 'inline',
|
||||
key: '1',
|
||||
type: 'link',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -5,10 +5,7 @@ import { createHyperscript } from 'slate-hyperscript'
|
||||
const h = createHyperscript({
|
||||
blocks: {
|
||||
paragraph: 'paragraph',
|
||||
image: {
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
},
|
||||
image: 'image',
|
||||
},
|
||||
inlines: {
|
||||
link: 'link',
|
||||
@@ -39,7 +36,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -71,7 +67,6 @@ export const output = {
|
||||
{
|
||||
object: 'inline',
|
||||
type: 'link',
|
||||
isVoid: false,
|
||||
data: {
|
||||
src: 'http://slatejs.org',
|
||||
},
|
||||
@@ -103,7 +98,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
data: {
|
||||
src: 'https://...',
|
||||
},
|
||||
|
@@ -40,7 +40,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -60,7 +59,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '3',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -37,7 +37,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '1',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -17,7 +17,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -20,7 +20,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -20,7 +20,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -32,7 +32,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '0',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -24,7 +24,6 @@ export const output = {
|
||||
object: 'block',
|
||||
key: '4',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -43,7 +42,6 @@ export const output = {
|
||||
key: '1',
|
||||
type: 'link',
|
||||
data: {},
|
||||
isVoid: false,
|
||||
nodes: [
|
||||
{
|
||||
object: 'text',
|
||||
|
@@ -12,7 +12,7 @@ export const input = (
|
||||
</inline>{' '}
|
||||
editor!
|
||||
</block>
|
||||
<block type="image" data={{ src: 'https://...' }} isVoid />
|
||||
<block type="image" data={{ src: 'https://...' }} />
|
||||
</document>
|
||||
</value>
|
||||
)
|
||||
@@ -26,7 +26,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'paragraph',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
@@ -58,7 +57,6 @@ export const output = {
|
||||
{
|
||||
object: 'inline',
|
||||
type: 'link',
|
||||
isVoid: false,
|
||||
data: {
|
||||
src: 'http://slatejs.org',
|
||||
},
|
||||
@@ -90,7 +88,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
data: {
|
||||
src: 'https://...',
|
||||
},
|
||||
|
@@ -4,6 +4,14 @@ This document maintains a list of changes to the `slate-plain-serializer` packag
|
||||
|
||||
---
|
||||
|
||||
### `0.6.0` — August 22, 2018
|
||||
|
||||
###### BREAKING
|
||||
|
||||
**Remove all previously deprecated code paths.** This helps to reduce some of the complexity in Slate by not having to handle these code paths anymore. And it helps to reduce file size. When upgrading, it's _highly_ recommended that you upgrade to the previous version first and ensure there are no deprecation warnings being logged, then upgrade to this version.
|
||||
|
||||
---
|
||||
|
||||
### `0.5.0` — January 4, 2018
|
||||
|
||||
###### BREAKING
|
||||
|
@@ -12,9 +12,6 @@
|
||||
"dist/",
|
||||
"lib/"
|
||||
],
|
||||
"dependencies": {
|
||||
"slate-dev-logger": "^0.1.43"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"immutable": ">=3.8.1",
|
||||
"slate": ">=0.32.0"
|
||||
|
@@ -31,7 +31,6 @@ function deserialize(string, options = {}) {
|
||||
return {
|
||||
...defaultBlock,
|
||||
object: 'block',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -11,7 +11,6 @@ export const output = {
|
||||
{
|
||||
object: 'block',
|
||||
type: 'line',
|
||||
isVoid: false,
|
||||
data: {},
|
||||
nodes: [
|
||||
{
|
||||
|
@@ -12,19 +12,13 @@ const h = createHyperscript({
|
||||
paragraph: 'paragraph',
|
||||
quote: 'quote',
|
||||
code: 'code',
|
||||
image: {
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
},
|
||||
image: 'image',
|
||||
},
|
||||
inlines: {
|
||||
link: 'link',
|
||||
hashtag: 'hashtag',
|
||||
comment: 'comment',
|
||||
emoji: {
|
||||
type: 'emoji',
|
||||
isVoid: true,
|
||||
},
|
||||
emoji: 'emoji',
|
||||
},
|
||||
marks: {
|
||||
b: 'bold',
|
||||
|
@@ -12,9 +12,6 @@
|
||||
"dist/",
|
||||
"lib/"
|
||||
],
|
||||
"dependencies": {
|
||||
"slate-dev-logger": "^0.1.43"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"immutable": ">=3.8.1",
|
||||
"slate": ">=0.32.0"
|
||||
|
@@ -4,6 +4,14 @@ This document maintains a list of changes to the `slate-react` package with each
|
||||
|
||||
---
|
||||
|
||||
### `0.18.0` — August 22, 2018
|
||||
|
||||
###### BREAKING
|
||||
|
||||
**Remove all previously deprecated code paths.** This helps to reduce some of the complexity in Slate by not having to handle these code paths anymore. And it helps to reduce file size. When upgrading, it's _highly_ recommended that you upgrade to the previous version first and ensure there are no deprecation warnings being logged, then upgrade to this version.
|
||||
|
||||
---
|
||||
|
||||
### `0.17.0` — August 22, 2018
|
||||
|
||||
###### NEW
|
||||
|
@@ -16,16 +16,14 @@
|
||||
"debug": "^3.1.0",
|
||||
"get-window": "^1.1.1",
|
||||
"is-window": "^1.0.2",
|
||||
"keycode": "^2.1.2",
|
||||
"lodash": "^4.1.1",
|
||||
"memoize-one": "^4.0.0",
|
||||
"prop-types": "^15.5.8",
|
||||
"react-immutable-proptypes": "^2.1.0",
|
||||
"react-portal": "^3.1.0",
|
||||
"selection-is-backward": "^1.0.0",
|
||||
"slate-base64-serializer": "^0.2.60",
|
||||
"slate-dev-environment": "^0.2.0",
|
||||
"slate-dev-logger": "^0.1.43",
|
||||
"slate-dev-warning": "^0.0.0",
|
||||
"slate-hotkeys": "^0.2.3",
|
||||
"slate-plain-serializer": "^0.5.41",
|
||||
"slate-prop-types": "^0.4.58"
|
||||
|
@@ -2,9 +2,9 @@ import Debug from 'debug'
|
||||
import React from 'react'
|
||||
import Types from 'prop-types'
|
||||
import getWindow from 'get-window'
|
||||
import { IS_FIREFOX, HAS_INPUT_EVENTS_LEVEL_2 } from 'slate-dev-environment'
|
||||
import logger from 'slate-dev-logger'
|
||||
import warning from 'slate-dev-warning'
|
||||
import throttle from 'lodash/throttle'
|
||||
import { IS_FIREFOX, HAS_INPUT_EVENTS_LEVEL_2 } from 'slate-dev-environment'
|
||||
|
||||
import EVENT_HANDLERS from '../constants/event-handlers'
|
||||
import Node from './node'
|
||||
@@ -37,7 +37,6 @@ class Content extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
autoCorrect: Types.bool.isRequired,
|
||||
children: Types.any.isRequired,
|
||||
className: Types.string,
|
||||
editor: Types.object.isRequired,
|
||||
readOnly: Types.bool.isRequired,
|
||||
@@ -165,10 +164,11 @@ class Content extends React.Component {
|
||||
const range = findDOMRange(selection, window)
|
||||
|
||||
if (!range) {
|
||||
logger.error(
|
||||
'Unable to find a native DOM range from the current selection.',
|
||||
{ selection }
|
||||
warning(
|
||||
false,
|
||||
'Unable to find a native DOM range from the current selection.'
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -426,7 +426,6 @@ class Content extends React.Component {
|
||||
data-gramm={false}
|
||||
>
|
||||
{children}
|
||||
{this.props.children}
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
@@ -1,9 +1,8 @@
|
||||
import Debug from 'debug'
|
||||
import Portal from 'react-portal'
|
||||
import React from 'react'
|
||||
import SlateTypes from 'slate-prop-types'
|
||||
import Types from 'prop-types'
|
||||
import logger from 'slate-dev-logger'
|
||||
import warning from 'slate-dev-warning'
|
||||
import { Schema, Stack } from 'slate'
|
||||
import memoizeOne from 'memoize-one'
|
||||
|
||||
@@ -136,11 +135,10 @@ class Editor extends React.Component {
|
||||
|
||||
// If we've resolved a few times already, and it's exactly in line with
|
||||
// the updates, then warn the user that they may be doing something wrong.
|
||||
if (resolves > 5 && resolves === updates) {
|
||||
logger.warn(
|
||||
warning(
|
||||
resolves < 5 || resolves !== updates,
|
||||
'A Slate <Editor> component is re-resolving `props.plugins` or `props.schema` on each update, which leads to poor performance. This is often due to passing in a new `schema` or `plugins` prop with each render by declaring them inline in your render function. Do not do this!'
|
||||
)
|
||||
}
|
||||
|
||||
if (change) {
|
||||
this.onChange(change)
|
||||
@@ -155,16 +153,7 @@ class Editor extends React.Component {
|
||||
|
||||
render() {
|
||||
debug('render', this)
|
||||
|
||||
const children = this.stack
|
||||
.map('renderPortal', this.value, this)
|
||||
.map((child, i) => (
|
||||
<Portal key={i} isOpened>
|
||||
{child}
|
||||
</Portal>
|
||||
))
|
||||
|
||||
const props = { ...this.props, children }
|
||||
const props = { ...this.props }
|
||||
const tree = this.stack.render('renderEditor', props, this)
|
||||
return tree
|
||||
}
|
||||
@@ -231,7 +220,8 @@ class Editor extends React.Component {
|
||||
|
||||
change = (...args) => {
|
||||
if (this.tmp.isChanging) {
|
||||
logger.warn(
|
||||
warning(
|
||||
false,
|
||||
"The `editor.change` method was called from within an existing `editor.change` callback. This is not allowed, and often due to calling `editor.change` directly from a plugin's event handler which is unnecessary."
|
||||
)
|
||||
|
||||
|
@@ -143,13 +143,13 @@ class Leaf extends React.Component {
|
||||
text === '' &&
|
||||
parent.object === 'block' &&
|
||||
parent.text === '' &&
|
||||
parent.nodes.size === 1
|
||||
parent.nodes.last() === node
|
||||
) {
|
||||
return <span data-slate-zero-width="n">{'\u200B'}</span>
|
||||
}
|
||||
|
||||
// COMPAT: If the text is empty, it's because it's on the edge of an inline
|
||||
// void node, so we render a zero-width space so that the selection can be
|
||||
// node, so we render a zero-width space so that the selection can be
|
||||
// inserted next to it still.
|
||||
if (text === '') {
|
||||
return <span data-slate-zero-width="z">{'\u200B'}</span>
|
||||
|
@@ -2,7 +2,7 @@ import Debug from 'debug'
|
||||
import ImmutableTypes from 'react-immutable-proptypes'
|
||||
import React from 'react'
|
||||
import SlateTypes from 'slate-prop-types'
|
||||
import logger from 'slate-dev-logger'
|
||||
import warning from 'slate-dev-warning'
|
||||
import Types from 'prop-types'
|
||||
|
||||
import Void from './void'
|
||||
@@ -81,12 +81,11 @@ class Node extends React.Component {
|
||||
return true
|
||||
}
|
||||
|
||||
if (shouldUpdate === false) {
|
||||
logger.warn(
|
||||
warning(
|
||||
shouldUpdate !== false,
|
||||
"Returning false in `shouldNodeComponentUpdate` does not disable Slate's internal `shouldComponentUpdate` logic. If you want to prevent updates, use React's `shouldComponentUpdate` instead."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// If the `readOnly` status has changed, re-render in case there is any
|
||||
// user-land logic that depends on it, like nested editable contents.
|
||||
|
@@ -64,7 +64,7 @@ function AfterPlugin() {
|
||||
event.preventDefault()
|
||||
|
||||
const { value } = change
|
||||
const { selection } = value
|
||||
const { document, selection, schema } = value
|
||||
const range = findRange(targetRange, value)
|
||||
|
||||
switch (event.inputType) {
|
||||
@@ -101,7 +101,12 @@ function AfterPlugin() {
|
||||
|
||||
case 'insertLineBreak':
|
||||
case 'insertParagraph': {
|
||||
if (change.value.isInVoid) {
|
||||
const hasVoidParent = document.hasVoidParent(
|
||||
selection.start.path,
|
||||
schema
|
||||
)
|
||||
|
||||
if (hasVoidParent) {
|
||||
change.moveToStartOfNextText()
|
||||
} else {
|
||||
change.splitBlockAtRange(range)
|
||||
@@ -450,13 +455,14 @@ function AfterPlugin() {
|
||||
debug('onKeyDown', { event })
|
||||
|
||||
const { value } = change
|
||||
const { schema } = value
|
||||
const { document, selection, schema } = value
|
||||
const hasVoidParent = document.hasVoidParent(selection.start.path, schema)
|
||||
|
||||
// COMPAT: In iOS, some of these hotkeys are handled in the
|
||||
// `onNativeBeforeInput` handler of the `<Content>` component in order to
|
||||
// preserve native autocorrect behavior, so they shouldn't be handled here.
|
||||
if (Hotkeys.isSplitBlock(event) && !IS_IOS) {
|
||||
return value.isInVoid
|
||||
return hasVoidParent
|
||||
? change.moveToStartOfNextText()
|
||||
: change.splitBlock()
|
||||
}
|
||||
@@ -520,44 +526,44 @@ function AfterPlugin() {
|
||||
// an inline is selected, we need to handle these hotkeys manually because
|
||||
// browsers won't know what to do.
|
||||
if (Hotkeys.isMoveBackward(event)) {
|
||||
const { document, isInVoid, previousText, startText } = value
|
||||
const { previousText, startText } = value
|
||||
const isPreviousInVoid =
|
||||
previousText && document.hasVoidParent(previousText.key, schema)
|
||||
|
||||
if (isInVoid || isPreviousInVoid || startText.text == '') {
|
||||
if (hasVoidParent || isPreviousInVoid || startText.text == '') {
|
||||
event.preventDefault()
|
||||
return change.moveBackward()
|
||||
}
|
||||
}
|
||||
|
||||
if (Hotkeys.isMoveForward(event)) {
|
||||
const { document, isInVoid, nextText, startText } = value
|
||||
const { nextText, startText } = value
|
||||
const isNextInVoid =
|
||||
nextText && document.hasVoidParent(nextText.key, schema)
|
||||
|
||||
if (isInVoid || isNextInVoid || startText.text == '') {
|
||||
if (hasVoidParent || isNextInVoid || startText.text == '') {
|
||||
event.preventDefault()
|
||||
return change.moveForward()
|
||||
}
|
||||
}
|
||||
|
||||
if (Hotkeys.isExtendBackward(event)) {
|
||||
const { document, isInVoid, previousText, startText } = value
|
||||
const { previousText, startText } = value
|
||||
const isPreviousInVoid =
|
||||
previousText && document.hasVoidParent(previousText.key, schema)
|
||||
|
||||
if (isInVoid || isPreviousInVoid || startText.text == '') {
|
||||
if (hasVoidParent || isPreviousInVoid || startText.text == '') {
|
||||
event.preventDefault()
|
||||
return change.moveFocusBackward()
|
||||
}
|
||||
}
|
||||
|
||||
if (Hotkeys.isExtendForward(event)) {
|
||||
const { document, isInVoid, nextText, startText } = value
|
||||
const { nextText, startText } = value
|
||||
const isNextInVoid =
|
||||
nextText && document.hasVoidParent(nextText.key, schema)
|
||||
|
||||
if (isInVoid || isNextInVoid || startText.text == '') {
|
||||
if (hasVoidParent || isNextInVoid || startText.text == '') {
|
||||
event.preventDefault()
|
||||
return change.moveFocusForward()
|
||||
}
|
||||
@@ -686,13 +692,11 @@ function AfterPlugin() {
|
||||
|
||||
function renderEditor(props, editor) {
|
||||
const { handlers } = editor
|
||||
|
||||
return (
|
||||
<Content
|
||||
{...handlers}
|
||||
autoCorrect={props.autoCorrect}
|
||||
className={props.className}
|
||||
children={props.children}
|
||||
editor={editor}
|
||||
readOnly={props.readOnly}
|
||||
role={props.role}
|
||||
|
@@ -12,19 +12,13 @@ const h = createHyperscript({
|
||||
paragraph: 'paragraph',
|
||||
quote: 'quote',
|
||||
code: 'code',
|
||||
image: {
|
||||
type: 'image',
|
||||
isVoid: true,
|
||||
},
|
||||
image: 'image',
|
||||
},
|
||||
inlines: {
|
||||
link: 'link',
|
||||
hashtag: 'hashtag',
|
||||
comment: 'comment',
|
||||
emoji: {
|
||||
type: 'emoji',
|
||||
isVoid: true,
|
||||
},
|
||||
emoji: 'emoji',
|
||||
},
|
||||
marks: {
|
||||
b: 'bold',
|
||||
|
16
packages/slate-react/test/helpers/schema.js
Normal file
16
packages/slate-react/test/helpers/schema.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Schema } from 'slate'
|
||||
|
||||
const schema = Schema.create({
|
||||
blocks: {
|
||||
image: {
|
||||
isVoid: true,
|
||||
},
|
||||
},
|
||||
inlines: {
|
||||
emoji: {
|
||||
isVoid: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default schema
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user