# HG changeset patch # User Mario Ferraro # Date 1256497778 0 # Node ID 14194c0b3cd1cb0c963dc3623ce2398e08856f6a # Parent 34eeacafc5dc44ecc630852754ebe23cc632da2b General JavaScript utilities for melange. This script is going to be the core of Melange JS. It provides a melange namespace and general utilies for logging, loading of google api, common errors, base class for templates that reads context from a script tag attribute. It also reads general options from its script tag. diff -r 34eeacafc5dc -r 14194c0b3cd1 app/soc/content/js/melange-091015.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/soc/content/js/melange-091015.js Sun Oct 25 19:09:38 2009 +0000 @@ -0,0 +1,312 @@ +/* Copyright 2009 the Melange authors. + * + * 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. + */ +/** + * @author Mario Ferraro + */ + +(function () { + /** @lends melange */ + + /** General melange package. + * @name melange + * @namespace melange + */ + var melange = window.melange = function () { + return new melange(); + }; + + if (window.jQuery === undefined) { + throw new Error("jQuery package must be loaded exposing jQuery namespace"); + } + + if (window.JSON === undefined) { + throw new Error("json2 package must be loaded exposing JSON namespace"); + } + + /** Shortcut to current package. + * @private + */ + var $m = melange; + + /** Contains general configuration for melange package. + * @variable + * @public + * @name melange.config + */ + $m.config = {}; + + (function () { + var configuration = + jQuery("script[melangeConfig][src$='melange.js']").attr("melangeConfig"); + if (configuration) { + var configuration_object = JSON.parse("{ " + configuration + " }"); + jQuery.extend($m.config, configuration_object); + } + }()); + + /** Shortcut to clone objects using jQuery. + * @function + * @public + * @name melange.clone + * @param {Object} object the object to clone + * @returns {Object} a new, cloned object + */ + $m.clone = function (object) { + // clone object, see + // http://stackoverflow.com/questions/122102/ + // what-is-the-most-efficent-way-to-clone-a-javascript-object + return jQuery.extend(true, {}, object); + }; + + /** Set melange general options. + * @function + * @public + * @name melange.setOptions + * @param {Object} options Options to set/unset + */ + $m.setOptions = function (options) { + switch (options.debug) { + case true: + $m.logging.setDebug(); + break; + case false: + $m.logging.unsetDebug(); + break; + default: + $m.logging.setDebug(); + } + if (options.debugLevel) { + $m.logging.setDebugLevel(options.debugLevel); + } + }; + + /** Facility to load google API. + * @function + * @public + * @name melange.loadGoogleApi + * @param {String} modulename Google Ajax module to load + * @param {String|Number} moduleversion Google Ajax module version to load + * @param {Object} settings Google Ajax settings for the module + * @param {Function} callback to be called as soon as module is loaded + */ + $m.loadGoogleApi = function (modulename, moduleversion, settings, callback) { + + if (!modulename || !moduleversion) { + throw new TypeError("modulename must be defined"); + } + + /** Options to be sent to google.load constructor + * @private + * @name melange.loadGoogleApi.options + */ + var options = { + name : modulename, + version : moduleversion, + settings : settings + }; + jQuery.extend(options.settings, {callback: callback}); + google.load(options.name, options.version, options.settings); + }; + + (function () { + /** @lends melange.error */ + + /** Package that handles melange errors + * @namespace melange.error + */ + melange.error = window.melange.error = function () { + return new melange.error(); + }; + + /** Shortcut to current package. + * @property + * @private + */ + var $m = melange.error; + + /** List of default custom error types to be created. + * @property + * @private + */ + var error_types = [ + "DependencyNotSatisfied", + "notImplementedByChildClass" + ]; + + /** Create errors + * @function + * @public + * @name melange.error.createErrors + * @param {String[]} error_types Array of strings with errors names + */ + $m.createErrors = function (error_types) { + jQuery.each(error_types, function () { + melange.error[this] = Error; + }); + }; + + $m.createErrors(error_types); + }()); + + (function () { + /** @lends melange.logging */ + + /** Package that contains all log related functions. + * @name melange.logging + * @namespace melange.logging + */ + melange.logging = window.melange.logging = function () { + return new melange.logging(); + }; + + /** Shortcut to current package. + * @property + * @private + */ + var $m = melange.logging; + /** @private */ + var debug = false; + /** @private */ + var current_debug_level = 5; + + /** Set debug logging on. + * @function + * @public + * @name melange.logging.setDebug + */ + $m.setDebug = function () { + debug = true; + }; + + /** Set debug logging off. + * @function + * @public + * @name melange.logging.unsetDebug + */ + $m.unsetDebug = function () { + debug = false; + }; + + /** Check if debug is active. + * @function + * @public + * @name melange.logging.isDebug + * @returns {boolean} true if debug is on, false otherwise + */ + $m.isDebug = function () { + return debug ? true : false; + }; + + /** Set the current debug level. + * @function + * @public + * @name melange.logging.setDebugLevel + * @param level The log level to set + * @throws {TypeError} if the parameter given is not a number + */ + $m.setDebugLevel = function (level) { + if (isNaN(level)) { + throw new melange.error.TypeError( + "melange.logging.setDebugLevel: parameter must be a number" + ); + } + if (level <= 0) { + level = 1; + } + if (level >= 6) { + level = 5; + } + current_debug_level = level; + }; + + /** Get the current debug level. + * @function + * @public + * @name melange.logging.getDebugLevel + * @returns {Number} The current debug level + */ + $m.getDebugLevel = function () { + return current_debug_level; + }; + + /** A decorator for logging. + * @function + * @public + * @name melange.logging.debugDecorator + * @param {Object} object_to_decorate The Function/Object to decorate + * @returns {Object} Same object,decorated with log(level,message) func + */ + $m.debugDecorator = function (object_to_decorate) { + /** Function to handle output of logs. + * @function + * @name melange.logging.debugDecorator.log + * @param level The log level + * @param message The string + */ + object_to_decorate.log = function (level, message) { + if (melange.logging.isDebug() && current_debug_level >= level) { + console.debug(message); + } + }; + return object_to_decorate; + }; + }()); + + (function () { + /** @lends melange.templates */ + + /** Package that provides basic templates functions + * @name melange.templates + * @namespace melange.templates + */ + melange.templates = window.melange.templates = function () { + return new melange.templates(); + }; + + /** Shortcut to current package + * @private + */ + var $m = melange.logging.debugDecorator(melange.templates); + + melange.error.createErrors([ + ]); + + /** Parent prototype for all templates + * @class + * @constructor + * @name melange.templates._baseTemplate + * @public + */ + $m._baseTemplate = function () { + this.context = {}; + var configuration = jQuery("script[melangeContext]")[0]; + if (configuration !== undefined) { + configuration = jQuery(configuration).attr("melangeContext"); + if (configuration) { + /* FIXME: json2 doesn't parse the object if they have k:"v" instead + of "k":"v", but this is not what gviz outputs, we need to change + gviz source or hack json2 source or use another method. eval() + must be not used anyway + */ + /*jslint evil: true,undef: false */ + eval("var configuration_object = " + configuration); + jQuery.extend(this.context, configuration_object); + /*jslint evil: false,undef: true */ + } + } + }; + }()); +}()); +window.melange = window.melange.logging.debugDecorator(window.melange);