log4javascript-rails 1.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +25 -0
  3. data/lib/log4javascript-rails.rb +8 -0
  4. data/lib/log4javascript-rails/version.rb +5 -0
  5. data/vendor/assets/javascripts/log4javascript-1.4.6.tar.gz +0 -0
  6. data/vendor/assets/javascripts/log4javascript-1.4.6/changelog.txt +379 -0
  7. data/vendor/assets/javascripts/log4javascript-1.4.6/console.html +263 -0
  8. data/vendor/assets/javascripts/log4javascript-1.4.6/console_uncompressed.html +2279 -0
  9. data/vendor/assets/javascripts/log4javascript-1.4.6/demos/basic.html +159 -0
  10. data/vendor/assets/javascripts/log4javascript-1.4.6/demos/blank.html +4 -0
  11. data/vendor/assets/javascripts/log4javascript-1.4.6/demos/index.html +49 -0
  12. data/vendor/assets/javascripts/log4javascript-1.4.6/demos/inpage.html +174 -0
  13. data/vendor/assets/javascripts/log4javascript-1.4.6/demos/lite.html +148 -0
  14. data/vendor/assets/javascripts/log4javascript-1.4.6/docs/backwardsincompatibilities.html +90 -0
  15. data/vendor/assets/javascripts/log4javascript-1.4.6/docs/distribution.html +87 -0
  16. data/vendor/assets/javascripts/log4javascript-1.4.6/docs/index.html +190 -0
  17. data/vendor/assets/javascripts/log4javascript-1.4.6/docs/lite.html +182 -0
  18. data/vendor/assets/javascripts/log4javascript-1.4.6/docs/manual.html +3198 -0
  19. data/vendor/assets/javascripts/log4javascript-1.4.6/docs/manual_lite.html +383 -0
  20. data/vendor/assets/javascripts/log4javascript-1.4.6/docs/quickstart.html +230 -0
  21. data/vendor/assets/javascripts/log4javascript-1.4.6/docs/whatsnew.html +86 -0
  22. data/vendor/assets/javascripts/log4javascript-1.4.6/examples/demo.html +16 -0
  23. data/vendor/assets/javascripts/log4javascript-1.4.6/examples/example_manual.html +31 -0
  24. data/vendor/assets/javascripts/log4javascript-1.4.6/examples/example_quickstart_1.html +36 -0
  25. data/vendor/assets/javascripts/log4javascript-1.4.6/examples/myloggingservlet.do +0 -0
  26. data/vendor/assets/javascripts/log4javascript-1.4.6/js/console.html +263 -0
  27. data/vendor/assets/javascripts/log4javascript-1.4.6/js/console_uncompressed.html +2279 -0
  28. data/vendor/assets/javascripts/log4javascript-1.4.6/js/liteconsole.html +41 -0
  29. data/vendor/assets/javascripts/log4javascript-1.4.6/js/liteconsole_uncompressed.html +194 -0
  30. data/vendor/assets/javascripts/log4javascript-1.4.6/js/log4javascript.js +274 -0
  31. data/vendor/assets/javascripts/log4javascript-1.4.6/js/log4javascript_lite.js +55 -0
  32. data/vendor/assets/javascripts/log4javascript-1.4.6/js/log4javascript_lite_uncompressed.js +620 -0
  33. data/vendor/assets/javascripts/log4javascript-1.4.6/js/log4javascript_production.js +188 -0
  34. data/vendor/assets/javascripts/log4javascript-1.4.6/js/log4javascript_production_uncompressed.js +2290 -0
  35. data/vendor/assets/javascripts/log4javascript-1.4.6/js/log4javascript_uncompressed.js +5879 -0
  36. data/vendor/assets/javascripts/log4javascript-1.4.6/js/stubs/log4javascript.js +23 -0
  37. data/vendor/assets/javascripts/log4javascript-1.4.6/js/stubs/log4javascript_lite.js +21 -0
  38. data/vendor/assets/javascripts/log4javascript-1.4.6/js/stubs/log4javascript_lite_uncompressed.js +102 -0
  39. data/vendor/assets/javascripts/log4javascript-1.4.6/js/stubs/log4javascript_production.js +22 -0
  40. data/vendor/assets/javascripts/log4javascript-1.4.6/js/stubs/log4javascript_production_uncompressed.js +253 -0
  41. data/vendor/assets/javascripts/log4javascript-1.4.6/js/stubs/log4javascript_uncompressed.js +341 -0
  42. data/vendor/assets/javascripts/log4javascript-1.4.6/js/tests/log4javascript.js +32 -0
  43. data/vendor/assets/javascripts/log4javascript-1.4.6/js/tests/log4javascript_lite.js +16 -0
  44. data/vendor/assets/javascripts/log4javascript-1.4.6/js/tests/log4javascript_lite_uncompressed.js +16 -0
  45. data/vendor/assets/javascripts/log4javascript-1.4.6/js/tests/log4javascript_production.js +28 -0
  46. data/vendor/assets/javascripts/log4javascript-1.4.6/js/tests/log4javascript_production_uncompressed.js +728 -0
  47. data/vendor/assets/javascripts/log4javascript-1.4.6/js/tests/log4javascript_uncompressed.js +862 -0
  48. data/vendor/assets/javascripts/log4javascript-1.4.6/license.txt +201 -0
  49. data/vendor/assets/javascripts/log4javascript-1.4.6/log4javascript.js +274 -0
  50. data/vendor/assets/javascripts/log4javascript-1.4.6/log4javascript_uncompressed.js +5879 -0
  51. data/vendor/assets/javascripts/log4javascript-1.4.6/main.css +300 -0
  52. data/vendor/assets/javascripts/log4javascript-1.4.6/test/index.html +15 -0
  53. data/vendor/assets/javascripts/log4javascript-1.4.6/test/log4javascript.html +16 -0
  54. data/vendor/assets/javascripts/log4javascript-1.4.6/test/log4javascript_lite.html +16 -0
  55. data/vendor/assets/javascripts/log4javascript-1.4.6/test/log4javascript_lite_uncompressed.html +16 -0
  56. data/vendor/assets/javascripts/log4javascript-1.4.6/test/log4javascript_production.html +16 -0
  57. data/vendor/assets/javascripts/log4javascript-1.4.6/test/log4javascript_production_uncompressed.html +16 -0
  58. data/vendor/assets/javascripts/log4javascript-1.4.6/test/log4javascript_uncompressed.html +16 -0
  59. data/vendor/assets/javascripts/log4javascript-1.4.6/test/main.html +16 -0
  60. data/vendor/assets/javascripts/log4javascript-1.4.6/test/tests.css +88 -0
  61. data/vendor/assets/javascripts/log4javascript-1.4.6/test/xntest.js +739 -0
  62. data/vendor/assets/javascripts/log4javascript.js +1 -0
  63. data/vendor/assets/stylesheets/angular-ng-grid-rails.css +439 -0
  64. metadata +107 -0
@@ -0,0 +1,86 @@
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
+ <head>
5
+ <title>log4javascript - what's new in version 1.4</title>
6
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
7
+ <meta name="author" content="Tim Down - tim@log4javascript.org" />
8
+ <meta name="description" content="log4javascript, a logging framework for JavaScript based on log4j" />
9
+ <meta name="robots" content="all" />
10
+ <link rel="stylesheet" type="text/css" media="screen,print" href="../main.css" title="Default" />
11
+ </head>
12
+ <body>
13
+ <div id="container" class="nonav">
14
+ <div id="header">
15
+ <h1><a href="index.html">log4javascript</a></h1>
16
+ </div>
17
+ <div id="content">
18
+ <div id="nav">
19
+ <a class="navitem" href="../index.html">home</a>
20
+ | <a class="navitem" href="http://sourceforge.net/projects/log4javascript" target="_blank" title="Download (opens in new window)">download</a>
21
+ | <a class="navitem" href="index.html">docs</a>
22
+ | <a class="navitem" href="quickstart.html">quick start</a>
23
+ | <a class="navitem" href="../demos/index.html">demos</a>
24
+ | <a class="navitem" href="http://log4javascript.org" target="_blank">website</a>
25
+ | <a class="navitem" href="http://www.timdown.co.uk" target="_blank">timdown.co.uk</a>
26
+ </div>
27
+ <h1>log4javascript - what's new in version 1.4</h1>
28
+ <ul>
29
+ <li>
30
+ log4javascript now comes in three different editions: Standard, Production
31
+ and Lite. <a href="distribution.html">Full details here</a>.
32
+ </li>
33
+ <li>
34
+ Loggers are now hierarchical and work exactly the same as log4j loggers.
35
+ This means that a logger with no level set on it inherits its level from its parent,
36
+ and inherits all of its parents appenders.
37
+ </li>
38
+ <li>
39
+ The logging console used by <code><a href="manual.html#popupappender">PopUpAppender</a></code> and
40
+ <code><a href="manual.html#inpageappender">InPageAppender</a></code>now has a command line, featuring
41
+ a command history navigated with the up and down arrow keys and a number of built-in command line
42
+ functions.
43
+ </li>
44
+ <li>
45
+ It is now possible to specify multiple messages in a single log call.
46
+ </li>
47
+ <li>
48
+ Log messages may be grouped in the logging console.
49
+ </li>
50
+ <li>
51
+ Built-in timers.
52
+ </li>
53
+ <li>
54
+ Improved <code><a href="manual.html#ajaxappender">AjaxAppender</a></code>, with the ability
55
+ to send all pending log calls to the server when navigating away from a page. Timestamps now
56
+ include milliseconds. All log messages or batches of log messages are now posted as
57
+ name-value pairs.
58
+ </li>
59
+ <li>
60
+ Support for IE8 beta 2.
61
+ </li>
62
+ <li>
63
+ Many minor enhancements and bug fixes. See the <a href="../changelog.txt">change log</a> for full
64
+ details.
65
+ </li>
66
+ </ul>
67
+ <p>
68
+ Please note that there are a few minor <a href="backwardsincompatibilities.html">incompatibilities
69
+ with earlier versions of log4javascript</a>.
70
+ </p>
71
+ </div>
72
+ <div id="footer">
73
+ <span class="externallinkinfo">
74
+ <strong>NB.</strong> All external links open in a new window.
75
+ </span>
76
+ Written by Tim Down. <a href="mailto:tim@log4javascript.org">tim@log4javascript.org</a>
77
+ <br />
78
+ log4javascript is distributed under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html"
79
+ title="Apache License, Version 2.0 (opens in new window)" target="_blank">Apache License,
80
+ Version 2.0</a>
81
+
82
+ </div>
83
+ </div>
84
+
85
+ </body>
86
+ </html>
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
+ <head>
5
+ <title>log4javascript demo redirect</title>
6
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
7
+ <meta name="author" content="Tim Down - tim@log4javascript.org" />
8
+ <meta name="description" content="log4javascript, a logging framework for JavaScript based on log4j" />
9
+ <meta name="robots" content="noindex" />
10
+ <meta http-equiv="refresh" content="0; url=../demos/basic.html" />
11
+ </head>
12
+ <body>
13
+ This page has been replaced by <a href="/demos/basic.html">the basic demo page</a>.
14
+ Please use this link if you are not redirected automatically.
15
+ </body>
16
+ </html>
@@ -0,0 +1,31 @@
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
+ <head>
5
+ <title>log4javascript example from manual</title>
6
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
7
+ <meta name="author" content="Tim Down - tim@log4javascript.org" />
8
+ <meta name="description" content="log4javascript, a logging framework for JavaScript based on log4j" />
9
+ <meta name="robots" content="all" />
10
+ <script type="text/javascript" src="../js/log4javascript.js"></script>
11
+ <script type="text/javascript">
12
+ //<![CDATA[
13
+ var log = log4javascript.getLogger();
14
+ var popUpAppender = new log4javascript.PopUpAppender();
15
+ var popUpLayout = new log4javascript.PatternLayout("%d{HH:mm:ss} %-5p - %m%n");
16
+ popUpAppender.setLayout(popUpLayout);
17
+ log.addAppender(popUpAppender);
18
+ var ajaxAppender = new log4javascript.AjaxAppender("myloggingservlet.do");
19
+ ajaxAppender.setThreshold(log4javascript.Level.ERROR);
20
+ log.addAppender(ajaxAppender);
21
+ log.debug("Debugging message (appears in pop-up)");
22
+ log.error("Error message (appears in pop-up and in server log)");
23
+ //]]>
24
+ </script>
25
+ </head>
26
+ <body>
27
+ <h1>log4javascript example from manual</h1>
28
+
29
+
30
+ </body>
31
+ </html>
@@ -0,0 +1,36 @@
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
+ <head>
5
+ <title>log4javascript quick start example 1</title>
6
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
7
+ <meta name="author" content="Tim Down - tim@log4javascript.org" />
8
+ <meta name="description" content="log4javascript, a logging framework for JavaScript based on log4j" />
9
+ <meta name="robots" content="all" />
10
+ <script type="text/javascript" src="../js/log4javascript.js"></script>
11
+ <script type="text/javascript">
12
+ //<![CDATA[
13
+ // Create the logger
14
+ var log = log4javascript.getLogger();
15
+
16
+ // Create a PopUpAppender with default options
17
+ var popUpAppender = new log4javascript.PopUpAppender();
18
+
19
+ // Change the desired configuration options
20
+ popUpAppender.setFocusPopUp(true);
21
+ popUpAppender.setNewestMessageAtTop(true);
22
+
23
+ // Add the appender to the logger
24
+ log.addAppender(popUpAppender);
25
+
26
+ // Test the logger
27
+ log.debug("Hello world!");
28
+ //]]>
29
+ </script>
30
+ </head>
31
+ <body>
32
+ <h1>log4javascript quick start example 1</h1>
33
+
34
+
35
+ </body>
36
+ </html>
@@ -0,0 +1,263 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
3
+ <head>
4
+ <title>log4javascript</title>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+ <!-- Make IE8 behave like IE7, having gone to all the trouble of making IE work -->
7
+ <meta http-equiv="X-UA-Compatible" content="IE=7" />
8
+ <script type="text/javascript">var isIe = false, isIePre7 = false;</script>
9
+ <!--[if IE]><script type="text/javascript">isIe = true</script><![endif]-->
10
+ <!--[if lt IE 7]><script type="text/javascript">isIePre7 = true</script><![endif]-->
11
+ <script type="text/javascript">
12
+ //<![CDATA[
13
+ var loggingEnabled=true;var logQueuedEventsTimer=null;var logEntries=[];var logEntriesAndSeparators=[];var logItems=[];var renderDelay=100;var unrenderedLogItemsExist=false;var rootGroup,currentGroup=null;var loaded=false;var currentLogItem=null;var logMainContainer;function copyProperties(obj,props){for(var i in props){obj[i]=props[i];}}
14
+ function LogItem(){}
15
+ LogItem.prototype={mainContainer:null,wrappedContainer:null,unwrappedContainer:null,group:null,appendToLog:function(){for(var i=0,len=this.elementContainers.length;i<len;i++){this.elementContainers[i].appendToLog();}
16
+ this.group.update();},doRemove:function(doUpdate,removeFromGroup){if(this.rendered){for(var i=0,len=this.elementContainers.length;i<len;i++){this.elementContainers[i].remove();}
17
+ this.unwrappedElementContainer=null;this.wrappedElementContainer=null;this.mainElementContainer=null;}
18
+ if(this.group&&removeFromGroup){this.group.removeChild(this,doUpdate);}
19
+ if(this===currentLogItem){currentLogItem=null;}},remove:function(doUpdate,removeFromGroup){this.doRemove(doUpdate,removeFromGroup);},render:function(){},accept:function(visitor){visitor.visit(this);},getUnwrappedDomContainer:function(){return this.group.unwrappedElementContainer.contentDiv;},getWrappedDomContainer:function(){return this.group.wrappedElementContainer.contentDiv;},getMainDomContainer:function(){return this.group.mainElementContainer.contentDiv;}};LogItem.serializedItemKeys={LOG_ENTRY:0,GROUP_START:1,GROUP_END:2};function LogItemContainerElement(){}
20
+ LogItemContainerElement.prototype={appendToLog:function(){var insertBeforeFirst=(newestAtTop&&this.containerDomNode.hasChildNodes());if(insertBeforeFirst){this.containerDomNode.insertBefore(this.mainDiv,this.containerDomNode.firstChild);}else{this.containerDomNode.appendChild(this.mainDiv);}}};function SeparatorElementContainer(containerDomNode){this.containerDomNode=containerDomNode;this.mainDiv=document.createElement("div");this.mainDiv.className="separator";this.mainDiv.innerHTML="&nbsp;";}
21
+ SeparatorElementContainer.prototype=new LogItemContainerElement();SeparatorElementContainer.prototype.remove=function(){this.mainDiv.parentNode.removeChild(this.mainDiv);this.mainDiv=null;};function Separator(){this.rendered=false;}
22
+ Separator.prototype=new LogItem();copyProperties(Separator.prototype,{render:function(){var containerDomNode=this.group.contentDiv;if(isIe){this.unwrappedElementContainer=new SeparatorElementContainer(this.getUnwrappedDomContainer());this.wrappedElementContainer=new SeparatorElementContainer(this.getWrappedDomContainer());this.elementContainers=[this.unwrappedElementContainer,this.wrappedElementContainer];}else{this.mainElementContainer=new SeparatorElementContainer(this.getMainDomContainer());this.elementContainers=[this.mainElementContainer];}
23
+ this.content=this.formattedMessage;this.rendered=true;}});function GroupElementContainer(group,containerDomNode,isRoot,isWrapped){this.group=group;this.containerDomNode=containerDomNode;this.isRoot=isRoot;this.isWrapped=isWrapped;this.expandable=false;if(this.isRoot){if(isIe){this.contentDiv=logMainContainer.appendChild(document.createElement("div"));this.contentDiv.id=this.isWrapped?"log_wrapped":"log_unwrapped";}else{this.contentDiv=logMainContainer;}}else{var groupElementContainer=this;this.mainDiv=document.createElement("div");this.mainDiv.className="group";this.headingDiv=this.mainDiv.appendChild(document.createElement("div"));this.headingDiv.className="groupheading";this.expander=this.headingDiv.appendChild(document.createElement("span"));this.expander.className="expander unselectable greyedout";this.expander.unselectable=true;var expanderText=this.group.expanded?"-":"+";this.expanderTextNode=this.expander.appendChild(document.createTextNode(expanderText));this.headingDiv.appendChild(document.createTextNode(" "+this.group.name));this.contentDiv=this.mainDiv.appendChild(document.createElement("div"));var contentCssClass=this.group.expanded?"expanded":"collapsed";this.contentDiv.className="groupcontent "+contentCssClass;this.expander.onclick=function(){if(groupElementContainer.group.expandable){groupElementContainer.group.toggleExpanded();}};}}
24
+ GroupElementContainer.prototype=new LogItemContainerElement();copyProperties(GroupElementContainer.prototype,{toggleExpanded:function(){if(!this.isRoot){var oldCssClass,newCssClass,expanderText;if(this.group.expanded){newCssClass="expanded";oldCssClass="collapsed";expanderText="-";}else{newCssClass="collapsed";oldCssClass="expanded";expanderText="+";}
25
+ replaceClass(this.contentDiv,newCssClass,oldCssClass);this.expanderTextNode.nodeValue=expanderText;}},remove:function(){if(!this.isRoot){this.headingDiv=null;this.expander.onclick=null;this.expander=null;this.expanderTextNode=null;this.contentDiv=null;this.containerDomNode=null;this.mainDiv.parentNode.removeChild(this.mainDiv);this.mainDiv=null;}},reverseChildren:function(){var node=null;var childDomNodes=[];while((node=this.contentDiv.firstChild)){this.contentDiv.removeChild(node);childDomNodes.push(node);}
26
+ while((node=childDomNodes.pop())){this.contentDiv.appendChild(node);}},update:function(){if(!this.isRoot){if(this.group.expandable){removeClass(this.expander,"greyedout");}else{addClass(this.expander,"greyedout");}}},clear:function(){if(this.isRoot){this.contentDiv.innerHTML="";}}});function Group(name,isRoot,initiallyExpanded){this.name=name;this.group=null;this.isRoot=isRoot;this.initiallyExpanded=initiallyExpanded;this.elementContainers=[];this.children=[];this.expanded=initiallyExpanded;this.rendered=false;this.expandable=false;}
27
+ Group.prototype=new LogItem();copyProperties(Group.prototype,{addChild:function(logItem){this.children.push(logItem);logItem.group=this;},render:function(){if(isIe){var unwrappedDomContainer,wrappedDomContainer;if(this.isRoot){unwrappedDomContainer=logMainContainer;wrappedDomContainer=logMainContainer;}else{unwrappedDomContainer=this.getUnwrappedDomContainer();wrappedDomContainer=this.getWrappedDomContainer();}
28
+ this.unwrappedElementContainer=new GroupElementContainer(this,unwrappedDomContainer,this.isRoot,false);this.wrappedElementContainer=new GroupElementContainer(this,wrappedDomContainer,this.isRoot,true);this.elementContainers=[this.unwrappedElementContainer,this.wrappedElementContainer];}else{var mainDomContainer=this.isRoot?logMainContainer:this.getMainDomContainer();this.mainElementContainer=new GroupElementContainer(this,mainDomContainer,this.isRoot,false);this.elementContainers=[this.mainElementContainer];}
29
+ this.rendered=true;},toggleExpanded:function(){this.expanded=!this.expanded;for(var i=0,len=this.elementContainers.length;i<len;i++){this.elementContainers[i].toggleExpanded();}},expand:function(){if(!this.expanded){this.toggleExpanded();}},accept:function(visitor){visitor.visitGroup(this);},reverseChildren:function(){if(this.rendered){for(var i=0,len=this.elementContainers.length;i<len;i++){this.elementContainers[i].reverseChildren();}}},update:function(){var previouslyExpandable=this.expandable;this.expandable=(this.children.length!==0);if(this.expandable!==previouslyExpandable){for(var i=0,len=this.elementContainers.length;i<len;i++){this.elementContainers[i].update();}}},flatten:function(){var visitor=new GroupFlattener();this.accept(visitor);return visitor.logEntriesAndSeparators;},removeChild:function(child,doUpdate){array_remove(this.children,child);child.group=null;if(doUpdate){this.update();}},remove:function(doUpdate,removeFromGroup){for(var i=0,len=this.children.length;i<len;i++){this.children[i].remove(false,false);}
30
+ this.children=[];this.update();if(this===currentGroup){currentGroup=this.group;}
31
+ this.doRemove(doUpdate,removeFromGroup);},serialize:function(items){items.push([LogItem.serializedItemKeys.GROUP_START,this.name]);for(var i=0,len=this.children.length;i<len;i++){this.children[i].serialize(items);}
32
+ if(this!==currentGroup){items.push([LogItem.serializedItemKeys.GROUP_END]);}},clear:function(){for(var i=0,len=this.elementContainers.length;i<len;i++){this.elementContainers[i].clear();}}});function LogEntryElementContainer(){}
33
+ LogEntryElementContainer.prototype=new LogItemContainerElement();copyProperties(LogEntryElementContainer.prototype,{remove:function(){this.doRemove();},doRemove:function(){this.mainDiv.parentNode.removeChild(this.mainDiv);this.mainDiv=null;this.contentElement=null;this.containerDomNode=null;},setContent:function(content,wrappedContent){if(content===this.formattedMessage){this.contentElement.innerHTML="";this.contentElement.appendChild(document.createTextNode(this.formattedMessage));}else{this.contentElement.innerHTML=content;}},setSearchMatch:function(isMatch){var oldCssClass=isMatch?"searchnonmatch":"searchmatch";var newCssClass=isMatch?"searchmatch":"searchnonmatch";replaceClass(this.mainDiv,newCssClass,oldCssClass);},clearSearch:function(){removeClass(this.mainDiv,"searchmatch");removeClass(this.mainDiv,"searchnonmatch");}});function LogEntryWrappedElementContainer(logEntry,containerDomNode){this.logEntry=logEntry;this.containerDomNode=containerDomNode;this.mainDiv=document.createElement("div");this.mainDiv.appendChild(document.createTextNode(this.logEntry.formattedMessage));this.mainDiv.className="logentry wrapped "+this.logEntry.level;this.contentElement=this.mainDiv;}
34
+ LogEntryWrappedElementContainer.prototype=new LogEntryElementContainer();LogEntryWrappedElementContainer.prototype.setContent=function(content,wrappedContent){if(content===this.formattedMessage){this.contentElement.innerHTML="";this.contentElement.appendChild(document.createTextNode(this.formattedMessage));}else{this.contentElement.innerHTML=wrappedContent;}};function LogEntryUnwrappedElementContainer(logEntry,containerDomNode){this.logEntry=logEntry;this.containerDomNode=containerDomNode;this.mainDiv=document.createElement("div");this.mainDiv.className="logentry unwrapped "+this.logEntry.level;this.pre=this.mainDiv.appendChild(document.createElement("pre"));this.pre.appendChild(document.createTextNode(this.logEntry.formattedMessage));this.pre.className="unwrapped";this.contentElement=this.pre;}
35
+ LogEntryUnwrappedElementContainer.prototype=new LogEntryElementContainer();LogEntryUnwrappedElementContainer.prototype.remove=function(){this.doRemove();this.pre=null;};function LogEntryMainElementContainer(logEntry,containerDomNode){this.logEntry=logEntry;this.containerDomNode=containerDomNode;this.mainDiv=document.createElement("div");this.mainDiv.className="logentry nonielogentry "+this.logEntry.level;this.contentElement=this.mainDiv.appendChild(document.createElement("span"));this.contentElement.appendChild(document.createTextNode(this.logEntry.formattedMessage));}
36
+ LogEntryMainElementContainer.prototype=new LogEntryElementContainer();function LogEntry(level,formattedMessage){this.level=level;this.formattedMessage=formattedMessage;this.rendered=false;}
37
+ LogEntry.prototype=new LogItem();copyProperties(LogEntry.prototype,{render:function(){var logEntry=this;var containerDomNode=this.group.contentDiv;if(isIe){this.formattedMessage=this.formattedMessage.replace(/\r\n/g,"\r");this.unwrappedElementContainer=new LogEntryUnwrappedElementContainer(this,this.getUnwrappedDomContainer());this.wrappedElementContainer=new LogEntryWrappedElementContainer(this,this.getWrappedDomContainer());this.elementContainers=[this.unwrappedElementContainer,this.wrappedElementContainer];}else{this.mainElementContainer=new LogEntryMainElementContainer(this,this.getMainDomContainer());this.elementContainers=[this.mainElementContainer];}
38
+ this.content=this.formattedMessage;this.rendered=true;},setContent:function(content,wrappedContent){if(content!=this.content){if(isIe&&(content!==this.formattedMessage)){content=content.replace(/\r\n/g,"\r");}
39
+ for(var i=0,len=this.elementContainers.length;i<len;i++){this.elementContainers[i].setContent(content,wrappedContent);}
40
+ this.content=content;}},getSearchMatches:function(){var matches=[];var i,len;if(isIe){var unwrappedEls=getElementsByClass(this.unwrappedElementContainer.mainDiv,"searchterm","span");var wrappedEls=getElementsByClass(this.wrappedElementContainer.mainDiv,"searchterm","span");for(i=0,len=unwrappedEls.length;i<len;i++){matches[i]=new Match(this.level,null,unwrappedEls[i],wrappedEls[i]);}}else{var els=getElementsByClass(this.mainElementContainer.mainDiv,"searchterm","span");for(i=0,len=els.length;i<len;i++){matches[i]=new Match(this.level,els[i]);}}
41
+ return matches;},setSearchMatch:function(isMatch){for(var i=0,len=this.elementContainers.length;i<len;i++){this.elementContainers[i].setSearchMatch(isMatch);}},clearSearch:function(){for(var i=0,len=this.elementContainers.length;i<len;i++){this.elementContainers[i].clearSearch();}},accept:function(visitor){visitor.visitLogEntry(this);},serialize:function(items){items.push([LogItem.serializedItemKeys.LOG_ENTRY,this.level,this.formattedMessage]);}});function LogItemVisitor(){}
42
+ LogItemVisitor.prototype={visit:function(logItem){},visitParent:function(logItem){if(logItem.group){logItem.group.accept(this);}},visitChildren:function(logItem){for(var i=0,len=logItem.children.length;i<len;i++){logItem.children[i].accept(this);}},visitLogEntry:function(logEntry){this.visit(logEntry);},visitSeparator:function(separator){this.visit(separator);},visitGroup:function(group){this.visit(group);}};function GroupFlattener(){this.logEntriesAndSeparators=[];}
43
+ GroupFlattener.prototype=new LogItemVisitor();GroupFlattener.prototype.visitGroup=function(group){this.visitChildren(group);};GroupFlattener.prototype.visitLogEntry=function(logEntry){this.logEntriesAndSeparators.push(logEntry);};GroupFlattener.prototype.visitSeparator=function(separator){this.logEntriesAndSeparators.push(separator);};window.onload=function(){if(location.search){var queryBits=unescape(location.search).substr(1).split("&"),nameValueBits;for(var i=0,len=queryBits.length;i<len;i++){nameValueBits=queryBits[i].split("=");if(nameValueBits[0]=="log4javascript_domain"){document.domain=nameValueBits[1];break;}}}
44
+ logMainContainer=$("log");if(isIePre7){addClass(logMainContainer,"oldIe");}
45
+ rootGroup=new Group("root",true);rootGroup.render();currentGroup=rootGroup;setCommandInputWidth();setLogContainerHeight();toggleLoggingEnabled();toggleSearchEnabled();toggleSearchFilter();toggleSearchHighlight();applyFilters();checkAllLevels();toggleWrap();toggleNewestAtTop();toggleScrollToLatest();renderQueuedLogItems();loaded=true;$("command").value="";$("command").autocomplete="off";$("command").onkeydown=function(evt){evt=getEvent(evt);if(evt.keyCode==10||evt.keyCode==13){evalCommandLine();stopPropagation(evt);}else if(evt.keyCode==27){this.value="";this.focus();}else if(evt.keyCode==38&&commandHistory.length>0){currentCommandIndex=Math.max(0,currentCommandIndex-1);this.value=commandHistory[currentCommandIndex];moveCaretToEnd(this);}else if(evt.keyCode==40&&commandHistory.length>0){currentCommandIndex=Math.min(commandHistory.length-1,currentCommandIndex+1);this.value=commandHistory[currentCommandIndex];moveCaretToEnd(this);}};$("command").onkeypress=function(evt){evt=getEvent(evt);if(evt.keyCode==38&&commandHistory.length>0&&evt.preventDefault){evt.preventDefault();}};$("command").onkeyup=function(evt){evt=getEvent(evt);if(evt.keyCode==27&&evt.preventDefault){evt.preventDefault();this.focus();}};document.onkeydown=function keyEventHandler(evt){evt=getEvent(evt);switch(evt.keyCode){case 69:if(evt.shiftKey&&(evt.ctrlKey||evt.metaKey)){evalLastCommand();cancelKeyEvent(evt);return false;}
46
+ break;case 75:if(evt.shiftKey&&(evt.ctrlKey||evt.metaKey)){focusSearch();cancelKeyEvent(evt);return false;}
47
+ break;case 40:case 76:if(evt.shiftKey&&(evt.ctrlKey||evt.metaKey)){focusCommandLine();cancelKeyEvent(evt);return false;}
48
+ break;}};setTimeout(setLogContainerHeight,20);setShowCommandLine(showCommandLine);doSearch();};window.onunload=function(){if(mainWindowExists()){appender.unload();}
49
+ appender=null;};function toggleLoggingEnabled(){setLoggingEnabled($("enableLogging").checked);}
50
+ function setLoggingEnabled(enable){loggingEnabled=enable;}
51
+ var appender=null;function setAppender(appenderParam){appender=appenderParam;}
52
+ function setShowCloseButton(showCloseButton){$("closeButton").style.display=showCloseButton?"inline":"none";}
53
+ function setShowHideButton(showHideButton){$("hideButton").style.display=showHideButton?"inline":"none";}
54
+ var newestAtTop=false;function LogItemContentReverser(){}
55
+ LogItemContentReverser.prototype=new LogItemVisitor();LogItemContentReverser.prototype.visitGroup=function(group){group.reverseChildren();this.visitChildren(group);};function setNewestAtTop(isNewestAtTop){var oldNewestAtTop=newestAtTop;var i,iLen,j,jLen;newestAtTop=Boolean(isNewestAtTop);if(oldNewestAtTop!=newestAtTop){var visitor=new LogItemContentReverser();rootGroup.accept(visitor);if(currentSearch){var currentMatch=currentSearch.matches[currentMatchIndex];var matchIndex=0;var matches=[];var actOnLogEntry=function(logEntry){var logEntryMatches=logEntry.getSearchMatches();for(j=0,jLen=logEntryMatches.length;j<jLen;j++){matches[matchIndex]=logEntryMatches[j];if(currentMatch&&logEntryMatches[j].equals(currentMatch)){currentMatchIndex=matchIndex;}
56
+ matchIndex++;}};if(newestAtTop){for(i=logEntries.length-1;i>=0;i--){actOnLogEntry(logEntries[i]);}}else{for(i=0,iLen=logEntries.length;i<iLen;i++){actOnLogEntry(logEntries[i]);}}
57
+ currentSearch.matches=matches;if(currentMatch){currentMatch.setCurrent();}}else if(scrollToLatest){doScrollToLatest();}}
58
+ $("newestAtTop").checked=isNewestAtTop;}
59
+ function toggleNewestAtTop(){var isNewestAtTop=$("newestAtTop").checked;setNewestAtTop(isNewestAtTop);}
60
+ var scrollToLatest=true;function setScrollToLatest(isScrollToLatest){scrollToLatest=isScrollToLatest;if(scrollToLatest){doScrollToLatest();}
61
+ $("scrollToLatest").checked=isScrollToLatest;}
62
+ function toggleScrollToLatest(){var isScrollToLatest=$("scrollToLatest").checked;setScrollToLatest(isScrollToLatest);}
63
+ function doScrollToLatest(){var l=logMainContainer;if(typeof l.scrollTop!="undefined"){if(newestAtTop){l.scrollTop=0;}else{var latestLogEntry=l.lastChild;if(latestLogEntry){l.scrollTop=l.scrollHeight;}}}}
64
+ var closeIfOpenerCloses=true;function setCloseIfOpenerCloses(isCloseIfOpenerCloses){closeIfOpenerCloses=isCloseIfOpenerCloses;}
65
+ var maxMessages=null;function setMaxMessages(max){maxMessages=max;pruneLogEntries();}
66
+ var showCommandLine=false;function setShowCommandLine(isShowCommandLine){showCommandLine=isShowCommandLine;if(loaded){$("commandLine").style.display=showCommandLine?"block":"none";setCommandInputWidth();setLogContainerHeight();}}
67
+ function focusCommandLine(){if(loaded){$("command").focus();}}
68
+ function focusSearch(){if(loaded){$("searchBox").focus();}}
69
+ function getLogItems(){var items=[];for(var i=0,len=logItems.length;i<len;i++){logItems[i].serialize(items);}
70
+ return items;}
71
+ function setLogItems(items){var loggingReallyEnabled=loggingEnabled;loggingEnabled=true;for(var i=0,len=items.length;i<len;i++){switch(items[i][0]){case LogItem.serializedItemKeys.LOG_ENTRY:log(items[i][1],items[i][2]);break;case LogItem.serializedItemKeys.GROUP_START:group(items[i][1]);break;case LogItem.serializedItemKeys.GROUP_END:groupEnd();break;}}
72
+ loggingEnabled=loggingReallyEnabled;}
73
+ function log(logLevel,formattedMessage){if(loggingEnabled){var logEntry=new LogEntry(logLevel,formattedMessage);logEntries.push(logEntry);logEntriesAndSeparators.push(logEntry);logItems.push(logEntry);currentGroup.addChild(logEntry);if(loaded){if(logQueuedEventsTimer!==null){clearTimeout(logQueuedEventsTimer);}
74
+ logQueuedEventsTimer=setTimeout(renderQueuedLogItems,renderDelay);unrenderedLogItemsExist=true;}}}
75
+ function renderQueuedLogItems(){logQueuedEventsTimer=null;var pruned=pruneLogEntries();var initiallyHasMatches=currentSearch?currentSearch.hasMatches():false;for(var i=0,len=logItems.length;i<len;i++){if(!logItems[i].rendered){logItems[i].render();logItems[i].appendToLog();if(currentSearch&&(logItems[i]instanceof LogEntry)){currentSearch.applyTo(logItems[i]);}}}
76
+ if(currentSearch){if(pruned){if(currentSearch.hasVisibleMatches()){if(currentMatchIndex===null){setCurrentMatchIndex(0);}
77
+ displayMatches();}else{displayNoMatches();}}else if(!initiallyHasMatches&&currentSearch.hasVisibleMatches()){setCurrentMatchIndex(0);displayMatches();}}
78
+ if(scrollToLatest){doScrollToLatest();}
79
+ unrenderedLogItemsExist=false;}
80
+ function pruneLogEntries(){if((maxMessages!==null)&&(logEntriesAndSeparators.length>maxMessages)){var numberToDelete=logEntriesAndSeparators.length-maxMessages;var prunedLogEntries=logEntriesAndSeparators.slice(0,numberToDelete);if(currentSearch){currentSearch.removeMatches(prunedLogEntries);}
81
+ var group;for(var i=0;i<numberToDelete;i++){group=logEntriesAndSeparators[i].group;array_remove(logItems,logEntriesAndSeparators[i]);array_remove(logEntries,logEntriesAndSeparators[i]);logEntriesAndSeparators[i].remove(true,true);if(group.children.length===0&&group!==currentGroup&&group!==rootGroup){array_remove(logItems,group);group.remove(true,true);}}
82
+ logEntriesAndSeparators=array_removeFromStart(logEntriesAndSeparators,numberToDelete);return true;}
83
+ return false;}
84
+ function group(name,startExpanded){if(loggingEnabled){initiallyExpanded=(typeof startExpanded==="undefined")?true:Boolean(startExpanded);var newGroup=new Group(name,false,initiallyExpanded);currentGroup.addChild(newGroup);currentGroup=newGroup;logItems.push(newGroup);if(loaded){if(logQueuedEventsTimer!==null){clearTimeout(logQueuedEventsTimer);}
85
+ logQueuedEventsTimer=setTimeout(renderQueuedLogItems,renderDelay);unrenderedLogItemsExist=true;}}}
86
+ function groupEnd(){currentGroup=(currentGroup===rootGroup)?rootGroup:currentGroup.group;}
87
+ function mainPageReloaded(){currentGroup=rootGroup;var separator=new Separator();logEntriesAndSeparators.push(separator);logItems.push(separator);currentGroup.addChild(separator);}
88
+ function closeWindow(){if(appender&&mainWindowExists()){appender.close(true);}else{window.close();}}
89
+ function hide(){if(appender&&mainWindowExists()){appender.hide();}}
90
+ var mainWindow=window;var windowId="log4javascriptConsoleWindow_"+new Date().getTime()+"_"+(""+Math.random()).substr(2);function setMainWindow(win){mainWindow=win;mainWindow[windowId]=window;if(opener&&closeIfOpenerCloses){pollOpener();}}
91
+ function pollOpener(){if(closeIfOpenerCloses){if(mainWindowExists()){setTimeout(pollOpener,500);}else{closeWindow();}}}
92
+ function mainWindowExists(){try{return(mainWindow&&!mainWindow.closed&&mainWindow[windowId]==window);}catch(ex){}
93
+ return false;}
94
+ var logLevels=["TRACE","DEBUG","INFO","WARN","ERROR","FATAL"];function getCheckBox(logLevel){return $("switch_"+logLevel);}
95
+ function getIeWrappedLogContainer(){return $("log_wrapped");}
96
+ function getIeUnwrappedLogContainer(){return $("log_unwrapped");}
97
+ function applyFilters(){for(var i=0;i<logLevels.length;i++){if(getCheckBox(logLevels[i]).checked){addClass(logMainContainer,logLevels[i]);}else{removeClass(logMainContainer,logLevels[i]);}}
98
+ updateSearchFromFilters();}
99
+ function toggleAllLevels(){var turnOn=$("switch_ALL").checked;for(var i=0;i<logLevels.length;i++){getCheckBox(logLevels[i]).checked=turnOn;if(turnOn){addClass(logMainContainer,logLevels[i]);}else{removeClass(logMainContainer,logLevels[i]);}}}
100
+ function checkAllLevels(){for(var i=0;i<logLevels.length;i++){if(!getCheckBox(logLevels[i]).checked){getCheckBox("ALL").checked=false;return;}}
101
+ getCheckBox("ALL").checked=true;}
102
+ function clearLog(){rootGroup.clear();currentGroup=rootGroup;logEntries=[];logItems=[];logEntriesAndSeparators=[];doSearch();}
103
+ function toggleWrap(){var enable=$("wrap").checked;if(enable){addClass(logMainContainer,"wrap");}else{removeClass(logMainContainer,"wrap");}
104
+ refreshCurrentMatch();}
105
+ var searchTimer=null;function scheduleSearch(){try{clearTimeout(searchTimer);}catch(ex){}
106
+ searchTimer=setTimeout(doSearch,500);}
107
+ function Search(searchTerm,isRegex,searchRegex,isCaseSensitive){this.searchTerm=searchTerm;this.isRegex=isRegex;this.searchRegex=searchRegex;this.isCaseSensitive=isCaseSensitive;this.matches=[];}
108
+ Search.prototype={hasMatches:function(){return this.matches.length>0;},hasVisibleMatches:function(){if(this.hasMatches()){for(var i=0;i<this.matches.length;i++){if(this.matches[i].isVisible()){return true;}}}
109
+ return false;},match:function(logEntry){var entryText=String(logEntry.formattedMessage);var matchesSearch=false;if(this.isRegex){matchesSearch=this.searchRegex.test(entryText);}else if(this.isCaseSensitive){matchesSearch=(entryText.indexOf(this.searchTerm)>-1);}else{matchesSearch=(entryText.toLowerCase().indexOf(this.searchTerm.toLowerCase())>-1);}
110
+ return matchesSearch;},getNextVisibleMatchIndex:function(){for(var i=currentMatchIndex+1;i<this.matches.length;i++){if(this.matches[i].isVisible()){return i;}}
111
+ for(i=0;i<=currentMatchIndex;i++){if(this.matches[i].isVisible()){return i;}}
112
+ return-1;},getPreviousVisibleMatchIndex:function(){for(var i=currentMatchIndex-1;i>=0;i--){if(this.matches[i].isVisible()){return i;}}
113
+ for(var i=this.matches.length-1;i>=currentMatchIndex;i--){if(this.matches[i].isVisible()){return i;}}
114
+ return-1;},applyTo:function(logEntry){var doesMatch=this.match(logEntry);if(doesMatch){logEntry.group.expand();logEntry.setSearchMatch(true);var logEntryContent;var wrappedLogEntryContent;var searchTermReplacementStartTag="<span class=\"searchterm\">";var searchTermReplacementEndTag="<"+"/span>";var preTagName=isIe?"pre":"span";var preStartTag="<"+preTagName+" class=\"pre\">";var preEndTag="<"+"/"+preTagName+">";var startIndex=0;var searchIndex,matchedText,textBeforeMatch;if(this.isRegex){var flags=this.isCaseSensitive?"g":"gi";var capturingRegex=new RegExp("("+this.searchRegex.source+")",flags);var rnd=(""+Math.random()).substr(2);var startToken="%%s"+rnd+"%%";var endToken="%%e"+rnd+"%%";logEntryContent=logEntry.formattedMessage.replace(capturingRegex,startToken+"$1"+endToken);logEntryContent=escapeHtml(logEntryContent);var result;var searchString=logEntryContent;logEntryContent="";wrappedLogEntryContent="";while((searchIndex=searchString.indexOf(startToken,startIndex))>-1){var endTokenIndex=searchString.indexOf(endToken,searchIndex);matchedText=searchString.substring(searchIndex+startToken.length,endTokenIndex);textBeforeMatch=searchString.substring(startIndex,searchIndex);logEntryContent+=preStartTag+textBeforeMatch+preEndTag;logEntryContent+=searchTermReplacementStartTag+preStartTag+matchedText+
115
+ preEndTag+searchTermReplacementEndTag;if(isIe){wrappedLogEntryContent+=textBeforeMatch+searchTermReplacementStartTag+
116
+ matchedText+searchTermReplacementEndTag;}
117
+ startIndex=endTokenIndex+endToken.length;}
118
+ logEntryContent+=preStartTag+searchString.substr(startIndex)+preEndTag;if(isIe){wrappedLogEntryContent+=searchString.substr(startIndex);}}else{logEntryContent="";wrappedLogEntryContent="";var searchTermReplacementLength=searchTermReplacementStartTag.length+
119
+ this.searchTerm.length+searchTermReplacementEndTag.length;var searchTermLength=this.searchTerm.length;var searchTermLowerCase=this.searchTerm.toLowerCase();var logTextLowerCase=logEntry.formattedMessage.toLowerCase();while((searchIndex=logTextLowerCase.indexOf(searchTermLowerCase,startIndex))>-1){matchedText=escapeHtml(logEntry.formattedMessage.substr(searchIndex,this.searchTerm.length));textBeforeMatch=escapeHtml(logEntry.formattedMessage.substring(startIndex,searchIndex));var searchTermReplacement=searchTermReplacementStartTag+
120
+ preStartTag+matchedText+preEndTag+searchTermReplacementEndTag;logEntryContent+=preStartTag+textBeforeMatch+preEndTag+searchTermReplacement;if(isIe){wrappedLogEntryContent+=textBeforeMatch+searchTermReplacementStartTag+
121
+ matchedText+searchTermReplacementEndTag;}
122
+ startIndex=searchIndex+searchTermLength;}
123
+ var textAfterLastMatch=escapeHtml(logEntry.formattedMessage.substr(startIndex));logEntryContent+=preStartTag+textAfterLastMatch+preEndTag;if(isIe){wrappedLogEntryContent+=textAfterLastMatch;}}
124
+ logEntry.setContent(logEntryContent,wrappedLogEntryContent);var logEntryMatches=logEntry.getSearchMatches();this.matches=this.matches.concat(logEntryMatches);}else{logEntry.setSearchMatch(false);logEntry.setContent(logEntry.formattedMessage,logEntry.formattedMessage);}
125
+ return doesMatch;},removeMatches:function(logEntries){var matchesToRemoveCount=0;var currentMatchRemoved=false;var matchesToRemove=[];var i,iLen,j,jLen;for(i=0,iLen=this.matches.length;i<iLen;i++){for(j=0,jLen=logEntries.length;j<jLen;j++){if(this.matches[i].belongsTo(logEntries[j])){matchesToRemove.push(this.matches[i]);if(i===currentMatchIndex){currentMatchRemoved=true;}}}}
126
+ var newMatch=currentMatchRemoved?null:this.matches[currentMatchIndex];if(currentMatchRemoved){for(i=currentMatchIndex,iLen=this.matches.length;i<iLen;i++){if(this.matches[i].isVisible()&&!array_contains(matchesToRemove,this.matches[i])){newMatch=this.matches[i];break;}}}
127
+ for(i=0,iLen=matchesToRemove.length;i<iLen;i++){array_remove(this.matches,matchesToRemove[i]);matchesToRemove[i].remove();}
128
+ if(this.hasVisibleMatches()){if(newMatch===null){setCurrentMatchIndex(0);}else{var newMatchIndex=0;for(i=0,iLen=this.matches.length;i<iLen;i++){if(newMatch===this.matches[i]){newMatchIndex=i;break;}}
129
+ setCurrentMatchIndex(newMatchIndex);}}else{currentMatchIndex=null;displayNoMatches();}}};function getPageOffsetTop(el,container){var currentEl=el;var y=0;while(currentEl&&currentEl!=container){y+=currentEl.offsetTop;currentEl=currentEl.offsetParent;}
130
+ return y;}
131
+ function scrollIntoView(el){var logContainer=logMainContainer;if(!$("wrap").checked){var logContainerLeft=logContainer.scrollLeft;var logContainerRight=logContainerLeft+logContainer.offsetWidth;var elLeft=el.offsetLeft;var elRight=elLeft+el.offsetWidth;if(elLeft<logContainerLeft||elRight>logContainerRight){logContainer.scrollLeft=elLeft-(logContainer.offsetWidth-el.offsetWidth)/2;}}
132
+ var logContainerTop=logContainer.scrollTop;var logContainerBottom=logContainerTop+logContainer.offsetHeight;var elTop=getPageOffsetTop(el)-getToolBarsHeight();var elBottom=elTop+el.offsetHeight;if(elTop<logContainerTop||elBottom>logContainerBottom){logContainer.scrollTop=elTop-(logContainer.offsetHeight-el.offsetHeight)/2;}}
133
+ function Match(logEntryLevel,spanInMainDiv,spanInUnwrappedPre,spanInWrappedDiv){this.logEntryLevel=logEntryLevel;this.spanInMainDiv=spanInMainDiv;if(isIe){this.spanInUnwrappedPre=spanInUnwrappedPre;this.spanInWrappedDiv=spanInWrappedDiv;}
134
+ this.mainSpan=isIe?spanInUnwrappedPre:spanInMainDiv;}
135
+ Match.prototype={equals:function(match){return this.mainSpan===match.mainSpan;},setCurrent:function(){if(isIe){addClass(this.spanInUnwrappedPre,"currentmatch");addClass(this.spanInWrappedDiv,"currentmatch");var elementToScroll=$("wrap").checked?this.spanInWrappedDiv:this.spanInUnwrappedPre;scrollIntoView(elementToScroll);}else{addClass(this.spanInMainDiv,"currentmatch");scrollIntoView(this.spanInMainDiv);}},belongsTo:function(logEntry){if(isIe){return isDescendant(this.spanInUnwrappedPre,logEntry.unwrappedPre);}else{return isDescendant(this.spanInMainDiv,logEntry.mainDiv);}},setNotCurrent:function(){if(isIe){removeClass(this.spanInUnwrappedPre,"currentmatch");removeClass(this.spanInWrappedDiv,"currentmatch");}else{removeClass(this.spanInMainDiv,"currentmatch");}},isOrphan:function(){return isOrphan(this.mainSpan);},isVisible:function(){return getCheckBox(this.logEntryLevel).checked;},remove:function(){if(isIe){this.spanInUnwrappedPre=null;this.spanInWrappedDiv=null;}else{this.spanInMainDiv=null;}}};var currentSearch=null;var currentMatchIndex=null;function doSearch(){var searchBox=$("searchBox");var searchTerm=searchBox.value;var isRegex=$("searchRegex").checked;var isCaseSensitive=$("searchCaseSensitive").checked;var i;if(searchTerm===""){$("searchReset").disabled=true;$("searchNav").style.display="none";removeClass(document.body,"searching");removeClass(searchBox,"hasmatches");removeClass(searchBox,"nomatches");for(i=0;i<logEntries.length;i++){logEntries[i].clearSearch();logEntries[i].setContent(logEntries[i].formattedMessage,logEntries[i].formattedMessage);}
136
+ currentSearch=null;setLogContainerHeight();}else{$("searchReset").disabled=false;$("searchNav").style.display="block";var searchRegex;var regexValid;if(isRegex){try{searchRegex=isCaseSensitive?new RegExp(searchTerm,"g"):new RegExp(searchTerm,"gi");regexValid=true;replaceClass(searchBox,"validregex","invalidregex");searchBox.title="Valid regex";}catch(ex){regexValid=false;replaceClass(searchBox,"invalidregex","validregex");searchBox.title="Invalid regex: "+(ex.message?ex.message:(ex.description?ex.description:"unknown error"));return;}}else{searchBox.title="";removeClass(searchBox,"validregex");removeClass(searchBox,"invalidregex");}
137
+ addClass(document.body,"searching");currentSearch=new Search(searchTerm,isRegex,searchRegex,isCaseSensitive);for(i=0;i<logEntries.length;i++){currentSearch.applyTo(logEntries[i]);}
138
+ setLogContainerHeight();if(currentSearch.hasVisibleMatches()){setCurrentMatchIndex(0);displayMatches();}else{displayNoMatches();}}}
139
+ function updateSearchFromFilters(){if(currentSearch){if(currentSearch.hasMatches()){if(currentMatchIndex===null){currentMatchIndex=0;}
140
+ var currentMatch=currentSearch.matches[currentMatchIndex];if(currentMatch.isVisible()){displayMatches();setCurrentMatchIndex(currentMatchIndex);}else{currentMatch.setNotCurrent();var nextVisibleMatchIndex=currentSearch.getNextVisibleMatchIndex();if(nextVisibleMatchIndex>-1){setCurrentMatchIndex(nextVisibleMatchIndex);displayMatches();}else{displayNoMatches();}}}else{displayNoMatches();}}}
141
+ function refreshCurrentMatch(){if(currentSearch&&currentSearch.hasVisibleMatches()){setCurrentMatchIndex(currentMatchIndex);}}
142
+ function displayMatches(){replaceClass($("searchBox"),"hasmatches","nomatches");$("searchBox").title=""+currentSearch.matches.length+" matches found";$("searchNav").style.display="block";setLogContainerHeight();}
143
+ function displayNoMatches(){replaceClass($("searchBox"),"nomatches","hasmatches");$("searchBox").title="No matches found";$("searchNav").style.display="none";setLogContainerHeight();}
144
+ function toggleSearchEnabled(enable){enable=(typeof enable=="undefined")?!$("searchDisable").checked:enable;$("searchBox").disabled=!enable;$("searchReset").disabled=!enable;$("searchRegex").disabled=!enable;$("searchNext").disabled=!enable;$("searchPrevious").disabled=!enable;$("searchCaseSensitive").disabled=!enable;$("searchNav").style.display=(enable&&($("searchBox").value!=="")&&currentSearch&&currentSearch.hasVisibleMatches())?"block":"none";if(enable){removeClass($("search"),"greyedout");addClass(document.body,"searching");if($("searchHighlight").checked){addClass(logMainContainer,"searchhighlight");}else{removeClass(logMainContainer,"searchhighlight");}
145
+ if($("searchFilter").checked){addClass(logMainContainer,"searchfilter");}else{removeClass(logMainContainer,"searchfilter");}
146
+ $("searchDisable").checked=!enable;}else{addClass($("search"),"greyedout");removeClass(document.body,"searching");removeClass(logMainContainer,"searchhighlight");removeClass(logMainContainer,"searchfilter");}
147
+ setLogContainerHeight();}
148
+ function toggleSearchFilter(){var enable=$("searchFilter").checked;if(enable){addClass(logMainContainer,"searchfilter");}else{removeClass(logMainContainer,"searchfilter");}
149
+ refreshCurrentMatch();}
150
+ function toggleSearchHighlight(){var enable=$("searchHighlight").checked;if(enable){addClass(logMainContainer,"searchhighlight");}else{removeClass(logMainContainer,"searchhighlight");}}
151
+ function clearSearch(){$("searchBox").value="";doSearch();}
152
+ function searchNext(){if(currentSearch!==null&&currentMatchIndex!==null){currentSearch.matches[currentMatchIndex].setNotCurrent();var nextMatchIndex=currentSearch.getNextVisibleMatchIndex();if(nextMatchIndex>currentMatchIndex||confirm("Reached the end of the page. Start from the top?")){setCurrentMatchIndex(nextMatchIndex);}}}
153
+ function searchPrevious(){if(currentSearch!==null&&currentMatchIndex!==null){currentSearch.matches[currentMatchIndex].setNotCurrent();var previousMatchIndex=currentSearch.getPreviousVisibleMatchIndex();if(previousMatchIndex<currentMatchIndex||confirm("Reached the start of the page. Continue from the bottom?")){setCurrentMatchIndex(previousMatchIndex);}}}
154
+ function setCurrentMatchIndex(index){currentMatchIndex=index;currentSearch.matches[currentMatchIndex].setCurrent();}
155
+ function addClass(el,cssClass){if(!hasClass(el,cssClass)){if(el.className){el.className+=" "+cssClass;}else{el.className=cssClass;}}}
156
+ function hasClass(el,cssClass){if(el.className){var classNames=el.className.split(" ");return array_contains(classNames,cssClass);}
157
+ return false;}
158
+ function removeClass(el,cssClass){if(hasClass(el,cssClass)){var existingClasses=el.className.split(" ");var newClasses=[];for(var i=0,len=existingClasses.length;i<len;i++){if(existingClasses[i]!=cssClass){newClasses[newClasses.length]=existingClasses[i];}}
159
+ el.className=newClasses.join(" ");}}
160
+ function replaceClass(el,newCssClass,oldCssClass){removeClass(el,oldCssClass);addClass(el,newCssClass);}
161
+ function getElementsByClass(el,cssClass,tagName){var elements=el.getElementsByTagName(tagName);var matches=[];for(var i=0,len=elements.length;i<len;i++){if(hasClass(elements[i],cssClass)){matches.push(elements[i]);}}
162
+ return matches;}
163
+ function $(id){return document.getElementById(id);}
164
+ function isDescendant(node,ancestorNode){while(node!=null){if(node===ancestorNode){return true;}
165
+ node=node.parentNode;}
166
+ return false;}
167
+ function isOrphan(node){var currentNode=node;while(currentNode){if(currentNode==document.body){return false;}
168
+ currentNode=currentNode.parentNode;}
169
+ return true;}
170
+ function escapeHtml(str){return str.replace(/&/g,"&amp;").replace(/[<]/g,"&lt;").replace(/>/g,"&gt;");}
171
+ function getWindowWidth(){if(window.innerWidth){return window.innerWidth;}else if(document.documentElement&&document.documentElement.clientWidth){return document.documentElement.clientWidth;}else if(document.body){return document.body.clientWidth;}
172
+ return 0;}
173
+ function getWindowHeight(){if(window.innerHeight){return window.innerHeight;}else if(document.documentElement&&document.documentElement.clientHeight){return document.documentElement.clientHeight;}else if(document.body){return document.body.clientHeight;}
174
+ return 0;}
175
+ function getToolBarsHeight(){return $("switches").offsetHeight;}
176
+ function getChromeHeight(){var height=getToolBarsHeight();if(showCommandLine){height+=$("commandLine").offsetHeight;}
177
+ return height;}
178
+ function setLogContainerHeight(){if(logMainContainer){var windowHeight=getWindowHeight();$("body").style.height=getWindowHeight()+"px";logMainContainer.style.height=""+
179
+ Math.max(0,windowHeight-getChromeHeight())+"px";}}
180
+ function setCommandInputWidth(){if(showCommandLine){$("command").style.width=""+Math.max(0,$("commandLineContainer").offsetWidth-
181
+ ($("evaluateButton").offsetWidth+13))+"px";}}
182
+ window.onresize=function(){setCommandInputWidth();setLogContainerHeight();};if(!Array.prototype.push){Array.prototype.push=function(){for(var i=0,len=arguments.length;i<len;i++){this[this.length]=arguments[i];}
183
+ return this.length;};}
184
+ if(!Array.prototype.pop){Array.prototype.pop=function(){if(this.length>0){var val=this[this.length-1];this.length=this.length-1;return val;}};}
185
+ if(!Array.prototype.shift){Array.prototype.shift=function(){if(this.length>0){var firstItem=this[0];for(var i=0,len=this.length-1;i<len;i++){this[i]=this[i+1];}
186
+ this.length=this.length-1;return firstItem;}};}
187
+ if(!Array.prototype.splice){Array.prototype.splice=function(startIndex,deleteCount){var itemsAfterDeleted=this.slice(startIndex+deleteCount);var itemsDeleted=this.slice(startIndex,startIndex+deleteCount);this.length=startIndex;var argumentsArray=[];for(var i=0,len=arguments.length;i<len;i++){argumentsArray[i]=arguments[i];}
188
+ var itemsToAppend=(argumentsArray.length>2)?itemsAfterDeleted=argumentsArray.slice(2).concat(itemsAfterDeleted):itemsAfterDeleted;for(i=0,len=itemsToAppend.length;i<len;i++){this.push(itemsToAppend[i]);}
189
+ return itemsDeleted;};}
190
+ function array_remove(arr,val){var index=-1;for(var i=0,len=arr.length;i<len;i++){if(arr[i]===val){index=i;break;}}
191
+ if(index>=0){arr.splice(index,1);return index;}else{return false;}}
192
+ function array_removeFromStart(array,numberToRemove){if(Array.prototype.splice){array.splice(0,numberToRemove);}else{for(var i=numberToRemove,len=array.length;i<len;i++){array[i-numberToRemove]=array[i];}
193
+ array.length=array.length-numberToRemove;}
194
+ return array;}
195
+ function array_contains(arr,val){for(var i=0,len=arr.length;i<len;i++){if(arr[i]==val){return true;}}
196
+ return false;}
197
+ function getErrorMessage(ex){if(ex.message){return ex.message;}else if(ex.description){return ex.description;}
198
+ return""+ex;}
199
+ function moveCaretToEnd(input){if(input.setSelectionRange){input.focus();var length=input.value.length;input.setSelectionRange(length,length);}else if(input.createTextRange){var range=input.createTextRange();range.collapse(false);range.select();}
200
+ input.focus();}
201
+ function stopPropagation(evt){if(evt.stopPropagation){evt.stopPropagation();}else if(typeof evt.cancelBubble!="undefined"){evt.cancelBubble=true;}}
202
+ function getEvent(evt){return evt?evt:event;}
203
+ function getTarget(evt){return evt.target?evt.target:evt.srcElement;}
204
+ function getRelatedTarget(evt){if(evt.relatedTarget){return evt.relatedTarget;}else if(evt.srcElement){switch(evt.type){case"mouseover":return evt.fromElement;case"mouseout":return evt.toElement;default:return evt.srcElement;}}}
205
+ function cancelKeyEvent(evt){evt.returnValue=false;stopPropagation(evt);}
206
+ function evalCommandLine(){var expr=$("command").value;evalCommand(expr);$("command").value="";}
207
+ function evalLastCommand(){if(lastCommand!=null){evalCommand(lastCommand);}}
208
+ var lastCommand=null;var commandHistory=[];var currentCommandIndex=0;function evalCommand(expr){if(appender){appender.evalCommandAndAppend(expr);}else{var prefix=">>> "+expr+"\r\n";try{log("INFO",prefix+eval(expr));}catch(ex){log("ERROR",prefix+"Error: "+getErrorMessage(ex));}}
209
+ if(expr!=commandHistory[commandHistory.length-1]){commandHistory.push(expr);if(appender){appender.storeCommandHistory(commandHistory);}}
210
+ currentCommandIndex=(expr==commandHistory[currentCommandIndex])?currentCommandIndex+1:commandHistory.length;lastCommand=expr;}
211
+ //]]>
212
+ </script>
213
+ <style type="text/css">
214
+ body{background-color:white;color:black;padding:0;margin:0;font-family:tahoma,verdana,arial,helvetica,sans-serif;overflow:hidden}div#switchesContainer input{margin-bottom:0}div.toolbar{border-top:solid #ffffff 1px;border-bottom:solid #aca899 1px;background-color:#f1efe7;padding:3px 5px;font-size:68.75%}div.toolbar,div#search input{font-family:tahoma,verdana,arial,helvetica,sans-serif}div.toolbar input.button{padding:0 5px;font-size:100%}div.toolbar input.hidden{display:none}div#switches input#clearButton{margin-left:20px}div#levels label{font-weight:bold}div#levels label,div#options label{margin-right:5px}div#levels label#wrapLabel{font-weight:normal}div#search label{margin-right:10px}div#search label.searchboxlabel{margin-right:0}div#search input{font-size:100%}div#search input.validregex{color:green}div#search input.invalidregex{color:red}div#search input.nomatches{color:white;background-color:#ff6666}div#search input.nomatches{color:white;background-color:#ff6666}div#searchNav{display:none}div#commandLine{display:none}div#commandLine input#command{font-size:100%;font-family:Courier New,Courier}div#commandLine input#evaluateButton{}*.greyedout{color:gray !important;border-color:gray !important}*.greyedout *.alwaysenabled{color:black}*.unselectable{-khtml-user-select:none;-moz-user-select:none;user-select:none}div#log{font-family:Courier New,Courier;font-size:75%;width:100%;overflow:auto;clear:both;position:relative}div.group{border-color:#cccccc;border-style:solid;border-width:1px 0 1px 1px;overflow:visible}div.oldIe div.group,div.oldIe div.group *,div.oldIe *.logentry{height:1%}div.group div.groupheading span.expander{border:solid black 1px;font-family:Courier New,Courier;font-size:0.833em;background-color:#eeeeee;position:relative;top:-1px;color:black;padding:0 2px;cursor:pointer;cursor:hand;height:1%}div.group div.groupcontent{margin-left:10px;padding-bottom:2px;overflow:visible}div.group div.expanded{display:block}div.group div.collapsed{display:none}*.logentry{overflow:visible;display:none;white-space:pre}span.pre{white-space:pre}pre.unwrapped{display:inline !important}pre.unwrapped pre.pre,div.wrapped pre.pre{display:inline}div.wrapped pre.pre{white-space:normal}div.wrapped{display:none}body.searching *.logentry span.currentmatch{color:white !important;background-color:green !important}body.searching div.searchhighlight *.logentry span.searchterm{color:black;background-color:yellow}div.wrap *.logentry{white-space:normal !important;border-width:0 0 1px 0;border-color:#dddddd;border-style:dotted}div.wrap #log_wrapped,#log_unwrapped{display:block}div.wrap #log_unwrapped,#log_wrapped{display:none}div.wrap *.logentry span.pre{overflow:visible;white-space:normal}div.wrap *.logentry pre.unwrapped{display:none}div.wrap *.logentry span.wrapped{display:inline}div.searchfilter *.searchnonmatch{display:none !important}div#log *.TRACE,label#label_TRACE{color:#666666}div#log *.DEBUG,label#label_DEBUG{color:green}div#log *.INFO,label#label_INFO{color:#000099}div#log *.WARN,label#label_WARN{color:#999900}div#log *.ERROR,label#label_ERROR{color:red}div#log *.FATAL,label#label_FATAL{color:#660066}div.TRACE#log *.TRACE,div.DEBUG#log *.DEBUG,div.INFO#log *.INFO,div.WARN#log *.WARN,div.ERROR#log *.ERROR,div.FATAL#log *.FATAL{display:block}div#log div.separator{background-color:#cccccc;margin:5px 0;line-height:1px}
215
+ </style>
216
+ </head>
217
+ <body id="body">
218
+ <div id="switchesContainer">
219
+ <div id="switches">
220
+ <div id="levels" class="toolbar">
221
+ Filters:
222
+ <input type="checkbox" id="switch_TRACE" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide trace messages" /><label for="switch_TRACE" id="label_TRACE">trace</label>
223
+ <input type="checkbox" id="switch_DEBUG" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide debug messages" /><label for="switch_DEBUG" id="label_DEBUG">debug</label>
224
+ <input type="checkbox" id="switch_INFO" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide info messages" /><label for="switch_INFO" id="label_INFO">info</label>
225
+ <input type="checkbox" id="switch_WARN" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide warn messages" /><label for="switch_WARN" id="label_WARN">warn</label>
226
+ <input type="checkbox" id="switch_ERROR" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide error messages" /><label for="switch_ERROR" id="label_ERROR">error</label>
227
+ <input type="checkbox" id="switch_FATAL" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide fatal messages" /><label for="switch_FATAL" id="label_FATAL">fatal</label>
228
+ <input type="checkbox" id="switch_ALL" onclick="toggleAllLevels(); applyFilters()" checked="checked" title="Show/hide all messages" /><label for="switch_ALL" id="label_ALL">all</label>
229
+ </div>
230
+ <div id="search" class="toolbar">
231
+ <label for="searchBox" class="searchboxlabel">Search:</label> <input type="text" id="searchBox" onclick="toggleSearchEnabled(true)" onkeyup="scheduleSearch()" size="20" />
232
+ <input type="button" id="searchReset" disabled="disabled" value="Reset" onclick="clearSearch()" class="button" title="Reset the search" />
233
+ <input type="checkbox" id="searchRegex" onclick="doSearch()" title="If checked, search is treated as a regular expression" /><label for="searchRegex">Regex</label>
234
+ <input type="checkbox" id="searchCaseSensitive" onclick="doSearch()" title="If checked, search is case sensitive" /><label for="searchCaseSensitive">Match case</label>
235
+ <input type="checkbox" id="searchDisable" onclick="toggleSearchEnabled()" title="Enable/disable search" /><label for="searchDisable" class="alwaysenabled">Disable</label>
236
+ <div id="searchNav">
237
+ <input type="button" id="searchNext" disabled="disabled" value="Next" onclick="searchNext()" class="button" title="Go to the next matching log entry" />
238
+ <input type="button" id="searchPrevious" disabled="disabled" value="Previous" onclick="searchPrevious()" class="button" title="Go to the previous matching log entry" />
239
+ <input type="checkbox" id="searchFilter" onclick="toggleSearchFilter()" title="If checked, non-matching log entries are filtered out" /><label for="searchFilter">Filter</label>
240
+ <input type="checkbox" id="searchHighlight" onclick="toggleSearchHighlight()" title="Highlight matched search terms" /><label for="searchHighlight" class="alwaysenabled">Highlight all</label>
241
+ </div>
242
+ </div>
243
+ <div id="options" class="toolbar">
244
+ Options:
245
+ <input type="checkbox" id="enableLogging" onclick="toggleLoggingEnabled()" checked="checked" title="Enable/disable logging" /><label for="enableLogging" id="enableLoggingLabel">Log</label>
246
+ <input type="checkbox" id="wrap" onclick="toggleWrap()" title="Enable / disable word wrap" /><label for="wrap" id="wrapLabel">Wrap</label>
247
+ <input type="checkbox" id="newestAtTop" onclick="toggleNewestAtTop()" title="If checked, causes newest messages to appear at the top" /><label for="newestAtTop" id="newestAtTopLabel">Newest at the top</label>
248
+ <input type="checkbox" id="scrollToLatest" onclick="toggleScrollToLatest()" checked="checked" title="If checked, window automatically scrolls to a new message when it is added" /><label for="scrollToLatest" id="scrollToLatestLabel">Scroll to latest</label>
249
+ <input type="button" id="clearButton" value="Clear" onclick="clearLog()" class="button" title="Clear all log messages" />
250
+ <input type="button" id="hideButton" value="Hide" onclick="hide()" class="hidden button" title="Hide the console" />
251
+ <input type="button" id="closeButton" value="Close" onclick="closeWindow()" class="hidden button" title="Close the window" />
252
+ </div>
253
+ </div>
254
+ </div>
255
+ <div id="log" class="TRACE DEBUG INFO WARN ERROR FATAL"></div>
256
+ <div id="commandLine" class="toolbar">
257
+ <div id="commandLineContainer">
258
+ <input type="text" id="command" title="Enter a JavaScript command here and hit return or press 'Evaluate'" />
259
+ <input type="button" id="evaluateButton" value="Evaluate" class="button" title="Evaluate the command" onclick="evalCommandLine()" />
260
+ </div>
261
+ </div>
262
+ </body>
263
+ </html>
@@ -0,0 +1,2279 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
3
+ <head>
4
+ <title>log4javascript</title>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+ <!-- Make IE8 behave like IE7, having gone to all the trouble of making IE work -->
7
+ <meta http-equiv="X-UA-Compatible" content="IE=7" />
8
+ <script type="text/javascript">var isIe = false, isIePre7 = false;</script>
9
+ <!--[if IE]><script type="text/javascript">isIe = true</script><![endif]-->
10
+ <!--[if lt IE 7]><script type="text/javascript">isIePre7 = true</script><![endif]-->
11
+ <script type="text/javascript">
12
+ //<![CDATA[
13
+ var loggingEnabled = true;
14
+ var logQueuedEventsTimer = null;
15
+ var logEntries = [];
16
+ var logEntriesAndSeparators = [];
17
+ var logItems = [];
18
+ var renderDelay = 100;
19
+ var unrenderedLogItemsExist = false;
20
+ var rootGroup, currentGroup = null;
21
+ var loaded = false;
22
+ var currentLogItem = null;
23
+ var logMainContainer;
24
+
25
+ function copyProperties(obj, props) {
26
+ for (var i in props) {
27
+ obj[i] = props[i];
28
+ }
29
+ }
30
+
31
+ /*----------------------------------------------------------------*/
32
+
33
+ function LogItem() {
34
+ }
35
+
36
+ LogItem.prototype = {
37
+ mainContainer: null,
38
+ wrappedContainer: null,
39
+ unwrappedContainer: null,
40
+ group: null,
41
+
42
+ appendToLog: function() {
43
+ for (var i = 0, len = this.elementContainers.length; i < len; i++) {
44
+ this.elementContainers[i].appendToLog();
45
+ }
46
+ this.group.update();
47
+ },
48
+
49
+ doRemove: function(doUpdate, removeFromGroup) {
50
+ if (this.rendered) {
51
+ for (var i = 0, len = this.elementContainers.length; i < len; i++) {
52
+ this.elementContainers[i].remove();
53
+ }
54
+ this.unwrappedElementContainer = null;
55
+ this.wrappedElementContainer = null;
56
+ this.mainElementContainer = null;
57
+ }
58
+ if (this.group && removeFromGroup) {
59
+ this.group.removeChild(this, doUpdate);
60
+ }
61
+ if (this === currentLogItem) {
62
+ currentLogItem = null;
63
+ }
64
+ },
65
+
66
+ remove: function(doUpdate, removeFromGroup) {
67
+ this.doRemove(doUpdate, removeFromGroup);
68
+ },
69
+
70
+ render: function() {},
71
+
72
+ accept: function(visitor) {
73
+ visitor.visit(this);
74
+ },
75
+
76
+ getUnwrappedDomContainer: function() {
77
+ return this.group.unwrappedElementContainer.contentDiv;
78
+ },
79
+
80
+ getWrappedDomContainer: function() {
81
+ return this.group.wrappedElementContainer.contentDiv;
82
+ },
83
+
84
+ getMainDomContainer: function() {
85
+ return this.group.mainElementContainer.contentDiv;
86
+ }
87
+ };
88
+
89
+ LogItem.serializedItemKeys = {LOG_ENTRY: 0, GROUP_START: 1, GROUP_END: 2};
90
+
91
+ /*----------------------------------------------------------------*/
92
+
93
+ function LogItemContainerElement() {
94
+ }
95
+
96
+ LogItemContainerElement.prototype = {
97
+ appendToLog: function() {
98
+ var insertBeforeFirst = (newestAtTop && this.containerDomNode.hasChildNodes());
99
+ if (insertBeforeFirst) {
100
+ this.containerDomNode.insertBefore(this.mainDiv, this.containerDomNode.firstChild);
101
+ } else {
102
+ this.containerDomNode.appendChild(this.mainDiv);
103
+ }
104
+ }
105
+ };
106
+
107
+ /*----------------------------------------------------------------*/
108
+
109
+ function SeparatorElementContainer(containerDomNode) {
110
+ this.containerDomNode = containerDomNode;
111
+ this.mainDiv = document.createElement("div");
112
+ this.mainDiv.className = "separator";
113
+ this.mainDiv.innerHTML = "&nbsp;";
114
+ }
115
+
116
+ SeparatorElementContainer.prototype = new LogItemContainerElement();
117
+
118
+ SeparatorElementContainer.prototype.remove = function() {
119
+ this.mainDiv.parentNode.removeChild(this.mainDiv);
120
+ this.mainDiv = null;
121
+ };
122
+
123
+ /*----------------------------------------------------------------*/
124
+
125
+ function Separator() {
126
+ this.rendered = false;
127
+ }
128
+
129
+ Separator.prototype = new LogItem();
130
+
131
+ copyProperties(Separator.prototype, {
132
+ render: function() {
133
+ var containerDomNode = this.group.contentDiv;
134
+ if (isIe) {
135
+ this.unwrappedElementContainer = new SeparatorElementContainer(this.getUnwrappedDomContainer());
136
+ this.wrappedElementContainer = new SeparatorElementContainer(this.getWrappedDomContainer());
137
+ this.elementContainers = [this.unwrappedElementContainer, this.wrappedElementContainer];
138
+ } else {
139
+ this.mainElementContainer = new SeparatorElementContainer(this.getMainDomContainer());
140
+ this.elementContainers = [this.mainElementContainer];
141
+ }
142
+ this.content = this.formattedMessage;
143
+ this.rendered = true;
144
+ }
145
+ });
146
+
147
+ /*----------------------------------------------------------------*/
148
+
149
+ function GroupElementContainer(group, containerDomNode, isRoot, isWrapped) {
150
+ this.group = group;
151
+ this.containerDomNode = containerDomNode;
152
+ this.isRoot = isRoot;
153
+ this.isWrapped = isWrapped;
154
+ this.expandable = false;
155
+
156
+ if (this.isRoot) {
157
+ if (isIe) {
158
+ this.contentDiv = logMainContainer.appendChild(document.createElement("div"));
159
+ this.contentDiv.id = this.isWrapped ? "log_wrapped" : "log_unwrapped";
160
+ } else {
161
+ this.contentDiv = logMainContainer;
162
+ }
163
+ } else {
164
+ var groupElementContainer = this;
165
+
166
+ this.mainDiv = document.createElement("div");
167
+ this.mainDiv.className = "group";
168
+
169
+ this.headingDiv = this.mainDiv.appendChild(document.createElement("div"));
170
+ this.headingDiv.className = "groupheading";
171
+
172
+ this.expander = this.headingDiv.appendChild(document.createElement("span"));
173
+ this.expander.className = "expander unselectable greyedout";
174
+ this.expander.unselectable = true;
175
+ var expanderText = this.group.expanded ? "-" : "+";
176
+ this.expanderTextNode = this.expander.appendChild(document.createTextNode(expanderText));
177
+
178
+ this.headingDiv.appendChild(document.createTextNode(" " + this.group.name));
179
+
180
+ this.contentDiv = this.mainDiv.appendChild(document.createElement("div"));
181
+ var contentCssClass = this.group.expanded ? "expanded" : "collapsed";
182
+ this.contentDiv.className = "groupcontent " + contentCssClass;
183
+
184
+ this.expander.onclick = function() {
185
+ if (groupElementContainer.group.expandable) {
186
+ groupElementContainer.group.toggleExpanded();
187
+ }
188
+ };
189
+ }
190
+ }
191
+
192
+ GroupElementContainer.prototype = new LogItemContainerElement();
193
+
194
+ copyProperties(GroupElementContainer.prototype, {
195
+ toggleExpanded: function() {
196
+ if (!this.isRoot) {
197
+ var oldCssClass, newCssClass, expanderText;
198
+ if (this.group.expanded) {
199
+ newCssClass = "expanded";
200
+ oldCssClass = "collapsed";
201
+ expanderText = "-";
202
+ } else {
203
+ newCssClass = "collapsed";
204
+ oldCssClass = "expanded";
205
+ expanderText = "+";
206
+ }
207
+ replaceClass(this.contentDiv, newCssClass, oldCssClass);
208
+ this.expanderTextNode.nodeValue = expanderText;
209
+ }
210
+ },
211
+
212
+ remove: function() {
213
+ if (!this.isRoot) {
214
+ this.headingDiv = null;
215
+ this.expander.onclick = null;
216
+ this.expander = null;
217
+ this.expanderTextNode = null;
218
+ this.contentDiv = null;
219
+ this.containerDomNode = null;
220
+ this.mainDiv.parentNode.removeChild(this.mainDiv);
221
+ this.mainDiv = null;
222
+ }
223
+ },
224
+
225
+ reverseChildren: function() {
226
+ // Invert the order of the log entries
227
+ var node = null;
228
+
229
+ // Remove all the log container nodes
230
+ var childDomNodes = [];
231
+ while ((node = this.contentDiv.firstChild)) {
232
+ this.contentDiv.removeChild(node);
233
+ childDomNodes.push(node);
234
+ }
235
+
236
+ // Put them all back in reverse order
237
+ while ((node = childDomNodes.pop())) {
238
+ this.contentDiv.appendChild(node);
239
+ }
240
+ },
241
+
242
+ update: function() {
243
+ if (!this.isRoot) {
244
+ if (this.group.expandable) {
245
+ removeClass(this.expander, "greyedout");
246
+ } else {
247
+ addClass(this.expander, "greyedout");
248
+ }
249
+ }
250
+ },
251
+
252
+ clear: function() {
253
+ if (this.isRoot) {
254
+ this.contentDiv.innerHTML = "";
255
+ }
256
+ }
257
+ });
258
+
259
+ /*----------------------------------------------------------------*/
260
+
261
+ function Group(name, isRoot, initiallyExpanded) {
262
+ this.name = name;
263
+ this.group = null;
264
+ this.isRoot = isRoot;
265
+ this.initiallyExpanded = initiallyExpanded;
266
+ this.elementContainers = [];
267
+ this.children = [];
268
+ this.expanded = initiallyExpanded;
269
+ this.rendered = false;
270
+ this.expandable = false;
271
+ }
272
+
273
+ Group.prototype = new LogItem();
274
+
275
+ copyProperties(Group.prototype, {
276
+ addChild: function(logItem) {
277
+ this.children.push(logItem);
278
+ logItem.group = this;
279
+ },
280
+
281
+ render: function() {
282
+ if (isIe) {
283
+ var unwrappedDomContainer, wrappedDomContainer;
284
+ if (this.isRoot) {
285
+ unwrappedDomContainer = logMainContainer;
286
+ wrappedDomContainer = logMainContainer;
287
+ } else {
288
+ unwrappedDomContainer = this.getUnwrappedDomContainer();
289
+ wrappedDomContainer = this.getWrappedDomContainer();
290
+ }
291
+ this.unwrappedElementContainer = new GroupElementContainer(this, unwrappedDomContainer, this.isRoot, false);
292
+ this.wrappedElementContainer = new GroupElementContainer(this, wrappedDomContainer, this.isRoot, true);
293
+ this.elementContainers = [this.unwrappedElementContainer, this.wrappedElementContainer];
294
+ } else {
295
+ var mainDomContainer = this.isRoot ? logMainContainer : this.getMainDomContainer();
296
+ this.mainElementContainer = new GroupElementContainer(this, mainDomContainer, this.isRoot, false);
297
+ this.elementContainers = [this.mainElementContainer];
298
+ }
299
+ this.rendered = true;
300
+ },
301
+
302
+ toggleExpanded: function() {
303
+ this.expanded = !this.expanded;
304
+ for (var i = 0, len = this.elementContainers.length; i < len; i++) {
305
+ this.elementContainers[i].toggleExpanded();
306
+ }
307
+ },
308
+
309
+ expand: function() {
310
+ if (!this.expanded) {
311
+ this.toggleExpanded();
312
+ }
313
+ },
314
+
315
+ accept: function(visitor) {
316
+ visitor.visitGroup(this);
317
+ },
318
+
319
+ reverseChildren: function() {
320
+ if (this.rendered) {
321
+ for (var i = 0, len = this.elementContainers.length; i < len; i++) {
322
+ this.elementContainers[i].reverseChildren();
323
+ }
324
+ }
325
+ },
326
+
327
+ update: function() {
328
+ var previouslyExpandable = this.expandable;
329
+ this.expandable = (this.children.length !== 0);
330
+ if (this.expandable !== previouslyExpandable) {
331
+ for (var i = 0, len = this.elementContainers.length; i < len; i++) {
332
+ this.elementContainers[i].update();
333
+ }
334
+ }
335
+ },
336
+
337
+ flatten: function() {
338
+ var visitor = new GroupFlattener();
339
+ this.accept(visitor);
340
+ return visitor.logEntriesAndSeparators;
341
+ },
342
+
343
+ removeChild: function(child, doUpdate) {
344
+ array_remove(this.children, child);
345
+ child.group = null;
346
+ if (doUpdate) {
347
+ this.update();
348
+ }
349
+ },
350
+
351
+ remove: function(doUpdate, removeFromGroup) {
352
+ for (var i = 0, len = this.children.length; i < len; i++) {
353
+ this.children[i].remove(false, false);
354
+ }
355
+ this.children = [];
356
+ this.update();
357
+ if (this === currentGroup) {
358
+ currentGroup = this.group;
359
+ }
360
+ this.doRemove(doUpdate, removeFromGroup);
361
+ },
362
+
363
+ serialize: function(items) {
364
+ items.push([LogItem.serializedItemKeys.GROUP_START, this.name]);
365
+ for (var i = 0, len = this.children.length; i < len; i++) {
366
+ this.children[i].serialize(items);
367
+ }
368
+ if (this !== currentGroup) {
369
+ items.push([LogItem.serializedItemKeys.GROUP_END]);
370
+ }
371
+ },
372
+
373
+ clear: function() {
374
+ for (var i = 0, len = this.elementContainers.length; i < len; i++) {
375
+ this.elementContainers[i].clear();
376
+ }
377
+ }
378
+ });
379
+
380
+ /*----------------------------------------------------------------*/
381
+
382
+ function LogEntryElementContainer() {
383
+ }
384
+
385
+ LogEntryElementContainer.prototype = new LogItemContainerElement();
386
+
387
+ copyProperties(LogEntryElementContainer.prototype, {
388
+ remove: function() {
389
+ this.doRemove();
390
+ },
391
+
392
+ doRemove: function() {
393
+ this.mainDiv.parentNode.removeChild(this.mainDiv);
394
+ this.mainDiv = null;
395
+ this.contentElement = null;
396
+ this.containerDomNode = null;
397
+ },
398
+
399
+ setContent: function(content, wrappedContent) {
400
+ if (content === this.formattedMessage) {
401
+ this.contentElement.innerHTML = "";
402
+ this.contentElement.appendChild(document.createTextNode(this.formattedMessage));
403
+ } else {
404
+ this.contentElement.innerHTML = content;
405
+ }
406
+ },
407
+
408
+ setSearchMatch: function(isMatch) {
409
+ var oldCssClass = isMatch ? "searchnonmatch" : "searchmatch";
410
+ var newCssClass = isMatch ? "searchmatch" : "searchnonmatch";
411
+ replaceClass(this.mainDiv, newCssClass, oldCssClass);
412
+ },
413
+
414
+ clearSearch: function() {
415
+ removeClass(this.mainDiv, "searchmatch");
416
+ removeClass(this.mainDiv, "searchnonmatch");
417
+ }
418
+ });
419
+
420
+ /*----------------------------------------------------------------*/
421
+
422
+ function LogEntryWrappedElementContainer(logEntry, containerDomNode) {
423
+ this.logEntry = logEntry;
424
+ this.containerDomNode = containerDomNode;
425
+ this.mainDiv = document.createElement("div");
426
+ this.mainDiv.appendChild(document.createTextNode(this.logEntry.formattedMessage));
427
+ this.mainDiv.className = "logentry wrapped " + this.logEntry.level;
428
+ this.contentElement = this.mainDiv;
429
+ }
430
+
431
+ LogEntryWrappedElementContainer.prototype = new LogEntryElementContainer();
432
+
433
+ LogEntryWrappedElementContainer.prototype.setContent = function(content, wrappedContent) {
434
+ if (content === this.formattedMessage) {
435
+ this.contentElement.innerHTML = "";
436
+ this.contentElement.appendChild(document.createTextNode(this.formattedMessage));
437
+ } else {
438
+ this.contentElement.innerHTML = wrappedContent;
439
+ }
440
+ };
441
+
442
+ /*----------------------------------------------------------------*/
443
+
444
+ function LogEntryUnwrappedElementContainer(logEntry, containerDomNode) {
445
+ this.logEntry = logEntry;
446
+ this.containerDomNode = containerDomNode;
447
+ this.mainDiv = document.createElement("div");
448
+ this.mainDiv.className = "logentry unwrapped " + this.logEntry.level;
449
+ this.pre = this.mainDiv.appendChild(document.createElement("pre"));
450
+ this.pre.appendChild(document.createTextNode(this.logEntry.formattedMessage));
451
+ this.pre.className = "unwrapped";
452
+ this.contentElement = this.pre;
453
+ }
454
+
455
+ LogEntryUnwrappedElementContainer.prototype = new LogEntryElementContainer();
456
+
457
+ LogEntryUnwrappedElementContainer.prototype.remove = function() {
458
+ this.doRemove();
459
+ this.pre = null;
460
+ };
461
+
462
+ /*----------------------------------------------------------------*/
463
+
464
+ function LogEntryMainElementContainer(logEntry, containerDomNode) {
465
+ this.logEntry = logEntry;
466
+ this.containerDomNode = containerDomNode;
467
+ this.mainDiv = document.createElement("div");
468
+ this.mainDiv.className = "logentry nonielogentry " + this.logEntry.level;
469
+ this.contentElement = this.mainDiv.appendChild(document.createElement("span"));
470
+ this.contentElement.appendChild(document.createTextNode(this.logEntry.formattedMessage));
471
+ }
472
+
473
+ LogEntryMainElementContainer.prototype = new LogEntryElementContainer();
474
+
475
+ /*----------------------------------------------------------------*/
476
+
477
+ function LogEntry(level, formattedMessage) {
478
+ this.level = level;
479
+ this.formattedMessage = formattedMessage;
480
+ this.rendered = false;
481
+ }
482
+
483
+ LogEntry.prototype = new LogItem();
484
+
485
+ copyProperties(LogEntry.prototype, {
486
+ render: function() {
487
+ var logEntry = this;
488
+ var containerDomNode = this.group.contentDiv;
489
+
490
+ // Support for the CSS attribute white-space in IE for Windows is
491
+ // non-existent pre version 6 and slightly odd in 6, so instead
492
+ // use two different HTML elements
493
+ if (isIe) {
494
+ this.formattedMessage = this.formattedMessage.replace(/\r\n/g, "\r"); // Workaround for IE's treatment of white space
495
+ this.unwrappedElementContainer = new LogEntryUnwrappedElementContainer(this, this.getUnwrappedDomContainer());
496
+ this.wrappedElementContainer = new LogEntryWrappedElementContainer(this, this.getWrappedDomContainer());
497
+ this.elementContainers = [this.unwrappedElementContainer, this.wrappedElementContainer];
498
+ } else {
499
+ this.mainElementContainer = new LogEntryMainElementContainer(this, this.getMainDomContainer());
500
+ this.elementContainers = [this.mainElementContainer];
501
+ }
502
+ this.content = this.formattedMessage;
503
+ this.rendered = true;
504
+ },
505
+
506
+ setContent: function(content, wrappedContent) {
507
+ if (content != this.content) {
508
+ if (isIe && (content !== this.formattedMessage)) {
509
+ content = content.replace(/\r\n/g, "\r"); // Workaround for IE's treatment of white space
510
+ }
511
+ for (var i = 0, len = this.elementContainers.length; i < len; i++) {
512
+ this.elementContainers[i].setContent(content, wrappedContent);
513
+ }
514
+ this.content = content;
515
+ }
516
+ },
517
+
518
+ getSearchMatches: function() {
519
+ var matches = [];
520
+ var i, len;
521
+ if (isIe) {
522
+ var unwrappedEls = getElementsByClass(this.unwrappedElementContainer.mainDiv, "searchterm", "span");
523
+ var wrappedEls = getElementsByClass(this.wrappedElementContainer.mainDiv, "searchterm", "span");
524
+ for (i = 0, len = unwrappedEls.length; i < len; i++) {
525
+ matches[i] = new Match(this.level, null, unwrappedEls[i], wrappedEls[i]);
526
+ }
527
+ } else {
528
+ var els = getElementsByClass(this.mainElementContainer.mainDiv, "searchterm", "span");
529
+ for (i = 0, len = els.length; i < len; i++) {
530
+ matches[i] = new Match(this.level, els[i]);
531
+ }
532
+ }
533
+ return matches;
534
+ },
535
+
536
+ setSearchMatch: function(isMatch) {
537
+ for (var i = 0, len = this.elementContainers.length; i < len; i++) {
538
+ this.elementContainers[i].setSearchMatch(isMatch);
539
+ }
540
+ },
541
+
542
+ clearSearch: function() {
543
+ for (var i = 0, len = this.elementContainers.length; i < len; i++) {
544
+ this.elementContainers[i].clearSearch();
545
+ }
546
+ },
547
+
548
+ accept: function(visitor) {
549
+ visitor.visitLogEntry(this);
550
+ },
551
+
552
+ serialize: function(items) {
553
+ items.push([LogItem.serializedItemKeys.LOG_ENTRY, this.level, this.formattedMessage]);
554
+ }
555
+ });
556
+
557
+ /*----------------------------------------------------------------*/
558
+
559
+ function LogItemVisitor() {
560
+ }
561
+
562
+ LogItemVisitor.prototype = {
563
+ visit: function(logItem) {
564
+ },
565
+
566
+ visitParent: function(logItem) {
567
+ if (logItem.group) {
568
+ logItem.group.accept(this);
569
+ }
570
+ },
571
+
572
+ visitChildren: function(logItem) {
573
+ for (var i = 0, len = logItem.children.length; i < len; i++) {
574
+ logItem.children[i].accept(this);
575
+ }
576
+ },
577
+
578
+ visitLogEntry: function(logEntry) {
579
+ this.visit(logEntry);
580
+ },
581
+
582
+ visitSeparator: function(separator) {
583
+ this.visit(separator);
584
+ },
585
+
586
+ visitGroup: function(group) {
587
+ this.visit(group);
588
+ }
589
+ };
590
+
591
+ /*----------------------------------------------------------------*/
592
+
593
+ function GroupFlattener() {
594
+ this.logEntriesAndSeparators = [];
595
+ }
596
+
597
+ GroupFlattener.prototype = new LogItemVisitor();
598
+
599
+ GroupFlattener.prototype.visitGroup = function(group) {
600
+ this.visitChildren(group);
601
+ };
602
+
603
+ GroupFlattener.prototype.visitLogEntry = function(logEntry) {
604
+ this.logEntriesAndSeparators.push(logEntry);
605
+ };
606
+
607
+ GroupFlattener.prototype.visitSeparator = function(separator) {
608
+ this.logEntriesAndSeparators.push(separator);
609
+ };
610
+
611
+ /*----------------------------------------------------------------*/
612
+
613
+ window.onload = function() {
614
+ // Sort out document.domain
615
+ if (location.search) {
616
+ var queryBits = unescape(location.search).substr(1).split("&"), nameValueBits;
617
+ for (var i = 0, len = queryBits.length; i < len; i++) {
618
+ nameValueBits = queryBits[i].split("=");
619
+ if (nameValueBits[0] == "log4javascript_domain") {
620
+ document.domain = nameValueBits[1];
621
+ break;
622
+ }
623
+ }
624
+ }
625
+
626
+ // Create DOM objects
627
+ logMainContainer = $("log");
628
+ if (isIePre7) {
629
+ addClass(logMainContainer, "oldIe");
630
+ }
631
+
632
+ rootGroup = new Group("root", true);
633
+ rootGroup.render();
634
+ currentGroup = rootGroup;
635
+
636
+ setCommandInputWidth();
637
+ setLogContainerHeight();
638
+ toggleLoggingEnabled();
639
+ toggleSearchEnabled();
640
+ toggleSearchFilter();
641
+ toggleSearchHighlight();
642
+ applyFilters();
643
+ checkAllLevels();
644
+ toggleWrap();
645
+ toggleNewestAtTop();
646
+ toggleScrollToLatest();
647
+ renderQueuedLogItems();
648
+ loaded = true;
649
+ $("command").value = "";
650
+ $("command").autocomplete = "off";
651
+ $("command").onkeydown = function(evt) {
652
+ evt = getEvent(evt);
653
+ if (evt.keyCode == 10 || evt.keyCode == 13) { // Return/Enter
654
+ evalCommandLine();
655
+ stopPropagation(evt);
656
+ } else if (evt.keyCode == 27) { // Escape
657
+ this.value = "";
658
+ this.focus();
659
+ } else if (evt.keyCode == 38 && commandHistory.length > 0) { // Up
660
+ currentCommandIndex = Math.max(0, currentCommandIndex - 1);
661
+ this.value = commandHistory[currentCommandIndex];
662
+ moveCaretToEnd(this);
663
+ } else if (evt.keyCode == 40 && commandHistory.length > 0) { // Down
664
+ currentCommandIndex = Math.min(commandHistory.length - 1, currentCommandIndex + 1);
665
+ this.value = commandHistory[currentCommandIndex];
666
+ moveCaretToEnd(this);
667
+ }
668
+ };
669
+
670
+ // Prevent the keypress moving the caret in Firefox
671
+ $("command").onkeypress = function(evt) {
672
+ evt = getEvent(evt);
673
+ if (evt.keyCode == 38 && commandHistory.length > 0 && evt.preventDefault) { // Up
674
+ evt.preventDefault();
675
+ }
676
+ };
677
+
678
+ // Prevent the keyup event blurring the input in Opera
679
+ $("command").onkeyup = function(evt) {
680
+ evt = getEvent(evt);
681
+ if (evt.keyCode == 27 && evt.preventDefault) { // Up
682
+ evt.preventDefault();
683
+ this.focus();
684
+ }
685
+ };
686
+
687
+ // Add document keyboard shortcuts
688
+ document.onkeydown = function keyEventHandler(evt) {
689
+ evt = getEvent(evt);
690
+ switch (evt.keyCode) {
691
+ case 69: // Ctrl + shift + E: re-execute last command
692
+ if (evt.shiftKey && (evt.ctrlKey || evt.metaKey)) {
693
+ evalLastCommand();
694
+ cancelKeyEvent(evt);
695
+ return false;
696
+ }
697
+ break;
698
+ case 75: // Ctrl + shift + K: focus search
699
+ if (evt.shiftKey && (evt.ctrlKey || evt.metaKey)) {
700
+ focusSearch();
701
+ cancelKeyEvent(evt);
702
+ return false;
703
+ }
704
+ break;
705
+ case 40: // Ctrl + shift + down arrow: focus command line
706
+ case 76: // Ctrl + shift + L: focus command line
707
+ if (evt.shiftKey && (evt.ctrlKey || evt.metaKey)) {
708
+ focusCommandLine();
709
+ cancelKeyEvent(evt);
710
+ return false;
711
+ }
712
+ break;
713
+ }
714
+ };
715
+
716
+ // Workaround to make sure log div starts at the correct size
717
+ setTimeout(setLogContainerHeight, 20);
718
+
719
+ setShowCommandLine(showCommandLine);
720
+ doSearch();
721
+ };
722
+
723
+ window.onunload = function() {
724
+ if (mainWindowExists()) {
725
+ appender.unload();
726
+ }
727
+ appender = null;
728
+ };
729
+
730
+ /*----------------------------------------------------------------*/
731
+
732
+ function toggleLoggingEnabled() {
733
+ setLoggingEnabled($("enableLogging").checked);
734
+ }
735
+
736
+ function setLoggingEnabled(enable) {
737
+ loggingEnabled = enable;
738
+ }
739
+
740
+ var appender = null;
741
+
742
+ function setAppender(appenderParam) {
743
+ appender = appenderParam;
744
+ }
745
+
746
+ function setShowCloseButton(showCloseButton) {
747
+ $("closeButton").style.display = showCloseButton ? "inline" : "none";
748
+ }
749
+
750
+ function setShowHideButton(showHideButton) {
751
+ $("hideButton").style.display = showHideButton ? "inline" : "none";
752
+ }
753
+
754
+ var newestAtTop = false;
755
+
756
+ /*----------------------------------------------------------------*/
757
+
758
+ function LogItemContentReverser() {
759
+ }
760
+
761
+ LogItemContentReverser.prototype = new LogItemVisitor();
762
+
763
+ LogItemContentReverser.prototype.visitGroup = function(group) {
764
+ group.reverseChildren();
765
+ this.visitChildren(group);
766
+ };
767
+
768
+ /*----------------------------------------------------------------*/
769
+
770
+ function setNewestAtTop(isNewestAtTop) {
771
+ var oldNewestAtTop = newestAtTop;
772
+ var i, iLen, j, jLen;
773
+ newestAtTop = Boolean(isNewestAtTop);
774
+ if (oldNewestAtTop != newestAtTop) {
775
+ var visitor = new LogItemContentReverser();
776
+ rootGroup.accept(visitor);
777
+
778
+ // Reassemble the matches array
779
+ if (currentSearch) {
780
+ var currentMatch = currentSearch.matches[currentMatchIndex];
781
+ var matchIndex = 0;
782
+ var matches = [];
783
+ var actOnLogEntry = function(logEntry) {
784
+ var logEntryMatches = logEntry.getSearchMatches();
785
+ for (j = 0, jLen = logEntryMatches.length; j < jLen; j++) {
786
+ matches[matchIndex] = logEntryMatches[j];
787
+ if (currentMatch && logEntryMatches[j].equals(currentMatch)) {
788
+ currentMatchIndex = matchIndex;
789
+ }
790
+ matchIndex++;
791
+ }
792
+ };
793
+ if (newestAtTop) {
794
+ for (i = logEntries.length - 1; i >= 0; i--) {
795
+ actOnLogEntry(logEntries[i]);
796
+ }
797
+ } else {
798
+ for (i = 0, iLen = logEntries.length; i < iLen; i++) {
799
+ actOnLogEntry(logEntries[i]);
800
+ }
801
+ }
802
+ currentSearch.matches = matches;
803
+ if (currentMatch) {
804
+ currentMatch.setCurrent();
805
+ }
806
+ } else if (scrollToLatest) {
807
+ doScrollToLatest();
808
+ }
809
+ }
810
+ $("newestAtTop").checked = isNewestAtTop;
811
+ }
812
+
813
+ function toggleNewestAtTop() {
814
+ var isNewestAtTop = $("newestAtTop").checked;
815
+ setNewestAtTop(isNewestAtTop);
816
+ }
817
+
818
+ var scrollToLatest = true;
819
+
820
+ function setScrollToLatest(isScrollToLatest) {
821
+ scrollToLatest = isScrollToLatest;
822
+ if (scrollToLatest) {
823
+ doScrollToLatest();
824
+ }
825
+ $("scrollToLatest").checked = isScrollToLatest;
826
+ }
827
+
828
+ function toggleScrollToLatest() {
829
+ var isScrollToLatest = $("scrollToLatest").checked;
830
+ setScrollToLatest(isScrollToLatest);
831
+ }
832
+
833
+ function doScrollToLatest() {
834
+ var l = logMainContainer;
835
+ if (typeof l.scrollTop != "undefined") {
836
+ if (newestAtTop) {
837
+ l.scrollTop = 0;
838
+ } else {
839
+ var latestLogEntry = l.lastChild;
840
+ if (latestLogEntry) {
841
+ l.scrollTop = l.scrollHeight;
842
+ }
843
+ }
844
+ }
845
+ }
846
+
847
+ var closeIfOpenerCloses = true;
848
+
849
+ function setCloseIfOpenerCloses(isCloseIfOpenerCloses) {
850
+ closeIfOpenerCloses = isCloseIfOpenerCloses;
851
+ }
852
+
853
+ var maxMessages = null;
854
+
855
+ function setMaxMessages(max) {
856
+ maxMessages = max;
857
+ pruneLogEntries();
858
+ }
859
+
860
+ var showCommandLine = false;
861
+
862
+ function setShowCommandLine(isShowCommandLine) {
863
+ showCommandLine = isShowCommandLine;
864
+ if (loaded) {
865
+ $("commandLine").style.display = showCommandLine ? "block" : "none";
866
+ setCommandInputWidth();
867
+ setLogContainerHeight();
868
+ }
869
+ }
870
+
871
+ function focusCommandLine() {
872
+ if (loaded) {
873
+ $("command").focus();
874
+ }
875
+ }
876
+
877
+ function focusSearch() {
878
+ if (loaded) {
879
+ $("searchBox").focus();
880
+ }
881
+ }
882
+
883
+ function getLogItems() {
884
+ var items = [];
885
+ for (var i = 0, len = logItems.length; i < len; i++) {
886
+ logItems[i].serialize(items);
887
+ }
888
+ return items;
889
+ }
890
+
891
+ function setLogItems(items) {
892
+ var loggingReallyEnabled = loggingEnabled;
893
+ // Temporarily turn logging on
894
+ loggingEnabled = true;
895
+ for (var i = 0, len = items.length; i < len; i++) {
896
+ switch (items[i][0]) {
897
+ case LogItem.serializedItemKeys.LOG_ENTRY:
898
+ log(items[i][1], items[i][2]);
899
+ break;
900
+ case LogItem.serializedItemKeys.GROUP_START:
901
+ group(items[i][1]);
902
+ break;
903
+ case LogItem.serializedItemKeys.GROUP_END:
904
+ groupEnd();
905
+ break;
906
+ }
907
+ }
908
+ loggingEnabled = loggingReallyEnabled;
909
+ }
910
+
911
+ function log(logLevel, formattedMessage) {
912
+ if (loggingEnabled) {
913
+ var logEntry = new LogEntry(logLevel, formattedMessage);
914
+ logEntries.push(logEntry);
915
+ logEntriesAndSeparators.push(logEntry);
916
+ logItems.push(logEntry);
917
+ currentGroup.addChild(logEntry);
918
+ if (loaded) {
919
+ if (logQueuedEventsTimer !== null) {
920
+ clearTimeout(logQueuedEventsTimer);
921
+ }
922
+ logQueuedEventsTimer = setTimeout(renderQueuedLogItems, renderDelay);
923
+ unrenderedLogItemsExist = true;
924
+ }
925
+ }
926
+ }
927
+
928
+ function renderQueuedLogItems() {
929
+ logQueuedEventsTimer = null;
930
+ var pruned = pruneLogEntries();
931
+
932
+ // Render any unrendered log entries and apply the current search to them
933
+ var initiallyHasMatches = currentSearch ? currentSearch.hasMatches() : false;
934
+ for (var i = 0, len = logItems.length; i < len; i++) {
935
+ if (!logItems[i].rendered) {
936
+ logItems[i].render();
937
+ logItems[i].appendToLog();
938
+ if (currentSearch && (logItems[i] instanceof LogEntry)) {
939
+ currentSearch.applyTo(logItems[i]);
940
+ }
941
+ }
942
+ }
943
+ if (currentSearch) {
944
+ if (pruned) {
945
+ if (currentSearch.hasVisibleMatches()) {
946
+ if (currentMatchIndex === null) {
947
+ setCurrentMatchIndex(0);
948
+ }
949
+ displayMatches();
950
+ } else {
951
+ displayNoMatches();
952
+ }
953
+ } else if (!initiallyHasMatches && currentSearch.hasVisibleMatches()) {
954
+ setCurrentMatchIndex(0);
955
+ displayMatches();
956
+ }
957
+ }
958
+ if (scrollToLatest) {
959
+ doScrollToLatest();
960
+ }
961
+ unrenderedLogItemsExist = false;
962
+ }
963
+
964
+ function pruneLogEntries() {
965
+ if ((maxMessages !== null) && (logEntriesAndSeparators.length > maxMessages)) {
966
+ var numberToDelete = logEntriesAndSeparators.length - maxMessages;
967
+ var prunedLogEntries = logEntriesAndSeparators.slice(0, numberToDelete);
968
+ if (currentSearch) {
969
+ currentSearch.removeMatches(prunedLogEntries);
970
+ }
971
+ var group;
972
+ for (var i = 0; i < numberToDelete; i++) {
973
+ group = logEntriesAndSeparators[i].group;
974
+ array_remove(logItems, logEntriesAndSeparators[i]);
975
+ array_remove(logEntries, logEntriesAndSeparators[i]);
976
+ logEntriesAndSeparators[i].remove(true, true);
977
+ if (group.children.length === 0 && group !== currentGroup && group !== rootGroup) {
978
+ array_remove(logItems, group);
979
+ group.remove(true, true);
980
+ }
981
+ }
982
+ logEntriesAndSeparators = array_removeFromStart(logEntriesAndSeparators, numberToDelete);
983
+ return true;
984
+ }
985
+ return false;
986
+ }
987
+
988
+ function group(name, startExpanded) {
989
+ if (loggingEnabled) {
990
+ initiallyExpanded = (typeof startExpanded === "undefined") ? true : Boolean(startExpanded);
991
+ var newGroup = new Group(name, false, initiallyExpanded);
992
+ currentGroup.addChild(newGroup);
993
+ currentGroup = newGroup;
994
+ logItems.push(newGroup);
995
+ if (loaded) {
996
+ if (logQueuedEventsTimer !== null) {
997
+ clearTimeout(logQueuedEventsTimer);
998
+ }
999
+ logQueuedEventsTimer = setTimeout(renderQueuedLogItems, renderDelay);
1000
+ unrenderedLogItemsExist = true;
1001
+ }
1002
+ }
1003
+ }
1004
+
1005
+ function groupEnd() {
1006
+ currentGroup = (currentGroup === rootGroup) ? rootGroup : currentGroup.group;
1007
+ }
1008
+
1009
+ function mainPageReloaded() {
1010
+ currentGroup = rootGroup;
1011
+ var separator = new Separator();
1012
+ logEntriesAndSeparators.push(separator);
1013
+ logItems.push(separator);
1014
+ currentGroup.addChild(separator);
1015
+ }
1016
+
1017
+ function closeWindow() {
1018
+ if (appender && mainWindowExists()) {
1019
+ appender.close(true);
1020
+ } else {
1021
+ window.close();
1022
+ }
1023
+ }
1024
+
1025
+ function hide() {
1026
+ if (appender && mainWindowExists()) {
1027
+ appender.hide();
1028
+ }
1029
+ }
1030
+
1031
+ var mainWindow = window;
1032
+ var windowId = "log4javascriptConsoleWindow_" + new Date().getTime() + "_" + ("" + Math.random()).substr(2);
1033
+
1034
+ function setMainWindow(win) {
1035
+ mainWindow = win;
1036
+ mainWindow[windowId] = window;
1037
+ // If this is a pop-up, poll the opener to see if it's closed
1038
+ if (opener && closeIfOpenerCloses) {
1039
+ pollOpener();
1040
+ }
1041
+ }
1042
+
1043
+ function pollOpener() {
1044
+ if (closeIfOpenerCloses) {
1045
+ if (mainWindowExists()) {
1046
+ setTimeout(pollOpener, 500);
1047
+ } else {
1048
+ closeWindow();
1049
+ }
1050
+ }
1051
+ }
1052
+
1053
+ function mainWindowExists() {
1054
+ try {
1055
+ return (mainWindow && !mainWindow.closed &&
1056
+ mainWindow[windowId] == window);
1057
+ } catch (ex) {}
1058
+ return false;
1059
+ }
1060
+
1061
+ var logLevels = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"];
1062
+
1063
+ function getCheckBox(logLevel) {
1064
+ return $("switch_" + logLevel);
1065
+ }
1066
+
1067
+ function getIeWrappedLogContainer() {
1068
+ return $("log_wrapped");
1069
+ }
1070
+
1071
+ function getIeUnwrappedLogContainer() {
1072
+ return $("log_unwrapped");
1073
+ }
1074
+
1075
+ function applyFilters() {
1076
+ for (var i = 0; i < logLevels.length; i++) {
1077
+ if (getCheckBox(logLevels[i]).checked) {
1078
+ addClass(logMainContainer, logLevels[i]);
1079
+ } else {
1080
+ removeClass(logMainContainer, logLevels[i]);
1081
+ }
1082
+ }
1083
+ updateSearchFromFilters();
1084
+ }
1085
+
1086
+ function toggleAllLevels() {
1087
+ var turnOn = $("switch_ALL").checked;
1088
+ for (var i = 0; i < logLevels.length; i++) {
1089
+ getCheckBox(logLevels[i]).checked = turnOn;
1090
+ if (turnOn) {
1091
+ addClass(logMainContainer, logLevels[i]);
1092
+ } else {
1093
+ removeClass(logMainContainer, logLevels[i]);
1094
+ }
1095
+ }
1096
+ }
1097
+
1098
+ function checkAllLevels() {
1099
+ for (var i = 0; i < logLevels.length; i++) {
1100
+ if (!getCheckBox(logLevels[i]).checked) {
1101
+ getCheckBox("ALL").checked = false;
1102
+ return;
1103
+ }
1104
+ }
1105
+ getCheckBox("ALL").checked = true;
1106
+ }
1107
+
1108
+ function clearLog() {
1109
+ rootGroup.clear();
1110
+ currentGroup = rootGroup;
1111
+ logEntries = [];
1112
+ logItems = [];
1113
+ logEntriesAndSeparators = [];
1114
+ doSearch();
1115
+ }
1116
+
1117
+ function toggleWrap() {
1118
+ var enable = $("wrap").checked;
1119
+ if (enable) {
1120
+ addClass(logMainContainer, "wrap");
1121
+ } else {
1122
+ removeClass(logMainContainer, "wrap");
1123
+ }
1124
+ refreshCurrentMatch();
1125
+ }
1126
+
1127
+ /* ------------------------------------------------------------------- */
1128
+
1129
+ // Search
1130
+
1131
+ var searchTimer = null;
1132
+
1133
+ function scheduleSearch() {
1134
+ try {
1135
+ clearTimeout(searchTimer);
1136
+ } catch (ex) {
1137
+ // Do nothing
1138
+ }
1139
+ searchTimer = setTimeout(doSearch, 500);
1140
+ }
1141
+
1142
+ function Search(searchTerm, isRegex, searchRegex, isCaseSensitive) {
1143
+ this.searchTerm = searchTerm;
1144
+ this.isRegex = isRegex;
1145
+ this.searchRegex = searchRegex;
1146
+ this.isCaseSensitive = isCaseSensitive;
1147
+ this.matches = [];
1148
+ }
1149
+
1150
+ Search.prototype = {
1151
+ hasMatches: function() {
1152
+ return this.matches.length > 0;
1153
+ },
1154
+
1155
+ hasVisibleMatches: function() {
1156
+ if (this.hasMatches()) {
1157
+ for (var i = 0; i < this.matches.length; i++) {
1158
+ if (this.matches[i].isVisible()) {
1159
+ return true;
1160
+ }
1161
+ }
1162
+ }
1163
+ return false;
1164
+ },
1165
+
1166
+ match: function(logEntry) {
1167
+ var entryText = String(logEntry.formattedMessage);
1168
+ var matchesSearch = false;
1169
+ if (this.isRegex) {
1170
+ matchesSearch = this.searchRegex.test(entryText);
1171
+ } else if (this.isCaseSensitive) {
1172
+ matchesSearch = (entryText.indexOf(this.searchTerm) > -1);
1173
+ } else {
1174
+ matchesSearch = (entryText.toLowerCase().indexOf(this.searchTerm.toLowerCase()) > -1);
1175
+ }
1176
+ return matchesSearch;
1177
+ },
1178
+
1179
+ getNextVisibleMatchIndex: function() {
1180
+ for (var i = currentMatchIndex + 1; i < this.matches.length; i++) {
1181
+ if (this.matches[i].isVisible()) {
1182
+ return i;
1183
+ }
1184
+ }
1185
+ // Start again from the first match
1186
+ for (i = 0; i <= currentMatchIndex; i++) {
1187
+ if (this.matches[i].isVisible()) {
1188
+ return i;
1189
+ }
1190
+ }
1191
+ return -1;
1192
+ },
1193
+
1194
+ getPreviousVisibleMatchIndex: function() {
1195
+ for (var i = currentMatchIndex - 1; i >= 0; i--) {
1196
+ if (this.matches[i].isVisible()) {
1197
+ return i;
1198
+ }
1199
+ }
1200
+ // Start again from the last match
1201
+ for (var i = this.matches.length - 1; i >= currentMatchIndex; i--) {
1202
+ if (this.matches[i].isVisible()) {
1203
+ return i;
1204
+ }
1205
+ }
1206
+ return -1;
1207
+ },
1208
+
1209
+ applyTo: function(logEntry) {
1210
+ var doesMatch = this.match(logEntry);
1211
+ if (doesMatch) {
1212
+ logEntry.group.expand();
1213
+ logEntry.setSearchMatch(true);
1214
+ var logEntryContent;
1215
+ var wrappedLogEntryContent;
1216
+ var searchTermReplacementStartTag = "<span class=\"searchterm\">";
1217
+ var searchTermReplacementEndTag = "<" + "/span>";
1218
+ var preTagName = isIe ? "pre" : "span";
1219
+ var preStartTag = "<" + preTagName + " class=\"pre\">";
1220
+ var preEndTag = "<" + "/" + preTagName + ">";
1221
+ var startIndex = 0;
1222
+ var searchIndex, matchedText, textBeforeMatch;
1223
+ if (this.isRegex) {
1224
+ var flags = this.isCaseSensitive ? "g" : "gi";
1225
+ var capturingRegex = new RegExp("(" + this.searchRegex.source + ")", flags);
1226
+
1227
+ // Replace the search term with temporary tokens for the start and end tags
1228
+ var rnd = ("" + Math.random()).substr(2);
1229
+ var startToken = "%%s" + rnd + "%%";
1230
+ var endToken = "%%e" + rnd + "%%";
1231
+ logEntryContent = logEntry.formattedMessage.replace(capturingRegex, startToken + "$1" + endToken);
1232
+
1233
+ // Escape the HTML to get rid of angle brackets
1234
+ logEntryContent = escapeHtml(logEntryContent);
1235
+
1236
+ // Substitute the proper HTML back in for the search match
1237
+ var result;
1238
+ var searchString = logEntryContent;
1239
+ logEntryContent = "";
1240
+ wrappedLogEntryContent = "";
1241
+ while ((searchIndex = searchString.indexOf(startToken, startIndex)) > -1) {
1242
+ var endTokenIndex = searchString.indexOf(endToken, searchIndex);
1243
+ matchedText = searchString.substring(searchIndex + startToken.length, endTokenIndex);
1244
+ textBeforeMatch = searchString.substring(startIndex, searchIndex);
1245
+ logEntryContent += preStartTag + textBeforeMatch + preEndTag;
1246
+ logEntryContent += searchTermReplacementStartTag + preStartTag + matchedText +
1247
+ preEndTag + searchTermReplacementEndTag;
1248
+ if (isIe) {
1249
+ wrappedLogEntryContent += textBeforeMatch + searchTermReplacementStartTag +
1250
+ matchedText + searchTermReplacementEndTag;
1251
+ }
1252
+ startIndex = endTokenIndex + endToken.length;
1253
+ }
1254
+ logEntryContent += preStartTag + searchString.substr(startIndex) + preEndTag;
1255
+ if (isIe) {
1256
+ wrappedLogEntryContent += searchString.substr(startIndex);
1257
+ }
1258
+ } else {
1259
+ logEntryContent = "";
1260
+ wrappedLogEntryContent = "";
1261
+ var searchTermReplacementLength = searchTermReplacementStartTag.length +
1262
+ this.searchTerm.length + searchTermReplacementEndTag.length;
1263
+ var searchTermLength = this.searchTerm.length;
1264
+ var searchTermLowerCase = this.searchTerm.toLowerCase();
1265
+ var logTextLowerCase = logEntry.formattedMessage.toLowerCase();
1266
+ while ((searchIndex = logTextLowerCase.indexOf(searchTermLowerCase, startIndex)) > -1) {
1267
+ matchedText = escapeHtml(logEntry.formattedMessage.substr(searchIndex, this.searchTerm.length));
1268
+ textBeforeMatch = escapeHtml(logEntry.formattedMessage.substring(startIndex, searchIndex));
1269
+ var searchTermReplacement = searchTermReplacementStartTag +
1270
+ preStartTag + matchedText + preEndTag + searchTermReplacementEndTag;
1271
+ logEntryContent += preStartTag + textBeforeMatch + preEndTag + searchTermReplacement;
1272
+ if (isIe) {
1273
+ wrappedLogEntryContent += textBeforeMatch + searchTermReplacementStartTag +
1274
+ matchedText + searchTermReplacementEndTag;
1275
+ }
1276
+ startIndex = searchIndex + searchTermLength;
1277
+ }
1278
+ var textAfterLastMatch = escapeHtml(logEntry.formattedMessage.substr(startIndex));
1279
+ logEntryContent += preStartTag + textAfterLastMatch + preEndTag;
1280
+ if (isIe) {
1281
+ wrappedLogEntryContent += textAfterLastMatch;
1282
+ }
1283
+ }
1284
+ logEntry.setContent(logEntryContent, wrappedLogEntryContent);
1285
+ var logEntryMatches = logEntry.getSearchMatches();
1286
+ this.matches = this.matches.concat(logEntryMatches);
1287
+ } else {
1288
+ logEntry.setSearchMatch(false);
1289
+ logEntry.setContent(logEntry.formattedMessage, logEntry.formattedMessage);
1290
+ }
1291
+ return doesMatch;
1292
+ },
1293
+
1294
+ removeMatches: function(logEntries) {
1295
+ var matchesToRemoveCount = 0;
1296
+ var currentMatchRemoved = false;
1297
+ var matchesToRemove = [];
1298
+ var i, iLen, j, jLen;
1299
+
1300
+ // Establish the list of matches to be removed
1301
+ for (i = 0, iLen = this.matches.length; i < iLen; i++) {
1302
+ for (j = 0, jLen = logEntries.length; j < jLen; j++) {
1303
+ if (this.matches[i].belongsTo(logEntries[j])) {
1304
+ matchesToRemove.push(this.matches[i]);
1305
+ if (i === currentMatchIndex) {
1306
+ currentMatchRemoved = true;
1307
+ }
1308
+ }
1309
+ }
1310
+ }
1311
+
1312
+ // Set the new current match index if the current match has been deleted
1313
+ // This will be the first match that appears after the first log entry being
1314
+ // deleted, if one exists; otherwise, it's the first match overall
1315
+ var newMatch = currentMatchRemoved ? null : this.matches[currentMatchIndex];
1316
+ if (currentMatchRemoved) {
1317
+ for (i = currentMatchIndex, iLen = this.matches.length; i < iLen; i++) {
1318
+ if (this.matches[i].isVisible() && !array_contains(matchesToRemove, this.matches[i])) {
1319
+ newMatch = this.matches[i];
1320
+ break;
1321
+ }
1322
+ }
1323
+ }
1324
+
1325
+ // Remove the matches
1326
+ for (i = 0, iLen = matchesToRemove.length; i < iLen; i++) {
1327
+ array_remove(this.matches, matchesToRemove[i]);
1328
+ matchesToRemove[i].remove();
1329
+ }
1330
+
1331
+ // Set the new match, if one exists
1332
+ if (this.hasVisibleMatches()) {
1333
+ if (newMatch === null) {
1334
+ setCurrentMatchIndex(0);
1335
+ } else {
1336
+ // Get the index of the new match
1337
+ var newMatchIndex = 0;
1338
+ for (i = 0, iLen = this.matches.length; i < iLen; i++) {
1339
+ if (newMatch === this.matches[i]) {
1340
+ newMatchIndex = i;
1341
+ break;
1342
+ }
1343
+ }
1344
+ setCurrentMatchIndex(newMatchIndex);
1345
+ }
1346
+ } else {
1347
+ currentMatchIndex = null;
1348
+ displayNoMatches();
1349
+ }
1350
+ }
1351
+ };
1352
+
1353
+ function getPageOffsetTop(el, container) {
1354
+ var currentEl = el;
1355
+ var y = 0;
1356
+ while (currentEl && currentEl != container) {
1357
+ y += currentEl.offsetTop;
1358
+ currentEl = currentEl.offsetParent;
1359
+ }
1360
+ return y;
1361
+ }
1362
+
1363
+ function scrollIntoView(el) {
1364
+ var logContainer = logMainContainer;
1365
+ // Check if the whole width of the element is visible and centre if not
1366
+ if (!$("wrap").checked) {
1367
+ var logContainerLeft = logContainer.scrollLeft;
1368
+ var logContainerRight = logContainerLeft + logContainer.offsetWidth;
1369
+ var elLeft = el.offsetLeft;
1370
+ var elRight = elLeft + el.offsetWidth;
1371
+ if (elLeft < logContainerLeft || elRight > logContainerRight) {
1372
+ logContainer.scrollLeft = elLeft - (logContainer.offsetWidth - el.offsetWidth) / 2;
1373
+ }
1374
+ }
1375
+ // Check if the whole height of the element is visible and centre if not
1376
+ var logContainerTop = logContainer.scrollTop;
1377
+ var logContainerBottom = logContainerTop + logContainer.offsetHeight;
1378
+ var elTop = getPageOffsetTop(el) - getToolBarsHeight();
1379
+ var elBottom = elTop + el.offsetHeight;
1380
+ if (elTop < logContainerTop || elBottom > logContainerBottom) {
1381
+ logContainer.scrollTop = elTop - (logContainer.offsetHeight - el.offsetHeight) / 2;
1382
+ }
1383
+ }
1384
+
1385
+ function Match(logEntryLevel, spanInMainDiv, spanInUnwrappedPre, spanInWrappedDiv) {
1386
+ this.logEntryLevel = logEntryLevel;
1387
+ this.spanInMainDiv = spanInMainDiv;
1388
+ if (isIe) {
1389
+ this.spanInUnwrappedPre = spanInUnwrappedPre;
1390
+ this.spanInWrappedDiv = spanInWrappedDiv;
1391
+ }
1392
+ this.mainSpan = isIe ? spanInUnwrappedPre : spanInMainDiv;
1393
+ }
1394
+
1395
+ Match.prototype = {
1396
+ equals: function(match) {
1397
+ return this.mainSpan === match.mainSpan;
1398
+ },
1399
+
1400
+ setCurrent: function() {
1401
+ if (isIe) {
1402
+ addClass(this.spanInUnwrappedPre, "currentmatch");
1403
+ addClass(this.spanInWrappedDiv, "currentmatch");
1404
+ // Scroll the visible one into view
1405
+ var elementToScroll = $("wrap").checked ? this.spanInWrappedDiv : this.spanInUnwrappedPre;
1406
+ scrollIntoView(elementToScroll);
1407
+ } else {
1408
+ addClass(this.spanInMainDiv, "currentmatch");
1409
+ scrollIntoView(this.spanInMainDiv);
1410
+ }
1411
+ },
1412
+
1413
+ belongsTo: function(logEntry) {
1414
+ if (isIe) {
1415
+ return isDescendant(this.spanInUnwrappedPre, logEntry.unwrappedPre);
1416
+ } else {
1417
+ return isDescendant(this.spanInMainDiv, logEntry.mainDiv);
1418
+ }
1419
+ },
1420
+
1421
+ setNotCurrent: function() {
1422
+ if (isIe) {
1423
+ removeClass(this.spanInUnwrappedPre, "currentmatch");
1424
+ removeClass(this.spanInWrappedDiv, "currentmatch");
1425
+ } else {
1426
+ removeClass(this.spanInMainDiv, "currentmatch");
1427
+ }
1428
+ },
1429
+
1430
+ isOrphan: function() {
1431
+ return isOrphan(this.mainSpan);
1432
+ },
1433
+
1434
+ isVisible: function() {
1435
+ return getCheckBox(this.logEntryLevel).checked;
1436
+ },
1437
+
1438
+ remove: function() {
1439
+ if (isIe) {
1440
+ this.spanInUnwrappedPre = null;
1441
+ this.spanInWrappedDiv = null;
1442
+ } else {
1443
+ this.spanInMainDiv = null;
1444
+ }
1445
+ }
1446
+ };
1447
+
1448
+ var currentSearch = null;
1449
+ var currentMatchIndex = null;
1450
+
1451
+ function doSearch() {
1452
+ var searchBox = $("searchBox");
1453
+ var searchTerm = searchBox.value;
1454
+ var isRegex = $("searchRegex").checked;
1455
+ var isCaseSensitive = $("searchCaseSensitive").checked;
1456
+ var i;
1457
+
1458
+ if (searchTerm === "") {
1459
+ $("searchReset").disabled = true;
1460
+ $("searchNav").style.display = "none";
1461
+ removeClass(document.body, "searching");
1462
+ removeClass(searchBox, "hasmatches");
1463
+ removeClass(searchBox, "nomatches");
1464
+ for (i = 0; i < logEntries.length; i++) {
1465
+ logEntries[i].clearSearch();
1466
+ logEntries[i].setContent(logEntries[i].formattedMessage, logEntries[i].formattedMessage);
1467
+ }
1468
+ currentSearch = null;
1469
+ setLogContainerHeight();
1470
+ } else {
1471
+ $("searchReset").disabled = false;
1472
+ $("searchNav").style.display = "block";
1473
+ var searchRegex;
1474
+ var regexValid;
1475
+ if (isRegex) {
1476
+ try {
1477
+ searchRegex = isCaseSensitive ? new RegExp(searchTerm, "g") : new RegExp(searchTerm, "gi");
1478
+ regexValid = true;
1479
+ replaceClass(searchBox, "validregex", "invalidregex");
1480
+ searchBox.title = "Valid regex";
1481
+ } catch (ex) {
1482
+ regexValid = false;
1483
+ replaceClass(searchBox, "invalidregex", "validregex");
1484
+ searchBox.title = "Invalid regex: " + (ex.message ? ex.message : (ex.description ? ex.description : "unknown error"));
1485
+ return;
1486
+ }
1487
+ } else {
1488
+ searchBox.title = "";
1489
+ removeClass(searchBox, "validregex");
1490
+ removeClass(searchBox, "invalidregex");
1491
+ }
1492
+ addClass(document.body, "searching");
1493
+ currentSearch = new Search(searchTerm, isRegex, searchRegex, isCaseSensitive);
1494
+ for (i = 0; i < logEntries.length; i++) {
1495
+ currentSearch.applyTo(logEntries[i]);
1496
+ }
1497
+ setLogContainerHeight();
1498
+
1499
+ // Highlight the first search match
1500
+ if (currentSearch.hasVisibleMatches()) {
1501
+ setCurrentMatchIndex(0);
1502
+ displayMatches();
1503
+ } else {
1504
+ displayNoMatches();
1505
+ }
1506
+ }
1507
+ }
1508
+
1509
+ function updateSearchFromFilters() {
1510
+ if (currentSearch) {
1511
+ if (currentSearch.hasMatches()) {
1512
+ if (currentMatchIndex === null) {
1513
+ currentMatchIndex = 0;
1514
+ }
1515
+ var currentMatch = currentSearch.matches[currentMatchIndex];
1516
+ if (currentMatch.isVisible()) {
1517
+ displayMatches();
1518
+ setCurrentMatchIndex(currentMatchIndex);
1519
+ } else {
1520
+ currentMatch.setNotCurrent();
1521
+ // Find the next visible match, if one exists
1522
+ var nextVisibleMatchIndex = currentSearch.getNextVisibleMatchIndex();
1523
+ if (nextVisibleMatchIndex > -1) {
1524
+ setCurrentMatchIndex(nextVisibleMatchIndex);
1525
+ displayMatches();
1526
+ } else {
1527
+ displayNoMatches();
1528
+ }
1529
+ }
1530
+ } else {
1531
+ displayNoMatches();
1532
+ }
1533
+ }
1534
+ }
1535
+
1536
+ function refreshCurrentMatch() {
1537
+ if (currentSearch && currentSearch.hasVisibleMatches()) {
1538
+ setCurrentMatchIndex(currentMatchIndex);
1539
+ }
1540
+ }
1541
+
1542
+ function displayMatches() {
1543
+ replaceClass($("searchBox"), "hasmatches", "nomatches");
1544
+ $("searchBox").title = "" + currentSearch.matches.length + " matches found";
1545
+ $("searchNav").style.display = "block";
1546
+ setLogContainerHeight();
1547
+ }
1548
+
1549
+ function displayNoMatches() {
1550
+ replaceClass($("searchBox"), "nomatches", "hasmatches");
1551
+ $("searchBox").title = "No matches found";
1552
+ $("searchNav").style.display = "none";
1553
+ setLogContainerHeight();
1554
+ }
1555
+
1556
+ function toggleSearchEnabled(enable) {
1557
+ enable = (typeof enable == "undefined") ? !$("searchDisable").checked : enable;
1558
+ $("searchBox").disabled = !enable;
1559
+ $("searchReset").disabled = !enable;
1560
+ $("searchRegex").disabled = !enable;
1561
+ $("searchNext").disabled = !enable;
1562
+ $("searchPrevious").disabled = !enable;
1563
+ $("searchCaseSensitive").disabled = !enable;
1564
+ $("searchNav").style.display = (enable && ($("searchBox").value !== "") &&
1565
+ currentSearch && currentSearch.hasVisibleMatches()) ?
1566
+ "block" : "none";
1567
+ if (enable) {
1568
+ removeClass($("search"), "greyedout");
1569
+ addClass(document.body, "searching");
1570
+ if ($("searchHighlight").checked) {
1571
+ addClass(logMainContainer, "searchhighlight");
1572
+ } else {
1573
+ removeClass(logMainContainer, "searchhighlight");
1574
+ }
1575
+ if ($("searchFilter").checked) {
1576
+ addClass(logMainContainer, "searchfilter");
1577
+ } else {
1578
+ removeClass(logMainContainer, "searchfilter");
1579
+ }
1580
+ $("searchDisable").checked = !enable;
1581
+ } else {
1582
+ addClass($("search"), "greyedout");
1583
+ removeClass(document.body, "searching");
1584
+ removeClass(logMainContainer, "searchhighlight");
1585
+ removeClass(logMainContainer, "searchfilter");
1586
+ }
1587
+ setLogContainerHeight();
1588
+ }
1589
+
1590
+ function toggleSearchFilter() {
1591
+ var enable = $("searchFilter").checked;
1592
+ if (enable) {
1593
+ addClass(logMainContainer, "searchfilter");
1594
+ } else {
1595
+ removeClass(logMainContainer, "searchfilter");
1596
+ }
1597
+ refreshCurrentMatch();
1598
+ }
1599
+
1600
+ function toggleSearchHighlight() {
1601
+ var enable = $("searchHighlight").checked;
1602
+ if (enable) {
1603
+ addClass(logMainContainer, "searchhighlight");
1604
+ } else {
1605
+ removeClass(logMainContainer, "searchhighlight");
1606
+ }
1607
+ }
1608
+
1609
+ function clearSearch() {
1610
+ $("searchBox").value = "";
1611
+ doSearch();
1612
+ }
1613
+
1614
+ function searchNext() {
1615
+ if (currentSearch !== null && currentMatchIndex !== null) {
1616
+ currentSearch.matches[currentMatchIndex].setNotCurrent();
1617
+ var nextMatchIndex = currentSearch.getNextVisibleMatchIndex();
1618
+ if (nextMatchIndex > currentMatchIndex || confirm("Reached the end of the page. Start from the top?")) {
1619
+ setCurrentMatchIndex(nextMatchIndex);
1620
+ }
1621
+ }
1622
+ }
1623
+
1624
+ function searchPrevious() {
1625
+ if (currentSearch !== null && currentMatchIndex !== null) {
1626
+ currentSearch.matches[currentMatchIndex].setNotCurrent();
1627
+ var previousMatchIndex = currentSearch.getPreviousVisibleMatchIndex();
1628
+ if (previousMatchIndex < currentMatchIndex || confirm("Reached the start of the page. Continue from the bottom?")) {
1629
+ setCurrentMatchIndex(previousMatchIndex);
1630
+ }
1631
+ }
1632
+ }
1633
+
1634
+ function setCurrentMatchIndex(index) {
1635
+ currentMatchIndex = index;
1636
+ currentSearch.matches[currentMatchIndex].setCurrent();
1637
+ }
1638
+
1639
+ /* ------------------------------------------------------------------------- */
1640
+
1641
+ // CSS Utilities
1642
+
1643
+ function addClass(el, cssClass) {
1644
+ if (!hasClass(el, cssClass)) {
1645
+ if (el.className) {
1646
+ el.className += " " + cssClass;
1647
+ } else {
1648
+ el.className = cssClass;
1649
+ }
1650
+ }
1651
+ }
1652
+
1653
+ function hasClass(el, cssClass) {
1654
+ if (el.className) {
1655
+ var classNames = el.className.split(" ");
1656
+ return array_contains(classNames, cssClass);
1657
+ }
1658
+ return false;
1659
+ }
1660
+
1661
+ function removeClass(el, cssClass) {
1662
+ if (hasClass(el, cssClass)) {
1663
+ // Rebuild the className property
1664
+ var existingClasses = el.className.split(" ");
1665
+ var newClasses = [];
1666
+ for (var i = 0, len = existingClasses.length; i < len; i++) {
1667
+ if (existingClasses[i] != cssClass) {
1668
+ newClasses[newClasses.length] = existingClasses[i];
1669
+ }
1670
+ }
1671
+ el.className = newClasses.join(" ");
1672
+ }
1673
+ }
1674
+
1675
+ function replaceClass(el, newCssClass, oldCssClass) {
1676
+ removeClass(el, oldCssClass);
1677
+ addClass(el, newCssClass);
1678
+ }
1679
+
1680
+ /* ------------------------------------------------------------------------- */
1681
+
1682
+ // Other utility functions
1683
+
1684
+ function getElementsByClass(el, cssClass, tagName) {
1685
+ var elements = el.getElementsByTagName(tagName);
1686
+ var matches = [];
1687
+ for (var i = 0, len = elements.length; i < len; i++) {
1688
+ if (hasClass(elements[i], cssClass)) {
1689
+ matches.push(elements[i]);
1690
+ }
1691
+ }
1692
+ return matches;
1693
+ }
1694
+
1695
+ // Syntax borrowed from Prototype library
1696
+ function $(id) {
1697
+ return document.getElementById(id);
1698
+ }
1699
+
1700
+ function isDescendant(node, ancestorNode) {
1701
+ while (node != null) {
1702
+ if (node === ancestorNode) {
1703
+ return true;
1704
+ }
1705
+ node = node.parentNode;
1706
+ }
1707
+ return false;
1708
+ }
1709
+
1710
+ function isOrphan(node) {
1711
+ var currentNode = node;
1712
+ while (currentNode) {
1713
+ if (currentNode == document.body) {
1714
+ return false;
1715
+ }
1716
+ currentNode = currentNode.parentNode;
1717
+ }
1718
+ return true;
1719
+ }
1720
+
1721
+ function escapeHtml(str) {
1722
+ return str.replace(/&/g, "&amp;").replace(/[<]/g, "&lt;").replace(/>/g, "&gt;");
1723
+ }
1724
+
1725
+ function getWindowWidth() {
1726
+ if (window.innerWidth) {
1727
+ return window.innerWidth;
1728
+ } else if (document.documentElement && document.documentElement.clientWidth) {
1729
+ return document.documentElement.clientWidth;
1730
+ } else if (document.body) {
1731
+ return document.body.clientWidth;
1732
+ }
1733
+ return 0;
1734
+ }
1735
+
1736
+ function getWindowHeight() {
1737
+ if (window.innerHeight) {
1738
+ return window.innerHeight;
1739
+ } else if (document.documentElement && document.documentElement.clientHeight) {
1740
+ return document.documentElement.clientHeight;
1741
+ } else if (document.body) {
1742
+ return document.body.clientHeight;
1743
+ }
1744
+ return 0;
1745
+ }
1746
+
1747
+ function getToolBarsHeight() {
1748
+ return $("switches").offsetHeight;
1749
+ }
1750
+
1751
+ function getChromeHeight() {
1752
+ var height = getToolBarsHeight();
1753
+ if (showCommandLine) {
1754
+ height += $("commandLine").offsetHeight;
1755
+ }
1756
+ return height;
1757
+ }
1758
+
1759
+ function setLogContainerHeight() {
1760
+ if (logMainContainer) {
1761
+ var windowHeight = getWindowHeight();
1762
+ $("body").style.height = getWindowHeight() + "px";
1763
+ logMainContainer.style.height = "" +
1764
+ Math.max(0, windowHeight - getChromeHeight()) + "px";
1765
+ }
1766
+ }
1767
+
1768
+ function setCommandInputWidth() {
1769
+ if (showCommandLine) {
1770
+ $("command").style.width = "" + Math.max(0, $("commandLineContainer").offsetWidth -
1771
+ ($("evaluateButton").offsetWidth + 13)) + "px";
1772
+ }
1773
+ }
1774
+
1775
+ window.onresize = function() {
1776
+ setCommandInputWidth();
1777
+ setLogContainerHeight();
1778
+ };
1779
+
1780
+ if (!Array.prototype.push) {
1781
+ Array.prototype.push = function() {
1782
+ for (var i = 0, len = arguments.length; i < len; i++){
1783
+ this[this.length] = arguments[i];
1784
+ }
1785
+ return this.length;
1786
+ };
1787
+ }
1788
+
1789
+ if (!Array.prototype.pop) {
1790
+ Array.prototype.pop = function() {
1791
+ if (this.length > 0) {
1792
+ var val = this[this.length - 1];
1793
+ this.length = this.length - 1;
1794
+ return val;
1795
+ }
1796
+ };
1797
+ }
1798
+
1799
+ if (!Array.prototype.shift) {
1800
+ Array.prototype.shift = function() {
1801
+ if (this.length > 0) {
1802
+ var firstItem = this[0];
1803
+ for (var i = 0, len = this.length - 1; i < len; i++) {
1804
+ this[i] = this[i + 1];
1805
+ }
1806
+ this.length = this.length - 1;
1807
+ return firstItem;
1808
+ }
1809
+ };
1810
+ }
1811
+
1812
+ if (!Array.prototype.splice) {
1813
+ Array.prototype.splice = function(startIndex, deleteCount) {
1814
+ var itemsAfterDeleted = this.slice(startIndex + deleteCount);
1815
+ var itemsDeleted = this.slice(startIndex, startIndex + deleteCount);
1816
+ this.length = startIndex;
1817
+ // Copy the arguments into a proper Array object
1818
+ var argumentsArray = [];
1819
+ for (var i = 0, len = arguments.length; i < len; i++) {
1820
+ argumentsArray[i] = arguments[i];
1821
+ }
1822
+ var itemsToAppend = (argumentsArray.length > 2) ?
1823
+ itemsAfterDeleted = argumentsArray.slice(2).concat(itemsAfterDeleted) : itemsAfterDeleted;
1824
+ for (i = 0, len = itemsToAppend.length; i < len; i++) {
1825
+ this.push(itemsToAppend[i]);
1826
+ }
1827
+ return itemsDeleted;
1828
+ };
1829
+ }
1830
+
1831
+ function array_remove(arr, val) {
1832
+ var index = -1;
1833
+ for (var i = 0, len = arr.length; i < len; i++) {
1834
+ if (arr[i] === val) {
1835
+ index = i;
1836
+ break;
1837
+ }
1838
+ }
1839
+ if (index >= 0) {
1840
+ arr.splice(index, 1);
1841
+ return index;
1842
+ } else {
1843
+ return false;
1844
+ }
1845
+ }
1846
+
1847
+ function array_removeFromStart(array, numberToRemove) {
1848
+ if (Array.prototype.splice) {
1849
+ array.splice(0, numberToRemove);
1850
+ } else {
1851
+ for (var i = numberToRemove, len = array.length; i < len; i++) {
1852
+ array[i - numberToRemove] = array[i];
1853
+ }
1854
+ array.length = array.length - numberToRemove;
1855
+ }
1856
+ return array;
1857
+ }
1858
+
1859
+ function array_contains(arr, val) {
1860
+ for (var i = 0, len = arr.length; i < len; i++) {
1861
+ if (arr[i] == val) {
1862
+ return true;
1863
+ }
1864
+ }
1865
+ return false;
1866
+ }
1867
+
1868
+ function getErrorMessage(ex) {
1869
+ if (ex.message) {
1870
+ return ex.message;
1871
+ } else if (ex.description) {
1872
+ return ex.description;
1873
+ }
1874
+ return "" + ex;
1875
+ }
1876
+
1877
+ function moveCaretToEnd(input) {
1878
+ if (input.setSelectionRange) {
1879
+ input.focus();
1880
+ var length = input.value.length;
1881
+ input.setSelectionRange(length, length);
1882
+ } else if (input.createTextRange) {
1883
+ var range = input.createTextRange();
1884
+ range.collapse(false);
1885
+ range.select();
1886
+ }
1887
+ input.focus();
1888
+ }
1889
+
1890
+ function stopPropagation(evt) {
1891
+ if (evt.stopPropagation) {
1892
+ evt.stopPropagation();
1893
+ } else if (typeof evt.cancelBubble != "undefined") {
1894
+ evt.cancelBubble = true;
1895
+ }
1896
+ }
1897
+
1898
+ function getEvent(evt) {
1899
+ return evt ? evt : event;
1900
+ }
1901
+
1902
+ function getTarget(evt) {
1903
+ return evt.target ? evt.target : evt.srcElement;
1904
+ }
1905
+
1906
+ function getRelatedTarget(evt) {
1907
+ if (evt.relatedTarget) {
1908
+ return evt.relatedTarget;
1909
+ } else if (evt.srcElement) {
1910
+ switch(evt.type) {
1911
+ case "mouseover":
1912
+ return evt.fromElement;
1913
+ case "mouseout":
1914
+ return evt.toElement;
1915
+ default:
1916
+ return evt.srcElement;
1917
+ }
1918
+ }
1919
+ }
1920
+
1921
+ function cancelKeyEvent(evt) {
1922
+ evt.returnValue = false;
1923
+ stopPropagation(evt);
1924
+ }
1925
+
1926
+ function evalCommandLine() {
1927
+ var expr = $("command").value;
1928
+ evalCommand(expr);
1929
+ $("command").value = "";
1930
+ }
1931
+
1932
+ function evalLastCommand() {
1933
+ if (lastCommand != null) {
1934
+ evalCommand(lastCommand);
1935
+ }
1936
+ }
1937
+
1938
+ var lastCommand = null;
1939
+ var commandHistory = [];
1940
+ var currentCommandIndex = 0;
1941
+
1942
+ function evalCommand(expr) {
1943
+ if (appender) {
1944
+ appender.evalCommandAndAppend(expr);
1945
+ } else {
1946
+ var prefix = ">>> " + expr + "\r\n";
1947
+ try {
1948
+ log("INFO", prefix + eval(expr));
1949
+ } catch (ex) {
1950
+ log("ERROR", prefix + "Error: " + getErrorMessage(ex));
1951
+ }
1952
+ }
1953
+ // Update command history
1954
+ if (expr != commandHistory[commandHistory.length - 1]) {
1955
+ commandHistory.push(expr);
1956
+ // Update the appender
1957
+ if (appender) {
1958
+ appender.storeCommandHistory(commandHistory);
1959
+ }
1960
+ }
1961
+ currentCommandIndex = (expr == commandHistory[currentCommandIndex]) ? currentCommandIndex + 1 : commandHistory.length;
1962
+ lastCommand = expr;
1963
+ }
1964
+ //]]>
1965
+ </script>
1966
+ <style type="text/css">
1967
+ body {
1968
+ background-color: white;
1969
+ color: black;
1970
+ padding: 0;
1971
+ margin: 0;
1972
+ font-family: tahoma, verdana, arial, helvetica, sans-serif;
1973
+ overflow: hidden;
1974
+ }
1975
+
1976
+ div#switchesContainer input {
1977
+ margin-bottom: 0;
1978
+ }
1979
+
1980
+ div.toolbar {
1981
+ border-top: solid #ffffff 1px;
1982
+ border-bottom: solid #aca899 1px;
1983
+ background-color: #f1efe7;
1984
+ padding: 3px 5px;
1985
+ font-size: 68.75%;
1986
+ }
1987
+
1988
+ div.toolbar, div#search input {
1989
+ font-family: tahoma, verdana, arial, helvetica, sans-serif;
1990
+ }
1991
+
1992
+ div.toolbar input.button {
1993
+ padding: 0 5px;
1994
+ font-size: 100%;
1995
+ }
1996
+
1997
+ div.toolbar input.hidden {
1998
+ display: none;
1999
+ }
2000
+
2001
+ div#switches input#clearButton {
2002
+ margin-left: 20px;
2003
+ }
2004
+
2005
+ div#levels label {
2006
+ font-weight: bold;
2007
+ }
2008
+
2009
+ div#levels label, div#options label {
2010
+ margin-right: 5px;
2011
+ }
2012
+
2013
+ div#levels label#wrapLabel {
2014
+ font-weight: normal;
2015
+ }
2016
+
2017
+ div#search label {
2018
+ margin-right: 10px;
2019
+ }
2020
+
2021
+ div#search label.searchboxlabel {
2022
+ margin-right: 0;
2023
+ }
2024
+
2025
+ div#search input {
2026
+ font-size: 100%;
2027
+ }
2028
+
2029
+ div#search input.validregex {
2030
+ color: green;
2031
+ }
2032
+
2033
+ div#search input.invalidregex {
2034
+ color: red;
2035
+ }
2036
+
2037
+ div#search input.nomatches {
2038
+ color: white;
2039
+ background-color: #ff6666;
2040
+ }
2041
+
2042
+ div#search input.nomatches {
2043
+ color: white;
2044
+ background-color: #ff6666;
2045
+ }
2046
+
2047
+ div#searchNav {
2048
+ display: none;
2049
+ }
2050
+
2051
+ div#commandLine {
2052
+ display: none;
2053
+ }
2054
+
2055
+ div#commandLine input#command {
2056
+ font-size: 100%;
2057
+ font-family: Courier New, Courier;
2058
+ }
2059
+
2060
+ div#commandLine input#evaluateButton {
2061
+ }
2062
+
2063
+ *.greyedout {
2064
+ color: gray !important;
2065
+ border-color: gray !important;
2066
+ }
2067
+
2068
+ *.greyedout *.alwaysenabled { color: black; }
2069
+
2070
+ *.unselectable {
2071
+ -khtml-user-select: none;
2072
+ -moz-user-select: none;
2073
+ user-select: none;
2074
+ }
2075
+
2076
+ div#log {
2077
+ font-family: Courier New, Courier;
2078
+ font-size: 75%;
2079
+ width: 100%;
2080
+ overflow: auto;
2081
+ clear: both;
2082
+ position: relative;
2083
+ }
2084
+
2085
+ div.group {
2086
+ border-color: #cccccc;
2087
+ border-style: solid;
2088
+ border-width: 1px 0 1px 1px;
2089
+ overflow: visible;
2090
+ }
2091
+
2092
+ div.oldIe div.group, div.oldIe div.group *, div.oldIe *.logentry {
2093
+ height: 1%;
2094
+ }
2095
+
2096
+ div.group div.groupheading span.expander {
2097
+ border: solid black 1px;
2098
+ font-family: Courier New, Courier;
2099
+ font-size: 0.833em;
2100
+ background-color: #eeeeee;
2101
+ position: relative;
2102
+ top: -1px;
2103
+ color: black;
2104
+ padding: 0 2px;
2105
+ cursor: pointer;
2106
+ cursor: hand;
2107
+ height: 1%;
2108
+ }
2109
+
2110
+ div.group div.groupcontent {
2111
+ margin-left: 10px;
2112
+ padding-bottom: 2px;
2113
+ overflow: visible;
2114
+ }
2115
+
2116
+ div.group div.expanded {
2117
+ display: block;
2118
+ }
2119
+
2120
+ div.group div.collapsed {
2121
+ display: none;
2122
+ }
2123
+
2124
+ *.logentry {
2125
+ overflow: visible;
2126
+ display: none;
2127
+ white-space: pre;
2128
+ }
2129
+
2130
+ span.pre {
2131
+ white-space: pre;
2132
+ }
2133
+
2134
+ pre.unwrapped {
2135
+ display: inline !important;
2136
+ }
2137
+
2138
+ pre.unwrapped pre.pre, div.wrapped pre.pre {
2139
+ display: inline;
2140
+ }
2141
+
2142
+ div.wrapped pre.pre {
2143
+ white-space: normal;
2144
+ }
2145
+
2146
+ div.wrapped {
2147
+ display: none;
2148
+ }
2149
+
2150
+ body.searching *.logentry span.currentmatch {
2151
+ color: white !important;
2152
+ background-color: green !important;
2153
+ }
2154
+
2155
+ body.searching div.searchhighlight *.logentry span.searchterm {
2156
+ color: black;
2157
+ background-color: yellow;
2158
+ }
2159
+
2160
+ div.wrap *.logentry {
2161
+ white-space: normal !important;
2162
+ border-width: 0 0 1px 0;
2163
+ border-color: #dddddd;
2164
+ border-style: dotted;
2165
+ }
2166
+
2167
+ div.wrap #log_wrapped, #log_unwrapped {
2168
+ display: block;
2169
+ }
2170
+
2171
+ div.wrap #log_unwrapped, #log_wrapped {
2172
+ display: none;
2173
+ }
2174
+
2175
+ div.wrap *.logentry span.pre {
2176
+ overflow: visible;
2177
+ white-space: normal;
2178
+ }
2179
+
2180
+ div.wrap *.logentry pre.unwrapped {
2181
+ display: none;
2182
+ }
2183
+
2184
+ div.wrap *.logentry span.wrapped {
2185
+ display: inline;
2186
+ }
2187
+
2188
+ div.searchfilter *.searchnonmatch {
2189
+ display: none !important;
2190
+ }
2191
+
2192
+ div#log *.TRACE, label#label_TRACE {
2193
+ color: #666666;
2194
+ }
2195
+
2196
+ div#log *.DEBUG, label#label_DEBUG {
2197
+ color: green;
2198
+ }
2199
+
2200
+ div#log *.INFO, label#label_INFO {
2201
+ color: #000099;
2202
+ }
2203
+
2204
+ div#log *.WARN, label#label_WARN {
2205
+ color: #999900;
2206
+ }
2207
+
2208
+ div#log *.ERROR, label#label_ERROR {
2209
+ color: red;
2210
+ }
2211
+
2212
+ div#log *.FATAL, label#label_FATAL {
2213
+ color: #660066;
2214
+ }
2215
+
2216
+ div.TRACE#log *.TRACE,
2217
+ div.DEBUG#log *.DEBUG,
2218
+ div.INFO#log *.INFO,
2219
+ div.WARN#log *.WARN,
2220
+ div.ERROR#log *.ERROR,
2221
+ div.FATAL#log *.FATAL {
2222
+ display: block;
2223
+ }
2224
+
2225
+ div#log div.separator {
2226
+ background-color: #cccccc;
2227
+ margin: 5px 0;
2228
+ line-height: 1px;
2229
+ }
2230
+ </style>
2231
+ </head>
2232
+
2233
+ <body id="body">
2234
+ <div id="switchesContainer">
2235
+ <div id="switches">
2236
+ <div id="levels" class="toolbar">
2237
+ Filters:
2238
+ <input type="checkbox" id="switch_TRACE" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide trace messages" /><label for="switch_TRACE" id="label_TRACE">trace</label>
2239
+ <input type="checkbox" id="switch_DEBUG" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide debug messages" /><label for="switch_DEBUG" id="label_DEBUG">debug</label>
2240
+ <input type="checkbox" id="switch_INFO" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide info messages" /><label for="switch_INFO" id="label_INFO">info</label>
2241
+ <input type="checkbox" id="switch_WARN" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide warn messages" /><label for="switch_WARN" id="label_WARN">warn</label>
2242
+ <input type="checkbox" id="switch_ERROR" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide error messages" /><label for="switch_ERROR" id="label_ERROR">error</label>
2243
+ <input type="checkbox" id="switch_FATAL" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide fatal messages" /><label for="switch_FATAL" id="label_FATAL">fatal</label>
2244
+ <input type="checkbox" id="switch_ALL" onclick="toggleAllLevels(); applyFilters()" checked="checked" title="Show/hide all messages" /><label for="switch_ALL" id="label_ALL">all</label>
2245
+ </div>
2246
+ <div id="search" class="toolbar">
2247
+ <label for="searchBox" class="searchboxlabel">Search:</label> <input type="text" id="searchBox" onclick="toggleSearchEnabled(true)" onkeyup="scheduleSearch()" size="20" />
2248
+ <input type="button" id="searchReset" disabled="disabled" value="Reset" onclick="clearSearch()" class="button" title="Reset the search" />
2249
+ <input type="checkbox" id="searchRegex" onclick="doSearch()" title="If checked, search is treated as a regular expression" /><label for="searchRegex">Regex</label>
2250
+ <input type="checkbox" id="searchCaseSensitive" onclick="doSearch()" title="If checked, search is case sensitive" /><label for="searchCaseSensitive">Match case</label>
2251
+ <input type="checkbox" id="searchDisable" onclick="toggleSearchEnabled()" title="Enable/disable search" /><label for="searchDisable" class="alwaysenabled">Disable</label>
2252
+ <div id="searchNav">
2253
+ <input type="button" id="searchNext" disabled="disabled" value="Next" onclick="searchNext()" class="button" title="Go to the next matching log entry" />
2254
+ <input type="button" id="searchPrevious" disabled="disabled" value="Previous" onclick="searchPrevious()" class="button" title="Go to the previous matching log entry" />
2255
+ <input type="checkbox" id="searchFilter" onclick="toggleSearchFilter()" title="If checked, non-matching log entries are filtered out" /><label for="searchFilter">Filter</label>
2256
+ <input type="checkbox" id="searchHighlight" onclick="toggleSearchHighlight()" title="Highlight matched search terms" /><label for="searchHighlight" class="alwaysenabled">Highlight all</label>
2257
+ </div>
2258
+ </div>
2259
+ <div id="options" class="toolbar">
2260
+ Options:
2261
+ <input type="checkbox" id="enableLogging" onclick="toggleLoggingEnabled()" checked="checked" title="Enable/disable logging" /><label for="enableLogging" id="enableLoggingLabel">Log</label>
2262
+ <input type="checkbox" id="wrap" onclick="toggleWrap()" title="Enable / disable word wrap" /><label for="wrap" id="wrapLabel">Wrap</label>
2263
+ <input type="checkbox" id="newestAtTop" onclick="toggleNewestAtTop()" title="If checked, causes newest messages to appear at the top" /><label for="newestAtTop" id="newestAtTopLabel">Newest at the top</label>
2264
+ <input type="checkbox" id="scrollToLatest" onclick="toggleScrollToLatest()" checked="checked" title="If checked, window automatically scrolls to a new message when it is added" /><label for="scrollToLatest" id="scrollToLatestLabel">Scroll to latest</label>
2265
+ <input type="button" id="clearButton" value="Clear" onclick="clearLog()" class="button" title="Clear all log messages" />
2266
+ <input type="button" id="hideButton" value="Hide" onclick="hide()" class="hidden button" title="Hide the console" />
2267
+ <input type="button" id="closeButton" value="Close" onclick="closeWindow()" class="hidden button" title="Close the window" />
2268
+ </div>
2269
+ </div>
2270
+ </div>
2271
+ <div id="log" class="TRACE DEBUG INFO WARN ERROR FATAL"></div>
2272
+ <div id="commandLine" class="toolbar">
2273
+ <div id="commandLineContainer">
2274
+ <input type="text" id="command" title="Enter a JavaScript command here and hit return or press 'Evaluate'" />
2275
+ <input type="button" id="evaluateButton" value="Evaluate" class="button" title="Evaluate the command" onclick="evalCommandLine()" />
2276
+ </div>
2277
+ </div>
2278
+ </body>
2279
+ </html>