add some more commands

This commit is contained in:
Philipp Kühn
2020-09-21 23:17:30 +02:00
parent 778e064979
commit 4da71ecfbb
27 changed files with 207 additions and 210 deletions

View File

@@ -21,19 +21,18 @@ import defaultPlugins from './plugins'
import * as commands from './commands'
import { deleteSelection } from 'prosemirror-commands'
// export type Command = (next: Function, editor: Editor) => (...args: any) => any
// export type Command = (...args: any) => ({ editor: Editor }) => boolean
export type Command = (props: {
editor: Editor
tr: Transaction
// TODO: find correct type
commands: any
state: EditorState
state: EditorState,
view: EditorView,
dispatch: () => any
}) => boolean
export interface CommandSpec {
[key: string]: Command
[key: string]: (...args: any[]) => Command
}
export interface Commands {}
@@ -126,13 +125,26 @@ export class Editor extends EventEmitter {
return (...args: any) => {
const { tr } = this.state
const callback = command(...args)({
const props = {
editor: this.proxy,
state: this.chainableEditorState(tr, this.state),
view: this.view,
dispatch: () => false,
tr,
})
}
Object.defineProperty(props, 'commands', {
get: function() {
return Object.fromEntries(Object
.entries(this.commands)
.map(([name, command]) => {
return [name, (...args) => command(...args)(props)]
}))
}.bind(this)
});
const callback = command(...args)(props)
this.view.dispatch(tr)

View File

@@ -4,15 +4,15 @@ export { deleteSelection } from './deleteSelection'
export { focus } from './focus'
export { insertHTML } from './insertHTML'
export { insertText } from './insertText'
// export { default as liftListItem } from './liftListItem'
// export { default as removeMark } from './removeMark'
// export { default as removeMarks } from './removeMarks'
// export { default as replaceWithNode } from './replaceWithNode'
// export { default as selectAll } from './selectAll'
// export { default as selectParentNode } from './selectParentNode'
export { liftListItem } from './liftListItem'
export { removeMark } from './removeMark'
export { removeMarks } from './removeMarks'
export { replaceWithNode } from './replaceWithNode'
export { selectAll } from './selectAll'
export { selectParentNode } from './selectParentNode'
export { setContent } from './setContent'
// export { default as sinkListItem } from './sinkListItem'
// export { default as splitListItem } from './splitListItem'
// export { default as toggleMark } from './toggleMark'
// export { default as toggleNode } from './toggleNode'
// export { default as updateMark } from './updateMark'
export { sinkListItem } from './sinkListItem'
export { splitListItem } from './splitListItem'
export { toggleMark } from './toggleMark'
export { toggleNode } from './toggleNode'
export { updateMark } from './updateMark'

View File

@@ -1,9 +1,9 @@
import { Editor } from '../Editor'
import { liftListItem } from 'prosemirror-schema-list'
import { Command } from '../Editor'
import { liftListItem as originalLiftListItem } from 'prosemirror-schema-list'
import { NodeType } from 'prosemirror-model'
import getNodeType from '../utils/getNodeType'
type LiftListItem = (typeOrName: string | NodeType) => Editor
type LiftListItem = (typeOrName: string | NodeType) => Command
declare module '../Editor' {
interface Editor {
@@ -11,10 +11,8 @@ declare module '../Editor' {
}
}
export default (next: Function, editor: Editor) => (typeOrName: string | NodeType) => {
const { view, state, schema } = editor
const type = getNodeType(typeOrName, schema)
export const liftListItem: LiftListItem = (typeOrName) => ({ state, dispatch }) => {
const type = getNodeType(typeOrName, state.schema)
liftListItem(type)(state, view.dispatch)
next()
return originalLiftListItem(type)(state, dispatch)
}

View File

@@ -1,9 +1,9 @@
import { Editor } from '../Editor'
import { Command } from '../Editor'
import { MarkType } from 'prosemirror-model'
import getMarkType from '../utils/getMarkType'
import getMarkRange from '../utils/getMarkRange'
type RemoveMarkCommand = (typeOrName: string | MarkType) => Editor
type RemoveMarkCommand = (typeOrName: string | MarkType) => Command
declare module '../Editor' {
interface Editor {
@@ -11,10 +11,9 @@ declare module '../Editor' {
}
}
export default (next: Function, editor: Editor) => (typeOrName: string | MarkType) => {
const { view, state, schema } = editor
const { tr, selection } = state
const type = getMarkType(typeOrName, schema)
export const removeMark: RemoveMarkCommand = (typeOrName) => ({ tr, state }) => {
const { selection } = tr
const type = getMarkType(typeOrName, state.schema)
let { from, to, $from, empty } = selection
if (empty) {
@@ -27,6 +26,6 @@ export default (next: Function, editor: Editor) => (typeOrName: string | MarkTyp
}
tr.removeMark(from, to, type)
view.dispatch(tr)
next()
return true
}

View File

@@ -1,6 +1,6 @@
import { Editor } from '../Editor'
import { Command } from '../Editor'
type RemoveMarksCommand = () => Editor
type RemoveMarksCommand = () => Command
declare module '../Editor' {
interface Editor {
@@ -8,23 +8,19 @@ declare module '../Editor' {
}
}
export default (next: Function, editor: Editor) => () => {
const { state, view, schema } = editor
const { selection, tr } = state
export const removeMarks: RemoveMarksCommand = () => ({ tr, state }) => {
const { selection } = tr
const { from, to, empty } = selection
let transaction = tr
if (empty) {
next()
return
return true
}
Object
.entries(schema.marks)
.entries(state.schema.marks)
.forEach(([name, mark]) => {
transaction.removeMark(from, to, mark)
tr.removeMark(from, to, mark)
})
view.dispatch(transaction)
next()
return true
}

View File

@@ -1,4 +1,4 @@
import { Editor } from '../Editor'
import { Command } from '../Editor'
import { NodeType } from 'prosemirror-model'
import getNodeType from '../utils/getNodeType'
@@ -11,7 +11,7 @@ type ReplaceWithNodeCommand = (
typeOrName: NodeType,
attrs: {},
range?: Range,
) => Editor
) => Command
declare module '../Editor' {
interface Editor {
@@ -19,17 +19,18 @@ declare module '../Editor' {
}
}
export default (next: Function, editor: Editor) => (typeOrName: NodeType, attrs: {}, range?: Range) => {
const { view, state, schema } = editor
const { $from, $to } = state.selection
const type = getNodeType(typeOrName, schema)
export const replaceWithNode: ReplaceWithNodeCommand = (typeOrName, attrs = {}, range) => ({ view, tr, state }) => {
const { $from, $to } = tr.selection
const type = getNodeType(typeOrName, state.schema)
const index = $from.index()
const from = range ? range.from : $from.pos
const to = range ? range.to : $to.pos
if ($from.parent.canReplaceWith(index, index, type)) {
view.dispatch(state.tr.replaceWith(from, to, type.create(attrs)))
if (!$from.parent.canReplaceWith(index, index, type)) {
return false
}
view.dispatch(tr.replaceWith(from, to, type.create(attrs)))
next()
return true
}

View File

@@ -1,7 +1,7 @@
import { Editor } from '../Editor'
import { selectAll } from 'prosemirror-commands'
import { Command } from '../Editor'
import { selectAll as originalSelectAll } from 'prosemirror-commands'
type SelectAllCommand = () => Editor
type SelectAllCommand = () => Command
declare module '../Editor' {
interface Editor {
@@ -9,7 +9,6 @@ declare module '../Editor' {
}
}
export default (next: Function, { state, view }: Editor) => () => {
selectAll(state, view.dispatch)
next()
export const selectAll: SelectAllCommand = () => ({ state, dispatch }) => {
return originalSelectAll(state, dispatch)
}

View File

@@ -1,7 +1,7 @@
import { Editor } from '../Editor'
import { selectParentNode } from 'prosemirror-commands'
import { Command } from '../Editor'
import { selectParentNode as originalSelectParentNode } from 'prosemirror-commands'
type SelectParentNodeCommand = () => Editor
type SelectParentNodeCommand = () => Command
declare module '../Editor' {
interface Editor {
@@ -9,7 +9,6 @@ declare module '../Editor' {
}
}
export default (next: Function, { state, view }: Editor) => () => {
selectParentNode(state, view.dispatch)
next()
export const selectParentNode: SelectParentNodeCommand = () => ({ state, dispatch }) => {
return originalSelectParentNode(state, dispatch)
}

View File

@@ -1,9 +1,9 @@
import { Editor } from '../Editor'
import { sinkListItem } from 'prosemirror-schema-list'
import { Command } from '../Editor'
import { sinkListItem as originalSinkListItem } from 'prosemirror-schema-list'
import { NodeType } from 'prosemirror-model'
import getNodeType from '../utils/getNodeType'
type SinkListItem = (typeOrName: string | NodeType) => Editor
type SinkListItem = (typeOrName: string | NodeType) => Command
declare module '../Editor' {
interface Editor {
@@ -11,10 +11,8 @@ declare module '../Editor' {
}
}
export default (next: Function, editor: Editor) => (typeOrName: string | NodeType) => {
const { view, state, schema } = editor
const type = getNodeType(typeOrName, schema)
export const sinkListItem: SinkListItem = (typeOrName) => ({ state, dispatch }) => {
const type = getNodeType(typeOrName, state.schema)
sinkListItem(type)(state, view.dispatch)
next()
return originalSinkListItem(type)(state, dispatch)
}

View File

@@ -1,9 +1,9 @@
import { Editor } from '../Editor'
import { splitListItem } from 'prosemirror-schema-list'
import { Command } from '../Editor'
import { splitListItem as originalSplitListItem } from 'prosemirror-schema-list'
import { NodeType } from 'prosemirror-model'
import getNodeType from '../utils/getNodeType'
type SplitListItem = (typeOrName: string | NodeType) => Editor
type SplitListItem = (typeOrName: string | NodeType) => Command
declare module '../Editor' {
interface Editor {
@@ -11,10 +11,8 @@ declare module '../Editor' {
}
}
export default (next: Function, editor: Editor) => (typeOrName: string | NodeType) => {
const { view, state, schema } = editor
const type = getNodeType(typeOrName, schema)
export const splitListItem: SplitListItem = (typeOrName) => ({ state, dispatch }) => {
const type = getNodeType(typeOrName, state.schema)
return splitListItem(type)(state, view.dispatch)
// next()
return originalSplitListItem(type)(state, dispatch)
}

View File

@@ -1,9 +1,9 @@
import { Editor } from '../Editor'
import { toggleMark } from 'prosemirror-commands'
import { Command } from '../Editor'
import { toggleMark as originalToggleMark } from 'prosemirror-commands'
import { MarkType } from 'prosemirror-model'
import getMarkType from '../utils/getMarkType'
type ToggleMarkCommand = (typeOrName: string | MarkType) => Editor
type ToggleMarkCommand = (typeOrName: string | MarkType) => Command
declare module '../Editor' {
interface Editor {
@@ -11,10 +11,8 @@ declare module '../Editor' {
}
}
export default (next: Function, editor: Editor) => (typeOrName: string | MarkType) => {
const { view, state, schema } = editor
const type = getMarkType(typeOrName, schema)
export const toggleMark: ToggleMarkCommand = (typeOrName) => ({ state, dispatch }) => {
const type = getMarkType(typeOrName, state.schema)
toggleMark(type)(state, view.dispatch)
next()
return originalToggleMark(type)(state, dispatch)
}

View File

@@ -1,6 +1,6 @@
import { NodeType } from 'prosemirror-model'
import { setBlockType } from 'prosemirror-commands'
import { Editor } from '../Editor'
import { Command } from '../Editor'
import nodeIsActive from '../utils/nodeIsActive'
import getNodeType from '../utils/getNodeType'
@@ -8,7 +8,7 @@ type ToggleNodeCommand = (
typeOrName: string | NodeType,
toggleType: string | NodeType,
attrs?: {}
) => Editor
) => Command
declare module '../Editor' {
interface Editor {
@@ -16,17 +16,14 @@ declare module '../Editor' {
}
}
export default (next: Function, editor: Editor) => (typeOrName: string | NodeType, toggleTypeOrName: string | NodeType, attrs = {}) => {
const { view, state, schema } = editor
const type = getNodeType(typeOrName, schema)
const toggleType = getNodeType(toggleTypeOrName, schema)
export const toggleNode: ToggleNodeCommand = (typeOrName, toggleTypeOrName, attrs = {}) => ({ state, dispatch }) => {
const type = getNodeType(typeOrName, state.schema)
const toggleType = getNodeType(toggleTypeOrName, state.schema)
const isActive = nodeIsActive(state, type, attrs)
if (isActive) {
setBlockType(toggleType)(view.state, view.dispatch)
return setBlockType(toggleType)(state, dispatch)
} else {
setBlockType(type, attrs)(view.state, view.dispatch)
return setBlockType(type, attrs)(state, dispatch)
}
next()
}

View File

@@ -1,4 +1,4 @@
import { Editor } from '../Editor'
import { Command } from '../Editor'
import { MarkType } from 'prosemirror-model'
import getMarkType from '../utils/getMarkType'
import getMarkRange from '../utils/getMarkRange'
@@ -6,7 +6,7 @@ import getMarkRange from '../utils/getMarkRange'
type UpdateMarkCommand = (
typeOrName: string | MarkType,
attrs: {},
) => Editor
) => Command
declare module '../Editor' {
interface Editor {
@@ -14,11 +14,10 @@ declare module '../Editor' {
}
}
export default (next: Function, editor: Editor) => (typeOrName: string | MarkType, attrs = {}) => {
const { view, state, schema } = editor
const { tr, selection, doc } = state
export const updateMark: UpdateMarkCommand = (typeOrName, attrs = {}) => ({ tr, state }) => {
const { selection, doc } = tr
let { from, to, $from, empty } = selection
const type = getMarkType(typeOrName, schema)
const type = getMarkType(typeOrName, state.schema)
if (empty) {
const range = getMarkRange($from, type)
@@ -36,6 +35,6 @@ export default (next: Function, editor: Editor) => (typeOrName: string | MarkTyp
}
tr.addMark(from, to, type.create(attrs))
view.dispatch(tr)
next()
return true
}