2 * Ext JS Library 0.30
\r
3 * Copyright(c) 2006-2009, Ext JS, LLC.
\r
4 * licensing@extjs.com
\r
6 * http://extjs.com/license
\r
10 * Ext JS Library 2.0.1
\r
11 * Copyright(c) 2006-2008, Ext JS, LLC.
\r
12 * licensing@extjs.com
\r
14 * http://extjs.com/license
\r
18 Ext.namespace('Ext.air', 'Ext.sql');
\r
20 Ext.Template.prototype.compile = function() {
\r
21 var fm = Ext.util.Format;
\r
22 var useF = this.disableFormats !== true;
\r
27 var fn = function(m, name, format, args, offset, s){
\r
28 if (prevOffset != offset) {
\r
29 var action = {type: 1, value: s.substr(prevOffset, offset - prevOffset)};
\r
32 prevOffset = offset + m.length;
\r
35 var re = /^\s*['"](.*)["']\s*$/;
\r
36 args = args.split(/,(?=(?:[^"]*"[^"]*")*(?![^"]*"))/);
\r
37 for(var i = 0, len = args.length; i < len; i++){
\r
38 args[i] = args[i].replace(re, "$1");
\r
40 args = [''].concat(args);
\r
44 if(format.substr(0, 5) != "this."){
\r
45 var action = {type: 3, value:name, format: fm[format], args: args, scope: fm};
\r
48 var action = {type: 3, value:name, format:tpl[format.substr(5)], args:args, scope: tpl};
\r
52 var action = {type: 2, value: name};
\r
58 var s = this.html.replace(this.re, fn);
\r
59 if (prevOffset != (s.length - 1)) {
\r
60 var action = {type: 1, value: s.substr(prevOffset, s.length - prevOffset)};
\r
64 this.compiled = function(values) {
\r
65 function applyValues(el) {
\r
70 return (values[el.value] ? values[el.value] : '');
\r
72 el.args[0] = values[el.value];
\r
73 return el.format.apply(el.scope, el.args);
\r
76 return arr.map(applyValues).join('');
\r
81 Ext.Template.prototype.call = function(fnName, value, allValues){
\r
82 return this[fnName](value, allValues);
\r
86 Ext.DomQuery = function(){
\r
87 var cache = {}, simpleCache = {}, valueCache = {};
\r
88 var nonSpace = /\S/;
\r
89 var trimRe = /^\s+|\s+$/g;
\r
90 var tplRe = /\{(\d+)\}/g;
\r
91 var modeRe = /^(\s?[\/>+~]\s?|\s|$)/;
\r
92 var tagTokenRe = /^(#)?([\w-\*]+)/;
\r
93 var nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/;
\r
95 function child(p, index){
\r
97 var n = p.firstChild;
\r
99 if(n.nodeType == 1){
\r
110 while((n = n.nextSibling) && n.nodeType != 1);
\r
115 while((n = n.previousSibling) && n.nodeType != 1);
\r
119 function children(d){
\r
120 var n = d.firstChild, ni = -1;
\r
122 var nx = n.nextSibling;
\r
123 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
\r
126 n.nodeIndex = ++ni;
\r
133 function byClassName(c, a, v){
\r
137 var r = [], ri = -1, cn;
\r
138 for(var i = 0, ci; ci = c[i]; i++){
\r
139 if((' '+ci.className+' ').indexOf(v) != -1){
\r
146 function attrValue(n, attr){
\r
147 if(!n.tagName && typeof n.length != "undefined"){
\r
156 if(attr == "class" || attr == "className"){
\r
157 return n.className;
\r
159 return n.getAttribute(attr) || n[attr];
\r
163 function getNodes(ns, mode, tagName){
\r
164 var result = [], ri = -1, cs;
\r
168 tagName = tagName || "*";
\r
169 if(typeof ns.getElementsByTagName != "undefined"){
\r
173 for(var i = 0, ni; ni = ns[i]; i++){
\r
174 cs = ni.getElementsByTagName(tagName);
\r
175 for(var j = 0, ci; ci = cs[j]; j++){
\r
179 }else if(mode == "/" || mode == ">"){
\r
180 var utag = tagName.toUpperCase();
\r
181 for(var i = 0, ni, cn; ni = ns[i]; i++){
\r
182 cn = ni.children || ni.childNodes;
\r
183 for(var j = 0, cj; cj = cn[j]; j++){
\r
184 if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
\r
189 }else if(mode == "+"){
\r
190 var utag = tagName.toUpperCase();
\r
191 for(var i = 0, n; n = ns[i]; i++){
\r
192 while((n = n.nextSibling) && n.nodeType != 1);
\r
193 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
\r
197 }else if(mode == "~"){
\r
198 for(var i = 0, n; n = ns[i]; i++){
\r
199 while((n = n.nextSibling) && (n.nodeType != 1 || (tagName == '*' || n.tagName.toLowerCase()!=tagName)));
\r
208 function concat(a, b){
\r
210 return a.concat(b);
\r
212 for(var i = 0, l = b.length; i < l; i++){
\r
213 a[a.length] = b[i];
\r
218 function byTag(cs, tagName){
\r
219 if(cs.tagName || cs == document){
\r
225 var r = [], ri = -1;
\r
226 tagName = tagName.toLowerCase();
\r
227 for(var i = 0, ci; ci = cs[i]; i++){
\r
228 if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
\r
235 function byId(cs, attr, id){
\r
236 if(cs.tagName || cs == document){
\r
242 var r = [], ri = -1;
\r
243 for(var i = 0,ci; ci = cs[i]; i++){
\r
244 if(ci && ci.id == id){
\r
252 function byAttribute(cs, attr, value, op, custom){
\r
253 var r = [], ri = -1, st = custom=="{";
\r
254 var f = Ext.DomQuery.operators[op];
\r
255 for(var i = 0, ci; ci = cs[i]; i++){
\r
258 a = Ext.DomQuery.getStyle(ci, attr);
\r
260 else if(attr == "class" || attr == "className"){
\r
262 }else if(attr == "for"){
\r
264 }else if(attr == "href"){
\r
265 a = ci.getAttribute("href", 2);
\r
267 a = ci.getAttribute(attr);
\r
269 if((f && f(a, value)) || (!f && a)){
\r
276 function byPseudo(cs, name, value){
\r
277 return Ext.DomQuery.pseudos[name](cs, value);
\r
283 eval("var batch = 30803;");
\r
287 function nodup(cs){
\r
291 var len = cs.length, c, i, r = cs, cj, ri = -1;
\r
292 if(!len || typeof cs.nodeType != "undefined" || len == 1){
\r
297 for(i = 1; c = cs[i]; i++){
\r
302 for(var j = 0; j < i; j++){
\r
305 for(j = i+1; cj = cs[j]; j++){
\r
306 if(cj._nodup != d){
\r
317 function quickDiff(c1, c2){
\r
318 var len1 = c1.length;
\r
323 for(var i = 0; i < len1; i++){
\r
327 for(var i = 0, len = c2.length; i < len; i++){
\r
328 if(c2[i]._qdiff != d){
\r
329 r[r.length] = c2[i];
\r
335 function quickId(ns, mode, root, id){
\r
337 var d = root.ownerDocument || root;
\r
338 return d.getElementById(id);
\r
340 ns = getNodes(ns, mode, "*");
\r
341 return byId(ns, null, id);
\r
344 function search(path, root, type) {
\r
345 type = type || "select";
\r
347 var n = root || document;
\r
349 var q = path, mode, lq;
\r
350 var tk = Ext.DomQuery.matchers;
\r
351 var tklen = tk.length;
\r
354 var lmode = q.match(modeRe);
\r
355 if(lmode && lmode[1]){
\r
356 mode=lmode[1].replace(trimRe, "");
\r
357 q = q.replace(lmode[1], "");
\r
359 while(path.substr(0, 1)=="/"){
\r
360 path = path.substr(1);
\r
362 while(q && lq != q){
\r
364 var tm = q.match(tagTokenRe);
\r
365 if(type == "select"){
\r
368 n = quickId(n, mode, root, tm[2]);
\r
370 n = getNodes(n, mode, tm[2]);
\r
372 q = q.replace(tm[0], "");
\r
373 }else if(q.substr(0, 1) != '@'){
\r
374 n = getNodes(n, mode, "*");
\r
379 n = byId(n, null, tm[2]);
\r
381 n = byTag(n, tm[2]);
\r
383 q = q.replace(tm[0], "");
\r
386 while(!(mm = q.match(modeRe))){
\r
387 var matched = false;
\r
388 for(var j = 0; j < tklen; j++){
\r
390 var m = q.match(t.re);
\r
394 n = byClassName(n, null, " " + m[1] +" ");
\r
397 n = byPseudo(n, m[1], m[2]);
\r
400 n = byAttribute(n, m[2], m[4], m[3], m[1]);
\r
403 n = byId(n, null, m[1]);
\r
406 return {firstChild:{nodeValue:attrValue(n, m[1])}};
\r
409 q = q.replace(m[0], "");
\r
416 throw 'Error parsing selector, parsing failed at "' + q + '"';
\r
420 mode=mm[1].replace(trimRe, "");
\r
421 q = q.replace(mm[1], "");
\r
428 getStyle : function(el, name){
\r
429 return Ext.fly(el).getStyle(name);
\r
432 compile: function(path, type) {
\r
433 return function(root) {
\r
434 return search(path, root, type);
\r
439 select : function(path, root, type){
\r
440 if(!root || root == document){
\r
443 if(typeof root == "string"){
\r
444 root = document.getElementById(root);
\r
446 var paths = path.split(",");
\r
448 for(var i = 0, len = paths.length; i < len; i++){
\r
449 var p = paths[i].replace(trimRe, "");
\r
451 cache[p] = Ext.DomQuery.compile(p);
\r
453 throw p + " is not a valid selector";
\r
456 var result = cache[p](root);
\r
457 if(result && result != document){
\r
458 results = results.concat(result);
\r
461 if(paths.length > 1){
\r
462 return nodup(results);
\r
468 selectNode : function(path, root){
\r
469 return Ext.DomQuery.select(path, root)[0];
\r
473 selectValue : function(path, root, defaultValue){
\r
474 path = path.replace(trimRe, "");
\r
475 if(!valueCache[path]){
\r
476 valueCache[path] = Ext.DomQuery.compile(path, "select");
\r
478 var n = valueCache[path](root);
\r
479 n = n[0] ? n[0] : n;
\r
480 var v = (n && n.firstChild ? n.firstChild.nodeValue : null);
\r
481 return ((v === null||v === undefined||v==='') ? defaultValue : v);
\r
485 selectNumber : function(path, root, defaultValue){
\r
486 var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
\r
487 return parseFloat(v);
\r
491 is : function(el, ss){
\r
492 if(typeof el == "string"){
\r
493 el = document.getElementById(el);
\r
495 var isArray = Ext.isArray(el);
\r
496 var result = Ext.DomQuery.filter(isArray ? el : [el], ss);
\r
497 return isArray ? (result.length == el.length) : (result.length > 0);
\r
501 filter : function(els, ss, nonMatches){
\r
502 ss = ss.replace(trimRe, "");
\r
503 if(!simpleCache[ss]){
\r
504 simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
\r
506 var result = simpleCache[ss](els);
\r
507 return nonMatches ? quickDiff(result, els) : result;
\r
513 select: 'n = byClassName(n, null, " {1} ");'
\r
515 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
\r
516 select: 'n = byPseudo(n, "{1}", "{2}");'
\r
518 re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
\r
519 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
\r
522 select: 'n = byId(n, null, "{1}");'
\r
525 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
\r
531 "=" : function(a, v){
\r
534 "!=" : function(a, v){
\r
537 "^=" : function(a, v){
\r
538 return a && a.substr(0, v.length) == v;
\r
540 "$=" : function(a, v){
\r
541 return a && a.substr(a.length-v.length) == v;
\r
543 "*=" : function(a, v){
\r
544 return a && a.indexOf(v) !== -1;
\r
546 "%=" : function(a, v){
\r
547 return (a % v) == 0;
\r
549 "|=" : function(a, v){
\r
550 return a && (a == v || a.substr(0, v.length+1) == v+'-');
\r
552 "~=" : function(a, v){
\r
553 return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
\r
559 "first-child" : function(c){
\r
560 var r = [], ri = -1, n;
\r
561 for(var i = 0, ci; ci = n = c[i]; i++){
\r
562 while((n = n.previousSibling) && n.nodeType != 1);
\r
570 "last-child" : function(c){
\r
571 var r = [], ri = -1, n;
\r
572 for(var i = 0, ci; ci = n = c[i]; i++){
\r
573 while((n = n.nextSibling) && n.nodeType != 1);
\r
581 "nth-child" : function(c, a) {
\r
582 var r = [], ri = -1;
\r
583 var m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a);
\r
584 var f = (m[1] || 1) - 0, l = m[2] - 0;
\r
585 for(var i = 0, n; n = c[i]; i++){
\r
586 var pn = n.parentNode;
\r
587 if (batch != pn._batch) {
\r
589 for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
\r
590 if(cn.nodeType == 1){
\r
591 cn.nodeIndex = ++j;
\r
597 if (l == 0 || n.nodeIndex == l){
\r
600 } else if ((n.nodeIndex + l) % f == 0){
\r
608 "only-child" : function(c){
\r
609 var r = [], ri = -1;;
\r
610 for(var i = 0, ci; ci = c[i]; i++){
\r
611 if(!prev(ci) && !next(ci)){
\r
618 "empty" : function(c){
\r
619 var r = [], ri = -1;
\r
620 for(var i = 0, ci; ci = c[i]; i++){
\r
621 var cns = ci.childNodes, j = 0, cn, empty = true;
\r
622 while(cn = cns[j]){
\r
624 if(cn.nodeType == 1 || cn.nodeType == 3){
\r
636 "contains" : function(c, v){
\r
637 var r = [], ri = -1;
\r
638 for(var i = 0, ci; ci = c[i]; i++){
\r
639 if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
\r
646 "nodeValue" : function(c, v){
\r
647 var r = [], ri = -1;
\r
648 for(var i = 0, ci; ci = c[i]; i++){
\r
649 if(ci.firstChild && ci.firstChild.nodeValue == v){
\r
656 "checked" : function(c){
\r
657 var r = [], ri = -1;
\r
658 for(var i = 0, ci; ci = c[i]; i++){
\r
659 if(ci.checked == true){
\r
666 "not" : function(c, ss){
\r
667 return Ext.DomQuery.filter(c, ss, true);
\r
670 "any" : function(c, selectors){
\r
671 var ss = selectors.split('|');
\r
672 var r = [], ri = -1, s;
\r
673 for(var i = 0, ci; ci = c[i]; i++){
\r
674 for(var j = 0; s = ss[j]; j++){
\r
675 if(Ext.DomQuery.is(ci, s)){
\r
684 "odd" : function(c){
\r
685 return this["nth-child"](c, "odd");
\r
688 "even" : function(c){
\r
689 return this["nth-child"](c, "even");
\r
692 "nth" : function(c, a){
\r
693 return c[a-1] || [];
\r
696 "first" : function(c){
\r
700 "last" : function(c){
\r
701 return c[c.length-1] || [];
\r
704 "has" : function(c, ss){
\r
705 var s = Ext.DomQuery.select;
\r
706 var r = [], ri = -1;
\r
707 for(var i = 0, ci; ci = c[i]; i++){
\r
708 if(s(ss, ci).length > 0){
\r
715 "next" : function(c, ss){
\r
716 var is = Ext.DomQuery.is;
\r
717 var r = [], ri = -1;
\r
718 for(var i = 0, ci; ci = c[i]; i++){
\r
720 if(n && is(n, ss)){
\r
727 "prev" : function(c, ss){
\r
728 var is = Ext.DomQuery.is;
\r
729 var r = [], ri = -1;
\r
730 for(var i = 0, ci; ci = c[i]; i++){
\r
732 if(n && is(n, ss)){
\r
742 Ext.query = Ext.DomQuery.select;
\r
744 Date.precompileFormats = function(s){
\r
745 var formats = s.split('|');
\r
746 for(var i = 0, len = formats.length;i < len;i++){
\r
747 Date.createNewFormat(formats[i]);
\r
748 Date.createParser(formats[i]);
\r
752 Date.precompileFormats("D n/j/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|YmdHis|F d, Y|l, F d, Y|H:i:s|g:i A|g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|m/d/y|m/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|Y-m-d H:i:s|d/m/y|d/m/Y|d-m-y|d-m-Y|d/m|d-m|dm|dmy|dmY|Y-m-d|l|D m/d|D m/d/Y|m/d/Y");
\r
755 Ext.ColorPalette.prototype.tpl = new Ext.XTemplate(
\r
756 '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on"> </span></em></a></tpl>'
\r
765 Ext.air.FileProvider = function(config){
\r
766 Ext.air.FileProvider.superclass.constructor.call(this);
\r
768 this.defaultState = {
\r
777 Ext.apply(this, config);
\r
778 this.state = this.readState();
\r
780 var provider = this;
\r
781 air.NativeApplication.nativeApplication.addEventListener('exiting', function(){
\r
782 provider.saveState();
\r
786 Ext.extend(Ext.air.FileProvider, Ext.state.Provider, {
\r
787 file: 'extstate.data',
\r
790 readState : function(){
\r
791 var stateFile = air.File.applicationStorageDirectory.resolvePath(this.file);
\r
792 if(!stateFile.exists){
\r
793 return this.defaultState || {};
\r
796 var stream = new air.FileStream();
\r
797 stream.open(stateFile, air.FileMode.READ);
\r
799 var stateData = stream.readObject();
\r
802 return stateData || this.defaultState || {};
\r
806 saveState : function(name, value){
\r
807 var stateFile = air.File.applicationStorageDirectory.resolvePath(this.file);
\r
808 var stream = new air.FileStream();
\r
809 stream.open(stateFile, air.FileMode.WRITE);
\r
810 stream.writeObject(this.state);
\r
814 Ext.air.NativeObservable = Ext.extend(Ext.util.Observable, {
\r
815 addListener : function(name){
\r
816 this.proxiedEvents = this.proxiedEvents || {};
\r
817 if(!this.proxiedEvents[name]){
\r
818 var instance = this;
\r
819 var f = function(){
\r
820 var args = Array.prototype.slice.call(arguments, 0);
\r
821 args.unshift(name);
\r
822 instance.fireEvent.apply(instance, args);
\r
824 this.proxiedEvents[name] = f;
\r
825 this.getNative().addEventListener(name, f);
\r
827 Ext.air.NativeObservable.superclass.addListener.apply(this, arguments);
\r
831 Ext.air.NativeObservable.prototype.on = Ext.air.NativeObservable.prototype.addListener;
833 Ext.air.NativeWindow = function(config){
\r
834 Ext.apply(this, config);
\r
836 this.id = this.id || Ext.uniqueId();
\r
845 'displayStateChange',
\r
846 'displayStateChanging'
\r
849 Ext.air.NativeWindow.superclass.constructor.call(this);
\r
851 if(!this.instance){
\r
852 var options = new air.NativeWindowInitOptions();
\r
853 options.systemChrome = this.chrome;
\r
854 options.type = this.type;
\r
855 options.resizable = this.resizable;
\r
856 options.minimizable = this.minimizable;
\r
857 options.maximizable = this.maximizable;
\r
858 options.transparent = this.transparent;
\r
860 this.loader = window.runtime.flash.html.HTMLLoader.createRootWindow(false, options, false);
\r
861 this.loader.load(new air.URLRequest(this.file));
\r
863 this.instance = this.loader.window.nativeWindow;
\r
865 this.loader = this.instance.stage.getChildAt(0);
\r
868 var provider = Ext.state.Manager;
\r
869 var b = air.Screen.mainScreen.visibleBounds;
\r
871 var state = provider.get(this.id) || {};
\r
872 provider.set(this.id, state);
\r
874 var win = this.instance;
\r
876 var width = Math.max(state.width || this.width, 100);
\r
877 var height = Math.max(state.height || this.height, 100);
\r
879 var centerX = b.x + ((b.width/2)-(width/2));
\r
880 var centerY = b.y + ((b.height/2)-(height/2));
\r
882 var x = !Ext.isEmpty(state.x, false) ? state.x : (!Ext.isEmpty(this.x, false) ? this.x : centerX);
\r
883 var y = !Ext.isEmpty(state.y, false) ? state.y : (!Ext.isEmpty(this.y, false) ? this.y : centerY);
\r
886 win.height = height;
\r
890 win.addEventListener('move', function(){
\r
891 if(win.displayState != air.NativeWindowDisplayState.MINIMIZED && win.width > 100 && win.height > 100) {
\r
896 win.addEventListener('resize', function(){
\r
897 if (win.displayState != air.NativeWindowDisplayState.MINIMIZED && win.width > 100 && win.height > 100) {
\r
898 state.width = win.width;
\r
899 state.height = win.height;
\r
903 Ext.air.NativeWindowManager.register(this);
\r
904 this.on('close', this.unregister, this);
\r
906 if(this.minimizeToTray){
\r
907 this.initMinimizeToTray(this.trayIcon, this.trayMenu);
\r
912 Ext.extend(Ext.air.NativeWindow, Ext.air.NativeObservable, {
\r
920 transparent: false,
\r
922 getNative : function(){
\r
923 return this.instance;
\r
926 getCenterXY : function(){
\r
927 var b = air.Screen.mainScreen.visibleBounds;
\r
929 x: b.x + ((b.width/2)-(this.width/2)),
\r
930 y: b.y + ((b.height/2)-(this.height/2))
\r
936 Ext.air.SystemTray.hideIcon();
\r
937 this.trayed = false;
\r
939 this.instance.visible = true;
\r
942 activate : function(){
\r
944 this.instance.activate();
\r
948 this.instance.visible = false;
\r
951 close : function(){
\r
952 this.instance.close();
\r
955 isMinimized :function(){
\r
956 return this.instance.displayState == air.NativeWindowDisplayState.MINIMIZED;
\r
959 isMaximized :function(){
\r
960 return this.instance.displayState == air.NativeWindowDisplayState.MAXIMIZED;
\r
963 moveTo : function(x, y){
\r
964 this.x = this.instance.x = x;
\r
965 this.y = this.instance.y = y;
\r
968 resize : function(width, height){
\r
969 this.width = this.instance.width = width;
\r
970 this.height = this.instance.height = height;
\r
973 unregister : function(){
\r
974 Ext.air.NativeWindowManager.unregister(this);
\r
977 initMinimizeToTray : function(icon, menu){
\r
978 var tray = Ext.air.SystemTray;
\r
979 tray.setIcon(icon, this.trayTip);
\r
980 this.on('displayStateChanging', function(e){
\r
981 if(e.afterDisplayState == 'minimized'){
\r
982 e.preventDefault();
\r
985 this.trayed = true;
\r
989 tray.on('click', function(){
\r
994 tray.setMenu(menu);
\r
999 Ext.air.NativeWindow.getRootWindow = function(){
\r
1000 return air.NativeApplication.nativeApplication.openedWindows[0];
\r
1003 Ext.air.NativeWindow.getRootHtmlWindow = function(){
\r
1004 return Ext.air.NativeWindow.getRootWindow().stage.getChildAt(0).window;
\r
1007 Ext.air.NativeWindowGroup = function(){
\r
1011 register : function(win){
\r
1012 list[win.id] = win;
\r
1015 unregister : function(win){
\r
1016 delete list[win.id];
\r
1019 get : function(id){
\r
1023 closeAll : function(){
\r
1024 for(var id in list){
\r
1025 if(list.hasOwnProperty(id)){
\r
1032 each : function(fn, scope){
\r
1033 for(var id in list){
\r
1034 if(list.hasOwnProperty(id)){
\r
1035 if(fn.call(scope || list[id], list[id]) === false){
\r
1045 Ext.air.NativeWindowManager = new Ext.air.NativeWindowGroup();
1047 Ext.sql.Connection = function(config){
\r
1048 Ext.apply(this, config);
\r
1049 Ext.sql.Connection.superclass.constructor.call(this);
\r
1057 Ext.extend(Ext.sql.Connection, Ext.util.Observable, {
\r
1058 maxResults: 10000,
\r
1059 openState : false,
\r
1062 open : function(file){
\r
1065 close : function(){
\r
1068 exec : function(sql){
\r
1071 execBy : function(sql, args){
\r
1074 query : function(sql){
\r
1077 queryBy : function(sql, args){
\r
1081 isOpen : function(){
\r
1082 return this.openState;
\r
1085 getTable : function(name, keyName){
\r
1086 return new Ext.sql.Table(this, name, keyName);
\r
1089 createTable : function(o){
\r
1090 var tableName = o.name;
\r
1091 var keyName = o.key;
\r
1092 var fs = o.fields;
\r
1093 if(!Ext.isArray(fs)){
1097 for(var i = 0, len = fs.length; i < len; i++){
\r
1098 var f = fs[i], s = f.name;
\r
1111 if(f.allowNull === false || f.name == keyName){
\r
1114 if(f.name == keyName){
\r
1115 s += ' PRIMARY KEY';
\r
1117 if(f.unique === true){
\r
1121 buf[buf.length] = s;
\r
1123 var sql = ['CREATE TABLE IF NOT EXISTS ', tableName, ' (', buf.join(','), ')'].join('');
\r
1129 Ext.sql.Connection.getInstance = function(db, config){
\r
1131 return new Ext.sql.AirConnection(config);
\r
1133 return new Ext.sql.GearsConnection(config);
\r
1136 Ext.sql.Table = function(conn, name, keyName){
\r
1139 this.keyName = keyName;
\r
1142 Ext.sql.Table.prototype = {
\r
1143 update : function(o){
\r
1144 var clause = this.keyName + " = ?";
\r
1145 return this.updateBy(o, clause, [o[this.keyName]]);
\r
1148 updateBy : function(o, clause, args){
\r
1149 var sql = "UPDATE " + this.name + " set ";
\r
1150 var fs = [], a = [];
\r
1151 for(var key in o){
\r
1152 if(o.hasOwnProperty(key)){
\r
1153 fs[fs.length] = key + ' = ?';
\r
1154 a[a.length] = o[key];
\r
1157 for(var key in args){
\r
1158 if(args.hasOwnProperty(key)){
\r
1159 a[a.length] = args[key];
\r
1162 sql = [sql, fs.join(','), ' WHERE ', clause].join('');
\r
1163 return this.conn.execBy(sql, a);
\r
1166 insert : function(o){
\r
1167 var sql = "INSERT into " + this.name + " ";
\r
1168 var fs = [], vs = [], a = [];
\r
1169 for(var key in o){
\r
1170 if(o.hasOwnProperty(key)){
\r
1171 fs[fs.length] = key;
\r
1172 vs[vs.length] = '?';
\r
1173 a[a.length] = o[key];
\r
1176 sql = [sql, '(', fs.join(','), ') VALUES (', vs.join(','), ')'].join('');
\r
1177 return this.conn.execBy(sql, a);
\r
1180 lookup : function(id){
\r
1181 return this.selectBy('where ' + this.keyName + " = ?", [id])[0] || null;
\r
1184 exists : function(id){
\r
1185 return !!this.lookup(id);
\r
1188 save : function(o){
\r
1189 if(this.exists(o[this.keyName])){
\r
1196 select : function(clause){
\r
1197 return this.selectBy(clause, null);
\r
1200 selectBy : function(clause, args){
\r
1201 var sql = "select * from " + this.name;
\r
1203 sql += ' ' + clause;
\r
1205 args = args || {};
\r
1206 return this.conn.queryBy(sql, args);
\r
1209 remove : function(clause){
\r
1210 this.deleteBy(clause, null);
\r
1213 removeBy : function(clause, args){
\r
1214 var sql = "delete from " + this.name;
\r
1216 sql += ' where ' + clause;
\r
1218 args = args || {};
\r
1219 this.conn.execBy(sql, args);
\r
1222 Ext.sql.Proxy = function(conn, table, keyName, store, readonly){
\r
1223 Ext.sql.Proxy.superclass.constructor.call(this);
\r
1225 this.table = this.conn.getTable(table, keyName);
\r
1226 this.store = store;
\r
1228 if (readonly !== true) {
\r
1229 this.store.on('add', this.onAdd, this);
\r
1230 this.store.on('update', this.onUpdate, this);
\r
1231 this.store.on('remove', this.onRemove, this);
\r
1235 Ext.sql.Proxy.DATE_FORMAT = 'Y-m-d H:i:s';
\r
1237 Ext.extend(Ext.sql.Proxy, Ext.data.DataProxy, {
\r
1238 load : function(params, reader, callback, scope, arg){
\r
1239 if(!this.conn.isOpen()){
1240 this.conn.on('open', function(){
\r
1241 this.load(params, reader, callback, scope, arg);
\r
1242 }, this, {single:true});
\r
1245 if(this.fireEvent("beforeload", this, params, reader, callback, scope, arg) !== false){
\r
1246 var clause = params.where || '';
\r
1247 var args = params.args || [];
\r
1248 var group = params.groupBy;
\r
1249 var sort = params.sort;
\r
1250 var dir = params.dir;
\r
1252 if(group || sort){
\r
1253 clause += ' ORDER BY ';
\r
1254 if(group && group != sort){
\r
1255 clause += group + ' ASC, ';
\r
1257 clause += sort + ' ' + (dir || 'ASC');
\r
1260 var rs = this.table.selectBy(clause, args);
\r
1261 this.onLoad({callback:callback, scope:scope, arg:arg, reader: reader}, rs);
\r
1263 callback.call(scope||this, null, arg, false);
\r
1267 onLoad : function(trans, rs, e, stmt){
\r
1269 this.fireEvent("loadexception", this, null, trans.arg, e);
\r
1270 trans.callback.call(trans.scope||window, null, trans.arg, false);
\r
1273 var result = trans.reader.readRecords(rs);
\r
1274 this.fireEvent("load", this, rs, trans.arg);
\r
1275 trans.callback.call(trans.scope||window, result, trans.arg, true);
\r
1278 processData : function(o){
\r
1279 var fs = this.store.fields;
\r
1281 for(var key in o){
\r
1282 var f = fs.key(key), v = o[key];
\r
1284 if(f.type == 'date'){
\r
1285 r[key] = v ? v.format(Ext.sql.Proxy.DATE_FORMAT,10) : '';
\r
1286 }else if(f.type == 'boolean'){
\r
1287 r[key] = v ? 1 : 0;
\r
1296 onUpdate : function(ds, record){
\r
1297 var changes = record.getChanges();
\r
1298 var kn = this.table.keyName;
\r
1299 this.table.updateBy(this.processData(changes), kn + ' = ?', [record.data[kn]]);
\r
1300 record.commit(true);
\r
1303 onAdd : function(ds, records, index){
\r
1304 for(var i = 0, len = records.length; i < len; i++){
\r
1305 this.table.insert(this.processData(records[i].data));
\r
1309 onRemove : function(ds, record, index){
\r
1310 var kn = this.table.keyName;
\r
1311 this.table.removeBy(kn + ' = ?', [record.data[kn]]);
\r
1314 Ext.sql.AirConnection = Ext.extend(Ext.sql.Connection, {
\r
1316 open : function(db){
\r
1317 this.conn = new air.SQLConnection();
\r
1318 var file = air.File.applicationDirectory.resolvePath(db);
\r
1319 this.conn.open(file);
\r
1320 this.openState = true;
\r
1321 this.fireEvent('open', this);
\r
1324 close : function(){
\r
1325 this.conn.close();
\r
1326 this.fireEvent('close', this);
\r
1329 createStatement : function(type){
\r
1330 var stmt = new air.SQLStatement();
\r
1331 stmt.sqlConnection = this.conn;
\r
1335 exec : function(sql){
\r
1336 var stmt = this.createStatement('exec');
\r
1341 execBy : function(sql, args){
\r
1342 var stmt = this.createStatement('exec');
\r
1344 this.addParams(stmt, args);
\r
1348 query : function(sql){
\r
1349 var stmt = this.createStatement('query');
\r
1351 stmt.execute(this.maxResults);
\r
1352 return this.readResults(stmt.getResult());
\r
1355 queryBy : function(sql, args){
\r
1356 var stmt = this.createStatement('query');
\r
1358 this.addParams(stmt, args);
\r
1359 stmt.execute(this.maxResults);
\r
1360 return this.readResults(stmt.getResult());
\r
1363 addParams : function(stmt, args){
\r
1364 if(!args){ return; }
\r
1365 for(var key in args){
\r
1366 if(args.hasOwnProperty(key)){
\r
1368 var v = args[key];
\r
1369 if(Ext.isDate(v)){
\r
1370 v = v.format(Ext.sql.Proxy.DATE_FORMAT);
\r
1372 stmt.parameters[parseInt(key)] = v;
\r
1374 stmt.parameters[':' + key] = args[key];
\r
1381 readResults : function(rs){
\r
1383 if(rs && rs.data){
\r
1384 var len = rs.data.length;
\r
1385 for(var i = 0; i < len; i++) {
\r
1386 r[r.length] = rs.data[i];
\r
1392 Ext.air.SystemTray = function(){
\r
1393 var app = air.NativeApplication.nativeApplication;
\r
1394 var icon, isWindows = false, bitmaps;
\r
1397 if(air.NativeApplication.supportsSystemTrayIcon) {
\r
1403 if(air.NativeApplication.supportsDockIcon) {
\r
1409 setIcon : function(icon, tooltip, initWithIcon){
\r
1413 var loader = new air.Loader();
\r
1414 loader.contentLoaderInfo.addEventListener(air.Event.COMPLETE, function(e){
\r
1415 bitmaps = new runtime.Array(e.target.content.bitmapData);
\r
1416 if (initWithIcon) {
\r
1417 icon.bitmaps = bitmaps;
\r
1420 loader.load(new air.URLRequest(icon));
\r
1421 if(tooltip && air.NativeApplication.supportsSystemTrayIcon) {
\r
1422 app.icon.tooltip = tooltip;
\r
1426 bounce : function(priority){
\r
1427 icon.bounce(priority);
\r
1430 on : function(eventName, fn, scope){
\r
1431 icon.addEventListener(eventName, function(){
\r
1432 fn.apply(scope || this, arguments);
\r
1436 hideIcon : function(){
\r
1440 icon.bitmaps = [];
\r
1443 showIcon : function(){
\r
1447 icon.bitmaps = bitmaps;
\r
1450 setMenu: function(actions, _parentMenu){
\r
1454 var menu = new air.NativeMenu();
\r
1456 for (var i = 0, len = actions.length; i < len; i++) {
\r
1457 var a = actions[i];
\r
1459 menu.addItem(new air.NativeMenuItem("", true));
\r
1461 var item = menu.addItem(Ext.air.MenuItem(a));
\r
1462 if(a.menu || (a.initialConfig && a.initialConfig.menu)){
\r
1463 item.submenu = Ext.air.SystemTray.setMenu(a.menu || a.initialConfig.menu, menu);
\r
1478 Ext.air.DragType = {
\r
1479 TEXT : 'text/plain',
\r
1480 HTML : 'text/html',
\r
1481 URL : 'text/uri-list',
\r
1482 BITMAP : 'image/x-vnd.adobe.air.bitmap',
\r
1483 FILES : 'application/x-vnd.adobe.air.file-list'
\r
1486 Ext.apply(Ext.EventObjectImpl.prototype, {
\r
1487 hasFormat : function(format){
\r
1488 if (this.browserEvent.dataTransfer) {
\r
1489 for (var i = 0, len = this.browserEvent.dataTransfer.types.length; i < len; i++) {
\r
1490 if(this.browserEvent.dataTransfer.types[i] == format) {
\r
1498 getData : function(type){
\r
1499 return this.browserEvent.dataTransfer.getData(type);
\r
1506 play : function(file, startAt){
\r
1507 var soundFile = air.File.applicationDirectory.resolvePath(file);
\r
1508 var sound = new air.Sound();
\r
1509 sound.load(new air.URLRequest(soundFile.url));
\r
1510 sound.play(startAt);
\r
1515 Ext.air.SystemMenu = function(){
\r
1518 if(air.NativeWindow.supportsMenu && nativeWindow.systemChrome != air.NativeWindowSystemChrome.NONE) {
\r
1519 menu = new air.NativeMenu();
\r
1520 nativeWindow.menu = menu;
\r
1524 if(air.NativeApplication.supportsMenu) {
\r
1525 menu = air.NativeApplication.nativeApplication.menu;
\r
1528 function find(menu, text){
\r
1529 for(var i = 0, len = menu.items.length; i < len; i++){
\r
1530 if(menu.items[i]['label'] == text){
\r
1531 return menu.items[i];
\r
1538 add: function(text, actions, mindex){
\r
1540 var item = find(menu, text);
\r
1542 item = menu.addItem(new air.NativeMenuItem(text));
\r
1543 item.mnemonicIndex = mindex || 0;
\r
1545 item.submenu = new air.NativeMenu();
\r
1547 for (var i = 0, len = actions.length; i < len; i++) {
\r
1548 item.submenu.addItem(actions[i] == '-' ? new air.NativeMenuItem("", true) : Ext.air.MenuItem(actions[i]));
\r
1550 return item.submenu;
\r
1560 Ext.air.MenuItem = function(action){
\r
1561 if(!action.isAction){
\r
1562 action = new Ext.Action(action);
\r
1564 var cfg = action.initialConfig;
\r
1565 var nativeItem = new air.NativeMenuItem(cfg.itemText || cfg.text);
\r
1567 nativeItem.enabled = !cfg.disabled;
\r
1569 if(!Ext.isEmpty(cfg.checked)){
\r
1570 nativeItem.checked = cfg.checked;
\r
1573 var handler = cfg.handler;
\r
1574 var scope = cfg.scope;
\r
1576 nativeItem.addEventListener(air.Event.SELECT, function(){
\r
1577 handler.call(scope || window, cfg);
\r
1580 action.addComponent({
\r
1581 setDisabled : function(v){
\r
1582 nativeItem.enabled = !v;
\r
1585 setText : function(v){
\r
1586 nativeItem.label = v;
\r
1589 setVisible : function(v){
\r
1591 nativeItem.enabled = !v;
\r
1594 setHandler : function(newHandler, newScope){
\r
1595 handler = newHandler;
\r
1602 return nativeItem;
\r