aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--background_scripts/main.coffee21
-rw-r--r--content_scripts/link_hints.coffee54
-rw-r--r--content_scripts/vimium_frontend.coffee1
-rw-r--r--lib/dom_utils.coffee8
5 files changed, 49 insertions, 37 deletions
diff --git a/README.md b/README.md
index 5e0d18d7..38d6289f 100644
--- a/README.md
+++ b/README.md
@@ -173,6 +173,8 @@ In `master` (not yet released)
- Backup and restore Vimium options (see the very bottom of the options page, below *Advanced Options*).
- It is now possible to map `<tab>`, `<enter>`, `<delete>`, `<insert>`, `<home>` and `<end>`.
+- New command options for `createTab` to create create new normal and incognito windows
+ ([examples](https://github.com/philc/vimium/wiki/Tips-and-Tricks#creating-tabs-with-urls-and-windows)).
1.61 (2017-10-27)
diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee
index 8f095ef1..4e36907a 100644
--- a/background_scripts/main.coffee
+++ b/background_scripts/main.coffee
@@ -188,13 +188,20 @@ BackgroundCommands =
[if request.tab.incognito then "chrome://newtab" else chrome.runtime.getURL newTabUrl]
else
[newTabUrl]
- urls = request.urls[..].reverse()
- do openNextUrl = (request) ->
- if 0 < urls.length
- TabOperations.openUrlInNewTab (extend request, {url: urls.pop()}), (tab) ->
- openNextUrl extend request, {tab, tabId: tab.id}
- else
- callback request
+ if request.registryEntry.options.incognito or request.registryEntry.options.window
+ windowConfig =
+ url: request.urls
+ focused: true
+ incognito: request.registryEntry.options.incognito ? false
+ chrome.windows.create windowConfig, -> callback request
+ else
+ urls = request.urls[..].reverse()
+ do openNextUrl = (request) ->
+ if 0 < urls.length
+ TabOperations.openUrlInNewTab (extend request, {url: urls.pop()}), (tab) ->
+ openNextUrl extend request, {tab, tabId: tab.id}
+ else
+ callback request
duplicateTab: mkRepeatCommand (request, callback) ->
chrome.tabs.duplicate request.tabId, (tab) -> callback extend request, {tab, tabId: tab.id}
moveTabToNewWindow: ({count, tab}) ->
diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee
index f57ec6c7..d4a95d36 100644
--- a/content_scripts/link_hints.coffee
+++ b/content_scripts/link_hints.coffee
@@ -232,13 +232,9 @@ class LinkHintsMode
onKeyDownInMode: (event) ->
return if event.repeat
- previousTabCount = @tabCount
- @tabCount = 0
-
# NOTE(smblott) The modifier behaviour here applies only to alphabet hints.
if event.key in ["Control", "Shift"] and not Settings.get("filterLinkHints") and
@mode in [ OPEN_IN_CURRENT_TAB, OPEN_WITH_QUEUE, OPEN_IN_NEW_BG_TAB, OPEN_IN_NEW_FG_TAB ]
- @tabCount = previousTabCount
# Toggle whether to open the link in a new or current tab.
previousMode = @mode
key = event.key
@@ -258,6 +254,7 @@ class LinkHintsMode
else if KeyboardUtils.isBackspace event
if @markerMatcher.popKeyChar()
+ @tabCount = 0
@updateVisibleMarkers()
else
# Exit via @hintMode.exit(), so that the LinkHints.activate() "onExit" callback sees the key event and
@@ -269,15 +266,13 @@ class LinkHintsMode
HintCoordinator.sendMessage "activateActiveHintMarker" if @markerMatcher.activeHintMarker
else if event.key == "Tab"
- @tabCount = previousTabCount + (if event.shiftKey then -1 else 1)
- @updateVisibleMarkers @tabCount
+ if event.shiftKey then @tabCount-- else @tabCount++
+ @updateVisibleMarkers()
else if event.key == " " and @markerMatcher.shouldRotateHints event
- @tabCount = previousTabCount
HintCoordinator.sendMessage "rotateHints"
else
- @tabCount = previousTabCount if event.ctrlKey or event.metaKey or event.altKey
unless event.repeat
keyChar =
if Settings.get "filterLinkHints"
@@ -287,16 +282,18 @@ class LinkHintsMode
if keyChar
keyChar = " " if keyChar == "space"
if keyChar.length == 1
+ @tabCount = 0
@markerMatcher.pushKeyChar keyChar
@updateVisibleMarkers()
else
- return
+ return handlerStack.suppressPropagation
handlerStack.suppressEvent
- updateVisibleMarkers: (tabCount = 0) ->
+ updateVisibleMarkers: ->
{hintKeystrokeQueue, linkTextKeystrokeQueue} = @markerMatcher
- HintCoordinator.sendMessage "updateKeyState", {hintKeystrokeQueue, linkTextKeystrokeQueue, tabCount}
+ HintCoordinator.sendMessage "updateKeyState",
+ {hintKeystrokeQueue, linkTextKeystrokeQueue, tabCount: @tabCount}
updateKeyState: ({hintKeystrokeQueue, linkTextKeystrokeQueue, tabCount}) ->
extend @markerMatcher, {hintKeystrokeQueue, linkTextKeystrokeQueue}
@@ -305,7 +302,7 @@ class LinkHintsMode
if linksMatched.length == 0
@deactivateMode()
else if linksMatched.length == 1
- @activateLink linksMatched[0], userMightOverType ? false
+ @activateLink linksMatched[0], userMightOverType
else
@hideMarker marker for marker in @hintMarkers
@showMarker matched, @markerMatcher.hintKeystrokeQueue.length for matched in linksMatched
@@ -359,7 +356,7 @@ class LinkHintsMode
# When only one hint remains, activate it in the appropriate way. The current frame may or may not contain
# the matched link, and may or may not have the focus. The resulting four cases are accounted for here by
# selectively pushing the appropriate HintCoordinator.onExit handlers.
- activateLink: (linkMatched, userMightOverType=false) ->
+ activateLink: (linkMatched, userMightOverType = false) ->
@removeHintMarkers()
if linkMatched.isLocalMarker
@@ -385,25 +382,26 @@ class LinkHintsMode
clickEl.focus()
linkActivator clickEl
- installKeyboardBlocker = (startKeyboardBlocker) ->
- if linkMatched.isLocalMarker
- {top: viewportTop, left: viewportLeft} = DomUtils.getViewportTopLeft()
- for rect in (Rect.copy rect for rect in clickEl.getClientRects())
- extend rect, top: rect.top + viewportTop, left: rect.left + viewportLeft
- flashEl = DomUtils.addFlashRect rect
- do (flashEl) -> HintCoordinator.onExit.push -> DomUtils.removeElement flashEl
-
- if windowIsFocused()
- startKeyboardBlocker (isSuccess) -> HintCoordinator.sendMessage "exit", {isSuccess}
+ # If flash elements are created, then this function can be used later to remove them.
+ removeFlashElements = ->
+ if linkMatched.isLocalMarker
+ {top: viewportTop, left: viewportLeft} = DomUtils.getViewportTopLeft()
+ flashElements = for rect in clickEl.getClientRects()
+ DomUtils.addFlashRect Rect.translate rect, viewportLeft, viewportTop
+ removeFlashElements = -> DomUtils.removeElement flashEl for flashEl in flashElements
# If we're using a keyboard blocker, then the frame with the focus sends the "exit" message, otherwise the
# frame containing the matched link does.
- if userMightOverType and Settings.get "waitForEnterForFilteredHints"
- installKeyboardBlocker (callback) -> new WaitForEnter callback
- else if userMightOverType
- installKeyboardBlocker (callback) -> new TypingProtector 200, callback
+ if userMightOverType
+ HintCoordinator.onExit.push removeFlashElements
+ if windowIsFocused()
+ callback = (isSuccess) -> HintCoordinator.sendMessage "exit", {isSuccess}
+ if Settings.get "waitForEnterForFilteredHints"
+ new WaitForEnter callback
+ else
+ new TypingProtector 200, callback
else if linkMatched.isLocalMarker
- DomUtils.flashRect linkMatched.rect
+ Utils.setTimeout 400, removeFlashElements
HintCoordinator.sendMessage "exit", isSuccess: true
#
diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee
index fa973e43..432fa7a2 100644
--- a/content_scripts/vimium_frontend.coffee
+++ b/content_scripts/vimium_frontend.coffee
@@ -221,6 +221,7 @@ Frame =
@port = chrome.runtime.connect name: "frames"
@port.onMessage.addListener (request) =>
+ root.extend window, root unless extend? # See #2800 and #2831.
(@listeners[request.handler] ? this[request.handler]) request
# We disable the content scripts when we lose contact with the background page, or on unload.
diff --git a/lib/dom_utils.coffee b/lib/dom_utils.coffee
index 95b9f4b3..67d5a44c 100644
--- a/lib/dom_utils.coffee
+++ b/lib/dom_utils.coffee
@@ -363,8 +363,12 @@ DomUtils =
@remove() if event.target == window
handlerStack.continueBubbling
callback?()
- @suppressEvent event
- handlerStack.suppressEvent
+ if suppressPropagation
+ DomUtils.suppressPropagation event
+ handlerStack.suppressPropagation
+ else
+ DomUtils.suppressEvent event
+ handlerStack.suppressEvent
# Polyfill for selection.type (which is not available in Firefox).
getSelectionType: (selection = document.getSelection()) ->