From b489a9e4034e35c897083f9ce97866fd837680d8 Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 3 Sep 2010 06:31:09 -0500 Subject: Basic Support for Frames Only the focused frame will act on key commands. On some sites (such as Gmail), the main frame is already focused, so commands just work. For other sites, focusing the desired frame may be necessary, which can be done with the Tab key (not optimal) or by clicking with the mouse (even less optimal). An additional command to cycle through frames is desirable, which will likely come in a future commit. --- background_page.html | 9 +++++---- manifest.json | 3 ++- vimiumFrontend.js | 21 ++++++++++----------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/background_page.html b/background_page.html index 349212ef..4133a023 100644 --- a/background_page.html +++ b/background_page.html @@ -480,19 +480,20 @@ return {count: count, command: command}; } - function handleKeyDown(key, port) { + function handleKeyDown(request, port) { + var key = request.keyChar; if (key == "") { console.log("clearing keyQueue"); keyQueue = "" } else { console.log("checking keyQueue: [", keyQueue + key, "]"); - keyQueue = checkKeyQueue(keyQueue + key, port.tab.id); + keyQueue = checkKeyQueue(keyQueue + key, port.tab.id, request.frameId); console.log("new KeyQueue: " + keyQueue); } } - function checkKeyQueue(keysToCheck, tabId) { + function checkKeyQueue(keysToCheck, tabId, frameId) { var refreshedCompletionKeys = false; var splitHash = splitKeyQueue(keysToCheck); command = splitHash.command; @@ -507,7 +508,7 @@ if (!registryEntry.isBackgroundCommand) { var port = chrome.tabs.connect(tabId, { name: "executePageCommand" }); - port.postMessage({ command: registryEntry.command, count: count, + port.postMessage({ command: registryEntry.command, count: count, frameId: frameId, completionKeys: generateCompletionKeys("") }); refreshedCompletionKeys = true; diff --git a/manifest.json b/manifest.json index 97966dd5..703fd069 100644 --- a/manifest.json +++ b/manifest.json @@ -18,7 +18,8 @@ "linkHints.js", "vimiumFrontend.js" ], - "run_at": "document_start" + "run_at": "document_start", + "all_frames": true } ] } diff --git a/vimiumFrontend.js b/vimiumFrontend.js index e288714a..226c7953 100644 --- a/vimiumFrontend.js +++ b/vimiumFrontend.js @@ -75,7 +75,7 @@ function initializePreDomReady() { chrome.extension.onConnect.addListener(function(port, name) { if (port.name == "executePageCommand") { port.onMessage.addListener(function(args) { - if (this[args.command]) { + if (this[args.command] && frameId == args.frameId) { for (var i = 0; i < args.count; i++) { this[args.command].call(); } } @@ -134,6 +134,11 @@ function initializeWhenEnabled() { enterInsertModeIfElementIsFocused(); } +/* + * Give this frame a unique id. + */ +frameId = Math.floor(Math.random()*999999999) + /* * Initialization tasks that must wait for the document to be ready. */ @@ -324,10 +329,10 @@ function onKeydown(event) { event.stopPropagation(); } - keyPort.postMessage(keyChar); + keyPort.postMessage({keyChar:keyChar, frameId:frameId}); } else if (isEscape(event)) { - keyPort.postMessage(""); + keyPort.postMessage({keyChar:"", frameId:frameId}); } } } @@ -690,14 +695,8 @@ function addCssToPage(css) { head.appendChild(style); } -// Prevent our content script from being run on iframes -- only allow it to run on the top level DOM "window". -// TODO(philc): We don't want to process multiple keyhandlers etc. when embedded on a page containing IFrames. -// This should be revisited, because sometimes we *do* want to listen inside of the currently focused iframe. -var isIframe = (window.self != window.parent); -if (!isIframe) { - initializePreDomReady(); - window.addEventListener("DOMContentLoaded", initializeOnDomReady); -} +initializePreDomReady(); +window.addEventListener("DOMContentLoaded", initializeOnDomReady); window.onbeforeunload = function() { chrome.extension.sendRequest({ handler: "updateScrollPosition", -- cgit v1.2.3 From c1d255a662390027a5a61360d173f46b136478b8 Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 3 Sep 2010 19:59:36 -0500 Subject: Fix view source toggle when inside a frame. --- background_page.html | 10 ++++++++++ vimiumFrontend.js | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/background_page.html b/background_page.html index 4133a023..1efd6ae0 100644 --- a/background_page.html +++ b/background_page.html @@ -66,6 +66,7 @@ var sendRequestHandlers = { getCompletionKeys: getCompletionKeys, getLinkHintCss: getLinkHintCss, + openUrlInCurrentTab: openUrlInCurrentTab, openOptionsPageInNewTab: openOptionsPageInNewTab, upgradeNotificationClosed: upgradeNotificationClosed, updateScrollPosition: handleUpdateScrollPosition @@ -219,6 +220,15 @@ return {completionKeys: generateCompletionKeys()}; } + /** + * Opens the url in the current tab. + */ + function openUrlInCurrentTab(request) { + chrome.tabs.getSelected(null, function(tab) { + chrome.tabs.update(tab.id, {url: request.url}); + }); + } + /* * Returns the core CSS used for link hints, along with any user-provided overrides. */ diff --git a/vimiumFrontend.js b/vimiumFrontend.js index 226c7953..331e9afe 100644 --- a/vimiumFrontend.js +++ b/vimiumFrontend.js @@ -238,9 +238,10 @@ function copyCurrentUrl() { function toggleViewSourceCallback(url) { if (url.substr(0, 12) == "view-source:") { - window.location.href = url.substr(12, url.length - 12); + url = url.substr(12, url.length - 12); } - else { window.location.href = "view-source:" + url; } + else { url = "view-source:" + url; } + chrome.extension.sendRequest({handler: "openUrlInCurrentTab", url:url}); } /** -- cgit v1.2.3 From f9f5208f4d88873ee55a4c54062920981ad22eb8 Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 3 Sep 2010 20:15:59 -0500 Subject: Only show the Help Dialog on the focused frame. --- background_page.html | 10 +++++----- vimiumFrontend.js | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/background_page.html b/background_page.html index 1efd6ae0..8abe2f9e 100644 --- a/background_page.html +++ b/background_page.html @@ -153,9 +153,9 @@ returnPort.postMessage({ zoomLevel: zoomLevel }); } - function showHelp() { + function showHelp(callback, frameId) { chrome.tabs.getSelected(null, function(tab) { - chrome.tabs.sendRequest(tab.id, { name: "showHelpDialog", dialogHtml: helpDialogHtml() }); + chrome.tabs.sendRequest(tab.id, { name: "showHelpDialog", dialogHtml: helpDialogHtml(), frameId:frameId }); }); } @@ -271,9 +271,9 @@ if (selectionChangedHandlers.length > 0) { selectionChangedHandlers.pop().call(); } }); - function repeatFunction(func, totalCount, currentCount) { + function repeatFunction(func, totalCount, currentCount, frameId) { if (currentCount < totalCount) - func(function() { repeatFunction(func, totalCount, currentCount + 1); }); + func(function() { repeatFunction(func, totalCount, currentCount + 1, frameId); }, frameId); } // Returns the scroll coordinates of the given tab. Pass in a callback of the form: @@ -523,7 +523,7 @@ refreshedCompletionKeys = true; } else { - repeatFunction(this[registryEntry.command], count, 0); + repeatFunction(this[registryEntry.command], count, 0, frameId); } newKeyQueue = ""; diff --git a/vimiumFrontend.js b/vimiumFrontend.js index 331e9afe..829ded5e 100644 --- a/vimiumFrontend.js +++ b/vimiumFrontend.js @@ -66,7 +66,7 @@ function initializePreDomReady() { if (isShowingHelpDialog) hideHelpDialog(); else - showHelpDialog(request.dialogHtml); + showHelpDialog(request.dialogHtml, request.frameId); else if (request.name == "refreshCompletionKeys") refreshCompletionKeys(request.completionKeys); sendResponse({}); // Free up the resources used by this open connection. @@ -475,8 +475,8 @@ function exitFindMode() { HUD.hide(); } -function showHelpDialog(html) { - if (isShowingHelpDialog || !document.body) +function showHelpDialog(html, fid) { + if (isShowingHelpDialog || !document.body || fid != frameId) return; isShowingHelpDialog = true; var container = document.createElement("div"); -- cgit v1.2.3 From f146e5908bd79dcab4d4afa219af79d4a892b099 Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 3 Sep 2010 22:38:45 -0500 Subject: Command to go to next frame. I remapped toggleViewSource to 'gs' and set 'gf' to nextFrame. Sorry this is such a huge commit. This is really the simplest way I can find to allow the extension to track all available frames as well as the currently-focused frame. If Chrome would allow access to window.frames[i], then this could probably be simpler. --- background_page.html | 31 +++++++++++++++++++++++++++++++ commands.js | 8 ++++++-- vimiumFrontend.js | 28 +++++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/background_page.html b/background_page.html index 8abe2f9e..6014d4c8 100644 --- a/background_page.html +++ b/background_page.html @@ -68,6 +68,8 @@ getLinkHintCss: getLinkHintCss, openUrlInCurrentTab: openUrlInCurrentTab, openOptionsPageInNewTab: openOptionsPageInNewTab, + registerFrame: registerFrame, + focusFrame: focusFrame, upgradeNotificationClosed: upgradeNotificationClosed, updateScrollPosition: handleUpdateScrollPosition }; @@ -593,6 +595,35 @@ }); } + var framesForTab = {}; + + function registerFrame(request, sender) { + if(request.top) + framesForTab[sender.tab.id] = []; + framesForTab[sender.tab.id].push(request.frameId); + } + + var focusedFrame = null; + function focusFrame(request, sender) { + focusedFrame = request.frameId; + } + + function nextFrame(callback, frameId) { + chrome.tabs.getSelected(null, function(tab) { + //chrome.tabs.sendRequest(tab.id, { name: "showHelpDialog", dialogHtml: helpDialogHtml(), frameId:frameId }); + var index; + var frames = framesForTab[tab.id]; + for(index=0; index= frames.length-1) + index = 0; + else + index++; + chrome.tabs.sendRequest(tab.id, { name: "focusFrame", frameId: frames[index] }); + }); + } + function init() { clearKeyMappingsAndSetDefaults(); diff --git a/commands.js b/commands.js index 477e5cd3..e49574e3 100644 --- a/commands.js +++ b/commands.js @@ -92,7 +92,7 @@ function clearKeyMappingsAndSetDefaults() { mapKeyToCommand('', 'scrollFullPageDown'); mapKeyToCommand('', 'scrollFullPageUp'); mapKeyToCommand('r', 'reload'); - mapKeyToCommand('gf', 'toggleViewSource'); + mapKeyToCommand('gs', 'toggleViewSource'); mapKeyToCommand('i', 'enterInsertMode'); @@ -120,6 +120,8 @@ function clearKeyMappingsAndSetDefaults() { mapKeyToCommand('t', 'createTab'); mapKeyToCommand('d', 'removeTab'); mapKeyToCommand('u', 'restoreTab'); + + mapKeyToCommand('gf', 'nextFrame'); } // Navigating the current page: @@ -166,6 +168,8 @@ addCommand('createTab', 'Create new tab', true); addCommand('removeTab', 'Close current tab', true); addCommand('restoreTab', "Restore closed tab", true); +addCommand('nextFrame', "Cycle forward to the next frame on the page", true); + // An ordered listing of all available commands, grouped by type. This is the order they will // be shown in the help page. @@ -175,7 +179,7 @@ var commandGroups = { "scrollToTop", "scrollToBottom", "scrollToLeft", "scrollToRight", "scrollPageDown", "scrollPageUp", "scrollFullPageDown", "reload", "toggleViewSource", "zoomIn", "zoomOut", "copyCurrentUrl", "goUp", "enterInsertMode", "activateLinkHintsMode", "activateLinkHintsModeToOpenInNewTab", - "enterFindMode", "performFind", "performBackwardsFind"], + "enterFindMode", "performFind", "performBackwardsFind", "nextFrame"], historyNavigation: ["goBack", "goForward"], tabManipulation: diff --git a/vimiumFrontend.js b/vimiumFrontend.js index 829ded5e..685e121f 100644 --- a/vimiumFrontend.js +++ b/vimiumFrontend.js @@ -67,6 +67,9 @@ function initializePreDomReady() { hideHelpDialog(); else showHelpDialog(request.dialogHtml, request.frameId); + else if (request.name == "focusFrame") + if(frameId == request.frameId) + focusThisFrame(); else if (request.name == "refreshCompletionKeys") refreshCompletionKeys(request.completionKeys); sendResponse({}); // Free up the resources used by this open connection. @@ -135,9 +138,32 @@ function initializeWhenEnabled() { } /* - * Give this frame a unique id. + * Give this frame a unique id and register with the backend. */ frameId = Math.floor(Math.random()*999999999) +if(window.top == window.self) + chrome.extension.sendRequest({handler: "registerFrame", frameId: frameId, top: true}); +else + chrome.extension.sendRequest({handler: "registerFrame", frameId: frameId}); + +/* + * The backend needs to know which frame has focus. + */ +window.addEventListener("focus", function(e){ + chrome.extension.sendRequest({handler: "focusFrame", frameId: frameId}); +}); + +/* + * Called from the backend in order to change frame focus. + */ +function focusThisFrame() { + window.focus(); + if(document.body) { + var borderWas = document.body.style.border; + document.body.style.border = '1px solid red'; + setTimeout(function(){document.body.style.border = borderWas}, 200); + } +} /* * Initialization tasks that must wait for the document to be ready. -- cgit v1.2.3 From f377565c3b5c3731623c24da96c8623860cec3f2 Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 3 Sep 2010 23:25:40 -0500 Subject: Update README with new/changed key mappings. --- README.markdown | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 7e525141..f05aa3a8 100644 --- a/README.markdown +++ b/README.markdown @@ -37,7 +37,7 @@ Navigating the current page: f activate link hints mode to open in current tab F activate link hints mode to open in new tab r reload - gf view source + gs view source zi zoom in zo zoom out / enter find mode -- type your search query and hit enter to search or esc to cancel @@ -46,6 +46,7 @@ Navigating the current page: i enter insert mode -- all commands will be ignored until you hit esc to exit yy copy the current url to the clipboard gu go up one level in the URL hierarchy + gf cycle forward to the next frame Navigating your history: H go back in history -- cgit v1.2.3 From 4473dafcb82103572810cb501ca8bce56ca93c5e Mon Sep 17 00:00:00 2001 From: abe Date: Wed, 22 Sep 2010 01:38:54 +0200 Subject: Added activeteLinkHintsModeWithQueue and resetLinkHintsMode to linkHints.js and added 'q cmd' and 'q help cmd' to commands.js --- commands.js | 4 +++- linkHints.js | 37 +++++++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/commands.js b/commands.js index a9fa0aba..01f7735c 100644 --- a/commands.js +++ b/commands.js @@ -112,6 +112,7 @@ function clearKeyMappingsAndSetDefaults() { mapKeyToCommand('f', 'activateLinkHintsMode'); mapKeyToCommand('F', 'activateLinkHintsModeToOpenInNewTab'); + mapKeyToCommand('q', 'activeteLinkHintsModeWithQueue'); mapKeyToCommand('/', 'enterFindMode'); mapKeyToCommand('n', 'performFind'); @@ -156,6 +157,7 @@ addCommand('focusInput', 'Focus the first (or n-th) text box on the pag addCommand('activateLinkHintsMode', 'Enter link hints mode to open links in current tab'); addCommand('activateLinkHintsModeToOpenInNewTab', 'Enter link hints mode to open links in new tab'); +addCommand('activeteLinkHintsModeWithQueue', 'Enter link hints mode to open multiple links in a new tab'); addCommand('enterFindMode', 'Enter find mode'); addCommand('performFind', 'Cycle forward to the next find match'); @@ -185,7 +187,7 @@ var commandGroups = { "scrollPageUp", "scrollFullPageDown", "reload", "toggleViewSource", "zoomIn", "zoomOut", "copyCurrentUrl", "goUp", "enterInsertMode", "focusInput", - "activateLinkHintsMode", "activateLinkHintsModeToOpenInNewTab", + "activateLinkHintsMode", "activateLinkHintsModeToOpenInNewTab", "activeteLinkHintsModeWithQueue", "enterFindMode", "performFind", "performBackwardsFind"], historyNavigation: ["goBack", "goForward"], diff --git a/linkHints.js b/linkHints.js index fcaa832b..5a7fb118 100644 --- a/linkHints.js +++ b/linkHints.js @@ -13,6 +13,7 @@ var hintMarkerContainingDiv = null; var hintKeystrokeQueue = []; var linkHintsModeActivated = false; var shouldOpenLinkHintInNewTab = false; +var shouldOpenLinkHintWithQueue = false; // Whether link hint's "open in current/new tab" setting is currently toggled var openLinkModeToggle = false; // Whether we have added to the page the CSS needed to display link hints. @@ -32,25 +33,32 @@ var clickableElementsXPath = (function() { })(); // We need this as a top-level function because our command system doesn't yet support arguments. -function activateLinkHintsModeToOpenInNewTab() { activateLinkHintsMode(true); } +function activateLinkHintsModeToOpenInNewTab() { activateLinkHintsMode(true, false); } -function activateLinkHintsMode(openInNewTab) { +function activeteLinkHintsModeWithQueue() { activateLinkHintsMode(true, true); } + +function activateLinkHintsMode(openInNewTab, withQueue) { if (!linkHintsCssAdded) addCssToPage(linkHintCss); // linkHintCss is declared by vimiumFrontend.js linkHintCssAdded = true; linkHintsModeActivated = true; - setOpenLinkMode(openInNewTab); + setOpenLinkMode(openInNewTab, withQueue); buildLinkHints(); document.addEventListener("keydown", onKeyDownInLinkHintsMode, true); document.addEventListener("keyup", onKeyUpInLinkHintsMode, true); } -function setOpenLinkMode(openInNewTab) { +function setOpenLinkMode(openInNewTab, withQueue) { shouldOpenLinkHintInNewTab = openInNewTab; - if (shouldOpenLinkHintInNewTab) - HUD.show("Open link in new tab"); - else - HUD.show("Open link in current tab"); + shouldOpenLinkHintWithQueue = withQueue + if (shouldOpenLinkHintWithQueue) { + HUD.show("Open multiple links in a new tab"); + } else { + if (shouldOpenLinkHintInNewTab) + HUD.show("Open link in new tab"); + else + HUD.show("Open link in current tab"); + } } /* @@ -206,9 +214,14 @@ function updateLinkHints() { setTimeout(function() { simulateClick(matchedLink); }, 400); else simulateClick(matchedLink); - matchedLink.focus(); + if (!shouldOpenLinkHintWithQueue) { + matchedLink.focus(); + deactivateLinkHintsMode(); + } else { + console.log("Reseting Hint Link Mode"); + resetLinkHintsMode(); + } } - deactivateLinkHintsMode(); } } @@ -289,6 +302,10 @@ function deactivateLinkHintsMode() { HUD.hide(); } +function resetLinkHintsMode() { + hintKeystrokeQueue = []; +} + /* * Creates a link marker for the given link. */ -- cgit v1.2.3 From 7c4f41a35b6af3efbc3adfa5a1e6bbab667fc096 Mon Sep 17 00:00:00 2001 From: abe Date: Thu, 23 Sep 2010 00:25:11 +0200 Subject: added resetLinkHintsMode --- linkHints.js | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/linkHints.js b/linkHints.js index 5a7fb118..b30c74e0 100644 --- a/linkHints.js +++ b/linkHints.js @@ -151,9 +151,10 @@ function isVisible(element, clientRect) { } function onKeyDownInLinkHintsMode(event) { + console.log("Key Down"); if (event.keyCode == keyCodes.shiftKey && !openLinkModeToggle) { // Toggle whether to open link in a new or current tab. - setOpenLinkMode(!shouldOpenLinkHintInNewTab); + setOpenLinkMode(!shouldOpenLinkHintInNewTab, shouldOpenLinkHintWithQueue); openLinkModeToggle = true; } @@ -185,7 +186,7 @@ function onKeyDownInLinkHintsMode(event) { function onKeyUpInLinkHintsMode(event) { if (event.keyCode == keyCodes.shiftKey && openLinkModeToggle) { // Revert toggle on whether to open link in new or current tab. - setOpenLinkMode(!shouldOpenLinkHintInNewTab); + setOpenLinkMode(!shouldOpenLinkHintInNewTab, shouldOpenLinkHintWithQueue); openLinkModeToggle = false; } event.stopPropagation(); @@ -210,17 +211,25 @@ function updateLinkHints() { } else { // When we're opening the link in the current tab, don't navigate to the selected link immediately; // we want to give the user some feedback depicting which link they've selected by focusing it. - if (!shouldOpenLinkHintInNewTab) - setTimeout(function() { simulateClick(matchedLink); }, 400); - else + if (shouldOpenLinkHintWithQueue) { + simulateClick(matchedLink); + resetLinkHintsMode(); + } else if (shouldOpenLinkHintInNewTab) { simulateClick(matchedLink); - if (!shouldOpenLinkHintWithQueue) { + matchedLink.focus(); + deactivateLinkHintsMode(); + } else { + setTimeout(function() { simulateClick(matchedLink); }, 400); + matchedLink.focus(); + deactivateLinkHintsMode(); + } + /*if (!shouldOpenLinkHintWithQueue) { matchedLink.focus(); deactivateLinkHintsMode(); } else { console.log("Reseting Hint Link Mode"); resetLinkHintsMode(); - } + }*/ } } } @@ -303,7 +312,8 @@ function deactivateLinkHintsMode() { } function resetLinkHintsMode() { - hintKeystrokeQueue = []; + deactivateLinkHintsMode(); + activeteLinkHintsModeWithQueue(); } /* -- cgit v1.2.3 From fd909e1bdbe10d598522498c32a6c4b8db231644 Mon Sep 17 00:00:00 2001 From: abe Date: Thu, 23 Sep 2010 00:26:49 +0200 Subject: Clean up code --- linkHints.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/linkHints.js b/linkHints.js index b30c74e0..c470dfe0 100644 --- a/linkHints.js +++ b/linkHints.js @@ -223,13 +223,6 @@ function updateLinkHints() { matchedLink.focus(); deactivateLinkHintsMode(); } - /*if (!shouldOpenLinkHintWithQueue) { - matchedLink.focus(); - deactivateLinkHintsMode(); - } else { - console.log("Reseting Hint Link Mode"); - resetLinkHintsMode(); - }*/ } } } -- cgit v1.2.3 From 547ca0464279f2fcc1b1da8379b32dc1caeb882f Mon Sep 17 00:00:00 2001 From: abe Date: Thu, 23 Sep 2010 00:51:08 +0200 Subject: Added ab3 to Credits ;) --- CREDITS | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS b/CREDITS index 8c986adc..b9af3760 100644 --- a/CREDITS +++ b/CREDITS @@ -15,5 +15,6 @@ Contributors: markstos rodimius tsigo + Werner Laurensse (github: ab3) Feel free to add real names in addition to GitHub usernames. -- cgit v1.2.3 From 7329e2dbd195c17c53acb647247194eb7536ddec Mon Sep 17 00:00:00 2001 From: Werner Laurensse Date: Thu, 23 Sep 2010 00:55:13 +0200 Subject: Updated README --- README.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/README.markdown b/README.markdown index 2e144110..3908c809 100644 --- a/README.markdown +++ b/README.markdown @@ -36,6 +36,7 @@ Navigating the current page: scroll up a full page f activate link hints mode to open in current tab F activate link hints mode to open in new tab + q activate link hints mode to open multiple links in a new tab r reload gf view source zi zoom in -- cgit v1.2.3 From 64b550a4a7fa4af1d9c0996d6f66715dc479ccb5 Mon Sep 17 00:00:00 2001 From: Ilya Sukhar Date: Thu, 23 Sep 2010 23:27:56 -0700 Subject: A bunch of changes having to do with the frame support patch: - Focus the largest frame by default - Change the border styling to match link hints - Clean up framesForTab when tab is closed - Don't cycle through parent. This may break some sites. Needs more testing. - Fixed some naming and style - Added seven1m to CREDITS - Updated README--- CREDITS | 1 + README.markdown | 1 + background_page.html | 54 ++++++++++++++++++++++++++++++++++++++-------------- manifest.json | 4 +++- vimiumFrontend.js | 36 ++++++++++++++++++++++------------- 5 files changed, 68 insertions(+), 28 deletions(-) diff --git a/CREDITS b/CREDITS index 8c986adc..0f1c5797 100644 --- a/CREDITS +++ b/CREDITS @@ -14,6 +14,7 @@ Contributors: lack markstos rodimius + Tim Morgan (github: seven1m) tsigo Feel free to add real names in addition to GitHub usernames. diff --git a/README.markdown b/README.markdown index f05aa3a8..dff5f8da 100644 --- a/README.markdown +++ b/README.markdown @@ -84,6 +84,7 @@ Release Notes - In link hints mode, holding down the shift key will now toggle between opening in the current tab and opening in a new tab. - Two new commands to scroll to the left and right edges of the page bound to zH and zL respectively. +- Frame support. - Bug fixes. 1.19 (06/29/2010) diff --git a/background_page.html b/background_page.html index 6014d4c8..fb1eb48b 100644 --- a/background_page.html +++ b/background_page.html @@ -14,6 +14,8 @@ var keyQueue = ""; // Queue of keys typed var validFirstKeys = {}; var singleKeyCommands = []; + var focusedFrame = null; + var framesForTab = {}; // Keys are either literal characters, or "named" - for example (alt+b), (the left arrow) or // This regular expression captures two groups, the first is a named key, the second is the remainder of the string. @@ -69,7 +71,7 @@ openUrlInCurrentTab: openUrlInCurrentTab, openOptionsPageInNewTab: openOptionsPageInNewTab, registerFrame: registerFrame, - focusFrame: focusFrame, + frameFocused: handleFrameFocused, upgradeNotificationClosed: upgradeNotificationClosed, updateScrollPosition: handleUpdateScrollPosition }; @@ -93,6 +95,7 @@ } // domReady is the appropriate time to show the "vimium has been upgraded" message. + // TODO: This might be broken on pages with frames. if (shouldShowUpgradeMessage()) chrome.tabs.sendRequest(senderTabId, { name: "showUpgradeNotification", version: currentVersion }); } @@ -374,6 +377,7 @@ tabQueue[openTabInfo.windowId] = [openTabInfo]; delete openTabs[tabId]; + delete framesForTab[tabId]; }); chrome.windows.onRemoved.addListener(function(windowId) { @@ -595,32 +599,54 @@ }); } - var framesForTab = {}; - function registerFrame(request, sender) { - if(request.top) - framesForTab[sender.tab.id] = []; - framesForTab[sender.tab.id].push(request.frameId); + if (request.top) + framesForTab[sender.tab.id] = { total: request.total, frames: [] }; + else { + framesForTab[sender.tab.id].frames.push({ id: request.frameId, area: request.area }); + + // We've seen all the frames. Time to focus the largest one. + if (framesForTab[sender.tab.id].frames.length == framesForTab[sender.tab.id].total) + focusLargestFrame(sender.tab.id); + } } - var focusedFrame = null; - function focusFrame(request, sender) { + function focusLargestFrame(tabId) { + var mainFrameId = null; + var mainFrameArea = 0; + + for (var i = 0; i < framesForTab[tabId].frames.length; i++) { + var currentFrame = framesForTab[tabId].frames[i]; + + if (currentFrame.area > mainFrameArea) { + mainFrameId = currentFrame.id; + mainFrameArea = currentFrame.area; + } + } + + chrome.tabs.sendRequest(tabId, { name: "focusFrame", frameId: mainFrameId, highlight: false }); + } + + function handleFrameFocused(request, sender) { focusedFrame = request.frameId; } function nextFrame(callback, frameId) { chrome.tabs.getSelected(null, function(tab) { - //chrome.tabs.sendRequest(tab.id, { name: "showHelpDialog", dialogHtml: helpDialogHtml(), frameId:frameId }); var index; - var frames = framesForTab[tab.id]; - for(index=0; index= frames.length-1) + + if (index >= frames.length-1) index = 0; else index++; - chrome.tabs.sendRequest(tab.id, { name: "focusFrame", frameId: frames[index] }); + + chrome.tabs.sendRequest(tab.id, { name: "focusFrame", frameId: frames[index].id, highlight: true }); }); } diff --git a/manifest.json b/manifest.json index 703fd069..d49adfa2 100644 --- a/manifest.json +++ b/manifest.json @@ -8,7 +8,9 @@ "background_page": "background_page.html", "options_page": "options.html", "permissions": [ - "tabs" + "tabs", + "http://*/*", + "https://*/*" ], "content_scripts": [ { diff --git a/vimiumFrontend.js b/vimiumFrontend.js index 685e121f..ac7d366a 100644 --- a/vimiumFrontend.js +++ b/vimiumFrontend.js @@ -26,6 +26,11 @@ var linkHintCss; // TODO(philc): This should be pulled from the extension's storage when the page loads. var currentZoomLevel = 100; +/* + * Give this frame a unique id. + */ +frameId = Math.floor(Math.random()*999999999) + var hasModifiersRegex = /^<([amc]-)+.>/; function getSetting(key) { @@ -69,7 +74,7 @@ function initializePreDomReady() { showHelpDialog(request.dialogHtml, request.frameId); else if (request.name == "focusFrame") if(frameId == request.frameId) - focusThisFrame(); + focusThisFrame(request.highlight); else if (request.name == "refreshCompletionKeys") refreshCompletionKeys(request.completionKeys); sendResponse({}); // Free up the resources used by this open connection. @@ -137,30 +142,22 @@ function initializeWhenEnabled() { enterInsertModeIfElementIsFocused(); } -/* - * Give this frame a unique id and register with the backend. - */ -frameId = Math.floor(Math.random()*999999999) -if(window.top == window.self) - chrome.extension.sendRequest({handler: "registerFrame", frameId: frameId, top: true}); -else - chrome.extension.sendRequest({handler: "registerFrame", frameId: frameId}); /* * The backend needs to know which frame has focus. */ window.addEventListener("focus", function(e){ - chrome.extension.sendRequest({handler: "focusFrame", frameId: frameId}); + chrome.extension.sendRequest({handler: "frameFocused", frameId: frameId}); }); /* * Called from the backend in order to change frame focus. */ -function focusThisFrame() { +function focusThisFrame(shouldHighlight) { window.focus(); - if(document.body) { + if (document.body && shouldHighlight) { var borderWas = document.body.style.border; - document.body.style.border = '1px solid red'; + document.body.style.border = '5px solid yellow'; setTimeout(function(){document.body.style.border = borderWas}, 200); } } @@ -169,6 +166,11 @@ function focusThisFrame() { * Initialization tasks that must wait for the document to be ready. */ function initializeOnDomReady() { + if (window.top == window.self) + chrome.extension.sendRequest({ handler: "registerFrame", frameId: frameId, top: true, total: frames.length }); + else + registerFrameIfSizeAvailable(); + if (isEnabledForUrl) enterInsertModeIfElementIsFocused(); @@ -176,6 +178,14 @@ function initializeOnDomReady() { chrome.extension.connect({ name: "domReady" }); }; +// This is a little hacky but sometimes the size wasn't available on domReady? +function registerFrameIfSizeAvailable () { + if (innerWidth != undefined && innerWidth != 0 && innerHeight != undefined && innerHeight != 0) + chrome.extension.sendRequest({ handler: "registerFrame", frameId: frameId, area: innerWidth * innerHeight }); + else + setTimeout(registerFrameIfSizeAvailable, 100); +} + /* * Checks the currently focused element of the document and will enter insert mode if that element is focusable. */ -- cgit v1.2.3 From 11b879f6d49f6f5c08cd3276ab871d1ccffb179d Mon Sep 17 00:00:00 2001 From: Ilya Sukhar Date: Fri, 24 Sep 2010 00:37:21 -0700 Subject: Fix some frame logic and disable focusing the largest one for now because it's buggy with iframes. --- background_page.html | 19 ++++++++++++------- vimiumFrontend.js | 11 ++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/background_page.html b/background_page.html index b862a881..48084f77 100644 --- a/background_page.html +++ b/background_page.html @@ -604,15 +604,20 @@ } function registerFrame(request, sender) { - if (request.top) - framesForTab[sender.tab.id] = { total: request.total, frames: [] }; - else { - framesForTab[sender.tab.id].frames.push({ id: request.frameId, area: request.area }); + if (!framesForTab[sender.tab.id]) + framesForTab[sender.tab.id] = { frames: [] }; - // We've seen all the frames. Time to focus the largest one. - if (framesForTab[sender.tab.id].frames.length == framesForTab[sender.tab.id].total) - focusLargestFrame(sender.tab.id); + if (request.top) { + focusedFrame = request.frameId; + framesForTab[sender.tab.id].total = request.total; } + + framesForTab[sender.tab.id].frames.push({ id: request.frameId, area: request.area }); + + // We've seen all the frames. Time to focus the largest one. + // NOTE: Disabled because it's buggy with iframes. + // if (framesForTab[sender.tab.id].frames.length >= framesForTab[sender.tab.id].total) + // focusLargestFrame(sender.tab.id); } function focusLargestFrame(tabId) { diff --git a/vimiumFrontend.js b/vimiumFrontend.js index 3b73144a..d7c429cb 100644 --- a/vimiumFrontend.js +++ b/vimiumFrontend.js @@ -170,10 +170,7 @@ function focusThisFrame(shouldHighlight) { * Initialization tasks that must wait for the document to be ready. */ function initializeOnDomReady() { - if (window.top == window.self) - chrome.extension.sendRequest({ handler: "registerFrame", frameId: frameId, top: true, total: frames.length }); - else - registerFrameIfSizeAvailable(); + registerFrameIfSizeAvailable(window.top == window.self); if (isEnabledForUrl) enterInsertModeIfElementIsFocused(); @@ -183,11 +180,11 @@ function initializeOnDomReady() { }; // This is a little hacky but sometimes the size wasn't available on domReady? -function registerFrameIfSizeAvailable () { +function registerFrameIfSizeAvailable (top) { if (innerWidth != undefined && innerWidth != 0 && innerHeight != undefined && innerHeight != 0) - chrome.extension.sendRequest({ handler: "registerFrame", frameId: frameId, area: innerWidth * innerHeight }); + chrome.extension.sendRequest({ handler: "registerFrame", frameId: frameId, area: innerWidth * innerHeight, top: top, total: frames.length + 1 }); else - setTimeout(registerFrameIfSizeAvailable, 100); + setTimeout(function () { registerFrameIfSizeAvailable(top); }, 100); } /* -- cgit v1.2.3 From 6e959935f94355bfe55dee808abd7ecc9fd42c66 Mon Sep 17 00:00:00 2001 From: Ilya Sukhar Date: Fri, 24 Sep 2010 00:53:04 -0700 Subject: Code cleanup & README changes for the multiple link hints patch. --- README.markdown | 3 ++- commands.js | 10 +++++----- linkHints.js | 8 +++----- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/README.markdown b/README.markdown index 668f0c2b..36e267bf 100644 --- a/README.markdown +++ b/README.markdown @@ -36,7 +36,7 @@ Navigating the current page: scroll up a full page f activate link hints mode to open in current tab F activate link hints mode to open in new tab - q activate link hints mode to open multiple links in a new tab + activate link hints mode to open multiple links in a new tab r reload gs view source zi zoom in @@ -86,6 +86,7 @@ Release Notes - In link hints mode, holding down the shift key will now toggle between opening in the current tab and opening in a new tab. - Two new commands (`zH` and `zL`) to scroll to the left and right edges of the page. - A new command (`gi`) to focus the first (or n-th) text input box on the page. +- A new command (``) to open up multiple links at a time in new tabs. - Frame support. - Bug fixes. diff --git a/commands.js b/commands.js index a952ae91..46a52632 100644 --- a/commands.js +++ b/commands.js @@ -110,9 +110,9 @@ function clearKeyMappingsAndSetDefaults() { mapKeyToCommand('gi', 'focusInput'); - mapKeyToCommand('f', 'activateLinkHintsMode'); - mapKeyToCommand('F', 'activateLinkHintsModeToOpenInNewTab'); - mapKeyToCommand('q', 'activeteLinkHintsModeWithQueue'); + mapKeyToCommand('f', 'activateLinkHintsMode'); + mapKeyToCommand('F', 'activateLinkHintsModeToOpenInNewTab'); + mapKeyToCommand('', 'activateLinkHintsModeWithQueue'); mapKeyToCommand('/', 'enterFindMode'); mapKeyToCommand('n', 'performFind'); @@ -159,7 +159,7 @@ addCommand('focusInput', 'Focus the first (or n-th) text box on the pag addCommand('activateLinkHintsMode', 'Enter link hints mode to open links in current tab'); addCommand('activateLinkHintsModeToOpenInNewTab', 'Enter link hints mode to open links in new tab'); -addCommand('activeteLinkHintsModeWithQueue', 'Enter link hints mode to open multiple links in a new tab'); +addCommand('activateLinkHintsModeWithQueue', 'Enter link hints mode to open multiple links in a new tab'); addCommand('enterFindMode', 'Enter find mode'); addCommand('performFind', 'Cycle forward to the next find match'); @@ -191,7 +191,7 @@ var commandGroups = { "scrollPageUp", "scrollFullPageDown", "reload", "toggleViewSource", "zoomIn", "zoomOut", "copyCurrentUrl", "goUp", "enterInsertMode", "focusInput", - "activateLinkHintsMode", "activateLinkHintsModeToOpenInNewTab", "activeteLinkHintsModeWithQueue", + "activateLinkHintsMode", "activateLinkHintsModeToOpenInNewTab", "activateLinkHintsModeWithQueue", "enterFindMode", "performFind", "performBackwardsFind", "nextFrame"], historyNavigation: ["goBack", "goForward"], diff --git a/linkHints.js b/linkHints.js index c470dfe0..c62468fb 100644 --- a/linkHints.js +++ b/linkHints.js @@ -35,7 +35,7 @@ var clickableElementsXPath = (function() { // We need this as a top-level function because our command system doesn't yet support arguments. function activateLinkHintsModeToOpenInNewTab() { activateLinkHintsMode(true, false); } -function activeteLinkHintsModeWithQueue() { activateLinkHintsMode(true, true); } +function activateMultipleLinkHintsMode() { activateLinkHintsMode(true, true); } function activateLinkHintsMode(openInNewTab, withQueue) { if (!linkHintsCssAdded) @@ -48,9 +48,7 @@ function activateLinkHintsMode(openInNewTab, withQueue) { document.addEventListener("keyup", onKeyUpInLinkHintsMode, true); } -function setOpenLinkMode(openInNewTab, withQueue) { - shouldOpenLinkHintInNewTab = openInNewTab; - shouldOpenLinkHintWithQueue = withQueue +function setOpenLinkMode(shouldOpenLinkHintInNewTab, shouldOpenLinkHintWithQueue) { if (shouldOpenLinkHintWithQueue) { HUD.show("Open multiple links in a new tab"); } else { @@ -306,7 +304,7 @@ function deactivateLinkHintsMode() { function resetLinkHintsMode() { deactivateLinkHintsMode(); - activeteLinkHintsModeWithQueue(); + activateMultipleLinkHintsMode(); } /* -- cgit v1.2.3 From f18052e836e9387968969e2cd6b71e0a8d5bd943 Mon Sep 17 00:00:00 2001 From: Ilya Sukhar Date: Fri, 24 Sep 2010 01:23:11 -0700 Subject: Oops, fixed a regression. --- linkHints.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/linkHints.js b/linkHints.js index c62468fb..e7f069cb 100644 --- a/linkHints.js +++ b/linkHints.js @@ -48,7 +48,9 @@ function activateLinkHintsMode(openInNewTab, withQueue) { document.addEventListener("keyup", onKeyUpInLinkHintsMode, true); } -function setOpenLinkMode(shouldOpenLinkHintInNewTab, shouldOpenLinkHintWithQueue) { +function setOpenLinkMode(openInNewTab, withQueue) { + shouldOpenLinkHintInNewTab = openInNewTab; + shouldOpenLinkHintWithQueue = withQueue; if (shouldOpenLinkHintWithQueue) { HUD.show("Open multiple links in a new tab"); } else { @@ -153,7 +155,7 @@ function onKeyDownInLinkHintsMode(event) { if (event.keyCode == keyCodes.shiftKey && !openLinkModeToggle) { // Toggle whether to open link in a new or current tab. setOpenLinkMode(!shouldOpenLinkHintInNewTab, shouldOpenLinkHintWithQueue); - openLinkModeToggle = true; + openLinkModeToggle = true; } var keyChar = getKeyChar(event); @@ -185,7 +187,7 @@ function onKeyUpInLinkHintsMode(event) { if (event.keyCode == keyCodes.shiftKey && openLinkModeToggle) { // Revert toggle on whether to open link in new or current tab. setOpenLinkMode(!shouldOpenLinkHintInNewTab, shouldOpenLinkHintWithQueue); - openLinkModeToggle = false; + openLinkModeToggle = false; } event.stopPropagation(); event.preventDefault(); -- cgit v1.2.3 From 9d9bd40ae050ae4b5b9665fcdde4c60e3486cc87 Mon Sep 17 00:00:00 2001 From: Ilya Sukhar Date: Fri, 24 Sep 2010 01:33:15 -0700 Subject: Revert a rename - not sure why I committed that. --- linkHints.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linkHints.js b/linkHints.js index e7f069cb..7593a630 100644 --- a/linkHints.js +++ b/linkHints.js @@ -35,7 +35,7 @@ var clickableElementsXPath = (function() { // We need this as a top-level function because our command system doesn't yet support arguments. function activateLinkHintsModeToOpenInNewTab() { activateLinkHintsMode(true, false); } -function activateMultipleLinkHintsMode() { activateLinkHintsMode(true, true); } +function activateLinkHintsModeWithQueue() { activateLinkHintsMode(true, true); } function activateLinkHintsMode(openInNewTab, withQueue) { if (!linkHintsCssAdded) @@ -306,7 +306,7 @@ function deactivateLinkHintsMode() { function resetLinkHintsMode() { deactivateLinkHintsMode(); - activateMultipleLinkHintsMode(); + activateLinkHintsModeWithQueue(); } /* -- cgit v1.2.3