aboutsummaryrefslogtreecommitdiffstats
path: root/completionDialog.js
diff options
context:
space:
mode:
Diffstat (limited to 'completionDialog.js')
-rw-r--r--completionDialog.js180
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))