From 1bab947c9c16f3725076462a702c880a083afe90 Mon Sep 17 00:00:00 2001 From: Abdo Date: Fri, 10 Jun 2022 16:33:53 +0300 Subject: [PATCH] Fix JS drop event not firing in the reviewer (#1906) * Allow webviews to opt in to default D&D handling * Remove redundant webview.js include * Block default drag & drop behavior in reviewing screens * Fix mypy error --- qt/aqt/browser/previewer.py | 2 ++ qt/aqt/clayout.py | 2 ++ qt/aqt/reviewer.py | 3 +++ qt/aqt/toolbar.py | 2 +- qt/aqt/webview.py | 7 ++++++- ts/reviewer/index.ts | 10 ++++++++++ 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/qt/aqt/browser/previewer.py b/qt/aqt/browser/previewer.py index f33417c95..5ed549286 100644 --- a/qt/aqt/browser/previewer.py +++ b/qt/aqt/browser/previewer.py @@ -132,6 +132,8 @@ class Previewer(QDialog): ], context=self, ) + self._web.allow_drops = True + self._web.eval("_blockDefaultDragDropBehavior();") self._web.set_bridge_command(self._on_bridge_cmd, self) def _on_bridge_cmd(self, cmd: str) -> Any: diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py index 5d56c1646..e10a7dcd6 100644 --- a/qt/aqt/clayout.py +++ b/qt/aqt/clayout.py @@ -355,6 +355,8 @@ class CardLayout(QDialog): ], context=self, ) + self.preview_web.allow_drops = True + self.preview_web.eval("_blockDefaultDragDropBehavior();") self.preview_web.set_bridge_command(self._on_bridge_cmd, self) if self._isCloze(): diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index 3e223b83f..5fd3a011e 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -313,6 +313,9 @@ class Reviewer: ], context=self, ) + # block default drag & drop behavior while allowing drop events to be received by JS handlers + self.web.allow_drops = True + self.web.eval("_blockDefaultDragDropBehavior();") # show answer / ease buttons self.bottom.web.show() self.bottom.web.stdHtml( diff --git a/qt/aqt/toolbar.py b/qt/aqt/toolbar.py index b12ab94cb..c0d0ba320 100644 --- a/qt/aqt/toolbar.py +++ b/qt/aqt/toolbar.py @@ -47,7 +47,7 @@ class Toolbar: self.web.stdHtml( self._body % self._centerLinks(), css=["css/toolbar.css"], - js=["js/webview.js", "js/vendor/jquery.min.js", "js/toolbar.js"], + js=["js/vendor/jquery.min.js", "js/toolbar.js"], context=web_context, ) self.web.adjustHeightToFit() diff --git a/qt/aqt/webview.py b/qt/aqt/webview.py index 4f24274aa..f68b58926 100644 --- a/qt/aqt/webview.py +++ b/qt/aqt/webview.py @@ -222,6 +222,8 @@ class WebContent: class AnkiWebView(QWebEngineView): + allow_drops = False + def __init__( self, parent: Optional[QWidget] = None, @@ -322,7 +324,8 @@ class AnkiWebView(QWebEngineView): m.popup(QCursor.pos()) def dropEvent(self, evt: QDropEvent) -> None: - pass + if self.allow_drops: + super().dropEvent(evt) def setHtml(self, html: str) -> None: # type: ignore # discard any previous pending actions @@ -331,6 +334,7 @@ class AnkiWebView(QWebEngineView): self._queueAction("setHtml", html) self.set_open_links_externally(True) self.setZoomFactor(1) + self.allow_drops = False self.show() def _setHtml(self, html: str) -> None: @@ -357,6 +361,7 @@ class AnkiWebView(QWebEngineView): def load_url(self, url: QUrl) -> None: # allow queuing actions when loading url directly self._domDone = False + self.allow_drops = False super().load(url) def app_zoom_factor(self) -> float: diff --git a/ts/reviewer/index.ts b/ts/reviewer/index.ts index ebb5d9ffc..e857df809 100644 --- a/ts/reviewer/index.ts +++ b/ts/reviewer/index.ts @@ -227,3 +227,13 @@ export function _typeAnsPress(): void { export function _emulateMobile(enabled: boolean): void { document.documentElement.classList.toggle("mobile", enabled); } + +// Block Qt's default drag & drop behavior by default +export function _blockDefaultDragDropBehavior(): void { + function handler(evt: DragEvent) { + evt.preventDefault(); + } + document.ondragenter = handler; + document.ondragover = handler; + document.ondrop = handler; +}