1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-31 19:01:54 +02:00

Add controller (#2221)

* fold Stack into Editor

* switch Change objects to be tied to editors, not values

* introduce controller

* add the "commands" concept

* convert history into commands on `value.data`

* add the ability to not normalize on editor creation/setting

* convert schema to a mutable constructor

* add editor.command method

* convert plugin handlers to receive `next`

* switch commands to use the onCommand middleware

* add queries support, convert schema to queries

* split out browser plugin

* remove noop util

* fixes

* fixes

* start fixing tests, refactor hyperscript to be more literal

* fix slate-html-serializer tests

* fix schema tests with hyperscript

* fix text model tests with hyperscript

* fix more tests

* get all tests passing

* fix lint

* undo decorations example update

* update examples

* small changes to the api to make it nicer

* update docs

* update commands/queries plugin logic

* change normalizeNode and validateNode to be middleware

* fix decoration removal

* rename commands tests

* add useful errors to existing APIs

* update changelogs

* cleanup

* fixes

* update docs

* add editor docs
This commit is contained in:
Ian Storm Taylor
2018-10-09 14:03:27 -07:00
committed by GitHub
parent e6372d829a
commit 7a71de387c
709 changed files with 6073 additions and 5927 deletions

View File

@@ -41,8 +41,9 @@ class App extends React.Component {
}
// Define a new handler which prints the key that was pressed.
onKeyDown = (event, change) => {
onKeyDown = (event, change, next) => {
console.log(event.key)
return next()
}
render() {
@@ -73,9 +74,9 @@ class App extends React.Component {
this.setState({ value })
}
onKeyDown = (event, change) => {
onKeyDown = (event, change, next) => {
// Return with no changes if the keypress is not '&'
if (event.key !== '&') return
if (event.key !== '&') return next()
// Prevent the ampersand character from being inserted.
event.preventDefault()

View File

@@ -20,8 +20,8 @@ class App extends React.Component {
this.setState({ value })
}
onKeyDown = (event, change) => {
if (event.key != '`' || !event.ctrlKey) return
onKeyDown = (event, change, next) => {
if (event.key != '`' || !event.ctrlKey) return next()
event.preventDefault()
const isCode = change.value.blocks.some(block => block.type == 'code')
@@ -40,10 +40,12 @@ class App extends React.Component {
)
}
renderNode = props => {
renderNode = (props, next) => {
switch (props.node.type) {
case 'code':
return <CodeNode {...props} />
default:
return next()
}
}
}
@@ -61,8 +63,8 @@ class App extends React.Component {
this.setState({ value })
}
onKeyDown = (event, change) => {
if (!event.ctrlKey) return
onKeyDown = (event, change, next) => {
if (!event.ctrlKey) return next()
// Decide what to do based on the key code...
switch (event.key) {
@@ -79,6 +81,10 @@ class App extends React.Component {
change.setBlocks(isCode ? 'paragraph' : 'code')
return true
}
// Otherwise, let other plugins handle it.
default: {
return next()
}
}
}
@@ -93,10 +99,12 @@ class App extends React.Component {
)
}
renderNode = props => {
renderNode = (props, next) => {
switch (props.node.type) {
case 'code':
return <CodeNode {...props} />
default:
return next()
}
}
}
@@ -131,8 +139,8 @@ class App extends React.Component {
this.setState({ value })
}
onKeyDown = (event, change) => {
if (!event.ctrlKey) return
onKeyDown = (event, change, next) => {
if (!event.ctrlKey) return next()
switch (event.key) {
case 'b': {
@@ -146,6 +154,9 @@ class App extends React.Component {
change.setBlocks(isCode ? 'paragraph' : 'code')
return true
}
default: {
return next()
}
}
}
@@ -162,18 +173,22 @@ class App extends React.Component {
)
}
renderNode = props => {
renderNode = (props, next) => {
switch (props.node.type) {
case 'code':
return <CodeNode {...props} />
default:
return next()
}
}
// Add a `renderMark` method to render marks.
renderMark = props => {
renderMark = (props, next) => {
switch (props.mark.type) {
case 'bold':
return <BoldMark {...props} />
default:
return next()
}
}
}

View File

@@ -20,8 +20,8 @@ class App extends React.Component {
this.setState({ value })
}
onKeyDown = (event, change) => {
if (event.key != '&') return
onKeyDown = (event, change, next) => {
if (event.key != '&') return next()
event.preventDefault()
change.insertText('and')
return true
@@ -82,8 +82,8 @@ class App extends React.Component {
this.setState({ value })
}
onKeyDown = (event, change) => {
if (event.key != '&') return
onKeyDown = (event, change, next) => {
if (event.key != '&') return next()
event.preventDefault()
change.insertText('and')
return true
@@ -102,10 +102,12 @@ class App extends React.Component {
}
// Add a `renderNode` method to render a `CodeNode` for code blocks.
renderNode = props => {
renderNode = (props, next) => {
switch (props.node.type) {
case 'code':
return <CodeNode {...props} />
default:
return next()
}
}
}
@@ -131,9 +133,9 @@ class App extends React.Component {
this.setState({ value })
}
onKeyDown = (event, change) => {
onKeyDown = (event, change, next) => {
// Return with no changes if it's not the "`" key with ctrl pressed.
if (event.key != '`' || !event.ctrlKey) return
if (event.key != '`' || !event.ctrlKey) return next()
// Prevent the "`" from being inserted by default.
event.preventDefault()
@@ -154,10 +156,12 @@ class App extends React.Component {
)
}
renderNode = props => {
renderNode = (props, next) => {
switch (props.node.type) {
case 'code':
return <CodeNode {...props} />
default:
return next()
}
}
}
@@ -187,8 +191,8 @@ class App extends React.Component {
this.setState({ value })
}
onKeyDown = (event, change) => {
if (event.key != '`' || !event.ctrlKey) return
onKeyDown = (event, change, next) => {
if (event.key != '`' || !event.ctrlKey) return next()
event.preventDefault()
@@ -211,10 +215,12 @@ class App extends React.Component {
)
}
renderNode = props => {
renderNode = (props, next) => {
switch (props.node.type) {
case 'code':
return <CodeNode {...props} />
default:
return next()
}
}
}

View File

@@ -263,7 +263,7 @@ class App extends React.Component {
)
}
renderNode = props => {
renderNode = (props, next) => {
switch (props.node.type) {
case 'code':
return (
@@ -279,11 +279,13 @@ class App extends React.Component {
)
case 'quote':
return <blockquote {...props.attributes}>{props.children}</blockquote>
default:
return next()
}
}
// Add a `renderMark` method to render marks.
renderMark = props => {
renderMark = (props, next) => {
const { mark, attributes } = props
switch (mark.type) {
case 'bold':
@@ -292,6 +294,8 @@ class App extends React.Component {
return <em {...attributes}>{props.children}</em>
case 'underline':
return <u {...attributes}>{props.children}</u>
default:
return next()
}
}
}

View File

@@ -22,8 +22,8 @@ class App extends React.Component {
this.setState({ value })
}
onKeyDown = (event, change) => {
if (event.key != 'b' || !event.ctrlKey) return
onKeyDown = (event, change, next) => {
if (event.key != 'b' || !event.ctrlKey) return next()
event.preventDefault()
change.toggleMark('bold')
return true
@@ -40,10 +40,12 @@ class App extends React.Component {
)
}
renderMark = props => {
renderMark = (props, next) => {
switch (props.mark.type) {
case 'bold':
return <strong {...props.attributes}>{props.children}</strong>
default:
return next()
}
}
}
@@ -70,9 +72,9 @@ function MarkHotkey(options) {
// Return our "plugin" object, containing the `onKeyDown` handler.
return {
onKeyDown(event, change) {
// Check that the key pressed matches our `key` option.
if (!event.ctrlKey || event.key != key) return
onKeyDown(event, change, next) {
// If it doesn't match our `key`, let other plugins handle it.
if (!event.ctrlKey || event.key != key) return next()
// Prevent the default characters from being inserted.
event.preventDefault()
@@ -120,10 +122,12 @@ class App extends React.Component {
)
}
renderMark = props => {
renderMark = (props, next) => {
switch (props.mark.type) {
case 'bold':
return <strong>{props.children}</strong>
default:
return next()
}
}
}
@@ -163,7 +167,7 @@ class App extends React.Component {
)
}
renderMark = props => {
renderMark = (props, next) => {
switch (props.mark.type) {
case 'bold':
return <strong>{props.children}</strong>
@@ -176,6 +180,8 @@ class App extends React.Component {
return <del>{props.children}</del>
case 'underline':
return <u>{props.children}</u>
default:
return next()
}
}
}