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

View file

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

View file

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

View file

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