aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--README.md2
-rw-r--r--background_scripts/commands.coffee4
-rw-r--r--background_scripts/main.coffee15
-rw-r--r--content_scripts/link_hints.coffee2
-rw-r--r--content_scripts/ui_component.coffee28
-rw-r--r--lib/utils.coffee5
-rw-r--r--tests/dom_tests/dom_tests.coffee2
-rw-r--r--tests/unit_tests/test_chrome_stubs.coffee3
9 files changed, 48 insertions, 15 deletions
diff --git a/.travis.yml b/.travis.yml
index c186f393..971676d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@ language: node_js
node_js: 0.10
before_install:
- "npm install -g coffee-script"
- - "npm install path"
+ - "npm install path@0.11"
- "npm install util"
- "cake build"
script: "cake test"
diff --git a/README.md b/README.md
index d1f7dbbf..9b871b04 100644
--- a/README.md
+++ b/README.md
@@ -155,6 +155,8 @@ Release Notes
-------------
Updates since 1.52 (not yet released)
+- Vimium now works on the new-tab page for Chrome 47.
+- `g0` and `g$` now accept count prefixes; so `2g0` selects the second tab, and so on.
- Bug fixes:
- Fix `moveTabLeft` and `moveTabRight` for pinned tabs (#1814 and #1815).
diff --git a/background_scripts/commands.coffee b/background_scripts/commands.coffee
index 64ec36be..a0b17ebc 100644
--- a/background_scripts/commands.coffee
+++ b/background_scripts/commands.coffee
@@ -309,8 +309,8 @@ commandDescriptions =
# Manipulating tabs
nextTab: ["Go one tab right", { background: true, passCountToFunction: true }]
previousTab: ["Go one tab left", { background: true, passCountToFunction: true }]
- firstTab: ["Go to the first tab", { background: true }]
- lastTab: ["Go to the last tab", { background: true }]
+ firstTab: ["Go to the first tab", { background: true, passCountToFunction: true }]
+ lastTab: ["Go to the last tab", { background: true, passCountToFunction: true }]
createTab: ["Create new tab", { background: true, repeatLimit: 20 }]
duplicateTab: ["Duplicate current tab", { background: true, repeatLimit: 20 }]
diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee
index 1a49c3cb..10f7500e 100644
--- a/background_scripts/main.coffee
+++ b/background_scripts/main.coffee
@@ -267,8 +267,8 @@ BackgroundCommands =
chrome.windows.create {tabId: tab.id, incognito: tab.incognito}
nextTab: (count) -> selectTab "next", count
previousTab: (count) -> selectTab "previous", count
- firstTab: -> selectTab "first"
- lastTab: -> selectTab "last"
+ firstTab: (count) -> selectTab "first", count
+ lastTab: (count) -> selectTab "last", count
removeTab: (callback) ->
chrome.tabs.getSelected(null, (tab) ->
chrome.tabs.remove(tab.id)
@@ -349,15 +349,13 @@ selectTab = (direction, count = 1) ->
toSelect =
switch direction
when "next"
- currentTab.index + count
+ (currentTab.index + count) % tabs.length
when "previous"
- currentTab.index - count
+ (currentTab.index - count + count * tabs.length) % tabs.length
when "first"
- 0
+ Math.min tabs.length - 1, count - 1
when "last"
- tabs.length - 1
- # Bring toSelect into the range [0,tabs.length).
- toSelect = (toSelect + tabs.length * Math.abs count) % tabs.length
+ Math.max 0, tabs.length - count
chrome.tabs.update tabs[toSelect].id, selected: true
updateOpenTabs = (tab, deleteFrames = false) ->
@@ -670,6 +668,7 @@ sendRequestHandlers =
setIcon: setIcon
sendMessageToFrames: sendMessageToFrames
log: bgLog
+ fetchFileContents: (request, sender) -> fetchFileContents request.fileName
# We always remove chrome.storage.local/findModeRawQueryListIncognito on startup.
chrome.storage.local.remove "findModeRawQueryListIncognito"
diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee
index 18c608a5..a5e94fd0 100644
--- a/content_scripts/link_hints.coffee
+++ b/content_scripts/link_hints.coffee
@@ -214,6 +214,8 @@ class LinkHintsMode
(element.readOnly and DomUtils.isSelectable element))
when "button", "select"
isClickable ||= not element.disabled
+ when "label"
+ isClickable ||= element.control? and (@getVisibleClickable element.control).length == 0
# Elements with tabindex are sometimes useful, but usually not. We can treat them as second class
# citizens when it improves UX, so take special note of them.
diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee
index d935079d..72627f69 100644
--- a/content_scripts/ui_component.coffee
+++ b/content_scripts/ui_component.coffee
@@ -4,12 +4,16 @@ class UIComponent
showing: null
options: null
shadowDOM: null
+ styleSheetGetter: null
constructor: (iframeUrl, className, @handleMessage) ->
styleSheet = DomUtils.createElement "style"
styleSheet.type = "text/css"
# Default to everything hidden while the stylesheet loads.
- styleSheet.innerHTML = "@import url(\"#{chrome.runtime.getURL("content_scripts/vimium.css")}\");"
+ styleSheet.innerHTML = "iframe {display: none;}"
+
+ UIComponent::styleSheetGetter ?= new AsyncDataFetcher @fetchFileContents "content_scripts/vimium.css"
+ @styleSheetGetter.use (styles) -> styleSheet.innerHTML = styles
@iframeElement = DomUtils.createElement "iframe"
extend @iframeElement,
@@ -112,5 +116,27 @@ class UIComponent
window.removeEventListener "focus", handler
refocusSourceFrame()
+ # Fetch a Vimium file/resource (such as "content_scripts/vimium.css").
+ # We try making an XMLHttpRequest request. That can fail (see #1817), in which case we fetch the
+ # file/resource via the background page.
+ fetchFileContents: (file) -> (callback) ->
+ request = new XMLHttpRequest()
+
+ request.onload = ->
+ if request.status == 200
+ callback request.responseText
+ else
+ request.onerror()
+
+ request.onerror = ->
+ chrome.runtime.sendMessage
+ handler: "fetchFileContents"
+ fileName: file
+ , callback
+
+ request.open "GET", (chrome.runtime.getURL file), true
+ request.send()
+
+
root = exports ? window
root.UIComponent = UIComponent
diff --git a/lib/utils.coffee b/lib/utils.coffee
index e0b9ba36..b69b926b 100644
--- a/lib/utils.coffee
+++ b/lib/utils.coffee
@@ -150,7 +150,8 @@ Utils =
if Utils.hasChromePrefix string
string
else if Utils.hasJavascriptPrefix string
- Utils.decodeURIByParts string
+ # In Chrome versions older than 46.0.2467.2, encoded javascript URIs weren't handled correctly.
+ if Utils.haveChromeVersion "46.0.2467.2" then string else Utils.decodeURIByParts string
else if Utils.isUrl string
Utils.createFullUrl string
else
@@ -182,7 +183,7 @@ Utils =
# True if the current Chrome version is at least the required version.
haveChromeVersion: (required) ->
- chromeVersion = navigator.appVersion.match(/Chrome\/(.*?) /)?[1]
+ chromeVersion = navigator.appVersion.match(/Chrom(e|ium)\/(.*?) /)?[2]
chromeVersion and 0 <= Utils.compareVersions chromeVersion, required
# Zip two (or more) arrays:
diff --git a/tests/dom_tests/dom_tests.coffee b/tests/dom_tests/dom_tests.coffee
index 9d703774..e814ec76 100644
--- a/tests/dom_tests/dom_tests.coffee
+++ b/tests/dom_tests/dom_tests.coffee
@@ -243,7 +243,7 @@ context "Filtered link hints",
hintMarkers = getHintMarkers()
hintMarkers = getHintMarkers().map (marker) -> marker.textContent.toLowerCase()
# We don't know the actual hint numbers which will be assigned, so we replace them with "N".
- hintMarkers = hintMarkers.map (str) -> str.replace /^[1-5]/, "N"
+ hintMarkers = hintMarkers.map (str) -> str.replace /^[0-9]+/, "N"
assert.equal 5, hintMarkers.length
assert.isTrue "N" in hintMarkers
assert.isTrue "N" in hintMarkers
diff --git a/tests/unit_tests/test_chrome_stubs.coffee b/tests/unit_tests/test_chrome_stubs.coffee
index 0bb6ed81..8814ab23 100644
--- a/tests/unit_tests/test_chrome_stubs.coffee
+++ b/tests/unit_tests/test_chrome_stubs.coffee
@@ -8,6 +8,9 @@
exports.window = {}
exports.localStorage = {}
+global.navigator =
+ appVersion: "5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36"
+
global.document =
createElement: -> {}
addEventListener: ->