PageRenderTime 440ms CodeModel.GetById 100ms app.highlight 260ms RepoModel.GetById 73ms app.codeStats 0ms

/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
  2if (!("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}