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

Mouse out of last clicked element when ESC is typed #4420

Merged
merged 2 commits into from
Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions content_scripts/link_hints.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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);
}
}
Expand Down
5 changes: 4 additions & 1 deletion content_scripts/mode_key_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,14 @@ 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) {
// 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);
Expand Down
1 change: 0 additions & 1 deletion content_scripts/mode_visual.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
4 changes: 1 addition & 3 deletions lib/handler_stack.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down