Updated slate-irc and tabcomplete

This commit is contained in:
Mattias Erming 2014-06-06 22:05:47 +02:00
parent e7234f66d5
commit ad03879a34
4 changed files with 113 additions and 56 deletions

View File

@ -224,9 +224,10 @@ button {
color: #33b0f7; color: #33b0f7;
} }
#chat .show-more:disabled { #chat .show-more:disabled {
color: #bec5d0; display: none;
/*color: #bec5d0;
opacity: .4; opacity: .4;
text-decoration: line-through; text-decoration: line-through;*/
} }
#chat .messages { #chat .messages {
display: table; display: table;
@ -336,7 +337,7 @@ button {
height: 35px; height: 35px;
left: 0; left: 0;
position: absolute; position: absolute;
right: 180px; right: 160px;
} }
#chat .form .hint { #chat .form .hint {
color: #bbb; color: #bbb;

View File

@ -64,7 +64,7 @@ $(function() {
.sticky() .sticky()
.end() .end()
.find(".input") .find(".input")
.tabComplete(commands, {hint: false}); .tabcomplete(commands, {hint: false});
$("#network-" + data.id) $("#network-" + data.id)
.append(render("channels", {channels: [data.chan]})) .append(render("channels", {channels: [data.chan]}))
@ -95,7 +95,7 @@ $(function() {
var channels = $.map(data.networks, function(n) { return n.channels; }); var channels = $.map(data.networks, function(n) { return n.channels; });
chat.html(render("windows", {windows: channels})) chat.html(render("windows", {windows: channels}))
.find(".input") .find(".input")
.tabComplete(commands, {hint: false}) .tabcomplete(commands, {hint: false})
.end() .end()
.find(".hidden") .find(".hidden")
.prev(".show-more") .prev(".show-more")

View File

@ -94,28 +94,30 @@
})(jQuery); })(jQuery);
/*! /*!
* tabComplete * tabcomplete
* Lightweight tab completion for <input> and <textarea> * Lightweight tab completion for inputs and textareas
* *
* Source: * Source:
* https://github.com/erming/tabComplete * https://github.com/erming/tabcomplete
* *
* Copyright (c) 2014 Mattias Erming <mattias@mattiaserming.com> * Copyright (c) 2014 Mattias Erming <mattias@mattiaserming.com>
* Licensed under the MIT License. * Licensed under the MIT License.
* *
* Version 1.1.1 * Version 1.3.1
*/ */
(function($) { (function($) {
var keys = { var keys = {
backspace: 8,
tab: 9, tab: 9,
up: 38, up: 38,
down: 40 down: 40
}; };
$.fn.tabComplete = function(args, options) { $.fn.tab = // Alias
$.fn.tabcomplete = function(args, options) {
if (this.length > 1) { if (this.length > 1) {
return this.each(function() { return this.each(function() {
$(this).tabComplete(args, options); $(this).tabcomplete(args, options);
}); });
} }
@ -130,42 +132,67 @@
after: "", after: "",
arrowKeys: tag == "INPUT" ? true : false, arrowKeys: tag == "INPUT" ? true : false,
caseSensitive: false, caseSensitive: false,
hint: true, hint: "placeholder",
minLength: 1, minLength: 1
onTabComplete: $.noop
}, options); }, options);
// Unbind namespace. // Remove any leftovers.
// This allows us to override the plugin if necessary. // This allows us to override the plugin if necessary.
this.unbind(".tabComplete"); this.unbind(".tabcomplete");
this.prev(".hint").remove();
var self = this; var self = this;
var backspace = false;
var i = -1; var i = -1;
var words = []; var words = [];
var last = ""; var last = "";
this.on("input.tabComplete", function(e) { var hint = $.noop;
// Determine what type of hinting to use.
switch (options.hint) {
case "placeholder":
hint = placeholder;
break;
case "select":
hint = select;
break;
}
this.on("input.tabcomplete", function() {
var input = self.val(); var input = self.val();
var word = input.split(/ |\n/).pop(); var word = input.split(/ |\n/).pop();
if (!word) { // Reset iteration.
i = -1; i = -1;
words = []; last = "";
last = ""; words = [];
} else if (typeof args === "function") {
// If the user supplies a function, invoke it // Check for matches if the current word is the last word.
// and keep the result. if (self[0].selectionStart == input.length
words = args(word); && word.length) {
} else { if (typeof args === "function") {
// Otherwise, call the .match() function. // If the user supplies a function, invoke it
words = match(args, word, options.caseSensitive); // and keep the result.
words = args(word);
} else {
// Otherwise, call the .match() function.
words = match(word, args, options.caseSensitive);
}
// Append 'after' to each word.
if (options.after) {
words = $.map(words, function(w) { return w + options.after; });
}
} }
// Emit the number of matching words with the 'match' event. // Emit the number of matching words with the 'match' event.
self.trigger("match", words.length); self.trigger("match", words.length);
if (options.hint) { if (options.hint) {
if (word.length >= options.minLength && words.length) { if (!(options.hint == "select" && backspace) && word.length >= options.minLength) {
// Show hint.
hint.call(self, words[0]); hint.call(self, words[0]);
} else { } else {
// Clear hinting. // Clear hinting.
@ -173,11 +200,17 @@
hint.call(self, ""); hint.call(self, "");
} }
} }
if (backspace) {
backspace = false;
}
}); });
this.on("keydown.tabComplete", function(e) { this.on("keydown.tabcomplete", function(e) {
var key = e.which; var key = e.which;
if (key == keys.tab || (options.arrowKeys && (key == keys.up || key == keys.down))) { if (key == keys.tab
|| (options.arrowKeys && (key == keys.up || key == keys.down))) {
// Don't lose focus on tab click. // Don't lose focus on tab click.
e.preventDefault(); e.preventDefault();
@ -194,39 +227,50 @@
i--; i--;
} }
} }
// Get next match. // Get next match.
var word = words[i % words.length]; var word = words[i % words.length];
if (!word) { if (!word) {
return; return;
} }
var input = self.val().trim(); var value = self.val();
last = last || input.split(/ |\n/).pop(); last = last || value.split(/ |\n/).pop();
// Return if the 'minLength' requirement isn't met.
if (last.length < options.minLength) { if (last.length < options.minLength) {
return; return;
} }
self.val( // Update element with the completed text.
input.substr(0, input.lastIndexOf(last)) var text = value.substr(0, self[0].selectionStart - last.length) + word;
+ word self.val(text);
+ options.after
); // Put the cursor at the end after completion.
// This isn't strictly necessary, but solves an issue with
// Internet Explorer.
if (options.hint == "select") {
self[0].selectionStart = text.length;
}
// Remember the word until next time. // Remember the word until next time.
last = word; last = word;
// Trigger callback. // Emit event.
options.onTabComplete(last); self.trigger("tabcomplete", last);
// Trigger the 'tabComplete' event on a successful complete.
self.trigger("tabComplete", last);
if (options.hint) { if (options.hint) {
// Turn off any additional hinting. // Turn off any additional hinting.
hint.call(self, ""); hint.call(self, "");
} }
} else if (e.which == keys.backspace) {
// Remember that backspace was pressed. This is used
// by the 'input' event.
backspace = true;
// Reset iteration.
i = -1;
last = "";
} }
}); });
@ -239,8 +283,8 @@
} }
// Simple matching. // Simple matching.
// Filter the array and return the items that begins with `word`. // Filter the array and return the items that begins with 'word'.
function match(array, word, caseSensitive) { function match(word, array, caseSensitive) {
return $.grep( return $.grep(
array, array,
function(w) { function(w) {
@ -253,10 +297,10 @@
); );
} }
// Input hinting. // Show placeholder text.
// This works by creating a copy of the input and placing it behind // This works by creating a copy of the input and placing it behind
// the real input. // the real input.
function hint(word) { function placeholder(word) {
var input = this; var input = this;
var clone = input.prev(".hint"); var clone = input.prev(".hint");
@ -284,12 +328,27 @@
var hint = ""; var hint = "";
if (typeof word !== "undefined") { if (typeof word !== "undefined") {
var text = input.val(); var value = input.val();
hint = text + word.substr(text.split(/ |\n/).pop().length); hint = value + word.substr(value.split(/ |\n/).pop().length);
} }
clone.val(hint); clone.val(hint);
} }
// Hint by selecting part of the suggested word.
function select(word) {
var input = this;
var value = input.val();
if (word) {
input.val(
value
+ word.substr(value.split(/ |\n/).pop().length)
);
// Select hint.
input[0].selectionStart = value.length;
}
}
})(jQuery); })(jQuery);
/*! /*!

View File

@ -501,12 +501,9 @@ function event(e, data) {
break; break;
} }
chan.users = []; chan.users = [];
for (var n in data.names) { _.each(data.names, function(n) {
chan.users.push(new User({ chan.users.push(new User(n));
mode: data.names[n], });
name: n
}));
}
chan.sortUsers(); chan.sortUsers();
sockets.emit("users", { sockets.emit("users", {
id: chan.id, id: chan.id,