mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-08-06 13:38:49 +08:00
Merge branch 'main' of github.com:ueberdosis/tiptap
# 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
af3f96a07c
@ -2,6 +2,7 @@ import {
|
|||||||
Command,
|
Command,
|
||||||
Node,
|
Node,
|
||||||
nodeInputRule,
|
nodeInputRule,
|
||||||
|
mergeAttributes,
|
||||||
} from '@tiptap/core'
|
} from '@tiptap/core'
|
||||||
|
|
||||||
export interface FigureOptions {
|
export interface FigureOptions {
|
||||||
@ -35,6 +36,8 @@ export const Figure = Node.create<FigureOptions>({
|
|||||||
|
|
||||||
draggable: true,
|
draggable: true,
|
||||||
|
|
||||||
|
isolating: true,
|
||||||
|
|
||||||
addAttributes() {
|
addAttributes() {
|
||||||
return {
|
return {
|
||||||
src: {
|
src: {
|
||||||
@ -76,7 +79,7 @@ export const Figure = Node.create<FigureOptions>({
|
|||||||
renderHTML({ HTMLAttributes }) {
|
renderHTML({ HTMLAttributes }) {
|
||||||
return [
|
return [
|
||||||
'figure', this.options.HTMLAttributes,
|
'figure', this.options.HTMLAttributes,
|
||||||
['img', HTMLAttributes],
|
['img', mergeAttributes(HTMLAttributes, { draggable: false, contenteditable: false })],
|
||||||
['figcaption', 0],
|
['figcaption', 0],
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
80
docs/src/demos/Experiments/Nested/CustomNode.js
Normal file
80
docs/src/demos/Experiments/Nested/CustomNode.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import { Node, mergeAttributes } from '@tiptap/core'
|
||||||
|
import { VueNodeViewRenderer } from '@tiptap/vue-2'
|
||||||
|
import { Plugin } from 'prosemirror-state'
|
||||||
|
|
||||||
|
import CustomNodeView from './CustomNode.vue'
|
||||||
|
|
||||||
|
export default Node.create({
|
||||||
|
name: 'customNode',
|
||||||
|
isBlock: true,
|
||||||
|
inline: false,
|
||||||
|
group: 'block',
|
||||||
|
draggable: true,
|
||||||
|
isolating: true,
|
||||||
|
defining: true,
|
||||||
|
selectable: true,
|
||||||
|
|
||||||
|
addAttributes() {
|
||||||
|
return {
|
||||||
|
nest: { default: false },
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
parseHTML() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
tag: 'custom-node',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
renderHTML({ HTMLAttributes }) {
|
||||||
|
return ['custom-node', mergeAttributes(HTMLAttributes)]
|
||||||
|
},
|
||||||
|
|
||||||
|
addNodeView() {
|
||||||
|
return VueNodeViewRenderer(CustomNodeView)
|
||||||
|
},
|
||||||
|
|
||||||
|
addProseMirrorPlugins() {
|
||||||
|
return [
|
||||||
|
new Plugin({
|
||||||
|
props: {
|
||||||
|
handleKeyDown: (view, event) => {
|
||||||
|
// Prevent _any_ key from clearing block. As soon as you start typing,
|
||||||
|
// and a block is focused, it'll blast the block away.
|
||||||
|
view.state.typing = true
|
||||||
|
},
|
||||||
|
|
||||||
|
handlePaste: (view, event, slice) => {
|
||||||
|
// Prevent pasting overwriting block
|
||||||
|
view.state.pasting = true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
filterTransaction: (transaction, state) => {
|
||||||
|
let result = true
|
||||||
|
|
||||||
|
// Check if our flags are set, and if the selected node is a custom node
|
||||||
|
if (state.typing || state.pasting) {
|
||||||
|
transaction.mapping.maps.forEach(map => {
|
||||||
|
map.forEach((oldStart, oldEnd, newStart, newEnd) => {
|
||||||
|
state.doc.nodesBetween(
|
||||||
|
oldStart,
|
||||||
|
oldEnd,
|
||||||
|
(node, number, pos, parent, index) => {
|
||||||
|
if (node.type.name === 'customNode') {
|
||||||
|
result = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
})
|
106
docs/src/demos/Experiments/Nested/CustomNode.vue
Normal file
106
docs/src/demos/Experiments/Nested/CustomNode.vue
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<template>
|
||||||
|
<node-view-wrapper class="draggable-item" :class="{ active: selected }">
|
||||||
|
<div
|
||||||
|
class="drag-handle"
|
||||||
|
contenteditable="false"
|
||||||
|
draggable="true"
|
||||||
|
data-drag-handle
|
||||||
|
/>
|
||||||
|
<div class="draggable-nested">
|
||||||
|
<tiptap-nested />
|
||||||
|
</div>
|
||||||
|
</node-view-wrapper>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { NodeViewWrapper } from '@tiptap/vue-2'
|
||||||
|
import TiptapNested from './Nested.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CustomNode',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
NodeViewWrapper,
|
||||||
|
TiptapNested,
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
editor: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
|
||||||
|
node: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
|
||||||
|
decorations: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
|
||||||
|
selected: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
extension: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
|
||||||
|
getPos: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
|
||||||
|
updateAttributes: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.draggable-item {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 0.5rem;
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), 0px 10px 20px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border: 1px red solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin: 0 0 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drag-handle {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
position: relative;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
top: 0.3rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
cursor: grab;
|
||||||
|
background-image: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 16"><path fill-opacity="0.2" d="M4 14c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zM2 6C.9 6 0 6.9 0 8s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6C.9 0 0 .9 0 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" /></svg>');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.draggable-nested {
|
||||||
|
flex: 1
|
||||||
|
}
|
||||||
|
</style>
|
45
docs/src/demos/Experiments/Nested/Nested.vue
Normal file
45
docs/src/demos/Experiments/Nested/Nested.vue
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<div class="editor-nested" v-if="editor">
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-2'
|
||||||
|
import StarterKit from '@tiptap/starter-kit'
|
||||||
|
import CustomNode from './CustomNode.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
content: `
|
||||||
|
Nested intro text`,
|
||||||
|
extensions: [StarterKit, CustomNode],
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.editor-nested {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px gray solid;
|
||||||
|
}
|
||||||
|
.ProseMirror {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
</style>
|
49
docs/src/demos/Experiments/Nested/index.vue
Normal file
49
docs/src/demos/Experiments/Nested/index.vue
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div class="editor" v-if="editor">
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-2'
|
||||||
|
import StarterKit from '@tiptap/starter-kit'
|
||||||
|
import CustomNode from './CustomNode.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
content: 'Testing<custom-node></custom-node>Text',
|
||||||
|
extensions: [StarterKit, CustomNode],
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px gray solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ProseMirror {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
</style>
|
21
docs/src/docPages/api/commands/set-meta.md
Normal file
21
docs/src/docPages/api/commands/set-meta.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# setMeta
|
||||||
|
Store a metadata property in the current transaction.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
`key: string`
|
||||||
|
|
||||||
|
The name of your metadata. You can get its value at any time with [getMeta](https://prosemirror.net/docs/ref/#state.Transaction.getMeta).
|
||||||
|
|
||||||
|
`value: any`
|
||||||
|
|
||||||
|
Store any value within your metadata.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
```js
|
||||||
|
// Prevent the update event from being triggered
|
||||||
|
editor.commands.setMeta('preventUpdate', true)
|
||||||
|
|
||||||
|
// Store any value in the current transaction.
|
||||||
|
// You can get this value at any time with tr.getMeta('foo').
|
||||||
|
editor.commands.setMeta('foo', 'bar')
|
||||||
|
```
|
@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
⚠️ Experiment
|
⚠️ Experiment
|
||||||
|
|
||||||
## Known issues
|
|
||||||
* Dragging should move the image, but duplicates it
|
|
||||||
|
|
||||||
## Tasks
|
## Tasks
|
||||||
* Add the caption as an optional parameter to the command
|
* Add the caption as an optional parameter to the command
|
||||||
* Build commands to wrap an image into a figure + figcaption?
|
* Build commands to wrap an image into a figure + figcaption?
|
||||||
|
@ -206,6 +206,8 @@
|
|||||||
- title: setMark
|
- title: setMark
|
||||||
link: /api/commands/set-mark
|
link: /api/commands/set-mark
|
||||||
type: draft
|
type: draft
|
||||||
|
- title: setMeta
|
||||||
|
link: /api/commands/set-meta
|
||||||
- title: setNode
|
- title: setNode
|
||||||
link: /api/commands/set-node
|
link: /api/commands/set-node
|
||||||
type: draft
|
type: draft
|
||||||
|
@ -3,6 +3,47 @@
|
|||||||
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.79](https://github.com/ueberdosis/tiptap/compare/@tiptap/core@2.0.0-beta.77...@tiptap/core@2.0.0-beta.79) (2021-06-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.0.0-beta.77](https://github.com/ueberdosis/tiptap/compare/@tiptap/core@2.0.0-beta.76...@tiptap/core@2.0.0-beta.77) (2021-06-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add setMeta command ([36dad2b](https://github.com/ueberdosis/tiptap/commit/36dad2bbae5ed66077822330133a9d8ee0d28747))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.0.0-beta.76](https://github.com/ueberdosis/tiptap/compare/@tiptap/core@2.0.0-beta.75...@tiptap/core@2.0.0-beta.76) (2021-06-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* remove custom coordsAtPos method, fix [#583](https://github.com/ueberdosis/tiptap/issues/583) ([485fb8c](https://github.com/ueberdosis/tiptap/commit/485fb8c74c831256aaa2cefdf130e05438c2e476))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.0.0-beta.75](https://github.com/ueberdosis/tiptap/compare/@tiptap/core@2.0.0-beta.74...@tiptap/core@2.0.0-beta.75) (2021-06-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* prevent dispatch empty fragment when parsing content with insertContent ([2a4e02a](https://github.com/ueberdosis/tiptap/commit/2a4e02ade3b74999a9632673a607568644d6d26c))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [2.0.0-beta.74](https://github.com/ueberdosis/tiptap/compare/@tiptap/core@2.0.0-beta.73...@tiptap/core@2.0.0-beta.74) (2021-05-31)
|
# [2.0.0-beta.74](https://github.com/ueberdosis/tiptap/compare/@tiptap/core@2.0.0-beta.73...@tiptap/core@2.0.0-beta.74) (2021-05-31)
|
||||||
|
|
||||||
**Note:** Version bump only for package @tiptap/core
|
**Note:** Version bump only for package @tiptap/core
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@tiptap/core",
|
"name": "@tiptap/core",
|
||||||
"description": "headless rich text editor",
|
"description": "headless rich text editor",
|
||||||
"version": "2.0.0-beta.74",
|
"version": "2.0.0-beta.79",
|
||||||
"homepage": "https://tiptap.dev",
|
"homepage": "https://tiptap.dev",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tiptap",
|
"tiptap",
|
||||||
|
@ -25,6 +25,12 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value)
|
|||||||
preserveWhitespace: 'full',
|
preserveWhitespace: 'full',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// don’t dispatch an empty fragment because this can lead to strange errors
|
||||||
|
if (content.toString() === '<>') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
const { from, to } = typeof position === 'number'
|
const { from, to } = typeof position === 'number'
|
||||||
? { from: position, to: position }
|
? { from: position, to: position }
|
||||||
: position
|
: position
|
||||||
|
18
packages/core/src/commands/setMeta.ts
Normal file
18
packages/core/src/commands/setMeta.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Command, RawCommands } from '../types'
|
||||||
|
|
||||||
|
declare module '@tiptap/core' {
|
||||||
|
interface Commands {
|
||||||
|
setMeta: {
|
||||||
|
/**
|
||||||
|
* Store a metadata property in the current transaction.
|
||||||
|
*/
|
||||||
|
setMeta: (key: string, value: any) => Command,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setMeta: RawCommands['setMeta'] = (key, value) => ({ tr }) => {
|
||||||
|
tr.setMeta(key, value)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
@ -30,6 +30,7 @@ import * as selectNodeForward from '../commands/selectNodeForward'
|
|||||||
import * as selectParentNode from '../commands/selectParentNode'
|
import * as selectParentNode from '../commands/selectParentNode'
|
||||||
import * as setContent from '../commands/setContent'
|
import * as setContent from '../commands/setContent'
|
||||||
import * as setMark from '../commands/setMark'
|
import * as setMark from '../commands/setMark'
|
||||||
|
import * as setMeta from '../commands/setMeta'
|
||||||
import * as setNode from '../commands/setNode'
|
import * as setNode from '../commands/setNode'
|
||||||
import * as setNodeSelection from '../commands/setNodeSelection'
|
import * as setNodeSelection from '../commands/setNodeSelection'
|
||||||
import * as setTextSelection from '../commands/setTextSelection'
|
import * as setTextSelection from '../commands/setTextSelection'
|
||||||
@ -78,6 +79,7 @@ export { selectNodeForward }
|
|||||||
export { selectParentNode }
|
export { selectParentNode }
|
||||||
export { setContent }
|
export { setContent }
|
||||||
export { setMark }
|
export { setMark }
|
||||||
|
export { setMeta }
|
||||||
export { setNode }
|
export { setNode }
|
||||||
export { setNodeSelection }
|
export { setNodeSelection }
|
||||||
export { setTextSelection }
|
export { setTextSelection }
|
||||||
@ -131,6 +133,7 @@ export const Commands = Extension.create({
|
|||||||
...selectParentNode,
|
...selectParentNode,
|
||||||
...setContent,
|
...setContent,
|
||||||
...setMark,
|
...setMark,
|
||||||
|
...setMeta,
|
||||||
...setNode,
|
...setNode,
|
||||||
...setNodeSelection,
|
...setNodeSelection,
|
||||||
...setTextSelection,
|
...setTextSelection,
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
import { EditorView } from 'prosemirror-view'
|
|
||||||
|
|
||||||
type DOMRectSide = 'bottom' | 'left' | 'right' | 'top';
|
|
||||||
|
|
||||||
function textRange(node: Node, from?: number, to?: number) {
|
|
||||||
const range = document.createRange()
|
|
||||||
range.setEnd(node, typeof to === 'number' ? to : (node.nodeValue || '').length)
|
|
||||||
range.setStart(node, Math.max(from || 0, 0))
|
|
||||||
|
|
||||||
return range
|
|
||||||
}
|
|
||||||
|
|
||||||
function singleRect(object: Range | Element, bias: number) {
|
|
||||||
const rects = object.getClientRects()
|
|
||||||
return !rects.length
|
|
||||||
? object.getBoundingClientRect()
|
|
||||||
: rects[bias < 0 ? 0 : rects.length - 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function coordsAtPos(view: EditorView, pos: number, end = false) {
|
|
||||||
const { node, offset } = view.domAtPos(pos) // view.docView.domFromPos(pos);
|
|
||||||
let side: DOMRectSide | null = null
|
|
||||||
let rect: DOMRect | null = null
|
|
||||||
if (node.nodeType === 3) {
|
|
||||||
const nodeValue = node.nodeValue || ''
|
|
||||||
if (end && offset < nodeValue.length) {
|
|
||||||
rect = singleRect(textRange(node, offset - 1, offset), -1)
|
|
||||||
side = 'right'
|
|
||||||
} else if (offset < nodeValue.length) {
|
|
||||||
rect = singleRect(textRange(node, offset, offset + 1), -1)
|
|
||||||
side = 'left'
|
|
||||||
}
|
|
||||||
} else if (node.firstChild) {
|
|
||||||
if (offset < node.childNodes.length) {
|
|
||||||
const child = node.childNodes[offset]
|
|
||||||
rect = singleRect(
|
|
||||||
child.nodeType === 3 ? textRange(child) : (child as Element),
|
|
||||||
-1,
|
|
||||||
)
|
|
||||||
side = 'left'
|
|
||||||
}
|
|
||||||
if ((!rect || rect.top === rect.bottom) && offset) {
|
|
||||||
const child = node.childNodes[offset - 1]
|
|
||||||
rect = singleRect(
|
|
||||||
child.nodeType === 3 ? textRange(child) : (child as Element),
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
side = 'right'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const element = node as Element
|
|
||||||
rect = element.getBoundingClientRect()
|
|
||||||
side = 'left'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rect && side) {
|
|
||||||
const x = rect[side]
|
|
||||||
|
|
||||||
return {
|
|
||||||
top: rect.top,
|
|
||||||
bottom: rect.bottom,
|
|
||||||
left: x,
|
|
||||||
right: x,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
top: 0,
|
|
||||||
bottom: 0,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,8 @@
|
|||||||
import { EditorView } from 'prosemirror-view'
|
import { EditorView } from 'prosemirror-view'
|
||||||
import coordsAtPos from './coordsAtPos'
|
|
||||||
|
|
||||||
export default function posToDOMRect(view: EditorView, from: number, to: number): DOMRect {
|
export default function posToDOMRect(view: EditorView, from: number, to: number): DOMRect {
|
||||||
const start = coordsAtPos(view, from)
|
const start = view.coordsAtPos(from)
|
||||||
const end = coordsAtPos(view, to, true)
|
const end = view.coordsAtPos(to, -1)
|
||||||
const top = Math.min(start.top, end.top)
|
const top = Math.min(start.top, end.top)
|
||||||
const bottom = Math.max(start.bottom, end.bottom)
|
const bottom = Math.max(start.bottom, end.bottom)
|
||||||
const left = Math.min(start.left, end.left)
|
const left = Math.min(start.left, end.left)
|
||||||
|
@ -12,7 +12,6 @@ export { default as markPasteRule } from './pasteRules/markPasteRule'
|
|||||||
export { default as callOrReturn } from './utilities/callOrReturn'
|
export { default as callOrReturn } from './utilities/callOrReturn'
|
||||||
export { default as mergeAttributes } from './utilities/mergeAttributes'
|
export { default as mergeAttributes } from './utilities/mergeAttributes'
|
||||||
|
|
||||||
export { default as coordsAtPos } from './helpers/coordsAtPos'
|
|
||||||
export { default as getExtensionField } from './helpers/getExtensionField'
|
export { default as getExtensionField } from './helpers/getExtensionField'
|
||||||
export { default as findChildren } from './helpers/findChildren'
|
export { default as findChildren } from './helpers/findChildren'
|
||||||
export { default as findChildrenInRange } from './helpers/findChildrenInRange'
|
export { default as findChildrenInRange } from './helpers/findChildrenInRange'
|
||||||
|
@ -37,6 +37,12 @@ function getDecorations({ doc, name, lowlight }: { doc: ProsemirrorNode, name: s
|
|||||||
? lowlight.highlight(language, block.node.textContent).children
|
? lowlight.highlight(language, block.node.textContent).children
|
||||||
: lowlight.highlightAuto(block.node.textContent).children
|
: lowlight.highlightAuto(block.node.textContent).children
|
||||||
|
|
||||||
|
console.log({
|
||||||
|
lowlight,
|
||||||
|
languages,
|
||||||
|
nodes,
|
||||||
|
})
|
||||||
|
|
||||||
parseNodes(nodes).forEach(node => {
|
parseNodes(nodes).forEach(node => {
|
||||||
const to = from + node.text.length
|
const to = from + node.text.length
|
||||||
|
|
||||||
|
@ -3,6 +3,38 @@
|
|||||||
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.78](https://github.com/ueberdosis/tiptap/compare/@tiptap/html@2.0.0-beta.77...@tiptap/html@2.0.0-beta.78) (2021-06-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.0.0-beta.77](https://github.com/ueberdosis/tiptap/compare/@tiptap/html@2.0.0-beta.76...@tiptap/html@2.0.0-beta.77) (2021-06-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.0.0-beta.76](https://github.com/ueberdosis/tiptap/compare/@tiptap/html@2.0.0-beta.75...@tiptap/html@2.0.0-beta.76) (2021-06-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.0.0-beta.75](https://github.com/ueberdosis/tiptap/compare/@tiptap/html@2.0.0-beta.74...@tiptap/html@2.0.0-beta.75) (2021-06-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [2.0.0-beta.74](https://github.com/ueberdosis/tiptap/compare/@tiptap/html@2.0.0-beta.73...@tiptap/html@2.0.0-beta.74) (2021-05-31)
|
# [2.0.0-beta.74](https://github.com/ueberdosis/tiptap/compare/@tiptap/html@2.0.0-beta.73...@tiptap/html@2.0.0-beta.74) (2021-05-31)
|
||||||
|
|
||||||
**Note:** Version bump only for package @tiptap/html
|
**Note:** Version bump only for package @tiptap/html
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@tiptap/html",
|
"name": "@tiptap/html",
|
||||||
"description": "utility package to render tiptap JSON as HTML",
|
"description": "utility package to render tiptap JSON as HTML",
|
||||||
"version": "2.0.0-beta.74",
|
"version": "2.0.0-beta.78",
|
||||||
"homepage": "https://tiptap.dev",
|
"homepage": "https://tiptap.dev",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tiptap",
|
"tiptap",
|
||||||
@ -21,7 +21,7 @@
|
|||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tiptap/core": "^2.0.0-beta.74",
|
"@tiptap/core": "^2.0.0-beta.79",
|
||||||
"hostic-dom": "^0.8.6",
|
"hostic-dom": "^0.8.6",
|
||||||
"prosemirror-model": "^1.14.1"
|
"prosemirror-model": "^1.14.1"
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,38 @@
|
|||||||
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.75](https://github.com/ueberdosis/tiptap/compare/@tiptap/starter-kit@2.0.0-beta.74...@tiptap/starter-kit@2.0.0-beta.75) (2021-06-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/starter-kit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.0.0-beta.74](https://github.com/ueberdosis/tiptap/compare/@tiptap/starter-kit@2.0.0-beta.73...@tiptap/starter-kit@2.0.0-beta.74) (2021-06-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/starter-kit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.0.0-beta.73](https://github.com/ueberdosis/tiptap/compare/@tiptap/starter-kit@2.0.0-beta.72...@tiptap/starter-kit@2.0.0-beta.73) (2021-06-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/starter-kit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.0.0-beta.72](https://github.com/ueberdosis/tiptap/compare/@tiptap/starter-kit@2.0.0-beta.71...@tiptap/starter-kit@2.0.0-beta.72) (2021-06-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @tiptap/starter-kit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [2.0.0-beta.71](https://github.com/ueberdosis/tiptap/compare/@tiptap/starter-kit@2.0.0-beta.70...@tiptap/starter-kit@2.0.0-beta.71) (2021-05-31)
|
# [2.0.0-beta.71](https://github.com/ueberdosis/tiptap/compare/@tiptap/starter-kit@2.0.0-beta.70...@tiptap/starter-kit@2.0.0-beta.71) (2021-05-31)
|
||||||
|
|
||||||
**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.71",
|
"version": "2.0.0-beta.75",
|
||||||
"homepage": "https://tiptap.dev",
|
"homepage": "https://tiptap.dev",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tiptap",
|
"tiptap",
|
||||||
@ -21,7 +21,7 @@
|
|||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tiptap/core": "^2.0.0-beta.74",
|
"@tiptap/core": "^2.0.0-beta.79",
|
||||||
"@tiptap/extension-blockquote": "^2.0.0-beta.13",
|
"@tiptap/extension-blockquote": "^2.0.0-beta.13",
|
||||||
"@tiptap/extension-bold": "^2.0.0-beta.13",
|
"@tiptap/extension-bold": "^2.0.0-beta.13",
|
||||||
"@tiptap/extension-bullet-list": "^2.0.0-beta.13",
|
"@tiptap/extension-bullet-list": "^2.0.0-beta.13",
|
||||||
|
Loading…
Reference in New Issue
Block a user