Changeset 29937
- Timestamp:
- 06/23/10 15:29:12 (3 years ago)
- Files:
-
- plugins/ExtjsGeneratorPlugin/trunk/TODO.txt (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/config/ExtjsGeneratorPluginConfiguration.class.php (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/data/generator/ExtjsModule/admin/template/templates/_filterpanel.js.php (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/lib/widget/ExtjsWidgetForm.class.php (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.data.HttpProxy.override.js (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.TabCloseMenu.js (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.form.IsEmptyCheckbox.js (added)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.form.ItemSelector.js (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.form.MultiSelect.js (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.form.TwinComboBox.js (modified) (5 diffs)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.form.TwinDateField.js (modified) (3 diffs)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.grid.CheckColumn.js (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.grid.RowActions.js (modified) (20 diffs)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/ExtjsGeneratorConstants.js (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/ext-basex.js (modified) (1 diff)
- plugins/ExtjsGeneratorPlugin/trunk/web/js/jit.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
plugins/ExtjsGeneratorPlugin/trunk/TODO.txt
r29921 r29937 19 19 foreign columns should show __toString() output in list 20 20 foreign columns should be clickable to open an adminstration for that foreign table if one exists 21 22 ### filter23 move is_empty checkbox for filter to an Ext.ux extension24 is_empty doesn't reset when value is set from the session25 is_empty should clear associated fields when set26 is_empty oncheck listener to submit the filter27 21 28 22 ### generic plugins/ExtjsGeneratorPlugin/trunk/config/ExtjsGeneratorPluginConfiguration.class.php
r29743 r29937 59 59 '/ExtjsGeneratorPlugin/js/Ext.ux.form.TwinDateField.js', 60 60 '/ExtjsGeneratorPlugin/js/Ext.ux.form.TwinComboBox.js', 61 '/ExtjsGeneratorPlugin/js/Ext.ux.form.IsEmptyCheckbox.js', 61 62 '/ExtjsGeneratorPlugin/js/Ext.ux.grid.CheckColumn.js', 62 63 '/ExtjsGeneratorPlugin/js/Ext.data.HttpProxy.override.js' // adds setMethod method plugins/ExtjsGeneratorPlugin/trunk/data/generator/ExtjsModule/admin/template/templates/_filterpanel.js.php
r29921 r29937 24 24 var params=this.form.getValues(); 25 25 this.fireEvent('filter_set', params, this); 26 this.fireEvent('click'); 26 27 "), 27 28 'scope' => 'this' plugins/ExtjsGeneratorPlugin/trunk/lib/widget/ExtjsWidgetForm.class.php
r29919 r29937 19 19 public function renderExtjsFilterIsEmptyCheckbox($name, $values) 20 20 { 21 return $this->renderExtjsContentBlock('filter', ' Checkbox', array(21 return $this->renderExtjsContentBlock('filter', 'IsEmptyCheckbox', array( 22 22 'name' => $name . '[is_empty]', 23 23 'boxLabel' => $this->translate($this->getOption('empty_label')), 24 'checked' => $values['is_empty'] ? true : false, 25 'inputValue' => 'true', 26 'hideLabel' => true, 27 'listeners' => array( 28 'render' => array( 29 'fn' => "function(){this.getEl().up('div.x-form-item').setStyle({paddingLeft:'5px',marginTop:'-10px'});}", 30 'single' => true 31 ) 32 ) 24 'checked' => $values['is_empty'] ? true : false 33 25 )); 34 26 } plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.data.HttpProxy.override.js
r29426 r29937 19 19 this.conn.method = method; 20 20 if (!makePermanent) { 21 this.on('load', function(){this.conn.method = confMethod;}, this, {single:true}); 21 this.on('load', function() { 22 this.conn.method = confMethod; 23 }, this, { 24 single : true 25 }); 22 26 } 23 27 } plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.TabCloseMenu.js
r29426 r29937 2 2 3 3 /* 4 * Ext JS Library 2.0 Beta 1 5 * Copyright(c) 2006-2007, Ext JS, LLC. 4 * Ext JS Library 2.0 Beta 1 Copyright(c) 2006-2007, Ext JS, LLC. 6 5 * licensing@extjs.com 7 * 6 * 8 7 * http://extjs.com/license 9 8 */ 10 9 10 // Very simple plugin for adding a close context menu to tabs 11 Ext.ux.TabCloseMenu = function() { 12 var tabs, menu, ctxItem; 13 this.init = function(tp) { 14 tabs = tp; 15 tabs.on('contextmenu', onContextMenu); 16 } 11 17 12 // Very simple plugin for adding a close context menu to tabs 13 Ext.ux.TabCloseMenu = function(){ 14 var tabs, menu, ctxItem; 15 this.init = function(tp){ 16 tabs = tp; 17 tabs.on('contextmenu', onContextMenu); 18 function onContextMenu(ts, item, e) { 19 if (!menu) { // create context menu on first right click 20 menu = new Ext.menu.Menu([ 21 { 22 id : tabs.id + '-close', 23 text : 'Close Tab', 24 handler : function() { 25 tabs.remove(ctxItem); 26 } 27 }, { 28 id : tabs.id + '-close-others', 29 text : 'Close Other Tabs', 30 handler : function() { 31 tabs.items.each(function(item) { 32 if (item.closable && item != ctxItem) { 33 tabs.remove(item); 34 } 35 }); 36 } 37 } 38 ]); 18 39 } 19 20 function onContextMenu(ts, item, e){ 21 if(!menu){ // create context menu on first right click 22 menu = new Ext.menu.Menu([{ 23 id: tabs.id + '-close', 24 text: 'Close Tab', 25 handler : function(){ 26 tabs.remove(ctxItem); 27 } 28 },{ 29 id: tabs.id + '-close-others', 30 text: 'Close Other Tabs', 31 handler : function(){ 32 tabs.items.each(function(item){ 33 if(item.closable && item != ctxItem){ 34 tabs.remove(item); 35 } 36 }); 37 } 38 }]); 39 } 40 ctxItem = item; 41 var items = menu.items; 42 items.get(tabs.id + '-close').setDisabled(!item.closable); 43 var disableOthers = true; 44 tabs.items.each(function(){ 45 if(this != item && this.closable){ 46 disableOthers = false; 47 return false; 48 } 49 }); 50 items.get(tabs.id + '-close-others').setDisabled(disableOthers); 51 menu.showAt(e.getPoint()); 52 } 40 ctxItem = item; 41 var items = menu.items; 42 items.get(tabs.id + '-close').setDisabled(!item.closable); 43 var disableOthers = true; 44 tabs.items.each(function() { 45 if (this != item && this.closable) { 46 disableOthers = false; 47 return false; 48 } 49 }); 50 items.get(tabs.id + '-close-others').setDisabled(disableOthers); 51 menu.showAt(e.getPoint()); 52 } 53 53 }; plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.form.ItemSelector.js
r29426 r29937 441 441 if (!val) 442 442 return; 443 443 444 444 if (!Ext.isArray(val)) { 445 445 val = val.split(this.delimiter); plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.form.MultiSelect.js
r29426 r29937 604 604 } 605 605 } else { // If the last element to be inserted above is the target node, 606 // remove it606 // remove it 607 607 if (data.viewNodes[data.viewNodes.length - 1] == n) { 608 608 data.viewNodes.pop(); plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.form.TwinComboBox.js
r29436 r29937 41 41 submitOnClear : true, 42 42 allowClear : true, 43 defaultValue : null,43 defaultValue : null, 44 44 plugins : [ 45 45 Ext.ux.ComboListAutoSizer … … 109 109 if (r.data[prop] == value) { 110 110 record = r; 111 // return false;111 // return false; 112 112 } 113 113 }); … … 117 117 118 118 reset : Ext.form.Field.prototype.reset.createSequence(function() { 119 this.originalValue = this.defaultValue;120 this.setValue(this.defaultValue);119 this.originalValue = this.defaultValue; 120 this.setValue(this.defaultValue); 121 121 if (this.allowClear) 122 122 this.triggers[0].hide(); … … 133 133 134 134 onTrigger1Click : function() { 135 if(!this.disabled) {135 if (!this.disabled) { 136 136 this.clearValue(); 137 137 this.triggers[0].hide(); … … 141 141 this.el.dom.qtip = null; 142 142 this.fireEvent('clear', this); 143 }143 } 144 144 } 145 145 }); plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.form.TwinDateField.js
r29443 r29937 65 65 66 66 onTrigger1Click : function() { 67 if(!this.disabled) {67 if (!this.disabled) { 68 68 this.clearValue(); 69 69 this.triggers[0].hide(); … … 72 72 } 73 73 this.fireEvent('clear', this); 74 }74 } 75 75 }, 76 76 … … 87 87 this.value = ''; 88 88 }, 89 89 90 90 setValue : Ext.form.DateField.prototype.setValue.createSequence(function(v) { 91 91 if (v !== null && v != '') { plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.grid.CheckColumn.js
r29426 r29937 44 44 */ 45 45 Ext.ux.grid.CheckColumn = function(config) { 46 this.editable = false;46 this.editable = false; 47 47 Ext.apply(this, config); 48 48 if (!this.id) { plugins/ExtjsGeneratorPlugin/trunk/web/js/Ext.ux.grid.RowActions.js
r29740 r29937 4 4 * @class Ext.ux.grid.RowActions 5 5 * @extends Ext.util.Observable 6 * 6 * 7 7 * RowActions plugin for Ext grid. Contains renderer for icons and fires events 8 8 * when an icon is clicked. CSS rules from Ext.ux.RowActions.css are mandatory 9 * 9 * 10 10 * Important general information: Actions are identified by iconCls. Wherever an 11 11 * <i>action</i> is referenced (event argument, callback argument), the iconCls 12 12 * of clicked icon is used. In other words, action identifier === iconCls. 13 * 13 * 14 14 * @author Ing. Jozef Sak�� 15 15 * @copyright (c) 2008, by Ing. Jozef Sak�� … … 17 17 * @version 1.0 18 18 * @revision $Id: Ext.ux.grid.RowActions.js 747 2009-09-03 23:30:52Z jozo $ 19 * 19 * 20 20 * @license Ext.ux.grid.RowActions is licensed under the terms of the Open 21 21 * Source LGPL 3.0 license. Commercial use is permitted to the extent … … 23 23 * or Commercially licensed development library or toolkit without 24 24 * explicit permission. 25 * 25 * 26 26 * <p> 27 27 * License details: <a href="http://www.gnu.org/licenses/lgpl.html" 28 28 * target="_blank">http://www.gnu.org/licenses/lgpl.html</a> 29 29 * </p> 30 * 30 * 31 31 * @forum 29961 32 32 * @demo http://rowactions.extjs.eu … … 39 39 * <li><a href="http://rowactions.extjs.eu/rowactions.zip">rowactions.zip</a></li> 40 40 * </ul> 41 * 41 * 42 42 * @donate <form action="https://www.paypal.com/cgi-bin/webscr" method="post" 43 43 * target="_blank"> <input type="hidden" name="cmd" value="_s-xclick"> … … 66 66 /** 67 67 * Creates new RowActions plugin 68 * 68 * 69 69 * @constructor 70 70 * @param {Object} … … 76 76 // {{{ 77 77 this.addEvents( 78 /** 79 * @event beforeaction Fires before action event. Return false to cancel 80 * the subsequent action event. 81 * @param {Ext.grid.GridPanel} 82 * grid 83 * @param {Ext.data.Record} 84 * record Record corresponding to row clicked 85 * @param {String} 86 * action Identifies the action icon clicked. Equals to icon css 87 * class name. 88 * @param {Integer} 89 * rowIndex Index of clicked grid row 90 * @param {Integer} 91 * colIndex Index of clicked grid column that contains all action 92 * icons 93 */ 94 'beforeaction' 95 /** 96 * @event action Fires when icon is clicked 97 * @param {Ext.grid.GridPanel} 98 * grid 99 * @param {Ext.data.Record} 100 * record Record corresponding to row clicked 101 * @param {String} 102 * action Identifies the action icon clicked. Equals to icon css 103 * class name. 104 * @param {Integer} 105 * rowIndex Index of clicked grid row 106 * @param {Integer} 107 * colIndex Index of clicked grid column that contains all action 108 * icons 109 */ 110 , 'action' 111 /** 112 * @event beforegroupaction Fires before group action event. Return false 113 * to cancel the subsequent groupaction event. 114 * @param {Ext.grid.GridPanel} 115 * grid 116 * @param {Array} 117 * records Array of records in this group 118 * @param {String} 119 * action Identifies the action icon clicked. Equals to icon css 120 * class name. 121 * @param {String} 122 * groupId Identifies the group clicked 123 */ 124 , 'beforegroupaction' 125 /** 126 * @event groupaction Fires when icon in a group header is clicked 127 * @param {Ext.grid.GridPanel} 128 * grid 129 * @param {Array} 130 * records Array of records in this group 131 * @param {String} 132 * action Identifies the action icon clicked. Equals to icon css 133 * class name. 134 * @param {String} 135 * groupId Identifies the group clicked 136 */ 137 , 'groupaction'); 78 /** 79 * @event beforeaction Fires before action event. Return false to cancel the 80 * subsequent action event. 81 * @param {Ext.grid.GridPanel} 82 * grid 83 * @param {Ext.data.Record} 84 * record Record corresponding to row clicked 85 * @param {String} 86 * action Identifies the action icon clicked. Equals to icon css 87 * class name. 88 * @param {Integer} 89 * rowIndex Index of clicked grid row 90 * @param {Integer} 91 * colIndex Index of clicked grid column that contains all action 92 * icons 93 */ 94 'beforeaction' 95 /** 96 * @event action Fires when icon is clicked 97 * @param {Ext.grid.GridPanel} 98 * grid 99 * @param {Ext.data.Record} 100 * record Record corresponding to row clicked 101 * @param {String} 102 * action Identifies the action icon clicked. Equals to icon css 103 * class name. 104 * @param {Integer} 105 * rowIndex Index of clicked grid row 106 * @param {Integer} 107 * colIndex Index of clicked grid column that contains all action 108 * icons 109 */ 110 , 'action' 111 /** 112 * @event beforegroupaction Fires before group action event. Return false to 113 * cancel the subsequent groupaction event. 114 * @param {Ext.grid.GridPanel} 115 * grid 116 * @param {Array} 117 * records Array of records in this group 118 * @param {String} 119 * action Identifies the action icon clicked. Equals to icon css 120 * class name. 121 * @param {String} 122 * groupId Identifies the group clicked 123 */ 124 , 'beforegroupaction' 125 /** 126 * @event groupaction Fires when icon in a group header is clicked 127 * @param {Ext.grid.GridPanel} 128 * grid 129 * @param {Array} 130 * records Array of records in this group 131 * @param {String} 132 * action Identifies the action icon clicked. Equals to icon css 133 * class name. 134 * @param {String} 135 * groupId Identifies the group clicked 136 */ 137 , 'groupaction' 138 ); 138 139 // }}} 139 140 … … 242 243 * @cfg {Object} callbacks iconCls keyed object that contains callback 243 244 * functions. For example: 244 * 245 * 245 246 * <pre> 246 247 * callbacks:{ … … 301 302 , 302 303 tplRow : '<div class="ux-row-action">' + '<tpl for="actions">' + '<div class="ux-row-action-item {cls} <tpl if="text">' + 'ux-row-action-text</tpl>" style="{hide}{style}" qtip="{qtip}">' 303 + '<tpl if="text"><span qtip="{qtip}">{text}</span></tpl></div>' + '</tpl>' + '</div>'304 + '<tpl if="text"><span qtip="{qtip}">{text}</span></tpl></div>' + '</tpl>' + '</div>' 304 305 305 306 /** … … 332 333 /** 333 334 * Init function 334 * 335 * 335 336 * @param {Ext.grid.GridPanel} 336 337 * grid Grid this plugin is in … … 349 350 lookup[this.id] = this; 350 351 351 if(!this.actions) 352 { 352 if (!this.actions) { 353 353 var colIndex = grid.getColumnModel().getIndexById(this.id); 354 354 var config = grid.getColumnModel().config; 355 grid.getColumnModel().config = [config[colIndex]]; 355 grid.getColumnModel().config = [ 356 config[colIndex] 357 ]; 356 358 config.splice(colIndex, 1); 357 359 grid.getColumnModel().setConfig(config); … … 380 382 cfg[this.actionEvent] = this.onClick; 381 383 grid.afterRender = grid.afterRender.createSequence(function() { 382 view.mainBody.on(cfg);383 grid.on('destroy', this.purgeListeners, this);384 }, this);384 view.mainBody.on(cfg); 385 grid.on('destroy', this.purgeListeners, this); 386 }, this); 385 387 386 388 // setup renderer … … 395 397 if (view.groupTextTpl && this.groupActions) { 396 398 view.interceptMouse = view.interceptMouse.createInterceptor(function(e) { 397 if (e.getTarget('.ux-grow-action-item')) {398 return false;399 }400 });399 if (e.getTarget('.ux-grow-action-item')) { 400 return false; 401 } 402 }); 401 403 view.groupTextTpl = '<div class="ux-grow-action-text">' + view.groupTextTpl + '</div>' + this.processActions(this.groupActions, this.tplGroup).apply(); 402 404 } … … 405 407 if (true === this.keepSelection) { 406 408 grid.processEvent = grid.processEvent.createInterceptor(function(name, e) { 407 if ('mousedown' === name) {408 return !this.getAction(e);409 }410 }, this);409 if ('mousedown' === name) { 410 return !this.getAction(e); 411 } 412 }, this); 411 413 } 412 414 … … 414 416 if (Ext.util.CSS.getRule('.ux-row-action-cell') == null) { 415 417 var styleBody = '.ux-row-action-cell .x-grid3-cell-inner {padding: 1px 0 0 0;}' 416 + '.ux-row-action-item {float: left;min-width: 16px;height: 16px;background-repeat: no-repeat;margin: 0 5px 0 0;cursor: pointer;overflow: hidden;}'417 + '.ext-ie .ux-row-action-item {width: 16px;}'418 + '.ext-ie .ux-row-action-text {width: auto;}'419 + '.ux-row-action-item span {vertical-align:middle; padding: 0 0 0 20px; line-height: 18px;}'420 + '.ext-ie .ux-row-action-item span {width: auto;}'421 + '.x-grid-group-hd div {position: relative;height: 16px;}'422 + '.ux-grow-action-item {min-width: 16px;height: 16px;background-repeat: no-repeat;background-position: 0 50% ! important;margin: 0 0 0 4px;padding: 0 ! important;cursor: pointer;float: left;}'423 + '.ext-ie .ux-grow-action-item {width: 16px;}' + '.ux-action-right {float: right;margin: 0 3px 0 2px;padding: 0 ! important;}'424 + '.ux-grow-action-text {padding: 0 ! important;margin: 0 ! important;background: transparent none ! important;float: left;}'418 + '.ux-row-action-item {float: left;min-width: 16px;height: 16px;background-repeat: no-repeat;margin: 0 5px 0 0;cursor: pointer;overflow: hidden;}' 419 + '.ext-ie .ux-row-action-item {width: 16px;}' 420 + '.ext-ie .ux-row-action-text {width: auto;}' 421 + '.ux-row-action-item span {vertical-align:middle; padding: 0 0 0 20px; line-height: 18px;}' 422 + '.ext-ie .ux-row-action-item span {width: auto;}' 423 + '.x-grid-group-hd div {position: relative;height: 16px;}' 424 + '.ux-grow-action-item {min-width: 16px;height: 16px;background-repeat: no-repeat;background-position: 0 50% ! important;margin: 0 0 0 4px;padding: 0 ! important;cursor: pointer;float: left;}' 425 + '.ext-ie .ux-grow-action-item {width: 16px;}' + '.ux-action-right {float: right;margin: 0 3px 0 2px;padding: 0 ! important;}' 426 + '.ux-grow-action-text {padding: 0 ! important;margin: 0 ! important;background: transparent none ! important;float: left;}' 425 427 426 428 var styleSheet = Ext.util.CSS.createStyleSheet('/* Ext.ux.grid.RowActions stylesheet */\n' + styleBody, 'RowActions'); … … 433 435 /** 434 436 * Returns data to apply to template. Override this if needed. 435 * 437 * 436 438 * @param {Mixed} 437 439 * value … … 456 458 /** 457 459 * Processes actions configs and returns template. 458 * 460 * 459 461 * @param {Array} 460 462 * actions … … 470 472 // actions loop 471 473 Ext.each(actions, function(a, i) { 472 // save callback 473 if (a.iconCls && 'function' === typeof(a.callback || a.cb)) { 474 this.callbacks = this.callbacks || {}; 475 this.callbacks[a.iconCls] = a.callback || a.cb; 476 } 477 478 // data for intermediate template 479 var o = { 480 cls : a.iconIndex ? '{' + a.iconIndex + '}' : (a.iconCls ? a.iconCls : ''), 481 qtip : a.qtipIndex ? '{' + a.qtipIndex + '}' : (a.tooltip || a.qtip ? a.tooltip || a.qtip : ''), 482 text : a.textIndex ? '{' + a.textIndex + '}' : (a.text ? a.text : ''), 483 hide : a.hideIndex ? '<tpl if="' + a.hideIndex + '">' + ('display' === this.hideMode ? 'display:none' : 'visibility:hidden') + ';</tpl>' : (a.hide ? ('display' === this.hideMode 484 ? 'display:none' 485 : 'visibility:hidden;') : ''), 486 align : a.align || 'right', 487 style : a.style ? a.style : '' 488 }; 489 acts.push(o); 490 491 }, this); // eo actions loop 474 // save callback 475 if (a.iconCls && 'function' === typeof(a.callback || a.cb)) { 476 this.callbacks = this.callbacks || {}; 477 this.callbacks[a.iconCls] = a.callback || a.cb; 478 } 479 480 // data for intermediate template 481 var o = { 482 cls : a.iconIndex ? '{' + a.iconIndex + '}' : (a.iconCls ? a.iconCls : ''), 483 qtip : a.qtipIndex ? '{' + a.qtipIndex + '}' : (a.tooltip || a.qtip ? a.tooltip || a.qtip : ''), 484 text : a.textIndex ? '{' + a.textIndex + '}' : (a.text ? a.text : ''), 485 hide : a.hideIndex ? '<tpl if="' + a.hideIndex + '">' + ('display' === this.hideMode ? 'display:none' : 'visibility:hidden') + ';</tpl>' : (a.hide ? ('display' === this.hideMode 486 ? 'display:none' : 'visibility:hidden;') : ''), 487 align : a.align || 'right', 488 style : a.style ? a.style : '' 489 }; 490 acts.push(o); 491 492 }, this); // eo actions loop 492 493 493 494 var xt = new Ext.XTemplate(template || this.tplRow); 494 495 return new Ext.XTemplate(xt.apply({ 495 actions : acts496 }));496 actions : acts 497 })); 497 498 498 499 } // eo function processActions … … 514 515 /** 515 516 * Grid body actionEvent event handler 516 * 517 * 517 518 * @private 518 519 */ … … 565 566 var re = new RegExp(RegExp.escape(groupId)); 566 567 records = this.grid.store.queryBy(function(r) { 567 return r._groupId.match(re);568 });568 return r._groupId.match(re); 569 }); 569 570 records = records ? records.items : []; 570 571 } … … 583 584 } 584 585 } // eo function onClick 585 // }}} 586 587 }); 586 // }}} 587 588 } 589 ); 588 590 589 591 // registre xtype plugins/ExtjsGeneratorPlugin/trunk/web/js/ExtjsGeneratorConstants.js
r29426 r29937 1 1 Ext.ux.IconMgr.setIconPath('/ExtjsGeneratorPlugin/Ext.ux.IconMgr'); 2 2 Ext.state.Manager.setProvider(new Ext.state.CookieProvider({ 3 expires: new Date(new Date().getTime()+(1000*60*60*24*7))3 expires : new Date(new Date().getTime() + (1000 * 60 * 60 * 24 * 7)) 4 4 })); plugins/ExtjsGeneratorPlugin/trunk/web/js/ext-basex.js
r29426 r29937 2 2 /** 3 3 * @version 4.1 4 * *********************************************************************************** 5 * 6 * Ext.lib.Ajax enhancements: - adds EventManager Support to Ext.lib.Ajax (if 7 * Ext.util.Observable is present in the stack) - adds Synchronous Ajax Support ( 8 * options.async =false ) - Permits IE to Access Local File Systems using IE's 9 * older ActiveX interface via the forceActiveX property - Pluggable Form 10 * encoder (encodeURIComponent is still the default encoder) - Corrects the 11 * Content-Type Headers for posting JSON (application/json) and XML (text/xml) 12 * data payloads and sets only one value (per RFC) - Adds fullStatus:{ isLocal, 13 * proxied, isOK, isError, isTimeout, isAbort, error, status, statusText} object 14 * to the existing Response Object. - Adds standard HTTP Auth cache support to 15 * every request (XHR userId, password config options) - options.method prevails 16 * over any method derived by the lib.Ajax stack (DELETE, PUT, HEAD etc). - Adds 17 * named-Priority-Queuing for Ajax Requests - adds Script=Tag support for 18 * foreign-domains (proxied:true) with configurable callbacks. - Adds final 19 * features for $JIT support. 20 * - Adds Browser capabilities object reporting on presence of: 21 * Ext.capabilities.isEventSupported('resize'[, forElement]) to determine if the 22 * browser supports a specific event. SVG, Canvas, Flash, Cookies, XPath, 23 * Audio(HTML5), ChromeFrame (IE) if(Ext.capabilities.hasFlash){ ... } - Adds 24 * Ext.overload supported for parameter-based overloading of Function and class 25 * methods. - Adds Ext.clone functions for any datatype. - Adds Array prototype 26 * features: first, last, clone, forEach, atRandom, include, flatten, compact, 27 * unique, filter, map - Connection/response object members : 28 * getAllResponseHeaders, getResponseHeader are now functions. - Adds 29 * Array.slice support for other browsers (Gecko already supports it) 30 * @example: Array.slice( someArray, 2 ) - Adds Ext[isFunction, isObject, 31 * isDocument, isElement, isEvent] methods. - Adds multiPart Response 32 * handling (via onpart callbacks and/or parts Array of response 33 * Object) - Adds parsed contentType to response objects - Adds 34 * Xdomain request support for modern browsers 35 * 4 36 * *********************************************************************************** 5 * 6 * Ext.lib.Ajax enhancements: 7 * - adds EventManager Support to Ext.lib.Ajax (if Ext.util.Observable is present in the stack) 8 * - adds Synchronous Ajax Support ( options.async =false ) 9 * - Permits IE to Access Local File Systems using IE's older ActiveX interface via the forceActiveX property 10 * - Pluggable Form encoder (encodeURIComponent is still the default encoder) 11 * - Corrects the Content-Type Headers for posting JSON (application/json) and XML (text/xml) 12 * data payloads and sets only one value (per RFC) 13 * - Adds fullStatus:{ isLocal, proxied, isOK, isError, isTimeout, isAbort, error, status, statusText} object 14 * to the existing Response Object. 15 * - Adds standard HTTP Auth cache support to every request (XHR userId, password config options) 16 * - options.method prevails over any method derived by the lib.Ajax stack (DELETE, PUT, HEAD etc). 17 * - Adds named-Priority-Queuing for Ajax Requests 18 * - adds Script=Tag support for foreign-domains (proxied:true) with configurable callbacks. 19 * - Adds final features for $JIT support. 20 * 21 * - Adds Browser capabilities object reporting on presence of: 22 * Ext.capabilities.isEventSupported('resize'[, forElement]) to determine if the browser supports a specific event. 23 * SVG, Canvas, Flash, Cookies, XPath, Audio(HTML5), ChromeFrame (IE) 24 * if(Ext.capabilities.hasFlash){ ... } 25 * - Adds Ext.overload supported for parameter-based overloading of Function and class methods. 26 * - Adds Ext.clone functions for any datatype. 27 * - Adds Array prototype features: first, last, clone, forEach, atRandom, include, flatten, compact, unique, filter, map 28 * - Connection/response object members : getAllResponseHeaders, getResponseHeader are now functions. 29 * - Adds Array.slice support for other browsers (Gecko already supports it) 30 * @example: Array.slice( someArray, 2 ) 31 * - Adds Ext[isFunction, isObject, isDocument, isElement, isEvent] methods. 32 * - Adds multiPart Response handling (via onpart callbacks and/or parts Array of response Object) 33 * - Adds parsed contentType to response objects 34 * - Adds Xdomain request support for modern browsers 35 * 36 * *********************************************************************************** 37 * @author Doug Hendricks. doug[always-At]theactivegroup.com 37 * @author Doug Hendricks. doug[always-At]theactivegroup.com 38 38 * @copyright 2007-2009, Active Group, Inc. All rights reserved. 39 * ***********************************************************************************40 * 39 * *********************************************************************************** 40 * 41 41 * @license <a href="http://www.gnu.org/licenses/gpl.html">GPL 3.0</a> 42 * 42 * 43 43 * Commercial use is prohibited without a Developer License, see: 44 44 * http://licensing.theactivegroup.com. 45 * 45 * 46 46 * This program is free software: you can redistribute it and/or modify it under 47 47 * the terms of the GNU General Public License as published by the Free Software 48 48 * Foundation, either version 3 of the License, or any later version. 49 * 49 * 50 50 * This program is distributed in the hope that it will be useful, but WITHOUT 51 51 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 52 52 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 53 53 * details. 54 * 54 * 55 55 * You should have received a copy of the GNU General Public License along with 56 56 * this program. If not, see < http://www.gnu.org/licenses/gpl.html>. 57 * 57 * 58 58 * Donations are welcomed: http://donate.theactivegroup.com 59 * 59 * 60 60 */ 61 61 62 62 (function() { 63 var A = Ext.lib.Ajax, 64 defined = function(test){return typeof test != 'undefined';}, 65 emptyFn = Ext.emptyFn || function(){}, 66 OP = Object.prototype; 67 68 69 Ext.lib.Ajax.Queue = function(config) { 70 71 config = config ? (config.name ? config : { name : config }) : {}; 72 Ext.apply(this, config, { 73 name : 'q-default', 74 priority : 5, 75 FIFO : true, // false implies LIFO 76 callback : null, // optional callback when queue is emptied 77 scope : null, // scope of callback 78 suspended : false, 79 progressive : false // if true, one queue item is dispatched per poll interval 80 81 }); 82 this.requests = new Array(); 63 var A = Ext.lib.Ajax, defined = function(test) { 64 return typeof test != 'undefined'; 65 }, emptyFn = Ext.emptyFn || function() {}, OP = Object.prototype; 66 67 Ext.lib.Ajax.Queue = function(config) { 68 69 config = config ? (config.name ? config : { 70 name : config 71 }) : {}; 72 Ext.apply(this, config, { 73 name : 'q-default', 74 priority : 5, 75 FIFO : true, // false implies LIFO 76 callback : null, // optional callback when queue is emptied 77 scope : null, // scope of callback 78 suspended : false, 79 progressive : false 80 // if true, one queue item is dispatched per poll interval 81 82 } 83 ); 84 this.requests = new Array(); 85 this.pending = false; 86 // assert/resolve to 0-9 87 this.priority = this.priority > 9 ? 9 : (this.priority < 0 ? 0 : this.priority); 88 }; 89 90 Ext.extend(Ext.lib.Ajax.Queue, Object, { 91 /** 92 * Adds Ext.lib.Ajax.request arguments to queue 93 * 94 * @param {Array} 95 * request An array of request method arguments. 96 * 97 */ 98 add : function(req) { 99 100 var permit = A.events ? A.fireEvent('beforequeue', this, req) : true; 101 if (permit !== false) { 102 this.requests.push(req); 103 this.pending = true; 104 A.pendingRequests++; 105 this.manager && this.manager.start(); 106 } 107 }, 108 109 /** 110 * @property {Boolean} suspended Indicate the suspense state of the queue. 111 */ 112 suspended : false, 113 /** 114 * @property {Object} activeRequest A reference to current/last active 115 * request. 116 */ 117 activeRequest : null, 118 119 /** 120 * Selects the next item on the queue stack 121 * 122 * @param {Boolean} 123 * peek If true, the queue item is returned but not removed from 124 * the stack. @ default false 125 */ 126 next : function(peek) { 127 var req = peek ? this.requests[this.FIFO ? 'first' : 'last']() : this.requests[this.FIFO ? 'shift' : 'pop'](); 128 129 if (this.requests.length == 0) { 130 // queue emptied callback 83 131 this.pending = false; 84 // assert/resolve to 0-9 85 this.priority = this.priority > 9 ? 9 : (this.priority < 0 ? 0 : this.priority); 86 }; 87 88 Ext.extend(Ext.lib.Ajax.Queue, Object, { 89 /** 90 * Adds Ext.lib.Ajax.request arguments to queue 91 * @param {Array} request An array of request method arguments. 92 * 93 */ 94 add : function(req) { 95 96 var permit = A.events ? A.fireEvent('beforequeue', this, req) : true; 97 if (permit !== false) { 98 this.requests.push(req); 99 this.pending = true; 100 A.pendingRequests++; 101 this.manager && this.manager.start(); 132 Ext.isFunction(this.callback) && this.callback.call(this.scope || null, this); 133 A.events && A.fireEvent('queueempty', this); 134 } 135 return req || null; 136 }, 137 138 /** 139 * clear the queue of any remaining (pending) requests 140 */ 141 clear : function() { 142 this.suspend(); 143 A.pendingRequests -= this.requests.length; 144 this.requests.length = 0; 145 this.pending = false; 146 this.resume(); 147 this.next(); // force the empty callback/event 148 149 }, 150 151 /** 152 * Suspend queue further queue dispatches of any remaining (pending) 153 * requests until the {@link #Ext.ux.ModuleManager-resume} method is called. 154 */ 155 suspend : function() { 156 this.suspended = true; 157 }, 158 159 /** Resume from a suspended state */ 160 resume : function() { 161 this.suspended = false; 162 }, 163 164 /** 165 * Dispatches the next queue item and initiates a Ext.lib.Ajax request on 166 * the result. 167 * 168 * @param {Boolean} 169 * peek If true, the queue item is returned but not removed from 170 * the stack. 171 * @return activeRequest 172 */ 173 requestNext : function(peek) { 174 var req; 175 this.activeRequest = null; 176 if (!this.suspended && (req = this.next(peek))) { 177 if (req.active) { // was it aborted 178 this.activeRequest = A.request.apply(A, req); 179 A.pendingRequests--; 180 } else { 181 return this.requestNext(peek); 182 } 183 } 184 return this.activeRequest; 185 } 186 }); 187 188 Ext.lib.Ajax.QueueManager = function(config) { 189 190 Ext.apply(this, config || {}, { 191 quantas : 10, // adjustable milliseconds deferred dispatch 192 // value 193 priorityQueues : new Array(new Array(), new Array(), new Array(), new Array(), new Array(), new Array(), new Array(), new Array(), new Array(), new Array()), // iterable 194 // array 195 // (0-9) 196 // of 197 // prioritized 198 // queues: 199 queues : {} 200 }); 201 }; 202 203 Ext.extend(Ext.lib.Ajax.QueueManager, Object, { 204 /** 205 * @cfg {Integer} quantas Adjustable milliseconds deferred dispatch timer 206 * interval 207 */ 208 quantas : 10, 209 210 /** 211 * Return a named queue reference param {String} name The name of the 212 * desired queue. 213 * 214 * @return Ext.lib.Ajax.Queue 215 */ 216 getQueue : function(name) { 217 return this.queues[name]; 218 }, 219 220 createQueue : function(config) { 221 if (!config) { 222 return null; 223 } 224 225 var q = new A.Queue(config); 226 q.manager = this; 227 this.queues[q.name] = q; 228 229 var pqa = this.priorityQueues[q.priority]; 230 pqa && pqa.indexOf(q.name) == -1 && pqa.push(q.name); 231 return q; 232 }, 233 /** 234 * Remove a Queue by passed name or Queue Object reference 235 * 236 * @param {String/Ext.lib.Ajax.Queue} 237 * queue 238 */ 239 removeQueue : function(q) { 240 if (q && (q = this.getQueue(q.name || q))) { 241 q.clear(); // purge any pending requests 242 this.priorityQueues[q.priority].remove(q.name); 243 delete this.queues[q.name]; 244 } 245 }, 246 247 /** @private */ 248 start : function() { 249 if (!this.started) { 250 this.started = true; 251 this.dispatch(); 252 } 253 return this; 254 }, 255 256 /** Suspends all defined queues */ 257 suspendAll : function() { 258 forEach(this.queues, function(Q) { 259 Q.suspend(); 260 }); 261 }, 262 263 /** Resumes all suspended queues */ 264 resumeAll : function() { 265 forEach(this.queues, function(Q) { 266 Q.resume(); 267 }); 268 this.start(); 269 }, 270 271 /** 272 * @cfg (Boolean) progressive Default Dispatch mode for all defined queues 273 * <p> 274 * a false value will exhaust a priority queue until empty during 275 * dispatch (sequential) 276 * <p> 277 * true to dispatch a single request from each priority queue until all 278 * queues exhausted. 279 * <p> 280 * This option may be set on the Queue itself as well. 281 * @default false 282 */ 283 progressive : false, 284 285 stop : function() { 286 this.started = false; 287 return this; 288 }, 289 290 /** 291 * private main Request dispatch loop. This keeps the maximum allowed number 292 * of requests going at any one time (based on defined queue priority and 293 * dispatch mode (see progressive). 294 */ 295 296 dispatch : function() { 297 var qm = this, qmq = qm.queues; 298 var quit = (A.activeRequests > A.maxConcurrentRequests); 299 while (A.pendingRequests && !quit) { 300 301 var disp = function(qName) { 302 var q = qmq[qName], AR; 303 304 while (q && !q.suspended && q.pending && q.requestNext()) { 305 306 quit || (quit = A.activeRequests > A.maxConcurrentRequests); 307 if (quit) 308 break; 309 310 // progressive, take the first one off each queue only 311 if (q.progressive || qm.progressive) { 312 break; 102 313 } 314 315 } 316 // keep going? 317 if (quit) 318 return false; 319 }; 320 321 forEach(this.priorityQueues, function(pqueue) { 322 // pqueue == array of queue names 323 !!pqueue.length && forEach(pqueue, disp, this); 324 quit || (quit = A.activeRequests > A.maxConcurrentRequests); 325 if (quit) 326 return false; 327 }, this); 328 329 } 330 331 if (A.pendingRequests || quit) { 332 this.dispatch.defer(this.quantas, this); 333 } else { 334 this.stop(); 335 } 336 } 337 }); 338 339 Ext.apply(A, { 340 341 headers : A.headers || {}, 342 defaultPostHeader : A.defaultPostHeader || 'application/x-www-form-urlencoded; charset=UTF-8', 343 defaultHeaders : A.defaultHeaders || {}, 344 useDefaultXhrHeader : !!A.useDefaultXhrHeader, 345 defaultXhrHeader : 'Ext.basex', 346 347 // Reusable script tag pool for IE. 348 SCRIPTTAG_POOL : [], 349 _domRefs : [], 350 onUnload : function() { 351 delete A._domRefs; 352 delete A.SCRIPTTAG_POOL; 353 }, 354 355 /** 356 * private -- <script and link> tag support 357 */ 358 monitoredNode : function(tag, attributes, callback, context, deferred) { 359 360 var node = null, doc = (context || window).document, head = doc ? doc.getElementsByTagName("head")[0] : null; 361 362 if (tag && doc && head) { 363 node = tag.toUpperCase() == 'SCRIPT' && !!A.SCRIPTTAG_POOL.length ? Ext.get(A.SCRIPTTAG_POOL.pop()) : null; 364 if (node) { 365 node.removeAllListeners(); 366 } else { 367 node = Ext.get(doc.createElement(tag)); 368 } 369 var ndom = Ext.getDom(node); 370 371 ndom && forEach(attributes || {}, function(value, attrib) { 372 373 value && (attrib in ndom) && ndom.setAttribute(attrib, value); 374 }); 375 376 if (callback) { 377 var cb = (callback.success || callback).createDelegate(callback.scope || null, [ 378 callback || {} 379 ], 0); 380 381 Ext.isIE ? node.on('readystatechange', function() { 382 this.dom.readyState == 'loaded' && cb(); 383 }) : node.on("load", cb); 384 } 385 deferred || ndom.parentNode || head.appendChild(ndom); 386 } 387 A._domRefs.push(node); 388 return node; 389 }, 390 391 poll : {}, 392 393 pollInterval : A.pollInterval || 50, 394 395 queueManager : new A.QueueManager(), 396 397 // If true (or queue config object) ALL requests are queued 398 queueAll : false, 399 400 // the Current number of active Ajax requests. 401 activeRequests : 0, 402 403 // the Current number of pending Queued requests. 404 pendingRequests : 0, 405 406 /** 407 * @property maxConcurrentRequests Specify the maximum allowed during 408 * concurrent Queued browser (XHR) requests Note: IE8 increases 409 * this limit to 6 410 */ 411 maxConcurrentRequests : Ext.isIE ? Ext.value(window.maxConnectionsPerServer, 2) : 4, 412 413 /** 414 * set True as needed, to coerce IE to use older ActiveX interface 415 */ 416 forceActiveX : false, 417 418 /** 419 * Global default may be toggled at any time 420 */ 421 async : true, 422 423 /** private */ 424 createXhrObject : function(transactionId, options) { 425 var obj = { 426 status : { 427 isError : false 103 428 }, 104 429 105 /** 106 * @property {Boolean} suspended Indicate the suspense state of the queue. 107 */ 108 suspended : false, 109 /** 110 * @property {Object} activeRequest A reference to current/last active request. 111 */ 112 activeRequest : null, 113 114 /** 115 * Selects the next item on the queue stack 116 * @param {Boolean} peek If true, the queue item is returned but not removed from the stack. 117 * @ default false 118 */ 119 next : function(peek) { 120 var req = peek ? 121 this.requests[this.FIFO ? 'first' : 'last']() 122 :this.requests[this.FIFO ? 'shift' : 'pop'](); 123 124 if (this.requests.length == 0) { 125 // queue emptied callback 126 this.pending = false; 127 Ext.isFunction(this.callback) && this.callback.call(this.scope || null, this); 128 A.events && A.fireEvent('queueempty', this); 129 } 130 return req || null; 131 }, 132 133 /** 134 * clear the queue of any remaining (pending) requests 135 */ 136 clear : function() { 137 this.suspend(); 138 A.pendingRequests -= this.requests.length; 139 this.requests.length = 0; 140 this.pending = false; 141 this.resume(); 142 this.next(); //force the empty callback/event 143 144 }, 145 146 /** 147 * Suspend queue further queue dispatches of any remaining (pending) requests until the {@link #Ext.ux.ModuleManager-resume} method is called. 148 */ 149 suspend : function() { 150 this.suspended = true; 151 }, 152 153 /** Resume from a suspended state */ 154 resume : function() { 155 this.suspended = false; 156 }, 157 158 /** 159 * Dispatches the next queue item and initiates a Ext.lib.Ajax request on the result. 160 * @param {Boolean} peek If true, the queue item is returned but not removed from the stack. 161 * @return activeRequest 162 */ 163 requestNext : function(peek) { 164 var req; 165 this.activeRequest = null; 166 if (!this.suspended && (req = this.next(peek))) { 167 if(req.active){ //was it aborted 168 this.activeRequest = A.request.apply(A,req); 169 A.pendingRequests--; 170 } else { 171 return this.requestNext(peek); 172 } 173 } 174 return this.activeRequest; 175 } 176 }); 177 178 Ext.lib.Ajax.QueueManager = function(config) { 179 180 Ext.apply(this, config || {}, { 181 quantas : 10, // adjustable milliseconds deferred dispatch 182 // value 183 priorityQueues : new Array(new Array(), new Array(), 184 new Array(), new Array(), new Array(), new Array(), 185 new Array(), new Array(), new Array(), new Array()), // iterable 186 // array 187 // (0-9) 188 // of 189 // prioritized 190 // queues: 191 queues : {} 192 }); 193 }; 194 195 Ext.extend(Ext.lib.Ajax.QueueManager, Object, { 196 /** 197 * @cfg {Integer} quantas Adjustable milliseconds deferred dispatch timer interval 198 */ 199 quantas : 10, 200 201 /** Return a named queue reference 202 * param {String} name The name of the desired queue. 203 * @return Ext.lib.Ajax.Queue 204 */ 205 getQueue : function(name) { 206 return this.queues[name]; 207 }, 208 209 createQueue : function(config) { 210 if (!config) {return null;} 211 212 var q = new A.Queue(config); 213 q.manager = this; 214 this.queues[q.name] = q; 215 216 var pqa = this.priorityQueues[q.priority]; 217 pqa && pqa.indexOf(q.name) == -1 && pqa.push(q.name); 218 return q; 219 }, 220 /** Remove a Queue by passed name or Queue Object reference 221 * @param {String/Ext.lib.Ajax.Queue} queue 222 */ 223 removeQueue : function(q) { 224 if (q && (q = this.getQueue(q.name || q))) { 225 q.clear(); // purge any pending requests 226 this.priorityQueues[q.priority].remove(q.name); 227 delete this.queues[q.name]; 228 } 229 }, 230 231 /** @private */ 232 start : function() { 233 if (!this.started) { 234 this.started = true; 235 this.dispatch(); 236 } 237 return this; 238 }, 239 240 /** Suspends all defined queues */ 241 suspendAll : function() { 242 forEach(this.queues, function(Q) { Q.suspend(); }); 243 }, 244 245 /** Resumes all suspended queues */ 246 resumeAll : function() { 247 forEach(this.queues, function(Q) { Q.resume(); }); 248 this.start(); 249 }, 250 251 /** 252 * @cfg (Boolean) progressive Default Dispatch mode for all defined queues<p> 253 * a false value will exhaust a priority queue until empty during dispatch (sequential) <p> 254 * true to dispatch a single request from each priority queue until all queues exhausted.<p>This 255 * option may be set on the Queue itself as well. 256 * @default false 257 */ 258 progressive : false, 259 260 stop : function() { 261 this.started = false; 262 return this; 263 }, 264 265 /** private 266 * main Request dispatch loop. This keeps the maximum allowed number of 267 * requests going at any one time (based on defined queue priority and 268 * dispatch mode (see progressive). 269 */ 270 271 dispatch : function(){ 272 var qm = this, qmq = qm.queues; 273 var quit=(A.activeRequests > A.maxConcurrentRequests); 274 while(A.pendingRequests && !quit){ 275 276 var disp = function(qName) { 277 var q = qmq[qName], AR; 278 279 while (q && !q.suspended && q.pending && q.requestNext()) { 280 281 quit || (quit = A.activeRequests > A.maxConcurrentRequests); 282 if(quit)break; 283 284 // progressive, take the first one off each queue only 285 if (q.progressive || qm.progressive) { break;} 286 287 } 288 // keep going? 289 if(quit)return false; 290 }; 291 292 forEach(this.priorityQueues, function(pqueue) { 293 // pqueue == array of queue names 294 !!pqueue.length && forEach(pqueue , disp, this); 295 quit || (quit = A.activeRequests > A.maxConcurrentRequests); 296 if(quit)return false; 297 }, this); 298 299 } 300 301 if(A.pendingRequests || quit){ 302 this.dispatch.defer(this.quantas, this); 303 } else{ 304 this.stop(); 305 } 306 } 307 }); 308 309 Ext.apply(A, { 310 311 headers : A.headers || {}, 312 defaultPostHeader : A.defaultPostHeader || 'application/x-www-form-urlencoded; charset=UTF-8', 313 defaultHeaders : A.defaultHeaders || {}, 314 useDefaultXhrHeader : !!A.useDefaultXhrHeader, 315 defaultXhrHeader : 'Ext.basex', 316 317 //Reusable script tag pool for IE. 318 SCRIPTTAG_POOL : [], 319 _domRefs : [], 320 onUnload : function(){ 321 delete A._domRefs; 322 delete A.SCRIPTTAG_POOL; 323 }, 324 325 /** 326 * private -- <script and link> tag support 327 */ 328 monitoredNode : function(tag, attributes, callback, context, deferred) { 329 330 var node = null, doc = (context || window).document, 331 head = doc ? doc.getElementsByTagName("head")[0] : null; 332 333 if (tag && doc && head) { 334 node = tag.toUpperCase() == 'SCRIPT' && !!A.SCRIPTTAG_POOL.length ? Ext.get(A.SCRIPTTAG_POOL.pop()) : null; 335 if(node){ 336 node.removeAllListeners(); 337 }else{ 338 node = Ext.get(doc.createElement(tag)); 339 } 340 var ndom = Ext.getDom(node); 341 342 ndom && forEach(attributes || {}, function(value, attrib) { 343 344 value && (attrib in ndom) && ndom.setAttribute(attrib, value); 345 }); 346 347 if (callback) { 348 var cb = (callback.success || callback).createDelegate(callback.scope || null, [callback||{}], 0); 349 350 Ext.isIE ? node.on('readystatechange', function(){ 351 this.dom.readyState == 'loaded' && cb(); 352 }) : node.on("load", cb); 353 } 354 deferred || ndom.parentNode || head.appendChild(ndom); 355 } 356 A._domRefs.push(node); 357 return node; 358 }, 359 360 poll : {}, 361 362 pollInterval : A.pollInterval || 50, 363 364 queueManager : new A.QueueManager(), 365 366 // If true (or queue config object) ALL requests are queued 367 queueAll : false, 368 369 // the Current number of active Ajax requests. 370 activeRequests : 0, 371 372 // the Current number of pending Queued requests. 373 pendingRequests : 0, 374 375 /** 376 * @property maxConcurrentRequests 377 * Specify the maximum allowed during concurrent Queued browser (XHR) requests 378 * Note: IE8 increases this limit to 6 379 */ 380 maxConcurrentRequests : Ext.isIE ? Ext.value(window.maxConnectionsPerServer, 2) : 4, 381 382 /** set True as needed, to coerce IE to use older ActiveX interface 383 */ 384 forceActiveX : false, 385 386 /** 387 * Global default may be toggled at any time 388 */ 389 async : true, 390 391 /** private */ 392 createXhrObject : function(transactionId, options) { 393 var obj = { 394 status : { 395 isError : false 396 }, 397 398 tId : transactionId 399 }, 400 ecode = null; 401 402 options || (options = {}); 430 tId : transactionId 431 }, ecode = null; 432 433 options || (options = {}); 434 try { 435 options.xdomain && window.XDomainRequest && (obj.conn = new XDomainRequest()); 436 437 if (!defined(obj.conn) && Ext.capabilities.hasActiveX && !!Ext.value(options.forceActiveX, this.forceActiveX)) { 438 throw ("IE7forceActiveX"); 439 } 440 obj.conn || (obj.conn = new XMLHttpRequest()); 441 442 } catch (eo) { 443 var actX = Ext.capabilities.hasActiveX ? (options.multiPart ? this.activeXMultipart : this.activeX) : null; 444 445 if (actX) { 446 for (var i = 0, l = actX.length; i < l; ++i) { 403 447 try { 404 options.xdomain && window.XDomainRequest && (obj.conn = new XDomainRequest()); 405 406 if (!defined(obj.conn) && 407 Ext.capabilities.hasActiveX && 408 !!Ext.value(options.forceActiveX, this.forceActiveX)) { 409 throw ("IE7forceActiveX"); 410 } 411 obj.conn || (obj.conn = new XMLHttpRequest()); 412 413 } catch (eo) { 414 var actX = Ext.capabilities.hasActiveX ? 415 ( options.multiPart ? this.activeXMultipart : this.activeX ) : null ; 416 417 if(actX){ 418 for (var i = 0, l = actX.length; i < l; ++i) { 419 try { 420 obj.conn = new ActiveXObject(actX[i]); 421 break; 422 } catch (e) {ecode = (eo == "IE7forceActiveX"? e: eo);} 423 } 424 } 425 } finally { 426 obj.status.isError = !defined(obj.conn); 427 obj.status.error= ecode; 428 } 429 return obj; 430 431 }, 432 433 createExceptionObject: function (tId, callbackArg, isAbort, isTimeout, errObj) { 434 return { 435 tId : tId, 436 status : isAbort ? -1 : 0, 437 statusText : isAbort ? 'transaction aborted' : 'communication failure', 438 isAbort: isAbort, 439 isTimeout: isTimeout, 440 argument : callbackArg 441 }; 442 }, 443 444 /* Replaceable Form encoder */ 445 446 encoder : encodeURIComponent, 447 448 serializeForm : function(){ 449 var reSelect = /select-(one|multiple)/i, 450 reInput = /file|undefined|reset|button/i, 451 reChecks = /radio|checkbox/i; 452 453 return function(form) { 454 var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements, 455 hasSubmit = false, 456 encoder = this.encoder, 457 element, 458 options, 459 name, 460 val, 461 data = '', 462 type; 463 forEach(fElements, function(element) { 464 name = element.name; 465 type = element.type; 466 if (!element.disabled && name){ 467 if(reSelect.test(type)){ 468 forEach(element.options, function(opt) { 469 if (opt.selected) { 470 data += String.format("{0}={1}&", 471 encoder(name), 472 encoder( 473 opt.hasAttribute && opt.hasAttribute('value') && 474 opt.getAttribute('value') !== null ? opt.value : opt.text 475 ) 476 ); 477 } 478 }); 479 } else if(!reInput.test(type)) { 480 if(!(reChecks.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)){ 481 data += encoder(name) + '=' + encoder(element.value) + '&'; 482 hasSubmit = /submit/i.test(type); 483 } 484 } 485 } 486 }); 487 return data.substr(0, data.length - 1); 488 }; 489 }(), 490 491 /** private */ 492 getHttpStatus : function(reqObj, isAbort, isTimeout) { 493 494 var statObj = { 495 status : 0, 496 statusText : '', 497 isError : false, 498 isLocal : false, 499 isOK : true, 500 error : null, 501 isAbort : !!isAbort, 502 isTimeout : !!isTimeout 503 }; 504 505 try { 506 if (!reqObj || !('status' in reqObj)) { throw ('noobj'); } 507 statObj.status = reqObj.status; 508 statObj.readyState = reqObj.readyState; 509 statObj.isLocal = (!reqObj.status && location.protocol == "file:") 510 || (Ext.isSafari && !defined(reqObj.status)); 511 512 statObj.isOK = (statObj.isLocal || (statObj.status == 304 513 || statObj.status == 1223 || (statObj.status > 199 && statObj.status < 300))); 514 515 statObj.statusText = reqObj.statusText || ''; 448 obj.conn = new ActiveXObject(actX[i]); 449 break; 516 450 } catch (e) { 517 } // status may not avail/valid yet, called too early, or status not support by the transport 518 519 return statObj; 520 521 }, 522 /** 523 * @private 524 */ 525 handleTransactionResponse : function(o, callback, isAbort, isTimeout) { 526 527 callback = callback || {}; 528 var responseObject = null; 529 o.isPart || A.activeRequests--; 530 531 if (!o.status.isError) { 532 o.status = this.getHttpStatus(o.conn, isAbort, isTimeout); 533 /* 534 * create and enhance the response with proper status and XMLDOM 535 * if necessary 536 */ 537 responseObject = this.createResponseObject(o, callback.argument, isAbort, isTimeout); 538 } 539 o.isPart || this.releaseObject(o); 540 541 /* 542 * checked again in case exception was raised - ActiveX was 543 * disabled during XML-DOM creation? And mixin everything the 544 * XHR object had to offer as well 545 */ 546 o.status.isError && (responseObject = Ext.apply({}, responseObject || {}, 547 this.createExceptionObject(o.tId, callback.argument, !!isAbort, !!isTimeout, o.status.error))); 548 549 responseObject.options = o.options; 550 responseObject.fullStatus = o.status; 551 552 if (!this.events 553 || this.fireEvent('status:' + o.status.status, 554 o.status.status, o, responseObject, callback, 555 isAbort) !== false) { 556 557 if (o.status.isOK && !o.status.isError) { 558 if (!this.events 559 || this.fireEvent('response', o, responseObject, 560 callback, isAbort, isTimeout) !== false) { 561 562 var cb = o.isPart? 'onpart':'success'; 563 564 Ext.isFunction(callback[cb]) && 565 callback[cb].call(callback.scope || null,responseObject); 566 567 } 568 } else { 569 if (!this.events 570 || this.fireEvent('exception', o, responseObject, 571 callback, isAbort, isTimeout, responseObject.fullStatus.error) !== false) { 572 Ext.isFunction(callback.failure) && 573 callback.failure.call(callback.scope || null, responseObject, responseObject.fullStatus.error); 574 575 } 576 } 577 } 578 579 return responseObject; 580 581 }, 582 /** 583 * @private 584 * Release the allocated XHR object and reset any timers 585 */ 586 releaseObject:function(o){ 587 588 o && (o.conn = null); 589 if(o && Ext.value(o.tId,-1)+1){ 590 if(this.poll[o.tId]){ 591 window.clearInterval(this.poll[o.tId]); 592 delete this.poll[o.tId]; 593 } 594 if(this.timeout[o.tId]){ 595 window.clearInterval(this.timeout[o.tId]); 596 delete this.timeout[o.tId]; 597 } 598 } 599 }, 600 601 /** 602 * replace with a custom JSON decoder/validator if required 603 */ 604 decodeJSON : Ext.decode, 605 606 /** 607 * @cfg reCtypeJSON 608 * regexp test pattern applied to incoming response Content-Type header 609 * to identify a potential JSON response. The default pattern handles 610 * either text/json or application/json 611 */ 612 reCtypeJSON : /(application|text)\/json/i, 613 614 /** 615 * @cfg reCtypeXML 616 * regexp test pattern applied to incoming response Content-Type header 617 * to identify a potential JSON response. The default pattern handles 618 * either text/json or application/json 619 */ 620 reCtypeXML : /(application|text)\/xml/i, 621 622 /** private */ 623 createResponseObject : function(o, callbackArg, isAbort, isTimeout) { 624 var CTYPE = 'content-type', 625 obj = { 626 responseXML : null, 627 responseText : '', 628 responseStream : null, 629 responseJSON : null, 630 contentType : null, 631 getResponseHeader : emptyFn, 632 getAllResponseHeaders : emptyFn 633 }; 634 635 var headerObj = {}, headerStr = ''; 636 637 if (isAbort !== true) { 638 try { // to catch bad encoding problems here 639 obj.responseJSON = o.conn.responseJSON || null; 640 obj.responseStream = o.conn.responseStream || null; 641 obj.contentType = o.conn.contentType || null; 642 obj.responseText = o.conn.responseText; 643 } catch (e) { 644 o.status.isError = true; 645 o.status.error = e; 646 } 647 648 try { 649 obj.responseXML = o.conn.responseXML || null; 650 } catch (ex) { 651 } 652 653 try { 654 headerStr = ('getAllResponseHeaders' in o.conn ? o.conn.getAllResponseHeaders() : null ) || ''; 655 var s; 656 headerStr.split('\n').forEach( function(sHeader){ 657 (s = sHeader.split(':')) && s.first() && 658 (headerObj[s.first().trim().toLowerCase()] = (s.last()||'').trim()); 659 }); 660 661 } catch (ex1) { 662 o.status.isError = true; // trigger future exception callback 663 o.status.error = ex1; 664 } 665 finally{ obj.contentType = obj.contentType || headerObj[CTYPE] || ''; } 666 667 if ((o.status.isLocal || o.proxied) 668 && typeof obj.responseText == 'string') { 669 670 o.status.isOK = !o.status.isError 671 && ((o.status.status = (!!obj.responseText.length) 672 ? 200 : 404) == 200); 673 674 if (o.status.isOK 675 && 676 ( (!obj.responseXML && this.reCtypeXML.test(obj.contentType )) 677 || (obj.responseXML && obj.responseXML.childNodes.length === 0) ) 678 ) { 679 680 var xdoc = null; 681 try { // ActiveX may be disabled 682 if (Ext.capabilities.hasActiveX) { 683 xdoc = new ActiveXObject("MSXML2.DOMDocument.3.0"); 684 xdoc.async = false; 685 xdoc.loadXML(obj.responseText); 686 } else { 687 var domParser = null; 688 try { // Opera 9 will fail parsing non-XML content, so trap here. 689 domParser = new DOMParser(); 690 xdoc = domParser.parseFromString(obj.responseText,'application\/xml'); 691 } catch (exP) { 692 } finally { 693 domParser = null; 694 } 695 } 696 } catch (exd) { 697 o.status.isError = true; 698 o.status.error = exd; 699 } 700 obj.responseXML = xdoc; 701 } 702 if (obj.responseXML) { 703 var parseBad = (obj.responseXML.documentElement && obj.responseXML.documentElement.nodeName == 'parsererror') 704 || (obj.responseXML.parseError || 0) !== 0 705 || obj.responseXML.childNodes.length === 0; 706 parseBad || 707 (obj.contentType = headerObj[CTYPE] = obj.responseXML.contentType || 'text\/xml'); 708 } 709 } 710 711 if (o.options.isJSON || (this.reCtypeJSON && this.reCtypeJSON.test(headerObj[CTYPE] || ""))) { 712 try { 713 Ext.isObject(obj.responseJSON) || 714 (obj.responseJSON = Ext.isFunction( this.decodeJSON ) && 715 Ext.isString(obj.responseText) 716 ? this.decodeJSON(obj.responseText) 717 : null); 718 } catch (exJSON) { 719 o.status.isError = true; // trigger future exception callback 720 o.status.error = exJSON; 721 } 722 } 723 724 } // isAbort? 725 o.status.proxied = !!o.proxied; 726 727 Ext.apply(obj, { 728 tId : o.tId, 729 status : o.status.status, 730 statusText : o.status.statusText, 731 contentType : obj.contentType || headerObj[CTYPE], 732 getResponseHeader : function(header){return headerObj[(header||'').trim().toLowerCase()];}, 733 getAllResponseHeaders : function(){return headerStr;}, 734 fullStatus : o.status, 735 isPart : o.isPart || false 736 }); 737 738 o.parts && !o.isPart && (obj.parts = o.parts); 739 defined(callbackArg) && (obj.argument = callbackArg); 740 return obj; 741 }, 742 743 744 setDefaultPostHeader : function(contentType) { 745 this.defaultPostHeader = contentType||''; 746 }, 747 748 /** 749 * Toggle use of the DefaultXhrHeader ('Ext.basex') 750 */ 751 setDefaultXhrHeader : function(bool) { 752 this.useDefaultXhrHeader = bool || false; 753 }, 754 755 request : function(method, uri, cb, data, options) { 756 757 var O = options = Ext.apply({ 758 async : this.async || false, 759 headers : false, 760 userId : null, 761 password : null, 762 xmlData : null, 763 jsonData : null, 764 queue : null, 765 proxied : false, 766 multiPart : false, 767 xdomain : false 768 }, options || {}); 769 770 //Seek out nested config options 771 var _to; 772 if( cb.argument && 773 cb.argument.options && 774 cb.argument.options.request && 775 (_to = cb.argument.options.request.arg) ){ 776 777 Ext.apply(O,{ 778 async : O.async || _to.async, 779 proxied : O.proxied || _to.proxied, 780 multiPart : O.multiPart || _to.multiPart, 781 xdomain : O.xdomain ||_to.xdomain, 782 queue : O.queue ||_to.queue, 783 onPart : O.onPart ||_to.onPart 784 }); 785 } 786 787 if (!this.events 788 || this.fireEvent('request', method, uri, cb, data, O) !== false) { 789 790 // Named priority queues 791 if (!O.queued && (O.queue || (O.queue = this.queueAll || null)) ) { 792 793 O.queue === true && (O.queue = {name:'q-default'}); 794 var oq = O.queue; 795 var qname = oq.name || oq , qm = this.queueManager; 796 797 var q = qm.getQueue(qname) || qm.createQueue(oq); 798 O.queue = q; 799 O.queued = true; 800 801 var req = [method, uri, cb, data, O]; 802 req.active = true; 803 q.add(req); 804 805 return { 806 tId : this.transactionId++, 807 queued : true, 808 request : req, 809 options : O 810 }; 811 } 812 813 options.onpart && (cb.onpart || 814 (cb.onpart = Ext.isFunction(options.onpart) ? 815 options.onpart.createDelegate(options.scope): null)); 816 817 O.headers && forEach(O.headers, 818 function(value, key) { this.initHeader(key, value, false); },this); 819 820 var cType; 821 // The Content-Type specified on options.headers always has priority over 822 // a calculated value. 823 if (cType = (this.headers ? this.headers['Content-Type'] || null : null)) { 824 // remove to ensure only ONE is passed later.(per RFC) 825 delete this.headers['Content-Type']; 826 } 827 if (O.xmlData) { 828 cType || (cType = 'text/xml'); 829 method = 'POST'; 830 data = O.xmlData; 831 } else if (O.jsonData) { 832 cType || (cType = 'application/json; charset=utf-8'); 833 method = 'POST'; 834 data = (Ext.isArray(O.jsonData) || Ext.isObject(O.jsonData)) ? 835 Ext.encode(O.jsonData) : 836 O.jsonData; 837 } 838 if (data) { 839 cType || (cType = this.useDefaultHeader 840 ? this.defaultPostHeader 841 : null); 842 cType && this.initHeader('Content-Type', cType, false); 843 } 844 845 // options.method prevails over any derived method. 846 return this.makeRequest(O.method || method, uri, cb, data, O); 847 } 848 return null; 849 850 }, 851 852 853 /** private */ 854 getConnectionObject : function(uri, options, data) { 855 var o, f; 856 var tId = this.transactionId; 857 options || (options = {}); 858 try { 859 if (f = options.proxied) { /* JSONP scriptTag Support */ 860 861 o = { 862 tId : tId, 863 status : {isError : false}, 864 proxied : true, 865 // synthesize an XHR object 866 conn : { 867 el : null, 868 send : function(data) { 869 var doc = (f.target || window).document, 870 head = doc.getElementsByTagName("head")[0]; 871 if (head && this.el) { 872 head.appendChild(this.el.dom); 873 this.readyState = 2; 874 } 875 }, 876 abort : function() { 877 this.readyState = 0; 878 window[o.cbName] = undefined; 879 //IE dislikes this 880 Ext.isIE || delete window[o.cbName]; 881 882 var d = Ext.getDom(this.el); 883 884 if(this.el){ 885 this.el.removeAllListeners(); 886 if(!o.debug){ 887 if(Ext.isIE){ 888 //Script Tags are re-usable in IE 889 A.SCRIPTTAG_POOL.push(this.el); 890 }else{ 891 this.el.remove(); 892 //Other Browsers will not GBG-collect these tags, so help them along 893 if(d ){ 894 for(var prop in d) {delete d[prop];} 895 } 896 } 897 } 898 } 899 this.el = d = null; 900 }, 901 _headers : {}, 902 getAllResponseHeaders : function(){ 903 var out=[]; 904 forEach(this._headers,function(value, name){ 905 value && out.push(name + ': '+value); 906 }); 907 return out.join('\n'); 908 909 }, 910 getResponseHeader : function(header){ 911 return this._headers[String(header).toLowerCase()] || ''; 912 }, 913 onreadystatechange : null, 914 onload : null, 915 readyState : 0, 916 status : 0, 917 responseText : null, 918 responseXML : null, 919 responseJSON : null 920 }, 921 debug : f.debug, 922 params : Ext.isString(options.params) ? Ext.urlDecode(options.params) : options.params || {}, 923 cbName : f.callbackName || 'basexCallback' + tId, 924 cbParam : f.callbackParam || null 925 }; 926 927 window[o.cbName] = o.cb = function(content) { 928 929 content && typeof(content)=='object' && (this.responseJSON = content); 930 this.responseText = content || null; 931 this.status = !!content ? 200 : 404; 932 this.abort(); 933 this.readyState = 4; 934 Ext.isFunction(this.onreadystatechange) && this.onreadystatechange(); 935 Ext.isFunction(this.onload) && this.onload(); 936 937 }.createDelegate(o.conn); 938 939 o.conn.open = function() { 940 941 if (o.cbParam) { 942 o.params[o.cbParam] = o.cbName; 943 } 944 945 //apply any new params to any already supplied by the uri and postData 946 var params = Ext.urlEncode( 947 Ext.apply( 948 Ext.urlDecode(data) || {}, //decode any postData 949 o.params, 950 uri.indexOf("?") > -1 ? Ext.urlDecode(uri.split('?').last()): false 951 )) ; 952 953 o.uri = params ? uri.split('?').first() + '?' + params : uri; 954 955 this.el = A.monitoredNode( 956 f.tag || 'script', 957 { 958 type : f.contentType || "text/javascript", 959 src : o.uri, 960 charset : f.charset || options.charset || null 961 }, 962 null, 963 f.target, 964 true); //defer head insertion until send method 965 966 this._headers['content-type'] = this.el.dom.type; 967 this.readyState = 1; // show CallInProgress 968 Ext.isFunction(this.onreadystatechange) && this.onreadystatechange(); 969 970 }; 971 options.async = true; // force timeout support 972 973 } else { 974 o = this.createXhrObject(tId, options); 975 } 976 if (o) { 977 this.transactionId++; 978 } 979 } catch (ex3) { 980 o && (o.status.isError = !!(o.status.error = ex3)); 981 } finally { 982 return o; 983 } 984 }, 985 986 /** private */ 987 makeRequest : function(method, uri, callback, postData, options) { 988 989 var o; 990 if (o = this.getConnectionObject(uri, options, postData)) { 991 o.options = options; 992 var r = o.conn; 993 994 try { 995 if(o.status.isError){ throw o.status.error }; 996 997 A.activeRequests++; 998 r.open(method.toUpperCase(), uri, options.async, options.userId, options.password); 999 1000 ('onreadystatechange' in r) && 1001 (r.onreadystatechange = this.onStateChange.createDelegate(this, [o, callback, 'readystate'], 0)); 1002 1003 ('onload' in r) && 1004 (r.onload = this.onStateChange.createDelegate(this, [o, callback, 'load', 4], 0)); 1005 1006 ('onprogress' in r) && 1007 (r.onprogress = this.onStateChange.createDelegate(this, [o, callback, 'progress'], 0)); 1008 1009 //IE8/other? evolving timeout callback support 1010 if(callback && callback.timeout){ 1011 ('timeout' in r) && (r.timeout = callback.timeout); 1012 ('ontimeout' in r) && 1013 (r.ontimeout = this.abort.createDelegate(this, [o, callback, true], 0)); 1014 ('ontimeout' in r) || 1015 // Timers for syncro calls won't work here, as it's a blocking call 1016 (options.async && (this.timeout[o.tId] = window.setInterval( 1017 function() {A.abort(o, callback, true); 1018 }, callback.timeout))); 1019 } 1020 1021 if (this.useDefaultXhrHeader && !options.xdomain) { 1022 this.defaultHeaders['X-Requested-With'] || 1023 this.initHeader('X-Requested-With', this.defaultXhrHeader, true); 1024 } 1025 this.setHeaders(o); 1026 1027 if (!this.events 1028 || this.fireEvent('beforesend', o, method, uri, 1029 callback, postData, options) !== false) { 1030 r.send(postData || null); 1031 } 1032 } catch (exr) { 1033 o.status.isError = true; 1034 o.status.error = exr; 1035 } 1036 if(o.status.isError ) { 1037 return Ext.apply(o, this.handleTransactionResponse(o, callback)); 1038 } 1039 options.async || this.onStateChange(o, callback, 'load'); 1040 return o; 1041 } 1042 }, 1043 1044 1045 abort : function(o, callback, isTimeout) { 1046 1047 o && Ext.apply(o.status,{ 1048 isAbort : !!!isTimeout, 1049 isTimeout : !!isTimeout, 1050 isError : !!isTimeout || !!o.status.isError 1051 }); 1052 if (o && o.queued && o.request) { 1053 o.request.active = o.queued = false; 1054 this.events && this.fireEvent('abort', o, callback); 1055 return true; 1056 } else if (o && this.isCallInProgress(o)) { 1057 1058 if (!this.events || this.fireEvent(isTimeout ? 'timeout' : 'abort', o, callback)!== false){ 1059 ('abort' in o.conn) && o.conn.abort(); 1060 this.handleTransactionResponse(o, callback, o.status.isAbort, o.status.isTimeout); 1061 } 1062 return true; 1063 } 1064 return false; 1065 }, 1066 1067 isCallInProgress : function(o) { 1068 // if there is a connection and readyState is supported, and not 0 or 4 1069 if( o && o.conn ){ 1070 if('readyState' in o.conn && {0:true,4:true}[o.conn.readyState]){ 1071 return false; 1072 } 1073 return true; 1074 } 1075 return false; 1076 }, 1077 1078 /** 1079 * Clears the Browser authentication Cache 1080 * @param {String} url {optional) reset url for non-IE browsers 1081 * @return void 1082 */ 1083 clearAuthenticationCache : function(url) { 1084 1085 try { 1086 1087 if (Ext.isIE) { 1088 // IE clear HTTP Authentication, (but ALL realms though) 1089 document.execCommand("ClearAuthenticationCache"); 1090 } else { 1091 // create an xmlhttp object 1092 var xmlhttp; 1093 if (xmlhttp = new XMLHttpRequest()) { 1094 // prepare invalid credentials 1095 xmlhttp.open("GET", url || '/@@', true, "logout", "logout"); 1096 // send the request to the server 1097 xmlhttp.send(""); 1098 // abort the request 1099 xmlhttp.abort.defer(100, xmlhttp); 1100 } 1101 } 1102 } catch (e) {} // There was an error 1103 1104 }, 1105 1106 // private 1107 initHeader : function(label, value) { 1108 (this.headers = this.headers || {})[label] = value; 1109 }, 1110 1111 /** @private 1112 * General readyStateChange multiPart handler 1113 */ 1114 onStateChange : function(o, callback, mode) { 1115 1116 if(!o.conn || o.status.isTimeout || o.status.isError){ return; } 1117 1118 var C = o.conn, readyState = ('readyState' in C ? C.readyState : 0); 1119 if(mode === 'load' || readyState > 2){ 1120 var ct; 1121 try{ct = C.contentType || C.getResponseHeader('Content-Type') || '';} 1122 catch(exRs){ } 1123 1124 if(ct && /multipart\//i.test(ct)){ 1125 var r = null, boundary = ct.split('"')[1], kb = '--' + boundary; 1126 o.multiPart = true; 1127 try{r = C.responseText;}catch(ers){} 1128 1129 var p = r ? r.split(kb) : null; 1130 1131 if(p){ 1132 o.parts || (o.parts = []); 1133 p.shift(); 1134 p.pop(); 1135 1136 forEach( 1137 Array.slice(p, o.parts.length), //skip parts already parsed 1138 function(newPart){ 1139 var content = newPart.split('\n\n'); 1140 var H = (content[0] ? content[0] : '') + '\n'; 1141 o.parts.push(this.handleTransactionResponse( 1142 Ext.apply( 1143 Ext.clone(o),{ 1144 boundary : boundary, 1145 conn : { //synthetic conn structure for each part 1146 status : 200, 1147 responseText : (content[1]||'').trim(), 1148 getAllResponseHeaders : function(){ 1149 return H.split('\n').filter( 1150 function(value){return !!value;}).join('\n'); 1151 } 1152 }, 1153 isPart : true 1154 }), callback)); 1155 },this); 1156 } 1157 1158 } 1159 } 1160 (readyState === 4 || mode === 'load') && A.handleTransactionResponse(o, callback); 1161 this.events && this.fireEvent.apply(this, ['readystatechange'].concat(Array.slice(arguments, 0))); 1162 }, 1163 1164 setHeaders:function(o){ 1165 1166 //Some XDomain implementations (IE8) do not support setting headers 1167 if(o.conn && 'setRequestHeader' in o.conn){ 1168 this.defaultHeaders && 1169 forEach(this.defaultHeaders, function(value, key){ o.conn.setRequestHeader(key, value);}); 1170 1171 this.headers && 1172 forEach(this.headers, function(value, key){o.conn.setRequestHeader(key, value);}); 1173 } 1174 this.headers = {}; 1175 this.hasHeaders = false; 1176 1177 }, 1178 1179 resetDefaultHeaders:function() { 1180 delete this.defaultHeaders; 1181 this.defaultHeaders = {}; 1182 this.hasDefaultHeaders = false; 1183 }, 1184 1185 //These are only current versions of ActiveX XHR that support multipart responses 1186 activeXMultipart : [ 1187 'MSXML2.XMLHTTP.6.0', 1188 'MSXML3.XMLHTTP' 1189 ], 1190 1191 activeX:[ 1192 'MSXML2.XMLHTTP.3.0', 1193 'MSXML2.XMLHTTP', 1194 'Microsoft.XMLHTTP' 1195 ] 1196 1197 }); 1198 1199 if (Ext.util.Observable) { 1200 1201 Ext.apply(A, { 1202 1203 events : { 1204 request : true, 1205 beforesend : true, 1206 response : true, 1207 exception : true, 1208 abort : true, 1209 timeout : true, 1210 readystatechange : true, 1211 beforequeue : true, 1212 queue : true, 1213 queueempty : true 1214 }, 1215 1216 /** 1217 * onStatus define eventListeners for a single (or array) of 1218 * HTTP status codes. 1219 */ 1220 1221 onStatus : function(status, fn, scope, options) { 1222 var args = Array.slice(arguments, 1); 1223 status = new Array().concat(status || new Array()); 1224 forEach(status, function(statusCode) { 1225 statusCode = parseInt(statusCode, 10); 1226 if (!isNaN(statusCode)) { 1227 var ev = 'status:' + statusCode; 1228 this.events[ev] || (this.events[ev] = true); 1229 this.on.apply(this, [ev].concat(args)); 1230 } 1231 }, this); 1232 }, 1233 1234 /** 1235 * unStatus unSet eventListeners for a single (or array) of 1236 * HTTP status codes. 1237 */ 1238 1239 unStatus : function(status, fn, scope, options) { 1240 var args = Array.slice(arguments, 1); 1241 status = new Array().concat(status || new Array()); 1242 forEach(status, function(statusCode) { 1243 statusCode = parseInt(statusCode, 10); 1244 if (!isNaN(statusCode)) { 1245 var ev = 'status:' + statusCode; 1246 this.un.apply(this, [ev].concat(args)); 1247 } 1248 }, this); 1249 } 1250 1251 }, new Ext.util.Observable()); 1252 1253 Ext.hasBasex = true; 1254 } 1255 1256 // Array, object iteration and clone support 1257 Ext.stopIteration = { stopIter : true }; 1258 1259 Ext.applyIf(Array.prototype, { 1260 1261 /* 1262 * Fix for IE, Opera < 9.5, which does not seem to include the map 1263 * function on Array's 1264 */ 1265 map : function(fun, scope) { 1266 var len = this.length; 1267 if (typeof fun != "function") { 1268 throw new TypeError(); 1269 } 1270 var res = new Array(len); 1271 1272 for (var i = 0; i < len; ++i) { 1273 i in this && 1274 (res[i] = fun.call(scope || this, this[i], i, this)); 1275 } 1276 return res; 1277 }, 1278 1279 /** 1280 * Return true of the passed Function test true of ANY array elememt. 1281 * (added for IE) 1282 */ 1283 some : function(fn){ 1284 var f= Ext.isFunction(fn) ? fn : function(){}; 1285 var i=0, l=this.length, test=false; 1286 while(i<l && !(test=!!f(this[i++]))){} 1287 return test; 1288 }, 1289 1290 /** 1291 * Return true of the passed Function test true of ALL array elememts. 1292 * (added for IE) 1293 */ 1294 every : function(fn){ 1295 var f= Ext.isFunction(fn) ? fn : function(){}; 1296 var i=0, l=this.length, test=true; 1297 while(i<l && (test=!!f(this[i++]))){} 1298 return test; 1299 }, 1300 1301 include : function(value, deep) { // Boolean: is value present 1302 // in Array 1303 // use native indexOf if available 1304 if (!deep && typeof this.indexOf == 'function') { 1305 return this.indexOf(value) != -1; 1306 } 1307 var found = false; 1308 try { 1309 this.forEach(function(item, index) { 1310 if (found = (deep 1311 ? (item.include 1312 ? item.include(value, deep) 1313 : (item === value)) 1314 : item === value)) { 1315 throw Ext.stopIteration; 1316 } 1317 }); 1318 } catch (exc) { 1319 if (exc != Ext.stopIteration) { 1320 throw exc; 1321 } 1322 } 1323 return found; 1324 }, 1325 // Using iterFn, traverse the array, push the current element 1326 // value onto the 1327 // result if the iterFn returns true 1328 filter : function(iterFn, scope) { 1329 var a = new Array(); 1330 iterFn || (iterFn = function(value) { 1331 return value; 1332 }); 1333 this.forEach(function(value, index) { 1334 iterFn.call(scope, value, index) && a.push(value); 1335 }); 1336 return a; 1337 }, 1338 1339 compact : function(deep) { // Remove null, undefined array 1340 // elements 1341 var a = new Array(); 1342 this.forEach(function(v) { 1343 (v === null || v === undefined) || a.push(deep && Ext.isArray(v) ? v.compact() : v); 1344 }, this); 1345 return a; 1346 }, 1347 1348 flatten : function() { // flatten: [1,2,3,[4,5,6]] -> 1349 // [1,2,3,4,5,6] 1350 var a = new Array(); 1351 this.forEach(function(v) { 1352 Ext.isArray(v) ? (a = a.concat(v)) : a.push(v); 1353 }, this); 1354 return a; 1355 }, 1356 1357 indexOf : function(o){ 1358 for (var i = 0, len = this.length; i < len; ++i){ 1359 if(this[i] == o) return i; 1360 } 1361 return -1; 1362 }, 1363 1364 1365 lastIndexOf : function(val){ 1366 var i= this.length-1; 1367 while(i>-1 && this[i] != val){i--;} 1368 return i; 1369 }, 1370 1371 unique : function(sorted /* sort optimization */, exact) { // unique: 1372 // [1,3,3,4,4,5] 1373 // -> 1374 // [1,3,4,5] 1375 var a = new Array(); 1376 this.forEach(function(value, index) { 1377 if (0 == index 1378 || (sorted ? a.last() != value : !a.include(value, exact))) { 1379 a.push(value); 1380 } 1381 }, this); 1382 return a; 1383 }, 1384 // search array values based on regExpression pattern returning 1385 // test (and optionally execute function(value,index) on test 1386 // before returned) 1387 grep : function(rePattern, iterFn, scope) { 1388 var a = new Array(); 1389 iterFn || (iterFn = function(value) { 1390 return value; 1391 }); 1392 var fn = scope ? iterFn.createDelegate(scope) : iterFn; 1393 1394 if (typeof rePattern == 'string') { 1395 rePattern = new RegExp(rePattern); 1396 } 1397 rePattern instanceof RegExp && 1398 this.forEach(function(value, index) { 1399 rePattern.test(value) && a.push(fn(value, index)); 1400 }); 1401 return a; 1402 }, 1403 1404 first : function() { 1405 return this[0]; 1406 }, 1407 1408 last : function() { 1409 return this[this.length - 1]; 1410 }, 1411 1412 clear : function() { 1413 this.length = 0; 1414 }, 1415 1416 // return an array element selected at random 1417 atRandom : function(defValue) { 1418 var r = Math.floor(Math.random() * this.length); 1419 return this[r] || defValue; 1420 }, 1421 1422 clone : function(deep) { 1423 if (!deep) {return this.concat();} 1424 1425 var length = this.length || 0, t = new Array(length); 1426 while (length--) { 1427 t[length] = Ext.clone(this[length], true); 1428 } 1429 return t; 1430 1431 }, 1432 1433 /* 1434 * Array forEach Iteration based on previous work by: Dean Edwards 1435 * (http://dean.edwards.name/weblog/2006/07/enum/) Gecko already 1436 * supports forEach for Arrays : see 1437 * http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/forEach 1438 */ 1439 forEach : function( block, scope) { 1440 Array.forEach(this, block, scope); 1441 }, 1442 1443 reversed : function(){ 1444 var length = this.length || 0, t = []; 1445 while (length--) { 1446 t.push(this[length]); 1447 } 1448 return t; 1449 } 1450 1451 }); 1452 1453 1454 // globally resolve forEach enumeration 1455 window.forEach = function(object, block, context, deep) { 1456 context = context || object; 1457 if (object) { 1458 if (typeof block != "function") { 1459 throw new TypeError(); 1460 } 1461 var resolve = Object; 1462 if (object instanceof Function) { 1463 // functions have a "length" property 1464 resolve = Function; 1465 1466 } else if (object.forEach instanceof Function) { 1467 // the object implements a custom forEach method so use that 1468 return object.forEach(block, context); 1469 1470 } else if (typeof object == "string") { 1471 // the object is a string 1472 resolve = String; 1473 1474 } else if (Ext.isNumber(object.length)) { 1475 // the object is array-like 1476 resolve = Array; 1477 } 1478 return resolve.forEach(object, block, context, deep); 1479 } 1480 }; 1481 1482 /** 1483 * 1484 * Primary clone Function 1485 */ 1486 Ext.clone = function(obj, deep) { 1487 if (obj === null || obj === undefined) {return obj;} 1488 1489 if (Ext.isFunction(obj.clone)) { 1490 return obj.clone(deep); 1491 } 1492 else if(Ext.isFunction(obj.cloneNode)){ 1493 return obj.cloneNode(deep); 1494 } 1495 var o={}; 1496 forEach(obj, function(value, name, objAll){ 1497 o[name] = (value === objAll ? // reference to itself? 1498 o : deep ? Ext.clone(value, true) : value); 1499 }, obj, deep); 1500 return o; 1501 }; 1502 1503 var slice = Array.prototype.slice; 1504 var filter = Array.prototype.filter; 1505 Ext.applyIf(Array,{ 1506 // Permits: Array.slice(arguments, 1); // mozilla already supports this 1507 slice: function(obj) { 1508 return slice.apply(obj, slice.call(arguments, 1)); 1509 }, 1510 //String filter iteration 1511 filter: function(obj, fn){ 1512 var t = obj && typeof obj == 'string' ? obj.split('') : []; 1513 return filter.call(t, fn); 1514 }, 1515 /* 1516 * Array forEach Iteration based on previous work by: Dean Edwards 1517 * (http://dean.edwards.name/weblog/2006/07/enum/) Gecko already 1518 * supports forEach for Arrays : see 1519 * https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/forEach 1520 */ 1521 forEach : function( collection, block, scope) { 1522 1523 if (typeof block != "function") { 1524 throw new TypeError(); 1525 } 1526 for (var i = 0, l = collection.length >>> 0; i < l; ++i) { 1527 (i in collection) && block.call(scope || null, collection[i], i, collection); 451 ecode = (eo == "IE7forceActiveX" ? e : eo); 1528 452 } 1529 453 } 1530 }); 1531 1532 //Add clone function to primitive prototypes 1533 1534 Ext.applyIf(RegExp.prototype,{ 1535 clone : function() { 1536 return new RegExp(this); 1537 } 1538 }); 1539 1540 Ext.applyIf(Date.prototype, { 1541 clone : function(deep){ 1542 return deep? new Date(this.getTime()) : this ; 1543 } 1544 }); 1545 1546 Ext.applyIf(Boolean.prototype, { 1547 clone : function(){ 1548 return this === true; 1549 } 1550 }); 1551 1552 Ext.applyIf(Number.prototype, { 1553 times : function(block, context){ 1554 var total = parseInt(this,10) || 0; 1555 for (var i=1; i <= total; ){ 1556 block.call(context, i++); 454 } 455 } finally { 456 obj.status.isError = !defined(obj.conn); 457 obj.status.error = ecode; 458 } 459 return obj; 460 461 }, 462 463 createExceptionObject : function(tId, callbackArg, isAbort, isTimeout, errObj) { 464 return { 465 tId : tId, 466 status : isAbort ? -1 : 0, 467 statusText : isAbort ? 'transaction aborted' : 'communication failure', 468 isAbort : isAbort, 469 isTimeout : isTimeout, 470 argument : callbackArg 471 }; 472 }, 473 474 /* Replaceable Form encoder */ 475 476 encoder : encodeURIComponent, 477 478 serializeForm : function() { 479 var reSelect = /select-(one|multiple)/i, reInput = /file|undefined|reset|button/i, reChecks = /radio|checkbox/i; 480 481 return function(form) { 482 var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements, hasSubmit = false, encoder = this.encoder, element, options, name, val, data = '', type; 483 forEach(fElements, function(element) { 484 name = element.name; 485 type = element.type; 486 if (!element.disabled && name) { 487 if (reSelect.test(type)) { 488 forEach(element.options, function(opt) { 489 if (opt.selected) { 490 data += String.format("{0}={1}&", encoder(name), encoder(opt.hasAttribute && opt.hasAttribute('value') && opt.getAttribute('value') !== null ? opt.value : opt.text 491 )); 492 } 493 }); 494 } else if (!reInput.test(type)) { 495 if (!(reChecks.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) { 496 data += encoder(name) + '=' + encoder(element.value) + '&'; 497 hasSubmit = /submit/i.test(type); 498 } 1557 499 } 500 } 501 }); 502 return data.substr(0, data.length - 1); 503 }; 504 }(), 505 506 /** private */ 507 getHttpStatus : function(reqObj, isAbort, isTimeout) { 508 509 var statObj = { 510 status : 0, 511 statusText : '', 512 isError : false, 513 isLocal : false, 514 isOK : true, 515 error : null, 516 isAbort : !!isAbort, 517 isTimeout : !!isTimeout 518 }; 519 520 try { 521 if (!reqObj || !('status' in reqObj)) { 522 throw ('noobj'); 523 } 524 statObj.status = reqObj.status; 525 statObj.readyState = reqObj.readyState; 526 statObj.isLocal = (!reqObj.status && location.protocol == "file:") || (Ext.isSafari && !defined(reqObj.status)); 527 528 statObj.isOK = (statObj.isLocal || (statObj.status == 304 || statObj.status == 1223 || (statObj.status > 199 && statObj.status < 300))); 529 530 statObj.statusText = reqObj.statusText || ''; 531 } catch (e) {} // status may not avail/valid yet, called too early, or 532 // status not support by the transport 533 534 return statObj; 535 536 }, 537 /** 538 * @private 539 */ 540 handleTransactionResponse : function(o, callback, isAbort, isTimeout) { 541 542 callback = callback || {}; 543 var responseObject = null; 544 o.isPart || A.activeRequests--; 545 546 if (!o.status.isError) { 547 o.status = this.getHttpStatus(o.conn, isAbort, isTimeout); 548 /* 549 * create and enhance the response with proper status and XMLDOM if 550 * necessary 551 */ 552 responseObject = this.createResponseObject(o, callback.argument, isAbort, isTimeout); 553 } 554 o.isPart || this.releaseObject(o); 555 556 /* 557 * checked again in case exception was raised - ActiveX was disabled 558 * during XML-DOM creation? And mixin everything the XHR object had to 559 * offer as well 560 */ 561 o.status.isError && (responseObject = Ext.apply({}, responseObject || {}, this.createExceptionObject(o.tId, callback.argument, !!isAbort, !!isTimeout, o.status.error))); 562 563 responseObject.options = o.options; 564 responseObject.fullStatus = o.status; 565 566 if (!this.events || this.fireEvent('status:' + o.status.status, o.status.status, o, responseObject, callback, isAbort) !== false) { 567 568 if (o.status.isOK && !o.status.isError) { 569 if (!this.events || this.fireEvent('response', o, responseObject, callback, isAbort, isTimeout) !== false) { 570 571 var cb = o.isPart ? 'onpart' : 'success'; 572 573 Ext.isFunction(callback[cb]) && callback[cb].call(callback.scope || null, responseObject); 574 575 } 576 } else { 577 if (!this.events || this.fireEvent('exception', o, responseObject, callback, isAbort, isTimeout, responseObject.fullStatus.error) !== false) { 578 Ext.isFunction(callback.failure) && callback.failure.call(callback.scope || null, responseObject, responseObject.fullStatus.error); 579 580 } 581 } 582 } 583 584 return responseObject; 585 586 }, 587 /** 588 * @private Release the allocated XHR object and reset any timers 589 */ 590 releaseObject : function(o) { 591 592 o && (o.conn = null); 593 if (o && Ext.value(o.tId, -1) + 1) { 594 if (this.poll[o.tId]) { 595 window.clearInterval(this.poll[o.tId]); 596 delete this.poll[o.tId]; 597 } 598 if (this.timeout[o.tId]) { 599 window.clearInterval(this.timeout[o.tId]); 600 delete this.timeout[o.tId]; 601 } 602 } 603 }, 604 605 /** 606 * replace with a custom JSON decoder/validator if required 607 */ 608 decodeJSON : Ext.decode, 609 610 /** 611 * @cfg reCtypeJSON regexp test pattern applied to incoming response 612 * Content-Type header to identify a potential JSON response. The 613 * default pattern handles either text/json or application/json 614 */ 615 reCtypeJSON : /(application|text)\/json/i, 616 617 /** 618 * @cfg reCtypeXML regexp test pattern applied to incoming response 619 * Content-Type header to identify a potential JSON response. The 620 * default pattern handles either text/json or application/json 621 */ 622 reCtypeXML : /(application|text)\/xml/i, 623 624 /** private */ 625 createResponseObject : function(o, callbackArg, isAbort, isTimeout) { 626 var CTYPE = 'content-type', obj = { 627 responseXML : null, 628 responseText : '', 629 responseStream : null, 630 responseJSON : null, 631 contentType : null, 632 getResponseHeader : emptyFn, 633 getAllResponseHeaders : emptyFn 634 }; 635 636 var headerObj = {}, headerStr = ''; 637 638 if (isAbort !== true) { 639 try { // to catch bad encoding problems here 640 obj.responseJSON = o.conn.responseJSON || null; 641 obj.responseStream = o.conn.responseStream || null; 642 obj.contentType = o.conn.contentType || null; 643 obj.responseText = o.conn.responseText; 644 } catch (e) { 645 o.status.isError = true; 646 o.status.error = e; 647 } 648 649 try { 650 obj.responseXML = o.conn.responseXML || null; 651 } catch (ex) {} 652 653 try { 654 headerStr = ('getAllResponseHeaders' in o.conn ? o.conn.getAllResponseHeaders() : null) || ''; 655 var s; 656 headerStr.split('\n').forEach(function(sHeader) { 657 (s = sHeader.split(':')) && s.first() && (headerObj[s.first().trim().toLowerCase()] = (s.last() || '').trim()); 658 }); 659 660 } catch (ex1) { 661 o.status.isError = true; // trigger future exception callback 662 o.status.error = ex1; 663 } finally { 664 obj.contentType = obj.contentType || headerObj[CTYPE] || ''; 665 } 666 667 if ((o.status.isLocal || o.proxied) && typeof obj.responseText == 'string') { 668 669 o.status.isOK = !o.status.isError && ((o.status.status = (!!obj.responseText.length) ? 200 : 404) == 200); 670 671 if (o.status.isOK && ((!obj.responseXML && this.reCtypeXML.test(obj.contentType)) || (obj.responseXML && obj.responseXML.childNodes.length === 0))) { 672 673 var xdoc = null; 674 try { // ActiveX may be disabled 675 if (Ext.capabilities.hasActiveX) { 676 xdoc = new ActiveXObject("MSXML2.DOMDocument.3.0"); 677 xdoc.async = false; 678 xdoc.loadXML(obj.responseText); 679 } else { 680 var domParser = null; 681 try { // Opera 9 will fail parsing non-XML content, so trap 682 // here. 683 domParser = new DOMParser(); 684 xdoc = domParser.parseFromString(obj.responseText, 'application\/xml'); 685 } catch (exP) {} finally { 686 domParser = null; 687 } 688 } 689 } catch (exd) { 690 o.status.isError = true; 691 o.status.error = exd; 692 } 693 obj.responseXML = xdoc; 694 } 695 if (obj.responseXML) { 696 var parseBad = (obj.responseXML.documentElement && obj.responseXML.documentElement.nodeName == 'parsererror') || (obj.responseXML.parseError || 0) !== 0 697 || obj.responseXML.childNodes.length === 0; 698 parseBad || (obj.contentType = headerObj[CTYPE] = obj.responseXML.contentType || 'text\/xml'); 699 } 700 } 701 702 if (o.options.isJSON || (this.reCtypeJSON && this.reCtypeJSON.test(headerObj[CTYPE] || ""))) { 703 try { 704 Ext.isObject(obj.responseJSON) || (obj.responseJSON = Ext.isFunction(this.decodeJSON) && Ext.isString(obj.responseText) ? this.decodeJSON(obj.responseText) : null); 705 } catch (exJSON) { 706 o.status.isError = true; // trigger future exception callback 707 o.status.error = exJSON; 708 } 709 } 710 711 } // isAbort? 712 o.status.proxied = !!o.proxied; 713 714 Ext.apply(obj, { 715 tId : o.tId, 716 status : o.status.status, 717 statusText : o.status.statusText, 718 contentType : obj.contentType || headerObj[CTYPE], 719 getResponseHeader : function(header) { 720 return headerObj[(header || '').trim().toLowerCase()]; 1558 721 }, 1559 forEach : function(){1560 this.times.apply(this, arguments);722 getAllResponseHeaders : function() { 723 return headerStr; 1561 724 }, 1562 1563 clone : function(){ 1564 return (this)+ 0; 1565 } 1566 }); 1567 1568 // character enumeration 1569 Ext.applyIf(String.prototype, { 1570 1571 trim : function() { 1572 var re = /^\s+|\s+$/g; 1573 return function() { 1574 return this.replace(re, ""); 1575 }; 1576 }(), 1577 1578 trimRight : function() { 1579 var re = /^|\s+$/g; 1580 return function() { 1581 return this.replace(re, ""); 1582 }; 1583 }(), 1584 1585 trimLeft : function() { 1586 var re = /^\s+|$/g; 1587 return function() { 1588 return this.replace(re, ""); 1589 }; 1590 }(), 1591 1592 clone : function() { return String(this)+''; }, 1593 1594 forEach : function(block, context){ 1595 String.forEach(this, block,context); 1596 } 1597 1598 }); 1599 1600 1601 var overload = function(pfn, fn ){ 1602 1603 var f = typeof pfn == 'function' ? pfn : function(){}; 1604 1605 var ov = f._ovl; //call signature hash 1606 if(!ov){ 1607 ov = { base: f}; 1608 ov[f.length|| 0] = f; 1609 1610 f= function(){ //the proxy stub 1611 var o = arguments.callee._ovl; 1612 var fn = o[arguments.length] || o.base; 1613 //recursion safety 1614 return fn && fn != arguments.callee ? fn.apply(this,arguments): undefined; 1615 }; 1616 } 1617 var fnA = [].concat(fn); 1618 for(var i=0,l=fnA.length; i<l; ++i){ 1619 //ensures no duplicate call signatures, but last in rules! 1620 ov[fnA[i].length] = fnA[i]; 1621 } 1622 f._ovl= ov; 1623 return f; 1624 1625 }; 1626 1627 1628 Ext.apply(Ext,{ 1629 overload : overload( overload, 1630 [ 1631 function(fn){ return overload(null, fn);}, 1632 function(obj, mname, fn){ 1633 return obj[mname] = overload(obj[mname],fn);} 1634 ]), 1635 1636 isIterable : function(e){ 1637 if (Ext.isArray(e) || e.callee) { return true; } 1638 if (/NodeList|HTMLCollection/.test(OP.toString.call(e))) { return true; } 1639 return (typeof e.nextNode != 'undefined' || e.item) && Ext.isNumber(e.length); 1640 }, 1641 1642 isArray : function(obj){ 1643 return OP.toString.apply(obj) == '[object Array]'; 1644 }, 1645 1646 isObject:function(obj){ 1647 return !!obj && OP.toString.apply(obj) == '[object Object]'; 1648 }, 1649 1650 isNumber: function(obj){ 1651 return typeof obj == 'number' && isFinite(obj); 1652 }, 1653 1654 isBoolean: function(obj){ 1655 return typeof obj == 'boolean'; 1656 }, 1657 1658 isDocument : function(obj){ 1659 return OP.toString.apply(obj) == '[object HTMLDocument]' || (obj && obj.nodeType === 9); 1660 }, 1661 1662 isElement : function(obj){ 1663 if(obj){ 1664 var o = obj.dom || obj; 1665 return !!o.tagName || (/\[object html/i).test(OP.toString.apply(o)); 725 fullStatus : o.status, 726 isPart : o.isPart || false 727 }); 728 729 o.parts && !o.isPart && (obj.parts = o.parts); 730 defined(callbackArg) && (obj.argument = callbackArg); 731 return obj; 732 }, 733 734 setDefaultPostHeader : function(contentType) { 735 this.defaultPostHeader = contentType || ''; 736 }, 737 738 /** 739 * Toggle use of the DefaultXhrHeader ('Ext.basex') 740 */ 741 setDefaultXhrHeader : function(bool) { 742 this.useDefaultXhrHeader = bool || false; 743 }, 744 745 request : function(method, uri, cb, data, options) { 746 747 var O = options = Ext.apply({ 748 async : this.async || false, 749 headers : false, 750 userId : null, 751 password : null, 752 xmlData : null, 753 jsonData : null, 754 queue : null, 755 proxied : false, 756 multiPart : false, 757 xdomain : false 758 }, options || {}); 759 760 // Seek out nested config options 761 var _to; 762 if (cb.argument && cb.argument.options && cb.argument.options.request && (_to = cb.argument.options.request.arg)) { 763 764 Ext.apply(O, { 765 async : O.async || _to.async, 766 proxied : O.proxied || _to.proxied, 767 multiPart : O.multiPart || _to.multiPart, 768 xdomain : O.xdomain || _to.xdomain, 769 queue : O.queue || _to.queue, 770 onPart : O.onPart || _to.onPart 771 }); 772 } 773 774 if (!this.events || this.fireEvent('request', method, uri, cb, data, O) !== false) { 775 776 // Named priority queues 777 if (!O.queued && (O.queue || (O.queue = this.queueAll || null))) { 778 779 O.queue === true && (O.queue = { 780 name : 'q-default' 781 }); 782 var oq = O.queue; 783 var qname = oq.name || oq, qm = this.queueManager; 784 785 var q = qm.getQueue(qname) || qm.createQueue(oq); 786 O.queue = q; 787 O.queued = true; 788 789 var req = [ 790 method, uri, cb, data, O 791 ]; 792 req.active = true; 793 q.add(req); 794 795 return { 796 tId : this.transactionId++, 797 queued : true, 798 request : req, 799 options : O 800 }; 801 } 802 803 options.onpart && (cb.onpart || (cb.onpart = Ext.isFunction(options.onpart) ? options.onpart.createDelegate(options.scope) : null)); 804 805 O.headers && forEach(O.headers, function(value, key) { 806 this.initHeader(key, value, false); 807 }, this); 808 809 var cType; 810 // The Content-Type specified on options.headers always has priority 811 // over 812 // a calculated value. 813 if (cType = (this.headers ? this.headers['Content-Type'] || null : null)) { 814 // remove to ensure only ONE is passed later.(per RFC) 815 delete this.headers['Content-Type']; 816 } 817 if (O.xmlData) { 818 cType || (cType = 'text/xml'); 819 method = 'POST'; 820 data = O.xmlData; 821 } else if (O.jsonData) { 822 cType || (cType = 'application/json; charset=utf-8'); 823 method = 'POST'; 824 data = (Ext.isArray(O.jsonData) || Ext.isObject(O.jsonData)) ? Ext.encode(O.jsonData) : O.jsonData; 825 } 826 if (data) { 827 cType || (cType = this.useDefaultHeader ? this.defaultPostHeader : null); 828 cType && this.initHeader('Content-Type', cType, false); 829 } 830 831 // options.method prevails over any derived method. 832 return this.makeRequest(O.method || method, uri, cb, data, O); 833 } 834 return null; 835 836 }, 837 838 /** private */ 839 getConnectionObject : function(uri, options, data) { 840 var o, f; 841 var tId = this.transactionId; 842 options || (options = {}); 843 try { 844 if (f = options.proxied) { /* JSONP scriptTag Support */ 845 846 o = { 847 tId : tId, 848 status : { 849 isError : false 850 }, 851 proxied : true, 852 // synthesize an XHR object 853 conn : { 854 el : null, 855 send : function(data) { 856 var doc = (f.target || window).document, head = doc.getElementsByTagName("head")[0]; 857 if (head && this.el) { 858 head.appendChild(this.el.dom); 859 this.readyState = 2; 860 } 861 }, 862 abort : function() { 863 this.readyState = 0; 864 window[o.cbName] = undefined; 865 // IE dislikes this 866 Ext.isIE || delete window[o.cbName]; 867 868 var d = Ext.getDom(this.el); 869 870 if (this.el) { 871 this.el.removeAllListeners(); 872 if (!o.debug) { 873 if (Ext.isIE) { 874 // Script Tags are re-usable in IE 875 A.SCRIPTTAG_POOL.push(this.el); 876 } else { 877 this.el.remove(); 878 // Other Browsers will not GBG-collect these tags, so help 879 // them along 880 if (d) { 881 for (var prop in d) { 882 delete d[prop]; 883 } 884 } 885 } 886 } 887 } 888 this.el = d = null; 889 }, 890 _headers : {}, 891 getAllResponseHeaders : function() { 892 var out = []; 893 forEach(this._headers, function(value, name) { 894 value && out.push(name + ': ' + value); 895 }); 896 return out.join('\n'); 897 898 }, 899 getResponseHeader : function(header) { 900 return this._headers[String(header).toLowerCase()] || ''; 901 }, 902 onreadystatechange : null, 903 onload : null, 904 readyState : 0, 905 status : 0, 906 responseText : null, 907 responseXML : null, 908 responseJSON : null 909 }, 910 debug : f.debug, 911 params : Ext.isString(options.params) ? Ext.urlDecode(options.params) : options.params || {}, 912 cbName : f.callbackName || 'basexCallback' + tId, 913 cbParam : f.callbackParam || null 914 }; 915 916 window[o.cbName] = o.cb = function(content) { 917 918 content && typeof(content) == 'object' && (this.responseJSON = content); 919 this.responseText = content || null; 920 this.status = !!content ? 200 : 404; 921 this.abort(); 922 this.readyState = 4; 923 Ext.isFunction(this.onreadystatechange) && this.onreadystatechange(); 924 Ext.isFunction(this.onload) && this.onload(); 925 926 }.createDelegate(o.conn); 927 928 o.conn.open = function() { 929 930 if (o.cbParam) { 931 o.params[o.cbParam] = o.cbName; 1666 932 } 1667 return false; 1668 }, 1669 1670 isEvent : function(obj){ 1671 return OP.toString.apply(obj) == '[object Event]' || (Ext.isObject(obj) && !Ext.type(obj.constructor) && (window.event && obj.clientX && obj.clientX === window.event.clientX)); 1672 }, 1673 1674 isFunction: function(obj){ 1675 return OP.toString.apply(obj) == '[object Function]'; 1676 }, 1677 1678 isString : function(obj){ 1679 return typeof obj == 'string'; 1680 }, 1681 1682 isPrimitive : function(v){ 1683 return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v); 1684 }, 1685 1686 isDefined: defined 1687 1688 }); 1689 /** 1690 * @class Ext 1691 * @singleton 1692 * @constructor 1693 * @description Ext Adapter extensions 1694 */ 1695 1696 /** 1697 * @class Ext.capabilities 1698 * @singleton 1699 * @version 4.0 1700 * @donate <a target="tag_donate" href="http://donate.theactivegroup.com"><img border="0" src="http://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" border="0" alt="Make a donation to support ongoing development"></a> 1701 * @license <a href="http://www.gnu.org/licenses/gpl.html">GPL 3.0</a> 1702 * @author Doug Hendricks. Forum ID: <a href="http://extjs.com/forum/member.php?u=8730">hendricd</a> 1703 * @copyright 2007-2009, Active Group, Inc. All rights reserved. 1704 * @desc Describes Detected Browser capabilities. 1705 */ 1706 Ext.ns('Ext.capabilities'); 1707 var caps = Ext.capabilities; 1708 Ext.apply(caps , { 1709 /** 1710 * @property {Boolean} hasActiveX True if the Browser support (and is enabled) ActiveX. 1711 */ 1712 hasActiveX : defined(window.ActiveXObject), 1713 1714 /** 1715 * @property {Boolean} hasXDR True if the Browser has native Cross-Domain Ajax request support. 1716 */ 1717 hasXDR : function(){ 1718 return defined(window.XDomainRequest) || (defined(window.XMLHttpRequest) && 'withCredentials' in new XMLHttpRequest()); 1719 }(), 1720 1721 /** 1722 * @property {Boolean} hasChromeFrame true, if the Google ChromeFrame plugin is install on IE 1723 */ 1724 hasChromeFrame : function(){ 1725 try{ 1726 if(defined(window.ActiveXObject) && !!(new ActiveXObject("ChromeTab.ChromeFrame")))return true; 1727 }catch(ef){} 1728 var a = navigator.userAgent.toLowerCase(); 1729 return !!(a.indexOf("chromeframe")>=0 || a.indexOf("x-clock")>=0 ); 1730 1731 }(), 1732 1733 /** 1734 * @property {Boolean} hasFlash True if the Flash Browser plugin is installed. 1735 */ 1736 hasFlash : (function(){ 1737 //Check for ActiveX first because some versions of IE support navigator.plugins, just not the same as other browsers 1738 if(defined(window.ActiveXObject)){ 1739 try{ 1740 //try to create a flash instance 1741 new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); 1742 return true; 1743 }catch(e){}; 1744 //If the try-catch fails, return false 1745 return false; 1746 }else if(navigator.plugins){ 1747 //Loop through all the plugins 1748 for(var i=0, P=navigator.plugins,length = P.length; i < length; ++i){ 1749 //test to see if any plugin names contain the word flash, if so it must support it - return true 1750 if((/flash/i).test(P[i].name)){ 1751 return true; 1752 } 933 934 // apply any new params to any already supplied by the uri and 935 // postData 936 var params = Ext.urlEncode(Ext.apply(Ext.urlDecode(data) || {}, // decode 937 // any 938 // postData 939 o.params, uri.indexOf("?") > -1 ? Ext.urlDecode(uri.split('?').last()) : false 940 ) 941 ); 942 943 o.uri = params ? uri.split('?').first() + '?' + params : uri; 944 945 this.el = A.monitoredNode(f.tag || 'script', { 946 type : f.contentType || "text/javascript", 947 src : o.uri, 948 charset : f.charset || options.charset || null 949 }, null, f.target, true); // defer head insertion until send method 950 951 this._headers['content-type'] = this.el.dom.type; 952 this.readyState = 1; // show CallInProgress 953 Ext.isFunction(this.onreadystatechange) && this.onreadystatechange(); 954 955 }; 956 options.async = true; // force timeout support 957 958 } else { 959 o = this.createXhrObject(tId, options); 960 } 961 if (o) { 962 this.transactionId++; 963 } 964 } catch (ex3) { 965 o && (o.status.isError = !!(o.status.error = ex3)); 966 } finally { 967 return o; 968 } 969 }, 970 971 /** private */ 972 makeRequest : function(method, uri, callback, postData, options) { 973 974 var o; 975 if (o = this.getConnectionObject(uri, options, postData)) { 976 o.options = options; 977 var r = o.conn; 978 979 try { 980 if (o.status.isError) { 981 throw o.status.error 982 }; 983 984 A.activeRequests++; 985 r.open(method.toUpperCase(), uri, options.async, options.userId, options.password); 986 987 ('onreadystatechange' in r) && (r.onreadystatechange = this.onStateChange.createDelegate(this, [ 988 o, callback, 'readystate' 989 ], 0)); 990 991 ('onload' in r) && (r.onload = this.onStateChange.createDelegate(this, [ 992 o, callback, 'load', 4 993 ], 0)); 994 995 ('onprogress' in r) && (r.onprogress = this.onStateChange.createDelegate(this, [ 996 o, callback, 'progress' 997 ], 0)); 998 999 // IE8/other? evolving timeout callback support 1000 if (callback && callback.timeout) { 1001 ('timeout' in r) && (r.timeout = callback.timeout); 1002 ('ontimeout' in r) && (r.ontimeout = this.abort.createDelegate(this, [ 1003 o, callback, true 1004 ], 0)); 1005 ('ontimeout' in r) || 1006 // Timers for syncro calls won't work here, as it's a blocking 1007 // call 1008 (options.async && (this.timeout[o.tId] = window.setInterval(function() { 1009 A.abort(o, callback, true); 1010 }, callback.timeout))); 1011 } 1012 1013 if (this.useDefaultXhrHeader && !options.xdomain) { 1014 this.defaultHeaders['X-Requested-With'] || this.initHeader('X-Requested-With', this.defaultXhrHeader, true); 1015 } 1016 this.setHeaders(o); 1017 1018 if (!this.events || this.fireEvent('beforesend', o, method, uri, callback, postData, options) !== false) { 1019 r.send(postData || null); 1020 } 1021 } catch (exr) { 1022 o.status.isError = true; 1023 o.status.error = exr; 1024 } 1025 if (o.status.isError) { 1026 return Ext.apply(o, this.handleTransactionResponse(o, callback)); 1027 } 1028 options.async || this.onStateChange(o, callback, 'load'); 1029 return o; 1030 } 1031 }, 1032 1033 abort : function(o, callback, isTimeout) { 1034 1035 o && Ext.apply(o.status, { 1036 isAbort : !!!isTimeout, 1037 isTimeout : !!isTimeout, 1038 isError : !!isTimeout || !!o.status.isError 1039 }); 1040 if (o && o.queued && o.request) { 1041 o.request.active = o.queued = false; 1042 this.events && this.fireEvent('abort', o, callback); 1043 return true; 1044 } else if (o && this.isCallInProgress(o)) { 1045 1046 if (!this.events || this.fireEvent(isTimeout ? 'timeout' : 'abort', o, callback) !== false) { 1047 ('abort' in o.conn) && o.conn.abort(); 1048 this.handleTransactionResponse(o, callback, o.status.isAbort, o.status.isTimeout); 1049 } 1050 return true; 1051 } 1052 return false; 1053 }, 1054 1055 isCallInProgress : function(o) { 1056 // if there is a connection and readyState is supported, and not 0 or 4 1057 if (o && o.conn) { 1058 if ('readyState' in o.conn && { 1059 0 : true, 1060 4 : true 1061 }[o.conn.readyState]) { 1062 return false; 1063 } 1064 return true; 1065 } 1066 return false; 1067 }, 1068 1069 /** 1070 * Clears the Browser authentication Cache 1071 * 1072 * @param {String} 1073 * url {optional) reset url for non-IE browsers 1074 * @return void 1075 */ 1076 clearAuthenticationCache : function(url) { 1077 1078 try { 1079 1080 if (Ext.isIE) { 1081 // IE clear HTTP Authentication, (but ALL realms though) 1082 document.execCommand("ClearAuthenticationCache"); 1083 } else { 1084 // create an xmlhttp object 1085 var xmlhttp; 1086 if (xmlhttp = new XMLHttpRequest()) { 1087 // prepare invalid credentials 1088 xmlhttp.open("GET", url || '/@@', true, "logout", "logout"); 1089 // send the request to the server 1090 xmlhttp.send(""); 1091 // abort the request 1092 xmlhttp.abort.defer(100, xmlhttp); 1093 } 1094 } 1095 } catch (e) {} // There was an error 1096 1097 }, 1098 1099 // private 1100 initHeader : function(label, value) { 1101 (this.headers = this.headers || {})[label] = value; 1102 }, 1103 1104 /** 1105 * @private General readyStateChange multiPart handler 1106 */ 1107 onStateChange : function(o, callback, mode) { 1108 1109 if (!o.conn || o.status.isTimeout || o.status.isError) { 1110 return; 1111 } 1112 1113 var C = o.conn, readyState = ('readyState' in C ? C.readyState : 0); 1114 if (mode === 'load' || readyState > 2) { 1115 var ct; 1116 try { 1117 ct = C.contentType || C.getResponseHeader('Content-Type') || ''; 1118 } catch (exRs) {} 1119 1120 if (ct && /multipart\//i.test(ct)) { 1121 var r = null, boundary = ct.split('"')[1], kb = '--' + boundary; 1122 o.multiPart = true; 1123 try { 1124 r = C.responseText; 1125 } catch (ers) {} 1126 1127 var p = r ? r.split(kb) : null; 1128 1129 if (p) { 1130 o.parts || (o.parts = []); 1131 p.shift(); 1132 p.pop(); 1133 1134 forEach(Array.slice(p, o.parts.length), // skip parts already parsed 1135 function(newPart) { 1136 var content = newPart.split('\n\n'); 1137 var H = (content[0] ? content[0] : '') + '\n'; 1138 o.parts.push(this.handleTransactionResponse(Ext.apply(Ext.clone(o), { 1139 boundary : boundary, 1140 conn : { // synthetic conn structure for each part 1141 status : 200, 1142 responseText : (content[1] || '').trim(), 1143 getAllResponseHeaders : function() { 1144 return H.split('\n').filter(function(value) { 1145 return !!value; 1146 }).join('\n'); 1753 1147 } 1754 //return false if no plugins match 1755 return false; 1756 } 1757 //Return false if ActiveX and nagivator.plugins are not supported 1758 return false; 1759 })(), 1760 1761 /** 1762 * @property {Boolean} hasCookies True if the browser cookies are enabled/supported. 1763 * On IE, ModalDialog windows will issue a security risk warning to the user during this check, so assert 1764 * to false. (Cookie implementations on IE's [Modeless|Modal]Dialogs are not supported as 1765 * they run in a seperate ActiveX browser context) 1766 */ 1767 hasCookies : Ext.isIE && ('dialogArguments' in window) ? false : !!navigator.cookieEnabled , 1768 1769 /** 1770 * @property {Boolean} hasCanvas True if the browser has canvas Element support. 1771 */ 1772 hasCanvas : !!document.createElement("canvas").getContext, 1773 1774 /** 1775 * @property {Boolean} hasCanvasText True if the browser has canvas Element Text support. 1776 */ 1777 hasCanvasText : function(){ 1778 return !!(this.hasCanvas && typeof document.createElement('canvas').getContext('2d').fillText == 'function'); 1779 }(), 1780 1781 /** 1782 * @property {Boolean} hasSVG True if the browser has SVG support. 1783 */ 1784 hasSVG : !!(document.createElementNS && document.createElementNS('http://www.w3.org/2000/svg', 'svg').width), 1785 1786 /** 1787 * @property {Boolean} hasXpath True if the browser has Xpath query support. 1788 */ 1789 hasXpath : !!document.evaluate, 1790 1791 /** 1792 * @property {Boolean} hasWorkers True if the browser has support for threaded Workers. 1793 */ 1794 hasWorkers : defined(window.Worker) || caps.hasGears, 1795 1796 /** 1797 * @property {Boolean} hasOffline True if the browser has offline support. 1798 */ 1799 hasOffline : defined(window.applicationCache), 1800 1801 /** 1802 * @property {Boolean} hasLocalStorage True if the browser has Local Storage support. 1803 */ 1804 hasLocalStorage : defined(window.localStorage), 1805 1806 /** 1807 * Basic HTML5 geolocation services support test 1808 * @property {Boolean} hasGeoLocation 1809 */ 1810 hasGeoLocation : defined(navigator.geolocation), 1811 1812 hasBasex : true, 1813 1814 /** 1815 * 1816 * @property {Boolean/Object} hasAudio 1817 * @desc Basic HTML5 Element support for the <audio> tag and/or Audio object. 1818 * @example 1819 If the browser has <audio> tag or Audio object support,<br />the property contains a mime-type map of standard audio formats. 1820 { 1821 mp3 : false, //mp3 1822 ogg : false, //Ogg Vorbis 1823 wav : true, //wav 1824 basic : false, //au, snd 1825 aif : false, //aif, aifc, aiff 1826 tag : true, //is audio HTML element supported? 1827 object : true, //is the window.Audio Object supported 1828 <b>testMime</b> : function() 1829 } 1830 1831 The included <b>testMime</b> function permits selective mime-type testing as well for custom audio formats: 1832 if(Ext.capabilities.hasAudio && 1833 Ext.capabilities.hasAudio.testMime('audio/ogg') ){ 1834 alert ('Vorbis playback is supported'); 1148 }, 1149 isPart : true 1150 }), callback)); 1151 }, this 1152 ); 1835 1153 } 1154 1155 } 1156 } 1157 (readyState === 4 || mode === 'load') && A.handleTransactionResponse(o, callback); 1158 this.events && this.fireEvent.apply(this, [ 1159 'readystatechange' 1160 ].concat(Array.slice(arguments, 0))); 1161 }, 1162 1163 setHeaders : function(o) { 1164 1165 // Some XDomain implementations (IE8) do not support setting headers 1166 if (o.conn && 'setRequestHeader' in o.conn) { 1167 this.defaultHeaders && forEach(this.defaultHeaders, function(value, key) { 1168 o.conn.setRequestHeader(key, value); 1169 }); 1170 1171 this.headers && forEach(this.headers, function(value, key) { 1172 o.conn.setRequestHeader(key, value); 1173 }); 1174 } 1175 this.headers = {}; 1176 this.hasHeaders = false; 1177 1178 }, 1179 1180 resetDefaultHeaders : function() { 1181 delete this.defaultHeaders; 1182 this.defaultHeaders = {}; 1183 this.hasDefaultHeaders = false; 1184 }, 1185 1186 // These are only current versions of ActiveX XHR that support multipart 1187 // responses 1188 activeXMultipart : [ 1189 'MSXML2.XMLHTTP.6.0', 'MSXML3.XMLHTTP' 1190 ], 1191 1192 activeX : [ 1193 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP' 1194 ] 1195 1196 }); 1197 1198 if (Ext.util.Observable) { 1199 1200 Ext.apply(A, { 1201 1202 events : { 1203 request : true, 1204 beforesend : true, 1205 response : true, 1206 exception : true, 1207 abort : true, 1208 timeout : true, 1209 readystatechange : true, 1210 beforequeue : true, 1211 queue : true, 1212 queueempty : true 1213 }, 1214 1215 /** 1216 * onStatus define eventListeners for a single (or array) of HTTP status 1217 * codes. 1218 */ 1219 1220 onStatus : function(status, fn, scope, options) { 1221 var args = Array.slice(arguments, 1); 1222 status = new Array().concat(status || new Array()); 1223 forEach(status, function(statusCode) { 1224 statusCode = parseInt(statusCode, 10); 1225 if (!isNaN(statusCode)) { 1226 var ev = 'status:' + statusCode; 1227 this.events[ev] || (this.events[ev] = true); 1228 this.on.apply(this, [ 1229 ev 1230 ].concat(args)); 1231 } 1232 }, this); 1233 }, 1234 1235 /** 1236 * unStatus unSet eventListeners for a single (or array) of HTTP status 1237 * codes. 1238 */ 1239 1240 unStatus : function(status, fn, scope, options) { 1241 var args = Array.slice(arguments, 1); 1242 status = new Array().concat(status || new Array()); 1243 forEach(status, function(statusCode) { 1244 statusCode = parseInt(statusCode, 10); 1245 if (!isNaN(statusCode)) { 1246 var ev = 'status:' + statusCode; 1247 this.un.apply(this, [ 1248 ev 1249 ].concat(args)); 1250 } 1251 }, this); 1252 } 1253 1254 }, new Ext.util.Observable()); 1255 1256 Ext.hasBasex = true; 1257 } 1258 1259 // Array, object iteration and clone support 1260 Ext.stopIteration = { 1261 stopIter : true 1262 }; 1263 1264 Ext.applyIf(Array.prototype, { 1265 1266 /* 1267 * Fix for IE, Opera < 9.5, which does not seem to include the map function 1268 * on Array's 1269 */ 1270 map : function(fun, scope) { 1271 var len = this.length; 1272 if (typeof fun != "function") { 1273 throw new TypeError(); 1274 } 1275 var res = new Array(len); 1276 1277 for (var i = 0; i < len; ++i) { 1278 i in this && (res[i] = fun.call(scope || this, this[i], i, this)); 1279 } 1280 return res; 1281 }, 1282 1283 /** 1284 * Return true of the passed Function test true of ANY array elememt. (added 1285 * for IE) 1286 */ 1287 some : function(fn) { 1288 var f = Ext.isFunction(fn) ? fn : function() {}; 1289 var i = 0, l = this.length, test = false; 1290 while (i < l && !(test = !!f(this[i++]))) {} 1291 return test; 1292 }, 1293 1294 /** 1295 * Return true of the passed Function test true of ALL array elememts. 1296 * (added for IE) 1297 */ 1298 every : function(fn) { 1299 var f = Ext.isFunction(fn) ? fn : function() {}; 1300 var i = 0, l = this.length, test = true; 1301 while (i < l && (test = !!f(this[i++]))) {} 1302 return test; 1303 }, 1304 1305 include : function(value, deep) { // Boolean: is value present 1306 // in Array 1307 // use native indexOf if available 1308 if (!deep && typeof this.indexOf == 'function') { 1309 return this.indexOf(value) != -1; 1310 } 1311 var found = false; 1312 try { 1313 this.forEach(function(item, index) { 1314 if (found = (deep ? (item.include ? item.include(value, deep) : (item === value)) : item === value)) { 1315 throw Ext.stopIteration; 1316 } 1317 }); 1318 } catch (exc) { 1319 if (exc != Ext.stopIteration) { 1320 throw exc; 1321 } 1322 } 1323 return found; 1324 }, 1325 // Using iterFn, traverse the array, push the current element 1326 // value onto the 1327 // result if the iterFn returns true 1328 filter : function(iterFn, scope) { 1329 var a = new Array(); 1330 iterFn || (iterFn = function(value) { 1331 return value; 1332 }); 1333 this.forEach(function(value, index) { 1334 iterFn.call(scope, value, index) && a.push(value); 1335 }); 1336 return a; 1337 }, 1338 1339 compact : function(deep) { // Remove null, undefined array 1340 // elements 1341 var a = new Array(); 1342 this.forEach(function(v) { 1343 (v === null || v === undefined) || a.push(deep && Ext.isArray(v) ? v.compact() : v); 1344 }, this); 1345 return a; 1346 }, 1347 1348 flatten : function() { // flatten: [1,2,3,[4,5,6]] -> 1349 // [1,2,3,4,5,6] 1350 var a = new Array(); 1351 this.forEach(function(v) { 1352 Ext.isArray(v) ? (a = a.concat(v)) : a.push(v); 1353 }, this); 1354 return a; 1355 }, 1356 1357 indexOf : function(o) { 1358 for (var i = 0, len = this.length; i < len; ++i) { 1359 if (this[i] == o) 1360 return i; 1361 } 1362 return -1; 1363 }, 1364 1365 lastIndexOf : function(val) { 1366 var i = this.length - 1; 1367 while (i > -1 && this[i] != val) { 1368 i--; 1369 } 1370 return i; 1371 }, 1372 1373 unique : function(sorted /* sort optimization */, exact) { // unique: 1374 // [1,3,3,4,4,5] 1375 // -> 1376 // [1,3,4,5] 1377 var a = new Array(); 1378 this.forEach(function(value, index) { 1379 if (0 == index || (sorted ? a.last() != value : !a.include(value, exact))) { 1380 a.push(value); 1381 } 1382 }, this); 1383 return a; 1384 }, 1385 // search array values based on regExpression pattern returning 1386 // test (and optionally execute function(value,index) on test 1387 // before returned) 1388 grep : function(rePattern, iterFn, scope) { 1389 var a = new Array(); 1390 iterFn || (iterFn = function(value) { 1391 return value; 1392 }); 1393 var fn = scope ? iterFn.createDelegate(scope) : iterFn; 1394 1395 if (typeof rePattern == 'string') { 1396 rePattern = new RegExp(rePattern); 1397 } 1398 rePattern instanceof RegExp && this.forEach(function(value, index) { 1399 rePattern.test(value) && a.push(fn(value, index)); 1400 }); 1401 return a; 1402 }, 1403 1404 first : function() { 1405 return this[0]; 1406 }, 1407 1408 last : function() { 1409 return this[this.length - 1]; 1410 }, 1411 1412 clear : function() { 1413 this.length = 0; 1414 }, 1415 1416 // return an array element selected at random 1417 atRandom : function(defValue) { 1418 var r = Math.floor(Math.random() * this.length); 1419 return this[r] || defValue; 1420 }, 1421 1422 clone : function(deep) { 1423 if (!deep) { 1424 return this.concat(); 1425 } 1426 1427 var length = this.length || 0, t = new Array(length); 1428 while (length--) { 1429 t[length] = Ext.clone(this[length], true); 1430 } 1431 return t; 1432 1433 }, 1434 1435 /* 1436 * Array forEach Iteration based on previous work by: Dean Edwards 1437 * (http://dean.edwards.name/weblog/2006/07/enum/) Gecko already supports 1438 * forEach for Arrays : see 1439 * http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/forEach 1440 */ 1441 forEach : function(block, scope) { 1442 Array.forEach(this, block, scope); 1443 }, 1444 1445 reversed : function() { 1446 var length = this.length || 0, t = []; 1447 while (length--) { 1448 t.push(this[length]); 1449 } 1450 return t; 1451 } 1452 1453 }); 1454 1455 // globally resolve forEach enumeration 1456 window.forEach = function(object, block, context, deep) { 1457 context = context || object; 1458 if (object) { 1459 if (typeof block != "function") { 1460 throw new TypeError(); 1461 } 1462 var resolve = Object; 1463 if (object instanceof Function) { 1464 // functions have a "length" property 1465 resolve = Function; 1466 1467 } else if (object.forEach instanceof Function) { 1468 // the object implements a custom forEach method so use that 1469 return object.forEach(block, context); 1470 1471 } else if (typeof object == "string") { 1472 // the object is a string 1473 resolve = String; 1474 1475 } else if (Ext.isNumber(object.length)) { 1476 // the object is array-like 1477 resolve = Array; 1478 } 1479 return resolve.forEach(object, block, context, deep); 1480 } 1481 }; 1482 1483 /** 1484 * 1485 * Primary clone Function 1486 */ 1487 Ext.clone = function(obj, deep) { 1488 if (obj === null || obj === undefined) { 1489 return obj; 1490 } 1491 1492 if (Ext.isFunction(obj.clone)) { 1493 return obj.clone(deep); 1494 } else if (Ext.isFunction(obj.cloneNode)) { 1495 return obj.cloneNode(deep); 1496 } 1497 var o = {}; 1498 forEach(obj, function(value, name, objAll) { 1499 o[name] = (value === objAll ? // reference to itself? 1500 o : deep ? Ext.clone(value, true) : value); 1501 }, obj, deep); 1502 return o; 1503 }; 1504 1505 var slice = Array.prototype.slice; 1506 var filter = Array.prototype.filter; 1507 Ext.applyIf(Array, { 1508 // Permits: Array.slice(arguments, 1); // mozilla already supports this 1509 slice : function(obj) { 1510 return slice.apply(obj, slice.call(arguments, 1)); 1511 }, 1512 // String filter iteration 1513 filter : function(obj, fn) { 1514 var t = obj && typeof obj == 'string' ? obj.split('') : []; 1515 return filter.call(t, fn); 1516 }, 1517 /* 1518 * Array forEach Iteration based on previous work by: Dean Edwards 1519 * (http://dean.edwards.name/weblog/2006/07/enum/) Gecko already supports 1520 * forEach for Arrays : see 1521 * https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/forEach 1522 */ 1523 forEach : function(collection, block, scope) { 1524 1525 if (typeof block != "function") { 1526 throw new TypeError(); 1527 } 1528 for (var i = 0, l = collection.length >>> 0; i < l; ++i) { 1529 (i in collection) && block.call(scope || null, collection[i], i, collection); 1530 } 1531 } 1532 }); 1533 1534 // Add clone function to primitive prototypes 1535 1536 Ext.applyIf(RegExp.prototype, { 1537 clone : function() { 1538 return new RegExp(this); 1539 } 1540 }); 1541 1542 Ext.applyIf(Date.prototype, { 1543 clone : function(deep) { 1544 return deep ? new Date(this.getTime()) : this; 1545 } 1546 }); 1547 1548 Ext.applyIf(Boolean.prototype, { 1549 clone : function() { 1550 return this === true; 1551 } 1552 }); 1553 1554 Ext.applyIf(Number.prototype, { 1555 times : function(block, context) { 1556 var total = parseInt(this, 10) || 0; 1557 for (var i = 1; i <= total;) { 1558 block.call(context, i++); 1559 } 1560 }, 1561 forEach : function() { 1562 this.times.apply(this, arguments); 1563 }, 1564 1565 clone : function() { 1566 return (this) + 0; 1567 } 1568 }); 1569 1570 // character enumeration 1571 Ext.applyIf(String.prototype, { 1572 1573 trim : function() { 1574 var re = /^\s+|\s+$/g; 1575 return function() { 1576 return this.replace(re, ""); 1577 }; 1578 }(), 1579 1580 trimRight : function() { 1581 var re = /^|\s+$/g; 1582 return function() { 1583 return this.replace(re, ""); 1584 }; 1585 }(), 1586 1587 trimLeft : function() { 1588 var re = /^\s+|$/g; 1589 return function() { 1590 return this.replace(re, ""); 1591 }; 1592 }(), 1593 1594 clone : function() { 1595 return String(this) + ''; 1596 }, 1597 1598 forEach : function(block, context) { 1599 String.forEach(this, block, context); 1600 } 1601 1602 }); 1603 1604 var overload = function(pfn, fn) { 1605 1606 var f = typeof pfn == 'function' ? pfn : function() {}; 1607 1608 var ov = f._ovl; // call signature hash 1609 if (!ov) { 1610 ov = { 1611 base : f 1612 }; 1613 ov[f.length || 0] = f; 1614 1615 f = function() { // the proxy stub 1616 var o = arguments.callee._ovl; 1617 var fn = o[arguments.length] || o.base; 1618 // recursion safety 1619 return fn && fn != arguments.callee ? fn.apply(this, arguments) : undefined; 1620 }; 1621 } 1622 var fnA = [].concat(fn); 1623 for (var i = 0, l = fnA.length; i < l; ++i) { 1624 // ensures no duplicate call signatures, but last in rules! 1625 ov[fnA[i].length] = fnA[i]; 1626 } 1627 f._ovl = ov; 1628 return f; 1629 1630 }; 1631 1632 Ext.apply(Ext, { 1633 overload : overload(overload, [ 1634 function(fn) { 1635 return overload(null, fn); 1636 }, function(obj, mname, fn) { 1637 return obj[mname] = overload(obj[mname], fn); 1638 } 1639 ]), 1640 1641 isIterable : function(e) { 1642 if (Ext.isArray(e) || e.callee) { 1643 return true; 1644 } 1645 if (/NodeList|HTMLCollection/.test(OP.toString.call(e))) { 1646 return true; 1647 } 1648 return (typeof e.nextNode != 'undefined' || e.item) && Ext.isNumber(e.length); 1649 }, 1650 1651 isArray : function(obj) { 1652 return OP.toString.apply(obj) == '[object Array]'; 1653 }, 1654 1655 isObject : function(obj) { 1656 return !!obj && OP.toString.apply(obj) == '[object Object]'; 1657 }, 1658 1659 isNumber : function(obj) { 1660 return typeof obj == 'number' && isFinite(obj); 1661 }, 1662 1663 isBoolean : function(obj) { 1664 return typeof obj == 'boolean'; 1665 }, 1666 1667 isDocument : function(obj) { 1668 return OP.toString.apply(obj) == '[object HTMLDocument]' || (obj && obj.nodeType === 9); 1669 }, 1670 1671 isElement : function(obj) { 1672 if (obj) { 1673 var o = obj.dom || obj; 1674 return !!o.tagName || (/\[object html/i).test(OP.toString.apply(o)); 1675 } 1676 return false; 1677 }, 1678 1679 isEvent : function(obj) { 1680 return OP.toString.apply(obj) == '[object Event]' || (Ext.isObject(obj) && !Ext.type(obj.constructor) && (window.event && obj.clientX && obj.clientX === window.event.clientX)); 1681 }, 1682 1683 isFunction : function(obj) { 1684 return OP.toString.apply(obj) == '[object Function]'; 1685 }, 1686 1687 isString : function(obj) { 1688 return typeof obj == 'string'; 1689 }, 1690 1691 isPrimitive : function(v) { 1692 return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v); 1693 }, 1694 1695 isDefined : defined 1696 1697 }); 1698 /** 1699 * @class Ext 1700 * @singleton 1701 * @constructor 1702 * @description Ext Adapter extensions 1703 */ 1704 1705 /** 1706 * @class Ext.capabilities 1707 * @singleton 1708 * @version 4.0 1709 * @donate <a target="tag_donate" href="http://donate.theactivegroup.com"><img 1710 * border="0" 1711 * src="http://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" 1712 * border="0" alt="Make a donation to support ongoing development"></a> 1713 * @license <a href="http://www.gnu.org/licenses/gpl.html">GPL 3.0</a> 1714 * @author Doug Hendricks. Forum ID: <a 1715 * href="http://extjs.com/forum/member.php?u=8730">hendricd</a> 1716 * @copyright 2007-2009, Active Group, Inc. All rights reserved. 1717 * @desc Describes Detected Browser capabilities. 1718 */ 1719 Ext.ns('Ext.capabilities'); 1720 var caps = Ext.capabilities; 1721 Ext.apply(caps, { 1722 /** 1723 * @property {Boolean} hasActiveX True if the Browser support (and is 1724 * enabled) ActiveX. 1725 */ 1726 hasActiveX : defined(window.ActiveXObject), 1727 1728 /** 1729 * @property {Boolean} hasXDR True if the Browser has native Cross-Domain 1730 * Ajax request support. 1731 */ 1732 hasXDR : function() { 1733 return defined(window.XDomainRequest) || (defined(window.XMLHttpRequest) && 'withCredentials' in new XMLHttpRequest()); 1734 }(), 1735 1736 /** 1737 * @property {Boolean} hasChromeFrame true, if the Google ChromeFrame plugin 1738 * is install on IE 1739 */ 1740 hasChromeFrame : function() { 1741 try { 1742 if (defined(window.ActiveXObject) && !!(new ActiveXObject("ChromeTab.ChromeFrame"))) 1743 return true; 1744 } catch (ef) {} 1745 var a = navigator.userAgent.toLowerCase(); 1746 return !!(a.indexOf("chromeframe") >= 0 || a.indexOf("x-clock") >= 0); 1747 1748 }(), 1749 1750 /** 1751 * @property {Boolean} hasFlash True if the Flash Browser plugin is 1752 * installed. 1753 */ 1754 hasFlash : (function() { 1755 // Check for ActiveX first because some versions of IE support 1756 // navigator.plugins, just not the same as other browsers 1757 if (defined(window.ActiveXObject)) { 1758 try { 1759 // try to create a flash instance 1760 new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); 1761 return true; 1762 } catch (e) {}; 1763 // If the try-catch fails, return false 1764 return false; 1765 } else if (navigator.plugins) { 1766 // Loop through all the plugins 1767 for (var i = 0, P = navigator.plugins, length = P.length; i < length; ++i) { 1768 // test to see if any plugin names contain the word flash, if so it 1769 // must support it - return true 1770 if ((/flash/i).test(P[i].name)) { 1771 return true; 1772 } 1773 } 1774 // return false if no plugins match 1775 return false; 1776 } 1777 // Return false if ActiveX and nagivator.plugins are not supported 1778 return false; 1779 })(), 1780 1781 /** 1782 * @property {Boolean} hasCookies True if the browser cookies are 1783 * enabled/supported. On IE, ModalDialog windows will issue a 1784 * security risk warning to the user during this check, so assert 1785 * to false. (Cookie implementations on IE's 1786 * [Modeless|Modal]Dialogs are not supported as they run in a 1787 * seperate ActiveX browser context) 1788 */ 1789 hasCookies : Ext.isIE && ('dialogArguments' in window) ? false : !!navigator.cookieEnabled, 1790 1791 /** 1792 * @property {Boolean} hasCanvas True if the browser has canvas Element 1793 * support. 1794 */ 1795 hasCanvas : !!document.createElement("canvas").getContext, 1796 1797 /** 1798 * @property {Boolean} hasCanvasText True if the browser has canvas Element 1799 * Text support. 1800 */ 1801 hasCanvasText : function() { 1802 return !!(this.hasCanvas && typeof document.createElement('canvas').getContext('2d').fillText == 'function'); 1803 }(), 1804 1805 /** 1806 * @property {Boolean} hasSVG True if the browser has SVG support. 1807 */ 1808 hasSVG : !!(document.createElementNS && document.createElementNS('http://www.w3.org/2000/svg', 'svg').width), 1809 1810 /** 1811 * @property {Boolean} hasXpath True if the browser has Xpath query support. 1812 */ 1813 hasXpath : !!document.evaluate, 1814 1815 /** 1816 * @property {Boolean} hasWorkers True if the browser has support for 1817 * threaded Workers. 1818 */ 1819 hasWorkers : defined(window.Worker) || caps.hasGears, 1820 1821 /** 1822 * @property {Boolean} hasOffline True if the browser has offline support. 1823 */ 1824 hasOffline : defined(window.applicationCache), 1825 1826 /** 1827 * @property {Boolean} hasLocalStorage True if the browser has Local Storage 1828 * support. 1829 */ 1830 hasLocalStorage : defined(window.localStorage), 1831 1832 /** 1833 * Basic HTML5 geolocation services support test 1834 * 1835 * @property {Boolean} hasGeoLocation 1836 */ 1837 hasGeoLocation : defined(navigator.geolocation), 1838 1839 hasBasex : true, 1840 1841 /** 1842 * 1843 * @property {Boolean/Object} hasAudio 1844 * @desc Basic HTML5 Element support for the <audio> tag and/or Audio 1845 * object. 1846 * @example 1847 * If the browser has <audio> tag or Audio object support,<br /> 1848 * the property contains a mime-type map of standard audio formats. { 1849 * mp3 : false, //mp3 ogg : false, //Ogg Vorbis wav : true, //wav 1850 * basic : false, //au, snd aif : false, //aif, aifc, aiff tag : true, 1851 * //is audio HTML element supported? object : true, //is the 1852 * window.Audio Object supported <b>testMime</b> : function() } 1853 * 1854 * The included <b>testMime</b> function permits selective mime-type 1855 * testing as well for custom audio formats: if(Ext.capabilities.hasAudio && 1856 * Ext.capabilities.hasAudio.testMime('audio/ogg') ){ alert ('Vorbis 1857 * playback is supported'); } 1858 */ 1859 hasAudio : function() { 1860 1861 var aTag = !!document.createElement('audio').canPlayType, aAudio = ('Audio' in window) ? new Audio('') : {}, caps = aTag || ('canPlayType' in aAudio) ? { 1862 tag : aTag, 1863 object : ('play' in aAudio), 1864 1865 /* 1866 * Test for a specific audio mime-type 1836 1867 */ 1837 hasAudio : function(){ 1838 1839 var aTag = !!document.createElement('audio').canPlayType, 1840 aAudio = ('Audio' in window) ? new Audio('') : {}, 1841 caps = aTag || ('canPlayType' in aAudio) ? 1842 { tag : aTag, 1843 object : ('play' in aAudio), 1844 1845 /* 1846 * Test for a specific audio mime-type 1847 */ 1848 testMime : function(mime){ 1849 var M; return (M = aAudio.canPlayType ? aAudio.canPlayType(mime): 'no') !== 'no' && M !== ''; 1850 } 1851 } : false, 1852 mime, 1853 chk, 1854 mimes = { 1855 mp3 : 'audio/mpeg', //mp3 1856 ogg : 'audio/ogg', //Ogg Vorbis 1857 wav : 'audio/x-wav', //wav 1858 basic : 'audio/basic', //au, snd 1859 aif : 'audio/x-aiff' //aif, aifc, aiff 1860 }; 1861 1862 if(caps && caps.testMime){ 1863 for (chk in mimes){ 1864 caps[chk] = caps.testMime(mimes[chk]); 1865 } 1866 } 1867 return caps; 1868 }(), 1869 1870 /** 1871 * 1872 * @property {Boolean/Object} hasVideo 1873 * @desc Basic HTML5 Element support for the <video> tag. 1874 * @example 1875 If the browser has <video> tag support, the property contains a codec map of supported video formats. 1876 { 1877 mp4 : false, 1878 ogg : true, 1879 testCodec : function() 1880 } 1881 The testCodec function permits selective codec support testing: 1882 if(Ext.capabilities.hasVideo && 1883 Ext.capabilities.hasVideo.testCodec("avc1.42E01E, mp4a.40.2") ){ 1884 alert ('Apple Video decoder is supported'); 1885 } 1886 */ 1887 hasVideo : function(){ 1888 var vTag = !!document.createElement('video').canPlayType, 1889 vVideo = vTag ? document.createElement('video') : {}, 1890 caps = ('canPlayType' in vVideo) ? 1891 { tag : vTag, 1892 /* 1893 * Test for a specific video and codec (eg: 'video/ogg; codecs="theora, vorbis"' ) 1894 */ 1895 testCodec : function(codec){ 1896 var C; return (C = vVideo.canPlayType ? vVideo.canPlayType(codec): 'no') !== 'no' && C !== ''; 1897 } 1898 } : false, 1899 codec, 1900 chk, 1901 codecs = { 1902 mp4 : 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', //mp4 (Apple: patented licensed codec) 1903 ogg : 'video/ogg; codecs="theora, vorbis"' //ogg Vorbis codec 1904 }; 1905 1906 if(caps && caps.testCodec){ 1907 for (chk in codecs){ 1908 caps[chk] = caps.testCodec(codecs[chk]); 1909 } 1910 } 1911 return caps; 1912 }(), 1913 1914 /** 1915 * @desc Basic HTML5 Input Element support for autofocus. 1916 * @return {Boolean} 1917 */ 1918 hasInputAutoFocus : function(){ 1919 return ('autofocus' in (document.createElement('input'))); 1920 }(), 1921 1922 /** 1923 * @desc Basic HTML5 Input Element support for placeholder 1924 * @return {Boolean} 1925 */ 1926 hasInputPlaceHolder : function(){ 1927 return ('placeholder' in (document.createElement('input'))); 1928 }(), 1929 1930 /** 1931 * 1932 * @param {String) type The input type to test for. 1933 * @return {Boolean} 1934 * @desc Does the HTML5 enabled browser support extended input types 1935 * @example Typical input type tests: 1936 * search, number, range, color, tel, url, email, date, month, week, tine, datetime, datetime-local 1937 */ 1938 hasInputType : function(type){ 1939 var el = document.createElement("input"); 1940 if(el){ 1941 try{ el.setAttribute("type", type)}catch(e){}; 1942 return el.type !== 'text'; 1943 } 1944 return false; 1945 }, 1946 1947 /** 1948 * 1949 * @param {String} type The eventName (without the 'on' prefix) 1950 * @param {HTMLElement/Object/String} testEl (optional) A specific HTMLElement/Object to test against, otherwise a tagName to test against. 1951 * based on the passed eventName is used, or DIV as default. (window and document objects are supported) 1952 * @return {Boolean} True if the passed object supports the named event. 1953 * @desc Determines whether a specified DOMEvent is supported by a given HTMLElement or Object. 1954 * @example Does the <script> tag support the load event? 1955 Ext.capabilities.isEventSupported('load', document.createElement('script')); 1956 */ 1957 isEventSupported : function(){ 1958 var TAGNAMES = { 1959 'select':'input', 1960 'change':'input', 1961 'submit':'form', 1962 'reset':'form', 1963 'load':'img', 1964 'error':'img', 1965 'abort':'img' 1966 } 1967 //Cached results 1968 var cache = {}, 1969 onPrefix = /^on/i, 1970 //Get a tokenized string of the form nodeName:type 1971 getKey = function(type, el){ 1972 var tEl = Ext.getDom(el); 1973 return (tEl ? 1974 (Ext.isElement(tEl) || Ext.isDocument(tEl) ? 1975 tEl.nodeName.toLowerCase() : 1976 el.self ? '#window' : el || '#object') 1977 : el || 'div') + ':' + type; 1978 }; 1979 1980 return function (evName, testEl) { 1981 evName = (evName || '').replace(onPrefix,''); 1982 var el, isSupported = false; 1983 var eventName = 'on' + evName; 1984 var tag = (testEl ? testEl : TAGNAMES[evName]) || 'div'; 1985 var key = getKey(evName, tag); 1986 1987 if(key in cache){ 1988 //Use a previously cached result if available 1989 return cache[key]; 1990 } 1991 1992 el = Ext.isString(tag) ? document.createElement(tag): testEl; 1993 isSupported = (!!el && (eventName in el)); 1994 1995 isSupported || (isSupported = window.Event && !!(String(evName).toUpperCase() in window.Event)); 1996 1997 if (!isSupported && el) { 1998 el.setAttribute && el.setAttribute(eventName, 'return;'); 1999 isSupported = Ext.isFunction(el[eventName]); 2000 } 2001 //save the cached result for future tests 2002 cache[key] = isSupported; 2003 el = null; 2004 return isSupported; 2005 }; 2006 2007 }() 2008 }); 2009 Ext.EventManager.on(window, "beforeunload", A.onUnload ,A,{single:true}); 1868 testMime : function(mime) { 1869 var M; 1870 return (M = aAudio.canPlayType ? aAudio.canPlayType(mime) : 'no') !== 'no' && M !== ''; 1871 } 1872 } : false, mime, chk, mimes = { 1873 mp3 : 'audio/mpeg', // mp3 1874 ogg : 'audio/ogg', // Ogg Vorbis 1875 wav : 'audio/x-wav', // wav 1876 basic : 'audio/basic', // au, snd 1877 aif : 'audio/x-aiff' // aif, aifc, aiff 1878 }; 1879 1880 if (caps && caps.testMime) { 1881 for (chk in mimes) { 1882 caps[chk] = caps.testMime(mimes[chk]); 1883 } 1884 } 1885 return caps; 1886 }(), 1887 1888 /** 1889 * 1890 * @property {Boolean/Object} hasVideo 1891 * @desc Basic HTML5 Element support for the <video> tag. 1892 * @example 1893 * If the browser has <video> tag support, the property contains a codec map of supported video formats. 1894 { 1895 mp4 : false, 1896 ogg : true, 1897 testCodec : function() 1898 } 1899 The testCodec function permits selective codec support testing: 1900 if(Ext.capabilities.hasVideo && 1901 Ext.capabilities.hasVideo.testCodec("avc1.42E01E, mp4a.40.2") ){ 1902 alert ('Apple Video decoder is supported'); 1903 } 1904 */ 1905 hasVideo : function() { 1906 var vTag = !!document.createElement('video').canPlayType, vVideo = vTag ? document.createElement('video') : {}, caps = ('canPlayType' in vVideo) ? { 1907 tag : vTag, 1908 /* 1909 * Test for a specific video and codec (eg: 'video/ogg; codecs="theora, 1910 * vorbis"' ) 1911 */ 1912 testCodec : function(codec) { 1913 var C; 1914 return (C = vVideo.canPlayType ? vVideo.canPlayType(codec) : 'no') !== 'no' && C !== ''; 1915 } 1916 } : false, codec, chk, codecs = { 1917 mp4 : 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', // mp4 (Apple: 1918 // patented licensed 1919 // codec) 1920 ogg : 'video/ogg; codecs="theora, vorbis"' // ogg Vorbis codec 1921 }; 1922 1923 if (caps && caps.testCodec) { 1924 for (chk in codecs) { 1925 caps[chk] = caps.testCodec(codecs[chk]); 1926 } 1927 } 1928 return caps; 1929 }(), 1930 1931 /** 1932 * @desc Basic HTML5 Input Element support for autofocus. 1933 * @return {Boolean} 1934 */ 1935 hasInputAutoFocus : function() { 1936 return ('autofocus' in (document.createElement('input'))); 1937 }(), 1938 1939 /** 1940 * @desc Basic HTML5 Input Element support for placeholder 1941 * @return {Boolean} 1942 */ 1943 hasInputPlaceHolder : function() { 1944 return ('placeholder' in (document.createElement('input'))); 1945 }(), 1946 1947 /** 1948 * 1949 * @param {String) 1950 * type The input type to test for. 1951 * @return {Boolean} 1952 * @desc Does the HTML5 enabled browser support extended input types 1953 * @example 1954 * Typical input type tests: 1955 * search, number, range, color, tel, url, email, date, month, week, tine, datetime, datetime-local 1956 */ 1957 hasInputType : function(type) { 1958 var el = document.createElement("input"); 1959 if (el) { 1960 try { 1961 el.setAttribute("type", type) 1962 } catch (e) {}; 1963 return el.type !== 'text'; 1964 } 1965 return false; 1966 }, 1967 1968 /** 1969 * 1970 * @param {String} 1971 * type The eventName (without the 'on' prefix) 1972 * @param {HTMLElement/Object/String} 1973 * testEl (optional) A specific HTMLElement/Object to test against, 1974 * otherwise a tagName to test against. based on the passed 1975 * eventName is used, or DIV as default. (window and document 1976 * objects are supported) 1977 * @return {Boolean} True if the passed object supports the named event. 1978 * @desc Determines whether a specified DOMEvent is supported by a given 1979 * HTMLElement or Object. 1980 * @example 1981 * Does the <script> tag support the load event? 1982 Ext.capabilities.isEventSupported('load', document.createElement('script')); 1983 */ 1984 isEventSupported : function() { 1985 var TAGNAMES = { 1986 'select' : 'input', 1987 'change' : 'input', 1988 'submit' : 'form', 1989 'reset' : 'form', 1990 'load' : 'img', 1991 'error' : 'img', 1992 'abort' : 'img' 1993 } 1994 // Cached results 1995 var cache = {}, onPrefix = /^on/i, 1996 // Get a tokenized string of the form nodeName:type 1997 getKey = function(type, el) { 1998 var tEl = Ext.getDom(el); 1999 return (tEl ? (Ext.isElement(tEl) || Ext.isDocument(tEl) ? tEl.nodeName.toLowerCase() : el.self ? '#window' : el || '#object') : el || 'div') + ':' + type; 2000 }; 2001 2002 return function(evName, testEl) { 2003 evName = (evName || '').replace(onPrefix, ''); 2004 var el, isSupported = false; 2005 var eventName = 'on' + evName; 2006 var tag = (testEl ? testEl : TAGNAMES[evName]) || 'div'; 2007 var key = getKey(evName, tag); 2008 2009 if (key in cache) { 2010 // Use a previously cached result if available 2011 return cache[key]; 2012 } 2013 2014 el = Ext.isString(tag) ? document.createElement(tag) : testEl; 2015 isSupported = (!!el && (eventName in el)); 2016 2017 isSupported || (isSupported = window.Event && !!(String(evName).toUpperCase() in window.Event)); 2018 2019 if (!isSupported && el) { 2020 el.setAttribute && el.setAttribute(eventName, 'return;'); 2021 isSupported = Ext.isFunction(el[eventName]); 2022 } 2023 // save the cached result for future tests 2024 cache[key] = isSupported; 2025 el = null; 2026 return isSupported; 2027 }; 2028 2029 }() 2030 }); 2031 Ext.EventManager.on(window, "beforeunload", A.onUnload, A, { 2032 single : true 2033 }); 2010 2034 })(); 2011 2035 2012 // enumerate custom class properties (not prototypes unless protos==true) 2013 // usually only called by the global forEach function 2014 Ext.applyIf(Function.prototype, { 2015 forEach : function( object, block, context, protos) { 2016 if(object){ 2017 var key; 2018 for (key in object) { 2019 (!!protos || object.hasOwnProperty(key)) && 2020 block.call(context||object, object[key], key, object); 2021 } 2022 } 2023 }, 2024 2025 // Credit: @Animal -- the_bagbournes@btinternet.com 2026 createBuffered: function(buffer, scope){ 2027 var method = this, task = new Ext.util.DelayedTask(); 2028 return function(){ 2029 task.delay(buffer, method, scope, Array.slice(arguments,0)); 2030 }; 2031 }, 2032 2033 /** 2034 * Credit: @Animal -- the_bagbournes@btinternet.com 2035 * Creates a delegate (callback) which, when called, executes after a specific delay. 2036 * Optionally, a replacement (or additional) argument list may be specified. 2037 * @param {Number} delay The number of milliseconds to defer execution by whenever called. 2038 * @param {Object} scope (optional) The scope (<code>this</code> reference) used by the function at execution time. 2039 * @param {Array} args (optional) Override arguments for the call. (Defaults to the arguments passed by the caller) 2040 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, 2041 * if a number the args are inserted at the specified position. 2042 * @return {Function} A function which, when called, executes the original function after the specified delay. 2043 */ 2044 createDelayed: function(delay, scope, args, appendArgs){ 2045 var method = (scope || args) ? this.createDelegate(scope, args, appendArgs) : this; 2046 return delay ? function() { 2047 setTimeout(method, delay); 2048 } : method; 2049 }, 2050 2051 2052 clone : function(deep){ return this;} 2053 }); 2036 // enumerate custom class properties (not prototypes unless protos==true) 2037 // usually only called by the global forEach function 2038 Ext.applyIf(Function.prototype, { 2039 forEach : function(object, block, context, protos) { 2040 if (object) { 2041 var key; 2042 for (key in object) { 2043 (!!protos || object.hasOwnProperty(key)) && block.call(context || object, object[key], key, object); 2044 } 2045 } 2046 }, 2047 2048 // Credit: @Animal -- the_bagbournes@btinternet.com 2049 createBuffered : function(buffer, scope) { 2050 var method = this, task = new Ext.util.DelayedTask(); 2051 return function() { 2052 task.delay(buffer, method, scope, Array.slice(arguments, 0)); 2053 }; 2054 }, 2055 2056 /** 2057 * Credit: 2058 * 2059 * @Animal -- the_bagbournes@btinternet.com Creates a delegate (callback) 2060 * which, when called, executes after a specific delay. Optionally, a 2061 * replacement (or additional) argument list may be specified. 2062 * @param {Number} 2063 * delay The number of milliseconds to defer execution by whenever 2064 * called. 2065 * @param {Object} 2066 * scope (optional) The scope (<code>this</code> reference) used 2067 * by the function at execution time. 2068 * @param {Array} 2069 * args (optional) Override arguments for the call. (Defaults to the 2070 * arguments passed by the caller) 2071 * @param {Boolean/Number} 2072 * appendArgs (optional) if True args are appended to call args 2073 * instead of overriding, if a number the args are inserted at the 2074 * specified position. 2075 * @return {Function} A function which, when called, executes the original 2076 * function after the specified delay. 2077 */ 2078 createDelayed : function(delay, scope, args, appendArgs) { 2079 var method = (scope || args) ? this.createDelegate(scope, args, appendArgs) : this; 2080 return delay ? function() { 2081 setTimeout(method, delay); 2082 } : method; 2083 }, 2084 2085 clone : function(deep) { 2086 return this; 2087 } 2088 }); plugins/ExtjsGeneratorPlugin/trunk/web/js/jit.js
r29426 r29937 1 /* global Ext */ 2 3 /** 4 jit.js 1.4.1 5 ************************************************************************************ 6 7 $JIT [Dynamic Resource loader (basex 3.1+ support required)] 8 9 ************************************************************************************ 10 * Author: Doug Hendricks. doug[always-At]theactivegroup.com 11 * Copyright 2007-2008, Active Group, Inc. All rights reserved. 12 ************************************************************************************ 13 14 License: ext-basex and $JIT are licensed under the terms of : GNU Open Source GPL 3.0 license: 15 16 Commercial use is prohibited without contacting licensing[at]theactivegroup.com. 17 18 This program is free software: you can redistribute it and/or modify 19 it under the terms of the GNU General Public License as published by 20 the Free Software Foundation, either version 3 of the License, or 21 any later version. 22 23 This program is distributed in the hope that it will be useful, 24 but WITHOUT ANY WARRANTY; without even the implied warranty of 25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 GNU General Public License for more details. 27 28 You should have received a copy of the GNU General Public License 29 along with this program. If not, see < http://www.gnu.org/licenses/gpl.html>. 30 31 Donations are welcomed: http://donate.theactivegroup.com 32 33 */ 34 35 36 if(typeof Ext == undefined || !Ext.hasBasex) 37 {throw "Ext and ext-basex 3.1 or higher required.";} 38 39 (function(){ 40 41 /** 42 * private -- <script and link> tag support 43 */ 44 var A = Ext.lib.Ajax, 45 StopIter = "StopIteration", 46 defined = function(test){return typeof test !== 'undefined';}, 47 emptyFn = function(){}; 48 49 50 /** 51 * @class Ext.ux.ModuleManager 52 * @version 1.3 53 * *********************************************************************************** 54 * @author Doug Hendricks. doug[always-At]theactivegroup.com 55 * @copyright 2007-2008, Active Group, Inc. All rights reserved. 56 * *********************************************************************************** 57 * @donate <a target="tag_donate" href="http://donate.theactivegroup.com"><img border="0" src="http://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" border="0" alt="Make a donation to support ongoing development"></a> 58 * @license <a href="http://www.gnu.org/licenses/gpl.html">GPL 3.0</a> 59 * 60 * Commercial Use is prohibited without contacting 61 * licensing[at]theactivegroup.com. 62 * 63 * This program is free software: you can redistribute it and/or modify 64 * it under the terms of the GNU General Public License as published by 65 * the Free Software Foundation, either version 3 of the License, or any 66 * later version. 67 * 68 * This program is distributed in the hope that it will be useful, but 69 * WITHOUT ANY WARRANTY; without even the implied warranty of 70 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 71 * General Public License for more details. 72 * 73 * You should have received a copy of the GNU General Public License 74 * along with this program. If not, see < 75 * http://www.gnu.org/licenses/gpl.html>. 76 * 77 * Donations are welcomed: http://donate.theactivegroup.com 78 * 79 * @constructor - creates a new instance of ux.ModuleManager 80 * @methodOf Ext.ux.ModuleManager @param {Object} config 81 * @example 82 * Sample Usage: 83 * 84 * YourApp.CodeLoader = new 85 * Ext.ux.ModuleManager({modulePath:yourBasePath }); 86 * YourApp.CodeLoader.on({ 'beforeload':function(manager, module, 87 * response){ 88 * 89 * //return false to prevent the script from being executed. return 90 * module.extension == 'js'; 91 * } ,scope:YourApp.CodeLoader }); 92 * 93 * //Create a useful 'syntax' for your App. 94 * 95 * YourApp.needs = 96 * YourApp.CodeLoader.load.createDelegate(YourApp.CodeLoader); 97 * YourApp.provide = 98 * YourApp.CodeLoader.provides.createDelegate(YourApp.CodeLoader); 99 * 100 * YourApp.needs('ext/layouts','js/dragdrop','js/customgrid','style/custom.css'); 101 * 102 * 103 * Configuration options 104 */ 105 Ext.namespace('Ext.ux'); 106 Ext.ux.ModuleManager = function(config) { 107 108 Ext.apply(this, config || {}, { 109 modulePath : function() { // based on current page 110 var d = location.href.indexOf('\/') != -1 111 ? '\/' 112 : '\\'; 113 var u = location.href.split(d); 114 u.pop(); // this page 115 return u.join(d) + d; 116 }() 117 }); 118 119 this.addEvents({ 120 /** 121 * @event loadexception Fires when any exception is raised. 122 * Returning false prevents any subsequent pending module load requests 123 * @param {Ext.ux.ModuleManager} this 124 * @param {String} module -- the module object 125 * @param {Object} error -- An error object containing: 126 * httpStatus, httpStatusText, error object 127 */ 128 "loadexception" : true, 129 130 /** 131 * @event alreadyloaded Fires when the ModuleManager 132 * determines that the requested module has 133 * already been loaded 134 * @param {Ext.ux.ModuleManager} 135 * this 136 * @param {String} 137 * module -- the module object 138 */ 139 "alreadyloaded" : true, 140 141 /** 142 * @event load Fires when the retrieved content has been 143 * successfully loaded 144 * @param {Ext.ux.ModuleManager} 145 * this 146 * @param {String} 147 * module -- the module name 148 * @param {Object} 149 * response -- the Ajax response object 150 * @param {String} 151 * contents -- the raw text content retrieved 152 * @param {Boolean} 153 * executed -- true if the resource was 154 * executed into the target context. 155 */ 156 "load" : true, 157 158 /** 159 * @event beforeload Fires when the request has 160 * successfully completed and just prior to eval 161 * returning false prevents the content (of this 162 * module) from being loaded (eval'ed) 163 * @param {Ext.ux.ModuleManager} 164 * this 165 * @param {String} 166 * module -- the module name 167 * @param {Object} 168 * response - the Ajax response object 169 * @param {String} 170 * contents -- the raw text content retrieved 171 */ 172 "beforeload" : true, 173 174 /** 175 * @event complete Fires when all module load request 176 * have completed (successfully or not) 177 * @param {Ext.ux.ModuleManager} 178 * this 179 * @param {Boolen} 180 * success 181 * @param {Array} 182 * loaded -- the modules now available as a 183 * result of (or previously -- already 184 * loaded) the last load operation. 185 * @param {Array} 186 * executed -- modules that were executed 187 * (evaled) as a result of (or previously 188 * executed) the last load operation. 189 */ 190 "complete" : true, 191 192 /** 193 * @event timeout Fires when module {@link #load} or 194 * {@link #onAvailable} requests have timed out. 195 * @param {Ext.ux.ModuleManager} this 196 * @param {Object/String} module module descriptor object or module name of the last pending module 197 */ 198 "timeout" : true 1 /* global Ext */ 2 3 /** 4 * jit.js 1.4.1 5 * *********************************************************************************** 6 * 7 * $JIT [Dynamic Resource loader (basex 3.1+ support required)] 8 * 9 * *********************************************************************************** 10 * Author: Doug Hendricks. doug[always-At]theactivegroup.com Copyright 11 * 2007-2008, Active Group, Inc. All rights reserved. 12 * *********************************************************************************** 13 * 14 * License: ext-basex and $JIT are licensed under the terms of : GNU Open Source 15 * GPL 3.0 license: 16 * 17 * Commercial use is prohibited without contacting 18 * licensing[at]theactivegroup.com. 19 * 20 * This program is free software: you can redistribute it and/or modify it under 21 * the terms of the GNU General Public License as published by the Free Software 22 * Foundation, either version 3 of the License, or any later version. 23 * 24 * This program is distributed in the hope that it will be useful, but WITHOUT 25 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 26 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 27 * details. 28 * 29 * You should have received a copy of the GNU General Public License along with 30 * this program. If not, see < http://www.gnu.org/licenses/gpl.html>. 31 * 32 * Donations are welcomed: http://donate.theactivegroup.com 33 * 34 */ 35 36 if (typeof Ext == undefined || !Ext.hasBasex) { 37 throw "Ext and ext-basex 3.1 or higher required."; 38 } 39 40 (function() { 41 42 /** 43 * private -- <script and link> tag support 44 */ 45 var A = Ext.lib.Ajax, StopIter = "StopIteration", defined = function(test) { 46 return typeof test !== 'undefined'; 47 }, emptyFn = function() {}; 48 49 /** 50 * @class Ext.ux.ModuleManager 51 * @version 1.3 52 * *********************************************************************************** 53 * @author Doug Hendricks. doug[always-At]theactivegroup.com 54 * @copyright 2007-2008, Active Group, Inc. All rights reserved. 55 * *********************************************************************************** 56 * @donate <a target="tag_donate" href="http://donate.theactivegroup.com"><img 57 * border="0" 58 * src="http://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" 59 * border="0" alt="Make a donation to support ongoing development"></a> 60 * @license <a href="http://www.gnu.org/licenses/gpl.html">GPL 3.0</a> 61 * 62 * Commercial Use is prohibited without contacting 63 * licensing[at]theactivegroup.com. 64 * 65 * This program is free software: you can redistribute it and/or modify it 66 * under the terms of the GNU General Public License as published by the Free 67 * Software Foundation, either version 3 of the License, or any later version. 68 * 69 * This program is distributed in the hope that it will be useful, but WITHOUT 70 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 71 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 72 * more details. 73 * 74 * You should have received a copy of the GNU General Public License along 75 * with this program. If not, see < http://www.gnu.org/licenses/gpl.html>. 76 * 77 * Donations are welcomed: http://donate.theactivegroup.com 78 * 79 * @constructor - creates a new instance of ux.ModuleManager 80 * @methodOf Ext.ux.ModuleManager 81 * @param {Object} 82 * config 83 * @example 84 * Sample Usage: 85 * 86 * YourApp.CodeLoader = new 87 * Ext.ux.ModuleManager({modulePath:yourBasePath }); 88 * YourApp.CodeLoader.on({ 'beforeload':function(manager, module, 89 * response){ 90 * 91 * //return false to prevent the script from being executed. return 92 * module.extension == 'js'; 93 * } ,scope:YourApp.CodeLoader }); 94 * 95 * //Create a useful 'syntax' for your App. 96 * 97 * YourApp.needs = 98 * YourApp.CodeLoader.load.createDelegate(YourApp.CodeLoader); 99 * YourApp.provide = 100 * YourApp.CodeLoader.provides.createDelegate(YourApp.CodeLoader); 101 * 102 * YourApp.needs('ext/layouts','js/dragdrop','js/customgrid','style/custom.css'); 103 * 104 * 105 * Configuration options 106 */ 107 Ext.namespace('Ext.ux'); 108 Ext.ux.ModuleManager = function(config) { 109 110 Ext.apply(this, config || {}, { 111 modulePath : function() { // based on current page 112 var d = location.href.indexOf('\/') != -1 ? '\/' : '\\'; 113 var u = location.href.split(d); 114 u.pop(); // this page 115 return u.join(d) + d; 116 }() 117 }); 118 119 this.addEvents({ 120 /** 121 * @event loadexception Fires when any exception is raised. Returning 122 * false prevents any subsequent pending module load requests 123 * @param {Ext.ux.ModuleManager} 124 * this 125 * @param {String} 126 * module -- the module object 127 * @param {Object} 128 * error -- An error object containing: httpStatus, 129 * httpStatusText, error object 130 */ 131 "loadexception" : true, 132 133 /** 134 * @event alreadyloaded Fires when the ModuleManager determines that the 135 * requested module has already been loaded 136 * @param {Ext.ux.ModuleManager} 137 * this 138 * @param {String} 139 * module -- the module object 140 */ 141 "alreadyloaded" : true, 142 143 /** 144 * @event load Fires when the retrieved content has been successfully 145 * loaded 146 * @param {Ext.ux.ModuleManager} 147 * this 148 * @param {String} 149 * module -- the module name 150 * @param {Object} 151 * response -- the Ajax response object 152 * @param {String} 153 * contents -- the raw text content retrieved 154 * @param {Boolean} 155 * executed -- true if the resource was executed into the target 156 * context. 157 */ 158 "load" : true, 159 160 /** 161 * @event beforeload Fires when the request has successfully completed and 162 * just prior to eval returning false prevents the content (of this 163 * module) from being loaded (eval'ed) 164 * @param {Ext.ux.ModuleManager} 165 * this 166 * @param {String} 167 * module -- the module name 168 * @param {Object} 169 * response - the Ajax response object 170 * @param {String} 171 * contents -- the raw text content retrieved 172 */ 173 "beforeload" : true, 174 175 /** 176 * @event complete Fires when all module load request have completed 177 * (successfully or not) 178 * @param {Ext.ux.ModuleManager} 179 * this 180 * @param {Boolen} 181 * success 182 * @param {Array} 183 * loaded -- the modules now available as a result of (or 184 * previously -- already loaded) the last load operation. 185 * @param {Array} 186 * executed -- modules that were executed (evaled) as a result of 187 * (or previously executed) the last load operation. 188 */ 189 "complete" : true, 190 191 /** 192 * @event timeout Fires when module {@link #load} or {@link #onAvailable} 193 * requests have timed out. 194 * @param {Ext.ux.ModuleManager} 195 * this 196 * @param {Object/String} 197 * module module descriptor object or module name of the last 198 * pending module 199 */ 200 "timeout" : true 201 }); 202 Ext.ux.ModuleManager.superclass.constructor.call(this); 203 204 }; 205 206 /** @private */ 207 var gather = function(method, url, callbacks, data, options) { 208 209 var tag, attribs; 210 callbacks || (callbacks = {}); 211 212 if (method == 'SCRIPT') { 213 tag = method; 214 attribs = { 215 type : "text/javascript", 216 src : url 217 }; 218 219 } else if (method == 'LINK') { 220 tag = method; 221 attribs = { 222 rel : "stylesheet", 223 type : "text/css", 224 href : url 225 }; 226 } 227 return tag ? A.monitoredNode(tag, attribs, callbacks, options.target || window) : A.request.apply(A, arguments); 228 }; 229 230 // normalize a resource to name-component hash 231 /** @private */ 232 var modulate = function(moduleName, options) { 233 if (!moduleName) 234 return null; 235 options || (options = {}); 236 var mname = String(moduleName.name || moduleName), name = mname.trim().split('\/').last(), fname = options ? (name.indexOf('.') !== -1 ? mname : mname + '.js') : '', path = options.path || ''; 237 238 var mod = Ext.apply({ 239 name : name, 240 fullName : moduleName.name ? moduleName.name : fname, 241 extension : !moduleName.name ? fname.split('.').last().trim().toLowerCase() : '', 242 path : path 243 }, options); 244 245 mod.url = options.url || (path + fname); 246 return mod; 247 }; 248 249 Ext.extend(Ext.ux.ModuleManager, Ext.util.Observable, { 250 /** 251 * @cfg {Boolean} disableCaching True to ensure the the browser's cache is 252 * bypassed when retrieving resources. 253 */ 254 disableCaching : false, 255 256 /** @private */ 257 258 modules : {}, 259 260 /** 261 * @cfg {String} method The default request method used to retrieve 262 * resources. This method may also changed in-line during a 263 * {@link #load) operation. Supported methods: 264 * <ul> 265 * <li>DOM - Retrieve the resource by <SCRIPT/LINK> tag insertion</li> 266 * <li>GET Retrieve the resource by Ajax Request</li> 267 * <li>POST</li> 268 * <li>PUT</li> 269 * </ul> 270 */ 271 272 method : 'GET', 273 274 /** 275 * @cfg {Boolean} noExecute Permits retrieval of a resource without script 276 * execution of the results. This option may also be changed in-line 277 * during a {@link #load) operation. 278 */ 279 280 noExecute : false, 281 /** 282 * @cfg {Boolean} asynchronous Sets the default behaviour for AJAX requests 283 * onlu This option may also be changed in-line (async: true) during a 284 * {@link #load) operation. 285 */ 286 287 asynchronous : true, 288 289 /** 290 * @cfg {Boolean} cacheResponses True, saves any content received in a 291 * content object with the following structure: 292 * 293 * This option may also be changed in-line during a {@link #load) operation. 294 */ 295 296 cacheResponses : false, 297 298 /** 299 * @cfg {Integer} default onAvailable/load method timeout value in 300 * milliseconds 301 */ 302 303 timeout : 30000, 304 305 /** 306 * @cfg {Boolean} True retains the resulting content within each module 307 * object for debugging. 308 */ 309 310 debug : false, 311 312 /** @private */ 313 loadStack : new Array(), 314 315 loaded : function(name) { 316 var module; 317 return (module = this.getModule(name)) ? module.loaded === true : false; 318 }, 319 320 getModule : function(name) { 321 name && (name = name.name ? name.name : modulate(name, false).name); 322 return name ? this.modules[name] : null; 323 }, 324 /* 325 * A mechanism for modules to identify their presence when loaded via 326 * conventional <script> tags @param {String} module names(s) Usage: <pre><code>Ext.Loader.provides('moduleA', 327 * 'moduleB');</code></pre> 328 */ 329 330 createModule : function(name, extras) { 331 var mod, existing; 332 mod = (existing = this.getModule(name)) || modulate(name, extras); 333 334 return existing || (this.modules[mod.name] = Ext.apply({ 335 executed : false, 336 contentType : '', 337 content : null, 338 loaded : false, 339 pending : false 340 }, mod)); 341 342 if (!mod) { 343 var m = modulate(name, extras); 344 mod = this.modules[m.name] = Ext.apply({ 345 executed : false, 346 contentType : '', 347 content : null, 348 loaded : false, 349 pending : false 350 }, m); 351 } 352 353 return mod; 354 }, 355 356 /** 357 * Assert loaded status of module name arguments and invoke callback(s) when 358 * all are available 359 * 360 * @param {Array/String} 361 * modules A list of module names to monitor 362 * @param {Function} 363 * callback The callback function called when all named resources 364 * are available or timeout 365 * @param (Object) 366 * scope The execution scope of the callback 367 * @param {integer} 368 * timeout The timeout value in milliseconds. 369 */ 370 371 onAvailable : function(modules, callbackFn, scope, timeout, options) { 372 373 if (arguments.length < 2) { 374 return false; 375 } 376 377 var MM = this, block = { 378 379 modules : new Array().concat(modules), 380 poll : function() { 381 382 var depends = (window.$JIT ? $JIT.depends : null) || {}; 383 var assert = this.polling ? this.modules.every(function(arg, index, args) { 384 385 var modName = arg.replace('@', ''), virtual = false, test = true; 386 if (depends[modName] && ((virtual = depends[modName].virtual || false) || (Ext.isArray(depends[modName].depends && !!depends[modName].length)))) { 387 test = depends[modName].depends.every(arguments.callee); 388 test = virtual ? test && ((MM.getModule(modName) || {}).loaded = true) : test; 389 } 390 391 test = test && (virtual || MM.loaded(modName) === true); 392 block.pendingModule = test ? null : MM.getModule(modName); 393 return test; 394 }) : false; 395 396 if (!assert && this.polling && !this.aborted) { 397 this.poll.defer(50, this); 398 return; 399 } 400 401 this.stop(); 402 Ext.isFunction(callbackFn) && callbackFn.call(scope, assert, this.timedOut, this.pendingModule); 403 404 }, 405 406 polling : false, 407 408 abort : function() { 409 this.aborted = true; 410 this.stop(); 411 }, 412 413 stop : function() { 414 this.polling = false; 415 this.timer && clearTimeout(this.timer); 416 this.timer = null; 417 }, 418 419 timer : null, 420 421 timeout : parseInt(timeout || MM.timeout, 10) || 10000, 422 423 onTimeout : function() { 424 this.timedOut = true; 425 this.abort(); 426 }, 427 428 retry : function(timeout) { 429 430 this.stop(); 431 this.polling = true; 432 this.aborted = this.timedOut = false; 433 this.timer = this.onTimeout.defer(timeout || this.timeout, this); 434 this.poll(); 435 return this; 436 } 437 }; 438 return block.retry(); 439 }, 440 441 /** 442 * A mechanism for modules to identify their presence when loaded via 443 * conventional <script> tags or nested on other scripts. 444 * 445 * @param {String} 446 * module names(s) Usage: 447 * 448 * <pre><code> 449 * Ext.Loader.provides('moduleA', 'moduleB'); 450 * </code></pre> 451 */ 452 453 provides : function() { 454 forEach(arguments, function(module) { 455 456 var moduleObj = this.createModule(module, false); 457 moduleObj.loaded || // already loaded ? 458 Ext.apply(moduleObj, { 459 executed : moduleObj.extension === 'js', 460 contentType : '', 461 content : null, 462 loaded : true, 463 pending : false 464 }); 465 }, this); 466 467 }, 468 /** 469 * load external resources in dependency order alternate load syntax: 470 * 471 * <pre><code> 472 * load( 'moduleA', 'path/moduleB' ); 473 * load( {module:['modA','path/modB'], callback:cbFn, method:'DOM', queue:'fast', ... }); 474 * load( {async:false, listeners: {complete: onCompleteFn, loadexception: loadExFn }}, 'moduleA', inlineFn, {async:true}, 'moduleB', inlineFn, .... ); 475 * 476 * 477 * </code></pre> 478 * 479 * @name load 480 * @methodOf Ext.ux.ModuleManager 481 * @param {Mixed} 482 * args One or more module definitions, inline functions to be 483 * execute in sequential order 484 */ 485 486 load : function(modList) { 487 488 try { 489 var task = new Task(this, Ext.isArray(modList) ? modList : Array.slice(arguments, 0)); 490 task.start(); 491 492 } catch (ex) { 493 494 if (ex != StopIter) { 495 496 if (task) { 497 task.lastError = ex; 498 task.active = false; 499 } 500 501 this.fireEvent('loadexception', this, task ? task.currentModule : null, this.lastError = ex); 502 } 503 } 504 505 return task; 506 }, 507 508 globalEval : function(data, scope, context) { 509 scope || (scope = window); 510 data = String(data || "").trim(); 511 if (data.length === 0) { 512 return false; 513 } 514 try { 515 if (scope.execScript) { 516 // window.execScript in IE fails when scripts include 517 // HTML comment tag. 518 scope.execScript(data.replace(/^<!--/, "").replace(/-->$/, "")); 519 520 } else { 521 // context (target namespace) is only support on Gecko. 522 eval.call(scope, data, context || null); 523 } 524 return true; 525 } catch (ex) { 526 return ex; 527 } 528 529 }, 530 styleAdjust : null, 531 532 applyStyle : function(module, styleRules, target) { 533 var rules; 534 if (module = this.getModule(module)) { 535 // All css is injected into document's head section 536 var doc = (target || window).document; 537 var ct = (styleRules || (module.content ? module.content.text : '') || '') + ''; 538 var head; 539 if (doc && !!ct.length && (head = doc.getElementsByTagName("head")[0])) { 540 541 if (module.element) { 542 this.removeModuleElement(module); 543 } 544 if (this.styleAdjust && this.styleAdjust.pattern) { 545 // adjust CSS (eg. urls (images etc)) 546 ct = ct.replace(this.styleAdjust.pattern, this.styleAdjust.replacement || ''); 547 } 548 549 rules = doc.createElement("style"); 550 module.element = Ext.get(rules); 551 A._domRefs.push(module.element); 552 rules.setAttribute("type", "text/css"); 553 if (Ext.isIE) { 554 head.appendChild(rules); 555 rules.styleSheet.cssText = ct; 556 } else { 557 try { 558 rules.appendChild(doc.createTextNode(ct)); 559 } catch (e) { 560 rules.cssText = ct; 561 } 562 head.appendChild(rules); 563 } 564 } 565 } 566 return rules; // the style element created 567 }, 568 569 /** 570 * Remove a style element 571 * 572 * @name removeStyle 573 * @param {Mixed} 574 * module A Ext.ux.ModuleManager.module or dom Node 575 * @return {Ext.Element} the element removed. 576 */ 577 578 removeStyle : function(module) { 579 return this.removeModuleElement(module); 580 }, 581 582 /** @private */ 583 // Remove an associated module.element from the DOM 584 removeModuleElement : function(module) { 585 var el; 586 if (module = this.getModule(module)) { 587 if (el = module.element) { 588 el.dom ? el.removeAllListeners().remove(true) : Ext.removeNode(el); 589 } 590 module.element = el = null; 591 } 592 593 }, 594 destroy : function() { 595 forEach(this.modules, function(module, name) { 596 this.removeModuleElement(name); 597 delete this.modules[name]; 598 }, this); 599 } 600 }); 601 602 var Task = Ext.ux.ModuleManager.Task = function(MM, modules) { 603 604 Ext.apply(this, { 605 result : true, 606 active : false, 607 options : null, 608 executed : new Array(), 609 loaded : new Array(), 610 params : null, 611 data : null, 612 oav : null, 613 timedOut : false, 614 unlisteners : new Array(), 615 MM : MM, 616 id : Ext.id(null, 'mm-task-'), 617 defOptions : { 618 async : MM.asynchronous, 619 headers : MM.headers || false, 620 modulePath : MM.modulePath, 621 forced : false, 622 cacheResponses : MM.cacheResponses, 623 method : (MM.noExecute || MM.cacheResponses ? 'GET' : MM.method || 'GET').toUpperCase(), 624 noExecute : MM.noExecute || false, 625 disableCaching : MM.disableCaching, 626 timeout : MM.timeout, 627 callback : null, 628 scope : null, 629 params : null 630 } 631 }); 632 633 this.prepare(modules); 634 635 }; 636 637 Ext.apply(Task.prototype, { 638 /** 639 * @private 640 * 641 */ 642 643 start : function() { 644 this.active = true; 645 this.nextModule(); 646 if (this.options.async) { 647 this.oav = this.MM.onAvailable.call(this.MM, this.onAvailableList, this.onComplete, this, this.options.timeout, this.options); 648 } else { 649 this.onComplete(this.result); 650 } 651 652 }, 653 654 /** 655 * @private 656 * 657 */ 658 doCallBacks : function(options, success, currModule, args) { 659 var cb, C; 660 661 if (C = currModule) { 662 var res = this.timedOut || this.MM.fireEvent.apply(this.MM, [ 663 (success ? 'load' : 'loadexception'), this.MM, C 664 ].concat(args || [])); 665 666 success || (this.active = (!this.timedOut && res !== false)); 667 668 // Notify other pending async listeners 669 if (this.active && Ext.isArray(C.notify)) { 670 forEach(C.notify, function(chain, index, chains) { 671 if (chain) { 672 chain.nextModule(); 673 chains[index] = null; 674 } 675 }); 676 C.notify = []; 677 } 678 679 // script Tag cleanup 680 if (C.element && !options.debug && C.extension == "js" && options.method == 'DOM') { 681 682 C.element.removeAllListeners(); 683 var d = C.element.dom; 684 if (Ext.isIE) { 685 // Script Tags are re-usable in IE 686 A.SCRIPTTAG_POOL.push(C.element); 687 } else { 688 689 C.element.remove(); 690 // Other Browsers will not GBG-collect these tags, so help them 691 // along 692 if (d) { 693 for (var prop in d) { 694 delete d[prop]; 695 } 696 } 697 } 698 d = null; 699 delete C.element; 700 } 701 702 } 703 }, 704 705 /** 706 * @private 707 * 708 */ 709 success : function(response, ev, target) { 710 711 var module = response.argument.module.module, opt = response.argument.module, executable = (!opt.proxied && module.extension == "js" && !opt.noExecute && opt.method !== 'DOM'), cbArgs = null, MM = this.MM; 712 713 module = MM.getModule(module.name); 714 this.currentModule = module.name; 715 716 if (!module.loaded) { 717 try { 718 719 if (MM.fireEvent('beforeload', MM, module, response, response.responseText) !== false) { 720 721 Ext.apply(module, { 722 loaded : true, 723 pending : false, 724 contentType : response.contentType || (target && Ext.fly(target) ? Ext.fly(target).getAttributeNS(null, 'type') : ''), 725 content : opt.cacheResponses || module.extension == "css" ? { 726 text : response.responseText || null, 727 XML : response.responseXML || null, 728 JSON : response.responseJSON || null, 729 parts : response.parts 730 731 } : null 732 }); 733 734 this.loaded.push(module); 735 var exception = executable && (!module.executed || opt.forced) ? MM.globalEval(response.responseText, opt.target) : true; 736 if (exception === true) { 737 if (executable) { 738 module.executed = true; 739 this.executed.push(module); 740 } 741 cbArgs = [ 742 response, response.responseText, module.executed 743 ]; 744 } else { 745 // coerce to actual module URL 746 throw Ext.applyIf({ 747 fileName : module.url, 748 lineNumber : exception.lineNumber || 0 749 }, exception); 750 } 751 } 752 753 } catch (exl) { 754 cbArgs = [ 755 { 756 error : (this.lastError = exl), 757 httpStatus : response.status, 758 httpStatusText : response.statusText 759 } 760 ]; 761 762 this.result = false; 763 } 764 765 this.doCallBacks(opt, this.result, module, cbArgs); 766 } else { 767 opt.async && this.nextModule(); 768 } 769 770 }, 771 772 /** 773 * @private 774 * 775 */ 776 777 failure : function(response) { 778 779 var module = response.argument.module.module, opt = response.argument.module; 780 module.contentType = response.contentType || ''; 781 this.currentModule = module.name; 782 this.result = module.pending = false; 783 784 this.doCallBacks(opt, this.result = false, module, [ 785 { 786 error : (this.lastError = response.fullStatus.error), 787 httpStatus : response.status, 788 httpStatusText : response.statusText 789 } 790 ]); 791 }, 792 793 /** 794 * @private 795 * 796 */ 797 798 nextModule : function() { 799 var module, transport, executable, options, url; 800 801 while (this.active && (module = this.workList.shift())) { 802 803 // inline callbacks 804 if (Ext.isFunction(module)) { 805 module.apply(this, [ 806 this.result, null, this.loaded 807 ]); 808 continue; 809 } 810 811 // setup possible single-use listeners for the current 812 // request chain 813 if (module.listeners) { 814 this.unlisteners.push(module.listeners); 815 this.MM.on(module.listeners); 816 delete module.listeners; 817 818 } 819 820 var params = null, data = null, moduleObj; 821 options = module; 822 if (params = module.params) { 823 Ext.isFunction(params) && (params = params.call(options.scope || window, options)); 824 (Ext.isObject(params) || Ext.isObject(params)) && (params = Ext.urlEncode(params)); 825 module.params = data = params; // setup for possible post 826 } 827 828 if (moduleObj = this.MM.createModule(module.module, { 829 path : options.modulePath 830 })) { 831 url = moduleObj.url; 832 833 executable = (!options.proxied && moduleObj.extension == "js" && !options.noExecute); 834 835 if ((!moduleObj.loaded) || options.forced) { 836 837 if (!moduleObj.pending) { 838 moduleObj.pending = true; 839 if (/get|script|dom|link/i.test(options.method)) { 840 url += (params ? '?' + params : ''); 841 if (options.disableCaching == true) { 842 url += (params ? '&' : '?') + '_dc=' + (new Date().getTime()); 843 } 844 data = null; 845 } 846 847 options.async = options.method === 'DOM' ? true : options.async; 848 849 transport = gather(options.method == 'DOM' ? (moduleObj.extension == 'css' ? 'LINK' : 'SCRIPT') : options.method, url, options.callback = { 850 success : this.success, 851 failure : this.failure, 852 scope : this, 853 argument : { 854 module : module 855 } 856 }, data, options); 857 858 Ext.apply(moduleObj, { 859 element : options.method == 'DOM' ? transport : null, 860 method : options.method || this.method, 861 options : options 862 }); 863 } 864 865 if (options.async) { 866 break; 867 } 868 869 } else { 870 this.active = this.MM.fireEvent('alreadyloaded', this.MM, moduleObj) !== false; 871 executable && this.executed.push(moduleObj); 872 this.loaded.push(moduleObj); 873 } 874 875 } // if moduleObj 876 } // oe while(module) 877 878 if (this.active && module && module.async && moduleObj) { 879 moduleObj.notify || (moduleObj.notify = new Array()); 880 moduleObj.notify.push(this); 881 } 882 883 }, 884 885 /** 886 * @private Normalize requested modules and options into a sequential series 887 * of load requests and inline callbacks 888 */ 889 890 prepare : function(modules) { 891 892 var onAvailableList = new Array(), workList = new Array(), options = this.defOptions, mtype, MM = this.MM; 893 894 var adds = new Array(); 895 896 var expand = function(mods) { 897 898 mods = new Array().concat(mods); 899 var adds = new Array(); 900 forEach(mods, function(module) { 901 902 if (!module) 903 return; 904 var m; 905 906 mtype = typeof(module); 907 switch (mtype) { 908 case 'string' : // a named resource 909 910 m = MM.createModule(module, { 911 path : options.modulePath, 912 url : module.url || null 913 }); 914 if (!m.loaded) { 915 module = Ext.applyIf({ 916 name : m.name, 917 module : m, 918 callback : null 919 }, options); 920 delete options.listeners; 921 workList.push(module); 922 adds.push(module); 923 } 924 925 onAvailableList.push(m.name); 926 break; 927 case 'object' : // or array of modules 928 // coerce to array to support this notation: 929 // {module:'name' or 930 // {module:['name1','name2'],callback:cbFn,... 931 // so that callback is only called when the last 932 // in the implied list is loaded. 933 934 if (m = (module.modules || module.module)) { 935 adds = expand(m); 936 delete module.module; 937 delete module.modules; 938 } 939 940 if (module.proxied) { 941 module.method = 'GET'; 942 module.cacheResponses = module.async = true; 943 } 944 945 if (Ext.isArray(module)) { 946 adds = expand(module); 947 } else { 948 var mod = module; 949 if (module.name) { // for notation 950 // {name:'something', 951 // url:'assets/something'} 952 953 m = MM.createModule(module, { 954 path : options.modulePath, 955 url : mod.url || null 956 }); 957 delete mod.url; 958 Ext.apply(options, mod); 959 if (!m.loaded) { 960 mod = Ext.applyIf({ 961 name : m.name, 962 module : m, 963 callback : null 964 }, options); 965 delete options.listeners; 966 workList.push(mod); 967 adds.push(mod); 968 } 969 970 onAvailableList.push(m.name); 971 972 } else { 973 Ext.apply(options, mod); 974 } 975 976 } 977 break; 978 case 'function' : 979 workList.push(module); 980 default : 981 } 982 199 983 }); 200 Ext.ux.ModuleManager.superclass.constructor.call(this); 201 202 }; 203 204 /** @private */ 205 var gather = function(method, url, callbacks, data, options) { 206 207 var tag, attribs; 208 callbacks || (callbacks = {}); 209 210 if (method == 'SCRIPT') { 211 tag = method; 212 attribs = { 213 type : "text/javascript", 214 src : url 215 }; 216 217 } else if (method == 'LINK') { 218 tag = method; 219 attribs = { 220 rel : "stylesheet", 221 type : "text/css", 222 href : url 223 }; 984 985 return adds; 986 }; 987 988 expand(modules); 989 this.options = options; 990 this.workList = workList.flatten().compact(); 991 this.onAvailableList = onAvailableList.flatten().unique(); 992 }, 993 994 /** 995 * @private 996 */ 997 onComplete : function(loaded, timedOut, lastModule) { // called with scope 998 // of last module 999 // in chain 1000 var cb = this.options.callback, MM = this.MM; 1001 1002 this.timedOut = !!timedOut; 1003 1004 if (loaded) { 1005 cb && cb.apply(this.options.scope || this, [ 1006 this.result, this.loaded, this.executed 1007 ]); 1008 MM.fireEvent('complete', MM, this.result, this.loaded, this.executed); 1009 1010 } else if (this.active && this.timedOut) { 1011 cb && cb.apply(this.options.scope || this, [ 1012 this.result, this.loaded, this.executed 1013 ]); 1014 MM.fireEvent('timeout', MM, lastModule, this.executed); 1015 } 1016 1017 // cleanup single-use listeners from the previous request chain 1018 if (this.unlisteners) { 1019 forEach(this.unlisteners, function(block) { 1020 forEach(block, function(listener, name, listeners) { 1021 var fn = listener.fn || listener; 1022 var scope = listener.scope || listeners.scope || this.MM; 1023 var ev = listener.name || name; 1024 this.MM.removeListener(ev, fn, scope); 1025 }, this); 1026 }, this); 1027 } 1028 this.active = false; 1029 } 1030 } 1031 ); 1032 1033 // Enable local file access for IE 1034 Ext.lib.Ajax.forceActiveX = (Ext.isIE7 && document.location.protocol == 'file:'); 1035 1036 var L = Ext.Loader = new Ext.ux.ModuleManager({ 1037 1038 modulePath : '', // adjust for site root 1039 method : 'DOM', 1040 depends : {}, // Ext dependency table 1041 disableCaching : true, 1042 1043 getMap : function(module) { 1044 1045 var result = new Array(), mods = new Array().concat(module.module || module); 1046 var options = Ext.isObject(module) ? module : { 1047 module : module 1048 }; 1049 1050 forEach(mods, function(mod) { 1051 var c = arguments.callee; 1052 var moduleName = Ext.isObject(mod) ? mod.module || null : mod; 1053 var map = moduleName ? this.depends[moduleName.replace("@", "")] || false : false; 1054 1055 map = Ext.apply({ 1056 path : '', 1057 depends : false 1058 }, map); 1059 1060 forEach(map.depends || new Array(), function(module, index, dep) { 1061 // chain dependencies 1062 module.substr(0, 1) == "@" ? c.call(this, module) : (result = result.concat(module)); 1063 1064 }, this); 1065 1066 if (moduleName && !(map.none || map.virtual)) { 1067 result = result.concat((map.path || '') + moduleName.replace("@", "")); 224 1068 } 225 return tag ? A.monitoredNode(tag, attribs, callbacks, options.target || window) : 226 A.request.apply(A,arguments); 227 }; 228 229 // normalize a resource to name-component hash 230 /** @private */ 231 var modulate = function(moduleName, options) { 232 if (!moduleName) 233 return null; 234 options || (options = {}); 235 var mname = String(moduleName.name || moduleName), 236 name = mname.trim().split('\/').last(), 237 fname = options ? (name.indexOf('.') !== -1 ? mname : mname + '.js') : '', 238 path = options.path || ''; 239 240 var mod = Ext.apply({ 241 name : name, 242 fullName : moduleName.name ? moduleName.name : fname, 243 extension : !moduleName.name ? fname.split('.').last() 244 .trim().toLowerCase() : '', 245 path : path 246 }, options); 247 248 mod.url = options.url || (path + fname); 249 return mod; 250 }; 251 252 Ext.extend(Ext.ux.ModuleManager, Ext.util.Observable, { 253 /** 254 * @cfg {Boolean} disableCaching True to ensure the the browser's 255 * cache is bypassed when retrieving resources. 256 */ 257 disableCaching : false, 258 259 /** @private */ 260 261 modules : {}, 262 263 /** 264 * @cfg {String} method The default request method used to retrieve 265 * resources. This method may also changed in-line during a 266 * {@link #load) operation. Supported methods: 267 * <ul> 268 * <li>DOM - Retrieve the resource by <SCRIPT/LINK> tag 269 * insertion</li> 270 * <li>GET Retrieve the resource by Ajax Request</li> 271 * <li>POST</li> 272 * <li>PUT</li> 273 * </ul> 274 */ 275 276 method : 'GET', 277 278 /** 279 * @cfg {Boolean} noExecute Permits retrieval of a resource without 280 * script execution of the results. This option may also be 281 * changed in-line during a {@link #load) operation. 282 */ 283 284 noExecute : false, 285 /** 286 * @cfg {Boolean} asynchronous Sets the default behaviour for AJAX 287 * requests onlu This option may also be changed in-line 288 * (async: true) during a {@link #load) operation. 289 */ 290 291 asynchronous : true, 292 293 /** 294 * @cfg {Boolean} cacheResponses True, saves any content received in 295 * a content object with the following structure: 296 * 297 * This option may also be changed in-line during a 298 * {@link #load) operation. 299 */ 300 301 cacheResponses : false, 302 303 /** 304 * @cfg {Integer} default onAvailable/load method timeout value in 305 * milliseconds 306 */ 307 308 timeout : 30000, 309 310 /** 311 * @cfg {Boolean} True retains the resulting content within each 312 * module object for debugging. 313 */ 314 315 debug : false, 316 317 /** @private */ 318 loadStack : new Array(), 319 320 loaded : function(name) { 321 var module; 322 return (module = this.getModule(name))? module.loaded === true : false; 323 }, 324 325 326 getModule : function(name) { 327 name && (name = name.name ? name.name : modulate(name, false).name); 328 return name ? this.modules[name] : null; 329 }, 330 /* 331 * A mechanism for modules to identify their presence when loaded 332 * via conventional <script> tags 333 * @param {String} module names(s) 334 * Usage: <pre><code>Ext.Loader.provides('moduleA', 'moduleB');</code></pre> 335 */ 336 337 createModule : function(name, extras) { 338 var mod, existing; 339 mod = (existing = this.getModule(name)) || modulate(name, extras); 340 341 return existing || 342 (this.modules[mod.name] = Ext.apply({ 343 executed : false, 344 contentType : '', 345 content : null, 346 loaded : false, 347 pending : false 348 },mod)); 349 350 351 if (!mod) { 352 var m = modulate(name, extras); 353 mod = this.modules[m.name] = Ext.apply({ 354 executed : false, 355 contentType : '', 356 content : null, 357 loaded : false, 358 pending : false 359 }, m); 360 } 361 362 return mod; 363 }, 364 365 /** 366 * Assert loaded status of module name arguments and invoke 367 * callback(s) when all are available 368 * 369 * @param {Array/String} 370 * modules A list of module names to monitor 371 * @param {Function} 372 * callback The callback function called when all named 373 * resources are available or timeout 374 * @param (Object) 375 * scope The execution scope of the callback 376 * @param {integer} 377 * timeout The timeout value in milliseconds. 378 */ 379 380 onAvailable : function(modules, callbackFn, scope, timeout, options) { 381 382 if (arguments.length < 2) { 383 return false; 384 } 385 386 var MM = this, 387 block = { 388 389 modules : new Array().concat(modules), 390 poll : function() { 391 392 var depends = (window.$JIT ? $JIT.depends : null) || {}; 393 var assert = this.polling ? this.modules.every( function(arg, index, args) { 394 395 var modName = arg.replace('@',''),virtual = false, test=true; 396 if(depends[modName] && 397 ((virtual = depends[modName].virtual || false) || 398 (Ext.isArray(depends[modName].depends && 399 !!depends[modName].length 400 )))){ 401 test = depends[modName].depends.every(arguments.callee); 402 test = virtual ? test && ((MM.getModule(modName)||{}).loaded = true): test; 403 } 404 405 test = test && (virtual || MM.loaded(modName) === true); 406 block.pendingModule = test ? null : MM.getModule(modName); 407 return test; 408 }) : false; 409 410 if (!assert && this.polling && !this.aborted) { 411 this.poll.defer(50, this); 412 return; 413 } 414 415 this.stop(); 416 Ext.isFunction(callbackFn) && callbackFn.call(scope, assert, this.timedOut, this.pendingModule); 417 418 }, 419 420 polling : false, 421 422 abort : function() { 423 this.aborted = true; 424 this.stop(); 425 }, 426 427 stop : function() { 428 this.polling = false; 429 this.timer && clearTimeout(this.timer); 430 this.timer = null; 431 }, 432 433 timer : null, 434 435 timeout : parseInt(timeout || MM.timeout, 10) || 10000, 436 437 onTimeout : function() { 438 this.timedOut = true; 439 this.abort(); 440 }, 441 442 retry : function(timeout) { 443 444 this.stop(); 445 this.polling = true; 446 this.aborted = this.timedOut = false; 447 this.timer = this.onTimeout.defer(timeout || this.timeout, this); 448 this.poll(); 449 return this; 450 } 451 }; 452 return block.retry(); 453 }, 454 455 /** 456 * A mechanism for modules to identify their presence when loaded 457 * via conventional <script> tags or nested on other scripts. 458 * 459 * @param {String} 460 * module names(s) Usage: 461 * 462 * <pre><code> 463 * Ext.Loader.provides('moduleA', 'moduleB'); 464 * </code></pre> 465 */ 466 467 provides : function() { 468 forEach(arguments, function(module) { 469 470 var moduleObj = this.createModule(module, false); 471 moduleObj.loaded || //already loaded ? 472 Ext.apply(moduleObj, { 473 executed : moduleObj.extension === 'js', 474 contentType : '', 475 content : null, 476 loaded : true, 477 pending : false 478 }); 479 }, this); 480 481 }, 482 /** 483 * load external resources in dependency order alternate load 484 * syntax: 485 * 486 * <pre><code> 487 * load( 'moduleA', 'path/moduleB' ); 488 * load( {module:['modA','path/modB'], callback:cbFn, method:'DOM', queue:'fast', ... }); 489 * load( {async:false, listeners: {complete: onCompleteFn, loadexception: loadExFn }}, 'moduleA', inlineFn, {async:true}, 'moduleB', inlineFn, .... ); 490 * 491 * </code></pre> 492 * 493 * @name load 494 * @methodOf Ext.ux.ModuleManager 495 * @param {Mixed} 496 * args One or more module definitions, inline functions 497 * to be execute in sequential order 498 */ 499 500 501 load : function(modList) { 502 503 try { 504 var task = new Task(this, Ext.isArray(modList) ? modList : Array.slice(arguments, 0)); 505 task.start(); 506 507 } catch (ex) { 508 509 if (ex != StopIter) { 510 511 if (task) { 512 task.lastError = ex; 513 task.active = false; 514 } 515 516 this.fireEvent('loadexception', this, task 517 ? task.currentModule 518 : null, this.lastError = ex); 519 } 520 } 521 522 return task; 523 }, 524 525 526 globalEval : function(data, scope, context) { 527 scope || (scope = window); 528 data = String(data || "").trim(); 529 if (data.length === 0) {return false;} 530 try { 531 if (scope.execScript) { 532 // window.execScript in IE fails when scripts include 533 // HTML comment tag. 534 scope.execScript(data.replace(/^<!--/, "").replace(/-->$/, "")); 535 536 } else { 537 // context (target namespace) is only support on Gecko. 538 eval.call(scope, data, context || null); 539 } 540 return true; 541 } catch (ex) { 542 return ex; 543 } 544 545 }, 546 styleAdjust : null, 547 548 549 applyStyle : function(module, styleRules, target) { 550 var rules; 551 if (module = this.getModule(module)) { 552 // All css is injected into document's head section 553 var doc = (target || window).document; 554 var ct = (styleRules 555 || (module.content ? module.content.text : '') || '') 556 + ''; 557 var head; 558 if (doc && !!ct.length 559 && (head = doc.getElementsByTagName("head")[0])) { 560 561 if (module.element) { 562 this.removeModuleElement(module); 563 } 564 if (this.styleAdjust && this.styleAdjust.pattern) { 565 // adjust CSS (eg. urls (images etc)) 566 ct = ct.replace(this.styleAdjust.pattern, 567 this.styleAdjust.replacement || ''); 568 } 569 570 rules = doc.createElement("style"); 571 module.element = Ext.get(rules); 572 A._domRefs.push(module.element); 573 rules.setAttribute("type", "text/css"); 574 if (Ext.isIE) { 575 head.appendChild(rules); 576 rules.styleSheet.cssText = ct; 577 } else { 578 try { 579 rules.appendChild(doc.createTextNode(ct)); 580 } catch (e) { 581 rules.cssText = ct; 582 } 583 head.appendChild(rules); 584 } 585 } 586 } 587 return rules; // the style element created 588 }, 589 590 /** 591 * Remove a style element 592 * 593 * @name removeStyle 594 * @param {Mixed} 595 * module A Ext.ux.ModuleManager.module or dom Node 596 * @return {Ext.Element} the element removed. 597 */ 598 599 removeStyle : function(module) { 600 return this.removeModuleElement(module); 601 }, 602 603 /** @private */ 604 // Remove an associated module.element from the DOM 605 606 removeModuleElement : function(module) { 607 var el; 608 if (module = this.getModule(module)) { 609 if (el = module.element) { 610 el.dom ? el.removeAllListeners().remove(true) : Ext.removeNode(el); 611 } 612 module.element = el = null; 613 } 614 615 }, 616 destroy : function(){ 617 forEach(this.modules, 618 function(module, name){ 619 this.removeModuleElement(name); 620 delete this.modules[name]; 621 }, this); 622 } 623 }); 624 625 var Task = Ext.ux.ModuleManager.Task = function(MM, modules) { 626 627 Ext.apply(this, { 628 result : true, 629 active : false, 630 options : null, 631 executed : new Array(), 632 loaded : new Array(), 633 params : null, 634 data : null, 635 oav : null, 636 timedOut : false, 637 unlisteners : new Array(), 638 MM : MM, 639 id : Ext.id(null, 'mm-task-'), 640 defOptions : { 641 async : MM.asynchronous, 642 headers : MM.headers || false, 643 modulePath : MM.modulePath, 644 forced : false, 645 cacheResponses : MM.cacheResponses, 646 method : (MM.noExecute || MM.cacheResponses 647 ? 'GET' 648 : MM.method || 'GET').toUpperCase(), 649 noExecute : MM.noExecute || false, 650 disableCaching : MM.disableCaching, 651 timeout : MM.timeout, 652 callback : null, 653 scope : null, 654 params : null 655 } 656 }); 657 658 this.prepare(modules); 659 660 }; 661 662 Ext.apply(Task.prototype, { 663 /** 664 * @private 665 * 666 */ 667 668 start : function() { 669 this.active = true; 670 this.nextModule(); 671 if (this.options.async) { 672 this.oav = this.MM.onAvailable.call(this.MM, 673 this.onAvailableList, this.onComplete, this, 674 this.options.timeout, this.options); 675 } else { 676 this.onComplete(this.result); 677 } 678 679 }, 680 681 /** 682 * @private 683 * 684 */ 685 doCallBacks : function(options, success, currModule, args) { 686 var cb, C; 687 688 if (C = currModule) { 689 var res = this.timedOut || this.MM.fireEvent.apply(this.MM, [ 690 (success ? 'load' : 'loadexception'), 691 this.MM, C ].concat(args || [])); 692 693 success || (this.active = (!this.timedOut && res !== false)); 694 695 // Notify other pending async listeners 696 if (this.active && Ext.isArray(C.notify)) { 697 forEach(C.notify, 698 function(chain, index, chains) { 699 if (chain) { 700 chain.nextModule(); 701 chains[index] = null; 702 } 703 }); 704 C.notify = []; 705 } 706 707 //script Tag cleanup 708 if(C.element && !options.debug && C.extension == "js" && options.method == 'DOM'){ 709 710 C.element.removeAllListeners(); 711 var d = C.element.dom; 712 if(Ext.isIE){ 713 //Script Tags are re-usable in IE 714 A.SCRIPTTAG_POOL.push(C.element); 715 }else{ 716 717 C.element.remove(); 718 //Other Browsers will not GBG-collect these tags, so help them along 719 if(d){ 720 for(var prop in d) {delete d[prop];} 721 } 722 } 723 d = null; 724 delete C.element; 725 } 726 1069 }, this); 1070 1071 return Ext.applyIf({ 1072 module : !!result.length ? result.unique() : null 1073 }, options); 1074 1075 }, 1076 1077 styleAdjust : { 1078 pattern : /url\(\s*\.\.\//ig, 1079 replacement : 'url(resources/' 1080 } 1081 1082 }); 1083 1084 /** 1085 * @class $JIT 1086 * @version 1.4.1 1087 * @author Doug Hendricks. doug[always-At]theactivegroup.com 1088 * @copyright 2007-2009, Active Group, Inc. All rights reserved. 1089 * @donate <a target="tag_donate" href="http://donate.theactivegroup.com"><img 1090 * border="0" 1091 * src="http://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" 1092 * border="0" alt="Make a donation to support ongoing development"></a> 1093 * @license <a href="http://www.gnu.org/licenses/gpl.html">GPL 3.0</a> 1094 * @singleton 1095 * @static 1096 * @description Load external resources in dependency order by any transport 1097 * supported by the ext-basex adapter. 1098 * <p> 1099 * For an online demonstration of $JIT in action, <a 1100 * href="http://demos.theactivegroup.com/?demo=basex&script=multipart" 1101 * target="tagdemo">click here.</a> 1102 * @example 1103 * Flexible load syntaxes: 1104 * 1105 * $JIT( 'moduleA', 'path/moduleB', function(loaded, modules){ 1106 * if(loaded){ 1107 * var t = new justLoadedClass(); 1108 * } 1109 * }); 1110 * 1111 * //or, A long running request can be evaluated asynchronously later: 1112 * $JIT.onAvailable (['moduleA', 'uxpackage'], function(loaded){ 1113 * if(loaded){ 1114 * var t = new justLoadedClass(); 1115 * } 1116 * }); 1117 * 1118 * $JIT( {module:['modA','path/modB'], 1119 * callback: cbFn, 1120 * scope: null, //callback scope 1121 * modulePath : 'assets/scripts/', //(optional) root for request chain 1122 * disableCaching : true, //prevent browser caching of modules 1123 * cacheResponses : false, //true to cache the text content of the module 1124 * async : false // synchronous request 1125 * method:'DOM', //others: 'GET', 'POST', 'DOM' writes to script tags for debugging 1126 * proxied : false //if true or config, uses the JSONP transport 1127 * xdomain : false, //(optional) for modern browsers supporting cross-domain requests 1128 * queue:{name:'fast', priority: 2}, //(optional) Queuing support 1129 * ... }); 1130 * 1131 * //Inline callbacks 1132 * $JIT( { 1133 * async :false, //start out synchronous mode 1134 * listeners: { 1135 * complete: onCompleteFn, 1136 * loadexception: loadExFn 1137 * } 1138 * }, 1139 * 'moduleA', 1140 * progressFn, 1141 * {async:true}, //switch to asynchronous mode 1142 * 'moduleB', 1143 * progressFn, .... ); 1144 * 1145 * //Define logical dependencies: (Adjust to suite your site layout.) 1146 * 1147 * var ux= 'ux/'; 1148 * Ext.apply( $JIT.depends , { 1149 * // JS source file | source location | Dependencies (in required load order) 1150 * 'uxvismode' : {path: ux } 1151 * ,'uxmedia' : {path: ux , depends: [ '@uxvismode']} 1152 * ,'uxflash' : {path: ux , depends: [ '@uxmedia'] } 1153 * ,'uxchart' : {path: ux , depends: [ '@uxflash'] } 1154 * ,'uxfusion' : {path: ux , depends: [ '@uxchart'] } 1155 * ,'uxofc' : {path: ux , depends: [ '@uxchart'] } 1156 * ,'uxamchart' : {path: ux , depends: [ '@uxchart'] } 1157 * ,'uxflex' : {path: ux , depends: [ '@uxflash'] } 1158 * ,'mif' : {path: ux , depends: [ '@uxvismode' ] } 1159 * ,'mifmsg' : {path: ux , depends: [ '@mif'] } 1160 * ,'mifdd' : {path: ux , depends: [ '@mif'] } 1161 * }); 1162 * 1163 * //then, load as assembly: 1164 * $JIT('@uxfusion', callbackFn); 1165 * or 1166 * $JIT.onAvailable('uxfusion', callbackFn); 1167 * 1168 * //$JIT also amends Ext.ComponentMgr to permit inline dynamic (synchronous-only) 1169 * loading of resources when using delayed-loading of Component configurations: 1170 * 1171 * new Ext.Panel({ 1172 * layout:'fit', 1173 * items:{ 1174 * //demand and load 'customerform.js' and 'gmap' modules (if not already available) 1175 * <b>require</b> : ['dialogs/customerform','gmap'], 1176 * xtype : 'tabpanel', 1177 * items : {title:'Grid', <b>JIT:</b>'custom-grid',...} 1178 * } 1179 * }); 1180 * 1181 * Another asynchronous method available is namespace/object polling: 1182 * $JIT('ux/Rowediter'); 1183 * $JIT.onClassAvailable('Ext.ux.grid.RowEditor',function(available){ 1184 if(available){ 1185 var plugin = new Ext.ux.grid.RowEditor().init(this); 1186 ..... 727 1187 } 728 1188 }, 729 730 /** 731 * @private 732 * 733 */ 734 success : function(response , ev, target ) { 735 736 var module = response.argument.module.module, 737 opt = response.argument.module, 738 executable = (!opt.proxied && module.extension == "js" && !opt.noExecute && opt.method !== 'DOM'), 739 cbArgs = null, 740 MM = this.MM; 741 742 module = MM.getModule(module.name); 743 this.currentModule = module.name; 744 745 if (!module.loaded) { 746 try { 747 748 if (MM.fireEvent('beforeload', MM, module, 749 response, response.responseText) !== false) { 750 751 Ext.apply(module, { 752 loaded : true, 753 pending : false, 754 contentType : response.contentType || (target && Ext.fly(target) ? Ext.fly(target).getAttributeNS(null,'type'):''), 755 content : opt.cacheResponses 756 || module.extension == "css" ? { 757 text : response.responseText || null, 758 XML : response.responseXML || null, 759 JSON : response.responseJSON || null, 760 parts : response.parts 761 762 } : null 763 }); 764 765 this.loaded.push(module); 766 var exception = executable 767 && (!module.executed || opt.forced) 768 ? MM.globalEval(response.responseText, opt.target) 769 : true; 770 if (exception === true) { 771 if (executable) { 772 module.executed = true; 773 this.executed.push(module); 774 } 775 cbArgs = [response, response.responseText, module.executed]; 776 } else { 777 // coerce to actual module URL 778 throw Ext.applyIf({ 779 fileName : module.url, 780 lineNumber : exception.lineNumber || 0 781 }, exception); 782 } 783 } 784 785 } catch (exl) { 786 cbArgs = [{ 787 error : (this.lastError = exl), 788 httpStatus : response.status, 789 httpStatusText : response.statusText 790 }]; 791 792 this.result = false; 793 } 794 795 this.doCallBacks(opt, this.result, module, cbArgs); 796 } else { 797 opt.async && this.nextModule(); 798 } 799 800 }, 801 802 /** 803 * @private 804 * 805 */ 806 807 failure : function(response) { 808 809 var module = response.argument.module.module, opt = response.argument.module; 810 module.contentType = response.contentType || ''; 811 this.currentModule = module.name; 812 this.result = module.pending = false; 813 814 this.doCallBacks(opt, this.result = false, module, [{ 815 error : (this.lastError = response.fullStatus.error), 816 httpStatus : response.status, 817 httpStatusText : response.statusText 818 }]); 819 }, 820 821 /** 822 * @private 823 * 824 */ 825 826 nextModule : function() { 827 var module, transport, executable, options, url; 828 829 while (this.active && (module = this.workList.shift())) { 830 831 // inline callbacks 832 if (Ext.isFunction(module)) { 833 module.apply(this, [this.result, null, this.loaded]); 834 continue; 835 } 836 837 // setup possible single-use listeners for the current 838 // request chain 839 if (module.listeners) { 840 this.unlisteners.push(module.listeners); 841 this.MM.on(module.listeners); 842 delete module.listeners; 843 844 } 845 846 847 var params = null, data = null, moduleObj; 848 options = module; 849 if (params = module.params) { 850 Ext.isFunction(params)&& (params = params.call(options.scope || window,options)); 851 (Ext.isObject(params) || Ext.isObject(params)) && (params = Ext.urlEncode(params)); 852 module.params = data = params; // setup for possible post 853 } 854 855 if (moduleObj = this.MM.createModule(module.module, { 856 path : options.modulePath 857 })) { 858 url = moduleObj.url; 859 860 executable = (!options.proxied 861 && moduleObj.extension == "js" && !options.noExecute); 862 863 if ((!moduleObj.loaded) || options.forced) { 864 865 if (!moduleObj.pending) { 866 moduleObj.pending = true; 867 if (/get|script|dom|link/i.test(options.method)) { 868 url += (params ? '?' + params : ''); 869 if (options.disableCaching == true) { 870 url += (params ? '&' : '?') + '_dc=' 871 + (new Date().getTime()); 872 } 873 data = null; 874 } 875 876 options.async = options.method === 'DOM' 877 ? true 878 : options.async; 879 880 transport = gather( 881 options.method == 'DOM' 882 ? (moduleObj.extension == 'css' 883 ? 'LINK' 884 : 'SCRIPT') 885 : options.method, 886 url, 887 options.callback = { 888 success : this.success, 889 failure : this.failure, 890 scope : this, 891 argument : { 892 module : module 893 } 894 }, 895 data, 896 options); 897 898 Ext.apply( moduleObj,{ 899 element : options.method == 'DOM' ? transport : null, 900 method : options.method || this.method, 901 options : options 902 }); 903 } 904 905 if (options.async) { break; } 906 907 } else { 908 this.active = this.MM.fireEvent('alreadyloaded', this.MM, moduleObj) !== false; 909 executable && this.executed.push(moduleObj); 910 this.loaded.push(moduleObj); 911 } 912 913 } // if moduleObj 914 } // oe while(module) 915 916 if (this.active && module && module.async && moduleObj) { 917 moduleObj.notify || (moduleObj.notify = new Array()); 918 moduleObj.notify.push(this); 919 } 920 921 }, 922 923 /** 924 * @private 925 * Normalize requested modules and options into a sequential series 926 * of load requests and inline callbacks 927 */ 928 929 prepare : function(modules) { 930 931 var onAvailableList = new Array(), 932 workList = new Array(), 933 options = this.defOptions, 934 mtype, 935 MM = this.MM; 936 937 var adds = new Array(); 938 939 var expand = function(mods) { 940 941 mods = new Array().concat(mods); 942 var adds = new Array(); 943 forEach(mods, function(module) { 944 945 if (!module)return; 946 var m; 947 948 mtype = typeof(module); 949 switch (mtype) { 950 case 'string' : // a named resource 951 952 m = MM.createModule(module, { 953 path : options.modulePath, 954 url : module.url || null 955 }); 956 if (!m.loaded) { 957 module = Ext.applyIf({ 958 name : m.name, 959 module : m, 960 callback : null 961 }, options); 962 delete options.listeners; 963 workList.push(module); 964 adds.push(module); 965 } 966 967 onAvailableList.push(m.name); 968 break; 969 case 'object' : // or array of modules 970 // coerce to array to support this notation: 971 // {module:'name' or 972 // {module:['name1','name2'],callback:cbFn,... 973 // so that callback is only called when the last 974 // in the implied list is loaded. 975 976 if (m = (module.modules || module.module)) { 977 adds = expand(m); 978 delete module.module; 979 delete module.modules; 980 } 981 982 if (module.proxied) { 983 module.method = 'GET'; 984 module.cacheResponses = module.async = true; 985 } 986 987 if (Ext.isArray(module)) { 988 adds = expand(module); 989 } else { 990 var mod = module; 991 if (module.name) { // for notation 992 // {name:'something', 993 // url:'assets/something'} 994 995 m = MM.createModule(module, { 996 path : options.modulePath, 997 url : mod.url || null 998 }); 999 delete mod.url; 1000 Ext.apply(options, mod); 1001 if (!m.loaded) { 1002 mod = Ext.applyIf({ 1003 name : m.name, 1004 module : m, 1005 callback : null 1006 }, options); 1007 delete options.listeners; 1008 workList.push(mod); 1009 adds.push(mod); 1010 } 1011 1012 onAvailableList.push(m.name); 1013 1014 } else { 1015 Ext.apply(options, mod); 1016 } 1017 1018 } 1019 break; 1020 case 'function' : 1021 workList.push(module); 1022 default : 1023 } 1024 1025 }); 1026 1027 return adds; 1028 }; 1029 1030 expand(modules); 1031 this.options = options; 1032 this.workList = workList.flatten().compact(); 1033 this.onAvailableList = onAvailableList.flatten().unique(); 1034 }, 1035 1036 /** 1037 * @private 1038 */ 1039 onComplete : function(loaded, timedOut, lastModule) { // called with scope of last module 1040 // in chain 1041 var cb = this.options.callback, 1042 MM = this.MM; 1043 1044 this.timedOut = !!timedOut; 1045 1046 if(loaded){ 1047 cb && cb.apply(this.options.scope || this, [this.result, this.loaded, this.executed]); 1048 MM.fireEvent('complete', MM, this.result, this.loaded, this.executed); 1049 1050 }else if(this.active && this.timedOut){ 1051 cb && cb.apply(this.options.scope || this, [this.result, this.loaded, this.executed]); 1052 MM.fireEvent('timeout', MM, lastModule , this.executed); 1053 } 1054 1055 1056 // cleanup single-use listeners from the previous request chain 1057 if (this.unlisteners) { 1058 forEach(this.unlisteners, function(block) { 1059 forEach(block, function(listener, name, 1060 listeners) { 1061 var fn = listener.fn || listener; 1062 var scope = listener.scope 1063 || listeners.scope 1064 || this.MM; 1065 var ev = listener.name || name; 1066 this.MM.removeListener(ev, fn, 1067 scope); 1068 }, this); 1069 }, this); 1070 } 1071 this.active = false; 1072 } 1073 }); 1074 1075 //Enable local file access for IE 1076 Ext.lib.Ajax.forceActiveX = (Ext.isIE7 && document.location.protocol == 'file:'); 1077 1078 var L = Ext.Loader = new Ext.ux.ModuleManager({ 1079 1080 modulePath : '', //adjust for site root 1081 method : 'DOM', 1082 depends : {}, // Ext dependency table 1083 disableCaching : true, 1084 1085 getMap:function(module){ 1086 1087 var result = new Array(), mods= new Array().concat(module.module || module); 1088 var options = Ext.isObject(module) ? module : {module:module}; 1089 1090 forEach(mods, 1091 function(mod){ 1092 var c=arguments.callee; 1093 var moduleName = Ext.isObject(mod)? mod.module || null : mod; 1094 var map = moduleName ? this.depends[moduleName.replace("@","")]||false : false; 1095 1096 map = Ext.apply({path:'',depends:false}, map); 1097 1098 forEach(map.depends||new Array() , 1099 function(module,index,dep){ 1100 //chain dependencies 1101 module.substr(0,1)=="@" ? 1102 c.call(this, module ): 1103 (result = result.concat(module)); 1104 1105 },this); 1106 1107 if(moduleName && !(map.none || map.virtual)){result = result.concat((map.path||'') + moduleName.replace("@","")); } 1108 },this); 1109 1110 return Ext.applyIf({module:!!result.length ? result.unique() :null},options); 1111 1112 }, 1113 1114 styleAdjust : {pattern:/url\(\s*\.\.\//ig, replacement:'url(resources/'} 1115 1116 }); 1117 1118 1119 /** 1120 * @class $JIT 1121 * @version 1.4.1 1122 * @author Doug Hendricks. doug[always-At]theactivegroup.com 1123 * @copyright 2007-2009, Active Group, Inc. All rights reserved. 1124 * @donate <a target="tag_donate" href="http://donate.theactivegroup.com"><img border="0" src="http://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" border="0" alt="Make a donation to support ongoing development"></a> 1125 * @license <a href="http://www.gnu.org/licenses/gpl.html">GPL 3.0</a> 1126 * @singleton 1127 * @static 1128 * @description Load external resources in dependency order by any transport supported by the ext-basex adapter. 1129 * <p>For an online demonstration of $JIT in action, <a href="http://demos.theactivegroup.com/?demo=basex&script=multipart" target="tagdemo">click here.</a> 1130 * @example 1131 * Flexible load syntaxes: 1132 * 1133 * $JIT( 'moduleA', 'path/moduleB', function(loaded, modules){ 1134 * if(loaded){ 1135 * var t = new justLoadedClass(); 1136 * } 1137 * }); 1138 * 1139 * //or, A long running request can be evaluated asynchronously later: 1140 * $JIT.onAvailable (['moduleA', 'uxpackage'], function(loaded){ 1141 * if(loaded){ 1142 * var t = new justLoadedClass(); 1143 * } 1144 * }); 1145 * 1146 * $JIT( {module:['modA','path/modB'], 1147 * callback: cbFn, 1148 * scope: null, //callback scope 1149 * modulePath : 'assets/scripts/', //(optional) root for request chain 1150 * disableCaching : true, //prevent browser caching of modules 1151 * cacheResponses : false, //true to cache the text content of the module 1152 * async : false // synchronous request 1153 * method:'DOM', //others: 'GET', 'POST', 'DOM' writes to script tags for debugging 1154 * proxied : false //if true or config, uses the JSONP transport 1155 * xdomain : false, //(optional) for modern browsers supporting cross-domain requests 1156 * queue:{name:'fast', priority: 2}, //(optional) Queuing support 1157 * ... }); 1158 * 1159 * //Inline callbacks 1160 * $JIT( { 1161 * async :false, //start out synchronous mode 1162 * listeners: { 1163 * complete: onCompleteFn, 1164 * loadexception: loadExFn 1165 * } 1166 * }, 1167 * 'moduleA', 1168 * progressFn, 1169 * {async:true}, //switch to asynchronous mode 1170 * 'moduleB', 1171 * progressFn, .... ); 1172 * 1173 * //Define logical dependencies: (Adjust to suite your site layout.) 1174 * 1175 * var ux= 'ux/'; 1176 * Ext.apply( $JIT.depends , { 1177 * // JS source file | source location | Dependencies (in required load order) 1178 * 'uxvismode' : {path: ux } 1179 * ,'uxmedia' : {path: ux , depends: [ '@uxvismode']} 1180 * ,'uxflash' : {path: ux , depends: [ '@uxmedia'] } 1181 * ,'uxchart' : {path: ux , depends: [ '@uxflash'] } 1182 * ,'uxfusion' : {path: ux , depends: [ '@uxchart'] } 1183 * ,'uxofc' : {path: ux , depends: [ '@uxchart'] } 1184 * ,'uxamchart' : {path: ux , depends: [ '@uxchart'] } 1185 * ,'uxflex' : {path: ux , depends: [ '@uxflash'] } 1186 * ,'mif' : {path: ux , depends: [ '@uxvismode' ] } 1187 * ,'mifmsg' : {path: ux , depends: [ '@mif'] } 1188 * ,'mifdd' : {path: ux , depends: [ '@mif'] } 1189 * }); 1190 * 1191 * //then, load as assembly: 1192 * $JIT('@uxfusion', callbackFn); 1193 * or 1194 * $JIT.onAvailable('uxfusion', callbackFn); 1195 * 1196 * //$JIT also amends Ext.ComponentMgr to permit inline dynamic (synchronous-only) 1197 * loading of resources when using delayed-loading of Component configurations: 1198 * 1199 * new Ext.Panel({ 1200 * layout:'fit', 1201 * items:{ 1202 * //demand and load 'customerform.js' and 'gmap' modules (if not already available) 1203 * <b>require</b> : ['dialogs/customerform','gmap'], 1204 * xtype : 'tabpanel', 1205 * items : {title:'Grid', <b>JIT:</b>'custom-grid',...} 1206 * } 1207 * }); 1208 * 1209 * Another asynchronous method available is namespace/object polling: 1210 * $JIT('ux/Rowediter'); 1211 * $JIT.onClassAvailable('Ext.ux.grid.RowEditor',function(available){ 1212 if(available){ 1213 var plugin = new Ext.ux.grid.RowEditor().init(this); 1214 ..... 1215 } 1216 }, 1217 myGrid, 1218 30 //second timeout 1219 ); 1220 * 1221 * 1222 * //Load a script via script tag: 1223 * $JIT.script('resources/script/admin[.js]', function(loaded){ ... } ); 1224 * 1225 * //Make an Ajax request 1226 * $JIT.post({params:{node:44}}, 'assets/treenodes.php', 1227 * function(loaded, modules){ 1228 * if(loaded){ 1229 * var nodes = modules.first().content['JSON/text/XML']; 1230 * ... 1231 * } 1232 * }); 1233 * 1234 * //Retrieve the content from a previously loaded (cached) resource: 1235 * var text = $JIT.getModule('treenodes').content.text; 1236 * 1237 * //Load a CSS resource and apply it as a theme: 1238 * $JIT.css('themes/brightblue.css', 'lightgreen.css' ); 1239 * $JIT.onAvailable('brightblue.css', function(loaded){ 1240 * loaded && $JIT.applyStyle('brightblue.css'); 1241 * }); 1242 * //Stylesheet removal: 1243 * $JIT.removeStyle('brightblue.css'); 1244 */ 1245 1246 $JIT = function(){ 1247 var modules = new Array(); 1248 1249 forEach(Array.slice(arguments, 0), 1250 function(module){ 1251 modules = modules.concat(typeof module == 'function' ? module : L.getMap(module) ); 1252 }, L); 1253 L.load.apply(L,modules.flatten()); 1254 return L; 1255 }; 1256 1257 Ext.ux.$JIT = Ext.require = $JIT; 1258 1259 var on = L.addListener.createDelegate(L), 1260 un = L.removeListener.createDelegate(L); 1261 1262 //create a unique flexible dialect for $JIT: 1263 Ext.apply($JIT,{ 1264 1265 /** 1266 * @name onAvailable 1267 * @methodOf $JIT 1268 * Invoke the passed callback when all named modules in the array are available 1269 * @param {Array,String} classList single of Array of string classNames to test. 1270 * @param {Function} callbackFn Callback function invoked with the following arguments:<p> 1271 * {Boolean} success, 1272 * {Array} classes</p> 1273 * @param {Object} scope Scope with call the callback with. 1274 * @param (Integer) timeout Number of seconds to wait before timeout (default 30 seconds) 1275 * @example 1276 $JIT.onAvailable(['tree','grid'], this.buildWin , scope, timeout); 1277 */ 1278 onAvailable : Ext.Loader.onAvailable.createDelegate(L), 1279 1280 /** 1281 * @name onClassAvailable 1282 * @methodOf $JIT 1283 * Invoke the passed callback when all specified class Objects are available. 1284 * @param {Array,String} classList single of Array of string classNames to test. 1285 * @param {Function} callbackFn Callback function invoked with the following arguments:<p> 1286 * {Boolean} success, 1287 * {Array} classes</p> 1288 * @param {Object} scope Scope with call the callback with. 1289 * @param (Integer) timeout Number of seconds to wait before timeout (default 30 seconds) 1290 * @example 1291 $JIT.onClassAvailable('Ext.ux.grid.RowEditor',function(available){ 1292 if(available){ 1293 var plugin = new Ext.ux.grid.RowEditor().init(this); 1294 ..... 1295 } 1189 myGrid, 1190 30 //second timeout 1191 ); 1192 * 1193 * 1194 * //Load a script via script tag: 1195 * $JIT.script('resources/script/admin[.js]', function(loaded){ ... } ); 1196 * 1197 * //Make an Ajax request 1198 * $JIT.post({params:{node:44}}, 'assets/treenodes.php', 1199 * function(loaded, modules){ 1200 * if(loaded){ 1201 * var nodes = modules.first().content['JSON/text/XML']; 1202 * ... 1203 * } 1204 * }); 1205 * 1206 * //Retrieve the content from a previously loaded (cached) resource: 1207 * var text = $JIT.getModule('treenodes').content.text; 1208 * 1209 * //Load a CSS resource and apply it as a theme: 1210 * $JIT.css('themes/brightblue.css', 'lightgreen.css' ); 1211 * $JIT.onAvailable('brightblue.css', function(loaded){ 1212 * loaded && $JIT.applyStyle('brightblue.css'); 1213 * }); 1214 * //Stylesheet removal: 1215 * $JIT.removeStyle('brightblue.css'); 1216 */ 1217 1218 $JIT = function() { 1219 var modules = new Array(); 1220 1221 forEach(Array.slice(arguments, 0), function(module) { 1222 modules = modules.concat(typeof module == 'function' ? module : L.getMap(module)); 1223 }, L); 1224 L.load.apply(L, modules.flatten()); 1225 return L; 1226 }; 1227 1228 Ext.ux.$JIT = Ext.require = $JIT; 1229 1230 var on = L.addListener.createDelegate(L), un = L.removeListener.createDelegate(L); 1231 1232 // create a unique flexible dialect for $JIT: 1233 Ext.apply($JIT, { 1234 1235 /** 1236 * @name onAvailable 1237 * @methodOf $JIT Invoke the passed callback when all named modules in the 1238 * array are available 1239 * @param {Array,String} 1240 * classList single of Array of string classNames to test. 1241 * @param {Function} 1242 * callbackFn Callback function invoked with the following 1243 * arguments: 1244 * <p> 1245 * {Boolean} success, {Array} classes 1246 * </p> 1247 * @param {Object} 1248 * scope Scope with call the callback with. 1249 * @param (Integer) 1250 * timeout Number of seconds to wait before timeout (default 30 1251 * seconds) 1252 * @example 1253 * $JIT.onAvailable(['tree','grid'], this.buildWin , scope, timeout); 1254 */ 1255 onAvailable : Ext.Loader.onAvailable.createDelegate(L), 1256 1257 /** 1258 * @name onClassAvailable 1259 * @methodOf $JIT Invoke the passed callback when all specified class 1260 * Objects are available. 1261 * @param {Array,String} 1262 * classList single of Array of string classNames to test. 1263 * @param {Function} 1264 * callbackFn Callback function invoked with the following 1265 * arguments: 1266 * <p> 1267 * {Boolean} success, {Array} classes 1268 * </p> 1269 * @param {Object} 1270 * scope Scope with call the callback with. 1271 * @param (Integer) 1272 * timeout Number of seconds to wait before timeout (default 30 1273 * seconds) 1274 * @example 1275 * $JIT.onClassAvailable('Ext.ux.grid.RowEditor',function(available){ 1276 if(available){ 1277 var plugin = new Ext.ux.grid.RowEditor().init(this); 1278 ..... 1279 } 1296 1280 }, 1297 1281 myGrid 1298 1282 ); 1299 1300 or 1301 1302 $JIT.onClassAvailable(['Ext.ux.grid.RowEditor','Ext.ux.ManagedIFrame'],classesAreHereFn); 1303 */ 1304 onClassAvailable : (function(){ 1305 1306 var options = null; 1307 1308 var F = function OCAV(classList, callback, scope, timeout) { 1309 var o, 1310 d, 1311 classes=[], 1312 opt = { 1313 interval : 100, 1314 retries : (timeout||30000)/100, 1315 callback : callback || Ext.emptyFn, 1316 scope : scope || null 1317 }; 1318 1319 1320 if(!options){ 1321 options = Ext.clone(opt); 1322 } 1323 1324 Ext.each([].concat(classList||[]).compact(), 1325 function (v) { 1326 if(Ext.isString(v)){ 1327 d = v.split("."); 1328 if(o = window[d[0]]){ 1329 Ext.each(d.slice(1), 1330 function (next) { 1331 return !!(o = o[next]); 1332 }); 1333 o && classes.push(o); 1334 } else return false; 1335 } 1336 }); 1337 1338 //callback with the first Array element if only one 1339 var C = classes.compact(); 1340 C = C.length < 2 ? C.first() : C; 1341 1342 if(!!o){ 1343 options.callback.call(options.scope, true, C); 1344 }else{ 1345 if(--options.retries){ 1346 arguments.callee.defer(options.interval,this,arguments); 1347 return; 1348 } 1349 else { 1350 options.callback.call(options.scope, false, C); 1351 } 1352 } 1353 options = null; 1354 }; 1355 var OCAV = null; 1356 return F; 1357 })(), 1358 1359 //Logical Registration of a module eg: $JIT.provide('mainAppStart'); 1360 provide : Ext.provide = L.provides.createDelegate(L), 1361 1362 on : on, 1363 addListener : on, 1364 un : un, 1365 removeListener : un, 1366 depends : L.depends, 1367 1368 loaded : L.loaded.createDelegate(L), 1369 getModule : L.getModule.createDelegate(L), 1370 1371 1372 //Set the default module retrieval mechanism (DOM == <script, link> tags, GET,PUT,POST == XHR methods ) 1373 setMethod : function(method){ 1374 L.method = (method||'DOM').toUpperCase(); 1375 }, 1376 //Set the default site path (relative/absolute) 1377 setModulePath: function(path){ 1378 L.modulePath = path || ''; 1379 }, 1380 execScript : L.globalEval.createDelegate(L), 1381 lastError : function(){return L.lastError;}, 1382 1383 /** 1384 * @param {Integer} set/change the default onAvailable/load method timeout value in 1385 * milliseconds 1386 */ 1387 setTimeout : function(tmo){ L.timeout = parseInt(tmo||0,10);}, 1388 applyStyle : L.applyStyle.createDelegate(L), 1389 removeStyle : L.removeStyle.createDelegate(L), 1390 1391 css : L.load.createDelegate(L,[ 1392 {method :'GET', 1393 cacheResponses: true, 1394 modulePath :'' 1395 }],0), 1396 1397 script : L.load.createDelegate(L,[ 1398 {method :'DOM', 1399 modulePath :'' 1400 }],0), 1401 1402 get : L.load.createDelegate(L,[ 1403 {method :'GET', 1404 modulePath :'' 1405 }],0), 1406 1407 post : L.load.createDelegate(L,[ 1408 {method :'POST', 1409 modulePath :'' 1410 }],0), 1411 1412 getCached : L.load.createDelegate(L,[ 1413 {method :'GET', 1414 modulePath :'', 1415 cacheResponses: true 1416 }],0) 1283 * 1284 * or 1285 * 1286 * $JIT.onClassAvailable(['Ext.ux.grid.RowEditor','Ext.ux.ManagedIFrame'],classesAreHereFn); 1287 */ 1288 onClassAvailable : (function() { 1289 1290 var options = null; 1291 1292 var F = function OCAV(classList, callback, scope, timeout) { 1293 var o, d, classes = [], opt = { 1294 interval : 100, 1295 retries : (timeout || 30000) / 100, 1296 callback : callback || Ext.emptyFn, 1297 scope : scope || null 1298 }; 1299 1300 if (!options) { 1301 options = Ext.clone(opt); 1302 } 1303 1304 Ext.each([].concat(classList || []).compact(), function(v) { 1305 if (Ext.isString(v)) { 1306 d = v.split("."); 1307 if (o = window[d[0]]) { 1308 Ext.each(d.slice(1), function(next) { 1309 return !!(o = o[next]); 1310 }); 1311 o && classes.push(o); 1312 } else 1313 return false; 1314 } 1315 }); 1316 1317 // callback with the first Array element if only one 1318 var C = classes.compact(); 1319 C = C.length < 2 ? C.first() : C; 1320 1321 if (!!o) { 1322 options.callback.call(options.scope, true, C); 1323 } else { 1324 if (--options.retries) { 1325 arguments.callee.defer(options.interval, this, arguments); 1326 return; 1327 } else { 1328 options.callback.call(options.scope, false, C); 1329 } 1330 } 1331 options = null; 1332 }; 1333 var OCAV = null; 1334 return F; 1335 })(), 1336 1337 // Logical Registration of a module eg: $JIT.provide('mainAppStart'); 1338 provide : Ext.provide = L.provides.createDelegate(L), 1339 1340 on : on, 1341 addListener : on, 1342 un : un, 1343 removeListener : un, 1344 depends : L.depends, 1345 1346 loaded : L.loaded.createDelegate(L), 1347 getModule : L.getModule.createDelegate(L), 1348 1349 // Set the default module retrieval mechanism (DOM == <script, link> tags, 1350 // GET,PUT,POST == XHR methods ) 1351 setMethod : function(method) { 1352 L.method = (method || 'DOM').toUpperCase(); 1353 }, 1354 // Set the default site path (relative/absolute) 1355 setModulePath : function(path) { 1356 L.modulePath = path || ''; 1357 }, 1358 execScript : L.globalEval.createDelegate(L), 1359 lastError : function() { 1360 return L.lastError; 1361 }, 1362 1363 /** 1364 * @param {Integer} 1365 * set/change the default onAvailable/load method timeout value in 1366 * milliseconds 1367 */ 1368 setTimeout : function(tmo) { 1369 L.timeout = parseInt(tmo || 0, 10); 1370 }, 1371 applyStyle : L.applyStyle.createDelegate(L), 1372 removeStyle : L.removeStyle.createDelegate(L), 1373 1374 css : L.load.createDelegate(L, [ 1375 { 1376 method : 'GET', 1377 cacheResponses : true, 1378 modulePath : '' 1379 } 1380 ], 0), 1381 1382 script : L.load.createDelegate(L, [ 1383 { 1384 method : 'DOM', 1385 modulePath : '' 1386 } 1387 ], 0), 1388 1389 get : L.load.createDelegate(L, [ 1390 { 1391 method : 'GET', 1392 modulePath : '' 1393 } 1394 ], 0), 1395 1396 post : L.load.createDelegate(L, [ 1397 { 1398 method : 'POST', 1399 modulePath : '' 1400 } 1401 ], 0), 1402 1403 getCached : L.load.createDelegate(L, [ 1404 { 1405 method : 'GET', 1406 modulePath : '', 1407 cacheResponses : true 1408 } 1409 ], 0) 1410 }); 1411 1412 $JIT.provide('jit', 'ext-basex'); 1413 1414 /* 1415 * 1416 * Sample global loadexception handler 1417 * $JIT.on('loadexception',function(loader, module , ecode, title){ 1418 * 1419 * if(!ecode)return; var ec = ecode.error || ecode; var msg = ec? ec.message || 1420 * ec.description || ec.name || ecode: null; 1421 * 1422 * if(msg){ msg.httpStatusText && ( msg = msg.httpStatus + ' ' + 1423 * msg.httpStatusText); title = title || (module ? 'Error retrieving '+ 1424 * (module.name || module) : ''); if(Ext.MessageBox){ 1425 * Ext.MessageBox.alert(title ,msg); } else { alert((title?title+'\n':'')+msg ); } } 1426 * }); 1427 */ 1428 1429 /* 1430 * Add 'require/JIT' support (synchronous only) permitting progressive loads 1431 * to lazy-loaded component configs new Ext.Panel({ layout:'fit', items:{ 1432 * require : ['tabs','gmap'], //demand and load 'tabs' and 'gmap' module 1433 * configs if not already available xtype : 'tabpanel', items : {title:'Grid', 1434 * JIT:'edit-grid',...} } }); 1435 * 1436 * or 1437 * 1438 * var grid = $JIT.create({ require : [{timeout: 15000}, 'customGrid.js'], 1439 * title : 'User List', .... }); 1440 */ 1441 1442 var mgr = Ext.ComponentMgr, load_options = { 1443 async : false, 1444 method : 'GET', 1445 callback : function(completed) { 1446 !completed && L.fireEvent('loadexception', L, this.currentModule, "Ext.ComponentMgr:$JIT Load Failure"); 1447 }, 1448 scope : L 1449 }, assert = function(rm) { 1450 return !!rm && typeof rm == 'object' ? Ext.apply({}, load_options, rm) : rm; 1451 }; 1452 1453 if (mgr) { 1454 1455 $JIT.create = Ext.create = mgr.create = mgr.create.createInterceptor(function(config, defaultType) { 1456 1457 var require = config.require || config.JIT; 1458 if (!!require) { 1459 require = [ 1460 load_options 1461 ].concat(require).map(assert).compact(); 1462 // This synchronous request will block until completed 1463 Ext.require.apply(Ext, require); 1464 1465 } 1417 1466 }); 1418 1467 1419 $JIT.provide('jit','ext-basex'); 1420 1421 /* 1422 * 1423 Sample global loadexception handler 1424 $JIT.on('loadexception',function(loader, module , ecode, title){ 1425 1426 if(!ecode)return; 1427 var ec = ecode.error || ecode; 1428 var msg = ec? ec.message || ec.description || ec.name || ecode: null; 1429 1430 if(msg){ 1431 msg.httpStatusText && ( msg = msg.httpStatus + ' ' + msg.httpStatusText); 1432 title = title || (module ? 'Error retrieving '+ (module.name || module) : ''); 1433 if(Ext.MessageBox){ 1434 Ext.MessageBox.alert(title ,msg); 1435 } else { 1436 alert((title?title+'\n':'')+msg ); 1437 } 1438 } 1439 }); 1440 */ 1441 1442 /* Add 'require/JIT' support (synchronous only) permitting progressive loads to lazy-loaded component configs 1443 new Ext.Panel({ 1444 layout:'fit', 1445 items:{ 1446 require : ['tabs','gmap'], //demand and load 'tabs' and 'gmap' module configs if not already available 1447 xtype : 'tabpanel', 1448 items : {title:'Grid', JIT:'edit-grid',...} 1449 } 1450 }); 1451 1452 or 1453 1454 var grid = $JIT.create({ 1455 require : [{timeout: 15000}, 'customGrid.js'], 1456 title : 'User List', 1457 .... 1458 }); 1459 */ 1460 1461 var mgr = Ext.ComponentMgr, 1462 load_options = 1463 {async :false, 1464 method :'GET', 1465 callback : function(completed){ 1466 !completed && 1467 L.fireEvent('loadexception', L, this.currentModule, "Ext.ComponentMgr:$JIT Load Failure"); 1468 }, 1469 scope : L 1470 }, 1471 assert = function(rm){ 1472 return !!rm && typeof rm == 'object' ? Ext.apply({},load_options, rm): rm; 1473 }; 1474 1475 if(mgr){ 1476 1477 $JIT.create = 1478 Ext.create = 1479 mgr.create = 1480 mgr.create.createInterceptor( function(config, defaultType){ 1481 1482 var require= config.require || config.JIT; 1483 if(!!require){ 1484 require = [load_options].concat(require).map( assert ).compact(); 1485 //This synchronous request will block until completed 1486 Ext.require.apply(Ext, require); 1487 1488 } 1489 }); 1490 1491 } 1492 1493 1494 })(); 1468 } 1469 1470 })();