PageRenderTime 112ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 1ms

/timeplot/lib/firebug/firebug.js

http://showslow.googlecode.com/
JavaScript | 672 lines | 547 code | 120 blank | 5 comment | 97 complexity | c32da437064c8f7a1a0769d8bf1faedf MD5 | raw file
  1. if (!("console" in window) || !("firebug" in console)) {
  2. (function()
  3. {
  4. window.console =
  5. {
  6. log: function()
  7. {
  8. logFormatted(arguments, "");
  9. },
  10. debug: function()
  11. {
  12. logFormatted(arguments, "debug");
  13. },
  14. info: function()
  15. {
  16. logFormatted(arguments, "info");
  17. },
  18. warn: function()
  19. {
  20. logFormatted(arguments, "warning");
  21. },
  22. error: function()
  23. {
  24. logFormatted(arguments, "error");
  25. },
  26. assert: function(truth, message)
  27. {
  28. if (!truth)
  29. {
  30. var args = [];
  31. for (var i = 1; i < arguments.length; ++i)
  32. args.push(arguments[i]);
  33. logFormatted(args.length ? args : ["Assertion Failure"], "error");
  34. throw message ? message : "Assertion Failure";
  35. }
  36. },
  37. dir: function(object)
  38. {
  39. var html = [];
  40. var pairs = [];
  41. for (var name in object)
  42. {
  43. try
  44. {
  45. pairs.push([name, object[name]]);
  46. }
  47. catch (exc)
  48. {
  49. }
  50. }
  51. pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; });
  52. html.push('<table>');
  53. for (var i = 0; i < pairs.length; ++i)
  54. {
  55. var name = pairs[i][0], value = pairs[i][1];
  56. html.push('<tr>',
  57. '<td class="propertyNameCell"><span class="propertyName">',
  58. escapeHTML(name), '</span></td>', '<td><span class="propertyValue">');
  59. appendObject(value, html);
  60. html.push('</span></td></tr>');
  61. }
  62. html.push('</table>');
  63. logRow(html, "dir");
  64. },
  65. dirxml: function(node)
  66. {
  67. var html = [];
  68. appendNode(node, html);
  69. logRow(html, "dirxml");
  70. },
  71. group: function()
  72. {
  73. logRow(arguments, "group", pushGroup);
  74. },
  75. groupEnd: function()
  76. {
  77. logRow(arguments, "", popGroup);
  78. },
  79. time: function(name)
  80. {
  81. timeMap[name] = (new Date()).getTime();
  82. },
  83. timeEnd: function(name)
  84. {
  85. if (name in timeMap)
  86. {
  87. var delta = (new Date()).getTime() - timeMap[name];
  88. logFormatted([name+ ":", delta+"ms"]);
  89. delete timeMap[name];
  90. }
  91. },
  92. count: function()
  93. {
  94. this.warn(["count() not supported."]);
  95. },
  96. trace: function()
  97. {
  98. this.warn(["trace() not supported."]);
  99. },
  100. profile: function()
  101. {
  102. this.warn(["profile() not supported."]);
  103. },
  104. profileEnd: function()
  105. {
  106. },
  107. clear: function()
  108. {
  109. consoleBody.innerHTML = "";
  110. },
  111. open: function()
  112. {
  113. toggleConsole(true);
  114. },
  115. close: function()
  116. {
  117. if (frameVisible)
  118. toggleConsole();
  119. }
  120. };
  121. // ********************************************************************************************
  122. var consoleFrame = null;
  123. var consoleBody = null;
  124. var commandLine = null;
  125. var frameVisible = false;
  126. var messageQueue = [];
  127. var groupStack = [];
  128. var timeMap = {};
  129. var clPrefix = ">>> ";
  130. var isFirefox = navigator.userAgent.indexOf("Firefox") != -1;
  131. var isIE = navigator.userAgent.indexOf("MSIE") != -1;
  132. var isOpera = navigator.userAgent.indexOf("Opera") != -1;
  133. var isSafari = navigator.userAgent.indexOf("AppleWebKit") != -1;
  134. // ********************************************************************************************
  135. function toggleConsole(forceOpen)
  136. {
  137. frameVisible = forceOpen || !frameVisible;
  138. if (consoleFrame)
  139. consoleFrame.style.visibility = frameVisible ? "visible" : "hidden";
  140. else
  141. waitForBody();
  142. }
  143. function focusCommandLine()
  144. {
  145. toggleConsole(true);
  146. if (commandLine)
  147. commandLine.focus();
  148. }
  149. function waitForBody()
  150. {
  151. if (document.body)
  152. createFrame();
  153. else
  154. setTimeout(waitForBody, 200);
  155. }
  156. function createFrame()
  157. {
  158. if (consoleFrame)
  159. return;
  160. window.onFirebugReady = function(doc)
  161. {
  162. window.onFirebugReady = null;
  163. var toolbar = doc.getElementById("toolbar");
  164. toolbar.onmousedown = onSplitterMouseDown;
  165. commandLine = doc.getElementById("commandLine");
  166. addEvent(commandLine, "keydown", onCommandLineKeyDown);
  167. addEvent(doc, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
  168. consoleBody = doc.getElementById("log");
  169. layout();
  170. flush();
  171. }
  172. var baseURL = getFirebugURL();
  173. consoleFrame = document.createElement("iframe");
  174. consoleFrame.setAttribute("src", baseURL+"/firebug.html");
  175. consoleFrame.setAttribute("frameBorder", "0");
  176. consoleFrame.style.visibility = (frameVisible ? "visible" : "hidden");
  177. consoleFrame.style.zIndex = "2147483647";
  178. consoleFrame.style.position = "fixed";
  179. consoleFrame.style.width = "100%";
  180. consoleFrame.style.left = "0";
  181. consoleFrame.style.bottom = "0";
  182. consoleFrame.style.height = "200px";
  183. document.body.appendChild(consoleFrame);
  184. }
  185. function getFirebugURL()
  186. {
  187. var scripts = document.getElementsByTagName("script");
  188. for (var i = 0; i < scripts.length; ++i)
  189. {
  190. if (scripts[i].src.indexOf("firebug.js") != -1)
  191. {
  192. var lastSlash = scripts[i].src.lastIndexOf("/");
  193. return scripts[i].src.substr(0, lastSlash);
  194. }
  195. }
  196. }
  197. function evalCommandLine()
  198. {
  199. var text = commandLine.value;
  200. commandLine.value = "";
  201. logRow([clPrefix, text], "command");
  202. var value;
  203. try
  204. {
  205. value = eval(text);
  206. }
  207. catch (exc)
  208. {
  209. }
  210. console.log(value);
  211. }
  212. function layout()
  213. {
  214. var toolbar = consoleBody.ownerDocument.getElementById("toolbar");
  215. var height = consoleFrame.offsetHeight - (toolbar.offsetHeight + commandLine.offsetHeight);
  216. consoleBody.style.top = toolbar.offsetHeight + "px";
  217. consoleBody.style.height = height + "px";
  218. commandLine.style.top = (consoleFrame.offsetHeight - commandLine.offsetHeight) + "px";
  219. }
  220. function logRow(message, className, handler)
  221. {
  222. if (consoleBody)
  223. writeMessage(message, className, handler);
  224. else
  225. {
  226. messageQueue.push([message, className, handler]);
  227. waitForBody();
  228. }
  229. }
  230. function flush()
  231. {
  232. var queue = messageQueue;
  233. messageQueue = [];
  234. for (var i = 0; i < queue.length; ++i)
  235. writeMessage(queue[i][0], queue[i][1], queue[i][2]);
  236. }
  237. function writeMessage(message, className, handler)
  238. {
  239. var isScrolledToBottom =
  240. consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
  241. if (!handler)
  242. handler = writeRow;
  243. handler(message, className);
  244. if (isScrolledToBottom)
  245. consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
  246. }
  247. function appendRow(row)
  248. {
  249. var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
  250. container.appendChild(row);
  251. }
  252. function writeRow(message, className)
  253. {
  254. var row = consoleBody.ownerDocument.createElement("div");
  255. row.className = "logRow" + (className ? " logRow-"+className : "");
  256. row.innerHTML = message.join("");
  257. appendRow(row);
  258. }
  259. function pushGroup(message, className)
  260. {
  261. logFormatted(message, className);
  262. var groupRow = consoleBody.ownerDocument.createElement("div");
  263. groupRow.className = "logGroup";
  264. var groupRowBox = consoleBody.ownerDocument.createElement("div");
  265. groupRowBox.className = "logGroupBox";
  266. groupRow.appendChild(groupRowBox);
  267. appendRow(groupRowBox);
  268. groupStack.push(groupRowBox);
  269. }
  270. function popGroup()
  271. {
  272. groupStack.pop();
  273. }
  274. // ********************************************************************************************
  275. function logFormatted(objects, className)
  276. {
  277. var html = [];
  278. var format = objects[0];
  279. var objIndex = 0;
  280. if (typeof(format) != "string")
  281. {
  282. format = "";
  283. objIndex = -1;
  284. }
  285. var parts = parseFormat(format);
  286. for (var i = 0; i < parts.length; ++i)
  287. {
  288. var part = parts[i];
  289. if (part && typeof(part) == "object")
  290. {
  291. var object = objects[++objIndex];
  292. part.appender(object, html);
  293. }
  294. else
  295. appendText(part, html);
  296. }
  297. for (var i = objIndex+1; i < objects.length; ++i)
  298. {
  299. appendText(" ", html);
  300. var object = objects[i];
  301. if (typeof(object) == "string")
  302. appendText(object, html);
  303. else
  304. appendObject(object, html);
  305. }
  306. logRow(html, className);
  307. }
  308. function parseFormat(format)
  309. {
  310. var parts = [];
  311. var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
  312. var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
  313. for (var m = reg.exec(format); m; m = reg.exec(format))
  314. {
  315. var type = m[8] ? m[8] : m[5];
  316. var appender = type in appenderMap ? appenderMap[type] : appendObject;
  317. var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
  318. parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
  319. parts.push({appender: appender, precision: precision});
  320. format = format.substr(m.index+m[0].length);
  321. }
  322. parts.push(format);
  323. return parts;
  324. }
  325. function escapeHTML(value)
  326. {
  327. function replaceChars(ch)
  328. {
  329. switch (ch)
  330. {
  331. case "<":
  332. return "&lt;";
  333. case ">":
  334. return "&gt;";
  335. case "&":
  336. return "&amp;";
  337. case "'":
  338. return "&#39;";
  339. case '"':
  340. return "&quot;";
  341. }
  342. return "?";
  343. };
  344. return String(value).replace(/[<>&"']/g, replaceChars);
  345. }
  346. function objectToString(object)
  347. {
  348. try
  349. {
  350. return object+"";
  351. }
  352. catch (exc)
  353. {
  354. return null;
  355. }
  356. }
  357. // ********************************************************************************************
  358. function appendText(object, html)
  359. {
  360. html.push(escapeHTML(objectToString(object)));
  361. }
  362. function appendNull(object, html)
  363. {
  364. html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
  365. }
  366. function appendString(object, html)
  367. {
  368. html.push('<span class="objectBox-string">&quot;', escapeHTML(objectToString(object)),
  369. '&quot;</span>');
  370. }
  371. function appendInteger(object, html)
  372. {
  373. html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
  374. }
  375. function appendFloat(object, html)
  376. {
  377. html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
  378. }
  379. function appendFunction(object, html)
  380. {
  381. var reName = /function ?(.*?)\(/;
  382. var m = reName.exec(objectToString(object));
  383. var name = m ? m[1] : "function";
  384. html.push('<span class="objectBox-function">', escapeHTML(name), '()</span>');
  385. }
  386. function appendObject(object, html)
  387. {
  388. try
  389. {
  390. if (object == undefined)
  391. appendNull("undefined", html);
  392. else if (object == null)
  393. appendNull("null", html);
  394. else if (typeof object == "string")
  395. appendString(object, html);
  396. else if (typeof object == "number")
  397. appendInteger(object, html);
  398. else if (typeof object == "function")
  399. appendFunction(object, html);
  400. else if (object.nodeType == 1)
  401. appendSelector(object, html);
  402. else if (typeof object == "object")
  403. appendObjectFormatted(object, html);
  404. else
  405. appendText(object, html);
  406. }
  407. catch (exc)
  408. {
  409. }
  410. }
  411. function appendObjectFormatted(object, html)
  412. {
  413. var text = objectToString(object);
  414. var reObject = /\[object (.*?)\]/;
  415. var m = reObject.exec(text);
  416. html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>')
  417. }
  418. function appendSelector(object, html)
  419. {
  420. html.push('<span class="objectBox-selector">');
  421. html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
  422. if (object.id)
  423. html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
  424. if (object.className)
  425. html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
  426. html.push('</span>');
  427. }
  428. function appendNode(node, html)
  429. {
  430. if (node.nodeType == 1)
  431. {
  432. html.push(
  433. '<div class="objectBox-element">',
  434. '&lt;<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
  435. for (var i = 0; i < node.attributes.length; ++i)
  436. {
  437. var attr = node.attributes[i];
  438. if (!attr.specified)
  439. continue;
  440. html.push('&nbsp;<span class="nodeName">', attr.nodeName.toLowerCase(),
  441. '</span>=&quot;<span class="nodeValue">', escapeHTML(attr.nodeValue),
  442. '</span>&quot;')
  443. }
  444. if (node.firstChild)
  445. {
  446. html.push('&gt;</div><div class="nodeChildren">');
  447. for (var child = node.firstChild; child; child = child.nextSibling)
  448. appendNode(child, html);
  449. html.push('</div><div class="objectBox-element">&lt;/<span class="nodeTag">',
  450. node.nodeName.toLowerCase(), '&gt;</span></div>');
  451. }
  452. else
  453. html.push('/&gt;</div>');
  454. }
  455. else if (node.nodeType == 3)
  456. {
  457. html.push('<div class="nodeText">', escapeHTML(node.nodeValue),
  458. '</div>');
  459. }
  460. }
  461. // ********************************************************************************************
  462. function addEvent(object, name, handler)
  463. {
  464. if (document.all)
  465. object.attachEvent("on"+name, handler);
  466. else
  467. object.addEventListener(name, handler, false);
  468. }
  469. function removeEvent(object, name, handler)
  470. {
  471. if (document.all)
  472. object.detachEvent("on"+name, handler);
  473. else
  474. object.removeEventListener(name, handler, false);
  475. }
  476. function cancelEvent(event)
  477. {
  478. if (document.all)
  479. event.cancelBubble = true;
  480. else
  481. event.stopPropagation();
  482. }
  483. function onError(msg, href, lineNo)
  484. {
  485. var html = [];
  486. var lastSlash = href.lastIndexOf("/");
  487. var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
  488. html.push(
  489. '<span class="errorMessage">', msg, '</span>',
  490. '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
  491. );
  492. logRow(html, "error");
  493. };
  494. function onKeyDown(event)
  495. {
  496. if (event.keyCode == 123)
  497. toggleConsole();
  498. else if ((event.keyCode == 108 || event.keyCode == 76) && event.shiftKey
  499. && (event.metaKey || event.ctrlKey))
  500. focusCommandLine();
  501. else
  502. return;
  503. cancelEvent(event);
  504. }
  505. function onSplitterMouseDown(event)
  506. {
  507. if (isSafari || isOpera)
  508. return;
  509. addEvent(document, "mousemove", onSplitterMouseMove);
  510. addEvent(document, "mouseup", onSplitterMouseUp);
  511. for (var i = 0; i < frames.length; ++i)
  512. {
  513. addEvent(frames[i].document, "mousemove", onSplitterMouseMove);
  514. addEvent(frames[i].document, "mouseup", onSplitterMouseUp);
  515. }
  516. }
  517. function onSplitterMouseMove(event)
  518. {
  519. var win = document.all
  520. ? event.srcElement.ownerDocument.parentWindow
  521. : event.target.ownerDocument.defaultView;
  522. var clientY = event.clientY;
  523. if (win != win.parent)
  524. clientY += win.frameElement ? win.frameElement.offsetTop : 0;
  525. var height = consoleFrame.offsetTop + consoleFrame.clientHeight;
  526. var y = height - clientY;
  527. consoleFrame.style.height = y + "px";
  528. layout();
  529. }
  530. function onSplitterMouseUp(event)
  531. {
  532. removeEvent(document, "mousemove", onSplitterMouseMove);
  533. removeEvent(document, "mouseup", onSplitterMouseUp);
  534. for (var i = 0; i < frames.length; ++i)
  535. {
  536. removeEvent(frames[i].document, "mousemove", onSplitterMouseMove);
  537. removeEvent(frames[i].document, "mouseup", onSplitterMouseUp);
  538. }
  539. }
  540. function onCommandLineKeyDown(event)
  541. {
  542. if (event.keyCode == 13)
  543. evalCommandLine();
  544. else if (event.keyCode == 27)
  545. commandLine.value = "";
  546. }
  547. window.onerror = onError;
  548. addEvent(document, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
  549. if (document.documentElement.getAttribute("debug") == "true")
  550. toggleConsole(true);
  551. })();
  552. }