3 <title>The source code</title>
\r
4 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
\r
5 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
\r
7 <body onload="prettyPrint();">
\r
8 <pre class="prettyprint lang-js">/*
\r
9 * Ext JS Library 2.0.1
\r
10 * Copyright(c) 2006-2008, Ext JS, LLC.
\r
11 * licensing@extjs.com
\r
13 * http://extjs.com/license
\r
17 Ext.namespace('Ext.air', 'Ext.sql');
\r
19 Ext.Template.prototype.compile = function() {
\r
20 var fm = Ext.util.Format;
\r
21 var useF = this.disableFormats !== true;
\r
26 var fn = function(m, name, format, args, offset, s){
\r
27 if (prevOffset != offset) {
\r
28 var action = {type: 1, value: s.substr(prevOffset, offset - prevOffset)};
\r
31 prevOffset = offset + m.length;
\r
34 var re = /^\s*['"](.*)["']\s*$/;
\r
35 args = args.split(/,(?=(?:[^"]*"[^"]*")*(?![^"]*"))/);
\r
36 for(var i = 0, len = args.length; i < len; i++){
\r
37 args[i] = args[i].replace(re, "$1");
\r
39 args = [''].concat(args);
\r
43 if(format.substr(0, 5) != "this."){
\r
44 var action = {type: 3, value:name, format: fm[format], args: args, scope: fm};
\r
47 var action = {type: 3, value:name, format:tpl[format.substr(5)], args:args, scope: tpl};
\r
51 var action = {type: 2, value: name};
\r
57 var s = this.html.replace(this.re, fn);
\r
58 if (prevOffset != (s.length - 1)) {
\r
59 var action = {type: 1, value: s.substr(prevOffset, s.length - prevOffset)};
\r
63 this.compiled = function(values) {
\r
64 function applyValues(el) {
\r
69 return (values[el.value] ? values[el.value] : '');
\r
71 el.args[0] = values[el.value];
\r
72 return el.format.apply(el.scope, el.args);
\r
75 return arr.map(applyValues).join('');
\r
80 Ext.Template.prototype.call = function(fnName, value, allValues){
\r
81 return this[fnName](value, allValues);
\r
85 Ext.DomQuery = function(){
\r
86 var cache = {}, simpleCache = {}, valueCache = {};
\r
87 var nonSpace = /\S/;
\r
88 var trimRe = /^\s+|\s+$/g;
\r
89 var tplRe = /\{(\d+)\}/g;
\r
90 var modeRe = /^(\s?[\/>+~]\s?|\s|$)/;
\r
91 var tagTokenRe = /^(#)?([\w-\*]+)/;
\r
92 var nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/;
\r
94 function child(p, index){
\r
96 var n = p.firstChild;
\r
98 if(n.nodeType == 1){
\r
109 while((n = n.nextSibling) && n.nodeType != 1);
\r
114 while((n = n.previousSibling) && n.nodeType != 1);
\r
118 function children(d){
\r
119 var n = d.firstChild, ni = -1;
\r
121 var nx = n.nextSibling;
\r
122 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
\r
125 n.nodeIndex = ++ni;
\r
132 function byClassName(c, a, v){
\r
136 var r = [], ri = -1, cn;
\r
137 for(var i = 0, ci; ci = c[i]; i++){
\r
138 if((' '+ci.className+' ').indexOf(v) != -1){
\r
145 function attrValue(n, attr){
\r
146 if(!n.tagName && typeof n.length != "undefined"){
\r
155 if(attr == "class" || attr == "className"){
\r
156 return n.className;
\r
158 return n.getAttribute(attr) || n[attr];
\r
162 function getNodes(ns, mode, tagName){
\r
163 var result = [], ri = -1, cs;
\r
167 tagName = tagName || "*";
\r
168 if(typeof ns.getElementsByTagName != "undefined"){
\r
172 for(var i = 0, ni; ni = ns[i]; i++){
\r
173 cs = ni.getElementsByTagName(tagName);
\r
174 for(var j = 0, ci; ci = cs[j]; j++){
\r
178 }else if(mode == "/" || mode == ">"){
\r
179 var utag = tagName.toUpperCase();
\r
180 for(var i = 0, ni, cn; ni = ns[i]; i++){
\r
181 cn = ni.children || ni.childNodes;
\r
182 for(var j = 0, cj; cj = cn[j]; j++){
\r
183 if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
\r
188 }else if(mode == "+"){
\r
189 var utag = tagName.toUpperCase();
\r
190 for(var i = 0, n; n = ns[i]; i++){
\r
191 while((n = n.nextSibling) && n.nodeType != 1);
\r
192 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
\r
196 }else if(mode == "~"){
\r
197 for(var i = 0, n; n = ns[i]; i++){
\r
198 while((n = n.nextSibling) && (n.nodeType != 1 || (tagName == '*' || n.tagName.toLowerCase()!=tagName)));
\r
207 function concat(a, b){
\r
209 return a.concat(b);
\r
211 for(var i = 0, l = b.length; i < l; i++){
\r
212 a[a.length] = b[i];
\r
217 function byTag(cs, tagName){
\r
218 if(cs.tagName || cs == document){
\r
224 var r = [], ri = -1;
\r
225 tagName = tagName.toLowerCase();
\r
226 for(var i = 0, ci; ci = cs[i]; i++){
\r
227 if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
\r
234 function byId(cs, attr, id){
\r
235 if(cs.tagName || cs == document){
\r
241 var r = [], ri = -1;
\r
242 for(var i = 0,ci; ci = cs[i]; i++){
\r
243 if(ci && ci.id == id){
\r
251 function byAttribute(cs, attr, value, op, custom){
\r
252 var r = [], ri = -1, st = custom=="{";
\r
253 var f = Ext.DomQuery.operators[op];
\r
254 for(var i = 0, ci; ci = cs[i]; i++){
\r
257 a = Ext.DomQuery.getStyle(ci, attr);
\r
259 else if(attr == "class" || attr == "className"){
\r
261 }else if(attr == "for"){
\r
263 }else if(attr == "href"){
\r
264 a = ci.getAttribute("href", 2);
\r
266 a = ci.getAttribute(attr);
\r
268 if((f && f(a, value)) || (!f && a)){
\r
275 function byPseudo(cs, name, value){
\r
276 return Ext.DomQuery.pseudos[name](cs, value);
\r
282 eval("var batch = 30803;");
\r
286 function nodup(cs){
\r
290 var len = cs.length, c, i, r = cs, cj, ri = -1;
\r
291 if(!len || typeof cs.nodeType != "undefined" || len == 1){
\r
296 for(i = 1; c = cs[i]; i++){
\r
301 for(var j = 0; j < i; j++){
\r
304 for(j = i+1; cj = cs[j]; j++){
\r
305 if(cj._nodup != d){
\r
316 function quickDiff(c1, c2){
\r
317 var len1 = c1.length;
\r
322 for(var i = 0; i < len1; i++){
\r
326 for(var i = 0, len = c2.length; i < len; i++){
\r
327 if(c2[i]._qdiff != d){
\r
328 r[r.length] = c2[i];
\r
334 function quickId(ns, mode, root, id){
\r
336 var d = root.ownerDocument || root;
\r
337 return d.getElementById(id);
\r
339 ns = getNodes(ns, mode, "*");
\r
340 return byId(ns, null, id);
\r
343 function search(path, root, type) {
\r
344 type = type || "select";
\r
346 var n = root || document;
\r
348 var q = path, mode, lq;
\r
349 var tk = Ext.DomQuery.matchers;
\r
350 var tklen = tk.length;
\r
353 var lmode = q.match(modeRe);
\r
354 if(lmode && lmode[1]){
\r
355 mode=lmode[1].replace(trimRe, "");
\r
356 q = q.replace(lmode[1], "");
\r
358 while(path.substr(0, 1)=="/"){
\r
359 path = path.substr(1);
\r
361 while(q && lq != q){
\r
363 var tm = q.match(tagTokenRe);
\r
364 if(type == "select"){
\r
367 n = quickId(n, mode, root, tm[2]);
\r
369 n = getNodes(n, mode, tm[2]);
\r
371 q = q.replace(tm[0], "");
\r
372 }else if(q.substr(0, 1) != '@'){
\r
373 n = getNodes(n, mode, "*");
\r
378 n = byId(n, null, tm[2]);
\r
380 n = byTag(n, tm[2]);
\r
382 q = q.replace(tm[0], "");
\r
385 while(!(mm = q.match(modeRe))){
\r
386 var matched = false;
\r
387 for(var j = 0; j < tklen; j++){
\r
389 var m = q.match(t.re);
\r
393 n = byClassName(n, null, " " + m[1] +" ");
\r
396 n = byPseudo(n, m[1], m[2]);
\r
399 n = byAttribute(n, m[2], m[4], m[3], m[1]);
\r
402 n = byId(n, null, m[1]);
\r
405 return {firstChild:{nodeValue:attrValue(n, m[1])}};
\r
408 q = q.replace(m[0], "");
\r
415 throw 'Error parsing selector, parsing failed at "' + q + '"';
\r
419 mode=mm[1].replace(trimRe, "");
\r
420 q = q.replace(mm[1], "");
\r
427 getStyle : function(el, name){
\r
428 return Ext.fly(el).getStyle(name);
\r
431 compile: function(path, type) {
\r
432 return function(root) {
\r
433 return search(path, root, type);
\r
438 select : function(path, root, type){
\r
439 if(!root || root == document){
\r
442 if(typeof root == "string"){
\r
443 root = document.getElementById(root);
\r
445 var paths = path.split(",");
\r
447 for(var i = 0, len = paths.length; i < len; i++){
\r
448 var p = paths[i].replace(trimRe, "");
\r
450 cache[p] = Ext.DomQuery.compile(p);
\r
452 throw p + " is not a valid selector";
\r
455 var result = cache[p](root);
\r
456 if(result && result != document){
\r
457 results = results.concat(result);
\r
460 if(paths.length > 1){
\r
461 return nodup(results);
\r
467 selectNode : function(path, root){
\r
468 return Ext.DomQuery.select(path, root)[0];
\r
472 selectValue : function(path, root, defaultValue){
\r
473 path = path.replace(trimRe, "");
\r
474 if(!valueCache[path]){
\r
475 valueCache[path] = Ext.DomQuery.compile(path, "select");
\r
477 var n = valueCache[path](root);
\r
478 n = n[0] ? n[0] : n;
\r
479 var v = (n && n.firstChild ? n.firstChild.nodeValue : null);
\r
480 return ((v === null||v === undefined||v==='') ? defaultValue : v);
\r
484 selectNumber : function(path, root, defaultValue){
\r
485 var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
\r
486 return parseFloat(v);
\r
490 is : function(el, ss){
\r
491 if(typeof el == "string"){
\r
492 el = document.getElementById(el);
\r
494 var isArray = Ext.isArray(el);
\r
495 var result = Ext.DomQuery.filter(isArray ? el : [el], ss);
\r
496 return isArray ? (result.length == el.length) : (result.length > 0);
\r
500 filter : function(els, ss, nonMatches){
\r
501 ss = ss.replace(trimRe, "");
\r
502 if(!simpleCache[ss]){
\r
503 simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
\r
505 var result = simpleCache[ss](els);
\r
506 return nonMatches ? quickDiff(result, els) : result;
\r
512 select: 'n = byClassName(n, null, " {1} ");'
\r
514 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
\r
515 select: 'n = byPseudo(n, "{1}", "{2}");'
\r
517 re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
\r
518 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
\r
521 select: 'n = byId(n, null, "{1}");'
\r
524 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
\r
530 "=" : function(a, v){
\r
533 "!=" : function(a, v){
\r
536 "^=" : function(a, v){
\r
537 return a && a.substr(0, v.length) == v;
\r
539 "$=" : function(a, v){
\r
540 return a && a.substr(a.length-v.length) == v;
\r
542 "*=" : function(a, v){
\r
543 return a && a.indexOf(v) !== -1;
\r
545 "%=" : function(a, v){
\r
546 return (a % v) == 0;
\r
548 "|=" : function(a, v){
\r
549 return a && (a == v || a.substr(0, v.length+1) == v+'-');
\r
551 "~=" : function(a, v){
\r
552 return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
\r
558 "first-child" : function(c){
\r
559 var r = [], ri = -1, n;
\r
560 for(var i = 0, ci; ci = n = c[i]; i++){
\r
561 while((n = n.previousSibling) && n.nodeType != 1);
\r
569 "last-child" : function(c){
\r
570 var r = [], ri = -1, n;
\r
571 for(var i = 0, ci; ci = n = c[i]; i++){
\r
572 while((n = n.nextSibling) && n.nodeType != 1);
\r
580 "nth-child" : function(c, a) {
\r
581 var r = [], ri = -1;
\r
582 var m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a);
\r
583 var f = (m[1] || 1) - 0, l = m[2] - 0;
\r
584 for(var i = 0, n; n = c[i]; i++){
\r
585 var pn = n.parentNode;
\r
586 if (batch != pn._batch) {
\r
588 for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
\r
589 if(cn.nodeType == 1){
\r
590 cn.nodeIndex = ++j;
\r
596 if (l == 0 || n.nodeIndex == l){
\r
599 } else if ((n.nodeIndex + l) % f == 0){
\r
607 "only-child" : function(c){
\r
608 var r = [], ri = -1;;
\r
609 for(var i = 0, ci; ci = c[i]; i++){
\r
610 if(!prev(ci) && !next(ci)){
\r
617 "empty" : function(c){
\r
618 var r = [], ri = -1;
\r
619 for(var i = 0, ci; ci = c[i]; i++){
\r
620 var cns = ci.childNodes, j = 0, cn, empty = true;
\r
621 while(cn = cns[j]){
\r
623 if(cn.nodeType == 1 || cn.nodeType == 3){
\r
635 "contains" : function(c, v){
\r
636 var r = [], ri = -1;
\r
637 for(var i = 0, ci; ci = c[i]; i++){
\r
638 if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
\r
645 "nodeValue" : function(c, v){
\r
646 var r = [], ri = -1;
\r
647 for(var i = 0, ci; ci = c[i]; i++){
\r
648 if(ci.firstChild && ci.firstChild.nodeValue == v){
\r
655 "checked" : function(c){
\r
656 var r = [], ri = -1;
\r
657 for(var i = 0, ci; ci = c[i]; i++){
\r
658 if(ci.checked == true){
\r
665 "not" : function(c, ss){
\r
666 return Ext.DomQuery.filter(c, ss, true);
\r
669 "any" : function(c, selectors){
\r
670 var ss = selectors.split('|');
\r
671 var r = [], ri = -1, s;
\r
672 for(var i = 0, ci; ci = c[i]; i++){
\r
673 for(var j = 0; s = ss[j]; j++){
\r
674 if(Ext.DomQuery.is(ci, s)){
\r
683 "odd" : function(c){
\r
684 return this["nth-child"](c, "odd");
\r
687 "even" : function(c){
\r
688 return this["nth-child"](c, "even");
\r
691 "nth" : function(c, a){
\r
692 return c[a-1] || [];
\r
695 "first" : function(c){
\r
699 "last" : function(c){
\r
700 return c[c.length-1] || [];
\r
703 "has" : function(c, ss){
\r
704 var s = Ext.DomQuery.select;
\r
705 var r = [], ri = -1;
\r
706 for(var i = 0, ci; ci = c[i]; i++){
\r
707 if(s(ss, ci).length > 0){
\r
714 "next" : function(c, ss){
\r
715 var is = Ext.DomQuery.is;
\r
716 var r = [], ri = -1;
\r
717 for(var i = 0, ci; ci = c[i]; i++){
\r
719 if(n && is(n, ss)){
\r
726 "prev" : function(c, ss){
\r
727 var is = Ext.DomQuery.is;
\r
728 var r = [], ri = -1;
\r
729 for(var i = 0, ci; ci = c[i]; i++){
\r
731 if(n && is(n, ss)){
\r
741 Ext.query = Ext.DomQuery.select;
\r
743 Date.precompileFormats = function(s){
\r
744 var formats = s.split('|');
\r
745 for(var i = 0, len = formats.length;i < len;i++){
\r
746 Date.createNewFormat(formats[i]);
\r
747 Date.createParser(formats[i]);
\r
751 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
754 Ext.ColorPalette.prototype.tpl = new Ext.XTemplate(
\r
755 '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on"> </span></em></a></tpl>'
\r
764 Ext.air.FileProvider = function(config){
\r
765 Ext.air.FileProvider.superclass.constructor.call(this);
\r
767 this.defaultState = {
\r
776 Ext.apply(this, config);
\r
777 this.state = this.readState();
\r
779 var provider = this;
\r
780 air.NativeApplication.nativeApplication.addEventListener('exiting', function(){
\r
781 provider.saveState();
\r
785 Ext.extend(Ext.air.FileProvider, Ext.state.Provider, {
\r
786 file: 'extstate.data',
\r
789 readState : function(){
\r
790 var stateFile = air.File.applicationStorageDirectory.resolvePath(this.file);
\r
791 if(!stateFile.exists){
\r
792 return this.defaultState || {};
\r
795 var stream = new air.FileStream();
\r
796 stream.open(stateFile, air.FileMode.READ);
\r
798 var stateData = stream.readObject();
\r
801 return stateData || this.defaultState || {};
\r
805 saveState : function(name, value){
\r
806 var stateFile = air.File.applicationStorageDirectory.resolvePath(this.file);
\r
807 var stream = new air.FileStream();
\r
808 stream.open(stateFile, air.FileMode.WRITE);
\r
809 stream.writeObject(this.state);
\r
813 Ext.air.NativeObservable = Ext.extend(Ext.util.Observable, {
\r
814 addListener : function(name){
\r
815 this.proxiedEvents = this.proxiedEvents || {};
\r
816 if(!this.proxiedEvents[name]){
\r
817 var instance = this;
\r
818 var f = function(){
\r
819 var args = Array.prototype.slice.call(arguments, 0);
\r
820 args.unshift(name);
\r
821 instance.fireEvent.apply(instance, args);
\r
823 this.proxiedEvents[name] = f;
\r
824 this.getNative().addEventListener(name, f);
\r
826 Ext.air.NativeObservable.superclass.addListener.apply(this, arguments);
\r
830 Ext.air.NativeObservable.prototype.on = Ext.air.NativeObservable.prototype.addListener;
832 Ext.air.NativeWindow = function(config){
\r
833 Ext.apply(this, config);
\r
835 this.id = this.id || Ext.uniqueId();
\r
844 'displayStateChange',
\r
845 'displayStateChanging'
\r
848 Ext.air.NativeWindow.superclass.constructor.call(this);
\r
850 if(!this.instance){
\r
851 var options = new air.NativeWindowInitOptions();
\r
852 options.systemChrome = this.chrome;
\r
853 options.type = this.type;
\r
854 options.resizable = this.resizable;
\r
855 options.minimizable = this.minimizable;
\r
856 options.maximizable = this.maximizable;
\r
857 options.transparent = this.transparent;
\r
859 this.loader = window.runtime.flash.html.HTMLLoader.createRootWindow(false, options, false);
\r
860 this.loader.load(new air.URLRequest(this.file));
\r
862 this.instance = this.loader.window.nativeWindow;
\r
864 this.loader = this.instance.stage.getChildAt(0);
\r
867 var provider = Ext.state.Manager;
\r
868 var b = air.Screen.mainScreen.visibleBounds;
\r
870 var state = provider.get(this.id) || {};
\r
871 provider.set(this.id, state);
\r
873 var win = this.instance;
\r
875 var width = Math.max(state.width || this.width, 100);
\r
876 var height = Math.max(state.height || this.height, 100);
\r
878 var centerX = b.x + ((b.width/2)-(width/2));
\r
879 var centerY = b.y + ((b.height/2)-(height/2));
\r
881 var x = !Ext.isEmpty(state.x, false) ? state.x : (!Ext.isEmpty(this.x, false) ? this.x : centerX);
\r
882 var y = !Ext.isEmpty(state.y, false) ? state.y : (!Ext.isEmpty(this.y, false) ? this.y : centerY);
\r
885 win.height = height;
\r
889 win.addEventListener('move', function(){
\r
890 if(win.displayState != air.NativeWindowDisplayState.MINIMIZED && win.width > 100 && win.height > 100) {
\r
895 win.addEventListener('resize', function(){
\r
896 if (win.displayState != air.NativeWindowDisplayState.MINIMIZED && win.width > 100 && win.height > 100) {
\r
897 state.width = win.width;
\r
898 state.height = win.height;
\r
902 Ext.air.NativeWindowManager.register(this);
\r
903 this.on('close', this.unregister, this);
\r
905 if(this.minimizeToTray){
\r
906 this.initMinimizeToTray(this.trayIcon, this.trayMenu);
\r
911 Ext.extend(Ext.air.NativeWindow, Ext.air.NativeObservable, {
\r
919 transparent: false,
\r
921 getNative : function(){
\r
922 return this.instance;
\r
925 getCenterXY : function(){
\r
926 var b = air.Screen.mainScreen.visibleBounds;
\r
928 x: b.x + ((b.width/2)-(this.width/2)),
\r
929 y: b.y + ((b.height/2)-(this.height/2))
\r
935 Ext.air.SystemTray.hideIcon();
\r
936 this.trayed = false;
\r
938 this.instance.visible = true;
\r
941 activate : function(){
\r
943 this.instance.activate();
\r
947 this.instance.visible = false;
\r
950 close : function(){
\r
951 this.instance.close();
\r
954 isMinimized :function(){
\r
955 return this.instance.displayState == air.NativeWindowDisplayState.MINIMIZED;
\r
958 isMaximized :function(){
\r
959 return this.instance.displayState == air.NativeWindowDisplayState.MAXIMIZED;
\r
962 moveTo : function(x, y){
\r
963 this.x = this.instance.x = x;
\r
964 this.y = this.instance.y = y;
\r
967 resize : function(width, height){
\r
968 this.width = this.instance.width = width;
\r
969 this.height = this.instance.height = height;
\r
972 unregister : function(){
\r
973 Ext.air.NativeWindowManager.unregister(this);
\r
976 initMinimizeToTray : function(icon, menu){
\r
977 var tray = Ext.air.SystemTray;
\r
978 tray.setIcon(icon, this.trayTip);
\r
979 this.on('displayStateChanging', function(e){
\r
980 if(e.afterDisplayState == 'minimized'){
\r
981 e.preventDefault();
\r
984 this.trayed = true;
\r
988 tray.on('click', function(){
\r
993 tray.setMenu(menu);
\r
998 Ext.air.NativeWindow.getRootWindow = function(){
\r
999 return air.NativeApplication.nativeApplication.openedWindows[0];
\r
1002 Ext.air.NativeWindow.getRootHtmlWindow = function(){
\r
1003 return Ext.air.NativeWindow.getRootWindow().stage.getChildAt(0).window;
\r
1006 Ext.air.NativeWindowGroup = function(){
\r
1010 register : function(win){
\r
1011 list[win.id] = win;
\r
1014 unregister : function(win){
\r
1015 delete list[win.id];
\r
1018 get : function(id){
\r
1022 closeAll : function(){
\r
1023 for(var id in list){
\r
1024 if(list.hasOwnProperty(id)){
\r
1031 each : function(fn, scope){
\r
1032 for(var id in list){
\r
1033 if(list.hasOwnProperty(id)){
\r
1034 if(fn.call(scope || list[id], list[id]) === false){
\r
1044 Ext.air.NativeWindowManager = new Ext.air.NativeWindowGroup();
1046 Ext.sql.Connection = function(config){
\r
1047 Ext.apply(this, config);
\r
1048 Ext.sql.Connection.superclass.constructor.call(this);
\r
1056 Ext.extend(Ext.sql.Connection, Ext.util.Observable, {
\r
1057 maxResults: 10000,
\r
1058 openState : false,
\r
1061 open : function(file){
\r
1064 close : function(){
\r
1067 exec : function(sql){
\r
1070 execBy : function(sql, args){
\r
1073 query : function(sql){
\r
1076 queryBy : function(sql, args){
\r
1080 isOpen : function(){
\r
1081 return this.openState;
\r
1084 getTable : function(name, keyName){
\r
1085 return new Ext.sql.Table(this, name, keyName);
\r
1088 createTable : function(o){
\r
1089 var tableName = o.name;
\r
1090 var keyName = o.key;
\r
1091 var fs = o.fields;
\r
1092 if(!Ext.isArray(fs)){
1096 for(var i = 0, len = fs.length; i < len; i++){
\r
1097 var f = fs[i], s = f.name;
\r
1110 if(f.allowNull === false || f.name == keyName){
\r
1113 if(f.name == keyName){
\r
1114 s += ' PRIMARY KEY';
\r
1116 if(f.unique === true){
\r
1120 buf[buf.length] = s;
\r
1122 var sql = ['CREATE TABLE IF NOT EXISTS ', tableName, ' (', buf.join(','), ')'].join('');
\r
1128 Ext.sql.Connection.getInstance = function(db, config){
\r
1130 return new Ext.sql.AirConnection(config);
\r
1132 return new Ext.sql.GearsConnection(config);
\r
1135 Ext.sql.Table = function(conn, name, keyName){
\r
1138 this.keyName = keyName;
\r
1141 Ext.sql.Table.prototype = {
\r
1142 update : function(o){
\r
1143 var clause = this.keyName + " = ?";
\r
1144 return this.updateBy(o, clause, [o[this.keyName]]);
\r
1147 updateBy : function(o, clause, args){
\r
1148 var sql = "UPDATE " + this.name + " set ";
\r
1149 var fs = [], a = [];
\r
1150 for(var key in o){
\r
1151 if(o.hasOwnProperty(key)){
\r
1152 fs[fs.length] = key + ' = ?';
\r
1153 a[a.length] = o[key];
\r
1156 for(var key in args){
\r
1157 if(args.hasOwnProperty(key)){
\r
1158 a[a.length] = args[key];
\r
1161 sql = [sql, fs.join(','), ' WHERE ', clause].join('');
\r
1162 return this.conn.execBy(sql, a);
\r
1165 insert : function(o){
\r
1166 var sql = "INSERT into " + this.name + " ";
\r
1167 var fs = [], vs = [], a = [];
\r
1168 for(var key in o){
\r
1169 if(o.hasOwnProperty(key)){
\r
1170 fs[fs.length] = key;
\r
1171 vs[vs.length] = '?';
\r
1172 a[a.length] = o[key];
\r
1175 sql = [sql, '(', fs.join(','), ') VALUES (', vs.join(','), ')'].join('');
\r
1176 return this.conn.execBy(sql, a);
\r
1179 lookup : function(id){
\r
1180 return this.selectBy('where ' + this.keyName + " = ?", [id])[0] || null;
\r
1183 exists : function(id){
\r
1184 return !!this.lookup(id);
\r
1187 save : function(o){
\r
1188 if(this.exists(o[this.keyName])){
\r
1195 select : function(clause){
\r
1196 return this.selectBy(clause, null);
\r
1199 selectBy : function(clause, args){
\r
1200 var sql = "select * from " + this.name;
\r
1202 sql += ' ' + clause;
\r
1204 args = args || {};
\r
1205 return this.conn.queryBy(sql, args);
\r
1208 remove : function(clause){
\r
1209 this.deleteBy(clause, null);
\r
1212 removeBy : function(clause, args){
\r
1213 var sql = "delete from " + this.name;
\r
1215 sql += ' where ' + clause;
\r
1217 args = args || {};
\r
1218 this.conn.execBy(sql, args);
\r
1221 Ext.sql.Proxy = function(conn, table, keyName, store, readonly){
\r
1222 Ext.sql.Proxy.superclass.constructor.call(this);
\r
1224 this.table = this.conn.getTable(table, keyName);
\r
1225 this.store = store;
\r
1227 if (readonly !== true) {
\r
1228 this.store.on('add', this.onAdd, this);
\r
1229 this.store.on('update', this.onUpdate, this);
\r
1230 this.store.on('remove', this.onRemove, this);
\r
1234 Ext.sql.Proxy.DATE_FORMAT = 'Y-m-d H:i:s';
\r
1236 Ext.extend(Ext.sql.Proxy, Ext.data.DataProxy, {
\r
1237 load : function(params, reader, callback, scope, arg){
\r
1238 if(!this.conn.isOpen()){
1239 this.conn.on('open', function(){
\r
1240 this.load(params, reader, callback, scope, arg);
\r
1241 }, this, {single:true});
\r
1244 if(this.fireEvent("beforeload", this, params, reader, callback, scope, arg) !== false){
\r
1245 var clause = params.where || '';
\r
1246 var args = params.args || [];
\r
1247 var group = params.groupBy;
\r
1248 var sort = params.sort;
\r
1249 var dir = params.dir;
\r
1251 if(group || sort){
\r
1252 clause += ' ORDER BY ';
\r
1253 if(group && group != sort){
\r
1254 clause += group + ' ASC, ';
\r
1256 clause += sort + ' ' + (dir || 'ASC');
\r
1259 var rs = this.table.selectBy(clause, args);
\r
1260 this.onLoad({callback:callback, scope:scope, arg:arg, reader: reader}, rs);
\r
1262 callback.call(scope||this, null, arg, false);
\r
1266 onLoad : function(trans, rs, e, stmt){
\r
1268 this.fireEvent("loadexception", this, null, trans.arg, e);
\r
1269 trans.callback.call(trans.scope||window, null, trans.arg, false);
\r
1272 var result = trans.reader.readRecords(rs);
\r
1273 this.fireEvent("load", this, rs, trans.arg);
\r
1274 trans.callback.call(trans.scope||window, result, trans.arg, true);
\r
1277 processData : function(o){
\r
1278 var fs = this.store.fields;
\r
1280 for(var key in o){
\r
1281 var f = fs.key(key), v = o[key];
\r
1283 if(f.type == 'date'){
\r
1284 r[key] = v ? v.format(Ext.sql.Proxy.DATE_FORMAT,10) : '';
\r
1285 }else if(f.type == 'boolean'){
\r
1286 r[key] = v ? 1 : 0;
\r
1295 onUpdate : function(ds, record){
\r
1296 var changes = record.getChanges();
\r
1297 var kn = this.table.keyName;
\r
1298 this.table.updateBy(this.processData(changes), kn + ' = ?', [record.data[kn]]);
\r
1299 record.commit(true);
\r
1302 onAdd : function(ds, records, index){
\r
1303 for(var i = 0, len = records.length; i < len; i++){
\r
1304 this.table.insert(this.processData(records[i].data));
\r
1308 onRemove : function(ds, record, index){
\r
1309 var kn = this.table.keyName;
\r
1310 this.table.removeBy(kn + ' = ?', [record.data[kn]]);
\r
1313 Ext.sql.AirConnection = Ext.extend(Ext.sql.Connection, {
\r
1315 open : function(db){
\r
1316 this.conn = new air.SQLConnection();
\r
1317 var file = air.File.applicationDirectory.resolvePath(db);
\r
1318 this.conn.open(file);
\r
1319 this.openState = true;
\r
1320 this.fireEvent('open', this);
\r
1323 close : function(){
\r
1324 this.conn.close();
\r
1325 this.fireEvent('close', this);
\r
1328 createStatement : function(type){
\r
1329 var stmt = new air.SQLStatement();
\r
1330 stmt.sqlConnection = this.conn;
\r
1334 exec : function(sql){
\r
1335 var stmt = this.createStatement('exec');
\r
1340 execBy : function(sql, args){
\r
1341 var stmt = this.createStatement('exec');
\r
1343 this.addParams(stmt, args);
\r
1347 query : function(sql){
\r
1348 var stmt = this.createStatement('query');
\r
1350 stmt.execute(this.maxResults);
\r
1351 return this.readResults(stmt.getResult());
\r
1354 queryBy : function(sql, args){
\r
1355 var stmt = this.createStatement('query');
\r
1357 this.addParams(stmt, args);
\r
1358 stmt.execute(this.maxResults);
\r
1359 return this.readResults(stmt.getResult());
\r
1362 addParams : function(stmt, args){
\r
1363 if(!args){ return; }
\r
1364 for(var key in args){
\r
1365 if(args.hasOwnProperty(key)){
\r
1367 var v = args[key];
\r
1368 if(Ext.isDate(v)){
\r
1369 v = v.format(Ext.sql.Proxy.DATE_FORMAT);
\r
1371 stmt.parameters[parseInt(key)] = v;
\r
1373 stmt.parameters[':' + key] = args[key];
\r
1380 readResults : function(rs){
\r
1382 if(rs && rs.data){
\r
1383 var len = rs.data.length;
\r
1384 for(var i = 0; i < len; i++) {
\r
1385 r[r.length] = rs.data[i];
\r
1391 Ext.air.SystemTray = function(){
\r
1392 var app = air.NativeApplication.nativeApplication;
\r
1393 var icon, isWindows = false, bitmaps;
\r
1396 if(air.NativeApplication.supportsSystemTrayIcon) {
\r
1402 if(air.NativeApplication.supportsDockIcon) {
\r
1408 setIcon : function(icon, tooltip, initWithIcon){
\r
1412 var loader = new air.Loader();
\r
1413 loader.contentLoaderInfo.addEventListener(air.Event.COMPLETE, function(e){
\r
1414 bitmaps = new runtime.Array(e.target.content.bitmapData);
\r
1415 if (initWithIcon) {
\r
1416 icon.bitmaps = bitmaps;
\r
1419 loader.load(new air.URLRequest(icon));
\r
1420 if(tooltip && air.NativeApplication.supportsSystemTrayIcon) {
\r
1421 app.icon.tooltip = tooltip;
\r
1425 bounce : function(priority){
\r
1426 icon.bounce(priority);
\r
1429 on : function(eventName, fn, scope){
\r
1430 icon.addEventListener(eventName, function(){
\r
1431 fn.apply(scope || this, arguments);
\r
1435 hideIcon : function(){
\r
1439 icon.bitmaps = [];
\r
1442 showIcon : function(){
\r
1446 icon.bitmaps = bitmaps;
\r
1449 setMenu: function(actions, _parentMenu){
\r
1453 var menu = new air.NativeMenu();
\r
1455 for (var i = 0, len = actions.length; i < len; i++) {
\r
1456 var a = actions[i];
\r
1458 menu.addItem(new air.NativeMenuItem("", true));
\r
1460 var item = menu.addItem(Ext.air.MenuItem(a));
\r
1461 if(a.menu || (a.initialConfig && a.initialConfig.menu)){
\r
1462 item.submenu = Ext.air.SystemTray.setMenu(a.menu || a.initialConfig.menu, menu);
\r
1477 Ext.air.DragType = {
\r
1478 TEXT : 'text/plain',
\r
1479 HTML : 'text/html',
\r
1480 URL : 'text/uri-list',
\r
1481 BITMAP : 'image/x-vnd.adobe.air.bitmap',
\r
1482 FILES : 'application/x-vnd.adobe.air.file-list'
\r
1485 Ext.apply(Ext.EventObjectImpl.prototype, {
\r
1486 hasFormat : function(format){
\r
1487 if (this.browserEvent.dataTransfer) {
\r
1488 for (var i = 0, len = this.browserEvent.dataTransfer.types.length; i < len; i++) {
\r
1489 if(this.browserEvent.dataTransfer.types[i] == format) {
\r
1497 getData : function(type){
\r
1498 return this.browserEvent.dataTransfer.getData(type);
\r
1505 play : function(file, startAt){
\r
1506 var soundFile = air.File.applicationDirectory.resolvePath(file);
\r
1507 var sound = new air.Sound();
\r
1508 sound.load(new air.URLRequest(soundFile.url));
\r
1509 sound.play(startAt);
\r
1514 Ext.air.SystemMenu = function(){
\r
1517 if(air.NativeWindow.supportsMenu && nativeWindow.systemChrome != air.NativeWindowSystemChrome.NONE) {
\r
1518 menu = new air.NativeMenu();
\r
1519 nativeWindow.menu = menu;
\r
1523 if(air.NativeApplication.supportsMenu) {
\r
1524 menu = air.NativeApplication.nativeApplication.menu;
\r
1527 function find(menu, text){
\r
1528 for(var i = 0, len = menu.items.length; i < len; i++){
\r
1529 if(menu.items[i]['label'] == text){
\r
1530 return menu.items[i];
\r
1537 add: function(text, actions, mindex){
\r
1539 var item = find(menu, text);
\r
1541 item = menu.addItem(new air.NativeMenuItem(text));
\r
1542 item.mnemonicIndex = mindex || 0;
\r
1544 item.submenu = new air.NativeMenu();
\r
1546 for (var i = 0, len = actions.length; i < len; i++) {
\r
1547 item.submenu.addItem(actions[i] == '-' ? new air.NativeMenuItem("", true) : Ext.air.MenuItem(actions[i]));
\r
1549 return item.submenu;
\r
1559 Ext.air.MenuItem = function(action){
\r
1560 if(!action.isAction){
\r
1561 action = new Ext.Action(action);
\r
1563 var cfg = action.initialConfig;
\r
1564 var nativeItem = new air.NativeMenuItem(cfg.itemText || cfg.text);
\r
1566 nativeItem.enabled = !cfg.disabled;
\r
1568 if(!Ext.isEmpty(cfg.checked)){
\r
1569 nativeItem.checked = cfg.checked;
\r
1572 var handler = cfg.handler;
\r
1573 var scope = cfg.scope;
\r
1575 nativeItem.addEventListener(air.Event.SELECT, function(){
\r
1576 handler.call(scope || window, cfg);
\r
1579 action.addComponent({
\r
1580 setDisabled : function(v){
\r
1581 nativeItem.enabled = !v;
\r
1584 setText : function(v){
\r
1585 nativeItem.label = v;
\r
1588 setVisible : function(v){
\r
1590 nativeItem.enabled = !v;
\r
1593 setHandler : function(newHandler, newScope){
\r
1594 handler = newHandler;
\r
1601 return nativeItem;
\r