diff --git a/trunk/ToDo.txt b/trunk/ToDo.txt index a89f863a..7db2465f 100644 --- a/trunk/ToDo.txt +++ b/trunk/ToDo.txt @@ -1,3 +1 @@ -- Check mail jars - Google Tracking -- Customizable JSP Replacements \ No newline at end of file diff --git a/trunk/core-js/pom.xml b/trunk/core-js/pom.xml index 1e11e749..f899e925 100644 --- a/trunk/core-js/pom.xml +++ b/trunk/core-js/pom.xml @@ -51,7 +51,7 @@ ${basedir}/target/tmp/header-min.js ${basedir}/target/tmp/ColorPicker-min.js ${basedir}/target/tmp/Loader-min.js - ${basedir}/target/tmp/Logger-min.js + ${basedir}/target/tmp/log4js-min.js ${basedir}/target/tmp/Monitor-min.js ${basedir}/target/tmp/Point-min.js ${basedir}/target/tmp/UserAgent-min.js diff --git a/trunk/core-js/src/main/javascript/Logger.js b/trunk/core-js/src/main/javascript/Logger.js deleted file mode 100644 index 1754686c..00000000 --- a/trunk/core-js/src/main/javascript/Logger.js +++ /dev/null @@ -1,129 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You 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. -* -* $Id: file 64488 2006-03-10 17:32:09Z paulo $ -*/ - -core.Logger = -{ - _enabled: false, - setEnabled: function (enabled) { - this._enabled = enabled; - },init: function(serverLogger) -{ - this._serverLogger = serverLogger; - if (window.onerror) { - // Save any previously defined handler to call - core.Logger._origOnWindowError = window.onerror; - } - window.onerror = core.Logger._onWindowError; -}, - log: function(message, severity, src) - { - if (!severity) - { - severity = core.LoggerSeverity.DEBUG; - } - - // Error messages must be loggued in the server ... - if (severity >= core.LoggerSeverity.ERROR) - { - if (this._serverLogger) - { - try - { - this._serverLogger.logError(core.LoggerSeverity.ERROR, message); - } catch(e) - { - } - } - } - - // // Finally, log the error in debug console if it's enabled. - if (this._enabled) - { - this._browserLogger(message); - } - }, - _browserLogger: function(message) { - // Firebug is not enabled. - - if (core.Logger._origOnWindowError) { - core.Logger._origOnWindowError(); - } - - if (!console) - { - if (!this._isInitialized) - { - this._console = window.document.createElement("div"); - this._console.style.position = "absolute"; - this._console.style.width = "300px"; - this._console.style.height = "200px"; - this._console.style.bottom = 0; - this._console.style.right = 0; - this._console.style.border = '1px solid black'; - this._console.style.background = 'yellow'; - this._console.style.zIndex = 60000; - - this._textArea = window.document.createElement("textarea"); - this._textArea.cols = "40"; - this._textArea.rows = "10"; - this._console.appendChild(this._textArea); - - window.document.body.appendChild(this._console); - this._isInitialized = true; - } - this._textArea.value = this._textArea.value + "\n" + msg; - - } else - { - // Firebug console... - console.log(message); - } - }, -/** - * Handles logging of messages due to window error events. - * - * @method _onWindowError - * @param sMsg {String} The error message. - * @param sUrl {String} URL of the error. - * @param sLine {String} Line number of the error. - * @private - */ - _onWindowError: function(sMsg, sUrl, sLine) { - // Logger is not in scope of this event handler - // http://cfis.savagexi.com/articles/2007/05/08/what-went-wrong-with-my-javascript - try { - core.Logger.log(sMsg + ' (' + sUrl + ', line ' + sLine + ')', core.LoggerSeverity.ERROR, "window"); - } - catch(e) { - return false; - } - return true; - }, - logError: function(msg) { - core.Logger.log(msg, core.LoggerSeverity.ERROR, "code"); - } -}; - -core.LoggerSeverity = -{ - DEBUG: 1, - WARNING: 2, - ERROR: 3, - WINDOW: 4 -}; \ No newline at end of file diff --git a/trunk/core-js/src/main/javascript/UserAgent.js b/trunk/core-js/src/main/javascript/UserAgent.js index c6586eff..43bb9d29 100644 --- a/trunk/core-js/src/main/javascript/UserAgent.js +++ b/trunk/core-js/src/main/javascript/UserAgent.js @@ -1,22 +1,22 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You 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. -* -* $Id: file 64488 2006-03-10 17:32:09Z paulo $ -*/ - +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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. +* +* $Id: file 64488 2006-03-10 17:32:09Z paulo $ +*/ + core.UserAgent = { _isVMLSupported:null, isVMLSupported: function() @@ -31,10 +31,6 @@ core.UserAgent = { { return !core.UserAgent.isVMLSupported(); }, - isIframeWorkaroundRequired: function() - { - return core.UserAgent.OS == "Mac" && core.UserAgent.browser == "Firefox" && core.UserAgent.version < 3; - }, isMozillaFamily: function() { return this.browser == "Netscape" || this.browser == "Firefox"; diff --git a/trunk/core-js/src/main/javascript/Utils.js b/trunk/core-js/src/main/javascript/Utils.js index 3179e3d5..36acc802 100644 --- a/trunk/core-js/src/main/javascript/Utils.js +++ b/trunk/core-js/src/main/javascript/Utils.js @@ -1,22 +1,22 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You 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. -* -* $Id: file 64488 2006-03-10 17:32:09Z paulo $ -*/ - +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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. +* +* $Id: file 64488 2006-03-10 17:32:09Z paulo $ +*/ + core.Utils = { isDefined: function(val) @@ -70,21 +70,7 @@ core.assert = function(assert, message) core.findElement = function(name) { - var result; - if (core.UserAgent.isIframeWorkaroundRequired()) - { - var iframe = $('mindplotIFrame'); - var doc = iframe.contentDocument; - if (doc == undefined || doc == null) - doc = iframe.contentWindow.document; - result = $(doc.getElementById(name)); - } - if (!result) - { - result = $(name); - } - - return result; + return $(name); } Math.sign = function(value) diff --git a/trunk/core-js/src/main/javascript/WaitDialog.js b/trunk/core-js/src/main/javascript/WaitDialog.js index 9ab35f10..3bc08710 100644 --- a/trunk/core-js/src/main/javascript/WaitDialog.js +++ b/trunk/core-js/src/main/javascript/WaitDialog.js @@ -1,96 +1,47 @@ /* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You 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. -* -* $Id: file 64488 2006-03-10 17:32:09Z paulo $ -*/ + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + * + * $Id: file 64488 2006-03-10 17:32:09Z paulo $ + */ /* -Created By: Chris Campbell -Website: http://particletree.com -Date: 2/1/2006 + Created By: Chris Campbell + Website: http://particletree.com + Date: 2/1/2006 -Inspired by the lightbox implementation found at http://www.huddletogether.com/projects/lightbox/ -*/ + Inspired by the lightbox implementation found at http://www.huddletogether.com/projects/lightbox/ + /*-----------------------------------------------------------------------------------------------*/ -/*-------------------------------GLOBAL VARIABLES------------------------------------*/ - -var detect = navigator.userAgent.toLowerCase(); -var OS,browser,version,total,thestring; - -/*-----------------------------------------------------------------------------------------------*/ - -//Browser detect script origionally created by Peter Paul Koch at http://www.quirksmode.org/ - -function getBrowserInfo(evt) { - if (checkIt('konqueror')) { - browser = "Konqueror"; - OS = "Linux"; - } - else if (checkIt('safari')) browser = "Safari" - else if (checkIt('omniweb')) browser = "OmniWeb" - else if (checkIt('opera')) browser = "Opera" - else if (checkIt('webtv')) browser = "WebTV"; - else if (checkIt('icab')) browser = "iCab" - else if (checkIt('msie')) browser = "Internet Explorer" - else if (!checkIt('compatible')) { - browser = "Netscape Navigator" - version = detect.charAt(8); - } - else browser = "An unknown browser"; - - if (!version) version = detect.charAt(place + thestring.length); - - if (!OS) { - if (checkIt('linux')) OS = "Linux"; - else if (checkIt('x11')) OS = "Unix"; - else if (checkIt('mac')) OS = "Mac" - else if (checkIt('win')) OS = "Windows" - else OS = "an unknown operating system"; - } -} - -function checkIt(string) { - place = detect.indexOf(string) + 1; - thestring = string; - return place; -} - -/*-----------------------------------------------------------------------------------------------*/ - -$(window).addEvent('load', getBrowserInfo); core.WaitDialog = new Class({ - initialize: function(contentId) { - this.content = $(contentId); - }, yPos : 0, - xPos : 0, -// Turn everything on - mainly the IE fixes - activate: function(changeCursor) + initialize: function() { + }, + // Turn everything on - mainly the IE fixes + activate: function(changeCursor, dialogContent) { - // if (browser == 'Internet Explorer'){ - //// this.getScroll(); - // this.prepareIE('100%', 'hidden'); - //// this.setScroll(0,0); - //// this.hideSelects('hidden'); - // } + + this.content = dialogContent; + + this._initLightboxMarkup(); + this.displayLightbox("block"); // Change to loading cursor. @@ -99,41 +50,27 @@ core.WaitDialog = new Class({ window.document.body.style.cursor = "wait"; } }, + changeContent: function(dialogContent, changeCursor) + { + this.content = dialogContent; + if (!$('lbContent')) + { + // Dialog is not activated. Nothing to do ... + window.document.body.style.cursor = "pointer"; + return; + } -// Ie requires height to 100% and overflow hidden or else you can scroll down past the lightbox - prepareIE: function(height, overflow) { - bod = document.getElementsByTagName('body')[0]; - bod.style.height = height; - bod.style.overflow = overflow; + this.processInfo(); - htm = document.getElementsByTagName('html')[0]; - htm.style.height = height; - htm.style.overflow = overflow; - }, - -// In IE, select elements hover on top of the lightbox - hideSelects: function(visibility) { - selects = document.getElementsByTagName('select'); - for (i = 0; i < selects.length; i++) { - selects[i].style.visibility = visibility; + // Change to loading cursor. + if (changeCursor) + { + window.document.body.style.cursor = "wait"; + }else + { + window.document.body.style.cursor = "auto"; } }, - -// Taken from lightbox implementation found at http://www.huddletogether.com/projects/lightbox/ - getScroll: function() { - if (self.pageYOffset) { - this.yPos = self.pageYOffset; - } else if (document.documentElement && document.documentElement.scrollTop) { - this.yPos = document.documentElement.scrollTop; - } else if (document.body) { - this.yPos = document.body.scrollTop; - } - }, - - setScroll: function(x, y) { - window.scrollTo(x, y); - }, - displayLightbox: function(display) { $('overlay').style.display = display; $('lightbox').style.display = display; @@ -141,15 +78,19 @@ core.WaitDialog = new Class({ this.processInfo(); }, -// Display Ajax response + // Display dialog content ... processInfo: function() { - var info = new Element('div').setProperty('id', 'lbContent'); - info.setHTML(this.content.innerHTML); - info.injectBefore($('lbLoadMessage')); + if ($('lbContent')) + $('lbContent').remove(); + + var lbContentElement = new Element('div').setProperty('id', 'lbContent'); + lbContentElement.setHTML(this.content.innerHTML); + + lbContentElement.injectBefore($('lbLoadMessage')); $('lightbox').className = "done"; }, -// Search through new links within the lightbox, and attach click event + // Search through new links within the lightbox, and attach click event actions: function() { lbActions = document.getElementsByClassName('lbAction'); @@ -164,53 +105,31 @@ core.WaitDialog = new Class({ }, -// Example of creating your own functionality once lightbox is initiated - insert: function(e) { - var event = new Event(e); - link = event.target; - if ($('lbContent')) - $('lbContent').remove(); - - var myAjax = new Ajax.Request( - link.href, - {method: 'post', parameters: "", onComplete: this.processInfo.pass(this)} - ); - - }, - -// Example of creating your own functionality once lightbox is initiated + // Example of creating your own functionality once lightbox is initiated deactivate: function(time) { if ($('lbContent')) $('lbContent').remove(); - // - // if (browser == "Internet Explorer"){ - // this.setScroll(0,this.yPos); - // this.prepareIE("auto", "auto"); - // this.hideSelects("visible"); - // } + this.displayLightbox("none"); window.document.body.style.cursor = "default"; } -}); + , _initLightboxMarkup:function() + { + // Add overlay element inside body ... + var bodyElem = document.getElementsByTagName('body')[0]; + var overlayElem = new Element('div').setProperty('id', 'overlay'); + overlayElem.injectInside(bodyElem); -/*-----------------------------------------------------------------------------------------------*/ + // Add lightbox element inside body ... + var lightboxElem = new Element('div').setProperty('id', 'lightbox'); + lightboxElem.addClass('loading'); -// Onload, make all links that need to trigger a lightbox active -function initialize() { - addLightboxMarkup(); - valid = new core.WaitDialog($('sampleDialog')); -} + var lbLoadMessageElem = new Element('div').setProperty('id', 'lbLoadMessage'); + lbLoadMessageElem.injectInside(lightboxElem); -// Add in markup necessary to make this work. Basically two divs: -// Overlay holds the shadow -// Lightbox is the centered square that the content is put into. -function addLightboxMarkup() { - var body = document.getElementsByTagName('body')[0]; - overlay = new Element('div').setProperty('id', 'overlay').injectInside(document.body); - var lb = new Element('div').setProperty('id', 'lightbox'); - lb.addClass('loading'); - var tmp = new Element('div').setProperty('id', 'lbLoadMessage').injectInside(lb); - lb.injectInside(document.body); -} \ No newline at end of file + lightboxElem.injectInside(bodyElem); + + } +}); \ No newline at end of file diff --git a/trunk/core-js/src/main/javascript/footer.js b/trunk/core-js/src/main/javascript/footer.js index b68760ab..3e73abfb 100644 --- a/trunk/core-js/src/main/javascript/footer.js +++ b/trunk/core-js/src/main/javascript/footer.js @@ -1,21 +1,94 @@ /* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You 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. -* -* $Id: file 64488 2006-03-10 17:32:09Z paulo $ -*/ + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + * + * $Id: file 64488 2006-03-10 17:32:09Z paulo $ + */ + +// Init default logger level ... +var wLogger = new Log4js.getLogger("WiseMapping"); +wLogger.setLevel(Log4js.Level.ALL); +wLogger.addAppender(new Log4js.BrowserConsoleAppender()); + +// Is logger service available ? +if (window.LoggerService) +{ + Log4js.WiseServerAppender = function() + { + this.layout = new Log4js.SimpleLayout(); + }; + + Log4js.WiseServerAppender.prototype = Log4js.extend(new Log4js.Appender(), { + /** + * @see Log4js.Appender#doAppend + */ + doAppend: function(loggingEvent) { + try { + var message = this.layout.format(loggingEvent); + var level = this.levelCode(loggingEvent); + + window.LoggerService.logError(level, message); + + } catch (e) { + alert(e); + } + }, + + /** + * toString + */ + toString: function() { + return "Log4js.WiseServerAppender"; + }, + + levelCode: function(loggingEvent) + { + var retval; + switch (loggingEvent.level) { + case Log4js.Level.FATAL: + retval = 3; + break; + case Log4js.Level.ERROR: + retval = 3; + break; + case Log4js.Level.WARN: + retval = 2; + break; + default: + retval = 1; + break; + } + + return retval; + } + }); + + wLogger.addAppender(new Log4js.WiseServerAppender()); + +} + + +// Handle error events ... +window.onerror = function(sMsg, sUrl, sLine) +{ + window.hasUnexpectedErrors = true; + var msg = sMsg + ' (' + sUrl + ', line ' + sLine + ')'; + wLogger.fatal(msg); + + return true; +}; window.__coreLoad = function() { diff --git a/trunk/core-js/src/main/javascript/header.js b/trunk/core-js/src/main/javascript/header.js index 9208f24c..3d4560b6 100644 --- a/trunk/core-js/src/main/javascript/header.js +++ b/trunk/core-js/src/main/javascript/header.js @@ -17,4 +17,4 @@ * $Id: file 64488 2006-03-10 17:32:09Z paulo $ */ -var core = {}; \ No newline at end of file +var core = {}; diff --git a/trunk/core-js/src/main/javascript/log4js.js b/trunk/core-js/src/main/javascript/log4js.js new file mode 100644 index 00000000..29000f95 --- /dev/null +++ b/trunk/core-js/src/main/javascript/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. + * + *

Example:

+ *
+ *  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" );
+ * 
+ * + * @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.

+ * 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: + * + * @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("\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 = ".*"; + + // 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.levelCode(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: + * + * @private + */ + levelCode: 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.MozillaJSConsoleAppender(); + } + 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/trunk/mindplot/src/main/javascript/MindmapDesigner.js b/trunk/mindplot/src/main/javascript/MindmapDesigner.js index d4b7c9d3..e781f953 100644 --- a/trunk/mindplot/src/main/javascript/MindmapDesigner.js +++ b/trunk/mindplot/src/main/javascript/MindmapDesigner.js @@ -426,6 +426,9 @@ mindplot.MindmapDesigner.prototype.loadFromXML = function(mapId, xmlContent) // Place the focus on the Central Topic var centralTopic = this.getCentralTopic(); this._goToNode.attempt(centralTopic, this); + + this._fireEvent("loadsuccess"); + }; mindplot.MindmapDesigner.prototype.load = function(mapId) @@ -444,6 +447,8 @@ mindplot.MindmapDesigner.prototype.load = function(mapId) // Place the focus on the Central Topic var centralTopic = this.getCentralTopic(); this._goToNode.attempt(centralTopic, this); + + this._fireEvent("loadsuccess"); }; mindplot.MindmapDesigner.prototype._loadMap = function(mapId, mindmapModel) @@ -466,6 +471,8 @@ mindplot.MindmapDesigner.prototype._loadMap = function(mapId, mindmapModel) nodeGraph.setBranchVisibility(true); } } + this._fireEvent("loadsuccess"); + }; diff --git a/trunk/mindplot/src/main/javascript/PersistanceManager.js b/trunk/mindplot/src/main/javascript/PersistanceManager.js index 2b53bf9c..eb29548b 100644 --- a/trunk/mindplot/src/main/javascript/PersistanceManager.js +++ b/trunk/mindplot/src/main/javascript/PersistanceManager.js @@ -1,22 +1,22 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You 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. -* -* $Id: file 64488 2006-03-10 17:32:09Z paulo $ -*/ - +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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. +* +* $Id: file 64488 2006-03-10 17:32:09Z paulo $ +*/ + mindplot.PersistanceManager = function(editorService) { this._editorService = editorService; @@ -43,7 +43,7 @@ mindplot.PersistanceManager.prototype.save = function(mindmap, chartType, xmlCha if (response.msgCode != "OK") { monitor.logError("Save could not be completed. Please,try again in a couple of minutes."); - core.Logger.logError(response.msgDetails); + wLogger.error(response.msgDetails); } else { // Execute on success handler ... @@ -56,7 +56,7 @@ mindplot.PersistanceManager.prototype.save = function(mindmap, chartType, xmlCha errorHandler:function(message) { var monitor = core.Monitor.getInstance(); monitor.logError("Save could not be completed. Please,try again in a couple of minutes."); - core.Logger.logError(message); + wLogger.error(message); }, verb:"POST", async: false @@ -89,7 +89,7 @@ mindplot.PersistanceManager.prototype.load = function(mapId) var msg = response.msgDetails; var monitor = core.Monitor.getInstance(); monitor.logFatal("We're sorry, an error has occurred and we can't load your map. Please try again in a few minutes."); - core.Logger.logError(msg); + wLogger.error(msg); } }, verb:"GET", @@ -97,7 +97,7 @@ mindplot.PersistanceManager.prototype.load = function(mapId) errorHandler:function(msg) { var monitor = core.Monitor.getInstance(); monitor.logFatal("We're sorry, an error has occurred and we can't load your map. Please try again in a few minutes."); - core.Logger.logError(msg); + wLogger.error(msg); } }); diff --git a/trunk/web2d/src/main/javascript/peer/svg/GroupPeer.js b/trunk/web2d/src/main/javascript/peer/svg/GroupPeer.js index 879584b7..eef85194 100644 --- a/trunk/web2d/src/main/javascript/peer/svg/GroupPeer.js +++ b/trunk/web2d/src/main/javascript/peer/svg/GroupPeer.js @@ -1,22 +1,22 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You 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. -* -* $Id: file 64488 2006-03-10 17:32:09Z paulo $ -*/ - +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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. +* +* $Id: file 64488 2006-03-10 17:32:09Z paulo $ +*/ + web2d.peer.svg.GroupPeer = function() { var svgElement = window.document.createElementNS(this.svgNamespace, 'g'); @@ -77,7 +77,6 @@ web2d.peer.svg.GroupPeer.prototype.updateTransform = function() var cx = this._position.x - this._coordOrigin.x * sx; var cy = this._position.y - this._coordOrigin.y * sy; - //Logger.logMsg("Group.updateTrasform:"+"translate("+ cx + "," + cy+ ") scale("+ sx + "," + sy + ")"); this._native.setAttribute("transform", "translate(" + cx + "," + cy + ") scale(" + sx + "," + sy + ")"); }; diff --git a/trunk/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java b/trunk/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java index 915eb7c6..d1c20b1c 100644 --- a/trunk/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java +++ b/trunk/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java @@ -312,7 +312,8 @@ public class UserAgent implements Serializable { public boolean isBrowserSupported() { // Is it a supported browser ?. final UserAgent.Product product = this.getProduct(); - boolean result = product == UserAgent.Product.FIREFOX && this.isVersionGreatedOrEqualThan(1, 5); + boolean result = product == UserAgent.Product.FIREFOX && ((this.isVersionGreatedOrEqualThan(1, 5) && this.getOs() != UserAgent.OS.MAC) || (this.isVersionGreatedOrEqualThan(3, 0) && this.getOs() == UserAgent.OS.MAC)); + result = result || product == UserAgent.Product.EXPLORER && this.isVersionGreatedOrEqualThan(6, 0) && this.getOs() == UserAgent.OS.WINDOWS; result = result || product == UserAgent.Product.OPERA && this.isVersionGreatedOrEqualThan(9, 2); return result; diff --git a/trunk/wise-webapp/src/main/webapp/WEB-INF/classes/messages.properties b/trunk/wise-webapp/src/main/webapp/WEB-INF/classes/messages.properties index 0edb1166..21bf2fd7 100644 --- a/trunk/wise-webapp/src/main/webapp/WEB-INF/classes/messages.properties +++ b/trunk/wise-webapp/src/main/webapp/WEB-INF/classes/messages.properties @@ -70,6 +70,7 @@ YES=yes NO=no EDITOR.LOADING=Loading ... +EDITOR.ERROR_LOADING=An unexpected error has occurred initializing this page. <br/>We'll solve this problem as soon as possible. Please, click <a href="mymaps.htm">here</a> to return to your mindmap list. SITE.TITLE=WiseMapping SITE.SLOGAN=Visual Thinking Evolution SAVE=Save diff --git a/trunk/wise-webapp/src/main/webapp/css/editor.css b/trunk/wise-webapp/src/main/webapp/css/editor.css index 8a716d83..7c3d8429 100644 --- a/trunk/wise-webapp/src/main/webapp/css/editor.css +++ b/trunk/wise-webapp/src/main/webapp/css/editor.css @@ -24,7 +24,7 @@ html { top: 30px; } -#loadingContainer { +#waitingContainer,#errorContainer { position: relative; top: 80px; height: 120px; /*background: whitesmoke;*/ @@ -36,7 +36,12 @@ html { } -#loadingContainer .loadingText { +#errorContainer { + width: 400px; + border: 1px solid red; +} + +#waitingContainer .loadingText { position: relative; top: 50%; margin-top: -35px; @@ -47,9 +52,32 @@ html { float: left; } -#loadingContainer .loadingIcon { +#errorContainer .loadingText { position: relative; - background: url( ../images/loadingIcon.gif ) no-repeat; + top: 50%; + margin-top: -80px; + font-size: 15px; + font-weight: bold; + vertical-align: text-bottom; + height: 30px; + float: right; + padding-left:120px; +} + +#waitingContainer .loadingIcon { + position: relative; + background: url(../images/loadingIcon.gif) no-repeat; + top: 50%; + margin-top: -65px; + height: 100px; + width: 121px; + float: left; + clear: both; +} + +#errorContainer .loadingIcon { + position: relative; + background: url(../images/errorIcon.png) no-repeat; top: 50%; margin-top: -65px; height: 100px; @@ -107,7 +135,7 @@ div#toolbar .buttonContainer { border: 1px solid #BBB4D6; padding: 2px; margin: 1px; - padding-bottom:4px; + padding-bottom: 4px; } .buttonContainer legend { @@ -118,8 +146,8 @@ div#toolbar .buttonContainer { font-size: 11px; text-align: right; margin: 0px; - -moz-margin-start:7px; - -moz-margin-end:7px; + -moz-margin-start: 7px; + -moz-margin-end: 7px; } div#toolbar .button { @@ -128,7 +156,7 @@ div#toolbar .button { float: left; margin: 0px 2px 2px 2px; cursor: pointer; - text-align:center; + text-align: center; } div#toolbar .comboButton { @@ -150,22 +178,21 @@ div#toolbar .comboButton:hover { width: 34px; } -div#toolbar .button img{ +div#toolbar .button img { width: 30px; height: 30px; - border:0; + border: 0; } -div#toolbar .toolbarLabel{ - position:relative; - top:55%; - text-align:center; - width:34px; - height:36px; - font-size:10px; +div#toolbar .toolbarLabel { + position: relative; + top: 55%; + text-align: center; + width: 34px; + height: 36px; + font-size: 10px; } - .mapSeparator { width: 1px; height: 20px; @@ -175,151 +202,149 @@ div#toolbar .toolbarLabel{ } div#file, div#zoom, div#node, div#font, div#share { - position:absolute; - top:-6px; - left:3px; + position: absolute; + top: -6px; + left: 3px; } div#zoom { - left:229px; + left: 229px; } div#node { - left:311px; + left: 311px; } div#font { - left:619px; - /*left:581px;*/ + left: 619px; /*left:581px;*/ } div#share { - left:815px; - /*left:777px;*/ + left: 815px; /*left:777px;*/ } div#saveButton { - background: url( ../images/save.png) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/save.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } div#discardButton { - background: url( ../images/close.png) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/close.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } div#history { - background: url( ../images/history.png) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/history.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } div#print { - background: url( ../images/file_printer.png) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/file_printer.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } div#undoEdition { - background: url( ../images/file_undo_dis.png) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/file_undo_dis.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } div#redoEdition { - background: url( ../images/file_redo_dis.png) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/file_redo_dis.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } #export { - background: url( ../images/file_export.png) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/file_export.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } div#zoomIn { - background: url( ../images/zoom_in.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/zoom_in.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } #zoomOut { - background: url( ../images/zoom_out.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/zoom_out.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } #addTopic { - background: url( ../images/topic_add.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/topic_add.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } #deleteTopic { - background: url( ../images/topic_delete.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/topic_delete.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } div#topicColor { - background: url( ../images/topic_bgcolor.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/topic_bgcolor.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); z-index: 4; } div#topicIcon { - background: url( ../images/topic_icon.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/topic_icon.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); z-index: 4; } div#topicNote { - background: url( ../images/note.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/note.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); z-index: 4; } div#topicLink { - background: url( ../images/topic_link.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/topic_link.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); z-index: 4; } div#topicNote { - background-image: url( ../images/note.png ); - behavior: url( ../css/iepngfix.htc ); + background-image: url(../images/note.png); + behavior: url(../css/iepngfix.htc); z-index: 4; } #topicBorder { - background: url( ../images/topic_border.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/topic_border.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); width: 30px; } #fontFamily { - background: url( ../images/font_type.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/font_type.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } #topicShape { - background: url( ../images/topic_shape.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/topic_shape.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); width: 30px; } #fontBold { - background: url( ../images/font_bold.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/font_bold.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } #fontItalic { - background: url( ../images/font_italic.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/font_italic.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } div#fontColor { - background: url( ../images/font_color.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/font_color.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); z-index: 4; } #fontSize { float: left; - background: url( ../images/font_size.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/font_size.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } #font-size { @@ -336,19 +361,19 @@ div#fontColor { } #shareIt { - background: url( ../images/collab_share.png ) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/collab_share.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } #publishIt { - background: url( ../images/collab_publish.png) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/collab_publish.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } #tagIt { - background: url( ../images/collab_tag.png) no-repeat center top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/collab_tag.png) no-repeat center top; + behavior: url(../css/iepngfix.htc); } #colorPalette { @@ -414,7 +439,7 @@ div#actionsContainer { width: 190px; right: 0; margin: 10px; - float:left; + float: left; } #actionsContainer .button { @@ -447,17 +472,16 @@ div#actionsContainer { text-decoration: none; } - #actionsContainer .buttonStart { width: 6px; height: 25px; - background: url( ../images/btnStart2.png ) no-repeat left top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/btnStart2.png) no-repeat left top; + behavior: url(../css/iepngfix.htc); float: left; } #actionsContainer .buttonBody { - background: url( ../images/btnBody2.png ); + background: url(../images/btnBody2.png); float: left; height: 18px; padding: 0px 5px; @@ -469,8 +493,8 @@ div#actionsContainer { #actionsContainer .buttonEnd { width: 7px; height: 23px; - background: url( ../images/btnEnd2.png ) no-repeat right top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/btnEnd2.png) no-repeat right top; + behavior: url(../css/iepngfix.htc); float: left; } @@ -489,8 +513,8 @@ div#footerEditor { width: 80px; float: right; margin: 5px; - background: url( ../images/logo-vsmall.png ) no-repeat right top; - behavior: url( ../css/iepngfix.htc ); + background: url(../images/logo-vsmall.png) no-repeat right top; + behavior: url(../css/iepngfix.htc); } #footerEditor .msgLoggerContainer { @@ -508,14 +532,14 @@ div#msgStart { float: left; height: 36px; width: 16px; - background: url( ../images/footerStart.png ) no-repeat right top; + background: url(../images/footerStart.png) no-repeat right top; } div#msgEnd { float: left; height: 36px; width: 16px; - background: url( ../images/footerEnd.png ) no-repeat right top; + background: url(../images/footerEnd.png) no-repeat right top; } @@ -523,7 +547,7 @@ div#msgLogger { float: left; height: 36px; width: 500px; - background: url( ../images/footerBody.png ) repeat-x right top; + background: url(../images/footerBody.png) repeat-x right top; text-align: center; white-space: nowrap; padding: 5px; @@ -567,7 +591,7 @@ ol#toc li { } ol#toc a { - background: #fff url( ../images/tab4.png ); + background: #fff url(../images/tab4.png); color: #008; display: block; float: left; @@ -597,7 +621,7 @@ ol#toc li.current span { } ol#toc span { - background: #fff url( ../images/tab4.png ) 100% 0; + background: #fff url(../images/tab4.png) 100% 0; display: block; line-height: 2em; padding-right: 10px; @@ -612,7 +636,7 @@ ol#toc span { } #workspaceContainer { - background: url( ../images/grid.gif ) bottom left repeat !important; + background: url(../images/grid.gif) bottom left repeat !important; } @@ -653,8 +677,8 @@ span#lastSaved { opacity: 0.9; cursor: move; background-color: #69686F; - filter: alpha( opacity = 90 ); - color:#000c8f; + filter: alpha(opacity = 90); + color: #000c8f; } #tryEditorWarning a { @@ -681,7 +705,7 @@ div#helpContainer { padding: 20px; cursor: move; background-color: #69686F; - filter: alpha( opacity = 90 ); + filter: alpha(opacity = 90); } div#helpContent h1 { @@ -703,7 +727,7 @@ div.close { top: 7px; right: 10px; cursor: pointer; - background: url( ../images/close12_1.gif ) bottom left no-repeat !important; + background: url(../images/close12_1.gif) bottom left no-repeat !important; } div#helpContent li { @@ -716,5 +740,5 @@ div#helpContent li { div#small_error_icon { padding-left: 18px; min-height: 16px; - background: url( ../images/error_icon.png ) bottom left no-repeat !important; + background: url(../images/error_icon.png) bottom left no-repeat !important; } \ No newline at end of file diff --git a/trunk/wise-webapp/src/main/webapp/images/errorIcon.png b/trunk/wise-webapp/src/main/webapp/images/errorIcon.png new file mode 100644 index 00000000..bc396479 Binary files /dev/null and b/trunk/wise-webapp/src/main/webapp/images/errorIcon.png differ diff --git a/trunk/wise-webapp/src/main/webapp/js/editor.js b/trunk/wise-webapp/src/main/webapp/js/editor.js index a267f11d..745f12f0 100644 --- a/trunk/wise-webapp/src/main/webapp/js/editor.js +++ b/trunk/wise-webapp/src/main/webapp/js/editor.js @@ -1,22 +1,22 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You 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. -* -* $Id: file 64488 2006-03-10 17:32:09Z paulo $ -*/ - +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + * + * $Id: file 64488 2006-03-10 17:32:09Z paulo $ + */ + /*Extend mootools known keys*/ ExtendedKeys = { 'insert': 45, @@ -443,8 +443,14 @@ function afterWisemapLoading() shapeTypePanel(); fontSizePanel(); - // Disable loading dialog ... - setTimeout("loadingDialog.deactivate();", 500); + // If not problem has occured, I close the dialod ... + var closeDialog = function(){ + + if(!window.hasUnexpectedErrors) + { + waitDialog.deactivate(); + } + }.delay(500); } function buildIconChooser() { @@ -497,36 +503,7 @@ function buildMindmapDesigner() var monitor = new core.Monitor($('msgLoggerContainer'), $('msgLogger')); core.Monitor.setInstance(monitor); - // Initialize logger... - core.Logger.init(window.LoggerService); - var container = $('mindplot'); - var footer = $('footerEditor'); - if (core.UserAgent.isIframeWorkaroundRequired()) - { - var iframe = document.createElement('iframe'); - iframe.id = "mindplotIFrame"; - var top = container.offsetTop; - var bottom = footer.offsetTop; - iframe.setStyle('width', "100%"); - iframe.setStyle('height', bottom - top + "px"); - iframe.setStyle('overflow', "hidden"); - iframe.setStyle('border', "none"); - container.appendChild(iframe); - var mapContainer = "<div id='mindplot' style='background: url( ../images/grid.gif ) bottom left repeat !important;'></div><script>function styleMe() {" + - "var small_head = document.getElementsByTagName('head').item(0);" + - "var thestyle = document.createElement('link');" + - "thestyle.setAttribute('rel', 'stylesheet');thestyle.setAttribute('type', 'text/css');thestyle.setAttribute('href', '../css/bubble.css');small_head.appendChild(thestyle);}; styleMe();</script>"; - var doc = iframe.contentDocument; - if (doc == undefined || doc == null) - doc = iframe.contentWindow.document; - doc.open(); - doc.write(mapContainer); - doc.close(); - $(doc.body).setStyle('margin', '0px'); - container = doc.getElementById('mindplot'); - - } // Initialize Editor ... var persistantManager = new mindplot.PersistanceManager(window.MapEditorService); @@ -534,7 +511,7 @@ function buildMindmapDesigner() var screenWidth = window.getWidth(); var screenHeight = window.getHeight(); - // Positionate node ... h + // Positionate node ... // header - footer screenHeight = screenHeight - 90 - 61; diff --git a/trunk/wise-webapp/src/main/webapp/js/embedded.js b/trunk/wise-webapp/src/main/webapp/js/embedded.js index 1a517c6a..dcb9faa7 100644 --- a/trunk/wise-webapp/src/main/webapp/js/embedded.js +++ b/trunk/wise-webapp/src/main/webapp/js/embedded.js @@ -1,21 +1,21 @@ /* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You 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. -* -* $Id: file 64488 2006-03-10 17:32:09Z paulo $ -*/ + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + * + * $Id: file 64488 2006-03-10 17:32:09Z paulo $ + */ function afterCoreLoading() { @@ -34,7 +34,6 @@ function afterWisemapLoading() { buildMindmapDesigner(); - $('zoomIn').addEvent('click', function(event) { designer.zoomIn(); }); @@ -43,8 +42,16 @@ function afterWisemapLoading() designer.zoomOut(); }); - // Disable loading dialog ... - setTimeout("loadingDialog.deactivate();", 500); + + // If not problem has occured, I close the dialod ... + var closeDialog = function() { + + if (!window.hasUnexpectedErrors) + { + waitDialog.deactivate(); + } + }.delay(500); + } function setCurrentColorPicker(colorPicker) @@ -56,36 +63,7 @@ function setCurrentColorPicker(colorPicker) function buildMindmapDesigner() { - // Initialize logger... - core.Logger.init(window.LoggerService); - var container = $('mindplot'); - var footer = $('embFooter'); - if (core.UserAgent.isIframeWorkaroundRequired()) - { - var iframe = document.createElement('iframe'); - iframe.id = "mindplotIFrame"; - var top = container.offsetTop; - var bottom = footer.offsetTop; - iframe.setStyle('width', "100%"); - iframe.setStyle('height', bottom - top + "px"); - iframe.setStyle('overflow', "hidden"); - iframe.setStyle('border', "none"); - container.appendChild(iframe); - var mapContainer = "<div id='mindplot' style='background: url( ../images/grid.gif ) bottom left repeat !important;'></div><script>function styleMe() {" + - "var small_head = document.getElementsByTagName('head').item(0);" + - "var thestyle = document.createElement('link');" + - "thestyle.setAttribute('rel', 'stylesheet');thestyle.setAttribute('type', 'text/css');thestyle.setAttribute('href', '../css/bubble.css');small_head.appendChild(thestyle);}; styleMe();</script>"; - var doc = iframe.contentDocument; - if (doc == undefined || doc == null) - doc = iframe.contentWindow.document; - doc.open(); - doc.write(mapContainer); - doc.close(); - $(doc.body).setStyle('margin', '0px'); - container = doc.getElementById('mindplot'); - - } // Initialize Editor ... var persistantManager = new mindplot.PersistanceManager(window.MapEditorService); @@ -93,10 +71,6 @@ function buildMindmapDesigner() var screenWidth = window.getWidth(); var screenHeight = window.getHeight(); - // Positionate node ... - // header - footer - screenHeight = screenHeight; - // body margin ... editorProperties.width = screenWidth; editorProperties.height = screenHeight; diff --git a/trunk/wise-webapp/src/main/webapp/jsp/browserNotSupported.jsp b/trunk/wise-webapp/src/main/webapp/jsp/browserNotSupported.jsp index 7eebddeb..6746b5fd 100644 --- a/trunk/wise-webapp/src/main/webapp/jsp/browserNotSupported.jsp +++ b/trunk/wise-webapp/src/main/webapp/jsp/browserNotSupported.jsp @@ -9,8 +9,8 @@ <p>Although you can use our site with that browser, some features may not be functional.</p> WiseMapping is optimized for use with: <ul> - <li>Internet Explorer 6.0 or greater</li> - <li>Firefox 1.5 or greater</li> + <li>Internet Explorer 7.0 or greater</li> + <li>Firefox 3.0 or greater</li> <li>Opera 9.21 or greater</li> </ul> diff --git a/trunk/wise-webapp/src/main/webapp/jsp/embeddedView.jsp b/trunk/wise-webapp/src/main/webapp/jsp/embeddedView.jsp index e5cc0de6..751c0c37 100644 --- a/trunk/wise-webapp/src/main/webapp/jsp/embeddedView.jsp +++ b/trunk/wise-webapp/src/main/webapp/jsp/embeddedView.jsp @@ -23,10 +23,19 @@ </div> </div> <script type="text/javascript"> + //Dialog box display ... - var loadingDialog = new core.WaitDialog('waitDialog'); - addLightboxMarkup(); - loadingDialog.activate(true); + var waitDialog = new core.WaitDialog(); + waitDialog.activate(true, $("waitDialog")); + + $(window).addEvent("error", function(event) { + + // Show error dialog ... + waitDialog.changeContent($("errorDialog"), false); + return false; + }); + + var mapId = '${mindmap.id}'; var mapXml = '${mapXml}'; var editorProperties = {zoom:${zoom}}; diff --git a/trunk/wise-webapp/src/main/webapp/jsp/mindmapEditor.jsp b/trunk/wise-webapp/src/main/webapp/jsp/mindmapEditor.jsp index 36c47664..b331fed7 100644 --- a/trunk/wise-webapp/src/main/webapp/jsp/mindmapEditor.jsp +++ b/trunk/wise-webapp/src/main/webapp/jsp/mindmapEditor.jsp @@ -20,6 +20,9 @@ <link rel="stylesheet" type="text/css" href="../css/bubble.css"> <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/thirdparty.css"> + <script type="text/javascript" src="../dwr/engine.js"></script> + <script type="text/javascript" src="../dwr/interface/LoggerService.js"></script> + <script type='text/javascript' src='../js/wiseLibrary.js'></script> <script type='text/javascript' src='../js/core.js'></script> @@ -38,18 +41,35 @@ </form> <div id="waitDialog" style="display:none"> - <div id="loadingContainer"> + <div id="waitingContainer"> <div class="loadingIcon"></div> <div class="loadingText"> <spring:message code="EDITOR.LOADING"/> </div> </div> </div> + +<div id="errorDialog" style="display:none"> + <div id="errorContainer"> + <div class="loadingIcon"></div> + <div class="loadingText"> + <spring:message code="EDITOR.ERROR_LOADING"/> + </div> + </div> +</div> + <script type="text/javascript"> - //Dialog box display ... - var loadingDialog = new core.WaitDialog('waitDialog'); - addLightboxMarkup(); - loadingDialog.activate(true); + + var waitDialog = new core.WaitDialog(); + waitDialog.activate(true, $("waitDialog")); + $(window).addEvent("error", function(event) { + + // Show error dialog ... + waitDialog.changeContent($("errorDialog"), false); + return false; + }); + + var mapId = '${mindmap.id}'; var mapXml = '${mapXml}'; var editorProperties = ${mindmap.properties}; @@ -100,162 +120,163 @@ </div> <div id="toolbar"> -<div id="editTab" class="tabContent"> -<div id="file" class="buttonContainer" title="<spring:message code="FILE"/>"> - <fieldset> - <legend> - <spring:message code="FILE"/> - </legend> - <div id="saveButton" class="button" title="<spring:message code="SAVE"/>"> - <div class="toolbarLabel"><p><spring:message code="SAVE"/></p></div> - </div> - <div id="discardButton" class="button" title="<spring:message code="CLOSE"/>"> - <div class="toolbarLabel"><p><spring:message code="CLOSE"/></p></div> - </div> - <div id="undoEdition" class="button" title="<spring:message code="UNDO_EDITION"/>"> - <div class="toolbarLabel"><p><spring:message code="UNDO"/></p></div> - </div> - <div id="redoEdition" class="button" title="<spring:message code="REDO_EDITION"/>"> - <div class="toolbarLabel"><p><spring:message code="REDO"/></p></div> - </div> - <a id="printAnchor" href="javascript:printMap();" title="<spring:message code="PRINT"/>"> - <div id="print" class="button" title="<spring:message code="PRINT"/>"> - <div class="toolbarLabel"><p><spring:message code="PRINT"/></p></div> - </div> - </a> - <a id="exportAnchor" href="export.htm?mapId=${mindmap.id}" rel="moodalbox 600px 400px" - title="<spring:message code="EXPORT_DETAILS"/>"> - <div id="export" class="button" title="<spring:message code="EXPORT"/>"> - <div class="toolbarLabel"><p><spring:message code="EXPORT"/></p></div> - </div> - </a> - </fieldset> -</div> -<div id="zoom" class="buttonContainer" title="Zoom In"> - <fieldset> - <legend> - <spring:message code="ZOOM"/> - </legend> - <div id="zoomIn" class="button" title="<spring:message code="ZOOM_IN"/>"> - <div class="toolbarLabel"><p><spring:message code="IN"/></p></div> - </div> - <div id="zoomOut" class="button" title="<spring:message code="ZOOM_OUT"/>"> - <div class="toolbarLabel"><p><spring:message code="OUT"/></p></div> - </div> - </fieldset> -</div> -<div id="node" class="buttonContainer" title="Node Properties"> - <fieldset> - <legend> - <spring:message code="TOPIC"/> - </legend> - <div id="topicShape" class="button comboButton" title="<spring:message code="TOPIC_SHAPE"/>"> - <div class="toolbarLabel"><p><spring:message code="SHAPE"/></p></div> - </div> - <div id="addTopic" class="button" title="<spring:message code="TOPIC_ADD"/>"> - <div class="toolbarLabel"><p><spring:message code="ADD"/></p></div> - </div> - <div id="deleteTopic" class="button" title="<spring:message code="TOPIC_DELETE"/>"> - <div class="toolbarLabel"><p><spring:message code="DELETE"/></p></div> - </div> - <div id="topicBorder" class="button comboButton" title="<spring:message code="TOPIC_BORDER_COLOR"/>"> - <div class="toolbarLabel"><p><spring:message code="BORDER"/></p></div> - </div> - <div id="topicColor" class="button comboButton" title="<spring:message code="TOPIC_BACKGROUND_COLOR"/>"> - <div class="toolbarLabel"><p><spring:message code="COLOR"/></p></div> - </div> - <div id="topicIcon" class="button comboButton" title="<spring:message code="TOPIC_ICON"/>"> - <div class="toolbarLabel"><p><spring:message code="ICON"/></p></div> - </div> - <div id="topicNote" class="button comboButton" title="<spring:message code="TOPIC_NOTE"/>"> - <div class="toolbarLabel"><p><spring:message code="NOTE"/></p></div> - </div> - <div id="topicLink" class="button" title="<spring:message code="TOPIC_LINK"/>"> - <div class="toolbarLabel"><p><spring:message code="LINK"/></p></div> - </div> - </fieldset> -</div> -<div id="font" class="buttonContainer" title="Font Properties"> - <fieldset> - <legend> - <spring:message code="FONT"/> - </legend> - <div id="fontFamily" class="button comboButton" title="<spring:message code="FONT_TYPE"/>"> - <div class="toolbarLabel"><p><spring:message code="TYPE"/></p></div> - </div> - <div id="fontSize" class="button comboButton" title="<spring:message code="FONT_SIZE"/>"> - <div class="toolbarLabel"><p><spring:message code="SIZE"/></p></div> - </div> - <div id="fontBold" class="button" title="<spring:message code="FONT_BOLD"/>"> - <div class="toolbarLabel"><p><spring:message code="BOLD"/></p></div> - </div> - <div id="fontItalic" class="button" title="<spring:message code="FONT_ITALIC"/>"> - <div class="toolbarLabel"><p><spring:message code="ITALIC"/></p></div> - </div> - <div id="fontColor" class="button comboButton" title="<spring:message code="FONT_COLOR"/>"> - <div class="toolbarLabel"><p><spring:message code="COLOR"/></p></div> - </div> - </fieldset> -</div> -<div id="share" class="buttonContainer" title="Share Properties"> - <c:choose> - <c:when test="${editorTryMode==false}"> + <div id="editTab" class="tabContent"> + <div id="file" class="buttonContainer" title="<spring:message code="FILE"/>"> <fieldset> <legend> - <spring:message code="COLLABORATION"/> + <spring:message code="FILE"/> </legend> - <a id="tagAnchor" href="tags.htm?mapId=${mindmap.id}" rel="moodalbox 400px 200px wizard" - title="<spring:message code="TAGS_DETAILS"/>"> - <div id="tagIt" class="button" title="<spring:message code="TAG"/>"> - <div class="toolbarLabel"><p><spring:message code="TAG"/></p></div> + <div id="saveButton" class="button" title="<spring:message code="SAVE"/>"> + <div class="toolbarLabel"><p><spring:message code="SAVE"/></p></div> + </div> + <div id="discardButton" class="button" title="<spring:message code="CLOSE"/>"> + <div class="toolbarLabel"><p><spring:message code="CLOSE"/></p></div> + </div> + <div id="undoEdition" class="button" title="<spring:message code="UNDO_EDITION"/>"> + <div class="toolbarLabel"><p><spring:message code="UNDO"/></p></div> + </div> + <div id="redoEdition" class="button" title="<spring:message code="REDO_EDITION"/>"> + <div class="toolbarLabel"><p><spring:message code="REDO"/></p></div> + </div> + <a id="printAnchor" href="javascript:printMap();" title="<spring:message code="PRINT"/>"> + <div id="print" class="button" title="<spring:message code="PRINT"/>"> + <div class="toolbarLabel"><p><spring:message code="PRINT"/></p></div> </div> </a> - <c:choose> - <c:when test="${mindmap.owner==user}"> - <a id="shareAnchor" href="<c:out value="${shareMap}"/>&mapId=${mindmap.id}" - rel="moodalbox 780px 530px wizard" title="<spring:message code="SHARE_DETAILS"/>"> - <div id="shareIt" class="button" title="<spring:message code="COLLABORATION"/>"> - <div class="toolbarLabel"><p><spring:message code="SHARE"/></p></div> - </div> - </a> - <a id="publishAnchor" href="publish.htm?mapId=${mindmap.id}" rel="moodalbox 600px 400px wizard" - title="<spring:message code="PUBLISH_MSG"/>"> - <div id="publishIt" class="button" title="<spring:message code="PUBLISH"/>"> - <div class="toolbarLabel"><p><spring:message code="PUBLISH"/></p></div> - </div> - </a> - </c:when> - </c:choose> - <a id="historyAnchor" href="history.htm?action=list&mapId=${mindmap.id}" - rel="moodalbox 600px 400px wizard" title="<spring:message code="HISTORY_MSG"/>"> - <div id="history" class="button" title="<spring:message code="HISTORY_MSG"/>"> - <div class="toolbarLabel"><p><spring:message code="HISTORY"/></p></div> + <a id="exportAnchor" href="export.htm?mapId=${mindmap.id}" rel="moodalbox 600px 400px" + title="<spring:message code="EXPORT_DETAILS"/>"> + <div id="export" class="button" title="<spring:message code="EXPORT"/>"> + <div class="toolbarLabel"><p><spring:message code="EXPORT"/></p></div> </div> </a> </fieldset> - </c:when> - <c:otherwise> + </div> + <div id="zoom" class="buttonContainer" title="Zoom In"> <fieldset> <legend> - <spring:message code="COLLABORATION"/> + <spring:message code="ZOOM"/> </legend> - <div id="tagIt" class="button" title="<spring:message code="TAG"/>"> - <div class="toolbarLabel"><p><spring:message code="TAG"/></p></div> + <div id="zoomIn" class="button" title="<spring:message code="ZOOM_IN"/>"> + <div class="toolbarLabel"><p><spring:message code="IN"/></p></div> </div> - <div id="shareIt" class="button" title="<spring:message code="COLLABORATE"/>"> - <div class="toolbarLabel"><p><spring:message code="SHARE"/></p></div> - </div> - <div id="publishIt" class="button" title="<spring:message code="PUBLISH"/>"> - <div class="toolbarLabel"><p><spring:message code="PUBLISH"/></p></div> - </div> - <div id="history" class="button" title="<spring:message code="HISTORY_MSG"/>"> - <div class="toolbarLabel"><p><spring:message code="HISTORY"/></p></div> + <div id="zoomOut" class="button" title="<spring:message code="ZOOM_OUT"/>"> + <div class="toolbarLabel"><p><spring:message code="OUT"/></p></div> </div> </fieldset> - </c:otherwise> - </c:choose> -</div> -</div> + </div> + <div id="node" class="buttonContainer" title="Node Properties"> + <fieldset> + <legend> + <spring:message code="TOPIC"/> + </legend> + <div id="topicShape" class="button comboButton" title="<spring:message code="TOPIC_SHAPE"/>"> + <div class="toolbarLabel"><p><spring:message code="SHAPE"/></p></div> + </div> + <div id="addTopic" class="button" title="<spring:message code="TOPIC_ADD"/>"> + <div class="toolbarLabel"><p><spring:message code="ADD"/></p></div> + </div> + <div id="deleteTopic" class="button" title="<spring:message code="TOPIC_DELETE"/>"> + <div class="toolbarLabel"><p><spring:message code="DELETE"/></p></div> + </div> + <div id="topicBorder" class="button comboButton" title="<spring:message code="TOPIC_BORDER_COLOR"/>"> + <div class="toolbarLabel"><p><spring:message code="BORDER"/></p></div> + </div> + <div id="topicColor" class="button comboButton" title="<spring:message code="TOPIC_BACKGROUND_COLOR"/>"> + <div class="toolbarLabel"><p><spring:message code="COLOR"/></p></div> + </div> + <div id="topicIcon" class="button comboButton" title="<spring:message code="TOPIC_ICON"/>"> + <div class="toolbarLabel"><p><spring:message code="ICON"/></p></div> + </div> + <div id="topicNote" class="button comboButton" title="<spring:message code="TOPIC_NOTE"/>"> + <div class="toolbarLabel"><p><spring:message code="NOTE"/></p></div> + </div> + <div id="topicLink" class="button" title="<spring:message code="TOPIC_LINK"/>"> + <div class="toolbarLabel"><p><spring:message code="LINK"/></p></div> + </div> + </fieldset> + </div> + <div id="font" class="buttonContainer" title="Font Properties"> + <fieldset> + <legend> + <spring:message code="FONT"/> + </legend> + <div id="fontFamily" class="button comboButton" title="<spring:message code="FONT_TYPE"/>"> + <div class="toolbarLabel"><p><spring:message code="TYPE"/></p></div> + </div> + <div id="fontSize" class="button comboButton" title="<spring:message code="FONT_SIZE"/>"> + <div class="toolbarLabel"><p><spring:message code="SIZE"/></p></div> + </div> + <div id="fontBold" class="button" title="<spring:message code="FONT_BOLD"/>"> + <div class="toolbarLabel"><p><spring:message code="BOLD"/></p></div> + </div> + <div id="fontItalic" class="button" title="<spring:message code="FONT_ITALIC"/>"> + <div class="toolbarLabel"><p><spring:message code="ITALIC"/></p></div> + </div> + <div id="fontColor" class="button comboButton" title="<spring:message code="FONT_COLOR"/>"> + <div class="toolbarLabel"><p><spring:message code="COLOR"/></p></div> + </div> + </fieldset> + </div> + <div id="share" class="buttonContainer" title="Share Properties"> + <c:choose> + <c:when test="${editorTryMode==false}"> + <fieldset> + <legend> + <spring:message code="COLLABORATION"/> + </legend> + <a id="tagAnchor" href="tags.htm?mapId=${mindmap.id}" rel="moodalbox 400px 200px wizard" + title="<spring:message code="TAGS_DETAILS"/>"> + <div id="tagIt" class="button" title="<spring:message code="TAG"/>"> + <div class="toolbarLabel"><p><spring:message code="TAG"/></p></div> + </div> + </a> + <c:choose> + <c:when test="${mindmap.owner==user}"> + <a id="shareAnchor" href="<c:out value="${shareMap}"/>&mapId=${mindmap.id}" + rel="moodalbox 780px 530px wizard" title="<spring:message code="SHARE_DETAILS"/>"> + <div id="shareIt" class="button" title="<spring:message code="COLLABORATION"/>"> + <div class="toolbarLabel"><p><spring:message code="SHARE"/></p></div> + </div> + </a> + <a id="publishAnchor" href="publish.htm?mapId=${mindmap.id}" + rel="moodalbox 600px 400px wizard" + title="<spring:message code="PUBLISH_MSG"/>"> + <div id="publishIt" class="button" title="<spring:message code="PUBLISH"/>"> + <div class="toolbarLabel"><p><spring:message code="PUBLISH"/></p></div> + </div> + </a> + </c:when> + </c:choose> + <a id="historyAnchor" href="history.htm?action=list&mapId=${mindmap.id}" + rel="moodalbox 600px 400px wizard" title="<spring:message code="HISTORY_MSG"/>"> + <div id="history" class="button" title="<spring:message code="HISTORY_MSG"/>"> + <div class="toolbarLabel"><p><spring:message code="HISTORY"/></p></div> + </div> + </a> + </fieldset> + </c:when> + <c:otherwise> + <fieldset> + <legend> + <spring:message code="COLLABORATION"/> + </legend> + <div id="tagIt" class="button" title="<spring:message code="TAG"/>"> + <div class="toolbarLabel"><p><spring:message code="TAG"/></p></div> + </div> + <div id="shareIt" class="button" title="<spring:message code="COLLABORATE"/>"> + <div class="toolbarLabel"><p><spring:message code="SHARE"/></p></div> + </div> + <div id="publishIt" class="button" title="<spring:message code="PUBLISH"/>"> + <div class="toolbarLabel"><p><spring:message code="PUBLISH"/></p></div> + </div> + <div id="history" class="button" title="<spring:message code="HISTORY_MSG"/>"> + <div class="toolbarLabel"><p><spring:message code="HISTORY"/></p></div> + </div> + </fieldset> + </c:otherwise> + </c:choose> + </div> + </div> </div> <div id="mindplot"></div> @@ -272,14 +293,6 @@ <div id="msgEnd"></div> </div> </div> - <%if (userAgent != null && !(userAgent.getOs() == UserAgent.OS.MAC && userAgent.getProduct() == UserAgent.Product.FIREFOX && userAgent.getVersionMajor() < 3)) { %> - <div id="helpButton" - style="text-align:center; width:90px; height:20px; background-color:#f5f5f5; border: 1px solid #BBB6D6; cursor:pointer; padding-left:5px; margin-left:3px;"> - <div style="float:left; position:relative; top:50%; margin-top:-8px; margin-left:15px;"><img - src="../images/help.png"/></div> - <div style="float:left; position:relative; top:50%; margin-top:-8px; margin-left:4px;">Help</div> - </div> - <% } else {%> <div id="helpButtonFirstSteps" style="text-align:center; width:90px; height:20px; background-color:#f5f5f5; border: 1px solid #BBB6D6; cursor:pointer; padding-left:5px; margin-left:3px;float:left;"> <div style="float:left; position:relative; top:50%; margin-top:-8px; margin-left:5px;"><img @@ -292,7 +305,6 @@ src="../images/help.png"/></div> <div style="float:left; position:relative; top:50%; margin-top:-8px; margin-left:4px;">Shortcuts</div> </div> - <% } %> </div> <c:if test="${editorTryMode==true}"> <div id="tryEditorWarning" class="sb"> @@ -308,8 +320,6 @@ </div> <script type="text/javascript"> // Register close event ... - //$('tryEditorWarning').makeRounded({radius: 8,borderColor: '#69686F',backgroundColor: '#69686F'}); - var tryElem = $('tryEditorWarning'); tryElem.addClass('drag').makeDraggable(); $('tryClose').addEvent('click', function(event) { @@ -319,11 +329,9 @@ </script> </c:if> <div id="ffoxworkarround" style="display:none;"><input id="ffoxWorkarroundInput" type="text"></div> -<script type="text/javascript" src="../dwr/engine.js"></script> <c:if test="${editorTryMode==false}"> <script type="text/javascript" src="../dwr/interface/MapEditorService.js"></script> </c:if> -<script type="text/javascript" src="../dwr/interface/LoggerService.js"></script> <script type="text/javascript" src="../js/editor.js"></script> <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script>