diff options
Diffstat (limited to 'completionDialog.js')
| -rw-r--r-- | completionDialog.js | 180 | 
1 files changed, 180 insertions, 0 deletions
| diff --git a/completionDialog.js b/completionDialog.js new file mode 100644 index 00000000..fae034fd --- /dev/null +++ b/completionDialog.js @@ -0,0 +1,180 @@ +(function(window, document) { + +  var CompletionDialog = function(options) { this.options = options; } + +  CompletionDialog.prototype = { +    show: function() { +      if (!this.isShown) { +        this.isShown=true; +        this.query = []; +        if (!this.initialized) { +          initialize.call(this); +          this.initialized = true; +        } +        handlerStack.push({ keydown: this.onKeydown }); +        render.call(this); +        clearInterval(this._tweenId); +        this.container.style.display = ""; +        this._tweenId = Tween.fade(this.container, 1.0, 150); +      } +    }, + +    hide: function() { +      if (this.isShown) { +        handlerStack.pop(); +        this.isShown = false; +        this.currentSelection = 0; +        clearInterval(this._tweenId); +        var completionContainer = this.container; +        var cssHide = function() { completionContainer.style.display = "none"; } +        this._tweenId = Tween.fade(this.container, 0, 150, cssHide); +      } +    }, + +    getDisplayElement: function() { +      if (!this.container) +        this.container = createDivInside(document.body); +      return this.container; +    }, + +    getQueryString: function() { return this.query.join(""); } +  } + +  var initialize = function() { +    var self = this; +    addCssToPage(completionCSS); + +    self.currentSelection = 0; + +    self.onKeydown = function(event) { +      var keyChar = getKeyChar(event); +      // change selection with up or Shift-Tab +      if (keyChar==="up" || (event.keyCode == 9 && event.shiftKey)) { +        if (self.currentSelection>0) { +          self.currentSelection-=1; +        } +        render.call(self,self.getQueryString(), self.completions); +      } +      // change selection with down or Tab +      else if (keyChar==="down" || (event.keyCode == 9 && !event.shiftKey)) { +        if (self.currentSelection < self.completions.length - 1) { +          self.currentSelection += 1; +        } +        render.call(self,self.getQueryString(), self.completions); +      } +      else if (event.keyCode == keyCodes.enter) { +        self.options.onSelect(self.completions[self.currentSelection]); +      } +      else if (event.keyCode == keyCodes.backspace || event.keyCode == keyCodes.deleteKey) { +        if (self.query.length > 0) { +          self.query.pop(); +          self.options.source(self.getQueryString(), function(completions) { +            render.call(self, self.getQueryString(), completions); +          }) +        } +      } +      else if (keyChar!=="left" && keyChar!="right") { +        self.query.push(keyChar); +        self.options.source(self.getQueryString(), function(completions) { +          render.call(self, self.getQueryString(), completions); +        }); +      } + +      event.stopPropagation(); +      event.preventDefault(); +      return true; +    } +  } + +  var render = function(searchString, completions) { +    if (this.isShown) { +      this.searchString = searchString; +      this.completions = completions; +      var container = this.getDisplayElement(); +      clearChildren(container); + +      if (searchString === undefined) { +        this.container.className = "vimium-dialog"; +        createDivInside(container).innerHTML = this.options.initialSearchText || "Begin typing"; +      } +      else { +        this.container.className = "vimium-dialog vimium-completions"; +        var searchBar = createDivInside(container); +        searchBar.innerHTML=searchString; +        searchBar.className="vimium-searchBar"; + +        searchResults = createDivInside(container); +        searchResults.className="vimium-searchResults"; +        if (completions.length<=0) { +          var resultDiv = createDivInside(searchResults); +          resultDiv.className="vimium-noResults"; +          resultDiv.innerHTML="No results found"; +        } +        else { +          for (var i = 0; i < completions.length; i++) { +            var resultDiv = createDivInside(searchResults); +            if (i === this.currentSelection) { +              resultDiv.className="vimium-selected"; +            } +            resultDiv.innerHTML=this.options.renderOption(searchString, completions[i]); +          } +        } +      } + +      container.style.top = Math.max(0, (window.innerHeight/2-container.clientHeight/2)) + "px"; +      container.style.left = (window.innerWidth/2-container.clientWidth/2) + "px"; +    } +  }; +  var createDivInside = function(parent) { +    var element = document.createElement("div"); +    parent.appendChild(element); +    return element; +  } + +  var clearChildren = function(elem) { +    if (elem.hasChildNodes()) { +      while (elem.childNodes.length >= 1) { +        elem.removeChild(elem.firstChild); +      } +    } +  } + +  var completionCSS = ".vimium-dialog {"+ +    "position:fixed;"+ +    "background-color: #ebebeb;" + +    "z-index: 99999998;" + +    "border: 1px solid #b3b3b3;" + +    "font-size: 12px;" + +    "text-align:left;"+ +    "color: black;" + +    "padding:10px;"+ +    "border-radius: 4px;" + +    "font-family: Lucida Grande, Arial, Sans;" + +    "}"+ +    ".vimium-completions {"+ +    "width:400px;"+ +    "}"+ +    ".vimium-completions .vimium-searchBar {"+ +    "height: 15px;"+ +    "border-bottom: 1px solid #b3b3b3;"+ +    "}"+ +    ".vimium-completions .vimium-searchResults {"+ +    "}"+ +    ".vimium-completions .vimium-searchResults .vimium-selected{"+ +    "background-color:#aaa;"+ +    "border-radius: 4px;" + +    "}"+ +    ".vimium-completions div{"+ +    "padding:4px;"+ +    "}"+ +    ".vimium-completions div strong{"+ +    "color: black;" + +    "font-weight:bold;"+ +    "}"+ +    ".vimium-completions .vimium-noResults{"+ +    "color:#555;"+ +    "}"; + +  window.CompletionDialog = CompletionDialog; + +}(window, document)) | 
