X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/362ea2e7f8ac4254398791139cc060090199f400..b4497f656baaee3053895d2b4060f26542e69ffe:/wolnelektury/static/js/jquery.autocomplete.js
diff --git a/wolnelektury/static/js/jquery.autocomplete.js b/wolnelektury/static/js/jquery.autocomplete.js
index 5ad9178f8..4e425e8bd 100644
--- a/wolnelektury/static/js/jquery.autocomplete.js
+++ b/wolnelektury/static/js/jquery.autocomplete.js
@@ -1,14 +1,18 @@
/*
- * Autocomplete - jQuery plugin 1.0.2
+ * jQuery Autocomplete plugin 1.1
*
- * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
+ * Copyright (c) 2009 Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
- * Revision: $Id: jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer $
- *
+ * Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $
+ */
+
+/*
+ * Modified by Radek Czajka, Fundacja Nowoczesna Polska, 2010-05-10:
+ * escape regex for word start checking in matchSubset
*/
;(function($) {
@@ -90,6 +94,9 @@ $.Autocompleter = function(input, options) {
// only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
+ // a keypress means the input has focus
+ // avoids issue where input had focus before the autocomplete was applied
+ hasFocus = 1;
// track last key pressed
lastKeyPressCode = event.keyCode;
switch(event.keyCode) {
@@ -209,7 +216,21 @@ $.Autocompleter = function(input, options) {
if ( options.multiple ) {
var words = trimWords($input.val());
if ( words.length > 1 ) {
- v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
+ var seperator = options.multipleSeparator.length;
+ var cursorAt = $(input).selection().start;
+ var wordAt, progress = 0;
+ $.each(words, function(i, word) {
+ progress += word.length;
+ if (cursorAt <= progress) {
+ wordAt = i;
+ return false;
+ }
+ progress += seperator;
+ });
+ words[wordAt] = v;
+ // TODO this should set the cursor to the right position, but it gets overriden somewhere
+ //$.Autocompleter.Selection(input, progress + seperator, progress + seperator);
+ v = words.join( options.multipleSeparator );
}
v += options.multipleSeparator;
}
@@ -246,22 +267,27 @@ $.Autocompleter = function(input, options) {
};
function trimWords(value) {
- if ( !value ) {
+ if (!value)
return [""];
- }
- var words = value.split( options.multipleSeparator );
- var result = [];
- $.each(words, function(i, value) {
- if ( $.trim(value) )
- result[i] = $.trim(value);
+ if (!options.multiple)
+ return [$.trim(value)];
+ return $.map(value.split(options.multipleSeparator), function(word) {
+ return $.trim(value).length ? $.trim(word) : null;
});
- return result;
}
function lastWord(value) {
if ( !options.multiple )
return value;
var words = trimWords(value);
+ if (words.length == 1)
+ return words[0];
+ var cursorAt = $(input).selection().start;
+ if (cursorAt == value.length) {
+ words = trimWords(value)
+ } else {
+ words = trimWords(value.replace(value.substring(cursorAt), ""));
+ }
return words[words.length - 1];
}
@@ -275,7 +301,7 @@ $.Autocompleter = function(input, options) {
// fill in the value (keep the case the user has typed)
$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
// select the portion of the value not typed by the user (so the next character will erase)
- $.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
+ $(input).selection(previousValue.length, previousValue.length + sValue.length);
}
};
@@ -299,15 +325,14 @@ $.Autocompleter = function(input, options) {
var words = trimWords($input.val()).slice(0, -1);
$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
}
- else
+ else {
$input.val( "" );
+ $input.trigger("result", null);
+ }
}
}
);
}
- if (wasVisible)
- // position cursor at end of input field
- $.Autocompleter.Selection(input, input.value.length, input.value.length);
};
function receiveData(q, data) {
@@ -405,8 +430,22 @@ $.Autocompleter.defaults = {
width: 0,
multiple: false,
multipleSeparator: ", ",
+ regex_escape: function(term) {
+ term = term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1");
+ /* no polish diacritics; should be more locale-aware */
+ term = term.replace(/a/g, '[aÄ
]')
+ .replace(/c/g, '[cÄ]')
+ .replace(/e/g, '[eÄ]')
+ .replace(/l/g, '[lÅ]')
+ .replace(/n/g, '[nÅ]')
+ .replace(/o/g, '[oó]')
+ .replace(/s/g, '[sÅ]')
+ .replace(/z/g, '[zźż]');
+ return term;
+ },
highlight: function(value, term) {
- return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1");
+ term = $.Autocompleter.defaults.regex_escape(term);
+ return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1");
},
scroll: true,
scrollHeight: 180
@@ -421,6 +460,10 @@ $.Autocompleter.Cache = function(options) {
if (!options.matchCase)
s = s.toLowerCase();
var i = s.indexOf(sub);
+ if (options.matchContains == "word"){
+ query = $.Autocompleter.defaults.regex_escape(sub.toLowerCase());
+ i = s.toLowerCase().search("\\b" + query);
+ }
if (i == -1) return false;
return i == 0 || options.matchContains;
};
@@ -738,22 +781,48 @@ $.Autocompleter.Select = function (options, input, select, config) {
};
};
-$.Autocompleter.Selection = function(field, start, end) {
- if( field.createTextRange ){
- var selRange = field.createTextRange();
- selRange.collapse(true);
- selRange.moveStart("character", start);
- selRange.moveEnd("character", end);
- selRange.select();
- } else if( field.setSelectionRange ){
- field.setSelectionRange(start, end);
- } else {
- if( field.selectionStart ){
- field.selectionStart = start;
- field.selectionEnd = end;
+$.fn.selection = function(start, end) {
+ if (start !== undefined) {
+ return this.each(function() {
+ if( this.createTextRange ){
+ var selRange = this.createTextRange();
+ if (end === undefined || start == end) {
+ selRange.move("character", start);
+ selRange.select();
+ } else {
+ selRange.collapse(true);
+ selRange.moveStart("character", start);
+ selRange.moveEnd("character", end);
+ selRange.select();
+ }
+ } else if( this.setSelectionRange ){
+ this.setSelectionRange(start, end);
+ } else if( this.selectionStart ){
+ this.selectionStart = start;
+ this.selectionEnd = end;
+ }
+ });
+ }
+ var field = this[0];
+ if ( field.createTextRange ) {
+ var range = document.selection.createRange(),
+ orig = field.value,
+ teststring = "<->",
+ textLength = range.text.length;
+ range.text = teststring;
+ var caretAt = field.value.indexOf(teststring);
+ field.value = orig;
+ this.selection(caretAt, caretAt + textLength);
+ return {
+ start: caretAt,
+ end: caretAt + textLength
+ }
+ } else if( field.selectionStart !== undefined ){
+ return {
+ start: field.selectionStart,
+ end: field.selectionEnd
}
}
- field.focus();
};
})(jQuery);
\ No newline at end of file