Comparing version 0.0.0 to 0.1.0
{ | ||
"name": "ClazzJS", | ||
"version": "0.0.0", | ||
"version": "0.1.0", | ||
"ignore": [ | ||
@@ -5,0 +5,0 @@ "node_modules", |
;(function(global, Meta, undefined) { | ||
var Meta = function(options) { | ||
this._options = {}; | ||
var Clazz = function(name, parent, meta) { | ||
if (typeof options !== 'undefined') { | ||
this.setOptions(options); | ||
// If called as constructor - creates new clazz object. | ||
if (this instanceof Clazz) { | ||
var clazz = Manager.get(name); | ||
return clazz.create.apply(clazz, Array.prototype.slice.call(arguments, 1)); | ||
} | ||
else { | ||
if (arguments.length == 1) { | ||
if (typeof name === 'object') { | ||
meta = name; | ||
name = null; | ||
} | ||
// If only name is specified - returns entity clazz. | ||
return name ? Manager.get(name) : Factory.create(meta); | ||
} | ||
// If name and some meta data are specified - save meta. | ||
// Class will be created on demand (lazy load). | ||
else { | ||
Manager.setMeta(name, parent, meta); | ||
} | ||
} | ||
} | ||
var Base = function() { | ||
if (typeof this.init === 'function') { | ||
this.init.apply(this, Array.prototype.slice.call(arguments)); | ||
} | ||
} | ||
Meta.prototype = { | ||
Base.NAME = '__BASE_CLAZZ__'; | ||
Base.parent = null; | ||
process: function(object, meta) { | ||
var metaOption, option; | ||
Base.create = function() { | ||
// Dirty hack!!!! But I don't know better solution:( | ||
var a = arguments; | ||
return new this(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]); | ||
} | ||
for (option in meta) { | ||
Base.prototype = { | ||
parent: null, | ||
clazz: Base | ||
} | ||
var Factory = { | ||
metaOption = this.hasOption(option) | ||
? (this.getOption(option)) | ||
: (this.hasOption('__DEFAULT__') ? this.getOption('__DEFAULT__') : null) | ||
CLASS_NAME: 'Clazz{uid}', | ||
if (metaOption) { | ||
metaOption.process.apply(metaOption, [object, meta[option]].concat(Array.prototype.slice.call(arguments,2)) ); | ||
_clazzUID: 0, | ||
create: function(name, parent, meta) { | ||
if (typeof meta === 'undefined') { | ||
meta = parent; | ||
parent = null; | ||
} | ||
if (typeof meta === 'undefined') { | ||
meta = name; | ||
name = null; | ||
} | ||
if (typeof parent === 'string') { | ||
parent = Manager.get(parent); | ||
} | ||
return this.processMeta(this.createClazz(name, parent), meta); | ||
}, | ||
createClazz: function(name, parent) { | ||
if (!parent) { | ||
parent = Base; | ||
} | ||
var clazz = function () { | ||
parent.apply(this, Array.prototype.slice.call(arguments)); | ||
} | ||
// Copy all parent methods and initialize properties | ||
for (var property in parent) { | ||
if (typeof parent[property] === 'function') { | ||
clazz[property] = parent[property]; | ||
} | ||
else if (property[0] === '_') { | ||
clazz[property] = undefined; | ||
} | ||
} | ||
clazz.NAME = name || this.generateName(); | ||
clazz.parent = parent; | ||
clazz.prototype = Object.create(parent.prototype); | ||
clazz.prototype.clazz = clazz; | ||
clazz.prototype.parent = parent.prototype; | ||
return clazz; | ||
}, | ||
getOption: function(name) { | ||
if (!(name in this._options)) { | ||
throw new Error('Meta option "' + name + '" does not exists!'); | ||
generateName: function() { | ||
return this.CLASS_NAME.replace('{uid}', ++this._clazzUID); | ||
}, | ||
processMeta: function(clazz, meta) { | ||
if (typeof meta === 'function') { | ||
meta = meta.apply(clazz) | ||
} | ||
return this._options[name]; | ||
if (meta) { | ||
Clazz.Meta.Clazz.process(clazz, meta); | ||
Clazz.Meta.Object.process(clazz.prototype, meta); | ||
} | ||
return clazz; | ||
} | ||
} | ||
var Manager = { | ||
_clazz: {}, | ||
_meta: {}, | ||
setMeta: function(name, parent, meta) { | ||
if (typeof meta === 'undefined') { | ||
meta = parent; | ||
parent = undefined; | ||
} | ||
this._meta[name] = [parent, meta]; | ||
return this; | ||
}, | ||
hasOption: function(name) { | ||
return name in this._options; | ||
hasMeta: function(name) { | ||
return name in this._meta; | ||
}, | ||
setOption: function(option) { | ||
if (!(option instanceof MetaOption)) { | ||
throw new Error('Meta option must be instance of "Option" class!'); | ||
getMeta: function(name) { | ||
if (!(name in this._meta)) { | ||
throw new Error('Meta does not exists for "' + name + '"!'); | ||
} | ||
this._options[option.getName()] = option; | ||
return this._meta[name]; | ||
}, | ||
getClazz: function(name) { | ||
if (!(name in this._clazz)) { | ||
throw new Error('Clazz does not exists for "' + name + '"!'); | ||
} | ||
return this._clazz[name]; | ||
}, | ||
hasClazz: function(name) { | ||
return name in this._clazz; | ||
}, | ||
setClazz: function(name, clazz) { | ||
if (typeof clazz !== 'function') { | ||
throw new Error('Clazz must be a function!'); | ||
} | ||
this._clazz[name] = clazz; | ||
return this; | ||
}, | ||
getOptions: function() { | ||
return this._options; | ||
get: function(name) { | ||
if (!this.hasClazz(name)) { | ||
var meta = this.getMeta(name); | ||
this.setClazz(name, Factory.create(name, meta[0], meta[1])); | ||
} | ||
return this.getClazz(name); | ||
}, | ||
setOptions: function(options) { | ||
has: function(name) { | ||
return this.hasClazz(name) || this.hasMeta(name); | ||
} | ||
} | ||
var ConstantsInitProcessor = function(object, constants) { | ||
object['__constants'] = {}; | ||
if (Object.prototype.toString.apply(options) === '[object Array]') { | ||
for (var i = 0, ii = options.length; i < ii; ++i) { | ||
this.setOption(options[i]); | ||
for (var constant in constants) { | ||
object['__constants'][constant] = constants[constant]; | ||
} | ||
} | ||
var ConstantsInterfaceProcessor = new Meta.Processor.Interface({ | ||
const: function(name) { | ||
return this.__getConstant(name); | ||
}, | ||
__getConstant: function(name, constants) { | ||
var self = this; | ||
if (typeof constants === 'undefined') { | ||
constants = self.__getConstants(); | ||
} | ||
if (typeof name !== 'undefined') { | ||
if (!(name in constants)) { | ||
throw new Error('Constant "' + name + '" does not defined!'); | ||
} | ||
constants = constants[name]; | ||
if (Object.prototype.toString.apply(constants) === '[object Object]') { | ||
return function(name) { | ||
return self.__getConstant(name, constants) | ||
} | ||
} | ||
} | ||
return constants; | ||
}, | ||
__getConstants: function() { | ||
var constants = {}, parent = this; | ||
while (parent) { | ||
if (parent.hasOwnProperty('__constants')) { | ||
for (var constant in parent['__constants']) { | ||
if (!(constant in constants)) { | ||
constants[constant] = parent['__constants'][constant]; | ||
} | ||
} | ||
} | ||
parent = parent.parent; | ||
} | ||
return constants; | ||
} | ||
}); | ||
var ConstantsProcessor = new Meta.Processor.Chain({ | ||
init: ConstantsInitProcessor, | ||
interface: ConstantsInterfaceProcessor | ||
}) | ||
var MethodsProcessor = function(object, methods) { | ||
// Copy parent clazz methods | ||
if (typeof object === 'function' && object.parent) { | ||
for (var method in object.parent) { | ||
if (typeof object.parent[method] !== 'function') { | ||
continue; | ||
} | ||
object[method] = object.parent[method]; | ||
} | ||
} | ||
// Creates specified methods | ||
for (var method in methods) { | ||
if (typeof methods[method] !== 'function') { | ||
throw new Error('Method "' + method + '" must be a function!'); | ||
} | ||
object[method] = methods[method] | ||
} | ||
} | ||
var PropertiesDefaultsProcessor = function(object) { | ||
var property, defaults = object.getDefaults(); | ||
for (property in defaults) { | ||
object['_' + property] = defaults[property]; | ||
} | ||
} | ||
var PropertiesInitProcessor = function(object, properties) { | ||
for (var property in properties) { | ||
object['_' + property] = undefined; | ||
} | ||
} | ||
var PropertiesInterfaceProcessor = new Meta.Processor.Interface({ | ||
__setters: {}, | ||
__getters: {}, | ||
__defaults: {}, | ||
init: function(data) { | ||
this.__setData(data); | ||
}, | ||
__adjustPropertyName: function(name) { | ||
return name.replace(/(?:_)\w/, function (match) { return match[1].toUpperCase(); }); | ||
}, | ||
__getDefaults: function() { | ||
var defaults = {}, parent = this; | ||
while (parent) { | ||
if (parent.hasOwnProperty('__defaults')) { | ||
for (var prop in parent.__defaults) { | ||
if (!(prop in defaults)) { | ||
defaults[prop] = parent.__defaults[prop]; | ||
} | ||
} | ||
} | ||
parent = parent.parent; | ||
} | ||
return defaults | ||
}, | ||
__getDefault: function(property) { | ||
var defaults = this.__getDefaults(); | ||
return property in defaults ? defaults[property] : undefined; | ||
}, | ||
__setDefault: function(property, value) { | ||
this.__defaults[property] = value; | ||
}, | ||
__hasDefault: function(property) { | ||
return property in this.__getDefaults(); | ||
}, | ||
__setData: function(data) { | ||
for (var property in data) { | ||
if (!this.__hasProperty(property)) { | ||
continue; | ||
} | ||
this.__setProperty(property, data[property]); | ||
} | ||
return this; | ||
}, | ||
__getProperty: function(property) { | ||
property = this.__adjustPropertyName(property); | ||
if (!this.__hasProperty(property)) { | ||
throw new Error('Can\'t get! Property "' + property + '" does not exists!'); | ||
} | ||
var value = this['_' + property], getters = this.__getGetters(property); | ||
for (var name in getters) { | ||
value = getters[name].call(this, value); | ||
} | ||
return value; | ||
}, | ||
__setProperty: function(property, value) { | ||
property = this.__adjustPropertyName(property); | ||
if (!this.__hasProperty(property)) { | ||
throw new Error('Can\'t set! Property "' + property + '" does not exists!'); | ||
} | ||
var setters = this.__getSetters(property); | ||
for (var name in setters) { | ||
value = setters[name].call(this, value); | ||
} | ||
this['_' + property] = value; | ||
return this; | ||
}, | ||
__hasProperty: function(property) { | ||
property = this.__adjustPropertyName(property); | ||
return ('_' + property) in this && typeof this['_' + property] !== 'function'; | ||
}, | ||
__isProperty: function(property, value) { | ||
return typeof value !== 'undefined' ? value == this.__getProperty(property) : Boolean(this.__getProperty(property)); | ||
}, | ||
__isEmptyProperty: function(property) { | ||
var value = this.__getProperty(property); | ||
if (Object.prototype.toString.apply(value) === '[object Object]') { | ||
for (var prop in value) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
return (typeof this[value] === 'undefined') | ||
|| (value === null) | ||
|| (typeof value === 'string' && value === '') | ||
|| (Object.prototype.toString.apply(value) === '[object Array]' && value.length === 0); | ||
}, | ||
__addSetter: function(property, weight, callback) { | ||
if (typeof callback === 'undefined') { | ||
callback = weight; | ||
weight = 0; | ||
} | ||
if (typeof callback !== 'function') { | ||
throw new Error('Set callback must be a function!'); | ||
} | ||
if (!(property in this.__setters)) { | ||
this.__setters[property] = []; | ||
} | ||
this.__setters[property].push([weight, callback]); | ||
return this; | ||
}, | ||
__getSetters: function(property) { | ||
var setters, prop, allSetters = {}, parent = this.clazz.prototype; | ||
while (parent) { | ||
if (parent.hasOwnProperty('__setters')) { | ||
for (var prop in parent.__setters) { | ||
if (!(prop in allSetters)) { | ||
allSetters[prop] = parent.__setters[prop]; | ||
} | ||
} | ||
} | ||
parent = parent.parent; | ||
} | ||
if (typeof property !== 'undefined') { | ||
setters = []; | ||
if (property in allSetters && allSetters[property].length) { | ||
allSetters[property].sort(function(s1, s2) { | ||
return s2[0] - s1[0]; | ||
}); | ||
for (var i = 0, ii = allSetters[property].length; i < ii; ++i) { | ||
setters.push(allSetters[property][i][1]); | ||
} | ||
} | ||
} | ||
else { | ||
for (var name in options) { | ||
this.setOption(new MetaOption(name, options[name])); | ||
setters = allSetters; | ||
} | ||
return setters; | ||
}, | ||
__addGetter: function(property, weight, callback) { | ||
if (typeof callback === 'undefined') { | ||
callback = weight; | ||
weight = 0; | ||
} | ||
if (typeof callback !== 'function') { | ||
throw new Error('Get callback must be a function!'); | ||
} | ||
if (!(property in this.__getters)) { | ||
this.__getters[property] = []; | ||
} | ||
this.__getters[property].push([weight, callback]); | ||
return this; | ||
}, | ||
__getGetters: function(property) { | ||
var getters, allGetters = {}, parent = this.clazz.prototype; | ||
while (parent) { | ||
if (parent.hasOwnProperty('__getters')) { | ||
for (var prop in parent.__getters) { | ||
if (!(prop in allGetters)) { | ||
allGetters[prop] = parent.__getters[prop]; | ||
} | ||
} | ||
} | ||
parent = parent.parent; | ||
} | ||
return this; | ||
if (typeof property !== 'undefined') { | ||
getters = []; | ||
if (property in allGetters && allGetters[property].length) { | ||
allGetters[property].sort(function(s1, s2) { | ||
return s2[0] - s1[0]; | ||
}); | ||
for (var i = 0, ii = allGetters[property].length; i < ii; ++i) { | ||
getters.push(allGetters[property][i][1]); | ||
} | ||
} | ||
} | ||
else { | ||
getters = allGetters; | ||
} | ||
return getters; | ||
} | ||
}) | ||
var PropertiesMetaProcessor = { | ||
process: function(object, properties) { | ||
for (var property in properties) { | ||
this.Meta.process(object, properties[property], property) | ||
} | ||
}, | ||
Meta: new Meta({ | ||
type: { | ||
process: function(object, type, option, property) { | ||
if (Object.prototype.toString.apply(type) !== '[object Array]') { | ||
type = [type, {}]; | ||
} | ||
if (!(type[0] in this.TYPES)) { | ||
throw new Error('Unsupported property type "' + type[0] + '"!'); | ||
} | ||
var typer = this.TYPES[type[0]]; | ||
object.__addSetter(property, function(value) { | ||
return typer.call(object, value, type[1]); | ||
}); | ||
}, | ||
TYPES: { | ||
boolean: function(value) { | ||
return Boolean(value); | ||
}, | ||
number: function(value, params) { | ||
value = Number(value); | ||
if ('min' in params && value < params['min']) { | ||
throw new Error('Value "' + value + '" must not be less then "' + params['min'] + '"!'); | ||
} | ||
if ('max' in params && value > params['max']) { | ||
throw new Error('Value "' + value + '" must not be greater then "' + params['max'] + '"!'); | ||
} | ||
return value; | ||
}, | ||
string: function(value, params) { | ||
value = String(value); | ||
if ('pattern' in params && !params['pattern'].test(value)) { | ||
throw new Error('Value "' + value + '" does not match pattern "' + params['pattern'] + '"!'); | ||
} | ||
return value; | ||
}, | ||
datetime: function(value) { | ||
if (!(value instanceof Date)) { | ||
value = new Date(Date.parse(value)); | ||
} | ||
return value; | ||
}, | ||
array: function(value, params) { | ||
return typeof value === 'string' ? value.split(params['delimiter'] || ',') : [].concat(value); | ||
} | ||
} | ||
}, | ||
default: function(object, defaultValue, option, property) { | ||
if (typeof defaultValue === 'function') { | ||
defaultValue = defaultValue(); | ||
} | ||
this.__setDefault(property, defaultValue); | ||
}, | ||
methods: { | ||
process: function(object, methods, option, property) { | ||
if (Object.prototype.toString.apply(methods) !== '[object Array]') { | ||
methods = [methods]; | ||
} | ||
for (var i = 0, ii = methods.length; i < ii; ++i) { | ||
this.addMethod(methods[i], object, property); | ||
} | ||
}, | ||
addMethod: function(name, object, property) { | ||
var method = this.createMethod(name, property); | ||
object[method.name] = method.body; | ||
}, | ||
createMethod: function(name, property) { | ||
if (!(name in this.METHODS)) { | ||
throw new Error('Unsupported method "' + name + '"!'); | ||
} | ||
return this.METHODS[name](property); | ||
}, | ||
METHODS: { | ||
get: function(property) { | ||
return { | ||
name: 'get' + property[0].toUpperCase() + property.slice(1), | ||
body: function() { | ||
return this.__getProperty(property); | ||
} | ||
} | ||
}, | ||
set: function(property) { | ||
return { | ||
name: 'set' + property[0].toUpperCase() + property.slice(1), | ||
body: function(value) { | ||
return this.__setProperty(property, value); | ||
} | ||
} | ||
}, | ||
is: function(property) { | ||
return { | ||
name: (0 !== property.indexOf('is') ? 'is' : '') + property[0].toUpperCase() + property.slice(1), | ||
body: function(value) { | ||
return this.__isProperty(property, value); | ||
} | ||
} | ||
}, | ||
isEmpty: function(property) { | ||
return { | ||
name: (0 !== property.indexOf('isEmpty') ? 'isEmpty' : '') + property[0].toUpperCase() + property.slice(1), | ||
body: function() { | ||
return this.__isEmptyProperty(property); | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
converters: function(object, converters, option, property) { | ||
object.__addSetter(property, 1000, function(value) { | ||
for (var name in converters) { | ||
value = converters[name].call(this, value); | ||
} | ||
return value; | ||
}) | ||
}, | ||
constraints: function(object, constraints, option, property) { | ||
object.__addSetter(property, function(value) { | ||
for (var name in constraints) { | ||
if (!constraints[name].call(this, value)) { | ||
throw new Error('Constraint "' + name + '" was failed!'); | ||
} | ||
} | ||
return value; | ||
}) | ||
} | ||
}) | ||
} | ||
var PropertiesProcessor = new Meta.Processor.Chain({ | ||
init: PropertiesInitProcessor, | ||
interface: PropertiesInterfaceProcessor, | ||
meta: PropertiesMetaProcessor | ||
}) | ||
Clazz.Base = Base; | ||
Clazz.Factory = Factory; | ||
Clazz.Manager = Manager; | ||
Clazz.Meta = { | ||
Clazz: new Meta({ | ||
constants: ConstantsProcessor, | ||
clazz_properties: PropertiesProcessor, | ||
clazz_methods: MethodsProcessor | ||
}), | ||
Object: new Meta({ | ||
properties: PropertiesProcessor, | ||
methods: MethodsProcessor | ||
}) | ||
} | ||
global.Clazz = Clazz; | ||
})(this, Meta); |
@@ -1,2 +0,2 @@ | ||
!function(a,b,c){var b=function(a){this._options={},"undefined"!=typeof a&&this.setOptions(a)};b.prototype={process:function(a,b){var c,d;for(d in b)c=this.hasOption(d)?this.getOption(d):this.hasOption("__DEFAULT__")?this.getOption("__DEFAULT__"):null,c&&c.process.apply(c,[a,b[d]].concat(Array.prototype.slice.call(arguments,2)))},getOption:function(a){if(!(a in this._options))throw new Error('Meta option "'+a+'" does not exists!');return this._options[a]},hasOption:function(a){return a in this._options},setOption:function(a){if(!(a instanceof MetaOption))throw new Error('Meta option must be instance of "Option" class!');return this._options[a.getName()]=a,this},getOptions:function(){return this._options},setOptions:function(a){if("[object Array]"===Object.prototype.toString.apply(a))for(var b=0,c=a.length;c>b;++b)this.setOption(a[b]);else for(var d in a)this.setOption(new MetaOption(d,a[d]));return this}},a.Clazz=Clazz}(this,Meta); | ||
!function(a,b,c){var d=function(a,b,c){if(this instanceof d){var e=g.get(a);return e.create.apply(e,Array.prototype.slice.call(arguments,1))}return 1==arguments.length?("object"==typeof a&&(c=a,a=null),a?g.get(a):f.create(c)):(g.setMeta(a,b,c),void 0)},e=function(){"function"==typeof this.init&&this.init.apply(this,Array.prototype.slice.call(arguments))};e.NAME="__BASE_CLAZZ__",e.parent=null,e.create=function(){var a=arguments;return new this(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10])},e.prototype={parent:null,clazz:e};var f={CLASS_NAME:"Clazz{uid}",_clazzUID:0,create:function(a,b,c){return"undefined"==typeof c&&(c=b,b=null),"undefined"==typeof c&&(c=a,a=null),"string"==typeof b&&(b=g.get(b)),this.processMeta(this.createClazz(a,b),c)},createClazz:function(a,b){b||(b=e);var d=function(){b.apply(this,Array.prototype.slice.call(arguments))};for(var f in b)"function"==typeof b[f]?d[f]=b[f]:"_"===f[0]&&(d[f]=c);return d.NAME=a||this.generateName(),d.parent=b,d.prototype=Object.create(b.prototype),d.prototype.clazz=d,d.prototype.parent=b.prototype,d},generateName:function(){return this.CLASS_NAME.replace("{uid}",++this._clazzUID)},processMeta:function(a,b){return"function"==typeof b&&(b=b.apply(a)),b&&(d.Meta.Clazz.process(a,b),d.Meta.Object.process(a.prototype,b)),a}},g={_clazz:{},_meta:{},setMeta:function(a,b,d){return"undefined"==typeof d&&(d=b,b=c),this._meta[a]=[b,d],this},hasMeta:function(a){return a in this._meta},getMeta:function(a){if(!(a in this._meta))throw new Error('Meta does not exists for "'+a+'"!');return this._meta[a]},getClazz:function(a){if(!(a in this._clazz))throw new Error('Clazz does not exists for "'+a+'"!');return this._clazz[a]},hasClazz:function(a){return a in this._clazz},setClazz:function(a,b){if("function"!=typeof b)throw new Error("Clazz must be a function!");return this._clazz[a]=b,this},get:function(a){if(!this.hasClazz(a)){var b=this.getMeta(a);this.setClazz(a,f.create(a,b[0],b[1]))}return this.getClazz(a)},has:function(a){return this.hasClazz(a)||this.hasMeta(a)}},h=function(a,b){a.__constants={};for(var c in b)a.__constants[c]=b[c]},i=new b.Processor.Interface({"const":function(a){return this.__getConstant(a)},__getConstant:function(a,b){var c=this;if("undefined"==typeof b&&(b=c.__getConstants()),"undefined"!=typeof a){if(!(a in b))throw new Error('Constant "'+a+'" does not defined!');if(b=b[a],"[object Object]"===Object.prototype.toString.apply(b))return function(a){return c.__getConstant(a,b)}}return b},__getConstants:function(){for(var a={},b=this;b;){if(b.hasOwnProperty("__constants"))for(var c in b.__constants)c in a||(a[c]=b.__constants[c]);b=b.parent}return a}}),j=new b.Processor.Chain({init:h,"interface":i}),k=function(a,b){if("function"==typeof a&&a.parent)for(var c in a.parent)"function"==typeof a.parent[c]&&(a[c]=a.parent[c]);for(var c in b){if("function"!=typeof b[c])throw new Error('Method "'+c+'" must be a function!');a[c]=b[c]}},l=function(a){var b,c=a.getDefaults();for(b in c)a["_"+b]=c[b]},m=function(a,b){for(var d in b)a["_"+d]=c},n=new b.Processor.Interface({__setters:{},__getters:{},__defaults:{},init:function(a){this.__setData(a)},__adjustPropertyName:function(a){return a.replace(/(?:_)\w/,function(a){return a[1].toUpperCase()})},__getDefaults:function(){for(var a={},b=this;b;){if(b.hasOwnProperty("__defaults"))for(var c in b.__defaults)c in a||(a[c]=b.__defaults[c]);b=b.parent}return a},__getDefault:function(a){var b=this.__getDefaults();return a in b?b[a]:c},__setDefault:function(a,b){this.__defaults[a]=b},__hasDefault:function(a){return a in this.__getDefaults()},__setData:function(a){for(var b in a)this.__hasProperty(b)&&this.__setProperty(b,a[b]);return this},__getProperty:function(a){if(a=this.__adjustPropertyName(a),!this.__hasProperty(a))throw new Error("Can't get! Property \""+a+'" does not exists!');var b=this["_"+a],c=this.__getGetters(a);for(var d in c)b=c[d].call(this,b);return b},__setProperty:function(a,b){if(a=this.__adjustPropertyName(a),!this.__hasProperty(a))throw new Error("Can't set! Property \""+a+'" does not exists!');var c=this.__getSetters(a);for(var d in c)b=c[d].call(this,b);return this["_"+a]=b,this},__hasProperty:function(a){return a=this.__adjustPropertyName(a),"_"+a in this&&"function"!=typeof this["_"+a]},__isProperty:function(a,b){return"undefined"!=typeof b?b==this.__getProperty(a):Boolean(this.__getProperty(a))},__isEmptyProperty:function(a){var b=this.__getProperty(a);if("[object Object]"===Object.prototype.toString.apply(b)){for(var c in b)return!0;return!1}return"undefined"==typeof this[b]||null===b||"string"==typeof b&&""===b||"[object Array]"===Object.prototype.toString.apply(b)&&0===b.length},__addSetter:function(a,b,c){if("undefined"==typeof c&&(c=b,b=0),"function"!=typeof c)throw new Error("Set callback must be a function!");return a in this.__setters||(this.__setters[a]=[]),this.__setters[a].push([b,c]),this},__getSetters:function(a){for(var b,c,d={},e=this.clazz.prototype;e;){if(e.hasOwnProperty("__setters"))for(var c in e.__setters)c in d||(d[c]=e.__setters[c]);e=e.parent}if("undefined"!=typeof a){if(b=[],a in d&&d[a].length){d[a].sort(function(a,b){return b[0]-a[0]});for(var f=0,g=d[a].length;g>f;++f)b.push(d[a][f][1])}}else b=d;return b},__addGetter:function(a,b,c){if("undefined"==typeof c&&(c=b,b=0),"function"!=typeof c)throw new Error("Get callback must be a function!");return a in this.__getters||(this.__getters[a]=[]),this.__getters[a].push([b,c]),this},__getGetters:function(a){for(var b,c={},d=this.clazz.prototype;d;){if(d.hasOwnProperty("__getters"))for(var e in d.__getters)e in c||(c[e]=d.__getters[e]);d=d.parent}if("undefined"!=typeof a){if(b=[],a in c&&c[a].length){c[a].sort(function(a,b){return b[0]-a[0]});for(var f=0,g=c[a].length;g>f;++f)b.push(c[a][f][1])}}else b=c;return b}}),o={process:function(a,b){for(var c in b)this.Meta.process(a,b[c],c)},Meta:new b({type:{process:function(a,b,c,d){if("[object Array]"!==Object.prototype.toString.apply(b)&&(b=[b,{}]),!(b[0]in this.TYPES))throw new Error('Unsupported property type "'+b[0]+'"!');var e=this.TYPES[b[0]];a.__addSetter(d,function(c){return e.call(a,c,b[1])})},TYPES:{"boolean":function(a){return Boolean(a)},number:function(a,b){if(a=Number(a),"min"in b&&a<b.min)throw new Error('Value "'+a+'" must not be less then "'+b.min+'"!');if("max"in b&&a>b.max)throw new Error('Value "'+a+'" must not be greater then "'+b.max+'"!');return a},string:function(a,b){if(a=String(a),"pattern"in b&&!b.pattern.test(a))throw new Error('Value "'+a+'" does not match pattern "'+b.pattern+'"!');return a},datetime:function(a){return a instanceof Date||(a=new Date(Date.parse(a))),a},array:function(a,b){return"string"==typeof a?a.split(b.delimiter||","):[].concat(a)}}},"default":function(a,b,c,d){"function"==typeof b&&(b=b()),this.__setDefault(d,b)},methods:{process:function(a,b,c,d){"[object Array]"!==Object.prototype.toString.apply(b)&&(b=[b]);for(var e=0,f=b.length;f>e;++e)this.addMethod(b[e],a,d)},addMethod:function(a,b,c){var d=this.createMethod(a,c);b[d.name]=d.body},createMethod:function(a,b){if(!(a in this.METHODS))throw new Error('Unsupported method "'+a+'"!');return this.METHODS[a](b)},METHODS:{get:function(a){return{name:"get"+a[0].toUpperCase()+a.slice(1),body:function(){return this.__getProperty(a)}}},set:function(a){return{name:"set"+a[0].toUpperCase()+a.slice(1),body:function(b){return this.__setProperty(a,b)}}},is:function(a){return{name:(0!==a.indexOf("is")?"is":"")+a[0].toUpperCase()+a.slice(1),body:function(b){return this.__isProperty(a,b)}}},isEmpty:function(a){return{name:(0!==a.indexOf("isEmpty")?"isEmpty":"")+a[0].toUpperCase()+a.slice(1),body:function(){return this.__isEmptyProperty(a)}}}}},converters:function(a,b,c,d){a.__addSetter(d,1e3,function(a){for(var c in b)a=b[c].call(this,a);return a})},constraints:function(a,b,c,d){a.__addSetter(d,function(a){for(var c in b)if(!b[c].call(this,a))throw new Error('Constraint "'+c+'" was failed!');return a})}})},p=new b.Processor.Chain({init:m,"interface":n,meta:o});d.Base=e,d.Factory=f,d.Manager=g,d.Meta={Clazz:new b({constants:j,clazz_properties:p,clazz_methods:k}),Object:new b({properties:p,methods:k})},a.Clazz=d}(this,Meta); | ||
//# sourceMappingURL=dist/ClazzJS.min.map |
@@ -15,3 +15,10 @@ "use strict"; | ||
"src/.prefix", | ||
"src/Clazz.js", | ||
"src/Base.js", | ||
"src/Factory.js", | ||
"src/Manager.js", | ||
"src/MetaProcessors/*.js", | ||
"src/.suffix" | ||
@@ -18,0 +25,0 @@ ] |
{ | ||
"name": "clazz-js", | ||
"title": "ClazzJS", | ||
"version": "0.0.0", | ||
"version": "0.1.0", | ||
"description": "Portable JavaScript library for class-style OOP programming", | ||
@@ -6,0 +6,0 @@ "author": { |
@@ -5,1 +5,3 @@ ClazzJS | ||
Portable JavaScript library for class-style OOP programming | ||
Documentation is coming soon. Until that look at usage example: http://plnkr.co/edit/c5Xveb |
@@ -1,64 +0,23 @@ | ||
var Meta = function(options) { | ||
this._options = {}; | ||
var Clazz = function(name, parent, meta) { | ||
if (typeof options !== 'undefined') { | ||
this.setOptions(options); | ||
// If called as constructor - creates new clazz object. | ||
if (this instanceof Clazz) { | ||
var clazz = Manager.get(name); | ||
return clazz.create.apply(clazz, Array.prototype.slice.call(arguments, 1)); | ||
} | ||
} | ||
Meta.prototype = { | ||
process: function(object, meta) { | ||
var metaOption, option; | ||
for (option in meta) { | ||
metaOption = this.hasOption(option) | ||
? (this.getOption(option)) | ||
: (this.hasOption('__DEFAULT__') ? this.getOption('__DEFAULT__') : null) | ||
if (metaOption) { | ||
metaOption.process.apply(metaOption, [object, meta[option]].concat(Array.prototype.slice.call(arguments,2)) ); | ||
else { | ||
if (arguments.length == 1) { | ||
if (typeof name === 'object') { | ||
meta = name; | ||
name = null; | ||
} | ||
// If only name is specified - returns entity clazz. | ||
return name ? Manager.get(name) : Factory.create(meta); | ||
} | ||
}, | ||
getOption: function(name) { | ||
if (!(name in this._options)) { | ||
throw new Error('Meta option "' + name + '" does not exists!'); | ||
} | ||
return this._options[name]; | ||
}, | ||
hasOption: function(name) { | ||
return name in this._options; | ||
}, | ||
setOption: function(option) { | ||
if (!(option instanceof MetaOption)) { | ||
throw new Error('Meta option must be instance of "Option" class!'); | ||
} | ||
this._options[option.getName()] = option; | ||
return this; | ||
}, | ||
getOptions: function() { | ||
return this._options; | ||
}, | ||
setOptions: function(options) { | ||
if (Object.prototype.toString.apply(options) === '[object Array]') { | ||
for (var i = 0, ii = options.length; i < ii; ++i) { | ||
this.setOption(options[i]); | ||
} | ||
} | ||
// If name and some meta data are specified - save meta. | ||
// Class will be created on demand (lazy load). | ||
else { | ||
for (var name in options) { | ||
this.setOption(new MetaOption(name, options[name])); | ||
} | ||
Manager.setMeta(name, parent, meta); | ||
} | ||
return this; | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
50598
24
1129
7
1