diff options
| -rw-r--r-- | background_page.html | 60 | ||||
| -rw-r--r-- | vimiumFrontend.js | 15 |
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); } + }); + } }); /** |
