quill icon indicating copy to clipboard operation
quill copied to clipboard

Vue3 - InsertEmbed Image Url Causing Formatting Issues when Pressing Enter

Open jonah-butler opened this issue 2 years ago • 3 comments

I have a custom image handler for inserting image url deltas into the editor. When I select the image icon in the toolbar, the file browser is opened, and after selection, the image handler method is fired. At this point, instead of uploading data to a server that returns a url, I'm testing by just inserting a dummy image url into the editor. Once the image is inserted, I set the selection to after the inserted image. From here, I am unable to press Enter to go to a next line to continue inserting text or more images. The text caret, jumps back to before the image. If I move the cursor back to after the image, it continues to jump back to before the image whenever Enter is pressed.

I set up a Vue3 repo with the quill instance setup on /.

You can clone that repo and fire it up to see this issue in action.

Github Quill Image Insert Bug

Steps for Reproduction

  1. Click image icon in editor
  2. Select any file(it doesn't matter at this point)
  3. Image handler will be invoked, inserting image url into editor
  4. The text caret will be blinking after image, press Enter key
  5. The caret will move to before the image, then applying the next line
  6. I'm unable to move down a line below the inserted image by using Enter key
  7. If I press an alphanumeric key, the editor moves down a line, but it is wrapping the new text like this: <p><img src="img_src.jpeg"/>text below image</p> Which is not the intended effect

Expected behavior: After an image is inserted, and the cursor is to the right of the image, pressing Enter should move down to the next line, where more text or images can be inserted

Actual behavior: Pressing the Enter key after an image is inserted using a custom image handler, causes the caret to move back before the image, and then the newline is inserted, making users unable to move below an inserted image using the Ente rkey

Platforms: Vue - v3.0.0 Quill - v1.3.7 Chrome - Version 99.0.4844.74 (Official Build) (arm64) Macbook Air - M1 chip, Monterey 12.0.1

jonah-butler avatar Mar 22 '22 15:03 jonah-butler

you can use ‘quill.setSelection(1, Quill.sources.SILENT)‘ to remove the cursor

heyang1014 avatar Mar 30 '22 11:03 heyang1014

Have you solved it? I have the same problem!

yunxiaopw avatar Aug 09 '22 10:08 yunxiaopw

@yunxiaopw The only approach that ended up working for me was where I initiated the image handler outside of the component's export. Maybe something to do with scope, not sure. It was an odd fix.

Here's my working code using some helpers for image upload. Really the takeaway here was just where I setup the image handler. Hopefully this helps.

//SomeComponent.vue

<script lang="ts">
export function imageHandler(this: any) {
  const input = document.createElement("input");
  input.setAttribute("type", "file");
  input.click();
  input.onchange = async () => {
    if(input.files === null) return;
    const file = input.files[0];
    if (/^image\//.test(file.type)) {
      try {
        // get current position of cursor
        const range = this.quill.getSelection(true);
        // insert uploading gif as placeholder
        this.quill.insertEmbed(range.index, 'video', uploadPlaceholder);
        // set cursor position to after placeholder image
        // for better usability: user can continue typing
        // while image gets uploaded, then placeholder is replaced
        // with s3 url
        this.quill.setSelection(range.index + 1);
        const resp = await S3.upload(file);
        this.quill.deleteText(range.index, 1);
        if(resp !== S3.S3ERRORS.upload.catch) {
          const range = this.quill.getSelection();
          this.quill.insertEmbed(range.index, "image", resp);
          this.quill.setSelection(range.index + 1);
        }
      } catch(error) {
        if(error instanceof Error) {
          ElNotification({
            type: 'error',
            message: error.message,
            duration: 3500,
          })
        }
      }
    } else {
      ElNotification({
        type: 'info',
        message: 'Only images are allowed - please select another file',
        duration: 2500,
      })
    }
  };
}

export default defineComponent({
   name: "Editor"
   components: {
      quillEditor
   },
   data() {
      quill: null,
      editorOptions: {
        theme: "snow",
        modules: {
          toolbar: {
            container: [
              [
                'bold',
                'italic',
                'underline',
                'strike',
                {'font': [] },
                {'align': [] },
                'image'
              ],
              [
                'blockquote',
                'link',
                { 'header': [1,2,3,4,5,6] },
                { 'list': 'ordered' },
                { 'list': 'bullet' },
                { 'size': ['small', false, 'large', 'huge'] },
                { 'color': [] },
                { 'background': [] }
              ],
            ],
            handlers: {
              image: imageHandler,
            },
          },
        },
      },
   },
   methods: {
     onEditorChange(quill: any) {
      this.$emit('update:modelValue', quill.html);
    },
    onEditorReady(quill: any) {
      quill.blur();
      window.scrollTo(0,0);
      this.quill = quill;
    },
   }
})

jonah-butler avatar Aug 09 '22 13:08 jonah-butler

Have you solved it? I have the same problem!

This is works for me!

const uploadUrl = await uploadImage(file);
const range = quill.getSelection(true);
quill.insertText(range.index, '\n');
quill.setSelection(range.index + 1, 1);
quill.insertEmbed(range.index, 'image', uploadUrl);
quill.deleteText(range.index + 1, 1);
quill.setSelection(range.index + 1, 1);

unformalized avatar Apr 20 '23 09:04 unformalized

Quill 2.0 has been released (announcement post) with many changes and fixes. If this is still an issue please create a new issue after reviewing our updated Contributing guide :pray:

quill-bot avatar Apr 17 '24 11:04 quill-bot