1 Ext.BLANK_IMAGE_URL = 'resources/s.gif';
5 ApiPanel = function() {
6 ApiPanel.superclass.constructor.call(this, {
23 loader: new Ext.tree.TreeLoader({
24 preloadChildren: true,
27 root: new Ext.tree.AsyncTreeNode({
31 children:[Docs.classData]
36 //new Ext.tree.TreeSorter(this, {folderSort:true,leafAttr:'isClass'});
38 this.getSelectionModel().on('beforeselect', function(sm, node){
43 Ext.extend(ApiPanel, Ext.tree.TreePanel, {
44 initComponent: function(){
48 new Ext.form.TextField({
50 emptyText:'Find a Class',
51 enableKeyEvents: true,
54 this.filter = new Ext.tree.TreeFilter(this, {
68 iconCls: 'icon-expand-all',
69 tooltip: 'Expand All',
70 handler: function(){ this.root.expand(true); },
73 iconCls: 'icon-collapse-all',
74 tooltip: 'Collapse All',
75 handler: function(){ this.root.collapse(true); },
79 ApiPanel.superclass.initComponent.call(this);
81 filterTree: function(t, e){
82 var text = t.getValue();
83 Ext.each(this.hiddenPkgs, function(n){
92 var re = new RegExp('^' + Ext.escapeRe(text), 'i');
93 this.filter.filterBy(function(n){
94 return !n.attributes.isClass || re.test(n.text);
97 // hide empty packages that weren't filtered
100 this.root.cascade(function(n){
101 if(!n.attributes.isClass && n.ui.ctNode.offsetHeight < 3){
103 me.hiddenPkgs.push(n);
107 selectClass : function(cls){
109 var parts = cls.split('.');
110 var last = parts.length-1;
113 for(var i = 0; i < last; i++){ // things get nasty - static classes can have .
115 var fc = p.charAt(0);
116 var staticCls = fc.toUpperCase() == fc;
117 if(p == 'Ext' || !staticCls){
119 res[i] = 'pkg-'+pkg.join('.');
127 this.selectPath('/root/apidocs/'+res.join('/'));
133 DocPanel = Ext.extend(Ext.Panel, {
137 initComponent : function(){
138 var ps = this.cclass.split('.');
139 this.title = ps[ps.length-1];
142 text: 'Config Options',
143 handler: this.scrollToMember.createDelegate(this, ['configs']),
144 iconCls: 'icon-config'
147 handler: this.scrollToMember.createDelegate(this, ['props']),
151 handler: this.scrollToMember.createDelegate(this, ['methods']),
152 iconCls: 'icon-method'
155 handler: this.scrollToMember.createDelegate(this, ['events']),
156 iconCls: 'icon-event'
159 handler: this.directLink,
163 tooltip:'Hide Inherited Members',
164 iconCls: 'icon-hide-inherited',
167 toggleHandler : function(b, pressed){
168 this.body[pressed ? 'addClass' : 'removeClass']('hide-inherited');
171 tooltip:'Expand All Members',
172 iconCls: 'icon-expand-members',
175 toggleHandler : function(b, pressed){
176 this.body[pressed ? 'addClass' : 'removeClass']('full-details');
180 DocPanel.superclass.initComponent.call(this);
183 directLink : function(){
184 var link = String.format(
185 "<a href=\"{0}\" target=\"_blank\">{0}</a>",
186 document.location.href+'?class='+this.cclass
188 Ext.Msg.alert('Direct Link to ' + this.cclass,link);
191 scrollToMember : function(member){
192 var el = Ext.fly(this.cclass + '-' + member);
194 var top = (el.getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
195 this.body.scrollTo('top', top-25, {duration:0.75, callback: this.hlMember.createDelegate(this, [member])});
199 scrollToSection : function(id){
200 var el = Ext.getDom(id);
202 var top = (Ext.fly(el).getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
203 this.body.scrollTo('top', top-25, {duration:0.5, callback: function(){
204 Ext.fly(el).next('h2').pause(0.2).highlight('#8DB2E3', {attr:'color'});
209 hlMember : function(member){
210 var el = Ext.fly(this.cclass + '-' + member);
212 if (tr = el.up('tr')) {
213 tr.highlight('#cadaf9');
220 MainPanel = function(){
222 this.searchStore = new Ext.data.Store({
223 proxy: new Ext.data.ScriptTagProxy({
224 url: 'http://extjs.com/playpen/api.php'
226 reader: new Ext.data.JsonReader({
229 ['cls', 'member', 'type', 'doc']
233 'beforeload' : function(){
234 this.baseParams.qt = Ext.getCmp('search-type').getValue();
239 MainPanel.superclass.constructor.call(this, {
246 plugins: new Ext.ux.TabCloseMenu(),
247 enableTabScroll: true,
253 autoLoad: {url: 'welcome.html', callback: this.initSearch, scope: this},
258 new Ext.ux.SelectBox({
259 listClass:'x-combo-list-small',
263 store: new Ext.data.SimpleStore({
266 data : ['Starts with', 'Ends with', 'Any match']
270 new Ext.app.SearchField({
272 store: this.searchStore,
280 Ext.extend(MainPanel, Ext.TabPanel, {
282 initEvents : function(){
283 MainPanel.superclass.initEvents.call(this);
284 this.body.on('click', this.onClick, this);
287 onClick: function(e, target){
288 if(target = e.getTarget('a:not(.exi)', 3)){
289 var cls = Ext.fly(target).getAttributeNS('ext', 'cls');
292 var member = Ext.fly(target).getAttributeNS('ext', 'member');
293 this.loadClass(target.href, cls, member);
294 }else if(target.className == 'inner-link'){
295 this.getActiveTab().scrollToSection(target.href.split('#')[1]);
297 window.open(target.href);
299 }else if(target = e.getTarget('.micon', 2)){
301 var tr = Ext.fly(target.parentNode);
302 if(tr.hasClass('expandable')){
303 tr.toggleClass('expanded');
308 loadClass : function(href, cls, member){
309 var id = 'docs-' + cls;
310 var tab = this.getComponent(id);
312 this.setActiveTab(tab);
314 tab.scrollToMember(member);
317 var autoLoad = {url: href};
319 autoLoad.callback = function(){
320 Ext.getCmp(id).scrollToMember(member);
323 var p = this.add(new DocPanel({
327 iconCls: Docs.icons[cls]
329 this.setActiveTab(p);
333 initSearch : function(){
334 // Custom rendering Template for the View
335 var resultTpl = new Ext.XTemplate(
337 '<div class="search-item">',
338 '<a class="member" ext:cls="{cls}" ext:member="{member}" href="output/{cls}.html">',
339 '<img src="../resources/images/default/s.gif" class="item-icon icon-{type}"/>{member}',
341 '<a class="cls" ext:cls="{cls}" href="output/{cls}.html">{cls}</a>',
346 var p = new Ext.DataView({
349 loadingText:'Searching...',
350 store: this.searchStore,
351 itemSelector: 'div.search-item',
352 emptyText: '<h3>Use the search field above to search the Ext API for classes, properties, config options, methods and events.</h3>'
356 doSearch : function(e){
358 if(!e.isSpecialKey()){
359 var text = e.target.value;
361 this.searchStore.baseParams.q = '';
362 this.searchStore.removeAll();
364 this.searchStore.baseParams.q = text;
365 this.searchStore.reload();
372 Ext.onReady(function(){
374 Ext.QuickTips.init();
376 var api = new ApiPanel();
377 var mainPanel = new MainPanel();
379 api.on('click', function(node, e){
382 mainPanel.loadClass(node.attributes.href, node.id);
386 mainPanel.on('tabchange', function(tp, tab){
387 api.selectClass(tab.cclass);
390 var viewport = new Ext.Viewport({
403 api.expandPath('/root/apidocs');
406 var page = window.location.href.split('?')[1];
408 var ps = Ext.urlDecode(page);
409 var cls = ps['class'];
410 mainPanel.loadClass('output/' + cls + '.html', cls, ps.member);
415 setTimeout(function(){
416 Ext.get('loading').remove();
417 Ext.get('loading-mask').fadeOut({remove:true});
423 Ext.app.SearchField = Ext.extend(Ext.form.TwinTriggerField, {
424 initComponent : function(){
425 if(!this.store.baseParams){
426 this.store.baseParams = {};
428 Ext.app.SearchField.superclass.initComponent.call(this);
429 this.on('specialkey', function(f, e){
430 if(e.getKey() == e.ENTER){
431 this.onTrigger2Click();
436 validationEvent:false,
437 validateOnBlur:false,
438 trigger1Class:'x-form-clear-trigger',
439 trigger2Class:'x-form-search-trigger',
445 onTrigger1Click : function(){
447 this.store.baseParams[this.paramName] = '';
448 this.store.removeAll();
449 this.el.dom.value = '';
450 this.triggers[0].hide();
451 this.hasSearch = false;
456 onTrigger2Click : function(){
457 var v = this.getRawValue();
459 this.onTrigger1Click();
463 Ext.Msg.alert('Invalid Search', 'You must enter a minimum of 2 characters to search the API');
466 this.store.baseParams[this.paramName] = v;
468 this.store.reload({params:o});
469 this.hasSearch = true;
470 this.triggers[0].show();
477 * Makes a ComboBox more closely mimic an HTML SELECT. Supports clicking and dragging
478 * through the list, with item selection occurring when the mouse button is released.
479 * When used will automatically set {@link #editable} to false and call {@link Ext.Element#unselectable}
480 * on inner elements. Re-enabling editable after calling this will NOT work.
482 * @author Corey Gilmore
483 * http://extjs.com/forum/showthread.php?t=6392
485 * @history 2007-07-08 jvs
486 * Slight mods for Ext 2.0
488 Ext.ux.SelectBox = function(config){
489 this.searchResetDelay = 1000;
490 config = config || {};
491 config = Ext.apply(config || {}, {
493 forceSelection: true,
495 lastSearchTerm: false,
496 triggerAction: 'all',
500 Ext.ux.SelectBox.superclass.constructor.apply(this, arguments);
502 this.lastSelectedIndex = this.selectedIndex || 0;
505 Ext.extend(Ext.ux.SelectBox, Ext.form.ComboBox, {
507 initEvents : function(){
508 Ext.ux.SelectBox.superclass.initEvents.apply(this, arguments);
509 // you need to use keypress to capture upper/lower case and shift+key, but it doesn't work in IE
510 this.el.on('keydown', this.keySearch, this, true);
511 this.cshTask = new Ext.util.DelayedTask(this.clearSearchHistory, this);
514 keySearch : function(e, target, options) {
515 var raw = e.getKey();
516 var key = String.fromCharCode(raw);
519 if( !this.store.getCount() ) {
524 case Ext.EventObject.HOME:
529 case Ext.EventObject.END:
534 case Ext.EventObject.PAGEDOWN:
535 this.selectNextPage();
539 case Ext.EventObject.PAGEUP:
540 this.selectPrevPage();
545 // skip special keys other than the shift key
546 if( (e.hasModifier() && !e.shiftKey) || e.isNavKeyPress() || e.isSpecialKey() ) {
549 if( this.lastSearchTerm == key ) {
550 startIndex = this.lastSelectedIndex;
552 this.search(this.displayField, key, startIndex);
553 this.cshTask.delay(this.searchResetDelay);
556 onRender : function(ct, position) {
557 this.store.on('load', this.calcRowsPerPage, this);
558 Ext.ux.SelectBox.superclass.onRender.apply(this, arguments);
559 if( this.mode == 'local' ) {
560 this.calcRowsPerPage();
564 onSelect : function(record, index, skipCollapse){
565 if(this.fireEvent('beforeselect', this, record, index) !== false){
566 this.setValue(record.data[this.valueField || this.displayField]);
567 if( !skipCollapse ) {
570 this.lastSelectedIndex = index + 1;
571 this.fireEvent('select', this, record, index);
575 render : function(ct) {
576 Ext.ux.SelectBox.superclass.render.apply(this, arguments);
578 this.el.swallowEvent('mousedown', true);
580 this.el.unselectable();
581 this.innerList.unselectable();
582 this.trigger.unselectable();
583 this.innerList.on('mouseup', function(e, target, options) {
584 if( target.id && target.id == this.innerList.id ) {
590 this.innerList.on('mouseover', function(e, target, options) {
591 if( target.id && target.id == this.innerList.id ) {
594 this.lastSelectedIndex = this.view.getSelectedIndexes()[0] + 1;
595 this.cshTask.delay(this.searchResetDelay);
598 this.trigger.un('click', this.onTriggerClick, this);
599 this.trigger.on('mousedown', function(e, target, options) {
601 this.onTriggerClick();
604 this.on('collapse', function(e, target, options) {
605 Ext.getDoc().un('mouseup', this.collapseIf, this);
608 this.on('expand', function(e, target, options) {
609 Ext.getDoc().on('mouseup', this.collapseIf, this);
613 clearSearchHistory : function() {
614 this.lastSelectedIndex = 0;
615 this.lastSearchTerm = false;
618 selectFirst : function() {
619 this.focusAndSelect(this.store.data.first());
622 selectLast : function() {
623 this.focusAndSelect(this.store.data.last());
626 selectPrevPage : function() {
627 if( !this.rowHeight ) {
630 var index = Math.max(this.selectedIndex-this.rowsPerPage, 0);
631 this.focusAndSelect(this.store.getAt(index));
634 selectNextPage : function() {
635 if( !this.rowHeight ) {
638 var index = Math.min(this.selectedIndex+this.rowsPerPage, this.store.getCount() - 1);
639 this.focusAndSelect(this.store.getAt(index));
642 search : function(field, value, startIndex) {
643 field = field || this.displayField;
644 this.lastSearchTerm = value;
645 var index = this.store.find.apply(this.store, arguments);
647 this.focusAndSelect(index);
651 focusAndSelect : function(record) {
652 var index = typeof record === 'number' ? record : this.store.indexOf(record);
653 this.select(index, this.isExpanded());
654 this.onSelect(this.store.getAt(record), index, this.isExpanded());
657 calcRowsPerPage : function() {
658 if( this.store.getCount() ) {
659 this.rowHeight = Ext.fly(this.view.getNode(0)).getHeight();
660 this.rowsPerPage = this.maxHeight / this.rowHeight;
662 this.rowHeight = false;
668 Ext.Ajax.on('requestcomplete', function(ajax, xhr, o){
669 if(typeof urchinTracker == 'function' && o && o.url){
670 urchinTracker(o.url);