From 55e9fc7c5e6690adcbbab7f40fb92746c68db159 Mon Sep 17 00:00:00 2001 From: "vincent@cubedesigners.com" Date: Wed, 3 Sep 2014 14:27:33 +0000 Subject: [PATCH] --- fluidbook/compile/_js/esapi.js | 2953 +++++++++++++++++ fluidbook/compile/_js/fluidbook.js | 587 ++-- fluidbook/compile/_js/log4js-lib.js | 1 + fluidbook/compile/_js/log4js.js | 2501 ++++++++++++++ .../_js/resources/Base.esapi.properties.js | 68 + fluidbook/compile/_js/swfaddress.js | 855 ++++- .../Util/packager/class.ws.packager.html.php | 2 +- inc/ws/Util/packager/class.ws.packager.php | 466 +-- 8 files changed, 6909 insertions(+), 524 deletions(-) create mode 100644 fluidbook/compile/_js/esapi.js create mode 100644 fluidbook/compile/_js/log4js-lib.js create mode 100644 fluidbook/compile/_js/log4js.js create mode 100644 fluidbook/compile/_js/resources/Base.esapi.properties.js diff --git a/fluidbook/compile/_js/esapi.js b/fluidbook/compile/_js/esapi.js new file mode 100644 index 000000000..3447881e3 --- /dev/null +++ b/fluidbook/compile/_js/esapi.js @@ -0,0 +1,2953 @@ +/* + * OWASP Enterprise Security API (ESAPI) + * + * This file is part of the Open Web Application Security Project (OWASP) + * Enterprise Security API (ESAPI) project. For details, please see + * http://www.owasp.org/index.php/ESAPI. + * + * Copyright (c) 2008 - The OWASP Foundation + * + * The ESAPI is published by OWASP under the BSD license. You should read and accept the + * LICENSE before you use, modify, and/or redistribute this software. + */ + + +// Utility and Core API Methods +var $namespace = function(name, separator, container){ + var ns = name.split(separator || '.'), + o = container || window, + i, + len; + for(i = 0, len = ns.length; i < len; i++){ + o = o[ns[i]] = o[ns[i]] || {}; + } + return o; +}; + +var $type = function( oVar, oType ) { + if ( !oVar instanceof oType ) { + throw new SyntaxError(); + } +}; + +if (!$) { + var $ = function( sElementID ) { + return document.getElementById( sElementID ); + }; +} + +if (!Array.prototype.each) { + Array.prototype.each = function(fIterator) { + if (typeof fIterator != 'function') { + throw 'Illegal Argument for Array.each'; + } + + for (var i = 0; i < this.length; i ++) { + fIterator(this[i]); + } + }; +} + +if (!Array.prototype.contains) { + Array.prototype.contains = function(srch) { + var found = false; + this.each(function(e) { + if ( ( srch.equals && srch.equals(e) ) || e == srch) { + found = true; + return; + } + }); + return found; + }; +} + +if (!Array.prototype.containsKey) { + Array.prototype.containsKey = function(srch) { + for ( var key in this ) { + if ( key.toLowerCase() == srch.toLowerCase() ) { + return true; + } + } + return false; + }; +} + +if (!Array.prototype.getCaseInsensitive) { + Array.prototype.getCaseInsensitive = function(key) { + for (var k in this) { + if (k.toLowerCase() == key.toLowerCase()) { + return this[k]; + } + } + return null; + }; +} + +if (!String.prototype.charCodeAt) { + String.prototype.charCodeAt = function( idx ) { + var c = this.charAt(idx); + for ( var i=0;i<65536;i++) { + var s = String.fromCharCode(i); + if ( s == c ) { return i; } + } + return 0; + }; +} + +if (!String.prototype.endsWith) { + String.prototype.endsWith = function( test ) { + return this.substr( ( this.length - test.length ), test.length ) == test; + }; +} + +// Declare Core Exceptions +if ( !Exception ) { + var Exception = function( sMsg, oException ) { + this.cause = oException; + this.errorMessage = sMsg; + }; + + Exception.prototype = Error.prototype; + + Exception.prototype.getCause = function() { return this.cause; }; + + Exception.prototype.getMessage = function() { return this.message; }; + + /** + * This method creates the stacktrace for the Exception only when it is called the first time and + * caches it for access after that. Since building a stacktrace is a fairly expensive process, we + * only want to do it if it is called. + */ + Exception.prototype.getStackTrace = function() { + if ( this.callstack ) { + return this.callstack; + } + + if ( this.stack ) { // Mozilla + var lines = stack.split("\n"); + for ( var i=0, len=lines.length; i" ); + } else if ( writer.innerText ) { + writer.innerText = out.replace( "|||", "
" ); + } else if ( writer.append ) { + writer.append( out.replace( "|||", "\n" ) ); + } else if ( writer instanceof Function ) { + writer(out.replace( "|||", "\n" ) ); + } + }; +} + +if ( !RuntimeException ) { + var RuntimeException = Exception; +} + +if ( !IllegalArgumentException ) { + var IllegalArgumentException = Exception; +} + +if ( !DateFormat ) { + // Based on http://jacwright.com/projects/javascript/date_format + var DateFormat = function( sFmt ) { + + var fmt = sFmt; + + var replaceChars = { + longMonths: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], + shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], + longDays: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], + shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], + + // Day + d: function(date) { return (date.getDate() < 10 ? '0' : '') + date.getDate(); }, + D: function(date) { return replaceChars.shortDays[date.getDay()]; }, + j: function(date) { return date.getDate(); }, + l: function(date) { return replaceChars.longDays[date.getDay()]; }, + N: function(date) { return date.getDay() + 1; }, + S: function(date) { return (date.getDate() % 10 == 1 && date.getDate() != 11 ? 'st' : (date.getDate() % 10 == 2 && date.getDate() != 12 ? 'nd' : (date.getDate() % 10 == 3 && date.getDate() != 13 ? 'rd' : 'th'))); }, + w: function(date) { return date.getDay(); }, + z: function(date) { return "Not Yet Supported"; }, + // Week + W: function(date) { return "Not Yet Supported"; }, + // Month + F: function(date) { return replaceChars.longMonths[date.getMonth()]; }, + m: function(date) { return (date.getMonth() < 9 ? '0' : '') + (date.getMonth() + 1); }, + M: function(date) { return replaceChars.shortMonths[date.getMonth()]; }, + n: function(date) { return date.getMonth() + 1; }, + t: function(date) { return "Not Yet Supported"; }, + // Year + L: function(date) { return (((date.getFullYear()%4==0)&&(date.getFullYear()%100 != 0)) || (date.getFullYear()%400==0)) ? '1' : '0'; }, + o: function(date) { return "Not Supported"; }, + Y: function(date) { return date.getFullYear(); }, + y: function(date) { return ('' + date.getFullYear()).substr(2); }, + // Time + a: function(date) { return date.getHours() < 12 ? 'am' : 'pm'; }, + A: function(date) { return date.getHours() < 12 ? 'AM' : 'PM'; }, + B: function(date) { return "Not Yet Supported"; }, + g: function(date) { return date.getHours() % 12 || 12; }, + G: function(date) { return date.getHours(); }, + h: function(date) { return ((date.getHours() % 12 || 12) < 10 ? '0' : '') + (date.getHours() % 12 || 12); }, + H: function(date) { return (date.getHours() < 10 ? '0' : '') + date.getHours(); }, + i: function(date) { return (date.getMinutes() < 10 ? '0' : '') + date.getMinutes(); }, + s: function(date) { return (date.getSeconds() < 10 ? '0' : '') + date.getSeconds(); }, + // Timezone + e: function(date) { return "Not Yet Supported"; }, + I: function(date) { return "Not Supported"; }, + O: function(date) { return (-date.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(date.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(date.getTimezoneOffset() / 60)) + '00'; }, + P: function(date) { return (-date.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(date.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(date.getTimezoneOffset() / 60)) + ':' + (Math.abs(date.getTimezoneOffset() % 60) < 10 ? '0' : '') + (Math.abs(date.getTimezoneOffset() % 60)); }, + T: function(date) { var m = date.getMonth(); date.setMonth(0); var result = date.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/, '$1'); date.setMonth(m); return result;}, + Z: function(date) { return -date.getTimezoneOffset() * 60; }, + // Full Date/Time + c: function(date) { return date.format("Y-m-d") + "T" + date.format("H:i:sP"); }, + r: function(date) { return date.toString(); }, + U: function(date) { return date.getTime() / 1000; } + }; + + + return { + format: function(oDate) { + var out = ''; + for(var i=0;i parameters.length) { + throw new IllegalArgumentException("Attempt to set parameter: " + iIndex + " on a PreparedString with only " + parameters.length + " placeholders"); + } + if (!codec) { + codec = oCodec; + } + parameters[iIndex - 1] = codec.encode([], sValue); + }, + + toString: function() { + for (var ix = 0; ix < parameters.length; ix ++) { + if (parameters[ix] == null) { + throw new RuntimeException("Attempt to render PreparedString without setting parameter " + (ix + 1)); + } + } + var out = '', i = 0; + for (var p = 0; p < parts.length; p ++) { + out += parts[p]; + if (i < parameters.length) { + out += parameters[i++]; + } + } + return out; + } + }; +}; + + +$namespace('org.owasp.esapi'); + +org.owasp.esapi.ValidationErrorList = function() { + var errorList = Array(); + + return { + addError: function( sContext, oValidationException ) { + if ( sContext == null ) throw new RuntimeException( "Context cannot be null: " + oValidationException.getLogMessage(), oValidationException ); + if ( oValidationException == null ) throw new RuntimeException( "Context (" + sContext + ") - Error cannot be null" ); + if ( errorList[sContext] ) throw new RuntimeException( "Context (" + sContext + ") already exists. must be unique." ); + errorList[sContext] = oValidationException; + }, + + errors: function() { + return errorList; + }, + + isEmpty: function() { + return errorList.length == 0; + }, + + size: function() { + return errorList.length; + } + }; +}; + + +$namespace('org.owasp.esapi'); + +org.owasp.esapi.ValidationRule = function() { + return { + getValid: false, + setAllowNull: false, + getTypeName: false, + setTypeName: false, + setEncoder: false, + assertValid: false, + getSafe: false, + isValid: false, + whitelist: false + }; +}; + + +$namespace('org.owasp.esapi'); + +org.owasp.esapi.Validator = function() { + return { + addRule: false, + getRule: false, + getValidInput: false, + isValidDate: false, + getValidDate: false, + isValidSafeHTML: false, + getValidSafeHTML: false, + isValidCreditCard: false, + getValidCreditCard: false, + isValidFilename: false, + getValidFilename: false, + isValidNumber: false, + getValidNumber: false, + isValidPrintable: false, + getValidPrintable: false + }; +}; + + +$namespace('org.owasp.esapi.codecs.Base64'); + +org.owasp.esapi.codecs.Base64 = { + _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + + encode: function(sInput) { + if (!sInput) { + return null; + } + + var out = ''; + var ch1,ch2,ch3,enc1,enc2,enc3,enc4; + var i = 0; + + var input = org.owasp.esapi.codecs.UTF8.encode(sInput); + + while (i < input.length) { + ch1 = input.charCodeAt(i++); + ch2 = input.charCodeAt(i++); + ch3 = input.charCodeAt(i++); + + enc1 = ch1 >> 2; + enc2 = ((ch1 & 3) << 4) | (ch2 >> 4); + enc3 = ((ch2 & 15) << 2) | (ch3 >> 6); + enc4 = ch3 & 63; + + if (isNaN(ch2)) { + enc3 = enc4 = 64; + } + else if (isNaN(ch3)) { + enc4 = 64; + } + + out += this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); + } + + return out; + }, + + decode: function(sInput) { + if (!sInput) { + return null; + } + + var out = ''; + var ch1, ch2, ch3, enc1, enc2, enc3, enc4; + var i = 0; + + var input = sInput.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + + ch1 = (enc1 << 2) | (enc2 >> 4); + ch2 = ((enc2 & 15) << 4) | (enc3 >> 2); + ch3 = ((enc3 & 3) << 6) | enc4; + + out += String.fromCharCode(ch1); + if (enc3 != 64) { + out += String.fromCharCode(ch2); + } + if (enc4 != 64) { + out += String.fromCharCode(ch3); + } + } + + out = org.owasp.esapi.codecs.UTF8.decode(out); + return out; + } +}; + + +$namespace('org.owasp.esapi.codecs'); + +org.owasp.esapi.codecs.CSSCodec = function() { + var _super = new org.owasp.esapi.codecs.Codec(); + + return { + encode: _super.encode, + + decode: _super.decode, + + encodeCharacter: function(aImmune, c) { + if (aImmune.contains(c)) { + return c; + } + + var hex = org.owasp.esapi.codecs.Codec.getHexForNonAlphanumeric(c); + if (hex == null) { + return c; + } + + return "\\" + hex + " "; + }, + + decodeCharacter: function(oPushbackString) { + oPushbackString.mark(); + var first = oPushbackString.next(); + if (first == null) { + oPushbackString.reset(); + return null; + } + + if (first != '\\') { + oPushbackString.reset(); + return null; + } + + var second = oPushbackString.next(); + if (second == null) { + oPushbackString.reset(); + return null; + } + + if (oPushbackString.isHexDigit(second)) { + var out = second; + for (var i = 0; i < 6; i ++) { + var c = oPushbackString.next(); + if (c == null || c.charCodeAt(0) == 0x20) { + break; + } + if (oPushbackString.isHexDigit(c)) { + out += c; + } else { + input.pushback(c); + break; + } + } + + try { + var n = parseInt(out, 16); + return String.fromCharCode(n); + } catch (e) { + oPushbackString.reset(); + return null; + } + } + + return second; + } + }; +}; + + +$namespace('org.owasp.esapi.codecs'); + +org.owasp.esapi.codecs.Codec = function() { + return { + /** + * Encode a String so that it can be safely used in a specific context. + * + * @param aImmune + * array of immune characters + * @param sInput + * the String to encode + * @return the encoded String + */ + encode: function(aImmune, sInput) { + var out = ''; + for (var i = 0; i < sInput.length; i ++) { + var c = sInput.charAt(i); + out += this.encodeCharacter(aImmune, c); + } + return out; + }, + + /** + * Default implementation that should be overridden in specific codecs. + * + * @param aImmune + * array of immune characters + * @param c + * the Character to encode + * @return + * the encoded Character + */ + encodeCharacter: function(aImmune, c) { + return c; + }, + + /** + * Decode a String that was encoded using the encode method in this Class + * + * @param sInput + * the String to decode + * @return + * the decoded String + */ + decode: function(sInput) { + var out = ''; + var pbs = new org.owasp.esapi.codecs.PushbackString(sInput); + while (pbs.hasNext()) { + var c = this.decodeCharacter(pbs); + if (c != null) { + out += c; + } else { + out += pbs.next(); + } + } + return out; + }, + + /** + * Returns the decoded version of the next character from the input string and advances the + * current character in the PushbackString. If the current character is not encoded, this + * method MUST reset the PushbackString. + * + * @param oPushbackString the Character to decode + * @return the decoded Character + */ + decodeCharacter: function(oPushbackString) { + return oPushbackString.next(); + } + }; +}; + +org.owasp.esapi.codecs.Codec.getHexForNonAlphanumeric = function(c) { + if (c.charCodeAt(0) < 256) { + return org.owasp.esapi.codecs.Codec.hex[c.charCodeAt(0)]; + } + return c.charCodeAt(0).toString(16); +}; + +org.owasp.esapi.codecs.Codec.hex = []; +for ( var c = 0; c < 0xFF; c ++ ) { + if ( c >= 0x30 && c <= 0x39 || c>= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A ) { + org.owasp.esapi.codecs.Codec.hex[c] = null; + } else { + org.owasp.esapi.codecs.Codec.hex[c] = c.toString(16); + } +}; + +var entityToCharacterMap = []; +entityToCharacterMap["""] = "34"; /* 34 : quotation mark */ +entityToCharacterMap["&"] = "38"; /* 38 : ampersand */ +entityToCharacterMap["<"] = "60"; /* 60 : less-than sign */ +entityToCharacterMap[">"] = "62"; /* 62 : greater-than sign */ +entityToCharacterMap[" "] = "160"; /* 160 : no-break space */ +entityToCharacterMap["¡"] = "161"; /* 161 : inverted exclamation mark */ +entityToCharacterMap["¢"] = "162"; /* 162 : cent sign */ +entityToCharacterMap["£"] = "163"; /* 163 : pound sign */ +entityToCharacterMap["¤"] = "164"; /* 164 : currency sign */ +entityToCharacterMap["¥"] = "165"; /* 165 : yen sign */ +entityToCharacterMap["¦"] = "166"; /* 166 : broken bar */ +entityToCharacterMap["§"] = "167"; /* 167 : section sign */ +entityToCharacterMap["¨"] = "168"; /* 168 : diaeresis */ +entityToCharacterMap["©"] = "169"; /* 169 : copyright sign */ +entityToCharacterMap["ª"] = "170"; /* 170 : feminine ordinal indicator */ +entityToCharacterMap["«"] = "171"; /* 171 : left-pointing double angle quotation mark */ +entityToCharacterMap["¬"] = "172"; /* 172 : not sign */ +entityToCharacterMap["­"] = "173"; /* 173 : soft hyphen */ +entityToCharacterMap["®"] = "174"; /* 174 : registered sign */ +entityToCharacterMap["¯"] = "175"; /* 175 : macron */ +entityToCharacterMap["°"] = "176"; /* 176 : degree sign */ +entityToCharacterMap["±"] = "177"; /* 177 : plus-minus sign */ +entityToCharacterMap["²"] = "178"; /* 178 : superscript two */ +entityToCharacterMap["³"] = "179"; /* 179 : superscript three */ +entityToCharacterMap["´"] = "180"; /* 180 : acute accent */ +entityToCharacterMap["µ"] = "181"; /* 181 : micro sign */ +entityToCharacterMap["¶"] = "182"; /* 182 : pilcrow sign */ +entityToCharacterMap["·"] = "183"; /* 183 : middle dot */ +entityToCharacterMap["¸"] = "184"; /* 184 : cedilla */ +entityToCharacterMap["¹"] = "185"; /* 185 : superscript one */ +entityToCharacterMap["º"] = "186"; /* 186 : masculine ordinal indicator */ +entityToCharacterMap["»"] = "187"; /* 187 : right-pointing double angle quotation mark */ +entityToCharacterMap["¼"] = "188"; /* 188 : vulgar fraction one quarter */ +entityToCharacterMap["½"] = "189"; /* 189 : vulgar fraction one half */ +entityToCharacterMap["¾"] = "190"; /* 190 : vulgar fraction three quarters */ +entityToCharacterMap["¿"] = "191"; /* 191 : inverted question mark */ +entityToCharacterMap["À"] = "192"; /* 192 : Latin capital letter a with grave */ +entityToCharacterMap["Á"] = "193"; /* 193 : Latin capital letter a with acute */ +entityToCharacterMap["Â"] = "194"; /* 194 : Latin capital letter a with circumflex */ +entityToCharacterMap["Ã"] = "195"; /* 195 : Latin capital letter a with tilde */ +entityToCharacterMap["Ä"] = "196"; /* 196 : Latin capital letter a with diaeresis */ +entityToCharacterMap["Å"] = "197"; /* 197 : Latin capital letter a with ring above */ +entityToCharacterMap["Æ"] = "198"; /* 198 : Latin capital letter ae */ +entityToCharacterMap["Ç"] = "199"; /* 199 : Latin capital letter c with cedilla */ +entityToCharacterMap["È"] = "200"; /* 200 : Latin capital letter e with grave */ +entityToCharacterMap["É"] = "201"; /* 201 : Latin capital letter e with acute */ +entityToCharacterMap["Ê"] = "202"; /* 202 : Latin capital letter e with circumflex */ +entityToCharacterMap["Ë"] = "203"; /* 203 : Latin capital letter e with diaeresis */ +entityToCharacterMap["Ì"] = "204"; /* 204 : Latin capital letter i with grave */ +entityToCharacterMap["Í"] = "205"; /* 205 : Latin capital letter i with acute */ +entityToCharacterMap["Î"] = "206"; /* 206 : Latin capital letter i with circumflex */ +entityToCharacterMap["Ï"] = "207"; /* 207 : Latin capital letter i with diaeresis */ +entityToCharacterMap["Ð"] = "208"; /* 208 : Latin capital letter eth */ +entityToCharacterMap["Ñ"] = "209"; /* 209 : Latin capital letter n with tilde */ +entityToCharacterMap["Ò"] = "210"; /* 210 : Latin capital letter o with grave */ +entityToCharacterMap["Ó"] = "211"; /* 211 : Latin capital letter o with acute */ +entityToCharacterMap["Ô"] = "212"; /* 212 : Latin capital letter o with circumflex */ +entityToCharacterMap["Õ"] = "213"; /* 213 : Latin capital letter o with tilde */ +entityToCharacterMap["Ö"] = "214"; /* 214 : Latin capital letter o with diaeresis */ +entityToCharacterMap["×"] = "215"; /* 215 : multiplication sign */ +entityToCharacterMap["Ø"] = "216"; /* 216 : Latin capital letter o with stroke */ +entityToCharacterMap["Ù"] = "217"; /* 217 : Latin capital letter u with grave */ +entityToCharacterMap["Ú"] = "218"; /* 218 : Latin capital letter u with acute */ +entityToCharacterMap["Û"] = "219"; /* 219 : Latin capital letter u with circumflex */ +entityToCharacterMap["Ü"] = "220"; /* 220 : Latin capital letter u with diaeresis */ +entityToCharacterMap["Ý"] = "221"; /* 221 : Latin capital letter y with acute */ +entityToCharacterMap["Þ"] = "222"; /* 222 : Latin capital letter thorn */ +entityToCharacterMap["ß"] = "223"; /* 223 : Latin small letter sharp s, German Eszett */ +entityToCharacterMap["à"] = "224"; /* 224 : Latin small letter a with grave */ +entityToCharacterMap["á"] = "225"; /* 225 : Latin small letter a with acute */ +entityToCharacterMap["â"] = "226"; /* 226 : Latin small letter a with circumflex */ +entityToCharacterMap["ã"] = "227"; /* 227 : Latin small letter a with tilde */ +entityToCharacterMap["ä"] = "228"; /* 228 : Latin small letter a with diaeresis */ +entityToCharacterMap["å"] = "229"; /* 229 : Latin small letter a with ring above */ +entityToCharacterMap["æ"] = "230"; /* 230 : Latin lowercase ligature ae */ +entityToCharacterMap["ç"] = "231"; /* 231 : Latin small letter c with cedilla */ +entityToCharacterMap["è"] = "232"; /* 232 : Latin small letter e with grave */ +entityToCharacterMap["é"] = "233"; /* 233 : Latin small letter e with acute */ +entityToCharacterMap["ê"] = "234"; /* 234 : Latin small letter e with circumflex */ +entityToCharacterMap["ë"] = "235"; /* 235 : Latin small letter e with diaeresis */ +entityToCharacterMap["ì"] = "236"; /* 236 : Latin small letter i with grave */ +entityToCharacterMap["í"] = "237"; /* 237 : Latin small letter i with acute */ +entityToCharacterMap["î"] = "238"; /* 238 : Latin small letter i with circumflex */ +entityToCharacterMap["ï"] = "239"; /* 239 : Latin small letter i with diaeresis */ +entityToCharacterMap["ð"] = "240"; /* 240 : Latin small letter eth */ +entityToCharacterMap["ñ"] = "241"; /* 241 : Latin small letter n with tilde */ +entityToCharacterMap["ò"] = "242"; /* 242 : Latin small letter o with grave */ +entityToCharacterMap["ó"] = "243"; /* 243 : Latin small letter o with acute */ +entityToCharacterMap["ô"] = "244"; /* 244 : Latin small letter o with circumflex */ +entityToCharacterMap["õ"] = "245"; /* 245 : Latin small letter o with tilde */ +entityToCharacterMap["ö"] = "246"; /* 246 : Latin small letter o with diaeresis */ +entityToCharacterMap["÷"] = "247"; /* 247 : division sign */ +entityToCharacterMap["ø"] = "248"; /* 248 : Latin small letter o with stroke */ +entityToCharacterMap["ù"] = "249"; /* 249 : Latin small letter u with grave */ +entityToCharacterMap["ú"] = "250"; /* 250 : Latin small letter u with acute */ +entityToCharacterMap["û"] = "251"; /* 251 : Latin small letter u with circumflex */ +entityToCharacterMap["ü"] = "252"; /* 252 : Latin small letter u with diaeresis */ +entityToCharacterMap["ý"] = "253"; /* 253 : Latin small letter y with acute */ +entityToCharacterMap["þ"] = "254"; /* 254 : Latin small letter thorn */ +entityToCharacterMap["ÿ"] = "255"; /* 255 : Latin small letter y with diaeresis */ +entityToCharacterMap["&OElig"] = "338"; /* 338 : Latin capital ligature oe */ +entityToCharacterMap["&oelig"] = "339"; /* 339 : Latin small ligature oe */ +entityToCharacterMap["&Scaron"] = "352"; /* 352 : Latin capital letter s with caron */ +entityToCharacterMap["&scaron"] = "353"; /* 353 : Latin small letter s with caron */ +entityToCharacterMap["&Yuml"] = "376"; /* 376 : Latin capital letter y with diaeresis */ +entityToCharacterMap["&fnof"] = "402"; /* 402 : Latin small letter f with hook */ +entityToCharacterMap["&circ"] = "710"; /* 710 : modifier letter circumflex accent */ +entityToCharacterMap["&tilde"] = "732"; /* 732 : small tilde */ +entityToCharacterMap["&Alpha"] = "913"; /* 913 : Greek capital letter alpha */ +entityToCharacterMap["&Beta"] = "914"; /* 914 : Greek capital letter beta */ +entityToCharacterMap["&Gamma"] = "915"; /* 915 : Greek capital letter gamma */ +entityToCharacterMap["&Delta"] = "916"; /* 916 : Greek capital letter delta */ +entityToCharacterMap["&Epsilon"] = "917"; /* 917 : Greek capital letter epsilon */ +entityToCharacterMap["&Zeta"] = "918"; /* 918 : Greek capital letter zeta */ +entityToCharacterMap["&Eta"] = "919"; /* 919 : Greek capital letter eta */ +entityToCharacterMap["&Theta"] = "920"; /* 920 : Greek capital letter theta */ +entityToCharacterMap["&Iota"] = "921"; /* 921 : Greek capital letter iota */ +entityToCharacterMap["&Kappa"] = "922"; /* 922 : Greek capital letter kappa */ +entityToCharacterMap["&Lambda"] = "923"; /* 923 : Greek capital letter lambda */ +entityToCharacterMap["&Mu"] = "924"; /* 924 : Greek capital letter mu */ +entityToCharacterMap["&Nu"] = "925"; /* 925 : Greek capital letter nu */ +entityToCharacterMap["&Xi"] = "926"; /* 926 : Greek capital letter xi */ +entityToCharacterMap["&Omicron"] = "927"; /* 927 : Greek capital letter omicron */ +entityToCharacterMap["&Pi"] = "928"; /* 928 : Greek capital letter pi */ +entityToCharacterMap["&Rho"] = "929"; /* 929 : Greek capital letter rho */ +entityToCharacterMap["&Sigma"] = "931"; /* 931 : Greek capital letter sigma */ +entityToCharacterMap["&Tau"] = "932"; /* 932 : Greek capital letter tau */ +entityToCharacterMap["&Upsilon"] = "933"; /* 933 : Greek capital letter upsilon */ +entityToCharacterMap["&Phi"] = "934"; /* 934 : Greek capital letter phi */ +entityToCharacterMap["&Chi"] = "935"; /* 935 : Greek capital letter chi */ +entityToCharacterMap["&Psi"] = "936"; /* 936 : Greek capital letter psi */ +entityToCharacterMap["&Omega"] = "937"; /* 937 : Greek capital letter omega */ +entityToCharacterMap["&alpha"] = "945"; /* 945 : Greek small letter alpha */ +entityToCharacterMap["&beta"] = "946"; /* 946 : Greek small letter beta */ +entityToCharacterMap["&gamma"] = "947"; /* 947 : Greek small letter gamma */ +entityToCharacterMap["&delta"] = "948"; /* 948 : Greek small letter delta */ +entityToCharacterMap["&epsilon"] = "949"; /* 949 : Greek small letter epsilon */ +entityToCharacterMap["&zeta"] = "950"; /* 950 : Greek small letter zeta */ +entityToCharacterMap["&eta"] = "951"; /* 951 : Greek small letter eta */ +entityToCharacterMap["&theta"] = "952"; /* 952 : Greek small letter theta */ +entityToCharacterMap["&iota"] = "953"; /* 953 : Greek small letter iota */ +entityToCharacterMap["&kappa"] = "954"; /* 954 : Greek small letter kappa */ +entityToCharacterMap["&lambda"] = "955"; /* 955 : Greek small letter lambda */ +entityToCharacterMap["&mu"] = "956"; /* 956 : Greek small letter mu */ +entityToCharacterMap["&nu"] = "957"; /* 957 : Greek small letter nu */ +entityToCharacterMap["&xi"] = "958"; /* 958 : Greek small letter xi */ +entityToCharacterMap["&omicron"] = "959"; /* 959 : Greek small letter omicron */ +entityToCharacterMap["&pi"] = "960"; /* 960 : Greek small letter pi */ +entityToCharacterMap["&rho"] = "961"; /* 961 : Greek small letter rho */ +entityToCharacterMap["&sigmaf"] = "962"; /* 962 : Greek small letter final sigma */ +entityToCharacterMap["&sigma"] = "963"; /* 963 : Greek small letter sigma */ +entityToCharacterMap["&tau"] = "964"; /* 964 : Greek small letter tau */ +entityToCharacterMap["&upsilon"] = "965"; /* 965 : Greek small letter upsilon */ +entityToCharacterMap["&phi"] = "966"; /* 966 : Greek small letter phi */ +entityToCharacterMap["&chi"] = "967"; /* 967 : Greek small letter chi */ +entityToCharacterMap["&psi"] = "968"; /* 968 : Greek small letter psi */ +entityToCharacterMap["&omega"] = "969"; /* 969 : Greek small letter omega */ +entityToCharacterMap["&thetasym"] = "977"; /* 977 : Greek theta symbol */ +entityToCharacterMap["&upsih"] = "978"; /* 978 : Greek upsilon with hook symbol */ +entityToCharacterMap["&piv"] = "982"; /* 982 : Greek pi symbol */ +entityToCharacterMap["&ensp"] = "8194"; /* 8194 : en space */ +entityToCharacterMap["&emsp"] = "8195"; /* 8195 : em space */ +entityToCharacterMap["&thinsp"] = "8201"; /* 8201 : thin space */ +entityToCharacterMap["&zwnj"] = "8204"; /* 8204 : zero width non-joiner */ +entityToCharacterMap["&zwj"] = "8205"; /* 8205 : zero width joiner */ +entityToCharacterMap["&lrm"] = "8206"; /* 8206 : left-to-right mark */ +entityToCharacterMap["&rlm"] = "8207"; /* 8207 : right-to-left mark */ +entityToCharacterMap["&ndash"] = "8211"; /* 8211 : en dash */ +entityToCharacterMap["&mdash"] = "8212"; /* 8212 : em dash */ +entityToCharacterMap["&lsquo"] = "8216"; /* 8216 : left single quotation mark */ +entityToCharacterMap["&rsquo"] = "8217"; /* 8217 : right single quotation mark */ +entityToCharacterMap["&sbquo"] = "8218"; /* 8218 : single low-9 quotation mark */ +entityToCharacterMap["&ldquo"] = "8220"; /* 8220 : left double quotation mark */ +entityToCharacterMap["&rdquo"] = "8221"; /* 8221 : right double quotation mark */ +entityToCharacterMap["&bdquo"] = "8222"; /* 8222 : double low-9 quotation mark */ +entityToCharacterMap["&dagger"] = "8224"; /* 8224 : dagger */ +entityToCharacterMap["&Dagger"] = "8225"; /* 8225 : double dagger */ +entityToCharacterMap["&bull"] = "8226"; /* 8226 : bullet */ +entityToCharacterMap["&hellip"] = "8230"; /* 8230 : horizontal ellipsis */ +entityToCharacterMap["&permil"] = "8240"; /* 8240 : per mille sign */ +entityToCharacterMap["&prime"] = "8242"; /* 8242 : prime */ +entityToCharacterMap["&Prime"] = "8243"; /* 8243 : double prime */ +entityToCharacterMap["&lsaquo"] = "8249"; /* 8249 : single left-pointing angle quotation mark */ +entityToCharacterMap["&rsaquo"] = "8250"; /* 8250 : single right-pointing angle quotation mark */ +entityToCharacterMap["&oline"] = "8254"; /* 8254 : overline */ +entityToCharacterMap["&frasl"] = "8260"; /* 8260 : fraction slash */ +entityToCharacterMap["&euro"] = "8364"; /* 8364 : euro sign */ +entityToCharacterMap["&image"] = "8365"; /* 8465 : black-letter capital i */ +entityToCharacterMap["&weierp"] = "8472"; /* 8472 : script capital p, Weierstrass p */ +entityToCharacterMap["&real"] = "8476"; /* 8476 : black-letter capital r */ +entityToCharacterMap["&trade"] = "8482"; /* 8482 : trademark sign */ +entityToCharacterMap["&alefsym"] = "8501"; /* 8501 : alef symbol */ +entityToCharacterMap["&larr"] = "8592"; /* 8592 : leftwards arrow */ +entityToCharacterMap["&uarr"] = "8593"; /* 8593 : upwards arrow */ +entityToCharacterMap["&rarr"] = "8594"; /* 8594 : rightwards arrow */ +entityToCharacterMap["&darr"] = "8595"; /* 8595 : downwards arrow */ +entityToCharacterMap["&harr"] = "8596"; /* 8596 : left right arrow */ +entityToCharacterMap["&crarr"] = "8629"; /* 8629 : downwards arrow with corner leftwards */ +entityToCharacterMap["&lArr"] = "8656"; /* 8656 : leftwards double arrow */ +entityToCharacterMap["&uArr"] = "8657"; /* 8657 : upwards double arrow */ +entityToCharacterMap["&rArr"] = "8658"; /* 8658 : rightwards double arrow */ +entityToCharacterMap["&dArr"] = "8659"; /* 8659 : downwards double arrow */ +entityToCharacterMap["&hArr"] = "8660"; /* 8660 : left right double arrow */ +entityToCharacterMap["&forall"] = "8704"; /* 8704 : for all */ +entityToCharacterMap["&part"] = "8706"; /* 8706 : partial differential */ +entityToCharacterMap["&exist"] = "8707"; /* 8707 : there exists */ +entityToCharacterMap["&empty"] = "8709"; /* 8709 : empty set */ +entityToCharacterMap["&nabla"] = "8711"; /* 8711 : nabla */ +entityToCharacterMap["&isin"] = "8712"; /* 8712 : element of */ +entityToCharacterMap["¬in"] = "8713"; /* 8713 : not an element of */ +entityToCharacterMap["&ni"] = "8715"; /* 8715 : contains as member */ +entityToCharacterMap["&prod"] = "8719"; /* 8719 : n-ary product */ +entityToCharacterMap["&sum"] = "8721"; /* 8721 : n-ary summation */ +entityToCharacterMap["&minus"] = "8722"; /* 8722 : minus sign */ +entityToCharacterMap["&lowast"] = "8727"; /* 8727 : asterisk operator */ +entityToCharacterMap["&radic"] = "8730"; /* 8730 : square root */ +entityToCharacterMap["&prop"] = "8733"; /* 8733 : proportional to */ +entityToCharacterMap["&infin"] = "8734"; /* 8734 : infinity */ +entityToCharacterMap["&ang"] = "8736"; /* 8736 : angle */ +entityToCharacterMap["&and"] = "8743"; /* 8743 : logical and */ +entityToCharacterMap["&or"] = "8744"; /* 8744 : logical or */ +entityToCharacterMap["&cap"] = "8745"; /* 8745 : intersection */ +entityToCharacterMap["&cup"] = "8746"; /* 8746 : union */ +entityToCharacterMap["&int"] = "8747"; /* 8747 : integral */ +entityToCharacterMap["&there4"] = "8756"; /* 8756 : therefore */ +entityToCharacterMap["&sim"] = "8764"; /* 8764 : tilde operator */ +entityToCharacterMap["&cong"] = "8773"; /* 8773 : congruent to */ +entityToCharacterMap["&asymp"] = "8776"; /* 8776 : almost equal to */ +entityToCharacterMap["&ne"] = "8800"; /* 8800 : not equal to */ +entityToCharacterMap["&equiv"] = "8801"; /* 8801 : identical to, equivalent to */ +entityToCharacterMap["&le"] = "8804"; /* 8804 : less-than or equal to */ +entityToCharacterMap["&ge"] = "8805"; /* 8805 : greater-than or equal to */ +entityToCharacterMap["&sub"] = "8834"; /* 8834 : subset of */ +entityToCharacterMap["&sup"] = "8835"; /* 8835 : superset of */ +entityToCharacterMap["&nsub"] = "8836"; /* 8836 : not a subset of */ +entityToCharacterMap["&sube"] = "8838"; /* 8838 : subset of or equal to */ +entityToCharacterMap["&supe"] = "8839"; /* 8839 : superset of or equal to */ +entityToCharacterMap["&oplus"] = "8853"; /* 8853 : circled plus */ +entityToCharacterMap["&otimes"] = "8855"; /* 8855 : circled times */ +entityToCharacterMap["&perp"] = "8869"; /* 8869 : up tack */ +entityToCharacterMap["&sdot"] = "8901"; /* 8901 : dot operator */ +entityToCharacterMap["&lceil"] = "8968"; /* 8968 : left ceiling */ +entityToCharacterMap["&rceil"] = "8969"; /* 8969 : right ceiling */ +entityToCharacterMap["&lfloor"] = "8970"; /* 8970 : left floor */ +entityToCharacterMap["&rfloor"] = "8971"; /* 8971 : right floor */ +entityToCharacterMap["&lang"] = "9001"; /* 9001 : left-pointing angle bracket */ +entityToCharacterMap["&rang"] = "9002"; /* 9002 : right-pointing angle bracket */ +entityToCharacterMap["&loz"] = "9674"; /* 9674 : lozenge */ +entityToCharacterMap["&spades"] = "9824"; /* 9824 : black spade suit */ +entityToCharacterMap["&clubs"] = "9827"; /* 9827 : black club suit */ +entityToCharacterMap["&hearts"] = "9829"; /* 9829 : black heart suit */ +entityToCharacterMap["&diams"] = "9830"; /* 9830 : black diamond suit */ + +var characterToEntityMap = []; + +for ( var entity in entityToCharacterMap ) { + characterToEntityMap[entityToCharacterMap[entity]] = entity; +} + +$namespace('org.owasp.esapi.codecs'); + +org.owasp.esapi.codecs.HTMLEntityCodec = function() { + var _super = new org.owasp.esapi.codecs.Codec(); + + var getNumericEntity = function(input) { + var first = input.peek(); + if (first == null) { + return null; + } + + if (first == 'x' || first == 'X') { + input.next(); + return parseHex(input); + } + return parseNumber(input); + }; + + var parseNumber = function(input) { + var out = ''; + while (input.hasNext()) { + var c = input.peek(); + if (c.match(/[0-9]/)) { + out += c; + input.next(); + } else if (c == ';') { + input.next(); + break; + } else { + break; + } + } + + try { + return parseInt(out); + } catch (e) { + return null; + } + }; + + var parseHex = function(input) { + var out = ''; + while (input.hasNext()) { + var c = input.peek(); + if (c.match(/[0-9A-Fa-f]/)) { + out += c; + input.next(); + } else if (c == ';') { + input.next(); + break; + } else { + break; + } + } + try { + return parseInt(out, 16); + } catch (e) { + return null; + } + }; + + var getNamedEntity = function(input) { + var entity = ''; + while (input.hasNext()) { + var c = input.peek(); + if (c.match(/[A-Za-z]/)) { + entity += c; + input.next(); + if (entityToCharacterMap.containsKey('&' + entity)) { + if (input.peek(';')) input.next(); + break; + } + } else if (c == ';') { + input.next(); + } else { + break; + } + } + + return String.fromCharCode(entityToCharacterMap.getCaseInsensitive('&' + entity)); + }; + + return { + encode: _super.encode, + + decode: _super.decode, + + encodeCharacter: function(aImmune, c) { + if (aImmune.contains(c)) { + return c; + } + + var hex = org.owasp.esapi.codecs.Codec.getHexForNonAlphanumeric(c); + if (hex == null) { + return c; + } + + var cc = c.charCodeAt(0); + if (( cc <= 0x1f && c != '\t' && c != '\n' && c != '\r' ) || ( cc >= 0x7f && cc <= 0x9f ) || c == ' ') { + return " "; + } + + var entityName = characterToEntityMap[cc]; + if (entityName != null) { + return entityName + ";"; + } + + return "&#x" + hex + ";"; + }, + + decodeCharacter: function(oPushbackString) { + //noinspection UnnecessaryLocalVariableJS + var input = oPushbackString; + input.mark(); + var first = input.next(); + if (first == null || first != '&') { + input.reset(); + return null; + } + + var second = input.next(); + if (second == null) { + input.reset(); + return null; + } + + if (second == '#') { + var c = getNumericEntity(input); + if (c != null) { + return c; + } + } else if (second.match(/[A-Za-z]/)) { + input.pushback(second); + c = getNamedEntity(input); + if (c != null) { + return c; + } + } + input.reset(); + return null; + } + }; +}; + + +$namespace('org.owasp.esapi.codecs'); + +org.owasp.esapi.codecs.JavascriptCodec = function() { + var _super = new org.owasp.esapi.codecs.Codec(); + + return { + encode: function(aImmune, sInput) { + var out = ''; + for (var idx = 0; idx < sInput.length; idx ++) { + var ch = sInput.charAt(idx); + if (aImmune.contains(ch)) { + out += ch; + } + else { + var hex = org.owasp.esapi.codecs.Codec.getHexForNonAlphanumeric(ch); + if (hex == null) { + out += ch; + } + else { + var tmp = ch.charCodeAt(0).toString(16); + if (ch.charCodeAt(0) < 256) { + var pad = "00".substr(tmp.length); + out += "\\x" + pad + tmp.toUpperCase(); + } + else { + pad = "0000".substr(tmp.length); + out += "\\u" + pad + tmp.toUpperCase(); + } + } + } + } + return out; + }, + + decode: _super.decode, + + decodeCharacter: function(oPushbackString) { + oPushbackString.mark(); + var first = oPushbackString.next(); + if (first == null) { + oPushbackString.reset(); + return null; + } + + if (first != '\\') { + oPushbackString.reset(); + return null; + } + + var second = oPushbackString.next(); + if (second == null) { + oPushbackString.reset(); + return null; + } + + // \0 collides with the octal decoder and is non-standard + // if ( second.charValue() == '0' ) { + // return Character.valueOf( (char)0x00 ); + if (second == 'b') { + return 0x08; + } else if (second == 't') { + return 0x09; + } else if (second == 'n') { + return 0x0a; + } else if (second == 'v') { + return 0x0b; + } else if (second == 'f') { + return 0x0c; + } else if (second == 'r') { + return 0x0d; + } else if (second == '\"') { + return 0x22; + } else if (second == '\'') { + return 0x27; + } else if (second == '\\') { + return 0x5c; + } else if (second.toLowerCase() == 'x') { + out = ''; + for (var i = 0; i < 2; i++) { + var c = oPushbackString.nextHex(); + if (c != null) { + out += c; + } else { + input.reset(); + return null; + } + } + try { + n = parseInt(out, 16); + return String.fromCharCode(n); + } catch (e) { + oPushbackString.reset(); + return null; + } + } else if (second.toLowerCase() == 'u') { + out = ''; + for (i = 0; i < 4; i++) { + c = oPushbackString.nextHex(); + if (c != null) { + out += c; + } else { + input.reset(); + return null; + } + } + try { + var n = parseInt(out, 16); + return String.fromCharCode(n); + } catch (e) { + oPushbackString.reset(); + return null; + } + } else if (oPushbackString.isOctalDigit(second)) { + var out = second; + var c2 = oPushbackString.next(); + if (!oPushbackString.isOctalDigit(c2)) { + oPushbackString.pushback(c2); + } else { + out += c2; + var c3 = oPushbackString.next(); + if (!oPushbackString.isOctalDigit(c3)) { + oPushbackString.pushback(c3); + } else { + out += c3; + } + } + + try { + n = parseInt(out, 8); + return String.fromCharCode(n); + } catch (e) { + oPushbackString.reset(); + return null; + } + } + return second; + } + }; +}; + + +$namespace('org.owasp.esapi.codecs'); + +org.owasp.esapi.codecs.PercentCodec = function() { + var _super = new org.owasp.esapi.codecs.Codec(); + + var ALPHA_NUMERIC_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + var RFC_NON_ALPHANUMERIC_UNRESERVED_STR = "-._~"; + var ENCODED_NON_ALPHA_NUMERIC_UNRESERVED = true; + var UNENCODED_STR = ALPHA_NUMERIC_STR + (ENCODED_NON_ALPHA_NUMERIC_UNRESERVED ? "" : RFC_NON_ALPHANUMERIC_UNRESERVED_STR); + + var getTwoUpperBytes = function(b) { + var out = ''; + if (b < -128 || b > 127) { + throw new IllegalArgumentException("b is not a byte (was " + b + ")"); + } + b &= 0xFF; + if (b < 0x10) { + out += '0'; + } + return out + b.toString(16).toUpperCase(); + }; + + return { + encode: _super.encode, + + decode: _super.decode, + + encodeCharacter: function(aImmune, c) { + if (UNENCODED_STR.indexOf(c) > -1) { + return c; + } + + var bytes = org.owasp.esapi.codecs.UTF8.encode(c); + var out = ''; + for (var b = 0; b < bytes.length; b++) { + out += '%' + getTwoUpperBytes(bytes.charCodeAt(b)); + } + return out; + }, + + decodeCharacter: function(oPushbackString) { + oPushbackString.mark(); + var first = oPushbackString.next(); + if (first == null || first != '%') { + oPushbackString.reset(); + return null; + } + + var out = ''; + for (var i = 0; i < 2; i++) { + var c = oPushbackString.nextHex(); + if (c != null) { + out += c; + } + } + if (out.length == 2) { + try { + var n = parseInt(out, 16); + return String.fromCharCode(n); + } catch (e) { + } + } + oPushbackString.reset(); + return null; + } + }; +}; + + +$namespace('org.owasp.esapi.codecs'); + +org.owasp.esapi.codecs.PushbackString = function(sInput) { + var _input = sInput, + _pushback = '', + _temp = '', + _index = 0, + _mark = 0; + + return { + pushback: function(c) { + _pushback = c; + }, + + index: function() { + return _index; + }, + + hasNext: function() { + if (_pushback != null) return true; + return !(_input == null || _input.length == 0 || _index >= _input.length); + + }, + + next: function() { + if (_pushback != null) { + var save = _pushback; + _pushback = null; + return save; + } + if (_input == null || _input.length == 0 || _index >= _input.length) { + return null; + } + return _input.charAt(_index++); + }, + + nextHex: function() { + var c = this.next(); + if (this.isHexDigit(c)) return c; + return null; + }, + + nextOctal: function() { + var c = this.next(); + if (this.isOctalDigit(c)) return c; + return null; + }, + + isHexDigit: function(c) { + return c != null && ( ( c >= '0' && c <= '9' ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) ); + }, + + isOctalDigit: function(c) { + return c != null && ( c >= '0' && c <= '7' ); + }, + + peek: function(c) { + if (!c) { + if (_pushback != null) return _pushback; + if (_input == null || _input.length == 0 || _index >= _input.length) return null; + return _input.charAt(_index); + } else { + if (_pushback != null && _pushback == c) return true; + if (_input == null || _input.length == 0 || _index >= _input.length) return false; + return _input.charAt(_index) == c; + } + }, + + mark: function() { + _temp = _pushback; + _mark = _index; + }, + + reset: function() { + _pushback = _temp; + _index = _mark; + }, + + remainder: function() { + var out = _input.substr(_index); + if (_pushback != null) { + out = _pushback + out; + } + return out; + } + }; +}; + + +$namespace('org.owasp.esapi.codecs'); + +org.owasp.esapi.codecs.UTF8 = { + encode: function(sInput) { + var input = sInput.replace(/\r\n/g, "\n"); + var utftext = ''; + + for (var n = 0; n < input.length; n ++) { + var c = input.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if (( c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } + + return utftext; + } + , + + decode: function(sInput) { + var out = ''; + var i = c = c1 = c2 = 0; + + while (i < sInput.length) { + c = sInput.charCodeAt(i); + + if (c < 128) { + out += String.fromCharCode(c); + i ++; + } + else if ((c > 191) && (c < 224)) { + c2 = sInput.charCodeAt(i + 1); + out += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else { + c2 = utftext.charCodeAt(i + 1); + c3 = utftext.charCodeAt(i + 2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + } + + return out; + } +}; + + +$namespace('org.owasp.esapi.i18n'); + +org.owasp.esapi.i18n.ArrayResourceBundle = function( sName, oLocale, aMessages, oParent ) { + with(org.owasp.esapi.i18n) var _super = new ResourceBundle( sName, oLocale, oParent ); + + var messages = aMessages; + + return { + getParent: _super.getParent, + getLocale: _super.getLocale, + getName: _super.getName, + getString: _super.getString, + getMessage: function(sKey) { + return messages[sKey]; + } + }; +}; + + +$namespace('org.owasp.esapi.i18n'); + +org.owasp.esapi.i18n.Locale = function( sLanguage, sCountry, sVariant ) { + var language = sLanguage, country = sCountry, variant = sVariant; + + return { + getLanguage: function() { return language; }, + getCountry: function() { return country; }, + getVariant: function() { return variant; }, + toString: function() { return language + ( country ? "-" + country + ( variant ? "-" + variant : "" ) : "" ); } + }; +}; + +org.owasp.esapi.i18n.Locale.US = new org.owasp.esapi.i18n.Locale("en","US"); +org.owasp.esapi.i18n.Locale.GB = new org.owasp.esapi.i18n.Locale("en","GB"); + +org.owasp.esapi.i18n.Locale.getLocale = function(sLocale) { + var l = sLocale.split("-"); + return new org.owasp.esapi.i18n.Locale( l[0], (l.length>1?l[1]:""), (l.length>2?l.length[2]:"")); +}; + +org.owasp.esapi.i18n.Locale.getDefault = function() { + var l = (navigator['language']?navigator['language']:(navigator['userLanguage']?navigator['userLanguage']:'en-US')).split("-"); + return new org.owasp.esapi.i18n.Locale( l[0], (l.length>1?l[1]:""), (l.length>2?l.length[2]:"")); +}; + + +$namespace('org.owasp.esapi.i18n'); + +org.owasp.esapi.i18n.ObjectResourceBundle = function( oResource, oParent ) { + var _super = new org.owasp.esapi.i18n.ResourceBundle( oResource.name, org.owasp.esapi.i18n.Locale.getLocale(oResource.locale), oParent ); + + var messages = oResource.messages; + + return { + getParent: _super.getParent, + getLocale: _super.getLocale, + getName: _super.getName, + getString: _super.getString, + getMessage: function(sKey) { + return messages[sKey]; + } + }; +}; + + +$namespace('org.owasp.esapi.i18n'); + +org.owasp.esapi.i18n.ResourceBundle = function( sName, oLocale, oParentResourceBundle ) { + var parent = oParentResourceBundle; + var locale = oLocale; + var name = sName; + + if ( !name ) throw new SyntaxError("Name required for implementations of org.owasp.esapi.i18n.ResourceBundle"); + if ( !locale ) throw new SyntaxError("Locale required for implementations of org.owasp.esapi.i18n.ResourceBundle"); + + return { + getParent: function() { return parent; }, + getLocale: function() { return locale; }, + getName: function() { return name; }, + getMessage: function(sKey) { return sKey; }, + getString: function( sKey, oContextMap ) { + if ( arguments.length < 1 ) { + throw new IllegalArgumentException("No key passed to getString"); + } + + var msg = this.getMessage(sKey); + if ( !msg ) { + if ( parent ) { + return parent.getString( sKey, oContextMap ); + } else { + return sKey; + } + } + + if ( !msg.match( /\{([A-Za-z]+)\}/ ) || !oContextMap ) { + return msg; + } + + var out = '', lastIndex = 0; + while (true) { + var nextVarIdx = msg.indexOf( "{", lastIndex ); + var endIndex = msg.indexOf( "}", nextVarIdx ); + + if ( nextVarIdx < 0 ) { + out += msg.substr( lastIndex, msg.length-lastIndex ); + break; + } + + if ( nextVarIdx >= 0 && endIndex < -1 ) { + throw new SyntaxError("Invalid Message - Unclosed Context Reference: " + msg ); + } + + out += msg.substring( lastIndex, nextVarIdx ); + var contextKey = msg.substring( nextVarIdx+1, endIndex ); + if ( oContextMap[contextKey] ) { + out += oContextMap[contextKey]; + } else { + out += msg.substring( nextVarIdx, endIndex+1 ); + } + + lastIndex = endIndex + 1; + } + + return out; + } + }; +}; + +org.owasp.esapi.i18n.ResourceBundle.getResourceBundle = function(sResource, oLocale) { + var classname = sResource + "_" + oLocale.toString().replace("-","_"); + + with( org.owasp.esapi.i18n ) { + if ( ResourceBundle[classname] instanceof Object ) { + return ResourceBundle[classname]; + } else { + return new ResourceBundle[classname](); + } + } +}; + +$namespace('org.owasp.esapi.net'); + +/** + * Constructs a cookie with a specified name and value. + *

+ * The name must conform to RFC 2109. That means it can contain only ASCII alphanumeric characters and cannot contain + * commas, semicolons, or white space or begin with a $ character. The cookie's name cannot be changed after creation. + *

+ * The value can be anything the server chooses to send. Its value is probably of interest only to the server. The + * cookie's value can be changed after creation with the setValue method. + *

+ * By default, cookies are created according to the Netscape cookie specification. The version can be changed with the + * {@link #setVersion} method. + * + * @constructor + * @param sName {String} a String specifying the name of the cookie + * @param sValue {String} a String specifying the value of the cookie + * @throws IllegalArgumentException + * if the cookie name contains illegal characters (for example, a comma, space, or semicolon) or it is one of + * the tokens reserved for use by the cookie protocol + */ +org.owasp.esapi.net.Cookie = function( sName, sValue ) { + var name; // NAME= ... "$Name" style is reserved + var value; // value of NAME + + var comment; // ;Comment=VALUE ... describes the cookies use + var domain; // ;Domain=VALUE ... domain that sees the cookie + var maxAge; // ;Max-Age=VALUE ... cookies auto-expire + var path; // ;Path=VALUE ... URLs that see the cookie + var secure; // ;Secure ... e.g. use SSL + var version; // ;Version=1 ... means RFC-2109++ style + + var _resourceBundle = $ESAPI.resourceBundle(); + + var tSpecials = ",; "; + + var isToken = function(sValue) { + for(var i=0,len=sValue.length;i=0x7F||tSpecials.indexOf(c)!=-1) { + return false; + } + } + return true; + }; + + if ( !isToken(sName) + || sName.toLowerCase() == 'comment' + || sName.toLowerCase() == 'discard' + || sName.toLowerCase() == 'domain' + || sName.toLowerCase() == 'expires' + || sName.toLowerCase() == 'max-age' + || sName.toLowerCase() == 'path' + || sName.toLowerCase() == 'secure' + || sName.toLowerCase() == 'version' + || sName.charAt(0) == '$' ) { + var errMsg = _resourceBundle.getString( "Cookie.Name", { 'name':sName } ); + throw new IllegalArgumentException(errMsg); + } + + name = sName; + value = sValue; + + return { + setComment: function(purpose) { comment = purpose; }, + getComment: function() { return comment; }, + setDomain: function(sDomain) { domain = sDomain.toLowerCase(); }, + getDomain: function() { return domain; }, + setMaxAge: function(nExpirey) { maxAge = nExpirey; }, + getMaxAge: function() { return maxAge; }, + setPath: function(sPath) { path = sPath; }, + getPath: function() { return path; }, + setSecure: function(bSecure) { secure = bSecure; }, + getSecure: function() { return secure; }, + getName: function() { return name; }, + setValue: function(sValue) { value = sValue; }, + getValue: function() { return value; }, + setVersion: function(nVersion) { + if(nVersion<0||nVersion>1)throw new IllegalArgumentException(_resourceBundle.getString("Cookie.Version", { 'version':nVersion } ) ); + version = nVersion; + }, + getVersion: function() { return version; } + }; +}; + +$namespace('org.owasp.esapi.reference.encoding'); + +org.owasp.esapi.reference.encoding.DefaultEncoder = function(aCodecs) { + var _codecs = [], + _htmlCodec = new org.owasp.esapi.codecs.HTMLEntityCodec(), + _javascriptCodec = new org.owasp.esapi.codecs.JavascriptCodec(), + _cssCodec = new org.owasp.esapi.codecs.CSSCodec(), + _percentCodec = new org.owasp.esapi.codecs.PercentCodec(); + + if (!aCodecs) { + _codecs.push(_htmlCodec); + _codecs.push(_javascriptCodec); + _codecs.push(_cssCodec); + _codecs.push(_percentCodec); + } else { + _codecs = aCodecs; + } + + var IMMUNE_HTML = new Array(',', '.', '-', '_', ' '); + var IMMUNE_HTMLATTR = new Array(',', '.', '-', '_'); + var IMMUNE_CSS = new Array(); + var IMMUNE_JAVASCRIPT = new Array(',', '.', '_'); + + return { + cananicalize: function(sInput, bStrict) { + if (!sInput) { + return null; + } + var working = sInput, codecFound = null, mixedCount = 1, foundCount = 0, clean = false; + while (!clean) { + clean = true; + + _codecs.each(function(codec) { + var old = working; + working = codec.decode(working); + + if (old != working) { + if (codecFound != null && codecFound != codec) { + mixedCount ++; + } + codecFound = codec; + if (clean) { + foundCount ++; + } + clean = false; + } + }); + } + + if (foundCount >= 2 && mixedCount > 1) { + if (bStrict) { + throw new org.owasp.esapi.IntrusionException("Input validation failure", "Multiple (" + foundCount + "x) and mixed encoding (" + mixedCount + "x) detected in " + sInput); + } + } + else if (foundCount >= 2) { + if (bStrict) { + throw new org.owasp.esapi.IntrusionException("Input validation failure", "Multiple (" + foundCount + "x) encoding detected in " + sInput); + } + } + else if (mixedCount > 1) { + if (bStrict) { + throw new org.owasp.esapi.IntrusionException("Input validation failure", "Mixed (" + mixedCount + "x) encoding detected in " + sInput); + } + } + return working; + }, + + normalize: function(sInput) { + return sInput.replace(/[^\x00-\x7F]/g, ''); + }, + + encodeForHTML: function(sInput) { + return !sInput ? null : _htmlCodec.encode(IMMUNE_HTML, sInput); + }, + + decodeForHTML: function(sInput) { + return !sInput ? null : _htmlCodec.decode(sInput); + }, + + encodeForHTMLAttribute: function(sInput) { + return !sInput ? null : _htmlCodec.encode(IMMUNE_HTMLATTR, sInput); + }, + + encodeForCSS: function(sInput) { + return !sInput ? null : _cssCodec.encode(IMMUNE_CSS, sInput); + }, + + encodeForJavaScript: function(sInput) { + return !sInput ? null : _javascriptCodec.encode(IMMUNE_JAVASCRIPT, sInput); + }, + + encodeForJavascript: this.encodeForJavaScript, + + encodeForURL: function(sInput) { + return !sInput ? null : escape(sInput); + }, + + decodeFromURL: function(sInput) { + return !sInput ? null : unescape(sInput); + }, + + encodeForBase64: function(sInput) { + return !sInput ? null : org.owasp.esapi.codecs.Base64.encode(sInput); + }, + + decodeFromBase64: function(sInput) { + return !sInput ? null : org.owasp.esapi.codecs.Base64.decode(sInput); + } + }; +}; + + +$namespace('org.owasp.esapi.reference.logging'); + +org.owasp.esapi.reference.logging.Log4JSLogFactory = function() { + var loggersMap = Array(); + + var Log4JSLogger = function( sModuleName ) { + var jsLogger = null; + var moduleName = sModuleName?sModuleName:null; + var Level = Log4js.Level; + + var logUrl = false, logApplicationName = false, encodingRequired = false, encodingFunction = $ESAPI.encoder().encodeForHTML; + + jsLogger = Log4js.getLogger( moduleName ); + + var convertESAPILevel = function( nLevel ) { + var Logger = org.owasp.esapi.Logger; + switch (nLevel) { + case Logger.OFF: return Log4js.Level.OFF; + case Logger.FATAL: return Log4js.Level.FATAL; + case Logger.ERROR: return Log4js.Level.ERROR; + case Logger.WARNING: return Log4js.Level.WARN; + case Logger.INFO: return Log4js.Level.INFO; + case Logger.DEBUG: return Log4js.Level.DEBUG; + case Logger.TRACE: return Log4js.Level.TRACE; + case Logger.ALL: return Log4js.Level.ALL; + } + }; + + return { + setLevel: function( nLevel ) { + try { + jsLogger.setLevel( convertESAPILevel( nLevel ) ); + } catch (e) { + this.error( org.owasp.esapi.Logger.SECURITY_FAILURE, "", e ); + } + }, + + trace: function( oEventType, sMessage, oException ) { + this.log( Level.TRACE, oEventType, sMessage, oException ); + }, + + debug: function( oEventType, sMessage, oException ) { + this.log( Level.DEBUG, oEventType, sMessage, oException ); + }, + + info: function( oEventType, sMessage, oException ) { + this.log( Level.INFO, oEventType, sMessage, oException ); + }, + + warning: function( oEventType, sMessage, oException ) { + this.log( Level.WARN, oEventType, sMessage, oException ); + }, + + error: function( oEventType, sMessage, oException ) { + this.log( Level.ERROR, oEventType, sMessage, oException ); + }, + + fatal: function( oEventType, sMessage, oException ) { + this.log( Level.FATAL, oEventType, sMessage, oException ); + }, + + log: function( oLevel, oEventType, sMessage, oException ) { + switch(oLevel) { + case Level.TRACE: if ( !jsLogger.isTraceEnabled() ) { return; } break; + case Level.DEBUG: if ( !jsLogger.isDebugEnabled() ) { return; } break; + case Level.INFO: if ( !jsLogger.isInfoEnabled() ) { return; } break; + case Level.WARNING: if ( !jsLogger.isWarnEnabled() ) { return; } break; + case Level.ERROR: if ( !jsLogger.isErrorEnabled() ) { return; } break; + case Level.FATAL: if ( !jsLogger.isFatalEnabled() ) { return; } break; + } + + if ( !sMessage ) { + sMessage = ""; + } + + sMessage = '[' + oEventType.toString() + '] - ' + sMessage; + + var clean = sMessage.replace("\n","_").replace("\r","_"); + if ( encodingRequired ) { + clean = encodingFunction(clean); + if ( clean != sMessage) { + clean += " [Encoded]"; + } + } + + var appInfo = ( logUrl ? window.location.href : "" ) + + ( logApplicationName ? "/" + $ESAPI.properties.application.Name : "" ); + + jsLogger.log( oLevel, ( appInfo != "" ? "[" + appInfo + "] " : "" ) + clean, oException ); + }, + + addAppender: function( oAppender ) { + jsLogger.addAppender( oAppender ); + }, + + isLogUrl: function() { return logUrl; }, + setLogUrl: function(b) { logUrl = b; }, + isLogApplicationName: function() { return logApplicationName; }, + setLogApplicationName: function(b) { logApplicationName = b; }, + isEncodingRequired: function() { return encodingRequired; }, + setEncodingRequired: function(b) { encodingRequired = b; }, + setEncodingFunction: function(f) { encodingFunction = f; }, + isDebugEnabled: function() { return jsLogger.isDebugEnabled(); }, + isErrorEnabled: function() { return jsLogger.isErrorEnabled(); }, + isFatalEnabled: function() { return jsLogger.isFatalEnabled(); }, + isInfoEnabled: function() { return jsLogger.isInfoEnabled(); }, + isTraceEnabled: function() { return jsLogger.isTraceEnabled(); }, + isWarningEnabled: function() { return jsLogger.isWarnEnabled(); } + }; + }; + + var getLoggerConfig = function( moduleName ) { + var logConfig = $ESAPI.properties.logging; + if ( logConfig[moduleName] ) { + logConfig = logConfig[moduleName]; + } + return logConfig; + }; + + return { + getLogger: function ( moduleName ) { + var key = ( typeof moduleName == 'string' ) ? moduleName : moduleName.constructor.toString(); + var logger = loggersMap[key]; + if ( !logger ) { + logger = new Log4JSLogger(key); + + var logConfig = getLoggerConfig(moduleName); + + logger.setLevel( logConfig.Level ); + logger.setLogUrl( logConfig.LogUrl ); + logger.setLogApplicationName( logConfig.LogApplicationName ); + logger.setEncodingRequired( logConfig.EncodingRequired ); + + if ( logConfig.EncodingFunction ) { + logger.setEncodingFunction( logConfig.EncodingFunction ); + } + + logConfig.Appenders.each(function(e){ + if ( logConfig.Layout ) { + e.setLayout( logConfig.Layout ); + } + logger.addAppender(e); + }); + + loggersMap[key] = logger; + } + return logger; + } + }; +}; + + +$namespace('org.owasp.esapi.reference.validation'); + +org.owasp.esapi.reference.validation.BaseValidationRule = function( sTypeName, oEncoder, oLocale ) { + var log = $ESAPI.logger( "Validation" ); + var EventType = org.owasp.esapi.Logger.EventType; + + var typename = sTypeName; + var encoder = oEncoder?oEncoder:$ESAPI.encoder(); + var allowNull = false; + + var ResourceBundle = org.owasp.esapi.i18n.ResourceBundle; + + var locale = oLocale?oLocale:$ESAPI.locale(); + var resourceBundle; + + if ( $ESAPI.properties.validation.ResourceBundle ) { + resourceBundle = ResourceBundle.getResourceBundle( $ESAPI.properties.validation.ResourceBundle, locale ); + } + + if ( !resourceBundle ) { + resourceBundle = $ESAPI.resourceBundle(); + log.info( EventType.EVENT_FAILURE, "No Validation ResourceBundle - Defaulting to " + resourceBundle.getName() + "(" + resourceBundle.getLocale().toString() + ")" ); + } + + log.info( EventType.EVENT_SUCCESS, "Validation Rule Initialized with ResourceBundle: " + resourceBundle.getName() ); + + return { + setAllowNull: function(b) { allowNull = b; }, + + isAllowNull: function() { return allowNull; }, + + getTypeName: function() { return typename; }, + + setTypeName: function(s) { typename = s; }, + + setEncoder: function(oEncoder) { encoder = oEncoder; }, + + getEncoder: function() { return encoder; }, + + assertValid: function( sContext, sInput ) { + this.getValid( sContext, sInput ); + }, + + getValid: function( sContext, sInput, oValidationErrorList ) { + var valid = null; + try { + valid = this.getValidInput( sContext, sInput ); + } catch (oValidationException) { + return this.sanitize( sContext, sInput ); + } + return valid; + }, + + getValidInput: function( sContext, sInput ) { + return sInput; + }, + + getSafe: function( sContext, sInput ) { + var valid = null; + try { + valid = this.getValidInput( sContext, sInput ); + } catch (oValidationException) { + return this.sanitize( sContext, sInput ); + } + return valid; + }, + + /** + * The method is similar to ValidationRuile.getSafe except that it returns a + * harmless object that may or may not have any similarity to the original + * input (in some cases you may not care). In most cases this should be the + * same as the getSafe method only instead of throwing an exception, return + * some default value. + * + * @param context + * @param input + * @return a parsed version of the input or a default value. + */ + sanitize: function( sContext, sInput ) { + return sInput; + }, + + isValid: function( sContext, sInput ) { + var valid = false; + try { + this.getValidInput( sContext, sInput ); + valid = true; + } catch (oValidationException) { + return false; + } + return valid; + }, + + /** + * Removes characters that aren't in the whitelist from the input String. + * O(input.length) whitelist performance + * @param input String to be sanitized + * @param whitelist allowed characters + * @return input stripped of all chars that aren't in the whitelist + */ + whitelist: function( sInput, aWhitelist ) { + var stripped = ''; + for ( var i=0;i=0; j--) { + digit = parseInt(digitsonly.substring(j,i+1)); + if ( timesTwo ) { + addend = digit * 2; + if ( addend > 9 ) addend -= 9; + } else { + addend = digit; + } + sum += addend; + timesTwo = !timesTwo; + } + return sum % 10 == 0; + }; + + return { + getMaxCardLength: function() { return maxCardLength; }, + + setMaxCardLength: function(n) { maxCardLength = n; }, + + setAllowNull: _super.setAllowNull, + + isAllowNull: _super.isAllowNull, + + getTypeName: _super.getTypeName, + + setTypeName: _super.setTypeName, + + setEncoder: _super.setEncoder, + + getEncoder: _super.getEncoder, + + assertValid: _super.assertValid, + + getValid: _super.getValid, + + getValidInput: function( sContext, sInput ) { + if ( !sInput || sInput.trim() == '' ) { + if ( this.isAllowNull() ) { + return null; + } + _super.validationException( sContext, _validationType, "Required", { "context":sContext, "input":sInput } ); + } + + var canonical = ccrule.getValid( sContext, sInput ); + + if ( !validCreditCardFormat(canonical) ) { + _super.validationException( sContext, _validationType, "Invalid", { "context":sContext, "input":sInput } ); + } + + return canonical; + }, + + getSafe: _super.getSafe, + + sanitize: function( sContext, sInput ) { + return this.whitelist( sInput, org.owasp.esapi.EncoderConstants.CHAR_DIGITS ); + }, + + isValid: _super.isValid, + + whitelist: _super.whitelist + }; +}; + + +$namespace('org.owasp.esapi.reference.validation'); + +org.owasp.esapi.reference.validation.DateValidationRule = function( sTypeName, oEncoder, oLocale ) { + var _super = new org.owasp.esapi.reference.validation.BaseValidationRule( sTypeName, oEncoder, oLocale ); + var _validationTarget = "Date"; + + var format = DateFormat.getDateInstance(); + + var safelyParse = function(sContext,sInput) { + if ( !sContext || sContext.trim() == '' ) { + if ( _super.isAllowNull() ) { + return null; + } + _super.validationException( sContext, _validationTarget, "Required", { "context":sContext, "input":sInput, "format":format } ); + } + + var canonical = _super.getEncoder().cananicalize(sInput); + + try { + return format.parse(canonical); + } catch (e) { + _super.validationException( sContext, _validationTarget, "Invalid", { "context":sContext, "input":sInput, "format":format } ); + } + }; + + return { + setDateFormat: function(fmt) { + if ( !fmt ) { + throw new IllegalArgumentException("DateValidationRule.setDateFormat requires a non-null DateFormat"); + } + format = fmt; + }, + + setAllowNull: _super.setAllowNull, + + isAllowNull: _super.isAllowNull, + + getTypeName: _super.getTypeName, + + setTypeName: _super.setTypeName, + + setEncoder: _super.setEncoder, + + getEncoder: _super.getEncoder, + + assertValid: _super.assertValid, + + getValid: _super.getValid, + + getValidInput: function( sContext, sInput ) { + return safelyParse(sContext,sInput); + }, + + getSafe: _super.getSafe, + + sanitize: function( sContext, sInput ) { + var date = new Date(0); + try { + date = safelyParse(sContext,sInput); + } catch (e) { } + return date; + }, + + isValid: _super.isValid, + + whitelist: _super.whitelist + }; +}; + + +$namespace('org.owasp.esapi.reference.validation'); + +org.owasp.esapi.reference.validation.DefaultValidator = function( oEncoder, oLocale ) { + var rules = Array(); + var encoder = oEncoder?oEncoder:$ESAPI.encoder(); + var locale = oLocale?oLocale:org.owasp.esapi.i18n.Locale.getDefault(); + + var p = org.owasp.esapi.reference.validation; + + return { + addRule: function( oValidationRule ) { + rules[oValidationRule.getName()] = oValidationRule; + }, + + getRule: function( sName ) { + return rules[sName]; + }, + + isValidInput: function( sContext, sInput, sType, nMaxLength, bAllowNull ) { + try { + this.getValidInput( sContext, sInput, sType, nMaxLength, bAllowNull ); + return true; + } catch (e) { + return false; + } + }, + + getValidInput: function( sContext, sInput, sType, nMaxLength, bAllowNull, oValidationErrorList ) { + var rvr = new org.owasp.esapi.reference.validation.StringValidationRule( sType, encoder, locale ); + var p = new RegExp($ESAPI.properties.validation[sType]); + if ( p && p instanceof RegExp ) { + rvr.addWhitelistPattern( p ); + } else { + throw new IllegalArgumentException("Invalid Type: " + sType + " not found."); + } + rvr.setMaxLength( nMaxLength ); + rvr.setAllowNull( bAllowNull ); + + try { + return rvr.getValid(sContext,sInput); + } catch (e) { + if ( e instanceof p.ValidationErrorList && oValidationErrorList ) { + oValidationErrorList.addError( sContext, e ); + } + throw e; + } + }, + + isValidDate: function( sContext, sInput, oDateFormat, bAllowNull ) { + try { + this.getValidDate( sContext, sInput, oDateFormat, bAllowNull ); + return true; + } catch (e) { + return false; + } + }, + + getValidDate: function( sContext, sInput, oDateFormat, bAllowNull, oValidationErrorList ) { + var dvr = new p.DateValidationRule( sContext, encoder, locale ); + dvr.setAllowNull( bAllowNull ); + dvr.setDateFormat(oDateFormat); + try { + return dvr.getValid( sContext, sInput ); + } catch (e) { + if ( e instanceof p.ValidationErrorList && oValidationErrorList ) { + oValidationErrorList.addError( sContext, e ); + } + throw e; + } + }, + + getValidCreditCard: function( sContext, sInput, bAllowNull, oValidationErrorList ) { + var ccr = new p.CreditCardValidationRule( sContext, encoder, locale ); + ccr.setAllowNull(bAllowNull); + + try { + return ccr.getValid(sContext,sInput); + } catch (e) { + if ( e instanceof p.ValidationErrorList && oValidationErrorList ) { + oValidationErrorList.addError( sContext, e ); + } + throw e; + } + }, + + isValidCreditCard: function( sContext, sInput, bAllowNull ) { + try { + this.getValidCreditCard( sContext,sInput,bAllowNull ); + return true; + } catch (e) { + return false; + } + }, + + getValidNumber: function( sContext, sInput, bAllowNull, nMinValue, nMaxValue, oValidationErrorList ) { + var nvr = new p.NumberValidationRule( sContext, encoder, locale, nMinValue, nMaxValue ); + nvr.setAllowNull(bAllowNull); + + try { + return nvr.getValid(sContext, sInput); + } catch(e) { + if ( e instanceof p.ValidationErrorList && oValidationErrorList ) { + oValidationErrorList.addError( sContext, e ); + } + throw e; + } + }, + + isValidNumber: function( sContext, sInput, bAllowNull, nMinValue, nMaxValue ) { + try { + this.getValidNumber(sContext,sInput,bAllowNull,nMinValue,nMaxValue); + return true; + } catch (e) { + return false; + } + }, + + getValidInteger: function( sContext, sInput, bAllowNull, nMinValue, nMaxValue, oValidationErrorList ) { + var nvr = new p.IntegerValidationRule( sContext, encoder, locale, nMinValue, nMaxValue ); + nvr.setAllowNull(bAllowNull); + + try { + return nvr.getValid(sContext, sInput); + } catch(e) { + if ( e instanceof p.ValidationErrorList && oValidationErrorList ) { + oValidationErrorList.addError( sContext, e ); + } + throw e; + } + }, + + isValidInteger: function( sContext, sInput, bAllowNull, nMinValue, nMaxValue ) { + try { + this.getValidInteger(sContext,sInput,bAllowNull,nMinValue,nMaxValue); + return true; + } catch (e) { + return false; + } + } + }; +}; + + +$namespace('org.owasp.esapi.reference.validation'); + +org.owasp.esapi.reference.validation.IntegerValidationRule = function( sTypeName, oEncoder, oLocale, nMinValue, nMaxValue ) { + var _super = new org.owasp.esapi.reference.validation.BaseValidationRule( sTypeName, oEncoder, oLocale ); + var _validationTarget = "Integer"; + + var minValue = nMinValue?nMinValue:Number.MIN_VALUE; + var maxValue = nMaxValue?nMaxValue:Number.MAX_VALUE; + + if ( minValue >= maxValue ) { + throw new IllegalArgumentException( "minValue must be less than maxValue" ); + } + + var safelyParse = function(sContext,sInput) { + if ( !sInput || sInput.trim() == '' ) { + if ( _super.allowNull() ) { + return null; + } + _super.validationException( sContext, _validationTarget, "Required", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } ); + } + + var canonical = _super.getEncoder().cananicalize(sInput); + + var n = parseInt(canonical); + if ( n == 'NaN' ) { + _super.validationException( sContext, _validationTarget, "NaN", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } ); + } + if ( n < minValue ) { + _super.validationException( sContext, _validationTarget, "MinValue", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } ); + } + if ( n > maxValue ) { + _super.validationException( sContext, _validationTarget, "MaxValue", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } ); + } + return n; + }; + + return { + setMinValue: function(n) { minValue = n; }, + + getMinValue: function() { return minValue; }, + + setMaxValue: function(n) { maxValue = n; }, + + getMaxValue: function() { return maxValue; }, + + setAllowNull: _super.setAllowNull, + + isAllowNull: _super.isAllowNull, + + getTypeName: _super.getTypeName, + + setTypeName: _super.setTypeName, + + setEncoder: _super.setEncoder, + + getEncoder: _super.getEncoder, + + assertValid: _super.assertValid, + + getValid: _super.getValid, + + getValidInput: function( sContext, sInput ) { + return safelyParse(sContext,sInput); + }, + + getSafe: _super.getSafe, + + sanitize: function( sContext, sInput ) { + var n = 0; + try { + n = safelyParse(sContext,sInput); + } catch (e) { } + return n; + }, + + isValid: _super.isValid, + + whitelist: _super.whitelist + }; +}; + + +$namespace('org.owasp.esapi.reference.validation'); + +org.owasp.esapi.reference.validation.NumberValidationRule = function( sTypeName, oEncoder, oLocale, fMinValue, fMaxValue ) { + var _super = new org.owasp.esapi.reference.validation.BaseValidationRule( sTypeName, oEncoder, oLocale ); + var _validationTarget = 'Number'; + + var minValue = fMinValue?fMinValue:Number.MIN_VALUE; + var maxValue = fMaxValue?fMaxValue:Number.MAX_VALUE; + + if ( minValue >= maxValue ) throw new IllegalArgumentException("MinValue must be less that MaxValue"); + + var safelyParse = function( sContext, sInput ) { + if ( !sInput || sInput.trim() == '' ) { + if ( _super.isAllowNull() ) { + return null; + } + _super.validationException( sContext, _validationTarget, "Required", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } ); + } + + var canonical = _super.getEncoder().cananicalize( sInput ); + + var f = 0.0; + try { + f = parseFloat( canonical ); + } catch (e) { + _super.validationException( sContext, _validationTarget, "Invalid", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } ); + } + + if ( f == 'NaN' ) { + _super.validationException( sContext, _validationTarget, "NaN", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } ); + } + if ( f < minValue ) { + _super.validationException( sContext, _validationTarget, "MinValue", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } ); + } + if ( f > maxValue ) { + _super.validationException( sContext, _validationTarget, "MaxValue", { "context":sContext, "input":sInput, "minValue":minValue, "maxValue":maxValue } ); + } + return f; + }; + + return { + setMinValue: function(n) { minValue = n; }, + + getMinValue: function() { return minValue; }, + + setMaxValue: function(n) { maxValue = n; }, + + getMaxValue: function() { return maxValue; }, + + setAllowNull: _super.setAllowNull, + + isAllowNull: _super.isAllowNull, + + getTypeName: _super.getTypeName, + + setTypeName: _super.setTypeName, + + setEncoder: _super.setEncoder, + + getEncoder: _super.getEncoder, + + assertValid: _super.assertValid, + + getValid: _super.getValid, + + getValidInput: function( sContext, sInput ) { + return safelyParse(sContext,sInput); + }, + + getSafe: _super.getSafe, + + sanitize: function( sContext, sInput ) { + var n = 0; + try { + n = safelyParse(sContext,sInput); + } catch (e) { } + return n; + }, + + isValid: _super.isValid, + + whitelist: _super.whitelist + }; +}; + + +$namespace('org.owasp.esapi.reference.validation'); + +org.owasp.esapi.reference.validation.StringValidationRule = function( sTypeName, oEncoder, oLocale, sWhiteListPattern ) { + var _super = new org.owasp.esapi.reference.validation.BaseValidationRule( sTypeName, oEncoder, oLocale ); + var _validationTarget = 'String'; + + var whitelistPatterns = Array(); + var blacklistPatterns = Array(); + var minLength = 0; + var maxLength = Number.MAX_VALUE; + var validateInputAndCanonical = true; + + if ( sWhiteListPattern ) { + if ( sWhiteListPattern instanceof String ) { + whitelistPatterns.push( new RegExp(sWhiteListPattern) ); + } else if ( sWhiteListPattern instanceof RegExp ) { + whitelistPatterns.push( sWhiteListPattern ); + } else { + throw new IllegalArgumentException("sWhiteListPattern must be a string containing RegExp or a RegExp Object"); + } + } + + var checkWhitelist = function( sContext, sInput, sOrig ) { + whitelistPatterns.each(function(p){ + if ( sInput.match(p) ) { + _super.validationException( sContext, _validationTarget, "Whitelist", { "context":sContext, "input":sInput, "orig":sOrig, "pattern":p.toString(), "minLength":minLength, "maxLength":maxLength, "validateInputAndCanonical":validateInputAndCanonical } ); + } + }); + }; + + var checkBlacklist = function( sContext, sInput, sOrig ) { + blacklistPatterns.each(function(p){ + if ( sInput.match(p) ) { + _super.validationException( sContext, _validationTarget, "Blacklist", { "context":sContext, "input":sInput, "orig":sOrig, "pattern":p.toString(), "minLength":minLength, "maxLength":maxLength, "validateInputAndCanonical":validateInputAndCanonical } ); + } + }); + }; + + var checkLength = function( sContext, sInput, sOrig ) { + if ( sInput.length < minLength ) { + _super.validationException( sContext, _validationTarget, "MinLength", { "context":sContext, "input":sInput, "orig":sOrig, "minLength":minLength, "maxLength":maxLength, "validateInputAndCanonical":validateInputAndCanonical } ); + } + if ( sInput.length > maxLength ) { + _super.validationException( sContext, _validationTarget, "MaxLength", { "context":sContext, "input":sInput, "orig":sOrig, "minLength":minLength, "maxLength":maxLength, "validateInputAndCanonical":validateInputAndCanonical } ); + } + return sInput; + }; + + var checkEmpty = function( sContext, sInput, sOrig ) { + if ( !sInput || sInput.trim() == '' ) { + if ( _super.isAllowNull() ) { + return null; + } + _super.validationException( sContext, _validationTarget, "Required", { "context":sContext, "input":sInput, "orig":sOrig, "minLength":minLength, "maxLength":maxLength, "validateInputAndCanonical":validateInputAndCanonical } ); + } + }; + + return { + addWhitelistPattern: function(p) { + if ( p instanceof String ) { + whitelistPatterns.push( new RegExp(p) ); + } else if ( p instanceof RegExp ) { + whitelistPatterns.push(p); + } else { + throw new IllegalArgumentException("p must be a string containing RegExp or a RegExp Object"); + } + }, + + addBlacklistPattern: function(p) { + if ( p instanceof String ) { + blacklistPatterns.push( new RegExp(p) ); + } else if ( p instanceof RegExp ) { + blacklistPatterns.push(p); + } else { + throw new IllegalArgumentException("p must be a string containing RegExp or a RegExp Object"); + } + }, + + setMinLength: function(n) { minLength = n; }, + + getMinLength: function() { return minLength; }, + + setMaxLength: function(n) { maxLength = n; }, + + getMaxLength: function() { return maxLength; }, + + setValidateInputAndCanonical: function(b) { validateInputAndCanonical = b; }, + + isValidateInputAndCanonical: function() { return validateInputAndCanonical; }, + + setAllowNull: _super.setAllowNull, + + isAllowNull: _super.isAllowNull, + + getTypeName: _super.getTypeName, + + setTypeName: _super.setTypeName, + + setEncoder: _super.setEncoder, + + getEncoder: _super.getEncoder, + + assertValid: _super.assertValid, + + getValid: _super.getValid, + + getValidInput: function( sContext, sInput ) { + var canonical = null; + + if ( checkEmpty( sContext, sInput ) == null ) { + return null; + } + + if ( validateInputAndCanonical ) { + checkLength(sContext, sInput); + checkWhitelist(sContext,sInput); + checkBlacklist(sContext,sInput); + } + + canonical = this.getEncoder().cananicalize(sInput); + + if ( checkEmpty( sContext, canonical, sInput ) == null ) { + return null; + } + + checkLength( sContext, canonical, sInput ); + checkWhitelist( sContext, canonical, sInput ); + checkBlacklist( sContext, canonical, sInput ); + + return canonical; + }, + + getSafe: _super.getSafe, + + sanitize: function( sContext, sInput ) { + return this.whitelist( sInput, org.owasp.esapi.EncoderConstants.CHAR_ALNUM ); + }, + + isValid: _super.isValid, + + whitelist: _super.whitelist + }; +}; + + +$namespace('org.owasp.esapi.reference.validation'); + +org.owasp.esapi.reference.validation.ValidationException = function( sUserMessage, sLogMessage ) { + var oException, sContext; + if ( arguments[2] && arguments[2] instanceof Exception ) { + oException = arguments[2]; + if ( arguments[3] && arguments[3] instanceof String ) { + sContext = arguments[3]; + } + } else if ( arguments[2] && arguments[2] instanceof String ) { + sContext = arguments[2]; + } + + var _super = new org.owasp.esapi.EnterpriseSecurityException( sUserMessage, sLogMessage, oException ); + + return { + setContext: function(s) { sContext = s; }, + getContext: function() { return sContext; }, + getMessage: _super.getMessage, + getUserMessage: _super.getMessage, + getLogMessage: _super.getLogMessage, + getStackTrace: _super.getStackTrace, + printStackTrace: _super.printStackTrace + }; +}; diff --git a/fluidbook/compile/_js/fluidbook.js b/fluidbook/compile/_js/fluidbook.js index 7dd30868a..eb3141b99 100644 --- a/fluidbook/compile/_js/fluidbook.js +++ b/fluidbook/compile/_js/fluidbook.js @@ -1,290 +1,299 @@ -var _GET = parseGet(); -var _openedWindows = {}; - -function getWmode() { - if (_GET['wmode'] != undefined) { - return _GET['wmode']; - } - - var ua = navigator.userAgent; - if (ua.search(/mac/i) > -1 && ua.search(/opera/i) > -1) { - return 'normal'; - } else { - return 'direct'; - } -} - -function getLocation() { - return window.location.toString(); -} - -function getPath() { - var l = window.location; - - var res = l.toString(); - var origin = l.protocol + '//' + l.host - return res.replace(origin, ''); -} - -function getFlashvars(junk, fv) { - var res = {}; - if (fv != undefined) { - res = fv; - } - - res = parseGet(res); - - res['junk'] = junk; - return res; -} - -function parseGet(res) { - if (res == undefined) { - res = {}; - } - var couples = window.location.search.substr(1).split('&'); - var couple = new Array(); - for (var i = 0; i < couples.length; i++) { - couple = couples[i].split('='); - res[couple[0]] = couple[1]; - } - return res; -} - -function getLang() { - if (_GET.lang == undefined || _GET.lang == null || _GET.lang == '') { - return FB_DEFAULT_LANG; - } - return _GET.lang; -} - -function mailto(adresse) { - window.location = 'mailto:' + adresse; -} -function getBookmarks(id) { - return getCookie('fb_bookmarks_' + id); -} -function setBookmarks(data, id) { - date = new Date; - date.setFullYear(date.getFullYear() + 10); - setCookie('fb_bookmarks_' + id, data, date, '/'); -} - -function popupFS(page) { - if (page == undefined) { - page = 0; - } - var date = new Date().getTime(); - window.open('index.html#/' + page, 'fbpopupfs_' + date, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes'); -} - -function popupFocus(url, target) { - var openedw; - if (target.substr(0, 1) == '_') { - openedw = window.open(url, target, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes'); - } else { - if (_openedWindows[target] != undefined && _openedWindows[target] != null) { - openedw = _openedWindows[target]; - openedw.location = url; - } else { - openedw = window.open(url, target, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes'); - _openedWindows[target] = openedw; - } - } - - - - - openedw.focus(); -} - -function getCookieVal(offset) -{ - var endstr = document.cookie.indexOf(";", offset); - if (endstr == -1) { - endstr = document.cookie.length; - } - return unescape(document.cookie.substring(offset, endstr)); -} -function getCookie(nom) -{ - var arg = nom + "="; - var alen = arg.length; - var clen = document.cookie.length; - var i = 0; - while (i < clen) { - var j = i + alen; - if (document.cookie.substring(i, j) == arg) { - return getCookieVal(j); - } - i = document.cookie.indexOf(" ", i) + 1; - if (i == 0) { - break; - } - } - return null; -} -function setCookie(nom, valeur) -{ - date = new Date; - date.setFullYear(date.getFullYear() + 10); - - var argv = setCookie.arguments; - var argc = setCookie.arguments.length; - var expires = (argc > 2) ? argv[2] : date; - var path = (argc > 3) ? argv[3] : '/'; - var domain = (argc > 4) ? argv[4] : null; - var secure = (argc > 5) ? argv[5] : false; - document.cookie = nom + "=" + escape(valeur) + - ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + - ((path == null) ? "" : ("; path=/")) + - ((domain == null) ? "" : ("; domain=" + domain)) + - ((secure == true) ? "; secure" : ""); -} -function addThis(x) { - addthis_offset_left = parseFloat(x); - addthis_open(document.getElementById('addThisBt'), '', '[URL]', '[TITLE]'); -} -function handleWheel(delta) { - try { - fb(delta); - document.getElementById('fluidbook').mouseWheel(delta); - } catch (e) { - - } -} - -function isMobile() { - var devices = ['iphone', 'ipad', 'ipod', 'droid', 'blackberry', 'mobile', 'htc', 'samsung', 'nokia', 'archos', 'galaxy', 'motorola', 'pad', 'slate', 'symbian', 'phone', 'nintendo', 'playstation', 'touch', 'webos', 'ericsson', 'metro']; - return _isMobile(devices); -} - -function isBadMobile() { - var devices = ['kindle']; - return _isMobile(devices); -} - -function _isMobile(devices) { - var ua = navigator.userAgent; - var pattern; - - for (i = 0; i < devices.length; i++) { - pattern = new RegExp(devices[i], 'i'); - if (ua.search(pattern) > -1) { - return true; - } - } - return false; -} - -function redirectPDF() { - window.location = 'data/document.pdf'; -} - -function redirectMobile() { - var page = ''; - var get = parseGet(); - console.log(get); - var html = 'index.html'; - if (get['widget'] != undefined && get['widget'] == '1') { - html = 'widget.html'; - page = '?widget=1&'; - if (get['background'] != undefined) { - page += "background=" + get['background']; - } - } - var pageNr = 0; - if (get.page != undefined) { - pageNr = parseInt(get.page); - } - if (window.location.hash != '') { - var e = window.location.hash.split('/'); - var pnr = parseInt(e[1]); - if (!isNaN(pnr)) { - pageNr = pnr; - } - } - - - if (page == '' && pageNr > 0) { - page = '#/page/' + pageNr; - } - - window.location = 'm/' + html + page; -} - -function fb(e) { - try { - console.log(e); - } catch (err) { - - } -} - - -function wheel(event) { - var delta = 0; - if (!event) /* For IE. */ - event = window.event; - if (event.wheelDelta) { /* IE/Opera. */ - delta = event.wheelDelta / 120; - /** In Opera 9, delta differs in sign as compared to IE. - */ - if (window.opera) - delta = -delta; - } else if (event.detail) { /** Mozilla case. */ - /** In Mozilla, sign of delta is different than in IE. - * Also, delta is multiple of 3. - */ - delta = -event.detail / 3; - } - /** If delta is nonzero, handle it. - * Basically, delta is now positive if wheel was scrolled up, - * and negative, if wheel was scrolled down. - */ - if (delta) { - handleWheel(delta); - } - /** Prevent default actions caused by mouse wheel. - * That might be ugly, but we handle scrolls somehow - * anyway, so don't bother here.. - */ - if (event.preventDefault) { - event.preventDefault(); - } - event.returnValue = false; -} - -function ready() { - document.body.style.backgroundColor = '#' + getBackgroundColor(); -} - -function getBackgroundColor() { - if (_GET['background'] != undefined) { - return _GET['background']; - } else { - return backgroundColor; - } -} - -/** Initialization code. - * If you use your own event management code, change it as required. - */ -if (window.addEventListener) { - /** DOMMouseScroll is for mozilla. */ - window.addEventListener('DOMMouseScroll', wheel, false); -} -/** IE/Opera. */ -window.onmousewheel = document.onmousewheel = wheel; - -window.onkeydown = key; -window.onkeypress = key; -window.onkeydown = key; - -function key(e) { - if (e.ctrlKey && (e.keyCode == 80 || e.keyCode == 112)) { - return false; - } - - return true; +// Initialize the api +org.owasp.esapi.ESAPI.initialize(); + +var _GET = parseGet(); +var _openedWindows = {}; + +function getWmode() { + if (_GET['wmode'] != undefined) { + return _GET['wmode']; + } + + var ua = navigator.userAgent; + if (ua.search(/mac/i) > -1 && ua.search(/opera/i) > -1) { + return 'normal'; + } else { + return 'direct'; + } +} + +function getLocation() { + return window.location.toString(); +} + +function getPath() { + var l = window.location; + + var res = l.toString(); + var origin = l.protocol + '//' + l.host + return res.replace(origin, ''); +} + +function getFlashvars(junk, fv) { + var res = {}; + if (fv != undefined) { + res = fv; + } + + res = parseGet(res); + res['junk'] = $ESAPI.encoder().encodeForJavaScript(junk); + return res; +} + +function parseGet(res) { + if (res == undefined) { + res = {}; + } + var couples = window.location.search.substr(1).split('&'); + var couple = new Array(); + for (var i = 0; i < couples.length; i++) { + couple = couples[i].split('='); + res[couple[0]] = $ESAPI.httpUtilities().getRequestParameter(couple[0]); + } + return res; +} + +function getLang() { + if (_GET.lang == undefined || _GET.lang == null || _GET.lang == '') { + return FB_DEFAULT_LANG; + } + return _GET.lang; +} + +function mailto(adresse) { + window.location = 'mailto:' + adresse; +} +function getBookmarks(id) { + return getCookie('fb_bookmarks_' + id); +} +function setBookmarks(data, id) { + date = new Date; + date.setFullYear(date.getFullYear() + 10); + setCookie('fb_bookmarks_' + id, data, date, '/'); +} + +function popupFS(page) { + if (page == undefined) { + page = 0; + } + var date = new Date().getTime(); + window.open('index.html#/' + page, 'fbpopupfs_' + date, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes'); +} + +function popupFocus(url, target) { + var openedw; + if (target.substr(0, 1) == '_') { + openedw = window.open(url, target, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes'); + } else { + if (_openedWindows[target] != undefined && _openedWindows[target] != null) { + openedw = _openedWindows[target]; + openedw.location = url; + } else { + openedw = window.open(url, target, 'width=' + screen.width + ',height=' + screen.height + ',resizable=yes'); + _openedWindows[target] = openedw; + } + } + + + + + openedw.focus(); +} + +function getCookieVal(offset) +{ + var endstr = document.cookie.indexOf(";", offset); + if (endstr == -1) { + endstr = document.cookie.length; + } + return unescape(document.cookie.substring(offset, endstr)); +} +function getCookie(nom) +{ + return $ESAPI.httpUtilities().getCookie(nom); + + /*var arg = nom + "="; + var alen = arg.length; + var clen = document.cookie.length; + var i = 0; + while (i < clen) { + var j = i + alen; + if (document.cookie.substring(i, j) == arg) { + return getCookieVal(j); + } + i = document.cookie.indexOf(" ", i) + 1; + if (i == 0) { + break; + } + } + return null;*/ +} +function setCookie(nom, valeur) +{ + var cookie = new org.owasp.esapi.net.Cookie(nom, valeur); + cookie.setMaxAge(10 * 365 * 24 * 3600); + return $ESAPI.httpUtilities().addCookie(cookie); + + + /*date = new Date; + date.setFullYear(date.getFullYear() + 10); + + var argv = setCookie.arguments; + var argc = setCookie.arguments.length; + var expires = (argc > 2) ? argv[2] : date; + var path = (argc > 3) ? argv[3] : '/'; + var domain = (argc > 4) ? argv[4] : null; + var secure = (argc > 5) ? argv[5] : false; + document.cookie = nom + "=" + escape(valeur) + + ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + + ((path == null) ? "" : ("; path=/")) + + ((domain == null) ? "" : ("; domain=" + domain)) + + ((secure == true) ? "; secure" : "");*/ +} +function addThis(x) { + addthis_offset_left = parseFloat(x); + addthis_open(document.getElementById('addThisBt'), '', '[URL]', '[TITLE]'); +} +function handleWheel(delta) { + try { + fb(delta); + document.getElementById('fluidbook').mouseWheel(delta); + } catch (e) { + + } +} + +function isMobile() { + var devices = ['iphone', 'ipad', 'ipod', 'droid', 'blackberry', 'mobile', 'htc', 'samsung', 'nokia', 'archos', 'galaxy', 'motorola', 'pad', 'slate', 'symbian', 'phone', 'nintendo', 'playstation', 'touch', 'webos', 'ericsson', 'metro']; + return _isMobile(devices); +} + +function isBadMobile() { + var devices = ['kindle']; + return _isMobile(devices); +} + +function _isMobile(devices) { + var ua = navigator.userAgent; + var pattern; + + for (i = 0; i < devices.length; i++) { + pattern = new RegExp(devices[i], 'i'); + if (ua.search(pattern) > -1) { + return true; + } + } + return false; +} + +function redirectPDF() { + window.location = 'data/document.pdf'; +} + +function redirectMobile() { + var page = ''; + var get = parseGet(); + console.log(get); + var html = 'index.html'; + if (get['widget'] != undefined && get['widget'] == '1') { + html = 'widget.html'; + page = '?widget=1&'; + if (get['background'] != undefined) { + page += "background=" + get['background']; + } + } + var pageNr = 0; + if (get.page != undefined) { + pageNr = parseInt(get.page); + } + if (window.location.hash != '') { + var e = window.location.hash.split('/'); + var pnr = parseInt(e[1]); + if (!isNaN(pnr)) { + pageNr = pnr; + } + } + + + if (page == '' && pageNr > 0) { + page = '#/page/' + pageNr; + } + + window.location = 'm/' + html + page; +} + +function fb(e) { + try { + console.log(e); + } catch (err) { + + } +} + + +function wheel(event) { + var delta = 0; + if (!event) /* For IE. */ + event = window.event; + if (event.wheelDelta) { /* IE/Opera. */ + delta = event.wheelDelta / 120; + /** In Opera 9, delta differs in sign as compared to IE. + */ + if (window.opera) + delta = -delta; + } else if (event.detail) { /** Mozilla case. */ + /** In Mozilla, sign of delta is different than in IE. + * Also, delta is multiple of 3. + */ + delta = -event.detail / 3; + } + /** If delta is nonzero, handle it. + * Basically, delta is now positive if wheel was scrolled up, + * and negative, if wheel was scrolled down. + */ + if (delta) { + handleWheel(delta); + } + /** Prevent default actions caused by mouse wheel. + * That might be ugly, but we handle scrolls somehow + * anyway, so don't bother here.. + */ + if (event.preventDefault) { + event.preventDefault(); + } + event.returnValue = false; +} + +function ready() { + document.body.style.backgroundColor = '#' + getBackgroundColor(); +} + +function getBackgroundColor() { + if (_GET['background'] != undefined) { + return _GET['background']; + } else { + return backgroundColor; + } +} + +/** Initialization code. + * If you use your own event management code, change it as required. + */ +if (window.addEventListener) { + /** DOMMouseScroll is for mozilla. */ + window.addEventListener('DOMMouseScroll', wheel, false); +} +/** IE/Opera. */ +window.onmousewheel = document.onmousewheel = wheel; + +window.onkeydown = key; +window.onkeypress = key; +window.onkeydown = key; + +function key(e) { + if (e.ctrlKey && (e.keyCode == 80 || e.keyCode == 112)) { + return false; + } + + return true; } \ No newline at end of file diff --git a/fluidbook/compile/_js/log4js-lib.js b/fluidbook/compile/_js/log4js-lib.js new file mode 100644 index 000000000..86a66979b --- /dev/null +++ b/fluidbook/compile/_js/log4js-lib.js @@ -0,0 +1 @@ +var Log4js={version:"1.0",applicationStartDate:new Date(),loggers:{},getLogger:function(categoryName){if(!(typeof categoryName=="string")){categoryName="[default]";}if(!Log4js.loggers[categoryName]){Log4js.loggers[categoryName]=new Log4js.Logger(categoryName);}return Log4js.loggers[categoryName];},getDefaultLogger:function(){return Log4js.getLogger("[default]");},attachEvent:function(element,name,observer){if(element.addEventListener){element.addEventListener(name,observer,false);}else if(element.attachEvent){element.attachEvent('on'+name,observer);}}};Log4js.extend=function(destination,source){for(property in source){destination[property]=source[property];}return destination;}Log4js.bind=function(fn,object){return function(){return fn.apply(object,arguments);};};Log4js.Level=function(level,levelStr){this.level=level;this.levelStr=levelStr;};Log4js.Level.prototype={toLevel:function(sArg,defaultLevel){if(sArg===null){return defaultLevel;}if(typeof sArg=="string"){var s=sArg.toUpperCase();if(s=="ALL"){return Log4js.Level.ALL;}if(s=="DEBUG"){return Log4js.Level.DEBUG;}if(s=="INFO"){return Log4js.Level.INFO;}if(s=="WARN"){return Log4js.Level.WARN;}if(s=="ERROR"){return Log4js.Level.ERROR;}if(s=="FATAL"){return Log4js.Level.FATAL;}if(s=="OFF"){return Log4js.Level.OFF;}if(s=="TRACE"){return Log4js.Level.TRACE;}return defaultLevel;}else if(typeof sArg=="number"){switch(sArg){case ALL_INT:return Log4js.Level.ALL;case DEBUG_INT:return Log4js.Level.DEBUG;case INFO_INT:return Log4js.Level.INFO;case WARN_INT:return Log4js.Level.WARN;case ERROR_INT:return Log4js.Level.ERROR;case FATAL_INT:return Log4js.Level.FATAL;case OFF_INT:return Log4js.Level.OFF;case TRACE_INT:return Log4js.Level.TRACE;default:return defaultLevel;}}else{return defaultLevel;}},toString:function(){return this.levelStr;},valueOf:function(){return this.level;}};Log4js.Level.OFF_INT=Number.MAX_VALUE;Log4js.Level.FATAL_INT=50000;Log4js.Level.ERROR_INT=40000;Log4js.Level.WARN_INT=30000;Log4js.Level.INFO_INT=20000;Log4js.Level.DEBUG_INT=10000;Log4js.Level.TRACE_INT=5000;Log4js.Level.ALL_INT=Number.MIN_VALUE;Log4js.Level.OFF=new Log4js.Level(Log4js.Level.OFF_INT,"OFF");Log4js.Level.FATAL=new Log4js.Level(Log4js.Level.FATAL_INT,"FATAL");Log4js.Level.ERROR=new Log4js.Level(Log4js.Level.ERROR_INT,"ERROR");Log4js.Level.WARN=new Log4js.Level(Log4js.Level.WARN_INT,"WARN");Log4js.Level.INFO=new Log4js.Level(Log4js.Level.INFO_INT,"INFO");Log4js.Level.DEBUG=new Log4js.Level(Log4js.Level.DEBUG_INT,"DEBUG");Log4js.Level.TRACE=new Log4js.Level(Log4js.Level.TRACE_INT,"TRACE");Log4js.Level.ALL=new Log4js.Level(Log4js.Level.ALL_INT,"ALL");Log4js.CustomEvent=function(){this.listeners=[];};Log4js.CustomEvent.prototype={addListener:function(method){this.listeners.push(method);},removeListener:function(method){var foundIndexes=this.findListenerIndexes(method);for(var i=0;i\n\n");doc.write("Log4js - "+this.logger.category+"\n");doc.write("\n");win.blur();win.focus();}this.docReference=doc;this.winReference=win;}else{this.docReference=document;this.winReference=window;}this.outputCount=0;this.tagPattern=".*";this.logElement=this.docReference.createElement('div');this.docReference.body.appendChild(this.logElement);this.logElement.style.display='none';this.logElement.style.position="absolute";this.logElement.style.left='0px';this.logElement.style.width='100%';this.logElement.style.textAlign="left";this.logElement.style.fontFamily="lucida console";this.logElement.style.fontSize="100%";this.logElement.style.backgroundColor='darkgray';this.logElement.style.opacity=0.9;this.logElement.style.zIndex=2000;this.toolbarElement=this.docReference.createElement('div');this.logElement.appendChild(this.toolbarElement);this.toolbarElement.style.padding="0 0 0 2px";this.buttonsContainerElement=this.docReference.createElement('span');this.toolbarElement.appendChild(this.buttonsContainerElement);if(this.inline){var closeButton=this.docReference.createElement('button');closeButton.style.cssFloat="right";closeButton.style.styleFloat="right";closeButton.style.color="black";closeButton.innerHTML="close";closeButton.onclick=Log4js.bind(this.toggle,this);this.buttonsContainerElement.appendChild(closeButton);}var clearButton=this.docReference.createElement('button');clearButton.style.cssFloat="right";clearButton.style.styleFloat="right";clearButton.style.color="black";clearButton.innerHTML="clear";clearButton.onclick=Log4js.bind(this.logger.clear,this.logger);this.buttonsContainerElement.appendChild(clearButton);this.tagFilterContainerElement=this.docReference.createElement('span');this.toolbarElement.appendChild(this.tagFilterContainerElement);this.tagFilterContainerElement.style.cssFloat='left';this.tagFilterContainerElement.appendChild(this.docReference.createTextNode("Log4js - "+this.logger.category));this.tagFilterContainerElement.appendChild(this.docReference.createTextNode(" | Level Filter: "));this.tagFilterElement=this.docReference.createElement('input');this.tagFilterContainerElement.appendChild(this.tagFilterElement);this.tagFilterElement.style.width='200px';this.tagFilterElement.value=this.tagPattern;this.tagFilterElement.setAttribute('autocomplete','off');Log4js.attachEvent(this.tagFilterElement,'keyup',Log4js.bind(this.updateTags,this));Log4js.attachEvent(this.tagFilterElement,'click',Log4js.bind(function(){this.tagFilterElement.select();},this));this.outputElement=this.docReference.createElement('div');this.logElement.appendChild(this.outputElement);this.outputElement.style.overflow="auto";this.outputElement.style.clear="both";this.outputElement.style.height=(this.inline)?("200px"):("650px");this.outputElement.style.width="100%";this.outputElement.style.backgroundColor='black';this.inputContainerElement=this.docReference.createElement('div');this.inputContainerElement.style.width="100%";this.logElement.appendChild(this.inputContainerElement);this.inputElement=this.docReference.createElement('input');this.inputContainerElement.appendChild(this.inputElement);this.inputElement.style.width='100%';this.inputElement.style.borderWidth='0px';this.inputElement.style.margin='0px';this.inputElement.style.padding='0px';this.inputElement.value='Type command here';this.inputElement.setAttribute('autocomplete','off');Log4js.attachEvent(this.inputElement,'keyup',Log4js.bind(this.handleInput,this));Log4js.attachEvent(this.inputElement,'click',Log4js.bind(function(){this.inputElement.select();},this));if(this.inline){window.setInterval(Log4js.bind(this.repositionWindow,this),500);this.repositionWindow();var accessElement=this.docReference.createElement('button');accessElement.style.position="absolute";accessElement.style.top="-100px";accessElement.accessKey=this.accesskey;accessElement.onclick=Log4js.bind(this.toggle,this);this.docReference.body.appendChild(accessElement);}else{this.show();}},toggle:function(){if(this.logElement.style.display=='none'){this.show();return true;}else{this.hide();return false;}},show:function(){this.logElement.style.display='';this.outputElement.scrollTop=this.outputElement.scrollHeight;this.inputElement.select();},hide:function(){this.logElement.style.display='none';},output:function(message,style){var shouldScroll=(this.outputElement.scrollTop+(2*this.outputElement.clientHeight))>=this.outputElement.scrollHeight;this.outputCount++;style=(style?style+=';':'');style+='padding:1px;margin:0 0 5px 0';if(this.outputCount%2===0){style+=";background-color:#101010";}message=message||"undefined";message=message.toString();this.outputElement.innerHTML+="

"+message+"
";if(shouldScroll){this.outputElement.scrollTop=this.outputElement.scrollHeight;}},updateTags:function(){var pattern=this.tagFilterElement.value;if(this.tagPattern==pattern){return;}try{new RegExp(pattern);}catch(e){return;}this.tagPattern=pattern;this.outputElement.innerHTML="";this.outputCount=0;for(var i=0;i"+e.message);break;}this.logger.trace(consoleOutput);break;}if(this.inputElement.value!==""&&this.inputElement.value!==this.commandHistory[0]){this.commandHistory.unshift(this.inputElement.value);}this.commandIndex=0;this.inputElement.value="";}else if(e.keyCode==38&&this.commandHistory.length>0){this.inputElement.value=this.commandHistory[this.commandIndex];if(this.commandIndex0){if(this.commandIndex>0){this.commandIndex-=1;}this.inputElement.value=this.commandHistory[this.commandIndex];}else{this.commandIndex=0;}},toString:function(){return "Log4js.ConsoleAppender[inline="+this.inline+"]";}});Log4js.MetatagAppender=function(){this.currentLine=0;};Log4js.MetatagAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){var now=new Date();var lines=loggingEvent.message.split("\n");var headTag=document.getElementsByTagName("head")[0];for(var i=1;i<=lines.length;i++){var value=lines[i-1];if(i==1){value=loggingEvent.level.toString()+": "+value;}else{value="> "+value;}var metaTag=document.createElement("meta");metaTag.setAttribute("name","X-log4js:"+this.currentLine);metaTag.setAttribute("content",value);headTag.appendChild(metaTag);this.currentLine+=1;}},toString:function(){return "Log4js.MetatagAppender";}});Log4js.AjaxAppender=function(loggingUrl){this.isInProgress=false;this.loggingUrl=loggingUrl||"logging.log4js";this.threshold=1;this.timeout=2000;this.loggingEventMap=new Log4js.FifoBuffer();this.layout=new Log4js.XMLLayout();this.httpRequest=null;};Log4js.AjaxAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){log4jsLogger.trace("> AjaxAppender.append");if(this.loggingEventMap.length()<=this.threshold||this.isInProgress===true){this.loggingEventMap.push(loggingEvent);}if(this.loggingEventMap.length()>=this.threshold&&this.isInProgress===false){this.send();}log4jsLogger.trace("< AjaxAppender.append");},doClear:function(){log4jsLogger.trace("> AjaxAppender.doClear");if(this.loggingEventMap.length()>0){this.send();}log4jsLogger.trace("< AjaxAppender.doClear");},setThreshold:function(threshold){log4jsLogger.trace("> AjaxAppender.setThreshold: "+threshold);this.threshold=threshold;log4jsLogger.trace("< AjaxAppender.setThreshold");},setTimeout:function(milliseconds){this.timeout=milliseconds;},send:function(){if(this.loggingEventMap.length()>0){log4jsLogger.trace("> AjaxAppender.send");this.isInProgress=true;var a=[];for(var i=0;i AjaxAppender.timeout");appender.httpRequest.onreadystatechange=function(){return;};appender.httpRequest.abort();appender.isInProgress=false;if(appender.loggingEventMap.length()>0){appender.send();}log4jsLogger.trace("< AjaxAppender.timeout");},this.timeout);}catch(e){log4jsLogger.fatal(e);}log4jsLogger.trace("> AjaxAppender.send");}},onReadyStateChanged:function(){log4jsLogger.trace("> AjaxAppender.onReadyStateChanged");var req=this.httpRequest;if(this.httpRequest.readyState!=4){log4jsLogger.trace("< AjaxAppender.onReadyStateChanged: readyState "+req.readyState+" != 4");return;}var success=((typeof req.status==="undefined")||req.status===0||(req.status>=200&&req.status<300));if(success){log4jsLogger.trace(" AjaxAppender.onReadyStateChanged: success");this.isInProgress=false;}else{var msg=" AjaxAppender.onReadyStateChanged: XMLHttpRequest request to URL "+this.loggingUrl+" returned status code "+this.httpRequest.status;log4jsLogger.error(msg);}log4jsLogger.trace("< AjaxAppender.onReadyStateChanged: readyState == 4");},getXmlHttpRequest:function(){log4jsLogger.trace("> AjaxAppender.getXmlHttpRequest");var httpRequest=false;try{if(window.XMLHttpRequest){httpRequest=new XMLHttpRequest();if(httpRequest.overrideMimeType){httpRequest.overrideMimeType(this.layout.getContentType());}}else if(window.ActiveXObject){try{httpRequest=new ActiveXObject("Msxml2.XMLHTTP");}catch(e){httpRequest=new ActiveXObject("Microsoft.XMLHTTP");}}}catch(e){httpRequest=false;}if(!httpRequest){log4jsLogger.fatal("Unfortunatelly your browser does not support AjaxAppender for log4js!");}log4jsLogger.trace("< AjaxAppender.getXmlHttpRequest");return httpRequest;},toString:function(){return "Log4js.AjaxAppender[loggingUrl="+this.loggingUrl+", threshold="+this.threshold+"]";}});Log4js.FileAppender=function(file){this.layout=new Log4js.SimpleLayout();this.isIE='undefined';this.file=file||"log4js.log";try{this.fso=new ActiveXObject("Scripting.FileSystemObject");this.isIE=true;}catch(e){try{netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");this.fso=Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);this.isIE=false;}catch(e){log4jsLogger.error(e);}}};Log4js.FileAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){try{var fileHandle=null;if(this.isIE==='undefined'){log4jsLogger.error("Unsupported ")}else if(this.isIE){fileHandle=this.fso.OpenTextFile(this.file,8,true);fileHandle.WriteLine(this.layout.format(loggingEvent));fileHandle.close();}else{netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");this.fso.initWithPath(this.file);if(!this.fso.exists()){this.fso.create(0x00,0600);}fileHandle=Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);fileHandle.init(this.fso,0x04|0x08|0x10,064,0);var line=this.layout.format(loggingEvent);fileHandle.write(line,line.length);fileHandle.close();}}catch(e){log4jsLogger.error(e);}},doClear:function(){try{if(this.isIE){var fileHandle=this.fso.GetFile(this.file);fileHandle.Delete();}else{netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");this.fso.initWithPath(this.file);if(this.fso.exists()){this.fso.remove(false);}}}catch(e){log4jsLogger.error(e);}},toString:function(){return "Log4js.FileAppender[file="+this.file+"]";}});Log4js.WindowsEventAppender=function(){this.layout=new Log4js.SimpleLayout();try{this.shell=new ActiveXObject("WScript.Shell");}catch(e){log4jsLogger.error(e);}};Log4js.WindowsEventAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){var winLevel=4;switch(loggingEvent.level){case Log4js.Level.FATAL:winLevel=1;break;case Log4js.Level.ERROR:winLevel=1;break;case Log4js.Level.WARN:winLevel=2;break;default:winLevel=4;break;}try{this.shell.LogEvent(winLevel,this.level.format(loggingEvent));}catch(e){log4jsLogger.error(e);}},toString:function(){return "Log4js.WindowsEventAppender";}});Log4js.JSAlertAppender=function(){this.layout=new Log4js.SimpleLayout();};Log4js.JSAlertAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){alert(this.layout.getHeader()+this.layout.format(loggingEvent)+this.layout.getFooter());},toString:function(){return "Log4js.JSAlertAppender";}});Log4js.MozillaJSConsoleAppender=function(){this.layout=new Log4js.SimpleLayout();try{netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");this.jsConsole=Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);this.scriptError=Components.classes["@mozilla.org/scripterror;1"].createInstance(Components.interfaces.nsIScriptError);}catch(e){log4jsLogger.error(e);}};Log4js.MozillaJSConsoleAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){try{netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");this.scriptError.init(this.layout.format(loggingEvent),null,null,null,null,this.getFlag(loggingEvent),loggingEvent.categoryName);this.jsConsole.logMessage(this.scriptError);}catch(e){log4jsLogger.error(e);}},toString:function(){return "Log4js.MozillaJSConsoleAppender";},getFlag:function(loggingEvent){var retval;switch(loggingEvent.level){case Log4js.Level.FATAL:retval=2;break;case Log4js.Level.ERROR:retval=0;break;case Log4js.Level.WARN:retval=1;break;default:retval=1;break;}return retval;}});Log4js.OperaJSConsoleAppender=function(){this.layout=new Log4js.SimpleLayout();};Log4js.OperaJSConsoleAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){opera.postError(this.layout.format(loggingEvent));},toString:function(){return "Log4js.OperaJSConsoleAppender";}});Log4js.SafariJSConsoleAppender=function(){this.layout=new Log4js.SimpleLayout();};Log4js.SafariJSConsoleAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){window.console.log(this.layout.format(loggingEvent));},toString:function(){return "Log4js.SafariJSConsoleAppender";}});Log4js.BrowserConsoleAppender=function(){this.consoleDelegate=null;if(window.console){this.consoleDelegate=new Log4js.SafariJSConsoleAppender();}else if(window.opera){this.consoleDelegate=new Log4js.OperaJSConsoleAppender();}else if(netscape){this.consoleDelegate=new Log4js.MozJSConsoleAppender();}else{log4jsLogger.error("Unsupported Browser");}};Log4js.BrowserConsoleAppender.prototype=Log4js.extend(new Log4js.Appender(),{doAppend:function(loggingEvent){this.consoleDelegate.doAppend(loggingEvent);},doClear:function(){this.consoleDelegate.doClear();},setLayout:function(layout){this.consoleDelegate.setLayout(layout);},toString:function(){return "Log4js.BrowserConsoleAppender: "+this.consoleDelegate.toString();}});Log4js.SimpleLayout=function(){this.LINE_SEP="\n";this.LINE_SEP_LEN=1;};Log4js.SimpleLayout.prototype=Log4js.extend(new Log4js.Layout(),{format:function(loggingEvent){return loggingEvent.level.toString()+" - "+loggingEvent.message+this.LINE_SEP;},getContentType:function(){return "text/plain";},getHeader:function(){return "";},getFooter:function(){return "";}});Log4js.BasicLayout=function(){this.LINE_SEP="\n";};Log4js.BasicLayout.prototype=Log4js.extend(new Log4js.Layout(),{format:function(loggingEvent){return loggingEvent.categoryName+"~"+loggingEvent.startTime.toLocaleString()+" ["+loggingEvent.level.toString()+"] "+loggingEvent.message+this.LINE_SEP;},getContentType:function(){return "text/plain";},getHeader:function(){return "";},getFooter:function(){return "";}});Log4js.HtmlLayout=function(){return;};Log4js.HtmlLayout.prototype=Log4js.extend(new Log4js.Layout(),{format:function(loggingEvent){return "
"+loggingEvent.getFormattedTimestamp()+" - "+loggingEvent.level.toString()+" - "+loggingEvent.message+"
\n";},getContentType:function(){return "text/html";},getHeader:function(){return "log4js</head><body>";},getFooter:function(){return "</body></html>";},getStyle:function(loggingEvent){var style;if(loggingEvent.level.toString().search(/ERROR/)!=-1){style='color:red';}else if(loggingEvent.level.toString().search(/FATAL/)!=-1){style='color:red';}else if(loggingEvent.level.toString().search(/WARN/)!=-1){style='color:orange';}else if(loggingEvent.level.toString().search(/DEBUG/)!=-1){style='color:green';}else if(loggingEvent.level.toString().search(/INFO/)!=-1){style='color:white';}else{style='color:yellow';}return style;}});Log4js.XMLLayout=function(){return;};Log4js.XMLLayout.prototype=Log4js.extend(new Log4js.Layout(),{format:function(loggingEvent){var useragent="unknown";try{useragent=navigator.userAgent;}catch(e){useragent="unknown";}var referer="unknown";try{referer=location.href;}catch(e){referer="unknown";}var content="<log4js:event logger=\"";content+=loggingEvent.categoryName+"\" level=\"";content+=loggingEvent.level.toString()+"\" useragent=\"";content+=useragent+"\" referer=\"";content+=referer.replace(/&/g,"&")+"\" timestamp=\"";content+=loggingEvent.getFormattedTimestamp()+"\">\n";content+="\t<log4js:message><![CDATA["+this.escapeCdata(loggingEvent.message)+"]]></log4js:message>\n";if(loggingEvent.exception){content+=this.formatException(loggingEvent.exception);}content+="</log4js:event>\n";return content;},getContentType:function(){return "text/xml";},getHeader:function(){return "<log4js:eventSet version=\""+Log4js.version+"\" xmlns:log4js=\"http://log4js.berlios.de/2007/log4js/\">\n";},getFooter:function(){return "</log4js:eventSet>\n";},getSeparator:function(){return "\n";},formatException:function(ex){if(ex){var exStr="\t<log4js:throwable>";if(ex.message){exStr+="\t\t<log4js:message><![CDATA["+this.escapeCdata(ex.message)+"]]></log4js:message>\n";}if(ex.description){exStr+="\t\t<log4js:description><![CDATA["+this.escapeCdata(ex.description)+"]]></log4js:description>\n";}exStr+="\t\t<log4js:stacktrace>";exStr+="\t\t\t<log4js:location fileName=\""+ex.fileName+"\" lineNumber=\""+ex.lineNumber+"\" />";exStr+="\t\t</log4js:stacktrace>";exStr="\t</log4js:throwable>";return exStr;}return null;},escapeCdata:function(str){return str.replace(/\]\]>/,"]]>]]><![CDATA[");}});Log4js.JSONLayout=function(){this.df=new Log4js.DateFormatter();};Log4js.JSONLayout.prototype=Log4js.extend(new Log4js.Layout(),{format:function(loggingEvent){var useragent="unknown";try{useragent=navigator.userAgent;}catch(e){useragent="unknown";}var referer="unknown";try{referer=location.href;}catch(e){referer="unknown";}var jsonString="{\n \"LoggingEvent\": {\n";jsonString+="\t\"logger\": \""+loggingEvent.categoryName+"\",\n";jsonString+="\t\"level\": \""+loggingEvent.level.toString()+"\",\n";jsonString+="\t\"message\": \""+loggingEvent.message+"\",\n";jsonString+="\t\"referer\": \""+referer+"\",\n";jsonString+="\t\"useragent\": \""+useragent+"\",\n";jsonString+="\t\"timestamp\": \""+this.df.formatDate(loggingEvent.startTime,"yyyy-MM-ddThh:mm:ssZ")+"\",\n";jsonString+="\t\"exception\": \""+loggingEvent.exception+"\"\n";jsonString+="}}";return jsonString;},getContentType:function(){return "text/json";},getHeader:function(){return "{\"Log4js\": [\n";},getFooter:function(){return "\n]}";},getSeparator:function(){return ",\n";}});Log4js.PatternLayout=function(pattern){if(pattern){this.pattern=pattern;}else{this.pattern=Log4js.PatternLayout.DEFAULT_CONVERSION_PATTERN;}};Log4js.PatternLayout.TTCC_CONVERSION_PATTERN="%r %p %c - %m%n";Log4js.PatternLayout.DEFAULT_CONVERSION_PATTERN="%m%n";Log4js.PatternLayout.ISO8601_DATEFORMAT="yyyy-MM-dd HH:mm:ss,SSS";Log4js.PatternLayout.DATETIME_DATEFORMAT="dd MMM YYYY HH:mm:ss,SSS";Log4js.PatternLayout.ABSOLUTETIME_DATEFORMAT="HH:mm:ss,SSS";Log4js.PatternLayout.prototype=Log4js.extend(new Log4js.Layout(),{getContentType:function(){return "text/plain";},getHeader:function(){return null;},getFooter:function(){return null;},format:function(loggingEvent){var regex= /%(-?[0-9]+)?(\.?[0-9]+)?([cdmnpr%])(\{([^\}]+)\})?|([^%]+)/;var formattedString="";var result;var searchString=this.pattern;while((result=regex.exec(searchString))){var matchedString=result[0];var padding=result[1];var truncation=result[2];var conversionCharacter=result[3];var specifier=result[5];var text=result[6];if(text){formattedString+=""+text;}else{var replacement="";switch(conversionCharacter){case "c":var loggerName=loggingEvent.categoryName;if(specifier){var precision=parseInt(specifier,10);var loggerNameBits=loggingEvent.categoryName.split(".");if(precision>=loggerNameBits.length){replacement=loggerName;}else{replacement=loggerNameBits.slice(loggerNameBits.length-precision).join(".");}}else{replacement=loggerName;}break;case "d":var dateFormat=Log4js.PatternLayout.ISO8601_DATEFORMAT;if(specifier){dateFormat=specifier;if(dateFormat=="ISO8601"){dateFormat=Log4js.PatternLayout.ISO8601_DATEFORMAT;}else if(dateFormat=="ABSOLUTE"){dateFormat=Log4js.PatternLayout.ABSOLUTETIME_DATEFORMAT;}else if(dateFormat=="DATE"){dateFormat=Log4js.PatternLayout.DATETIME_DATEFORMAT;}}replacement=(new Log4js.SimpleDateFormat(dateFormat)).format(loggingEvent.startTime);break;case "m":replacement=loggingEvent.message;break;case "n":replacement="\n";break;case "p":replacement=loggingEvent.level.toString();break;case "r":replacement=""+loggingEvent.startTime.toLocaleTimeString();break;case "%":replacement="%";break;default:replacement=matchedString;break;}var len;if(truncation){len=parseInt(truncation.substr(1),10);replacement=replacement.substring(0,len);}if(padding){if(padding.charAt(0)=="-"){len=parseInt(padding.substr(1),10);while(replacement.length<len){replacement+=" ";}}else{len=parseInt(padding,10);while(replacement.length<len){replacement=" "+replacement;}}}formattedString+=replacement;}searchString=searchString.substr(result.index+result[0].length);}return formattedString;}});if(!Array.prototype.push){Array.prototype.push=function(){var startLength=this.length;for(var i=0;i<arguments.length;i++){this[startLength+i]=arguments[i];}return this.length;};}Log4js.FifoBuffer=function(){this.array=new Array();};Log4js.FifoBuffer.prototype={push:function(obj){this.array[this.array.length]=obj;return this.array.length;},pull:function(){if(this.array.length>0){var firstItem=this.array[0];for(var i=0;i<this.array.length-1;i++){this.array[i]=this.array[i+1];}this.array.length=this.array.length-1;return firstItem;}return null;},length:function(){return this.array.length;}};Log4js.DateFormatter=function(){return;};Log4js.DateFormatter.DEFAULT_DATE_FORMAT="yyyy-MM-ddThh:mm:ssO";Log4js.DateFormatter.prototype={formatDate:function(vDate,vFormat){var vDay=this.addZero(vDate.getDate());var vMonth=this.addZero(vDate.getMonth()+1);var vYearLong=this.addZero(vDate.getFullYear());var vYearShort=this.addZero(vDate.getFullYear().toString().substring(3,4));var vYear=(vFormat.indexOf("yyyy")>-1?vYearLong:vYearShort);var vHour=this.addZero(vDate.getHours());var vMinute=this.addZero(vDate.getMinutes());var vSecond=this.addZero(vDate.getSeconds());var vTimeZone=this.O(vDate);var vDateString=vFormat.replace(/dd/g,vDay).replace(/MM/g,vMonth).replace(/y{1,4}/g,vYear);vDateString=vDateString.replace(/hh/g,vHour).replace(/mm/g,vMinute).replace(/ss/g,vSecond);vDateString=vDateString.replace(/O/g,vTimeZone);return vDateString;},addZero:function(vNumber){return((vNumber<10)?"0":"")+vNumber;},O:function(date){var os=Math.abs(date.getTimezoneOffset());var h=String(Math.floor(os/60));var m=String(os%60);h.length==1?h="0"+h:1;m.length==1?m="0"+m:1;return date.getTimezoneOffset()<0?"+"+h+m:"-"+h+m;}};var log4jsLogger=Log4js.getLogger("Log4js");log4jsLogger.addAppender(new Log4js.ConsoleAppender());log4jsLogger.setLevel(Log4js.Level.ALL); diff --git a/fluidbook/compile/_js/log4js.js b/fluidbook/compile/_js/log4js.js new file mode 100644 index 000000000..d2c9dd6fe --- /dev/null +++ b/fluidbook/compile/_js/log4js.js @@ -0,0 +1,2501 @@ +/* + * 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. + */ + +/*jsl:option explicit*/ + +/** + * @fileoverview log4js is a library to log in JavaScript in similar manner + * than in log4j for Java. The API should be nearly the same. + * + * This file contains all log4js code and is the only file required for logging. + * + * <h3>Example:</h3> + * <pre> + * var log = new Log4js.getLogger("some-category-name"); //create logger instance + * log.setLevel(Log4js.Level.TRACE); //set the Level + * log.addAppender(new ConsoleAppender(log, false)); // console that launches in new window + + * // if multiple appenders are set all will log + * log.addAppender(new ConsoleAppender(log, true)); // console that is in-line in the page + * log.addAppender(new FileAppender("C:\\somefile.log")); // file appender logs to C:\\somefile.log + * + * ... + * + * //call the log + * log.trace("trace me" ); + * </pre> + * + * @version 0.3 + * @author Stephan Strittmatter - http://jroller.com/page/stritti + * @author Seth Chisamore - http://www.chisamore.com + * @since 2005-05-20 + * Website: http://log4js.berlios.de + */ +var Log4js = { + + /** + * Current version of log4js. + * @static + * @final + */ + version: "1.0", + + /** + * Date of logger initialized. + * @static + * @final + */ + applicationStartDate: new Date(), + + /** + * Hashtable of loggers. + * @static + * @final + * @private + */ + loggers: {}, + + /** + * Get a logger instance. Instance is cached on categoryName level. + * @param {String} categoryName name of category to log to. + * @return {Logger} instance of logger for the category + * @static + */ + getLogger: function(categoryName) { + + // Use default logger if categoryName is not specified or invalid + if (!(typeof categoryName == "string")) { + categoryName = "[default]"; + } + + if (!Log4js.loggers[categoryName]) { + // Create the logger for this name if it doesn't already exist + Log4js.loggers[categoryName] = new Log4js.Logger(categoryName); + } + + return Log4js.loggers[categoryName]; + }, + + /** + * Get the default logger instance. + * @return {Logger} instance of default logger + * @static + */ + getDefaultLogger: function() { + return Log4js.getLogger("[default]"); + }, + + /** + * Atatch an observer function to an elements event browser independent. + * + * @param element element to attach event + * @param name name of event + * @param observer observer method to be called + * @private + */ + attachEvent: function (element, name, observer) { + if (element.addEventListener) { //DOM event model + element.addEventListener(name, observer, false); + } else if (element.attachEvent) { //M$ event model + element.attachEvent('on' + name, observer); + } + } + + /** + * Load a JS-script dynamically. + * @param {String} src + */ +/* $import: function (src) { + var documentScripts = document.getElementsByTagName("script"); + + for (index = 0; index < documentScripts.length; ++index) + { + var documentScript = documentScripts[index]; + if (documentScript.src == src) { + return false; + } + } + + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = src; + document.getElementsByTagName('head')[0].appendChild(script); + + return true; + } + */ +}; + +/** + * Internal object extension (OO) methods. + * + * @private + * @ignore + */ +Log4js.extend = function(destination, source) { + for (property in source) { + destination[property] = source[property]; + } + return destination; +} + +/** + * Functions taken from Prototype library, + * didn't want to require for just few functions. + * More info at {@link http://prototype.conio.net/} + * @private + */ +Log4js.bind = function(fn, object) { + return function() { + return fn.apply(object, arguments); + }; +}; + +/** + * Log4js.Level Enumeration. Do not use directly. Use static objects instead. + * @constructor + * @param {Number} level number of level + * @param {String} levelString String representation of level + * @private + */ +Log4js.Level = function(level, levelStr) { + this.level = level; + this.levelStr = levelStr; +}; + +Log4js.Level.prototype = { + /** + * converts given String to corresponding Level + * @param {String} sArg String value of Level + * @param {Log4js.Level} defaultLevel default Level, if no String representation + * @return Level object + * @type Log4js.Level + */ + toLevel: function(sArg, defaultLevel) { + + if(sArg === null) { + return defaultLevel; + } + + if(typeof sArg == "string") { + var s = sArg.toUpperCase(); + if(s == "ALL") {return Log4js.Level.ALL;} + if(s == "DEBUG") {return Log4js.Level.DEBUG;} + if(s == "INFO") {return Log4js.Level.INFO;} + if(s == "WARN") {return Log4js.Level.WARN;} + if(s == "ERROR") {return Log4js.Level.ERROR;} + if(s == "FATAL") {return Log4js.Level.FATAL;} + if(s == "OFF") {return Log4js.Level.OFF;} + if(s == "TRACE") {return Log4js.Level.TRACE;} + return defaultLevel; + } else if(typeof sArg == "number") { + switch(sArg) { + case ALL_INT: return Log4js.Level.ALL; + case DEBUG_INT: return Log4js.Level.DEBUG; + case INFO_INT: return Log4js.Level.INFO; + case WARN_INT: return Log4js.Level.WARN; + case ERROR_INT: return Log4js.Level.ERROR; + case FATAL_INT: return Log4js.Level.FATAL; + case OFF_INT: return Log4js.Level.OFF; + case TRACE_INT: return Log4js.Level.TRACE; + default: return defaultLevel; + } + } else { + return defaultLevel; + } + }, + /** + * @return converted Level to String + * @type String + */ + toString: function() { + return this.levelStr; + }, + /** + * @return internal Number value of Level + * @type Number + */ + valueOf: function() { + return this.level; + } +}; + +// Static variables +/** + * @private + */ +Log4js.Level.OFF_INT = Number.MAX_VALUE; +/** + * @private + */ +Log4js.Level.FATAL_INT = 50000; +/** + * @private + */ +Log4js.Level.ERROR_INT = 40000; +/** + * @private + */ +Log4js.Level.WARN_INT = 30000; +/** + * @private + */ +Log4js.Level.INFO_INT = 20000; +/** + * @private + */ +Log4js.Level.DEBUG_INT = 10000; +/** + * @private + */ +Log4js.Level.TRACE_INT = 5000; +/** + * @private + */ +Log4js.Level.ALL_INT = Number.MIN_VALUE; + +/** + * Logging Level OFF - all disabled + * @type Log4js.Level + * @static + */ +Log4js.Level.OFF = new Log4js.Level(Log4js.Level.OFF_INT, "OFF"); +/** + * Logging Level Fatal + * @type Log4js.Level + * @static + */ +Log4js.Level.FATAL = new Log4js.Level(Log4js.Level.FATAL_INT, "FATAL"); +/** + * Logging Level Error + * @type Log4js.Level + * @static + */ +Log4js.Level.ERROR = new Log4js.Level(Log4js.Level.ERROR_INT, "ERROR"); +/** + * Logging Level Warn + * @type Log4js.Level + * @static + */ +Log4js.Level.WARN = new Log4js.Level(Log4js.Level.WARN_INT, "WARN"); +/** + * Logging Level Info + * @type Log4js.Level + * @static + */ +Log4js.Level.INFO = new Log4js.Level(Log4js.Level.INFO_INT, "INFO"); +/** + * Logging Level Debug + * @type Log4js.Level + * @static + */ +Log4js.Level.DEBUG = new Log4js.Level(Log4js.Level.DEBUG_INT, "DEBUG"); +/** + * Logging Level Trace + * @type Log4js.Level + * @static + */ +Log4js.Level.TRACE = new Log4js.Level(Log4js.Level.TRACE_INT, "TRACE"); +/** + * Logging Level All - All traces are enabled + * @type Log4js.Level + * @static + */ +Log4js.Level.ALL = new Log4js.Level(Log4js.Level.ALL_INT, "ALL"); + +/** + * Log4js CustomEvent + * @constructor + * @author Corey Johnson - original code in Lumberjack (http://gleepglop.com/javascripts/logger/) + * @author Seth Chisamore - adapted for Log4js + * @private + */ +Log4js.CustomEvent = function() { + this.listeners = []; +}; + +Log4js.CustomEvent.prototype = { + + /** + * @param method method to be added + */ + addListener : function(method) { + this.listeners.push(method); + }, + + /** + * @param method method to be removed + */ + removeListener : function(method) { + var foundIndexes = this.findListenerIndexes(method); + + for(var i = 0; i < foundIndexes.length; i++) { + this.listeners.splice(foundIndexes[i], 1); + } + }, + + /** + * @param handler + */ + dispatch : function(handler) { + for(var i = 0; i < this.listeners.length; i++) { + try { + this.listeners[i](handler); + } + catch (e) { + log4jsLogger.warn("Could not run the listener " + this.listeners[i] + ". \n" + e); + } + } + }, + + /** + * @private + * @param method + */ + findListenerIndexes : function(method) { + var indexes = []; + for(var i = 0; i < this.listeners.length; i++) { + if (this.listeners[i] == method) { + indexes.push(i); + } + } + + return indexes; + } +}; + +/** + * Models a logging event. + * @constructor + * @param {String} categoryName name of category + * @param {Log4js.Level} level level of message + * @param {String} message message to log + * @param {Log4js.Logger} logger the associated logger + * @author Seth Chisamore + */ +Log4js.LoggingEvent = function(categoryName, level, message, exception, logger) { + /** + * the timestamp of the Logging Event + * @type Date + * @private + */ + this.startTime = new Date(); + /** + * category of event + * @type String + * @private + */ + this.categoryName = categoryName; + /** + * the logging message + * @type String + * @private + */ + this.message = message; + /** + * the logging exception + * @type Exception + * @private + */ + this.exception = exception; + /** + * level of log + * @type Log4js.Level + * @private + */ + this.level = level; + /** + * reference to logger + * @type Log4js.Logger + * @private + */ + this.logger = logger; +}; + +Log4js.LoggingEvent.prototype = { + /** + * get the timestamp formatted as String. + * @return {String} formatted timestamp + * @see Log4js#setDateFormat() + */ + getFormattedTimestamp: function() { + if(this.logger) { + return this.logger.getFormattedTimestamp(this.startTime); + } else { + return this.startTime.toGMTString(); + } + } +}; + +/** + * Logger to log messages to the defined appender.</p> + * Default appender is Appender, which is ignoring all messages. Please + * use setAppender() to set a specific appender (e.g. WindowAppender). + * use {@see Log4js#getLogger(String)} to get an instance. + * @constructor + * @param name name of category to log to + * @author Stephan Strittmatter + */ +Log4js.Logger = function(name) { + this.loggingEvents = []; + this.appenders = []; + /** category of logger */ + this.category = name || ""; + /** level to be logged */ + this.level = Log4js.Level.FATAL; + + this.dateformat = Log4js.DateFormatter.DEFAULT_DATE_FORMAT; + this.dateformatter = new Log4js.DateFormatter(); + + this.onlog = new Log4js.CustomEvent(); + this.onclear = new Log4js.CustomEvent(); + + /** appender to write in */ + this.appenders.push(new Log4js.Appender(this)); + + // if multiple log objects are instantiated this will only log to the log + // object that is declared last can't seem to get the attachEvent method to + // work correctly + try { + window.onerror = this.windowError.bind(this); + } catch (e) { + //log4jsLogger.fatal(e); + } +}; + +Log4js.Logger.prototype = { + + /** + * add additional appender. DefaultAppender always is there. + * @param appender additional wanted appender + */ + addAppender: function(appender) { + if (appender instanceof Log4js.Appender) { + appender.setLogger(this); + this.appenders.push(appender); + } else { + throw "Not instance of an Appender: " + appender; + } + }, + + /** + * set Array of appenders. Previous Appenders are cleared and removed. + * @param {Array} appenders Array of Appenders + */ + setAppenders: function(appenders) { + //clear first all existing appenders + for(var i = 0; i < this.appenders.length; i++) { + this.appenders[i].doClear(); + } + + this.appenders = appenders; + + for(var j = 0; j < this.appenders.length; j++) { + this.appenders[j].setLogger(this); + } + }, + + /** + * Set the Loglevel default is LogLEvel.TRACE + * @param level wanted logging level + */ + setLevel: function(level) { + this.level = level; + }, + + /** + * main log method logging to all available appenders + * @private + */ + log: function(logLevel, message, exception) { + var loggingEvent = new Log4js.LoggingEvent(this.category, logLevel, + message, exception, this); + this.loggingEvents.push(loggingEvent); + this.onlog.dispatch(loggingEvent); + }, + + /** clear logging */ + clear : function () { + try{ + this.loggingEvents = []; + this.onclear.dispatch(); + } catch(e){} + }, + /** checks if Level Trace is enabled */ + isTraceEnabled: function() { + if (this.level.valueOf() <= Log4js.Level.TRACE.valueOf()) { + return true; + } + return false; + }, + /** + * Trace messages + * @param message {Object} message to be logged + */ + trace: function(message) { + if (this.isTraceEnabled()) { + this.log(Log4js.Level.TRACE, message, null); + } + }, + /** checks if Level Debug is enabled */ + isDebugEnabled: function() { + if (this.level.valueOf() <= Log4js.Level.DEBUG.valueOf()) { + return true; + } + return false; + }, + /** + * Debug messages + * @param message {Object} message to be logged + */ + debug: function(message) { + if (this.isDebugEnabled()) { + this.log(Log4js.Level.DEBUG, message, null); + } + }, + /** + * Debug messages + * @param {Object} message message to be logged + * @param {Throwable} throwable + */ + debug: function(message, throwable) { + if (this.isDebugEnabled()) { + this.log(Log4js.Level.DEBUG, message, throwable); + } + }, + /** checks if Level Info is enabled */ + isInfoEnabled: function() { + if (this.level.valueOf() <= Log4js.Level.INFO.valueOf()) { + return true; + } + return false; + }, + /** + * logging info messages + * @param {Object} message message to be logged + */ + info: function(message) { + if (this.isInfoEnabled()) { + this.log(Log4js.Level.INFO, message, null); + } + }, + /** + * logging info messages + * @param {Object} message message to be logged + * @param {Throwable} throwable + */ + info: function(message, throwable) { + if (this.isInfoEnabled()) { + this.log(Log4js.Level.INFO, message, throwable); + } + }, + /** checks if Level Warn is enabled */ + isWarnEnabled: function() { + if (this.level.valueOf() <= Log4js.Level.WARN.valueOf()) { + return true; + } + return false; + }, + + /** logging warn messages */ + warn: function(message) { + if (this.isWarnEnabled()) { + this.log(Log4js.Level.WARN, message, null); + } + }, + /** logging warn messages */ + warn: function(message, throwable) { + if (this.isWarnEnabled()) { + this.log(Log4js.Level.WARN, message, throwable); + } + }, + /** checks if Level Error is enabled */ + isErrorEnabled: function() { + if (this.level.valueOf() <= Log4js.Level.ERROR.valueOf()) { + return true; + } + return false; + }, + /** logging error messages */ + error: function(message) { + if (this.isErrorEnabled()) { + this.log(Log4js.Level.ERROR, message, null); + } + }, + /** logging error messages */ + error: function(message, throwable) { + if (this.isErrorEnabled()) { + this.log(Log4js.Level.ERROR, message, throwable); + } + }, + /** checks if Level Fatal is enabled */ + isFatalEnabled: function() { + if (this.level.valueOf() <= Log4js.Level.FATAL.valueOf()) { + return true; + } + return false; + }, + /** logging fatal messages */ + fatal: function(message) { + if (this.isFatalEnabled()) { + this.log(Log4js.Level.FATAL, message, null); + } + }, + /** logging fatal messages */ + fatal: function(message, throwable) { + if (this.isFatalEnabled()) { + this.log(Log4js.Level.FATAL, message, throwable); + } + }, + /** + * Capture main window errors and log as fatal. + * @private + */ + windowError: function(msg, url, line){ + var message = "Error in (" + (url || window.location) + ") on line "+ line +" with message (" + msg + ")"; + this.log(Log4js.Level.FATAL, message, null); + }, + + /** + * Set the date format of logger. Following switches are supported: + * <ul> + * <li>yyyy - The year</li> + * <li>MM - the month</li> + * <li>dd - the day of month<li> + * <li>hh - the hour<li> + * <li>mm - minutes</li> + * <li>O - timezone offset</li> + * </ul> + * @param {String} format format String for the date + * @see #getTimestamp + */ + setDateFormat: function(format) { + this.dateformat = format; + }, + + /** + * Generates a timestamp using the format set in {Log4js.setDateFormat}. + * @param {Date} date the date to format + * @see #setDateFormat + * @return A formatted timestamp with the current date and time. + */ + getFormattedTimestamp: function(date) { + return this.dateformatter.formatDate(date, this.dateformat); + } +}; + +/** + * Abstract base class for other appenders. + * It is doing nothing. + * + * @constructor + * @param {Log4js.Logger} logger log4js instance this appender is attached to + * @author Stephan Strittmatter + */ +Log4js.Appender = function () { + /** + * Reference to calling logger + * @type Log4js.Logger + * @private + */ + this.logger = null; +}; + +Log4js.Appender.prototype = { + /** + * appends the given loggingEvent appender specific + * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to append + */ + doAppend: function(loggingEvent) { + return; + }, + /** + * clears the Appender + */ + doClear: function() { + return; + }, + + /** + * Set the Layout for this appender. + * @param {Log4js.Layout} layout Layout for formatting loggingEvent + */ + setLayout: function(layout){ + this.layout = layout; + }, + /** + * Set reference to the logger. + * @param {Log4js.Logger} the invoking logger + */ + setLogger: function(logger){ + // add listener to the logger methods + logger.onlog.addListener(Log4js.bind(this.doAppend, this)); + logger.onclear.addListener(Log4js.bind(this.doClear, this)); + + this.logger = logger; + } +}; + +/** + * Interface for Layouts. + * Use this Layout as "interface" for other Layouts. It is doing nothing. + * + * @constructor + * @author Stephan Strittmatter + */ +Log4js.Layout = function(){return;}; +Log4js.Layout.prototype = { + /** + * Implement this method to create your own layout format. + * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format + * @return formatted String + * @type String + */ + format: function(loggingEvent) { + return ""; + }, + /** + * Returns the content type output by this layout. + * @return The base class returns "text/plain". + * @type String + */ + getContentType: function() { + return "text/plain"; + }, + /** + * @return Returns the header for the layout format. The base class returns null. + * @type String + */ + getHeader: function() { + return null; + }, + /** + * @return Returns the footer for the layout format. The base class returns null. + * @type String + */ + getFooter: function() { + return null; + }, + + /** + * @return Separator between events + * @type String + */ + getSeparator: function() { + return ""; + } +}; + +/** + * Console Appender writes the logs to a console. If "inline" is + * set to "false" the console launches in another window otherwise + * the window is inline on the page and toggled on and off with "Alt-D". + * Note: At FireFox &gb; 2.0 the keystroke is little different now: "SHIFT+ALT+D". + * + * @constructor + * @extends Log4js.Appender + * @param {boolean} isInline boolean value that indicates whether the console be placed inline, default is to launch in new window + * + * @author Corey Johnson - original console code in Lumberjack (http://gleepglop.com/javascripts/logger/) + * @author Seth Chisamore - adapted for use as a log4js appender + */ +Log4js.ConsoleAppender = function(isInline) { + + /** + * @type Log4js.Layout + * @private + */ + this.layout = new Log4js.PatternLayout(Log4js.PatternLayout.TTCC_CONVERSION_PATTERN); + /** + * @type boolean + * @private + */ + this.inline = isInline; + + /** + * @type String + * @private + */ + this.accesskey = "d"; + + /** + * @private + */ + this.tagPattern = null; + + this.commandHistory = []; + this.commandIndex = 0; + + /** + * true if popup is blocked. + */ + this.popupBlocker = false; + + /** + * current output div-element. + */ + this.outputElement = null; + + this.docReference = null; + this.winReference = null; + + if(this.inline) { + Log4js.attachEvent(window, 'load', Log4js.bind(this.initialize, this)); + } +}; + +Log4js.ConsoleAppender.prototype = Log4js.extend(new Log4js.Appender(), { + + /** + * Set the access key to show/hide the inline console (default "e;d"e;) + * @param key access key to show/hide the inline console + */ + setAccessKey : function(key) { + this.accesskey = key; + }, + + /** + * @private + */ + initialize : function() { + + if(!this.inline) { + var doc = null; + var win = null; + window.top.consoleWindow = window.open("", this.logger.category, + "left=0,top=0,width=700,height=700,scrollbars=no,status=no,resizable=yes;toolbar=no"); + window.top.consoleWindow.opener = self; + win = window.top.consoleWindow; + + if (!win) { + this.popupBlocker=true; + alert("Popup window manager blocking the Log4js popup window to bedisplayed.\n\n" + + "Please disabled this to properly see logged events."); + } else { + + doc = win.document; + doc.open(); + doc.write("<!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN "); + doc.write(" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd>\n\n"); + doc.write("<html><head><title>Log4js - " + this.logger.category + "\n"); + doc.write("\n"); + win.blur(); + win.focus(); + } + + this.docReference = doc; + this.winReference = win; + } else { + this.docReference = document; + this.winReference = window; + } + + this.outputCount = 0; + this.tagPattern = ".*"; + + // I hate writing javascript in HTML... but what's a better alternative + this.logElement = this.docReference.createElement('div'); + this.docReference.body.appendChild(this.logElement); + this.logElement.style.display = 'none'; + + this.logElement.style.position = "absolute"; + this.logElement.style.left = '0px'; + this.logElement.style.width = '100%'; + + this.logElement.style.textAlign = "left"; + this.logElement.style.fontFamily = "lucida console"; + this.logElement.style.fontSize = "100%"; + this.logElement.style.backgroundColor = 'darkgray'; + this.logElement.style.opacity = 0.9; + this.logElement.style.zIndex = 2000; + + // Add toolbarElement + this.toolbarElement = this.docReference.createElement('div'); + this.logElement.appendChild(this.toolbarElement); + this.toolbarElement.style.padding = "0 0 0 2px"; + + // Add buttons + this.buttonsContainerElement = this.docReference.createElement('span'); + this.toolbarElement.appendChild(this.buttonsContainerElement); + + if(this.inline) { + var closeButton = this.docReference.createElement('button'); + closeButton.style.cssFloat = "right"; + closeButton.style.styleFloat = "right"; // IE dom bug...doesn't understand cssFloat + closeButton.style.color = "black"; + closeButton.innerHTML = "close"; + closeButton.onclick = Log4js.bind(this.toggle, this); + this.buttonsContainerElement.appendChild(closeButton); + } + + var clearButton = this.docReference.createElement('button'); + clearButton.style.cssFloat = "right"; + clearButton.style.styleFloat = "right"; // IE dom bug...doesn't understand cssFloat + clearButton.style.color = "black"; + clearButton.innerHTML = "clear"; + clearButton.onclick = Log4js.bind(this.logger.clear, this.logger); + this.buttonsContainerElement.appendChild(clearButton); + + + //Add CategoryName and Level Filter + this.tagFilterContainerElement = this.docReference.createElement('span'); + this.toolbarElement.appendChild(this.tagFilterContainerElement); + this.tagFilterContainerElement.style.cssFloat = 'left'; + + this.tagFilterContainerElement.appendChild(this.docReference.createTextNode("Log4js - " + this.logger.category)); + this.tagFilterContainerElement.appendChild(this.docReference.createTextNode(" | Level Filter: ")); + + this.tagFilterElement = this.docReference.createElement('input'); + this.tagFilterContainerElement.appendChild(this.tagFilterElement); + this.tagFilterElement.style.width = '200px'; + this.tagFilterElement.value = this.tagPattern; + this.tagFilterElement.setAttribute('autocomplete', 'off'); // So Firefox doesn't flip out + + Log4js.attachEvent(this.tagFilterElement, 'keyup', Log4js.bind(this.updateTags, this)); + Log4js.attachEvent(this.tagFilterElement, 'click', Log4js.bind( function() {this.tagFilterElement.select();}, this)); + + // Add outputElement + this.outputElement = this.docReference.createElement('div'); + this.logElement.appendChild(this.outputElement); + this.outputElement.style.overflow = "auto"; + this.outputElement.style.clear = "both"; + this.outputElement.style.height = (this.inline) ? ("200px"):("650px"); + this.outputElement.style.width = "100%"; + this.outputElement.style.backgroundColor = 'black'; + + this.inputContainerElement = this.docReference.createElement('div'); + this.inputContainerElement.style.width = "100%"; + this.logElement.appendChild(this.inputContainerElement); + + this.inputElement = this.docReference.createElement('input'); + this.inputContainerElement.appendChild(this.inputElement); + this.inputElement.style.width = '100%'; + this.inputElement.style.borderWidth = '0px'; // Inputs with 100% width always seem to be too large (I HATE THEM) they only work if the border, margin and padding are 0 + this.inputElement.style.margin = '0px'; + this.inputElement.style.padding = '0px'; + this.inputElement.value = 'Type command here'; + this.inputElement.setAttribute('autocomplete', 'off'); // So Firefox doesn't flip out + + Log4js.attachEvent(this.inputElement, 'keyup', Log4js.bind(this.handleInput, this)); + Log4js.attachEvent(this.inputElement, 'click', Log4js.bind( function() {this.inputElement.select();}, this)); + + if(this.inline){ + window.setInterval(Log4js.bind(this.repositionWindow, this), 500); + this.repositionWindow(); + // Allow acess key link + var accessElement = this.docReference.createElement('button'); + accessElement.style.position = "absolute"; + accessElement.style.top = "-100px"; + accessElement.accessKey = this.accesskey; + accessElement.onclick = Log4js.bind(this.toggle, this); + this.docReference.body.appendChild(accessElement); + } else { + this.show(); + } + }, + /** + * shows/hide an element + * @private + * @return true if shown + */ + toggle : function() { + if (this.logElement.style.display == 'none') { + this.show(); + return true; + } else { + this.hide(); + return false; + } + }, + /** + * @private + */ + show : function() { + this.logElement.style.display = ''; + this.outputElement.scrollTop = this.outputElement.scrollHeight; // Scroll to bottom when toggled + this.inputElement.select(); + }, + /** + * @private + */ + hide : function() { + this.logElement.style.display = 'none'; + }, + /** + * @private + * @param message + * @style + */ + output : function(message, style) { + + // If we are at the bottom of the window, then keep scrolling with the output + var shouldScroll = (this.outputElement.scrollTop + (2 * this.outputElement.clientHeight)) >= this.outputElement.scrollHeight; + + this.outputCount++; + style = (style ? style += ';' : ''); + style += 'padding:1px;margin:0 0 5px 0'; + + if (this.outputCount % 2 === 0) { + style += ";background-color:#101010"; + } + + message = message || "undefined"; + message = message.toString(); + + this.outputElement.innerHTML += "
" + message + "
"; + + if (shouldScroll) { + this.outputElement.scrollTop = this.outputElement.scrollHeight; + } + }, + + /** + * @private + */ + updateTags : function() { + + var pattern = this.tagFilterElement.value; + + if (this.tagPattern == pattern) { + return; + } + + try { + new RegExp(pattern); + } catch (e) { + return; + } + + this.tagPattern = pattern; + + this.outputElement.innerHTML = ""; + + // Go through each log entry again + this.outputCount = 0; + for (var i = 0; i < this.logger.loggingEvents.length; i++) { + this.doAppend(this.logger.loggingEvents[i]); + } + }, + + /** + * @private + */ + repositionWindow : function() { + var offset = window.pageYOffset || this.docReference.documentElement.scrollTop || this.docReference.body.scrollTop; + var pageHeight = self.innerHeight || this.docReference.documentElement.clientHeight || this.docReference.body.clientHeight; + this.logElement.style.top = (offset + pageHeight - this.logElement.offsetHeight) + "px"; + }, + + /** + * @param loggingEvent event to be logged + * @see Log4js.Appender#doAppend + */ + doAppend : function(loggingEvent) { + + if(this.popupBlocker) { + //popup blocked, we return in this case + return; + } + + if ((!this.inline) && (!this.winReference || this.winReference.closed)) { + this.initialize(); + } + + if (this.tagPattern !== null && + loggingEvent.level.toString().search(new RegExp(this.tagPattern, 'igm')) == -1) { + return; + } + + var style = ''; + + if (loggingEvent.level.toString().search(/ERROR/) != -1) { + style += 'color:red'; + } else if (loggingEvent.level.toString().search(/FATAL/) != -1) { + style += 'color:red'; + } else if (loggingEvent.level.toString().search(/WARN/) != -1) { + style += 'color:orange'; + } else if (loggingEvent.level.toString().search(/DEBUG/) != -1) { + style += 'color:green'; + } else if (loggingEvent.level.toString().search(/INFO/) != -1) { + style += 'color:white'; + } else { + style += 'color:yellow'; + } + + this.output(this.layout.format(loggingEvent), style); + }, + + /** + * @see Log4js.Appender#doClear + */ + doClear : function() { + this.outputElement.innerHTML = ""; + }, + /** + * @private + * @param e + */ + handleInput : function(e) { + if (e.keyCode == 13 ) { + var command = this.inputElement.value; + + switch(command) { + case "clear": + this.logger.clear(); + break; + + default: + var consoleOutput = ""; + + try { + consoleOutput = eval(this.inputElement.value); + } catch (e) { + this.logger.error("Problem parsing input <" + command + ">" + e.message); + break; + } + + this.logger.trace(consoleOutput); + break; + } + + if (this.inputElement.value !== "" && this.inputElement.value !== this.commandHistory[0]) { + this.commandHistory.unshift(this.inputElement.value); + } + + this.commandIndex = 0; + this.inputElement.value = ""; + } else if (e.keyCode == 38 && this.commandHistory.length > 0) { + this.inputElement.value = this.commandHistory[this.commandIndex]; + + if (this.commandIndex < this.commandHistory.length - 1) { + this.commandIndex += 1; + } + } else if (e.keyCode == 40 && this.commandHistory.length > 0) { + if (this.commandIndex > 0) { + this.commandIndex -= 1; + } + + this.inputElement.value = this.commandHistory[this.commandIndex]; + } else { + this.commandIndex = 0; + } + }, + + /** + * toString + */ + toString: function() { + return "Log4js.ConsoleAppender[inline=" + this.inline + "]"; + } +}); + +/** + * Metatag Appender writing the logs to meta tags + * + * @extends Log4js.Appender + * @constructor + * @param logger log4js instance this appender is attached to + * @author Stephan Strittmatter + */ +Log4js.MetatagAppender = function() { + this.currentLine = 0; +}; +Log4js.MetatagAppender.prototype = Log4js.extend(new Log4js.Appender(), { + /** + * @param loggingEvent event to be logged + * @see Log4js.Appender#doAppend + */ + doAppend: function(loggingEvent) { + var now = new Date(); + var lines = loggingEvent.message.split("\n"); + var headTag = document.getElementsByTagName("head")[0]; + + for (var i = 1; i <= lines.length; i++) { + var value = lines[i - 1]; + if (i == 1) { + value = loggingEvent.level.toString() + ": " + value; + } else { + value = "> " + value; + } + + var metaTag = document.createElement("meta"); + metaTag.setAttribute("name", "X-log4js:" + this.currentLine); + metaTag.setAttribute("content", value); + headTag.appendChild(metaTag); + this.currentLine += 1; + } + }, + + /** + * toString + */ + toString: function() { + return "Log4js.MetatagAppender"; + } +}); + +/** + * AJAX Appender sending {@link Log4js.LoggingEvent}s asynchron via + * XMLHttpRequest to server.
+ * The {@link Log4js.LoggingEvent} is POSTed as response content and is + * formatted by the accociated layout. Default layout is {@link Log4js.XMLLayout}. + * The threshold defines when the logs + * should be send to the server. By default every event is sent on its + * own (threshold=1). If it is set to 10, then the events are send in groups of + * 10 events. + * + * @extends Log4js.Appender + * @constructor + * @param {Log4js.Logger} logger log4js instance this appender is attached to + * @param {String} loggingUrl url where appender will post log messages to + * @author Stephan Strittmatter + */ +Log4js.AjaxAppender = function(loggingUrl) { + + /** + * is still esnding data to server + * @type boolean + * @private + */ + this.isInProgress = false; + + /** + * @type String + * @private + */ + this.loggingUrl = loggingUrl || "logging.log4js"; + + /** + * @type Integer + * @private + */ + this.threshold = 1; + + /** + * timeout when request is aborted. + * @private + */ + this.timeout = 2000; + + /** + * List of LoggingEvents which should be send after threshold is reached. + * @type Map + * @private + */ + this.loggingEventMap = new Log4js.FifoBuffer(); + + /** + * @type Log4js.Layout + * @private + */ + this.layout = new Log4js.XMLLayout(); + /** + * @type XMLHttpRequest + * @private + */ + this.httpRequest = null; +}; + +Log4js.AjaxAppender.prototype = Log4js.extend(new Log4js.Appender(), { + /** + * sends the logs to the server + * @param loggingEvent event to be logged + * @see Log4js.Appender#doAppend + */ + doAppend: function(loggingEvent) { + log4jsLogger.trace("> AjaxAppender.append"); + + if (this.loggingEventMap.length() <= this.threshold || this.isInProgress === true) { + this.loggingEventMap.push(loggingEvent); + } + + if(this.loggingEventMap.length() >= this.threshold && this.isInProgress === false) { + //if threshold is reached send the events and reset current threshold + this.send(); + } + + log4jsLogger.trace("< AjaxAppender.append"); + }, + + /** @see Appender#doClear */ + doClear: function() { + log4jsLogger.trace("> AjaxAppender.doClear" ); + if(this.loggingEventMap.length() > 0) { + this.send(); + } + log4jsLogger.trace("< AjaxAppender.doClear" ); + }, + + /** + * Set the threshold when logs have to be send. Default threshold is 1. + * @praram {int} threshold new threshold + */ + setThreshold: function(threshold) { + log4jsLogger.trace("> AjaxAppender.setThreshold: " + threshold ); + this.threshold = threshold; + log4jsLogger.trace("< AjaxAppender.setThreshold" ); + }, + + /** + * Set the timeout in milli seconds until sending request is aborted. + * Default is 2000 ms. + * @param {int} milliseconds the new timeout + */ + setTimeout: function(milliseconds) { + this.timeout = milliseconds; + }, + + /** + * send the request. + */ + send: function() { + if(this.loggingEventMap.length() >0) { + + log4jsLogger.trace("> AjaxAppender.send"); + + + this.isInProgress = true; + var a = []; + + for(var i = 0; i < this.loggingEventMap.length() && i < this.threshold; i++) { + a.push(this.layout.format(this.loggingEventMap.pull())); + } + + var content = this.layout.getHeader(); + content += a.join(this.layout.getSeparator()); + content += this.layout.getFooter(); + + var appender = this; + if(this.httpRequest === null){ + this.httpRequest = this.getXmlHttpRequest(); + } + this.httpRequest.onreadystatechange = function() { + appender.onReadyStateChanged.call(appender); + }; + + this.httpRequest.open("POST", this.loggingUrl, true); + // set the request headers. + //this.httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + this.httpRequest.setRequestHeader("Content-type", this.layout.getContentType()); + //REFERER will be the top-level + // URI which may differ from the location of the error if + // it occurs in an included .js file + this.httpRequest.setRequestHeader("REFERER", location.href); + this.httpRequest.setRequestHeader("Content-length", content.length); + this.httpRequest.setRequestHeader("Connection", "close"); + this.httpRequest.send( content ); + + appender = this; + + try { + window.setTimeout(function(){ + log4jsLogger.trace("> AjaxAppender.timeout"); + appender.httpRequest.onreadystatechange = function(){return;}; + appender.httpRequest.abort(); + //this.httpRequest = null; + appender.isInProgress = false; + + if(appender.loggingEventMap.length() > 0) { + appender.send(); + } + log4jsLogger.trace("< AjaxAppender.timeout"); + }, this.timeout); + } catch (e) { + log4jsLogger.fatal(e); + } + log4jsLogger.trace("> AjaxAppender.send"); + } + }, + + /** + * @private + */ + onReadyStateChanged: function() { + log4jsLogger.trace("> AjaxAppender.onReadyStateChanged"); + var req = this.httpRequest; + if (this.httpRequest.readyState != 4) { + log4jsLogger.trace("< AjaxAppender.onReadyStateChanged: readyState " + req.readyState + " != 4"); + return; + } + + var success = ((typeof req.status === "undefined") || req.status === 0 || (req.status >= 200 && req.status < 300)); + + if (success) { + log4jsLogger.trace(" AjaxAppender.onReadyStateChanged: success"); + + //ready sending data + this.isInProgress = false; + + } else { + var msg = " AjaxAppender.onReadyStateChanged: XMLHttpRequest request to URL " + this.loggingUrl + " returned status code " + this.httpRequest.status; + log4jsLogger.error(msg); + } + + log4jsLogger.trace("< AjaxAppender.onReadyStateChanged: readyState == 4"); + }, + /** + * Get the XMLHttpRequest object independent of browser. + * @private + */ + getXmlHttpRequest: function() { + log4jsLogger.trace("> AjaxAppender.getXmlHttpRequest"); + + var httpRequest = false; + + try { + if (window.XMLHttpRequest) { // Mozilla, Safari, IE7... + httpRequest = new XMLHttpRequest(); + if (httpRequest.overrideMimeType) { + httpRequest.overrideMimeType(this.layout.getContentType()); + } + } else if (window.ActiveXObject) { // IE + try { + httpRequest = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); + } + } + } catch (e) { + httpRequest = false; + } + + if (!httpRequest) { + log4jsLogger.fatal("Unfortunatelly your browser does not support AjaxAppender for log4js!"); + } + + log4jsLogger.trace("< AjaxAppender.getXmlHttpRequest"); + return httpRequest; + }, + + /** + * toString + */ + toString: function() { + return "Log4js.AjaxAppender[loggingUrl=" + this.loggingUrl + ", threshold=" + this.threshold + "]"; + } +}); + +/** + * File Appender writing the logs to a text file. + * PLEASE NOTE - Only works in IE and Mozilla + * use ActiveX to write file on IE + * use XPCom components to write file on Mozilla + * + * @extends Log4js.Appender + * @constructor + * @param logger log4js instance this appender is attached to + * @param file file log messages will be written to + * @author Seth Chisamore + * @author Nicolas Justin njustin@idealx.com + * @author Gregory Kokanosky gkokanosky@idealx.com + */ +Log4js.FileAppender = function(file) { + + this.layout = new Log4js.SimpleLayout(); + this.isIE = 'undefined'; + + this.file = file || "log4js.log"; + + try{ + this.fso = new ActiveXObject("Scripting.FileSystemObject"); + this.isIE = true; + } catch(e){ + try { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + this.fso = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile); + this.isIE = false; //mozilla & co + } catch (e) { + log4jsLogger.error(e); + } + } +}; + +Log4js.FileAppender.prototype = Log4js.extend(new Log4js.Appender(), { + /** + * @param loggingEvent event to be logged + * @see Log4js.Appender#doAppend + */ + doAppend: function(loggingEvent) { + try { + var fileHandle = null; + + if( this.isIE === 'undefined') { + log4jsLogger.error("Unsupported ") + } + else if( this.isIE ){ + // try opening existing file, create if needed + fileHandle = this.fso.OpenTextFile(this.file, 8, true); + // write out our data + fileHandle.WriteLine(this.layout.format(loggingEvent)); + fileHandle.close(); + } else { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + this.fso.initWithPath(this.file); + if(!this.fso.exists()) { + //create file if needed + this.fso.create(0x00, 0600); + } + + fileHandle = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream); + fileHandle.init( this.fso, 0x04 | 0x08 | 0x10, 064, 0); + var line = this.layout.format(loggingEvent); + fileHandle.write(line, line.length); //write data + fileHandle.close(); + } + } catch (e) { + log4jsLogger.error(e); + } + }, + /* + * @see Log4js.Appender#doClear + */ + doClear: function() { + try { + if( this.isIE ){ + var fileHandle = this.fso.GetFile(this.file); + fileHandle.Delete(); + } else { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + this.fso.initWithPath(this.file); + if(this.fso.exists()) { + this.fso.remove(false); + } + } + } catch (e) { + log4jsLogger.error(e); + } + }, + + /** + * toString + */ + toString: function() { + return "Log4js.FileAppender[file=" + this.file + "]"; + } +}); + +/** + * Windows Event Appender writes the logs to the Windows Event log. + * PLEASE NOTE - Only works in IE..uses ActiveX to write to Windows Event log + * + * @extends Log4js.Appender + * @constructor + * @param logger log4js instance this appender is attached to + * @author Seth Chisamore + */ +Log4js.WindowsEventAppender = function() { + + this.layout = new Log4js.SimpleLayout(); + + try { + this.shell = new ActiveXObject("WScript.Shell"); + } catch(e) { + log4jsLogger.error(e); + } +}; + +Log4js.WindowsEventAppender.prototype = Log4js.extend(new Log4js.Appender(), { + /** + * @param loggingEvent event to be logged + * @see Log4js.Appender#doAppend + */ + doAppend: function(loggingEvent) { + var winLevel = 4; + + // Map log level to windows event log level. + // Windows events: - SUCCESS: 0, ERROR: 1, WARNING: 2, INFORMATION: 4, AUDIT_SUCCESS: 8, AUDIT_FAILURE: 16 + switch (loggingEvent.level) { + case Log4js.Level.FATAL: + winLevel = 1; + break; + case Log4js.Level.ERROR: + winLevel = 1; + break; + case Log4js.Level.WARN: + winLevel = 2; + break; + default: + winLevel = 4; + break; + } + + try { + this.shell.LogEvent(winLevel, this.level.format(loggingEvent)); + } catch(e) { + log4jsLogger.error(e); + } + }, + + /** + * toString + */ + toString: function() { + return "Log4js.WindowsEventAppender"; + } +}); + +/** + * JS Alert Appender writes the logs to the JavaScript alert dialog box + * @constructor + * @extends Log4js.Appender + * @param logger log4js instance this appender is attached to + * @author Sébastien LECACHEUR + */ +Log4js.JSAlertAppender = function() { + + this.layout = new Log4js.SimpleLayout(); +}; + +Log4js.JSAlertAppender.prototype = Log4js.extend(new Log4js.Appender(), { + /** + * @see Log4js.Appender#doAppend + */ + doAppend: function(loggingEvent) { + alert(this.layout.getHeader() + this.layout.format(loggingEvent) + this.layout.getFooter()); + }, + + /** + * toString + */ + toString: function() { + return "Log4js.JSAlertAppender"; + } +}); + +/** + * Appender writes the logs to the JavaScript console of Mozilla browser + * More infos: http://kb.mozillazine.org/index.php?title=JavaScript_Console&redirect=no + * PLEASE NOTE - Only works in Mozilla browser + * @constructor + * @extends Log4js.Appender + * @param logger log4js instance this appender is attached to + * @author Stephan Strittmatter + */ +Log4js.MozillaJSConsoleAppender = function() { + this.layout = new Log4js.SimpleLayout(); + try { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + this.jsConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService); + this.scriptError = Components.classes["@mozilla.org/scripterror;1"].createInstance(Components.interfaces.nsIScriptError); + } catch (e) { + log4jsLogger.error(e); + } +}; + +Log4js.MozillaJSConsoleAppender.prototype = Log4js.extend(new Log4js.Appender(), { + /** + * @see Log4js.Appender#doAppend + */ + doAppend: function(loggingEvent) { + try { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + this.scriptError.init(this.layout.format(loggingEvent), null, null, null, null, this.getFlag(loggingEvent), loggingEvent.categoryName); + this.jsConsole.logMessage(this.scriptError); + } catch (e) { + log4jsLogger.error(e); + } + }, + + /** + * toString + */ + toString: function() { + return "Log4js.MozillaJSConsoleAppender"; + }, + + /** + * Map Log4js.Level to jsConsole Flags: + *
    + *
  • nsIScriptError.errorFlag (0) = Level.Error
  • + *
  • nsIScriptError.warningFlag (1)= Log4js.Level.WARN
  • + *
  • nsIScriptError.exceptionFlag (2) = Log4js.Level.FATAL
  • + *
  • nsIScriptError.strictFlag (4) = unused
  • + *
+ * @private + */ + getFlag: function(loggingEvent) + { + var retval; + switch (loggingEvent.level) { + case Log4js.Level.FATAL: + retval = 2;//nsIScriptError.exceptionFlag = 2 + break; + case Log4js.Level.ERROR: + retval = 0;//nsIScriptError.errorFlag + break; + case Log4js.Level.WARN: + retval = 1;//nsIScriptError.warningFlag = 1 + break; + default: + retval = 1;//nsIScriptError.warningFlag = 1 + break; + } + + return retval; + } +}); + +/** + * Appender writes the logs to the JavaScript console of Opera browser + * PLEASE NOTE - Only works in Opera browser + * @constructor + * @extends Log4js.Appender + * @param logger log4js instance this appender is attached to + * @author Stephan Strittmatter + */ +Log4js.OperaJSConsoleAppender = function() { + this.layout = new Log4js.SimpleLayout(); +}; + +Log4js.OperaJSConsoleAppender.prototype = Log4js.extend(new Log4js.Appender(), { + /** + * @see Log4js.Appender#doAppend + */ + doAppend: function(loggingEvent) { + opera.postError(this.layout.format(loggingEvent)); + }, + + /** + * toString + */ + toString: function() { + return "Log4js.OperaJSConsoleAppender"; + } +}); + +/** + * Appender writes the logs to the JavaScript console of Safari browser + * PLEASE NOTE - Only works in Safari browser + * @constructor + * @extends Log4js.Appender + * @param logger log4js instance this appender is attached to + * @author Stephan Strittmatter + */ +Log4js.SafariJSConsoleAppender = function() { + this.layout = new Log4js.SimpleLayout(); +}; + +Log4js.SafariJSConsoleAppender.prototype = Log4js.extend(new Log4js.Appender(), { + /** + * @see Log4js.Appender#doAppend + */ + doAppend: function(loggingEvent) { + window.console.log(this.layout.format(loggingEvent)); + }, + + /** + * toString + */ + toString: function() { + return "Log4js.SafariJSConsoleAppender"; + } +}); + +/** + * JavaScript Console Appender which is browser independent. + * It checks internally for the current browser and adds delegate to + * specific JavaScript Console Appender of the browser. + * + * @author Stephan Strittmatter + * @since 1.0 + */ +Log4js.BrowserConsoleAppender = function() { + /** + * Delegate for browser specific implementation + * @type Log4js.Appender + * @private + */ + this.consoleDelegate = null; + + if (window.console) { + this.consoleDelegate = new Log4js.SafariJSConsoleAppender(); + } + else if (window.opera) { + this.consoleDelegate = new Log4js.OperaJSConsoleAppender(); + } + else if(netscape) { + this.consoleDelegate = new Log4js.MozJSConsoleAppender(); + } + else { + //@todo + log4jsLogger.error("Unsupported Browser"); + } +}; + +Log4js.BrowserConsoleAppender.prototype = Log4js.extend(new Log4js.Appender(), { + /** + * @see Log4js.Appender#doAppend + */ + doAppend: function(loggingEvent) { + this.consoleDelegate.doAppend(loggingEvent); + }, + /** + * @see Log4js.Appender#doClear + */ + doClear: function() { + this.consoleDelegate.doClear(); + }, + /** + * @see Log4js.Appender#setLayout + */ + setLayout: function(layout){ + this.consoleDelegate.setLayout(layout); + }, + + /** + * toString + */ + toString: function() { + return "Log4js.BrowserConsoleAppender: " + this.consoleDelegate.toString(); + } +}); + +/** + * SimpleLayout consists of the level of the log statement, followed by " - " + * and then the log message itself. For example, + * DEBUG - Hello world + * + * @constructor + * @extends Log4js.Layout + * @extends Layout + * @author Stephan Strittmatter + */ +Log4js.SimpleLayout = function() { + this.LINE_SEP = "\n"; + this.LINE_SEP_LEN = 1; +}; + +Log4js.SimpleLayout.prototype = Log4js.extend(new Log4js.Layout(), { + /** + * Implement this method to create your own layout format. + * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format + * @return formatted String + * @type String + */ + format: function(loggingEvent) { + return loggingEvent.level.toString() + " - " + loggingEvent.message + this.LINE_SEP; + }, + /** + * Returns the content type output by this layout. + * @return The base class returns "text/plain". + * @type String + */ + getContentType: function() { + return "text/plain"; + }, + /** + * @return Returns the header for the layout format. The base class returns null. + * @type String + */ + getHeader: function() { + return ""; + }, + /** + * @return Returns the footer for the layout format. The base class returns null. + * @type String + */ + getFooter: function() { + return ""; + } +}); + +/** + * BasicLayout is a simple layout for storing the loggs. The loggs are stored + * in following format: + *
+ * categoryName~startTime [logLevel] message\n
+ * 
+ * + * @constructor + * @extends Log4js.Layout + * @author Stephan Strittmatter + */ +Log4js.BasicLayout = function() { + this.LINE_SEP = "\n"; +}; + +Log4js.BasicLayout.prototype = Log4js.extend(new Log4js.Layout(), { + /** + * Implement this method to create your own layout format. + * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format + * @return formatted String + * @type String + */ + format: function(loggingEvent) { + return loggingEvent.categoryName + "~" + loggingEvent.startTime.toLocaleString() + " [" + loggingEvent.level.toString() + "] " + loggingEvent.message + this.LINE_SEP; + }, + /** + * Returns the content type output by this layout. + * @return The base class returns "text/plain". + * @type String + */ + getContentType: function() { + return "text/plain"; + }, + /** + * @return Returns the header for the layout format. The base class returns null. + * @type String + */ + getHeader: function() { + return ""; + }, + /** + * @return Returns the footer for the layout format. The base class returns null. + * @type String + */ + getFooter: function() { + return ""; + } +}); + +/** + * HtmlLayout write the logs in Html format. + * + * @constructor + * @extends Log4js.Layout + * @author Stephan Strittmatter + */ +Log4js.HtmlLayout = function() {return;}; + +Log4js.HtmlLayout.prototype = Log4js.extend(new Log4js.Layout(), { + /** + * Implement this method to create your own layout format. + * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format + * @return formatted String + * @type String + */ + format: function(loggingEvent) { + return "
" + loggingEvent.getFormattedTimestamp() + " - " + loggingEvent.level.toString() + " - " + loggingEvent.message + "
\n"; + }, + /** + * Returns the content type output by this layout. + * @return The base class returns "text/html". + * @type String + */ + getContentType: function() { + return "text/html"; + }, + /** + * @return Returns the header for the layout format. The base class returns null. + * @type String + */ + getHeader: function() { + return "log4js</head><body>"; + }, + /** + * @return Returns the footer for the layout format. The base class returns null. + * @type String + */ + getFooter: function() { + return "</body></html>"; + }, + + getStyle: function(loggingEvent) + { + var style; + if (loggingEvent.level.toString().search(/ERROR/) != -1) { + style = 'color:red'; + } else if (loggingEvent.level.toString().search(/FATAL/) != -1) { + style = 'color:red'; + } else if (loggingEvent.level.toString().search(/WARN/) != -1) { + style = 'color:orange'; + } else if (loggingEvent.level.toString().search(/DEBUG/) != -1) { + style = 'color:green'; + } else if (loggingEvent.level.toString().search(/INFO/) != -1) { + style = 'color:white'; + } else { + style = 'color:yellow'; + } + return style; + } +}); + +/** + * XMLLayout write the logs in XML format. + * Layout is simmilar to log4j's XMLLayout: + * <pre> + * <log4js:event category="category" level="Level" client="Client" referer="ref" timestam="Date"> + * <log4js:message>Logged message</log4js:message> + * </log4js:event> + * </pre> + * @constructor + * @extends Layout + * @author Stephan Strittmatter + */ +Log4js.XMLLayout = function(){return;}; +Log4js.XMLLayout.prototype = Log4js.extend(new Log4js.Layout(), { + /** + * Implement this method to create your own layout format. + * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format + * @return formatted String + * @type String + */ + format: function(loggingEvent) { + var useragent = "unknown"; + try { + useragent = navigator.userAgent; + } catch(e){ + useragent = "unknown"; + } + + var referer = "unknown"; + try { + referer = location.href; + } catch(e){ + referer = "unknown"; + } + + var content = "<log4js:event logger=\""; + content += loggingEvent.categoryName + "\" level=\""; + content += loggingEvent.level.toString() + "\" useragent=\""; + content += useragent + "\" referer=\""; + content += referer.replace(/&/g, "&") + "\" timestamp=\""; + content += loggingEvent.getFormattedTimestamp() + "\">\n"; + content += "\t<log4js:message><![CDATA[" + this.escapeCdata(loggingEvent.message) + "]]></log4js:message>\n"; + + if (loggingEvent.exception) { + content += this.formatException(loggingEvent.exception) ; + } + content += "</log4js:event>\n"; + + return content; + }, + /** + * Returns the content type output by this layout. + * @return The base class returns "text/xml". + * @type String + */ + getContentType: function() { + return "text/xml"; + }, + /** + * @return Returns the header for the layout format. The base class returns null. + * @type String + */ + getHeader: function() { + return "<log4js:eventSet version=\"" + Log4js.version + + "\" xmlns:log4js=\"http://log4js.berlios.de/2007/log4js/\">\n"; + }, + /** + * @return Returns the footer for the layout format. The base class returns null. + * @type String + */ + getFooter: function() { + return "</log4js:eventSet>\n"; + }, + + getSeparator: function() { + return "\n"; + }, + + /** + * better readable formatted Exceptions. + * @param ex {Exception} the exception to be formatted. + * @return {String} the formatted String representation of the exception. + * @private + */ + formatException: function(ex) { + if (ex) { + var exStr = "\t<log4js:throwable>"; + if (ex.message) { + exStr += "\t\t<log4js:message><![CDATA[" + this.escapeCdata(ex.message) + "]]></log4js:message>\n"; + } + if (ex.description) { + exStr += "\t\t<log4js:description><![CDATA[" + this.escapeCdata(ex.description) + "]]></log4js:description>\n"; + } + + exStr += "\t\t<log4js:stacktrace>"; + exStr += "\t\t\t<log4js:location fileName=\""+ex.fileName+"\" lineNumber=\""+ex.lineNumber+"\" />"; + exStr += "\t\t</log4js:stacktrace>"; + exStr = "\t</log4js:throwable>"; + return exStr; + } + return null; + }, + /** + * Escape Cdata messages + * @param str {String} message to escape + * @return {String} the escaped message + * @private + */ + escapeCdata: function(str) { + return str.replace(/\]\]>/, "]]>]]><![CDATA["); + } +}); + +/** + * JSONLayout write the logs in JSON format. + * JSON library is required to use this Layout. See also {@link http://www.json.org} + * @constructor + * @extends Log4js.Layout + * @author Stephan Strittmatter + */ +Log4js.JSONLayout = function() { + this.df = new Log4js.DateFormatter(); +}; +Log4js.JSONLayout.prototype = Log4js.extend(new Log4js.Layout(), { + /** + * Implement this method to create your own layout format. + * @param {Log4js.LoggingEvent} loggingEvent loggingEvent to format + * @return formatted String + * @type String + */ + format: function(loggingEvent) { + + var useragent = "unknown"; + try { + useragent = navigator.userAgent; + } catch(e){ + useragent = "unknown"; + } + + var referer = "unknown"; + try { + referer = location.href; + } catch(e){ + referer = "unknown"; + } + + var jsonString = "{\n \"LoggingEvent\": {\n"; + + jsonString += "\t\"logger\": \"" + loggingEvent.categoryName + "\",\n"; + jsonString += "\t\"level\": \"" + loggingEvent.level.toString() + "\",\n"; + jsonString += "\t\"message\": \"" + loggingEvent.message + "\",\n"; + jsonString += "\t\"referer\": \"" + referer + "\",\n"; + jsonString += "\t\"useragent\": \"" + useragent + "\",\n"; + jsonString += "\t\"timestamp\": \"" + this.df.formatDate(loggingEvent.startTime, "yyyy-MM-ddThh:mm:ssZ") + "\",\n"; + jsonString += "\t\"exception\": \"" + loggingEvent.exception + "\"\n"; + jsonString += "}}"; + + return jsonString; + }, + /** + * Returns the content type output by this layout. + * @return The base class returns "text/xml". + * @type String + */ + getContentType: function() { + return "text/json"; + }, + /** + * @return Returns the header for the layout format. The base class returns null. + * @type String + */ + getHeader: function() { + return "{\"Log4js\": [\n"; + }, + /** + * @return Returns the footer for the layout format. The base class returns null. + * @type String + */ + getFooter: function() { + return "\n]}"; + }, + + getSeparator: function() { + return ",\n"; + } +}); + +/** + * PatternLayout + */ +Log4js.PatternLayout = function(pattern) { + if (pattern) { + this.pattern = pattern; + } else { + this.pattern = Log4js.PatternLayout.DEFAULT_CONVERSION_PATTERN; + } +}; + +Log4js.PatternLayout.TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n"; +Log4js.PatternLayout.DEFAULT_CONVERSION_PATTERN = "%m%n"; +Log4js.PatternLayout.ISO8601_DATEFORMAT = "yyyy-MM-dd HH:mm:ss,SSS"; +Log4js.PatternLayout.DATETIME_DATEFORMAT = "dd MMM YYYY HH:mm:ss,SSS"; +Log4js.PatternLayout.ABSOLUTETIME_DATEFORMAT = "HH:mm:ss,SSS"; + +Log4js.PatternLayout.prototype = Log4js.extend(new Log4js.Layout(), { + /** + * Returns the content type output by this layout. + * @return "text/plain". + * @type String + */ + getContentType: function() { + return "text/plain"; + }, + /** + * @return Returns the header for the layout format. + * @type String + */ + getHeader: function() { + return null; + }, + /** + * @return Returns the footer for the layout format. + * @type String + */ + getFooter: function() { + return null; + }, + + format: function(loggingEvent) { + var regex = /%(-?[0-9]+)?(\.?[0-9]+)?([cdmnpr%])(\{([^\}]+)\})?|([^%]+)/; + var formattedString = ""; + var result; + var searchString = this.pattern; + + // Cannot use regex global flag since it doesn't work in IE5 + while ((result = regex.exec(searchString))) { + var matchedString = result[0]; + var padding = result[1]; + var truncation = result[2]; + var conversionCharacter = result[3]; + var specifier = result[5]; + var text = result[6]; + + // Check if the pattern matched was just normal text + if (text) { + formattedString += "" + text; + } else { + // Create a raw replacement string based on the conversion + // character and specifier + var replacement = ""; + switch(conversionCharacter) { + case "c": + var loggerName = loggingEvent.categoryName; + if (specifier) { + var precision = parseInt(specifier, 10); + var loggerNameBits = loggingEvent.categoryName.split("."); + if (precision >= loggerNameBits.length) { + replacement = loggerName; + } else { + replacement = loggerNameBits.slice(loggerNameBits.length - precision).join("."); + } + } else { + replacement = loggerName; + } + break; + case "d": + var dateFormat = Log4js.PatternLayout.ISO8601_DATEFORMAT; + if (specifier) { + dateFormat = specifier; + // Pick up special cases + if (dateFormat == "ISO8601") { + dateFormat = Log4js.PatternLayout.ISO8601_DATEFORMAT; + } else if (dateFormat == "ABSOLUTE") { + dateFormat = Log4js.PatternLayout.ABSOLUTETIME_DATEFORMAT; + } else if (dateFormat == "DATE") { + dateFormat = Log4js.PatternLayout.DATETIME_DATEFORMAT; + } + } + // Format the date + replacement = (new Log4js.SimpleDateFormat(dateFormat)).format(loggingEvent.startTime); + break; + case "m": + replacement = loggingEvent.message; + break; + case "n": + replacement = "\n"; + break; + case "p": + replacement = loggingEvent.level.toString(); + break; + case "r": + replacement = "" + loggingEvent.startTime.toLocaleTimeString(); //TODO: .getDifference(Log4js.applicationStartDate); + break; + case "%": + replacement = "%"; + break; + default: + replacement = matchedString; + break; + } + // Format the replacement according to any padding or + // truncation specified + + var len; + + // First, truncation + if (truncation) { + len = parseInt(truncation.substr(1), 10); + replacement = replacement.substring(0, len); + } + // Next, padding + if (padding) { + if (padding.charAt(0) == "-") { + len = parseInt(padding.substr(1), 10); + // Right pad with spaces + while (replacement.length < len) { + replacement += " "; + } + } else { + len = parseInt(padding, 10); + // Left pad with spaces + while (replacement.length < len) { + replacement = " " + replacement; + } + } + } + formattedString += replacement; + } + searchString = searchString.substr(result.index + result[0].length); + } + return formattedString; + } +}); + +/** + * @private + * @ignore + */ +if (!Array.prototype.push) { + /** + * Functions taken from Prototype library, didn't want to require for just few + * functions. + * More info at {@link http:// + * prototype.conio.net/} + * @private + */ + Array.prototype.push = function() { + var startLength = this.length; + for (var i = 0; i < arguments.length; i++) { + this[startLength + i] = arguments[i]; + } + return this.length; + }; +} + +/** + * FIFO buffer + * @private + */ +Log4js.FifoBuffer = function() +{ + this.array = new Array(); +}; + +Log4js.FifoBuffer.prototype = { + + /** + * @param {Object} obj any object added to buffer + */ + push : function(obj) { + this.array[this.array.length] = obj; + return this.array.length; + }, + + /** + * @return first putted in Object + */ + pull : function() { + if (this.array.length > 0) { + var firstItem = this.array[0]; + for (var i = 0; i < this.array.length - 1; i++) { + this.array[i] = this.array[i + 1]; + } + this.array.length = this.array.length - 1; + return firstItem; + } + return null; + }, + + length : function() { + return this.array.length; + } +}; + + + +/** + * Date Formatter + * addZero() and formatDate() are courtesy of Mike Golding: + * http://www.mikezilla.com/exp0015.html + * @private + */ +Log4js.DateFormatter = function() { + return; +}; +/** + * default format of date (ISO-8601) + * @static + * @final + */ +Log4js.DateFormatter.DEFAULT_DATE_FORMAT = "yyyy-MM-ddThh:mm:ssO"; + + +Log4js.DateFormatter.prototype = { + /** + * Formats the given date by the given pattern.<br /> + * Following switches are supported: + * <ul> + * <li>yyyy: The year</li> + * <li>MM: the month</li> + * <li>dd: the day of month<li> + * <li>hh: the hour<li> + * <li>mm: minutes</li> + * <li>O: timezone offset</li> + * </ul> + * @param {Date} vDate the date to format + * @param {String} vFormat the format pattern + * @return {String} formatted date string + * @static + */ + formatDate : function(vDate, vFormat) { + var vDay = this.addZero(vDate.getDate()); + var vMonth = this.addZero(vDate.getMonth()+1); + var vYearLong = this.addZero(vDate.getFullYear()); + var vYearShort = this.addZero(vDate.getFullYear().toString().substring(3,4)); + var vYear = (vFormat.indexOf("yyyy")>-1?vYearLong:vYearShort); + var vHour = this.addZero(vDate.getHours()); + var vMinute = this.addZero(vDate.getMinutes()); + var vSecond = this.addZero(vDate.getSeconds()); + var vTimeZone = this.O(vDate); + var vDateString = vFormat.replace(/dd/g, vDay).replace(/MM/g, vMonth).replace(/y{1,4}/g, vYear); + vDateString = vDateString.replace(/hh/g, vHour).replace(/mm/g, vMinute).replace(/ss/g, vSecond); + vDateString = vDateString.replace(/O/g, vTimeZone); + return vDateString; + }, + + /** + * @private + * @static + */ + addZero : function(vNumber) { + return ((vNumber < 10) ? "0" : "") + vNumber; + }, + + /** + * Formates the TimeOffest + * Thanks to http://www.svendtofte.com/code/date_format/ + * @private + */ + O : function (date) { + // Difference to Greenwich time (GMT) in hours + var os = Math.abs(date.getTimezoneOffset()); + var h = String(Math.floor(os/60)); + var m = String(os%60); + h.length == 1? h = "0"+h:1; + m.length == 1? m = "0"+m:1; + return date.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m; + } +}; + + +/** + * internal Logger to be used + * @private + */ +var log4jsLogger = Log4js.getLogger("Log4js"); +log4jsLogger.addAppender(new Log4js.ConsoleAppender()); +log4jsLogger.setLevel(Log4js.Level.ALL); \ No newline at end of file diff --git a/fluidbook/compile/_js/resources/Base.esapi.properties.js b/fluidbook/compile/_js/resources/Base.esapi.properties.js new file mode 100644 index 000000000..3bbdd5576 --- /dev/null +++ b/fluidbook/compile/_js/resources/Base.esapi.properties.js @@ -0,0 +1,68 @@ +/* + * OWASP Enterprise Security API (ESAPI) + * + * This file is part of the Open Web Application Security Project (OWASP) + * Enterprise Security API (ESAPI) project. For details, please see + * <a href="http://www.owasp.org/index.php/ESAPI">http://www.owasp.org/index.php/ESAPI</a>. + * + * Copyright (c) 2008 - The OWASP Foundation + * + * The ESAPI is published by OWASP under the BSD license. You should read and accept the + * LICENSE before you use, modify, and/or redistribute this software. + */ + +$namespace('Base.esapi.properties'); + +Base.esapi.properties = { + application: { + // Change this value to reflect your application, or override it in an application scoped configuration. + Name: 'ESAPI4JS Base Application' + }, + + httputilities: { + cookies: { + ForceSecure: true + } + }, + + logging: { + Implementation: org.owasp.esapi.reference.logging.Log4JSLogFactory, + Level: org.owasp.esapi.Logger.ERROR, + // For a console that pops up in a seperate window + // Appenders: [ new ConsoleAppender(true) ], + // To log to a logging service on the server + // Appenders: [ new AjaxAppender( '/log/' ) ], + // Default to log nowhere + Appenders: [ ], + LogUrl: false, + LogApplicationName: false, + EncodingRequired: true + }, + + encoder: { + Implementation: org.owasp.esapi.reference.encoding.DefaultEncoder, + AllowMultipleEncoding: false + }, + + localization: { + StandardResourceBundle: ESAPI_Standard_en_US, + DefaultLocale: 'en-US' + }, + + validation: { + Implementation: org.owasp.esapi.reference.validation.DefaultValidator, + AccountName: '^[a-zA-Z0-9]{3,20}$', + SafeString: '[a-zA-Z0-9\\-_+]*', + Email: '^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$', + IPAddress: '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$', + URL: '^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\\'\\/\\\\\\+=&%\\$#_]*)?$', + CreditCard: '^(\\d{4}[- ]?){3}\\d{4}$', + SSN: '^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$', + HttpScheme: '^(http|https)$', + HttpServerName: '^[a-zA-Z0-9_.\\-]*$', + HttpParameterName: '^[a-zA-Z0-9_]{1,32}$', + HttpParameterValue: '^[a-zA-Z0-9.\\-\\/+=_ ]*$', + HttpCookieName: '^[a-zA-Z0-9\\-_]{1,32}$', + HttpCookieValue: '^[a-zA-Z0-9\\-\\/+=_ ]*$' + } +}; \ No newline at end of file diff --git a/fluidbook/compile/_js/swfaddress.js b/fluidbook/compile/_js/swfaddress.js index 646b2292b..73bf4f973 100644 --- a/fluidbook/compile/_js/swfaddress.js +++ b/fluidbook/compile/_js/swfaddress.js @@ -1 +1,854 @@ -/** * SWFAddress 2.4: Deep linking for Flash and Ajax <http://www.asual.com/swfaddress/> * * SWFAddress is (c) 2006-2009 Rostislav Hristov and contributors * This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> * */ if (typeof asual == "undefined") var asual = {}; if (typeof asual.util == "undefined") asual.util = {}; asual.util.Browser = new function() { var _agent = navigator.userAgent.toLowerCase(), _safari = /webkit/.test(_agent), _opera = /opera/.test(_agent), _msie = /msie/.test(_agent) && !/opera/.test(_agent), _mozilla = /mozilla/.test(_agent) && !/(compatible|webkit)/.test(_agent), _version = parseFloat(_msie ? _agent.substr(_agent.indexOf('msie') + 4) : (_agent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0,'0'])[1]); this.toString = function() { return '[class Browser]'; }; this.getVersion = function() { return _version; }; this.isMSIE = function() { return _msie; }; this.isSafari = function() { return _safari; }; this.isOpera = function() { return _opera; }; this.isMozilla = function() { return _mozilla; }; }; asual.util.Events = new function() { var DOM_LOADED = 'DOMContentLoaded', STOP = 'onstop', _w = window, _d = document, _cache = [], _util = asual.util, _browser = _util.Browser, _msie = _browser.isMSIE(), _safari = _browser.isSafari(); this.toString = function() { return '[class Events]'; }; this.addListener = function(obj, type, listener) { _cache.push({o: obj, t: type, l: listener}); if (!(type == DOM_LOADED && (_msie || _safari))) { if (obj.addEventListener) obj.addEventListener(type, listener, false); else if (obj.attachEvent) obj.attachEvent('on' + type, listener); } }; this.removeListener = function(obj, type, listener) { for (var i = 0, e; e = _cache[i]; i++) { if (e.o == obj && e.t == type && e.l == listener) { _cache.splice(i, 1); break; } } if (!(type == DOM_LOADED && (_msie || _safari))) { if (obj.removeEventListener) obj.removeEventListener(type, listener, false); else if (obj.detachEvent) obj.detachEvent('on' + type, listener); } }; var _unload = function() { for (var i = 0, evt; evt = _cache[i]; i++) { if (evt.t != DOM_LOADED) _util.Events.removeListener(evt.o, evt.t, evt.l); } }; var _unloadFix = function() { if (_d.readyState == 'interactive') { function stop() { _d.detachEvent(STOP, stop); _unload(); }; _d.attachEvent(STOP, stop); _w.setTimeout(function() { _d.detachEvent(STOP, stop); }, 0); } }; if (_msie || _safari) { (function (){ try { if ((_msie && _d.body) || !/loaded|complete/.test(_d.readyState)) _d.documentElement.doScroll('left'); } catch(e) { return setTimeout(arguments.callee, 0); } for (var i = 0, e; e = _cache[i]; i++) if (e.t == DOM_LOADED) e.l.call(null); })(); } if (_msie) _w.attachEvent('onbeforeunload', _unloadFix); this.addListener(_w, 'unload', _unload); }; asual.util.Functions = new function() { this.toString = function() { return '[class Functions]'; }; this.bind = function(method, object, param) { for (var i = 2, p, arr = []; p = arguments[i]; i++) arr.push(p); return function() { return method.apply(object, arr); } }; }; var SWFAddressEvent = function(type) { this.toString = function() { return '[object SWFAddressEvent]'; }; this.type = type; this.target = [SWFAddress][0]; this.value = SWFAddress.getValue(); this.path = SWFAddress.getPath(); this.pathNames = SWFAddress.getPathNames(); this.parameters = {}; var _parameterNames = SWFAddress.getParameterNames(); for (var i = 0, l = _parameterNames.length; i < l; i++) this.parameters[_parameterNames[i]] = SWFAddress.getParameter(_parameterNames[i]); this.parameterNames = _parameterNames; }; SWFAddressEvent.INIT = 'init'; SWFAddressEvent.CHANGE = 'change'; SWFAddressEvent.INTERNAL_CHANGE = 'internalChange'; SWFAddressEvent.EXTERNAL_CHANGE = 'externalChange'; var SWFAddress = new function() { var _getHash = function() { var index = _l.href.indexOf('#'); return index != -1 ? _ec(_dc(_l.href.substr(index + 1))) : ''; }; var _getWindow = function() { return window; }; var _strictCheck = function(value, force) { if (_opts.strict) value = force ? (value.substr(0, 1) != '/' ? '/' + value : value) : (value == '' ? '/' : value); return value; }; var _ieLocal = function(value, direction) { return (_msie && _l.protocol == 'file:') ? (direction ? _value.replace(/\?/, '%3F') : _value.replace(/%253F/, '?')) : value; }; var _searchScript = function(el) { if (el.childNodes) { for (var i = 0, l = el.childNodes.length, s; i < l; i++) { if (el.childNodes[i].src) _url = String(el.childNodes[i].src); if (s = _searchScript(el.childNodes[i])) return s; } } }; var _titleCheck = function() { if (_d.title != _title && _d.title.indexOf('#') != -1) _d.title = _title; }; var _listen = function() { if (!_silent) { var hash = _getHash(); var diff = !(_value == hash); if (_safari && _version < 523) { if (_length != _h.length) { _length = _h.length; if (typeof _stack[_length - 1] != UNDEFINED) _value = _stack[_length - 1]; _update.call(this, false); } } else if (_msie && diff) { if (_version < 7) _l.reload(); else this.setValue(hash); } else if (diff) { _value = hash; _update.call(this, false); } if (_msie) _titleCheck.call(this); } }; var _bodyClick = function(e) { if (_popup.length > 0) { var popup = window.open(_popup[0], _popup[1], eval(_popup[2])); if (typeof _popup[3] != UNDEFINED) eval(_popup[3]); } _popup = []; }; var _swfChange = function() { for (var i = 0, id, obj, value = SWFAddress.getValue(), setter = 'setSWFAddressValue'; id = _ids[i]; i++) { obj = document.getElementById(id); if (obj) { if (obj.parentNode && typeof obj.parentNode.so != UNDEFINED) { obj.parentNode.so.call(setter, value); } else { if (!(obj && typeof obj[setter] != UNDEFINED)) { var objects = obj.getElementsByTagName('object'); var embeds = obj.getElementsByTagName('embed'); obj = ((objects[0] && typeof objects[0][setter] != UNDEFINED) ? objects[0] : ((embeds[0] && typeof embeds[0][setter] != UNDEFINED) ? embeds[0] : null)); } if (obj) obj[setter](value); } } else if (obj = document[id]) { if (typeof obj[setter] != UNDEFINED) obj[setter](value); } } }; var _jsDispatch = function(type) { this.dispatchEvent(new SWFAddressEvent(type)); type = type.substr(0, 1).toUpperCase() + type.substr(1); if(typeof this['on' + type] == FUNCTION) this['on' + type](); }; var _jsInit = function() { if (_util.Browser.isSafari()) _d.body.addEventListener('click', _bodyClick); _jsDispatch.call(this, 'init'); }; var _jsChange = function() { _swfChange(); _jsDispatch.call(this, 'change'); }; var _update = function(internal) { _jsChange.call(this); if (internal) { _jsDispatch.call(this, 'internalChange'); } else { _jsDispatch.call(this, 'externalChange'); } _st(_functions.bind(_track, this), 10); }; var _track = function() { var value = (_l.pathname + (/\/$/.test(_l.pathname) ? '' : '/') + this.getValue()).replace(/\/\//, '/').replace(/^\/$/, ''); var fn = _t[_opts.tracker]; if (typeof fn == FUNCTION) fn(value); else if (typeof _t.pageTracker != UNDEFINED && typeof _t.pageTracker._trackPageview == FUNCTION) _t.pageTracker._trackPageview(value); else if (typeof _t.urchinTracker == FUNCTION) _t.urchinTracker(value); }; var _htmlWrite = function() { var doc = _frame.contentWindow.document; doc.open(); doc.write('<html><head><title>' + _d.title + ''); doc.close(); }; var _htmlLoad = function() { var win = _frame.contentWindow; var src = win.location.href; _value = (typeof win[ID] != UNDEFINED ? win[ID] : ''); if (_value != _getHash()) { _update.call(SWFAddress, false); _l.hash = _ieLocal(_value, TRUE); } }; var _load = function() { if (!_loaded) { _loaded = TRUE; if (_msie && _version < 8) { var frameset = _d.getElementsByTagName('frameset')[0]; _frame = _d.createElement((frameset ? '' : 'i') + 'frame'); if (frameset) { frameset.insertAdjacentElement('beforeEnd', _frame); frameset[frameset.cols ? 'cols' : 'rows'] += ',0'; _frame.src = 'javascript:false'; _frame.noResize = true; _frame.frameBorder = _frame.frameSpacing = 0; } else { _frame.src = 'javascript:false'; _frame.style.display = 'none'; _d.body.insertAdjacentElement('afterBegin', _frame); } _st(function() { _events.addListener(_frame, 'load', _htmlLoad); if (typeof _frame.contentWindow[ID] == UNDEFINED) _htmlWrite(); }, 50); } else if (_safari) { if (_version < 418) { _d.body.innerHTML += '
'; _form = _d.getElementById(ID); } if (typeof _l[ID] == UNDEFINED) _l[ID] = {}; if (typeof _l[ID][_l.pathname] != UNDEFINED) _stack = _l[ID][_l.pathname].split(','); } _st(_functions.bind(function() { _jsInit.call(this); _jsChange.call(this); _track.call(this); }, this), 1); if (_msie && _version >= 8) { _d.body.onhashchange = _functions.bind(_listen, this); _si(_functions.bind(_titleCheck, this), 50); } else { _si(_functions.bind(_listen, this), 50); } } }; var ID = 'swfaddress', FUNCTION = 'function', UNDEFINED = 'undefined', TRUE = true, FALSE = false, _util = asual.util, _browser = _util.Browser, _events = _util.Events, _functions = _util.Functions, _version = _browser.getVersion(), _msie = _browser.isMSIE(), _mozilla = _browser.isMozilla(), _opera = _browser.isOpera(), _safari = _browser.isSafari(), _supported = FALSE, _t = _getWindow(), _d = _t.document, _h = _t.history, _l = _t.location, _si = setInterval, _st = setTimeout, _dc = decodeURI, _ec = encodeURI, _frame, _form, _url, _title = _d.title, _length = _h.length, _silent = FALSE, _loaded = FALSE, _justset = TRUE, _juststart = TRUE, _ref = this, _stack = [], _ids = [], _popup = [], _listeners = {}, _value = _getHash(), _opts = {history: TRUE, strict: TRUE}; if (_msie && _d.documentMode && _d.documentMode != _version) _version = _d.documentMode != 8 ? 7 : 8; _supported = (_mozilla && _version >= 1) || (_msie && _version >= 6) || (_opera && _version >= 9.5) || (_safari && _version >= 312); if (_supported) { if (_opera) history.navigationMode = 'compatible'; for (var i = 1; i < _length; i++) _stack.push(''); _stack.push(_getHash()); if (_msie && _l.hash != _getHash()) _l.hash = '#' + _ieLocal(_getHash(), TRUE); _searchScript(document); var _qi = _url ? _url.indexOf('?') : -1; if (_qi != -1) { var param, params = _url.substr(_qi + 1).split('&'); for (var i = 0, p; p = params[i]; i++) { param = p.split('='); if (/^(history|strict)$/.test(param[0])) { _opts[param[0]] = (isNaN(param[1]) ? /^(true|yes)$/i.test(param[1]) : (parseInt(param[1]) != 0)); } if (/^tracker$/.test(param[0])) _opts[param[0]] = param[1]; } } if (_msie) _titleCheck.call(this); if (window == _t) _events.addListener(document, 'DOMContentLoaded', _functions.bind(_load, this)); _events.addListener(_t, 'load', _functions.bind(_load, this)); } else if ((!_supported && _l.href.indexOf('#') != -1) || (_safari && _version < 418 && _l.href.indexOf('#') != -1 && _l.search != '')){ _d.open(); _d.write(''); _d.close(); } else { _track(); } this.toString = function() { return '[class SWFAddress]'; }; this.back = function() { _h.back(); }; this.forward = function() { _h.forward(); }; this.up = function() { var path = this.getPath(); this.setValue(path.substr(0, path.lastIndexOf('/', path.length - 2) + (path.substr(path.length - 1) == '/' ? 1 : 0))); }; this.go = function(delta) { _h.go(delta); }; this.href = function(url, target) { target = typeof target != UNDEFINED ? target : '_self'; if (target == '_self') self.location.href = url; else if (target == '_top') _l.href = url; else if (target == '_blank') window.open(url); else _t.frames[target].location.href = url; }; this.popup = function(url, name, options, handler) { try { var popup = window.open(url, name, eval(options)); if (typeof handler != UNDEFINED) eval(handler); } catch (ex) {} _popup = arguments; }; this.getIds = function() { return _ids; }; this.getId = function(index) { return _ids[0]; }; this.setId = function(id) { _ids[0] = id; }; this.addId = function(id) { this.removeId(id); _ids.push(id); }; this.removeId = function(id) { for (var i = 0; i < _ids.length; i++) { if (id == _ids[i]) { _ids.splice(i, 1); break; } } }; this.addEventListener = function(type, listener) { if (typeof _listeners[type] == UNDEFINED) _listeners[type] = []; _listeners[type].push(listener); }; this.removeEventListener = function(type, listener) { if (typeof _listeners[type] != UNDEFINED) { for (var i = 0, l; l = _listeners[type][i]; i++) if (l == listener) break; _listeners[type].splice(i, 1); } }; this.dispatchEvent = function(event) { if (this.hasEventListener(event.type)) { event.target = this; for (var i = 0, l; l = _listeners[event.type][i]; i++) l(event); return TRUE; } return FALSE; }; this.hasEventListener = function(type) { return (typeof _listeners[type] != UNDEFINED && _listeners[type].length > 0); }; this.getBaseURL = function() { var url = _l.href; if (url.indexOf('#') != -1) url = url.substr(0, url.indexOf('#')); if (url.substr(url.length - 1) == '/') url = url.substr(0, url.length - 1); return url; }; this.getStrict = function() { return _opts.strict; }; this.setStrict = function(strict) { _opts.strict = strict; }; this.getHistory = function() { return _opts.history; }; this.setHistory = function(history) { _opts.history = history; }; this.getTracker = function() { return _opts.tracker; }; this.setTracker = function(tracker) { _opts.tracker = tracker; }; this.getTitle = function() { return _d.title; }; this.setTitle = function(title) { if (!_supported) return null; if (typeof title == UNDEFINED) return; if (title == 'null') title = ''; title = _dc(title); _st(function() { _title = _d.title = title; if (_juststart && _frame && _frame.contentWindow && _frame.contentWindow.document) { _frame.contentWindow.document.title = title; _juststart = FALSE; } if (!_justset && _mozilla) _l.replace(_l.href.indexOf('#') != -1 ? _l.href : _l.href + '#'); _justset = FALSE; }, 10); }; this.getStatus = function() { return _t.status; }; this.setStatus = function(status) { if (!_supported) return null; if (typeof status == UNDEFINED) return; if (status == 'null') status = ''; status = _dc(status); if (!_safari) { status = _strictCheck((status != 'null') ? status : '', TRUE); if (status == '/') status = ''; if (!(/http(s)?:\/\//.test(status))) { var index = _l.href.indexOf('#'); status = (index == -1 ? _l.href : _l.href.substr(0, index)) + '#' + status; } _t.status = status; } }; this.resetStatus = function() { _t.status = ''; }; this.getValue = function() { if (!_supported) return null; return _dc(_strictCheck(_ieLocal(_value, FALSE), FALSE)); }; this.setValue = function(value) { if (!_supported) return null; if (typeof value == UNDEFINED) return; if (value == 'null') value = ''; value = _ec(_dc(_strictCheck(value, TRUE))); if (value == '/') value = ''; if (_value == value) return; _justset = TRUE; _value = value; _silent = TRUE; _update.call(SWFAddress, true); _stack[_h.length] = _value; if (_safari) { if (_opts.history) { _l[ID][_l.pathname] = _stack.toString(); _length = _h.length + 1; if (_version < 418) { if (_l.search == '') { _form.action = '#' + _value; _form.submit(); } } else if (_version < 523 || _value == '') { var evt = _d.createEvent('MouseEvents'); evt.initEvent('click', TRUE, TRUE); var anchor = _d.createElement('a'); anchor.href = '#' + _value; anchor.dispatchEvent(evt); } else { _l.hash = '#' + _value; } } else { _l.replace('#' + _value); } } else if (_value != _getHash()) { if (_opts.history) _l.hash = '#' + _dc(_ieLocal(_value, TRUE)); else _l.replace('#' + _dc(_value)); } if ((_msie && _version < 8) && _opts.history) { _st(_htmlWrite, 50); } if (_safari) _st(function(){ _silent = FALSE; }, 1); else _silent = FALSE; }; this.getPath = function() { var value = this.getValue(); if (value.indexOf('?') != -1) { return value.split('?')[0]; } else if (value.indexOf('#') != -1) { return value.split('#')[0]; } else { return value; } }; this.getPathNames = function() { var path = this.getPath(), names = path.split('/'); if (path.substr(0, 1) == '/' || path.length == 0) names.splice(0, 1); if (path.substr(path.length - 1, 1) == '/') names.splice(names.length - 1, 1); return names; }; this.getQueryString = function() { var value = this.getValue(), index = value.indexOf('?'); if (index != -1 && index < value.length) return value.substr(index + 1); }; this.getParameter = function(param) { var value = this.getValue(); var index = value.indexOf('?'); if (index != -1) { value = value.substr(index + 1); var p, params = value.split('&'), i = params.length, r = []; while(i--) { p = params[i].split('='); if (p[0] == param) r.push(p[1]); } if (r.length != 0) return r.length != 1 ? r : r[0]; } }; this.getParameterNames = function() { var value = this.getValue(); var index = value.indexOf('?'); var names = []; if (index != -1) { value = value.substr(index + 1); if (value != '' && value.indexOf('=') != -1) { var params = value.split('&'), i = 0; while(i < params.length) { names.push(params[i].split('=')[0]); i++; } } } return names; }; this.onInit = null; this.onChange = null; this.onInternalChange = null; this.onExternalChange = null; (function() { var _args; if (typeof FlashObject != UNDEFINED) SWFObject = FlashObject; if (typeof SWFObject != UNDEFINED && SWFObject.prototype && SWFObject.prototype.write) { var _s1 = SWFObject.prototype.write; SWFObject.prototype.write = function() { _args = arguments; if (this.getAttribute('version').major < 8) { this.addVariable('$swfaddress', SWFAddress.getValue()); ((typeof _args[0] == 'string') ? document.getElementById(_args[0]) : _args[0]).so = this; } var success; if (success = _s1.apply(this, _args)) _ref.addId(this.getAttribute('id')); return success; } } if (typeof swfobject != UNDEFINED) { var _s2r = swfobject.registerObject; swfobject.registerObject = function() { _args = arguments; _s2r.apply(this, _args); _ref.addId(_args[0]); } var _s2c = swfobject.createSWF; swfobject.createSWF = function() { _args = arguments; var swf = _s2c.apply(this, _args); if (swf) _ref.addId(_args[0].id); return swf; } var _s2e = swfobject.embedSWF; swfobject.embedSWF = function() { _args = arguments; if (typeof _args[8] == UNDEFINED) _args[8] = {}; if (typeof _args[8].id == UNDEFINED) _args[8].id = _args[1]; _s2e.apply(this, _args); _ref.addId(_args[8].id); } } if (typeof UFO != UNDEFINED) { var _u = UFO.create; UFO.create = function() { _args = arguments; _u.apply(this, _args); _ref.addId(_args[0].id); } } if (typeof AC_FL_RunContent != UNDEFINED) { var _a = AC_FL_RunContent; AC_FL_RunContent = function() { _args = arguments; _a.apply(this, _args); for (var i = 0, l = _args.length; i < l; i++) if (_args[i]== 'id') _ref.addId(_args[i+1]); } } })(); }; \ No newline at end of file +/** + * SWFAddress 2.4: Deep linking for Flash and Ajax + * + * SWFAddress is (c) 2006-2009 Rostislav Hristov and contributors + * This software is released under the MIT License + * + */ + +if (typeof asual == "undefined") + var asual = {}; +if (typeof asual.util == "undefined") + asual.util = {}; + +asual.util.Browser = new function() { + + var _agent = navigator.userAgent.toLowerCase(), + _safari = /webkit/.test(_agent), + _opera = /opera/.test(_agent), + _msie = /msie/.test(_agent) && !/opera/.test(_agent), + _mozilla = /mozilla/.test(_agent) && !/(compatible|webkit)/.test(_agent), + _version = parseFloat(_msie ? _agent.substr(_agent.indexOf('msie') + 4) : + (_agent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0, '0'])[1]); + + this.toString = function() { + return '[class Browser]'; + }; + + this.getVersion = function() { + return _version; + }; + + this.isMSIE = function() { + return _msie; + }; + + this.isSafari = function() { + return _safari; + }; + + this.isOpera = function() { + return _opera; + }; + + this.isMozilla = function() { + return _mozilla; + }; +}; + +asual.util.Events = new function() { + + var DOM_LOADED = 'DOMContentLoaded', + STOP = 'onstop', + _w = window, + _d = document, + _cache = [], + _util = asual.util, + _browser = _util.Browser, + _msie = _browser.isMSIE(), + _safari = _browser.isSafari(); + + this.toString = function() { + return '[class Events]'; + }; + + this.addListener = function(obj, type, listener) { + _cache.push({o: obj, t: type, l: listener}); + if (!(type == DOM_LOADED && (_msie || _safari))) { + if (obj.addEventListener) + obj.addEventListener(type, listener, false); + else if (obj.attachEvent) + obj.attachEvent('on' + type, listener); + } + }; + + this.removeListener = function(obj, type, listener) { + for (var i = 0, e; e = _cache[i]; i++) { + if (e.o == obj && e.t == type && e.l == listener) { + _cache.splice(i, 1); + break; + } + } + if (!(type == DOM_LOADED && (_msie || _safari))) { + if (obj.removeEventListener) + obj.removeEventListener(type, listener, false); + else if (obj.detachEvent) + obj.detachEvent('on' + type, listener); + } + }; + + var _unload = function() { + for (var i = 0, evt; evt = _cache[i]; i++) { + if (evt.t != DOM_LOADED) + _util.Events.removeListener(evt.o, evt.t, evt.l); + } + }; + + var _unloadFix = function() { + if (_d.readyState == 'interactive') { + function stop() { + _d.detachEvent(STOP, stop); + _unload(); + } + ; + _d.attachEvent(STOP, stop); + _w.setTimeout(function() { + _d.detachEvent(STOP, stop); + }, 0); + } + }; + + if (_msie || _safari) { + (function() { + try { + if ((_msie && _d.body) || !/loaded|complete/.test(_d.readyState)) + _d.documentElement.doScroll('left'); + } catch (e) { + return setTimeout(arguments.callee, 0); + } + for (var i = 0, e; e = _cache[i]; i++) + if (e.t == DOM_LOADED) + e.l.call(null); + })(); + } + + if (_msie) + _w.attachEvent('onbeforeunload', _unloadFix); + + this.addListener(_w, 'unload', _unload); +}; + +asual.util.Functions = new function() { + + this.toString = function() { + return '[class Functions]'; + }; + + this.bind = function(method, object, param) { + for (var i = 2, p, arr = []; p = arguments[i]; i++) + arr.push(p); + return function() { + return method.apply(object, arr); + } + }; +}; + +var SWFAddressEvent = function(type) { + + this.toString = function() { + return '[object SWFAddressEvent]'; + }; + + this.type = type; + + this.target = [SWFAddress][0]; + + this.value = SWFAddress.getValue(); + + this.path = SWFAddress.getPath(); + + this.pathNames = SWFAddress.getPathNames(); + + this.parameters = {}; + + var _parameterNames = SWFAddress.getParameterNames(); + for (var i = 0, l = _parameterNames.length; i < l; i++) + this.parameters[_parameterNames[i]] = SWFAddress.getParameter(_parameterNames[i]); + + this.parameterNames = _parameterNames; + +}; + +SWFAddressEvent.INIT = 'init'; + +SWFAddressEvent.CHANGE = 'change'; + +SWFAddressEvent.INTERNAL_CHANGE = 'internalChange'; + +SWFAddressEvent.EXTERNAL_CHANGE = 'externalChange'; + +var SWFAddress = new function() { + + var _getHash = function() { + var index = _l.href.indexOf('#'); + return index != -1 ? _ec(_dc(_l.href.substr(index + 1))) : ''; + }; + + var _getWindow = function() { + return window; + }; + + var _strictCheck = function(value, force) { + if (_opts.strict) + value = force ? (value.substr(0, 1) != '/' ? '/' + value : value) : (value == '' ? '/' : value); + return value; + }; + + var _ieLocal = function(value, direction) { + return (_msie && _l.protocol == 'file:') ? + (direction ? _value.replace(/\?/, '%3F') : _value.replace(/%253F/, '?')) : value; + }; + + var _searchScript = function(el) { + if (el.childNodes) { + for (var i = 0, l = el.childNodes.length, s; i < l; i++) { + if (el.childNodes[i].src) + _url = String(el.childNodes[i].src); + if (s = _searchScript(el.childNodes[i])) + return s; + } + } + }; + + var _titleCheck = function() { + if (_d.title != _title && _d.title.indexOf('#') != -1) + _d.title = _title; + }; + + var _listen = function() { + if (!_silent) { + var hash = _getHash(); + var diff = !(_value == hash); + if (_safari && _version < 523) { + if (_length != _h.length) { + _length = _h.length; + if (typeof _stack[_length - 1] != UNDEFINED) + _value = _stack[_length - 1]; + _update.call(this, false); + } + } else if (_msie && diff) { + if (_version < 7) + _l.reload(); + else + this.setValue(hash); + } else if (diff) { + _value = hash; + _update.call(this, false); + } + if (_msie) + _titleCheck.call(this); + } + }; + + var _bodyClick = function(e) { + if (_popup.length > 0) { + var popup = window.open(_popup[0], _popup[1], eval(_popup[2])); + if (typeof _popup[3] != UNDEFINED) + eval(_popup[3]); + } + _popup = []; + }; + + var _swfChange = function() { + for (var i = 0, id, obj, value = SWFAddress.getValue(), setter = 'setSWFAddressValue'; id = _ids[i]; i++) { + obj = document.getElementById(id); + if (obj) { + if (obj.parentNode && typeof obj.parentNode.so != UNDEFINED) { + obj.parentNode.so.call(setter, value); + } else { + if (!(obj && typeof obj[setter] != UNDEFINED)) { + var objects = obj.getElementsByTagName('object'); + var embeds = obj.getElementsByTagName('embed'); + obj = ((objects[0] && typeof objects[0][setter] != UNDEFINED) ? + objects[0] : ((embeds[0] && typeof embeds[0][setter] != UNDEFINED) ? + embeds[0] : null)); + } + if (obj) + obj[setter](value); + } + } else if (obj = document[id]) { + if (typeof obj[setter] != UNDEFINED) + obj[setter](value); + } + } + }; + + var _jsDispatch = function(type) { + this.dispatchEvent(new SWFAddressEvent(type)); + type = type.substr(0, 1).toUpperCase() + type.substr(1); + if (typeof this['on' + type] == FUNCTION) + this['on' + type](); + }; + + var _jsInit = function() { + if (_util.Browser.isSafari()) + _d.body.addEventListener('click', _bodyClick); + _jsDispatch.call(this, 'init'); + }; + + var _jsChange = function() { + _swfChange(); + _jsDispatch.call(this, 'change'); + }; + + var _update = function(internal) { + _jsChange.call(this); + if (internal) { + _jsDispatch.call(this, 'internalChange'); + } else { + _jsDispatch.call(this, 'externalChange'); + } + _st(_functions.bind(_track, this), 10); + }; + + var _track = function() { + var value = (_l.pathname + (/\/$/.test(_l.pathname) ? '' : '/') + this.getValue()).replace(/\/\//, '/').replace(/^\/$/, ''); + var fn = _t[_opts.tracker]; + if (typeof fn == FUNCTION) + fn(value); + else if (typeof _t.pageTracker != UNDEFINED && typeof _t.pageTracker._trackPageview == FUNCTION) + _t.pageTracker._trackPageview(value); + else if (typeof _t.urchinTracker == FUNCTION) + _t.urchinTracker(value); + }; + + var _htmlWrite = function() { + var doc = _frame.contentWindow.document; + doc.open(); + doc.write('' + _d.title + ''); + doc.close(); + }; + + var _htmlLoad = function() { + var win = _frame.contentWindow; + var src = win.location.href; + _value = (typeof win[ID] != UNDEFINED ? win[ID] : ''); + if (_value != _getHash()) { + _update.call(SWFAddress, false); + _l.hash = _ieLocal(_value, TRUE); + } + }; + + var _load = function() { + if (!_loaded) { + _loaded = TRUE; + if (_msie && _version < 8) { + var frameset = _d.getElementsByTagName('frameset')[0]; + _frame = _d.createElement((frameset ? '' : 'i') + 'frame'); + if (frameset) { + frameset.insertAdjacentElement('beforeEnd', _frame); + frameset[frameset.cols ? 'cols' : 'rows'] += ',0'; + _frame.src = 'javascript:false'; + _frame.noResize = true; + _frame.frameBorder = _frame.frameSpacing = 0; + } else { + _frame.src = 'javascript:false'; + _frame.style.display = 'none'; + _d.body.insertAdjacentElement('afterBegin', _frame); + } + _st(function() { + _events.addListener(_frame, 'load', _htmlLoad); + if (typeof _frame.contentWindow[ID] == UNDEFINED) + _htmlWrite(); + }, 50); + } else if (_safari) { + if (_version < 418) { + _d.body.innerHTML += '
'; + _form = _d.getElementById(ID); + } + if (typeof _l[ID] == UNDEFINED) + _l[ID] = {}; + if (typeof _l[ID][_l.pathname] != UNDEFINED) + _stack = _l[ID][_l.pathname].split(','); + } + + _st(_functions.bind(function() { + _jsInit.call(this); + _jsChange.call(this); + _track.call(this); + }, this), 1); + + if (_msie && _version >= 8) { + _d.body.onhashchange = _functions.bind(_listen, this); + _si(_functions.bind(_titleCheck, this), 50); + } else { + _si(_functions.bind(_listen, this), 50); + } + } + }; + + var ID = 'swfaddress', + FUNCTION = 'function', + UNDEFINED = 'undefined', + TRUE = true, + FALSE = false, + _util = asual.util, + _browser = _util.Browser, + _events = _util.Events, + _functions = _util.Functions, + _version = _browser.getVersion(), + _msie = _browser.isMSIE(), + _mozilla = _browser.isMozilla(), + _opera = _browser.isOpera(), + _safari = _browser.isSafari(), + _supported = FALSE, + _t = _getWindow(), + _d = _t.document, + _h = _t.history, + _l = _t.location, + _si = setInterval, + _st = setTimeout, + _dc = decodeURI, + _ec = encodeURI, + _frame, + _form, + _url, + _title = _d.title, + _length = _h.length, + _silent = FALSE, + _loaded = FALSE, + _justset = TRUE, + _juststart = TRUE, + _ref = this, + _stack = [], + _ids = [], + _popup = [], + _listeners = {}, + _value = _getHash(), + _opts = {history: TRUE, strict: TRUE}; + + if (_msie && _d.documentMode && _d.documentMode != _version) + _version = _d.documentMode != 8 ? 7 : 8; + + _supported = + (_mozilla && _version >= 1) || + (_msie && _version >= 6) || + (_opera && _version >= 9.5) || + (_safari && _version >= 312); + + if (_supported) { + + if (_opera) + history.navigationMode = 'compatible'; + + for (var i = 1; i < _length; i++) + _stack.push(''); + + _stack.push(_getHash()); + + if (_msie && _l.hash != _getHash()) + _l.hash = '#' + _ieLocal(_getHash(), TRUE); + + _searchScript(document); + var _qi = _url ? _url.indexOf('?') : -1; + if (_qi != -1) { + var param, params = _url.substr(_qi + 1).split('&'); + for (var i = 0, p; p = params[i]; i++) { + param = p.split('='); + if (/^(history|strict)$/.test(param[0])) { + _opts[param[0]] = (isNaN(param[1]) ? /^(true|yes)$/i.test(param[1]) : (parseInt(param[1]) != 0)); + } + if (/^tracker$/.test(param[0])) + _opts[param[0]] = param[1]; + } + } + + if (_msie) + _titleCheck.call(this); + + if (window == _t) + _events.addListener(document, 'DOMContentLoaded', _functions.bind(_load, this)); + _events.addListener(_t, 'load', _functions.bind(_load, this)); + + } /*else if ((!_supported && _l.href.indexOf('#') != -1) || + (_safari && _version < 418 && _l.href.indexOf('#') != -1 && _l.search != '')){ + _d.open(); + _d.write(''); + _d.close(); + } */ else { + _track(); + } + + this.toString = function() { + return '[class SWFAddress]'; + }; + + this.back = function() { + _h.back(); + }; + + this.forward = function() { + _h.forward(); + }; + + this.up = function() { + var path = this.getPath(); + this.setValue(path.substr(0, path.lastIndexOf('/', path.length - 2) + (path.substr(path.length - 1) == '/' ? 1 : 0))); + }; + + this.go = function(delta) { + _h.go(delta); + }; + + this.href = function(url, target) { + target = typeof target != UNDEFINED ? target : '_self'; + if (target == '_self') + self.location.href = url; + else if (target == '_top') + _l.href = url; + else if (target == '_blank') + window.open(url); + else + _t.frames[target].location.href = url; + }; + + this.popup = function(url, name, options, handler) { + try { + var popup = window.open(url, name, eval(options)); + if (typeof handler != UNDEFINED) + eval(handler); + } catch (ex) { + } + _popup = arguments; + }; + + this.getIds = function() { + return _ids; + }; + + this.getId = function(index) { + return _ids[0]; + }; + + this.setId = function(id) { + _ids[0] = id; + }; + + this.addId = function(id) { + this.removeId(id); + _ids.push(id); + }; + + this.removeId = function(id) { + for (var i = 0; i < _ids.length; i++) { + if (id == _ids[i]) { + _ids.splice(i, 1); + break; + } + } + }; + + this.addEventListener = function(type, listener) { + if (typeof _listeners[type] == UNDEFINED) + _listeners[type] = []; + _listeners[type].push(listener); + }; + + this.removeEventListener = function(type, listener) { + if (typeof _listeners[type] != UNDEFINED) { + for (var i = 0, l; l = _listeners[type][i]; i++) + if (l == listener) + break; + _listeners[type].splice(i, 1); + } + }; + + this.dispatchEvent = function(event) { + if (this.hasEventListener(event.type)) { + event.target = this; + for (var i = 0, l; l = _listeners[event.type][i]; i++) + l(event); + return TRUE; + } + return FALSE; + }; + + this.hasEventListener = function(type) { + return (typeof _listeners[type] != UNDEFINED && _listeners[type].length > 0); + }; + + this.getBaseURL = function() { + var url = _l.href; + if (url.indexOf('#') != -1) + url = url.substr(0, url.indexOf('#')); + if (url.substr(url.length - 1) == '/') + url = url.substr(0, url.length - 1); + return url; + }; + + this.getStrict = function() { + return _opts.strict; + }; + + this.setStrict = function(strict) { + _opts.strict = strict; + }; + + this.getHistory = function() { + return _opts.history; + }; + + this.setHistory = function(history) { + _opts.history = history; + }; + + this.getTracker = function() { + return _opts.tracker; + }; + + this.setTracker = function(tracker) { + _opts.tracker = tracker; + }; + + this.getTitle = function() { + return _d.title; + }; + + this.setTitle = function(title) { + if (!_supported) + return null; + if (typeof title == UNDEFINED) + return; + if (title == 'null') + title = ''; + title = _dc(title); + _st(function() { + _title = _d.title = title; + if (_juststart && _frame && _frame.contentWindow && _frame.contentWindow.document) { + _frame.contentWindow.document.title = title; + _juststart = FALSE; + } + if (!_justset && _mozilla) + _l.replace(_l.href.indexOf('#') != -1 ? _l.href : _l.href + '#'); + _justset = FALSE; + }, 10); + }; + + this.getStatus = function() { + return _t.status; + }; + + this.setStatus = function(status) { + if (!_supported) + return null; + if (typeof status == UNDEFINED) + return; + if (status == 'null') + status = ''; + status = _dc(status); + if (!_safari) { + status = _strictCheck((status != 'null') ? status : '', TRUE); + if (status == '/') + status = ''; + if (!(/http(s)?:\/\//.test(status))) { + var index = _l.href.indexOf('#'); + status = (index == -1 ? _l.href : _l.href.substr(0, index)) + '#' + status; + } + _t.status = status; + } + }; + + this.resetStatus = function() { + _t.status = ''; + }; + + this.getValue = function() { + if (!_supported) + return null; + return _dc(_strictCheck(_ieLocal(_value, FALSE), FALSE)); + }; + + this.setValue = function(value) { + if (!_supported) + return null; + if (typeof value == UNDEFINED) + return; + if (value == 'null') + value = ''; + value = _ec(_dc(_strictCheck(value, TRUE))); + if (value == '/') + value = ''; + if (_value == value) + return; + _justset = TRUE; + _value = value; + _silent = TRUE; + _update.call(SWFAddress, true); + _stack[_h.length] = _value; + if (_safari) { + if (_opts.history) { + _l[ID][_l.pathname] = _stack.toString(); + _length = _h.length + 1; + if (_version < 418) { + if (_l.search == '') { + _form.action = '#' + _value; + _form.submit(); + } + } else if (_version < 523 || _value == '') { + var evt = _d.createEvent('MouseEvents'); + evt.initEvent('click', TRUE, TRUE); + var anchor = _d.createElement('a'); + anchor.href = '#' + _value; + anchor.dispatchEvent(evt); + } else { + _l.hash = '#' + _value; + } + } else { + _l.replace('#' + _value); + } + } else if (_value != _getHash()) { + if (_opts.history) + _l.hash = '#' + _dc(_ieLocal(_value, TRUE)); + else + _l.replace('#' + _dc(_value)); + } + if ((_msie && _version < 8) && _opts.history) { + _st(_htmlWrite, 50); + } + if (_safari) + _st(function() { + _silent = FALSE; + }, 1); + else + _silent = FALSE; + }; + + this.getPath = function() { + var value = this.getValue(); + if (value.indexOf('?') != -1) { + return value.split('?')[0]; + } else if (value.indexOf('#') != -1) { + return value.split('#')[0]; + } else { + return value; + } + }; + + this.getPathNames = function() { + var path = this.getPath(), names = path.split('/'); + if (path.substr(0, 1) == '/' || path.length == 0) + names.splice(0, 1); + if (path.substr(path.length - 1, 1) == '/') + names.splice(names.length - 1, 1); + return names; + }; + + this.getQueryString = function() { + var value = this.getValue(), index = value.indexOf('?'); + if (index != -1 && index < value.length) + return value.substr(index + 1); + }; + + this.getParameter = function(param) { + var value = this.getValue(); + var index = value.indexOf('?'); + if (index != -1) { + value = value.substr(index + 1); + var p, params = value.split('&'), i = params.length, r = []; + while (i--) { + p = params[i].split('='); + if (p[0] == param) + r.push(p[1]); + } + if (r.length != 0) + return r.length != 1 ? r : r[0]; + } + }; + + this.getParameterNames = function() { + var value = this.getValue(); + var index = value.indexOf('?'); + var names = []; + if (index != -1) { + value = value.substr(index + 1); + if (value != '' && value.indexOf('=') != -1) { + var params = value.split('&'), i = 0; + while (i < params.length) { + names.push(params[i].split('=')[0]); + i++; + } + } + } + return names; + }; + + this.onInit = null; + + this.onChange = null; + + this.onInternalChange = null; + + this.onExternalChange = null; + + (function() { + + var _args; + + if (typeof FlashObject != UNDEFINED) + SWFObject = FlashObject; + if (typeof SWFObject != UNDEFINED && SWFObject.prototype && SWFObject.prototype.write) { + var _s1 = SWFObject.prototype.write; + SWFObject.prototype.write = function() { + _args = arguments; + if (this.getAttribute('version').major < 8) { + this.addVariable('$swfaddress', SWFAddress.getValue()); + ((typeof _args[0] == 'string') ? + document.getElementById(_args[0]) : _args[0]).so = this; + } + var success; + if (success = _s1.apply(this, _args)) + _ref.addId(this.getAttribute('id')); + return success; + } + } + + if (typeof swfobject != UNDEFINED) { + var _s2r = swfobject.registerObject; + swfobject.registerObject = function() { + _args = arguments; + _s2r.apply(this, _args); + _ref.addId(_args[0]); + } + var _s2c = swfobject.createSWF; + swfobject.createSWF = function() { + _args = arguments; + var swf = _s2c.apply(this, _args); + if (swf) + _ref.addId(_args[0].id); + return swf; + } + var _s2e = swfobject.embedSWF; + swfobject.embedSWF = function() { + _args = arguments; + if (typeof _args[8] == UNDEFINED) + _args[8] = {}; + if (typeof _args[8].id == UNDEFINED) + _args[8].id = _args[1]; + _s2e.apply(this, _args); + _ref.addId(_args[8].id); + } + } + + if (typeof UFO != UNDEFINED) { + var _u = UFO.create; + UFO.create = function() { + _args = arguments; + _u.apply(this, _args); + _ref.addId(_args[0].id); + } + } + + if (typeof AC_FL_RunContent != UNDEFINED) { + var _a = AC_FL_RunContent; + AC_FL_RunContent = function() { + _args = arguments; + _a.apply(this, _args); + for (var i = 0, l = _args.length; i < l; i++) + if (_args[i] == 'id') + _ref.addId(_args[i + 1]); + } + } + + })(); +}; diff --git a/inc/ws/Util/packager/class.ws.packager.html.php b/inc/ws/Util/packager/class.ws.packager.html.php index 98639fe8e..cbac22f02 100644 --- a/inc/ws/Util/packager/class.ws.packager.html.php +++ b/inc/ws/Util/packager/class.ws.packager.html.php @@ -340,7 +340,7 @@ class wsPackagerHTML extends wsPackager { protected function mergeJavascript() { $dest = WS_COMPILE_ASSETS . '/fluidbook.js'; $orig = WS_COMPILE_ASSETS . '/_js/'; - $files = array('swfobject.js' => false, 'swfaddress.js' => true, 'fluidbook.js' => true); + $files = array('log4js.js' => false, 'esapi.js' => false, 'resources/i18n/ESAPI_Standard_en_US.properties.js' => false, 'resources/Base.esapi.properties.js' => false, 'swfobject.js' => false, 'swfaddress.js' => true, 'fluidbook.js' => true); $refresh = false; if (file_exists($dest)) { diff --git a/inc/ws/Util/packager/class.ws.packager.php b/inc/ws/Util/packager/class.ws.packager.php index 3245a794b..238394a94 100644 --- a/inc/ws/Util/packager/class.ws.packager.php +++ b/inc/ws/Util/packager/class.ws.packager.php @@ -1,234 +1,234 @@ -makePackage($zip); - } - - public function __construct($book_id, $vdir = null, $whole = true) { - global $core; - - $this->book_id = $book_id; - - $this->vdir = $vdir; - $this->dir = ROOT . '/fluidbook/packager/' . $book_id . '/'; - $this->whole = $whole; - - if (!file_exists($this->dir)) { - mkdir($this->dir, 0777, true); - } - - $this->daoBook = new wsDAOBook($core->con); - $this->book = $this->daoBook->selectById($book_id); - $this->pages = $this->daoBook->getPagesOfBook($book_id, false); - - $daoTheme = new wsDAOTheme($core->con); - $this->theme = $daoTheme->getThemeOfBook($book_id, true); - $this->themeRoot = WS_THEMES . '/' . $this->theme->theme_id . '/'; - - $this->workingDir = WS_BOOKS . '/working/' . $book_id . '/'; - - $this->compile(); - } - - protected function compile() { - $this->daoBook->compile($this->book_id, '2'); - } - - protected function preparePackage() { - $this->initTempDir(); - } - - public function makePackage($zip) { - $this->preparePackage(); - } - - protected function replaceContents($str, $toReplace) { - $res = $str; - foreach ($toReplace as $k => $v) { - if (is_null($v)) { - return; - } - $res = str_replace('$' . $k, $v, $res); - } - return $res; - } - - protected function copyFluidbookFiles() { - // Copie du FB vers un répertoire temporaire - $cp = new cubeCommandLine('cp'); - $cp->setArg('R'); - $cp->setArg('p'); - $cp->setArg(null, WS_BOOKS . '/final/' . $this->book->book_id . '/*'); - $cp->setArg(null, $this->vdir); - $cp->execute(); - } - - protected function copyOtherFiles($files) { - foreach ($files as $source => $dest) { - if (is_int($source)) { - $source = $dest; - } - - $s = WS_COMPILE_ASSETS . '/' . $source; - if (is_file($s) && !file_exists($this->vdir . $dest)) { - $this->copy($s, $this->vdir . $dest); - } else if (is_dir($s)) { - $cp = new cubeCommandLine('cp'); - $cp->setArg('R'); - $cp->setArg('p'); - $cp->setArg(null, $s); - $cp->setArg(null, $this->vdir); - $cp->execute(); - - $mv = new cubeCommandLine('mv'); - $mv->setArg($this->vdir . '/' . $source); - $mv->setArg($this->vdir . '/' . $dest); - $mv->execute(); - } - } - } - - protected function getBaseFile() { - return $this->version . '-' . date('Ymdhis', TIME) . '-' . cubeText::str2URL($this->book->parametres->title); - } - - protected function getRelativeBase() { - return '/packager/download/' . $this->getBaseFile(); - } - - protected function getURLBase($ext = '') { - $res = '/fluidbook' . $this->getRelativeBase(); - if ($ext != '') { - $res .= '.' . $ext; - } - return $res; - } - - protected function getPathBase($ext = '') { - $res = WS_FILES . $this->getRelativeBase(); - if ($ext != '') { - $res .= '.' . $ext; - } - - return $res; - } - - protected function zip($zipfile = null) { - if (!$this->whole) { - return; - } - $url = $this->getURLBase('zip'); - $final = $this->getPathBase('zip'); - $rename = false; - if (is_null($zipfile)) { - $zipfile = $final; - } else { - $rename = true; - } - - $zip = new cubeCommandLine('zip'); - $zip->cd($this->vdir); - $zip->setArg(null, $zipfile); - $zip->setArg('0'); - $zip->setArg('r'); - $zip->setArg('u'); - $zip->setArg(null, '.'); - $zip->execute(); - - if (!file_exists(WS_FILES . '/packager/download')) { - mkdir(WS_FILES . '/packager/download', 0777, true); - } - - if ($rename) { - rename($zipfile, $final); - } - return $url; - } - - protected function initTempDir() { - if (is_null($this->vdir)) { - $this->vdir = $this->dir . $this->version . '/'; - } - $this->cleanVdir(); - if (!file_exists($this->vdir . '/data')) { - mkdir($this->vdir . '/data', 0777, true); - } - } - - protected function cleanVdir() { - if (file_exists($this->vdir)) { - return; - // Suppression du répertoire si il existe - $rm = new cubeCommandLine('rm'); - $rm->setArg('r'); - $rm->setArg('f'); - $rm->setArg(null, $this->vdir); - $rm->execute(); - } - } - - protected function moveDatasSWF() { - if (file_exists($this->vdir . '/FluidbookDatas.swf')) { - rename($this->vdir . '/FluidbookDatas.swf', $this->vdir . '/data/FluidbookDatas.swf'); - } - if (file_exists($this->vdir . '/FluidbookDatasLight.swf')) { - rename($this->vdir . '/FluidbookDatasLight.swf', $this->vdir . '/data/FluidbookDatasLight.swf'); - } - } - - protected function postPackage() { - - } - - public function __destruct() { - if ($this->whole && $this->cleanOnDestruct) { - $this->cleanVdir(); - } - } - - public function copy($source, $dest) { - if (!file_exists($source)) { - return; - } - copy($source, $dest); - touch($dest, filemtime($source)); - } - -} - +makePackage($zip); + } + + public function __construct($book_id, $vdir = null, $whole = true) { + global $core; + + $this->book_id = $book_id; + + $this->vdir = $vdir; + $this->dir = ROOT . '/fluidbook/packager/' . $book_id . '/'; + $this->whole = $whole; + + if (!file_exists($this->dir)) { + mkdir($this->dir, 0777, true); + } + + $this->daoBook = new wsDAOBook($core->con); + $this->book = $this->daoBook->selectById($book_id); + $this->pages = $this->daoBook->getPagesOfBook($book_id, false); + + $daoTheme = new wsDAOTheme($core->con); + $this->theme = $daoTheme->getThemeOfBook($book_id, true); + $this->themeRoot = WS_THEMES . '/' . $this->theme->theme_id . '/'; + + $this->workingDir = WS_BOOKS . '/working/' . $book_id . '/'; + + $this->compile(); + } + + protected function compile() { + $this->daoBook->compile($this->book_id, '2'); + } + + protected function preparePackage() { + $this->initTempDir(); + } + + public function makePackage($zip) { + $this->preparePackage(); + } + + protected function replaceContents($str, $toReplace) { + $res = $str; + foreach ($toReplace as $k => $v) { + if (is_null($v)) { + return; + } + $res = str_replace('$' . $k, $v, $res); + } + return $res; + } + + protected function copyFluidbookFiles() { + // Copie du FB vers un répertoire temporaire + $cp = new cubeCommandLine('cp'); + $cp->setArg('R'); + $cp->setArg('p'); + $cp->setArg(null, WS_BOOKS . '/final/' . $this->book->book_id . '/*'); + $cp->setArg(null, $this->vdir); + $cp->execute(); + } + + protected function copyOtherFiles($files) { + foreach ($files as $source => $dest) { + if (is_int($source)) { + $source = $dest; + } + + $s = WS_COMPILE_ASSETS . '/' . $source; + if (is_file($s) && !file_exists($this->vdir . $dest)) { + $this->copy($s, $this->vdir . $dest); + } else if (is_dir($s)) { + $cp = new cubeCommandLine('cp'); + $cp->setArg('R'); + $cp->setArg('p'); + $cp->setArg(null, $s); + $cp->setArg(null, $this->vdir); + $cp->execute(); + + $mv = new cubeCommandLine('mv'); + $mv->setArg($this->vdir . '/' . $source); + $mv->setArg($this->vdir . '/' . $dest); + $mv->execute(); + } + } + } + + protected function getBaseFile() { + return $this->version . '-' . date('Ymdhis', TIME) . '-' . cubeText::str2URL($this->book->parametres->title); + } + + protected function getRelativeBase() { + return '/packager/download/' . $this->getBaseFile(); + } + + protected function getURLBase($ext = '') { + $res = '/fluidbook' . $this->getRelativeBase(); + if ($ext != '') { + $res .= '.' . $ext; + } + return $res; + } + + protected function getPathBase($ext = '') { + $res = WS_FILES . $this->getRelativeBase(); + if ($ext != '') { + $res .= '.' . $ext; + } + + return $res; + } + + protected function zip($zipfile = null) { + if (!$this->whole) { + return; + } + $url = $this->getURLBase('zip'); + $final = $this->getPathBase('zip'); + $rename = false; + if (is_null($zipfile)) { + $zipfile = $final; + } else { + $rename = true; + } + + $zip = new cubeCommandLine('zip'); + $zip->cd($this->vdir); + $zip->setArg(null, $zipfile); + $zip->setArg('0'); + $zip->setArg('r'); + $zip->setArg('u'); + $zip->setArg(null, '.'); + $zip->execute(); + + if (!file_exists(WS_FILES . '/packager/download')) { + mkdir(WS_FILES . '/packager/download', 0777, true); + } + + if ($rename) { + rename($zipfile, $final); + } + return $url; + } + + protected function initTempDir() { + if (is_null($this->vdir)) { + $this->vdir = $this->dir . $this->version . '/'; + } + $this->cleanVdir(); + if (!file_exists($this->vdir . '/data')) { + mkdir($this->vdir . '/data', 0777, true); + } + } + + protected function cleanVdir() { + if (file_exists($this->vdir)) { + + // Suppression du répertoire si il existe + $rm = new cubeCommandLine('rm'); + $rm->setArg('r'); + $rm->setArg('f'); + $rm->setArg(null, $this->vdir); + $rm->execute(); + } + } + + protected function moveDatasSWF() { + if (file_exists($this->vdir . '/FluidbookDatas.swf')) { + rename($this->vdir . '/FluidbookDatas.swf', $this->vdir . '/data/FluidbookDatas.swf'); + } + if (file_exists($this->vdir . '/FluidbookDatasLight.swf')) { + rename($this->vdir . '/FluidbookDatasLight.swf', $this->vdir . '/data/FluidbookDatasLight.swf'); + } + } + + protected function postPackage() { + + } + + public function __destruct() { + if ($this->whole && $this->cleanOnDestruct) { + $this->cleanVdir(); + } + } + + public function copy($source, $dest) { + if (!file_exists($source)) { + return; + } + copy($source, $dest); + touch($dest, filemtime($source)); + } + +} + ?> \ No newline at end of file -- 2.39.5