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/ node_modules/
npm-debug.log

View File

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

View File

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

View File

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

View File

@ -71,7 +71,7 @@
* 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.2.0 * Version 1.2.1
*/ */
(function($) { (function($) {
$.fn.scrollGlue = function(options) { $.fn.scrollGlue = function(options) {
@ -161,75 +161,164 @@
* 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 0.2.4 * Version 1.0.0-alpha2
*/ */
(function($) { (function($) {
$.fn.tabComplete = function(options) { var defaults = {
var settings = $.extend({ after: "",
after: '',
caseSensitive: false, caseSensitive: false,
list: [], hint: true,
}, options); minLength: 1,
};
$.fn.tabComplete = function(args, options) {
var self = this; var self = this;
if (self.size() > 1) { options = $.extend(
return self.each(function() { {}, defaults, options
$(this).tabComplete(options); );
if (this.length > 1) {
return this.each(function() {
$(this).tabComplete(args, options);
}); });
} }
// Keep the list stored in the DOM via jQuery.data() if (options.hint) {
self.data('list', settings.list); // Lets turn on hinting.
hint.call(self, "");
var match = [];
self.on('keydown', function(e) {
var key = e.which;
if (key != 9) {
match = [];
return;
} }
var text = self.val().trim().split(' '); // Unbind namespace.
var last = text.splice(-1)[0]; // This allows us to override the plugin if necessary.
this.unbind(".tabComplete");
if (!match.length) { var i = 0;
match = []; var words = [];
$.each(self.data('list'), function(i, w) { var last = "";
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; this.on("input.tabComplete", function(e) {
if (i == match.length) { var input = self.val();
var word = input.split(/ |\n/).pop();
if (!word) {
i = 0; 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) { if (options.hint) {
text.push(match[i]); if (word.length >= options.minLength) {
self.val(text.join(' ') + settings.after); 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;
} }
return false; 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 this; 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); })(jQuery);
/*! /*!

View File

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