diff --git a/extension/chrome/elements/compose-modules/compose-input-module.ts b/extension/chrome/elements/compose-modules/compose-input-module.ts index e03d78c9baf..93c5dbeea34 100644 --- a/extension/chrome/elements/compose-modules/compose-input-module.ts +++ b/extension/chrome/elements/compose-modules/compose-input-module.ts @@ -110,6 +110,7 @@ export class ComposeInputModule extends ViewModule { this.squire = new window.Squire(el, { addLinks }); this.initShortcuts(); this.handlePaste(); + this.handleDragImages(); this.handlePasteImages(); this.resizeReplyBox(); this.scrollIntoView(); @@ -136,35 +137,51 @@ export class ComposeInputModule extends ViewModule { }); }; - private handlePasteImages = () => { + private loadImageFromFile = (file: File, callback: (result: string) => void) => { + const reader = new FileReader(); + reader.onload = () => callback(reader.result as string); + reader.readAsDataURL(file); + }; + + private insertImageIntoSquire = (imageData: string, name: string) => { + try { + this.squire.insertImage(imageData, { name, title: name }); + this.view.draftModule.draftSave().catch(Catch.reportErr); + } catch (e) { + Catch.reportErr(e); + } + }; + + private handleDragImages = () => { this.squire.addEventListener('drop', (ev: DragEvent) => { - try { - if (!this.isRichText()) { - return; - } - if (!ev.dataTransfer?.files.length) { - return; - } - const file = ev.dataTransfer.files[0]; - const reader = new FileReader(); - reader.onload = () => { - try { - this.squire.insertImage(reader.result?.toString() ?? '', { name: file.name, title: file.name }); - this.view.draftModule.draftSave().catch(Catch.reportErr); - } catch (e) { - Catch.reportErr(e); - } - }; - reader.readAsDataURL(file); - } catch (e) { - Catch.reportErr(e); + if (!this.isRichText() || !ev.dataTransfer?.files.length) { + return; } + const file = ev.dataTransfer.files[0]; + this.loadImageFromFile(file, imageData => { + this.insertImageIntoSquire(imageData, file.name); + }); }); this.squire.addEventListener('dragover', (e: DragEvent) => { e.preventDefault(); // this is needed for 'drop' event to fire }); }; + private handlePasteImages = () => { + this.squire.addEventListener('pasteImage', (ev: Event & { detail: { clipboardData: DataTransfer } }) => { + if (!this.isRichText()) return; + const items = Array.from(ev.detail.clipboardData?.items ?? []); + const imageItem = items.find(item => /image/.test(item.type)); + + const imageFile = imageItem?.getAsFile(); + if (imageItem && imageFile) { + this.loadImageFromFile(imageFile, imageData => { + this.insertImageIntoSquire(imageData, 'Pasted Image'); + }); + } + }); + }; + private handleRTL = () => { const checkRTL = () => { let container = $(this.squire.getSelection().commonAncestorContainer);