debug.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:27k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.1.0
  3.  * Copyright(c) 2006-2009 Ext JS, LLC
  4.  * licensing@extjs.com
  5.  * http://www.extjs.com/license
  6.  */
  7. Ext.debug = {};
  8. (function(){
  9. var cp;
  10. function createConsole(){
  11.     var scriptPanel = new Ext.debug.ScriptsPanel();
  12.     var logView = new Ext.debug.LogPanel();
  13.     var tree = new Ext.debug.DomTree();
  14.     var compInspector = new Ext.debug.ComponentInspector();
  15.     var compInfoPanel = new Ext.debug.ComponentInfoPanel();
  16.     var storeInspector = new Ext.debug.StoreInspector();
  17.     var objInspector = new Ext.debug.ObjectInspector();
  18.     var tabs = new Ext.TabPanel({
  19.         activeTab: 0,
  20.         border: false,
  21.         tabPosition: 'bottom',
  22.         items: [{
  23.             title: 'Debug Console',
  24.             layout:'border',
  25.             items: [logView, scriptPanel]
  26.         },{
  27.             title: 'HTML Inspector',
  28.             layout:'border',
  29.             items: [tree]
  30.         },{
  31.             title: 'Component Inspector',
  32.             layout: 'border',
  33.             items: [compInspector,compInfoPanel]
  34.         },{
  35.             title: 'Object Inspector',
  36.             layout: 'border',
  37.             items: [objInspector]
  38.         },{
  39.             title: 'Data Stores',
  40.             layout: 'border',
  41.             items: [storeInspector]
  42.         }]
  43.     });
  44.     cp = new Ext.Panel({
  45.         id: 'x-debug-browser',
  46.         title: 'Console',
  47.         collapsible: true,
  48.         animCollapse: false,
  49.         style: 'position:absolute;left:0;bottom:0;z-index:101',
  50.         height:200,
  51.         logView: logView,
  52.         layout: 'fit',
  53.         tools:[{
  54.             id: 'close',
  55.             handler: function(){
  56.                 cp.destroy();
  57.                 cp = null;
  58.                 Ext.EventManager.removeResizeListener(handleResize);
  59.             }
  60.         }],
  61.         items: tabs
  62.     });
  63.     cp.render(Ext.getBody());
  64.     cp.resizer = new Ext.Resizable(cp.el, {
  65.         minHeight:50,
  66.         handles: "n",
  67.         pinned: true,
  68.         transparent:true,
  69.         resizeElement : function(){
  70.             var box = this.proxy.getBox();
  71.             this.proxy.hide();
  72.             cp.setHeight(box.height);
  73.             return box;
  74.         }
  75.     });
  76. //     function handleResize(){
  77. //         cp.setWidth(Ext.getBody().getViewSize().width);
  78. //     }
  79. //     Ext.EventManager.onWindowResize(handleResize);
  80. //
  81. //     handleResize();
  82.     function handleResize(){
  83.         var b = Ext.getBody()
  84.         var size = b.getViewSize();
  85.         if(size.height < b.dom.scrollHeight) {
  86.             size.width -= 18;
  87.         }
  88.         cp.setWidth(size.width);
  89.     }
  90.     Ext.EventManager.onWindowResize(handleResize);
  91.     handleResize();
  92. }
  93. Ext.apply(Ext, {
  94.     log : function(){
  95.         if(!cp){
  96.             createConsole();
  97.         }
  98.         cp.logView.log.apply(cp.logView, arguments);
  99.     },
  100.     logf : function(format, arg1, arg2, etc){
  101.         Ext.log(String.format.apply(String, arguments));
  102.     },
  103.     dump : function(o){
  104.         if(typeof o == 'string' || typeof o == 'number' || typeof o == 'undefined' || Ext.isDate(o)){
  105.             Ext.log(o);
  106.         }else if(!o){
  107.             Ext.log("null");
  108.         }else if(typeof o != "object"){
  109.             Ext.log('Unknown return type');
  110.         }else if(Ext.isArray(o)){
  111.             Ext.log('['+o.join(',')+']');
  112.         }else{
  113.             var b = ["{n"];
  114.             for(var key in o){
  115.                 var to = typeof o[key];
  116.                 if(to != "function" && to != "object"){
  117.                     b.push(String.format("  {0}: {1},n", key, o[key]));
  118.                 }
  119.             }
  120.             var s = b.join("");
  121.             if(s.length > 3){
  122.                 s = s.substr(0, s.length-2);
  123.             }
  124.             Ext.log(s + "n}");
  125.         }
  126.     },
  127.     _timers : {},
  128.     time : function(name){
  129.         name = name || "def";
  130.         Ext._timers[name] = new Date().getTime();
  131.     },
  132.     timeEnd : function(name, printResults){
  133.         var t = new Date().getTime();
  134.         name = name || "def";
  135.         var v = String.format("{0} ms", t-Ext._timers[name]);
  136.         Ext._timers[name] = new Date().getTime();
  137.         if(printResults !== false){
  138.             Ext.log('Timer ' + (name == "def" ? v : name + ": " + v));
  139.         }
  140.         return v;
  141.     }
  142. });
  143. })();
  144. Ext.debug.ScriptsPanel = Ext.extend(Ext.Panel, {
  145.     id:'x-debug-scripts',
  146.     region: 'east',
  147.     minWidth: 200,
  148.     split: true,
  149.     width: 350,
  150.     border: false,
  151.     layout:'anchor',
  152.     style:'border-width:0 0 0 1px;',
  153.     initComponent : function(){
  154.         this.scriptField = new Ext.form.TextArea({
  155.             anchor: '100% -26',
  156.             style:'border-width:0;'
  157.         });
  158.         this.trapBox = new Ext.form.Checkbox({
  159.             id: 'console-trap',
  160.             boxLabel: 'Trap Errors',
  161.             checked: true
  162.         });
  163.         this.toolbar = new Ext.Toolbar([{
  164.                 text: 'Run',
  165.                 scope: this,
  166.                 handler: this.evalScript
  167.             },{
  168.                 text: 'Clear',
  169.                 scope: this,
  170.                 handler: this.clear
  171.             },
  172.             '->',
  173.             this.trapBox,
  174.             ' ', ' '
  175.         ]);
  176.         this.items = [this.toolbar, this.scriptField];
  177.         Ext.debug.ScriptsPanel.superclass.initComponent.call(this);
  178.     },
  179.     evalScript : function(){
  180.         var s = this.scriptField.getValue();
  181.         if(this.trapBox.getValue()){
  182.             try{
  183.                 var rt = eval(s);
  184.                 Ext.dump(rt === undefined? '(no return)' : rt);
  185.             }catch(e){
  186.                 Ext.log(e.message || e.descript);
  187.             }
  188.         }else{
  189.             var rt = eval(s);
  190.             Ext.dump(rt === undefined? '(no return)' : rt);
  191.         }
  192.     },
  193.     clear : function(){
  194.         this.scriptField.setValue('');
  195.         this.scriptField.focus();
  196.     }
  197. });
  198. Ext.debug.LogPanel = Ext.extend(Ext.Panel, {
  199.     autoScroll: true,
  200.     region: 'center',
  201.     border: false,
  202.     style:'border-width:0 1px 0 0',
  203.     log : function(){
  204.         var markup = [  '<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
  205.                     Ext.util.Format.htmlEncode(Array.prototype.join.call(arguments, ', ')).replace(/n/g, '<br/>').replace(/s/g, '&#160;'),
  206.                     '</div>'].join(''),
  207.             bd = this.body.dom;
  208.         this.body.insertHtml('beforeend', markup);
  209.         bd.scrollTop = bd.scrollHeight;
  210.     },
  211.     clear : function(){
  212.         this.body.update('');
  213.         this.body.dom.scrollTop = 0;
  214.     }
  215. });
  216. Ext.debug.DomTree = Ext.extend(Ext.tree.TreePanel, {
  217.     enableDD:false ,
  218.     lines:false,
  219.     rootVisible:false,
  220.     animate:false,
  221.     hlColor:'ffff9c',
  222.     autoScroll: true,
  223.     region:'center',
  224.     border:false,
  225.     initComponent : function(){
  226.         Ext.debug.DomTree.superclass.initComponent.call(this);
  227.         // tree related stuff
  228.         var styles = false, hnode;
  229.         var nonSpace = /^s*$/;
  230.         var html = Ext.util.Format.htmlEncode;
  231.         var ellipsis = Ext.util.Format.ellipsis;
  232.         var styleRe = /s?([a-z-]*):([^;]*)(?:[;snr]*)/gi;
  233.         function findNode(n){
  234.             if(!n || n.nodeType != 1 || n == document.body || n == document){
  235.                 return false;
  236.             }
  237.             var pn = [n], p = n;
  238.             while((p = p.parentNode) && p.nodeType == 1 && p.tagName.toUpperCase() != 'HTML'){
  239.                 pn.unshift(p);
  240.             }
  241.             var cn = hnode;
  242.             for(var i = 0, len = pn.length; i < len; i++){
  243.                 cn.expand();
  244.                 cn = cn.findChild('htmlNode', pn[i]);
  245.                 if(!cn){ // in this dialog?
  246.                     return false;
  247.                 }
  248.             }
  249.             cn.select();
  250.             var a = cn.ui.anchor;
  251.             this.getTreeEl().dom.scrollTop = Math.max(0 ,a.offsetTop-10);
  252.             //treeEl.dom.scrollLeft = Math.max(0 ,a.offsetLeft-10); no likey
  253.             cn.highlight();
  254.             return true;
  255.         }
  256.         function nodeTitle(n){
  257.             var s = n.tagName;
  258.             if(n.id){
  259.                 s += '#'+n.id;
  260.             }else if(n.className){
  261.                 s += '.'+n.className;
  262.             }
  263.             return s;
  264.         }
  265.         /*
  266.         function onNodeSelect(t, n, last){
  267.             return;
  268.             if(last && last.unframe){
  269.                 last.unframe();
  270.             }
  271.             var props = {};
  272.             if(n && n.htmlNode){
  273.                 if(frameEl.pressed){
  274.                     n.frame();
  275.                 }
  276.                 if(inspecting){
  277.                     return;
  278.                 }
  279.                 addStyle.enable();
  280.                 reload.setDisabled(n.leaf);
  281.                 var dom = n.htmlNode;
  282.                 stylePanel.setTitle(nodeTitle(dom));
  283.                 if(styles && !showAll.pressed){
  284.                     var s = dom.style ? dom.style.cssText : '';
  285.                     if(s){
  286.                         var m;
  287.                         while ((m = styleRe.exec(s)) != null){
  288.                             props[m[1].toLowerCase()] = m[2];
  289.                         }
  290.                     }
  291.                 }else if(styles){
  292.                     var cl = Ext.debug.cssList;
  293.                     var s = dom.style, fly = Ext.fly(dom);
  294.                     if(s){
  295.                         for(var i = 0, len = cl.length; i<len; i++){
  296.                             var st = cl[i];
  297.                             var v = s[st] || fly.getStyle(st);
  298.                             if(v != undefined && v !== null && v !== ''){
  299.                                 props[st] = v;
  300.                             }
  301.                         }
  302.                     }
  303.                 }else{
  304.                     for(var a in dom){
  305.                         var v = dom[a];
  306.                         if((isNaN(a+10)) && v != undefined && v !== null && v !== '' && !(Ext.isGecko && a[0] == a[0].toUpperCase())){
  307.                             props[a] = v;
  308.                         }
  309.                     }
  310.                 }
  311.             }else{
  312.                 if(inspecting){
  313.                     return;
  314.                 }
  315.                 addStyle.disable();
  316.                 reload.disabled();
  317.             }
  318.             stylesGrid.setSource(props);
  319.             stylesGrid.treeNode = n;
  320.             stylesGrid.view.fitColumns();
  321.         }
  322.         */
  323.         this.loader = new Ext.tree.TreeLoader();
  324.         this.loader.load = function(n, cb){
  325.             var isBody = n.htmlNode == document.body;
  326.             var cn = n.htmlNode.childNodes;
  327.             for(var i = 0, c; c = cn[i]; i++){
  328.                 if(isBody && c.id == 'x-debug-browser'){
  329.                     continue;
  330.                 }
  331.                 if(c.nodeType == 1){
  332.                     n.appendChild(new Ext.debug.HtmlNode(c));
  333.                 }else if(c.nodeType == 3 && !nonSpace.test(c.nodeValue)){
  334.                     n.appendChild(new Ext.tree.TreeNode({
  335.                         text:'<em>' + ellipsis(html(String(c.nodeValue)), 35) + '</em>',
  336.                         cls: 'x-tree-noicon'
  337.                     }));
  338.                 }
  339.             }
  340.             cb();
  341.         };
  342.         //tree.getSelectionModel().on('selectionchange', onNodeSelect, null, {buffer:250});
  343.         this.root = this.setRootNode(new Ext.tree.TreeNode('Ext'));
  344.         hnode = this.root.appendChild(new Ext.debug.HtmlNode(
  345.                 document.getElementsByTagName('html')[0]
  346.         ));
  347.     }
  348. });
  349. Ext.debug.ComponentNodeUI = Ext.extend(Ext.tree.TreeNodeUI,{
  350.     onOver : function(e){
  351.         Ext.debug.ComponentNodeUI.superclass.onOver.call(this);
  352.         var cmp = this.node.attributes.component;
  353.         if (cmp.el && cmp.el.mask && cmp.id !='x-debug-browser') {
  354.             try { // Oddly bombs on some elements in IE, gets any we care about though
  355.                 cmp.el.mask();
  356.             } catch(e) {}
  357.         }
  358.     },
  359.     onOut : function(e){
  360.         Ext.debug.ComponentNodeUI.superclass.onOut.call(this);
  361.         var cmp = this.node.attributes.component;
  362.         if (cmp.el && cmp.el.unmask && cmp.id !='x-debug-browser') {
  363.             try {
  364.                 cmp.el.unmask();
  365.             } catch(e) {}
  366.         }
  367.     }
  368. });
  369. Ext.debug.ComponentInspector = Ext.extend(Ext.tree.TreePanel, {
  370.     enableDD:false ,
  371.     lines:false,
  372.     rootVisible:false,
  373.     animate:false,
  374.     hlColor:'ffff9c',
  375.     autoScroll: true,
  376.     region:'center',
  377.     border:false,
  378.     initComponent : function(){
  379.         this.loader = new Ext.tree.TreeLoader();
  380.         this.bbar = new Ext.Toolbar([{
  381.             text: 'Refresh',
  382.             handler: this.refresh,
  383.             scope: this
  384.         }]);
  385.         Ext.debug.ComponentInspector.superclass.initComponent.call(this);
  386.         this.root = this.setRootNode(new Ext.tree.TreeNode({
  387.             text: 'Ext Components',
  388.             component: Ext.ComponentMgr.all,
  389.             leaf: false
  390.         }));
  391.         this.parseRootNode();
  392.         this.on('click', this.onClick, this);
  393.     },
  394.     createNode: function(n,c) {
  395.         var leaf = (c.items && c.items.length > 0);
  396.         return n.appendChild(new Ext.tree.TreeNode({
  397.             text: c.id + (c.getXType() ? ' [ ' + c.getXType() + ' ]': '' ),
  398.             component: c,
  399.             uiProvider:Ext.debug.ComponentNodeUI,
  400.             leaf: !leaf
  401.         }));
  402.     },
  403.     parseChildItems: function(n) {
  404.         var cn = n.attributes.component.items;
  405.         if (cn) {
  406.             for (var i = 0;i < cn.length; i++) {
  407.                 var c = cn.get(i);
  408.                 if (c.id != this.id && c.id != this.bottomToolbar.id) {
  409.                     var newNode = this.createNode(n,c);
  410.                     if (!newNode.leaf) {
  411.                         this.parseChildItems(newNode)
  412.                     }
  413.                 }
  414.             }
  415.         }
  416.     },
  417.     parseRootNode: function() {
  418.         var n = this.root;
  419.         var cn = n.attributes.component.items;
  420.         for (var i = 0,c;c = cn[i];i++) {
  421.             if (c.id != this.id && c.id != this.bottomToolbar.id) {
  422.                 if (!c.ownerCt) {
  423.                     var newNode = this.createNode(n,c);
  424.                     if (!newNode.leaf) {
  425.                         this.parseChildItems(newNode);
  426.                     }
  427.                 }
  428.             }
  429.         }
  430.     },
  431.     onClick: function(node, e) {
  432.         var oi = Ext.getCmp('x-debug-objinspector');
  433.         oi.refreshNodes(node.attributes.component);
  434.         oi.ownerCt.show();
  435.     },
  436.     refresh: function() {
  437.         while (this.root.firstChild) {
  438.             this.root.removeChild(this.root.firstChild);
  439.         }
  440.         this.parseRootNode();
  441.         var ci = Ext.getCmp('x-debug-compinfo');
  442.         if (ci) {
  443.             ci.message('refreshed component tree - '+Ext.ComponentMgr.all.length)
  444.         }
  445.     }
  446. });
  447. Ext.debug.ComponentInfoPanel = Ext.extend(Ext.Panel,{
  448.     id:'x-debug-compinfo',
  449.     region: 'east',
  450.     minWidth: 200,
  451.     split: true,
  452.     width: 350,
  453.     border: false,
  454.     autoScroll: true,
  455.     layout:'anchor',
  456.     style:'border-width:0 0 0 1px;',
  457.     initComponent: function() {
  458.         this.watchBox = new Ext.form.Checkbox({
  459.             id: 'x-debug-watchcomp',
  460.             boxLabel: 'Watch ComponentMgr',
  461.             listeners: {
  462.                 check: function(cb, val) {
  463.                     if (val) {
  464.                         Ext.ComponentMgr.all.on('add', this.onAdd, this);
  465.                         Ext.ComponentMgr.all.on('remove', this.onRemove, this);
  466.                     } else {
  467.                         Ext.ComponentMgr.all.un('add', this.onAdd, this);
  468.                         Ext.ComponentMgr.all.un('remove', this.onRemove, this);
  469.                     }
  470.                 },
  471.                 scope: this
  472.             }
  473.         });
  474.         this.tbar = new Ext.Toolbar([{
  475.             text: 'Clear',
  476.             handler: this.clear,
  477.             scope: this
  478.         },'->',this.watchBox
  479.         ]);
  480.         Ext.debug.ComponentInfoPanel.superclass.initComponent.call(this);
  481.     },
  482.     onAdd: function(i, o, key) {
  483.         var markup = ['<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
  484.                     'Added: '+o.id,
  485.                     '</div>'].join('');
  486.         this.insertMarkup(markup);
  487.     },
  488.     onRemove: function(o, key) {
  489.         var markup = ['<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
  490.                     'Removed: '+o.id,
  491.                     '</div>'].join('');
  492.         this.insertMarkup(markup);
  493.     },
  494.     message: function(msg) {
  495.         var markup = ['<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
  496.                     msg,
  497.                     '</div>'].join('');
  498.         this.insertMarkup(markup);
  499.     },
  500.     insertMarkup: function(markup) {
  501.         this.body.insertHtml('beforeend', markup);
  502.         this.body.scrollTo('top', 100000);
  503.     },
  504.     clear : function(){
  505.         this.body.update('');
  506.         this.body.dom.scrollTop = 0;
  507.     }
  508. });
  509. Ext.debug.ColumnNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
  510.     focus: Ext.emptyFn, // prevent odd scrolling behavior
  511.     renderElements : function(n, a, targetNode, bulkRender){
  512.         this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
  513.         var t = n.getOwnerTree();
  514.         var cols = t.columns;
  515.         var bw = t.borderWidth;
  516.         var c = cols[0];
  517.         var buf = [
  518.              '<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf ', a.cls,'">',
  519.                 '<div class="x-tree-col" style="width:',c.width-bw,'px;">',
  520.                     '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
  521.                     '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow"/>',
  522.                     '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on"/>',
  523.                     '<a hidefocus="on" class="x-tree-node-anchor" href="',a.href ? a.href : "#",'" tabIndex="1" ',
  524.                     a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '>',
  525.                     '<span unselectable="on">', n.text || (c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]),"</span></a>",
  526.                 "</div>"];
  527.          for(var i = 1, len = cols.length; i < len; i++){
  528.              c = cols[i];
  529.              buf.push('<div class="x-tree-col ',(c.cls?c.cls:''),'" style="width:',c.width-bw,'px;">',
  530.                         '<div class="x-tree-col-text">',(c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]),"</div>",
  531.                       "</div>");
  532.          }
  533.          buf.push(
  534.             '<div class="x-clear"></div></div>',
  535.             '<ul class="x-tree-node-ct" style="display:none;"></ul>',
  536.             "</li>");
  537.         if(bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()){
  538.             this.wrap = Ext.DomHelper.insertHtml("beforeBegin",
  539.                                 n.nextSibling.ui.getEl(), buf.join(""));
  540.         }else{
  541.             this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf.join(""));
  542.         }
  543.         this.elNode = this.wrap.childNodes[0];
  544.         this.ctNode = this.wrap.childNodes[1];
  545.         var cs = this.elNode.firstChild.childNodes;
  546.         this.indentNode = cs[0];
  547.         this.ecNode = cs[1];
  548.         this.iconNode = cs[2];
  549.         this.anchor = cs[3];
  550.         this.textNode = cs[3].firstChild;
  551.     }
  552. });
  553. Ext.debug.ObjectInspector = Ext.extend(Ext.tree.TreePanel, {
  554.     id: 'x-debug-objinspector',
  555.     enableDD:false ,
  556.     lines:false,
  557.     rootVisible:false,
  558.     animate:false,
  559.     hlColor:'ffff9c',
  560.     autoScroll: true,
  561.     region:'center',
  562.     border:false,
  563.     lines:false,
  564.     borderWidth: Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell
  565.     cls:'x-column-tree',
  566.     initComponent : function(){
  567.         this.showFunc = false;
  568.         this.toggleFunc = function() {
  569.             this.showFunc = !this.showFunc;
  570.             this.refreshNodes(this.currentObject);
  571.         }
  572.         this.bbar = new Ext.Toolbar([{
  573.             text: 'Show Functions',
  574.             enableToggle: true,
  575.             pressed: false,
  576.             handler: this.toggleFunc,
  577.             scope: this
  578.         }]);
  579.         Ext.apply(this,{
  580.             title: ' ',
  581.             loader: new Ext.tree.TreeLoader(),
  582.             columns:[{
  583.                 header:'Property',
  584.                 width: 300,
  585.                 dataIndex:'name'
  586.             },{
  587.                 header:'Value',
  588.                 width: 900,
  589.                 dataIndex:'value'
  590.             }]
  591.         });
  592.         Ext.debug.ObjectInspector.superclass.initComponent.call(this);
  593.         this.root = this.setRootNode(new Ext.tree.TreeNode({
  594.             text: 'Dummy Node',
  595.             leaf: false
  596.         }));
  597.         if (this.currentObject) {
  598.             this.parseNodes();
  599.         }
  600.     },
  601.     refreshNodes: function(newObj) {
  602.         this.currentObject = newObj;
  603.         var node = this.root;
  604.         while(node.firstChild){
  605.             node.removeChild(node.firstChild);
  606.         }
  607.         this.parseNodes();
  608.     },
  609.     parseNodes: function() {
  610.         for (var o in this.currentObject) {
  611.             if (!this.showFunc) {
  612.                 if (Ext.isFunction(this.currentObject[o])) {
  613.                     continue;
  614.                 }
  615.             }
  616.             this.createNode(o);
  617.         }
  618.     },
  619.     createNode: function(o) {
  620.         return this.root.appendChild(new Ext.tree.TreeNode({
  621.             name: o,
  622.             value: this.currentObject[o],
  623.             uiProvider:Ext.debug.ColumnNodeUI,
  624.             iconCls: 'x-debug-node',
  625.             leaf: true
  626.         }));
  627.     },
  628.     onRender : function(){
  629.         Ext.debug.ObjectInspector.superclass.onRender.apply(this, arguments);
  630.         this.headers = this.header.createChild({cls:'x-tree-headers'});
  631.         var cols = this.columns, c;
  632.         var totalWidth = 0;
  633.         for(var i = 0, len = cols.length; i < len; i++){
  634.              c = cols[i];
  635.              totalWidth += c.width;
  636.              this.headers.createChild({
  637.                  cls:'x-tree-hd ' + (c.cls?c.cls+'-hd':''),
  638.                  cn: {
  639.                      cls:'x-tree-hd-text',
  640.                      html: c.header
  641.                  },
  642.                  style:'width:'+(c.width-this.borderWidth)+'px;'
  643.              });
  644.         }
  645.         this.headers.createChild({cls:'x-clear'});
  646.         // prevent floats from wrapping when clipped
  647.         this.headers.setWidth(totalWidth);
  648.         this.innerCt.setWidth(totalWidth);
  649.     }
  650. });
  651. Ext.debug.StoreInspector = Ext.extend(Ext.tree.TreePanel, {
  652.     enableDD:false ,
  653.     lines:false,
  654.     rootVisible:false,
  655.     animate:false,
  656.     hlColor:'ffff9c',
  657.     autoScroll: true,
  658.     region:'center',
  659.     border:false,
  660.     initComponent: function() {
  661.         this.bbar = new Ext.Toolbar([{
  662.             text: 'Refresh',
  663.             handler: this.refresh,
  664.             scope: this
  665.         }]);
  666.         Ext.debug.StoreInspector.superclass.initComponent.call(this);
  667.         this.root = this.setRootNode(new Ext.tree.TreeNode({
  668.             text: 'Data Stores',
  669.             leaf: false
  670.         }));
  671.         this.on('click', this.onClick, this);
  672.         this.parseStores();
  673.     },
  674.     parseStores: function() {
  675.         var cn = Ext.StoreMgr.items;
  676.         for (var i = 0,c;c = cn[i];i++) {
  677.             this.root.appendChild({
  678.                 text: c.storeId + ' - ' + c.totalLength + ' records',
  679.                 component: c,
  680.                 leaf: true
  681.             });
  682.         }
  683.     },
  684.     onClick: function(node, e) {
  685.         var oi = Ext.getCmp('x-debug-objinspector');
  686.         oi.refreshNodes(node.attributes.component);
  687.         oi.ownerCt.show();
  688.     },
  689.     refresh: function() {
  690.         while (this.root.firstChild) {
  691.             this.root.removeChild(this.root.firstChild);
  692.         }
  693.         this.parseStores();
  694.     }
  695. });
  696. // highly unusual class declaration
  697. Ext.debug.HtmlNode = function(){
  698.     var html = Ext.util.Format.htmlEncode;
  699.     var ellipsis = Ext.util.Format.ellipsis;
  700.     var nonSpace = /^s*$/;
  701.     var attrs = [
  702.         {n: 'id', v: 'id'},
  703.         {n: 'className', v: 'class'},
  704.         {n: 'name', v: 'name'},
  705.         {n: 'type', v: 'type'},
  706.         {n: 'src', v: 'src'},
  707.         {n: 'href', v: 'href'}
  708.     ];
  709.     function hasChild(n){
  710.         for(var i = 0, c; c = n.childNodes[i]; i++){
  711.             if(c.nodeType == 1){
  712.                 return true;
  713.             }
  714.         }
  715.         return false;
  716.     }
  717.     function renderNode(n, leaf){
  718.         var tag = n.tagName.toLowerCase();
  719.         var s = '&lt;' + tag;
  720.         for(var i = 0, len = attrs.length; i < len; i++){
  721.             var a = attrs[i];
  722.             var v = n[a.n];
  723.             if(v && !nonSpace.test(v)){
  724.                 s += ' ' + a.v + '=&quot;<i>' + html(v) +'</i>&quot;';
  725.             }
  726.         }
  727.         var style = n.style ? n.style.cssText : '';
  728.         if(style){
  729.             s += ' style=&quot;<i>' + html(style.toLowerCase()) +'</i>&quot;';
  730.         }
  731.         if(leaf && n.childNodes.length > 0){
  732.             s+='&gt;<em>' + ellipsis(html(String(n.innerHTML)), 35) + '</em>&lt;/'+tag+'&gt;';
  733.         }else if(leaf){
  734.             s += ' /&gt;';
  735.         }else{
  736.             s += '&gt;';
  737.         }
  738.         return s;
  739.     }
  740.     var HtmlNode = function(n){
  741.         var leaf = !hasChild(n);
  742.         this.htmlNode = n;
  743.         this.tagName = n.tagName.toLowerCase();
  744.         var attr = {
  745.             text : renderNode(n, leaf),
  746.             leaf : leaf,
  747.             cls: 'x-tree-noicon'
  748.         };
  749.         HtmlNode.superclass.constructor.call(this, attr);
  750.         this.attributes.htmlNode = n; // for searching
  751.         if(!leaf){
  752.             this.on('expand', this.onExpand,  this);
  753.             this.on('collapse', this.onCollapse,  this);
  754.         }
  755.     };
  756.     Ext.extend(HtmlNode, Ext.tree.AsyncTreeNode, {
  757.         cls: 'x-tree-noicon',
  758.         preventHScroll: true,
  759.         refresh : function(highlight){
  760.             var leaf = !hasChild(this.htmlNode);
  761.             this.setText(renderNode(this.htmlNode, leaf));
  762.             if(highlight){
  763.                 Ext.fly(this.ui.textNode).highlight();
  764.             }
  765.         },
  766.         onExpand : function(){
  767.             if(!this.closeNode && this.parentNode){
  768.                 this.closeNode = this.parentNode.insertBefore(new Ext.tree.TreeNode({
  769.                     text:'&lt;/' + this.tagName + '&gt;',
  770.                     cls: 'x-tree-noicon'
  771.                 }), this.nextSibling);
  772.             }else if(this.closeNode){
  773.                 this.closeNode.ui.show();
  774.             }
  775.         },
  776.         onCollapse : function(){
  777.             if(this.closeNode){
  778.                 this.closeNode.ui.hide();
  779.             }
  780.         },
  781.         render : function(bulkRender){
  782.             HtmlNode.superclass.render.call(this, bulkRender);
  783.         },
  784.         highlightNode : function(){
  785.             //Ext.fly(this.htmlNode).highlight();
  786.         },
  787.         highlight : function(){
  788.             //Ext.fly(this.ui.textNode).highlight();
  789.         },
  790.         frame : function(){
  791.             this.htmlNode.style.border = '1px solid #0000ff';
  792.             //this.highlightNode();
  793.         },
  794.         unframe : function(){
  795.             //Ext.fly(this.htmlNode).removeClass('x-debug-frame');
  796.             this.htmlNode.style.border = '';
  797.         }
  798.     });
  799.     return HtmlNode;
  800. }();