Merge branch 'main' of github.com:ueberdosis/tiptap into main
This commit is contained in:
@@ -1,12 +1,18 @@
|
|||||||
context('/demos/Guide/Content/ReadOnly', () => {
|
context('/demos/Guide/Content/ReadOnly', () => {
|
||||||
beforeEach(() => {
|
before(() => {
|
||||||
cy.visit('/demos/Guide/Content/ReadOnly')
|
cy.visit('/demos/Guide/Content/ReadOnly')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.clearContent()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('should be read-only', () => {
|
it('should be read-only', () => {
|
||||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
editor.setEditable(false)
|
editor.setEditable(false)
|
||||||
editor.commands.insertContent('Edited: ')
|
cy.get('.ProseMirror').type('Edited: ')
|
||||||
|
|
||||||
cy.get('.ProseMirror p:first').should('not.contain', 'Edited: ')
|
cy.get('.ProseMirror p:first').should('not.contain', 'Edited: ')
|
||||||
})
|
})
|
||||||
@@ -15,7 +21,7 @@ context('/demos/Guide/Content/ReadOnly', () => {
|
|||||||
it('should be editable', () => {
|
it('should be editable', () => {
|
||||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
editor.setEditable(true)
|
editor.setEditable(true)
|
||||||
editor.commands.insertContent('Edited: ')
|
cy.get('.ProseMirror').type('Edited: ')
|
||||||
|
|
||||||
cy.get('.ProseMirror p:first').should('contain', 'Edited: ')
|
cy.get('.ProseMirror p:first').should('contain', 'Edited: ')
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,10 +47,17 @@ context('/demos/Marks/Link', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('detects a pasted URL within a text', () => {
|
||||||
|
cy.get('.ProseMirror').paste({ pastePayload: 'some text https://example.com around an url', pasteType: 'text/plain' })
|
||||||
|
.find('a')
|
||||||
|
.should('contain', 'https://example.com')
|
||||||
|
.should('have.attr', 'href', 'https://example.com')
|
||||||
|
})
|
||||||
|
|
||||||
it('detects a pasted URL', () => {
|
it('detects a pasted URL', () => {
|
||||||
cy.get('.ProseMirror').paste({ pastePayload: 'https://example.com', pasteType: 'text/plain' })
|
cy.get('.ProseMirror').paste({ pastePayload: 'https://example.com', pasteType: 'text/plain' })
|
||||||
.find('a')
|
.find('a')
|
||||||
.should('contain', 'https://example.com')
|
.should('contain', 'Example Text')
|
||||||
.should('have.attr', 'href', 'https://example.com')
|
.should('have.attr', 'href', 'https://example.com')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -155,9 +155,10 @@ Have a look at all of the core commands listed below. They should give you a goo
|
|||||||
|
|
||||||
### Content
|
### Content
|
||||||
| Command | Description | Links |
|
| Command | Description | Links |
|
||||||
| ---------------- | -------------------------------------------------------- | ------------------------------------ |
|
| ------------------ | -------------------------------------------------------- | --------------------------------------- |
|
||||||
| .clearContent() | Clear the whole document. | [More](/api/commands/clear-content) |
|
| .clearContent() | Clear the whole document. | [More](/api/commands/clear-content) |
|
||||||
| .insertContent() | Insert a node or string of HTML at the current position. | [More](/api/commands/insert-content) |
|
| .insertContent() | Insert a node or string of HTML at the current position. | [More](/api/commands/insert-content) |
|
||||||
|
| .insertContentAt() | Insert a node or string of HTML at a specific position. | [More](/api/commands/insert-content-at) |
|
||||||
| .setContent() | Replace the whole document with new content. | [More](/api/commands/set-content) |
|
| .setContent() | Replace the whole document with new content. | [More](/api/commands/set-content) |
|
||||||
|
|
||||||
### Nodes & Marks
|
### Nodes & Marks
|
||||||
@@ -172,8 +173,6 @@ Have a look at all of the core commands listed below. They should give you a goo
|
|||||||
| .lift() | Removes an existing wrap. | [More](/api/commands/lift) |
|
| .lift() | Removes an existing wrap. | [More](/api/commands/lift) |
|
||||||
| .liftEmptyBlock() | Lift block if empty. | [More](/api/commands/lift-empty-block) |
|
| .liftEmptyBlock() | Lift block if empty. | [More](/api/commands/lift-empty-block) |
|
||||||
| .newlineInCode() | Add a newline character in code. | [More](/api/commands/newline-in-code) |
|
| .newlineInCode() | Add a newline character in code. | [More](/api/commands/newline-in-code) |
|
||||||
| .replace() | Replaces text with a node. | [More](/api/commands/replace) |
|
|
||||||
| .replaceRange() | Replaces text with a node within a range. | [More](/api/commands/replace-range) |
|
|
||||||
| .resetAttributes() | Resets some node or mark attributes to the default value. | [More](/api/commands/reset-attributes) |
|
| .resetAttributes() | Resets some node or mark attributes to the default value. | [More](/api/commands/reset-attributes) |
|
||||||
| .setMark() | Add a mark with new attributes. | [More](/api/commands/set-mark) |
|
| .setMark() | Add a mark with new attributes. | [More](/api/commands/set-mark) |
|
||||||
| .setNode() | Replace a given range with a node. | [More](/api/commands/set-node) |
|
| .setNode() | Replace a given range with a node. | [More](/api/commands/set-node) |
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# replaceRange
|
# insertContentAt
|
||||||
|
|
||||||
<ContentMissing />
|
<ContentMissing />
|
||||||
@@ -29,5 +29,27 @@ editor.commands.insertContent({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Multiple nodes at once
|
||||||
|
editor.commands.insertContent([
|
||||||
|
{
|
||||||
|
type: 'paragraph',
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
text: 'First paragraph',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'paragraph',
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
text: 'Second paragraph',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
# replace
|
|
||||||
|
|
||||||
<ContentMissing />
|
|
||||||
@@ -157,6 +157,9 @@
|
|||||||
type: draft
|
type: draft
|
||||||
- title: insertContent
|
- title: insertContent
|
||||||
link: /api/commands/insert-content
|
link: /api/commands/insert-content
|
||||||
|
- title: insertContentAt
|
||||||
|
link: /api/commands/insert-content-at
|
||||||
|
type: draft
|
||||||
- title: joinBackward
|
- title: joinBackward
|
||||||
link: /api/commands/join-backward
|
link: /api/commands/join-backward
|
||||||
type: draft
|
type: draft
|
||||||
@@ -178,12 +181,6 @@
|
|||||||
- title: newlineInCode
|
- title: newlineInCode
|
||||||
link: /api/commands/newline-in-code
|
link: /api/commands/newline-in-code
|
||||||
type: draft
|
type: draft
|
||||||
- title: replaceRange
|
|
||||||
link: /api/commands/replace-range
|
|
||||||
type: draft
|
|
||||||
- title: replace
|
|
||||||
link: /api/commands/replace
|
|
||||||
type: draft
|
|
||||||
- title: resetAttributes
|
- title: resetAttributes
|
||||||
link: /api/commands/reset-attributes
|
link: /api/commands/reset-attributes
|
||||||
type: draft
|
type: draft
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import createNodeFromContent from '../helpers/createNodeFromContent'
|
|
||||||
import selectionToInsertionEnd from '../helpers/selectionToInsertionEnd'
|
|
||||||
import { Command, RawCommands, Content } from '../types'
|
import { Command, RawCommands, Content } from '../types'
|
||||||
|
|
||||||
declare module '@tiptap/core' {
|
declare module '@tiptap/core' {
|
||||||
@@ -13,25 +11,6 @@ declare module '@tiptap/core' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const insertContent: RawCommands['insertContent'] = value => ({ tr, dispatch, editor }) => {
|
export const insertContent: RawCommands['insertContent'] = value => ({ tr, commands }) => {
|
||||||
if (dispatch) {
|
return commands.insertContentAt({ from: tr.selection.from, to: tr.selection.to }, value)
|
||||||
const content = createNodeFromContent(value, editor.schema)
|
|
||||||
|
|
||||||
if (typeof content === 'string') {
|
|
||||||
tr.insertText(content)
|
|
||||||
tr.scrollIntoView()
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tr.selection.empty) {
|
|
||||||
tr.deleteSelection()
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.insert(tr.selection.anchor, content)
|
|
||||||
selectionToInsertionEnd(tr, tr.steps.length - 1, -1)
|
|
||||||
tr.scrollIntoView()
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|||||||
32
packages/core/src/commands/insertContentAt.ts
Normal file
32
packages/core/src/commands/insertContentAt.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import createNodeFromContent from '../helpers/createNodeFromContent'
|
||||||
|
import selectionToInsertionEnd from '../helpers/selectionToInsertionEnd'
|
||||||
|
import {
|
||||||
|
Command,
|
||||||
|
RawCommands,
|
||||||
|
Content,
|
||||||
|
Range,
|
||||||
|
} from '../types'
|
||||||
|
|
||||||
|
declare module '@tiptap/core' {
|
||||||
|
interface Commands {
|
||||||
|
insertContentAt: {
|
||||||
|
/**
|
||||||
|
* Insert a node or string of HTML at a specific position.
|
||||||
|
*/
|
||||||
|
insertContentAt: (range: Range, value: Content) => Command,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const insertContentAt: RawCommands['insertContentAt'] = (range, value) => ({ tr, dispatch, editor }) => {
|
||||||
|
if (dispatch) {
|
||||||
|
const content = createNodeFromContent(value, editor.schema)
|
||||||
|
|
||||||
|
tr.replaceWith(range.from, range.to, content)
|
||||||
|
|
||||||
|
// set cursor at end of inserted content
|
||||||
|
selectionToInsertionEnd(tr, tr.steps.length - 1, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import { DOMParser } from 'prosemirror-model'
|
|
||||||
import elementFromString from '../utilities/elementFromString'
|
|
||||||
import selectionToInsertionEnd from '../helpers/selectionToInsertionEnd'
|
|
||||||
import { Command, RawCommands } from '../types'
|
|
||||||
|
|
||||||
declare module '@tiptap/core' {
|
|
||||||
interface Commands {
|
|
||||||
insertHTML: {
|
|
||||||
/**
|
|
||||||
* Insert a string of HTML at the current position.
|
|
||||||
*/
|
|
||||||
insertHTML: (value: string) => Command,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const insertHTML: RawCommands['insertHTML'] = value => ({ tr, state, dispatch }) => {
|
|
||||||
console.warn('[tiptap warn]: insertHTML() is deprecated. please use insertContent() instead.')
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
import { NodeType } from 'prosemirror-model'
|
|
||||||
import getNodeType from '../helpers/getNodeType'
|
|
||||||
import { Command, RawCommands } from '../types'
|
|
||||||
|
|
||||||
declare module '@tiptap/core' {
|
|
||||||
interface Commands {
|
|
||||||
insertNode: {
|
|
||||||
/**
|
|
||||||
* Insert a node at the current position.
|
|
||||||
*/
|
|
||||||
insertNode: (typeOrName: string | NodeType, attributes?: Record<string, any>) => Command,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const insertNode: RawCommands['insertNode'] = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
|
|
||||||
console.warn('[tiptap warn]: insertNode() is deprecated. please use insertContent() instead.')
|
|
||||||
|
|
||||||
const { selection } = tr
|
|
||||||
const type = getNodeType(typeOrName, state.schema)
|
|
||||||
|
|
||||||
if (!type) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const node = type.create(attributes)
|
|
||||||
|
|
||||||
if (dispatch) {
|
|
||||||
tr.insert(selection.anchor, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import { Command, RawCommands } from '../types'
|
|
||||||
|
|
||||||
declare module '@tiptap/core' {
|
|
||||||
interface Commands {
|
|
||||||
insertText: {
|
|
||||||
/**
|
|
||||||
* Insert a string of text at the current position.
|
|
||||||
*/
|
|
||||||
insertText: (value: string) => Command,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const insertText: RawCommands['insertText'] = value => ({ tr, dispatch }) => {
|
|
||||||
console.warn('[tiptap warn]: insertText() is deprecated. please use insertContent() instead.')
|
|
||||||
|
|
||||||
if (dispatch) {
|
|
||||||
tr.insertText(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
@@ -13,6 +13,8 @@ declare module '@tiptap/core' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const replace: RawCommands['replace'] = (typeOrName, attributes = {}) => ({ state, commands }) => {
|
export const replace: RawCommands['replace'] = (typeOrName, attributes = {}) => ({ state, commands }) => {
|
||||||
|
console.warn('[tiptap warn]: replace() is deprecated. please use insertContent() instead.')
|
||||||
|
|
||||||
const { from, to } = state.selection
|
const { from, to } = state.selection
|
||||||
const range = { from, to }
|
const range = { from, to }
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ declare module '@tiptap/core' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const replaceRange: RawCommands['replaceRange'] = (range, typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
|
export const replaceRange: RawCommands['replaceRange'] = (range, typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
|
||||||
|
console.warn('[tiptap warn]: replaceRange() is deprecated. please use insertContent() instead.')
|
||||||
|
|
||||||
const type = getNodeType(typeOrName, state.schema)
|
const type = getNodeType(typeOrName, state.schema)
|
||||||
const { from, to } = range
|
const { from, to } = range
|
||||||
// const $from = tr.doc.resolve(from)
|
// const $from = tr.doc.resolve(from)
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ import * as extendMarkRange from '../commands/extendMarkRange'
|
|||||||
import * as first from '../commands/first'
|
import * as first from '../commands/first'
|
||||||
import * as focus from '../commands/focus'
|
import * as focus from '../commands/focus'
|
||||||
import * as insertContent from '../commands/insertContent'
|
import * as insertContent from '../commands/insertContent'
|
||||||
import * as insertHTML from '../commands/insertHTML'
|
import * as insertContentAt from '../commands/insertContentAt'
|
||||||
import * as insertNode from '../commands/insertNode'
|
|
||||||
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 keyboardShortcut from '../commands/keyboardShortcut'
|
||||||
@@ -64,9 +62,7 @@ export { extendMarkRange }
|
|||||||
export { first }
|
export { first }
|
||||||
export { focus }
|
export { focus }
|
||||||
export { insertContent }
|
export { insertContent }
|
||||||
export { insertHTML }
|
export { insertContentAt }
|
||||||
export { insertNode }
|
|
||||||
export { insertText }
|
|
||||||
export { joinBackward }
|
export { joinBackward }
|
||||||
export { joinForward }
|
export { joinForward }
|
||||||
export { keyboardShortcut }
|
export { keyboardShortcut }
|
||||||
@@ -121,9 +117,7 @@ export const Commands = Extension.create({
|
|||||||
...first,
|
...first,
|
||||||
...focus,
|
...focus,
|
||||||
...insertContent,
|
...insertContent,
|
||||||
...insertHTML,
|
...insertContentAt,
|
||||||
...insertNode,
|
|
||||||
...insertText,
|
|
||||||
...joinBackward,
|
...joinBackward,
|
||||||
...joinForward,
|
...joinForward,
|
||||||
...keyboardShortcut,
|
...keyboardShortcut,
|
||||||
|
|||||||
@@ -17,15 +17,19 @@ export default function createNodeFromContent(
|
|||||||
content: Content,
|
content: Content,
|
||||||
schema: Schema,
|
schema: Schema,
|
||||||
options?: CreateNodeFromContentOptions,
|
options?: CreateNodeFromContentOptions,
|
||||||
): string | ProseMirrorNode | Fragment {
|
): ProseMirrorNode | Fragment {
|
||||||
options = {
|
options = {
|
||||||
slice: true,
|
slice: true,
|
||||||
parseOptions: {},
|
parseOptions: {},
|
||||||
...options,
|
...options,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content && typeof content === 'object') {
|
if (typeof content === 'object' && content !== null) {
|
||||||
try {
|
try {
|
||||||
|
if (Array.isArray(content)) {
|
||||||
|
return Fragment.fromArray(content.map(item => schema.nodeFromJSON(item)))
|
||||||
|
}
|
||||||
|
|
||||||
return schema.nodeFromJSON(content)
|
return schema.nodeFromJSON(content)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(
|
console.warn(
|
||||||
@@ -41,9 +45,6 @@ export default function createNodeFromContent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof content === 'string') {
|
if (typeof content === 'string') {
|
||||||
const isHTML = content.trim().startsWith('<') && content.trim().endsWith('>')
|
|
||||||
|
|
||||||
if (isHTML || !options.slice) {
|
|
||||||
const parser = DOMParser.fromSchema(schema)
|
const parser = DOMParser.fromSchema(schema)
|
||||||
|
|
||||||
return options.slice
|
return options.slice
|
||||||
@@ -51,8 +52,5 @@ export default function createNodeFromContent(
|
|||||||
: parser.parse(elementFromString(content), options.parseOptions)
|
: parser.parse(elementFromString(content), options.parseOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
return content
|
|
||||||
}
|
|
||||||
|
|
||||||
return createNodeFromContent('', schema, options)
|
return createNodeFromContent('', schema, options)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,17 @@ export interface EditorOptions {
|
|||||||
onDestroy: () => void,
|
onDestroy: () => void,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Content = string | Record<string, any> | null
|
export type HTMLContent = string
|
||||||
|
|
||||||
|
export type JSONContent = {
|
||||||
|
type: string,
|
||||||
|
attrs?: Record<string, any>,
|
||||||
|
content?: JSONContent[],
|
||||||
|
text?: string,
|
||||||
|
[key: string]: any,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Content = HTMLContent | JSONContent | JSONContent[] | null
|
||||||
|
|
||||||
export type CommandProps = {
|
export type CommandProps = {
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@tiptap/core": "^2.0.0-beta.1",
|
"@tiptap/core": "^2.0.0-beta.1"
|
||||||
"prosemirror-commands": "^1.1.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Command, Node, mergeAttributes } from '@tiptap/core'
|
import { Command, Node, mergeAttributes } from '@tiptap/core'
|
||||||
import { exitCode } from 'prosemirror-commands'
|
|
||||||
|
|
||||||
export interface HardBreakOptions {
|
export interface HardBreakOptions {
|
||||||
HTMLAttributes: Record<string, any>,
|
HTMLAttributes: Record<string, any>,
|
||||||
@@ -41,16 +40,10 @@ export const HardBreak = Node.create<HardBreakOptions>({
|
|||||||
|
|
||||||
addCommands() {
|
addCommands() {
|
||||||
return {
|
return {
|
||||||
setHardBreak: () => ({ commands, state, dispatch }) => {
|
setHardBreak: () => ({ commands }) => {
|
||||||
return commands.first([
|
return commands.first([
|
||||||
() => exitCode(state, dispatch),
|
() => commands.exitCode(),
|
||||||
() => {
|
() => commands.insertContent({ type: this.name }),
|
||||||
if (dispatch) {
|
|
||||||
state.tr.replaceSelectionWith(this.type.create()).scrollIntoView()
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,17 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [2.0.0-beta.9](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-horizontal-rule@2.0.0-beta.8...@tiptap/extension-horizontal-rule@2.0.0-beta.9) (2021-05-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix lint error ([d5dd568](https://github.com/ueberdosis/tiptap/commit/d5dd568d862fee60c975ec7314615032f0558872))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [2.0.0-beta.8](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-horizontal-rule@2.0.0-beta.7...@tiptap/extension-horizontal-rule@2.0.0-beta.8) (2021-05-04)
|
# [2.0.0-beta.8](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-horizontal-rule@2.0.0-beta.7...@tiptap/extension-horizontal-rule@2.0.0-beta.8) (2021-05-04)
|
||||||
|
|
||||||
**Note:** Version bump only for package @tiptap/extension-horizontal-rule
|
**Note:** Version bump only for package @tiptap/extension-horizontal-rule
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@tiptap/extension-horizontal-rule",
|
"name": "@tiptap/extension-horizontal-rule",
|
||||||
"description": "horizontal rule extension for tiptap",
|
"description": "horizontal rule extension for tiptap",
|
||||||
"version": "2.0.0-beta.8",
|
"version": "2.0.0-beta.9",
|
||||||
"homepage": "https://tiptap.dev",
|
"homepage": "https://tiptap.dev",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tiptap",
|
"tiptap",
|
||||||
|
|||||||
@@ -42,10 +42,11 @@ export const HorizontalRule = Node.create<HorizontalRuleOptions>({
|
|||||||
|
|
||||||
addCommands() {
|
addCommands() {
|
||||||
return {
|
return {
|
||||||
setHorizontalRule: () => ({ tr, dispatch }) => {
|
setHorizontalRule: () => ({ chain }) => {
|
||||||
|
return chain()
|
||||||
|
.insertContent({ type: this.name })
|
||||||
|
.command(({ tr, dispatch }) => {
|
||||||
if (dispatch) {
|
if (dispatch) {
|
||||||
tr.replaceSelectionWith(this.type.create())
|
|
||||||
|
|
||||||
const { parent, pos } = tr.selection.$from
|
const { parent, pos } = tr.selection.$from
|
||||||
const posAfter = pos + 1
|
const posAfter = pos + 1
|
||||||
const nodeAfter = tr.doc.nodeAt(posAfter)
|
const nodeAfter = tr.doc.nodeAt(posAfter)
|
||||||
@@ -64,13 +65,15 @@ export const HorizontalRule = Node.create<HorizontalRuleOptions>({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
})
|
||||||
|
.run()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addInputRules() {
|
addInputRules() {
|
||||||
return [
|
return [
|
||||||
nodeInputRule(/^(?:---|\—-|___\s|\*\*\*\s)$/, this.type),
|
nodeInputRule(/^(?:---|—-|___\s|\*\*\*\s)$/, this.type),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -69,15 +69,11 @@ export const Image = Node.create<ImageOptions>({
|
|||||||
|
|
||||||
addCommands() {
|
addCommands() {
|
||||||
return {
|
return {
|
||||||
setImage: options => ({ tr, dispatch }) => {
|
setImage: options => ({ commands }) => {
|
||||||
const { selection } = tr
|
return commands.insertContent({
|
||||||
const node = this.type.create(options)
|
type: this.name,
|
||||||
|
attrs: options,
|
||||||
if (dispatch) {
|
})
|
||||||
tr.replaceRangeWith(selection.from, selection.to, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,12 +17,20 @@ export const Mention = Node.create<MentionOptions>({
|
|||||||
editor
|
editor
|
||||||
.chain()
|
.chain()
|
||||||
.focus()
|
.focus()
|
||||||
.replaceRange(range, 'mention', props)
|
.insertContentAt(range, [
|
||||||
.insertContent(' ')
|
{
|
||||||
|
type: 'mention',
|
||||||
|
attrs: props,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
text: ' ',
|
||||||
|
},
|
||||||
|
])
|
||||||
.run()
|
.run()
|
||||||
},
|
},
|
||||||
allow: ({ editor, range }) => {
|
allow: ({ editor, range }) => {
|
||||||
return editor.can().replaceRange(range, 'mention')
|
return editor.can().insertContentAt(range, { type: 'mention' })
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -66,11 +74,15 @@ export const Mention = Node.create<MentionOptions>({
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderHTML({ node, HTMLAttributes }) {
|
renderHTML({ node, HTMLAttributes }) {
|
||||||
return ['span', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), `@${node.attrs.id}`]
|
return [
|
||||||
|
'span',
|
||||||
|
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
|
||||||
|
`${this.options.suggestion.char}${node.attrs.id}`,
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
renderText({ node }) {
|
renderText({ node }) {
|
||||||
return `@${node.attrs.id}`
|
return `${this.options.suggestion.char}${node.attrs.id}`
|
||||||
},
|
},
|
||||||
|
|
||||||
addKeyboardShortcuts() {
|
addKeyboardShortcuts() {
|
||||||
@@ -85,7 +97,7 @@ export const Mention = Node.create<MentionOptions>({
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
|
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
|
||||||
if (node.type.name === 'mention') {
|
if (node.type.name === this.name) {
|
||||||
isMention = true
|
isMention = true
|
||||||
tr.insertText(this.options.suggestion.char || '', pos, pos + node.nodeSize)
|
tr.insertText(this.options.suggestion.char || '', pos, pos + node.nodeSize)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [2.0.0-beta.40](https://github.com/ueberdosis/tiptap/compare/@tiptap/starter-kit@2.0.0-beta.39...@tiptap/starter-kit@2.0.0-beta.40) (2021-05-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/starter-kit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [2.0.0-beta.39](https://github.com/ueberdosis/tiptap/compare/@tiptap/starter-kit@2.0.0-beta.38...@tiptap/starter-kit@2.0.0-beta.39) (2021-05-05)
|
# [2.0.0-beta.39](https://github.com/ueberdosis/tiptap/compare/@tiptap/starter-kit@2.0.0-beta.38...@tiptap/starter-kit@2.0.0-beta.39) (2021-05-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @tiptap/starter-kit
|
**Note:** Version bump only for package @tiptap/starter-kit
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@tiptap/starter-kit",
|
"name": "@tiptap/starter-kit",
|
||||||
"description": "starter kit for tiptap",
|
"description": "starter kit for tiptap",
|
||||||
"version": "2.0.0-beta.39",
|
"version": "2.0.0-beta.40",
|
||||||
"homepage": "https://tiptap.dev",
|
"homepage": "https://tiptap.dev",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tiptap",
|
"tiptap",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"@tiptap/extension-hard-break": "^2.0.0-beta.6",
|
"@tiptap/extension-hard-break": "^2.0.0-beta.6",
|
||||||
"@tiptap/extension-heading": "^2.0.0-beta.6",
|
"@tiptap/extension-heading": "^2.0.0-beta.6",
|
||||||
"@tiptap/extension-history": "^2.0.0-beta.5",
|
"@tiptap/extension-history": "^2.0.0-beta.5",
|
||||||
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.8",
|
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.9",
|
||||||
"@tiptap/extension-italic": "^2.0.0-beta.6",
|
"@tiptap/extension-italic": "^2.0.0-beta.6",
|
||||||
"@tiptap/extension-list-item": "^2.0.0-beta.6",
|
"@tiptap/extension-list-item": "^2.0.0-beta.6",
|
||||||
"@tiptap/extension-ordered-list": "^2.0.0-beta.6",
|
"@tiptap/extension-ordered-list": "^2.0.0-beta.6",
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [2.0.0-beta.28](https://github.com/ueberdosis/tiptap/compare/@tiptap/vue-3@2.0.0-beta.27...@tiptap/vue-3@2.0.0-beta.28) (2021-05-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/vue-3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [2.0.0-beta.27](https://github.com/ueberdosis/tiptap/compare/@tiptap/vue-3@2.0.0-beta.26...@tiptap/vue-3@2.0.0-beta.27) (2021-05-04)
|
# [2.0.0-beta.27](https://github.com/ueberdosis/tiptap/compare/@tiptap/vue-3@2.0.0-beta.26...@tiptap/vue-3@2.0.0-beta.27) (2021-05-04)
|
||||||
|
|
||||||
**Note:** Version bump only for package @tiptap/vue-3
|
**Note:** Version bump only for package @tiptap/vue-3
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@tiptap/vue-3",
|
"name": "@tiptap/vue-3",
|
||||||
"description": "Vue components for tiptap",
|
"description": "Vue components for tiptap",
|
||||||
"version": "2.0.0-beta.27",
|
"version": "2.0.0-beta.28",
|
||||||
"homepage": "https://tiptap.dev",
|
"homepage": "https://tiptap.dev",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tiptap",
|
"tiptap",
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export class VueRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get ref(): any {
|
get ref(): any {
|
||||||
return this.editor.contentComponent?.ctx.$refs[this.id]
|
return this.editor.contentComponent?.refs[this.id]
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProps(props: Record<string, any> = {}): void {
|
updateProps(props: Record<string, any> = {}): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user