Merge branch 'main' of github.com:ueberdosis/tiptap-next into main

This commit is contained in:
Hans Pagel
2020-12-02 09:57:10 +01:00
20 changed files with 92 additions and 26 deletions

View File

@@ -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,
}), }),

View File

@@ -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;

View File

@@ -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>
`, `,
}) })

View File

@@ -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
}, },
} }

View File

@@ -7,7 +7,7 @@ export interface ExtensionConfig<Options = any, Commands = {}> {
/** /**
* Name * Name
*/ */
name?: string, name: string,
/** /**
* Default options * Default options

View File

@@ -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,

View File

@@ -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({

View File

@@ -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

View File

@@ -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),

View File

@@ -65,5 +65,5 @@ export default function isMarkActive(
return sum + size return sum + size
}, 0) }, 0)
return selectionRange === range return range >= selectionRange
} }

View File

@@ -63,5 +63,5 @@ export default function isNodeActive(
return sum + size return sum + size
}, 0) }, 0)
return selectionRange === range return range >= selectionRange
} }

View File

@@ -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: {

View File

@@ -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()
}, },

View File

@@ -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,

View File

@@ -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,

View File

@@ -6,6 +6,8 @@ type FontFamilyOptions = {
} }
const FontFamily = Extension.create({ const FontFamily = Extension.create({
name: 'fontFamily',
defaultOptions: <FontFamilyOptions>{ defaultOptions: <FontFamilyOptions>{
types: ['textStyle'], types: ['textStyle'],
}, },

View File

@@ -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(),

View File

@@ -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,

View File

@@ -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'],

View File

@@ -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,