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;
49 for(var i = 0; i < last; i++){ // things get nasty - static classes can have .
52 var staticCls = fc.toUpperCase() == fc;
53 if(p == 'Ext' || !staticCls){
55 res[i] = 'pkg-'+pkg.join('.');
63 this.selectPath('/root/apidocs/'+res.join('/'));
69 DocPanel = Ext.extend(Ext.Panel, {
73 initComponent : function(){
74 var ps = this.cclass.split('.');
75 this.title = ps[ps.length-1];
77 DocPanel.superclass.initComponent.call(this);
80 scrollToMember : function(member){
81 var el = Ext.fly(this.cclass + '-' + member);
83 var top = (el.getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
84 this.body.scrollTo('top', top-25, {duration:.75, callback: this.hlMember.createDelegate(this, [member])});
88 scrollToSection : function(id){
89 var el = Ext.getDom(id);
91 var top = (Ext.fly(el).getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
92 this.body.scrollTo('top', top-25, {duration:.5, callback: function(){
93 Ext.fly(el).next('h2').pause(.2).highlight('#8DB2E3', {attr:'color'});
98 hlMember : function(member){
99 var el = Ext.fly(this.cclass + '-' + member);
101 el.up('tr').highlight('#cadaf9');
107 MainPanel = function(){
109 this.searchStore = new Ext.data.Store({
110 proxy: new Ext.data.ScriptTagProxy({
111 url: 'http://extjs.com/playpen/api.php'
113 reader: new Ext.data.JsonReader({
116 ['cls', 'member', 'type', 'doc']
120 'beforeload' : function(){
121 this.baseParams.qt = Ext.getCmp('search-type').getValue();
126 MainPanel.superclass.constructor.call(this, {
133 plugins: new Ext.ux.TabCloseMenu(),
134 enableTabScroll: true,
140 autoLoad: {url: 'welcome.html', callback: this.initSearch, scope: this},
145 new Ext.ux.SelectBox({
146 listClass:'x-combo-list-small',
150 store: new Ext.data.SimpleStore({
153 data : ['Starts with', 'Ends with', 'Any match']
157 new Ext.app.SearchField({
159 store: this.searchStore,
167 Ext.extend(MainPanel, Ext.TabPanel, {
169 initEvents : function(){
170 MainPanel.superclass.initEvents.call(this);
171 this.body.on('click', this.onClick, this);
173 mouseover: this.onMarginEnter,
174 mouseout: this.onMarginLeave,
179 renderTo: document.body,
181 delegate: 'td.micon',
185 // Don't show if you *can't* expand it.
186 beforeshow: function(t) {
187 var tr = Ext.get(t.triggerElement.parentNode);
188 var result = tr.hasClass("expandable");
190 t.body.dom.innerHTML = (tr.hasClass("expanded")) ? "Click to collapse" : "Click to expand";
198 onMarginEnter: function(e) {
199 var t = e.getTarget('td.micon', 2, true);
200 if (t && Ext.fly(t.dom.parentNode).hasClass("expandable")) {
205 onMarginLeave: function(e) {
206 var t = e.getTarget('td.micon', 2, true), toTd = Ext.get(e.getRelatedTarget());
207 if (toTd) toTd = toTd.up('td.micon', 2);
208 if (!toTd || (toTd !== t)) {
209 t.removeClass('over');
213 onClick: function(e, target){
214 if(target = e.getTarget('a:not(.exi)', 3)){
215 var cls = Ext.fly(target).getAttributeNS('ext', 'cls');
218 var member = Ext.fly(target).getAttributeNS('ext', 'member');
219 this.loadClass(target.href, cls, member);
220 }else if(target.className == 'inner-link'){
221 this.getActiveTab().scrollToSection(target.href.split('#')[1]);
223 window.open(target.href);
225 }else if(target = e.getTarget('.micon', 2)){
227 var tr = Ext.fly(target.parentNode);
228 if(tr.hasClass('expandable')){
229 tr.toggleClass('expanded');
234 loadClass : function(href, cls, member){
235 var id = 'docs-' + cls;
236 var tab = this.getComponent(id);
238 this.setActiveTab(tab);
240 tab.scrollToMember(member);
243 var autoLoad = {url: href};
245 autoLoad.callback = function(){
246 Ext.getCmp(id).scrollToMember(member);
249 var p = this.add(new DocPanel({
253 iconCls: Docs.icons[cls]
255 this.setActiveTab(p);
259 initSearch : function(){
260 // Custom rendering Template for the View
261 var resultTpl = new Ext.XTemplate(
263 '<div class="search-item">',
264 '<a class="member" ext:cls="{cls}" ext:member="{member}" href="output/{cls}.html">',
265 '<img src="resources/images/default/s.gif" class="item-icon icon-{type}"/>{member}',
267 '<a class="cls" ext:cls="{cls}" href="output/{cls}.html">{cls}</a>',
272 var p = new Ext.DataView({
275 loadingText:'Searching...',
276 store: this.searchStore,
277 itemSelector: 'div.search-item',
278 emptyText: '<h3>Use the search field above to search the Ext API for classes, properties, config options, methods and events.</h3>'
282 doSearch : function(e){
284 if(!e.isSpecialKey()){
285 var text = e.target.value;
287 this.searchStore.baseParams.q = '';
288 this.searchStore.removeAll();
290 this.searchStore.baseParams.q = text;
291 this.searchStore.reload();
298 Ext.onReady(function(){
300 Ext.QuickTips.init();
302 var api = new ApiPanel();
303 var mainPanel = new MainPanel();
305 api.on('click', function(node, e){
308 mainPanel.loadClass(node.attributes.href, node.id);
312 mainPanel.on('tabchange', function(tp, tab){
313 api.selectClass(tab.cclass);
316 var hd = new Ext.Panel({
331 new Ext.form.TextField({
333 emptyText:'Find a Class',
336 f.el.on('keydown', filterTree, f, {buffer: 350});
341 iconCls: 'icon-expand-all',
342 tooltip: 'Expand All',
343 handler: function(){ api.root.expand(true); }
345 iconCls: 'icon-collapse-all',
346 tooltip: 'Collapse All',
347 handler: function(){ api.root.collapse(true); }
349 tooltip:'Hide Inherited Members',
350 iconCls: 'icon-hide-inherited',
352 toggleHandler : function(b, pressed){
353 mainPanel[pressed ? 'addClass' : 'removeClass']('hide-inherited');
356 tooltip:'Expand All Members',
357 iconCls: 'icon-expand-members',
359 toggleHandler : function(b, pressed){
360 mainPanel[pressed ? 'addClass' : 'removeClass']('full-details');
366 var viewport = new Ext.Viewport({
368 items:[ hd, api, mainPanel ]
371 api.expandPath('/root/apidocs');
374 var page = window.location.href.split('?')[1];
376 var ps = Ext.urlDecode(page);
377 var cls = ps['class'];
378 mainPanel.loadClass('output/' + cls + '.html', cls, ps.member);
383 setTimeout(function(){
384 Ext.get('loading').remove();
385 Ext.get('loading-mask').fadeOut({remove:true});
388 var filter = new Ext.tree.TreeFilter(api, {
393 function filterTree(e){
394 var text = e.target.value;
395 Ext.each(hiddenPkgs, function(n){
404 var re = new RegExp('^' + Ext.escapeRe(text), 'i');
405 filter.filterBy(function(n){
406 return !n.attributes.isClass || re.test(n.text);
409 // hide empty packages that weren't filtered
411 api.root.cascade(function(n){
412 if(!n.attributes.isClass && n.ui.ctNode.offsetHeight < 3){
422 Ext.app.SearchField = Ext.extend(Ext.form.TwinTriggerField, {
423 initComponent : function(){
424 if(!this.store.baseParams){
425 this.store.baseParams = {};
427 Ext.app.SearchField.superclass.initComponent.call(this);
428 this.on('specialkey', function(f, e){
429 if(e.getKey() == e.ENTER){
430 this.onTrigger2Click();
435 validationEvent:false,
436 validateOnBlur:false,
437 trigger1Class:'x-form-clear-trigger',
438 trigger2Class:'x-form-search-trigger',
444 onTrigger1Click : function(){
446 this.store.baseParams[this.paramName] = '';
447 this.store.removeAll();
448 this.el.dom.value = '';
449 this.triggers[0].hide();
450 this.hasSearch = false;
455 onTrigger2Click : function(){
456 var v = this.getRawValue();
458 this.onTrigger1Click();
462 Ext.Msg.alert('Invalid Search', 'You must enter a minimum of 2 characters to search the API');
465 this.store.baseParams[this.paramName] = v;
467 this.store.reload({params:o});
468 this.hasSearch = true;
469 this.triggers[0].show();
476 * Makes a ComboBox more closely mimic an HTML SELECT. Supports clicking and dragging
477 * through the list, with item selection occurring when the mouse button is released.
478 * When used will automatically set {@link #editable} to false and call {@link Ext.Element#unselectable}
479 * on inner elements. Re-enabling editable after calling this will NOT work.
481 * @author Corey Gilmore
482 * http://extjs.com/forum/showthread.php?t=6392
484 * @history 2007-07-08 jvs
485 * Slight mods for Ext 2.0
487 Ext.ux.SelectBox = function(config){
488 this.searchResetDelay = 1000;
489 config = config || {};
490 config = Ext.apply(config || {}, {
492 forceSelection: true,
494 lastSearchTerm: false,
495 triggerAction: 'all',
499 Ext.ux.SelectBox.superclass.constructor.apply(this, arguments);
501 this.lastSelectedIndex = this.selectedIndex || 0;
504 Ext.extend(Ext.ux.SelectBox, Ext.form.ComboBox, {
506 initEvents : function(){
507 Ext.ux.SelectBox.superclass.initEvents.apply(this, arguments);
508 // you need to use keypress to capture upper/lower case and shift+key, but it doesn't work in IE
509 this.el.on('keydown', this.keySearch, this, true);
510 this.cshTask = new Ext.util.DelayedTask(this.clearSearchHistory, this);
513 keySearch : function(e, target, options) {
514 var raw = e.getKey();
515 var key = String.fromCharCode(raw);
518 if( !this.store.getCount() ) {
523 case Ext.EventObject.HOME:
528 case Ext.EventObject.END:
533 case Ext.EventObject.PAGEDOWN:
534 this.selectNextPage();
538 case Ext.EventObject.PAGEUP:
539 this.selectPrevPage();
544 // skip special keys other than the shift key
545 if( (e.hasModifier() && !e.shiftKey) || e.isNavKeyPress() || e.isSpecialKey() ) {
548 if( this.lastSearchTerm == key ) {
549 startIndex = this.lastSelectedIndex;
551 this.search(this.displayField, key, startIndex);
552 this.cshTask.delay(this.searchResetDelay);
555 onRender : function(ct, position) {
556 this.store.on('load', this.calcRowsPerPage, this);
557 Ext.ux.SelectBox.superclass.onRender.apply(this, arguments);
558 if( this.mode == 'local' ) {
559 this.calcRowsPerPage();
563 onSelect : function(record, index, skipCollapse){
564 if(this.fireEvent('beforeselect', this, record, index) !== false){
565 this.setValue(record.data[this.valueField || this.displayField]);
566 if( !skipCollapse ) {
569 this.lastSelectedIndex = index + 1;
570 this.fireEvent('select', this, record, index);
574 render : function(ct) {
575 Ext.ux.SelectBox.superclass.render.apply(this, arguments);
577 this.el.swallowEvent('mousedown', true);
579 this.el.unselectable();
580 this.innerList.unselectable();
581 this.trigger.unselectable();
582 this.innerList.on('mouseup', function(e, target, options) {
583 if( target.id && target.id == this.innerList.id ) {
589 this.innerList.on('mouseover', function(e, target, options) {
590 if( target.id && target.id == this.innerList.id ) {
593 this.lastSelectedIndex = this.view.getSelectedIndexes()[0] + 1;
594 this.cshTask.delay(this.searchResetDelay);
597 this.trigger.un('click', this.onTriggerClick, this);
598 this.trigger.on('mousedown', function(e, target, options) {
600 this.onTriggerClick();
603 this.on('collapse', function(e, target, options) {
604 Ext.getDoc().un('mouseup', this.collapseIf, this);
607 this.on('expand', function(e, target, options) {
608 Ext.getDoc().on('mouseup', this.collapseIf, this);
612 clearSearchHistory : function() {
613 this.lastSelectedIndex = 0;
614 this.lastSearchTerm = false;
617 selectFirst : function() {
618 this.focusAndSelect(this.store.data.first());
621 selectLast : function() {
622 this.focusAndSelect(this.store.data.last());
625 selectPrevPage : function() {
626 if( !this.rowHeight ) {
629 var index = Math.max(this.selectedIndex-this.rowsPerPage, 0);
630 this.focusAndSelect(this.store.getAt(index));
633 selectNextPage : function() {
634 if( !this.rowHeight ) {
637 var index = Math.min(this.selectedIndex+this.rowsPerPage, this.store.getCount() - 1);
638 this.focusAndSelect(this.store.getAt(index));
641 search : function(field, value, startIndex) {
642 field = field || this.displayField;
643 this.lastSearchTerm = value;
644 var index = this.store.find.apply(this.store, arguments);
646 this.focusAndSelect(index);
650 focusAndSelect : function(record) {
651 var index = typeof record === 'number' ? record : this.store.indexOf(record);
652 this.select(index, this.isExpanded());
653 this.onSelect(this.store.getAt(record), index, this.isExpanded());
656 calcRowsPerPage : function() {
657 if( this.store.getCount() ) {
658 this.rowHeight = Ext.fly(this.view.getNode(0)).getHeight();
659 this.rowsPerPage = this.maxHeight / this.rowHeight;
661 this.rowHeight = false;
667 Ext.Ajax.on('requestcomplete', function(ajax, xhr, o){
668 if(typeof urchinTracker == 'function' && o && o.url){
669 urchinTracker(o.url);