diff options
| -rw-r--r-- | background_page.html | 49 | ||||
| -rw-r--r-- | commands.js | 22 | ||||
| -rw-r--r-- | helpDialog.html | 105 | ||||
| -rw-r--r-- | vimiumFrontend.js | 25 |
4 files changed, 198 insertions, 3 deletions
diff --git a/background_page.html b/background_page.html index 520ae49c..ab76e59e 100644 --- a/background_page.html +++ b/background_page.html @@ -142,6 +142,54 @@ returnPort.postMessage({ zoomLevel: zoomLevel }); } + function showHelp() { + chrome.tabs.getSelected(null, function(tab) { + chrome.tabs.sendRequest(tab.id, { name: "showHelpDialog", dialogHtml: helpDialogHtml() }); + }); + } + + /* + * Retrieves the help dialog HTML template from a file, and populates it with the latest keybindings. + */ + function helpDialogHtml() { + var commandsToKey = {}; + for (var key in keyToCommandRegistry) { + var command = keyToCommandRegistry[key].command; + commandsToKey[command] = (commandsToKey[command] || []).concat(key); + } + var dialogHtml = fetchFileContents("helpDialog.html"); + for (var group in commandGroups) + dialogHtml = dialogHtml.replace("{{" + group + "}}", + helpDialogHtmlForCommandGroup(group, commandsToKey, availableCommands)); + return dialogHtml; + } + + /* + * Generates HTML for a given set of commands. commandGroups are defined in commands.js + */ + function helpDialogHtmlForCommandGroup(group, commandsToKey, availableCommands) { + var html = []; + for (var i = 0; i < commandGroups[group].length; i++) { + var command = commandGroups[group][i]; + if (commandsToKey[command]) + html.push("<tr><td>", escapeHtml(commandsToKey[command].join(", ")), + "</td><td>:</td><td>",availableCommands[command].description, "</td></tr>"); + } + return html.join("\n"); + } + + function escapeHtml(string) { return string.replace(/</g, "<").replace(/>/g, ">"); } + + /* + * Fetches the contents of a file bundled with this extension. + */ + function fetchFileContents(extensionFileName) { + var req = new XMLHttpRequest(); + req.open("GET", chrome.extension.getURL(extensionFileName), false); // false => synchronous + req.send(); + return req.responseText; + } + /** * Returns the keys that can complete a valid command given the current key queue. */ @@ -446,7 +494,6 @@ if (shouldShowUpgradeMessage()) sendRequestToAllTabs({ name: "showUpgradeNotification", version: currentVersion }); } - init(); </script> </head> diff --git a/commands.js b/commands.js index 69501b5d..7cab1a56 100644 --- a/commands.js +++ b/commands.js @@ -52,6 +52,7 @@ function parseCustomKeyMappings(customKeyMappings) { } // Navigating the current page: +addCommand('showHelp', 'Show help.', true); addCommand('scrollDown', 'Scroll down.'); addCommand('scrollUp', 'Scroll up.'); addCommand('scrollLeft', 'Scroll left.'); @@ -87,8 +88,25 @@ addCommand('nextTab', 'Go one tab right.', true); addCommand('previousTab', 'Go one tab left.', true); addCommand('createTab', 'Create new tab.', true); addCommand('removeTab', 'Close current tab.', true); -addCommand('restoreTab', "Restore closed tab. (i.e. unwind the 'd' command).", true); - +addCommand('restoreTab', "Restore closed tab.", true); + + +// An ordered listing of all available commands, grouped by type. This is the order they will +// be shown in the help page. +var commandGroups = { + pageNavigation: + ["scrollDown", "scrollUp", "scrollLeft", "scrollRight", + "scrollToTop", "scrollToBottom", "scrollPageDown", "scrollPageUp", "scrollFullPageDown", + "reload", "toggleViewSource", "zoomIn", "zoomOut", "copyCurrentUrl", + "enterInsertMode", "activateLinkHintsMode", "activateLinkHintsModeToOpenInNewTab", + "enterFindMode", "performFind", "performBackwardsFind"], + historyNavigation: + ["goBack", "goForward"], + tabManipulation: + ["nextTab", "previousTab", "createTab", "removeTab", "restoreTab"] +}; + +mapKeyToCommand('?', 'showHelp'); mapKeyToCommand('j', 'scrollDown'); mapKeyToCommand('k', 'scrollUp'); mapKeyToCommand('h', 'scrollLeft'); diff --git a/helpDialog.html b/helpDialog.html new file mode 100644 index 00000000..856663f1 --- /dev/null +++ b/helpDialog.html @@ -0,0 +1,105 @@ +<!-- + This is show when typing "?". This HTML is loaded by the background page and then populated with the + latest keybindings information before displaying. +--> +<div id="vimiumHelpDialog"> + <style> + #vimiumHelpDialog { + text-align:left; + border:3px solid red; + opacity:0.92; + background-color:#eee; + position:fixed; + width:600px; + font-size:12px; + color:black; + font-family:helvetica, arial, sans; + border: 2px solid #b3b3b3; + border-radius:6px; + padding:8px 12px; + width:640px; + left:50%; + /* This needs to be 1/2 width to horizontally center the help dialog */ + margin-left:-320px; + top:50px; + -webkit-box-shadow: rgba(0, 0, 0, 0.4) 0px 0px 6px; + } + #vimiumHelpDialog a { color:blue; } + #vimiumTitle { font-size:20px; } + .vimiumColumn { + width:50%; + float:left; + } + .vimiumColumn table { width:100%; } + .vimiumColumn td { vertical-align:top; } + .vimiumColumn tr > td:first-of-type { + text-align:right; + font-weight:bold; + color:#2f508e; + padding-right:4px; + white-space:nowrap; + } + .vimiumDivider { + height:1px; + width:92%; + margin:10px auto; + background-color:#9a9a9a; + } + .vimiumHelpSectionTitle { + font-weight:bold; + padding-top:5px; + } + #vimiumHelpDialog .closeButton { + position:absolute; + right:10px; + top:5px; + font-family:"courier new"; + font-weight:bold; + color:#555; + text-decoration:none; + padding-left:10px; + font-size:16px; + } + #vimiumHelpDialog .closeButton:hover { + color:black; + cursor:default; + -webkit-user-select:none; + } + #vimiumHelpDialogFooter { font-size:9px; } + </style> + + <!-- Note that the template placeholders (e.g. "pageNavigation") will be filled in by the background + page with the up-to-date key bindings when the dialog is shown. --> + <a class="closeButton" href="#">x</a> + <div id="vimiumTitle">Vim<span style="color:#2f508e">ium</span> Help</div> + <div class="vimiumColumn"> + <table> + <tr><td></td><td></td><td class="vimiumHelpSectionTitle">Navigating the page</td></tr> + {{pageNavigation}} + </table> + </div> + <div class="vimiumColumn"> + <table> + <tr><td></td><td></td><td class="vimiumHelpSectionTitle">Navigating history</td></tr> + {{historyNavigation}} + <tr><td></td><td></td><td class="vimiumHelpSectionTitle">Manipulating tabs</td></tr> + {{tabManipulation}} + </table> + </div> + + <br clear="both"/> + <div class="vimiumDivider"></div> + + <div id="vimiumHelpDialogFooter"> + <div class="vimiumColumn"> + Enjoying Vimium? + <a href="https://chrome.google.com/extensions/detail/dbepggeogbaibhgnhhndojpepiihcmeb">Leave us feedback</a>.<br/> + Found a bug? <a href="http://github.com/philc/vimium/issues">Report it here</a>. + </div> + <div class="vimiumColumn" style="text-align:right"> + <!-- TODO(philc): Replace with real version --> + <span>Version 1.1</span><br/> + <a href="#">Homepage</a> + </div> + </div> +</div>
\ No newline at end of file diff --git a/vimiumFrontend.js b/vimiumFrontend.js index f3259f10..a7dd263d 100644 --- a/vimiumFrontend.js +++ b/vimiumFrontend.js @@ -14,6 +14,7 @@ var insertMode = false; var findMode = false; var findModeQuery = ""; var findModeQueryHasResults = false; +var isShowingHelpDialog = false; var keyPort; var settingPort; var saveZoomLevelPort; @@ -85,6 +86,8 @@ function initializePreDomReady() { HUD.hideUpgradeNotification(); else if (request.name == "showUpgradeNotification" && isEnabledForUrl) HUD.showUpgradeNotification(request.version); + else if (request.name == "showHelpDialog") + showHelpDialog(request.dialogHtml); sendResponse({}); // Free up the resources used by this open connection. }); @@ -331,6 +334,10 @@ function onKeydown(event) { else if (event.keyCode == keyCodes.enter) handleEnterForFindMode(); } + else if (isShowingHelpDialog && isEscape(event)) + { + hideHelpDialog(); + } else if (!insertMode && !findMode) { if (keyChar) { if (currentCompletionKeys.indexOf(keyChar) != -1) { @@ -483,6 +490,24 @@ function exitFindMode() { HUD.hide(); } +function showHelpDialog(html) { + if (isShowingHelpDialog) + return false; + isShowingHelpDialog = true; + var container = document.createElement("div"); + container.id = "vimiumHelpDialogContainer"; + container.innerHTML = html; + container.getElementsByClassName("closeButton")[0].addEventListener("click", hideHelpDialog, false); + document.body.appendChild(container); +} + +function hideHelpDialog() { + isShowingHelpDialog = false; + var helpDialog = document.getElementById("vimiumHelpDialogContainer"); + if (helpDialog) + helpDialog.parentNode.removeChild(helpDialog); +} + /* * A heads-up-display (HUD) for showing Vimium page operations. * Note: you cannot interact with the HUD until document.body is available. |
