add imageToFigure command for figure experiment

This commit is contained in:
Philipp Kühn
2021-06-04 15:06:36 +02:00
parent 517ecc577b
commit be776e09f9
2 changed files with 68 additions and 1 deletions

View File

@@ -3,6 +3,10 @@ import {
Node, Node,
nodeInputRule, nodeInputRule,
mergeAttributes, mergeAttributes,
findChildrenInRange,
isNodeSelection,
Predicate,
NodeWithPos,
} from '@tiptap/core' } from '@tiptap/core'
export interface FigureOptions { export interface FigureOptions {
@@ -21,6 +25,16 @@ declare module '@tiptap/core' {
title?: string, title?: string,
caption?: string, caption?: string,
}) => Command, }) => Command,
/**
* Converts an image to a figure
*/
imageToFigure: () => Command,
/**
* Converts a figure to an image
*/
figureToImage: () => Command,
} }
} }
} }
@@ -52,6 +66,7 @@ export const Figure = Node.create<FigureOptions>({
} }
}, },
}, },
alt: { alt: {
default: null, default: null,
parseHTML: element => { parseHTML: element => {
@@ -60,6 +75,7 @@ export const Figure = Node.create<FigureOptions>({
} }
}, },
}, },
title: { title: {
default: null, default: null,
parseHTML: element => { parseHTML: element => {
@@ -108,6 +124,45 @@ export const Figure = Node.create<FigureOptions>({
}) })
.run() .run()
}, },
imageToFigure: () => ({ tr }) => {
const { doc, selection } = tr
const nodes: NodeWithPos[] = []
const predicate: Predicate = node => node.type.name === 'image'
if (isNodeSelection(selection)) {
const node = doc.nodeAt(selection.from)
if (!node || !predicate(node)) {
return false
}
nodes.push({ node, pos: selection.from })
} else {
const range = {
from: selection.from,
to: selection.to,
}
nodes.push(...findChildrenInRange(doc, range, predicate))
}
nodes.forEach(({ node, pos }, index) => {
const mappedPos = tr.steps
.slice(tr.steps.length - index)
.reduce((newPos, step) => step.getMap().map(newPos), pos)
tr.replaceRangeWith(mappedPos, mappedPos + node.nodeSize, this.type.create({
src: node.attrs.src,
}))
})
return true
},
figureToImage: () => () => {
return true
},
} }
}, },

View File

@@ -3,6 +3,12 @@
<button @click="addFigure"> <button @click="addFigure">
figure figure
</button> </button>
<button @click="editor.chain().focus().imageToFigure().run()">
image to figure
</button>
<button @click="editor.chain().focus().figureToImage().run()">
figure to image
</button>
<editor-content :editor="editor" /> <editor-content :editor="editor" />
<h2>HTML</h2> <h2>HTML</h2>
@@ -13,6 +19,7 @@
<script> <script>
import { Editor, EditorContent } from '@tiptap/vue-2' import { Editor, EditorContent } from '@tiptap/vue-2'
import StarterKit from '@tiptap/starter-kit' import StarterKit from '@tiptap/starter-kit'
import Image from '@tiptap/extension-image'
import { Figure } from './figure' import { Figure } from './figure'
export default { export default {
@@ -46,6 +53,7 @@ export default {
extensions: [ extensions: [
StarterKit, StarterKit,
Figure, Figure,
Image,
], ],
content: ` content: `
<p>Figure + Figcaption</p> <p>Figure + Figcaption</p>
@@ -55,6 +63,9 @@ export default {
<p>Amazing caption</p> <p>Amazing caption</p>
</figcaption> </figcaption>
</figure> </figure>
<img src="https://source.unsplash.com/K9QHL52rE2k/800x400">
<img src="https://source.unsplash.com/8xznAGy4HcY/800x400">
<img src="https://source.unsplash.com/K9QHL52rE2k/800x400">
<p>Thats it.</p> <p>Thats it.</p>
`, `,
}) })
@@ -90,7 +101,8 @@ export default {
} }
img { img {
max-width: 100%; display: block;
max-width: min(100%, 25rem);
height: auto; height: auto;
border-radius: 0.5rem; border-radius: 0.5rem;
} }