aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bookmarks.js97
-rw-r--r--completionDialog.js155
-rw-r--r--lib/keyboardUtils.js22
-rw-r--r--manifest.json1
4 files changed, 225 insertions, 50 deletions
diff --git a/bookmarks.js b/bookmarks.js
index faa82148..6708067e 100644
--- a/bookmarks.js
+++ b/bookmarks.js
@@ -36,12 +36,14 @@ function activateBookmarkFindMode() {
}
this.renderHUD();
+ this.completionDialog.show();
this.keyPressListener.enable();
},
disable: function() {
this.enabled = false;
this.keyPressListener.disable();
+ this.completionDialog.hide()
HUD.hide();
},
getQueryString: function() {
@@ -61,71 +63,84 @@ function activateBookmarkFindMode() {
// private method
var initialize = function() {
+ var self = this;
this.initialized = true;
this.finder = new BookmarkFinder({
onResultsFound: function(bookmarks) {
- BookmarkMode.bookmarksFound = bookmarks;
- for(var i=0;i<bookmarks.length;i++) {
- console.log(bookmarks[i].title)
+ self.bookmarksFound = bookmarks;
+ if(bookmarks.length>10) {
+ bookmarks=bookmarks.slice(0, 10)
}
+ self.completionDialog.showCompletions(self.getQueryString(), bookmarks)
}
});
+ this.completionDialog = new CompletionDialog({
+ onSelect: function(selection) {
+ var url = selection.url
+ var isABookmarklet = function(url) {
+ return url.indexOf("javascript:")===0
+ }
+
+ if(!self.newTab || isABookmarklet(url)) {
+ window.location=url
+ }
+ else {
+ window.open(url)
+ }
+
+ self.disable();
+ },
+ renderOption: function(searchString, selection) {
+
+ var displaytext = selection.title + " (" + selection.url + ")"
+
+ if(displaytext.length>70) {
+ displaytext = displaytext.substr(0, 70)+"..."
+ }
+
+ return displaytext.split(new RegExp(searchString, "i")).join("<strong>"+searchString+"</strong>")
+ },
+ initialSearchText: "Type a bookmark name or URL"
+ })
+
this.keyPressListener = new KeyPressListener({
- keyDown: function(key) {
+ keyDown: function(event) {
// shift key will toggle between new tab/same tab
if (event.keyCode == keyCodes.shiftKey) {
- BookmarkMode.invertNewTabSetting();
+ self.invertNewTabSetting();
shiftWasPressedWhileToggled = true
return
}
- if(event.keyCode == keyCodes.enter) {
- var bookmarksFound = BookmarkMode.bookmarksFound;
- if(bookmarksFound && bookmarksFound.length>0) {
- var url = bookmarksFound[0].url
- var isABookmarklet = function(url) {
- return url.indexOf("javascript:")===0
- }
-
- if(!BookmarkMode.newTab || isABookmarklet(url)) {
- window.location=url
- }
- else {
- window.open(url)
- }
-
- BookmarkMode.disable();
- }
- }
-
var keyChar = getKeyChar(event);
if (!keyChar)
return;
// TODO(philc): Ignore keys that have modifiers.
if (isEscape(event)) {
- BookmarkMode.disable();
+ self.disable();
}
else if (event.keyCode == keyCodes.backspace || event.keyCode == keyCodes.deleteKey) {
- if (BookmarkMode.query.length == 0) {
- BookmarkMode.disable();
+ if (self.query.length == 0) {
+ self.disable();
} else {
- BookmarkMode.query.pop();
+ self.query.pop();
+ self.finder.find(self.getQueryString())
}
}
- else {
- BookmarkMode.query.push(keyChar);
+ else if(keyChar!=="up" && keyChar!=="down" && keyChar!=="left" && keyChar!="right") {
+ self.query.push(keyChar);
+ self.finder.find(self.getQueryString())
}
- BookmarkMode.finder.find(BookmarkMode.getQueryString())
event.stopPropagation();
event.preventDefault();
},
keyUp: function(event) {
// shift key will toggle between new tab/same tab
if (event.keyCode == keyCodes.shiftKey && shiftWasPressedWhileToggled) {
- BookmarkMode.invertNewTabSetting();
+ self.invertNewTabSetting();
shiftWasPressedWhileToggled = false
}
event.stopPropagation();
@@ -142,28 +157,10 @@ function activateBookmarkFindMode() {
}
BookmarkFinder.prototype = {
find: function(query) {
- console.log("You typed: " + query)
this.port.postMessage({query:query})
}
}
- var KeyPressListener = function(handlers) {
- this.handlers = handlers;
- }
-
- KeyPressListener.prototype = {
- enable: function() {
- var handlers = this.handlers;
- (handlers.keyDown && document.addEventListener("keydown", handlers.keyDown, true));
- (handlers.keyUp && document.addEventListener("keyup", handlers.keyUp, true));
- },
- disable: function() {
- var handlers = this.handlers;
- (handlers.keyDown && document.removeEventListener("keydown", handlers.keyDown, true));
- (handlers.keyUp && document.removeEventListener("keyup", handlers.keyUp, true));
- }
- }
-
//export global
window.BookmarkMode = BookmarkMode;
diff --git a/completionDialog.js b/completionDialog.js
new file mode 100644
index 00000000..f7ebefa5
--- /dev/null
+++ b/completionDialog.js
@@ -0,0 +1,155 @@
+(function(window, document) {
+
+ var CompletionDialog = function(options) {
+ this.options = options
+ }
+
+ CompletionDialog.prototype = {
+ show: function() {
+ this.showCompletions()
+ },
+ showCompletions: function(searchString, completions) {
+ this.searchString = searchString;
+ this.completions = completions;
+ if(!this.initialized) {
+ initialize.call(this);
+ this.initialized=true;
+ }
+ var container = this.getDisplayElement()
+ clearChildren(container);
+
+ if(searchString===undefined) {
+ this.container.className = "dialog";
+ createDivInside(container).innerHTML=this.options.initialSearchText || "Begin typing"
+ }
+ else {
+ this.container.className = "dialog completions";
+ var searchBar = createDivInside(container)
+ searchBar.innerHTML=searchString
+ searchBar.className="searchBar"
+
+ searchResults = createDivInside(container)
+ searchResults.className="searchResults"
+ if(completions.length<=0) {
+ var resultDiv = createDivInside(searchResults)
+ resultDiv.className="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="selected"
+ }
+ resultDiv.innerHTML=this.options.renderOption(searchString, completions[i])
+ }
+ }
+ }
+
+ container.style.top=(window.innerHeight/2-container.clientHeight/2) + "px";
+ container.style.left=(window.innerWidth/2-container.clientWidth/2) + "px";
+ if(!this.isShown) {
+ this.keyPressListener.enable();
+ clearInterval(this._tweenId);
+ this._tweenId = Tween.fade(container, 1.0, 150);
+ this.isShown=true;
+ }
+ },
+ hide: function() {
+ if(this.isShown) {
+ this.keyPressListener.disable();
+ this.isShown=false;
+ this.currentSelection=0;
+ clearInterval(this._tweenId);
+ this._tweenId = Tween.fade(this.container, 0, 150);
+ }
+ },
+ getDisplayElement: function() {
+ if(!this.container) {
+ this.container = createDivInside(document.body)
+ }
+ return this.container
+ }
+ }
+
+ var initialize = function() {
+ addCssToPage(completionCSS)
+
+ this.currentSelection=0;
+ var self = this;
+ this.keyPressListener = new KeyPressListener({
+ keyDown: function(event) {
+ var keyChar = getKeyChar(event);
+ if(keyChar==="up") {
+ if(self.currentSelection>0) {
+ self.currentSelection-=1;
+ }
+ self.showCompletions(self.searchString, self.completions)
+ }
+ else if(keyChar==="down") {
+ if(self.currentSelection<self.completions.length-1) {
+ self.currentSelection+=1;
+ }
+ self.showCompletions(self.searchString, self.completions)
+ }
+ else if(event.keyCode == keyCodes.enter) {
+ self.options.onSelect(self.completions[self.currentSelection])
+ }
+
+ event.stopPropagation();
+ event.preventDefault();
+ }
+ })
+ }
+
+ 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 = ".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;" +
+ "}"+
+ ".completions {"+
+ "width:400px;"+
+ "}"+
+ ".completions .searchBar {"+
+ "border-bottom: 1px solid #b3b3b3;"+
+ "}"+
+ ".completions .searchResults {"+
+ "}"+
+ ".completions .searchResults .selected{"+
+ "background-color:#aaa;"+
+ "border-radius: 4px;" +
+ "}"+
+ ".completions div{"+
+ "padding:4px;"+
+ "}"+
+ ".completions div strong{"+
+ "font-weight:bold;"+
+ "}"+
+ ".completions .noResults{"+
+ "color:#555;"+
+ "}";
+
+ window.CompletionDialog = CompletionDialog;
+
+}(window, document))
diff --git a/lib/keyboardUtils.js b/lib/keyboardUtils.js
index 98725d95..60eb487f 100644
--- a/lib/keyboardUtils.js
+++ b/lib/keyboardUtils.js
@@ -61,3 +61,25 @@ function isEscape(event) {
return event.keyCode == keyCodes.ESC ||
(event.ctrlKey && getKeyChar(event) == '['); // c-[ is mapped to ESC in Vim by default.
}
+
+var KeyPressListener = function(handlers) {
+ this.handlers = handlers;
+}
+
+KeyPressListener.prototype = {
+ enable: function() {
+ var handlers = this.handlers;
+ var wrapper = function(callback){
+ return function(event) {
+ callback(event)
+ }
+ }
+ (handlers.keyDown && document.addEventListener("keydown", handlers.keyDown, true));
+ (handlers.keyUp && document.addEventListener("keyup", handlers.keyUp, true));
+ },
+ disable: function() {
+ var handlers = this.handlers;
+ (handlers.keyDown && document.removeEventListener("keydown", handlers.keyDown, true));
+ (handlers.keyUp && document.removeEventListener("keyup", handlers.keyUp, true));
+ }
+}
diff --git a/manifest.json b/manifest.json
index 878d8b5c..b8203717 100644
--- a/manifest.json
+++ b/manifest.json
@@ -20,6 +20,7 @@
"lib/clipboard.js",
"linkHints.js",
"vimiumFrontend.js",
+ "completionDialog.js",
"bookmarks.js"
],
"run_at": "document_start",