From af4bb9f2af350727b1112e55adc55341df0808e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bu=CC=80i=20Vie=CC=A3=CC=82t=20Tha=CC=80nh?= Date: Tue, 23 Apr 2019 01:04:36 +0700 Subject: [PATCH] done migrate all test to typescript & lerna --- .gitignore | 6 - external/jshashtable.js | 16 - external/log4javascript.js | 6178 ----------------- external/log4javascript_stub.js | 23 - package.json | 9 +- packages/classapplier/package.json | 9 + packages/core/package.json | 9 + packages/core/test/index.html | 4 +- packages/highlighter/package.json | 9 + packages/selectionsaverestore/package.json | 9 + packages/selectionsaverestore/src/index.ts | 2 +- packages/selectionsaverestore/test/index.html | 55 +- .../selectionsaverestore/test/index.test.ts | 23 +- .../selectionsaverestore/test/tsconfig.json | 8 + packages/serializer/package.json | 9 + packages/util/package.json | 8 + tsconfig.json | 3 +- yarn.lock | 12 +- 18 files changed, 100 insertions(+), 6292 deletions(-) delete mode 100644 external/jshashtable.js delete mode 100644 external/log4javascript.js delete mode 100644 external/log4javascript_stub.js create mode 100644 packages/selectionsaverestore/test/tsconfig.json diff --git a/.gitignore b/.gitignore index 26077372..ab6b779e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,5 @@ .idea -dist node_modules -/tscOut/ -/.rpt2_cache/ -/lib/ /scripts/*.js *.js.map *.ts.map @@ -12,8 +8,6 @@ node_modules *.test.amd.js *.test.iife.js *.test.d.ts -/test/*.d.ts -!/test/typings.d.ts /packages/test-util/*.js* /packages/test-util/*.d.ts !/packages/test-util/typings.d.ts diff --git a/external/jshashtable.js b/external/jshashtable.js deleted file mode 100644 index e19c0be7..00000000 --- a/external/jshashtable.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright 2010 Tim Down. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -var Hashtable=(function(){var p="function";var n=(typeof Array.prototype.splice==p)?function(s,r){s.splice(r,1)}:function(u,t){var s,v,r;if(t===u.length-1){u.length=t}else{s=u.slice(t+1);u.length=t;for(v=0,r=s.length;v - * Version: 1.5 dev - * Edition: log4javascript - * Build date: 6 April 2009 - * Website: http://log4javascript.org - */ - -/* -------------------------------------------------------------------------- */ - -var log4javascript = (function() { - - // Create a reference to the global object - var global = (function() { return this; })(); - - function isUndefined(obj) { - return typeof obj === "undefined"; - } - - - function hasMethod(obj, methodName) { - return typeof obj[methodName] === "function"; - } - - // Trio of functions taken from Peter Michaux's article: - // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting - function isHostMethod(object, property) { - var t = typeof object[property]; - return t === "function" || (!!(t === "object" && object[property])) || t === "unknown"; - } - - function isHostCollection(object, property) { - var t = typeof object[property]; - return (!!(t === "object" && object[property])) || t === "function"; - } - - function isHostObject(object, property) { - return !!(typeof object[property] === "object" && object[property]); - } - - /* ---------------------------------------------------------------------- */ - // Array-related stuff, the first three for the sole benefit of IE5 - - var Arrays = (function() { - var push = Array.prototype.push ? - function(arr, val) { - return arr.push(val); - } : - - function(arr, val) { - arr[arr.length] = val; - return arr.length; - }; - - var shift = Array.prototype.shift ? - function(arr) { - return arr.shift(); - } : - - function(arr) { - if (arr.length > 0) { - var firstItem = arr[0]; - for (var i = 0, len = arr.length - 1; i < len; i++) { - arr[i] = arr[i + 1]; - } - arr.length = arr.length - 1; - return firstItem; - } - }; - - var indexOf = Array.prototype.indexOf ? - function(arr, val, from) { - return arr.indexOf(val, from); - } : - - function(arr, val, from) { - var len = arr.length; - - from = Number(arguments[2]) || 0; - from = Math.floor( Math.max(from, 0) ); - - for (; from < len; from++) { - if (typeof arr[from] !== "undefined" && arr[from] === val) { - return from; - } - } - return -1; - }; - - var remove = Array.prototype.splice ? - function(arr, val) { - var index = indexOf(arr, val); - if (index >= 0) { - arr.splice(index, 1); - return true; - } else { - return false; - } - } : - - function(arr, val) { - var index = indexOf(arr, val); - var i, len, itemsToAdd, removedAny = false; - if (index >= 0) { - if (index == arr.length - 1) { - arr.length--; - } else { - itemsToAdd = arr.slice(index + 1); - arr.length = index; - for (i = 0, len = itemsToAdd.length; i < len; i++) { - Arrays.push(arr, itemsToAdd[i]); - } - } - removedAny = true; - } - return removedAny; - }; - - function contains(arr, val) { - return indexOf(arr, val) > -1; - } - - return { - push: push, - shift: shift, - indexOf: indexOf, - remove: remove, - contains: contains - }; - })(); - - /* ---------------------------------------------------------------------- */ - // Custom event support - - function EventSupport() {} - - 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 (!Arrays.contains(this.eventTypes, eventType)) { - handleError("log4javascript.EventSupport [" + this + "]: addEventListener: no event called '" + eventType + "'"); - } - Arrays.push(this.eventListeners[eventType], listener); - } else { - handleError("log4javascript.EventSupport [" + this + "]: addEventListener: listener must be a function"); - } - }, - - removeEventListener: function(eventType, listener) { - if (typeof listener == "function") { - if (!Arrays.contains(this.eventTypes, eventType)) { - handleError("log4javascript.EventSupport [" + this + "]: removeEventListener: no event called '" + eventType + "'"); - } - Arrays.remove(this.eventListeners[eventType], listener); - } else { - handleError("log4javascript.EventSupport [" + this + "]: removeEventListener: listener must be a function"); - } - }, - - dispatchEvent: function(eventType, eventArgs) { - if (Arrays.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() + "_" + - Math.floor(Math.random() * 100000000); - var emptyFunction = function() {}; - var newLine = "\r\n"; - var pageLoaded = false; - - // Create main log4javascript object; this will be assigned public properties - function Log4JavaScript() {} - Log4JavaScript.prototype = new EventSupport(); - - log4javascript = new Log4JavaScript(); - log4javascript.version = "1.5 dev"; - log4javascript.edition = "log4javascript"; - - /* -------------------------------------------------------------------------- */ - // Utility functions - - function toStr(obj) { - if (obj && obj.toString) { - return obj.toString(); - } else { - return String(obj); - } - } - - function getExceptionMessage(ex) { - if (ex.message) { - return ex.message; - } else if (ex.description) { - return ex.description; - } else { - return toStr(ex); - } - } - - // Gets the portion of the URL after the last slash - function getUrlFileName(url) { - var lastSlashIndex = Math.max(url.lastIndexOf("/"), url.lastIndexOf("\\")); - return url.substr(lastSlashIndex + 1); - } - - // Returns a nicely formatted representation of an error - function getExceptionStringRep(ex) { - if (ex) { - var exStr = "Exception: " + getExceptionMessage(ex); - try { - if (ex.lineNumber) { - exStr += " on line number " + ex.lineNumber; - } - if (ex.fileName) { - exStr += " in file " + getUrlFileName(ex.fileName); - } - } catch (localEx) { - logLog.warn("Unable to obtain file and line information for error"); - } - if (showStackTraces && ex.stack) { - exStr += newLine + "Stack trace:" + newLine + ex.stack; - } - return exStr; - } - return null; - } - - function bool(obj) { - return Boolean(obj); - } - - function trim(str) { - return str.replace(/^\s+/, "").replace(/\s+$/, ""); - } - - function splitIntoLines(text) { - // Ensure all line breaks are \n only - var text2 = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); - return text2.split("\n"); - } - - function createCharString(str, len) { - var c = [], i = len; - while (i--) { - c[i] = str; - } - return c.join(""); - } - - function leftPad(str, len, padStr) { - return createCharString(padStr, len) + str; - } - - function rightPad(str, len, padStr) { - return str + createCharString(padStr, len); - } - - // Cannot use encode URIComponent since it is not supported in IE5 - var urlEncode = (function() { - function toUtf8(str, useCaching) { - var i, len, c, cachedChars, newStrParts = [], cachedParts = {}, newPart; - if (useCaching) { - cachedChars = {}; - } - for (i = 0, len = str.length; i < len; i++) { - c = str.charCodeAt(i); - newPart = useCaching ? cachedParts[c] : null; - - if (!newPart) { - // Single byte characters - if (c < 128) { - newPart = String.fromCharCode(c); - } - - // 2 byte characters - else if( (c > 127) && (c < 2048) ) { - newPart = String.fromCharCode( (c >> 6) | 192 ) + String.fromCharCode( (c & 63) | 128 ); - } - - // 3 byte characters - else { - newPart = String.fromCharCode( (c >> 12) | 224 ) + String.fromCharCode( ( (c >> 6) & 63 ) | 128 ) - + String.fromCharCode( (c & 63) | 128 ); - } - } - if (useCaching) { - cachedParts[c] = newPart; - } - - Arrays.push(newStrParts, newPart); - } - - return newStrParts.join(""); - } - - function hex(charCode) { - return ( charCode < 16 ? "%0" + charCode.toString(16) : "%" + charCode.toString(16) ).toUpperCase(); - } - - var unencodedCharRegex = /[a-z0-9.\-*_]/i; - - return function(str) { - // Normalize a line breaks so that \r and \n not in the combination /r/n are converted to /r/n - var i, len, c, newStrParts = [], newPart, character; - var newStr = toStr(str).replace(/\r\n/g, "\n").replace(/[\r\n]/g, "\r\n"); - - // Convert to UTF-8 - newStr = toUtf8(newStr, true); - - // Go through each character and convert where necessaru - - for (i = 0, len = newStr.length; i < len; i++) { - c = newStr.charCodeAt(i); - - // Check whether the character needs to be encoded - // Characters that do not are a-z, A-Z, 0-9, ".", "-", "*", and "_". - // Space is mapped to +. - // All other chars are encoded. These are the same rules as Java's URLEncoder class. - character = String.fromCharCode(c); - - if ( unencodedCharRegex.test( character ) ) { - newPart = character; - } else if (character == " ") { - newPart = "+"; - } else { - newPart = hex(c); - } - - Arrays.push(newStrParts, newPart); - } - - return newStrParts.join(""); - }; - })(); - - - function extractBooleanFromParam(param, defaultValue) { - if (isUndefined(param)) { - return defaultValue; - } else { - return bool(param); - } - } - - function extractStringFromParam(param, defaultValue) { - if (isUndefined(param)) { - return defaultValue; - } else { - return String(param); - } - } - - function extractIntFromParam(param, defaultValue) { - var value; - if (isUndefined(param)) { - return defaultValue; - } else { - try { - value = parseInt(param, 10); - return isNaN(value) ? defaultValue : value; - } catch (ex) { - logLog.warn("Invalid int param " + param, ex); - return defaultValue; - } - } - } - - function extractFunctionFromParam(param, defaultValue) { - if (typeof param == "function") { - return param; - } else { - return defaultValue; - } - } - - function isError(err) { - return (err instanceof Error); - } - - if (!Function.prototype.apply){ - Function.prototype.apply = function(obj, args) { - var methodName = "__apply__"; - if (typeof obj[methodName] != "undefined") { - methodName += String(Math.random()).substr(2); - } - obj[methodName] = this; - - var argsStrings = []; - for (var i = 0, len = args.length; i < len; i++) { - argsStrings[i] = "args[" + i + "]"; - } - var script = "obj." + methodName + "(" + argsStrings.join(",") + ")"; - var returnValue = eval(script); - delete obj[methodName]; - return returnValue; - }; - } - - 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]; - } - return this.apply(obj, args); - }; - } - - function getListenersPropertyName(eventName) { - return "__log4javascript_listeners__" + eventName; - } - - 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] = []; - // Set event handler - node["on" + eventName] = function(evt) { - evt = evt || win.event; - var listenersPropertyName = getListenersPropertyName(eventName); - - // Clone the array of listeners to leave the original untouched - var listeners = this[listenersPropertyName].concat([]); - var currentListener; - - // Call each listener in turn - while ((currentListener = listeners.shift())) { - currentListener.call(this, evt); - } - }; - } - Arrays.push(node[propertyName], listener); - } - } - -/* - 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]) { - Arrays.remove(node[propertyName], listener); - } - } - } -*/ - - /* ---------------------------------------------------------------------- */ - // Simple logging for log4javascript itself - - 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) { - Arrays.push(this.debugMessages, message); - }, - - displayDebug: function() { - alert(this.debugMessages.join(newLine)); - }, - - warn: function() { - }, - - 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); - } - alert(alertMessage); - } - } - } - }; - log4javascript.logLog = logLog; - - log4javascript.setEventTypes(["load", "error"]); - - function handleError(message, exception) { - logLog.error(message, exception); - log4javascript.dispatchEvent("error", { "message": message, "exception": exception }); - } - - log4javascript.handleError = handleError; - - /* ---------------------------------------------------------------------- */ - - var enabled = !((typeof global.log4javascript_disabled !== "undefined") && - global.log4javascript_disabled); - - log4javascript.setEnabled = function(enable) { - enabled = !!enable; - }; - - log4javascript.isEnabled = function() { - return enabled; - }; - - var useTimeStampsInMilliseconds = true; - - log4javascript.setTimeStampsInMilliseconds = function(timeStampsInMilliseconds) { - useTimeStampsInMilliseconds = !!timeStampsInMilliseconds; - }; - - log4javascript.isTimeStampsInMilliseconds = function() { - return useTimeStampsInMilliseconds; - }; - - - // This evaluates the given expression in the current scope, thus allowing - // scripts to access private variables. Particularly useful for testing - log4javascript.evalInScope = function(expr) { - return eval(expr); - }; - - var showStackTraces = false; - - log4javascript.setShowStackTraces = function(show) { - showStackTraces = !!show; - }; - - /* ---------------------------------------------------------------------- */ - // Levels - - 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; - - /* ---------------------------------------------------------------------- */ - // Timers - - function Timer(name, level) { - this.name = name; - this.level = level || Level.INFO; - this.start = new Date(); - } - - Timer.prototype.getElapsedTime = function() { - return new Date().getTime() - this.start.getTime(); - }; - - /* ---------------------------------------------------------------------- */ - // Renderers - - function Renderer(testFn, renderFn) { - this.shouldRender = testFn; - this.doRender = renderFn; - } - - var renderers = []; - - Renderer.forInstancesOf = function(constructorFn, renderFn) { - return new Renderer( - function(obj) { - return obj instanceof constructorFn; - }, - renderFn - ); - }; - - function render(obj) { - var i = renderers.length, renderer; - while (i--) { - renderer = renderers[i]; - if (renderer.shouldRender(obj)) { - return renderer.doRender(obj); - } - } - return null; - } - - log4javascript.addRenderer = function(testFn, renderFn) { - Arrays.push( renderers, new Renderer(testFn, renderFn) ); - }; - - log4javascript.addRendererForInstancesOf = function(constructorFn, renderFn) { - Arrays.push( renderers, Renderer.forInstancesOf(constructorFn, renderFn) ); - }; - - /* ---------------------------------------------------------------------- */ - // Loggers - - var anonymousLoggerName = "[anonymous]"; - 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; - - // Additivity - var additive = true; - this.getAdditivity = function() { - return additive; - }; - - this.setAdditivity = function(additivity) { - var valueChanged = (additive != additivity); - additive = additivity; - if (valueChanged) { - this.invalidateAppenderCache(); - } - }; - - // Create methods that use the appenders variable in this scope - 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 (!Arrays.contains(appenders, appender)) { - Arrays.push(appenders, appender); - appender.setAddedToLogger(this); - this.invalidateAppenderCache(); - } - } else { - handleError("Logger.addAppender: appender supplied ('" + - toStr(appender) + "') is not a subclass of Appender"); - } - } - }; - - this.removeAppender = function(appender) { - Arrays.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); - } - appenders.length = 0; - this.invalidateAppenderCache(); - } - }; - - this.getEffectiveAppenders = function() { - if (appenderCache === null || appenderCacheInvalidated) { - // Build appender cache - var parentEffectiveAppenders = (isRoot || !this.getAdditivity()) ? - [] : this.parent.getEffectiveAppenders(); - appenderCache = parentEffectiveAppenders.concat(appenders); - appenderCacheInvalidated = false; - } - 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) { - var exception, finalParamIndex, lastParam, messages, date, loggingEvent, i; - if (enabled && level.isGreaterOrEqual(this.getEffectiveLevel())) { - date = new Date(); - - // Check whether last param is an exception - finalParamIndex = params.length - 1; - lastParam = params[finalParamIndex]; - if (params.length > 1 && isError(lastParam)) { - exception = lastParam; - finalParamIndex--; - } - - // Construct genuine array for the params - messages = []; - for (i = 0; i <= finalParamIndex; i++) { - messages[i] = params[i]; - } - - loggingEvent = new LoggingEvent(this, date, level, messages, exception); - this.callAppenders(loggingEvent); - } - }; - - this.setLevel = function(level) { - // Having a level of null on the root logger would be very bad. - 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 " + - this.name + " is not an instance of log4javascript.Level"); - } - }; - - this.getLevel = function() { - return loggerLevel; - }; - - 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 " + - name + " is not an instance of log4javascript.Level"); - } else { - timers[name] = new Timer(name, level); - } - } - }; - - this.timeEnd = function(name) { - var timer, milliseconds; - if (enabled) { - if (isUndefined(name)) { - handleError("Logger.timeEnd: a name for the timer must be supplied"); - } else if (timers[name]) { - timer = timers[name]; - milliseconds = timer.getElapsedTime(); - this.log(timer.level, ["Timer \"" + toStr(name) + "\" completed in " + milliseconds + "ms"]); - timers[name] = null; - } else { - logLog.warn("Logger.timeEnd: no timer found with name \"" + name + "\""); - } - } - }; - } - - Logger.prototype = { - isEnabledFor: function(level) { - return level.isGreaterOrEqual(this.getEffectiveLevel()); - }, - - addChild: function(childLogger) { - Arrays.push(this.children, childLogger); - childLogger.parent = this; - childLogger.invalidateAppenderCache(); - }, - - callAppenders: function(loggingEvent) { - var effectiveAppenders = this.getEffectiveAppenders(); - var i = effectiveAppenders.length; - while (i--) { - effectiveAppenders[i].doAppend(loggingEvent); - } - }, - - getEffectiveLevel: function() { - for (var logger = this; logger !== null; logger = logger.parent) { - var level = logger.getLevel(); - if (level !== null) { - return level; - } - } - }, - - group: function(name, initiallyExpanded) { - var effectiveAppenders, i; - if (enabled) { - effectiveAppenders = this.getEffectiveAppenders(); - i = effectiveAppenders.length; - while (i--) { - effectiveAppenders[i].group(name, initiallyExpanded); - } - } - }, - - groupEnd: function() { - var effectiveAppenders, i; - if (enabled) { - effectiveAppenders = this.getEffectiveAppenders(); - i = effectiveAppenders.length; - while (i--) { - effectiveAppenders[i].groupEnd(); - } - } - }, - - assert: function(expr) { - var args, i, len; - if (enabled && !expr) { - args = []; - for (i = 1, len = arguments.length; i < len; i++) { - Arrays.push(args, arguments[i]); - } - args = (args.length > 0) ? args : ["Assertion Failure"]; - Arrays.push(args, newLine); - Arrays.push(args, expr); - this.log(Level.ERROR, args); - } - }, - - toString: function() { - return "Logger[" + this.name + "]"; - } - }; - - - // This has the benefits of being simple and working in all browsers. It's also quicker than the equivalent - // function using a regular expression in some browsers on my PC, and as the number of replaced tokens increases, - // this function gets more efficient relative to the regex equivalent. - function stringFormat(str, replacements) { - var formattedString = str; - - var i = replacements.length; - while (i--) { - formattedString = formattedString.replace("{" + i + "}", replacements[i]); - } - - return formattedString; - } - - (function() { - function createLevelMethods(levelName) { - var upper = levelName.toUpperCase(), lower = levelName.toLowerCase(); - var level = Level[upper]; - Logger.prototype[lower] = function() { - this.log(level, arguments); - }; - Logger.prototype[lower + "Format"] = function() { - this.log( level, [ stringFormat( arguments[0], Array.prototype.slice.call(arguments, 1) ) ] ); - }; - Logger.prototype[ "is" + levelName + "Enabled" ] = function() { - return this.isEnabledFor(level); - }; - } - - var i, levelNames = ["Trace", "Debug", "Info", "Warn", "Error", "Fatal"]; - i = levelNames.length; - while (i--) { - createLevelMethods( levelNames[i] ); - } - })(); - - - /* ---------------------------------------------------------------------- */ - // Logger access methods - - // Hashtable of loggers keyed by logger name - 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) { - // Use anonymous logger if loggerName is not specified or invalid - if (!(typeof loggerName == "string")) { - loggerName = anonymousLoggerName; - logLog.warn("log4javascript.getLogger: non-string logger name " + - toStr(loggerName) + " supplied, returning anonymous logger"); - } - - // Do not allow retrieval of the root logger by name - if (loggerName == rootLoggerName) { - handleError("log4javascript.getLogger: root logger may not be obtained by name"); - } - - // Create the logger for this name if it doesn't already exist - if (!loggers[loggerName]) { - var logger = new Logger(loggerName); - loggers[loggerName] = logger; - Arrays.push(loggerNames, loggerName); - - // Set up parent logger, if it doesn't exist - var lastDotIndex = loggerName.lastIndexOf("."); - var parentLogger; - if (lastDotIndex > -1) { - var parentLoggerName = loggerName.substring(0, lastDotIndex); - parentLogger = log4javascript.getLogger(parentLoggerName); // Recursively sets up grandparents etc. - } else { - parentLogger = rootLogger; - } - parentLogger.addChild(logger); - } - return loggers[loggerName]; - }; - - var nullLogger = null; - log4javascript.getNullLogger = function() { - if (!nullLogger) { - nullLogger = new Logger(nullLoggerName); - nullLogger.setLevel(Level.OFF); - } - return nullLogger; - }; - - // Destroys all loggers - log4javascript.resetConfiguration = function() { - rootLogger.setLevel(ROOT_LOGGER_DEFAULT_LEVEL); - loggers = {}; - }; - - /* ---------------------------------------------------------------------- */ - // Logging events - - 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); - }, - - getRenderedMessages: function() { - var renderedMessages = []; - for (var i = 0, len = this.messages.length; i < len; i++) { - renderedMessages[i] = render(this.messages[i]); - } - return renderedMessages; - }, - - getCombinedRenderedMessages: function() { - return (this.messages.length === 1) ? render(this.messages[0]) : - this.getRenderedMessages().join(newLine); - }, - - toString: function() { - return "LoggingEvent[" + this.level + "]"; - } - }; - - log4javascript.LoggingEvent = LoggingEvent; - - /* ---------------------------------------------------------------------- */ - // Layout prototype - - 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()) { - Arrays.push(dataValues, [this.millisecondsKey, loggingEvent.milliseconds]); - } - if (loggingEvent.exception) { - Arrays.push(dataValues, [this.exceptionKey, getExceptionStringRep(loggingEvent.exception)]); - } - if (this.hasCustomFields()) { - for (var i = 0, len = this.customFields.length; i < len; i++) { - var val = this.customFields[i].value; - - // Check if the value is a function. If so, execute it, passing it the - // current layout and the logging event - if (typeof val === "function") { - val = val(this, loggingEvent); - } - Arrays.push(dataValues, [this.customFields[i].name, val]); - } - } - 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; - } - } - if (!fieldUpdated) { - Arrays.push(this.customFields, {"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; - - /* ---------------------------------------------------------------------- */ - // Appender prototype - - var Appender = function() {}; - - Appender.prototype = new EventSupport(); - - Appender.prototype.layout = new PatternLayout(); - Appender.prototype.threshold = Level.ALL; - Appender.prototype.loggers = []; - - // Performs threshold checks before delegating actual logging to the - // subclass's specific append method. - 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 " + - 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 " + - this.toString() + " is not a subclass of Level"); - } - }; - - Appender.prototype.getThreshold = function() { - return this.threshold; - }; - - Appender.prototype.setAddedToLogger = function(logger) { - Arrays.push(this.loggers, logger); - }; - - Appender.prototype.setRemovedFromLogger = function(logger) { - Arrays.remove(this.loggers, logger); - }; - - Appender.prototype.group = function() { - logLog.warn("Appender.group: grouping not supported by this appender"); - }; - - Appender.prototype.groupEnd = function() { - logLog.warn("Appender.groupEnd: grouping not supported by this appender"); - }; - - Appender.prototype.toString = function() { - handleError("Appender.toString: all appenders must override this method"); - }; - - log4javascript.Appender = Appender; - - /* ---------------------------------------------------------------------- */ - // Default logger methods - - var defaultLoggerName = "[default]"; - var defaultLogger = null; - - function getDefaultPopUpLogger() { - if (!defaultLogger) { - defaultLogger = log4javascript.getLogger(defaultLoggerName); - var a = new log4javascript.PopUpAppender(); - defaultLogger.addAppender(a); - } - return defaultLogger; - } - - var defaultInPageLoggerName = "[default_in_page]"; - var defaultInPageLogger = null; - - function getDefaultInPageLogger() { - if (!defaultInPageLogger) { - defaultInPageLogger = log4javascript.getLogger(defaultInPageLoggerName); - var a = new log4javascript.InPageAppender(); - defaultInPageLogger.addAppender(a); - } - return defaultInPageLogger; - } - - log4javascript.getDefaultLogger = function(inPage) { - return inPage ? getDefaultInPageLogger() : getDefaultPopUpLogger(); - }; - - log4javascript.getDefaultInPageLogger = function() { - return getDefaultInPageLogger(); - }; - /* ---------------------------------------------------------------------- */ - // SimpleLayout - - function SimpleLayout() { - this.customFields = []; - } - - 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; - /* ----------------------------------------------------------------------- */ - // NullLayout - - function NullLayout() { - this.customFields = []; - } - - 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; -/* ---------------------------------------------------------------------- */ - // XmlLayout - - function XmlLayout(combineMessages) { - this.combineMessages = extractBooleanFromParam(combineMessages, true); - this.customFields = []; - } - - 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(/\]\]>/, "]]>]]>"; - } - - var str = "" + newLine; - if (this.combineMessages) { - str += formatMessage(loggingEvent.getCombinedMessages()); - } else { - str += "" + newLine; - for (i = 0, len = loggingEvent.messages.length; i < len; i++) { - str += formatMessage(loggingEvent.messages[i]) + newLine; - } - str += "" + newLine; - } - if (this.hasCustomFields()) { - for (i = 0, len = this.customFields.length; i < len; i++) { - str += "" + newLine; - } - } - if (loggingEvent.exception) { - str += "" + newLine; - } - str += "" + newLine + newLine; - return str; - }; - - XmlLayout.prototype.ignoresThrowable = function() { - return false; - }; - - XmlLayout.prototype.toString = function() { - return "XmlLayout"; - }; - - log4javascript.XmlLayout = XmlLayout; - /* ---------------------------------------------------------------------- */ - // JsonLayout related - - function escapeNewLines(str) { - return str.replace(/\r\n|\r|\n/g, "\\r\\n"); - } - - 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 = []; - } - - /* ---------------------------------------------------------------------- */ - // JsonLayout - - 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; - - function formatValue(val, prefix, expand) { - // Check the type of the data value to decide whether quotation marks - // or expansion are required - var formattedValue; - var valType = typeof val; - if (val instanceof Date) { - formattedValue = String(val.getTime()); - } else if (expand && (val instanceof Array)) { - formattedValue = "[" + layout.lineBreak; - for (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 += ","; - } - formattedValue += layout.lineBreak; - } - formattedValue += prefix + "]"; - } else if (valType !== "number" && valType !== "boolean") { - formattedValue = "\"" + escapeNewLines(toStr(val).replace(/\"/g, "\\\"")) + "\""; - } else { - formattedValue = val; - } - return formattedValue; - } - - for (i = 0, len = dataValues.length; i < len; i++) { - str += this.tab + "\"" + dataValues[i][0] + "\"" + this.colon + formatValue(dataValues[i][1], this.tab, true); - if (i < dataValues.length - 1) { - str += ","; - } - str += this.lineBreak; - } - - 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; - /* ---------------------------------------------------------------------- */ - // HttpPostDataLayout - - function HttpPostDataLayout() { - this.setKeys(); - this.customFields = []; - } - - HttpPostDataLayout.prototype = new Layout(); - HttpPostDataLayout.prototype.returnsPostData = true; - - // Disable batching - 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]; - Arrays.push(queryBits, urlEncode(dataValues[i][0]) + "=" + urlEncode(val)); - } - return queryBits.join("&"); - }; - - HttpPostDataLayout.prototype.ignoresThrowable = function(loggingEvent) { - return false; - }; - - HttpPostDataLayout.prototype.toString = function() { - return "HttpPostDataLayout"; - }; - - log4javascript.HttpPostDataLayout = HttpPostDataLayout; - /* ---------------------------------------------------------------------- */ - // formatObjectExpansion - - function ConsoleMessage(message) { - this.message = message; - } - - ConsoleMessage.prototype.toString = function() { - return this.message; - }; - - var formatObjectExpansion = (function() { - function PropertyExpansion(indentation, name) { - this.indentation = indentation; - this.name = name; - this.value = null; - } - - PropertyExpansion.prototype.toString = function() { - return this.indentation + this.name + ": " + this.value; - }; - - function propertyComparer(prop1, prop2) { - return (prop1.name === prop2.name) ? 0 : - ( (prop1.name > prop2.name) ? 1 : -1 ); - } - - function formatString(text, addQuotes, indentation) { - var lines = splitIntoLines(text); - for (var i = 1, len = lines.length; i < len; i++) { - lines[i] = indentation + lines[i]; - } - var str = lines.join(newLine); - return addQuotes ? '"' + str + '"' : str; - } - - function createFormattingContext(maxDepth, showMethods, alphabetical) { - return { - maxDepth: maxDepth, - objectsExpanded: [], - showMethods: showMethods, - alphabetical: alphabetical - }; - } - - function doFormat(obj, depth, indentation, quoteStrings, context) { - var i, len, childDepth, childIndentation, childLines, expansion, - childExpansion, isMethod, properties, methods; - - indentation = indentation || ""; - - // Check if there's a renderer that wants to handle this object first - var renderedObj = render(obj); - if (renderedObj !== null) { - return renderedObj; - } else if (obj === null) { - return "null"; - } else if (typeof obj === "undefined") { - return "undefined"; - } else if (obj instanceof ConsoleMessage) { - return obj.message; - } else if (typeof obj === "string") { - return formatString(obj, quoteStrings, indentation); - } else if (typeof obj === "function") { - return formatString(obj.toString(), false, indentation); - } else if (typeof obj === "object" && Arrays.contains(context.objectsExpanded, obj)) { - try { - expansion = toStr(obj); - } catch (ex) { - expansion = "(Error formatting property. Details: " + getExceptionStringRep(ex) + ")"; - } - return expansion + " (already expanded)"; - } else if ((obj instanceof Array) && depth > 0) { - Arrays.push(context.objectsExpanded, 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, true, context); - Arrays.push(childLines, childIndentation + childExpansion); - } catch (ex) { - Arrays.push(childLines, childIndentation + "(Error formatting array member. Details: " + - getExceptionStringRep(ex) + ")"); - } - } - expansion += childLines.join("," + newLine) + newLine + indentation + "]"; - return expansion; - } else if (typeof obj === "object" && depth > 0) { - Arrays.push(context.objectsExpanded, obj); - - expansion = "{" + newLine; - childDepth = depth - 1; - childIndentation = indentation + " "; - - // Separate the properties from the methods, filtering out methods if required - properties = []; - methods = []; - - for (i in obj) { - childExpansion = new PropertyExpansion(childIndentation, i); - isMethod = false; - - try { - isMethod = (typeof obj[i] === "function"); - if (!isMethod || context.showMethods) { - childExpansion.value = doFormat(obj[i], childDepth, childIndentation, true, context); - } - } catch (ex) { - childExpansion.value = "(Error formatting property. Details: " + - getExceptionStringRep(ex) + ")"; - } - Arrays.push( (isMethod ? methods : properties), childExpansion ); - } - - // Arrange the property names into alphabetical order, if required - if (context.alphabetical) { - properties.sort(propertyComparer); - methods.sort(propertyComparer); - } - properties = properties.concat(methods); - - expansion += properties.join("," + newLine) + newLine + indentation + "}"; - return expansion; - } else { - return formatString(toStr(obj), false, indentation); - } - } - - return function(obj, maxDepth, indentation, quoteStrings, alphabetical, showMethods) { - var context = createFormattingContext(maxDepth, showMethods, alphabetical); - return doFormat(obj, maxDepth, indentation, quoteStrings, context); - }; - })(); - - /* ---------------------------------------------------------------------- */ - // Date-related stuff - - 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; - }; - - function getUTCTime(d) { - return Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), - d.getSeconds(), d.getMilliseconds()); - } - - function getTimeSince(d1, d2) { - return getUTCTime(d1) - getUTCTime(d2); - } - - function getPreviousSunday(d) { - // Using midday avoids any possibility of DST messing things up - var midday = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 12, 0, 0); - var previousSunday = new Date(midday.getTime() - d.getDay() * ONE_DAY); - return newDateAtMidnight(previousSunday.getFullYear(), previousSunday.getMonth(), - previousSunday.getDate()); - } - - function getWeekInYear(d, minimalDaysInFirstWeek) { - if (isUndefined(minimalDaysInFirstWeek)) { - minimalDaysInFirstWeek = DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK; - } - var previousSunday = getPreviousSunday(d); - var startOfYear = newDateAtMidnight(d.getFullYear(), 0, 1); - var numberOfSundays = (previousSunday < startOfYear) ? - 0 : 1 + Math.floor(getTimeSince(previousSunday, startOfYear) / ONE_WEEK); - var numberOfDaysInFirstWeek = 7 - startOfYear.getDay(); - var weekInYear = numberOfSundays; - if (numberOfDaysInFirstWeek < minimalDaysInFirstWeek) { - weekInYear--; - } - return weekInYear; - } - - function getWeekInMonth(d, minimalDaysInFirstWeek) { - if (isUndefined(minimalDaysInFirstWeek)) { - minimalDaysInFirstWeek = DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK; - } - var previousSunday = getPreviousSunday(d); - var startOfMonth = newDateAtMidnight(d.getFullYear(), d.getMonth(), 1); - var numberOfSundays = (previousSunday < startOfMonth) ? - 0 : 1 + Math.floor(getTimeSince(previousSunday, startOfMonth) / ONE_WEEK); - var numberOfDaysInFirstWeek = 7 - startOfMonth.getDay(); - var weekInMonth = numberOfSundays; - if (numberOfDaysInFirstWeek >= minimalDaysInFirstWeek) { - weekInMonth++; - } - return weekInMonth; - } - - function getDayInYear(d) { - var startOfYear = newDateAtMidnight(d.getFullYear(), 0, 1); - return 1 + Math.floor(getTimeSince(d, startOfYear) / ONE_DAY); - } - - /* ------------------------------------------------------------------ */ - - function SimpleDateFormat(formatString) { - this.formatString = formatString; - }; - - /** - * Sets the minimum number of days in a week in order for that week to - * be considered as belonging to a particular month or year - */ - SimpleDateFormat.prototype.setMinimalDaysInFirstWeek = function(days) { - this.minimalDaysInFirstWeek = days; - }; - - SimpleDateFormat.prototype.getMinimalDaysInFirstWeek = function() { - return isUndefined(this.minimalDaysInFirstWeek) ? - DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK : this.minimalDaysInFirstWeek; - }; - - function formatText(data, numberOfLetters, minLength) { - return (numberOfLetters >= 4) ? data : data.substr(0, Math.max(minLength, numberOfLetters)); - } - - function formatNumber(data, numberOfLetters) { - var dataString = "" + data; - // Pad with 0s as necessary - return leftPad(dataString, numberOfLetters - dataString.length, "0"); - } - - SimpleDateFormat.prototype.format = function(date) { - var parts = []; - var result; - var searchString = this.formatString; - var dataString, prefix, absData, hours, minutes; - while ( (result = regex.exec(searchString)) ) { - var quotedString = result[1]; - var patternLetters = result[2]; - var otherLetters = result[3]; - var otherCharacters = result[4]; - - // If the pattern matched is quoted string, output the text between the quotes - if (quotedString) { - if (quotedString == "''") { - Arrays.push(parts, "'"); - } else { - Arrays.push(parts, quotedString.substring(1, quotedString.length - 1)); - } - } else if (otherLetters) { - // Swallow non-pattern letters by doing nothing here - } else if (otherCharacters) { - // Simply output other characters - Arrays.push(parts, otherCharacters); - } else if (patternLetters) { - // Replace pattern letters - 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 = getWeekInYear(date, this.getMinimalDaysInFirstWeek()); - break; - case "W": - rawData = getWeekInMonth(date, this.getMinimalDaysInFirstWeek()); - break; - case "D": - rawData = getDayInYear(date); - 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(); // This returns the number of minutes since GMT was this time. - break; - } - // Format the raw data depending on the type - switch(types[patternLetter]) { - case TEXT2: - Arrays.push(parts, formatText(rawData, numberOfLetters, 2)); - break; - case TEXT3: - Arrays.push(parts, formatText(rawData, numberOfLetters, 3)); - break; - case NUMBER: - Arrays.push(parts, formatNumber(rawData, numberOfLetters)); - break; - case YEAR: - if (numberOfLetters <= 3) { - // Output a 2-digit year - dataString = "" + rawData; - Arrays.push(parts, dataString.substr(2, 2)); - } else { - Arrays.push(parts, formatNumber(rawData, numberOfLetters)); - } - break; - case MONTH: - if (numberOfLetters >= 3) { - Arrays.push(parts, formatText(monthNames[rawData], numberOfLetters, numberOfLetters)); - } else { - // NB. Months returned by getMonth are zero-based - Arrays.push(parts, formatNumber(rawData + 1, numberOfLetters)); - } - break; - case TIMEZONE: - // The following line looks like a mistake but isn't - // because of the way getTimezoneOffset measures. - prefix = (rawData > 0) ? "-" : "+"; - absData = Math.abs(rawData); - - // Hours - hours = leftPad("" + Math.floor(absData / 60), 2, "0"); - - // Minutes - minutes = leftPad("" + (absData % 60), 2, "0"); - - Arrays.push(parts, prefix + hours + minutes); - break; - } - } - searchString = searchString.substr(result.index + result[0].length); - } - return parts.join(""); - }; - - return SimpleDateFormat; - })(); - - log4javascript.SimpleDateFormat = SimpleDateFormat; - - /* ---------------------------------------------------------------------- */ - // PatternLayout - - function PatternLayout(pattern) { - if (pattern) { - this.pattern = pattern; - } else { - this.pattern = PatternLayout.DEFAULT_CONVERSION_PATTERN; - } - this.customFields = []; - } - - 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 parts = []; - var result; - var searchString = this.pattern; - var i, len, l, replacement, replacementParts, replacementLen, depth; - var matchedString, padding, truncation, conversionCharacter, specifier, text; - - // Cannot use regex global flag since it doesn't work with exec in IE5 - while ( (result = regex.exec(searchString)) ) { - matchedString = result[0]; - padding = result[1]; - truncation = result[2]; - conversionCharacter = result[3]; - specifier = result[5]; - text = result[6]; - - // Check if the pattern matched was just normal text - if (text) { - Arrays.push(parts, text); - } else { - // Create a raw replacement string based on the conversion - // character and specifier - replacement = ""; - switch(conversionCharacter) { - case "a": // Array of messages - case "m": // Message - depth = 0; - replacementParts = []; - if (specifier) { - depth = parseInt(specifier, 10); - if (isNaN(depth)) { - handleError("PatternLayout.format: invalid specifier '" + - specifier + "' for conversion character '" + conversionCharacter + - "' - should be a number"); - depth = 0; - } - } - var messages = (conversionCharacter === "a") ? loggingEvent.messages[0] : loggingEvent.messages; - for (i = 0, len = messages.length; i < len; i++) { - if (depth === 0) { - Arrays.push(replacementParts, messages[i]); - } else { - Arrays.push(replacementParts, formatObjectExpansion(messages[i], depth, "", false, true, true)); - } - } - replacement = replacementParts.join(" "); - break; - case "c": // Logger name - 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; - } - break; - case "d": // Date - var dateFormat = PatternLayout.ISO8601_DATEFORMAT; - if (specifier) { - dateFormat = specifier; - // Pick up special cases - if (dateFormat == "ISO8601") { - dateFormat = PatternLayout.ISO8601_DATEFORMAT; - } else if (dateFormat == "ABSOLUTE") { - dateFormat = PatternLayout.ABSOLUTETIME_DATEFORMAT; - } else if (dateFormat == "DATE") { - dateFormat = PatternLayout.DATETIME_DATEFORMAT; - } - } - // Format the date - replacement = new SimpleDateFormat(dateFormat).format(loggingEvent.timeStamp); - break; - case "f": // Custom field - if (this.hasCustomFields()) { - var fieldIndex = 0; - if (specifier) { - fieldIndex = parseInt(specifier, 10); - if (isNaN(fieldIndex)) { - handleError("PatternLayout.format: invalid specifier '" + - specifier + "' for conversion character 'f' - should be a number"); - } else if (fieldIndex === 0) { - handleError("PatternLayout.format: invalid specifier '" + - specifier + "' for conversion character 'f' - must be greater than zero"); - } else if (fieldIndex > this.customFields.length) { - handleError("PatternLayout.format: invalid specifier '" + - specifier + "' for conversion character 'f' - there aren't that many custom fields"); - } else { - fieldIndex = fieldIndex - 1; - } - } - replacement = this.customFields[fieldIndex].value; - } - break; - case "n": // New line - replacement = newLine; - break; - case "p": // Level - replacement = loggingEvent.level.name; - break; - case "r": // Milliseconds since log4javascript startup - replacement = "" + (loggingEvent.timeStamp - applicationStartDate); - break; - case "%": // Literal % sign - replacement = "%"; - break; - default: - replacement = matchedString; - break; - } - // Format the replacement according to any padding or - // truncation specified - - // First, truncation - if (truncation) { - l = parseInt(truncation.substr(1), 10); - var strLen = replacement.length; - if (l < strLen) { - replacement = replacement.substring(strLen - l, strLen); - } - } - // Next, padding - if (padding) { - if (padding.charAt(0) == "-") { - l = parseInt(padding.substr(1), 10); - replacementLen = replacement.length; - // Right pad with spaces - if (replacementLen < l) { - replacement = rightPad(replacement, l - replacementLen, " "); - } - } else { - l = parseInt(padding, 10); - replacementLen = replacement.length; - // Left pad with spaces - while (replacement.length < l) { - replacement = leftPad(replacement, l - replacementLen, " "); - } - } - } - Arrays.push(parts, replacement); - } - searchString = searchString.substr(result.index + result[0].length); - } - return parts.join(""); - }; - - PatternLayout.prototype.ignoresThrowable = function() { - return true; - }; - - PatternLayout.prototype.toString = function() { - return "PatternLayout"; - }; - - log4javascript.PatternLayout = PatternLayout; - /* ---------------------------------------------------------------------- */ - // AlertAppender - - function AlertAppender() {} - - AlertAppender.prototype = new Appender(); - - AlertAppender.prototype.layout = new SimpleLayout(); - - AlertAppender.prototype.append = function(loggingEvent) { - var formattedMessage = this.getLayout().format(loggingEvent); - if (this.getLayout().ignoresThrowable()) { - formattedMessage += loggingEvent.getThrowableStrRep(); - } - alert(formattedMessage); - }; - - AlertAppender.prototype.toString = function() { - return "AlertAppender"; - }; - - log4javascript.AlertAppender = AlertAppender; - /* ---------------------------------------------------------------------- */ - // BrowserConsoleAppender (only works in Opera and Safari and Firefox with - // Firebug extension) - - function BrowserConsoleAppender() {} - - BrowserConsoleAppender.prototype = new log4javascript.Appender(); - BrowserConsoleAppender.prototype.layout = new NullLayout(); - BrowserConsoleAppender.prototype.threshold = Level.DEBUG; - - BrowserConsoleAppender.prototype.append = function(loggingEvent) { - var appender = this; - var formattedMesage, console; - - var getFormattedMessage = function() { - var layout = appender.getLayout(); - var formattedMessage = layout.format(loggingEvent); - if (layout.ignoresThrowable() && loggingEvent.exception) { - formattedMessage += loggingEvent.getThrowableStrRep(); - } - return formattedMessage; - }; - - if ((typeof window.opera != "undefined") && window.opera.postError) { // Opera - window.opera.postError(getFormattedMessage()); - } else if (window.console && window.console.log) { // Safari and Firebug - console = window.console; - formattedMesage = getFormattedMessage(); - // Log to Firebug using its logging methods or revert to the console.log - // method in Safari - if (console.debug && Level.DEBUG.isGreaterOrEqual(loggingEvent.level)) { - console.debug(formattedMesage); - } else if (console.info && Level.INFO.equals(loggingEvent.level)) { - console.info(formattedMesage); - } else if (console.warn && Level.WARN.equals(loggingEvent.level)) { - console.warn(formattedMesage); - } else if (console.error && loggingEvent.level.isGreaterOrEqual(Level.ERROR)) { - console.error(formattedMesage); - } else { - console.log(formattedMesage); - } - } - }; - - BrowserConsoleAppender.prototype.group = function(name) { - if (window.console && window.console.group) { - window.console.group(name); - } - }; - - BrowserConsoleAppender.prototype.groupEnd = function() { - if (window.console && window.console.groupEnd) { - window.console.groupEnd(); - } - }; - - BrowserConsoleAppender.prototype.toString = function() { - return "BrowserConsoleAppender"; - }; - - log4javascript.BrowserConsoleAppender = BrowserConsoleAppender; - /* ---------------------------------------------------------------------- */ - // AjaxAppender related - - var xmlHttpFactories = [ - function() { return new XMLHttpRequest(); }, - function() { return new ActiveXObject("Msxml2.XMLHTTP"); }, - function() { return new ActiveXObject("Microsoft.XMLHTTP"); } - ]; - - var getXmlHttp = function(errorHandler) { - // This is only run the first time; the value of getXmlHttp gets - // replaced with the factory that succeeds on the first run - 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) { - } - } - // If we're here, all factories have failed, so throw an error - 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)); - } - - /* ---------------------------------------------------------------------- */ - // AjaxAppender - - function AjaxAppender(url) { - var appender = this; - var isSupported = true; - if (!url) { - handleError("AjaxAppender: URL must be specified in constructor"); - isSupported = false; - } - - 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 sessionId = null; - - var queuedLoggingEvents = []; - var queuedRequests = []; - var sending = false; - var initialized = false; - - // Configuration methods. The function scope is used to prevent - // direct alteration to the appender configuration properties. - function checkCanConfigure(configOptionName) { - if (initialized) { - handleError("AjaxAppender: configuration option '" + - configOptionName + - "' may not be set after the appender has been initialized"); - return false; - } - return true; - } - - 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; - // Set the session id as a custom field on the layout, if not already present - 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 = extractIntFromParam(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); - } - }; - - // Internal functions - function sendAll() { - if (isSupported && enabled) { - sending = true; - var currentRequestBatch; - if (waitForResponse) { - // Send the first request then use this function as the callback once - // the response comes back - if (queuedRequests.length > 0) { - currentRequestBatch = Arrays.shift(queuedRequests); - sendRequest(preparePostData(currentRequestBatch), sendAll); - } else { - sending = false; - if (timed) { - scheduleSending(); - } - } - } else { - // Rattle off all the requests without waiting to see the response - while ( (currentRequestBatch = Arrays.shift(queuedRequests)) ) { - sendRequest(preparePostData(currentRequestBatch)); - } - sending = false; - if (timed) { - scheduleSending(); - } - } - } - } - - this.sendAll = sendAll; - - // Called when the window unloads. At this point we're past caring about - // waiting for responses or timers or incomplete batches - everything - // must go, now - function sendAllRemaining() { - if (isSupported && enabled) { - // Create requests for everything left over, batched as normal - var actualBatchSize = appender.getLayout().allowBatching() ? batchSize : 1; - var currentLoggingEvent; - var postData = ""; - var batchedLoggingEvents = []; - while ((currentLoggingEvent = Arrays.shift(queuedLoggingEvents))) { - Arrays.push(batchedLoggingEvents, currentLoggingEvent); - if (queuedLoggingEvents.length >= actualBatchSize) { - // Queue this batch of log entries - Arrays.push(queuedRequests, batchedLoggingEvents); - batchedLoggingEvents = []; - } - } - // If there's a partially completed batch, add it - if (batchedLoggingEvents.length > 0) { - Arrays.push(queuedRequests, batchedLoggingEvents); - } - waitForResponse = false; - timed = false; - sendAll(); - } - } - - function preparePostData(batchedLoggingEvents) { - // Format the logging events - var formattedMessages = []; - var currentLoggingEvent; - var postData = ""; - while ((currentLoggingEvent = Arrays.shift(batchedLoggingEvents))) { - var currentFormattedMessage = appender.getLayout().format(currentLoggingEvent); - if (appender.getLayout().ignoresThrowable()) { - currentFormattedMessage += loggingEvent.getThrowableStrRep(); - } - Arrays.push(formattedMessages, currentFormattedMessage); - } - // Create the post data string - if (batchedLoggingEvents.length == 1) { - postData = formattedMessages.join(""); - } else { - postData = appender.getLayout().batchHeader + - formattedMessages.join(appender.getLayout().batchSeparator) + - appender.getLayout().batchFooter; - } - postData = appender.getLayout().returnsPostData ? postData : - urlEncode(postVarName) + "=" + urlEncode(postData); - // Add the layout name to the post data - if (postData.length > 0) { - postData += "&"; - } - return postData + "layout=" + urlEncode(appender.getLayout().toString()); - } - - function scheduleSending() { - setTimeout(sendAll, timerInterval); - } - - function xmlHttpErrorHandler() { - var msg = "AjaxAppender: could not create XMLHttpRequest object. AjaxAppender disabled"; - handleError(msg); - isSupported = false; - if (failCallback) { - failCallback(msg); - } - } - - function sendRequest(postData, successCallback) { - try { - var xmlHttp = getXmlHttp(xmlHttpErrorHandler); - if (isSupported) { - if (xmlHttp.overrideMimeType) { - xmlHttp.overrideMimeType(appender.getLayout().getContentType()); - } - xmlHttp.onreadystatechange = function() { - if (xmlHttp.readyState == 4) { - if (isHttpRequestSuccessful(xmlHttp)) { - if (requestSuccessCallback) { - requestSuccessCallback(xmlHttp); - } - if (successCallback) { - successCallback(xmlHttp); - } - } else { - var msg = "AjaxAppender.append: XMLHttpRequest request to URL " + - url + " returned status code " + xmlHttp.status; - handleError(msg); - if (failCallback) { - failCallback(msg); - } - } - xmlHttp.onreadystatechange = emptyFunction; - xmlHttp = null; - } - }; - xmlHttp.open("POST", url, true); - try { - xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); - } 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); - } - return; - } - 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)); - } - } - } - - this.append = function(loggingEvent) { - if (isSupported) { - if (!initialized) { - init(); - } - Arrays.push(queuedLoggingEvents, loggingEvent); - var actualBatchSize = this.getLayout().allowBatching() ? batchSize : 1; - - if (queuedLoggingEvents.length >= actualBatchSize) { - var currentLoggingEvent; - var batchedLoggingEvents = []; - while ( (currentLoggingEvent = Arrays.shift(queuedLoggingEvents)) ) { - Arrays.push(batchedLoggingEvents, currentLoggingEvent); - } - // Queue this batch of log entries - Arrays.push(queuedRequests, batchedLoggingEvents); - - // If using a timer, the queue of requests will be processed by the - // timer function, so nothing needs to be done here. - if (!timed && (!waitForResponse || (waitForResponse && !sending))) { - sendAll(); - } - } - } - }; - - function init() { - initialized = true; - // Add unload event to send outstanding messages - if (sendAllOnUnload) { - addEvent(window, "unload", sendAllRemaining); - } - // Start timer - if (timed) { - scheduleSending(); - } - } - } - - AjaxAppender.prototype = new Appender(); - - AjaxAppender.prototype.defaults = { - waitForResponse: false, - timed: false, - timerInterval: 1000, - batchSize: 1, - sendAllOnUnload: true, - requestSuccessCallback: null, - failCallback: null, - postVarName: "data" - }; - - AjaxAppender.prototype.layout = new HttpPostDataLayout(); - - AjaxAppender.prototype.toString = function() { - return "AjaxAppender"; - }; - - log4javascript.AjaxAppender = AjaxAppender; - /* ---------------------------------------------------------------------- */ - // PopUpAppender and InPageAppender related - - function setCookie(name, value, days, path) { - var expires; - path = path ? "; path=" + path : ""; - if (days) { - var date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = "; expires=" + date.toGMTString(); - } else { - expires = ""; - } - document.cookie = escape(name) + "=" + escape(value) + expires + path; - } - - function getCookie(name) { - var nameEquals = escape(name) + "="; - var ca = document.cookie.split(";"); - for (var i = 0, len = ca.length; i < len; i++) { - var c = ca[i]; - while (c.charAt(0) === " ") { - c = c.substring(1, c.length); - } - if (c.indexOf(nameEquals) === 0) { - return unescape(c.substring(nameEquals.length, c.length)); - } - } - return null; - } - - // Gets the base URL of the location of the log4javascript script. - // This is far from infallible. - function getBaseUrl() { - var scripts = document.getElementsByTagName("script"); - for (var i = 0, len = scripts.length; i < len; ++i) { - if (scripts[i].src.indexOf("log4javascript") != -1) { - var lastSlash = scripts[i].src.lastIndexOf("/"); - return (lastSlash == -1) ? "" : scripts[i].src.substr(0, lastSlash + 1); - } - } - return null; - } - - function isLoaded(win) { - try { - return bool(win.loaded); - } catch (ex) { - return false; - } - } - - /* ---------------------------------------------------------------------- */ - // ConsoleAppender (prototype for PopUpAppender and InPageAppender) - - var ConsoleAppender; - - // Create an anonymous function to protect base console methods - (function() { - var getConsoleHtmlLines = function() { - return [ -'', -'', -' ', -' log4javascript', -' ', -' ', -' ', -' ', -' ', -' ', -' ', -' ', -' ', -'', -' ', -'
', -'
', -'
', -' Filters:', -' ', -' ', -' ', -' ', -' ', -' ', -' ', -'
', -' ', -'
', -' Options:', -' ', -' ', -' ', -' ', -' ', -' ', -' ', -'
', -'
', -'
', -'
', -'
', -'
', -' ', -' ', -'
', -'
', -' ', -'', -'' -]; - }; - - var defaultCommandLineFunctions = []; - - ConsoleAppender = function() {}; - - var consoleAppenderIdCounter = 1; - ConsoleAppender.prototype = new Appender(); - - ConsoleAppender.prototype.create = function(inPage, container, - lazyInit, initiallyMinimized, useDocumentWrite, width, height, focusConsoleWindow) { - var appender = this; - - // Common properties - var initialized = false; - var consoleWindowCreated = false; - var consoleWindowLoaded = false; - var consoleClosed = false; - - var queuedLoggingEvents = []; - var isSupported = true; - var consoleAppenderId = consoleAppenderIdCounter++; - - // Local variables - initiallyMinimized = extractBooleanFromParam(initiallyMinimized, this.defaults.initiallyMinimized); - lazyInit = extractBooleanFromParam(lazyInit, this.defaults.lazyInit); - useDocumentWrite = extractBooleanFromParam(useDocumentWrite, this.defaults.useDocumentWrite); - var newestMessageAtTop = this.defaults.newestMessageAtTop; - var scrollToLatestMessage = this.defaults.scrollToLatestMessage; - width = width ? width : this.defaults.width; - height = height ? height : this.defaults.height; - var maxMessages = this.defaults.maxMessages; - var showCommandLine = this.defaults.showCommandLine; - var commandLineObjectExpansionDepth = this.defaults.commandLineObjectExpansionDepth; - var showHideButton = this.defaults.showHideButton; - var showCloseButton = this.defaults.showCloseButton; - - this.setLayout(this.defaults.layout); - - // Functions whose implementations vary between subclasses - var init, createWindow, safeToAppend, getConsoleWindow, open; - - // Configuration methods. The function scope is used to prevent - // direct alteration to the appender configuration properties. - var appenderName = inPage ? "InPageAppender" : "PopUpAppender"; - var checkCanConfigure = function(configOptionName) { - if (consoleWindowCreated) { - handleError(appenderName + ": configuration option '" + configOptionName + "' may not be set after the appender has been initialized"); - return false; - } - return true; - }; - - var consoleWindowExists = function() { - return (consoleWindowLoaded && isSupported && !consoleClosed); - }; - - this.isNewestMessageAtTop = function() { return newestMessageAtTop; }; - this.setNewestMessageAtTop = function(newestMessageAtTopParam) { - newestMessageAtTop = bool(newestMessageAtTopParam); - if (consoleWindowExists()) { - getConsoleWindow().setNewestAtTop(newestMessageAtTop); - } - }; - - this.isScrollToLatestMessage = function() { return scrollToLatestMessage; }; - this.setScrollToLatestMessage = function(scrollToLatestMessageParam) { - scrollToLatestMessage = bool(scrollToLatestMessageParam); - if (consoleWindowExists()) { - getConsoleWindow().setScrollToLatest(scrollToLatestMessage); - } - }; - - this.getWidth = function() { return width; }; - this.setWidth = function(widthParam) { - if (checkCanConfigure("width")) { - width = extractStringFromParam(widthParam, width); - } - }; - - this.getHeight = function() { return height; }; - this.setHeight = function(heightParam) { - if (checkCanConfigure("height")) { - height = extractStringFromParam(heightParam, height); - } - }; - - this.getMaxMessages = function() { return maxMessages; }; - this.setMaxMessages = function(maxMessagesParam) { - maxMessages = extractIntFromParam(maxMessagesParam, maxMessages); - if (consoleWindowExists()) { - getConsoleWindow().setMaxMessages(maxMessages); - } - }; - - this.isShowCommandLine = function() { return showCommandLine; }; - this.setShowCommandLine = function(showCommandLineParam) { - showCommandLine = bool(showCommandLineParam); - if (consoleWindowExists()) { - getConsoleWindow().setShowCommandLine(showCommandLine); - } - }; - - this.isShowHideButton = function() { return showHideButton; }; - this.setShowHideButton = function(showHideButtonParam) { - showHideButton = bool(showHideButtonParam); - if (consoleWindowExists()) { - getConsoleWindow().setShowHideButton(showHideButton); - } - }; - - this.isShowCloseButton = function() { return showCloseButton; }; - this.setShowCloseButton = function(showCloseButtonParam) { - showCloseButton = bool(showCloseButtonParam); - if (consoleWindowExists()) { - getConsoleWindow().setShowCloseButton(showCloseButton); - } - }; - - this.getCommandLineObjectExpansionDepth = function() { return commandLineObjectExpansionDepth; }; - this.setCommandLineObjectExpansionDepth = function(commandLineObjectExpansionDepthParam) { - commandLineObjectExpansionDepth = extractIntFromParam(commandLineObjectExpansionDepthParam, commandLineObjectExpansionDepth); - }; - - var minimized = initiallyMinimized; - this.isInitiallyMinimized = function() { return initiallyMinimized; }; - this.setInitiallyMinimized = function(initiallyMinimizedParam) { - if (checkCanConfigure("initiallyMinimized")) { - initiallyMinimized = bool(initiallyMinimizedParam); - minimized = initiallyMinimized; - } - }; - - this.isUseDocumentWrite = function() { return useDocumentWrite; }; - this.setUseDocumentWrite = function(useDocumentWriteParam) { - if (checkCanConfigure("useDocumentWrite")) { - useDocumentWrite = bool(useDocumentWriteParam); - } - }; - - // Common methods - function QueuedLoggingEvent(loggingEvent, formattedMessage) { - this.loggingEvent = loggingEvent; - this.levelName = loggingEvent.level.name; - this.formattedMessage = formattedMessage; - } - - QueuedLoggingEvent.prototype.append = function() { - getConsoleWindow().log(this.levelName, this.formattedMessage); - }; - - function QueuedGroup(name, initiallyExpanded) { - this.name = name; - this.initiallyExpanded = initiallyExpanded; - } - - QueuedGroup.prototype.append = function() { - getConsoleWindow().group(this.name, this.initiallyExpanded); - }; - - function QueuedGroupEnd() {} - - QueuedGroupEnd.prototype.append = function() { - getConsoleWindow().groupEnd(); - }; - - var checkAndAppend = function() { - // Next line forces a check of whether the window has been closed - safeToAppend(); - if (!initialized) { - init(); - } else if (consoleClosed && reopenWhenClosed) { - createWindow(); - } - if (safeToAppend()) { - appendQueuedLoggingEvents(); - } - }; - - this.append = function(loggingEvent) { - if (isSupported) { - // Format the message - var formattedMessage = appender.getLayout().format(loggingEvent); - if (this.getLayout().ignoresThrowable()) { - formattedMessage += loggingEvent.getThrowableStrRep(); - } - Arrays.push(queuedLoggingEvents, new QueuedLoggingEvent(loggingEvent, formattedMessage)); - checkAndAppend(); - } - }; - - this.group = function(name, initiallyExpanded) { - if (isSupported) { - Arrays.push(queuedLoggingEvents, new QueuedGroup(name, initiallyExpanded)); - checkAndAppend(); - } - }; - - this.groupEnd = function() { - if (isSupported) { - Arrays.push(queuedLoggingEvents, new QueuedGroupEnd()); - checkAndAppend(); - } - }; - - var appendQueuedLoggingEvents = function() { - while (queuedLoggingEvents.length > 0) { - Arrays.shift(queuedLoggingEvents).append(); - } - if (focusConsoleWindow) { - getConsoleWindow().focus(); - } - }; - - this.setAddedToLogger = function(logger) { - Arrays.push(this.loggers, logger); - if (enabled && !lazyInit) { - init(); - } - }; - - this.clear = function() { - if (consoleWindowExists()) { - getConsoleWindow().clearLog(); - } - queuedLoggingEvents.length = 0; - }; - - this.focus = function() { - if (consoleWindowExists()) { - getConsoleWindow().focus(); - } - }; - - this.focusCommandLine = function() { - if (consoleWindowExists()) { - getConsoleWindow().focusCommandLine(); - } - }; - - this.focusSearch = function() { - if (consoleWindowExists()) { - getConsoleWindow().focusSearch(); - } - }; - - var commandWindow = window; - - this.getCommandWindow = function() { return commandWindow; }; - this.setCommandWindow = function(commandWindowParam) { - commandWindow = commandWindowParam; - }; - - this.executeLastCommand = function() { - if (consoleWindowExists()) { - getConsoleWindow().evalLastCommand(); - } - }; - - var commandLayout = new PatternLayout("%m"); - this.getCommandLayout = function() { return commandLayout; }; - this.setCommandLayout = function(commandLayoutParam) { - commandLayout = commandLayoutParam; - }; - - this.evalCommandAndAppend = function(expr) { - var commandReturnValue = { appendResult: true, isError: false, isMessage: false }; - var commandOutput = ""; - // Evaluate the command - try { - var result, i; - // The next three lines constitute a workaround for IE. Bizarrely, iframes seem to have no - // eval method on the window object initially, but once execScript has been called on - // it once then the eval method magically appears. See http://www.thismuchiknow.co.uk/?p=25 - if (!commandWindow.eval && commandWindow.execScript) { - commandWindow.execScript("null"); - } - - var commandLineFunctionsHash = {}; - for (i = 0, len = commandLineFunctions.length; i < len; i++) { - commandLineFunctionsHash[commandLineFunctions[i][0]] = commandLineFunctions[i][1]; - } - - // Keep an array of variables that are being changed in the command window so that they - // can be restored to their original values afterwards - var objectsToRestore = []; - var addObjectToRestore = function(name) { - Arrays.push(objectsToRestore, [name, commandWindow[name]]); - }; - - addObjectToRestore("appender"); - commandWindow.appender = appender; - - addObjectToRestore("commandReturnValue"); - commandWindow.commandReturnValue = commandReturnValue; - - addObjectToRestore("commandLineFunctionsHash"); - commandWindow.commandLineFunctionsHash = commandLineFunctionsHash; - - var addFunctionToWindow = function(name) { - addObjectToRestore(name); - commandWindow[name] = function() { - return this.commandLineFunctionsHash[name](appender, arguments, commandReturnValue); - }; - }; - - for (i = 0, len = commandLineFunctions.length; i < len; i++) { - addFunctionToWindow(commandLineFunctions[i][0]); - } - - // Another bizarre workaround to get IE to eval in the global scope - if (commandWindow === window && commandWindow.execScript) { - addObjectToRestore("evalExpr"); - addObjectToRestore("result"); - window.evalExpr = expr; - commandWindow.execScript("window.result=eval(window.evalExpr);"); - result = window.result; - } else { - result = commandWindow.eval(expr); - } - //commandOutput = isUndefined(result) ? result : formatObjectExpansion(result, commandLineObjectExpansionDepth); - commandOutput = formatObjectExpansion(result, commandLineObjectExpansionDepth, "", true, true, true); - - // Restore variables in the command window to their original state - for (i = 0, len = objectsToRestore.length; i < len; i++) { - commandWindow[objectsToRestore[i][0]] = objectsToRestore[i][1]; - } - } catch (ex) { - commandOutput = "Error evaluating command: " + getExceptionStringRep(ex); - commandReturnValue.isError = true; - } - // Append command output - if (commandReturnValue.appendResult) { - var message = ">>> " + expr; - if (!isUndefined(commandOutput)) { - message += newLine + commandOutput; - } - var level = commandReturnValue.isError ? Level.ERROR : Level.INFO; - var loggingEvent = new LoggingEvent(null, new Date(), level, [message], null); - var mainLayout = this.getLayout(); - this.setLayout(commandLayout); - this.append(loggingEvent); - this.setLayout(mainLayout); - } - }; - - var commandLineFunctions = defaultCommandLineFunctions.concat([]); - - this.addCommandLineFunction = function(functionName, commandLineFunction) { - Arrays.push(commandLineFunctions, [functionName, commandLineFunction]); - }; - - var commandHistoryCookieName = "log4javascriptCommandHistory"; - this.storeCommandHistory = function(commandHistory) { - setCookie(commandHistoryCookieName, commandHistory.join(",")); - }; - - var writeHtml = function(doc) { - var lines = getConsoleHtmlLines(); - doc.open(); - for (var i = 0, len = lines.length; i < len; i++) { - doc.writeln(lines[i]); - } - doc.close(); - }; - - // Set up event listeners - this.setEventTypes(["load", "unload"]); - - var consoleWindowLoadHandler = function() { - var win = getConsoleWindow(); - win.setAppender(appender); - win.setNewestAtTop(newestMessageAtTop); - win.setScrollToLatest(scrollToLatestMessage); - win.setMaxMessages(maxMessages); - win.setShowCommandLine(showCommandLine); - win.setShowHideButton(showHideButton); - win.setShowCloseButton(showCloseButton); - win.setMainWindow(window); - - // Restore command history stored in cookie - var storedValue = getCookie(commandHistoryCookieName); - if (storedValue) { - win.commandHistory = storedValue.split(","); - win.currentCommandIndex = win.commandHistory.length; - } - - appender.dispatchEvent("load", { "win" : win }); - }; - - this.unload = function() { - logLog.debug("unload " + this + ", caller: " + this.unload.caller); - if (!consoleClosed) { - logLog.debug("really doing unload " + this); - consoleClosed = true; - consoleWindowLoaded = false; - consoleWindowCreated = false; - appender.dispatchEvent("unload", {}); - } - }; - - var pollConsoleWindow = function(windowTest, interval, successCallback, errorMessage) { - function doPoll() { - try { - // Test if the console has been closed while polling - if (consoleClosed) { - clearInterval(poll); - } - if (windowTest(getConsoleWindow())) { - clearInterval(poll); - successCallback(); - } - } catch (ex) { - clearInterval(poll); - isSupported = false; - handleError(errorMessage, ex); - } - } - - // Poll the pop-up since the onload event is not reliable - var poll = setInterval(doPoll, interval); - }; - - var getConsoleUrl = function() { - var documentDomainSet = (document.domain != location.hostname); - return useDocumentWrite ? "" : getBaseUrl() + "console_uncompressed.html" + - (documentDomainSet ? "?log4javascript_domain=" + escape(document.domain) : ""); - }; - - // Define methods and properties that vary between subclasses - if (inPage) { - // InPageAppender - - var iframeHeightCookieName = "log4javascript_inpageappender_height"; - - var containerElement = null; - var bottomMarginDiv = null; - - // Configuration methods. The function scope is used to prevent - // direct alteration to the appender configuration properties. - var cssProperties = []; - this.addCssProperty = function(name, value) { - if (checkCanConfigure("cssProperties")) { - Arrays.push(cssProperties, [name, value]); - } - }; - - // Define useful variables - var windowCreationStarted = false; - var iframeContainerDiv; - var iframeId = uniqueId + "_InPageAppender_" + consoleAppenderId; - - this.hide = function() { - if (initialized && consoleWindowCreated) { - if (consoleWindowExists()) { - getConsoleWindow().$("command").blur(); - } - iframeContainerDiv.style.display = "none"; - minimized = true; - } - }; - - this.show = function() { - if (initialized) { - if (consoleWindowCreated) { - iframeContainerDiv.style.display = "block"; - this.setShowCommandLine(showCommandLine); // Force IE to update - minimized = false; - } else if (!windowCreationStarted) { - createWindow(true); - } - } - }; - - this.isVisible = function() { - return !minimized; - }; - - this.close = function(fromButton) { - if (!consoleClosed && (!fromButton || confirm("This will permanently remove the console from the page. No more messages will be logged. Do you wish to continue?"))) { - iframeContainerDiv.parentNode.removeChild(iframeContainerDiv); - this.unload(); - } - }; - - // Create open, init, getConsoleWindow and safeToAppend functions - open = function() { - var initErrorMessage = "InPageAppender.open: unable to create console iframe"; - - function finalInit() { - try { - if (!initiallyMinimized) { - appender.show(); - } - bottomMarginDiv.style.height = containerElement.offsetHeight + "px"; - consoleWindowLoadHandler(); - consoleWindowLoaded = true; - appendQueuedLoggingEvents(); - } catch (ex) { - isSupported = false; - handleError(initErrorMessage, ex); - } - } - - function writeToDocument() { - try { - var windowTest = function(win) { return isLoaded(win); }; - if (useDocumentWrite) { - writeHtml(getConsoleWindow().document); - } - if (windowTest(getConsoleWindow())) { - finalInit(); - } else { - pollConsoleWindow(windowTest, 100, finalInit, initErrorMessage); - } - } catch (ex) { - isSupported = false; - handleError(initErrorMessage, ex); - } - } - - minimized = false; - iframeContainerDiv = containerElement.appendChild(document.createElement("div")); - - iframeContainerDiv.style.width = width; - iframeContainerDiv.style.height = getCookie(iframeHeightCookieName) || height; - iframeContainerDiv.style.border = "solid gray 1px"; - - for (var i = 0, len = cssProperties.length; i < len; i++) { - iframeContainerDiv.style[cssProperties[i][0]] = cssProperties[i][1]; - } - - var iframeSrc = useDocumentWrite ? "" : " src='" + getConsoleUrl() + "'"; - - // Adding an iframe using the DOM would be preferable, but it doesn't work - // in IE5 on Windows, or in Konqueror prior to version 3.5 - in Konqueror - // it creates the iframe fine but I haven't been able to find a way to obtain - // the iframe's window object - iframeContainerDiv.innerHTML = ""; - consoleClosed = false; - - // Write the console HTML to the iframe - var iframeDocumentExistsTest = function(win) { - try { - return bool(win) && bool(win.document); - } catch (ex) { - return false; - } - }; - if (iframeDocumentExistsTest(getConsoleWindow())) { - writeToDocument(); - } else { - pollConsoleWindow(iframeDocumentExistsTest, 100, writeToDocument, initErrorMessage); - } - consoleWindowCreated = true; - }; - - var getMargin = (typeof window.getComputedStyle != "undefined") ? - function(el, side) { - return parseInt(window.getComputedStyle(el, null).getPropertyValue("margin-" + side.toLowerCase()), 10) || 0; - } : - function(el, side) { - if (typeof el.currentStyle != "undefined") { - return parseInt(el.currentStyle["margin" + side], 10) || 0; - } - return 0; - }; - - /* - Based on code from Matt Kruse's javascriptoolbox.com. This is undoubtedly not perfect, but will work in most cases, - and where it doesn't the consequences should be minor. The alternative is to use something large like David Mark's - My Library (http://www.cinsoft.net/mylib.html), which is overkill here. - */ - - function getDocumentDimensions(win) { - var doc = win.document, body = doc.body || document.getElementsByTagName("body")[0]; - var width = 0, height = 0; - if (doc.documentElement && (!doc.compatMode || doc.compatMode=="CSS1Compat")) { - width = Math.max(body.offsetWidth + getMargin(body, "Left") + getMargin(body, "Right"), doc.documentElement.clientWidth); - height = Math.max(body.offsetHeight + getMargin(body, "Top") + getMargin(body, "Bottom"), doc.documentElement.clientHeight, doc.documentElement.scrollHeight, win.innerHeight || 0); - } else { - width = Math.max(body.clientWidth, body.scrollWidth); - height = Math.max(body.clientHeight, body.scrollHeight, win.innerHeight || 0); - } - if (isNaN(width) || width == 0) { - width = win.innerWidth || 0; - } - return { width: width, height: height }; - } - - function createResizer(containerElement) { - var resizer = document.createElement("div"); - resizer.style.fontSize = "1px"; - resizer.style.height = "4px"; - resizer.style.cursor = "n-resize"; - resizer.style.backgroundColor = "#cccccc"; - - var oldMouseMove, oldMouseUp; - var startY; - var startHeight, startIframeHeight; - var overlayDiv; - - var mouseMove = function(evt) { - evt = evt || window.event; - var heightDiff = startY - evt.clientY; - containerElement.style.height = (startHeight + heightDiff) + "px"; - iframeContainerDiv.style.height = (startIframeHeight + heightDiff) + "px"; - getConsoleWindow().setLogContainerHeight(); - bottomMarginDiv.style.height = containerElement.style.height; - return false; - }; - - var mouseUp = function(evt) { - evt = evt || window.event; - document.onmousemove = oldMouseMove || function() {}; - document.onmouseup = oldMouseUp || function() {}; - document.body.removeChild(overlayDiv); - document.body.style.cursor = "auto"; - setCookie(iframeHeightCookieName, iframeContainerDiv.style.height); - }; - - resizer.onmousedown = function(evt) { - evt = evt || window.event; - startY = evt.clientY; - var h = containerElement.offsetHeight; - containerElement.style.height = h + "px"; - startHeight = 2 * h - containerElement.offsetHeight; - containerElement.style.height = startHeight + "px"; - - var iframeH = iframeContainerDiv.offsetHeight; - iframeContainerDiv.style.height = iframeH + "px"; - startIframeHeight = 2 * iframeH - iframeContainerDiv.offsetHeight; - iframeContainerDiv.style.height = startIframeHeight + "px"; - - // Add event catcher to prevent mouse pointer going into iframe document - overlayDiv = document.body.appendChild(document.createElement("div")); - var op = "0", opIe = "0"; - - var docSize = getDocumentDimensions(window); - - var s = overlayDiv.style; - s.position = "absolute"; - s.left = "0"; - s.top = "0"; - s.width = docSize.width + "px"; - s.height = docSize.height + "px"; - s.backgroundColor = "white"; - s.zIndex = "1000001"; - s.overflow = "hidden"; - s.KhtmlOpacity = op; - s.MozOpacity = op; - s.filter = "alpha(opacity=" + opIe + ")"; - s.opacity = op; - - oldMouseMove = document.onmousemove; - oldMouseUp = document.onmouseup; - - document.onmousemove = mouseMove; - document.onmouseup = mouseUp; - document.body.style.cursor = "n-resize"; - - return false; - }; - - - return resizer; - } - - createWindow = function(show) { - if (show || !initiallyMinimized) { - var pageLoadHandler = function() { - if (!container) { - // Set up default container element - containerElement = document.createElement("div"); - containerElement.appendChild(createResizer(containerElement)); - containerElement.style.position = "fixed"; - containerElement.style.left = "0"; - containerElement.style.right = "0"; - containerElement.style.bottom = "0"; - document.body.appendChild(containerElement); - appender.addCssProperty("borderWidth", "1px 0 0 0"); - appender.addCssProperty("zIndex", 1000000); // Can't find anything authoritative that says how big z-index can be - - bottomMarginDiv = document.createElement("div"); - bottomMarginDiv.style.padding = "0"; - bottomMarginDiv.style.margin = "0"; - bottomMarginDiv.style.borderWidth = "0"; - document.body.appendChild(bottomMarginDiv); - open(); - } else { - try { - var el = document.getElementById(container); - if (el.nodeType == 1) { - containerElement = el; - } - open(); - } catch (ex) { - handleError("InPageAppender.init: invalid container element '" + container + "' supplied", ex); - } - } - }; - - // Test the type of the container supplied. First, check if it's an element - if (pageLoaded && container && container.appendChild) { - containerElement = container; - open(); - } else if (pageLoaded) { - pageLoadHandler(); - } else { - log4javascript.addEventListener("load", pageLoadHandler); - } - windowCreationStarted = true; - } - }; - - init = function() { - createWindow(); - initialized = true; - }; - - getConsoleWindow = function() { - var iframe = window.frames[iframeId]; - if (iframe) { - return iframe; - } - }; - - safeToAppend = function() { - if (isSupported && !consoleClosed) { - if (consoleWindowCreated && !consoleWindowLoaded && getConsoleWindow() && isLoaded(getConsoleWindow())) { - consoleWindowLoaded = true; - } - return consoleWindowLoaded; - } - return false; - }; - } else { - // PopUpAppender - - // Extract params - var useOldPopUp = appender.defaults.useOldPopUp; - var complainAboutPopUpBlocking = appender.defaults.complainAboutPopUpBlocking; - var reopenWhenClosed = this.defaults.reopenWhenClosed; - - // Configuration methods. The function scope is used to prevent - // direct alteration to the appender configuration properties. - this.isUseOldPopUp = function() { return useOldPopUp; }; - this.setUseOldPopUp = function(useOldPopUpParam) { - if (checkCanConfigure("useOldPopUp")) { - useOldPopUp = bool(useOldPopUpParam); - } - }; - - this.isComplainAboutPopUpBlocking = function() { return complainAboutPopUpBlocking; }; - this.setComplainAboutPopUpBlocking = function(complainAboutPopUpBlockingParam) { - if (checkCanConfigure("complainAboutPopUpBlocking")) { - complainAboutPopUpBlocking = bool(complainAboutPopUpBlockingParam); - } - }; - - this.isFocusPopUp = function() { return focusConsoleWindow; }; - this.setFocusPopUp = function(focusPopUpParam) { - // This property can be safely altered after logging has started - focusConsoleWindow = bool(focusPopUpParam); - }; - - this.isReopenWhenClosed = function() { return reopenWhenClosed; }; - this.setReopenWhenClosed = function(reopenWhenClosedParam) { - // This property can be safely altered after logging has started - reopenWhenClosed = bool(reopenWhenClosedParam); - }; - - this.close = function() { - logLog.debug("close " + this); - try { - popUp.close(); - this.unload(); - } catch (ex) { - // Do nothing - } - }; - - this.hide = function() { - logLog.debug("hide " + this); - if (consoleWindowExists()) { - this.close(); - } - }; - - this.show = function() { - logLog.debug("show " + this); - if (!consoleWindowCreated) { - open(); - } - }; - - // Define useful variables - var popUp; - - // Create open, init, getConsoleWindow and safeToAppend functions - open = function() { - var windowProperties = "width=" + width + ",height=" + height + ",status,resizable"; - var windowName = "PopUp_" + location.host.replace(/[^a-z0-9]/gi, "_") + "_" + consoleAppenderId; - if (!useOldPopUp || !useDocumentWrite) { - // Ensure a previous window isn't used by using a unique name - windowName = windowName + "_" + uniqueId; - } - - var checkPopUpClosed = function(win) { - if (consoleClosed) { - return true; - } else { - try { - return bool(win) && win.closed; - } catch(ex) {} - } - return false; - }; - - var popUpClosedCallback = function() { - if (!consoleClosed) { - appender.unload(); - } - }; - - function finalInit() { - getConsoleWindow().setCloseIfOpenerCloses(!useOldPopUp || !useDocumentWrite); - consoleWindowLoadHandler(); - consoleWindowLoaded = true; - appendQueuedLoggingEvents(); - pollConsoleWindow(checkPopUpClosed, 500, popUpClosedCallback, - "PopUpAppender.checkPopUpClosed: error checking pop-up window"); - } - - try { - popUp = window.open(getConsoleUrl(), windowName, windowProperties); - consoleClosed = false; - consoleWindowCreated = true; - if (popUp && popUp.document) { - if (useDocumentWrite && useOldPopUp && isLoaded(popUp)) { - popUp.mainPageReloaded(); - finalInit(); - } else { - if (useDocumentWrite) { - writeHtml(popUp.document); - } - // Check if the pop-up window object is available - var popUpLoadedTest = function(win) { return bool(win) && isLoaded(win); }; - if (isLoaded(popUp)) { - finalInit(); - } else { - pollConsoleWindow(popUpLoadedTest, 100, finalInit, - "PopUpAppender.init: unable to create console window"); - } - } - } else { - isSupported = false; - logLog.warn("PopUpAppender.init: pop-ups blocked, please unblock to use PopUpAppender"); - if (complainAboutPopUpBlocking) { - handleError("log4javascript: pop-up windows appear to be blocked. Please unblock them to use pop-up logging."); - } - } - } catch (ex) { - handleError("PopUpAppender.init: error creating pop-up", ex); - } - }; - - createWindow = function() { - if (!initiallyMinimized) { - open(); - } - }; - - init = function() { - createWindow(); - initialized = true; - }; - - getConsoleWindow = function() { - return popUp; - }; - - safeToAppend = function() { - if (isSupported && !isUndefined(popUp) && !consoleClosed) { - if (popUp.closed || - (consoleWindowLoaded && isUndefined(popUp.closed))) { // Extra check for Opera - appender.unload(); - logLog.debug("PopUpAppender: pop-up closed"); - return false; - } - if (!consoleWindowLoaded && isLoaded(popUp)) { - consoleWindowLoaded = true; - } - } - return isSupported && consoleWindowLoaded && !consoleClosed; - }; - - this.isVisible = function() { - return safeToAppend(); - }; - } - - // Expose getConsoleWindow so that automated tests can check the DOM - this.getConsoleWindow = getConsoleWindow; - }; - - ConsoleAppender.addGlobalCommandLineFunction = function(functionName, commandLineFunction) { - Arrays.push(defaultCommandLineFunctions, [functionName, commandLineFunction]); - }; - - /* ------------------------------------------------------------------ */ - - function PopUpAppender(lazyInit, initiallyMinimized, useDocumentWrite, - width, height) { - this.create(false, null, lazyInit, initiallyMinimized, - useDocumentWrite, width, height, this.defaults.focusPopUp); - } - - PopUpAppender.prototype = new ConsoleAppender(); - - PopUpAppender.prototype.defaults = { - layout: new PatternLayout("%d{HH:mm:ss} %-5p - %m{1}%n"), - initiallyMinimized: false, - focusPopUp: false, - lazyInit: true, - useOldPopUp: true, - complainAboutPopUpBlocking: true, - newestMessageAtTop: false, - scrollToLatestMessage: true, - width: "600", - height: "400", - reopenWhenClosed: false, - maxMessages: null, - showCommandLine: true, - commandLineObjectExpansionDepth: 1, - showHideButton: false, - showCloseButton: true, - useDocumentWrite: true - }; - - PopUpAppender.prototype.toString = function() { - return "PopUpAppender"; - }; - - log4javascript.PopUpAppender = PopUpAppender; - - /* ------------------------------------------------------------------ */ - - function InPageAppender(container, lazyInit, initiallyMinimized, - useDocumentWrite, width, height) { - this.create(true, container, lazyInit, initiallyMinimized, - useDocumentWrite, width, height, false); - } - - InPageAppender.prototype = new ConsoleAppender(); - - InPageAppender.prototype.defaults = { - layout: new PatternLayout("%d{HH:mm:ss} %-5p - %m{1}%n"), - initiallyMinimized: false, - lazyInit: true, - newestMessageAtTop: false, - scrollToLatestMessage: true, - width: "100%", - height: "220px", - maxMessages: null, - showCommandLine: true, - commandLineObjectExpansionDepth: 1, - showHideButton: false, - showCloseButton: false, - useDocumentWrite: true - }; - - InPageAppender.prototype.toString = function() { - return "InPageAppender"; - }; - - log4javascript.InPageAppender = InPageAppender; - - // Next line for backwards compatibility - log4javascript.InlineAppender = InPageAppender; - })(); - /* ---------------------------------------------------------------------- */ - // Console extension functions - - function padWithSpaces(str, len) { - if (str.length < len) { - var spaces = []; - var numberOfSpaces = Math.max(0, len - str.length); - for (var i = 0; i < numberOfSpaces; i++) { - spaces[i] = " "; - } - str += spaces.join(""); - } - return str; - } - - (function() { - function dir(obj) { - var maxLen = 0; - // Obtain the length of the longest property name - for (var p in obj) { - maxLen = Math.max(toStr(p).length, maxLen); - } - // Create the nicely formatted property list - var propList = []; - for (p in obj) { - var propNameStr = " " + padWithSpaces(toStr(p), maxLen + 2); - var propVal; - try { - propVal = splitIntoLines(toStr(obj[p])).join(padWithSpaces(newLine, maxLen + 6)); - } catch (ex) { - propVal = "[Error obtaining property. Details: " + getExceptionMessage(ex) + "]"; - } - Arrays.push(propList, propNameStr + propVal); - } - return propList.join(newLine); - } - - var nodeTypes = { - ELEMENT_NODE: 1, - ATTRIBUTE_NODE: 2, - TEXT_NODE: 3, - CDATA_SECTION_NODE: 4, - ENTITY_REFERENCE_NODE: 5, - ENTITY_NODE: 6, - PROCESSING_INSTRUCTION_NODE: 7, - COMMENT_NODE: 8, - DOCUMENT_NODE: 9, - DOCUMENT_TYPE_NODE: 10, - DOCUMENT_FRAGMENT_NODE: 11, - NOTATION_NODE: 12 - }; - - var preFormattedElements = ["script", "pre"]; - - // This should be the definitive list, as specified by the XHTML 1.0 Transitional DTD - var emptyElements = ["br", "img", "hr", "param", "link", "area", "input", "col", "base", "meta"]; - var indentationUnit = " "; - - // Create and return an XHTML string from the node specified - function getXhtml(rootNode, includeRootNode, indentation, startNewLine, preformatted) { - includeRootNode = (typeof includeRootNode == "undefined") ? true : !!includeRootNode; - if (typeof indentation != "string") { - indentation = ""; - } - startNewLine = !!startNewLine; - preformatted = !!preformatted; - var xhtml; - - function isWhitespace(node) { - return ((node.nodeType == nodeTypes.TEXT_NODE) && /^[ \t\r\n]*$/.test(node.data)); - } - - function fixAttributeValue(attrValue) { - return attrValue.toString().replace(/\&/g, "&").replace(/]*>", "i"); - if (regex.test(el.outerHTML)) { - return RegExp.$1.toLowerCase(); - } - } - return ""; - } - - var lt = "<"; - var gt = ">"; - - if (includeRootNode && rootNode.nodeType != nodeTypes.DOCUMENT_FRAGMENT_NODE) { - switch (rootNode.nodeType) { - case nodeTypes.ELEMENT_NODE: - var tagName = rootNode.tagName.toLowerCase(); - xhtml = startNewLine ? newLine + indentation : ""; - xhtml += lt; - // Allow for namespaces, where present - var prefix = getNamespace(rootNode); - var hasPrefix = !!prefix; - if (hasPrefix) { - xhtml += prefix + ":"; - } - xhtml += tagName; - for (i = 0, len = rootNode.attributes.length; i < len; i++) { - var currentAttr = rootNode.attributes[i]; - // Check the attribute is valid. - if (! currentAttr.specified || - currentAttr.nodeValue === null || - currentAttr.nodeName.toLowerCase() === "style" || - typeof currentAttr.nodeValue !== "string" || - currentAttr.nodeName.indexOf("_moz") === 0) { - continue; - } - xhtml += " " + currentAttr.nodeName.toLowerCase() + "=\""; - xhtml += fixAttributeValue(currentAttr.nodeValue); - xhtml += "\""; - } - // Style needs to be done separately as it is not reported as an - // attribute in IE - if (rootNode.style.cssText) { - var styleValue = getStyleAttributeValue(rootNode); - if (styleValue !== "") { - xhtml += " style=\"" + getStyleAttributeValue(rootNode) + "\""; - } - } - if (Arrays.contains(emptyElements, tagName) || - (hasPrefix && !rootNode.hasChildNodes())) { - xhtml += "/" + gt; - } else { - xhtml += gt; - // Add output for childNodes collection (which doesn't include attribute nodes) - var childStartNewLine = !(rootNode.childNodes.length === 1 && - rootNode.childNodes[0].nodeType === nodeTypes.TEXT_NODE); - var childPreformatted = Arrays.contains(preFormattedElements, tagName); - for (var i = 0, len = rootNode.childNodes.length; i < len; i++) { - xhtml += getXhtml(rootNode.childNodes[i], true, indentation + indentationUnit, - childStartNewLine, childPreformatted); - } - // Add the end tag - var endTag = lt + "/" + tagName + gt; - xhtml += childStartNewLine ? newLine + indentation + endTag : endTag; - } - return xhtml; - case nodeTypes.TEXT_NODE: - if (isWhitespace(rootNode)) { - xhtml = ""; - } else { - if (preformatted) { - xhtml = rootNode.nodeValue; - } else { - // Trim whitespace from each line of the text node - var lines = splitIntoLines(trim(rootNode.nodeValue)); - var trimmedLines = []; - for (var i = 0, len = lines.length; i < len; i++) { - trimmedLines[i] = trim(lines[i]); - } - xhtml = trimmedLines.join(newLine + indentation); - } - if (startNewLine) { - xhtml = newLine + indentation + xhtml; - } - } - return xhtml; - case nodeTypes.CDATA_SECTION_NODE: - return "" + newLine; - case nodeTypes.DOCUMENT_NODE: - xhtml = ""; - // Add output for childNodes collection (which doesn't include attribute nodes) - for (var i = 0, len = rootNode.childNodes.length; i < len; i++) { - xhtml += getXhtml(rootNode.childNodes[i], true, indentation); - } - return xhtml; - default: - return ""; - } - } else { - xhtml = ""; - // Add output for childNodes collection (which doesn't include attribute nodes) - for (var i = 0, len = rootNode.childNodes.length; i < len; i++) { - xhtml += getXhtml(rootNode.childNodes[i], true, indentation + indentationUnit); - } - return xhtml; - } - } - - function createCommandLineFunctions(appender) { - ConsoleAppender.addGlobalCommandLineFunction("$", function(appender, args, returnValue) { - return document.getElementById(args[0]); - }); - - ConsoleAppender.addGlobalCommandLineFunction("dir", function(appender, args, returnValue) { - var lines = []; - for (var i = 0, len = args.length; i < len; i++) { - lines[i] = dir(args[i]); - } - return lines.join(newLine + newLine); - }); - - ConsoleAppender.addGlobalCommandLineFunction("dirxml", function(appender, args, returnValue) { - var lines = []; - for (var i = 0, len = args.length; i < len; i++) { - lines[i] = getXhtml(args[i]); - } - return lines.join(newLine + newLine); - }); - - ConsoleAppender.addGlobalCommandLineFunction("cd", function(appender, args, returnValue) { - var win, message; - if (args.length === 0 || args[0] === "") { - win = window; - message = "Command line set to run in main window"; - } else { - if (args[0].window == args[0]) { - win = args[0]; - message = "Command line set to run in frame '" + args[0].name + "'"; - } else { - win = window.frames[args[0]]; - if (win) { - message = "Command line set to run in frame '" + args[0] + "'"; - } else { - returnValue.isError = true; - message = "Frame '" + args[0] + "' does not exist"; - win = appender.getCommandWindow(); - } - } - } - appender.setCommandWindow(win); - return new ConsoleMessage(message); - }); - - ConsoleAppender.addGlobalCommandLineFunction("clear", function(appender, args, returnValue) { - returnValue.appendResult = false; - appender.clear(); - }); - - ConsoleAppender.addGlobalCommandLineFunction("keys", function(appender, args, returnValue) { - var keys = []; - for (var k in args[0]) { - Arrays.push(keys, k); - } - return keys; - }); - - ConsoleAppender.addGlobalCommandLineFunction("values", function(appender, args, returnValue) { - var values = []; - for (var k in args[0]) { - try { - Arrays.push(values, args[0][k]); - } catch (ex) { - logLog.warn("values(): Unable to obtain value for key " + k + ". Details: " + getExceptionMessage(ex)); - } - } - return values; - }); - - ConsoleAppender.addGlobalCommandLineFunction("expansionDepth", function(appender, args, returnValue) { - var expansionDepth = parseInt(args[0], 10); - var message; - if (isNaN(expansionDepth) || expansionDepth < 0) { - returnValue.isError = true; - message = "" + args[0] + " is not a valid expansion depth"; - } else { - appender.setCommandLineObjectExpansionDepth(expansionDepth); - message = "Object expansion depth set to " + expansionDepth; - } - return new ConsoleMessage(message); - }); - } - - function init() { - // Add command line functions - createCommandLineFunctions(); - } - - /* ------------------------------------------------------------------ */ - - init(); - })(); - - /* ---------------------------------------------------------------------- */ - // Main load - - 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); - } - log4javascript.setDocumentReady(); - }; - } - } - - // Ensure that the log4javascript object is available in the window. This - // is necessary for log4javascript to be available in IE if loaded using - // Dojo's module system - window.log4javascript = log4javascript; - - return log4javascript; -})(); \ No newline at end of file diff --git a/external/log4javascript_stub.js b/external/log4javascript_stub.js deleted file mode 100644 index 8ce81eb1..00000000 --- a/external/log4javascript_stub.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2008 Tim Down. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -var log4javascript_stub=(function(){var log4javascript;function ff(){return function(){};} -function copy(obj,props){for(var i in props){obj[i]=props[i];}} -var f=ff();var Logger=ff();copy(Logger.prototype,{addChild:f,getEffectiveAppenders:f,invalidateAppenderCache:f,getAdditivity:f,setAdditivity:f,addAppender:f,removeAppender:f,removeAllAppenders:f,log:f,setLevel:f,getLevel:f,getEffectiveLevel:f,trace:f,debug:f,info:f,warn:f,error:f,fatal:f,isEnabledFor:f,isTraceEnabled:f,isDebugEnabled:f,isInfoEnabled:f,isWarnEnabled:f,isErrorEnabled:f,isFatalEnabled:f,callAppenders:f,group:f,groupEnd:f,time:f,timeEnd:f,assert:f,parent:new Logger()});var getLogger=function(){return new Logger();};function EventSupport(){};copy(EventSupport.prototype,{setEventTypes:f,addEventListener:f,removeEventListener:f,dispatchEvent:f,eventTypes:[],eventListeners:{}});function Log4JavaScript(){} -Log4JavaScript.prototype=new EventSupport();log4javascript=new Log4JavaScript();log4javascript={isStub:true,version:"1.4",edition:"log4javascript",setEventTypes:f,addEventListener:f,removeEventListener:f,dispatchEvent:f,eventTypes:[],eventListeners:{},logLog:{setQuietMode:f,setAlertAllErrors:f,debug:f,displayDebug:f,warn:f,error:f},handleError:f,setEnabled:f,isEnabled:f,setTimeStampsInMilliseconds:f,isTimeStampsInMilliseconds:f,evalInScope:f,setShowStackTraces:f,getLogger:getLogger,getDefaultLogger:getLogger,getNullLogger:getLogger,getRootLogger:getLogger,resetConfiguration:f,Level:ff(),LoggingEvent:ff(),Layout:ff(),Appender:ff()};log4javascript.LoggingEvent.prototype={getThrowableStrRep:f,getCombinedMessages:f};log4javascript.Level.prototype={toString:f,equals:f,isGreaterOrEqual:f};var level=new log4javascript.Level();copy(log4javascript.Level,{ALL:level,TRACE:level,DEBUG:level,INFO:level,WARN:level,ERROR:level,FATAL:level,OFF:level});log4javascript.Layout.prototype={defaults:{},format:f,ignoresThrowable:f,getContentType:f,allowBatching:f,getDataValues:f,setKeys:f,setCustomField:f,hasCustomFields:f,setTimeStampsInMilliseconds:f,isTimeStampsInMilliseconds:f,getTimeStampValue:f,toString:f};log4javascript.SimpleDateFormat=ff();log4javascript.SimpleDateFormat.prototype = {setMinimalDaysInFirstWeek:f,getMinimalDaysInFirstWeek:f,format:f}; -log4javascript.PatternLayout=ff();log4javascript.PatternLayout.prototype=new log4javascript.Layout();log4javascript.Appender=ff();log4javascript.Appender.prototype=new EventSupport();copy(log4javascript.Appender.prototype,{layout:new log4javascript.PatternLayout(),threshold:log4javascript.Level.ALL,loggers:[],doAppend:f,append:f,setLayout:f,getLayout:f,setThreshold:f,getThreshold:f,setAddedToLogger:f,setRemovedFromLogger:f,group:f,groupEnd:f,toString:f});log4javascript.SimpleLayout=ff();log4javascript.SimpleLayout.prototype=new log4javascript.Layout();log4javascript.NullLayout=ff();log4javascript.NullLayout.prototype=new log4javascript.Layout();log4javascript.XmlLayout=ff();log4javascript.XmlLayout.prototype=new log4javascript.Layout();copy(log4javascript.XmlLayout.prototype,{escapeCdata:f,isCombinedMessages:f});log4javascript.JsonLayout=ff();log4javascript.JsonLayout.prototype=new log4javascript.Layout();copy(log4javascript.JsonLayout.prototype,{isReadable:f,isCombinedMessages:f});log4javascript.HttpPostDataLayout=ff();log4javascript.HttpPostDataLayout.prototype=new log4javascript.Layout();log4javascript.PatternLayout=ff();log4javascript.PatternLayout.prototype=new log4javascript.Layout();log4javascript.AlertAppender=ff();log4javascript.AlertAppender.prototype=new log4javascript.Appender();log4javascript.BrowserConsoleAppender=ff();log4javascript.BrowserConsoleAppender.prototype=new log4javascript.Appender();log4javascript.AjaxAppender=ff();log4javascript.AjaxAppender.prototype=new log4javascript.Appender();copy(log4javascript.AjaxAppender.prototype,{getSessionId:f,setSessionId:f,isTimed:f,setTimed:f,getTimerInterval:f,setTimerInterval:f,isWaitForResponse:f,setWaitForResponse:f,getBatchSize:f,setBatchSize:f,isSendAllOnUnload:f,setSendAllOnUnload:f,setRequestSuccessCallback:f,setFailCallback:f,getPostVarName:f,setPostVarName:f,sendAll:f,defaults:{requestSuccessCallback:null,failCallback:null}});function ConsoleAppender(){} -ConsoleAppender.prototype=new log4javascript.Appender();copy(ConsoleAppender.prototype,{create:f,isNewestMessageAtTop:f,setNewestMessageAtTop:f,isScrollToLatestMessage:f,setScrollToLatestMessage:f,getWidth:f,setWidth:f,getHeight:f,setHeight:f,getMaxMessages:f,setMaxMessages:f,isShowCommandLine:f,setShowCommandLine:f,isShowHideButton:f,setShowHideButton:f,isShowCloseButton:f,setShowCloseButton:f,getCommandLineObjectExpansionDepth:f,setCommandLineObjectExpansionDepth:f,isInitiallyMinimized:f,setInitiallyMinimized:f,isUseDocumentWrite:f,setUseDocumentWrite:f,group:f,groupEnd:f,clear:f,focus:f,focusCommandLine:f,focusSearch:f,getCommandWindow:f,setCommandWindow:f,executeLastCommand:f,getCommandLayout:f,setCommandLayout:f,evalCommandAndAppend:f,addCommandLineFunction:f,storeCommandHistory:f,unload:f});ConsoleAppender.addGlobalCommandLineFunction=f;log4javascript.InPageAppender=ff();log4javascript.InPageAppender.prototype=new ConsoleAppender();copy(log4javascript.InPageAppender.prototype,{addCssProperty:f,hide:f,show:f,isVisible:f,close:f,defaults:{layout:new log4javascript.PatternLayout(),maxMessages:null}});log4javascript.InlineAppender=log4javascript.InPageAppender;log4javascript.PopUpAppender=ff();log4javascript.PopUpAppender.prototype=new ConsoleAppender();copy(log4javascript.PopUpAppender.prototype,{isUseOldPopUp:f,setUseOldPopUp:f,isComplainAboutPopUpBlocking:f,setComplainAboutPopUpBlocking:f,isFocusPopUp:f,setFocusPopUp:f,isReopenWhenClosed:f,setReopenWhenClosed:f,close:f,hide:f,show:f,defaults:{layout:new log4javascript.PatternLayout(),maxMessages:null}});return log4javascript;})();if(typeof window.log4javascript=="undefined"){var log4javascript=log4javascript_stub;} \ No newline at end of file diff --git a/package.json b/package.json index 7b68c6af..9fb10bab 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "postinstall": "echo 'https://github.com/qunitjs/qunit/issues/1389' && patch -i qunit.patch node_modules/qunit/qunit/qunit.js", "tsc:scripts": "tsc -b scripts/tsconfig.json", "watch:scripts": "tsc -b scripts/tsconfig.json --watch --pretty", - "clean": "node scripts/clean.js && rimraf .rpt2_cache", + "clean": "node scripts/clean.js", "tsc:es2018": "tsc -b", "watch:tsc_es2018": "tsc -b --watch --pretty", "tsc:es5": "lerna exec --no-private --stream --parallel -- ../../node_modules/.bin/tsc -p src/ --outDir lib/esm5 --target es5", @@ -51,9 +51,8 @@ "build:src": "npm-run-all tsc:es2018 tsc:es5 rollup:src", "build:test": "rollup -c scripts/rollup.config.test.js", "watch:test": "FORCE_COLOR=1 rollup -c scripts/rollup.config.test.js --watch", - "build": "run-s tsc:scripts build:src build:test", - "prerelease": "run-s clean build", - "release": "TODO node scripts/publish.js", + "build": "run-s build:src build:test", + "prepublishOnly": "run-s tsc:scripts clean build", "watch": "run-p -l watch:*", "test": "echo 'pls browse test/*.html for testing'" }, @@ -68,7 +67,6 @@ "devDependencies": { "@types/glob": "^7.1.1", "@types/qunit": "^2.5.4", - "@types/rimraf": "^2.0.2", "bowser": "^2.3.0", "delete-empty": "^2.0.0", "glob": "^7.1.3", @@ -78,7 +76,6 @@ "promisify-child-process": "^3.1.0", "qunit": "^2.9.2", "requirejs": "^2.3.6", - "rimraf": "^2.6.3", "rollup": "^1.8.0", "rollup-plugin-commonjs": "^9.3.4", "rollup-plugin-node-resolve": "^4.0.1", diff --git a/packages/classapplier/package.json b/packages/classapplier/package.json index aee34ba5..8586bfc0 100644 --- a/packages/classapplier/package.json +++ b/packages/classapplier/package.json @@ -34,6 +34,15 @@ "type": "git", "url": "https://github.com/ohze/rangy.git" }, + "directories": { + "src": "src", + "lib": "lib", + "test": "test" + }, + "files": [ + "lib", + "src" + ], "main": "lib/bundles/index.umd.js", "module": "lib/esm5/index.js", "es2015": "lib/esm2015/index.js", diff --git a/packages/core/package.json b/packages/core/package.json index efa1e015..235bc2e1 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -34,6 +34,15 @@ "type": "git", "url": "https://github.com/ohze/rangy.git" }, + "directories": { + "src": "src", + "lib": "lib", + "test": "test" + }, + "files": [ + "lib", + "src" + ], "main": "lib/bundles/index.umd.js", "module": "lib/esm5/index.js", "es2015": "lib/esm2015/index.js", diff --git a/packages/core/test/index.html b/packages/core/test/index.html index 61bf2062..7fd2b3f4 100644 --- a/packages/core/test/index.html +++ b/packages/core/test/index.html @@ -13,9 +13,9 @@
- + - + diff --git a/packages/highlighter/package.json b/packages/highlighter/package.json index cc793cf1..975520a0 100644 --- a/packages/highlighter/package.json +++ b/packages/highlighter/package.json @@ -34,6 +34,15 @@ "type": "git", "url": "https://github.com/ohze/rangy.git" }, + "directories": { + "src": "src", + "lib": "lib", + "test": "test" + }, + "files": [ + "lib", + "src" + ], "main": "lib/bundles/index.umd.js", "module": "lib/esm5/index.js", "es2015": "lib/esm2015/index.js", diff --git a/packages/selectionsaverestore/package.json b/packages/selectionsaverestore/package.json index 48a6c72b..13620849 100644 --- a/packages/selectionsaverestore/package.json +++ b/packages/selectionsaverestore/package.json @@ -34,6 +34,15 @@ "type": "git", "url": "https://github.com/ohze/rangy.git" }, + "directories": { + "src": "src", + "lib": "lib", + "test": "test" + }, + "files": [ + "lib", + "src" + ], "main": "lib/bundles/index.umd.js", "module": "lib/esm5/index.js", "es2015": "lib/esm2015/index.js", diff --git a/packages/selectionsaverestore/src/index.ts b/packages/selectionsaverestore/src/index.ts index 3860f277..fd66536f 100644 --- a/packages/selectionsaverestore/src/index.ts +++ b/packages/selectionsaverestore/src/index.ts @@ -153,7 +153,7 @@ export function saveRanges(ranges, direction) { return rangeInfos; } -export function saveSelection(win) { +export function saveSelection(win?) { var sel = api.getSelection(win); var ranges = sel.getAllRanges(); var backward = (ranges.length == 1 && sel.isBackward()); diff --git a/packages/selectionsaverestore/test/index.html b/packages/selectionsaverestore/test/index.html index e1faba0f..d1d256ad 100644 --- a/packages/selectionsaverestore/test/index.html +++ b/packages/selectionsaverestore/test/index.html @@ -1,37 +1,18 @@ - - - - - Rangy - Selection save and restore tests - - - - - - - - - - - - - - - - - - -
-
- - - + + + + + + QUnit Example + + + + + + + +
+
+ + + \ No newline at end of file diff --git a/packages/selectionsaverestore/test/index.test.ts b/packages/selectionsaverestore/test/index.test.ts index 735a7ae3..b14677b8 100644 --- a/packages/selectionsaverestore/test/index.test.ts +++ b/packages/selectionsaverestore/test/index.test.ts @@ -1,23 +1,22 @@ -xn.test.suite("Selection save/restore module tests", function(s) { - s.tearDown = function() { - document.getElementById("test").innerHTML = ""; - }; +import * as rangy from "@rangy/core"; +import "@rangy/test-util/qunit-ex"; +import "@rangy/selectionsaverestore"; - s.test("Issue 140 (saveSelection reverses backward selection)", function(t) { - var testEl = document.getElementById("test"); +QUnit.module("Selection save/restore module tests"); +QUnit.test("Issue 140 (saveSelection reverses backward selection)", function(t) { + var testEl = document.getElementById("qunit-fixture"); testEl.innerHTML = "test"; var range = rangy.createRange(); range.setStartAndEnd(testEl.firstChild, 1, 3); var sel = rangy.getSelection(); sel.addRange(range, "backward"); - t.assert(sel.isBackward()); - t.assertEquals(sel.rangeCount, 1); - t.assert(sel.getRangeAt(0).equals(range)); + t.ok(sel.isBackward()); + t.equal(sel.rangeCount, 1); + t.ok(sel.getRangeAt(0).equals(range)); rangy.saveSelection(); - t.assert(sel.isBackward()); - t.assertEquals(sel.rangeCount, 1); + t.ok(sel.isBackward()); + t.equal(sel.rangeCount, 1); }); -}, false); diff --git a/packages/selectionsaverestore/test/tsconfig.json b/packages/selectionsaverestore/test/tsconfig.json new file mode 100644 index 00000000..43e5e2b7 --- /dev/null +++ b/packages/selectionsaverestore/test/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "references": [ + {"path": "../src"}, + {"path": "../../core/src"}, + {"path": "../../test-util"} + ] +} \ No newline at end of file diff --git a/packages/serializer/package.json b/packages/serializer/package.json index 2e05d0a0..29708cd2 100644 --- a/packages/serializer/package.json +++ b/packages/serializer/package.json @@ -34,6 +34,15 @@ "type": "git", "url": "https://github.com/ohze/rangy.git" }, + "directories": { + "src": "src", + "lib": "lib", + "test": "test" + }, + "files": [ + "lib", + "src" + ], "main": "lib/bundles/index.umd.js", "module": "lib/esm5/index.js", "es2015": "lib/esm2015/index.js", diff --git a/packages/util/package.json b/packages/util/package.json index 6ddb96d4..c362139a 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -34,6 +34,14 @@ "type": "git", "url": "https://github.com/ohze/rangy.git" }, + "directories": { + "src": "src", + "lib": "lib" + }, + "files": [ + "lib", + "src" + ], "main": "lib/bundles/index.umd.js", "module": "lib/esm5/index.js", "es2015": "lib/esm2015/index.js", diff --git a/tsconfig.json b/tsconfig.json index daa2253f..18f16eb1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,8 @@ { "path": "packages/core/test"}, { "path": "packages/classapplier/test"}, { "path": "packages/highlighter/test"}, - { "path": "packages/serializer/test"} + { "path": "packages/serializer/test"}, + { "path": "packages/selectionsaverestore/test"} ], "files": [] } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 8297e990..ae30da56 100644 --- a/yarn.lock +++ b/yarn.lock @@ -714,7 +714,7 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== -"@types/glob@*", "@types/glob@^7.1.1": +"@types/glob@^7.1.1": version "7.1.1" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== @@ -745,14 +745,6 @@ dependencies: "@types/node" "*" -"@types/rimraf@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.2.tgz#7f0fc3cf0ff0ad2a99bb723ae1764f30acaf8b6e" - integrity sha512-Hm/bnWq0TCy7jmjeN5bKYij9vw5GrDFWME4IuxV08278NtU/VdGbzsBohcCUJ7+QMqmUq5hpRKB39HeQWJjztQ== - dependencies: - "@types/glob" "*" - "@types/node" "*" - JSONStream@^1.0.4, JSONStream@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -4130,7 +4122,7 @@ retry@^0.10.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= -rimraf@2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: +rimraf@2, rimraf@^2.5.4, rimraf@^2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==