aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--background_page.html49
-rw-r--r--commands.js22
-rw-r--r--helpDialog.html105
-rw-r--r--vimiumFrontend.js25
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, "&lt;").replace(/>/g, "&gt;"); }
+
+ /*
+ * 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.