PageRenderTime 56ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/hippo/src/main/webapp/ext/adapter/ext/ext-base-debug.js

http://hdbc.googlecode.com/
JavaScript | 1806 lines | 759 code | 112 blank | 935 comment | 190 complexity | d4535f5f0c4e7aa64a2f8fcfcf08eaff MD5 | raw file
  1. /*!
  2. * Ext JS Library 3.0.0
  3. * Copyright(c) 2006-2009 Ext JS, LLC
  4. * licensing@extjs.com
  5. * http://www.extjs.com/license
  6. */
  7. // for old browsers
  8. window.undefined = window.undefined;
  9. /**
  10. * @class Ext
  11. * Ext core utilities and functions.
  12. * @singleton
  13. */
  14. Ext = {
  15. /**
  16. * The version of the framework
  17. * @type String
  18. */
  19. version : '3.0'
  20. };
  21. /**
  22. * Copies all the properties of config to obj.
  23. * @param {Object} obj The receiver of the properties
  24. * @param {Object} config The source of the properties
  25. * @param {Object} defaults A different object that will also be applied for default values
  26. * @return {Object} returns obj
  27. * @member Ext apply
  28. */
  29. Ext.apply = function(o, c, defaults){
  30. // no "this" reference for friendly out of scope calls
  31. if(defaults){
  32. Ext.apply(o, defaults);
  33. }
  34. if(o && c && typeof c == 'object'){
  35. for(var p in c){
  36. o[p] = c[p];
  37. }
  38. }
  39. return o;
  40. };
  41. (function(){
  42. var idSeed = 0,
  43. toString = Object.prototype.toString,
  44. //assume it's not null and not an array
  45. isIterable = function(v){
  46. //check for array or arguments
  47. if(Ext.isArray(v) || v.callee){
  48. return true;
  49. }
  50. //check for node list type
  51. if(/NodeList|HTMLCollection/.test(toString.call(v))){
  52. return true;
  53. }
  54. //NodeList has an item and length property
  55. //IXMLDOMNodeList has nextNode method, needs to be checked first.
  56. return ((v.nextNode || v.item) && Ext.isNumber(v.length));
  57. },
  58. ua = navigator.userAgent.toLowerCase(),
  59. check = function(r){
  60. return r.test(ua);
  61. },
  62. DOC = document,
  63. isStrict = DOC.compatMode == "CSS1Compat",
  64. isOpera = check(/opera/),
  65. isChrome = check(/chrome/),
  66. isWebKit = check(/webkit/),
  67. isSafari = !isChrome && check(/safari/),
  68. isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2
  69. isSafari3 = isSafari && check(/version\/3/),
  70. isSafari4 = isSafari && check(/version\/4/),
  71. isIE = !isOpera && check(/msie/),
  72. isIE7 = isIE && check(/msie 7/),
  73. isIE8 = isIE && check(/msie 8/),
  74. isIE6 = isIE && !isIE7 && !isIE8,
  75. isGecko = !isWebKit && check(/gecko/),
  76. isGecko2 = isGecko && check(/rv:1\.8/),
  77. isGecko3 = isGecko && check(/rv:1\.9/),
  78. isBorderBox = isIE && !isStrict,
  79. isWindows = check(/windows|win32/),
  80. isMac = check(/macintosh|mac os x/),
  81. isAir = check(/adobeair/),
  82. isLinux = check(/linux/),
  83. isSecure = /^https/i.test(window.location.protocol);
  84. // remove css image flicker
  85. if(isIE6){
  86. try{
  87. DOC.execCommand("BackgroundImageCache", false, true);
  88. }catch(e){}
  89. }
  90. Ext.apply(Ext, {
  91. /**
  92. * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent
  93. * the IE insecure content warning (defaults to javascript:false).
  94. * @type String
  95. */
  96. SSL_SECURE_URL : 'javascript:false',
  97. /**
  98. * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode
  99. * @type Boolean
  100. */
  101. isStrict : isStrict,
  102. /**
  103. * True if the page is running over SSL
  104. * @type Boolean
  105. */
  106. isSecure : isSecure,
  107. /**
  108. * True when the document is fully initialized and ready for action
  109. * @type Boolean
  110. */
  111. isReady : false,
  112. /**
  113. * True if the {@link Ext.Fx} Class is available
  114. * @type Boolean
  115. * @property enableFx
  116. */
  117. /**
  118. * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)
  119. * @type Boolean
  120. */
  121. enableGarbageCollector : true,
  122. /**
  123. * True to automatically purge event listeners after uncaching an element (defaults to false).
  124. * Note: this only happens if {@link #enableGarbageCollector} is true.
  125. * @type Boolean
  126. */
  127. enableListenerCollection : false,
  128. /**
  129. * Indicates whether to use native browser parsing for JSON methods.
  130. * This option is ignored if the browser does not support native JSON methods.
  131. * <b>Note: Native JSON methods will not work with objects that have functions.
  132. * Also, property names must be quoted, otherwise the data will not parse.</b> (Defaults to false)
  133. * @type Boolean
  134. */
  135. USE_NATIVE_JSON : false,
  136. /**
  137. * Copies all the properties of config to obj if they don't already exist.
  138. * @param {Object} obj The receiver of the properties
  139. * @param {Object} config The source of the properties
  140. * @return {Object} returns obj
  141. */
  142. applyIf : function(o, c){
  143. if(o){
  144. for(var p in c){
  145. if(Ext.isEmpty(o[p])){
  146. o[p] = c[p];
  147. }
  148. }
  149. }
  150. return o;
  151. },
  152. /**
  153. * Generates unique ids. If the element already has an id, it is unchanged
  154. * @param {Mixed} el (optional) The element to generate an id for
  155. * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
  156. * @return {String} The generated Id.
  157. */
  158. id : function(el, prefix){
  159. return (el = Ext.getDom(el) || {}).id = el.id || (prefix || "ext-gen") + (++idSeed);
  160. },
  161. /**
  162. * Extends one class with another class and optionally overrides members with the passed literal. This class
  163. * also adds the function "override()" to the class that can be used to override
  164. * members on an instance.
  165. * * <p>
  166. * This function also supports a 2-argument call in which the subclass's constructor is
  167. * not passed as an argument. In this form, the parameters are as follows:</p><p>
  168. * <div class="mdetail-params"><ul>
  169. * <li><code>superclass</code>
  170. * <div class="sub-desc">The class being extended</div></li>
  171. * <li><code>overrides</code>
  172. * <div class="sub-desc">A literal with members which are copied into the subclass's
  173. * prototype, and are therefore shared among all instances of the new class.<p>
  174. * This may contain a special member named <tt><b>constructor</b></tt>. This is used
  175. * to define the constructor of the new class, and is returned. If this property is
  176. * <i>not</i> specified, a constructor is generated and returned which just calls the
  177. * superclass's constructor passing on its parameters.</p></div></li>
  178. * </ul></div></p><p>
  179. * For example, to create a subclass of the Ext GridPanel:
  180. * <pre><code>
  181. MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
  182. constructor: function(config) {
  183. // Your preprocessing here
  184. MyGridPanel.superclass.constructor.apply(this, arguments);
  185. // Your postprocessing here
  186. },
  187. yourMethod: function() {
  188. // etc.
  189. }
  190. });
  191. </code></pre>
  192. * </p>
  193. * @param {Function} subclass The class inheriting the functionality
  194. * @param {Function} superclass The class being extended
  195. * @param {Object} overrides (optional) A literal with members which are copied into the subclass's
  196. * prototype, and are therefore shared between all instances of the new class.
  197. * @return {Function} The subclass constructor.
  198. * @method extend
  199. */
  200. extend : function(){
  201. // inline overrides
  202. var io = function(o){
  203. for(var m in o){
  204. this[m] = o[m];
  205. }
  206. };
  207. var oc = Object.prototype.constructor;
  208. return function(sb, sp, overrides){
  209. if(Ext.isObject(sp)){
  210. overrides = sp;
  211. sp = sb;
  212. sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
  213. }
  214. var F = function(){},
  215. sbp,
  216. spp = sp.prototype;
  217. F.prototype = spp;
  218. sbp = sb.prototype = new F();
  219. sbp.constructor=sb;
  220. sb.superclass=spp;
  221. if(spp.constructor == oc){
  222. spp.constructor=sp;
  223. }
  224. sb.override = function(o){
  225. Ext.override(sb, o);
  226. };
  227. sbp.superclass = sbp.supr = (function(){
  228. return spp;
  229. });
  230. sbp.override = io;
  231. Ext.override(sb, overrides);
  232. sb.extend = function(o){Ext.extend(sb, o);};
  233. return sb;
  234. };
  235. }(),
  236. /**
  237. * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.
  238. * Usage:<pre><code>
  239. Ext.override(MyClass, {
  240. newMethod1: function(){
  241. // etc.
  242. },
  243. newMethod2: function(foo){
  244. // etc.
  245. }
  246. });
  247. </code></pre>
  248. * @param {Object} origclass The class to override
  249. * @param {Object} overrides The list of functions to add to origClass. This should be specified as an object literal
  250. * containing one or more methods.
  251. * @method override
  252. */
  253. override : function(origclass, overrides){
  254. if(overrides){
  255. var p = origclass.prototype;
  256. Ext.apply(p, overrides);
  257. if(Ext.isIE && overrides.toString != origclass.toString){
  258. p.toString = overrides.toString;
  259. }
  260. }
  261. },
  262. /**
  263. * Creates namespaces to be used for scoping variables and classes so that they are not global.
  264. * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
  265. * <pre><code>
  266. Ext.namespace('Company', 'Company.data');
  267. Ext.namespace('Company.data'); // equivalent and preferable to above syntax
  268. Company.Widget = function() { ... }
  269. Company.data.CustomStore = function(config) { ... }
  270. </code></pre>
  271. * @param {String} namespace1
  272. * @param {String} namespace2
  273. * @param {String} etc
  274. * @method namespace
  275. */
  276. namespace : function(){
  277. var o, d;
  278. Ext.each(arguments, function(v) {
  279. d = v.split(".");
  280. o = window[d[0]] = window[d[0]] || {};
  281. Ext.each(d.slice(1), function(v2){
  282. o = o[v2] = o[v2] || {};
  283. });
  284. });
  285. return o;
  286. },
  287. /**
  288. * Takes an object and converts it to an encoded URL. e.g. Ext.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.
  289. * @param {Object} o
  290. * @param {String} pre (optional) A prefix to add to the url encoded string
  291. * @return {String}
  292. */
  293. urlEncode: function(o, pre){
  294. var undef, buf = [], key, e = encodeURIComponent;
  295. for(key in o){
  296. undef = !Ext.isDefined(o[key]);
  297. Ext.each(undef ? key : o[key], function(val, i){
  298. buf.push("&", e(key), "=", (val != key || !undef) ? e(val) : "");
  299. });
  300. }
  301. if(!pre){
  302. buf.shift();
  303. pre = "";
  304. }
  305. return pre + buf.join('');
  306. },
  307. /**
  308. * Takes an encoded URL and and converts it to an object. Example: <pre><code>
  309. Ext.urlDecode("foo=1&bar=2"); // returns {foo: "1", bar: "2"}
  310. Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); // returns {foo: "1", bar: ["2", "3", "4"]}
  311. </code></pre>
  312. * @param {String} string
  313. * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
  314. * @return {Object} A literal with members
  315. */
  316. urlDecode : function(string, overwrite){
  317. var obj = {},
  318. pairs = string.split('&'),
  319. d = decodeURIComponent,
  320. name,
  321. value;
  322. Ext.each(pairs, function(pair) {
  323. pair = pair.split('=');
  324. name = d(pair[0]);
  325. value = d(pair[1]);
  326. obj[name] = overwrite || !obj[name] ? value :
  327. [].concat(obj[name]).concat(value);
  328. });
  329. return obj;
  330. },
  331. /**
  332. * Appends content to the query string of a URL, which handles logic for whether to place
  333. * a question mark or ampersand.
  334. * @param {String} url The url to append to.
  335. * @@param {String} s The content to append to the url.
  336. * @return (String) The appended string
  337. */
  338. urlAppend : function(url, s){
  339. if(!Ext.isEmpty(s)){
  340. return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
  341. }
  342. return url;
  343. },
  344. /**
  345. * Converts any iterable (numeric indices and a length property) into a true array
  346. * Don't use this on strings. IE doesn't support "abc"[0] which this implementation depends on.
  347. * For strings, use this instead: "abc".match(/./g) => [a,b,c];
  348. * @param {Iterable} the iterable object to be turned into a true Array.
  349. * @return (Array) array
  350. */
  351. toArray : function(){
  352. return isIE ?
  353. function(a, i, j, res){
  354. res = [];
  355. Ext.each(a, function(v) {
  356. res.push(v);
  357. });
  358. return res.slice(i || 0, j || res.length);
  359. } :
  360. function(a, i, j){
  361. return Array.prototype.slice.call(a, i || 0, j || a.length);
  362. }
  363. }(),
  364. /**
  365. * Iterates an array calling the passed function with each item, stopping if your function returns false. If the
  366. * passed array is not really an array, your function is called once with it.
  367. * The supplied function is called with (Object item, Number index, Array allItems).
  368. * @param {Array/NodeList/Mixed} array
  369. * @param {Function} fn
  370. * @param {Object} scope
  371. */
  372. each: function(array, fn, scope){
  373. if(Ext.isEmpty(array, true)){
  374. return;
  375. }
  376. if(!isIterable(array) || Ext.isPrimitive(array)){
  377. array = [array];
  378. }
  379. for(var i = 0, len = array.length; i < len; i++){
  380. if(fn.call(scope || array[i], array[i], i, array) === false){
  381. return i;
  382. };
  383. }
  384. },
  385. /**
  386. * Iterates either the elements in an array, or each of the properties in an object.
  387. * <b>Note</b>: If you are only iterating arrays, it is better to call {@link #each}.
  388. * @param {Object/Array} object The object or array to be iterated
  389. * @param {Function} fn The function to be called for each iteration.
  390. * The iteration will stop if the supplied function returns false, or
  391. * all array elements / object properties have been covered. The signature
  392. * varies depending on the type of object being interated:
  393. * <div class="mdetail-params"><ul>
  394. * <li>Arrays : <tt>(Object item, Number index, Array allItems)</tt>
  395. * <div class="sub-desc">
  396. * When iterating an array, the supplied function is called with each item.</div></li>
  397. * <li>Objects : <tt>(String key, Object value)</tt>
  398. * <div class="sub-desc">
  399. * When iterating an object, the supplied function is called with each key-value pair in
  400. * the object.</div></li>
  401. * </ul></div>
  402. * @param {Object} scope The scope to call the supplied function with, defaults to
  403. * the specified <tt>object</tt>
  404. */
  405. iterate : function(obj, fn, scope){
  406. if(isIterable(obj)){
  407. Ext.each(obj, fn, scope);
  408. return;
  409. }else if(Ext.isObject(obj)){
  410. for(var prop in obj){
  411. if(obj.hasOwnProperty(prop)){
  412. if(fn.call(scope || obj, prop, obj[prop]) === false){
  413. return;
  414. };
  415. }
  416. }
  417. }
  418. },
  419. /**
  420. * Return the dom node for the passed String (id), dom node, or Ext.Element.
  421. * Here are some examples:
  422. * <pre><code>
  423. // gets dom node based on id
  424. var elDom = Ext.getDom('elId');
  425. // gets dom node based on the dom node
  426. var elDom1 = Ext.getDom(elDom);
  427. // If we don&#39;t know if we are working with an
  428. // Ext.Element or a dom node use Ext.getDom
  429. function(el){
  430. var dom = Ext.getDom(el);
  431. // do something with the dom node
  432. }
  433. * </code></pre>
  434. * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc)
  435. * when this method is called to be successful.
  436. * @param {Mixed} el
  437. * @return HTMLElement
  438. */
  439. getDom : function(el){
  440. if(!el || !DOC){
  441. return null;
  442. }
  443. return el.dom ? el.dom : (Ext.isString(el) ? DOC.getElementById(el) : el);
  444. },
  445. /**
  446. * Returns the current document body as an {@link Ext.Element}.
  447. * @return Ext.Element The document body
  448. */
  449. getBody : function(){
  450. return Ext.get(DOC.body || DOC.documentElement);
  451. },
  452. /**
  453. * Removes a DOM node from the document. The body node will be ignored if passed in.
  454. * @param {HTMLElement} node The node to remove
  455. */
  456. removeNode : isIE ? function(){
  457. var d;
  458. return function(n){
  459. if(n && n.tagName != 'BODY'){
  460. d = d || DOC.createElement('div');
  461. d.appendChild(n);
  462. d.innerHTML = '';
  463. }
  464. }
  465. }() : function(n){
  466. if(n && n.parentNode && n.tagName != 'BODY'){
  467. n.parentNode.removeChild(n);
  468. }
  469. },
  470. /**
  471. * <p>Returns true if the passed value is empty.</p>
  472. * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
  473. * <li>null</li>
  474. * <li>undefined</li>
  475. * <li>an empty array</li>
  476. * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
  477. * </ul></div>
  478. * @param {Mixed} value The value to test
  479. * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
  480. * @return {Boolean}
  481. */
  482. isEmpty : function(v, allowBlank){
  483. return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
  484. },
  485. /**
  486. * Returns true if the passed object is a JavaScript array, otherwise false.
  487. * @param {Object} object The object to test
  488. * @return {Boolean}
  489. */
  490. isArray : function(v){
  491. return toString.apply(v) === '[object Array]';
  492. },
  493. /**
  494. * Returns true if the passed object is a JavaScript Object, otherwise false.
  495. * @param {Object} object The object to test
  496. * @return {Boolean}
  497. */
  498. isObject : function(v){
  499. return v && typeof v == "object";
  500. },
  501. /**
  502. * Returns true if the passed object is a JavaScript 'primitive', a string, number or boolean.
  503. * @param {Mixed} value The value to test
  504. * @return {Boolean}
  505. */
  506. isPrimitive : function(v){
  507. return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v);
  508. },
  509. /**
  510. * Returns true if the passed object is a JavaScript Function, otherwise false.
  511. * @param {Object} object The object to test
  512. * @return {Boolean}
  513. */
  514. isFunction : function(v){
  515. return toString.apply(v) === '[object Function]';
  516. },
  517. /**
  518. * Returns true if the passed object is a number. Returns false for non-finite numbers.
  519. * @param {Object} v The object to test
  520. * @return {Boolean}
  521. */
  522. isNumber: function(v){
  523. return typeof v === 'number' && isFinite(v);
  524. },
  525. /**
  526. * Returns true if the passed object is a string.
  527. * @param {Object} v The object to test
  528. * @return {Boolean}
  529. */
  530. isString: function(v){
  531. return typeof v === 'string';
  532. },
  533. /**
  534. * Returns true if the passed object is a boolean.
  535. * @param {Object} v The object to test
  536. * @return {Boolean}
  537. */
  538. isBoolean: function(v){
  539. return typeof v === 'boolean';
  540. },
  541. /**
  542. * Returns true if the passed object is not undefined.
  543. * @param {Object} v The object to test
  544. * @return {Boolean}
  545. */
  546. isDefined: function(v){
  547. return typeof v !== 'undefined';
  548. },
  549. /**
  550. * True if the detected browser is Opera.
  551. * @type Boolean
  552. */
  553. isOpera : isOpera,
  554. /**
  555. * True if the detected browser uses WebKit.
  556. * @type Boolean
  557. */
  558. isWebKit: isWebKit,
  559. /**
  560. * True if the detected browser is Chrome.
  561. * @type Boolean
  562. */
  563. isChrome : isChrome,
  564. /**
  565. * True if the detected browser is Safari.
  566. * @type Boolean
  567. */
  568. isSafari : isSafari,
  569. /**
  570. * True if the detected browser is Safari 3.x.
  571. * @type Boolean
  572. */
  573. isSafari3 : isSafari3,
  574. /**
  575. * True if the detected browser is Safari 4.x.
  576. * @type Boolean
  577. */
  578. isSafari4 : isSafari4,
  579. /**
  580. * True if the detected browser is Safari 2.x.
  581. * @type Boolean
  582. */
  583. isSafari2 : isSafari2,
  584. /**
  585. * True if the detected browser is Internet Explorer.
  586. * @type Boolean
  587. */
  588. isIE : isIE,
  589. /**
  590. * True if the detected browser is Internet Explorer 6.x.
  591. * @type Boolean
  592. */
  593. isIE6 : isIE6,
  594. /**
  595. * True if the detected browser is Internet Explorer 7.x.
  596. * @type Boolean
  597. */
  598. isIE7 : isIE7,
  599. /**
  600. * True if the detected browser is Internet Explorer 8.x.
  601. * @type Boolean
  602. */
  603. isIE8 : isIE8,
  604. /**
  605. * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
  606. * @type Boolean
  607. */
  608. isGecko : isGecko,
  609. /**
  610. * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x).
  611. * @type Boolean
  612. */
  613. isGecko2 : isGecko2,
  614. /**
  615. * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
  616. * @type Boolean
  617. */
  618. isGecko3 : isGecko3,
  619. /**
  620. * True if the detected browser is Internet Explorer running in non-strict mode.
  621. * @type Boolean
  622. */
  623. isBorderBox : isBorderBox,
  624. /**
  625. * True if the detected platform is Linux.
  626. * @type Boolean
  627. */
  628. isLinux : isLinux,
  629. /**
  630. * True if the detected platform is Windows.
  631. * @type Boolean
  632. */
  633. isWindows : isWindows,
  634. /**
  635. * True if the detected platform is Mac OS.
  636. * @type Boolean
  637. */
  638. isMac : isMac,
  639. /**
  640. * True if the detected platform is Adobe Air.
  641. * @type Boolean
  642. */
  643. isAir : isAir
  644. });
  645. /**
  646. * Creates namespaces to be used for scoping variables and classes so that they are not global.
  647. * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
  648. * <pre><code>
  649. Ext.namespace('Company', 'Company.data');
  650. Ext.namespace('Company.data'); // equivalent and preferable to above syntax
  651. Company.Widget = function() { ... }
  652. Company.data.CustomStore = function(config) { ... }
  653. </code></pre>
  654. * @param {String} namespace1
  655. * @param {String} namespace2
  656. * @param {String} etc
  657. * @method namespace
  658. */
  659. Ext.ns = Ext.namespace;
  660. })();
  661. Ext.ns("Ext", "Ext.util", "Ext.lib", "Ext.data");
  662. /**
  663. * @class Function
  664. * These functions are available on every Function object (any JavaScript function).
  665. */
  666. Ext.apply(Function.prototype, {
  667. /**
  668. * Creates an interceptor function. The passed fcn is called before the original one. If it returns false,
  669. * the original one is not called. The resulting function returns the results of the original function.
  670. * The passed fcn is called with the parameters of the original function. Example usage:
  671. * <pre><code>
  672. var sayHi = function(name){
  673. alert('Hi, ' + name);
  674. }
  675. sayHi('Fred'); // alerts "Hi, Fred"
  676. // create a new function that validates input without
  677. // directly modifying the original function:
  678. var sayHiToFriend = sayHi.createInterceptor(function(name){
  679. return name == 'Brian';
  680. });
  681. sayHiToFriend('Fred'); // no alert
  682. sayHiToFriend('Brian'); // alerts "Hi, Brian"
  683. </code></pre>
  684. * @param {Function} fcn The function to call before the original
  685. * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
  686. * @return {Function} The new function
  687. */
  688. createInterceptor : function(fcn, scope){
  689. var method = this;
  690. return !Ext.isFunction(fcn) ?
  691. this :
  692. function() {
  693. var me = this,
  694. args = arguments;
  695. fcn.target = me;
  696. fcn.method = method;
  697. return (fcn.apply(scope || me || window, args) !== false) ?
  698. method.apply(me || window, args) :
  699. null;
  700. };
  701. },
  702. /**
  703. * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
  704. * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code>
  705. * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the
  706. * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always
  707. * executes in the window scope.
  708. * <p>This method is required when you want to pass arguments to a callback function. If no arguments
  709. * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn).
  710. * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function
  711. * would simply execute immediately when the code is parsed. Example usage:
  712. * <pre><code>
  713. var sayHi = function(name){
  714. alert('Hi, ' + name);
  715. }
  716. // clicking the button alerts "Hi, Fred"
  717. new Ext.Button({
  718. text: 'Say Hi',
  719. renderTo: Ext.getBody(),
  720. handler: sayHi.createCallback('Fred')
  721. });
  722. </code></pre>
  723. * @return {Function} The new function
  724. */
  725. createCallback : function(/*args...*/){
  726. // make args available, in function below
  727. var args = arguments,
  728. method = this;
  729. return function() {
  730. return method.apply(window, args);
  731. };
  732. },
  733. /**
  734. * Creates a delegate (callback) that sets the scope to obj.
  735. * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code>
  736. * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
  737. * callback points to obj. Example usage:
  738. * <pre><code>
  739. var sayHi = function(name){
  740. // Note this use of "this.text" here. This function expects to
  741. // execute within a scope that contains a text property. In this
  742. // example, the "this" variable is pointing to the btn object that
  743. // was passed in createDelegate below.
  744. alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
  745. }
  746. var btn = new Ext.Button({
  747. text: 'Say Hi',
  748. renderTo: Ext.getBody()
  749. });
  750. // This callback will execute in the scope of the
  751. // button instance. Clicking the button alerts
  752. // "Hi, Fred. You clicked the "Say Hi" button."
  753. btn.on('click', sayHi.createDelegate(btn, ['Fred']));
  754. </code></pre>
  755. * @param {Object} obj (optional) The object for which the scope is set
  756. * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
  757. * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
  758. * if a number the args are inserted at the specified position
  759. * @return {Function} The new function
  760. */
  761. createDelegate : function(obj, args, appendArgs){
  762. var method = this;
  763. return function() {
  764. var callArgs = args || arguments;
  765. if (appendArgs === true){
  766. callArgs = Array.prototype.slice.call(arguments, 0);
  767. callArgs = callArgs.concat(args);
  768. }else if (Ext.isNumber(appendArgs)){
  769. callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
  770. var applyArgs = [appendArgs, 0].concat(args); // create method call params
  771. Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
  772. }
  773. return method.apply(obj || window, callArgs);
  774. };
  775. },
  776. /**
  777. * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
  778. * <pre><code>
  779. var sayHi = function(name){
  780. alert('Hi, ' + name);
  781. }
  782. // executes immediately:
  783. sayHi('Fred');
  784. // executes after 2 seconds:
  785. sayHi.defer(2000, this, ['Fred']);
  786. // this syntax is sometimes useful for deferring
  787. // execution of an anonymous function:
  788. (function(){
  789. alert('Anonymous');
  790. }).defer(100);
  791. </code></pre>
  792. * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
  793. * @param {Object} obj (optional) The object for which the scope is set
  794. * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
  795. * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
  796. * if a number the args are inserted at the specified position
  797. * @return {Number} The timeout id that can be used with clearTimeout
  798. */
  799. defer : function(millis, obj, args, appendArgs){
  800. var fn = this.createDelegate(obj, args, appendArgs);
  801. if(millis > 0){
  802. return setTimeout(fn, millis);
  803. }
  804. fn();
  805. return 0;
  806. }
  807. });
  808. /**
  809. * @class String
  810. * These functions are available on every String object.
  811. */
  812. Ext.applyIf(String, {
  813. /**
  814. * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each
  815. * token must be unique, and must increment in the format {0}, {1}, etc. Example usage:
  816. * <pre><code>
  817. var cls = 'my-class', text = 'Some text';
  818. var s = String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
  819. // s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
  820. * </code></pre>
  821. * @param {String} string The tokenized string to be formatted
  822. * @param {String} value1 The value to replace token {0}
  823. * @param {String} value2 Etc...
  824. * @return {String} The formatted string
  825. * @static
  826. */
  827. format : function(format){
  828. var args = Ext.toArray(arguments, 1);
  829. return format.replace(/\{(\d+)\}/g, function(m, i){
  830. return args[i];
  831. });
  832. }
  833. });
  834. /**
  835. * @class Array
  836. */
  837. Ext.applyIf(Array.prototype, {
  838. /**
  839. * Checks whether or not the specified object exists in the array.
  840. * @param {Object} o The object to check for
  841. * @return {Number} The index of o in the array (or -1 if it is not found)
  842. */
  843. indexOf : function(o){
  844. for (var i = 0, len = this.length; i < len; i++){
  845. if(this[i] == o){
  846. return i;
  847. }
  848. }
  849. return -1;
  850. },
  851. /**
  852. * Removes the specified object from the array. If the object is not found nothing happens.
  853. * @param {Object} o The object to remove
  854. * @return {Array} this array
  855. */
  856. remove : function(o){
  857. var index = this.indexOf(o);
  858. if(index != -1){
  859. this.splice(index, 1);
  860. }
  861. return this;
  862. }
  863. });
  864. /**
  865. * @class Ext
  866. */
  867. Ext.ns("Ext.grid", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
  868. "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct");
  869. /**
  870. * Namespace alloted for extensions to the framework.
  871. * @property ux
  872. * @type Object
  873. */
  874. Ext.apply(Ext, function(){
  875. var E = Ext, idSeed = 0;
  876. return {
  877. /**
  878. * A reusable empty function
  879. * @property
  880. * @type Function
  881. */
  882. emptyFn : function(){},
  883. /**
  884. * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images.
  885. * In older versions of IE, this defaults to "http://extjs.com/s.gif" and you should change this to a URL on your server.
  886. * For other browsers it uses an inline data URL.
  887. * @type String
  888. */
  889. BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 ?
  890. 'http:/' + '/extjs.com/s.gif' :
  891. 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
  892. extendX : function(supr, fn){
  893. return Ext.extend(supr, fn(supr.prototype));
  894. },
  895. /**
  896. * Returns the current HTML document object as an {@link Ext.Element}.
  897. * @return Ext.Element The document
  898. */
  899. getDoc : function(){
  900. return Ext.get(document);
  901. },
  902. /**
  903. * Returns true if the passed object is a JavaScript date object, otherwise false.
  904. * @param {Object} object The object to test
  905. * @return {Boolean}
  906. */
  907. isDate : function(v){
  908. return Object.prototype.toString.apply(v) === '[object Date]';
  909. },
  910. /**
  911. * Utility method for validating that a value is numeric, returning the specified default value if it is not.
  912. * @param {Mixed} value Should be a number, but any type will be handled appropriately
  913. * @param {Number} defaultValue The value to return if the original value is non-numeric
  914. * @return {Number} Value, if numeric, else defaultValue
  915. */
  916. num : function(v, defaultValue){
  917. v = Number(v === null || typeof v == 'boolean'? NaN : v);
  918. return isNaN(v)? defaultValue : v;
  919. },
  920. /**
  921. * <p>Utility method for returning a default value if the passed value is empty.</p>
  922. * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
  923. * <li>null</li>
  924. * <li>undefined</li>
  925. * <li>an empty array</li>
  926. * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
  927. * </ul></div>
  928. * @param {Mixed} value The value to test
  929. * @param {Mixed} defaultValue The value to return if the original value is empty
  930. * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false)
  931. * @return {Mixed} value, if non-empty, else defaultValue
  932. */
  933. value : function(v, defaultValue, allowBlank){
  934. return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
  935. },
  936. /**
  937. * Escapes the passed string for use in a regular expression
  938. * @param {String} str
  939. * @return {String}
  940. */
  941. escapeRe : function(s) {
  942. return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1");
  943. },
  944. sequence : function(o, name, fn, scope){
  945. o[name] = o[name].createSequence(fn, scope);
  946. },
  947. /**
  948. * Applies event listeners to elements by selectors when the document is ready.
  949. * The event name is specified with an <tt>&#64;</tt> suffix.
  950. * <pre><code>
  951. Ext.addBehaviors({
  952. // add a listener for click on all anchors in element with id foo
  953. '#foo a&#64;click' : function(e, t){
  954. // do something
  955. },
  956. // add the same listener to multiple selectors (separated by comma BEFORE the &#64;)
  957. '#foo a, #bar span.some-class&#64;mouseover' : function(){
  958. // do something
  959. }
  960. });
  961. * </code></pre>
  962. * @param {Object} obj The list of behaviors to apply
  963. */
  964. addBehaviors : function(o){
  965. if(!Ext.isReady){
  966. Ext.onReady(function(){
  967. Ext.addBehaviors(o);
  968. });
  969. } else {
  970. var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times
  971. parts,
  972. b,
  973. s;
  974. for (b in o) {
  975. if ((parts = b.split('@'))[1]) { // for Object prototype breakers
  976. s = parts[0];
  977. if(!cache[s]){
  978. cache[s] = Ext.select(s);
  979. }
  980. cache[s].on(parts[1], o[b]);
  981. }
  982. }
  983. cache = null;
  984. }
  985. },
  986. // deprecated
  987. combine : function(){
  988. var as = arguments, l = as.length, r = [];
  989. for(var i = 0; i < l; i++){
  990. var a = as[i];
  991. if(Ext.isArray(a)){
  992. r = r.concat(a);
  993. }else if(a.length !== undefined && !a.substr){
  994. r = r.concat(Array.prototype.slice.call(a, 0));
  995. }else{
  996. r.push(a);
  997. }
  998. }
  999. return r;
  1000. },
  1001. /**
  1002. * Copies a set of named properties fom the source object to the destination object.
  1003. * <p>example:<pre><code>
  1004. ImageComponent = Ext.extend(Ext.BoxComponent, {
  1005. initComponent: function() {
  1006. this.autoEl = { tag: 'img' };
  1007. MyComponent.superclass.initComponent.apply(this, arguments);
  1008. this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
  1009. }
  1010. });
  1011. * </code></pre>
  1012. * @param {Object} The destination object.
  1013. * @param {Object} The source object.
  1014. * @param {Array/String} Either an Array of property names, or a comma-delimited list
  1015. * of property names to copy.
  1016. * @return {Object} The modified object.
  1017. */
  1018. copyTo : function(dest, source, names){
  1019. if(typeof names == 'string'){
  1020. names = names.split(/[,;\s]/);
  1021. }
  1022. Ext.each(names, function(name){
  1023. if(source.hasOwnProperty(name)){
  1024. dest[name] = source[name];
  1025. }
  1026. }, this);
  1027. return dest;
  1028. },
  1029. /**
  1030. * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
  1031. * DOM (if applicable) and calling their destroy functions (if available). This method is primarily
  1032. * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of
  1033. * {@link Ext.util.Observable} can be passed in. Any number of elements and/or components can be
  1034. * passed into this function in a single call as separate arguments.
  1035. * @param {Mixed} arg1 An {@link Ext.Element}, {@link Ext.Component}, or an Array of either of these to destroy
  1036. * @param {Mixed} arg2 (optional)
  1037. * @param {Mixed} etc... (optional)
  1038. */
  1039. destroy : function(){
  1040. Ext.each(arguments, function(arg){
  1041. if(arg){
  1042. if(Ext.isArray(arg)){
  1043. this.destroy.apply(this, arg);
  1044. }else if(Ext.isFunction(arg.destroy)){
  1045. arg.destroy();
  1046. }else if(arg.dom){
  1047. arg.remove();
  1048. }
  1049. }
  1050. }, this);
  1051. },
  1052. /**
  1053. * Attempts to destroy and then remove a set of named properties of the passed object.
  1054. * @param {Object} o The object (most likely a Component) who's properties you wish to destroy.
  1055. * @param {Mixed} arg1 The name of the property to destroy and remove from the object.
  1056. * @param {Mixed} etc... More property names to destroy and remove.
  1057. */
  1058. destroyMembers : function(o, arg1, arg2, etc){
  1059. for(var i = 1, a = arguments, len = a.length; i < len; i++) {
  1060. Ext.destroy(o[a[i]]);
  1061. delete o[a[i]];
  1062. }
  1063. },
  1064. /**
  1065. * Creates a copy of the passed Array with falsy values removed.
  1066. * @param {Array/NodeList} arr The Array from which to remove falsy values.
  1067. * @return {Array} The new, compressed Array.
  1068. */
  1069. clean : function(arr){
  1070. var ret = [];
  1071. Ext.each(arr, function(v){
  1072. if(!!v){
  1073. ret.push(v);
  1074. }
  1075. });
  1076. return ret;
  1077. },
  1078. /**
  1079. * Creates a copy of the passed Array, filtered to contain only unique values.
  1080. * @param {Array} arr The Array to filter
  1081. * @return {Array} The new Array containing unique values.
  1082. */
  1083. unique : function(arr){
  1084. var ret = [],
  1085. collect = {};
  1086. Ext.each(arr, function(v) {
  1087. if(!collect[v]){
  1088. ret.push(v);
  1089. }
  1090. collect[v] = true;
  1091. });
  1092. return ret;
  1093. },
  1094. /**
  1095. * Recursively flattens into 1-d Array. Injects Arrays inline.
  1096. * @param {Array} arr The array to flatten
  1097. * @return {Array} The new, flattened array.
  1098. */
  1099. flatten : function(arr){
  1100. var worker = [];
  1101. function rFlatten(a) {
  1102. Ext.each(a, function(v) {
  1103. if(Ext.isArray(v)){
  1104. rFlatten(v);
  1105. }else{
  1106. worker.push(v);
  1107. }
  1108. });
  1109. return worker;
  1110. }
  1111. return rFlatten(arr);
  1112. },
  1113. /**
  1114. * Returns the minimum value in the Array.
  1115. * @param {Array|NodeList} arr The Array from which to select the minimum value.
  1116. * @param {Function} comp (optional) a function to perform the comparision which determines minimization.
  1117. * If omitted the "<" operator will be used. Note: gt = 1; eq = 0; lt = -1
  1118. * @return {Object} The minimum value in the Array.
  1119. */
  1120. min : function(arr, comp){
  1121. var ret = arr[0];
  1122. comp = comp || function(a,b){ return a < b ? -1 : 1; };
  1123. Ext.each(arr, function(v) {
  1124. ret = comp(ret, v) == -1 ? ret : v;
  1125. });
  1126. return ret;
  1127. },
  1128. /**
  1129. * Returns the maximum value in the Array
  1130. * @param {Array|NodeList} arr The Array from which to select the maximum value.
  1131. * @param {Function} comp (optional) a function to perform the comparision which determines maximization.
  1132. * If omitted the ">" operator will be used. Note: gt = 1; eq = 0; lt = -1
  1133. * @return {Object} The maximum value in the Array.
  1134. */
  1135. max : function(arr, comp){
  1136. var ret = arr[0];
  1137. comp = comp || function(a,b){ return a > b ? 1 : -1; };
  1138. Ext.each(arr, function(v) {
  1139. ret = comp(ret, v) == 1 ? ret : v;
  1140. });
  1141. return ret;
  1142. },
  1143. /**
  1144. * Calculates the mean of the Array
  1145. * @param {Array} arr The Array to calculate the mean value of.
  1146. * @return {Number} The mean.
  1147. */
  1148. mean : function(arr){
  1149. return Ext.sum(arr) / arr.length;
  1150. },
  1151. /**
  1152. * Calculates the sum of the Array
  1153. * @param {Array} arr The Array to calculate the sum value of.
  1154. * @return {Number} The sum.
  1155. */
  1156. sum : function(arr){
  1157. var ret = 0;
  1158. Ext.each(arr, function(v) {
  1159. ret += v;
  1160. });
  1161. return ret;
  1162. },
  1163. /**
  1164. * Partitions the set into two sets: a true set and a false set.
  1165. * Example:
  1166. * Example2:
  1167. * <pre><code>
  1168. // Example 1:
  1169. Ext.partition([true, false, true, true, false]); // [[true, true, true], [false, false]]
  1170. // Example 2:
  1171. Ext.partition(
  1172. Ext.query("p"),
  1173. function(val){
  1174. return val.className == "class1"
  1175. }
  1176. );
  1177. // true are those paragraph elements with a className of "class1",
  1178. // false set are those that do not have that className.
  1179. * </code></pre>
  1180. * @param {Array|NodeList} arr The array to partition
  1181. * @param {Function} truth (optional) a function to determine truth. If this is omitted the element
  1182. * itself must be able to be evaluated for its truthfulness.
  1183. * @return {Array} [true<Array>,false<Array>]
  1184. */
  1185. partition : function(arr, truth){
  1186. var ret = [[],[]];
  1187. Ext.each(arr, function(v, i, a) {
  1188. ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
  1189. });
  1190. return ret;
  1191. },
  1192. /**
  1193. * Invokes a method on each item in an Array.
  1194. * <pre><code>
  1195. // Example:
  1196. Ext.invoke(Ext.query("p"), "getAttribute", "id");
  1197. // [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")]
  1198. * </code></pre>
  1199. * @param {Array|NodeList} arr The Array of items to invoke the method on.
  1200. * @param {String} methodName The method name to invoke.
  1201. * @param {Anything} ... Arguments to send into the method invocation.
  1202. * @return {Array} The results of invoking the method on each item in the array.
  1203. */
  1204. invoke : function(arr, methodName){
  1205. var ret = [],
  1206. args = Array.prototype.slice.call(arguments, 2);
  1207. Ext.each(arr, function(v,i) {
  1208. if (v && typeof v[methodName] == "function") {
  1209. ret.push(v[methodName].apply(v, args));
  1210. } else {
  1211. ret.push(undefined);
  1212. }
  1213. });
  1214. return ret;
  1215. },
  1216. /**
  1217. * Plucks the value of a property from each item in the Array
  1218. * <pre><code>
  1219. // Example:
  1220. Ext.pluck(Ext.query("p"), "className"); // [el1.className, el2.className, ..., elN.className]
  1221. * </code></pre>
  1222. * @param {Array|NodeList} arr The Array of items to pluck the value from.
  1223. * @param {String} prop The property name to pluck from each element.
  1224. * @return {Array} The value from each item in the Array.
  1225. */
  1226. pluck : function(arr, prop){
  1227. var ret = [];
  1228. Ext.each(arr, function(v) {
  1229. ret.push( v[prop] );
  1230. });
  1231. return ret;
  1232. },
  1233. /**
  1234. * <p>Zips N sets together.</p>
  1235. * <pre><code>
  1236. // Example 1:
  1237. Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]]
  1238. // Example 2:
  1239. Ext.zip(
  1240. [ "+", "-", "+"],
  1241. [ 12, 10, 22],
  1242. [ 43, 15, 96],
  1243. function(a, b, c){
  1244. return "$" + a + "" + b + "." + c
  1245. }
  1246. ); // ["$+12.43", "$-10.15", "$+22.96"]
  1247. * </code></pre>
  1248. * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values.
  1249. * @param {Function} zipper (optional) The last item in the argument list. This will drive how the items are zipped together.
  1250. * @return {Array} The zipped set.
  1251. */
  1252. zip : function(){
  1253. var parts = Ext.partition(arguments, function( val ){ return !Ext.isFunction(val); }),
  1254. arrs = parts[0],
  1255. fn = parts[1][0],
  1256. len = Ext.max(Ext.pluck(arrs, "length")),
  1257. ret = [];
  1258. for (var i = 0; i < len; i++) {
  1259. ret[i] = [];
  1260. if(fn){
  1261. ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
  1262. }else{
  1263. for (var j = 0, aLen = arrs.length; j < aLen; j++){
  1264. ret[i].push( arrs[j][i] );
  1265. }
  1266. }
  1267. }
  1268. return ret;
  1269. },
  1270. /**
  1271. * This is shorthand reference to {@link Ext.ComponentMgr#get}.
  1272. * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id}
  1273. * @param {String} id The component {@link Ext.Component#id id}
  1274. * @return Ext.Component The Component, <tt>undefined</tt> if not found, or <tt>null</tt> if a
  1275. * Class was found.
  1276. */
  1277. getCmp : function(id){
  1278. return Ext.ComponentMgr.get(id);
  1279. },
  1280. /**
  1281. * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
  1282. * you may want to set this to true.
  1283. * @type Boolean
  1284. */
  1285. useShims: E.isIE6 || (E.isMac && E.isGecko2),
  1286. // inpired by a similar function in mootools library
  1287. /**
  1288. * Returns the type of object that is passed in. If the object passed in is null or undefined it
  1289. * return false otherwise it returns one of the following values:<div class="mdetail-params"><ul>
  1290. * <li><b>string</b>: If the object passed is a string</li>
  1291. * <li><b>number</b>: If the object passed is a number</li>
  1292. * <li><b>boolean</b>: If the object passed is a boolean value</li>
  1293. * <li><b>date</b>: If the object passed is a Date object</li>
  1294. * <li><b>function</b>: If the object passed is a function reference</li>
  1295. * <li><b>object</b>: If the object passed is an object</li>
  1296. * <li><b>array</b>: If the object passed is an array</li>
  1297. * <li><b>regexp</b>: If the object passed is a regular expression</li>
  1298. * <li><b>element</b>: If the object passed is a DOM Element</li>
  1299. * <li><b>nodelist</b>: If the object passed is a DOM NodeList</li>
  1300. * <li><b>textnode</b>: If the object passed is a DOM text node and contains something other than whitespace</li>
  1301. * <li><b>whitespace</b>: If the object passed is a DOM text node and contains only whitespace</li>
  1302. * </ul></div>
  1303. * @param {Mixed} object
  1304. * @return {String}
  1305. */
  1306. type : function(o){
  1307. if(o === undefined || o === null){
  1308. return false;
  1309. }
  1310. if(o.htmlElement){
  1311. return 'element';
  1312. }
  1313. var t = typeof o;
  1314. if(t == 'object' && o.nodeName) {
  1315. switch(o.nodeType) {
  1316. case 1: return 'element';
  1317. case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
  1318. }
  1319. }
  1320. if(t == 'object' || t == 'function') {
  1321. switch(o.constructor) {
  1322. case Array: return 'array';
  1323. case RegExp: return 'regexp';
  1324. case Date: return 'date';
  1325. }
  1326. if(typeof o.length == 'number' && typeof o.item == 'function') {
  1327. return 'nodelist';
  1328. }
  1329. }
  1330. return t;
  1331. },
  1332. intercept : function(o, name, fn, scope){
  1333. o[name] = o[name].createInterceptor(fn, scope);
  1334. },
  1335. // internal
  1336. callback : function(cb, scope, args, delay){
  1337. if(Ext.isFunction(cb)){
  1338. if(delay){
  1339. cb.defer(delay, scope, args || []);
  1340. }else{
  1341. cb.apply(scope, args || []);
  1342. }
  1343. }
  1344. }
  1345. };
  1346. }());
  1347. /**
  1348. * @class Function
  1349. * These functions are available on every Function object (any JavaScript function).
  1350. */
  1351. Ext.apply(Function.prototype, {
  1352. /**
  1353. * Create a combined function call sequence of the original function + the passed function.
  1354. * The resulting function returns the results of the original function.
  1355. * The passed fcn is called with the parameters of the original function. Example usage:
  1356. * <pre><code>
  1357. var sayHi = function(name){
  1358. alert('Hi, ' + name);
  1359. }
  1360. sayHi('Fred'); // alerts "Hi, Fred"
  1361. var sayGoodbye = sayHi.createSequence(function(name){
  1362. alert('Bye, ' + name);
  1363. });
  1364. sayGoodbye('Fred'); // both alerts show
  1365. </code></pre>
  1366. * @param {Function} fcn The function to sequence
  1367. * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
  1368. * @return {Function} The new function
  1369. */
  1370. createSequence : function(fcn, scope){
  1371. var method = this;
  1372. return !Ext.isFunction(fcn) ?
  1373. this :
  1374. function(){
  1375. var retval = method.apply(this || window, arguments);
  1376. fcn.apply(scope || this || window, arguments);
  1377. return retval;
  1378. };
  1379. }
  1380. });
  1381. /**
  1382. * @class String
  1383. * These functions are available as static methods on the JavaScript String object.
  1384. */
  1385. Ext.applyIf(String, {
  1386. /**
  1387. * Escapes the passed string for ' and \
  1388. * @param {String} string The string to escape
  1389. * @return {String} The escaped string
  1390. * @static
  1391. */
  1392. escape : function(string) {
  1393. return string.replace(/('|\\)/g, "\\$1");
  1394. },
  1395. /**
  1396. * Pads the left side of a string with a specified character. This is especially useful
  1397. * for normalizing number and date strings. Example usage:
  1398. * <pre><code>
  1399. var s = String.leftPad('123', 5, '0');
  1400. // s now contains the string: '00123'
  1401. * </code></pre>
  1402. * @param {String} string The original string
  1403. * @param {Number} size The total length of the output string
  1404. * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
  1405. * @return {String} The padded string
  1406. * @static
  1407. */
  1408. leftPad : function (val, size, ch) {
  1409. var result = String(val);
  1410. if(!ch) {
  1411. ch = " ";
  1412. }
  1413. while (result.length < size) {
  1414. result = ch + result;
  1415. }
  1416. return result;
  1417. }
  1418. });
  1419. /**
  1420. * Utility function that allows you to easily switch a string between two alternating values. The passed value
  1421. * is compared to the current string, and if they are equal, the other value that was passed in is returned. If
  1422. * they are already different, the first value passed in is returned. Note that this method returns the new value
  1423. * but does not change the current string.
  1424. * <pre><code>
  1425. // alternate sort directions
  1426. sort = sort.toggle('ASC', 'DESC');
  1427. // instead of conditional logic:
  1428. sort = (sort == 'ASC' ? 'DESC' : 'ASC');
  1429. </code></pre>
  1430. * @param {String} value The value to compare to the current string
  1431. * @param {String} other The new value to use if the string already equals the first value passed in
  1432. * @return {String} The new value
  1433. */
  1434. String.prototype.toggle = function(value, other){
  1435. return this == value ? other : value;
  1436. };
  1437. /**
  1438. * Trims whitespace from either end of a string, leaving spaces within the string intact. Example:
  1439. * <pre><code>
  1440. var s = ' foo bar ';
  1441. alert('-' + s + '-'); //alerts "- foo bar -"
  1442. alert('-' + s.trim() + '-'); //alerts "-foo bar-"
  1443. </code></pre>
  1444. * @return {String} The trimmed string
  1445. */
  1446. String.prototype.trim = function(){
  1447. var re = /^\s+|\s+$/g;
  1448. return function(){ return this.replace(re, ""); };
  1449. }();
  1450. // here to prevent dependency on Date.js
  1451. /**
  1452. Returns the number of milliseconds between this date and date
  1453. @param {Date} date (optional) Defaults to now
  1454. @return {Number} The diff in milliseconds
  1455. @member Date getElapsed
  1456. */
  1457. Date.prototype.getElapsed = function(date) {
  1458. return Math.abs((date || new Date()).getTime()-this.getTime());
  1459. };
  1460. /**
  1461. * @class Number
  1462. */
  1463. Ext.applyIf(Number.prototype, {
  1464. /**
  1465. * Checks whether or not the current number is within a desired range. If the number is already within the
  1466. * range it is returned, otherwise the min or max value is returned depending on which side of the range is
  1467. * exceeded. Note that this method returns the constrained value but does not change the current number.
  1468. * @param {Number} min The minimum number in the range
  1469. * @param {Number} max The maximum number in the range
  1470. * @return {Number} The constrained value if outside the range, otherwise the current value
  1471. */
  1472. constrain : function(min, max){
  1473. return Math.min(Math.max(this, min), max);
  1474. }
  1475. });
  1476. /**
  1477. * @class Ext.util.TaskRunner
  1478. * Provides the ability to execute one or more arbitrary tasks in a multithreaded
  1479. * manner. Generally, you can use the singleton {@link Ext.TaskMgr} instead, but
  1480. * if needed, you can create separate instances of TaskRunner. Any number of
  1481. * separate tasks can be started at any time and will run independently of each
  1482. * other. Example usage:
  1483. * <pre><code>
  1484. // Start a simple clock task that updates a div once per second
  1485. var updateClock = function(){
  1486. Ext.fly('clock').update(new Date().format('g:i:s A'));
  1487. }
  1488. var task = {
  1489. run: updateClock,
  1490. interval: 1000 //1 second
  1491. }
  1492. var runner = new Ext.util.TaskRunner();
  1493. runner.start(task);
  1494. // equivalent using TaskMgr
  1495. Ext.TaskMgr.start({
  1496. run: updateClock,
  1497. interval: 1000
  1498. });
  1499. * </code></pre>
  1500. * Also see {@link Ext.util.DelayedTask}.
  1501. *
  1502. * @constructor
  1503. * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance
  1504. * (defaults to 10)
  1505. */
  1506. Ext.util.TaskRunner = function(interval){
  1507. interval = interval || 10;
  1508. var tasks = [],
  1509. removeQueue = [],
  1510. id = 0,
  1511. running = false,
  1512. // private
  1513. stopThread = function(){
  1514. running = false;
  1515. clearInterval(id);
  1516. id = 0;
  1517. },
  1518. // private
  1519. startThread = function(){
  1520. if(!running){
  1521. running = true;
  1522. id = setInterval(runTasks, interval);
  1523. }
  1524. },
  1525. // private
  1526. removeTask = function(t){
  1527. removeQueue.push(t);
  1528. if(t.onStop){
  1529. t.onStop.apply(t.scope || t);
  1530. }
  1531. },
  1532. // private
  1533. runTasks = function(){
  1534. var rqLen = removeQueue.length,
  1535. now = new Date().getTime();
  1536. if(rqLen > 0){
  1537. for(var i = 0; i < rqLen; i++){
  1538. tasks.remove(removeQueue[i]);
  1539. }
  1540. removeQueue = [];
  1541. if(tasks.length < 1){
  1542. stopThread();
  1543. return;
  1544. }
  1545. }
  1546. for(var i = 0, t, itime, rt, len = tasks.length; i < len; ++i){
  1547. t = tasks[i];
  1548. itime = now - t.taskRunTime;
  1549. if(t.interval <= itime){
  1550. rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
  1551. t.taskRunTime = now;
  1552. if(rt === false || t.taskRunCount === t.repeat){
  1553. removeTask(t);
  1554. return;
  1555. }
  1556. }
  1557. if(t.duration && t.duration <= (now - t.taskStartTime)){
  1558. removeTask(t);
  1559. }
  1560. }
  1561. };
  1562. /**
  1563. * Starts a new task.
  1564. * @method start
  1565. * @param {Object} task A config object that supports the following properties:<ul>
  1566. * <li><code>run</code> : Function<div class="sub-desc">The function to execute each time the task is run. The
  1567. * function will be called at each interval and passed the <code>args</code> argument if specified. If a
  1568. * particular scope is required, be sure to specify it using the <code>scope</code> argument.</div></li>
  1569. * <li><code>interval</code> : Number<div class="sub-desc">The frequency in milliseconds with which the task
  1570. * should be executed.</div></li>
  1571. * <li><code>args</code> : Array<div class="sub-desc">(optional) An array of arguments to be passed to the function
  1572. * specified by <code>run</code>.</div></li>
  1573. * <li><code>scope</code> : Object<div class="sub-desc">(optional) The scope (<tt>this</tt> reference) in which to execute the
  1574. * <code>run</code> function. Defaults to the task config object.</div></li>
  1575. * <li><code>duration</code> : Number<div class="sub-desc">(optional) The length of time in milliseconds to execute
  1576. * the task before stopping automatically (defaults to indefinite).</div></li>
  1577. * <li><code>repeat</code> : Number<div class="sub-desc">(optional) The number of times to execute the task before
  1578. * stopping automatically (defaults to indefinite).</div></li>
  1579. * </ul>
  1580. * @return {Object} The task
  1581. */
  1582. this.start = function(task){
  1583. tasks.push(task);
  1584. task.taskStartTime = new Date().getTime();
  1585. task.taskRunTime = 0;
  1586. task.taskRunCount = 0;
  1587. startThread();
  1588. return task;
  1589. };
  1590. /**
  1591. * Stops an existing running task.
  1592. * @method stop
  1593. * @param {Object} task The task to stop
  1594. * @return {Object} The task
  1595. */
  1596. this.stop = function(task){
  1597. removeTask(task);
  1598. return task;
  1599. };
  1600. /**
  1601. * Stops all tasks that are currently running.
  1602. * @method stopAll
  1603. */
  1604. this.stopAll = function(){
  1605. stopThread();
  1606. for(var i = 0, len = tasks.length; i < len; i++){
  1607. if(tasks[i].onStop){
  1608. tasks[i].onStop();
  1609. }
  1610. }
  1611. tasks = [];
  1612. removeQueue = [];
  1613. };
  1614. };
  1615. /**
  1616. * @class Ext.TaskMgr
  1617. * @extends Ext.util.TaskRunner
  1618. * A static {@link Ext.util.TaskRunner} instance that can be used to start and stop arbitrary tasks. See
  1619. * {@link Ext.util.TaskRunner} for supported methods and task config properties.
  1620. * <pre><code>
  1621. // Start a simple clock task that updates a div once per second
  1622. var task = {
  1623. run: function(){
  1624. Ext.fly('clock').update(new Date().format('g:i:s A'));
  1625. },
  1626. interval: 1000 //1 second
  1627. }
  1628. Ext.TaskMgr.start(task);
  1629. </code></pre>
  1630. * @singleton
  1631. */
  1632. Ext.TaskMgr = new Ext.util.TaskRunner();(function(){
  1633. var libFlyweight;
  1634. function fly(el) {
  1635. if (!libFlyweight) {
  1636. libFlyweight = new Ext.Element.Flyweight();
  1637. }
  1638. libFlyweight.dom = el;
  1639. return libFlyweight;
  1640. }
  1641. (function(){
  1642. var doc = document,
  1643. isCSS1 = doc.compatMode == "CSS1Compat",
  1644. MAX = Math.max,
  1645. PARSEINT = parseInt;
  1646. Ext.lib.Dom = {
  1647. isAncestor : function(p, c) {
  1648. var ret = false;
  1649. p = Ext.getDom(p);
  1650. c = Ext.getDom(c);
  1651. if (p && c) {
  1652. if (p.contains) {
  1653. return p.contains(c);
  1654. } else if (p.compareDocumentPosition) {
  1655. return !!(p.compareDocumentPosition(c) & 16);
  1656. } else {
  1657. while (c = c.parentNode) {
  1658. ret = c == p || ret;
  1659. }
  1660. }
  1661. }
  1662. return ret;
  1663. },
  1664. getViewWidth : function(full) {
  1665. return full ? this.getDocumentWidth() : this.getViewportWidth();
  1666. },
  1667. getViewHeight : function(full) {
  1668. return full ? this.getDocumentHeight() : this.getViewportHeight();
  1669. },
  1670. getDocumentHeight: function() {
  1671. return MAX(!isCSS1 ? doc.body.scrollHeight : doc.documentElement.scrollHeight, this.getViewportHeight());
  1672. },
  1673. getDocumentWidth: function() {
  1674. return MAX(!isCSS1 ? doc.body.scrollWidth : doc.documentElement.scrollWidth, this.getViewportWidth());
  1675. },