diff options
| author | jez | 2011-01-23 20:35:33 +0800 | 
|---|---|---|
| committer | jez | 2011-01-23 20:35:33 +0800 | 
| commit | dd26fc934d2b40cc25b6e357c08ef697435edec9 (patch) | |
| tree | 460b9c5842f94cf75e652934acd1846979cafa0a | |
| parent | fbcb2ddc585c1078e68efc2cfec324a0436ed5f7 (diff) | |
| download | vimium-dd26fc934d2b40cc25b6e357c08ef697435edec9.tar.bz2 | |
Make deactivateMode() within linkHintsBase async
| -rw-r--r-- | linkHints.js | 126 | ||||
| -rw-r--r-- | test_harnesses/automated.html | 4 | 
2 files changed, 45 insertions, 85 deletions
| diff --git a/linkHints.js b/linkHints.js index f7f3e306..40538e0a 100644 --- a/linkHints.js +++ b/linkHints.js @@ -39,6 +39,8 @@ var linkHintsBase = {    openLinkModeToggle: false,    // Whether we have added to the page the CSS needed to display link hints.    cssAdded: false, +  // While in delayMode, all keypresses have no effect. +  delayMode: false,    /*     * To be called after linkHints has been generated from linkHintsBase. @@ -200,6 +202,9 @@ var linkHintsBase = {     * Handles shift and esc keys. The other keys are passed to normalKeyDownHandler.     */    onKeyDownInMode: function(event) { +    if (this.delayMode) +      return; +      if (event.keyCode == keyCodes.shiftKey && !this.openLinkModeToggle) {        // Toggle whether to open link in a new or current tab.        this.setOpenLinkMode(!this.shouldOpenInNewTab, this.shouldOpenWithQueue); @@ -235,24 +240,28 @@ var linkHintsBase = {    /*     * When only one link hint remains, this function activates it in the appropriate way.     */ -  activateLink: function(matchedLink) { +  activateLink: function(matchedLink, delay) { +    var that = this; +    this.delayMode = true;      if (this.isSelectable(matchedLink)) {        this.simulateSelect(matchedLink); -      this.deactivateMode();      } 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 (this.shouldOpenWithQueue) {          this.simulateClick(matchedLink); -        this.resetMode(); +        this.deactivateMode(delay, function() { +          that.delayMode = false; +          that.activateModeWithQueue(); +        });        } else if (this.shouldOpenInNewTab) {          this.simulateClick(matchedLink);          matchedLink.focus(); -        this.deactivateMode(); +        this.deactivateMode(delay, function() { that.delayMode = false; });        } 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.          setTimeout(this.simulateClick.bind(this, matchedLink), 400);          matchedLink.focus(); -        this.deactivateMode(); +        this.deactivateMode(delay, function() { that.delayMode = false; });        }      }    }, @@ -302,21 +311,29 @@ var linkHintsBase = {      link.dispatchEvent(event);    }, -  deactivateMode: function() { -    if (this.hintMarkerContainingDiv) -      this.hintMarkerContainingDiv.parentNode.removeChild(this.hintMarkerContainingDiv); -    this.hintMarkerContainingDiv = null; -    this.hintMarkers = []; -    this.hintKeystrokeQueue = []; -    document.removeEventListener("keydown", this.onKeyDownInMode, true); -    document.removeEventListener("keyup", this.onKeyUpInMode, true); -    this.modeActivated = false; -    HUD.hide(); -  }, - -  resetMode: function() { -    this.deactivateMode(); -    this.activateModeWithQueue(); +  /* +   * If called without arguments, it executes immediately.  Othewise, it +   * executes after 'delay' and invokes 'callback' when it is finished. +   */ +  deactivateMode: function(delay, callback) { +    var that = this; +    function deactivate() { +      if (that.hintMarkerContainingDiv) +        that.hintMarkerContainingDiv.parentNode.removeChild(that.hintMarkerContainingDiv); +      that.hintMarkerContainingDiv = null; +      that.hintMarkers = []; +      that.hintKeystrokeQueue = []; +      document.removeEventListener("keydown", that.onKeyDownInMode, true); +      document.removeEventListener("keyup", that.onKeyUpInMode, true); +      that.modeActivated = false; +      HUD.hide(); +    } +    // we invoke the deactivate() function directly instead of using setTimeout(callback, 0) so that +    // deactivateMode can be tested synchronously +    if (!delay) +      deactivate(); +    else +      setTimeout(function() { deactivate(); if (callback) callback(); }, delay);    },    /* @@ -417,7 +434,6 @@ var alphabetHints = {  filterHints = {    linkTextKeystrokeQueue: [],    labelMap: {}, -  delayMode: false,    /*     * Generate a map of input element => label @@ -469,8 +485,6 @@ filterHints = {    },    normalKeyDownHandler: function(event) { -    if (this.delayMode) -      return;      if (event.keyCode == keyCodes.backspace || event.keyCode == keyCodes.deleteKey) {        if (this.linkTextKeystrokeQueue.length == 0 && this.hintKeystrokeQueue.length == 0) {          this.deactivateMode(); @@ -529,36 +543,6 @@ filterHints = {    },    /* -   * If called without arguments, it executes immediately.  Othewise, it -   * executes after 'delay'. -   */ -  activateLink: function(matchedLink, delay) { -    var that = this; -    if (delay) { -      that.delayMode = true; -      if (that.isSelectable(matchedLink)) { -        that.simulateSelect(matchedLink); -        that.deactivateMode(delay, function() { that.delayMode = false; }); -      } else { -        if (that.shouldOpenWithQueue) { -          that.simulateClick(matchedLink); -          that.resetMode(delay); -        } else if (that.shouldOpenInNewTab) { -          that.simulateClick(matchedLink); -          matchedLink.focus(); -          that.deactivateMode(delay, function() { that.delayMode = false; }); -        } else { -          setTimeout(that.simulateClick.bind(that, matchedLink), 400); -          matchedLink.focus(); -          that.deactivateMode(delay, function() { that.delayMode = false; }); -        } -      } -    } else { -      that._super('activateLink')(matchedLink); -    } -  }, - -  /*     * Hides the links that do not match the linkText search string and marks     * them with the 'filtered' DOM property. Renumbers the remainder.  Should     * only be called when there is a change in linkTextKeystrokeQueue, to @@ -588,36 +572,10 @@ filterHints = {      return linksMatched;    }, -  /* -   * If called without arguments, it executes immediately.  Othewise, it -   * executes after 'delay' and invokes 'callback' when it is finished. -   */    deactivateMode: function(delay, callback) { -    var that = this; -    function deactivate() { -      that.linkTextKeystrokeQueue = []; -      that.labelMap = {}; -      that._super('deactivateMode')(); -    } -    if (!delay) -      deactivate(); -    else -      setTimeout(function() { deactivate(); if (callback) callback(); }, delay); -  }, - -  resetMode: function(delay, callback) { -    var that = this; -    if (!delay) { -      that.deactivateMode(); -      that.activateModeWithQueue(); -    } else { -      that.deactivateMode(delay, function() { -          that.delayMode = false; -          that.activateModeWithQueue(); -          if (callback) -            callback(); -      }); -    } +    this.linkTextKeystrokeQueue = []; +    this.labelMap = {}; +    this._super('deactivateMode')(delay, callback);    }  } diff --git a/test_harnesses/automated.html b/test_harnesses/automated.html index 0d3aa9c4..bbfa220f 100644 --- a/test_harnesses/automated.html +++ b/test_harnesses/automated.html @@ -84,8 +84,10 @@              linkHints.activateMode();              assertStartPosition(document.getElementsByTagName("a")[0], linkHints.hintMarkers[0]);              assertStartPosition(document.getElementsByTagName("a")[1], linkHints.hintMarkers[1]); +            linkHints.deactivateMode(); +              stub(document.body.style, "position", "relative"); -            linkHints.resetMode(); +            linkHints.activateMode();              assertStartPosition(document.getElementsByTagName("a")[0], linkHints.hintMarkers[0]);              assertStartPosition(document.getElementsByTagName("a")[1], linkHints.hintMarkers[1]);              linkHints.deactivateMode(); | 
