-
Notifications
You must be signed in to change notification settings - Fork 49
/
apf.js
2561 lines (2245 loc) · 94.7 KB
/
apf.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
*/
//#ifndef __WITH_O3
/**
* Ajax.org Platform
*
* @author Ruben Daniels (ruben AT ajax DOT org)
* @version 3.0
* @url http://www.ajax.org
*
* @event domready Fires when the browsers' dom is ready to be manipulated.
* @event movefocus Fires when the focus moves from one element to another.
* object:
* {AMLElement} toElement the element that will receive the focus.
* @event exit Fires when the application wants to exit.
* cancelable: Prevents the application from exiting. The returnValue of the
* event object is displayed in a popup which asks the user for permission.
* @event keyup Fires when the user stops pressing a key.
* cancelable: Prevents the behaviour.
* object:
* {Number} keyCode the char code of the pressed key.
* {Boolean} ctrlKey whether the ctrl key was pressed.
* {Boolean} shiftKey whether the shift key was pressed.
* {Boolean} altKey whether the alt key was pressed.
* {Object} htmlEvent the html event object.
* @event mousescroll Fires when the user scrolls the mouse
* cancelable: Prevents the container to scroll
* object:
* {Number} delta the scroll impulse.
* @event hotkey Fires when the user presses a hotkey
* bubbles: yes
* cancelable: Prevents the default hotkey behaviour.
* object:
* {Number} keyCode the char code of the pressed key.
* {Boolean} ctrlKey whether the ctrl key was pressed.
* {Boolean} shiftKey whether the shift key was pressed.
* {Boolean} altKey whether the alt key was pressed.
* {Object} htmlEvent the html event object.
* @event keydown Fires when the user presses a key
* bubbles: yes
* cancelable: Prevents the behaviour.
* object:
* {Number} keyCode the char code of the pressed key.
* {Boolean} ctrlKey whether the ctrl key was pressed.
* {Boolean} shiftKey whether the shift key was pressed.
* {Boolean} altKey whether the alt key was pressed.
* {Object} htmlEvent the html event object.
* @event mousedown Fires when the user presses a mouse button
* object:
* {Event} htmlEvent the char code of the pressed key.
* {AMLElement} amlNode the element on which is clicked.
* @event onbeforeprint Fires before the application will print.
* @event onafterprint Fires after the application has printed.
* @event load Fires after the application is loaded.
* @event error Fires when a communication error has occured while making a request for this element.
* cancelable: Prevents the error from being thrown.
* bubbles:
* object:
* {Error} error the error object that is thrown when the event callback doesn't return false.
* {Number} state the state of the call
* Possible values:
* apf.SUCCESS the request was successfull
* apf.TIMEOUT the request has timed out.
* apf.ERROR an error has occurred while making the request.
* apf.OFFLINE the request was made while the application was offline.
* {mixed} userdata data that the caller wanted to be available in the callback of the http request.
* {XMLHttpRequest} http the object that executed the actual http request.
* {String} url the url that was requested.
* {Http} tpModule the teleport module that is making the request.
* {Number} id the id of the request.
* {String} message the error message.
* @default_private
*/
var apf = {
// Content Distribution Network URL:
// #ifndef __WITH_CDN
/**
* The url to the content delivery network.
* @type {String}
*/
CDN : "",
/* #else
CDN : "http://cdn.ajax.org/platform/",
#endif */
/**
* Boolean specifying whether apf is ready for dom operations.
* @type {Boolean}
*/
READY : false,
//AML nodeFunc constants
/**
* Constant for a hidden aml element.
* @type {Number}
*/
NODE_HIDDEN : 101,
/**
* Constant for a visible aml element.
* @type {Number}
*/
NODE_VISIBLE : 102,
/**
* Constant for an o3 widget.
* @type {Number}
*/
NODE_O3 : 103,
/**
* Constant for specifying that a widget is using only the keyboard to receive focus.
* @type {Number}
* @see baseclass.guielement.method.focus
*/
KEYBOARD : 2,
/**
* Constant for specifying that a widget is using the keyboard or the mouse to receive focus.
* @type {Boolean}
* @see baseclass.guielement.method.focus
*/
KEYBOARD_MOUSE : true,
/**
* Constant for specifying success.
* @type {Number}
* @see element.teleport
*/
SUCCESS : 1,
/**
* Constant for specifying a timeout.
* @type {Number}
* @see element.teleport
*/
TIMEOUT : 2,
/**
* Constant for specifying an error.
* @type {Number}
* @see element.teleport
*/
ERROR : 3,
/**
* Constant for specifying the application is offline.
* @type {Number}
* @see element.teleport
*/
OFFLINE : 4,
//#ifdef __DEBUG
debug : true,
debugType : "Memory",
debugFilter : "!teleport",
/* #else
debug : false,
#endif */
includeStack : [],
initialized : false,
AppModules : [],
/**
* Boolean specifying whether apf tries to load a skin from skins.xml when no skin element is specified.
* @type {Boolean}
*/
autoLoadSkin : false,
/**
* Boolean specifying whether apf has started loading scripts and started the init process.
* @type {Boolean}
*/
started : false,
/**
* Namespace for all crypto libraries included with Ajax.org Platform.
*/
crypto : {}, //namespace
config : {},
_GET : {},
$asyncObjects : {"apf.oHttp" : 1, "apf.ajax": 1},
/**
* String specifying the basepath for loading apf from seperate files.
* @type {String}
*/
basePath : "",
//#ifdef __PARSER_AML
/**
* {Object} contains several known and often used namespace URI's.
* @private
*/
ns : {
apf : "http://ajax.org/2005/aml",
aml : "http://ajax.org/2005/aml",
xsd : "http://www.w3.org/2001/XMLSchema",
xhtml : "http://www.w3.org/1999/xhtml",
xslt : "http://www.w3.org/1999/XSL/Transform",
xforms : "http://www.w3.org/2002/xforms",
ev : "http://www.w3.org/2001/xml-events"
},
//#endif
xPathAxis : {"self":1, "following-sibling":1, "ancestor":1}, //@todo finish list
hasRequireJS : window.require && typeof require.def == "function",
availHTTP : [],
/**
* @private
*/
releaseHTTP: function(http){
if (apf.brokenHttpAbort)
return;
if (self.XMLHttpRequestUnSafe && http.constructor == XMLHttpRequestUnSafe)
return;
http.onreadystatechange = function(){};
http.abort();
this.availHTTP.push(http);
},
/**
* @private
*/
browserDetect : function(){
if (this.$bdetect)
return;
this.$bdetect = true;
// Browser Detection, using feature inference methods where possible:
// http://www.thespanner.co.uk/2009/01/29/detecting-browsers-javascript-hacks/
// http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
// http://sla.ckers.org/forum/read.php?24,31765,33730
var sAgent = navigator.userAgent.toLowerCase() || "",
// 1->IE, 0->FF, 2->GCrome, 3->Safari, 4->Opera, 5->Konqueror
b = (typeof/./)[0]=='f'?+'1\0'?3:2:+'1\0'?5:1-'\0'?1:+{valueOf:function(x){return!x}}?4:0;
/*
* Fix for firefox older than 2
* Older versions of firefox have (typeof/./) = function
* So firefox to be treated as Chrome, since the above expresion will return 2
* Newer versions have (typeof/./) = object
*
*/
if((typeof/./)[0]=='f' && parseFloat((sAgent.match(/(?:firefox|minefield)\/([\d\.]+)/i) || {})[1]) <= 2)
b = 0;
if (b == 2 && sAgent.indexOf("chrome") == -1)
b = 3;
/**
* Specifies whether the application is running in the Opera browser.
* @type {Boolean}
*/
this.isOpera = b===4 || b===5;//(self.opera && Object.prototype.toString.call(self.opera) == "[object Opera]");
//b = 5 for Opera 9
/**
* Specifies whether the application is running in the Konqueror browser.
* @type {Boolean}
*/
this.isKonqueror = b===5;//sAgent.indexOf("konqueror") != -1;
/**
* Specifies whether the application is running in the Safari browser.
* @type {Boolean}
*/
this.isSafari = b===3;//a/.__proto__ == "//";
/**
* Specifies whether the application is running in the Safari browser version 2.4 or below.
* @type {Boolean}
*/
this.isSafariOld = false;
/**
* Specifies whether the application is running on the Iphone.
* @type {Boolean}
*/
this.isIphone = sAgent.indexOf("iphone") != -1 || sAgent.indexOf("aspen simulator") != -1;
/**
* Specifies whether the application is running in the Chrome browser.
* @type {Boolean}
*/
this.isChrome = b===2;//Boolean(/source/.test((/a/.toString + ""))) || sAgent.indexOf("chrome") != -1;
/**
* Specifies whether the application is running in a Webkit-based browser
* @type {Boolean}
*/
this.isWebkit = this.isSafari || this.isChrome || this.isKonqueror;
if (this.isWebkit) {
var matches = sAgent.match(/applewebkit\/(\d+)/);
if (matches) {
this.webkitRev = parseInt(matches[1])
this.isSafariOld = parseInt(matches[1]) < 420;
}
}
/**
* Specifies whether the application is running in the AIR runtime.
* @type {Boolean}
*/
this.isAIR = sAgent.indexOf("adobeair") != -1;
/**
* Specifies whether the application is running in a Gecko based browser.
* @type {Boolean}
*/
this.isGecko = b===0;//(function(o) { o[o] = o + ""; return o[o] != o + ""; })(new String("__count__"));
/**
* Specifies whether the application is running in the Firefox browser version 3.
* @type {Boolean}
*/
this.isGecko3 = this.isGecko;// && (function x(){})[-5] == "x";
this.isGecko35 = this.isGecko && (/a/[-1] && Object.getPrototypeOf) ? true : false;
this.versionGecko = this.isGecko ? parseFloat(sAgent.match(/(?:gecko)\/([\d\.]+)/i)[1]) : -1;
this.versionFF = this.isGecko ? parseFloat(sAgent.match(/(?:firefox(-[\d.]+)?|minefield)\/([\d.]+)/i)[2]) : -1;
this.versionSafari = this.isSafari && !this.isAIR ? parseFloat(sAgent.match(/(?:version)\/([\d\.]+)/i)[1]) : -1;
this.versionChrome = this.isChrome ? parseFloat(sAgent.match(/(?:chrome)\/([\d\.]+)/i)[1]) : -1;
this.versionOpera = this.isOpera
? parseFloat(sAgent.match(b===4
? /(?:version)\/([\d\.]+)/i
: /(?:opera)\/([\d\.]+)/i)[1])
: -1;
var found;
/**
* Specifies whether the application is running in the Internet Explorer browser, any version.
* @type {Boolean}
*/
this.isIE = b===1;//! + "\v1";
if (this.isIE)
this.isIE = parseFloat(sAgent.match(/msie ([\d\.]*)/)[1]);
/**
* Specifies whether the application is running in the Internet Explorer browser version 8.
* @type {Boolean}
*/
this.isIE8 = this.isIE == 8 && (found = true);
/**
* Specifies whether the application is running in the Internet Explorer browser version 7.
* @type {Boolean}
*/
this.isIE7 = !found && this.isIE == 7 && (found = true);
//Mode detection
if (document.documentMode == 7) { //this.isIE == 7 &&
apf.isIE7 = true;
apf.isIE8 = false;
apf.isIE7Emulate = true;
apf.isIE = 7;
}
/**
* Specifies whether the application is running in the Internet Explorer browser version 6.
* @type {Boolean}
*/
this.isIE6 = !found && this.isIE == 6 && (found = true);
var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
/**
* Specifies whether the application is running on the Windows operating system.
* @type {Boolean}
*/
this.isWin = (os == "win");
/**
* Specifies whether the application is running in the OSX operating system..
* @type {Boolean}
*/
this.isMac = (os == "mac");
/**
* Specifies whether the application is running in the OSX operating system..
* @type {Boolean}
*/
this.isLinux = (os == "linux");
/*#ifdef __SUPPORT_GWT
this.isGWT = true;
#endif*/
//#ifdef __DESKRUN
try {
//this.isDeskrun = window.external.shell.runtime == 2;
}
catch(e) {
/**
* Specifies whether the application is running in the Deskrun runtime.
* @type {Boolean}
*/
this.isDeskrun = false;
}
//#endif
},
/**
* @private
*/
setCompatFlags : function(){
//Set Compatibility
this.TAGNAME = apf.isIE ? "baseName" : "localName";
this.styleSheetRules = apf.isIE ? "rules" : "cssRules";
this.brokenHttpAbort = apf.isIE6;
this.canUseHtmlAsXml = apf.isIE;
this.supportNamespaces = !apf.isIE;
this.cannotSizeIframe = apf.isIE;
this.hasConditionCompilation = apf.isIE;
this.supportOverflowComponent = apf.isIE;
this.hasFlexibleBox = apf.versionGecko > 2 || apf.webkitRev > 2; //@todo check this
this.hasEventSrcElement = apf.isIE;
this.canHaveHtmlOverSelects = !apf.isIE6 && !apf.isIE5;
this.hasInnerText = apf.isIE;
this.hasMsRangeObject = apf.isIE;
this.descPropJs = apf.isIE;
this.hasClickFastBug = apf.isIE;
this.hasExecScript = window.execScript ? true : false;
this.canDisableKeyCodes = apf.isIE;
this.hasTextNodeWhiteSpaceBug = apf.isIE || apf.isIE >= 8;
this.hasCssUpdateScrollbarBug = apf.isIE;
this.canUseInnerHtmlWithTables = !apf.isIE;
this.hasSingleResizeEvent = !apf.isIE;
this.hasStyleFilters = apf.isIE;
this.supportOpacity = !apf.isIE;
this.supportPng24 = !apf.isIE6 && !apf.isIE5;
this.cantParseXmlDefinition = apf.isIE50;
this.hasDynamicItemList = !apf.isIE || apf.isIE >= 7;
this.canImportNode = apf.isIE;
this.hasSingleRszEvent = !apf.isIE;
this.hasXPathHtmlSupport = !apf.isIE;
this.hasFocusBug = apf.isIE;
this.hasHeightAutoDrawBug = apf.isIE && apf.isIE < 8;
//this.hasIndexOfNodeList = !apf.isIE;
this.hasReadyStateBug = apf.isIE50;
this.dateSeparator = apf.isIE ? "-" : "/";
this.canCreateStyleNode = !apf.isIE;
this.supportFixedPosition = !apf.isIE || apf.isIE >= 7;
this.hasHtmlIdsInJs = apf.isIE && apf.isIE < 8 || apf.isWebkit;
this.needsCssPx = !apf.isIE;
this.hasCSSChildOfSelector = !apf.isIE || apf.isIE >= 8;
this.hasStyleAnchors = !apf.isIE || apf.isIE >= 8;
this.styleAttrIsObj = apf.isIE < 8;
this.hasAutocompleteXulBug = apf.isGecko;
this.loadsLocalFilesSync = apf.isIE || apf.isGecko;
this.mouseEventBuffer = apf.isIE ? 20 : 6;
this.hasComputedStyle = typeof document.defaultView != "undefined"
&& typeof document.defaultView.getComputedStyle != "undefined";
this.w3cRange = Boolean(window["getSelection"]);
this.locale = (apf.isIE
? navigator.userLanguage
: navigator.language).toLowerCase();
this.characterSet = document.characterSet || document.defaultCharset || "utf-8";
var t = document.createElement("div");
this.hasContentEditable = (typeof t.contentEditable == "string"
|| typeof t.contentEditable == "boolean");
apf.hasContentEditableContainerBug = apf.isWebkit;
// Try transform first for forward compatibility
var props = ["transform", "OTransform", "KhtmlTransform", "MozTransform", "WebkitTransform"],
prefixR = ["", "O", "Khtml", "Moz", "Webkit"],
prefixC = ["", "o-", "khtml-", "moz-", "webkit-"],
events = ["transitionend", "transitionend", "transitionend", "transitionend", "webkitTransitionEnd"],
i = 0,
l = 5;
this.supportCSSAnim = false;
this.supportCSSTransition = false;
for (; i < l && !this.supportCSSAnim; ++i) {
if (typeof t.style[props[i]] == "undefined") continue;
this.supportCSSAnim = props[i];
this.runtimeStylePrefix = prefixR[i];
this.classNamePrefix = prefixC[i];
this.cssAnimEvent = events[i];
}
t = null;
delete t;
this.supportVML = apf.isIE;
this.supportSVG = !apf.isIE || apf.isIE > 8;
this.hasHtml5XDomain = apf.versionGecko >= 3.5;
this.supportCanvas = !!document.createElement("canvas").getContext;
this.supportCanvasText = !!(this.supportCanvas
&& typeof document.createElement("canvas").getContext("2d").fillText == "function")
this.hasVideo = !!document.createElement("video")["canPlayType"];
this.hasAudio = !!document.createElement("audio")["canPlayType"];
this.supportHashChange = ("onhashchange" in self) && (!apf.isIE || apf.isIE >= 8);
if (self.XMLHttpRequest) {
var xhr = new XMLHttpRequest();
this.hasXhrProgress = !!xhr.upload;
if (this.hasXhrBinary = !!(xhr.sendAsBinary || xhr.upload)) {
this.hasHtml5File = !!(File && File.prototype.getAsDataURL);
this.hasHtml5FileSlice = !!(File && File.prototype.slice);
}
}
else {
this.hasXhrProgress = this.hasXhrBinary = this.hasHtml5File
= this.hasHtml5FileSlice = false;
}
this.windowHorBorder =
this.windowVerBorder = apf.isIE8 && (!self.frameElement
|| parseInt(self.frameElement.frameBorder)) ? 4 : 0;
//#ifdef __WITH_HTML5_TEST
// Run through HTML5's new input types to see if the UA understands any.
// This is put behind the tests runloop because it doesn't return a
// true/false like all the other tests; instead, it returns an array
// containing properties that represent the 'supported' input types.
t = document.createElement("input");
var _self = this;
(function(props) {
for (var i in props) {
t.setAttribute("type", i);
_self["hasInput" + i.charAt(0).toUpperCase()
+ i.substr(1).replace("-l", "L")] = !!(t.type !== "text");
}
})({"search":1, "tel":1, "url":1, "email":1, "datetime":1, "date":1,
"month":1, "week":1, "time":1, "datetime-local":1, "number":1,
"range":1, "color":1});
t = null;
delete t;
//#endif
this.enableAnim = !apf.isIE || apf.isIE > 8;
this.animSteps = apf.isIE ? 0.3 : 1;
this.animInterval = apf.isIE ? 7 : 1;
this.CSSFLOAT = apf.isIE ? "styleFloat" : "cssFloat";
this.CSSPREFIX = apf.isGecko ? "Moz" : (apf.isWebkit ? "webkit" : "");
this.CSSPREFIX2 = apf.isGecko ? "-moz" : (apf.isWebkit ? "-webkit" : "");
this.INLINE = apf.isIE && apf.isIE < 8 ? "inline" : "inline-block";
this.needZoomForLayout = apf.isIE && apf.isIE < 8;
//Other settings
this.maxHttpRetries = apf.isOpera ? 0 : 3;
//#ifdef __WITH_ANCHORING
this.percentageMatch = new RegExp();
this.percentageMatch.compile("([\\-\\d\\.]+)\\%", "g");
//#endif
this.reMatchXpath = new RegExp();
this.reMatchXpath.compile("(^|\\|)(?!\\@|[\\w-]+::)", "g");
//#ifdef __SUPPORT_GEARS
apf.isGears = !!apf.initGears() || 0;
//#endif
},
hasGeoLocation: function() {
//#ifdef __WITH_GEOLOCATION
return typeof apf.geolocation != "undefined" && apf.geolocation.init();
/*#else
return false;
#endif*/
},
//#ifdef __DEBUG
/**
* Restarts the application.
*/
reboot : function(){
apf.console.info("Restarting application...");
location.href = location.href;
},
//#endif
/**
* Extends an object with one or more other objects by copying all their
* properties.
* @param {Object} dest the destination object.
* @param {Object} src the object that is copies from.
* @return {Object} the destination object.
*/
extend : function(dest, src){
var prop, i, x = !dest.notNull;
if (arguments.length == 2) {
for (prop in src) {
if (x || src[prop])
dest[prop] = src[prop];
}
return dest;
}
for (i = 1; i < arguments.length; i++) {
src = arguments[i];
for (prop in src) {
if (x || src[prop])
dest[prop] = src[prop];
}
}
return dest;
},
$extend : function(dest, src){
for (var prop in src) {
dest[prop] = src[prop];
}
return dest;
},
// #ifdef __TP_HTTP
/**
* Sends and retrieves data from remote locations over http.
* Example:
* <code>
* var content = apf.ajax("http://www.ajax.org", {
* method : "POST",
* data : "<data />",
* async : false,
* callback : function( data, state ) {
* if (state == apf.SUCCESS)
* alert("Success");
* else
* alert("Failure")
* }
* });
* alert(content);
* </code>
*
* @param {String} url the url that is accessed.
* @param {Object} options the options for the http request
* Properties:
* {Boolean} async whether the request is sent asynchronously. Defaults to true.
* {mixed} userdata custom data that is available to the callback function.
* {String} method the request method (POST|GET|PUT|DELETE). Defaults to GET.
* {Boolean} nocache whether browser caching is prevented.
* {String} data the data sent in the body of the message.
* {Boolean} useXML whether the result should be interpreted as xml.
* {Boolean} autoroute whether the request can fallback to a server proxy.
* {Boolean} caching whether the request should use internal caching.
* {Boolean} ignoreOffline whether to ignore offline catching.
* {String} contentType the mime type of the message
* {Function} callback the handler that gets called whenever the
* request completes succesfully or with an error,
* or when the request times out.
*/
ajax : (function(){
var f = function(){
return this.oHttp.get.apply(this.oHttp, arguments);
};
f.exec = function(method, args, callback, options){
if (method == "ajax" && args[0]) {
var opt = args[1] || {};
return this.oHttp.exec(opt.method || "GET", [args[0]],
opt.callback, apf.extend(options || {}, opt));
}
};
return f;
})(),
// #endif
/**
* Starts the application.
* @private
*/
start : function(){
this.started = true;
var sHref = location.href.split("#")[0].split("?")[0];
//Set Variables
this.host = location.hostname && sHref.replace(/(\/\/[^\/]*)\/.*$/, "$1");
this.hostPath = sHref.replace(/\/[^\/]*$/, "") + "/";
//#ifdef __DEBUG
apf.console.info("Starting Ajax.org Platform Application...");
apf.console.warn("Debug build of Ajax.org Platform " + (apf.VERSION ? "version " + apf.VERSION : ""));
//#endif
//mozilla root detection
//try{ISROOT = !window.opener || !window.opener.apf}catch(e){ISROOT = true}
//Browser Specific Stuff
//this.browserDetect();
this.setCompatFlags();
if (apf.onstart && apf.onstart() === false)
return false;
//#ifdef __WITH_DEBUG_WIN
apf.$debugwin.start();
//#endif
//Load Browser Specific Code
// #ifdef __SUPPORT_IE
if (this.isIE) apf.runIE();
//this.importClass(apf.runIE, true, self);
// #endif
// #ifdef __SUPPORT_WEBKIT
if (apf.isWebkit) apf.runWebkit();
//this.importClass(apf.runSafari, true, self);
// #endif
// #ifdef __SUPPORT_OPERA
if (this.isOpera) apf.runOpera();
//this.importClass(apf.runOpera, true, self);
// #endif
// #ifdef __SUPPORT_GECKO
if (this.isGecko || !this.isIE && !apf.isWebkit && !this.isOpera)
apf.runGecko();
//this.importClass(apf.runGecko, true, self);
// #endif
//#ifdef __PARSE_GET_VARS
for (var i, l2, a, m, n, o, v, p = location.href.split(/[?&]/), l = p.length, k = 1; k < l; k++) {
if (m = p[k].match(/(.*?)(\..*?|\[.*?\])?=([^#]*)/)) {
n = decodeURI(m[1]).toLowerCase(), o = this._GET;
if (m[2]) {
for (a = decodeURI(m[2]).replace(/\[\s*\]/g, "[-1]").split(/[\.\[\]]/), i = 0, l2 = a.length; i < l2; i++) {
v = a[i],
o = o[n]
? o[n]
: o[n] = (parseInt(v) == v)
? []
: {},
n = v.replace(/^["\'](.*)["\']$/, "$1");
}
}
o[n != "-1" ? n : o.length] = unescape(decodeURI(m[3]));
}
}
//#endif
// #ifdef __TP_HTTP
// Start HTTP object
this.oHttp = new this.http();
//#endif
// #ifndef __SUPPORT_GWT
// Load user defined includes
this.Init.addConditional(this.parseAppMarkup, apf, ["body"]);
//@todo, as an experiment I removed 'HTTP' and 'Teleport'
// #endif
//IE fix
try {
if (apf.isIE)
document.execCommand("BackgroundImageCache", false, true);
}
catch(e) {}
//#ifdef __WITH_WINDOW
//apf.window.init();
//#endif
this.started = true;
// #ifndef __SUPPORT_GWT
// DOMReady already fired, so plz continue the loading and parsing
if (this.load_done)
this.execDeferred();
// #endif
//try{apf.root = !window.opener || !window.opener.apf;}
//catch(e){apf.root = false}
this.root = true;
/* #ifdef __PACKAGED
for (var i = 0; i < apf.$required.length; i++) {
apf.include(apf.$required[i]);
}
apf.require = apf.include;
#endif*/
/*#ifdef __SUPPORT_GWT
// Load user defined includes
//this.parseAppMarkup();
//GWT
apf.initialize("<html xmlns:a='" + apf.ns.aml + "' xmlns='" + apf.ns.xhtml + "'><head /><body /></html>");
#endif*/
},
nsqueue : {},
//#ifdef __PARSER_AML || __WITH_NS_SUPPORT
/**
* @private
*/
findPrefix : function(xmlNode, xmlns){
var docEl;
if (xmlNode.nodeType == 9) {
if (!xmlNode.documentElement)
return false;
if (xmlNode.documentElement.namespaceURI == xmlns)
return xmlNode.prefix || xmlNode.scopeName;
docEl = xmlNode.documentElement;
}
else {
if (xmlNode.namespaceURI == xmlns)
return xmlNode.prefix || xmlNode.scopeName;
docEl = xmlNode.ownerDocument.documentElement;
if (docEl && docEl.namespaceURI == xmlns)
return xmlNode.prefix || xmlNode.scopeName;
while (xmlNode.parentNode) {
xmlNode = xmlNode.parentNode;
if (xmlNode.namespaceURI == xmlns)
return xmlNode.prefix || xmlNode.scopeName;
}
}
if (docEl) {
for (var i = 0; i < docEl.attributes.length; i++) {
if (docEl.attributes[i].nodeValue == xmlns)
return docEl.attributes[i][apf.TAGNAME]
}
}
return false;
},
//#endif
/**
* @private
*/
importClass : function(ref, strip, win){
if (!ref)
throw new Error(apf.formatErrorString(1018, null,
"importing class",
"Could not load reference. Reference is null"));
if (!strip)
return apf.jsexec(ref.toString(), win);
var q = ref.toString().replace(/^\s*function\s*\w*\s*\([^\)]*\)\s*\{/, "")
.replace(/\}\s*$/, "");
return apf.jsexec(q, win);
},
/**
* This method returns a string representation of the object
* @return {String} Returns a string representing the object.
*/
toString : function(){
return "[Ajax.org Platform (apf)]";
},
all : [],
/**
* This method implements all properties and methods to this object from another class
* @param {Function} classRef Class reference
* @private
*/
implement : function(classRef) {
// for speed, we check for the most common case first
if (arguments.length == 1) {
//#ifdef __DEBUG
if (!classRef) {
throw new Error(apf.formatErrorString(0, this,
"Implementing class",
"Could not implement from '" + classRef[i] + "'", this));
}
//#endif
classRef.call(this);//classRef
}
else {
for (var a, i = 0, l = arguments.length; i < l; i++) {
a = arguments[i];
//#ifdef __DEBUG
if (!a) {
throw new Error(apf.formatErrorString(0, this,
"Implementing class",
"Could not implement from '" + arguments[i] + "'", this));
}
//#endif
arguments[i].call(this);//classRef
}
}
return this;
},
/**
* @private
*/
uniqueHtmlIds : 0,
/**
* Adds a unique id attribute to an html element.
* @param {HTMLElement} oHtml the object getting the attribute.
*/
setUniqueHtmlId : function(oHtml){
var id;
oHtml.setAttribute("id", id = "q" + this.uniqueHtmlIds++);
return id;
},
/**
* Retrieves a new unique id
*/
getUniqueId : function(){
return this.uniqueHtmlIds++;
},
/**
* Finds a aml element based on it's uniqueId
*/
lookup : function(uniqueId){
return this.all[uniqueId];
},
/**
* Searches in the html tree from a certain point to find the
* aml element that is responsible for rendering the specified html
* element.
* @param {HTMLElement} oHtml the html context to start the search from.
*/
findHost : function(o){
while (o && o.parentNode) { //!o.host &&
try {
if ((o.host || o.host === false) && typeof o.host != "string")
return o.host;
}
catch(e){}
o = o.parentNode;
}
return null;
},
/**
* Sets a reference to an object by name in the global javascript space.
* @param {String} name the name of the reference.
* @param {mixed} o the reference to the object subject to the reference.
*/
setReference : function(name, o){
return self[name] && self[name].hasFeature
? 0
: (self[name] = o);
},
/**
* The console outputs to the debug screen and offers differents ways to do
* this.
*/
console : {
//#ifdef __DEBUG
/**
* @private
*/
data : {
time : {
messages : {}
},
log : {
messages : {}
},
custom : {
messages : {}
},
warn : {
messages : {}
},
error : {
messages : {}
},
repeat : {
messages : {}
}
},
/**
* @private
*/
toggle : function(node, id){
var sPath = apf.$debugwin ? apf.$debugwin.resPath : apf.basePath + "core/debug/resources/";
if (node.style.display == "block") {
node.style.display = "none";