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,188 @@
1
+ /**
2
+ * Copyright 2013 Tim Down.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+
18
+ if(!Array.prototype.push){Array.prototype.push=function(){for(var i=0,len=arguments.length;i<len;i++){this[this.length]=arguments[i];}
19
+ return this.length;};}
20
+ 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];}
21
+ this.length=this.length-1;return firstItem;}};}
22
+ 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];}
23
+ 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]);}
24
+ return itemsDeleted;};}
25
+ var log4javascript=(function(){function isUndefined(obj){return typeof obj=="undefined";}
26
+ function EventSupport(){}
27
+ EventSupport.prototype={eventTypes:[],eventListeners:{},setEventTypes:function(eventTypesParam){if(eventTypesParam instanceof Array){this.eventTypes=eventTypesParam;this.eventListeners={};for(var i=0,len=this.eventTypes.length;i<len;i++){this.eventListeners[this.eventTypes[i]]=[];}}else{handleError("log4javascript.EventSupport ["+this+"]: setEventTypes: eventTypes parameter must be an Array");}},addEventListener:function(eventType,listener){if(typeof listener=="function"){if(!array_contains(this.eventTypes,eventType)){handleError("log4javascript.EventSupport ["+this+"]: addEventListener: no event called '"+eventType+"'");}
28
+ this.eventListeners[eventType].push(listener);}else{handleError("log4javascript.EventSupport ["+this+"]: addEventListener: listener must be a function");}},removeEventListener:function(eventType,listener){if(typeof listener=="function"){if(!array_contains(this.eventTypes,eventType)){handleError("log4javascript.EventSupport ["+this+"]: removeEventListener: no event called '"+eventType+"'");}
29
+ array_remove(this.eventListeners[eventType],listener);}else{handleError("log4javascript.EventSupport ["+this+"]: removeEventListener: listener must be a function");}},dispatchEvent:function(eventType,eventArgs){if(array_contains(this.eventTypes,eventType)){var listeners=this.eventListeners[eventType];for(var i=0,len=listeners.length;i<len;i++){listeners[i](this,eventType,eventArgs);}}else{handleError("log4javascript.EventSupport ["+this+"]: dispatchEvent: no event called '"+eventType+"'");}}};var applicationStartDate=new Date();var uniqueId="log4javascript_"+applicationStartDate.getTime()+"_"+
30
+ Math.floor(Math.random()*100000000);var emptyFunction=function(){};var newLine="\r\n";var pageLoaded=false;function Log4JavaScript(){}
31
+ Log4JavaScript.prototype=new EventSupport();log4javascript=new Log4JavaScript();log4javascript.version="1.4.6";log4javascript.edition="log4javascript_production";function toStr(obj){if(obj&&obj.toString){return obj.toString();}else{return String(obj);}}
32
+ function getExceptionMessage(ex){if(ex.message){return ex.message;}else if(ex.description){return ex.description;}else{return toStr(ex);}}
33
+ function getUrlFileName(url){var lastSlashIndex=Math.max(url.lastIndexOf("/"),url.lastIndexOf("\\"));return url.substr(lastSlashIndex+1);}
34
+ function getExceptionStringRep(ex){if(ex){var exStr="Exception: "+getExceptionMessage(ex);try{if(ex.lineNumber){exStr+=" on line number "+ex.lineNumber;}
35
+ if(ex.fileName){exStr+=" in file "+getUrlFileName(ex.fileName);}}catch(localEx){logLog.warn("Unable to obtain file and line information for error");}
36
+ if(showStackTraces&&ex.stack){exStr+=newLine+"Stack trace:"+newLine+ex.stack;}
37
+ return exStr;}
38
+ return null;}
39
+ function bool(obj){return Boolean(obj);}
40
+ function trim(str){return str.replace(/^\s+/,"").replace(/\s+$/,"");}
41
+ function splitIntoLines(text){var text2=text.replace(/\r\n/g,"\n").replace(/\r/g,"\n");return text2.split("\n");}
42
+ var urlEncode=(typeof window.encodeURIComponent!="undefined")?function(str){return encodeURIComponent(str);}:function(str){return escape(str).replace(/\+/g,"%2B").replace(/"/g,"%22").replace(/'/g,"%27").replace(/\//g,"%2F").replace(/=/g,"%3D");};var urlDecode=(typeof window.decodeURIComponent!="undefined")?function(str){return decodeURIComponent(str);}:function(str){return unescape(str).replace(/%2B/g,"+").replace(/%22/g,"\"").replace(/%27/g,"'").replace(/%2F/g,"/").replace(/%3D/g,"=");};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;}}
43
+ if(index>=0){arr.splice(index,1);return true;}else{return false;}}
44
+ function array_contains(arr,val){for(var i=0,len=arr.length;i<len;i++){if(arr[i]==val){return true;}}
45
+ return false;}
46
+ function extractBooleanFromParam(param,defaultValue){if(isUndefined(param)){return defaultValue;}else{return bool(param);}}
47
+ function extractStringFromParam(param,defaultValue){if(isUndefined(param)){return defaultValue;}else{return String(param);}}
48
+ function extractIntFromParam(param,defaultValue){if(isUndefined(param)){return defaultValue;}else{try{var value=parseInt(param,10);return isNaN(value)?defaultValue:value;}catch(ex){logLog.warn("Invalid int param "+param,ex);return defaultValue;}}}
49
+ function extractFunctionFromParam(param,defaultValue){if(typeof param=="function"){return param;}else{return defaultValue;}}
50
+ function isError(err){return(err instanceof Error);}
51
+ if(!Function.prototype.apply){Function.prototype.apply=function(obj,args){var methodName="__apply__";if(typeof obj[methodName]!="undefined"){methodName+=String(Math.random()).substr(2);}
52
+ obj[methodName]=this;var argsStrings=[];for(var i=0,len=args.length;i<len;i++){argsStrings[i]="args["+i+"]";}
53
+ var script="obj."+methodName+"("+argsStrings.join(",")+")";var returnValue=eval(script);delete obj[methodName];return returnValue;};}
54
+ if(!Function.prototype.call){Function.prototype.call=function(obj){var args=[];for(var i=1,len=arguments.length;i<len;i++){args[i-1]=arguments[i];}
55
+ return this.apply(obj,args);};}
56
+ function getListenersPropertyName(eventName){return"__log4javascript_listeners__"+eventName;}
57
+ function addEvent(node,eventName,listener,useCapture,win){win=win?win:window;if(node.addEventListener){node.addEventListener(eventName,listener,useCapture);}else if(node.attachEvent){node.attachEvent("on"+eventName,listener);}else{var propertyName=getListenersPropertyName(eventName);if(!node[propertyName]){node[propertyName]=[];node["on"+eventName]=function(evt){evt=getEvent(evt,win);var listenersPropertyName=getListenersPropertyName(eventName);var listeners=this[listenersPropertyName].concat([]);var currentListener;while((currentListener=listeners.shift())){currentListener.call(this,evt);}};}
58
+ node[propertyName].push(listener);}}
59
+ function removeEvent(node,eventName,listener,useCapture){if(node.removeEventListener){node.removeEventListener(eventName,listener,useCapture);}else if(node.detachEvent){node.detachEvent("on"+eventName,listener);}else{var propertyName=getListenersPropertyName(eventName);if(node[propertyName]){array_remove(node[propertyName],listener);}}}
60
+ function getEvent(evt,win){win=win?win:window;return evt?evt:win.event;}
61
+ function stopEventPropagation(evt){if(evt.stopPropagation){evt.stopPropagation();}else if(typeof evt.cancelBubble!="undefined"){evt.cancelBubble=true;}
62
+ evt.returnValue=false;}
63
+ var logLog={quietMode:false,debugMessages:[],setQuietMode:function(quietMode){this.quietMode=bool(quietMode);},numberOfErrors:0,alertAllErrors:false,setAlertAllErrors:function(alertAllErrors){this.alertAllErrors=alertAllErrors;},debug:function(message){this.debugMessages.push(message);},displayDebug:function(){alert(this.debugMessages.join(newLine));},warn:function(message,exception){},error:function(message,exception){if(++this.numberOfErrors==1||this.alertAllErrors){if(!this.quietMode){var alertMessage="log4javascript error: "+message;if(exception){alertMessage+=newLine+newLine+"Original error: "+getExceptionStringRep(exception);}
64
+ alert(alertMessage);}}}};log4javascript.logLog=logLog;log4javascript.setEventTypes(["load","error"]);function handleError(message,exception){logLog.error(message,exception);log4javascript.dispatchEvent("error",{"message":message,"exception":exception});}
65
+ log4javascript.handleError=handleError;var enabled=!((typeof log4javascript_disabled!="undefined")&&log4javascript_disabled);log4javascript.setEnabled=function(enable){enabled=bool(enable);};log4javascript.isEnabled=function(){return enabled;};var useTimeStampsInMilliseconds=true;log4javascript.setTimeStampsInMilliseconds=function(timeStampsInMilliseconds){useTimeStampsInMilliseconds=bool(timeStampsInMilliseconds);};log4javascript.isTimeStampsInMilliseconds=function(){return useTimeStampsInMilliseconds;};log4javascript.evalInScope=function(expr){return eval(expr);};var showStackTraces=false;log4javascript.setShowStackTraces=function(show){showStackTraces=bool(show);};var Level=function(level,name){this.level=level;this.name=name;};Level.prototype={toString:function(){return this.name;},equals:function(level){return this.level==level.level;},isGreaterOrEqual:function(level){return this.level>=level.level;}};Level.ALL=new Level(Number.MIN_VALUE,"ALL");Level.TRACE=new Level(10000,"TRACE");Level.DEBUG=new Level(20000,"DEBUG");Level.INFO=new Level(30000,"INFO");Level.WARN=new Level(40000,"WARN");Level.ERROR=new Level(50000,"ERROR");Level.FATAL=new Level(60000,"FATAL");Level.OFF=new Level(Number.MAX_VALUE,"OFF");log4javascript.Level=Level;function Timer(name,level){this.name=name;this.level=isUndefined(level)?Level.INFO:level;this.start=new Date();}
66
+ Timer.prototype.getElapsedTime=function(){return new Date().getTime()-this.start.getTime();};var anonymousLoggerName="[anonymous]";var defaultLoggerName="[default]";var nullLoggerName="[null]";var rootLoggerName="root";function Logger(name){this.name=name;this.parent=null;this.children=[];var appenders=[];var loggerLevel=null;var isRoot=(this.name===rootLoggerName);var isNull=(this.name===nullLoggerName);var appenderCache=null;var appenderCacheInvalidated=false;this.addChild=function(childLogger){this.children.push(childLogger);childLogger.parent=this;childLogger.invalidateAppenderCache();};var additive=true;this.getAdditivity=function(){return additive;};this.setAdditivity=function(additivity){var valueChanged=(additive!=additivity);additive=additivity;if(valueChanged){this.invalidateAppenderCache();}};this.addAppender=function(appender){if(isNull){handleError("Logger.addAppender: you may not add an appender to the null logger");}else{if(appender instanceof log4javascript.Appender){if(!array_contains(appenders,appender)){appenders.push(appender);appender.setAddedToLogger(this);this.invalidateAppenderCache();}}else{handleError("Logger.addAppender: appender supplied ('"+
67
+ toStr(appender)+"') is not a subclass of Appender");}}};this.removeAppender=function(appender){array_remove(appenders,appender);appender.setRemovedFromLogger(this);this.invalidateAppenderCache();};this.removeAllAppenders=function(){var appenderCount=appenders.length;if(appenderCount>0){for(var i=0;i<appenderCount;i++){appenders[i].setRemovedFromLogger(this);}
68
+ appenders.length=0;this.invalidateAppenderCache();}};this.getEffectiveAppenders=function(){if(appenderCache===null||appenderCacheInvalidated){var parentEffectiveAppenders=(isRoot||!this.getAdditivity())?[]:this.parent.getEffectiveAppenders();appenderCache=parentEffectiveAppenders.concat(appenders);appenderCacheInvalidated=false;}
69
+ return appenderCache;};this.invalidateAppenderCache=function(){appenderCacheInvalidated=true;for(var i=0,len=this.children.length;i<len;i++){this.children[i].invalidateAppenderCache();}};this.log=function(level,params){if(enabled&&level.isGreaterOrEqual(this.getEffectiveLevel())){var exception;var finalParamIndex=params.length-1;var lastParam=params[finalParamIndex];if(params.length>1&&isError(lastParam)){exception=lastParam;finalParamIndex--;}
70
+ var messages=[];for(var i=0;i<=finalParamIndex;i++){messages[i]=params[i];}
71
+ var loggingEvent=new LoggingEvent(this,new Date(),level,messages,exception);this.callAppenders(loggingEvent);}};this.callAppenders=function(loggingEvent){var effectiveAppenders=this.getEffectiveAppenders();for(var i=0,len=effectiveAppenders.length;i<len;i++){effectiveAppenders[i].doAppend(loggingEvent);}};this.setLevel=function(level){if(isRoot&&level===null){handleError("Logger.setLevel: you cannot set the level of the root logger to null");}else if(level instanceof Level){loggerLevel=level;}else{handleError("Logger.setLevel: level supplied to logger "+
72
+ this.name+" is not an instance of log4javascript.Level");}};this.getLevel=function(){return loggerLevel;};this.getEffectiveLevel=function(){for(var logger=this;logger!==null;logger=logger.parent){var level=logger.getLevel();if(level!==null){return level;}}};this.group=function(name,initiallyExpanded){if(enabled){var effectiveAppenders=this.getEffectiveAppenders();for(var i=0,len=effectiveAppenders.length;i<len;i++){effectiveAppenders[i].group(name,initiallyExpanded);}}};this.groupEnd=function(){if(enabled){var effectiveAppenders=this.getEffectiveAppenders();for(var i=0,len=effectiveAppenders.length;i<len;i++){effectiveAppenders[i].groupEnd();}}};var timers={};this.time=function(name,level){if(enabled){if(isUndefined(name)){handleError("Logger.time: a name for the timer must be supplied");}else if(level&&!(level instanceof Level)){handleError("Logger.time: level supplied to timer "+
73
+ name+" is not an instance of log4javascript.Level");}else{timers[name]=new Timer(name,level);}}};this.timeEnd=function(name){if(enabled){if(isUndefined(name)){handleError("Logger.timeEnd: a name for the timer must be supplied");}else if(timers[name]){var timer=timers[name];var milliseconds=timer.getElapsedTime();this.log(timer.level,["Timer "+toStr(name)+" completed in "+milliseconds+"ms"]);delete timers[name];}else{logLog.warn("Logger.timeEnd: no timer found with name "+name);}}};this.assert=function(expr){if(enabled&&!expr){var args=[];for(var i=1,len=arguments.length;i<len;i++){args.push(arguments[i]);}
74
+ args=(args.length>0)?args:["Assertion Failure"];args.push(newLine);args.push(expr);this.log(Level.ERROR,args);}};this.toString=function(){return"Logger["+this.name+"]";};}
75
+ Logger.prototype={trace:function(){this.log(Level.TRACE,arguments);},debug:function(){this.log(Level.DEBUG,arguments);},info:function(){this.log(Level.INFO,arguments);},warn:function(){this.log(Level.WARN,arguments);},error:function(){this.log(Level.ERROR,arguments);},fatal:function(){this.log(Level.FATAL,arguments);},isEnabledFor:function(level){return level.isGreaterOrEqual(this.getEffectiveLevel());},isTraceEnabled:function(){return this.isEnabledFor(Level.TRACE);},isDebugEnabled:function(){return this.isEnabledFor(Level.DEBUG);},isInfoEnabled:function(){return this.isEnabledFor(Level.INFO);},isWarnEnabled:function(){return this.isEnabledFor(Level.WARN);},isErrorEnabled:function(){return this.isEnabledFor(Level.ERROR);},isFatalEnabled:function(){return this.isEnabledFor(Level.FATAL);}};Logger.prototype.trace.isEntryPoint=true;Logger.prototype.debug.isEntryPoint=true;Logger.prototype.info.isEntryPoint=true;Logger.prototype.warn.isEntryPoint=true;Logger.prototype.error.isEntryPoint=true;Logger.prototype.fatal.isEntryPoint=true;var loggers={};var loggerNames=[];var ROOT_LOGGER_DEFAULT_LEVEL=Level.DEBUG;var rootLogger=new Logger(rootLoggerName);rootLogger.setLevel(ROOT_LOGGER_DEFAULT_LEVEL);log4javascript.getRootLogger=function(){return rootLogger;};log4javascript.getLogger=function(loggerName){if(!(typeof loggerName=="string")){loggerName=anonymousLoggerName;logLog.warn("log4javascript.getLogger: non-string logger name "+
76
+ toStr(loggerName)+" supplied, returning anonymous logger");}
77
+ if(loggerName==rootLoggerName){handleError("log4javascript.getLogger: root logger may not be obtained by name");}
78
+ if(!loggers[loggerName]){var logger=new Logger(loggerName);loggers[loggerName]=logger;loggerNames.push(loggerName);var lastDotIndex=loggerName.lastIndexOf(".");var parentLogger;if(lastDotIndex>-1){var parentLoggerName=loggerName.substring(0,lastDotIndex);parentLogger=log4javascript.getLogger(parentLoggerName);}else{parentLogger=rootLogger;}
79
+ parentLogger.addChild(logger);}
80
+ return loggers[loggerName];};var defaultLogger=null;log4javascript.getDefaultLogger=function(){if(!defaultLogger){defaultLogger=log4javascript.getLogger(defaultLoggerName);var a=new log4javascript.PopUpAppender();defaultLogger.addAppender(a);}
81
+ return defaultLogger;};var nullLogger=null;log4javascript.getNullLogger=function(){if(!nullLogger){nullLogger=new Logger(nullLoggerName);nullLogger.setLevel(Level.OFF);}
82
+ return nullLogger;};log4javascript.resetConfiguration=function(){rootLogger.setLevel(ROOT_LOGGER_DEFAULT_LEVEL);loggers={};};var LoggingEvent=function(logger,timeStamp,level,messages,exception){this.logger=logger;this.timeStamp=timeStamp;this.timeStampInMilliseconds=timeStamp.getTime();this.timeStampInSeconds=Math.floor(this.timeStampInMilliseconds/1000);this.milliseconds=this.timeStamp.getMilliseconds();this.level=level;this.messages=messages;this.exception=exception;};LoggingEvent.prototype={getThrowableStrRep:function(){return this.exception?getExceptionStringRep(this.exception):"";},getCombinedMessages:function(){return(this.messages.length==1)?this.messages[0]:this.messages.join(newLine);},toString:function(){return"LoggingEvent["+this.level+"]";}};log4javascript.LoggingEvent=LoggingEvent;var Layout=function(){};Layout.prototype={defaults:{loggerKey:"logger",timeStampKey:"timestamp",millisecondsKey:"milliseconds",levelKey:"level",messageKey:"message",exceptionKey:"exception",urlKey:"url"},loggerKey:"logger",timeStampKey:"timestamp",millisecondsKey:"milliseconds",levelKey:"level",messageKey:"message",exceptionKey:"exception",urlKey:"url",batchHeader:"",batchFooter:"",batchSeparator:"",returnsPostData:false,overrideTimeStampsSetting:false,useTimeStampsInMilliseconds:null,format:function(){handleError("Layout.format: layout supplied has no format() method");},ignoresThrowable:function(){handleError("Layout.ignoresThrowable: layout supplied has no ignoresThrowable() method");},getContentType:function(){return"text/plain";},allowBatching:function(){return true;},setTimeStampsInMilliseconds:function(timeStampsInMilliseconds){this.overrideTimeStampsSetting=true;this.useTimeStampsInMilliseconds=bool(timeStampsInMilliseconds);},isTimeStampsInMilliseconds:function(){return this.overrideTimeStampsSetting?this.useTimeStampsInMilliseconds:useTimeStampsInMilliseconds;},getTimeStampValue:function(loggingEvent){return this.isTimeStampsInMilliseconds()?loggingEvent.timeStampInMilliseconds:loggingEvent.timeStampInSeconds;},getDataValues:function(loggingEvent,combineMessages){var dataValues=[[this.loggerKey,loggingEvent.logger.name],[this.timeStampKey,this.getTimeStampValue(loggingEvent)],[this.levelKey,loggingEvent.level.name],[this.urlKey,window.location.href],[this.messageKey,combineMessages?loggingEvent.getCombinedMessages():loggingEvent.messages]];if(!this.isTimeStampsInMilliseconds()){dataValues.push([this.millisecondsKey,loggingEvent.milliseconds]);}
83
+ if(loggingEvent.exception){dataValues.push([this.exceptionKey,getExceptionStringRep(loggingEvent.exception)]);}
84
+ if(this.hasCustomFields()){for(var i=0,len=this.customFields.length;i<len;i++){var val=this.customFields[i].value;if(typeof val==="function"){val=val(this,loggingEvent);}
85
+ dataValues.push([this.customFields[i].name,val]);}}
86
+ return dataValues;},setKeys:function(loggerKey,timeStampKey,levelKey,messageKey,exceptionKey,urlKey,millisecondsKey){this.loggerKey=extractStringFromParam(loggerKey,this.defaults.loggerKey);this.timeStampKey=extractStringFromParam(timeStampKey,this.defaults.timeStampKey);this.levelKey=extractStringFromParam(levelKey,this.defaults.levelKey);this.messageKey=extractStringFromParam(messageKey,this.defaults.messageKey);this.exceptionKey=extractStringFromParam(exceptionKey,this.defaults.exceptionKey);this.urlKey=extractStringFromParam(urlKey,this.defaults.urlKey);this.millisecondsKey=extractStringFromParam(millisecondsKey,this.defaults.millisecondsKey);},setCustomField:function(name,value){var fieldUpdated=false;for(var i=0,len=this.customFields.length;i<len;i++){if(this.customFields[i].name===name){this.customFields[i].value=value;fieldUpdated=true;}}
87
+ if(!fieldUpdated){this.customFields.push({"name":name,"value":value});}},hasCustomFields:function(){return(this.customFields.length>0);},toString:function(){handleError("Layout.toString: all layouts must override this method");}};log4javascript.Layout=Layout;var Appender=function(){};Appender.prototype=new EventSupport();Appender.prototype.layout=new PatternLayout();Appender.prototype.threshold=Level.ALL;Appender.prototype.loggers=[];Appender.prototype.doAppend=function(loggingEvent){if(enabled&&loggingEvent.level.level>=this.threshold.level){this.append(loggingEvent);}};Appender.prototype.append=function(loggingEvent){};Appender.prototype.setLayout=function(layout){if(layout instanceof Layout){this.layout=layout;}else{handleError("Appender.setLayout: layout supplied to "+
88
+ this.toString()+" is not a subclass of Layout");}};Appender.prototype.getLayout=function(){return this.layout;};Appender.prototype.setThreshold=function(threshold){if(threshold instanceof Level){this.threshold=threshold;}else{handleError("Appender.setThreshold: threshold supplied to "+
89
+ this.toString()+" is not a subclass of Level");}};Appender.prototype.getThreshold=function(){return this.threshold;};Appender.prototype.setAddedToLogger=function(logger){this.loggers.push(logger);};Appender.prototype.setRemovedFromLogger=function(logger){array_remove(this.loggers,logger);};Appender.prototype.group=emptyFunction;Appender.prototype.groupEnd=emptyFunction;Appender.prototype.toString=function(){handleError("Appender.toString: all appenders must override this method");};log4javascript.Appender=Appender;function SimpleLayout(){this.customFields=[];}
90
+ SimpleLayout.prototype=new Layout();SimpleLayout.prototype.format=function(loggingEvent){return loggingEvent.level.name+" - "+loggingEvent.getCombinedMessages();};SimpleLayout.prototype.ignoresThrowable=function(){return true;};SimpleLayout.prototype.toString=function(){return"SimpleLayout";};log4javascript.SimpleLayout=SimpleLayout;function NullLayout(){this.customFields=[];}
91
+ NullLayout.prototype=new Layout();NullLayout.prototype.format=function(loggingEvent){return loggingEvent.messages;};NullLayout.prototype.ignoresThrowable=function(){return true;};NullLayout.prototype.toString=function(){return"NullLayout";};log4javascript.NullLayout=NullLayout;function XmlLayout(combineMessages){this.combineMessages=extractBooleanFromParam(combineMessages,true);this.customFields=[];}
92
+ XmlLayout.prototype=new Layout();XmlLayout.prototype.isCombinedMessages=function(){return this.combineMessages;};XmlLayout.prototype.getContentType=function(){return"text/xml";};XmlLayout.prototype.escapeCdata=function(str){return str.replace(/\]\]>/,"]]>]]&gt;<![CDATA[");};XmlLayout.prototype.format=function(loggingEvent){var layout=this;var i,len;function formatMessage(message){message=(typeof message==="string")?message:toStr(message);return"<log4javascript:message><![CDATA["+
93
+ layout.escapeCdata(message)+"]]></log4javascript:message>";}
94
+ var str="<log4javascript:event logger=\""+loggingEvent.logger.name+"\" timestamp=\""+this.getTimeStampValue(loggingEvent)+"\"";if(!this.isTimeStampsInMilliseconds()){str+=" milliseconds=\""+loggingEvent.milliseconds+"\"";}
95
+ str+=" level=\""+loggingEvent.level.name+"\">"+newLine;if(this.combineMessages){str+=formatMessage(loggingEvent.getCombinedMessages());}else{str+="<log4javascript:messages>"+newLine;for(i=0,len=loggingEvent.messages.length;i<len;i++){str+=formatMessage(loggingEvent.messages[i])+newLine;}
96
+ str+="</log4javascript:messages>"+newLine;}
97
+ if(this.hasCustomFields()){for(i=0,len=this.customFields.length;i<len;i++){str+="<log4javascript:customfield name=\""+
98
+ this.customFields[i].name+"\"><![CDATA["+
99
+ this.customFields[i].value.toString()+"]]></log4javascript:customfield>"+newLine;}}
100
+ if(loggingEvent.exception){str+="<log4javascript:exception><![CDATA["+
101
+ getExceptionStringRep(loggingEvent.exception)+"]]></log4javascript:exception>"+newLine;}
102
+ str+="</log4javascript:event>"+newLine+newLine;return str;};XmlLayout.prototype.ignoresThrowable=function(){return false;};XmlLayout.prototype.toString=function(){return"XmlLayout";};log4javascript.XmlLayout=XmlLayout;function escapeNewLines(str){return str.replace(/\r\n|\r|\n/g,"\\r\\n");}
103
+ function JsonLayout(readable,combineMessages){this.readable=extractBooleanFromParam(readable,false);this.combineMessages=extractBooleanFromParam(combineMessages,true);this.batchHeader=this.readable?"["+newLine:"[";this.batchFooter=this.readable?"]"+newLine:"]";this.batchSeparator=this.readable?","+newLine:",";this.setKeys();this.colon=this.readable?": ":":";this.tab=this.readable?"\t":"";this.lineBreak=this.readable?newLine:"";this.customFields=[];}
104
+ JsonLayout.prototype=new Layout();JsonLayout.prototype.isReadable=function(){return this.readable;};JsonLayout.prototype.isCombinedMessages=function(){return this.combineMessages;};JsonLayout.prototype.format=function(loggingEvent){var layout=this;var dataValues=this.getDataValues(loggingEvent,this.combineMessages);var str="{"+this.lineBreak;var i,len;function formatValue(val,prefix,expand){var formattedValue;var valType=typeof val;if(val instanceof Date){formattedValue=String(val.getTime());}else if(expand&&(val instanceof Array)){formattedValue="["+layout.lineBreak;for(var i=0,len=val.length;i<len;i++){var childPrefix=prefix+layout.tab;formattedValue+=childPrefix+formatValue(val[i],childPrefix,false);if(i<val.length-1){formattedValue+=",";}
105
+ formattedValue+=layout.lineBreak;}
106
+ formattedValue+=prefix+"]";}else if(valType!=="number"&&valType!=="boolean"){formattedValue="\""+escapeNewLines(toStr(val).replace(/\"/g,"\\\""))+"\"";}else{formattedValue=val;}
107
+ return formattedValue;}
108
+ for(i=0,len=dataValues.length-1;i<=len;i++){str+=this.tab+"\""+dataValues[i][0]+"\""+this.colon+formatValue(dataValues[i][1],this.tab,true);if(i<len){str+=",";}
109
+ str+=this.lineBreak;}
110
+ str+="}"+this.lineBreak;return str;};JsonLayout.prototype.ignoresThrowable=function(){return false;};JsonLayout.prototype.toString=function(){return"JsonLayout";};JsonLayout.prototype.getContentType=function(){return"application/json";};log4javascript.JsonLayout=JsonLayout;function HttpPostDataLayout(){this.setKeys();this.customFields=[];this.returnsPostData=true;}
111
+ HttpPostDataLayout.prototype=new Layout();HttpPostDataLayout.prototype.allowBatching=function(){return false;};HttpPostDataLayout.prototype.format=function(loggingEvent){var dataValues=this.getDataValues(loggingEvent);var queryBits=[];for(var i=0,len=dataValues.length;i<len;i++){var val=(dataValues[i][1]instanceof Date)?String(dataValues[i][1].getTime()):dataValues[i][1];queryBits.push(urlEncode(dataValues[i][0])+"="+urlEncode(val));}
112
+ return queryBits.join("&");};HttpPostDataLayout.prototype.ignoresThrowable=function(loggingEvent){return false;};HttpPostDataLayout.prototype.toString=function(){return"HttpPostDataLayout";};log4javascript.HttpPostDataLayout=HttpPostDataLayout;function formatObjectExpansion(obj,depth,indentation){var objectsExpanded=[];function doFormat(obj,depth,indentation){var i,j,len,childDepth,childIndentation,childLines,expansion,childExpansion;if(!indentation){indentation="";}
113
+ function formatString(text){var lines=splitIntoLines(text);for(var j=1,jLen=lines.length;j<jLen;j++){lines[j]=indentation+lines[j];}
114
+ return lines.join(newLine);}
115
+ if(obj===null){return"null";}else if(typeof obj=="undefined"){return"undefined";}else if(typeof obj=="string"){return formatString(obj);}else if(typeof obj=="object"&&array_contains(objectsExpanded,obj)){try{expansion=toStr(obj);}catch(ex){expansion="Error formatting property. Details: "+getExceptionStringRep(ex);}
116
+ return expansion+" [already expanded]";}else if((obj instanceof Array)&&depth>0){objectsExpanded.push(obj);expansion="["+newLine;childDepth=depth-1;childIndentation=indentation+" ";childLines=[];for(i=0,len=obj.length;i<len;i++){try{childExpansion=doFormat(obj[i],childDepth,childIndentation);childLines.push(childIndentation+childExpansion);}catch(ex){childLines.push(childIndentation+"Error formatting array member. Details: "+
117
+ getExceptionStringRep(ex)+"");}}
118
+ expansion+=childLines.join(","+newLine)+newLine+indentation+"]";return expansion;}else if(Object.prototype.toString.call(obj)=="[object Date]"){return obj.toString();}else if(typeof obj=="object"&&depth>0){objectsExpanded.push(obj);expansion="{"+newLine;childDepth=depth-1;childIndentation=indentation+" ";childLines=[];for(i in obj){try{childExpansion=doFormat(obj[i],childDepth,childIndentation);childLines.push(childIndentation+i+": "+childExpansion);}catch(ex){childLines.push(childIndentation+i+": Error formatting property. Details: "+
119
+ getExceptionStringRep(ex));}}
120
+ expansion+=childLines.join(","+newLine)+newLine+indentation+"}";return expansion;}else{return formatString(toStr(obj));}}
121
+ return doFormat(obj,depth,indentation);}
122
+ var SimpleDateFormat;(function(){var regex=/('[^']*')|(G+|y+|M+|w+|W+|D+|d+|F+|E+|a+|H+|k+|K+|h+|m+|s+|S+|Z+)|([a-zA-Z]+)|([^a-zA-Z']+)/;var monthNames=["January","February","March","April","May","June","July","August","September","October","November","December"];var dayNames=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var TEXT2=0,TEXT3=1,NUMBER=2,YEAR=3,MONTH=4,TIMEZONE=5;var types={G:TEXT2,y:YEAR,M:MONTH,w:NUMBER,W:NUMBER,D:NUMBER,d:NUMBER,F:NUMBER,E:TEXT3,a:TEXT2,H:NUMBER,k:NUMBER,K:NUMBER,h:NUMBER,m:NUMBER,s:NUMBER,S:NUMBER,Z:TIMEZONE};var ONE_DAY=24*60*60*1000;var ONE_WEEK=7*ONE_DAY;var DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK=1;var newDateAtMidnight=function(year,month,day){var d=new Date(year,month,day,0,0,0);d.setMilliseconds(0);return d;};Date.prototype.getDifference=function(date){return this.getTime()-date.getTime();};Date.prototype.isBefore=function(d){return this.getTime()<d.getTime();};Date.prototype.getUTCTime=function(){return Date.UTC(this.getFullYear(),this.getMonth(),this.getDate(),this.getHours(),this.getMinutes(),this.getSeconds(),this.getMilliseconds());};Date.prototype.getTimeSince=function(d){return this.getUTCTime()-d.getUTCTime();};Date.prototype.getPreviousSunday=function(){var midday=new Date(this.getFullYear(),this.getMonth(),this.getDate(),12,0,0);var previousSunday=new Date(midday.getTime()-this.getDay()*ONE_DAY);return newDateAtMidnight(previousSunday.getFullYear(),previousSunday.getMonth(),previousSunday.getDate());};Date.prototype.getWeekInYear=function(minimalDaysInFirstWeek){if(isUndefined(this.minimalDaysInFirstWeek)){minimalDaysInFirstWeek=DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK;}
123
+ var previousSunday=this.getPreviousSunday();var startOfYear=newDateAtMidnight(this.getFullYear(),0,1);var numberOfSundays=previousSunday.isBefore(startOfYear)?0:1+Math.floor(previousSunday.getTimeSince(startOfYear)/ONE_WEEK);var numberOfDaysInFirstWeek=7-startOfYear.getDay();var weekInYear=numberOfSundays;if(numberOfDaysInFirstWeek<minimalDaysInFirstWeek){weekInYear--;}
124
+ return weekInYear;};Date.prototype.getWeekInMonth=function(minimalDaysInFirstWeek){if(isUndefined(this.minimalDaysInFirstWeek)){minimalDaysInFirstWeek=DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK;}
125
+ var previousSunday=this.getPreviousSunday();var startOfMonth=newDateAtMidnight(this.getFullYear(),this.getMonth(),1);var numberOfSundays=previousSunday.isBefore(startOfMonth)?0:1+Math.floor(previousSunday.getTimeSince(startOfMonth)/ONE_WEEK);var numberOfDaysInFirstWeek=7-startOfMonth.getDay();var weekInMonth=numberOfSundays;if(numberOfDaysInFirstWeek>=minimalDaysInFirstWeek){weekInMonth++;}
126
+ return weekInMonth;};Date.prototype.getDayInYear=function(){var startOfYear=newDateAtMidnight(this.getFullYear(),0,1);return 1+Math.floor(this.getTimeSince(startOfYear)/ONE_DAY);};SimpleDateFormat=function(formatString){this.formatString=formatString;};SimpleDateFormat.prototype.setMinimalDaysInFirstWeek=function(days){this.minimalDaysInFirstWeek=days;};SimpleDateFormat.prototype.getMinimalDaysInFirstWeek=function(){return isUndefined(this.minimalDaysInFirstWeek)?DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK:this.minimalDaysInFirstWeek;};var padWithZeroes=function(str,len){while(str.length<len){str="0"+str;}
127
+ return str;};var formatText=function(data,numberOfLetters,minLength){return(numberOfLetters>=4)?data:data.substr(0,Math.max(minLength,numberOfLetters));};var formatNumber=function(data,numberOfLetters){var dataString=""+data;return padWithZeroes(dataString,numberOfLetters);};SimpleDateFormat.prototype.format=function(date){var formattedString="";var result;var searchString=this.formatString;while((result=regex.exec(searchString))){var quotedString=result[1];var patternLetters=result[2];var otherLetters=result[3];var otherCharacters=result[4];if(quotedString){if(quotedString=="''"){formattedString+="'";}else{formattedString+=quotedString.substring(1,quotedString.length-1);}}else if(otherLetters){}else if(otherCharacters){formattedString+=otherCharacters;}else if(patternLetters){var patternLetter=patternLetters.charAt(0);var numberOfLetters=patternLetters.length;var rawData="";switch(patternLetter){case"G":rawData="AD";break;case"y":rawData=date.getFullYear();break;case"M":rawData=date.getMonth();break;case"w":rawData=date.getWeekInYear(this.getMinimalDaysInFirstWeek());break;case"W":rawData=date.getWeekInMonth(this.getMinimalDaysInFirstWeek());break;case"D":rawData=date.getDayInYear();break;case"d":rawData=date.getDate();break;case"F":rawData=1+Math.floor((date.getDate()-1)/7);break;case"E":rawData=dayNames[date.getDay()];break;case"a":rawData=(date.getHours()>=12)?"PM":"AM";break;case"H":rawData=date.getHours();break;case"k":rawData=date.getHours()||24;break;case"K":rawData=date.getHours()%12;break;case"h":rawData=(date.getHours()%12)||12;break;case"m":rawData=date.getMinutes();break;case"s":rawData=date.getSeconds();break;case"S":rawData=date.getMilliseconds();break;case"Z":rawData=date.getTimezoneOffset();break;}
128
+ switch(types[patternLetter]){case TEXT2:formattedString+=formatText(rawData,numberOfLetters,2);break;case TEXT3:formattedString+=formatText(rawData,numberOfLetters,3);break;case NUMBER:formattedString+=formatNumber(rawData,numberOfLetters);break;case YEAR:if(numberOfLetters<=3){var dataString=""+rawData;formattedString+=dataString.substr(2,2);}else{formattedString+=formatNumber(rawData,numberOfLetters);}
129
+ break;case MONTH:if(numberOfLetters>=3){formattedString+=formatText(monthNames[rawData],numberOfLetters,numberOfLetters);}else{formattedString+=formatNumber(rawData+1,numberOfLetters);}
130
+ break;case TIMEZONE:var isPositive=(rawData>0);var prefix=isPositive?"-":"+";var absData=Math.abs(rawData);var hours=""+Math.floor(absData/60);hours=padWithZeroes(hours,2);var minutes=""+(absData%60);minutes=padWithZeroes(minutes,2);formattedString+=prefix+hours+minutes;break;}}
131
+ searchString=searchString.substr(result.index+result[0].length);}
132
+ return formattedString;};})();log4javascript.SimpleDateFormat=SimpleDateFormat;function PatternLayout(pattern){if(pattern){this.pattern=pattern;}else{this.pattern=PatternLayout.DEFAULT_CONVERSION_PATTERN;}
133
+ this.customFields=[];}
134
+ PatternLayout.TTCC_CONVERSION_PATTERN="%r %p %c - %m%n";PatternLayout.DEFAULT_CONVERSION_PATTERN="%m%n";PatternLayout.ISO8601_DATEFORMAT="yyyy-MM-dd HH:mm:ss,SSS";PatternLayout.DATETIME_DATEFORMAT="dd MMM yyyy HH:mm:ss,SSS";PatternLayout.ABSOLUTETIME_DATEFORMAT="HH:mm:ss,SSS";PatternLayout.prototype=new Layout();PatternLayout.prototype.format=function(loggingEvent){var regex=/%(-?[0-9]+)?(\.?[0-9]+)?([acdfmMnpr%])(\{([^\}]+)\})?|([^%]+)/;var formattedString="";var result;var searchString=this.pattern;while((result=regex.exec(searchString))){var matchedString=result[0];var padding=result[1];var truncation=result[2];var conversionCharacter=result[3];var specifier=result[5];var text=result[6];if(text){formattedString+=""+text;}else{var replacement="";switch(conversionCharacter){case"a":case"m":var depth=0;if(specifier){depth=parseInt(specifier,10);if(isNaN(depth)){handleError("PatternLayout.format: invalid specifier '"+
135
+ specifier+"' for conversion character '"+conversionCharacter+"' - should be a number");depth=0;}}
136
+ var messages=(conversionCharacter==="a")?loggingEvent.messages[0]:loggingEvent.messages;for(var i=0,len=messages.length;i<len;i++){if(i>0&&(replacement.charAt(replacement.length-1)!==" ")){replacement+=" ";}
137
+ if(depth===0){replacement+=messages[i];}else{replacement+=formatObjectExpansion(messages[i],depth);}}
138
+ break;case"c":var loggerName=loggingEvent.logger.name;if(specifier){var precision=parseInt(specifier,10);var loggerNameBits=loggingEvent.logger.name.split(".");if(precision>=loggerNameBits.length){replacement=loggerName;}else{replacement=loggerNameBits.slice(loggerNameBits.length-precision).join(".");}}else{replacement=loggerName;}
139
+ break;case"d":var dateFormat=PatternLayout.ISO8601_DATEFORMAT;if(specifier){dateFormat=specifier;if(dateFormat=="ISO8601"){dateFormat=PatternLayout.ISO8601_DATEFORMAT;}else if(dateFormat=="ABSOLUTE"){dateFormat=PatternLayout.ABSOLUTETIME_DATEFORMAT;}else if(dateFormat=="DATE"){dateFormat=PatternLayout.DATETIME_DATEFORMAT;}}
140
+ replacement=(new SimpleDateFormat(dateFormat)).format(loggingEvent.timeStamp);break;case"f":if(this.hasCustomFields()){var fieldIndex=0;if(specifier){fieldIndex=parseInt(specifier,10);if(isNaN(fieldIndex)){handleError("PatternLayout.format: invalid specifier '"+
141
+ specifier+"' for conversion character 'f' - should be a number");}else if(fieldIndex===0){handleError("PatternLayout.format: invalid specifier '"+
142
+ specifier+"' for conversion character 'f' - must be greater than zero");}else if(fieldIndex>this.customFields.length){handleError("PatternLayout.format: invalid specifier '"+
143
+ specifier+"' for conversion character 'f' - there aren't that many custom fields");}else{fieldIndex=fieldIndex-1;}}
144
+ var val=this.customFields[fieldIndex].value;if(typeof val=="function"){val=val(this,loggingEvent);}
145
+ replacement=val;}
146
+ break;case"n":replacement=newLine;break;case"p":replacement=loggingEvent.level.name;break;case"r":replacement=""+loggingEvent.timeStamp.getDifference(applicationStartDate);break;case"%":replacement="%";break;default:replacement=matchedString;break;}
147
+ var l;if(truncation){l=parseInt(truncation.substr(1),10);var strLen=replacement.length;if(l<strLen){replacement=replacement.substring(strLen-l,strLen);}}
148
+ if(padding){if(padding.charAt(0)=="-"){l=parseInt(padding.substr(1),10);while(replacement.length<l){replacement+=" ";}}else{l=parseInt(padding,10);while(replacement.length<l){replacement=" "+replacement;}}}
149
+ formattedString+=replacement;}
150
+ searchString=searchString.substr(result.index+result[0].length);}
151
+ return formattedString;};PatternLayout.prototype.ignoresThrowable=function(){return true;};PatternLayout.prototype.toString=function(){return"PatternLayout";};log4javascript.PatternLayout=PatternLayout;var xmlHttpFactories=[function(){return new XMLHttpRequest();},function(){return new ActiveXObject("Msxml2.XMLHTTP");},function(){return new ActiveXObject("Microsoft.XMLHTTP");}];var getXmlHttp=function(errorHandler){var xmlHttp=null,factory;for(var i=0,len=xmlHttpFactories.length;i<len;i++){factory=xmlHttpFactories[i];try{xmlHttp=factory();getXmlHttp=factory;return xmlHttp;}catch(e){}}
152
+ if(errorHandler){errorHandler();}else{handleError("getXmlHttp: unable to obtain XMLHttpRequest object");}};function isHttpRequestSuccessful(xmlHttp){return isUndefined(xmlHttp.status)||xmlHttp.status===0||(xmlHttp.status>=200&&xmlHttp.status<300)||xmlHttp.status==1223;}
153
+ function AjaxAppender(url){var appender=this;var isSupported=true;if(!url){handleError("AjaxAppender: URL must be specified in constructor");isSupported=false;}
154
+ var timed=this.defaults.timed;var waitForResponse=this.defaults.waitForResponse;var batchSize=this.defaults.batchSize;var timerInterval=this.defaults.timerInterval;var requestSuccessCallback=this.defaults.requestSuccessCallback;var failCallback=this.defaults.failCallback;var postVarName=this.defaults.postVarName;var sendAllOnUnload=this.defaults.sendAllOnUnload;var contentType=this.defaults.contentType;var sessionId=null;var queuedLoggingEvents=[];var queuedRequests=[];var headers=[];var sending=false;var initialized=false;function checkCanConfigure(configOptionName){if(initialized){handleError("AjaxAppender: configuration option '"+
155
+ configOptionName+"' may not be set after the appender has been initialized");return false;}
156
+ return true;}
157
+ this.getSessionId=function(){return sessionId;};this.setSessionId=function(sessionIdParam){sessionId=extractStringFromParam(sessionIdParam,null);this.layout.setCustomField("sessionid",sessionId);};this.setLayout=function(layoutParam){if(checkCanConfigure("layout")){this.layout=layoutParam;if(sessionId!==null){this.setSessionId(sessionId);}}};this.isTimed=function(){return timed;};this.setTimed=function(timedParam){if(checkCanConfigure("timed")){timed=bool(timedParam);}};this.getTimerInterval=function(){return timerInterval;};this.setTimerInterval=function(timerIntervalParam){if(checkCanConfigure("timerInterval")){timerInterval=extractIntFromParam(timerIntervalParam,timerInterval);}};this.isWaitForResponse=function(){return waitForResponse;};this.setWaitForResponse=function(waitForResponseParam){if(checkCanConfigure("waitForResponse")){waitForResponse=bool(waitForResponseParam);}};this.getBatchSize=function(){return batchSize;};this.setBatchSize=function(batchSizeParam){if(checkCanConfigure("batchSize")){batchSize=extractIntFromParam(batchSizeParam,batchSize);}};this.isSendAllOnUnload=function(){return sendAllOnUnload;};this.setSendAllOnUnload=function(sendAllOnUnloadParam){if(checkCanConfigure("sendAllOnUnload")){sendAllOnUnload=extractBooleanFromParam(sendAllOnUnloadParam,sendAllOnUnload);}};this.setRequestSuccessCallback=function(requestSuccessCallbackParam){requestSuccessCallback=extractFunctionFromParam(requestSuccessCallbackParam,requestSuccessCallback);};this.setFailCallback=function(failCallbackParam){failCallback=extractFunctionFromParam(failCallbackParam,failCallback);};this.getPostVarName=function(){return postVarName;};this.setPostVarName=function(postVarNameParam){if(checkCanConfigure("postVarName")){postVarName=extractStringFromParam(postVarNameParam,postVarName);}};this.getHeaders=function(){return headers;};this.addHeader=function(name,value){if(name.toLowerCase()=="content-type"){contentType=value;}else{headers.push({name:name,value:value});}};function sendAll(){if(isSupported&&enabled){sending=true;var currentRequestBatch;if(waitForResponse){if(queuedRequests.length>0){currentRequestBatch=queuedRequests.shift();sendRequest(preparePostData(currentRequestBatch),sendAll);}else{sending=false;if(timed){scheduleSending();}}}else{while((currentRequestBatch=queuedRequests.shift())){sendRequest(preparePostData(currentRequestBatch));}
158
+ sending=false;if(timed){scheduleSending();}}}}
159
+ this.sendAll=sendAll;function sendAllRemaining(){var sendingAnything=false;if(isSupported&&enabled){var actualBatchSize=appender.getLayout().allowBatching()?batchSize:1;var currentLoggingEvent;var batchedLoggingEvents=[];while((currentLoggingEvent=queuedLoggingEvents.shift())){batchedLoggingEvents.push(currentLoggingEvent);if(queuedLoggingEvents.length>=actualBatchSize){queuedRequests.push(batchedLoggingEvents);batchedLoggingEvents=[];}}
160
+ if(batchedLoggingEvents.length>0){queuedRequests.push(batchedLoggingEvents);}
161
+ sendingAnything=(queuedRequests.length>0);waitForResponse=false;timed=false;sendAll();}
162
+ return sendingAnything;}
163
+ this.sendAllRemaining=sendAllRemaining;function preparePostData(batchedLoggingEvents){var formattedMessages=[];var currentLoggingEvent;var postData="";while((currentLoggingEvent=batchedLoggingEvents.shift())){var currentFormattedMessage=appender.getLayout().format(currentLoggingEvent);if(appender.getLayout().ignoresThrowable()){currentFormattedMessage+=currentLoggingEvent.getThrowableStrRep();}
164
+ formattedMessages.push(currentFormattedMessage);}
165
+ if(batchedLoggingEvents.length==1){postData=formattedMessages.join("");}else{postData=appender.getLayout().batchHeader+
166
+ formattedMessages.join(appender.getLayout().batchSeparator)+
167
+ appender.getLayout().batchFooter;}
168
+ if(contentType==appender.defaults.contentType){postData=appender.getLayout().returnsPostData?postData:urlEncode(postVarName)+"="+urlEncode(postData);if(postData.length>0){postData+="&";}
169
+ postData+="layout="+urlEncode(appender.getLayout().toString());}
170
+ return postData;}
171
+ function scheduleSending(){window.setTimeout(sendAll,timerInterval);}
172
+ function xmlHttpErrorHandler(){var msg="AjaxAppender: could not create XMLHttpRequest object. AjaxAppender disabled";handleError(msg);isSupported=false;if(failCallback){failCallback(msg);}}
173
+ function sendRequest(postData,successCallback){try{var xmlHttp=getXmlHttp(xmlHttpErrorHandler);if(isSupported){if(xmlHttp.overrideMimeType){xmlHttp.overrideMimeType(appender.getLayout().getContentType());}
174
+ xmlHttp.onreadystatechange=function(){if(xmlHttp.readyState==4){if(isHttpRequestSuccessful(xmlHttp)){if(requestSuccessCallback){requestSuccessCallback(xmlHttp);}
175
+ if(successCallback){successCallback(xmlHttp);}}else{var msg="AjaxAppender.append: XMLHttpRequest request to URL "+
176
+ url+" returned status code "+xmlHttp.status;handleError(msg);if(failCallback){failCallback(msg);}}
177
+ xmlHttp.onreadystatechange=emptyFunction;xmlHttp=null;}};xmlHttp.open("POST",url,true);try{for(var i=0,header;header=headers[i++];){xmlHttp.setRequestHeader(header.name,header.value);}
178
+ xmlHttp.setRequestHeader("Content-Type",contentType);}catch(headerEx){var msg="AjaxAppender.append: your browser's XMLHttpRequest implementation"+" does not support setRequestHeader, therefore cannot post data. AjaxAppender disabled";handleError(msg);isSupported=false;if(failCallback){failCallback(msg);}
179
+ return;}
180
+ xmlHttp.send(postData);}}catch(ex){var errMsg="AjaxAppender.append: error sending log message to "+url;handleError(errMsg,ex);isSupported=false;if(failCallback){failCallback(errMsg+". Details: "+getExceptionStringRep(ex));}}}
181
+ this.append=function(loggingEvent){if(isSupported){if(!initialized){init();}
182
+ queuedLoggingEvents.push(loggingEvent);var actualBatchSize=this.getLayout().allowBatching()?batchSize:1;if(queuedLoggingEvents.length>=actualBatchSize){var currentLoggingEvent;var batchedLoggingEvents=[];while((currentLoggingEvent=queuedLoggingEvents.shift())){batchedLoggingEvents.push(currentLoggingEvent);}
183
+ queuedRequests.push(batchedLoggingEvents);if(!timed&&(!waitForResponse||(waitForResponse&&!sending))){sendAll();}}}};function init(){initialized=true;if(sendAllOnUnload){var oldBeforeUnload=window.onbeforeunload;window.onbeforeunload=function(){if(oldBeforeUnload){oldBeforeUnload();}
184
+ if(sendAllRemaining()){return"Sending log messages";}};}
185
+ if(timed){scheduleSending();}}}
186
+ AjaxAppender.prototype=new Appender();AjaxAppender.prototype.defaults={waitForResponse:false,timed:false,timerInterval:1000,batchSize:1,sendAllOnUnload:false,requestSuccessCallback:null,failCallback:null,postVarName:"data",contentType:"application/x-www-form-urlencoded"};AjaxAppender.prototype.layout=new HttpPostDataLayout();AjaxAppender.prototype.toString=function(){return"AjaxAppender";};log4javascript.AjaxAppender=AjaxAppender;log4javascript.setDocumentReady=function(){pageLoaded=true;log4javascript.dispatchEvent("load",{});};if(window.addEventListener){window.addEventListener("load",log4javascript.setDocumentReady,false);}else if(window.attachEvent){window.attachEvent("onload",log4javascript.setDocumentReady);}else{var oldOnload=window.onload;if(typeof window.onload!="function"){window.onload=log4javascript.setDocumentReady;}else{window.onload=function(evt){if(oldOnload){oldOnload(evt);}
187
+ log4javascript.setDocumentReady();};}}
188
+ window.log4javascript=log4javascript;return log4javascript;})();
@@ -0,0 +1,2290 @@
1
+ /**
2
+ * Copyright 2013 Tim Down.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * log4javascript
19
+ *
20
+ * log4javascript is a logging framework for JavaScript based on log4j
21
+ * for Java. This file contains all core log4javascript code and is the only
22
+ * file required to use log4javascript, unless you require support for
23
+ * document.domain, in which case you will also need console.html, which must be
24
+ * stored in the same directory as the main log4javascript.js file.
25
+ *
26
+ * Author: Tim Down <tim@log4javascript.org>
27
+ * Version: 1.4.6
28
+ * Edition: log4javascript_production
29
+ * Build date: 19 March 2013
30
+ * Website: http://log4javascript.org
31
+ */
32
+
33
+ /* -------------------------------------------------------------------------- */
34
+ // Array-related stuff
35
+
36
+ // Next three methods are solely for IE5, which is missing them
37
+ if (!Array.prototype.push) {
38
+ Array.prototype.push = function() {
39
+ for (var i = 0, len = arguments.length; i < len; i++){
40
+ this[this.length] = arguments[i];
41
+ }
42
+ return this.length;
43
+ };
44
+ }
45
+
46
+ if (!Array.prototype.shift) {
47
+ Array.prototype.shift = function() {
48
+ if (this.length > 0) {
49
+ var firstItem = this[0];
50
+ for (var i = 0, len = this.length - 1; i < len; i++) {
51
+ this[i] = this[i + 1];
52
+ }
53
+ this.length = this.length - 1;
54
+ return firstItem;
55
+ }
56
+ };
57
+ }
58
+
59
+ if (!Array.prototype.splice) {
60
+ Array.prototype.splice = function(startIndex, deleteCount) {
61
+ var itemsAfterDeleted = this.slice(startIndex + deleteCount);
62
+ var itemsDeleted = this.slice(startIndex, startIndex + deleteCount);
63
+ this.length = startIndex;
64
+ // Copy the arguments into a proper Array object
65
+ var argumentsArray = [];
66
+ for (var i = 0, len = arguments.length; i < len; i++) {
67
+ argumentsArray[i] = arguments[i];
68
+ }
69
+ var itemsToAppend = (argumentsArray.length > 2) ?
70
+ itemsAfterDeleted = argumentsArray.slice(2).concat(itemsAfterDeleted) : itemsAfterDeleted;
71
+ for (i = 0, len = itemsToAppend.length; i < len; i++) {
72
+ this.push(itemsToAppend[i]);
73
+ }
74
+ return itemsDeleted;
75
+ };
76
+ }
77
+
78
+ /* -------------------------------------------------------------------------- */
79
+
80
+ var log4javascript = (function() {
81
+
82
+ function isUndefined(obj) {
83
+ return typeof obj == "undefined";
84
+ }
85
+
86
+ /* ---------------------------------------------------------------------- */
87
+ // Custom event support
88
+
89
+ function EventSupport() {}
90
+
91
+ EventSupport.prototype = {
92
+ eventTypes: [],
93
+ eventListeners: {},
94
+ setEventTypes: function(eventTypesParam) {
95
+ if (eventTypesParam instanceof Array) {
96
+ this.eventTypes = eventTypesParam;
97
+ this.eventListeners = {};
98
+ for (var i = 0, len = this.eventTypes.length; i < len; i++) {
99
+ this.eventListeners[this.eventTypes[i]] = [];
100
+ }
101
+ } else {
102
+ handleError("log4javascript.EventSupport [" + this + "]: setEventTypes: eventTypes parameter must be an Array");
103
+ }
104
+ },
105
+
106
+ addEventListener: function(eventType, listener) {
107
+ if (typeof listener == "function") {
108
+ if (!array_contains(this.eventTypes, eventType)) {
109
+ handleError("log4javascript.EventSupport [" + this + "]: addEventListener: no event called '" + eventType + "'");
110
+ }
111
+ this.eventListeners[eventType].push(listener);
112
+ } else {
113
+ handleError("log4javascript.EventSupport [" + this + "]: addEventListener: listener must be a function");
114
+ }
115
+ },
116
+
117
+ removeEventListener: function(eventType, listener) {
118
+ if (typeof listener == "function") {
119
+ if (!array_contains(this.eventTypes, eventType)) {
120
+ handleError("log4javascript.EventSupport [" + this + "]: removeEventListener: no event called '" + eventType + "'");
121
+ }
122
+ array_remove(this.eventListeners[eventType], listener);
123
+ } else {
124
+ handleError("log4javascript.EventSupport [" + this + "]: removeEventListener: listener must be a function");
125
+ }
126
+ },
127
+
128
+ dispatchEvent: function(eventType, eventArgs) {
129
+ if (array_contains(this.eventTypes, eventType)) {
130
+ var listeners = this.eventListeners[eventType];
131
+ for (var i = 0, len = listeners.length; i < len; i++) {
132
+ listeners[i](this, eventType, eventArgs);
133
+ }
134
+ } else {
135
+ handleError("log4javascript.EventSupport [" + this + "]: dispatchEvent: no event called '" + eventType + "'");
136
+ }
137
+ }
138
+ };
139
+
140
+ /* -------------------------------------------------------------------------- */
141
+
142
+ var applicationStartDate = new Date();
143
+ var uniqueId = "log4javascript_" + applicationStartDate.getTime() + "_" +
144
+ Math.floor(Math.random() * 100000000);
145
+ var emptyFunction = function() {};
146
+ var newLine = "\r\n";
147
+ var pageLoaded = false;
148
+
149
+ // Create main log4javascript object; this will be assigned public properties
150
+ function Log4JavaScript() {}
151
+ Log4JavaScript.prototype = new EventSupport();
152
+
153
+ log4javascript = new Log4JavaScript();
154
+ log4javascript.version = "1.4.6";
155
+ log4javascript.edition = "log4javascript_production";
156
+
157
+ /* -------------------------------------------------------------------------- */
158
+ // Utility functions
159
+
160
+ function toStr(obj) {
161
+ if (obj && obj.toString) {
162
+ return obj.toString();
163
+ } else {
164
+ return String(obj);
165
+ }
166
+ }
167
+
168
+ function getExceptionMessage(ex) {
169
+ if (ex.message) {
170
+ return ex.message;
171
+ } else if (ex.description) {
172
+ return ex.description;
173
+ } else {
174
+ return toStr(ex);
175
+ }
176
+ }
177
+
178
+ // Gets the portion of the URL after the last slash
179
+ function getUrlFileName(url) {
180
+ var lastSlashIndex = Math.max(url.lastIndexOf("/"), url.lastIndexOf("\\"));
181
+ return url.substr(lastSlashIndex + 1);
182
+ }
183
+
184
+ // Returns a nicely formatted representation of an error
185
+ function getExceptionStringRep(ex) {
186
+ if (ex) {
187
+ var exStr = "Exception: " + getExceptionMessage(ex);
188
+ try {
189
+ if (ex.lineNumber) {
190
+ exStr += " on line number " + ex.lineNumber;
191
+ }
192
+ if (ex.fileName) {
193
+ exStr += " in file " + getUrlFileName(ex.fileName);
194
+ }
195
+ } catch (localEx) {
196
+ logLog.warn("Unable to obtain file and line information for error");
197
+ }
198
+ if (showStackTraces && ex.stack) {
199
+ exStr += newLine + "Stack trace:" + newLine + ex.stack;
200
+ }
201
+ return exStr;
202
+ }
203
+ return null;
204
+ }
205
+
206
+ function bool(obj) {
207
+ return Boolean(obj);
208
+ }
209
+
210
+ function trim(str) {
211
+ return str.replace(/^\s+/, "").replace(/\s+$/, "");
212
+ }
213
+
214
+ function splitIntoLines(text) {
215
+ // Ensure all line breaks are \n only
216
+ var text2 = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
217
+ return text2.split("\n");
218
+ }
219
+
220
+ var urlEncode = (typeof window.encodeURIComponent != "undefined") ?
221
+ function(str) {
222
+ return encodeURIComponent(str);
223
+ }:
224
+ function(str) {
225
+ return escape(str).replace(/\+/g, "%2B").replace(/"/g, "%22").replace(/'/g, "%27").replace(/\//g, "%2F").replace(/=/g, "%3D");
226
+ };
227
+
228
+ var urlDecode = (typeof window.decodeURIComponent != "undefined") ?
229
+ function(str) {
230
+ return decodeURIComponent(str);
231
+ }:
232
+ function(str) {
233
+ return unescape(str).replace(/%2B/g, "+").replace(/%22/g, "\"").replace(/%27/g, "'").replace(/%2F/g, "/").replace(/%3D/g, "=");
234
+ };
235
+
236
+ function array_remove(arr, val) {
237
+ var index = -1;
238
+ for (var i = 0, len = arr.length; i < len; i++) {
239
+ if (arr[i] === val) {
240
+ index = i;
241
+ break;
242
+ }
243
+ }
244
+ if (index >= 0) {
245
+ arr.splice(index, 1);
246
+ return true;
247
+ } else {
248
+ return false;
249
+ }
250
+ }
251
+
252
+ function array_contains(arr, val) {
253
+ for(var i = 0, len = arr.length; i < len; i++) {
254
+ if (arr[i] == val) {
255
+ return true;
256
+ }
257
+ }
258
+ return false;
259
+ }
260
+
261
+ function extractBooleanFromParam(param, defaultValue) {
262
+ if (isUndefined(param)) {
263
+ return defaultValue;
264
+ } else {
265
+ return bool(param);
266
+ }
267
+ }
268
+
269
+ function extractStringFromParam(param, defaultValue) {
270
+ if (isUndefined(param)) {
271
+ return defaultValue;
272
+ } else {
273
+ return String(param);
274
+ }
275
+ }
276
+
277
+ function extractIntFromParam(param, defaultValue) {
278
+ if (isUndefined(param)) {
279
+ return defaultValue;
280
+ } else {
281
+ try {
282
+ var value = parseInt(param, 10);
283
+ return isNaN(value) ? defaultValue : value;
284
+ } catch (ex) {
285
+ logLog.warn("Invalid int param " + param, ex);
286
+ return defaultValue;
287
+ }
288
+ }
289
+ }
290
+
291
+ function extractFunctionFromParam(param, defaultValue) {
292
+ if (typeof param == "function") {
293
+ return param;
294
+ } else {
295
+ return defaultValue;
296
+ }
297
+ }
298
+
299
+ function isError(err) {
300
+ return (err instanceof Error);
301
+ }
302
+
303
+ if (!Function.prototype.apply){
304
+ Function.prototype.apply = function(obj, args) {
305
+ var methodName = "__apply__";
306
+ if (typeof obj[methodName] != "undefined") {
307
+ methodName += String(Math.random()).substr(2);
308
+ }
309
+ obj[methodName] = this;
310
+
311
+ var argsStrings = [];
312
+ for (var i = 0, len = args.length; i < len; i++) {
313
+ argsStrings[i] = "args[" + i + "]";
314
+ }
315
+ var script = "obj." + methodName + "(" + argsStrings.join(",") + ")";
316
+ var returnValue = eval(script);
317
+ delete obj[methodName];
318
+ return returnValue;
319
+ };
320
+ }
321
+
322
+ if (!Function.prototype.call){
323
+ Function.prototype.call = function(obj) {
324
+ var args = [];
325
+ for (var i = 1, len = arguments.length; i < len; i++) {
326
+ args[i - 1] = arguments[i];
327
+ }
328
+ return this.apply(obj, args);
329
+ };
330
+ }
331
+
332
+ function getListenersPropertyName(eventName) {
333
+ return "__log4javascript_listeners__" + eventName;
334
+ }
335
+
336
+ function addEvent(node, eventName, listener, useCapture, win) {
337
+ win = win ? win : window;
338
+ if (node.addEventListener) {
339
+ node.addEventListener(eventName, listener, useCapture);
340
+ } else if (node.attachEvent) {
341
+ node.attachEvent("on" + eventName, listener);
342
+ } else {
343
+ var propertyName = getListenersPropertyName(eventName);
344
+ if (!node[propertyName]) {
345
+ node[propertyName] = [];
346
+ // Set event handler
347
+ node["on" + eventName] = function(evt) {
348
+ evt = getEvent(evt, win);
349
+ var listenersPropertyName = getListenersPropertyName(eventName);
350
+
351
+ // Clone the array of listeners to leave the original untouched
352
+ var listeners = this[listenersPropertyName].concat([]);
353
+ var currentListener;
354
+
355
+ // Call each listener in turn
356
+ while ((currentListener = listeners.shift())) {
357
+ currentListener.call(this, evt);
358
+ }
359
+ };
360
+ }
361
+ node[propertyName].push(listener);
362
+ }
363
+ }
364
+
365
+ function removeEvent(node, eventName, listener, useCapture) {
366
+ if (node.removeEventListener) {
367
+ node.removeEventListener(eventName, listener, useCapture);
368
+ } else if (node.detachEvent) {
369
+ node.detachEvent("on" + eventName, listener);
370
+ } else {
371
+ var propertyName = getListenersPropertyName(eventName);
372
+ if (node[propertyName]) {
373
+ array_remove(node[propertyName], listener);
374
+ }
375
+ }
376
+ }
377
+
378
+ function getEvent(evt, win) {
379
+ win = win ? win : window;
380
+ return evt ? evt : win.event;
381
+ }
382
+
383
+ function stopEventPropagation(evt) {
384
+ if (evt.stopPropagation) {
385
+ evt.stopPropagation();
386
+ } else if (typeof evt.cancelBubble != "undefined") {
387
+ evt.cancelBubble = true;
388
+ }
389
+ evt.returnValue = false;
390
+ }
391
+
392
+ /* ---------------------------------------------------------------------- */
393
+ // Simple logging for log4javascript itself
394
+
395
+ var logLog = {
396
+ quietMode: false,
397
+
398
+ debugMessages: [],
399
+
400
+ setQuietMode: function(quietMode) {
401
+ this.quietMode = bool(quietMode);
402
+ },
403
+
404
+ numberOfErrors: 0,
405
+
406
+ alertAllErrors: false,
407
+
408
+ setAlertAllErrors: function(alertAllErrors) {
409
+ this.alertAllErrors = alertAllErrors;
410
+ },
411
+
412
+ debug: function(message) {
413
+ this.debugMessages.push(message);
414
+ },
415
+
416
+ displayDebug: function() {
417
+ alert(this.debugMessages.join(newLine));
418
+ },
419
+
420
+ warn: function(message, exception) {
421
+ },
422
+
423
+ error: function(message, exception) {
424
+ if (++this.numberOfErrors == 1 || this.alertAllErrors) {
425
+ if (!this.quietMode) {
426
+ var alertMessage = "log4javascript error: " + message;
427
+ if (exception) {
428
+ alertMessage += newLine + newLine + "Original error: " + getExceptionStringRep(exception);
429
+ }
430
+ alert(alertMessage);
431
+ }
432
+ }
433
+ }
434
+ };
435
+ log4javascript.logLog = logLog;
436
+
437
+ log4javascript.setEventTypes(["load", "error"]);
438
+
439
+ function handleError(message, exception) {
440
+ logLog.error(message, exception);
441
+ log4javascript.dispatchEvent("error", { "message": message, "exception": exception });
442
+ }
443
+
444
+ log4javascript.handleError = handleError;
445
+
446
+ /* ---------------------------------------------------------------------- */
447
+
448
+ var enabled = !((typeof log4javascript_disabled != "undefined") &&
449
+ log4javascript_disabled);
450
+
451
+ log4javascript.setEnabled = function(enable) {
452
+ enabled = bool(enable);
453
+ };
454
+
455
+ log4javascript.isEnabled = function() {
456
+ return enabled;
457
+ };
458
+
459
+ var useTimeStampsInMilliseconds = true;
460
+
461
+ log4javascript.setTimeStampsInMilliseconds = function(timeStampsInMilliseconds) {
462
+ useTimeStampsInMilliseconds = bool(timeStampsInMilliseconds);
463
+ };
464
+
465
+ log4javascript.isTimeStampsInMilliseconds = function() {
466
+ return useTimeStampsInMilliseconds;
467
+ };
468
+
469
+
470
+ // This evaluates the given expression in the current scope, thus allowing
471
+ // scripts to access private variables. Particularly useful for testing
472
+ log4javascript.evalInScope = function(expr) {
473
+ return eval(expr);
474
+ };
475
+
476
+ var showStackTraces = false;
477
+
478
+ log4javascript.setShowStackTraces = function(show) {
479
+ showStackTraces = bool(show);
480
+ };
481
+
482
+ /* ---------------------------------------------------------------------- */
483
+ // Levels
484
+
485
+ var Level = function(level, name) {
486
+ this.level = level;
487
+ this.name = name;
488
+ };
489
+
490
+ Level.prototype = {
491
+ toString: function() {
492
+ return this.name;
493
+ },
494
+ equals: function(level) {
495
+ return this.level == level.level;
496
+ },
497
+ isGreaterOrEqual: function(level) {
498
+ return this.level >= level.level;
499
+ }
500
+ };
501
+
502
+ Level.ALL = new Level(Number.MIN_VALUE, "ALL");
503
+ Level.TRACE = new Level(10000, "TRACE");
504
+ Level.DEBUG = new Level(20000, "DEBUG");
505
+ Level.INFO = new Level(30000, "INFO");
506
+ Level.WARN = new Level(40000, "WARN");
507
+ Level.ERROR = new Level(50000, "ERROR");
508
+ Level.FATAL = new Level(60000, "FATAL");
509
+ Level.OFF = new Level(Number.MAX_VALUE, "OFF");
510
+
511
+ log4javascript.Level = Level;
512
+
513
+ /* ---------------------------------------------------------------------- */
514
+ // Timers
515
+
516
+ function Timer(name, level) {
517
+ this.name = name;
518
+ this.level = isUndefined(level) ? Level.INFO : level;
519
+ this.start = new Date();
520
+ }
521
+
522
+ Timer.prototype.getElapsedTime = function() {
523
+ return new Date().getTime() - this.start.getTime();
524
+ };
525
+
526
+ /* ---------------------------------------------------------------------- */
527
+ // Loggers
528
+
529
+ var anonymousLoggerName = "[anonymous]";
530
+ var defaultLoggerName = "[default]";
531
+ var nullLoggerName = "[null]";
532
+ var rootLoggerName = "root";
533
+
534
+ function Logger(name) {
535
+ this.name = name;
536
+ this.parent = null;
537
+ this.children = [];
538
+
539
+ var appenders = [];
540
+ var loggerLevel = null;
541
+ var isRoot = (this.name === rootLoggerName);
542
+ var isNull = (this.name === nullLoggerName);
543
+
544
+ var appenderCache = null;
545
+ var appenderCacheInvalidated = false;
546
+
547
+ this.addChild = function(childLogger) {
548
+ this.children.push(childLogger);
549
+ childLogger.parent = this;
550
+ childLogger.invalidateAppenderCache();
551
+ };
552
+
553
+ // Additivity
554
+ var additive = true;
555
+ this.getAdditivity = function() {
556
+ return additive;
557
+ };
558
+
559
+ this.setAdditivity = function(additivity) {
560
+ var valueChanged = (additive != additivity);
561
+ additive = additivity;
562
+ if (valueChanged) {
563
+ this.invalidateAppenderCache();
564
+ }
565
+ };
566
+
567
+ // Create methods that use the appenders variable in this scope
568
+ this.addAppender = function(appender) {
569
+ if (isNull) {
570
+ handleError("Logger.addAppender: you may not add an appender to the null logger");
571
+ } else {
572
+ if (appender instanceof log4javascript.Appender) {
573
+ if (!array_contains(appenders, appender)) {
574
+ appenders.push(appender);
575
+ appender.setAddedToLogger(this);
576
+ this.invalidateAppenderCache();
577
+ }
578
+ } else {
579
+ handleError("Logger.addAppender: appender supplied ('" +
580
+ toStr(appender) + "') is not a subclass of Appender");
581
+ }
582
+ }
583
+ };
584
+
585
+ this.removeAppender = function(appender) {
586
+ array_remove(appenders, appender);
587
+ appender.setRemovedFromLogger(this);
588
+ this.invalidateAppenderCache();
589
+ };
590
+
591
+ this.removeAllAppenders = function() {
592
+ var appenderCount = appenders.length;
593
+ if (appenderCount > 0) {
594
+ for (var i = 0; i < appenderCount; i++) {
595
+ appenders[i].setRemovedFromLogger(this);
596
+ }
597
+ appenders.length = 0;
598
+ this.invalidateAppenderCache();
599
+ }
600
+ };
601
+
602
+ this.getEffectiveAppenders = function() {
603
+ if (appenderCache === null || appenderCacheInvalidated) {
604
+ // Build appender cache
605
+ var parentEffectiveAppenders = (isRoot || !this.getAdditivity()) ?
606
+ [] : this.parent.getEffectiveAppenders();
607
+ appenderCache = parentEffectiveAppenders.concat(appenders);
608
+ appenderCacheInvalidated = false;
609
+ }
610
+ return appenderCache;
611
+ };
612
+
613
+ this.invalidateAppenderCache = function() {
614
+ appenderCacheInvalidated = true;
615
+ for (var i = 0, len = this.children.length; i < len; i++) {
616
+ this.children[i].invalidateAppenderCache();
617
+ }
618
+ };
619
+
620
+ this.log = function(level, params) {
621
+ if (enabled && level.isGreaterOrEqual(this.getEffectiveLevel())) {
622
+ // Check whether last param is an exception
623
+ var exception;
624
+ var finalParamIndex = params.length - 1;
625
+ var lastParam = params[finalParamIndex];
626
+ if (params.length > 1 && isError(lastParam)) {
627
+ exception = lastParam;
628
+ finalParamIndex--;
629
+ }
630
+
631
+ // Construct genuine array for the params
632
+ var messages = [];
633
+ for (var i = 0; i <= finalParamIndex; i++) {
634
+ messages[i] = params[i];
635
+ }
636
+
637
+ var loggingEvent = new LoggingEvent(
638
+ this, new Date(), level, messages, exception);
639
+
640
+ this.callAppenders(loggingEvent);
641
+ }
642
+ };
643
+
644
+ this.callAppenders = function(loggingEvent) {
645
+ var effectiveAppenders = this.getEffectiveAppenders();
646
+ for (var i = 0, len = effectiveAppenders.length; i < len; i++) {
647
+ effectiveAppenders[i].doAppend(loggingEvent);
648
+ }
649
+ };
650
+
651
+ this.setLevel = function(level) {
652
+ // Having a level of null on the root logger would be very bad.
653
+ if (isRoot && level === null) {
654
+ handleError("Logger.setLevel: you cannot set the level of the root logger to null");
655
+ } else if (level instanceof Level) {
656
+ loggerLevel = level;
657
+ } else {
658
+ handleError("Logger.setLevel: level supplied to logger " +
659
+ this.name + " is not an instance of log4javascript.Level");
660
+ }
661
+ };
662
+
663
+ this.getLevel = function() {
664
+ return loggerLevel;
665
+ };
666
+
667
+ this.getEffectiveLevel = function() {
668
+ for (var logger = this; logger !== null; logger = logger.parent) {
669
+ var level = logger.getLevel();
670
+ if (level !== null) {
671
+ return level;
672
+ }
673
+ }
674
+ };
675
+
676
+ this.group = function(name, initiallyExpanded) {
677
+ if (enabled) {
678
+ var effectiveAppenders = this.getEffectiveAppenders();
679
+ for (var i = 0, len = effectiveAppenders.length; i < len; i++) {
680
+ effectiveAppenders[i].group(name, initiallyExpanded);
681
+ }
682
+ }
683
+ };
684
+
685
+ this.groupEnd = function() {
686
+ if (enabled) {
687
+ var effectiveAppenders = this.getEffectiveAppenders();
688
+ for (var i = 0, len = effectiveAppenders.length; i < len; i++) {
689
+ effectiveAppenders[i].groupEnd();
690
+ }
691
+ }
692
+ };
693
+
694
+ var timers = {};
695
+
696
+ this.time = function(name, level) {
697
+ if (enabled) {
698
+ if (isUndefined(name)) {
699
+ handleError("Logger.time: a name for the timer must be supplied");
700
+ } else if (level && !(level instanceof Level)) {
701
+ handleError("Logger.time: level supplied to timer " +
702
+ name + " is not an instance of log4javascript.Level");
703
+ } else {
704
+ timers[name] = new Timer(name, level);
705
+ }
706
+ }
707
+ };
708
+
709
+ this.timeEnd = function(name) {
710
+ if (enabled) {
711
+ if (isUndefined(name)) {
712
+ handleError("Logger.timeEnd: a name for the timer must be supplied");
713
+ } else if (timers[name]) {
714
+ var timer = timers[name];
715
+ var milliseconds = timer.getElapsedTime();
716
+ this.log(timer.level, ["Timer " + toStr(name) + " completed in " + milliseconds + "ms"]);
717
+ delete timers[name];
718
+ } else {
719
+ logLog.warn("Logger.timeEnd: no timer found with name " + name);
720
+ }
721
+ }
722
+ };
723
+
724
+ this.assert = function(expr) {
725
+ if (enabled && !expr) {
726
+ var args = [];
727
+ for (var i = 1, len = arguments.length; i < len; i++) {
728
+ args.push(arguments[i]);
729
+ }
730
+ args = (args.length > 0) ? args : ["Assertion Failure"];
731
+ args.push(newLine);
732
+ args.push(expr);
733
+ this.log(Level.ERROR, args);
734
+ }
735
+ };
736
+
737
+ this.toString = function() {
738
+ return "Logger[" + this.name + "]";
739
+ };
740
+ }
741
+
742
+ Logger.prototype = {
743
+ trace: function() {
744
+ this.log(Level.TRACE, arguments);
745
+ },
746
+
747
+ debug: function() {
748
+ this.log(Level.DEBUG, arguments);
749
+ },
750
+
751
+ info: function() {
752
+ this.log(Level.INFO, arguments);
753
+ },
754
+
755
+ warn: function() {
756
+ this.log(Level.WARN, arguments);
757
+ },
758
+
759
+ error: function() {
760
+ this.log(Level.ERROR, arguments);
761
+ },
762
+
763
+ fatal: function() {
764
+ this.log(Level.FATAL, arguments);
765
+ },
766
+
767
+ isEnabledFor: function(level) {
768
+ return level.isGreaterOrEqual(this.getEffectiveLevel());
769
+ },
770
+
771
+ isTraceEnabled: function() {
772
+ return this.isEnabledFor(Level.TRACE);
773
+ },
774
+
775
+ isDebugEnabled: function() {
776
+ return this.isEnabledFor(Level.DEBUG);
777
+ },
778
+
779
+ isInfoEnabled: function() {
780
+ return this.isEnabledFor(Level.INFO);
781
+ },
782
+
783
+ isWarnEnabled: function() {
784
+ return this.isEnabledFor(Level.WARN);
785
+ },
786
+
787
+ isErrorEnabled: function() {
788
+ return this.isEnabledFor(Level.ERROR);
789
+ },
790
+
791
+ isFatalEnabled: function() {
792
+ return this.isEnabledFor(Level.FATAL);
793
+ }
794
+ };
795
+
796
+ Logger.prototype.trace.isEntryPoint = true;
797
+ Logger.prototype.debug.isEntryPoint = true;
798
+ Logger.prototype.info.isEntryPoint = true;
799
+ Logger.prototype.warn.isEntryPoint = true;
800
+ Logger.prototype.error.isEntryPoint = true;
801
+ Logger.prototype.fatal.isEntryPoint = true;
802
+
803
+ /* ---------------------------------------------------------------------- */
804
+ // Logger access methods
805
+
806
+ // Hashtable of loggers keyed by logger name
807
+ var loggers = {};
808
+ var loggerNames = [];
809
+
810
+ var ROOT_LOGGER_DEFAULT_LEVEL = Level.DEBUG;
811
+ var rootLogger = new Logger(rootLoggerName);
812
+ rootLogger.setLevel(ROOT_LOGGER_DEFAULT_LEVEL);
813
+
814
+ log4javascript.getRootLogger = function() {
815
+ return rootLogger;
816
+ };
817
+
818
+ log4javascript.getLogger = function(loggerName) {
819
+ // Use default logger if loggerName is not specified or invalid
820
+ if (!(typeof loggerName == "string")) {
821
+ loggerName = anonymousLoggerName;
822
+ logLog.warn("log4javascript.getLogger: non-string logger name " +
823
+ toStr(loggerName) + " supplied, returning anonymous logger");
824
+ }
825
+
826
+ // Do not allow retrieval of the root logger by name
827
+ if (loggerName == rootLoggerName) {
828
+ handleError("log4javascript.getLogger: root logger may not be obtained by name");
829
+ }
830
+
831
+ // Create the logger for this name if it doesn't already exist
832
+ if (!loggers[loggerName]) {
833
+ var logger = new Logger(loggerName);
834
+ loggers[loggerName] = logger;
835
+ loggerNames.push(loggerName);
836
+
837
+ // Set up parent logger, if it doesn't exist
838
+ var lastDotIndex = loggerName.lastIndexOf(".");
839
+ var parentLogger;
840
+ if (lastDotIndex > -1) {
841
+ var parentLoggerName = loggerName.substring(0, lastDotIndex);
842
+ parentLogger = log4javascript.getLogger(parentLoggerName); // Recursively sets up grandparents etc.
843
+ } else {
844
+ parentLogger = rootLogger;
845
+ }
846
+ parentLogger.addChild(logger);
847
+ }
848
+ return loggers[loggerName];
849
+ };
850
+
851
+ var defaultLogger = null;
852
+ log4javascript.getDefaultLogger = function() {
853
+ if (!defaultLogger) {
854
+ defaultLogger = log4javascript.getLogger(defaultLoggerName);
855
+ var a = new log4javascript.PopUpAppender();
856
+ defaultLogger.addAppender(a);
857
+ }
858
+ return defaultLogger;
859
+ };
860
+
861
+ var nullLogger = null;
862
+ log4javascript.getNullLogger = function() {
863
+ if (!nullLogger) {
864
+ nullLogger = new Logger(nullLoggerName);
865
+ nullLogger.setLevel(Level.OFF);
866
+ }
867
+ return nullLogger;
868
+ };
869
+
870
+ // Destroys all loggers
871
+ log4javascript.resetConfiguration = function() {
872
+ rootLogger.setLevel(ROOT_LOGGER_DEFAULT_LEVEL);
873
+ loggers = {};
874
+ };
875
+
876
+ /* ---------------------------------------------------------------------- */
877
+ // Logging events
878
+
879
+ var LoggingEvent = function(logger, timeStamp, level, messages,
880
+ exception) {
881
+ this.logger = logger;
882
+ this.timeStamp = timeStamp;
883
+ this.timeStampInMilliseconds = timeStamp.getTime();
884
+ this.timeStampInSeconds = Math.floor(this.timeStampInMilliseconds / 1000);
885
+ this.milliseconds = this.timeStamp.getMilliseconds();
886
+ this.level = level;
887
+ this.messages = messages;
888
+ this.exception = exception;
889
+ };
890
+
891
+ LoggingEvent.prototype = {
892
+ getThrowableStrRep: function() {
893
+ return this.exception ?
894
+ getExceptionStringRep(this.exception) : "";
895
+ },
896
+ getCombinedMessages: function() {
897
+ return (this.messages.length == 1) ? this.messages[0] :
898
+ this.messages.join(newLine);
899
+ },
900
+ toString: function() {
901
+ return "LoggingEvent[" + this.level + "]";
902
+ }
903
+ };
904
+
905
+ log4javascript.LoggingEvent = LoggingEvent;
906
+
907
+ /* ---------------------------------------------------------------------- */
908
+ // Layout prototype
909
+
910
+ var Layout = function() {
911
+ };
912
+
913
+ Layout.prototype = {
914
+ defaults: {
915
+ loggerKey: "logger",
916
+ timeStampKey: "timestamp",
917
+ millisecondsKey: "milliseconds",
918
+ levelKey: "level",
919
+ messageKey: "message",
920
+ exceptionKey: "exception",
921
+ urlKey: "url"
922
+ },
923
+ loggerKey: "logger",
924
+ timeStampKey: "timestamp",
925
+ millisecondsKey: "milliseconds",
926
+ levelKey: "level",
927
+ messageKey: "message",
928
+ exceptionKey: "exception",
929
+ urlKey: "url",
930
+ batchHeader: "",
931
+ batchFooter: "",
932
+ batchSeparator: "",
933
+ returnsPostData: false,
934
+ overrideTimeStampsSetting: false,
935
+ useTimeStampsInMilliseconds: null,
936
+
937
+ format: function() {
938
+ handleError("Layout.format: layout supplied has no format() method");
939
+ },
940
+
941
+ ignoresThrowable: function() {
942
+ handleError("Layout.ignoresThrowable: layout supplied has no ignoresThrowable() method");
943
+ },
944
+
945
+ getContentType: function() {
946
+ return "text/plain";
947
+ },
948
+
949
+ allowBatching: function() {
950
+ return true;
951
+ },
952
+
953
+ setTimeStampsInMilliseconds: function(timeStampsInMilliseconds) {
954
+ this.overrideTimeStampsSetting = true;
955
+ this.useTimeStampsInMilliseconds = bool(timeStampsInMilliseconds);
956
+ },
957
+
958
+ isTimeStampsInMilliseconds: function() {
959
+ return this.overrideTimeStampsSetting ?
960
+ this.useTimeStampsInMilliseconds : useTimeStampsInMilliseconds;
961
+ },
962
+
963
+ getTimeStampValue: function(loggingEvent) {
964
+ return this.isTimeStampsInMilliseconds() ?
965
+ loggingEvent.timeStampInMilliseconds : loggingEvent.timeStampInSeconds;
966
+ },
967
+
968
+ getDataValues: function(loggingEvent, combineMessages) {
969
+ var dataValues = [
970
+ [this.loggerKey, loggingEvent.logger.name],
971
+ [this.timeStampKey, this.getTimeStampValue(loggingEvent)],
972
+ [this.levelKey, loggingEvent.level.name],
973
+ [this.urlKey, window.location.href],
974
+ [this.messageKey, combineMessages ? loggingEvent.getCombinedMessages() : loggingEvent.messages]
975
+ ];
976
+ if (!this.isTimeStampsInMilliseconds()) {
977
+ dataValues.push([this.millisecondsKey, loggingEvent.milliseconds]);
978
+ }
979
+ if (loggingEvent.exception) {
980
+ dataValues.push([this.exceptionKey, getExceptionStringRep(loggingEvent.exception)]);
981
+ }
982
+ if (this.hasCustomFields()) {
983
+ for (var i = 0, len = this.customFields.length; i < len; i++) {
984
+ var val = this.customFields[i].value;
985
+
986
+ // Check if the value is a function. If so, execute it, passing it the
987
+ // current layout and the logging event
988
+ if (typeof val === "function") {
989
+ val = val(this, loggingEvent);
990
+ }
991
+ dataValues.push([this.customFields[i].name, val]);
992
+ }
993
+ }
994
+ return dataValues;
995
+ },
996
+
997
+ setKeys: function(loggerKey, timeStampKey, levelKey, messageKey,
998
+ exceptionKey, urlKey, millisecondsKey) {
999
+ this.loggerKey = extractStringFromParam(loggerKey, this.defaults.loggerKey);
1000
+ this.timeStampKey = extractStringFromParam(timeStampKey, this.defaults.timeStampKey);
1001
+ this.levelKey = extractStringFromParam(levelKey, this.defaults.levelKey);
1002
+ this.messageKey = extractStringFromParam(messageKey, this.defaults.messageKey);
1003
+ this.exceptionKey = extractStringFromParam(exceptionKey, this.defaults.exceptionKey);
1004
+ this.urlKey = extractStringFromParam(urlKey, this.defaults.urlKey);
1005
+ this.millisecondsKey = extractStringFromParam(millisecondsKey, this.defaults.millisecondsKey);
1006
+ },
1007
+
1008
+ setCustomField: function(name, value) {
1009
+ var fieldUpdated = false;
1010
+ for (var i = 0, len = this.customFields.length; i < len; i++) {
1011
+ if (this.customFields[i].name === name) {
1012
+ this.customFields[i].value = value;
1013
+ fieldUpdated = true;
1014
+ }
1015
+ }
1016
+ if (!fieldUpdated) {
1017
+ this.customFields.push({"name": name, "value": value});
1018
+ }
1019
+ },
1020
+
1021
+ hasCustomFields: function() {
1022
+ return (this.customFields.length > 0);
1023
+ },
1024
+
1025
+ toString: function() {
1026
+ handleError("Layout.toString: all layouts must override this method");
1027
+ }
1028
+ };
1029
+
1030
+ log4javascript.Layout = Layout;
1031
+
1032
+ /* ---------------------------------------------------------------------- */
1033
+ // Appender prototype
1034
+
1035
+ var Appender = function() {};
1036
+
1037
+ Appender.prototype = new EventSupport();
1038
+
1039
+ Appender.prototype.layout = new PatternLayout();
1040
+ Appender.prototype.threshold = Level.ALL;
1041
+ Appender.prototype.loggers = [];
1042
+
1043
+ // Performs threshold checks before delegating actual logging to the
1044
+ // subclass's specific append method.
1045
+ Appender.prototype.doAppend = function(loggingEvent) {
1046
+ if (enabled && loggingEvent.level.level >= this.threshold.level) {
1047
+ this.append(loggingEvent);
1048
+ }
1049
+ };
1050
+
1051
+ Appender.prototype.append = function(loggingEvent) {};
1052
+
1053
+ Appender.prototype.setLayout = function(layout) {
1054
+ if (layout instanceof Layout) {
1055
+ this.layout = layout;
1056
+ } else {
1057
+ handleError("Appender.setLayout: layout supplied to " +
1058
+ this.toString() + " is not a subclass of Layout");
1059
+ }
1060
+ };
1061
+
1062
+ Appender.prototype.getLayout = function() {
1063
+ return this.layout;
1064
+ };
1065
+
1066
+ Appender.prototype.setThreshold = function(threshold) {
1067
+ if (threshold instanceof Level) {
1068
+ this.threshold = threshold;
1069
+ } else {
1070
+ handleError("Appender.setThreshold: threshold supplied to " +
1071
+ this.toString() + " is not a subclass of Level");
1072
+ }
1073
+ };
1074
+
1075
+ Appender.prototype.getThreshold = function() {
1076
+ return this.threshold;
1077
+ };
1078
+
1079
+ Appender.prototype.setAddedToLogger = function(logger) {
1080
+ this.loggers.push(logger);
1081
+ };
1082
+
1083
+ Appender.prototype.setRemovedFromLogger = function(logger) {
1084
+ array_remove(this.loggers, logger);
1085
+ };
1086
+
1087
+ Appender.prototype.group = emptyFunction;
1088
+ Appender.prototype.groupEnd = emptyFunction;
1089
+
1090
+ Appender.prototype.toString = function() {
1091
+ handleError("Appender.toString: all appenders must override this method");
1092
+ };
1093
+
1094
+ log4javascript.Appender = Appender;
1095
+
1096
+ /* ---------------------------------------------------------------------- */
1097
+ // SimpleLayout
1098
+
1099
+ function SimpleLayout() {
1100
+ this.customFields = [];
1101
+ }
1102
+
1103
+ SimpleLayout.prototype = new Layout();
1104
+
1105
+ SimpleLayout.prototype.format = function(loggingEvent) {
1106
+ return loggingEvent.level.name + " - " + loggingEvent.getCombinedMessages();
1107
+ };
1108
+
1109
+ SimpleLayout.prototype.ignoresThrowable = function() {
1110
+ return true;
1111
+ };
1112
+
1113
+ SimpleLayout.prototype.toString = function() {
1114
+ return "SimpleLayout";
1115
+ };
1116
+
1117
+ log4javascript.SimpleLayout = SimpleLayout;
1118
+ /* ----------------------------------------------------------------------- */
1119
+ // NullLayout
1120
+
1121
+ function NullLayout() {
1122
+ this.customFields = [];
1123
+ }
1124
+
1125
+ NullLayout.prototype = new Layout();
1126
+
1127
+ NullLayout.prototype.format = function(loggingEvent) {
1128
+ return loggingEvent.messages;
1129
+ };
1130
+
1131
+ NullLayout.prototype.ignoresThrowable = function() {
1132
+ return true;
1133
+ };
1134
+
1135
+ NullLayout.prototype.toString = function() {
1136
+ return "NullLayout";
1137
+ };
1138
+
1139
+ log4javascript.NullLayout = NullLayout;
1140
+ /* ---------------------------------------------------------------------- */
1141
+ // XmlLayout
1142
+
1143
+ function XmlLayout(combineMessages) {
1144
+ this.combineMessages = extractBooleanFromParam(combineMessages, true);
1145
+ this.customFields = [];
1146
+ }
1147
+
1148
+ XmlLayout.prototype = new Layout();
1149
+
1150
+ XmlLayout.prototype.isCombinedMessages = function() {
1151
+ return this.combineMessages;
1152
+ };
1153
+
1154
+ XmlLayout.prototype.getContentType = function() {
1155
+ return "text/xml";
1156
+ };
1157
+
1158
+ XmlLayout.prototype.escapeCdata = function(str) {
1159
+ return str.replace(/\]\]>/, "]]>]]&gt;<![CDATA[");
1160
+ };
1161
+
1162
+ XmlLayout.prototype.format = function(loggingEvent) {
1163
+ var layout = this;
1164
+ var i, len;
1165
+ function formatMessage(message) {
1166
+ message = (typeof message === "string") ? message : toStr(message);
1167
+ return "<log4javascript:message><![CDATA[" +
1168
+ layout.escapeCdata(message) + "]]></log4javascript:message>";
1169
+ }
1170
+
1171
+ var str = "<log4javascript:event logger=\"" + loggingEvent.logger.name +
1172
+ "\" timestamp=\"" + this.getTimeStampValue(loggingEvent) + "\"";
1173
+ if (!this.isTimeStampsInMilliseconds()) {
1174
+ str += " milliseconds=\"" + loggingEvent.milliseconds + "\"";
1175
+ }
1176
+ str += " level=\"" + loggingEvent.level.name + "\">" + newLine;
1177
+ if (this.combineMessages) {
1178
+ str += formatMessage(loggingEvent.getCombinedMessages());
1179
+ } else {
1180
+ str += "<log4javascript:messages>" + newLine;
1181
+ for (i = 0, len = loggingEvent.messages.length; i < len; i++) {
1182
+ str += formatMessage(loggingEvent.messages[i]) + newLine;
1183
+ }
1184
+ str += "</log4javascript:messages>" + newLine;
1185
+ }
1186
+ if (this.hasCustomFields()) {
1187
+ for (i = 0, len = this.customFields.length; i < len; i++) {
1188
+ str += "<log4javascript:customfield name=\"" +
1189
+ this.customFields[i].name + "\"><![CDATA[" +
1190
+ this.customFields[i].value.toString() +
1191
+ "]]></log4javascript:customfield>" + newLine;
1192
+ }
1193
+ }
1194
+ if (loggingEvent.exception) {
1195
+ str += "<log4javascript:exception><![CDATA[" +
1196
+ getExceptionStringRep(loggingEvent.exception) +
1197
+ "]]></log4javascript:exception>" + newLine;
1198
+ }
1199
+ str += "</log4javascript:event>" + newLine + newLine;
1200
+ return str;
1201
+ };
1202
+
1203
+ XmlLayout.prototype.ignoresThrowable = function() {
1204
+ return false;
1205
+ };
1206
+
1207
+ XmlLayout.prototype.toString = function() {
1208
+ return "XmlLayout";
1209
+ };
1210
+
1211
+ log4javascript.XmlLayout = XmlLayout;
1212
+ /* ---------------------------------------------------------------------- */
1213
+ // JsonLayout related
1214
+
1215
+ function escapeNewLines(str) {
1216
+ return str.replace(/\r\n|\r|\n/g, "\\r\\n");
1217
+ }
1218
+
1219
+ function JsonLayout(readable, combineMessages) {
1220
+ this.readable = extractBooleanFromParam(readable, false);
1221
+ this.combineMessages = extractBooleanFromParam(combineMessages, true);
1222
+ this.batchHeader = this.readable ? "[" + newLine : "[";
1223
+ this.batchFooter = this.readable ? "]" + newLine : "]";
1224
+ this.batchSeparator = this.readable ? "," + newLine : ",";
1225
+ this.setKeys();
1226
+ this.colon = this.readable ? ": " : ":";
1227
+ this.tab = this.readable ? "\t" : "";
1228
+ this.lineBreak = this.readable ? newLine : "";
1229
+ this.customFields = [];
1230
+ }
1231
+
1232
+ /* ---------------------------------------------------------------------- */
1233
+ // JsonLayout
1234
+
1235
+ JsonLayout.prototype = new Layout();
1236
+
1237
+ JsonLayout.prototype.isReadable = function() {
1238
+ return this.readable;
1239
+ };
1240
+
1241
+ JsonLayout.prototype.isCombinedMessages = function() {
1242
+ return this.combineMessages;
1243
+ };
1244
+
1245
+ JsonLayout.prototype.format = function(loggingEvent) {
1246
+ var layout = this;
1247
+ var dataValues = this.getDataValues(loggingEvent, this.combineMessages);
1248
+ var str = "{" + this.lineBreak;
1249
+ var i, len;
1250
+
1251
+ function formatValue(val, prefix, expand) {
1252
+ // Check the type of the data value to decide whether quotation marks
1253
+ // or expansion are required
1254
+ var formattedValue;
1255
+ var valType = typeof val;
1256
+ if (val instanceof Date) {
1257
+ formattedValue = String(val.getTime());
1258
+ } else if (expand && (val instanceof Array)) {
1259
+ formattedValue = "[" + layout.lineBreak;
1260
+ for (var i = 0, len = val.length; i < len; i++) {
1261
+ var childPrefix = prefix + layout.tab;
1262
+ formattedValue += childPrefix + formatValue(val[i], childPrefix, false);
1263
+ if (i < val.length - 1) {
1264
+ formattedValue += ",";
1265
+ }
1266
+ formattedValue += layout.lineBreak;
1267
+ }
1268
+ formattedValue += prefix + "]";
1269
+ } else if (valType !== "number" && valType !== "boolean") {
1270
+ formattedValue = "\"" + escapeNewLines(toStr(val).replace(/\"/g, "\\\"")) + "\"";
1271
+ } else {
1272
+ formattedValue = val;
1273
+ }
1274
+ return formattedValue;
1275
+ }
1276
+
1277
+ for (i = 0, len = dataValues.length - 1; i <= len; i++) {
1278
+ str += this.tab + "\"" + dataValues[i][0] + "\"" + this.colon + formatValue(dataValues[i][1], this.tab, true);
1279
+ if (i < len) {
1280
+ str += ",";
1281
+ }
1282
+ str += this.lineBreak;
1283
+ }
1284
+
1285
+ str += "}" + this.lineBreak;
1286
+ return str;
1287
+ };
1288
+
1289
+ JsonLayout.prototype.ignoresThrowable = function() {
1290
+ return false;
1291
+ };
1292
+
1293
+ JsonLayout.prototype.toString = function() {
1294
+ return "JsonLayout";
1295
+ };
1296
+
1297
+ JsonLayout.prototype.getContentType = function() {
1298
+ return "application/json";
1299
+ };
1300
+
1301
+ log4javascript.JsonLayout = JsonLayout;
1302
+ /* ---------------------------------------------------------------------- */
1303
+ // HttpPostDataLayout
1304
+
1305
+ function HttpPostDataLayout() {
1306
+ this.setKeys();
1307
+ this.customFields = [];
1308
+ this.returnsPostData = true;
1309
+ }
1310
+
1311
+ HttpPostDataLayout.prototype = new Layout();
1312
+
1313
+ // Disable batching
1314
+ HttpPostDataLayout.prototype.allowBatching = function() {
1315
+ return false;
1316
+ };
1317
+
1318
+ HttpPostDataLayout.prototype.format = function(loggingEvent) {
1319
+ var dataValues = this.getDataValues(loggingEvent);
1320
+ var queryBits = [];
1321
+ for (var i = 0, len = dataValues.length; i < len; i++) {
1322
+ var val = (dataValues[i][1] instanceof Date) ?
1323
+ String(dataValues[i][1].getTime()) : dataValues[i][1];
1324
+ queryBits.push(urlEncode(dataValues[i][0]) + "=" + urlEncode(val));
1325
+ }
1326
+ return queryBits.join("&");
1327
+ };
1328
+
1329
+ HttpPostDataLayout.prototype.ignoresThrowable = function(loggingEvent) {
1330
+ return false;
1331
+ };
1332
+
1333
+ HttpPostDataLayout.prototype.toString = function() {
1334
+ return "HttpPostDataLayout";
1335
+ };
1336
+
1337
+ log4javascript.HttpPostDataLayout = HttpPostDataLayout;
1338
+ /* ---------------------------------------------------------------------- */
1339
+ // formatObjectExpansion
1340
+
1341
+ function formatObjectExpansion(obj, depth, indentation) {
1342
+ var objectsExpanded = [];
1343
+
1344
+ function doFormat(obj, depth, indentation) {
1345
+ var i, j, len, childDepth, childIndentation, childLines, expansion,
1346
+ childExpansion;
1347
+
1348
+ if (!indentation) {
1349
+ indentation = "";
1350
+ }
1351
+
1352
+ function formatString(text) {
1353
+ var lines = splitIntoLines(text);
1354
+ for (var j = 1, jLen = lines.length; j < jLen; j++) {
1355
+ lines[j] = indentation + lines[j];
1356
+ }
1357
+ return lines.join(newLine);
1358
+ }
1359
+
1360
+ if (obj === null) {
1361
+ return "null";
1362
+ } else if (typeof obj == "undefined") {
1363
+ return "undefined";
1364
+ } else if (typeof obj == "string") {
1365
+ return formatString(obj);
1366
+ } else if (typeof obj == "object" && array_contains(objectsExpanded, obj)) {
1367
+ try {
1368
+ expansion = toStr(obj);
1369
+ } catch (ex) {
1370
+ expansion = "Error formatting property. Details: " + getExceptionStringRep(ex);
1371
+ }
1372
+ return expansion + " [already expanded]";
1373
+ } else if ((obj instanceof Array) && depth > 0) {
1374
+ objectsExpanded.push(obj);
1375
+ expansion = "[" + newLine;
1376
+ childDepth = depth - 1;
1377
+ childIndentation = indentation + " ";
1378
+ childLines = [];
1379
+ for (i = 0, len = obj.length; i < len; i++) {
1380
+ try {
1381
+ childExpansion = doFormat(obj[i], childDepth, childIndentation);
1382
+ childLines.push(childIndentation + childExpansion);
1383
+ } catch (ex) {
1384
+ childLines.push(childIndentation + "Error formatting array member. Details: " +
1385
+ getExceptionStringRep(ex) + "");
1386
+ }
1387
+ }
1388
+ expansion += childLines.join("," + newLine) + newLine + indentation + "]";
1389
+ return expansion;
1390
+ } else if (Object.prototype.toString.call(obj) == "[object Date]") {
1391
+ return obj.toString();
1392
+ } else if (typeof obj == "object" && depth > 0) {
1393
+ objectsExpanded.push(obj);
1394
+ expansion = "{" + newLine;
1395
+ childDepth = depth - 1;
1396
+ childIndentation = indentation + " ";
1397
+ childLines = [];
1398
+ for (i in obj) {
1399
+ try {
1400
+ childExpansion = doFormat(obj[i], childDepth, childIndentation);
1401
+ childLines.push(childIndentation + i + ": " + childExpansion);
1402
+ } catch (ex) {
1403
+ childLines.push(childIndentation + i + ": Error formatting property. Details: " +
1404
+ getExceptionStringRep(ex));
1405
+ }
1406
+ }
1407
+ expansion += childLines.join("," + newLine) + newLine + indentation + "}";
1408
+ return expansion;
1409
+ } else {
1410
+ return formatString(toStr(obj));
1411
+ }
1412
+ }
1413
+ return doFormat(obj, depth, indentation);
1414
+ }
1415
+ /* ---------------------------------------------------------------------- */
1416
+ // Date-related stuff
1417
+
1418
+ var SimpleDateFormat;
1419
+
1420
+ (function() {
1421
+ var regex = /('[^']*')|(G+|y+|M+|w+|W+|D+|d+|F+|E+|a+|H+|k+|K+|h+|m+|s+|S+|Z+)|([a-zA-Z]+)|([^a-zA-Z']+)/;
1422
+ var monthNames = ["January", "February", "March", "April", "May", "June",
1423
+ "July", "August", "September", "October", "November", "December"];
1424
+ var dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
1425
+ var TEXT2 = 0, TEXT3 = 1, NUMBER = 2, YEAR = 3, MONTH = 4, TIMEZONE = 5;
1426
+ var types = {
1427
+ G : TEXT2,
1428
+ y : YEAR,
1429
+ M : MONTH,
1430
+ w : NUMBER,
1431
+ W : NUMBER,
1432
+ D : NUMBER,
1433
+ d : NUMBER,
1434
+ F : NUMBER,
1435
+ E : TEXT3,
1436
+ a : TEXT2,
1437
+ H : NUMBER,
1438
+ k : NUMBER,
1439
+ K : NUMBER,
1440
+ h : NUMBER,
1441
+ m : NUMBER,
1442
+ s : NUMBER,
1443
+ S : NUMBER,
1444
+ Z : TIMEZONE
1445
+ };
1446
+ var ONE_DAY = 24 * 60 * 60 * 1000;
1447
+ var ONE_WEEK = 7 * ONE_DAY;
1448
+ var DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK = 1;
1449
+
1450
+ var newDateAtMidnight = function(year, month, day) {
1451
+ var d = new Date(year, month, day, 0, 0, 0);
1452
+ d.setMilliseconds(0);
1453
+ return d;
1454
+ };
1455
+
1456
+ Date.prototype.getDifference = function(date) {
1457
+ return this.getTime() - date.getTime();
1458
+ };
1459
+
1460
+ Date.prototype.isBefore = function(d) {
1461
+ return this.getTime() < d.getTime();
1462
+ };
1463
+
1464
+ Date.prototype.getUTCTime = function() {
1465
+ return Date.UTC(this.getFullYear(), this.getMonth(), this.getDate(), this.getHours(), this.getMinutes(),
1466
+ this.getSeconds(), this.getMilliseconds());
1467
+ };
1468
+
1469
+ Date.prototype.getTimeSince = function(d) {
1470
+ return this.getUTCTime() - d.getUTCTime();
1471
+ };
1472
+
1473
+ Date.prototype.getPreviousSunday = function() {
1474
+ // Using midday avoids any possibility of DST messing things up
1475
+ var midday = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 12, 0, 0);
1476
+ var previousSunday = new Date(midday.getTime() - this.getDay() * ONE_DAY);
1477
+ return newDateAtMidnight(previousSunday.getFullYear(), previousSunday.getMonth(),
1478
+ previousSunday.getDate());
1479
+ };
1480
+
1481
+ Date.prototype.getWeekInYear = function(minimalDaysInFirstWeek) {
1482
+ if (isUndefined(this.minimalDaysInFirstWeek)) {
1483
+ minimalDaysInFirstWeek = DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK;
1484
+ }
1485
+ var previousSunday = this.getPreviousSunday();
1486
+ var startOfYear = newDateAtMidnight(this.getFullYear(), 0, 1);
1487
+ var numberOfSundays = previousSunday.isBefore(startOfYear) ?
1488
+ 0 : 1 + Math.floor(previousSunday.getTimeSince(startOfYear) / ONE_WEEK);
1489
+ var numberOfDaysInFirstWeek = 7 - startOfYear.getDay();
1490
+ var weekInYear = numberOfSundays;
1491
+ if (numberOfDaysInFirstWeek < minimalDaysInFirstWeek) {
1492
+ weekInYear--;
1493
+ }
1494
+ return weekInYear;
1495
+ };
1496
+
1497
+ Date.prototype.getWeekInMonth = function(minimalDaysInFirstWeek) {
1498
+ if (isUndefined(this.minimalDaysInFirstWeek)) {
1499
+ minimalDaysInFirstWeek = DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK;
1500
+ }
1501
+ var previousSunday = this.getPreviousSunday();
1502
+ var startOfMonth = newDateAtMidnight(this.getFullYear(), this.getMonth(), 1);
1503
+ var numberOfSundays = previousSunday.isBefore(startOfMonth) ?
1504
+ 0 : 1 + Math.floor(previousSunday.getTimeSince(startOfMonth) / ONE_WEEK);
1505
+ var numberOfDaysInFirstWeek = 7 - startOfMonth.getDay();
1506
+ var weekInMonth = numberOfSundays;
1507
+ if (numberOfDaysInFirstWeek >= minimalDaysInFirstWeek) {
1508
+ weekInMonth++;
1509
+ }
1510
+ return weekInMonth;
1511
+ };
1512
+
1513
+ Date.prototype.getDayInYear = function() {
1514
+ var startOfYear = newDateAtMidnight(this.getFullYear(), 0, 1);
1515
+ return 1 + Math.floor(this.getTimeSince(startOfYear) / ONE_DAY);
1516
+ };
1517
+
1518
+ /* ------------------------------------------------------------------ */
1519
+
1520
+ SimpleDateFormat = function(formatString) {
1521
+ this.formatString = formatString;
1522
+ };
1523
+
1524
+ /**
1525
+ * Sets the minimum number of days in a week in order for that week to
1526
+ * be considered as belonging to a particular month or year
1527
+ */
1528
+ SimpleDateFormat.prototype.setMinimalDaysInFirstWeek = function(days) {
1529
+ this.minimalDaysInFirstWeek = days;
1530
+ };
1531
+
1532
+ SimpleDateFormat.prototype.getMinimalDaysInFirstWeek = function() {
1533
+ return isUndefined(this.minimalDaysInFirstWeek) ?
1534
+ DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK : this.minimalDaysInFirstWeek;
1535
+ };
1536
+
1537
+ var padWithZeroes = function(str, len) {
1538
+ while (str.length < len) {
1539
+ str = "0" + str;
1540
+ }
1541
+ return str;
1542
+ };
1543
+
1544
+ var formatText = function(data, numberOfLetters, minLength) {
1545
+ return (numberOfLetters >= 4) ? data : data.substr(0, Math.max(minLength, numberOfLetters));
1546
+ };
1547
+
1548
+ var formatNumber = function(data, numberOfLetters) {
1549
+ var dataString = "" + data;
1550
+ // Pad with 0s as necessary
1551
+ return padWithZeroes(dataString, numberOfLetters);
1552
+ };
1553
+
1554
+ SimpleDateFormat.prototype.format = function(date) {
1555
+ var formattedString = "";
1556
+ var result;
1557
+ var searchString = this.formatString;
1558
+ while ((result = regex.exec(searchString))) {
1559
+ var quotedString = result[1];
1560
+ var patternLetters = result[2];
1561
+ var otherLetters = result[3];
1562
+ var otherCharacters = result[4];
1563
+
1564
+ // If the pattern matched is quoted string, output the text between the quotes
1565
+ if (quotedString) {
1566
+ if (quotedString == "''") {
1567
+ formattedString += "'";
1568
+ } else {
1569
+ formattedString += quotedString.substring(1, quotedString.length - 1);
1570
+ }
1571
+ } else if (otherLetters) {
1572
+ // Swallow non-pattern letters by doing nothing here
1573
+ } else if (otherCharacters) {
1574
+ // Simply output other characters
1575
+ formattedString += otherCharacters;
1576
+ } else if (patternLetters) {
1577
+ // Replace pattern letters
1578
+ var patternLetter = patternLetters.charAt(0);
1579
+ var numberOfLetters = patternLetters.length;
1580
+ var rawData = "";
1581
+ switch(patternLetter) {
1582
+ case "G":
1583
+ rawData = "AD";
1584
+ break;
1585
+ case "y":
1586
+ rawData = date.getFullYear();
1587
+ break;
1588
+ case "M":
1589
+ rawData = date.getMonth();
1590
+ break;
1591
+ case "w":
1592
+ rawData = date.getWeekInYear(this.getMinimalDaysInFirstWeek());
1593
+ break;
1594
+ case "W":
1595
+ rawData = date.getWeekInMonth(this.getMinimalDaysInFirstWeek());
1596
+ break;
1597
+ case "D":
1598
+ rawData = date.getDayInYear();
1599
+ break;
1600
+ case "d":
1601
+ rawData = date.getDate();
1602
+ break;
1603
+ case "F":
1604
+ rawData = 1 + Math.floor((date.getDate() - 1) / 7);
1605
+ break;
1606
+ case "E":
1607
+ rawData = dayNames[date.getDay()];
1608
+ break;
1609
+ case "a":
1610
+ rawData = (date.getHours() >= 12) ? "PM" : "AM";
1611
+ break;
1612
+ case "H":
1613
+ rawData = date.getHours();
1614
+ break;
1615
+ case "k":
1616
+ rawData = date.getHours() || 24;
1617
+ break;
1618
+ case "K":
1619
+ rawData = date.getHours() % 12;
1620
+ break;
1621
+ case "h":
1622
+ rawData = (date.getHours() % 12) || 12;
1623
+ break;
1624
+ case "m":
1625
+ rawData = date.getMinutes();
1626
+ break;
1627
+ case "s":
1628
+ rawData = date.getSeconds();
1629
+ break;
1630
+ case "S":
1631
+ rawData = date.getMilliseconds();
1632
+ break;
1633
+ case "Z":
1634
+ rawData = date.getTimezoneOffset(); // This returns the number of minutes since GMT was this time.
1635
+ break;
1636
+ }
1637
+ // Format the raw data depending on the type
1638
+ switch(types[patternLetter]) {
1639
+ case TEXT2:
1640
+ formattedString += formatText(rawData, numberOfLetters, 2);
1641
+ break;
1642
+ case TEXT3:
1643
+ formattedString += formatText(rawData, numberOfLetters, 3);
1644
+ break;
1645
+ case NUMBER:
1646
+ formattedString += formatNumber(rawData, numberOfLetters);
1647
+ break;
1648
+ case YEAR:
1649
+ if (numberOfLetters <= 3) {
1650
+ // Output a 2-digit year
1651
+ var dataString = "" + rawData;
1652
+ formattedString += dataString.substr(2, 2);
1653
+ } else {
1654
+ formattedString += formatNumber(rawData, numberOfLetters);
1655
+ }
1656
+ break;
1657
+ case MONTH:
1658
+ if (numberOfLetters >= 3) {
1659
+ formattedString += formatText(monthNames[rawData], numberOfLetters, numberOfLetters);
1660
+ } else {
1661
+ // NB. Months returned by getMonth are zero-based
1662
+ formattedString += formatNumber(rawData + 1, numberOfLetters);
1663
+ }
1664
+ break;
1665
+ case TIMEZONE:
1666
+ var isPositive = (rawData > 0);
1667
+ // The following line looks like a mistake but isn't
1668
+ // because of the way getTimezoneOffset measures.
1669
+ var prefix = isPositive ? "-" : "+";
1670
+ var absData = Math.abs(rawData);
1671
+
1672
+ // Hours
1673
+ var hours = "" + Math.floor(absData / 60);
1674
+ hours = padWithZeroes(hours, 2);
1675
+ // Minutes
1676
+ var minutes = "" + (absData % 60);
1677
+ minutes = padWithZeroes(minutes, 2);
1678
+
1679
+ formattedString += prefix + hours + minutes;
1680
+ break;
1681
+ }
1682
+ }
1683
+ searchString = searchString.substr(result.index + result[0].length);
1684
+ }
1685
+ return formattedString;
1686
+ };
1687
+ })();
1688
+
1689
+ log4javascript.SimpleDateFormat = SimpleDateFormat;
1690
+
1691
+ /* ---------------------------------------------------------------------- */
1692
+ // PatternLayout
1693
+
1694
+ function PatternLayout(pattern) {
1695
+ if (pattern) {
1696
+ this.pattern = pattern;
1697
+ } else {
1698
+ this.pattern = PatternLayout.DEFAULT_CONVERSION_PATTERN;
1699
+ }
1700
+ this.customFields = [];
1701
+ }
1702
+
1703
+ PatternLayout.TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n";
1704
+ PatternLayout.DEFAULT_CONVERSION_PATTERN = "%m%n";
1705
+ PatternLayout.ISO8601_DATEFORMAT = "yyyy-MM-dd HH:mm:ss,SSS";
1706
+ PatternLayout.DATETIME_DATEFORMAT = "dd MMM yyyy HH:mm:ss,SSS";
1707
+ PatternLayout.ABSOLUTETIME_DATEFORMAT = "HH:mm:ss,SSS";
1708
+
1709
+ PatternLayout.prototype = new Layout();
1710
+
1711
+ PatternLayout.prototype.format = function(loggingEvent) {
1712
+ var regex = /%(-?[0-9]+)?(\.?[0-9]+)?([acdfmMnpr%])(\{([^\}]+)\})?|([^%]+)/;
1713
+ var formattedString = "";
1714
+ var result;
1715
+ var searchString = this.pattern;
1716
+
1717
+ // Cannot use regex global flag since it doesn't work with exec in IE5
1718
+ while ((result = regex.exec(searchString))) {
1719
+ var matchedString = result[0];
1720
+ var padding = result[1];
1721
+ var truncation = result[2];
1722
+ var conversionCharacter = result[3];
1723
+ var specifier = result[5];
1724
+ var text = result[6];
1725
+
1726
+ // Check if the pattern matched was just normal text
1727
+ if (text) {
1728
+ formattedString += "" + text;
1729
+ } else {
1730
+ // Create a raw replacement string based on the conversion
1731
+ // character and specifier
1732
+ var replacement = "";
1733
+ switch(conversionCharacter) {
1734
+ case "a": // Array of messages
1735
+ case "m": // Message
1736
+ var depth = 0;
1737
+ if (specifier) {
1738
+ depth = parseInt(specifier, 10);
1739
+ if (isNaN(depth)) {
1740
+ handleError("PatternLayout.format: invalid specifier '" +
1741
+ specifier + "' for conversion character '" + conversionCharacter +
1742
+ "' - should be a number");
1743
+ depth = 0;
1744
+ }
1745
+ }
1746
+ var messages = (conversionCharacter === "a") ? loggingEvent.messages[0] : loggingEvent.messages;
1747
+ for (var i = 0, len = messages.length; i < len; i++) {
1748
+ if (i > 0 && (replacement.charAt(replacement.length - 1) !== " ")) {
1749
+ replacement += " ";
1750
+ }
1751
+ if (depth === 0) {
1752
+ replacement += messages[i];
1753
+ } else {
1754
+ replacement += formatObjectExpansion(messages[i], depth);
1755
+ }
1756
+ }
1757
+ break;
1758
+ case "c": // Logger name
1759
+ var loggerName = loggingEvent.logger.name;
1760
+ if (specifier) {
1761
+ var precision = parseInt(specifier, 10);
1762
+ var loggerNameBits = loggingEvent.logger.name.split(".");
1763
+ if (precision >= loggerNameBits.length) {
1764
+ replacement = loggerName;
1765
+ } else {
1766
+ replacement = loggerNameBits.slice(loggerNameBits.length - precision).join(".");
1767
+ }
1768
+ } else {
1769
+ replacement = loggerName;
1770
+ }
1771
+ break;
1772
+ case "d": // Date
1773
+ var dateFormat = PatternLayout.ISO8601_DATEFORMAT;
1774
+ if (specifier) {
1775
+ dateFormat = specifier;
1776
+ // Pick up special cases
1777
+ if (dateFormat == "ISO8601") {
1778
+ dateFormat = PatternLayout.ISO8601_DATEFORMAT;
1779
+ } else if (dateFormat == "ABSOLUTE") {
1780
+ dateFormat = PatternLayout.ABSOLUTETIME_DATEFORMAT;
1781
+ } else if (dateFormat == "DATE") {
1782
+ dateFormat = PatternLayout.DATETIME_DATEFORMAT;
1783
+ }
1784
+ }
1785
+ // Format the date
1786
+ replacement = (new SimpleDateFormat(dateFormat)).format(loggingEvent.timeStamp);
1787
+ break;
1788
+ case "f": // Custom field
1789
+ if (this.hasCustomFields()) {
1790
+ var fieldIndex = 0;
1791
+ if (specifier) {
1792
+ fieldIndex = parseInt(specifier, 10);
1793
+ if (isNaN(fieldIndex)) {
1794
+ handleError("PatternLayout.format: invalid specifier '" +
1795
+ specifier + "' for conversion character 'f' - should be a number");
1796
+ } else if (fieldIndex === 0) {
1797
+ handleError("PatternLayout.format: invalid specifier '" +
1798
+ specifier + "' for conversion character 'f' - must be greater than zero");
1799
+ } else if (fieldIndex > this.customFields.length) {
1800
+ handleError("PatternLayout.format: invalid specifier '" +
1801
+ specifier + "' for conversion character 'f' - there aren't that many custom fields");
1802
+ } else {
1803
+ fieldIndex = fieldIndex - 1;
1804
+ }
1805
+ }
1806
+ var val = this.customFields[fieldIndex].value;
1807
+ if (typeof val == "function") {
1808
+ val = val(this, loggingEvent);
1809
+ }
1810
+ replacement = val;
1811
+ }
1812
+ break;
1813
+ case "n": // New line
1814
+ replacement = newLine;
1815
+ break;
1816
+ case "p": // Level
1817
+ replacement = loggingEvent.level.name;
1818
+ break;
1819
+ case "r": // Milliseconds since log4javascript startup
1820
+ replacement = "" + loggingEvent.timeStamp.getDifference(applicationStartDate);
1821
+ break;
1822
+ case "%": // Literal % sign
1823
+ replacement = "%";
1824
+ break;
1825
+ default:
1826
+ replacement = matchedString;
1827
+ break;
1828
+ }
1829
+ // Format the replacement according to any padding or
1830
+ // truncation specified
1831
+ var l;
1832
+
1833
+ // First, truncation
1834
+ if (truncation) {
1835
+ l = parseInt(truncation.substr(1), 10);
1836
+ var strLen = replacement.length;
1837
+ if (l < strLen) {
1838
+ replacement = replacement.substring(strLen - l, strLen);
1839
+ }
1840
+ }
1841
+ // Next, padding
1842
+ if (padding) {
1843
+ if (padding.charAt(0) == "-") {
1844
+ l = parseInt(padding.substr(1), 10);
1845
+ // Right pad with spaces
1846
+ while (replacement.length < l) {
1847
+ replacement += " ";
1848
+ }
1849
+ } else {
1850
+ l = parseInt(padding, 10);
1851
+ // Left pad with spaces
1852
+ while (replacement.length < l) {
1853
+ replacement = " " + replacement;
1854
+ }
1855
+ }
1856
+ }
1857
+ formattedString += replacement;
1858
+ }
1859
+ searchString = searchString.substr(result.index + result[0].length);
1860
+ }
1861
+ return formattedString;
1862
+ };
1863
+
1864
+ PatternLayout.prototype.ignoresThrowable = function() {
1865
+ return true;
1866
+ };
1867
+
1868
+ PatternLayout.prototype.toString = function() {
1869
+ return "PatternLayout";
1870
+ };
1871
+
1872
+ log4javascript.PatternLayout = PatternLayout;
1873
+ /* ---------------------------------------------------------------------- */
1874
+ // AjaxAppender related
1875
+
1876
+ var xmlHttpFactories = [
1877
+ function() { return new XMLHttpRequest(); },
1878
+ function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
1879
+ function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
1880
+ ];
1881
+
1882
+ var getXmlHttp = function(errorHandler) {
1883
+ // This is only run the first time; the value of getXmlHttp gets
1884
+ // replaced with the factory that succeeds on the first run
1885
+ var xmlHttp = null, factory;
1886
+ for (var i = 0, len = xmlHttpFactories.length; i < len; i++) {
1887
+ factory = xmlHttpFactories[i];
1888
+ try {
1889
+ xmlHttp = factory();
1890
+ getXmlHttp = factory;
1891
+ return xmlHttp;
1892
+ } catch (e) {
1893
+ }
1894
+ }
1895
+ // If we're here, all factories have failed, so throw an error
1896
+ if (errorHandler) {
1897
+ errorHandler();
1898
+ } else {
1899
+ handleError("getXmlHttp: unable to obtain XMLHttpRequest object");
1900
+ }
1901
+ };
1902
+
1903
+ function isHttpRequestSuccessful(xmlHttp) {
1904
+ return isUndefined(xmlHttp.status) || xmlHttp.status === 0 ||
1905
+ (xmlHttp.status >= 200 && xmlHttp.status < 300) ||
1906
+ xmlHttp.status == 1223 /* Fix for IE */;
1907
+ }
1908
+
1909
+ /* ---------------------------------------------------------------------- */
1910
+ // AjaxAppender
1911
+
1912
+ function AjaxAppender(url) {
1913
+ var appender = this;
1914
+ var isSupported = true;
1915
+ if (!url) {
1916
+ handleError("AjaxAppender: URL must be specified in constructor");
1917
+ isSupported = false;
1918
+ }
1919
+
1920
+ var timed = this.defaults.timed;
1921
+ var waitForResponse = this.defaults.waitForResponse;
1922
+ var batchSize = this.defaults.batchSize;
1923
+ var timerInterval = this.defaults.timerInterval;
1924
+ var requestSuccessCallback = this.defaults.requestSuccessCallback;
1925
+ var failCallback = this.defaults.failCallback;
1926
+ var postVarName = this.defaults.postVarName;
1927
+ var sendAllOnUnload = this.defaults.sendAllOnUnload;
1928
+ var contentType = this.defaults.contentType;
1929
+ var sessionId = null;
1930
+
1931
+ var queuedLoggingEvents = [];
1932
+ var queuedRequests = [];
1933
+ var headers = [];
1934
+ var sending = false;
1935
+ var initialized = false;
1936
+
1937
+ // Configuration methods. The function scope is used to prevent
1938
+ // direct alteration to the appender configuration properties.
1939
+ function checkCanConfigure(configOptionName) {
1940
+ if (initialized) {
1941
+ handleError("AjaxAppender: configuration option '" +
1942
+ configOptionName +
1943
+ "' may not be set after the appender has been initialized");
1944
+ return false;
1945
+ }
1946
+ return true;
1947
+ }
1948
+
1949
+ this.getSessionId = function() { return sessionId; };
1950
+ this.setSessionId = function(sessionIdParam) {
1951
+ sessionId = extractStringFromParam(sessionIdParam, null);
1952
+ this.layout.setCustomField("sessionid", sessionId);
1953
+ };
1954
+
1955
+ this.setLayout = function(layoutParam) {
1956
+ if (checkCanConfigure("layout")) {
1957
+ this.layout = layoutParam;
1958
+ // Set the session id as a custom field on the layout, if not already present
1959
+ if (sessionId !== null) {
1960
+ this.setSessionId(sessionId);
1961
+ }
1962
+ }
1963
+ };
1964
+
1965
+ this.isTimed = function() { return timed; };
1966
+ this.setTimed = function(timedParam) {
1967
+ if (checkCanConfigure("timed")) {
1968
+ timed = bool(timedParam);
1969
+ }
1970
+ };
1971
+
1972
+ this.getTimerInterval = function() { return timerInterval; };
1973
+ this.setTimerInterval = function(timerIntervalParam) {
1974
+ if (checkCanConfigure("timerInterval")) {
1975
+ timerInterval = extractIntFromParam(timerIntervalParam, timerInterval);
1976
+ }
1977
+ };
1978
+
1979
+ this.isWaitForResponse = function() { return waitForResponse; };
1980
+ this.setWaitForResponse = function(waitForResponseParam) {
1981
+ if (checkCanConfigure("waitForResponse")) {
1982
+ waitForResponse = bool(waitForResponseParam);
1983
+ }
1984
+ };
1985
+
1986
+ this.getBatchSize = function() { return batchSize; };
1987
+ this.setBatchSize = function(batchSizeParam) {
1988
+ if (checkCanConfigure("batchSize")) {
1989
+ batchSize = extractIntFromParam(batchSizeParam, batchSize);
1990
+ }
1991
+ };
1992
+
1993
+ this.isSendAllOnUnload = function() { return sendAllOnUnload; };
1994
+ this.setSendAllOnUnload = function(sendAllOnUnloadParam) {
1995
+ if (checkCanConfigure("sendAllOnUnload")) {
1996
+ sendAllOnUnload = extractBooleanFromParam(sendAllOnUnloadParam, sendAllOnUnload);
1997
+ }
1998
+ };
1999
+
2000
+ this.setRequestSuccessCallback = function(requestSuccessCallbackParam) {
2001
+ requestSuccessCallback = extractFunctionFromParam(requestSuccessCallbackParam, requestSuccessCallback);
2002
+ };
2003
+
2004
+ this.setFailCallback = function(failCallbackParam) {
2005
+ failCallback = extractFunctionFromParam(failCallbackParam, failCallback);
2006
+ };
2007
+
2008
+ this.getPostVarName = function() { return postVarName; };
2009
+ this.setPostVarName = function(postVarNameParam) {
2010
+ if (checkCanConfigure("postVarName")) {
2011
+ postVarName = extractStringFromParam(postVarNameParam, postVarName);
2012
+ }
2013
+ };
2014
+
2015
+ this.getHeaders = function() { return headers; };
2016
+ this.addHeader = function(name, value) {
2017
+ if (name.toLowerCase() == "content-type") {
2018
+ contentType = value;
2019
+ } else {
2020
+ headers.push( { name: name, value: value } );
2021
+ }
2022
+ };
2023
+
2024
+ // Internal functions
2025
+ function sendAll() {
2026
+ if (isSupported && enabled) {
2027
+ sending = true;
2028
+ var currentRequestBatch;
2029
+ if (waitForResponse) {
2030
+ // Send the first request then use this function as the callback once
2031
+ // the response comes back
2032
+ if (queuedRequests.length > 0) {
2033
+ currentRequestBatch = queuedRequests.shift();
2034
+ sendRequest(preparePostData(currentRequestBatch), sendAll);
2035
+ } else {
2036
+ sending = false;
2037
+ if (timed) {
2038
+ scheduleSending();
2039
+ }
2040
+ }
2041
+ } else {
2042
+ // Rattle off all the requests without waiting to see the response
2043
+ while ((currentRequestBatch = queuedRequests.shift())) {
2044
+ sendRequest(preparePostData(currentRequestBatch));
2045
+ }
2046
+ sending = false;
2047
+ if (timed) {
2048
+ scheduleSending();
2049
+ }
2050
+ }
2051
+ }
2052
+ }
2053
+
2054
+ this.sendAll = sendAll;
2055
+
2056
+ // Called when the window unloads. At this point we're past caring about
2057
+ // waiting for responses or timers or incomplete batches - everything
2058
+ // must go, now
2059
+ function sendAllRemaining() {
2060
+ var sendingAnything = false;
2061
+ if (isSupported && enabled) {
2062
+ // Create requests for everything left over, batched as normal
2063
+ var actualBatchSize = appender.getLayout().allowBatching() ? batchSize : 1;
2064
+ var currentLoggingEvent;
2065
+ var batchedLoggingEvents = [];
2066
+ while ((currentLoggingEvent = queuedLoggingEvents.shift())) {
2067
+ batchedLoggingEvents.push(currentLoggingEvent);
2068
+ if (queuedLoggingEvents.length >= actualBatchSize) {
2069
+ // Queue this batch of log entries
2070
+ queuedRequests.push(batchedLoggingEvents);
2071
+ batchedLoggingEvents = [];
2072
+ }
2073
+ }
2074
+ // If there's a partially completed batch, add it
2075
+ if (batchedLoggingEvents.length > 0) {
2076
+ queuedRequests.push(batchedLoggingEvents);
2077
+ }
2078
+ sendingAnything = (queuedRequests.length > 0);
2079
+ waitForResponse = false;
2080
+ timed = false;
2081
+ sendAll();
2082
+ }
2083
+ return sendingAnything;
2084
+ }
2085
+
2086
+ this.sendAllRemaining = sendAllRemaining;
2087
+
2088
+ function preparePostData(batchedLoggingEvents) {
2089
+ // Format the logging events
2090
+ var formattedMessages = [];
2091
+ var currentLoggingEvent;
2092
+ var postData = "";
2093
+ while ((currentLoggingEvent = batchedLoggingEvents.shift())) {
2094
+ var currentFormattedMessage = appender.getLayout().format(currentLoggingEvent);
2095
+ if (appender.getLayout().ignoresThrowable()) {
2096
+ currentFormattedMessage += currentLoggingEvent.getThrowableStrRep();
2097
+ }
2098
+ formattedMessages.push(currentFormattedMessage);
2099
+ }
2100
+ // Create the post data string
2101
+ if (batchedLoggingEvents.length == 1) {
2102
+ postData = formattedMessages.join("");
2103
+ } else {
2104
+ postData = appender.getLayout().batchHeader +
2105
+ formattedMessages.join(appender.getLayout().batchSeparator) +
2106
+ appender.getLayout().batchFooter;
2107
+ }
2108
+ if (contentType == appender.defaults.contentType) {
2109
+ postData = appender.getLayout().returnsPostData ? postData :
2110
+ urlEncode(postVarName) + "=" + urlEncode(postData);
2111
+ // Add the layout name to the post data
2112
+ if (postData.length > 0) {
2113
+ postData += "&";
2114
+ }
2115
+ postData += "layout=" + urlEncode(appender.getLayout().toString());
2116
+ }
2117
+ return postData;
2118
+ }
2119
+
2120
+ function scheduleSending() {
2121
+ window.setTimeout(sendAll, timerInterval);
2122
+ }
2123
+
2124
+ function xmlHttpErrorHandler() {
2125
+ var msg = "AjaxAppender: could not create XMLHttpRequest object. AjaxAppender disabled";
2126
+ handleError(msg);
2127
+ isSupported = false;
2128
+ if (failCallback) {
2129
+ failCallback(msg);
2130
+ }
2131
+ }
2132
+
2133
+ function sendRequest(postData, successCallback) {
2134
+ try {
2135
+ var xmlHttp = getXmlHttp(xmlHttpErrorHandler);
2136
+ if (isSupported) {
2137
+ if (xmlHttp.overrideMimeType) {
2138
+ xmlHttp.overrideMimeType(appender.getLayout().getContentType());
2139
+ }
2140
+ xmlHttp.onreadystatechange = function() {
2141
+ if (xmlHttp.readyState == 4) {
2142
+ if (isHttpRequestSuccessful(xmlHttp)) {
2143
+ if (requestSuccessCallback) {
2144
+ requestSuccessCallback(xmlHttp);
2145
+ }
2146
+ if (successCallback) {
2147
+ successCallback(xmlHttp);
2148
+ }
2149
+ } else {
2150
+ var msg = "AjaxAppender.append: XMLHttpRequest request to URL " +
2151
+ url + " returned status code " + xmlHttp.status;
2152
+ handleError(msg);
2153
+ if (failCallback) {
2154
+ failCallback(msg);
2155
+ }
2156
+ }
2157
+ xmlHttp.onreadystatechange = emptyFunction;
2158
+ xmlHttp = null;
2159
+ }
2160
+ };
2161
+ xmlHttp.open("POST", url, true);
2162
+ try {
2163
+ for (var i = 0, header; header = headers[i++]; ) {
2164
+ xmlHttp.setRequestHeader(header.name, header.value);
2165
+ }
2166
+ xmlHttp.setRequestHeader("Content-Type", contentType);
2167
+ } catch (headerEx) {
2168
+ var msg = "AjaxAppender.append: your browser's XMLHttpRequest implementation" +
2169
+ " does not support setRequestHeader, therefore cannot post data. AjaxAppender disabled";
2170
+ handleError(msg);
2171
+ isSupported = false;
2172
+ if (failCallback) {
2173
+ failCallback(msg);
2174
+ }
2175
+ return;
2176
+ }
2177
+ xmlHttp.send(postData);
2178
+ }
2179
+ } catch (ex) {
2180
+ var errMsg = "AjaxAppender.append: error sending log message to " + url;
2181
+ handleError(errMsg, ex);
2182
+ isSupported = false;
2183
+ if (failCallback) {
2184
+ failCallback(errMsg + ". Details: " + getExceptionStringRep(ex));
2185
+ }
2186
+ }
2187
+ }
2188
+
2189
+ this.append = function(loggingEvent) {
2190
+ if (isSupported) {
2191
+ if (!initialized) {
2192
+ init();
2193
+ }
2194
+ queuedLoggingEvents.push(loggingEvent);
2195
+ var actualBatchSize = this.getLayout().allowBatching() ? batchSize : 1;
2196
+
2197
+ if (queuedLoggingEvents.length >= actualBatchSize) {
2198
+ var currentLoggingEvent;
2199
+ var batchedLoggingEvents = [];
2200
+ while ((currentLoggingEvent = queuedLoggingEvents.shift())) {
2201
+ batchedLoggingEvents.push(currentLoggingEvent);
2202
+ }
2203
+ // Queue this batch of log entries
2204
+ queuedRequests.push(batchedLoggingEvents);
2205
+
2206
+ // If using a timer, the queue of requests will be processed by the
2207
+ // timer function, so nothing needs to be done here.
2208
+ if (!timed && (!waitForResponse || (waitForResponse && !sending))) {
2209
+ sendAll();
2210
+ }
2211
+ }
2212
+ }
2213
+ };
2214
+
2215
+ function init() {
2216
+ initialized = true;
2217
+ // Add unload event to send outstanding messages
2218
+ if (sendAllOnUnload) {
2219
+ var oldBeforeUnload = window.onbeforeunload;
2220
+ window.onbeforeunload = function() {
2221
+ if (oldBeforeUnload) {
2222
+ oldBeforeUnload();
2223
+ }
2224
+ if (sendAllRemaining()) {
2225
+ return "Sending log messages";
2226
+ }
2227
+ };
2228
+ }
2229
+ // Start timer
2230
+ if (timed) {
2231
+ scheduleSending();
2232
+ }
2233
+ }
2234
+ }
2235
+
2236
+ AjaxAppender.prototype = new Appender();
2237
+
2238
+ AjaxAppender.prototype.defaults = {
2239
+ waitForResponse: false,
2240
+ timed: false,
2241
+ timerInterval: 1000,
2242
+ batchSize: 1,
2243
+ sendAllOnUnload: false,
2244
+ requestSuccessCallback: null,
2245
+ failCallback: null,
2246
+ postVarName: "data",
2247
+ contentType: "application/x-www-form-urlencoded"
2248
+ };
2249
+
2250
+ AjaxAppender.prototype.layout = new HttpPostDataLayout();
2251
+
2252
+ AjaxAppender.prototype.toString = function() {
2253
+ return "AjaxAppender";
2254
+ };
2255
+
2256
+ log4javascript.AjaxAppender = AjaxAppender;
2257
+
2258
+ /* ---------------------------------------------------------------------- */
2259
+ // Main load
2260
+
2261
+ log4javascript.setDocumentReady = function() {
2262
+ pageLoaded = true;
2263
+ log4javascript.dispatchEvent("load", {});
2264
+ };
2265
+
2266
+ if (window.addEventListener) {
2267
+ window.addEventListener("load", log4javascript.setDocumentReady, false);
2268
+ } else if (window.attachEvent) {
2269
+ window.attachEvent("onload", log4javascript.setDocumentReady);
2270
+ } else {
2271
+ var oldOnload = window.onload;
2272
+ if (typeof window.onload != "function") {
2273
+ window.onload = log4javascript.setDocumentReady;
2274
+ } else {
2275
+ window.onload = function(evt) {
2276
+ if (oldOnload) {
2277
+ oldOnload(evt);
2278
+ }
2279
+ log4javascript.setDocumentReady();
2280
+ };
2281
+ }
2282
+ }
2283
+
2284
+ // Ensure that the log4javascript object is available in the window. This
2285
+ // is necessary for log4javascript to be available in IE if loaded using
2286
+ // Dojo's module system
2287
+ window.log4javascript = log4javascript;
2288
+
2289
+ return log4javascript;
2290
+ })();