mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-01-18 14:13:21 +08:00
Merge branch 'main' of github.com:ueberdosis/tiptap-next into main
This commit is contained in:
commit
b7dbc4d9bc
@ -40,10 +40,10 @@
|
||||
<button @click="editor.chain().focus().heading({ level: 6 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 6 }) }">
|
||||
h6
|
||||
</button>
|
||||
<button @click="editor.chain().focus().bulletList().run()" :class="{ 'is-active': editor.isActive('bullet_list') }">
|
||||
<button @click="editor.chain().focus().bulletList().run()" :class="{ 'is-active': editor.isActive('bulletList') }">
|
||||
bullet list
|
||||
</button>
|
||||
<button @click="editor.chain().focus().orderedList().run()" :class="{ 'is-active': editor.isActive('ordered_list') }">
|
||||
<button @click="editor.chain().focus().orderedList().run()" :class="{ 'is-active': editor.isActive('orderedList') }">
|
||||
ordered list
|
||||
</button>
|
||||
<button @click="editor.chain().focus().codeBlock().run()" :class="{ 'is-active': editor.isActive('codeBlock') }">
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.chain().focus().bulletList().run()" :class="{ 'is-active': editor.isActive('bullet_list') }">
|
||||
<button @click="editor.chain().focus().bulletList().run()" :class="{ 'is-active': editor.isActive('bulletList') }">
|
||||
bullet list
|
||||
</button>
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.chain().focus().bulletList().run()" :class="{ 'is-active': editor.isActive('bullet_list') }">
|
||||
<button @click="editor.chain().focus().bulletList().run()" :class="{ 'is-active': editor.isActive('bulletList') }">
|
||||
bullet list
|
||||
</button>
|
||||
<button @click="editor.chain().focus().orderedList().run()" :class="{ 'is-active': editor.isActive('ordered_list') }">
|
||||
<button @click="editor.chain().focus().orderedList().run()" :class="{ 'is-active': editor.isActive('orderedList') }">
|
||||
ordered list
|
||||
</button>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.chain().focus().orderedList().run()" :class="{ 'is-active': editor.isActive('ordered_list') }">
|
||||
<button @click="editor.chain().focus().orderedList().run()" :class="{ 'is-active': editor.isActive('orderedList') }">
|
||||
ordered list
|
||||
</button>
|
||||
|
||||
|
@ -12,15 +12,15 @@ context('/api/nodes/task-list', () => {
|
||||
|
||||
it('should parse unordered lists correctly', () => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.setContent('<ul data-type="task_list"><li data-checked="true" data-type="task_item"><p>Example Text</p></li></ul>')
|
||||
expect(editor.getHTML()).to.eq('<ul data-type="task_list"><li data-checked="true" data-type="task_item"><p>Example Text</p></li></ul>')
|
||||
editor.setContent('<ul data-type="task_list"><li data-checked="true" data-type="taskItem"><p>Example Text</p></li></ul>')
|
||||
expect(editor.getHTML()).to.eq('<ul data-type="task_list"><li data-checked="true" data-type="taskItem"><p>Example Text</p></li></ul>')
|
||||
})
|
||||
})
|
||||
|
||||
it('should parse unordered lists without paragraphs correctly', () => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.setContent('<ul data-type="task_list"><li data-checked="false" data-type="task_item">Example Text</li></ul>')
|
||||
expect(editor.getHTML()).to.eq('<ul data-type="task_list"><li data-checked="false" data-type="task_item"><p>Example Text</p></li></ul>')
|
||||
editor.setContent('<ul data-type="task_list"><li data-checked="false" data-type="taskItem">Example Text</li></ul>')
|
||||
expect(editor.getHTML()).to.eq('<ul data-type="task_list"><li data-checked="false" data-type="taskItem"><p>Example Text</p></li></ul>')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -39,8 +39,8 @@ export default {
|
||||
],
|
||||
content: `
|
||||
<ul data-type="task_list">
|
||||
<li data-type="task_item" data-checked="true">A list item</li>
|
||||
<li data-type="task_item" data-checked="false">And another one</li>
|
||||
<li data-type="taskItem" data-checked="true">A list item</li>
|
||||
<li data-type="taskItem" data-checked="false">And another one</li>
|
||||
</ul>
|
||||
`,
|
||||
})
|
||||
|
@ -24,7 +24,7 @@ yarn add @tiptap/extension-bullet-list @tiptap/extension-list-item
|
||||
## Commands
|
||||
| Command | Parameters | Description |
|
||||
| ----------- | ---------- | --------------------- |
|
||||
| bullet_list | — | Toggle a bullet list. |
|
||||
| bulletList | — | Toggle a bullet list. |
|
||||
|
||||
## Keyboard shortcuts
|
||||
* `Control` `Shift` `8`
|
||||
|
@ -189,6 +189,7 @@ $menuBreakPoint: 800px;
|
||||
&::after {
|
||||
content: 'draft';
|
||||
font-family: 'JetBrainsMono', monospace;
|
||||
text-transform: uppercase;
|
||||
color: $colorGrey;
|
||||
background-color: rgba($colorGrey, 0.1);
|
||||
padding: 0 0.5em;
|
||||
@ -200,6 +201,7 @@ $menuBreakPoint: 800px;
|
||||
&::after {
|
||||
content: 'PRO';
|
||||
font-family: 'JetBrainsMono', monospace;
|
||||
text-transform: uppercase;
|
||||
color: $colorOrange;
|
||||
background-color: rgba($colorOrange, 0.1);
|
||||
padding: 0 0.5em;
|
||||
|
@ -131,7 +131,7 @@ export default class CommandManager {
|
||||
view,
|
||||
state: this.chainableState(tr, state),
|
||||
dispatch: shouldDispatch
|
||||
? () => true
|
||||
? () => undefined
|
||||
: undefined,
|
||||
chain: () => this.createChain(tr),
|
||||
can: () => this.createCan(tr),
|
||||
|
@ -261,15 +261,20 @@ export class Editor extends EventEmitter {
|
||||
*/
|
||||
private createView() {
|
||||
this.view = new EditorView(this.options.element, {
|
||||
dispatchTransaction: this.dispatchTransaction.bind(this),
|
||||
state: EditorState.create({
|
||||
doc: this.createDocument(this.options.content),
|
||||
plugins: this.extensionManager.plugins,
|
||||
}),
|
||||
dispatchTransaction: this.dispatchTransaction.bind(this),
|
||||
})
|
||||
|
||||
// `editor.view` is not yet available at this time.
|
||||
// Therefore we will add all node views directly afterwards.
|
||||
// Therefore we will add all plugins and node views directly afterwards.
|
||||
const newState = this.state.reconfigure({
|
||||
plugins: this.extensionManager.plugins,
|
||||
})
|
||||
|
||||
this.view.updateState(newState)
|
||||
|
||||
this.view.setProps({
|
||||
nodeViews: this.extensionManager.nodeViews,
|
||||
})
|
||||
|
9
packages/core/src/commands/blur.ts
Normal file
9
packages/core/src/commands/blur.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (): Command => ({ view }) => {
|
||||
const element = view.dom as HTMLElement
|
||||
|
||||
element.blur()
|
||||
|
||||
return true
|
||||
}
|
5
packages/core/src/commands/clearContent.ts
Normal file
5
packages/core/src/commands/clearContent.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (emitUpdate: Boolean = false): Command => ({ commands }) => {
|
||||
return commands.setContent('', emitUpdate)
|
||||
}
|
29
packages/core/src/commands/clearNodes.ts
Normal file
29
packages/core/src/commands/clearNodes.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { liftTarget } from 'prosemirror-transform'
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (): Command => ({ state, tr, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const { from, to } = selection
|
||||
|
||||
state.doc.nodesBetween(from, to, (node, pos) => {
|
||||
if (!node.type.isText) {
|
||||
const fromPos = tr.doc.resolve(tr.mapping.map(pos + 1))
|
||||
const toPos = tr.doc.resolve(tr.mapping.map(pos + node.nodeSize - 1))
|
||||
const nodeRange = fromPos.blockRange(toPos)
|
||||
|
||||
if (nodeRange) {
|
||||
const targetLiftDepth = liftTarget(nodeRange)
|
||||
|
||||
if (node.type.isTextblock && dispatch) {
|
||||
tr.setNodeMarkup(nodeRange.start, state.schema.nodes.paragraph)
|
||||
}
|
||||
|
||||
if ((targetLiftDepth || targetLiftDepth === 0) && dispatch) {
|
||||
tr.lift(nodeRange, targetLiftDepth)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return true
|
||||
}
|
6
packages/core/src/commands/deleteSelection.ts
Normal file
6
packages/core/src/commands/deleteSelection.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { deleteSelection } from 'prosemirror-commands'
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (): Command => ({ state, dispatch }) => {
|
||||
return deleteSelection(state, dispatch)
|
||||
}
|
58
packages/core/src/commands/focus.ts
Normal file
58
packages/core/src/commands/focus.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { TextSelection } from 'prosemirror-state'
|
||||
import { Editor, Command } from '../Editor'
|
||||
import minMax from '../utils/minMax'
|
||||
|
||||
type Position = 'start' | 'end' | number | boolean | null
|
||||
|
||||
interface ResolvedSelection {
|
||||
from: number,
|
||||
to: number,
|
||||
}
|
||||
|
||||
function resolveSelection(editor: Editor, position: Position = null): ResolvedSelection {
|
||||
if (position === null) {
|
||||
return editor.selection
|
||||
}
|
||||
|
||||
if (position === 'start' || position === true) {
|
||||
return {
|
||||
from: 0,
|
||||
to: 0,
|
||||
}
|
||||
}
|
||||
|
||||
if (position === 'end') {
|
||||
const { size } = editor.state.doc.content
|
||||
|
||||
return {
|
||||
from: size,
|
||||
to: size - 1, // TODO: -1 only for nodes with content
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
from: position as number,
|
||||
to: position as number,
|
||||
}
|
||||
}
|
||||
|
||||
export default (position: Position = null): Command => ({
|
||||
editor, view, tr, dispatch,
|
||||
}) => {
|
||||
if ((view.hasFocus() && position === null) || position === false) {
|
||||
return true
|
||||
}
|
||||
|
||||
const { from, to } = resolveSelection(editor, position)
|
||||
const { doc } = tr
|
||||
const resolvedFrom = minMax(from, 0, doc.content.size)
|
||||
const resolvedEnd = minMax(to, 0, doc.content.size)
|
||||
const selection = TextSelection.create(doc, resolvedFrom, resolvedEnd)
|
||||
|
||||
if (dispatch) {
|
||||
tr.setSelection(selection)
|
||||
view.focus()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
@ -3,7 +3,6 @@ import { Selection, Transaction } from 'prosemirror-state'
|
||||
import { ReplaceStep, ReplaceAroundStep } from 'prosemirror-transform'
|
||||
import elementFromString from '../utils/elementFromString'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
// TODO: move to utils
|
||||
// https://github.com/ProseMirror/prosemirror-state/blob/master/src/selection.js#L466
|
||||
@ -18,27 +17,15 @@ function selectionToInsertionEnd(tr: Transaction, startLen: number, bias: number
|
||||
tr.setSelection(Selection.near(tr.doc.resolve(end as unknown as number), bias))
|
||||
}
|
||||
|
||||
export const InsertHTML = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
insertHTML: (value: string): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const element = elementFromString(value)
|
||||
const slice = DOMParser.fromSchema(state.schema).parseSlice(element)
|
||||
export default (value: string): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const element = elementFromString(value)
|
||||
const slice = DOMParser.fromSchema(state.schema).parseSlice(element)
|
||||
|
||||
if (dispatch) {
|
||||
tr.insert(selection.anchor, slice.content)
|
||||
selectionToInsertionEnd(tr, tr.steps.length - 1, -1)
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
InsertHTML: typeof InsertHTML,
|
||||
if (dispatch) {
|
||||
tr.insert(selection.anchor, slice.content)
|
||||
selectionToInsertionEnd(tr, tr.steps.length - 1, -1)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
9
packages/core/src/commands/insertText.ts
Normal file
9
packages/core/src/commands/insertText.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (value: string): Command => ({ tr, dispatch }) => {
|
||||
if (dispatch) {
|
||||
tr.insertText(value)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
10
packages/core/src/commands/liftListItem.ts
Normal file
10
packages/core/src/commands/liftListItem.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { liftListItem } from 'prosemirror-schema-list'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export default (typeOrName: string | NodeType): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
|
||||
return liftListItem(type)(state, dispatch)
|
||||
}
|
26
packages/core/src/commands/removeMark.ts
Normal file
26
packages/core/src/commands/removeMark.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { MarkType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import getMarkType from '../utils/getMarkType'
|
||||
import getMarkRange from '../utils/getMarkRange'
|
||||
|
||||
export default (typeOrName: string | MarkType): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const type = getMarkType(typeOrName, state.schema)
|
||||
let { from, to } = selection
|
||||
const { $from, empty } = selection
|
||||
|
||||
if (empty) {
|
||||
const range = getMarkRange($from, type)
|
||||
|
||||
if (range) {
|
||||
from = range.from
|
||||
to = range.to
|
||||
}
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
tr.removeMark(from, to, type)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
20
packages/core/src/commands/removeMarks.ts
Normal file
20
packages/core/src/commands/removeMarks.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const { from, to, empty } = selection
|
||||
|
||||
if (empty) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
Object
|
||||
.entries(state.schema.marks)
|
||||
.forEach(([, mark]) => {
|
||||
tr.removeMark(from, to, mark as any)
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
23
packages/core/src/commands/resetNodeAttributes.ts
Normal file
23
packages/core/src/commands/resetNodeAttributes.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (attributeNames: string[] = []): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const { from, to } = selection
|
||||
|
||||
state.doc.nodesBetween(from, to, (node, pos) => {
|
||||
if (!node.type.isText) {
|
||||
attributeNames.forEach(name => {
|
||||
const attribute = node.type.spec.attrs?.[name]
|
||||
const defaultValue = attribute?.default
|
||||
|
||||
if (attribute && defaultValue !== undefined && dispatch) {
|
||||
tr.setNodeMarkup(pos, undefined, {
|
||||
[name]: defaultValue,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return true
|
||||
}
|
9
packages/core/src/commands/scrollIntoView.ts
Normal file
9
packages/core/src/commands/scrollIntoView.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (): Command => ({ tr, dispatch }) => {
|
||||
if (dispatch) {
|
||||
tr.scrollIntoView()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
6
packages/core/src/commands/selectAll.ts
Normal file
6
packages/core/src/commands/selectAll.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { selectAll } from 'prosemirror-commands'
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (): Command => ({ state, dispatch }) => {
|
||||
return selectAll(state, dispatch)
|
||||
}
|
6
packages/core/src/commands/selectParentNode.ts
Normal file
6
packages/core/src/commands/selectParentNode.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { selectParentNode } from 'prosemirror-commands'
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (): Command => ({ state, dispatch }) => {
|
||||
return selectParentNode(state, dispatch)
|
||||
}
|
10
packages/core/src/commands/setBlockType.ts
Normal file
10
packages/core/src/commands/setBlockType.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { setBlockType } from 'prosemirror-commands'
|
||||
import { Command } from '../Editor'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export default (typeOrName: string | NodeType, attrs = {}): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
|
||||
return setBlockType(type, attrs)(state, dispatch)
|
||||
}
|
17
packages/core/src/commands/setContent.ts
Normal file
17
packages/core/src/commands/setContent.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { TextSelection } from 'prosemirror-state'
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (content: string, emitUpdate: Boolean = false, parseOptions = {}): Command => ({ tr, editor, dispatch }) => {
|
||||
const { createDocument } = editor
|
||||
const { doc } = tr
|
||||
const document = createDocument(content, parseOptions)
|
||||
const selection = TextSelection.create(doc, 0, doc.content.size)
|
||||
|
||||
if (dispatch) {
|
||||
tr.setSelection(selection)
|
||||
.replaceSelectionWith(document, false)
|
||||
.setMeta('preventUpdate', !emitUpdate)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
14
packages/core/src/commands/setNodeAttributes.ts
Normal file
14
packages/core/src/commands/setNodeAttributes.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (attributes: {}): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const { from, to } = selection
|
||||
|
||||
state.doc.nodesBetween(from, to, (node, pos) => {
|
||||
if (!node.type.isText && dispatch) {
|
||||
tr.setNodeMarkup(pos, undefined, attributes)
|
||||
}
|
||||
})
|
||||
|
||||
return true
|
||||
}
|
10
packages/core/src/commands/sinkListItem.ts
Normal file
10
packages/core/src/commands/sinkListItem.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { sinkListItem as originalSinkListItem } from 'prosemirror-schema-list'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export default (typeOrName: string | NodeType): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
|
||||
return originalSinkListItem(type)(state, dispatch)
|
||||
}
|
117
packages/core/src/commands/splitBlock.ts
Normal file
117
packages/core/src/commands/splitBlock.ts
Normal file
@ -0,0 +1,117 @@
|
||||
import { canSplit } from 'prosemirror-transform'
|
||||
import { ContentMatch, Fragment } from 'prosemirror-model'
|
||||
import { EditorState, NodeSelection, TextSelection } from 'prosemirror-state'
|
||||
import { Command } from '../Editor'
|
||||
|
||||
function defaultBlockAt(match: ContentMatch) {
|
||||
for (let i = 0; i < match.edgeCount; i + 1) {
|
||||
const { type } = match.edge(i)
|
||||
// @ts-ignore
|
||||
if (type.isTextblock && !type.hasRequiredAttrs()) return type
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export interface SplitBlockOptions {
|
||||
withAttributes: boolean,
|
||||
withMarks: boolean,
|
||||
}
|
||||
|
||||
function keepMarks(state: EditorState) {
|
||||
const marks = state.storedMarks
|
||||
|| (state.selection.$to.parentOffset && state.selection.$from.marks())
|
||||
|
||||
if (marks) {
|
||||
state.tr.ensureMarks(marks)
|
||||
}
|
||||
}
|
||||
|
||||
export default (options: Partial<SplitBlockOptions> = {}): Command => ({ tr, state, dispatch }) => {
|
||||
const defaultOptions: SplitBlockOptions = {
|
||||
withAttributes: false,
|
||||
withMarks: true,
|
||||
}
|
||||
const config = { ...defaultOptions, ...options }
|
||||
const { selection, doc } = tr
|
||||
const { $from, $to } = selection
|
||||
|
||||
if (selection instanceof NodeSelection && selection.node.isBlock) {
|
||||
if (!$from.parentOffset || !canSplit(doc, $from.pos)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
if (config.withMarks) {
|
||||
keepMarks(state)
|
||||
}
|
||||
|
||||
tr.split($from.pos).scrollIntoView()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if (!$from.parent.isBlock) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
const atEnd = $to.parentOffset === $to.parent.content.size
|
||||
|
||||
if (selection instanceof TextSelection) {
|
||||
tr.deleteSelection()
|
||||
}
|
||||
|
||||
const deflt = $from.depth === 0
|
||||
? undefined
|
||||
: defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)))
|
||||
|
||||
let types = atEnd && deflt
|
||||
? [{
|
||||
type: deflt,
|
||||
attrs: config.withAttributes
|
||||
? $from.node().attrs
|
||||
: {},
|
||||
}]
|
||||
: undefined
|
||||
|
||||
let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types)
|
||||
|
||||
if (
|
||||
!types
|
||||
&& !can
|
||||
&& canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : undefined)
|
||||
) {
|
||||
can = true
|
||||
types = deflt
|
||||
? [{
|
||||
type: deflt,
|
||||
attrs: config.withAttributes
|
||||
? $from.node().attrs
|
||||
: {},
|
||||
}]
|
||||
: undefined
|
||||
}
|
||||
|
||||
if (can) {
|
||||
tr.split(tr.mapping.map($from.pos), 1, types)
|
||||
|
||||
if (
|
||||
!atEnd
|
||||
&& !$from.parentOffset
|
||||
&& $from.parent.type !== deflt
|
||||
&& $from.node(-1).canReplace($from.index(-1), $from.indexAfter(-1), Fragment.from(deflt?.create()))
|
||||
) {
|
||||
tr.setNodeMarkup(tr.mapping.map($from.before()), deflt || undefined)
|
||||
}
|
||||
}
|
||||
|
||||
if (config.withMarks) {
|
||||
keepMarks(state)
|
||||
}
|
||||
|
||||
tr.scrollIntoView()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
10
packages/core/src/commands/splitListItem.ts
Normal file
10
packages/core/src/commands/splitListItem.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { splitListItem } from 'prosemirror-schema-list'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export default (typeOrName: string | NodeType): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
|
||||
return splitListItem(type)(state, dispatch)
|
||||
}
|
16
packages/core/src/commands/toggleBlockType.ts
Normal file
16
packages/core/src/commands/toggleBlockType.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import nodeIsActive from '../utils/nodeIsActive'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export default (typeOrName: string | NodeType, toggleTypeOrName: string | NodeType, attrs = {}): Command => ({ state, commands }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
const toggleType = getNodeType(toggleTypeOrName, state.schema)
|
||||
const isActive = nodeIsActive(state, type, attrs)
|
||||
|
||||
if (isActive) {
|
||||
return commands.setBlockType(toggleType)
|
||||
}
|
||||
|
||||
return commands.setBlockType(type, attrs)
|
||||
}
|
52
packages/core/src/commands/toggleList.ts
Normal file
52
packages/core/src/commands/toggleList.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { findParentNode } from 'prosemirror-utils'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
import isList from '../utils/isList'
|
||||
|
||||
export default (listTypeOrName: string | NodeType, itemTypeOrName: string | NodeType): Command => ({
|
||||
editor, tr, state, dispatch, chain, commands, can,
|
||||
}) => {
|
||||
const { extensions } = editor.options
|
||||
const listType = getNodeType(listTypeOrName, state.schema)
|
||||
const itemType = getNodeType(itemTypeOrName, state.schema)
|
||||
const { selection } = state
|
||||
const { $from, $to } = selection
|
||||
const range = $from.blockRange($to)
|
||||
|
||||
if (!range) {
|
||||
return false
|
||||
}
|
||||
|
||||
const parentList = findParentNode(node => isList(node.type.name, extensions))(selection)
|
||||
|
||||
if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) {
|
||||
// remove list
|
||||
if (parentList.node.type === listType) {
|
||||
return commands.liftListItem(itemType)
|
||||
}
|
||||
|
||||
// change list type
|
||||
if (
|
||||
isList(parentList.node.type.name, extensions)
|
||||
&& listType.validContent(parentList.node.content)
|
||||
&& dispatch
|
||||
) {
|
||||
tr.setNodeMarkup(parentList.pos, listType)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const canWrapInList = can().wrapInList(listType)
|
||||
|
||||
// try to convert node to paragraph if needed
|
||||
if (!canWrapInList) {
|
||||
return chain()
|
||||
.clearNodes()
|
||||
.wrapInList(listType)
|
||||
.run()
|
||||
}
|
||||
|
||||
return commands.wrapInList(listType)
|
||||
}
|
10
packages/core/src/commands/toggleMark.ts
Normal file
10
packages/core/src/commands/toggleMark.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { toggleMark as originalToggleMark } from 'prosemirror-commands'
|
||||
import { MarkType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import getMarkType from '../utils/getMarkType'
|
||||
|
||||
export default (typeOrName: string | MarkType): Command => ({ state, dispatch }) => {
|
||||
const type = getMarkType(typeOrName, state.schema)
|
||||
|
||||
return originalToggleMark(type)(state, dispatch)
|
||||
}
|
16
packages/core/src/commands/toggleWrap.ts
Normal file
16
packages/core/src/commands/toggleWrap.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { wrapIn, lift } from 'prosemirror-commands'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import nodeIsActive from '../utils/nodeIsActive'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export default (typeOrName: string | NodeType, attrs = {}): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
const isActive = nodeIsActive(state, type, attrs)
|
||||
|
||||
if (isActive) {
|
||||
return lift(state, dispatch)
|
||||
}
|
||||
|
||||
return wrapIn(type, attrs)(state, dispatch)
|
||||
}
|
15
packages/core/src/commands/try.ts
Normal file
15
packages/core/src/commands/try.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Command } from '../Editor'
|
||||
|
||||
export default (commands: Command[] | ((props: Parameters<Command>[0]) => Command[])): Command => props => {
|
||||
const items = typeof commands === 'function'
|
||||
? commands(props)
|
||||
: commands
|
||||
|
||||
for (let i = 0; i < items.length; i += 1) {
|
||||
if (items[i](props)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
32
packages/core/src/commands/updateMark.ts
Normal file
32
packages/core/src/commands/updateMark.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { MarkType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import getMarkType from '../utils/getMarkType'
|
||||
import getMarkRange from '../utils/getMarkRange'
|
||||
|
||||
export default (typeOrName: string | MarkType, attrs: {}): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection, doc } = tr
|
||||
let { from, to } = selection
|
||||
const { $from, empty } = selection
|
||||
const type = getMarkType(typeOrName, state.schema)
|
||||
|
||||
if (empty) {
|
||||
const range = getMarkRange($from, type)
|
||||
|
||||
if (range) {
|
||||
from = range.from
|
||||
to = range.to
|
||||
}
|
||||
}
|
||||
|
||||
const hasMark = doc.rangeHasMark(from, to, type)
|
||||
|
||||
if (hasMark && dispatch) {
|
||||
tr.removeMark(from, to, type)
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
tr.addMark(from, to, type.create(attrs))
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
10
packages/core/src/commands/wrapInList.ts
Normal file
10
packages/core/src/commands/wrapInList.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { wrapInList } from 'prosemirror-schema-list'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export default (typeOrName: string | NodeType, attrs?: {}): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
|
||||
return wrapInList(type, attrs)(state, dispatch)
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
import { baseKeymap } from 'prosemirror-commands'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const BaseKeymap = createExtension({
|
||||
addKeyboardShortcuts() {
|
||||
return baseKeymap
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
BaseKeymap: typeof BaseKeymap,
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const Blur = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
blur: (): Command => ({ view }) => {
|
||||
const element = view.dom as HTMLElement
|
||||
|
||||
element.blur()
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
Blur: typeof Blur,
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const ClearContent = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
clearContent: (emitUpdate: Boolean = false): Command => ({ commands }) => {
|
||||
return commands.setContent('', emitUpdate)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
ClearContent: typeof ClearContent,
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
import { liftTarget } from 'prosemirror-transform'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const ClearNodes = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
clearNodes: (): Command => ({ state, tr, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const { from, to } = selection
|
||||
|
||||
state.doc.nodesBetween(from, to, (node, pos) => {
|
||||
if (!node.type.isText) {
|
||||
const fromPos = tr.doc.resolve(tr.mapping.map(pos + 1))
|
||||
const toPos = tr.doc.resolve(tr.mapping.map(pos + node.nodeSize - 1))
|
||||
const nodeRange = fromPos.blockRange(toPos)
|
||||
|
||||
if (nodeRange) {
|
||||
const targetLiftDepth = liftTarget(nodeRange)
|
||||
|
||||
if (node.type.isTextblock && dispatch) {
|
||||
tr.setNodeMarkup(nodeRange.start, state.schema.nodes.paragraph)
|
||||
}
|
||||
|
||||
if ((targetLiftDepth || targetLiftDepth === 0) && dispatch) {
|
||||
tr.lift(nodeRange, targetLiftDepth)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
ClearNodes: typeof ClearNodes,
|
||||
}
|
||||
}
|
68
packages/core/src/extensions/commands.ts
Normal file
68
packages/core/src/extensions/commands.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { createExtension } from '../Extension'
|
||||
import blur from '../commands/blur'
|
||||
import clearContent from '../commands/clearContent'
|
||||
import clearNodes from '../commands/clearNodes'
|
||||
import deleteSelection from '../commands/deleteSelection'
|
||||
import focus from '../commands/focus'
|
||||
import insertHTML from '../commands/insertHTML'
|
||||
import insertText from '../commands/insertText'
|
||||
import liftListItem from '../commands/liftListItem'
|
||||
import removeMark from '../commands/removeMark'
|
||||
import removeMarks from '../commands/removeMarks'
|
||||
import resetNodeAttributes from '../commands/resetNodeAttributes'
|
||||
import scrollIntoView from '../commands/scrollIntoView'
|
||||
import selectAll from '../commands/selectAll'
|
||||
import selectParentNode from '../commands/selectParentNode'
|
||||
import setBlockType from '../commands/setBlockType'
|
||||
import setContent from '../commands/setContent'
|
||||
import setNodeAttributes from '../commands/setNodeAttributes'
|
||||
import sinkListItem from '../commands/sinkListItem'
|
||||
import splitBlock from '../commands/splitBlock'
|
||||
import splitListItem from '../commands/splitListItem'
|
||||
import toggleBlockType from '../commands/toggleBlockType'
|
||||
import toggleList from '../commands/toggleList'
|
||||
import toggleMark from '../commands/toggleMark'
|
||||
import toggleWrap from '../commands/toggleWrap'
|
||||
import tryCommand from '../commands/try'
|
||||
import updateMark from '../commands/updateMark'
|
||||
import wrapInList from '../commands/wrapInList'
|
||||
|
||||
export const Commands = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
blur,
|
||||
clearContent,
|
||||
clearNodes,
|
||||
deleteSelection,
|
||||
focus,
|
||||
insertHTML,
|
||||
insertText,
|
||||
liftListItem,
|
||||
removeMark,
|
||||
removeMarks,
|
||||
resetNodeAttributes,
|
||||
scrollIntoView,
|
||||
selectAll,
|
||||
selectParentNode,
|
||||
setBlockType,
|
||||
setContent,
|
||||
setNodeAttributes,
|
||||
sinkListItem,
|
||||
splitBlock,
|
||||
splitListItem,
|
||||
toggleBlockType,
|
||||
toggleList,
|
||||
toggleMark,
|
||||
toggleWrap,
|
||||
try: tryCommand,
|
||||
updateMark,
|
||||
wrapInList,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
Commands: typeof Commands,
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import { deleteSelection } from 'prosemirror-commands'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const DeleteSelection = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
deleteSelection: (): Command => ({ state, dispatch }) => {
|
||||
return deleteSelection(state, dispatch)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
DeleteSelection: typeof DeleteSelection,
|
||||
}
|
||||
}
|
@ -13,3 +13,10 @@ export const Editable = createExtension({
|
||||
]
|
||||
},
|
||||
})
|
||||
|
||||
// TODO: Editable circularly references itself!?
|
||||
// declare module '../Editor' {
|
||||
// interface AllExtensions {
|
||||
// Editable: typeof Editable,
|
||||
// }
|
||||
// }
|
||||
|
@ -1,72 +0,0 @@
|
||||
import { TextSelection } from 'prosemirror-state'
|
||||
import { Editor, Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import minMax from '../utils/minMax'
|
||||
|
||||
type Position = 'start' | 'end' | number | boolean | null
|
||||
|
||||
interface ResolvedSelection {
|
||||
from: number,
|
||||
to: number,
|
||||
}
|
||||
|
||||
function resolveSelection(editor: Editor, position: Position = null): ResolvedSelection {
|
||||
if (position === null) {
|
||||
return editor.selection
|
||||
}
|
||||
|
||||
if (position === 'start' || position === true) {
|
||||
return {
|
||||
from: 0,
|
||||
to: 0,
|
||||
}
|
||||
}
|
||||
|
||||
if (position === 'end') {
|
||||
const { size } = editor.state.doc.content
|
||||
|
||||
return {
|
||||
from: size,
|
||||
to: size - 1, // TODO: -1 only for nodes with content
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
from: position as number,
|
||||
to: position as number,
|
||||
}
|
||||
}
|
||||
|
||||
export const Focus = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
focus: (position: Position = null): Command => ({
|
||||
editor, view, tr, dispatch,
|
||||
}) => {
|
||||
if ((view.hasFocus() && position === null) || position === false) {
|
||||
return true
|
||||
}
|
||||
|
||||
const { from, to } = resolveSelection(editor, position)
|
||||
const { doc } = tr
|
||||
const resolvedFrom = minMax(from, 0, doc.content.size)
|
||||
const resolvedEnd = minMax(to, 0, doc.content.size)
|
||||
const selection = TextSelection.create(doc, resolvedFrom, resolvedEnd)
|
||||
|
||||
if (dispatch) {
|
||||
tr.setSelection(selection)
|
||||
}
|
||||
|
||||
view.focus()
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
Focus: typeof Focus,
|
||||
}
|
||||
}
|
@ -1,30 +1,4 @@
|
||||
export { Blur } from './blur'
|
||||
export { ClearContent } from './clearContent'
|
||||
export { ClearNodes } from './clearNodes'
|
||||
export { DeleteSelection } from './deleteSelection'
|
||||
export { Commands } from './commands'
|
||||
export { Editable } from './editable'
|
||||
export { Focus } from './focus'
|
||||
export { FocusEvents } from './focusEvents'
|
||||
export { InputRules } from './inputRules'
|
||||
export { InsertHTML } from './insertHTML'
|
||||
export { InsertText } from './insertText'
|
||||
export { BaseKeymap } from './baseKeymap'
|
||||
export { LiftListItem } from './liftListItem'
|
||||
export { RemoveMark } from './removeMark'
|
||||
export { RemoveMarks } from './removeMarks'
|
||||
export { ScrollIntoView } from './scrollIntoView'
|
||||
export { SelectAll } from './selectAll'
|
||||
export { SelectParentNode } from './selectParentNode'
|
||||
export { ResetNodeAttributes } from './resetNodeAttributes'
|
||||
export { SetNodeAttributes } from './setNodeAttributes'
|
||||
export { SetBlockType } from './setBlockType'
|
||||
export { SetContent } from './setContent'
|
||||
export { SinkListItem } from './sinkListItem'
|
||||
export { SplitBlock } from './splitBlock'
|
||||
export { SplitListItem } from './splitListItem'
|
||||
export { ToggleBlockType } from './toggleBlockType'
|
||||
export { ToggleList } from './toggleList'
|
||||
export { ToggleMark } from './toggleMark'
|
||||
export { UpdateMark } from './updateMark'
|
||||
export { ToggleWrap } from './toggleWrap'
|
||||
export { WrapInList } from './wrapInList'
|
||||
export { Keymap } from './keymap'
|
||||
|
@ -1,16 +0,0 @@
|
||||
import { undoInputRule } from 'prosemirror-inputrules'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const InputRules = createExtension({
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Backspace: undoInputRule,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
InputRules: typeof InputRules,
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const InsertText = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
insertText: (value: string): Command => ({ tr, dispatch }) => {
|
||||
if (dispatch) {
|
||||
tr.insertText(value)
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
InsertText: typeof InsertText,
|
||||
}
|
||||
}
|
52
packages/core/src/extensions/keymap.ts
Normal file
52
packages/core/src/extensions/keymap.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import {
|
||||
newlineInCode,
|
||||
createParagraphNear,
|
||||
liftEmptyBlock,
|
||||
exitCode,
|
||||
deleteSelection,
|
||||
joinForward,
|
||||
joinBackward,
|
||||
selectNodeForward,
|
||||
selectNodeBackward,
|
||||
} from 'prosemirror-commands'
|
||||
import { undoInputRule } from 'prosemirror-inputrules'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const Keymap = createExtension({
|
||||
addKeyboardShortcuts() {
|
||||
const handleBackspace = () => this.editor.try(({ state, dispatch }) => [
|
||||
() => undoInputRule(state, dispatch),
|
||||
() => deleteSelection(state, dispatch),
|
||||
() => joinBackward(state, dispatch),
|
||||
() => selectNodeBackward(state, dispatch),
|
||||
])
|
||||
|
||||
const handleDelete = () => this.editor.try(({ state, dispatch }) => [
|
||||
() => deleteSelection(state, dispatch),
|
||||
() => joinForward(state, dispatch),
|
||||
() => selectNodeForward(state, dispatch),
|
||||
])
|
||||
|
||||
return {
|
||||
Enter: () => this.editor.try(({ commands, state, dispatch }) => [
|
||||
() => newlineInCode(state, dispatch),
|
||||
() => createParagraphNear(state, dispatch),
|
||||
() => liftEmptyBlock(state, dispatch),
|
||||
() => commands.splitBlock(),
|
||||
]),
|
||||
'Mod-Enter': exitCode,
|
||||
Backspace: () => handleBackspace(),
|
||||
'Mod-Backspace': () => handleBackspace(),
|
||||
Delete: () => handleDelete(),
|
||||
'Mod-Delete': () => handleDelete(),
|
||||
// we don’t need a custom `selectAll` for now
|
||||
// 'Mod-a': () => this.editor.selectAll(),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
Keymap: typeof Keymap,
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { liftListItem } from 'prosemirror-schema-list'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export const LiftListItem = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
liftListItem: (typeOrName: string | NodeType): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
|
||||
return liftListItem(type)(state, dispatch)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
LiftListItem: typeof LiftListItem,
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
import { MarkType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import getMarkType from '../utils/getMarkType'
|
||||
import getMarkRange from '../utils/getMarkRange'
|
||||
|
||||
export const RemoveMark = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
removeMark: (typeOrName: string | MarkType): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const type = getMarkType(typeOrName, state.schema)
|
||||
let { from, to } = selection
|
||||
const { $from, empty } = selection
|
||||
|
||||
if (empty) {
|
||||
const range = getMarkRange($from, type)
|
||||
|
||||
if (range) {
|
||||
from = range.from
|
||||
to = range.to
|
||||
}
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
tr.removeMark(from, to, type)
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
RemoveMark: typeof RemoveMark,
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const RemoveMarks = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
removeMarks: (): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const { from, to, empty } = selection
|
||||
|
||||
if (empty) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
Object
|
||||
.entries(state.schema.marks)
|
||||
.forEach(([, mark]) => {
|
||||
tr.removeMark(from, to, mark as any)
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
RemoveMarks: typeof RemoveMarks,
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const ResetNodeAttributes = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
resetNodeAttributes: (attributeNames: string[] = []): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const { from, to } = selection
|
||||
|
||||
state.doc.nodesBetween(from, to, (node, pos) => {
|
||||
if (!node.type.isText) {
|
||||
attributeNames.forEach(name => {
|
||||
const attribute = node.type.spec.attrs?.[name]
|
||||
const defaultValue = attribute?.default
|
||||
|
||||
if (attribute && defaultValue !== undefined && dispatch) {
|
||||
tr.setNodeMarkup(pos, undefined, {
|
||||
[name]: defaultValue,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
ResetNodeAttributes: typeof ResetNodeAttributes,
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const ScrollIntoView = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
scrollIntoView: (): Command => ({ tr, dispatch }) => {
|
||||
if (dispatch) {
|
||||
tr.scrollIntoView()
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
ScrollIntoView: typeof ScrollIntoView,
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import { selectAll } from 'prosemirror-commands'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const SelectAll = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
selectAll: (): Command => ({ state, dispatch }) => {
|
||||
return selectAll(state, dispatch)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
SelectAll: typeof SelectAll,
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import { selectParentNode } from 'prosemirror-commands'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const SelectParentNode = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
selectParentNode: (): Command => ({ state, dispatch }) => {
|
||||
return selectParentNode(state, dispatch)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
SelectParentNode: typeof SelectParentNode,
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { setBlockType } from 'prosemirror-commands'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export const SetBlockType = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
setBlockType: (typeOrName: string | NodeType, attrs = {}): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
|
||||
return setBlockType(type, attrs)(state, dispatch)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
SetBlockType: typeof SetBlockType,
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
import { TextSelection } from 'prosemirror-state'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const SetContent = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
setContent: (content: string, emitUpdate: Boolean = false, parseOptions = {}): Command => ({ tr, editor, dispatch }) => {
|
||||
const { createDocument } = editor
|
||||
const { doc } = tr
|
||||
const document = createDocument(content, parseOptions)
|
||||
const selection = TextSelection.create(doc, 0, doc.content.size)
|
||||
|
||||
if (dispatch) {
|
||||
tr.setSelection(selection)
|
||||
.replaceSelectionWith(document, false)
|
||||
.setMeta('preventUpdate', !emitUpdate)
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
SetContent: typeof SetContent,
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
export const SetNodeAttributes = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
setNodeAttributes: (attributes: {}): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection } = tr
|
||||
const { from, to } = selection
|
||||
|
||||
state.doc.nodesBetween(from, to, (node, pos) => {
|
||||
if (!node.type.isText && dispatch) {
|
||||
tr.setNodeMarkup(pos, undefined, attributes)
|
||||
}
|
||||
})
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
SetNodeAttributes: typeof SetNodeAttributes,
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { sinkListItem as originalSinkListItem } from 'prosemirror-schema-list'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export const SinkListItem = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
sinkListItem: (typeOrName: string | NodeType): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
|
||||
return originalSinkListItem(type)(state, dispatch)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
SinkListItem: typeof SinkListItem,
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
import { canSplit } from 'prosemirror-transform'
|
||||
import { ContentMatch, Fragment } from 'prosemirror-model'
|
||||
import { NodeSelection, TextSelection } from 'prosemirror-state'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
|
||||
function defaultBlockAt(match: ContentMatch) {
|
||||
for (let i = 0; i < match.edgeCount; i + 1) {
|
||||
const { type } = match.edge(i)
|
||||
// @ts-ignore
|
||||
if (type.isTextblock && !type.hasRequiredAttrs()) return type
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const SplitBlock = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
splitBlock: (copyAttributes = false): Command => ({ tr, dispatch }) => {
|
||||
const { selection, doc } = tr
|
||||
const { $from, $to } = selection
|
||||
|
||||
if (selection instanceof NodeSelection && selection.node.isBlock) {
|
||||
if (!$from.parentOffset || !canSplit(doc, $from.pos)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
tr.split($from.pos).scrollIntoView()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if (!$from.parent.isBlock) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
const atEnd = $to.parentOffset === $to.parent.content.size
|
||||
|
||||
if (selection instanceof TextSelection) {
|
||||
tr.deleteSelection()
|
||||
}
|
||||
|
||||
const deflt = $from.depth === 0
|
||||
? undefined
|
||||
: defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)))
|
||||
|
||||
let types = atEnd && deflt
|
||||
? [{ type: deflt, attrs: copyAttributes ? $from.node().attrs : {} }]
|
||||
: undefined
|
||||
|
||||
let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types)
|
||||
|
||||
if (
|
||||
!types
|
||||
&& !can
|
||||
&& canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : undefined)
|
||||
) {
|
||||
can = true
|
||||
types = deflt
|
||||
? [{ type: deflt, attrs: copyAttributes ? $from.node().attrs : {} }]
|
||||
: undefined
|
||||
}
|
||||
|
||||
if (can) {
|
||||
tr.split(tr.mapping.map($from.pos), 1, types)
|
||||
|
||||
if (
|
||||
!atEnd
|
||||
&& !$from.parentOffset
|
||||
&& $from.parent.type !== deflt
|
||||
&& $from.node(-1).canReplace($from.index(-1), $from.indexAfter(-1), Fragment.from(deflt?.create()))
|
||||
) {
|
||||
tr.setNodeMarkup(tr.mapping.map($from.before()), deflt || undefined)
|
||||
}
|
||||
}
|
||||
|
||||
tr.scrollIntoView()
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
SplitBlock: typeof SplitBlock,
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { splitListItem } from 'prosemirror-schema-list'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export const SplitListItem = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
splitListItem: (typeOrName: string | NodeType): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
|
||||
return splitListItem(type)(state, dispatch)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
SplitListItem: typeof SplitListItem,
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import nodeIsActive from '../utils/nodeIsActive'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export const ToggleBlockType = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
toggleBlockType: (typeOrName: string | NodeType, toggleTypeOrName: string | NodeType, attrs = {}): Command => ({ state, commands }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
const toggleType = getNodeType(toggleTypeOrName, state.schema)
|
||||
const isActive = nodeIsActive(state, type, attrs)
|
||||
|
||||
if (isActive) {
|
||||
return commands.setBlockType(toggleType)
|
||||
}
|
||||
|
||||
return commands.setBlockType(type, attrs)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
ToggleBlockType: typeof ToggleBlockType,
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
import { findParentNode } from 'prosemirror-utils'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
import isList from '../utils/isList'
|
||||
|
||||
export const ToggleList = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
toggleList: (listTypeOrName: string | NodeType, itemTypeOrName: string | NodeType): Command => ({
|
||||
tr, state, dispatch, chain, commands, can,
|
||||
}) => {
|
||||
const { extensions } = this.editor.options
|
||||
const listType = getNodeType(listTypeOrName, state.schema)
|
||||
const itemType = getNodeType(itemTypeOrName, state.schema)
|
||||
const { selection } = state
|
||||
const { $from, $to } = selection
|
||||
const range = $from.blockRange($to)
|
||||
|
||||
if (!range) {
|
||||
return false
|
||||
}
|
||||
|
||||
const parentList = findParentNode(node => isList(node.type.name, extensions))(selection)
|
||||
|
||||
if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) {
|
||||
// remove list
|
||||
if (parentList.node.type === listType) {
|
||||
return commands.liftListItem(itemType)
|
||||
}
|
||||
|
||||
// change list type
|
||||
if (
|
||||
isList(parentList.node.type.name, extensions)
|
||||
&& listType.validContent(parentList.node.content)
|
||||
&& dispatch
|
||||
) {
|
||||
tr.setNodeMarkup(parentList.pos, listType)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const canWrapInList = can().wrapInList(listType)
|
||||
|
||||
// try to convert node to paragraph if needed
|
||||
if (!canWrapInList) {
|
||||
return chain()
|
||||
.clearNodes()
|
||||
.wrapInList(listType)
|
||||
.run()
|
||||
}
|
||||
|
||||
return commands.wrapInList(listType)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
ToggleList: typeof ToggleList,
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { toggleMark as originalToggleMark } from 'prosemirror-commands'
|
||||
import { MarkType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import getMarkType from '../utils/getMarkType'
|
||||
|
||||
export const ToggleMark = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
toggleMark: (typeOrName: string | MarkType): Command => ({ state, dispatch }) => {
|
||||
const type = getMarkType(typeOrName, state.schema)
|
||||
|
||||
return originalToggleMark(type)(state, dispatch)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
ToggleMark: typeof ToggleMark,
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
import { wrapIn, lift } from 'prosemirror-commands'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import nodeIsActive from '../utils/nodeIsActive'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export const ToggleWrap = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
toggleWrap: (typeOrName: string | NodeType, attrs = {}): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
const isActive = nodeIsActive(state, type, attrs)
|
||||
|
||||
if (isActive) {
|
||||
return lift(state, dispatch)
|
||||
}
|
||||
|
||||
return wrapIn(type, attrs)(state, dispatch)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
ToggleWrap: typeof ToggleWrap,
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
import { MarkType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import getMarkType from '../utils/getMarkType'
|
||||
import getMarkRange from '../utils/getMarkRange'
|
||||
|
||||
export const UpdateMark = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
updateMark: (typeOrName: string | MarkType, attrs: {}): Command => ({ tr, state, dispatch }) => {
|
||||
const { selection, doc } = tr
|
||||
let { from, to } = selection
|
||||
const { $from, empty } = selection
|
||||
const type = getMarkType(typeOrName, state.schema)
|
||||
|
||||
if (empty) {
|
||||
const range = getMarkRange($from, type)
|
||||
|
||||
if (range) {
|
||||
from = range.from
|
||||
to = range.to
|
||||
}
|
||||
}
|
||||
|
||||
const hasMark = doc.rangeHasMark(from, to, type)
|
||||
|
||||
if (hasMark && dispatch) {
|
||||
tr.removeMark(from, to, type)
|
||||
}
|
||||
|
||||
if (dispatch) {
|
||||
tr.addMark(from, to, type.create(attrs))
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
UpdateMark: typeof UpdateMark,
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { wrapInList } from 'prosemirror-schema-list'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
import { Command } from '../Editor'
|
||||
import { createExtension } from '../Extension'
|
||||
import getNodeType from '../utils/getNodeType'
|
||||
|
||||
export const WrapInList = createExtension({
|
||||
addCommands() {
|
||||
return {
|
||||
wrapInList: (typeOrName: string | NodeType, attrs?: {}): Command => ({ state, dispatch }) => {
|
||||
const type = getNodeType(typeOrName, state.schema)
|
||||
|
||||
return wrapInList(type, attrs)(state, dispatch)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
declare module '../Editor' {
|
||||
interface AllExtensions {
|
||||
WrapInList: typeof WrapInList,
|
||||
}
|
||||
}
|
@ -16,9 +16,11 @@ function getMarksBetween(start: number, end: number, state: EditorState) {
|
||||
return marks
|
||||
}
|
||||
|
||||
export default function (regexp: RegExp, markType: MarkType, getAttrs?: Function) {
|
||||
export default function (regexp: RegExp, markType: MarkType, getAttributes?: Function) {
|
||||
return new InputRule(regexp, (state, match, start, end) => {
|
||||
const attributes = getAttrs instanceof Function ? getAttrs(match) : getAttrs
|
||||
const attributes = getAttributes instanceof Function
|
||||
? getAttributes(match)
|
||||
: getAttributes
|
||||
const { tr } = state
|
||||
const captureGroup = match[match.length - 1]
|
||||
const fullMatch = match[0]
|
||||
|
@ -1,13 +1,15 @@
|
||||
import { InputRule } from 'prosemirror-inputrules'
|
||||
import { NodeType } from 'prosemirror-model'
|
||||
|
||||
export default function (regexp: RegExp, type: NodeType, getAttrs?: (match: any) => any): InputRule {
|
||||
export default function (regexp: RegExp, type: NodeType, getAttributes?: (match: any) => any): InputRule {
|
||||
return new InputRule(regexp, (state, match, start, end) => {
|
||||
const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs
|
||||
const attributes = getAttributes instanceof Function
|
||||
? getAttributes(match)
|
||||
: getAttributes
|
||||
const { tr } = state
|
||||
|
||||
if (match[0]) {
|
||||
tr.replaceWith(start - 1, end, type.create(attrs))
|
||||
tr.replaceWith(start - 1, end, type.create(attributes))
|
||||
}
|
||||
|
||||
return tr
|
||||
|
@ -4,11 +4,11 @@ import { wrappingInputRule } from 'prosemirror-inputrules'
|
||||
export const inputRegex = /^\s*([-+*])\s$/
|
||||
|
||||
const BulletList = createNode({
|
||||
name: 'bullet_list',
|
||||
name: 'bulletList',
|
||||
|
||||
group: 'block list',
|
||||
|
||||
content: 'list_item+',
|
||||
content: 'listItem+',
|
||||
|
||||
parseHTML() {
|
||||
return [
|
||||
@ -23,7 +23,7 @@ const BulletList = createNode({
|
||||
addCommands() {
|
||||
return {
|
||||
bulletList: (): Command => ({ commands }) => {
|
||||
return commands.toggleList('bullet_list', 'list_item')
|
||||
return commands.toggleList('bulletList', 'listItem')
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Command, createNode } from '@tiptap/core'
|
||||
import { chainCommands, exitCode } from 'prosemirror-commands'
|
||||
import { exitCode } from 'prosemirror-commands'
|
||||
|
||||
const HardBreak = createNode({
|
||||
name: 'hardBreak',
|
||||
@ -22,19 +22,17 @@ const HardBreak = createNode({
|
||||
|
||||
addCommands() {
|
||||
return {
|
||||
hardBreak: (): Command => ({ state, dispatch, view }) => {
|
||||
return chainCommands(
|
||||
exitCode,
|
||||
(_, d) => {
|
||||
if (typeof d !== 'function') {
|
||||
return false
|
||||
hardBreak: (): Command => ({ commands, state, dispatch }) => {
|
||||
return commands.try([
|
||||
() => exitCode(state, dispatch),
|
||||
() => {
|
||||
if (dispatch) {
|
||||
state.tr.replaceSelectionWith(this.type.create()).scrollIntoView()
|
||||
}
|
||||
|
||||
d(state.tr.replaceSelectionWith(this.type.create()).scrollIntoView())
|
||||
|
||||
return true
|
||||
},
|
||||
)(state, dispatch, view)
|
||||
])
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { createNode } from '@tiptap/core'
|
||||
|
||||
const ListItem = createNode({
|
||||
name: 'list_item',
|
||||
name: 'listItem',
|
||||
|
||||
content: '(paragraph|list?)+',
|
||||
|
||||
@ -21,9 +21,9 @@ const ListItem = createNode({
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Enter: () => this.editor.splitListItem('list_item'),
|
||||
Tab: () => this.editor.sinkListItem('list_item'),
|
||||
'Shift-Tab': () => this.editor.liftListItem('list_item'),
|
||||
Enter: () => this.editor.splitListItem('listItem'),
|
||||
Tab: () => this.editor.sinkListItem('listItem'),
|
||||
'Shift-Tab': () => this.editor.liftListItem('listItem'),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -4,11 +4,11 @@ import { wrappingInputRule } from 'prosemirror-inputrules'
|
||||
export const inputRegex = /^(\d+)\.\s$/
|
||||
|
||||
const OrderedList = createNode({
|
||||
name: 'ordered_list',
|
||||
name: 'orderedList',
|
||||
|
||||
group: 'block list',
|
||||
|
||||
content: 'list_item+',
|
||||
content: 'listItem+',
|
||||
|
||||
addAttributes() {
|
||||
return {
|
||||
@ -42,7 +42,7 @@ const OrderedList = createNode({
|
||||
addCommands() {
|
||||
return {
|
||||
orderedList: (): Command => ({ commands }) => {
|
||||
return commands.toggleList('ordered_list', 'list_item')
|
||||
return commands.toggleList('orderedList', 'listItem')
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -8,7 +8,7 @@ export interface TaskItemOptions {
|
||||
}
|
||||
|
||||
const TaskItem = createNode({
|
||||
name: 'task_item',
|
||||
name: 'taskItem',
|
||||
|
||||
content() {
|
||||
return this.options.nested ? '(paragraph|task_list)+' : 'paragraph+'
|
||||
@ -37,20 +37,20 @@ const TaskItem = createNode({
|
||||
parseHTML() {
|
||||
return [
|
||||
{
|
||||
tag: 'li[data-type="task_item"]',
|
||||
tag: 'li[data-type="taskItem"]',
|
||||
priority: 51,
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
renderHTML({ attributes }) {
|
||||
return ['li', mergeAttributes(attributes, { 'data-type': 'task_item' }), 0]
|
||||
return ['li', mergeAttributes(attributes, { 'data-type': 'taskItem' }), 0]
|
||||
},
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
const shortcuts = {
|
||||
Enter: () => this.editor.splitListItem('task_item'),
|
||||
'Shift-Tab': () => this.editor.liftListItem('task_item'),
|
||||
Enter: () => this.editor.splitListItem('taskItem'),
|
||||
'Shift-Tab': () => this.editor.liftListItem('taskItem'),
|
||||
}
|
||||
|
||||
if (!this.options.nested) {
|
||||
@ -59,7 +59,7 @@ const TaskItem = createNode({
|
||||
|
||||
return {
|
||||
...shortcuts,
|
||||
Tab: () => this.editor.sinkListItem('task_item'),
|
||||
Tab: () => this.editor.sinkListItem('taskItem'),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -5,7 +5,7 @@ const TaskList = createNode({
|
||||
|
||||
group: 'block list',
|
||||
|
||||
content: 'task_item+',
|
||||
content: 'taskItem+',
|
||||
|
||||
parseHTML() {
|
||||
return [
|
||||
@ -23,7 +23,7 @@ const TaskList = createNode({
|
||||
addCommands() {
|
||||
return {
|
||||
taskList: (): Command => ({ commands }) => {
|
||||
return commands.toggleList('task_list', 'task_item')
|
||||
return commands.toggleList('task_list', 'taskItem')
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -49,7 +49,9 @@ const TextAlign = createExtension({
|
||||
// TODO: re-use only 'textAlign' attribute
|
||||
// TODO: use custom splitBlock only for `this.options.types`
|
||||
// TODO: use complete default enter handler (chainCommand) with custom splitBlock
|
||||
Enter: () => this.editor.splitBlock(true),
|
||||
Enter: () => this.editor.splitBlock({
|
||||
withAttributes: true,
|
||||
}),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
252
yarn.lock
252
yarn.lock
@ -9,10 +9,10 @@
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.10.4"
|
||||
|
||||
"@babel/compat-data@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.1.tgz#d7386a689aa0ddf06255005b4b991988021101a0"
|
||||
integrity sha512-725AQupWJZ8ba0jbKceeFblZTY90McUBWMwHhkFQ9q1zKPJ95GUktljFcgcsIVwRnTnRKlcYzfiNImg5G9m6ZQ==
|
||||
"@babel/compat-data@^7.12.1", "@babel/compat-data@^7.12.5":
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.5.tgz#f56db0c4bb1bbbf221b4e81345aab4141e7cb0e9"
|
||||
integrity sha512-DTsS7cxrsH3by8nqQSpFSyjSfSYl57D6Cf4q8dW3LK83tBKBDCkfcay1nYkXq1nIHXnpX8WMMb/O25HOy3h1zg==
|
||||
|
||||
"@babel/core@^7.0.0", "@babel/core@^7.10.2", "@babel/core@^7.11.0", "@babel/core@^7.11.6":
|
||||
version "7.12.3"
|
||||
@ -36,12 +36,12 @@
|
||||
semver "^5.4.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.1.tgz#0d70be32bdaa03d7c51c8597dda76e0df1f15468"
|
||||
integrity sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg==
|
||||
"@babel/generator@^7.12.1", "@babel/generator@^7.12.5":
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.5.tgz#a2c50de5c8b6d708ab95be5e6053936c1884a4de"
|
||||
integrity sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==
|
||||
dependencies:
|
||||
"@babel/types" "^7.12.1"
|
||||
"@babel/types" "^7.12.5"
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
@ -78,13 +78,13 @@
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/helper-compilation-targets@^7.12.1", "@babel/helper-compilation-targets@^7.9.6":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.1.tgz#310e352888fbdbdd8577be8dfdd2afb9e7adcf50"
|
||||
integrity sha512-jtBEif7jsPwP27GPHs06v4WBV0KrE8a/P7n0N0sSvHn2hwUCYnolP/CLmz51IzAW4NlN+HuoBtb9QcwnRo9F/g==
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831"
|
||||
integrity sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==
|
||||
dependencies:
|
||||
"@babel/compat-data" "^7.12.1"
|
||||
"@babel/compat-data" "^7.12.5"
|
||||
"@babel/helper-validator-option" "^7.12.1"
|
||||
browserslist "^4.12.0"
|
||||
browserslist "^4.14.5"
|
||||
semver "^5.5.0"
|
||||
|
||||
"@babel/helper-create-class-features-plugin@^7.12.1", "@babel/helper-create-class-features-plugin@^7.7.4":
|
||||
@ -154,11 +154,11 @@
|
||||
"@babel/types" "^7.12.1"
|
||||
|
||||
"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.8.3":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.1.tgz#1644c01591a15a2f084dd6d092d9430eb1d1216c"
|
||||
integrity sha512-ZeC1TlMSvikvJNy1v/wPIazCu3NdOwgYZLIkmIyAsGhqkNpiDoQQRmaCK8YP4Pq3GPTLPV9WXaPCJKvx06JxKA==
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb"
|
||||
integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.12.1"
|
||||
"@babel/types" "^7.12.5"
|
||||
|
||||
"@babel/helper-module-transforms@^7.12.1":
|
||||
version "7.12.1"
|
||||
@ -204,14 +204,14 @@
|
||||
"@babel/types" "^7.12.1"
|
||||
|
||||
"@babel/helper-replace-supers@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.1.tgz#f15c9cc897439281891e11d5ce12562ac0cf3fa9"
|
||||
integrity sha512-zJjTvtNJnCFsCXVi5rUInstLd/EIVNmIKA1Q9ynESmMBWPWd+7sdR+G4/wdu+Mppfep0XLyG2m7EBPvjCeFyrw==
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz#f009a17543bbbbce16b06206ae73b63d3fca68d9"
|
||||
integrity sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==
|
||||
dependencies:
|
||||
"@babel/helper-member-expression-to-functions" "^7.12.1"
|
||||
"@babel/helper-optimise-call-expression" "^7.10.4"
|
||||
"@babel/traverse" "^7.12.1"
|
||||
"@babel/types" "^7.12.1"
|
||||
"@babel/traverse" "^7.12.5"
|
||||
"@babel/types" "^7.12.5"
|
||||
|
||||
"@babel/helper-simple-access@^7.12.1":
|
||||
version "7.12.1"
|
||||
@ -255,13 +255,13 @@
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/helpers@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.1.tgz#8a8261c1d438ec18cb890434df4ec768734c1e79"
|
||||
integrity sha512-9JoDSBGoWtmbay98efmT2+mySkwjzeFeAL9BuWNoVQpkPFQF8SIIFUfY5os9u8wVzglzoiPRSW7cuJmBDUt43g==
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e"
|
||||
integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==
|
||||
dependencies:
|
||||
"@babel/template" "^7.10.4"
|
||||
"@babel/traverse" "^7.12.1"
|
||||
"@babel/types" "^7.12.1"
|
||||
"@babel/traverse" "^7.12.5"
|
||||
"@babel/types" "^7.12.5"
|
||||
|
||||
"@babel/highlight@^7.10.4":
|
||||
version "7.10.4"
|
||||
@ -272,10 +272,10 @@
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@^7.0.0", "@babel/parser@^7.10.4", "@babel/parser@^7.12.0", "@babel/parser@^7.12.1", "@babel/parser@^7.12.3", "@babel/parser@^7.3.3":
|
||||
version "7.12.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd"
|
||||
integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw==
|
||||
"@babel/parser@^7.0.0", "@babel/parser@^7.10.4", "@babel/parser@^7.12.0", "@babel/parser@^7.12.3", "@babel/parser@^7.12.5", "@babel/parser@^7.3.3":
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.5.tgz#b4af32ddd473c0bfa643bd7ff0728b8e71b81ea0"
|
||||
integrity sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==
|
||||
|
||||
"@babel/plugin-proposal-async-generator-functions@^7.12.1":
|
||||
version "7.12.1"
|
||||
@ -352,9 +352,9 @@
|
||||
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
|
||||
|
||||
"@babel/plugin-proposal-numeric-separator@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.1.tgz#0e2c6774c4ce48be412119b4d693ac777f7685a6"
|
||||
integrity sha512-MR7Ok+Af3OhNTCxYVjJZHS0t97ydnJZt/DbR4WISO39iDnhiD8XHrY12xuSJ90FFEGjir0Fzyyn7g/zY6hxbxA==
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.5.tgz#b1ce757156d40ed79d59d467cb2b154a5c4149ba"
|
||||
integrity sha512-UiAnkKuOrCyjZ3sYNHlRlfuZJbBHknMQ9VMwVeX97Ofwx7RpD6gS2HfqTCh8KNUQgcOm8IKt103oR4KIjh7Q8g==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.10.4"
|
||||
"@babel/plugin-syntax-numeric-separator" "^7.10.4"
|
||||
@ -712,10 +712,10 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.10.4"
|
||||
|
||||
"@babel/plugin-transform-react-jsx-development@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.1.tgz#0b8f8cd531dcf7991f1e5f2c10a2a4f1cfc78e36"
|
||||
integrity sha512-IilcGWdN1yNgEGOrB96jbTplRh+V2Pz1EoEwsKsHfX1a/L40cUYuD71Zepa7C+ujv7kJIxnDftWeZbKNEqZjCQ==
|
||||
"@babel/plugin-transform-react-jsx-development@^7.12.5":
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.5.tgz#677de5b96da310430d6cfb7fee16a1603afa3d56"
|
||||
integrity sha512-1JJusg3iPgsZDthyWiCr3KQiGs31ikU/mSf2N2dSYEAO0GEImmVUbWf0VoSDGDFTAn5Dj4DUiR6SdIXHY7tELA==
|
||||
dependencies:
|
||||
"@babel/helper-builder-react-jsx-experimental" "^7.12.1"
|
||||
"@babel/helper-plugin-utils" "^7.10.4"
|
||||
@ -735,10 +735,10 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.10.4"
|
||||
|
||||
"@babel/plugin-transform-react-jsx@^7.10.1", "@babel/plugin-transform-react-jsx@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.1.tgz#c2d96c77c2b0e4362cc4e77a43ce7c2539d478cb"
|
||||
integrity sha512-RmKejwnT0T0QzQUzcbP5p1VWlpnP8QHtdhEtLG55ZDQnJNalbF3eeDyu3dnGKvGzFIQiBzFhBYTwvv435p9Xpw==
|
||||
"@babel/plugin-transform-react-jsx@^7.10.1", "@babel/plugin-transform-react-jsx@^7.12.5":
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.5.tgz#39ede0e30159770561b6963be143e40af3bde00c"
|
||||
integrity sha512-2xkcPqqrYiOQgSlM/iwto1paPijjsDbUynN13tI6bosDz/jOW3CRzYguIE8wKX32h+msbBM22Dv5fwrFkUOZjQ==
|
||||
dependencies:
|
||||
"@babel/helper-builder-react-jsx" "^7.10.4"
|
||||
"@babel/helper-builder-react-jsx-experimental" "^7.12.1"
|
||||
@ -921,22 +921,22 @@
|
||||
esutils "^2.0.2"
|
||||
|
||||
"@babel/preset-react@^7.10.4":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.12.1.tgz#7f022b13f55b6dd82f00f16d1c599ae62985358c"
|
||||
integrity sha512-euCExymHCi0qB9u5fKw7rvlw7AZSjw/NaB9h7EkdTt5+yHRrXdiRTh7fkG3uBPpJg82CqLfp1LHLqWGSCrab+g==
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.12.5.tgz#d45625f65d53612078a43867c5c6750e78772c56"
|
||||
integrity sha512-jcs++VPrgyFehkMezHtezS2BpnUlR7tQFAyesJn1vGTO9aTFZrgIQrA5YydlTwxbcjMwkFY6i04flCigRRr3GA==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.10.4"
|
||||
"@babel/plugin-transform-react-display-name" "^7.12.1"
|
||||
"@babel/plugin-transform-react-jsx" "^7.12.1"
|
||||
"@babel/plugin-transform-react-jsx-development" "^7.12.1"
|
||||
"@babel/plugin-transform-react-jsx" "^7.12.5"
|
||||
"@babel/plugin-transform-react-jsx-development" "^7.12.5"
|
||||
"@babel/plugin-transform-react-jsx-self" "^7.12.1"
|
||||
"@babel/plugin-transform-react-jsx-source" "^7.12.1"
|
||||
"@babel/plugin-transform-react-pure-annotations" "^7.12.1"
|
||||
|
||||
"@babel/runtime@^7.11.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740"
|
||||
integrity sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
|
||||
integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
@ -949,25 +949,25 @@
|
||||
"@babel/parser" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/traverse@^7.0.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e"
|
||||
integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw==
|
||||
"@babel/traverse@^7.0.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.5":
|
||||
version "7.12.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.5.tgz#78a0c68c8e8a35e4cacfd31db8bb303d5606f095"
|
||||
integrity sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/generator" "^7.12.1"
|
||||
"@babel/generator" "^7.12.5"
|
||||
"@babel/helper-function-name" "^7.10.4"
|
||||
"@babel/helper-split-export-declaration" "^7.11.0"
|
||||
"@babel/parser" "^7.12.1"
|
||||
"@babel/types" "^7.12.1"
|
||||
"@babel/parser" "^7.12.5"
|
||||
"@babel/types" "^7.12.5"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.19"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.0", "@babel/types@^7.12.1", "@babel/types@^7.4.4":
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae"
|
||||
integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.0", "@babel/types@^7.12.1", "@babel/types@^7.12.5", "@babel/types@^7.4.4":
|
||||
version "7.12.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.6.tgz#ae0e55ef1cce1fbc881cd26f8234eb3e657edc96"
|
||||
integrity sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.10.4"
|
||||
lodash "^4.17.19"
|
||||
@ -2411,60 +2411,60 @@
|
||||
"@types/vfile-message" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^4.6.0":
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.6.0.tgz#210cd538bb703f883aff81d3996961f5dba31fdb"
|
||||
integrity sha512-1+419X+Ynijytr1iWI+/IcX/kJryc78YNpdaXR1aRO1sU3bC0vZrIAF1tIX7rudVI84W7o7M4zo5p1aVt70fAg==
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.6.1.tgz#99d77eb7a016fd5a5e749d2c44a7e4c317eb7da3"
|
||||
integrity sha512-SNZyflefTMK2JyrPfFFzzoy2asLmZvZJ6+/L5cIqg4HfKGiW2Gr1Go1OyEVqne/U4QwmoasuMwppoBHWBWF2nA==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "4.6.0"
|
||||
"@typescript-eslint/scope-manager" "4.6.0"
|
||||
"@typescript-eslint/experimental-utils" "4.6.1"
|
||||
"@typescript-eslint/scope-manager" "4.6.1"
|
||||
debug "^4.1.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
regexpp "^3.0.0"
|
||||
semver "^7.3.2"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@typescript-eslint/experimental-utils@4.6.0":
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.6.0.tgz#f750aef4dd8e5970b5c36084f0a5ca2f0db309a4"
|
||||
integrity sha512-pnh6Beh2/4xjJVNL+keP49DFHk3orDHHFylSp3WEjtgW3y1U+6l+jNnJrGlbs6qhAz5z96aFmmbUyKhunXKvKw==
|
||||
"@typescript-eslint/experimental-utils@4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.6.1.tgz#a9c691dfd530a9570274fe68907c24c07a06c4aa"
|
||||
integrity sha512-qyPqCFWlHZXkEBoV56UxHSoXW2qnTr4JrWVXOh3soBP3q0o7p4pUEMfInDwIa0dB/ypdtm7gLOS0hg0a73ijfg==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.3"
|
||||
"@typescript-eslint/scope-manager" "4.6.0"
|
||||
"@typescript-eslint/types" "4.6.0"
|
||||
"@typescript-eslint/typescript-estree" "4.6.0"
|
||||
"@typescript-eslint/scope-manager" "4.6.1"
|
||||
"@typescript-eslint/types" "4.6.1"
|
||||
"@typescript-eslint/typescript-estree" "4.6.1"
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^2.0.0"
|
||||
|
||||
"@typescript-eslint/parser@^4.6.0":
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.6.0.tgz#7e9ff7df2f21d5c8f65f17add3b99eeeec33199d"
|
||||
integrity sha512-Dj6NJxBhbdbPSZ5DYsQqpR32MwujF772F2H3VojWU6iT4AqL4BKuoNWOPFCoSZvCcADDvQjDpa6OLDAaiZPz2Q==
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.6.1.tgz#b801bff67b536ecc4a840ac9289ba2be57e02428"
|
||||
integrity sha512-lScKRPt1wM9UwyKkGKyQDqf0bh6jm8DQ5iN37urRIXDm16GEv+HGEmum2Fc423xlk5NUOkOpfTnKZc/tqKZkDQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "4.6.0"
|
||||
"@typescript-eslint/types" "4.6.0"
|
||||
"@typescript-eslint/typescript-estree" "4.6.0"
|
||||
"@typescript-eslint/scope-manager" "4.6.1"
|
||||
"@typescript-eslint/types" "4.6.1"
|
||||
"@typescript-eslint/typescript-estree" "4.6.1"
|
||||
debug "^4.1.1"
|
||||
|
||||
"@typescript-eslint/scope-manager@4.6.0":
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.6.0.tgz#b7d8b57fe354047a72dfb31881d9643092838662"
|
||||
integrity sha512-uZx5KvStXP/lwrMrfQQwDNvh2ppiXzz5TmyTVHb+5TfZ3sUP7U1onlz3pjoWrK9konRyFe1czyxObWTly27Ang==
|
||||
"@typescript-eslint/scope-manager@4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.6.1.tgz#21872b91cbf7adfc7083f17b8041149148baf992"
|
||||
integrity sha512-f95+80r6VdINYscJY1KDUEDcxZ3prAWHulL4qRDfNVD0I5QAVSGqFkwHERDoLYJJWmEAkUMdQVvx7/c2Hp+Bjg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.6.0"
|
||||
"@typescript-eslint/visitor-keys" "4.6.0"
|
||||
"@typescript-eslint/types" "4.6.1"
|
||||
"@typescript-eslint/visitor-keys" "4.6.1"
|
||||
|
||||
"@typescript-eslint/types@4.6.0":
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.6.0.tgz#157ca925637fd53c193c6bf226a6c02b752dde2f"
|
||||
integrity sha512-5FAgjqH68SfFG4UTtIFv+rqYJg0nLjfkjD0iv+5O27a0xEeNZ5rZNDvFGZDizlCD1Ifj7MAbSW2DPMrf0E9zjA==
|
||||
"@typescript-eslint/types@4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.6.1.tgz#d3ad7478f53f22e7339dc006ab61aac131231552"
|
||||
integrity sha512-k2ZCHhJ96YZyPIsykickez+OMHkz06xppVLfJ+DY90i532/Cx2Z+HiRMH8YZQo7a4zVd/TwNBuRCdXlGK4yo8w==
|
||||
|
||||
"@typescript-eslint/typescript-estree@4.6.0":
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.6.0.tgz#85bd98dcc8280511cfc5b2ce7b03a9ffa1732b08"
|
||||
integrity sha512-s4Z9qubMrAo/tw0CbN0IN4AtfwuehGXVZM0CHNMdfYMGBDhPdwTEpBrecwhP7dRJu6d9tT9ECYNaWDHvlFSngA==
|
||||
"@typescript-eslint/typescript-estree@4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.6.1.tgz#6025cce724329413f57e4959b2d676fceeca246f"
|
||||
integrity sha512-/J/kxiyjQQKqEr5kuKLNQ1Finpfb8gf/NpbwqFFYEBjxOsZ621r9AqwS9UDRA1Rrr/eneX/YsbPAIhU2rFLjXQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.6.0"
|
||||
"@typescript-eslint/visitor-keys" "4.6.0"
|
||||
"@typescript-eslint/types" "4.6.1"
|
||||
"@typescript-eslint/visitor-keys" "4.6.1"
|
||||
debug "^4.1.1"
|
||||
globby "^11.0.1"
|
||||
is-glob "^4.0.1"
|
||||
@ -2472,12 +2472,12 @@
|
||||
semver "^7.3.2"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@typescript-eslint/visitor-keys@4.6.0":
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.6.0.tgz#fb05d6393891b0a089b243fc8f9fb8039383d5da"
|
||||
integrity sha512-38Aa9Ztl0XyFPVzmutHXqDMCu15Xx8yKvUo38Gu3GhsuckCh3StPI5t2WIO9LHEsOH7MLmlGfKUisU8eW1Sjhg==
|
||||
"@typescript-eslint/visitor-keys@4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.6.1.tgz#6b125883402d8939df7b54528d879e88f7ba3614"
|
||||
integrity sha512-owABze4toX7QXwOLT3/D5a8NecZEjEWU1srqxENTfqsY3bwVnl3YYbOh6s1rp2wQKO9RTHFGjKes08FgE7SVMw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.6.0"
|
||||
"@typescript-eslint/types" "4.6.1"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
|
||||
"@vue/babel-helper-vue-jsx-merge-props@^1.2.1":
|
||||
@ -3588,7 +3588,7 @@ browserify-zlib@^0.2.0:
|
||||
dependencies:
|
||||
pako "~1.0.5"
|
||||
|
||||
browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.8.5:
|
||||
browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.8.5:
|
||||
version "4.14.6"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.6.tgz#97702a9c212e0c6b6afefad913d3a1538e348457"
|
||||
integrity sha512-zeFYcUo85ENhc/zxHbiIp0LGzzTrE2Pv2JhxvS7kpUb9Q9D38kUX6Bie7pGutJ/5iF5rOxE7CepAuWD56xJ33A==
|
||||
@ -5428,9 +5428,9 @@ ee-first@1.1.1:
|
||||
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
|
||||
|
||||
electron-to-chromium@^1.3.585:
|
||||
version "1.3.585"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.585.tgz#71cdb722c73488b9475ad1c572cf43a763ef9081"
|
||||
integrity sha512-xoeqjMQhgHDZM7FiglJAb2aeOxHZWFruUc3MbAGTgE7GB8rr5fTn1Sdh5THGuQtndU3GuXlu91ZKqRivxoCZ/A==
|
||||
version "1.3.588"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.588.tgz#c6515571737bfb42678115a5eaa818384593a9a5"
|
||||
integrity sha512-0zr+ZfytnLeJZxGgmEpPTcItu5Mm4A5zHPZXLfHcGp0mdsk95rmD7ePNewYtK1yIdLbk8Z1U2oTRRfOtR4gbYg==
|
||||
|
||||
elegant-spinner@^1.0.1:
|
||||
version "1.0.1"
|
||||
@ -7897,9 +7897,9 @@ is-buffer@^1.1.5:
|
||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
||||
|
||||
is-buffer@^2.0.0:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
|
||||
integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
|
||||
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
|
||||
|
||||
is-callable@^1.1.4, is-callable@^1.2.2:
|
||||
version "1.2.2"
|
||||
@ -7926,9 +7926,9 @@ is-color-stop@^1.0.0:
|
||||
rgba-regex "^1.0.0"
|
||||
|
||||
is-core-module@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.0.0.tgz#58531b70aed1db7c0e8d4eb1a0a2d1ddd64bd12d"
|
||||
integrity sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.1.0.tgz#a4cc031d9b1aca63eecbd18a650e13cb4eeab946"
|
||||
integrity sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
@ -9018,9 +9018,9 @@ markdown-escapes@^1.0.0:
|
||||
integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==
|
||||
|
||||
marked@^1.1.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.2.tgz#5d77ffb789c4cb0ae828bfe76250f7140b123f70"
|
||||
integrity sha512-5jjKHVl/FPo0Z6ocP3zYhKiJLzkwJAw4CZoLjv57FkvbUuwOX4LIBBGGcXjAY6ATcd1q9B8UTj5T9Umauj0QYQ==
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.3.tgz#58817ba348a7c9398cb94d40d12e0d08df83af57"
|
||||
integrity sha512-RQuL2i6I6Gn+9n81IDNGbL0VHnta4a+8ZhqvryXEniTb/hQNtf3i26hi1XWUhzb9BgVyWHKR3UO8MaHtKoYibw==
|
||||
|
||||
maxmin@^2.1.0:
|
||||
version "2.1.0"
|
||||
@ -13608,9 +13608,9 @@ trough@^1.0.0:
|
||||
glob "^7.1.2"
|
||||
|
||||
ts-loader@^8.0.7:
|
||||
version "8.0.7"
|
||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.0.7.tgz#9ce70db5b3906cc9143a09c54ff5247d102ea974"
|
||||
integrity sha512-ooa4wxlZ9TOXaJ/iVyZlWsim79Ul4KyifSwyT2hOrbQA6NZJypsLOE198o8Ko+JV+ZHnMArvWcl4AnRqpCU/Mw==
|
||||
version "8.0.9"
|
||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.0.9.tgz#890fc25f49a99124268f4e738ed22d00f666dc37"
|
||||
integrity sha512-rQd+iIfz5z4HSVzhhRFP4M2OQ0QmihilWWauYvvowBfnRvr4DW+gqA2om70xp/07EQj1qBkLMWobnXsgmWMbmg==
|
||||
dependencies:
|
||||
chalk "^2.3.0"
|
||||
enhanced-resolve "^4.0.0"
|
||||
@ -13750,9 +13750,9 @@ uglify-js@3.4.x:
|
||||
source-map "~0.6.1"
|
||||
|
||||
uglify-js@^3.1.4:
|
||||
version "3.11.4"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.11.4.tgz#b47b7ae99d4bd1dca65b53aaa69caa0909e6fadf"
|
||||
integrity sha512-FyYnoxVL1D6+jDGQpbK5jW6y/2JlVfRfEeQ67BPCUg5wfCjaKOpr2XeceE4QL+MkhxliLtf5EbrMDZgzpt2CNw==
|
||||
version "3.11.5"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.11.5.tgz#d6788bc83cf35ff18ea78a65763e480803409bc6"
|
||||
integrity sha512-btvv/baMqe7HxP7zJSF7Uc16h1mSfuuSplT0/qdjxseesDU+yYzH33eHBH+eMdeRXwujXspaCTooWHQVVBh09w==
|
||||
|
||||
uid-number@0.0.6:
|
||||
version "0.0.6"
|
||||
@ -13871,9 +13871,9 @@ unist-builder@^1.0.1, unist-builder@^1.0.3, unist-builder@^1.0.4:
|
||||
object-assign "^4.1.0"
|
||||
|
||||
unist-util-generated@^1.1.0:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.5.tgz#1e903e68467931ebfaea386dae9ea253628acd42"
|
||||
integrity sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw==
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b"
|
||||
integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==
|
||||
|
||||
unist-util-is@^2.0.0:
|
||||
version "2.1.3"
|
||||
@ -14818,8 +14818,8 @@ yauzl@^2.10.0, yauzl@^2.4.2:
|
||||
fd-slicer "~1.1.0"
|
||||
|
||||
yjs@^13.4.1:
|
||||
version "13.4.2"
|
||||
resolved "https://registry.yarnpkg.com/yjs/-/yjs-13.4.2.tgz#565fff706064e6fe59b75cc08dd724b2ac4f3783"
|
||||
integrity sha512-HtlrDT55db2Gtu09UDijDCCH+7FLG2FX+TRP0ySZJZYPj22qkinS2oAcuzjKbsJ1Ed0RSJGSgUE6ImagFdMJvA==
|
||||
version "13.4.3"
|
||||
resolved "https://registry.yarnpkg.com/yjs/-/yjs-13.4.3.tgz#b10c63cbc4e6fd1bc3a7974965b75fefc72f70c3"
|
||||
integrity sha512-jHlk3SKz2gC/rO0WBEuyn8yxtxEjDDMuANQYLR7EJjdbYhbdKYiaoPsNsFOgMDy7u8R6i2N3gVIRcmXYrbAvzg==
|
||||
dependencies:
|
||||
lib0 "^0.2.33"
|
||||
|
Loading…
Reference in New Issue
Block a user