aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Blott2014-12-21 06:39:46 +0000
committerStephen Blott2014-12-21 06:39:46 +0000
commit681bc13783d1f1b8579f810dbbc68174a84c1a10 (patch)
tree0f4d5957e853eb23e250326b58e5b322fea77585
parente2fe06c25ad0d478a602f77d3ea052ac0e886233 (diff)
downloadvimium-681bc13783d1f1b8579f810dbbc68174a84c1a10.tar.bz2
Exclusion; multi-rule matching.
-rw-r--r--background_scripts/exclusions.coffee24
-rw-r--r--background_scripts/main.coffee19
-rw-r--r--pages/options.coffee35
3 files changed, 37 insertions, 41 deletions
diff --git a/background_scripts/exclusions.coffee b/background_scripts/exclusions.coffee
index fd74e7da..db86e583 100644
--- a/background_scripts/exclusions.coffee
+++ b/background_scripts/exclusions.coffee
@@ -23,11 +23,14 @@ root.Exclusions = Exclusions =
rules: Settings.get("exclusionRules")
- # Return the first exclusion rule matching the URL, or null.
+ # Merge the matching rules for URL, or null.
getRule: (url) ->
- for rule in @rules
- return rule if url.match(RegexpCache.get(rule.pattern))
- return null
+ matching = (rule for rule in @rules when url.match(RegexpCache.get(rule.pattern)))
+ if matching.length
+ pattern: (rule.pattern for rule in matching).join " | " # Not used; for documentation/debugging only.
+ passKeys: (rule.passKeys for rule in matching).join ""
+ else
+ null
setRules: (rules) ->
# Callers map a rule to null to have it deleted, and rules without a pattern are useless.
@@ -37,19 +40,6 @@ root.Exclusions = Exclusions =
postUpdateHook: (rules) ->
@rules = rules
- # Update an existing rule or add a new rule.
- updateOrAdd: (newRule) ->
- seen = false
- @rules.push(newRule)
- @setRules @rules.map (rule) ->
- if rule.pattern == newRule.pattern
- if seen then null else seen = newRule
- else
- rule
-
- remove: (pattern) ->
- @setRules(@rules.filter((rule) -> rule and rule.pattern != pattern))
-
# Development and debug only.
# Enable this (temporarily) to restore legacy exclusion rules from backup.
if false and Settings.has("excludedUrlsBackup")
diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee
index 647923c0..cebb38ca 100644
--- a/background_scripts/main.coffee
+++ b/background_scripts/main.coffee
@@ -75,26 +75,10 @@ getCurrentTabUrl = (request, sender) -> sender.tab.url
root.isEnabledForUrl = isEnabledForUrl = (request) ->
rule = Exclusions.getRule(request.url)
{
- rule: rule
isEnabledForUrl: not rule or rule.passKeys
passKeys: rule?.passKeys or ""
}
-# Called by the popup UI.
-# If the URL pattern matches an existing rule, then the existing rule is updated. Otherwise, a new rule is created.
-root.addExclusionRule = (pattern,passKeys) ->
- if pattern = pattern.trim()
- Exclusions.updateOrAdd({ pattern: pattern, passKeys: passKeys })
- chrome.tabs.query({ windowId: chrome.windows.WINDOW_ID_CURRENT, active: true },
- (tabs) -> updateActiveState(tabs[0].id))
-
-# Called by the popup UI. Remove all existing exclusion rules with this pattern.
-root.removeExclusionRule = (pattern) ->
- if pattern = pattern.trim()
- Exclusions.remove(pattern)
- chrome.tabs.query({ windowId: chrome.windows.WINDOW_ID_CURRENT, active: true },
- (tabs) -> updateActiveState(tabs[0].id))
-
saveHelpDialogSettings = (request) ->
Settings.set("helpDialog_showAdvancedCommands", request.showAdvancedCommands)
@@ -353,7 +337,8 @@ setBrowserActionIcon = (tabId,path) ->
# Updates the browserAction icon to indicate whether Vimium is enabled or disabled on the current page.
# Also propagates new enabled/disabled/passkeys state to active window, if necessary.
# This lets you disable Vimium on a page without needing to reload.
-updateActiveState = (tabId) ->
+# Exported via root because it's called from the page popup.
+root.updateActiveState = updateActiveState = (tabId) ->
enabledIcon = "icons/browser_action_enabled.png"
disabledIcon = "icons/browser_action_disabled.png"
partialIcon = "icons/browser_action_partial.png"
diff --git a/pages/options.coffee b/pages/options.coffee
index 956c3e4e..1cd0661f 100644
--- a/pages/options.coffee
+++ b/pages/options.coffee
@@ -1,6 +1,18 @@
$ = (id) -> document.getElementById id
bgSettings = chrome.extension.getBackgroundPage().Settings
-Exclusions = chrome.extension.getBackgroundPage().Exclusions
+bgExclusions = chrome.extension.getBackgroundPage().Exclusions
+
+# Generate a default exclusion-rule pattern from a URL.
+generateDefaultPattern = (url) ->
+ if /^https?:\/\/./.test url
+ # The common use case is to disable Vimium at the domain level.
+ # Generate "https?://www.example.com/*" from "http://www.example.com/path/to/page.html".
+ "https?:/" + url.split("/",3)[1..].join("/") + "/*"
+ else if /^[a-z]{3,}:\/\/./.test url
+ # Anything else which seems to be a URL.
+ url.split("/",3).join("/") + "/*"
+ else
+ url + "*"
#
# Class hierarchy for various types of option.
@@ -76,12 +88,17 @@ class CheckBoxOption extends Option
readValueFromElement: -> @element.checked
class ExclusionRulesOption extends Option
- constructor: (field, onUpdated, @url=null) ->
+ constructor: (field, onUpdated, @url="") ->
super(field, onUpdated)
$("exclusionAddButton").addEventListener "click", (event) =>
- @appendRule { pattern: "", passKeys: "" }
- # Focus the pattern element in the new rule.
- @element.children[@element.children.length-1].children[0].children[0].focus()
+ @addRule()
+
+ addRule: ->
+ @appendRule { pattern: (if @url then generateDefaultPattern(@url) else ""), passKeys: "" }
+ # On the options page, focus the pattern; on the page popup (where we already have a pattern), focus the
+ # passKeys.
+ focus = if @url then 1 else 0
+ @element.children[@element.children.length-1].children[focus].children[0].focus()
# Scroll the new rule into view.
exclusionScrollBox = $("exclusionScrollBox")
exclusionScrollBox.scrollTop = exclusionScrollBox.scrollHeight
@@ -96,9 +113,11 @@ class ExclusionRulesOption extends Option
haveMatch = false
for element in @element.getElementsByClassName "exclusionRuleTemplateInstance"
pattern = element.children[0].firstChild.value.trim()
- unless @url.match Exclusions.RegexpCache.get pattern
- element.style.display = 'none'
+ if @url.match bgExclusions.RegexpCache.get pattern
haveMatch = true
+ else
+ element.style.display = 'none'
+ @addRule() unless haveMatch
# Append a row for a new rule.
appendRule: (rule) ->
@@ -222,6 +241,8 @@ initPopupPage = ->
document.addEventListener "keyup", (event) ->
if event.ctrlKey and event.keyCode == 13
Option.saveOptions()
+ chrome.tabs.query { windowId: chrome.windows.WINDOW_ID_CURRENT, active: true }, (tabs) ->
+ chrome.extension.getBackgroundPage().updateActiveState(tabs[0].id)
window.close()
new ExclusionRulesOption("exclusionRules", onUpdated, tab.url)