diff options
| -rw-r--r-- | CREDITS | 2 | ||||
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | background_scripts/commands.coffee | 9 | ||||
| -rw-r--r-- | background_scripts/main.coffee | 1 | ||||
| -rw-r--r-- | content_scripts/scroller.coffee | 29 | ||||
| -rw-r--r-- | lib/keyboard_utils.coffee | 22 |
6 files changed, 45 insertions, 23 deletions
@@ -46,5 +46,7 @@ Contributors: Michael Salihi <admin@prestance-informatique.fr> (github: PrestanceDesign) Dahan Gong <gdh1995@qq.com> (github: gdh1995) Scott Pinkelman <scott@scottpinkelman.com> (github: sco-tt) + Darryl Pogue <darryl@dpogue.ca> (github: dpogue) + tobimensch Feel free to add real names in addition to GitHub usernames. @@ -161,6 +161,9 @@ Release Notes Changes since previous release (not in the Chrome Store version) +- New commands: + - `toggleMuteTab` - mute or unmute the current tab (default binding `<a-m>`). +- You can now map `<backspace>` to a Vimium command (e.g. `map <backspace> goBack`). - Bug fixes: - `<c-a-[>` is no longer handled (incorrectly) as `Escape`. This also affects `<Alt-Gr-[>`. @@ -390,7 +393,7 @@ Changes since previous release (not in the Chrome Store version) - In link hints mode, holding down the shift key will now toggle between opening in the current tab and opening in a new tab. - Two new commands (`zH` and `zL`) to scroll to the left and right edges of the page. -- A new command (`gi`) to focus the first (or n-th) text input box on the page. +- A new command (`gi`) to focus the first (or n-th) visible text input. - A new command (`<a-f>`) to open up multiple links at a time in new tabs. - Frame support. - More robust support for non-US keyboard layouts. diff --git a/background_scripts/commands.coffee b/background_scripts/commands.coffee index c334cf9d..e905c410 100644 --- a/background_scripts/commands.coffee +++ b/background_scripts/commands.coffee @@ -41,7 +41,7 @@ Commands = # them you have to press "shift" as well. normalizeKey: (key) -> key.replace(/<[acm]-/ig, (match) -> match.toLowerCase()) - .replace(/<([acm]-)?([a-zA-Z0-9]{2,5})>/g, (match, optionalPrefix, keyName) -> + .replace(/<([acm]-)?([a-zA-Z0-9]{2,})>/g, (match, optionalPrefix, keyName) -> "<" + (if optionalPrefix then optionalPrefix else "") + keyName.toLowerCase() + ">") parseCustomKeyMappings: (customKeyMappings) -> @@ -97,7 +97,7 @@ Commands = # Keys are either literal characters, or "named" - for example <a-b> (alt+b), <left> (left arrow) or <f12> # This regular expression captures two groups: the first is a named key, the second is the remainder of # the string. - namedKeyRegex = /^(<(?:[amc]-.|(?:[amc]-)?[a-z0-9]{2,5})>)(.*)$/ + namedKeyRegex = /^(<(?:[amc]-.|(?:[amc]-)?[a-z0-9]{2,})>)(.*)$/ keyStateMapping = {} for own keys, registryEntry of @keyToCommandRegistry currentMapping = keyStateMapping @@ -171,6 +171,7 @@ Commands = "lastTab", "duplicateTab", "togglePinTab", + "toggleMuteTab", "removeTab", "restoreTab", "moveTabToNewWindow", @@ -273,6 +274,7 @@ defaultKeyMappings = "X": "restoreTab" "<a-p>": "togglePinTab" + "<a-m>": "toggleMuteTab" "o": "Vomnibar.activate" "O": "Vomnibar.activateInNewTab" @@ -362,7 +364,8 @@ commandDescriptions = restoreTab: ["Restore closed tab", { background: true, repeatLimit: 20 }] moveTabToNewWindow: ["Move tab to new window", { background: true }] - togglePinTab: ["Pin/unpin current tab", { background: true, noRepeat: true }] + togglePinTab: ["Pin or unpin current tab", { background: true, noRepeat: true }] + toggleMuteTab: ["Mute or unmute current tab", { background: true, noRepeat: true }] closeTabsOnLeft: ["Close tabs on the left", {background: true, noRepeat: true}] closeTabsOnRight: ["Close tabs on the right", {background: true, noRepeat: true}] diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 929d5537..d9b527ef 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -210,6 +210,7 @@ BackgroundCommands = openCopiedUrlInCurrentTab: (request) -> TabOperations.openUrlInCurrentTab extend request, url: Clipboard.paste() openCopiedUrlInNewTab: (request) -> @createTab extend request, url: Clipboard.paste() togglePinTab: ({tab}) -> chrome.tabs.update tab.id, {pinned: !tab.pinned} + toggleMuteTab: ({tab}) -> chrome.tabs.update tab.id, {muted: !tab.mutedInfo.muted} moveTabLeft: moveTab moveTabRight: moveTab nextFrame: ({count, frameId, tabId}) -> diff --git a/content_scripts/scroller.coffee b/content_scripts/scroller.coffee index 56b9a6c6..3a1b3772 100644 --- a/content_scripts/scroller.coffee +++ b/content_scripts/scroller.coffee @@ -4,6 +4,12 @@ # activatedElement = null +# Previously, the main scrolling element was document.body. If the "experimental web platform features" flag +# is enabled, then we need to use document.scrollingElement instead. There's an explanation in #2168: +# https://github.com/philc/vimium/pull/2168#issuecomment-236488091 + +getScrollingElement = -> document.scrollingElement ? document.body + # Return 0, -1 or 1: the sign of the argument. # NOTE(smblott; 2014/12/17) We would like to use Math.sign(). However, according to this site # (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign) Math.sign() was @@ -37,7 +43,7 @@ getDimension = (el, direction, amount) -> name = amount # the clientSizes of the body are the dimensions of the entire page, but the viewport should only be the # part visible through the window - if name is 'viewSize' and el is document.body + if name is 'viewSize' and el is getScrollingElement() # TODO(smblott) Should we not be returning the width/height of element, here? if direction is 'x' then window.innerWidth else window.innerHeight else @@ -82,13 +88,14 @@ isScrollableElement = (element, direction = "y", amount = 1, factor = 1) -> # From element and its parents, find the first which we should scroll and which does scroll. findScrollableElement = (element, direction, amount, factor) -> - while element != document.body and not isScrollableElement element, direction, amount, factor - element = DomUtils.getContainingElement(element) ? document.body + while element != getScrollingElement() and not isScrollableElement element, direction, amount, factor + element = DomUtils.getContainingElement(element) ? getScrollingElement() element -# On some pages, document.body is not scrollable. Here, we search the document for the largest visible -# element which does scroll vertically. This is used to initialize activatedElement. See #1358. -firstScrollableElement = (element=document.body) -> +# On some pages, the scrolling element is not actually scrollable. Here, we search the document for the +# largest visible element which does scroll vertically. This is used to initialize activatedElement. See +# #1358. +firstScrollableElement = (element=getScrollingElement()) -> if doesScroll(element, "y", 1, 1) or doesScroll(element, "y", -1, 1) element else @@ -234,14 +241,14 @@ Scroller = # :factor is needed because :amount can take on string values, which scrollBy converts to element dimensions. scrollBy: (direction, amount, factor = 1, continuous = true) -> # if this is called before domReady, just use the window scroll function - if (!document.body and amount instanceof Number) + if (!getScrollingElement() and amount instanceof Number) if (direction == "x") window.scrollBy(amount, 0) else window.scrollBy(0, amount) return - activatedElement ||= (document.body and firstScrollableElement()) or document.body + activatedElement ||= (getScrollingElement() and firstScrollableElement()) or getScrollingElement() return unless activatedElement # Avoid the expensive scroll calculation if it will not be used. This reduces costs during smooth, @@ -252,7 +259,7 @@ Scroller = CoreScroller.scroll element, direction, elementAmount, continuous scrollTo: (direction, pos) -> - activatedElement ||= (document.body and firstScrollableElement()) or document.body + activatedElement ||= (getScrollingElement() and firstScrollableElement()) or getScrollingElement() return unless activatedElement element = findScrollableElement activatedElement, direction, pos, 1 @@ -261,13 +268,13 @@ Scroller = # Is element scrollable and not the activated element? isScrollableElement: (element) -> - activatedElement ||= (document.body and firstScrollableElement()) or document.body + activatedElement ||= (getScrollingElement() and firstScrollableElement()) or getScrollingElement() element != activatedElement and isScrollableElement element # Scroll the top, bottom, left and right of element into view. The is used by visual mode to ensure the # focus remains visible. scrollIntoView: (element) -> - activatedElement ||= document.body and firstScrollableElement() + activatedElement ||= getScrollingElement() and firstScrollableElement() rect = element. getClientRects()?[0] if rect? # Scroll y axis. diff --git a/lib/keyboard_utils.coffee b/lib/keyboard_utils.coffee index 9c694826..dabf864d 100644 --- a/lib/keyboard_utils.coffee +++ b/lib/keyboard_utils.coffee @@ -4,7 +4,7 @@ KeyboardUtils = f12: 123, tab: 9, downArrow: 40, upArrow: 38 } keyNames: - { 37: "left", 38: "up", 39: "right", 40: "down", 32: "space" } + { 37: "left", 38: "up", 39: "right", 40: "down", 32: "space", 8: "backspace" } # This is a mapping of the incorrect keyIdentifiers generated by Webkit on Windows during keydown events to # the correct identifiers, which are correctly generated on Mac. We require this mapping to properly handle @@ -53,15 +53,21 @@ KeyboardUtils = "" getKeyCharUsingKeyIdentifier: (event) -> - # Not a letter - if (event.keyIdentifier.slice(0, 2) != "U+") - return @keyNames[event.keyCode] if (@keyNames[event.keyCode]) - # F-key - if (event.keyCode >= @keyCodes.f1 && event.keyCode <= @keyCodes.f12) - return "f" + (1 + event.keyCode - keyCodes.f1) - return "" + # Handle named keys. + keyCode = event.keyCode + if keyCode + if keyCode of @keyNames + return @keyNames[keyCode] + # Function keys. + if @keyCodes.f1 <= keyCode <= @keyCodes.f12 + return "f" + (1 + keyCode - keyCodes.f1) keyIdentifier = event.keyIdentifier + + # Not a letter. + if not keyIdentifier.startsWith "U+" + return "" + # On Windows, the keyIdentifiers for non-letter keys are incorrect. See # https://bugs.webkit.org/show_bug.cgi?id=19906 for more details. if ((@platform == "Windows" || @platform == "Linux") && @keyIdentifierCorrectionMap[keyIdentifier]) |
