modularize oxui
|
@ -1 +1,2 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
build/js
|
||||||
|
|
4376
build/js/jquery-1.3.2.js
vendored
6078
build/js/jquery-1.4.1.js
vendored
152
build/js/jquery-1.4.1.min.js
vendored
|
@ -1,152 +0,0 @@
|
||||||
/*!
|
|
||||||
* jQuery JavaScript Library v1.4.1
|
|
||||||
* http://jquery.com/
|
|
||||||
*
|
|
||||||
* Copyright 2010, John Resig
|
|
||||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
||||||
* http://jquery.org/license
|
|
||||||
*
|
|
||||||
* Includes Sizzle.js
|
|
||||||
* http://sizzlejs.com/
|
|
||||||
* Copyright 2010, The Dojo Foundation
|
|
||||||
* Released under the MIT, BSD, and GPL Licenses.
|
|
||||||
*
|
|
||||||
* Date: Mon Jan 25 19:43:33 2010 -0500
|
|
||||||
*/
|
|
||||||
(function(z,v){function la(){if(!c.isReady){try{r.documentElement.doScroll("left")}catch(a){setTimeout(la,1);return}c.ready()}}function Ma(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var n in b)X(a,n,b[n],f,e,d);return a}if(d!==v){f=!i&&f&&c.isFunction(d);for(n=0;n<j;n++)e(a[n],b,f?d.call(a[n],n,e(a[n],b)):d,i);return a}return j?
|
|
||||||
e(a[0],b):null}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function ma(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function na(a){var b,d=[],f=[],e=arguments,i,j,n,o,m,s,x=c.extend({},c.data(this,"events").live);if(!(a.button&&a.type==="click")){for(o in x){j=x[o];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete x[o]}i=c(a.target).closest(f,
|
|
||||||
a.currentTarget);m=0;for(s=i.length;m<s;m++)for(o in x){j=x[o];n=i[m].elem;f=null;if(i[m].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==n)d.push({elem:n,fn:j})}}m=0;for(s=d.length;m<s;m++){i=d[m];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}}function oa(a,b){return"live."+(a?a+".":"")+b.replace(/\./g,"`").replace(/ /g,"&")}function pa(a){return!a||!a.parentNode||a.parentNode.nodeType===
|
|
||||||
11}function qa(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ra(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0&&(c.support.checkClone||!sa.test(a[0]))){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:r;f=b.createDocumentFragment();
|
|
||||||
c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=i?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(ta.concat.apply([],ta.slice(0,b)),function(){d[this]=a});return d}function ua(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Na=z.jQuery,Oa=z.$,r=z.document,S,Pa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Qa=/^.[^:#\[\.,]*$/,Ra=/\S/,Sa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Ta=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,O=navigator.userAgent,
|
|
||||||
va=false,P=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,Q=Array.prototype.slice,wa=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Pa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:r;if(a=Ta.exec(a))if(c.isPlainObject(b)){a=[r.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ra([d[1]],
|
|
||||||
[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=r.getElementById(d[2])){if(b.id!==d[2])return S.find(a);this.length=1;this[0]=b}this.context=r;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=r;a=r.getElementsByTagName(a)}else return!b||b.jquery?(b||S).find(a):c(b).find(a);else if(c.isFunction(a))return S.ready(a);if(a.selector!==v){this.selector=a.selector;this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,
|
|
||||||
this)},selector:"",jquery:"1.4.1",length:0,size:function(){return this.length},toArray:function(){return Q.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=0;ba.apply(this,a);return this},each:function(a,b){return c.each(this,
|
|
||||||
a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(r,c);else P&&P.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(Q.apply(this,arguments),"slice",Q.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};
|
|
||||||
c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,n;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];n=e[i];if(a!==n)if(f&&n&&(c.isPlainObject(n)||c.isArray(n))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(n)?[]:{};a[i]=c.extend(f,j,n)}else if(n!==v)a[i]=n}return a};c.extend({noConflict:function(a){z.$=
|
|
||||||
Oa;if(a)z.jQuery=Na;return c},isReady:false,ready:function(){if(!c.isReady){if(!r.body)return setTimeout(c.ready,13);c.isReady=true;if(P){for(var a,b=0;a=P[b++];)a.call(r,c);P=null}c.fn.triggerHandler&&c(r).triggerHandler("ready")}},bindReady:function(){if(!va){va=true;if(r.readyState==="complete")return c.ready();if(r.addEventListener){r.addEventListener("DOMContentLoaded",L,false);z.addEventListener("load",c.ready,false)}else if(r.attachEvent){r.attachEvent("onreadystatechange",L);z.attachEvent("onload",
|
|
||||||
c.ready);var a=false;try{a=z.frameElement==null}catch(b){}r.documentElement.doScroll&&a&&la()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===v||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;
|
|
||||||
return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return z.JSON&&z.JSON.parse?z.JSON.parse(a):(new Function("return "+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Ra.test(a)){var b=r.getElementsByTagName("head")[0]||
|
|
||||||
r.documentElement,d=r.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(r.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===v||c.isFunction(a);if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=
|
|
||||||
a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Sa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==
|
|
||||||
v;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=v}else if(b&&!c.isFunction(b)){d=b;b=v}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},
|
|
||||||
uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});O=c.uaMatch(O);if(O.browser){c.browser[O.browser]=true;c.browser.version=O.version}if(c.browser.webkit)c.browser.safari=true;if(wa)c.inArray=function(a,b){return wa.call(b,a)};S=c(r);if(r.addEventListener)L=function(){r.removeEventListener("DOMContentLoaded",
|
|
||||||
L,false);c.ready()};else if(r.attachEvent)L=function(){if(r.readyState==="complete"){r.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=r.documentElement,b=r.createElement("script"),d=r.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support=
|
|
||||||
{leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:r.createElement("select").appendChild(r.createElement("option")).selected,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};
|
|
||||||
b.type="text/javascript";try{b.appendChild(r.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,a.firstChild);if(z[f]){c.support.scriptEval=true;delete z[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function n(){c.support.noCloneEvent=false;d.detachEvent("onclick",n)});d.cloneNode(true).fireEvent("onclick")}d=r.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=r.createDocumentFragment();a.appendChild(d.firstChild);
|
|
||||||
c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var n=r.createElement("div");n.style.width=n.style.paddingLeft="1px";r.body.appendChild(n);c.boxModel=c.support.boxModel=n.offsetWidth===2;r.body.removeChild(n).style.display="none"});a=function(n){var o=r.createElement("div");n="on"+n;var m=n in o;if(!m){o.setAttribute(n,"return;");m=typeof o[n]==="function"}return m};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props=
|
|
||||||
{"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ua=0,xa={},Va={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var f=a[G],e=c.cache;if(!b&&!f)return null;f||(f=++Ua);if(typeof b==="object"){a[G]=f;e=e[f]=c.extend(true,
|
|
||||||
{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Va:(e[f]={});if(d!==v){a[G]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[G]}catch(i){a.removeAttribute&&a.removeAttribute(G)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,
|
|
||||||
a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===v){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===v&&this.length)f=c.data(this[0],a);return f===v&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);
|
|
||||||
return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===v)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||
|
|
||||||
a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var ya=/[\n\t]/g,ca=/\s+/,Wa=/\r/g,Xa=/href|src|style/,Ya=/(button|input)/i,Za=/(button|input|object|select|textarea)/i,$a=/^(a|area)$/i,za=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=
|
|
||||||
c(this);m.addClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,n=b.length;j<n;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=c(this);m.removeClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string"||a===v)for(var b=(a||"").split(ca),
|
|
||||||
d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(ya," "),j=0,n=b.length;j<n;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),n=b,o=
|
|
||||||
a.split(ca);e=o[i++];){n=f?n:!j.hasClass(e);j[n?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(ya," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===v){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||
|
|
||||||
{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(za.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Wa,"")}return v}var n=c.isFunction(a);return this.each(function(o){var m=c(this),s=a;if(this.nodeType===1){if(n)s=a.call(this,o,m.val());
|
|
||||||
if(typeof s==="number")s+="";if(c.isArray(s)&&za.test(this.type))this.checked=c.inArray(m.val(),s)>=0;else if(c.nodeName(this,"select")){var x=c.makeArray(s);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),x)>=0});if(!x.length)this.selectedIndex=-1}else this.value=s}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return v;if(f&&b in c.attrFn)return c(a)[b](d);
|
|
||||||
f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==v;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Xa.test(b);if(b in a&&f&&!i){if(e){b==="type"&&Ya.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Za.test(a.nodeName)||$a.test(a.nodeName)&&a.href?0:v;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=
|
|
||||||
""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?v:a}return c.style(a,b,d)}});var ab=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==z&&!a.frameElement)a=z;if(!d.guid)d.guid=c.guid++;if(f!==v){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=
|
|
||||||
function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):v};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var n,o=0;n=b[o++];){var m=n.split(".");n=m.shift();if(o>1){d=c.proxy(d);if(f!==v)d.data=f}d.type=m.slice(0).sort().join(".");var s=e[n],x=this.special[n]||{};if(!s){s=e[n]={};if(!x.setup||x.setup.call(a,f,m,d)===false)if(a.addEventListener)a.addEventListener(n,i,false);else a.attachEvent&&a.attachEvent("on"+n,i)}if(x.add)if((m=x.add.call(a,
|
|
||||||
d,f,m,s))&&c.isFunction(m)){m.guid=m.guid||d.guid;m.data=m.data||d.data;m.type=m.type||d.type;d=m}s[d.guid]=d;this.global[n]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===v||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);for(var n=0;i=b[n++];){var o=i.split(".");i=o.shift();var m=!o.length,s=c.map(o.slice(0).sort(),ab);s=new RegExp("(^|\\.)"+
|
|
||||||
s.join("\\.(?:.*\\.)?")+"(\\.|$)");var x=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var A in f[i])if(m||s.test(f[i][A].type))delete f[i][A];x.remove&&x.remove.call(a,o,j);for(e in f[i])break;if(!e){if(!x.teardown||x.teardown.call(a,o)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(A=c.data(a,"handle"))A.elem=null;c.removeData(a,
|
|
||||||
"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return v;a.result=v;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,
|
|
||||||
b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(i){}if(!a.isPropagationStopped()&&f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){d=a.target;var j;if(!(c.nodeName(d,"a")&&e==="click")&&!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){try{if(d[e]){if(j=d["on"+e])d["on"+e]=null;this.triggered=true;d[e]()}}catch(n){}if(j)d["on"+e]=j;this.triggered=false}}},handle:function(a){var b,
|
|
||||||
d;a=arguments[0]=c.event.fix(a||z.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==v){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
|
|
||||||
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||r;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=r.documentElement;d=r.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
|
|
||||||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==v)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;b.liveProxy=a;c.event.add(this,b.live,na,b)},remove:function(a){if(a.length){var b=
|
|
||||||
0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],na)}},special:{}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};
|
|
||||||
c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y};var Aa=function(a){for(var b=
|
|
||||||
a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ba=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ba:Aa,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ba:Aa)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!==
|
|
||||||
"form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return ma("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return ma("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,
|
|
||||||
"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var da=/textarea|input|select/i;function Ca(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ea(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Ca(d);if(a.type!=="focusout"||
|
|
||||||
d.type!=="radio")c.data(d,"_change_data",e);if(!(f===v||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}}c.event.special.change={filters:{focusout:ea,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ea.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ea.call(this,a)},beforeactivate:function(a){a=
|
|
||||||
a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Ca(a))}},setup:function(a,b,d){for(var f in T)c.event.add(this,f+".specialChange."+d.guid,T[f]);return da.test(this.nodeName)},remove:function(a,b){for(var d in T)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),T[d]);return da.test(this.nodeName)}};var T=c.event.special.change.filters}r.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,
|
|
||||||
f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){e=f;f=v}var j=b==="one"?c.proxy(e,function(n){c(this).unbind(n,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,
|
|
||||||
b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+
|
|
||||||
a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e){var i,j=0;if(c.isFunction(f)){e=f;f=v}for(d=(d||"").split(/\s+/);(i=d[j++])!=null;){i=i==="focus"?"focusin":i==="blur"?"focusout":i==="hover"?d.push("mouseleave")&&"mouseenter":i;b==="live"?c(this.context).bind(oa(i,this.selector),{data:f,selector:this.selector,
|
|
||||||
live:i},e):c(this.context).unbind(oa(i,this.selector),e?{guid:e.guid+this.selector+i}:null)}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});z.attachEvent&&!z.addEventListener&&z.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});
|
|
||||||
(function(){function a(g){for(var h="",k,l=0;g[l];l++){k=g[l];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===k){y=l[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=k;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}l[q]=y}}}function d(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===
|
|
||||||
k){y=l[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=k;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(o.filter(h,[t]).length>0){y=t;break}}t=t[g]}l[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,i=Object.prototype.toString,j=false,n=true;[0,0].sort(function(){n=false;return 0});var o=function(g,h,k,l){k=k||[];var q=h=h||r;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||
|
|
||||||
typeof g!=="string")return k;for(var p=[],u,t,y,R,H=true,M=w(h),I=g;(f.exec(""),u=f.exec(I))!==null;){I=u[3];p.push(u[1]);if(u[2]){R=u[3];break}}if(p.length>1&&s.exec(g))if(p.length===2&&m.relative[p[0]])t=fa(p[0]+p[1],h);else for(t=m.relative[p[0]]?[h]:o(p.shift(),h);p.length;){g=p.shift();if(m.relative[g])g+=p.shift();t=fa(g,t)}else{if(!l&&p.length>1&&h.nodeType===9&&!M&&m.match.ID.test(p[0])&&!m.match.ID.test(p[p.length-1])){u=o.find(p.shift(),h,M);h=u.expr?o.filter(u.expr,u.set)[0]:u.set[0]}if(h){u=
|
|
||||||
l?{expr:p.pop(),set:A(l)}:o.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=u.expr?o.filter(u.expr,u.set):u.set;if(p.length>0)y=A(t);else H=false;for(;p.length;){var D=p.pop();u=D;if(m.relative[D])u=p.pop();else D="";if(u==null)u=h;m.relative[D](y,u,M)}}else y=[]}y||(y=t);y||o.error(D||g);if(i.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))k.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&
|
|
||||||
y[g].nodeType===1&&k.push(t[g]);else k.push.apply(k,y);else A(y,k);if(R){o(R,q,k,l);o.uniqueSort(k)}return k};o.uniqueSort=function(g){if(C){j=n;g.sort(C);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};o.matches=function(g,h){return o(g,null,null,h)};o.find=function(g,h,k){var l,q;if(!g)return[];for(var p=0,u=m.order.length;p<u;p++){var t=m.order[p];if(q=m.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");l=m.find[t](q,
|
|
||||||
h,k);if(l!=null){g=g.replace(m.match[t],"");break}}}}l||(l=h.getElementsByTagName("*"));return{set:l,expr:g}};o.filter=function(g,h,k,l){for(var q=g,p=[],u=h,t,y,R=h&&h[0]&&w(h[0]);g&&h.length;){for(var H in m.filter)if((t=m.leftMatch[H].exec(g))!=null&&t[2]){var M=m.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(u===p)p=[];if(m.preFilter[H])if(t=m.preFilter[H](t,u,k,p,l,R)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=u[U])!=null;U++)if(D){I=M(D,t,U,u);var Da=
|
|
||||||
l^!!I;if(k&&I!=null)if(Da)y=true;else u[U]=false;else if(Da){p.push(D);y=true}}if(I!==v){k||(u=p);g=g.replace(m.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)o.error(g);else break;q=g}return u};o.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var m=o.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
|
|
||||||
TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,h){var k=typeof h==="string",l=k&&!/\W/.test(h);k=k&&!l;if(l)h=h.toLowerCase();l=0;for(var q=g.length,
|
|
||||||
p;l<q;l++)if(p=g[l]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[l]=k||p&&p.nodeName.toLowerCase()===h?p||false:p===h}k&&o.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var l=0,q=g.length;l<q;l++){var p=g[l];if(p){k=p.parentNode;g[l]=k.nodeName.toLowerCase()===h?k:false}}}else{l=0;for(q=g.length;l<q;l++)if(p=g[l])g[l]=k?p.parentNode:p.parentNode===h;k&&o.filter(h,g,true)}},"":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=
|
|
||||||
h=h.toLowerCase();q=b}q("parentNode",h,l,g,p,k)},"~":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,l,g,p,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];h=h.getElementsByName(g[1]);for(var l=0,q=h.length;l<q;l++)h[l].getAttribute("name")===g[1]&&k.push(h[l]);return k.length===0?null:k}},
|
|
||||||
TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,l,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var u;(u=h[p])!=null;p++)if(u)if(q^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||l.push(u);else if(k)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&
|
|
||||||
"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,l,q,p){h=g[1].replace(/\\/g,"");if(!p&&m.attrMap[h])g[1]=m.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,l,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=o(g[3],null,null,h);else{g=o.filter(g[3],h,k,true^q);k||l.push.apply(l,g);return false}else if(m.match.POS.test(g[0])||m.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);
|
|
||||||
return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!o(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===
|
|
||||||
g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,h){return h===0},last:function(g,h,k,l){return h===l.length-1},even:function(g,h){return h%2===
|
|
||||||
0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,l){var q=h[1],p=m.filters[q];if(p)return p(g,k,h,l);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=h[3];k=0;for(l=h.length;k<l;k++)if(h[k]===g)return false;return true}else o.error("Syntax error, unrecognized expression: "+
|
|
||||||
q)},CHILD:function(g,h){var k=h[1],l=g;switch(k){case "only":case "first":for(;l=l.previousSibling;)if(l.nodeType===1)return false;if(k==="first")return true;l=g;case "last":for(;l=l.nextSibling;)if(l.nodeType===1)return false;return true;case "nth":k=h[2];var q=h[3];if(k===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var u=0;for(l=p.firstChild;l;l=l.nextSibling)if(l.nodeType===1)l.nodeIndex=++u;p.sizcache=h}g=g.nodeIndex-q;return k===0?g===0:g%k===0&&g/k>=
|
|
||||||
0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=m.attrHandle[k]?m.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var l=h[2];h=h[4];return g==null?l==="!=":l==="="?k===h:l==="*="?k.indexOf(h)>=0:l==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:l==="!="?k!==h:l==="^="?
|
|
||||||
k.indexOf(h)===0:l==="$="?k.substr(k.length-h.length)===h:l==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,l){var q=m.setFilters[h[2]];if(q)return q(g,k,h,l)}}},s=m.match.POS;for(var x in m.match){m.match[x]=new RegExp(m.match[x].source+/(?![^\[]*\])(?![^\(]*\))/.source);m.leftMatch[x]=new RegExp(/(^(?:.|\r|\n)*?)/.source+m.match[x].source.replace(/\\(\d+)/g,function(g,h){return"\\"+(h-0+1)}))}var A=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};
|
|
||||||
try{Array.prototype.slice.call(r.documentElement.childNodes,0)}catch(B){A=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,l=g.length;k<l;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var C;if(r.documentElement.compareDocumentPosition)C=function(g,h){if(!g.compareDocumentPosition||!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===
|
|
||||||
h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in r.documentElement)C=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(r.createRange)C=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),l=h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);l.setStart(h,0);l.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,
|
|
||||||
l);if(g===0)j=true;return g};(function(){var g=r.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=r.documentElement;k.insertBefore(g,k.firstChild);if(r.getElementById(h)){m.find.ID=function(l,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(l[1]))?q.id===l[1]||typeof q.getAttributeNode!=="undefined"&&q.getAttributeNode("id").nodeValue===l[1]?[q]:v:[]};m.filter.ID=function(l,q){var p=typeof l.getAttributeNode!=="undefined"&&l.getAttributeNode("id");
|
|
||||||
return l.nodeType===1&&p&&p.nodeValue===q}}k.removeChild(g);k=g=null})();(function(){var g=r.createElement("div");g.appendChild(r.createComment(""));if(g.getElementsByTagName("*").length>0)m.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var l=0;k[l];l++)k[l].nodeType===1&&h.push(k[l]);k=h}return k};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")m.attrHandle.href=function(h){return h.getAttribute("href",
|
|
||||||
2)};g=null})();r.querySelectorAll&&function(){var g=o,h=r.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){o=function(l,q,p,u){q=q||r;if(!u&&q.nodeType===9&&!w(q))try{return A(q.querySelectorAll(l),p)}catch(t){}return g(l,q,p,u)};for(var k in g)o[k]=g[k];h=null}}();(function(){var g=r.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===
|
|
||||||
0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){m.order.splice(1,0,"CLASS");m.find.CLASS=function(h,k,l){if(typeof k.getElementsByClassName!=="undefined"&&!l)return k.getElementsByClassName(h[1])};g=null}}})();var E=r.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,h){return g!==h&&(g.contains?g.contains(h):true)},w=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},fa=function(g,h){var k=[],
|
|
||||||
l="",q;for(h=h.nodeType?[h]:h;q=m.match.PSEUDO.exec(g);){l+=q[0];g=g.replace(m.match.PSEUDO,"")}g=m.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)o(g,h[q],k);return o.filter(l,k)};c.find=o;c.expr=o.selectors;c.expr[":"]=c.expr.filters;c.unique=o.uniqueSort;c.getText=a;c.isXMLDoc=w;c.contains=E})();var bb=/Until$/,cb=/^(?:parents|prevUntil|prevAll)/,db=/,/;Q=Array.prototype.slice;var Ea=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,
|
|
||||||
function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Qa.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=
|
|
||||||
0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ea(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ea(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i={},j;if(f&&a.length){e=0;for(var n=a.length;e<n;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>
|
|
||||||
-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var o=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(m,s){for(;s&&s.ownerDocument&&s!==b;){if(o?o.index(s)>-1:c(s).is(a))return s;s=s.parentNode}return null})},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),
|
|
||||||
a);return this.pushStack(pa(a[0])||pa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},
|
|
||||||
nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);bb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):
|
|
||||||
e;if((this.length>1||db.test(f))&&cb.test(a))e=e.reverse();return this.pushStack(e,a,Q.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===v||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==
|
|
||||||
b&&d.push(a);return d}});var Fa=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ga=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,sa=/checked\s*(?:[^=]|=\s*.checked.)/i,Ia=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],
|
|
||||||
col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==v)return this.empty().append((this[0]&&this[0].ownerDocument||r).createTextNode(a));return c.getText(this)},
|
|
||||||
wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?
|
|
||||||
d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,
|
|
||||||
false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&
|
|
||||||
!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Fa,"").replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){qa(this,b);qa(this.find("*"),b.find("*"))}return b},html:function(a){if(a===v)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Fa,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(Ha.exec(a)||
|
|
||||||
["",""])[1].toLowerCase()]){a=a.replace(Ga,Ia);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,
|
|
||||||
b,f))});else a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(s){return c.nodeName(s,"table")?s.getElementsByTagName("tbody")[0]||s.appendChild(s.ownerDocument.createElement("tbody")):s}var e,i,j=a[0],n=[];if(!c.support.checkClone&&arguments.length===3&&typeof j===
|
|
||||||
"string"&&sa.test(j))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(j))return this.each(function(s){var x=c(this);a[0]=j.call(this,s,b?x.html():v);x.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ra(a,this,n);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var o=0,m=this.length;o<m;o++)d.call(b?f(this[o],i):this[o],e.cacheable||this.length>1||o>0?e.fragment.cloneNode(true):e.fragment)}n&&c.each(n,
|
|
||||||
Ma)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){c.cleanData(this.getElementsByTagName("*"));c.cleanData([this])}this.parentNode&&
|
|
||||||
this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&c.cleanData(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||r;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||r;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j===
|
|
||||||
"string"){j=j.replace(Ga,Ia);var n=(Ha.exec(j)||["",""])[1].toLowerCase(),o=F[n]||F._default,m=o[0];i=b.createElement("div");for(i.innerHTML=o[1]+j+o[2];m--;)i=i.lastChild;if(!c.support.tbody){m=fb.test(j);n=n==="table"&&!m?i.firstChild&&i.firstChild.childNodes:o[1]==="<table>"&&!m?i.childNodes:[];for(o=n.length-1;o>=0;--o)c.nodeName(n[o],"tbody")&&!n[o].childNodes.length&&n[o].parentNode.removeChild(n[o])}!c.support.leadingWhitespace&&V.test(j)&&i.insertBefore(b.createTextNode(V.exec(j)[0]),i.firstChild);
|
|
||||||
j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()==="text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e},cleanData:function(a){for(var b=0,d;(d=a[b])!=null;b++){c.event.remove(d);c.removeData(d)}}});var hb=/z-?index|font-?weight|opacity|zoom|line-?height/i,
|
|
||||||
Ja=/alpha\([^)]*\)/,Ka=/opacity=([^)]*)/,ga=/float/i,ha=/-([a-z])/ig,ib=/([A-Z])/g,jb=/^-?\d+(?:px)?$/i,kb=/^-?\d/,lb={position:"absolute",visibility:"hidden",display:"block"},mb=["Left","Right"],nb=["Top","Bottom"],ob=r.defaultView&&r.defaultView.getComputedStyle,La=c.support.cssFloat?"cssFloat":"styleFloat",ia=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===v)return c.curCSS(d,f);if(typeof e==="number"&&!hb.test(f))e+="px";c.style(d,f,e)})};
|
|
||||||
c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return v;if((b==="width"||b==="height")&&parseFloat(d)<0)d=v;var f=a.style||a,e=d!==v;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ja.test(a)?a.replace(Ja,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ka.exec(f.filter)[1])/100+"":""}if(ga.test(b))b=La;b=b.replace(ha,ia);if(e)f[b]=d;return f[b]},css:function(a,
|
|
||||||
b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?mb:nb;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,lb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&
|
|
||||||
a.currentStyle){f=Ka.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ga.test(b))b=La;if(!d&&e&&e[b])f=e[b];else if(ob){if(ga.test(b))b="float";b=b.replace(ib,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ha,ia);f=a.currentStyle[b]||a.currentStyle[d];if(!jb.test(f)&&kb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=
|
|
||||||
a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var pb=
|
|
||||||
J(),qb=/<script(.|\s)*?\/script>/gi,rb=/select|textarea/i,sb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ja=/\?/,tb=/(\?|&)_=.*?(&|$)/,ub=/^(\w+:)?\/\/([^\/?#]+)/,vb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=
|
|
||||||
c.param(b,c.ajaxSettings.traditional);f="POST"}var i=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(j,n){if(n==="success"||n==="notmodified")i.html(e?c("<div />").append(j.responseText.replace(qb,"")).find(e):j.responseText);d&&i.each(d,[j.responseText,n,j])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&
|
|
||||||
(this.checked||rb.test(this.nodeName)||sb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,
|
|
||||||
b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:z.XMLHttpRequest&&(z.location.protocol!=="file:"||!z.ActiveXObject)?function(){return new z.XMLHttpRequest}:
|
|
||||||
function(){try{return new z.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(o,n,j,w);e.global&&f("ajaxSuccess",[w,e])}function d(){e.complete&&e.complete.call(o,w,j);e.global&&f("ajaxComplete",[w,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}
|
|
||||||
function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,n,o=a&&a.context||e,m=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(m==="GET")N.test(e.url)||(e.url+=(ja.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||
|
|
||||||
N.test(e.url))){i=e.jsonpCallback||"jsonp"+pb++;if(e.data)e.data=(e.data+"").replace(N,"="+i+"$1");e.url=e.url.replace(N,"="+i+"$1");e.dataType="script";z[i]=z[i]||function(q){n=q;b();d();z[i]=v;try{delete z[i]}catch(p){}A&&A.removeChild(B)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&m==="GET"){var s=J(),x=e.url.replace(tb,"$1_="+s+"$2");e.url=x+(x===e.url?(ja.test(e.url)?"&":"?")+"_="+s:"")}if(e.data&&m==="GET")e.url+=(ja.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&
|
|
||||||
c.event.trigger("ajaxStart");s=(s=ub.exec(e.url))&&(s[1]&&s[1]!==location.protocol||s[2]!==location.host);if(e.dataType==="script"&&m==="GET"&&s){var A=r.getElementsByTagName("head")[0]||r.documentElement,B=r.createElement("script");B.src=e.url;if(e.scriptCharset)B.charset=e.scriptCharset;if(!i){var C=false;B.onload=B.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;b();d();B.onload=B.onreadystatechange=null;A&&B.parentNode&&
|
|
||||||
A.removeChild(B)}}}A.insertBefore(B,A.firstChild);return v}var E=false,w=e.xhr();if(w){e.username?w.open(m,e.url,e.async,e.username,e.password):w.open(m,e.url,e.async);try{if(e.data||a&&a.contentType)w.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&w.setRequestHeader("If-None-Match",c.etag[e.url])}s||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",
|
|
||||||
e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(fa){}if(e.beforeSend&&e.beforeSend.call(o,w,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");w.abort();return false}e.global&&f("ajaxSend",[w,e]);var g=w.onreadystatechange=function(q){if(!w||w.readyState===0||q==="abort"){E||d();E=true;if(w)w.onreadystatechange=c.noop}else if(!E&&w&&(w.readyState===4||q==="timeout")){E=true;w.onreadystatechange=c.noop;j=q==="timeout"?"timeout":!c.httpSuccess(w)?
|
|
||||||
"error":e.ifModified&&c.httpNotModified(w,e.url)?"notmodified":"success";var p;if(j==="success")try{n=c.httpData(w,e.dataType,e)}catch(u){j="parsererror";p=u}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,w,j,p);d();q==="timeout"&&w.abort();if(e.async)w=null}};try{var h=w.abort;w.abort=function(){w&&h.call(w);g("abort")}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){w&&!E&&g("timeout")},e.timeout);try{w.send(m==="POST"||m==="PUT"||m==="DELETE"?e.data:null)}catch(l){c.handleError(e,
|
|
||||||
w,null,l);d()}e.async||g();return w}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=
|
|
||||||
f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(j,n){if(c.isArray(n))c.each(n,
|
|
||||||
function(o,m){b?f(j,m):d(j+"["+(typeof m==="object"||c.isArray(m)?o:"")+"]",m)});else!b&&n!=null&&typeof n==="object"?c.each(n,function(o,m){d(j+"["+o+"]",m)}):f(j,n)}function f(j,n){n=c.isFunction(n)?n():n;e[e.length]=encodeURIComponent(j)+"="+encodeURIComponent(n)}var e=[];if(b===v)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var i in a)d(i,a[i]);return e.join("&").replace(vb,"+")}});var ka={},wb=/toggle|show|hide/,xb=/^([+-]=)?([\d+-.]+)(.*)$/,
|
|
||||||
W,ta=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(ka[d])f=ka[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
|
|
||||||
ka[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
|
|
||||||
c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,n=this.nodeType===1&&c(this).is(":hidden"),
|
|
||||||
o=this;for(j in a){var m=j.replace(ha,ia);if(j!==m){a[m]=a[j];delete a[j];j=m}if(a[j]==="hide"&&n||a[j]==="show"&&!n)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(s,x){var A=new c.fx(o,i,s);if(wb.test(x))A[x==="toggle"?n?"show":"hide":x](a);
|
|
||||||
else{var B=xb.exec(x),C=A.cur(true)||0;if(B){x=parseFloat(B[2]);var E=B[3]||"px";if(E!=="px"){o.style[s]=(x||1)+E;C=(x||1)/A.cur(true)*C;o.style[s]=C+E}if(B[1])x=(B[1]==="-="?-1:1)*x+C;A.custom(C,x,E)}else A.custom(C,x,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",
|
|
||||||
1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
|
|
||||||
b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
|
|
||||||
null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
|
|
||||||
"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
|
|
||||||
this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
|
|
||||||
c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
|
|
||||||
null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in r.documentElement?function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
|
|
||||||
f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(s){c.offset.setOffset(this,a,s)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
|
|
||||||
b,e=b.ownerDocument,i,j=e.documentElement,n=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var o=b.offsetTop,m=b.offsetLeft;(b=b.parentNode)&&b!==n&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;o-=b.scrollTop;m-=b.scrollLeft;if(b===d){o+=b.offsetTop;m+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){o+=parseFloat(i.borderTopWidth)||
|
|
||||||
0;m+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){o+=parseFloat(i.borderTopWidth)||0;m+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){o+=n.offsetTop;m+=n.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){o+=Math.max(j.scrollTop,n.scrollTop);m+=Math.max(j.scrollLeft,n.scrollLeft)}return{top:o,left:m}};c.offset={initialize:function(){var a=r.body,b=r.createElement("div"),
|
|
||||||
d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
|
|
||||||
d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
|
|
||||||
bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
|
|
||||||
e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
|
|
||||||
this.offsetParent||r.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==v)return this.each(function(){if(i=ua(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=ua(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
|
|
||||||
c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(i){var j=c(this);j[d](f.call(this,i,j[d]()))});return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||
|
|
||||||
e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===v?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});z.jQuery=z.$=c})(window);
|
|
6240
build/js/jquery-1.4.2.js
vendored
5999
build/js/jquery-1.4.js
vendored
151
build/js/jquery-1.4.min.js
vendored
|
@ -1,151 +0,0 @@
|
||||||
/*!
|
|
||||||
* jQuery JavaScript Library v1.4
|
|
||||||
* http://jquery.com/
|
|
||||||
*
|
|
||||||
* Copyright 2010, John Resig
|
|
||||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
||||||
* http://docs.jquery.com/License
|
|
||||||
*
|
|
||||||
* Includes Sizzle.js
|
|
||||||
* http://sizzlejs.com/
|
|
||||||
* Copyright 2010, The Dojo Foundation
|
|
||||||
* Released under the MIT, BSD, and GPL Licenses.
|
|
||||||
*
|
|
||||||
* Date: Wed Jan 13 15:23:05 2010 -0500
|
|
||||||
*/
|
|
||||||
(function(A,w){function oa(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(oa,1);return}c.ready()}}function La(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function $(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var o in b)$(a,o,b[o],f,e,d);return a}if(d!==w){f=!i&&f&&c.isFunction(d);for(o=0;o<j;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,i);return a}return j?
|
|
||||||
e(a[0],b):null}function K(){return(new Date).getTime()}function aa(){return false}function ba(){return true}function pa(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function qa(a){var b=true,d=[],f=[],e=arguments,i,j,o,p,n,t=c.extend({},c.data(this,"events").live);for(p in t){j=t[p];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete t[p]}i=c(a.target).closest(f,a.currentTarget);
|
|
||||||
n=0;for(l=i.length;n<l;n++)for(p in t){j=t[p];o=i[n].elem;f=null;if(i[n].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==o)d.push({elem:o,fn:j})}}n=0;for(l=d.length;n<l;n++){i=d[n];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}function ra(a,b){return["live",a,b.replace(/\./g,"`").replace(/ /g,"&")].join(".")}function sa(a){return!a||!a.parentNode||a.parentNode.nodeType===
|
|
||||||
11}function ta(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ua(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:s;f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=
|
|
||||||
i?f:1;return{fragment:f,cacheable:e}}function T(a){for(var b=0,d,f;(d=a[b])!=null;b++)if(!c.noData[d.nodeName.toLowerCase()]&&(f=d[H]))delete c.cache[f]}function L(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ma=A.jQuery,Na=A.$,s=A.document,U,Oa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Pa=/^.[^:#\[\.,]*$/,Qa=/\S/,
|
|
||||||
Ra=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Sa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],M,ca=Object.prototype.toString,da=Object.prototype.hasOwnProperty,ea=Array.prototype.push,R=Array.prototype.slice,V=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Oa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Sa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];
|
|
||||||
c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ua([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return U.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a)}else return!b||b.jquery?(b||U).find(a):c(b).find(a);else if(c.isFunction(a))return U.ready(a);if(a.selector!==w){this.selector=a.selector;
|
|
||||||
this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,this)},selector:"",jquery:"1.4",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=
|
|
||||||
0;ea.apply(this,a);return this},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||
|
|
||||||
c(null)},push:ea,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];o=e[i];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(o)?[]:{};a[i]=c.extend(f,j,o)}else if(o!==w)a[i]=
|
|
||||||
o}return a};c.extend({noConflict:function(a){A.$=Na;if(a)A.jQuery=Ma;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",M,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",
|
|
||||||
M);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&oa()}}},isFunction:function(a){return ca.call(a)==="[object Function]"},isArray:function(a){return ca.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||ca.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!da.call(a,"constructor")&&!da.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===w||da.call(a,b)},
|
|
||||||
isEmptyObject:function(a){for(var b in a)return false;return true},noop:function(){},globalEval:function(a){if(a&&Qa.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===w||c.isFunction(a);
|
|
||||||
if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Ra,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ea.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=
|
|
||||||
0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b===
|
|
||||||
"string"){d=a;a=d[b];b=w}else if(b&&!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){var b={browser:""};a=a.toLowerCase();if(/webkit/.test(a))b={browser:"webkit",version:/webkit[\/ ]([\w.]+)/};else if(/opera/.test(a))b={browser:"opera",version:/version/.test(a)?/version[\/ ]([\w.]+)/:/opera[\/ ]([\w.]+)/};else if(/msie/.test(a))b={browser:"msie",version:/msie ([\w.]+)/};else if(/mozilla/.test(a)&&
|
|
||||||
!/compatible/.test(a))b={browser:"mozilla",version:/rv:([\w.]+)/};b.version=(b.version&&b.version.exec(a)||[0,"0"])[1];return b},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=true;if(V)c.inArray=function(a,b){return V.call(b,a)};U=c(s);if(s.addEventListener)M=function(){s.removeEventListener("DOMContentLoaded",M,false);c.ready()};else if(s.attachEvent)M=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",
|
|
||||||
M);c.ready()}};if(V)c.inArray=function(a,b){return V.call(b,a)};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+K();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,
|
|
||||||
htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,
|
|
||||||
a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function o(){c.support.noCloneEvent=false;d.detachEvent("onclick",o)});d.cloneNode(true).fireEvent("onclick")}c(function(){var o=s.createElement("div");o.style.width=o.style.paddingLeft="1px";s.body.appendChild(o);c.boxModel=c.support.boxModel=o.offsetWidth===2;s.body.removeChild(o).style.display="none"});a=function(o){var p=s.createElement("div");o="on"+o;var n=o in
|
|
||||||
p;if(!n){p.setAttribute(o,"return;");n=typeof p[o]==="function"}return n};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var H="jQuery"+K(),Ta=0,ya={},Ua={};c.extend({cache:{},expando:H,noData:{embed:true,object:true,applet:true},data:function(a,
|
|
||||||
b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var f=a[H],e=c.cache;if(!b&&!f)return null;f||(f=++Ta);if(typeof b==="object"){a[H]=f;e=e[f]=c.extend(true,{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Ua:(e[f]={});if(d!==w){a[H]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var d=a[H],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[H]}catch(i){a.removeAttribute&&
|
|
||||||
a.removeAttribute(H)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,
|
|
||||||
a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,
|
|
||||||
a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var za=/[\n\t]/g,fa=/\s+/,Va=/\r/g,Wa=/href|src|style/,Xa=/(button|input)/i,Ya=/(button|input|object|select|textarea)/i,Za=/^(a|area)$/i,Aa=/radio|checkbox/;c.fn.extend({attr:function(a,
|
|
||||||
b){return $(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.addClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(fa),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,o=b.length;j<o;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=
|
|
||||||
" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.removeClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(fa),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(za," "),j=0,o=b.length;j<o;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,
|
|
||||||
b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),o=b,p=a.split(fa);e=p[i++];){o=f?o:!j.hasClass(e);j[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=
|
|
||||||
" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(za," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(Aa.test(b.type)&&
|
|
||||||
!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Va,"")}return w}var o=c.isFunction(a);return this.each(function(p){var n=c(this),t=a;if(this.nodeType===1){if(o)t=a.call(this,p,n.val());if(typeof t==="number")t+="";if(c.isArray(t)&&Aa.test(this.type))this.checked=c.inArray(n.val(),t)>=0;else if(c.nodeName(this,"select")){var z=c.makeArray(t);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),z)>=0});if(!z.length)this.selectedIndex=
|
|
||||||
-1}else this.value=t}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Wa.test(b);if(b in a&&f&&!i){if(e){if(b==="type"&&Xa.test(a.nodeName)&&a.parentNode)throw"type property can't be changed";a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;
|
|
||||||
if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Ya.test(a.nodeName)||Za.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var $a=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===
|
|
||||||
3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;if(!d.guid)d.guid=c.guid++;if(f!==w){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):w};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var o,p=0;o=b[p++];){var n=o.split(".");o=n.shift();d.type=n.slice(0).sort().join(".");var t=e[o],z=this.special[o]||{};if(!t){t=e[o]={};
|
|
||||||
if(!z.setup||z.setup.call(a,f,n,d)===false)if(a.addEventListener)a.addEventListener(o,i,false);else a.attachEvent&&a.attachEvent("on"+o,i)}if(z.add)if((n=z.add.call(a,d,f,n,t))&&c.isFunction(n)){n.guid=n.guid||d.guid;d=n}t[d.guid]=d;this.global[o]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===w||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);
|
|
||||||
for(var o=0;i=b[o++];){var p=i.split(".");i=p.shift();var n=!p.length,t=c.map(p.slice(0).sort(),$a);t=new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.)?")+"(\\.|$)");var z=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var B in f[i])if(n||t.test(f[i][B].type))delete f[i][B];z.remove&&z.remove.call(a,p,j);for(e in f[i])break;if(!e){if(!z.teardown||z.teardown.call(a,p)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+
|
|
||||||
i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(B=c.data(a,"handle"))B.elem=null;c.removeData(a,"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[H]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===
|
|
||||||
8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;var i=c.data(d,"handle");i&&i.apply(d,b);var j,o;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){j=d[e];o=d["on"+e]}}catch(p){}i=c.nodeName(d,"a")&&e==="click";if(!f&&j&&!a.isDefaultPrevented()&&!i){this.triggered=true;try{d[e]()}catch(n){}}else if(o&&d["on"+e].apply(d,b)===false)a.result=false;this.triggered=false;if(!a.isPropagationStopped())(d=d.parentNode||d.ownerDocument)&&c.event.trigger(a,b,d,true)},
|
|
||||||
handle:function(a){var b,d;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},
|
|
||||||
props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[H])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||
|
|
||||||
s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&
|
|
||||||
a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;c.event.add(this,b.live,qa,b)},remove:function(a){if(a.length){var b=0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],qa)}},special:{}},beforeunload:{setup:function(a,
|
|
||||||
b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=K();this[H]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ba;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=
|
|
||||||
ba;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ba;this.stopPropagation()},isDefaultPrevented:aa,isPropagationStopped:aa,isImmediatePropagationStopped:aa};var Ba=function(a){for(var b=a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ca=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",
|
|
||||||
mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ca:Ba,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ca:Ba)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return pa("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+
|
|
||||||
d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return pa("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var ga=/textarea|input|select/i;function Da(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>
|
|
||||||
-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ha(a,b){var d=a.target,f,e;if(!(!ga.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Da(d);if(e!==f){if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",e);if(d.type!=="select"&&(f!=null||e)){a.type="change";return c.event.trigger(a,b,this)}}}}c.event.special.change={filters:{focusout:ha,click:function(a){var b=a.target,d=b.type;if(d===
|
|
||||||
"radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ha.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ha.call(this,a)},beforeactivate:function(a){a=a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Da(a))}},setup:function(a,b,d){for(var f in W)c.event.add(this,f+".specialChange."+d.guid,W[f]);return ga.test(this.nodeName)},
|
|
||||||
remove:function(a,b){for(var d in W)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),W[d]);return ga.test(this.nodeName)}};var W=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,
|
|
||||||
f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){thisObject=e;e=f;f=w}var j=b==="one"?c.proxy(e,function(o){c(this).unbind(o,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e,thisObject):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,
|
|
||||||
b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||
|
|
||||||
a)},live:function(a,b,d){if(c.isFunction(b)){d=b;b=w}c(this.context).bind(ra(a,this.selector),{data:b,selector:this.selector,live:a},d);return this},die:function(a,b){c(this.context).unbind(ra(a,this.selector),b?{guid:b.guid+this.selector+a}:null);return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?
|
|
||||||
this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",k,m=0;g[m];m++){k=g[m];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,m,r,q){r=0;for(var v=m.length;r<v;r++){var u=m[r];if(u){u=u[g];for(var y=false;u;){if(u.sizcache===
|
|
||||||
k){y=m[u.sizset];break}if(u.nodeType===1&&!q){u.sizcache=k;u.sizset=r}if(u.nodeName.toLowerCase()===h){y=u;break}u=u[g]}m[r]=y}}}function d(g,h,k,m,r,q){r=0;for(var v=m.length;r<v;r++){var u=m[r];if(u){u=u[g];for(var y=false;u;){if(u.sizcache===k){y=m[u.sizset];break}if(u.nodeType===1){if(!q){u.sizcache=k;u.sizset=r}if(typeof h!=="string"){if(u===h){y=true;break}}else if(p.filter(h,[u]).length>0){y=u;break}}u=u[g]}m[r]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
|
|
||||||
e=0,i=Object.prototype.toString,j=false,o=true;[0,0].sort(function(){o=false;return 0});var p=function(g,h,k,m){k=k||[];var r=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return k;for(var q=[],v,u,y,S,I=true,N=x(h),J=g;(f.exec(""),v=f.exec(J))!==null;){J=v[3];q.push(v[1]);if(v[2]){S=v[3];break}}if(q.length>1&&t.exec(g))if(q.length===2&&n.relative[q[0]])u=ia(q[0]+q[1],h);else for(u=n.relative[q[0]]?[h]:p(q.shift(),h);q.length;){g=q.shift();if(n.relative[g])g+=q.shift();
|
|
||||||
u=ia(g,u)}else{if(!m&&q.length>1&&h.nodeType===9&&!N&&n.match.ID.test(q[0])&&!n.match.ID.test(q[q.length-1])){v=p.find(q.shift(),h,N);h=v.expr?p.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:q.pop(),set:B(m)}:p.find(q.pop(),q.length===1&&(q[0]==="~"||q[0]==="+")&&h.parentNode?h.parentNode:h,N);u=v.expr?p.filter(v.expr,v.set):v.set;if(q.length>0)y=B(u);else I=false;for(;q.length;){var E=q.pop();v=E;if(n.relative[E])v=q.pop();else E="";if(v==null)v=h;n.relative[E](y,v,N)}}else y=[]}y||(y=u);if(!y)throw"Syntax error, unrecognized expression: "+
|
|
||||||
(E||g);if(i.call(y)==="[object Array]")if(I)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&F(h,y[g])))k.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&k.push(u[g]);else k.push.apply(k,y);else B(y,k);if(S){p(S,r,k,m);p.uniqueSort(k)}return k};p.uniqueSort=function(g){if(D){j=o;g.sort(D);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};p.matches=function(g,h){return p(g,null,null,h)};p.find=function(g,h,k){var m,r;if(!g)return[];
|
|
||||||
for(var q=0,v=n.order.length;q<v;q++){var u=n.order[q];if(r=n.leftMatch[u].exec(g)){var y=r[1];r.splice(1,1);if(y.substr(y.length-1)!=="\\"){r[1]=(r[1]||"").replace(/\\/g,"");m=n.find[u](r,h,k);if(m!=null){g=g.replace(n.match[u],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};p.filter=function(g,h,k,m){for(var r=g,q=[],v=h,u,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var I in n.filter)if((u=n.leftMatch[I].exec(g))!=null&&u[2]){var N=n.filter[I],J,E;E=u[1];y=false;u.splice(1,1);if(E.substr(E.length-
|
|
||||||
1)!=="\\"){if(v===q)q=[];if(n.preFilter[I])if(u=n.preFilter[I](u,v,k,q,m,S)){if(u===true)continue}else y=J=true;if(u)for(var X=0;(E=v[X])!=null;X++)if(E){J=N(E,u,X,v);var Ea=m^!!J;if(k&&J!=null)if(Ea)y=true;else v[X]=false;else if(Ea){q.push(E);y=true}}if(J!==w){k||(v=q);g=g.replace(n.match[I],"");if(!y)return[];break}}}if(g===r)if(y==null)throw"Syntax error, unrecognized expression: "+g;else break;r=g}return v};var n=p.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
|
|
||||||
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
|
|
||||||
relative:{"+":function(g,h){var k=typeof h==="string",m=k&&!/\W/.test(h);k=k&&!m;if(m)h=h.toLowerCase();m=0;for(var r=g.length,q;m<r;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=k||q&&q.nodeName.toLowerCase()===h?q||false:q===h}k&&p.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,r=g.length;m<r;m++){var q=g[m];if(q){k=q.parentNode;g[m]=k.nodeName.toLowerCase()===h?k:false}}}else{m=0;for(r=g.length;m<r;m++)if(q=g[m])g[m]=
|
|
||||||
k?q.parentNode:q.parentNode===h;k&&p.filter(h,g,true)}},"":function(g,h,k){var m=e++,r=d;if(typeof h==="string"&&!/\W/.test(h)){var q=h=h.toLowerCase();r=b}r("parentNode",h,m,g,q,k)},"~":function(g,h,k){var m=e++,r=d;if(typeof h==="string"&&!/\W/.test(h)){var q=h=h.toLowerCase();r=b}r("previousSibling",h,m,g,q,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];
|
|
||||||
h=h.getElementsByName(g[1]);for(var m=0,r=h.length;m<r;m++)h[m].getAttribute("name")===g[1]&&k.push(h[m]);return k.length===0?null:k}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,m,r,q){g=" "+g[1].replace(/\\/g,"")+" ";if(q)return g;q=0;for(var v;(v=h[q])!=null;q++)if(v)if(r^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||m.push(v);else if(k)h[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
|
|
||||||
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,m,r,q){h=g[1].replace(/\\/g,"");if(!q&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,m,r){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=p(g[3],null,null,h);else{g=p.filter(g[3],h,k,true^r);k||m.push.apply(m,
|
|
||||||
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!p(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
|
|
||||||
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
|
|
||||||
setFilters:{first:function(g,h){return h===0},last:function(g,h,k,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,m){var r=h[1],q=n.filters[r];if(q)return q(g,k,h,m);else if(r==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(r==="not"){h=
|
|
||||||
h[3];k=0;for(m=h.length;k<m;k++)if(h[k]===g)return false;return true}else throw"Syntax error, unrecognized expression: "+r;},CHILD:function(g,h){var k=h[1],m=g;switch(k){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(k==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":k=h[2];var r=h[3];if(k===1&&r===0)return true;h=h[0];var q=g.parentNode;if(q&&(q.sizcache!==h||!g.nodeIndex)){var v=0;for(m=q.firstChild;m;m=
|
|
||||||
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;q.sizcache=h}g=g.nodeIndex-r;return k===0?g===0:g%k===0&&g/k>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=n.attrHandle[k]?n.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
|
|
||||||
"="?k===h:m==="*="?k.indexOf(h)>=0:m==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:m==="!="?k!==h:m==="^="?k.indexOf(h)===0:m==="$="?k.substr(k.length-h.length)===h:m==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,m){var r=n.setFilters[h[2]];if(r)return r(g,k,h,m)}}},t=n.match.POS;for(var z in n.match){n.match[z]=new RegExp(n.match[z].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[z]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[z].source.replace(/\\(\d+)/g,function(g,
|
|
||||||
h){return"\\"+(h-0+1)}))}var B=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){B=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,m=g.length;k<m;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var D;if(s.documentElement.compareDocumentPosition)D=function(g,h){if(!g.compareDocumentPosition||
|
|
||||||
!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in s.documentElement)D=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(s.createRange)D=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),m=
|
|
||||||
h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)j=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=s.documentElement;k.insertBefore(g,k.firstChild);if(s.getElementById(h)){n.find.ID=function(m,r,q){if(typeof r.getElementById!=="undefined"&&!q)return(r=r.getElementById(m[1]))?r.id===m[1]||typeof r.getAttributeNode!=="undefined"&&
|
|
||||||
r.getAttributeNode("id").nodeValue===m[1]?[r]:w:[]};n.filter.ID=function(m,r){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===r}}k.removeChild(g);k=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;k[m];m++)k[m].nodeType===1&&h.push(k[m]);k=h}return k};g.innerHTML="<a href='#'></a>";
|
|
||||||
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=p,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){p=function(m,r,q,v){r=r||s;if(!v&&r.nodeType===9&&!x(r))try{return B(r.querySelectorAll(m),q)}catch(u){}return g(m,r,q,v)};for(var k in g)p[k]=g[k];h=null}}();
|
|
||||||
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,k,m){if(typeof k.getElementsByClassName!=="undefined"&&!m)return k.getElementsByClassName(h[1])};g=null}}})();var F=s.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,
|
|
||||||
h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ia=function(g,h){var k=[],m="",r;for(h=h.nodeType?[h]:h;r=n.match.PSEUDO.exec(g);){m+=r[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;r=0;for(var q=h.length;r<q;r++)p(g,h[r],k);return p.filter(m,k)};c.find=p;c.expr=p.selectors;c.expr[":"]=c.expr.filters;c.unique=p.uniqueSort;c.getText=a;c.isXMLDoc=x;c.contains=F})();var ab=/Until$/,bb=/^(?:parents|prevUntil|prevAll)/,
|
|
||||||
cb=/,/;R=Array.prototype.slice;var Fa=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Pa.test(b))return c.filter(b,f,!d);else b=c.filter(b,a)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
|
|
||||||
c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Fa(this,a,false),"not",a)},filter:function(a){return this.pushStack(Fa(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i=
|
|
||||||
{},j;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var p=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,t){for(;t&&t.ownerDocument&&t!==b;){if(p?p.index(t)>-1:c(t).is(a))return t;t=t.parentNode}return null})},index:function(a){if(!a||typeof a===
|
|
||||||
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(sa(a[0])||sa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
|
|
||||||
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
|
|
||||||
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);ab.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||cb.test(f))&&bb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||!c(a).is(d));){a.nodeType===
|
|
||||||
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ga=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,db=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,hb=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},G={option:[1,"<select multiple='multiple'>","</select>"],
|
|
||||||
legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};G.optgroup=G.option;G.tbody=G.tfoot=G.colgroup=G.caption=G.thead;G.th=G.td;if(!c.support.htmlSerialize)G._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);
|
|
||||||
return d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.getText(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
|
|
||||||
wrapInner:function(a){return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&
|
|
||||||
this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,
|
|
||||||
"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ga,"").replace(Y,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ta(this,b);ta(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===
|
|
||||||
1?this[0].innerHTML.replace(Ga,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!Y.test(a))&&!G[(Ha.exec(a)||["",""])[1].toLowerCase()])try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){T(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
|
|
||||||
this[0].parentNode){c.isFunction(a)||(a=c(a).detach());return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(t){return c.nodeName(t,"table")?t.getElementsByTagName("tbody")[0]||t.appendChild(t.ownerDocument.createElement("tbody")):t}var e,i,j=a[0],o=[];if(c.isFunction(j))return this.each(function(t){var z=
|
|
||||||
c(this);a[0]=j.call(this,t,b?z.html():w);return z.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ua(a,this,o);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var p=0,n=this.length;p<n;p++)d.call(b?f(this[p],i):this[p],e.cacheable||this.length>1||p>0?e.fragment.cloneNode(true):e.fragment)}o&&c.each(o,La)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},
|
|
||||||
function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){T(this.getElementsByTagName("*"));T([this])}this.parentNode&&this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&T(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},
|
|
||||||
function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j==="string"){j=j.replace(db,hb);var o=(Ha.exec(j)||["",""])[1].toLowerCase(),p=G[o]||G._default,n=p[0];i=b.createElement("div");for(i.innerHTML=p[1]+j+p[2];n--;)i=i.lastChild;
|
|
||||||
if(!c.support.tbody){n=fb.test(j);o=o==="table"&&!n?i.firstChild&&i.firstChild.childNodes:p[1]==="<table>"&&!n?i.childNodes:[];for(p=o.length-1;p>=0;--p)c.nodeName(o[p],"tbody")&&!o[p].childNodes.length&&o[p].parentNode.removeChild(o[p])}!c.support.leadingWhitespace&&Y.test(j)&&i.insertBefore(b.createTextNode(Y.exec(j)[0]),i.firstChild);j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()===
|
|
||||||
"text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e}});var ib=/z-?index|font-?weight|opacity|zoom|line-?height/i,Ia=/alpha\([^)]*\)/,Ja=/opacity=([^)]*)/,ja=/float/i,ka=/-([a-z])/ig,jb=/([A-Z])/g,kb=/^-?\d+(?:px)?$/i,lb=/^-?\d/,mb={position:"absolute",visibility:"hidden",display:"block"},nb=["Left","Right"],ob=["Top","Bottom"],pb=s.defaultView&&
|
|
||||||
s.defaultView.getComputedStyle,Ka=c.support.cssFloat?"cssFloat":"styleFloat",la=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return $(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!ib.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""===
|
|
||||||
"NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ia.test(a)?a.replace(Ia,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ja.exec(f.filter)[1])/100+"":""}if(ja.test(b))b=Ka;b=b.replace(ka,la);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?nb:ob;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=
|
|
||||||
parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,mb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Ja.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ja.test(b))b=Ka;if(!d&&e&&e[b])f=e[b];else if(pb){if(ja.test(b))b="float";b=b.replace(jb,"-$1").toLowerCase();e=
|
|
||||||
a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ka,la);f=a.currentStyle[b]||a.currentStyle[d];if(!kb.test(f)&&lb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=
|
|
||||||
f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var qb=K(),rb=/<script(.|\s)*?\/script>/gi,sb=/select|textarea/i,tb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,O=/=\?(&|$)/,ma=/\?/,ub=/(\?|&)_=.*?(&|$)/,vb=/^(\w+:)?\/\/([^\/?#]+)/,
|
|
||||||
wb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}c.ajax({url:a,type:f,dataType:"html",data:b,context:this,complete:function(i,j){if(j==="success"||j==="notmodified")this.html(e?c("<div />").append(i.responseText.replace(rb,
|
|
||||||
"")).find(e):i.responseText);d&&this.each(d,[i.responseText,j,i])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||sb.test(this.nodeName)||tb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});
|
|
||||||
c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},
|
|
||||||
ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",
|
|
||||||
text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(p,o,j,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(p,x,j);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(r,q){(e.context?c(e.context):c.event).trigger(r,q)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,o,p=e.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,
|
|
||||||
e.traditional);if(e.dataType==="jsonp"){if(n==="GET")O.test(e.url)||(e.url+=(ma.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!O.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&O.test(e.data)||O.test(e.url))){i=e.jsonpCallback||"jsonp"+qb++;if(e.data)e.data=(e.data+"").replace(O,"="+i+"$1");e.url=e.url.replace(O,"="+i+"$1");e.dataType="script";A[i]=A[i]||function(r){o=r;b();d();A[i]=w;try{delete A[i]}catch(q){}B&&
|
|
||||||
B.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&n==="GET"){var t=K(),z=e.url.replace(ub,"$1_="+t+"$2");e.url=z+(z===e.url?(ma.test(e.url)?"&":"?")+"_="+t:"")}if(e.data&&n==="GET")e.url+=(ma.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");t=(t=vb.exec(e.url))&&(t[1]&&t[1]!==location.protocol||t[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&t){var B=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");
|
|
||||||
C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!i){var D=false;C.onload=C.onreadystatechange=function(){if(!D&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){D=true;b();d();C.onload=C.onreadystatechange=null;B&&C.parentNode&&B.removeChild(C)}}}B.insertBefore(C,B.firstChild);return w}var F=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",
|
|
||||||
e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}t||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ia){}if(e.beforeSend&&e.beforeSend.call(p,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",
|
|
||||||
[x,e]);var g=x.onreadystatechange=function(r){if(!x||x.readyState===0){F||d();F=true;if(x)x.onreadystatechange=c.noop}else if(!F&&x&&(x.readyState===4||r==="timeout")){F=true;x.onreadystatechange=c.noop;j=r==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";if(j==="success")try{o=c.httpData(x,e.dataType,e)}catch(q){j="parsererror"}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,x,j);d();r==="timeout"&&x.abort();if(e.async)x=
|
|
||||||
null}};try{var h=x.abort;x.abort=function(){if(x){h.call(x);if(x)x.readyState=0}g()}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){x&&!F&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||A,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol===
|
|
||||||
"file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;if(e&&a.documentElement.nodeName==="parsererror")throw"parsererror";if(d&&
|
|
||||||
d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))a=A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+a))();else throw"Invalid JSON: "+a;else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(e,i){i=
|
|
||||||
c.isFunction(i)?i():i;f[f.length]=encodeURIComponent(e)+"="+encodeURIComponent(i)}var f=[];if(b===w)b=c.ajaxSettings.traditional;c.isArray(a)||a.jquery?c.each(a,function(){d(this.name,this.value)}):c.each(a,function e(i,j){if(c.isArray(j))c.each(j,function(o,p){b?d(i,p):e(i+"["+(typeof p==="object"||c.isArray(p)?o:"")+"]",p)});else!b&&j!=null&&typeof j==="object"?c.each(j,function(o,p){e(i+"["+o+"]",p)}):d(i,j)});return f.join("&").replace(wb,"+")}});var na={},xb=/toggle|show|hide/,yb=/^([+-]=)?([\d+-.]+)(.*)$/,
|
|
||||||
Z,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a!=null)return this.animate(L("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(na[d])f=na[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
|
|
||||||
na[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a!=null)return this.animate(L("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
|
|
||||||
c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(L("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,o=this.nodeType===1&&c(this).is(":hidden"),
|
|
||||||
p=this;for(j in a){var n=j.replace(ka,la);if(j!==n){a[n]=a[j];delete a[j];j=n}if(a[j]==="hide"&&o||a[j]==="show"&&!o)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(t,z){var B=new c.fx(p,i,t);if(xb.test(z))B[z==="toggle"?o?"show":"hide":z](a);
|
|
||||||
else{var C=yb.exec(z),D=B.cur(true)||0;if(C){z=parseFloat(C[2]);var F=C[3]||"px";if(F!=="px"){p.style[t]=(z||1)+F;D=(z||1)/B.cur(true)*D;p.style[t]=D+F}if(C[1])z=(C[1]==="-="?-1:1)*z+D;B.custom(D,z,F)}else B.custom(D,z,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:L("show",1),slideUp:L("hide",1),slideToggle:L("toggle",
|
|
||||||
1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
|
|
||||||
b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
|
|
||||||
null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=K();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!Z)Z=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
|
|
||||||
"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=K(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
|
|
||||||
this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
|
|
||||||
c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(Z);Z=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
|
|
||||||
null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
|
|
||||||
f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(t){c.offset.setOffset(this,a,t)});if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
|
|
||||||
b,e=b.ownerDocument,i,j=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var p=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;p-=b.scrollTop;n-=b.scrollLeft;if(b===d){p+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){p+=parseFloat(i.borderTopWidth)||
|
|
||||||
0;n+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){p+=parseFloat(i.borderTopWidth)||0;n+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){p+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){p+=Math.max(j.scrollTop,o.scrollTop);n+=Math.max(j.scrollLeft,o.scrollLeft)}return{top:p,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),
|
|
||||||
d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
|
|
||||||
d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
|
|
||||||
bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
|
|
||||||
e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
|
|
||||||
this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==w)return this.each(function(){if(i=wa(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=wa(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
|
|
||||||
c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+
|
|
||||||
b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
|
|
6737
build/js/ox.data.js
|
@ -1,110 +0,0 @@
|
||||||
/*
|
|
||||||
################################################################################
|
|
||||||
ox.geo.js
|
|
||||||
|
|
||||||
requires
|
|
||||||
jquery.js
|
|
||||||
ox.js
|
|
||||||
################################################################################
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
var earthRadius = 6378137,
|
|
||||||
earthCircumference = 2 * Math.PI * earthRadius
|
|
||||||
latMax = Ox.deg(Math.atan(Ox.sinh(Math.PI))),
|
|
||||||
latMin = -latMax;
|
|
||||||
/*
|
|
||||||
map = {
|
|
||||||
width: window.innerWidth,
|
|
||||||
height: window.innerHeight,
|
|
||||||
margin: 16
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
Ox.getLatLng = (function() {
|
|
||||||
/*
|
|
||||||
returns {lat, lng} for a given (x, y)
|
|
||||||
*/
|
|
||||||
function getLatLng(xy) {
|
|
||||||
return (xy - 0.5) * 2 * Math.PI;
|
|
||||||
}
|
|
||||||
return function(x, y) {
|
|
||||||
return {
|
|
||||||
lat: -Ox.deg(Math.atan(Ox.sinh(getLatLng(y)))),
|
|
||||||
lng: Ox.deg(getLatLng(x))
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
Ox.getPlacemarks = (function() {
|
|
||||||
/*
|
|
||||||
Ox.getPlacemarks(name, callback)
|
|
||||||
Ox.getPlacemarks(lat, lng, callback)
|
|
||||||
*/
|
|
||||||
var cache = {};
|
|
||||||
return function() {
|
|
||||||
|
|
||||||
// $.getScript("http://maps.google.com/maps/api/js?sensor=false", function() {
|
|
||||||
// getPlacemarks(args);
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
// var args = arguments;
|
|
||||||
var reverse = typeof arguments[0] == "number",
|
|
||||||
query = $.extend({
|
|
||||||
language: "en"
|
|
||||||
}, !reverse ? {
|
|
||||||
address: arguments[0]
|
|
||||||
} : {
|
|
||||||
latLng: new google.maps.LatLng(arguments[0], arguments[1])
|
|
||||||
}),
|
|
||||||
id = JSON.stringify(query),
|
|
||||||
callback = arguments[arguments.length - 1],
|
|
||||||
geocoder = new google.maps.Geocoder();
|
|
||||||
if (cache[id]) {
|
|
||||||
callback(cache[id]);
|
|
||||||
} else {
|
|
||||||
geocoder.geocode(query, function(results, status) {
|
|
||||||
var data = {
|
|
||||||
results: results,
|
|
||||||
status: status
|
|
||||||
};
|
|
||||||
cache[id] = data;
|
|
||||||
callback(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
Ox.getXY = (function() {
|
|
||||||
/*
|
|
||||||
returns {x, y} for a given (lat, lng), between 0 and 1
|
|
||||||
*/
|
|
||||||
function getXY(xy) {
|
|
||||||
return (xy / (2 * Math.PI) + 0.5);
|
|
||||||
}
|
|
||||||
return function(lat, lng) {
|
|
||||||
return {
|
|
||||||
x: getXY(Ox.rad(lng)),
|
|
||||||
y: getXY(Ox.asinh(Math.tan(Ox.rad(-lat))))
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Ox.getZ = function(placemark, map) {
|
|
||||||
// returns zoom level at which placemark is fully included
|
|
||||||
map.width -= 2 * map.margin;
|
|
||||||
map.height -= 2 * map.margin;
|
|
||||||
var northEast = getXY(placemark.northEast),
|
|
||||||
southWest = getXY(placemark.southWest),
|
|
||||||
width = (northEast.x - southWest.x),
|
|
||||||
height = (northEast.y - southWest.y),
|
|
||||||
return parseInt(Ox.log(width / height > map.width / map.height ?
|
|
||||||
map.width / width : map.height / height, 2));
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,162 +0,0 @@
|
||||||
$(function() {
|
|
||||||
|
|
||||||
var $body = $('body'),
|
|
||||||
$div = $('<div>')
|
|
||||||
.css({
|
|
||||||
position: 'absolute',
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
background: 'rgb(240, 240, 240)',
|
|
||||||
opacity: 1,
|
|
||||||
zIndex: 1000
|
|
||||||
})
|
|
||||||
.appendTo($body),
|
|
||||||
css = {
|
|
||||||
position: 'absolute',
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
margin: 'auto',
|
|
||||||
MozUserSelect: 'none',
|
|
||||||
WebkitUserSelect: 'none'
|
|
||||||
},
|
|
||||||
file = 'js/ox.load.js',
|
|
||||||
path = $('script[src*="' + file + '"]').attr('src').replace(file, ''),
|
|
||||||
userAgent,
|
|
||||||
userAgents = {
|
|
||||||
'Chrome': 'http://www.google.com/chrome/',
|
|
||||||
'Firefox': 'http://www.mozilla.org/firefox/',
|
|
||||||
'Internet Explorer': '',
|
|
||||||
'Opera': 'http://www.opera.com/',
|
|
||||||
'Safari': 'http://www.apple.com/safari/'
|
|
||||||
};
|
|
||||||
|
|
||||||
userAgent = getUserAgent();
|
|
||||||
userAgents[userAgent] ? start() : stop();
|
|
||||||
|
|
||||||
function getUserAgent() {
|
|
||||||
var userAgent = '';
|
|
||||||
$.each(userAgents, function(name, link) {
|
|
||||||
if (navigator.userAgent.indexOf(name) > -1) {
|
|
||||||
userAgent = name;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (!userAgent && $.browser.mozilla) {
|
|
||||||
userAgent = 'Firefox';
|
|
||||||
}
|
|
||||||
if (!userAgent && $.browser.webkit) {
|
|
||||||
userAgent = 'Chrome';
|
|
||||||
}
|
|
||||||
return userAgent;
|
|
||||||
}
|
|
||||||
|
|
||||||
function start() {
|
|
||||||
var image = new Image(),
|
|
||||||
src = path + 'svg/ox.ui.classic/symbolLoading.svg';
|
|
||||||
image.src = src;
|
|
||||||
image.onload = function() {
|
|
||||||
var $img = $('<img>')
|
|
||||||
.attr({
|
|
||||||
src: src
|
|
||||||
})
|
|
||||||
.css($.extend(css, {
|
|
||||||
width: '32px',
|
|
||||||
height: '32px'
|
|
||||||
}))
|
|
||||||
.mousedown(function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
})
|
|
||||||
.appendTo($div);
|
|
||||||
/*
|
|
||||||
deg = 0,
|
|
||||||
interval = setInterval(function() {
|
|
||||||
deg = (deg + 30) % 360;
|
|
||||||
$img.css({
|
|
||||||
MozTransform: 'rotate(' + deg + 'deg)',
|
|
||||||
WebkitTransform: 'rotate(' + deg + 'deg)',
|
|
||||||
});
|
|
||||||
}, 83);
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function stop() {
|
|
||||||
var counter = 0,
|
|
||||||
length = 0,
|
|
||||||
src = {};
|
|
||||||
Ox.forEach(userAgents, function(link, name) {
|
|
||||||
if (link) {
|
|
||||||
length++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Ox.forEach(userAgents, function(link, name) {
|
|
||||||
var image;
|
|
||||||
if (link) {
|
|
||||||
image = new Image();
|
|
||||||
src[name] = path + 'png/ox.ui/browser' + name + '128.png';
|
|
||||||
image.src = src[name];
|
|
||||||
image.onload = function() {
|
|
||||||
if (++counter == length) {
|
|
||||||
loaded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
function loaded() {
|
|
||||||
var $div_ = $('<div>')
|
|
||||||
.css($.extend(css, {
|
|
||||||
width: (length * 72) + 'px',
|
|
||||||
height: '72px'
|
|
||||||
})),
|
|
||||||
i = 0;
|
|
||||||
$.each(src, function(name, src) {
|
|
||||||
$('<a>')
|
|
||||||
.attr({
|
|
||||||
href: userAgents[name],
|
|
||||||
title: name
|
|
||||||
})
|
|
||||||
.css({
|
|
||||||
position: 'absolute',
|
|
||||||
left: (i++ * 72) + 'px',
|
|
||||||
width: '72px',
|
|
||||||
height: '72px',
|
|
||||||
})
|
|
||||||
.append(
|
|
||||||
$('<img>')
|
|
||||||
.attr({
|
|
||||||
src: src
|
|
||||||
})
|
|
||||||
.css($.extend(css, {
|
|
||||||
width: '64px',
|
|
||||||
height: '64px',
|
|
||||||
border: 0,
|
|
||||||
cursor: 'pointer'
|
|
||||||
}))
|
|
||||||
.mousedown(function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
})
|
|
||||||
.mouseenter(function() {
|
|
||||||
$(this).animate({
|
|
||||||
width: '72px',
|
|
||||||
height: '72px',
|
|
||||||
}, 250);
|
|
||||||
})
|
|
||||||
.mouseleave(function() {
|
|
||||||
$(this).animate({
|
|
||||||
width: '64px',
|
|
||||||
height: '64px',
|
|
||||||
}, 250);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.appendTo($div_);
|
|
||||||
});
|
|
||||||
$div_.appendTo($div);
|
|
||||||
//throw new Error('User Agent not supported.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
|
@ -1,362 +0,0 @@
|
||||||
Ox.COUNTRIES = [
|
|
||||||
// 304 countries (see http://en.wikipedia.org/wiki/Table_of_administrative_divisions_by_country)
|
|
||||||
// 193 sovereign countries (see http://en.wikipedia.org/wiki/List_of_sovereign_states)
|
|
||||||
// 11 unrecognized countries (see http://en.wikipedia.org/wiki/List_of_sovereign_states#Other_states)
|
|
||||||
// 62 dependent countries (6 Australia, 2 China, 2 Denmark, 1 Finland, 13 France, 4 Netherlands,
|
|
||||||
// 3 New Zealand, 2 Norway, 2 Spain, 22 United Kingdom, 6 United States, plus Antarctica)
|
|
||||||
// 34 former countries (http://en.wikipedia.org/wiki/ISO_3166-3, http://www.imdb.com/country/)
|
|
||||||
// 2 other countries (EU, UK)
|
|
||||||
// also see http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2,
|
|
||||||
// http://en.wikipedia.org/wiki/Borders_of_the_continents
|
|
||||||
// and http://unstats.un.org/unsd/methods/m49/m49regin.htm
|
|
||||||
{code: 'AF', continent: 'Asia', name: 'Afghanistan', region: 'Southern Asia', type: 'sovereign'},
|
|
||||||
{code: 'AL', continent: 'Europe', name: 'Albania', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'DZ', continent: 'Africa', name: 'Algeria', region: 'Northern Africa', type: 'sovereign'},
|
|
||||||
{code: 'AD', continent: 'Europe', name: 'Andorra', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'AO', continent: 'Africa', name: 'Angola', region: 'Middle Africa', type: 'sovereign'},
|
|
||||||
{code: 'AG', continent: 'North America', name: 'Antigua and Barbuda', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'AR', continent: 'South America', name: 'Argentina', type: 'sovereign'},
|
|
||||||
{code: 'AM', continent: 'Asia', name: 'Armenia', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'AU', continent: 'Oceania', name: 'Australia', region: 'Australia and New Zealand', type: 'sovereign'},
|
|
||||||
{code: 'AT', continent: 'Europe', name: 'Austria', region: 'Western Europe', type: 'sovereign'},
|
|
||||||
{code: 'AZ', continent: 'Asia', name: 'Azerbaijan', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'BS', continent: 'North America', name: 'Bahamas', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'BH', continent: 'Asia', name: 'Bahrain', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'BD', continent: 'Asia', name: 'Bangladesh', region: 'Southern Asia', type: 'sovereign'},
|
|
||||||
{code: 'BB', continent: 'North America', name: 'Barbados', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'BY', continent: 'Europe', name: 'Belarus', region: 'Eastern Europe', type: 'sovereign'},
|
|
||||||
{code: 'BE', continent: 'Europe', name: 'Belgium', region: 'Western Europe', type: 'sovereign'},
|
|
||||||
{code: 'BZ', continent: 'North America', name: 'Belize', region: 'Central America', type: 'sovereign'},
|
|
||||||
{code: 'BJ', continent: 'Africa', name: 'Benin', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'BT', continent: 'Asia', name: 'Bhutan', region: 'Southern Asia', type: 'sovereign'},
|
|
||||||
{code: 'BO', continent: 'South America', name: 'Bolivia', type: 'sovereign'},
|
|
||||||
{code: 'BA', continent: 'Europe', name: 'Bosnia and Herzegovina', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'BW', continent: 'Africa', name: 'Botswana', region: 'Southern Africa', type: 'sovereign'},
|
|
||||||
{code: 'BR', continent: 'South America', name: 'Brazil', type: 'sovereign'},
|
|
||||||
{code: 'BN', continent: 'Asia', name: 'Brunei', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'BG', continent: 'Europe', name: 'Bulgaria', region: 'Eastern Europe', type: 'sovereign'},
|
|
||||||
{code: 'BF', continent: 'Africa', name: 'Burkina Faso', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'BI', continent: 'Africa', name: 'Burundi', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'KH', continent: 'Asia', name: 'Cambodia', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'CM', continent: 'Africa', name: 'Cameroon', region: 'Middle Africa', type: 'sovereign'},
|
|
||||||
{code: 'CA', continent: 'North America', name: 'Canada', region: 'Northern America', type: 'sovereign'},
|
|
||||||
{code: 'CV', continent: 'Africa', name: 'Cape Verde', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'CF', continent: 'Africa', name: 'Central African Republic', region: 'Middle Africa', type: 'sovereign'},
|
|
||||||
{code: 'TD', continent: 'Africa', name: 'Chad', region: 'Middle Africa', type: 'sovereign'},
|
|
||||||
{code: 'CL', continent: 'South America', name: 'Chile', type: 'sovereign'},
|
|
||||||
{code: 'CN', continent: 'Asia', name: 'China', region: 'Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'CO', continent: 'South America', name: 'Colombia', type: 'sovereign'},
|
|
||||||
{code: 'KM', continent: 'Africa', name: 'Comoros', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'CR', continent: 'North America', name: 'Costa Rica', region: 'Central America', type: 'sovereign'},
|
|
||||||
{code: 'CI', continent: 'Africa', name: 'Côte d\'Ivoire', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'HR', continent: 'Europe', name: 'Croatia', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'CU', continent: 'North America', name: 'Cuba', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'CY', continent: 'Asia', name: 'Cyprus', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'CZ', continent: 'Europe', name: 'Czech Republic', region: 'Eastern Europe', type: 'sovereign'},
|
|
||||||
{code: 'CD', continent: 'Africa', name: 'Democratic Republic of the Congo', region: 'Middle Africa', type: 'sovereign'},
|
|
||||||
{code: 'DK', continent: 'Europe', name: 'Denmark', region: 'Northern Europe', type: 'sovereign'},
|
|
||||||
{code: 'DJ', continent: 'Africa', name: 'Djibouti', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'DM', continent: 'North America', name: 'Dominica', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'DO', continent: 'North America', name: 'Dominican Republic', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'EC', continent: 'South America', name: 'Ecuador', type: 'sovereign'},
|
|
||||||
{code: 'EG', continent: 'Africa', name: 'Egypt', region: 'Northern Africa', type: 'sovereign'},
|
|
||||||
{code: 'SV', continent: 'North America', name: 'El Salvador', region: 'Central America', type: 'sovereign'},
|
|
||||||
{code: 'GQ', continent: 'Africa', name: 'Equatorial Guinea', region: 'Middle Africa', type: 'sovereign'},
|
|
||||||
{code: 'ER', continent: 'Africa', name: 'Eritrea', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'EE', continent: 'Europe', name: 'Estonia', region: 'Northern Europe', type: 'sovereign'},
|
|
||||||
{code: 'ET', continent: 'Africa', name: 'Ethiopia', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'FJ', continent: 'Oceania', name: 'Fiji', region: 'Melanesia', type: 'sovereign'},
|
|
||||||
{code: 'FI', continent: 'Europe', name: 'Finland', region: 'Northern Europe', type: 'sovereign'},
|
|
||||||
{code: 'FR', continent: 'Europe', name: 'France', region: 'Western Europe', type: 'sovereign'},
|
|
||||||
{code: 'GA', continent: 'Africa', name: 'Gabon', region: 'Middle Africa', type: 'sovereign'},
|
|
||||||
{code: 'GM', continent: 'Africa', name: 'Gambia', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'GE', continent: 'Asia', name: 'Georgia', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'DE', continent: 'Europe', name: 'Germany', region: 'Western Europe', type: 'sovereign'},
|
|
||||||
{code: 'GH', continent: 'Africa', name: 'Ghana', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'GR', continent: 'Europe', name: 'Greece', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'GD', continent: 'North America', name: 'Grenada', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'GT', continent: 'North America', name: 'Guatemala', region: 'Central America', type: 'sovereign'},
|
|
||||||
{code: 'GN', continent: 'Africa', name: 'Guinea', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'GW', continent: 'Africa', name: 'Guinea-Bissau', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'GY', continent: 'South America', name: 'Guyana', type: 'sovereign'},
|
|
||||||
{code: 'HT', continent: 'North America', name: 'Haiti', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'VA', continent: 'Europe', name: 'Holy See', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'HN', continent: 'North America', name: 'Honduras', region: 'Central America', type: 'sovereign'},
|
|
||||||
{code: 'HU', continent: 'Europe', name: 'Hungary', region: 'Eastern Europe', type: 'sovereign'},
|
|
||||||
{code: 'IS', continent: 'Europe', name: 'Iceland', region: 'Northern Europe', type: 'sovereign'},
|
|
||||||
{code: 'IN', continent: 'Asia', name: 'India', region: 'Southern Asia', type: 'sovereign'},
|
|
||||||
{code: 'ID', continent: 'Asia', name: 'Indonesia', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'IR', continent: 'Asia', name: 'Iran', region: 'Southern Asia', type: 'sovereign'},
|
|
||||||
{code: 'IQ', continent: 'Asia', name: 'Iraq', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'IE', continent: 'Europe', name: 'Ireland', region: 'Northern Europe', type: 'sovereign'},
|
|
||||||
{code: 'IL', continent: 'Asia', name: 'Israel', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'IT', continent: 'Europe', name: 'Italy', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'JM', continent: 'North America', name: 'Jamaica', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'JP', continent: 'Asia', name: 'Japan', region: 'Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'JO', continent: 'Asia', name: 'Jordan', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'KZ', continent: 'Asia', name: 'Kazakhstan', region: 'Central Asia', type: 'sovereign'},
|
|
||||||
{code: 'KE', continent: 'Africa', name: 'Kenya', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'KI', continent: 'Oceania', name: 'Kiribati', region: 'Micronesia', type: 'sovereign'},
|
|
||||||
{code: 'KW', continent: 'Asia', name: 'Kuwait', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'KG', continent: 'Asia', name: 'Kyrgyzstan', region: 'Central Asia', type: 'sovereign'},
|
|
||||||
{code: 'LA', continent: 'Asia', name: 'Laos', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'LV', continent: 'Europe', name: 'Latvia', region: 'Northern Europe', type: 'sovereign'},
|
|
||||||
{code: 'LB', continent: 'Asia', name: 'Lebanon', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'LS', continent: 'Africa', name: 'Lesotho', region: 'Southern Africa', type: 'sovereign'},
|
|
||||||
{code: 'LR', continent: 'Africa', name: 'Liberia', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'LY', continent: 'Africa', name: 'Libya', region: 'Northern Africa', type: 'sovereign'},
|
|
||||||
{code: 'LI', continent: 'Europe', name: 'Liechtenstein', region: 'Western Europe', type: 'sovereign'},
|
|
||||||
{code: 'LT', continent: 'Europe', name: 'Lithuania', region: 'Northern Europe', type: 'sovereign'},
|
|
||||||
{code: 'LU', continent: 'Europe', name: 'Luxembourg', region: 'Western Europe', type: 'sovereign'},
|
|
||||||
{code: 'MK', continent: 'Europe', name: 'Macedonia', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'MG', continent: 'Africa', name: 'Madagascar', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'MW', continent: 'Africa', name: 'Malawi', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'MY', continent: 'Asia', name: 'Malaysia', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'MV', continent: 'Asia', name: 'Maldives', region: 'Southern Asia', type: 'sovereign'},
|
|
||||||
{code: 'ML', continent: 'Africa', name: 'Mali', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'MT', continent: 'Europe', name: 'Malta', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'MH', continent: 'Oceania', name: 'Marshall Islands', region: 'Micronesia', type: 'sovereign'},
|
|
||||||
{code: 'MR', continent: 'Africa', name: 'Mauritania', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'MU', continent: 'Africa', name: 'Mauritius', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'MX', continent: 'North America', name: 'Mexico', region: 'Central America', type: 'sovereign'},
|
|
||||||
{code: 'FM', continent: 'Oceania', name: 'Micronesia', region: 'Micronesia', type: 'sovereign'},
|
|
||||||
{code: 'MD', continent: 'Europe', name: 'Moldova', region: 'Eastern Europe', type: 'sovereign'},
|
|
||||||
{code: 'MC', continent: 'Europe', name: 'Monaco', region: 'Western Europe', type: 'sovereign'},
|
|
||||||
{code: 'MN', continent: 'Asia', name: 'Mongolia', region: 'Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'ME', continent: 'Europe', name: 'Montenegro', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'MA', continent: 'Africa', name: 'Morocco', region: 'Northern Africa', type: 'sovereign'},
|
|
||||||
{code: 'MZ', continent: 'Africa', name: 'Mozambique', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'MM', continent: 'Asia', name: 'Myanmar', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'NA', continent: 'Africa', name: 'Namibia', region: 'Southern Africa', type: 'sovereign'},
|
|
||||||
{code: 'NR', continent: 'Oceania', name: 'Nauru', region: 'Micronesia', type: 'sovereign'},
|
|
||||||
{code: 'NP', continent: 'Asia', name: 'Nepal', region: 'Southern Asia', type: 'sovereign'},
|
|
||||||
{code: 'NL', continent: 'Europe', name: 'Netherlands', region: 'Western Europe', type: 'sovereign'},
|
|
||||||
{code: 'NZ', continent: 'Oceania', name: 'New Zealand', region: 'Australia and New Zealand', type: 'sovereign'},
|
|
||||||
{code: 'NI', continent: 'North America', name: 'Nicaragua', region: 'Central America', type: 'sovereign'},
|
|
||||||
{code: 'NE', continent: 'Africa', name: 'Niger', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'NG', continent: 'Africa', name: 'Nigeria', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'KP', continent: 'Asia', name: 'North Korea', region: 'Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'NO', continent: 'Europe', name: 'Norway', region: 'Northern Europe', type: 'sovereign'},
|
|
||||||
{code: 'OM', continent: 'Asia', name: 'Oman', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'PK', continent: 'Asia', name: 'Pakistan', region: 'Southern Asia', type: 'sovereign'},
|
|
||||||
{code: 'PW', continent: 'Oceania', name: 'Palau', region: 'Micronesia', type: 'sovereign'},
|
|
||||||
{code: 'PA', continent: 'North America', name: 'Panama', region: 'Central America', type: 'sovereign'},
|
|
||||||
{code: 'PG', continent: 'Oceania', name: 'Papua New Guinea', region: 'Melanesia', type: 'sovereign'},
|
|
||||||
{code: 'PY', continent: 'South America', name: 'Paraguay', type: 'sovereign'},
|
|
||||||
{code: 'PE', continent: 'South America', name: 'Peru', type: 'sovereign'},
|
|
||||||
{code: 'PH', continent: 'Asia', name: 'Philippines', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'PL', continent: 'Europe', name: 'Poland', region: 'Eastern Europe', type: 'sovereign'},
|
|
||||||
{code: 'PT', continent: 'Europe', name: 'Portugal', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'QA', continent: 'Asia', name: 'Qatar', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'CD', continent: 'Africa', name: 'Republic of the Congo', region: 'Middle Africa', type: 'sovereign'},
|
|
||||||
{code: 'RO', continent: 'Europe', name: 'Romania', region: 'Eastern Europe', type: 'sovereign'},
|
|
||||||
{code: 'RU', continent: 'Europe', name: 'Russia', region: 'Eastern Europe', type: 'sovereign'},
|
|
||||||
{code: 'RW', continent: 'Africa', name: 'Rwanda', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'KN', continent: 'North America', name: 'Saint Kitts and Nevis', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'LC', continent: 'North America', name: 'Saint Lucia', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'VC', continent: 'North America', name: 'Saint Vincent and the Grenadines', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'WS', continent: 'Oceania', name: 'Samoa', region: 'Polynesia', type: 'sovereign'},
|
|
||||||
{code: 'SM', continent: 'Europe', name: 'San Marino', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'ST', continent: 'Africa', name: 'São Tomé and Príncipe', region: 'Middle Africa', type: 'sovereign'},
|
|
||||||
{code: 'SA', continent: 'Asia', name: 'Saudi Arabia', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'SN', continent: 'Africa', name: 'Senegal', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'RS', continent: 'Europe', name: 'Serbia', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'SC', continent: 'Africa', name: 'Seychelles', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'SL', continent: 'Africa', name: 'Sierra Leone', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'SG', continent: 'Asia', name: 'Singapore', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'SK', continent: 'Europe', name: 'Slovakia', region: 'Eastern Europe', type: 'sovereign'},
|
|
||||||
{code: 'SI', continent: 'Europe', name: 'Slovenia', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'SB', continent: 'Oceania', name: 'Solomon Islands', region: 'Melanesia', type: 'sovereign'},
|
|
||||||
{code: 'SO', continent: 'Africa', name: 'Somalia', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'ZA', continent: 'Africa', name: 'South Africa', region: 'Southern Africa', type: 'sovereign'},
|
|
||||||
{code: 'KR', continent: 'Asia', name: 'South Korea', region: 'Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'ES', continent: 'Europe', name: 'Spain', region: 'Southern Europe', type: 'sovereign'},
|
|
||||||
{code: 'LK', continent: 'Asia', name: 'Sri Lanka', region: 'Southern Asia', type: 'sovereign'},
|
|
||||||
{code: 'SD', continent: 'Africa', name: 'Sudan', region: 'Northern Africa', type: 'sovereign'},
|
|
||||||
{code: 'SR', continent: 'South America', name: 'Suriname', type: 'sovereign'},
|
|
||||||
{code: 'SZ', continent: 'Africa', name: 'Swaziland', region: 'Southern Africa', type: 'sovereign'},
|
|
||||||
{code: 'SE', continent: 'Europe', name: 'Sweden', region: 'Northern Europe', type: 'sovereign'},
|
|
||||||
{code: 'CH', continent: 'Europe', name: 'Switzerland', region: 'Western Europe', type: 'sovereign'},
|
|
||||||
{code: 'SY', continent: 'Asia', name: 'Syria', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'TJ', continent: 'Asia', name: 'Tajikistan', region: 'Central Asia', type: 'sovereign'},
|
|
||||||
{code: 'TZ', continent: 'Africa', name: 'Tanzania', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'TH', continent: 'Asia', name: 'Thailand', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'TL', continent: 'Asia', name: 'Timor-Leste', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'TG', continent: 'Africa', name: 'Togo', region: 'Western Africa', type: 'sovereign'},
|
|
||||||
{code: 'TO', continent: 'Oceania', name: 'Tonga', region: 'Polynesia', type: 'sovereign'},
|
|
||||||
{code: 'TT', continent: 'North America', name: 'Trinidad and Tobago', region: 'Caribbean', type: 'sovereign'},
|
|
||||||
{code: 'TN', continent: 'Africa', name: 'Tunisia', region: 'Northern Africa', type: 'sovereign'},
|
|
||||||
{code: 'TR', continent: 'Asia', name: 'Turkey', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'TM', continent: 'Asia', name: 'Turkmenistan', region: 'Central Asia', type: 'sovereign'},
|
|
||||||
{code: 'TV', continent: 'Oceania', name: 'Tuvalu', region: 'Polynesia', type: 'sovereign'},
|
|
||||||
{code: 'UG', continent: 'Africa', name: 'Uganda', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'UA', continent: 'Europe', name: 'Ukraine', region: 'Eastern Europe', type: 'sovereign'},
|
|
||||||
{code: 'AE', continent: 'Asia', name: 'United Arab Emirates', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'GB', continent: 'Europe', name: 'United Kingdom', region: 'Northern Europe', type: 'sovereign'},
|
|
||||||
{code: 'US', continent: 'North America', name: 'United States', region: 'Northern America', type: 'sovereign'},
|
|
||||||
{code: 'UY', continent: 'South America', name: 'Uruguay', type: 'sovereign'},
|
|
||||||
{code: 'UZ', continent: 'Asia', name: 'Uzbekistan', region: 'Central Asia', type: 'sovereign'},
|
|
||||||
{code: 'VU', continent: 'Oceania', name: 'Vanuatu', region: 'Melanesia', type: 'sovereign'},
|
|
||||||
{code: 'VE', continent: 'South America', name: 'Venezuela', type: 'sovereign'},
|
|
||||||
{code: 'VN', continent: 'Asia', name: 'Vietnam', region: 'South-Eastern Asia', type: 'sovereign'},
|
|
||||||
{code: 'YE', continent: 'Asia', name: 'Yemen', region: 'Western Asia', type: 'sovereign'},
|
|
||||||
{code: 'ZM', continent: 'Africa', name: 'Zambia', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'ZW', continent: 'Africa', name: 'Zimbabwe', region: 'Eastern Africa', type: 'sovereign'},
|
|
||||||
{code: 'GE-AB', continent: 'Asia', name: 'Abkhazia', region: 'Western Asia', type: 'unrecognized'},
|
|
||||||
{code: 'RS-KO', continent: 'Europe', name: 'Kosovo', region: 'Southern Europe', type: 'unrecognized'},
|
|
||||||
{code: 'AZ-NK', continent: 'Asia', name: 'Nagorno-Karabakh', region: 'Western Asia', type: 'unrecognized'},
|
|
||||||
{code: 'CY-NC', continent: 'Asia', name: 'Northern Cyprus', region: 'Western Asia', type: 'unrecognized'},
|
|
||||||
{code: 'PS', continent: 'Asia', name: 'Palestine', region: 'Western Asia', region: 'Western Asia', type: 'unrecognized'},
|
|
||||||
{code: 'EH', continent: 'Aftica', name: 'Sahrawi', region: 'Northern Africa', type: 'unrecognized'},
|
|
||||||
{code: 'SO-SO', continent: 'Africa', name: 'Somaliland', region: 'Eastern Aftica', type: 'unrecognized'},
|
|
||||||
{code: 'GE-SO', continent: 'Asia', name: 'South Ossetia', region: 'Western Asia', type: 'unrecognized'},
|
|
||||||
{code: 'SD-SS', continent: 'Aftica', name: 'South Sudan', region: 'Northern Africa', type: 'unrecognized'},
|
|
||||||
{code: 'TW', continent: 'Asia', name: 'Taiwan', region: 'Eastern Asia', type: 'unrecognized'},
|
|
||||||
{code: 'MD-TR', continent: 'Europe', name: 'Transnistria', region: 'Eastern Europe', type: 'unrecognized'},
|
|
||||||
{code: 'AQ', continent: 'Antarctica', country: ['Argentina', 'Australia', 'Chile', 'France', 'New Zealand', 'Norway', 'United Kingdom'], name: 'Antarctica'},
|
|
||||||
{code: 'AU-AC', continent: 'Asia', country: 'Australia', name: 'Ashmore and Cartier Islands', type: 'dependent'},
|
|
||||||
{code: 'CX', continent: 'Asia', country: 'Australia', name: 'Christmas Island', region: 'South-Eastern Asia', type: 'dependent'},
|
|
||||||
{code: 'CC', continent: 'Asia', country: 'Australia', name: 'Cocos Islands', region: 'South-Eastern Asia', type: 'dependent'},
|
|
||||||
{code: 'AU-CS', continent: 'Oceania', country: 'Australia', name: 'Coral Sea Islands', type: 'dependent'},
|
|
||||||
{code: 'HM', continent: 'Antarctica', country: 'Australia', name: 'Heard Island and McDonald Islands', type: 'dependent'},
|
|
||||||
{code: 'NF', continent: 'Oceania', country: 'Australia', name: 'Norfolk Island', region: 'Australia and New Zealand', type: 'dependent'},
|
|
||||||
{code: 'HK', continent: 'Asia', country: 'China', name: 'Hong Kong', region: 'Eastern Asia', type: 'dependent'},
|
|
||||||
{code: 'MO', continent: 'Asia', country: 'China', name: 'Macau', region: 'Eastern Asia', type: 'dependent'},
|
|
||||||
{code: 'FO', continent: 'Europe', country: 'Denmark', name: 'Faroe Islands', region: 'Northern Europe', type: 'dependent'},
|
|
||||||
{code: 'GL', continent: 'North America', country: 'Denmark', name: 'Greenland', region: 'Northern America', type: 'dependent'},
|
|
||||||
{code: 'AX', continent: 'Europe', country: 'Finland', name: 'Åland', region: 'Northern Europe', type: 'dependent'},
|
|
||||||
{code: 'CP', country: 'France', name: 'Clipperton Island', type: 'dependent'},
|
|
||||||
{code: 'GF', continent: 'South America', country: 'France', name: 'French Guiana', type: 'dependent'},
|
|
||||||
{code: 'PF', continent: 'Oceania', country: 'France', name: 'French Polynesia', region: 'Polynesia', type: 'dependent'},
|
|
||||||
{code: 'TF', country: 'France', name: 'French Southern Territories', type: 'dependent'},
|
|
||||||
{code: 'GP', continent: 'North America', country: 'France', name: 'Guadeloupe', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'MQ', continent: 'North America', country: 'France', name: 'Martinique', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'YT', continent: 'Africa', country: 'France', name: 'Mayotte', region: 'Eastern Africa', type: 'dependent'},
|
|
||||||
{code: 'NC', continent: 'Oceania', country: 'France', name: 'New Caledonia', region: 'Melanesia', type: 'dependent'},
|
|
||||||
{code: 'RE', continent: 'Africa', country: 'France', name: 'Réunion', region: 'Eastern Africa', type: 'dependent', flag: 'png'},
|
|
||||||
{code: 'BL', continent: 'North America', country: 'France', name: 'Saint Barthélemy', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'MF', continent: 'North America', country: 'France', name: 'Saint Martin', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'PM', continent: 'North America', country: 'France', name: 'Saint Pierre and Miquelon', region: 'Northern America', type: 'dependent'},
|
|
||||||
{code: 'WF', continent: 'Oceania', country: 'France', name: 'Wallis and Futuna', region: 'Polynesia', type: 'dependent'},
|
|
||||||
{code: 'AW', continent: 'North America', country: 'Netherlands', name: 'Aruba', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'BQ', continent: 'North America', country: 'Netherlands', name: 'Bonaire, Saint Eustatius and Saba', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'CW', continent: 'North America', country: 'Netherlands', name: 'Curaçao', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'SX', continent: 'North America', country: 'Netherlands', name: 'Sint Maarten', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'CK', continent: 'Oceania', country: 'New Zealand', name: 'Cook Islands', region: 'Polynesia', type: 'dependent'},
|
|
||||||
{code: 'NU', continent: 'Oceania', country: 'New Zealand', name: 'Niue', region: 'Polynesia', type: 'dependent'},
|
|
||||||
{code: 'TK', continent: 'Oceania', country: 'New Zealand', name: 'Tokelau', region: 'Polynesia', type: 'dependent'},
|
|
||||||
{code: 'BV', continent: 'Antarctica', country: 'Norway', name: 'Bouvet Island', type: 'dependent'},
|
|
||||||
{code: 'SJ', continent: 'Europe', country: 'Norway', name: 'Svalbard and Jan Mayen', region: 'Northern Europe', type: 'dependent'},
|
|
||||||
{code: 'IC', continent: 'Africa', country: 'Spain', name: 'Canary Islands', region: 'Northern Africa', type: 'dependent'},
|
|
||||||
{code: 'EA', continent: 'Africa', country: 'Spain', name: 'Ceuta and Melilla', region: 'Northern Africa', type: 'dependent'},
|
|
||||||
{code: 'AI', continent: 'North America', country: 'United Kingdom', name: 'Anguilla', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'AC', continent: 'Africa', country: 'United Kingdom', name: 'Ascension', region: 'Western Africa', type: 'dependent'},
|
|
||||||
{code: 'BM', continent: 'North America', country: 'United Kingdom', name: 'Bermuda', region: 'Northern America', type: 'dependent'},
|
|
||||||
{code: 'IO', country: 'United Kingdom', name: 'British Indian Ocean Territory', type: 'dependent'},
|
|
||||||
{code: 'VG', continent: 'North America', country: 'United Kingdom', name: 'British Virgin Islands', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'KY', continent: 'North America', country: 'United Kingdom', name: 'Cayman Islands', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'DG', country: 'United Kingdom', name: 'Diego Garcia', type: 'dependent'},
|
|
||||||
{code: 'GB-ENG', continent: 'Europe', country: 'United Kingdom', name: 'England', region: 'Northern Europe', type: 'dependent'},
|
|
||||||
{code: 'FK', continent: 'South America', country: 'United Kingdom', name: 'Falkland Islands', type: 'dependent'},
|
|
||||||
{code: 'GI', continent: 'Europe', country: 'United Kingdom', name: 'Gibraltar', region: 'Southern Europe', type: 'dependent'},
|
|
||||||
{code: 'GG', continent: 'Europe', country: 'United Kingdom', name: 'Guernsey', region: 'Northern Europe', type: 'dependent'},
|
|
||||||
{code: 'IM', continent: 'Europe', country: 'United Kingdom', name: 'Isle of Man', region: 'Northern Europe', type: 'dependent'},
|
|
||||||
{code: 'JE', continent: 'Europe', country: 'United Kingdom', name: 'Jersey', region: 'Northern Europe', type: 'dependent'},
|
|
||||||
{code: 'MS', continent: 'North America', country: 'United Kingdom', name: 'Montserrat', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'GB-NIR', continent: 'Europe', country: 'United Kingdom', name: 'Northern Ireland', region: 'Northern Europe', type: 'dependent'},
|
|
||||||
{code: 'PN', continent: 'Oceania', country: 'United Kingdom', name: 'Pitcairn', region: 'Polynesia', type: 'dependent'},
|
|
||||||
{code: 'SH', continent: 'Africa', country: 'United Kingdom', name: 'Saint Helena', region: 'Western Africa', type: 'dependent'},
|
|
||||||
{code: 'GB-SCT', continent: 'Europe', country: 'United Kingdom', name: 'Scotland', region: 'Northern Europe', type: 'dependent'},
|
|
||||||
{code: 'GS', continent: 'South America', country: 'United Kingdom', name: 'South Georgia and the South Sandwich Islands', type: 'dependent'},
|
|
||||||
{code: 'TA', continent: 'Africa', country: 'United Kingdom', name: 'Tristan da Cunha', region: 'Western Africa', type: 'dependent'},
|
|
||||||
{code: 'TC', continent: 'Oceania', country: 'United Kingdom', name: 'Turks and Caicos Islands', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'GB-WLS', continent: 'Europe', country: 'United Kingdom', name: 'Wales', region: 'Northern Europe', type: 'dependent'},
|
|
||||||
{code: 'AS', continent: 'Oceania', country: 'United States', name: 'American Samoa', region: 'Polynesia', type: 'dependent'},
|
|
||||||
{code: 'GU', continent: 'Oceania', country: 'United States', name: 'Guam', region: 'Micronesia', type: 'dependent'},
|
|
||||||
{code: 'MP', continent: 'Oceania', country: 'United States', name: 'Northern Mariana Islands', region: 'Micronesia', type: 'dependent'},
|
|
||||||
{code: 'PR', continent: 'North America', country: 'United States', name: 'Puerto Rico', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'UM', country: 'United States', name: 'United States Minor Outlying Islands', type: 'dependent'},
|
|
||||||
{code: 'VI', continent: 'North America', country: 'United States', name: 'United States Virgin Islands', region: 'Caribbean', type: 'dependent'},
|
|
||||||
{code: 'BUMM', continent: 'Asia', name: 'Burma', region: 'South-Eastern Asia', type: 'former'},
|
|
||||||
{code: 'BYAA', continent: 'Europe', name: 'Byelorussian Soviet Socialist Republic', region: 'Eastern Europe', type: 'former'},
|
|
||||||
{code: 'CTKI', continent: 'Oceania', name: 'Canton and Enderbury Islands', region: 'Micronesia', type: 'former'},
|
|
||||||
{code: 'CSHH', continent: 'Europe', name: 'Czechoslovakia', region: 'Eastern Europe', type: 'former'},
|
|
||||||
{code: 'DYBJ', continent: 'Africa', name: 'Dahomey', region: 'Western Africa', type: 'former'},
|
|
||||||
{code: 'TPTL', continent: 'Asia', name: 'East Timor', region: 'South-Eastern Asia', type: 'former'},
|
|
||||||
{code: 'DDDE', continent: 'Europe', name: 'East Germany', region: 'Eastern Europe', type: 'former'},
|
|
||||||
{code: 'GEHH', name: 'Gilbert and Ellice Islands', type: 'former'},
|
|
||||||
{code: 'KOHH', continent: 'Asia', name: 'Korea', region: 'Eastern Asia', type: 'former'},
|
|
||||||
{code: 'NTHH', continent: 'Asia', name: 'Neutral Zone', region: 'Western Asia', type: 'former'},
|
|
||||||
{code: 'VDVN', continent: 'Asia', name: 'North Vietnam', region: 'South-Eastern Asia', type: 'former'},
|
|
||||||
{code: 'RHZW', continent: 'Africa', name: 'Rhodesia', region: 'Eastern Africa', type: 'former'},
|
|
||||||
{code: 'CSXX', continent: 'Europe', name: 'Serbia and Montenegro', type: 'former'},
|
|
||||||
{code: 'SITH', continent: 'Asia', name: 'Siam', region: 'South-Eastern Asia', type: 'former'},
|
|
||||||
{code: 'SKIN', continent: 'Asia', name: 'Sikkim', region: 'Southern Asia', type: 'former'},
|
|
||||||
{code: 'YDYE', continent: 'Asia', name: 'South Yemen', region: 'Western Asia', type: 'former'},
|
|
||||||
{code: 'SUHH', continent: 'Europe', name: 'Soviet Union', region: 'Eastern Europe', type: 'former'},
|
|
||||||
{code: 'HVBF', continent: 'Africa', name: 'Upper Volta', region: 'Western Africa', type: 'former'},
|
|
||||||
{code: 'DEDE', continent: 'Europe', name: 'West Germany', region: 'Western Europe', type: 'former'},
|
|
||||||
{code: 'YUCS', continent: 'Europe', name: 'Yugoslavia', region: 'Southern Europe', type: 'former'},
|
|
||||||
{code: 'ZRCD', continent: 'Africa', name: 'Zaire', region: 'Middle Africa', type: 'former'},
|
|
||||||
{code: 'AIDJ', continent: 'Africa', country: 'France', name: 'French Afar and Issas', region: 'Eastern Africa', type: 'former'},
|
|
||||||
{code: 'FQHH', continent: 'Antarctica', country: 'France', name: 'French Southern and Antarctic Territories', type: 'former'},
|
|
||||||
{code: 'FXFR', continent: 'Europe', country: 'France', name: 'Metropolitan France', type: 'former'},
|
|
||||||
{code: 'NHVU', country: ['France', 'United Kingdom'], name: 'New Hebrides', region: 'Melanesia', type: 'former'},
|
|
||||||
{code: 'ANHH', continent: 'North America', country: 'Netherlands', name: 'Netherlands Antilles', region: 'Caribbean', type: 'former'},
|
|
||||||
{code: 'NQAQ', continent: 'Antarctica', country: 'Norway', name: 'Dronning Maud Land', type: 'former'},
|
|
||||||
{code: 'BQAQ', continent: 'Antarctica', country: 'United Kingdom', name: 'British Antarctic Territory', type: 'former'},
|
|
||||||
{code: 'JTUM', continent: 'Oceania', country: 'United States', name: 'Johnston Island', region: 'Mictonesia', type: 'former'},
|
|
||||||
{code: 'MIUM', continent: 'Oceania', country: 'United States', name: 'Midway Islands', type: 'former'},
|
|
||||||
{code: 'PCHH', continent: 'Oceania', country: 'United States', name: 'Pacific Islands', region: 'Micronesia', type: 'former'},
|
|
||||||
{code: 'PZPA', continent: 'North America', country: 'United States', name: 'Panama Canal Zone', region: 'Central America', type: 'former', flag: 'png'},
|
|
||||||
{code: 'PUUM', continent: 'Oceania', country: 'United States', name: 'United States Miscellaneous Pacific Islands', type: 'former'},
|
|
||||||
{code: 'WKUM', continent: 'Oceania', country: 'United States', name: 'Wake Island', region: 'Micronesia', type: 'former'},
|
|
||||||
{code: 'EU', continent: 'Europe', name: 'European Union', type: 'other'},
|
|
||||||
{code: 'UK', continent: 'Europe', name: 'United Kingdom', region: 'Northern Europe', type: 'other'}
|
|
||||||
];
|
|
||||||
|
|
||||||
Ox.COUNTRY_CODES = Ox.map(Ox.COUNTRIES, function(country) {
|
|
||||||
return country.code.length == 2 && ['EU', 'UK'].indexOf(country.code) == -1 ? country.code : null;
|
|
||||||
}).sort();
|
|
||||||
|
|
||||||
Ox.getCountryCode = (function() {
|
|
||||||
var aliases = {
|
|
||||||
'Cocos (Keeling) Islands': 'Cocos Islands',
|
|
||||||
'Congo': 'Republic of the Congo',
|
|
||||||
'French Southern and Antarctic Lands': 'French Southern Territories',
|
|
||||||
'Macedonia (FYROM)': 'Macedonia',
|
|
||||||
'Pitcairn Islands': 'Pitcairn',
|
|
||||||
'Reunion': 'Réunion',
|
|
||||||
'St Barthélemy': 'Saint Barthélemy',
|
|
||||||
'St Helena': 'Saint Helena',
|
|
||||||
'St Kitts and Nevis': 'Saint Kitts and Nevis',
|
|
||||||
'St Lucia': 'Saint Lucia',
|
|
||||||
'St Pierre and Miquelon': 'Saint Pierre and Miquelon',
|
|
||||||
'St Vincent and the Grenadines': 'Saint Vincent and the Grenadines',
|
|
||||||
'The Bahamas': 'Bahamas',
|
|
||||||
'The Gambia': 'Gambia',
|
|
||||||
'The Netherlands': 'Netherlands',
|
|
||||||
'Trinidad & Tobago': 'Trinidad and Tobago',
|
|
||||||
'UK': 'United Kingdom',
|
|
||||||
'US Virgin Islands': 'United States Virgin Islands',
|
|
||||||
'USA': 'United States',
|
|
||||||
'Western Sahara': 'Sahrawi'
|
|
||||||
};
|
|
||||||
return function(geoname) {
|
|
||||||
var countryCode = '',
|
|
||||||
countryName = geoname.split(', ').pop();
|
|
||||||
Ox.forEach(aliases, function(val, key) {
|
|
||||||
if (countryName == key) {
|
|
||||||
countryName = val;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Ox.forEach(Ox.COUNTRIES, function(country) {
|
|
||||||
if (country.name == countryName) {
|
|
||||||
countryCode = country.code;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return countryCode;
|
|
||||||
};
|
|
||||||
}());
|
|
|
@ -1,57 +0,0 @@
|
||||||
onmessage = function(e) {
|
|
||||||
if (e.data.message) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function encode() {
|
|
||||||
str = Ox.encodeUTF8(str);
|
|
||||||
var c = Ox.canvas(img), len = str.length;
|
|
||||||
if (len > maxLength(img.width, img.height)) {
|
|
||||||
throw new RangeError("PNG codec can't encode " + len +
|
|
||||||
" bytes into " + (img.width * img.height) + " pixels");
|
|
||||||
}
|
|
||||||
len = Ox.pad(Ox.encodeBase256(len), 4, Ox.char(0));
|
|
||||||
Ox.each(Ox.map(len + str, function(byte) {
|
|
||||||
return Ox.map(new Array(8), function(v, i) {
|
|
||||||
return byte.charCodeAt(0) >> 7 - i & 1;
|
|
||||||
}).join("");
|
|
||||||
}).join(""), function(i, bit) {
|
|
||||||
var index, byte = c.data[index = parseInt(i * 4/3)];
|
|
||||||
c.data[index] = bit == xor(byte) ? byte :
|
|
||||||
byte & 254 | !(byte & 1);
|
|
||||||
});
|
|
||||||
c.context.putImageData(c.imageData, 0, 0);
|
|
||||||
postMessage(c.canvas.toDataURL());
|
|
||||||
}
|
|
||||||
|
|
||||||
function decode() {
|
|
||||||
var c = Ox.canvas(img), bits = "", str = "", i = 0; len = 4, flag = false;
|
|
||||||
do {
|
|
||||||
bits += xor(c.data[parseInt(i * 4/3)]);
|
|
||||||
if (++i % 8 == 0) {
|
|
||||||
str += Ox.char(parseInt(bits, 2));
|
|
||||||
bits = "";
|
|
||||||
len--;
|
|
||||||
if (len == 0 && !flag) {
|
|
||||||
if ((len = Ox.decodeBase256(str)) >
|
|
||||||
maxLength(img.width, img.height)) {
|
|
||||||
throwPNGError();
|
|
||||||
}
|
|
||||||
str = "";
|
|
||||||
flag = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (len);
|
|
||||||
try {
|
|
||||||
return Ox.decodeUTF8(str);
|
|
||||||
} catch(e) {
|
|
||||||
throwPNGError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function throwError() {
|
|
||||||
throw new RangeError("PNG codec can't decode image");
|
|
||||||
}
|
|
16019
build/js/ox.ui.js
|
@ -1,442 +0,0 @@
|
||||||
[
|
|
||||||
"png/ox.map/marker.png",
|
|
||||||
"png/ox.map/markerEditing.png",
|
|
||||||
"png/ox.map/markerResize.png",
|
|
||||||
"png/ox.map/markerResult.png",
|
|
||||||
"png/ox.map/markerResultEditing.png",
|
|
||||||
"png/ox.map/markerResultSelected.png",
|
|
||||||
"png/ox.map/markerSelected.png",
|
|
||||||
"png/ox.ui/browserChrome128.png",
|
|
||||||
"png/ox.ui/browserFirefox128.png",
|
|
||||||
"png/ox.ui/browserInternetExplorer128.png",
|
|
||||||
"png/ox.ui/browserOpera128.png",
|
|
||||||
"png/ox.ui/browserSafari128.png",
|
|
||||||
"png/ox.ui/icon16.png",
|
|
||||||
"png/ox.ui/transparent.png",
|
|
||||||
"png/ox.ui/videoMarkerCut.png",
|
|
||||||
"png/ox.ui/videoMarkerIn.png",
|
|
||||||
"png/ox.ui/videoMarkerInBottom.png",
|
|
||||||
"png/ox.ui/videoMarkerInTop.png",
|
|
||||||
"png/ox.ui/videoMarkerOut.png",
|
|
||||||
"png/ox.ui/videoMarkerOutBottom.png",
|
|
||||||
"png/ox.ui/videoMarkerOutTop.png",
|
|
||||||
"png/ox.ui/videoMarkerPlay.png",
|
|
||||||
"png/ox.ui.classic/scrollbarHorizontalDecrement.png",
|
|
||||||
"png/ox.ui.classic/scrollbarHorizontalIncrement.png",
|
|
||||||
"png/ox.ui.classic/scrollbarVerticalDecrement.png",
|
|
||||||
"png/ox.ui.classic/scrollbarVerticalIncrement.png",
|
|
||||||
"png/ox.ui.modern/scrollbarHorizontalDecrement.png",
|
|
||||||
"png/ox.ui.modern/scrollbarHorizontalIncrement.png",
|
|
||||||
"png/ox.ui.modern/scrollbarVerticalDecrement.png",
|
|
||||||
"png/ox.ui.modern/scrollbarVerticalIncrement.png",
|
|
||||||
"svg/ox.map/AC.svg",
|
|
||||||
"svg/ox.map/AD.svg",
|
|
||||||
"svg/ox.map/AE.svg",
|
|
||||||
"svg/ox.map/AF.svg",
|
|
||||||
"svg/ox.map/AG.svg",
|
|
||||||
"svg/ox.map/AI.svg",
|
|
||||||
"svg/ox.map/AIDJ.svg",
|
|
||||||
"svg/ox.map/AL.svg",
|
|
||||||
"svg/ox.map/AM.svg",
|
|
||||||
"svg/ox.map/ANHH.svg",
|
|
||||||
"svg/ox.map/AO.svg",
|
|
||||||
"svg/ox.map/AQ.svg",
|
|
||||||
"svg/ox.map/AR.svg",
|
|
||||||
"svg/ox.map/AS.svg",
|
|
||||||
"svg/ox.map/AT.svg",
|
|
||||||
"svg/ox.map/AU-AC.svg",
|
|
||||||
"svg/ox.map/AU-CS.svg",
|
|
||||||
"svg/ox.map/AU.svg",
|
|
||||||
"svg/ox.map/AW.svg",
|
|
||||||
"svg/ox.map/AX.svg",
|
|
||||||
"svg/ox.map/AZ-NK.svg",
|
|
||||||
"svg/ox.map/AZ.svg",
|
|
||||||
"svg/ox.map/BA.svg",
|
|
||||||
"svg/ox.map/BB.svg",
|
|
||||||
"svg/ox.map/BD.svg",
|
|
||||||
"svg/ox.map/BE.svg",
|
|
||||||
"svg/ox.map/BF.svg",
|
|
||||||
"svg/ox.map/BG.svg",
|
|
||||||
"svg/ox.map/BH.svg",
|
|
||||||
"svg/ox.map/BI.svg",
|
|
||||||
"svg/ox.map/BJ.svg",
|
|
||||||
"svg/ox.map/BL.svg",
|
|
||||||
"svg/ox.map/BM.svg",
|
|
||||||
"svg/ox.map/BN.svg",
|
|
||||||
"svg/ox.map/BO.svg",
|
|
||||||
"svg/ox.map/BQ.svg",
|
|
||||||
"svg/ox.map/BQAQ.svg",
|
|
||||||
"svg/ox.map/BR.svg",
|
|
||||||
"svg/ox.map/BS.svg",
|
|
||||||
"svg/ox.map/BT.svg",
|
|
||||||
"svg/ox.map/BUMM.svg",
|
|
||||||
"svg/ox.map/BV.svg",
|
|
||||||
"svg/ox.map/BW.svg",
|
|
||||||
"svg/ox.map/BY.svg",
|
|
||||||
"svg/ox.map/BYAA.svg",
|
|
||||||
"svg/ox.map/BZ.svg",
|
|
||||||
"svg/ox.map/CA.svg",
|
|
||||||
"svg/ox.map/CC.svg",
|
|
||||||
"svg/ox.map/CD.svg",
|
|
||||||
"svg/ox.map/CF.svg",
|
|
||||||
"svg/ox.map/CG.svg",
|
|
||||||
"svg/ox.map/CH.svg",
|
|
||||||
"svg/ox.map/CI.svg",
|
|
||||||
"svg/ox.map/CK.svg",
|
|
||||||
"svg/ox.map/CL.svg",
|
|
||||||
"svg/ox.map/CM.svg",
|
|
||||||
"svg/ox.map/CN.svg",
|
|
||||||
"svg/ox.map/CO.svg",
|
|
||||||
"svg/ox.map/CP.svg",
|
|
||||||
"svg/ox.map/CR.svg",
|
|
||||||
"svg/ox.map/CSHH.svg",
|
|
||||||
"svg/ox.map/CSXX.svg",
|
|
||||||
"svg/ox.map/CTKI.svg",
|
|
||||||
"svg/ox.map/CU.svg",
|
|
||||||
"svg/ox.map/CV.svg",
|
|
||||||
"svg/ox.map/CW.svg",
|
|
||||||
"svg/ox.map/CX.svg",
|
|
||||||
"svg/ox.map/CY-NC.svg",
|
|
||||||
"svg/ox.map/CY.svg",
|
|
||||||
"svg/ox.map/CZ.svg",
|
|
||||||
"svg/ox.map/DDDE.svg",
|
|
||||||
"svg/ox.map/DE.svg",
|
|
||||||
"svg/ox.map/DEDE.svg",
|
|
||||||
"svg/ox.map/DG.svg",
|
|
||||||
"svg/ox.map/DJ.svg",
|
|
||||||
"svg/ox.map/DK.svg",
|
|
||||||
"svg/ox.map/DM.svg",
|
|
||||||
"svg/ox.map/DO.svg",
|
|
||||||
"svg/ox.map/DYBJ.svg",
|
|
||||||
"svg/ox.map/DZ.svg",
|
|
||||||
"svg/ox.map/EA.svg",
|
|
||||||
"svg/ox.map/EC.svg",
|
|
||||||
"svg/ox.map/EE.svg",
|
|
||||||
"svg/ox.map/EG.svg",
|
|
||||||
"svg/ox.map/EH.svg",
|
|
||||||
"svg/ox.map/ER.svg",
|
|
||||||
"svg/ox.map/ES.svg",
|
|
||||||
"svg/ox.map/ET.svg",
|
|
||||||
"svg/ox.map/EU.svg",
|
|
||||||
"svg/ox.map/FI.svg",
|
|
||||||
"svg/ox.map/FJ.svg",
|
|
||||||
"svg/ox.map/FK.svg",
|
|
||||||
"svg/ox.map/FM.svg",
|
|
||||||
"svg/ox.map/FO.svg",
|
|
||||||
"svg/ox.map/FQHH.svg",
|
|
||||||
"svg/ox.map/FR.svg",
|
|
||||||
"svg/ox.map/FXFR.svg",
|
|
||||||
"svg/ox.map/GA.svg",
|
|
||||||
"svg/ox.map/GB-ENG.svg",
|
|
||||||
"svg/ox.map/GB-NIR.svg",
|
|
||||||
"svg/ox.map/GB-SCT.svg",
|
|
||||||
"svg/ox.map/GB-WLS.svg",
|
|
||||||
"svg/ox.map/GB.svg",
|
|
||||||
"svg/ox.map/GD.svg",
|
|
||||||
"svg/ox.map/GE-AB.svg",
|
|
||||||
"svg/ox.map/GE-SO.svg",
|
|
||||||
"svg/ox.map/GE.svg",
|
|
||||||
"svg/ox.map/GEHH.svg",
|
|
||||||
"svg/ox.map/GF.svg",
|
|
||||||
"svg/ox.map/GG.svg",
|
|
||||||
"svg/ox.map/GH.svg",
|
|
||||||
"svg/ox.map/GI.svg",
|
|
||||||
"svg/ox.map/GL.svg",
|
|
||||||
"svg/ox.map/GM.svg",
|
|
||||||
"svg/ox.map/GN.svg",
|
|
||||||
"svg/ox.map/GP.svg",
|
|
||||||
"svg/ox.map/GQ.svg",
|
|
||||||
"svg/ox.map/GR.svg",
|
|
||||||
"svg/ox.map/GS.svg",
|
|
||||||
"svg/ox.map/GT.svg",
|
|
||||||
"svg/ox.map/GU.svg",
|
|
||||||
"svg/ox.map/GW.svg",
|
|
||||||
"svg/ox.map/GY.svg",
|
|
||||||
"svg/ox.map/HK.svg",
|
|
||||||
"svg/ox.map/HM.svg",
|
|
||||||
"svg/ox.map/HN.svg",
|
|
||||||
"svg/ox.map/HR.svg",
|
|
||||||
"svg/ox.map/HT.svg",
|
|
||||||
"svg/ox.map/HU.svg",
|
|
||||||
"svg/ox.map/HVBF.svg",
|
|
||||||
"svg/ox.map/IC.svg",
|
|
||||||
"svg/ox.map/ID.svg",
|
|
||||||
"svg/ox.map/IE.svg",
|
|
||||||
"svg/ox.map/IL.svg",
|
|
||||||
"svg/ox.map/IM.svg",
|
|
||||||
"svg/ox.map/IN.svg",
|
|
||||||
"svg/ox.map/IO.svg",
|
|
||||||
"svg/ox.map/IQ.svg",
|
|
||||||
"svg/ox.map/IR.svg",
|
|
||||||
"svg/ox.map/IS.svg",
|
|
||||||
"svg/ox.map/IT.svg",
|
|
||||||
"svg/ox.map/JE.svg",
|
|
||||||
"svg/ox.map/JM.svg",
|
|
||||||
"svg/ox.map/JO.svg",
|
|
||||||
"svg/ox.map/JP.svg",
|
|
||||||
"svg/ox.map/JTUM.svg",
|
|
||||||
"svg/ox.map/KE.svg",
|
|
||||||
"svg/ox.map/KG.svg",
|
|
||||||
"svg/ox.map/KH.svg",
|
|
||||||
"svg/ox.map/KI.svg",
|
|
||||||
"svg/ox.map/KM.svg",
|
|
||||||
"svg/ox.map/KN.svg",
|
|
||||||
"svg/ox.map/KOHH.svg",
|
|
||||||
"svg/ox.map/KP.svg",
|
|
||||||
"svg/ox.map/KR.svg",
|
|
||||||
"svg/ox.map/KW.svg",
|
|
||||||
"svg/ox.map/KY.svg",
|
|
||||||
"svg/ox.map/KZ.svg",
|
|
||||||
"svg/ox.map/LA.svg",
|
|
||||||
"svg/ox.map/LB.svg",
|
|
||||||
"svg/ox.map/LC.svg",
|
|
||||||
"svg/ox.map/LI.svg",
|
|
||||||
"svg/ox.map/LK.svg",
|
|
||||||
"svg/ox.map/LR.svg",
|
|
||||||
"svg/ox.map/LS.svg",
|
|
||||||
"svg/ox.map/LT.svg",
|
|
||||||
"svg/ox.map/LU.svg",
|
|
||||||
"svg/ox.map/LV.svg",
|
|
||||||
"svg/ox.map/LY.svg",
|
|
||||||
"svg/ox.map/MA.svg",
|
|
||||||
"svg/ox.map/MC.svg",
|
|
||||||
"svg/ox.map/MD-TR.svg",
|
|
||||||
"svg/ox.map/MD.svg",
|
|
||||||
"svg/ox.map/ME.svg",
|
|
||||||
"svg/ox.map/MF.svg",
|
|
||||||
"svg/ox.map/MG.svg",
|
|
||||||
"svg/ox.map/MH.svg",
|
|
||||||
"svg/ox.map/MIUM.svg",
|
|
||||||
"svg/ox.map/MK.svg",
|
|
||||||
"svg/ox.map/ML.svg",
|
|
||||||
"svg/ox.map/MM.svg",
|
|
||||||
"svg/ox.map/MN.svg",
|
|
||||||
"svg/ox.map/MO.svg",
|
|
||||||
"svg/ox.map/MP.svg",
|
|
||||||
"svg/ox.map/MQ.svg",
|
|
||||||
"svg/ox.map/MR.svg",
|
|
||||||
"svg/ox.map/MS.svg",
|
|
||||||
"svg/ox.map/MT.svg",
|
|
||||||
"svg/ox.map/MU.svg",
|
|
||||||
"svg/ox.map/MV.svg",
|
|
||||||
"svg/ox.map/MW.svg",
|
|
||||||
"svg/ox.map/MX.svg",
|
|
||||||
"svg/ox.map/MY.svg",
|
|
||||||
"svg/ox.map/MZ.svg",
|
|
||||||
"svg/ox.map/NA.svg",
|
|
||||||
"svg/ox.map/NC.svg",
|
|
||||||
"svg/ox.map/NE.svg",
|
|
||||||
"svg/ox.map/NF.svg",
|
|
||||||
"svg/ox.map/NG.svg",
|
|
||||||
"svg/ox.map/NHVU.svg",
|
|
||||||
"svg/ox.map/NI.svg",
|
|
||||||
"svg/ox.map/NL.svg",
|
|
||||||
"svg/ox.map/NO.svg",
|
|
||||||
"svg/ox.map/NP.svg",
|
|
||||||
"svg/ox.map/NQAQ.svg",
|
|
||||||
"svg/ox.map/NR.svg",
|
|
||||||
"svg/ox.map/NTHH.svg",
|
|
||||||
"svg/ox.map/NU.svg",
|
|
||||||
"svg/ox.map/NZ.svg",
|
|
||||||
"svg/ox.map/OM.svg",
|
|
||||||
"svg/ox.map/PA.svg",
|
|
||||||
"svg/ox.map/PCHH.svg",
|
|
||||||
"svg/ox.map/PE.svg",
|
|
||||||
"svg/ox.map/PF.svg",
|
|
||||||
"svg/ox.map/PG.svg",
|
|
||||||
"svg/ox.map/PH.svg",
|
|
||||||
"svg/ox.map/PK.svg",
|
|
||||||
"svg/ox.map/PL.svg",
|
|
||||||
"svg/ox.map/PM.svg",
|
|
||||||
"svg/ox.map/PN.svg",
|
|
||||||
"svg/ox.map/PR.svg",
|
|
||||||
"svg/ox.map/PS.svg",
|
|
||||||
"svg/ox.map/PT.svg",
|
|
||||||
"svg/ox.map/PUUM.svg",
|
|
||||||
"svg/ox.map/PW.svg",
|
|
||||||
"svg/ox.map/PY.svg",
|
|
||||||
"svg/ox.map/PZPA.png",
|
|
||||||
"svg/ox.map/QA.svg",
|
|
||||||
"svg/ox.map/RE.png",
|
|
||||||
"svg/ox.map/RHZW.svg",
|
|
||||||
"svg/ox.map/RO.svg",
|
|
||||||
"svg/ox.map/RS-KO.svg",
|
|
||||||
"svg/ox.map/RS.svg",
|
|
||||||
"svg/ox.map/RU.svg",
|
|
||||||
"svg/ox.map/RW.svg",
|
|
||||||
"svg/ox.map/SA.svg",
|
|
||||||
"svg/ox.map/SB.svg",
|
|
||||||
"svg/ox.map/SC.svg",
|
|
||||||
"svg/ox.map/SD-SS.svg",
|
|
||||||
"svg/ox.map/SD.svg",
|
|
||||||
"svg/ox.map/SE.svg",
|
|
||||||
"svg/ox.map/SG.svg",
|
|
||||||
"svg/ox.map/SH.svg",
|
|
||||||
"svg/ox.map/SI.svg",
|
|
||||||
"svg/ox.map/SITH.svg",
|
|
||||||
"svg/ox.map/SJ.svg",
|
|
||||||
"svg/ox.map/SK.svg",
|
|
||||||
"svg/ox.map/SKIN.svg",
|
|
||||||
"svg/ox.map/SL.svg",
|
|
||||||
"svg/ox.map/SM.svg",
|
|
||||||
"svg/ox.map/SN.svg",
|
|
||||||
"svg/ox.map/SO-SO.svg",
|
|
||||||
"svg/ox.map/SO.svg",
|
|
||||||
"svg/ox.map/SR.svg",
|
|
||||||
"svg/ox.map/ST.svg",
|
|
||||||
"svg/ox.map/SUHH.svg",
|
|
||||||
"svg/ox.map/SV.svg",
|
|
||||||
"svg/ox.map/SX.svg",
|
|
||||||
"svg/ox.map/SY.svg",
|
|
||||||
"svg/ox.map/SZ.svg",
|
|
||||||
"svg/ox.map/TA.svg",
|
|
||||||
"svg/ox.map/TC.svg",
|
|
||||||
"svg/ox.map/TD.svg",
|
|
||||||
"svg/ox.map/TF.svg",
|
|
||||||
"svg/ox.map/TG.svg",
|
|
||||||
"svg/ox.map/TH.svg",
|
|
||||||
"svg/ox.map/TJ.svg",
|
|
||||||
"svg/ox.map/TK.svg",
|
|
||||||
"svg/ox.map/TL.svg",
|
|
||||||
"svg/ox.map/TM.svg",
|
|
||||||
"svg/ox.map/TN.svg",
|
|
||||||
"svg/ox.map/TO.svg",
|
|
||||||
"svg/ox.map/TPTL.svg",
|
|
||||||
"svg/ox.map/TR.svg",
|
|
||||||
"svg/ox.map/TT.svg",
|
|
||||||
"svg/ox.map/TV.svg",
|
|
||||||
"svg/ox.map/TW.svg",
|
|
||||||
"svg/ox.map/TZ.svg",
|
|
||||||
"svg/ox.map/UA.svg",
|
|
||||||
"svg/ox.map/UG.svg",
|
|
||||||
"svg/ox.map/UK.svg",
|
|
||||||
"svg/ox.map/UM.svg",
|
|
||||||
"svg/ox.map/US.svg",
|
|
||||||
"svg/ox.map/UY.svg",
|
|
||||||
"svg/ox.map/UZ.svg",
|
|
||||||
"svg/ox.map/VA.svg",
|
|
||||||
"svg/ox.map/VC.svg",
|
|
||||||
"svg/ox.map/VDVN.svg",
|
|
||||||
"svg/ox.map/VE.svg",
|
|
||||||
"svg/ox.map/VG.svg",
|
|
||||||
"svg/ox.map/VI.svg",
|
|
||||||
"svg/ox.map/VN.svg",
|
|
||||||
"svg/ox.map/VU.svg",
|
|
||||||
"svg/ox.map/WF.svg",
|
|
||||||
"svg/ox.map/WKUM.svg",
|
|
||||||
"svg/ox.map/WS.svg",
|
|
||||||
"svg/ox.map/YDYE.svg",
|
|
||||||
"svg/ox.map/YE.svg",
|
|
||||||
"svg/ox.map/YT.svg",
|
|
||||||
"svg/ox.map/YUCS.svg",
|
|
||||||
"svg/ox.map/ZA.svg",
|
|
||||||
"svg/ox.map/ZM.svg",
|
|
||||||
"svg/ox.map/ZRCD.svg",
|
|
||||||
"svg/ox.map/ZW.svg",
|
|
||||||
"svg/ox.ui.classic/symbolAdd.svg",
|
|
||||||
"svg/ox.ui.classic/symbolArrowDown.svg",
|
|
||||||
"svg/ox.ui.classic/symbolArrowLeft.svg",
|
|
||||||
"svg/ox.ui.classic/symbolArrowRight.svg",
|
|
||||||
"svg/ox.ui.classic/symbolArrowUp.svg",
|
|
||||||
"svg/ox.ui.classic/symbolBracket.svg",
|
|
||||||
"svg/ox.ui.classic/symbolCenter.svg",
|
|
||||||
"svg/ox.ui.classic/symbolCheck.svg",
|
|
||||||
"svg/ox.ui.classic/symbolClose.svg",
|
|
||||||
"svg/ox.ui.classic/symbolDelete.svg",
|
|
||||||
"svg/ox.ui.classic/symbolDown.svg",
|
|
||||||
"svg/ox.ui.classic/symbolDownload.svg",
|
|
||||||
"svg/ox.ui.classic/symbolEdit.svg",
|
|
||||||
"svg/ox.ui.classic/symbolFill.svg",
|
|
||||||
"svg/ox.ui.classic/symbolFind.svg",
|
|
||||||
"svg/ox.ui.classic/symbolFit.svg",
|
|
||||||
"svg/ox.ui.classic/symbolFlag.svg",
|
|
||||||
"svg/ox.ui.classic/symbolGoToIn.svg",
|
|
||||||
"svg/ox.ui.classic/symbolGoToOut.svg",
|
|
||||||
"svg/ox.ui.classic/symbolGrow.svg",
|
|
||||||
"svg/ox.ui.classic/symbolHelp.svg",
|
|
||||||
"svg/ox.ui.classic/symbolInfo.svg",
|
|
||||||
"svg/ox.ui.classic/symbolLeft.svg",
|
|
||||||
"svg/ox.ui.classic/symbolLike.svg",
|
|
||||||
"svg/ox.ui.classic/symbolLoading.svg",
|
|
||||||
"svg/ox.ui.classic/symbolLock.svg",
|
|
||||||
"svg/ox.ui.classic/symbolMount.svg",
|
|
||||||
"svg/ox.ui.classic/symbolMute.svg",
|
|
||||||
"svg/ox.ui.classic/symbolNone.svg",
|
|
||||||
"svg/ox.ui.classic/symbolPause.svg",
|
|
||||||
"svg/ox.ui.classic/symbolPlayInToOut.svg",
|
|
||||||
"svg/ox.ui.classic/symbolPublish.svg",
|
|
||||||
"svg/ox.ui.classic/symbolRedo.svg",
|
|
||||||
"svg/ox.ui.classic/symbolRemove.svg",
|
|
||||||
"svg/ox.ui.classic/symbolRight.svg",
|
|
||||||
"svg/ox.ui.classic/symbolSelect.svg",
|
|
||||||
"svg/ox.ui.classic/symbolSet.svg",
|
|
||||||
"svg/ox.ui.classic/symbolSetIn.svg",
|
|
||||||
"svg/ox.ui.classic/symbolSetOut.svg",
|
|
||||||
"svg/ox.ui.classic/symbolShrink.svg",
|
|
||||||
"svg/ox.ui.classic/symbolStar.svg",
|
|
||||||
"svg/ox.ui.classic/symbolSync.svg",
|
|
||||||
"svg/ox.ui.classic/symbolUndo.svg",
|
|
||||||
"svg/ox.ui.classic/symbolUnlock.svg",
|
|
||||||
"svg/ox.ui.classic/symbolUnmount.svg",
|
|
||||||
"svg/ox.ui.classic/symbolUnmute.svg",
|
|
||||||
"svg/ox.ui.classic/symbolUp.svg",
|
|
||||||
"svg/ox.ui.classic/symbolUser.svg",
|
|
||||||
"svg/ox.ui.classic/symbolView.svg",
|
|
||||||
"svg/ox.ui.classic/symbolVolumeDown.svg",
|
|
||||||
"svg/ox.ui.classic/symbolVolumeUp.svg",
|
|
||||||
"svg/ox.ui.classic/symbolWarning.svg",
|
|
||||||
"svg/ox.ui.classic/symbolZoom.svg",
|
|
||||||
"svg/ox.ui.modern/symbolAdd.svg",
|
|
||||||
"svg/ox.ui.modern/symbolArrowDown.svg",
|
|
||||||
"svg/ox.ui.modern/symbolArrowLeft.svg",
|
|
||||||
"svg/ox.ui.modern/symbolArrowRight.svg",
|
|
||||||
"svg/ox.ui.modern/symbolArrowUp.svg",
|
|
||||||
"svg/ox.ui.modern/symbolBracket.svg",
|
|
||||||
"svg/ox.ui.modern/symbolCenter.svg",
|
|
||||||
"svg/ox.ui.modern/symbolCheck.svg",
|
|
||||||
"svg/ox.ui.modern/symbolClose.svg",
|
|
||||||
"svg/ox.ui.modern/symbolDelete.svg",
|
|
||||||
"svg/ox.ui.modern/symbolDown.svg",
|
|
||||||
"svg/ox.ui.modern/symbolDownload.svg",
|
|
||||||
"svg/ox.ui.modern/symbolEdit.svg",
|
|
||||||
"svg/ox.ui.modern/symbolFill.svg",
|
|
||||||
"svg/ox.ui.modern/symbolFind.svg",
|
|
||||||
"svg/ox.ui.modern/symbolFit.svg",
|
|
||||||
"svg/ox.ui.modern/symbolFlag.svg",
|
|
||||||
"svg/ox.ui.modern/symbolGoToIn.svg",
|
|
||||||
"svg/ox.ui.modern/symbolGoToOut.svg",
|
|
||||||
"svg/ox.ui.modern/symbolGrow.svg",
|
|
||||||
"svg/ox.ui.modern/symbolHelp.svg",
|
|
||||||
"svg/ox.ui.modern/symbolInfo.svg",
|
|
||||||
"svg/ox.ui.modern/symbolLeft.svg",
|
|
||||||
"svg/ox.ui.modern/symbolLike.svg",
|
|
||||||
"svg/ox.ui.modern/symbolLoading.svg",
|
|
||||||
"svg/ox.ui.modern/symbolLock.svg",
|
|
||||||
"svg/ox.ui.modern/symbolMount.svg",
|
|
||||||
"svg/ox.ui.modern/symbolMute.svg",
|
|
||||||
"svg/ox.ui.modern/symbolNone.svg",
|
|
||||||
"svg/ox.ui.modern/symbolPause.svg",
|
|
||||||
"svg/ox.ui.modern/symbolPlayInToOut.svg",
|
|
||||||
"svg/ox.ui.modern/symbolPublish.svg",
|
|
||||||
"svg/ox.ui.modern/symbolRedo.svg",
|
|
||||||
"svg/ox.ui.modern/symbolRemove.svg",
|
|
||||||
"svg/ox.ui.modern/symbolRight.svg",
|
|
||||||
"svg/ox.ui.modern/symbolSelect.svg",
|
|
||||||
"svg/ox.ui.modern/symbolSet.svg",
|
|
||||||
"svg/ox.ui.modern/symbolSetIn.svg",
|
|
||||||
"svg/ox.ui.modern/symbolSetOut.svg",
|
|
||||||
"svg/ox.ui.modern/symbolShrink.svg",
|
|
||||||
"svg/ox.ui.modern/symbolStar.svg",
|
|
||||||
"svg/ox.ui.modern/symbolSync.svg",
|
|
||||||
"svg/ox.ui.modern/symbolUndo.svg",
|
|
||||||
"svg/ox.ui.modern/symbolUnlock.svg",
|
|
||||||
"svg/ox.ui.modern/symbolUnmount.svg",
|
|
||||||
"svg/ox.ui.modern/symbolUnmute.svg",
|
|
||||||
"svg/ox.ui.modern/symbolUp.svg",
|
|
||||||
"svg/ox.ui.modern/symbolUser.svg",
|
|
||||||
"svg/ox.ui.modern/symbolView.svg",
|
|
||||||
"svg/ox.ui.modern/symbolVolumeDown.svg",
|
|
||||||
"svg/ox.ui.modern/symbolVolumeUp.svg",
|
|
||||||
"svg/ox.ui.modern/symbolWarning.svg",
|
|
||||||
"svg/ox.ui.modern/symbolZoom.svg"
|
|
||||||
]
|
|
|
@ -1,6 +1,6 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
||||||
<g stroke="#404040" stroke-width="48">
|
<g stroke="#404040" stroke-width="48">
|
||||||
<line x1="128" y1="16" x2="128" y2="240"/>
|
<line x1="128" y1="0" x2="128" y2="256"/>
|
||||||
<line x1="16" y1="128" x2="240" y2="128"/>
|
<line x1="0" y1="128" x2="256" y2="128"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 229 B |
|
@ -1,3 +1,3 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
||||||
<polygon points="32,48 224,48 128,240" fill="#404040"/>
|
<polygon points="32,56 224,56 128,248" fill="#404040"/>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 132 B |
|
@ -1,3 +1,5 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
||||||
<line x1="16" y1="128" x2="240" y2="128" stroke="#404040" stroke-width="48"/>
|
<g stroke="#404040" stroke-width="48" stroke-linecap="round">
|
||||||
|
<line x1="0" y1="128" x2="256" y2="128"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 154 B After Width: | Height: | Size: 197 B |
|
@ -1,3 +1,3 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
||||||
<polygon points="32,208 128,16 224,208" fill="#404040"/>
|
<polygon points="32,200 128,8 224,200" fill="#404040"/>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 133 B After Width: | Height: | Size: 132 B |
|
@ -1,6 +1,6 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
||||||
<g stroke="#FFFFFF" stroke-width="48">
|
<g stroke="#FFFFFF" stroke-width="48">
|
||||||
<line x1="128" y1="16" x2="128" y2="240"/>
|
<line x1="128" y1="0" x2="128" y2="256"/>
|
||||||
<line x1="16" y1="128" x2="240" y2="128"/>
|
<line x1="0" y1="128" x2="256" y2="128"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 229 B |
|
@ -1,3 +1,3 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
||||||
<polygon points="32,48 224,48 128,240" fill="#FFFFFF"/>
|
<polygon points="32,56 224,56 128,248" fill="#FFFFFF"/>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 132 B After Width: | Height: | Size: 132 B |
|
@ -1,3 +1,5 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
||||||
<line x1="16" y1="128" x2="240" y2="128" stroke="#FFFFFF" stroke-width="48"/>
|
<g stroke="#FFFFFF" stroke-width="48" stroke-linecap="round">
|
||||||
|
<line x1="0" y1="128" x2="256" y2="128"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 154 B After Width: | Height: | Size: 197 B |
|
@ -1,3 +1,3 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
|
||||||
<polygon points="32,208 128,16 224,208" fill="#FFFFFF"/>
|
<polygon points="32,200 128,8 224,200" fill="#FFFFFF"/>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 133 B After Width: | Height: | Size: 132 B |
|
@ -4,10 +4,7 @@
|
||||||
<title>ox.js calendar demo</title>
|
<title>ox.js calendar demo</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
<link rel="stylesheet" type="text/css" href="../../build/css/ox.ui.css"/>
|
<link rel="stylesheet" type="text/css" href="../../build/css/ox.ui.css"/>
|
||||||
<script type="text/javascript" src="../../build/js/jquery-1.5.js"></script>
|
<script type="text/javascript" src="../../build/js/OxUI.js"></script>
|
||||||
<script type="text/javascript" src="../../build/js/jquery.mousewheel.js"></script>
|
|
||||||
<script type="text/javascript" src="../../build/js/ox.js"></script>
|
|
||||||
<script type="text/javascript" src="../../build/js/ox.ui.js"></script>
|
|
||||||
<script type="text/javascript" src="js/calendar.js"></script>
|
<script type="text/javascript" src="js/calendar.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body></body>
|
<body></body>
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
$(function() {
|
Ox.UI(function() {
|
||||||
|
|
||||||
|
Ox.UI.ready(function() {
|
||||||
|
|
||||||
Ox.theme('modern');
|
Ox.theme('modern');
|
||||||
|
|
||||||
|
Ox.print('$$$$', Ox.Calendar)
|
||||||
|
|
||||||
new Ox.Calendar({
|
new Ox.Calendar({
|
||||||
date: new Date(0),
|
date: new Date(0),
|
||||||
dates: [
|
dates: [
|
||||||
|
@ -131,3 +135,5 @@ $(function() {
|
||||||
}).appendTo(Ox.UI.$body);
|
}).appendTo(Ox.UI.$body);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
});
|
117
source/js/Ox.AnnotationPanel.js
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
Ox.AnnotationPanel = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
id: '',
|
||||||
|
items: [],
|
||||||
|
title: '',
|
||||||
|
type: 'text',
|
||||||
|
width: 0
|
||||||
|
})
|
||||||
|
.options(options || {});
|
||||||
|
|
||||||
|
self.selected = -1;
|
||||||
|
|
||||||
|
that.$element = new Ox.CollapsePanel({
|
||||||
|
collapsed: false,
|
||||||
|
extras: [
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'add',
|
||||||
|
style: 'symbol',
|
||||||
|
title: 'Add',
|
||||||
|
type: 'image'
|
||||||
|
}).bindEvent({
|
||||||
|
click: function(event, data) {
|
||||||
|
that.triggerEvent('add', {value: ''});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
size: 16,
|
||||||
|
title: self.options.title
|
||||||
|
})
|
||||||
|
.addClass('OxAnnotationPanel')
|
||||||
|
.bindEvent({
|
||||||
|
toggle: togglePanel
|
||||||
|
});
|
||||||
|
that.$content = that.$element.$content;
|
||||||
|
|
||||||
|
self.$annotations = new Ox.List({
|
||||||
|
construct: function(data) {
|
||||||
|
return new Ox.Element('div')
|
||||||
|
.addClass('OxAnnotation OxEditable OxTarget')
|
||||||
|
.html(Ox.parseHTML(data.value));
|
||||||
|
},
|
||||||
|
items: $.map(self.options.items, function(v, i) {
|
||||||
|
return {
|
||||||
|
id: v.id || i + '',
|
||||||
|
value: v.value
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
unique: 'id'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
open: function(event, data) {
|
||||||
|
if (data.ids.length == 1) {
|
||||||
|
var pos = Ox.getPositionById(self.$annotations.options('items'), data.ids[0]);
|
||||||
|
self.$annotations.editItem(pos);
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'delete': function(event, data) {
|
||||||
|
that.triggerEvent('delete', data);
|
||||||
|
},
|
||||||
|
select: selectAnnotation,
|
||||||
|
submit: updateAnnotation
|
||||||
|
})
|
||||||
|
.appendTo(that.$content);
|
||||||
|
|
||||||
|
/*
|
||||||
|
self.$annotations = new Ox.Element('div')
|
||||||
|
.appendTo(that.$content);
|
||||||
|
self.$annotation = [];
|
||||||
|
self.options.items.forEach(function(item, i) {
|
||||||
|
self.$annotation[i] = new Ox.Element('div')
|
||||||
|
.addClass('OxAnnotation')
|
||||||
|
.html(item.value.replace(/\n/g, '<br/>'))
|
||||||
|
.click(function() {
|
||||||
|
clickAnnotation(i);
|
||||||
|
})
|
||||||
|
.appendTo(self.$annotations);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
function selectAnnotation(event, data) {
|
||||||
|
var item = Ox.getObjectById(self.options.items, data.ids[0]);
|
||||||
|
that.triggerEvent('select', {
|
||||||
|
'in': item['in'],
|
||||||
|
'out': item.out,
|
||||||
|
'layer': self.options.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function updateAnnotation(event, data) {
|
||||||
|
var item = Ox.getObjectById(self.options.items, data.id);
|
||||||
|
item.value = data.value;
|
||||||
|
that.triggerEvent('submit', item);
|
||||||
|
}
|
||||||
|
|
||||||
|
function togglePanel() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
that.addItem = function(item) {
|
||||||
|
var pos = 0;
|
||||||
|
self.options.items.splice(pos, 0, item);
|
||||||
|
self.$annotations.addItems(pos, [item]);
|
||||||
|
self.$annotations.editItem(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
that.removeItems = function(ids) {
|
||||||
|
self.$annotations.removeItems(ids);
|
||||||
|
}
|
||||||
|
that.deselectItems = function() {
|
||||||
|
if(self.$annotations.options('selected'))
|
||||||
|
self.$annotations.options('selected',[]);
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
200
source/js/Ox.App.js
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
/*
|
||||||
|
============================================================================
|
||||||
|
Application
|
||||||
|
============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
// fixme: get rid og launch, fire load event
|
||||||
|
|
||||||
|
Ox.App = (function() {
|
||||||
|
|
||||||
|
/***
|
||||||
|
Ox.App
|
||||||
|
Basic application instance that communicates with a JSON API.
|
||||||
|
The JSON API should support at least the following actions:
|
||||||
|
api returns all api methods
|
||||||
|
init returns {config: {...}, user: {...}}
|
||||||
|
Options
|
||||||
|
timeout API timeout in msec
|
||||||
|
type 'GET' or 'POST'
|
||||||
|
url URL of the API
|
||||||
|
Methods
|
||||||
|
api[action] make a request
|
||||||
|
api.cancel cancel a request
|
||||||
|
launch launch the App
|
||||||
|
options get or set options
|
||||||
|
***/
|
||||||
|
|
||||||
|
return function(options) {
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
var self = {},
|
||||||
|
that = this;
|
||||||
|
|
||||||
|
self.time = +new Date();
|
||||||
|
|
||||||
|
self.options = $.extend({
|
||||||
|
timeout: 60000,
|
||||||
|
type: 'POST',
|
||||||
|
url: '/api/',
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
that.$element = new Ox.Element('body');
|
||||||
|
|
||||||
|
function getUserAgent() {
|
||||||
|
var userAgent = '';
|
||||||
|
Ox.forEach(['Chrome', 'Firefox', 'Internet Explorer', 'Opera', 'Safari'], function(v) {
|
||||||
|
if (navigator.userAgent.indexOf(v) > -1) {
|
||||||
|
userAgent = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!userAgent && $.browser.mozilla) {
|
||||||
|
userAgent = 'Firefox';
|
||||||
|
}
|
||||||
|
if (!userAgent && $.browser.webkit) {
|
||||||
|
userAgent = 'Chrome';
|
||||||
|
}
|
||||||
|
return userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUserData() {
|
||||||
|
return {
|
||||||
|
document: {
|
||||||
|
referrer: document.referrer
|
||||||
|
},
|
||||||
|
history: {
|
||||||
|
length: history.length
|
||||||
|
},
|
||||||
|
navigator: {
|
||||||
|
cookieEnabled: navigator.cookieEnabled,
|
||||||
|
plugins: $.map(navigator.plugins, function(plugin, i) {
|
||||||
|
return plugin.name;
|
||||||
|
}),
|
||||||
|
userAgent: navigator.userAgent
|
||||||
|
},
|
||||||
|
screen: screen,
|
||||||
|
time: (+new Date() - self.time) / 1000,
|
||||||
|
window: {
|
||||||
|
innerHeight: window.innerHeight,
|
||||||
|
innerWidth: window.innerWidth,
|
||||||
|
outerHeight: window.outerHeight,
|
||||||
|
outerWidth: window.outerWidth,
|
||||||
|
screenLeft: window.screenLeft,
|
||||||
|
screenTop: window.screenTop
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadImages(callback) {
|
||||||
|
window.OxImageCache = [];
|
||||||
|
$.getJSON(Ox.UI.PATH + 'json/ox.ui.images.json', function(data) {
|
||||||
|
// fixme: find a better way to not wait for flags
|
||||||
|
data = data.filter(function(image) {
|
||||||
|
return !Ox.startsWith(image, 'svg/ox.map/')
|
||||||
|
});
|
||||||
|
var counter = 0,
|
||||||
|
length = data.length;
|
||||||
|
data.forEach(function(src, i) {
|
||||||
|
var image = new Image();
|
||||||
|
image.src = Ox.UI.PATH + src;
|
||||||
|
image.onload = function() {
|
||||||
|
(++counter == length) && callback();
|
||||||
|
}
|
||||||
|
window.OxImageCache.push(image); // fixme: global var???
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.change = function(key, value) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.api = {
|
||||||
|
api: function(callback) {
|
||||||
|
Ox.Request.send({
|
||||||
|
url: self.options.url,
|
||||||
|
data: {
|
||||||
|
action: 'api'
|
||||||
|
},
|
||||||
|
callback: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cancel: function(id) {
|
||||||
|
Ox.Request.cancel(id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.bindEvent = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// fixme: use $.when()
|
||||||
|
that.launch = function(callback) {
|
||||||
|
var time = +new Date(),
|
||||||
|
userAgent = getUserAgent(),
|
||||||
|
userAgents = ['Chrome', 'Firefox', 'Opera', 'Safari'];
|
||||||
|
$.ajaxSetup({
|
||||||
|
timeout: self.options.timeour,
|
||||||
|
type: self.options.type,
|
||||||
|
url: self.options.url
|
||||||
|
});
|
||||||
|
userAgents.indexOf(userAgent) > -1 ? start() : stop();
|
||||||
|
function start() {
|
||||||
|
// fixme: rename config to site?
|
||||||
|
var counter = 0, config, user;
|
||||||
|
that.api.api(function(result) {
|
||||||
|
Ox.forEach(result.data.actions, function(val, key) {
|
||||||
|
that.api[key] = function(data, callback) {
|
||||||
|
if (arguments.length == 1 && Ox.isFunction(data)) {
|
||||||
|
callback = data;
|
||||||
|
data = {};
|
||||||
|
}
|
||||||
|
return Ox.Request.send($.extend({
|
||||||
|
url: self.options.url,
|
||||||
|
data: {
|
||||||
|
action: key,
|
||||||
|
data: JSON.stringify(data)
|
||||||
|
},
|
||||||
|
callback: callback
|
||||||
|
}, !val.cache ? {age: 0}: {}));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
that.api.init(getUserData(), function(result) {
|
||||||
|
config = result.data.config;
|
||||||
|
user = result.data.user;
|
||||||
|
// fixme: not generic
|
||||||
|
document.title = config.site.name;
|
||||||
|
launchCallback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
loadImages(launchCallback);
|
||||||
|
function launchCallback() {
|
||||||
|
++counter == 2 && $(function() {
|
||||||
|
var $div = Ox.UI.$body.find('div');
|
||||||
|
Ox.UI.$body.find('img').remove();
|
||||||
|
$div.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 1000, function() {
|
||||||
|
$div.remove();
|
||||||
|
});
|
||||||
|
// fixme: not generic enough, just pass data
|
||||||
|
callback({config: config, user: user});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function stop() {
|
||||||
|
that.request.send(self.options.init, getUserData(), function() {});
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.options = function() {
|
||||||
|
return Ox.getset(self.options, Array.prototype.slice.call(arguments), self.change, that);
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
18
source/js/Ox.Bar.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
Ox.Bar = function(options, self) {
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
size: 'medium' // can be int
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxBar Ox' + Ox.toTitleCase(self.options.orientation)),
|
||||||
|
dimensions = Ox.UI.DIMENSIONS[self.options.orientation];
|
||||||
|
self.options.size = Ox.isString(self.options.size) ?
|
||||||
|
Ox.UI.getBarSize(self.options.size) : self.options.size;
|
||||||
|
that.css(dimensions[0], '100%')
|
||||||
|
.css(dimensions[1], self.options.size + 'px');
|
||||||
|
return that;
|
||||||
|
};
|
363
source/js/Ox.BlockTimeline.js
Normal file
|
@ -0,0 +1,363 @@
|
||||||
|
Ox.BlockTimeline = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
cuts: [],
|
||||||
|
duration: 0,
|
||||||
|
find: '',
|
||||||
|
matches: [],
|
||||||
|
points: [0, 0],
|
||||||
|
position: 0,
|
||||||
|
subtitles: [],
|
||||||
|
videoId: '',
|
||||||
|
width: 0
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxTimelineSmall')
|
||||||
|
.mousedown(mousedown)
|
||||||
|
.mouseleave(mouseleave)
|
||||||
|
.mousemove(mousemove)
|
||||||
|
.bindEvent({
|
||||||
|
drag: function(event, e) {
|
||||||
|
mousedown(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
$images: [],
|
||||||
|
$lines: [],
|
||||||
|
$markerPoint: [],
|
||||||
|
$selection: [],
|
||||||
|
$subtitles: [],
|
||||||
|
$tooltip: new Ox.Tooltip({
|
||||||
|
animate: false
|
||||||
|
}).css({
|
||||||
|
textAlign: 'center'
|
||||||
|
}),
|
||||||
|
hasSubtitles: self.options.subtitles.length,
|
||||||
|
height: 16,
|
||||||
|
lines: Math.ceil(self.options.duration / self.options.width),
|
||||||
|
margin: 8
|
||||||
|
});
|
||||||
|
|
||||||
|
that.css({
|
||||||
|
width: (self.options.width + self.margin) + 'px',
|
||||||
|
height: ((self.height + self.margin) * self.lines + 4) + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
getTimelineImageURL(function(url) {
|
||||||
|
|
||||||
|
self.timelineImageURL = url;
|
||||||
|
|
||||||
|
Ox.range(0, self.lines).forEach(function(i) {
|
||||||
|
addLine(i);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$markerPosition = $('<img>')
|
||||||
|
.addClass('OxMarkerPosition')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/ox.ui/videoMarkerPlay.png'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
width: '9px',
|
||||||
|
height: '5px',
|
||||||
|
zIndex: 10
|
||||||
|
})
|
||||||
|
.appendTo(that.$element);
|
||||||
|
|
||||||
|
setPosition();
|
||||||
|
|
||||||
|
['in', 'out'].forEach(function(v, i) {
|
||||||
|
var titleCase = Ox.toTitleCase(v);
|
||||||
|
self.$markerPoint[i] = $('<img>')
|
||||||
|
.addClass('OxMarkerPoint' + titleCase)
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/ox.ui/videoMarker' + titleCase + '.png'
|
||||||
|
})
|
||||||
|
.appendTo(that.$element);
|
||||||
|
setMarkerPoint(i);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function addLine(i) {
|
||||||
|
// fixme: get URLs once, not once for every line
|
||||||
|
self.$lines[i] = new Ox.Element('div')
|
||||||
|
.css({
|
||||||
|
top: i * (self.height + self.margin) + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
self.$images[i] = $('<img>')
|
||||||
|
.addClass('OxTimelineSmallImage')
|
||||||
|
.attr({
|
||||||
|
src: self.timelineImageURL
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
marginLeft: (-i * self.options.width) + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$lines[i].$element)
|
||||||
|
if (self.hasSubtitles) {
|
||||||
|
self.subtitlesImageURL = getSubtitlesImageURL();
|
||||||
|
self.$subtitles[i] = $('<img>')
|
||||||
|
.addClass('OxTimelineSmallSubtitles')
|
||||||
|
.attr({
|
||||||
|
src: self.subtitlesImageURL
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
marginLeft: (-i * self.options.width) + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$lines[i].$element);
|
||||||
|
}
|
||||||
|
if (self.options.points[0] != self.options.points[1]) {
|
||||||
|
addSelection[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSelection(i) {
|
||||||
|
self.selectionImageURL = getSelectionImageURL();
|
||||||
|
self.$selection[i] && self.$selection[i].remove();
|
||||||
|
self.$selection[i] = $('<img>')
|
||||||
|
.addClass('OxTimelineSmallSelection')
|
||||||
|
.attr({
|
||||||
|
src: self.selectionImageURL
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
marginLeft: (-i * self.options.width) + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$lines[i].$element);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPosition(e) {
|
||||||
|
//FIXME: this might still be broken in opera according to http://acko.net/blog/mouse-handling-and-absolute-positions-in-javascript
|
||||||
|
return (e.offsetX ? e.offsetX : e.clientX - $(e.target).offset().left);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectionImageURL() {
|
||||||
|
var height = 18,
|
||||||
|
width = Math.ceil(self.options.duration),
|
||||||
|
$canvas = $('<canvas>')
|
||||||
|
.attr({
|
||||||
|
height: height,
|
||||||
|
width: width
|
||||||
|
}),
|
||||||
|
canvas = $canvas[0],
|
||||||
|
context = canvas.getContext('2d'),
|
||||||
|
imageData = context.createImageData(width, height),
|
||||||
|
data = imageData.data,
|
||||||
|
points = $.map(self.options.points, function(v, i) {
|
||||||
|
return Math.round(v) + i;
|
||||||
|
}),
|
||||||
|
top = 0,
|
||||||
|
bottom = 18;
|
||||||
|
Ox.range(points[0], points[1]).forEach(function(x) {
|
||||||
|
Ox.range(top, bottom).forEach(function(y) {
|
||||||
|
var color = (y == top || y == bottom - 1) ? [255, 255, 255, 255] : [255, 255, 255, 64],
|
||||||
|
index = x * 4 + y * 4 * width;
|
||||||
|
data[index] = color[0];
|
||||||
|
data[index + 1] = color[1];
|
||||||
|
data[index + 2] = color[2];
|
||||||
|
data[index + 3] = color[3]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
context.putImageData(imageData, 0, 0);
|
||||||
|
return canvas.toDataURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubtitle(position) {
|
||||||
|
var subtitle = null;
|
||||||
|
Ox.forEach(self.options.subtitles, function(v) {
|
||||||
|
if (v['in'] <= position && v['out'] >= position) {
|
||||||
|
subtitle = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return subtitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubtitlesImageURL() {
|
||||||
|
var height = 18,
|
||||||
|
width = Math.ceil(self.options.duration),
|
||||||
|
$canvas = $('<canvas>')
|
||||||
|
.attr({
|
||||||
|
height: height,
|
||||||
|
width: width
|
||||||
|
}),
|
||||||
|
canvas = $canvas[0],
|
||||||
|
context = canvas.getContext('2d'),
|
||||||
|
imageData = context.createImageData(width, height),
|
||||||
|
data = imageData.data;
|
||||||
|
self.options.subtitles.forEach(function(v) {
|
||||||
|
//var color = self.options.matches.indexOf(i) > -1 ? [255, 255, 0] : [255, 255, 255]
|
||||||
|
var inPoint = Math.round(v['in']),
|
||||||
|
outPoint = Math.round(v.out) + 1,
|
||||||
|
lines = v.value.split('\n').length,
|
||||||
|
bottom = 15,
|
||||||
|
top = bottom - lines - 2;
|
||||||
|
Ox.range(inPoint, outPoint).forEach(function(x) {
|
||||||
|
Ox.range(top, bottom).forEach(function(y) {
|
||||||
|
var color = (y == top || y == bottom - 1) ? [0, 0, 0] : [255, 255, 255],
|
||||||
|
index = x * 4 + y * 4 * width;
|
||||||
|
data[index] = color[0];
|
||||||
|
data[index + 1] = color[1];
|
||||||
|
data[index + 2] = color[2];
|
||||||
|
data[index + 3] = 128
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
context.putImageData(imageData, 0, 0);
|
||||||
|
return canvas.toDataURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimelineImageURL(callback) {
|
||||||
|
var height = 16,
|
||||||
|
images = Math.ceil(self.options.duration / 3600),
|
||||||
|
loaded = 0,
|
||||||
|
width = Math.ceil(self.options.duration),
|
||||||
|
$canvas = $('<canvas>')
|
||||||
|
.attr({
|
||||||
|
height: height,
|
||||||
|
width: width
|
||||||
|
}),
|
||||||
|
canvas = $canvas[0],
|
||||||
|
context = canvas.getContext('2d');
|
||||||
|
Ox.range(images).forEach(function(i) {
|
||||||
|
var $img = $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: '/' + self.options.videoId + '/timelines/timeline.16.' + i + '.png'
|
||||||
|
})
|
||||||
|
.load(function() {
|
||||||
|
context.drawImage($img[0], i * 3600, 0);
|
||||||
|
//Ox.print('loaded, images', loaded, images, $img[0])
|
||||||
|
if (++loaded == images) {
|
||||||
|
//Ox.print('callback', canvas.toDataURL().length)
|
||||||
|
callback(canvas.toDataURL());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousedown(e) {
|
||||||
|
var $target = $(e.target);
|
||||||
|
if (
|
||||||
|
$target.hasClass('OxTimelineSmallImage') ||
|
||||||
|
$target.hasClass('OxTimelineSmallSubtitles') ||
|
||||||
|
$target.hasClass('OxTimelineSmallSelection')
|
||||||
|
) {
|
||||||
|
self.options.position = getPosition(e);
|
||||||
|
setPosition();
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseleave(e) {
|
||||||
|
self.$tooltip.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousemove(e) {
|
||||||
|
var $target = $(e.target),
|
||||||
|
position,
|
||||||
|
subtitle;
|
||||||
|
if (
|
||||||
|
$target.hasClass('OxTimelineSmallImage') ||
|
||||||
|
$target.hasClass('OxTimelineSmallSubtitles') ||
|
||||||
|
$target.hasClass('OxTimelineSmallSelection')
|
||||||
|
) {
|
||||||
|
position = getPosition(e),
|
||||||
|
subtitle = getSubtitle(position);
|
||||||
|
self.$tooltip.options({
|
||||||
|
title: subtitle ?
|
||||||
|
'<span class=\'OxBright\'>' +
|
||||||
|
Ox.highlight(subtitle.value, self.options.find).replace(/\n/g, '<br/>') + '</span><br/>' +
|
||||||
|
Ox.formatDuration(subtitle['in'], 3) + ' - ' + Ox.formatDuration(subtitle['out'], 3) :
|
||||||
|
Ox.formatDuration(position, 3)
|
||||||
|
})
|
||||||
|
.show(e.clientX, e.clientY);
|
||||||
|
} else {
|
||||||
|
self.$tooltip.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMarker() {
|
||||||
|
self.$markerPosition
|
||||||
|
.css({
|
||||||
|
left: (self.options.position % self.options.width) + 'px',
|
||||||
|
top: (parseInt(self.options.position / self.options.width) * (self.height + self.margin) + 2) + 'px',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMarkerPoint(i) {
|
||||||
|
var position = Math.round(self.options.points[i]);
|
||||||
|
self.$markerPoint[i]
|
||||||
|
.css({
|
||||||
|
left: (position % self.options.width) + 'px',
|
||||||
|
top: (parseInt(position / self.options.width) * (self.height + self.margin) + 16) + 'px',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPosition() {
|
||||||
|
self.options.position = Ox.limit(self.options.position, 0, self.options.duration);
|
||||||
|
setMarker();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWidth() {
|
||||||
|
self.lines = Math.ceil(self.options.duration / self.options.width);
|
||||||
|
that.css({
|
||||||
|
width: (self.options.width + self.margin) + 'px',
|
||||||
|
height: ((self.height + self.margin) * self.lines + 4) + 'px'
|
||||||
|
});
|
||||||
|
Ox.range(self.lines).forEach(function(i) {
|
||||||
|
if (self.$lines[i]) {
|
||||||
|
self.$lines[i].css({
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
self.$images[i].css({
|
||||||
|
marginLeft: (-i * self.options.width) + 'px'
|
||||||
|
});
|
||||||
|
if (self.hasSubtitles) {
|
||||||
|
self.$subtitles[i].css({
|
||||||
|
marginLeft: (-i * self.options.width) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addLine(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
while (self.$lines.length > self.lines) {
|
||||||
|
self.$lines[self.$lines.length - 1].removeElement();
|
||||||
|
self.$lines.pop();
|
||||||
|
}
|
||||||
|
setMarker();
|
||||||
|
setMarkerPoint(0);
|
||||||
|
setMarkerPoint(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSelection() {
|
||||||
|
self.$lines.forEach(function($line, i) {
|
||||||
|
addSelection(i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
//Ox.print('onChange:', key, value)
|
||||||
|
if (key == 'points') {
|
||||||
|
//Ox.print('key', key, 'value', value)
|
||||||
|
setMarkerPoint(0);
|
||||||
|
setMarkerPoint(1);
|
||||||
|
updateSelection()
|
||||||
|
} else if (key == 'position') {
|
||||||
|
setPosition();
|
||||||
|
} else if (key == 'width') {
|
||||||
|
setWidth();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
163
source/js/Ox.Button.js
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
Ox.Button = function(options, self) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
methods:
|
||||||
|
toggleDisabled enable/disable button
|
||||||
|
toggleSelected select/unselect button
|
||||||
|
toggleTitle if more than one title was provided,
|
||||||
|
toggle to next title.
|
||||||
|
events:
|
||||||
|
click non-selectable button was clicked
|
||||||
|
deselect selectable button was deselected
|
||||||
|
select selectable button was selected
|
||||||
|
*/
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('input', self)
|
||||||
|
.defaults({
|
||||||
|
disabled: false,
|
||||||
|
group: false,
|
||||||
|
id: '',
|
||||||
|
overlap: 'none',
|
||||||
|
selectable: false,
|
||||||
|
selected: false,
|
||||||
|
size: 'medium',
|
||||||
|
// fixme: 'default' or ''?
|
||||||
|
style: 'default', // can be default, checkbox, symbol, or tab
|
||||||
|
title: '',
|
||||||
|
tooltip: '',
|
||||||
|
type: 'text',
|
||||||
|
width: 'auto'
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.attr({
|
||||||
|
disabled: self.options.disabled ? 'disabled' : '',
|
||||||
|
type: self.options.type == 'text' ? 'button' : 'image'
|
||||||
|
})
|
||||||
|
.addClass('OxButton Ox' + Ox.toTitleCase(self.options.size) +
|
||||||
|
(self.options.disabled ? ' OxDisabled': '') +
|
||||||
|
(self.options.selected ? ' OxSelected': '') +
|
||||||
|
(self.options.style != 'default' ? ' Ox' + Ox.toTitleCase(self.options.style) : '') +
|
||||||
|
(self.options.overlap != 'none' ? ' OxOverlap' + Ox.toTitleCase(self.options.overlap) : ''))
|
||||||
|
.css(self.options.width == 'auto' ? {} : {
|
||||||
|
width: (self.options.width - 14) + 'px'
|
||||||
|
})
|
||||||
|
.mousedown(mousedown)
|
||||||
|
.click(click);
|
||||||
|
|
||||||
|
$.extend(self, Ox.isArray(self.options.title) ? {
|
||||||
|
selectedTitle: Ox.setPropertyOnce(self.options.title, 'selected'),
|
||||||
|
titles: self.options.title
|
||||||
|
} : {
|
||||||
|
selectedTitle: 0,
|
||||||
|
titles: [{
|
||||||
|
id: '',
|
||||||
|
title: self.options.title
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
setTitle(self.titles[self.selectedTitle].title);
|
||||||
|
|
||||||
|
if (self.options.tooltip) {
|
||||||
|
self.tooltips = Ox.isArray(self.options.tooltip) ? self.options.tooltip : [self.options.tooltip];
|
||||||
|
self.$tooltip = new Ox.Tooltip({
|
||||||
|
title: self.tooltips[self.selectedTitle]
|
||||||
|
});
|
||||||
|
that.mouseenter(mouseenter)
|
||||||
|
.mouseleave(mouseleave);
|
||||||
|
}
|
||||||
|
|
||||||
|
function click() {
|
||||||
|
if (!self.options.disabled) {
|
||||||
|
var data = self.titles[self.selectedTitle];
|
||||||
|
if (!self.options.selectable) {
|
||||||
|
that.triggerEvent('click', data);
|
||||||
|
} else {
|
||||||
|
//self.options.selected = !self.options.selected;
|
||||||
|
//that.toggleClass('OxSelected');
|
||||||
|
if (self.options.group) {
|
||||||
|
that.triggerEvent('select', data);
|
||||||
|
} else {
|
||||||
|
that.toggleSelected();
|
||||||
|
//that.triggerEvent('change', {selected: self.options.selected});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self.titles.length == 2) {
|
||||||
|
that.toggleTitle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousedown(e) {
|
||||||
|
if (self.options.type == 'image' && $.browser.safari) {
|
||||||
|
// keep image from being draggable
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseenter(e) {
|
||||||
|
self.$tooltip.show(e.clientX, e.clientY);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseleave() {
|
||||||
|
self.$tooltip.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTitle(title) {
|
||||||
|
self.title = title;
|
||||||
|
if (self.options.type == 'image') {
|
||||||
|
that.attr({
|
||||||
|
src: Ox.UI.getImagePath(
|
||||||
|
'symbol' + title[0].toUpperCase() + title.substr(1) + '.svg'
|
||||||
|
)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
that.val(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'disabled') {
|
||||||
|
that.attr({
|
||||||
|
disabled: value ? 'disabled' : ''
|
||||||
|
})
|
||||||
|
.toggleClass('OxDisabled');
|
||||||
|
} else if (key == 'selected') {
|
||||||
|
if (value != that.hasClass('OxSelected')) { // fixme: neccessary?
|
||||||
|
that.toggleClass('OxSelected');
|
||||||
|
}
|
||||||
|
that.triggerEvent('change');
|
||||||
|
} else if (key == 'title') {
|
||||||
|
setTitle(value);
|
||||||
|
} else if (key == 'width') {
|
||||||
|
that.$element.css({
|
||||||
|
width: (value - 14) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.toggleDisabled = function() {
|
||||||
|
that.options({
|
||||||
|
enabled: !self.options.disabled
|
||||||
|
});
|
||||||
|
//self.options.disabled = !self.options.disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.toggleSelected = function() {
|
||||||
|
that.options({
|
||||||
|
selected: !self.options.selected
|
||||||
|
});
|
||||||
|
//self.options.selected = !self.options.selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.toggleTitle = function() {
|
||||||
|
self.selectedTitle = 1 - self.selectedTitle;
|
||||||
|
setTitle(self.titles[self.selectedTitle].title);
|
||||||
|
self.$tooltip && self.$tooltip.options({
|
||||||
|
title: self.tooltips[self.selectedTitle]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
74
source/js/Ox.ButtonGroup.js
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
Ox.ButtonGroup = function(options, self) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
options
|
||||||
|
buttons array of buttons
|
||||||
|
max integer, maximum number of selected buttons, 0 for all
|
||||||
|
min integer, minimum number of selected buttons, 0 for none
|
||||||
|
selectable if true, buttons are selectable
|
||||||
|
type string, 'image' or 'text'
|
||||||
|
methods:
|
||||||
|
events:
|
||||||
|
change {id, value} selection within a group changed
|
||||||
|
*/
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
buttons: [],
|
||||||
|
max: 1,
|
||||||
|
min: 1,
|
||||||
|
selectable: false,
|
||||||
|
size: 'medium',
|
||||||
|
style: '',
|
||||||
|
type: 'text',
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxButtonGroup');
|
||||||
|
|
||||||
|
if (self.options.selectable) {
|
||||||
|
self.optionGroup = new Ox.OptionGroup(
|
||||||
|
self.options.buttons,
|
||||||
|
self.options.min,
|
||||||
|
self.options.max,
|
||||||
|
'selected'
|
||||||
|
);
|
||||||
|
self.options.buttons = self.optionGroup.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.$buttons = [];
|
||||||
|
self.options.buttons.forEach(function(button, position) {
|
||||||
|
var id = self.options.id + Ox.toTitleCase(button.id)
|
||||||
|
self.$buttons[position] = Ox.Button({
|
||||||
|
disabled: button.disabled,
|
||||||
|
group: true,
|
||||||
|
id: id,
|
||||||
|
selectable: self.options.selectable,
|
||||||
|
selected: button.selected,
|
||||||
|
size: self.options.size,
|
||||||
|
style: self.options.style,
|
||||||
|
title: button.title,
|
||||||
|
type: self.options.type
|
||||||
|
})
|
||||||
|
.bindEvent('select', function() {
|
||||||
|
selectButton(position);
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
});
|
||||||
|
|
||||||
|
function selectButton(pos) {
|
||||||
|
var toggled = self.optionGroup.toggle(pos);
|
||||||
|
if (toggled.length) {
|
||||||
|
toggled.forEach(function(pos, i) {
|
||||||
|
self.$buttons[pos].toggleSelected();
|
||||||
|
});
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
selected: $.map(self.optionGroup.selected(), function(v, i) {
|
||||||
|
return self.options.buttons[v].id;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
};
|
711
source/js/Ox.Calendar.js
Normal file
|
@ -0,0 +1,711 @@
|
||||||
|
Ox.Calendar = function(options, self) {
|
||||||
|
|
||||||
|
self = self || {};
|
||||||
|
var that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
date: new Date(),
|
||||||
|
dates: [],
|
||||||
|
height: 512,
|
||||||
|
range: [100, 5101],
|
||||||
|
width: 512,
|
||||||
|
zoom: 8
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxCalendar')
|
||||||
|
.css({
|
||||||
|
width: self.options.width + 'px',
|
||||||
|
height: self.options.height + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
self.maxZoom = 32;
|
||||||
|
self.minLabelWidth = 80;
|
||||||
|
self.overlayWidths = [Math.round(self.options.width / 16)];
|
||||||
|
self.overlayWidths = [
|
||||||
|
Math.floor((self.options.width - self.overlayWidths[0]) / 2),
|
||||||
|
self.overlayWidths[0],
|
||||||
|
Math.ceil((self.options.width - self.overlayWidths[0]) / 2),
|
||||||
|
];
|
||||||
|
self.units = [
|
||||||
|
{
|
||||||
|
id: 'millennium',
|
||||||
|
seconds: 365242.5 * 86400,
|
||||||
|
date: function(i) {
|
||||||
|
return new Date((i + 1) + '000');
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.formatOrdinal(i + 2) + ' millennium';
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor(date.getFullYear() / 1000) - 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'century',
|
||||||
|
seconds: 36524.25 * 86400,
|
||||||
|
date: function(i) {
|
||||||
|
return new Date((i + 19) + '00');
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.formatOrdinal(i + 20) + ' century';
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor(date.getFullYear() / 100) - 19;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'decade',
|
||||||
|
seconds: 3652.425 * 86400,
|
||||||
|
date: function(i) {
|
||||||
|
return (i + 197) + '0'
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return (i + 197) + '0s'
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor(date.getFullYear() / 10) - 197;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'year',
|
||||||
|
seconds: 365.2425 * 86400,
|
||||||
|
date: function(i) {
|
||||||
|
return (i + 1970) + '';
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return (i + 1970) + '';
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return date.getFullYear() - 1970;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'month',
|
||||||
|
seconds: 365.2425 / 12 * 86400,
|
||||||
|
date: function(i) {
|
||||||
|
return (Math.floor(i / 12) + 1970) + '-' + (Ox.mod(i, 12) + 1);
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.SHORT_MONTHS[Ox.mod(i, 12)] + ' ' + Math.floor(i / 12 + 1970)
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return (date.getFullYear() - 1970) * 12 + date.getMonth();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'week',
|
||||||
|
seconds: 7 * 86400,
|
||||||
|
date: function(i) {
|
||||||
|
return (i * 7 - 3) * 86400000;
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.formatDate(new Date((i * 7 - 3) * 86400000), '%a, %b %e');
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor((+date / 86400000 + 4) / 7);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'day',
|
||||||
|
seconds: 86400,
|
||||||
|
date: function(i) {
|
||||||
|
// adjust for timezone difference
|
||||||
|
// fixme: may still be off
|
||||||
|
return i * 86400000 + Ox.TIMEZONE_OFFSET;
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.formatDate(new Date(i * 86400000), '%b %e, %Y');
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor(date / 86400000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'six_hours',
|
||||||
|
seconds: 21600,
|
||||||
|
date: function(i) {
|
||||||
|
return i * 21600000 + Ox.TIMEZONE_OFFSET;
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.formatDate(new Date(i * 21600000 + Ox.TIMEZONE_OFFSET), '%b %e, %H:00');
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor((date - Ox.TIMEZONE_OFFSET) / 21600000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'hour',
|
||||||
|
seconds: 3600,
|
||||||
|
date: function(i) {
|
||||||
|
return i * 3600000;
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.formatDate(new Date(i * 3600000), '%b %e, %H:00');
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor(date / 3600000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'five_minutes',
|
||||||
|
seconds: 300,
|
||||||
|
date: function(i) {
|
||||||
|
return i * 300000;
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.formatDate(new Date(i * 300000), '%b %e, %H:%M');
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor(date / 300000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'minute',
|
||||||
|
seconds: 60,
|
||||||
|
date: function(i) {
|
||||||
|
return i * 60000;
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.formatDate(new Date(i * 60000), '%b %e, %H:%M');
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor(date / 60000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'five_seconds',
|
||||||
|
seconds: 5,
|
||||||
|
date: function(i) {
|
||||||
|
return i * 5000;
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.formatDate(new Date(i * 5000), '%H:%M:%S');
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor(date / 5000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'second',
|
||||||
|
seconds: 1,
|
||||||
|
date: function(i) {
|
||||||
|
return i * 1000;
|
||||||
|
},
|
||||||
|
name: function(i) {
|
||||||
|
return Ox.formatDate(new Date(i * 1000), '%H:%M:%S');
|
||||||
|
},
|
||||||
|
value: function(date) {
|
||||||
|
return Math.floor(date / 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
self.$container = new Ox.Element()
|
||||||
|
.addClass('OxCalendarContainer')
|
||||||
|
.css({
|
||||||
|
top: '24px',
|
||||||
|
bottom: '40px'
|
||||||
|
})
|
||||||
|
.bind({
|
||||||
|
mouseleave: mouseleave,
|
||||||
|
mousemove: mousemove,
|
||||||
|
mousewheel: mousewheel
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
doubleclick: doubleclick,
|
||||||
|
dragstart: dragstart,
|
||||||
|
drag: drag,
|
||||||
|
dragpause: dragpause,
|
||||||
|
dragend: dragend,
|
||||||
|
singleclick: singleclick
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
|
||||||
|
self.$content = new Ox.Element()
|
||||||
|
.addClass('OxCalendarContent')
|
||||||
|
.appendTo(self.$container);
|
||||||
|
|
||||||
|
self.$background = new Ox.Element()
|
||||||
|
.addClass('OxBackground')
|
||||||
|
.appendTo(self.$content);
|
||||||
|
|
||||||
|
self.$scalebar = new Ox.Element()
|
||||||
|
.addClass('OxTimeline')
|
||||||
|
.css({
|
||||||
|
posision: 'absolute',
|
||||||
|
})
|
||||||
|
.appendTo(self.$content);
|
||||||
|
|
||||||
|
self.$scrollbar = new Ox.Element()
|
||||||
|
.addClass('OxTimeline')
|
||||||
|
.css({
|
||||||
|
posision: 'absolute',
|
||||||
|
bottom: '40px'
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
self.$overlay = new Ox.Element()
|
||||||
|
.addClass('OxOverlay')
|
||||||
|
.css({
|
||||||
|
bottom: '40px'
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
$('<div>').css({
|
||||||
|
width: self.overlayWidths[0] + 'px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
$('<div>').css({
|
||||||
|
left: self.overlayWidths[0] + 'px',
|
||||||
|
width: self.overlayWidths[1] + 'px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
$('<div>').css({
|
||||||
|
left: (self.overlayWidths[0] + self.overlayWidths[1]) + 'px',
|
||||||
|
width: self.overlayWidths[2] + 'px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.bindEvent({
|
||||||
|
dragstart: dragstartScrollbar,
|
||||||
|
drag: dragScrollbar,
|
||||||
|
dragpause: dragpauseScrollbar,
|
||||||
|
dragend: dragendScrollbar
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
|
||||||
|
self.$zoombar = new Ox.Element()
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 24 + 'px',
|
||||||
|
height: '16px'
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
self.$zoomInput = new Ox.Range({
|
||||||
|
arrows: true,
|
||||||
|
max: self.maxZoom,
|
||||||
|
min: 0,
|
||||||
|
size: self.options.width,
|
||||||
|
thumbSize: 32,
|
||||||
|
thumbValue: true,
|
||||||
|
value: self.options.zoom
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: changeZoom
|
||||||
|
})
|
||||||
|
.appendTo(self.$zoombar);
|
||||||
|
|
||||||
|
self.$statusbar = new Ox.Bar({
|
||||||
|
size: 24
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
// fixme: no need to set position absolute with map statusbar
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 0,
|
||||||
|
textAlign: 'center'
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
|
||||||
|
self.$tooltip = new Ox.Tooltip({
|
||||||
|
animate: false
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
textAlign: 'center'
|
||||||
|
});
|
||||||
|
|
||||||
|
renderCalendar();
|
||||||
|
|
||||||
|
function changeDate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeZoom(event, data) {
|
||||||
|
self.options.zoom = data.value;
|
||||||
|
renderCalendar();
|
||||||
|
}
|
||||||
|
|
||||||
|
function doubleclick(event, e) {
|
||||||
|
if ($(e.target).is(':not(.OxLine > .OxDate)')) {
|
||||||
|
if (self.options.zoom < self.maxZoom) {
|
||||||
|
self.options.date = new Date(
|
||||||
|
(+self.options.date + +getMouseDate(e)) / 2
|
||||||
|
);
|
||||||
|
self.options.zoom++;
|
||||||
|
}
|
||||||
|
renderCalendar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragstart(event, e) {
|
||||||
|
if ($(e.target).is(':not(.OxLine > .OxDate)')) {
|
||||||
|
self.drag = {x: e.clientX};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drag(event, e) {
|
||||||
|
if (self.drag) {
|
||||||
|
///*
|
||||||
|
self.$content.css({
|
||||||
|
marginLeft: (e.clientX - self.drag.x) + 'px'
|
||||||
|
});
|
||||||
|
self.$scrollbar.css({
|
||||||
|
marginLeft: Math.round((e.clientX - self.drag.x) / 16) + 'px'
|
||||||
|
});
|
||||||
|
//*/
|
||||||
|
/*
|
||||||
|
self.options.date = new Date(
|
||||||
|
+self.options.date - e.clientDX * getSecondsPerPixel() * 1000
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
//self.drag = {x: e.clientX};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragpause(event, e) {
|
||||||
|
if (self.drag) {
|
||||||
|
dragafter(e);
|
||||||
|
self.drag = {x: e.clientX};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragend(event, e) {
|
||||||
|
if (self.drag) {
|
||||||
|
dragafter(e);
|
||||||
|
self.drag = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragafter(e) {
|
||||||
|
self.options.date = new Date(
|
||||||
|
+self.options.date - (e.clientX - self.drag.x) * getSecondsPerPixel() * 1000
|
||||||
|
);
|
||||||
|
self.$content.css({
|
||||||
|
marginLeft: 0
|
||||||
|
});
|
||||||
|
self.$scrollbar.css({
|
||||||
|
marginLeft: 0
|
||||||
|
});
|
||||||
|
renderCalendar();
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragstartScrollbar(event, e) {
|
||||||
|
self.drag = {x: e.clientX};
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragScrollbar(event, e) {
|
||||||
|
self.$content.css({
|
||||||
|
marginLeft: ((e.clientX - self.drag.x) * 16) + 'px'
|
||||||
|
});
|
||||||
|
self.$scrollbar.css({
|
||||||
|
marginLeft: (e.clientX - self.drag.x) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragpauseScrollbar(event, e) {
|
||||||
|
dragafterScrollbar(e);
|
||||||
|
self.drag = {x: e.clientX};
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragendScrollbar(event, e) {
|
||||||
|
dragafterScrollbar(e);
|
||||||
|
self.drag = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragafterScrollbar(e) {
|
||||||
|
self.options.date = new Date(
|
||||||
|
+self.options.date + (self.drag.x - e.clientX) * getSecondsPerPixel() * 1000 * 16
|
||||||
|
);
|
||||||
|
// fixme: duplicated
|
||||||
|
self.$content.css({
|
||||||
|
marginLeft: 0
|
||||||
|
});
|
||||||
|
self.$scrollbar.css({
|
||||||
|
marginLeft: 0
|
||||||
|
});
|
||||||
|
renderCalendar();
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDate(date) {
|
||||||
|
var isFullDays = Ox.formatDate(date.start, '%H:%M:%S') == '00:00:00' &&
|
||||||
|
Ox.formatDate(date.stop, '%H:%M:%S') == '00:00:00',
|
||||||
|
isOneDay = isFullDays && date.stop - date.start == 86400000, // fixme: wrong, DST
|
||||||
|
isSameDay = Ox.formatDate(date.start, '%Y-%m-%d') ==
|
||||||
|
Ox.formatDate(date.stop, '%Y-%m-%d'),
|
||||||
|
isSameYear = date.start.getFullYear() == date.stop.getFullYear(),
|
||||||
|
timeFormat = isFullDays ? '' : ', %H:%M:%S',
|
||||||
|
str = Ox.formatDate(date.start, '%a, %b %e');
|
||||||
|
if (isOneDay || isSameDay || !isSameYear) {
|
||||||
|
str += Ox.formatDate(date.start, ', %Y' + timeFormat);
|
||||||
|
}
|
||||||
|
if (!isOneDay && !isSameDay) {
|
||||||
|
str += Ox.formatDate(date.stop, ' - %a, %b %e, %Y' + timeFormat);
|
||||||
|
}
|
||||||
|
if (isSameDay) {
|
||||||
|
str += Ox.formatDate(date.stop, ' - ' + timeFormat.replace(', ', ''));
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCalendarDate() {
|
||||||
|
var ms = self.options.width * getSecondsPerPixel() * 1000;
|
||||||
|
return {
|
||||||
|
start: new Date(+self.options.date - ms / 2),
|
||||||
|
stop: new Date(+self.options.date + ms / 2)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDateByName(name) {
|
||||||
|
var date = {};
|
||||||
|
Ox.forEach(self.options.dates, function(v) {
|
||||||
|
if (v.name == name) {
|
||||||
|
date = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDateElement(date, zoom) {
|
||||||
|
var left = getPosition(date.start, zoom),
|
||||||
|
width = Math.max(getPosition(date.stop, zoom) - left, 1);
|
||||||
|
return new Ox.Element()
|
||||||
|
.addClass('OxDate')
|
||||||
|
.css({
|
||||||
|
left: left + 'px',
|
||||||
|
width: width + 'px'
|
||||||
|
})
|
||||||
|
.data({
|
||||||
|
name: date.name
|
||||||
|
})
|
||||||
|
.html(' ' + date.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMouseDate(e) {
|
||||||
|
return new Date(+self.options.date + (
|
||||||
|
e.clientX - that.offset().left - self.options.width / 2 - 1
|
||||||
|
) * getSecondsPerPixel() * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPixelsPerSecond(zoom) {
|
||||||
|
return Math.pow(2, (zoom || self.options.zoom) - (self.maxZoom - 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPosition(date, zoom) {
|
||||||
|
return Math.round(
|
||||||
|
self.options.width / 2 +
|
||||||
|
(date - self.options.date) / 1000 *
|
||||||
|
getPixelsPerSecond(zoom || self.options.zoom)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSecondsPerPixel(zoom) {
|
||||||
|
return 1 / getPixelsPerSecond(zoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBackgroundElements(zoom) {
|
||||||
|
// fixme: duplicated
|
||||||
|
var $elements = [],
|
||||||
|
units = getUnits(zoom),
|
||||||
|
n, value, width;
|
||||||
|
[1, 0].forEach(function(u) {
|
||||||
|
var unit = units[u],
|
||||||
|
value = unit.value(self.options.date),
|
||||||
|
width = unit.seconds * getPixelsPerSecond(zoom),
|
||||||
|
n = Math.ceil(self.options.width * 1.5/* * 16*/ / width);
|
||||||
|
Ox.loop(-n, n + 1, function(i) {
|
||||||
|
$elements.push(
|
||||||
|
new Ox.Element()
|
||||||
|
.addClass(
|
||||||
|
u == 0 ? 'line' : Ox.mod(value + i, 2) == 0 ? 'even' : 'odd'
|
||||||
|
)
|
||||||
|
.css({
|
||||||
|
left: getPosition(new Date(unit.date(value + i)), zoom) + 'px',
|
||||||
|
width: (u == 0 ? 1 : width) + 'px'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return $elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimelineElements(zoom) {
|
||||||
|
var $elements = [],
|
||||||
|
unit = getUnits(zoom)[0],
|
||||||
|
value = unit.value(self.options.date),
|
||||||
|
width = unit.seconds * getPixelsPerSecond(zoom);
|
||||||
|
n = Math.ceil(self.options.width * 1.5/* * 16*/ / width);
|
||||||
|
Ox.loop(-n, n + 1, function(i) {
|
||||||
|
$elements.push(
|
||||||
|
getDateElement({
|
||||||
|
name: unit.name(value + i),
|
||||||
|
start: new Date(unit.date(value + i)),
|
||||||
|
stop: new Date(unit.date(value + i + 1))
|
||||||
|
}, zoom)
|
||||||
|
.addClass(Ox.mod(value + i, 2) == 0 ? 'even' : 'odd')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return $elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUnits(zoom) {
|
||||||
|
// returns array of 2 units
|
||||||
|
// units[0] for timeline
|
||||||
|
// units[1] for background
|
||||||
|
var pixelsPerSecond = getPixelsPerSecond(zoom),
|
||||||
|
units;
|
||||||
|
self.units = self.units.reverse();
|
||||||
|
Ox.forEach(self.units, function(v, i) {
|
||||||
|
width = Math.round(v.seconds * pixelsPerSecond);
|
||||||
|
if (width >= self.minLabelWidth) {
|
||||||
|
units = [self.units[i], self.units[i - 1]];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.units = self.units.reverse();
|
||||||
|
return units;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseleave() {
|
||||||
|
self.$tooltip.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousemove(e) {
|
||||||
|
var $target = $(e.target),
|
||||||
|
date, title;
|
||||||
|
if ($target.is('.OxLine > .OxDate')) {
|
||||||
|
date = getDateByName($target.data('name'));
|
||||||
|
title = '<span class="OxBright">' + date.name + '</span><br/>' +
|
||||||
|
formatDate(date);
|
||||||
|
} else {
|
||||||
|
title = Ox.formatDate(getMouseDate(e), '%a, %b %e, %Y, %H:%M:%S');
|
||||||
|
}
|
||||||
|
self.$tooltip.options({
|
||||||
|
title: title
|
||||||
|
})
|
||||||
|
.show(e.clientX, e.clientY);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousewheel(e, delta, deltaX, deltaY) {
|
||||||
|
//Ox.print('mousewheel', delta, deltaX, deltaY);
|
||||||
|
var deltaZ = 0;
|
||||||
|
if (!self.mousewheel && deltaY && Math.abs(deltaY) > Math.abs(deltaX)) {
|
||||||
|
if (deltaY < 0 && self.options.zoom > 0) {
|
||||||
|
deltaZ = -1
|
||||||
|
} else if (deltaY > 0 && self.options.zoom < self.maxZoom) {
|
||||||
|
deltaZ = 1
|
||||||
|
}
|
||||||
|
if (deltaZ) {
|
||||||
|
self.options.date = deltaZ == -1 ?
|
||||||
|
new Date(2 * +self.options.date - +getMouseDate(e)) :
|
||||||
|
new Date((+self.options.date + +getMouseDate(e)) / 2)
|
||||||
|
self.options.zoom += deltaZ;
|
||||||
|
self.$zoomInput.options({value: self.options.zoom});
|
||||||
|
renderCalendar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.mousewheel = true;
|
||||||
|
setTimeout(function() {
|
||||||
|
self.mousewheel = false;
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
function overlaps(date0, date1) {
|
||||||
|
return (
|
||||||
|
date0.start >= date1.start && date0.start < date1.stop
|
||||||
|
) || (
|
||||||
|
date1.start >= date0.start && date1.start < date0.stop
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderCalendar() {
|
||||||
|
$('.OxBackground').empty();
|
||||||
|
$('.OxDate').remove();
|
||||||
|
renderBackground();
|
||||||
|
renderTimelines();
|
||||||
|
renderDates();
|
||||||
|
self.$statusbar.html(
|
||||||
|
Ox.formatDate(self.options.date, '%Y-%m-%d %H:%M:%S %s')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderBackground() {
|
||||||
|
getBackgroundElements(self.options.zoom).forEach(function($element) {
|
||||||
|
$element.appendTo(self.$background);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDates() {
|
||||||
|
var calendarDate = getCalendarDate();
|
||||||
|
lineDates = [];
|
||||||
|
self.options.dates.filter(function(date) {
|
||||||
|
// filter out dates outside the visible area
|
||||||
|
return overlaps(date, calendarDate);
|
||||||
|
}).sort(function(a, b) {
|
||||||
|
// sort dates by duration, descending
|
||||||
|
return (b.stop - b.start) - (a.stop - a.start);
|
||||||
|
}).forEach(function(date, i) {
|
||||||
|
var line = lineDates.length;
|
||||||
|
// traverse lines
|
||||||
|
Ox.forEach(lineDates, function(dates, line_) {
|
||||||
|
var fits = true;
|
||||||
|
// traverse dates in line
|
||||||
|
Ox.forEach(dates, function(date_) {
|
||||||
|
// if overlaps, check next line
|
||||||
|
if (overlaps(date, date_)) {
|
||||||
|
fits = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (fits) {
|
||||||
|
line = line_;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (line == lineDates.length) {
|
||||||
|
lineDates[line] = [];
|
||||||
|
}
|
||||||
|
lineDates[line].push(date);
|
||||||
|
});
|
||||||
|
$('.OxLine').remove();
|
||||||
|
lineDates.forEach(function(dates, line) {
|
||||||
|
var $line = new Ox.Element()
|
||||||
|
.addClass('OxLine')
|
||||||
|
.css({
|
||||||
|
top: ((line + 1) * 16) + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$content);
|
||||||
|
dates.sort(function(a, b) {
|
||||||
|
// sort dates by start, ascending
|
||||||
|
return a.start - b.start;
|
||||||
|
}).forEach(function(date) {
|
||||||
|
getDateElement(date).appendTo($line);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTimelines() {
|
||||||
|
Ox.print(self.options.zoom, Math.max(self.options.zoom - 4, 0))
|
||||||
|
getTimelineElements(self.options.zoom).forEach(function($element) {
|
||||||
|
$element.appendTo(self.$scalebar.$element);
|
||||||
|
});
|
||||||
|
getTimelineElements(Math.max(self.options.zoom - 4, 0)).forEach(function($element) {
|
||||||
|
$element.appendTo(self.$scrollbar.$element);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function singleclick(event, e) {
|
||||||
|
if ($(e.target).is(':not(.OxLine > .OxDate)')) {
|
||||||
|
self.options.date = getMouseDate(e);
|
||||||
|
renderCalendar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, val) {
|
||||||
|
if (key == 'date') {
|
||||||
|
|
||||||
|
} else if (key == 'zoom') {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
25
source/js/Ox.CalendarDate.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
Ox.CalendarDate = function(options) {
|
||||||
|
|
||||||
|
var self = {},
|
||||||
|
that = this;
|
||||||
|
|
||||||
|
['start', 'stop'].forEach(function(v) {
|
||||||
|
var date = self.options[v];
|
||||||
|
if (Ox.isString(date)) {
|
||||||
|
date = new Date(self.options[v]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.duration = self.options.stop - self.options.start;
|
||||||
|
|
||||||
|
that.format = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.formatDuration = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
104
source/js/Ox.Checkbox.js
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
Ox.Checkbox = function(options, self) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
options
|
||||||
|
disabled boolean, if true, checkbox is disabled
|
||||||
|
id element id
|
||||||
|
group boolean, if true, checkbox is part of a group
|
||||||
|
checked boolean, if true, checkbox is checked
|
||||||
|
title string, text on label
|
||||||
|
width integer, width in px
|
||||||
|
methods:
|
||||||
|
toggleChecked function()
|
||||||
|
toggles checked property
|
||||||
|
returns that
|
||||||
|
events:
|
||||||
|
change triggered when checked property changes
|
||||||
|
passes {checked, id, title}
|
||||||
|
*/
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
disabled: false,
|
||||||
|
id: '',
|
||||||
|
group: false,
|
||||||
|
checked: false,
|
||||||
|
overlap: 'none',
|
||||||
|
title: '',
|
||||||
|
width: 'auto'
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxCheckbox' +
|
||||||
|
(self.options.overlap == 'none' ? '' : ' OxOverlap' +
|
||||||
|
Ox.toTitleCase(self.options.overlap))
|
||||||
|
)
|
||||||
|
.attr(self.options.disabled ? {
|
||||||
|
disabled: 'disabled'
|
||||||
|
} : {});
|
||||||
|
|
||||||
|
if (self.options.title) {
|
||||||
|
self.options.width != 'auto' && that.css({
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
self.$title = new Ox.Label({
|
||||||
|
disabled: self.options.disabled,
|
||||||
|
id: self.options.id + 'Label',
|
||||||
|
overlap: 'left',
|
||||||
|
title: self.options.title,
|
||||||
|
width: self.options.width - 16
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'right'
|
||||||
|
})
|
||||||
|
.click(clickTitle)
|
||||||
|
.appendTo(that);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.$button = new Ox.Button({
|
||||||
|
disabled: self.options.disabled,
|
||||||
|
id: self.options.id + 'Button',
|
||||||
|
title: [
|
||||||
|
{id: 'none', title: 'none', selected: !self.options.checked},
|
||||||
|
{id: 'check', title: 'check', selected: self.options.checked}
|
||||||
|
],
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.addClass('OxCheckbox')
|
||||||
|
.click(clickButton)
|
||||||
|
.appendTo(that);
|
||||||
|
|
||||||
|
function clickButton() {
|
||||||
|
self.options.checked = !self.options.checked;
|
||||||
|
// click will have toggled the button,
|
||||||
|
// if it is part of a group, we have to revert that
|
||||||
|
self.options.group && that.toggleChecked();
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
checked: self.options.checked,
|
||||||
|
id: self.options.id,
|
||||||
|
title: self.options.title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickTitle() {
|
||||||
|
!self.options.disabled && self.$button.trigger('click');
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'checked') {
|
||||||
|
that.toggleChecked();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.checked = function() {
|
||||||
|
return self.options.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.toggleChecked = function() {
|
||||||
|
self.$button.toggleTitle();
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
70
source/js/Ox.CheckboxGroup.js
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
Ox.CheckboxGroup = function(options, self) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
options
|
||||||
|
checkboxes [] array of checkboxes
|
||||||
|
max 1 integer
|
||||||
|
min 1 integer
|
||||||
|
width integer, width in px
|
||||||
|
events:
|
||||||
|
change triggered when checked property changes
|
||||||
|
passes {checked, id, title}
|
||||||
|
*/
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
checkboxes: [],
|
||||||
|
max: 1,
|
||||||
|
min: 1,
|
||||||
|
width: 256
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxCheckboxGroup');
|
||||||
|
|
||||||
|
self.optionGroup = new Ox.OptionGroup(
|
||||||
|
self.options.checkboxes,
|
||||||
|
self.options.min,
|
||||||
|
self.options.max);
|
||||||
|
self.options.checkboxes = self.optionGroup.init();
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
$checkboxes: [],
|
||||||
|
checkboxWidth: $.map(Ox.divideInt(
|
||||||
|
self.options.width + (self.options.checkboxes.length - 1) * 6,
|
||||||
|
self.options.checkboxes.length
|
||||||
|
), function(v, i) {
|
||||||
|
return v + (i < self.options.checkboxes.length - 1 ? 10 : 0);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
self.options.checkboxes.forEach(function(checkbox, position) {
|
||||||
|
var id = self.options.id + Ox.toTitleCase(checkbox.id)
|
||||||
|
self.$checkboxes[position] = new Ox.Checkbox($.extend(checkbox, {
|
||||||
|
group: true,
|
||||||
|
id: id,
|
||||||
|
width: self.checkboxWidth[position]
|
||||||
|
}))
|
||||||
|
.bindEvent('change', function() {
|
||||||
|
change(position);
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
});
|
||||||
|
|
||||||
|
function change(pos) {
|
||||||
|
var toggled = self.optionGroup.toggle(pos);
|
||||||
|
//Ox.print('change', pos, 'toggled', toggled)
|
||||||
|
if (toggled.length) {
|
||||||
|
toggled.forEach(function(pos, i) {
|
||||||
|
self.$checkboxes[pos].toggleChecked();
|
||||||
|
});
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
checked: $.map(self.optionGroup.checked(), function(v, i) {
|
||||||
|
return self.options.checkboxes[v].id;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
22
source/js/Ox.Clipboard.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Ox.Clipboard = function() {
|
||||||
|
/***
|
||||||
|
Ox.Clipboard
|
||||||
|
Basic clipboard handler
|
||||||
|
Methods
|
||||||
|
copy(data) copy data to clipboard
|
||||||
|
paste paste data from clipboard
|
||||||
|
***/
|
||||||
|
var clipboard = {};
|
||||||
|
return {
|
||||||
|
_print: function() {
|
||||||
|
Ox.print(JSON.stringify(clipboard));
|
||||||
|
},
|
||||||
|
copy: function(data) {
|
||||||
|
clipboard = data;
|
||||||
|
Ox.print('copy', JSON.stringify(clipboard));
|
||||||
|
},
|
||||||
|
paste: function(type) {
|
||||||
|
return clipboard;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}();
|
83
source/js/Ox.CollapsePanel.js
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
Ox.CollapsePanel = function(options, self) {
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Panel({}, self)
|
||||||
|
.defaults({
|
||||||
|
collapsed: false,
|
||||||
|
extras: [],
|
||||||
|
size: 16,
|
||||||
|
title: ''
|
||||||
|
})
|
||||||
|
.options(options)
|
||||||
|
.addClass('OxCollapsePanel'),
|
||||||
|
// fixme: the following should all be self.foo
|
||||||
|
title = self.options.collapsed ?
|
||||||
|
[{id: 'expand', title: 'right'}, {id: 'collapse', title: 'down'}] :
|
||||||
|
[{id: 'collapse', title: 'down'}, {id: 'expand', title: 'right'}],
|
||||||
|
$titlebar = new Ox.Bar({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
size: self.options.size,
|
||||||
|
})
|
||||||
|
.dblclick(dblclickTitlebar)
|
||||||
|
.appendTo(that),
|
||||||
|
$switch = new Ox.Button({
|
||||||
|
style: 'symbol',
|
||||||
|
title: title,
|
||||||
|
type: 'image',
|
||||||
|
})
|
||||||
|
.click(toggleCollapsed)
|
||||||
|
.appendTo($titlebar),
|
||||||
|
$title = new Ox.Element()
|
||||||
|
.addClass('OxTitle')
|
||||||
|
.html(self.options.title/*.toUpperCase()*/)
|
||||||
|
.appendTo($titlebar),
|
||||||
|
$extras;
|
||||||
|
if (self.options.extras.length) {
|
||||||
|
$extras = new Ox.Element()
|
||||||
|
.addClass('OxExtras')
|
||||||
|
.appendTo($titlebar);
|
||||||
|
self.options.extras.forEach(function($extra) {
|
||||||
|
$extra.appendTo($extras);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
that.$content = new Ox.Element()
|
||||||
|
.addClass('OxContent')
|
||||||
|
.appendTo(that);
|
||||||
|
// fixme: doesn't work, content still empty
|
||||||
|
// need to hide it if collapsed
|
||||||
|
if (self.options.collapsed) {
|
||||||
|
that.$content.css({
|
||||||
|
marginTop: -that.$content.height() + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function dblclickTitlebar(e) {
|
||||||
|
if (!$(e.target).hasClass('OxButton')) {
|
||||||
|
$switch.trigger('click');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function toggleCollapsed() {
|
||||||
|
var marginTop;
|
||||||
|
self.options.collapsed = !self.options.collapsed;
|
||||||
|
marginTop = self.options.collapsed ? -that.$content.height() : 0;
|
||||||
|
that.$content.animate({
|
||||||
|
marginTop: marginTop + 'px'
|
||||||
|
}, 200);
|
||||||
|
that.triggerEvent('toggle', {
|
||||||
|
collapsed: self.options.collapsed
|
||||||
|
});
|
||||||
|
}
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'collapsed') {
|
||||||
|
|
||||||
|
} else if (key == 'title') {
|
||||||
|
$title.html(self.options.title);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
that.update = function() { // fixme: used anywhere?
|
||||||
|
self.options.collapsed && that.$content.css({
|
||||||
|
marginTop: -that.$content.height()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return that;
|
||||||
|
};
|
71
source/js/Ox.ColorInput.js
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
Ox.ColorInput = function(options, self) {
|
||||||
|
|
||||||
|
var self = $.extend(self || {}, {
|
||||||
|
options: $.extend({
|
||||||
|
id: '',
|
||||||
|
value: '0, 0, 0'
|
||||||
|
}, options)
|
||||||
|
}),
|
||||||
|
that;
|
||||||
|
|
||||||
|
self.values = self.options.value.split(', ');
|
||||||
|
self.$inputs = [];
|
||||||
|
['red', 'green', 'blue'].forEach(function(v, i) {
|
||||||
|
self.$inputs[i] = new Ox.Input({
|
||||||
|
id: v,
|
||||||
|
max: 255,
|
||||||
|
type: 'integer',
|
||||||
|
value: self.values[i],
|
||||||
|
width: 36
|
||||||
|
})
|
||||||
|
.bindEvent('autovalidate', change);
|
||||||
|
});
|
||||||
|
self.$inputs[3] = new Ox.Label({
|
||||||
|
id: 'color',
|
||||||
|
width: 36
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
background: 'rgb(' + self.options.value + ')'
|
||||||
|
});
|
||||||
|
self.$inputs[4] = new Ox.ColorPicker({
|
||||||
|
id: 'picker'
|
||||||
|
})
|
||||||
|
.bindEvent('change', function(event, data) {
|
||||||
|
//Ox.print('change function called');
|
||||||
|
self.options.value = data.value;
|
||||||
|
self.values = data.value.split(', ');
|
||||||
|
Ox.range(3).forEach(function(i) {
|
||||||
|
self.$inputs[i].options({
|
||||||
|
value: self.values[i]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.options({
|
||||||
|
width: 16 // this is just a hack to make the InputGroup layout work
|
||||||
|
});
|
||||||
|
|
||||||
|
that = new Ox.InputGroup({
|
||||||
|
id: self.options.id,
|
||||||
|
inputs: self.$inputs,
|
||||||
|
separators: [
|
||||||
|
{title: ',', width: 8},
|
||||||
|
{title: ',', width: 8},
|
||||||
|
{title: '', width: 8},
|
||||||
|
{title: '', width: 8}
|
||||||
|
],
|
||||||
|
value: self.options.value // fixme: it'd be nicer if this would be taken care of by passing self
|
||||||
|
}, self)
|
||||||
|
.bindEvent('change', change);
|
||||||
|
|
||||||
|
function change() {
|
||||||
|
self.options.value = $.map(self.$inputs, function(v, i) {
|
||||||
|
return v.options('value');
|
||||||
|
}).join(', ');
|
||||||
|
self.$inputs[3].css({
|
||||||
|
background: 'rgb(' + self.options.value + ')'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
91
source/js/Ox.ColorPicker.js
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
Ox.ColorPicker = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
id: '',
|
||||||
|
value: '0, 0, 0'
|
||||||
|
})
|
||||||
|
.options(options || {});
|
||||||
|
|
||||||
|
//Ox.print(self)
|
||||||
|
self.$ranges = [];
|
||||||
|
self.rgb = ['red', 'green', 'blue'];
|
||||||
|
self.values = self.options.value.split(', ');
|
||||||
|
|
||||||
|
Ox.range(3).forEach(function(i) {
|
||||||
|
self.$ranges[i] = new Ox.Range({
|
||||||
|
arrows: true,
|
||||||
|
id: self.options.id + Ox.toTitleCase(self.rgb[i]),
|
||||||
|
max: 255,
|
||||||
|
size: 328, // 256 + 16 + 40 + 16
|
||||||
|
thumbSize: 40,
|
||||||
|
thumbValue: true,
|
||||||
|
trackColors: getColors(i),
|
||||||
|
value: self.values[i]
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
top: (i * 15) + 'px'
|
||||||
|
})
|
||||||
|
.bindEvent('change', function(event, data) {
|
||||||
|
change(i, data.value);
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
// fixme: make self.$ranges[i].children() work
|
||||||
|
if (i == 0) {
|
||||||
|
self.$ranges[i].$element.children('input.OxOverlapRight').css({
|
||||||
|
MozBorderRadius: 0,
|
||||||
|
WebkitBorderRadius: 0
|
||||||
|
});
|
||||||
|
self.$ranges[i].$element.children('input.OxOverlapLeft').css({
|
||||||
|
MozBorderRadius: '0 8px 0 0',
|
||||||
|
WebkitBorderRadius: '0 8px 0 0'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.$ranges[i].$element.children('input').css({
|
||||||
|
MozBorderRadius: 0,
|
||||||
|
WebkitBorderRadius: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
that = new Ox.Picker({
|
||||||
|
element: that,
|
||||||
|
elementHeight: 46,
|
||||||
|
elementWidth: 328,
|
||||||
|
id: self.options.id
|
||||||
|
});
|
||||||
|
|
||||||
|
function change(index, value) {
|
||||||
|
self.values[index] = value;
|
||||||
|
self.options.value = self.values.join(', ');
|
||||||
|
that.$label.css({
|
||||||
|
background: 'rgb(' + self.options.value + ')'
|
||||||
|
});
|
||||||
|
Ox.range(3).forEach(function(i) {
|
||||||
|
if (i != index) {
|
||||||
|
self.$ranges[i].options({
|
||||||
|
trackColors: getColors(i)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
value: self.options.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getColors(index) {
|
||||||
|
return [
|
||||||
|
'rgb(' + $.map(Ox.range(3), function(v) {
|
||||||
|
return v == index ? 0 : self.values[v];
|
||||||
|
}).join(', ') + ')',
|
||||||
|
'rgb(' + $.map(Ox.range(3), function(v) {
|
||||||
|
return v == index ? 255 : self.values[v];
|
||||||
|
}).join(', ') + ')'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
16
source/js/Ox.Container.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// fixme: wouldn't it be better to let the elements be,
|
||||||
|
// rather then $element, $content, and potentially others,
|
||||||
|
// 0, 1, 2, etc, so that append would append 0, and appendTo
|
||||||
|
// would append (length - 1)?
|
||||||
|
|
||||||
|
Ox.Container = function(options, self) {
|
||||||
|
// fixme: to be deprecated
|
||||||
|
var that = new Ox.Element('div', self)
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxContainer');
|
||||||
|
that.$content = new Ox.Element('div', self)
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxContent')
|
||||||
|
.appendTo(that);
|
||||||
|
return that;
|
||||||
|
};
|
217
source/js/Ox.DateInput.js
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
Ox.DateInput = function(options, self) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
options:
|
||||||
|
format: 'short'
|
||||||
|
value: date value
|
||||||
|
weekday: false
|
||||||
|
width: {
|
||||||
|
day: 32,
|
||||||
|
month: options.format == 'long' ? 80 : (options.format == 'medium' ? 40 : 32),
|
||||||
|
weekday: options.format == 'long' ? 80 : 40,
|
||||||
|
year: 48
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
var self = $.extend(self || {}, {
|
||||||
|
options: $.extend({
|
||||||
|
format: 'short',
|
||||||
|
value: Ox.formatDate(new Date(), '%F'),
|
||||||
|
weekday: false,
|
||||||
|
width: {
|
||||||
|
day: 32,
|
||||||
|
month: options.format == 'long' ? 80 : (options.format == 'medium' ? 40 : 32),
|
||||||
|
weekday: options.format == 'long' ? 80 : 40,
|
||||||
|
year: 48
|
||||||
|
}
|
||||||
|
}, options)
|
||||||
|
}),
|
||||||
|
that;
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
date: new Date(self.options.value.replace(/-/g, '/')),
|
||||||
|
formats: {
|
||||||
|
day: '%d',
|
||||||
|
month: self.options.format == 'short' ? '%m' :
|
||||||
|
(self.options.format == 'medium' ? '%b' : '%B'),
|
||||||
|
weekday: self.options.format == 'long' ? '%A' : '%a',
|
||||||
|
year: '%Y'
|
||||||
|
},
|
||||||
|
months: self.options.format == 'long' ? Ox.MONTHS : $.map(Ox.MONTHS, function(v, i) {
|
||||||
|
return v.substr(0, 3);
|
||||||
|
}),
|
||||||
|
weekdays: self.options.format == 'long' ? Ox.WEEKDAYS : $.map(Ox.WEEKDAYS, function(v, i) {
|
||||||
|
return v.substr(0, 3);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$input = $.extend(self.options.weekday ? {
|
||||||
|
weekday: new Ox.Input({
|
||||||
|
autocomplete: self.weekdays,
|
||||||
|
autocompleteReplace: true,
|
||||||
|
autocompleteReplaceCorrect: true,
|
||||||
|
id: 'weekday',
|
||||||
|
value: Ox.formatDate(self.date, self.formats.weekday),
|
||||||
|
width: self.options.width.weekday
|
||||||
|
})
|
||||||
|
.bindEvent('autocomplete', changeWeekday),
|
||||||
|
} : {}, {
|
||||||
|
day: new Ox.Input({
|
||||||
|
autocomplete: $.map(Ox.range(1, Ox.getDaysInMonth(
|
||||||
|
parseInt(Ox.formatDate(self.date, '%Y'), 10),
|
||||||
|
parseInt(Ox.formatDate(self.date, '%m'), 10)
|
||||||
|
) + 1), function(v, i) {
|
||||||
|
return self.options.format == 'short' ? Ox.pad(v, 2) : v.toString();
|
||||||
|
}),
|
||||||
|
autocompleteReplace: true,
|
||||||
|
autocompleteReplaceCorrect: true,
|
||||||
|
id: 'day',
|
||||||
|
value: Ox.formatDate(self.date, self.formats.day),
|
||||||
|
textAlign: 'right',
|
||||||
|
width: self.options.width.day
|
||||||
|
})
|
||||||
|
.bindEvent('autocomplete', changeDay),
|
||||||
|
month: new Ox.Input({
|
||||||
|
autocomplete: self.options.format == 'short' ? $.map(Ox.range(1, 13), function(v, i) {
|
||||||
|
return Ox.pad(v, 2);
|
||||||
|
}) : self.months,
|
||||||
|
autocompleteReplace: true,
|
||||||
|
autocompleteReplaceCorrect: true,
|
||||||
|
id: 'month',
|
||||||
|
value: Ox.formatDate(self.date, self.formats.month),
|
||||||
|
textAlign: self.options.format == 'short' ? 'right' : 'left',
|
||||||
|
width: self.options.width.month
|
||||||
|
})
|
||||||
|
.bindEvent('autocomplete', changeMonthOrYear),
|
||||||
|
year: new Ox.Input({
|
||||||
|
autocomplete: $.map($.merge(Ox.range(1900, 3000), Ox.range(1000, 1900)), function(v, i) {
|
||||||
|
return v.toString();
|
||||||
|
}),
|
||||||
|
autocompleteReplace: true,
|
||||||
|
autocompleteReplaceCorrect: true,
|
||||||
|
id: 'year',
|
||||||
|
value: Ox.formatDate(self.date, self.formats.year),
|
||||||
|
textAlign: 'right',
|
||||||
|
width: self.options.width.year
|
||||||
|
})
|
||||||
|
.bindEvent('autocomplete', changeMonthOrYear)
|
||||||
|
});
|
||||||
|
|
||||||
|
that = new Ox.InputGroup($.extend(self.options, {
|
||||||
|
id: self.options.id,
|
||||||
|
inputs: $.merge(self.options.weekday ? [
|
||||||
|
self.$input.weekday
|
||||||
|
] : [], self.options.format == 'short' ? [
|
||||||
|
self.$input.year, self.$input.month, self.$input.day
|
||||||
|
] : [
|
||||||
|
self.$input.month, self.$input.day, self.$input.year
|
||||||
|
]),
|
||||||
|
separators: $.merge(self.options.weekday ? [
|
||||||
|
{title: self.options.format == 'short' ? '' : ',', width: 8},
|
||||||
|
] : [], self.options.format == 'short' ? [
|
||||||
|
{title: '-', width: 8}, {title: '-', width: 8}
|
||||||
|
] : [
|
||||||
|
{title: '', width: 8}, {title: ',', width: 8}
|
||||||
|
]),
|
||||||
|
width: 0
|
||||||
|
}), self);
|
||||||
|
|
||||||
|
//Ox.print('SELF', self)
|
||||||
|
|
||||||
|
function changeDay() {
|
||||||
|
self.options.weekday && self.$input.weekday.options({
|
||||||
|
value: Ox.formatDate(new Date([
|
||||||
|
self.$input.month.options('value'),
|
||||||
|
self.$input.day.options('value'),
|
||||||
|
self.$input.year.options('value')
|
||||||
|
].join(' ')), self.formats.weekday)
|
||||||
|
});
|
||||||
|
setValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeMonthOrYear() {
|
||||||
|
var day = self.$input.day.options('value'),
|
||||||
|
month = self.$input.month.options('value'),
|
||||||
|
year = self.$input.year.options('value'),
|
||||||
|
days = Ox.getDaysInMonth(year, self.options.format == 'short' ? parseInt(month, 10) : month);
|
||||||
|
day = day <= days ? day : days;
|
||||||
|
//Ox.print(year, month, 'day days', day, days)
|
||||||
|
self.options.weekday && self.$input.weekday.options({
|
||||||
|
value: Ox.formatDate(new Date([month, day, year].join(' ')), self.formats.weekday)
|
||||||
|
});
|
||||||
|
self.$input.day.options({
|
||||||
|
autocomplete: $.map(Ox.range(1, days + 1), function(v, i) {
|
||||||
|
return self.options.format == 'short' ? Ox.pad(v, 2) : v.toString();
|
||||||
|
}),
|
||||||
|
value: self.options.format == 'short' ? Ox.pad(day, 2) : day.toString()
|
||||||
|
});
|
||||||
|
setValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeWeekday() {
|
||||||
|
var date = getDateInWeek(
|
||||||
|
self.$input.weekday.options('value'),
|
||||||
|
self.$input.month.options('value'),
|
||||||
|
self.$input.day.options('value'),
|
||||||
|
self.$input.year.options('value')
|
||||||
|
);
|
||||||
|
self.$input.month.options({value: date.month});
|
||||||
|
self.$input.day.options({
|
||||||
|
autocomplete: $.map(Ox.range(1, Ox.getDaysInMonth(date.year, date.month) + 1), function(v, i) {
|
||||||
|
return self.options.format == 'short' ? Ox.pad(v, 2) : v.toString();
|
||||||
|
}),
|
||||||
|
value: date.day
|
||||||
|
});
|
||||||
|
self.$input.year.options({value: date.year});
|
||||||
|
setValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDateInWeek(weekday, month, day, year) {
|
||||||
|
//Ox.print([month, day, year].join(' '))
|
||||||
|
var date = new Date([month, day, year].join(' '));
|
||||||
|
date = Ox.getDateInWeek(date, weekday);
|
||||||
|
return {
|
||||||
|
day: Ox.formatDate(date, self.formats.day),
|
||||||
|
month: Ox.formatDate(date, self.formats.month),
|
||||||
|
year: Ox.formatDate(date, self.formats.year)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setValue() {
|
||||||
|
self.options.value = Ox.formatDate(new Date(self.options.format == 'short' ? [
|
||||||
|
self.$input.year.options('value'),
|
||||||
|
self.$input.month.options('value'),
|
||||||
|
self.$input.day.options('value')
|
||||||
|
].join('/') : [
|
||||||
|
self.$input.month.options('value'),
|
||||||
|
self.$input.day.options('value'),
|
||||||
|
self.$input.year.options('value')
|
||||||
|
].join(' ')), '%F');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
function normalize() {
|
||||||
|
var year = that.getInputById('year').options('value'),
|
||||||
|
month = that.getInputById('month').options('value'),
|
||||||
|
day = that.getInputById('day').options('value')
|
||||||
|
return {
|
||||||
|
year: year,
|
||||||
|
month: self.options.format == 'short' ? month :
|
||||||
|
Ox.pad((format == 'medium' ? Ox.WEEKDAYS.map(function(v, i) {
|
||||||
|
return v.substr(0, 3);
|
||||||
|
}) : Ox.WEEKDAYS).indexOf(month), 2),
|
||||||
|
day: Ox.pad(day, 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
that.serialize = function() {
|
||||||
|
var normal = normalize();
|
||||||
|
return [normal.year, normal.month, normal.day].join('-');
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
48
source/js/Ox.DateTimeInput.js
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
Ox.DateTimeInput = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
ampm: false,
|
||||||
|
format: 'short',
|
||||||
|
seconds: false,
|
||||||
|
value: Ox.formatDate(new Date(), '%F %T'),
|
||||||
|
weekday: false
|
||||||
|
})
|
||||||
|
.options(options || {});
|
||||||
|
|
||||||
|
self.values = self.options.value.split(' ');
|
||||||
|
//Ox.print(self.values)
|
||||||
|
|
||||||
|
that = new Ox.InputGroup({
|
||||||
|
inputs: [
|
||||||
|
new Ox.DateInput({
|
||||||
|
format: self.options.format,
|
||||||
|
id: 'date',
|
||||||
|
value: self.values[0],
|
||||||
|
weekday: self.options.weekday
|
||||||
|
}),
|
||||||
|
new Ox.TimeInput({
|
||||||
|
ampm: self.options.ampm,
|
||||||
|
id: 'time',
|
||||||
|
value: self.values[1],
|
||||||
|
seconds: self.options.seconds
|
||||||
|
})
|
||||||
|
],
|
||||||
|
separators: [
|
||||||
|
{title: '', width: 8}
|
||||||
|
],
|
||||||
|
value: self.options.value
|
||||||
|
})
|
||||||
|
.bindEvent('change', setValue);
|
||||||
|
|
||||||
|
function setValue() {
|
||||||
|
self.options.value = [
|
||||||
|
self.options('inputs')[0].options('value'),
|
||||||
|
self.options('inputs')[1].options('value')
|
||||||
|
].join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
387
source/js/Ox.Dialog.js
Normal file
|
@ -0,0 +1,387 @@
|
||||||
|
Ox.Dialog = function(options, self) {
|
||||||
|
|
||||||
|
// fixme: dialog should be derived from a generic draggable
|
||||||
|
// fixme: buttons should have a close attribute, or the dialog a close id
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
title: '',
|
||||||
|
buttons: [],
|
||||||
|
content: null,
|
||||||
|
height: 216,
|
||||||
|
keys: {},
|
||||||
|
minHeight: 144,
|
||||||
|
minWidth: 256,
|
||||||
|
movable: true,
|
||||||
|
padding: 16,
|
||||||
|
resizable: true,
|
||||||
|
width: 384
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxDialog')
|
||||||
|
.bindEvent({
|
||||||
|
key_enter: function() {
|
||||||
|
keypress('enter');
|
||||||
|
},
|
||||||
|
key_escape: function() {
|
||||||
|
//Ox.print('KEY ESCAPE')
|
||||||
|
keypress('escape');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
initialWidth: self.options.width,
|
||||||
|
initialHeight: self.options.height
|
||||||
|
})
|
||||||
|
|
||||||
|
that.$titlebar = new Ox.Bar({
|
||||||
|
size: 'medium'
|
||||||
|
})
|
||||||
|
.addClass('OxTitleBar')
|
||||||
|
.appendTo(that);
|
||||||
|
self.options.movable && that.$titlebar
|
||||||
|
.dblclick(center)
|
||||||
|
.bindEvent({
|
||||||
|
dragstart: dragstart,
|
||||||
|
drag: drag
|
||||||
|
});
|
||||||
|
|
||||||
|
that.$title = new Ox.Element()
|
||||||
|
.addClass('OxTitle')
|
||||||
|
.html(self.options.title)
|
||||||
|
.appendTo(that.$titlebar);
|
||||||
|
|
||||||
|
that.$content = new Ox.Element()
|
||||||
|
.addClass('OxContent')
|
||||||
|
.css({
|
||||||
|
padding: self.options.padding + 'px',
|
||||||
|
overflow: 'auto'
|
||||||
|
})
|
||||||
|
.append(self.options.content)
|
||||||
|
.appendTo(that);
|
||||||
|
|
||||||
|
that.$buttonsbar = new Ox.Bar({})
|
||||||
|
.addClass('OxButtonsBar')
|
||||||
|
.appendTo(that);
|
||||||
|
loadButtons();
|
||||||
|
|
||||||
|
//that.$buttons[0].focus();
|
||||||
|
|
||||||
|
that.$layer = new Ox.Element() // fixme: Layer widget that would handle click?
|
||||||
|
.addClass('OxLayer')
|
||||||
|
.mousedown(mousedownLayer)
|
||||||
|
.mouseup(mouseupLayer);
|
||||||
|
|
||||||
|
function center() {
|
||||||
|
var documentHeight = Ox.UI.$document.height();
|
||||||
|
that.css({
|
||||||
|
left: 0,
|
||||||
|
top: Math.max(parseInt(-documentHeight / 10), self.options.height - documentHeight + 40) + 'px',
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
margin: 'auto'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragstart(event, e) {
|
||||||
|
self.drag = {
|
||||||
|
bodyWidth: Ox.UI.$body.width(),
|
||||||
|
bodyHeight: Ox.UI.$document.height(),
|
||||||
|
elementWidth: that.width(),
|
||||||
|
offset: that.offset(),
|
||||||
|
x: e.clientX,
|
||||||
|
y: e.clientY
|
||||||
|
};
|
||||||
|
that.css({
|
||||||
|
margin: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function drag(event, e) {
|
||||||
|
var left = Ox.limit(
|
||||||
|
self.drag.offset.left - self.drag.x + e.clientX,
|
||||||
|
24 - self.drag.elementWidth, self.drag.bodyWidth - 24
|
||||||
|
//0, self.drag.documentWidth - self.drag.elementWidth
|
||||||
|
),
|
||||||
|
top = Ox.limit(
|
||||||
|
self.drag.offset.top - self.drag.y + e.clientY,
|
||||||
|
24, self.drag.bodyHeight - 24
|
||||||
|
//24, self.drag.documentHeight - self.drag.elementHeight
|
||||||
|
);
|
||||||
|
that.css({
|
||||||
|
left: left + 'px',
|
||||||
|
top: top + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragstartResize(event, e) {
|
||||||
|
self.drag = {
|
||||||
|
documentWidth: Ox.UI.$document.width(),
|
||||||
|
documentHeight: Ox.UI.$document.height(),
|
||||||
|
elementWidth: that.width(),
|
||||||
|
elementHeight: that.height(),
|
||||||
|
offset: that.offset(),
|
||||||
|
x: e.clientX,
|
||||||
|
y: e.clientY
|
||||||
|
};
|
||||||
|
$.extend(self.drag, {
|
||||||
|
ratio: self.drag.elementWidth / self.drag.elementHeight
|
||||||
|
});
|
||||||
|
that.css({
|
||||||
|
left: self.drag.offset.left,
|
||||||
|
top: self.drag.offset.top,
|
||||||
|
margin: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragResize(event, e) {
|
||||||
|
if (!e.shiftKey) {
|
||||||
|
self.drag.ratio = self.options.width / self.options.height;
|
||||||
|
}
|
||||||
|
self.options.width = Ox.limit(
|
||||||
|
self.drag.elementWidth - self.drag.x + e.clientX,
|
||||||
|
self.options.minWidth,
|
||||||
|
Math.min(
|
||||||
|
self.drag.documentWidth,
|
||||||
|
self.drag.documentWidth - self.drag.offset.left
|
||||||
|
)
|
||||||
|
);
|
||||||
|
self.options.height = Ox.limit(
|
||||||
|
self.drag.elementHeight - self.drag.y + e.clientY,
|
||||||
|
self.options.minHeight,
|
||||||
|
Math.min(
|
||||||
|
self.drag.documentHeight,
|
||||||
|
self.drag.documentHeight - self.drag.offset.top
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (e.shiftKey) {
|
||||||
|
self.options.height = Ox.limit(
|
||||||
|
self.options.width / self.drag.ratio,
|
||||||
|
self.options.minHeight,
|
||||||
|
Math.min(
|
||||||
|
self.drag.documentHeight,
|
||||||
|
self.drag.documentHeight - self.drag.offset.top
|
||||||
|
)
|
||||||
|
);
|
||||||
|
self.options.width = self.options.height * self.drag.ratio;
|
||||||
|
}
|
||||||
|
that.width(self.options.width);
|
||||||
|
that.height(self.options.height);
|
||||||
|
that.$content.height(self.options.height - 48 - 2 * self.options.padding); // fixme: this should happen automatically
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragendResize(event, e) {
|
||||||
|
triggerResizeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getButtonById(id) {
|
||||||
|
var ret = null;
|
||||||
|
//Ox.print('that.$buttons', that.$buttons, id)
|
||||||
|
Ox.forEach(that.$buttons, function(button) {
|
||||||
|
if (button.options('id') == id) {
|
||||||
|
ret = button;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function keypress(key) {
|
||||||
|
var id = self.options.keys[key];
|
||||||
|
//Ox.print('X', key, self.options.keys)
|
||||||
|
id && getButtonById(id).$element.trigger('click');
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadButtons() {
|
||||||
|
/*Ox.print('loadButtons', $.map(self.options.buttons, function(v) {
|
||||||
|
return v;
|
||||||
|
}));*/
|
||||||
|
if (that.$buttons) {
|
||||||
|
that.$buttons.forEach(function($button) {
|
||||||
|
$button.removeElement();
|
||||||
|
});
|
||||||
|
that.$resize.removeElement();
|
||||||
|
// that.$buttonsbar.empty();
|
||||||
|
}
|
||||||
|
that.$buttons = [];
|
||||||
|
if (!Ox.isArray(self.options.buttons[0])) {
|
||||||
|
self.options.buttons = [[], self.options.buttons];
|
||||||
|
}
|
||||||
|
self.options.buttons[0].forEach(function(button, i) {
|
||||||
|
that.$buttons[i] = button
|
||||||
|
.addClass('OxLeft')
|
||||||
|
.appendTo(that.$buttonsbar);
|
||||||
|
});
|
||||||
|
if (self.options.resizable) {
|
||||||
|
that.$resize = new Ox.Element()
|
||||||
|
.addClass('OxResize')
|
||||||
|
.dblclick(reset)
|
||||||
|
.bindEvent({
|
||||||
|
dragstart: dragstartResize,
|
||||||
|
drag: dragResize,
|
||||||
|
dragend: dragendResize
|
||||||
|
})
|
||||||
|
.appendTo(that.$buttonsbar);
|
||||||
|
}
|
||||||
|
self.options.buttons[1].reverse().forEach(function(button) {
|
||||||
|
that.$buttons[that.$buttons.length] = button
|
||||||
|
.addClass('OxRight')
|
||||||
|
.appendTo(that.$buttonsbar);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousedownLayer() {
|
||||||
|
that.$layer.stop().animate({
|
||||||
|
opacity: 0.5
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseupLayer() {
|
||||||
|
that.$layer.stop().animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
$.extend(self.options, {
|
||||||
|
height: self.initialHeight,
|
||||||
|
width: self.initialWidth
|
||||||
|
});
|
||||||
|
that/*.css({
|
||||||
|
left: Math.max(that.offset().left, 24 - that.width())
|
||||||
|
})*/
|
||||||
|
.width(self.options.width)
|
||||||
|
.height(self.options.height);
|
||||||
|
that.$content.height(self.options.height - 48 - 2 * self.options.padding); // fixme: this should happen automatically
|
||||||
|
triggerResizeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerResizeEvent() {
|
||||||
|
that.triggerEvent('resize', {
|
||||||
|
width: self.options.width,
|
||||||
|
height: self.options.height
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'buttons') {
|
||||||
|
loadButtons();
|
||||||
|
/*
|
||||||
|
that.$buttonsbar.children().animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 100, function() {
|
||||||
|
loadButtons();
|
||||||
|
that.$buttonsbar.children().animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
} else if (key == 'content') {
|
||||||
|
that.$content.html(value);
|
||||||
|
} else if (key == 'height' || key == 'width') {
|
||||||
|
that.animate({
|
||||||
|
height: self.options.height + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
}, 100);
|
||||||
|
that.$content.height(self.options.height - 48 - 2 * self.options.padding); // fixme: this should happen automatically
|
||||||
|
} else if (key == 'title') {
|
||||||
|
that.$title.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 100, function() {
|
||||||
|
that.$title.html(value).animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.center = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.close = function(callback) {
|
||||||
|
callback = callback || function() {};
|
||||||
|
that.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 200, function() {
|
||||||
|
that.$buttons.forEach(function($button) {
|
||||||
|
$button.removeElement();
|
||||||
|
});
|
||||||
|
that.loseFocus();
|
||||||
|
that.$layer.removeElement();
|
||||||
|
that.removeElement();
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
Ox.UI.$window.unbind('mouseup', mouseupLayer)
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.content = function($element) {
|
||||||
|
that.$content.empty().append($element);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.disable = function() {
|
||||||
|
// to be used on submit of form, like login
|
||||||
|
that.$layer.addClass('OxFront');
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.disableButton = function(id) {
|
||||||
|
getButtonById(id).options({
|
||||||
|
disabled: true
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.enable = function() {
|
||||||
|
that.$layer.removeClass('OxFront');
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.enableButton = function(id) {
|
||||||
|
getButtonById(id).options({
|
||||||
|
disabled: false
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.open = function() {
|
||||||
|
//Ox.print('before open')
|
||||||
|
that.$layer.appendTo(Ox.UI.$body);
|
||||||
|
that.css({
|
||||||
|
opacity: 0
|
||||||
|
}).appendTo(Ox.UI.$body).animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 200);
|
||||||
|
center();
|
||||||
|
reset();
|
||||||
|
// fixme: the following line prevents preview-style dialog
|
||||||
|
that.gainFocus();
|
||||||
|
Ox.UI.$window.bind('mouseup', mouseupLayer)
|
||||||
|
//Ox.print('after open')
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.size = function(width, height, callback) {
|
||||||
|
$.extend(self, {
|
||||||
|
initialWidth: width,
|
||||||
|
initialHeight: height
|
||||||
|
});
|
||||||
|
$.extend(self.options, {
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
});
|
||||||
|
// fixme: duplicated
|
||||||
|
that.animate({
|
||||||
|
height: self.options.height + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
}, 100, function() {
|
||||||
|
that.$content.height(self.options.height - 48 - 2 * self.options.padding); // fixme: this should happen automatically
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
324
source/js/Ox.Element.js
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
// check out http://ejohn.org/apps/learn/#36 (-#38, making fns work w/o new)
|
||||||
|
|
||||||
|
Ox.Element = function() {
|
||||||
|
|
||||||
|
/***
|
||||||
|
Basic element object
|
||||||
|
***/
|
||||||
|
|
||||||
|
/*
|
||||||
|
tooltip option can be any of the following:
|
||||||
|
string
|
||||||
|
function(e), returns string
|
||||||
|
{mousemove: true, title: function(e)}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return function(options, self) {
|
||||||
|
|
||||||
|
if (!(this instanceof arguments.callee)) {
|
||||||
|
return new arguments.callee(options, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
self = self || {};
|
||||||
|
self.options = options || {};
|
||||||
|
// allow for Ox.Element('tagname', self)
|
||||||
|
if (typeof self.options == 'string') {
|
||||||
|
self.options = {
|
||||||
|
element: self.options
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!self.$eventHandler) {
|
||||||
|
self.$eventHandler = $('<div>');
|
||||||
|
}
|
||||||
|
|
||||||
|
var that = new Ox.JQueryElement(
|
||||||
|
$('<' + (self.options.element || 'div') + '>')
|
||||||
|
)
|
||||||
|
.mousedown(mousedown);
|
||||||
|
|
||||||
|
/*
|
||||||
|
self.options.tooltip && that.bind(Ox.extend({
|
||||||
|
mouseenter: mouseenter,
|
||||||
|
mouseleave: mouseleave
|
||||||
|
}, self.options.tooltip.mousemove ? {
|
||||||
|
mousemove: mousemove
|
||||||
|
} : {}));
|
||||||
|
*/
|
||||||
|
|
||||||
|
function mousedown(e) {
|
||||||
|
/*
|
||||||
|
better mouse events
|
||||||
|
mousedown:
|
||||||
|
trigger mousedown
|
||||||
|
within 250 msec:
|
||||||
|
mouseup: trigger anyclick ("click" would collide with click events of certain widgets)
|
||||||
|
mouseup + mousedown: trigger doubleclick
|
||||||
|
after 250 msec:
|
||||||
|
mouseup + no mousedown within 250 msec: trigger singleclick
|
||||||
|
no mouseup within 250 msec:
|
||||||
|
trigger mouserepeat every 50 msec
|
||||||
|
trigger dragstart
|
||||||
|
mousemove: trigger drag
|
||||||
|
no mousemove within 250 msec:
|
||||||
|
trigger dragpause
|
||||||
|
mouseup: trigger dragend
|
||||||
|
*/
|
||||||
|
var clientX, clientY,
|
||||||
|
dragTimeout = 0,
|
||||||
|
mouseInterval = 0;
|
||||||
|
if (!self.mouseTimeout) {
|
||||||
|
// first mousedown
|
||||||
|
that.triggerEvent('mousedown', e);
|
||||||
|
self.mouseup = false;
|
||||||
|
self.mouseTimeout = setTimeout(function() {
|
||||||
|
self.mouseTimeout = 0;
|
||||||
|
if (self.mouseup) {
|
||||||
|
// singleclick
|
||||||
|
that.triggerEvent('singleclick', e);
|
||||||
|
} else {
|
||||||
|
// mouserepeat, drag
|
||||||
|
clientX = e.clientX;
|
||||||
|
clientY = e.clientY;
|
||||||
|
that.triggerEvent('dragstart', e);
|
||||||
|
mouserepeat();
|
||||||
|
mouseInterval = setInterval(mouserepeat, 50);
|
||||||
|
Ox.UI.$window.unbind('mouseup', mouseup)
|
||||||
|
.mousemove(mousemove)
|
||||||
|
.one('mouseup', function(e) {
|
||||||
|
clearInterval(mouseInterval);
|
||||||
|
clearTimeout(dragTimeout);
|
||||||
|
Ox.UI.$window.unbind('mousemove', mousemove);
|
||||||
|
that.triggerEvent('dragend', extend(e));
|
||||||
|
});
|
||||||
|
that.one('mouseleave', function() {
|
||||||
|
clearInterval(mouseInterval);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 250);
|
||||||
|
} else {
|
||||||
|
// second mousedown
|
||||||
|
clearTimeout(self.mouseTimeout);
|
||||||
|
self.mouseTimeout = 0;
|
||||||
|
that.triggerEvent('doubleclick', e);
|
||||||
|
}
|
||||||
|
Ox.UI.$window.one('mouseup', mouseup);
|
||||||
|
function extend(e) {
|
||||||
|
return Ox.extend({
|
||||||
|
clientDX: e.clientX - clientX,
|
||||||
|
clientDY: e.clientY - clientY
|
||||||
|
}, e);
|
||||||
|
}
|
||||||
|
function mousemove(e) {
|
||||||
|
e = extend(e);
|
||||||
|
clearTimeout(dragTimeout);
|
||||||
|
dragTimeout = setTimeout(function() {
|
||||||
|
that.triggerEvent('dragpause', e);
|
||||||
|
}, 250);
|
||||||
|
that.triggerEvent('drag', e);
|
||||||
|
}
|
||||||
|
function mouserepeat() {
|
||||||
|
that.triggerEvent('mouserepeat');
|
||||||
|
}
|
||||||
|
function mouseup(e) {
|
||||||
|
// only trigger on firse mouseup
|
||||||
|
if (!self.mouseup) {
|
||||||
|
that.triggerEvent('anyclick', e);
|
||||||
|
self.mouseup = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
function mouseenter(e) {
|
||||||
|
self.$tooltip = new Ox.Tooltip({
|
||||||
|
title: Ox.isString(self.options.tooltip) ?
|
||||||
|
self.options.tooltip : Ox.isFunction(self.options.tooltip) ?
|
||||||
|
self.options.tooltip(e) : self.options.tooltip.title(e)
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseleave(e) {
|
||||||
|
self.$tooltip.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousemove(e) {
|
||||||
|
self.$tooltip.options({
|
||||||
|
title: self.options.tooltip.title(e)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
self.onChange = function() {
|
||||||
|
// self.onChange(key, value)
|
||||||
|
// is called when an option changes
|
||||||
|
// (to be implemented by widget)
|
||||||
|
// fixme: rename to self.setOption
|
||||||
|
};
|
||||||
|
|
||||||
|
that._leakSelf = function() { // fixme: remove
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.bindEvent = function() {
|
||||||
|
/***
|
||||||
|
binds a function to an event triggered by this object
|
||||||
|
Usage
|
||||||
|
bindEvent(event, fn) or bindEvent({event0: fn0, event1: fn1, ...})
|
||||||
|
***/
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
Ox.forEach(arguments[0], function(fn, event) {
|
||||||
|
// Ox.print(that.id, 'bind', event);
|
||||||
|
self.$eventHandler.bind('ox_' + event, fn);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Ox.print(that.id, 'bind', arguments[0]);
|
||||||
|
self.$eventHandler.bind('ox_' + arguments[0], arguments[1]);
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.bindEventOnce = function() {
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
Ox.forEach(arguments[0], function(fn, event) {
|
||||||
|
self.$eventHandler.one('ox_' + event, fn);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.$eventHandler.one('ox_' + arguments[0], arguments[1]);
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.defaults = function(defaults) {
|
||||||
|
/***
|
||||||
|
sets the default options
|
||||||
|
Usage
|
||||||
|
that.defaults({key0: value0, key1: value1, ...})
|
||||||
|
***/
|
||||||
|
self.defaults = defaults;
|
||||||
|
delete self.options; // fixme: hackish fix for that = Ox.Foo({...}, self).defaults({...}).options({...})
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.gainFocus = function() {
|
||||||
|
/***
|
||||||
|
make this object gain focus
|
||||||
|
***/
|
||||||
|
Ox.Focus.focus(that.id);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.hasFocus = function() {
|
||||||
|
/***
|
||||||
|
returns true if this object has focus
|
||||||
|
***/
|
||||||
|
return Ox.Focus.focused() == that.id;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.loseFocus = function() {
|
||||||
|
/***
|
||||||
|
make this object lose focus
|
||||||
|
***/
|
||||||
|
Ox.Focus.blur(that.id);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.options = function() { // fixme: use Ox.getset
|
||||||
|
/***
|
||||||
|
get or set options
|
||||||
|
Usage
|
||||||
|
that.options() returns self.options
|
||||||
|
that.options('foo') returns self.options.foo
|
||||||
|
that.options('foo', x) sets self.options.foo,
|
||||||
|
returns that
|
||||||
|
that.options({foo: x, bar: y}) sets self.options.foo
|
||||||
|
and self.options.bar,
|
||||||
|
returns that
|
||||||
|
***/
|
||||||
|
var args,
|
||||||
|
length = arguments.length,
|
||||||
|
oldOptions,
|
||||||
|
ret;
|
||||||
|
if (length == 0) {
|
||||||
|
// options()
|
||||||
|
ret = self.options;
|
||||||
|
} else if (length == 1 && typeof arguments[0] == 'string') {
|
||||||
|
// options(str)
|
||||||
|
ret = self.options ? self.options[arguments[0]] : options[arguments[0]];
|
||||||
|
} else {
|
||||||
|
// options (str, val) or options({str: val, ...})
|
||||||
|
// translate (str, val) to ({str: val})
|
||||||
|
args = Ox.makeObject.apply(that, arguments || {});
|
||||||
|
oldOptions = $.extend({}, self.options);
|
||||||
|
// if options have not been set, extend defaults,
|
||||||
|
// otherwise, extend options
|
||||||
|
//self.options = $.extend(self.options, self.options ? {} : self.defaults, args);
|
||||||
|
self.options = $.extend({}, self.defaults, self.options, args);
|
||||||
|
//self.options = $.extend(self.options || self.defaults, args);
|
||||||
|
Ox.forEach(args, function(val, key) {
|
||||||
|
// key == 'id' && id && Ox.Event.changeId(id, value);
|
||||||
|
/*!Ox.equals(value, oldOptions[key]) &&*/ self.onChange(key, val);
|
||||||
|
});
|
||||||
|
ret = that;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.removeElement = function() {
|
||||||
|
/***
|
||||||
|
remove this element, including its event handler
|
||||||
|
***/
|
||||||
|
that.loseFocus();
|
||||||
|
delete self.$eventHandler;
|
||||||
|
that.remove();
|
||||||
|
delete Ox.UI.elements[that.id];
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.triggerEvent = function() {
|
||||||
|
/***
|
||||||
|
triggers an event
|
||||||
|
Usage
|
||||||
|
triggerEvent(event)
|
||||||
|
triggerEvent(event, data)
|
||||||
|
triggerEvent({event0: data0, event1: data1, ...})
|
||||||
|
***/
|
||||||
|
if (Ox.isObject(arguments[0])) {
|
||||||
|
Ox.forEach(arguments[0], function(data, event) {
|
||||||
|
if (['mousedown', 'mouserepeat', 'anyclick', 'singleclick', 'doubleclick', 'dragstart', 'drag', 'dragpause', 'dragend', 'playing'].indexOf(event) == -1) {
|
||||||
|
Ox.print(that.id, self.options.id, 'trigger', event, data);
|
||||||
|
}
|
||||||
|
self.$eventHandler.trigger('ox_' + event, data);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (['mousedown', 'mouserepeat', 'anyclick', 'singleclick', 'doubleclick', 'dragstart', 'drag', 'dragpause', 'dragend', 'playing'].indexOf(arguments[0]) == -1) {
|
||||||
|
Ox.print(that.id, self.options ? self.options.id : '', 'trigger', arguments[0], arguments[1] || {});
|
||||||
|
}
|
||||||
|
self.$eventHandler.trigger('ox_' + arguments[0], arguments[1] || {});
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.unbindEvent = function() {
|
||||||
|
/***
|
||||||
|
unbinds a function from an event triggered by this element
|
||||||
|
Usage
|
||||||
|
unbindEvent(event, fn)
|
||||||
|
unbindEvent({event0: fn0, event1: fn1, ...})
|
||||||
|
***/
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
Ox.forEach(arguments[0], function(fn, event) {
|
||||||
|
// Ox.print(that.id, 'unbind', arguments[0]);
|
||||||
|
self.$eventHandler.unbind('ox_' + event, fn);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Ox.print(that.id, 'unbind', arguments[0]);
|
||||||
|
self.$eventHandler.unbind('ox_' + arguments[0], arguments[1]);
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}();
|
182
source/js/Ox.FilesView.js
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
// fixme: this is not necessarily part of OxUI
|
||||||
|
|
||||||
|
/*
|
||||||
|
============================================================================
|
||||||
|
Pan.do/ra
|
||||||
|
============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
Ox.FilesView = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
id: ''
|
||||||
|
})
|
||||||
|
.options(options || {});
|
||||||
|
|
||||||
|
self.$toolbar = new Ox.Bar({
|
||||||
|
size: 24
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$orderButton = new Ox.Button({
|
||||||
|
title: 'Change Order of Users...'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$toolbar);
|
||||||
|
|
||||||
|
self.$moveButton = new Ox.Button({
|
||||||
|
disabled: 'true',
|
||||||
|
title: 'Move Selected Files...'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'right',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$toolbar);
|
||||||
|
|
||||||
|
self.$filesList = new Ox.TextList({
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
id: 'users',
|
||||||
|
operator: '+',
|
||||||
|
title: 'Users',
|
||||||
|
visible: true,
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
id: 'folder',
|
||||||
|
operator: '+',
|
||||||
|
title: 'Folder',
|
||||||
|
visible: true,
|
||||||
|
width: 180
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
id: 'name',
|
||||||
|
operator: '+',
|
||||||
|
title: 'Name',
|
||||||
|
visible: true,
|
||||||
|
width: 360
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
id: 'type',
|
||||||
|
operator: '+',
|
||||||
|
title: 'Type',
|
||||||
|
visible: true,
|
||||||
|
width: 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
id: 'part',
|
||||||
|
operator: '+',
|
||||||
|
title: 'Part',
|
||||||
|
visible: true,
|
||||||
|
width: 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
format: {type: 'value', args: ['B']},
|
||||||
|
id: 'size',
|
||||||
|
operator: '-',
|
||||||
|
title: 'Size',
|
||||||
|
visible: true,
|
||||||
|
width: 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
format: {type: 'resolution', args: ['px']},
|
||||||
|
id: 'resolution',
|
||||||
|
operator: '-',
|
||||||
|
title: 'Resolution',
|
||||||
|
visible: true,
|
||||||
|
width: 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
format: {type: 'duration', args: [0, 'short']},
|
||||||
|
id: 'duration',
|
||||||
|
operator: '-',
|
||||||
|
title: 'Duration',
|
||||||
|
visible: true,
|
||||||
|
width: 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
id: 'oshash',
|
||||||
|
operator: '+',
|
||||||
|
title: 'Hash',
|
||||||
|
unique: true,
|
||||||
|
visible: false,
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
id: 'instances',
|
||||||
|
operator: '+',
|
||||||
|
title: 'Instances',
|
||||||
|
visible: false,
|
||||||
|
width: 120
|
||||||
|
}
|
||||||
|
],
|
||||||
|
columnsMovable: true,
|
||||||
|
columnsRemovable: true,
|
||||||
|
columnsResizable: true,
|
||||||
|
columnsVisible: true,
|
||||||
|
id: 'files',
|
||||||
|
items: function(data, callback) {
|
||||||
|
pandora.api.findFiles($.extend(data, {
|
||||||
|
query: {
|
||||||
|
conditions: [{
|
||||||
|
key: 'id',
|
||||||
|
value: self.options.id,
|
||||||
|
operator: '='
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}), callback);
|
||||||
|
},
|
||||||
|
scrollbarVisible: true,
|
||||||
|
sort: [{key: 'name', operator:'+'}]
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
open: openFiles,
|
||||||
|
select: selectFiles
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$instancesList = new Ox.Element()
|
||||||
|
.html('No files selected');
|
||||||
|
|
||||||
|
that.$element = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: self.$toolbar,
|
||||||
|
size: 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: self.$filesList
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: self.$instancesList,
|
||||||
|
size: 80
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'vertical'
|
||||||
|
});
|
||||||
|
|
||||||
|
function openFiles(event, data) {
|
||||||
|
//alert(JSON.stringify(self.$filesList.value(data.ids[0], 'instances')))
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectFiles(event, data) {
|
||||||
|
//alert(JSON.stringify(self.$filesList.value(data.ids[0], 'instances')))
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
403
source/js/Ox.Filter.js
Normal file
|
@ -0,0 +1,403 @@
|
||||||
|
Ox.Filter = function(options, self) {
|
||||||
|
|
||||||
|
/***
|
||||||
|
Options:
|
||||||
|
Methods:
|
||||||
|
Events:
|
||||||
|
***/
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
findKeys: [],
|
||||||
|
query: {
|
||||||
|
conditions: [],
|
||||||
|
operator: '&'
|
||||||
|
},
|
||||||
|
sortKeys: [],
|
||||||
|
viewKeys: []
|
||||||
|
})
|
||||||
|
.options(options || {});
|
||||||
|
|
||||||
|
Ox.print('Ox.Filter self.options', self.options)
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
conditionOperators: {
|
||||||
|
date: [
|
||||||
|
{id: '', title: 'is'},
|
||||||
|
{id: '!', title: 'is not'},
|
||||||
|
{id: '<', title: 'is before'},
|
||||||
|
{id: '>', title: 'is after'},
|
||||||
|
{id: '>&<', title: 'is between'},
|
||||||
|
{id: '<|>', title: 'is not between'}
|
||||||
|
],
|
||||||
|
list: [
|
||||||
|
{id: '', title: 'is'},
|
||||||
|
{id: '!', title: 'is not'}
|
||||||
|
],
|
||||||
|
number: [
|
||||||
|
{id: '', title: 'is'},
|
||||||
|
{id: '!', title: 'is not'},
|
||||||
|
{id: '<', title: 'is less than'},
|
||||||
|
{id: '>', title: 'is greater than'},
|
||||||
|
{id: '>&<', title: 'is between'},
|
||||||
|
{id: '<|>', title: 'is not between'}
|
||||||
|
],
|
||||||
|
string: [
|
||||||
|
{id: '=', title: 'is'},
|
||||||
|
{id: '!=', title: 'is not'},
|
||||||
|
{id: '^', title: 'begins with'},
|
||||||
|
{id: '$', title: 'ends with'},
|
||||||
|
{id: '', title: 'contains'},
|
||||||
|
{id: '!', title: 'does not contain'}
|
||||||
|
],
|
||||||
|
text: [
|
||||||
|
{id: '', title: 'contains'},
|
||||||
|
{id: '!', title: 'does not contain'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
operators: [
|
||||||
|
{id: '&', title: 'all'},
|
||||||
|
{id: '|', title: 'any'}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!self.options.query.conditions.length) {
|
||||||
|
self.options.query.conditions = [{
|
||||||
|
key: self.options.findKeys[0].id,
|
||||||
|
value: '',
|
||||||
|
operator: self.conditionOperators[
|
||||||
|
getConditionType(self.options.findKeys[0].type)
|
||||||
|
][0].id
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.$operator = new Ox.FormElementGroup({
|
||||||
|
elements: [
|
||||||
|
new Ox.Label({
|
||||||
|
title: 'Match',
|
||||||
|
overlap: 'right',
|
||||||
|
width: 48
|
||||||
|
}),
|
||||||
|
new Ox.FormElementGroup({
|
||||||
|
elements: [
|
||||||
|
new Ox.Select({
|
||||||
|
items: self.operators,
|
||||||
|
width: 48
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: changeOperator
|
||||||
|
}),
|
||||||
|
new Ox.Label({
|
||||||
|
overlap: 'left',
|
||||||
|
title: 'of the following conditions',
|
||||||
|
width: 160
|
||||||
|
})
|
||||||
|
],
|
||||||
|
float: 'right',
|
||||||
|
width: 208
|
||||||
|
})
|
||||||
|
],
|
||||||
|
float: 'left',
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$buttons = [];
|
||||||
|
self.$conditions = $.map(self.options.query.conditions, function(condition, i) {
|
||||||
|
return constructCondition(condition, i);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$limit = new Ox.InputGroup({
|
||||||
|
inputs: [
|
||||||
|
new Ox.Checkbox({
|
||||||
|
width: 16
|
||||||
|
}),
|
||||||
|
new Ox.FormElementGroup({
|
||||||
|
elements: [
|
||||||
|
new Ox.Input({
|
||||||
|
width: 56
|
||||||
|
}),
|
||||||
|
new Ox.Select({
|
||||||
|
items: [
|
||||||
|
{id: 'items', title: 'items'},
|
||||||
|
{},
|
||||||
|
{id: 'hours', title: 'hours'},
|
||||||
|
{id: 'days', title: 'days'},
|
||||||
|
{},
|
||||||
|
{id: 'GB', title: 'GB'}
|
||||||
|
],
|
||||||
|
overlap: 'left',
|
||||||
|
width: 64
|
||||||
|
})
|
||||||
|
],
|
||||||
|
float: 'right',
|
||||||
|
width: 120
|
||||||
|
}),
|
||||||
|
new Ox.Select({
|
||||||
|
items: self.options.sortKeys,
|
||||||
|
width: 128
|
||||||
|
}),
|
||||||
|
new Ox.FormElementGroup({
|
||||||
|
elements: [
|
||||||
|
new Ox.Select({
|
||||||
|
items: [
|
||||||
|
{id: 'ascending', title: 'ascending'},
|
||||||
|
{id: 'descending', title: 'descending'}
|
||||||
|
],
|
||||||
|
width: 96
|
||||||
|
}),
|
||||||
|
new Ox.Label({
|
||||||
|
overlap: 'left',
|
||||||
|
title: 'order',
|
||||||
|
width: 72
|
||||||
|
})
|
||||||
|
],
|
||||||
|
float: 'right',
|
||||||
|
width: 168
|
||||||
|
})
|
||||||
|
],
|
||||||
|
separators: [
|
||||||
|
{title: 'Limit to', width: 56},
|
||||||
|
{title: 'sorted by', width: 64},
|
||||||
|
{title: 'in', width: 32}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$view = new Ox.InputGroup({
|
||||||
|
inputs: [
|
||||||
|
new Ox.Checkbox({
|
||||||
|
width: 16
|
||||||
|
}),
|
||||||
|
new Ox.Select({
|
||||||
|
items: self.options.viewKeys,
|
||||||
|
width: 128
|
||||||
|
})
|
||||||
|
],
|
||||||
|
separators: [
|
||||||
|
{title: 'By default, view', width: 112}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$save = new Ox.InputGroup({
|
||||||
|
inputs: [
|
||||||
|
new Ox.Checkbox({
|
||||||
|
width: 16
|
||||||
|
}),
|
||||||
|
new Ox.Input({
|
||||||
|
id: 'list',
|
||||||
|
width: 128
|
||||||
|
})
|
||||||
|
],
|
||||||
|
separators: [
|
||||||
|
{title: 'Save as Smart List', width: 112}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$items = $.merge($.merge([self.$operator], self.$conditions), [self.$limit, self.$view, self.$save]);
|
||||||
|
|
||||||
|
self.$form = new Ox.Form({
|
||||||
|
items: self.$items
|
||||||
|
});
|
||||||
|
that.$element = self.$form.$element;
|
||||||
|
|
||||||
|
function addCondition(pos) {
|
||||||
|
var key = self.options.findKeys[0];
|
||||||
|
self.options.query.conditions.splice(pos, 0, {
|
||||||
|
key: key.id,
|
||||||
|
value: '',
|
||||||
|
operator: self.conditionOperators[key.type][0].id
|
||||||
|
});
|
||||||
|
self.$conditions.splice(pos, 0, constructCondition({}, pos));
|
||||||
|
updateConditions();
|
||||||
|
self.$form.addItem(pos + 1, self.$conditions[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addGroup(pos) {
|
||||||
|
self.$form.addItem(pos + 1, constructGroup(pos))
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeConditionKey(pos, key) {
|
||||||
|
Ox.print('changeConditionKey', pos, key);
|
||||||
|
var oldOperator = self.options.query.conditions[pos].operator,
|
||||||
|
oldType = Ox.getObjectById(
|
||||||
|
self.options.findKeys, self.options.query.conditions[pos].key
|
||||||
|
).type,
|
||||||
|
newType = Ox.getObjectById(
|
||||||
|
self.options.findKeys, key
|
||||||
|
).type,
|
||||||
|
oldConditionType = getConditionType(oldType),
|
||||||
|
newConditionType = getConditionType(newType);
|
||||||
|
changeConditionType = oldConditionType != newConditionType;
|
||||||
|
Ox.print('old new', oldConditionType, newConditionType)
|
||||||
|
self.options.query.conditions[pos].key = key;
|
||||||
|
if (changeConditionType) {
|
||||||
|
self.$conditions[pos].replaceElement(1, constructConditionOperator(pos, oldOperator));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeConditionOperator(pos, operator) {
|
||||||
|
self.options.query.conditions[pos].operator = operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeOperator(event, data) {
|
||||||
|
self.options.query.operator = data.selected[0].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructCondition(condition, pos) {
|
||||||
|
var $condition;
|
||||||
|
return $condition = new Ox.FormElementGroup({
|
||||||
|
elements: [
|
||||||
|
new Ox.Select({
|
||||||
|
items: $.map(self.options.findKeys, function(key) {
|
||||||
|
return {
|
||||||
|
id: key.id,
|
||||||
|
title: key.title
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
//items: $.extend({}, self.options.findKeys), // fixme: Ox.Menu messes with keys
|
||||||
|
overlap: 'right',
|
||||||
|
width: 128
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
Ox.print('event', event)
|
||||||
|
changeConditionKey($condition.data('position'), data.selected[0].id);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
constructConditionOperator(pos),
|
||||||
|
new Ox.Input({
|
||||||
|
width: 256
|
||||||
|
}),
|
||||||
|
new Ox.Button({
|
||||||
|
disabled: self.options.query.conditions.length == 1,
|
||||||
|
id: 'remove',
|
||||||
|
title: 'remove',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.css({margin: '0 4px 0 8px'})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
removeCondition($condition.data('position'));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'add',
|
||||||
|
title: 'add',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.css({margin: '0 4px 0 4px'})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
Ox.print('add', $(this).parent().parent().data('position'))
|
||||||
|
addCondition($condition.data('position') + 1)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'addgroup',
|
||||||
|
title: 'more',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.css({margin: '0 0 0 4px'})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
addGroup($condition.data('position') + 1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.data({position: pos});
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructConditionOperator(pos, selected) {
|
||||||
|
return new Ox.Select({
|
||||||
|
items: $.map(self.conditionOperators[getConditionType(
|
||||||
|
Ox.getObjectById(
|
||||||
|
self.options.findKeys,
|
||||||
|
self.options.query.conditions[pos].key
|
||||||
|
).type
|
||||||
|
)], function(operator) {
|
||||||
|
return {
|
||||||
|
checked: operator.id == selected, // fixme: should be "selected", not "checked"
|
||||||
|
id: operator.operator,
|
||||||
|
title: operator.title
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
overlap: 'right',
|
||||||
|
width: 128
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
changeConditionOperator(/*$condition.data('position')*/ pos, data.selected[0].id)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructGroup() {
|
||||||
|
// fixme: duplicated
|
||||||
|
return new Ox.FormElementGroup({
|
||||||
|
elements: [
|
||||||
|
new Ox.Label({
|
||||||
|
title: self.options.operator == '&' ? 'and' : 'or',
|
||||||
|
overlap: 'right',
|
||||||
|
width: 48
|
||||||
|
}),
|
||||||
|
new Ox.FormElementGroup({
|
||||||
|
elements: [
|
||||||
|
new Ox.Select({
|
||||||
|
items: $.map(self.operators, function(operator) {
|
||||||
|
Ox.print('!!!!', {
|
||||||
|
checked: operator.id != self.options.operator,
|
||||||
|
id: operator.id,
|
||||||
|
title: operator.title
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
//checked: operator.id != self.options.operator,
|
||||||
|
id: operator.id,
|
||||||
|
title: operator.title
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
width: 48
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: changeOperator
|
||||||
|
}),
|
||||||
|
new Ox.Label({
|
||||||
|
overlap: 'left',
|
||||||
|
title: 'of the following conditions',
|
||||||
|
width: 160
|
||||||
|
})
|
||||||
|
],
|
||||||
|
float: 'right',
|
||||||
|
width: 208
|
||||||
|
})
|
||||||
|
],
|
||||||
|
float: 'left',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConditionType(type) {
|
||||||
|
type = Ox.isArray(type) ? type[0] : type;
|
||||||
|
if (['float', 'integer', 'year'].indexOf(type) > -1) {
|
||||||
|
type = 'number';
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeCondition(pos) {
|
||||||
|
self.options.query.conditions.splice(pos, 1);
|
||||||
|
self.$conditions.splice(pos, 1);
|
||||||
|
updateConditions();
|
||||||
|
self.$form.removeItem(pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateConditions() {
|
||||||
|
self.$conditions.forEach(function(condition, pos) {
|
||||||
|
condition.data({position: pos});
|
||||||
|
});
|
||||||
|
self.$conditions[0].options('elements')[3].options({
|
||||||
|
disabled: self.options.query.conditions.length == 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
98
source/js/Ox.Flipbook.js
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
// fixme: rename!
|
||||||
|
|
||||||
|
Ox.Flipbook = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
frame = $('<img>').css({
|
||||||
|
'position': 'absolute',
|
||||||
|
'width': '100%',
|
||||||
|
'height': 'auto'
|
||||||
|
})
|
||||||
|
.hide(),
|
||||||
|
icon = $('<img>').css({
|
||||||
|
'position': 'absolute',
|
||||||
|
'width': '100%',
|
||||||
|
'height': 'auto'
|
||||||
|
}),
|
||||||
|
frames = {},
|
||||||
|
timestamp = $('<div>').css({
|
||||||
|
'position': 'absolute',
|
||||||
|
'text-align': 'center',
|
||||||
|
'width': '100%',
|
||||||
|
})
|
||||||
|
.hide(),
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
frames: {},
|
||||||
|
duration: 0,
|
||||||
|
icon: '',
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.append(icon)
|
||||||
|
.append(frame)
|
||||||
|
.append(timestamp)
|
||||||
|
.mouseover(function() {
|
||||||
|
frame.show();
|
||||||
|
timestamp.show();
|
||||||
|
icon.hide();
|
||||||
|
})
|
||||||
|
.mousemove(function(event) {
|
||||||
|
var position = getPosition(event),
|
||||||
|
image = getFrame(position),
|
||||||
|
frameHeight = image?image.height:that.height();
|
||||||
|
frame.attr('src', image.src);
|
||||||
|
timestamp.html(Ox.formatDuration(position, 'short'));
|
||||||
|
|
||||||
|
var height = (that.height() - frameHeight)/2;
|
||||||
|
frame.css({'top': height + 'px'});
|
||||||
|
timestamp.css({'top': (frameHeight + height) + 'px'});
|
||||||
|
})
|
||||||
|
.mouseout(function() {
|
||||||
|
frame.hide();
|
||||||
|
timestamp.hide();
|
||||||
|
icon.show();
|
||||||
|
})
|
||||||
|
.mousedown(function(event) {
|
||||||
|
that.triggerEvent('click', {
|
||||||
|
'position': getPosition(event)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function getPosition(event) {
|
||||||
|
var position = Math.floor(event.clientX - that.offset().left);
|
||||||
|
position = (position / that.width()) * self.options.duration;
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFrame(position) {
|
||||||
|
var frame;
|
||||||
|
frames.forEach(function(img, i) {
|
||||||
|
if (!frame || i <= position)
|
||||||
|
frame = img;
|
||||||
|
});
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cacheFrames() {
|
||||||
|
Ox.forEach(self.options.frames, function(src, i) {
|
||||||
|
frames[i] = new Image();
|
||||||
|
frames[i].onload = function() {
|
||||||
|
frameHeight = frames[i].height / frames[i].width * that.width();
|
||||||
|
}
|
||||||
|
frames[i].src = src;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'frames') {
|
||||||
|
cacheFrames();
|
||||||
|
} else if (key == 'icon') {
|
||||||
|
icon.attr('src', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.icon)
|
||||||
|
icon.attr('src', options.icon);
|
||||||
|
cacheFrames();
|
||||||
|
return that;
|
||||||
|
};
|
40
source/js/Ox.Focus.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
Ox.Focus = function() {
|
||||||
|
/***
|
||||||
|
Ox.Focus
|
||||||
|
Basic focus handler
|
||||||
|
Methods
|
||||||
|
blur(id) blur element
|
||||||
|
focus(id) focus element
|
||||||
|
focused() return id of focused element, or null
|
||||||
|
***/
|
||||||
|
var stack = [];
|
||||||
|
return {
|
||||||
|
_print: function() {
|
||||||
|
Ox.print(stack);
|
||||||
|
},
|
||||||
|
blur: function(id) {
|
||||||
|
var index = stack.indexOf(id);
|
||||||
|
if (index > -1 && index == stack.length - 1) {
|
||||||
|
stack.length == 1 ? stack.pop() :
|
||||||
|
stack.splice(stack.length - 2, 0, stack.pop());
|
||||||
|
//$elements[id].removeClass('OxFocus');
|
||||||
|
$('.OxFocus').removeClass('OxFocus'); // fixme: the above is better, and should work
|
||||||
|
stack.length && Ox.UI.elements[stack[stack.length - 1]].addClass('OxFocus');
|
||||||
|
Ox.print('blur', id, stack);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
focus: function(id) {
|
||||||
|
var index = stack.indexOf(id);
|
||||||
|
if (index == -1 || index < stack.length - 1) {
|
||||||
|
index > -1 && stack.splice(index, 1);
|
||||||
|
stack.push(id);
|
||||||
|
$('.OxFocus').removeClass('OxFocus'); // fixme: see above
|
||||||
|
Ox.UI.elements[id].addClass('OxFocus');
|
||||||
|
Ox.print('focus', id, stack);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
focused: function() {
|
||||||
|
return stack.length ? stack[stack.length - 1] : null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}();
|
121
source/js/Ox.Form.js
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
Ox.Form = function(options, self) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
error: '',
|
||||||
|
id: '',
|
||||||
|
items: [],
|
||||||
|
submit: null
|
||||||
|
})
|
||||||
|
.options(options || {}) // fixme: the || {} can be done once, in the options function
|
||||||
|
.addClass('OxForm');
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
$items: [],
|
||||||
|
$messages: [],
|
||||||
|
formIsValid: false,
|
||||||
|
itemIds: [],
|
||||||
|
itemIsValid: []
|
||||||
|
});
|
||||||
|
|
||||||
|
// fixme: form isn't necessarily empty/invalid
|
||||||
|
self.options.items.forEach(function(item, i) {
|
||||||
|
self.itemIds[i] = item.options('id') || item.id;
|
||||||
|
self.itemIsValid[i] = !!item.value().length;
|
||||||
|
that.append(self.$items[i] = new Ox.FormItem({element: item}));
|
||||||
|
item.bindEvent({
|
||||||
|
/*
|
||||||
|
blur: function(event, data) {
|
||||||
|
validate(i, data.valid);
|
||||||
|
if (data.valid) {
|
||||||
|
self.$messages[i].html('').hide();
|
||||||
|
} else {
|
||||||
|
self.$messages[i].html(data.message).show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
autovalidate: function(event, data) {
|
||||||
|
data.valid = !!data.value.length;
|
||||||
|
validate(i, data.valid);
|
||||||
|
data.valid && self.$items[i].setMessage('');
|
||||||
|
},
|
||||||
|
submit: function(event, data) {
|
||||||
|
self.formIsValid && that.submit();
|
||||||
|
},
|
||||||
|
validate: function(event, data) {
|
||||||
|
validate(i, data.valid);
|
||||||
|
self.$items[i].setMessage(data.valid ? '' : data.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function getItemPositionById(id) {
|
||||||
|
return self.itemIds.indexOf(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitCallback(data) {
|
||||||
|
data.forEach(function(v, i) {
|
||||||
|
self.$items[i].setMessage(v.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function validate(pos, valid) {
|
||||||
|
//Ox.print('FORM validate', pos, valid)
|
||||||
|
self.itemIsValid[pos] = valid;
|
||||||
|
if (Ox.every(self.itemIsValid) != self.formIsValid) {
|
||||||
|
self.formIsValid = !self.formIsValid;
|
||||||
|
that.triggerEvent('validate', {
|
||||||
|
valid: self.formIsValid
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.addItem = function(pos, item) {
|
||||||
|
Ox.print('addItem', pos)
|
||||||
|
self.options.items.splice(pos, 0, item);
|
||||||
|
self.$items.splice(pos, 0, new Ox.FormItem({element: item}));
|
||||||
|
pos == 0 ?
|
||||||
|
self.$items[pos].insertBefore(self.$items[0]) :
|
||||||
|
self.$items[pos].insertAfter(self.$items[pos - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
that.removeItem = function(pos) {
|
||||||
|
Ox.print('removeItem', pos);
|
||||||
|
self.$items[pos].removeElement();
|
||||||
|
self.options.items.splice(pos, 1);
|
||||||
|
self.$items.splice(pos, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
that.submit = function() {
|
||||||
|
//Ox.print('---- that.values()', that.values())
|
||||||
|
self.options.submit(that.values(), submitCallback);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.values = function() { // fixme: can this be private?
|
||||||
|
/*
|
||||||
|
get/set form values
|
||||||
|
call without arguments to get current form values
|
||||||
|
pass values as array to set values (not implemented)
|
||||||
|
*/
|
||||||
|
var values = {};
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
self.$items.forEach(function($item, i) {
|
||||||
|
values[self.itemIds[i]] = self.$items[i].value();
|
||||||
|
});
|
||||||
|
//Ox.print('VALUES', values)
|
||||||
|
return values;
|
||||||
|
} else {
|
||||||
|
Ox.each(arguments[0], function(val, key) {
|
||||||
|
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
73
source/js/Ox.FormElementGroup.js
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
Ox.FormElementGroup = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
id: '',
|
||||||
|
elements: [],
|
||||||
|
float: 'left',
|
||||||
|
separators: [],
|
||||||
|
width: 0
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxInputGroup');
|
||||||
|
|
||||||
|
(
|
||||||
|
self.options.float == 'left' ?
|
||||||
|
self.options.elements : self.options.elements.reverse()
|
||||||
|
).forEach(function($element, i) {
|
||||||
|
$element.css({
|
||||||
|
float: self.options.float // fixme: make this a class
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
validate: function(event, data) {
|
||||||
|
that.triggerEvent({
|
||||||
|
validate: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (self.options.width) {
|
||||||
|
setWidths();
|
||||||
|
} else {
|
||||||
|
self.options.width = getWidth();
|
||||||
|
}
|
||||||
|
that.css({
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getWidth() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWidth() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.replaceElement = function(pos, element) {
|
||||||
|
Ox.print('Ox.FormElementGroup replaceElement', pos, element)
|
||||||
|
self.options.elements[pos].replaceWith(element.$element);
|
||||||
|
self.options.elements[pos] = element;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.value = function() {
|
||||||
|
return $.map(self.options.elements, function(element) {
|
||||||
|
var ret = null;
|
||||||
|
['checked', 'selected', 'value'].forEach(function(v) {
|
||||||
|
element[v] && (ret = element[v]());
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
27
source/js/Ox.FormItem.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Ox.FormItem = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
element: null,
|
||||||
|
error: '',
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxFormItem')
|
||||||
|
.append(self.options.element);
|
||||||
|
|
||||||
|
self.$message = new Ox.Element()
|
||||||
|
.addClass('OxFormMessage')
|
||||||
|
.appendTo(that);
|
||||||
|
|
||||||
|
that.setMessage = function(message) {
|
||||||
|
self.$message.html(message)[message !== '' ? 'show' : 'hide']();
|
||||||
|
}
|
||||||
|
|
||||||
|
that.value = function() {
|
||||||
|
return self.options.element.value();
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
}
|
4
source/js/Ox.History.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/***
|
||||||
|
Ox.History
|
||||||
|
***/
|
||||||
|
|
155
source/js/Ox.IconItem.js
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
Ox.IconItem = function(options, self) {
|
||||||
|
|
||||||
|
//Ox.print('IconItem', options, self)
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
height: 128,
|
||||||
|
id: '',
|
||||||
|
info: '',
|
||||||
|
size: 128,
|
||||||
|
title: '',
|
||||||
|
width: 128,
|
||||||
|
url: ''
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
fontSize: self.options.size == 64 ? 6 : 9,
|
||||||
|
height: self.options.size * 1.5,
|
||||||
|
lineLength: self.options.size == 64 ? 15 : 23,
|
||||||
|
lines: self.options.size == 64 ? 4 : 5,
|
||||||
|
url: Ox.UI.PATH + '/png/ox.ui/transparent.png',
|
||||||
|
width: self.options.size
|
||||||
|
});
|
||||||
|
self.title = formatText(self.options.title, self.lines - 1, self.lineLength);
|
||||||
|
self.info = formatText(self.options.info, 5 - self.title.split('<br/>').length, self.lineLength);
|
||||||
|
|
||||||
|
that.css({
|
||||||
|
width: self.width + 'px',
|
||||||
|
height: self.height + 'px'
|
||||||
|
});
|
||||||
|
that.$icon = $('<div>')
|
||||||
|
.addClass('OxIcon')
|
||||||
|
.css({
|
||||||
|
top: self.options.size == 64 ? -64 : -124,
|
||||||
|
width: (self.options.size + 4) + 'px',
|
||||||
|
height: (self.options.size + 4) + 'px'
|
||||||
|
});
|
||||||
|
that.$iconImage = $('<img>')
|
||||||
|
.addClass('OxLoading OxTarget')
|
||||||
|
.attr({
|
||||||
|
src: self.url
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: self.options.width + 'px',
|
||||||
|
height: self.options.height + 'px'
|
||||||
|
})
|
||||||
|
.mousedown(mousedown)
|
||||||
|
.mouseenter(mouseenter)
|
||||||
|
.mouseleave(mouseleave);
|
||||||
|
self.options.url && that.$iconImage.one('load', load);
|
||||||
|
that.$textBox = $('<div>')
|
||||||
|
.addClass('OxText')
|
||||||
|
.css({
|
||||||
|
top: (self.options.size / 2) + 'px',
|
||||||
|
width: (self.options.size + 4) + 'px',
|
||||||
|
height: (self.options.size == 64 ? 30 : 58) + 'px'
|
||||||
|
})
|
||||||
|
that.$text = $('<div>')
|
||||||
|
.addClass('OxTarget')
|
||||||
|
.css({
|
||||||
|
fontSize: self.fontSize + 'px'
|
||||||
|
})
|
||||||
|
.html(
|
||||||
|
self.title + '<br/><span class="OxInfo">' + self.info + '</span>'
|
||||||
|
)
|
||||||
|
.mouseenter(mouseenter)
|
||||||
|
.mouseleave(mouseleave);
|
||||||
|
that.$reflection = $('<div>')
|
||||||
|
.addClass('OxReflection')
|
||||||
|
.css({
|
||||||
|
top: self.options.size + 'px',
|
||||||
|
width: (self.options.size + 4) + 'px',
|
||||||
|
height: (self.options.size / 2) + 'px'
|
||||||
|
});
|
||||||
|
that.$reflectionImage = $('<img>')
|
||||||
|
.addClass('OxLoading')
|
||||||
|
.attr({
|
||||||
|
src: self.url
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: self.options.width + 'px',
|
||||||
|
height: self.options.height + 'px',
|
||||||
|
// firefox is 1px off when centering images with odd width and scaleY(-1)
|
||||||
|
paddingLeft: ($.browser.mozilla && self.options.width % 2 ? 1 : 0) + 'px'
|
||||||
|
});
|
||||||
|
that.$gradient = $('<div>')
|
||||||
|
.css({
|
||||||
|
//top: (-self.options.size / 2) + 'px',
|
||||||
|
width: self.options.width + 'px',
|
||||||
|
height: (self.options.size / 2) + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
that.append(
|
||||||
|
that.$reflection.append(
|
||||||
|
that.$reflectionImage
|
||||||
|
).append(
|
||||||
|
that.$gradient
|
||||||
|
)
|
||||||
|
).append(
|
||||||
|
that.$textBox.append(
|
||||||
|
that.$text
|
||||||
|
)
|
||||||
|
).append(
|
||||||
|
that.$icon.append(
|
||||||
|
that.$iconImage
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
function formatText(text, maxLines, maxLength) {
|
||||||
|
var lines = Ox.wordwrap(text, maxLength, '<br/>', true, false).split('<br/>');
|
||||||
|
return $.map(lines, function(line, i) {
|
||||||
|
if (i < maxLines - 1) {
|
||||||
|
return line;
|
||||||
|
} else if (i == maxLines - 1) {
|
||||||
|
return lines.length == maxLines ? line : Ox.truncate($.map(lines, function(line, i) {
|
||||||
|
return i < maxLines - 1 ? null : line;
|
||||||
|
}).join(' '), maxLength, '...', 'center');
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).join('<br/>');
|
||||||
|
}
|
||||||
|
|
||||||
|
function load() {
|
||||||
|
that.$iconImage.attr({
|
||||||
|
src: self.options.url
|
||||||
|
})
|
||||||
|
.one('load', function() {
|
||||||
|
that.$iconImage.removeClass('OxLoading');
|
||||||
|
that.$reflectionImage
|
||||||
|
.attr({
|
||||||
|
src: self.options.url
|
||||||
|
})
|
||||||
|
.removeClass('OxLoading');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousedown(e) {
|
||||||
|
// fixme: preventDefault keeps image from being draggable in safari - but also keeps the list from getting focus
|
||||||
|
// e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseenter() {
|
||||||
|
that.addClass('OxHover');
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseleave() {
|
||||||
|
that.removeClass('OxHover');
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
138
source/js/Ox.IconList.js
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
Ox.IconList = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
centerSelection: false,
|
||||||
|
draggable: true,
|
||||||
|
id: '',
|
||||||
|
item: null,
|
||||||
|
items: null,
|
||||||
|
keys: [],
|
||||||
|
max: -1,
|
||||||
|
min: 0,
|
||||||
|
orientation: 'both',
|
||||||
|
selected: [],
|
||||||
|
size: 128,
|
||||||
|
sort: [],
|
||||||
|
})
|
||||||
|
.options(options || {});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
itemHeight: self.options.size * 1.5,
|
||||||
|
itemWidth: self.options.size
|
||||||
|
});
|
||||||
|
|
||||||
|
that.$element = new Ox.List({
|
||||||
|
centered: self.options.centered,
|
||||||
|
construct: constructItem,
|
||||||
|
draggable: self.options.draggable,
|
||||||
|
id: self.options.id,
|
||||||
|
itemHeight: self.itemHeight,
|
||||||
|
items: self.options.items,
|
||||||
|
itemWidth: self.itemWidth,
|
||||||
|
keys: self.options.keys,
|
||||||
|
orientation: self.options.orientation,
|
||||||
|
keys: self.options.keys,
|
||||||
|
max: self.options.max,
|
||||||
|
min: self.options.min,
|
||||||
|
selected: self.options.selected,
|
||||||
|
size: self.options.size,
|
||||||
|
sort: self.options.sort,
|
||||||
|
type: 'icon',
|
||||||
|
unique: self.options.unique
|
||||||
|
}, $.extend({}, self)) // pass event handler
|
||||||
|
.addClass('OxIconList Ox' + Ox.toTitleCase(self.options.orientation))
|
||||||
|
.click(click)
|
||||||
|
.dblclick(dblclick)
|
||||||
|
.scroll(scroll);
|
||||||
|
|
||||||
|
updateKeys();
|
||||||
|
|
||||||
|
function click() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructItem(data) {
|
||||||
|
var data = !$.isEmptyObject(data) ?
|
||||||
|
self.options.item(data, self.options.sort, self.options.size) :
|
||||||
|
{height: 8, width: 5},
|
||||||
|
ratio = data.width / data.height;
|
||||||
|
return new Ox.IconItem($.extend(data, {
|
||||||
|
height: Math.round(self.options.size / (ratio <= 1 ? 1 : ratio)),
|
||||||
|
size: self.options.size,
|
||||||
|
width: Math.round(self.options.size * (ratio >= 1 ? 1 : ratio))
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function dblclick() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function scroll() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateKeys() {
|
||||||
|
self.options.keys = Ox.unique($.merge(self.options.keys, [self.options.sort[0].key]));
|
||||||
|
that.$element.options({
|
||||||
|
keys: self.options.keys
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'items') {
|
||||||
|
that.$element.options(key, value);
|
||||||
|
} else if (key == 'paste') {
|
||||||
|
that.$element.options(key, value);
|
||||||
|
} else if (key == 'selected') {
|
||||||
|
that.$element.options(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.closePreview = function() {
|
||||||
|
that.$element.closePreview();
|
||||||
|
};
|
||||||
|
|
||||||
|
that.paste = function(data) {
|
||||||
|
that.$element.paste(data);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.reloadList = function() {
|
||||||
|
that.$element.reloadList();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.scrollToSelection = function() {
|
||||||
|
that.$element.scrollToSelection();
|
||||||
|
};
|
||||||
|
|
||||||
|
that.size = function() {
|
||||||
|
that.$element.size();
|
||||||
|
};
|
||||||
|
|
||||||
|
that.sortList = function(key, operator) {
|
||||||
|
self.options.sort = [{
|
||||||
|
key: key,
|
||||||
|
operator: operator
|
||||||
|
}];
|
||||||
|
updateKeys();
|
||||||
|
that.$element.sortList(key, operator);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.value = function(id, key, value) {
|
||||||
|
// fixme: make this accept id, {k: v, ...}
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
return that.$element.value(id);
|
||||||
|
} else if (arguments.length == 2) {
|
||||||
|
return that.$element.value(id, key);
|
||||||
|
} else {
|
||||||
|
that.$element.value(id, key, value);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
1762
source/js/Ox.Input.js
Normal file
133
source/js/Ox.InputGroup.js
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
Ox.InputGroup = function(options, self) {
|
||||||
|
|
||||||
|
/***
|
||||||
|
Ox.InputGroup
|
||||||
|
Options:
|
||||||
|
Methods:
|
||||||
|
Events:
|
||||||
|
***/
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
id: '',
|
||||||
|
inputs: [],
|
||||||
|
separators: [],
|
||||||
|
width: 0
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxInputGroup')
|
||||||
|
.click(click);
|
||||||
|
|
||||||
|
if (self.options.width) {
|
||||||
|
setWidths();
|
||||||
|
} else {
|
||||||
|
self.options.width = getWidth();
|
||||||
|
}
|
||||||
|
that.css({
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
//$input: [],
|
||||||
|
$separator: []
|
||||||
|
});
|
||||||
|
|
||||||
|
self.options.separators.forEach(function(v, i) {
|
||||||
|
self.options.id == 'debug' && Ox.print('separator #' + i + ' ' + self.options.inputs[i].options('id') + ' ' + self.options.inputs[i].options('width'))
|
||||||
|
self.$separator[i] = new Ox.Label({
|
||||||
|
textAlign: 'center',
|
||||||
|
title: v.title,
|
||||||
|
width: v.width + 32
|
||||||
|
})
|
||||||
|
.addClass('OxSeparator')
|
||||||
|
.css({
|
||||||
|
marginLeft: (self.options.inputs[i].options('width') - (i == 0 ? 16 : 32)) + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.options.inputs.forEach(function($input, i) {
|
||||||
|
$input.options({
|
||||||
|
id: self.options.id + Ox.toTitleCase($input.options('id')),
|
||||||
|
parent: that
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
marginLeft: -Ox.sum($.map(self.options.inputs, function(v_, i_) {
|
||||||
|
return i_ > i ? self.options.inputs[i_ - 1].options('width') +
|
||||||
|
self.options.separators[i_ - 1].width : (i_ == i ? 16 : 0);
|
||||||
|
})) + 'px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: change,
|
||||||
|
submit: change,
|
||||||
|
validate: validate
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
});
|
||||||
|
|
||||||
|
function change(event, data) {
|
||||||
|
//Ox.print('InputGroup change')
|
||||||
|
// fixme: would be good to pass a value here
|
||||||
|
that.triggerEvent('change');
|
||||||
|
}
|
||||||
|
|
||||||
|
function click(event) {
|
||||||
|
if ($(event.target).hasClass('OxSeparator')) {
|
||||||
|
self.options.inputs[0].focusInput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWidth() {
|
||||||
|
return Ox.sum($.map(self.options.inputs, function(v, i) {
|
||||||
|
return v.options('width');
|
||||||
|
})) + Ox.sum($.map(self.options.separators, function(v, i) {
|
||||||
|
return v.width;
|
||||||
|
})) + 2; // fixme: why + 2?
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWidths() {
|
||||||
|
var length = self.options.inputs.length,
|
||||||
|
inputWidths = Ox.divideInt(
|
||||||
|
self.options.width - Ox.sum($.map(self.options.separators, function(v, i) {
|
||||||
|
return v.width;
|
||||||
|
})), length
|
||||||
|
);
|
||||||
|
self.options.inputs.forEach(function(v) {
|
||||||
|
v.options({
|
||||||
|
width: inputWidths[1]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function validate(event, data) {
|
||||||
|
//Ox.print('INPUTGROUP TRIGGER VALIDATE')
|
||||||
|
that.triggerEvent('validate', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixme: is this used?
|
||||||
|
that.getInputById = function(id) {
|
||||||
|
var input = null;
|
||||||
|
Ox.forEach(self.options.inputs, function(v, i) {
|
||||||
|
//Ox.print(v, v.options('id'), id)
|
||||||
|
if (v.options('id') == self.options.id + Ox.toTitleCase(id)) {
|
||||||
|
input = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return input;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.value = function() {
|
||||||
|
return $.map(self.options.inputs, function(input) {
|
||||||
|
var ret = null;
|
||||||
|
['checked', 'selected', 'value'].forEach(function(v) {
|
||||||
|
input[v] && (ret = input[v]());
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
54
source/js/Ox.ItemInput.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
Ox.ItemInput = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
type: 'textarea',
|
||||||
|
value: '',
|
||||||
|
height: 300,
|
||||||
|
width: 100
|
||||||
|
})
|
||||||
|
.options(options || {}),
|
||||||
|
$input;
|
||||||
|
|
||||||
|
that.append(
|
||||||
|
$input = new Ox.Input({
|
||||||
|
height: self.options.height,
|
||||||
|
style: 'square',
|
||||||
|
type: self.options.type,
|
||||||
|
value: self.options.value,
|
||||||
|
width: self.options.width + 6
|
||||||
|
})
|
||||||
|
.bind({
|
||||||
|
mousedown: function(e) {
|
||||||
|
// keep mousedown from reaching list
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(new Ox.Element()
|
||||||
|
.append(new Ox.Button({type: 'text', title: 'Cancel'})
|
||||||
|
.css('width', '42%')
|
||||||
|
.bindEvent({
|
||||||
|
'click': function() {
|
||||||
|
that.triggerEvent('cancel');
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.append(new Ox.Button({type: 'text', title: 'Save'})
|
||||||
|
.css('width', '42%')
|
||||||
|
.bindEvent({
|
||||||
|
'click': function() {
|
||||||
|
that.triggerEvent('save', {
|
||||||
|
value: $input.value()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.css({
|
||||||
|
'margin-top': self.options.height-8,
|
||||||
|
'height': '16px',
|
||||||
|
'text-align': 'right',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
Ox.print($input);
|
||||||
|
return that;
|
||||||
|
}
|
32
source/js/Ox.JQueryElement.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Basic jQuery element
|
||||||
|
Ox.JQueryElement = function($element) {
|
||||||
|
var that = this;
|
||||||
|
that.id = Ox.uid();
|
||||||
|
that.ox = Ox.VERSION;
|
||||||
|
that.$element = $element.data({
|
||||||
|
oxid: that.id
|
||||||
|
});
|
||||||
|
Ox.UI.elements[that.id] = that;
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
Ox.forEach($('<div>'), function(val, key) {
|
||||||
|
if (Ox.isFunction(val)) {
|
||||||
|
Ox.JQueryElement.prototype[key] = function() {
|
||||||
|
var args = arguments, id, ret, that = this;
|
||||||
|
Ox.forEach(args, function(arg, i) {
|
||||||
|
// if an ox object was passed
|
||||||
|
// then pass its $element instead
|
||||||
|
// so that we can do oxObj.jqFn(oxObj)
|
||||||
|
if (arg && arg.ox) {
|
||||||
|
args[i] = arg.$element;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ret = that.$element[key].apply(that.$element, args);
|
||||||
|
// if the $element of an ox object was returned
|
||||||
|
// then return the ox object instead
|
||||||
|
// so that we can do oxObj.jqFn().oxFn()
|
||||||
|
return ret.jquery && Ox.UI.elements[id = ret.data('oxid')] ?
|
||||||
|
Ox.UI.elements[id] : ret;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
196
source/js/Ox.Keyboard.js
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
/***
|
||||||
|
Ox.Keyboard
|
||||||
|
***/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
var buffer = '',
|
||||||
|
bufferTime = 0,
|
||||||
|
bufferTimeout = 1000,
|
||||||
|
// wrapped in function so it can be collapsed in text editor
|
||||||
|
keyNames = (function() {
|
||||||
|
return {
|
||||||
|
0: 'section',
|
||||||
|
8: 'backspace',
|
||||||
|
9: 'tab',
|
||||||
|
12: 'clear',
|
||||||
|
13: 'enter',
|
||||||
|
16: 'shift',
|
||||||
|
17: 'control',
|
||||||
|
18: 'alt',
|
||||||
|
20: 'capslock',
|
||||||
|
27: 'escape',
|
||||||
|
32: 'space',
|
||||||
|
33: 'pageup',
|
||||||
|
34: 'pagedown',
|
||||||
|
35: 'end',
|
||||||
|
36: 'home',
|
||||||
|
37: 'left',
|
||||||
|
38: 'up',
|
||||||
|
39: 'right',
|
||||||
|
40: 'down',
|
||||||
|
45: 'insert',
|
||||||
|
46: 'delete',
|
||||||
|
47: 'help',
|
||||||
|
48: '0',
|
||||||
|
49: '1',
|
||||||
|
50: '2',
|
||||||
|
51: '3',
|
||||||
|
52: '4',
|
||||||
|
53: '5',
|
||||||
|
54: '6',
|
||||||
|
55: '7',
|
||||||
|
56: '8',
|
||||||
|
57: '9',
|
||||||
|
65: 'a',
|
||||||
|
66: 'b',
|
||||||
|
67: 'c',
|
||||||
|
68: 'd',
|
||||||
|
69: 'e',
|
||||||
|
70: 'f',
|
||||||
|
71: 'g',
|
||||||
|
72: 'h',
|
||||||
|
73: 'i',
|
||||||
|
74: 'j',
|
||||||
|
75: 'k',
|
||||||
|
76: 'l',
|
||||||
|
77: 'm',
|
||||||
|
78: 'n',
|
||||||
|
79: 'o',
|
||||||
|
80: 'p',
|
||||||
|
81: 'q',
|
||||||
|
82: 'r',
|
||||||
|
83: 's',
|
||||||
|
84: 't',
|
||||||
|
85: 'u',
|
||||||
|
86: 'v',
|
||||||
|
87: 'w',
|
||||||
|
88: 'x',
|
||||||
|
89: 'y',
|
||||||
|
90: 'z',
|
||||||
|
//91: 'meta.left',
|
||||||
|
//92: 'meta.right',
|
||||||
|
91: 'meta',
|
||||||
|
//92: 'meta',
|
||||||
|
93: 'meta',
|
||||||
|
96: '0.numpad',
|
||||||
|
97: '1.numpad',
|
||||||
|
98: '2.numpad',
|
||||||
|
99: '3.numpad',
|
||||||
|
100: '4.numpad',
|
||||||
|
101: '5.numpad',
|
||||||
|
102: '6.numpad',
|
||||||
|
103: '7.numpad',
|
||||||
|
104: '8.numpad',
|
||||||
|
105: '9.numpad',
|
||||||
|
106: 'asterisk.numpad',
|
||||||
|
107: 'plus.numpad',
|
||||||
|
109: 'minus.numpad',
|
||||||
|
108: 'enter.numpad',
|
||||||
|
110: 'dot.numpad',
|
||||||
|
111: 'slash.numpad',
|
||||||
|
112: 'f1',
|
||||||
|
113: 'f2',
|
||||||
|
114: 'f3',
|
||||||
|
115: 'f4',
|
||||||
|
116: 'f5',
|
||||||
|
117: 'f6',
|
||||||
|
118: 'f7',
|
||||||
|
119: 'f8',
|
||||||
|
120: 'f9',
|
||||||
|
121: 'f10',
|
||||||
|
122: 'f11',
|
||||||
|
123: 'f12',
|
||||||
|
124: 'f13',
|
||||||
|
125: 'f14',
|
||||||
|
126: 'f15',
|
||||||
|
127: 'f16',
|
||||||
|
144: 'numlock',
|
||||||
|
145: 'scrolllock',
|
||||||
|
186: 'semicolon',
|
||||||
|
187: 'equal',
|
||||||
|
188: 'comma',
|
||||||
|
189: 'minus',
|
||||||
|
190: 'dot',
|
||||||
|
191: 'slash',
|
||||||
|
192: 'backtick',
|
||||||
|
219: 'openbracket',
|
||||||
|
220: 'backslash',
|
||||||
|
221: 'closebracket',
|
||||||
|
222: 'quote'
|
||||||
|
// see dojo, for ex.
|
||||||
|
};
|
||||||
|
})(),
|
||||||
|
modifierNames = {
|
||||||
|
altKey: 'alt', // mac: option
|
||||||
|
ctrlKey: 'control',
|
||||||
|
// metaKey: 'meta', // mac: command
|
||||||
|
shiftKey: 'shift'
|
||||||
|
};
|
||||||
|
|
||||||
|
Ox.UI.ready(function() {
|
||||||
|
// fixme: how to do this better?
|
||||||
|
// in firefox on mac, keypress doesn't fire for up/down
|
||||||
|
// if the cursor is at the start/end of an input element
|
||||||
|
// on linux, it doesn't seem to fire if the input element has focus
|
||||||
|
if ($.browser.mozilla) {
|
||||||
|
Ox.UI.$document.keypress(keypress);
|
||||||
|
Ox.UI.$document.keydown(function(event) {
|
||||||
|
var $element = $('input:focus');
|
||||||
|
if ($element.length) {
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
keyNames[event.keyCode] == 'up' &&
|
||||||
|
$element[0].selectionStart + $element[0].selectionEnd == 0
|
||||||
|
) || (
|
||||||
|
keyNames[event.keyCode] == 'down' &&
|
||||||
|
$element[0].selectionStart == $element.val().length &&
|
||||||
|
$element[0].selectionEnd == $element.val().length
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
keypress(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Ox.UI.$document.keydown(keypress);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function keypress(event) {
|
||||||
|
var focused = Ox.Focus.focused(),
|
||||||
|
key,
|
||||||
|
keys = [],
|
||||||
|
//ret = true,
|
||||||
|
time;
|
||||||
|
Ox.forEach(modifierNames, function(v, k) {
|
||||||
|
event[k] && keys.push(v);
|
||||||
|
});
|
||||||
|
// avoid pushing modifier twice
|
||||||
|
if (keyNames[event.keyCode] && keys.indexOf(keyNames[event.keyCode]) == -1) {
|
||||||
|
keys.push(keyNames[event.keyCode]);
|
||||||
|
}
|
||||||
|
key = keys.join('_');
|
||||||
|
if (key.match(/^[\w\d\-]$|SPACE/)) {
|
||||||
|
time = Ox.getTime();
|
||||||
|
if (time - bufferTime > bufferTimeout) {
|
||||||
|
buffer = '';
|
||||||
|
}
|
||||||
|
buffer += key == 'SPACE' ? ' ' : key;
|
||||||
|
bufferTime = time;
|
||||||
|
}
|
||||||
|
focused !== null && Ox.UI.elements[focused].triggerEvent('key_' + key);
|
||||||
|
if (['down', 'space', 'up'].indexOf(key) > -1 && !Ox.UI.elements[focused].hasClass('OxInput')) {
|
||||||
|
// prevent chrome from scrolling
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
stack.forEach(function(v) {
|
||||||
|
// fixme: we dont get the return value!
|
||||||
|
ret = Ox.event.trigger(keyboard + Ox.toCamelCase(key) + '.' + v);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
34
source/js/Ox.Label.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
Ox.Label = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
disabled: false,
|
||||||
|
id: '',
|
||||||
|
overlap: 'none',
|
||||||
|
textAlign: 'left',
|
||||||
|
title: '',
|
||||||
|
width: 'auto'
|
||||||
|
})
|
||||||
|
.options(options)
|
||||||
|
.addClass(
|
||||||
|
'OxLabel' + (self.options.disabled ? ' OxDisabled' : '') +
|
||||||
|
(self.options.overlap != 'none' ?
|
||||||
|
' OxOverlap' + Ox.toTitleCase(self.options.overlap) : '')
|
||||||
|
)
|
||||||
|
.css($.extend(self.options.width == 'auto' ? {} : {
|
||||||
|
width: (self.options.width - 14) + 'px'
|
||||||
|
}, {
|
||||||
|
textAlign: self.options.textAlign
|
||||||
|
}))
|
||||||
|
.html(self.options.title);
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'title') {
|
||||||
|
that.html(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
212
source/js/Ox.LargeTimeline.js
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
Ox.LargeTimeline = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
cuts: [],
|
||||||
|
duration: 0,
|
||||||
|
find: '',
|
||||||
|
matches: [],
|
||||||
|
points: [0, 0],
|
||||||
|
position: 0,
|
||||||
|
style: 'default',
|
||||||
|
subtitles: [],
|
||||||
|
videoId: '',
|
||||||
|
width: 0
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxTimelineLarge')
|
||||||
|
.mouseleave(mouseleave)
|
||||||
|
.mousemove(mousemove)
|
||||||
|
.bindEvent({
|
||||||
|
anyclick: click,
|
||||||
|
dragstart: dragstart,
|
||||||
|
drag: drag
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
$cuts: [],
|
||||||
|
$markerPoint: [],
|
||||||
|
$subtitles: [],
|
||||||
|
$tiles: {},
|
||||||
|
$tooltip: new Ox.Tooltip({
|
||||||
|
animate: false
|
||||||
|
}),
|
||||||
|
center: parseInt(self.options.width / 2),
|
||||||
|
element: that.$element[0],
|
||||||
|
fps: 25,
|
||||||
|
height: 64,
|
||||||
|
tileWidth: 1500
|
||||||
|
});
|
||||||
|
self.tiles = self.options.duration * self.fps / self.tileWidth;
|
||||||
|
|
||||||
|
self.$timeline = $('<div>')
|
||||||
|
.css({
|
||||||
|
left: self.center + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(that.$element)
|
||||||
|
|
||||||
|
self.options.subtitles.forEach(function(v, i) {
|
||||||
|
self.$subtitles[i] = $('<div>')
|
||||||
|
.addClass('OxSubtitle' + (self.options.matches.indexOf(i) > -1 ? ' OxHighlight' : ''))
|
||||||
|
.css({
|
||||||
|
left: (v['in'] * self.fps) + 'px',
|
||||||
|
width: (((v['out'] - v['in']) * self.fps) - 2) + 'px'
|
||||||
|
})
|
||||||
|
.html(Ox.highlight(v.value, self.options.find))
|
||||||
|
.appendTo(self.$timeline)
|
||||||
|
});
|
||||||
|
|
||||||
|
self.options.cuts.forEach(function(v, i) {
|
||||||
|
self.$cuts[i] = $('<img>')
|
||||||
|
.addClass('OxCut')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/ox.ui/videoMarkerCut.png'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: (v * self.fps) + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$timeline)
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$markerPosition = $('<img>')
|
||||||
|
.addClass('OxMarkerPosition')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/ox.ui/videoMarkerPlay.png'
|
||||||
|
})
|
||||||
|
.appendTo(that.$element);
|
||||||
|
setMarker();
|
||||||
|
|
||||||
|
['In', 'Out'].forEach(function(v, i) {
|
||||||
|
self.$markerPoint[i] = $('<img>')
|
||||||
|
.addClass('OxMarkerPoint' + v)
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/ox.ui/videoMarker' + v + '.png'
|
||||||
|
})
|
||||||
|
.appendTo(self.$timeline);
|
||||||
|
setMarkerPoint(i);
|
||||||
|
});
|
||||||
|
|
||||||
|
setWidth();
|
||||||
|
setPosition();
|
||||||
|
|
||||||
|
function click(event, e) {
|
||||||
|
self.options.position = Ox.limit(
|
||||||
|
getPosition(e), 0, self.options.duration
|
||||||
|
);
|
||||||
|
setPosition();
|
||||||
|
triggerChangeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragstart(event, e) {
|
||||||
|
self.drag = {x: e.clientX};
|
||||||
|
}
|
||||||
|
|
||||||
|
function drag(event, e) {
|
||||||
|
self.options.position = Ox.limit(
|
||||||
|
self.options.position + (self.drag.x - e.clientX) / self.fps,
|
||||||
|
0, self.options.duration
|
||||||
|
);
|
||||||
|
self.drag.x = e.clientX;
|
||||||
|
setPosition();
|
||||||
|
triggerChangeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPosition(e) {
|
||||||
|
return self.options.position + (e.clientX - that.offset().left - self.center - 1) / self.fps
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseleave(e) {
|
||||||
|
self.clientX = 0;
|
||||||
|
self.clientY = 0;
|
||||||
|
self.$tooltip.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousemove(e) {
|
||||||
|
self.clientX = e.clientX;
|
||||||
|
self.clientY = e.clientY;
|
||||||
|
updateTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMarkerPoint(i) {
|
||||||
|
self.$markerPoint[i].css({
|
||||||
|
left: (self.options.points[i] * self.fps) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMarker() {
|
||||||
|
self.$markerPosition.css({
|
||||||
|
left: (self.center - 4) + 'px',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPosition() {
|
||||||
|
self.tile = parseInt(self.options.position * self.fps / self.tileWidth);
|
||||||
|
self.$timeline.css({
|
||||||
|
marginLeft: (-self.options.position * self.fps) + 'px'
|
||||||
|
});
|
||||||
|
Ox.range(
|
||||||
|
Math.max(self.tile - 1, 0), Math.min(self.tile + 2, self.tiles)
|
||||||
|
).forEach(function(v) {
|
||||||
|
if (!self.$tiles[v]) {
|
||||||
|
self.$tiles[v] = $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: '/' + self.options.videoId + '/timelines/' + (
|
||||||
|
self.options.style == 'default' ? 'timeline' : self.options.style
|
||||||
|
) + '.64.' + v + '.png'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: (v * self.tileWidth) + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$timeline);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (self.clientX && self.clientY) {
|
||||||
|
updateTooltip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWidth() {
|
||||||
|
self.center = parseInt(self.options.width / 2);
|
||||||
|
that.css({
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
self.$timeline.css({
|
||||||
|
left: self.center + 'px'
|
||||||
|
});
|
||||||
|
setMarker();
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerChangeEvent() {
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTooltip() {
|
||||||
|
var position = getPosition(self);
|
||||||
|
if (position >= 0 && position <= self.options.duration) {
|
||||||
|
self.$tooltip
|
||||||
|
.options({
|
||||||
|
title: Ox.formatDuration(position, 3)
|
||||||
|
})
|
||||||
|
.show(self.clientX, self.clientY);
|
||||||
|
} else {
|
||||||
|
self.$tooltip.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'points') {
|
||||||
|
setMarkerPoint(0);
|
||||||
|
setMarkerPoint(1);
|
||||||
|
} else if (key == 'position') {
|
||||||
|
setPosition();
|
||||||
|
} else if (key == 'width') {
|
||||||
|
setWidth();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
1422
source/js/Ox.List.js
Normal file
41
source/js/Ox.ListItem.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
Ox.ListItem = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
construct: function() {},
|
||||||
|
data: {},
|
||||||
|
draggable: false,
|
||||||
|
position: 0,
|
||||||
|
unique: ''
|
||||||
|
})
|
||||||
|
.options(options || {});
|
||||||
|
|
||||||
|
constructItem();
|
||||||
|
|
||||||
|
function constructItem(update) {
|
||||||
|
var $element = self.options.construct(self.options.data)
|
||||||
|
.addClass('OxItem')
|
||||||
|
.attr({
|
||||||
|
draggable: self.options.draggable
|
||||||
|
})
|
||||||
|
.data({
|
||||||
|
id: self.options.data[self.options.unique],
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
if (update) {
|
||||||
|
that.$element.hasClass('OxSelected') && $element.addClass('OxSelected');
|
||||||
|
that.$element.replaceWith($element);
|
||||||
|
}
|
||||||
|
that.$element = $element;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'data') {
|
||||||
|
constructItem(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
357
source/js/Ox.ListMap.js
Normal file
|
@ -0,0 +1,357 @@
|
||||||
|
Ox.ListMap = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
addPlace: null,
|
||||||
|
height: 256,
|
||||||
|
labels: false,
|
||||||
|
places: null,
|
||||||
|
selected: [],
|
||||||
|
width: 256
|
||||||
|
})
|
||||||
|
.addClass('OxListMap')
|
||||||
|
.options(options || {})
|
||||||
|
.css({
|
||||||
|
width: self.options.width + 'px',
|
||||||
|
height: self.options.height + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
self.columns = [
|
||||||
|
{
|
||||||
|
addable: false, // fixme: implement
|
||||||
|
id: 'id',
|
||||||
|
unique: true,
|
||||||
|
visible: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
editable: true,
|
||||||
|
id: 'name',
|
||||||
|
operator: '+',
|
||||||
|
removable: false,
|
||||||
|
title: 'Name',
|
||||||
|
visible: true,
|
||||||
|
width: 144
|
||||||
|
},
|
||||||
|
{
|
||||||
|
editable: true,
|
||||||
|
id: 'geoname',
|
||||||
|
removable: false,
|
||||||
|
operator: '+',
|
||||||
|
title: 'Geoname',
|
||||||
|
visible: true,
|
||||||
|
width: 192
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: function(value) {
|
||||||
|
return $('<img>')
|
||||||
|
.attr({
|
||||||
|
// fixme: not the right place to do these
|
||||||
|
src: Ox.UI.PATH + 'svg/ox.map/' + (value || 'NTHH') + '.' + (value == 'RE' ? 'png' : 'svg')
|
||||||
|
})
|
||||||
|
.load(function() {
|
||||||
|
$(this).css({
|
||||||
|
width: '21px',
|
||||||
|
height: '14px',
|
||||||
|
padding: '1px 0 0 1px'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
id: 'countryCode',
|
||||||
|
operator: '+',
|
||||||
|
title: 'Flag',
|
||||||
|
visible: true,
|
||||||
|
width: 48
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
format: {type: 'area', args: [0]},
|
||||||
|
id: 'size',
|
||||||
|
operator: '-',
|
||||||
|
title: 'Size',
|
||||||
|
visible: true,
|
||||||
|
width: 128
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
format: toFixed,
|
||||||
|
id: 'lat',
|
||||||
|
operator: '+',
|
||||||
|
title: 'Latitude',
|
||||||
|
visible: true,
|
||||||
|
width: 96
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
format: toFixed,
|
||||||
|
id: 'lng',
|
||||||
|
operator: '+',
|
||||||
|
title: 'Longitude',
|
||||||
|
visible: true,
|
||||||
|
width: 96
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
format: toFixed,
|
||||||
|
id: 'south',
|
||||||
|
operator: '+',
|
||||||
|
title: 'South',
|
||||||
|
visible: false,
|
||||||
|
width: 96
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
id: 'west',
|
||||||
|
operator: '+',
|
||||||
|
title: 'West',
|
||||||
|
visible: false,
|
||||||
|
width: 96
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
format: toFixed,
|
||||||
|
id: 'north',
|
||||||
|
operator: '+',
|
||||||
|
title: 'North',
|
||||||
|
visible: false,
|
||||||
|
width: 96
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
format: toFixed,
|
||||||
|
id: 'east',
|
||||||
|
operator: '+',
|
||||||
|
title: 'East',
|
||||||
|
visible: false,
|
||||||
|
width: 96
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
operator: '+',
|
||||||
|
title: 'User',
|
||||||
|
visible: false,
|
||||||
|
width: 96
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: 'date',
|
||||||
|
id: 'created',
|
||||||
|
operator: '-',
|
||||||
|
title: 'Date Created',
|
||||||
|
visible: false,
|
||||||
|
width: 96,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: 'date',
|
||||||
|
id: 'modified',
|
||||||
|
operator: '-',
|
||||||
|
title: 'Date Modified',
|
||||||
|
visible: false,
|
||||||
|
width: 96,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
id: 'matches',
|
||||||
|
operator: '-',
|
||||||
|
title: 'Matches',
|
||||||
|
visible: false,
|
||||||
|
width: 96,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
self.$toolbar = new Ox.Bar({
|
||||||
|
size: 24
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$findElement = new Ox.FormElementGroup({
|
||||||
|
elements: [
|
||||||
|
self.$findSelect = new Ox.Select({
|
||||||
|
items: [
|
||||||
|
{id: 'all', title: 'Find: All'},
|
||||||
|
{id: 'name', title: 'Find: Name'},
|
||||||
|
{id: 'geoname', title: 'Find: Geoname'},
|
||||||
|
{id: 'country', title: 'Find: Country'}
|
||||||
|
],
|
||||||
|
overlap: 'right',
|
||||||
|
width: 128
|
||||||
|
}),
|
||||||
|
self.$findInput = new Ox.Input({
|
||||||
|
clear: true,
|
||||||
|
width: 192
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.css({float: 'right', margin: '4px'})
|
||||||
|
.appendTo(self.$toolbar)
|
||||||
|
|
||||||
|
self.$list = new Ox.TextList({
|
||||||
|
columns: self.columns,
|
||||||
|
columnsRemovable: true,
|
||||||
|
columnsVisible: true,
|
||||||
|
items: self.options.places,
|
||||||
|
pageLength: 100,
|
||||||
|
scrollbarVisible: true,
|
||||||
|
sort: [
|
||||||
|
{key: 'name', operator: '+'}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
'delete': removeItem,
|
||||||
|
init: initList,
|
||||||
|
load: function() {
|
||||||
|
that.triggerEvent('loadlist');
|
||||||
|
},
|
||||||
|
open: openItem,
|
||||||
|
select: selectItem
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$statusbar = new Ox.Bar({
|
||||||
|
size: 24
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$status = new Ox.Element()
|
||||||
|
.css({paddingTop: '4px', margin: 'auto', textAlign: 'center'})
|
||||||
|
.appendTo(self.$statusbar);
|
||||||
|
|
||||||
|
self.mapResize = [
|
||||||
|
Math.round(self.options.width * 0.25),
|
||||||
|
Math.round(self.options.width * 0.5),
|
||||||
|
Math.round(self.options.width * 0.75)
|
||||||
|
];
|
||||||
|
|
||||||
|
if (Ox.isArray(self.options.places)) {
|
||||||
|
init(self.options.places)
|
||||||
|
} else {
|
||||||
|
self.options.places({}, function(result) {
|
||||||
|
Ox.print('$$$$', result.data.items)
|
||||||
|
self.options.places({
|
||||||
|
keys: self.columns.map(function(column) {
|
||||||
|
return column.id
|
||||||
|
}),
|
||||||
|
range: [0, result.data.items]
|
||||||
|
}, function(result) {
|
||||||
|
Ox.print('DATA', result)
|
||||||
|
init(result.data.items);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(places) {
|
||||||
|
Ox.print('PLACES', places)
|
||||||
|
self.$map = new Ox.Map({
|
||||||
|
clickable: true,
|
||||||
|
editable: true,
|
||||||
|
findPlaceholder: 'Find on Map',
|
||||||
|
height: self.options.height,
|
||||||
|
places: places,
|
||||||
|
statusbar: true,
|
||||||
|
toolbar: true,
|
||||||
|
width: self.mapResize[1],
|
||||||
|
zoombar: true
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
addplace: function(event, data) {
|
||||||
|
that.triggerEvent('addplace', data);
|
||||||
|
},
|
||||||
|
resize: function() {
|
||||||
|
self.$map.resizeMap(); // fixme: don't need event
|
||||||
|
},
|
||||||
|
selectplace: selectPlace
|
||||||
|
});
|
||||||
|
that.$element.replaceWith(
|
||||||
|
that.$element = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: self.$toolbar,
|
||||||
|
size: 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: self.$list
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: self.$statusbar,
|
||||||
|
size: 24
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'vertical'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: self.$map,
|
||||||
|
resizable: true,
|
||||||
|
resize: self.mapResize,
|
||||||
|
size: self.mapResize[1]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'horizontal'
|
||||||
|
}).$element
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initList(event, data) {
|
||||||
|
self.$status.html(data.items + ' place' + (data.items == 1 ? '' : 's'))
|
||||||
|
}
|
||||||
|
|
||||||
|
function openItem(event, data) {
|
||||||
|
selectItem(event, data);
|
||||||
|
self.$map.zoomToPlace(data.ids[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeItem(event, data) {
|
||||||
|
var id = data.ids[0];
|
||||||
|
that.triggerEvent('removeplace', {id: id});
|
||||||
|
self.$map.removePlace(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectItem(event, data) {
|
||||||
|
Ox.print('selectItem', data.ids[0])
|
||||||
|
var id = data.ids.length ? data.ids[0] : null;
|
||||||
|
self.$map.options({selected: id});
|
||||||
|
id && self.$map.panToPlace();
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectPlace(event, data) {
|
||||||
|
Ox.print('selectPlace', data, data.id)
|
||||||
|
data.id && data.id[0] != '_' && self.$list.options({
|
||||||
|
selected: data.id ? [data.id] : []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toFixed(val) {
|
||||||
|
return val.toFixed(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
Ox.print('ONCHANGE')
|
||||||
|
if (key == 'height' || key == 'width') {
|
||||||
|
Ox.print('ONCHANGE...')
|
||||||
|
self.$map.options({
|
||||||
|
height: self.options.height,
|
||||||
|
width: self.options.width
|
||||||
|
})
|
||||||
|
} else if (key == 'selected') {
|
||||||
|
self.$list.options({selected: value});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.focusList = function() {
|
||||||
|
self.$list.gainFocus();
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.reloadList = function() {
|
||||||
|
self.$list.reloadList();
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.resizeMap = function() {
|
||||||
|
Ox.print('Ox.ListMap.resizeMap()')
|
||||||
|
self.$map.resizeMap();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
6
source/js/Ox.ListPage.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
Ox.ListPage = function(options, self) {
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.addClass('OxPage');
|
||||||
|
return that;
|
||||||
|
};
|
27
source/js/Ox.LoadingIcon.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Ox.LoadingIcon = function(options, self) {
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('img', self)
|
||||||
|
.defaults({
|
||||||
|
size: 'medium'
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.getImagePath('symbolLoading.svg')
|
||||||
|
})
|
||||||
|
.addClass(
|
||||||
|
'OxLoadingIcon Ox' + Ox.toTitleCase(self.options.size)
|
||||||
|
);
|
||||||
|
that.start = function() {
|
||||||
|
that.animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 250);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
that.stop = function() {
|
||||||
|
that.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 250);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
184
source/js/Ox.MainMenu.js
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
Ox.MainMenu = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Bar({}, self)
|
||||||
|
.defaults({
|
||||||
|
extras: [],
|
||||||
|
menus: [],
|
||||||
|
size: 'medium'
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxMainMenu Ox' + Ox.toTitleCase(self.options.size)) // fixme: bar should accept small/medium/large ... like toolbar
|
||||||
|
.click(click)
|
||||||
|
.mousemove(mousemove);
|
||||||
|
|
||||||
|
self.focused = false;
|
||||||
|
self.selected = -1;
|
||||||
|
that.menus = [];
|
||||||
|
that.titles = [];
|
||||||
|
that.layer = $('<div>').addClass('OxLayer');
|
||||||
|
|
||||||
|
self.options.menus.forEach(function(menu, position) {
|
||||||
|
that.titles[position] = $('<div>')
|
||||||
|
.addClass('OxTitle')
|
||||||
|
.html(menu.title)
|
||||||
|
.data('position', position)
|
||||||
|
.appendTo(that.$element);
|
||||||
|
that.menus[position] = new Ox.Menu($.extend(menu, {
|
||||||
|
element: that.titles[position],
|
||||||
|
mainmenu: that,
|
||||||
|
size: self.options.size
|
||||||
|
}))
|
||||||
|
.bindEvent({
|
||||||
|
hide: onHideMenu
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (self.options.extras.length) {
|
||||||
|
that.extras = $('<div>')
|
||||||
|
.addClass('OxExtras')
|
||||||
|
.appendTo(that.$element);
|
||||||
|
self.options.extras.forEach(function(extra) {
|
||||||
|
extra.css({
|
||||||
|
float: 'left' // fixme: need class!
|
||||||
|
}).appendTo(that.extras);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function click(event) {
|
||||||
|
var $target = $(event.target),
|
||||||
|
position = typeof $target.data('position') != 'undefined' ?
|
||||||
|
$target.data('position') : -1;
|
||||||
|
clickTitle(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickTitle(position) {
|
||||||
|
var selected = self.selected;
|
||||||
|
if (self.selected > -1) {
|
||||||
|
that.menus[self.selected].hideMenu();
|
||||||
|
}
|
||||||
|
if (position > -1) {
|
||||||
|
if (position != selected) {
|
||||||
|
self.focused = true;
|
||||||
|
self.selected = position;
|
||||||
|
that.titles[self.selected].addClass('OxSelected');
|
||||||
|
that.menus[self.selected].showMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousemove(event) {
|
||||||
|
var $target = $(event.target),
|
||||||
|
focused,
|
||||||
|
position = typeof $target.data('position') != 'undefined' ?
|
||||||
|
$target.data('position') : -1;
|
||||||
|
if (self.focused && position != self.selected) {
|
||||||
|
if (position > -1) {
|
||||||
|
clickTitle(position);
|
||||||
|
} else {
|
||||||
|
focused = self.focused;
|
||||||
|
that.menus[self.selected].hideMenu();
|
||||||
|
self.focused = focused;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onHideMenu() {
|
||||||
|
if (self.selected > -1) {
|
||||||
|
that.titles[self.selected].removeClass('OxSelected');
|
||||||
|
self.selected = -1;
|
||||||
|
}
|
||||||
|
self.focused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.addMenuAfter = function(id) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.addMenuBefore = function(id) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.checkItem = function(id) {
|
||||||
|
var ids = id.split('_'),
|
||||||
|
itemId = ids.pop(),
|
||||||
|
menuId = ids.join('_');
|
||||||
|
that.getMenu(menuId).checkItem(itemId);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.disableItem = function(id) {
|
||||||
|
that.getItem(id).options({
|
||||||
|
disabled: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
that.enableItem = function(id) {
|
||||||
|
Ox.print('ENABLE ITEM', id)
|
||||||
|
that.getItem(id).options({
|
||||||
|
disabled: false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
that.getItem = function(id) {
|
||||||
|
var ids = id.split('_'),
|
||||||
|
item;
|
||||||
|
if (ids.length == 1) {
|
||||||
|
Ox.forEach(that.menus, function(menu) {
|
||||||
|
item = menu.getItem(id);
|
||||||
|
return !item;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
item = that.getMenu(ids.shift()).getItem(ids.join('_'));
|
||||||
|
}
|
||||||
|
Ox.print('getItem', id, item);
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.getMenu = function(id) {
|
||||||
|
var ids = id.split('_'),
|
||||||
|
menu;
|
||||||
|
if (ids.length == 1) {
|
||||||
|
Ox.forEach(that.menus, function(v) {
|
||||||
|
if (v.options('id') == id) {
|
||||||
|
menu = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
menu = that.getMenu(ids.shift()).getSubmenu(ids.join('_'));
|
||||||
|
}
|
||||||
|
//Ox.print('getMenu', id, menu);
|
||||||
|
return menu;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.removeMenu = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.selectNextMenu = function() {
|
||||||
|
if (self.selected < self.options.menus.length - 1) {
|
||||||
|
clickTitle(self.selected + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.selectPreviousMenu = function() {
|
||||||
|
if (self.selected) {
|
||||||
|
clickTitle(self.selected - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.uncheckItem = function(id) {
|
||||||
|
that.getItem(id).options({
|
||||||
|
checked: false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
950
source/js/Ox.Map.js
Normal file
|
@ -0,0 +1,950 @@
|
||||||
|
Ox.Map = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {}
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
// fixme: isClickable? hasZoombar?
|
||||||
|
clickable: false,
|
||||||
|
editable: false,
|
||||||
|
findPlaceholder: 'Find',
|
||||||
|
labels: false,
|
||||||
|
markers: 100,
|
||||||
|
places: [],
|
||||||
|
selected: null,
|
||||||
|
statusbar: false,
|
||||||
|
toolbar: false,
|
||||||
|
zoombar: false
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxMap')
|
||||||
|
.click(function(e) {
|
||||||
|
!$(e.target).is('input') && that.gainFocus();
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
key_0: function() {
|
||||||
|
that.panToPlace()
|
||||||
|
},
|
||||||
|
key_down: function() {
|
||||||
|
pan(0, 1);
|
||||||
|
},
|
||||||
|
key_enter: pressEnter,
|
||||||
|
key_escape: pressEscape,
|
||||||
|
key_equal: function() {
|
||||||
|
zoom(1);
|
||||||
|
},
|
||||||
|
key_l: toggleLabels,
|
||||||
|
key_left: function() {
|
||||||
|
pan(-1, 0);
|
||||||
|
},
|
||||||
|
key_meta: function() {
|
||||||
|
self.metaKey = true;
|
||||||
|
$(document).one({
|
||||||
|
keyup: function() {
|
||||||
|
self.metaKey = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
key_minus: function() {
|
||||||
|
zoom(-1);
|
||||||
|
},
|
||||||
|
key_right: function() {
|
||||||
|
pan(1, 0);
|
||||||
|
},
|
||||||
|
key_shift: function() {
|
||||||
|
self.shiftKey = true;
|
||||||
|
$(document).one({
|
||||||
|
keyup: function() {
|
||||||
|
self.shiftKey = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
key_shift_down: function() {
|
||||||
|
pan(0, 2);
|
||||||
|
},
|
||||||
|
key_shift_0: function() {
|
||||||
|
that.zoomToPlace();
|
||||||
|
},
|
||||||
|
key_shift_equal: function() {
|
||||||
|
zoom(2)
|
||||||
|
},
|
||||||
|
key_shift_left: function() {
|
||||||
|
pan(-2, 0);
|
||||||
|
},
|
||||||
|
key_shift_minus: function() {
|
||||||
|
zoom(-2);
|
||||||
|
},
|
||||||
|
key_shift_right: function() {
|
||||||
|
pan(2, 0);
|
||||||
|
},
|
||||||
|
key_shift_up: function() {
|
||||||
|
pan(0, -2);
|
||||||
|
},
|
||||||
|
key_up: function() {
|
||||||
|
pan(0, -1);
|
||||||
|
},
|
||||||
|
key_z: undo
|
||||||
|
});
|
||||||
|
|
||||||
|
self.mapHeight = getMapHeight();
|
||||||
|
self.minZoom = getMinZoom();
|
||||||
|
self.scaleMeters = [
|
||||||
|
50000000, 20000000, 10000000,
|
||||||
|
5000000, 2000000, 1000000,
|
||||||
|
500000, 200000, 100000,
|
||||||
|
50000, 20000, 10000,
|
||||||
|
5000, 2000, 1000,
|
||||||
|
500, 200, 100,
|
||||||
|
50, 20, 10
|
||||||
|
];
|
||||||
|
|
||||||
|
Ox.extend(self, {
|
||||||
|
metaKey: false,
|
||||||
|
resultPlace: null,
|
||||||
|
shiftKey: false
|
||||||
|
});
|
||||||
|
|
||||||
|
if (self.options.toolbar) {
|
||||||
|
self.$toolbar = new Ox.Bar({
|
||||||
|
size: 24
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
self.$labelsButton = new Ox.Button({
|
||||||
|
title: 'Show Labels',
|
||||||
|
width: 96
|
||||||
|
})
|
||||||
|
.css({float: 'left', margin: '4px'})
|
||||||
|
.bindEvent({
|
||||||
|
click: toggleLabels
|
||||||
|
})
|
||||||
|
.appendTo(self.$toolbar)
|
||||||
|
self.$findInput = new Ox.Input({
|
||||||
|
clear: true,
|
||||||
|
placeholder: self.options.findPlaceholder,
|
||||||
|
width: 192
|
||||||
|
})
|
||||||
|
.css({float: 'right', margin: '4px'})
|
||||||
|
.bindEvent({
|
||||||
|
submit: submitFind
|
||||||
|
})
|
||||||
|
.appendTo(self.$toolbar)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.$map = new Ox.Element('div')
|
||||||
|
.css({
|
||||||
|
left: 0,
|
||||||
|
top: self.options.toolbar * 24 + 'px',
|
||||||
|
right: 0,
|
||||||
|
bottom: self.options.zoombar * 16 + self.options.statusbar * 24 + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
|
||||||
|
if (self.options.zoombar) {
|
||||||
|
self.$zoombar = new Ox.Bar({
|
||||||
|
size: 16
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
bottom: self.options.statusbar * 24 + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.options.statusbar) {
|
||||||
|
self.$statusbar = new Ox.Bar({
|
||||||
|
size: 24
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
bottom: 0
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
self.$placeNameInput = new Ox.Input({
|
||||||
|
placeholder: 'Name',
|
||||||
|
width: 96
|
||||||
|
})
|
||||||
|
//.css({position: 'absolute', left: 4, top: 4})
|
||||||
|
.css({float: 'left', margin: '4px 1px 4px 4px'})
|
||||||
|
.appendTo(self.$statusbar);
|
||||||
|
self.$placeGeonameInput = new Ox.Input({
|
||||||
|
placeholder: 'Geoname',
|
||||||
|
width: 96
|
||||||
|
})
|
||||||
|
//.css({position: 'absolute', left: 104, top: 4})
|
||||||
|
.css({float: 'left', margin: '4px 1px 4px 4px'})
|
||||||
|
.appendTo(self.$statusbar);
|
||||||
|
self.$placeButton = new Ox.Button({
|
||||||
|
title: 'New Place',
|
||||||
|
width: 96
|
||||||
|
})
|
||||||
|
.css({float: 'right', margin: '4px 4px 4px 2px'})
|
||||||
|
.bindEvent({
|
||||||
|
click: clickPlaceButton
|
||||||
|
})
|
||||||
|
.appendTo(self.$statusbar);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.$navigationButtons = {
|
||||||
|
'center': new Ox.Button({
|
||||||
|
title: 'close',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.addClass('OxMapButton')
|
||||||
|
.css({
|
||||||
|
left: '24px',
|
||||||
|
top: '24px'
|
||||||
|
}),
|
||||||
|
'east': new Ox.Button({
|
||||||
|
title: 'right',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.addClass('OxMapButton')
|
||||||
|
.css({
|
||||||
|
left: '44px',
|
||||||
|
top: '24px',
|
||||||
|
}),
|
||||||
|
'north': new Ox.Button({
|
||||||
|
title: 'up',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.addClass('OxMapButton')
|
||||||
|
.css({
|
||||||
|
left: '24px',
|
||||||
|
top: '4px',
|
||||||
|
}),
|
||||||
|
'south': new Ox.Button({
|
||||||
|
title: 'down',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.addClass('OxMapButton')
|
||||||
|
.css({
|
||||||
|
left: '24px',
|
||||||
|
top: '44px',
|
||||||
|
}),
|
||||||
|
'west': new Ox.Button({
|
||||||
|
title: 'left',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.addClass('OxMapButton')
|
||||||
|
.css({
|
||||||
|
left: '4px',
|
||||||
|
top: '24px',
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
self.$scaleLabel = new Ox.Label({
|
||||||
|
textAlign: 'center',
|
||||||
|
title: '...'
|
||||||
|
})
|
||||||
|
.addClass('OxMapLabel')
|
||||||
|
.css({
|
||||||
|
right: '4px',
|
||||||
|
top: '4px'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!window.googleCallback) {
|
||||||
|
window.googleCallback = function() {
|
||||||
|
delete window.googleCallback;
|
||||||
|
initMap();
|
||||||
|
};
|
||||||
|
$.getScript('http://maps.google.com/maps/api/js?callback=googleCallback&sensor=false');
|
||||||
|
} else {
|
||||||
|
(function interval() {
|
||||||
|
window.google ? initMap() : setTimeout(interval, 100);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
|
||||||
|
function addPlaceToMap(place) {
|
||||||
|
// via find, click, or new place button
|
||||||
|
var exists = false;
|
||||||
|
if (!place) {
|
||||||
|
var bounds = self.map.getBounds(),
|
||||||
|
center = self.map.getCenter(),
|
||||||
|
southwest = new google.maps.LatLngBounds(
|
||||||
|
bounds.getSouthWest(), center
|
||||||
|
).getCenter(),
|
||||||
|
northeast = new google.maps.LatLngBounds(
|
||||||
|
center, bounds.getNorthEast()
|
||||||
|
).getCenter(),
|
||||||
|
place = new Ox.MapPlace({
|
||||||
|
countryCode: '',
|
||||||
|
editable: true,
|
||||||
|
geoname: '',
|
||||||
|
id: '_' + Ox.uid(), // fixme: stupid
|
||||||
|
lat: center.lat(),
|
||||||
|
lng: center.lng(),
|
||||||
|
map: that,
|
||||||
|
name: '',
|
||||||
|
south: southwest.lat(),
|
||||||
|
west: southwest.lng(),
|
||||||
|
north: northeast.lat(),
|
||||||
|
east: northeast.lng()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ox.forEach(self.places, function(p, i) {
|
||||||
|
if (place.bounds.equals(p.bounds)) {
|
||||||
|
place = p;
|
||||||
|
exists = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!exists) {
|
||||||
|
self.resultPlace && self.resultPlace.removeElement();
|
||||||
|
self.resultPlace = place;
|
||||||
|
place.add();
|
||||||
|
}
|
||||||
|
selectPlace(place.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addPlaceToPlaces() {
|
||||||
|
var place = getSelectedPlace();
|
||||||
|
if (self.options.selected == place.id) {
|
||||||
|
self.options.selected = place.id.substr(1);
|
||||||
|
}
|
||||||
|
place.id = place.id.substr(1); // fixme: NOT SAFE!
|
||||||
|
place.name = self.$placeNameInput.value();
|
||||||
|
place.geoname = self.$placeGeonameInput.value();
|
||||||
|
place.countryCode = Ox.getCountryCode(place.geoname);
|
||||||
|
place.marker.update();
|
||||||
|
self.places.push(place);
|
||||||
|
self.resultPlace = null;
|
||||||
|
that.triggerEvent('addplace', place)
|
||||||
|
Ox.print('SSSS', self.options.selected)
|
||||||
|
}
|
||||||
|
|
||||||
|
function boundsChanged() {
|
||||||
|
setScale();
|
||||||
|
self.boundsChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canContain(outerBounds, innerBounds) {
|
||||||
|
var outerSpan = outerBounds.toSpan(),
|
||||||
|
innerSpan = innerBounds.toSpan();
|
||||||
|
return outerSpan.lat() > innerSpan.lat() &&
|
||||||
|
outerSpan.lng() > innerSpan.lng();
|
||||||
|
}
|
||||||
|
|
||||||
|
function centerChanged() {
|
||||||
|
self.center = self.map.getCenter();
|
||||||
|
self.centerChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeZoom(event, data) {
|
||||||
|
self.map.setZoom(data.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickMap(event) {
|
||||||
|
Ox.print('Ox.Map clickMap')
|
||||||
|
if (self.options.clickable/* && !editing()*/) {
|
||||||
|
getPlaceByLatLng(event.latLng, self.map.getBounds(), function(place) {
|
||||||
|
if (place) {
|
||||||
|
addPlaceToMap(place);
|
||||||
|
//selectPlace(place.id);
|
||||||
|
} else {
|
||||||
|
selectPlace(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickPlaceButton() {
|
||||||
|
var place = getSelectedPlace(),
|
||||||
|
title = self.$placeButton.options('title');
|
||||||
|
if (title == 'New Place') {
|
||||||
|
addPlaceToMap();
|
||||||
|
} else if (title == 'Add Place') {
|
||||||
|
addPlaceToPlaces();
|
||||||
|
} else if (title == 'Remove Place') {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructZoomInput() {
|
||||||
|
Ox.print('constructZoomInput', self.minZoom, self.maxZoom)
|
||||||
|
if (self.options.zoombar) {
|
||||||
|
self.$zoomInput && self.$zoomInput.removeElement();
|
||||||
|
self.$zoomInput = new Ox.Range({
|
||||||
|
arrows: true,
|
||||||
|
max: self.maxZoom,
|
||||||
|
min: self.minZoom,
|
||||||
|
size: that.width(),
|
||||||
|
thumbSize: 32,
|
||||||
|
thumbValue: true,
|
||||||
|
value: self.map.getZoom()
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: changeZoom
|
||||||
|
})
|
||||||
|
.appendTo(self.$zoombar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function editing() {
|
||||||
|
var place = getSelectedPlace();
|
||||||
|
return place && place.editing;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getElevation(point, callback) {
|
||||||
|
// fixme: unused
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
callback = point;
|
||||||
|
point = self.map.getCenter();
|
||||||
|
}
|
||||||
|
self.elevationService.getElevationForLocations({
|
||||||
|
locations: [point]
|
||||||
|
}, function(data) {
|
||||||
|
callback(data.elevation);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMapHeight() {
|
||||||
|
return self.options.height -
|
||||||
|
self.options.statusbar * 24 -
|
||||||
|
self.options.toolbar * 24 -
|
||||||
|
self.options.zoombar * 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMapType() {
|
||||||
|
return self.options.labels ? 'HYBRID' : 'SATELLITE'
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMaxZoom(point, callback) {
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
callback = point;
|
||||||
|
point = self.map.getCenter();
|
||||||
|
}
|
||||||
|
self.maxZoomService.getMaxZoomAtLatLng(point, function(data) {
|
||||||
|
callback(data.status == 'OK' ? data.zoom : null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMinZoom() {
|
||||||
|
return 0;
|
||||||
|
return Math.ceil(
|
||||||
|
Ox.log(self.mapHeight / Ox.MAP_TILE_SIZE, 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlaceById(id) {
|
||||||
|
var place = Ox.getObjectById(self.places, id);
|
||||||
|
if (!place && self.resultPlace && self.resultPlace.id == id) {
|
||||||
|
place = self.resultPlace;
|
||||||
|
}
|
||||||
|
Ox.print('getPlaceById', id, place)
|
||||||
|
return place;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlaceByLatLng(latlng, bounds, callback) {
|
||||||
|
Ox.print('ll b', latlng, bounds)
|
||||||
|
var callback = arguments.length == 3 ? callback : bounds,
|
||||||
|
bounds = arguments.length == 3 ? bounds : null;
|
||||||
|
self.geocoder.geocode({
|
||||||
|
latLng: latlng
|
||||||
|
}, function(results, status) {
|
||||||
|
Ox.print('results', results)
|
||||||
|
var length = results.length;
|
||||||
|
if (status == google.maps.GeocoderStatus.OK) {
|
||||||
|
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
|
||||||
|
if (bounds) {
|
||||||
|
Ox.forEach(results.reverse(), function(result, i) {
|
||||||
|
if (
|
||||||
|
i == length - 1 ||
|
||||||
|
canContain(bounds, result.geometry.bounds || result.geometry.viewport)
|
||||||
|
) {
|
||||||
|
callback(new Ox.MapPlace(parseGeodata(results[i])));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(new Ox.MapPlace(parseGeodata(results[0])));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Ox.print('geocode failed:', status);
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlaceByName(name, callback) {
|
||||||
|
self.geocoder.geocode({
|
||||||
|
address: name
|
||||||
|
}, function(results, status) {
|
||||||
|
if (status == google.maps.GeocoderStatus.OK) {
|
||||||
|
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
|
||||||
|
Ox.print('GEOCODER RESULT', results[0])
|
||||||
|
callback(new Ox.MapPlace(parseGeodata(results[0])));
|
||||||
|
} else {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ox.print('geocode failed:', status);
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPositionByName(name) {
|
||||||
|
var position = -1;
|
||||||
|
Ox.forEach(self.options.places, function(place, i) {
|
||||||
|
if (place.name == name) {
|
||||||
|
position = i;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedMarker() {
|
||||||
|
// needed in case self.options.selected
|
||||||
|
// is changed from outside
|
||||||
|
var id = null;
|
||||||
|
if (self.resultPlace && self.resultPlace.selected) {
|
||||||
|
id = self.resultPlace.id;
|
||||||
|
} else {
|
||||||
|
Ox.forEach(self.places, function(place) {
|
||||||
|
if (place.selected) {
|
||||||
|
id = place.id;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedPlace() {
|
||||||
|
return self.options.selected ?
|
||||||
|
getPlaceById(self.options.selected) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initMap() {
|
||||||
|
var mapBounds;
|
||||||
|
|
||||||
|
updateFormElements();
|
||||||
|
|
||||||
|
self.elevationService = new google.maps.ElevationService();
|
||||||
|
self.geocoder = new google.maps.Geocoder();
|
||||||
|
self.maxZoomService = new google.maps.MaxZoomService();
|
||||||
|
self.places = [];
|
||||||
|
self.options.places.forEach(function(place, i) {
|
||||||
|
var bounds = new google.maps.LatLngBounds(
|
||||||
|
new google.maps.LatLng(place.south, place.west),
|
||||||
|
new google.maps.LatLng(place.north, place.east)
|
||||||
|
);
|
||||||
|
if (Ox.isUndefined(place.id)) {
|
||||||
|
place.id = Ox.uid();
|
||||||
|
}
|
||||||
|
mapBounds = i == 0 ? bounds : mapBounds.union(bounds);
|
||||||
|
});
|
||||||
|
self.center = mapBounds ? mapBounds.getCenter() : new google.maps.LatLng(0, 0);
|
||||||
|
self.zoom = 1; // fixme: should depend on height
|
||||||
|
that.map = self.map = new google.maps.Map(self.$map.$element[0], {
|
||||||
|
center: self.center,
|
||||||
|
disableDefaultUI: true,
|
||||||
|
disableDoubleClickZoom: true,
|
||||||
|
mapTypeId: google.maps.MapTypeId[getMapType()],
|
||||||
|
zoom: self.zoom
|
||||||
|
});
|
||||||
|
google.maps.event.addListener(self.map, 'bounds_changed', boundsChanged);
|
||||||
|
google.maps.event.addListener(self.map, 'center_changed', centerChanged);
|
||||||
|
google.maps.event.addListener(self.map, 'click', clickMap);
|
||||||
|
google.maps.event.addListener(self.map, 'idle', mapChanged);
|
||||||
|
google.maps.event.addListener(self.map, 'zoom_changed', zoomChanged);
|
||||||
|
google.maps.event.addListenerOnce(self.map, 'tilesloaded', tilesLoaded);
|
||||||
|
mapBounds && self.map.fitBounds(mapBounds);
|
||||||
|
/*
|
||||||
|
setTimeout(function() {
|
||||||
|
}, 1000);
|
||||||
|
*/
|
||||||
|
self.options.places.forEach(function(place, i) {
|
||||||
|
self.places[i] = new Ox.MapPlace(Ox.extend({
|
||||||
|
map: that
|
||||||
|
}, place))/*.add()*/;
|
||||||
|
});
|
||||||
|
google.maps.event.trigger(self.map, 'resize');
|
||||||
|
//that.gainFocus();
|
||||||
|
that.triggerEvent('load');
|
||||||
|
function tilesLoaded() {
|
||||||
|
// fixme: can add earlier, use don't replace map contents option
|
||||||
|
Ox.forEach(self.$navigationButtons, function(button) {
|
||||||
|
button.appendTo(self.$map);
|
||||||
|
});
|
||||||
|
self.$scaleLabel.appendTo(self.$map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapChanged() {
|
||||||
|
// gets called after panning or zooming
|
||||||
|
Ox.print('mapChanged');
|
||||||
|
var bounds;
|
||||||
|
if (self.boundsChanged) {
|
||||||
|
bounds = self.map.getBounds();
|
||||||
|
self.places.sort(function(a, b) {
|
||||||
|
var sort = {
|
||||||
|
a: a.selected ? Infinity :
|
||||||
|
(bounds.contains(a.center) ? a.size : -Infinity),
|
||||||
|
b: b.selected ? Infinity :
|
||||||
|
(bounds.contains(b.center) ? b.size : -Infinity),
|
||||||
|
};
|
||||||
|
return sort.b - sort.a;
|
||||||
|
}).forEach(function(place, i) {
|
||||||
|
if (i < self.options.markers && !place.visible) {
|
||||||
|
place.add();
|
||||||
|
} else if (i >= self.options.markers && place.visible) {
|
||||||
|
place.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.boundsChanged = false;
|
||||||
|
}
|
||||||
|
if (self.centerChanged) {
|
||||||
|
getMaxZoom(function(zoom) {
|
||||||
|
if (zoom != self.maxZoom) {
|
||||||
|
self.maxZoom = zoom;
|
||||||
|
if (self.map.getZoom() > zoom) {
|
||||||
|
self.map.setZoom(zoom);
|
||||||
|
}
|
||||||
|
constructZoomInput();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.centerChanged = false;
|
||||||
|
}
|
||||||
|
if (self.zoomChanged) {
|
||||||
|
self.zoomChanged = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pan(x, y) {
|
||||||
|
self.map.panBy(x * self.$map.width() / 2, y * self.$map.height() / 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
function parseGeodata(data) {
|
||||||
|
var bounds = data.geometry.bounds || data.geometry.viewport,
|
||||||
|
place = {
|
||||||
|
components: data.address_components,
|
||||||
|
countryCode: getCountryCode(data.address_components),
|
||||||
|
east: bounds.getNorthEast().lng(),
|
||||||
|
editable: self.options.editable,
|
||||||
|
fullGeoname: getFullGeoname(data.address_components),
|
||||||
|
geoname: data.formatted_address,
|
||||||
|
id: '_' + Ox.uid(),
|
||||||
|
map: that,
|
||||||
|
name: data.formatted_address.split(', ')[0],
|
||||||
|
north: bounds.getNorthEast().lat(),
|
||||||
|
south: bounds.getSouthWest().lat(),
|
||||||
|
types: data.types.map(function(type) {
|
||||||
|
return Ox.toTitleCase(type.replace(/_/g, ' '));
|
||||||
|
}),
|
||||||
|
west: bounds.getSouthWest().lng()
|
||||||
|
};
|
||||||
|
function getCountryCode(components) {
|
||||||
|
countryCode = '';
|
||||||
|
Ox.forEach(components, function(component) {
|
||||||
|
if (component.types.indexOf('country') > -1) {
|
||||||
|
countryCode = component.short_name;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return countryCode;
|
||||||
|
}
|
||||||
|
function getFullGeoname(components) {
|
||||||
|
var country = false;
|
||||||
|
return components.map(function(component, i) {
|
||||||
|
var name = component.long_name;
|
||||||
|
if (i && components[i - 1].types.indexOf('country') > -1) {
|
||||||
|
country = true;
|
||||||
|
}
|
||||||
|
return !country && (
|
||||||
|
i == 0 || name != components[i - 1].long_name
|
||||||
|
) ? name : null;
|
||||||
|
}).join(', ')
|
||||||
|
}
|
||||||
|
return place;
|
||||||
|
}
|
||||||
|
|
||||||
|
function pressEnter() {
|
||||||
|
var place = getSelectedPlace();
|
||||||
|
if (place) {
|
||||||
|
if (place.editing) {
|
||||||
|
place.submit();
|
||||||
|
} else {
|
||||||
|
place.edit();
|
||||||
|
}
|
||||||
|
} else if (self.resultPlace) {
|
||||||
|
selectPlace(self.resultPlace.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pressEscape() {
|
||||||
|
var place = getSelectedPlace();
|
||||||
|
if (place) {
|
||||||
|
if (place.editing) {
|
||||||
|
place.cancel();
|
||||||
|
} else {
|
||||||
|
selectPlace(null);
|
||||||
|
}
|
||||||
|
} else if (self.resultPlace) {
|
||||||
|
self.resultPlace.remove();
|
||||||
|
self.resultPlace = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removePlace(id) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
//Ox.print(self.map.getZoom(), self.zoom);
|
||||||
|
self.map.getZoom() == self.zoom ?
|
||||||
|
self.map.panTo(self.center) :
|
||||||
|
self.map.fitBounds(self.bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeMap() {
|
||||||
|
/*
|
||||||
|
Ox.print('resizeMap', self.options.width, self.options.height);
|
||||||
|
var center = self.map.getCenter();
|
||||||
|
self.mapHeight = getMapHeight();
|
||||||
|
self.minZoom = getMinZoom();
|
||||||
|
that.css({
|
||||||
|
height: self.options.height + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
self.$map.css({
|
||||||
|
height: self.mapHeight + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
google.maps.event.trigger(self.map, 'resize');
|
||||||
|
self.map.setCenter(center);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectPlace(id) {
|
||||||
|
var place,
|
||||||
|
selected = getSelectedMarker();
|
||||||
|
Ox.print('Ox.Map selectPlace()', id, selected);
|
||||||
|
if (id != selected) {
|
||||||
|
place = getPlaceById(selected);
|
||||||
|
place && place.deselect();
|
||||||
|
place = getPlaceById(id);
|
||||||
|
place && place.select();
|
||||||
|
self.options.selected = id;
|
||||||
|
setStatus();
|
||||||
|
that.triggerEvent('selectplace', place);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getMetersPerPixel() {
|
||||||
|
var mapWidth = self.$map.width(),
|
||||||
|
span = self.map.getBounds().toSpan().lng();
|
||||||
|
if (span >= 360) {
|
||||||
|
span = 360 * mapWidth / Ox.MAP_TILE_SIZE;
|
||||||
|
}
|
||||||
|
return span * Ox.getMetersPerDegree(self.map.getCenter().lat()) / mapWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setScale() {
|
||||||
|
var metersPerPixel = getMetersPerPixel();
|
||||||
|
Ox.forEach(self.scaleMeters, function(meters) {
|
||||||
|
var scaleWidth = Math.round(meters / metersPerPixel);
|
||||||
|
if (scaleWidth <= 256) {
|
||||||
|
self.$scaleLabel
|
||||||
|
.options({
|
||||||
|
title: '\u2190 ' + (
|
||||||
|
meters > 1000 ? Ox.formatNumber(meters / 1000) + ' k' : meters + ' '
|
||||||
|
) + 'm \u2192'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: (scaleWidth - 10) + 'px'
|
||||||
|
})
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setStatus() {
|
||||||
|
Ox.print('setStatus()', self.options.selected)
|
||||||
|
var disabled, place, title;
|
||||||
|
if (self.options.statusbar) {
|
||||||
|
place = getSelectedPlace();
|
||||||
|
if (place) {
|
||||||
|
title = place.id[0] == '_' ? 'Add Place' : 'Remove Place';
|
||||||
|
} else {
|
||||||
|
title = 'New Place';
|
||||||
|
}
|
||||||
|
disabled = place && !place.editable;
|
||||||
|
self.$placeNameInput.options({
|
||||||
|
disabled: disabled,
|
||||||
|
value: place ? place.name : ''
|
||||||
|
});
|
||||||
|
self.$placeGeonameInput.options({
|
||||||
|
disabled: disabled,
|
||||||
|
value: place ? place.geoname : ''
|
||||||
|
});
|
||||||
|
self.$placeButton.options({
|
||||||
|
disabled: disabled,
|
||||||
|
title: title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ox.print('STATUS DONE');
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitFind(event, data) {
|
||||||
|
that.findPlace(data.value, function(place) {
|
||||||
|
setStatus(place);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleLabels() {
|
||||||
|
self.options.labels = !self.options.labels
|
||||||
|
self.map.setMapTypeId(google.maps.MapTypeId[getMapType()]);
|
||||||
|
self.$labelsButton.options({
|
||||||
|
title: self.$labelsButton.options('title') == 'Show Labels' ?
|
||||||
|
'Hide Labels' : 'Show Labels'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function undo() {
|
||||||
|
Ox.print('Map undo')
|
||||||
|
var place = getSelectedPlace();
|
||||||
|
place.editing && place.undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateFormElements() {
|
||||||
|
var width = that.width();
|
||||||
|
self.$zoomInput && constructZoomInput();
|
||||||
|
self.$placeNameInput.options({
|
||||||
|
width: Math.floor((width - 112) / 2)
|
||||||
|
});
|
||||||
|
self.$placeGeonameInput.options({
|
||||||
|
width: Math.ceil((width - 112) / 2)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function zoom(z) {
|
||||||
|
self.map.setZoom(self.map.getZoom() + z);
|
||||||
|
}
|
||||||
|
|
||||||
|
function zoomChanged() {
|
||||||
|
var zoom = self.map.getZoom();
|
||||||
|
if (zoom < self.minZoom) {
|
||||||
|
self.map.setZoom(self.minZoom);
|
||||||
|
} else if (self.maxZoom && zoom > self.maxZoom) {
|
||||||
|
self.map.setZoom(self.maxZoom);
|
||||||
|
} else {
|
||||||
|
self.zoomChanged = true;
|
||||||
|
self.$zoomInput && self.$zoomInput.options({value: zoom});
|
||||||
|
that.triggerEvent('zoom', {
|
||||||
|
value: zoom
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function zoomToPlace() {
|
||||||
|
Ox.print('zoomToPlace')
|
||||||
|
if (self.options.selected !== null) {
|
||||||
|
self.map.fitBounds(getPlaceById(self.options.selected).bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
/*if (key == 'height' || key == 'width') {
|
||||||
|
resizeMap();
|
||||||
|
} else */if (key == 'places') {
|
||||||
|
loadPlaces();
|
||||||
|
} else if (key == 'selected') {
|
||||||
|
selectPlace(value);
|
||||||
|
} else if (key == 'type') {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.getKey = function() {
|
||||||
|
var key = null;
|
||||||
|
if (self.shiftKey) {
|
||||||
|
key = 'shift'
|
||||||
|
} else if (self.metaKey) {
|
||||||
|
key = 'meta'
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.editPlace = function() {
|
||||||
|
getPlaceById(self.options.selected).edit();
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.findPlace = function(name, callback) {
|
||||||
|
getPlaceByName(name, function(place) {
|
||||||
|
if (place) {
|
||||||
|
addPlaceToMap(place);
|
||||||
|
self.map.fitBounds(place.bounds);
|
||||||
|
}
|
||||||
|
callback(place);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
that.panToPlace = function() {
|
||||||
|
Ox.print('panToPlace:', self.options.selected)
|
||||||
|
var place = getSelectedPlace();
|
||||||
|
place && self.map.panTo(place.center);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.removePlace = function(id) {
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.resizeMap = function() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ox.print('resizeMap', self.options.width, self.options.height);
|
||||||
|
var center = self.map.getCenter();
|
||||||
|
self.mapHeight = getMapHeight();
|
||||||
|
self.minZoom = getMinZoom();
|
||||||
|
that.css({
|
||||||
|
height: self.options.height + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
self.$map.css({
|
||||||
|
height: self.mapHeight + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
google.maps.event.trigger(self.map, 'resize');
|
||||||
|
self.map.setCenter(center);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ox.print('Ox.Map.resizeMap()');
|
||||||
|
var center = self.map.getCenter();
|
||||||
|
self.options.height = that.$element.height();
|
||||||
|
self.options.width = that.$element.width();
|
||||||
|
Ox.print(self.options.width, self.options.height)
|
||||||
|
self.$map.css({
|
||||||
|
height: self.mapHeight + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
google.maps.event.trigger(self.map, 'resize');
|
||||||
|
self.map.setCenter(center);
|
||||||
|
self.options.zoombar && self.$zoomInput.options({
|
||||||
|
size: self.options.width
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
updateFormElements();
|
||||||
|
google.maps.event.trigger(self.map, 'resize');
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.zoomToPlace = function() {
|
||||||
|
Ox.print('zoomToPlace')
|
||||||
|
var place = getSelectedPlace();
|
||||||
|
place && self.map.fitBounds(place.bounds);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.zoom = function(value) {
|
||||||
|
self.map.setZoom(value);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
67
source/js/Ox.MapImage.js
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
Ox.MapImage = function(options, self) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
options
|
||||||
|
height image height (px)
|
||||||
|
places array of either names (''), points ([0, 0]),
|
||||||
|
or objects ({name, point, highlight})
|
||||||
|
type map type ('hybrid', 'roadmap', 'satellite', 'terrain')
|
||||||
|
width image width (px)
|
||||||
|
*/
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('img', self)
|
||||||
|
.defaults({
|
||||||
|
height: 360,
|
||||||
|
markerColorHighlight: 'yellow',
|
||||||
|
markerColorNormal: 'blue',
|
||||||
|
places: [],
|
||||||
|
type: 'satellite',
|
||||||
|
width: 640
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
markers: {
|
||||||
|
highlight: [],
|
||||||
|
normal: []
|
||||||
|
},
|
||||||
|
src: 'http://maps.google.com/maps/api/staticmap?sensor=false' +
|
||||||
|
'&size=' + self.options.width + 'x' + self.options.height +
|
||||||
|
'&maptype=' + self.options.type
|
||||||
|
});
|
||||||
|
|
||||||
|
if (self.options.places.length) {
|
||||||
|
self.options.places.forEach(function(place) {
|
||||||
|
if (Ox.isString(place)) {
|
||||||
|
self.markers.normal.push(place);
|
||||||
|
} else if (Ox.isArray(place)) {
|
||||||
|
self.markers.normal.push(place.join(','));
|
||||||
|
} else {
|
||||||
|
self.markers[place.highlight ? 'highlight' : 'normal']
|
||||||
|
.push('point' in place ? place.point.join(',') : place.name)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ox.forEach(self.markers, function(markers, k) {
|
||||||
|
if (markers.length) {
|
||||||
|
self.src += '&markers=icon:' + 'http://dev.pan.do:8000' +
|
||||||
|
Ox.UI.PATH + 'png/ox.map/marker' +
|
||||||
|
Ox.toTitleCase(self.options['markerColor' + Ox.toTitleCase(k)]) +
|
||||||
|
'.png|' + markers.join('|')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.src += '¢er=0,0&zoom=2'
|
||||||
|
}
|
||||||
|
|
||||||
|
that.attr({
|
||||||
|
src: self.src
|
||||||
|
});
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
130
source/js/Ox.MapMarker.js
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
Ox.MapMarker = function(options) {
|
||||||
|
|
||||||
|
var options = Ox.extend({
|
||||||
|
map: null,
|
||||||
|
place: null
|
||||||
|
}, options),
|
||||||
|
that = this;
|
||||||
|
|
||||||
|
Ox.forEach(options, function(val, key) {
|
||||||
|
that[key] = val;
|
||||||
|
});
|
||||||
|
that.marker = new google.maps.Marker({
|
||||||
|
raiseOnDrag: false,
|
||||||
|
shape: {coords: [8, 8, 8], type: 'circle'},
|
||||||
|
title: that.place.name,
|
||||||
|
//zIndex: 1000
|
||||||
|
});
|
||||||
|
|
||||||
|
setOptions();
|
||||||
|
|
||||||
|
function click() {
|
||||||
|
if (!that.place.selected) {
|
||||||
|
that.map.options({selected: that.place.id});
|
||||||
|
} else if (that.map.getKey() == 'meta') {
|
||||||
|
that.map.options({selected: null});
|
||||||
|
} else if (that.map.getKey() == 'shift') {
|
||||||
|
that.map.zoomToPlace();
|
||||||
|
} else {
|
||||||
|
that.map.panToPlace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragstart(e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function drag(e) {
|
||||||
|
var northSouth = (that.place.north - that.place.south) / 2,
|
||||||
|
lat = Ox.limit(
|
||||||
|
e.latLng.lat(),
|
||||||
|
Ox.MIN_LATITUDE + northSouth,
|
||||||
|
Ox.MAX_LATITUDE - northSouth
|
||||||
|
),
|
||||||
|
lng = e.latLng.lng(),
|
||||||
|
span = Math.min(
|
||||||
|
that.place.sizeEastWest * Ox.getDegreesPerMeter(lat) / 2, 179.99999999
|
||||||
|
);
|
||||||
|
degreesPerMeter = Ox.getDegreesPerMeter(lat);
|
||||||
|
that.place.south += lat - that.place.lat;
|
||||||
|
that.place.north += lat - that.place.lat;
|
||||||
|
that.place.west = lng - span;
|
||||||
|
that.place.east = lng + span;
|
||||||
|
if (that.place.west < -180) {
|
||||||
|
that.place.west += 360;
|
||||||
|
} else if (that.place.east > 180) {
|
||||||
|
that.place.east -= 360;
|
||||||
|
}
|
||||||
|
Ox.print('west', that.place.west, 'east', that.place.east, 'span', span);
|
||||||
|
that.place.update();
|
||||||
|
that.marker.setOptions({
|
||||||
|
position: that.place.center
|
||||||
|
})
|
||||||
|
that.place.rectangle.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragend(e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setOptions() {
|
||||||
|
// workaround to prevent marker from appearing twice
|
||||||
|
// after setting draggable from true to false
|
||||||
|
var fix = that.marker.getDraggable() && !that.place.editing;
|
||||||
|
that.marker.setOptions({
|
||||||
|
// fixme: cursor remains pointer
|
||||||
|
cursor: that.place.editing ? 'move' : 'pointer',
|
||||||
|
draggable: that.place.editing,
|
||||||
|
icon: new google.maps.MarkerImage(
|
||||||
|
Ox.UI.PATH + 'png/ox.map/marker' +
|
||||||
|
(that.place.id[0] == '_' ? 'Result' : '') +
|
||||||
|
(that.place.editing ? 'Editing' : (
|
||||||
|
that.place.selected ? 'Selected' : ''
|
||||||
|
)) + '.png',
|
||||||
|
new google.maps.Size(16, 16),
|
||||||
|
new google.maps.Point(0, 0),
|
||||||
|
new google.maps.Point(8, 8)
|
||||||
|
),
|
||||||
|
position: that.place.center
|
||||||
|
});
|
||||||
|
if (fix) {
|
||||||
|
that.marker.setVisible(false);
|
||||||
|
setTimeout(function() {
|
||||||
|
that.marker.setVisible(true);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.add = function() {
|
||||||
|
//Ox.print('MapMarker add', that)
|
||||||
|
that.marker.setMap(that.map.map);
|
||||||
|
google.maps.event.addListener(that.marker, 'click', click);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.edit = function() {
|
||||||
|
setOptions();
|
||||||
|
google.maps.event.addListener(that.marker, 'dragstart', dragstart);
|
||||||
|
google.maps.event.addListener(that.marker, 'drag', drag);
|
||||||
|
google.maps.event.addListener(that.marker, 'dragend', dragend);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.remove = function() {
|
||||||
|
that.marker.setMap(null);
|
||||||
|
google.maps.event.clearListeners(that.marker);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.submit = function() {
|
||||||
|
google.maps.event.clearListeners(that.marker, 'dragstart');
|
||||||
|
google.maps.event.clearListeners(that.marker, 'drag');
|
||||||
|
google.maps.event.clearListeners(that.marker, 'dragend');
|
||||||
|
}
|
||||||
|
|
||||||
|
that.update = function() {
|
||||||
|
setOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
156
source/js/Ox.MapPlace.js
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
Ox.MapPlace = function(options) {
|
||||||
|
|
||||||
|
options = Ox.extend({
|
||||||
|
east: 0,
|
||||||
|
editing: false,
|
||||||
|
geoname: '',
|
||||||
|
map: null,
|
||||||
|
name: '',
|
||||||
|
north: 0,
|
||||||
|
selected: false,
|
||||||
|
south: 0,
|
||||||
|
type: [],
|
||||||
|
visible: false,
|
||||||
|
west: 0
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
Ox.forEach(options, function(val, key) {
|
||||||
|
that[key] = val;
|
||||||
|
});
|
||||||
|
|
||||||
|
update();
|
||||||
|
|
||||||
|
function update() {
|
||||||
|
that.points = {
|
||||||
|
ne: new google.maps.LatLng(that.north, that.east),
|
||||||
|
sw: new google.maps.LatLng(that.south, that.west)
|
||||||
|
};
|
||||||
|
that.bounds = new google.maps.LatLngBounds(that.points.sw, that.points.ne);
|
||||||
|
that.center = that.bounds.getCenter();
|
||||||
|
that.lat = that.center.lat();
|
||||||
|
that.lng = that.center.lng();
|
||||||
|
Ox.extend(that.points, {
|
||||||
|
e: new google.maps.LatLng(that.lat, that.east),
|
||||||
|
s: new google.maps.LatLng(that.south, that.lng),
|
||||||
|
se: new google.maps.LatLng(that.south, that.east),
|
||||||
|
n: new google.maps.LatLng(that.north, that.lng),
|
||||||
|
nw: new google.maps.LatLng(that.north, that.west),
|
||||||
|
w: new google.maps.LatLng(that.lat, that.west),
|
||||||
|
});
|
||||||
|
// fixme: use bounds.toSpan()
|
||||||
|
that.sizeNorthSouth = (that.north - that.south) *
|
||||||
|
Ox.EARTH_CIRCUMFERENCE / 360;
|
||||||
|
that.sizeEastWest = (that.east + (that.west > that.east ? 360 : 0) - that.west) *
|
||||||
|
Ox.getMetersPerDegree(that.lat);
|
||||||
|
that.size = Ox.getArea(
|
||||||
|
{lat: that.south, lng: that.west},
|
||||||
|
{lat: that.north, lng: that.east}
|
||||||
|
);
|
||||||
|
if (!that.marker) {
|
||||||
|
that.marker = new Ox.MapMarker({
|
||||||
|
map: that.map,
|
||||||
|
place: that
|
||||||
|
});
|
||||||
|
that.rectangle = new Ox.MapRectangle({
|
||||||
|
map: that.map,
|
||||||
|
place: that
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//Ox.print('PLACE', that)
|
||||||
|
}
|
||||||
|
|
||||||
|
function editable() {
|
||||||
|
return that.map.options('editable') && that.editable;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.add = function() {
|
||||||
|
//Ox.print('MapPlace add', that)
|
||||||
|
that.visible = true;
|
||||||
|
that.marker.add();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.cancel = function() {
|
||||||
|
if (editable()) {
|
||||||
|
that.undo();
|
||||||
|
that.editing = false;
|
||||||
|
that.marker.update();
|
||||||
|
that.rectangle.deselect();
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.crossesDateline = function() {
|
||||||
|
return that.west > that.east;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.deselect = function() {
|
||||||
|
that.editing && that.submit();
|
||||||
|
that.selected = false;
|
||||||
|
that.marker.update();
|
||||||
|
that.rectangle.remove();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.edit = function() {
|
||||||
|
if (editable()) {
|
||||||
|
that.editing = true;
|
||||||
|
that.original = {
|
||||||
|
south: that.south,
|
||||||
|
west: that.west,
|
||||||
|
north: that.north,
|
||||||
|
east: that.east
|
||||||
|
};
|
||||||
|
that.marker.edit();
|
||||||
|
that.rectangle.select();
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.remove = function() {
|
||||||
|
that.editing && that.submit();
|
||||||
|
that.selected && that.deselect();
|
||||||
|
that.visible = false;
|
||||||
|
that.marker.remove();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.select = function() {
|
||||||
|
that.selected = true;
|
||||||
|
!that.visible && that.add();
|
||||||
|
that.marker.update();
|
||||||
|
that.rectangle.add();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.submit = function() {
|
||||||
|
if (editable()) {
|
||||||
|
that.editing = false;
|
||||||
|
that.marker.update();
|
||||||
|
that.rectangle.deselect();
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.update = function() {
|
||||||
|
update();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.undo = function() {
|
||||||
|
if (editable()) {
|
||||||
|
Ox.forEach(that.original, function(v, k) {
|
||||||
|
that[k] = v;
|
||||||
|
});
|
||||||
|
that.update();
|
||||||
|
that.marker.update();
|
||||||
|
that.rectangle.update();
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
88
source/js/Ox.MapRectangle.js
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
Ox.MapRectangle = function(options, self) {
|
||||||
|
|
||||||
|
var options = Ox.extend({
|
||||||
|
map: null,
|
||||||
|
place: null
|
||||||
|
}, options),
|
||||||
|
that = this;
|
||||||
|
|
||||||
|
Ox.forEach(options, function(val, key) {
|
||||||
|
that[key] = val;
|
||||||
|
});
|
||||||
|
|
||||||
|
that.rectangle = new google.maps.Rectangle({
|
||||||
|
clickable: true,
|
||||||
|
bounds: that.place.bounds,
|
||||||
|
});
|
||||||
|
that.markers = Ox.map(that.place.points, function(point, position) {
|
||||||
|
return new Ox.MapRectangleMarker({
|
||||||
|
map: that.map,
|
||||||
|
place: that.place,
|
||||||
|
position: position
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
setOptions();
|
||||||
|
|
||||||
|
function click() {
|
||||||
|
if (that.map.options('editable') && that.place.editable && !that.place.editing) {
|
||||||
|
that.place.edit();
|
||||||
|
} else if (that.map.getKey() == 'meta') {
|
||||||
|
that.place.submit();
|
||||||
|
} else if (that.map.getKey() == 'shift') {
|
||||||
|
that.map.zoomToPlace();
|
||||||
|
} else {
|
||||||
|
that.map.panToPlace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setOptions() {
|
||||||
|
var color = that.place.editing ? '#8080FF' : '#FFFFFF';
|
||||||
|
that.rectangle.setOptions({
|
||||||
|
fillColor: color,
|
||||||
|
fillOpacity: that.place.editing ? 0.1 : 0,
|
||||||
|
strokeColor: color,
|
||||||
|
strokeOpacity: 1,
|
||||||
|
strokeWeight: 2
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
that.add = function() {
|
||||||
|
that.rectangle.setMap(that.map.map);
|
||||||
|
google.maps.event.addListener(that.rectangle, 'click', click);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.deselect = function() {
|
||||||
|
setOptions();
|
||||||
|
Ox.print('MARKERS', that.markers)
|
||||||
|
Ox.forEach(that.markers, function(marker) {
|
||||||
|
marker.remove();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
that.remove = function() {
|
||||||
|
that.rectangle.setMap(null);
|
||||||
|
google.maps.event.clearListeners(that.rectangle);
|
||||||
|
return that
|
||||||
|
}
|
||||||
|
|
||||||
|
that.select = function() {
|
||||||
|
setOptions();
|
||||||
|
Ox.forEach(that.markers, function(marker) {
|
||||||
|
marker.add();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
that.update = function() {
|
||||||
|
that.rectangle.setOptions({
|
||||||
|
bounds: that.place.bounds
|
||||||
|
});
|
||||||
|
Ox.forEach(that.markers, function(marker) {
|
||||||
|
marker.update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
95
source/js/Ox.MapRectangleMarker.js
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
Ox.MapRectangleMarker = function(options, self) {
|
||||||
|
|
||||||
|
var options = Ox.extend({
|
||||||
|
map: null,
|
||||||
|
place: null,
|
||||||
|
position: ''
|
||||||
|
}, options),
|
||||||
|
that = this;
|
||||||
|
|
||||||
|
Ox.forEach(options, function(val, key) {
|
||||||
|
that[key] = val;
|
||||||
|
});
|
||||||
|
|
||||||
|
that.markerImage = new google.maps.MarkerImage
|
||||||
|
that.marker = new google.maps.Marker({
|
||||||
|
cursor: that.position + '-resize',
|
||||||
|
draggable: true,
|
||||||
|
icon: new google.maps.MarkerImage(
|
||||||
|
Ox.UI.PATH + 'png/ox.map/markerResize.png',
|
||||||
|
new google.maps.Size(16, 16),
|
||||||
|
new google.maps.Point(0, 0),
|
||||||
|
new google.maps.Point(8, 8)
|
||||||
|
),
|
||||||
|
position: that.place.points[that.position],
|
||||||
|
raiseOnDrag: false
|
||||||
|
});
|
||||||
|
|
||||||
|
function dragstart(e) {
|
||||||
|
that.drag = {
|
||||||
|
lat: e.latLng.lat(),
|
||||||
|
lng: e.latLng.lng()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function drag(e) {
|
||||||
|
// fixme: implement shift+drag (center stays the same)
|
||||||
|
Ox.print(e.pixel.x, e.pixel.y)
|
||||||
|
var lat = Ox.limit(e.latLng.lat(), Ox.MIN_LATITUDE, Ox.MAX_LATITUDE),
|
||||||
|
lng = e.latLng.lng();
|
||||||
|
that.drag = {
|
||||||
|
lat: lat,
|
||||||
|
lng: lng
|
||||||
|
};
|
||||||
|
if (that.position.indexOf('s') > -1) {
|
||||||
|
that.place.south = lat;
|
||||||
|
}
|
||||||
|
if (that.position.indexOf('n') > -1) {
|
||||||
|
that.place.north = lat;
|
||||||
|
}
|
||||||
|
if (that.position.indexOf('w') > -1) {
|
||||||
|
that.place.west = lng;
|
||||||
|
}
|
||||||
|
if (that.position.indexOf('e') > -1) {
|
||||||
|
that.place.east = lng;
|
||||||
|
}
|
||||||
|
Ox.print('west', that.place.west, 'east', that.place.east);
|
||||||
|
Ox.print('south', that.place.south, 'north', that.place.north);
|
||||||
|
that.place.update();
|
||||||
|
that.place.marker.update();
|
||||||
|
that.place.rectangle.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragend(e) {
|
||||||
|
var south;
|
||||||
|
if (that.place.south > that.place.north) {
|
||||||
|
south = that.place.south;
|
||||||
|
that.place.south = that.place.north;
|
||||||
|
that.place.north = south;
|
||||||
|
that.place.update();
|
||||||
|
that.place.marker.update();
|
||||||
|
that.place.rectangle.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.add = function() {
|
||||||
|
that.marker.setMap(that.map.map);
|
||||||
|
google.maps.event.addListener(that.marker, 'dragstart', dragstart);
|
||||||
|
google.maps.event.addListener(that.marker, 'drag', drag);
|
||||||
|
google.maps.event.addListener(that.marker, 'dragend', dragend);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.remove = function() {
|
||||||
|
that.marker.setMap(null);
|
||||||
|
google.maps.event.clearListeners(that.marker);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.update = function() {
|
||||||
|
that.marker.setOptions({
|
||||||
|
position: that.place.points[that.position]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
687
source/js/Ox.Menu.js
Normal file
|
@ -0,0 +1,687 @@
|
||||||
|
/**
|
||||||
|
options
|
||||||
|
element the element the menu is attached to
|
||||||
|
id the menu id
|
||||||
|
items array of menu items
|
||||||
|
mainmenu the main menu this menu is part of, if any
|
||||||
|
offset offset of the menu, in px
|
||||||
|
parent the supermenu, if any
|
||||||
|
selected the position of the selected item
|
||||||
|
side open to 'bottom' or 'right'
|
||||||
|
size 'large', 'medium' or 'small'
|
||||||
|
|
||||||
|
events:
|
||||||
|
change_groupId {id, value} checked item of a group has changed
|
||||||
|
click_itemId item not belonging to a group was clicked
|
||||||
|
click_menuId {id, value} item not belonging to a group was clicked
|
||||||
|
deselect_menuId {id, value} item was deselected not needed, not implemented
|
||||||
|
hide_menuId menu was hidden
|
||||||
|
select_menuId {id, value} item was selected
|
||||||
|
*/
|
||||||
|
Ox.Menu = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
element: null,
|
||||||
|
id: '',
|
||||||
|
items: [],
|
||||||
|
mainmenu: null,
|
||||||
|
offset: {
|
||||||
|
left: 0,
|
||||||
|
top: 0
|
||||||
|
},
|
||||||
|
parent: null,
|
||||||
|
selected: -1,
|
||||||
|
side: 'bottom',
|
||||||
|
size: 'medium',
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass(
|
||||||
|
'OxMenu Ox' + Ox.toTitleCase(self.options.side) +
|
||||||
|
' Ox' + Ox.toTitleCase(self.options.size)
|
||||||
|
)
|
||||||
|
.click(click)
|
||||||
|
.mouseenter(mouseenter)
|
||||||
|
.mouseleave(mouseleave)
|
||||||
|
.mousemove(mousemove)
|
||||||
|
.bindEvent({
|
||||||
|
key_up: selectPreviousItem,
|
||||||
|
key_down: selectNextItem,
|
||||||
|
key_left: selectSupermenu,
|
||||||
|
key_right: selectSubmenu,
|
||||||
|
key_escape: hideMenu,
|
||||||
|
key_enter: clickSelectedItem
|
||||||
|
}),
|
||||||
|
itemHeight = self.options.size == 'small' ? 12 : (self.options.size == 'medium' ? 16 : 20),
|
||||||
|
// menuHeight,
|
||||||
|
scrollSpeed = 1,
|
||||||
|
$item; // fixme: used?
|
||||||
|
// fixme: attach all private vars to self
|
||||||
|
|
||||||
|
// construct
|
||||||
|
that.items = [];
|
||||||
|
that.submenus = {};
|
||||||
|
that.$scrollbars = [];
|
||||||
|
that.$top = $('<div>')
|
||||||
|
.addClass('OxTop')
|
||||||
|
.appendTo(that.$element);
|
||||||
|
that.$scrollbars.up = constructScrollbar('up')
|
||||||
|
.appendTo(that.$element);
|
||||||
|
that.$container = $('<div>')
|
||||||
|
.addClass('OxContainer')
|
||||||
|
.appendTo(that.$element);
|
||||||
|
that.$content = $('<table>')
|
||||||
|
.addClass('OxContent')
|
||||||
|
.appendTo(that.$container);
|
||||||
|
constructItems(self.options.items);
|
||||||
|
that.$scrollbars.down = constructScrollbar('down')
|
||||||
|
.appendTo(that.$element);
|
||||||
|
that.$bottom = $('<div>')
|
||||||
|
.addClass('OxBottom')
|
||||||
|
.appendTo(that.$element);
|
||||||
|
that.$layer = $('<div>')
|
||||||
|
.addClass(self.options.mainmenu ? 'OxMainMenuLayer' : 'OxMenuLayer')
|
||||||
|
.click(click);
|
||||||
|
|
||||||
|
function click(event) {
|
||||||
|
var item,
|
||||||
|
position,
|
||||||
|
$target = $(event.target),
|
||||||
|
$parent = $target.parent();
|
||||||
|
// necessary for highlight
|
||||||
|
if ($parent.is('.OxCell')) {
|
||||||
|
$target = $parent;
|
||||||
|
$parent = $target.parent();
|
||||||
|
}
|
||||||
|
if ($target.is('.OxCell')) {
|
||||||
|
position = $parent.data('position');
|
||||||
|
item = that.items[position];
|
||||||
|
if (!item.options('disabled')) {
|
||||||
|
clickItem(position);
|
||||||
|
} else {
|
||||||
|
that.hideMenu();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
that.hideMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickItem(position) {
|
||||||
|
var item = that.items[position],
|
||||||
|
menu = self.options.mainmenu || self.options.parent || that,
|
||||||
|
toggled;
|
||||||
|
that.hideMenu();
|
||||||
|
if (!item.options('items').length) {
|
||||||
|
if (that.options('parent')) {
|
||||||
|
that.options('parent').hideMenu().triggerEvent('click');
|
||||||
|
}
|
||||||
|
if (item.options('checked') !== null) {
|
||||||
|
if (item.options('group')) {
|
||||||
|
//Ox.print('has group', item.options('group'))
|
||||||
|
toggled = self.optionGroups[item.options('group')].toggle(position);
|
||||||
|
//Ox.print('toggled', toggled)
|
||||||
|
if (toggled.length) {
|
||||||
|
toggled.forEach(function(pos) {
|
||||||
|
that.items[pos].toggleChecked();
|
||||||
|
});
|
||||||
|
//Ox.print('--triggering change event--');
|
||||||
|
menu.triggerEvent('change', {
|
||||||
|
id: item.options('group'),
|
||||||
|
checked: $.map(self.optionGroups[item.options('group')].checked(), function(v, i) {
|
||||||
|
return {
|
||||||
|
id: that.items[v].options('id'),
|
||||||
|
title: Ox.stripTags(that.items[v].options('title')[0])
|
||||||
|
};
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item.toggleChecked();
|
||||||
|
menu.triggerEvent('change', {
|
||||||
|
checked: item.options('checked'),
|
||||||
|
id: item.options('id'),
|
||||||
|
title: Ox.stripTags(item.options('title')[0])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
menu.triggerEvent('click', {
|
||||||
|
id: item.options('id'),
|
||||||
|
title: Ox.stripTags(item.options('title')[0])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (item.options('title').length == 2) {
|
||||||
|
item.toggleTitle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickSelectedItem() {
|
||||||
|
// called on key.enter
|
||||||
|
if (self.options.selected > -1) {
|
||||||
|
clickItem(self.options.selected);
|
||||||
|
} else {
|
||||||
|
that.hideMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructItems(items) {
|
||||||
|
|
||||||
|
that.$content.empty();
|
||||||
|
scrollMenuUp();
|
||||||
|
|
||||||
|
self.optionGroups = {};
|
||||||
|
items.forEach(function(item, i) {
|
||||||
|
if (item.group) {
|
||||||
|
items[i] = $.map(item.items, function(v, i) {
|
||||||
|
return $.extend(v, {
|
||||||
|
group: item.group
|
||||||
|
});
|
||||||
|
});
|
||||||
|
self.optionGroups[item.group] = new Ox.OptionGroup(
|
||||||
|
items[i],
|
||||||
|
'min' in item ? item.min : 1,
|
||||||
|
'max' in item ? item.max : 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
items = Ox.flatten(items);
|
||||||
|
|
||||||
|
that.items = [];
|
||||||
|
items.forEach(function(item) {
|
||||||
|
var position;
|
||||||
|
if ('id' in item) {
|
||||||
|
that.items.push(new Ox.MenuItem($.extend(item, {
|
||||||
|
menu: that,
|
||||||
|
position: position = that.items.length
|
||||||
|
})).data('position', position).appendTo(that.$content)); // fixme: jquery bug when passing {position: position}? does not return the object?;
|
||||||
|
if (item.items) {
|
||||||
|
that.submenus[item.id] = new Ox.Menu({
|
||||||
|
element: that.items[position],
|
||||||
|
id: Ox.toCamelCase(self.options.id + '/' + item.id),
|
||||||
|
items: item.items,
|
||||||
|
mainmenu: self.options.mainmenu,
|
||||||
|
offset: {
|
||||||
|
left: 0,
|
||||||
|
top: -4
|
||||||
|
},
|
||||||
|
parent: that,
|
||||||
|
side: 'right',
|
||||||
|
size: self.options.size,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
that.$content.append(constructSpace());
|
||||||
|
that.$content.append(constructLine());
|
||||||
|
that.$content.append(constructSpace());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!that.is(':hidden')) {
|
||||||
|
that.hideMenu();
|
||||||
|
that.showMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructLine() {
|
||||||
|
return $('<tr>').append(
|
||||||
|
$('<td>', {
|
||||||
|
'class': 'OxLine',
|
||||||
|
colspan: 5
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructScrollbar(direction) {
|
||||||
|
var interval,
|
||||||
|
speed = direction == 'up' ? -1 : 1;
|
||||||
|
return $('<div/>', {
|
||||||
|
'class': 'OxScrollbar Ox' + Ox.toTitleCase(direction),
|
||||||
|
html: Ox.UI.symbols['triangle_' + direction],
|
||||||
|
click: function() { // fixme: do we need to listen to click event?
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
mousedown: function() {
|
||||||
|
scrollSpeed = 2;
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
mouseenter: function() {
|
||||||
|
var $otherScrollbar = that.$scrollbars[direction == 'up' ? 'down' : 'up'];
|
||||||
|
$(this).addClass('OxSelected');
|
||||||
|
if ($otherScrollbar.is(':hidden')) {
|
||||||
|
$otherScrollbar.show();
|
||||||
|
that.$container.height(that.$container.height() - itemHeight);
|
||||||
|
if (direction == 'down') {
|
||||||
|
that.$content.css({
|
||||||
|
top: -itemHeight + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scrollMenu(speed);
|
||||||
|
interval = setInterval(function() {
|
||||||
|
scrollMenu(speed);
|
||||||
|
}, 100);
|
||||||
|
},
|
||||||
|
mouseleave: function() {
|
||||||
|
$(this).removeClass('OxSelected');
|
||||||
|
clearInterval(interval);
|
||||||
|
},
|
||||||
|
mouseup: function() {
|
||||||
|
scrollSpeed = 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructSpace() {
|
||||||
|
return $('<tr>').append(
|
||||||
|
$('<td>', {
|
||||||
|
'class': 'OxSpace',
|
||||||
|
colspan: 5
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getElement(id) {
|
||||||
|
// fixme: needed?
|
||||||
|
return $('#' + Ox.toCamelCase(options.id + '/' + id));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItemPositionById(id) {
|
||||||
|
var position;
|
||||||
|
Ox.forEach(that.items, function(item, i) {
|
||||||
|
if (item.options('id') == id) {
|
||||||
|
position = i;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideMenu() {
|
||||||
|
// called on key_escape
|
||||||
|
that.hideMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFirstEnabledItem() {
|
||||||
|
var ret = true;
|
||||||
|
Ox.forEach(that.items, function(item, i) {
|
||||||
|
if (i < self.options.selected && !item.options('disabled')) {
|
||||||
|
return ret = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLastEnabledItem() {
|
||||||
|
var ret = true;
|
||||||
|
Ox.forEach(that.items, function(item, i) {
|
||||||
|
if (i > self.options.selected && !item.options('disabled')) {
|
||||||
|
return ret = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseenter() {
|
||||||
|
that.gainFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseleave() {
|
||||||
|
if (self.options.selected > -1 && !that.items[self.options.selected].options('items').length) {
|
||||||
|
selectItem(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousemove(event) {
|
||||||
|
var item,
|
||||||
|
position,
|
||||||
|
$target = $(event.target);
|
||||||
|
$parent = $target.parent();
|
||||||
|
if ($parent.is('.OxCell')) {
|
||||||
|
$target = $parent;
|
||||||
|
$parent = $target.parent();
|
||||||
|
}
|
||||||
|
if ($target.is('.OxCell')) {
|
||||||
|
position = $parent.data('position');
|
||||||
|
item = that.items[position];
|
||||||
|
if (!item.options('disabled') && position != self.options.selected) {
|
||||||
|
selectItem(position);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mouseleave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrollMenu(speed) {
|
||||||
|
var containerHeight = that.$container.height(),
|
||||||
|
contentHeight = that.$content.height(),
|
||||||
|
top = parseInt(that.$content.css('top')) || 0,
|
||||||
|
min = containerHeight - contentHeight + itemHeight,
|
||||||
|
max = 0;
|
||||||
|
top += speed * scrollSpeed * -itemHeight;
|
||||||
|
if (top <= min) {
|
||||||
|
top = min;
|
||||||
|
that.$scrollbars.down.hide().trigger('mouseleave');
|
||||||
|
that.$container.height(containerHeight + itemHeight);
|
||||||
|
that.items[that.items.length - 1].trigger('mouseover');
|
||||||
|
} else if (top >= max - itemHeight) {
|
||||||
|
top = max;
|
||||||
|
that.$scrollbars.up.hide().trigger('mouseleave');
|
||||||
|
that.$container.height(containerHeight + itemHeight);
|
||||||
|
that.items[0].trigger('mouseover');
|
||||||
|
}
|
||||||
|
that.$content.css({
|
||||||
|
top: top + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrollMenuUp() {
|
||||||
|
if (that.$scrollbars.up.is(':visible')) {
|
||||||
|
that.$content.css({
|
||||||
|
top: '0px'
|
||||||
|
});
|
||||||
|
that.$scrollbars.up.hide();
|
||||||
|
if (that.$scrollbars.down.is(':hidden')) {
|
||||||
|
that.$scrollbars.down.show();
|
||||||
|
} else {
|
||||||
|
that.$container.height(that.$container.height() + itemHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectItem(position) {
|
||||||
|
var item;
|
||||||
|
if (self.options.selected > -1) {
|
||||||
|
//Ox.print('s.o.s', self.options.selected, that.items)
|
||||||
|
item = that.items[self.options.selected]
|
||||||
|
item.removeClass('OxSelected');
|
||||||
|
/* disabled
|
||||||
|
that.triggerEvent('deselect', {
|
||||||
|
id: item.options('id'),
|
||||||
|
title: Ox.stripTags(item.options('title')[0])
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if (position > -1) {
|
||||||
|
item = that.items[position];
|
||||||
|
Ox.forEach(that.submenus, function(submenu, id) {
|
||||||
|
if (!submenu.is(':hidden')) {
|
||||||
|
submenu.hideMenu();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
item.options('items').length && that.submenus[item.options('id')].showMenu(); // fixme: do we want to switch to this style?
|
||||||
|
item.addClass('OxSelected');
|
||||||
|
/* disabled
|
||||||
|
that.triggerEvent('select', {
|
||||||
|
id: item.options('id'),
|
||||||
|
title: Ox.stripTags(item.options('title')[0])
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
self.options.selected = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectNextItem() {
|
||||||
|
var offset,
|
||||||
|
selected = self.options.selected;
|
||||||
|
//Ox.print('sNI', selected)
|
||||||
|
if (!isLastEnabledItem()) {
|
||||||
|
if (selected == -1) {
|
||||||
|
scrollMenuUp();
|
||||||
|
} else {
|
||||||
|
that.items[selected].removeClass('OxSelected');
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
selected++;
|
||||||
|
} while (that.items[selected].options('disabled'))
|
||||||
|
selectItem(selected);
|
||||||
|
offset = that.items[selected].offset().top + itemHeight -
|
||||||
|
that.$container.offset().top - that.$container.height();
|
||||||
|
if (offset > 0) {
|
||||||
|
if (that.$scrollbars.up.is(':hidden')) {
|
||||||
|
that.$scrollbars.up.show();
|
||||||
|
that.$container.height(that.$container.height() - itemHeight);
|
||||||
|
offset += itemHeight;
|
||||||
|
}
|
||||||
|
if (selected == that.items.length - 1) {
|
||||||
|
that.$scrollbars.down.hide();
|
||||||
|
that.$container.height(that.$container.height() + itemHeight);
|
||||||
|
} else {
|
||||||
|
that.$content.css({
|
||||||
|
top: ((parseInt(that.$content.css('top')) || 0) - offset) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectPreviousItem() {
|
||||||
|
var offset,
|
||||||
|
selected = self.options.selected;
|
||||||
|
//Ox.print('sPI', selected)
|
||||||
|
if (selected > - 1) {
|
||||||
|
if (!isFirstEnabledItem()) {
|
||||||
|
that.items[selected].removeClass('OxSelected');
|
||||||
|
do {
|
||||||
|
selected--;
|
||||||
|
} while (that.items[selected].options('disabled'))
|
||||||
|
selectItem(selected);
|
||||||
|
}
|
||||||
|
offset = that.items[selected].offset().top - that.$container.offset().top;
|
||||||
|
if (offset < 0) {
|
||||||
|
if (that.$scrollbars.down.is(':hidden')) {
|
||||||
|
that.$scrollbars.down.show();
|
||||||
|
that.$container.height(that.$container.height() - itemHeight);
|
||||||
|
}
|
||||||
|
if (selected == 0) {
|
||||||
|
that.$scrollbars.up.hide();
|
||||||
|
that.$container.height(that.$container.height() + itemHeight);
|
||||||
|
}
|
||||||
|
that.$content.css({
|
||||||
|
top: ((parseInt(that.$content.css('top')) || 0) - offset) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectSubmenu() {
|
||||||
|
//Ox.print('selectSubmenu', self.options.selected)
|
||||||
|
if (self.options.selected > -1) {
|
||||||
|
var submenu = that.submenus[that.items[self.options.selected].options('id')];
|
||||||
|
//Ox.print('submenu', submenu, that.submenus);
|
||||||
|
if (submenu && submenu.hasEnabledItems()) {
|
||||||
|
submenu.gainFocus();
|
||||||
|
submenu.selectFirstItem();
|
||||||
|
} else if (self.options.mainmenu) {
|
||||||
|
self.options.mainmenu.selectNextMenu();
|
||||||
|
}
|
||||||
|
} else if (self.options.mainmenu) {
|
||||||
|
self.options.mainmenu.selectNextMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectSupermenu() {
|
||||||
|
//Ox.print('selectSupermenu', self.options.selected)
|
||||||
|
if (self.options.parent) {
|
||||||
|
self.options.selected > -1 && that.items[self.options.selected].trigger('mouseleave');
|
||||||
|
scrollMenuUp();
|
||||||
|
self.options.parent.gainFocus();
|
||||||
|
} else if (self.options.mainmenu) {
|
||||||
|
self.options.mainmenu.selectPreviousMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'items') {
|
||||||
|
constructItems(value);
|
||||||
|
} else if (key == 'selected') {
|
||||||
|
that.$content.find('.OxSelected').removeClass('OxSelected');
|
||||||
|
selectItem(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.addItem = function(item, position) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.addItemAfter = function(item, id) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.addItemBefore = function(item, id) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.checkItem = function(id) {
|
||||||
|
var item = that.getItem(id);
|
||||||
|
if (item.options('group')) {
|
||||||
|
var position = getItemPositionById(id),
|
||||||
|
toggled = self.optionGroups[item.options('group')].toggle(position);
|
||||||
|
if (toggled.length) {
|
||||||
|
toggled.forEach(function(pos) {
|
||||||
|
that.items[pos].toggleChecked();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item.options({
|
||||||
|
checked: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.getItem = function(id) {
|
||||||
|
//Ox.print('id', id)
|
||||||
|
var ids = id.split('_'),
|
||||||
|
item;
|
||||||
|
if (ids.length == 1) {
|
||||||
|
Ox.forEach(that.items, function(v) {
|
||||||
|
if (v.options('id') == id) {
|
||||||
|
item = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!item) {
|
||||||
|
Ox.forEach(that.submenus, function(submenu) {
|
||||||
|
item = submenu.getItem(id);
|
||||||
|
return !item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item = that.submenus[ids.shift()].getItem(ids.join('_'));
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.getSubmenu = function(id) {
|
||||||
|
var ids = id.split('_'),
|
||||||
|
submenu;
|
||||||
|
if (ids.length == 1) {
|
||||||
|
submenu = that.submenus[id];
|
||||||
|
} else {
|
||||||
|
submenu = that.submenus[ids.shift()].getSubmenu(ids.join('_'));
|
||||||
|
}
|
||||||
|
//Ox.print('getSubmenu', id, submenu);
|
||||||
|
return submenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.hasEnabledItems = function() {
|
||||||
|
var ret = false;
|
||||||
|
Ox.forEach(that.items, function(item) {
|
||||||
|
if (!item.options('disabled')) {
|
||||||
|
return ret = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.hideMenu = function() {
|
||||||
|
if (that.is(':hidden')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ox.forEach(that.submenus, function(submenu) {
|
||||||
|
if (submenu.is(':visible')) {
|
||||||
|
submenu.hideMenu();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
selectItem(-1);
|
||||||
|
scrollMenuUp();
|
||||||
|
that.$scrollbars.up.is(':visible') && that.$scrollbars.up.hide();
|
||||||
|
that.$scrollbars.down.is(':visible') && that.$scrollbars.down.hide();
|
||||||
|
if (self.options.parent) {
|
||||||
|
//self.options.element.removeClass('OxSelected');
|
||||||
|
self.options.parent.options({
|
||||||
|
selected: -1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
that.hide()
|
||||||
|
.loseFocus()
|
||||||
|
.triggerEvent('hide');
|
||||||
|
that.$layer.hide();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.removeItem = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.selectFirstItem = function() {
|
||||||
|
selectNextItem();
|
||||||
|
};
|
||||||
|
|
||||||
|
that.showMenu = function() {
|
||||||
|
if (!that.is(':hidden')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!self.options.parent && !that.$layer.parent().length) {
|
||||||
|
that.$layer.appendTo(Ox.UI.$body);
|
||||||
|
}
|
||||||
|
that.parent().length == 0 && that.appendTo(Ox.UI.$body);
|
||||||
|
that.css({
|
||||||
|
left: '-1000px',
|
||||||
|
top: '-1000px',
|
||||||
|
}).show();
|
||||||
|
var offset = self.options.element.offset(),
|
||||||
|
width = self.options.element.outerWidth(),
|
||||||
|
height = self.options.element.outerHeight(),
|
||||||
|
left = Ox.limit(
|
||||||
|
offset.left + self.options.offset.left + (self.options.side == 'bottom' ? 0 : width),
|
||||||
|
0, Ox.UI.$window.width() - that.width()
|
||||||
|
),
|
||||||
|
top = offset.top + self.options.offset.top + (self.options.side == 'bottom' ? height : 0),
|
||||||
|
menuHeight = that.$content.outerHeight(); // fixme: why is outerHeight 0 when hidden?
|
||||||
|
menuMaxHeight = Math.floor(Ox.UI.$window.height() - top - 16);
|
||||||
|
if (self.options.parent) {
|
||||||
|
if (menuHeight > menuMaxHeight) {
|
||||||
|
top = Ox.limit(top - menuHeight + menuMaxHeight, self.options.parent.offset().top, top);
|
||||||
|
menuMaxHeight = Math.floor(Ox.UI.$window.height() - top - 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
that.css({
|
||||||
|
left: left + 'px',
|
||||||
|
top: top + 'px'
|
||||||
|
});
|
||||||
|
if (menuHeight > menuMaxHeight) {
|
||||||
|
that.$container.height(menuMaxHeight - itemHeight - 8); // margin
|
||||||
|
that.$scrollbars.down.show();
|
||||||
|
} else {
|
||||||
|
that.$container.height(menuHeight);
|
||||||
|
}
|
||||||
|
if (!self.options.parent) {
|
||||||
|
that.gainFocus();
|
||||||
|
}
|
||||||
|
that.$layer.show();
|
||||||
|
return that;
|
||||||
|
//that.triggerEvent('show');
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggleMenu = function() {
|
||||||
|
that.is(':hidden') ? that.showMenu() : that.hideMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
117
source/js/Ox.MenuItem.js
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
Ox.MenuItem = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('tr', self)
|
||||||
|
.defaults({
|
||||||
|
bind: [], // fixme: what's this?
|
||||||
|
checked: null,
|
||||||
|
disabled: false,
|
||||||
|
group: '',
|
||||||
|
icon: '',
|
||||||
|
id: '',
|
||||||
|
items: [],
|
||||||
|
keyboard: '',
|
||||||
|
menu: null, // fixme: is passing the menu to 100s of menu items really memory-neutral?
|
||||||
|
position: 0,
|
||||||
|
title: [],
|
||||||
|
})
|
||||||
|
.options($.extend(options, {
|
||||||
|
keyboard: parseKeyboard(options.keyboard || self.defaults.keyboard),
|
||||||
|
title: Ox.toArray(options.title || self.defaults.title)
|
||||||
|
}))
|
||||||
|
.addClass('OxItem' + (self.options.disabled ? ' OxDisabled' : ''))
|
||||||
|
/*
|
||||||
|
.attr({
|
||||||
|
id: Ox.toCamelCase(self.options.menu.options('id') + '/' + self.options.id)
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
.data('group', self.options.group); // fixme: why?
|
||||||
|
|
||||||
|
if (self.options.group && self.options.checked === null) {
|
||||||
|
self.options.checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct
|
||||||
|
that.append(
|
||||||
|
that.$status = $('<td>', {
|
||||||
|
'class': 'OxCell OxStatus',
|
||||||
|
html: self.options.checked ? Ox.UI.symbols.check : ''
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
that.$icon = $('<td>', {
|
||||||
|
'class': 'OxCell OxIcon'
|
||||||
|
})
|
||||||
|
.append(self.options.icon ?
|
||||||
|
$('<img>', {
|
||||||
|
src: self.options.icon
|
||||||
|
}) : null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
that.$title = $('<td>', {
|
||||||
|
'class': 'OxCell OxTitle',
|
||||||
|
html: self.options.title[0]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
$('<td>', {
|
||||||
|
'class': 'OxCell OxModifiers',
|
||||||
|
html: $.map(self.options.keyboard.modifiers, function(modifier) {
|
||||||
|
return Ox.UI.symbols[modifier];
|
||||||
|
}).join('')
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
$('<td>', {
|
||||||
|
'class': 'OxCell Ox' + (self.options.items.length ? 'Submenu' : 'Key'),
|
||||||
|
html: self.options.items.length ? Ox.UI.symbols.triangle_right :
|
||||||
|
Ox.UI.symbols[self.options.keyboard.key] ||
|
||||||
|
self.options.keyboard.key.toUpperCase()
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
function parseKeyboard(str) {
|
||||||
|
var modifiers = str.split(' '),
|
||||||
|
key = modifiers.pop();
|
||||||
|
return {
|
||||||
|
modifiers: modifiers,
|
||||||
|
key: key
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'checked') {
|
||||||
|
that.$status.html(value ? Ox.UI.symbols.check : '')
|
||||||
|
} else if (key == 'disabled') {
|
||||||
|
that.toggleClass('OxDisabled'); // fixme: this will only work if onChange is only invoked on actual change
|
||||||
|
} else if (key == 'title') {
|
||||||
|
self.options.title = Ox.toArray(value);
|
||||||
|
that.$title.html(self.options.title[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.toggle = function() {
|
||||||
|
// toggle id and title
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggleChecked = function() {
|
||||||
|
that.options({
|
||||||
|
checked: !self.options.checked
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggleDisabled = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggleTitle = function() {
|
||||||
|
//Ox.print('s.o.t', self.options.title)
|
||||||
|
that.options({
|
||||||
|
title: self.options.title.reverse()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
103
source/js/Ox.OptionGroup.js
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
Ox.OptionGroup = function(items, min, max, property) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
to be used by ButtonGroup, CheckboxGroup, Select and Menu
|
||||||
|
*/
|
||||||
|
|
||||||
|
var property = property || 'checked'
|
||||||
|
length = items.length,
|
||||||
|
max = max == -1 ? length : max;
|
||||||
|
|
||||||
|
function getLastBefore(pos) {
|
||||||
|
// returns the position of the last checked item before position pos
|
||||||
|
var last = -1;
|
||||||
|
/*Ox.print(items, items.length, length, $.merge(
|
||||||
|
pos > 0 ? Ox.range(pos - 1, -1, -1) : [],
|
||||||
|
pos < items.length - 1 ? Ox.range(items.length - 1, pos, -1) : []
|
||||||
|
))*/
|
||||||
|
// fixme: why is length not == items.length here?
|
||||||
|
Ox.forEach($.merge(
|
||||||
|
pos > 0 ? Ox.range(pos - 1, -1, -1) : [],
|
||||||
|
pos < items.length - 1 ? Ox.range(items.length - 1, pos, -1) : []
|
||||||
|
), function(v) {
|
||||||
|
//Ox.print(pos, v)
|
||||||
|
if (items[v][property]) {
|
||||||
|
last = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNumber() {
|
||||||
|
// returns the number of checked items
|
||||||
|
var num = 0;
|
||||||
|
items.forEach(function(item) {
|
||||||
|
if (item[property]) {
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
this[property] = function() {
|
||||||
|
// returns an array with the positions of all checked item
|
||||||
|
var checked = [];
|
||||||
|
items.forEach(function(item, i) {
|
||||||
|
if (item[property]) {
|
||||||
|
checked.push(i);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return checked;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.init = function() {
|
||||||
|
var num = getNumber(),
|
||||||
|
count = 0;
|
||||||
|
//if (num < min || num > max) {
|
||||||
|
items.forEach(function(item) {
|
||||||
|
if (Ox.isUndefined(item[property])) {
|
||||||
|
item[property] = false;
|
||||||
|
}
|
||||||
|
if (item[property]) {
|
||||||
|
count++;
|
||||||
|
if (count > max) {
|
||||||
|
item[property] = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (num < min) {
|
||||||
|
item[property] = true;
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//}
|
||||||
|
return items;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.toggle = function(pos) {
|
||||||
|
var last,
|
||||||
|
num = getNumber(),
|
||||||
|
toggled = [];
|
||||||
|
if (!items[pos][property]) { // check
|
||||||
|
if (num >= max) {
|
||||||
|
last = getLastBefore(pos);
|
||||||
|
items[last][property] = false;
|
||||||
|
toggled.push(last);
|
||||||
|
}
|
||||||
|
if (!items[pos][property]) {
|
||||||
|
items[pos][property] = true;
|
||||||
|
toggled.push(pos);
|
||||||
|
}
|
||||||
|
} else { // uncheck
|
||||||
|
if (num > min) {
|
||||||
|
items[pos][property] = false;
|
||||||
|
toggled.push(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toggled;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
|
||||||
|
}
|
8
source/js/Ox.Panel.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
Ox.Panel = function(options, self) {
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.addClass('OxPanel');
|
||||||
|
return that;
|
||||||
|
};
|
92
source/js/Ox.Picker.js
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
Ox.Picker = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
element: null,
|
||||||
|
elementHeight: 128,
|
||||||
|
elementWidth: 256,
|
||||||
|
id: '',
|
||||||
|
overlap: 'none'
|
||||||
|
})
|
||||||
|
.options(options || {});
|
||||||
|
|
||||||
|
self.$selectButton = new Ox.Button({
|
||||||
|
overlap: self.options.overlap,
|
||||||
|
title: 'select',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.click(showMenu)
|
||||||
|
.appendTo(that);
|
||||||
|
|
||||||
|
self.$menu = new Ox.Element('div')
|
||||||
|
.addClass('OxPicker')
|
||||||
|
.css({
|
||||||
|
width: self.options.elementWidth + 'px',
|
||||||
|
height: (self.options.elementHeight + 24) + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
self.options.element
|
||||||
|
.css({
|
||||||
|
width: self.options.elementWidth + 'px',
|
||||||
|
height: self.options.elementHeight + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$menu);
|
||||||
|
|
||||||
|
self.$bar = new Ox.Bar({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
size: 24
|
||||||
|
})
|
||||||
|
.appendTo(self.$menu);
|
||||||
|
|
||||||
|
that.$label = new Ox.Label({
|
||||||
|
width: self.options.elementWidth - 60
|
||||||
|
})
|
||||||
|
.appendTo(self.$bar);
|
||||||
|
|
||||||
|
self.$doneButton = new Ox.Button({
|
||||||
|
title: 'Done',
|
||||||
|
width: 48
|
||||||
|
})
|
||||||
|
.click(hideMenu)
|
||||||
|
.appendTo(self.$bar);
|
||||||
|
|
||||||
|
self.$layer = $('<div>')
|
||||||
|
.addClass('OxLayer')
|
||||||
|
.click(hideMenu);
|
||||||
|
|
||||||
|
function hideMenu() {
|
||||||
|
self.$menu.detach();
|
||||||
|
self.$layer.detach();
|
||||||
|
self.$selectButton
|
||||||
|
.removeClass('OxSelected')
|
||||||
|
.css({
|
||||||
|
MozBorderRadius: '8px',
|
||||||
|
WebkitBorderRadius: '8px'
|
||||||
|
});
|
||||||
|
that.triggerEvent('hide');
|
||||||
|
};
|
||||||
|
|
||||||
|
function showMenu() {
|
||||||
|
var offset = that.offset(),
|
||||||
|
left = offset.left,
|
||||||
|
top = offset.top + 15;
|
||||||
|
self.$selectButton
|
||||||
|
.addClass('OxSelected')
|
||||||
|
.css({
|
||||||
|
MozBorderRadius: '8px 8px 0 0',
|
||||||
|
WebkitBorderRadius: '8px 8px 0 0'
|
||||||
|
});
|
||||||
|
self.$layer.appendTo(Ox.UI.$body);
|
||||||
|
self.$menu
|
||||||
|
.css({
|
||||||
|
left: left + 'px',
|
||||||
|
top: top + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(Ox.UI.$body);
|
||||||
|
that.triggerEvent('show');
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
34
source/js/Ox.PlaceInput.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
Ox.PlaceInput = function(options, self) {
|
||||||
|
|
||||||
|
var self = $.extend(self || {}, {
|
||||||
|
options: $.extend({
|
||||||
|
id: '',
|
||||||
|
value: 'United States'
|
||||||
|
}, options)
|
||||||
|
}),
|
||||||
|
that;
|
||||||
|
|
||||||
|
that = new Ox.FormElementGroup({
|
||||||
|
id: self.options.id,
|
||||||
|
elements: [
|
||||||
|
new Ox.Input({
|
||||||
|
id: 'input',
|
||||||
|
value: self.options.value
|
||||||
|
}),
|
||||||
|
new Ox.PlacePicker({
|
||||||
|
id: 'picker',
|
||||||
|
overlap: 'left',
|
||||||
|
value: self.options.value
|
||||||
|
})
|
||||||
|
],
|
||||||
|
float: 'right'
|
||||||
|
}, self)
|
||||||
|
.bindEvent('change', change);
|
||||||
|
|
||||||
|
function change() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
142
source/js/Ox.PlacePicker.js
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
Ox.PlacePicker = function(options, self) {
|
||||||
|
|
||||||
|
var self = $.extend(self || {}, {
|
||||||
|
options: $.extend({
|
||||||
|
id: '',
|
||||||
|
value: 'United States'
|
||||||
|
}, options)
|
||||||
|
}),
|
||||||
|
that;
|
||||||
|
|
||||||
|
self.$element = new Ox.Element('div')
|
||||||
|
.css({
|
||||||
|
width: '256px',
|
||||||
|
height: '192px'
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
self.$topBar = new Ox.Bar({
|
||||||
|
size: 16
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
MozBorderRadius: '0 8px 0 0',
|
||||||
|
WebkitBorderRadius: '0 8px 0 0'
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
self.$input = new Ox.Input({
|
||||||
|
clear: true,
|
||||||
|
id: self.options.id + 'Input',
|
||||||
|
placeholder: 'Find',
|
||||||
|
width: 256
|
||||||
|
})
|
||||||
|
.bindEvent('submit', findPlace)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
self.$container = new Ox.Element('div')
|
||||||
|
.css({
|
||||||
|
width: '256px',
|
||||||
|
height: '160px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
self.$bottomBar = new Ox.Bar({
|
||||||
|
size: 16
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
self.$range = new Ox.Range({
|
||||||
|
arrows: true,
|
||||||
|
id: self.options.id + 'Range',
|
||||||
|
max: 22,
|
||||||
|
size: 256,
|
||||||
|
thumbSize: 32,
|
||||||
|
thumbValue: true
|
||||||
|
})
|
||||||
|
.bindEvent('change', changeZoom)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
self.$input.$element.children('input[type=text]').css({
|
||||||
|
width: '230px',
|
||||||
|
paddingLeft: '2px',
|
||||||
|
MozBorderRadius: '0 8px 8px 0',
|
||||||
|
WebkitBorderRadius: '0 8px 8px 0'
|
||||||
|
});
|
||||||
|
self.$input.$element.children('input[type=image]').css({
|
||||||
|
MozBorderRadius: '0 8px 0 0',
|
||||||
|
WebkitBorderRadius: '0 8px 0 0'
|
||||||
|
});
|
||||||
|
self.$range.$element.children('input').css({
|
||||||
|
MozBorderRadius: 0,
|
||||||
|
WebkitBorderRadius: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
that = new Ox.Picker({
|
||||||
|
element: self.$element,
|
||||||
|
elementHeight: 192,
|
||||||
|
elementWidth: 256,
|
||||||
|
id: self.options.id,
|
||||||
|
overlap: self.options.overlap,
|
||||||
|
value: self.options.value
|
||||||
|
}, self)
|
||||||
|
.bindEvent('show', showPicker);
|
||||||
|
|
||||||
|
that.$label.bind('click', clickLabel)
|
||||||
|
|
||||||
|
self.map = false;
|
||||||
|
|
||||||
|
function changeZoom(event, data) {
|
||||||
|
//Ox.print('changeZoom')
|
||||||
|
self.$map.zoom(data.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickLabel() {
|
||||||
|
var name = that.$label.html();
|
||||||
|
if (name) {
|
||||||
|
self.$input.options({
|
||||||
|
value: name
|
||||||
|
})
|
||||||
|
.triggerEvent('submit', {
|
||||||
|
value: name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findPlace(event, data) {
|
||||||
|
//Ox.print('findPlace', data);
|
||||||
|
self.$map.find(data.value, function(place) {
|
||||||
|
place && that.$label.html(place.geoname);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSelect(event, data) {
|
||||||
|
that.$label.html(data.geoname);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onZoom(event, data) {
|
||||||
|
self.$range.options({
|
||||||
|
value: data.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showPicker() {
|
||||||
|
if (!self.map) {
|
||||||
|
self.$map = new Ox.Map({
|
||||||
|
id: self.options.id + 'Map',
|
||||||
|
places: [self.options.value]
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '256px',
|
||||||
|
height: '160px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
select: onSelect,
|
||||||
|
zoom: onZoom
|
||||||
|
})
|
||||||
|
.appendTo(self.$container);
|
||||||
|
self.map = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
4
source/js/Ox.Progressbar.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
Ox.Progressbar
|
||||||
|
*/
|
||||||
|
|
248
source/js/Ox.Range.js
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
Ox.Range = function(options, self) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
options
|
||||||
|
arrows boolean if true, show arrows
|
||||||
|
arrowStep number step when clicking arrows
|
||||||
|
arrowSymbols array arrow symbols, like ['minus', 'plus']
|
||||||
|
max number maximum value
|
||||||
|
min number minimum value
|
||||||
|
orientation string 'horizontal' or 'vertical'
|
||||||
|
step number step between values
|
||||||
|
size number width or height, in px
|
||||||
|
thumbSize number minimum width or height of thumb, in px
|
||||||
|
thumbValue boolean if true, display value on thumb
|
||||||
|
trackGradient array colors
|
||||||
|
trackImages string or array one or multiple track background image URLs
|
||||||
|
trackStep number 0 (scroll here) or step when clicking track
|
||||||
|
value number initial value
|
||||||
|
valueNames array value names to display on thumb
|
||||||
|
*/
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
arrows: false,
|
||||||
|
arrowStep: 1,
|
||||||
|
arrowSymbols: ['left', 'right'],
|
||||||
|
max: 100,
|
||||||
|
min: 0,
|
||||||
|
orientation: 'horizontal',
|
||||||
|
step: 1,
|
||||||
|
size: 128,
|
||||||
|
thumbSize: 16,
|
||||||
|
thumbValue: false,
|
||||||
|
trackColors: [],
|
||||||
|
trackImages: [],
|
||||||
|
trackStep: 0,
|
||||||
|
value: 0,
|
||||||
|
valueNames: null,
|
||||||
|
})
|
||||||
|
.options($.extend(options, {
|
||||||
|
arrowStep: options.arrowStep ?
|
||||||
|
options.arrowStep : options.step,
|
||||||
|
trackImages: $.makeArray(options.trackImages || [])
|
||||||
|
}))
|
||||||
|
.addClass('OxRange')
|
||||||
|
.css({
|
||||||
|
width: self.options.size + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
trackColors: self.options.trackColors.length,
|
||||||
|
trackImages: self.options.trackImages.length,
|
||||||
|
values: (self.options.max - self.options.min + self.options.step) /
|
||||||
|
self.options.step
|
||||||
|
});
|
||||||
|
setSizes();
|
||||||
|
|
||||||
|
if (self.options.arrows) {
|
||||||
|
self.$arrows = [];
|
||||||
|
Ox.range(0, 2).forEach(function(i) {
|
||||||
|
self.$arrows[i] = new Ox.Button({
|
||||||
|
overlap: i == 0 ? 'right' : 'left',
|
||||||
|
title: self.options.arrowSymbols[i],
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.addClass('OxArrow')
|
||||||
|
.bindEvent({
|
||||||
|
mousedown: function(event, e) {
|
||||||
|
clickArrow(e, i, true);
|
||||||
|
},
|
||||||
|
mouserepeat: function(event, e) {
|
||||||
|
clickArrow(e, i, false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(that.$element);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.$track = new Ox.Element()
|
||||||
|
.addClass('OxTrack')
|
||||||
|
.css($.extend({
|
||||||
|
width: (self.trackSize - 2) + 'px'
|
||||||
|
}, self.trackImages == 1 ? {
|
||||||
|
background: 'rgb(0, 0, 0)'
|
||||||
|
} : {}))
|
||||||
|
.bindEvent({
|
||||||
|
mousedown: clickTrack,
|
||||||
|
drag: dragTrack
|
||||||
|
})
|
||||||
|
.appendTo(that.$element);
|
||||||
|
|
||||||
|
self.trackColors && setTrackColors();
|
||||||
|
|
||||||
|
if (self.trackImages) {
|
||||||
|
self.$trackImages = $('<div>')
|
||||||
|
.css({
|
||||||
|
width: self.trackSize + 'px',
|
||||||
|
marginRight: (-self.trackSize - 1) + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$track.$element);
|
||||||
|
self.options.trackImages.forEach(function(v, i) {
|
||||||
|
//Ox.print(self.trackImageWidths[i])
|
||||||
|
$('<img>')
|
||||||
|
.attr({
|
||||||
|
src: v
|
||||||
|
})
|
||||||
|
.addClass(i == 0 ? 'OxFirstChild' : '')
|
||||||
|
.addClass(i == self.trackImages - 1 ? 'OxLastChild' : '')
|
||||||
|
.css({
|
||||||
|
width: self.trackImageWidths[i] + 'px'
|
||||||
|
})
|
||||||
|
.mousedown(function(e) {
|
||||||
|
e.preventDefault(); // prevent drag
|
||||||
|
})
|
||||||
|
.appendTo(self.$trackImages);
|
||||||
|
//left += self.trackImageWidths[i];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.$thumb = Ox.Button({
|
||||||
|
id: self.options.id + 'Thumb',
|
||||||
|
title: self.options.thumbValue ? (self.options.valueNames ?
|
||||||
|
self.options.valueNames[self.options.value] :
|
||||||
|
self.options.value) : '',
|
||||||
|
width: self.thumbSize
|
||||||
|
})
|
||||||
|
.addClass('OxThumb')
|
||||||
|
/*
|
||||||
|
.css({
|
||||||
|
border: '1px solid rgb(255, 255, 255)',
|
||||||
|
background: 'rgba(0, 0, 0, 0)'
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
.appendTo(self.$track);
|
||||||
|
|
||||||
|
setThumb();
|
||||||
|
|
||||||
|
function clickArrow(e, i, animate) {
|
||||||
|
// fixme: shift doesn't work, see menu scrolling
|
||||||
|
setValue(self.options.value + self.options.arrowStep * (i == 0 ? -1 : 1) * (e.shiftKey ? 2 : 1), animate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickTrack(event, e) {
|
||||||
|
// fixme: thumb ends up a bit too far on the right
|
||||||
|
var isThumb = $(e.target).hasClass('OxThumb');
|
||||||
|
self.drag = {
|
||||||
|
left: self.$track.offset().left,
|
||||||
|
offset: isThumb ? e.clientX - self.$thumb.offset().left - 8 /*self.thumbSize / 2*/ : 0
|
||||||
|
};
|
||||||
|
setValue(getVal(e.clientX - self.drag.left - self.drag.offset), !isThumb);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragTrack(event, e) {
|
||||||
|
setValue(getVal(e.clientX - self.drag.left - self.drag.offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPx(val) {
|
||||||
|
var pxPerVal = (self.trackSize - self.thumbSize) /
|
||||||
|
(self.options.max - self.options.min);
|
||||||
|
return Math.ceil((val - self.options.min) * pxPerVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
function getTime(oldValue, newValue) {
|
||||||
|
return self.animationTime * Math.abs(oldValue - newValue) / (self.options.max - self.options.min);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getVal(px) {
|
||||||
|
var px = self.trackSize / self.values >= 16 ? px : px - 8,
|
||||||
|
valPerPx = (self.options.max - self.options.min) /
|
||||||
|
(self.trackSize - self.thumbSize);
|
||||||
|
return Ox.limit(self.options.min +
|
||||||
|
Math.floor(px * valPerPx / self.options.step) * self.options.step,
|
||||||
|
self.options.min, self.options.max);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSizes() {
|
||||||
|
self.trackSize = self.options.size - self.options.arrows * 32;
|
||||||
|
self.thumbSize = Math.max(self.trackSize / self.values, self.options.thumbSize);
|
||||||
|
self.trackImageWidths = self.trackImages == 1 ? [self.trackSize - 16] :
|
||||||
|
Ox.divideInt(self.trackSize - 2, self.trackImages);
|
||||||
|
self.trackColorsStart = self.thumbSize / 2 / self.options.size;
|
||||||
|
self.trackColorsStep = (self.options.size - self.thumbSize) /
|
||||||
|
(self.trackColors - 1) / self.options.size;
|
||||||
|
self.$track && self.$track.css({
|
||||||
|
width: (self.trackSize - 2) + 'px'
|
||||||
|
});
|
||||||
|
self.$thumb && self.$thumb.options({
|
||||||
|
width: self.thumbSize
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setThumb(animate) {
|
||||||
|
self.$thumb.stop().animate({
|
||||||
|
marginLeft: (getPx(self.options.value) - 1) + 'px',
|
||||||
|
//width: self.thumbSize + 'px'
|
||||||
|
}, animate ? 200 : 0, function() {
|
||||||
|
if (self.options.thumbValue) {
|
||||||
|
self.$thumb.options({
|
||||||
|
title: self.options.valueNames ?
|
||||||
|
self.options.valueNames[self.options.value] :
|
||||||
|
self.options.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTrackColors() {
|
||||||
|
self.$track.css({
|
||||||
|
backgroundImage: $.browser.mozilla ?
|
||||||
|
('-moz-linear-gradient(left, ' +
|
||||||
|
self.options.trackColors[0] + ' 0%, ' + $.map(self.options.trackColors, function(v, i) {
|
||||||
|
return v + ' ' + ((self.trackColorsStart + self.trackColorsStep * i) * 100) + '%';
|
||||||
|
}).join(', ') + ', ' + self.options.trackColors[self.trackColors - 1] + ' 100%)') :
|
||||||
|
('-webkit-gradient(linear, left top, right top, color-stop(0, ' +
|
||||||
|
self.options.trackColors[0] + '), ' + $.map(self.options.trackColors, function(v, i) {
|
||||||
|
return 'color-stop(' + (self.trackColorsStart + self.trackColorsStep * i) + ', ' + v + ')';
|
||||||
|
}).join(', ') + ', color-stop(1, ' + self.options.trackColors[self.trackColors - 1] + '))')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setValue(value, animate) {
|
||||||
|
var value = Ox.limit(value, self.options.min, self.options.max);
|
||||||
|
if (value != self.options.value) {
|
||||||
|
//time = getTime(self.options.value, value);
|
||||||
|
self.options.value = value;
|
||||||
|
setThumb(animate);
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
value: value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'size') {
|
||||||
|
setSizes();
|
||||||
|
} else if (key == 'trackColors') {
|
||||||
|
setTrackColors();
|
||||||
|
} else if (key == 'value') {
|
||||||
|
setThumb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
221
source/js/Ox.Request.js
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
Ox.Request = function(options) {
|
||||||
|
|
||||||
|
/***
|
||||||
|
Ox.Request
|
||||||
|
Basic request handler
|
||||||
|
Options
|
||||||
|
timeout
|
||||||
|
Methods
|
||||||
|
cancel() cancel request
|
||||||
|
clearCache() clear cache
|
||||||
|
options() get or set options
|
||||||
|
requests() return number of active requests
|
||||||
|
send() send request
|
||||||
|
***/
|
||||||
|
|
||||||
|
var cache = {},
|
||||||
|
//dfd = $.Deferred(),
|
||||||
|
pending = {},
|
||||||
|
requests = {},
|
||||||
|
self = {
|
||||||
|
options: $.extend({
|
||||||
|
timeout: 60000,
|
||||||
|
type: 'POST',
|
||||||
|
url: '/api/'
|
||||||
|
}, options)
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
cancel: function() {
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
// cancel all requests
|
||||||
|
requests = {};
|
||||||
|
} else if (Ox.isFunction(arguments[0])) {
|
||||||
|
// cancel with function
|
||||||
|
Ox.forEach(requests, function(req, id) {
|
||||||
|
if (arguments[0](req)) {
|
||||||
|
delete requests[id];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// cancel by id
|
||||||
|
delete requests[arguments[0]];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clearCache: function() {
|
||||||
|
cache = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
options: function(options) {
|
||||||
|
return Ox.getset(self.options, options, $.noop(), this);
|
||||||
|
},
|
||||||
|
|
||||||
|
requests: function() {
|
||||||
|
return Ox.len(requests);
|
||||||
|
},
|
||||||
|
|
||||||
|
send: function(options) {
|
||||||
|
|
||||||
|
var options = $.extend({
|
||||||
|
age: -1,
|
||||||
|
callback: null,
|
||||||
|
id: Ox.uid(),
|
||||||
|
timeout: self.options.timeout,
|
||||||
|
type: self.options.type,
|
||||||
|
url: self.options.url
|
||||||
|
}, options),
|
||||||
|
req = JSON.stringify({
|
||||||
|
url: options.url,
|
||||||
|
data: options.data
|
||||||
|
});
|
||||||
|
|
||||||
|
if (pending[options.id]) {
|
||||||
|
setTimeout(function() {
|
||||||
|
Ox.Request.send(options);
|
||||||
|
}, 0);
|
||||||
|
} else {
|
||||||
|
requests[options.id] = {
|
||||||
|
url: options.url,
|
||||||
|
data: options.data
|
||||||
|
};
|
||||||
|
if (cache[req] && (options.age == -1 || options.age > Ox.getTime() - cache[req].time)) {
|
||||||
|
setTimeout(function() {
|
||||||
|
callback && callback(cache[req].data);
|
||||||
|
}, 0);
|
||||||
|
} else {
|
||||||
|
pending[options.id] = true;
|
||||||
|
$.ajax({
|
||||||
|
data: options.data,
|
||||||
|
dataType: 'json',
|
||||||
|
error: error,
|
||||||
|
success: success,
|
||||||
|
timeout: options.timeout,
|
||||||
|
type: options.type,
|
||||||
|
url: options.url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function callback(data) {
|
||||||
|
delete requests[options.id];
|
||||||
|
//Ox.len(requests) == 0 && $body.trigger('requestStop');
|
||||||
|
options.callback && options.callback(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function debug(request) {
|
||||||
|
var $iframe = $('<iframe>')
|
||||||
|
.css({ // fixme: should go into a class
|
||||||
|
width: 768,
|
||||||
|
height: 384
|
||||||
|
}),
|
||||||
|
$dialog = new Ox.Dialog({
|
||||||
|
title: 'Application Error',
|
||||||
|
buttons: [
|
||||||
|
new Ox.Button({
|
||||||
|
title: 'Close'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
$dialog.close();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
content: $iframe,
|
||||||
|
width: 800,
|
||||||
|
height: 400
|
||||||
|
})
|
||||||
|
.open(),
|
||||||
|
iframe = $iframe[0].contentDocument || $iframe[0].contentWindow.document;
|
||||||
|
iframe.open();
|
||||||
|
iframe.write(request.responseText);
|
||||||
|
iframe.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function error(request, status, error) {
|
||||||
|
var data;
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
data = arguments[0]
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
data = JSON.parse(request.responseText);
|
||||||
|
} catch (err) {
|
||||||
|
try {
|
||||||
|
data = {
|
||||||
|
status: {
|
||||||
|
code: request.status,
|
||||||
|
text: request.statusText
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
data = {
|
||||||
|
status: {
|
||||||
|
code: '500',
|
||||||
|
text: 'Unknown Error'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data.status.code < 500) {
|
||||||
|
callback(data);
|
||||||
|
} else {
|
||||||
|
var $dialog = new Ox.Dialog({
|
||||||
|
title: 'Application Error',
|
||||||
|
buttons: [
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'details',
|
||||||
|
title: 'Details'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
$dialog.close(function() {
|
||||||
|
debug(request);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'close',
|
||||||
|
title: 'Close'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
$dialog.close();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
content: 'Sorry, we have encountered an application error while handling your request. To help us find out what went wrong, you may want to report this error to an administrator. Otherwise, please try again later.',
|
||||||
|
keys: {enter: 'close', escape: 'close'},
|
||||||
|
width: 400,
|
||||||
|
height: 200
|
||||||
|
})
|
||||||
|
.open();
|
||||||
|
// fixme: change this to Send / Don't Send
|
||||||
|
/*Ox.print({
|
||||||
|
request: request,
|
||||||
|
status: status,
|
||||||
|
error: error
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
pending[options.id] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function success(data) {
|
||||||
|
pending[options.id] = false;
|
||||||
|
cache[req] = {
|
||||||
|
data: data,
|
||||||
|
time: Ox.getTime()
|
||||||
|
};
|
||||||
|
callback(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return dfd.promise();
|
||||||
|
|
||||||
|
return options.id;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}();
|
143
source/js/Ox.Resizebar.js
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
Ox.Resizebar = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
collapsed: false,
|
||||||
|
collapsible: true,
|
||||||
|
edge: 'left',
|
||||||
|
elements: [],
|
||||||
|
orientation: 'horizontal',
|
||||||
|
parent: null,
|
||||||
|
resizable: true,
|
||||||
|
resize: [],
|
||||||
|
size: 0
|
||||||
|
})
|
||||||
|
.options(options || {}) // fixme: options function should be able to handle undefined, no need for || {}
|
||||||
|
.addClass('OxResizebar Ox' + Ox.toTitleCase(self.options.orientation))
|
||||||
|
/*
|
||||||
|
.attr({
|
||||||
|
draggable: 'true'
|
||||||
|
})
|
||||||
|
.bind('dragstart', function(e) {
|
||||||
|
// e.originalEvent.dataTransfer.setDragImage($('<div>')[0], 0, 0);
|
||||||
|
})
|
||||||
|
.bind('drag', function(e) {
|
||||||
|
Ox.print('dragging', e)
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
.bindEvent({
|
||||||
|
anyclick: toggle,
|
||||||
|
dragstart: dragstart,
|
||||||
|
drag: drag,
|
||||||
|
dragend: dragend
|
||||||
|
})
|
||||||
|
.append($('<div>').addClass('OxSpace'))
|
||||||
|
.append($('<div>').addClass('OxLine'))
|
||||||
|
.append($('<div>').addClass('OxSpace'));
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
clientXY: self.options.orientation == 'horizontal' ? 'clientY' : 'clientX',
|
||||||
|
dimensions: Ox.UI.DIMENSIONS[self.options.orientation], // fixme: should orientation be the opposite orientation here?
|
||||||
|
edges: Ox.UI.EDGES[self.options.orientation],
|
||||||
|
leftOrTop: self.options.edge == 'left' || self.options.edge == 'top'
|
||||||
|
});
|
||||||
|
|
||||||
|
function dragstart(event, e) {
|
||||||
|
if (self.options.resizable && !self.options.collapsed) {
|
||||||
|
Ox.print('DRAGSTART')
|
||||||
|
self.drag = {
|
||||||
|
startPos: e[self.clientXY],
|
||||||
|
startSize: self.options.size
|
||||||
|
}
|
||||||
|
} else { Ox.print('NO DRAGSTART r !c', self.options.resizable, !self.options.collapsed) }
|
||||||
|
}
|
||||||
|
|
||||||
|
function drag(event, e) {
|
||||||
|
if (self.options.resizable && !self.options.collapsed) {
|
||||||
|
var d = e[self.clientXY] - self.drag.startPos,
|
||||||
|
size = self.options.size;
|
||||||
|
self.options.size = Ox.limit(
|
||||||
|
self.drag.startSize + d * (self.leftOrTop ? 1 : -1),
|
||||||
|
self.options.resize[0],
|
||||||
|
self.options.resize[self.options.resize.length - 1]
|
||||||
|
);
|
||||||
|
Ox.forEach(self.options.resize, function(v) {
|
||||||
|
if (self.options.size >= v - 8 && self.options.size <= v + 8) {
|
||||||
|
self.options.size = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (self.options.size != size) {
|
||||||
|
that.css(self.edges[self.leftOrTop ? 2 : 3], self.options.size + 'px');
|
||||||
|
// fixme: send {size: x}, not x
|
||||||
|
if (self.leftOrTop) {
|
||||||
|
self.options.elements[0]
|
||||||
|
.css(self.dimensions[1], self.options.size + 'px')
|
||||||
|
self.options.elements[1]
|
||||||
|
.css(self.edges[2], (self.options.size + 1) + 'px')
|
||||||
|
} else {
|
||||||
|
self.options.elements[0]
|
||||||
|
.css(self.edges[3], (self.options.size + 1) + 'px')
|
||||||
|
self.options.elements[1]
|
||||||
|
.css(self.dimensions[1], self.options.size + 'px')
|
||||||
|
}
|
||||||
|
triggerEvents('resize');
|
||||||
|
self.options.parent.updateSize(self.leftOrTop ? 0 : 1, self.options.size); // fixme: listen to event instead?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragend() {
|
||||||
|
if (self.options.resizable && !self.options.collapsed) {
|
||||||
|
self.options.size != self.drag.startSize && triggerEvents('resizeend');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
if (self.options.collapsible) {
|
||||||
|
// fixme: silly, pass a parameter
|
||||||
|
self.options.parent.toggle(
|
||||||
|
self.leftOrTop ? 0 :
|
||||||
|
self.options.parent.options('elements').length - 1
|
||||||
|
);
|
||||||
|
self.options.collapsed = !self.options.collapsed;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
//Ox.print('toggle');
|
||||||
|
if (Ox.isUndefined(self.options.position)) {
|
||||||
|
self.options.position = parseInt(self.options.parent.css(self.options.edge)) +
|
||||||
|
(self.options.collapsed ? self.options.size : 0);
|
||||||
|
}
|
||||||
|
var size = self.options.position -
|
||||||
|
(self.options.collapsed ? 0 : self.options.size),
|
||||||
|
animate = {};
|
||||||
|
//Ox.print('s.o.e', self.options.edge);
|
||||||
|
animate[self.options.edge] = size;
|
||||||
|
self.options.parent.animate(animate, 200, function() {
|
||||||
|
var i = (self.options.edge == 'left' || self.options.edge == 'top') ? 0 : 1;
|
||||||
|
self.options.collapsed = !self.options.collapsed;
|
||||||
|
Ox.Event.trigger(self.ids[i], 'toggle', self.options.collapsed);
|
||||||
|
Ox.Event.trigger(self.ids[1 - i], 'resize', self.options.elements[1 - i][self.dimensions[1]]());
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerEvents(event) {
|
||||||
|
self.options.elements[0].triggerEvent(event,
|
||||||
|
self.leftOrTop ?
|
||||||
|
self.options.size :
|
||||||
|
self.options.elements[0][self.dimensions[1]]()
|
||||||
|
);
|
||||||
|
self.options.elements[1].triggerEvent(event,
|
||||||
|
self.leftOrTop ?
|
||||||
|
self.options.elements[1][self.dimensions[1]]() :
|
||||||
|
self.options.size
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
162
source/js/Ox.Select.js
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
Ox.Select = function(options, self) {
|
||||||
|
|
||||||
|
// fixme: selected item needs attribute "checked", not "selected" ... that's strange
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self) // fixme: do we use 'div', or {}, or '', by default?
|
||||||
|
.defaults({
|
||||||
|
id: '',
|
||||||
|
items: [],
|
||||||
|
max: 1,
|
||||||
|
min: 1,
|
||||||
|
overlap: 'none', // can be none, left or right
|
||||||
|
selectable: true,
|
||||||
|
size: 'medium',
|
||||||
|
title: '',
|
||||||
|
type: 'text', // can be 'text' or 'image'
|
||||||
|
width: 'auto'
|
||||||
|
})
|
||||||
|
// fixme: make default selection restorable
|
||||||
|
// or allow for extra action items below options
|
||||||
|
.options(options)
|
||||||
|
.addClass(
|
||||||
|
'OxSelect Ox' + Ox.toTitleCase(self.options.size) +
|
||||||
|
(self.options.overlap == 'none' ? '' : ' OxOverlap' +
|
||||||
|
Ox.toTitleCase(self.options.overlap))
|
||||||
|
)
|
||||||
|
.css(self.options.width == 'auto' ? {} : {
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
key_escape: loseFocus,
|
||||||
|
key_down: showMenu
|
||||||
|
});
|
||||||
|
|
||||||
|
Ox.print('Ox.Select', self.options)
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
buttonId: self.options.id + 'Button',
|
||||||
|
groupId: self.options.id + 'Group',
|
||||||
|
menuId: self.options.id + 'Menu'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (self.options.selectable) {
|
||||||
|
self.optionGroup = new Ox.OptionGroup(
|
||||||
|
self.options.items,
|
||||||
|
self.options.min,
|
||||||
|
self.options.max
|
||||||
|
);
|
||||||
|
self.options.items = self.optionGroup.init();
|
||||||
|
self.checked = self.optionGroup.checked();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.options.type == 'text') {
|
||||||
|
self.$title = $('<div>')
|
||||||
|
.addClass('OxTitle')
|
||||||
|
.css({
|
||||||
|
width: (self.options.width - 22) + 'px'
|
||||||
|
})
|
||||||
|
.html(
|
||||||
|
self.options.title ? self.options.title :
|
||||||
|
self.options.items[self.checked[0]].title
|
||||||
|
)
|
||||||
|
.click(showMenu)
|
||||||
|
.appendTo(that.$element);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.$button = new Ox.Button({
|
||||||
|
id: self.buttonId,
|
||||||
|
style: 'symbol',
|
||||||
|
title: 'select',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent('click', showMenu)
|
||||||
|
.appendTo(that);
|
||||||
|
|
||||||
|
self.$menu = new Ox.Menu({
|
||||||
|
element: self.$title || self.$button,
|
||||||
|
id: self.menuId,
|
||||||
|
items: [self.options.selectable ? {
|
||||||
|
group: self.groupId,
|
||||||
|
items: self.options.items,
|
||||||
|
max: self.options.max,
|
||||||
|
min: self.options.min
|
||||||
|
} : self.options.items],
|
||||||
|
side: 'bottom',
|
||||||
|
size: self.options.size
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: changeMenu,
|
||||||
|
click: clickMenu,
|
||||||
|
hide: hideMenu
|
||||||
|
});
|
||||||
|
|
||||||
|
self.options.type == 'image' && self.$menu.addClass('OxRight');
|
||||||
|
|
||||||
|
function clickMenu(event, data) {
|
||||||
|
that.triggerEvent('click', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeMenu(event, data) {
|
||||||
|
//Ox.print('clickMenu: ', self.options.id, data)
|
||||||
|
self.checked = self.optionGroup.checked();
|
||||||
|
self.$title && self.$title.html(
|
||||||
|
self.options.title ? self.options.title :
|
||||||
|
data.checked[0].title
|
||||||
|
);
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
selected: data.checked
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideMenu() {
|
||||||
|
//Ox.print('%% hideMenu that', that, 'self', self)
|
||||||
|
that.removeClass('OxSelected');
|
||||||
|
// self.$button.removeClass('OxSelected');
|
||||||
|
//Ox.print('%% hideMenu end')
|
||||||
|
}
|
||||||
|
|
||||||
|
function loseFocus() {
|
||||||
|
that.loseFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMenu() {
|
||||||
|
that.gainFocus();
|
||||||
|
that.addClass('OxSelected');
|
||||||
|
self.$menu.showMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.selected = function() {
|
||||||
|
return $.map(/*self.checked*/self.optionGroup.checked(), function(v) {
|
||||||
|
return {
|
||||||
|
id: self.options.items[v].id,
|
||||||
|
title: self.options.items[v].title
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
that.selectItem = function(id) {
|
||||||
|
//Ox.print('selectItem', id, Ox.getObjectById(self.options.items, id).title)
|
||||||
|
self.options.type == 'text' && self.$title.html(
|
||||||
|
Ox.getObjectById(self.options.items, id).title[0] // fixme: title should not have become an array
|
||||||
|
);
|
||||||
|
self.$menu.checkItem(id);
|
||||||
|
self.checked = self.optionGroup.checked();
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
that.width = function(val) {
|
||||||
|
// fixme: silly hack, and won't work for css() ... remove!
|
||||||
|
that.$element.width(val + 16);
|
||||||
|
that.$button.width(val);
|
||||||
|
//that.$symbol.width(val);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
191
source/js/Ox.SmallTimeline.js
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
Ox.SmallTimeline = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
duration: 0,
|
||||||
|
find: '',
|
||||||
|
matches: [],
|
||||||
|
points: [0, 0],
|
||||||
|
position: 0,
|
||||||
|
subtitles: [],
|
||||||
|
videoId: '',
|
||||||
|
width: 0
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxTimelineSmall')
|
||||||
|
.mousedown(mousedown)
|
||||||
|
.mouseleave(mouseleave)
|
||||||
|
.mousemove(mousemove)
|
||||||
|
.bindEvent({
|
||||||
|
drag: function(event, e) {
|
||||||
|
mousedown(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
$images: [],
|
||||||
|
$markerPoint: [],
|
||||||
|
$subtitles: [],
|
||||||
|
$tooltip: new Ox.Tooltip({
|
||||||
|
animate: false
|
||||||
|
}).css({
|
||||||
|
textAlign: 'center'
|
||||||
|
}),
|
||||||
|
hasSubtitles: self.options.subtitles.length,
|
||||||
|
height: 16,
|
||||||
|
margin: 8
|
||||||
|
});
|
||||||
|
|
||||||
|
that.css({
|
||||||
|
width: (self.options.width + self.margin) + 'px',
|
||||||
|
height: (self.height + self.margin) + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$line = $('<img>')
|
||||||
|
.addClass('OxTimelineSmallImage')
|
||||||
|
.attr({
|
||||||
|
src: '/' + self.options.videoId + '/timelines/timeline.16.0.png'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
left: '4px',
|
||||||
|
top: '4px',
|
||||||
|
width: self.options.width,
|
||||||
|
height: '16px'
|
||||||
|
})
|
||||||
|
.appendTo(that.$element);
|
||||||
|
|
||||||
|
self.$markerPosition = $('<img>')
|
||||||
|
.addClass('OxMarkerPosition')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/ox.ui/videoMarkerPlay.png'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
width: '9px',
|
||||||
|
height: '5px',
|
||||||
|
zIndex: 10
|
||||||
|
})
|
||||||
|
.appendTo(that.$element);
|
||||||
|
|
||||||
|
setPosition();
|
||||||
|
|
||||||
|
['in', 'out'].forEach(function(v, i) {
|
||||||
|
var titleCase = Ox.toTitleCase(v);
|
||||||
|
self.$markerPoint[i] = $('<img>')
|
||||||
|
.addClass('OxMarkerPoint' + titleCase)
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/ox.ui/videoMarker' + titleCase + '.png'
|
||||||
|
})
|
||||||
|
.appendTo(that.$element);
|
||||||
|
setMarkerPoint(i);
|
||||||
|
});
|
||||||
|
|
||||||
|
function getPosition(e) {
|
||||||
|
return e.offsetX / self.options.width * self.options.duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubtitle(position) {
|
||||||
|
var subtitle = null;
|
||||||
|
Ox.forEach(self.options.subtitles, function(v) {
|
||||||
|
if (v['in'] <= position && v['out'] >= position) {
|
||||||
|
subtitle = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return subtitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousedown(e) {
|
||||||
|
var $target = $(e.target);
|
||||||
|
if (
|
||||||
|
$target.hasClass('OxTimelineSmallImage') ||
|
||||||
|
$target.hasClass('OxTimelineSmallSubtitles')
|
||||||
|
) {
|
||||||
|
self.options.position = getPosition(e);
|
||||||
|
setPosition();
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseleave(e) {
|
||||||
|
self.$tooltip.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousemove(e) {
|
||||||
|
var $target = $(e.target),
|
||||||
|
position,
|
||||||
|
subtitle;
|
||||||
|
if (
|
||||||
|
$target.hasClass('OxTimelineSmallImage') ||
|
||||||
|
$target.hasClass('OxTimelineSmallSubtitles')
|
||||||
|
) {
|
||||||
|
position = getPosition(e),
|
||||||
|
subtitle = getSubtitle(position);
|
||||||
|
self.$tooltip.options({
|
||||||
|
title: subtitle ?
|
||||||
|
'<span class=\'OxBright\'>' +
|
||||||
|
Ox.highlight(subtitle.value, self.options.find).replace(/\n/g, '<br/>') + '</span><br/>' +
|
||||||
|
Ox.formatDuration(subtitle['in'], 3) + ' - ' + Ox.formatDuration(subtitle['out'], 3) :
|
||||||
|
Ox.formatDuration(position, 3)
|
||||||
|
})
|
||||||
|
.show(e.clientX, e.clientY);
|
||||||
|
} else {
|
||||||
|
self.$tooltip.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMarker() {
|
||||||
|
self.$markerPosition
|
||||||
|
.css({
|
||||||
|
left: parseInt(
|
||||||
|
self.options.position / self.options.duration * self.options.width
|
||||||
|
) + 'px',
|
||||||
|
top: '2px',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMarkerPoint(i) {
|
||||||
|
var position = self.options.points[i];
|
||||||
|
self.$markerPoint[i]
|
||||||
|
.css({
|
||||||
|
left: (position % self.options.width) + 'px',
|
||||||
|
top: (parseInt(position / self.options.width) * (self.height + self.margin) + 16) + 'px',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPosition() {
|
||||||
|
self.options.position = Ox.limit(self.options.position, 0, self.options.duration);
|
||||||
|
setMarker();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWidth() {
|
||||||
|
self.$line.css({
|
||||||
|
width: self.options.width + 'px',
|
||||||
|
});
|
||||||
|
setMarker();
|
||||||
|
setMarkerPoint(0);
|
||||||
|
setMarkerPoint(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
//Ox.print('onChange:', key, value)
|
||||||
|
if (key == 'points') {
|
||||||
|
//Ox.print('key', key, 'value', value)
|
||||||
|
setMarkerPoint(0);
|
||||||
|
setMarkerPoint(1);
|
||||||
|
} else if (key == 'position') {
|
||||||
|
setPosition();
|
||||||
|
} else if (key == 'width') {
|
||||||
|
setWidth();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
435
source/js/Ox.SplitPanel.js
Normal file
|
@ -0,0 +1,435 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
options:
|
||||||
|
elements: [{ array of one, two or three elements
|
||||||
|
collapsible: false, collapsible or not (only for outer elements)
|
||||||
|
collapsed: false, collapsed or not (only for collapsible elements)
|
||||||
|
element: {}, OxElement (if any element is resizable or
|
||||||
|
collapsible, all OxElements must have an id)
|
||||||
|
resizable: false, resizable or not (only for outer elements)
|
||||||
|
resize: [], array of sizes (only for resizable elements,
|
||||||
|
first value is min, last value is max,
|
||||||
|
other values are 'snappy' points in between)
|
||||||
|
size: 0 size in px (one element must have no size)
|
||||||
|
}],
|
||||||
|
orientation: '' 'horizontal' or 'vertical'
|
||||||
|
events:
|
||||||
|
resize
|
||||||
|
toggle
|
||||||
|
*/
|
||||||
|
Ox.SplitPanel = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self) // fixme: Container
|
||||||
|
.defaults({
|
||||||
|
elements: [],
|
||||||
|
orientation: 'horizontal'
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxSplitPanel');
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
dimensions: Ox.UI.DIMENSIONS[self.options.orientation],
|
||||||
|
edges: Ox.UI.EDGES[self.options.orientation],
|
||||||
|
length: self.options.elements.length,
|
||||||
|
resizebarElements: [],
|
||||||
|
$resizebars: []
|
||||||
|
});
|
||||||
|
|
||||||
|
// create elements
|
||||||
|
that.$elements = [];
|
||||||
|
self.options.elements.forEach(function(v, i) {
|
||||||
|
self.options.elements[i] = $.extend({
|
||||||
|
collapsible: false,
|
||||||
|
collapsed: false,
|
||||||
|
resizable: false,
|
||||||
|
resize: [],
|
||||||
|
size: 'auto'
|
||||||
|
}, v);
|
||||||
|
that.$elements[i] = v.element
|
||||||
|
.css(self.edges[2], (parseInt(v.element.css(self.edges[2])) || 0) + 'px')
|
||||||
|
.css(self.edges[3], (parseInt(v.element.css(self.edges[3])) || 0) + 'px');
|
||||||
|
//alert(v.element.css(self.edges[3]))
|
||||||
|
});
|
||||||
|
|
||||||
|
// create resizebars
|
||||||
|
self.options.elements.forEach(function(v, i) {
|
||||||
|
//that.append(element)
|
||||||
|
//Ox.print('V: ', v, that.$elements[i])
|
||||||
|
var index = i == 0 ? 0 : 1;
|
||||||
|
that.$elements[i].appendTo(that.$element); // fixme: that.$content
|
||||||
|
if (v.collapsible || v.resizable) {
|
||||||
|
//Ox.print('v.size', v.size)
|
||||||
|
self.resizebarElements[index] = i < 2 ? [0, 1] : [1, 2];
|
||||||
|
self.$resizebars[index] = new Ox.Resizebar({
|
||||||
|
collapsible: v.collapsible,
|
||||||
|
edge: self.edges[index],
|
||||||
|
elements: [
|
||||||
|
that.$elements[self.resizebarElements[index][0]],
|
||||||
|
that.$elements[self.resizebarElements[index][1]]
|
||||||
|
],
|
||||||
|
id: v.element.options('id'),
|
||||||
|
orientation: self.options.orientation == 'horizontal' ? 'vertical' : 'horizontal',
|
||||||
|
parent: that, // fixme: that.$content
|
||||||
|
resizable: v.resizable,
|
||||||
|
resize: v.resize,
|
||||||
|
size: v.size
|
||||||
|
});
|
||||||
|
self.$resizebars[index][i == 0 ? 'insertAfter' : 'insertBefore'](that.$elements[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.options.elements.forEach(function(v, i) {
|
||||||
|
v.collapsed && that.css(
|
||||||
|
self.edges[i == 0 ? 0 : 1], -self.options.elements[i].size + 'px'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
setSizes(true);
|
||||||
|
|
||||||
|
function getPositionById(id) {
|
||||||
|
var position = -1;
|
||||||
|
Ox.forEach(self.options.elements, function(element, i) {
|
||||||
|
if (element.element.options('id') == id) {
|
||||||
|
position = i;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//Ox.print('getPositionById', id, position);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSize(element) {
|
||||||
|
return element.size + (element.collapsible || element.resizable);
|
||||||
|
//return (element.size + (element.collapsible || element.resizable)) * !element.collapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVisibleSize(element) {
|
||||||
|
return getSize(element) * !element.collapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSizes(init) {
|
||||||
|
self.options.elements.forEach(function(v, i) {
|
||||||
|
// fixme: maybe we can add a conditional here, since init
|
||||||
|
// is about elements that are collapsed splitpanels
|
||||||
|
var edges = [
|
||||||
|
(init && parseInt(that.$elements[i].css(self.edges[0]))) || 0,
|
||||||
|
(init && parseInt(that.$elements[i].css(self.edges[1]))) || 0
|
||||||
|
];
|
||||||
|
v.size != 'auto' && that.$elements[i].css(self.dimensions[0], v.size + 'px');
|
||||||
|
if (i == 0) {
|
||||||
|
that.$elements[i].css(
|
||||||
|
self.edges[0], edges[0] + 'px'
|
||||||
|
);
|
||||||
|
that.$elements[i].css(
|
||||||
|
self.edges[1], (getSize(self.options.elements[1]) + (length == 3 ? getSize(self.options.elements[2]) : 0)) + 'px'
|
||||||
|
);
|
||||||
|
} else if (i == 1) {
|
||||||
|
that.$elements[i].css(
|
||||||
|
self.edges[0], self.options.elements[0].size == 'auto' ? 'auto' :
|
||||||
|
edges[0] + getSize(self.options.elements[0]) + 'px'
|
||||||
|
);
|
||||||
|
(self.options.elements[0].size != 'auto' || v.size != 'auto') && that.$elements[i].css(
|
||||||
|
self.edges[1], (self.length == 3 ? getSize(self.options.elements[2]) : 0) + 'px'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
that.$elements[i].css(
|
||||||
|
self.edges[0], (self.options.elements[1].size == 'auto' || v.size == 'auto') ? 'auto' :
|
||||||
|
(getVisibleSize(self.options.elements[0]) + getVisibleSize(self.options.elements[1])) + 'px'
|
||||||
|
);
|
||||||
|
that.$elements[i].css(
|
||||||
|
self.edges[1], edges[1] + 'px'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (v.collapsible || v.resizable) {
|
||||||
|
self.$resizebars[i == 0 ? 0 : 1].css(self.edges[i == 0 ? 0 : 1], v.size);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
that.isCollapsed = function(id) {
|
||||||
|
var pos = Ox.isNumber(id) ? id : getPositionById(id);
|
||||||
|
return self.options.elements[pos].collapsed;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.replaceElement = function(id, element) {
|
||||||
|
// one can pass pos instead of id
|
||||||
|
var pos = Ox.isNumber(id) ? id : getPositionById(id);
|
||||||
|
//Ox.print('replace', pos, element);
|
||||||
|
//Ox.print('element', self.options.elements[pos].element, element)
|
||||||
|
that.$elements[pos] = element
|
||||||
|
.css(self.edges[2], (parseInt(element.css(self.edges[2])) || 0) + 'px')
|
||||||
|
.css(self.edges[3], (parseInt(element.css(self.edges[3])) || 0) + 'px');
|
||||||
|
//alert(element.css(self.edges[3]))
|
||||||
|
self.options.elements[pos].element.replaceWith(element.$element.$element || element.$element);
|
||||||
|
self.options.elements[pos].element = element;
|
||||||
|
setSizes();
|
||||||
|
self.$resizebars.forEach(function($resizebar, i) {
|
||||||
|
$resizebar.options({
|
||||||
|
elements: [
|
||||||
|
that.$elements[self.resizebarElements[i][0]],
|
||||||
|
that.$elements[self.resizebarElements[i][1]]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//Ox.print(self.options.elements[pos])
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.replaceElements = function(elements) {
|
||||||
|
elements.forEach(function(element, i) {
|
||||||
|
if (Ox.isNumber(element.size)) {
|
||||||
|
that.size(i, element.size);
|
||||||
|
if (element.collapsible || element.resizable) {
|
||||||
|
self.$resizebars[i == 0 ? 0 : 1].options({
|
||||||
|
collapsible: element.collapsible,
|
||||||
|
resizable: element.resizable,
|
||||||
|
size: element.size
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
that.replace(i, element.element);
|
||||||
|
});
|
||||||
|
self.options.elements = elements;
|
||||||
|
self.$resizebars.forEach(function($resizebar, i) {
|
||||||
|
$resizebar.options({
|
||||||
|
elements: [
|
||||||
|
that.$elements[self.resizebarElements[i][0]],
|
||||||
|
that.$elements[self.resizebarElements[i][1]]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.size = function(id, size) {
|
||||||
|
// one can pass pos instead of id
|
||||||
|
var pos = Ox.isNumber(id) ? id : getPositionById(id),
|
||||||
|
element = self.options.elements[pos];
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
return element.element[self.dimensions[0]]() * !that.isCollapsed(pos);
|
||||||
|
} else {
|
||||||
|
element.size = size;
|
||||||
|
setSizes();
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggle = function(id) {
|
||||||
|
// one can pass pos instead of id
|
||||||
|
var pos = Ox.isNumber(id) ? id : getPositionById(id),
|
||||||
|
element = self.options.elements[pos],
|
||||||
|
value = parseInt(that.css(self.edges[pos == 0 ? 0 : 1])) +
|
||||||
|
element.element[self.dimensions[0]]() *
|
||||||
|
(element.collapsed ? 1 : -1),
|
||||||
|
animate = {};
|
||||||
|
animate[self.edges[pos == 0 ? 0 : 1]] = value;
|
||||||
|
that.animate(animate, 200, function() { // fixme: 250?
|
||||||
|
element.collapsed = !element.collapsed;
|
||||||
|
element.element.triggerEvent('toggle', {
|
||||||
|
'collapsed': element.collapsed
|
||||||
|
});
|
||||||
|
element = self.options.elements[pos == 0 ? 1 : pos - 1];
|
||||||
|
element.element.triggerEvent(
|
||||||
|
'resize',
|
||||||
|
element.element[self.dimensions[0]]()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
that.updateSize = function(pos, size) {
|
||||||
|
// this is called from resizebar
|
||||||
|
var pos = pos == 0 ? 0 : self.options.elements.length - 1; // fixme: silly that 0 or 1 is passed, and not pos
|
||||||
|
self.options.elements[pos].size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Ox.SplitPanel_ = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
elements: [],
|
||||||
|
orientation: 'horizontal'
|
||||||
|
})
|
||||||
|
.options(options)
|
||||||
|
.addClass(
|
||||||
|
'OxSplitPanel_ Ox' + Ox.toTitleCase(self.options.orientation)
|
||||||
|
);
|
||||||
|
|
||||||
|
Ox.extend(self, {
|
||||||
|
$separators: [],
|
||||||
|
clientXY: self.options.orientation == 'horizontal' ? 'clientX' : 'clientY',
|
||||||
|
dimensions: Ox.UI.DIMENSIONS[self.options.orientation],
|
||||||
|
edges: Ox.UI.EDGES[self.options.orientation]
|
||||||
|
});
|
||||||
|
|
||||||
|
self.options.elements.forEach(function(element, i) {
|
||||||
|
self.options.elements[i] = Ox.extend({
|
||||||
|
collapsible: false,
|
||||||
|
collapsed: false,
|
||||||
|
resizable: false,
|
||||||
|
resize: [],
|
||||||
|
size: 'auto'
|
||||||
|
}, element);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.autoPercent = (100 - self.options.elements.reduce(function(val, element) {
|
||||||
|
return val + (Ox.endsWith(element.size, '%') ? parseFloat(element.size) : 0);
|
||||||
|
}, 0)) / self.options.elements.filter(function(element) {
|
||||||
|
return element.size == 'auto';
|
||||||
|
}).length + '%';
|
||||||
|
|
||||||
|
self.options.elements.forEach(function(element, i) {
|
||||||
|
var flex, index = i == 0 ? 0 : 1;
|
||||||
|
if (Ox.isNumber(element.size)) {
|
||||||
|
element.element.css(self.dimensions[0], element.size + 'px');
|
||||||
|
} else {
|
||||||
|
flex = (
|
||||||
|
element.size == 'auto' ? self.autoPercent : element.size
|
||||||
|
).replace('%', '');
|
||||||
|
element.element.css({
|
||||||
|
boxFlex: flex,
|
||||||
|
MozBoxFlex: flex,
|
||||||
|
WebkitBoxFlex: flex
|
||||||
|
});
|
||||||
|
}
|
||||||
|
element.element.appendTo(that);
|
||||||
|
if (element.collapsible || element.resizable) {
|
||||||
|
self.$separators.push(
|
||||||
|
Ox.Element()
|
||||||
|
.addClass('OxSeparator')
|
||||||
|
.bindEvent({
|
||||||
|
anyclick: function() {
|
||||||
|
that.toggle(i);
|
||||||
|
},
|
||||||
|
dragstart: function(event, e) {
|
||||||
|
dragstart(i, e);
|
||||||
|
},
|
||||||
|
drag: function(event, e) {
|
||||||
|
drag(i, e);
|
||||||
|
},
|
||||||
|
dragend: function(event, e) {
|
||||||
|
dragend(i, e);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.append($('<div>').addClass('OxSpace'))
|
||||||
|
.append($('<div>').addClass('OxLine'))
|
||||||
|
.append($('<div>').addClass('OxSpace'))
|
||||||
|
['insert' + (index ? 'Before' : 'After')](element.element)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function dragstart(pos, e) {
|
||||||
|
var element = self.options.elements[pos],
|
||||||
|
size = element.element[self.dimensions[0]]();
|
||||||
|
if (element.resizable && !element.collapsed) {
|
||||||
|
self.drag = {
|
||||||
|
size: size,
|
||||||
|
startPos: e[self.clientXY],
|
||||||
|
startSize: size
|
||||||
|
};
|
||||||
|
Ox.print('self.drag', self.drag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drag(pos, e) {
|
||||||
|
var data = {},
|
||||||
|
element = self.options.elements[pos],
|
||||||
|
index = pos == 0 ? 0 : 1;
|
||||||
|
if (element.resizable && !element.collapsed) {
|
||||||
|
var d = e[self.clientXY] - self.drag.startPos,
|
||||||
|
size = Ox.limit(
|
||||||
|
self.drag.startSize + d * (index ? -1 : 1),
|
||||||
|
element.resize[0],
|
||||||
|
element.resize[element.resize.length - 1]
|
||||||
|
);
|
||||||
|
Ox.forEach(element.resize, function(v) {
|
||||||
|
if (size >= v - 8 && size <= v + 8) {
|
||||||
|
size = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (size != self.drag.size) {
|
||||||
|
self.drag.size = size;
|
||||||
|
data[self.dimensions[0]] = size;
|
||||||
|
element.element
|
||||||
|
.css(self.dimensions[0], size + 'px')
|
||||||
|
.triggerEvent('resize', data);
|
||||||
|
triggerEvents('resize', pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragend(pos, e) {
|
||||||
|
var data = {},
|
||||||
|
element = self.options.elements[pos];
|
||||||
|
if (element.resizable && !element.collapsed) {
|
||||||
|
data[self.dimensions[0]] = self.drag.size
|
||||||
|
element.element.triggerEvent('resizeend', data);
|
||||||
|
triggerEvents('resizeend', pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerEvents(event, pos) {
|
||||||
|
var data = {};
|
||||||
|
self.options.elements.forEach(function(element, i) {
|
||||||
|
if (i != pos && element.size == 'auto') {
|
||||||
|
data[self.dimensions[0]] = element.element[self.dimensions[0]]();
|
||||||
|
element.element.triggerEvent(event, data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
that.replaceElement = function(pos, element) {
|
||||||
|
var $element = self.options.elements[pos].element,
|
||||||
|
size = self.options.elements[pos].size;
|
||||||
|
$element.replaceWith(self.options.elements[pos].element = element);
|
||||||
|
if (size == 'auto') {
|
||||||
|
$element.css(self.boxFlexCSS);
|
||||||
|
} else {
|
||||||
|
$element.css(self.dimensions[0], size + 'px')
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.size = function(pos, size) {
|
||||||
|
var element = self.options.elements[pos],
|
||||||
|
ret;
|
||||||
|
if (Ox.isUndefined(size)) {
|
||||||
|
ret = element.element[self.dimensions[0]]();
|
||||||
|
} else {
|
||||||
|
element.size = size;
|
||||||
|
element.element.css(self.dimensions[0], size + 'px')
|
||||||
|
ret = that;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.toggle = function(pos) {
|
||||||
|
var css = {},
|
||||||
|
element = self.options.elements[pos],
|
||||||
|
flex,
|
||||||
|
index = pos == 0 ? 0 : 1,
|
||||||
|
size = element.element[self.dimensions[0]]();
|
||||||
|
if (element.collapsible) {
|
||||||
|
element.collapsed = !element.collapsed;
|
||||||
|
css['margin' + Ox.toTitleCase(self.edges[0][index])] =
|
||||||
|
element.collapsed ? -size : 0;
|
||||||
|
Ox.print('css', css);
|
||||||
|
that.animate(css, 250, function() {
|
||||||
|
element.element.triggerEvent('toggle', {collapsed: element.collapsed});
|
||||||
|
triggerEvents('resize', pos);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
3
source/js/Ox.TabPanel.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Ox.TabPanel = function(options, self) {
|
||||||
|
|
||||||
|
};
|
27
source/js/Ox.Tabbar.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
Ox.Tabbar = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Bar({
|
||||||
|
size: 20
|
||||||
|
}, self)
|
||||||
|
.defaults({
|
||||||
|
selected: 0,
|
||||||
|
tabs: []
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxTabbar');
|
||||||
|
|
||||||
|
Ox.ButtonGroup({
|
||||||
|
buttons: self.options.tabs,
|
||||||
|
group: true,
|
||||||
|
selectable: true,
|
||||||
|
selected: self.options.selected,
|
||||||
|
size: 'medium',
|
||||||
|
style: 'tab',
|
||||||
|
}).appendTo(that);
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
719
source/js/Ox.TextList.js
Normal file
|
@ -0,0 +1,719 @@
|
||||||
|
Ox.TextList = function(options, self) {
|
||||||
|
|
||||||
|
// fixme: rename to TableList
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
columns: [],
|
||||||
|
columnsMovable: false,
|
||||||
|
columnsRemovable: false,
|
||||||
|
columnsResizable: false,
|
||||||
|
columnsVisible: false,
|
||||||
|
columnWidth: [40, 800],
|
||||||
|
id: '',
|
||||||
|
items: null, // function() {} {sort, range, keys, callback} or array
|
||||||
|
max: -1,
|
||||||
|
min: 0,
|
||||||
|
pageLength: 100,
|
||||||
|
scrollbarVisible: false,
|
||||||
|
selected: [],
|
||||||
|
sort: []
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxTextList');
|
||||||
|
|
||||||
|
Ox.print('Ox.TextList self.options', self.options)
|
||||||
|
|
||||||
|
self.options.columns.forEach(function(v) { // fixme: can this go into a generic ox.js function?
|
||||||
|
// fixme: and can't these just remain undefined?
|
||||||
|
if (Ox.isUndefined(v.align)) {
|
||||||
|
v.align = 'left';
|
||||||
|
}
|
||||||
|
if (Ox.isUndefined(v.clickable)) {
|
||||||
|
v.clickable = false;
|
||||||
|
}
|
||||||
|
if (Ox.isUndefined(v.editable)) {
|
||||||
|
v.editable = false;
|
||||||
|
}
|
||||||
|
if (Ox.isUndefined(v.unique)) {
|
||||||
|
v.unique = false;
|
||||||
|
}
|
||||||
|
if (Ox.isUndefined(v.visible)) {
|
||||||
|
v.visible = false;
|
||||||
|
}
|
||||||
|
if (v.unique) {
|
||||||
|
self.unique = v.id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
columnPositions: [],
|
||||||
|
defaultColumnWidths: $.map(self.options.columns, function(v) {
|
||||||
|
return v.defaultWidth || v.width;
|
||||||
|
}),
|
||||||
|
itemHeight: 16,
|
||||||
|
page: 0,
|
||||||
|
pageLength: 100,
|
||||||
|
scrollLeft: 0,
|
||||||
|
selectedColumn: getColumnIndexById(self.options.sort[0].key),
|
||||||
|
visibleColumns: $.map(self.options.columns, function(v) {
|
||||||
|
return v.visible ? v : null;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
// fixme: there might be a better way than passing both visible and position
|
||||||
|
self.options.columns.forEach(function(v) {
|
||||||
|
if (!Ox.isUndefined(v.position)) {
|
||||||
|
self.visibleColumns[v.position] = v;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.extend(self, {
|
||||||
|
columnWidths: $.map(self.visibleColumns, function(v, i) {
|
||||||
|
return v.width;
|
||||||
|
}),
|
||||||
|
pageHeight: self.options.pageLength * self.itemHeight
|
||||||
|
});
|
||||||
|
|
||||||
|
self.format = {};
|
||||||
|
self.options.columns.forEach(function(v, i) {
|
||||||
|
if (v.format) {
|
||||||
|
self.format[v.id] = v.format;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Head
|
||||||
|
|
||||||
|
if (self.options.columnsVisible) {
|
||||||
|
that.$bar = new Ox.Bar({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
size: 16
|
||||||
|
}).appendTo(that);
|
||||||
|
that.$head = new Ox.Container()
|
||||||
|
.addClass('OxHead')
|
||||||
|
.css({
|
||||||
|
right: self.options.scrollbarVisible ? Ox.UI.SCROLLBAR_SIZE + 'px' : 0
|
||||||
|
})
|
||||||
|
.appendTo(that.$bar);
|
||||||
|
that.$head.$content.addClass('OxTitles');
|
||||||
|
constructHead();
|
||||||
|
if (self.options.columnsRemovable) {
|
||||||
|
that.$select = new Ox.Select({
|
||||||
|
id: self.options.id + 'SelectColumns',
|
||||||
|
items: $.map(self.options.columns, function(v, i) {
|
||||||
|
return {
|
||||||
|
checked: v.visible,
|
||||||
|
disabled: v.removable === false,
|
||||||
|
id: v.id,
|
||||||
|
title: v.title
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
max: -1,
|
||||||
|
min: 1,
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent('change', changeColumns)
|
||||||
|
.appendTo(that.$bar.$element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Body
|
||||||
|
|
||||||
|
that.$body = new Ox.List({
|
||||||
|
construct: constructItem,
|
||||||
|
id: self.options.id,
|
||||||
|
items: self.options.items,
|
||||||
|
itemHeight: 16,
|
||||||
|
items: self.options.items,
|
||||||
|
itemWidth: getItemWidth(),
|
||||||
|
format: self.format, // fixme: not needed, happens in TextList
|
||||||
|
keys: $.map(self.visibleColumns, function(v) {
|
||||||
|
return v.id;
|
||||||
|
}),
|
||||||
|
max: self.options.max,
|
||||||
|
min: self.options.min,
|
||||||
|
pageLength: self.options.pageLength,
|
||||||
|
paste: self.options.paste,
|
||||||
|
orientation: 'vertical',
|
||||||
|
selected: self.options.selected,
|
||||||
|
sort: self.options.sort,
|
||||||
|
sortable: self.options.sortable,
|
||||||
|
type: 'text',
|
||||||
|
unique: self.unique
|
||||||
|
}, $.extend({}, self)) // pass event handler
|
||||||
|
.addClass('OxBody')
|
||||||
|
.css({
|
||||||
|
top: (self.options.columnsVisible ? 16 : 0) + 'px',
|
||||||
|
overflowY: (self.options.scrollbarVisible ? 'scroll' : 'hidden')
|
||||||
|
})
|
||||||
|
.scroll(function() {
|
||||||
|
var scrollLeft = $(this).scrollLeft();
|
||||||
|
if (scrollLeft != self.scrollLeft) {
|
||||||
|
self.scrollLeft = scrollLeft;
|
||||||
|
that.$head && that.$head.scrollLeft(scrollLeft);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
edit: function(event, data) {
|
||||||
|
that.editCell(data.id, data.key);
|
||||||
|
},
|
||||||
|
select: function(event, data) {
|
||||||
|
self.options.selected = data.ids;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
that.$body.$content.css({
|
||||||
|
width: getItemWidth() + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
//Ox.print('s.vC', self.visibleColumns)
|
||||||
|
|
||||||
|
function addColumn(id) {
|
||||||
|
//Ox.print('addColumn', id);
|
||||||
|
var column, ids,
|
||||||
|
index = 0;
|
||||||
|
Ox.forEach(self.options.columns, function(v) {
|
||||||
|
if (v.visible) {
|
||||||
|
index++;
|
||||||
|
} else if (v.id == id) {
|
||||||
|
column = v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
column.visible = true;
|
||||||
|
self.visibleColumns.splice(index, 0, column);
|
||||||
|
self.columnWidths.splice(index, 0, column.width);
|
||||||
|
that.$head.$content.empty();
|
||||||
|
constructHead();
|
||||||
|
that.$body.options({
|
||||||
|
keys: $.map(self.visibleColumns, function(v, i) {
|
||||||
|
return v.id;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
that.$body.reloadPages();
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeColumns(event, data) {
|
||||||
|
var add,
|
||||||
|
ids = [];
|
||||||
|
Ox.forEach(data.selected, function(column) {
|
||||||
|
var index = getColumnIndexById(column.id);
|
||||||
|
if (!self.options.columns[index].visible) {
|
||||||
|
addColumn(column.id);
|
||||||
|
add = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ids.push(column.id);
|
||||||
|
});
|
||||||
|
if (!add) {
|
||||||
|
Ox.forEach(self.visibleColumns, function(column) {
|
||||||
|
if (ids.indexOf(column.id) == -1) {
|
||||||
|
removeColumn(column.id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
triggerColumnChangeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickColumn(id) {
|
||||||
|
Ox.print('clickColumn', id);
|
||||||
|
var i = getColumnIndexById(id),
|
||||||
|
isSelected = self.options.sort[0].key == self.options.columns[i].id;
|
||||||
|
that.sortList(
|
||||||
|
self.options.columns[i].id, isSelected ?
|
||||||
|
(self.options.sort[0].operator == '+' ? '-' : '+') :
|
||||||
|
self.options.columns[i].operator
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructHead() {
|
||||||
|
var offset = 0;
|
||||||
|
that.$titles = [];
|
||||||
|
self.columnOffsets = [];
|
||||||
|
self.visibleColumns.forEach(function(v, i) {
|
||||||
|
var $order, $resize, $left, $center, $right;
|
||||||
|
offset += self.columnWidths[i];
|
||||||
|
self.columnOffsets[i] = offset - self.columnWidths[i] / 2;
|
||||||
|
that.$titles[i] = new Ox.Element()
|
||||||
|
.addClass('OxTitle OxColumn' + Ox.toTitleCase(v.id))
|
||||||
|
.css({
|
||||||
|
width: (self.columnWidths[i] - 9) + 'px',
|
||||||
|
textAlign: v.align
|
||||||
|
})
|
||||||
|
.html(v.title)
|
||||||
|
.bindEvent({
|
||||||
|
anyclick: function(event, e) {
|
||||||
|
clickColumn(v.id);
|
||||||
|
},
|
||||||
|
dragstart: function(event, e) {
|
||||||
|
dragstartColumn(v.id, e);
|
||||||
|
},
|
||||||
|
drag: function(event, e) {
|
||||||
|
dragColumn(v.id, e);
|
||||||
|
},
|
||||||
|
dragend: function(event, e) {
|
||||||
|
dragendColumn(v.id, e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(that.$head.$content.$element);
|
||||||
|
$order = $('<div>')
|
||||||
|
.addClass('OxOrder')
|
||||||
|
.html(Ox.UI.symbols['triangle_' + (
|
||||||
|
v.operator == '+' ? 'up' : 'down'
|
||||||
|
)])
|
||||||
|
.click(function() {
|
||||||
|
$(this).prev().trigger('click')
|
||||||
|
})
|
||||||
|
.appendTo(that.$head.$content.$element);
|
||||||
|
$resize = new Ox.Element()
|
||||||
|
.addClass('OxResize')
|
||||||
|
.appendTo(that.$head.$content.$element);
|
||||||
|
if (self.options.columnsResizable) {
|
||||||
|
$resize.addClass('OxResizable')
|
||||||
|
.bindEvent({
|
||||||
|
doubleclick: function(event, e) {
|
||||||
|
resetColumn(v.id, e);
|
||||||
|
},
|
||||||
|
dragstart: function(event, e) {
|
||||||
|
dragstartResize(v.id, e);
|
||||||
|
},
|
||||||
|
drag: function(event, e) {
|
||||||
|
dragResize(v.id, e);
|
||||||
|
},
|
||||||
|
dragend: function(event, e) {
|
||||||
|
dragendResize(v.id, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$left = $('<div>').addClass('OxLeft').appendTo($resize.$element);
|
||||||
|
$center = $('<div>').addClass('OxCenter').appendTo($resize.$element);
|
||||||
|
$right = $('<div>').addClass('OxRight').appendTo($resize.$element);
|
||||||
|
});
|
||||||
|
that.$head.$content.css({
|
||||||
|
width: (Ox.sum(self.columnWidths) + 2) + 'px'
|
||||||
|
});
|
||||||
|
//Ox.print('s.sC', self.selectedColumn)
|
||||||
|
//Ox.print('s.cO', self.columnOffsets)
|
||||||
|
if (getColumnPositionById(self.options.columns[self.selectedColumn].id) > -1) { // fixme: save in var
|
||||||
|
toggleSelected(self.options.columns[self.selectedColumn].id);
|
||||||
|
that.$titles[getColumnPositionById(self.options.columns[self.selectedColumn].id)].css({
|
||||||
|
width: (self.options.columns[self.selectedColumn].width - 25) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructItem(data) {
|
||||||
|
var $item = $('<div>')
|
||||||
|
.addClass('OxTarget')
|
||||||
|
.css({
|
||||||
|
width: getItemWidth() + 'px'
|
||||||
|
});
|
||||||
|
self.visibleColumns.forEach(function(v, i) {
|
||||||
|
var clickable = Ox.isBoolean(v.clickable) ? v.clickable : v.clickable(data),
|
||||||
|
editable = Ox.isBoolean(v.editable) ? v.editable : v.editable(data),
|
||||||
|
$cell = $('<div>')
|
||||||
|
.addClass(
|
||||||
|
'OxCell OxColumn' + Ox.toTitleCase(v.id) +
|
||||||
|
(clickable ? ' OxClickable' : '') +
|
||||||
|
(editable ? ' OxEditable' : '')
|
||||||
|
)
|
||||||
|
.css({
|
||||||
|
width: (self.columnWidths[i] - (self.options.columnsVisible ? 9 : 8)) + 'px',
|
||||||
|
borderRightWidth: (self.options.columnsVisible ? 1 : 0) + 'px',
|
||||||
|
textAlign: v.align
|
||||||
|
})
|
||||||
|
.html(v.id in data ? formatValue(data[v.id], v.format) : '')
|
||||||
|
.appendTo($item);
|
||||||
|
});
|
||||||
|
function formatValue(value, format) {
|
||||||
|
if (value === null) {
|
||||||
|
value = '';
|
||||||
|
} else if (format) {
|
||||||
|
value = Ox.isObject(format) ?
|
||||||
|
Ox['format' + Ox.toTitleCase(format.type)]
|
||||||
|
.apply(this, $.merge([value], format.args)) :
|
||||||
|
format(value);
|
||||||
|
} else if (Ox.isArray(value)) {
|
||||||
|
value = value.join(', ');
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
//Math.random() < 0.01 && Ox.print('item', data, $item);
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragstartColumn(id, e) {
|
||||||
|
self.drag = {
|
||||||
|
startX: e.clientX,
|
||||||
|
startPos: getColumnPositionById(id)
|
||||||
|
}
|
||||||
|
$.extend(self.drag, {
|
||||||
|
stopPos: self.drag.startPos,
|
||||||
|
offsets: $.map(self.visibleColumns, function(v, i) {
|
||||||
|
return self.columnOffsets[i] - self.columnOffsets[self.drag.startPos]
|
||||||
|
})
|
||||||
|
});
|
||||||
|
$('.OxColumn' + Ox.toTitleCase(id)).css({
|
||||||
|
opacity: 0.25
|
||||||
|
});
|
||||||
|
that.$titles[self.drag.startPos].addClass('OxDrag').css({ // fixme: why does the class not work?
|
||||||
|
cursor: 'move'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragColumn(id, e) {
|
||||||
|
var d = e.clientX - self.drag.startX,
|
||||||
|
pos = self.drag.stopPos;
|
||||||
|
Ox.forEach(self.drag.offsets, function(v, i) {
|
||||||
|
if (d < 0 && d < v) {
|
||||||
|
self.drag.stopPos = i;
|
||||||
|
return false;
|
||||||
|
} else if (d > 0 && d > v) {
|
||||||
|
self.drag.stopPos = i;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (self.drag.stopPos != pos) {
|
||||||
|
moveColumn(id, self.drag.stopPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragendColumn(id, e) {
|
||||||
|
var column = self.visibleColumns.splice(self.drag.stopPos, 1)[0],
|
||||||
|
width = self.columnWidths.splice(self.drag.stopPos, 1)[0];
|
||||||
|
self.visibleColumns.splice(self.drag.stopPos, 0, column);
|
||||||
|
self.columnWidths.splice(self.drag.stopPos, 0, width);
|
||||||
|
that.$head.$content.empty();
|
||||||
|
constructHead();
|
||||||
|
$('.OxColumn' + Ox.toTitleCase(id)).css({
|
||||||
|
opacity: 1
|
||||||
|
});
|
||||||
|
that.$titles[self.drag.stopPos].removeClass('OxDrag').css({
|
||||||
|
cursor: 'pointer'
|
||||||
|
});
|
||||||
|
that.$body.clearCache();
|
||||||
|
triggerColumnChangeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragstartResize(id, e) {
|
||||||
|
var pos = getColumnPositionById(id);
|
||||||
|
self.drag = {
|
||||||
|
startX: e.clientX,
|
||||||
|
startWidth: self.columnWidths[pos]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragResize(id, e) {
|
||||||
|
var width = Ox.limit(
|
||||||
|
self.drag.startWidth - self.drag.startX + e.clientX,
|
||||||
|
self.options.columnWidth[0],
|
||||||
|
self.options.columnWidth[1]
|
||||||
|
);
|
||||||
|
resizeColumn(id, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragendResize(id, e) {
|
||||||
|
var pos = getColumnPositionById(id);
|
||||||
|
that.triggerEvent('columnresize', {
|
||||||
|
id: id,
|
||||||
|
width: self.columnWidths[pos]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCell(id, key) {
|
||||||
|
Ox.print('getCell', id, key)
|
||||||
|
var $item = getItem(id);
|
||||||
|
return $($item.find('.OxCell.OxColumn' + Ox.toTitleCase(key))[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getColumnIndexById(id) {
|
||||||
|
return Ox.getPositionById(self.options.columns, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getColumnPositionById(id) {
|
||||||
|
return Ox.getPositionById(self.visibleColumns, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItem(id) {
|
||||||
|
//Ox.print('getItem', id)
|
||||||
|
var $item = null;
|
||||||
|
$.each(that.find('.OxItem'), function(i, v) {
|
||||||
|
$v = $(v);
|
||||||
|
if ($v.data('id') == id) {
|
||||||
|
$item = $v;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItemWidth() {
|
||||||
|
return Math.max(
|
||||||
|
Ox.sum(self.columnWidths),
|
||||||
|
that.$element.width() -
|
||||||
|
(self.options.scrollbarVisible ? Ox.UI.SCROLLBAR_SIZE : 0)
|
||||||
|
);
|
||||||
|
//return Ox.sum(self.columnWidths)
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveColumn(id, pos) {
|
||||||
|
// fixme: column head should be one element, not three
|
||||||
|
//Ox.print('moveColumn', id, pos)
|
||||||
|
var startPos = getColumnPositionById(id),
|
||||||
|
stopPos = pos,
|
||||||
|
startClassName = '.OxColumn' + Ox.toTitleCase(id),
|
||||||
|
stopClassName = '.OxColumn' + Ox.toTitleCase(self.visibleColumns[stopPos].id),
|
||||||
|
insert = startPos < stopPos ? 'insertAfter' : 'insertBefore'
|
||||||
|
$column = $('.OxTitle' + startClassName),
|
||||||
|
$order = $column.next(),
|
||||||
|
$resize = $order.next();
|
||||||
|
//Ox.print(startClassName, insert, stopClassName)
|
||||||
|
$column.detach()[insert](insert == 'insertAfter' ? $('.OxTitle' + stopClassName).next().next() : $('.OxTitle' + stopClassName));
|
||||||
|
$order.detach().insertAfter($column);
|
||||||
|
$resize.detach().insertAfter($order);
|
||||||
|
$.each(that.$body.find('.OxItem'), function(i, v) {
|
||||||
|
var $v = $(v);
|
||||||
|
$v.children(startClassName).detach()[insert]($v.children(stopClassName));
|
||||||
|
});
|
||||||
|
var column = self.visibleColumns.splice(startPos, 1)[0],
|
||||||
|
width = self.columnWidths.splice(startPos, 1)[0];
|
||||||
|
self.visibleColumns.splice(stopPos, 0, column);
|
||||||
|
self.columnWidths.splice(stopPos, 0, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeColumn(id) {
|
||||||
|
//Ox.print('removeColumn', id);
|
||||||
|
var className = '.OxColumn' + Ox.toTitleCase(id),
|
||||||
|
index = getColumnIndexById(id),
|
||||||
|
itemWidth,
|
||||||
|
position = getColumnPositionById(id),
|
||||||
|
$column = $('.OxTitle' + className),
|
||||||
|
$order = $column.next(),
|
||||||
|
$resize = $order.next();
|
||||||
|
self.options.columns[index].visible = false;
|
||||||
|
self.visibleColumns.splice(position, 1);
|
||||||
|
self.columnWidths.splice(position, 1);
|
||||||
|
that.$head.$content.empty();
|
||||||
|
constructHead();
|
||||||
|
itemWidth = getItemWidth();
|
||||||
|
$.each(that.$body.find('.OxItem'), function(i, v) {
|
||||||
|
var $v = $(v);
|
||||||
|
$v.children(className).remove();
|
||||||
|
$v.css({
|
||||||
|
width: itemWidth + 'px'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
that.$body.$content.css({
|
||||||
|
width: itemWidth + 'px'
|
||||||
|
});
|
||||||
|
that.$body.options({
|
||||||
|
keys: $.map(self.visibleColumns, function(v, i) {
|
||||||
|
return v.id;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
//that.$body.clearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetColumn(id) {
|
||||||
|
var width = self.defaultColumnWidths[getColumnIndexById(id)];
|
||||||
|
resizeColumn(id, width);
|
||||||
|
that.triggerEvent('columnresize', {
|
||||||
|
id: id,
|
||||||
|
width: width
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeColumn(id, width) {
|
||||||
|
var i = getColumnIndexById(id),
|
||||||
|
pos = getColumnPositionById(id);
|
||||||
|
self.options.columns[i].width = width;
|
||||||
|
self.columnWidths[pos] = width;
|
||||||
|
if (self.options.columnsVisible) {
|
||||||
|
that.$head.$content.css({
|
||||||
|
width: (Ox.sum(self.columnWidths) + 2) + 'px'
|
||||||
|
});
|
||||||
|
that.$titles[pos].css({
|
||||||
|
width: (width - 9 - (i == self.selectedColumn ? 16 : 0)) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
that.find('.OxCell.OxColumn' + Ox.toTitleCase(self.options.columns[i].id)).css({
|
||||||
|
width: (width - (self.options.columnsVisible ? 9 : 8)) + 'px'
|
||||||
|
});
|
||||||
|
setWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWidth() {
|
||||||
|
var width = getItemWidth();
|
||||||
|
that.$body.$content.find('.OxItem').css({ // fixme: can we avoid this lookup?
|
||||||
|
width: width + 'px'
|
||||||
|
});
|
||||||
|
that.$body.$content.css({
|
||||||
|
width: width + 'px' // fixme: check if scrollbar visible, and listen to resize/toggle event
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSelected(id) {
|
||||||
|
var pos = getColumnPositionById(id);
|
||||||
|
if (pos > -1) {
|
||||||
|
updateOrder(id);
|
||||||
|
pos > 0 && that.$titles[pos].prev().children().eq(2).toggleClass('OxSelected');
|
||||||
|
that.$titles[pos].toggleClass('OxSelected');
|
||||||
|
that.$titles[pos].next().toggleClass('OxSelected');
|
||||||
|
that.$titles[pos].next().next().children().eq(0).toggleClass('OxSelected');
|
||||||
|
that.$titles[pos].css({
|
||||||
|
width: (
|
||||||
|
that.$titles[pos].width() + (that.$titles[pos].hasClass('OxSelected') ? -16 : 16)
|
||||||
|
) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerColumnChangeEvent() {
|
||||||
|
that.triggerEvent('columnchange', {
|
||||||
|
ids: $.map(self.visibleColumns, function(v, i) {
|
||||||
|
return v.id;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateOrder(id) {
|
||||||
|
var pos = getColumnPositionById(id);
|
||||||
|
//Ox.print(id, pos)
|
||||||
|
that.$titles[pos].next().html(Ox.UI.symbols[
|
||||||
|
'triangle_' + (self.options.sort[0].operator == '+' ? 'up' : 'down')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'items') {
|
||||||
|
//alert('request set!!')
|
||||||
|
that.$body.options(key, value);
|
||||||
|
} else if (key == 'paste') {
|
||||||
|
that.$body.options(key, value);
|
||||||
|
} else if (key == 'selected') {
|
||||||
|
that.$body.options(key, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// fixme: doesn't work, doesn't return that
|
||||||
|
that.closePreview = that.$body.closePreview;
|
||||||
|
|
||||||
|
that.editCell = function(id, key) {
|
||||||
|
Ox.print('editCell', id, key)
|
||||||
|
var $item = getItem(id),
|
||||||
|
$cell = getCell(id, key),
|
||||||
|
$input,
|
||||||
|
html = $cell.html(),
|
||||||
|
index = getColumnIndexById(key),
|
||||||
|
column = self.options.columns[index],
|
||||||
|
width = column.width - self.options.columnsVisible;
|
||||||
|
$cell.empty()
|
||||||
|
.addClass('OxEdit')
|
||||||
|
.css({
|
||||||
|
width: width + 'px'
|
||||||
|
});
|
||||||
|
$input = new Ox.Input({
|
||||||
|
autovalidate: column.input ? column.input.autovalidate : null,
|
||||||
|
style: 'square',
|
||||||
|
value: html,
|
||||||
|
width: width
|
||||||
|
})
|
||||||
|
.bind({
|
||||||
|
mousedown: function(e) {
|
||||||
|
// keep mousedown from reaching list
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
blur: submit,
|
||||||
|
})
|
||||||
|
.appendTo($cell);
|
||||||
|
//.focusInput();
|
||||||
|
setTimeout($input.focusInput, 0); // fixme: strange
|
||||||
|
function submit() {
|
||||||
|
var value = $input.value();
|
||||||
|
//$input.loseFocus().remove();
|
||||||
|
// fixme: leaky, inputs remain in focus stack
|
||||||
|
$cell.removeClass('OxEdit')
|
||||||
|
.css({
|
||||||
|
width: (width - 8) + 'px'
|
||||||
|
})
|
||||||
|
.html(value)
|
||||||
|
that.triggerEvent('submit', {
|
||||||
|
id: id,
|
||||||
|
key: key,
|
||||||
|
value: value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.gainFocus = function() {
|
||||||
|
that.$body.gainFocus();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.loseFocus = function() {
|
||||||
|
that.$body.loseFocus();
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.paste = function(data) {
|
||||||
|
that.$body.paste();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.reloadList = function() {
|
||||||
|
that.$body.reloadList();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.resizeColumn = function(id, width) {
|
||||||
|
resizeColumn(id, width);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.size = function() {
|
||||||
|
setWidth();
|
||||||
|
that.$body.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
that.sortList = function(key, operator) {
|
||||||
|
var isSelected = key == self.options.sort[0].key;
|
||||||
|
self.options.sort = [{key: key, operator: operator}];
|
||||||
|
if (self.options.columnsVisible) {
|
||||||
|
if (isSelected) {
|
||||||
|
updateOrder(self.options.columns[self.selectedColumn].id);
|
||||||
|
} else {
|
||||||
|
toggleSelected(self.options.columns[self.selectedColumn].id);
|
||||||
|
self.selectedColumn = getColumnIndexById(key);
|
||||||
|
toggleSelected(self.options.columns[self.selectedColumn].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
that.$body.sortList(self.options.sort[0].key, self.options.sort[0].operator);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.value = function(id, key, value) {
|
||||||
|
// fixme: make this accept id, {k: v, ...}
|
||||||
|
var $item = getItem(id),
|
||||||
|
//$cell = getCell(id, key),
|
||||||
|
column = self.options.columns[getColumnIndexById(key)];
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
return that.$body.value(id);
|
||||||
|
} else if (arguments.length == 2) {
|
||||||
|
return that.$body.value(id, key);
|
||||||
|
} else {
|
||||||
|
that.$body.value(id, key, value);
|
||||||
|
/*
|
||||||
|
$cell && $cell.html(column.format ? column.format(value) : value);
|
||||||
|
if (column.unique) {
|
||||||
|
that.$body.setId($item.data('id'), value);
|
||||||
|
$item.data({id: value});
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
65
source/js/Ox.Theme.js
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// fixme: this should be Ox.Theme, and provide Ox.Theme.set(), Ox.Theme.load, etc.
|
||||||
|
/**
|
||||||
|
if name is given as argument, switch to this theme.
|
||||||
|
return current theme otherwise.
|
||||||
|
|
||||||
|
Ox.theme()
|
||||||
|
get theme
|
||||||
|
Ox.theme('foo')
|
||||||
|
set theme to 'foo'
|
||||||
|
*/
|
||||||
|
|
||||||
|
Ox.UI.ready(function() {
|
||||||
|
|
||||||
|
Ox.theme = function() {
|
||||||
|
var length = arguments.length,
|
||||||
|
classes = Ox.UI.$body.attr('class').split(' '),
|
||||||
|
arg, theme;
|
||||||
|
Ox.forEach(classes, function(v) {
|
||||||
|
if (Ox.startsWith(v, 'OxTheme')) {
|
||||||
|
theme = v.replace('OxTheme', '').toLowerCase();
|
||||||
|
if (length == 1) {
|
||||||
|
Ox.UI.$body.removeClass(v);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (length == 1) {
|
||||||
|
arg = arguments[0]
|
||||||
|
Ox.UI.$body.addClass('OxTheme' + Ox.toTitleCase(arg));
|
||||||
|
if (theme) {
|
||||||
|
$('img').each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
if (!$this.attr('src')) return; // fixme: remove, should't be neccessary
|
||||||
|
$this.attr({
|
||||||
|
src: $this.attr('src').replace(
|
||||||
|
'/ox.ui.' + theme + '/', '/ox.ui.' + arg + '/'
|
||||||
|
)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$('input[type=image]').each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
$this.attr({
|
||||||
|
src: $this.attr('src').replace(
|
||||||
|
'/ox.ui.' + theme + '/', '/ox.ui.' + arg + '/'
|
||||||
|
)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$('.OxLoadingIcon').each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
$this.attr({
|
||||||
|
src: $this.attr('src').replace(
|
||||||
|
'/ox.ui.' + theme + '/', '/ox.ui.' + arg + '/'
|
||||||
|
)
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return theme;
|
||||||
|
};
|
||||||
|
|
||||||
|
Ox.theme(Ox.UI.DEFAULT_THEME);
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
152
source/js/Ox.TimeInput.js
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
Ox.TimeInput = function(options, self) {
|
||||||
|
|
||||||
|
// fixme: seconds get set even if options.seconds is false
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element({}, self)
|
||||||
|
.defaults({
|
||||||
|
ampm: false,
|
||||||
|
seconds: false,
|
||||||
|
milliseconds: false,
|
||||||
|
value: Ox.formatDate(new Date(), '%T'),
|
||||||
|
})
|
||||||
|
.options(options || {});
|
||||||
|
|
||||||
|
if (self.options.milliseconds) {
|
||||||
|
self.options.seconds = true;
|
||||||
|
if (self.options.value.indexOf('.') == -1) {
|
||||||
|
self.options.value += '.000';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.date = getDate();
|
||||||
|
self.values = getValues();
|
||||||
|
|
||||||
|
self.$input = {
|
||||||
|
hours: new Ox.Input({
|
||||||
|
autocomplete: $.map(self.options.ampm ? Ox.range(1, 13) : Ox.range(0, 24), function(v) {
|
||||||
|
return Ox.pad(v, 2);
|
||||||
|
}),
|
||||||
|
autocompleteReplace: true,
|
||||||
|
autocompleteReplaceCorrect: true,
|
||||||
|
id: 'hours',
|
||||||
|
textAlign: 'right',
|
||||||
|
value: self.values.hours,
|
||||||
|
width: 32
|
||||||
|
}),
|
||||||
|
minutes: new Ox.Input({
|
||||||
|
autocomplete: $.map(Ox.range(0, 60), function(v) {
|
||||||
|
return Ox.pad(v, 2);
|
||||||
|
}),
|
||||||
|
autocompleteReplace: true,
|
||||||
|
autocompleteReplaceCorrect: true,
|
||||||
|
id: 'minutes',
|
||||||
|
textAlign: 'right',
|
||||||
|
value: self.values.minutes,
|
||||||
|
width: 32
|
||||||
|
}),
|
||||||
|
seconds: new Ox.Input({
|
||||||
|
autocomplete: $.map(Ox.range(0, 60), function(v) {
|
||||||
|
return Ox.pad(v, 2);
|
||||||
|
}),
|
||||||
|
autocompleteReplace: true,
|
||||||
|
autocompleteReplaceCorrect: true,
|
||||||
|
id: 'seconds',
|
||||||
|
textAlign: 'right',
|
||||||
|
value: self.values.seconds,
|
||||||
|
width: 32
|
||||||
|
}),
|
||||||
|
milliseconds: new Ox.Input({
|
||||||
|
autocomplete: $.map(Ox.range(0, 1000), function(v) {
|
||||||
|
return Ox.pad(v, 3);
|
||||||
|
}),
|
||||||
|
autocompleteReplace: true,
|
||||||
|
autocompleteReplaceCorrect: true,
|
||||||
|
id: 'milliseconds',
|
||||||
|
textAlign: 'right',
|
||||||
|
value: self.values.milliseconds,
|
||||||
|
width: 40
|
||||||
|
}),
|
||||||
|
ampm: new Ox.Input({
|
||||||
|
autocomplete: ['AM', 'PM'],
|
||||||
|
autocompleteReplace: true,
|
||||||
|
autocompleteReplaceCorrect: true,
|
||||||
|
id: 'ampm',
|
||||||
|
value: self.values.ampm,
|
||||||
|
width: 32
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
that = new Ox.InputGroup($.extend(self.options, {
|
||||||
|
inputs: $.merge($.merge($.merge([
|
||||||
|
self.$input.hours,
|
||||||
|
self.$input.minutes,
|
||||||
|
], self.options.seconds ? [
|
||||||
|
self.$input.seconds
|
||||||
|
] : []), self.options.milliseconds ? [
|
||||||
|
self.$input.milliseconds
|
||||||
|
] : []), self.options.ampm ? [
|
||||||
|
self.$input.ampm
|
||||||
|
] : []),
|
||||||
|
separators: $.merge($.merge($.merge([
|
||||||
|
{title: ':', width: 8},
|
||||||
|
], self.options.seconds ? [
|
||||||
|
{title: ':', width: 8}
|
||||||
|
] : []), self.options.milliseconds ? [
|
||||||
|
{title: '.', width: 8}
|
||||||
|
] : []), self.options.ampm ? [
|
||||||
|
{title: '', width: 8}
|
||||||
|
] : []),
|
||||||
|
//width: self.options.width || 128
|
||||||
|
}), self)
|
||||||
|
.bindEvent('change', setValue);
|
||||||
|
|
||||||
|
setValue();
|
||||||
|
|
||||||
|
function getDate() {
|
||||||
|
return new Date('1970/01/01 ' + (
|
||||||
|
self.options.milliseconds ?
|
||||||
|
self.options.value.substr(0, self.options.value.length - 4) :
|
||||||
|
self.options.value
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getValues() {
|
||||||
|
self.date = getDate();
|
||||||
|
return {
|
||||||
|
ampm: Ox.formatDate(self.date, '%p'),
|
||||||
|
hours: Ox.formatDate(self.date, self.options.ampm ? '%I' : '%H'),
|
||||||
|
milliseconds: self.options.milliseconds ? self.options.value.substr(-3) : '000',
|
||||||
|
minutes: Ox.formatDate(self.date, '%M'),
|
||||||
|
seconds: Ox.formatDate(self.date, '%S')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setValue() {
|
||||||
|
self.options.value = Ox.formatDate(new Date('1970/01/01 ' + [
|
||||||
|
self.$input.hours.options('value'),
|
||||||
|
self.$input.minutes.options('value'),
|
||||||
|
self.options.seconds ? self.$input.seconds.options('value') : '00'
|
||||||
|
].join(':') + (self.options.ampm ? ' ' + self.$input.ampm.options('value') : '')),
|
||||||
|
(self.options.seconds? '%T' : '%H:%M')) +
|
||||||
|
(self.options.milliseconds ? '.' + self.$input.milliseconds.options('value') : '');
|
||||||
|
//Ox.print('SETVALUE', self.options.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setValues() {
|
||||||
|
self.values = getValues();
|
||||||
|
Ox.forEach(self.$input, function(v, k) {
|
||||||
|
self.$input[k].options({
|
||||||
|
value: self.values[k]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'value') {
|
||||||
|
setValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
10
source/js/Ox.Toolbar.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/**
|
||||||
|
fixme: no need for this
|
||||||
|
*/
|
||||||
|
Ox.Toolbar = function(options, self) {
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Bar({
|
||||||
|
size: Ox.UI.getBarSize(options.size)
|
||||||
|
}, self);
|
||||||
|
return that;
|
||||||
|
};
|
56
source/js/Ox.Tooltip.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
Ox.Tooltip = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
animate: true,
|
||||||
|
title: ''
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxTooltip')
|
||||||
|
.html(self.options.title);
|
||||||
|
|
||||||
|
self.options.animate && that.css({
|
||||||
|
opacity: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'title') {
|
||||||
|
that.html(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.hide = function() {
|
||||||
|
if (self.options.animate) {
|
||||||
|
that.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 250, function() {
|
||||||
|
that.removeElement();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
that.removeElement();
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.show = function(x, y) {
|
||||||
|
var left, top, width, height;
|
||||||
|
$('.OxTooltip').remove(); // fixme: don't use DOM
|
||||||
|
that.appendTo(Ox.UI.$body);
|
||||||
|
width = that.width();
|
||||||
|
height = that.height();
|
||||||
|
left = Ox.limit(x - width / 2, 0, Ox.UI.$document.width() - width);
|
||||||
|
top = y > Ox.UI.$document.height() - height - 16 ? y - 32 : y + 16;
|
||||||
|
that.css({
|
||||||
|
left: left + 'px',
|
||||||
|
top: top + 'px'
|
||||||
|
});
|
||||||
|
self.options.animate && that.animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 250);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
196
source/js/Ox.TreeList.js
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
Ox.TreeList = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
data: null,
|
||||||
|
items: [],
|
||||||
|
max: -1,
|
||||||
|
min: 0,
|
||||||
|
selected: [],
|
||||||
|
width: 256
|
||||||
|
})
|
||||||
|
.options(options || {});
|
||||||
|
|
||||||
|
if (self.options.data) {
|
||||||
|
self.options.items = [];
|
||||||
|
//Ox.print('d', self.options.data, 'i', self.options.items)
|
||||||
|
Ox.forEach(self.options.data, function(value, key) {
|
||||||
|
self.options.items.push(parseData(key, value));
|
||||||
|
});
|
||||||
|
//Ox.print('d', self.options.data, 'i', self.options.items)
|
||||||
|
}
|
||||||
|
|
||||||
|
that.$element = new Ox.List({
|
||||||
|
construct: constructItem,
|
||||||
|
itemHeight: 16,
|
||||||
|
items: parseItems(),
|
||||||
|
itemWidth: self.options.width,
|
||||||
|
max: self.options.max,
|
||||||
|
min: self.options.min,
|
||||||
|
unique: 'id',
|
||||||
|
}, $.extend({}, self))
|
||||||
|
.addClass('OxTextList OxTreeList')
|
||||||
|
.css({
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
})
|
||||||
|
.click(clickItem)
|
||||||
|
.bindEvent({
|
||||||
|
toggle: toggleItems
|
||||||
|
});
|
||||||
|
|
||||||
|
function clickItem(e) {
|
||||||
|
var $target = $(e.target),
|
||||||
|
$item, id, item;
|
||||||
|
if ($target.hasClass('OxToggle')) {
|
||||||
|
$item = $target.parent().parent();
|
||||||
|
id = $item.data('id');
|
||||||
|
item = getItemById(id);
|
||||||
|
toggleItem(item, !item.expanded)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructItem(data) {
|
||||||
|
var $item = $('<div>'),
|
||||||
|
padding = (data.level + !data.items) * 16 - 8;
|
||||||
|
if (data.level || !data.items) {
|
||||||
|
$('<div>')
|
||||||
|
.addClass('OxCell OxTarget')
|
||||||
|
.css({
|
||||||
|
width: padding + 'px',
|
||||||
|
})
|
||||||
|
.appendTo($item);
|
||||||
|
}
|
||||||
|
if (data.items) {
|
||||||
|
$('<div>')
|
||||||
|
.addClass('OxCell')
|
||||||
|
.css({
|
||||||
|
width: '8px',
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
// fixme: need Ox.Icon()
|
||||||
|
$('<img>')
|
||||||
|
.addClass('OxToggle')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.getImagePath(
|
||||||
|
'symbol' + (data.expanded ? 'Down' : 'Right') + '.svg'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
padding: '3px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.appendTo($item);
|
||||||
|
}
|
||||||
|
$('<div>')
|
||||||
|
.addClass('OxCell OxTarget')
|
||||||
|
.css({
|
||||||
|
width: (self.options.width - padding - 32 + !data.items * 16) + 'px'
|
||||||
|
})
|
||||||
|
.html(data.title)
|
||||||
|
.appendTo($item);
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItemById(id, items, level) {
|
||||||
|
var items = items || self.options.items,
|
||||||
|
level = level || 0,
|
||||||
|
ret = null;
|
||||||
|
Ox.forEach(items, function(item) {
|
||||||
|
if (item.id == id) {
|
||||||
|
ret = $.extend(item, {
|
||||||
|
level: level
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (item.items) {
|
||||||
|
ret = getItemById(id, item.items, level + 1);
|
||||||
|
if (ret) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseData(key, value) {
|
||||||
|
//Ox.print('parseData', key, value)
|
||||||
|
var ret = {
|
||||||
|
id: key,
|
||||||
|
title: key.toString().split('.').pop()
|
||||||
|
},
|
||||||
|
type = Ox.typeOf(value);
|
||||||
|
if (type == 'array' || type == 'object') {
|
||||||
|
ret.title += ': ' + Ox.toTitleCase(Ox.typeOf(value));
|
||||||
|
ret.items = Ox.map(Ox.sort(Ox.keys(value)), function(k) {
|
||||||
|
return parseData(key + '.' + k, value[k]);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ret.title += ': ' + (
|
||||||
|
type == 'function' ?
|
||||||
|
value.toString().split('{')[0] :
|
||||||
|
JSON.stringify(value)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseItems(items, level) {
|
||||||
|
var items = items || self.options.items,
|
||||||
|
level = level || 0,
|
||||||
|
ret = [];
|
||||||
|
items.forEach(function(item, i) {
|
||||||
|
var item_ = $.extend({
|
||||||
|
level: level
|
||||||
|
}, item, item.items ? {
|
||||||
|
items: !!item.expanded ?
|
||||||
|
parseItems(item.items, level + 1) : []
|
||||||
|
} : {});
|
||||||
|
ret.push(item_);
|
||||||
|
item.items && $.merge(ret, item_.items);
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleItem(item, expanded) {
|
||||||
|
var $img, $item, pos;
|
||||||
|
item.expanded = expanded;
|
||||||
|
$.each(that.$element.find('.OxItem'), function(i, v) {
|
||||||
|
var $item = $(v);
|
||||||
|
if ($item.data('id') == item.id) {
|
||||||
|
$img = $item.find('img');
|
||||||
|
pos = $item.data('position');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ox.print('i.e', item.expanded)
|
||||||
|
$img.attr({
|
||||||
|
src: Ox.UI.getImagePath(
|
||||||
|
'symbol' + (item.expanded ? 'Down' : 'Right') + '.svg'
|
||||||
|
)
|
||||||
|
});
|
||||||
|
item.expanded ?
|
||||||
|
that.$element.addItems(pos + 1, parseItems(item.items, item.level + 1)) :
|
||||||
|
that.$element.removeItems(pos + 1, parseItems(item.items, item.level + 1).length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleItems(event, data) {
|
||||||
|
data.ids.forEach(function(id, i) {
|
||||||
|
var item = getItemById(id);
|
||||||
|
if (item.items && data.expanded != !!item.expanded) {
|
||||||
|
toggleItem(item, data.expanded);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'data') {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
4
source/js/Ox.URL.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/***
|
||||||
|
Ox.URL
|
||||||
|
***/
|
||||||
|
|
413
source/js/Ox.VideoEditorPlayer.js
Normal file
|
@ -0,0 +1,413 @@
|
||||||
|
Ox.VideoEditorPlayer = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
duration: 0,
|
||||||
|
find: '',
|
||||||
|
height: 0,
|
||||||
|
points: [0, 0],
|
||||||
|
position: 0,
|
||||||
|
posterFrame: 0,
|
||||||
|
size: 'small',
|
||||||
|
subtitles: [],
|
||||||
|
type: 'play',
|
||||||
|
url: '',
|
||||||
|
width: 0
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.addClass('OxVideoPlayer')
|
||||||
|
.css({
|
||||||
|
height: (self.options.height + 16) + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
self.controlsHeight = 16;
|
||||||
|
|
||||||
|
if (self.options.type == 'play') {
|
||||||
|
self.$video = new Ox.VideoElement({
|
||||||
|
height: self.options.height,
|
||||||
|
paused: true,
|
||||||
|
points: self.options.points,
|
||||||
|
position: self.options.position,
|
||||||
|
url: self.options.url,
|
||||||
|
width: self.options.width
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
paused: paused,
|
||||||
|
playing: playing
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
self.video = self.$video.$element[0];
|
||||||
|
} else {
|
||||||
|
self.$video = $('<img>')
|
||||||
|
.css({
|
||||||
|
height: self.options.height + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(that.$element)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.$subtitle = $('<div>')
|
||||||
|
.addClass('OxSubtitle')
|
||||||
|
.appendTo(that.$element);
|
||||||
|
|
||||||
|
setSubtitleSize();
|
||||||
|
|
||||||
|
self.$markerFrame = $('<div>')
|
||||||
|
.addClass('OxMarkerFrame')
|
||||||
|
.append(
|
||||||
|
$('<div>')
|
||||||
|
.addClass('OxFrame')
|
||||||
|
.css({
|
||||||
|
width: Math.floor((self.options.width - self.options.height) / 2) + 'px',
|
||||||
|
height: self.options.height + 'px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
$('<div>')
|
||||||
|
.addClass('OxPoster')
|
||||||
|
.css({
|
||||||
|
width: (self.options.height - 2) + 'px',
|
||||||
|
height: (self.options.height - 2) + 'px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
$('<div>')
|
||||||
|
.addClass('OxFrame')
|
||||||
|
.css({
|
||||||
|
width: Math.ceil((self.options.width - self.options.height) / 2) + 'px',
|
||||||
|
height: self.options.height + 'px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.hide()
|
||||||
|
.appendTo(that.$element);
|
||||||
|
|
||||||
|
self.$markerPoint = {};
|
||||||
|
['in', 'out'].forEach(function(point, i) {
|
||||||
|
self.$markerPoint[point] = {};
|
||||||
|
['top', 'bottom'].forEach(function(edge) {
|
||||||
|
var titleCase = Ox.toTitleCase(point) + Ox.toTitleCase(edge);
|
||||||
|
self.$markerPoint[point][edge] = $('<img>')
|
||||||
|
.addClass('OxMarkerPoint OxMarker' + titleCase)
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/ox.ui/videoMarker' + titleCase + '.png'
|
||||||
|
})
|
||||||
|
.hide()
|
||||||
|
.appendTo(that.$element);
|
||||||
|
if (self.options.points[i] == self.options.position) {
|
||||||
|
self.$markerPoint[point][edge].show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$controls = new Ox.Bar({
|
||||||
|
size: self.controlsHeight
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
marginTop: '-2px'
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
|
||||||
|
if (self.options.type == 'play') {
|
||||||
|
// fixme: $buttonPlay etc. ?
|
||||||
|
self.$playButton = new Ox.Button({
|
||||||
|
id: self.options.id + 'Play',
|
||||||
|
title: [
|
||||||
|
{id: 'play', title: 'play'},
|
||||||
|
{id: 'pause', title: 'pause'}
|
||||||
|
],
|
||||||
|
tooltip: ['Play', 'Pause'],
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent('click', togglePlay)
|
||||||
|
.appendTo(self.$controls);
|
||||||
|
self.$playInToOutButton = new Ox.Button({
|
||||||
|
id: self.options.id + 'PlayInToOut',
|
||||||
|
title: 'PlayInToOut',
|
||||||
|
tooltip: 'Play In to Out',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent('click', function() {
|
||||||
|
that.playInToOut();
|
||||||
|
})
|
||||||
|
.appendTo(self.$controls);
|
||||||
|
self.$muteButton = new Ox.Button({
|
||||||
|
id: self.options.id + 'Mute',
|
||||||
|
title: [
|
||||||
|
{id: 'mute', title: 'mute'},
|
||||||
|
{id: 'unmute', title: 'unmute'}
|
||||||
|
],
|
||||||
|
tooltip: ['Mute', 'Unmute'],
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent('click', toggleMute)
|
||||||
|
.appendTo(self.$controls);
|
||||||
|
self.$sizeButton = new Ox.Button({
|
||||||
|
id: self.options.id + 'Size',
|
||||||
|
title: self.options.size == 'small' ? [
|
||||||
|
{id: 'large', title: 'grow'},
|
||||||
|
{id: 'small', title: 'shrink'}
|
||||||
|
] : [
|
||||||
|
{id: 'small', title: 'shrink'},
|
||||||
|
{id: 'large', title: 'grow'}
|
||||||
|
],
|
||||||
|
tooltip: ['Larger', 'Smaller'],
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent('click', toggleSize)
|
||||||
|
.appendTo(self.$controls);
|
||||||
|
} else {
|
||||||
|
self.$goToPointButton = new Ox.Button({
|
||||||
|
id: self.options.id + 'GoTo' + Ox.toTitleCase(self.options.type),
|
||||||
|
title: 'GoTo' + Ox.toTitleCase(self.options.type),
|
||||||
|
tooltip: 'Go to ' + Ox.toTitleCase(self.options.type) + ' Point',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent('click', goToPoint)
|
||||||
|
.appendTo(self.$controls);
|
||||||
|
self.$setPointButton = new Ox.Button({
|
||||||
|
id: self.options.id + 'Set' + Ox.toTitleCase(self.options.type),
|
||||||
|
title: 'Set' + Ox.toTitleCase(self.options.type),
|
||||||
|
tooltip: 'Set ' + Ox.toTitleCase(self.options.type) + ' Point',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent('click', setPoint)
|
||||||
|
.appendTo(self.$controls);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.$positionInput = new Ox.TimeInput({
|
||||||
|
milliseconds: true,
|
||||||
|
seconds: true,
|
||||||
|
value: Ox.formatDuration(self.options.position, 3)
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'right',
|
||||||
|
})
|
||||||
|
.appendTo(self.$controls)
|
||||||
|
|
||||||
|
// fixme: strange positioning hack
|
||||||
|
self.$positionInput.css({
|
||||||
|
width: '98px'
|
||||||
|
});
|
||||||
|
$.browser.mozilla && self.$positionInput.css({
|
||||||
|
marginTop: '-19px'
|
||||||
|
});
|
||||||
|
// fixme: children doesnt work w/o $element
|
||||||
|
self.$positionInput.$element.children('.OxLabel').each(function(i, element) {
|
||||||
|
$(this).css({
|
||||||
|
width: '22px',
|
||||||
|
marginLeft: (i == 0 ? 8 : 0) + 'px',
|
||||||
|
background: 'rgb(32, 32, 32)'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
self.$positionInput.$element.children('div.OxInput').each(function(i) {
|
||||||
|
var marginLeft = [-82, -58, -34, -10];
|
||||||
|
$(this).css({
|
||||||
|
marginLeft: marginLeft[i] + 'px'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (self.options.type == 'play') {
|
||||||
|
self.$loadingIcon = new Ox.LoadingIcon()
|
||||||
|
.appendTo(that)
|
||||||
|
.start();
|
||||||
|
self.loadingInterval = setInterval(function() {
|
||||||
|
if (self.video.readyState) {
|
||||||
|
clearInterval(self.loadingInterval);
|
||||||
|
self.$loadingIcon.stop();
|
||||||
|
setPosition();
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
} else {
|
||||||
|
setPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubtitle() {
|
||||||
|
var subtitle = '';
|
||||||
|
Ox.forEach(self.options.subtitles, function(v) {
|
||||||
|
if (v['in'] <= self.options.position && v['out'] > self.options.position) {
|
||||||
|
subtitle = v.value;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return subtitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
function goToPoint() {
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
position: self.options.points[self.options.type == 'in' ? 0 : 1]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function paused(event, data) {
|
||||||
|
self.$playButton.toggleTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
function playing(event, data) {
|
||||||
|
self.options.position = data.position;
|
||||||
|
setMarkers();
|
||||||
|
setSubtitle();
|
||||||
|
self.$positionInput.options({
|
||||||
|
value: Ox.formatDuration(self.options.position, 3)
|
||||||
|
});
|
||||||
|
that.triggerEvent('playing', {
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHeight() {
|
||||||
|
that.css({
|
||||||
|
height: (self.options.height + 16) + 'px'
|
||||||
|
});
|
||||||
|
self.options.type == 'play' ? self.$video.options({
|
||||||
|
height: self.options.height
|
||||||
|
}) : self.$video.css({
|
||||||
|
height: self.options.height + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMarkers() {
|
||||||
|
self.options.position == self.options.posterFrame ?
|
||||||
|
self.$markerFrame.show() : self.$markerFrame.hide();
|
||||||
|
Ox.forEach(self.$markerPoint, function(markers, point) {
|
||||||
|
Ox.forEach(markers, function(marker) {
|
||||||
|
self.options.position == self.options.points[point == 'in' ? 0 : 1] ?
|
||||||
|
marker.show() : marker.hide();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPoint() {
|
||||||
|
var data = {};
|
||||||
|
self.options.points[self.options.type == 'in' ? 0 : 1] = self.options.position;
|
||||||
|
setMarkers();
|
||||||
|
data[self.options.type] = self.options.position;
|
||||||
|
that.triggerEvent('set', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPosition() {
|
||||||
|
var position = Ox.limit(
|
||||||
|
self.options.position - (self.options.type == 'out' ? 0.01 : 0),
|
||||||
|
0, self.options.duration - 0.01
|
||||||
|
),
|
||||||
|
url;
|
||||||
|
if (self.options.type == 'play') {
|
||||||
|
self.$video.position(self.options.position);
|
||||||
|
} else {
|
||||||
|
self.$loadingIcon && self.$loadingIcon.stop();
|
||||||
|
url = self.options.url(position);
|
||||||
|
if (self.$video.attr('src') != url) {
|
||||||
|
self.$loadingIcon = new Ox.LoadingIcon()
|
||||||
|
.appendTo(that)
|
||||||
|
.start();
|
||||||
|
self.$video.attr({
|
||||||
|
src: url
|
||||||
|
})
|
||||||
|
.load(self.$loadingIcon.stop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setMarkers();
|
||||||
|
setSubtitle();
|
||||||
|
self.$positionInput.options({
|
||||||
|
value: Ox.formatDuration(self.options.position, 3)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSubtitle() {
|
||||||
|
var subtitle = getSubtitle();
|
||||||
|
if (subtitle != self.subtitle) {
|
||||||
|
self.subtitle = subtitle;
|
||||||
|
self.$subtitle.html(Ox.highlight(self.subtitle, self.options.find).replace(/\n/g, '<br/>'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSubtitleSize() {
|
||||||
|
self.$subtitle.css({
|
||||||
|
bottom: parseInt(self.controlsHeight + self.options.height / 16) + 'px',
|
||||||
|
width: self.options.width + 'px',
|
||||||
|
fontSize: parseInt(self.options.height / 20) + 'px',
|
||||||
|
WebkitTextStroke: (self.options.height / 1000) + 'px rgb(0, 0, 0)'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWidth() {
|
||||||
|
that.css({
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
self.options.type == 'play' ? self.$video.options({
|
||||||
|
width: self.options.width
|
||||||
|
}) : self.$video.css({
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
});
|
||||||
|
setSubtitleSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMute() {
|
||||||
|
self.$video.toggleMute();
|
||||||
|
}
|
||||||
|
|
||||||
|
function togglePlay() {
|
||||||
|
self.video.paused ? that.play() : that.pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSize(event, data) {
|
||||||
|
self.options.size = data.id
|
||||||
|
that.triggerEvent('togglesize', {
|
||||||
|
size: self.options.size
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'height') {
|
||||||
|
setHeight();
|
||||||
|
} else if (key == 'points') {
|
||||||
|
setMarkers();
|
||||||
|
} else if (key == 'position') {
|
||||||
|
setPosition();
|
||||||
|
} else if (key == 'posterFrame') {
|
||||||
|
setMarkers();
|
||||||
|
} else if (key == 'width') {
|
||||||
|
setWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.mute = function() {
|
||||||
|
self.$video.mute();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.pause = function() {
|
||||||
|
self.$video.pause();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.play = function() {
|
||||||
|
self.$video.play();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.playInToOut = function() {
|
||||||
|
self.$video.paused() && self.$playButton.toggleTitle();
|
||||||
|
self.$video.playInToOut();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggleMute = function() {
|
||||||
|
self.$muteButton.trigger('click');
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.togglePlay = function() {
|
||||||
|
self.$playButton.trigger('click');
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.unmute = function() {
|
||||||
|
self.$video.unmute();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
158
source/js/Ox.VideoElement.js
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
Ox.VideoElement = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('video', self)
|
||||||
|
.defaults({
|
||||||
|
fps: 25,
|
||||||
|
height: 0,
|
||||||
|
loop: false,
|
||||||
|
muted: false,
|
||||||
|
paused: false,
|
||||||
|
playInToOut: false,
|
||||||
|
points: [0, 0],
|
||||||
|
position: 0,
|
||||||
|
poster: '',
|
||||||
|
url: '',
|
||||||
|
width: 0
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.attr({
|
||||||
|
poster: self.options.poster,
|
||||||
|
preload: 'auto',
|
||||||
|
src: self.options.url
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
height: self.options.height + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
})
|
||||||
|
.bind({
|
||||||
|
ended: ended,
|
||||||
|
loadedmetadata: function() {
|
||||||
|
self.video.currentTime = self.options.position;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
millisecondsPerFrame: 1000 / self.options.fps,
|
||||||
|
video: that.$element[0]
|
||||||
|
});
|
||||||
|
|
||||||
|
function ended() {
|
||||||
|
that.pause()
|
||||||
|
.triggerEvent('paused', {
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function playing() {
|
||||||
|
var event = 'playing';
|
||||||
|
self.options.position = Math.round(self.video.currentTime * self.options.fps) / self.options.fps;
|
||||||
|
if (self.options.playInToOut && self.options.position >= self.options.points[1]) {
|
||||||
|
event = 'paused';
|
||||||
|
that.position(self.options.points[1]).pause();
|
||||||
|
}
|
||||||
|
that.triggerEvent(event, {
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'height') {
|
||||||
|
that.size(self.options.width, value);
|
||||||
|
} else if (key == 'muted') {
|
||||||
|
that[value ? 'mute' : 'unmute']();
|
||||||
|
} else if (key == 'paused') {
|
||||||
|
that[value ? 'pause' : 'play']();
|
||||||
|
} else if (key == 'points') {
|
||||||
|
that.points(value);
|
||||||
|
} else if (key == 'width') {
|
||||||
|
that.size(value, self.options.height);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.mute = function() {
|
||||||
|
self.options.muted = true;
|
||||||
|
self.video.muted = true;
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.muted = function() {
|
||||||
|
return self.options.muted;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.pause = function() {
|
||||||
|
self.options.paused = true;
|
||||||
|
self.options.playInToOut = false;
|
||||||
|
self.video.pause();
|
||||||
|
clearInterval(self.playInterval);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.paused = function() {
|
||||||
|
return self.options.paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.play = function() {
|
||||||
|
self.options.paused = false;
|
||||||
|
self.video.play();
|
||||||
|
self.playInterval = setInterval(playing, self.millisecondsPerFrame);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.playInToOut = function() {
|
||||||
|
self.options.playInToOut = true;
|
||||||
|
that.position(self.options.points[0]);
|
||||||
|
self.options.paused && that.play();
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
that.points = function(points) {
|
||||||
|
self.options.points = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.position = function(pos) {
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
return self.video.currentTime;
|
||||||
|
} else {
|
||||||
|
self.options.position = pos;
|
||||||
|
self.video.currentTime = self.options.position;
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.size = function(width, height) {
|
||||||
|
// fixme: why options? use css!
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
return {
|
||||||
|
width: self.options.width,
|
||||||
|
height: self.options.height
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
self.options.width = width;
|
||||||
|
self.options.height = height;
|
||||||
|
that.css({
|
||||||
|
width: width + 'px',
|
||||||
|
height: height + 'px'
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggleMute = function() {
|
||||||
|
self.video.muted = !self.video.muted;
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
that.togglePlay = function() {
|
||||||
|
self.options.paused = !self.options.paused;
|
||||||
|
that[self.options.paused ? 'pause' : 'play']();
|
||||||
|
}
|
||||||
|
|
||||||
|
that.unmute = function() {
|
||||||
|
self.video.muted = false;
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
421
source/js/Ox.VideoPanelPlayer.js
Normal file
|
@ -0,0 +1,421 @@
|
||||||
|
Ox.VideoPanelPlayer = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
annotationsSize: 256,
|
||||||
|
duration: 0,
|
||||||
|
height: 0,
|
||||||
|
loop: false,
|
||||||
|
muted: false,
|
||||||
|
paused: false,
|
||||||
|
playInToOut: false,
|
||||||
|
points: [0, 0],
|
||||||
|
position: 0,
|
||||||
|
poster: '',
|
||||||
|
showAnnotations: true,
|
||||||
|
showControls: true,
|
||||||
|
subtitles: [],
|
||||||
|
videoHeight: 0,
|
||||||
|
videoSize: 'fit',
|
||||||
|
videoWidth: 0,
|
||||||
|
videoURL: '',
|
||||||
|
width: 0
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.css({
|
||||||
|
height: self.options.height + 'px',
|
||||||
|
width: self.options.width + 'px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
resize: resizeElement,
|
||||||
|
key_shift_a: function() {
|
||||||
|
that.toggleAnnotations();
|
||||||
|
},
|
||||||
|
key_shift_c: function() {
|
||||||
|
that.toggleControls();
|
||||||
|
},
|
||||||
|
key_shift_s: function() {
|
||||||
|
that.toggleSize();
|
||||||
|
},
|
||||||
|
key_space: function() {
|
||||||
|
that.togglePlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
fullscreen: false,
|
||||||
|
videoCSS: getVideoCSS()
|
||||||
|
});
|
||||||
|
//alert(JSON.stringify([self.playerHeight, self.playerWidth, self.videoCSS]))
|
||||||
|
|
||||||
|
self.$player = new Ox.Element()
|
||||||
|
.css({
|
||||||
|
overflowX: 'hidden',
|
||||||
|
overflowY: 'hidden'
|
||||||
|
})
|
||||||
|
.bind({
|
||||||
|
mousedown: that.gainFocus
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
resize: resizeVideo
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$video = new Ox.VideoElement({
|
||||||
|
height: self.videoCSS.height,
|
||||||
|
paused: true,
|
||||||
|
points: self.options.points,
|
||||||
|
position: self.options.position,
|
||||||
|
url: self.options.videoURL,
|
||||||
|
width: self.videoCSS.width
|
||||||
|
})
|
||||||
|
.css(self.videoCSS)
|
||||||
|
.bindEvent({
|
||||||
|
paused: paused,
|
||||||
|
playing: playing
|
||||||
|
})
|
||||||
|
.appendTo(self.$player);
|
||||||
|
|
||||||
|
self.$controls = new Ox.Element()
|
||||||
|
.bindEvent({
|
||||||
|
toggle: toggleControls
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$buttons = new Ox.Element()
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
width: '16px',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$controls);
|
||||||
|
|
||||||
|
self.$button = {
|
||||||
|
play: new Ox.Button({
|
||||||
|
id: 'play',
|
||||||
|
title: [
|
||||||
|
{id: 'play', title: 'play'},
|
||||||
|
{id: 'pause', title: 'pause'}
|
||||||
|
],
|
||||||
|
tooltip: ['Play', 'Pause'],
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: self.$video.togglePlay
|
||||||
|
}),
|
||||||
|
mute: new Ox.Button({
|
||||||
|
id: 'mute',
|
||||||
|
title: [
|
||||||
|
{id: 'mute', title: 'mute'},
|
||||||
|
{id: 'unmute', title: 'unmute'}
|
||||||
|
],
|
||||||
|
tooltip: ['Mute', 'Unmute'],
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: self.$video.toggleMute
|
||||||
|
}),
|
||||||
|
size: new Ox.Button({
|
||||||
|
id: 'size',
|
||||||
|
title: self.options.videoSize == 'fit' ? [
|
||||||
|
{id: 'fill', title: 'fill'},
|
||||||
|
{id: 'fit', title: 'fit'}
|
||||||
|
] : [
|
||||||
|
{id: 'fit', title: 'fit'},
|
||||||
|
{id: 'fill', title: 'fill'}
|
||||||
|
],
|
||||||
|
tooltip: self.options.videoSize == 'fit' ? [
|
||||||
|
'Fill Screen', 'Fit to Screen'
|
||||||
|
] : [
|
||||||
|
'Fit to Screen', 'Fill Screen'
|
||||||
|
],
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: toggleSize
|
||||||
|
}),
|
||||||
|
fullscreen: new Ox.Button({
|
||||||
|
id: 'size',
|
||||||
|
title: [
|
||||||
|
{id: 'grow', title: 'grow'},
|
||||||
|
{id: 'shrink', title: 'shrink'}
|
||||||
|
],
|
||||||
|
tooltip: [
|
||||||
|
'Enter Fullscreen', 'Exit Fullscreen'
|
||||||
|
],
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: toggleFullscreen
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var i = 0;
|
||||||
|
Ox.forEach(self.$button, function($button) {
|
||||||
|
$button.css({
|
||||||
|
position: 'absolute',
|
||||||
|
left: '8px',
|
||||||
|
top: (8 + i++ * 24) + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$buttons);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$timelines = new Ox.Element()
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
.appendTo(self.$controls);
|
||||||
|
|
||||||
|
self.$timeline = {
|
||||||
|
large: new Ox.LargeTimeline({
|
||||||
|
duration: self.options.duration,
|
||||||
|
position: self.options.position,
|
||||||
|
subtitles: self.options.subtitles,
|
||||||
|
videoId: self.options.videoId,
|
||||||
|
width: getTimelineWidth()
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
top: '4px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: changeLargeTimeline
|
||||||
|
}),
|
||||||
|
small: new Ox.SmallTimeline({
|
||||||
|
duration: self.options.duration,
|
||||||
|
position: self.options.position,
|
||||||
|
subtitles: self.options.subtitles,
|
||||||
|
videoId: self.options.videoId,
|
||||||
|
width: getTimelineWidth()
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
top: '76px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: changeSmallTimeline
|
||||||
|
})
|
||||||
|
};
|
||||||
|
Ox.forEach(self.$timeline, function($timeline) {
|
||||||
|
$timeline.appendTo(self.$timelines);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$panel = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: self.$player
|
||||||
|
},
|
||||||
|
{
|
||||||
|
collapsed: !self.options.showControls,
|
||||||
|
collapsible: true,
|
||||||
|
element: self.$controls,
|
||||||
|
size: 104
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'vertical'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
resize: resizePanel
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$annotations = new Ox.Element()
|
||||||
|
.bindEvent({
|
||||||
|
resize: resizeAnnotations,
|
||||||
|
resizeend: resizeendAnnotations,
|
||||||
|
toggle: toggleAnnotations
|
||||||
|
});
|
||||||
|
|
||||||
|
that.$element = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: self.$panel
|
||||||
|
},
|
||||||
|
{
|
||||||
|
collapsed: !self.options.showAnnotations,
|
||||||
|
collapsible: true,
|
||||||
|
element: self.$annotations,
|
||||||
|
resizable: true,
|
||||||
|
resize: [192, 256, 320, 384],
|
||||||
|
size: self.options.annotationsSize
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'horizontal'
|
||||||
|
});
|
||||||
|
|
||||||
|
function changeLargeTimeline(event, data) {
|
||||||
|
self.options.position = data.position;
|
||||||
|
self.$video.position(self.options.position);
|
||||||
|
self.$timeline.small.options({
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeSmallTimeline(event, data) {
|
||||||
|
self.options.position = data.position;
|
||||||
|
self.$video.position(self.options.position);
|
||||||
|
self.$timeline.large.options({
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlayerHeight() {
|
||||||
|
return self.options.height -
|
||||||
|
self.options.showControls * 104 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlayerWidth() {
|
||||||
|
return self.options.width -
|
||||||
|
(self.options.showAnnotations && !self.fullscreen) *
|
||||||
|
self.options.annotationsSize - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimelineWidth() {
|
||||||
|
return self.options.width -
|
||||||
|
(self.options.showAnnotations && !self.fullscreen) *
|
||||||
|
self.options.annotationsSize - 40
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVideoCSS() {
|
||||||
|
var width = getPlayerWidth(),
|
||||||
|
height = getPlayerHeight(),
|
||||||
|
ratio = width / height,
|
||||||
|
videoRatio = self.options.videoWidth / self.options.videoHeight,
|
||||||
|
isWide = ratio < videoRatio;
|
||||||
|
return self.options.videoSize == 'fit' ? {
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
width: (isWide ? width : Math.round(height * videoRatio)) + 'px',
|
||||||
|
height: (isWide ? Math.round(width / videoRatio) : height) + 'px',
|
||||||
|
margin: 'auto'
|
||||||
|
} : {
|
||||||
|
width: (isWide ? Math.round(height * videoRatio) : width) + 'px',
|
||||||
|
height: (isWide ? height : Math.round(width / videoRatio)) + 'px',
|
||||||
|
margin: [
|
||||||
|
isWide ? '0' : Math.floor((height - width / videoRatio) / 2) + 'px',
|
||||||
|
isWide ? Math.ceil((width - height * videoRatio) / 2) + 'px' : '0',
|
||||||
|
isWide ? '0' : Math.ceil((height - width / videoRatio) / 2) + 'px',
|
||||||
|
isWide ? Math.floor((width - height * videoRatio) / 2) + 'px' : '0'
|
||||||
|
].join(' ')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function paused() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function playing(event, data) {
|
||||||
|
self.options.position = data.position;
|
||||||
|
self.$timeline.large.options({
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
self.$timeline.small.options({
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeAnnotations(event, data) {
|
||||||
|
self.options.annotationsSize = data;
|
||||||
|
resizeVideoAndControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeendAnnotations(event, data) {
|
||||||
|
self.options.annotationsSize = data;
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
annotationsSize: self.options.annotationsSize
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeControls() {
|
||||||
|
self.$timeline.large.options({
|
||||||
|
width: getTimelineWidth()
|
||||||
|
});
|
||||||
|
self.$timeline.small.options({
|
||||||
|
width: getTimelineWidth()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeElement(event, data) {
|
||||||
|
// called on browser toggle
|
||||||
|
self.options.height = data;
|
||||||
|
resizeVideo();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizePanel(event, data) {
|
||||||
|
// called on annotations toggle
|
||||||
|
resizeVideoAndControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeVideoAndControls() {
|
||||||
|
resizeVideo();
|
||||||
|
resizeControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeVideo() {
|
||||||
|
self.videoCSS = getVideoCSS();
|
||||||
|
self.$video.css(self.videoCSS);
|
||||||
|
};
|
||||||
|
|
||||||
|
function toggleAnnotations(event, data) {
|
||||||
|
self.options.showAnnotations = !data.collapsed;
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
showAnnotations: self.options.showAnnotations
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleControls(event, data) {
|
||||||
|
self.options.showControls = !data.collapsed;
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
showControls: self.options.showControls
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleFullscreen() {
|
||||||
|
self.fullscreen = !self.fullscreen;
|
||||||
|
self.options.showAnnotations && that.$element.toggle(1);
|
||||||
|
self.fullscreen && self.options.showControls && self.$panel.toggle(1);
|
||||||
|
that.triggerEvent((self.fullscreen ? 'enter' : 'exit') + 'fullscreen', {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSize() {
|
||||||
|
self.options.videoSize = self.options.videoSize == 'fit' ? 'fill' : 'fit';
|
||||||
|
resizeVideo();
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
videoSize: self.options.videoSize
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'height') {
|
||||||
|
resizeVideo();
|
||||||
|
} else if (key == 'position') {
|
||||||
|
self.$video.position(value);
|
||||||
|
} else if (key == 'width') {
|
||||||
|
resizeVideoAndControls();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
that.toggleAnnotations = function() {
|
||||||
|
that.$element.toggle(1);
|
||||||
|
//that.toggleAnnotations(null, !self.options.showAnnotations);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggleControls = function() {
|
||||||
|
self.$panel.toggle(1);
|
||||||
|
//that.toggleControls(null, !self.options.showControls);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggleMute = function() {
|
||||||
|
self.$button.mute.trigger('click');
|
||||||
|
};
|
||||||
|
|
||||||
|
that.togglePlay = function() {
|
||||||
|
self.$button.play.trigger('click');
|
||||||
|
};
|
||||||
|
|
||||||
|
that.toggleSize = function() {
|
||||||
|
self.$button.size.trigger('click');
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
}
|
588
source/js/Ox.VideoPlayer.js
Normal file
|
@ -0,0 +1,588 @@
|
||||||
|
Ox.VideoEditor = function(options, self) {
|
||||||
|
|
||||||
|
var self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
annotationsSize: 0,
|
||||||
|
cuts: [],
|
||||||
|
duration: 0,
|
||||||
|
find: '',
|
||||||
|
frameURL: function() {},
|
||||||
|
fps: 25, // fixme: doesn't get handed through to player
|
||||||
|
height: 0,
|
||||||
|
largeTimeline: true,
|
||||||
|
layers: [],
|
||||||
|
matches: [],
|
||||||
|
points: [0, 0],
|
||||||
|
position: 0,
|
||||||
|
posterFrame: 0,
|
||||||
|
showAnnotations: false,
|
||||||
|
subtitles: [],
|
||||||
|
videoHeight: 0,
|
||||||
|
videoId: '',
|
||||||
|
videoWidth: 0,
|
||||||
|
videoSize: 'small',
|
||||||
|
videoURL: '',
|
||||||
|
width: 0
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
.mousedown(function() {
|
||||||
|
that.gainFocus();
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
key_shift_0: function() {
|
||||||
|
movePositionBy(-self.options.position);
|
||||||
|
},
|
||||||
|
key_alt_left: function() {
|
||||||
|
},
|
||||||
|
key_alt_right: function() {
|
||||||
|
},
|
||||||
|
key_alt_shift_left: function() {
|
||||||
|
},
|
||||||
|
key_alt_shift_right: function() {
|
||||||
|
},
|
||||||
|
key_backslash: function() {
|
||||||
|
select('subtitle');
|
||||||
|
},
|
||||||
|
key_closebracket: function() {
|
||||||
|
movePositionTo('subtitle', 1);
|
||||||
|
},
|
||||||
|
key_comma: function() {
|
||||||
|
movePositionTo('cut', -1);
|
||||||
|
},
|
||||||
|
key_dot: function() {
|
||||||
|
movePositionTo('cut', 1);
|
||||||
|
},
|
||||||
|
key_down: function() {
|
||||||
|
movePositionBy(self.sizes.timeline[0].width);
|
||||||
|
},
|
||||||
|
key_i: function() {
|
||||||
|
setPoint('in');
|
||||||
|
},
|
||||||
|
key_left: function() {
|
||||||
|
movePositionBy(-1);
|
||||||
|
},
|
||||||
|
key_m: toggleMute,
|
||||||
|
key_o: function() {
|
||||||
|
setPoint('out');
|
||||||
|
},
|
||||||
|
key_openbracket: function() {
|
||||||
|
movePositionTo('subtitle', -1);
|
||||||
|
},
|
||||||
|
key_p: playInToOut,
|
||||||
|
key_right: function() {
|
||||||
|
movePositionBy(1);
|
||||||
|
},
|
||||||
|
key_s: function() {
|
||||||
|
// toggleSize
|
||||||
|
},
|
||||||
|
key_shift_comma: function() {
|
||||||
|
movePositionTo('match', -1)
|
||||||
|
},
|
||||||
|
key_shift_dot: function() {
|
||||||
|
movePositionTo('match', 1)
|
||||||
|
},
|
||||||
|
key_shift_down: function() {
|
||||||
|
movePositionBy(self.options.duration);
|
||||||
|
},
|
||||||
|
key_shift_left: function() {
|
||||||
|
movePositionBy(-0.04);
|
||||||
|
//movePositionBy(-60);
|
||||||
|
},
|
||||||
|
key_shift_i: function() {
|
||||||
|
goToPoint('in');
|
||||||
|
},
|
||||||
|
key_shift_o: function() {
|
||||||
|
goToPoint('out');
|
||||||
|
},
|
||||||
|
key_shift_right: function() {
|
||||||
|
movePositionBy(0.04);
|
||||||
|
//movePositionBy(60);
|
||||||
|
},
|
||||||
|
key_shift_up: function() {
|
||||||
|
movePositionBy(-self.options.duration);
|
||||||
|
},
|
||||||
|
key_slash: function() {
|
||||||
|
select('cut');
|
||||||
|
},
|
||||||
|
key_space: togglePlay,
|
||||||
|
key_up: function() {
|
||||||
|
movePositionBy(-self.sizes.timeline[0].width);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend(self, {
|
||||||
|
$player: [],
|
||||||
|
$timeline: [],
|
||||||
|
controlsHeight: 16,
|
||||||
|
margin: 8,
|
||||||
|
videoRatio: self.options.videoWidth / self.options.videoHeight
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$editor = new Ox.Element()
|
||||||
|
.addClass('OxVideoEditor')
|
||||||
|
.click(function() {
|
||||||
|
that.gainFocus()
|
||||||
|
});
|
||||||
|
|
||||||
|
self.sizes = getSizes();
|
||||||
|
|
||||||
|
['play', 'in', 'out'].forEach(function(type, i) {
|
||||||
|
self.$player[i] = new Ox.VideoEditorPlayer({
|
||||||
|
duration: self.options.duration,
|
||||||
|
find: self.options.find,
|
||||||
|
height: self.sizes.player[i].height,
|
||||||
|
id: 'player' + Ox.toTitleCase(type),
|
||||||
|
points: self.options.points,
|
||||||
|
position: type == 'play' ? self.options.position : self.options.points[type == 'in' ? 0 : 1],
|
||||||
|
posterFrame: self.options.posterFrame,
|
||||||
|
subtitles: self.options.subtitles,
|
||||||
|
type: type,
|
||||||
|
url: type == 'play' ? self.options.videoURL : self.options.frameURL,
|
||||||
|
width: self.sizes.player[i].width
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: self.sizes.player[i].left + 'px',
|
||||||
|
top: self.sizes.player[i].top + 'px'
|
||||||
|
})
|
||||||
|
.bindEvent(type == 'play' ? {
|
||||||
|
playing: changePlayer,
|
||||||
|
togglesize: toggleSize
|
||||||
|
} : {
|
||||||
|
change: function() {
|
||||||
|
goToPoint(type);
|
||||||
|
},
|
||||||
|
set: function() {
|
||||||
|
setPoint(type);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(self.$editor);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$timeline[0] = new Ox.LargeTimeline({
|
||||||
|
cuts: self.options.cuts,
|
||||||
|
duration: self.options.duration,
|
||||||
|
find: self.options.find,
|
||||||
|
id: 'timelineLarge',
|
||||||
|
matches: self.options.matches,
|
||||||
|
points: self.options.points,
|
||||||
|
position: self.options.position,
|
||||||
|
subtitles: self.options.subtitles,
|
||||||
|
videoId: self.options.videoId,
|
||||||
|
width: self.sizes.timeline[0].width
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: self.sizes.timeline[0].left + 'px',
|
||||||
|
top: self.sizes.timeline[0].top + 'px'
|
||||||
|
})
|
||||||
|
.bindEvent('change', changeTimelineLarge)
|
||||||
|
.bindEvent('changeEnd', changeTimelineLarge)
|
||||||
|
.appendTo(self.$editor);
|
||||||
|
|
||||||
|
self.$timeline[1] = new Ox.BlockTimeline({
|
||||||
|
cuts: self.options.cuts,
|
||||||
|
duration: self.options.duration,
|
||||||
|
find: self.options.find,
|
||||||
|
id: 'timelineSmall',
|
||||||
|
matches: self.options.matches,
|
||||||
|
points: self.options.points,
|
||||||
|
position: self.options.position,
|
||||||
|
subtitles: self.options.subtitles,
|
||||||
|
videoId: self.options.videoId,
|
||||||
|
width: self.sizes.timeline[1].width
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: self.sizes.timeline[1].left + 'px',
|
||||||
|
top: self.sizes.timeline[1].top + 'px'
|
||||||
|
})
|
||||||
|
.bindEvent('change', changeTimelineSmall)
|
||||||
|
.appendTo(self.$editor);
|
||||||
|
|
||||||
|
self.$annotations = new Ox.Element()
|
||||||
|
.css({
|
||||||
|
overflowY: 'auto'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
resize: resizeAnnotations,
|
||||||
|
toggle: toggleAnnotations
|
||||||
|
});
|
||||||
|
self.$annotationPanel = [];
|
||||||
|
|
||||||
|
self.options.layers.forEach(function(layer, i) {
|
||||||
|
self.$annotationPanel[i] = new Ox.AnnotationPanel(
|
||||||
|
$.extend({
|
||||||
|
width: self.options.annotationSize
|
||||||
|
}, layer)
|
||||||
|
)
|
||||||
|
.bindEvent({
|
||||||
|
add: function(event, data) {
|
||||||
|
data.layer = layer.id;
|
||||||
|
data['in'] = self.options.points[0];
|
||||||
|
data.out = self.options.points[1];
|
||||||
|
that.triggerEvent('addAnnotation', data);
|
||||||
|
},
|
||||||
|
'delete': function(event, data) {
|
||||||
|
data.layer = layer.id;
|
||||||
|
that.triggerEvent('removeAnnotations', data);
|
||||||
|
},
|
||||||
|
select: function(event, data) {
|
||||||
|
self.options.layers.forEach(function(l, j) { // fixme: l? j?
|
||||||
|
if(l.id != layer.id) {
|
||||||
|
self.$annotationPanel[j].deselectItems();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
selectAnnotation(event, data);
|
||||||
|
},
|
||||||
|
submit: updateAnnotation
|
||||||
|
});
|
||||||
|
self.$annotationPanel[i]
|
||||||
|
.appendTo(self.$annotations);
|
||||||
|
});
|
||||||
|
|
||||||
|
that.$element = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: self.$editor
|
||||||
|
},
|
||||||
|
{
|
||||||
|
collapsed: !self.options.showAnnotations,
|
||||||
|
collapsible: true,
|
||||||
|
element: self.$annotations,
|
||||||
|
resizable: true,
|
||||||
|
resize: [192, 256, 320, 384],
|
||||||
|
size: self.options.annotationsSize
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'horizontal'
|
||||||
|
});
|
||||||
|
|
||||||
|
function changePlayer(event, data) {
|
||||||
|
self.options.position = data.position;
|
||||||
|
self.$timeline[0].options({
|
||||||
|
position: data.position
|
||||||
|
});
|
||||||
|
self.$timeline[1].options({
|
||||||
|
position: data.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeTimelineLarge(event, data) {
|
||||||
|
self.options.position = data.position;
|
||||||
|
self.$player[0].options({
|
||||||
|
position: data.position
|
||||||
|
});
|
||||||
|
self.$timeline[1].options({
|
||||||
|
position: data.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeTimelineSmall(event, data) {
|
||||||
|
self.options.position = data.position;
|
||||||
|
self.$player[0].options({
|
||||||
|
position: data.position
|
||||||
|
});
|
||||||
|
self.$timeline[0].options({
|
||||||
|
position: data.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNextPosition(type, direction) {
|
||||||
|
var found = false,
|
||||||
|
position = 0,
|
||||||
|
positions;
|
||||||
|
if (type == 'cut') {
|
||||||
|
positions = self.options.cuts;
|
||||||
|
} else if (type == 'match') {
|
||||||
|
positions = $.map(self.options.matches, function(v, i) {
|
||||||
|
return self.options.subtitles[v]['in'];
|
||||||
|
});
|
||||||
|
} else if (type == 'subtitle') {
|
||||||
|
positions = $.map(self.options.subtitles, function(v, i) {
|
||||||
|
return v['in'];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
direction == -1 && positions.reverse();
|
||||||
|
Ox.forEach(positions, function(v) {
|
||||||
|
if (direction == 1 ? v > self.options.position : v < self.options.position) {
|
||||||
|
position = v;
|
||||||
|
found = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
direction == -1 && positions.reverse();
|
||||||
|
if (!found) {
|
||||||
|
position = positions[direction == 1 ? 0 : positions.length - 1];
|
||||||
|
}
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPoints(type) {
|
||||||
|
var found = false,
|
||||||
|
points,
|
||||||
|
positions = [];
|
||||||
|
if (type == 'cut') {
|
||||||
|
positions = self.options.cuts;
|
||||||
|
} else if (type == 'match') {
|
||||||
|
// ...
|
||||||
|
} else if (type == 'subtitle') {
|
||||||
|
self.options.subtitles.forEach(function(v, i) {
|
||||||
|
positions.push(v['in']);
|
||||||
|
positions.push(v.out);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
positions.indexOf(0) == -1 && positions.unshift(0);
|
||||||
|
positions.indexOf(self.options.duration) == -1 &&
|
||||||
|
positions.push(self.options.duration);
|
||||||
|
Ox.forEach(positions, function(v, i) {
|
||||||
|
if (v > self.options.position) {
|
||||||
|
points = [positions[i - 1], positions[i]];
|
||||||
|
found = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSizes(scrollbarIsVisible) {
|
||||||
|
//Ox.print('getSizes', scrollbarIsVisible)
|
||||||
|
var scrollbarWidth = Ox.UI.SCROLLBAR_SIZE,
|
||||||
|
contentWidth = self.options.width -
|
||||||
|
(self.options.showAnnotations * self.options.annotationsSize) - 1 -
|
||||||
|
(scrollbarIsVisible ? scrollbarWidth : 0),
|
||||||
|
height,
|
||||||
|
lines,
|
||||||
|
size = {
|
||||||
|
player: [],
|
||||||
|
timeline: []
|
||||||
|
},
|
||||||
|
width, widths;
|
||||||
|
if (self.options.videoSize == 'small') {
|
||||||
|
width = 0;
|
||||||
|
widths = Ox.divideInt(contentWidth - 4 * self.margin, 3);
|
||||||
|
[1, 0, 2].forEach(function(v, i) {
|
||||||
|
size.player[v] = {
|
||||||
|
left: (i + 0.5) * self.margin + width,
|
||||||
|
top: self.margin / 2,
|
||||||
|
width: widths[i],
|
||||||
|
height: Math.round(widths[1] / self.videoRatio)
|
||||||
|
}
|
||||||
|
width += widths[i];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
size.player[0] = {
|
||||||
|
left: self.margin / 2,
|
||||||
|
top: self.margin / 2,
|
||||||
|
width: Math.round((contentWidth - 3 * self.margin + (self.controlsHeight + self.margin) / 2 * self.videoRatio) * 2/3),
|
||||||
|
}
|
||||||
|
size.player[0].height = Math.round(size.player[0].width / self.videoRatio);
|
||||||
|
size.player[1] = {
|
||||||
|
left: size.player[0].left + size.player[0].width + self.margin,
|
||||||
|
top: size.player[0].top,
|
||||||
|
width: contentWidth - 3 * self.margin - size.player[0].width
|
||||||
|
}
|
||||||
|
size.player[1].height = Math.ceil(size.player[1].width / self.videoRatio)
|
||||||
|
size.player[2] = {
|
||||||
|
left: size.player[1].left,
|
||||||
|
top: size.player[0].top + size.player[1].height + self.controlsHeight + self.margin,
|
||||||
|
width: size.player[1].width,
|
||||||
|
height: size.player[0].height - size.player[1].height - self.controlsHeight - self.margin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size.timeline[0] = {
|
||||||
|
left: self.margin / 2,
|
||||||
|
top: size.player[0].height + self.controlsHeight + 1.5 * self.margin,
|
||||||
|
width: contentWidth - 2 * self.margin,
|
||||||
|
height: 64
|
||||||
|
}
|
||||||
|
size.timeline[1] = {
|
||||||
|
left: size.timeline[0].left,
|
||||||
|
top: size.timeline[0].top + size.timeline[0].height + self.margin,
|
||||||
|
width: size.timeline[0].width
|
||||||
|
}
|
||||||
|
lines = Math.ceil(self.options.duration / size.timeline[1].width);
|
||||||
|
height = getHeight();
|
||||||
|
self.$editor.css({
|
||||||
|
overflowY: (scrollbarIsVisible && height <= self.options.height) ? 'scroll' : 'auto'
|
||||||
|
});
|
||||||
|
return (!scrollbarIsVisible && height > self.options.height) ? getSizes(true) : size;
|
||||||
|
function getHeight() {
|
||||||
|
return size.player[0].height + self.controlsHeight +
|
||||||
|
size.timeline[0].height + lines * 16 +
|
||||||
|
(lines + 3) * self.margin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function goToPoint(point) {
|
||||||
|
self.options.position = self.options.points[point == 'in' ? 0 : 1];
|
||||||
|
setPosition();
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function movePositionBy(sec) {
|
||||||
|
self.options.position = Ox.limit(self.options.position + sec, 0, self.options.duration);
|
||||||
|
setPosition();
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function movePositionTo(type, direction) {
|
||||||
|
self.options.position = getNextPosition(type, direction);
|
||||||
|
setPosition();
|
||||||
|
that.triggerEvent('change', {
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function playInToOut() {
|
||||||
|
self.$player[0].playInToOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeAnnotations(event, data) {
|
||||||
|
self.options.annotationsSize = data;
|
||||||
|
setSizes();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeEditor(event, data) {
|
||||||
|
var width = data - 2 * margin + 100;
|
||||||
|
resizeVideoPlayers(width);
|
||||||
|
$timelineLarge.options({
|
||||||
|
width: width
|
||||||
|
});
|
||||||
|
$timelineSmall.options({
|
||||||
|
width: width
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizePlayers() {
|
||||||
|
self.$player.forEach(function(v, i) {
|
||||||
|
v.options({
|
||||||
|
width: size[i].width,
|
||||||
|
height: size[i].height
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: size[i].left + 'px',
|
||||||
|
top: size[i].top + 'px',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectAnnotation(event, data) {
|
||||||
|
self.options.position = data['in']
|
||||||
|
self.options.points = [data['in'], data.out];
|
||||||
|
setPosition();
|
||||||
|
setPoints();
|
||||||
|
}
|
||||||
|
function updateAnnotation(event, data) {
|
||||||
|
data['in'] = self.options.points[0];
|
||||||
|
data.out = self.options.points[1];
|
||||||
|
that.triggerEvent('updateAnnotation', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function select(type) {
|
||||||
|
self.options.points = getPoints(type);
|
||||||
|
setPoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPoint(point) {
|
||||||
|
self.options.points[point == 'in' ? 0 : 1] = self.options.position;
|
||||||
|
if (self.options.points[1] < self.options.points[0]) {
|
||||||
|
self.options.points[point == 'in' ? 1 : 0] = self.options.position;
|
||||||
|
}
|
||||||
|
setPoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPoints() {
|
||||||
|
self.$player.forEach(function(v, i) {
|
||||||
|
v.options($.extend({
|
||||||
|
points: self.options.points
|
||||||
|
}, i ? {
|
||||||
|
position: self.options.points[i - 1]
|
||||||
|
} : {}));
|
||||||
|
});
|
||||||
|
self.$timeline.forEach(function(v) {
|
||||||
|
v.options({
|
||||||
|
points: self.options.points
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPosition() {
|
||||||
|
self.$player[0].options({
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
self.$timeline.forEach(function(v) {
|
||||||
|
v.options({
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSizes() {
|
||||||
|
self.sizes = getSizes();
|
||||||
|
self.$player.forEach(function(v, i) {
|
||||||
|
v.options({
|
||||||
|
height: self.sizes.player[i].height,
|
||||||
|
width: self.sizes.player[i].width
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: self.sizes.player[i].left + 'px',
|
||||||
|
top: self.sizes.player[i].top + 'px'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
self.$timeline.forEach(function(v, i) {
|
||||||
|
v.options({
|
||||||
|
width: self.sizes.timeline[i].width
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: self.sizes.timeline[i].left + 'px',
|
||||||
|
top: self.sizes.timeline[i].top + 'px'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleAnnotations(event, data) {
|
||||||
|
self.options.showAnnotations = !data.collapsed;
|
||||||
|
setSizes();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMute() {
|
||||||
|
self.$player[0].toggleMute();
|
||||||
|
}
|
||||||
|
|
||||||
|
function togglePlay() {
|
||||||
|
self.$player[0].togglePlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSize(event, data) {
|
||||||
|
self.options.videoSize = data.size
|
||||||
|
setSizes();
|
||||||
|
that.triggerEvent('togglesize', {
|
||||||
|
size: self.options.videoSize
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onChange = function(key, value) {
|
||||||
|
if (key == 'width' || key == 'height') {
|
||||||
|
//Ox.print('XXXX setSizes', key, value, self.options.width, self.options.height)
|
||||||
|
setSizes();
|
||||||
|
} else if (key == 'position') {
|
||||||
|
self.$player[0].position(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
that.addAnnotation = function(layer, item) {
|
||||||
|
var i = Ox.getPositionById(self.options.layers, layer);
|
||||||
|
self.$annotationPanel[i].addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
that.removeAnnotations = function(layer, ids) {
|
||||||
|
var i = Ox.getPositionById(self.options.layers, layer);
|
||||||
|
self.$annotationPanel[i].removeItems(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
53
source/js/Ox.Window.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
Ox.Window = function(options, self) {
|
||||||
|
|
||||||
|
self = self || {},
|
||||||
|
that = new Ox.Element('div', self)
|
||||||
|
.defaults({
|
||||||
|
draggable: true,
|
||||||
|
fullscreenable: true, // fixme: silly name
|
||||||
|
height: 225,
|
||||||
|
resizeable: true,
|
||||||
|
scaleable: true,
|
||||||
|
width: 400
|
||||||
|
})
|
||||||
|
.options(options || {})
|
||||||
|
|
||||||
|
self.center = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
self.drag = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
self.fullscreen = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
self.onChange = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
self.reset = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
self.resize = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
self.scale = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.close = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
that.open = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|