1329 lines
128 KiB
JavaScript
1329 lines
128 KiB
JavaScript
|
|
||
|
var ApiGen = ApiGen || {};
|
||
|
ApiGen.config = {"require":{"min":"2.8.0"},"resources":{"resources":"resources"},"templates":{"common":{"overview.latte":"index.html","combined.js.latte":"resources\/combined.js","elementlist.js.latte":"elementlist.js","404.latte":"404.html"},"optional":{"sitemap":{"filename":"sitemap.xml","template":"sitemap.xml.latte"},"opensearch":{"filename":"opensearch.xml","template":"opensearch.xml.latte"},"robots":{"filename":"robots.txt","template":"robots.txt.latte"}},"main":{"package":{"filename":"package-%s.html","template":"package.latte"},"namespace":{"filename":"namespace-%s.html","template":"namespace.latte"},"class":{"filename":"class-%s.html","template":"class.latte"},"constant":{"filename":"constant-%s.html","template":"constant.latte"},"function":{"filename":"function-%s.html","template":"function.latte"},"source":{"filename":"source-%s.html","template":"source.latte"},"tree":{"filename":"tree.html","template":"tree.latte"},"deprecated":{"filename":"deprecated.html","template":"deprecated.latte"},"todo":{"filename":"todo.html","template":"todo.latte"}}},"options":{"elementDetailsCollapsed":true,"elementsOrder":"natural"},"config":"\/home\/greg\/MaxMind\/GeoIP2-php\/vendor\/apigen\/apigen\/templates\/default\/config.neon"};
|
||
|
|
||
|
|
||
|
/*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
|
||
|
*/
|
||
|
(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:fu
|
||
|
}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){retu
|
||
|
u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},
|
||
|
|
||
|
/*!
|
||
|
* jQuery Cookie Plugin v1.3.1
|
||
|
* https://github.com/carhartl/jquery-cookie
|
||
|
*
|
||
|
* Copyright 2013 Klaus Hartl
|
||
|
* Released under the MIT license
|
||
|
*/
|
||
|
(function ($, document, undefined) {
|
||
|
|
||
|
var pluses = /\+/g;
|
||
|
|
||
|
function raw(s) {
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
function decoded(s) {
|
||
|
return unRfc2068(decodeURIComponent(s.replace(pluses, ' ')));
|
||
|
}
|
||
|
|
||
|
function unRfc2068(value) {
|
||
|
if (value.indexOf('"') === 0) {
|
||
|
// This is a quoted cookie as according to RFC2068, unescape
|
||
|
value = value.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
function fromJSON(value) {
|
||
|
return config.json ? JSON.parse(value) : value;
|
||
|
}
|
||
|
|
||
|
var config = $.cookie = function (key, value, options) {
|
||
|
|
||
|
// write
|
||
|
if (value !== undefined) {
|
||
|
options = $.extend({}, config.defaults, options);
|
||
|
|
||
|
if (value === null) {
|
||
|
options.expires = -1;
|
||
|
}
|
||
|
|
||
|
if (typeof options.expires === 'number') {
|
||
|
var days = options.expires, t = options.expires = new Date();
|
||
|
t.setDate(t.getDate() + days);
|
||
|
}
|
||
|
|
||
|
value = config.json ? JSON.stringify(value) : String(value);
|
||
|
|
||
|
return (document.cookie = [
|
||
|
encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value),
|
||
|
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
|
||
|
options.path ? '; path=' + options.path : '',
|
||
|
options.domain ? '; domain=' + options.domain : '',
|
||
|
options.secure ? '; secure' : ''
|
||
|
].join(''));
|
||
|
}
|
||
|
|
||
|
// read
|
||
|
var decode = config.raw ? raw : decoded;
|
||
|
var cookies = document.cookie.split('; ');
|
||
|
var result = key ? null : {};
|
||
|
for (var i = 0, l = cookies.length; i < l; i++) {
|
||
|
var parts = cookies[i].split('=');
|
||
|
var name = decode(parts.shift());
|
||
|
var cookie = decode(parts.join('='));
|
||
|
|
||
|
if (key && key === name) {
|
||
|
result = fromJSON(cookie);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (!key) {
|
||
|
result[name] = fromJSON(cookie);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
config.defaults = {};
|
||
|
|
||
|
$.removeCookie = function (key, options) {
|
||
|
if ($.cookie(key) !== null) {
|
||
|
$.cookie(key, null, options);
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
})(jQuery, document);
|
||
|
|
||
|
/*!
|
||
|
* sprintf and vsprintf for jQuery
|
||
|
* somewhat based on http://jan.moesen.nu/code/javascript/sprintf-and-printf-in-javascript/
|
||
|
* Copyright (c) 2008 Sabin Iacob (m0n5t3r) <iacobs@m0n5t3r.info>
|
||
|
* @license http://www.gnu.org/licenses/gpl.html
|
||
|
* @project jquery.sprintf
|
||
|
*/
|
||
|
(function(d){var a={b:function(e){return parseInt(e,10).toString(2)},c:function(e){return String.fromCharCode(parseInt(e,10))},d:function(e){return parseInt(e,10)},u:function(e){return Math.abs(e)},f:function(f,e){e=parseInt(e,10);f=parseFloat(f);if(isNaN(e&&f)){return NaN}return e&&f.toFixed(e)||f},o:function(e){return parseInt(e,10).toString(8)},s:function(e){return e},x:function(e){return(""+parseInt(e,10).toString(16)).toLowerCase()},X:function(e){return(""+parseInt(e,10).toString(16)).toUpperCase()}};var c=/%(?:(\d+)?(?:\.(\d+))?|\(([^)]+)\))([%bcdufosxX])/g;var b=function(f){if(f.length==1&&typeof f[0]=="object"){f=f[0];return function(i,h,k,j,g,m,l){return a[g](f[j])}}else{var e=0;return function(i,h,k,j,g,m,l){if(g=="%"){return"%"}return a[g](f[e++],k)}}};d.extend({sprintf:function(f){var e=Array.apply(null,arguments).slice(1);return f.replace(c,b(e))},vsprintf:function(f,e){return f.replace(c,b(e))}})})(jQuery);
|
||
|
|
||
|
/*
|
||
|
* jQuery Autocomplete plugin 1.2.3
|
||
|
*
|
||
|
* 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
|
||
|
*
|
||
|
* With small modifications by Alfonso Gómez-Arzola.
|
||
|
* See changelog for details.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
;(function($) {
|
||
|
|
||
|
$.fn.extend({
|
||
|
autocomplete: function(urlOrData, options) {
|
||
|
var isUrl = typeof urlOrData == "string";
|
||
|
options = $.extend({}, $.Autocompleter.defaults, {
|
||
|
url: isUrl ? urlOrData : null,
|
||
|
data: isUrl ? null : urlOrData,
|
||
|
delay: isUrl ? $.Autocompleter.defaults.delay : 10,
|
||
|
max: options && !options.scroll ? 10 : 150,
|
||
|
noRecord: "No Records."
|
||
|
}, options);
|
||
|
|
||
|
// if highlight is set to false, replace it with a do-nothing function
|
||
|
options.highlight = options.highlight || function(value) { return value; };
|
||
|
|
||
|
// if the formatMatch option is not specified, then use formatItem for backwards compatibility
|
||
|
options.formatMatch = options.formatMatch || options.formatItem;
|
||
|
|
||
|
return this.each(function() {
|
||
|
new $.Autocompleter(this, options);
|
||
|
});
|
||
|
},
|
||
|
result: function(handler) {
|
||
|
return this.bind("result", handler);
|
||
|
},
|
||
|
search: function(handler) {
|
||
|
return this.trigger("search", [handler]);
|
||
|
},
|
||
|
flushCache: function() {
|
||
|
return this.trigger("flushCache");
|
||
|
},
|
||
|
setOptions: function(options){
|
||
|
return this.trigger("setOptions", [options]);
|
||
|
},
|
||
|
unautocomplete: function() {
|
||
|
return this.trigger("unautocomplete");
|
||
|
}
|
||
|
});
|
||
|
|
||
|
$.Autocompleter = function(input, options) {
|
||
|
|
||
|
var KEY = {
|
||
|
UP: 38,
|
||
|
DOWN: 40,
|
||
|
DEL: 46,
|
||
|
TAB: 9,
|
||
|
RETURN: 13,
|
||
|
ESC: 27,
|
||
|
COMMA: 188,
|
||
|
PAGEUP: 33,
|
||
|
PAGEDOWN: 34,
|
||
|
BACKSPACE: 8
|
||
|
};
|
||
|
|
||
|
var globalFailure = null;
|
||
|
if(options.failure != null && typeof options.failure == "function") {
|
||
|
globalFailure = options.failure;
|
||
|
}
|
||
|
|
||
|
// Create $ object for input element
|
||
|
var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
|
||
|
|
||
|
var timeout;
|
||
|
var previousValue = "";
|
||
|
var cache = $.Autocompleter.Cache(options);
|
||
|
var hasFocus = 0;
|
||
|
var lastKeyPressCode;
|
||
|
var config = {
|
||
|
mouseDownOnSelect: false
|
||
|
};
|
||
|
var select = $.Autocompleter.Select(options, input, selectCurrent, config);
|
||
|
|
||
|
var blockSubmit;
|
||
|
|
||
|
// prevent form submit in opera when selecting with return key
|
||
|
navigator.userAgent.indexOf("Opera") != -1 && $(input.form).bind("submit.autocomplete", function() {
|
||
|
if (blockSubmit) {
|
||
|
blockSubmit = false;
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// older versions of opera don't trigger keydown multiple times while pressed, others don't work with keypress at all
|
||
|
$input.bind((navigator.userAgent.indexOf("Opera") != -1 && !'KeyboardEvent' in window ? "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) {
|
||
|
|
||
|
case KEY.UP:
|
||
|
if ( select.visible() ) {
|
||
|
event.preventDefault();
|
||
|
select.prev();
|
||
|
} else {
|
||
|
onChange(0, true);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case KEY.DOWN:
|
||
|
if ( select.visible() ) {
|
||
|
event.preventDefault();
|
||
|
select.next();
|
||
|
} else {
|
||
|
onChange(0, true);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case KEY.PAGEUP:
|
||
|
if ( select.visible() ) {
|
||
|
event.preventDefault();
|
||
|
select.pageUp();
|
||
|
} else {
|
||
|
onChange(0, true);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case KEY.PAGEDOWN:
|
||
|
if ( select.visible() ) {
|
||
|
event.preventDefault();
|
||
|
select.pageDown();
|
||
|
} else {
|
||
|
onChange(0, true);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
// matches also semicolon
|
||
|
case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
|
||
|
case KEY.TAB:
|
||
|
case KEY.RETURN:
|
||
|
if( selectCurrent() ) {
|
||
|
// stop default to prevent a form submit, Opera needs special handling
|
||
|
event.preventDefault();
|
||
|
blockSubmit = true;
|
||
|
return false;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case KEY.ESC:
|
||
|
select.hide();
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
clearTimeout(timeout);
|
||
|
timeout = setTimeout(onChange, options.delay);
|
||
|
break;
|
||
|
}
|
||
|
}).focus(function(){
|
||
|
// track whether the field has focus, we shouldn't process any
|
||
|
// results if the field no longer has focus
|
||
|
hasFocus++;
|
||
|
}).blur(function() {
|
||
|
hasFocus = 0;
|
||
|
if (!config.mouseDownOnSelect) {
|
||
|
hideResults();
|
||
|
}
|
||
|
}).click(function() {
|
||
|
// show select when clicking in a focused field
|
||
|
// but if clickFire is true, don't require field
|
||
|
// to be focused to begin with; just show select
|
||
|
if( options.clickFire ) {
|
||
|
if ( !select.visible() ) {
|
||
|
onChange(0, true);
|
||
|
}
|
||
|
} else {
|
||
|
if ( hasFocus++ > 1 && !select.visible() ) {
|
||
|
onChange(0, true);
|
||
|
}
|
||
|
}
|
||
|
}).bind("search", function() {
|
||
|
// TODO why not just specifying both arguments?
|
||
|
var fn = (arguments.length > 1) ? arguments[1] : null;
|
||
|
function findValueCallback(q, data) {
|
||
|
var result;
|
||
|
if( data && data.length ) {
|
||
|
for (var i=0; i < data.length; i++) {
|
||
|
if( data[i].result.toLowerCase() == q.toLowerCase() ) {
|
||
|
result = data[i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if( typeof fn == "function" ) fn(result);
|
||
|
else $input.trigger("result", result && [result.data, result.value]);
|
||
|
}
|
||
|
$.each(trimWords($input.val()), function(i, value) {
|
||
|
request(value, findValueCallback, findValueCallback);
|
||
|
});
|
||
|
}).bind("flushCache", function() {
|
||
|
cache.flush();
|
||
|
}).bind("setOptions", function() {
|
||
|
$.extend(true, options, arguments[1]);
|
||
|
// if we've updated the data, repopulate
|
||
|
if ( "data" in arguments[1] )
|
||
|
cache.populate();
|
||
|
}).bind("unautocomplete", function() {
|
||
|
select.unbind();
|
||
|
$input.unbind();
|
||
|
$(input.form).unbind(".autocomplete");
|
||
|
});
|
||
|
|
||
|
|
||
|
function selectCurrent() {
|
||
|
var selected = select.selected();
|
||
|
if( !selected )
|
||
|
return false;
|
||
|
|
||
|
var v = selected.result;
|
||
|
previousValue = v;
|
||
|
|
||
|
if ( options.multiple ) {
|
||
|
var words = trimWords($input.val());
|
||
|
if ( words.length > 1 ) {
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
$input.val(v);
|
||
|
hideResultsNow();
|
||
|
$input.trigger("result", [selected.data, selected.value]);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function onChange(crap, skipPrevCheck) {
|
||
|
if( lastKeyPressCode == KEY.DEL ) {
|
||
|
select.hide();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var currentValue = $input.val();
|
||
|
|
||
|
if ( !skipPrevCheck && currentValue == previousValue )
|
||
|
return;
|
||
|
|
||
|
previousValue = currentValue;
|
||
|
|
||
|
currentValue = lastWord(currentValue);
|
||
|
if ( currentValue.length >= options.minChars) {
|
||
|
$input.addClass(options.loadingClass);
|
||
|
if (!options.matchCase)
|
||
|
currentValue = currentValue.toLowerCase();
|
||
|
request(currentValue, receiveData, hideResultsNow);
|
||
|
} else {
|
||
|
stopLoading();
|
||
|
select.hide();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function trimWords(value) {
|
||
|
if (!value)
|
||
|
return [""];
|
||
|
if (!options.multiple)
|
||
|
return [$.trim(value)];
|
||
|
return $.map(value.split(options.multipleSeparator), function(word) {
|
||
|
return $.trim(value).length ? $.trim(word) : null;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
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];
|
||
|
}
|
||
|
|
||
|
// fills in the input box w/the first match (assumed to be the best match)
|
||
|
// q: the term entered
|
||
|
// sValue: the first matching result
|
||
|
function autoFill(q, sValue){
|
||
|
// autofill in the complete box w/the first match as long as the user hasn't entered in more data
|
||
|
// if the last user key pressed was backspace, don't autofill
|
||
|
if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
|
||
|
// 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)
|
||
|
$(input).selection(previousValue.length, previousValue.length + sValue.length);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function hideResults() {
|
||
|
clearTimeout(timeout);
|
||
|
timeout = setTimeout(hideResultsNow, 200);
|
||
|
};
|
||
|
|
||
|
function hideResultsNow() {
|
||
|
var wasVisible = select.visible();
|
||
|
select.hide();
|
||
|
clearTimeout(timeout);
|
||
|
stopLoading();
|
||
|
if (options.mustMatch) {
|
||
|
// call search and run callback
|
||
|
$input.search(
|
||
|
function (result){
|
||
|
// if no value found, clear the input box
|
||
|
if( !result ) {
|
||
|
if (options.multiple) {
|
||
|
var words = trimWords($input.val()).slice(0, -1);
|
||
|
$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
|
||
|
}
|
||
|
else {
|
||
|
$input.val( "" );
|
||
|
$input.trigger("result", null);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function receiveData(q, data) {
|
||
|
if ( data && data.length && hasFocus ) {
|
||
|
stopLoading();
|
||
|
select.display(data, q);
|
||
|
autoFill(q, data[0].value);
|
||
|
select.show();
|
||
|
} else {
|
||
|
hideResultsNow();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function request(term, success, failure) {
|
||
|
if (!options.matchCase)
|
||
|
term = term.toLowerCase();
|
||
|
var data = cache.load(term);
|
||
|
// recieve the cached data
|
||
|
if (data) {
|
||
|
if(data.length) {
|
||
|
success(term, data);
|
||
|
}
|
||
|
else{
|
||
|
var parsed = options.parse && options.parse(options.noRecord) || parse(options.noRecord);
|
||
|
success(term,parsed);
|
||
|
}
|
||
|
// if an AJAX url has been supplied, try loading the data now
|
||
|
} else if( (typeof options.url == "string") && (options.url.length > 0) ){
|
||
|
|
||
|
var extraParams = {
|
||
|
timestamp: +new Date()
|
||
|
};
|
||
|
$.each(options.extraParams, function(key, param) {
|
||
|
extraParams[key] = typeof param == "function" ? param() : param;
|
||
|
});
|
||
|
|
||
|
$.ajax({
|
||
|
// try to leverage ajaxQueue plugin to abort previous requests
|
||
|
mode: "abort",
|
||
|
// limit abortion to this input
|
||
|
port: "autocomplete" + input.name,
|
||
|
dataType: options.dataType,
|
||
|
url: options.url,
|
||
|
data: $.extend({
|
||
|
q: lastWord(term),
|
||
|
limit: options.max
|
||
|
}, extraParams),
|
||
|
success: function(data) {
|
||
|
var parsed = options.parse && options.parse(data) || parse(data);
|
||
|
cache.add(term, parsed);
|
||
|
success(term, parsed);
|
||
|
}
|
||
|
});
|
||
|
} else {
|
||
|
// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
|
||
|
select.emptyList();
|
||
|
if(globalFailure != null) {
|
||
|
globalFailure();
|
||
|
}
|
||
|
else {
|
||
|
failure(term);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function parse(data) {
|
||
|
var parsed = [];
|
||
|
var rows = data.split("\n");
|
||
|
for (var i=0; i < rows.length; i++) {
|
||
|
var row = $.trim(rows[i]);
|
||
|
if (row) {
|
||
|
row = row.split("|");
|
||
|
parsed[parsed.length] = {
|
||
|
data: row,
|
||
|
value: row[0],
|
||
|
result: options.formatResult && options.formatResult(row, row[0]) || row[0]
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
return parsed;
|
||
|
};
|
||
|
|
||
|
function stopLoading() {
|
||
|
$input.removeClass(options.loadingClass);
|
||
|
};
|
||
|
|
||
|
};
|
||
|
|
||
|
$.Autocompleter.defaults = {
|
||
|
inputClass: "ac_input",
|
||
|
resultsClass: "ac_results",
|
||
|
loadingClass: "ac_loading",
|
||
|
minChars: 1,
|
||
|
delay: 400,
|
||
|
matchCase: false,
|
||
|
matchSubset: true,
|
||
|
matchContains: false,
|
||
|
cacheLength: 100,
|
||
|
max: 1000,
|
||
|
mustMatch: false,
|
||
|
extraParams: {},
|
||
|
selectFirst: true,
|
||
|
formatItem: function(row) { return row[0]; },
|
||
|
formatMatch: null,
|
||
|
autoFill: false,
|
||
|
width: 0,
|
||
|
multiple: false,
|
||
|
multipleSeparator: " ",
|
||
|
inputFocus: true,
|
||
|
clickFire: false,
|
||
|
highlight: function(value, term) {
|
||
|
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
|
||
|
},
|
||
|
scroll: true,
|
||
|
scrollHeight: 180,
|
||
|
scrollJumpPosition: true
|
||
|
};
|
||
|
|
||
|
$.Autocompleter.Cache = function(options) {
|
||
|
|
||
|
var data = {};
|
||
|
var length = 0;
|
||
|
|
||
|
function matchSubset(s, sub) {
|
||
|
return (new RegExp(sub.toUpperCase().replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1").replace(/[A-Z0-9]/g, function(m, offset) {
|
||
|
return offset === 0 ? '(?:' + m + '|^' + m.toLowerCase() + ')' : '(?:.*' + m + '|' + m.toLowerCase() + ')';
|
||
|
}))).test(s); // find by initials
|
||
|
};
|
||
|
|
||
|
function add(q, value) {
|
||
|
if (length > options.cacheLength){
|
||
|
flush();
|
||
|
}
|
||
|
if (!data[q]){
|
||
|
length++;
|
||
|
}
|
||
|
data[q] = value;
|
||
|
}
|
||
|
|
||
|
function populate(){
|
||
|
if( !options.data ) return false;
|
||
|
// track the matches
|
||
|
var stMatchSets = {},
|
||
|
nullData = 0;
|
||
|
|
||
|
// no url was specified, we need to adjust the cache length to make sure it fits the local data store
|
||
|
if( !options.url ) options.cacheLength = 1;
|
||
|
|
||
|
// track all options for minChars = 0
|
||
|
stMatchSets[""] = [];
|
||
|
|
||
|
// loop through the array and create a lookup structure
|
||
|
for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
|
||
|
var rawValue = options.data[i];
|
||
|
// if rawValue is a string, make an array otherwise just reference the array
|
||
|
rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
|
||
|
|
||
|
var value = options.formatMatch(rawValue, i+1, options.data.length);
|
||
|
if ( typeof(value) === 'undefined' || value === false )
|
||
|
continue;
|
||
|
|
||
|
var firstChar = value.charAt(0).toLowerCase();
|
||
|
// if no lookup array for this character exists, look it up now
|
||
|
if( !stMatchSets[firstChar] )
|
||
|
stMatchSets[firstChar] = [];
|
||
|
|
||
|
// if the match is a string
|
||
|
var row = {
|
||
|
value: value,
|
||
|
data: rawValue,
|
||
|
result: options.formatResult && options.formatResult(rawValue) || value
|
||
|
};
|
||
|
|
||
|
// push the current match into the set list
|
||
|
stMatchSets[firstChar].push(row);
|
||
|
|
||
|
// keep track of minChars zero items
|
||
|
if ( nullData++ < options.max ) {
|
||
|
stMatchSets[""].push(row);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// add the data items to the cache
|
||
|
$.each(stMatchSets, function(i, value) {
|
||
|
// increase the cache size
|
||
|
options.cacheLength++;
|
||
|
// add to the cache
|
||
|
add(i, value);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// populate any existing data
|
||
|
setTimeout(populate, 25);
|
||
|
|
||
|
function flush(){
|
||
|
data = {};
|
||
|
length = 0;
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
flush: flush,
|
||
|
add: add,
|
||
|
populate: populate,
|
||
|
load: function(q) {
|
||
|
if (!options.cacheLength || !length)
|
||
|
return null;
|
||
|
/*
|
||
|
* if dealing w/local data and matchContains than we must make sure
|
||
|
* to loop through all the data collections looking for matches
|
||
|
*/
|
||
|
if( !options.url && options.matchContains ){
|
||
|
// track all matches
|
||
|
var csub = [];
|
||
|
// loop through all the data grids for matches
|
||
|
for( var k in data ){
|
||
|
// don't search through the stMatchSets[""] (minChars: 0) cache
|
||
|
// this prevents duplicates
|
||
|
if( k.length > 0 ){
|
||
|
var c = data[k];
|
||
|
$.each(c, function(i, x) {
|
||
|
// if we've got a match, add it to the array
|
||
|
if (matchSubset(x.value, q)) {
|
||
|
csub.push(x);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
return csub;
|
||
|
} else
|
||
|
// if the exact item exists, use it
|
||
|
if (data[q]){
|
||
|
return data[q];
|
||
|
} else
|
||
|
if (options.matchSubset) {
|
||
|
for (var i = q.length - 1; i >= options.minChars; i--) {
|
||
|
var c = data[q.substr(0, i)];
|
||
|
if (c) {
|
||
|
var csub = [];
|
||
|
$.each(c, function(i, x) {
|
||
|
if (matchSubset(x.value, q)) {
|
||
|
csub[csub.length] = x;
|
||
|
}
|
||
|
});
|
||
|
return csub;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
|
||
|
$.Autocompleter.Select = function (options, input, select, config) {
|
||
|
var CLASSES = {
|
||
|
ACTIVE: "ac_over"
|
||
|
};
|
||
|
|
||
|
var listItems,
|
||
|
active = -1,
|
||
|
data,
|
||
|
term = "",
|
||
|
needsInit = true,
|
||
|
element,
|
||
|
list;
|
||
|
|
||
|
// Create results
|
||
|
function init() {
|
||
|
if (!needsInit)
|
||
|
return;
|
||
|
element = $("<div/>")
|
||
|
.hide()
|
||
|
.addClass(options.resultsClass)
|
||
|
.css("position", "absolute")
|
||
|
.appendTo(document.body)
|
||
|
.hover(function(event) {
|
||
|
// Browsers except FF do not fire mouseup event on scrollbars, resulting in mouseDownOnSelect remaining true, and results list not always hiding.
|
||
|
if($(this).is(":visible")) {
|
||
|
input.focus();
|
||
|
}
|
||
|
config.mouseDownOnSelect = false;
|
||
|
});
|
||
|
|
||
|
list = $("<ul/>").appendTo(element).mouseover( function(event) {
|
||
|
if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
|
||
|
active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
|
||
|
$(target(event)).addClass(CLASSES.ACTIVE);
|
||
|
}
|
||
|
}).click(function(event) {
|
||
|
$(target(event)).addClass(CLASSES.ACTIVE);
|
||
|
select();
|
||
|
if( options.inputFocus )
|
||
|
input.focus();
|
||
|
return false;
|
||
|
}).mousedown(function() {
|
||
|
config.mouseDownOnSelect = true;
|
||
|
}).mouseup(function() {
|
||
|
config.mouseDownOnSelect = false;
|
||
|
});
|
||
|
|
||
|
if( options.width > 0 )
|
||
|
element.css("width", options.width);
|
||
|
|
||
|
needsInit = false;
|
||
|
}
|
||
|
|
||
|
function target(event) {
|
||
|
var element = event.target;
|
||
|
while(element && element.tagName != "LI")
|
||
|
element = element.parentNode;
|
||
|
// more fun with IE, sometimes event.target is empty, just ignore it then
|
||
|
if(!element)
|
||
|
return [];
|
||
|
return element;
|
||
|
}
|
||
|
|
||
|
function moveSelect(step) {
|
||
|
listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
|
||
|
movePosition(step);
|
||
|
var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
|
||
|
if(options.scroll) {
|
||
|
var offset = 0;
|
||
|
listItems.slice(0, active).each(function() {
|
||
|
offset += this.offsetHeight;
|
||
|
});
|
||
|
if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
|
||
|
list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
|
||
|
} else if(offset < list.scrollTop()) {
|
||
|
list.scrollTop(offset);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function movePosition(step) {
|
||
|
if (options.scrollJumpPosition || (!options.scrollJumpPosition && !((step < 0 && active == 0) || (step > 0 && active == listItems.size() - 1)) )) {
|
||
|
active += step;
|
||
|
if (active < 0) {
|
||
|
active = listItems.size() - 1;
|
||
|
} else if (active >= listItems.size()) {
|
||
|
active = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
function limitNumberOfItems(available) {
|
||
|
return options.max && options.max < available
|
||
|
? options.max
|
||
|
: available;
|
||
|
}
|
||
|
|
||
|
function fillList() {
|
||
|
list.empty();
|
||
|
var max = limitNumberOfItems(data.length);
|
||
|
for (var i=0; i < max; i++) {
|
||
|
if (!data[i])
|
||
|
continue;
|
||
|
var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
|
||
|
if ( formatted === false )
|
||
|
continue;
|
||
|
var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
|
||
|
$.data(li, "ac_data", data[i]);
|
||
|
}
|
||
|
listItems = list.find("li");
|
||
|
if ( options.selectFirst ) {
|
||
|
listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
|
||
|
active = 0;
|
||
|
}
|
||
|
// apply bgiframe if available
|
||
|
if ( $.fn.bgiframe )
|
||
|
list.bgiframe();
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
display: function(d, q) {
|
||
|
init();
|
||
|
data = d;
|
||
|
term = q;
|
||
|
fillList();
|
||
|
},
|
||
|
next: function() {
|
||
|
moveSelect(1);
|
||
|
},
|
||
|
prev: function() {
|
||
|
moveSelect(-1);
|
||
|
},
|
||
|
pageUp: function() {
|
||
|
if (active != 0 && active - 8 < 0) {
|
||
|
moveSelect( -active );
|
||
|
} else {
|
||
|
moveSelect(-8);
|
||
|
}
|
||
|
},
|
||
|
pageDown: function() {
|
||
|
if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
|
||
|
moveSelect( listItems.size() - 1 - active );
|
||
|
} else {
|
||
|
moveSelect(8);
|
||
|
}
|
||
|
},
|
||
|
hide: function() {
|
||
|
element && element.hide();
|
||
|
listItems && listItems.removeClass(CLASSES.ACTIVE);
|
||
|
active = -1;
|
||
|
},
|
||
|
visible : function() {
|
||
|
return element && element.is(":visible");
|
||
|
},
|
||
|
current: function() {
|
||
|
return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
|
||
|
},
|
||
|
show: function() {
|
||
|
var offset = $(input).offset();
|
||
|
element.css({
|
||
|
width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
|
||
|
top: offset.top + input.offsetHeight,
|
||
|
left: offset.left
|
||
|
}).show();
|
||
|
if(options.scroll) {
|
||
|
list.scrollTop(0);
|
||
|
list.css({
|
||
|
maxHeight: options.scrollHeight,
|
||
|
overflow: 'auto'
|
||
|
});
|
||
|
|
||
|
if(navigator.userAgent.indexOf("MSIE") != -1 && typeof document.body.style.maxHeight === "undefined") {
|
||
|
var listHeight = 0;
|
||
|
listItems.each(function() {
|
||
|
listHeight += this.offsetHeight;
|
||
|
});
|
||
|
var scrollbarsVisible = listHeight > options.scrollHeight;
|
||
|
list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
|
||
|
if (!scrollbarsVisible) {
|
||
|
// IE doesn't recalculate width when scrollbar disappears
|
||
|
listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
},
|
||
|
selected: function() {
|
||
|
var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
|
||
|
return selected && selected.length && $.data(selected[0], "ac_data");
|
||
|
},
|
||
|
emptyList: function (){
|
||
|
list && list.empty();
|
||
|
},
|
||
|
unbind: function() {
|
||
|
element && element.remove();
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
|
||
|
$.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
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
})(jQuery);
|
||
|
|
||
|
/**
|
||
|
* jQuery.fn.sortElements
|
||
|
* --------------
|
||
|
* @author James Padolsey (http://james.padolsey.com)
|
||
|
* @version 0.11
|
||
|
* @updated 18-MAR-2010
|
||
|
* --------------
|
||
|
* @param Function comparator:
|
||
|
* Exactly the same behaviour as [1,2,3].sort(comparator)
|
||
|
*
|
||
|
* @param Function getSortable
|
||
|
* A function that should return the element that is
|
||
|
* to be sorted. The comparator will run on the
|
||
|
* current collection, but you may want the actual
|
||
|
* resulting sort to occur on a parent or another
|
||
|
* associated element.
|
||
|
*
|
||
|
* E.g. $('td').sortElements(comparator, function(){
|
||
|
* return this.parentNode;
|
||
|
* })
|
||
|
*
|
||
|
* The <td>'s parent (<tr>) will be sorted instead
|
||
|
* of the <td> itself.
|
||
|
*/
|
||
|
jQuery.fn.sortElements = (function(){
|
||
|
|
||
|
var sort = [].sort;
|
||
|
|
||
|
return function(comparator, getSortable) {
|
||
|
|
||
|
getSortable = getSortable || function(){return this;};
|
||
|
|
||
|
var placements = this.map(function(){
|
||
|
|
||
|
var sortElement = getSortable.call(this),
|
||
|
parentNode = sortElement.parentNode,
|
||
|
|
||
|
// Since the element itself will change position, we have
|
||
|
// to have some way of storing it's original position in
|
||
|
// the DOM. The easiest way is to have a 'flag' node:
|
||
|
nextSibling = parentNode.insertBefore(
|
||
|
document.createTextNode(''),
|
||
|
sortElement.nextSibling
|
||
|
);
|
||
|
|
||
|
return function() {
|
||
|
|
||
|
if (parentNode === this) {
|
||
|
throw new Error(
|
||
|
"You can't sort elements if any one is a descendant of another."
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// Insert before flag:
|
||
|
parentNode.insertBefore(this, nextSibling);
|
||
|
// Remove flag:
|
||
|
parentNode.removeChild(nextSibling);
|
||
|
|
||
|
};
|
||
|
|
||
|
});
|
||
|
|
||
|
return sort.call(this, comparator).each(function(i){
|
||
|
placements[i].call(getSortable.call(this));
|
||
|
});
|
||
|
|
||
|
};
|
||
|
|
||
|
})();
|
||
|
/*!
|
||
|
* ApiGen 2.8.0 - API documentation generator for PHP 5.3+
|
||
|
*
|
||
|
* Copyright (c) 2010-2011 David Grudl (http://davidgrudl.com)
|
||
|
* Copyright (c) 2011-2012 Jaroslav Hanslík (https://github.com/kukulich)
|
||
|
* Copyright (c) 2011-2012 Ondřej Nešpor (https://github.com/Andrewsville)
|
||
|
*
|
||
|
* For the full copyright and license information, please view
|
||
|
* the file LICENSE.md that was distributed with this source code.
|
||
|
*/
|
||
|
|
||
|
$(function() {
|
||
|
var $document = $(document);
|
||
|
var $left = $('#left');
|
||
|
var $right = $('#right');
|
||
|
var $rightInner = $('#rightInner');
|
||
|
var $splitter = $('#splitter');
|
||
|
var $groups = $('#groups');
|
||
|
var $content = $('#content');
|
||
|
|
||
|
// Menu
|
||
|
|
||
|
// Hide deep packages and namespaces
|
||
|
$('ul span', $groups).click(function(event) {
|
||
|
event.preventDefault();
|
||
|
event.stopPropagation();
|
||
|
$(this)
|
||
|
.toggleClass('collapsed')
|
||
|
.parent()
|
||
|
.next('ul')
|
||
|
.toggleClass('collapsed');
|
||
|
}).click();
|
||
|
|
||
|
$active = $('ul li.active', $groups);
|
||
|
if ($active.length > 0) {
|
||
|
// Open active
|
||
|
$('> a > span', $active).click();
|
||
|
} else {
|
||
|
$main = $('> ul > li.main', $groups);
|
||
|
if ($main.length > 0) {
|
||
|
// Open first level of the main project
|
||
|
$('> a > span', $main).click();
|
||
|
} else {
|
||
|
// Open first level of all
|
||
|
$('> ul > li > a > span', $groups).click();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Content
|
||
|
|
||
|
// Search autocompletion
|
||
|
var autocompleteFound = false;
|
||
|
var autocompleteFiles = {'c': 'class', 'co': 'constant', 'f': 'function', 'm': 'class', 'mm': 'class', 'p': 'class', 'mp': 'class', 'cc': 'class'};
|
||
|
var $search = $('#search input[name=q]');
|
||
|
$search
|
||
|
.autocomplete(ApiGen.elements, {
|
||
|
matchContains: true,
|
||
|
scrollHeight: 200,
|
||
|
max: 20,
|
||
|
noRecord: '',
|
||
|
highlight: function(value, term) {
|
||
|
var term = term.toUpperCase().replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1").replace(/[A-Z0-9]/g, function(m, offset) {
|
||
|
return offset === 0 ? '(?:' + m + '|^' + m.toLowerCase() + ')' : '(?:(?:[^<>]|<[^<>]*>)*' + m + '|' + m.toLowerCase() + ')';
|
||
|
});
|
||
|
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)"), "<strong>$1</strong>");
|
||
|
},
|
||
|
formatItem: function(data) {
|
||
|
return data.length > 1 ? data[1].replace(/^(.+\\)(.+)$/, '<span><small>$1</small>$2</span>') : data[0];
|
||
|
},
|
||
|
formatMatch: function(data) {
|
||
|
return data[1];
|
||
|
},
|
||
|
formatResult: function(data) {
|
||
|
return data[1];
|
||
|
},
|
||
|
show: function($list) {
|
||
|
var $items = $('li span', $list);
|
||
|
var maxWidth = Math.max.apply(null, $items.map(function() {
|
||
|
return $(this).width();
|
||
|
}));
|
||
|
// 10px padding
|
||
|
$list
|
||
|
.width(Math.max(maxWidth + 10, $search.innerWidth()))
|
||
|
.css('left', $search.offset().left + $search.outerWidth() - $list.outerWidth());
|
||
|
}
|
||
|
}).result(function(event, data) {
|
||
|
autocompleteFound = true;
|
||
|
var location = window.location.href.split('/');
|
||
|
location.pop();
|
||
|
var parts = data[1].split(/::|$/);
|
||
|
var file = $.sprintf(ApiGen.config.templates.main[autocompleteFiles[data[0]]].filename, parts[0].replace(/\(\)/, '').replace(/[^\w]/g, '.'));
|
||
|
if (parts[1]) {
|
||
|
file += '#' + ('mm' === data[0] || 'mp' === data[0] ? 'm' : '') + parts[1].replace(/([\w]+)\(\)/, '_$1');
|
||
|
}
|
||
|
location.push(file);
|
||
|
window.location = location.join('/');
|
||
|
|
||
|
// Workaround for Opera bug
|
||
|
$(this).closest('form').attr('action', location.join('/'));
|
||
|
}).closest('form')
|
||
|
.submit(function() {
|
||
|
var query = $search.val();
|
||
|
if ('' === query) {
|
||
|
return false;
|
||
|
}
|
||
|
return !autocompleteFound && '' !== $('#search input[name=cx]').val();
|
||
|
});
|
||
|
|
||
|
// Save natural order
|
||
|
$('table.summary tr[data-order]', $content).each(function(index) {
|
||
|
do {
|
||
|
index = '0' + index;
|
||
|
} while (index.length < 3);
|
||
|
$(this).attr('data-order-natural', index);
|
||
|
});
|
||
|
|
||
|
// Switch between natural and alphabetical order
|
||
|
var $caption = $('table.summary', $content)
|
||
|
.filter(':has(tr[data-order])')
|
||
|
.find('caption');
|
||
|
$caption
|
||
|
.click(function() {
|
||
|
var $this = $(this);
|
||
|
var order = $this.data('order') || 'natural';
|
||
|
order = 'natural' === order ? 'alphabetical' : 'natural';
|
||
|
$this.data('order', order);
|
||
|
$.cookie('order', order, {expires: 365});
|
||
|
var attr = 'alphabetical' === order ? 'data-order' : 'data-order-natural';
|
||
|
$this
|
||
|
.closest('table')
|
||
|
.find('tr').sortElements(function(a, b) {
|
||
|
return $(a).attr(attr) > $(b).attr(attr) ? 1 : -1;
|
||
|
});
|
||
|
return false;
|
||
|
})
|
||
|
.addClass('switchable')
|
||
|
.attr('title', 'Switch between natural and alphabetical order');
|
||
|
if ((null === $.cookie('order') && 'alphabetical' === ApiGen.config.options.elementsOrder) || 'alphabetical' === $.cookie('order')) {
|
||
|
$caption.click();
|
||
|
}
|
||
|
|
||
|
// Open details
|
||
|
if (ApiGen.config.options.elementDetailsCollapsed) {
|
||
|
$('tr', $content).filter(':has(.detailed)')
|
||
|
.click(function() {
|
||
|
var $this = $(this);
|
||
|
$('.short', $this).hide();
|
||
|
$('.detailed', $this).show();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Splitter
|
||
|
var splitterWidth = $splitter.width();
|
||
|
var splitterPosition = $.cookie('splitter') ? parseInt($.cookie('splitter')) : null;
|
||
|
var splitterPositionBackup = $.cookie('splitterBackup') ? parseInt($.cookie('splitterBackup')) : null;
|
||
|
function setSplitterPosition(position)
|
||
|
{
|
||
|
splitterPosition = position;
|
||
|
|
||
|
$left.width(position);
|
||
|
$right.css('margin-left', position + splitterWidth);
|
||
|
$splitter.css('left', position);
|
||
|
}
|
||
|
function setContentWidth()
|
||
|
{
|
||
|
var width = $rightInner.width();
|
||
|
$rightInner
|
||
|
.toggleClass('medium', width <= 960)
|
||
|
.toggleClass('small', width <= 650);
|
||
|
}
|
||
|
$splitter.mousedown(function() {
|
||
|
$splitter.addClass('active');
|
||
|
|
||
|
$document.mousemove(function(event) {
|
||
|
if (event.pageX >= 230 && $document.width() - event.pageX >= 600 + splitterWidth) {
|
||
|
setSplitterPosition(event.pageX);
|
||
|
setContentWidth();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
$()
|
||
|
.add($splitter)
|
||
|
.add($document)
|
||
|
.mouseup(function() {
|
||
|
$splitter
|
||
|
.removeClass('active')
|
||
|
.unbind('mouseup');
|
||
|
$document
|
||
|
.unbind('mousemove')
|
||
|
.unbind('mouseup');
|
||
|
|
||
|
$.cookie('splitter', splitterPosition, {expires: 365});
|
||
|
});
|
||
|
|
||
|
return false;
|
||
|
});
|
||
|
$splitter.dblclick(function() {
|
||
|
if (splitterPosition) {
|
||
|
splitterPositionBackup = $left.width();
|
||
|
setSplitterPosition(0);
|
||
|
} else {
|
||
|
setSplitterPosition(splitterPositionBackup);
|
||
|
splitterPositionBackup = null;
|
||
|
}
|
||
|
|
||
|
setContentWidth();
|
||
|
|
||
|
$.cookie('splitter', splitterPosition, {expires: 365});
|
||
|
$.cookie('splitterBackup', splitterPositionBackup, {expires: 365});
|
||
|
});
|
||
|
if (null !== splitterPosition) {
|
||
|
setSplitterPosition(splitterPosition);
|
||
|
}
|
||
|
setContentWidth();
|
||
|
$(window).resize(setContentWidth);
|
||
|
|
||
|
// Select selected lines
|
||
|
var matches = window.location.hash.substr(1).match(/^\d+(?:-\d+)?(?:,\d+(?:-\d+)?)*$/);
|
||
|
if (null !== matches) {
|
||
|
var lists = matches[0].split(',');
|
||
|
for (var i = 0; i < lists.length; i++) {
|
||
|
var lines = lists[i].split('-');
|
||
|
lines[0] = parseInt(lines[0]);
|
||
|
lines[1] = parseInt(lines[1] || lines[0]);
|
||
|
for (var j = lines[0]; j <= lines[1]; j++) {
|
||
|
$('#' + j).addClass('selected');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var $firstLine = $('#' + parseInt(matches[0]));
|
||
|
if ($firstLine.length > 0) {
|
||
|
$document.scrollTop($firstLine.offset().top);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Save selected lines
|
||
|
var lastLine;
|
||
|
$('a.l').click(function(event) {
|
||
|
event.preventDefault();
|
||
|
|
||
|
var $selectedLine = $(this).parent();
|
||
|
var selectedLine = parseInt($selectedLine.attr('id'));
|
||
|
|
||
|
if (event.shiftKey) {
|
||
|
if (lastLine) {
|
||
|
for (var i = Math.min(selectedLine, lastLine); i <= Math.max(selectedLine, lastLine); i++) {
|
||
|
$('#' + i).addClass('selected');
|
||
|
}
|
||
|
} else {
|
||
|
$selectedLine.addClass('selected');
|
||
|
}
|
||
|
} else if (event.ctrlKey) {
|
||
|
$selectedLine.toggleClass('selected');
|
||
|
} else {
|
||
|
var $selected = $('.l.selected')
|
||
|
.not($selectedLine)
|
||
|
.removeClass('selected');
|
||
|
if ($selected.length > 0) {
|
||
|
$selectedLine.addClass('selected');
|
||
|
} else {
|
||
|
$selectedLine.toggleClass('selected');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
lastLine = $selectedLine.hasClass('selected') ? selectedLine : null;
|
||
|
|
||
|
// Update hash
|
||
|
var lines = $('.l.selected')
|
||
|
.map(function() {
|
||
|
return parseInt($(this).attr('id'));
|
||
|
})
|
||
|
.get()
|
||
|
.sort(function(a, b) {
|
||
|
return a - b;
|
||
|
});
|
||
|
|
||
|
var hash = [];
|
||
|
var list = [];
|
||
|
for (var j = 0; j < lines.length; j++) {
|
||
|
if (0 === j && j + 1 === lines.length) {
|
||
|
hash.push(lines[j]);
|
||
|
} else if (0 === j) {
|
||
|
list[0] = lines[j];
|
||
|
} else if (lines[j - 1] + 1 !== lines[j] && j + 1 === lines.length) {
|
||
|
hash.push(list.join('-'));
|
||
|
hash.push(lines[j]);
|
||
|
} else if (lines[j - 1] + 1 !== lines[j]) {
|
||
|
hash.push(list.join('-'));
|
||
|
list = [lines[j]];
|
||
|
} else if (j + 1 === lines.length) {
|
||
|
list[1] = lines[j];
|
||
|
hash.push(list.join('-'));
|
||
|
} else {
|
||
|
list[1] = lines[j];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hash = hash.join(',');
|
||
|
$backup = $('#' + hash).removeAttr('id');
|
||
|
window.location.hash = hash;
|
||
|
$backup.attr('id', hash);
|
||
|
});
|
||
|
});
|
||
|
|