Ext.debug = {};
(function(){
var cp;
function createConsole(){
var scriptPanel = new Ext.debug.ScriptsPanel();
var logView = new Ext.debug.LogPanel();
var tree = new Ext.debug.DomTree();
var compInspector = new Ext.debug.ComponentInspector();
var compInfoPanel = new Ext.debug.ComponentInfoPanel();
var storeInspector = new Ext.debug.StoreInspector();
var objInspector = new Ext.debug.ObjectInspector();
var tabs = new Ext.TabPanel({
activeTab: 0,
border: false,
tabPosition: 'bottom',
items: [{
title: 'Debug Console',
layout:'border',
items: [logView, scriptPanel]
},{
title: 'HTML Inspector',
layout:'border',
items: [tree]
},{
title: 'Component Inspector',
layout: 'border',
items: [compInspector,compInfoPanel]
},{
title: 'Object Inspector',
layout: 'border',
items: [objInspector]
},{
title: 'Data Stores',
layout: 'border',
items: [storeInspector]
}]
});
cp = new Ext.Panel({
id: 'x-debug-browser',
title: 'Console',
collapsible: true,
animCollapse: false,
style: 'position:absolute;left:0;bottom:0;z-index:101',
height:200,
logView: logView,
layout: 'fit',
tools:[{
id: 'close',
handler: function(){
cp.destroy();
cp = null;
Ext.EventManager.removeResizeListener(handleResize);
}
}],
items: tabs
});
cp.render(Ext.getBody());
cp.resizer = new Ext.Resizable(cp.el, {
minHeight:50,
handles: "n",
pinned: true,
transparent:true,
resizeElement : function(){
var box = this.proxy.getBox();
this.proxy.hide();
cp.setHeight(box.height);
return box;
}
});
// function handleResize(){
// cp.setWidth(Ext.getBody().getViewSize().width);
// }
// Ext.EventManager.onWindowResize(handleResize);
//
// handleResize();
function handleResize(){
var b = Ext.getBody()
var size = b.getViewSize();
if(size.height < b.dom.scrollHeight) {
size.width -= 18;
}
cp.setWidth(size.width);
}
Ext.EventManager.onWindowResize(handleResize);
handleResize();
}
Ext.apply(Ext, {
log : function(){
if(!cp){
createConsole();
}
cp.logView.log.apply(cp.logView, arguments);
},
logf : function(format, arg1, arg2, etc){
Ext.log(String.format.apply(String, arguments));
},
dump : function(o){
if(typeof o == 'string' || typeof o == 'number' || typeof o == 'undefined' || Ext.isDate(o)){
Ext.log(o);
}else if(!o){
Ext.log("null");
}else if(typeof o != "object"){
Ext.log('Unknown return type');
}else if(Ext.isArray(o)){
Ext.log('['+o.join(',')+']');
}else{
var b = ["{\n"];
for(var key in o){
var to = typeof o[key];
if(to != "function" && to != "object"){
b.push(String.format(" {0}: {1},\n", key, o[key]));
}
}
var s = b.join("");
if(s.length > 3){
s = s.substr(0, s.length-2);
}
Ext.log(s + "\n}");
}
},
_timers : {},
time : function(name){
name = name || "def";
Ext._timers[name] = new Date().getTime();
},
timeEnd : function(name, printResults){
var t = new Date().getTime();
name = name || "def";
var v = String.format("{0} ms", t-Ext._timers[name]);
Ext._timers[name] = new Date().getTime();
if(printResults !== false){
Ext.log('Timer ' + (name == "def" ? v : name + ": " + v));
}
return v;
}
});
})();
Ext.debug.ScriptsPanel = Ext.extend(Ext.Panel, {
id:'x-debug-scripts',
region: 'east',
minWidth: 200,
split: true,
width: 350,
border: false,
layout:'anchor',
style:'border-width:0 0 0 1px;',
initComponent : function(){
this.scriptField = new Ext.form.TextArea({
anchor: '100% -26',
style:'border-width:0;'
});
this.trapBox = new Ext.form.Checkbox({
id: 'console-trap',
boxLabel: 'Trap Errors',
checked: true
});
this.toolbar = new Ext.Toolbar([{
text: 'Run',
scope: this,
handler: this.evalScript
},{
text: 'Clear',
scope: this,
handler: this.clear
},
'->',
this.trapBox,
' ', ' '
]);
this.items = [this.toolbar, this.scriptField];
Ext.debug.ScriptsPanel.superclass.initComponent.call(this);
},
evalScript : function(){
var s = this.scriptField.getValue();
if(this.trapBox.getValue()){
try{
var rt = eval(s);
Ext.dump(rt === undefined? '(no return)' : rt);
}catch(e){
Ext.log(e.message || e.descript);
}
}else{
var rt = eval(s);
Ext.dump(rt === undefined? '(no return)' : rt);
}
},
clear : function(){
this.scriptField.setValue('');
this.scriptField.focus();
}
});
Ext.debug.LogPanel = Ext.extend(Ext.Panel, {
autoScroll: true,
region: 'center',
border: false,
style:'border-width:0 1px 0 0',
log : function(){
var markup = [ '',
Ext.util.Format.htmlEncode(Array.prototype.join.call(arguments, ', ')).replace(/\n/g, '
').replace(/\s/g, ' '),
'
'].join('');
this.body.insertHtml('beforeend', markup);
this.body.scrollTo('top', 100000);
},
clear : function(){
this.body.update('');
this.body.dom.scrollTop = 0;
}
});
Ext.debug.DomTree = Ext.extend(Ext.tree.TreePanel, {
enableDD:false ,
lines:false,
rootVisible:false,
animate:false,
hlColor:'ffff9c',
autoScroll: true,
region:'center',
border:false,
initComponent : function(){
Ext.debug.DomTree.superclass.initComponent.call(this);
// tree related stuff
var styles = false, hnode;
var nonSpace = /^\s*$/;
var html = Ext.util.Format.htmlEncode;
var ellipsis = Ext.util.Format.ellipsis;
var styleRe = /\s?([a-z\-]*)\:([^;]*)(?:[;\s\n\r]*)/gi;
function findNode(n){
if(!n || n.nodeType != 1 || n == document.body || n == document){
return false;
}
var pn = [n], p = n;
while((p = p.parentNode) && p.nodeType == 1 && p.tagName.toUpperCase() != 'HTML'){
pn.unshift(p);
}
var cn = hnode;
for(var i = 0, len = pn.length; i < len; i++){
cn.expand();
cn = cn.findChild('htmlNode', pn[i]);
if(!cn){ // in this dialog?
return false;
}
}
cn.select();
var a = cn.ui.anchor;
treeEl.dom.scrollTop = Math.max(0 ,a.offsetTop-10);
//treeEl.dom.scrollLeft = Math.max(0 ,a.offsetLeft-10); no likey
cn.highlight();
return true;
}
function nodeTitle(n){
var s = n.tagName;
if(n.id){
s += '#'+n.id;
}else if(n.className){
s += '.'+n.className;
}
return s;
}
function onNodeSelect(t, n, last){
return;
if(last && last.unframe){
last.unframe();
}
var props = {};
if(n && n.htmlNode){
if(frameEl.pressed){
n.frame();
}
if(inspecting){
return;
}
addStyle.enable();
reload.setDisabled(n.leaf);
var dom = n.htmlNode;
stylePanel.setTitle(nodeTitle(dom));
if(styles && !showAll.pressed){
var s = dom.style ? dom.style.cssText : '';
if(s){
var m;
while ((m = styleRe.exec(s)) != null){
props[m[1].toLowerCase()] = m[2];
}
}
}else if(styles){
var cl = Ext.debug.cssList;
var s = dom.style, fly = Ext.fly(dom);
if(s){
for(var i = 0, len = cl.length; i' + ellipsis(html(String(c.nodeValue)), 35) + '',
cls: 'x-tree-noicon'
}));
}
}
cb();
};
//tree.getSelectionModel().on('selectionchange', onNodeSelect, null, {buffer:250});
this.root = this.setRootNode(new Ext.tree.TreeNode('Ext'));
hnode = this.root.appendChild(new Ext.debug.HtmlNode(
document.getElementsByTagName('html')[0]
));
}
});
Ext.debug.ComponentNodeUI = Ext.extend(Ext.tree.TreeNodeUI,{
onOver : function(e){
Ext.debug.ComponentNodeUI.superclass.onOver.call(this);
var cmp = this.node.attributes.component;
if (cmp.el && cmp.el.mask && cmp.id !='x-debug-browser') {
try { // Oddly bombs on some elements in IE, gets any we care about though
cmp.el.mask();
} catch(e) {}
}
},
onOut : function(e){
Ext.debug.ComponentNodeUI.superclass.onOut.call(this);
var cmp = this.node.attributes.component;
if (cmp.el && cmp.el.unmask && cmp.id !='x-debug-browser') {
try {
cmp.el.unmask();
} catch(e) {}
}
}
});
Ext.debug.ComponentInspector = Ext.extend(Ext.tree.TreePanel, {
enableDD:false ,
lines:false,
rootVisible:false,
animate:false,
hlColor:'ffff9c',
autoScroll: true,
region:'center',
border:false,
initComponent : function(){
this.loader = new Ext.tree.TreeLoader();
this.bbar = new Ext.Toolbar([{
text: 'Refresh',
handler: this.refresh,
scope: this
}]);
Ext.debug.ComponentInspector.superclass.initComponent.call(this);
this.root = this.setRootNode(new Ext.tree.TreeNode({
text: 'Ext Components',
component: Ext.ComponentMgr.all,
leaf: false
}));
this.parseRootNode();
this.on('click', this.onClick, this);
},
createNode: function(n,c) {
var leaf = (c.items && c.items.length > 0);
return n.appendChild(new Ext.tree.TreeNode({
text: c.id + (c.getXType() ? ' [ ' + c.getXType() + ' ]': '' ),
component: c,
uiProvider:Ext.debug.ComponentNodeUI,
leaf: !leaf
}));
},
parseChildItems: function(n) {
var cn = n.attributes.component.items;
if (cn) {
for (var i = 0;i < cn.length; i++) {
var c = cn.get(i);
if (c.id != this.id && c.id != this.bottomToolbar.id) {
var newNode = this.createNode(n,c);
if (!newNode.leaf) {
this.parseChildItems(newNode)
}
}
}
}
},
parseRootNode: function() {
var n = this.root;
var cn = n.attributes.component.items;
for (var i = 0,c;c = cn[i];i++) {
if (c.id != this.id && c.id != this.bottomToolbar.id) {
if (!c.ownerCt) {
var newNode = this.createNode(n,c);
if (!newNode.leaf) {
this.parseChildItems(newNode);
}
}
}
}
},
onClick: function(node, e) {
var oi = Ext.getCmp('x-debug-objinspector');
oi.refreshNodes(node.attributes.component);
oi.ownerCt.show();
},
refresh: function() {
while (this.root.firstChild) {
this.root.removeChild(this.root.firstChild);
}
this.parseRootNode();
var ci = Ext.getCmp('x-debug-compinfo');
if (ci) {
ci.message('refreshed component tree - '+Ext.ComponentMgr.all.length)
}
}
});
Ext.debug.ComponentInfoPanel = Ext.extend(Ext.Panel,{
id:'x-debug-compinfo',
region: 'east',
minWidth: 200,
split: true,
width: 350,
border: false,
autoScroll: true,
layout:'anchor',
style:'border-width:0 0 0 1px;',
initComponent: function() {
this.watchBox = new Ext.form.Checkbox({
id: 'x-debug-watchcomp',
boxLabel: 'Watch ComponentMgr',
listeners: {
check: function(cb, val) {
if (val) {
Ext.ComponentMgr.all.on('add', this.onAdd, this);
Ext.ComponentMgr.all.on('remove', this.onRemove, this);
} else {
Ext.ComponentMgr.all.un('add', this.onAdd, this);
Ext.ComponentMgr.all.un('remove', this.onRemove, this);
}
},
scope: this
}
});
this.tbar = new Ext.Toolbar([{
text: 'Clear',
handler: this.clear,
scope: this
},'->',this.watchBox
]);
Ext.debug.ComponentInfoPanel.superclass.initComponent.call(this);
},
onAdd: function(i, o, key) {
var markup = ['',
'Added: '+o.id,
'
'].join('');
this.insertMarkup(markup);
},
onRemove: function(o, key) {
var markup = ['',
'Removed: '+o.id,
'
'].join('');
this.insertMarkup(markup);
},
message: function(msg) {
var markup = ['',
msg,
'
'].join('');
this.insertMarkup(markup);
},
insertMarkup: function(markup) {
this.body.insertHtml('beforeend', markup);
this.body.scrollTo('top', 100000);
},
clear : function(){
this.body.update('');
this.body.dom.scrollTop = 0;
}
});
Ext.debug.ColumnNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
focus: Ext.emptyFn, // prevent odd scrolling behavior
renderElements : function(n, a, targetNode, bulkRender){
this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
var t = n.getOwnerTree();
var cols = t.columns;
var bw = t.borderWidth;
var c = cols[0];
var buf = [
'',
'
',
'
',this.indentMarkup,"",
'
',
'
',
'
',
'', n.text || (c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]),"",
"
"];
for(var i = 1, len = cols.length; i < len; i++){
c = cols[i];
buf.push('
',
'
',(c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]),"
",
"
");
}
buf.push(
'
',
'',
"");
if(bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()){
this.wrap = Ext.DomHelper.insertHtml("beforeBegin",
n.nextSibling.ui.getEl(), buf.join(""));
}else{
this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf.join(""));
}
this.elNode = this.wrap.childNodes[0];
this.ctNode = this.wrap.childNodes[1];
var cs = this.elNode.firstChild.childNodes;
this.indentNode = cs[0];
this.ecNode = cs[1];
this.iconNode = cs[2];
this.anchor = cs[3];
this.textNode = cs[3].firstChild;
}
});
Ext.debug.ObjectInspector = Ext.extend(Ext.tree.TreePanel, {
id: 'x-debug-objinspector',
enableDD:false ,
lines:false,
rootVisible:false,
animate:false,
hlColor:'ffff9c',
autoScroll: true,
region:'center',
border:false,
lines:false,
borderWidth: Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell
cls:'x-column-tree',
initComponent : function(){
this.showFunc = false;
this.toggleFunc = function() {
this.showFunc = !this.showFunc;
this.refreshNodes(this.currentObject);
}
this.bbar = new Ext.Toolbar([{
text: 'Show Functions',
enableToggle: true,
pressed: false,
handler: this.toggleFunc,
scope: this
}]);
Ext.apply(this,{
title: ' ',
loader: new Ext.tree.TreeLoader(),
columns:[{
header:'Property',
width: 300,
dataIndex:'name'
},{
header:'Value',
width: 900,
dataIndex:'value'
}]
});
Ext.debug.ObjectInspector.superclass.initComponent.call(this);
this.root = this.setRootNode(new Ext.tree.TreeNode({
text: 'Dummy Node',
leaf: false
}));
if (this.currentObject) {
this.parseNodes();
}
},
refreshNodes: function(newObj) {
this.currentObject = newObj;
var node = this.root;
while(node.firstChild){
node.removeChild(node.firstChild);
}
this.parseNodes();
},
parseNodes: function() {
for (var o in this.currentObject) {
if (!this.showFunc) {
if (Ext.isFunction(this.currentObject[o])) {
continue;
}
}
this.createNode(o);
}
},
createNode: function(o) {
return this.root.appendChild(new Ext.tree.TreeNode({
name: o,
value: this.currentObject[o],
uiProvider:Ext.debug.ColumnNodeUI,
iconCls: 'x-debug-node',
leaf: true
}));
},
onRender : function(){
Ext.debug.ObjectInspector.superclass.onRender.apply(this, arguments);
this.headers = this.header.createChild({cls:'x-tree-headers'});
var cols = this.columns, c;
var totalWidth = 0;
for(var i = 0, len = cols.length; i < len; i++){
c = cols[i];
totalWidth += c.width;
this.headers.createChild({
cls:'x-tree-hd ' + (c.cls?c.cls+'-hd':''),
cn: {
cls:'x-tree-hd-text',
html: c.header
},
style:'width:'+(c.width-this.borderWidth)+'px;'
});
}
this.headers.createChild({cls:'x-clear'});
// prevent floats from wrapping when clipped
this.headers.setWidth(totalWidth);
this.innerCt.setWidth(totalWidth);
}
});
Ext.debug.StoreInspector = Ext.extend(Ext.tree.TreePanel, {
enableDD:false ,
lines:false,
rootVisible:false,
animate:false,
hlColor:'ffff9c',
autoScroll: true,
region:'center',
border:false,
initComponent: function() {
this.bbar = new Ext.Toolbar([{
text: 'Refresh',
handler: this.refresh,
scope: this
}]);
Ext.debug.StoreInspector.superclass.initComponent.call(this);
this.root = this.setRootNode(new Ext.tree.TreeNode({
text: 'Data Stores',
leaf: false
}));
this.on('click', this.onClick, this);
this.parseStores();
},
parseStores: function() {
var cn = Ext.StoreMgr.items;
for (var i = 0,c;c = cn[i];i++) {
this.root.appendChild({
text: c.storeId + ' - ' + c.totalLength + ' records',
component: c,
leaf: true
});
}
},
onClick: function(node, e) {
var oi = Ext.getCmp('x-debug-objinspector');
oi.refreshNodes(node.attributes.component);
oi.ownerCt.show();
},
refresh: function() {
while (this.root.firstChild) {
this.root.removeChild(this.root.firstChild);
}
this.parseStores();
}
});
// highly unusual class declaration
Ext.debug.HtmlNode = function(){
var html = Ext.util.Format.htmlEncode;
var ellipsis = Ext.util.Format.ellipsis;
var nonSpace = /^\s*$/;
var attrs = [
{n: 'id', v: 'id'},
{n: 'className', v: 'class'},
{n: 'name', v: 'name'},
{n: 'type', v: 'type'},
{n: 'src', v: 'src'},
{n: 'href', v: 'href'}
];
function hasChild(n){
for(var i = 0, c; c = n.childNodes[i]; i++){
if(c.nodeType == 1){
return true;
}
}
return false;
}
function renderNode(n, leaf){
var tag = n.tagName.toLowerCase();
var s = '<' + tag;
for(var i = 0, len = attrs.length; i < len; i++){
var a = attrs[i];
var v = n[a.n];
if(v && !nonSpace.test(v)){
s += ' ' + a.v + '="' + html(v) +'"';
}
}
var style = n.style ? n.style.cssText : '';
if(style){
s += ' style="' + html(style.toLowerCase()) +'"';
}
if(leaf && n.childNodes.length > 0){
s+='>' + ellipsis(html(String(n.innerHTML)), 35) + '</'+tag+'>';
}else if(leaf){
s += ' />';
}else{
s += '>';
}
return s;
}
var HtmlNode = function(n){
var leaf = !hasChild(n);
this.htmlNode = n;
this.tagName = n.tagName.toLowerCase();
var attr = {
text : renderNode(n, leaf),
leaf : leaf,
cls: 'x-tree-noicon'
};
HtmlNode.superclass.constructor.call(this, attr);
this.attributes.htmlNode = n; // for searching
if(!leaf){
this.on('expand', this.onExpand, this);
this.on('collapse', this.onCollapse, this);
}
};
Ext.extend(HtmlNode, Ext.tree.AsyncTreeNode, {
cls: 'x-tree-noicon',
preventHScroll: true,
refresh : function(highlight){
var leaf = !hasChild(this.htmlNode);
this.setText(renderNode(this.htmlNode, leaf));
if(highlight){
Ext.fly(this.ui.textNode).highlight();
}
},
onExpand : function(){
if(!this.closeNode && this.parentNode){
this.closeNode = this.parentNode.insertBefore(new Ext.tree.TreeNode({
text:'</' + this.tagName + '>',
cls: 'x-tree-noicon'
}), this.nextSibling);
}else if(this.closeNode){
this.closeNode.ui.show();
}
},
onCollapse : function(){
if(this.closeNode){
this.closeNode.ui.hide();
}
},
render : function(bulkRender){
HtmlNode.superclass.render.call(this, bulkRender);
},
highlightNode : function(){
//Ext.fly(this.htmlNode).highlight();
},
highlight : function(){
//Ext.fly(this.ui.textNode).highlight();
},
frame : function(){
this.htmlNode.style.border = '1px solid #0000ff';
//this.highlightNode();
},
unframe : function(){
//Ext.fly(this.htmlNode).removeClass('x-debug-frame');
this.htmlNode.style.border = '';
}
});
return HtmlNode;
}();