From 412e03e576fc7f91fd1c9457d56386b0297c6fd2 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Thu, 6 Jun 2024 21:32:20 +0200 Subject: [PATCH] [Editor] Support dragging & dropping images on a pdf (bug 1900907) --- src/display/editor/tools.js | 44 +++++++++++++++++++++++++++++++++++++ web/app.js | 20 ++++++++++------- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/display/editor/tools.js b/src/display/editor/tools.js index b51bca5204c44..dd277b7c3f523 100644 --- a/src/display/editor/tools.js +++ b/src/display/editor/tools.js @@ -600,6 +600,10 @@ class AnnotationEditorUIManager { #boundCut = this.cut.bind(this); + #boundDragOver = this.dragOver.bind(this); + + #boundDrop = this.drop.bind(this); + #boundPaste = this.paste.bind(this); #boundKeydown = this.keydown.bind(this); @@ -790,6 +794,7 @@ class AnnotationEditorUIManager { this._eventBus._on("scalechanging", this.#boundOnScaleChanging); this._eventBus._on("rotationchanging", this.#boundOnRotationChanging); this.#addSelectionListener(); + this.#addDragAndDropListeners(); this.#addKeyboardManager(); this.#annotationStorage = pdfDocument.annotationStorage; this.#filterFactory = pdfDocument.filterFactory; @@ -815,6 +820,7 @@ class AnnotationEditorUIManager { } destroy() { + this.#removeDragAndDropListeners(); this.#removeKeyboardManager(); this.#removeFocusManager(); this._eventBus._off("editingaction", this.#boundOnEditingAction); @@ -1183,6 +1189,16 @@ class AnnotationEditorUIManager { document.removeEventListener("paste", this.#boundPaste); } + #addDragAndDropListeners() { + document.addEventListener("dragover", this.#boundDragOver); + document.addEventListener("drop", this.#boundDrop); + } + + #removeDragAndDropListeners() { + document.removeEventListener("dragover", this.#boundDragOver); + document.removeEventListener("drop", this.#boundDrop); + } + addEditListeners() { this.#addKeyboardManager(); this.#addCopyPasteListeners(); @@ -1193,6 +1209,34 @@ class AnnotationEditorUIManager { this.#removeCopyPasteListeners(); } + dragOver(event) { + for (const { type } of event.dataTransfer.items) { + for (const editorType of this.#editorTypes) { + if (editorType.isHandlingMimeForPasting(type)) { + event.dataTransfer.dropEffect = "copy"; + event.preventDefault(); + return; + } + } + } + } + + /** + * Drop callback. + * @param {DragEvent} event + */ + drop(event) { + for (const item of event.dataTransfer.items) { + for (const editorType of this.#editorTypes) { + if (editorType.isHandlingMimeForPasting(item.type)) { + editorType.paste(item, this.currentLayer); + event.preventDefault(); + return; + } + } + } + } + /** * Copy callback. * @param {ClipboardEvent} event diff --git a/web/app.js b/web/app.js index 3debecece2fdc..d75800ae38766 100644 --- a/web/app.js +++ b/web/app.js @@ -670,18 +670,22 @@ const PDFViewerApplication = { // Enable dragging-and-dropping a new PDF file onto the viewerContainer. appConfig.mainContainer.addEventListener("dragover", function (evt) { - evt.preventDefault(); - - evt.dataTransfer.dropEffect = - evt.dataTransfer.effectAllowed === "copy" ? "copy" : "move"; + for (const item of evt.dataTransfer.items) { + if (item.type === "application/pdf") { + evt.dataTransfer.dropEffect = + evt.dataTransfer.effectAllowed === "copy" ? "copy" : "move"; + evt.preventDefault(); + evt.stopPropagation(); + return; + } + } }); appConfig.mainContainer.addEventListener("drop", function (evt) { - evt.preventDefault(); - - const { files } = evt.dataTransfer; - if (!files || files.length === 0) { + if (evt.dataTransfer.files?.[0].type !== "application/pdf") { return; } + evt.preventDefault(); + evt.stopPropagation(); eventBus.dispatch("fileinputchange", { source: this, fileInput: evt.dataTransfer,