Merge branch 'main' of github.com:ueberdosis/tiptap-next into main
This commit is contained in:
@@ -82,7 +82,7 @@ export default {
|
|||||||
|
|
||||||
this.editor = new Editor({
|
this.editor = new Editor({
|
||||||
extensions: [
|
extensions: [
|
||||||
...defaultExtensions(),
|
...defaultExtensions().filter(extension => extension.config.name !== 'history'),
|
||||||
Collaboration.configure({
|
Collaboration.configure({
|
||||||
provider,
|
provider,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -63,7 +63,9 @@ export default {
|
|||||||
margin-top: 0.75em;
|
margin-top: 0.75em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
.toc {
|
.toc {
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
|
|||||||
@@ -27,15 +27,15 @@ export default {
|
|||||||
],
|
],
|
||||||
content: `
|
content: `
|
||||||
<toc></toc>
|
<toc></toc>
|
||||||
<h2>heading</h2>
|
<h2>1 heading</h2>
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
<h3>heading</h3>
|
<h3>1.1 heading</h3>
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
<h3>heading</h3>
|
<h3>1.2 heading</h3>
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
<h2>heading</h2>
|
<h2>2 heading</h2>
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
<h3>heading</h3>
|
<h3>2.1 heading</h3>
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ export default class CommandManager {
|
|||||||
const method = (...args: any) => {
|
const method = (...args: any) => {
|
||||||
const callback = command(...args)(props)
|
const callback = command(...args)(props)
|
||||||
|
|
||||||
view.dispatch(tr)
|
if (tr.steps.length) {
|
||||||
|
view.dispatch(tr)
|
||||||
|
}
|
||||||
|
|
||||||
return callback
|
return callback
|
||||||
}
|
}
|
||||||
@@ -68,12 +70,11 @@ export default class CommandManager {
|
|||||||
const callbacks: boolean[] = []
|
const callbacks: boolean[] = []
|
||||||
const hasStartTransaction = !!startTr
|
const hasStartTransaction = !!startTr
|
||||||
const tr = startTr || state.tr
|
const tr = startTr || state.tr
|
||||||
const props = this.buildProps(tr, shouldDispatch)
|
|
||||||
|
|
||||||
return new Proxy({}, {
|
return new Proxy({}, {
|
||||||
get: (_, name: string, proxy) => {
|
get: (_, name: string, proxy) => {
|
||||||
if (name === 'run') {
|
if (name === 'run') {
|
||||||
if (!hasStartTransaction && shouldDispatch) {
|
if (!hasStartTransaction && shouldDispatch && tr.steps.length) {
|
||||||
view.dispatch(tr)
|
view.dispatch(tr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +88,9 @@ export default class CommandManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (...args: any) => {
|
return (...args: any) => {
|
||||||
|
const props = this.buildProps(tr, shouldDispatch)
|
||||||
const callback = command(...args)(props)
|
const callback = command(...args)(props)
|
||||||
|
|
||||||
callbacks.push(callback)
|
callbacks.push(callback)
|
||||||
|
|
||||||
return proxy
|
return proxy
|
||||||
@@ -118,6 +121,10 @@ export default class CommandManager {
|
|||||||
const { editor, commands } = this
|
const { editor, commands } = this
|
||||||
const { state, view } = editor
|
const { state, view } = editor
|
||||||
|
|
||||||
|
if (state.storedMarks) {
|
||||||
|
tr.setStoredMarks(state.storedMarks)
|
||||||
|
}
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
tr,
|
tr,
|
||||||
editor,
|
editor,
|
||||||
@@ -141,6 +148,10 @@ export default class CommandManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public chainableState(tr: Transaction, state: EditorState): EditorState {
|
public chainableState(tr: Transaction, state: EditorState): EditorState {
|
||||||
|
let { selection } = tr
|
||||||
|
let { doc } = tr
|
||||||
|
let { storedMarks } = tr
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
schema: state.schema,
|
schema: state.schema,
|
||||||
@@ -150,15 +161,19 @@ export default class CommandManager {
|
|||||||
reconfigure: state.reconfigure.bind(state),
|
reconfigure: state.reconfigure.bind(state),
|
||||||
toJSON: state.toJSON.bind(state),
|
toJSON: state.toJSON.bind(state),
|
||||||
get storedMarks() {
|
get storedMarks() {
|
||||||
return tr.storedMarks
|
return storedMarks
|
||||||
},
|
},
|
||||||
get selection() {
|
get selection() {
|
||||||
return tr.selection
|
return selection
|
||||||
},
|
},
|
||||||
get doc() {
|
get doc() {
|
||||||
return tr.doc
|
return doc
|
||||||
},
|
},
|
||||||
get tr() {
|
get tr() {
|
||||||
|
selection = tr.selection
|
||||||
|
doc = tr.doc
|
||||||
|
storedMarks = tr.storedMarks
|
||||||
|
|
||||||
return tr
|
return tr
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export interface ExtensionConfig<Options = any, Commands = {}> {
|
|||||||
/**
|
/**
|
||||||
* Name
|
* Name
|
||||||
*/
|
*/
|
||||||
name?: string,
|
name: string,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default options
|
* Default options
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ import * as wrapIn from '../commands/wrapIn'
|
|||||||
import * as wrapInList from '../commands/wrapInList'
|
import * as wrapInList from '../commands/wrapInList'
|
||||||
|
|
||||||
export const Commands = Extension.create({
|
export const Commands = Extension.create({
|
||||||
|
name: 'commands',
|
||||||
|
|
||||||
addCommands() {
|
addCommands() {
|
||||||
return {
|
return {
|
||||||
...blur,
|
...blur,
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { Plugin, PluginKey } from 'prosemirror-state'
|
|||||||
import { Extension } from '../Extension'
|
import { Extension } from '../Extension'
|
||||||
|
|
||||||
export const Editable = Extension.create({
|
export const Editable = Extension.create({
|
||||||
|
name: 'editable',
|
||||||
|
|
||||||
addProseMirrorPlugins() {
|
addProseMirrorPlugins() {
|
||||||
return [
|
return [
|
||||||
new Plugin({
|
new Plugin({
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { Plugin, PluginKey } from 'prosemirror-state'
|
|||||||
import { Extension } from '../Extension'
|
import { Extension } from '../Extension'
|
||||||
|
|
||||||
export const FocusEvents = Extension.create({
|
export const FocusEvents = Extension.create({
|
||||||
|
name: 'focusEvents',
|
||||||
|
|
||||||
addProseMirrorPlugins() {
|
addProseMirrorPlugins() {
|
||||||
const { editor } = this
|
const { editor } = this
|
||||||
|
|
||||||
@@ -16,7 +18,10 @@ export const FocusEvents = Extension.create({
|
|||||||
focus: (view, event) => {
|
focus: (view, event) => {
|
||||||
editor.isFocused = true
|
editor.isFocused = true
|
||||||
|
|
||||||
const transaction = editor.state.tr.setMeta('focus', { event })
|
const transaction = editor.state.tr
|
||||||
|
.setMeta('focus', { event })
|
||||||
|
.setMeta('addToHistory', false)
|
||||||
|
|
||||||
view.dispatch(transaction)
|
view.dispatch(transaction)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@@ -24,7 +29,10 @@ export const FocusEvents = Extension.create({
|
|||||||
blur: (view, event) => {
|
blur: (view, event) => {
|
||||||
editor.isFocused = false
|
editor.isFocused = false
|
||||||
|
|
||||||
const transaction = editor.state.tr.setMeta('blur', { event })
|
const transaction = editor.state.tr
|
||||||
|
.setMeta('blur', { event })
|
||||||
|
.setMeta('addToHistory', false)
|
||||||
|
|
||||||
view.dispatch(transaction)
|
view.dispatch(transaction)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import { undoInputRule } from 'prosemirror-inputrules'
|
|||||||
import { Extension } from '../Extension'
|
import { Extension } from '../Extension'
|
||||||
|
|
||||||
export const Keymap = Extension.create({
|
export const Keymap = Extension.create({
|
||||||
|
name: 'keymap',
|
||||||
|
|
||||||
addKeyboardShortcuts() {
|
addKeyboardShortcuts() {
|
||||||
const handleBackspace = () => this.editor.commands.first(({ state, dispatch }) => [
|
const handleBackspace = () => this.editor.commands.first(({ state, dispatch }) => [
|
||||||
() => undoInputRule(state, dispatch),
|
() => undoInputRule(state, dispatch),
|
||||||
|
|||||||
@@ -65,5 +65,5 @@ export default function isMarkActive(
|
|||||||
return sum + size
|
return sum + size
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|
||||||
return selectionRange === range
|
return range >= selectionRange
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,5 +63,5 @@ export default function isNodeActive(
|
|||||||
return sum + size
|
return sum + size
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|
||||||
return selectionRange === range
|
return range >= selectionRange
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ const awarenessStatesToArray = (states: Map<number, { [key: string]: any }>) =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
const CollaborationCursor = Extension.create({
|
const CollaborationCursor = Extension.create({
|
||||||
|
name: 'collaborationCursor',
|
||||||
|
|
||||||
defaultOptions: <CollaborationCursorOptions>{
|
defaultOptions: <CollaborationCursorOptions>{
|
||||||
provider: null,
|
provider: null,
|
||||||
user: {
|
user: {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Extension } from '@tiptap/core'
|
import { Extension, Command } from '@tiptap/core'
|
||||||
import {
|
import {
|
||||||
redo,
|
redo,
|
||||||
undo,
|
undo,
|
||||||
@@ -11,10 +11,37 @@ export interface CollaborationOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Collaboration = Extension.create({
|
const Collaboration = Extension.create({
|
||||||
|
name: 'collaboration',
|
||||||
|
|
||||||
defaultOptions: <CollaborationOptions>{
|
defaultOptions: <CollaborationOptions>{
|
||||||
provider: null,
|
provider: null,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addCommands() {
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* Undo recent changes
|
||||||
|
*/
|
||||||
|
undo: (): Command => ({ state }) => {
|
||||||
|
return undo(state)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Reapply reverted changes
|
||||||
|
*/
|
||||||
|
redo: (): Command => ({ state }) => {
|
||||||
|
return redo(state)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addKeyboardShortcuts() {
|
||||||
|
return {
|
||||||
|
'Mod-z': () => this.editor.commands.undo(),
|
||||||
|
'Mod-y': () => this.editor.commands.redo(),
|
||||||
|
'Shift-Mod-z': () => this.editor.commands.redo(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
addProseMirrorPlugins() {
|
addProseMirrorPlugins() {
|
||||||
return [
|
return [
|
||||||
ySyncPlugin(
|
ySyncPlugin(
|
||||||
@@ -24,14 +51,6 @@ const Collaboration = Extension.create({
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
addKeyboardShortcuts() {
|
|
||||||
return {
|
|
||||||
'Mod-z': undo,
|
|
||||||
'Mod-y': redo,
|
|
||||||
'Mod-Shift-z': redo,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onDestroy() {
|
onDestroy() {
|
||||||
this.options.provider?.destroy()
|
this.options.provider?.destroy()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export interface DropcursorOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Dropcursor = Extension.create({
|
const Dropcursor = Extension.create({
|
||||||
|
name: 'dropCursor',
|
||||||
|
|
||||||
defaultOptions: <DropcursorOptions>{
|
defaultOptions: <DropcursorOptions>{
|
||||||
color: 'black',
|
color: 'black',
|
||||||
width: 1,
|
width: 1,
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export interface FocusOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FocusClasses = Extension.create({
|
const FocusClasses = Extension.create({
|
||||||
|
name: 'focus',
|
||||||
|
|
||||||
defaultOptions: <FocusOptions>{
|
defaultOptions: <FocusOptions>{
|
||||||
className: 'has-focus',
|
className: 'has-focus',
|
||||||
nested: false,
|
nested: false,
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ type FontFamilyOptions = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FontFamily = Extension.create({
|
const FontFamily = Extension.create({
|
||||||
|
name: 'fontFamily',
|
||||||
|
|
||||||
defaultOptions: <FontFamilyOptions>{
|
defaultOptions: <FontFamilyOptions>{
|
||||||
types: ['textStyle'],
|
types: ['textStyle'],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { Extension } from '@tiptap/core'
|
|||||||
import { gapCursor } from 'prosemirror-gapcursor'
|
import { gapCursor } from 'prosemirror-gapcursor'
|
||||||
|
|
||||||
const Gapcursor = Extension.create({
|
const Gapcursor = Extension.create({
|
||||||
|
name: 'gapCursor',
|
||||||
|
|
||||||
addProseMirrorPlugins() {
|
addProseMirrorPlugins() {
|
||||||
return [
|
return [
|
||||||
gapCursor(),
|
gapCursor(),
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ export interface HistoryOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const History = Extension.create({
|
const History = Extension.create({
|
||||||
|
name: 'history',
|
||||||
|
|
||||||
defaultOptions: <HistoryOptions>{
|
defaultOptions: <HistoryOptions>{
|
||||||
depth: 100,
|
depth: 100,
|
||||||
newGroupDelay: 500,
|
newGroupDelay: 500,
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ type TextAlignOptions = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TextAlign = Extension.create({
|
const TextAlign = Extension.create({
|
||||||
|
name: 'textAlign',
|
||||||
|
|
||||||
defaultOptions: <TextAlignOptions>{
|
defaultOptions: <TextAlignOptions>{
|
||||||
types: ['heading', 'paragraph'],
|
types: ['heading', 'paragraph'],
|
||||||
alignments: ['left', 'center', 'right', 'justify'],
|
alignments: ['left', 'center', 'right', 'justify'],
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ export const raquo = new InputRule(/>>$/, '»')
|
|||||||
export const multiplication = new InputRule(/\d+\s?([*x])\s?\d+$/, '×')
|
export const multiplication = new InputRule(/\d+\s?([*x])\s?\d+$/, '×')
|
||||||
|
|
||||||
const Typography = Extension.create({
|
const Typography = Extension.create({
|
||||||
|
name: 'typography',
|
||||||
|
|
||||||
addInputRules() {
|
addInputRules() {
|
||||||
return [
|
return [
|
||||||
emDash,
|
emDash,
|
||||||
|
|||||||
Reference in New Issue
Block a user