mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-30 10:29:48 +02:00
Next (#3093)
* remove some key usage from core, refactor Operations.apply * undeprecate some methods * convert more key usage to paths * update deprecations * convert selection commands to use all paths * refactor word boundary selection logic * convert many at-range commands to use paths * convert wrapBlock and wrapInline to not use keys * cleanup * remove chainability from editor * simplify commands, queries and middleware * convert deleteAtRange * remove key usage from schema, deprecate *ByKey methods * migrate *ByKey tests, remove index from *ByPath signatures * rename at-current-range tests * deprecate mode key usage, migrate more tests away from keys * deprecate range and point methods which rely on keys to work * refactor insertBlock, without fixing warnings * add pathRef/pointRef, fix insertBlock/Inline deprecations, work on insertFragment * refactor insertFragment * get rich-text example rendering * fix lint * refactor query files, fix more tests * remove unused queries, refactor others * deprecate splitDescendantsByPath * merge master * add typescript, convert slate, slate-hyperscript, slate-plain-serializer * add Point, Path, Range, Annotation tests * add Annotation, Change, Element, Fragment, Mark, Range, Selection, Value interfaces tests * add Operation and Text tests * add Node tests * get operations and normalization tests working for slate * get *AtPath command tests passing * rename *AtPath command tests * rename * get *AtPoint tests working * rename * rename * add value queries tests * add element, mark and path queries tests * convert most on-selection tests * convert on-selection commands * rename * get addMarks and delete commands working * rename * rename * rename * refactor value.positions(), work on delete tests * progress on delete tests * more delete work * finish delete tests * start converting to at-based commands * restructure query tests * restructure operations tests * more work converting to multi-purpose commands * lots of progress on converting to at-based commands * add unwrapNodes * remove setValue * more progress * refactor node commands to use consistent matching logic * cleanup, get non-fragment commands passing * remove annotations and isAtomic * rename surround/pluck to cover/uncover * add location concept, change at-path to from-path for iterables * refactor batches * add location-based queries * refactor hanging logic * more location query work * renaming * use getMatch more * add split to wrap/unwrap * flip levels/ancestors ordering * switch splitNodes to use levels * change split to always:false by default * fix tests * add more queries tests * fixing more delete logic * add more splitNodes tests * get rest of delete tests passing * fix location-based logic in some commands * cleanup * get previous packages tests passing again * add slate-history package * start slate-schema work * start of react working * rendering fixes * get rich and plain text examples working * get image example working with hooks and dropping * refactor onDrop to be internal * inline more event handlers * refactor lots of event-related logic * change rendering to use render props * delete unused stuff * cleanup dom utils * remove unused deps * remove unnecessary packages, add placeholder * remove slate-react-placeholder package * remove unused dep * remove unnecessary tests, fix readonly example * convert checklists example * switch to next from webpack * get link example working * convert more examples * preserve keys, memoized leafs/texts, fix node lookup * fix to always useLayoutEffect for ordering * fix annotations to be maps, memoize elements * remove Change interface * remove String interface * rename Node.entries to Node.nodes * remove unnecessary value queries * default to selection when iterating, cleanup * remove unused files * update scroll into view logic * fix undoing, remove constructor types * dont sync selection while composing * add workflows * remove unused deps * convert mentions example * tweaks * convert remaining examples * rename h to jsx, update schema * fix schema tests * fix slate-schema logic and tests * really fix slate-schema and forced-layout example * get start of insertFragment tests working * remove Fragment interface * remove debugger * get all non-skipped tests passing * cleanup deps * run prettier * configure eslint for typescript * more eslint fixes... * more passing * update some docs * fix examples * port windows undo hotkey change * fix deps, add basic firefox support * add event overriding, update walkthroughs * add commands, remove classes, cleanup examples * cleanup rollup config * update tests * rename queries tests * update other tests * update walkthroughs * cleanup interface exports * cleanup, change mark transforms to require location * undo mark transform change * more * fix tests * fix example * update walkthroughs * update docs * update docs * remove annotations * remove value, move selection and children to editor * add migrating doc * fix lint * fix tests * fix DOM types aliasing * add next export * update deps, fix prod build * fix prod build * update scripts * update docs and changelogs * update workflow and pull request template
This commit is contained in:
117
docs/concepts/07-editor.md
Normal file
117
docs/concepts/07-editor.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Editor
|
||||
|
||||
All of the behaviors, content and state of a Slate editor is rollup up into a single, top-level `Editor` object. It has an interface of:
|
||||
|
||||
```ts
|
||||
interface Editor {
|
||||
apply: (operation: Operation) => void
|
||||
exec: (command: Command) => void
|
||||
isInline: (element: Element) => boolean
|
||||
isVoid: (element: Element) => boolean
|
||||
normalizeNode: (entry: NodeEntry) => void
|
||||
onChange: (children: Node[], operations: Operation[]) => void
|
||||
children: Node[]
|
||||
operations: Operation[]
|
||||
selection: Range | null
|
||||
[key: string]: any
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
The `selection` property contains the user's current selection, if any.
|
||||
|
||||
And the `operations` property contains all of the operations that have been applied since the last "change" was flushed. (Since Slate batches operations up into ticks of the event loop.)
|
||||
|
||||
## Overriding Behaviors
|
||||
|
||||
In previous guides we've already hinted at this, but you can overriding any of the behaviors of an editor by overriding it's function properties.
|
||||
|
||||
For example, if you want define link elements that are inline nodes:
|
||||
|
||||
```js
|
||||
const { isInline } = editor
|
||||
|
||||
editor.isInline = element => {
|
||||
return element.type === 'link' ? true : isInline(element)
|
||||
}
|
||||
```
|
||||
|
||||
Or maybe you want to define a custom command:
|
||||
|
||||
```js
|
||||
const { exec } = editor
|
||||
|
||||
editor.exec = command => {
|
||||
if (command.type === 'insert_link') {
|
||||
const { url } = command
|
||||
// ...
|
||||
} else {
|
||||
exec(command)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or you can even define custom "normalizations" that take place to ensure that links obey certain constraints:
|
||||
|
||||
```js
|
||||
const { normalizeNode } = editor
|
||||
|
||||
editor.normalizeNode = entry => {
|
||||
const [node, path] = entry
|
||||
|
||||
if (Element.isElement(node) && node.type === 'link') {
|
||||
// ...
|
||||
}
|
||||
|
||||
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).
|
||||
|
||||
## Helper Functions
|
||||
|
||||
The `Editor` interface, like all Slate interfaces, exposes helper functions that are useful when implementing certain behaviors. There are many, many editor-related helpers. For example:
|
||||
|
||||
```js
|
||||
// Get the start point of a specific node at path.
|
||||
const point = Editor.start(editor, [0, 0])
|
||||
|
||||
// Check whether an element matches a set of properties.
|
||||
const isMatch = Editor.isMatch(editor, element, { type: 'quote' })
|
||||
|
||||
// Get the fragment (a slice of the document) at a range.
|
||||
const fragment = Editor.fragment(editor, range)
|
||||
```
|
||||
|
||||
There are also many iterator-based helpers, for example:
|
||||
|
||||
```js
|
||||
// Iterate over every element in a range.
|
||||
for (const [element, path] of Editor.elements(editor, { at: range })) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Iterate over every mark in every text node in the current selection.
|
||||
for (const [mark, index, text, path] of Editor.marks(editor)) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Another special group of helper functions exposed on the `Editor` interface are the "transform" helpers. They are the lower-level functions that commands use to define their behaviors. For example:
|
||||
|
||||
```js
|
||||
// Insert an element node at a specific path.
|
||||
Editor.insertNodes(editor, [element], { at: path })
|
||||
|
||||
// Split the nodes in half at a specific point.
|
||||
Editor.splitNodes(editor, { at: point })
|
||||
|
||||
// Add a mark to all the text in a range.
|
||||
Editor.addMarks(editor, [mark], { at: range })
|
||||
```
|
||||
|
||||
The editor-specific helpers are the ones you'll use most often when working with Slate editors, so it pays to become very familiar with them.
|
Reference in New Issue
Block a user