(function (){
var _=function (input, o){
var me=this;
this.isOpened=false;
this.input=$(input);
this.input.setAttribute("autocomplete", "off");
this.input.setAttribute("aria-autocomplete", "list");
o=o||{};
configure(this, {
minChars: 2,
maxItems: 10,
autoFirst: false,
data: _.DATA,
filter: _.FILTER_CONTAINS,
sort: _.SORT_BYLENGTH,
item: _.ITEM,
replace: _.REPLACE
}, o);
this.index=-1;
this.container=$.create("div", {
className: "awesomplete",
around: input
});
this.ul=$.create("ul", {
hidden: "hidden",
inside: this.container
});
this.status=$.create("span", {
className: "visually-hidden",
role: "status",
"aria-live": "assertive",
"aria-relevant": "additions",
inside: this.container
});
$.bind(this.input, {
"input": this.evaluate.bind(this),
"blur": this.close.bind(this, { reason: "blur" }),
"keydown": function(evt){
var c=evt.keyCode;
if(me.opened){
if(c===13&&me.selected){
evt.preventDefault();
me.select();
}
else if(c===27){
me.close({ reason: "esc" });
}
else if(c===38||c===40){
evt.preventDefault();
me[c===38? "previous":"next"]();
}}
}});
$.bind(this.input.form, {"submit": this.close.bind(this, { reason: "submit" })});
$.bind(this.ul, {"mousedown": function(evt){
var li=evt.target;
if(li!==this){
while (li&&!/li/i.test(li.nodeName)){
li=li.parentNode;
}
if(li&&evt.button===0){
evt.preventDefault();
me.select(li, evt.target);
}}
}});
if(this.input.hasAttribute("list")){
this.list="#" + this.input.getAttribute("list");
this.input.removeAttribute("list");
}else{
this.list=this.input.getAttribute("data-list")||o.list||[];
}
_.all.push(this);
};
_.prototype={
set list(list){
if(Array.isArray(list)){
this._list=list;
}
else if(typeof list==="string"&&list.indexOf(",") > -1){
this._list=list.split(/\s*,\s*/);
}else{
list=$(list);
if(list&&list.children){
var items=[];
slice.apply(list.children).forEach(function (el){
if(!el.disabled){
var text=el.textContent.trim();
var value=el.value||text;
var label=el.label||text;
if(value!==""){
items.push({ label: label, value: value });
}}
});
this._list=items;
}}
if(document.activeElement===this.input){
this.evaluate();
}},
get selected(){
return this.index > -1;
},
get opened(){
return this.isOpened;
},
close: function (o){
if(!this.opened){
return;
}
this.ul.setAttribute("hidden", "");
this.isOpened=false;
this.index=-1;
$.fire(this.input, "awesomplete-close", o||{});
},
open: function (){
this.ul.removeAttribute("hidden");
this.isOpened=true;
if(this.autoFirst&&this.index===-1){
this.goto(0);
}
$.fire(this.input, "awesomplete-open");
},
next: function (){
var count=this.ul.children.length;
this.goto(this.index < count - 1 ? this.index + 1:(count ? 0:-1));
},
previous: function (){
var count=this.ul.children.length;
var pos=this.index - 1;
this.goto(this.selected&&pos!==-1 ? pos:count - 1);
},
goto: function (i){
var lis=this.ul.children;
if(this.selected){
lis[this.index].setAttribute("aria-selected", "false");
}
this.index=i;
if(i > -1&&lis.length > 0){
lis[i].setAttribute("aria-selected", "true");
this.status.textContent=lis[i].textContent;
$.fire(this.input, "awesomplete-highlight", {
text: this.suggestions[this.index]
});
}},
select: function (selected, origin){
if(selected){
this.index=$.siblingIndex(selected);
}else{
selected=this.ul.children[this.index];
}
if(selected){
var suggestion=this.suggestions[this.index];
var allowed=$.fire(this.input, "awesomplete-select", {
text: suggestion,
origin: origin||selected
});
if(allowed){
this.replace(suggestion);
this.close({ reason: "select" });
$.fire(this.input, "awesomplete-selectcomplete", {
text: suggestion
});
}}
},
evaluate: function(){
var me=this;
var value=this.input.value;
if(value.length >=this.minChars&&this._list.length > 0){
this.index=-1;
this.ul.innerHTML="";
this.suggestions=this._list
.map(function(item){
return new Suggestion(me.data(item, value));
})
.filter(function(item){
return me.filter(item, value);
})
.sort(this.sort)
.slice(0, this.maxItems);
this.suggestions.forEach(function(text){
me.ul.appendChild(me.item(text, value));
});
if(this.ul.children.length===0){
this.close({ reason: "nomatches" });
}else{
this.open();
}}else{
this.close({ reason: "nomatches" });
}}
};
_.all=[];
_.FILTER_CONTAINS=function (text, input){
return RegExp($.regExpEscape(input.trim()), "i").test(text);
};
_.FILTER_STARTSWITH=function (text, input){
return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text);
};
_.SORT_BYLENGTH=function (a, b){
if(a.length!==b.length){
return a.length - b.length;
}
return a < b? -1:1;
};
_.ITEM=function (text, input){
var html=input.trim()==='' ? text:text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>");
return $.create("li", {
innerHTML: html,
"aria-selected": "false"
});
};
_.REPLACE=function (text){
this.input.value=text.value;
};
_.DATA=function (item){ return item; };
function Suggestion(data){
var o=Array.isArray(data)
? { label: data[0], value: data[1] }
: typeof data==="object"&&"label" in data&&"value" in data ? data:{ label: data, value: data };
this.label=o.label||o.value;
this.value=o.value;
}
Object.defineProperty(Suggestion.prototype=Object.create(String.prototype), "length", {
get: function(){ return this.label.length; }});
Suggestion.prototype.toString=Suggestion.prototype.valueOf=function (){
return "" + this.label;
};
function configure(instance, properties, o){
for (var i in properties){
var initial=properties[i],
attrValue=instance.input.getAttribute("data-" + i.toLowerCase());
if(typeof initial==="number"){
instance[i]=parseInt(attrValue);
}
else if(initial===false){
instance[i]=attrValue!==null;
}
else if(initial instanceof Function){
instance[i]=null;
}else{
instance[i]=attrValue;
}
if(!instance[i]&&instance[i]!==0){
instance[i]=(i in o)? o[i]:initial;
}}
}
var slice=Array.prototype.slice;
function $(expr, con){
return typeof expr==="string"? (con||document).querySelector(expr):expr||null;
}
function $$(expr, con){
return slice.call((con||document).querySelectorAll(expr));
}
$.create=function(tag, o){
var element=document.createElement(tag);
for (var i in o){
var val=o[i];
if(i==="inside"){
$(val).appendChild(element);
}
else if(i==="around"){
var ref=$(val);
ref.parentNode.insertBefore(element, ref);
element.appendChild(ref);
}
else if(i in element){
element[i]=val;
}else{
element.setAttribute(i, val);
}}
return element;
};
$.bind=function(element, o){
if(element){
for (var event in o){
var callback=o[event];
event.split(/\s+/).forEach(function (event){
element.addEventListener(event, callback);
});
}}
};
$.fire=function(target, type, properties){
var evt=document.createEvent("HTMLEvents");
evt.initEvent(type, true, true);
for (var j in properties){
evt[j]=properties[j];
}
return target.dispatchEvent(evt);
};
$.regExpEscape=function (s){
return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
};
$.siblingIndex=function (el){
for (var i=0; el=el.previousElementSibling; i++);
return i;
};
function init(){
$$("input.awesomplete").forEach(function (input){
new _(input);
});
}
if(typeof Document!=="undefined"){
if(document.readyState!=="loading"){
init();
}else{
document.addEventListener("DOMContentLoaded", init);
}}
_.$=$;
_.$$=$$;
if(typeof self!=="undefined"){
self.Awesomplete=_;
}
if(typeof module==="object"&&module.exports){
module.exports=_;
}
return _;
}());