From be776e09f9d4300f63ec8ce76bde5124988c50d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Fri, 4 Jun 2021 15:06:36 +0200 Subject: [PATCH] add imageToFigure command for figure experiment --- docs/src/demos/Experiments/Figure/figure.ts | 55 +++++++++++++++++++++ docs/src/demos/Experiments/Figure/index.vue | 14 +++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/docs/src/demos/Experiments/Figure/figure.ts b/docs/src/demos/Experiments/Figure/figure.ts index e5628295..8ed8db80 100644 --- a/docs/src/demos/Experiments/Figure/figure.ts +++ b/docs/src/demos/Experiments/Figure/figure.ts @@ -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({ } }, }, + alt: { default: null, parseHTML: element => { @@ -60,6 +75,7 @@ export const Figure = Node.create({ } }, }, + title: { default: null, parseHTML: element => { @@ -108,6 +124,45 @@ export const Figure = Node.create({ }) .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 + }, } }, diff --git a/docs/src/demos/Experiments/Figure/index.vue b/docs/src/demos/Experiments/Figure/index.vue index 1319f19b..37af2a68 100644 --- a/docs/src/demos/Experiments/Figure/index.vue +++ b/docs/src/demos/Experiments/Figure/index.vue @@ -3,6 +3,12 @@ + +

HTML

@@ -13,6 +19,7 @@