Forked mumble-django project from https://bitbucket.org/Svedrin/mumble-django
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3631 lines
121 KiB

  1. /*!
  2. * Ext JS Library 3.2.0
  3. * Copyright(c) 2006-2010 Ext JS, Inc.
  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.2.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. ua = navigator.userAgent.toLowerCase(),
  45. check = function(r){
  46. return r.test(ua);
  47. },
  48. DOC = document,
  49. isStrict = DOC.compatMode == "CSS1Compat",
  50. isOpera = check(/opera/),
  51. isChrome = check(/\bchrome\b/),
  52. isWebKit = check(/webkit/),
  53. isSafari = !isChrome && check(/safari/),
  54. isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2
  55. isSafari3 = isSafari && check(/version\/3/),
  56. isSafari4 = isSafari && check(/version\/4/),
  57. isIE = !isOpera && check(/msie/),
  58. isIE7 = isIE && check(/msie 7/),
  59. isIE8 = isIE && check(/msie 8/),
  60. isIE6 = isIE && !isIE7 && !isIE8,
  61. isGecko = !isWebKit && check(/gecko/),
  62. isGecko2 = isGecko && check(/rv:1\.8/),
  63. isGecko3 = isGecko && check(/rv:1\.9/),
  64. isBorderBox = isIE && !isStrict,
  65. isWindows = check(/windows|win32/),
  66. isMac = check(/macintosh|mac os x/),
  67. isAir = check(/adobeair/),
  68. isLinux = check(/linux/),
  69. isSecure = /^https/i.test(window.location.protocol);
  70. // remove css image flicker
  71. if(isIE6){
  72. try{
  73. DOC.execCommand("BackgroundImageCache", false, true);
  74. }catch(e){}
  75. }
  76. Ext.apply(Ext, {
  77. /**
  78. * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent
  79. * the IE insecure content warning (<tt>'about:blank'</tt>, except for IE in secure mode, which is <tt>'javascript:""'</tt>).
  80. * @type String
  81. */
  82. SSL_SECURE_URL : isSecure && isIE ? 'javascript:""' : 'about:blank',
  83. /**
  84. * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode
  85. * @type Boolean
  86. */
  87. isStrict : isStrict,
  88. /**
  89. * True if the page is running over SSL
  90. * @type Boolean
  91. */
  92. isSecure : isSecure,
  93. /**
  94. * True when the document is fully initialized and ready for action
  95. * @type Boolean
  96. */
  97. isReady : false,
  98. /**
  99. * True if the {@link Ext.Fx} Class is available
  100. * @type Boolean
  101. * @property enableFx
  102. */
  103. /**
  104. * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)
  105. * @type Boolean
  106. */
  107. enableGarbageCollector : true,
  108. /**
  109. * True to automatically purge event listeners during garbageCollection (defaults to false).
  110. * @type Boolean
  111. */
  112. enableListenerCollection : false,
  113. /**
  114. * EXPERIMENTAL - True to cascade listener removal to child elements when an element is removed.
  115. * Currently not optimized for performance.
  116. * @type Boolean
  117. */
  118. enableNestedListenerRemoval : false,
  119. /**
  120. * Indicates whether to use native browser parsing for JSON methods.
  121. * This option is ignored if the browser does not support native JSON methods.
  122. * <b>Note: Native JSON methods will not work with objects that have functions.
  123. * Also, property names must be quoted, otherwise the data will not parse.</b> (Defaults to false)
  124. * @type Boolean
  125. */
  126. USE_NATIVE_JSON : false,
  127. /**
  128. * Copies all the properties of config to obj if they don't already exist.
  129. * @param {Object} obj The receiver of the properties
  130. * @param {Object} config The source of the properties
  131. * @return {Object} returns obj
  132. */
  133. applyIf : function(o, c){
  134. if(o){
  135. for(var p in c){
  136. if(!Ext.isDefined(o[p])){
  137. o[p] = c[p];
  138. }
  139. }
  140. }
  141. return o;
  142. },
  143. /**
  144. * Generates unique ids. If the element already has an id, it is unchanged
  145. * @param {Mixed} el (optional) The element to generate an id for
  146. * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
  147. * @return {String} The generated Id.
  148. */
  149. id : function(el, prefix){
  150. el = Ext.getDom(el, true) || {};
  151. if (!el.id) {
  152. el.id = (prefix || "ext-gen") + (++idSeed);
  153. }
  154. return el.id;
  155. },
  156. /**
  157. * <p>Extends one class to create a subclass and optionally overrides members with the passed literal. This method
  158. * also adds the function "override()" to the subclass that can be used to override members of the class.</p>
  159. * For example, to create a subclass of Ext GridPanel:
  160. * <pre><code>
  161. MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
  162. constructor: function(config) {
  163. // Create configuration for this Grid.
  164. var store = new Ext.data.Store({...});
  165. var colModel = new Ext.grid.ColumnModel({...});
  166. // Create a new config object containing our computed properties
  167. // *plus* whatever was in the config parameter.
  168. config = Ext.apply({
  169. store: store,
  170. colModel: colModel
  171. }, config);
  172. MyGridPanel.superclass.constructor.call(this, config);
  173. // Your postprocessing here
  174. },
  175. yourMethod: function() {
  176. // etc.
  177. }
  178. });
  179. </code></pre>
  180. *
  181. * <p>This function also supports a 3-argument call in which the subclass's constructor is
  182. * passed as an argument. In this form, the parameters are as follows:</p>
  183. * <div class="mdetail-params"><ul>
  184. * <li><code>subclass</code> : Function <div class="sub-desc">The subclass constructor.</div></li>
  185. * <li><code>superclass</code> : Function <div class="sub-desc">The constructor of class being extended</div></li>
  186. * <li><code>overrides</code> : Object <div class="sub-desc">A literal with members which are copied into the subclass's
  187. * prototype, and are therefore shared among all instances of the new class.</div></li>
  188. * </ul></div>
  189. *
  190. * @param {Function} superclass The constructor of class being extended.
  191. * @param {Object} overrides <p>A literal with members which are copied into the subclass's
  192. * prototype, and are therefore shared between all instances of the new class.</p>
  193. * <p>This may contain a special member named <tt><b>constructor</b></tt>. This is used
  194. * to define the constructor of the new class, and is returned. If this property is
  195. * <i>not</i> specified, a constructor is generated and returned which just calls the
  196. * superclass's constructor passing on its parameters.</p>
  197. * <p><b>It is essential that you call the superclass constructor in any provided constructor. See example code.</b></p>
  198. * @return {Function} The subclass constructor from the <code>overrides</code> parameter, or a generated one if not provided.
  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){return 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.hasOwnProperty('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. * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created)
  275. * @method namespace
  276. */
  277. namespace : function(){
  278. var o, d;
  279. Ext.each(arguments, function(v) {
  280. d = v.split(".");
  281. o = window[d[0]] = window[d[0]] || {};
  282. Ext.each(d.slice(1), function(v2){
  283. o = o[v2] = o[v2] || {};
  284. });
  285. });
  286. return o;
  287. },
  288. /**
  289. * 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.
  290. * @param {Object} o
  291. * @param {String} pre (optional) A prefix to add to the url encoded string
  292. * @return {String}
  293. */
  294. urlEncode : function(o, pre){
  295. var empty,
  296. buf = [],
  297. e = encodeURIComponent;
  298. Ext.iterate(o, function(key, item){
  299. empty = Ext.isEmpty(item);
  300. Ext.each(empty ? key : item, function(val){
  301. buf.push('&', e(key), '=', (!Ext.isEmpty(val) && (val != key || !empty)) ? (Ext.isDate(val) ? Ext.encode(val).replace(/"/g, '') : e(val)) : '');
  302. });
  303. });
  304. if(!pre){
  305. buf.shift();
  306. pre = '';
  307. }
  308. return pre + buf.join('');
  309. },
  310. /**
  311. * Takes an encoded URL and and converts it to an object. Example: <pre><code>
  312. Ext.urlDecode("foo=1&bar=2"); // returns {foo: "1", bar: "2"}
  313. Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); // returns {foo: "1", bar: ["2", "3", "4"]}
  314. </code></pre>
  315. * @param {String} string
  316. * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
  317. * @return {Object} A literal with members
  318. */
  319. urlDecode : function(string, overwrite){
  320. if(Ext.isEmpty(string)){
  321. return {};
  322. }
  323. var obj = {},
  324. pairs = string.split('&'),
  325. d = decodeURIComponent,
  326. name,
  327. value;
  328. Ext.each(pairs, function(pair) {
  329. pair = pair.split('=');
  330. name = d(pair[0]);
  331. value = d(pair[1]);
  332. obj[name] = overwrite || !obj[name] ? value :
  333. [].concat(obj[name]).concat(value);
  334. });
  335. return obj;
  336. },
  337. /**
  338. * Appends content to the query string of a URL, handling logic for whether to place
  339. * a question mark or ampersand.
  340. * @param {String} url The URL to append to.
  341. * @param {String} s The content to append to the URL.
  342. * @return (String) The resulting URL
  343. */
  344. urlAppend : function(url, s){
  345. if(!Ext.isEmpty(s)){
  346. return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
  347. }
  348. return url;
  349. },
  350. /**
  351. * Converts any iterable (numeric indices and a length property) into a true array
  352. * Don't use this on strings. IE doesn't support "abc"[0] which this implementation depends on.
  353. * For strings, use this instead: "abc".match(/./g) => [a,b,c];
  354. * @param {Iterable} the iterable object to be turned into a true Array.
  355. * @return (Array) array
  356. */
  357. toArray : function(){
  358. return isIE ?
  359. function(a, i, j, res){
  360. res = [];
  361. for(var x = 0, len = a.length; x < len; x++) {
  362. res.push(a[x]);
  363. }
  364. return res.slice(i || 0, j || res.length);
  365. } :
  366. function(a, i, j){
  367. return Array.prototype.slice.call(a, i || 0, j || a.length);
  368. }
  369. }(),
  370. isIterable : function(v){
  371. //check for array or arguments
  372. if(Ext.isArray(v) || v.callee){
  373. return true;
  374. }
  375. //check for node list type
  376. if(/NodeList|HTMLCollection/.test(toString.call(v))){
  377. return true;
  378. }
  379. //NodeList has an item and length property
  380. //IXMLDOMNodeList has nextNode method, needs to be checked first.
  381. return ((typeof v.nextNode != 'undefined' || v.item) && Ext.isNumber(v.length));
  382. },
  383. /**
  384. * Iterates an array calling the supplied function.
  385. * @param {Array/NodeList/Mixed} array The array to be iterated. If this
  386. * argument is not really an array, the supplied function is called once.
  387. * @param {Function} fn The function to be called with each item. If the
  388. * supplied function returns false, iteration stops and this method returns
  389. * the current <code>index</code>. This function is called with
  390. * the following arguments:
  391. * <div class="mdetail-params"><ul>
  392. * <li><code>item</code> : <i>Mixed</i>
  393. * <div class="sub-desc">The item at the current <code>index</code>
  394. * in the passed <code>array</code></div></li>
  395. * <li><code>index</code> : <i>Number</i>
  396. * <div class="sub-desc">The current index within the array</div></li>
  397. * <li><code>allItems</code> : <i>Array</i>
  398. * <div class="sub-desc">The <code>array</code> passed as the first
  399. * argument to <code>Ext.each</code>.</div></li>
  400. * </ul></div>
  401. * @param {Object} scope The scope (<code>this</code> reference) in which the specified function is executed.
  402. * Defaults to the <code>item</code> at the current <code>index</code>
  403. * within the passed <code>array</code>.
  404. * @return See description for the fn parameter.
  405. */
  406. each : function(array, fn, scope){
  407. if(Ext.isEmpty(array, true)){
  408. return;
  409. }
  410. if(!Ext.isIterable(array) || Ext.isPrimitive(array)){
  411. array = [array];
  412. }
  413. for(var i = 0, len = array.length; i < len; i++){
  414. if(fn.call(scope || array[i], array[i], i, array) === false){
  415. return i;
  416. };
  417. }
  418. },
  419. /**
  420. * Iterates either the elements in an array, or each of the properties in an object.
  421. * <b>Note</b>: If you are only iterating arrays, it is better to call {@link #each}.
  422. * @param {Object/Array} object The object or array to be iterated
  423. * @param {Function} fn The function to be called for each iteration.
  424. * The iteration will stop if the supplied function returns false, or
  425. * all array elements / object properties have been covered. The signature
  426. * varies depending on the type of object being interated:
  427. * <div class="mdetail-params"><ul>
  428. * <li>Arrays : <tt>(Object item, Number index, Array allItems)</tt>
  429. * <div class="sub-desc">
  430. * When iterating an array, the supplied function is called with each item.</div></li>
  431. * <li>Objects : <tt>(String key, Object value, Object)</tt>
  432. * <div class="sub-desc">
  433. * When iterating an object, the supplied function is called with each key-value pair in
  434. * the object, and the iterated object</div></li>
  435. * </ul></div>
  436. * @param {Object} scope The scope (<code>this</code> reference) in which the specified function is executed. Defaults to
  437. * the <code>object</code> being iterated.
  438. */
  439. iterate : function(obj, fn, scope){
  440. if(Ext.isEmpty(obj)){
  441. return;
  442. }
  443. if(Ext.isIterable(obj)){
  444. Ext.each(obj, fn, scope);
  445. return;
  446. }else if(Ext.isObject(obj)){
  447. for(var prop in obj){
  448. if(obj.hasOwnProperty(prop)){
  449. if(fn.call(scope || obj, prop, obj[prop], obj) === false){
  450. return;
  451. };
  452. }
  453. }
  454. }
  455. },
  456. /**
  457. * Return the dom node for the passed String (id), dom node, or Ext.Element.
  458. * Optional 'strict' flag is needed for IE since it can return 'name' and
  459. * 'id' elements by using getElementById.
  460. * Here are some examples:
  461. * <pre><code>
  462. // gets dom node based on id
  463. var elDom = Ext.getDom('elId');
  464. // gets dom node based on the dom node
  465. var elDom1 = Ext.getDom(elDom);
  466. // If we don&#39;t know if we are working with an
  467. // Ext.Element or a dom node use Ext.getDom
  468. function(el){
  469. var dom = Ext.getDom(el);
  470. // do something with the dom node
  471. }
  472. * </code></pre>
  473. * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc)
  474. * when this method is called to be successful.
  475. * @param {Mixed} el
  476. * @return HTMLElement
  477. */
  478. getDom : function(el, strict){
  479. if(!el || !DOC){
  480. return null;
  481. }
  482. if (el.dom){
  483. return el.dom;
  484. } else {
  485. if (Ext.isString(el)) {
  486. var e = DOC.getElementById(el);
  487. // IE returns elements with the 'name' and 'id' attribute.
  488. // we do a strict check to return the element with only the id attribute
  489. if (e && isIE && strict) {
  490. if (el == e.getAttribute('id')) {
  491. return e;
  492. } else {
  493. return null;
  494. }
  495. }
  496. return e;
  497. } else {
  498. return el;
  499. }
  500. }
  501. },
  502. /**
  503. * Returns the current document body as an {@link Ext.Element}.
  504. * @return Ext.Element The document body
  505. */
  506. getBody : function(){
  507. return Ext.get(DOC.body || DOC.documentElement);
  508. },
  509. /**
  510. * Removes a DOM node from the document.
  511. */
  512. /**
  513. * <p>Removes this element from the document, removes all DOM event listeners, and deletes the cache reference.
  514. * All DOM event listeners are removed from this element. If {@link Ext#enableNestedListenerRemoval} is
  515. * <code>true</code>, then DOM event listeners are also removed from all child nodes. The body node
  516. * will be ignored if passed in.</p>
  517. * @param {HTMLElement} node The node to remove
  518. */
  519. removeNode : isIE && !isIE8 ? function(){
  520. var d;
  521. return function(n){
  522. if(n && n.tagName != 'BODY'){
  523. (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n);
  524. d = d || DOC.createElement('div');
  525. d.appendChild(n);
  526. d.innerHTML = '';
  527. delete Ext.elCache[n.id];
  528. }
  529. }
  530. }() : function(n){
  531. if(n && n.parentNode && n.tagName != 'BODY'){
  532. (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n);
  533. n.parentNode.removeChild(n);
  534. delete Ext.elCache[n.id];
  535. }
  536. },
  537. /**
  538. * <p>Returns true if the passed value is empty.</p>
  539. * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
  540. * <li>null</li>
  541. * <li>undefined</li>
  542. * <li>an empty array</li>
  543. * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
  544. * </ul></div>
  545. * @param {Mixed} value The value to test
  546. * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
  547. * @return {Boolean}
  548. */
  549. isEmpty : function(v, allowBlank){
  550. return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
  551. },
  552. /**
  553. * Returns true if the passed value is a JavaScript array, otherwise false.
  554. * @param {Mixed} value The value to test
  555. * @return {Boolean}
  556. */
  557. isArray : function(v){
  558. return toString.apply(v) === '[object Array]';
  559. },
  560. /**
  561. * Returns true if the passed object is a JavaScript date object, otherwise false.
  562. * @param {Object} object The object to test
  563. * @return {Boolean}
  564. */
  565. isDate : function(v){
  566. return toString.apply(v) === '[object Date]';
  567. },
  568. /**
  569. * Returns true if the passed value is a JavaScript Object, otherwise false.
  570. * @param {Mixed} value The value to test
  571. * @return {Boolean}
  572. */
  573. isObject : function(v){
  574. return !!v && Object.prototype.toString.call(v) === '[object Object]';
  575. },
  576. /**
  577. * Returns true if the passed value is a JavaScript 'primitive', a string, number or boolean.
  578. * @param {Mixed} value The value to test
  579. * @return {Boolean}
  580. */
  581. isPrimitive : function(v){
  582. return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v);
  583. },
  584. /**
  585. * Returns true if the passed value is a JavaScript Function, otherwise false.
  586. * @param {Mixed} value The value to test
  587. * @return {Boolean}
  588. */
  589. isFunction : function(v){
  590. return toString.apply(v) === '[object Function]';
  591. },
  592. /**
  593. * Returns true if the passed value is a number. Returns false for non-finite numbers.
  594. * @param {Mixed} value The value to test
  595. * @return {Boolean}
  596. */
  597. isNumber : function(v){
  598. return typeof v === 'number' && isFinite(v);
  599. },
  600. /**
  601. * Returns true if the passed value is a string.
  602. * @param {Mixed} value The value to test
  603. * @return {Boolean}
  604. */
  605. isString : function(v){
  606. return typeof v === 'string';
  607. },
  608. /**
  609. * Returns true if the passed value is a boolean.
  610. * @param {Mixed} value The value to test
  611. * @return {Boolean}
  612. */
  613. isBoolean : function(v){
  614. return typeof v === 'boolean';
  615. },
  616. /**
  617. * Returns true if the passed value is an HTMLElement
  618. * @param {Mixed} value The value to test
  619. * @return {Boolean}
  620. */
  621. isElement : function(v) {
  622. return v ? !!v.tagName : false;
  623. },
  624. /**
  625. * Returns true if the passed value is not undefined.
  626. * @param {Mixed} value The value to test
  627. * @return {Boolean}
  628. */
  629. isDefined : function(v){
  630. return typeof v !== 'undefined';
  631. },
  632. /**
  633. * True if the detected browser is Opera.
  634. * @type Boolean
  635. */
  636. isOpera : isOpera,
  637. /**
  638. * True if the detected browser uses WebKit.
  639. * @type Boolean
  640. */
  641. isWebKit : isWebKit,
  642. /**
  643. * True if the detected browser is Chrome.
  644. * @type Boolean
  645. */
  646. isChrome : isChrome,
  647. /**
  648. * True if the detected browser is Safari.
  649. * @type Boolean
  650. */
  651. isSafari : isSafari,
  652. /**
  653. * True if the detected browser is Safari 3.x.
  654. * @type Boolean
  655. */
  656. isSafari3 : isSafari3,
  657. /**
  658. * True if the detected browser is Safari 4.x.
  659. * @type Boolean
  660. */
  661. isSafari4 : isSafari4,
  662. /**
  663. * True if the detected browser is Safari 2.x.
  664. * @type Boolean
  665. */
  666. isSafari2 : isSafari2,
  667. /**
  668. * True if the detected browser is Internet Explorer.
  669. * @type Boolean
  670. */
  671. isIE : isIE,
  672. /**
  673. * True if the detected browser is Internet Explorer 6.x.
  674. * @type Boolean
  675. */
  676. isIE6 : isIE6,
  677. /**
  678. * True if the detected browser is Internet Explorer 7.x.
  679. * @type Boolean
  680. */
  681. isIE7 : isIE7,
  682. /**
  683. * True if the detected browser is Internet Explorer 8.x.
  684. * @type Boolean
  685. */
  686. isIE8 : isIE8,
  687. /**
  688. * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
  689. * @type Boolean
  690. */
  691. isGecko : isGecko,
  692. /**
  693. * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x).
  694. * @type Boolean
  695. */
  696. isGecko2 : isGecko2,
  697. /**
  698. * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
  699. * @type Boolean
  700. */
  701. isGecko3 : isGecko3,
  702. /**
  703. * True if the detected browser is Internet Explorer running in non-strict mode.
  704. * @type Boolean
  705. */
  706. isBorderBox : isBorderBox,
  707. /**
  708. * True if the detected platform is Linux.
  709. * @type Boolean
  710. */
  711. isLinux : isLinux,
  712. /**
  713. * True if the detected platform is Windows.
  714. * @type Boolean
  715. */
  716. isWindows : isWindows,
  717. /**
  718. * True if the detected platform is Mac OS.
  719. * @type Boolean
  720. */
  721. isMac : isMac,
  722. /**
  723. * True if the detected platform is Adobe Air.
  724. * @type Boolean
  725. */
  726. isAir : isAir
  727. });
  728. /**
  729. * Creates namespaces to be used for scoping variables and classes so that they are not global.
  730. * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
  731. * <pre><code>
  732. Ext.namespace('Company', 'Company.data');
  733. Ext.namespace('Company.data'); // equivalent and preferable to above syntax
  734. Company.Widget = function() { ... }
  735. Company.data.CustomStore = function(config) { ... }
  736. </code></pre>
  737. * @param {String} namespace1
  738. * @param {String} namespace2
  739. * @param {String} etc
  740. * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created)
  741. * @method ns
  742. */
  743. Ext.ns = Ext.namespace;
  744. })();
  745. Ext.ns("Ext.util", "Ext.lib", "Ext.data");
  746. Ext.elCache = {};
  747. /**
  748. * @class Function
  749. * These functions are available on every Function object (any JavaScript function).
  750. */
  751. Ext.apply(Function.prototype, {
  752. /**
  753. * Creates an interceptor function. The passed function is called before the original one. If it returns false,
  754. * the original one is not called. The resulting function returns the results of the original function.
  755. * The passed function is called with the parameters of the original function. Example usage:
  756. * <pre><code>
  757. var sayHi = function(name){
  758. alert('Hi, ' + name);
  759. }
  760. sayHi('Fred'); // alerts "Hi, Fred"
  761. // create a new function that validates input without
  762. // directly modifying the original function:
  763. var sayHiToFriend = sayHi.createInterceptor(function(name){
  764. return name == 'Brian';
  765. });
  766. sayHiToFriend('Fred'); // no alert
  767. sayHiToFriend('Brian'); // alerts "Hi, Brian"
  768. </code></pre>
  769. * @param {Function} fcn The function to call before the original
  770. * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
  771. * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
  772. * @return {Function} The new function
  773. */
  774. createInterceptor : function(fcn, scope){
  775. var method = this;
  776. return !Ext.isFunction(fcn) ?
  777. this :
  778. function() {
  779. var me = this,
  780. args = arguments;
  781. fcn.target = me;
  782. fcn.method = method;
  783. return (fcn.apply(scope || me || window, args) !== false) ?
  784. method.apply(me || window, args) :
  785. null;
  786. };
  787. },
  788. /**
  789. * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
  790. * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code>
  791. * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the
  792. * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always
  793. * executes in the window scope.
  794. * <p>This method is required when you want to pass arguments to a callback function. If no arguments
  795. * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn).
  796. * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function
  797. * would simply execute immediately when the code is parsed. Example usage:
  798. * <pre><code>
  799. var sayHi = function(name){
  800. alert('Hi, ' + name);
  801. }
  802. // clicking the button alerts "Hi, Fred"
  803. new Ext.Button({
  804. text: 'Say Hi',
  805. renderTo: Ext.getBody(),
  806. handler: sayHi.createCallback('Fred')
  807. });
  808. </code></pre>
  809. * @return {Function} The new function
  810. */
  811. createCallback : function(/*args...*/){
  812. // make args available, in function below
  813. var args = arguments,
  814. method = this;
  815. return function() {
  816. return method.apply(window, args);
  817. };
  818. },
  819. /**
  820. * Creates a delegate (callback) that sets the scope to obj.
  821. * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code>
  822. * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
  823. * callback points to obj. Example usage:
  824. * <pre><code>
  825. var sayHi = function(name){
  826. // Note this use of "this.text" here. This function expects to
  827. // execute within a scope that contains a text property. In this
  828. // example, the "this" variable is pointing to the btn object that
  829. // was passed in createDelegate below.
  830. alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
  831. }
  832. var btn = new Ext.Button({
  833. text: 'Say Hi',
  834. renderTo: Ext.getBody()
  835. });
  836. // This callback will execute in the scope of the
  837. // button instance. Clicking the button alerts
  838. // "Hi, Fred. You clicked the "Say Hi" button."
  839. btn.on('click', sayHi.createDelegate(btn, ['Fred']));
  840. </code></pre>
  841. * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
  842. * <b>If omitted, defaults to the browser window.</b>
  843. * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
  844. * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
  845. * if a number the args are inserted at the specified position
  846. * @return {Function} The new function
  847. */
  848. createDelegate : function(obj, args, appendArgs){
  849. var method = this;
  850. return function() {
  851. var callArgs = args || arguments;
  852. if (appendArgs === true){
  853. callArgs = Array.prototype.slice.call(arguments, 0);
  854. callArgs = callArgs.concat(args);
  855. }else if (Ext.isNumber(appendArgs)){
  856. callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
  857. var applyArgs = [appendArgs, 0].concat(args); // create method call params
  858. Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
  859. }
  860. return method.apply(obj || window, callArgs);
  861. };
  862. },
  863. /**
  864. * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
  865. * <pre><code>
  866. var sayHi = function(name){
  867. alert('Hi, ' + name);
  868. }
  869. // executes immediately:
  870. sayHi('Fred');
  871. // executes after 2 seconds:
  872. sayHi.defer(2000, this, ['Fred']);
  873. // this syntax is sometimes useful for deferring
  874. // execution of an anonymous function:
  875. (function(){
  876. alert('Anonymous');
  877. }).defer(100);
  878. </code></pre>
  879. * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
  880. * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
  881. * <b>If omitted, defaults to the browser window.</b>
  882. * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
  883. * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
  884. * if a number the args are inserted at the specified position
  885. * @return {Number} The timeout id that can be used with clearTimeout
  886. */
  887. defer : function(millis, obj, args, appendArgs){
  888. var fn = this.createDelegate(obj, args, appendArgs);
  889. if(millis > 0){
  890. return setTimeout(fn, millis);
  891. }
  892. fn();
  893. return 0;
  894. }
  895. });
  896. /**
  897. * @class String
  898. * These functions are available on every String object.
  899. */
  900. Ext.applyIf(String, {
  901. /**
  902. * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each
  903. * token must be unique, and must increment in the format {0}, {1}, etc. Example usage:
  904. * <pre><code>
  905. var cls = 'my-class', text = 'Some text';
  906. var s = String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
  907. // s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
  908. * </code></pre>
  909. * @param {String} string The tokenized string to be formatted
  910. * @param {String} value1 The value to replace token {0}
  911. * @param {String} value2 Etc...
  912. * @return {String} The formatted string
  913. * @static
  914. */
  915. format : function(format){
  916. var args = Ext.toArray(arguments, 1);
  917. return format.replace(/\{(\d+)\}/g, function(m, i){
  918. return args[i];
  919. });
  920. }
  921. });
  922. /**
  923. * @class Array
  924. */
  925. Ext.applyIf(Array.prototype, {
  926. /**
  927. * Checks whether or not the specified object exists in the array.
  928. * @param {Object} o The object to check for
  929. * @param {Number} from (Optional) The index at which to begin the search
  930. * @return {Number} The index of o in the array (or -1 if it is not found)
  931. */
  932. indexOf : function(o, from){
  933. var len = this.length;
  934. from = from || 0;
  935. from += (from < 0) ? len : 0;
  936. for (; from < len; ++from){
  937. if(this[from] === o){
  938. return from;
  939. }
  940. }
  941. return -1;
  942. },
  943. /**
  944. * Removes the specified object from the array. If the object is not found nothing happens.
  945. * @param {Object} o The object to remove
  946. * @return {Array} this array
  947. */
  948. remove : function(o){
  949. var index = this.indexOf(o);
  950. if(index != -1){
  951. this.splice(index, 1);
  952. }
  953. return this;
  954. }
  955. });
  956. /**
  957. * @class Ext
  958. */
  959. Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
  960. "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct");
  961. /**
  962. * Namespace alloted for extensions to the framework.
  963. * @property ux
  964. * @type Object
  965. */
  966. Ext.apply(Ext, function(){
  967. var E = Ext,
  968. idSeed = 0,
  969. scrollWidth = null;
  970. return {
  971. /**
  972. * A reusable empty function
  973. * @property
  974. * @type Function
  975. */
  976. emptyFn : function(){},
  977. /**
  978. * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images.
  979. * In older versions of IE, this defaults to "http://extjs.com/s.gif" and you should change this to a URL on your server.
  980. * For other browsers it uses an inline data URL.
  981. * @type String
  982. */
  983. BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ?
  984. 'http:/' + '/extjs.com/s.gif' :
  985. 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
  986. extendX : function(supr, fn){
  987. return Ext.extend(supr, fn(supr.prototype));
  988. },
  989. /**
  990. * Returns the current HTML document object as an {@link Ext.Element}.
  991. * @return Ext.Element The document
  992. */
  993. getDoc : function(){
  994. return Ext.get(document);
  995. },
  996. /**
  997. * Utility method for validating that a value is numeric, returning the specified default value if it is not.
  998. * @param {Mixed} value Should be a number, but any type will be handled appropriately
  999. * @param {Number} defaultValue The value to return if the original value is non-numeric
  1000. * @return {Number} Value, if numeric, else defaultValue
  1001. */
  1002. num : function(v, defaultValue){
  1003. v = Number(Ext.isEmpty(v) || Ext.isArray(v) || Ext.isBoolean(v) || (Ext.isString(v) && v.trim().length == 0) ? NaN : v);
  1004. return isNaN(v) ? defaultValue : v;
  1005. },
  1006. /**
  1007. * <p>Utility method for returning a default value if the passed value is empty.</p>
  1008. * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
  1009. * <li>null</li>
  1010. * <li>undefined</li>
  1011. * <li>an empty array</li>
  1012. * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
  1013. * </ul></div>
  1014. * @param {Mixed} value The value to test
  1015. * @param {Mixed} defaultValue The value to return if the original value is empty
  1016. * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false)
  1017. * @return {Mixed} value, if non-empty, else defaultValue
  1018. */
  1019. value : function(v, defaultValue, allowBlank){
  1020. return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
  1021. },
  1022. /**
  1023. * Escapes the passed string for use in a regular expression
  1024. * @param {String} str
  1025. * @return {String}
  1026. */
  1027. escapeRe : function(s) {
  1028. return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
  1029. },
  1030. sequence : function(o, name, fn, scope){
  1031. o[name] = o[name].createSequence(fn, scope);
  1032. },
  1033. /**
  1034. * Applies event listeners to elements by selectors when the document is ready.
  1035. * The event name is specified with an <tt>&#64;</tt> suffix.
  1036. * <pre><code>
  1037. Ext.addBehaviors({
  1038. // add a listener for click on all anchors in element with id foo
  1039. '#foo a&#64;click' : function(e, t){
  1040. // do something
  1041. },
  1042. // add the same listener to multiple selectors (separated by comma BEFORE the &#64;)
  1043. '#foo a, #bar span.some-class&#64;mouseover' : function(){
  1044. // do something
  1045. }
  1046. });
  1047. * </code></pre>
  1048. * @param {Object} obj The list of behaviors to apply
  1049. */
  1050. addBehaviors : function(o){
  1051. if(!Ext.isReady){
  1052. Ext.onReady(function(){
  1053. Ext.addBehaviors(o);
  1054. });
  1055. } else {
  1056. var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times
  1057. parts,
  1058. b,
  1059. s;
  1060. for (b in o) {
  1061. if ((parts = b.split('@'))[1]) { // for Object prototype breakers
  1062. s = parts[0];
  1063. if(!cache[s]){
  1064. cache[s] = Ext.select(s);
  1065. }
  1066. cache[s].on(parts[1], o[b]);
  1067. }
  1068. }
  1069. cache = null;
  1070. }
  1071. },
  1072. /**
  1073. * Utility method for getting the width of the browser scrollbar. This can differ depending on
  1074. * operating system settings, such as the theme or font size.
  1075. * @param {Boolean} force (optional) true to force a recalculation of the value.
  1076. * @return {Number} The width of the scrollbar.
  1077. */
  1078. getScrollBarWidth: function(force){
  1079. if(!Ext.isReady){
  1080. return 0;
  1081. }
  1082. if(force === true || scrollWidth === null){
  1083. // Append our div, do our calculation and then remove it
  1084. var div = Ext.getBody().createChild('<div class="x-hide-offsets" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
  1085. child = div.child('div', true);
  1086. var w1 = child.offsetWidth;
  1087. div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
  1088. var w2 = child.offsetWidth;
  1089. div.remove();
  1090. // Need to add 2 to ensure we leave enough space
  1091. scrollWidth = w1 - w2 + 2;
  1092. }
  1093. return scrollWidth;
  1094. },
  1095. // deprecated
  1096. combine : function(){
  1097. var as = arguments, l = as.length, r = [];
  1098. for(var i = 0; i < l; i++){
  1099. var a = as[i];
  1100. if(Ext.isArray(a)){
  1101. r = r.concat(a);
  1102. }else if(a.length !== undefined && !a.substr){
  1103. r = r.concat(Array.prototype.slice.call(a, 0));
  1104. }else{
  1105. r.push(a);
  1106. }
  1107. }
  1108. return r;
  1109. },
  1110. /**
  1111. * Copies a set of named properties fom the source object to the destination object.
  1112. * <p>example:<pre><code>
  1113. ImageComponent = Ext.extend(Ext.BoxComponent, {
  1114. initComponent: function() {
  1115. this.autoEl = { tag: 'img' };
  1116. MyComponent.superclass.initComponent.apply(this, arguments);
  1117. this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
  1118. }
  1119. });
  1120. * </code></pre>
  1121. * @param {Object} dest The destination object.
  1122. * @param {Object} source The source object.
  1123. * @param {Array/String} names Either an Array of property names, or a comma-delimited list
  1124. * of property names to copy.
  1125. * @return {Object} The modified object.
  1126. */
  1127. copyTo : function(dest, source, names){
  1128. if(Ext.isString(names)){
  1129. names = names.split(/[,;\s]/);
  1130. }
  1131. Ext.each(names, function(name){
  1132. if(source.hasOwnProperty(name)){
  1133. dest[name] = source[name];
  1134. }
  1135. }, this);
  1136. return dest;
  1137. },
  1138. /**
  1139. * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
  1140. * DOM (if applicable) and calling their destroy functions (if available). This method is primarily
  1141. * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of
  1142. * {@link Ext.util.Observable} can be passed in. Any number of elements and/or components can be
  1143. * passed into this function in a single call as separate arguments.
  1144. * @param {Mixed} arg1 An {@link Ext.Element}, {@link Ext.Component}, or an Array of either of these to destroy
  1145. * @param {Mixed} arg2 (optional)
  1146. * @param {Mixed} etc... (optional)
  1147. */
  1148. destroy : function(){
  1149. Ext.each(arguments, function(arg){
  1150. if(arg){
  1151. if(Ext.isArray(arg)){
  1152. this.destroy.apply(this, arg);
  1153. }else if(Ext.isFunction(arg.destroy)){
  1154. arg.destroy();
  1155. }else if(arg.dom){
  1156. arg.remove();
  1157. }
  1158. }
  1159. }, this);
  1160. },
  1161. /**
  1162. * Attempts to destroy and then remove a set of named properties of the passed object.
  1163. * @param {Object} o The object (most likely a Component) who's properties you wish to destroy.
  1164. * @param {Mixed} arg1 The name of the property to destroy and remove from the object.
  1165. * @param {Mixed} etc... More property names to destroy and remove.
  1166. */
  1167. destroyMembers : function(o, arg1, arg2, etc){
  1168. for(var i = 1, a = arguments, len = a.length; i < len; i++) {
  1169. Ext.destroy(o[a[i]]);
  1170. delete o[a[i]];
  1171. }
  1172. },
  1173. /**
  1174. * Creates a copy of the passed Array with falsy values removed.
  1175. * @param {Array/NodeList} arr The Array from which to remove falsy values.
  1176. * @return {Array} The new, compressed Array.
  1177. */
  1178. clean : function(arr){
  1179. var ret = [];
  1180. Ext.each(arr, function(v){
  1181. if(!!v){
  1182. ret.push(v);
  1183. }
  1184. });
  1185. return ret;
  1186. },
  1187. /**
  1188. * Creates a copy of the passed Array, filtered to contain only unique values.
  1189. * @param {Array} arr The Array to filter
  1190. * @return {Array} The new Array containing unique values.
  1191. */
  1192. unique : function(arr){
  1193. var ret = [],
  1194. collect = {};
  1195. Ext.each(arr, function(v) {
  1196. if(!collect[v]){
  1197. ret.push(v);
  1198. }
  1199. collect[v] = true;
  1200. });
  1201. return ret;
  1202. },
  1203. /**
  1204. * Recursively flattens into 1-d Array. Injects Arrays inline.
  1205. * @param {Array} arr The array to flatten
  1206. * @return {Array} The new, flattened array.
  1207. */
  1208. flatten : function(arr){
  1209. var worker = [];
  1210. function rFlatten(a) {
  1211. Ext.each(a, function(v) {
  1212. if(Ext.isArray(v)){
  1213. rFlatten(v);
  1214. }else{
  1215. worker.push(v);
  1216. }
  1217. });
  1218. return worker;
  1219. }
  1220. return rFlatten(arr);
  1221. },
  1222. /**
  1223. * Returns the minimum value in the Array.
  1224. * @param {Array|NodeList} arr The Array from which to select the minimum value.
  1225. * @param {Function} comp (optional) a function to perform the comparision which determines minimization.
  1226. * If omitted the "<" operator will be used. Note: gt = 1; eq = 0; lt = -1
  1227. * @return {Object} The minimum value in the Array.
  1228. */
  1229. min : function(arr, comp){
  1230. var ret = arr[0];
  1231. comp = comp || function(a,b){ return a < b ? -1 : 1; };
  1232. Ext.each(arr, function(v) {
  1233. ret = comp(ret, v) == -1 ? ret : v;
  1234. });
  1235. return ret;
  1236. },
  1237. /**
  1238. * Returns the maximum value in the Array
  1239. * @param {Array|NodeList} arr The Array from which to select the maximum value.
  1240. * @param {Function} comp (optional) a function to perform the comparision which determines maximization.
  1241. * If omitted the ">" operator will be used. Note: gt = 1; eq = 0; lt = -1
  1242. * @return {Object} The maximum value in the Array.
  1243. */
  1244. max : function(arr, comp){
  1245. var ret = arr[0];
  1246. comp = comp || function(a,b){ return a > b ? 1 : -1; };
  1247. Ext.each(arr, function(v) {
  1248. ret = comp(ret, v) == 1 ? ret : v;
  1249. });
  1250. return ret;
  1251. },
  1252. /**
  1253. * Calculates the mean of the Array
  1254. * @param {Array} arr The Array to calculate the mean value of.
  1255. * @return {Number} The mean.
  1256. */
  1257. mean : function(arr){
  1258. return arr.length > 0 ? Ext.sum(arr) / arr.length : undefined;
  1259. },
  1260. /**
  1261. * Calculates the sum of the Array
  1262. * @param {Array} arr The Array to calculate the sum value of.
  1263. * @return {Number} The sum.
  1264. */
  1265. sum : function(arr){
  1266. var ret = 0;
  1267. Ext.each(arr, function(v) {
  1268. ret += v;
  1269. });
  1270. return ret;
  1271. },
  1272. /**
  1273. * Partitions the set into two sets: a true set and a false set.
  1274. * Example:
  1275. * Example2:
  1276. * <pre><code>
  1277. // Example 1:
  1278. Ext.partition([true, false, true, true, false]); // [[true, true, true], [false, false]]
  1279. // Example 2:
  1280. Ext.partition(
  1281. Ext.query("p"),
  1282. function(val){
  1283. return val.className == "class1"
  1284. }
  1285. );
  1286. // true are those paragraph elements with a className of "class1",
  1287. // false set are those that do not have that className.
  1288. * </code></pre>
  1289. * @param {Array|NodeList} arr The array to partition
  1290. * @param {Function} truth (optional) a function to determine truth. If this is omitted the element
  1291. * itself must be able to be evaluated for its truthfulness.
  1292. * @return {Array} [true<Array>,false<Array>]
  1293. */
  1294. partition : function(arr, truth){
  1295. var ret = [[],[]];
  1296. Ext.each(arr, function(v, i, a) {
  1297. ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
  1298. });
  1299. return ret;
  1300. },
  1301. /**
  1302. * Invokes a method on each item in an Array.
  1303. * <pre><code>
  1304. // Example:
  1305. Ext.invoke(Ext.query("p"), "getAttribute", "id");
  1306. // [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")]
  1307. * </code></pre>
  1308. * @param {Array|NodeList} arr The Array of items to invoke the method on.
  1309. * @param {String} methodName The method name to invoke.
  1310. * @param {...*} args Arguments to send into the method invocation.
  1311. * @return {Array} The results of invoking the method on each item in the array.
  1312. */
  1313. invoke : function(arr, methodName){
  1314. var ret = [],
  1315. args = Array.prototype.slice.call(arguments, 2);
  1316. Ext.each(arr, function(v,i) {
  1317. if (v && Ext.isFunction(v[methodName])) {
  1318. ret.push(v[methodName].apply(v, args));
  1319. } else {
  1320. ret.push(undefined);
  1321. }
  1322. });
  1323. return ret;
  1324. },
  1325. /**
  1326. * Plucks the value of a property from each item in the Array
  1327. * <pre><code>
  1328. // Example:
  1329. Ext.pluck(Ext.query("p"), "className"); // [el1.className, el2.className, ..., elN.className]
  1330. * </code></pre>
  1331. * @param {Array|NodeList} arr The Array of items to pluck the value from.
  1332. * @param {String} prop The property name to pluck from each element.
  1333. * @return {Array} The value from each item in the Array.
  1334. */
  1335. pluck : function(arr, prop){
  1336. var ret = [];
  1337. Ext.each(arr, function(v) {
  1338. ret.push( v[prop] );
  1339. });
  1340. return ret;
  1341. },
  1342. /**
  1343. * <p>Zips N sets together.</p>
  1344. * <pre><code>
  1345. // Example 1:
  1346. Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]]
  1347. // Example 2:
  1348. Ext.zip(
  1349. [ "+", "-", "+"],
  1350. [ 12, 10, 22],
  1351. [ 43, 15, 96],
  1352. function(a, b, c){
  1353. return "$" + a + "" + b + "." + c
  1354. }
  1355. ); // ["$+12.43", "$-10.15", "$+22.96"]
  1356. * </code></pre>
  1357. * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values.
  1358. * @param {Function} zipper (optional) The last item in the argument list. This will drive how the items are zipped together.
  1359. * @return {Array} The zipped set.
  1360. */
  1361. zip : function(){
  1362. var parts = Ext.partition(arguments, function( val ){ return !Ext.isFunction(val); }),
  1363. arrs = parts[0],
  1364. fn = parts[1][0],
  1365. len = Ext.max(Ext.pluck(arrs, "length")),
  1366. ret = [];
  1367. for (var i = 0; i < len; i++) {
  1368. ret[i] = [];
  1369. if(fn){
  1370. ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
  1371. }else{
  1372. for (var j = 0, aLen = arrs.length; j < aLen; j++){
  1373. ret[i].push( arrs[j][i] );
  1374. }
  1375. }
  1376. }
  1377. return ret;
  1378. },
  1379. /**
  1380. * This is shorthand reference to {@link Ext.ComponentMgr#get}.
  1381. * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id}
  1382. * @param {String} id The component {@link Ext.Component#id id}
  1383. * @return Ext.Component The Component, <tt>undefined</tt> if not found, or <tt>null</tt> if a
  1384. * Class was found.
  1385. */
  1386. getCmp : function(id){
  1387. return Ext.ComponentMgr.get(id);
  1388. },
  1389. /**
  1390. * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
  1391. * you may want to set this to true.
  1392. * @type Boolean
  1393. */
  1394. useShims: E.isIE6 || (E.isMac && E.isGecko2),
  1395. // inpired by a similar function in mootools library
  1396. /**
  1397. * Returns the type of object that is passed in. If the object passed in is null or undefined it
  1398. * return false otherwise it returns one of the following values:<div class="mdetail-params"><ul>
  1399. * <li><b>string</b>: If the object passed is a string</li>
  1400. * <li><b>number</b>: If the object passed is a number</li>
  1401. * <li><b>boolean</b>: If the object passed is a boolean value</li>
  1402. * <li><b>date</b>: If the object passed is a Date object</li>
  1403. * <li><b>function</b>: If the object passed is a function reference</li>
  1404. * <li><b>object</b>: If the object passed is an object</li>
  1405. * <li><b>array</b>: If the object passed is an array</li>
  1406. * <li><b>regexp</b>: If the object passed is a regular expression</li>
  1407. * <li><b>element</b>: If the object passed is a DOM Element</li>
  1408. * <li><b>nodelist</b>: If the object passed is a DOM NodeList</li>
  1409. * <li><b>textnode</b>: If the object passed is a DOM text node and contains something other than whitespace</li>
  1410. * <li><b>whitespace</b>: If the object passed is a DOM text node and contains only whitespace</li>
  1411. * </ul></div>
  1412. * @param {Mixed} object
  1413. * @return {String}
  1414. */
  1415. type : function(o){
  1416. if(o === undefined || o === null){
  1417. return false;
  1418. }
  1419. if(o.htmlElement){
  1420. return 'element';
  1421. }
  1422. var t = typeof o;
  1423. if(t == 'object' && o.nodeName) {
  1424. switch(o.nodeType) {
  1425. case 1: return 'element';
  1426. case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
  1427. }
  1428. }
  1429. if(t == 'object' || t == 'function') {
  1430. switch(o.constructor) {
  1431. case Array: return 'array';
  1432. case RegExp: return 'regexp';
  1433. case Date: return 'date';
  1434. }
  1435. if(Ext.isNumber(o.length) && Ext.isFunction(o.item)) {
  1436. return 'nodelist';
  1437. }
  1438. }
  1439. return t;
  1440. },
  1441. intercept : function(o, name, fn, scope){
  1442. o[name] = o[name].createInterceptor(fn, scope);
  1443. },
  1444. // internal
  1445. callback : function(cb, scope, args, delay){
  1446. if(Ext.isFunction(cb)){
  1447. if(delay){
  1448. cb.defer(delay, scope, args || []);
  1449. }else{
  1450. cb.apply(scope, args || []);
  1451. }
  1452. }
  1453. }
  1454. };
  1455. }());
  1456. /**
  1457. * @class Function
  1458. * These functions are available on every Function object (any JavaScript function).
  1459. */
  1460. Ext.apply(Function.prototype, {
  1461. /**
  1462. * Create a combined function call sequence of the original function + the passed function.
  1463. * The resulting function returns the results of the original function.
  1464. * The passed fcn is called with the parameters of the original function. Example usage:
  1465. * <pre><code>
  1466. var sayHi = function(name){
  1467. alert('Hi, ' + name);
  1468. }
  1469. sayHi('Fred'); // alerts "Hi, Fred"
  1470. var sayGoodbye = sayHi.createSequence(function(name){
  1471. alert('Bye, ' + name);
  1472. });
  1473. sayGoodbye('Fred'); // both alerts show
  1474. </code></pre>
  1475. * @param {Function} fcn The function to sequence
  1476. * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
  1477. * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
  1478. * @return {Function} The new function
  1479. */
  1480. createSequence : function(fcn, scope){
  1481. var method = this;
  1482. return !Ext.isFunction(fcn) ?
  1483. this :
  1484. function(){
  1485. var retval = method.apply(this || window, arguments);
  1486. fcn.apply(scope || this || window, arguments);
  1487. return retval;
  1488. };
  1489. }
  1490. });
  1491. /**
  1492. * @class String
  1493. * These functions are available as static methods on the JavaScript String object.
  1494. */
  1495. Ext.applyIf(String, {
  1496. /**
  1497. * Escapes the passed string for ' and \
  1498. * @param {String} string The string to escape
  1499. * @return {String} The escaped string
  1500. * @static
  1501. */
  1502. escape : function(string) {
  1503. return string.replace(/('|\\)/g, "\\$1");
  1504. },
  1505. /**
  1506. * Pads the left side of a string with a specified character. This is especially useful
  1507. * for normalizing number and date strings. Example usage:
  1508. * <pre><code>
  1509. var s = String.leftPad('123', 5, '0');
  1510. // s now contains the string: '00123'
  1511. * </code></pre>
  1512. * @param {String} string The original string
  1513. * @param {Number} size The total length of the output string
  1514. * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
  1515. * @return {String} The padded string
  1516. * @static
  1517. */
  1518. leftPad : function (val, size, ch) {
  1519. var result = String(val);
  1520. if(!ch) {
  1521. ch = " ";
  1522. }
  1523. while (result.length < size) {
  1524. result = ch + result;
  1525. }
  1526. return result;
  1527. }
  1528. });
  1529. /**
  1530. * Utility function that allows you to easily switch a string between two alternating values. The passed value
  1531. * is compared to the current string, and if they are equal, the other value that was passed in is returned. If
  1532. * they are already different, the first value passed in is returned. Note that this method returns the new value
  1533. * but does not change the current string.
  1534. * <pre><code>
  1535. // alternate sort directions
  1536. sort = sort.toggle('ASC', 'DESC');
  1537. // instead of conditional logic:
  1538. sort = (sort == 'ASC' ? 'DESC' : 'ASC');
  1539. </code></pre>
  1540. * @param {String} value The value to compare to the current string
  1541. * @param {String} other The new value to use if the string already equals the first value passed in
  1542. * @return {String} The new value
  1543. */
  1544. String.prototype.toggle = function(value, other){
  1545. return this == value ? other : value;
  1546. };
  1547. /**
  1548. * Trims whitespace from either end of a string, leaving spaces within the string intact. Example:
  1549. * <pre><code>
  1550. var s = ' foo bar ';
  1551. alert('-' + s + '-'); //alerts "- foo bar -"
  1552. alert('-' + s.trim() + '-'); //alerts "-foo bar-"
  1553. </code></pre>
  1554. * @return {String} The trimmed string
  1555. */
  1556. String.prototype.trim = function(){
  1557. var re = /^\s+|\s+$/g;
  1558. return function(){ return this.replace(re, ""); };
  1559. }();
  1560. // here to prevent dependency on Date.js
  1561. /**
  1562. Returns the number of milliseconds between this date and date
  1563. @param {Date} date (optional) Defaults to now
  1564. @return {Number} The diff in milliseconds
  1565. @member Date getElapsed
  1566. */
  1567. Date.prototype.getElapsed = function(date) {
  1568. return Math.abs((date || new Date()).getTime()-this.getTime());
  1569. };
  1570. /**
  1571. * @class Number
  1572. */
  1573. Ext.applyIf(Number.prototype, {
  1574. /**
  1575. * Checks whether or not the current number is within a desired range. If the number is already within the
  1576. * range it is returned, otherwise the min or max value is returned depending on which side of the range is
  1577. * exceeded. Note that this method returns the constrained value but does not change the current number.
  1578. * @param {Number} min The minimum number in the range
  1579. * @param {Number} max The maximum number in the range
  1580. * @return {Number} The constrained value if outside the range, otherwise the current value
  1581. */
  1582. constrain : function(min, max){
  1583. return Math.min(Math.max(this, min), max);
  1584. }
  1585. });
  1586. /**
  1587. * @class Ext.util.TaskRunner
  1588. * Provides the ability to execute one or more arbitrary tasks in a multithreaded
  1589. * manner. Generally, you can use the singleton {@link Ext.TaskMgr} instead, but
  1590. * if needed, you can create separate instances of TaskRunner. Any number of
  1591. * separate tasks can be started at any time and will run independently of each
  1592. * other. Example usage:
  1593. * <pre><code>
  1594. // Start a simple clock task that updates a div once per second
  1595. var updateClock = function(){
  1596. Ext.fly('clock').update(new Date().format('g:i:s A'));
  1597. }
  1598. var task = {
  1599. run: updateClock,
  1600. interval: 1000 //1 second
  1601. }
  1602. var runner = new Ext.util.TaskRunner();
  1603. runner.start(task);
  1604. // equivalent using TaskMgr
  1605. Ext.TaskMgr.start({
  1606. run: updateClock,
  1607. interval: 1000
  1608. });
  1609. * </code></pre>
  1610. * <p>See the {@link #start} method for details about how to configure a task object.</p>
  1611. * Also see {@link Ext.util.DelayedTask}.
  1612. *
  1613. * @constructor
  1614. * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance
  1615. * (defaults to 10)
  1616. */
  1617. Ext.util.TaskRunner = function(interval){
  1618. interval = interval || 10;
  1619. var tasks = [],
  1620. removeQueue = [],
  1621. id = 0,
  1622. running = false,
  1623. // private
  1624. stopThread = function(){
  1625. running = false;
  1626. clearInterval(id);
  1627. id = 0;
  1628. },
  1629. // private
  1630. startThread = function(){
  1631. if(!running){
  1632. running = true;
  1633. id = setInterval(runTasks, interval);
  1634. }
  1635. },
  1636. // private
  1637. removeTask = function(t){
  1638. removeQueue.push(t);
  1639. if(t.onStop){
  1640. t.onStop.apply(t.scope || t);
  1641. }
  1642. },
  1643. // private
  1644. runTasks = function(){
  1645. var rqLen = removeQueue.length,
  1646. now = new Date().getTime();
  1647. if(rqLen > 0){
  1648. for(var i = 0; i < rqLen; i++){
  1649. tasks.remove(removeQueue[i]);
  1650. }
  1651. removeQueue = [];
  1652. if(tasks.length < 1){
  1653. stopThread();
  1654. return;
  1655. }
  1656. }
  1657. for(var i = 0, t, itime, rt, len = tasks.length; i < len; ++i){
  1658. t = tasks[i];
  1659. itime = now - t.taskRunTime;
  1660. if(t.interval <= itime){
  1661. rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
  1662. t.taskRunTime = now;
  1663. if(rt === false || t.taskRunCount === t.repeat){
  1664. removeTask(t);
  1665. return;
  1666. }
  1667. }
  1668. if(t.duration && t.duration <= (now - t.taskStartTime)){
  1669. removeTask(t);
  1670. }
  1671. }
  1672. };
  1673. /**
  1674. * Starts a new task.
  1675. * @method start
  1676. * @param {Object} task <p>A config object that supports the following properties:<ul>
  1677. * <li><code>run</code> : Function<div class="sub-desc"><p>The function to execute each time the task is invoked. The
  1678. * function will be called at each interval and passed the <code>args</code> argument if specified, and the
  1679. * current invocation count if not.</p>
  1680. * <p>If a particular scope (<code>this</code> reference) is required, be sure to specify it using the <code>scope</code> argument.</p>
  1681. * <p>Return <code>false</code> from this function to terminate the task.</p></div></li>
  1682. * <li><code>interval</code> : Number<div class="sub-desc">The frequency in milliseconds with which the task
  1683. * should be invoked.</div></li>
  1684. * <li><code>args</code> : Array<div class="sub-desc">(optional) An array of arguments to be passed to the function
  1685. * specified by <code>run</code>. If not specified, the current invocation count is passed.</div></li>
  1686. * <li><code>scope</code> : Object<div class="sub-desc">(optional) The scope (<tt>this</tt> reference) in which to execute the
  1687. * <code>run</code> function. Defaults to the task config object.</div></li>
  1688. * <li><code>duration</code> : Number<div class="sub-desc">(optional) The length of time in milliseconds to invoke
  1689. * the task before stopping automatically (defaults to indefinite).</div></li>
  1690. * <li><code>repeat</code> : Number<div class="sub-desc">(optional) The number of times to invoke the task before
  1691. * stopping automatically (defaults to indefinite).</div></li>
  1692. * </ul></p>
  1693. * <p>Before each invocation, Ext injects the property <code>taskRunCount</code> into the task object so
  1694. * that calculations based on the repeat count can be performed.</p>
  1695. * @return {Object} The task
  1696. */
  1697. this.start = function(task){
  1698. tasks.push(task);
  1699. task.taskStartTime = new Date().getTime();
  1700. task.taskRunTime = 0;
  1701. task.taskRunCount = 0;
  1702. startThread();
  1703. return task;
  1704. };
  1705. /**
  1706. * Stops an existing running task.
  1707. * @method stop
  1708. * @param {Object} task The task to stop
  1709. * @return {Object} The task
  1710. */
  1711. this.stop = function(task){
  1712. removeTask(task);
  1713. return task;
  1714. };
  1715. /**
  1716. * Stops all tasks that are currently running.
  1717. * @method stopAll
  1718. */
  1719. this.stopAll = function(){
  1720. stopThread();
  1721. for(var i = 0, len = tasks.length; i < len; i++){
  1722. if(tasks[i].onStop){
  1723. tasks[i].onStop();
  1724. }
  1725. }
  1726. tasks = [];
  1727. removeQueue = [];
  1728. };
  1729. };
  1730. /**
  1731. * @class Ext.TaskMgr
  1732. * @extends Ext.util.TaskRunner
  1733. * A static {@link Ext.util.TaskRunner} instance that can be used to start and stop arbitrary tasks. See
  1734. * {@link Ext.util.TaskRunner} for supported methods and task config properties.
  1735. * <pre><code>
  1736. // Start a simple clock task that updates a div once per second
  1737. var task = {
  1738. run: function(){
  1739. Ext.fly('clock').update(new Date().format('g:i:s A'));
  1740. },
  1741. interval: 1000 //1 second
  1742. }
  1743. Ext.TaskMgr.start(task);
  1744. </code></pre>
  1745. * <p>See the {@link #start} method for details about how to configure a task object.</p>
  1746. * @singleton
  1747. */
  1748. Ext.TaskMgr = new Ext.util.TaskRunner();(function(){
  1749. var libFlyweight;
  1750. function fly(el) {
  1751. if (!libFlyweight) {
  1752. libFlyweight = new Ext.Element.Flyweight();
  1753. }
  1754. libFlyweight.dom = el;
  1755. return libFlyweight;
  1756. }
  1757. (function(){
  1758. var doc = document,
  1759. isCSS1 = doc.compatMode == "CSS1Compat",
  1760. MAX = Math.max,
  1761. ROUND = Math.round,
  1762. PARSEINT = parseInt;
  1763. Ext.lib.Dom = {
  1764. isAncestor : function(p, c) {
  1765. var ret = false;
  1766. p = Ext.getDom(p);
  1767. c = Ext.getDom(c);
  1768. if (p && c) {
  1769. if (p.contains) {
  1770. return p.contains(c);
  1771. } else if (p.compareDocumentPosition) {
  1772. return !!(p.compareDocumentPosition(c) & 16);
  1773. } else {
  1774. while (c = c.parentNode) {
  1775. ret = c == p || ret;
  1776. }
  1777. }
  1778. }
  1779. return ret;
  1780. },
  1781. getViewWidth : function(full) {
  1782. return full ? this.getDocumentWidth() : this.getViewportWidth();
  1783. },
  1784. getViewHeight : function(full) {
  1785. return full ? this.getDocumentHeight() : this.getViewportHeight();
  1786. },
  1787. getDocumentHeight: function() {
  1788. return MAX(!isCSS1 ? doc.body.scrollHeight : doc.documentElement.scrollHeight, this.getViewportHeight());
  1789. },
  1790. getDocumentWidth: function() {
  1791. return MAX(!isCSS1 ? doc.body.scrollWidth : doc.documentElement.scrollWidth, this.getViewportWidth());
  1792. },
  1793. getViewportHeight: function(){
  1794. return Ext.isIE ?
  1795. (Ext.isStrict ? doc.documentElement.clientHeight : doc.body.clientHeight) :
  1796. self.innerHeight;
  1797. },
  1798. getViewportWidth : function() {
  1799. return !Ext.isStrict && !Ext.isOpera ? doc.body.clientWidth :
  1800. Ext.isIE ? doc.documentElement.clientWidth : self.innerWidth;
  1801. },
  1802. getY : function(el) {
  1803. return this.getXY(el)[1];
  1804. },
  1805. getX : function(el) {
  1806. return this.getXY(el)[0];
  1807. },
  1808. getXY : function(el) {
  1809. var p,
  1810. pe,
  1811. b,
  1812. bt,
  1813. bl,
  1814. dbd,
  1815. x = 0,
  1816. y = 0,
  1817. scroll,
  1818. hasAbsolute,
  1819. bd = (doc.body || doc.documentElement),
  1820. ret = [0,0];
  1821. el = Ext.getDom(el);
  1822. if(el != bd){
  1823. if (el.getBoundingClientRect) {
  1824. b = el.getBoundingClientRect();
  1825. scroll = fly(document).getScroll();
  1826. ret = [ROUND(b.left + scroll.left), ROUND(b.top + scroll.top)];
  1827. } else {
  1828. p = el;
  1829. hasAbsolute = fly(el).isStyle("position", "absolute");
  1830. while (p) {
  1831. pe = fly(p);
  1832. x += p.offsetLeft;
  1833. y += p.offsetTop;
  1834. hasAbsolute = hasAbsolute || pe.isStyle("position", "absolute");
  1835. if (Ext.isGecko) {
  1836. y += bt = PARSEINT(pe.getStyle("borderTopWidth"), 10) || 0;
  1837. x += bl = PARSEINT(pe.getStyle("borderLeftWidth"), 10) || 0;
  1838. if (p != el && !pe.isStyle('overflow','visible')) {
  1839. x += bl;
  1840. y += bt;
  1841. }
  1842. }
  1843. p = p.offsetParent;
  1844. }
  1845. if (Ext.isSafari && hasAbsolute) {
  1846. x -= bd.offsetLeft;
  1847. y -= bd.offsetTop;
  1848. }
  1849. if (Ext.isGecko && !hasAbsolute) {
  1850. dbd = fly(bd);
  1851. x += PARSEINT(dbd.getStyle("borderLeftWidth"), 10) || 0;
  1852. y += PARSEINT(dbd.getStyle("borderTopWidth"), 10) || 0;
  1853. }
  1854. p = el.parentNode;
  1855. while (p && p != bd) {
  1856. if (!Ext.isOpera || (p.tagName != 'TR' && !fly(p).isStyle("display", "inline"))) {
  1857. x -= p.scrollLeft;
  1858. y -= p.scrollTop;
  1859. }
  1860. p = p.parentNode;
  1861. }
  1862. ret = [x,y];
  1863. }
  1864. }
  1865. return ret
  1866. },
  1867. setXY : function(el, xy) {
  1868. (el = Ext.fly(el, '_setXY')).position();
  1869. var pts = el.translatePoints(xy),
  1870. style = el.dom.style,
  1871. pos;
  1872. for (pos in pts) {
  1873. if(!isNaN(pts[pos])) style[pos] = pts[pos] + "px"
  1874. }
  1875. },
  1876. setX : function(el, x) {
  1877. this.setXY(el, [x, false]);
  1878. },
  1879. setY : function(el, y) {
  1880. this.setXY(el, [false, y]);
  1881. }
  1882. };
  1883. })();Ext.lib.Dom.getRegion = function(el) {
  1884. return Ext.lib.Region.getRegion(el);
  1885. };Ext.lib.Event = function() {
  1886. var loadComplete = false,
  1887. unloadListeners = {},
  1888. retryCount = 0,
  1889. onAvailStack = [],
  1890. _interval,
  1891. locked = false,
  1892. win = window,
  1893. doc = document,
  1894. // constants
  1895. POLL_RETRYS = 200,
  1896. POLL_INTERVAL = 20,
  1897. EL = 0,
  1898. TYPE = 0,
  1899. FN = 1,
  1900. WFN = 2,
  1901. OBJ = 2,
  1902. ADJ_SCOPE = 3,
  1903. SCROLLLEFT = 'scrollLeft',
  1904. SCROLLTOP = 'scrollTop',
  1905. UNLOAD = 'unload',
  1906. MOUSEOVER = 'mouseover',
  1907. MOUSEOUT = 'mouseout',
  1908. // private
  1909. doAdd = function() {
  1910. var ret;
  1911. if (win.addEventListener) {
  1912. ret = function(el, eventName, fn, capture) {
  1913. if (eventName == 'mouseenter') {
  1914. fn = fn.createInterceptor(checkRelatedTarget);
  1915. el.addEventListener(MOUSEOVER, fn, (capture));
  1916. } else if (eventName == 'mouseleave') {
  1917. fn = fn.createInterceptor(checkRelatedTarget);
  1918. el.addEventListener(MOUSEOUT, fn, (capture));
  1919. } else {
  1920. el.addEventListener(eventName, fn, (capture));
  1921. }
  1922. return fn;
  1923. };
  1924. } else if (win.attachEvent) {
  1925. ret = function(el, eventName, fn, capture) {
  1926. el.attachEvent("on" + eventName, fn);
  1927. return fn;
  1928. };
  1929. } else {
  1930. ret = function(){};
  1931. }
  1932. return ret;
  1933. }(),
  1934. // private
  1935. doRemove = function(){
  1936. var ret;
  1937. if (win.removeEventListener) {
  1938. ret = function (el, eventName, fn, capture) {
  1939. if (eventName == 'mouseenter') {
  1940. eventName = MOUSEOVER;
  1941. } else if (eventName == 'mouseleave') {
  1942. eventName = MOUSEOUT;
  1943. }
  1944. el.removeEventListener(eventName, fn, (capture));
  1945. };
  1946. } else if (win.detachEvent) {
  1947. ret = function (el, eventName, fn) {
  1948. el.detachEvent("on" + eventName, fn);
  1949. };
  1950. } else {
  1951. ret = function(){};
  1952. }
  1953. return ret;
  1954. }();
  1955. function checkRelatedTarget(e) {
  1956. return !elContains(e.currentTarget, pub.getRelatedTarget(e));
  1957. }
  1958. function elContains(parent, child) {
  1959. if(parent && parent.firstChild){
  1960. while(child) {
  1961. if(child === parent) {
  1962. return true;
  1963. }
  1964. child = child.parentNode;
  1965. if(child && (child.nodeType != 1)) {
  1966. child = null;
  1967. }
  1968. }
  1969. }
  1970. return false;
  1971. }
  1972. // private
  1973. function _tryPreloadAttach() {
  1974. var ret = false,
  1975. notAvail = [],
  1976. element, i, len, v,
  1977. tryAgain = !loadComplete || (retryCount > 0);
  1978. if (!locked) {
  1979. locked = true;
  1980. for (i = 0, len = onAvailStack.length; i < len; i++) {
  1981. v = onAvailStack[i];
  1982. if(v && (element = doc.getElementById(v.id))){
  1983. if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) {
  1984. element = v.override ? (v.override === true ? v.obj : v.override) : element;
  1985. v.fn.call(element, v.obj);
  1986. onAvailStack.remove(v);
  1987. } else {
  1988. notAvail.push(v);
  1989. }
  1990. }
  1991. }
  1992. retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
  1993. if (tryAgain) {
  1994. startInterval();
  1995. } else {
  1996. clearInterval(_interval);
  1997. _interval = null;
  1998. }
  1999. ret = !(locked = false);
  2000. }
  2001. return ret;
  2002. }
  2003. // private
  2004. function startInterval() {
  2005. if(!_interval){
  2006. var callback = function() {
  2007. _tryPreloadAttach();
  2008. };
  2009. _interval = setInterval(callback, POLL_INTERVAL);
  2010. }
  2011. }
  2012. // private
  2013. function getScroll() {
  2014. var dd = doc.documentElement,
  2015. db = doc.body;
  2016. if(dd && (dd[SCROLLTOP] || dd[SCROLLLEFT])){
  2017. return [dd[SCROLLLEFT], dd[SCROLLTOP]];
  2018. }else if(db){
  2019. return [db[SCROLLLEFT], db[SCROLLTOP]];
  2020. }else{
  2021. return [0, 0];
  2022. }
  2023. }
  2024. // private
  2025. function getPageCoord (ev, xy) {
  2026. ev = ev.browserEvent || ev;
  2027. var coord = ev['page' + xy];
  2028. if (!coord && coord !== 0) {
  2029. coord = ev['client' + xy] || 0;
  2030. if (Ext.isIE) {
  2031. coord += getScroll()[xy == "X" ? 0 : 1];
  2032. }
  2033. }
  2034. return coord;
  2035. }
  2036. var pub = {
  2037. extAdapter: true,
  2038. onAvailable : function(p_id, p_fn, p_obj, p_override) {
  2039. onAvailStack.push({
  2040. id: p_id,
  2041. fn: p_fn,
  2042. obj: p_obj,
  2043. override: p_override,
  2044. checkReady: false });
  2045. retryCount = POLL_RETRYS;
  2046. startInterval();
  2047. },
  2048. // This function should ALWAYS be called from Ext.EventManager
  2049. addListener: function(el, eventName, fn) {
  2050. el = Ext.getDom(el);
  2051. if (el && fn) {
  2052. if (eventName == UNLOAD) {
  2053. if (unloadListeners[el.id] === undefined) {
  2054. unloadListeners[el.id] = [];
  2055. }
  2056. unloadListeners[el.id].push([eventName, fn]);
  2057. return fn;
  2058. }
  2059. return doAdd(el, eventName, fn, false);
  2060. }
  2061. return false;
  2062. },
  2063. // This function should ALWAYS be called from Ext.EventManager
  2064. removeListener: function(el, eventName, fn) {
  2065. el = Ext.getDom(el);
  2066. var i, len, li, lis;
  2067. if (el && fn) {
  2068. if(eventName == UNLOAD){
  2069. if((lis = unloadListeners[el.id]) !== undefined){
  2070. for(i = 0, len = lis.length; i < len; i++){
  2071. if((li = lis[i]) && li[TYPE] == eventName && li[FN] == fn){
  2072. unloadListeners[el.id].splice(i, 1);
  2073. }
  2074. }
  2075. }
  2076. return;
  2077. }
  2078. doRemove(el, eventName, fn, false);
  2079. }
  2080. },
  2081. getTarget : function(ev) {
  2082. ev = ev.browserEvent || ev;
  2083. return this.resolveTextNode(ev.target || ev.srcElement);
  2084. },
  2085. resolveTextNode : Ext.isGecko ? function(node){
  2086. if(!node){
  2087. return;
  2088. }
  2089. // work around firefox bug, https://bugzilla.mozilla.org/show_bug.cgi?id=101197
  2090. var s = HTMLElement.prototype.toString.call(node);
  2091. if(s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]'){
  2092. return;
  2093. }
  2094. return node.nodeType == 3 ? node.parentNode : node;
  2095. } : function(node){
  2096. return node && node.nodeType == 3 ? node.parentNode : node;
  2097. },
  2098. getRelatedTarget : function(ev) {
  2099. ev = ev.browserEvent || ev;
  2100. return this.resolveTextNode(ev.relatedTarget ||
  2101. (ev.type == MOUSEOUT ? ev.toElement :
  2102. ev.type == MOUSEOVER ? ev.fromElement : null));
  2103. },
  2104. getPageX : function(ev) {
  2105. return getPageCoord(ev, "X");
  2106. },
  2107. getPageY : function(ev) {
  2108. return getPageCoord(ev, "Y");
  2109. },
  2110. getXY : function(ev) {
  2111. return [this.getPageX(ev), this.getPageY(ev)];
  2112. },
  2113. stopEvent : function(ev) {
  2114. this.stopPropagation(ev);
  2115. this.preventDefault(ev);
  2116. },
  2117. stopPropagation : function(ev) {
  2118. ev = ev.browserEvent || ev;
  2119. if (ev.stopPropagation) {
  2120. ev.stopPropagation();
  2121. } else {
  2122. ev.cancelBubble = true;
  2123. }
  2124. },
  2125. preventDefault : function(ev) {
  2126. ev = ev.browserEvent || ev;
  2127. if (ev.preventDefault) {
  2128. ev.preventDefault();
  2129. } else {
  2130. ev.returnValue = false;
  2131. }
  2132. },
  2133. getEvent : function(e) {
  2134. e = e || win.event;
  2135. if (!e) {
  2136. var c = this.getEvent.caller;
  2137. while (c) {
  2138. e = c.arguments[0];
  2139. if (e && Event == e.constructor) {
  2140. break;
  2141. }
  2142. c = c.caller;
  2143. }
  2144. }
  2145. return e;
  2146. },
  2147. getCharCode : function(ev) {
  2148. ev = ev.browserEvent || ev;
  2149. return ev.charCode || ev.keyCode || 0;
  2150. },
  2151. //clearCache: function() {},
  2152. // deprecated, call from EventManager
  2153. getListeners : function(el, eventName) {
  2154. Ext.EventManager.getListeners(el, eventName);
  2155. },
  2156. // deprecated, call from EventManager
  2157. purgeElement : function(el, recurse, eventName) {
  2158. Ext.EventManager.purgeElement(el, recurse, eventName);
  2159. },
  2160. _load : function(e) {
  2161. loadComplete = true;
  2162. var EU = Ext.lib.Event;
  2163. if (Ext.isIE && e !== true) {
  2164. // IE8 complains that _load is null or not an object
  2165. // so lets remove self via arguments.callee
  2166. doRemove(win, "load", arguments.callee);
  2167. }
  2168. },
  2169. _unload : function(e) {
  2170. var EU = Ext.lib.Event,
  2171. i, j, l, v, ul, id, len, index, scope;
  2172. for (id in unloadListeners) {
  2173. ul = unloadListeners[id];
  2174. for (i = 0, len = ul.length; i < len; i++) {
  2175. v = ul[i];
  2176. if (v) {
  2177. try{
  2178. scope = v[ADJ_SCOPE] ? (v[ADJ_SCOPE] === true ? v[OBJ] : v[ADJ_SCOPE]) : win;
  2179. v[FN].call(scope, EU.getEvent(e), v[OBJ]);
  2180. }catch(ex){}
  2181. }
  2182. }
  2183. };
  2184. Ext.EventManager._unload();
  2185. doRemove(win, UNLOAD, EU._unload);
  2186. }
  2187. };
  2188. // Initialize stuff.
  2189. pub.on = pub.addListener;
  2190. pub.un = pub.removeListener;
  2191. if (doc && doc.body) {
  2192. pub._load(true);
  2193. } else {
  2194. doAdd(win, "load", pub._load);
  2195. }
  2196. doAdd(win, UNLOAD, pub._unload);
  2197. _tryPreloadAttach();
  2198. return pub;
  2199. }();
  2200. /*
  2201. * Portions of this file are based on pieces of Yahoo User Interface Library
  2202. * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
  2203. * YUI licensed under the BSD License:
  2204. * http://developer.yahoo.net/yui/license.txt
  2205. */
  2206. Ext.lib.Ajax = function() {
  2207. var activeX = ['MSXML2.XMLHTTP.3.0',
  2208. 'MSXML2.XMLHTTP',
  2209. 'Microsoft.XMLHTTP'],
  2210. CONTENTTYPE = 'Content-Type';
  2211. // private
  2212. function setHeader(o) {
  2213. var conn = o.conn,
  2214. prop;
  2215. function setTheHeaders(conn, headers){
  2216. for (prop in headers) {
  2217. if (headers.hasOwnProperty(prop)) {
  2218. conn.setRequestHeader(prop, headers[prop]);
  2219. }
  2220. }
  2221. }
  2222. if (pub.defaultHeaders) {
  2223. setTheHeaders(conn, pub.defaultHeaders);
  2224. }
  2225. if (pub.headers) {
  2226. setTheHeaders(conn, pub.headers);
  2227. delete pub.headers;
  2228. }
  2229. }
  2230. // private
  2231. function createExceptionObject(tId, callbackArg, isAbort, isTimeout) {
  2232. return {
  2233. tId : tId,
  2234. status : isAbort ? -1 : 0,
  2235. statusText : isAbort ? 'transaction aborted' : 'communication failure',
  2236. isAbort: isAbort,
  2237. isTimeout: isTimeout,
  2238. argument : callbackArg
  2239. };
  2240. }
  2241. // private
  2242. function initHeader(label, value) {
  2243. (pub.headers = pub.headers || {})[label] = value;
  2244. }
  2245. // private
  2246. function createResponseObject(o, callbackArg) {
  2247. var headerObj = {},
  2248. headerStr,
  2249. conn = o.conn,
  2250. t,
  2251. s,
  2252. // see: https://prototype.lighthouseapp.com/projects/8886/tickets/129-ie-mangles-http-response-status-code-204-to-1223
  2253. isBrokenStatus = conn.status == 1223;
  2254. try {
  2255. headerStr = o.conn.getAllResponseHeaders();
  2256. Ext.each(headerStr.replace(/\r\n/g, '\n').split('\n'), function(v){
  2257. t = v.indexOf(':');
  2258. if(t >= 0){
  2259. s = v.substr(0, t).toLowerCase();
  2260. if(v.charAt(t + 1) == ' '){
  2261. ++t;
  2262. }
  2263. headerObj[s] = v.substr(t + 1);
  2264. }
  2265. });
  2266. } catch(e) {}
  2267. return {
  2268. tId : o.tId,
  2269. // Normalize the status and statusText when IE returns 1223, see the above link.
  2270. status : isBrokenStatus ? 204 : conn.status,
  2271. statusText : isBrokenStatus ? 'No Content' : conn.statusText,
  2272. getResponseHeader : function(header){return headerObj[header.toLowerCase()];},
  2273. getAllResponseHeaders : function(){return headerStr},
  2274. responseText : conn.responseText,
  2275. responseXML : conn.responseXML,
  2276. argument : callbackArg
  2277. };
  2278. }
  2279. // private
  2280. function releaseObject(o) {
  2281. if (o.tId) {
  2282. pub.conn[o.tId] = null;
  2283. }
  2284. o.conn = null;
  2285. o = null;
  2286. }
  2287. // private
  2288. function handleTransactionResponse(o, callback, isAbort, isTimeout) {
  2289. if (!callback) {
  2290. releaseObject(o);
  2291. return;
  2292. }
  2293. var httpStatus, responseObject;
  2294. try {
  2295. if (o.conn.status !== undefined && o.conn.status != 0) {
  2296. httpStatus = o.conn.status;
  2297. }
  2298. else {
  2299. httpStatus = 13030;
  2300. }
  2301. }
  2302. catch(e) {
  2303. httpStatus = 13030;
  2304. }
  2305. if ((httpStatus >= 200 && httpStatus < 300) || (Ext.isIE && httpStatus == 1223)) {
  2306. responseObject = createResponseObject(o, callback.argument);
  2307. if (callback.success) {
  2308. if (!callback.scope) {
  2309. callback.success(responseObject);
  2310. }
  2311. else {
  2312. callback.success.apply(callback.scope, [responseObject]);
  2313. }
  2314. }
  2315. }
  2316. else {
  2317. switch (httpStatus) {
  2318. case 12002:
  2319. case 12029:
  2320. case 12030:
  2321. case 12031:
  2322. case 12152:
  2323. case 13030:
  2324. responseObject = createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false), isTimeout);
  2325. if (callback.failure) {
  2326. if (!callback.scope) {
  2327. callback.failure(responseObject);
  2328. }
  2329. else {
  2330. callback.failure.apply(callback.scope, [responseObject]);
  2331. }
  2332. }
  2333. break;
  2334. default:
  2335. responseObject = createResponseObject(o, callback.argument);
  2336. if (callback.failure) {
  2337. if (!callback.scope) {
  2338. callback.failure(responseObject);
  2339. }
  2340. else {
  2341. callback.failure.apply(callback.scope, [responseObject]);
  2342. }
  2343. }
  2344. }
  2345. }
  2346. releaseObject(o);
  2347. responseObject = null;
  2348. }
  2349. // private
  2350. function handleReadyState(o, callback){
  2351. callback = callback || {};
  2352. var conn = o.conn,
  2353. tId = o.tId,
  2354. poll = pub.poll,
  2355. cbTimeout = callback.timeout || null;
  2356. if (cbTimeout) {
  2357. pub.conn[tId] = conn;
  2358. pub.timeout[tId] = setTimeout(function() {
  2359. pub.abort(o, callback, true);
  2360. }, cbTimeout);
  2361. }
  2362. poll[tId] = setInterval(
  2363. function() {
  2364. if (conn && conn.readyState == 4) {
  2365. clearInterval(poll[tId]);
  2366. poll[tId] = null;
  2367. if (cbTimeout) {
  2368. clearTimeout(pub.timeout[tId]);
  2369. pub.timeout[tId] = null;
  2370. }
  2371. handleTransactionResponse(o, callback);
  2372. }
  2373. },
  2374. pub.pollInterval);
  2375. }
  2376. // private
  2377. function asyncRequest(method, uri, callback, postData) {
  2378. var o = getConnectionObject() || null;
  2379. if (o) {
  2380. o.conn.open(method, uri, true);
  2381. if (pub.useDefaultXhrHeader) {
  2382. initHeader('X-Requested-With', pub.defaultXhrHeader);
  2383. }
  2384. if(postData && pub.useDefaultHeader && (!pub.headers || !pub.headers[CONTENTTYPE])){
  2385. initHeader(CONTENTTYPE, pub.defaultPostHeader);
  2386. }
  2387. if (pub.defaultHeaders || pub.headers) {
  2388. setHeader(o);
  2389. }
  2390. handleReadyState(o, callback);
  2391. o.conn.send(postData || null);
  2392. }
  2393. return o;
  2394. }
  2395. // private
  2396. function getConnectionObject() {
  2397. var o;
  2398. try {
  2399. if (o = createXhrObject(pub.transactionId)) {
  2400. pub.transactionId++;
  2401. }
  2402. } catch(e) {
  2403. } finally {
  2404. return o;
  2405. }
  2406. }
  2407. // private
  2408. function createXhrObject(transactionId) {
  2409. var http;
  2410. try {
  2411. http = new XMLHttpRequest();
  2412. } catch(e) {
  2413. for (var i = 0; i < activeX.length; ++i) {
  2414. try {
  2415. http = new ActiveXObject(activeX[i]);
  2416. break;
  2417. } catch(e) {}
  2418. }
  2419. } finally {
  2420. return {conn : http, tId : transactionId};
  2421. }
  2422. }
  2423. var pub = {
  2424. request : function(method, uri, cb, data, options) {
  2425. if(options){
  2426. var me = this,
  2427. xmlData = options.xmlData,
  2428. jsonData = options.jsonData,
  2429. hs;
  2430. Ext.applyIf(me, options);
  2431. if(xmlData || jsonData){
  2432. hs = me.headers;
  2433. if(!hs || !hs[CONTENTTYPE]){
  2434. initHeader(CONTENTTYPE, xmlData ? 'text/xml' : 'application/json');
  2435. }
  2436. data = xmlData || (!Ext.isPrimitive(jsonData) ? Ext.encode(jsonData) : jsonData);
  2437. }
  2438. }
  2439. return asyncRequest(method || options.method || "POST", uri, cb, data);
  2440. },
  2441. serializeForm : function(form) {
  2442. var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,
  2443. hasSubmit = false,
  2444. encoder = encodeURIComponent,
  2445. element,
  2446. options,
  2447. name,
  2448. val,
  2449. data = '',
  2450. type;
  2451. Ext.each(fElements, function(element) {
  2452. name = element.name;
  2453. type = element.type;
  2454. if (!element.disabled && name){
  2455. if(/select-(one|multiple)/i.test(type)) {
  2456. Ext.each(element.options, function(opt) {
  2457. if (opt.selected) {
  2458. data += String.format("{0}={1}&", encoder(name), encoder((opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttribute('value') !== null) ? opt.value : opt.text));
  2459. }
  2460. });
  2461. } else if(!/file|undefined|reset|button/i.test(type)) {
  2462. if(!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)){
  2463. data += encoder(name) + '=' + encoder(element.value) + '&';
  2464. hasSubmit = /submit/i.test(type);
  2465. }
  2466. }
  2467. }
  2468. });
  2469. return data.substr(0, data.length - 1);
  2470. },
  2471. useDefaultHeader : true,
  2472. defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8',
  2473. useDefaultXhrHeader : true,
  2474. defaultXhrHeader : 'XMLHttpRequest',
  2475. poll : {},
  2476. timeout : {},
  2477. conn: {},
  2478. pollInterval : 50,
  2479. transactionId : 0,
  2480. // This is never called - Is it worth exposing this?
  2481. // setProgId : function(id) {
  2482. // activeX.unshift(id);
  2483. // },
  2484. // This is never called - Is it worth exposing this?
  2485. // setDefaultPostHeader : function(b) {
  2486. // this.useDefaultHeader = b;
  2487. // },
  2488. // This is never called - Is it worth exposing this?
  2489. // setDefaultXhrHeader : function(b) {
  2490. // this.useDefaultXhrHeader = b;
  2491. // },
  2492. // This is never called - Is it worth exposing this?
  2493. // setPollingInterval : function(i) {
  2494. // if (typeof i == 'number' && isFinite(i)) {
  2495. // this.pollInterval = i;
  2496. // }
  2497. // },
  2498. // This is never called - Is it worth exposing this?
  2499. // resetDefaultHeaders : function() {
  2500. // this.defaultHeaders = null;
  2501. // },
  2502. abort : function(o, callback, isTimeout) {
  2503. var me = this,
  2504. tId = o.tId,
  2505. isAbort = false;
  2506. if (me.isCallInProgress(o)) {
  2507. o.conn.abort();
  2508. clearInterval(me.poll[tId]);
  2509. me.poll[tId] = null;
  2510. clearTimeout(pub.timeout[tId]);
  2511. me.timeout[tId] = null;
  2512. handleTransactionResponse(o, callback, (isAbort = true), isTimeout);
  2513. }
  2514. return isAbort;
  2515. },
  2516. isCallInProgress : function(o) {
  2517. // if there is a connection and readyState is not 0 or 4
  2518. return o.conn && !{0:true,4:true}[o.conn.readyState];
  2519. }
  2520. };
  2521. return pub;
  2522. }(); Ext.lib.Region = function(t, r, b, l) {
  2523. var me = this;
  2524. me.top = t;
  2525. me[1] = t;
  2526. me.right = r;
  2527. me.bottom = b;
  2528. me.left = l;
  2529. me[0] = l;
  2530. };
  2531. Ext.lib.Region.prototype = {
  2532. contains : function(region) {
  2533. var me = this;
  2534. return ( region.left >= me.left &&
  2535. region.right <= me.right &&
  2536. region.top >= me.top &&
  2537. region.bottom <= me.bottom );
  2538. },
  2539. getArea : function() {
  2540. var me = this;
  2541. return ( (me.bottom - me.top) * (me.right - me.left) );
  2542. },
  2543. intersect : function(region) {
  2544. var me = this,
  2545. t = Math.max(me.top, region.top),
  2546. r = Math.min(me.right, region.right),
  2547. b = Math.min(me.bottom, region.bottom),
  2548. l = Math.max(me.left, region.left);
  2549. if (b >= t && r >= l) {
  2550. return new Ext.lib.Region(t, r, b, l);
  2551. }
  2552. },
  2553. union : function(region) {
  2554. var me = this,
  2555. t = Math.min(me.top, region.top),
  2556. r = Math.max(me.right, region.right),
  2557. b = Math.max(me.bottom, region.bottom),
  2558. l = Math.min(me.left, region.left);
  2559. return new Ext.lib.Region(t, r, b, l);
  2560. },
  2561. constrainTo : function(r) {
  2562. var me = this;
  2563. me.top = me.top.constrain(r.top, r.bottom);
  2564. me.bottom = me.bottom.constrain(r.top, r.bottom);
  2565. me.left = me.left.constrain(r.left, r.right);
  2566. me.right = me.right.constrain(r.left, r.right);
  2567. return me;
  2568. },
  2569. adjust : function(t, l, b, r) {
  2570. var me = this;
  2571. me.top += t;
  2572. me.left += l;
  2573. me.right += r;
  2574. me.bottom += b;
  2575. return me;
  2576. }
  2577. };
  2578. Ext.lib.Region.getRegion = function(el) {
  2579. var p = Ext.lib.Dom.getXY(el),
  2580. t = p[1],
  2581. r = p[0] + el.offsetWidth,
  2582. b = p[1] + el.offsetHeight,
  2583. l = p[0];
  2584. return new Ext.lib.Region(t, r, b, l);
  2585. }; Ext.lib.Point = function(x, y) {
  2586. if (Ext.isArray(x)) {
  2587. y = x[1];
  2588. x = x[0];
  2589. }
  2590. var me = this;
  2591. me.x = me.right = me.left = me[0] = x;
  2592. me.y = me.top = me.bottom = me[1] = y;
  2593. };
  2594. Ext.lib.Point.prototype = new Ext.lib.Region();
  2595. (function(){
  2596. var EXTLIB = Ext.lib,
  2597. noNegatives = /width|height|opacity|padding/i,
  2598. offsetAttribute = /^((width|height)|(top|left))$/,
  2599. defaultUnit = /width|height|top$|bottom$|left$|right$/i,
  2600. offsetUnit = /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i,
  2601. isset = function(v){
  2602. return typeof v !== 'undefined';
  2603. },
  2604. now = function(){
  2605. return new Date();
  2606. };
  2607. EXTLIB.Anim = {
  2608. motion : function(el, args, duration, easing, cb, scope) {
  2609. return this.run(el, args, duration, easing, cb, scope, Ext.lib.Motion);
  2610. },
  2611. run : function(el, args, duration, easing, cb, scope, type) {
  2612. type = type || Ext.lib.AnimBase;
  2613. if (typeof easing == "string") {
  2614. easing = Ext.lib.Easing[easing];
  2615. }
  2616. var anim = new type(el, args, duration, easing);
  2617. anim.animateX(function() {
  2618. if(Ext.isFunction(cb)){
  2619. cb.call(scope);
  2620. }
  2621. });
  2622. return anim;
  2623. }
  2624. };
  2625. EXTLIB.AnimBase = function(el, attributes, duration, method) {
  2626. if (el) {
  2627. this.init(el, attributes, duration, method);
  2628. }
  2629. };
  2630. EXTLIB.AnimBase.prototype = {
  2631. doMethod: function(attr, start, end) {
  2632. var me = this;
  2633. return me.method(me.curFrame, start, end - start, me.totalFrames);
  2634. },
  2635. setAttr: function(attr, val, unit) {
  2636. if (noNegatives.test(attr) && val < 0) {
  2637. val = 0;
  2638. }
  2639. Ext.fly(this.el, '_anim').setStyle(attr, val + unit);
  2640. },
  2641. getAttr: function(attr) {
  2642. var el = Ext.fly(this.el),
  2643. val = el.getStyle(attr),
  2644. a = offsetAttribute.exec(attr) || [];
  2645. if (val !== 'auto' && !offsetUnit.test(val)) {
  2646. return parseFloat(val);
  2647. }
  2648. return (!!(a[2]) || (el.getStyle('position') == 'absolute' && !!(a[3]))) ? el.dom['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)] : 0;
  2649. },
  2650. getDefaultUnit: function(attr) {
  2651. return defaultUnit.test(attr) ? 'px' : '';
  2652. },
  2653. animateX : function(callback, scope) {
  2654. var me = this,
  2655. f = function() {
  2656. me.onComplete.removeListener(f);
  2657. if (Ext.isFunction(callback)) {
  2658. callback.call(scope || me, me);
  2659. }
  2660. };
  2661. me.onComplete.addListener(f, me);
  2662. me.animate();
  2663. },
  2664. setRunAttr: function(attr) {
  2665. var me = this,
  2666. a = this.attributes[attr],
  2667. to = a.to,
  2668. by = a.by,
  2669. from = a.from,
  2670. unit = a.unit,
  2671. ra = (this.runAttrs[attr] = {}),
  2672. end;
  2673. if (!isset(to) && !isset(by)){
  2674. return false;
  2675. }
  2676. var start = isset(from) ? from : me.getAttr(attr);
  2677. if (isset(to)) {
  2678. end = to;
  2679. }else if(isset(by)) {
  2680. if (Ext.isArray(start)){
  2681. end = [];
  2682. for(var i=0,len=start.length; i<len; i++) {
  2683. end[i] = start[i] + by[i];
  2684. }
  2685. }else{
  2686. end = start + by;
  2687. }
  2688. }
  2689. Ext.apply(ra, {
  2690. start: start,
  2691. end: end,
  2692. unit: isset(unit) ? unit : me.getDefaultUnit(attr)
  2693. });
  2694. },
  2695. init: function(el, attributes, duration, method) {
  2696. var me = this,
  2697. actualFrames = 0,
  2698. mgr = EXTLIB.AnimMgr;
  2699. Ext.apply(me, {
  2700. isAnimated: false,
  2701. startTime: null,
  2702. el: Ext.getDom(el),
  2703. attributes: attributes || {},
  2704. duration: duration || 1,
  2705. method: method || EXTLIB.Easing.easeNone,
  2706. useSec: true,
  2707. curFrame: 0,
  2708. totalFrames: mgr.fps,
  2709. runAttrs: {},
  2710. animate: function(){
  2711. var me = this,
  2712. d = me.duration;
  2713. if(me.isAnimated){
  2714. return false;
  2715. }
  2716. me.curFrame = 0;
  2717. me.totalFrames = me.useSec ? Math.ceil(mgr.fps * d) : d;
  2718. mgr.registerElement(me);
  2719. },
  2720. stop: function(finish){
  2721. var me = this;
  2722. if(finish){
  2723. me.curFrame = me.totalFrames;
  2724. me._onTween.fire();
  2725. }
  2726. mgr.stop(me);
  2727. }
  2728. });
  2729. var onStart = function(){
  2730. var me = this,
  2731. attr;
  2732. me.onStart.fire();
  2733. me.runAttrs = {};
  2734. for(attr in this.attributes){
  2735. this.setRunAttr(attr);
  2736. }
  2737. me.isAnimated = true;
  2738. me.startTime = now();
  2739. actualFrames = 0;
  2740. };
  2741. var onTween = function(){
  2742. var me = this;
  2743. me.onTween.fire({
  2744. duration: now() - me.startTime,
  2745. curFrame: me.curFrame
  2746. });
  2747. var ra = me.runAttrs;
  2748. for (var attr in ra) {
  2749. this.setAttr(attr, me.doMethod(attr, ra[attr].start, ra[attr].end), ra[attr].unit);
  2750. }
  2751. ++actualFrames;
  2752. };
  2753. var onComplete = function() {
  2754. var me = this,
  2755. actual = (now() - me.startTime) / 1000,
  2756. data = {
  2757. duration: actual,
  2758. frames: actualFrames,
  2759. fps: actualFrames / actual
  2760. };
  2761. me.isAnimated = false;
  2762. actualFrames = 0;
  2763. me.onComplete.fire(data);
  2764. };
  2765. me.onStart = new Ext.util.Event(me);
  2766. me.onTween = new Ext.util.Event(me);
  2767. me.onComplete = new Ext.util.Event(me);
  2768. (me._onStart = new Ext.util.Event(me)).addListener(onStart);
  2769. (me._onTween = new Ext.util.Event(me)).addListener(onTween);
  2770. (me._onComplete = new Ext.util.Event(me)).addListener(onComplete);
  2771. }
  2772. };
  2773. Ext.lib.AnimMgr = new function() {
  2774. var me = this,
  2775. thread = null,
  2776. queue = [],
  2777. tweenCount = 0;
  2778. Ext.apply(me, {
  2779. fps: 1000,
  2780. delay: 1,
  2781. registerElement: function(tween){
  2782. queue.push(tween);
  2783. ++tweenCount;
  2784. tween._onStart.fire();
  2785. me.start();
  2786. },
  2787. unRegister: function(tween, index){
  2788. tween._onComplete.fire();
  2789. index = index || getIndex(tween);
  2790. if (index != -1) {
  2791. queue.splice(index, 1);
  2792. }
  2793. if (--tweenCount <= 0) {
  2794. me.stop();
  2795. }
  2796. },
  2797. start: function(){
  2798. if(thread === null){
  2799. thread = setInterval(me.run, me.delay);
  2800. }
  2801. },
  2802. stop: function(tween){
  2803. if(!tween){
  2804. clearInterval(thread);
  2805. for(var i = 0, len = queue.length; i < len; ++i){
  2806. if(queue[0].isAnimated){
  2807. me.unRegister(queue[0], 0);
  2808. }
  2809. }
  2810. queue = [];
  2811. thread = null;
  2812. tweenCount = 0;
  2813. }else{
  2814. me.unRegister(tween);
  2815. }
  2816. },
  2817. run: function(){
  2818. var tf, i, len, tween;
  2819. for(i = 0, len = queue.length; i<len; i++) {
  2820. tween = queue[i];
  2821. if(tween && tween.isAnimated){
  2822. tf = tween.totalFrames;
  2823. if(tween.curFrame < tf || tf === null){
  2824. ++tween.curFrame;
  2825. if(tween.useSec){
  2826. correctFrame(tween);
  2827. }
  2828. tween._onTween.fire();
  2829. }else{
  2830. me.stop(tween);
  2831. }
  2832. }
  2833. }
  2834. }
  2835. });
  2836. var getIndex = function(anim) {
  2837. var i, len;
  2838. for(i = 0, len = queue.length; i<len; i++) {
  2839. if(queue[i] === anim) {
  2840. return i;
  2841. }
  2842. }
  2843. return -1;
  2844. };
  2845. var correctFrame = function(tween) {
  2846. var frames = tween.totalFrames,
  2847. frame = tween.curFrame,
  2848. duration = tween.duration,
  2849. expected = (frame * duration * 1000 / frames),
  2850. elapsed = (now() - tween.startTime),
  2851. tweak = 0;
  2852. if(elapsed < duration * 1000){
  2853. tweak = Math.round((elapsed / expected - 1) * frame);
  2854. }else{
  2855. tweak = frames - (frame + 1);
  2856. }
  2857. if(tweak > 0 && isFinite(tweak)){
  2858. if(tween.curFrame + tweak >= frames){
  2859. tweak = frames - (frame + 1);
  2860. }
  2861. tween.curFrame += tweak;
  2862. }
  2863. };
  2864. };
  2865. EXTLIB.Bezier = new function() {
  2866. this.getPosition = function(points, t) {
  2867. var n = points.length,
  2868. tmp = [],
  2869. c = 1 - t,
  2870. i,
  2871. j;
  2872. for (i = 0; i < n; ++i) {
  2873. tmp[i] = [points[i][0], points[i][1]];
  2874. }
  2875. for (j = 1; j < n; ++j) {
  2876. for (i = 0; i < n - j; ++i) {
  2877. tmp[i][0] = c * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
  2878. tmp[i][1] = c * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
  2879. }
  2880. }
  2881. return [ tmp[0][0], tmp[0][1] ];
  2882. };
  2883. };
  2884. EXTLIB.Easing = {
  2885. easeNone: function (t, b, c, d) {
  2886. return c * t / d + b;
  2887. },
  2888. easeIn: function (t, b, c, d) {
  2889. return c * (t /= d) * t + b;
  2890. },
  2891. easeOut: function (t, b, c, d) {
  2892. return -c * (t /= d) * (t - 2) + b;
  2893. }
  2894. };
  2895. (function() {
  2896. EXTLIB.Motion = function(el, attributes, duration, method) {
  2897. if (el) {
  2898. EXTLIB.Motion.superclass.constructor.call(this, el, attributes, duration, method);
  2899. }
  2900. };
  2901. Ext.extend(EXTLIB.Motion, Ext.lib.AnimBase);
  2902. var superclass = EXTLIB.Motion.superclass,
  2903. proto = EXTLIB.Motion.prototype,
  2904. pointsRe = /^points$/i;
  2905. Ext.apply(EXTLIB.Motion.prototype, {
  2906. setAttr: function(attr, val, unit){
  2907. var me = this,
  2908. setAttr = superclass.setAttr;
  2909. if (pointsRe.test(attr)) {
  2910. unit = unit || 'px';
  2911. setAttr.call(me, 'left', val[0], unit);
  2912. setAttr.call(me, 'top', val[1], unit);
  2913. } else {
  2914. setAttr.call(me, attr, val, unit);
  2915. }
  2916. },
  2917. getAttr: function(attr){
  2918. var me = this,
  2919. getAttr = superclass.getAttr;
  2920. return pointsRe.test(attr) ? [getAttr.call(me, 'left'), getAttr.call(me, 'top')] : getAttr.call(me, attr);
  2921. },
  2922. doMethod: function(attr, start, end){
  2923. var me = this;
  2924. return pointsRe.test(attr)
  2925. ? EXTLIB.Bezier.getPosition(me.runAttrs[attr], me.method(me.curFrame, 0, 100, me.totalFrames) / 100)
  2926. : superclass.doMethod.call(me, attr, start, end);
  2927. },
  2928. setRunAttr: function(attr){
  2929. if(pointsRe.test(attr)){
  2930. var me = this,
  2931. el = this.el,
  2932. points = this.attributes.points,
  2933. control = points.control || [],
  2934. from = points.from,
  2935. to = points.to,
  2936. by = points.by,
  2937. DOM = EXTLIB.Dom,
  2938. start,
  2939. i,
  2940. end,
  2941. len,
  2942. ra;
  2943. if(control.length > 0 && !Ext.isArray(control[0])){
  2944. control = [control];
  2945. }else{
  2946. /*
  2947. var tmp = [];
  2948. for (i = 0,len = control.length; i < len; ++i) {
  2949. tmp[i] = control[i];
  2950. }
  2951. control = tmp;
  2952. */
  2953. }
  2954. Ext.fly(el, '_anim').position();
  2955. DOM.setXY(el, isset(from) ? from : DOM.getXY(el));
  2956. start = me.getAttr('points');
  2957. if(isset(to)){
  2958. end = translateValues.call(me, to, start);
  2959. for (i = 0,len = control.length; i < len; ++i) {
  2960. control[i] = translateValues.call(me, control[i], start);
  2961. }
  2962. } else if (isset(by)) {
  2963. end = [start[0] + by[0], start[1] + by[1]];
  2964. for (i = 0,len = control.length; i < len; ++i) {
  2965. control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
  2966. }
  2967. }
  2968. ra = this.runAttrs[attr] = [start];
  2969. if (control.length > 0) {
  2970. ra = ra.concat(control);
  2971. }
  2972. ra[ra.length] = end;
  2973. }else{
  2974. superclass.setRunAttr.call(this, attr);
  2975. }
  2976. }
  2977. });
  2978. var translateValues = function(val, start) {
  2979. var pageXY = EXTLIB.Dom.getXY(this.el);
  2980. return [val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1]];
  2981. };
  2982. })();
  2983. })();// Easing functions
  2984. (function(){
  2985. // shortcuts to aid compression
  2986. var abs = Math.abs,
  2987. pi = Math.PI,
  2988. asin = Math.asin,
  2989. pow = Math.pow,
  2990. sin = Math.sin,
  2991. EXTLIB = Ext.lib;
  2992. Ext.apply(EXTLIB.Easing, {
  2993. easeBoth: function (t, b, c, d) {
  2994. return ((t /= d / 2) < 1) ? c / 2 * t * t + b : -c / 2 * ((--t) * (t - 2) - 1) + b;
  2995. },
  2996. easeInStrong: function (t, b, c, d) {
  2997. return c * (t /= d) * t * t * t + b;
  2998. },
  2999. easeOutStrong: function (t, b, c, d) {
  3000. return -c * ((t = t / d - 1) * t * t * t - 1) + b;
  3001. },
  3002. easeBothStrong: function (t, b, c, d) {
  3003. return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t + b : -c / 2 * ((t -= 2) * t * t * t - 2) + b;
  3004. },
  3005. elasticIn: function (t, b, c, d, a, p) {
  3006. if (t == 0 || (t /= d) == 1) {
  3007. return t == 0 ? b : b + c;
  3008. }
  3009. p = p || (d * .3);
  3010. var s;
  3011. if (a >= abs(c)) {
  3012. s = p / (2 * pi) * asin(c / a);
  3013. } else {
  3014. a = c;
  3015. s = p / 4;
  3016. }
  3017. return -(a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b;
  3018. },
  3019. elasticOut: function (t, b, c, d, a, p) {
  3020. if (t == 0 || (t /= d) == 1) {
  3021. return t == 0 ? b : b + c;
  3022. }
  3023. p = p || (d * .3);
  3024. var s;
  3025. if (a >= abs(c)) {
  3026. s = p / (2 * pi) * asin(c / a);
  3027. } else {
  3028. a = c;
  3029. s = p / 4;
  3030. }
  3031. return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b;
  3032. },
  3033. elasticBoth: function (t, b, c, d, a, p) {
  3034. if (t == 0 || (t /= d / 2) == 2) {
  3035. return t == 0 ? b : b + c;
  3036. }
  3037. p = p || (d * (.3 * 1.5));
  3038. var s;
  3039. if (a >= abs(c)) {
  3040. s = p / (2 * pi) * asin(c / a);
  3041. } else {
  3042. a = c;
  3043. s = p / 4;
  3044. }
  3045. return t < 1 ?
  3046. -.5 * (a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b :
  3047. a * pow(2, -10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p) * .5 + c + b;
  3048. },
  3049. backIn: function (t, b, c, d, s) {
  3050. s = s || 1.70158;
  3051. return c * (t /= d) * t * ((s + 1) * t - s) + b;
  3052. },
  3053. backOut: function (t, b, c, d, s) {
  3054. if (!s) {
  3055. s = 1.70158;
  3056. }
  3057. return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
  3058. },
  3059. backBoth: function (t, b, c, d, s) {
  3060. s = s || 1.70158;
  3061. return ((t /= d / 2 ) < 1) ?
  3062. c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b :
  3063. c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
  3064. },
  3065. bounceIn: function (t, b, c, d) {
  3066. return c - EXTLIB.Easing.bounceOut(d - t, 0, c, d) + b;
  3067. },
  3068. bounceOut: function (t, b, c, d) {
  3069. if ((t /= d) < (1 / 2.75)) {
  3070. return c * (7.5625 * t * t) + b;
  3071. } else if (t < (2 / 2.75)) {
  3072. return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
  3073. } else if (t < (2.5 / 2.75)) {
  3074. return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
  3075. }
  3076. return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
  3077. },
  3078. bounceBoth: function (t, b, c, d) {
  3079. return (t < d / 2) ?
  3080. EXTLIB.Easing.bounceIn(t * 2, 0, c, d) * .5 + b :
  3081. EXTLIB.Easing.bounceOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
  3082. }
  3083. });
  3084. })();
  3085. (function() {
  3086. var EXTLIB = Ext.lib;
  3087. // Color Animation
  3088. EXTLIB.Anim.color = function(el, args, duration, easing, cb, scope) {
  3089. return EXTLIB.Anim.run(el, args, duration, easing, cb, scope, EXTLIB.ColorAnim);
  3090. }
  3091. EXTLIB.ColorAnim = function(el, attributes, duration, method) {
  3092. EXTLIB.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
  3093. };
  3094. Ext.extend(EXTLIB.ColorAnim, EXTLIB.AnimBase);
  3095. var superclass = EXTLIB.ColorAnim.superclass,
  3096. colorRE = /color$/i,
  3097. transparentRE = /^transparent|rgba\(0, 0, 0, 0\)$/,
  3098. rgbRE = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
  3099. hexRE= /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,
  3100. hex3RE = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i,
  3101. isset = function(v){
  3102. return typeof v !== 'undefined';
  3103. };
  3104. // private
  3105. function parseColor(s) {
  3106. var pi = parseInt,
  3107. base,
  3108. out = null,
  3109. c;
  3110. if (s.length == 3) {
  3111. return s;
  3112. }
  3113. Ext.each([hexRE, rgbRE, hex3RE], function(re, idx){
  3114. base = (idx % 2 == 0) ? 16 : 10;
  3115. c = re.exec(s);
  3116. if(c && c.length == 4){
  3117. out = [pi(c[1], base), pi(c[2], base), pi(c[3], base)];
  3118. return false;
  3119. }
  3120. });
  3121. return out;
  3122. }
  3123. Ext.apply(EXTLIB.ColorAnim.prototype, {
  3124. getAttr : function(attr) {
  3125. var me = this,
  3126. el = me.el,
  3127. val;
  3128. if(colorRE.test(attr)){
  3129. while(el && transparentRE.test(val = Ext.fly(el).getStyle(attr))){
  3130. el = el.parentNode;
  3131. val = "fff";
  3132. }
  3133. }else{
  3134. val = superclass.getAttr.call(me, attr);
  3135. }
  3136. return val;
  3137. },
  3138. doMethod : function(attr, start, end) {
  3139. var me = this,
  3140. val,
  3141. floor = Math.floor,
  3142. i,
  3143. len,
  3144. v;
  3145. if(colorRE.test(attr)){
  3146. val = [];
  3147. end = end || [];
  3148. for(i = 0, len = start.length; i < len; i++) {
  3149. v = start[i];
  3150. val[i] = superclass.doMethod.call(me, attr, v, end[i]);
  3151. }
  3152. val = 'rgb(' + floor(val[0]) + ',' + floor(val[1]) + ',' + floor(val[2]) + ')';
  3153. }else{
  3154. val = superclass.doMethod.call(me, attr, start, end);
  3155. }
  3156. return val;
  3157. },
  3158. setRunAttr : function(attr) {
  3159. var me = this,
  3160. a = me.attributes[attr],
  3161. to = a.to,
  3162. by = a.by,
  3163. ra;
  3164. superclass.setRunAttr.call(me, attr);
  3165. ra = me.runAttrs[attr];
  3166. if(colorRE.test(attr)){
  3167. var start = parseColor(ra.start),
  3168. end = parseColor(ra.end);
  3169. if(!isset(to) && isset(by)){
  3170. end = parseColor(by);
  3171. for(var i=0,len=start.length; i<len; i++) {
  3172. end[i] = start[i] + end[i];
  3173. }
  3174. }
  3175. ra.start = start;
  3176. ra.end = end;
  3177. }
  3178. }
  3179. });
  3180. })();
  3181. (function() {
  3182. // Scroll Animation
  3183. var EXTLIB = Ext.lib;
  3184. EXTLIB.Anim.scroll = function(el, args, duration, easing, cb, scope) {
  3185. return EXTLIB.Anim.run(el, args, duration, easing, cb, scope, EXTLIB.Scroll);
  3186. };
  3187. EXTLIB.Scroll = function(el, attributes, duration, method) {
  3188. if(el){
  3189. EXTLIB.Scroll.superclass.constructor.call(this, el, attributes, duration, method);
  3190. }
  3191. };
  3192. Ext.extend(EXTLIB.Scroll, EXTLIB.ColorAnim);
  3193. var superclass = EXTLIB.Scroll.superclass,
  3194. SCROLL = 'scroll';
  3195. Ext.apply(EXTLIB.Scroll.prototype, {
  3196. doMethod : function(attr, start, end) {
  3197. var val,
  3198. me = this,
  3199. curFrame = me.curFrame,
  3200. totalFrames = me.totalFrames;
  3201. if(attr == SCROLL){
  3202. val = [me.method(curFrame, start[0], end[0] - start[0], totalFrames),
  3203. me.method(curFrame, start[1], end[1] - start[1], totalFrames)];
  3204. }else{
  3205. val = superclass.doMethod.call(me, attr, start, end);
  3206. }
  3207. return val;
  3208. },
  3209. getAttr : function(attr) {
  3210. var me = this;
  3211. if (attr == SCROLL) {
  3212. return [me.el.scrollLeft, me.el.scrollTop];
  3213. }else{
  3214. return superclass.getAttr.call(me, attr);
  3215. }
  3216. },
  3217. setAttr : function(attr, val, unit) {
  3218. var me = this;
  3219. if(attr == SCROLL){
  3220. me.el.scrollLeft = val[0];
  3221. me.el.scrollTop = val[1];
  3222. }else{
  3223. superclass.setAttr.call(me, attr, val, unit);
  3224. }
  3225. }
  3226. });
  3227. })();
  3228. if(Ext.isIE) {
  3229. function fnCleanUp() {
  3230. var p = Function.prototype;
  3231. delete p.createSequence;
  3232. delete p.defer;
  3233. delete p.createDelegate;
  3234. delete p.createCallback;
  3235. delete p.createInterceptor;
  3236. window.detachEvent("onunload", fnCleanUp);
  3237. }
  3238. window.attachEvent("onunload", fnCleanUp);
  3239. }
  3240. })();