1 Ext.BLANK_IMAGE_URL = 'resources/s.gif';
5 ApiPanel = function() {
6 ApiPanel.superclass.constructor.call(this, {
22 loader: new Ext.tree.TreeLoader({
23 preloadChildren: true,
26 root: new Ext.tree.AsyncTreeNode({
30 children:[Docs.classData]
35 //new Ext.tree.TreeSorter(this, {folderSort:true,leafAttr:'isClass'});
37 this.getSelectionModel().on('beforeselect', function(sm, node){
42 Ext.extend(ApiPanel, Ext.tree.TreePanel, {
43 selectClass : function(cls){
45 var parts = cls.split('.');
46 var last = parts.length-1;
47 for(var i = 0; i < last; i++){ // things get nasty - static classes can have .
50 var staticCls = fc.toUpperCase() == fc;
51 if(p == 'Ext' || !staticCls){
60 this.selectPath('/root/apidocs/'+parts.join('/'));
66 DocPanel = Ext.extend(Ext.Panel, {
70 initComponent : function(){
71 var ps = this.cclass.split('.');
72 this.title = ps[ps.length-1];
74 DocPanel.superclass.initComponent.call(this);
77 scrollToMember : function(member){
78 var el = Ext.fly(this.cclass + '-' + member);
80 var top = (el.getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
81 this.body.scrollTo('top', top-25, {duration:.75, callback: this.hlMember.createDelegate(this, [member])});
85 scrollToSection : function(id){
86 var el = Ext.getDom(id);
88 var top = (Ext.fly(el).getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
89 this.body.scrollTo('top', top-25, {duration:.5, callback: function(){
90 Ext.fly(el).next('h2').pause(.2).highlight('#8DB2E3', {attr:'color'});
95 hlMember : function(member){
96 var el = Ext.fly(this.cclass + '-' + member);
98 el.up('tr').highlight('#cadaf9');
104 MainPanel = function(){
106 this.searchStore = new Ext.data.Store({
107 proxy: new Ext.data.ScriptTagProxy({
108 url: 'http://extjs.com/playpen/api.php'
110 reader: new Ext.data.JsonReader({
113 ['cls', 'member', 'type', 'doc']
117 'beforeload' : function(){
118 this.baseParams.qt = Ext.getCmp('search-type').getValue();
123 MainPanel.superclass.constructor.call(this, {
130 plugins: new Ext.ux.TabCloseMenu(),
131 enableTabScroll: true,
137 autoLoad: {url: 'welcome.html', callback: this.initSearch, scope: this},
142 new Ext.ux.SelectBox({
143 listClass:'x-combo-list-small',
147 store: new Ext.data.SimpleStore({
150 data : ['Starts with', 'Ends with', 'Any match']
154 new Ext.app.SearchField({
156 store: this.searchStore,
164 Ext.extend(MainPanel, Ext.TabPanel, {
166 initEvents : function(){
167 MainPanel.superclass.initEvents.call(this);
168 this.body.on('click', this.onClick, this);
171 onClick: function(e, target){
172 if(target = e.getTarget('a:not(.exi)', 3)){
173 var cls = Ext.fly(target).getAttributeNS('ext', 'cls');
176 var member = Ext.fly(target).getAttributeNS('ext', 'member');
177 this.loadClass(target.href, cls, member);
178 }else if(target.className == 'inner-link'){
179 this.getActiveTab().scrollToSection(target.href.split('#')[1]);
181 window.open(target.href);
183 }else if(target = e.getTarget('.micon', 2)){
185 var tr = Ext.fly(target.parentNode);
186 if(tr.hasClass('expandable')){
187 tr.toggleClass('expanded');
192 loadClass : function(href, cls, member){
193 var id = 'docs-' + cls;
194 var tab = this.getComponent(id);
196 this.setActiveTab(tab);
198 tab.scrollToMember(member);
201 var autoLoad = {url: href};
203 autoLoad.callback = function(){
204 Ext.getCmp(id).scrollToMember(member);
207 var p = this.add(new DocPanel({
211 iconCls: Docs.icons[cls]
213 this.setActiveTab(p);
217 initSearch : function(){
218 // Custom rendering Template for the View
219 var resultTpl = new Ext.XTemplate(
221 '<div class="search-item">',
222 '<a class="member" ext:cls="{cls}" ext:member="{member}" href="output/{cls}.html">',
223 '<img src="../resources/images/default/s.gif" class="item-icon icon-{type}"/>{member}',
225 '<a class="cls" ext:cls="{cls}" href="output/{cls}.html">{cls}</a>',
230 var p = new Ext.DataView({
233 loadingText:'Searching...',
234 store: this.searchStore,
235 itemSelector: 'div.search-item',
236 emptyText: '<h3>Use the search field above to search the Ext API for classes, properties, config options, methods and events.</h3>'
240 doSearch : function(e){
242 if(!e.isSpecialKey()){
243 var text = e.target.value;
245 this.searchStore.baseParams.q = '';
246 this.searchStore.removeAll();
248 this.searchStore.baseParams.q = text;
249 this.searchStore.reload();
256 Ext.onReady(function(){
258 Ext.QuickTips.init();
260 var api = new ApiPanel();
261 var mainPanel = new MainPanel();
263 api.on('click', function(node, e){
266 mainPanel.loadClass(node.attributes.href, node.id);
270 mainPanel.on('tabchange', function(tp, tab){
271 api.selectClass(tab.cclass);
274 var hd = new Ext.Panel({
289 new Ext.form.TextField({
291 emptyText:'Find a Class',
294 f.el.on('keydown', filterTree, f, {buffer: 350});
299 iconCls: 'icon-expand-all',
300 tooltip: 'Expand All',
301 handler: function(){ api.root.expand(true); }
303 iconCls: 'icon-collapse-all',
304 tooltip: 'Collapse All',
305 handler: function(){ api.root.collapse(true); }
307 tooltip:'Hide Inherited Members',
308 iconCls: 'icon-hide-inherited',
310 toggleHandler : function(b, pressed){
311 mainPanel[pressed ? 'addClass' : 'removeClass']('hide-inherited');
314 tooltip:'Expand All Members',
315 iconCls: 'icon-expand-members',
317 toggleHandler : function(b, pressed){
318 mainPanel[pressed ? 'addClass' : 'removeClass']('full-details');
324 var viewport = new Ext.Viewport({
326 items:[ hd, api, mainPanel ]
329 api.expandPath('/root/apidocs');
332 var page = window.location.href.split('?')[1];
334 var ps = Ext.urlDecode(page);
335 var cls = ps['class'];
336 mainPanel.loadClass('output/' + cls + '.html', cls, ps.member);
341 setTimeout(function(){
342 Ext.get('loading').remove();
343 Ext.get('loading-mask').fadeOut({remove:true});
346 var filter = new Ext.tree.TreeFilter(api, {
351 function filterTree(e){
352 var text = e.target.value;
353 Ext.each(hiddenPkgs, function(n){
362 var re = new RegExp('^' + Ext.escapeRe(text), 'i');
363 filter.filterBy(function(n){
364 return !n.attributes.isClass || re.test(n.text);
367 // hide empty packages that weren't filtered
369 api.root.cascade(function(n){
370 if(!n.attributes.isClass && n.ui.ctNode.offsetHeight < 3){
380 Ext.app.SearchField = Ext.extend(Ext.form.TwinTriggerField, {
381 initComponent : function(){
382 if(!this.store.baseParams){
383 this.store.baseParams = {};
385 Ext.app.SearchField.superclass.initComponent.call(this);
386 this.on('specialkey', function(f, e){
387 if(e.getKey() == e.ENTER){
388 this.onTrigger2Click();
393 validationEvent:false,
394 validateOnBlur:false,
395 trigger1Class:'x-form-clear-trigger',
396 trigger2Class:'x-form-search-trigger',
402 onTrigger1Click : function(){
404 this.store.baseParams[this.paramName] = '';
405 this.store.removeAll();
406 this.el.dom.value = '';
407 this.triggers[0].hide();
408 this.hasSearch = false;
413 onTrigger2Click : function(){
414 var v = this.getRawValue();
416 this.onTrigger1Click();
420 Ext.Msg.alert('Invalid Search', 'You must enter a minimum of 2 characters to search the API');
423 this.store.baseParams[this.paramName] = v;
425 this.store.reload({params:o});
426 this.hasSearch = true;
427 this.triggers[0].show();
434 * Makes a ComboBox more closely mimic an HTML SELECT. Supports clicking and dragging
435 * through the list, with item selection occurring when the mouse button is released.
436 * When used will automatically set {@link #editable} to false and call {@link Ext.Element#unselectable}
437 * on inner elements. Re-enabling editable after calling this will NOT work.
439 * @author Corey Gilmore
440 * http://extjs.com/forum/showthread.php?t=6392
442 * @history 2007-07-08 jvs
443 * Slight mods for Ext 2.0
445 Ext.ux.SelectBox = function(config){
446 this.searchResetDelay = 1000;
447 config = config || {};
448 config = Ext.apply(config || {}, {
450 forceSelection: true,
452 lastSearchTerm: false,
453 triggerAction: 'all',
457 Ext.ux.SelectBox.superclass.constructor.apply(this, arguments);
459 this.lastSelectedIndex = this.selectedIndex || 0;
462 Ext.extend(Ext.ux.SelectBox, Ext.form.ComboBox, {
464 initEvents : function(){
465 Ext.ux.SelectBox.superclass.initEvents.apply(this, arguments);
466 // you need to use keypress to capture upper/lower case and shift+key, but it doesn't work in IE
467 this.el.on('keydown', this.keySearch, this, true);
468 this.cshTask = new Ext.util.DelayedTask(this.clearSearchHistory, this);
471 keySearch : function(e, target, options) {
472 var raw = e.getKey();
473 var key = String.fromCharCode(raw);
476 if( !this.store.getCount() ) {
481 case Ext.EventObject.HOME:
486 case Ext.EventObject.END:
491 case Ext.EventObject.PAGEDOWN:
492 this.selectNextPage();
496 case Ext.EventObject.PAGEUP:
497 this.selectPrevPage();
502 // skip special keys other than the shift key
503 if( (e.hasModifier() && !e.shiftKey) || e.isNavKeyPress() || e.isSpecialKey() ) {
506 if( this.lastSearchTerm == key ) {
507 startIndex = this.lastSelectedIndex;
509 this.search(this.displayField, key, startIndex);
510 this.cshTask.delay(this.searchResetDelay);
513 onRender : function(ct, position) {
514 this.store.on('load', this.calcRowsPerPage, this);
515 Ext.ux.SelectBox.superclass.onRender.apply(this, arguments);
516 if( this.mode == 'local' ) {
517 this.calcRowsPerPage();
521 onSelect : function(record, index, skipCollapse){
522 if(this.fireEvent('beforeselect', this, record, index) !== false){
523 this.setValue(record.data[this.valueField || this.displayField]);
524 if( !skipCollapse ) {
527 this.lastSelectedIndex = index + 1;
528 this.fireEvent('select', this, record, index);
532 render : function(ct) {
533 Ext.ux.SelectBox.superclass.render.apply(this, arguments);
535 this.el.swallowEvent('mousedown', true);
537 this.el.unselectable();
538 this.innerList.unselectable();
539 this.trigger.unselectable();
540 this.innerList.on('mouseup', function(e, target, options) {
541 if( target.id && target.id == this.innerList.id ) {
547 this.innerList.on('mouseover', function(e, target, options) {
548 if( target.id && target.id == this.innerList.id ) {
551 this.lastSelectedIndex = this.view.getSelectedIndexes()[0] + 1;
552 this.cshTask.delay(this.searchResetDelay);
555 this.trigger.un('click', this.onTriggerClick, this);
556 this.trigger.on('mousedown', function(e, target, options) {
558 this.onTriggerClick();
561 this.on('collapse', function(e, target, options) {
562 Ext.getDoc().un('mouseup', this.collapseIf, this);
565 this.on('expand', function(e, target, options) {
566 Ext.getDoc().on('mouseup', this.collapseIf, this);
570 clearSearchHistory : function() {
571 this.lastSelectedIndex = 0;
572 this.lastSearchTerm = false;
575 selectFirst : function() {
576 this.focusAndSelect(this.store.data.first());
579 selectLast : function() {
580 this.focusAndSelect(this.store.data.last());
583 selectPrevPage : function() {
584 if( !this.rowHeight ) {
587 var index = Math.max(this.selectedIndex-this.rowsPerPage, 0);
588 this.focusAndSelect(this.store.getAt(index));
591 selectNextPage : function() {
592 if( !this.rowHeight ) {
595 var index = Math.min(this.selectedIndex+this.rowsPerPage, this.store.getCount() - 1);
596 this.focusAndSelect(this.store.getAt(index));
599 search : function(field, value, startIndex) {
600 field = field || this.displayField;
601 this.lastSearchTerm = value;
602 var index = this.store.find.apply(this.store, arguments);
604 this.focusAndSelect(index);
608 focusAndSelect : function(record) {
609 var index = typeof record === 'number' ? record : this.store.indexOf(record);
610 this.select(index, this.isExpanded());
611 this.onSelect(this.store.getAt(record), index, this.isExpanded());
614 calcRowsPerPage : function() {
615 if( this.store.getCount() ) {
616 this.rowHeight = Ext.fly(this.view.getNode(0)).getHeight();
617 this.rowsPerPage = this.maxHeight / this.rowHeight;
619 this.rowHeight = false;
625 Ext.Ajax.on('requestcomplete', function(ajax, xhr, o){
626 if(typeof urchinTracker == 'function' && o && o.url){
627 urchinTracker(o.url);