aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Crosby2009-11-11 00:28:09 -0800
committerPhil Crosby2009-11-11 00:28:09 -0800
commit300fa151c6f59955f9deb7ef2e195f11d79a95ec (patch)
tree8d599ba7ed0b585b7439c1b938c21736cb85f60f
parentd367e58a555606b7ad232fa880484cad8a2f7844 (diff)
parent263ee35bcd468004718ee0457967c57991b0f09b (diff)
downloadvimium-300fa151c6f59955f9deb7ef2e195f11d79a95ec.tar.bz2
Merge branch 'master' of github.com:philc/vimium
Conflicts: vimiumFrontend.js
-rw-r--r--README11
-rw-r--r--background_page.html65
-rw-r--r--manifest.json5
-rw-r--r--toolstrip.html3
-rw-r--r--vimiumFrontend.js20
5 files changed, 79 insertions, 25 deletions
diff --git a/README b/README
index 5667fc4a..ae116dfe 100644
--- a/README
+++ b/README
@@ -1 +1,10 @@
-A work in progress.
+Vimium - The Hacker's Browser
+=============================
+
+Vimium is a Chrome extension that provides keyboard based navigation and control in the spirit of the Vim
+editor.
+
+Installation Instructions:
+ 1. Navigate to chrome://extensions
+ 2. Click on "Load Extension..."
+ 3. Select the vimium directory.
diff --git a/background_page.html b/background_page.html
index a85d8a4f..948aad90 100644
--- a/background_page.html
+++ b/background_page.html
@@ -1,12 +1,13 @@
<html>
<head>
<script type="text/javascript" charset="utf-8">
- var tabQueue = []; // Queue of tabs to restore with scroll info
+ var tabQueue = {}; // windowId -> Array
var keyQueue = ""; // Queue of keys typed
// Port handler mapping
var portHandlers = { "keyDown": handleKeyDown,
- "returnScrollPosition": handleReturnScrollPosition };
+ "returnScrollPosition": handleReturnScrollPosition,
+ "getCurrentTabUrl": getCurrentTabUrl };
// Event handlers
var selectionChangedHandlers = [];
@@ -38,6 +39,17 @@
}
}
+ /*
+ * Used by the content scripts to get their full URL. This is needed for URLs like "view-source:http:// .."
+ * because window.location doesn't know anything about the Chrome-specific "view-source:".
+ */
+ function getCurrentTabUrl(args) {
+ chrome.tabs.getSelected(null, function (tab) {
+ var returnPort = chrome.tabs.connect(tab.id, { name: "returnCurrentTabUrl" });
+ returnPort.postMessage({ url: tab.url });
+ });
+ }
+
chrome.tabs.onSelectionChanged.addListener(function (tabId, selectionInfo) {
if (selectionChangedHandlers.length > 0) { selectionChangedHandlers.pop().call(); }
});
@@ -85,7 +97,15 @@
function removeTab(callback) {
getCurrentTabWithScrollPosition(function(tab, scrollX, scrollY) {
- tabQueue.push({ tabUrl: tab.url, scrollX: scrollX, scrollY: scrollY });
+ var tabQueueEntry = { tabUrl: tab.url,
+ scrollX: scrollX,
+ scrollY: scrollY };
+
+ if (tabQueue[tab.windowId])
+ tabQueue[tab.windowId].push(tabQueueEntry);
+ else
+ tabQueue[tab.windowId] = [tabQueueEntry];
+
chrome.tabs.remove(tab.id);
// We can't just call the callback here because we actually need to wait
// for the selection to change to consider this action done.
@@ -94,21 +114,29 @@
}
function restoreTab(callback) {
- if (tabQueue.length > 0) {
- var tabQueueEntry = tabQueue.pop();
-
- // We have to chain a few callbacks to set the appropriate scroll position. We can't just wait until the
- // tab is created because the content script is not available during the "loading" state. We need to
- // wait until that's over before we can call setScrollPosition.
- chrome.tabs.create({ url: tabQueueEntry.tabUrl }, function(tab) {
- tabLoadedHandlers[tab.id] = function() {
- var scrollPort = chrome.tabs.connect(tab.id, {name: "setScrollPosition"});
- scrollPort.postMessage({ scrollX: tabQueueEntry.scrollX, scrollY: tabQueueEntry.scrollY });
- };
-
- callback();
- });
- }
+ // TODO(ilya): Should this be getLastFocused instead?
+ chrome.windows.getCurrent(function (window) {
+ if (tabQueue[window.id] && tabQueue[window.id].length > 0)
+ {
+ var tabQueueEntry = tabQueue[window.id].pop();
+
+ // Clean out the tabQueue so we don't have unused windows laying about.
+ if (tabQueue[window.id].length == 0)
+ delete tabQueue[window.id];
+
+ // We have to chain a few callbacks to set the appropriate scroll position. We can't just wait until the
+ // tab is created because the content script is not available during the "loading" state. We need to
+ // wait until that's over before we can call setScrollPosition.
+ chrome.tabs.create({ url: tabQueueEntry.tabUrl }, function(tab) {
+ tabLoadedHandlers[tab.id] = function() {
+ var scrollPort = chrome.tabs.connect(tab.id, {name: "setScrollPosition"});
+ scrollPort.postMessage({ scrollX: tabQueueEntry.scrollX, scrollY: tabQueueEntry.scrollY });
+ };
+
+ callback();
+ });
+ }
+ });
}
// End action functions
@@ -122,6 +150,7 @@
keyToCommandRegistry['<c-d>'] = "scrollPageDown";
keyToCommandRegistry['<c-u>'] = "scrollPageUp";
keyToCommandRegistry['r'] = 'reload';
+ keyToCommandRegistry['gf'] = 'toggleViewSource';
keyToCommandRegistry['ba'] = 'goBack';
keyToCommandRegistry['H'] = 'goBack';
diff --git a/manifest.json b/manifest.json
index 3310bf34..d5498c00 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,8 +1,7 @@
{
"name": "Vimium",
"version": "1.0",
- "description": "The hacker's browser.",
- "toolstrips": [ "toolstrip.html" ],
+ "description": "The Hacker's Browser.",
"background_page": "background_page.html",
"permissions": [
"tabs"
@@ -13,4 +12,4 @@
"js": ["vimiumFrontend.js"]
}
]
-} \ No newline at end of file
+}
diff --git a/toolstrip.html b/toolstrip.html
deleted file mode 100644
index c984ed06..00000000
--- a/toolstrip.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<div class="toolstrip-button">
- <span>Hello, World!</span>
-</div>
diff --git a/vimiumFrontend.js b/vimiumFrontend.js
index d6223b32..39ce6036 100644
--- a/vimiumFrontend.js
+++ b/vimiumFrontend.js
@@ -1,4 +1,5 @@
var SCROLL_STEP_SIZE = 60; // Pixels
+var getCurrentUrlHandlers = []; // function (url)
var keyCodes = { ESC: 27 };
var insertMode = false;
@@ -56,10 +57,29 @@ function initializeFrontend() {
port.onMessage.addListener(function (args) {
if (args.scrollX > 0 || args.scrollY > 0) { window.scrollBy(args.scrollX, args.scrollY); }
});
+ } else if (port.name == "returnCurrentTabUrl") {
+ port.onMessage.addListener(function (args) {
+ if (getCurrentUrlHandlers.length > 0) { getCurrentUrlHandlers.pop()(args.url); }
+ });
}
});
};
+function toggleViewSource() {
+ getCurrentUrlHandlers.push(toggleViewSourceCallback);
+
+ var getCurrentUrlPort = chrome.extension.connect({ name: "getCurrentTabUrl" });
+ getCurrentUrlPort.postMessage({});
+}
+
+function toggleViewSourceCallback(url) {
+ if (url.substr(0, 12) == "view-source:")
+ {
+ window.location.href = url.substr(12, url.length - 12);
+ }
+ else { window.location.href = "view-source:" + url; }
+}
+
/**
* Sends everything except i & ESC to the handler in background_page. i & ESC are special because they control
* insert mode which is local state to the page. The key will be are either a single ascii letter or a