debug.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. // Licensed Materials - Property of IBM
  2. //
  3. // IBM Cognos Products: cpscrn
  4. //
  5. // (C) Copyright IBM Corp. 2005, 2011
  6. //
  7. // US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  8. //
  9. //
  10. // Copyright (C) 2008 Cognos ULC, an IBM Company. All rights reserved.
  11. // Cognos (R) is a trademark of Cognos ULC, (formerly Cognos Incorporated).
  12. // _F_Debug object can
  13. // 1) output to a log
  14. // 2) display a fragment tree.
  15. // 3) dump an object's contents to a new html window - make sure popups are not blocked
  16. // For more details see:
  17. // Debugging Fragments section on http://sottcps4/wiki/index.php?title=Fragment_Implementation_Debugging
  18. /*
  19. ** general log object definition
  20. */
  21. function _FD_log(useFireBugLite)
  22. {
  23. this.useFireBugLite = useFireBugLite;
  24. // array of queued log entries
  25. this.entries = new Array();
  26. }
  27. _FD_log.prototype =
  28. {
  29. // add an entry to the log queue
  30. logEntry: function(obj, func, parms)
  31. {
  32. this.obj = obj; // "this" object for func
  33. this.func = func; // function to execute
  34. this.parms = parms; // array of arguments
  35. },
  36. // call this function to add new entries to the log queue
  37. // it is expected that the parameters to the func will be passed in the call to this function
  38. appendLogEntry: function(obj, func) // ...
  39. {
  40. var parms = Array.prototype.slice.call(arguments, 2);
  41. var entry = new this.logEntry(obj, func, parms);
  42. this.entries.push(entry);
  43. },
  44. // process the queue of log entries by calling the specified functions in each log entry
  45. processQueuedEntries: function()
  46. {
  47. var current = null;
  48. if (window.console !== undefined) {
  49. for (var i=0; i < this.entries.length; i++) {
  50. current = this.entries[i];
  51. if (typeof current.func == "string")
  52. {
  53. try
  54. {
  55. func = eval(current.func);
  56. }
  57. catch(e)
  58. {}
  59. }
  60. else
  61. {
  62. func = current.func;
  63. }
  64. if (typeof func == "function")
  65. {
  66. func.apply(current.obj, current.parms);
  67. }
  68. }
  69. }
  70. },
  71. // begin a new group
  72. group: function (text, addTimeStamp)
  73. {
  74. if (addTimeStamp) {
  75. var date = new Date();
  76. text += " : Time: " + date.toLocaleTimeString()
  77. }
  78. if (this.useFireBugLite) {
  79. if (_F_Config.browser == "unknown") {
  80. // firebug lite console has not finished loading
  81. // queue the log entry
  82. this.appendLogEntry(window, "console.group", text);
  83. return;
  84. }
  85. }
  86. if (window.console !== undefined) {
  87. console.group(text);
  88. }
  89. },
  90. // end group
  91. groupEnd: function ()
  92. {
  93. if (this.useFireBugLite) {
  94. if (_F_Config.browser == "unknown") {
  95. // firebug lite console has not finished loading
  96. // queue the log entry
  97. this.appendLogEntry(window, "console.groupEnd");
  98. return;
  99. }
  100. }
  101. if (window.console !== undefined) {
  102. console.groupEnd();
  103. }
  104. },
  105. // log text
  106. logText: function (text)
  107. {
  108. if (this.useFireBugLite) {
  109. if (_F_Config.browser == "unknown") {
  110. // firebug lite console has not finished loading
  111. // queue the log entry
  112. this.appendLogEntry(window, "console.log", text );
  113. return;
  114. }
  115. }
  116. if (window.console !== undefined) {
  117. console.log(text);
  118. }
  119. },
  120. // log with option to group and option to send multiple object arguments
  121. logDetails: function (groupText) // ...
  122. {
  123. if (_F_Debug.useFireBugLite) {
  124. if (_F_Config.browser == "unknown") {
  125. // firebug lite console has not finished loading
  126. // queue the log entry
  127. var newArgs = Array.prototype.slice.call(arguments, 0);
  128. newArgs.unshift(this.logDetails); // add "function to call" to front of arguments
  129. newArgs.unshift(this); // add "object instance to execute function in" to front of arguments
  130. this.appendLogEntry.apply(_F_Debug.log, newArgs);
  131. return;
  132. }
  133. }
  134. if (window.console !== undefined) {
  135. var objs = Array.prototype.slice.call(arguments, 1);
  136. if (groupText != null)
  137. {
  138. console.group(groupText);
  139. }
  140. var curObj = null;
  141. for ( i = 0 ; i < objs.length; i++)
  142. {
  143. curObj = objs[i];
  144. if (typeof curObj == "object")
  145. {
  146. if (curObj.debugInfo !== undefined) {
  147. curObj.debugInfo(curObj);
  148. }
  149. else
  150. {
  151. console.log(curObj);
  152. }
  153. }
  154. else
  155. {
  156. console.log(curObj);
  157. }
  158. }
  159. if (groupText != null)
  160. {
  161. console.groupEnd();
  162. }
  163. }
  164. }
  165. }
  166. /*
  167. ** fragTree object definition
  168. */
  169. function _FD_fragTree(useFireBugLite, IELiteLevel )
  170. {
  171. this.useFireBugLite = useFireBugLite;
  172. this.IELiteLevel = IELiteLevel;
  173. }
  174. _FD_fragTree.prototype =
  175. {
  176. // walk the fragment tree and process each node for display.
  177. display: function (nodeId, maxLevel)
  178. {
  179. var curLevel = 0;
  180. if (maxLevel == null) {
  181. maxLevel = 9999;
  182. }
  183. if (nodeId != null && nodeId != "root") {
  184. this.processFragment(fragments[nodeId], maxLevel, curLevel);
  185. }
  186. else {
  187. for (var id in fragments) {
  188. if (fragments[id].parent == null) {
  189. this.processFragment(fragments[id], maxLevel, curLevel);
  190. }
  191. }
  192. }
  193. },
  194. processFragment: function(frag, maxLevel, curLevel)
  195. {
  196. if (frag != null && window.console !== undefined) {
  197. console.group(frag.id + "\ttitle: " + _F_Strings.normalize(frag.title));
  198. this.outputFragmentNode(frag);
  199. this.processBranch(frag, maxLevel, curLevel);
  200. console.groupEnd();
  201. }
  202. },
  203. // recursive function to display the fragments in a tree branch
  204. processBranch: function(frag, maxLevel, curLevel)
  205. {
  206. curLevel++;
  207. if (frag != null && curLevel < maxLevel) {
  208. var children = frag.getChildren();
  209. var i, l = children.length;
  210. for (i = 0; i < l; i++) {
  211. this.processFragment(children[i], maxLevel, curLevel);
  212. }
  213. }
  214. },
  215. // output the fragment node to the console
  216. outputFragmentNode: function(frag)
  217. {
  218. if (window.console !== undefined) {
  219. if (this.useFireBugLite) {
  220. if (this.IELiteLevel & _F_Debug.OBJECT_LVL) {
  221. console.group("frag");
  222. console.dir(frag);
  223. console.groupEnd();
  224. }
  225. console.group("div");
  226. if (this.IELiteLevel & _F_Debug.DIV_LVL) {
  227. var divObj = $(frag.div);
  228. if (divObj !== null) {
  229. console.dirxml($(frag.div));
  230. }
  231. }
  232. else {
  233. console.log(frag.div);
  234. }
  235. console.groupEnd();
  236. }
  237. else { // Firebug on Firefox
  238. console.log(frag);
  239. console.log($(frag.div));
  240. }
  241. }
  242. }
  243. }
  244. /*
  245. ** Dump object definition
  246. */
  247. function _FD_Dump ()
  248. {
  249. _debug_all = [];
  250. }
  251. _FD_Dump.prototype =
  252. {
  253. DebugView: function(o)
  254. {
  255. this._debug_all = [];
  256. var w = window.open("about:blank");
  257. if ( w == null) {
  258. return ("Cannot open window!");
  259. }
  260. w.location.href = "about:blank";
  261. w.document.open();
  262. w.document.writeln("<HTML><HEAD>"+
  263. "<TITLE>Dump</TITLE>"+
  264. "<STYLE type=\"text/css\">"+
  265. "BODY{font-family:andale mono, courier; font-size: 8pt; -moz-user-select: none;}"+
  266. "DIV{display:inline}"+
  267. ".H{color:blue;text-decoration:underline;cursor:pointer}"+
  268. ".c{color:#006600}"+
  269. ".n{color:#FF6600}"+
  270. ".f{color:#000066;font-weight:bold}"+
  271. ".t{color:#3366CC}"+
  272. "</STYLE>"+
  273. "<SCRIPT type=\"text/javascript\">"+
  274. "var last=null;"+
  275. "var lastLeft=0;"+
  276. "var lastTop=0;"+
  277. "function _debug_hilite(id){"+
  278. "if(last!=null){"+
  279. "document.getElementById(last).style.backgroundColor=\"\";" +
  280. "window.scrollTo(lastLeft,lastTop);"+
  281. "}"+
  282. "if(id!=null){" +
  283. "lastLeft=document.body.scrollLeft;"+
  284. "lastTop=document.body.scrollTop;"+
  285. "document.getElementById(id).style.backgroundColor=\"#FFCC66\";" +
  286. "window.scrollTo(0,document.getElementById(id).offsetTop);"+
  287. "}" +
  288. "last=id;" +
  289. "return false;"+
  290. "}" +
  291. "window.onload = function() {"+
  292. "document.onselectstart = function() {return false;}"+
  293. "}"+
  294. "</SCRIPT>" +
  295. "</HEAD><BODY onmouseup=\"_debug_hilite(null)\">");
  296. w.document.writeln(this._debug_renderObject(o,1));
  297. w.document.writeln("</BODY></HTML>");
  298. w.document.close();
  299. return ("Done");
  300. },
  301. _debug_indent: function(l)
  302. {
  303. var ret = "";
  304. for (var i=0; i<l; i++) ret = ret + "&nbsp;&nbsp;";
  305. return ret;
  306. },
  307. _debug_renderObject: function(o,l)
  308. {
  309. if (o==null) {
  310. return "<SPAN class=\"n\">null</SPAN>";
  311. } else if (typeof(o)=="string") {
  312. return "<SPAN class=\"t\">\"" + this._debugHtmlEncode(o) + "\"</SPAN>";
  313. } else if (typeof(o)=="boolean") {
  314. return "<SPAN class=\"n\">"+((o) ? "true" : "false")+"</SPAN>";
  315. } else if (typeof(o)=="number") {
  316. return "<SPAN class=\"n\">"+o+"</SPAN>";
  317. } else if (typeof(o)=="function") {
  318. return "<SPAN class=\"f\">function()</SPAN> { <SPAN class=\"c\">/* code omitted */</SPAN> }";
  319. } else if (typeof(o)=="object") {
  320. var ret = this._debug_filterObject(o);
  321. if (ret != null) {
  322. return ret;
  323. }
  324. var i = this._debug_wasDisplayed(o);
  325. if (i != -1) {
  326. return "{ <SPAN class=\"H\" onmousedown=\"_debug_hilite('I"+i+"')\">object</SPAN> }";
  327. }
  328. var ret;
  329. if (typeof(o.length)=="number" ) {
  330. ret = "<DIV id=\"I"+(this._debug_all.length-1)+"\">[ ";
  331. i = 0;
  332. if (o.length >= 0) {
  333. for (i=0; i<o.length;i++) {
  334. if (i>0) {
  335. ret += ",<BR>\n";
  336. }
  337. else {
  338. ret += "<BR>\n";
  339. }
  340. ret += this._debug_indent(l) + this._debug_renderObject(o[i],l+1);
  341. }
  342. }
  343. if (i > 0) {
  344. ret += "<BR>\n";
  345. }
  346. ret += this._debug_indent(l-1) + "]</DIV>";
  347. return ret;
  348. } else {
  349. ret = "<DIV id=\"I"+(this._debug_all.length-1)+"\">{ ";
  350. var count = 0;
  351. try {
  352. for (i in o) {
  353. if (count++>0) {
  354. ret += ",<BR>\n";
  355. }
  356. else {
  357. ret += "<BR>\n";
  358. }
  359. ret += this._debug_indent(l) + i + ": " + this._debug_renderObject(o[i],l+1);
  360. }
  361. } catch(e) {
  362. }
  363. if (count > 0) {
  364. ret += "<BR>\n";
  365. }
  366. ret += this._debug_indent(l-1) + "}</DIV>";
  367. return ret;
  368. }
  369. } else {
  370. return "!"+typeof(o);
  371. }
  372. },
  373. _debug_wasDisplayed: function(o) {
  374. var c=this._debug_all.length;
  375. for (var i=0; i<c; i++) {
  376. if (this._debug_all[i]===o) {
  377. return i;
  378. }
  379. }
  380. this._debug_all[c] = o;
  381. return -1;
  382. },
  383. _debug_filterObject: function (o) {
  384. if (o===document) {
  385. return "document";
  386. } else if (o===window) {
  387. return "window";
  388. } else if (o===document.body) {
  389. return "document.body";
  390. } else if (o===document.documentElement) {
  391. return "document.documentElement";
  392. } else if (o.constructor && o.constructor.toString().indexOf("[HTML") == 0) {
  393. return "HTMLDOM";
  394. }
  395. return null;
  396. },
  397. _debugHtmlEncode: function(text)
  398. {
  399. return text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
  400. }
  401. }
  402. /**
  403. * Initial settings for _F_Debug come from pf.properties file
  404. * Main object for debug functionality
  405. */
  406. var _F_Debug =
  407. {
  408. enabled: false,
  409. useFireBugLite: (navigator.userAgent.indexOf("Firefox")== -1),
  410. // bit masks for IE logging level
  411. // developers can change this setting by calling setIELiteLevel
  412. NORMAL_LVL : 0x1, // 1 - minimal logging
  413. OBJECT_LVL : 0x2, // 2 - output object xml
  414. DIV_LVL : 0x4, // 4 - output div html
  415. // 15 - for all levels of IE Lite logging
  416. IELiteLevel: 1,
  417. // developers can change the global settings per object type directly on the firebug console cmd line.
  418. // _F_Debug.settings["fragment"]= 0; or 1 or 2 ( OFF, ON, DEPEND )
  419. // _F_Debug.settings["_F_Event"]= 2;
  420. SETTING_OFF: 0,
  421. SETTING_ON: 1,
  422. SETTING_DEPEND: 2, // example: if parent or source debug is on
  423. settings: new Object(),
  424. log: new _FD_log((navigator.userAgent.indexOf("Firefox")== -1)),
  425. fragTree: new _FD_fragTree((navigator.userAgent.indexOf("Firefox")== -1), 1),
  426. dump: new _FD_Dump(),
  427. initialize: function()
  428. {
  429. if(this.useFireBugLite) {
  430. if (window.console === undefined) {
  431. window.alert("FireBugLite is not installed");
  432. }
  433. else {
  434. _F_Debug.log.processQueuedEntries();
  435. }
  436. }
  437. else if (window.console === undefined) {
  438. window.alert("FireBug is not installed or it is disabled");
  439. }
  440. },
  441. /**
  442. * CONSOLE CMD: developer can change IE logging level from the firebug command line
  443. * see values above.
  444. **/
  445. setIELiteLevel: function (level)
  446. {
  447. _F_Debug.IELiteLevel = level;
  448. _F_Debug.fragTree.IELiteLevel = level;
  449. return ("Done");
  450. },
  451. /**
  452. * CONSOLE CMD: Used to set the debug override for fragment objects and possibly their children.
  453. *
  454. * Example to debug events that apply only to a particular fragment and the fragment's children:
  455. * _F_Debug.settings["fragment"] = 0; turn off global fragment debugging
  456. * _F_Debug.settings["_F_Event"]= 2; sets global event setting to DEPEND which will check the source fragment
  457. * setFragmentDebug(fragId, 1, true); turn on debugging for only certain fragments.
  458. */
  459. setFragmentSetting: function(objectId, setting, bChildren)
  460. {
  461. var frag = fragments[objectId];
  462. if (frag != null) {
  463. frag.debugOverride = setting;
  464. if (bChildren) {
  465. var children = frag.getChildren();
  466. var i, l = children.length;
  467. for (i = 0; i < l; i++) {
  468. children[i].debugOverride = setting;
  469. }
  470. }
  471. return "Done";
  472. }
  473. else
  474. {
  475. return "Fragment( " + objectId + ") was not found";
  476. }
  477. },
  478. /**
  479. * CONSOLE CMD: Used to display the fragments in a tree. Useful to get id to send to setFragmentSetting.
  480. * Examples:
  481. * showFragmentTree(); returns entire tree
  482. * showFragmentTree("root",4); returns the first 4 levels of the tree starting from the root
  483. * showFragmentTree("adminconsole_xmlbooklet"); returns the tree starting from the given fragment id.
  484. * showFragmentTree("adminconsole_xmlbooklet", 4); returns the first 4 levels starting from the given fragment id.
  485. **/
  486. showFragmentTree: function(nodeId, maxLevel)
  487. {
  488. if (_F_Debug.enabled) {
  489. _F_Debug.fragTree.display( nodeId, maxLevel);
  490. return("Done");
  491. }
  492. return ("Debug not enabled");
  493. },
  494. /**
  495. * CONSOLE CMD: Dumps the contents of an object to a new window
  496. */
  497. dumpObject: function(object)
  498. {
  499. return(_F_Debug.dump.DebugView(object));
  500. }
  501. }
  502. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  503. // Extend the fragment object definition
  504. // set the debugOverride to override the global setting for this object
  505. fragment.prototype.debugOverride = -1; // 0 - off, 1 - on, 2 - depends
  506. fragment.prototype.debugEnabled = function()
  507. {
  508. if ( _F_Debug.enabled)
  509. {
  510. var debug = this.debugOverride != -1? this.debugOverride : _F_Debug.settings["fragment"];
  511. if ( debug == _F_Debug.SETTING_DEPEND)
  512. {
  513. var frag = this.parent;
  514. if (frag)
  515. {
  516. return frag.debugEnabled();
  517. }
  518. }
  519. return (debug == _F_Debug.SETTING_ON);
  520. }
  521. else
  522. {
  523. return false;
  524. }
  525. };
  526. // output the fragment information to the console
  527. fragment.prototype.debugInfo = function(frag)
  528. {
  529. if (window.console !== undefined) {
  530. if (_F_Debug.useFireBugLite) {
  531. if (_F_Debug.IELiteLevel & _F_Debug.OBJECT_LVL) {
  532. console.group("frag");
  533. console.dir(frag);
  534. console.groupEnd();
  535. }
  536. console.group("div");
  537. if (_F_Debug.IELiteLevel & _F_Debug.DIV_LVL) {
  538. var divObj = $(frag.div);
  539. if (divObj !== null) {
  540. console.dirxml($(frag.div));
  541. }
  542. }
  543. else {
  544. console.log(frag.div);
  545. }
  546. console.groupEnd();
  547. }
  548. else { // Firebug on Firefox
  549. console.log(frag);
  550. console.log($(frag.div));
  551. }
  552. }
  553. }
  554. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  555. // Extend the _F_Event object definition
  556. // set the debugOverride to override the global setting for this object
  557. _F_Event.Event.prototype.debugOverride = -1; // 0 - off, 1 - on, 2 - depends
  558. _F_Event.Event.prototype.debugEnabled = function()
  559. {
  560. if ( _F_Debug.enabled)
  561. {
  562. var debug = this.debugOverride != -1? this.debugOverride : _F_Debug.settings["_F_Event"];
  563. if ( debug == _F_Debug.SETTING_DEPEND)
  564. {
  565. var frag = this.source;
  566. if (frag)
  567. {
  568. return frag.debugEnabled();
  569. }
  570. }
  571. return (debug == _F_Debug.SETTING_ON);
  572. }
  573. else
  574. {
  575. return false;
  576. }
  577. };
  578. //output event information to the console
  579. _F_Event.Event.prototype.debugInfo = function( evt)
  580. {
  581. if (window.console !== undefined) {
  582. if (this.useFireBugLite) {
  583. if (this.IELiteLevel & _F_Debug.OBJECT_LVL) {
  584. console.group("evt");
  585. console.dir(evt);
  586. console.groupEnd();
  587. }
  588. else {
  589. console.log(evt.name);
  590. }
  591. }
  592. else // Firebug on Firefox
  593. {
  594. console.log(evt);
  595. }
  596. }
  597. }