4 * Copyright(c) 2006-2007, Ext JS, LLC.
6 * Originally Released Under LGPL - original licence link has changed is not relivant.
9 * <script type="text/javascript">
17 window["undefined"] = window["undefined"];
21 * Roo core utilities and functions.
26 * Copies all the properties of config to obj.
27 * @param {Object} obj The receiver of the properties
28 * @param {Object} config The source of the properties
29 * @param {Object} defaults A different object that will also be applied for default values
30 * @return {Object} returns obj
35 Roo.apply = function(o, c, defaults){
37 // no "this" reference for friendly out of scope calls
38 Roo.apply(o, defaults);
40 if(o && c && typeof c == 'object'){
51 var ua = navigator.userAgent.toLowerCase();
53 var isStrict = document.compatMode == "CSS1Compat",
54 isOpera = ua.indexOf("opera") > -1,
55 isSafari = (/webkit|khtml/).test(ua),
56 isIE = ua.indexOf("msie") > -1,
57 isIE7 = ua.indexOf("msie 7") > -1,
58 isGecko = !isSafari && ua.indexOf("gecko") > -1,
59 isBorderBox = isIE && !isStrict,
60 isWindows = (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1),
61 isMac = (ua.indexOf("macintosh") != -1 || ua.indexOf("mac os x") != -1),
62 isLinux = (ua.indexOf("linux") != -1),
63 isSecure = window.location.href.toLowerCase().indexOf("https") === 0;
65 // remove css image flicker
68 document.execCommand("BackgroundImageCache", false, true);
74 * True if the browser is in strict mode
79 * True if the page is running over SSL
84 * True when the document is fully initialized and ready for action
90 * True to automatically uncache orphaned Roo.Elements periodically (defaults to true)
93 enableGarbageCollector : true,
96 * True to automatically purge event listeners after uncaching an element (defaults to false).
97 * Note: this only happens if enableGarbageCollector is true.
100 enableListenerCollection:false,
103 * URL to a blank file used by Roo when in secure mode for iframe src and onReady src to prevent
104 * the IE insecure content warning (defaults to javascript:false).
107 SSL_SECURE_URL : "javascript:false",
110 * URL to a 1x1 transparent gif image used by Roo to create inline icons with CSS background images. (Defaults to
111 * "http://Roojs.com/s.gif" and you should change this to a URL on your server).
114 BLANK_IMAGE_URL : "http:/"+"/localhost/s.gif",
116 emptyFn : function(){},
119 * Copies all the properties of config to obj if they don't already exist.
120 * @param {Object} obj The receiver of the properties
121 * @param {Object} config The source of the properties
122 * @return {Object} returns obj
124 applyIf : function(o, c){
127 if(typeof o[p] == "undefined"){ o[p] = c[p]; }
134 * Applies event listeners to elements by selectors when the document is ready.
135 * The event name is specified with an @ suffix.
138 // add a listener for click on all anchors in element with id foo
139 '#foo a@click' : function(e, t){
143 // add the same listener to multiple selectors (separated by comma BEFORE the @)
144 '#foo a, #bar span.some-class@mouseover' : function(){
149 * @param {Object} obj The list of behaviors to apply
151 addBehaviors : function(o){
153 Roo.onReady(function(){
158 var cache = {}; // simple cache for applying multiple behaviors to same selector does query multiple times
160 var parts = b.split('@');
161 if(parts[1]){ // for Object prototype breakers
164 cache[s] = Roo.select(s);
166 cache[s].on(parts[1], o[b]);
173 * Generates unique ids. If the element already has an id, it is unchanged
174 * @param {String/HTMLElement/Element} el (optional) The element to generate an id for
175 * @param {String} prefix (optional) Id prefix (defaults "Roo-gen")
176 * @return {String} The generated Id.
178 id : function(el, prefix){
179 prefix = prefix || "roo-gen";
181 var id = prefix + (++idSeed);
182 return el ? (el.id ? el.id : (el.id = id)) : id;
187 * Extends one class with another class and optionally overrides members with the passed literal. This class
188 * also adds the function "override()" to the class that can be used to override
189 * members on an instance.
190 * @param {Object} subclass The class inheriting the functionality
191 * @param {Object} superclass The class being extended
192 * @param {Object} overrides (optional) A literal with members
197 var io = function(o){
202 return function(sb, sp, overrides){
203 if(typeof sp == 'object'){ // eg. prototype, rather than function constructor..
206 sb = function(){sp.apply(this, arguments);};
208 var F = function(){}, sbp, spp = sp.prototype;
210 sbp = sb.prototype = new F();
214 if(spp.constructor == Object.prototype.constructor){
219 sb.override = function(o){
223 Roo.override(sb, overrides);
229 * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.
231 Roo.override(MyClass, {
232 newMethod1: function(){
235 newMethod2: function(foo){
240 * @param {Object} origclass The class to override
241 * @param {Object} overrides The list of functions to add to origClass. This should be specified as an object literal
242 * containing one or more methods.
245 override : function(origclass, overrides){
247 var p = origclass.prototype;
248 for(var method in overrides){
249 p[method] = overrides[method];
254 * Creates namespaces to be used for scoping variables and classes so that they are not global. Usage:
256 Roo.namespace('Company', 'Company.data');
257 Company.Widget = function() { ... }
258 Company.data.CustomStore = function(config) { ... }
260 * @param {String} namespace1
261 * @param {String} namespace2
262 * @param {String} etc
265 namespace : function(){
266 var a=arguments, o=null, i, j, d, rt;
267 for (i=0; i<a.length; ++i) {
271 eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';');
272 for (j=1; j<d.length; ++j) {
273 o[d[j]]=o[d[j]] || {};
279 * Creates namespaces to be used for scoping variables and classes so that they are not global. Usage:
281 Roo.factory({ xns: Roo.data, xtype : 'Store', .....});
282 Roo.factory(conf, Roo.data);
284 * @param {String} classname
285 * @param {String} namespace (optional)
289 factory : function(c, ns)
291 // no xtype, no ns or c.xns - or forced off by c.xns
292 if (!c.xtype || (!ns && !c.xns) || (c.xns === false)) { // not enough info...
295 ns = c.xns ? c.xns : ns; // if c.xns is set, then use that..
296 if (c.constructor == ns[c.xtype]) {// already created...
300 if (Roo.debug) console.log("Roo.Factory(" + c.xtype + ")");
301 var ret = new ns[c.xtype](c);
305 c.xns = false; // prevent recursion..
310 * Takes an object and converts it to an encoded URL. e.g. Roo.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2". Optionally, property values can be arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value.
314 urlEncode : function(o){
320 var ov = o[key], k = encodeURIComponent(key);
321 var type = typeof ov;
322 if(type == 'undefined'){
324 }else if(type != "function" && type != "object"){
325 buf.push(k, "=", encodeURIComponent(ov), "&");
326 }else if(ov instanceof Array){
328 for(var i = 0, len = ov.length; i < len; i++) {
329 buf.push(k, "=", encodeURIComponent(ov[i] === undefined ? '' : ov[i]), "&");
341 * Takes an encoded URL and and converts it to an object. e.g. Roo.urlDecode("foo=1&bar=2"); would return {foo: 1, bar: 2} or Roo.urlDecode("foo=1&bar=2&bar=3&bar=4", true); would return {foo: 1, bar: [2, 3, 4]}.
342 * @param {String} string
343 * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
344 * @return {Object} A literal with members
346 urlDecode : function(string, overwrite){
347 if(!string || !string.length){
351 var pairs = string.split('&');
352 var pair, name, value;
353 for(var i = 0, len = pairs.length; i < len; i++){
354 pair = pairs[i].split('=');
355 name = decodeURIComponent(pair[0]);
356 value = decodeURIComponent(pair[1]);
357 if(overwrite !== true){
358 if(typeof obj[name] == "undefined"){
360 }else if(typeof obj[name] == "string"){
361 obj[name] = [obj[name]];
362 obj[name].push(value);
364 obj[name].push(value);
374 * Iterates an array calling the passed function with each item, stopping if your function returns false. If the
375 * passed array is not really an array, your function is called once with it.
376 * The supplied function is called with (Object item, Number index, Array allItems).
377 * @param {Array/NodeList/Mixed} array
378 * @param {Function} fn
379 * @param {Object} scope
381 each : function(array, fn, scope){
382 if(typeof array.length == "undefined" || typeof array == "string"){
385 for(var i = 0, len = array.length; i < len; i++){
386 if(fn.call(scope || array[i], array[i], i, array) === false){ return i; };
391 combine : function(){
392 var as = arguments, l = as.length, r = [];
393 for(var i = 0; i < l; i++){
395 if(a instanceof Array){
397 }else if(a.length !== undefined && !a.substr){
398 r = r.concat(Array.prototype.slice.call(a, 0));
407 * Escapes the passed string for use in a regular expression
408 * @param {String} str
411 escapeRe : function(s) {
412 return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1");
416 callback : function(cb, scope, args, delay){
417 if(typeof cb == "function"){
419 cb.defer(delay, scope, args || []);
421 cb.apply(scope, args || []);
427 * Return the dom node for the passed string (id), dom node, or Roo.Element
428 * @param {String/HTMLElement/Roo.Element} el
429 * @return HTMLElement
431 getDom : function(el){
435 return el.dom ? el.dom : (typeof el == 'string' ? document.getElementById(el) : el);
439 * Shorthand for {@link Roo.ComponentMgr#get}
441 * @return Roo.Component
443 getCmp : function(id){
444 return Roo.ComponentMgr.get(id);
447 num : function(v, defaultValue){
448 if(typeof v != 'number'){
454 destroy : function(){
455 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
459 as.removeAllListeners();
463 if(typeof as.purgeListeners == 'function'){
466 if(typeof as.destroy == 'function'){
473 // inpired by a similar function in mootools library
475 * Returns the type of object that is passed in. If the object passed in is null or undefined it
476 * return false otherwise it returns one of the following values:<ul>
477 * <li><b>string</b>: If the object passed is a string</li>
478 * <li><b>number</b>: If the object passed is a number</li>
479 * <li><b>boolean</b>: If the object passed is a boolean value</li>
480 * <li><b>function</b>: If the object passed is a function reference</li>
481 * <li><b>object</b>: If the object passed is an object</li>
482 * <li><b>array</b>: If the object passed is an array</li>
483 * <li><b>regexp</b>: If the object passed is a regular expression</li>
484 * <li><b>element</b>: If the object passed is a DOM Element</li>
485 * <li><b>nodelist</b>: If the object passed is a DOM NodeList</li>
486 * <li><b>textnode</b>: If the object passed is a DOM text node and contains something other than whitespace</li>
487 * <li><b>whitespace</b>: If the object passed is a DOM text node and contains only whitespace</li>
488 * @param {Mixed} object
492 if(o === undefined || o === null){
499 if(t == 'object' && o.nodeName) {
501 case 1: return 'element';
502 case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
505 if(t == 'object' || t == 'function') {
506 switch(o.constructor) {
507 case Array: return 'array';
508 case RegExp: return 'regexp';
510 if(typeof o.length == 'number' && typeof o.item == 'function') {
518 * Returns true if the passed value is null, undefined or an empty string (optional).
519 * @param {Mixed} value The value to test
520 * @param {Boolean} allowBlank (optional) Pass true if an empty string is not considered empty
523 isEmpty : function(v, allowBlank){
524 return v === null || v === undefined || (!allowBlank ? v === '' : false);
538 isBorderBox : isBorderBox,
540 isWindows : isWindows,
547 * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
548 * you may want to set this to true.
551 useShims : ((isIE && !isIE7) || (isGecko && isMac))
557 Roo.namespace("Roo", "Roo.util", "Roo.grid", "Roo.dd", "Roo.tree", "Roo.data",
558 "Roo.form", "Roo.menu", "Roo.state", "Roo.lib", "Roo.layout", "Roo.app", "Roo.ux");
561 * Ext JS Library 1.1.1
562 * Copyright(c) 2006-2007, Ext JS, LLC.
564 * Originally Released Under LGPL - original licence link has changed is not relivant.
567 * <script type="text/javascript">
571 // wrappedn so fnCleanup is not in global scope...
573 function fnCleanUp() {
574 var p = Function.prototype;
575 delete p.createSequence;
577 delete p.createDelegate;
578 delete p.createCallback;
579 delete p.createInterceptor;
581 window.detachEvent("onunload", fnCleanUp);
583 window.attachEvent("onunload", fnCleanUp);
590 * These functions are available on every Function object (any JavaScript function).
592 Roo.apply(Function.prototype, {
594 * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
595 * Call directly on any function. Example: <code>myFunction.createCallback(myarg, myarg2)</code>
596 * Will create a function that is bound to those 2 args.
597 * @return {Function} The new function
599 createCallback : function(/*args...*/){
600 // make args available, in function below
601 var args = arguments;
604 return method.apply(window, args);
609 * Creates a delegate (callback) that sets the scope to obj.
610 * Call directly on any function. Example: <code>this.myFunction.createDelegate(this)</code>
611 * Will create a function that is automatically scoped to this.
612 * @param {Object} obj (optional) The object for which the scope is set
613 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
614 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
615 * if a number the args are inserted at the specified position
616 * @return {Function} The new function
618 createDelegate : function(obj, args, appendArgs){
621 var callArgs = args || arguments;
622 if(appendArgs === true){
623 callArgs = Array.prototype.slice.call(arguments, 0);
624 callArgs = callArgs.concat(args);
625 }else if(typeof appendArgs == "number"){
626 callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
627 var applyArgs = [appendArgs, 0].concat(args); // create method call params
628 Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
630 return method.apply(obj || window, callArgs);
635 * Calls this function after the number of millseconds specified.
636 * @param {Number} millis The number of milliseconds for the setTimeout call (if 0 the function is executed immediately)
637 * @param {Object} obj (optional) The object for which the scope is set
638 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
639 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
640 * if a number the args are inserted at the specified position
641 * @return {Number} The timeout id that can be used with clearTimeout
643 defer : function(millis, obj, args, appendArgs){
644 var fn = this.createDelegate(obj, args, appendArgs);
646 return setTimeout(fn, millis);
652 * Create a combined function call sequence of the original function + the passed function.
653 * The resulting function returns the results of the original function.
654 * The passed fcn is called with the parameters of the original function
655 * @param {Function} fcn The function to sequence
656 * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
657 * @return {Function} The new function
659 createSequence : function(fcn, scope){
660 if(typeof fcn != "function"){
665 var retval = method.apply(this || window, arguments);
666 fcn.apply(scope || this || window, arguments);
672 * Creates an interceptor function. The passed fcn is called before the original one. If it returns false, the original one is not called.
673 * The resulting function returns the results of the original function.
674 * The passed fcn is called with the parameters of the original function.
676 * @param {Function} fcn The function to call before the original
677 * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
678 * @return {Function} The new function
680 createInterceptor : function(fcn, scope){
681 if(typeof fcn != "function"){
688 if(fcn.apply(scope || this || window, arguments) === false){
691 return method.apply(this || window, arguments);
697 * Ext JS Library 1.1.1
698 * Copyright(c) 2006-2007, Ext JS, LLC.
700 * Originally Released Under LGPL - original licence link has changed is not relivant.
703 * <script type="text/javascript">
706 Roo.applyIf(String, {
711 * Escapes the passed string for ' and \
712 * @param {String} string The string to escape
713 * @return {String} The escaped string
716 escape : function(string) {
717 return string.replace(/('|\\)/g, "\\$1");
721 * Pads the left side of a string with a specified character. This is especially useful
722 * for normalizing number and date strings. Example usage:
724 var s = String.leftPad('123', 5, '0');
725 // s now contains the string: '00123'
727 * @param {String} string The original string
728 * @param {Number} size The total length of the output string
729 * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
730 * @return {String} The padded string
733 leftPad : function (val, size, ch) {
734 var result = new String(val);
735 if(ch === null || ch === undefined || ch === '') {
738 while (result.length < size) {
739 result = ch + result;
745 * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each
746 * token must be unique, and must increment in the format {0}, {1}, etc. Example usage:
748 var cls = 'my-class', text = 'Some text';
749 var s = String.format('<div class="{0}">{1}</div>', cls, text);
750 // s now contains the string: '<div class="my-class">Some text</div>'
752 * @param {String} string The tokenized string to be formatted
753 * @param {String} value1 The value to replace token {0}
754 * @param {String} value2 Etc...
755 * @return {String} The formatted string
758 format : function(format){
759 var args = Array.prototype.slice.call(arguments, 1);
760 return format.replace(/\{(\d+)\}/g, function(m, i){
761 return Roo.util.Format.htmlEncode(args[i]);
767 * Utility function that allows you to easily switch a string between two alternating values. The passed value
768 * is compared to the current string, and if they are equal, the other value that was passed in is returned. If
769 * they are already different, the first value passed in is returned. Note that this method returns the new value
770 * but does not change the current string.
772 // alternate sort directions
773 sort = sort.toggle('ASC', 'DESC');
775 // instead of conditional logic:
776 sort = (sort == 'ASC' ? 'DESC' : 'ASC');
778 * @param {String} value The value to compare to the current string
779 * @param {String} other The new value to use if the string already equals the first value passed in
780 * @return {String} The new value
783 String.prototype.toggle = function(value, other){
784 return this == value ? other : value;
787 * Ext JS Library 1.1.1
788 * Copyright(c) 2006-2007, Ext JS, LLC.
790 * Originally Released Under LGPL - original licence link has changed is not relivant.
793 * <script type="text/javascript">
799 Roo.applyIf(Number.prototype, {
801 * Checks whether or not the current number is within a desired range. If the number is already within the
802 * range it is returned, otherwise the min or max value is returned depending on which side of the range is
803 * exceeded. Note that this method returns the constrained value but does not change the current number.
804 * @param {Number} min The minimum number in the range
805 * @param {Number} max The maximum number in the range
806 * @return {Number} The constrained value if outside the range, otherwise the current value
808 constrain : function(min, max){
809 return Math.min(Math.max(this, min), max);
813 * Ext JS Library 1.1.1
814 * Copyright(c) 2006-2007, Ext JS, LLC.
816 * Originally Released Under LGPL - original licence link has changed is not relivant.
819 * <script type="text/javascript">
824 Roo.applyIf(Array.prototype, {
826 * Checks whether or not the specified object exists in the array.
827 * @param {Object} o The object to check for
828 * @return {Number} The index of o in the array (or -1 if it is not found)
830 indexOf : function(o){
831 for (var i = 0, len = this.length; i < len; i++){
832 if(this[i] == o) return i;
838 * Removes the specified object from the array. If the object is not found nothing happens.
839 * @param {Object} o The object to remove
841 remove : function(o){
842 var index = this.indexOf(o);
844 this.splice(index, 1);
848 * Map (JS 1.6 compatibility)
849 * @param {Function} function to call
853 var len = this.length >>> 0;
854 if (typeof fun != "function")
855 throw new TypeError();
857 var res = new Array(len);
858 var thisp = arguments[1];
859 for (var i = 0; i < len; i++)
862 res[i] = fun.call(thisp, this[i], i, this);
873 * Ext JS Library 1.1.1
874 * Copyright(c) 2006-2007, Ext JS, LLC.
876 * Originally Released Under LGPL - original licence link has changed is not relivant.
879 * <script type="text/javascript">
885 * The date parsing and format syntax is a subset of
886 * <a href="http://www.php.net/date">PHP's date() function</a>, and the formats that are
887 * supported will provide results equivalent to their PHP versions.
889 * Following is the list of all currently supported formats:
892 'Wed Jan 10 2007 15:05:01 GMT-0600 (Central Standard Time)'
894 Format Output Description
895 ------ ---------- --------------------------------------------------------------
896 d 10 Day of the month, 2 digits with leading zeros
897 D Wed A textual representation of a day, three letters
898 j 10 Day of the month without leading zeros
899 l Wednesday A full textual representation of the day of the week
900 S th English ordinal day of month suffix, 2 chars (use with j)
901 w 3 Numeric representation of the day of the week
902 z 9 The julian date, or day of the year (0-365)
903 W 01 ISO-8601 2-digit week number of year, weeks starting on Monday (00-52)
904 F January A full textual representation of the month
905 m 01 Numeric representation of a month, with leading zeros
906 M Jan Month name abbreviation, three letters
907 n 1 Numeric representation of a month, without leading zeros
908 t 31 Number of days in the given month
909 L 0 Whether it's a leap year (1 if it is a leap year, else 0)
910 Y 2007 A full numeric representation of a year, 4 digits
911 y 07 A two digit representation of a year
912 a pm Lowercase Ante meridiem and Post meridiem
913 A PM Uppercase Ante meridiem and Post meridiem
914 g 3 12-hour format of an hour without leading zeros
915 G 15 24-hour format of an hour without leading zeros
916 h 03 12-hour format of an hour with leading zeros
917 H 15 24-hour format of an hour with leading zeros
918 i 05 Minutes with leading zeros
919 s 01 Seconds, with leading zeros
920 O -0600 Difference to Greenwich time (GMT) in hours
921 T CST Timezone setting of the machine running the code
922 Z -21600 Timezone offset in seconds (negative if west of UTC, positive if east)
925 * Example usage (note that you must escape format specifiers with '\\' to render them as character literals):
927 var dt = new Date('1/10/2007 03:05:01 PM GMT-0600');
928 document.write(dt.format('Y-m-d')); //2007-01-10
929 document.write(dt.format('F j, Y, g:i a')); //January 10, 2007, 3:05 pm
930 document.write(dt.format('l, \\t\\he dS of F Y h:i:s A')); //Wednesday, the 10th of January 2007 03:05:01 PM
933 * Here are some standard date/time patterns that you might find helpful. They
934 * are not part of the source of Date.js, but to use them you can simply copy this
935 * block of code into any script that is included after Date.js and they will also become
936 * globally available on the Date object. Feel free to add or remove patterns as needed in your code.
939 ISO8601Long:"Y-m-d H:i:s",
940 ISO8601Short:"Y-m-d",
942 LongDate: "l, F d, Y",
943 FullDateTime: "l, F d, Y g:i:s A",
947 SortableDateTime: "Y-m-d\\TH:i:s",
948 UniversalSortableDateTime: "Y-m-d H:i:sO",
956 document.write(dt.format(Date.patterns.ShortDate));
961 * Most of the date-formatting functions below are the excellent work of Baron Schwartz.
962 * They generate precompiled functions from date formats instead of parsing and
963 * processing the pattern every time you format a date. These functions are available
964 * on every Date object (any javascript function).
966 * The original article and download are here:
967 * http://www.xaprb.com/blog/2005/12/12/javascript-closures-for-runtime-efficiency/
974 Returns the number of milliseconds between this date and date
975 @param {Date} date (optional) Defaults to now
976 @return {Number} The diff in milliseconds
977 @member Date getElapsed
979 Date.prototype.getElapsed = function(date) {
980 return Math.abs((date || new Date()).getTime()-this.getTime());
982 // was in date file..
986 Date.parseFunctions = {count:0};
988 Date.parseRegexes = [];
990 Date.formatFunctions = {count:0};
993 Date.prototype.dateFormat = function(format) {
994 if (Date.formatFunctions[format] == null) {
995 Date.createNewFormat(format);
997 var func = Date.formatFunctions[format];
1003 * Formats a date given the supplied format string
1004 * @param {String} format The format string
1005 * @return {String} The formatted date
1008 Date.prototype.format = Date.prototype.dateFormat;
1011 Date.createNewFormat = function(format) {
1012 var funcName = "format" + Date.formatFunctions.count++;
1013 Date.formatFunctions[format] = funcName;
1014 var code = "Date.prototype." + funcName + " = function(){return ";
1015 var special = false;
1017 for (var i = 0; i < format.length; ++i) {
1018 ch = format.charAt(i);
1019 if (!special && ch == "\\") {
1024 code += "'" + String.escape(ch) + "' + ";
1027 code += Date.getFormatCode(ch);
1030 /** eval:var:zzzzzzzzzzzzz */
1031 eval(code.substring(0, code.length - 3) + ";}");
1035 Date.getFormatCode = function(character) {
1036 switch (character) {
1038 return "String.leftPad(this.getDate(), 2, '0') + ";
1040 return "Date.dayNames[this.getDay()].substring(0, 3) + ";
1042 return "this.getDate() + ";
1044 return "Date.dayNames[this.getDay()] + ";
1046 return "this.getSuffix() + ";
1048 return "this.getDay() + ";
1050 return "this.getDayOfYear() + ";
1052 return "this.getWeekOfYear() + ";
1054 return "Date.monthNames[this.getMonth()] + ";
1056 return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
1058 return "Date.monthNames[this.getMonth()].substring(0, 3) + ";
1060 return "(this.getMonth() + 1) + ";
1062 return "this.getDaysInMonth() + ";
1064 return "(this.isLeapYear() ? 1 : 0) + ";
1066 return "this.getFullYear() + ";
1068 return "('' + this.getFullYear()).substring(2, 4) + ";
1070 return "(this.getHours() < 12 ? 'am' : 'pm') + ";
1072 return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
1074 return "((this.getHours() % 12) ? this.getHours() % 12 : 12) + ";
1076 return "this.getHours() + ";
1078 return "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0') + ";
1080 return "String.leftPad(this.getHours(), 2, '0') + ";
1082 return "String.leftPad(this.getMinutes(), 2, '0') + ";
1084 return "String.leftPad(this.getSeconds(), 2, '0') + ";
1086 return "this.getGMTOffset() + ";
1088 return "this.getTimezone() + ";
1090 return "(this.getTimezoneOffset() * -60) + ";
1092 return "'" + String.escape(character) + "' + ";
1097 * Parses the passed string using the specified format. Note that this function expects dates in normal calendar
1098 * format, meaning that months are 1-based (1 = January) and not zero-based like in JavaScript dates. Any part of
1099 * the date format that is not specified will default to the current date value for that part. Time parts can also
1100 * be specified, but default to 0. Keep in mind that the input date string must precisely match the specified format
1101 * string or the parse operation will fail.
1104 //dt = Fri May 25 2007 (current date)
1105 var dt = new Date();
1107 //dt = Thu May 25 2006 (today's month/day in 2006)
1108 dt = Date.parseDate("2006", "Y");
1110 //dt = Sun Jan 15 2006 (all date parts specified)
1111 dt = Date.parseDate("2006-1-15", "Y-m-d");
1113 //dt = Sun Jan 15 2006 15:20:01 GMT-0600 (CST)
1114 dt = Date.parseDate("2006-1-15 3:20:01 PM", "Y-m-d h:i:s A" );
1116 * @param {String} input The unparsed date as a string
1117 * @param {String} format The format the date is in
1118 * @return {Date} The parsed date
1121 Date.parseDate = function(input, format) {
1122 if (Date.parseFunctions[format] == null) {
1123 Date.createParser(format);
1125 var func = Date.parseFunctions[format];
1126 return Date[func](input);
1131 Date.createParser = function(format) {
1132 var funcName = "parse" + Date.parseFunctions.count++;
1133 var regexNum = Date.parseRegexes.length;
1134 var currentGroup = 1;
1135 Date.parseFunctions[format] = funcName;
1137 var code = "Date." + funcName + " = function(input){\n"
1138 + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, o, z, v;\n"
1139 + "var d = new Date();\n"
1140 + "y = d.getFullYear();\n"
1141 + "m = d.getMonth();\n"
1142 + "d = d.getDate();\n"
1143 + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
1144 + "if (results && results.length > 0) {";
1147 var special = false;
1149 for (var i = 0; i < format.length; ++i) {
1150 ch = format.charAt(i);
1151 if (!special && ch == "\\") {
1156 regex += String.escape(ch);
1159 var obj = Date.formatCodeToRegex(ch, currentGroup);
1160 currentGroup += obj.g;
1162 if (obj.g && obj.c) {
1168 code += "if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
1169 + "{v = new Date(y, m, d, h, i, s);}\n"
1170 + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
1171 + "{v = new Date(y, m, d, h, i);}\n"
1172 + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0)\n"
1173 + "{v = new Date(y, m, d, h);}\n"
1174 + "else if (y >= 0 && m >= 0 && d > 0)\n"
1175 + "{v = new Date(y, m, d);}\n"
1176 + "else if (y >= 0 && m >= 0)\n"
1177 + "{v = new Date(y, m);}\n"
1178 + "else if (y >= 0)\n"
1179 + "{v = new Date(y);}\n"
1180 + "}return (v && (z || o))?\n" // favour UTC offset over GMT offset
1181 + " ((z)? v.add(Date.SECOND, (v.getTimezoneOffset() * 60) + (z*1)) :\n" // reset to UTC, then add offset
1182 + " v.add(Date.HOUR, (v.getGMTOffset() / 100) + (o / -100))) : v\n" // reset to GMT, then add offset
1185 Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$");
1186 /** eval:var:zzzzzzzzzzzzz */
1191 Date.formatCodeToRegex = function(character, currentGroup) {
1192 switch (character) {
1196 s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};
1199 c:"d = parseInt(results[" + currentGroup + "], 10);\n",
1200 s:"(\\d{1,2})"}; // day of month without leading zeroes
1203 c:"d = parseInt(results[" + currentGroup + "], 10);\n",
1204 s:"(\\d{2})"}; // day of month with leading zeroes
1208 s:"(?:" + Date.dayNames.join("|") + ")"};
1212 s:"(?:st|nd|rd|th)"};
1227 c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n",
1228 s:"(" + Date.monthNames.join("|") + ")"};
1231 c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n",
1232 s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};
1235 c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
1236 s:"(\\d{1,2})"}; // Numeric representation of a month, without leading zeros
1239 c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
1240 s:"(\\d{2})"}; // Numeric representation of a month, with leading zeros
1251 c:"y = parseInt(results[" + currentGroup + "], 10);\n",
1255 c:"var ty = parseInt(results[" + currentGroup + "], 10);\n"
1256 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
1260 c:"if (results[" + currentGroup + "] == 'am') {\n"
1261 + "if (h == 12) { h = 0; }\n"
1262 + "} else { if (h < 12) { h += 12; }}",
1266 c:"if (results[" + currentGroup + "] == 'AM') {\n"
1267 + "if (h == 12) { h = 0; }\n"
1268 + "} else { if (h < 12) { h += 12; }}",
1273 c:"h = parseInt(results[" + currentGroup + "], 10);\n",
1274 s:"(\\d{1,2})"}; // 12/24-hr format format of an hour without leading zeroes
1278 c:"h = parseInt(results[" + currentGroup + "], 10);\n",
1279 s:"(\\d{2})"}; // 12/24-hr format format of an hour with leading zeroes
1282 c:"i = parseInt(results[" + currentGroup + "], 10);\n",
1286 c:"s = parseInt(results[" + currentGroup + "], 10);\n",
1291 "o = results[", currentGroup, "];\n",
1292 "var sn = o.substring(0,1);\n", // get + / - sign
1293 "var hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60);\n", // get hours (performs minutes-to-hour conversion also)
1294 "var mn = o.substring(3,5) % 60;\n", // get minutes
1295 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))?\n", // -12hrs <= GMT offset <= 14hrs
1296 " (sn + String.leftPad(hr, 2, 0) + String.leftPad(mn, 2, 0)) : null;\n"
1302 s:"[A-Z]{1,4}"}; // timezone abbrev. may be between 1 - 4 chars
1305 c:"z = results[" + currentGroup + "];\n" // -43200 <= UTC offset <= 50400
1306 + "z = (-43200 <= z*1 && z*1 <= 50400)? z : null;\n",
1307 s:"([+\-]?\\d{1,5})"}; // leading '+' sign is optional for UTC offset
1311 s:String.escape(character)};
1316 * Get the timezone abbreviation of the current date (equivalent to the format specifier 'T').
1317 * @return {String} The abbreviated timezone name (e.g. 'CST')
1319 Date.prototype.getTimezone = function() {
1320 return this.toString().replace(/^.*? ([A-Z]{1,4})[\-+][0-9]{4} .*$/, "$1");
1324 * Get the offset from GMT of the current date (equivalent to the format specifier 'O').
1325 * @return {String} The 4-character offset string prefixed with + or - (e.g. '-0600')
1327 Date.prototype.getGMTOffset = function() {
1328 return (this.getTimezoneOffset() > 0 ? "-" : "+")
1329 + String.leftPad(Math.abs(Math.floor(this.getTimezoneOffset() / 60)), 2, "0")
1330 + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
1334 * Get the numeric day number of the year, adjusted for leap year.
1335 * @return {Number} 0 through 364 (365 in leap years)
1337 Date.prototype.getDayOfYear = function() {
1339 Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
1340 for (var i = 0; i < this.getMonth(); ++i) {
1341 num += Date.daysInMonth[i];
1343 return num + this.getDate() - 1;
1347 * Get the string representation of the numeric week number of the year
1348 * (equivalent to the format specifier 'W').
1349 * @return {String} '00' through '52'
1351 Date.prototype.getWeekOfYear = function() {
1352 // Skip to Thursday of this week
1353 var now = this.getDayOfYear() + (4 - this.getDay());
1354 // Find the first Thursday of the year
1355 var jan1 = new Date(this.getFullYear(), 0, 1);
1356 var then = (7 - jan1.getDay() + 4);
1357 return String.leftPad(((now - then) / 7) + 1, 2, "0");
1361 * Whether or not the current date is in a leap year.
1362 * @return {Boolean} True if the current date is in a leap year, else false
1364 Date.prototype.isLeapYear = function() {
1365 var year = this.getFullYear();
1366 return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
1370 * Get the first day of the current month, adjusted for leap year. The returned value
1371 * is the numeric day index within the week (0-6) which can be used in conjunction with
1372 * the {@link #monthNames} array to retrieve the textual day name.
1375 var dt = new Date('1/10/2007');
1376 document.write(Date.dayNames[dt.getFirstDayOfMonth()]); //output: 'Monday'
1378 * @return {Number} The day number (0-6)
1380 Date.prototype.getFirstDayOfMonth = function() {
1381 var day = (this.getDay() - (this.getDate() - 1)) % 7;
1382 return (day < 0) ? (day + 7) : day;
1386 * Get the last day of the current month, adjusted for leap year. The returned value
1387 * is the numeric day index within the week (0-6) which can be used in conjunction with
1388 * the {@link #monthNames} array to retrieve the textual day name.
1391 var dt = new Date('1/10/2007');
1392 document.write(Date.dayNames[dt.getLastDayOfMonth()]); //output: 'Wednesday'
1394 * @return {Number} The day number (0-6)
1396 Date.prototype.getLastDayOfMonth = function() {
1397 var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
1398 return (day < 0) ? (day + 7) : day;
1403 * Get the first date of this date's month
1406 Date.prototype.getFirstDateOfMonth = function() {
1407 return new Date(this.getFullYear(), this.getMonth(), 1);
1411 * Get the last date of this date's month
1414 Date.prototype.getLastDateOfMonth = function() {
1415 return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
1418 * Get the number of days in the current month, adjusted for leap year.
1419 * @return {Number} The number of days in the month
1421 Date.prototype.getDaysInMonth = function() {
1422 Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
1423 return Date.daysInMonth[this.getMonth()];
1427 * Get the English ordinal suffix of the current day (equivalent to the format specifier 'S').
1428 * @return {String} 'st, 'nd', 'rd' or 'th'
1430 Date.prototype.getSuffix = function() {
1431 switch (this.getDate()) {
1448 Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
1451 * An array of textual month names.
1452 * Override these values for international dates, for example...
1453 * Date.monthNames = ['JanInYourLang', 'FebInYourLang', ...];
1472 * An array of textual day names.
1473 * Override these values for international dates, for example...
1474 * Date.dayNames = ['SundayInYourLang', 'MondayInYourLang', ...];
1490 Date.monthNumbers = {
1505 * Creates and returns a new Date instance with the exact same date value as the called instance.
1506 * Dates are copied and passed by reference, so if a copied date variable is modified later, the original
1507 * variable will also be changed. When the intention is to create a new variable that will not
1508 * modify the original instance, you should create a clone.
1510 * Example of correctly cloning a date:
1513 var orig = new Date('10/1/2006');
1516 document.write(orig); //returns 'Thu Oct 05 2006'!
1519 var orig = new Date('10/1/2006');
1520 var copy = orig.clone();
1522 document.write(orig); //returns 'Thu Oct 01 2006'
1524 * @return {Date} The new Date instance
1526 Date.prototype.clone = function() {
1527 return new Date(this.getTime());
1531 * Clears any time information from this date
1532 @param {Boolean} clone true to create a clone of this date, clear the time and return it
1533 @return {Date} this or the clone
1535 Date.prototype.clearTime = function(clone){
1537 return this.clone().clearTime();
1542 this.setMilliseconds(0);
1547 // safari setMonth is broken
1549 Date.brokenSetMonth = Date.prototype.setMonth;
1550 Date.prototype.setMonth = function(num){
1552 var n = Math.ceil(-num);
1553 var back_year = Math.ceil(n/12);
1554 var month = (n % 12) ? 12 - n % 12 : 0 ;
1555 this.setFullYear(this.getFullYear() - back_year);
1556 return Date.brokenSetMonth.call(this, month);
1558 return Date.brokenSetMonth.apply(this, arguments);
1563 /** Date interval constant
1567 /** Date interval constant
1571 /** Date interval constant
1575 /** Date interval constant
1579 /** Date interval constant
1583 /** Date interval constant
1587 /** Date interval constant
1593 * Provides a convenient method of performing basic date arithmetic. This method
1594 * does not modify the Date instance being called - it creates and returns
1595 * a new Date instance containing the resulting date value.
1600 var dt = new Date('10/29/2006').add(Date.DAY, 5);
1601 document.write(dt); //returns 'Fri Oct 06 2006 00:00:00'
1603 //Negative values will subtract correctly:
1604 var dt2 = new Date('10/1/2006').add(Date.DAY, -5);
1605 document.write(dt2); //returns 'Tue Sep 26 2006 00:00:00'
1607 //You can even chain several calls together in one line!
1608 var dt3 = new Date('10/1/2006').add(Date.DAY, 5).add(Date.HOUR, 8).add(Date.MINUTE, -30);
1609 document.write(dt3); //returns 'Fri Oct 06 2006 07:30:00'
1612 * @param {String} interval A valid date interval enum value
1613 * @param {Number} value The amount to add to the current date
1614 * @return {Date} The new Date instance
1616 Date.prototype.add = function(interval, value){
1617 var d = this.clone();
1618 if (!interval || value === 0) return d;
1619 switch(interval.toLowerCase()){
1621 d.setMilliseconds(this.getMilliseconds() + value);
1624 d.setSeconds(this.getSeconds() + value);
1627 d.setMinutes(this.getMinutes() + value);
1630 d.setHours(this.getHours() + value);
1633 d.setDate(this.getDate() + value);
1636 var day = this.getDate();
1638 day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
1641 d.setMonth(this.getMonth() + value);
1644 d.setFullYear(this.getFullYear() + value);
1650 * Ext JS Library 1.1.1
1651 * Copyright(c) 2006-2007, Ext JS, LLC.
1653 * Originally Released Under LGPL - original licence link has changed is not relivant.
1656 * <script type="text/javascript">
1660 getViewWidth : function(full) {
1661 return full ? this.getDocumentWidth() : this.getViewportWidth();
1664 getViewHeight : function(full) {
1665 return full ? this.getDocumentHeight() : this.getViewportHeight();
1668 getDocumentHeight: function() {
1669 var scrollHeight = (document.compatMode != "CSS1Compat") ? document.body.scrollHeight : document.documentElement.scrollHeight;
1670 return Math.max(scrollHeight, this.getViewportHeight());
1673 getDocumentWidth: function() {
1674 var scrollWidth = (document.compatMode != "CSS1Compat") ? document.body.scrollWidth : document.documentElement.scrollWidth;
1675 return Math.max(scrollWidth, this.getViewportWidth());
1678 getViewportHeight: function() {
1679 var height = self.innerHeight;
1680 var mode = document.compatMode;
1682 if ((mode || Roo.isIE) && !Roo.isOpera) {
1683 height = (mode == "CSS1Compat") ?
1684 document.documentElement.clientHeight :
1685 document.body.clientHeight;
1691 getViewportWidth: function() {
1692 var width = self.innerWidth;
1693 var mode = document.compatMode;
1695 if (mode || Roo.isIE) {
1696 width = (mode == "CSS1Compat") ?
1697 document.documentElement.clientWidth :
1698 document.body.clientWidth;
1703 isAncestor : function(p, c) {
1710 if (p.contains && !Roo.isSafari) {
1711 return p.contains(c);
1712 } else if (p.compareDocumentPosition) {
1713 return !!(p.compareDocumentPosition(c) & 16);
1715 var parent = c.parentNode;
1720 else if (!parent.tagName || parent.tagName.toUpperCase() == "HTML") {
1723 parent = parent.parentNode;
1729 getRegion : function(el) {
1730 return Roo.lib.Region.getRegion(el);
1733 getY : function(el) {
1734 return this.getXY(el)[1];
1737 getX : function(el) {
1738 return this.getXY(el)[0];
1741 getXY : function(el) {
1742 var p, pe, b, scroll, bd = document.body;
1743 el = Roo.getDom(el);
1744 var fly = Roo.lib.AnimBase.fly;
1745 if (el.getBoundingClientRect) {
1746 b = el.getBoundingClientRect();
1747 scroll = fly(document).getScroll();
1748 return [b.left + scroll.left, b.top + scroll.top];
1754 var hasAbsolute = fly(el).getStyle("position") == "absolute";
1761 if (!hasAbsolute && fly(p).getStyle("position") == "absolute") {
1768 var bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0;
1769 var bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0;
1776 if (p != el && pe.getStyle('overflow') != 'visible') {
1784 if (Roo.isSafari && hasAbsolute) {
1789 if (Roo.isGecko && !hasAbsolute) {
1791 x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0;
1792 y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0;
1796 while (p && p != bd) {
1797 if (!Roo.isOpera || (p.tagName != 'TR' && fly(p).getStyle("display") != "inline")) {
1809 setXY : function(el, xy) {
1810 el = Roo.fly(el, '_setXY');
1812 var pts = el.translatePoints(xy);
1813 if (xy[0] !== false) {
1814 el.dom.style.left = pts.left + "px";
1816 if (xy[1] !== false) {
1817 el.dom.style.top = pts.top + "px";
1821 setX : function(el, x) {
1822 this.setXY(el, [x, false]);
1825 setY : function(el, y) {
1826 this.setXY(el, [false, y]);
1830 * Portions of this file are based on pieces of Yahoo User Interface Library
1831 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
1832 * YUI licensed under the BSD License:
1833 * http://developer.yahoo.net/yui/license.txt
1834 * <script type="text/javascript">
1838 Roo.lib.Event = function() {
1839 var loadComplete = false;
1841 var unloadListeners = [];
1843 var onAvailStack = [];
1845 var lastError = null;
1858 startInterval: function() {
1859 if (!this._interval) {
1861 var callback = function() {
1862 self._tryPreloadAttach();
1864 this._interval = setInterval(callback, this.POLL_INTERVAL);
1869 onAvailable: function(p_id, p_fn, p_obj, p_override) {
1870 onAvailStack.push({ id: p_id,
1873 override: p_override,
1874 checkReady: false });
1876 retryCount = this.POLL_RETRYS;
1877 this.startInterval();
1881 addListener: function(el, eventName, fn) {
1882 el = Roo.getDom(el);
1887 if ("unload" == eventName) {
1888 unloadListeners[unloadListeners.length] =
1889 [el, eventName, fn];
1893 var wrappedFn = function(e) {
1894 return fn(Roo.lib.Event.getEvent(e));
1897 var li = [el, eventName, fn, wrappedFn];
1899 var index = listeners.length;
1900 listeners[index] = li;
1902 this.doAdd(el, eventName, wrappedFn, false);
1908 removeListener: function(el, eventName, fn) {
1911 el = Roo.getDom(el);
1914 return this.purgeElement(el, false, eventName);
1918 if ("unload" == eventName) {
1920 for (i = 0,len = unloadListeners.length; i < len; i++) {
1921 var li = unloadListeners[i];
1924 li[1] == eventName &&
1926 unloadListeners.splice(i, 1);
1934 var cacheItem = null;
1937 var index = arguments[3];
1939 if ("undefined" == typeof index) {
1940 index = this._getCacheIndex(el, eventName, fn);
1944 cacheItem = listeners[index];
1947 if (!el || !cacheItem) {
1951 this.doRemove(el, eventName, cacheItem[this.WFN], false);
1953 delete listeners[index][this.WFN];
1954 delete listeners[index][this.FN];
1955 listeners.splice(index, 1);
1962 getTarget: function(ev, resolveTextNode) {
1963 ev = ev.browserEvent || ev;
1964 var t = ev.target || ev.srcElement;
1965 return this.resolveTextNode(t);
1969 resolveTextNode: function(node) {
1970 if (Roo.isSafari && node && 3 == node.nodeType) {
1971 return node.parentNode;
1978 getPageX: function(ev) {
1979 ev = ev.browserEvent || ev;
1981 if (!x && 0 !== x) {
1982 x = ev.clientX || 0;
1985 x += this.getScroll()[1];
1993 getPageY: function(ev) {
1994 ev = ev.browserEvent || ev;
1996 if (!y && 0 !== y) {
1997 y = ev.clientY || 0;
2000 y += this.getScroll()[0];
2009 getXY: function(ev) {
2010 ev = ev.browserEvent || ev;
2011 return [this.getPageX(ev), this.getPageY(ev)];
2015 getRelatedTarget: function(ev) {
2016 ev = ev.browserEvent || ev;
2017 var t = ev.relatedTarget;
2019 if (ev.type == "mouseout") {
2021 } else if (ev.type == "mouseover") {
2026 return this.resolveTextNode(t);
2030 getTime: function(ev) {
2031 ev = ev.browserEvent || ev;
2033 var t = new Date().getTime();
2037 this.lastError = ex;
2046 stopEvent: function(ev) {
2047 this.stopPropagation(ev);
2048 this.preventDefault(ev);
2052 stopPropagation: function(ev) {
2053 ev = ev.browserEvent || ev;
2054 if (ev.stopPropagation) {
2055 ev.stopPropagation();
2057 ev.cancelBubble = true;
2062 preventDefault: function(ev) {
2063 ev = ev.browserEvent || ev;
2064 if(ev.preventDefault) {
2065 ev.preventDefault();
2067 ev.returnValue = false;
2072 getEvent: function(e) {
2073 var ev = e || window.event;
2075 var c = this.getEvent.caller;
2077 ev = c.arguments[0];
2078 if (ev && Event == ev.constructor) {
2088 getCharCode: function(ev) {
2089 ev = ev.browserEvent || ev;
2090 return ev.charCode || ev.keyCode || 0;
2094 _getCacheIndex: function(el, eventName, fn) {
2095 for (var i = 0,len = listeners.length; i < len; ++i) {
2096 var li = listeners[i];
2098 li[this.FN] == fn &&
2099 li[this.EL] == el &&
2100 li[this.TYPE] == eventName) {
2112 getEl: function(id) {
2113 return document.getElementById(id);
2117 clearCache: function() {
2121 _load: function(e) {
2122 loadComplete = true;
2123 var EU = Roo.lib.Event;
2127 EU.doRemove(window, "load", EU._load);
2132 _tryPreloadAttach: function() {
2141 var tryAgain = !loadComplete;
2143 tryAgain = (retryCount > 0);
2148 for (var i = 0,len = onAvailStack.length; i < len; ++i) {
2149 var item = onAvailStack[i];
2151 var el = this.getEl(item.id);
2154 if (!item.checkReady ||
2157 (document && document.body)) {
2160 if (item.override) {
2161 if (item.override === true) {
2164 scope = item.override;
2167 item.fn.call(scope, item.obj);
2168 onAvailStack[i] = null;
2171 notAvail.push(item);
2176 retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
2180 this.startInterval();
2182 clearInterval(this._interval);
2183 this._interval = null;
2186 this.locked = false;
2193 purgeElement: function(el, recurse, eventName) {
2194 var elListeners = this.getListeners(el, eventName);
2196 for (var i = 0,len = elListeners.length; i < len; ++i) {
2197 var l = elListeners[i];
2198 this.removeListener(el, l.type, l.fn);
2202 if (recurse && el && el.childNodes) {
2203 for (i = 0,len = el.childNodes.length; i < len; ++i) {
2204 this.purgeElement(el.childNodes[i], recurse, eventName);
2210 getListeners: function(el, eventName) {
2211 var results = [], searchLists;
2213 searchLists = [listeners, unloadListeners];
2214 } else if (eventName == "unload") {
2215 searchLists = [unloadListeners];
2217 searchLists = [listeners];
2220 for (var j = 0; j < searchLists.length; ++j) {
2221 var searchList = searchLists[j];
2222 if (searchList && searchList.length > 0) {
2223 for (var i = 0,len = searchList.length; i < len; ++i) {
2224 var l = searchList[i];
2225 if (l && l[this.EL] === el &&
2226 (!eventName || eventName === l[this.TYPE])) {
2231 adjust: l[this.ADJ_SCOPE],
2239 return (results.length) ? results : null;
2243 _unload: function(e) {
2245 var EU = Roo.lib.Event, i, j, l, len, index;
2247 for (i = 0,len = unloadListeners.length; i < len; ++i) {
2248 l = unloadListeners[i];
2251 if (l[EU.ADJ_SCOPE]) {
2252 if (l[EU.ADJ_SCOPE] === true) {
2255 scope = l[EU.ADJ_SCOPE];
2258 l[EU.FN].call(scope, EU.getEvent(e), l[EU.OBJ]);
2259 unloadListeners[i] = null;
2265 unloadListeners = null;
2267 if (listeners && listeners.length > 0) {
2268 j = listeners.length;
2271 l = listeners[index];
2273 EU.removeListener(l[EU.EL], l[EU.TYPE],
2283 EU.doRemove(window, "unload", EU._unload);
2288 getScroll: function() {
2289 var dd = document.documentElement, db = document.body;
2290 if (dd && (dd.scrollTop || dd.scrollLeft)) {
2291 return [dd.scrollTop, dd.scrollLeft];
2293 return [db.scrollTop, db.scrollLeft];
2300 doAdd: function () {
2301 if (window.addEventListener) {
2302 return function(el, eventName, fn, capture) {
2303 el.addEventListener(eventName, fn, (capture));
2305 } else if (window.attachEvent) {
2306 return function(el, eventName, fn, capture) {
2307 el.attachEvent("on" + eventName, fn);
2316 doRemove: function() {
2317 if (window.removeEventListener) {
2318 return function (el, eventName, fn, capture) {
2319 el.removeEventListener(eventName, fn, (capture));
2321 } else if (window.detachEvent) {
2322 return function (el, eventName, fn) {
2323 el.detachEvent("on" + eventName, fn);
2335 var E = Roo.lib.Event;
2336 E.on = E.addListener;
2337 E.un = E.removeListener;
2339 if (document && document.body) {
2342 E.doAdd(window, "load", E._load);
2344 E.doAdd(window, "unload", E._unload);
2345 E._tryPreloadAttach();
2349 * Portions of this file are based on pieces of Yahoo User Interface Library
2350 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
2351 * YUI licensed under the BSD License:
2352 * http://developer.yahoo.net/yui/license.txt
2353 * <script type="text/javascript">
2360 request : function(method, uri, cb, data, options) {
2362 var hs = options.headers;
2365 if(hs.hasOwnProperty(h)){
2366 this.initHeader(h, hs[h], false);
2370 if(options.xmlData){
2371 this.initHeader('Content-Type', 'text/xml', false);
2373 data = options.xmlData;
2377 return this.asyncRequest(method, uri, cb, data);
2380 serializeForm : function(form) {
2381 if(typeof form == 'string') {
2382 form = (document.getElementById(form) || document.forms[form]);
2385 var el, name, val, disabled, data = '', hasSubmit = false;
2386 for (var i = 0; i < form.elements.length; i++) {
2387 el = form.elements[i];
2388 disabled = form.elements[i].disabled;
2389 name = form.elements[i].name;
2390 val = form.elements[i].value;
2392 if (!disabled && name){
2396 case 'select-multiple':
2397 for (var j = 0; j < el.options.length; j++) {
2398 if (el.options[j].selected) {
2400 data += encodeURIComponent(name) + '=' + encodeURIComponent(el.options[j].attributes['value'].specified ? el.options[j].value : el.options[j].text) + '&';
2403 data += encodeURIComponent(name) + '=' + encodeURIComponent(el.options[j].hasAttribute('value') ? el.options[j].value : el.options[j].text) + '&';
2411 data += encodeURIComponent(name) + '=' + encodeURIComponent(val) + '&';
2424 if(hasSubmit == false) {
2425 data += encodeURIComponent(name) + '=' + encodeURIComponent(val) + '&';
2430 data += encodeURIComponent(name) + '=' + encodeURIComponent(val) + '&';
2435 data = data.substr(0, data.length - 1);
2443 useDefaultHeader:true,
2445 defaultPostHeader:'application/x-www-form-urlencoded',
2447 useDefaultXhrHeader:true,
2449 defaultXhrHeader:'XMLHttpRequest',
2451 hasDefaultHeaders:true,
2463 setProgId:function(id)
2465 this.activeX.unshift(id);
2468 setDefaultPostHeader:function(b)
2470 this.useDefaultHeader = b;
2473 setDefaultXhrHeader:function(b)
2475 this.useDefaultXhrHeader = b;
2478 setPollingInterval:function(i)
2480 if (typeof i == 'number' && isFinite(i)) {
2481 this.pollInterval = i;
2485 createXhrObject:function(transactionId)
2491 http = new XMLHttpRequest();
2493 obj = { conn:http, tId:transactionId };
2497 for (var i = 0; i < this.activeX.length; ++i) {
2501 http = new ActiveXObject(this.activeX[i]);
2503 obj = { conn:http, tId:transactionId };
2516 getConnectionObject:function()
2519 var tId = this.transactionId;
2523 o = this.createXhrObject(tId);
2525 this.transactionId++;
2536 asyncRequest:function(method, uri, callback, postData)
2538 var o = this.getConnectionObject();
2544 o.conn.open(method, uri, true);
2546 if (this.useDefaultXhrHeader) {
2547 if (!this.defaultHeaders['X-Requested-With']) {
2548 this.initHeader('X-Requested-With', this.defaultXhrHeader, true);
2552 if(postData && this.useDefaultHeader){
2553 this.initHeader('Content-Type', this.defaultPostHeader);
2556 if (this.hasDefaultHeaders || this.hasHeaders) {
2560 this.handleReadyState(o, callback);
2561 o.conn.send(postData || null);
2567 handleReadyState:function(o, callback)
2571 if (callback && callback.timeout) {
2572 this.timeout[o.tId] = window.setTimeout(function() {
2573 oConn.abort(o, callback, true);
2574 }, callback.timeout);
2577 this.poll[o.tId] = window.setInterval(
2579 if (o.conn && o.conn.readyState == 4) {
2580 window.clearInterval(oConn.poll[o.tId]);
2581 delete oConn.poll[o.tId];
2583 if(callback && callback.timeout) {
2584 window.clearTimeout(oConn.timeout[o.tId]);
2585 delete oConn.timeout[o.tId];
2588 oConn.handleTransactionResponse(o, callback);
2591 , this.pollInterval);
2594 handleTransactionResponse:function(o, callback, isAbort)
2598 this.releaseObject(o);
2602 var httpStatus, responseObject;
2606 if (o.conn.status !== undefined && o.conn.status != 0) {
2607 httpStatus = o.conn.status;
2619 if (httpStatus >= 200 && httpStatus < 300) {
2620 responseObject = this.createResponseObject(o, callback.argument);
2621 if (callback.success) {
2622 if (!callback.scope) {
2623 callback.success(responseObject);
2628 callback.success.apply(callback.scope, [responseObject]);
2633 switch (httpStatus) {
2641 responseObject = this.createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false));
2642 if (callback.failure) {
2643 if (!callback.scope) {
2644 callback.failure(responseObject);
2647 callback.failure.apply(callback.scope, [responseObject]);
2652 responseObject = this.createResponseObject(o, callback.argument);
2653 if (callback.failure) {
2654 if (!callback.scope) {
2655 callback.failure(responseObject);
2658 callback.failure.apply(callback.scope, [responseObject]);
2664 this.releaseObject(o);
2665 responseObject = null;
2668 createResponseObject:function(o, callbackArg)
2675 var headerStr = o.conn.getAllResponseHeaders();
2676 var header = headerStr.split('\n');
2677 for (var i = 0; i < header.length; i++) {
2678 var delimitPos = header[i].indexOf(':');
2679 if (delimitPos != -1) {
2680 headerObj[header[i].substring(0, delimitPos)] = header[i].substring(delimitPos + 2);
2688 obj.status = o.conn.status;
2689 obj.statusText = o.conn.statusText;
2690 obj.getResponseHeader = headerObj;
2691 obj.getAllResponseHeaders = headerStr;
2692 obj.responseText = o.conn.responseText;
2693 obj.responseXML = o.conn.responseXML;
2695 if (typeof callbackArg !== undefined) {
2696 obj.argument = callbackArg;
2702 createExceptionObject:function(tId, callbackArg, isAbort)
2705 var COMM_ERROR = 'communication failure';
2706 var ABORT_CODE = -1;
2707 var ABORT_ERROR = 'transaction aborted';
2713 obj.status = ABORT_CODE;
2714 obj.statusText = ABORT_ERROR;
2717 obj.status = COMM_CODE;
2718 obj.statusText = COMM_ERROR;
2722 obj.argument = callbackArg;
2728 initHeader:function(label, value, isDefault)
2730 var headerObj = (isDefault) ? this.defaultHeaders : this.headers;
2732 if (headerObj[label] === undefined) {
2733 headerObj[label] = value;
2738 headerObj[label] = value + "," + headerObj[label];
2742 this.hasDefaultHeaders = true;
2745 this.hasHeaders = true;
2750 setHeader:function(o)
2752 if (this.hasDefaultHeaders) {
2753 for (var prop in this.defaultHeaders) {
2754 if (this.defaultHeaders.hasOwnProperty(prop)) {
2755 o.conn.setRequestHeader(prop, this.defaultHeaders[prop]);
2760 if (this.hasHeaders) {
2761 for (var prop in this.headers) {
2762 if (this.headers.hasOwnProperty(prop)) {
2763 o.conn.setRequestHeader(prop, this.headers[prop]);
2767 this.hasHeaders = false;
2771 resetDefaultHeaders:function() {
2772 delete this.defaultHeaders;
2773 this.defaultHeaders = {};
2774 this.hasDefaultHeaders = false;
2777 abort:function(o, callback, isTimeout)
2779 if(this.isCallInProgress(o)) {
2781 window.clearInterval(this.poll[o.tId]);
2782 delete this.poll[o.tId];
2784 delete this.timeout[o.tId];
2787 this.handleTransactionResponse(o, callback, true);
2797 isCallInProgress:function(o)
2800 return o.conn.readyState != 4 && o.conn.readyState != 0;
2809 releaseObject:function(o)
2818 'MSXML2.XMLHTTP.3.0',
2826 * Portions of this file are based on pieces of Yahoo User Interface Library
2827 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
2828 * YUI licensed under the BSD License:
2829 * http://developer.yahoo.net/yui/license.txt
2830 * <script type="text/javascript">
2834 Roo.lib.Region = function(t, r, b, l) {
2844 Roo.lib.Region.prototype = {
2845 contains : function(region) {
2846 return ( region.left >= this.left &&
2847 region.right <= this.right &&
2848 region.top >= this.top &&
2849 region.bottom <= this.bottom );
2853 getArea : function() {
2854 return ( (this.bottom - this.top) * (this.right - this.left) );
2857 intersect : function(region) {
2858 var t = Math.max(this.top, region.top);
2859 var r = Math.min(this.right, region.right);
2860 var b = Math.min(this.bottom, region.bottom);
2861 var l = Math.max(this.left, region.left);
2863 if (b >= t && r >= l) {
2864 return new Roo.lib.Region(t, r, b, l);
2869 union : function(region) {
2870 var t = Math.min(this.top, region.top);
2871 var r = Math.max(this.right, region.right);
2872 var b = Math.max(this.bottom, region.bottom);
2873 var l = Math.min(this.left, region.left);
2875 return new Roo.lib.Region(t, r, b, l);
2878 adjust : function(t, l, b, r) {
2887 Roo.lib.Region.getRegion = function(el) {
2888 var p = Roo.lib.Dom.getXY(el);
2891 var r = p[0] + el.offsetWidth;
2892 var b = p[1] + el.offsetHeight;
2895 return new Roo.lib.Region(t, r, b, l);
2898 * Portions of this file are based on pieces of Yahoo User Interface Library
2899 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
2900 * YUI licensed under the BSD License:
2901 * http://developer.yahoo.net/yui/license.txt
2902 * <script type="text/javascript">
2905 //@@dep Roo.lib.Region
2908 Roo.lib.Point = function(x, y) {
2909 if (x instanceof Array) {
2913 this.x = this.right = this.left = this[0] = x;
2914 this.y = this.top = this.bottom = this[1] = y;
2917 Roo.lib.Point.prototype = new Roo.lib.Region();
2919 * Portions of this file are based on pieces of Yahoo User Interface Library
2920 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
2921 * YUI licensed under the BSD License:
2922 * http://developer.yahoo.net/yui/license.txt
2923 * <script type="text/javascript">
2930 scroll : function(el, args, duration, easing, cb, scope) {
2931 this.run(el, args, duration, easing, cb, scope, Roo.lib.Scroll);
2934 motion : function(el, args, duration, easing, cb, scope) {
2935 this.run(el, args, duration, easing, cb, scope, Roo.lib.Motion);
2938 color : function(el, args, duration, easing, cb, scope) {
2939 this.run(el, args, duration, easing, cb, scope, Roo.lib.ColorAnim);
2942 run : function(el, args, duration, easing, cb, scope, type) {
2943 type = type || Roo.lib.AnimBase;
2944 if (typeof easing == "string") {
2945 easing = Roo.lib.Easing[easing];
2947 var anim = new type(el, args, duration, easing);
2948 anim.animateX(function() {
2949 Roo.callback(cb, scope);
2955 * Portions of this file are based on pieces of Yahoo User Interface Library
2956 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
2957 * YUI licensed under the BSD License:
2958 * http://developer.yahoo.net/yui/license.txt
2959 * <script type="text/javascript">
2967 if (!libFlyweight) {
2968 libFlyweight = new Roo.Element.Flyweight();
2970 libFlyweight.dom = el;
2971 return libFlyweight;
2974 // since this uses fly! - it cant be in DOM (which does not have fly yet..)
2978 Roo.lib.AnimBase = function(el, attributes, duration, method) {
2980 this.init(el, attributes, duration, method);
2984 Roo.lib.AnimBase.fly = fly;
2988 Roo.lib.AnimBase.prototype = {
2990 toString: function() {
2991 var el = this.getEl();
2992 var id = el.id || el.tagName;
2993 return ("Anim " + id);
2997 noNegatives: /width|height|opacity|padding/i,
2998 offsetAttribute: /^((width|height)|(top|left))$/,
2999 defaultUnit: /width|height|top$|bottom$|left$|right$/i,
3000 offsetUnit: /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i
3004 doMethod: function(attr, start, end) {
3005 return this.method(this.currentFrame, start, end - start, this.totalFrames);
3009 setAttribute: function(attr, val, unit) {
3010 if (this.patterns.noNegatives.test(attr)) {
3011 val = (val > 0) ? val : 0;
3014 Roo.fly(this.getEl(), '_anim').setStyle(attr, val + unit);
3018 getAttribute: function(attr) {
3019 var el = this.getEl();
3020 var val = fly(el).getStyle(attr);
3022 if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
3023 return parseFloat(val);
3026 var a = this.patterns.offsetAttribute.exec(attr) || [];
3027 var pos = !!( a[3] );
3028 var box = !!( a[2] );
3031 if (box || (fly(el).getStyle('position') == 'absolute' && pos)) {
3032 val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
3041 getDefaultUnit: function(attr) {
3042 if (this.patterns.defaultUnit.test(attr)) {
3049 animateX : function(callback, scope) {
3050 var f = function() {
3051 this.onComplete.removeListener(f);
3052 if (typeof callback == "function") {
3053 callback.call(scope || this, this);
3056 this.onComplete.addListener(f, this);
3061 setRuntimeAttribute: function(attr) {
3064 var attributes = this.attributes;
3066 this.runtimeAttributes[attr] = {};
3068 var isset = function(prop) {
3069 return (typeof prop !== 'undefined');
3072 if (!isset(attributes[attr]['to']) && !isset(attributes[attr]['by'])) {
3076 start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
3079 if (isset(attributes[attr]['to'])) {
3080 end = attributes[attr]['to'];
3081 } else if (isset(attributes[attr]['by'])) {
3082 if (start.constructor == Array) {
3084 for (var i = 0, len = start.length; i < len; ++i) {
3085 end[i] = start[i] + attributes[attr]['by'][i];
3088 end = start + attributes[attr]['by'];
3092 this.runtimeAttributes[attr].start = start;
3093 this.runtimeAttributes[attr].end = end;
3096 this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ? attributes[attr]['unit'] : this.getDefaultUnit(attr);
3100 init: function(el, attributes, duration, method) {
3102 var isAnimated = false;
3105 var startTime = null;
3108 var actualFrames = 0;
3111 el = Roo.getDom(el);
3114 this.attributes = attributes || {};
3117 this.duration = duration || 1;
3120 this.method = method || Roo.lib.Easing.easeNone;
3123 this.useSeconds = true;
3126 this.currentFrame = 0;
3129 this.totalFrames = Roo.lib.AnimMgr.fps;
3132 this.getEl = function() {
3137 this.isAnimated = function() {
3142 this.getStartTime = function() {
3146 this.runtimeAttributes = {};
3149 this.animate = function() {
3150 if (this.isAnimated()) {
3154 this.currentFrame = 0;
3156 this.totalFrames = ( this.useSeconds ) ? Math.ceil(Roo.lib.AnimMgr.fps * this.duration) : this.duration;
3158 Roo.lib.AnimMgr.registerElement(this);
3162 this.stop = function(finish) {
3164 this.currentFrame = this.totalFrames;
3165 this._onTween.fire();
3167 Roo.lib.AnimMgr.stop(this);
3170 var onStart = function() {
3171 this.onStart.fire();
3173 this.runtimeAttributes = {};
3174 for (var attr in this.attributes) {
3175 this.setRuntimeAttribute(attr);
3180 startTime = new Date();
3184 var onTween = function() {
3186 duration: new Date() - this.getStartTime(),
3187 currentFrame: this.currentFrame
3190 data.toString = function() {
3192 'duration: ' + data.duration +
3193 ', currentFrame: ' + data.currentFrame
3197 this.onTween.fire(data);
3199 var runtimeAttributes = this.runtimeAttributes;
3201 for (var attr in runtimeAttributes) {
3202 this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);
3208 var onComplete = function() {
3209 var actual_duration = (new Date() - startTime) / 1000 ;
3212 duration: actual_duration,
3213 frames: actualFrames,
3214 fps: actualFrames / actual_duration
3217 data.toString = function() {
3219 'duration: ' + data.duration +
3220 ', frames: ' + data.frames +
3221 ', fps: ' + data.fps
3227 this.onComplete.fire(data);
3231 this._onStart = new Roo.util.Event(this);
3232 this.onStart = new Roo.util.Event(this);
3233 this.onTween = new Roo.util.Event(this);
3234 this._onTween = new Roo.util.Event(this);
3235 this.onComplete = new Roo.util.Event(this);
3236 this._onComplete = new Roo.util.Event(this);
3237 this._onStart.addListener(onStart);
3238 this._onTween.addListener(onTween);
3239 this._onComplete.addListener(onComplete);
3244 * Portions of this file are based on pieces of Yahoo User Interface Library
3245 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3246 * YUI licensed under the BSD License:
3247 * http://developer.yahoo.net/yui/license.txt
3248 * <script type="text/javascript">
3252 Roo.lib.AnimMgr = new function() {
3269 this.registerElement = function(tween) {
3270 queue[queue.length] = tween;
3272 tween._onStart.fire();
3277 this.unRegister = function(tween, index) {
3278 tween._onComplete.fire();
3279 index = index || getIndex(tween);
3281 queue.splice(index, 1);
3285 if (tweenCount <= 0) {
3291 this.start = function() {
3292 if (thread === null) {
3293 thread = setInterval(this.run, this.delay);
3298 this.stop = function(tween) {
3300 clearInterval(thread);
3302 for (var i = 0, len = queue.length; i < len; ++i) {
3303 if (queue[0].isAnimated()) {
3304 this.unRegister(queue[0], 0);
3313 this.unRegister(tween);
3318 this.run = function() {
3319 for (var i = 0, len = queue.length; i < len; ++i) {
3320 var tween = queue[i];
3321 if (!tween || !tween.isAnimated()) {
3325 if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
3327 tween.currentFrame += 1;
3329 if (tween.useSeconds) {
3330 correctFrame(tween);
3332 tween._onTween.fire();
3335 Roo.lib.AnimMgr.stop(tween, i);
3340 var getIndex = function(anim) {
3341 for (var i = 0, len = queue.length; i < len; ++i) {
3342 if (queue[i] == anim) {
3350 var correctFrame = function(tween) {
3351 var frames = tween.totalFrames;
3352 var frame = tween.currentFrame;
3353 var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
3354 var elapsed = (new Date() - tween.getStartTime());
3357 if (elapsed < tween.duration * 1000) {
3358 tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
3360 tweak = frames - (frame + 1);
3362 if (tweak > 0 && isFinite(tweak)) {
3363 if (tween.currentFrame + tweak >= frames) {
3364 tweak = frames - (frame + 1);
3367 tween.currentFrame += tweak;
3371 * Portions of this file are based on pieces of Yahoo User Interface Library
3372 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3373 * YUI licensed under the BSD License:
3374 * http://developer.yahoo.net/yui/license.txt
3375 * <script type="text/javascript">
3378 Roo.lib.Bezier = new function() {
3380 this.getPosition = function(points, t) {
3381 var n = points.length;
3384 for (var i = 0; i < n; ++i) {
3385 tmp[i] = [points[i][0], points[i][1]];
3388 for (var j = 1; j < n; ++j) {
3389 for (i = 0; i < n - j; ++i) {
3390 tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
3391 tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
3395 return [ tmp[0][0], tmp[0][1] ];
3399 * Portions of this file are based on pieces of Yahoo User Interface Library
3400 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3401 * YUI licensed under the BSD License:
3402 * http://developer.yahoo.net/yui/license.txt
3403 * <script type="text/javascript">
3408 Roo.lib.ColorAnim = function(el, attributes, duration, method) {
3409 Roo.lib.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
3412 Roo.extend(Roo.lib.ColorAnim, Roo.lib.AnimBase);
3414 var fly = Roo.lib.AnimBase.fly;
3416 var superclass = Y.ColorAnim.superclass;
3417 var proto = Y.ColorAnim.prototype;
3419 proto.toString = function() {
3420 var el = this.getEl();
3421 var id = el.id || el.tagName;
3422 return ("ColorAnim " + id);
3425 proto.patterns.color = /color$/i;
3426 proto.patterns.rgb = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
3427 proto.patterns.hex = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
3428 proto.patterns.hex3 = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
3429 proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/;
3432 proto.parseColor = function(s) {
3433 if (s.length == 3) {
3437 var c = this.patterns.hex.exec(s);
3438 if (c && c.length == 4) {
3439 return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
3442 c = this.patterns.rgb.exec(s);
3443 if (c && c.length == 4) {
3444 return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
3447 c = this.patterns.hex3.exec(s);
3448 if (c && c.length == 4) {
3449 return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
3454 // since this uses fly! - it cant be in ColorAnim (which does not have fly yet..)
3455 proto.getAttribute = function(attr) {
3456 var el = this.getEl();
3457 if (this.patterns.color.test(attr)) {
3458 var val = fly(el).getStyle(attr);
3460 if (this.patterns.transparent.test(val)) {
3461 var parent = el.parentNode;
3462 val = fly(parent).getStyle(attr);
3464 while (parent && this.patterns.transparent.test(val)) {
3465 parent = parent.parentNode;
3466 val = fly(parent).getStyle(attr);
3467 if (parent.tagName.toUpperCase() == 'HTML') {
3473 val = superclass.getAttribute.call(this, attr);
3478 proto.getAttribute = function(attr) {
3479 var el = this.getEl();
3480 if (this.patterns.color.test(attr)) {
3481 var val = fly(el).getStyle(attr);
3483 if (this.patterns.transparent.test(val)) {
3484 var parent = el.parentNode;
3485 val = fly(parent).getStyle(attr);
3487 while (parent && this.patterns.transparent.test(val)) {
3488 parent = parent.parentNode;
3489 val = fly(parent).getStyle(attr);
3490 if (parent.tagName.toUpperCase() == 'HTML') {
3496 val = superclass.getAttribute.call(this, attr);
3502 proto.doMethod = function(attr, start, end) {
3505 if (this.patterns.color.test(attr)) {
3507 for (var i = 0, len = start.length; i < len; ++i) {
3508 val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
3511 val = 'rgb(' + Math.floor(val[0]) + ',' + Math.floor(val[1]) + ',' + Math.floor(val[2]) + ')';
3514 val = superclass.doMethod.call(this, attr, start, end);
3520 proto.setRuntimeAttribute = function(attr) {
3521 superclass.setRuntimeAttribute.call(this, attr);
3523 if (this.patterns.color.test(attr)) {
3524 var attributes = this.attributes;
3525 var start = this.parseColor(this.runtimeAttributes[attr].start);
3526 var end = this.parseColor(this.runtimeAttributes[attr].end);
3528 if (typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined') {
3529 end = this.parseColor(attributes[attr].by);
3531 for (var i = 0, len = start.length; i < len; ++i) {
3532 end[i] = start[i] + end[i];
3536 this.runtimeAttributes[attr].start = start;
3537 this.runtimeAttributes[attr].end = end;
3543 * Portions of this file are based on pieces of Yahoo User Interface Library
3544 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3545 * YUI licensed under the BSD License:
3546 * http://developer.yahoo.net/yui/license.txt
3547 * <script type="text/javascript">
3553 easeNone: function (t, b, c, d) {
3554 return c * t / d + b;
3558 easeIn: function (t, b, c, d) {
3559 return c * (t /= d) * t + b;
3563 easeOut: function (t, b, c, d) {
3564 return -c * (t /= d) * (t - 2) + b;
3568 easeBoth: function (t, b, c, d) {
3569 if ((t /= d / 2) < 1) {
3570 return c / 2 * t * t + b;
3573 return -c / 2 * ((--t) * (t - 2) - 1) + b;
3577 easeInStrong: function (t, b, c, d) {
3578 return c * (t /= d) * t * t * t + b;
3582 easeOutStrong: function (t, b, c, d) {
3583 return -c * ((t = t / d - 1) * t * t * t - 1) + b;
3587 easeBothStrong: function (t, b, c, d) {
3588 if ((t /= d / 2) < 1) {
3589 return c / 2 * t * t * t * t + b;
3592 return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
3597 elasticIn: function (t, b, c, d, a, p) {
3601 if ((t /= d) == 1) {
3608 if (!a || a < Math.abs(c)) {
3613 var s = p / (2 * Math.PI) * Math.asin(c / a);
3616 return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
3620 elasticOut: function (t, b, c, d, a, p) {
3624 if ((t /= d) == 1) {
3631 if (!a || a < Math.abs(c)) {
3636 var s = p / (2 * Math.PI) * Math.asin(c / a);
3639 return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
3643 elasticBoth: function (t, b, c, d, a, p) {
3648 if ((t /= d / 2) == 2) {
3656 if (!a || a < Math.abs(c)) {
3661 var s = p / (2 * Math.PI) * Math.asin(c / a);
3665 return -.5 * (a * Math.pow(2, 10 * (t -= 1)) *
3666 Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
3668 return a * Math.pow(2, -10 * (t -= 1)) *
3669 Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
3674 backIn: function (t, b, c, d, s) {
3675 if (typeof s == 'undefined') {
3678 return c * (t /= d) * t * ((s + 1) * t - s) + b;
3682 backOut: function (t, b, c, d, s) {
3683 if (typeof s == 'undefined') {
3686 return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
3690 backBoth: function (t, b, c, d, s) {
3691 if (typeof s == 'undefined') {
3695 if ((t /= d / 2 ) < 1) {
3696 return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
3698 return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
3702 bounceIn: function (t, b, c, d) {
3703 return c - Roo.lib.Easing.bounceOut(d - t, 0, c, d) + b;
3707 bounceOut: function (t, b, c, d) {
3708 if ((t /= d) < (1 / 2.75)) {
3709 return c * (7.5625 * t * t) + b;
3710 } else if (t < (2 / 2.75)) {
3711 return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
3712 } else if (t < (2.5 / 2.75)) {
3713 return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
3715 return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
3719 bounceBoth: function (t, b, c, d) {
3721 return Roo.lib.Easing.bounceIn(t * 2, 0, c, d) * .5 + b;
3723 return Roo.lib.Easing.bounceOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
3726 * Portions of this file are based on pieces of Yahoo User Interface Library
3727 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3728 * YUI licensed under the BSD License:
3729 * http://developer.yahoo.net/yui/license.txt
3730 * <script type="text/javascript">
3734 Roo.lib.Motion = function(el, attributes, duration, method) {
3736 Roo.lib.Motion.superclass.constructor.call(this, el, attributes, duration, method);
3740 Roo.extend(Roo.lib.Motion, Roo.lib.ColorAnim);
3744 var superclass = Y.Motion.superclass;
3745 var proto = Y.Motion.prototype;
3747 proto.toString = function() {
3748 var el = this.getEl();
3749 var id = el.id || el.tagName;
3750 return ("Motion " + id);
3753 proto.patterns.points = /^points$/i;
3755 proto.setAttribute = function(attr, val, unit) {
3756 if (this.patterns.points.test(attr)) {
3757 unit = unit || 'px';
3758 superclass.setAttribute.call(this, 'left', val[0], unit);
3759 superclass.setAttribute.call(this, 'top', val[1], unit);
3761 superclass.setAttribute.call(this, attr, val, unit);
3765 proto.getAttribute = function(attr) {
3766 if (this.patterns.points.test(attr)) {
3768 superclass.getAttribute.call(this, 'left'),
3769 superclass.getAttribute.call(this, 'top')
3772 val = superclass.getAttribute.call(this, attr);
3778 proto.doMethod = function(attr, start, end) {
3781 if (this.patterns.points.test(attr)) {
3782 var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;
3783 val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
3785 val = superclass.doMethod.call(this, attr, start, end);
3790 proto.setRuntimeAttribute = function(attr) {
3791 if (this.patterns.points.test(attr)) {
3792 var el = this.getEl();
3793 var attributes = this.attributes;
3795 var control = attributes['points']['control'] || [];
3799 if (control.length > 0 && !(control[0] instanceof Array)) {
3800 control = [control];
3803 for (i = 0,len = control.length; i < len; ++i) {
3804 tmp[i] = control[i];
3809 Roo.fly(el).position();
3811 if (isset(attributes['points']['from'])) {
3812 Roo.lib.Dom.setXY(el, attributes['points']['from']);
3815 Roo.lib.Dom.setXY(el, Roo.lib.Dom.getXY(el));
3818 start = this.getAttribute('points');
3821 if (isset(attributes['points']['to'])) {
3822 end = translateValues.call(this, attributes['points']['to'], start);
3824 var pageXY = Roo.lib.Dom.getXY(this.getEl());
3825 for (i = 0,len = control.length; i < len; ++i) {
3826 control[i] = translateValues.call(this, control[i], start);
3830 } else if (isset(attributes['points']['by'])) {
3831 end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
3833 for (i = 0,len = control.length; i < len; ++i) {
3834 control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
3838 this.runtimeAttributes[attr] = [start];
3840 if (control.length > 0) {
3841 this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control);
3844 this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
3847 superclass.setRuntimeAttribute.call(this, attr);
3851 var translateValues = function(val, start) {
3852 var pageXY = Roo.lib.Dom.getXY(this.getEl());
3853 val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
3858 var isset = function(prop) {
3859 return (typeof prop !== 'undefined');
3863 * Portions of this file are based on pieces of Yahoo User Interface Library
3864 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3865 * YUI licensed under the BSD License:
3866 * http://developer.yahoo.net/yui/license.txt
3867 * <script type="text/javascript">
3871 Roo.lib.Scroll = function(el, attributes, duration, method) {
3873 Roo.lib.Scroll.superclass.constructor.call(this, el, attributes, duration, method);
3877 Roo.extend(Roo.lib.Scroll, Roo.lib.ColorAnim);
3881 var superclass = Y.Scroll.superclass;
3882 var proto = Y.Scroll.prototype;
3884 proto.toString = function() {
3885 var el = this.getEl();
3886 var id = el.id || el.tagName;
3887 return ("Scroll " + id);
3890 proto.doMethod = function(attr, start, end) {
3893 if (attr == 'scroll') {
3895 this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
3896 this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
3900 val = superclass.doMethod.call(this, attr, start, end);
3905 proto.getAttribute = function(attr) {
3907 var el = this.getEl();
3909 if (attr == 'scroll') {
3910 val = [ el.scrollLeft, el.scrollTop ];
3912 val = superclass.getAttribute.call(this, attr);
3918 proto.setAttribute = function(attr, val, unit) {
3919 var el = this.getEl();
3921 if (attr == 'scroll') {
3922 el.scrollLeft = val[0];
3923 el.scrollTop = val[1];
3925 superclass.setAttribute.call(this, attr, val, unit);
3931 * Ext JS Library 1.1.1
3932 * Copyright(c) 2006-2007, Ext JS, LLC.
3934 * Originally Released Under LGPL - original licence link has changed is not relivant.
3937 * <script type="text/javascript">
3942 * @class Roo.DomHelper
3943 * Utility class for working with DOM and/or Templates. It transparently supports using HTML fragments or DOM.
3944 * For more information see <a href="http://www.jackslocum.com/yui/2006/10/06/domhelper-create-elements-using-dom-html-fragments-or-templates/">this blog post with examples</a>.
3947 Roo.DomHelper = function(){
3948 var tempTableEl = null;
3949 var emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i;
3950 var tableRe = /^table|tbody|tr|td$/i;
3952 // build as innerHTML where available
3954 var createHtml = function(o){
3955 if(typeof o == 'string'){
3964 if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || typeof o[attr] == "function") continue;
3965 if(attr == "style"){
3967 if(typeof s == "function"){
3970 if(typeof s == "string"){
3971 b += ' style="' + s + '"';
3972 }else if(typeof s == "object"){
3975 if(typeof s[key] != "function"){
3976 b += key + ":" + s[key] + ";";
3983 b += ' class="' + o["cls"] + '"';
3984 }else if(attr == "htmlFor"){
3985 b += ' for="' + o["htmlFor"] + '"';
3987 b += " " + attr + '="' + o[attr] + '"';
3991 if(emptyTags.test(o.tag)){
3995 var cn = o.children || o.cn;
3997 //http://bugs.kde.org/show_bug.cgi?id=71506
3998 if((cn instanceof Array) || (Roo.isSafari && typeof(cn.join) == "function")){
3999 for(var i = 0, len = cn.length; i < len; i++) {
4000 b += createHtml(cn[i], b);
4003 b += createHtml(cn, b);
4009 b += "</" + o.tag + ">";
4016 var createDom = function(o, parentNode){
4018 // defininition craeted..
4020 if (o.ns && o.ns != 'html') {
4022 if (o.xmlns && typeof(xmlns[o.ns]) == 'undefined') {
4023 xmlns[o.ns] = o.xmlns;
4026 if (typeof(xmlns[o.ns]) == 'undefined') {
4027 console.log("Trying to create namespace element " + o.ns + ", however no xmlns was sent to builder previously");
4033 if (typeof(o) == 'string') {
4034 return parentNode.appendChild(document.createTextNode(o));
4036 o.tag = o.tag || div;
4037 if (o.ns && Roo.isIE) {
4039 o.tag = o.ns + ':' + o.tag;
4042 var el = ns ? document.createElementNS( ns, o.tag||'div') : document.createElement(o.tag||'div');
4043 var useSet = el.setAttribute ? true : false; // In IE some elements don't have setAttribute
4046 if(attr == "tag" || attr == "ns" ||attr == "xmlns" ||attr == "children" || attr == "cn" || attr == "html" ||
4047 attr == "style" || typeof o[attr] == "function") continue;
4049 if(attr=="cls" && Roo.isIE){
4050 el.className = o["cls"];
4052 if(useSet) el.setAttribute(attr=="cls" ? 'class' : attr, o[attr]);
4053 else el[attr] = o[attr];
4056 Roo.DomHelper.applyStyles(el, o.style);
4057 var cn = o.children || o.cn;
4059 //http://bugs.kde.org/show_bug.cgi?id=71506
4060 if((cn instanceof Array) || (Roo.isSafari && typeof(cn.join) == "function")){
4061 for(var i = 0, len = cn.length; i < len; i++) {
4062 createDom(cn[i], el);
4069 el.innerHTML = o.html;
4072 parentNode.appendChild(el);
4077 var ieTable = function(depth, s, h, e){
4078 tempTableEl.innerHTML = [s, h, e].join('');
4079 var i = -1, el = tempTableEl;
4086 // kill repeat to save bytes
4090 tbe = '</tbody>'+te,
4096 * Nasty code for IE's broken table implementation
4098 var insertIntoTable = function(tag, where, el, html){
4100 tempTableEl = document.createElement('div');
4105 if(where == 'afterbegin' || where == 'beforeend'){ // INTO a TD
4108 if(where == 'beforebegin'){
4112 before = el.nextSibling;
4115 node = ieTable(4, trs, html, tre);
4117 else if(tag == 'tr'){
4118 if(where == 'beforebegin'){
4121 node = ieTable(3, tbs, html, tbe);
4122 } else if(where == 'afterend'){
4123 before = el.nextSibling;
4125 node = ieTable(3, tbs, html, tbe);
4126 } else{ // INTO a TR
4127 if(where == 'afterbegin'){
4128 before = el.firstChild;
4130 node = ieTable(4, trs, html, tre);
4132 } else if(tag == 'tbody'){
4133 if(where == 'beforebegin'){
4136 node = ieTable(2, ts, html, te);
4137 } else if(where == 'afterend'){
4138 before = el.nextSibling;
4140 node = ieTable(2, ts, html, te);
4142 if(where == 'afterbegin'){
4143 before = el.firstChild;
4145 node = ieTable(3, tbs, html, tbe);
4148 if(where == 'beforebegin' || where == 'afterend'){ // OUTSIDE the table
4151 if(where == 'afterbegin'){
4152 before = el.firstChild;
4154 node = ieTable(2, ts, html, te);
4156 el.insertBefore(node, before);
4161 /** True to force the use of DOM instead of html fragments @type Boolean */
4165 * Returns the markup for the passed Element(s) config
4166 * @param {Object} o The Dom object spec (and children)
4169 markup : function(o){
4170 return createHtml(o);
4174 * Applies a style specification to an element
4175 * @param {String/HTMLElement} el The element to apply styles to
4176 * @param {String/Object/Function} styles A style specification string eg "width:100px", or object in the form {width:"100px"}, or
4177 * a function which returns such a specification.
4179 applyStyles : function(el, styles){
4182 if(typeof styles == "string"){
4183 var re = /\s?([a-z\-]*)\:\s?([^;]*);?/gi;
4185 while ((matches = re.exec(styles)) != null){
4186 el.setStyle(matches[1], matches[2]);
4188 }else if (typeof styles == "object"){
4189 for (var style in styles){
4190 el.setStyle(style, styles[style]);
4192 }else if (typeof styles == "function"){
4193 Roo.DomHelper.applyStyles(el, styles.call());
4199 * Inserts an HTML fragment into the Dom
4200 * @param {String} where Where to insert the html in relation to el - beforeBegin, afterBegin, beforeEnd, afterEnd.
4201 * @param {HTMLElement} el The context element
4202 * @param {String} html The HTML fragmenet
4203 * @return {HTMLElement} The new node
4205 insertHtml : function(where, el, html){
4206 where = where.toLowerCase();
4207 if(el.insertAdjacentHTML){
4208 if(tableRe.test(el.tagName)){
4210 if(rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html)){
4216 el.insertAdjacentHTML('BeforeBegin', html);
4217 return el.previousSibling;
4219 el.insertAdjacentHTML('AfterBegin', html);
4220 return el.firstChild;
4222 el.insertAdjacentHTML('BeforeEnd', html);
4223 return el.lastChild;
4225 el.insertAdjacentHTML('AfterEnd', html);
4226 return el.nextSibling;
4228 throw 'Illegal insertion point -> "' + where + '"';
4230 var range = el.ownerDocument.createRange();
4234 range.setStartBefore(el);
4235 frag = range.createContextualFragment(html);
4236 el.parentNode.insertBefore(frag, el);
4237 return el.previousSibling;
4240 range.setStartBefore(el.firstChild);
4241 frag = range.createContextualFragment(html);
4242 el.insertBefore(frag, el.firstChild);
4243 return el.firstChild;
4245 el.innerHTML = html;
4246 return el.firstChild;
4250 range.setStartAfter(el.lastChild);
4251 frag = range.createContextualFragment(html);
4252 el.appendChild(frag);
4253 return el.lastChild;
4255 el.innerHTML = html;
4256 return el.lastChild;
4259 range.setStartAfter(el);
4260 frag = range.createContextualFragment(html);
4261 el.parentNode.insertBefore(frag, el.nextSibling);
4262 return el.nextSibling;
4264 throw 'Illegal insertion point -> "' + where + '"';
4268 * Creates new Dom element(s) and inserts them before el
4269 * @param {String/HTMLElement/Element} el The context element
4270 * @param {Object/String} o The Dom object spec (and children) or raw HTML blob
4271 * @param {Boolean} returnElement (optional) true to return a Roo.Element
4272 * @return {HTMLElement/Roo.Element} The new node
4274 insertBefore : function(el, o, returnElement){
4275 return this.doInsert(el, o, returnElement, "beforeBegin");
4279 * Creates new Dom element(s) and inserts them after el
4280 * @param {String/HTMLElement/Element} el The context element
4281 * @param {Object} o The Dom object spec (and children)
4282 * @param {Boolean} returnElement (optional) true to return a Roo.Element
4283 * @return {HTMLElement/Roo.Element} The new node
4285 insertAfter : function(el, o, returnElement){
4286 return this.doInsert(el, o, returnElement, "afterEnd", "nextSibling");
4290 * Creates new Dom element(s) and inserts them as the first child of el
4291 * @param {String/HTMLElement/Element} el The context element
4292 * @param {Object/String} o The Dom object spec (and children) or raw HTML blob
4293 * @param {Boolean} returnElement (optional) true to return a Roo.Element
4294 * @return {HTMLElement/Roo.Element} The new node
4296 insertFirst : function(el, o, returnElement){
4297 return this.doInsert(el, o, returnElement, "afterBegin");
4301 doInsert : function(el, o, returnElement, pos, sibling){
4302 el = Roo.getDom(el);
4304 if(this.useDom || o.ns){
4305 newNode = createDom(o, null);
4306 el.parentNode.insertBefore(newNode, sibling ? el[sibling] : el);
4308 var html = createHtml(o);
4309 newNode = this.insertHtml(pos, el, html);
4311 return returnElement ? Roo.get(newNode, true) : newNode;
4315 * Creates new Dom element(s) and appends them to el
4316 * @param {String/HTMLElement/Element} el The context element
4317 * @param {Object/String} o The Dom object spec (and children) or raw HTML blob
4318 * @param {Boolean} returnElement (optional) true to return a Roo.Element
4319 * @return {HTMLElement/Roo.Element} The new node
4321 append : function(el, o, returnElement){
4322 el = Roo.getDom(el);
4324 if(this.useDom || o.ns){
4325 newNode = createDom(o, null);
4326 el.appendChild(newNode);
4328 var html = createHtml(o);
4329 newNode = this.insertHtml("beforeEnd", el, html);
4331 return returnElement ? Roo.get(newNode, true) : newNode;
4335 * Creates new Dom element(s) and overwrites the contents of el with them
4336 * @param {String/HTMLElement/Element} el The context element
4337 * @param {Object/String} o The Dom object spec (and children) or raw HTML blob
4338 * @param {Boolean} returnElement (optional) true to return a Roo.Element
4339 * @return {HTMLElement/Roo.Element} The new node
4341 overwrite : function(el, o, returnElement){
4342 el = Roo.getDom(el);
4345 while (el.childNodes.length) {
4346 el.removeChild(el.firstChild);
4350 el.innerHTML = createHtml(o);
4353 return returnElement ? Roo.get(el.firstChild, true) : el.firstChild;
4357 * Creates a new Roo.DomHelper.Template from the Dom object spec
4358 * @param {Object} o The Dom object spec (and children)
4359 * @return {Roo.DomHelper.Template} The new template
4361 createTemplate : function(o){
4362 var html = createHtml(o);
4363 return new Roo.Template(html);
4369 * Ext JS Library 1.1.1
4370 * Copyright(c) 2006-2007, Ext JS, LLC.
4372 * Originally Released Under LGPL - original licence link has changed is not relivant.
4375 * <script type="text/javascript">
4379 * @class Roo.Template
4380 * Represents an HTML fragment template. Templates can be precompiled for greater performance.
4381 * For a list of available format functions, see {@link Roo.util.Format}.<br />
4384 var t = new Roo.Template(
4385 '<div name="{id}">',
4386 '<span class="{cls}">{name:trim} {value:ellipsis(10)}</span>',
4389 t.append('some-element', {id: 'myid', cls: 'myclass', name: 'foo', value: 'bar'});
4391 * For more information see this blog post with examples: <a href="http://www.jackslocum.com/yui/2006/10/06/domhelper-create-elements-using-dom-html-fragments-or-templates/">DomHelper - Create Elements using DOM, HTML fragments and Templates</a>.
4393 * @param {String/Array} html The HTML fragment or an array of fragments to join("") or multiple arguments to join("")
4395 Roo.Template = function(html){
4396 if(html instanceof Array){
4397 html = html.join("");
4398 }else if(arguments.length > 1){
4399 html = Array.prototype.join.call(arguments, "");
4405 Roo.Template.prototype = {
4407 * Returns an HTML fragment of this template with the specified values applied.
4408 * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
4409 * @return {String} The HTML fragment
4411 applyTemplate : function(values){
4413 return this.compiled(values);
4415 var useF = this.disableFormats !== true;
4416 var fm = Roo.util.Format, tpl = this;
4417 var fn = function(m, name, format, args){
4419 if(format.substr(0, 5) == "this."){
4420 return tpl.call(format.substr(5), values[name], values);
4423 // quoted values are required for strings in compiled templates,
4424 // but for non compiled we need to strip them
4425 // quoted reversed for jsmin
4426 var re = /^\s*['"](.*)["']\s*$/;
4427 args = args.split(',');
4428 for(var i = 0, len = args.length; i < len; i++){
4429 args[i] = args[i].replace(re, "$1");
4431 args = [values[name]].concat(args);
4433 args = [values[name]];
4435 return fm[format].apply(fm, args);
4438 return values[name] !== undefined ? values[name] : "";
4441 return this.html.replace(this.re, fn);
4445 * Sets the HTML used as the template and optionally compiles it.
4446 * @param {String} html
4447 * @param {Boolean} compile (optional) True to compile the template (defaults to undefined)
4448 * @return {Roo.Template} this
4450 set : function(html, compile){
4452 this.compiled = null;
4460 * True to disable format functions (defaults to false)
4463 disableFormats : false,
4466 * The regular expression used to match template variables
4470 re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
4473 * Compiles the template into an internal function, eliminating the RegEx overhead.
4474 * @return {Roo.Template} this
4476 compile : function(){
4477 var fm = Roo.util.Format;
4478 var useF = this.disableFormats !== true;
4479 var sep = Roo.isGecko ? "+" : ",";
4480 var fn = function(m, name, format, args){
4482 args = args ? ',' + args : "";
4483 if(format.substr(0, 5) != "this."){
4484 format = "fm." + format + '(';
4486 format = 'this.call("'+ format.substr(5) + '", ';
4490 args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
4492 return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
4495 // branched to use + in gecko and [].join() in others
4497 body = "this.compiled = function(values){ return '" +
4498 this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
4501 body = ["this.compiled = function(values){ return ['"];
4502 body.push(this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn));
4503 body.push("'].join('');};");
4504 body = body.join('');
4514 // private function used to call members
4515 call : function(fnName, value, allValues){
4516 return this[fnName](value, allValues);
4520 * Applies the supplied values to the template and inserts the new node(s) as the first child of el.
4521 * @param {String/HTMLElement/Roo.Element} el The context element
4522 * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
4523 * @param {Boolean} returnElement (optional) true to return a Roo.Element (defaults to undefined)
4524 * @return {HTMLElement/Roo.Element} The new node or Element
4526 insertFirst: function(el, values, returnElement){
4527 return this.doInsert('afterBegin', el, values, returnElement);
4531 * Applies the supplied values to the template and inserts the new node(s) before el.
4532 * @param {String/HTMLElement/Roo.Element} el The context element
4533 * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
4534 * @param {Boolean} returnElement (optional) true to return a Roo.Element (defaults to undefined)
4535 * @return {HTMLElement/Roo.Element} The new node or Element
4537 insertBefore: function(el, values, returnElement){
4538 return this.doInsert('beforeBegin', el, values, returnElement);
4542 * Applies the supplied values to the template and inserts the new node(s) after el.
4543 * @param {String/HTMLElement/Roo.Element} el The context element
4544 * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
4545 * @param {Boolean} returnElement (optional) true to return a Roo.Element (defaults to undefined)
4546 * @return {HTMLElement/Roo.Element} The new node or Element
4548 insertAfter : function(el, values, returnElement){
4549 return this.doInsert('afterEnd', el, values, returnElement);
4553 * Applies the supplied values to the template and appends the new node(s) to el.
4554 * @param {String/HTMLElement/Roo.Element} el The context element
4555 * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
4556 * @param {Boolean} returnElement (optional) true to return a Roo.Element (defaults to undefined)
4557 * @return {HTMLElement/Roo.Element} The new node or Element
4559 append : function(el, values, returnElement){
4560 return this.doInsert('beforeEnd', el, values, returnElement);
4563 doInsert : function(where, el, values, returnEl){
4564 el = Roo.getDom(el);
4565 var newNode = Roo.DomHelper.insertHtml(where, el, this.applyTemplate(values));
4566 return returnEl ? Roo.get(newNode, true) : newNode;
4570 * Applies the supplied values to the template and overwrites the content of el with the new node(s).
4571 * @param {String/HTMLElement/Roo.Element} el The context element
4572 * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
4573 * @param {Boolean} returnElement (optional) true to return a Roo.Element (defaults to undefined)
4574 * @return {HTMLElement/Roo.Element} The new node or Element
4576 overwrite : function(el, values, returnElement){
4577 el = Roo.getDom(el);
4578 el.innerHTML = this.applyTemplate(values);
4579 return returnElement ? Roo.get(el.firstChild, true) : el.firstChild;
4583 * Alias for {@link #applyTemplate}
4586 Roo.Template.prototype.apply = Roo.Template.prototype.applyTemplate;
4589 Roo.DomHelper.Template = Roo.Template;
4592 * Creates a template from the passed element's value (<i>display:none</i> textarea, preferred) or innerHTML.
4593 * @param {String/HTMLElement} el A DOM element or its id
4594 * @returns {Roo.Template} The created template
4597 Roo.Template.from = function(el){
4598 el = Roo.getDom(el);
4599 return new Roo.Template(el.value || el.innerHTML);
4602 * Ext JS Library 1.1.1
4603 * Copyright(c) 2006-2007, Ext JS, LLC.
4605 * Originally Released Under LGPL - original licence link has changed is not relivant.
4608 * <script type="text/javascript">
4613 * This is code is also distributed under MIT license for use
4614 * with jQuery and prototype JavaScript libraries.
4617 * @class Roo.DomQuery
4618 Provides high performance selector/xpath processing by compiling queries into reusable functions. New pseudo classes and matchers can be plugged. It works on HTML and XML documents (if a content node is passed in).
4620 DomQuery supports most of the <a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215/">CSS3 selectors spec</a>, along with some custom selectors and basic XPath.</p>
4623 All selectors, attribute filters and pseudos below can be combined infinitely in any order. For example "div.foo:nth-child(odd)[@foo=bar].bar:first" would be a perfectly valid selector. Node filters are processed in the order in which they appear, which allows you to optimize your queries for your document structure.
4625 <h4>Element Selectors:</h4>
4627 <li> <b>*</b> any element</li>
4628 <li> <b>E</b> an element with the tag E</li>
4629 <li> <b>E F</b> All descendent elements of E that have the tag F</li>
4630 <li> <b>E > F</b> or <b>E/F</b> all direct children elements of E that have the tag F</li>
4631 <li> <b>E + F</b> all elements with the tag F that are immediately preceded by an element with the tag E</li>
4632 <li> <b>E ~ F</b> all elements with the tag F that are preceded by a sibling element with the tag E</li>
4634 <h4>Attribute Selectors:</h4>
4635 <p>The use of @ and quotes are optional. For example, div[@foo='bar'] is also a valid attribute selector.</p>
4637 <li> <b>E[foo]</b> has an attribute "foo"</li>
4638 <li> <b>E[foo=bar]</b> has an attribute "foo" that equals "bar"</li>
4639 <li> <b>E[foo^=bar]</b> has an attribute "foo" that starts with "bar"</li>
4640 <li> <b>E[foo$=bar]</b> has an attribute "foo" that ends with "bar"</li>
4641 <li> <b>E[foo*=bar]</b> has an attribute "foo" that contains the substring "bar"</li>
4642 <li> <b>E[foo%=2]</b> has an attribute "foo" that is evenly divisible by 2</li>
4643 <li> <b>E[foo!=bar]</b> has an attribute "foo" that does not equal "bar"</li>
4645 <h4>Pseudo Classes:</h4>
4647 <li> <b>E:first-child</b> E is the first child of its parent</li>
4648 <li> <b>E:last-child</b> E is the last child of its parent</li>
4649 <li> <b>E:nth-child(<i>n</i>)</b> E is the <i>n</i>th child of its parent (1 based as per the spec)</li>
4650 <li> <b>E:nth-child(odd)</b> E is an odd child of its parent</li>
4651 <li> <b>E:nth-child(even)</b> E is an even child of its parent</li>
4652 <li> <b>E:only-child</b> E is the only child of its parent</li>
4653 <li> <b>E:checked</b> E is an element that is has a checked attribute that is true (e.g. a radio or checkbox) </li>
4654 <li> <b>E:first</b> the first E in the resultset</li>
4655 <li> <b>E:last</b> the last E in the resultset</li>
4656 <li> <b>E:nth(<i>n</i>)</b> the <i>n</i>th E in the resultset (1 based)</li>
4657 <li> <b>E:odd</b> shortcut for :nth-child(odd)</li>
4658 <li> <b>E:even</b> shortcut for :nth-child(even)</li>
4659 <li> <b>E:contains(foo)</b> E's innerHTML contains the substring "foo"</li>
4660 <li> <b>E:nodeValue(foo)</b> E contains a textNode with a nodeValue that equals "foo"</li>
4661 <li> <b>E:not(S)</b> an E element that does not match simple selector S</li>
4662 <li> <b>E:has(S)</b> an E element that has a descendent that matches simple selector S</li>
4663 <li> <b>E:next(S)</b> an E element whose next sibling matches simple selector S</li>
4664 <li> <b>E:prev(S)</b> an E element whose previous sibling matches simple selector S</li>
4666 <h4>CSS Value Selectors:</h4>
4668 <li> <b>E{display=none}</b> css value "display" that equals "none"</li>
4669 <li> <b>E{display^=none}</b> css value "display" that starts with "none"</li>
4670 <li> <b>E{display$=none}</b> css value "display" that ends with "none"</li>
4671 <li> <b>E{display*=none}</b> css value "display" that contains the substring "none"</li>
4672 <li> <b>E{display%=2}</b> css value "display" that is evenly divisible by 2</li>
4673 <li> <b>E{display!=none}</b> css value "display" that does not equal "none"</li>
4677 Roo.DomQuery = function(){
4678 var cache = {}, simpleCache = {}, valueCache = {};
4679 var nonSpace = /\S/;
4680 var trimRe = /^\s+|\s+$/g;
4681 var tplRe = /\{(\d+)\}/g;
4682 var modeRe = /^(\s?[\/>+~]\s?|\s|$)/;
4683 var tagTokenRe = /^(#)?([\w-\*]+)/;
4684 var nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/;
4686 function child(p, index){
4688 var n = p.firstChild;
4690 if(n.nodeType == 1){
4701 while((n = n.nextSibling) && n.nodeType != 1);
4706 while((n = n.previousSibling) && n.nodeType != 1);
4710 function children(d){
4711 var n = d.firstChild, ni = -1;
4713 var nx = n.nextSibling;
4714 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
4724 function byClassName(c, a, v){
4728 var r = [], ri = -1, cn;
4729 for(var i = 0, ci; ci = c[i]; i++){
4730 if((' '+ci.className+' ').indexOf(v) != -1){
4737 function attrValue(n, attr){
4738 if(!n.tagName && typeof n.length != "undefined"){
4747 if(attr == "class" || attr == "className"){
4750 return n.getAttribute(attr) || n[attr];
4754 function getNodes(ns, mode, tagName){
4755 var result = [], ri = -1, cs;
4759 tagName = tagName || "*";
4760 if(typeof ns.getElementsByTagName != "undefined"){
4764 for(var i = 0, ni; ni = ns[i]; i++){
4765 cs = ni.getElementsByTagName(tagName);
4766 for(var j = 0, ci; ci = cs[j]; j++){
4770 }else if(mode == "/" || mode == ">"){
4771 var utag = tagName.toUpperCase();
4772 for(var i = 0, ni, cn; ni = ns[i]; i++){
4773 cn = ni.children || ni.childNodes;
4774 for(var j = 0, cj; cj = cn[j]; j++){
4775 if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
4780 }else if(mode == "+"){
4781 var utag = tagName.toUpperCase();
4782 for(var i = 0, n; n = ns[i]; i++){
4783 while((n = n.nextSibling) && n.nodeType != 1);
4784 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
4788 }else if(mode == "~"){
4789 for(var i = 0, n; n = ns[i]; i++){
4790 while((n = n.nextSibling) && (n.nodeType != 1 || (tagName == '*' || n.tagName.toLowerCase()!=tagName)));
4799 function concat(a, b){
4803 for(var i = 0, l = b.length; i < l; i++){
4809 function byTag(cs, tagName){
4810 if(cs.tagName || cs == document){
4816 var r = [], ri = -1;
4817 tagName = tagName.toLowerCase();
4818 for(var i = 0, ci; ci = cs[i]; i++){
4819 if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
4826 function byId(cs, attr, id){
4827 if(cs.tagName || cs == document){
4833 var r = [], ri = -1;
4834 for(var i = 0,ci; ci = cs[i]; i++){
4835 if(ci && ci.id == id){
4843 function byAttribute(cs, attr, value, op, custom){
4844 var r = [], ri = -1, st = custom=="{";
4845 var f = Roo.DomQuery.operators[op];
4846 for(var i = 0, ci; ci = cs[i]; i++){
4849 a = Roo.DomQuery.getStyle(ci, attr);
4851 else if(attr == "class" || attr == "className"){
4853 }else if(attr == "for"){
4855 }else if(attr == "href"){
4856 a = ci.getAttribute("href", 2);
4858 a = ci.getAttribute(attr);
4860 if((f && f(a, value)) || (!f && a)){
4867 function byPseudo(cs, name, value){
4868 return Roo.DomQuery.pseudos[name](cs, value);
4871 // This is for IE MSXML which does not support expandos.
4872 // IE runs the same speed using setAttribute, however FF slows way down
4873 // and Safari completely fails so they need to continue to use expandos.
4874 var isIE = window.ActiveXObject ? true : false;
4876 // this eval is stop the compressor from
4877 // renaming the variable to something shorter
4879 /** eval:var:batch */
4884 function nodupIEXml(cs){
4886 cs[0].setAttribute("_nodup", d);
4888 for(var i = 1, len = cs.length; i < len; i++){
4890 if(!c.getAttribute("_nodup") != d){
4891 c.setAttribute("_nodup", d);
4895 for(var i = 0, len = cs.length; i < len; i++){
4896 cs[i].removeAttribute("_nodup");
4905 var len = cs.length, c, i, r = cs, cj, ri = -1;
4906 if(!len || typeof cs.nodeType != "undefined" || len == 1){
4909 if(isIE && typeof cs[0].selectSingleNode != "undefined"){
4910 return nodupIEXml(cs);
4914 for(i = 1; c = cs[i]; i++){
4919 for(var j = 0; j < i; j++){
4922 for(j = i+1; cj = cs[j]; j++){
4934 function quickDiffIEXml(c1, c2){
4936 for(var i = 0, len = c1.length; i < len; i++){
4937 c1[i].setAttribute("_qdiff", d);
4940 for(var i = 0, len = c2.length; i < len; i++){
4941 if(c2[i].getAttribute("_qdiff") != d){
4942 r[r.length] = c2[i];
4945 for(var i = 0, len = c1.length; i < len; i++){
4946 c1[i].removeAttribute("_qdiff");
4951 function quickDiff(c1, c2){
4952 var len1 = c1.length;
4956 if(isIE && c1[0].selectSingleNode){
4957 return quickDiffIEXml(c1, c2);
4960 for(var i = 0; i < len1; i++){
4964 for(var i = 0, len = c2.length; i < len; i++){
4965 if(c2[i]._qdiff != d){
4966 r[r.length] = c2[i];
4972 function quickId(ns, mode, root, id){
4974 var d = root.ownerDocument || root;
4975 return d.getElementById(id);
4977 ns = getNodes(ns, mode, "*");
4978 return byId(ns, null, id);
4982 getStyle : function(el, name){
4983 return Roo.fly(el).getStyle(name);
4986 * Compiles a selector/xpath query into a reusable function. The returned function
4987 * takes one parameter "root" (optional), which is the context node from where the query should start.
4988 * @param {String} selector The selector/xpath query
4989 * @param {String} type (optional) Either "select" (the default) or "simple" for a simple selector match
4990 * @return {Function}
4992 compile : function(path, type){
4993 type = type || "select";
4995 var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"];
4996 var q = path, mode, lq;
4997 var tk = Roo.DomQuery.matchers;
4998 var tklen = tk.length;
5001 // accept leading mode switch
5002 var lmode = q.match(modeRe);
5003 if(lmode && lmode[1]){
5004 fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
5005 q = q.replace(lmode[1], "");
5007 // strip leading slashes
5008 while(path.substr(0, 1)=="/"){
5009 path = path.substr(1);
5012 while(q && lq != q){
5014 var tm = q.match(tagTokenRe);
5015 if(type == "select"){
5018 fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");';
5020 fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");';
5022 q = q.replace(tm[0], "");
5023 }else if(q.substr(0, 1) != '@'){
5024 fn[fn.length] = 'n = getNodes(n, mode, "*");';
5029 fn[fn.length] = 'n = byId(n, null, "'+tm[2]+'");';
5031 fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");';
5033 q = q.replace(tm[0], "");
5036 while(!(mm = q.match(modeRe))){
5037 var matched = false;
5038 for(var j = 0; j < tklen; j++){
5040 var m = q.match(t.re);
5042 fn[fn.length] = t.select.replace(tplRe, function(x, i){
5045 q = q.replace(m[0], "");
5050 // prevent infinite loop on bad selector
5052 throw 'Error parsing selector, parsing failed at "' + q + '"';
5056 fn[fn.length] = 'mode="'+mm[1].replace(trimRe, "")+'";';
5057 q = q.replace(mm[1], "");
5060 fn[fn.length] = "return nodup(n);\n}";
5063 * list of variables that need from compression as they are used by eval.
5073 * eval:var:byClassName
5075 * eval:var:byAttribute
5076 * eval:var:attrValue
5084 * Selects a group of elements.
5085 * @param {String} selector The selector/xpath query (can be a comma separated list of selectors)
5086 * @param {Node} root (optional) The start of the query (defaults to document).
5089 select : function(path, root, type){
5090 if(!root || root == document){
5093 if(typeof root == "string"){
5094 root = document.getElementById(root);
5096 var paths = path.split(",");
5098 for(var i = 0, len = paths.length; i < len; i++){
5099 var p = paths[i].replace(trimRe, "");
5101 cache[p] = Roo.DomQuery.compile(p);
5103 throw p + " is not a valid selector";
5106 var result = cache[p](root);
5107 if(result && result != document){
5108 results = results.concat(result);
5111 if(paths.length > 1){
5112 return nodup(results);
5118 * Selects a single element.
5119 * @param {String} selector The selector/xpath query
5120 * @param {Node} root (optional) The start of the query (defaults to document).
5123 selectNode : function(path, root){
5124 return Roo.DomQuery.select(path, root)[0];
5128 * Selects the value of a node, optionally replacing null with the defaultValue.
5129 * @param {String} selector The selector/xpath query
5130 * @param {Node} root (optional) The start of the query (defaults to document).
5131 * @param {String} defaultValue
5133 selectValue : function(path, root, defaultValue){
5134 path = path.replace(trimRe, "");
5135 if(!valueCache[path]){
5136 valueCache[path] = Roo.DomQuery.compile(path, "select");
5138 var n = valueCache[path](root);
5139 n = n[0] ? n[0] : n;
5140 var v = (n && n.firstChild ? n.firstChild.nodeValue : null);
5141 return ((v === null||v === undefined||v==='') ? defaultValue : v);
5145 * Selects the value of a node, parsing integers and floats.
5146 * @param {String} selector The selector/xpath query
5147 * @param {Node} root (optional) The start of the query (defaults to document).
5148 * @param {Number} defaultValue
5151 selectNumber : function(path, root, defaultValue){
5152 var v = Roo.DomQuery.selectValue(path, root, defaultValue || 0);
5153 return parseFloat(v);
5157 * Returns true if the passed element(s) match the passed simple selector (e.g. div.some-class or span:first-child)
5158 * @param {String/HTMLElement/Array} el An element id, element or array of elements
5159 * @param {String} selector The simple selector to test
5162 is : function(el, ss){
5163 if(typeof el == "string"){
5164 el = document.getElementById(el);
5166 var isArray = (el instanceof Array);
5167 var result = Roo.DomQuery.filter(isArray ? el : [el], ss);
5168 return isArray ? (result.length == el.length) : (result.length > 0);
5172 * Filters an array of elements to only include matches of a simple selector (e.g. div.some-class or span:first-child)
5173 * @param {Array} el An array of elements to filter
5174 * @param {String} selector The simple selector to test
5175 * @param {Boolean} nonMatches If true, it returns the elements that DON'T match
5176 * the selector instead of the ones that match
5179 filter : function(els, ss, nonMatches){
5180 ss = ss.replace(trimRe, "");
5181 if(!simpleCache[ss]){
5182 simpleCache[ss] = Roo.DomQuery.compile(ss, "simple");
5184 var result = simpleCache[ss](els);
5185 return nonMatches ? quickDiff(result, els) : result;
5189 * Collection of matching regular expressions and code snippets.
5193 select: 'n = byClassName(n, null, " {1} ");'
5195 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
5196 select: 'n = byPseudo(n, "{1}", "{2}");'
5198 re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
5199 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
5202 select: 'n = byId(n, null, "{1}");'
5205 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
5210 * Collection of operator comparison functions. The default operators are =, !=, ^=, $=, *=, %=, |= and ~=.
5211 * New operators can be added as long as the match the format <i>c</i>= where <i>c</i> is any character other than space, > <.
5214 "=" : function(a, v){
5217 "!=" : function(a, v){
5220 "^=" : function(a, v){
5221 return a && a.substr(0, v.length) == v;
5223 "$=" : function(a, v){
5224 return a && a.substr(a.length-v.length) == v;
5226 "*=" : function(a, v){
5227 return a && a.indexOf(v) !== -1;
5229 "%=" : function(a, v){
5230 return (a % v) == 0;
5232 "|=" : function(a, v){
5233 return a && (a == v || a.substr(0, v.length+1) == v+'-');
5235 "~=" : function(a, v){
5236 return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
5241 * Collection of "pseudo class" processors. Each processor is passed the current nodeset (array)
5242 * and the argument (if any) supplied in the selector.
5245 "first-child" : function(c){
5246 var r = [], ri = -1, n;
5247 for(var i = 0, ci; ci = n = c[i]; i++){
5248 while((n = n.previousSibling) && n.nodeType != 1);
5256 "last-child" : function(c){
5257 var r = [], ri = -1, n;
5258 for(var i = 0, ci; ci = n = c[i]; i++){
5259 while((n = n.nextSibling) && n.nodeType != 1);
5267 "nth-child" : function(c, a) {
5268 var r = [], ri = -1;
5269 var m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a);
5270 var f = (m[1] || 1) - 0, l = m[2] - 0;
5271 for(var i = 0, n; n = c[i]; i++){
5272 var pn = n.parentNode;
5273 if (batch != pn._batch) {
5275 for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
5276 if(cn.nodeType == 1){
5283 if (l == 0 || n.nodeIndex == l){
5286 } else if ((n.nodeIndex + l) % f == 0){
5294 "only-child" : function(c){
5295 var r = [], ri = -1;;
5296 for(var i = 0, ci; ci = c[i]; i++){
5297 if(!prev(ci) && !next(ci)){
5304 "empty" : function(c){
5305 var r = [], ri = -1;
5306 for(var i = 0, ci; ci = c[i]; i++){
5307 var cns = ci.childNodes, j = 0, cn, empty = true;
5310 if(cn.nodeType == 1 || cn.nodeType == 3){
5322 "contains" : function(c, v){
5323 var r = [], ri = -1;
5324 for(var i = 0, ci; ci = c[i]; i++){
5325 if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
5332 "nodeValue" : function(c, v){
5333 var r = [], ri = -1;
5334 for(var i = 0, ci; ci = c[i]; i++){
5335 if(ci.firstChild && ci.firstChild.nodeValue == v){
5342 "checked" : function(c){
5343 var r = [], ri = -1;
5344 for(var i = 0, ci; ci = c[i]; i++){
5345 if(ci.checked == true){
5352 "not" : function(c, ss){
5353 return Roo.DomQuery.filter(c, ss, true);
5356 "odd" : function(c){
5357 return this["nth-child"](c, "odd");
5360 "even" : function(c){
5361 return this["nth-child"](c, "even");
5364 "nth" : function(c, a){
5365 return c[a-1] || [];
5368 "first" : function(c){
5372 "last" : function(c){
5373 return c[c.length-1] || [];
5376 "has" : function(c, ss){
5377 var s = Roo.DomQuery.select;
5378 var r = [], ri = -1;
5379 for(var i = 0, ci; ci = c[i]; i++){
5380 if(s(ss, ci).length > 0){
5387 "next" : function(c, ss){
5388 var is = Roo.DomQuery.is;
5389 var r = [], ri = -1;
5390 for(var i = 0, ci; ci = c[i]; i++){
5399 "prev" : function(c, ss){
5400 var is = Roo.DomQuery.is;
5401 var r = [], ri = -1;
5402 for(var i = 0, ci; ci = c[i]; i++){
5415 * Selects an array of DOM nodes by CSS/XPath selector. Shorthand of {@link Roo.DomQuery#select}
5416 * @param {String} path The selector/xpath query
5417 * @param {Node} root (optional) The start of the query (defaults to document).
5422 Roo.query = Roo.DomQuery.select;