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