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,
nodeInputRule,
mergeAttributes,
findChildrenInRange,
isNodeSelection,
Predicate,
NodeWithPos,
} from '@tiptap/core'
export interface FigureOptions {
@@ -21,6 +25,16 @@ declare module '@tiptap/core' {
title?: string,
caption?: string,
}) => 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: {
default: null,
parseHTML: element => {
@@ -60,6 +75,7 @@ export const Figure = Node.create<FigureOptions>({
}
},
},
title: {
default: null,
parseHTML: element => {
@@ -108,6 +124,45 @@ export const Figure = Node.create<FigureOptions>({
})
.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">
figure
</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" />
<h2>HTML</h2>
@@ -13,6 +19,7 @@
<script>
import { Editor, EditorContent } from '@tiptap/vue-2'
import StarterKit from '@tiptap/starter-kit'
import Image from '@tiptap/extension-image'
import { Figure } from './figure'
export default {
@@ -46,6 +53,7 @@ export default {
extensions: [
StarterKit,
Figure,
Image,
],
content: `
<p>Figure + Figcaption</p>
@@ -55,6 +63,9 @@ export default {
<p>Amazing caption</p>
</figcaption>
</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>
`,
})
@@ -90,7 +101,8 @@ export default {
}
img {
max-width: 100%;
display: block;
max-width: min(100%, 25rem);
height: auto;
border-radius: 0.5rem;
}