mirror of
https://github.com/ueberdosis/tiptap.git
synced 2024-12-01 01:19:03 +08:00
Merge branch 'main' of github.com:ueberdosis/tiptap-next
# Bitte geben Sie eine Commit-Beschreibung ein, um zu erklären, warum dieser # Merge erforderlich ist, insbesondere wenn es einen aktualisierten # Upstream-Branch mit einem Thema-Branch zusammenführt. # # Zeilen, die mit '#' beginnen, werden ignoriert, # und eine leere Beschreibung bricht den Commit ab.
This commit is contained in:
commit
a0ce975a51
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -32,7 +32,7 @@ jobs:
|
|||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
- name: Load cached dependencies
|
- name: Load cached dependencies
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2.1.4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
@ -144,7 +144,7 @@ jobs:
|
|||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
- name: Load cached dependencies
|
- name: Load cached dependencies
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2.1.4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -33,8 +33,8 @@ To check out some live examples, visit [next.tiptap.dev](https://next.tiptap.dev
|
|||||||
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
|
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
|
||||||
|
|
||||||
## Maintainers
|
## Maintainers
|
||||||
- [Philipp Kühn](https://github.com/philippkuehn) (development)
|
- [Philipp Kühn](https://github.com/philippkuehn) (developer)
|
||||||
- [Hans Pagel](https://github.com/hanspagel) (documentation)
|
- [Hans Pagel](https://github.com/hanspagel) (maintainer)
|
||||||
|
|
||||||
## Premium Sponsors
|
## Premium Sponsors
|
||||||
- [überdosis](https://ueberdosis.io/)
|
- [überdosis](https://ueberdosis.io/)
|
||||||
|
@ -177,7 +177,9 @@ Have a look at all of the core commands listed below. They should give you a goo
|
|||||||
| .blur() | Removes focus from the editor. |
|
| .blur() | Removes focus from the editor. |
|
||||||
| .deleteRange() | Delete a given range. |
|
| .deleteRange() | Delete a given range. |
|
||||||
| .deleteSelection() | Delete the selection, if there is one. |
|
| .deleteSelection() | Delete the selection, if there is one. |
|
||||||
|
| .enter() | Trigger enter. |
|
||||||
| .focus() | Focus the editor at the given position. |
|
| .focus() | Focus the editor at the given position. |
|
||||||
|
| .keyboardShortcut() | Trigger a keyboard shortcut. |
|
||||||
| .scrollIntoView() | Scroll the selection into view. |
|
| .scrollIntoView() | Scroll the selection into view. |
|
||||||
| .selectAll() | Select the whole document. |
|
| .selectAll() | Select the whole document. |
|
||||||
| .selectNodeBackward() | Select a node backward. |
|
| .selectNodeBackward() | Select a node backward. |
|
||||||
|
@ -307,12 +307,40 @@ export class Editor extends EventEmitter {
|
|||||||
return this.createDocument('')
|
return this.createDocument('')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isCapturingTransaction = false
|
||||||
|
|
||||||
|
private capturedTransaction: Transaction | null = null
|
||||||
|
|
||||||
|
public captureTransaction(fn: Function) {
|
||||||
|
this.isCapturingTransaction = true
|
||||||
|
fn()
|
||||||
|
this.isCapturingTransaction = false
|
||||||
|
|
||||||
|
const tr = this.capturedTransaction
|
||||||
|
|
||||||
|
this.capturedTransaction = null
|
||||||
|
|
||||||
|
return tr
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The callback over which to send transactions (state updates) produced by the view.
|
* The callback over which to send transactions (state updates) produced by the view.
|
||||||
*
|
*
|
||||||
* @param transaction An editor state transaction
|
* @param transaction An editor state transaction
|
||||||
*/
|
*/
|
||||||
private dispatchTransaction(transaction: Transaction): void {
|
private dispatchTransaction(transaction: Transaction): void {
|
||||||
|
if (this.isCapturingTransaction) {
|
||||||
|
if (!this.capturedTransaction) {
|
||||||
|
this.capturedTransaction = transaction
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.steps.forEach(step => this.capturedTransaction?.step(step))
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const state = this.state.apply(transaction)
|
const state = this.state.apply(transaction)
|
||||||
const selectionHasChanged = !this.state.selection.eq(state.selection)
|
const selectionHasChanged = !this.state.selection.eq(state.selection)
|
||||||
|
|
||||||
|
8
packages/core/src/commands/enter.ts
Normal file
8
packages/core/src/commands/enter.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { Command } from '../types'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger enter.
|
||||||
|
*/
|
||||||
|
export const enter = (): Command => ({ commands }) => {
|
||||||
|
return commands.keyboardShortcut('Enter')
|
||||||
|
}
|
95
packages/core/src/commands/keyboardShortcut.ts
Normal file
95
packages/core/src/commands/keyboardShortcut.ts
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import { Command } from '../types'
|
||||||
|
|
||||||
|
const mac = typeof navigator !== 'undefined' ? /Mac/.test(navigator.platform) : false
|
||||||
|
|
||||||
|
function normalizeKeyName(name: string) {
|
||||||
|
const parts = name.split(/-(?!$)/)
|
||||||
|
let result = parts[parts.length - 1]
|
||||||
|
|
||||||
|
if (result === 'Space') {
|
||||||
|
result = ' '
|
||||||
|
}
|
||||||
|
|
||||||
|
let alt
|
||||||
|
let ctrl
|
||||||
|
let shift
|
||||||
|
let meta
|
||||||
|
|
||||||
|
for (let i = 0; i < parts.length - 1; i += 1) {
|
||||||
|
const mod = parts[i]
|
||||||
|
|
||||||
|
if (/^(cmd|meta|m)$/i.test(mod)) {
|
||||||
|
meta = true
|
||||||
|
} else if (/^a(lt)?$/i.test(mod)) {
|
||||||
|
alt = true
|
||||||
|
} else if (/^(c|ctrl|control)$/i.test(mod)) {
|
||||||
|
ctrl = true
|
||||||
|
} else if (/^s(hift)?$/i.test(mod)) {
|
||||||
|
shift = true
|
||||||
|
} else if (/^mod$/i.test(mod)) {
|
||||||
|
if (mac) {
|
||||||
|
meta = true
|
||||||
|
} else {
|
||||||
|
ctrl = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unrecognized modifier name: ${mod}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alt) {
|
||||||
|
result = `Alt-${result}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctrl) {
|
||||||
|
result = `Ctrl-${result}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meta) {
|
||||||
|
result = `Meta-${result}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shift) {
|
||||||
|
result = `Shift-${result}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger a keyboard shortcut.
|
||||||
|
*/
|
||||||
|
export const keyboardShortcut = (name: string): Command => ({
|
||||||
|
editor,
|
||||||
|
view,
|
||||||
|
tr,
|
||||||
|
dispatch,
|
||||||
|
}) => {
|
||||||
|
const keys = normalizeKeyName(name).split(/-(?!$)/)
|
||||||
|
const key = keys.find(item => !['Alt', 'Ctrl', 'Meta', 'Shift'].includes(item))
|
||||||
|
const event = new KeyboardEvent('keydown', {
|
||||||
|
key: key === 'Space'
|
||||||
|
? ' '
|
||||||
|
: key,
|
||||||
|
altKey: keys.includes('Alt'),
|
||||||
|
ctrlKey: keys.includes('Ctrl'),
|
||||||
|
metaKey: keys.includes('Meta'),
|
||||||
|
shiftKey: keys.includes('Shift'),
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const capturedTransaction = editor.captureTransaction(() => {
|
||||||
|
view.someProp('handleKeyDown', f => f(view, event))
|
||||||
|
})
|
||||||
|
|
||||||
|
capturedTransaction?.steps.forEach(step => {
|
||||||
|
const newStep = step.map(tr.mapping)
|
||||||
|
|
||||||
|
if (newStep && dispatch) {
|
||||||
|
tr.maybeStep(newStep)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
@ -6,6 +6,7 @@ import * as command from '../commands/command'
|
|||||||
import * as createParagraphNear from '../commands/createParagraphNear'
|
import * as createParagraphNear from '../commands/createParagraphNear'
|
||||||
import * as deleteRange from '../commands/deleteRange'
|
import * as deleteRange from '../commands/deleteRange'
|
||||||
import * as deleteSelection from '../commands/deleteSelection'
|
import * as deleteSelection from '../commands/deleteSelection'
|
||||||
|
import * as enter from '../commands/enter'
|
||||||
import * as exitCode from '../commands/exitCode'
|
import * as exitCode from '../commands/exitCode'
|
||||||
import * as extendMarkRange from '../commands/extendMarkRange'
|
import * as extendMarkRange from '../commands/extendMarkRange'
|
||||||
import * as first from '../commands/first'
|
import * as first from '../commands/first'
|
||||||
@ -14,6 +15,7 @@ import * as insertHTML from '../commands/insertHTML'
|
|||||||
import * as insertText from '../commands/insertText'
|
import * as insertText from '../commands/insertText'
|
||||||
import * as joinBackward from '../commands/joinBackward'
|
import * as joinBackward from '../commands/joinBackward'
|
||||||
import * as joinForward from '../commands/joinForward'
|
import * as joinForward from '../commands/joinForward'
|
||||||
|
import * as keyboardShortcut from '../commands/keyboardShortcut'
|
||||||
import * as lift from '../commands/lift'
|
import * as lift from '../commands/lift'
|
||||||
import * as liftEmptyBlock from '../commands/liftEmptyBlock'
|
import * as liftEmptyBlock from '../commands/liftEmptyBlock'
|
||||||
import * as liftListItem from '../commands/liftListItem'
|
import * as liftListItem from '../commands/liftListItem'
|
||||||
@ -55,6 +57,7 @@ export const Commands = Extension.create({
|
|||||||
...createParagraphNear,
|
...createParagraphNear,
|
||||||
...deleteRange,
|
...deleteRange,
|
||||||
...deleteSelection,
|
...deleteSelection,
|
||||||
|
...enter,
|
||||||
...exitCode,
|
...exitCode,
|
||||||
...extendMarkRange,
|
...extendMarkRange,
|
||||||
...first,
|
...first,
|
||||||
@ -63,6 +66,7 @@ export const Commands = Extension.create({
|
|||||||
...insertText,
|
...insertText,
|
||||||
...joinBackward,
|
...joinBackward,
|
||||||
...joinForward,
|
...joinForward,
|
||||||
|
...keyboardShortcut,
|
||||||
...lift,
|
...lift,
|
||||||
...liftEmptyBlock,
|
...liftEmptyBlock,
|
||||||
...liftListItem,
|
...liftListItem,
|
||||||
|
Loading…
Reference in New Issue
Block a user