var esPhinx, Iterable; (function($) { "use strict"; $.prototype.extend({ autocomplete: function(elementsList, options, callback) { var searchTextBox = this, nonCharacterKeysPattern = new RegExp($ .nonCharacterKeysPattern()), inline = false, elements2Recovery = [], afterAmountCharacters = options.afterAmountCharacters, resolveArguments = function(options) { if (!Object.belongToClass(options, Object)) { options = {}; } if (typeof options.caseSensitive != "boolean") { options.caseSensitive = false; } if (typeof options.orderlySearch != "boolean") { options.orderlySearch = false; } if (typeof afterAmountCharacters != "number") { afterAmountCharacters = 1; } }, inlineSearch = function(element, options) { var eventListenerMethod, previousElement, previousSearchText = ""; if (typeof eventListenerMethod == "function") { searchTextBox.off("input", eventListenerMethod); } eventListenerMethod = function(e) { previousElement = previousElement || element .clone(true); var resolvedList, foundElements, resolvedElementsParent, searchTextLength = searchTextBox.value().length; if (searchTextBox.value()) { if (searchTextLength < previousSearchText.length) { previousElement = element.clone(true); } previousSearchText = searchTextBox.value(); resolvedList = resolveList(previousElement, options.order); foundElements = resolvedList.elements; if (foundElements.some()) { resolvedElementsParent = previousElement .clone(); previousElement = resolvedElementsParent .append(resolvedList.elements); } callback.call($(this), foundElements, resolvedList .maps, e); } else { // reset elements2Recovery = []; previousSearchText = ""; previousElement = element.clone(true); callback.call($(this), $(), e); } }; searchTextBox.on("input", eventListenerMethod); }, remoteSearch = function(options) { var word, prevText, nextText, element, URLParameters, resolvedList, clipboardData, request = function(e) { if (options.remote.URLParameters) { URLParameters = options.remote.URLParameters .call(searchTextBox); } $.Ajax.new(options.remote.url.call(searchTextBox)) .get({ URLParameters: URLParameters, progress: function(xhr) { if (options.remote.loading) { options.remote .loading(xhr, e); } }, complete: function() { $(e.target).off("keypress"); }, success: function(r) { element = $(r); if (element.some()) { elements2Recovery.push(element); // completeOften = (searchTextBox // .value().length - // afterAmountCharacters) + 1; // complete2Recovery(element, // completeOften); } resolvedList = resolveList(element, options.order); callback.call(searchTextBox, resolvedList.elements, resolvedList.maps, e); if (element.length) { inlineSearch(element, options); } } }); }; searchTextBox.on("keyup", function(e) { word = searchTextBox.value(); if (word.length > afterAmountCharacters) { inline = true; } else if (word.length < afterAmountCharacters) { inline = false; } if (word.length == afterAmountCharacters && !nonCharacterKeysPattern.test(e.key) && !inline && options.remote) { $(e.target).on("keypress", function(e) { e.preventDefault(); }); request(e); } }); searchTextBox.on("paste", function(e) { word = searchTextBox.value(); prevText = word .slice(0, searchTextBox.cursorPosition()); nextText = word .slice(searchTextBox.selectionEnd(), word.length); clipboardData = e.clipboardData.getData("text"); if (word.length >= afterAmountCharacters) { inline = true; } else { inline = false; } word = prevText + clipboardData + nextText; if (word.length >= afterAmountCharacters && !inline && options.remote) { searchTextBox.value(word); request(e); e.preventDefault(); } }); }, mapIf = function(searchTextAsArray, textNodeAsArray) { var iterator, sliceIndex, regexp, textNodeHashSet = Object .asCountableLiteral(textNodeAsArray), mapped = {}, amount = 0, index = 0, previousIndex = -1, callback = function(slice) { slice = slice.trim(); index = Object.firstFromASlice(textNodeHashSet, slice, index, options .caseSensitive); if (index && ((options.orderlySearch && index > previousIndex) || !options.orderlySearch) && textNodeAsArray.countSlice(slice, options.caseSensitive) >= searchTextAsArray.amount(slice)) { previousIndex = index; if (options.caseSensitive) { regexp = new RegExp(slice); } else { regexp = new RegExp(slice, "i"); } sliceIndex = textNodeAsArray[index] .search(regexp); mapped[index] = textNodeAsArray[index] .slice(sliceIndex, sliceIndex + slice .length); Object.delete(index, textNodeHashSet); amount += 1; } else { this.finalize(); } }; if (textNodeHashSet.length >= searchTextAsArray.length) { iterator = Iterable.Proxy.new(searchTextAsArray); iterator.each(callback); if (amount == searchTextAsArray.length) { return mapped; } } return false; }, // resolveList = function(list, order = "desc") { resolveList = function(list, order) { if (order != "asc") {order = "desc";} var textNode, mapped, textNodeAsArray, sorted, found = {elements: $(), maps: []}, textBoxContentArr = searchTextBox.value().split(" ") .compact(), callback = function(element) { textNode = $(element).textContent().trim(); textNodeAsArray = textNode.split(" "); mapped = mapIf(textBoxContentArr, textNodeAsArray); if (mapped) { found.elements.push(element); found.maps.push(mapped); } }; if (list.elements().amount() == 1 && list.isA(window.Element)) { list = list.childElements().clone(true); } if (order == "desc") { sorted = list.orderTextNodeByDesc(); } else { sorted = list.orderTextNodeByAsc(); } sorted.each(callback); return found; }; resolveArguments(options); // init if (!Object.belongToClass(elementsList, Object)) { inlineSearch(elementsList, options); } else { options = elementsList; remoteSearch(options); } } }); })(esPhinx);