2 if (!window.console || !console.firebug) { (function()
8 logFormatted(arguments, "");
13 logFormatted(arguments, "debug");
18 logFormatted(arguments, "info");
23 logFormatted(arguments, "warning");
28 logFormatted(arguments, "error");
31 assert: function(truth, message)
36 for (var i = 1; i < arguments.length; ++i)
37 args.push(arguments[i]);
39 logFormatted(args.length ? args : ["Assertion Failure"], "error");
40 throw message ? message : "Assertion Failure";
49 for (var name in object)
53 pairs.push([name, object[name]]);
60 pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; });
63 for (var i = 0; i < pairs.length; ++i)
65 var name = pairs[i][0], value = pairs[i][1];
68 '<td class="propertyNameCell"><span class="propertyName">',
69 escapeHTML(name), '</span></td>', '<td><span class="propertyValue">');
70 appendObject(value, html);
71 html.push('</span></td></tr>');
73 html.push('</table>');
78 dirxml: function(node)
82 appendNode(node, html);
83 logRow(html, "dirxml");
88 logRow(arguments, "group", pushGroup);
93 logRow(arguments, "", popGroup);
98 timeMap[name] = (new Date()).getTime();
101 timeEnd: function(name)
105 var delta = (new Date()).getTime() - timeMap[name];
106 logFormatted([name+ ":", delta+"ms"]);
107 delete timeMap[name];
113 this.warn(["count() not supported."]);
118 this.warn(["trace() not supported."]);
123 this.warn(["profile() not supported."]);
126 profileEnd: function()
132 consoleBody.innerHTML = "";
147 // ********************************************************************************************
149 var consoleFrame = null;
150 var consoleBody = null;
151 var commandLine = null;
153 var frameVisible = false;
154 var messageQueue = [];
158 var clPrefix = ">>> ";
160 var isFirefox = navigator.userAgent.indexOf("Firefox") != -1;
161 var isIE = navigator.userAgent.indexOf("MSIE") != -1;
162 var isOpera = navigator.userAgent.indexOf("Opera") != -1;
163 var isSafari = navigator.userAgent.indexOf("AppleWebKit") != -1;
165 // ********************************************************************************************
167 function toggleConsole(forceOpen)
169 frameVisible = forceOpen || !frameVisible;
171 consoleFrame.style.visibility = frameVisible ? "visible" : "hidden";
176 function focusCommandLine()
183 function waitForBody()
188 setTimeout(waitForBody, 200);
191 function createFrame()
196 window.onFirebugReady = function(doc)
198 window.onFirebugReady = null;
200 var toolbar = doc.getElementById("toolbar");
201 toolbar.onmousedown = onSplitterMouseDown;
203 commandLine = doc.getElementById("commandLine");
204 addEvent(commandLine, "keydown", onCommandLineKeyDown);
206 addEvent(doc, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
208 consoleBody = doc.getElementById("log");
213 var baseURL = getFirebugURL();
215 consoleFrame = document.createElement("iframe");
216 consoleFrame.setAttribute("src", baseURL+"/firebug.html");
217 consoleFrame.setAttribute("frameBorder", "0");
218 consoleFrame.style.visibility = (frameVisible ? "visible" : "hidden");
219 consoleFrame.style.zIndex = "2147483583";
220 consoleFrame.style.position = document.all ? "absolute" : "fixed";
221 consoleFrame.style.width = "100%";
222 consoleFrame.style.left = "0";
223 consoleFrame.style.bottom = "0";
224 consoleFrame.style.height = "200px";
225 document.body.appendChild(consoleFrame);
228 function getFirebugURL()
230 var scripts = document.getElementsByTagName("script");
231 for (var i = 0; i < scripts.length; ++i)
233 if (scripts[i].src.indexOf("firebug.js") != -1)
235 var lastSlash = scripts[i].src.lastIndexOf("/");
236 return scripts[i].src.substr(0, lastSlash);
241 function evalCommandLine()
243 var text = commandLine.value;
244 commandLine.value = "";
246 logRow([clPrefix, text], "command");
262 var toolbar = consoleBody.ownerDocument.getElementById("toolbar");
263 var height = consoleFrame.offsetHeight - (toolbar.offsetHeight + commandLine.offsetHeight);
264 height = Math.max(height, 0);
265 consoleBody.style.top = toolbar.offsetHeight + "px";
266 consoleBody.style.height = height + "px";
268 commandLine.style.top = (consoleFrame.offsetHeight - commandLine.offsetHeight) + "px";
271 function logRow(message, className, handler)
274 writeMessage(message, className, handler);
277 messageQueue.push([message, className, handler]);
284 var queue = messageQueue;
287 for (var i = 0; i < queue.length; ++i)
288 writeMessage(queue[i][0], queue[i][1], queue[i][2]);
291 function writeMessage(message, className, handler)
293 var isScrolledToBottom =
294 consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
299 handler(message, className);
301 if (isScrolledToBottom)
302 consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
305 function appendRow(row)
307 var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
308 container.appendChild(row);
311 function writeRow(message, className)
313 var row = consoleBody.ownerDocument.createElement("div");
314 row.className = "logRow" + (className ? " logRow-"+className : "");
315 row.innerHTML = message.join("");
319 function pushGroup(message, className)
321 logFormatted(message, className);
323 var groupRow = consoleBody.ownerDocument.createElement("div");
324 groupRow.className = "logGroup";
325 var groupRowBox = consoleBody.ownerDocument.createElement("div");
326 groupRowBox.className = "logGroupBox";
327 groupRow.appendChild(groupRowBox);
328 appendRow(groupRowBox);
329 groupStack.push(groupRowBox);
337 // ********************************************************************************************
339 function logFormatted(objects, className)
343 var format = objects[0];
346 if (typeof(format) != "string")
352 var parts = parseFormat(format);
353 for (var i = 0; i < parts.length; ++i)
356 if (part && typeof(part) == "object")
358 var object = objects[++objIndex];
359 part.appender(object, html);
362 appendText(part, html);
365 for (var i = objIndex+1; i < objects.length; ++i)
367 appendText(" ", html);
369 var object = objects[i];
370 if (typeof(object) == "string")
371 appendText(object, html);
373 appendObject(object, html);
376 logRow(html, className);
379 function parseFormat(format)
383 var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
384 var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
386 for (var m = reg.exec(format); m; m = reg.exec(format))
388 var type = m[8] ? m[8] : m[5];
389 var appender = type in appenderMap ? appenderMap[type] : appendObject;
390 var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
392 parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
393 parts.push({appender: appender, precision: precision});
395 format = format.substr(m.index+m[0].length);
403 function escapeHTML(value)
405 function replaceChars(ch)
422 return String(value).replace(/[<>&"']/g, replaceChars);
425 function objectToString(object)
437 // ********************************************************************************************
439 function appendText(object, html)
441 html.push(escapeHTML(objectToString(object)));
444 function appendNull(object, html)
446 html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
449 function appendString(object, html)
451 html.push('<span class="objectBox-string">"', escapeHTML(objectToString(object)),
455 function appendInteger(object, html)
457 html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
460 function appendFloat(object, html)
462 html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
465 function appendFunction(object, html)
467 var reName = /function ?(.*?)\(/;
468 var m = reName.exec(objectToString(object));
469 var name = m ? m[1] : "function";
470 html.push('<span class="objectBox-function">', escapeHTML(name), '()</span>');
473 function appendObject(object, html)
477 if (object == undefined)
478 appendNull("undefined", html);
479 else if (object == null)
480 appendNull("null", html);
481 else if (typeof object == "string")
482 appendString(object, html);
483 else if (typeof object == "number")
484 appendInteger(object, html);
485 else if (typeof object == "function")
486 appendFunction(object, html);
487 else if (object.nodeType == 1)
488 appendSelector(object, html);
489 else if (typeof object == "object")
490 appendObjectFormatted(object, html);
492 appendText(object, html);
499 function appendObjectFormatted(object, html)
501 var text = objectToString(object);
502 var reObject = /\[object (.*?)\]/;
504 var m = reObject.exec(text);
505 html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>')
508 function appendSelector(object, html)
510 html.push('<span class="objectBox-selector">');
512 html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
514 html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
515 if (object.className)
516 html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
518 html.push('</span>');
521 function appendNode(node, html)
523 if (node.nodeType == 1)
526 '<div class="objectBox-element">',
527 '<<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
529 for (var i = 0; i < node.attributes.length; ++i)
531 var attr = node.attributes[i];
535 html.push(' <span class="nodeName">', attr.nodeName.toLowerCase(),
536 '</span>="<span class="nodeValue">', escapeHTML(attr.nodeValue),
542 html.push('></div><div class="nodeChildren">');
544 for (var child = node.firstChild; child; child = child.nextSibling)
545 appendNode(child, html);
547 html.push('</div><div class="objectBox-element"></<span class="nodeTag">',
548 node.nodeName.toLowerCase(), '></span></div>');
551 html.push('/></div>');
553 else if (node.nodeType == 3)
555 html.push('<div class="nodeText">', escapeHTML(node.nodeValue),
560 // ********************************************************************************************
562 function addEvent(object, name, handler)
565 object.attachEvent("on"+name, handler);
567 object.addEventListener(name, handler, false);
570 function removeEvent(object, name, handler)
573 object.detachEvent("on"+name, handler);
575 object.removeEventListener(name, handler, false);
578 function cancelEvent(event)
581 event.cancelBubble = true;
583 event.stopPropagation();
586 function onError(msg, href, lineNo)
590 var lastSlash = href.lastIndexOf("/");
591 var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
594 '<span class="errorMessage">', msg, '</span>',
595 '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
598 logRow(html, "error");
601 function onKeyDown(event)
603 if (event.keyCode == 123)
605 else if ((event.keyCode == 108 || event.keyCode == 76) && event.shiftKey
606 && (event.metaKey || event.ctrlKey))
614 function onSplitterMouseDown(event)
616 if (isSafari || isOpera)
619 addEvent(document, "mousemove", onSplitterMouseMove);
620 addEvent(document, "mouseup", onSplitterMouseUp);
622 for (var i = 0; i < frames.length; ++i)
624 addEvent(frames[i].document, "mousemove", onSplitterMouseMove);
625 addEvent(frames[i].document, "mouseup", onSplitterMouseUp);
629 function onSplitterMouseMove(event)
631 var win = document.all
632 ? event.srcElement.ownerDocument.parentWindow
633 : event.target.ownerDocument.defaultView;
635 var clientY = event.clientY;
636 if (win != win.parent)
637 clientY += win.frameElement ? win.frameElement.offsetTop : 0;
639 var height = consoleFrame.offsetTop + consoleFrame.clientHeight;
640 var toolbar = consoleBody.ownerDocument.getElementById("toolbar");
641 var y = Math.max(height - clientY,
642 toolbar.offsetHeight + commandLine.offsetHeight);
644 consoleFrame.style.height = y + "px";
648 function onSplitterMouseUp(event)
650 removeEvent(document, "mousemove", onSplitterMouseMove);
651 removeEvent(document, "mouseup", onSplitterMouseUp);
653 for (var i = 0; i < frames.length; ++i)
655 removeEvent(frames[i].document, "mousemove", onSplitterMouseMove);
656 removeEvent(frames[i].document, "mouseup", onSplitterMouseUp);
660 function onCommandLineKeyDown(event)
662 if (event.keyCode == 13)
664 else if (event.keyCode == 27)
665 commandLine.value = "";
668 window.onerror = onError;
669 addEvent(document, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
671 if (document.documentElement.getAttribute("debug") == "true")