1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-30 10:29:48 +02:00

Fix typos and other minor issues in docs (#3597)

Fixed typos and grammatical errors in the documentation
This commit is contained in:
Kirk Swenson
2020-04-10 09:05:03 -07:00
committed by GitHub
parent c9891a29e1
commit f6bfe034d7
16 changed files with 49 additions and 48 deletions

View File

@@ -1,8 +1,8 @@
# Nodes: Editor, Elements and Texts
The most important type are the `Node` objects:
The most important types are the `Node` objects:
- A root-level `Editor` node that contains their entire document's content.
- A root-level `Editor` node that contains the entire document's content.
- Container `Element` nodes which have semantic meaning in your domain.
- And leaf-level `Text` nodes which contain the document's text.
@@ -33,7 +33,7 @@ Mirroring the DOM as much as possible is one of Slate's principles. People use t
> - [Inline elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements)
> - [Text elements](https://developer.mozilla.org/en-US/docs/Web/API/Text)
A Slate document is a nested and recursive structure. In a document, elements can have children nodes—all which may have children nodes without limit. The nested and recursive structure enables you to model simple behaviors such as user mentions and hashtags or complex behaviors such as tables and figures with captions.
A Slate document is a nested and recursive structure. In a document, elements can have children nodes—all of which may have children nodes without limit. The nested and recursive structure enables you to model simple behaviors such as user mentions and hashtags or complex behaviors such as tables and figures with captions.
## `Editor`
@@ -101,7 +101,7 @@ Depending on your use case, you might want to define another behavior for `Eleme
All elements default to being "block" elements. They each appear separated by vertical space, and they never run into each other.
But in certain cases, like for links, you might want to make as "inline" flowing elements instead. That way they live at the same level as text nodes, and flow.
But in certain cases, like for links, you might want to make them "inline" flowing elements instead. That way they live at the same level as text nodes, and flow.
> 🤖 This is a concept borrowed from the DOM's behavior, see [Block Elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements) and [Inline Elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements).
@@ -111,13 +111,13 @@ Elements can either contain block elements as children. Or they can contain inli
## Voids
Similarly to blocks and inlines, there is another element-specific behavior you can define depending on your use case: their "void"-ness.
Similar to blocks and inlines, there is another element-specific behavior you can define depending on your use case: their "void"-ness.
Elements default to being non-void, meaning that their children are fully editable as text. But in some cases, like for images, you want to ensure that Slate doesn't treat their content as editable text, but instead as a black box.
> 🤖 This is a concept borrowed from the HTML spec, see [Void Elements](https://www.w3.org/TR/2011/WD-html-markup-20110405/syntax.html#void-element).
You can do define which elements are treated as void by overriding the `editor.isVoid` function. (By default it always returns `false`.)
You can define which elements are treated as void by overriding the `editor.isVoid` function. (By default it always returns `false`.)
## `Text`

View File

@@ -4,7 +4,7 @@ Locations are how you refer to specific places in the document when inserting, d
## `Path`
Paths are the lowest-level way to refer to a location. Each path is a simple array of numbers that refers to a node in the document tree by its indexes in each of its ancestors nodes down the tree:
Paths are the lowest-level way to refer to a location. Each path is a simple array of numbers that refers to a node in the document tree by its indexes in each of its ancestor nodes down the tree:
```ts
type Path = number[]
@@ -92,7 +92,7 @@ One important distinction is that the anchor and focus points of ranges **always
Ranges are used in many places in Slate's API when you need to refer to a span of content between two points. One of the most common though is the user's current "selection".
The selection is a special range that is property of the top-level `Editor`. For example, say someone has the whole sentence currently selected:
The selection is a special range that is a property of the top-level `Editor`. For example, say someone has the whole sentence currently selected:
```js
const editor = {
@@ -115,4 +115,4 @@ const editor = {
> 🤖 The selection concept is also borrowed from the DOM, see [`Selection`, MDN](https://developer.mozilla.org/en-US/docs/Web/API/Selection), although in a greatly-simplified form because Slate doesn't allow for multiple ranges inside a single selection, which makes things a lot easier to work with.
There isn't a special `Selection` interface, it's just an object that happens to respect the more general-purpose `Range` interface instead.
There isn't a special `Selection` interface. It's just an object that happens to respect the more general-purpose `Range` interface instead.

View File

@@ -1,6 +1,6 @@
# Commands
While editing richtext content, your users will be doing things like inserting text, deleteing text, splitting paragraphs, adding formatting, etc. These edits are expressed using two concepts: commands and operations.
While editing richtext content, your users will be doing things like inserting text, deleting text, splitting paragraphs, adding formatting, etc. These edits are expressed using two concepts: commands and operations.
Commands are the high-level actions that represent a specific intent of the user. They are represented as helper functions on the `Editor` interface. A handful of helpers are included in core for common richtext behaviors, but you are encouraged to write your own that model your specific domain.
@@ -16,9 +16,9 @@ Editor.insertBreak(editor)
But you can (and will!) also define your own custom commands that model your domain. For example, you might want to define a `formatQuote` command, or an `insertImage` command, or a `toggleBold` command depending on what types of content you allow.
Commands always describe an action to be taken as if the **user** themselves was performing the action. For that reason, they never need to define a location to perform the command, because they always act on the user's current selection.
Commands always describe an action to be taken as if the **user** was performing the action. For that reason, they never need to define a location to perform the command, because they always act on the user's current selection.
> 🤖 The concept of commands are loosely based on the DOM's built-in [`execCommand`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) APIs. However Slate defines its own simpler (and extendable!) version of the API, because the DOM's version is too opinionated and inconsistent.
> 🤖 The concept of commands is loosely based on the DOM's built-in [`execCommand`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) APIs. However Slate defines its own simpler (and extendable!) version of the API, because the DOM's version is too opinionated and inconsistent.
Under the covers, Slate takes care of converting each command into a set of low-level "operations" that are applied to produce a new value. This is what makes collaborative editing implementations possible. But you don't have to worry about that, because it happens automatically.

View File

@@ -33,4 +33,4 @@ editor.apply({
Under the covers Slate converts complex commands into the low-level operations and applies them to the editor automatically, so you rarely have to think about them.
> 🤖 Slate's editing behaviors being defined as operations is what makes things like collaborative editing possible, because each change is easily define-able, apply-able, compose-able and event undo-able!
> 🤖 Slate's editing behaviors being defined as operations is what makes things like collaborative editing possible, because each change is easily define-able, apply-able, compose-able and even undo-able!

View File

@@ -30,7 +30,7 @@ interface Editor {
}
```
Slightly more complex than the others, because it contains all of the top-level functions that define your custom, domain-specific behaviors.
It is slightly more complex than the others, because it contains all of the top-level functions that define your custom, domain-specific behaviors.
The `children` property contains the document tree of nodes that make up the editor's content.
@@ -42,9 +42,9 @@ The `marks` property stores formatting that is attached to the cursor, and that
## Overriding Behaviors
In previous guides we've already hinted at this, but you can override any of the behaviors of an editor by overriding it's function properties.
In previous guides we've already hinted at this, but you can override any of the behaviors of an editor by overriding its function properties.
For example, if you want define link elements that are inline nodes:
For example, if you want to define link elements that are inline nodes:
```js
const { isInline } = editor
@@ -86,7 +86,7 @@ editor.normalizeNode = entry => {
}
```
Whenever you override behaviors, be sure to call in to the existing functions as a fallback mechanism for the default behavior. Unless you really do want to completely remove the default behaviors (which is rarely a good idea).
Whenever you override behaviors, be sure to call the existing functions as a fallback mechanism for the default behavior. Unless you really do want to completely remove the default behaviors (which is rarely a good idea).
## Helper Functions

View File

@@ -1,6 +1,6 @@
# Plugins
You've already seen how the behaviors of Slate editors can be overriden. These overrides can also be packaged up into "plugins" to be reused, tested and shared. This is one of the most powerful aspects of Slate's architecture.
You've already seen how the behaviors of Slate editors can be overridden. These overrides can also be packaged up into "plugins" to be reused, tested and shared. This is one of the most powerful aspects of Slate's architecture.
A plugin is simply a function that takes an `Editor` object and returns it after it has augmented it in some way.

View File

@@ -76,7 +76,7 @@ const renderLeaf = useCallback(({ attributes, children, leaf }) => {
}, [])
```
Notice though how we've handled it slightly differently than `renderElement`. Since text formatting texts to be fairly simple, we've opted to ditch the `switch` statement and just toggle on/off a few styles instead. (But there's nothing preventing you from using custom components if you'd like!)
Notice though how we've handled it slightly differently than `renderElement`. Since text formatting tends to be fairly simple, we've opted to ditch the `switch` statement and just toggle on/off a few styles instead. (But there's nothing preventing you from using custom components if you'd like!)
One disadvantage of text-level formatting is that you cannot guarantee that any given format is "contiguous"—meaning that it stays as a single leaf. This limitation with respect to leaves is similar to the DOM, where this is invalid:

View File

@@ -119,7 +119,7 @@ It's really that easy!
## Deserializing
Another common use case in Slate is doing the reverse—deserializing. This is when you have some arbitrary input and want to convert it into a Slate-compabitable JSON structure. For example, when someone pastes HTML into your editor and you want to ensure it gets parsed with the proper formatting for your editor.
Another common use case in Slate is doing the reverse—deserializing. This is when you have some arbitrary input and want to convert it into a Slate-compatible JSON structure. For example, when someone pastes HTML into your editor and you want to ensure it gets parsed with the proper formatting for your editor.
Slate has a built-in helper for this: the `slate-hyperscript` package.

View File

@@ -1,6 +1,6 @@
# Normalizing
Slate editors can edit complex, nested data structures. And for the most part this is great, but in certain cases inconsistencies in the data structure can be introduced—most often when allowing a user to paste arbitrary richtext content.
Slate editors can edit complex, nested data structures. And for the most part this is great. But in certain cases inconsistencies in the data structure can be introduced—most often when allowing a user to paste arbitrary richtext content.
"Normalizing" is how you can ensure that your editor's content is always of a certain shape. It's similar to "validating", except instead of just determining whether the content is valid or invalid, its job is to fix the content to make it valid again.
@@ -37,7 +37,7 @@ const withParagraphs = editor => {
editor.normalizeNode = entry => {
const [node, path] = entry
// If the element is a paragraph, ensure it's children are valid.
// If the element is a paragraph, ensure its children are valid.
if (Element.isElement(node) && node.type === 'paragraph') {
for (const [child, childPath] of Node.children(editor, path)) {
if (Element.isElement(child) && !editor.isInline(child)) {
@@ -92,7 +92,7 @@ To see how this works in practice, let's start with this invalid document:
</editor>
```
The editor starts by running `normalizeNode` on `<paragraph c>`. And it is valid, because contains only text nodes as children.
The editor starts by running `normalizeNode` on `<paragraph c>`. And it is valid, because it contains only text nodes as children.
But then, it moves up the tree, and runs `normalizeNode` on `<paragraph b>`. This paragraph is invalid, since it contains a block element (`<paragraph c>`). So that child block gets unwrapped, resulting in a new document of:
@@ -118,7 +118,7 @@ And now when `normalizeNode` runs, no changes are made, so the document is valid
## Incorrect Fixes
The one pitfall to avoid however it creating an infinite normalization loop. This can happen if you check for a specific invalid structure, but then **don't** actually fix that structure with the change you make to the node. Resulting in an infinite loop because the node continues to be flagged as invalid, but never fixed properly.
The one pitfall to avoid however is creating an infinite normalization loop. This can happen if you check for a specific invalid structure, but then **don't** actually fix that structure with the change you make to the node. This results in an infinite loop because the node continues to be flagged as invalid, but it is never fixed properly.
For example, consider a normalization that ensured `link` elements have a valid `url` property:
@@ -135,6 +135,7 @@ const withLinks = editor => {
node.type === 'link' &&
typeof node.url !== 'string'
) {
// ERROR: null is not a valid value for a url
Transforms.setNodes(editor, { url: null }, { at: path })
return
}

View File

@@ -26,13 +26,13 @@ The codebase now uses TypeScript. Working with pure JSON as a data model, and us
### Fewer Concepts
The number of interfaces and commands has been reduced. Previously `Selection`, `Annotation`, `Decoration` used to all be separate classes. Now they are simply objects that implement the `Range` interface. Previously `Block` and `Inline` were separate, now they are objects that implement the `Element` interface. Previously there was a `Document` and `Value`, but now the top-level `Editor` contains the children nodes of the document itself.
The number of interfaces and commands has been reduced. Previously `Selection`, `Annotation`, and `Decoration` used to all be separate classes. Now they are simply objects that implement the `Range` interface. Previously `Block` and `Inline` were separate; now they are objects that implement the `Element` interface. Previously there was a `Document` and `Value`, but now the top-level `Editor` contains the children nodes of the document itself.
The number of commands has been reduced too. Previously we had commands for every type of input, like `insertText`, `insertTextAtRange`, `insertTextAtPath`. These have been merged into a smaller set of more customizable commands, eg. `insertText` which can take `at: Path | Range | Point`.
### Fewer Packages
In attempt to decrease the maintenance burden, and because the new abstraction and APIs in Slate's core packages make things much easier, the total number of packages has been reduced. Things like `slate-plain-serializer`, `slate-base64-serializer`, etc. have been removed and can be implemented in userland easily if needed. Even the `slate-html-deserializer` can now be implemented in userland (in ~10 LOC leveraging `slate-hyperscript`). And internal packages like `slate-dev-environment`, `slate-dev-test-utils`, etc. are no longer exposed because they are implementation details.
In an attempt to decrease the maintenance burden, and because the new abstraction and APIs in Slate's core packages make things much easier, the total number of packages has been reduced. Things like `slate-plain-serializer`, `slate-base64-serializer`, etc. have been removed and can be implemented in userland easily if needed. Even the `slate-html-deserializer` can now be implemented in userland (in ~10 LOC leveraging `slate-hyperscript`). And internal packages like `slate-dev-environment`, `slate-dev-test-utils`, etc. are no longer exposed because they are implementation details.
### Commands
@@ -42,7 +42,7 @@ Commands are triggered by calling the `editor.*` core functions. And they travel
### Plugins
Plugins are now plain functions that augment the `Editor` object they receive and return it again. For example can augment the command execution by composing the `editor.exec` function. Or listen to operations by composing `editor.apply`. Previously they relied on a custom middleware stack, and they were just bags of handlers that got merged onto an editor. Now we're using plain old function composition (aka wrapping) instead.
Plugins are now plain functions that augment the `Editor` object they receive and return it again. For example, they can augment the command execution by composing the `editor.exec` function or listen to operations by composing `editor.apply`. Previously they relied on a custom middleware stack, and they were just bags of handlers that got merged onto an editor. Now we're using plain old function composition (aka wrapping) instead.
### Elements
@@ -50,7 +50,7 @@ Block-ness and inline-ness is now a runtime choice. Previously it was baked into
### More React-ish
Rendering and event-handling is no longer a plugin's concern. Previously plugins had full control over the rendering logic, and event-handling logic in the editor. This creates a bad incentive to start putting **all** rendering logic in plugins, which puts Slate in a position of being a wrapper around all of React, which is very hard to do well. Instead, the new architecture has plugins focused purely on the richtext aspects, and leaves the rendering and event handling aspects to React.
Rendering and event-handling are no longer a plugin's concern. Previously plugins had full control over the rendering and event-handling logic in the editor. This creates a bad incentive to start putting **all** rendering logic in plugins, which puts Slate in a position of being a wrapper around all of React, which is very hard to do well. Instead, the new architecture has plugins focused purely on the richtext aspects, and leaves the rendering and event handling aspects to React.
### Context
@@ -62,7 +62,7 @@ In addition to the `useSlate` hook, there are a handful of other hooks. For exam
### `beforeinput`
We now use the `beforeinput` event almost exclusively. Instead of having relying on a series of shims and the quirks of React synthetic events, we're now using the standardized `beforeinput` event as our baseline. It is fully supported in Safari and Chrome, will soon be supported in the new Chromium-based Edge, and is currently being worked on in Firefox. In the meantime there are a few patches to make Firefox work. Internet Explorer is no longer supported in core out of the box.
We now use the `beforeinput` event almost exclusively. Instead of relying on a series of shims and the quirks of React synthetic events, we're now using the standardized `beforeinput` event as our baseline. It is fully supported in Safari and Chrome, will soon be supported in the new Chromium-based Edge, and is currently being worked on in Firefox. In the meantime there are a few patches to make Firefox work. Internet Explorer is no longer supported in core out of the box.
### History-less
@@ -70,11 +70,11 @@ The core history logic has now finally been extracted into a standalone plugin.
### Mark-less
Marks have been removed the Slate data model. Now that we have the ability to define custom properties right on the nodes themselves, you can model marks as custom properties of text nodes. For example bold can be modelled simply as a `bold: true` property.
Marks have been removed from the Slate data model. Now that we have the ability to define custom properties right on the nodes themselves, you can model marks as custom properties of text nodes. For example bold can be modelled simply as a `bold: true` property.
### Annotation-less
Similarly, annotations have been removed from Slate's core. They can be fully implemented now in userland by defining custom operations and rendering annotated ranges using decorations. But most cases should be using custom text node properties or decorations anyways. There were not that many use cases that benefitted from annotations.
Similarly, annotations have been removed from Slate's core. They can be fully implemented now in userland by defining custom operations and rendering annotated ranges using decorations. But most cases should be using custom text node properties or decorations anyways. There were not that many use cases that benefited from annotations.
## Reductions