debug.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /*
  2. * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
  3. *
  4. * http://extjs.com/license
  5. */
  6. Ext.debug = {};
  7. (function() {
  8. var cp;
  9. function createConsole() {
  10. var scriptPanel = new Ext.debug.ScriptsPanel();
  11. var logView = new Ext.debug.LogPanel();
  12. var tree = new Ext.debug.DomTree();
  13. var tabs = new Ext.TabPanel({
  14. activeTab : 0,
  15. border : false,
  16. tabPosition : 'bottom',
  17. items : [{
  18. title : 'Debug Console',
  19. layout : 'border',
  20. items : [logView, scriptPanel]
  21. }, {
  22. title : 'DOM Inspector',
  23. layout : 'border',
  24. items : [tree]
  25. }]
  26. });
  27. cp = new Ext.Panel({
  28. id : 'x-debug-browser',
  29. title : 'Console',
  30. collapsible : true,
  31. animCollapse : false,
  32. style : 'position:absolute;left:0;bottom:0;',
  33. height : 200,
  34. logView : logView,
  35. layout : 'fit',
  36. tools : [{
  37. id : 'close',
  38. handler : function() {
  39. cp.destroy();
  40. cp = null;
  41. Ext.EventManager.removeResizeListener(handleResize);
  42. }
  43. }],
  44. items : tabs
  45. });
  46. cp.render(document.body);
  47. cp.resizer = new Ext.Resizable(cp.el, {
  48. minHeight : 50,
  49. handles : "n",
  50. pinned : true,
  51. transparent : true,
  52. resizeElement : function() {
  53. var box = this.proxy.getBox();
  54. this.proxy.hide();
  55. cp.setHeight(box.height);
  56. return box;
  57. }
  58. });
  59. function handleResize() {
  60. cp.setWidth(Ext.getBody().getViewSize().width);
  61. }
  62. Ext.EventManager.onWindowResize(handleResize);
  63. handleResize();
  64. }
  65. Ext.apply(Ext, {
  66. log : function() {
  67. if (!cp) {
  68. createConsole();
  69. }
  70. cp.logView.log.apply(cp.logView, arguments);
  71. },
  72. logf : function(format, arg1, arg2, etc) {
  73. Ext.log(String.format.apply(String, arguments));
  74. },
  75. dump : function(o) {
  76. if (typeof o == 'string' || typeof o == 'number'
  77. || typeof o == 'undefined' || o instanceof Date) {
  78. Ext.log(o);
  79. } else if (!o) {
  80. Ext.log("null");
  81. } else if (typeof o != "object") {
  82. Ext.log('Unknown return type');
  83. } else if (o instanceof Array) {
  84. Ext.log('[' + o.join(',') + ']');
  85. } else {
  86. var b = ["{\n"];
  87. for (var key in o) {
  88. var to = typeof o[key];
  89. if (to != "function" && to != "object") {
  90. b.push(String.format(" {0}: {1},\n", key,
  91. o[key]));
  92. }
  93. }
  94. var s = b.join("");
  95. if (s.length > 3) {
  96. s = s.substr(0, s.length - 2);
  97. }
  98. Ext.log(s + "\n}");
  99. }
  100. },
  101. _timers : {},
  102. time : function(name) {
  103. name = name || "def";
  104. Ext._timers[name] = allGetServerTime().getTime();
  105. },
  106. timeEnd : function(name, printResults) {
  107. var t = allGetServerTime().getTime();
  108. name = name || "def";
  109. var v = String.format("{0} ms", t - Ext._timers[name]);
  110. Ext._timers[name] = allGetServerTime().getTime();
  111. if (printResults !== false) {
  112. Ext.log('Timer '
  113. + (name == "def" ? v : name + ": " + v));
  114. }
  115. return v;
  116. }
  117. });
  118. })();
  119. Ext.debug.ScriptsPanel = Ext.extend(Ext.Panel, {
  120. id : 'x-debug-scripts',
  121. region : 'east',
  122. minWidth : 200,
  123. split : true,
  124. width : 350,
  125. border : false,
  126. layout : 'anchor',
  127. style : 'border-width:0 0 0 1px;',
  128. initComponent : function() {
  129. this.scriptField = new Ext.form.TextArea({
  130. anchor : '100% -26',
  131. style : 'border-width:0;'
  132. });
  133. this.trapBox = new Ext.form.Checkbox({
  134. id : 'console-trap',
  135. boxLabel : 'Trap Errors',
  136. checked : true
  137. });
  138. this.toolbar = new Ext.Toolbar([{
  139. text : 'Run',
  140. scope : this,
  141. handler : this.evalScript
  142. }, {
  143. text : 'Clear',
  144. scope : this,
  145. handler : this.clear
  146. }, '->', this.trapBox, ' ', ' ']);
  147. this.items = [this.toolbar, this.scriptField];
  148. Ext.debug.ScriptsPanel.superclass.initComponent.call(this);
  149. },
  150. evalScript : function() {
  151. var s = this.scriptField.getValue();
  152. if (this.trapBox.getValue()) {
  153. try {
  154. var rt = eval(s);
  155. Ext.dump(rt === undefined ? '(no return)' : rt);
  156. } catch (e) {
  157. Ext.log(e.message || e.descript);
  158. }
  159. } else {
  160. var rt = eval(s);
  161. Ext.dump(rt === undefined ? '(no return)' : rt);
  162. }
  163. },
  164. clear : function() {
  165. this.scriptField.setValue('');
  166. this.scriptField.focus();
  167. }
  168. });
  169. Ext.debug.LogPanel = Ext.extend(Ext.Panel, {
  170. autoScroll : true,
  171. region : 'center',
  172. border : false,
  173. style : 'border-width:0 1px 0 0',
  174. log : function() {
  175. var markup = [
  176. '<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
  177. Ext.util.Format.htmlEncode(Array.prototype.join.call(arguments,
  178. ', ')).replace(/\n/g, '<br />')
  179. .replace(/\s/g, '&#160;'), '</div>'].join('');
  180. this.body.insertHtml('beforeend', markup);
  181. this.body.scrollTo('top', 100000);
  182. },
  183. clear : function() {
  184. this.body.update('');
  185. this.body.dom.scrollTop = 0;
  186. }
  187. });
  188. Ext.debug.DomTree = Ext.extend(Ext.tree.TreePanel, {
  189. enableDD : false,
  190. lines : false,
  191. rootVisible : false,
  192. animate : false,
  193. hlColor : 'ffff9c',
  194. autoScroll : true,
  195. region : 'center',
  196. border : false,
  197. initComponent : function() {
  198. Ext.debug.DomTree.superclass.initComponent.call(this);
  199. // tree related stuff
  200. var styles = false, hnode;
  201. var nonSpace = /^\s*$/;
  202. var html = Ext.util.Format.htmlEncode;
  203. var ellipsis = Ext.util.Format.ellipsis;
  204. var styleRe = /\s?([a-z\-]*)\:([^;]*)(?:[;\s\n\r]*)/gi;
  205. function findNode(n) {
  206. if (!n || n.nodeType != 1 || n == document.body || n == document) {
  207. return false;
  208. }
  209. var pn = [n], p = n;
  210. while ((p = p.parentNode) && p.nodeType == 1
  211. && p.tagName.toUpperCase() != 'HTML') {
  212. pn.unshift(p);
  213. }
  214. var cn = hnode;
  215. for (var i = 0, len = pn.length; i < len; i++) {
  216. cn.expand();
  217. cn = cn.findChild('htmlNode', pn[i]);
  218. if (!cn) { // in this dialog?
  219. return false;
  220. }
  221. }
  222. cn.select();
  223. var a = cn.ui.anchor;
  224. treeEl.dom.scrollTop = Math.max(0, a.offsetTop - 10);
  225. // treeEl.dom.scrollLeft = Math.max(0 ,a.offsetLeft-10); no likey
  226. cn.highlight();
  227. return true;
  228. }
  229. function nodeTitle(n) {
  230. var s = n.tagName;
  231. if (n.id) {
  232. s += '#' + n.id;
  233. } else if (n.className) {
  234. s += '.' + n.className;
  235. }
  236. return s;
  237. }
  238. function onNodeSelect(t, n, last) {
  239. return;
  240. if (last && last.unframe) {
  241. last.unframe();
  242. }
  243. var props = {};
  244. if (n && n.htmlNode) {
  245. if (frameEl.pressed) {
  246. n.frame();
  247. }
  248. if (inspecting) {
  249. return;
  250. }
  251. addStyle.enable();
  252. reload.setDisabled(n.leaf);
  253. var dom = n.htmlNode;
  254. stylePanel.setTitle(nodeTitle(dom));
  255. if (styles && !showAll.pressed) {
  256. var s = dom.style ? dom.style.cssText : '';
  257. if (s) {
  258. var m;
  259. while ((m = styleRe.exec(s)) != null) {
  260. props[m[1].toLowerCase()] = m[2];
  261. }
  262. }
  263. } else if (styles) {
  264. var cl = Ext.debug.cssList;
  265. var s = dom.style, fly = Ext.fly(dom);
  266. if (s) {
  267. for (var i = 0, len = cl.length; i < len; i++) {
  268. var st = cl[i];
  269. var v = s[st] || fly.getStyle(st);
  270. if (v != undefined && v !== null && v !== '') {
  271. props[st] = v;
  272. }
  273. }
  274. }
  275. } else {
  276. for (var a in dom) {
  277. var v = dom[a];
  278. if ((isNaN(a + 10)) && v != undefined && v !== null
  279. && v !== ''
  280. && !(Ext.isGecko && a[0] == a[0].toUpperCase())) {
  281. props[a] = v;
  282. }
  283. }
  284. }
  285. } else {
  286. if (inspecting) {
  287. return;
  288. }
  289. addStyle.disable();
  290. reload.disabled();
  291. }
  292. stylesGrid.setSource(props);
  293. stylesGrid.treeNode = n;
  294. stylesGrid.view.fitColumns();
  295. }
  296. this.loader = new Ext.tree.TreeLoader();
  297. this.loader.load = function(n, cb) {
  298. var isBody = n.htmlNode == document.body;
  299. var cn = n.htmlNode.childNodes;
  300. for (var i = 0, c; c = cn[i]; i++) {
  301. if (isBody && c.id == 'x-debug-browser') {
  302. continue;
  303. }
  304. if (c.nodeType == 1) {
  305. n.appendChild(new Ext.debug.HtmlNode(c));
  306. } else if (c.nodeType == 3 && !nonSpace.test(c.nodeValue)) {
  307. n.appendChild(new Ext.tree.TreeNode({
  308. text : '<em>'
  309. + ellipsis(html(String(c.nodeValue)),
  310. 35) + '</em>',
  311. cls : 'x-tree-noicon'
  312. }));
  313. }
  314. }
  315. cb();
  316. };
  317. // tree.getSelectionModel().on('selectionchange', onNodeSelect, null,
  318. // {buffer:250});
  319. this.root = this.setRootNode(new Ext.tree.TreeNode('Ext'));
  320. hnode = this.root.appendChild(new Ext.debug.HtmlNode(document
  321. .getElementsByTagName('html')[0]));
  322. }
  323. });
  324. // highly unusual class declaration
  325. Ext.debug.HtmlNode = function() {
  326. var html = Ext.util.Format.htmlEncode;
  327. var ellipsis = Ext.util.Format.ellipsis;
  328. var nonSpace = /^\s*$/;
  329. var attrs = [{
  330. n : 'id',
  331. v : 'id'
  332. }, {
  333. n : 'className',
  334. v : 'class'
  335. }, {
  336. n : 'name',
  337. v : 'name'
  338. }, {
  339. n : 'type',
  340. v : 'type'
  341. }, {
  342. n : 'src',
  343. v : 'src'
  344. }, {
  345. n : 'href',
  346. v : 'href'
  347. }];
  348. function hasChild(n) {
  349. for (var i = 0, c; c = n.childNodes[i]; i++) {
  350. if (c.nodeType == 1) {
  351. return true;
  352. }
  353. }
  354. return false;
  355. }
  356. function renderNode(n, leaf) {
  357. var tag = n.tagName.toLowerCase();
  358. var s = '&lt;' + tag;
  359. for (var i = 0, len = attrs.length; i < len; i++) {
  360. var a = attrs[i];
  361. var v = n[a.n];
  362. if (v && !nonSpace.test(v)) {
  363. s += ' ' + a.v + '=&quot;<i>' + html(v) + '</i>&quot;';
  364. }
  365. }
  366. var style = n.style ? n.style.cssText : '';
  367. if (style) {
  368. s += ' style=&quot;<i>' + html(style.toLowerCase()) + '</i>&quot;';
  369. }
  370. if (leaf && n.childNodes.length > 0) {
  371. s += '&gt;<em>' + ellipsis(html(String(n.innerHTML)), 35)
  372. + '</em>&lt;/' + tag + '&gt;';
  373. } else if (leaf) {
  374. s += ' /&gt;';
  375. } else {
  376. s += '&gt;';
  377. }
  378. return s;
  379. }
  380. var HtmlNode = function(n) {
  381. var leaf = !hasChild(n);
  382. this.htmlNode = n;
  383. this.tagName = n.tagName.toLowerCase();
  384. var attr = {
  385. text : renderNode(n, leaf),
  386. leaf : leaf,
  387. cls : 'x-tree-noicon'
  388. };
  389. HtmlNode.superclass.constructor.call(this, attr);
  390. this.attributes.htmlNode = n; // for searching
  391. if (!leaf) {
  392. this.on('expand', this.onExpand, this);
  393. this.on('collapse', this.onCollapse, this);
  394. }
  395. };
  396. Ext.extend(HtmlNode, Ext.tree.AsyncTreeNode, {
  397. cls : 'x-tree-noicon',
  398. preventHScroll : true,
  399. refresh : function(highlight) {
  400. var leaf = !hasChild(this.htmlNode);
  401. this.setText(renderNode(this.htmlNode, leaf));
  402. if (highlight) {
  403. Ext.fly(this.ui.textNode).highlight();
  404. }
  405. },
  406. onExpand : function() {
  407. if (!this.closeNode && this.parentNode) {
  408. this.closeNode = this.parentNode.insertBefore(
  409. new Ext.tree.TreeNode({
  410. text : '&lt;/' + this.tagName
  411. + '&gt;',
  412. cls : 'x-tree-noicon'
  413. }), this.nextSibling);
  414. } else if (this.closeNode) {
  415. this.closeNode.ui.show();
  416. }
  417. },
  418. onCollapse : function() {
  419. if (this.closeNode) {
  420. this.closeNode.ui.hide();
  421. }
  422. },
  423. render : function(bulkRender) {
  424. HtmlNode.superclass.render.call(this, bulkRender);
  425. },
  426. highlightNode : function() {
  427. // Ext.fly(this.htmlNode).highlight();
  428. },
  429. highlight : function() {
  430. // Ext.fly(this.ui.textNode).highlight();
  431. },
  432. frame : function() {
  433. this.htmlNode.style.border = '1px solid #0000ff';
  434. // this.highlightNode();
  435. },
  436. unframe : function() {
  437. // Ext.fly(this.htmlNode).removeClass('x-debug-frame');
  438. this.htmlNode.style.border = '';
  439. }
  440. });
  441. return HtmlNode;
  442. }();