[KSS-checkins] r49494 - in kukit/kukit.js/branch/finish-closures: doc kukit
gotcha at codespeak.net
gotcha at codespeak.net
Fri Dec 7 01:23:05 CET 2007
Author: gotcha
Date: Fri Dec 7 01:23:04 2007
New Revision: 49494
Modified:
kukit/kukit.js/branch/finish-closures/doc/HISTORY.txt
kukit/kukit.js/branch/finish-closures/kukit/commandprocessor.js
kukit/kukit.js/branch/finish-closures/kukit/dom.js
kukit/kukit.js/branch/finish-closures/kukit/errors.js
kukit/kukit.js/branch/finish-closures/kukit/forms.js
kukit/kukit.js/branch/finish-closures/kukit/kukit.js
kukit/kukit.js/branch/finish-closures/kukit/serveraction.js
kukit/kukit.js/branch/finish-closures/kukit/utils.js
Log:
trunk merged back
Modified: kukit/kukit.js/branch/finish-closures/doc/HISTORY.txt
==============================================================================
--- kukit/kukit.js/branch/finish-closures/doc/HISTORY.txt (original)
+++ kukit/kukit.js/branch/finish-closures/doc/HISTORY.txt Fri Dec 7 01:23:04 2007
@@ -6,6 +6,21 @@
- ...
+ - Fix multiple selection form fields
+ marshalling on Safari
+ (fixes #22 in kssproject)
+ and on IE.
+ [ree]
+
+ - Fix error fallback handling
+ [ree]
+
+ - Implement loglevels based on cookies
+ Add cookie handling code to kss.dom
+ Change logging on FireBug to avoid line info in debug
+ level messages
+ [ree]
+
- Implement event binding based on the ids fetched
dynamically from the dom, by value providers.
[ree]
Modified: kukit/kukit.js/branch/finish-closures/kukit/commandprocessor.js
==============================================================================
--- kukit/kukit.js/branch/finish-closures/kukit/commandprocessor.js (original)
+++ kukit/kukit.js/branch/finish-closures/kukit/commandprocessor.js Fri Dec 7 01:23:04 2007
@@ -41,8 +41,9 @@
// we make sure we execute none of them.
var lastcommand = this.commands[this.commands.length-1];
if (lastcommand.name == 'error') {
-;;; throw kukit.err.explicitError(lastcommand);
- throw new Error(kukit.E);
+ // We have to throw an explicitError always, since we want
+ // error fallbacks work both in production and development mode.
+ throw kukit.err.explicitError(lastcommand);
}
}
};
Modified: kukit/kukit.js/branch/finish-closures/kukit/dom.js
==============================================================================
--- kukit/kukit.js/branch/finish-closures/kukit/dom.js (original)
+++ kukit/kukit.js/branch/finish-closures/kukit/dom.js Fri Dec 7 01:23:04 2007
@@ -432,5 +432,30 @@
}
};
+
+/*
+ * Cookie handling code taken from:
+ * http://www.quirksmode.org/js/cookies.html
+ */
+
+dom.createCookie = function(name, value, days) {
+ if (days) {
+ var date = new Date();
+ date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
+ var expires = "; expires=" + date.toGMTString();
+ }
+ else var expires = "";
+ document.cookie = name + "=" + value + expires + "; path=/";
+};
+
+// we get this from kukit utils.js. We needed an early
+// definition there, because logging is needed from the
+// very beginning.
+dom.readCookie = kukit.readCookie;
+
+dom.eraseCookie = function(name) {
+ createCookie(name, "", -1);
+};
+
}(); /// MODULE END
Modified: kukit/kukit.js/branch/finish-closures/kukit/errors.js
==============================================================================
--- kukit/kukit.js/branch/finish-closures/kukit/errors.js (original)
+++ kukit/kukit.js/branch/finish-closures/kukit/errors.js Fri Dec 7 01:23:04 2007
@@ -55,67 +55,84 @@
*/
-;;; var ErrorAnnotation = function() {
-;;;
-;;; this.constructError = function(e, name, message, kw) {
-;;; if (typeof(kw) == "undefined") {
-;;; kw = {};
-;;; }
-;;; this.kw = kw;
-;;; this.message = name + ': ' + message;
-;;; var addMessage = true;
-;;; if (!e) {
-;;; e = new Error(message);
-;;; addMessage = false;
-;;; } else if (typeof(e) == "string") {
-;;; kukit.E = 'Do not raise string exceptions, as we cannot ';
-;;; kukit.E += 'annotate them properly. Use: throw new Error(msg);';
-;;; e = new Error(e);
-;;; }
-;;; this.previous_info = e.info;
-;;; e.name = name;
-;;; e.info = this;
-;;; if (addMessage) {
-;;; var fullMessage = message + ' [' + e.message + ']';
-;;; // for FF, and Safari:
-;;; e.message = fullMessage;
-;;; // for IE, message is ignored, description is used.
-;;; e.description = fullMessage;
+var ErrorAnnotation = function() {
+
+ this.constructError = function(e, name, message, kw) {
+;;; if (typeof(kw) == "undefined") {
+;;; kw = {};
+;;; }
+ this.kw = kw;
+;;; this.message = name + ': ' + message;
+;;; var addMessage = true;
+ if (!e) {
+;;; e = new Error(message);
+;;; addMessage = false;
+;;; } else if (typeof(e) == "string") {
+;;; kukit.E = 'Do not raise string exceptions, as we cannot ';
+;;; kukit.E += 'annotate them properly. Use: throw new Error(msg);';
+ e = new Error(kukit.E);
+ }
+;;; this.previous_info = e.info;
+ e.name = name;
+ e.info = this;
+;;; if (addMessage) {
+;;; var fullMessage = message + ' [' + e.message + ']';
+;;; // for FF, and Safari:
+;;; e.message = fullMessage;
+;;; // for IE, message is ignored, description is used.
+;;; e.description = fullMessage;
;;; }
-;;; return e;
-;;; };
+ return e;
+ };
;;;
-;;; this._logRecursive = function() {
-;;; kukit.logError(this.message);
-;;; if (this.previous_info) {
-;;; this.previous_info._logRecursive();
-;;; }
-;;; };
+;;; this._logRecursive = function() {
+;;; kukit.logError(this.message);
+;;; if (this.previous_info) {
+;;; this.previous_info._logRecursive();
+;;; }
+;;; };
;;;
-;;; this.log = function() {
-;;; // This is for debugging only, normal error handling
-;;; // does not use it.
-;;; kukit.logFatal('KSS error, stack information follows:');
-;;; this._logRecursive();
-;;; };
+;;; this.log = function() {
+;;; // This is for debugging only, normal error handling
+;;; // does not use it.
+;;; kukit.logFatal('KSS error, stack information follows:');
+;;; this._logRecursive();
;;; };
-;;; var setErrorInfo = function(e, name, message, kw) {
-;;; return new ErrorAnnotation().constructError(e, name, message, kw);
-;;; };
+};
+
+var setErrorInfo = function(e, name, message, kw) {
+ return new ErrorAnnotation().constructError(e, name, message, kw);
+};
/* Protects a function */
-;;; err.explicitError = function(errorcommand){
-;;; var kw = {'errorcommand':errorcommand};
-;;; var message = 'Explicit error';
-;;; return setErrorInfo(null, 'ExplicitError', message, kw);
-;;; };
-
-;;; err.responseParsingError = function(message){
-;;; return setErrorInfo(null, 'ResponseParsingError', message);
-;;; };
+/*
+ * Explicit error represents that the server side action failed and
+ * we need to handle this with an explicit error action defined from
+ * kss.
+ * There are three main cases when this can happen:
+ *
+ * 1. In case the server explicitely sent us an error (hence the
+ * name of this class) the parameter will contain the kss
+ * command from the payload.
+ *
+ * 2. If a payload response parsing error lead us here, then it
+ * will contain a string of the error message.
+ *
+ * 3. If a timeout of the response happened, the parameter will
+ * contain the text "timeout".
+ */
+err.explicitError = function(errorcommand){
+ var kw = {'errorcommand': errorcommand};
+;;; kukit.E = 'Explicit error';
+ return setErrorInfo(null, 'ExplicitError', kukit.E, kw);
+};
+
+err.responseParsingError = function(message){
+ return setErrorInfo(null, 'ResponseParsingError', message);
+};
;;; err.ruleMergeError = function(message){
;;; return setErrorInfo(null, 'RuleMergeError', message);
Modified: kukit/kukit.js/branch/finish-closures/kukit/forms.js
==============================================================================
--- kukit/kukit.js/branch/finish-closures/kukit/forms.js (original)
+++ kukit/kukit.js/branch/finish-closures/kukit/forms.js Fri Dec 7 01:23:04 2007
@@ -62,8 +62,11 @@
var elem = new _FormQueryElem(name, value);
this.l.push(elem);
}
+ // value.length is for detection of an Array.
+ // In addition we also check that value.pop is a function
else if (typeof(value) == 'object' &&
- value.constructor.toString().indexOf('Array') != -1) {
+ typeof(value.length) == 'number' &&
+ typeof(value.pop) == 'function') {
// Special marshalling of arrays
for (var i=0; i < value.length; i++) {
var elem = new _FormQueryElem(name, value[i]);
@@ -176,10 +179,9 @@
value="";
} else {
var option = element.options[element.selectedIndex];
- value = option.value;
- if (value == "") {
- value = option.text;
- }
+ // on FF and safari, option.value has the value
+ // on IE, option.text needs to be used
+ value = option.value || option.text;
}
// Now process selects with the multiple option set
} else {
@@ -187,7 +189,9 @@
for(i=0; i<element.options.length; i++) {
var option = element.options[i];
if(option.selected) {
- value.push(option.value);
+ // on FF and safari, option.value has the value
+ // on IE, option.text needs to be used
+ value.push(option.value || option.text);
}
}
}
Modified: kukit/kukit.js/branch/finish-closures/kukit/kukit.js
==============================================================================
--- kukit/kukit.js/branch/finish-closures/kukit/kukit.js (original)
+++ kukit/kukit.js/branch/finish-closures/kukit/kukit.js Fri Dec 7 01:23:04 2007
@@ -96,7 +96,8 @@
if((nodes[i].type == 'text/css') || (nodes[i].type == 'text/kss')) {
res_type = 'kss';
;;; } else {
-;;; throw kukit.err.explicitError("rel type is not text/css or text/kss");
+;;; // Just show this, and go on with the processing.
+;;; kukit.logError("rel type is not text/css or text/kss");
}
var newRuleLink = new _RuleSheetLink(nodes[i].href, res_type);
results[results.length] = newRuleLink;
Modified: kukit/kukit.js/branch/finish-closures/kukit/serveraction.js
==============================================================================
--- kukit/kukit.js/branch/finish-closures/kukit/serveraction.js (original)
+++ kukit/kukit.js/branch/finish-closures/kukit/serveraction.js Fri Dec 7 01:23:04 2007
@@ -111,20 +111,24 @@
if (success) {
// catch the errors otherwise won't get logged.
// In FF they seem to get swallowed silently.
-;;; try {
+ // We need these both in production and development mode,
+ // since the erorr fallbacks are activated from processError.
+ try {
// process the results
this.processResult(domDoc);
-;;; } catch(e) {
+ } catch(e) {
;;; if (e.name == 'RuleMergeError' || e.name == 'EventBindError') {
;;; throw kukit.err.eventSetupError(e);
-;;; } else if (e.name == 'ResponseParsingError') {
-;;; this.processError('Response parsing error: ' + e);
-;;; } else if (e.name == 'ExplicitError') {
-;;; this.processError(e.errorcommand);
-;;; } else {
-;;; throw e;
-;;; }
-;;; }
+;;; }
+ if (e.name == 'ResponseParsingError') {
+;;; kukit.E = 'Response parsing error: ' + e;
+ this.processError(kukit.E);
+ } else if (e.name == 'ExplicitError') {
+ this.processError(e.info.kw.errorcommand);
+ } else {
+ throw e;
+ }
+ }
}
}
};
@@ -151,9 +155,8 @@
try {
dom = (new DOMParser()).parseFromString(payload, "text/xml");
} catch(e) {
-;;; var msg = 'Error parsing X-KSSCOMMANDS header.';
-;;; throw kukit.err.responseParsingError(msg);
- throw new Error(kukit.E);
+;;; kukit.E = 'Error parsing X-KSSCOMMANDS header.';
+ throw kukit.err.responseParsingError(kukit.E);
}
commandstags = kukit.dom.getNsTags(dom, 'commands');
if (commandstags.length != 1) {
@@ -166,21 +169,19 @@
// and log it as reported from the dom
// Opera <= 8.5 does not have the parseError attribute,
// so check for it first
- dom = domDoc.responseXML;
-;;; var msg = 'Unknown server error (invalid KSS response, no error';
-;;; msg += ' info received)';
+;;; dom = domDoc.responseXML;
+;;; kukit.E = 'Unknown server error (invalid KSS response, no error';
+;;; kukit.E += ' info received)';
;;; if (dom && dom.parseError && (dom.parseError != 0)) {
-;;; msg += ' : ' + Sarissa.getParseErrorText(dom);
+;;; kukit.E += ' : ' + Sarissa.getParseErrorText(dom);
;;; }
-;;; throw kukit.err.responseParsingError(msg);
- throw new Error(kukit.E);
+ throw kukit.err.responseParsingError(kukit.E);
}
}
if (dom == null) {
// this should not happen
-;;; var msg = 'Neither xml nor html payload.';
-;;; throw kukit.err.responseParsingError(msg);
- throw new Error(kukit.E);
+;;; kukit.E = 'Neither xml nor html payload.';
+ throw kukit.err.responseParsingError(msg);
}
// find the commands (atm we don't limit ourselves inside the commandstag)
var commands = kukit.dom.getNsTags(dom, 'command');
@@ -207,6 +208,9 @@
;;; reason = ', client_reason="' + errorcommand + '" ';
;;; } else if (typeof(errorcommand) != 'undefined') {
;;; // a real error command, sent by the server
+;;; // as kukit payload.
+;;; // this way the server sends whatever message he wants as a parameter
+;;; // to the error command.
;;; reason = ', server_reason="' + errorcommand.parms.message + '" ';
;;; }
if (error_action) {
@@ -221,6 +225,14 @@
;;; kukit.E = 'Request failed at url ' + this.oper.queueItem.url;
;;; kukit.E += ', rid=' + this.oper.queueItem.rid + reason;
;;; kukit.logError(kukit.E);
+;;; return;
+ // in case of no logging, we would like to throw an error.
+ // This means user will see something went wrong.
+ // XXX But: throwing an error on Firefox
+ // _seems to be ineffective__
+ // and throwing the error from IE
+ // _throws an ugly window, "Uncaught exception"
+ // TODO figure out something?
}
};
Modified: kukit/kukit.js/branch/finish-closures/kukit/utils.js
==============================================================================
--- kukit/kukit.js/branch/finish-closures/kukit/utils.js (original)
+++ kukit/kukit.js/branch/finish-closures/kukit/utils.js Fri Dec 7 01:23:04 2007
@@ -66,6 +66,94 @@
;;; kukit.logWarning(msg);
;;; };
+/*
+ * Cookie handling code taken from:
+ * http://www.quirksmode.org/js/cookies.html
+ * Cookie handling is in dom.js, but this method
+ * is needed right here for log handling.
+ */
+
+kukit.readCookie = function(name) {
+ var nameEQ = name + "=";
+ var ca = document.cookie.split(';');
+ for(var i=0; i < ca.length; i++) {
+ var c = ca[i];
+ while (c.charAt(0) == ' ') c = c.substring(1, c.length);
+ if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
+ }
+ return null;
+}
+
+// a null function that is used for logging
+kukit._null = function() {};
+
+kukit._COOKIE_LOGLEVEL = '__kss_loglevel';
+
+// an empty logger
+kukit._logger = new function() {
+
+ this.updateLogLevel = function() {
+;;; // set default level
+;;; this.loglevel = 0;
+;;; // read the cookie
+;;; var cookie = kukit.readCookie(kukit._COOKIE_LOGLEVEL);
+;;; if (cookie) {
+;;; // decode it to a numeric level
+;;; cookie = cookie.toLowerCase();
+;;; // Cookies are quoted in Zope, for some reason (???)
+;;; // ie we get '"VALUE"' here. Let's compensate this.
+;;; if (cookie.substr(0, 1) == '"') {
+;;; cookie = cookie.substr(1, cookie.length - 2);
+;;; }
+;;; if (cookie == 'debug') this.loglevel = 0;
+;;; if (cookie == 'info') this.loglevel = 1;
+;;; if (cookie == 'warning') this.loglevel = 2;
+;;; if (cookie == 'error') this.loglevel = 3;
+;;; };
+ // Call the function that sets up the handlers
+ this._setupHandlers();
+ // Wrap the just set up handlers, to include wrapping
+;;; this.logDebug = this._logFilter(this.logDebug, 0);
+;;; this.log = this._logFilter(this.log, 1);
+;;; this.logWarning = this._logFilter(this.logWarning, 2);
+;;; this.logError = this._logFilter(this.logError, 3);
+;;; this.logFatal = this._logFilter(this.logFatal, 3);
+ };
+
+ // Log filter, for use from the handlers.
+;;; this._logFilter = function(f, currentlevel) {
+;;; return (currentlevel >= this.loglevel) ? f : kukit._null;
+;;; };
+
+ // This sets up the handlers and allows to set them
+ // up again with a different cookie setting.
+ // Will be overwritten by different loggers.
+ this._setupHandlers = function() {
+ this.logDebug = kukit._null;
+ this.log = kukit._null;
+ this.logWarning = kukit._null;
+ this.logError = kukit._null;
+ this.logFatal = kukit._null;
+ };
+}();
+
+// Stub functions that can be used for logging
+kukit.logDebug = function(message) {kukit._logger.logDebug(message);};
+kukit.log = function(message) {kukit._logger.log(message);};
+kukit.logWarning = function(message) {kukit._logger.logWarning(message);};
+kukit.logError = function(message) {kukit._logger.logError(message);};
+kukit.logFatal = function(message) {kukit._logger.logFatal(message);};
+
+// Function to change the log level from javascript
+// level must be one of "DEBUG", "INFO", "WARNING", "ERROR".
+// (Small caps are tolerated as well)
+kukit.setLogLevel = function(level) {
+;;; // Store it in the cookie so that it persists through requests.
+;;; kukit.dom.createCookie(kukit._COOKIE_LOGLEVEL, level);
+;;; // re-establish the log handlers, based on this cookie setting
+;;; kukit._logger.updateLogLevel();
+}
+
// We want a way of knowing if Firebug is available :
// it is very convenient to log a node in Firebug;
// you get a clickable result that brings you to Firebug inspector.
@@ -73,74 +161,77 @@
// if (kukit.hasFirebug) {
// kukit.log(node);
// }
-kukit.hasFirebug = false;
;;; // check whether the logging stuff of Firebug is available
;;; kukit.hasFirebug = function() {
-;;; var result = typeof kukit.log == 'undefined';
-;;; result = result && typeof console != 'undefined';
+;;; var result = typeof console != 'undefined';
;;; result = result && typeof console.log != 'undefined';
;;; result = result && typeof console.debug != 'undefined';
;;; result = result && typeof console.error != 'undefined';
;;; result = result && typeof console.warn != 'undefined';
;;; return result;
-;;; }
-;;; if (kukit.hasFirebug()) {
-;;; kukit.log = console.log;
-;;; kukit.logDebug = console.debug;
-;;; kukit.logFatal = console.error;
-;;; kukit.logError = console.error;
-;;; kukit.logWarning = console.warn;
-;;; kukit.hasFirebug = true;
+;;; }();
+
+;;; // Set up logging for FireBug
+;;; if (kukit.hasFirebug) {
+;;; kukit._logger._setupHandlers = function() {
+;;; // for debug level we also log as 'info', because we do
+;;; // not want FireBug to display line information.
+;;; this.logDebug = console.log;
+;;; this.log = console.log;
+;;; this.logWarning = console.warn;
+;;; this.logError = console.error;
+;;; this.logFatal = console.error;
+;;; }
;;; }
;;; // check whether the logging stuff of MochiKit is available
;;; kukit.hasMochiKit = function() {
-;;; var result = typeof kukit.log == 'undefined';
-;;; result = result && typeof MochiKit != 'undefined';
+;;; var result = typeof MochiKit != 'undefined';
;;; result = result && typeof MochiKit.Logging != 'undefined';
;;; result = result && typeof MochiKit.Logging.log != 'undefined';
;;; return result;
-;;; }
-;;; if (kukit.hasMochiKit()) {
-;;; kukit.log = MochiKit.Logging.log;
-;;; kukit.logError = MochiKit.Logging.logError;
-;;; kukit.logDebug = MochiKit.Logging.logDebug;
-;;; kukit.logFatal = MochiKit.Logging.logFatal;
-;;; kukit.logWarning = MochiKit.Logging.logWarning;
-;;; // make convenience url
-;;; // javascript:kukit.showLog();
-;;; // instead of the need to say
-;;; // javascript:void(createLoggingPane(true));
-;;; kukit.showLog = function() {
-;;; createLoggingPane(true);
-;;; };
+;;; }();
+
+;;; // Set up logging for MochiKit
+;;; if (! kukit.hasFirebug && kukit.hasMochiKit) {
+;;; kukit._logger._setupHandlers = function() {
+;;; this.logDebug = MochiKit.Logging.logDebug;
+;;; this.log = MochiKit.Logging.log;
+;;; this.logWarning = MochiKit.Logging.logWarning;
+;;; this.logError = MochiKit.Logging.logError;
+;;; this.logFatal = MochiKit.Logging.logFatal;
+;;; }
+;;; // make convenience url
+;;; // javascript:kukit.showLog();
+;;; // instead of the need to say
+;;; // javascript:void(createLoggingPane(true));
+;;; kukit.showLog = function() {
+;;; createLoggingPane(true);
+;;; };
;;; }
;;; // check whether the logging stuff of Safari is available
;;; kukit.hasSafari = function() {
-;;; var result = typeof kukit.log == 'undefined';
-;;; result = result && typeof console != 'undefined';
+;;; var result = typeof console != 'undefined';
;;; result = result && typeof console.log != 'undefined';
;;; return result;
-;;; }
-;;; if (kukit.hasSafari()) {
-;;; kukit.log = function(str) { console.log('INFO: '+str); };
-;;; kukit.logError = function(str) { console.log('ERROR: '+str); };
-;;; kukit.logDebug = function(str) { console.log('DEBUG: '+str); };
-;;; kukit.logFatal = function(str) { console.log('FATAL: '+str); };
-;;; kukit.logWarning = function(str) { console.log('WARNING: '+str); };
-;;; }
+;;; }();
-/* no logging solution available */
-;;; if (typeof kukit.log == 'undefined') {
- kukit.log = function(str){};
- kukit.logError = kukit.log;
- kukit.logDebug = kukit.log;
- kukit.logFatal = kukit.log;
- kukit.logWarning = kukit.log;
+;;; // Set up logging for Safari
+;;; if (! kukit.hasFirebug && ! kukit.hasMochiKit && kukit.hasSafari) {
+;;; kukit._logger._setupHandlers = function() {
+;;; this.logDebug = function(str) { console.log('DEBUG: '+str); };
+;;; this.log = function(str) { console.log('INFO: '+str); };
+;;; this.logWarning = function(str) { console.log('WARNING: '+str); };
+;;; this.logError = function(str) { console.log('ERROR: '+str); };
+;;; this.logFatal = function(str) { console.log('FATAL: '+str); };
+;;; }
;;; }
+// Initialize the logger with the solution we've just detected
+kukit._logger.updateLogLevel();
+
// log a startup message
;;; kukit.log('Loading KSS engine.');
More information about the Kukit-checkins
mailing list