mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-09-01 19:22:35 +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:
13
packages/slate-history/Changelog.md
Normal file
13
packages/slate-history/Changelog.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
A list of changes to the `slate-history` 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.50.0` — November 27, 2019
|
||||
|
||||
###### BREAKING
|
||||
|
||||
**A complete overhaul.** The Slate codebase has had a complete overhaul and many pieces of its core architecture have been reconsidered from the ground up. There are lots of changes. We recommend re-reading the [Walkthroughs](https://docs.slatejs.org/walkthroughs) and [Concepts](https://docs.slatejs.org/concepts) documentation and the [Examples](../../site/examples) to get a sense for everything that has changed. As well as the [Migration](https://docs.slatejs.org/concepts/XX-migrating) writeup for what the major changes are.
|
||||
|
||||
---
|
1
packages/slate-history/Readme.md
Normal file
1
packages/slate-history/Readme.md
Normal file
@@ -0,0 +1 @@
|
||||
This package contains the core logic of Slate. Feel free to poke around to learn more!
|
41
packages/slate-history/package.json
Normal file
41
packages/slate-history/package.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "slate-history",
|
||||
"type": "module",
|
||||
"description": "An operation-based history implementation for Slate editors.",
|
||||
"version": "0.47.8",
|
||||
"license": "MIT",
|
||||
"repository": "git://github.com/ianstormtaylor/slate.git",
|
||||
"main": "lib/index.js",
|
||||
"module": "lib/index.es.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"umd": "dist/slate-history.js",
|
||||
"umdMin": "dist/slate-history.min.js",
|
||||
"files": [
|
||||
"dist/",
|
||||
"lib/"
|
||||
],
|
||||
"dependencies": {
|
||||
"immer": "^5.0.0",
|
||||
"is-plain-object": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"slate": "^0.47.8",
|
||||
"slate-hyperscript": "^0.13.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"slate": ">=0.50.0"
|
||||
},
|
||||
"umdGlobals": {
|
||||
"slate": "Slate"
|
||||
},
|
||||
"keywords": [
|
||||
"editor",
|
||||
"history",
|
||||
"operation",
|
||||
"redo",
|
||||
"save",
|
||||
"slate",
|
||||
"stack",
|
||||
"undo"
|
||||
]
|
||||
}
|
39
packages/slate-history/src/history-command.ts
Normal file
39
packages/slate-history/src/history-command.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Command } from 'slate'
|
||||
|
||||
export interface RedoCommand {
|
||||
type: 'redo'
|
||||
}
|
||||
|
||||
export interface UndoCommand {
|
||||
type: 'undo'
|
||||
}
|
||||
|
||||
export type HistoryCommand = RedoCommand | UndoCommand
|
||||
|
||||
export const HistoryCommand = {
|
||||
/**
|
||||
* Check if a value is a `HistoryCommand` object.
|
||||
*/
|
||||
|
||||
isHistoryCommand(value: any): value is HistoryCommand {
|
||||
return (
|
||||
HistoryCommand.isRedoCommand(value) || HistoryCommand.isUndoCommand(value)
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if a value is a `RedoCommand` object.
|
||||
*/
|
||||
|
||||
isRedoCommand(value: any): value is RedoCommand {
|
||||
return Command.isCommand(value) && value.type === 'redo'
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if a value is an `UndoCommand` object.
|
||||
*/
|
||||
|
||||
isUndoCommand(value: any): value is UndoCommand {
|
||||
return Command.isCommand(value) && value.type === 'undo'
|
||||
},
|
||||
}
|
68
packages/slate-history/src/history-editor.ts
Normal file
68
packages/slate-history/src/history-editor.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Editor } from 'slate'
|
||||
import { History } from './history'
|
||||
|
||||
/**
|
||||
* Weakmaps for attaching state to the editor.
|
||||
*/
|
||||
|
||||
export const HISTORY = new WeakMap<Editor, History>()
|
||||
export const SAVING = new WeakMap<Editor, boolean | undefined>()
|
||||
export const MERGING = new WeakMap<Editor, boolean | undefined>()
|
||||
|
||||
/**
|
||||
* `HistoryEditor` contains helpers for history-enabled editors.
|
||||
*/
|
||||
|
||||
export interface HistoryEditor extends Editor {
|
||||
history: History
|
||||
}
|
||||
|
||||
export const HistoryEditor = {
|
||||
/**
|
||||
* Check if a value is a `HistoryEditor` object.
|
||||
*/
|
||||
|
||||
isHistoryEditor(value: any): value is HistoryEditor {
|
||||
return Editor.isEditor(value) && History.isHistory(value.history)
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the merge flag's current value.
|
||||
*/
|
||||
|
||||
isMerging(editor: Editor): boolean | undefined {
|
||||
return MERGING.get(editor)
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the saving flag's current value.
|
||||
*/
|
||||
|
||||
isSaving(editor: Editor): boolean | undefined {
|
||||
return SAVING.get(editor)
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply a series of changes inside a synchronous `fn`, without merging any of
|
||||
* the new operations into previous save point in the history.
|
||||
*/
|
||||
|
||||
withoutMerging(editor: Editor, fn: () => void): void {
|
||||
const prev = HistoryEditor.isMerging(editor)
|
||||
MERGING.set(editor, false)
|
||||
fn()
|
||||
MERGING.set(editor, prev)
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply a series of changes inside a synchronous `fn`, without saving any of
|
||||
* their operations into the history.
|
||||
*/
|
||||
|
||||
withoutSaving(editor: Editor, fn: () => void): void {
|
||||
const prev = HistoryEditor.isSaving(editor)
|
||||
SAVING.set(editor, false)
|
||||
fn()
|
||||
SAVING.set(editor, prev)
|
||||
},
|
||||
}
|
28
packages/slate-history/src/history.ts
Normal file
28
packages/slate-history/src/history.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import { Operation } from 'slate'
|
||||
|
||||
/**
|
||||
* `History` objects hold all of the operations that are applied to a value, so
|
||||
* they can be undone or redone as necessary.
|
||||
*/
|
||||
|
||||
export interface History {
|
||||
redos: Operation[][]
|
||||
undos: Operation[][]
|
||||
}
|
||||
|
||||
export const History = {
|
||||
/**
|
||||
* Check if a value is a `History` object.
|
||||
*/
|
||||
|
||||
isHistory(value: any): value is History {
|
||||
return (
|
||||
isPlainObject(value) &&
|
||||
Array.isArray(value.redos) &&
|
||||
Array.isArray(value.undos) &&
|
||||
(value.redos.length === 0 || Operation.isOperationList(value.redos[0])) &&
|
||||
(value.undos.length === 0 || Operation.isOperationList(value.undos[0]))
|
||||
)
|
||||
},
|
||||
}
|
4
packages/slate-history/src/index.ts
Normal file
4
packages/slate-history/src/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './history'
|
||||
export * from './history-command'
|
||||
export * from './history-editor'
|
||||
export * from './with-history'
|
174
packages/slate-history/src/with-history.ts
Normal file
174
packages/slate-history/src/with-history.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
import { Editor, Command, Operation, Path } from 'slate'
|
||||
|
||||
import { HistoryCommand } from './history-command'
|
||||
import { HistoryEditor } from './history-editor'
|
||||
|
||||
/**
|
||||
* The `withHistory` plugin keeps track of the operation history of a Slate
|
||||
* editor as operations are applied to it, using undo and redo stacks.
|
||||
*/
|
||||
|
||||
export const withHistory = (editor: Editor): Editor => {
|
||||
const { apply, exec } = editor
|
||||
editor.history = { undos: [], redos: [] }
|
||||
|
||||
editor.exec = (command: Command) => {
|
||||
if (HistoryEditor.isHistoryEditor(editor)) {
|
||||
const { history } = editor
|
||||
const { undos, redos } = history
|
||||
|
||||
if (redos.length > 0 && HistoryCommand.isRedoCommand(command)) {
|
||||
const batch = redos[redos.length - 1]
|
||||
|
||||
HistoryEditor.withoutSaving(editor, () => {
|
||||
Editor.withoutNormalizing(editor, () => {
|
||||
for (const op of batch) {
|
||||
editor.apply(op)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
history.redos.pop()
|
||||
history.undos.push(batch)
|
||||
return
|
||||
}
|
||||
|
||||
if (undos.length > 0 && HistoryCommand.isUndoCommand(command)) {
|
||||
const batch = undos[undos.length - 1]
|
||||
|
||||
HistoryEditor.withoutSaving(editor, () => {
|
||||
Editor.withoutNormalizing(editor, () => {
|
||||
const inverseOps = batch.map(Operation.inverse).reverse()
|
||||
|
||||
for (const op of inverseOps) {
|
||||
// If the final operation is deselecting the editor, skip it. This is
|
||||
if (
|
||||
op === inverseOps[inverseOps.length - 1] &&
|
||||
op.type === 'set_selection' &&
|
||||
op.newProperties == null
|
||||
) {
|
||||
continue
|
||||
} else {
|
||||
editor.apply(op)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
history.redos.push(batch)
|
||||
history.undos.pop()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
exec(command)
|
||||
}
|
||||
|
||||
editor.apply = (op: Operation) => {
|
||||
if (HistoryEditor.isHistoryEditor(editor)) {
|
||||
const { operations, history } = editor
|
||||
const { undos } = history
|
||||
const lastBatch = undos[undos.length - 1]
|
||||
const lastOp = lastBatch && lastBatch[lastBatch.length - 1]
|
||||
const overwrite = shouldOverwrite(op, lastOp)
|
||||
let save = HistoryEditor.isSaving(editor)
|
||||
let merge = HistoryEditor.isMerging(editor)
|
||||
|
||||
if (save == null) {
|
||||
save = shouldSave(op, lastOp)
|
||||
}
|
||||
|
||||
if (save) {
|
||||
if (merge == null) {
|
||||
if (lastBatch == null) {
|
||||
merge = false
|
||||
} else if (operations.length !== 0) {
|
||||
merge = true
|
||||
} else {
|
||||
merge = shouldMerge(op, lastOp) || overwrite
|
||||
}
|
||||
}
|
||||
|
||||
if (lastBatch && merge) {
|
||||
if (overwrite) {
|
||||
lastBatch.pop()
|
||||
}
|
||||
|
||||
lastBatch.push(op)
|
||||
} else {
|
||||
const batch = [op]
|
||||
undos.push(batch)
|
||||
}
|
||||
|
||||
while (undos.length > 100) {
|
||||
undos.shift()
|
||||
}
|
||||
|
||||
history.redos = []
|
||||
}
|
||||
}
|
||||
|
||||
apply(op)
|
||||
}
|
||||
|
||||
return editor
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether to merge an operation into the previous operation.
|
||||
*/
|
||||
|
||||
const shouldMerge = (op: Operation, prev: Operation | undefined): boolean => {
|
||||
if (op.type === 'set_selection') {
|
||||
return true
|
||||
}
|
||||
|
||||
if (
|
||||
prev &&
|
||||
op.type === 'insert_text' &&
|
||||
prev.type === 'insert_text' &&
|
||||
op.offset === prev.offset + prev.text.length &&
|
||||
Path.equals(op.path, prev.path)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (
|
||||
prev &&
|
||||
op.type === 'remove_text' &&
|
||||
prev.type === 'remove_text' &&
|
||||
op.offset + op.text.length === prev.offset &&
|
||||
Path.equals(op.path, prev.path)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an operation needs to be saved to the history.
|
||||
*/
|
||||
|
||||
const shouldSave = (op: Operation, prev: Operation | undefined): boolean => {
|
||||
if (op.type === 'set_selection' && op.newProperties == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an operation should overwrite the previous one.
|
||||
*/
|
||||
|
||||
const shouldOverwrite = (
|
||||
op: Operation,
|
||||
prev: Operation | undefined
|
||||
): boolean => {
|
||||
if (prev && op.type === 'set_selection' && prev.type === 'set_selection') {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
35
packages/slate-history/test/index.js
Normal file
35
packages/slate-history/test/index.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import assert from 'assert'
|
||||
import { fixtures } from '../../../support/fixtures'
|
||||
import { createHyperscript } from 'slate-hyperscript'
|
||||
import { withHistory } from '..'
|
||||
|
||||
describe('slate-history', () => {
|
||||
fixtures(__dirname, 'undo', ({ module }) => {
|
||||
const { input, run, output } = module
|
||||
const editor = withTest(withHistory(input))
|
||||
run(editor)
|
||||
editor.exec({ type: 'undo' })
|
||||
assert.deepEqual(editor.children, output.children)
|
||||
})
|
||||
})
|
||||
|
||||
export const jsx = createHyperscript({
|
||||
elements: {
|
||||
block: {},
|
||||
inline: { inline: true },
|
||||
},
|
||||
})
|
||||
|
||||
const withTest = editor => {
|
||||
const { isInline, isVoid } = editor
|
||||
|
||||
editor.isInline = element => {
|
||||
return element.inline === true ? true : isInline(element)
|
||||
}
|
||||
|
||||
editor.isVoid = element => {
|
||||
return element.void === true ? true : isVoid(element)
|
||||
}
|
||||
|
||||
return editor
|
||||
}
|
22
packages/slate-history/test/undo/add_mark/block-across.js
Normal file
22
packages/slate-history/test/undo/add_mark/block-across.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'add_mark', mark: { key: 'a' } })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
o<anchor />
|
||||
ne
|
||||
</block>
|
||||
<block>
|
||||
tw
|
||||
<focus />o
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
20
packages/slate-history/test/undo/add_mark/mark-across.js
Normal file
20
packages/slate-history/test/undo/add_mark/mark-across.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'add_mark', mark: { key: 'a' } })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<mark key="b">
|
||||
w<anchor />o
|
||||
</mark>
|
||||
r<focus />d
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
20
packages/slate-history/test/undo/add_mark/mark-from.js
Normal file
20
packages/slate-history/test/undo/add_mark/mark-from.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'add_mark', mark: { key: 'a' } })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<mark key="a">
|
||||
w<anchor />o
|
||||
</mark>
|
||||
r<focus />d
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
20
packages/slate-history/test/undo/add_mark/text.js
Normal file
20
packages/slate-history/test/undo/add_mark/text.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'add_mark', mark: { key: 'a' } })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<anchor />
|
||||
wo
|
||||
<focus />
|
||||
rd
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
@@ -0,0 +1,27 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'delete_backward' })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>Hello</block>
|
||||
<block>
|
||||
<cursor />
|
||||
world!
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = (
|
||||
<editor>
|
||||
<block>Hello</block>
|
||||
<block>
|
||||
<cursor />
|
||||
world!
|
||||
</block>
|
||||
</editor>
|
||||
)
|
@@ -0,0 +1,31 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'delete_backward' })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>Hello</block>
|
||||
<block>
|
||||
<block>
|
||||
<cursor />
|
||||
world!
|
||||
</block>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = (
|
||||
<editor>
|
||||
<block>Hello</block>
|
||||
<block>
|
||||
<block>
|
||||
<cursor />
|
||||
world!
|
||||
</block>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
@@ -0,0 +1,22 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.delete()
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
wo
|
||||
<cursor />
|
||||
rd
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
||||
|
||||
export const skip = true
|
@@ -0,0 +1,25 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.delete()
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block a>
|
||||
o<anchor />
|
||||
ne
|
||||
</block>
|
||||
<block b>
|
||||
tw
|
||||
<focus />o
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
||||
|
||||
export const skip = true
|
@@ -0,0 +1,33 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.delete()
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<text />
|
||||
<inline a>
|
||||
o<anchor />
|
||||
ne
|
||||
</inline>
|
||||
<text />
|
||||
</block>
|
||||
<block>
|
||||
<text />
|
||||
<inline b>
|
||||
tw
|
||||
<focus />o
|
||||
</inline>
|
||||
<text />
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
||||
|
||||
export const skip = true
|
@@ -0,0 +1,27 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.delete()
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<mark key="a">
|
||||
on
|
||||
<anchor />e
|
||||
</mark>
|
||||
<mark key="c">
|
||||
tw
|
||||
<focus />o
|
||||
</mark>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
||||
|
||||
export const skip = true
|
22
packages/slate-history/test/undo/insert_break/basic.js
Normal file
22
packages/slate-history/test/undo/insert_break/basic.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'insert_break' })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<block>
|
||||
on
|
||||
<cursor />e
|
||||
</block>
|
||||
<block>two</block>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
42
packages/slate-history/test/undo/insert_fragment/basic.js
Normal file
42
packages/slate-history/test/undo/insert_fragment/basic.js
Normal file
@@ -0,0 +1,42 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
const fragment = (
|
||||
<block type="d">
|
||||
<block>A</block>
|
||||
<block type="c">
|
||||
<block type="d">
|
||||
<block>B</block>
|
||||
<block>
|
||||
<block type="d">
|
||||
<block>C</block>
|
||||
</block>
|
||||
</block>
|
||||
</block>
|
||||
<block type="d">
|
||||
<block>D</block>
|
||||
</block>
|
||||
</block>
|
||||
</block>
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'insert_fragment', fragment })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block type="d">
|
||||
<block>
|
||||
<text>
|
||||
<cursor />
|
||||
</text>
|
||||
</block>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
||||
|
||||
export const skip = true
|
18
packages/slate-history/test/undo/insert_text/basic.js
Normal file
18
packages/slate-history/test/undo/insert_text/basic.js
Normal file
@@ -0,0 +1,18 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'insert_text', text: 'text' })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
one
|
||||
<cursor />
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
20
packages/slate-history/test/undo/insert_text/contiguous.js
Normal file
20
packages/slate-history/test/undo/insert_text/contiguous.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'insert_text', text: 't' })
|
||||
editor.exec({ type: 'insert_text', text: 'w' })
|
||||
editor.exec({ type: 'insert_text', text: 'o' })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
one
|
||||
<cursor />
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
@@ -0,0 +1,31 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'insert_text', text: 't' })
|
||||
// editor.move({ reverse: true })
|
||||
editor.exec({ type: 'insert_text', text: 'w' })
|
||||
// editor.move({ reverse: true })
|
||||
editor.exec({ type: 'insert_text', text: 'o' })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
one
|
||||
<cursor />
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = (
|
||||
<editor>
|
||||
<block>
|
||||
onew
|
||||
<cursor />t
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const skip = true
|
21
packages/slate-history/test/undo/remove_mark/basic.js
Normal file
21
packages/slate-history/test/undo/remove_mark/basic.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const run = editor => {
|
||||
editor.exec({ type: 'remove_mark', mark: { key: true } })
|
||||
}
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<mark key>
|
||||
<anchor />
|
||||
one
|
||||
<focus />
|
||||
</mark>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const output = input
|
10
packages/slate-history/tsconfig.json
Normal file
10
packages/slate-history/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../../config/typescript/tsconfig.json",
|
||||
"include": ["src/**/*"],
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"composite": true
|
||||
},
|
||||
"references": []
|
||||
}
|
Reference in New Issue
Block a user