diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/clipboard.coffee | 12 | ||||
| -rw-r--r-- | lib/dom_utils.coffee | 25 | ||||
| -rw-r--r-- | lib/find_mode_history.coffee | 3 | ||||
| -rw-r--r-- | lib/handler_stack.coffee | 14 | ||||
| -rw-r--r-- | lib/keyboard_utils.coffee | 32 | ||||
| -rw-r--r-- | lib/rect.coffee | 20 | ||||
| -rw-r--r-- | lib/settings.coffee | 7 | ||||
| -rw-r--r-- | lib/utils.coffee | 13 |
8 files changed, 74 insertions, 52 deletions
diff --git a/lib/clipboard.coffee b/lib/clipboard.coffee index af143dd9..a9e2e82e 100644 --- a/lib/clipboard.coffee +++ b/lib/clipboard.coffee @@ -1,8 +1,9 @@ Clipboard = - _createTextArea: -> - textArea = document.createElement "textarea" + _createTextArea: (tagName = "textarea") -> + textArea = document.createElement tagName textArea.style.position = "absolute" textArea.style.left = "-100%" + textArea.contentEditable = "true" textArea # http://groups.google.com/group/chromium-extensions/browse_thread/thread/49027e7f3b04f68/f6ab2457dee5bf55 @@ -16,14 +17,15 @@ Clipboard = document.body.removeChild(textArea) paste: -> - textArea = @_createTextArea() + textArea = @_createTextArea "div" # Use a <div> so Firefox pastes rich text. document.body.appendChild(textArea) textArea.focus() document.execCommand("Paste") - value = textArea.value + value = textArea.innerText document.body.removeChild(textArea) value -root = exports ? window +root = exports ? (window.root ?= {}) root.Clipboard = Clipboard +extend window, root unless exports? diff --git a/lib/dom_utils.coffee b/lib/dom_utils.coffee index ff5991dc..67d5a44c 100644 --- a/lib/dom_utils.coffee +++ b/lib/dom_utils.coffee @@ -219,7 +219,7 @@ DomUtils = node = selection.anchorNode node and @isDOMDescendant element, node else - if selection.type == "Range" and selection.isCollapsed + if DomUtils.getSelectionType(selection) == "Range" and selection.isCollapsed # The selection is inside the Shadow DOM of a node. We can check the node it registers as being # before, since this represents the node whose Shadow DOM it's inside. containerNode = selection.anchorNode.childNodes[selection.anchorOffset] @@ -344,7 +344,7 @@ DomUtils = consumeKeyup: do -> handlerId = null - (event, callback = null) -> + (event, callback = null, suppressPropagation) -> unless event.repeat handlerStack.remove handlerId if handlerId? code = event.code @@ -353,17 +353,25 @@ DomUtils = keyup: (event) -> return handlerStack.continueBubbling unless event.code == code @remove() - handlerStack.suppressEvent + if suppressPropagation + DomUtils.suppressPropagation event + else + DomUtils.suppressEvent event + handlerStack.continueBubbling # We cannot track keyup events if we lose the focus. blur: (event) -> @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) -> + getSelectionType: (selection = document.getSelection()) -> selection.type or do -> if selection.rangeCount == 0 "None" @@ -376,7 +384,7 @@ DomUtils = # This finds the element containing the selection focus. getElementWithFocus: (selection, backwards) -> r = t = selection.getRangeAt 0 - if selection.type == "Range" + if DomUtils.getSelectionType(selection) == "Range" r = t.cloneRange() r.collapse backwards t = r.startContainer @@ -416,5 +424,6 @@ DomUtils = style.textContent = Settings.get "userDefinedLinkHintCss" document.head.appendChild style -root = exports ? window +root = exports ? (window.root ?= {}) root.DomUtils = DomUtils +extend window, root unless exports? diff --git a/lib/find_mode_history.coffee b/lib/find_mode_history.coffee index ff660bd2..93698266 100644 --- a/lib/find_mode_history.coffee +++ b/lib/find_mode_history.coffee @@ -46,5 +46,6 @@ FindModeHistory = refreshRawQueryList: (query, rawQueryList) -> ([ query ].concat rawQueryList.filter (q) => q != query)[0..@max] -root = exports ? window +root = exports ? (window.root ?= {}) root.FindModeHistory = FindModeHistory +extend window, root unless exports? diff --git a/lib/handler_stack.coffee b/lib/handler_stack.coffee index 806b707f..a43fc356 100644 --- a/lib/handler_stack.coffee +++ b/lib/handler_stack.coffee @@ -1,4 +1,4 @@ -root = exports ? window +root = exports ? (window.root ?= {}) class HandlerStack constructor: -> @@ -57,7 +57,10 @@ class HandlerStack if result == @passEventToPage return true else if result == @suppressPropagation - DomUtils.suppressPropagation event + if type == "keydown" + DomUtils.consumeKeyup event, null, true + else + DomUtils.suppressPropagation event return false else if result == @restartBubbling return @bubbleEvent type, event @@ -65,7 +68,11 @@ class HandlerStack true # Do nothing, but continue bubbling. else # result is @suppressEvent or falsy. - DomUtils.suppressEvent event if @isChromeEvent event + if @isChromeEvent event + if type == "keydown" + DomUtils.consumeKeyup event + else + DomUtils.suppressEvent event return false # None of our handlers care about this event, so pass it to the page. @@ -120,3 +127,4 @@ class HandlerStack root.HandlerStack = HandlerStack root.handlerStack = new HandlerStack() +extend window, root unless exports? diff --git a/lib/keyboard_utils.coffee b/lib/keyboard_utils.coffee index e14e8b3e..09623e50 100644 --- a/lib/keyboard_utils.coffee +++ b/lib/keyboard_utils.coffee @@ -5,7 +5,7 @@ Utils?.monitorChromeStorage "mapKeyRegistry", (value) => mapKeyRegistry = value KeyboardUtils = # This maps event.key key names to Vimium key names. keyNames: - "ArrowLeft": "left", "ArrowUp": "up", "ArrowRight": "right", "ArrowDown": "down", " ": "space", "Backspace": "backspace" + "ArrowLeft": "left", "ArrowUp": "up", "ArrowRight": "right", "ArrowDown": "down", " ": "space" init: -> if (navigator.userAgent.indexOf("Mac") != -1) @@ -31,19 +31,17 @@ KeyboardUtils = else if key.length == 1 and not event.shiftKey key = key.toLowerCase() - if key of @keyNames - @keyNames[key] # It appears that key is not always defined (see #2453). - else if not key? + unless key "" + else if key of @keyNames + @keyNames[key] + else if @isModifier event + "" # Don't resolve modifier keys. else if key.length == 1 key - else if key.length == 2 and "F1" <= key <= "F9" - key.toLowerCase() # F1 to F9. - else if key.length == 3 and "F10" <= key <= "F12" - key.toLowerCase() # F10 to F12. else - "" + key.toLowerCase() getKeyCharString: (event) -> if keyChar = @getKeyChar event @@ -60,9 +58,13 @@ KeyboardUtils = keyChar = mapKeyRegistry[keyChar] ? keyChar keyChar - isEscape: (event) -> - # <c-[> is mapped to Escape in Vim by default. - event.key == "Escape" || @getKeyCharString(event) == "<c-[>" + isEscape: do -> + useVimLikeEscape = true + Utils.monitorChromeStorage "useVimLikeEscape", (value) -> useVimLikeEscape = value + + (event) -> + # <c-[> is mapped to Escape in Vim by default. + event.key == "Escape" or (useVimLikeEscape and @getKeyCharString(event) == "<c-[>") isBackspace: (event) -> event.key in ["Backspace", "Delete"] @@ -70,6 +72,9 @@ KeyboardUtils = isPrintable: (event) -> @getKeyCharString(event)?.length == 1 + isModifier: (event) -> + event.key in ["Control", "Shift", "Alt", "OS", "AltGraph", "Meta"] + enUsTranslations: "Backquote": ["`", "~"] "Minus": ["-", "_"] @@ -97,5 +102,6 @@ KeyboardUtils = KeyboardUtils.init() -root = exports ? window +root = exports ? (window.root ?= {}) root.KeyboardUtils = KeyboardUtils +extend window, root unless exports? diff --git a/lib/rect.coffee b/lib/rect.coffee index d4807cc2..0e9c3417 100644 --- a/lib/rect.coffee +++ b/lib/rect.coffee @@ -67,12 +67,18 @@ Rect = rects.filter (rect) -> rect.height > 0 and rect.width > 0 - contains: (rect1, rect2) -> + # Determine whether two rects overlap. + intersects: (rect1, rect2) -> rect1.right > rect2.left and rect1.left < rect2.right and rect1.bottom > rect2.top and rect1.top < rect2.bottom + # Determine whether two rects overlap, including 0-width intersections at borders. + intersectsStrict: (rect1, rect2) -> + rect1.right >= rect2.left and rect1.left <= rect2.right and + rect1.bottom >= rect2.top and rect1.top <= rect2.bottom + equals: (rect1, rect2) -> for property in ["top", "bottom", "left", "right", "width", "height"] return false if rect1[property] != rect2[property] @@ -82,14 +88,6 @@ Rect = @create (Math.max rect1.left, rect2.left), (Math.max rect1.top, rect2.top), (Math.min rect1.right, rect2.right), (Math.min rect1.bottom, rect2.bottom) - # Determine whether two rects overlap. - rectsOverlap: do -> - halfOverlapChecker = (rect1, rect2) -> - (rect1.left <= rect2.left <= rect1.right or rect1.left <= rect2.right <= rect1.right) and - (rect1.top <= rect2.top <= rect1.bottom or rect1.top <= rect2.bottom <= rect1.bottom) - - (rect1, rect2) -> - halfOverlapChecker(rect1, rect2) or halfOverlapChecker rect2, rect1 - -root = exports ? window +root = exports ? (window.root ?= {}) root.Rect = Rect +extend window, root unless exports? diff --git a/lib/settings.coffee b/lib/settings.coffee index 38718990..fd1ef268 100644 --- a/lib/settings.coffee +++ b/lib/settings.coffee @@ -202,7 +202,7 @@ Settings.init() # Perform migration from old settings versions, if this is the background page. if Utils.isBackgroundPage() - Settings.onLoaded -> + Settings.applyMigrations = -> unless Settings.get "settingsVersion" # This is a new install. For some settings, we retain a legacy default behaviour for existing users but # use a non-default behaviour for new users. @@ -218,5 +218,8 @@ if Utils.isBackgroundPage() # be removed after 1.58 has been out for sufficiently long. Settings.nuke "copyNonDefaultsToChromeStorage-20150717" -root = exports ? window + Settings.onLoaded Settings.applyMigrations.bind Settings + +root = exports ? (window.root ?= {}) root.Settings = Settings +extend window, root unless exports? diff --git a/lib/utils.coffee b/lib/utils.coffee index d0a82cf7..6f38be8f 100644 --- a/lib/utils.coffee +++ b/lib/utils.coffee @@ -32,14 +32,6 @@ Utils = # Returns true whenever the current page is the extension's background page. isBackgroundPage: -> @isExtensionPage() and chrome.extension.getBackgroundPage?() == window - # Takes a dot-notation object string and calls the function that it points to with the correct value for - # 'this'. - invokeCommandString: (str, args...) -> - [names..., name] = str.split '.' - obj = window - obj = obj[component] for component in names - obj[name].apply obj, args - # Escape all special characters, so RegExp will parse the string 'as is'. # Taken from http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex escapeRegexSpecialCharacters: do -> @@ -335,8 +327,11 @@ class JobRunner onReady: (callback) -> @fetcher.use callback -root = exports ? window +root = exports ? (window.root ?= {}) root.Utils = Utils root.SimpleCache = SimpleCache root.AsyncDataFetcher = AsyncDataFetcher root.JobRunner = JobRunner +unless exports? + root.extend = extend + extend window, root |
