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

Add a new "activateMode" option key named "action" #3098

Closed
wants to merge 1 commit into from
Closed
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
5 changes: 3 additions & 2 deletions background_scripts/main.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,8 @@ HintCoordinator =
for own frameId, port of @tabState[tabId].ports
@postMessage tabId, parseInt(frameId), messageType, port, request

prepareToActivateMode: (tabId, originatingFrameId, {modeIndex, isVimiumHelpDialog}) ->
@tabState[tabId] = {frameIds: frameIdsForTab[tabId][..], hintDescriptors: {}, originatingFrameId, modeIndex}
prepareToActivateMode: (tabId, originatingFrameId, {modeIndex, action, isVimiumHelpDialog}) ->
@tabState[tabId] = {frameIds: frameIdsForTab[tabId][..], hintDescriptors: {}, originatingFrameId, modeIndex, action}
@tabState[tabId].ports = {}
frameIdsForTab[tabId].map (frameId) => @tabState[tabId].ports[frameId] = portsForTab[tabId][frameId]
@sendMessage "getHintDescriptors", tabId, {modeIndex, isVimiumHelpDialog}
Expand All @@ -419,6 +419,7 @@ HintCoordinator =
originatingFrameId: @tabState[tabId].originatingFrameId
hintDescriptors: hintDescriptors
modeIndex: @tabState[tabId].modeIndex
action: @tabState[tabId].action

# If an unregistering frame is participating in link-hints mode, then we need to tidy up after it.
unregisterFrame: (tabId, frameId) ->
Expand Down
32 changes: 25 additions & 7 deletions content_scripts/link_hints.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,19 @@ DOWNLOAD_LINK_URL =
availableModes = [OPEN_IN_CURRENT_TAB, OPEN_IN_NEW_BG_TAB, OPEN_IN_NEW_FG_TAB, OPEN_WITH_QUEUE, COPY_LINK_URL,
OPEN_INCOGNITO, DOWNLOAD_LINK_URL]

availableActions =
focus: (link) -> link.focus()
hover: (link) -> DomUtils.simulateHover link
unhover: (link) -> DomUtils.simulateUnhover link
"yank-text": (link) ->
if link.text?
HUD.copyToClipboard link.text
text = link.text
text = text[0..25] + "...." if 28 < text.length
HUD.showForDuration "Yanked #{text}", 2000
else
HUD.showForDuration "No text to yank.", 2000

HintCoordinator =
onExit: []
localHints: null
Expand All @@ -57,7 +70,7 @@ HintCoordinator =
sendMessage: (messageType, request = {}) ->
Frame.postMessage "linkHintsMessage", extend request, {messageType}

prepareToActivateMode: (mode, onExit) ->
prepareToActivateMode: (mode, action, onExit) ->
# We need to communicate with the background page (and other frames) to initiate link-hints mode. To
# prevent other Vimium commands from being triggered before link-hints mode is launched, we install a
# temporary mode to block (and cache) keyboard events.
Expand All @@ -71,7 +84,7 @@ HintCoordinator =
Utils.setTimeout 1000, -> cacheAllKeydownEvents.exit() if cacheAllKeydownEvents?.modeIsActive
@onExit = [onExit]
@sendMessage "prepareToActivateMode",
modeIndex: availableModes.indexOf(mode), isVimiumHelpDialog: window.isVimiumHelpDialog
{modeIndex: availableModes.indexOf(mode), action, isVimiumHelpDialog: window.isVimiumHelpDialog}

# Hint descriptors are global. They include all of the information necessary for each frame to determine
# whether and when a hint from *any* frame is selected. They include the following properties:
Expand All @@ -96,7 +109,7 @@ HintCoordinator =
# We activate LinkHintsMode() in every frame and provide every frame with exactly the same hint descriptors.
# We also propagate the key state between frames. Therefore, the hint-selection process proceeds in lock
# step in every frame, and @linkHintsMode is in the same state in every frame.
activateMode: ({hintDescriptors, modeIndex, originatingFrameId}) ->
activateMode: ({hintDescriptors, modeIndex, action, originatingFrameId}) ->
# We do not receive the frame's own hint descritors back from the background page. Instead, we merge them
# with the hint descriptors from other frames here.
[hintDescriptors[frameId], @localHintDescriptors] = [@localHintDescriptors, null]
Expand All @@ -105,7 +118,7 @@ HintCoordinator =
DomUtils.documentReady => Settings.onLoaded =>
@cacheAllKeydownEvents.exit() if @cacheAllKeydownEvents?.modeIsActive
@onExit = [] unless frameId == originatingFrameId
@linkHintsMode = new LinkHintsMode hintDescriptors, availableModes[modeIndex]
@linkHintsMode = new LinkHintsMode hintDescriptors, availableModes[modeIndex], action
# Replay keydown events which we missed (but for filtered hints only).
@cacheAllKeydownEvents?.replayKeydownEvents() if Settings.get "filterLinkHints"
@cacheAllKeydownEvents = null
Expand All @@ -124,10 +137,11 @@ HintCoordinator =
@linkHintsMode = @localHints = null

LinkHints =
activateMode: (count = 1, {mode}) ->
activateMode: (count = 1, {mode, registryEntry}) ->
mode ?= OPEN_IN_CURRENT_TAB
action = registryEntry?.options?.action
if 0 < count or mode is OPEN_WITH_QUEUE
HintCoordinator.prepareToActivateMode mode, (isSuccess) ->
HintCoordinator.prepareToActivateMode mode, action, (isSuccess) ->
if isSuccess
# Wait for the next tick to allow the previous mode to exit. It might yet generate a click event,
# which would cause our new mode to exit immediately.
Expand All @@ -144,14 +158,16 @@ class LinkHintsMode
hintMarkerContainingDiv: null
# One of the enums listed at the top of this file.
mode: undefined
# Value of command option with key named "action".
action: undefined
# Function that does the appropriate action on the selected link.
linkActivator: undefined
# The link-hints "mode" (in the key-handler, indicator sense).
hintMode: null
# A count of the number of Tab presses since the last non-Tab keyboard event.
tabCount: 0

constructor: (hintDescriptors, @mode = OPEN_IN_CURRENT_TAB) ->
constructor: (hintDescriptors, @mode = OPEN_IN_CURRENT_TAB, @action) ->
# We need documentElement to be ready in order to append links.
return unless document.documentElement

Expand Down Expand Up @@ -377,6 +393,8 @@ class LinkHintsMode
else if DomUtils.isSelectable clickEl
window.focus()
DomUtils.simulateSelect clickEl
else if availableActions?[@action]
availableActions[@action] clickEl
else
clickActivator = (modifiers) -> (link) -> DomUtils.simulateClick link, modifiers
linkActivator = @mode.linkActivator ? clickActivator @mode.clickModifiers
Expand Down
7 changes: 7 additions & 0 deletions lib/dom_utils.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,13 @@ DomUtils =
if element.selectionStart == 0 and element.selectionEnd == 0
element.setSelectionRange element.value.length, element.value.length

# From @smblott-github: https://github.com/philc/vimium/pull/1948.
simulateHover: (element, modifiers = {}) ->
@simulateMouseEvent "mouseover", element, modifiers

simulateUnhover: (element, modifiers = {}) ->
@simulateMouseEvent "mouseout", element, modifiers

simulateClick: (element, modifiers = {}) ->
eventSequence = ["mouseover", "mousedown", "mouseup", "click"]
for event in eventSequence
Expand Down