/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */ /*global _export: true */ /** * Create a class, manage inheritance, static methods, * protected attributes and can hide methods or/and secure methods * * @param {Class} Class Classes to inherit from (0..n). The last class * parameter will inherit from the previous one, and so on * @param {Object} option Class option (0..n) * @param {Boolean} [option.secure_methods=false] Make methods not configurable * and not writable * @param {Boolean} [option.hide_methods=false] Make methods not enumerable * @param {Boolean} [option.secure_static_methods=true] Make static methods not * configurable and not * writable * @param {Boolean} [option.hide_static_methods=false] Make static methods not * enumerable * @param {Object} [option.static_methods={}] Object of static methods * @param {Function} constructor The new class constructor * @return {Class} The new class */ function newClass() { var j, k, constructors = [], option, new_class; for (j = 0; j < arguments.length; j += 1) { if (typeof arguments[j] === "function") { constructors.push(arguments[j]); } else if (typeof arguments[j] === "object") { option = option || {}; for (k in arguments[j]) { if (arguments[j].hasOwnProperty(k)) { option[k] = arguments[j][k]; } } } } function postObjectCreation(that) { // modify the object according to 'option' var key; if (option) { for (key in that) { if (that.hasOwnProperty(key)) { if (typeof that[key] === "function") { Object.defineProperty(that, key, { configurable: option.secure_methods ? false : true, enumerable: option.hide_methods ? false : true, writable: option.secure_methods ? false : true, value: that[key] }); } } } } } function postClassCreation(that) { // modify the object according to 'option' var key; if (option) { for (key in that) { if (that.hasOwnProperty(key)) { if (typeof that[key] === "function") { Object.defineProperty(that, key, { configurable: option.secure_static_methods === false ? true : false, enumerable: option.hide_static_methods ? false : true, writable: option.secure_static_methods === false ? true : false, value: that[key] }); } } } } } new_class = function (spec, my) { var i; spec = spec || {}; my = my || {}; // don't use forEach ! for (i = 0; i < constructors.length; i += 1) { constructors[i].apply(this, [spec, my]); } postObjectCreation(this); return this; }; option = option || {}; option.static_methods = option.static_methods || {}; for (j in option.static_methods) { if (option.static_methods.hasOwnProperty(j)) { new_class[j] = option.static_methods[j]; } } postClassCreation(new_class); return new_class; } /** * Escapes regexp special chars from a string. * * @param {String} string The string to escape * @return {String} The escaped string */ function stringEscapeRegexpCharacters(string) { if (typeof string === "string") { return string.replace(/([\\\.\$\[\]\(\)\{\}\^\?\*\+\-])/g, "\\$1"); } } /** * Convert a search text to a regexp. * * @param {String} string The string to convert * @param {String} [wildcard_character=undefined] The wildcard chararter * @return {RegExp} The search text regexp */ function convertSearchTextToRegExp(string, wildcard_character) { return new RegExp("^" + stringEscapeRegexpCharacters(string).replace( stringEscapeRegexpCharacters(wildcard_character), '.*' ) + "$"); } // XXX function sortFunction(key, way) { if (way === 'descending') { return function (a, b) { return a[key] < b[key] ? 1 : a[key] > b[key] ? -1 : 0; }; } return function (a, b) { return a[key] > b[key] ? 1 : a[key] < b[key] ? -1 : 0; }; }