From e35761dfb7506172ad00150d03653ae3f1adb57d Mon Sep 17 00:00:00 2001 From: Phil Crosby Date: Sat, 10 Feb 2024 22:44:14 -0800 Subject: [PATCH 1/2] Minor cleanups --- content_scripts/mode_key_handler.js | 2 +- content_scripts/mode_visual.js | 1 - lib/handler_stack.js | 4 +--- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/content_scripts/mode_key_handler.js b/content_scripts/mode_key_handler.js index 8b57b83a7..e64feec8b 100644 --- a/content_scripts/mode_key_handler.js +++ b/content_scripts/mode_key_handler.js @@ -62,8 +62,8 @@ class KeyHandlerMode extends Mode { const isEscape = KeyboardUtils.isEscape(event); if (isEscape && ((this.countPrefix !== 0) || (this.keyState.length !== 1))) { return DomUtils.consumeKeyup(event, () => this.reset()); - // If the help dialog loses the focus, then Escape should hide it; see point 2 in #2045. } else if (isEscape && HelpDialog && HelpDialog.isShowing()) { + // If the help dialog loses the focus, then Escape should hide it; see point 2 in #2045. HelpDialog.toggle(); return this.suppressEvent; } else if (isEscape) { diff --git a/content_scripts/mode_visual.js b/content_scripts/mode_visual.js index af68d78ed..45d7df870 100644 --- a/content_scripts/mode_visual.js +++ b/content_scripts/mode_visual.js @@ -271,7 +271,6 @@ class VisualMode extends KeyHandlerMode { this.onExit((event = null) => { // Retain any selection, regardless of how we exit. if (this.shouldRetainSelectionOnExit) { - null; // This mimics vim: when leaving visual mode via Escape, collapse to focus, otherwise // collapse to anchor. } else if ( diff --git a/lib/handler_stack.js b/lib/handler_stack.js index ce35787b0..a00485729 100644 --- a/lib/handler_stack.js +++ b/lib/handler_stack.js @@ -48,9 +48,7 @@ class HandlerStack { // @passEventToPage. bubbleEvent(type, event) { this.eventNumber += 1; - const { - eventNumber, - } = this; + const eventNumber = this.eventNumber; for (const handler of this.stack.slice().reverse()) { // A handler might have been removed (handler.id == null), so check; or there might just be no // handler for this type of event. From 1e50f601df77684f76533f0e5aeb9a28b7a36cb5 Mon Sep 17 00:00:00 2001 From: Phil Crosby Date: Sat, 10 Feb 2024 22:48:37 -0800 Subject: [PATCH 2/2] Mouse out of last clicked element when ESC is typed --- content_scripts/link_hints.js | 14 ++++++++++++++ content_scripts/mode_key_handler.js | 3 +++ 2 files changed, 17 insertions(+) diff --git a/content_scripts/link_hints.js b/content_scripts/link_hints.js index 09276059c..897de31d9 100644 --- a/content_scripts/link_hints.js +++ b/content_scripts/link_hints.js @@ -164,6 +164,10 @@ const HintCoordinator = { localHints: null, cacheAllKeydownEvents: null, + // A WeakRef to the last clicked element. We track this so that we can mouse of it if the user + // types ESC after clicking on it. See #3073. + lastClickedElementRef: null, + // Returns if the HintCoordinator will handle a given LinkHintsMessage. // Some messages will not be handled in the case where the help dialog is shown, and is then // hidden, but is still receiving link hints messages via broadcastLinkHintsMessage. @@ -290,6 +294,15 @@ const HintCoordinator = { } this.linkHintsMode = this.localHints = null; }, + + mouseOutOfLastClickedElement() { + if (this.lastClickedElementRef == null) return; + const el = this.lastClickedElementRef.deref(); + if (el) { + DomUtils.simulateMouseEvent("mouseout", el, null); + } + this.lastClickedElementRef = null; + }, }; const LinkHints = { @@ -680,6 +693,7 @@ class LinkHintsMode { if (["input", "select", "object", "embed"].includes(clickEl.nodeName.toLowerCase())) { clickEl.focus(); } + HintCoordinator.lastClickedElementRef = new WeakRef(clickEl); return linkActivator(clickEl); } } diff --git a/content_scripts/mode_key_handler.js b/content_scripts/mode_key_handler.js index e64feec8b..5a5d677fe 100644 --- a/content_scripts/mode_key_handler.js +++ b/content_scripts/mode_key_handler.js @@ -67,6 +67,9 @@ class KeyHandlerMode extends Mode { HelpDialog.toggle(); return this.suppressEvent; } else if (isEscape) { + // Some links stay "open" after clicking, until you mouse off of them, like Wikipedia's link + // preview popups. If the user types escape, issue a mouseout event here. See #3073. + HintCoordinator.mouseOutOfLastClickedElement(); return this.continueBubbling; } else if (this.isMappedKey(keyChar)) { this.handleKeyChar(keyChar);