diff options
Diffstat (limited to 'vimiumFrontend.js')
| -rw-r--r-- | vimiumFrontend.js | 93 | 
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() { | 
