back to devpro   download
/*! Object.defineStrictProperty Experiment
 * @author  Andrea Giammarchi
 * @blog    http://webreflection.blogspot.com/
 * @version 1.0b
 * @license Mit Style
 */
 
Object.defineStrictProperty || (Object.defineStrictProperty = function () {
    function args(args, get) {
        return function () {
            var callback = get.call(this);
            return function get() {
                for (var
                    length = args.length,
                    i = 0,
                    match = 0;
                    i < length && !match;
                    ++i
                ) {
                    for (var
                        current = args[i],
                        j = current.length,
                        single = 1;
                        j-- && single;
                    ) {
                        single = typeCheck(arguments[j], current[j]);
                    }
                    match = single;
                }
                if (!match && length) {
                    error("wrong arguments", {expected:args, received:args.slice.call(arguments)});
                }
                return callback.apply(this, arguments);
            };
        };
    }
    function argumentsGroups(args) {
        for (var i = args.length, match = 1; i-- && match;) {
            match = args[i] instanceof Array;
        }
        return match ? args : [args];
    }
    function concat(value) {
        return [].concat(value);
    }
    function defineStrictProperty(self, key, descriptor) {
        if (defineStrictProperty.production || !hasOwnProperty.call(descriptor, "type")) {
            defineProperty(self, key, descriptor);
        } else {
            var
                type = descriptor.type,
                $get = hasOwnProperty.call(descriptor, "get"),
                $set = hasOwnProperty.call(descriptor, "set"),
                $value = hasOwnProperty.call(descriptor, "value"),
                $key, value
            ;
            if ($value || (!$get && !$set)) {
                value = $value ? descriptor.value : null;
                delete descriptor.value;
                descriptor.get = get("this[p]", $key = "@" + key);
                descriptor.set = set(
                    "Object.defineStrictProperty(this,p,{configurable:0,writable:1,enumerable:0,value:v})",
                    $key,
                    type
                );
            } else {
                if ($get) {
                    descriptor.get = get("p.call(this)", descriptor.get);
                }
                if ($set) {
                    descriptor.set = set("p.call(this,v)", descriptor.set, type);
                }
            }
            if (type == fn || type == create) {
                if (hasOwnProperty.call(descriptor, "returns")) {
                    descriptor.get = returns(concat(descriptor.returns), descriptor.get);
                }
                if (hasOwnProperty.call(descriptor, "arguments")) {
                    descriptor.get = args(argumentsGroups(descriptor.arguments), descriptor.get);
                }
                
            }
            defineProperty(self, key, descriptor);
            if ($value) {
                self[key] = value;
            }
        }
        return self;
    }
    function error(message, log) {
        if (log && typeof console == ob) {
            console.log(log);
        }
        throw new TypeError(message);
    }
    function get(body, param) {
        return create("p", "return " + fn + " get(){return " + body + "}")(param);
    }
    function returns(returns, get) {
        return function () {
            var callback = get.call(this);
            return function get() {
                for (var
                    result = callback.apply(this, arguments),
                    i = returns.length,
                    match = 0;
                    i-- && !match;
                ) {
                    match = typeCheck(result, returns[i]);
                }
                if (!match) {
                    error("wrong return", {expected:returns, received:result});
                }
                return result;
            };
        };
    }
    function set(body, param, expected) {
        return create(
            "t,y,p,e",
            "return " +
                fn +
            " set(v){if(!t(v,e))y('wrong type',{expected:e,received:v});" +
                body +
            "}"
        )(typeCheck, error, param, expected);
    }
    function typeCheck(current, expected) {
        var
            type = typeof expected,
            undefined
        ;
        return (
            (type == st && typeof current == expected) ||
            (type == fn && (current instanceof expected)) ||
            (type == ob && (
                (expected != null && expected.isPrototypeOf(current)) ||
                (expected === null && current === expected)
            )) ||
            expected === undefined && current === expected
        );
    }
    var
        fn = "function", st = "string", ob = "object",
        hasOwnProperty = {}.hasOwnProperty,
        create = Function,
        defineProperty = Object.defineProperty || function (object, key, descriptor) {
            if (hasOwnProperty.call(descriptor, "value")) {
                object[key] = descriptor.value;
            } else {
                if (hasOwnProperty.call(descriptor, "get")) {
                    object.__defineGetter__(key, descriptor.get);
                }
                if (hasOwnProperty.call(descriptor, "set")) {
                    object.__defineSetter__(key, descriptor.set);
                }
            }
        }
    ;
    defineStrictProperty.production = false;
    return defineStrictProperty;
}());

Object.defineStrictProperties || (Object.defineStrictProperties = function () {
    function defineStrictProperties(self, descriptor) {
        for (var key in descriptor) {
            descriptor.hasOwnProperty(key) &&
                Object.defineStrictProperty(
                    self,
                    key,
                    descriptor[key]
                )
            ;
        }
        return self;
    }
    return defineStrictProperties;
}());
back to devpro   download
Creative Commons License