chenjuneking / quill-image-drop-and-paste

A quill editor module for drop and paste image, with a callback hook before insert image into the editor
ISC License
101 stars 42 forks source link

IndexSizeError: Failed to construct 'ImageData' #32

Closed TheDarkStrix closed 2 years ago

TheDarkStrix commented 2 years ago

Hi,

I face an error when using the quill-image-drop-and-paste, When using the upload file custom handler. I am using nextJS

The error : IndexSizeError: Failed to construct 'ImageData': The source width is zero or not a number.

Any help regarding this very much appreciated . @chenjuneking

Attached below is my code .

import React, { useState } from "react";

import { useQuill } from "react-quilljs";
import axios from "components/shared/Axios";

export default () => {
  const imageHandler = async (dataUrl, type, imageData) => {
    console.log("imageHandler", dataUrl, type, imageData);
    const types = dataUrl.match(/image\/[^;]+/);
    var file = imageData.toFile("something." + types);
    var blob = imageData.toBlob();
    const formData = new FormData();
    formData.append("file", file);
    axios
      .post(`${process.env.NEXT_PUBLIC_API}/upload-file`, formData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
        responseType: "json",
      })
      .then((res) => {
        if (res.data.ok == true) {
          insertToEditor(res.data.fileUrl);
        } else {
          console.error(res.data);
        }
      })
      .catch((e) => {
        console.error(e);
      });
  };
  const { quill, Quill, quillRef } = useQuill({
    modules: {
      toolbar: "#toolbar",
      imageDropAndPaste: {
        // add an custom image handler
        handler: imageHandler,
      },
    },
    formats: ["size", "bold", "script"], // Important
  });

  if (Quill && !quill) {
    // For execute this line only once.
    const QuillImageDropAndPaste =
      require("quill-image-drop-and-paste").default; // Install with 'yarn add quill-magic-url'
    Quill.register("modules/imageDropAndPaste", QuillImageDropAndPaste);
  }

  // Insert Image(selected by user) to quill
  const insertToEditor = (url) => {
    const range = quill.getSelection();
    quill.insertEmbed(range.index, "image", url);
  };

  React.useEffect(() => {
    if (quill) {
      console.log("quill regestered", quill);
      quill.getModule("toolbar").addHandler("image", function (clicked) {
        if (clicked) {
          var fileInput = this.container.querySelector(
            "input.ql-image[type=file]"
          );
          if (fileInput == null) {
            fileInput = document.createElement("input");
            fileInput.setAttribute("type", "file");
            fileInput.setAttribute(
              "accept",
              "image/png, image/gif, image/jpeg, image/bmp, image/x-icon"
            );
            fileInput.classList.add("ql-image");
            fileInput.addEventListener("change", function (e) {
              var files = e.target.files,
                file;
              if (files.length > 0) {
                file = files[0];
                var type = file.type;
                var reader = new FileReader();
                reader.onload = (e) => {
                  // handle the inserted image
                  console.log(e.target.result);
                  var dataUrl = e.target.result;
                  imageHandler(dataUrl, type, new ImageData(dataUrl, type));
                  fileInput.value = "";
                };
                reader.readAsDataURL(file);
              }
            });
          }
          fileInput.click();
        }
      });
    }
  }, [quill]);

  return (
    <div style={{ width: 500, height: 300, border: "1px solid lightgray" }}>
      <div ref={quillRef} />
      <div id="toolbar">
        <select className="ql-size">
          <option value="small" />
          <option selected />
          <option value="large" />
          <option value="huge" />
        </select>
        <button className="ql-bold" />
        <button className="ql-image" />
        <button className="ql-script" value="sub" />
        <button className="ql-script" value="super" />
      </div>
    </div>
  );
};