aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Crosby2012-04-06 13:52:18 -0700
committerPhil Crosby2012-04-06 13:52:18 -0700
commit269042a28230bb35406d1447fac8955ca1a5c0b3 (patch)
treed22b6c2f5739601bf2aa36aa0f2b9538f8bef451
parentd15f3abceb2c3ba0006999a194729c1c7cb1a095 (diff)
parent97127e056a27f8c397e97e7948a66d525e1c6a24 (diff)
downloadvimium-269042a28230bb35406d1447fac8955ca1a5c0b3.tar.bz2
Merge pull request #511 from dmacdougall/browser_icon
Browser icon and immediate disable
-rw-r--r--CREDITS1
-rw-r--r--background_page.html62
-rw-r--r--icons/check.pngbin0 -> 393 bytes
-rw-r--r--icons/icon48.pngbin4222 -> 4254 bytes
-rw-r--r--icons/icon48disabled.pngbin0 -> 3648 bytes
-rw-r--r--manifest.json6
-rw-r--r--popup.html79
-rw-r--r--vimiumFrontend.js19
8 files changed, 166 insertions, 1 deletions
diff --git a/CREDITS b/CREDITS
index 47e6116d..1635556d 100644
--- a/CREDITS
+++ b/CREDITS
@@ -32,5 +32,6 @@ Contributors:
Bernardo B. Marques <bernardo.fire@gmail.com> (github: bernardofire)
Niklas Baumstark <niklas.baumstark@gmail.com> (github: niklasb)
Ângelo Otávio Nuffer Nunes <angelonuffer@gmail.com> (github: angelonuffer)
+ Daniel MacDougall <dmacdougall@gmail.com> (github: dmacdougall)
Feel free to add real names in addition to GitHub usernames.
diff --git a/background_page.html b/background_page.html
index aed9617b..d8d3f75b 100644
--- a/background_page.html
+++ b/background_page.html
@@ -113,6 +113,22 @@
return { isEnabledForUrl: isEnabled };
}
+ /*
+ * Called by the popup UI. Strips leading/trailing whitespace and ignores empty strings.
+ */
+ function addExcludedUrl(url) {
+ url = trim(url);
+ if (url === "") { return; }
+
+ var excludedUrls = settings.get("excludedUrls");
+ excludedUrls += "\n" + url;
+ settings.set("excludedUrls", excludedUrls);
+
+ chrome.tabs.query({ windowId: chrome.windows.WINDOW_ID_CURRENT, active: true }, function(tabs) {
+ updateActiveState(tabs[0].id);
+ });
+ }
+
function saveHelpDialogSettings(request) {
settings.set("helpDialog_showAdvancedCommands", request.showAdvancedCommands);
}
@@ -332,6 +348,41 @@
delete framesForTab[tab.id];
}
+ /* Updates the browserAction icon to indicated whether Vimium is enabled or disabled on the current page.
+ * Also disables Vimium if it is currently enabled but should be disabled according to the url blacklist.
+ * This lets you disable Vimium on a page without needing to reload.
+ *
+ * Three situations are considered:
+ * 1. Active tab is disabled -> disable icon
+ * 2. Active tab is enabled and should be enabled -> enable icon
+ * 3. Active tab is enabled but should be disabled -> disable icon and disable vimium
+ */
+ function updateActiveState(tabId) {
+ var enabledIcon = "icons/icon48.png";
+ var disabledIcon = "icons/icon48disabled.png";
+ chrome.tabs.get(tabId, function(tab) {
+ // Default to disabled state in case we can't connect to Vimium, primarily for the "New Tab" page.
+ chrome.browserAction.setIcon({ path: disabledIcon });
+ var returnPort = chrome.tabs.connect(tabId, { name: "getActiveState" });
+ returnPort.onMessage.addListener(function(response) {
+ var isCurrentlyEnabled = response.enabled;
+ var shouldBeEnabled = isEnabledForUrl({url: tab.url}).isEnabledForUrl;
+
+ if (isCurrentlyEnabled) {
+ if (shouldBeEnabled) {
+ chrome.browserAction.setIcon({ path: enabledIcon });
+ } else {
+ chrome.browserAction.setIcon({ path: disabledIcon });
+ chrome.tabs.connect(tabId, { name: "disableVimium" }).postMessage();
+ }
+ } else {
+ chrome.browserAction.setIcon({ path: disabledIcon });
+ }
+ });
+ returnPort.postMessage();
+ });
+ }
+
function handleUpdateScrollPosition(request, sender) {
updateScrollPosition(sender.tab, request.scrollX, request.scrollY);
}
@@ -345,6 +396,7 @@
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.status != "loading") { return; } // only do this once per URL change
updateOpenTabs(tab);
+ updateActiveState(tabId);
});
chrome.tabs.onAttached.addListener(function(tabId, attachedInfo) {
@@ -383,6 +435,10 @@
delete framesForTab[tabId];
});
+ chrome.tabs.onActiveChanged.addListener(function(tabId, selectInfo) {
+ updateActiveState(tabId);
+ });
+
chrome.windows.onRemoved.addListener(function(windowId) {
delete tabQueue[windowId];
});
@@ -667,6 +723,12 @@
return index;
}
+ /*
+ * Convenience function for trimming leading and trailing whitespace.
+ */
+ function trim(str) {
+ return str.replace(/^\s*/, "").replace(/\s*$/, "");
+ }
function init() {
clearKeyMappingsAndSetDefaults();
diff --git a/icons/check.png b/icons/check.png
new file mode 100644
index 00000000..def20c00
--- /dev/null
+++ b/icons/check.png
Binary files differ
diff --git a/icons/icon48.png b/icons/icon48.png
index 6a3202f0..9eb94d4f 100644
--- a/icons/icon48.png
+++ b/icons/icon48.png
Binary files differ
diff --git a/icons/icon48disabled.png b/icons/icon48disabled.png
new file mode 100644
index 00000000..fa6279d3
--- /dev/null
+++ b/icons/icon48disabled.png
Binary files differ
diff --git a/manifest.json b/manifest.json
index 085caaed..72631a94 100644
--- a/manifest.json
+++ b/manifest.json
@@ -29,5 +29,9 @@
"run_at": "document_start",
"all_frames": true
}
- ]
+ ],
+ "browser_action": {
+ "default_icon": "icons/icon48disabled.png",
+ "popup": "popup.html"
+ }
}
diff --git a/popup.html b/popup.html
new file mode 100644
index 00000000..7fb9b646
--- /dev/null
+++ b/popup.html
@@ -0,0 +1,79 @@
+<style>
+ * {
+ margin: 0px;
+ padding: 0px;
+ }
+
+ #vimiumPopup { width: 300px; }
+
+ #excludeControls {
+ padding: 10px;
+ }
+
+ #popupInput {
+ width: 160px;
+ }
+
+ #excludeConfirm {
+ display: inline-block;
+ width: 18px;
+ height: 13px;
+ background: url(icons/check.png) 3px 2px no-repeat;
+ display: none;
+ }
+
+ #popupButton { margin-left: 10px; }
+
+ #popupMenu ul {
+ list-style: none;
+ }
+
+ #popupMenu a, #popupMenu a:active, #popupMenu a:visited {
+ color: #3F6EC2;
+ display: block;
+ border-top: 1px solid #DDDDDD;
+ padding: 3px;
+ padding-left: 10px;
+ }
+
+ #popupMenu a:hover {
+ background: #EEEEEE;
+ }
+</style>
+
+<div id="vimiumPopup">
+ <div id="excludeControls">
+ <input id="popupInput" type="text" />
+ <input id="popupButton" type="button" value="Exclude URL" />
+ <span id="excludeConfirm"></span>
+ </div>
+
+ <div id="popupMenu">
+ <ul>
+ <li><a id="optionsLink" target="_blank">Options</a></li>
+ </ul>
+ </div>
+</div>
+
+
+<script type="text/javascript">
+ function onLoad() {
+ document.getElementById("optionsLink").setAttribute("href", chrome.extension.getURL("options.html"));
+ chrome.tabs.getSelected(null, function(tab) {
+ // The common use case is to disable Vimium at the domain level.
+ // This regexp will match "http://www.example.com/" from "http://www.example.com/path/to/page.html".
+ var domain = tab.url.match(/[^\/]*\/\/[^\/]*\//) || tab.url;
+ document.getElementById("popupInput").value = domain + "*";
+ });
+ }
+
+ function onExcludeUrl(e) {
+ var url = document.getElementById("popupInput").value;
+ chrome.extension.getBackgroundPage().addExcludedUrl(url);
+ document.getElementById("excludeConfirm").setAttribute("style", "display: inline-block");
+ }
+
+ window.addEventListener("load", onLoad, false);
+ document.getElementById("popupButton").addEventListener("click", onExcludeUrl, false);
+</script>
+
diff --git a/vimiumFrontend.js b/vimiumFrontend.js
index 58863c6f..343a7906 100644
--- a/vimiumFrontend.js
+++ b/vimiumFrontend.js
@@ -177,6 +177,12 @@ function initializePreDomReady() {
port.onMessage.addListener(function (args) {
refreshCompletionKeys(args.completionKeys);
});
+ } else if (port.name == "getActiveState") {
+ port.onMessage.addListener(function(args) {
+ port.postMessage({ enabled: isEnabledForUrl });
+ });
+ } else if (port.name == "disableVimium") {
+ port.onMessage.addListener(function(args) { disableVimium(); });
}
});
}
@@ -194,6 +200,19 @@ function initializeWhenEnabled() {
enterInsertModeIfElementIsFocused();
}
+/*
+ * Used to disable Vimium without needing to reload the page.
+ * This is called if the current page's url is blacklisted using the popup UI.
+ */
+function disableVimium() {
+ document.removeEventListener("keydown", onKeydown, true);
+ document.removeEventListener("keypress", onKeypress, true);
+ document.removeEventListener("keyup", onKeyup, true);
+ document.removeEventListener("focus", onFocusCapturePhase, true);
+ document.removeEventListener("blur", onBlurCapturePhase, true);
+ document.removeEventListener("DOMActivate", onDOMActivate, true);
+ isEnabledForUrl = false;
+}
/*
* The backend needs to know which frame has focus.