Updated jQuery plugins

This commit is contained in:
Mattias Erming 2014-05-14 00:47:35 +02:00
parent ececa3d55c
commit ebabd789ed
6 changed files with 157 additions and 63 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
node_modules/
npm-debug.log

View file

@ -200,6 +200,9 @@ button::-moz-focus-inner {
padding: 0 10px;
width: 100%;
}
#chat form .hint {
color: #bdc3c7;
}
#chat .lobby .messages,
#chat .query .messages {
right: 0;

View file

@ -80,6 +80,7 @@
</div>
<form class="form" onSubmit="return false" data-target="{{id}}">
<input class="input">
<input type="submit" style="display: none">
</form>
</div>
{{/each}}

View file

@ -49,13 +49,13 @@ $(function() {
switch (e) {
case "join":
chat.append(render("windows", {windows: [data.chan]}))
.find(".messages")
.find(".window")
.last()
.find(".messages")
.scrollGlue({speed: 400})
.end()
.end()
.find(".input")
.tabComplete({list: commands});
.tabComplete(commands);
$("#network-" + data.id)
.append(render("channels", {channels: [data.chan]}))
@ -74,7 +74,7 @@ $(function() {
var channels = $.map(data.networks, function(n) { return n.channels; });
chat.html(render("windows", {windows: channels}))
.find(".input")
.tabComplete({list: commands})
.tabComplete(commands)
.end()
.find(".hidden")
.prev(".show-more")
@ -122,15 +122,12 @@ $(function() {
if (!target) {
return;
}
location.hash = target;
sidebar.find(".active").removeClass("active");
button.addClass("active")
.find(".badge")
.removeClass("highlight")
.empty();
var window = $(target)
.css("z-index", z++)
.find("input")
@ -179,7 +176,7 @@ $(function() {
chat.on("submit", "form", function() {
var form = $(this);
var input = form.find(".input");
var input = form.find(".input:not(.hint)");
var text = input.val();
if (text == "") {
return;

View file

@ -71,7 +71,7 @@
* Copyright (c) 2014 Mattias Erming <mattias@mattiaserming.com>
* Licensed under the MIT License.
*
* Version 1.2.0
* Version 1.2.1
*/
(function($) {
$.fn.scrollGlue = function(options) {
@ -161,75 +161,164 @@
* Copyright (c) 2014 Mattias Erming <mattias@mattiaserming.com>
* Licensed under the MIT License.
*
* Version 0.2.4
* Version 1.0.0-alpha2
*/
(function($) {
$.fn.tabComplete = function(options) {
var settings = $.extend({
after: '',
caseSensitive: false,
list: [],
}, options);
var defaults = {
after: "",
caseSensitive: false,
hint: true,
minLength: 1,
};
$.fn.tabComplete = function(args, options) {
var self = this;
if (self.size() > 1) {
return self.each(function() {
$(this).tabComplete(options);
options = $.extend(
{}, defaults, options
);
if (this.length > 1) {
return this.each(function() {
$(this).tabComplete(args, options);
});
}
// Keep the list stored in the DOM via jQuery.data()
self.data('list', settings.list);
if (options.hint) {
// Lets turn on hinting.
hint.call(self, "");
}
var match = [];
self.on('keydown', function(e) {
var key = e.which;
if (key != 9) {
match = [];
return;
}
// Unbind namespace.
// This allows us to override the plugin if necessary.
this.unbind(".tabComplete");
var i = 0;
var words = [];
var last = "";
this.on("input.tabComplete", function(e) {
var input = self.val();
var word = input.split(/ |\n/).pop();
var text = self.val().trim().split(' ');
var last = text.splice(-1)[0];
if (!match.length) {
match = [];
$.each(self.data('list'), function(i, w) {
var l = last;
if (l == '') {
return;
} else if (typeof w === "function") {
var words = w(l);
if (words) {
match = match.concat(words);
}
} else if (!settings.caseSensitive) {
if (0 == w.toLowerCase().indexOf(l.toLowerCase())) {
match.push(w);
}
} else {
if (0 == w.indexOf(l)) {
match.push(w);
}
}
});
}
var i = match.indexOf(last) + 1;
if (i == match.length) {
if (!word) {
i = 0;
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);
}
if (match.length) {
text.push(match[i]);
self.val(text.join(' ') + settings.after);
if (options.hint) {
if (word.length >= options.minLength) {
hint.call(self, words[0]);
} else {
// Clear hinting.
// This call is needed when using backspace.
hint.call(self, "");
}
}
});
this.on("keydown.tabComplete", function(e) {
var key = e.which;
if (key == 9) {
// Don't lose focus on tab click.
e.preventDefault();
// Get next match.
var word = words[i++ % words.length];
if (!word) {
return;
}
var input = self.val().trim();
last = last || input.split(/ |\n/).pop();
if (last.length < options.minLength) {
return;
}
self.val(
input.substr(0, input.lastIndexOf(last))
+ word
+ options.after
);
// Remember the word until next time.
last = word;
if (options.hint) {
// Turn off any additional hinting.
hint.call(self, "");
}
}
return false;
});
return this;
};
}
// Simple matching.
// Filter the array and return the items that begins with `word`.
function match(array, word, caseSensitive) {
return $.grep(
array,
function(w) {
if (caseSensitive) {
return !w.indexOf(word);
} else {
return !w.toLowerCase().indexOf(word.toLowerCase());
}
}
);
}
// Add input hinting.
// This works by creating a copy of the input and placing it behind
// the real input.
function hint(word) {
var input = this;
var clone = input.prev(".hint");
input.css({
backgroundColor: "transparent",
position: "relative",
});
// Lets create a clone of the input if it does
// not already exist.
if (!clone.length) {
input.wrap(
$("<div>").css({position: "relative"})
);
clone = input
.clone()
.prop("disabled", true)
.removeAttr("id name placeholder")
.addClass("hint")
.insertBefore(input);
clone.css({
position: "absolute",
});
}
var hint = "";
if (typeof word !== "undefined") {
var text = input.val();
hint = text + word.substr(last(text).length);
}
clone.val(hint);
}
// Get the last word of a string.
function last(str) {
return str.split(/ |\n/).pop();
}
})(jQuery);
/*!

View file

@ -121,6 +121,9 @@ function input(data) {
var id = data.id;
var text = data.text;
if (!text) {
return;
}
var args = text.replace(/^\//, '').split(" ");
var cmd = text.charAt(0) == "/" ? args[0].toLowerCase() : "";