aboutsummaryrefslogtreecommitdiffstats
path: root/vimiumFrontend.js
diff options
context:
space:
mode:
Diffstat (limited to 'vimiumFrontend.js')
-rw-r--r--vimiumFrontend.js93
1 files changed, 66 insertions, 27 deletions
diff --git a/vimiumFrontend.js b/vimiumFrontend.js
index c9c81381..eb0216f4 100644
--- a/vimiumFrontend.js
+++ b/vimiumFrontend.js
@@ -4,8 +4,6 @@
* the page's zoom level. We tell the background page that we're in domReady and ready to accept normal
* commands by connectiong to a port named "domReady".
*/
-var settings = {};
-var settingsToLoad = ["scrollStepSize", "linkHintCharacters"];
var getCurrentUrlHandlers = []; // function(url)
@@ -14,6 +12,7 @@ var findMode = false;
var findModeQuery = "";
var findModeQueryHasResults = false;
var isShowingHelpDialog = false;
+var handlerStack = [];
var keyPort;
var settingPort;
var saveZoomLevelPort;
@@ -38,6 +37,35 @@ var textInputXPath = '//input[' +
textInputTypes.map(function (type) { return '@type="' + type + '"'; }).join(" or ") +
' or not(@type)]';
+var settings = {
+ values: {},
+ loadedValues: 0,
+ valuesToLoad: ["scrollStepSize", "linkHintCharacters", "filterLinkHints"],
+
+ get: function (key) { return this.values[key]; },
+
+ load: function() {
+ for (var i in this.valuesToLoad) { this.sendMessage(this.valuesToLoad[i]); }
+ },
+
+ sendMessage: function (key) {
+ if (!settingPort)
+ settingPort = chrome.extension.connect({ name: "getSetting" });
+ settingPort.postMessage({ key: key });
+ },
+
+ receiveMessage: function (args) {
+ // not using 'this' due to issues with binding on callback
+ settings.values[args.key] = args.value;
+ if (++settings.loadedValues == settings.valuesToLoad.length)
+ settings.initializeOnReady();
+ },
+
+ initializeOnReady: function () {
+ linkHints.init();
+ }
+};
+
/*
* Give this frame a unique id.
*/
@@ -46,19 +74,11 @@ frameId = Math.floor(Math.random()*999999999)
var hasModifiersRegex = /^<([amc]-)+.>/;
var googleRegex = /:\/\/[^/]*google[^/]+/;
-function getSetting(key) {
- if (!settingPort)
- settingPort = chrome.extension.connect({ name: "getSetting" });
- settingPort.postMessage({ key: key });
-}
-
-function setSetting(args) { settings[args.key] = args.value; }
-
/*
* Complete initialization work that sould be done prior to DOMReady, like setting the page's zoom level.
*/
function initializePreDomReady() {
- for (var i in settingsToLoad) { getSetting(settingsToLoad[i]); }
+ settings.load();
checkIfEnabledForUrl();
@@ -97,11 +117,11 @@ function initializePreDomReady() {
chrome.extension.onConnect.addListener(function(port, name) {
if (port.name == "executePageCommand") {
port.onMessage.addListener(function(args) {
- if (this[args.command] && frameId == args.frameId) {
+ if (frameId == args.frameId) {
if (args.passCountToFunction) {
- this[args.command].call(null, args.count);
+ utils.invokeCommandString(args.command, [args.count]);
} else {
- for (var i = 0; i < args.count; i++) { this[args.command].call(); }
+ for (var i = 0; i < args.count; i++) { utils.invokeCommandString(args.command); }
}
}
@@ -132,7 +152,11 @@ function initializePreDomReady() {
setPageZoomLevel(currentZoomLevel);
});
} else if (port.name == "returnSetting") {
- port.onMessage.addListener(setSetting);
+ port.onMessage.addListener(settings.receiveMessage);
+ } else if (port.name == "refreshCompletionKeys") {
+ port.onMessage.addListener(function (args) {
+ refreshCompletionKeys(args.completionKeys);
+ });
}
});
}
@@ -244,14 +268,14 @@ function scrollToBottom() { window.scrollTo(window.pageXOffset, document.body.sc
function scrollToTop() { window.scrollTo(window.pageXOffset, 0); }
function scrollToLeft() { window.scrollTo(0, window.pageYOffset); }
function scrollToRight() { window.scrollTo(document.body.scrollWidth, window.pageYOffset); }
-function scrollUp() { window.scrollBy(0, -1 * settings["scrollStepSize"]); }
-function scrollDown() { window.scrollBy(0, settings["scrollStepSize"]); }
+function scrollUp() { window.scrollBy(0, -1 * settings.get("scrollStepSize")); }
+function scrollDown() { window.scrollBy(0, settings.get("scrollStepSize")); }
function scrollPageUp() { window.scrollBy(0, -1 * window.innerHeight / 2); }
function scrollPageDown() { window.scrollBy(0, window.innerHeight / 2); }
function scrollFullPageUp() { window.scrollBy(0, -window.innerHeight); }
function scrollFullPageDown() { window.scrollBy(0, window.innerHeight); }
-function scrollLeft() { window.scrollBy(-1 * settings["scrollStepSize"], 0); }
-function scrollRight() { window.scrollBy(settings["scrollStepSize"], 0); }
+function scrollLeft() { window.scrollBy(-1 * settings.get("scrollStepSize"), 0); }
+function scrollRight() { window.scrollBy(settings.get("scrollStepSize"), 0); }
function focusInput(count) {
var results = document.evaluate(textInputXPath,
@@ -326,11 +350,11 @@ function toggleViewSourceCallback(url) {
* Note that some keys will only register keydown events and not keystroke events, e.g. ESC.
*/
function onKeypress(event) {
- var keyChar = "";
-
- if (linkHintsModeActivated)
+ if (!bubbleEvent('keypress', event))
return;
+ var keyChar = "";
+
// Ignore modifier keys by themselves.
if (event.keyCode > 31) {
keyChar = String.fromCharCode(event.charCode);
@@ -360,12 +384,22 @@ function onKeypress(event) {
}
}
-function onKeydown(event) {
- var keyChar = "";
+function bubbleEvent(type, event) {
+ for (var i = handlerStack.length-1; i >= 0; i--) {
+ // We need to check for existence of handler because the last function call may have caused the release of
+ // more than one handler.
+ if (handlerStack[i] && handlerStack[i][type] && !handlerStack[i][type](event))
+ return false;
+ }
+ return true;
+}
- if (linkHintsModeActivated)
+function onKeydown(event) {
+ if (!bubbleEvent('keydown', event))
return;
+ var keyChar = "";
+
// handle modifiers being pressed.don't handle shiftKey alone (to avoid / being interpreted as ?
if (event.metaKey && event.keyCode > 31 || event.ctrlKey && event.keyCode > 31 || event.altKey && event.keyCode > 31) {
keyChar = getKeyChar(event);
@@ -447,6 +481,11 @@ function onKeydown(event) {
event.stopPropagation();
}
+function onKeyup() {
+ if (!bubbleEvent('keyup', event))
+ return;
+}
+
function checkIfEnabledForUrl() {
var url = window.location.toString();
@@ -496,7 +535,7 @@ function isFocusable(element) { return isEditable(element) || isEmbed(element);
* Embedded elements like Flash and quicktime players can obtain focus but cannot be programmatically
* unfocused.
*/
-function isEmbed(element) { return ["EMBED", "OBJECT"].indexOf(element.tagName) > 0; }
+function isEmbed(element) { return ["embed", "object"].indexOf(element.nodeName.toLowerCase()) > 0; }
/*
* Input or text elements are considered focusable and able to receieve their own keyboard events,
@@ -509,7 +548,7 @@ function isEditable(target) {
if (target.getAttribute("contentEditable") == "true")
return true;
var focusableInputs = ["input", "textarea", "select", "button"];
- return focusableInputs.indexOf(target.tagName.toLowerCase()) >= 0;
+ return focusableInputs.indexOf(target.nodeName.toLowerCase()) >= 0;
}
function enterInsertMode() {