diff --git a/docs/src/demos/Extensions/Image/index.vue b/docs/src/demos/Extensions/Image/index.vue
index 52615a3b..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: [
@@ -33,7 +44,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..2efeb9e1 100644
--- a/docs/src/layouts/App/base.scss
+++ b/docs/src/layouts/App/base.scss
@@ -109,6 +109,11 @@ code {
}
}
+ img {
+ max-width: 100%;
+ height: auto;
+ }
+
hr {
margin: 1rem 0;
}
diff --git a/packages/extension-image/index.ts b/packages/extension-image/index.ts
index 605a4b52..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',
@@ -10,6 +9,8 @@ const Image = createNode({
group: 'inline',
+ draggable: true,
+
addAttributes() {
return {
src: {
@@ -38,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
},
@@ -53,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 }
}),
]
},