diff --git a/Changelog.md b/Changelog.md
index 47787189f..277ee433c 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -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)
diff --git a/benchmark/helpers/h.js b/benchmark/helpers/h.js
index 14e7f67c9..7413eb04d 100644
--- a/benchmark/helpers/h.js
+++ b/benchmark/helpers/h.js
@@ -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',
diff --git a/benchmark/slate/models/from-json-big.js b/benchmark/slate/models/from-json-big.js
index d5bd1ccfa..79eee4cef 100644
--- a/benchmark/slate/models/from-json-big.js
+++ b/benchmark/slate/models/from-json-big.js
@@ -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,
},
diff --git a/docs/Readme.md b/docs/Readme.md
index 773c95958..57ec93a42 100644
--- a/docs/Readme.md
+++ b/docs/Readme.md
@@ -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)
diff --git a/docs/general/changelog.md b/docs/general/changelog.md
index a58cdac5e..1e5e5fdc8 100644
--- a/docs/general/changelog.md
+++ b/docs/general/changelog.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)
diff --git a/docs/general/resources.md b/docs/general/resources.md
index 9139a6070..15057824c 100644
--- a/docs/general/resources.md
+++ b/docs/general/resources.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 cmd vs. ctrl 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 `` components.
-## Tooling
+## Tools
These tools are helpful when developing with Slate:
diff --git a/docs/guides/changes.md b/docs/guides/changes.md
index 8c4e36cc3..ec208dbad 100644
--- a/docs/guides/changes.md
+++ b/docs/guides/changes.md
@@ -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 },
})
}
diff --git a/docs/guides/data-model.md b/docs/guides/data-model.md
index 7d47e2707..b23e7e3a1 100644
--- a/docs/guides/data-model.md
+++ b/docs/guides/data-model.md
@@ -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.
diff --git a/docs/reference/slate-hyperscript/index.md b/docs/reference/slate-hyperscript/index.md
index 101b12a89..6496fa9f3 100644
--- a/docs/reference/slate-hyperscript/index.md
+++ b/docs/reference/slate-hyperscript/index.md
@@ -24,7 +24,7 @@ const value = (
{' '}
editor!
-
+
)
@@ -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,
}
```
diff --git a/docs/reference/slate-react/core-plugins.md b/docs/reference/slate-react/core-plugins.md
index e3275cd92..a02644f5f 100644
--- a/docs/reference/slate-react/core-plugins.md
+++ b/docs/reference/slate-react/core-plugins.md
@@ -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!
diff --git a/docs/reference/slate-react/plugins.md b/docs/reference/slate-react/plugins.md
index c854f899f..f76bc6771 100644
--- a/docs/reference/slate-react/plugins.md
+++ b/docs/reference/slate-react/plugins.md
@@ -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` ``.
-
## Other Properties
```js
diff --git a/docs/reference/slate-schema-violations/index.md b/docs/reference/slate-schema-violations/index.md
deleted file mode 100644
index a8879e949..000000000
--- a/docs/reference/slate-schema-violations/index.md
+++ /dev/null
@@ -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.
diff --git a/docs/reference/slate/block.md b/docs/reference/slate/block.md
index e7f9f8303..8af889ee0 100644
--- a/docs/reference/slate/block.md
+++ b/docs/reference/slate/block.md
@@ -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,
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`
diff --git a/docs/reference/slate/decoration.md b/docs/reference/slate/decoration.md
new file mode 100644
index 000000000..b41a679cc
--- /dev/null
+++ b/docs/reference/slate/decoration.md
@@ -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`.
diff --git a/docs/reference/slate/inline.md b/docs/reference/slate/inline.md
index 7a83d60cc..ca51e1455 100644
--- a/docs/reference/slate/inline.md
+++ b/docs/reference/slate/inline.md
@@ -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,
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`
diff --git a/docs/reference/slate/operation.md b/docs/reference/slate/operation.md
index aae8d163f..0abcc55a5 100644
--- a/docs/reference/slate/operation.md
+++ b/docs/reference/slate/operation.md
@@ -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,
}
```
diff --git a/docs/reference/slate/point.md b/docs/reference/slate/point.md
index 66c7154cf..d9597c3eb 100644
--- a/docs/reference/slate/point.md
+++ b/docs/reference/slate/point.md
@@ -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`.
diff --git a/docs/reference/slate/range.md b/docs/reference/slate/range.md
index 02cfcd9a2..746f73cbf 100644
--- a/docs/reference/slate/range.md
+++ b/docs/reference/slate/range.md
@@ -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.
diff --git a/docs/reference/slate/schema.md b/docs/reference/slate/schema.md
index 33f4615af..5fc3a7c0b 100644
--- a/docs/reference/slate/schema.md
+++ b/docs/reference/slate/schema.md
@@ -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.
diff --git a/docs/reference/slate/selection.md b/docs/reference/slate/selection.md
new file mode 100644
index 000000000..039a7efcb
--- /dev/null
+++ b/docs/reference/slate/selection.md
@@ -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`.
diff --git a/docs/reference/slate/utils.md b/docs/reference/slate/utils.md
index 3000e591f..9ac6ce131 100644
--- a/docs/reference/slate/utils.md
+++ b/docs/reference/slate/utils.md
@@ -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'`, ...)
diff --git a/docs/reference/slate/value.md b/docs/reference/slate/value.md
index 055029da8..285c3f10e 100644
--- a/docs/reference/slate/value.md
+++ b/docs/reference/slate/value.md
@@ -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 [``](../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 [``](../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|Null,
+ decorations: List,
})
```
@@ -31,7 +31,7 @@ An object containing arbitrary data for the value.
### `decorations`
-`List|Null`
+`List`
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.
diff --git a/examples/embeds/index.js b/examples/embeds/index.js
index 2154465ae..aa8253d5f 100644
--- a/examples/embeds/index.js
+++ b/examples/embeds/index.js
@@ -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 {
diff --git a/examples/embeds/value.json b/examples/embeds/value.json
index d22a2ad17..7c645cbdb 100644
--- a/examples/embeds/value.json
+++ b/examples/embeds/value.json
@@ -19,7 +19,6 @@
{
"object": "block",
"type": "video",
- "isVoid": true,
"data": {
"video": "https://www.youtube.com/embed/FaHEusBG20c"
}
diff --git a/examples/emojis/index.js b/examples/emojis/index.js
index 1b201df93..53f5cc373 100644
--- a/examples/emojis/index.js
+++ b/examples/emojis/index.js
@@ -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 {
@@ -147,7 +162,6 @@ class Emojis extends React.Component {
change
.insertInline({
type: 'emoji',
- isVoid: true,
data: { code },
})
.moveToStartOfNextText()
diff --git a/examples/emojis/value.json b/examples/emojis/value.json
index c242238eb..7b082e9d9 100644
--- a/examples/emojis/value.json
+++ b/examples/emojis/value.json
@@ -17,7 +17,6 @@
{
"object": "inline",
"type": "emoji",
- "isVoid": true,
"data": {
"code": "😃"
}
@@ -39,7 +38,6 @@
{
"object": "inline",
"type": "emoji",
- "isVoid": true,
"data": {
"code": "🍔"
}
diff --git a/examples/forced-layout/index.js b/examples/forced-layout/index.js
index 3b3dd876f..2f37ab7e6 100644
--- a/examples/forced-layout/index.js
+++ b/examples/forced-layout/index.js
@@ -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)
}
diff --git a/examples/images/index.js b/examples/images/index.js
index cb00c3ad7..7faf8652f 100644
--- a/examples/images/index.js
+++ b/examples/images/index.js
@@ -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,
+ },
+ },
}
/**
diff --git a/examples/images/value.json b/examples/images/value.json
index 6adbd450d..e534cb6f2 100644
--- a/examples/images/value.json
+++ b/examples/images/value.json
@@ -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"
diff --git a/examples/paste-html/index.js b/examples/paste-html/index.js
index d951cf898..22067d80a 100644
--- a/examples/paste-html/index.js
+++ b/examples/paste-html/index.js
@@ -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 {
=0.37.0"
diff --git a/packages/slate-hyperscript/src/index.js b/packages/slate-hyperscript/src/index.js
index 69d7bb3da..2b0dc1c50 100644
--- a/packages/slate-hyperscript/src/index.js
+++ b/packages/slate-hyperscript/src/index.js
@@ -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
}
diff --git a/packages/slate-hyperscript/test/decorations/across-blocks.js b/packages/slate-hyperscript/test/decorations/across-blocks.js
index 6263bc591..4d2b0f941 100644
--- a/packages/slate-hyperscript/test/decorations/across-blocks.js
+++ b/packages/slate-hyperscript/test/decorations/across-blocks.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/decorations/across-marks.js b/packages/slate-hyperscript/test/decorations/across-marks.js
index 3927cfa7f..edab064ff 100644
--- a/packages/slate-hyperscript/test/decorations/across-marks.js
+++ b/packages/slate-hyperscript/test/decorations/across-marks.js
@@ -37,7 +37,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/decorations/deep-anchors.js b/packages/slate-hyperscript/test/decorations/deep-anchors.js
index 68e4a9a8a..0792363aa 100644
--- a/packages/slate-hyperscript/test/decorations/deep-anchors.js
+++ b/packages/slate-hyperscript/test/decorations/deep-anchors.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/decorations/intersecting-marks.js b/packages/slate-hyperscript/test/decorations/intersecting-marks.js
index abab2f306..62ac8e385 100644
--- a/packages/slate-hyperscript/test/decorations/intersecting-marks.js
+++ b/packages/slate-hyperscript/test/decorations/intersecting-marks.js
@@ -37,7 +37,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/decorations/multiple.js b/packages/slate-hyperscript/test/decorations/multiple.js
index 0d014299f..282648521 100644
--- a/packages/slate-hyperscript/test/decorations/multiple.js
+++ b/packages/slate-hyperscript/test/decorations/multiple.js
@@ -32,7 +32,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/decorations/nested.js b/packages/slate-hyperscript/test/decorations/nested.js
index 30fe9e188..e6c4ad2ae 100644
--- a/packages/slate-hyperscript/test/decorations/nested.js
+++ b/packages/slate-hyperscript/test/decorations/nested.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/decorations/overlapping.js b/packages/slate-hyperscript/test/decorations/overlapping.js
index 943a71e61..89f03819d 100644
--- a/packages/slate-hyperscript/test/decorations/overlapping.js
+++ b/packages/slate-hyperscript/test/decorations/overlapping.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/block.js b/packages/slate-hyperscript/test/fixtures/block.js
index 091c71900..19719a687 100644
--- a/packages/slate-hyperscript/test/fixtures/block.js
+++ b/packages/slate-hyperscript/test/fixtures/block.js
@@ -15,7 +15,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-across-block.js b/packages/slate-hyperscript/test/fixtures/cursor-across-block.js
index 7a0892b51..1846f387b 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-across-block.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-across-block.js
@@ -28,7 +28,6 @@ export const output = {
object: 'block',
key: '1',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-and-inlines.js b/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-and-inlines.js
index caaa9c0b1..4467bf4c1 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-and-inlines.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-and-inlines.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-end.js b/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-end.js
index 008954890..ed313894a 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-end.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-end.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-middle.js b/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-middle.js
index ad85d392b..111f7fbde 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-middle.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-middle.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-start.js b/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-start.js
index f340708f2..9605f2288 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-start.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-across-blocks-start.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-end.js b/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-end.js
index d08d66746..7dfd4b45e 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-end.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-end.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-middle.js b/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-middle.js
index 4c8623a66..041c207ba 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-middle.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-middle.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-start.js b/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-start.js
index 81c539de3..fc46b0e54 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-start.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-across-multiple-blocks-start.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-block-end.js b/packages/slate-hyperscript/test/fixtures/cursor-block-end.js
index 2cbf4fa37..cf3d693f2 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-block-end.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-block-end.js
@@ -28,7 +28,6 @@ export const output = {
object: 'block',
key: '1',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-block-middle.js b/packages/slate-hyperscript/test/fixtures/cursor-block-middle.js
index 1afd625a2..7d8c6e51e 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-block-middle.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-block-middle.js
@@ -28,7 +28,6 @@ export const output = {
object: 'block',
key: '1',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-block-start.js b/packages/slate-hyperscript/test/fixtures/cursor-block-start.js
index 4339596eb..a35427084 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-block-start.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-block-start.js
@@ -28,7 +28,6 @@ export const output = {
object: 'block',
key: '1',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-custom-block-middle.js b/packages/slate-hyperscript/test/fixtures/cursor-custom-block-middle.js
index e9e066150..e52cd5bb1 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-custom-block-middle.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-custom-block-middle.js
@@ -34,7 +34,6 @@ export const output = {
object: 'block',
key: '1',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-inline-end.js b/packages/slate-hyperscript/test/fixtures/cursor-inline-end.js
index f3bd8ff21..315b53a85 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-inline-end.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-inline-end.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-inline-start.js b/packages/slate-hyperscript/test/fixtures/cursor-inline-start.js
index 1bb73d340..47050b1e2 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-inline-start.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-inline-start.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-inline.js b/packages/slate-hyperscript/test/fixtures/cursor-inline.js
index e4f60f6fb..aaaf9a609 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-inline.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-inline.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-mark-end.js b/packages/slate-hyperscript/test/fixtures/cursor-mark-end.js
index 5bfe61b2a..2c54f2c92 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-mark-end.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-mark-end.js
@@ -32,7 +32,6 @@ export const output = {
object: 'block',
key: '1',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-mark-start.js b/packages/slate-hyperscript/test/fixtures/cursor-mark-start.js
index 2ff45d3de..018df593c 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-mark-start.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-mark-start.js
@@ -32,7 +32,6 @@ export const output = {
object: 'block',
key: '1',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/cursor-mark.js b/packages/slate-hyperscript/test/fixtures/cursor-mark.js
index 26425f68e..9aff83f27 100644
--- a/packages/slate-hyperscript/test/fixtures/cursor-mark.js
+++ b/packages/slate-hyperscript/test/fixtures/cursor-mark.js
@@ -32,7 +32,6 @@ export const output = {
object: 'block',
key: '1',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/custom-tags.js b/packages/slate-hyperscript/test/fixtures/custom-tags.js
index a6c70cc45..b71da41d6 100644
--- a/packages/slate-hyperscript/test/fixtures/custom-tags.js
+++ b/packages/slate-hyperscript/test/fixtures/custom-tags.js
@@ -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://...',
},
diff --git a/packages/slate-hyperscript/test/fixtures/decoration-across-blocks.js b/packages/slate-hyperscript/test/fixtures/decoration-across-blocks.js
index 48f8d83ea..f47178ef0 100644
--- a/packages/slate-hyperscript/test/fixtures/decoration-across-blocks.js
+++ b/packages/slate-hyperscript/test/fixtures/decoration-across-blocks.js
@@ -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: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/decoration.js b/packages/slate-hyperscript/test/fixtures/decoration.js
index edbb35fff..db8f73730 100644
--- a/packages/slate-hyperscript/test/fixtures/decoration.js
+++ b/packages/slate-hyperscript/test/fixtures/decoration.js
@@ -37,7 +37,6 @@ export const output = {
object: 'block',
key: '1',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/mark-empty.js b/packages/slate-hyperscript/test/fixtures/mark-empty.js
index 91e943d42..d0986751c 100644
--- a/packages/slate-hyperscript/test/fixtures/mark-empty.js
+++ b/packages/slate-hyperscript/test/fixtures/mark-empty.js
@@ -17,7 +17,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/normalize-default.js b/packages/slate-hyperscript/test/fixtures/normalize-default.js
index 15fcde3c6..ea04f9175 100644
--- a/packages/slate-hyperscript/test/fixtures/normalize-default.js
+++ b/packages/slate-hyperscript/test/fixtures/normalize-default.js
@@ -20,7 +20,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/normalize-disabled.js b/packages/slate-hyperscript/test/fixtures/normalize-disabled.js
index 778b58bb9..d3ac87d3c 100644
--- a/packages/slate-hyperscript/test/fixtures/normalize-disabled.js
+++ b/packages/slate-hyperscript/test/fixtures/normalize-disabled.js
@@ -20,7 +20,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/selection.js b/packages/slate-hyperscript/test/fixtures/selection.js
index b1986f76c..a77081f19 100644
--- a/packages/slate-hyperscript/test/fixtures/selection.js
+++ b/packages/slate-hyperscript/test/fixtures/selection.js
@@ -32,7 +32,6 @@ export const output = {
object: 'block',
key: '0',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-hyperscript/test/fixtures/text-perserve-keys.js b/packages/slate-hyperscript/test/fixtures/text-perserve-keys.js
index d113892b6..79cd02107 100644
--- a/packages/slate-hyperscript/test/fixtures/text-perserve-keys.js
+++ b/packages/slate-hyperscript/test/fixtures/text-perserve-keys.js
@@ -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',
diff --git a/packages/slate-hyperscript/test/fixtures/with-marks-and-inlines.js b/packages/slate-hyperscript/test/fixtures/with-marks-and-inlines.js
index a2f6f2633..b61db5356 100644
--- a/packages/slate-hyperscript/test/fixtures/with-marks-and-inlines.js
+++ b/packages/slate-hyperscript/test/fixtures/with-marks-and-inlines.js
@@ -12,7 +12,7 @@ export const input = (
{' '}
editor!
-
+
)
@@ -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://...',
},
diff --git a/packages/slate-plain-serializer/Changelog.md b/packages/slate-plain-serializer/Changelog.md
index 58161f9be..476296411 100644
--- a/packages/slate-plain-serializer/Changelog.md
+++ b/packages/slate-plain-serializer/Changelog.md
@@ -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
diff --git a/packages/slate-plain-serializer/package.json b/packages/slate-plain-serializer/package.json
index 2a97f8ec7..e0064b615 100644
--- a/packages/slate-plain-serializer/package.json
+++ b/packages/slate-plain-serializer/package.json
@@ -12,9 +12,6 @@
"dist/",
"lib/"
],
- "dependencies": {
- "slate-dev-logger": "^0.1.43"
- },
"peerDependencies": {
"immutable": ">=3.8.1",
"slate": ">=0.32.0"
diff --git a/packages/slate-plain-serializer/src/index.js b/packages/slate-plain-serializer/src/index.js
index 2988d5a0b..7e8decf1b 100644
--- a/packages/slate-plain-serializer/src/index.js
+++ b/packages/slate-plain-serializer/src/index.js
@@ -31,7 +31,6 @@ function deserialize(string, options = {}) {
return {
...defaultBlock,
object: 'block',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-plain-serializer/test/deserialize/to-json.js b/packages/slate-plain-serializer/test/deserialize/to-json.js
index 55de12047..96813268e 100644
--- a/packages/slate-plain-serializer/test/deserialize/to-json.js
+++ b/packages/slate-plain-serializer/test/deserialize/to-json.js
@@ -11,7 +11,6 @@ export const output = {
{
object: 'block',
type: 'line',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate-plain-serializer/test/helpers/h.js b/packages/slate-plain-serializer/test/helpers/h.js
index 63c2dc01b..b23cd7df4 100644
--- a/packages/slate-plain-serializer/test/helpers/h.js
+++ b/packages/slate-plain-serializer/test/helpers/h.js
@@ -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',
diff --git a/packages/slate-prop-types/package.json b/packages/slate-prop-types/package.json
index 560c3b720..c07a627ef 100644
--- a/packages/slate-prop-types/package.json
+++ b/packages/slate-prop-types/package.json
@@ -12,9 +12,6 @@
"dist/",
"lib/"
],
- "dependencies": {
- "slate-dev-logger": "^0.1.43"
- },
"peerDependencies": {
"immutable": ">=3.8.1",
"slate": ">=0.32.0"
diff --git a/packages/slate-react/Changelog.md b/packages/slate-react/Changelog.md
index de1f1e388..1ede09a51 100644
--- a/packages/slate-react/Changelog.md
+++ b/packages/slate-react/Changelog.md
@@ -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
diff --git a/packages/slate-react/package.json b/packages/slate-react/package.json
index b0de573d1..93dd1f784 100644
--- a/packages/slate-react/package.json
+++ b/packages/slate-react/package.json
@@ -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"
diff --git a/packages/slate-react/src/components/content.js b/packages/slate-react/src/components/content.js
index 4610a9762..d809ab74c 100644
--- a/packages/slate-react/src/components/content.js
+++ b/packages/slate-react/src/components/content.js
@@ -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}
)
}
diff --git a/packages/slate-react/src/components/editor.js b/packages/slate-react/src/components/editor.js
index 983eba1bb..115abe820 100644
--- a/packages/slate-react/src/components/editor.js
+++ b/packages/slate-react/src/components/editor.js
@@ -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(
- 'A Slate 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!'
- )
- }
+ warning(
+ resolves < 5 || resolves !== updates,
+ 'A Slate 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) => (
-
- {child}
-
- ))
-
- 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."
)
diff --git a/packages/slate-react/src/components/leaf.js b/packages/slate-react/src/components/leaf.js
index c28eae670..6717558d2 100644
--- a/packages/slate-react/src/components/leaf.js
+++ b/packages/slate-react/src/components/leaf.js
@@ -143,13 +143,13 @@ class Leaf extends React.Component {
text === '' &&
parent.object === 'block' &&
parent.text === '' &&
- parent.nodes.size === 1
+ parent.nodes.last() === node
) {
return {'\u200B'}
}
// 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 {'\u200B'}
diff --git a/packages/slate-react/src/components/node.js b/packages/slate-react/src/components/node.js
index d65b90b8d..f6508553e 100644
--- a/packages/slate-react/src/components/node.js
+++ b/packages/slate-react/src/components/node.js
@@ -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,11 +81,10 @@ class Node extends React.Component {
return true
}
- if (shouldUpdate === false) {
- logger.warn(
- "Returning false in `shouldNodeComponentUpdate` does not disable Slate's internal `shouldComponentUpdate` logic. If you want to prevent updates, use React's `shouldComponentUpdate` instead."
- )
- }
+ 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
diff --git a/packages/slate-react/src/plugins/after.js b/packages/slate-react/src/plugins/after.js
index 0415d79ed..807a73029 100644
--- a/packages/slate-react/src/plugins/after.js
+++ b/packages/slate-react/src/plugins/after.js
@@ -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 `` 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 (
-
+
diff --git a/packages/slate-react/test/rendering/fixtures/empty-block-with-inline.js b/packages/slate-react/test/rendering/fixtures/empty-block-with-inline.js
deleted file mode 100644
index 2fb474e01..000000000
--- a/packages/slate-react/test/rendering/fixtures/empty-block-with-inline.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/** @jsx h */
-
-import h from '../../helpers/h'
-
-export const props = {}
-
-export const value = (
-
-
-
-
-
-
-
-)
-
-export const output = `
-
-
-
-
- \u200B
-
-
-
-
-`.trim()
diff --git a/packages/slate-react/test/rendering/fixtures/readonly-custom-block-void.js b/packages/slate-react/test/rendering/fixtures/readonly-custom-block-void.js
index 7babef31c..dad2dcbad 100644
--- a/packages/slate-react/test/rendering/fixtures/readonly-custom-block-void.js
+++ b/packages/slate-react/test/rendering/fixtures/readonly-custom-block-void.js
@@ -20,6 +20,13 @@ function renderNode(props) {
export const props = {
readOnly: true,
renderNode,
+ schema: {
+ blocks: {
+ image: {
+ isVoid: true,
+ },
+ },
+ },
}
export const value = (
diff --git a/packages/slate-react/test/rendering/fixtures/readonly-custom-inline-void.js b/packages/slate-react/test/rendering/fixtures/readonly-custom-inline-void.js
index 8d59a8d69..d52bee679 100644
--- a/packages/slate-react/test/rendering/fixtures/readonly-custom-inline-void.js
+++ b/packages/slate-react/test/rendering/fixtures/readonly-custom-inline-void.js
@@ -17,6 +17,13 @@ function renderNode(props) {
export const props = {
readOnly: true,
renderNode,
+ schema: {
+ inlines: {
+ emoji: {
+ isVoid: true,
+ },
+ },
+ },
}
export const value = (
@@ -44,7 +51,7 @@ export const output = `
-
+
diff --git a/packages/slate-schema-violations/Changelog.md b/packages/slate-schema-violations/Changelog.md
deleted file mode 100644
index 982f82689..000000000
--- a/packages/slate-schema-violations/Changelog.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Changelog
-
-This document maintains a list of changes to the `slate-schema-violations` package with each new version. Until `1.0.0` is released, breaking changes will be added as minor version bumps, and smaller changes won't be accounted for since the library is moving quickly.
-
----
-
-### `0.1.0` — January 26, 2018
-
-:tada:
diff --git a/packages/slate-schema-violations/Readme.md b/packages/slate-schema-violations/Readme.md
deleted file mode 100644
index a2eb946fb..000000000
--- a/packages/slate-schema-violations/Readme.md
+++ /dev/null
@@ -1 +0,0 @@
-This package contains a set of constants for the built-in violations in a Slate schema.
diff --git a/packages/slate-schema-violations/package.json b/packages/slate-schema-violations/package.json
deleted file mode 100644
index debacf050..000000000
--- a/packages/slate-schema-violations/package.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "slate-schema-violations",
- "description": "A set of constants for the built-in violations in a Slate schema.",
- "version": "0.1.39",
- "license": "MIT",
- "repository": "git://github.com/ianstormtaylor/slate.git",
- "main": "lib/slate-schema-violations.js",
- "module": "lib/slate-schema-violations.es.js",
- "umd": "dist/slate-schema-violations.js",
- "umdMin": "dist/slate-schema-violations.min.js",
- "files": [
- "dist/",
- "lib/"
- ],
- "devDependencies": {
- "mocha": "^2.5.3",
- "slate": "^0.39.3"
- },
- "scripts": {
- "clean": "rm -rf ./dist ./lib ./node_modules"
- },
- "keywords": [
- "constants",
- "schema",
- "slate",
- "violation"
- ]
-}
diff --git a/packages/slate-schema-violations/src/index.js b/packages/slate-schema-violations/src/index.js
deleted file mode 100644
index 560a4156f..000000000
--- a/packages/slate-schema-violations/src/index.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Schema violations.
- *
- * @type {String}
- */
-
-export const CHILD_OBJECT_INVALID = 'child_object_invalid'
-export const CHILD_REQUIRED = 'child_required'
-export const CHILD_TYPE_INVALID = 'child_type_invalid'
-export const CHILD_UNKNOWN = 'child_unknown'
-export const FIRST_CHILD_OBJECT_INVALID = 'first_child_object_invalid'
-export const FIRST_CHILD_TYPE_INVALID = 'first_child_type_invalid'
-export const LAST_CHILD_OBJECT_INVALID = 'last_child_object_invalid'
-export const LAST_CHILD_TYPE_INVALID = 'last_child_type_invalid'
-export const NEXT_SIBLING_OBJECT_INVALID = 'next_sibling_object_invalid'
-export const NEXT_SIBLING_TYPE_INVALID = 'next_sibling_type_invalid'
-export const NODE_DATA_INVALID = 'node_data_invalid'
-export const NODE_IS_VOID_INVALID = 'node_is_void_invalid'
-export const NODE_MARK_INVALID = 'node_mark_invalid'
-export const NODE_OBJECT_INVALID = 'node_object_invalid'
-export const NODE_TEXT_INVALID = 'node_text_invalid'
-export const NODE_TYPE_INVALID = 'node_type_invalid'
-export const PARENT_OBJECT_INVALID = 'parent_object_invalid'
-export const PARENT_TYPE_INVALID = 'parent_type_invalid'
-export const PREVIOUS_SIBLING_OBJECT_INVALID = 'previous_sibling_object_invalid'
-export const PREVIOUS_SIBLING_TYPE_INVALID = 'previous_sibling_type_invalid'
diff --git a/packages/slate-schema-violations/test/index.js b/packages/slate-schema-violations/test/index.js
deleted file mode 100644
index e69de29bb..000000000
diff --git a/packages/slate/Changelog.md b/packages/slate/Changelog.md
index c6e73612e..6fd5c8e73 100644
--- a/packages/slate/Changelog.md
+++ b/packages/slate/Changelog.md
@@ -4,6 +4,14 @@ A list of changes to the `slate` package with each new version. Until `1.0.0` is
---
+### `0.40.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.39.0` — August 22, 2018
###### NEW
diff --git a/packages/slate/package.json b/packages/slate/package.json
index bcb6bcf8a..a17214222 100644
--- a/packages/slate/package.json
+++ b/packages/slate/package.json
@@ -16,11 +16,9 @@
"debug": "^3.1.0",
"direction": "^0.1.5",
"esrever": "^0.2.0",
- "is-empty": "^1.0.0",
"is-plain-object": "^2.0.4",
"lodash": "^4.17.4",
- "slate-dev-logger": "^0.1.43",
- "slate-schema-violations": "^0.1.39",
+ "slate-dev-warning": "^0.0.0",
"type-of": "^2.0.1"
},
"peerDependencies": {
diff --git a/packages/slate/src/changes/at-current-range.js b/packages/slate/src/changes/at-current-range.js
index 46a474f7d..ad50e2925 100644
--- a/packages/slate/src/changes/at-current-range.js
+++ b/packages/slate/src/changes/at-current-range.js
@@ -1,4 +1,3 @@
-import logger from 'slate-dev-logger'
import Block from '../models/block'
import Inline from '../models/inline'
import Mark from '../models/mark'
@@ -49,24 +48,6 @@ PROXY_TRANSFORMS.forEach(method => {
}
})
-Changes.setBlock = (...args) => {
- logger.deprecate(
- 'slate@0.33.0',
- 'The `setBlock` method of Slate changes has been renamed to `setBlocks`.'
- )
-
- Changes.setBlocks(...args)
-}
-
-Changes.setInline = (...args) => {
- logger.deprecate(
- 'slate@0.33.0',
- 'The `setInline` method of Slate changes has been renamed to `setInlines`.'
- )
-
- Changes.setInlines(...args)
-}
-
/**
* Add a `mark` to the characters in the current selection.
*
diff --git a/packages/slate/src/changes/at-range.js b/packages/slate/src/changes/at-range.js
index eddb1fb44..d0f2c4afb 100644
--- a/packages/slate/src/changes/at-range.js
+++ b/packages/slate/src/changes/at-range.js
@@ -1,5 +1,4 @@
import { List } from 'immutable'
-import logger from 'slate-dev-logger'
import Block from '../models/block'
import Inline from '../models/inline'
import Mark from '../models/mark'
@@ -965,15 +964,6 @@ Changes.setBlocksAtRange = (change, range, properties, options = {}) => {
})
}
-Changes.setBlockAtRange = (...args) => {
- logger.deprecate(
- 'slate@0.33.0',
- 'The `setBlockAtRange` method of Slate changes has been renamed to `setBlocksAtRange`.'
- )
-
- Changes.setBlocksAtRange(...args)
-}
-
/**
* Set the `properties` of inline nodes in a `range`.
*
@@ -995,15 +985,6 @@ Changes.setInlinesAtRange = (change, range, properties, options = {}) => {
})
}
-Changes.setInlineAtRange = (...args) => {
- logger.deprecate(
- 'slate@0.33.0',
- 'The `setInlineAtRange` method of Slate changes has been renamed to `setInlinesAtRange`.'
- )
-
- Changes.setInlinesAtRange(...args)
-}
-
/**
* Split the block nodes at a `range`, to optional `height`.
*
@@ -1016,10 +997,9 @@ Changes.setInlineAtRange = (...args) => {
Changes.splitBlockAtRange = (change, range, height = 1, options = {}) => {
const normalize = change.getFlag('normalize', options)
-
const { start, end } = range
- const { value } = change
- const { document } = value
+ let { value } = change
+ let { document } = value
let node = document.assertDescendant(start.key)
let parent = document.getClosestBlock(node.key)
let h = 0
@@ -1034,15 +1014,20 @@ Changes.splitBlockAtRange = (change, range, height = 1, options = {}) => {
normalize: normalize && range.isCollapsed,
})
+ value = change.value
+ document = value.document
+
if (range.isExpanded) {
if (range.isBackward) range = range.flip()
- const nextBlock = change.value.document.getNextBlock(node.key)
+ const nextBlock = document.getNextBlock(node.key)
range = range.moveAnchorToStartOfNode(nextBlock)
+ range = range.setFocus(range.focus.setPath(null))
if (start.key === end.key) {
range = range.moveFocusTo(range.anchor.key, end.offset - start.offset)
}
+ range = document.resolveRange(range)
change.deleteAtRange(range, { normalize })
}
}
@@ -1130,7 +1115,7 @@ Changes.unwrapBlockAtRange = (change, range, properties, options = {}) => {
const normalize = change.getFlag('normalize', options)
const { value } = change
- let { document, schema } = value
+ let { document } = value
const blocks = document.getBlocksAtRange(range)
const wrappers = blocks
.map(block => {
@@ -1138,11 +1123,6 @@ Changes.unwrapBlockAtRange = (change, range, properties, options = {}) => {
if (parent.object != 'block') return false
if (properties.type != null && parent.type != properties.type)
return false
- if (
- properties.isVoid != null &&
- schema.isVoid(parent) != properties.isVoid
- )
- return false
if (properties.data != null && !parent.data.isSuperset(properties.data))
return false
return true
@@ -1232,7 +1212,7 @@ Changes.unwrapInlineAtRange = (change, range, properties, options = {}) => {
const normalize = change.getFlag('normalize', options)
const { value } = change
- const { document, schema } = value
+ const { document } = value
const texts = document.getTextsAtRange(range)
const inlines = texts
.map(text => {
@@ -1240,11 +1220,6 @@ Changes.unwrapInlineAtRange = (change, range, properties, options = {}) => {
if (parent.object != 'inline') return false
if (properties.type != null && parent.type != properties.type)
return false
- if (
- properties.isVoid != null &&
- schema.isVoid(parent) != properties.isVoid
- )
- return false
if (properties.data != null && !parent.data.isSuperset(properties.data))
return false
return true
@@ -1263,6 +1238,8 @@ Changes.unwrapInlineAtRange = (change, range, properties, options = {}) => {
normalize: false,
})
})
+
+ change.removeNodeByKey(inline.key, { normalize: false })
})
// TODO: optmize to only normalize the right block
diff --git a/packages/slate/src/changes/on-selection.js b/packages/slate/src/changes/on-selection.js
index 7e00054be..978d6459d 100644
--- a/packages/slate/src/changes/on-selection.js
+++ b/packages/slate/src/changes/on-selection.js
@@ -1,6 +1,4 @@
import { is } from 'immutable'
-import isEmpty from 'is-empty'
-import logger from 'slate-dev-logger'
import pick from 'lodash/pick'
import Selection from '../models/selection'
@@ -576,7 +574,7 @@ Changes.select = (change, properties, options = {}) => {
}
// If there are no new properties to set, abort to avoid extra operations.
- if (isEmpty(props)) {
+ if (Object.keys(props).lengtgh === 0) {
return
}
@@ -660,10 +658,10 @@ function pointBackward(change, point, n = 1) {
const { value } = change
const { document, selection, schema } = value
const p = selection[point]
- const isInVoid = document.hasVoidParent(p.path, schema)
+ const hasVoidParent = document.hasVoidParent(p.path, schema)
// what is this?
- if (!isInVoid && p.offset - n >= 0) {
+ if (!hasVoidParent && p.offset - n >= 0) {
const range = selection[`move${Point}Backward`](n)
change.select(range)
return
@@ -679,7 +677,7 @@ function pointBackward(change, point, n = 1) {
change[`move${Point}ToEndOfNode`](previous)
// when is this called?
- if (!isInVoid && !isPreviousInVoid && isInBlock) {
+ if (!hasVoidParent && !isPreviousInVoid && isInBlock) {
const range = change.value.selection[`move${Point}Backward`](n)
change.select(range)
}
@@ -694,10 +692,10 @@ function pointForward(change, point, n = 1) {
const { document, selection, schema } = value
const p = selection[point]
const text = document.getNode(p.path)
- const isInVoid = document.hasVoidParent(p.path, schema)
+ const hasVoidParent = document.hasVoidParent(p.path, schema)
// what is this?
- if (!isInVoid && p.offset + n <= text.text.length) {
+ if (!hasVoidParent && p.offset + n <= text.text.length) {
const range = selection[`move${Point}Forward`](n)
change.select(range)
return
@@ -712,112 +710,10 @@ function pointForward(change, point, n = 1) {
change[`move${Point}ToStartOfNode`](next)
// when is this called?
- if (!isInVoid && !isNextInVoid && isInBlock) {
+ if (!hasVoidParent && !isNextInVoid && isInBlock) {
const range = change.value.selection[`move${Point}Forward`](n)
change.select(range)
}
}
-/**
- * Deprecated.
- */
-
-Changes.moveOffsetsTo = (change, start, end = start) => {
- logger.deprecate(
- '0.37.0',
- 'The `Change.moveOffsetsTo` method is deprecated, please use `Change.moveAnchorTo` and `Change.moveFocusTo` instead.'
- )
-
- change.moveAnchorTo(start).moveFocusTo(end)
-}
-
-const DEPRECATEDS = [
- ['collapseCharBackward', 'moveBackward'],
- ['collapseCharForward', 'moveForward'],
- ['collapseLineBackward', 'moveLineBackward'],
- ['collapseLineForward', 'moveLineForward'],
- ['collapseTo', 'moveTo'],
- ['collapseToAnchor', 'moveToAnchor'],
- ['collapseToEnd', 'moveToEnd'],
- ['collapseToEndOf', 'moveToEndOfNode'],
- ['collapseToEndOfBlock', 'moveToEndOfBlock'],
- ['collapseToEndOfNextBlock', 'moveToEndOfNextBlock'],
- ['collapseToEndOfNextInline', 'moveToEndOfNextInline'],
- ['collapseToEndOfNextText', 'moveToEndOfNextText'],
- ['collapseToEndOfPreviousBlock', 'moveToEndOfPreviousBlock'],
- ['collapseToEndOfPreviousInline', 'moveToEndOfPreviousInline'],
- ['collapseToEndOfPreviousText', 'moveToEndOfPreviousText'],
- ['collapseToFocus', 'moveToFocus'],
- ['collapseToStart', 'moveToStart'],
- ['collapseToStartOf', 'moveToStartOfNode'],
- ['collapseToStartOfBlock', 'moveToStartOfBlock'],
- ['collapseToStartOfNextBlock', 'moveToStartOfNextBlock'],
- ['collapseToStartOfNextInline', 'moveToStartOfNextInline'],
- ['collapseToStartOfNextText', 'moveToStartOfNextText'],
- ['collapseToStartOfPreviousBlock', 'moveToStartOfPreviousBlock'],
- ['collapseToStartOfPreviousInline', 'moveToStartOfPreviousInline'],
- ['collapseToStartOfPreviousText', 'moveToStartOfPreviousText'],
- ['extend', 'moveFocusForward'],
- ['extendCharBackward', 'moveFocusBackward'],
- ['extendCharForward', 'moveFocusForward'],
- ['extendLineBackward', 'moveFocusToStartOfBlock'],
- ['extendLineForward', 'moveFocusToEndOfBlock'],
- ['extendTo', 'moveFocusTo'],
- ['extendToEndOf', 'moveFocusToEndOfNode'],
- ['extendToEndOfBlock', 'moveFocusToEndOfBlock'],
- ['extendToEndOfBlock', 'moveFocusToEndOfBlock'],
- ['extendToEndOfNextBlock', 'moveFocusToEndOfNextBlock'],
- ['extendToEndOfNextInline', 'moveFocusToEndOfNextInline'],
- ['extendToEndOfNextText', 'moveFocusToEndOfNextText'],
- ['extendToEndOfPreviousBlock', 'moveFocusToEndOfPreviousBlock'],
- ['extendToEndOfPreviousInline', 'moveFocusToEndOfPreviousInline'],
- ['extendToEndOfPreviousText', 'moveFocusToEndOfPreviousText'],
- ['extendToStartOf', 'moveFocusToStartOfNode'],
- ['extendToStartOfBlock', 'moveFocusToStartOfBlock'],
- ['extendToStartOfNextBlock', 'moveFocusToStartOfNextBlock'],
- ['extendToStartOfNextInline', 'moveFocusToStartOfNextInline'],
- ['extendToStartOfNextText', 'moveFocusToStartOfNextText'],
- ['extendToStartOfPreviousBlock', 'moveFocusToStartOfPreviousBlock'],
- ['extendToStartOfPreviousInline', 'moveFocusToStartOfPreviousInline'],
- ['extendToStartOfPreviousText', 'moveFocusToStartOfPreviousText'],
- ['move', 'moveForward'],
- ['moveAnchor', 'moveAnchorForward'],
- ['moveAnchorCharBackward', 'moveAnchorBackward'],
- ['moveAnchorCharForward', 'moveAnchorForward'],
- ['moveAnchorOffsetTo', 'moveAnchorTo'],
- ['moveAnchorToEndOf', 'moveAnchorToEndOfNode'],
- ['moveAnchorToStartOf', 'moveAnchorToStartOfNode'],
- ['moveCharBackward', 'moveBackward'],
- ['moveCharForward', 'moveForward'],
- ['moveEnd', 'moveEndForward'],
- ['moveEndCharBackward', 'moveEndBackward'],
- ['moveEndCharForward', 'moveEndForward'],
- ['moveEndOffsetTo', 'moveEndTo'],
- ['moveFocus', 'moveFocusForward'],
- ['moveFocusCharBackward', 'moveFocusBackward'],
- ['moveFocusCharForward', 'moveFocusForward'],
- ['moveFocusOffsetTo', 'moveFocusTo'],
- ['moveFocusToEndOf', 'moveFocusToEndOfNode'],
- ['moveFocusToStartOf', 'moveFocusToStartOfNode'],
- ['moveStart', 'moveStartForward'],
- ['moveStartCharBackward', 'moveStartBackward'],
- ['moveStartCharForward', 'moveStartForward'],
- ['moveStartOffsetTo', 'moveStartTo'],
- ['moveToEndOf', 'moveToEndOfNode'],
- ['moveToRangeOf', 'moveToRangeOfNode'],
- ['moveToStartOf', 'moveToStartOfNode'],
- ['selectAll', 'moveToRangeOfDocument'],
-]
-
-DEPRECATEDS.forEach(([deprecated, method]) => {
- Changes[deprecated] = function(change, ...args) {
- logger.deprecate(
- '0.37.0',
- `The \`Change.${deprecated}\` method is deprecated, please use \`Change.${method}\` instead.`
- )
-
- change[method](...args)
- }
-})
-
export default Changes
diff --git a/packages/slate/src/index.js b/packages/slate/src/index.js
index 367101d04..f44a9d6ee 100644
--- a/packages/slate/src/index.js
+++ b/packages/slate/src/index.js
@@ -1,6 +1,8 @@
import './interfaces/common'
+import './interfaces/element'
import './interfaces/node'
import './interfaces/range'
+
import Block from './models/block'
import Change from './models/change'
import Changes from './changes'
@@ -24,7 +26,6 @@ import Stack from './models/stack'
import Text from './models/text'
import TextUtils from './utils/text-utils'
import Value from './models/value'
-import { resetKeyGenerator, setKeyGenerator } from './utils/generate-key'
import { resetMemoization, useMemoization } from './utils/memoize'
/**
@@ -51,11 +52,9 @@ export {
PathUtils,
Point,
Range,
- resetKeyGenerator,
resetMemoization,
Schema,
Selection,
- setKeyGenerator,
Stack,
Text,
TextUtils,
@@ -80,11 +79,9 @@ export default {
PathUtils,
Point,
Range,
- resetKeyGenerator,
resetMemoization,
Schema,
Selection,
- setKeyGenerator,
Stack,
Text,
TextUtils,
diff --git a/packages/slate/src/interfaces/common.js b/packages/slate/src/interfaces/common.js
index 77940edfe..65ea524d6 100644
--- a/packages/slate/src/interfaces/common.js
+++ b/packages/slate/src/interfaces/common.js
@@ -1,5 +1,3 @@
-import logger from 'slate-dev-logger'
-
import mixin from '../utils/mixin'
import Block from '../models/block'
import Change from '../models/change'
@@ -41,19 +39,6 @@ class CommonInterface {
toJS(...args) {
return this.toJSON(...args)
}
-
- /**
- * Deprecated.
- */
-
- get kind() {
- logger.deprecate(
- 'slate@0.32.0',
- 'The `kind` property of Slate objects has been renamed to `object`.'
- )
-
- return this.object
- }
}
/**
diff --git a/packages/slate/src/interfaces/element.js b/packages/slate/src/interfaces/element.js
new file mode 100644
index 000000000..1329025fd
--- /dev/null
+++ b/packages/slate/src/interfaces/element.js
@@ -0,0 +1,1826 @@
+import direction from 'direction'
+import { List, OrderedSet, Set } from 'immutable'
+
+import mixin from '../utils/mixin'
+import Block from '../models/block'
+import Decoration from '../models/decoration'
+import Document from '../models/document'
+import Inline from '../models/inline'
+import memoize from '../utils/memoize'
+import PathUtils from '../utils/path-utils'
+import Point from '../models/point'
+import Range from '../models/range'
+import Selection from '../models/selection'
+
+/**
+ * The interface that `Document`, `Block` and `Inline` all implement, to make
+ * working with the recursive node tree easier.
+ *
+ * @type {Class}
+ */
+
+class ElementInterface {
+ /**
+ * Add mark to text at `offset` and `length` in node by `path`.
+ *
+ * @param {List|String} path
+ * @param {Number} offset
+ * @param {Number} length
+ * @param {Mark} mark
+ * @return {Node}
+ */
+
+ addMark(path, offset, length, mark) {
+ let node = this.assertDescendant(path)
+ path = this.resolvePath(path)
+ node = node.addMark(offset, length, mark)
+ const ret = this.replaceNode(path, node)
+ return ret
+ }
+
+ /**
+ * Create a decoration with `properties` relative to the node.
+ *
+ * @param {Object|Decoration} properties
+ * @return {Decoration}
+ */
+
+ createDecoration(properties) {
+ properties = Decoration.createProperties(properties)
+ const decoration = this.resolveDecoration(properties)
+ return decoration
+ }
+
+ /**
+ * Create a point with `properties` relative to the node.
+ *
+ * @param {Object|Point} properties
+ * @return {Range}
+ */
+
+ createPoint(properties) {
+ properties = Point.createProperties(properties)
+ const point = this.resolvePoint(properties)
+ return point
+ }
+
+ /**
+ * Create a range with `properties` relative to the node.
+ *
+ * @param {Object|Range} properties
+ * @return {Range}
+ */
+
+ createRange(properties) {
+ properties = Range.createProperties(properties)
+ const range = this.resolveRange(properties)
+ return range
+ }
+
+ /**
+ * Create a selection with `properties` relative to the node.
+ *
+ * @param {Object|Selection} properties
+ * @return {Selection}
+ */
+
+ createSelection(properties) {
+ properties = Selection.createProperties(properties)
+ const selection = this.resolveSelection(properties)
+ return selection
+ }
+
+ /**
+ * Recursively filter all descendant nodes with `iterator`.
+ *
+ * @param {Function} iterator
+ * @return {List}
+ */
+
+ filterDescendants(iterator) {
+ const matches = []
+
+ this.forEachDescendant((node, i, nodes) => {
+ if (iterator(node, i, nodes)) matches.push(node)
+ })
+
+ return List(matches)
+ }
+
+ /**
+ * Recursively find all descendant nodes by `iterator`.
+ *
+ * @param {Function} iterator
+ * @return {Node|Null}
+ */
+
+ findDescendant(iterator) {
+ let found = null
+
+ this.forEachDescendant((node, i, nodes) => {
+ if (iterator(node, i, nodes)) {
+ found = node
+ return false
+ }
+ })
+
+ return found
+ }
+
+ /**
+ * Recursively iterate over all descendant nodes with `iterator`. If the
+ * iterator returns false it will break the loop.
+ *
+ * @param {Function} iterator
+ */
+
+ forEachDescendant(iterator) {
+ let ret
+
+ this.nodes.forEach((child, i, nodes) => {
+ if (iterator(child, i, nodes) === false) {
+ ret = false
+ return false
+ }
+
+ if (child.object != 'text') {
+ ret = child.forEachDescendant(iterator)
+ return ret
+ }
+ })
+
+ return ret
+ }
+
+ /**
+ * Get a set of the active marks in a `range`.
+ *
+ * @param {Range} range
+ * @return {Set}
+ */
+
+ getActiveMarksAtRange(range) {
+ range = this.resolveRange(range)
+ if (range.isUnset) return Set()
+
+ if (range.isCollapsed) {
+ const { start } = range
+ return this.getMarksAtPosition(start.key, start.offset).toSet()
+ }
+
+ const { start, end } = range
+ let startKey = start.key
+ let startOffset = start.offset
+ let endKey = end.key
+ let endOffset = end.offset
+ let startText = this.getDescendant(startKey)
+
+ if (startKey !== endKey) {
+ while (startKey !== endKey && endOffset === 0) {
+ const endText = this.getPreviousText(endKey)
+ endKey = endText.key
+ endOffset = endText.text.length
+ }
+
+ while (startKey !== endKey && startOffset === startText.text.length) {
+ startText = this.getNextText(startKey)
+ startKey = startText.key
+ startOffset = 0
+ }
+ }
+
+ if (startKey === endKey) {
+ return startText.getActiveMarksBetweenOffsets(startOffset, endOffset)
+ }
+
+ const startMarks = startText.getActiveMarksBetweenOffsets(
+ startOffset,
+ startText.text.length
+ )
+ if (startMarks.size === 0) return Set()
+ const endText = this.getDescendant(endKey)
+ const endMarks = endText.getActiveMarksBetweenOffsets(0, endOffset)
+ let marks = startMarks.intersect(endMarks)
+ // If marks is already empty, the active marks is empty
+ if (marks.size === 0) return marks
+
+ let text = this.getNextText(startKey)
+
+ while (text.key !== endKey) {
+ if (text.text.length !== 0) {
+ marks = marks.intersect(text.getActiveMarks())
+ if (marks.size === 0) return Set()
+ }
+
+ text = this.getNextText(text.key)
+ }
+ return marks
+ }
+
+ /**
+ * Get a list of the ancestors of a descendant.
+ *
+ * @param {List|String} path
+ * @return {List|Null}
+ */
+
+ getAncestors(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+
+ const ancestors = []
+
+ path.forEach((p, i) => {
+ const current = path.slice(0, i)
+ const parent = this.getNode(current)
+ ancestors.push(parent)
+ })
+
+ return List(ancestors)
+ }
+
+ /**
+ * Get the leaf block descendants of the node.
+ *
+ * @return {List}
+ */
+
+ getBlocks() {
+ const array = this.getBlocksAsArray()
+ return List(array)
+ }
+
+ /**
+ * Get the leaf block descendants of the node.
+ *
+ * @return {List}
+ */
+
+ getBlocksAsArray() {
+ return this.nodes.reduce((array, child) => {
+ if (child.object != 'block') return array
+ if (!child.isLeafBlock()) return array.concat(child.getBlocksAsArray())
+ array.push(child)
+ return array
+ }, [])
+ }
+
+ /**
+ * Get the leaf block descendants in a `range`.
+ *
+ * @param {Range} range
+ * @return {List}
+ */
+
+ getBlocksAtRange(range) {
+ const array = this.getBlocksAtRangeAsArray(range)
+ // Eliminate duplicates by converting to an `OrderedSet` first.
+ return List(OrderedSet(array))
+ }
+
+ /**
+ * Get the leaf block descendants in a `range` as an array
+ *
+ * @param {Range} range
+ * @return {Array}
+ */
+
+ getBlocksAtRangeAsArray(range) {
+ range = this.resolveRange(range)
+ if (range.isUnset) return []
+
+ const { start, end } = range
+ const startBlock = this.getClosestBlock(start.key)
+
+ // PERF: the most common case is when the range is in a single block node,
+ // where we can avoid a lot of iterating of the tree.
+ if (start.key === end.key) return [startBlock]
+
+ const endBlock = this.getClosestBlock(end.key)
+ const blocks = this.getBlocksAsArray()
+ const startIndex = blocks.indexOf(startBlock)
+ const endIndex = blocks.indexOf(endBlock)
+ return blocks.slice(startIndex, endIndex + 1)
+ }
+
+ /**
+ * Get all of the leaf blocks that match a `type`.
+ *
+ * @param {String} type
+ * @return {List}
+ */
+
+ getBlocksByType(type) {
+ const array = this.getBlocksByTypeAsArray(type)
+ return List(array)
+ }
+
+ /**
+ * Get all of the leaf blocks that match a `type` as an array
+ *
+ * @param {String} type
+ * @return {Array}
+ */
+
+ getBlocksByTypeAsArray(type) {
+ return this.nodes.reduce((array, node) => {
+ if (node.object != 'block') {
+ return array
+ } else if (node.isLeafBlock() && node.type == type) {
+ array.push(node)
+ return array
+ } else {
+ return array.concat(node.getBlocksByTypeAsArray(type))
+ }
+ }, [])
+ }
+
+ /**
+ * Get a child node.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getChild(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+ const child = path.size === 1 ? this.nodes.get(path.first()) : null
+ return child
+ }
+
+ /**
+ * Get closest parent of node that matches an `iterator`.
+ *
+ * @param {List|String} path
+ * @param {Function} iterator
+ * @return {Node|Null}
+ */
+
+ getClosest(path, iterator) {
+ const ancestors = this.getAncestors(path)
+ if (!ancestors) return null
+
+ const closest = ancestors.findLast((node, ...args) => {
+ // We never want to include the top-level node.
+ if (node === this) return false
+ return iterator(node, ...args)
+ })
+
+ return closest || null
+ }
+
+ /**
+ * Get the closest block parent of a node.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getClosestBlock(path) {
+ const closest = this.getClosest(path, n => n.object === 'block')
+ return closest
+ }
+
+ /**
+ * Get the closest inline parent of a node by `path`.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getClosestInline(path) {
+ const closest = this.getClosest(path, n => n.object === 'inline')
+ return closest
+ }
+
+ /**
+ * Get the closest void parent of a node by `path`.
+ *
+ * @param {List|String} path
+ * @param {Schema} schema
+ * @return {Node|Null}
+ */
+
+ getClosestVoid(path, schema) {
+ const ancestors = this.getAncestors(path)
+ const ancestor = ancestors.findLast(a => schema.isVoid(a))
+ return ancestor
+ }
+
+ /**
+ * Get the common ancestor of nodes `a` and `b`.
+ *
+ * @param {List} a
+ * @param {List} b
+ * @return {Node}
+ */
+
+ getCommonAncestor(a, b) {
+ a = this.resolvePath(a)
+ b = this.resolvePath(b)
+ if (!a || !b) return null
+
+ const path = PathUtils.relate(a, b)
+ const node = this.getNode(path)
+ return node
+ }
+
+ /**
+ * Get the decorations for the node from a `stack`.
+ *
+ * @param {Stack} stack
+ * @return {List}
+ */
+
+ getDecorations(stack) {
+ const decorations = stack.find('decorateNode', this)
+ const list = Decoration.createList(decorations || [])
+ return list
+ }
+
+ /**
+ * Get the depth of a descendant, with optional `startAt`.
+ *
+ * @param {List|String} path
+ * @param {Number} startAt
+ * @return {Number|Null}
+ */
+
+ getDepth(path, startAt = 1) {
+ path = this.resolvePath(path)
+ if (!path) return null
+
+ const node = this.getNode(path)
+ const depth = node ? path.size - 1 + startAt : null
+ return depth
+ }
+
+ /**
+ * Get a descendant node.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getDescendant(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+
+ const deep = path.flatMap(x => ['nodes', x])
+ const ret = this.getIn(deep)
+ return ret
+ }
+
+ /**
+ * Get a fragment of the node at a `range`.
+ *
+ * @param {Range} range
+ * @return {Document}
+ */
+
+ getFragmentAtRange(range) {
+ range = this.resolveRange(range)
+
+ if (range.isUnset) {
+ return Document.create()
+ }
+
+ const { start, end } = range
+ let node = this
+ let targetPath = end.path
+ let targetPosition = end.offset
+ let mode = 'end'
+
+ while (targetPath.size) {
+ const index = targetPath.last()
+ node = node.splitNode(targetPath, targetPosition)
+ targetPosition = index + 1
+ targetPath = PathUtils.lift(targetPath)
+
+ if (!targetPath.size && mode === 'end') {
+ targetPath = start.path
+ targetPosition = start.offset
+ mode = 'start'
+ }
+ }
+
+ const startIndex = start.path.first() + 1
+ const endIndex = end.path.first() + 2
+ const nodes = node.nodes.slice(startIndex, endIndex)
+ const fragment = Document.create({ nodes })
+ return fragment
+ }
+
+ /**
+ * Get the furthest parent of a node that matches an `iterator`.
+ *
+ * @param {Path} path
+ * @param {Function} iterator
+ * @return {Node|Null}
+ */
+
+ getFurthest(path, iterator) {
+ const ancestors = this.getAncestors(path)
+ if (!ancestors) return null
+
+ const furthest = ancestors.find((node, ...args) => {
+ // We never want to include the top-level node.
+ if (node === this) return false
+ return iterator(node, ...args)
+ })
+
+ return furthest || null
+ }
+
+ /**
+ * Get the furthest ancestor of a node.
+ *
+ * @param {Path} path
+ * @return {Node|Null}
+ */
+
+ getFurthestAncestor(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+ const furthest = path.size ? this.nodes.get(path.first()) : null
+ return furthest
+ }
+
+ /**
+ * Get the furthest block parent of a node.
+ *
+ * @param {Path} path
+ * @return {Node|Null}
+ */
+
+ getFurthestBlock(path) {
+ const furthest = this.getFurthest(path, n => n.object === 'block')
+ return furthest
+ }
+
+ /**
+ * Get the furthest inline parent of a node.
+ *
+ * @param {Path} path
+ * @return {Node|Null}
+ */
+
+ getFurthestInline(path) {
+ const furthest = this.getFurthest(path, n => n.object === 'inline')
+ return furthest
+ }
+
+ /**
+ * Get the furthest ancestor of a node that has only one child.
+ *
+ * @param {Path} path
+ * @return {Node|Null}
+ */
+
+ getFurthestOnlyChildAncestor(path) {
+ const ancestors = this.getAncestors(path)
+ if (!ancestors) return null
+
+ const furthest = ancestors
+ .rest()
+ .reverse()
+ .takeUntil(p => p.nodes.size > 1)
+ .last()
+
+ return furthest || null
+ }
+
+ /**
+ * Get the closest inline nodes for each text node in the node.
+ *
+ * @return {List}
+ */
+
+ getInlines() {
+ const array = this.getInlinesAsArray()
+ const list = List(array)
+ return list
+ }
+
+ /**
+ * Get the closest inline nodes for each text node in the node, as an array.
+ *
+ * @return {List}
+ */
+
+ getInlinesAsArray() {
+ let array = []
+
+ this.nodes.forEach(child => {
+ if (child.object == 'text') return
+
+ if (child.isLeafInline()) {
+ array.push(child)
+ } else {
+ array = array.concat(child.getInlinesAsArray())
+ }
+ })
+
+ return array
+ }
+
+ /**
+ * Get the closest inline nodes for each text node in a `range`.
+ *
+ * @param {Range} range
+ * @return {List}
+ */
+
+ getInlinesAtRange(range) {
+ const array = this.getInlinesAtRangeAsArray(range)
+ // Remove duplicates by converting it to an `OrderedSet` first.
+ const list = List(OrderedSet(array))
+ return list
+ }
+
+ /**
+ * Get the closest inline nodes for each text node in a `range` as an array.
+ *
+ * @param {Range} range
+ * @return {Array}
+ */
+
+ getInlinesAtRangeAsArray(range) {
+ range = this.resolveRange(range)
+ if (range.isUnset) return []
+
+ const array = this.getTextsAtRangeAsArray(range)
+ .map(text => this.getClosestInline(text.key))
+ .filter(exists => exists)
+
+ return array
+ }
+
+ /**
+ * Get all of the leaf inline nodes that match a `type`.
+ *
+ * @param {String} type
+ * @return {List}
+ */
+
+ getInlinesByType(type) {
+ const array = this.getInlinesByTypeAsArray(type)
+ const list = List(array)
+ return list
+ }
+
+ /**
+ * Get all of the leaf inline nodes that match a `type` as an array.
+ *
+ * @param {String} type
+ * @return {Array}
+ */
+
+ getInlinesByTypeAsArray(type) {
+ const array = this.nodes.reduce((inlines, node) => {
+ if (node.object == 'text') {
+ return inlines
+ } else if (node.isLeafInline() && node.type == type) {
+ inlines.push(node)
+ return inlines
+ } else {
+ return inlines.concat(node.getInlinesByTypeAsArray(type))
+ }
+ }, [])
+
+ return array
+ }
+
+ /**
+ * Get a set of the marks in a `range`.
+ *
+ * @param {Range} range
+ * @return {Set}
+ */
+
+ getInsertMarksAtRange(range) {
+ range = this.resolveRange(range)
+ const { start } = range
+
+ if (range.isUnset) {
+ return Set()
+ }
+
+ if (range.isCollapsed) {
+ // PERF: range is not cachable, use key and offset as proxies for cache
+ return this.getMarksAtPosition(start.key, start.offset)
+ }
+
+ const text = this.getDescendant(start.key)
+ const marks = text.getMarksAtIndex(start.offset + 1)
+ return marks
+ }
+
+ /**
+ * Get all of the marks for all of the characters of every text node.
+ *
+ * @return {Set}
+ */
+
+ getMarks() {
+ const array = this.getMarksAsArray()
+ return Set(array)
+ }
+
+ /**
+ * Get all of the marks as an array.
+ *
+ * @return {Array}
+ */
+
+ getMarksAsArray() {
+ const result = []
+
+ this.nodes.forEach(node => {
+ result.push(node.getMarksAsArray())
+ })
+
+ // PERF: use only one concat rather than multiple for speed.
+ const array = [].concat(...result)
+ return array
+ }
+
+ /**
+ * Get a set of marks in a `position`, the equivalent of a collapsed range
+ *
+ * @param {string} key
+ * @param {number} offset
+ * @return {Set}
+ */
+
+ getMarksAtPosition(key, offset) {
+ const text = this.getDescendant(key)
+ const currentMarks = text.getMarksAtIndex(offset)
+ if (offset !== 0) return currentMarks
+ const closestBlock = this.getClosestBlock(key)
+
+ if (closestBlock.text === '') {
+ // insert mark for empty block; the empty block are often created by split node or add marks in a range including empty blocks
+ return currentMarks
+ }
+
+ const previous = this.getPreviousText(key)
+ if (!previous) return Set()
+
+ if (closestBlock.hasDescendant(previous.key)) {
+ return previous.getMarksAtIndex(previous.text.length)
+ }
+
+ return currentMarks
+ }
+
+ /**
+ * Get a set of the marks in a `range`.
+ *
+ * @param {Range} range
+ * @return {Set}
+ */
+
+ getMarksAtRange(range) {
+ const marks = Set(this.getOrderedMarksAtRange(range))
+ return marks
+ }
+
+ /**
+ * Get all of the marks that match a `type`.
+ *
+ * @param {String} type
+ * @return {Set}
+ */
+
+ getMarksByType(type) {
+ const array = this.getMarksByTypeAsArray(type)
+ return Set(array)
+ }
+
+ /**
+ * Get all of the marks that match a `type` as an array.
+ *
+ * @param {String} type
+ * @return {Array}
+ */
+
+ getMarksByTypeAsArray(type) {
+ const array = this.nodes.reduce((memo, node) => {
+ return node.object == 'text'
+ ? memo.concat(node.getMarksAsArray().filter(m => m.type == type))
+ : memo.concat(node.getMarksByTypeAsArray(type))
+ }, [])
+
+ return array
+ }
+
+ /**
+ * Get the block node before a descendant text node by `key`.
+ *
+ * @param {String} key
+ * @return {Node|Null}
+ */
+
+ getNextBlock(key) {
+ const child = this.assertDescendant(key)
+ let last
+
+ if (child.object == 'block') {
+ last = child.getLastText()
+ } else {
+ const block = this.getClosestBlock(key)
+ last = block.getLastText()
+ }
+
+ const next = this.getNextText(last.key)
+ if (!next) return null
+
+ const closest = this.getClosestBlock(next.key)
+ return closest
+ }
+
+ /**
+ * Get the next node in the tree from a node.
+ *
+ * This will not only check for siblings but instead move up the tree
+ * returning the next ancestor if no sibling is found.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getNextNode(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+ if (!path.size) return null
+
+ for (let i = path.size; i > 0; i--) {
+ const p = path.slice(0, i)
+ const target = PathUtils.increment(p)
+ const node = this.getNode(target)
+ if (node) return node
+ }
+
+ return null
+ }
+
+ /**
+ * Get the next sibling of a node.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getNextSibling(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+ if (!path.size) return null
+ const p = PathUtils.increment(path)
+ const sibling = this.getNode(p)
+ return sibling
+ }
+
+ /**
+ * Get the text node after a descendant text node.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getNextText(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+ if (!path.size) return null
+ const next = this.getNextNode(path)
+ if (!next) return null
+ const text = next.getFirstText()
+ return text
+ }
+
+ /**
+ * Get the offset for a descendant text node by `key`.
+ *
+ * @param {String} key
+ * @return {Number}
+ */
+
+ getOffset(key) {
+ this.assertDescendant(key)
+
+ // Calculate the offset of the nodes before the highest child.
+ const child = this.getFurthestAncestor(key)
+ const offset = this.nodes
+ .takeUntil(n => n == child)
+ .reduce((memo, n) => memo + n.text.length, 0)
+
+ // Recurse if need be.
+ const ret = this.hasChild(key) ? offset : offset + child.getOffset(key)
+ return ret
+ }
+
+ /**
+ * Get the offset from a `range`.
+ *
+ * @param {Range} range
+ * @return {Number}
+ */
+
+ getOffsetAtRange(range) {
+ range = this.resolveRange(range)
+
+ if (range.isUnset) {
+ throw new Error('The range cannot be unset to calculcate its offset.')
+ }
+
+ if (range.isExpanded) {
+ throw new Error('The range must be collapsed to calculcate its offset.')
+ }
+
+ const { start } = range
+ const offset = this.getOffset(start.key) + start.offset
+ return offset
+ }
+
+ /**
+ * Get all of the marks for all of the characters of every text node.
+ *
+ * @return {OrderedSet}
+ */
+
+ getOrderedMarks() {
+ const array = this.getMarksAsArray()
+ return OrderedSet(array)
+ }
+
+ /**
+ * Get a set of the marks in a `range`.
+ *
+ * @param {Range} range
+ * @return {OrderedSet}
+ */
+
+ getOrderedMarksAtRange(range) {
+ range = this.resolveRange(range)
+ const { start, end } = range
+
+ if (range.isUnset) {
+ return OrderedSet()
+ }
+
+ if (range.isCollapsed) {
+ // PERF: range is not cachable, use key and offset as proxies for cache
+ return this.getMarksAtPosition(start.key, start.offset)
+ }
+
+ const marks = this.getOrderedMarksBetweenPositions(
+ start.key,
+ start.offset,
+ end.key,
+ end.offset
+ )
+
+ return marks
+ }
+
+ /**
+ * Get a set of the marks in a `range`.
+ * PERF: arguments use key and offset for utilizing cache
+ *
+ * @param {string} startKey
+ * @param {number} startOffset
+ * @param {string} endKey
+ * @param {number} endOffset
+ * @returns {OrderedSet}
+ */
+
+ getOrderedMarksBetweenPositions(startKey, startOffset, endKey, endOffset) {
+ if (startKey === endKey) {
+ const startText = this.getDescendant(startKey)
+ return startText.getMarksBetweenOffsets(startOffset, endOffset)
+ }
+
+ const texts = this.getTextsBetweenPositionsAsArray(startKey, endKey)
+
+ return OrderedSet().withMutations(result => {
+ texts.forEach(text => {
+ if (text.key === startKey) {
+ result.union(
+ text.getMarksBetweenOffsets(startOffset, text.text.length)
+ )
+ } else if (text.key === endKey) {
+ result.union(text.getMarksBetweenOffsets(0, endOffset))
+ } else {
+ result.union(text.getMarks())
+ }
+ })
+ })
+ }
+
+ /**
+ * Get all of the marks that match a `type`.
+ *
+ * @param {String} type
+ * @return {OrderedSet}
+ */
+
+ getOrderedMarksByType(type) {
+ const array = this.getMarksByTypeAsArray(type)
+ return OrderedSet(array)
+ }
+
+ /**
+ * Get the parent of a descendant node.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getParent(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+ if (!path.size) return null
+ const parentPath = PathUtils.lift(path)
+ const parent = this.getNode(parentPath)
+ return parent
+ }
+
+ /**
+ * Get the block node before a descendant text node by `key`.
+ *
+ * @param {String} key
+ * @return {Node|Null}
+ */
+
+ getPreviousBlock(key) {
+ const child = this.assertDescendant(key)
+ let first
+
+ if (child.object == 'block') {
+ first = child.getFirstText()
+ } else {
+ const block = this.getClosestBlock(key)
+ first = block.getFirstText()
+ }
+
+ const previous = this.getPreviousText(first.key)
+ if (!previous) return null
+
+ const closest = this.getClosestBlock(previous.key)
+ return closest
+ }
+
+ /**
+ * Get the previous node from a node in the tree.
+ *
+ * This will not only check for siblings but instead move up the tree
+ * returning the previous ancestor if no sibling is found.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getPreviousNode(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+ if (!path.size) return null
+
+ for (let i = path.size; i > 0; i--) {
+ const p = path.slice(0, i)
+ if (p.last() === 0) continue
+
+ const target = PathUtils.decrement(p)
+ const node = this.getNode(target)
+ if (node) return node
+ }
+
+ return null
+ }
+
+ /**
+ * Get the previous sibling of a node.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getPreviousSibling(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+ if (!path.size) return null
+ if (path.last() === 0) return null
+ const p = PathUtils.decrement(path)
+ const sibling = this.getNode(p)
+ return sibling
+ }
+
+ /**
+ * Get the text node after a descendant text node.
+ *
+ * @param {List|String} path
+ * @return {Node|Null}
+ */
+
+ getPreviousText(path) {
+ path = this.resolvePath(path)
+ if (!path) return null
+ if (!path.size) return null
+ const previous = this.getPreviousNode(path)
+ if (!previous) return null
+ const text = previous.getLastText()
+ return text
+ }
+
+ /**
+ * Get the indexes of the selection for a `range`, given an extra flag for
+ * whether the node `isSelected`, to determine whether not finding matches
+ * means everything is selected or nothing is.
+ *
+ * @param {Range} range
+ * @param {Boolean} isSelected
+ * @return {Object|Null}
+ */
+
+ getSelectionIndexes(range, isSelected = true) {
+ const { start, end } = range
+
+ // PERF: if we're not selected, we can exit early.
+ if (!isSelected) {
+ return null
+ }
+
+ // if we've been given an invalid selection we can exit early.
+ if (range.isUnset) {
+ return null
+ }
+
+ // PERF: if the start and end keys are the same, just check for the child
+ // that contains that single key.
+ if (start.key == end.key) {
+ const child = this.getFurthestAncestor(start.key)
+ const index = child ? this.nodes.indexOf(child) : null
+ return { start: index, end: index + 1 }
+ }
+
+ // Otherwise, check all of the children...
+ let startIndex = null
+ let endIndex = null
+
+ this.nodes.forEach((child, i) => {
+ if (child.object == 'text') {
+ if (startIndex == null && child.key == start.key) startIndex = i
+ if (endIndex == null && child.key == end.key) endIndex = i + 1
+ } else {
+ if (startIndex == null && child.hasDescendant(start.key)) startIndex = i
+ if (endIndex == null && child.hasDescendant(end.key)) endIndex = i + 1
+ }
+
+ // PERF: exit early if both start and end have been found.
+ return startIndex == null || endIndex == null
+ })
+
+ if (isSelected && startIndex == null) startIndex = 0
+ if (isSelected && endIndex == null) endIndex = this.nodes.size
+ return startIndex == null ? null : { start: startIndex, end: endIndex }
+ }
+
+ /**
+ * Get the descendent text node at an `offset`.
+ *
+ * @param {String} offset
+ * @return {Node|Null}
+ */
+
+ getTextAtOffset(offset) {
+ // PERF: Add a few shortcuts for the obvious cases.
+ if (offset === 0) return this.getFirstText()
+ if (offset === this.text.length) return this.getLastText()
+ if (offset < 0 || offset > this.text.length) return null
+
+ let length = 0
+ const text = this.getTexts().find((node, i, nodes) => {
+ length += node.text.length
+ return length > offset
+ })
+
+ return text
+ }
+
+ /**
+ * Get the direction of the node's text.
+ *
+ * @return {String}
+ */
+
+ getTextDirection() {
+ const dir = direction(this.text)
+ return dir === 'neutral' ? null : dir
+ }
+
+ /**
+ * Recursively get all of the child text nodes in order of appearance.
+ *
+ * @return {List}
+ */
+
+ getTexts() {
+ const array = this.getTextsAsArray()
+ return List(array)
+ }
+
+ /**
+ * Recursively get all the leaf text nodes in order of appearance, as array.
+ *
+ * @return {List}
+ */
+
+ getTextsAsArray() {
+ let array = []
+
+ this.nodes.forEach(node => {
+ if (node.object == 'text') {
+ array.push(node)
+ } else {
+ array = array.concat(node.getTextsAsArray())
+ }
+ })
+
+ return array
+ }
+
+ /**
+ * Get all of the text nodes in a `range`.
+ *
+ * @param {Range} range
+ * @return {List}
+ */
+
+ getTextsAtRange(range) {
+ range = this.resolveRange(range)
+ if (range.isUnset) return List()
+ const { start, end } = range
+ const list = List(this.getTextsBetweenPositionsAsArray(start.key, end.key))
+
+ return list
+ }
+
+ /**
+ * Get all of the text nodes in a `range` as an array.
+ *
+ * @param {Range} range
+ * @return {Array}
+ */
+
+ getTextsAtRangeAsArray(range) {
+ range = this.resolveRange(range)
+ if (range.isUnset) return []
+ const { start, end } = range
+ const texts = this.getTextsBetweenPositionsAsArray(start.key, end.key)
+ return texts
+ }
+
+ /**
+ * Get all of the text nodes in a `range` as an array.
+ * PERF: use key in arguments for cache
+ *
+ * @param {string} startKey
+ * @param {string} endKey
+ * @returns {Array}
+ */
+
+ getTextsBetweenPositionsAsArray(startKey, endKey) {
+ const startText = this.getDescendant(startKey)
+
+ // PERF: the most common case is when the range is in a single text node,
+ // where we can avoid a lot of iterating of the tree.
+ if (startKey == endKey) return [startText]
+
+ const endText = this.getDescendant(endKey)
+ const texts = this.getTextsAsArray()
+ const start = texts.indexOf(startText)
+ const end = texts.indexOf(endText, start)
+ const ret = texts.slice(start, end + 1)
+ return ret
+ }
+
+ /**
+ * Check if the node has block children.
+ *
+ * @return {Boolean}
+ */
+
+ hasBlockChildren() {
+ return !!(this.nodes && this.nodes.find(n => n.object === 'block'))
+ }
+
+ /**
+ * Check if a child node exists.
+ *
+ * @param {List|String} path
+ * @return {Boolean}
+ */
+
+ hasChild(path) {
+ const child = this.getChild(path)
+ return !!child
+ }
+
+ /**
+ * Check if a node has inline children.
+ *
+ * @return {Boolean}
+ */
+
+ hasInlineChildren() {
+ return !!(
+ this.nodes &&
+ this.nodes.find(n => n.object === 'inline' || n.object === 'text')
+ )
+ }
+
+ /**
+ * Recursively check if a child node exists.
+ *
+ * @param {List|String} path
+ * @return {Boolean}
+ */
+
+ hasDescendant(path) {
+ const descendant = this.getDescendant(path)
+ return !!descendant
+ }
+
+ /**
+ * Check if a node has a void parent.
+ *
+ * @param {List|String} path
+ * @param {Schema} schema
+ * @return {Boolean}
+ */
+
+ hasVoidParent(path, schema) {
+ const closest = this.getClosestVoid(path, schema)
+ return !!closest
+ }
+
+ /**
+ * Insert a `node`.
+ *
+ * @param {List|String} path
+ * @param {Node} node
+ * @return {Node}
+ */
+
+ insertNode(path, node) {
+ path = this.resolvePath(path)
+ const index = path.last()
+ const parentPath = PathUtils.lift(path)
+ let parent = this.assertNode(parentPath)
+ const nodes = parent.nodes.splice(index, 0, node)
+ parent = parent.set('nodes', nodes)
+ const ret = this.replaceNode(parentPath, parent)
+ return ret
+ }
+
+ /**
+ * Insert `text` at `offset` in node by `path`.
+ *
+ * @param {List|String} path
+ * @param {Number} offset
+ * @param {String} text
+ * @param {Set} marks
+ * @return {Node}
+ */
+
+ insertText(path, offset, text, marks) {
+ let node = this.assertDescendant(path)
+ path = this.resolvePath(path)
+ node = node.insertText(offset, text, marks)
+ const ret = this.replaceNode(path, node)
+ return ret
+ }
+
+ /**
+ * Check whether the node is a leaf block.
+ *
+ * @return {Boolean}
+ */
+
+ isLeafBlock() {
+ const { object, nodes } = this
+ const first = nodes.first()
+ return object === 'block' && first.object !== 'block'
+ }
+
+ /**
+ * Check whether the node is a leaf inline.
+ *
+ * @return {Boolean}
+ */
+
+ isLeafInline() {
+ const { object, nodes } = this
+ const first = nodes.first()
+ return object === 'inline' && first.object !== 'inline'
+ }
+
+ /**
+ * Map all child nodes, updating them in their parents. This method is
+ * optimized to not return a new node if no changes are made.
+ *
+ * @param {Function} iterator
+ * @return {Node}
+ */
+
+ mapChildren(iterator) {
+ let { nodes } = this
+
+ nodes.forEach((node, i) => {
+ const ret = iterator(node, i, this.nodes)
+ if (ret !== node) nodes = nodes.set(ret.key, ret)
+ })
+
+ const ret = this.set('nodes', nodes)
+ return ret
+ }
+
+ /**
+ * Map all descendant nodes, updating them in their parents. This method is
+ * optimized to not return a new node if no changes are made.
+ *
+ * @param {Function} iterator
+ * @return {Node}
+ */
+
+ mapDescendants(iterator) {
+ let { nodes } = this
+
+ nodes.forEach((node, index) => {
+ let ret = node
+ if (ret.object !== 'text') ret = ret.mapDescendants(iterator)
+ ret = iterator(ret, index, this.nodes)
+ if (ret === node) return
+
+ nodes = nodes.set(index, ret)
+ })
+
+ const ret = this.set('nodes', nodes)
+ return ret
+ }
+
+ /**
+ * Merge a node backwards its previous sibling.
+ *
+ * @param {List|Key} path
+ * @return {Node}
+ */
+
+ mergeNode(path) {
+ const b = this.assertNode(path)
+ path = this.resolvePath(path)
+
+ if (path.last() === 0) {
+ throw new Error(
+ `Unable to merge node because it has no previous sibling: ${b}`
+ )
+ }
+
+ const withPath = PathUtils.decrement(path)
+ const a = this.assertNode(withPath)
+
+ if (a.object !== b.object) {
+ throw new Error(
+ `Unable to merge two different kinds of nodes: ${a} and ${b}`
+ )
+ }
+
+ const newNode =
+ a.object === 'text'
+ ? a.mergeText(b)
+ : a.set('nodes', a.nodes.concat(b.nodes))
+
+ let ret = this
+ ret = ret.removeNode(path)
+ ret = ret.removeNode(withPath)
+ ret = ret.insertNode(withPath, newNode)
+ return ret
+ }
+
+ /**
+ * Move a node by `path` to `newPath`.
+ *
+ * A `newIndex` can be provided when move nodes by `key`, to account for not
+ * being able to have a key for a location in the tree that doesn't exist yet.
+ *
+ * @param {List|Key} path
+ * @param {List|Key} newPath
+ * @param {Number} newIndex
+ * @return {Node}
+ */
+
+ moveNode(path, newPath, newIndex = 0) {
+ const node = this.assertNode(path)
+ path = this.resolvePath(path)
+ newPath = this.resolvePath(newPath, newIndex)
+
+ const newParentPath = PathUtils.lift(newPath)
+ this.assertNode(newParentPath)
+
+ const [p, np] = PathUtils.crop(path, newPath)
+ const position = PathUtils.compare(p, np)
+
+ // If the old path ends above and before a node in the new path, then
+ // removing it will alter the target, so we need to adjust the new path.
+ if (path.size < newPath.size && position === -1) {
+ newPath = PathUtils.decrement(newPath, 1, p.size - 1)
+ }
+
+ let ret = this
+ ret = ret.removeNode(path)
+ ret = ret.insertNode(newPath, node)
+ return ret
+ }
+
+ /**
+ * Attempt to "refind" a node by a previous `path`, falling back to looking
+ * it up by `key` again.
+ *
+ * @param {List|String} path
+ * @param {String} key
+ * @return {Node|Null}
+ */
+
+ refindNode(path, key) {
+ const node = this.getDescendant(path)
+ const found = node && node.key === key ? node : this.getDescendant(key)
+ return found
+ }
+
+ /**
+ * Attempt to "refind" the path to a node by a previous `path`, falling back
+ * to looking it up by `key`.
+ *
+ * @param {List|String} path
+ * @param {String} key
+ * @return {List|Null}
+ */
+
+ refindPath(path, key) {
+ const node = this.getDescendant(path)
+ const found = node && node.key === key ? path : this.getPath(key)
+ return found
+ }
+
+ /**
+ * Remove mark from text at `offset` and `length` in node.
+ *
+ * @param {List} path
+ * @param {Number} offset
+ * @param {Number} length
+ * @param {Mark} mark
+ * @return {Node}
+ */
+
+ removeMark(path, offset, length, mark) {
+ let node = this.assertDescendant(path)
+ path = this.resolvePath(path)
+ node = node.removeMark(offset, length, mark)
+ const ret = this.replaceNode(path, node)
+ return ret
+ }
+
+ /**
+ * Remove a node.
+ *
+ * @param {List|String} path
+ * @return {Node}
+ */
+
+ removeNode(path) {
+ this.assertDescendant(path)
+ path = this.resolvePath(path)
+ const deep = path.flatMap(x => ['nodes', x])
+ const ret = this.deleteIn(deep)
+ return ret
+ }
+
+ /**
+ * Remove `text` at `offset` in node.
+ *
+ * @param {List|Key} path
+ * @param {Number} offset
+ * @param {String} text
+ * @return {Node}
+ */
+
+ removeText(path, offset, text) {
+ let node = this.assertDescendant(path)
+ node = node.removeText(offset, text.length)
+ const ret = this.replaceNode(path, node)
+ return ret
+ }
+
+ /**
+ * Replace a `node` in the tree.
+ *
+ * @param {List|Key} path
+ * @param {Node} node
+ * @return {Node}
+ */
+
+ replaceNode(path, node) {
+ path = this.resolvePath(path)
+
+ if (!path) {
+ throw new Error(
+ `Unable to replace a node because it could not be found in the first place: ${path}`
+ )
+ }
+
+ if (!path.size) return node
+ this.assertNode(path)
+ const deep = path.flatMap(x => ['nodes', x])
+ const ret = this.setIn(deep, node)
+ return ret
+ }
+
+ /**
+ * Resolve a `decoration`, relative to the node, ensuring that the keys and
+ * offsets in the decoration exist and that they are synced with the paths.
+ *
+ * @param {Decoration|Object} decoration
+ * @return {Decoration}
+ */
+
+ resolveDecoration(decoration) {
+ decoration = Decoration.create(decoration)
+ decoration = decoration.normalize(this)
+ return decoration
+ }
+
+ /**
+ * Resolve a `point`, relative to the node, ensuring that the keys and
+ * offsets in the point exist and that they are synced with the paths.
+ *
+ * @param {Point|Object} point
+ * @return {Point}
+ */
+
+ resolvePoint(point) {
+ point = Point.create(point)
+ point = point.normalize(this)
+ return point
+ }
+
+ /**
+ * Resolve a `range`, relative to the node, ensuring that the keys and
+ * offsets in the range exist and that they are synced with the paths.
+ *
+ * @param {Range|Object} range
+ * @return {Range}
+ */
+
+ resolveRange(range) {
+ range = Range.create(range)
+ range = range.normalize(this)
+ return range
+ }
+
+ /**
+ * Resolve a `selection`, relative to the node, ensuring that the keys and
+ * offsets in the selection exist and that they are synced with the paths.
+ *
+ * @param {Selection|Object} selection
+ * @return {Selection}
+ */
+
+ resolveSelection(selection) {
+ selection = Selection.create(selection)
+ selection = selection.normalize(this)
+ return selection
+ }
+
+ /**
+ * Set `properties` on a node.
+ *
+ * @param {List|String} path
+ * @param {Object} properties
+ * @return {Node}
+ */
+
+ setNode(path, properties) {
+ let node = this.assertNode(path)
+ node = node.merge(properties)
+ const ret = this.replaceNode(path, node)
+ return ret
+ }
+
+ /**
+ * Set `properties` on `mark` on text at `offset` and `length` in node.
+ *
+ * @param {List|String} path
+ * @param {Number} offset
+ * @param {Number} length
+ * @param {Mark} mark
+ * @param {Object} properties
+ * @return {Node}
+ */
+
+ setMark(path, offset, length, mark, properties) {
+ let node = this.assertNode(path)
+ node = node.updateMark(offset, length, mark, properties)
+ const ret = this.replaceNode(path, node)
+ return ret
+ }
+
+ /**
+ * Split a node by `path` at `position` with optional `properties` to apply
+ * to the newly split node.
+ *
+ * @param {List|String} path
+ * @param {Number} position
+ * @param {Object} properties
+ * @return {Node}
+ */
+
+ splitNode(path, position, properties) {
+ const child = this.assertNode(path)
+ path = this.resolvePath(path)
+ let a
+ let b
+
+ if (child.object === 'text') {
+ ;[a, b] = child.splitText(position)
+ } else {
+ const befores = child.nodes.take(position)
+ const afters = child.nodes.skip(position)
+ a = child.set('nodes', befores)
+ b = child.set('nodes', afters).regenerateKey()
+ }
+
+ if (properties && child.object !== 'text') {
+ b = b.merge(properties)
+ }
+
+ let ret = this
+ ret = ret.removeNode(path)
+ ret = ret.insertNode(path, b)
+ ret = ret.insertNode(path, a)
+ return ret
+ }
+}
+
+/**
+ * Mix in assertion variants.
+ */
+
+const ASSERTS = ['Child', 'Depth', 'Descendant', 'Node', 'Parent', 'Path']
+
+for (const method of ASSERTS) {
+ ElementInterface.prototype[`assert${method}`] = function(path, ...args) {
+ const ret = this[`get${method}`](path, ...args)
+
+ if (ret == null) {
+ throw new Error(
+ `\`Node.assert${method}\` could not find node with path or key: ${path}`
+ )
+ }
+
+ return ret
+ }
+}
+
+/**
+ * Memoize read methods.
+ */
+
+memoize(ElementInterface.prototype, [
+ 'getBlocksAsArray',
+ 'getBlocksAtRangeAsArray',
+ 'getBlocksByTypeAsArray',
+ 'getDecorations',
+ 'getFragmentAtRange',
+ 'getInlinesAsArray',
+ 'getInlinesAtRangeAsArray',
+ 'getInlinesByTypeAsArray',
+ 'getMarksAsArray',
+ 'getMarksAtPosition',
+ 'getOrderedMarksBetweenPositions',
+ 'getInsertMarksAtRange',
+ 'getMarksByTypeAsArray',
+ 'getNextBlock',
+ 'getOffset',
+ 'getOffsetAtRange',
+ 'getPreviousBlock',
+ 'getTextAtOffset',
+ 'getTextDirection',
+ 'getTextsAsArray',
+ 'getTextsBetweenPositionsAsArray',
+])
+
+/**
+ * Mix in the element interface.
+ */
+
+mixin(ElementInterface, [Block, Document, Inline])
diff --git a/packages/slate/src/interfaces/node.js b/packages/slate/src/interfaces/node.js
index d0f1abb91..9bd80d365 100644
--- a/packages/slate/src/interfaces/node.js
+++ b/packages/slate/src/interfaces/node.js
@@ -1,18 +1,14 @@
-import direction from 'direction'
-import logger from 'slate-dev-logger'
-import { List, OrderedSet, Set } from 'immutable'
+import warning from 'slate-dev-warning'
+import { List } from 'immutable'
import mixin from '../utils/mixin'
import Block from '../models/block'
-import Decoration from '../models/decoration'
import Document from '../models/document'
import Inline from '../models/inline'
import KeyUtils from '../utils/key-utils'
import memoize from '../utils/memoize'
import PathUtils from '../utils/path-utils'
-import Point from '../models/point'
-import Range from '../models/range'
-import Selection from '../models/selection'
+import Text from '../models/text'
/**
* The interface that `Document`, `Block` and `Inline` all implement, to make
@@ -23,7 +19,7 @@ import Selection from '../models/selection'
class NodeInterface {
/**
- * Get the concatenated text of all the block's children.
+ * Get the concatenated text of the node.
*
* @return {String}
*/
@@ -33,501 +29,38 @@ class NodeInterface {
}
/**
- * Add mark to text at `offset` and `length` in node by `path`.
+ * Check whether the node is a leaf inline.
*
- * @param {List|String} path
- * @param {Number} offset
- * @param {Number} length
- * @param {Mark} mark
- * @return {Node}
- */
-
- addMark(path, offset, length, mark) {
- let node = this.assertDescendant(path)
- path = this.resolvePath(path)
- node = node.addMark(offset, length, mark)
- const ret = this.replaceNode(path, node)
- return ret
- }
-
- /**
- * Create a decoration with `properties` relative to the node.
- *
- * @param {Object|Decoration} properties
- * @return {Decoration}
- */
-
- createDecoration(properties) {
- properties = Decoration.createProperties(properties)
- const decoration = this.resolveDecoration(properties)
- return decoration
- }
-
- /**
- * Create a point with `properties` relative to the node.
- *
- * @param {Object|Point} properties
- * @return {Range}
- */
-
- createPoint(properties) {
- properties = Point.createProperties(properties)
- const point = this.resolvePoint(properties)
- return point
- }
-
- /**
- * Create a range with `properties` relative to the node.
- *
- * @param {Object|Range} properties
- * @return {Range}
- */
-
- createRange(properties) {
- properties = Range.createProperties(properties)
- const range = this.resolveRange(properties)
- return range
- }
-
- /**
- * Create a selection with `properties` relative to the node.
- *
- * @param {Object|Selection} properties
- * @return {Selection}
- */
-
- createSelection(properties) {
- properties = Selection.createProperties(properties)
- const selection = this.resolveSelection(properties)
- return selection
- }
-
- /**
- * Recursively filter all descendant nodes with `iterator`.
- *
- * @param {Function} iterator
- * @return {List}
- */
-
- filterDescendants(iterator) {
- const matches = []
-
- this.forEachDescendant((node, i, nodes) => {
- if (iterator(node, i, nodes)) matches.push(node)
- })
-
- return List(matches)
- }
-
- /**
- * Recursively find all descendant nodes by `iterator`.
- *
- * @param {Function} iterator
- * @return {Node|Null}
- */
-
- findDescendant(iterator) {
- let found = null
-
- this.forEachDescendant((node, i, nodes) => {
- if (iterator(node, i, nodes)) {
- found = node
- return false
- }
- })
-
- return found
- }
-
- /**
- * Recursively iterate over all descendant nodes with `iterator`. If the
- * iterator returns false it will break the loop.
- *
- * @param {Function} iterator
- */
-
- forEachDescendant(iterator) {
- let ret
-
- this.nodes.forEach((child, i, nodes) => {
- if (iterator(child, i, nodes) === false) {
- ret = false
- return false
- }
-
- if (child.object != 'text') {
- ret = child.forEachDescendant(iterator)
- return ret
- }
- })
-
- return ret
- }
-
- /**
- * Get a set of the active marks in a `range`.
- *
- * @param {Range} range
- * @return {Set}
- */
-
- getActiveMarksAtRange(range) {
- range = this.resolveRange(range)
- if (range.isUnset) return Set()
-
- if (range.isCollapsed) {
- const { start } = range
- return this.getMarksAtPosition(start.key, start.offset).toSet()
- }
-
- const { start, end } = range
- let startKey = start.key
- let startOffset = start.offset
- let endKey = end.key
- let endOffset = end.offset
- let startText = this.getDescendant(startKey)
-
- if (startKey !== endKey) {
- while (startKey !== endKey && endOffset === 0) {
- const endText = this.getPreviousText(endKey)
- endKey = endText.key
- endOffset = endText.text.length
- }
-
- while (startKey !== endKey && startOffset === startText.text.length) {
- startText = this.getNextText(startKey)
- startKey = startText.key
- startOffset = 0
- }
- }
-
- if (startKey === endKey) {
- return startText.getActiveMarksBetweenOffsets(startOffset, endOffset)
- }
-
- const startMarks = startText.getActiveMarksBetweenOffsets(
- startOffset,
- startText.text.length
- )
- if (startMarks.size === 0) return Set()
- const endText = this.getDescendant(endKey)
- const endMarks = endText.getActiveMarksBetweenOffsets(0, endOffset)
- let marks = startMarks.intersect(endMarks)
- // If marks is already empty, the active marks is empty
- if (marks.size === 0) return marks
-
- let text = this.getNextText(startKey)
-
- while (text.key !== endKey) {
- if (text.text.length !== 0) {
- marks = marks.intersect(text.getActiveMarks())
- if (marks.size === 0) return Set()
- }
-
- text = this.getNextText(text.key)
- }
- return marks
- }
-
- /**
- * Get a list of the ancestors of a descendant.
- *
- * @param {List|String} path
- * @return {List|Null}
- */
-
- getAncestors(path) {
- path = this.resolvePath(path)
- if (!path) return null
-
- const ancestors = []
-
- path.forEach((p, i) => {
- const current = path.slice(0, i)
- const parent = this.getNode(current)
- ancestors.push(parent)
- })
-
- return List(ancestors)
- }
-
- /**
- * Get the leaf block descendants of the node.
- *
- * @return {List}
- */
-
- getBlocks() {
- const array = this.getBlocksAsArray()
- return List(array)
- }
-
- /**
- * Get the leaf block descendants of the node.
- *
- * @return {List}
- */
-
- getBlocksAsArray() {
- return this.nodes.reduce((array, child) => {
- if (child.object != 'block') return array
- if (!child.isLeafBlock()) return array.concat(child.getBlocksAsArray())
- array.push(child)
- return array
- }, [])
- }
-
- /**
- * Get the leaf block descendants in a `range`.
- *
- * @param {Range} range
- * @return {List}
- */
-
- getBlocksAtRange(range) {
- const array = this.getBlocksAtRangeAsArray(range)
- // Eliminate duplicates by converting to an `OrderedSet` first.
- return List(OrderedSet(array))
- }
-
- /**
- * Get the leaf block descendants in a `range` as an array
- *
- * @param {Range} range
- * @return {Array}
- */
-
- getBlocksAtRangeAsArray(range) {
- range = this.resolveRange(range)
- if (range.isUnset) return []
-
- const { start, end } = range
- const startBlock = this.getClosestBlock(start.key)
-
- // PERF: the most common case is when the range is in a single block node,
- // where we can avoid a lot of iterating of the tree.
- if (start.key === end.key) return [startBlock]
-
- const endBlock = this.getClosestBlock(end.key)
- const blocks = this.getBlocksAsArray()
- const startIndex = blocks.indexOf(startBlock)
- const endIndex = blocks.indexOf(endBlock)
- return blocks.slice(startIndex, endIndex + 1)
- }
-
- /**
- * Get all of the leaf blocks that match a `type`.
- *
- * @param {String} type
- * @return {List}
- */
-
- getBlocksByType(type) {
- const array = this.getBlocksByTypeAsArray(type)
- return List(array)
- }
-
- /**
- * Get all of the leaf blocks that match a `type` as an array
- *
- * @param {String} type
- * @return {Array}
- */
-
- getBlocksByTypeAsArray(type) {
- return this.nodes.reduce((array, node) => {
- if (node.object != 'block') {
- return array
- } else if (node.isLeafBlock() && node.type == type) {
- array.push(node)
- return array
- } else {
- return array.concat(node.getBlocksByTypeAsArray(type))
- }
- }, [])
- }
-
- /**
- * Get a child node.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getChild(path) {
- path = this.resolvePath(path)
- if (!path) return null
- const child = path.size === 1 ? this.nodes.get(path.first()) : null
- return child
- }
-
- /**
- * Get closest parent of node that matches an `iterator`.
- *
- * @param {List|String} path
- * @param {Function} iterator
- * @return {Node|Null}
- */
-
- getClosest(path, iterator) {
- const ancestors = this.getAncestors(path)
- if (!ancestors) return null
-
- const closest = ancestors.findLast((node, ...args) => {
- // We never want to include the top-level node.
- if (node === this) return false
- return iterator(node, ...args)
- })
-
- return closest || null
- }
-
- /**
- * Get the closest block parent of a node.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getClosestBlock(path) {
- const closest = this.getClosest(path, n => n.object === 'block')
- return closest
- }
-
- /**
- * Get the closest inline parent of a node by `path`.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getClosestInline(path) {
- const closest = this.getClosest(path, n => n.object === 'inline')
- return closest
- }
-
- /**
- * Get the closest void parent of a node by `path`.
- *
- * @param {List|String} path
- * @param {Schema} schema
- * @return {Node|Null}
- */
-
- getClosestVoid(path, schema) {
- if (!schema) {
- logger.deprecate(
- '0.38.0',
- 'Calling the `Node.getClosestVoid` method without passing a second `schema` argument is deprecated.'
- )
-
- const closest = this.getClosest(path, p => p.get('isVoid'))
- return closest
- }
-
- const ancestors = this.getAncestors(path)
- const ancestor = ancestors.findLast(a => schema.isVoid(a))
- return ancestor
- }
-
- /**
- * Get the common ancestor of nodes `a` and `b`.
- *
- * @param {List} a
- * @param {List} b
- * @return {Node}
- */
-
- getCommonAncestor(a, b) {
- a = this.resolvePath(a)
- b = this.resolvePath(b)
- if (!a || !b) return null
-
- const path = PathUtils.relate(a, b)
- const node = this.getNode(path)
- return node
- }
-
- /**
- * Get the decorations for the node from a `stack`.
- *
- * @param {Stack} stack
- * @return {List}
- */
-
- getDecorations(stack) {
- const decorations = stack.find('decorateNode', this)
- const list = Decoration.createList(decorations || [])
- return list
- }
-
- /**
- * Get the depth of a descendant, with optional `startAt`.
- *
- * @param {List|String} path
- * @param {Number} startAt
- * @return {Number|Null}
- */
-
- getDepth(path, startAt = 1) {
- path = this.resolvePath(path)
- if (!path) return null
-
- const node = this.getNode(path)
- const depth = node ? path.size - 1 + startAt : null
- return depth
- }
-
- /**
- * Get a descendant node.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getDescendant(path) {
- path = this.resolvePath(path)
- if (!path) return null
-
- const deep = path.flatMap(x => ['nodes', x])
- const ret = this.getIn(deep)
- return ret
- }
-
- /**
- * Get the first invalid descendant
- *
- * @param {Schema} schema
- * @return {Node|Text|Null}
+ * @return {Boolean}
*/
getFirstInvalidNode(schema) {
- let result = null
+ if (this.object === 'text') {
+ const invalid = this.validate(schema) ? this : null
+ return invalid
+ }
+
+ let invalid = null
this.nodes.find(n => {
- result = n.validate(schema) ? n : n.getFirstInvalidNode(schema)
- return result
+ invalid = n.validate(schema) ? n : n.getFirstInvalidNode(schema)
+ return invalid
})
- return result
- }
-
- getFirstInvalidDescendant(schema) {
- logger.deprecate(
- '0.39.0',
- 'The `Node.getFirstInvalidDescendant` method is deprecated, please use `Node.getFirstInvalidNode` instead.'
- )
-
- return this.getFirstInvalidNode(schema)
+ return invalid
}
/**
- * Get the first child text node.
+ * Get the first text node of a node, or the node itself.
*
* @return {Node|Null}
*/
getFirstText() {
+ if (this.object === 'text') {
+ return this
+ }
+
let descendant = null
const found = this.nodes.find(node => {
@@ -539,251 +72,6 @@ class NodeInterface {
return descendant || found
}
- /**
- * Get a fragment of the node at a `range`.
- *
- * @param {Range} range
- * @return {Document}
- */
-
- getFragmentAtRange(range) {
- range = this.resolveRange(range)
-
- if (range.isUnset) {
- return Document.create()
- }
-
- const { start, end } = range
- let node = this
- let targetPath = end.path
- let targetPosition = end.offset
- let mode = 'end'
-
- while (targetPath.size) {
- const index = targetPath.last()
- node = node.splitNode(targetPath, targetPosition)
- targetPosition = index + 1
- targetPath = PathUtils.lift(targetPath)
-
- if (!targetPath.size && mode === 'end') {
- targetPath = start.path
- targetPosition = start.offset
- mode = 'start'
- }
- }
-
- const startIndex = start.path.first() + 1
- const endIndex = end.path.first() + 2
- const nodes = node.nodes.slice(startIndex, endIndex)
- const fragment = Document.create({ nodes })
- return fragment
- }
-
- /**
- * Get the furthest parent of a node that matches an `iterator`.
- *
- * @param {Path} path
- * @param {Function} iterator
- * @return {Node|Null}
- */
-
- getFurthest(path, iterator) {
- const ancestors = this.getAncestors(path)
- if (!ancestors) return null
-
- const furthest = ancestors.find((node, ...args) => {
- // We never want to include the top-level node.
- if (node === this) return false
- return iterator(node, ...args)
- })
-
- return furthest || null
- }
-
- /**
- * Get the furthest ancestor of a node.
- *
- * @param {Path} path
- * @return {Node|Null}
- */
-
- getFurthestAncestor(path) {
- path = this.resolvePath(path)
- if (!path) return null
- const furthest = path.size ? this.nodes.get(path.first()) : null
- return furthest
- }
-
- /**
- * Get the furthest block parent of a node.
- *
- * @param {Path} path
- * @return {Node|Null}
- */
-
- getFurthestBlock(path) {
- const furthest = this.getFurthest(path, n => n.object === 'block')
- return furthest
- }
-
- /**
- * Get the furthest inline parent of a node.
- *
- * @param {Path} path
- * @return {Node|Null}
- */
-
- getFurthestInline(path) {
- const furthest = this.getFurthest(path, n => n.object === 'inline')
- return furthest
- }
-
- /**
- * Get the furthest ancestor of a node that has only one child.
- *
- * @param {Path} path
- * @return {Node|Null}
- */
-
- getFurthestOnlyChildAncestor(path) {
- const ancestors = this.getAncestors(path)
- if (!ancestors) return null
-
- const furthest = ancestors
- .rest()
- .reverse()
- .takeUntil(p => p.nodes.size > 1)
- .last()
-
- return furthest || null
- }
-
- /**
- * Get the closest inline nodes for each text node in the node.
- *
- * @return {List}
- */
-
- getInlines() {
- const array = this.getInlinesAsArray()
- const list = List(array)
- return list
- }
-
- /**
- * Get the closest inline nodes for each text node in the node, as an array.
- *
- * @return {List}
- */
-
- getInlinesAsArray() {
- let array = []
-
- this.nodes.forEach(child => {
- if (child.object == 'text') return
-
- if (child.isLeafInline()) {
- array.push(child)
- } else {
- array = array.concat(child.getInlinesAsArray())
- }
- })
-
- return array
- }
-
- /**
- * Get the closest inline nodes for each text node in a `range`.
- *
- * @param {Range} range
- * @return {List}
- */
-
- getInlinesAtRange(range) {
- const array = this.getInlinesAtRangeAsArray(range)
- // Remove duplicates by converting it to an `OrderedSet` first.
- const list = List(OrderedSet(array))
- return list
- }
-
- /**
- * Get the closest inline nodes for each text node in a `range` as an array.
- *
- * @param {Range} range
- * @return {Array}
- */
-
- getInlinesAtRangeAsArray(range) {
- range = this.resolveRange(range)
- if (range.isUnset) return []
-
- const array = this.getTextsAtRangeAsArray(range)
- .map(text => this.getClosestInline(text.key))
- .filter(exists => exists)
-
- return array
- }
-
- /**
- * Get all of the leaf inline nodes that match a `type`.
- *
- * @param {String} type
- * @return {List}
- */
-
- getInlinesByType(type) {
- const array = this.getInlinesByTypeAsArray(type)
- const list = List(array)
- return list
- }
-
- /**
- * Get all of the leaf inline nodes that match a `type` as an array.
- *
- * @param {String} type
- * @return {Array}
- */
-
- getInlinesByTypeAsArray(type) {
- const array = this.nodes.reduce((inlines, node) => {
- if (node.object == 'text') {
- return inlines
- } else if (node.isLeafInline() && node.type == type) {
- inlines.push(node)
- return inlines
- } else {
- return inlines.concat(node.getInlinesByTypeAsArray(type))
- }
- }, [])
-
- return array
- }
-
- /**
- * Get a set of the marks in a `range`.
- *
- * @param {Range} range
- * @return {Set}
- */
-
- getInsertMarksAtRange(range) {
- range = this.resolveRange(range)
- const { start } = range
-
- if (range.isUnset) {
- return Set()
- }
-
- if (range.isCollapsed) {
- // PERF: range is not cachable, use key and offset as proxies for cache
- return this.getMarksAtPosition(start.key, start.offset)
- }
-
- const text = this.getDescendant(start.key)
- const marks = text.getMarksAtIndex(start.offset + 1)
- return marks
- }
-
/**
* Get an object mapping all the keys in the node to their paths.
*
@@ -795,33 +83,37 @@ class NodeInterface {
[this.key]: [],
}
- this.nodes.forEach((node, i) => {
- const nested = node.getKeysToPathsTable()
+ if (this.nodes) {
+ this.nodes.forEach((node, i) => {
+ const nested = node.getKeysToPathsTable()
- for (const key in nested) {
- const path = nested[key]
+ for (const key in nested) {
+ const path = nested[key]
- if (ret[key]) {
- logger.warn(
- `A node with a duplicate key of "${key}" was found! Duplicate keys are not allowed, you should use \`node.regenerateKey\` before inserting if you are reusing an existing node.`,
- this
+ warning(
+ !(key in ret),
+ `A node with a duplicate key of "${key}" was found! Duplicate keys are not allowed, you should use \`node.regenerateKey\` before inserting if you are reusing an existing node.`
)
- }
- ret[key] = [i, ...path]
- }
- })
+ ret[key] = [i, ...path]
+ }
+ })
+ }
return ret
}
/**
- * Get the last child text node.
+ * Get the last text node of a node, or the node itself.
*
* @return {Node|Null}
*/
getLastText() {
+ if (this.object === 'text') {
+ return this
+ }
+
let descendant = null
const found = this.nodes.findLast(node => {
@@ -834,189 +126,7 @@ class NodeInterface {
}
/**
- * Get all of the marks for all of the characters of every text node.
- *
- * @return {Set}
- */
-
- getMarks() {
- const array = this.getMarksAsArray()
- return Set(array)
- }
-
- /**
- * Get all of the marks as an array.
- *
- * @return {Array}
- */
-
- getMarksAsArray() {
- const result = []
-
- this.nodes.forEach(node => {
- result.push(node.getMarksAsArray())
- })
-
- // PERF: use only one concat rather than multiple for speed.
- const array = [].concat(...result)
- return array
- }
-
- /**
- * Get a set of marks in a `position`, the equivalent of a collapsed range
- *
- * @param {string} key
- * @param {number} offset
- * @return {Set}
- */
-
- getMarksAtPosition(key, offset) {
- const text = this.getDescendant(key)
- const currentMarks = text.getMarksAtIndex(offset)
- if (offset !== 0) return currentMarks
- const closestBlock = this.getClosestBlock(key)
-
- if (closestBlock.text === '') {
- // insert mark for empty block; the empty block are often created by split node or add marks in a range including empty blocks
- return currentMarks
- }
-
- const previous = this.getPreviousText(key)
- if (!previous) return Set()
-
- if (closestBlock.hasDescendant(previous.key)) {
- return previous.getMarksAtIndex(previous.text.length)
- }
-
- return currentMarks
- }
-
- /**
- * Get a set of the marks in a `range`.
- *
- * @param {Range} range
- * @return {Set}
- */
-
- getMarksAtRange(range) {
- const marks = Set(this.getOrderedMarksAtRange(range))
- return marks
- }
-
- /**
- * Get all of the marks that match a `type`.
- *
- * @param {String} type
- * @return {Set}
- */
-
- getMarksByType(type) {
- const array = this.getMarksByTypeAsArray(type)
- return Set(array)
- }
-
- /**
- * Get all of the marks that match a `type` as an array.
- *
- * @param {String} type
- * @return {Array}
- */
-
- getMarksByTypeAsArray(type) {
- const array = this.nodes.reduce((memo, node) => {
- return node.object == 'text'
- ? memo.concat(node.getMarksAsArray().filter(m => m.type == type))
- : memo.concat(node.getMarksByTypeAsArray(type))
- }, [])
-
- return array
- }
-
- /**
- * Get the block node before a descendant text node by `key`.
- *
- * @param {String} key
- * @return {Node|Null}
- */
-
- getNextBlock(key) {
- const child = this.assertDescendant(key)
- let last
-
- if (child.object == 'block') {
- last = child.getLastText()
- } else {
- const block = this.getClosestBlock(key)
- last = block.getLastText()
- }
-
- const next = this.getNextText(last.key)
- if (!next) return null
-
- const closest = this.getClosestBlock(next.key)
- return closest
- }
-
- /**
- * Get the next node in the tree from a node.
- *
- * This will not only check for siblings but instead move up the tree
- * returning the next ancestor if no sibling is found.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getNextNode(path) {
- path = this.resolvePath(path)
- if (!path) return null
- if (!path.size) return null
-
- for (let i = path.size; i > 0; i--) {
- const p = path.slice(0, i)
- const target = PathUtils.increment(p)
- const node = this.getNode(target)
- if (node) return node
- }
-
- return null
- }
-
- /**
- * Get the next sibling of a node.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getNextSibling(path) {
- path = this.resolvePath(path)
- if (!path) return null
- if (!path.size) return null
- const p = PathUtils.increment(path)
- const sibling = this.getNode(p)
- return sibling
- }
-
- /**
- * Get the text node after a descendant text node.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getNextText(path) {
- path = this.resolvePath(path)
- if (!path) return null
- if (!path.size) return null
- const next = this.getNextNode(path)
- if (!next) return null
- const text = next.getFirstText()
- return text
- }
-
- /**
- * Get a node in the tree.
+ * Get a node in the tree, or the node itself.
*
* @param {List|String} path
* @return {Node|Null}
@@ -1025,157 +135,11 @@ class NodeInterface {
getNode(path) {
path = this.resolvePath(path)
if (!path) return null
+ if (this.object === 'text' && path.size) return null
const node = path.size ? this.getDescendant(path) : this
return node
}
- /**
- * Get the offset for a descendant text node by `key`.
- *
- * @param {String} key
- * @return {Number}
- */
-
- getOffset(key) {
- this.assertDescendant(key)
-
- // Calculate the offset of the nodes before the highest child.
- const child = this.getFurthestAncestor(key)
- const offset = this.nodes
- .takeUntil(n => n == child)
- .reduce((memo, n) => memo + n.text.length, 0)
-
- // Recurse if need be.
- const ret = this.hasChild(key) ? offset : offset + child.getOffset(key)
- return ret
- }
-
- /**
- * Get the offset from a `range`.
- *
- * @param {Range} range
- * @return {Number}
- */
-
- getOffsetAtRange(range) {
- range = this.resolveRange(range)
-
- if (range.isUnset) {
- throw new Error('The range cannot be unset to calculcate its offset.')
- }
-
- if (range.isExpanded) {
- throw new Error('The range must be collapsed to calculcate its offset.')
- }
-
- const { start } = range
- const offset = this.getOffset(start.key) + start.offset
- return offset
- }
-
- /**
- * Get all of the marks for all of the characters of every text node.
- *
- * @return {OrderedSet}
- */
-
- getOrderedMarks() {
- const array = this.getMarksAsArray()
- return OrderedSet(array)
- }
-
- /**
- * Get a set of the marks in a `range`.
- *
- * @param {Range} range
- * @return {OrderedSet}
- */
-
- getOrderedMarksAtRange(range) {
- range = this.resolveRange(range)
- const { start, end } = range
-
- if (range.isUnset) {
- return OrderedSet()
- }
-
- if (range.isCollapsed) {
- // PERF: range is not cachable, use key and offset as proxies for cache
- return this.getMarksAtPosition(start.key, start.offset)
- }
-
- const marks = this.getOrderedMarksBetweenPositions(
- start.key,
- start.offset,
- end.key,
- end.offset
- )
-
- return marks
- }
-
- /**
- * Get a set of the marks in a `range`.
- * PERF: arguments use key and offset for utilizing cache
- *
- * @param {string} startKey
- * @param {number} startOffset
- * @param {string} endKey
- * @param {number} endOffset
- * @returns {OrderedSet}
- */
-
- getOrderedMarksBetweenPositions(startKey, startOffset, endKey, endOffset) {
- if (startKey === endKey) {
- const startText = this.getDescendant(startKey)
- return startText.getMarksBetweenOffsets(startOffset, endOffset)
- }
-
- const texts = this.getTextsBetweenPositionsAsArray(startKey, endKey)
-
- return OrderedSet().withMutations(result => {
- texts.forEach(text => {
- if (text.key === startKey) {
- result.union(
- text.getMarksBetweenOffsets(startOffset, text.text.length)
- )
- } else if (text.key === endKey) {
- result.union(text.getMarksBetweenOffsets(0, endOffset))
- } else {
- result.union(text.getMarks())
- }
- })
- })
- }
-
- /**
- * Get all of the marks that match a `type`.
- *
- * @param {String} type
- * @return {OrderedSet}
- */
-
- getOrderedMarksByType(type) {
- const array = this.getMarksByTypeAsArray(type)
- return OrderedSet(array)
- }
-
- /**
- * Get the parent of a descendant node.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getParent(path) {
- path = this.resolvePath(path)
- if (!path) return null
- if (!path.size) return null
- const parentPath = PathUtils.lift(path)
- const parent = this.getNode(parentPath)
- return parent
- }
-
/**
* Find the path to a node.
*
@@ -1193,326 +157,19 @@ class NodeInterface {
}
/**
- * Get the block node before a descendant text node by `key`.
- *
- * @param {String} key
- * @return {Node|Null}
- */
-
- getPreviousBlock(key) {
- const child = this.assertDescendant(key)
- let first
-
- if (child.object == 'block') {
- first = child.getFirstText()
- } else {
- const block = this.getClosestBlock(key)
- first = block.getFirstText()
- }
-
- const previous = this.getPreviousText(first.key)
- if (!previous) return null
-
- const closest = this.getClosestBlock(previous.key)
- return closest
- }
-
- /**
- * Get the previous node from a node in the tree.
- *
- * This will not only check for siblings but instead move up the tree
- * returning the previous ancestor if no sibling is found.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getPreviousNode(path) {
- path = this.resolvePath(path)
- if (!path) return null
- if (!path.size) return null
-
- for (let i = path.size; i > 0; i--) {
- const p = path.slice(0, i)
- if (p.last() === 0) continue
-
- const target = PathUtils.decrement(p)
- const node = this.getNode(target)
- if (node) return node
- }
-
- return null
- }
-
- /**
- * Get the previous sibling of a node.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getPreviousSibling(path) {
- path = this.resolvePath(path)
- if (!path) return null
- if (!path.size) return null
- if (path.last() === 0) return null
- const p = PathUtils.decrement(path)
- const sibling = this.getNode(p)
- return sibling
- }
-
- /**
- * Get the text node after a descendant text node.
- *
- * @param {List|String} path
- * @return {Node|Null}
- */
-
- getPreviousText(path) {
- path = this.resolvePath(path)
- if (!path) return null
- if (!path.size) return null
- const previous = this.getPreviousNode(path)
- if (!previous) return null
- const text = previous.getLastText()
- return text
- }
-
- /**
- * Get the indexes of the selection for a `range`, given an extra flag for
- * whether the node `isSelected`, to determine whether not finding matches
- * means everything is selected or nothing is.
- *
- * @param {Range} range
- * @param {Boolean} isSelected
- * @return {Object|Null}
- */
-
- getSelectionIndexes(range, isSelected = true) {
- const { start, end } = range
-
- // PERF: if we're not selected, we can exit early.
- if (!isSelected) {
- return null
- }
-
- // if we've been given an invalid selection we can exit early.
- if (range.isUnset) {
- return null
- }
-
- // PERF: if the start and end keys are the same, just check for the child
- // that contains that single key.
- if (start.key == end.key) {
- const child = this.getFurthestAncestor(start.key)
- const index = child ? this.nodes.indexOf(child) : null
- return { start: index, end: index + 1 }
- }
-
- // Otherwise, check all of the children...
- let startIndex = null
- let endIndex = null
-
- this.nodes.forEach((child, i) => {
- if (child.object == 'text') {
- if (startIndex == null && child.key == start.key) startIndex = i
- if (endIndex == null && child.key == end.key) endIndex = i + 1
- } else {
- if (startIndex == null && child.hasDescendant(start.key)) startIndex = i
- if (endIndex == null && child.hasDescendant(end.key)) endIndex = i + 1
- }
-
- // PERF: exit early if both start and end have been found.
- return startIndex == null || endIndex == null
- })
-
- if (isSelected && startIndex == null) startIndex = 0
- if (isSelected && endIndex == null) endIndex = this.nodes.size
- return startIndex == null ? null : { start: startIndex, end: endIndex }
- }
-
- /**
- * Get the concatenated text string of all child nodes.
+ * Get the concatenated text string of a node.
*
* @return {String}
*/
getText() {
- const text = this.nodes.reduce((string, node) => {
- return string + node.text
- }, '')
-
+ const children = this.object === 'text' ? this.leaves : this.nodes
+ const text = children.reduce((memo, c) => memo + c.text, '')
return text
}
/**
- * Get the descendent text node at an `offset`.
- *
- * @param {String} offset
- * @return {Node|Null}
- */
-
- getTextAtOffset(offset) {
- // PERF: Add a few shortcuts for the obvious cases.
- if (offset === 0) return this.getFirstText()
- if (offset === this.text.length) return this.getLastText()
- if (offset < 0 || offset > this.text.length) return null
-
- let length = 0
- const text = this.getTexts().find((node, i, nodes) => {
- length += node.text.length
- return length > offset
- })
-
- return text
- }
-
- /**
- * Get the direction of the node's text.
- *
- * @return {String}
- */
-
- getTextDirection() {
- const dir = direction(this.text)
- return dir === 'neutral' ? null : dir
- }
-
- /**
- * Recursively get all of the child text nodes in order of appearance.
- *
- * @return {List}
- */
-
- getTexts() {
- const array = this.getTextsAsArray()
- return List(array)
- }
-
- /**
- * Recursively get all the leaf text nodes in order of appearance, as array.
- *
- * @return {List}
- */
-
- getTextsAsArray() {
- let array = []
-
- this.nodes.forEach(node => {
- if (node.object == 'text') {
- array.push(node)
- } else {
- array = array.concat(node.getTextsAsArray())
- }
- })
-
- return array
- }
-
- /**
- * Get all of the text nodes in a `range`.
- *
- * @param {Range} range
- * @return {List}
- */
-
- getTextsAtRange(range) {
- range = this.resolveRange(range)
- if (range.isUnset) return List()
- const { start, end } = range
- const list = List(this.getTextsBetweenPositionsAsArray(start.key, end.key))
-
- return list
- }
-
- /**
- * Get all of the text nodes in a `range` as an array.
- *
- * @param {Range} range
- * @return {Array}
- */
-
- getTextsAtRangeAsArray(range) {
- range = this.resolveRange(range)
- if (range.isUnset) return []
- const { start, end } = range
- const texts = this.getTextsBetweenPositionsAsArray(start.key, end.key)
- return texts
- }
-
- /**
- * Get all of the text nodes in a `range` as an array.
- * PERF: use key in arguments for cache
- *
- * @param {string} startKey
- * @param {string} endKey
- * @returns {Array}
- */
-
- getTextsBetweenPositionsAsArray(startKey, endKey) {
- const startText = this.getDescendant(startKey)
-
- // PERF: the most common case is when the range is in a single text node,
- // where we can avoid a lot of iterating of the tree.
- if (startKey == endKey) return [startText]
-
- const endText = this.getDescendant(endKey)
- const texts = this.getTextsAsArray()
- const start = texts.indexOf(startText)
- const end = texts.indexOf(endText, start)
- const ret = texts.slice(start, end + 1)
- return ret
- }
-
- /**
- * Check if the node has block children.
- *
- * @return {Boolean}
- */
-
- hasBlockChildren() {
- return !!(this.nodes && this.nodes.find(n => n.object === 'block'))
- }
-
- /**
- * Check if a child node exists.
- *
- * @param {List|String} path
- * @return {Boolean}
- */
-
- hasChild(path) {
- const child = this.getChild(path)
- return !!child
- }
-
- /**
- * Check if a node has inline children.
- *
- * @return {Boolean}
- */
-
- hasInlineChildren() {
- return !!(
- this.nodes &&
- this.nodes.find(n => n.object === 'inline' || n.object === 'text')
- )
- }
-
- /**
- * Recursively check if a child node exists.
- *
- * @param {List|String} path
- * @return {Boolean}
- */
-
- hasDescendant(path) {
- const descendant = this.getDescendant(path)
- return !!descendant
- }
-
- /**
- * Recursively check if a node exists.
+ * Check if a node exists.
*
* @param {List|String} path
* @return {Boolean}
@@ -1524,208 +181,7 @@ class NodeInterface {
}
/**
- * Check if a node has a void parent.
- *
- * @param {List|String} path
- * @param {Schema} schema
- * @return {Boolean}
- */
-
- hasVoidParent(path, schema) {
- if (!schema) {
- logger.deprecate(
- '0.38.0',
- 'Calling the `Node.hasVoidParent` method without the second `schema` argument is deprecated.'
- )
-
- const closest = this.getClosestVoid(path)
- return !!closest
- }
-
- const closest = this.getClosestVoid(path, schema)
- return !!closest
- }
-
- /**
- * Insert a `node`.
- *
- * @param {List|String} path
- * @param {Node} node
- * @return {Node}
- */
-
- insertNode(path, node) {
- path = this.resolvePath(path)
- const index = path.last()
- const parentPath = PathUtils.lift(path)
- let parent = this.assertNode(parentPath)
- const nodes = parent.nodes.splice(index, 0, node)
- parent = parent.set('nodes', nodes)
- const ret = this.replaceNode(parentPath, parent)
- return ret
- }
-
- /**
- * Insert `text` at `offset` in node by `path`.
- *
- * @param {List|String} path
- * @param {Number} offset
- * @param {String} text
- * @param {Set} marks
- * @return {Node}
- */
-
- insertText(path, offset, text, marks) {
- let node = this.assertDescendant(path)
- path = this.resolvePath(path)
- node = node.insertText(offset, text, marks)
- const ret = this.replaceNode(path, node)
- return ret
- }
-
- /**
- * Check whether the node is a leaf block.
- *
- * @return {Boolean}
- */
-
- isLeafBlock() {
- return (
- this.object === 'block' && this.nodes.every(n => n.object !== 'block')
- )
- }
-
- /**
- * Check whether the node is a leaf inline.
- *
- * @return {Boolean}
- */
-
- isLeafInline() {
- return (
- this.object === 'inline' && this.nodes.every(n => n.object !== 'inline')
- )
- }
-
- /**
- * Map all child nodes, updating them in their parents. This method is
- * optimized to not return a new node if no changes are made.
- *
- * @param {Function} iterator
- * @return {Node}
- */
-
- mapChildren(iterator) {
- let { nodes } = this
-
- nodes.forEach((node, i) => {
- const ret = iterator(node, i, this.nodes)
- if (ret !== node) nodes = nodes.set(ret.key, ret)
- })
-
- const ret = this.set('nodes', nodes)
- return ret
- }
-
- /**
- * Map all descendant nodes, updating them in their parents. This method is
- * optimized to not return a new node if no changes are made.
- *
- * @param {Function} iterator
- * @return {Node}
- */
-
- mapDescendants(iterator) {
- let { nodes } = this
-
- nodes.forEach((node, index) => {
- let ret = node
- if (ret.object !== 'text') ret = ret.mapDescendants(iterator)
- ret = iterator(ret, index, this.nodes)
- if (ret === node) return
-
- nodes = nodes.set(index, ret)
- })
-
- const ret = this.set('nodes', nodes)
- return ret
- }
-
- /**
- * Merge a node backwards its previous sibling.
- *
- * @param {List|Key} path
- * @return {Node}
- */
-
- mergeNode(path) {
- const b = this.assertNode(path)
- path = this.resolvePath(path)
-
- if (path.last() === 0) {
- throw new Error(
- `Unable to merge node because it has no previous sibling: ${b}`
- )
- }
-
- const withPath = PathUtils.decrement(path)
- const a = this.assertNode(withPath)
-
- if (a.object !== b.object) {
- throw new Error(
- `Unable to merge two different kinds of nodes: ${a} and ${b}`
- )
- }
-
- const newNode =
- a.object === 'text'
- ? a.mergeText(b)
- : a.set('nodes', a.nodes.concat(b.nodes))
-
- let ret = this
- ret = ret.removeNode(path)
- ret = ret.removeNode(withPath)
- ret = ret.insertNode(withPath, newNode)
- return ret
- }
-
- /**
- * Move a node by `path` to `newPath`.
- *
- * A `newIndex` can be provided when move nodes by `key`, to account for not
- * being able to have a key for a location in the tree that doesn't exist yet.
- *
- * @param {List|Key} path
- * @param {List|Key} newPath
- * @param {Number} newIndex
- * @return {Node}
- */
-
- moveNode(path, newPath, newIndex = 0) {
- const node = this.assertNode(path)
- path = this.resolvePath(path)
- newPath = this.resolvePath(newPath, newIndex)
-
- const newParentPath = PathUtils.lift(newPath)
- this.assertNode(newParentPath)
-
- const [p, np] = PathUtils.crop(path, newPath)
- const position = PathUtils.compare(p, np)
-
- // If the old path ends above and before a node in the new path, then
- // removing it will alter the target, so we need to adjust the new path.
- if (path.size < newPath.size && position === -1) {
- newPath = PathUtils.decrement(newPath, 1, p.size - 1)
- }
-
- let ret = this
- ret = ret.removeNode(path)
- ret = ret.insertNode(newPath, node)
- return ret
- }
-
- /**
- * Normalize the node with a `schema`.
+ * Normalize the text node with a `schema`.
*
* @param {Schema} schema
* @return {Function|Void}
@@ -1736,36 +192,6 @@ class NodeInterface {
return normalizer
}
- /**
- * Attempt to "refind" a node by a previous `path`, falling back to looking
- * it up by `key` again.
- *
- * @param {List|String} path
- * @param {String} key
- * @return {Node|Null}
- */
-
- refindNode(path, key) {
- const node = this.getDescendant(path)
- const found = node && node.key === key ? node : this.getDescendant(key)
- return found
- }
-
- /**
- * Attempt to "refind" the path to a node by a previous `path`, falling back
- * to looking it up by `key`.
- *
- * @param {List|String} path
- * @param {String} key
- * @return {List|Null}
- */
-
- refindPath(path, key) {
- const node = this.getDescendant(path)
- const found = node && node.key === key ? path : this.getPath(key)
- return found
- }
-
/**
* Regenerate the node's key.
*
@@ -1778,93 +204,6 @@ class NodeInterface {
return node
}
- /**
- * Remove mark from text at `offset` and `length` in node.
- *
- * @param {List} path
- * @param {Number} offset
- * @param {Number} length
- * @param {Mark} mark
- * @return {Node}
- */
-
- removeMark(path, offset, length, mark) {
- let node = this.assertDescendant(path)
- path = this.resolvePath(path)
- node = node.removeMark(offset, length, mark)
- const ret = this.replaceNode(path, node)
- return ret
- }
-
- /**
- * Remove a node.
- *
- * @param {List|String} path
- * @return {Node}
- */
-
- removeNode(path) {
- this.assertDescendant(path)
- path = this.resolvePath(path)
- const deep = path.flatMap(x => ['nodes', x])
- const ret = this.deleteIn(deep)
- return ret
- }
-
- /**
- * Remove `text` at `offset` in node.
- *
- * @param {List|Key} path
- * @param {Number} offset
- * @param {String} text
- * @return {Node}
- */
-
- removeText(path, offset, text) {
- let node = this.assertDescendant(path)
- node = node.removeText(offset, text.length)
- const ret = this.replaceNode(path, node)
- return ret
- }
-
- /**
- * Replace a `node` in the tree.
- *
- * @param {List|Key} path
- * @param {Node} node
- * @return {Node}
- */
-
- replaceNode(path, node) {
- path = this.resolvePath(path)
-
- if (!path) {
- throw new Error(
- `Unable to replace a node because it could not be found in the first place: ${path}`
- )
- }
-
- if (!path.size) return node
- this.assertNode(path)
- const deep = path.flatMap(x => ['nodes', x])
- const ret = this.setIn(deep, node)
- return ret
- }
-
- /**
- * Resolve a `decoration`, relative to the node, ensuring that the keys and
- * offsets in the decoration exist and that they are synced with the paths.
- *
- * @param {Decoration|Object} decoration
- * @return {Decoration}
- */
-
- resolveDecoration(decoration) {
- decoration = Decoration.create(decoration)
- decoration = decoration.normalize(this)
- return decoration
- }
-
/**
* Resolve a path from a path list or key string.
*
@@ -1892,117 +231,6 @@ class NodeInterface {
return path
}
- /**
- * Resolve a `point`, relative to the node, ensuring that the keys and
- * offsets in the point exist and that they are synced with the paths.
- *
- * @param {Point|Object} point
- * @return {Point}
- */
-
- resolvePoint(point) {
- point = Point.create(point)
- point = point.normalize(this)
- return point
- }
-
- /**
- * Resolve a `range`, relative to the node, ensuring that the keys and
- * offsets in the range exist and that they are synced with the paths.
- *
- * @param {Range|Object} range
- * @return {Range}
- */
-
- resolveRange(range) {
- range = Range.create(range)
- range = range.normalize(this)
- return range
- }
-
- /**
- * Resolve a `selection`, relative to the node, ensuring that the keys and
- * offsets in the selection exist and that they are synced with the paths.
- *
- * @param {Selection|Object} selection
- * @return {Selection}
- */
-
- resolveSelection(selection) {
- selection = Selection.create(selection)
- selection = selection.normalize(this)
- return selection
- }
-
- /**
- * Set `properties` on a node.
- *
- * @param {List|String} path
- * @param {Object} properties
- * @return {Node}
- */
-
- setNode(path, properties) {
- let node = this.assertNode(path)
- node = node.merge(properties)
- const ret = this.replaceNode(path, node)
- return ret
- }
-
- /**
- * Set `properties` on `mark` on text at `offset` and `length` in node.
- *
- * @param {List|String} path
- * @param {Number} offset
- * @param {Number} length
- * @param {Mark} mark
- * @param {Object} properties
- * @return {Node}
- */
-
- setMark(path, offset, length, mark, properties) {
- let node = this.assertNode(path)
- node = node.updateMark(offset, length, mark, properties)
- const ret = this.replaceNode(path, node)
- return ret
- }
-
- /**
- * Split a node by `path` at `position` with optional `properties` to apply
- * to the newly split node.
- *
- * @param {List|String} path
- * @param {Number} position
- * @param {Object} properties
- * @return {Node}
- */
-
- splitNode(path, position, properties) {
- const child = this.assertNode(path)
- path = this.resolvePath(path)
- let a
- let b
-
- if (child.object === 'text') {
- ;[a, b] = child.splitText(position)
- } else {
- const befores = child.nodes.take(position)
- const afters = child.nodes.skip(position)
- a = child.set('nodes', befores)
- b = child.set('nodes', afters).regenerateKey()
- }
-
- if (properties && child.object !== 'text') {
- b = b.merge(properties)
- }
-
- let ret = this
- ret = ret.removeNode(path)
- ret = ret.insertNode(path, b)
- ret = ret.insertNode(path, a)
- return ret
- }
-
/**
* Validate the node against a `schema`.
*
@@ -2011,156 +239,8 @@ class NodeInterface {
*/
validate(schema) {
- return schema.validateNode(this)
- }
-
- /**
- * Deprecated.
- */
-
- static createChildren(...args) {
- logger.deprecate(
- '0.39.0',
- 'The `Node.createChildren` static method is deprecated, please use `Node.createList` instead.'
- )
-
- return this.createList(...args)
- }
-
- get isVoid() {
- logger.deprecate(
- '0.38.0',
- 'The `Node.isVoid` property is deprecated, please use the `Schema.isVoid()` checking method instead.'
- )
-
- return this.get('isVoid')
- }
-
- get isEmpty() {
- logger.deprecate('0.38.0', 'The `Node.isEmpty` property is deprecated.')
-
- return !this.get('isVoid') && !this.nodes.some(child => !child.isEmpty)
- }
-
- getNodeAtPath(path) {
- logger.deprecate(
- `0.35.0`,
- 'The `Node.getNodeAtPath` method has been combined into `Node.getNode`.'
- )
-
- return this.getNode(path)
- }
-
- getDescendantAtPath(path) {
- logger.deprecate(
- `0.35.0`,
- 'The `Node.getDescendantAtPath` has been combined into `Node.getDescendant`.'
- )
-
- return this.getDescendant(path)
- }
-
- getKeys() {
- logger.deprecate(`0.35.0`, 'The `Node.getKeys` method is deprecated.')
-
- const keys = this.getKeysAsArray()
- return Set(keys)
- }
-
- getKeysAsArray() {
- logger.deprecate(
- `0.35.0`,
- 'The `Node.getKeysAsArray` method is deprecated.'
- )
-
- const dict = this.getKeysToPathsTable()
- const keys = []
-
- for (const key in dict) {
- if (this.key !== key) {
- keys.push(key)
- }
- }
-
- return keys
- }
-
- areDescendantsSorted(first, second) {
- logger.deprecate(
- `0.35.0`,
- 'The `Node.areDescendantsSorted` method is deprecated. Use the new `PathUtils.compare` helper instead.'
- )
-
- first = KeyUtils.create(first)
- second = KeyUtils.create(second)
-
- const keys = this.getKeysAsArray().filter(k => k !== this.key)
- const firstIndex = keys.indexOf(first)
- const secondIndex = keys.indexOf(second)
- if (firstIndex == -1 || secondIndex == -1) return null
-
- return firstIndex < secondIndex
- }
-
- isInRange(range) {
- logger.deprecate(
- `0.35.0`,
- 'The `Node.isInRange` method is deprecated. Use the new `PathUtils.compare` helper instead.'
- )
-
- range = this.resolveRange(range)
-
- const node = this
- const { startKey, endKey, isCollapsed } = range
-
- // PERF: solve the most common cast where the start or end key are inside
- // the node, for collapsed selections.
- if (
- node.key == startKey ||
- node.key == endKey ||
- node.hasDescendant(startKey) ||
- node.hasDescendant(endKey)
- ) {
- return true
- }
-
- // PERF: if the selection is collapsed and the previous check didn't return
- // true, then it must be false.
- if (isCollapsed) {
- return false
- }
-
- // Otherwise, look through all of the leaf text nodes in the range, to see
- // if any of them are inside the node.
- const texts = node.getTextsAtRange(range)
- let memo = false
-
- texts.forEach(text => {
- if (node.hasDescendant(text.key)) memo = true
- return memo
- })
-
- return memo
- }
-}
-
-/**
- * Mix in assertion variants.
- */
-
-const ASSERTS = ['Child', 'Depth', 'Descendant', 'Node', 'Parent', 'Path']
-
-for (const method of ASSERTS) {
- NodeInterface.prototype[`assert${method}`] = function(path, ...args) {
- const ret = this[`get${method}`](path, ...args)
-
- if (ret == null) {
- throw new Error(
- `\`Node.assert${method}\` could not find node with path or key: ${path}`
- )
- }
-
- return ret
+ const error = schema.validateNode(this)
+ return error
}
}
@@ -2169,34 +249,11 @@ for (const method of ASSERTS) {
*/
memoize(NodeInterface.prototype, [
- 'getBlocksAsArray',
- 'getBlocksAtRangeAsArray',
- 'getBlocksByTypeAsArray',
- 'getDecorations',
'getFirstInvalidNode',
'getFirstText',
- 'getFragmentAtRange',
- 'getInlinesAsArray',
- 'getInlinesAtRangeAsArray',
- 'getInlinesByTypeAsArray',
- 'getMarksAsArray',
- 'getMarksAtPosition',
- 'getOrderedMarksBetweenPositions',
- 'getInsertMarksAtRange',
'getKeysToPathsTable',
'getLastText',
- 'getMarksByTypeAsArray',
- 'getNextBlock',
- 'getOffset',
- 'getOffsetAtRange',
- 'getPreviousBlock',
'getText',
- 'getTextAtOffset',
- 'getTextDirection',
- 'getTextsAsArray',
- 'getTextsBetweenPositionsAsArray',
- 'isLeafBlock',
- 'isLeafInline',
'normalize',
'validate',
])
@@ -2205,4 +262,4 @@ memoize(NodeInterface.prototype, [
* Mix in the node interface.
*/
-mixin(NodeInterface, [Block, Inline, Document])
+mixin(NodeInterface, [Block, Document, Inline, Text])
diff --git a/packages/slate/src/interfaces/range.js b/packages/slate/src/interfaces/range.js
index 02d0fdb4b..a342d1dfd 100644
--- a/packages/slate/src/interfaces/range.js
+++ b/packages/slate/src/interfaces/range.js
@@ -1,5 +1,3 @@
-import logger from 'slate-dev-logger'
-
import mixin from '../utils/mixin'
import Decoration from '../models/decoration'
import PathUtils from '../utils/path-utils'
@@ -646,573 +644,8 @@ class RangeInterface {
const range = this.updatePoints(p => p.unset())
return range
}
-
- /**
- * Deprecated.
- */
-
- get anchorKey() {
- logger.deprecate(
- '0.37.0',
- 'The `range.anchorKey` property has been deprecated, use `range.anchor.key` instead.'
- )
-
- return this.anchor.key
- }
-
- get anchorOffset() {
- logger.deprecate(
- '0.37.0',
- 'The `range.anchorOffset` property has been deprecated, use `range.anchor.offset` instead.'
- )
-
- return this.anchor.offset
- }
-
- get anchorPath() {
- logger.deprecate(
- '0.37.0',
- 'The `range.anchorPath` property has been deprecated, use `range.anchor.path` instead.'
- )
-
- return this.anchor.path
- }
-
- get focusKey() {
- logger.deprecate(
- '0.37.0',
- 'The `range.focusKey` property has been deprecated, use `range.focus.key` instead.'
- )
-
- return this.focus.key
- }
-
- get focusOffset() {
- logger.deprecate(
- '0.37.0',
- 'The `range.focusOffset` property has been deprecated, use `range.focus.offset` instead.'
- )
-
- return this.focus.offset
- }
-
- get focusPath() {
- logger.deprecate(
- '0.37.0',
- 'The `range.focusPath` property has been deprecated, use `range.focus.path` instead.'
- )
-
- return this.focus.path
- }
-
- get startKey() {
- logger.deprecate(
- '0.37.0',
- 'The `range.startKey` property has been deprecated, use `range.start.key` instead.'
- )
-
- return this.start.key
- }
-
- get startOffset() {
- logger.deprecate(
- '0.37.0',
- 'The `range.startOffset` property has been deprecated, use `range.start.offset` instead.'
- )
-
- return this.start.offset
- }
-
- get startPath() {
- logger.deprecate(
- '0.37.0',
- 'The `range.startPath` property has been deprecated, use `range.start.path` instead.'
- )
-
- return this.start.path
- }
-
- get endKey() {
- logger.deprecate(
- '0.37.0',
- 'The `range.endKey` property has been deprecated, use `range.end.key` instead.'
- )
-
- return this.end.key
- }
-
- get endOffset() {
- logger.deprecate(
- '0.37.0',
- 'The `range.endOffset` property has been deprecated, use `range.end.offset` instead.'
- )
-
- return this.end.offset
- }
-
- get endPath() {
- logger.deprecate(
- '0.37.0',
- 'The `range.endPath` property has been deprecated, use `range.end.path` instead.'
- )
-
- return this.end.path
- }
-
- hasAnchorAtStartOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasAnchorAtStartOf` method is deprecated, please use `Range.anchor.isAtStartOfNode` instead.'
- )
-
- return this.anchor.isAtStartOfNode(node)
- }
-
- hasAnchorAtEndOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasAnchorAtEndOf` method is deprecated, please use `Range.anchor.isAtEndOfNode` instead.'
- )
-
- return this.anchor.isAtEndOfNode(node)
- }
-
- hasAnchorBetween(node, start, end) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasAnchorBetween` method is deprecated, please use the `Range.anchor` methods and properties directly instead.'
- )
-
- return (
- this.anchor.offset <= end &&
- start <= this.anchor.offset &&
- this.anchor.isInNode(node)
- )
- }
-
- hasAnchorIn(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasAnchorAtEndOf` method is deprecated, please use `Range.anchor.isInNode` instead.'
- )
-
- return this.anchor.isInNode(node)
- }
-
- hasEdgeAtStartOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasEdgeAtStartOf` method is deprecated.'
- )
-
- return this.anchor.isAtStartOfNode(node) || this.focus.isAtStartOfNode(node)
- }
-
- hasEdgeAtEndOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasEdgeAtEndOf` method is deprecated.'
- )
-
- return this.anchor.isAtEndOfNode(node) || this.focus.isAtEndOfNode(node)
- }
-
- hasEdgeBetween(node, start, end) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasEdgeBetween` method is deprecated.'
- )
-
- return (
- (this.anchor.offset <= end &&
- start <= this.anchor.offset &&
- this.anchor.isInNode(node)) ||
- (this.focus.offset <= end &&
- start <= this.focus.offset &&
- this.focus.isInNode(node))
- )
- }
-
- hasEdgeIn(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasEdgeAtEndOf` method is deprecated.'
- )
-
- return this.anchor.isInNode(node) || this.focus.isInNode(node)
- }
-
- hasEndAtStartOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasEndAtStartOf` method is deprecated, please use `Range.end.isAtStartOfNode` instead.'
- )
-
- return this.end.isAtStartOfNode(node)
- }
-
- hasEndAtEndOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasEndAtEndOf` method is deprecated, please use `Range.end.isAtEndOfNode` instead.'
- )
-
- return this.end.isAtEndOfNode(node)
- }
-
- hasEndBetween(node, start, end) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasEndBetween` method is deprecated, please use the `Range.end` methods and properties directly instead.'
- )
-
- return (
- this.end.offset <= end &&
- start <= this.end.offset &&
- this.end.isInNode(node)
- )
- }
-
- hasEndIn(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasEndAtEndOf` method is deprecated, please use `Range.end.isInNode` instead.'
- )
-
- return this.end.isInNode(node)
- }
-
- hasFocusAtEndOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasFocusAtEndOf` method is deprecated, please use `Range.focus.isAtEndOfNode` instead.'
- )
-
- return this.focus.isAtEndOfNode(node)
- }
-
- hasFocusAtStartOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasFocusAtStartOf` method is deprecated, please use `Range.focus.isAtStartOfNode` instead.'
- )
-
- return this.focus.isAtStartOfNode(node)
- }
-
- hasFocusBetween(node, start, end) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasFocusBetween` method is deprecated, please use the `Range.focus` methods and properties directly instead.'
- )
-
- return (
- start <= this.focus.offset &&
- this.focus.offset <= end &&
- this.focus.isInNode(node)
- )
- }
-
- hasFocusIn(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasFocusAtEndOf` method is deprecated, please use `Range.focus.isInNode` instead.'
- )
-
- return this.focus.isInNode(node)
- }
-
- hasStartAtStartOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasStartAtStartOf` method is deprecated, please use `Range.start.isAtStartOfNode` instead.'
- )
-
- return this.start.isAtStartOfNode(node)
- }
-
- hasStartAtEndOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasStartAtEndOf` method is deprecated, please use `Range.start.isAtEndOfNode` instead.'
- )
-
- return this.start.isAtEndOfNode(node)
- }
-
- hasStartBetween(node, start, end) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasStartBetween` method is deprecated, please use the `Range.start` methods and properties directly instead.'
- )
-
- return (
- this.start.offset <= end &&
- start <= this.start.offset &&
- this.start.isInNode(node)
- )
- }
-
- hasStartIn(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.hasStartAtEndOf` method is deprecated, please use `Range.start.isInNode` instead.'
- )
-
- return this.start.isInNode(node)
- }
-
- isAtStartOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.isAtStartOf` method is deprecated, please use `Range.isCollapsed` and `Point.isAtStartOfNode` instead.'
- )
-
- return this.isCollapsed && this.anchor.isAtStartOfNode(node)
- }
-
- isAtEndOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.isAtEndOf` method is deprecated, please use `Range.isCollapsed` and `Point.isAtEndOfNode` instead.'
- )
-
- return this.isCollapsed && this.anchor.isAtEndOfNode(node)
- }
-
- blur() {
- logger.deprecate(
- '0.37.0',
- 'The `Range.blur` method is deprecated, please use `Range.merge` directly instead.'
- )
-
- return this.merge({ isFocused: false })
- }
-
- deselect() {
- logger.deprecate(
- '0.37.0',
- 'The `Range.deselect` method is deprecated, please use `Range.create` to create a new unset range instead.'
- )
-
- return Range.create()
- }
-
- moveAnchorOffsetTo(o) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveAnchorOffsetTo` method is deprecated, please use `Range.moveAnchorTo(offset)` instead.'
- )
-
- return this.moveAnchorTo(o)
- }
-
- moveFocusOffsetTo(fo) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveFocusOffsetTo` method is deprecated, please use `Range.moveFocusTo(offset)` instead.'
- )
-
- return this.moveFocusTo(fo)
- }
-
- moveStartOffsetTo(o) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveStartOffsetTo` method is deprecated, please use `Range.moveStartTo(offset)` instead.'
- )
-
- return this.moveStartTo(o)
- }
-
- moveEndOffsetTo(o) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveEndOffsetTo` method is deprecated, please use `Range.moveEndTo(offset)` instead.'
- )
-
- return this.moveEndTo(o)
- }
-
- moveOffsetsTo(ao, fo = ao) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveOffsetsTo` method is deprecated, please use `Range.moveAnchorTo` and `Range.moveFocusTo` in sequence instead.'
- )
-
- return this.moveAnchorTo(ao).moveFocusTo(fo)
- }
-
- moveAnchorToStartOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveAnchorToStartOf` method is deprecated, please use `Range.moveAnchorToStartOfNode` instead.'
- )
-
- return this.moveAnchorToStartOfNode(node)
- }
-
- moveAnchorToEndOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveAnchorToEndOf` method is deprecated, please use `Range.moveAnchorToEndOfNode` instead.'
- )
-
- return this.moveAnchorToEndOfNode(node)
- }
-
- moveFocusToStartOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveFocusToStartOf` method is deprecated, please use `Range.moveFocusToStartOfNode` instead.'
- )
-
- return this.moveFocusToStartOfNode(node)
- }
-
- moveFocusToEndOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveFocusToEndOf` method is deprecated, please use `Range.moveFocusToEndOfNode` instead.'
- )
-
- return this.moveFocusToEndOfNode(node)
- }
-
- moveToStartOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveToStartOf` method is deprecated, please use `Range.moveToStartOfNode` instead.'
- )
-
- return this.moveToStartOfNode(node)
- }
-
- moveToEndOf(node) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveToEndOf` method is deprecated, please use `Range.moveToEndOfNode` instead.'
- )
-
- return this.moveToEndOfNode(node)
- }
-
- moveToRangeOf(...args) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveToRangeOf` method is deprecated, please use `Range.moveToRangeOfNode` instead.'
- )
-
- return this.moveToRangeOfNode(...args)
- }
-
- collapseToAnchor() {
- logger.deprecate(
- '0.37.0',
- 'The `Range.collapseToAnchor` method is deprecated, please use `Range.moveToAnchor` instead.'
- )
-
- return this.moveToAnchor()
- }
-
- collapseToEnd() {
- logger.deprecate(
- '0.37.0',
- 'The `Range.collapseToEnd` method is deprecated, please use `Range.moveToEnd` instead.'
- )
-
- return this.moveToEnd()
- }
-
- collapseToFocus() {
- logger.deprecate(
- '0.37.0',
- 'The `Range.collapseToFocus` method is deprecated, please use `Range.moveToFocus` instead.'
- )
-
- return this.moveToFocus()
- }
-
- collapseToStart() {
- logger.deprecate(
- '0.37.0',
- 'The `Range.collapseToStart` method is deprecated, please use `Range.moveToStart` instead.'
- )
-
- return this.moveToStart()
- }
-
- move(n = 1) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.move` method is deprecated, please use `Range.moveForward` or `Range.moveBackward` instead.'
- )
-
- return n > 0 ? this.moveForward(n) : this.moveBackward(-n)
- }
-
- moveAnchor(n = 1) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveAnchor` method is deprecated, please use `Range.moveAnchorForward` or `Range.moveAnchorBackward` instead.'
- )
-
- return n > 0 ? this.moveAnchorForward(n) : this.moveAnchorBackward(-n)
- }
-
- moveEnd(n = 1) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveEnd` method is deprecated, please use `Range.moveEndForward` or `Range.moveEndBackward` instead.'
- )
-
- return n > 0 ? this.moveEndForward(n) : this.moveEndBackward(-n)
- }
-
- moveFocus(n = 1) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveFocus` method is deprecated, please use `Range.moveFocusForward` or `Range.moveFocusBackward` instead.'
- )
-
- return n > 0 ? this.moveFocusForward(n) : this.moveFocusBackward(-n)
- }
-
- moveStart(n = 1) {
- logger.deprecate(
- '0.37.0',
- 'The `Range.moveStart` method is deprecated, please use `Range.moveStartForward` or `Range.moveStartBackward` instead.'
- )
-
- return n > 0 ? this.moveStartForward(n) : this.moveStartBackward(-n)
- }
}
-/**
- * Mix in some aliases for convenience / parallelism with the browser APIs.
- */
-
-const ALIAS_METHODS = [
- ['collapseTo', 'moveTo'],
- ['collapseToStartOf', 'moveToStartOfNode'],
- ['collapseToEndOf', 'moveToEndOfNode'],
- ['extend', 'moveFocus'],
- ['extendTo', 'moveFocusTo'],
- ['extendToStartOf', 'moveFocusToStartOfNode'],
- ['extendToEndOf', 'moveFocusToEndOfNode'],
-]
-
-ALIAS_METHODS.forEach(([alias, method]) => {
- RangeInterface.prototype[alias] = function(...args) {
- logger.deprecate(
- '0.37.0',
- `The \`Range.${alias}\` method is deprecated, please use \`Range.${method}\` instead.`
- )
-
- return this[method](...args)
- }
-})
-
/**
* Mix in the range interface.
*
diff --git a/packages/slate/src/models/block.js b/packages/slate/src/models/block.js
index f5c214339..0d8186327 100644
--- a/packages/slate/src/models/block.js
+++ b/packages/slate/src/models/block.js
@@ -13,7 +13,6 @@ import Node from './node'
const DEFAULTS = {
data: new Map(),
- isVoid: false,
key: undefined,
nodes: new List(),
type: undefined,
@@ -81,13 +80,7 @@ class Block extends Record(DEFAULTS) {
return object
}
- const {
- data = {},
- isVoid = false,
- key = KeyUtils.create(),
- nodes = [],
- type,
- } = object
+ const { data = {}, key = KeyUtils.create(), nodes = [], type } = object
if (typeof type != 'string') {
throw new Error('`Block.fromJSON` requires a `type` string.')
@@ -96,7 +89,6 @@ class Block extends Record(DEFAULTS) {
const block = new Block({
key,
type,
- isVoid: !!isVoid,
data: Map(data),
nodes: Node.createList(nodes),
})
@@ -145,7 +137,6 @@ class Block extends Record(DEFAULTS) {
const object = {
object: this.object,
type: this.type,
- isVoid: this.get('isVoid'),
data: this.data.toJSON(),
nodes: this.nodes.toArray().map(n => n.toJSON(options)),
}
diff --git a/packages/slate/src/models/decoration.js b/packages/slate/src/models/decoration.js
index 527e5db43..287908041 100644
--- a/packages/slate/src/models/decoration.js
+++ b/packages/slate/src/models/decoration.js
@@ -1,5 +1,4 @@
import isPlainObject from 'is-plain-object'
-import logger from 'slate-dev-logger'
import { List, Record } from 'immutable'
import Mark from './mark'
@@ -106,18 +105,7 @@ class Decoration extends Record(DEFAULTS) {
*/
static fromJSON(object) {
- const { anchor, focus } = object
- let { mark } = object
-
- if (object.marks) {
- logger.deprecate(
- '0.39.0',
- 'The `marks` property of decorations has been changed to a single `mark` property instead.'
- )
-
- mark = object.marks[0]
- }
-
+ const { anchor, focus, mark } = object
const decoration = new Decoration({
anchor: Point.fromJSON(anchor || {}),
focus: Point.fromJSON(focus || {}),
diff --git a/packages/slate/src/models/history.js b/packages/slate/src/models/history.js
index be6ff05da..6622c73af 100644
--- a/packages/slate/src/models/history.js
+++ b/packages/slate/src/models/history.js
@@ -1,5 +1,4 @@
import Debug from 'debug'
-import isEqual from 'lodash/isEqual'
import isPlainObject from 'is-plain-object'
import { List, Record, Stack } from 'immutable'
@@ -196,11 +195,11 @@ function shouldMerge(o, p) {
(o.type == 'insert_text' &&
p.type == 'insert_text' &&
o.offset == p.offset + p.text.length &&
- isEqual(o.path, p.path)) ||
+ o.path.equals(p.path)) ||
(o.type == 'remove_text' &&
p.type == 'remove_text' &&
o.offset + o.text.length == p.offset &&
- isEqual(o.path, p.path))
+ o.path.equals(p.path))
return merge
}
diff --git a/packages/slate/src/models/inline.js b/packages/slate/src/models/inline.js
index c0cc04457..4c0c68ad7 100644
--- a/packages/slate/src/models/inline.js
+++ b/packages/slate/src/models/inline.js
@@ -13,7 +13,6 @@ import Node from './node'
const DEFAULTS = {
data: new Map(),
- isVoid: false,
key: undefined,
nodes: new List(),
type: undefined,
@@ -81,13 +80,7 @@ class Inline extends Record(DEFAULTS) {
return object
}
- const {
- data = {},
- isVoid = false,
- key = KeyUtils.create(),
- nodes = [],
- type,
- } = object
+ const { data = {}, key = KeyUtils.create(), nodes = [], type } = object
if (typeof type != 'string') {
throw new Error('`Inline.fromJS` requires a `type` string.')
@@ -96,7 +89,6 @@ class Inline extends Record(DEFAULTS) {
const inline = new Inline({
key,
type,
- isVoid: !!isVoid,
data: new Map(data),
nodes: Node.createList(nodes),
})
@@ -145,7 +137,6 @@ class Inline extends Record(DEFAULTS) {
const object = {
object: this.object,
type: this.type,
- isVoid: this.get('isVoid'),
data: this.data.toJSON(),
nodes: this.nodes.toArray().map(n => n.toJSON(options)),
}
diff --git a/packages/slate/src/models/node.js b/packages/slate/src/models/node.js
index 8f418aeed..32e4e5990 100644
--- a/packages/slate/src/models/node.js
+++ b/packages/slate/src/models/node.js
@@ -1,5 +1,5 @@
import isPlainObject from 'is-plain-object'
-import logger from 'slate-dev-logger'
+import warning from 'slate-dev-warning'
import { List } from 'immutable'
import Block from './block'
@@ -32,9 +32,9 @@ class Node {
let { object } = attrs
if (!object && attrs.kind) {
- logger.deprecate(
- 'slate@0.32.0',
- 'The `kind` property of Slate objects has been renamed to `object`.'
+ warning(
+ false,
+ 'As of slate@0.32.0, the `kind` property of Slate objects has been renamed to `object`.'
)
object = attrs.kind
@@ -90,7 +90,6 @@ class Node {
if (Block.isBlock(attrs) || Inline.isInline(attrs)) {
return {
data: attrs.data,
- isVoid: attrs.isVoid,
type: attrs.type,
}
}
@@ -103,7 +102,6 @@ class Node {
const props = {}
if ('type' in attrs) props.type = attrs.type
if ('data' in attrs) props.data = Data.create(attrs.data)
- if ('isVoid' in attrs) props.isVoid = attrs.isVoid
return props
}
@@ -123,9 +121,9 @@ class Node {
let { object } = value
if (!object && value.kind) {
- logger.deprecate(
- 'slate@0.32.0',
- 'The `kind` property of Slate objects has been renamed to `object`.'
+ warning(
+ false,
+ 'As of slate@0.32.0, the `kind` property of Slate objects has been renamed to `object`.'
)
object = value.kind
diff --git a/packages/slate/src/models/operation.js b/packages/slate/src/models/operation.js
index 50a981003..0134f06e5 100644
--- a/packages/slate/src/models/operation.js
+++ b/packages/slate/src/models/operation.js
@@ -267,7 +267,6 @@ class Operation extends Record(DEFAULTS) {
if (key == 'properties' && type == 'set_node') {
const v = {}
if ('data' in value) v.data = value.data.toJS()
- if ('isVoid' in value) v.isVoid = value.get('isVoid')
if ('type' in value) v.type = value.type
value = v
}
diff --git a/packages/slate/src/models/point.js b/packages/slate/src/models/point.js
index dbc6c0f3a..b45307f2a 100644
--- a/packages/slate/src/models/point.js
+++ b/packages/slate/src/models/point.js
@@ -1,5 +1,5 @@
import isPlainObject from 'is-plain-object'
-import logger from 'slate-dev-logger'
+import warning from 'slate-dev-warning'
import { Record } from 'immutable'
import KeyUtils from '../utils/key-utils'
@@ -289,7 +289,7 @@ class Point extends Record(DEFAULTS) {
const target = node.getNode(key || path)
if (!target) {
- logger.warn("A point's `path` or `key` invalid and was reset:", this)
+ warning(false, "A point's `path` or `key` invalid and was reset!")
const text = node.getFirstText()
if (!text) return Point.create()
@@ -304,7 +304,7 @@ class Point extends Record(DEFAULTS) {
}
if (target.object !== 'text') {
- logger.warn('A point should not reference a non-text node:', target)
+ warning(false, 'A point should not reference a non-text node!')
const text = target.getTextAtOffset(offset)
const before = target.getOffset(text.key)
@@ -318,7 +318,7 @@ class Point extends Record(DEFAULTS) {
}
if (target && path && key && key !== target.key) {
- logger.warn("A point's `key` did not match its `path`:", this, target)
+ warning(false, "A point's `key` did not match its `path`!")
}
const point = this.merge({
diff --git a/packages/slate/src/models/range.js b/packages/slate/src/models/range.js
index c80aa52ec..692bea3c1 100644
--- a/packages/slate/src/models/range.js
+++ b/packages/slate/src/models/range.js
@@ -1,5 +1,4 @@
import isPlainObject from 'is-plain-object'
-import logger from 'slate-dev-logger'
import { List, Record } from 'immutable'
import Decoration from './decoration'
@@ -42,24 +41,6 @@ class Range extends Record(DEFAULTS) {
}
if (isPlainObject(attrs)) {
- if ('isFocused' in attrs || 'marks' in attrs) {
- logger.deprecate(
- '0.39.0',
- 'Using `Range.create` for selections is deprecated, please use `Selection.create` instead.'
- )
-
- return Selection.create(attrs)
- }
-
- if ('isAtomic' in attrs) {
- logger.deprecate(
- '0.39.0',
- 'Using `Range.create` for decorations is deprecated, please use `Decoration.create` instead.'
- )
-
- return Decoration.create(attrs)
- }
-
return Range.fromJSON(attrs)
}
@@ -121,39 +102,7 @@ class Range extends Record(DEFAULTS) {
*/
static fromJSON(object) {
- let { anchor, focus } = object
-
- if (
- !anchor &&
- (object.anchorKey || object.anchorOffset || object.anchorPath)
- ) {
- logger.deprecate(
- '0.37.0',
- '`Range` objects now take a `Point` object as an `anchor` instead of taking `anchorKey/Offset/Path` properties. But you passed:',
- object
- )
-
- anchor = {
- key: object.anchorKey,
- offset: object.anchorOffset,
- path: object.anchorPath,
- }
- }
-
- if (!focus && (object.focusKey || object.focusOffset || object.focusPath)) {
- logger.deprecate(
- '0.37.0',
- '`Range` objects now take a `Point` object as a `focus` instead of taking `focusKey/Offset/Path` properties. But you passed:',
- object
- )
-
- focus = {
- key: object.focusKey,
- offset: object.focusOffset,
- path: object.focusPath,
- }
- }
-
+ const { anchor, focus } = object
const range = new Range({
anchor: Point.fromJSON(anchor || {}),
focus: Point.fromJSON(focus || {}),
diff --git a/packages/slate/src/models/schema.js b/packages/slate/src/models/schema.js
index e497b56ef..234e968e4 100644
--- a/packages/slate/src/models/schema.js
+++ b/packages/slate/src/models/schema.js
@@ -1,25 +1,6 @@
import Debug from 'debug'
import isPlainObject from 'is-plain-object'
-import logger from 'slate-dev-logger'
import { Record } from 'immutable'
-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_OBJECT_INVALID,
- NODE_TEXT_INVALID,
- NODE_TYPE_INVALID,
- PARENT_OBJECT_INVALID,
- PARENT_TYPE_INVALID,
-} from 'slate-schema-violations'
import MODEL_TYPES from '../constants/model-types'
import Stack from './stack'
@@ -92,17 +73,7 @@ const CORE_RULES = [
},
},
- // Ensure that inline non-void nodes are never empty.
- {
- match: {
- object: 'inline',
- isVoid: false,
- nodes: [{ match: { object: 'text' } }],
- },
- text: /[\w\W]+/,
- },
-
- // Ensure that inline void nodes are surrounded by text nodes.
+ // Ensure that inline nodes are surrounded by text nodes.
{
match: { object: 'block' },
first: [{ object: 'block' }, { object: 'text' }],
@@ -279,6 +250,18 @@ class Schema extends Record(DEFAULTS) {
return 'schema'
}
+ /**
+ * Get the schema rules for a `node`.
+ *
+ * @param {Node} node
+ * @return {Array}
+ */
+
+ getNodeRules(node) {
+ const rules = this.rules.filter(r => testRules(node, r.match))
+ return rules
+ }
+
/**
* Validate a `node` with the schema, returning an error if it's invalid.
*
@@ -287,7 +270,7 @@ class Schema extends Record(DEFAULTS) {
*/
validateNode(node) {
- const rules = this.rules.filter(r => testRules(node, r.match))
+ const rules = this.getNodeRules(node)
const failure = validateRules(node, rules, this.rules, { every: true })
if (!failure) return
const error = new SlateError(failure.code, failure)
@@ -375,9 +358,8 @@ class Schema extends Record(DEFAULTS) {
*/
isVoid(node) {
- // COMPAT: Right now this just provides a way to get around the
- // deprecation warnings, but in the future it will check the rules.
- return node.get('isVoid')
+ const rule = this.rules.find(r => 'isVoid' in r && testRules(node, r.match))
+ return rule ? rule.isVoid : false
}
/**
@@ -407,13 +389,13 @@ function defaultNormalize(change, error) {
const { code, node, child, key, mark } = error
switch (code) {
- case CHILD_OBJECT_INVALID:
- case CHILD_TYPE_INVALID:
- case CHILD_UNKNOWN:
- case FIRST_CHILD_OBJECT_INVALID:
- case FIRST_CHILD_TYPE_INVALID:
- case LAST_CHILD_OBJECT_INVALID:
- case LAST_CHILD_TYPE_INVALID: {
+ case 'child_object_invalid':
+ case 'child_type_invalid':
+ case 'child_unknown':
+ case 'first_child_object_invalid':
+ case 'first_child_type_invalid':
+ case 'last_child_object_invalid':
+ case 'last_child_type_invalid': {
return child.object === 'text' &&
node.object === 'block' &&
node.nodes.size === 1
@@ -421,10 +403,10 @@ function defaultNormalize(change, error) {
: change.removeNodeByKey(child.key, { normalize: false })
}
- case CHILD_REQUIRED:
- case NODE_TEXT_INVALID:
- case PARENT_OBJECT_INVALID:
- case PARENT_TYPE_INVALID: {
+ case 'child_required':
+ case 'node_text_invalid':
+ case 'parent_object_invalid':
+ case 'parent_type_invalid': {
return node.object === 'document'
? node.nodes.forEach(n =>
change.removeNodeByKey(n.key, { normalize: false })
@@ -432,7 +414,7 @@ function defaultNormalize(change, error) {
: change.removeNodeByKey(node.key, { normalize: false })
}
- case NODE_DATA_INVALID: {
+ case 'node_data_invalid': {
return node.data.get(key) === undefined && node.object !== 'document'
? change.removeNodeByKey(node.key, { normalize: false })
: change.setNodeByKey(
@@ -442,15 +424,7 @@ function defaultNormalize(change, error) {
)
}
- case NODE_IS_VOID_INVALID: {
- return change.setNodeByKey(
- node.key,
- { isVoid: !node.get('isVoid') },
- { normalize: false }
- )
- }
-
- case NODE_MARK_INVALID: {
+ case 'node_mark_invalid': {
return node.getTexts().forEach(t =>
change.removeMarkByKey(t.key, 0, t.text.length, mark, {
normalize: false,
@@ -506,7 +480,6 @@ function validateRules(object, rule, rules, options = {}) {
const error =
validateObject(object, rule) ||
validateType(object, rule) ||
- validateIsVoid(object, rule) ||
validateData(object, rule) ||
validateMarks(object, rule) ||
validateText(object, rule) ||
@@ -518,33 +491,15 @@ function validateRules(object, rule, rules, options = {}) {
}
function validateObject(node, rule) {
- if (rule.objects) {
- logger.warn(
- 'The `objects` schema validation rule was changed. Please use the new `match` syntax with `object`.'
- )
- }
-
if (rule.object == null) return
if (rule.object === node.object) return
- return fail(NODE_OBJECT_INVALID, { rule, node })
+ return fail('node_object_invalid', { rule, node })
}
function validateType(node, rule) {
- if (rule.types) {
- logger.warn(
- 'The `types` schema validation rule was changed. Please use the new `match` syntax with `type`.'
- )
- }
-
if (rule.type == null) return
if (rule.type === node.type) return
- return fail(NODE_TYPE_INVALID, { rule, node })
-}
-
-function validateIsVoid(node, rule) {
- if (rule.isVoid == null) return
- if (rule.isVoid === node.get('isVoid')) return
- return fail(NODE_IS_VOID_INVALID, { rule, node })
+ return fail('node_type_invalid', { rule, node })
}
function validateData(node, rule) {
@@ -556,7 +511,7 @@ function validateData(node, rule) {
const value = node.data && node.data.get(key)
const valid = typeof fn === 'function' ? fn(value) : fn === value
if (valid) continue
- return fail(NODE_DATA_INVALID, { rule, node, key, value })
+ return fail('node_data_invalid', { rule, node, key, value })
}
}
@@ -567,7 +522,7 @@ function validateMarks(node, rule) {
for (const mark of marks) {
const valid = rule.marks.some(def => def.type === mark.type)
if (valid) continue
- return fail(NODE_MARK_INVALID, { rule, node, mark })
+ return fail('node_mark_invalid', { rule, node, mark })
}
}
@@ -577,7 +532,7 @@ function validateText(node, rule) {
const valid =
typeof rule.text === 'function' ? rule.text(text) : rule.text.test(text)
if (valid) return
- return fail(NODE_TEXT_INVALID, { rule, node, text })
+ return fail('node_text_invalid', { rule, node, text })
}
function validateFirst(node, rule) {
@@ -657,21 +612,7 @@ function validateNodes(node, rule, rules = []) {
if (rule.nodes != null) {
if (!def) {
- return fail(CHILD_UNKNOWN, { rule, node, child, index })
- }
-
- if (def) {
- if (def.objects) {
- logger.warn(
- 'The `objects` schema validation rule was changed. Please use the new `match` syntax with `object`.'
- )
- }
-
- if (def.types) {
- logger.warn(
- 'The `types` schema validation rule was changed. Please use the new `match` syntax with `type`.'
- )
- }
+ return fail('child_unknown', { rule, node, child, index })
}
if (def.match) {
@@ -697,7 +638,7 @@ function validateNodes(node, rule, rules = []) {
if (rule.nodes != null) {
while (min != null) {
if (offset < min) {
- return fail(CHILD_REQUIRED, { rule, node, index })
+ return fail('child_required', { rule, node, index })
}
nextDef()
diff --git a/packages/slate/src/models/selection.js b/packages/slate/src/models/selection.js
index 0feac7bf9..d4e011a73 100644
--- a/packages/slate/src/models/selection.js
+++ b/packages/slate/src/models/selection.js
@@ -1,5 +1,4 @@
import isPlainObject from 'is-plain-object'
-import logger from 'slate-dev-logger'
import { Record, Set } from 'immutable'
import MODEL_TYPES from '../constants/model-types'
@@ -99,39 +98,7 @@ class Selection extends Record(DEFAULTS) {
*/
static fromJSON(object) {
- let { anchor, focus, isFocused = false, marks = null } = object
-
- if (
- !anchor &&
- (object.anchorKey || object.anchorOffset || object.anchorPath)
- ) {
- logger.deprecate(
- '0.37.0',
- '`Selection` objects now take a `Point` object as an `anchor` instead of taking `anchorKey/Offset/Path` properties. But you passed:',
- object
- )
-
- anchor = {
- key: object.anchorKey,
- offset: object.anchorOffset,
- path: object.anchorPath,
- }
- }
-
- if (!focus && (object.focusKey || object.focusOffset || object.focusPath)) {
- logger.deprecate(
- '0.37.0',
- '`Selection` objects now take a `Point` object as a `focus` instead of taking `focusKey/Offset/Path` properties. But you passed:',
- object
- )
-
- focus = {
- key: object.focusKey,
- offset: object.focusOffset,
- path: object.focusPath,
- }
- }
-
+ const { anchor, focus, isFocused = false, marks = null } = object
const selection = new Selection({
anchor: Point.fromJSON(anchor || {}),
focus: Point.fromJSON(focus || {}),
diff --git a/packages/slate/src/models/stack.js b/packages/slate/src/models/stack.js
index 330c33f71..efd2d40bd 100644
--- a/packages/slate/src/models/stack.js
+++ b/packages/slate/src/models/stack.js
@@ -1,5 +1,4 @@
import { Record } from 'immutable'
-import logger from 'slate-dev-logger'
import MODEL_TYPES from '../constants/model-types'
import memoize from '../utils/memoize'
@@ -129,14 +128,6 @@ class Stack extends Record(DEFAULTS) {
const plugins = this.getPluginsWith(property)
return plugins.reduceRight((children, plugin) => {
if (!plugin[property]) return children
-
- if (property === 'renderPortal') {
- logger.deprecate(
- '0.39.0',
- 'The `renderPortal` property of plugins is deprecated, please use `renderEditor` with a `` in React 16 instead.'
- )
- }
-
const ret = plugin[property](props, ...args)
if (ret == null) return children
props.children = ret
diff --git a/packages/slate/src/models/text.js b/packages/slate/src/models/text.js
index 30b4d6267..983831876 100644
--- a/packages/slate/src/models/text.js
+++ b/packages/slate/src/models/text.js
@@ -1,5 +1,5 @@
import isPlainObject from 'is-plain-object'
-import logger from 'slate-dev-logger'
+import warning from 'slate-dev-warning'
import { List, OrderedSet, Record, Set } from 'immutable'
import Leaf from './leaf'
@@ -90,9 +90,9 @@ class Text extends Record(DEFAULTS) {
if (!leaves) {
if (object.ranges) {
- logger.deprecate(
- 'slate@0.27.0',
- 'The `ranges` property of Slate objects has been renamed to `leaves`.'
+ warning(
+ false,
+ 'As of slate@0.27.0, the `ranges` property of Slate objects has been renamed to `leaves`.'
)
leaves = object.ranges
@@ -137,18 +137,6 @@ class Text extends Record(DEFAULTS) {
return List.isList(any) && any.every(item => Text.isText(item))
}
- /**
- * Get an object mapping all the keys in the node to their paths.
- *
- * @return {Object}
- */
-
- getKeysToPathsTable() {
- return {
- [this.key]: [],
- }
- }
-
/**
* Object.
*
@@ -159,46 +147,6 @@ class Text extends Record(DEFAULTS) {
return 'text'
}
- /**
- * Is the node empty?
- *
- * @return {Boolean}
- */
-
- get isEmpty() {
- logger.deprecate('0.39.0', 'The `Text.isEmpty` property is deprecated.')
- return this.text == ''
- }
-
- /**
- * Get the concatenated text of the node.
- *
- * @return {String}
- */
-
- get text() {
- return this.getText()
- }
-
- /**
- * Get the concatenated text of the node, cached for text getter
- *
- * @returns {String}
- */
-
- getText() {
- return this.leaves.reduce((string, leaf) => string + leaf.text, '')
- }
-
- getString() {
- logger.deprecate(
- '0.39.0',
- 'The `Text.getString` property is deprecated, please use `Text.getText` instead.'
- )
-
- return this.getText()
- }
-
/**
* Find the 'first' leaf at offset; By 'first' the alorighthm prefers `endOffset === offset` than `startOffset === offset`
* Corner Cases:
@@ -387,14 +335,6 @@ class Text extends Record(DEFAULTS) {
})
}
- getFirstText() {
- return this
- }
-
- getLastText() {
- return this
- }
-
/**
* Get all of the marks on between two offsets
* Corner Cases:
@@ -483,28 +423,6 @@ class Text extends Record(DEFAULTS) {
return leaf.marks
}
- /**
- * Get a node by `key`, to parallel other nodes.
- *
- * @param {String} key
- * @return {Node|Null}
- */
-
- getNode(key) {
- return this.key == key ? this : null
- }
-
- /**
- * Check if the node has a node by `key`, to parallel other nodes.
- *
- * @param {String} key
- * @return {Boolean}
- */
-
- hasNode(key) {
- return !!this.getNode(key)
- }
-
/**
* Insert `text` at `index`.
*
@@ -546,17 +464,6 @@ class Text extends Record(DEFAULTS) {
return this.setLeaves(nextLeaves)
}
- /**
- * Regenerate the node's key.
- *
- * @return {Text}
- */
-
- regenerateKey() {
- const key = KeyUtils.create()
- return this.set('key', key)
- }
-
/**
* Remove a `mark` at `index` and `length`.
*
@@ -719,49 +626,6 @@ class Text extends Record(DEFAULTS) {
return this.setLeaves(leaves)
}
- /**
- * Normalize the text node with a `schema`.
- *
- * @param {Schema} schema
- * @return {Function|Void}
- */
-
- normalize(schema) {
- return schema.normalizeNode(this)
- }
-
- /**
- * Validate the text node against a `schema`.
- *
- * @param {Schema} schema
- * @return {Error|Void}
- */
-
- validate(schema) {
- return schema.validateNode(this)
- }
-
- /**
- * Get the first invalid descendant
- * PERF: Do not cache this method; because it can cause cycle reference
- *
- * @param {Schema} schema
- * @returns {Text|Null}
- */
-
- getFirstInvalidNode(schema) {
- return this.validate(schema) ? this : null
- }
-
- getFirstInvalidDescendant(schema) {
- logger.deprecate(
- '0.39.0',
- 'The `Node.getFirstInvalidDescendant` method is deprecated, please use `Node.getFirstInvalidNode` instead.'
- )
-
- return this.getFirstInvalidNode(schema)
- }
-
/**
* Set leaves with normalized `leaves`
*
@@ -796,15 +660,7 @@ Text.prototype[MODEL_TYPES.TEXT] = true
* Memoize read methods.
*/
-memoize(Text.prototype, [
- 'getActiveMarks',
- 'getMarks',
- 'getMarksAsArray',
- 'normalize',
- 'validate',
- 'getText',
- 'getKeysToPathsTable',
-])
+memoize(Text.prototype, ['getActiveMarks', 'getMarks', 'getMarksAsArray'])
/**
* Export.
diff --git a/packages/slate/src/models/value.js b/packages/slate/src/models/value.js
index ae97205bf..e12331759 100644
--- a/packages/slate/src/models/value.js
+++ b/packages/slate/src/models/value.js
@@ -1,5 +1,4 @@
import isPlainObject from 'is-plain-object'
-import logger from 'slate-dev-logger'
import { Record, Set, List, Map } from 'immutable'
import MODEL_TYPES from '../constants/model-types'
@@ -97,32 +96,18 @@ class Value extends Record(DEFAULTS) {
*/
static fromJSON(object, options = {}) {
- let { document = {}, selection = {}, schema = {}, history = {} } = object
- let data = new Map()
- document = Document.fromJSON(document)
- selection = Selection.fromJSON(selection)
+ let {
+ data = {},
+ document = {},
+ selection = {},
+ schema = {},
+ history = {},
+ } = object
+
+ data = Data.fromJSON(data)
schema = Schema.fromJSON(schema)
history = History.fromJSON(history)
-
- // Allow plugins to set a default value for `data`.
- if (options.plugins) {
- for (const plugin of options.plugins) {
- if (plugin.data) {
- logger.deprecate(
- '0.39.0',
- 'The plugin `data` property is deprecated.'
- )
-
- data = data.merge(plugin.data)
- }
- }
- }
-
- // Then merge in the `data` provided.
- if ('data' in object) {
- data = data.merge(object.data)
- }
-
+ document = Document.fromJSON(document)
selection = document.createSelection(selection)
if (selection.isUnset) {
@@ -131,8 +116,6 @@ class Value extends Record(DEFAULTS) {
selection = document.createSelection(selection)
}
- selection = document.createSelection(selection)
-
let value = new Value({
data,
document,
@@ -972,204 +955,6 @@ class Value extends Record(DEFAULTS) {
return object
}
-
- /**
- * Deprecated.
- */
-
- get hasUndos() {
- logger.deprecate(
- '0.38.0',
- 'The `Value.hasUndos` property is deprecated, please use `history.undos.size` instead.'
- )
-
- return this.history.undos.size > 0
- }
-
- get hasRedos() {
- logger.deprecate(
- '0.38.0',
- 'The `Value.hasRedos` property is deprecated, please use `history.redos.size` instead.'
- )
-
- return this.history.redos.size > 0
- }
-
- get isBlurred() {
- logger.deprecate(
- '0.38.0',
- 'The `Value.isBlurred` property is deprecated, please use `selection.isBlurred` instead.'
- )
-
- return this.selection.isBlurred
- }
-
- get isFocused() {
- logger.deprecate(
- '0.38.0',
- 'The `Value.isFocused` property is deprecated, please use `selection.isFocused` instead.'
- )
-
- return this.selection.isFocused
- }
-
- get isEmpty() {
- logger.deprecate('0.38.0', 'The `Value.isEmpty` property is deprecated.')
- if (this.selection.isCollapsed) return true
- if (this.selection.end.offset != 0 && this.selection.start.offset != 0)
- return false
- return this.fragment.isEmpty
- }
-
- get isInVoid() {
- logger.deprecate('0.38.0', 'The `Value.isInVoid` property is deprecated.')
- if (this.selection.isExpanded) return false
- return this.document.hasVoidParent(this.selection.start.key, this.schema)
- }
-
- get isCollapsed() {
- logger.deprecate(
- '0.37.0',
- 'The `value.isCollapsed` property is deprecated, please use `selection.isCollapsed` instead.'
- )
-
- return this.selection.isCollapsed
- }
-
- get isExpanded() {
- logger.deprecate(
- '0.37.0',
- 'The `value.isExpanded` property is deprecated, please use `selection.isExpanded` instead.'
- )
-
- return this.selection.isExpanded
- }
-
- get isBackward() {
- logger.deprecate(
- '0.37.0',
- 'The `value.isBackward` property is deprecated, please use `selection.isBackward` instead.'
- )
-
- return this.selection.isBackward
- }
-
- get isForward() {
- logger.deprecate(
- '0.37.0',
- 'The `value.isForward` property is deprecated, please use `selection.isForward` instead.'
- )
-
- return this.selection.isForward
- }
-
- get startKey() {
- logger.deprecate(
- '0.37.0',
- 'The `value.startKey` property is deprecated, please use `selection.start.key` instead.'
- )
-
- return this.selection.start.key
- }
-
- get endKey() {
- logger.deprecate(
- '0.37.0',
- 'The `value.endKey` property is deprecated, please use `selection.end.key` instead.'
- )
-
- return this.selection.end.key
- }
-
- get startPath() {
- logger.deprecate(
- '0.37.0',
- 'The `value.startPath` property is deprecated, please use `selection.start.path` instead.'
- )
-
- return this.selection.start.path
- }
-
- get endPath() {
- logger.deprecate(
- '0.37.0',
- 'The `value.endPath` property is deprecated, please use `selection.end.path` instead.'
- )
-
- return this.selection.end.path
- }
-
- get startOffset() {
- logger.deprecate(
- '0.37.0',
- 'The `value.startOffset` property is deprecated, please use `selection.start.offset` instead.'
- )
-
- return this.selection.start.offset
- }
-
- get endOffset() {
- logger.deprecate(
- '0.37.0',
- 'The `value.endOffset` property is deprecated, please use `selection.end.offset` instead.'
- )
-
- return this.selection.end.offset
- }
-
- get anchorKey() {
- logger.deprecate(
- '0.37.0',
- 'The `value.anchorKey` property is deprecated, please use `selection.anchor.key` instead.'
- )
-
- return this.selection.anchor.key
- }
-
- get focusKey() {
- logger.deprecate(
- '0.37.0',
- 'The `value.focusKey` property is deprecated, please use `selection.focus.key` instead.'
- )
-
- return this.selection.focus.key
- }
-
- get anchorPath() {
- logger.deprecate(
- '0.37.0',
- 'The `value.anchorPath` property is deprecated, please use `selection.anchor.path` instead.'
- )
-
- return this.selection.anchor.path
- }
-
- get focusPath() {
- logger.deprecate(
- '0.37.0',
- 'The `value.focusPath` property is deprecated, please use `selection.focus.path` instead.'
- )
-
- return this.selection.focus.path
- }
-
- get anchorOffset() {
- logger.deprecate(
- '0.37.0',
- 'The `value.anchorOffset` property is deprecated, please use `selection.anchor.offset` instead.'
- )
-
- return this.selection.anchor.offset
- }
-
- get focusOffset() {
- logger.deprecate(
- '0.37.0',
- 'The `value.focusOffset` property is deprecated, please use `selection.focus.offset` instead.'
- )
-
- return this.selection.focus.offset
- }
}
/**
diff --git a/packages/slate/src/utils/generate-key.js b/packages/slate/src/utils/generate-key.js
deleted file mode 100644
index eb8c35592..000000000
--- a/packages/slate/src/utils/generate-key.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import KeyUtils from './key-utils'
-import logger from 'slate-dev-logger'
-
-function generateKey() {
- logger.deprecate(
- `0.35.0`,
- 'The `generateKey()` util is deprecrated. Use the `KeyUtils.create()` helper instead.'
- )
-
- return KeyUtils.create()
-}
-
-function setKeyGenerator(fn) {
- logger.deprecate(
- `0.35.0`,
- 'The `setKeyGenerator()` util is deprecrated. Use the `KeyUtils.setGenerator()` helper instead.'
- )
-
- return KeyUtils.setGenerator(fn)
-}
-
-function resetKeyGenerator() {
- logger.deprecate(
- `0.35.0`,
- 'The `resetKeyGenerator()` util is deprecrated. Use the `KeyUtils.resetGenerator()` helper instead.'
- )
-
- return KeyUtils.resetGenerator()
-}
-
-export default generateKey
-export { setKeyGenerator, resetKeyGenerator }
diff --git a/packages/slate/test/changes/at-current-range/delete-backward/inline-inside.js b/packages/slate/test/changes/at-current-range/delete-backward/inline-inside.js
index 27b4080e5..5db6d9f1a 100644
--- a/packages/slate/test/changes/at-current-range/delete-backward/inline-inside.js
+++ b/packages/slate/test/changes/at-current-range/delete-backward/inline-inside.js
@@ -22,7 +22,9 @@ export const output = (
- onetwo
+ one
+
+ two
diff --git a/packages/slate/test/changes/at-current-range/delete-char-backward/inline-only-emoji.js b/packages/slate/test/changes/at-current-range/delete-char-backward/inline-only-emoji.js
index 4f6691789..f51880f7a 100644
--- a/packages/slate/test/changes/at-current-range/delete-char-backward/inline-only-emoji.js
+++ b/packages/slate/test/changes/at-current-range/delete-char-backward/inline-only-emoji.js
@@ -22,7 +22,9 @@ export const output = (
-
+
+
+
diff --git a/packages/slate/test/changes/at-current-range/delete-forward/inside-inline-sibling.js b/packages/slate/test/changes/at-current-range/delete-forward/inside-inline-sibling.js
index 2a671e971..3bcfe8056 100644
--- a/packages/slate/test/changes/at-current-range/delete-forward/inside-inline-sibling.js
+++ b/packages/slate/test/changes/at-current-range/delete-forward/inside-inline-sibling.js
@@ -22,7 +22,9 @@ export const output = (
- onetwo
+ one
+
+ two
diff --git a/packages/slate/test/changes/at-current-range/delete-line-forward/inline-middle-emoji.js b/packages/slate/test/changes/at-current-range/delete-line-forward/inline-middle-emoji.js
index 150c1b1ff..d940fd1f5 100644
--- a/packages/slate/test/changes/at-current-range/delete-line-forward/inline-middle-emoji.js
+++ b/packages/slate/test/changes/at-current-range/delete-line-forward/inline-middle-emoji.js
@@ -22,6 +22,7 @@ export const output = (
+
diff --git a/packages/slate/test/changes/at-current-range/delete-word-backward/inline-after-emoji.js b/packages/slate/test/changes/at-current-range/delete-word-backward/inline-after-emoji.js
index 29a7d358d..e8919708a 100644
--- a/packages/slate/test/changes/at-current-range/delete-word-backward/inline-after-emoji.js
+++ b/packages/slate/test/changes/at-current-range/delete-word-backward/inline-after-emoji.js
@@ -20,6 +20,7 @@ export const output = (
+
diff --git a/packages/slate/test/changes/at-current-range/delete-word-backward/inline-middle-emoji.js b/packages/slate/test/changes/at-current-range/delete-word-backward/inline-middle-emoji.js
index 82cdaf138..3671b1130 100644
--- a/packages/slate/test/changes/at-current-range/delete-word-backward/inline-middle-emoji.js
+++ b/packages/slate/test/changes/at-current-range/delete-word-backward/inline-middle-emoji.js
@@ -22,7 +22,9 @@ export const output = (
-
+
+
+
diff --git a/packages/slate/test/changes/at-current-range/delete-word-forward/inline-middle-emoji.js b/packages/slate/test/changes/at-current-range/delete-word-forward/inline-middle-emoji.js
index 7e4bb3cd0..3af8e0c47 100644
--- a/packages/slate/test/changes/at-current-range/delete-word-forward/inline-middle-emoji.js
+++ b/packages/slate/test/changes/at-current-range/delete-word-forward/inline-middle-emoji.js
@@ -22,6 +22,7 @@ export const output = (
+
diff --git a/packages/slate/test/changes/at-current-range/delete/inside-inline-sibling.js b/packages/slate/test/changes/at-current-range/delete/inside-inline-sibling.js
index 92489226b..3355048f8 100644
--- a/packages/slate/test/changes/at-current-range/delete/inside-inline-sibling.js
+++ b/packages/slate/test/changes/at-current-range/delete/inside-inline-sibling.js
@@ -22,7 +22,9 @@ export const output = (
- onetwo
+ one
+
+ two
diff --git a/packages/slate/test/changes/at-current-range/delete/whole-inline.js b/packages/slate/test/changes/at-current-range/delete/whole-inline.js
index aea046299..7e93ef2c3 100644
--- a/packages/slate/test/changes/at-current-range/delete/whole-inline.js
+++ b/packages/slate/test/changes/at-current-range/delete/whole-inline.js
@@ -22,7 +22,9 @@ export const output = (
-
+
+
+
diff --git a/packages/slate/test/changes/at-current-range/insert-fragment/end-inline.js b/packages/slate/test/changes/at-current-range/insert-fragment/end-inline.js
index 8865ddab6..61cc647ed 100644
--- a/packages/slate/test/changes/at-current-range/insert-fragment/end-inline.js
+++ b/packages/slate/test/changes/at-current-range/insert-fragment/end-inline.js
@@ -27,7 +27,10 @@ export const output = (
word
- fragment
+ fragment
+
+
+
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/block-end.js b/packages/slate/test/changes/at-current-range/insert-inline/block-end.js
index ee6130f47..5164f3801 100644
--- a/packages/slate/test/changes/at-current-range/insert-inline/block-end.js
+++ b/packages/slate/test/changes/at-current-range/insert-inline/block-end.js
@@ -3,10 +3,7 @@
import h from '../../../helpers/h'
export default function(change) {
- change.insertInline({
- type: 'emoji',
- isVoid: true,
- })
+ change.insertInline('emoji')
}
export const input = (
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/block-middle.js b/packages/slate/test/changes/at-current-range/insert-inline/block-middle.js
index 4df9aae97..84e75a104 100644
--- a/packages/slate/test/changes/at-current-range/insert-inline/block-middle.js
+++ b/packages/slate/test/changes/at-current-range/insert-inline/block-middle.js
@@ -3,10 +3,7 @@
import h from '../../../helpers/h'
export default function(change) {
- change.insertInline({
- type: 'emoji',
- isVoid: true,
- })
+ change.insertInline('emoji')
}
export const input = (
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/block-start.js b/packages/slate/test/changes/at-current-range/insert-inline/block-start.js
index dac0a2de3..1197e8db5 100644
--- a/packages/slate/test/changes/at-current-range/insert-inline/block-start.js
+++ b/packages/slate/test/changes/at-current-range/insert-inline/block-start.js
@@ -3,10 +3,7 @@
import h from '../../../helpers/h'
export default function(change) {
- change.insertInline({
- type: 'emoji',
- isVoid: true,
- })
+ change.insertInline('emoji')
}
export const input = (
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/inline-middle.js b/packages/slate/test/changes/at-current-range/insert-inline/inline-middle.js
index b877d7df3..480fb087e 100644
--- a/packages/slate/test/changes/at-current-range/insert-inline/inline-middle.js
+++ b/packages/slate/test/changes/at-current-range/insert-inline/inline-middle.js
@@ -3,10 +3,7 @@
import h from '../../../helpers/h'
export default function(change) {
- change.insertInline({
- type: 'emoji',
- isVoid: true,
- })
+ change.insertInline('emoji')
}
export const input = (
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/is-empty.js b/packages/slate/test/changes/at-current-range/insert-inline/is-empty.js
index df38230ef..a3f803840 100644
--- a/packages/slate/test/changes/at-current-range/insert-inline/is-empty.js
+++ b/packages/slate/test/changes/at-current-range/insert-inline/is-empty.js
@@ -3,10 +3,7 @@
import h from '../../../helpers/h'
export default function(change) {
- change.insertInline({
- type: 'emoji',
- isVoid: true,
- })
+ change.insertInline('emoji')
}
export const input = (
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/is-void.js b/packages/slate/test/changes/at-current-range/insert-inline/is-void.js
index 8b4ab3900..05e65b24e 100644
--- a/packages/slate/test/changes/at-current-range/insert-inline/is-void.js
+++ b/packages/slate/test/changes/at-current-range/insert-inline/is-void.js
@@ -3,10 +3,7 @@
import h from '../../../helpers/h'
export default function(change) {
- change.insertInline({
- type: 'emoji',
- isVoid: true,
- })
+ change.insertInline('emoji')
}
export const input = (
diff --git a/packages/slate/test/changes/at-current-range/insert-inline/with-inline.js b/packages/slate/test/changes/at-current-range/insert-inline/with-inline.js
index 4394c8f1e..1f4933ae0 100644
--- a/packages/slate/test/changes/at-current-range/insert-inline/with-inline.js
+++ b/packages/slate/test/changes/at-current-range/insert-inline/with-inline.js
@@ -4,12 +4,7 @@ import h from '../../../helpers/h'
import { Inline } from 'slate'
export default function(change) {
- change.insertInline(
- Inline.create({
- type: 'emoji',
- isVoid: true,
- })
- )
+ change.insertInline(Inline.create('emoji'))
}
export const input = (
diff --git a/packages/slate/test/changes/at-current-range/set-block/with-is-void.js b/packages/slate/test/changes/at-current-range/set-block/with-is-void.js
index 3f93a404b..8849f604f 100644
--- a/packages/slate/test/changes/at-current-range/set-block/with-is-void.js
+++ b/packages/slate/test/changes/at-current-range/set-block/with-is-void.js
@@ -3,10 +3,7 @@
import h from '../../../helpers/h'
export default function(change) {
- change.setBlocks({
- type: 'image',
- isVoid: true,
- })
+ change.setBlocks('image')
}
export const input = (
diff --git a/packages/slate/test/changes/at-current-range/set-inline/with-is-void.js b/packages/slate/test/changes/at-current-range/set-inline/with-is-void.js
index e71e2e5f8..e96029e7b 100644
--- a/packages/slate/test/changes/at-current-range/set-inline/with-is-void.js
+++ b/packages/slate/test/changes/at-current-range/set-inline/with-is-void.js
@@ -3,10 +3,7 @@
import h from '../../../helpers/h'
export default function(change) {
- change.setInlines({
- type: 'emoji',
- isVoid: true,
- })
+ change.setInlines('emoji')
}
export const input = (
diff --git a/packages/slate/test/changes/at-current-range/split-block/before-inline.js b/packages/slate/test/changes/at-current-range/split-block/before-inline.js
index 3f5748023..ee71fe69d 100644
--- a/packages/slate/test/changes/at-current-range/split-block/before-inline.js
+++ b/packages/slate/test/changes/at-current-range/split-block/before-inline.js
@@ -21,7 +21,9 @@ export const input = (
export const output = (
- word
+
+ word
+ hyperlink
diff --git a/packages/slate/test/changes/at-current-range/split-block/with-delete-across-blocks-and-inlines.js b/packages/slate/test/changes/at-current-range/split-block/with-delete-across-blocks-and-inlines.js
index 71b88b828..dd0c629b0 100644
--- a/packages/slate/test/changes/at-current-range/split-block/with-delete-across-blocks-and-inlines.js
+++ b/packages/slate/test/changes/at-current-range/split-block/with-delete-across-blocks-and-inlines.js
@@ -30,6 +30,7 @@ export const output = (
wo
+
other
diff --git a/packages/slate/test/changes/at-current-range/split-inline/block-end.js b/packages/slate/test/changes/at-current-range/split-inline/block-end.js
index 4cfffa337..dd4a70c41 100644
--- a/packages/slate/test/changes/at-current-range/split-inline/block-end.js
+++ b/packages/slate/test/changes/at-current-range/split-inline/block-end.js
@@ -22,8 +22,9 @@ export const output = (
+ word
- word
+
diff --git a/packages/slate/test/changes/at-current-range/split-inline/block-start.js b/packages/slate/test/changes/at-current-range/split-inline/block-start.js
index c2db3042f..a9331565d 100644
--- a/packages/slate/test/changes/at-current-range/split-inline/block-start.js
+++ b/packages/slate/test/changes/at-current-range/split-inline/block-start.js
@@ -22,6 +22,7 @@ export const output = (
+
word
diff --git a/packages/slate/test/changes/at-current-range/wrap-inline/twice.js b/packages/slate/test/changes/at-current-range/wrap-inline/twice.js
index b06cf9551..b031b6200 100644
--- a/packages/slate/test/changes/at-current-range/wrap-inline/twice.js
+++ b/packages/slate/test/changes/at-current-range/wrap-inline/twice.js
@@ -20,7 +20,8 @@ export const output = (
- w
+ w
+ or
diff --git a/packages/slate/test/changes/by-key/insert-node-by-key/inline.js b/packages/slate/test/changes/by-key/insert-node-by-key/inline.js
index 71fa7a91c..9149509ff 100644
--- a/packages/slate/test/changes/by-key/insert-node-by-key/inline.js
+++ b/packages/slate/test/changes/by-key/insert-node-by-key/inline.js
@@ -4,14 +4,7 @@ import h from '../../../helpers/h'
import { Inline } from 'slate'
export default function(change) {
- change.insertNodeByKey(
- 'a',
- 0,
- Inline.create({
- type: 'emoji',
- isVoid: true,
- })
- )
+ change.insertNodeByKey('a', 0, Inline.create('emoji'))
}
export const input = (
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/inline-last-character.js b/packages/slate/test/changes/by-key/remove-text-by-key/inline-last-character.js
index 7af8bf964..6837f1b8b 100644
--- a/packages/slate/test/changes/by-key/remove-text-by-key/inline-last-character.js
+++ b/packages/slate/test/changes/by-key/remove-text-by-key/inline-last-character.js
@@ -21,7 +21,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/changes/by-key/remove-text-by-key/inline-nested-last-character.js b/packages/slate/test/changes/by-key/remove-text-by-key/inline-nested-last-character.js
index 6004d6afe..78fc02667 100644
--- a/packages/slate/test/changes/by-key/remove-text-by-key/inline-nested-last-character.js
+++ b/packages/slate/test/changes/by-key/remove-text-by-key/inline-nested-last-character.js
@@ -26,7 +26,11 @@ export const output = (
-
+
+
+
+
+
diff --git a/packages/slate/test/changes/by-key/replace-node-by-key/inline.js b/packages/slate/test/changes/by-key/replace-node-by-key/inline.js
index d4f9b91fd..8f16ebc14 100644
--- a/packages/slate/test/changes/by-key/replace-node-by-key/inline.js
+++ b/packages/slate/test/changes/by-key/replace-node-by-key/inline.js
@@ -6,7 +6,6 @@ export default function(change) {
change.replaceNodeByKey('a', {
object: 'inline',
type: 'emoji',
- isVoid: true,
})
}
diff --git a/packages/slate/test/changes/by-key/replace-node-by-key/no-intermediate-normalization.js b/packages/slate/test/changes/by-key/replace-node-by-key/no-intermediate-normalization.js
deleted file mode 100644
index d34a4cf85..000000000
--- a/packages/slate/test/changes/by-key/replace-node-by-key/no-intermediate-normalization.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/** @jsx h */
-
-import h from '../../../helpers/h'
-
-/*
- * This test makes sure there are no intermediate normalization
- * when calling replaceNodeByKey which calls removeNodeByKey and insertNodeByKey successively.
- */
-
-export default function(change) {
- // Replacing by an empty text means the is now empty
- // and empty inlines are removed, according to Slate's core schema.
- // If an intermediate normalization were to happen, the final normalization
- // would fail to find the node's parent and thus throw because that parent
- // has already been removed before (due to the intermediate normalization).
- change.replaceNodeByKey('a', { object: 'text', text: '' })
-}
-
-export const input = (
-
-
-
-
- lorem
-
-
-
-
-)
-
-export const output = (
-
-
-
-
-
-)
diff --git a/packages/slate/test/changes/by-key/set-node-by-key/inline-with-is-void.js b/packages/slate/test/changes/by-key/set-node-by-key/inline-with-is-void.js
index 2913c7055..07b690dc7 100644
--- a/packages/slate/test/changes/by-key/set-node-by-key/inline-with-is-void.js
+++ b/packages/slate/test/changes/by-key/set-node-by-key/inline-with-is-void.js
@@ -3,10 +3,7 @@
import h from '../../../helpers/h'
export default function(change) {
- change.setNodeByKey('a', {
- type: 'emoji',
- isVoid: true,
- })
+ change.setNodeByKey('a', 'emoji')
}
export const input = (
diff --git a/packages/slate/test/changes/general/call/call-no-arguments.js b/packages/slate/test/changes/general/call/call-no-arguments.js
index 1deda9021..4bf2b927d 100644
--- a/packages/slate/test/changes/general/call/call-no-arguments.js
+++ b/packages/slate/test/changes/general/call/call-no-arguments.js
@@ -3,10 +3,7 @@
import h from '../../../helpers/h'
function insertImageBlock(change, blockType) {
- change.insertBlock({
- type: 'image',
- isVoid: true,
- })
+ change.insertBlock('image')
}
export default function(change) {
diff --git a/packages/slate/test/changes/general/call/call-with-arguments.js b/packages/slate/test/changes/general/call/call-with-arguments.js
index 03330a39a..ff579d912 100644
--- a/packages/slate/test/changes/general/call/call-with-arguments.js
+++ b/packages/slate/test/changes/general/call/call-with-arguments.js
@@ -2,15 +2,12 @@
import h from '../../../helpers/h'
-function insertVoid(change, blockType) {
- change.insertBlock({
- type: blockType,
- isVoid: true,
- })
+function insertBlockByType(change, blockType) {
+ change.insertBlock({ type: blockType })
}
export default function(change) {
- change.call(insertVoid, 'image')
+ change.call(insertBlockByType, 'image')
}
export const input = (
diff --git a/packages/slate/test/helpers/h.js b/packages/slate/test/helpers/h.js
index e82a303ed..e7eee36a4 100644
--- a/packages/slate/test/helpers/h.js
+++ b/packages/slate/test/helpers/h.js
@@ -8,19 +8,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',
@@ -33,6 +27,16 @@ const h = createHyperscript({
highlight: 'highlight',
},
schema: {
+ blocks: {
+ image: {
+ isVoid: true,
+ },
+ },
+ inlines: {
+ emoji: {
+ isVoid: true,
+ },
+ },
marks: {
result: {
isAtomic: true,
diff --git a/packages/slate/test/schema/core/block-all-block-children.js b/packages/slate/test/schema/core/block-all-block-children.js
index f179ab628..97b415004 100644
--- a/packages/slate/test/schema/core/block-all-block-children.js
+++ b/packages/slate/test/schema/core/block-all-block-children.js
@@ -24,13 +24,11 @@ export const output = {
{
object: 'block',
type: 'quote',
- isVoid: false,
data: {},
nodes: [
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/schema/core/block-all-inline-children.js b/packages/slate/test/schema/core/block-all-inline-children.js
index 38fb302bb..20c6e7e74 100644
--- a/packages/slate/test/schema/core/block-all-inline-children.js
+++ b/packages/slate/test/schema/core/block-all-inline-children.js
@@ -24,7 +24,6 @@ export const output = {
{
object: 'block',
type: 'quote',
- isVoid: false,
data: {},
nodes: [
{
@@ -40,7 +39,6 @@ export const output = {
{
object: 'inline',
type: 'link',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/schema/core/block-all-text-children.js b/packages/slate/test/schema/core/block-all-text-children.js
index 02f072d40..e8e67b074 100644
--- a/packages/slate/test/schema/core/block-all-text-children.js
+++ b/packages/slate/test/schema/core/block-all-text-children.js
@@ -24,7 +24,6 @@ export const output = {
{
object: 'block',
type: 'quote',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/schema/core/block-create-text.js b/packages/slate/test/schema/core/block-create-text.js
index 07b02e7e7..e98ea1670 100644
--- a/packages/slate/test/schema/core/block-create-text.js
+++ b/packages/slate/test/schema/core/block-create-text.js
@@ -21,7 +21,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/schema/core/document-no-inline-children.js b/packages/slate/test/schema/core/document-no-inline-children.js
index 375816409..ae79220ae 100644
--- a/packages/slate/test/schema/core/document-no-inline-children.js
+++ b/packages/slate/test/schema/core/document-no-inline-children.js
@@ -22,7 +22,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/schema/core/document-no-text-children.js b/packages/slate/test/schema/core/document-no-text-children.js
index 05ca0a91b..5caf95f72 100644
--- a/packages/slate/test/schema/core/document-no-text-children.js
+++ b/packages/slate/test/schema/core/document-no-text-children.js
@@ -22,7 +22,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/schema/core/inline-no-block-children.js b/packages/slate/test/schema/core/inline-no-block-children.js
index 01126c1cf..33ef2bd3f 100644
--- a/packages/slate/test/schema/core/inline-no-block-children.js
+++ b/packages/slate/test/schema/core/inline-no-block-children.js
@@ -26,7 +26,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
@@ -42,7 +41,6 @@ export const output = {
{
object: 'inline',
type: 'link',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/schema/core/inline-text-around.js b/packages/slate/test/schema/core/inline-text-around.js
index c875a629c..506d4fb14 100644
--- a/packages/slate/test/schema/core/inline-text-around.js
+++ b/packages/slate/test/schema/core/inline-text-around.js
@@ -26,7 +26,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
@@ -42,7 +41,6 @@ export const output = {
{
object: 'inline',
type: 'link',
- isVoid: false,
data: {},
nodes: [
{
@@ -58,7 +56,6 @@ export const output = {
{
object: 'inline',
type: 'link',
- isVoid: false,
data: {},
nodes: [
{
@@ -86,7 +83,6 @@ export const output = {
{
object: 'inline',
type: 'link',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/schema/core/merge-adjacent-texts.js b/packages/slate/test/schema/core/merge-adjacent-texts.js
index 108a222d0..e11221fd9 100644
--- a/packages/slate/test/schema/core/merge-adjacent-texts.js
+++ b/packages/slate/test/schema/core/merge-adjacent-texts.js
@@ -25,7 +25,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/schema/core/preserve-inline-with-empty-void.js b/packages/slate/test/schema/core/preserve-inline-with-empty-void.js
index 4c17f9d51..2657e5e31 100644
--- a/packages/slate/test/schema/core/preserve-inline-with-empty-void.js
+++ b/packages/slate/test/schema/core/preserve-inline-with-empty-void.js
@@ -9,7 +9,7 @@ export const input = (
-
+
@@ -25,7 +25,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
@@ -41,7 +40,6 @@ export const output = {
{
object: 'inline',
type: 'link',
- isVoid: false,
data: {},
nodes: [
{
@@ -57,7 +55,6 @@ export const output = {
{
object: 'inline',
type: '',
- isVoid: true,
data: {},
nodes: [
{
diff --git a/packages/slate/test/schema/core/remove-empty-inline.js b/packages/slate/test/schema/core/remove-empty-inline.js
deleted file mode 100644
index b3d1128af..000000000
--- a/packages/slate/test/schema/core/remove-empty-inline.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/** @jsx h */
-
-import h from '../../helpers/h'
-
-export const schema = {}
-
-export const input = (
-
-
-
-
-
-
-
-)
-
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- isVoid: false,
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
diff --git a/packages/slate/test/schema/core/remove-nested-empty-inline.js b/packages/slate/test/schema/core/remove-nested-empty-inline.js
deleted file mode 100644
index b6daa9d6e..000000000
--- a/packages/slate/test/schema/core/remove-nested-empty-inline.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/** @jsx h */
-
-import h from '../../helpers/h'
-
-export const schema = {}
-
-export const input = (
-
-
-
-
- one
-
- two
-
-
-
-
-)
-
-export const output = {
- object: 'value',
- document: {
- object: 'document',
- data: {},
- nodes: [
- {
- object: 'block',
- type: 'paragraph',
- isVoid: false,
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- {
- object: 'inline',
- type: 'link',
- isVoid: false,
- data: {},
- nodes: [
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: 'onetwo',
- marks: [],
- },
- ],
- },
- ],
- },
- {
- object: 'text',
- leaves: [
- {
- object: 'leaf',
- text: '',
- marks: [],
- },
- ],
- },
- ],
- },
- ],
- },
-}
diff --git a/packages/slate/test/schema/custom/child-kind-invalid-custom-optional-first.js b/packages/slate/test/schema/custom/child-kind-invalid-custom-optional-first.js
index 47172adad..7013521ce 100644
--- a/packages/slate/test/schema/custom/child-kind-invalid-custom-optional-first.js
+++ b/packages/slate/test/schema/custom/child-kind-invalid-custom-optional-first.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { CHILD_OBJECT_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -19,7 +18,7 @@ export const schema = {
},
],
normalize: (change, { code, child }) => {
- if (code == CHILD_OBJECT_INVALID) {
+ if (code == 'child_object_invalid') {
change.wrapBlockByKey(child.key, 'paragraph')
}
},
diff --git a/packages/slate/test/schema/custom/child-kind-invalid-custom.js b/packages/slate/test/schema/custom/child-kind-invalid-custom.js
index c37119d93..5a99d6401 100644
--- a/packages/slate/test/schema/custom/child-kind-invalid-custom.js
+++ b/packages/slate/test/schema/custom/child-kind-invalid-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { CHILD_OBJECT_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -13,7 +12,7 @@ export const schema = {
},
],
normalize: (change, { code, child }) => {
- if (code == CHILD_OBJECT_INVALID) {
+ if (code == 'child_object_invalid') {
change.wrapBlockByKey(child.key, 'paragraph')
}
},
diff --git a/packages/slate/test/schema/custom/child-required-custom.js b/packages/slate/test/schema/custom/child-required-custom.js
index 5ea67e0d9..26f45b579 100644
--- a/packages/slate/test/schema/custom/child-required-custom.js
+++ b/packages/slate/test/schema/custom/child-required-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { CHILD_REQUIRED } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -14,7 +13,7 @@ export const schema = {
},
],
normalize: (change, { code, node, index }) => {
- if (code == CHILD_REQUIRED) {
+ if (code == 'child_required') {
change.insertNodeByKey(node.key, index, {
object: 'block',
type: 'paragraph',
diff --git a/packages/slate/test/schema/custom/child-type-invalid-custom.js b/packages/slate/test/schema/custom/child-type-invalid-custom.js
index 34ff79aac..22b169168 100644
--- a/packages/slate/test/schema/custom/child-type-invalid-custom.js
+++ b/packages/slate/test/schema/custom/child-type-invalid-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { CHILD_TYPE_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -13,7 +12,7 @@ export const schema = {
},
],
normalize: (change, { code, child }) => {
- if (code == CHILD_TYPE_INVALID) {
+ if (code == 'child_type_invalid') {
change.wrapBlockByKey(child.key, 'paragraph')
}
},
diff --git a/packages/slate/test/schema/custom/child-unknown-custom.js b/packages/slate/test/schema/custom/child-unknown-custom.js
index 01d3dee40..d5882c547 100644
--- a/packages/slate/test/schema/custom/child-unknown-custom.js
+++ b/packages/slate/test/schema/custom/child-unknown-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { CHILD_UNKNOWN } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -14,7 +13,7 @@ export const schema = {
},
],
normalize: (change, { code, node, child }) => {
- if (code == CHILD_UNKNOWN) {
+ if (code == 'child_unknown') {
const previous = node.getPreviousSibling(child.key)
const offset = previous.nodes.size
diff --git a/packages/slate/test/schema/custom/first-child-kind-invalid-custom.js b/packages/slate/test/schema/custom/first-child-kind-invalid-custom.js
index 96f43a88d..7604b90f4 100644
--- a/packages/slate/test/schema/custom/first-child-kind-invalid-custom.js
+++ b/packages/slate/test/schema/custom/first-child-kind-invalid-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { FIRST_CHILD_OBJECT_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -9,7 +8,7 @@ export const schema = {
quote: {
first: [{ object: 'block' }],
normalize: (change, { code, child }) => {
- if (code == FIRST_CHILD_OBJECT_INVALID) {
+ if (code == 'first_child_object_invalid') {
change.wrapBlockByKey(child.key, 'paragraph')
}
},
diff --git a/packages/slate/test/schema/custom/first-child-type-invalid-custom.js b/packages/slate/test/schema/custom/first-child-type-invalid-custom.js
index 3cf6359d6..9156f2e19 100644
--- a/packages/slate/test/schema/custom/first-child-type-invalid-custom.js
+++ b/packages/slate/test/schema/custom/first-child-type-invalid-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { FIRST_CHILD_TYPE_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -9,7 +8,7 @@ export const schema = {
quote: {
first: [{ type: 'paragraph' }],
normalize: (change, { code, child }) => {
- if (code == FIRST_CHILD_TYPE_INVALID) {
+ if (code == 'first_child_type_invalid') {
change.wrapBlockByKey(child.key, 'paragraph')
}
},
diff --git a/packages/slate/test/schema/custom/last-child-kind-invalid-custom.js b/packages/slate/test/schema/custom/last-child-kind-invalid-custom.js
index 732ce6ce5..777d7575a 100644
--- a/packages/slate/test/schema/custom/last-child-kind-invalid-custom.js
+++ b/packages/slate/test/schema/custom/last-child-kind-invalid-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { LAST_CHILD_OBJECT_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -9,7 +8,7 @@ export const schema = {
quote: {
last: [{ object: 'block' }],
normalize: (change, { code, child }) => {
- if (code == LAST_CHILD_OBJECT_INVALID) {
+ if (code == 'last_child_object_invalid') {
change.wrapBlockByKey(child.key, 'paragraph')
}
},
diff --git a/packages/slate/test/schema/custom/last-child-type-invalid-custom.js b/packages/slate/test/schema/custom/last-child-type-invalid-custom.js
index d7b199dd3..bf5de7aec 100644
--- a/packages/slate/test/schema/custom/last-child-type-invalid-custom.js
+++ b/packages/slate/test/schema/custom/last-child-type-invalid-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { LAST_CHILD_TYPE_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -9,7 +8,7 @@ export const schema = {
quote: {
last: [{ type: 'paragraph' }],
normalize: (change, { code, child }) => {
- if (code == LAST_CHILD_TYPE_INVALID) {
+ if (code == 'last_child_type_invalid') {
change.wrapBlockByKey(child.key, 'paragraph')
}
},
diff --git a/packages/slate/test/schema/custom/node-data-invalid-custom.js b/packages/slate/test/schema/custom/node-data-invalid-custom.js
index ea1373564..605ce1a70 100644
--- a/packages/slate/test/schema/custom/node-data-invalid-custom.js
+++ b/packages/slate/test/schema/custom/node-data-invalid-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { NODE_DATA_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -10,7 +9,7 @@ export const schema = {
thing: v => v == 'value',
},
normalize: (change, { code, node, key }) => {
- if (code == NODE_DATA_INVALID) {
+ if (code == 'node_data_invalid') {
change.setNodeByKey(node.key, { data: { thing: 'value' } })
}
},
diff --git a/packages/slate/test/schema/custom/node-is-void-invalid-custom.js b/packages/slate/test/schema/custom/node-is-void-invalid-custom.js
deleted file mode 100644
index 9298dbd77..000000000
--- a/packages/slate/test/schema/custom/node-is-void-invalid-custom.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/** @jsx h */
-
-import { NODE_IS_VOID_INVALID } from 'slate-schema-violations'
-import h from '../../helpers/h'
-
-export const schema = {
- blocks: {
- paragraph: {
- isVoid: false,
- normalize: (change, { code, node }) => {
- if (code == NODE_IS_VOID_INVALID) {
- change.removeNodeByKey(node.key, 'paragraph')
- }
- },
- },
- },
-}
-
-export const input = (
-
-
-
-
-
-)
-
-export const output = (
-
-
-
-)
diff --git a/packages/slate/test/schema/custom/node-is-void-invalid-default.js b/packages/slate/test/schema/custom/node-is-void-invalid-default.js
deleted file mode 100644
index a6b2bef78..000000000
--- a/packages/slate/test/schema/custom/node-is-void-invalid-default.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/** @jsx h */
-
-import h from '../../helpers/h'
-
-export const schema = {
- blocks: {
- paragraph: {
- isVoid: false,
- },
- },
-}
-
-export const input = (
-
-
-
-
-
-)
-
-export const output = (
-
-
-
-
-
-)
diff --git a/packages/slate/test/schema/custom/node-mark-invalid-custom.js b/packages/slate/test/schema/custom/node-mark-invalid-custom.js
index 03b535dc2..0951c8eea 100644
--- a/packages/slate/test/schema/custom/node-mark-invalid-custom.js
+++ b/packages/slate/test/schema/custom/node-mark-invalid-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { NODE_MARK_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -8,7 +7,7 @@ export const schema = {
paragraph: {
marks: [{ type: 'bold' }],
normalize: (change, { code, node }) => {
- if (code == NODE_MARK_INVALID) {
+ if (code == 'node_mark_invalid') {
node.nodes.forEach(n => change.removeNodeByKey(n.key))
}
},
diff --git a/packages/slate/test/schema/custom/node-text-invalid-custom.js b/packages/slate/test/schema/custom/node-text-invalid-custom.js
index c4dc29f1c..e3ac1ffbd 100644
--- a/packages/slate/test/schema/custom/node-text-invalid-custom.js
+++ b/packages/slate/test/schema/custom/node-text-invalid-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { NODE_TEXT_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -8,7 +7,7 @@ export const schema = {
paragraph: {
text: /^\d*$/,
normalize: (change, { code, node }) => {
- if (code == NODE_TEXT_INVALID) {
+ if (code == 'node_text_invalid') {
node.nodes.forEach(n => change.removeNodeByKey(n.key))
}
},
diff --git a/packages/slate/test/schema/custom/parent-kind-invalid-custom.js b/packages/slate/test/schema/custom/parent-kind-invalid-custom.js
index 4b61e3361..4288c5720 100644
--- a/packages/slate/test/schema/custom/parent-kind-invalid-custom.js
+++ b/packages/slate/test/schema/custom/parent-kind-invalid-custom.js
@@ -1,14 +1,13 @@
/** @jsx h */
-import { PARENT_OBJECT_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
- inlines: {
- link: {
- parent: { object: 'block' },
+ blocks: {
+ paragraph: {
+ parent: { object: 'document' },
normalize: (change, { code, node }) => {
- if (code == PARENT_OBJECT_INVALID) {
+ if (code == 'parent_object_invalid') {
change.unwrapNodeByKey(node.key)
}
},
@@ -19,11 +18,9 @@ export const schema = {
export const input = (
-
-
- one
-
-
+
+ one
+
)
@@ -31,9 +28,7 @@ export const input = (
export const output = (
-
- one
-
+ one
)
diff --git a/packages/slate/test/schema/custom/parent-kind-invalid-default.js b/packages/slate/test/schema/custom/parent-kind-invalid-default.js
index 6549ec775..146d5799d 100644
--- a/packages/slate/test/schema/custom/parent-kind-invalid-default.js
+++ b/packages/slate/test/schema/custom/parent-kind-invalid-default.js
@@ -25,7 +25,9 @@ export const input = (
export const output = (
-
+
+
+
)
diff --git a/packages/slate/test/schema/custom/parent-type-invalid-custom.js b/packages/slate/test/schema/custom/parent-type-invalid-custom.js
index 5108fb8eb..9f1e88bf4 100644
--- a/packages/slate/test/schema/custom/parent-type-invalid-custom.js
+++ b/packages/slate/test/schema/custom/parent-type-invalid-custom.js
@@ -1,6 +1,5 @@
/** @jsx h */
-import { PARENT_TYPE_INVALID } from 'slate-schema-violations'
import h from '../../helpers/h'
export const schema = {
@@ -9,7 +8,7 @@ export const schema = {
item: {
parent: { type: 'list' },
normalize: (change, { code, node }) => {
- if (code == PARENT_TYPE_INVALID) {
+ if (code == 'parent_type_invalid') {
change.wrapBlockByKey(node.key, 'list')
}
},
diff --git a/packages/slate/test/serializers/raw/deserialize/block-nested.js b/packages/slate/test/serializers/raw/deserialize/block-nested.js
index cfe8fdd73..c049152b6 100644
--- a/packages/slate/test/serializers/raw/deserialize/block-nested.js
+++ b/packages/slate/test/serializers/raw/deserialize/block-nested.js
@@ -12,13 +12,11 @@ export const input = {
object: 'block',
type: 'quote',
data: {},
- isVoid: false,
nodes: [
{
object: 'block',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
diff --git a/packages/slate/test/serializers/raw/deserialize/block-with-data.js b/packages/slate/test/serializers/raw/deserialize/block-with-data.js
index f609e13bc..1d2be1ed4 100644
--- a/packages/slate/test/serializers/raw/deserialize/block-with-data.js
+++ b/packages/slate/test/serializers/raw/deserialize/block-with-data.js
@@ -11,7 +11,6 @@ export const input = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {
thing: 'value',
},
diff --git a/packages/slate/test/serializers/raw/deserialize/block-with-is-void.js b/packages/slate/test/serializers/raw/deserialize/block-with-is-void.js
index 6812cab48..f92c63149 100644
--- a/packages/slate/test/serializers/raw/deserialize/block-with-is-void.js
+++ b/packages/slate/test/serializers/raw/deserialize/block-with-is-void.js
@@ -11,7 +11,6 @@ export const input = {
{
object: 'block',
type: 'image',
- isVoid: true,
data: {},
nodes: [
{
diff --git a/packages/slate/test/serializers/raw/deserialize/block.js b/packages/slate/test/serializers/raw/deserialize/block.js
index 8c4cf368c..51ddc294f 100644
--- a/packages/slate/test/serializers/raw/deserialize/block.js
+++ b/packages/slate/test/serializers/raw/deserialize/block.js
@@ -12,7 +12,6 @@ export const input = {
object: 'block',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
diff --git a/packages/slate/test/serializers/raw/deserialize/inline-nested.js b/packages/slate/test/serializers/raw/deserialize/inline-nested.js
index 5bf87f860..d4a0cbbcf 100644
--- a/packages/slate/test/serializers/raw/deserialize/inline-nested.js
+++ b/packages/slate/test/serializers/raw/deserialize/inline-nested.js
@@ -12,7 +12,6 @@ export const input = {
object: 'block',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
@@ -28,7 +27,6 @@ export const input = {
object: 'inline',
type: 'link',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
@@ -44,7 +42,6 @@ export const input = {
object: 'inline',
type: 'hashtag',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
diff --git a/packages/slate/test/serializers/raw/deserialize/inline-with-data.js b/packages/slate/test/serializers/raw/deserialize/inline-with-data.js
index a3f54949d..74efe6b3b 100644
--- a/packages/slate/test/serializers/raw/deserialize/inline-with-data.js
+++ b/packages/slate/test/serializers/raw/deserialize/inline-with-data.js
@@ -12,7 +12,6 @@ export const input = {
object: 'block',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
@@ -27,7 +26,6 @@ export const input = {
{
object: 'inline',
type: 'link',
- isVoid: false,
data: {
thing: 'value',
},
diff --git a/packages/slate/test/serializers/raw/deserialize/inline-with-is-void.js b/packages/slate/test/serializers/raw/deserialize/inline-with-is-void.js
index d01ad602c..7322a2ae7 100644
--- a/packages/slate/test/serializers/raw/deserialize/inline-with-is-void.js
+++ b/packages/slate/test/serializers/raw/deserialize/inline-with-is-void.js
@@ -11,7 +11,6 @@ export const input = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
@@ -27,7 +26,6 @@ export const input = {
{
object: 'inline',
type: 'emoji',
- isVoid: true,
data: {},
nodes: [
{
diff --git a/packages/slate/test/serializers/raw/deserialize/inline.js b/packages/slate/test/serializers/raw/deserialize/inline.js
index 90cd8cfbc..5492f9f5f 100644
--- a/packages/slate/test/serializers/raw/deserialize/inline.js
+++ b/packages/slate/test/serializers/raw/deserialize/inline.js
@@ -11,7 +11,6 @@ export const input = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
@@ -27,7 +26,6 @@ export const input = {
{
object: 'inline',
type: 'link',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/serializers/raw/deserialize/range-with-mark.js b/packages/slate/test/serializers/raw/deserialize/range-with-mark.js
index 384dbc112..c7d3a3a1b 100644
--- a/packages/slate/test/serializers/raw/deserialize/range-with-mark.js
+++ b/packages/slate/test/serializers/raw/deserialize/range-with-mark.js
@@ -11,7 +11,6 @@ export const input = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/serializers/raw/serialize/block-nested.js b/packages/slate/test/serializers/raw/serialize/block-nested.js
index 09f165cb0..e0703e6e0 100644
--- a/packages/slate/test/serializers/raw/serialize/block-nested.js
+++ b/packages/slate/test/serializers/raw/serialize/block-nested.js
@@ -22,13 +22,11 @@ export const output = {
object: 'block',
type: 'quote',
data: {},
- isVoid: false,
nodes: [
{
object: 'block',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
diff --git a/packages/slate/test/serializers/raw/serialize/block-with-data.js b/packages/slate/test/serializers/raw/serialize/block-with-data.js
index 08e798665..e9a4bf9b4 100644
--- a/packages/slate/test/serializers/raw/serialize/block-with-data.js
+++ b/packages/slate/test/serializers/raw/serialize/block-with-data.js
@@ -19,7 +19,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {
thing: 'value',
},
diff --git a/packages/slate/test/serializers/raw/serialize/block-with-is-void.js b/packages/slate/test/serializers/raw/serialize/block-with-is-void.js
index 61987804d..acbfb7793 100644
--- a/packages/slate/test/serializers/raw/serialize/block-with-is-void.js
+++ b/packages/slate/test/serializers/raw/serialize/block-with-is-void.js
@@ -19,7 +19,6 @@ export const output = {
{
object: 'block',
type: 'image',
- isVoid: true,
data: {},
nodes: [
{
diff --git a/packages/slate/test/serializers/raw/serialize/block.js b/packages/slate/test/serializers/raw/serialize/block.js
index 89c5e2f89..e5993b268 100644
--- a/packages/slate/test/serializers/raw/serialize/block.js
+++ b/packages/slate/test/serializers/raw/serialize/block.js
@@ -20,7 +20,6 @@ export const output = {
object: 'block',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
diff --git a/packages/slate/test/serializers/raw/serialize/inline-nested.js b/packages/slate/test/serializers/raw/serialize/inline-nested.js
index 917f4b00b..966b1b555 100644
--- a/packages/slate/test/serializers/raw/serialize/inline-nested.js
+++ b/packages/slate/test/serializers/raw/serialize/inline-nested.js
@@ -24,7 +24,6 @@ export const output = {
object: 'block',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
@@ -40,7 +39,6 @@ export const output = {
object: 'inline',
type: 'link',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
@@ -56,7 +54,6 @@ export const output = {
object: 'inline',
type: 'hashtag',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
diff --git a/packages/slate/test/serializers/raw/serialize/inline-with-data.js b/packages/slate/test/serializers/raw/serialize/inline-with-data.js
index be3a9d097..67e89ad62 100644
--- a/packages/slate/test/serializers/raw/serialize/inline-with-data.js
+++ b/packages/slate/test/serializers/raw/serialize/inline-with-data.js
@@ -22,7 +22,6 @@ export const output = {
object: 'block',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
@@ -37,7 +36,6 @@ export const output = {
{
object: 'inline',
type: 'link',
- isVoid: false,
data: {
thing: 'value',
},
diff --git a/packages/slate/test/serializers/raw/serialize/inline-with-is-void.js b/packages/slate/test/serializers/raw/serialize/inline-with-is-void.js
index 2cfb8aa85..141862835 100644
--- a/packages/slate/test/serializers/raw/serialize/inline-with-is-void.js
+++ b/packages/slate/test/serializers/raw/serialize/inline-with-is-void.js
@@ -21,7 +21,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
@@ -37,7 +36,6 @@ export const output = {
{
object: 'inline',
type: 'emoji',
- isVoid: true,
data: {},
nodes: [
{
diff --git a/packages/slate/test/serializers/raw/serialize/inline.js b/packages/slate/test/serializers/raw/serialize/inline.js
index f70a9eab0..0d67794c3 100644
--- a/packages/slate/test/serializers/raw/serialize/inline.js
+++ b/packages/slate/test/serializers/raw/serialize/inline.js
@@ -21,7 +21,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
@@ -37,7 +36,6 @@ export const output = {
{
object: 'inline',
type: 'link',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/packages/slate/test/serializers/raw/serialize/preserve-data.js b/packages/slate/test/serializers/raw/serialize/preserve-data.js
index 3c699face..99fc21889 100644
--- a/packages/slate/test/serializers/raw/serialize/preserve-data.js
+++ b/packages/slate/test/serializers/raw/serialize/preserve-data.js
@@ -21,7 +21,6 @@ export const output = {
object: 'block',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
diff --git a/packages/slate/test/serializers/raw/serialize/preserve-keys.js b/packages/slate/test/serializers/raw/serialize/preserve-keys.js
index be4e4b854..70a14beec 100644
--- a/packages/slate/test/serializers/raw/serialize/preserve-keys.js
+++ b/packages/slate/test/serializers/raw/serialize/preserve-keys.js
@@ -24,7 +24,6 @@ export const output = {
key: '1',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
diff --git a/packages/slate/test/serializers/raw/serialize/preserve-selection-and-keys.js b/packages/slate/test/serializers/raw/serialize/preserve-selection-and-keys.js
index 3b6f8aa56..d390f2871 100644
--- a/packages/slate/test/serializers/raw/serialize/preserve-selection-and-keys.js
+++ b/packages/slate/test/serializers/raw/serialize/preserve-selection-and-keys.js
@@ -24,7 +24,6 @@ export const output = {
type: 'paragraph',
key: '1',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
diff --git a/packages/slate/test/serializers/raw/serialize/preserve-selection.js b/packages/slate/test/serializers/raw/serialize/preserve-selection.js
index 11d304e91..787335113 100644
--- a/packages/slate/test/serializers/raw/serialize/preserve-selection.js
+++ b/packages/slate/test/serializers/raw/serialize/preserve-selection.js
@@ -20,7 +20,6 @@ export const output = {
object: 'block',
type: 'paragraph',
data: {},
- isVoid: false,
nodes: [
{
object: 'text',
diff --git a/packages/slate/test/serializers/raw/serialize/range-with-mark.js b/packages/slate/test/serializers/raw/serialize/range-with-mark.js
index 486f7b167..7d8f3c856 100644
--- a/packages/slate/test/serializers/raw/serialize/range-with-mark.js
+++ b/packages/slate/test/serializers/raw/serialize/range-with-mark.js
@@ -21,7 +21,6 @@ export const output = {
{
object: 'block',
type: 'paragraph',
- isVoid: false,
data: {},
nodes: [
{
diff --git a/support/rollup/config.js b/support/rollup/config.js
index e88232b60..585f62754 100644
--- a/support/rollup/config.js
+++ b/support/rollup/config.js
@@ -2,29 +2,26 @@ import factory from './factory'
import slate from '../../packages/slate/package.json'
import slateBase64Serializer from '../../packages/slate-base64-serializer/package.json'
import slateDevEnvironment from '../../packages/slate-dev-environment/package.json'
-import slateDevLogger from '../../packages/slate-dev-logger/package.json'
+import slateDevWarning from '../../packages/slate-dev-warning/package.json'
import slateHotkeys from '../../packages/slate-hotkeys/package.json'
import slateHtmlSerializer from '../../packages/slate-html-serializer/package.json'
import slateHyperscript from '../../packages/slate-hyperscript/package.json'
import slatePlainSerializer from '../../packages/slate-plain-serializer/package.json'
import slatePropTypes from '../../packages/slate-prop-types/package.json'
import slateReact from '../../packages/slate-react/package.json'
-import slateSchemaViolations from '../../packages/slate-schema-violations/package.json'
import slateSimulator from '../../packages/slate-simulator/package.json'
-// Do not import slateDevBenchmark here. The benchmark shall be a pure nodeJS program and can be run without babel-node
const configurations = [
...factory(slate),
...factory(slateBase64Serializer),
...factory(slateDevEnvironment),
- ...factory(slateDevLogger),
+ ...factory(slateDevWarning),
...factory(slateHotkeys),
...factory(slateHtmlSerializer),
...factory(slateHyperscript),
...factory(slatePlainSerializer),
...factory(slatePropTypes),
...factory(slateReact),
- ...factory(slateSchemaViolations),
...factory(slateSimulator),
]
diff --git a/yarn.lock b/yarn.lock
index 4755afc9e..c468d430c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4640,10 +4640,6 @@ is-dotfile@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d"
-is-empty@^1.0.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/is-empty/-/is-empty-1.2.0.tgz#de9bb5b278738a05a0b09a57e1fb4d4a341a9f6b"
-
is-equal-shallow@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
@@ -5117,10 +5113,6 @@ jsx-ast-utils@^2.0.1:
dependencies:
array-includes "^3.0.3"
-keycode@^2.1.2:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04"
-
killable@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b"
@@ -7035,12 +7027,6 @@ react-immutable-proptypes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz#023d6f39bb15c97c071e9e60d00d136eac5fa0b4"
-react-portal@^3.1.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/react-portal/-/react-portal-3.2.0.tgz#4224e19b2b05d5cbe730a7ba0e34ec7585de0043"
- dependencies:
- prop-types "^15.5.8"
-
react-portal@^4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/react-portal/-/react-portal-4.1.5.tgz#6665d4d2a92d47d6f8b07a6529e26fc52d5cccde"