aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--background_page.html60
-rw-r--r--vimiumFrontend.js15
2 files changed, 71 insertions, 4 deletions
diff --git a/background_page.html b/background_page.html
index e3193a59..d4b5f4fb 100644
--- a/background_page.html
+++ b/background_page.html
@@ -3,13 +3,32 @@
<script type="text/javascript" charset="utf-8">
var tabQueue = [];
var selectionChangedHandlers = [];
+ var getScrollPositionHandlers = {}; // tabId -> function (tab, scrollTop, scrollLeft)
+ var tabLoadedHandlers = {}; // tabId -> function ()
var keyQueue = "";
chrome.extension.onConnect.addListener(function(port, name) {
if (port.name == "keyDown")
+ {
port.onMessage.addListener(handleKeyDown);
+ }
+ else if (port.name == "returnScrollPosition")
+ {
+ port.onMessage.addListener(handleReturnScrollPosition);
+ }
});
+ function handleReturnScrollPosition(args) {
+ if (getScrollPositionHandlers[args.currentTab.id])
+ {
+ // Delete first to be sure there's no circular events.
+ var toCall = getScrollPositionHandlers[args.currentTab.id];
+ delete getScrollPositionHandlers[args.currentTab.id];
+ toCall(args.currentTab, args.scrollTop, args.scrollLeft);
+ }
+ }
+
+ // TODO(ilya): Move this handler over to a dictionary like below.
chrome.tabs.onSelectionChanged.addListener(function (tabId, selectionInfo) {
if (selectionChangedHandlers.length > 0)
{
@@ -17,6 +36,16 @@
}
});
+ chrome.tabs.onUpdated.addListener(function (tabId, changeInfo) {
+ if (changeInfo.status == "complete" && tabLoadedHandlers[tabId])
+ {
+ // Delete first to be sure there's no circular events.
+ var toCall = tabLoadedHandlers[tabId];
+ delete tabLoadedHandlers[tabId];
+ toCall.call();
+ }
+ });
+
function registerSelectionChangedHandler(handler) {
selectionChangedHandlers.push(handler);
}
@@ -28,24 +57,47 @@
}
}
+ // Returns the currently selected tab along with scroll coordinates. Pass in a callback of the form:
+ // function (tab, scrollTop, scrollLeft) { .. }
+ function getCurrentTabWithScrollPosition(callback) {
+ chrome.tabs.getSelected(null, function (tab) {
+ getScrollPositionHandlers[tab.id] = callback;
+ var scrollPort = chrome.tabs.connect(tab.id, {name: "getScrollPosition"});
+ scrollPort.postMessage({currentTab: tab});
+ });
+ }
+
// Start action functions
function createTab(callback) {
chrome.tabs.create({}, function (tab) { callback(); });
}
function removeTab(callback) {
- chrome.tabs.getSelected(null, function(tab) {
- tabQueue.push(tab.url);
+ getCurrentTabWithScrollPosition(function(tab, scrollTop, scrollLeft) {
+ tabQueue.push({ tabUrl: tab.url, scrollTop: scrollTop,
+ scrollLeft: scrollLeft });
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.
registerSelectionChangedHandler(callback);
- });
+ });
}
function restoreTab(callback) {
if (tabQueue.length > 0) {
- chrome.tabs.create({url: tabQueue.pop()}, function (tab) { callback(); });
+ 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({ scrollTop: tabQueueEntry.scrollTop, scrollLeft: tabQueueEntry.scrollLeft });
+ };
+
+ callback();
+ });
}
}
// End action functions
diff --git a/vimiumFrontend.js b/vimiumFrontend.js
index 368b3b65..cb64361e 100644
--- a/vimiumFrontend.js
+++ b/vimiumFrontend.js
@@ -28,6 +28,21 @@ chrome.extension.onConnect.addListener(function (port, name) {
}
});
}
+ else if (port.name == "getScrollPosition")
+ {
+ port.onMessage.addListener(function (args) {
+ var scrollPort = chrome.extension.connect({name: "returnScrollPosition"});
+ scrollPort.postMessage({ scrollTop: document.body.scrollTop,
+ scrollLeft: document.body.scrollLeft,
+ currentTab: args.currentTab });
+ });
+ }
+ else if (port.name == "setScrollPosition")
+ {
+ port.onMessage.addListener(function (args) {
+ if (args.scrollTop > 0 || args.scrollLeft > 0) { window.scrollBy(args.scrollLeft, args.scrollTop); }
+ });
+ }
});
/**