Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pasting an image #508

Closed
sarimabbas opened this issue Oct 29, 2019 · 5 comments
Closed

Pasting an image #508

sarimabbas opened this issue Oct 29, 2019 · 5 comments

Comments

@sarimabbas
Copy link

Hi, thank you for your work on tiptap. This is neither a feature request nor a bug report, but a request for guidance.

I am creating an electron text editor, and am trying to add support for pasted images. I've tried to extend your Image.js extension as follows:

 handleDOMEvents: {
                        paste(view, event) {
                            const hasFiles =
                                event.clipboardData &&
                                event.clipboardData.files &&
                                event.clipboardData.files.length;

                            if (!hasFiles) {
                                return;
                            }

                            const images = Array.from(
                                event.clipboardData.files
                            ).filter(file => /image/i.test(file.type));

                            if (images.length === 0) {
                                return;
                            }

                            event.preventDefault();

                            const dir = "./mydir/assets/";
                            const new_paths = [];
                            images.forEach(image => {
                                const reader = new FileReader();
                                reader.onload = readerEvent => {
                                    fs_jetpack.remove(dir + image.name);
                                    const buffer = Buffer.from(
                                        new Uint8Array(
                                            readerEvent.target.result
                                        )
                                    );
                                    fs_jetpack.appendAsync(
                                        dir + image.name,
                                        buffer,
                                        {}
                                    );
                                    new_paths.push(dir + image.name);
                                };
                                reader.readAsArrayBuffer(image);
                            });

                             const coordinates = view.posAtCoords({
                                 left: event.clientX,
                                 top: event.clientY
                            });

                            new_paths.forEach(path => {
                                const node = schema.nodes.image.create({
                                    src: path
                                });
                                const transaction = view.state.tr.insert(
                                    coordinates.pos,
                                    node
                                );
                                view.dispatch(transaction);
                            });
                        },
}

Basically I'm copying the image files to disk and using those URLs, something I've been able to do successfully with the drop event.

What I'm having trouble with is the coordinates, which, unlike the drop event, cannot be retrieved for the paste event (because clientX and clientY do not exist). I've been going through the ProseMirror documentation, but they don't have a good account of handleDOMEvents and getting the editor position for this case. Would you be able to assist or point me in the right direction? Thank you!

@slava-vishnyakov
Copy link

Try this:

const node = schema.nodes.image.create({
    src: src,
});
const transaction = view.state.tr.replaceSelectionWith(node);
view.dispatch(transaction)

You don't need coordinates in this case at all.

@sarimabbas
Copy link
Author

Works really well, thank you for your help!

@sidian123
Copy link

sidian123 commented Feb 29, 2020

and then, the complete and simplified code as follow:

paste(view,event){
  let hasFiles=false;
  let reader=new FileReader();
  //注册加载文件完毕事件
  reader.onload=function(event){
      //获取object url
      let imageUrl=event.target.result;
      //插入到编辑器中
      const node = view.state.schema.nodes.image.create({src: imageUrl});
      const transaction = view.state.tr.replaceSelectionWith(node);
      view.dispatch(transaction);
  };
  //从剪贴板中读取图片文件
  Array.from(event.clipboardData.files)
      .filter(item=>item.type.startsWith("image"))//提取图片文件
      .forEach(item=>{//读取数据
          reader.readAsDataURL(item);
          hasFiles=true;
      });
  //扫尾
  if(hasFiles) {
      event.preventDefault();
      return true;
  }
},

@softmarshmallow
Copy link

softmarshmallow commented May 16, 2022

where should i put handleDOMEvents?
its not on useEditor

@sipec
Copy link
Contributor

sipec commented Jul 7, 2022

@sidian123 This is incorrect, it will only insert one image even if you are copying multiple

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants