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 initComponent: function(){
47 new Ext.form.TextField({
49 emptyText:'Find a Class',
50 enableKeyEvents: true,
53 this.filter = new Ext.tree.TreeFilter(this, {
67 iconCls: 'icon-expand-all',
68 tooltip: 'Expand All',
69 handler: function(){ this.root.expand(true); },
72 iconCls: 'icon-collapse-all',
73 tooltip: 'Collapse All',
74 handler: function(){ this.root.collapse(true); },
78 ApiPanel.superclass.initComponent.call(this);
80 filterTree: function(t, e){
81 var text = t.getValue();
82 Ext.each(this.hiddenPkgs, function(n){
91 var re = new RegExp('^' + Ext.escapeRe(text), 'i');
92 this.filter.filterBy(function(n){
93 return !n.attributes.isClass || re.test(n.text);
96 // hide empty packages that weren't filtered
98 this.root.cascade(function(n){
99 if(!n.attributes.isClass && n.ui.ctNode.offsetHeight < 3){
101 this.hiddenPkgs.push(n);
105 selectClass : function(cls){
107 var parts = cls.split('.');
108 var last = parts.length-1;
111 for(var i = 0; i < last; i++){ // things get nasty - static classes can have .
113 var fc = p.charAt(0);
114 var staticCls = fc.toUpperCase() == fc;
115 if(p == 'Ext' || !staticCls){
117 res[i] = 'pkg-'+pkg.join('.');
125 this.selectPath('/root/apidocs/'+res.join('/'));
131 DocPanel = Ext.extend(Ext.Panel, {
135 initComponent : function(){
136 var ps = this.cclass.split('.');
137 this.title = ps[ps.length-1];
140 text: 'Config Options',
141 handler: this.scrollToMember.createDelegate(this, ['configs']),
142 iconCls: 'icon-config'
145 handler: this.scrollToMember.createDelegate(this, ['props']),
149 handler: this.scrollToMember.createDelegate(this, ['methods']),
150 iconCls: 'icon-method'
153 handler: this.scrollToMember.createDelegate(this, ['events']),
154 iconCls: 'icon-event'
157 handler: this.directLink,
161 tooltip:'Hide Inherited Members',
162 iconCls: 'icon-hide-inherited',
165 toggleHandler : function(b, pressed){
166 this.body[pressed ? 'addClass' : 'removeClass']('hide-inherited');
169 tooltip:'Expand All Members',
170 iconCls: 'icon-expand-members',
173 toggleHandler : function(b, pressed){
174 this.body[pressed ? 'addClass' : 'removeClass']('full-details');
178 DocPanel.superclass.initComponent.call(this);
181 directLink : function(){
182 var link = String.format(
183 "<a href=\"{0}\" target=\"_blank\">{0}</a>",
184 document.location.href+'?class='+this.cclass
186 Ext.Msg.alert('Direct Link to ' + this.cclass,link);
189 scrollToMember : function(member){
190 var el = Ext.fly(this.cclass + '-' + member);
192 var top = (el.getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
193 this.body.scrollTo('top', top-25, {duration:0.75, callback: this.hlMember.createDelegate(this, [member])});
197 scrollToSection : function(id){
198 var el = Ext.getDom(id);
200 var top = (Ext.fly(el).getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
201 this.body.scrollTo('top', top-25, {duration:0.5, callback: function(){
202 Ext.fly(el).next('h2').pause(0.2).highlight('#8DB2E3', {attr:'color'});
207 hlMember : function(member){
208 var el = Ext.fly(this.cclass + '-' + member);
210 if (tr = el.up('tr')) {
211 tr.highlight('#cadaf9');
218 MainPanel = function(){
220 this.searchStore = new Ext.data.Store({
221 proxy: new Ext.data.ScriptTagProxy({
222 url: 'http://extjs.com/playpen/api.php'
224 reader: new Ext.data.JsonReader({
227 ['cls', 'member', 'type', 'doc']
231 'beforeload' : function(){
232 this.baseParams.qt = Ext.getCmp('search-type').getValue();
237 MainPanel.superclass.constructor.call(this, {
244 plugins: new Ext.ux.TabCloseMenu(),
245 enableTabScroll: true,
251 autoLoad: {url: 'welcome.html', callback: this.initSearch, scope: this},
256 new Ext.ux.SelectBox({
257 listClass:'x-combo-list-small',
261 store: new Ext.data.SimpleStore({
264 data : ['Starts with', 'Ends with', 'Any match']
268 new Ext.app.SearchField({
270 store: this.searchStore,
278 Ext.extend(MainPanel, Ext.TabPanel, {
280 initEvents : function(){
281 MainPanel.superclass.initEvents.call(this);
282 this.body.on('click', this.onClick, this);
285 onClick: function(e, target){
286 if(target = e.getTarget('a:not(.exi)', 3)){
287 var cls = Ext.fly(target).getAttributeNS('ext', 'cls');
290 var member = Ext.fly(target).getAttributeNS('ext', 'member');
291 this.loadClass(target.href, cls, member);
292 }else if(target.className == 'inner-link'){
293 this.getActiveTab().scrollToSection(target.href.split('#')[1]);
295 window.open(target.href);
297 }else if(target = e.getTarget('.micon', 2)){
299 var tr = Ext.fly(target.parentNode);
300 if(tr.hasClass('expandable')){
301 tr.toggleClass('expanded');
306 loadClass : function(href, cls, member){
307 var id = 'docs-' + cls;
308 var tab = this.getComponent(id);
310 this.setActiveTab(tab);
312 tab.scrollToMember(member);
315 var autoLoad = {url: href};
317 autoLoad.callback = function(){
318 Ext.getCmp(id).scrollToMember(member);
321 var p = this.add(new DocPanel({
325 iconCls: Docs.icons[cls]
327 this.setActiveTab(p);
331 initSearch : function(){
332 // Custom rendering Template for the View
333 var resultTpl = new Ext.XTemplate(
335 '<div class="search-item">',
336 '<a class="member" ext:cls="{cls}" ext:member="{member}" href="output/{cls}.html">',
337 '<img src="resources/images/default/s.gif" class="item-icon icon-{type}"/>{member}',
339 '<a class="cls" ext:cls="{cls}" href="output/{cls}.html">{cls}</a>',
344 var p = new Ext.DataView({
347 loadingText:'Searching...',
348 store: this.searchStore,
349 itemSelector: 'div.search-item',
350 emptyText: '<h3>Use the search field above to search the Ext API for classes, properties, config options, methods and events.</h3>'
354 doSearch : function(e){
356 if(!e.isSpecialKey()){
357 var text = e.target.value;
359 this.searchStore.baseParams.q = '';
360 this.searchStore.removeAll();
362 this.searchStore.baseParams.q = text;
363 this.searchStore.reload();
370 Ext.onReady(function(){
372 Ext.QuickTips.init();
374 var api = new ApiPanel();
375 var mainPanel = new MainPanel();
377 api.on('click', function(node, e){
380 mainPanel.loadClass(node.attributes.href, node.id);
384 mainPanel.on('tabchange', function(tp, tab){
385 api.selectClass(tab.cclass);
388 var viewport = new Ext.Viewport({
401 api.expandPath('/root/apidocs');
404 var page = window.location.href.split('?')[1];
406 var ps = Ext.urlDecode(page);
407 var cls = ps['class'];
408 mainPanel.loadClass('output/' + cls + '.html', cls, ps.member);
413 setTimeout(function(){
414 Ext.get('loading').remove();
415 Ext.get('loading-mask').fadeOut({remove:true});
421 Ext.app.SearchField = Ext.extend(Ext.form.TwinTriggerField, {
422 initComponent : function(){
423 if(!this.store.baseParams){
424 this.store.baseParams = {};
426 Ext.app.SearchField.superclass.initComponent.call(this);
427 this.on('specialkey', function(f, e){
428 if(e.getKey() == e.ENTER){
429 this.onTrigger2Click();
434 validationEvent:false,
435 validateOnBlur:false,
436 trigger1Class:'x-form-clear-trigger',
437 trigger2Class:'x-form-search-trigger',
443 onTrigger1Click : function(){
445 this.store.baseParams[this.paramName] = '';
446 this.store.removeAll();
447 this.el.dom.value = '';
448 this.triggers[0].hide();
449 this.hasSearch = false;
454 onTrigger2Click : function(){
455 var v = this.getRawValue();
457 this.onTrigger1Click();
461 Ext.Msg.alert('Invalid Search', 'You must enter a minimum of 2 characters to search the API');
464 this.store.baseParams[this.paramName] = v;
466 this.store.reload({params:o});
467 this.hasSearch = true;
468 this.triggers[0].show();
475 * Makes a ComboBox more closely mimic an HTML SELECT. Supports clicking and dragging
476 * through the list, with item selection occurring when the mouse button is released.
477 * When used will automatically set {@link #editable} to false and call {@link Ext.Element#unselectable}
478 * on inner elements. Re-enabling editable after calling this will NOT work.
480 * @author Corey Gilmore
481 * http://extjs.com/forum/showthread.php?t=6392
483 * @history 2007-07-08 jvs
484 * Slight mods for Ext 2.0
486 Ext.ux.SelectBox = function(config){
487 this.searchResetDelay = 1000;
488 config = config || {};
489 config = Ext.apply(config || {}, {
491 forceSelection: true,
493 lastSearchTerm: false,
494 triggerAction: 'all',
498 Ext.ux.SelectBox.superclass.constructor.apply(this, arguments);
500 this.lastSelectedIndex = this.selectedIndex || 0;
503 Ext.extend(Ext.ux.SelectBox, Ext.form.ComboBox, {
505 initEvents : function(){
506 Ext.ux.SelectBox.superclass.initEvents.apply(this, arguments);
507 // you need to use keypress to capture upper/lower case and shift+key, but it doesn't work in IE
508 this.el.on('keydown', this.keySearch, this, true);
509 this.cshTask = new Ext.util.DelayedTask(this.clearSearchHistory, this);
512 keySearch : function(e, target, options) {
513 var raw = e.getKey();
514 var key = String.fromCharCode(raw);
517 if( !this.store.getCount() ) {
522 case Ext.EventObject.HOME:
527 case Ext.EventObject.END:
532 case Ext.EventObject.PAGEDOWN:
533 this.selectNextPage();
537 case Ext.EventObject.PAGEUP:
538 this.selectPrevPage();
543 // skip special keys other than the shift key
544 if( (e.hasModifier() && !e.shiftKey) || e.isNavKeyPress() || e.isSpecialKey() ) {
547 if( this.lastSearchTerm == key ) {
548 startIndex = this.lastSelectedIndex;
550 this.search(this.displayField, key, startIndex);
551 this.cshTask.delay(this.searchResetDelay);
554 onRender : function(ct, position) {
555 this.store.on('load', this.calcRowsPerPage, this);
556 Ext.ux.SelectBox.superclass.onRender.apply(this, arguments);
557 if( this.mode == 'local' ) {
558 this.calcRowsPerPage();
562 onSelect : function(record, index, skipCollapse){
563 if(this.fireEvent('beforeselect', this, record, index) !== false){
564 this.setValue(record.data[this.valueField || this.displayField]);
565 if( !skipCollapse ) {
568 this.lastSelectedIndex = index + 1;
569 this.fireEvent('select', this, record, index);
573 render : function(ct) {
574 Ext.ux.SelectBox.superclass.render.apply(this, arguments);
576 this.el.swallowEvent('mousedown', true);
578 this.el.unselectable();
579 this.innerList.unselectable();
580 this.trigger.unselectable();
581 this.innerList.on('mouseup', function(e, target, options) {
582 if( target.id && target.id == this.innerList.id ) {
588 this.innerList.on('mouseover', function(e, target, options) {
589 if( target.id && target.id == this.innerList.id ) {
592 this.lastSelectedIndex = this.view.getSelectedIndexes()[0] + 1;
593 this.cshTask.delay(this.searchResetDelay);
596 this.trigger.un('click', this.onTriggerClick, this);
597 this.trigger.on('mousedown', function(e, target, options) {
599 this.onTriggerClick();
602 this.on('collapse', function(e, target, options) {
603 Ext.getDoc().un('mouseup', this.collapseIf, this);
606 this.on('expand', function(e, target, options) {
607 Ext.getDoc().on('mouseup', this.collapseIf, this);
611 clearSearchHistory : function() {
612 this.lastSelectedIndex = 0;
613 this.lastSearchTerm = false;
616 selectFirst : function() {
617 this.focusAndSelect(this.store.data.first());
620 selectLast : function() {
621 this.focusAndSelect(this.store.data.last());
624 selectPrevPage : function() {
625 if( !this.rowHeight ) {
628 var index = Math.max(this.selectedIndex-this.rowsPerPage, 0);
629 this.focusAndSelect(this.store.getAt(index));
632 selectNextPage : function() {
633 if( !this.rowHeight ) {
636 var index = Math.min(this.selectedIndex+this.rowsPerPage, this.store.getCount() - 1);
637 this.focusAndSelect(this.store.getAt(index));
640 search : function(field, value, startIndex) {
641 field = field || this.displayField;
642 this.lastSearchTerm = value;
643 var index = this.store.find.apply(this.store, arguments);
645 this.focusAndSelect(index);
649 focusAndSelect : function(record) {
650 var index = typeof record === 'number' ? record : this.store.indexOf(record);
651 this.select(index, this.isExpanded());
652 this.onSelect(this.store.getAt(record), index, this.isExpanded());
655 calcRowsPerPage : function() {
656 if( this.store.getCount() ) {
657 this.rowHeight = Ext.fly(this.view.getNode(0)).getHeight();
658 this.rowsPerPage = this.maxHeight / this.rowHeight;
660 this.rowHeight = false;
666 Ext.Ajax.on('requestcomplete', function(ajax, xhr, o){
667 if(typeof urchinTracker == 'function' && o && o.url){
668 urchinTracker(o.url);