/ext-4.1.0_b3/src/core/src/Ext-more.js

https://bitbucket.org/srogerf/javascript · JavaScript · 1190 lines · 489 code · 122 blank · 579 comment · 168 complexity · ccae3db3a298e56b4cf71c7520614537 MD5 · raw file

  1. /**
  2. * @class Ext
  3. *
  4. * The Ext namespace (global object) encapsulates all classes, singletons, and
  5. * utility methods provided by Sencha's libraries.
  6. *
  7. * Most user interface Components are at a lower level of nesting in the namespace,
  8. * but many common utility functions are provided as direct properties of the Ext namespace.
  9. *
  10. * Also many frequently used methods from other classes are provided as shortcuts
  11. * within the Ext namespace. For example {@link Ext#getCmp Ext.getCmp} aliases
  12. * {@link Ext.ComponentManager#get Ext.ComponentManager.get}.
  13. *
  14. * Many applications are initiated with {@link Ext#onReady Ext.onReady} which is
  15. * called once the DOM is ready. This ensures all scripts have been loaded,
  16. * preventing dependency issues. For example:
  17. *
  18. * Ext.onReady(function(){
  19. * new Ext.Component({
  20. * renderTo: document.body,
  21. * html: 'DOM ready!'
  22. * });
  23. * });
  24. *
  25. * For more information about how to use the Ext classes, see:
  26. *
  27. * - <a href="http://www.sencha.com/learn/">The Learning Center</a>
  28. * - <a href="http://www.sencha.com/learn/Ext_FAQ">The FAQ</a>
  29. * - <a href="http://www.sencha.com/forum/">The forums</a>
  30. *
  31. * @singleton
  32. */
  33. Ext.apply(Ext, {
  34. userAgent: navigator.userAgent.toLowerCase(),
  35. cache: {},
  36. idSeed: 1000,
  37. windowId: 'ext-window',
  38. documentId: 'ext-document',
  39. /**
  40. * True when the document is fully initialized and ready for action
  41. */
  42. isReady: false,
  43. /**
  44. * True to automatically uncache orphaned Ext.Elements periodically
  45. */
  46. enableGarbageCollector: true,
  47. /**
  48. * True to automatically purge event listeners during garbageCollection.
  49. */
  50. enableListenerCollection: true,
  51. /**
  52. * Generates unique ids. If the element already has an id, it is unchanged
  53. * @param {HTMLElement/Ext.Element} [el] The element to generate an id for
  54. * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
  55. * @return {String} The generated Id.
  56. */
  57. id: function(el, prefix) {
  58. var me = this,
  59. sandboxPrefix = '';
  60. el = Ext.getDom(el, true) || {};
  61. if (el === document) {
  62. el.id = me.documentId;
  63. }
  64. else if (el === window) {
  65. el.id = me.windowId;
  66. }
  67. if (!el.id) {
  68. if (me.isSandboxed) {
  69. sandboxPrefix = Ext.sandboxName.toLowerCase() + '-';
  70. }
  71. el.id = sandboxPrefix + (prefix || "ext-gen") + (++Ext.idSeed);
  72. }
  73. return el.id;
  74. },
  75. /**
  76. * Returns the current document body as an {@link Ext.Element}.
  77. * @return Ext.Element The document body
  78. */
  79. getBody: function() {
  80. var body;
  81. return function() {
  82. return body || (body = Ext.get(document.body));
  83. };
  84. }(),
  85. /**
  86. * Returns the current document head as an {@link Ext.Element}.
  87. * @return Ext.Element The document head
  88. * @method
  89. */
  90. getHead: function() {
  91. var head;
  92. return function() {
  93. return head || (head = Ext.get(document.getElementsByTagName("head")[0]));
  94. };
  95. }(),
  96. /**
  97. * Returns the current HTML document object as an {@link Ext.Element}.
  98. * @return Ext.Element The document
  99. */
  100. getDoc: function() {
  101. var doc;
  102. return function() {
  103. return doc || (doc = Ext.get(document));
  104. };
  105. }(),
  106. /**
  107. * This is shorthand reference to {@link Ext.ComponentManager#get}.
  108. * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id}
  109. *
  110. * @param {String} id The component {@link Ext.Component#id id}
  111. * @return Ext.Component The Component, `undefined` if not found, or `null` if a
  112. * Class was found.
  113. */
  114. getCmp: function(id) {
  115. return Ext.ComponentManager.get(id);
  116. },
  117. /**
  118. * Returns the current orientation of the mobile device
  119. * @return {String} Either 'portrait' or 'landscape'
  120. */
  121. getOrientation: function() {
  122. return window.innerHeight > window.innerWidth ? 'portrait' : 'landscape';
  123. },
  124. /**
  125. * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
  126. * DOM (if applicable) and calling their destroy functions (if available). This method is primarily
  127. * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of
  128. * {@link Ext.util.Observable} can be passed in. Any number of elements and/or components can be
  129. * passed into this function in a single call as separate arguments.
  130. *
  131. * @param {Ext.Element/Ext.Component/Ext.Element[]/Ext.Component[]...} args
  132. * An {@link Ext.Element}, {@link Ext.Component}, or an Array of either of these to destroy
  133. */
  134. destroy: function() {
  135. var ln = arguments.length,
  136. i, arg;
  137. for (i = 0; i < ln; i++) {
  138. arg = arguments[i];
  139. if (arg) {
  140. if (Ext.isArray(arg)) {
  141. this.destroy.apply(this, arg);
  142. }
  143. else if (Ext.isFunction(arg.destroy)) {
  144. arg.destroy();
  145. }
  146. else if (arg.dom) {
  147. arg.remove();
  148. }
  149. }
  150. }
  151. },
  152. /**
  153. * Execute a callback function in a particular scope. If no function is passed the call is ignored.
  154. *
  155. * For example, these lines are equivalent:
  156. *
  157. * Ext.callback(myFunc, this, [arg1, arg2]);
  158. * Ext.isFunction(myFunc) && myFunc.apply(this, [arg1, arg2]);
  159. *
  160. * @param {Function} callback The callback to execute
  161. * @param {Object} [scope] The scope to execute in
  162. * @param {Array} [args] The arguments to pass to the function
  163. * @param {Number} [delay] Pass a number to delay the call by a number of milliseconds.
  164. */
  165. callback: function(callback, scope, args, delay){
  166. if(Ext.isFunction(callback)){
  167. args = args || [];
  168. scope = scope || window;
  169. if (delay) {
  170. Ext.defer(callback, delay, scope, args);
  171. } else {
  172. callback.apply(scope, args);
  173. }
  174. }
  175. },
  176. /**
  177. * Alias for {@link Ext.String#htmlEncode}.
  178. * @inheritdoc Ext.String#htmlEncode
  179. */
  180. htmlEncode : function(value) {
  181. return Ext.String.htmlEncode(value);
  182. },
  183. /**
  184. * Alias for {@link Ext.String#htmlDecode}.
  185. * @inheritdoc Ext.String#htmlDecode
  186. */
  187. htmlDecode : function(value) {
  188. return Ext.String.htmlDecode(value);
  189. },
  190. /**
  191. * Alias for {@link Ext.String#urlAppend}.
  192. * @inheritdoc Ext.String#urlAppend
  193. */
  194. urlAppend : function(url, s) {
  195. return Ext.String.urlAppend(url, s);
  196. }
  197. });
  198. Ext.ns = Ext.namespace;
  199. // for old browsers
  200. window.undefined = window.undefined;
  201. /**
  202. * @class Ext
  203. */
  204. (function(){
  205. /*
  206. FF 3.6 - Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.17) Gecko/20110420 Firefox/3.6.17
  207. FF 4.0.1 - Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
  208. FF 5.0 - Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
  209. IE6 - Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)
  210. IE7 - Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1;)
  211. IE8 - Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
  212. IE9 - Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
  213. Chrome 11 - Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.60 Safari/534.24
  214. Safari 5 - Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1
  215. Opera 11.11 - Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11
  216. */
  217. var check = function(regex){
  218. return regex.test(Ext.userAgent);
  219. },
  220. isStrict = document.compatMode == "CSS1Compat",
  221. version = function (is, regex) {
  222. var m;
  223. return (is && (m = regex.exec(Ext.userAgent))) ? parseFloat(m[1]) : 0;
  224. },
  225. docMode = document.documentMode,
  226. isOpera = check(/opera/),
  227. isOpera10_5 = isOpera && check(/version\/10\.5/),
  228. isChrome = check(/\bchrome\b/),
  229. isWebKit = check(/webkit/),
  230. isSafari = !isChrome && check(/safari/),
  231. isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2
  232. isSafari3 = isSafari && check(/version\/3/),
  233. isSafari4 = isSafari && check(/version\/4/),
  234. isSafari5 = isSafari && check(/version\/5/),
  235. isIE = !isOpera && check(/msie/),
  236. isIE7 = isIE && ((check(/msie 7/) && docMode != 8 && docMode != 9) || docMode == 7),
  237. isIE8 = isIE && ((check(/msie 8/) && docMode != 7 && docMode != 9) || docMode == 8),
  238. isIE9 = isIE && ((check(/msie 9/) && docMode != 7 && docMode != 8) || docMode == 9),
  239. isIE6 = isIE && check(/msie 6/),
  240. isGecko = !isWebKit && check(/gecko/),
  241. isGecko3 = isGecko && check(/rv:1\.9/),
  242. isGecko4 = isGecko && check(/rv:2\.0/),
  243. isGecko5 = isGecko && check(/rv:5\./),
  244. isGecko10 = isGecko && check(/rv:10\./),
  245. isFF3_0 = isGecko3 && check(/rv:1\.9\.0/),
  246. isFF3_5 = isGecko3 && check(/rv:1\.9\.1/),
  247. isFF3_6 = isGecko3 && check(/rv:1\.9\.2/),
  248. isWindows = check(/windows|win32/),
  249. isMac = check(/macintosh|mac os x/),
  250. isLinux = check(/linux/),
  251. scrollbarSize = null,
  252. chromeVersion = version(true, /\bchrome\/(\d+\.\d+)/),
  253. firefoxVersion = version(true, /\bfirefox\/(\d+\.\d+)/),
  254. ieVersion = version(isIE, /msie (\d+\.\d+)/),
  255. operaVersion = version(isOpera, /version\/(\d+\.\d+)/),
  256. safariVersion = version(isSafari, /version\/(\d+\.\d+)/),
  257. webKitVersion = version(isWebKit, /webkit\/(\d+\.\d+)/),
  258. isSecure = /^https/i.test(window.location.protocol);
  259. // remove css image flicker
  260. try {
  261. document.execCommand("BackgroundImageCache", false, true);
  262. } catch(e) {}
  263. //<debug>
  264. var primitiveRe = /string|number|boolean/;
  265. function dumpObject (object) {
  266. var member, type, value, name,
  267. members = [];
  268. // Cannot use Ext.encode since it can recurse endlessly (if we're lucky)
  269. // ...and the data could be prettier!
  270. for (name in object) {
  271. if (object.hasOwnProperty(name)) {
  272. value = object[name];
  273. type = typeof value;
  274. if (type == "function") {
  275. continue;
  276. }
  277. if (type == 'undefined') {
  278. member = type;
  279. } else if (value === null || primitiveRe.test(type) || Ext.isDate(value)) {
  280. member = Ext.encode(value);
  281. } else if (Ext.isArray(value)) {
  282. member = '[ ]';
  283. } else if (Ext.isObject(value)) {
  284. member = '{ }';
  285. } else {
  286. member = type;
  287. }
  288. members.push(Ext.encode(name) + ': ' + member);
  289. }
  290. }
  291. if (members.length) {
  292. return ' \nData: {\n ' + members.join(',\n ') + '\n}';
  293. }
  294. return '';
  295. }
  296. function log (message) {
  297. var options, dump,
  298. con = Ext.global.console,
  299. level = 'log',
  300. indent = log.indent || 0,
  301. stack;
  302. log.indent = indent;
  303. if (typeof message != 'string') {
  304. options = message;
  305. message = options.msg || '';
  306. level = options.level || level;
  307. dump = options.dump;
  308. stack = options.stack;
  309. if (options.indent) {
  310. ++log.indent;
  311. } else if (options.outdent) {
  312. log.indent = indent = Math.max(indent - 1, 0);
  313. }
  314. if (dump && !(con && con.dir)) {
  315. message += dumpObject(dump);
  316. dump = null;
  317. }
  318. }
  319. if (arguments.length > 1) {
  320. message += Array.prototype.slice.call(arguments, 1).join('');
  321. }
  322. message = indent ? Ext.String.repeat(' ', log.indentSize * indent) + message : message;
  323. // w/o console, all messages are equal, so munge the level into the message:
  324. if (level != 'log') {
  325. message = '[' + level.charAt(0).toUpperCase() + '] ' + message;
  326. }
  327. // Not obvious, but 'console' comes and goes when Firebug is turned on/off, so
  328. // an early test may fail either direction if Firebug is toggled.
  329. //
  330. if (con) { // if (Firebug-like console)
  331. if (con[level]) {
  332. con[level](message);
  333. } else {
  334. con.log(message);
  335. }
  336. if (dump) {
  337. con.dir(dump);
  338. }
  339. if (stack && con.trace) {
  340. // Firebug's console.error() includes a trace already...
  341. if (!con.firebug || level != 'error') {
  342. con.trace();
  343. }
  344. }
  345. } else {
  346. if (Ext.isOpera) {
  347. opera.postError(message);
  348. } else {
  349. var out = log.out,
  350. max = log.max;
  351. if (out.length >= max) {
  352. // this formula allows out.max to change (via debugger), where the
  353. // more obvious "max/4" would not quite be the same
  354. Ext.Array.erase(out, 0, out.length - 3 * Math.floor(max / 4)); // keep newest 75%
  355. }
  356. out.push(message);
  357. }
  358. }
  359. // Mostly informational, but the Ext.Error notifier uses them:
  360. ++log.count;
  361. ++log.counters[level];
  362. }
  363. function logx (level, args) {
  364. if (typeof args[0] == 'string') {
  365. args.unshift({});
  366. }
  367. args[0].level = level;
  368. log.apply(this, args);
  369. }
  370. log.error = function () {
  371. logx('error', Array.prototype.slice.call(arguments));
  372. }
  373. log.info = function () {
  374. logx('info', Array.prototype.slice.call(arguments));
  375. }
  376. log.warn = function () {
  377. logx('warn', Array.prototype.slice.call(arguments));
  378. }
  379. log.count = 0;
  380. log.counters = { error: 0, warn: 0, info: 0, log: 0 };
  381. log.indentSize = 2;
  382. log.out = [];
  383. log.max = 750;
  384. log.show = function () {
  385. window.open('','extlog').document.write([
  386. '<html><head><script type="text/javascript">',
  387. 'var lastCount = 0;',
  388. 'function update () {',
  389. 'var ext = window.opener.Ext,',
  390. 'extlog = ext && ext.log;',
  391. 'if (extlog && extlog.out && lastCount != extlog.count) {',
  392. 'lastCount = extlog.count;',
  393. 'var s = "<tt>" + extlog.out.join("~~~").replace(/[&]/g, "&amp;").replace(/[<]/g, "&lt;").replace(/[ ]/g, "&nbsp;").replace(/\\~\\~\\~/g, "<br>") + "</tt>";',
  394. 'document.body.innerHTML = s;',
  395. '}',
  396. 'setTimeout(update, 1000);',
  397. '}',
  398. 'setTimeout(update, 1000);',
  399. '</script></head><body></body></html>'].join(''));
  400. };
  401. //</debug>
  402. var nullLog = function () {};
  403. nullLog.info = nullLog.warn = nullLog.error = Ext.emptyFn;
  404. Ext.setVersion('extjs', '4.1.0');
  405. Ext.apply(Ext, {
  406. /**
  407. * @property {String} SSL_SECURE_URL
  408. * URL to a blank file used by Ext when in secure mode for iframe src and onReady src
  409. * to prevent the IE insecure content warning (`'about:blank'`, except for IE
  410. * in secure mode, which is `'javascript:""'`).
  411. */
  412. SSL_SECURE_URL : isSecure && isIE ? 'javascript:\'\'' : 'about:blank',
  413. /**
  414. * @property {Boolean} enableFx
  415. * True if the {@link Ext.fx.Anim} Class is available.
  416. */
  417. /**
  418. * @property {Boolean} scopeResetCSS
  419. * True to scope the reset CSS to be just applied to Ext components. Note that this
  420. * wraps root containers with an additional element. Also remember that when you turn
  421. * on this option, you have to use ext-all-scoped (unless you use the bootstrap.js to
  422. * load your javascript, in which case it will be handled for you).
  423. */
  424. scopeResetCSS : Ext.buildSettings.scopeResetCSS,
  425. /**
  426. * @property {String} resetCls
  427. * The css class used to wrap Ext components when the {@link #scopeResetCSS} option
  428. * is used.
  429. */
  430. resetCls: Ext.buildSettings.baseCSSPrefix + 'reset',
  431. /**
  432. * @property {Boolean} enableNestedListenerRemoval
  433. * **Experimental.** True to cascade listener removal to child elements when an element
  434. * is removed. Currently not optimized for performance.
  435. */
  436. enableNestedListenerRemoval : false,
  437. /**
  438. * @property {Boolean} USE_NATIVE_JSON
  439. * Indicates whether to use native browser parsing for JSON methods.
  440. * This option is ignored if the browser does not support native JSON methods.
  441. *
  442. * **Note:** Native JSON methods will not work with objects that have functions.
  443. * Also, property names must be quoted, otherwise the data will not parse.
  444. */
  445. USE_NATIVE_JSON : false,
  446. /**
  447. * Returns the dom node for the passed String (id), dom node, or Ext.Element.
  448. * Optional 'strict' flag is needed for IE since it can return 'name' and
  449. * 'id' elements by using getElementById.
  450. *
  451. * Here are some examples:
  452. *
  453. * // gets dom node based on id
  454. * var elDom = Ext.getDom('elId');
  455. * // gets dom node based on the dom node
  456. * var elDom1 = Ext.getDom(elDom);
  457. *
  458. * // If we don&#39;t know if we are working with an
  459. * // Ext.Element or a dom node use Ext.getDom
  460. * function(el){
  461. * var dom = Ext.getDom(el);
  462. * // do something with the dom node
  463. * }
  464. *
  465. * **Note:** the dom node to be found actually needs to exist (be rendered, etc)
  466. * when this method is called to be successful.
  467. *
  468. * @param {String/HTMLElement/Ext.Element} el
  469. * @return HTMLElement
  470. */
  471. getDom : function(el, strict) {
  472. if (!el || !document) {
  473. return null;
  474. }
  475. if (el.dom) {
  476. return el.dom;
  477. } else {
  478. if (typeof el == 'string') {
  479. var e = Ext.getElementById(el);
  480. // IE returns elements with the 'name' and 'id' attribute.
  481. // we do a strict check to return the element with only the id attribute
  482. if (e && isIE && strict) {
  483. if (el == e.getAttribute('id')) {
  484. return e;
  485. } else {
  486. return null;
  487. }
  488. }
  489. return e;
  490. } else {
  491. return el;
  492. }
  493. }
  494. },
  495. /**
  496. * Removes a DOM node from the document.
  497. *
  498. * Removes this element from the document, removes all DOM event listeners, and
  499. * deletes the cache reference. All DOM event listeners are removed from this element.
  500. * If {@link Ext#enableNestedListenerRemoval Ext.enableNestedListenerRemoval} is
  501. * `true`, then DOM event listeners are also removed from all child nodes.
  502. * The body node will be ignored if passed in.
  503. *
  504. * @param {HTMLElement} node The node to remove
  505. * @method
  506. */
  507. removeNode : isIE6 || isIE7 ? function() {
  508. var d;
  509. return function(n){
  510. if(n && n.tagName != 'BODY'){
  511. (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n) : Ext.EventManager.removeAll(n);
  512. d = d || document.createElement('div');
  513. d.appendChild(n);
  514. d.innerHTML = '';
  515. delete Ext.cache[n.id];
  516. }
  517. };
  518. }() : function(n) {
  519. if (n && n.parentNode && n.tagName != 'BODY') {
  520. (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n) : Ext.EventManager.removeAll(n);
  521. n.parentNode.removeChild(n);
  522. delete Ext.cache[n.id];
  523. }
  524. },
  525. isStrict: isStrict,
  526. isIEQuirks: isIE && !isStrict,
  527. /**
  528. * True if the detected browser is Opera.
  529. * @type Boolean
  530. */
  531. isOpera : isOpera,
  532. /**
  533. * True if the detected browser is Opera 10.5x.
  534. * @type Boolean
  535. */
  536. isOpera10_5 : isOpera10_5,
  537. /**
  538. * True if the detected browser uses WebKit.
  539. * @type Boolean
  540. */
  541. isWebKit : isWebKit,
  542. /**
  543. * True if the detected browser is Chrome.
  544. * @type Boolean
  545. */
  546. isChrome : isChrome,
  547. /**
  548. * True if the detected browser is Safari.
  549. * @type Boolean
  550. */
  551. isSafari : isSafari,
  552. /**
  553. * True if the detected browser is Safari 3.x.
  554. * @type Boolean
  555. */
  556. isSafari3 : isSafari3,
  557. /**
  558. * True if the detected browser is Safari 4.x.
  559. * @type Boolean
  560. */
  561. isSafari4 : isSafari4,
  562. /**
  563. * True if the detected browser is Safari 5.x.
  564. * @type Boolean
  565. */
  566. isSafari5 : isSafari5,
  567. /**
  568. * True if the detected browser is Safari 2.x.
  569. * @type Boolean
  570. */
  571. isSafari2 : isSafari2,
  572. /**
  573. * True if the detected browser is Internet Explorer.
  574. * @type Boolean
  575. */
  576. isIE : isIE,
  577. /**
  578. * True if the detected browser is Internet Explorer 6.x.
  579. * @type Boolean
  580. */
  581. isIE6 : isIE6,
  582. /**
  583. * True if the detected browser is Internet Explorer 7.x.
  584. * @type Boolean
  585. */
  586. isIE7 : isIE7,
  587. /**
  588. * True if the detected browser is Internet Explorer 8.x.
  589. * @type Boolean
  590. */
  591. isIE8 : isIE8,
  592. /**
  593. * True if the detected browser is Internet Explorer 9.x.
  594. * @type Boolean
  595. */
  596. isIE9 : isIE9,
  597. /**
  598. * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
  599. * @type Boolean
  600. */
  601. isGecko : isGecko,
  602. /**
  603. * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
  604. * @type Boolean
  605. */
  606. isGecko3 : isGecko3,
  607. /**
  608. * True if the detected browser uses a Gecko 2.0+ layout engine (e.g. Firefox 4.x).
  609. * @type Boolean
  610. */
  611. isGecko4 : isGecko4,
  612. /**
  613. * True if the detected browser uses a Gecko 5.0+ layout engine (e.g. Firefox 5.x).
  614. * @type Boolean
  615. */
  616. isGecko5 : isGecko5,
  617. /**
  618. * True if the detected browser uses a Gecko 5.0+ layout engine (e.g. Firefox 5.x).
  619. * @type Boolean
  620. */
  621. isGecko10 : isGecko10,
  622. /**
  623. * True if the detected browser uses FireFox 3.0
  624. * @type Boolean
  625. */
  626. isFF3_0 : isFF3_0,
  627. /**
  628. * True if the detected browser uses FireFox 3.5
  629. * @type Boolean
  630. */
  631. isFF3_5 : isFF3_5,
  632. /**
  633. * True if the detected browser uses FireFox 3.6
  634. * @type Boolean
  635. */
  636. isFF3_6 : isFF3_6,
  637. /**
  638. * True if the detected browser uses FireFox 4
  639. * @type Boolean
  640. */
  641. isFF4 : 4 <= firefoxVersion && firefoxVersion < 5,
  642. /**
  643. * True if the detected browser uses FireFox 5
  644. * @type Boolean
  645. */
  646. isFF5 : 5 <= firefoxVersion && firefoxVersion < 6,
  647. /**
  648. * True if the detected browser uses FireFox 10
  649. * @type Boolean
  650. */
  651. isFF10 : 10 <= firefoxVersion && firefoxVersion < 11,
  652. /**
  653. * True if the detected platform is Linux.
  654. * @type Boolean
  655. */
  656. isLinux : isLinux,
  657. /**
  658. * True if the detected platform is Windows.
  659. * @type Boolean
  660. */
  661. isWindows : isWindows,
  662. /**
  663. * True if the detected platform is Mac OS.
  664. * @type Boolean
  665. */
  666. isMac : isMac,
  667. /**
  668. * The current version of Chrome (0 if the browser is not Chrome).
  669. * @type Number
  670. */
  671. chromeVersion: chromeVersion,
  672. /**
  673. * The current version of Firefox (0 if the browser is not Firefox).
  674. * @type Number
  675. */
  676. firefoxVersion: firefoxVersion,
  677. /**
  678. * The current version of IE (0 if the browser is not IE). This does not account
  679. * for the documentMode of the current page, which is factored into {@link #isIE7},
  680. * {@link #isIE8} and {@link #isIE9}. Thus this is not always true:
  681. *
  682. * Ext.isIE8 == (Ext.ieVersion == 8)
  683. *
  684. * @type Number
  685. */
  686. ieVersion: ieVersion,
  687. /**
  688. * The current version of Opera (0 if the browser is not Opera).
  689. * @type Number
  690. */
  691. operaVersion: operaVersion,
  692. /**
  693. * The current version of Safari (0 if the browser is not Safari).
  694. * @type Number
  695. */
  696. safariVersion: safariVersion,
  697. /**
  698. * The current version of WebKit (0 if the browser does not use WebKit).
  699. * @type Number
  700. */
  701. webKitVersion: webKitVersion,
  702. /**
  703. * True if the page is running over SSL
  704. * @type Boolean
  705. */
  706. isSecure: isSecure,
  707. /**
  708. * URL to a 1x1 transparent gif image used by Ext to create inline icons with
  709. * CSS background images. In older versions of IE, this defaults to
  710. * "http://sencha.com/s.gif" and you should change this to a URL on your server.
  711. * For other browsers it uses an inline data URL.
  712. * @type String
  713. */
  714. BLANK_IMAGE_URL : (isIE6 || isIE7) ? '/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
  715. /**
  716. * Utility method for returning a default value if the passed value is empty.
  717. *
  718. * The value is deemed to be empty if it is:
  719. *
  720. * - null
  721. * - undefined
  722. * - an empty array
  723. * - a zero length string (Unless the `allowBlank` parameter is `true`)
  724. *
  725. * @param {Object} value The value to test
  726. * @param {Object} defaultValue The value to return if the original value is empty
  727. * @param {Boolean} [allowBlank=false] true to allow zero length strings to qualify as non-empty.
  728. * @return {Object} value, if non-empty, else defaultValue
  729. * @deprecated 4.0.0 Use {@link Ext#valueFrom} instead
  730. */
  731. value : function(v, defaultValue, allowBlank){
  732. return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
  733. },
  734. /**
  735. * Escapes the passed string for use in a regular expression.
  736. * @param {String} str
  737. * @return {String}
  738. * @deprecated 4.0.0 Use {@link Ext.String#escapeRegex} instead
  739. */
  740. escapeRe : function(s) {
  741. return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
  742. },
  743. /**
  744. * Applies event listeners to elements by selectors when the document is ready.
  745. * The event name is specified with an `@` suffix.
  746. *
  747. * Ext.addBehaviors({
  748. * // add a listener for click on all anchors in element with id foo
  749. * '#foo a@click' : function(e, t){
  750. * // do something
  751. * },
  752. *
  753. * // add the same listener to multiple selectors (separated by comma BEFORE the @)
  754. * '#foo a, #bar span.some-class@mouseover' : function(){
  755. * // do something
  756. * }
  757. * });
  758. *
  759. * @param {Object} obj The list of behaviors to apply
  760. */
  761. addBehaviors : function(o){
  762. if(!Ext.isReady){
  763. Ext.onReady(function(){
  764. Ext.addBehaviors(o);
  765. });
  766. } else {
  767. var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times
  768. parts,
  769. b,
  770. s;
  771. for (b in o) {
  772. if ((parts = b.split('@'))[1]) { // for Object prototype breakers
  773. s = parts[0];
  774. if(!cache[s]){
  775. cache[s] = Ext.select(s);
  776. }
  777. cache[s].on(parts[1], o[b]);
  778. }
  779. }
  780. cache = null;
  781. }
  782. },
  783. /**
  784. * Returns the size of the browser scrollbars. This can differ depending on
  785. * operating system settings, such as the theme or font size.
  786. * @param {Boolean} [force] true to force a recalculation of the value.
  787. * @return {Object} An object containing scrollbar sizes.
  788. * @return.width {Number} The width of the vertical scrollbar.
  789. * @return.height {Number} The height of the horizontal scrollbar.
  790. */
  791. getScrollbarSize: function (force) {
  792. if (!Ext.isReady) {
  793. return {};
  794. }
  795. if (force || !scrollbarSize) {
  796. var db = document.body,
  797. div = document.createElement('div');
  798. div.style.width = div.style.height = '100px';
  799. div.style.overflow = 'scroll';
  800. div.style.position = 'absolute';
  801. db.appendChild(div); // now we can measure the div...
  802. // at least in iE9 the div is not 100px - the scrollbar size is removed!
  803. scrollbarSize = {
  804. width: div.offsetWidth - div.clientWidth,
  805. height: div.offsetHeight - div.clientHeight
  806. };
  807. db.removeChild(div);
  808. }
  809. return scrollbarSize;
  810. },
  811. /**
  812. * Utility method for getting the width of the browser's vertical scrollbar. This
  813. * can differ depending on operating system settings, such as the theme or font size.
  814. *
  815. * This method is deprected in favor of {@link #getScrollbarSize}.
  816. *
  817. * @param {Boolean} [force] true to force a recalculation of the value.
  818. * @return {Number} The width of a vertical scrollbar.
  819. * @deprecated
  820. */
  821. getScrollBarWidth: function(force){
  822. var size = Ext.getScrollbarSize(force);
  823. return size.width + 2; // legacy fudge factor
  824. },
  825. /**
  826. * Copies a set of named properties fom the source object to the destination object.
  827. *
  828. * Example:
  829. *
  830. * ImageComponent = Ext.extend(Ext.Component, {
  831. * initComponent: function() {
  832. * this.autoEl = { tag: 'img' };
  833. * MyComponent.superclass.initComponent.apply(this, arguments);
  834. * this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
  835. * }
  836. * });
  837. *
  838. * Important note: To borrow class prototype methods, use {@link Ext.Base#borrow} instead.
  839. *
  840. * @param {Object} dest The destination object.
  841. * @param {Object} source The source object.
  842. * @param {String/String[]} names Either an Array of property names, or a comma-delimited list
  843. * of property names to copy.
  844. * @param {Boolean} [usePrototypeKeys] Defaults to false. Pass true to copy keys off of the
  845. * prototype as well as the instance.
  846. * @return {Object} The modified object.
  847. */
  848. copyTo : function(dest, source, names, usePrototypeKeys){
  849. if(typeof names == 'string'){
  850. names = names.split(/[,;\s]/);
  851. }
  852. var n,
  853. nLen = names.length,
  854. name;
  855. for(n = 0; n < nLen; n++) {
  856. name = names[n];
  857. if(usePrototypeKeys || source.hasOwnProperty(name)){
  858. dest[name] = source[name];
  859. }
  860. }
  861. return dest;
  862. },
  863. /**
  864. * Attempts to destroy and then remove a set of named properties of the passed object.
  865. * @param {Object} o The object (most likely a Component) who's properties you wish to destroy.
  866. * @param {String...} args One or more names of the properties to destroy and remove from the object.
  867. */
  868. destroyMembers : function(o){
  869. for (var i = 1, a = arguments, len = a.length; i < len; i++) {
  870. Ext.destroy(o[a[i]]);
  871. delete o[a[i]];
  872. }
  873. },
  874. /**
  875. * Logs a message. If a console is present it will be used. On Opera, the method
  876. * "opera.postError" is called. In other cases, the message is logged to an array
  877. * "Ext.log.out". An attached debugger can watch this array and view the log. The
  878. * log buffer is limited to a maximum of "Ext.log.max" entries (defaults to 250).
  879. * The `Ext.log.out` array can also be written to a popup window by entering the
  880. * following in the URL bar (a "bookmarklet"):
  881. *
  882. * javascript:void(Ext.log.show());
  883. *
  884. * If additional parameters are passed, they are joined and appended to the message.
  885. * A technique for tracing entry and exit of a function is this:
  886. *
  887. * function foo () {
  888. * Ext.log({ indent: 1 }, '>> foo');
  889. *
  890. * // log statements in here or methods called from here will be indented
  891. * // by one step
  892. *
  893. * Ext.log({ outdent: 1 }, '<< foo');
  894. * }
  895. *
  896. * This method does nothing in a release build.
  897. *
  898. * @param {String/Object} message The message to log or an options object with any
  899. * of the following properties:
  900. *
  901. * - `msg`: The message to log (required).
  902. * - `level`: One of: "error", "warn", "info" or "log" (the default is "log").
  903. * - `dump`: An object to dump to the log as part of the message.
  904. * - `stack`: True to include a stack trace in the log.
  905. * - `indent`: Cause subsequent log statements to be indented one step.
  906. * - `outdent`: Cause this and following statements to be one step less indented.
  907. *
  908. * @method
  909. */
  910. log :
  911. //<debug>
  912. log ||
  913. //</debug>
  914. nullLog,
  915. /**
  916. * Partitions the set into two sets: a true set and a false set.
  917. *
  918. * Example 1:
  919. *
  920. * Ext.partition([true, false, true, true, false]);
  921. * // returns [[true, true, true], [false, false]]
  922. *
  923. * Example 2:
  924. *
  925. * Ext.partition(
  926. * Ext.query("p"),
  927. * function(val){
  928. * return val.className == "class1"
  929. * }
  930. * );
  931. * // true are those paragraph elements with a className of "class1",
  932. * // false set are those that do not have that className.
  933. *
  934. * @param {Array/NodeList} arr The array to partition
  935. * @param {Function} truth (optional) a function to determine truth.
  936. * If this is omitted the element itself must be able to be evaluated for its truthfulness.
  937. * @return {Array} [array of truish values, array of falsy values]
  938. * @deprecated 4.0.0 Will be removed in the next major version
  939. */
  940. partition : function(arr, truth){
  941. var ret = [[],[]],
  942. a, v,
  943. aLen = arr.length;
  944. for (a = 0; a < aLen; a++) {
  945. v = arr[a];
  946. ret[ (truth && truth(v, a, arr)) || (!truth && v) ? 0 : 1].push(v);
  947. }
  948. return ret;
  949. },
  950. /**
  951. * Invokes a method on each item in an Array.
  952. *
  953. * Example:
  954. *
  955. * Ext.invoke(Ext.query("p"), "getAttribute", "id");
  956. * // [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")]
  957. *
  958. * @param {Array/NodeList} arr The Array of items to invoke the method on.
  959. * @param {String} methodName The method name to invoke.
  960. * @param {Object...} args Arguments to send into the method invocation.
  961. * @return {Array} The results of invoking the method on each item in the array.
  962. * @deprecated 4.0.0 Will be removed in the next major version
  963. */
  964. invoke : function(arr, methodName){
  965. var ret = [],
  966. args = Array.prototype.slice.call(arguments, 2),
  967. a, v,
  968. aLen = arr.length;
  969. for (a = 0; a < aLen; a++) {
  970. v = arr[a];
  971. if (v && typeof v[methodName] == 'function') {
  972. ret.push(v[methodName].apply(v, args));
  973. } else {
  974. ret.push(undefined);
  975. }
  976. }
  977. return ret;
  978. },
  979. /**
  980. * Zips N sets together.
  981. *
  982. * Example 1:
  983. *
  984. * Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]]
  985. *
  986. * Example 2:
  987. *
  988. * Ext.zip(
  989. * [ "+", "-", "+"],
  990. * [ 12, 10, 22],
  991. * [ 43, 15, 96],
  992. * function(a, b, c){
  993. * return "$" + a + "" + b + "." + c
  994. * }
  995. * ); // ["$+12.43", "$-10.15", "$+22.96"]
  996. *
  997. * @param {Array/NodeList...} arr This argument may be repeated. Array(s)
  998. * to contribute values.
  999. * @param {Function} zipper (optional) The last item in the argument list.
  1000. * This will drive how the items are zipped together.
  1001. * @return {Array} The zipped set.
  1002. * @deprecated 4.0.0 Will be removed in the next major version
  1003. */
  1004. zip : function(){
  1005. var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }),
  1006. arrs = parts[0],
  1007. fn = parts[1][0],
  1008. len = Ext.max(Ext.pluck(arrs, "length")),
  1009. ret = [];
  1010. for (var i = 0; i < len; i++) {
  1011. ret[i] = [];
  1012. if(fn){
  1013. ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
  1014. }else{
  1015. for (var j = 0, aLen = arrs.length; j < aLen; j++){
  1016. ret[i].push( arrs[j][i] );
  1017. }
  1018. }
  1019. }
  1020. return ret;
  1021. },
  1022. /**
  1023. * Turns an array into a sentence, joined by a specified connector - e.g.:
  1024. *
  1025. * Ext.toSentence(['Adama', 'Tigh', 'Roslin']); //'Adama, Tigh and Roslin'
  1026. * Ext.toSentence(['Adama', 'Tigh', 'Roslin'], 'or'); //'Adama, Tigh or Roslin'
  1027. *
  1028. * @param {String[]} items The array to create a sentence from
  1029. * @param {String} connector The string to use to connect the last two words.
  1030. * Usually 'and' or 'or' - defaults to 'and'.
  1031. * @return {String} The sentence string
  1032. * @deprecated 4.0.0 Will be removed in the next major version
  1033. */
  1034. toSentence: function(items, connector) {
  1035. var length = items.length;
  1036. if (length <= 1) {
  1037. return items[0];
  1038. } else {
  1039. var head = items.slice(0, length - 1),
  1040. tail = items[length - 1];
  1041. return Ext.util.Format.format("{0} {1} {2}", head.join(", "), connector || 'and', tail);
  1042. }
  1043. },
  1044. /**
  1045. * @property {Boolean} useShims
  1046. * By default, Ext intelligently decides whether floating elements should be shimmed.
  1047. * If you are using flash, you may want to set this to true.
  1048. */
  1049. useShims: isIE6
  1050. });
  1051. })();
  1052. /**
  1053. * Loads Ext.app.Application class and starts it up with given configuration after the page is ready.
  1054. *
  1055. * See Ext.app.Application for details.
  1056. *
  1057. * @param {Object} config
  1058. */
  1059. Ext.application = function(config) {
  1060. Ext.require('Ext.app.Application');
  1061. Ext.onReady(function() {
  1062. new Ext.app.Application(config);
  1063. });
  1064. };