From d8e82959ec828c5b40c8785088ea759d362dc9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Tue, 27 Oct 2020 21:38:29 +0100 Subject: [PATCH 1/2] add some random image --- docs/src/demos/Extensions/Image/index.vue | 2 +- docs/src/layouts/App/base.scss | 5 +++++ packages/extension-image/index.ts | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/src/demos/Extensions/Image/index.vue b/docs/src/demos/Extensions/Image/index.vue index 52615a3b..69981469 100644 --- a/docs/src/demos/Extensions/Image/index.vue +++ b/docs/src/demos/Extensions/Image/index.vue @@ -33,7 +33,7 @@ export default { ], content: `

This is basic example of implementing images. Try to drop new images here. Reordering also works.

- + `, }) }, diff --git a/docs/src/layouts/App/base.scss b/docs/src/layouts/App/base.scss index 95b824ad..39e5629b 100644 --- a/docs/src/layouts/App/base.scss +++ b/docs/src/layouts/App/base.scss @@ -109,6 +109,11 @@ code { } } + img { + width: 100%; + height: auto; + } + hr { margin: 1rem 0; } diff --git a/packages/extension-image/index.ts b/packages/extension-image/index.ts index 605a4b52..73264e60 100644 --- a/packages/extension-image/index.ts +++ b/packages/extension-image/index.ts @@ -10,6 +10,8 @@ const Image = createNode({ group: 'inline', + draggable: true, + addAttributes() { return { src: { From a731ff8ea2b42453ab6a39d02bfd3b4ca54b0b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Tue, 27 Oct 2020 22:35:31 +0100 Subject: [PATCH 2/2] refactoring --- docs/src/demos/Extensions/Image/index.vue | 11 ++++ docs/src/layouts/App/base.scss | 2 +- packages/extension-image/index.ts | 71 +++-------------------- 3 files changed, 19 insertions(+), 65 deletions(-) diff --git a/docs/src/demos/Extensions/Image/index.vue b/docs/src/demos/Extensions/Image/index.vue index 69981469..f390a7ac 100644 --- a/docs/src/demos/Extensions/Image/index.vue +++ b/docs/src/demos/Extensions/Image/index.vue @@ -1,5 +1,8 @@ @@ -23,6 +26,14 @@ export default { } }, + methods: { + addImage() { + const url = window.prompt('URL') + + this.editor.chain().focus().image({ src: url }).run() + }, + }, + mounted() { this.editor = new Editor({ extensions: [ diff --git a/docs/src/layouts/App/base.scss b/docs/src/layouts/App/base.scss index 39e5629b..2efeb9e1 100644 --- a/docs/src/layouts/App/base.scss +++ b/docs/src/layouts/App/base.scss @@ -110,7 +110,7 @@ code { } img { - width: 100%; + max-width: 100%; height: auto; } diff --git a/packages/extension-image/index.ts b/packages/extension-image/index.ts index 73264e60..424cffc5 100644 --- a/packages/extension-image/index.ts +++ b/packages/extension-image/index.ts @@ -1,7 +1,6 @@ import { Command, createNode, nodeInputRule } from '@tiptap/core' -import { Plugin } from 'prosemirror-state' -const IMAGE_INPUT_REGEX = /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/ +export const inputRegex = /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/ const Image = createNode({ name: 'image', @@ -40,13 +39,11 @@ const Image = createNode({ addCommands() { return { - image: (attrs: any): Command => ({ tr }) => { + image: (options: { src: string, alt?: string, title?: string }): Command => ({ tr }) => { const { selection } = tr - console.log({ selection }) - // const position = selection.$cursor ? selection.$cursor.pos : selection.$to.pos - const position = selection.$anchor ? selection.$anchor.pos : selection.$to.pos - const node = this.type.create(attrs) - tr.insert(position, node) + const node = this.type.create(options) + + tr.replaceRangeWith(selection.from, selection.to, node) return true }, @@ -55,64 +52,10 @@ const Image = createNode({ addInputRules() { return [ - nodeInputRule(IMAGE_INPUT_REGEX, this.type, match => { + nodeInputRule(inputRegex, this.type, match => { const [, alt, src, title] = match - return { - src, - alt, - title, - } - }), - ] - }, - addProseMirrorPlugins() { - return [ - new Plugin({ - props: { - handleDOMEvents: { - drop(view, event) { - const hasFiles = event.dataTransfer - && event.dataTransfer.files - && event.dataTransfer.files.length - - if (!hasFiles) { - return false - } - - const images = Array - // @ts-ignore - .from(event.dataTransfer.files) - .filter(file => (/image/i).test(file.type)) - - if (images.length === 0) { - return false - } - - event.preventDefault() - - const { schema } = view.state - const coordinates = view.posAtCoords({ left: event.clientX, top: event.clientY }) - - images.forEach(image => { - const reader = new FileReader() - - reader.onload = readerEvent => { - const node = schema.nodes.image.create({ - // @ts-ignore - src: readerEvent.target.result, - }) - // @ts-ignore - const transaction = view.state.tr.insert(coordinates.pos, node) - view.dispatch(transaction) - } - reader.readAsDataURL(image) - }) - - return true - }, - }, - }, + return { src, alt, title } }), ] },