From d42f9ede3833aaf92c32e1dd9d546afcca6e570f Mon Sep 17 00:00:00 2001 From: goto100 Date: Tue, 3 Sep 2013 16:28:31 +0800 Subject: [PATCH 01/13] kissy gallery init --- package.json | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 2c923d2..32af2ee 100644 --- a/package.json +++ b/package.json @@ -1,25 +1,11 @@ -{ - "name": "oop.js", - "version": "0.0.1", - "description": "", - "main": "lib/oop.js", - "directories": { - "test": "test" - }, - "scripts": { - "test": "mocha" - }, - "repository": { - "type": "git", - "url": "git://github.com/ObjectJS/oop.git" - }, - "keywords": [ - "OOP", - "class", - "mixin", - "extend", - "prototype" - ], - "author": "", - "license": "BSD" -} +{ + "name": "oop", + "version": "1.0.0", + "devDependencies": { + "grunt-contrib-uglify": "~0.2.0", + "grunt": "~0.4.1", + "grunt-kmc": "~0.1.1", + "grunt-contrib-cssmin": "~0.6.0", + "grunt-contrib-copy":"~0.4.0" + } +} From 5b22d61f80b5c0498ac1c0ba925cc72defec0493 Mon Sep 17 00:00:00 2001 From: goto100 Date: Tue, 3 Sep 2013 16:29:30 +0800 Subject: [PATCH 02/13] kissy gallery init --- .gitignore | 6 ++++ 0.1/demo/index.html | 33 ++++++++++++++++++++ 0.1/guide/index.md | 15 ++++++++++ 0.1/index.js | 29 ++++++++++++++++++ 0.1/meta/alias.js | 3 ++ 0.1/meta/modules.js | 3 ++ Gruntfile.js | 73 +++++++++++++++++++++++++++++++++++++++++++++ abc.json | 14 +++++++++ 8 files changed, 176 insertions(+) create mode 100644 .gitignore create mode 100644 0.1/demo/index.html create mode 100644 0.1/guide/index.md create mode 100644 0.1/index.js create mode 100644 0.1/meta/alias.js create mode 100644 0.1/meta/modules.js create mode 100644 Gruntfile.js create mode 100644 abc.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0fa60a6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.DS_Store +node_modules +npm-debug.log +*.swp +.sw* +.idea/* \ No newline at end of file diff --git a/0.1/demo/index.html b/0.1/demo/index.html new file mode 100644 index 0000000..327475f --- /dev/null +++ b/0.1/demo/index.html @@ -0,0 +1,33 @@ + + + + + oop的demo + + + + +

oop的demo

+ + + + diff --git a/0.1/guide/index.md b/0.1/guide/index.md new file mode 100644 index 0000000..7d72cba --- /dev/null +++ b/0.1/guide/index.md @@ -0,0 +1,15 @@ +## 综述 + +oop是。 + +* 版本:1.0 +* 作者:goto100 +* demo:[http://gallery.kissyui.com/oop/1.0/demo/index.html](http://gallery.kissyui.com/oop/1.0/demo/index.html) + +## 初始化组件 + + S.use('gallery/oop/1.0/index', function (S, Oop) { + var oop = new Oop(); + }) + +## API说明 diff --git a/0.1/index.js b/0.1/index.js new file mode 100644 index 0000000..da2b735 --- /dev/null +++ b/0.1/index.js @@ -0,0 +1,29 @@ +/** + * @fileoverview + * @author goto100 + * @module oop + **/ +KISSY.add(function (S, Node,Base) { + var EMPTY = ''; + var $ = Node.all; + /** + * + * @class Oop + * @constructor + * @extends Base + */ + function Oop(comConfig) { + var self = this; + //调用父类构造函数 + Oop.superclass.constructor.call(self, comConfig); + } + S.extend(Oop, Base, /** @lends Oop.prototype*/{ + + }, {ATTRS : /** @lends Oop*/{ + + }}); + return Oop; +}, {requires:['node', 'base']}); + + + diff --git a/0.1/meta/alias.js b/0.1/meta/alias.js new file mode 100644 index 0000000..11710b0 --- /dev/null +++ b/0.1/meta/alias.js @@ -0,0 +1,3 @@ +config({ + 'gallery/oop/index': {alias: ['gallery/oop/1.0/index']} +}); \ No newline at end of file diff --git a/0.1/meta/modules.js b/0.1/meta/modules.js new file mode 100644 index 0000000..6052141 --- /dev/null +++ b/0.1/meta/modules.js @@ -0,0 +1,3 @@ +config({ + 'gallery/oop/index': {requires: ['node','base']} +}); \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..aaff4ae --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,73 @@ +module.exports = function(grunt) { + grunt.initConfig({ + // 配置文件,参考package.json配置方式,必须设置项是 + // name, version, author + // name作为gallery发布后的模块名 + // version是版本,也是发布目录 + // author必须是{name: "xxx", email: "xxx"}格式 + pkg: grunt.file.readJSON('abc.json'), + banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + + '<%= grunt.template.today("yyyy-mm-dd h:MM:ss TT") %>\n' + + '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + + '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + + ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n', + + // kmc打包任务,默认情况,入口文件是index.js,可以自行添加入口文件,在files下面 + // 添加 + kmc: { + options: { + packages: [ + { + name: '<%= pkg.name %>', + path: '../' + } + ], + map: [["<%= pkg.name %>/", "gallery/<%= pkg.name %>/"]] + }, + main: { + files: [ + { + src: "<%= pkg.version %>/index.js", + dest: "<%= pkg.version %>/build/index.js" + } + ] + } + }, + // 打包后压缩文件 + // 压缩文件和入口文件一一对应 + uglify: { + options: { + banner: '<%= banner %>', + beautify: { + ascii_only: true + } + }, + base: { + files: { + '<%= pkg.version %>/build/index-min.js': ['<%= pkg.version %>/build/index.js'] + } + } + }, + copy: { + main: { + files: [ + {src: ['<%= pkg.version %>/index.css'], dest: '<%= pkg.version %>/build/index.css'} + ] + } + }, + cssmin: { + combine: { + files: { + '<%= pkg.version %>/build/index-min.css': ['<%= pkg.version %>/build/index.css'] + } + } + } + }); + + // 使用到的任务,可以增加其他任务 + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-kmc'); + grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-copy'); + return grunt.registerTask('default', ['kmc', 'uglify']); +}; \ No newline at end of file diff --git a/abc.json b/abc.json new file mode 100644 index 0000000..4a3ef3b --- /dev/null +++ b/abc.json @@ -0,0 +1,14 @@ +{ + "name": "oop", + "version": "1.0", + "desc": "", + "cover": "", + "tag":"oop", + "author": { + "name": "goto100", + "email": "yiyu.ljw@taobao.com", + "page": "" + }, + "type": "kissy-gallery", + "type-url": "http://gallery.kissyui.com/guide" +} From f61143c9f5874639b9df8e176a9586df2337bfb4 Mon Sep 17 00:00:00 2001 From: goto100 Date: Tue, 3 Sep 2013 16:32:58 +0800 Subject: [PATCH 03/13] first build --- 0.1/build/index-min.js | 3 + 0.1/build/index.js | 36 ++++ abc.json | 2 +- index.js | 461 +++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 5 files changed, 502 insertions(+), 2 deletions(-) create mode 100644 0.1/build/index-min.js create mode 100644 0.1/build/index.js create mode 100644 index.js diff --git a/0.1/build/index-min.js b/0.1/build/index-min.js new file mode 100644 index 0000000..87fc8fc --- /dev/null +++ b/0.1/build/index-min.js @@ -0,0 +1,3 @@ +/*! oop - v0.1 - 2013-09-03 4:32:09 PM +* Copyright (c) 2013 goto100; Licensed */ +KISSY.add("gallery/oop/0.1/index",function(a,b,c){function d(a){var b=this;d.superclass.constructor.call(b,a)}return b.all,a.extend(d,c,{},{ATTRS:{}}),d},{requires:["node","base"]}); \ No newline at end of file diff --git a/0.1/build/index.js b/0.1/build/index.js new file mode 100644 index 0000000..53f7657 --- /dev/null +++ b/0.1/build/index.js @@ -0,0 +1,36 @@ +/* +combined files : + +gallery/oop/0.1/index + +*/ +/** + * @fileoverview + * @author goto100 + * @module oop + **/ +KISSY.add('gallery/oop/0.1/index',function (S, Node,Base) { + var EMPTY = ''; + var $ = Node.all; + /** + * + * @class Oop + * @constructor + * @extends Base + */ + function Oop(comConfig) { + var self = this; + //调用父类构造函数 + Oop.superclass.constructor.call(self, comConfig); + } + S.extend(Oop, Base, /** @lends Oop.prototype*/{ + + }, {ATTRS : /** @lends Oop*/{ + + }}); + return Oop; +}, {requires:['node', 'base']}); + + + + diff --git a/abc.json b/abc.json index 4a3ef3b..70a0e3c 100644 --- a/abc.json +++ b/abc.json @@ -1,6 +1,6 @@ { "name": "oop", - "version": "1.0", + "version": "0.1", "desc": "", "cover": "", "tag":"oop", diff --git a/index.js b/index.js new file mode 100644 index 0000000..a219fbb --- /dev/null +++ b/index.js @@ -0,0 +1,461 @@ +KISSY.add('oop', function() { + +var exports = {}; + +// 无法通过 Object.defineProperty 判断是否支持,IE8 有此方法,但无法设置普通对象 +var supportDefineProperty = true; +try { + Object.defineProperty({}, 'a', {value: 1}); +} catch(e) { + supportDefineProperty = false; +} + +if (!Object.keys) { + Object.keys = function(o) { + var result = []; + if (o === undefined || o === null) { + return result; + } + + // 在Safari 5.0.2(7533.18.5)中,在这里用for in遍历parent会将prototype属性遍历出来,导致原型被指向一个错误的对象 + // 经过试验,在Safari下,仅仅通过 obj.prototype.xxx = xxx 这样的方式就会导致 prototype 变成自定义属性,会被 for in 出来 + // 而其他浏览器仅仅是在重新指向prototype时,类似 obj.prototype = {} 这样的写法才会出现这个情况 + // 因此,在使用时一定要注意 + for (var name in o) { + if (o.hasOwnProperty(name)) { + result.push(name); + } + } + + return result; + }; +} + +if (!Array.prototype.forEach) { + Array.prototype.forEach = function(fn, bind) { + for (var i = 0; i < this.length; i++) { + fn.call(bind, this[i], i, this); + } + }; +} + +if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function(str) { + for (var i = 0; i < this.length; i++) { + if (str === this[i]) { + return i; + } + } + return -1; + }; +} + +if (!Function.prototype.bind) { + Function.prototype.bind = function(object) { + var method = this; + var args = Array.prototype.slice.call(arguments, 1); + return function() { + return method.apply(object, args.concat(Array.prototype.slice.call(arguments))); + }; + }; +} + +function extend(obj, properties, ov) { + var filter = null; + if (typeof ov == 'function') { + filter = ov; + } else if (ov === true || typeof ov === 'undefined') { + filter = function(prop, dest, src) { + return true; + }; + } else { + filter = function(prop, dest, src) { + return !(prop in dest); + }; + } + + for (var property in properties) { + if (filter(property, obj, properties)) { + obj[property] = properties[property]; + } + } + if (properties && properties.hasOwnProperty('call') && filter(obj, properties, 'call')) { + obj.call = properties.call; + } + + return obj; +} + +// 仿照 mootools 的overloadsetter +// 返回一个 key/value 这种形式的function参数的包装,使其支持{key1: value1, key2: value2} 这种传参形式 +function overloadsetter(usePlural) { + var func; + function setter(a, b) { + if (a === null) return this; + if (usePlural || typeof a != 'string') { + for (var k in a) func.call(this, k, a[k]); + } else { + func.call(this, a, b); + } + return this; + }; + + if (typeof usePlural == 'function') { + func = usePlural; + usePlural = false; + } + + if (func) { + return setter; + } else { + return function(f) { + func = f; + return setter; + } + } +}; + +var getter = supportDefineProperty? function(name) { + return this[name]; +} : function(name) { + return this['__' + name + '_get'](); +}; + +var setter = supportDefineProperty? function(name, value) { + return this[name] = value; +} : function(name, value) { + return this['__' + name + '_set'](value); +} + +function instancemethod(func) { + return { + __class__: arguments.callee, + __func__: func + }; +} + +instancemethod.setTo = function(cls, name, member) { + var proto = cls.prototype; + member.__func__.__name__ = name; + proto[name] = member.__func__; +}; + +function staticmethod(func) { + return { + __class__: arguments.callee, + __func__: func + }; +} + +staticmethod.setTo = function(cls, name, member) { + var proto = cls.prototype; + cls[name] = proto[name] = member.__func__; +}; + +function property(fget, fset) { + var describer = { + __class__: arguments.callee, + fget: fget, + fset: fset + }; + return describer; +} + +property.setTo = function(cls, name, member) { + var proto = cls.prototype; + member.enumerable = true; + var type = cls.__metaclass__.prototype.__defaultmethodtype__; + if (member.fget) { + type.setTo(cls, '__' + name + '_get', type(member.fget)); + member.get = function() { + return this['__' + name + '_get'](); + }; + } + if (member.fset) { + type.setTo(cls, '__' + name + '_set', type(member.fset)); + member.set = function(value) { + return this['__' + name + '_set'](value); + }; + } + proto.__properties__[name] = member; + if (supportDefineProperty) { + Object.defineProperty(proto, name, member); + } +}; + +function nontypemember() {} + +nontypemember.setTo = function(cls, name, member) { + var proto = cls.prototype; + cls[name] = proto[name] = member; +}; + +function typeOf(obj) { + if (instanceOf(obj.__metaclass__, Type)) { + return 'type'; + } else { + return typeof obj; + } +} + +function instanceOf(obj, func) { + if (typeof func != 'function') { + throw new Error('bad arguments.'); + } + + var cls; + + // 查询一个func的constructor,js中的function是没有原型继承的,只能通过递归查询。 + // 一般来说就是Type + if (typeof obj == 'function') { + // 遍历实例的创建者继承链,找是否与func相同 + cls = obj.__class__; + if (cls) { + do { + if (cls === func) return true; + } while (cls = cls.__base__); + } + } + // 查询普通对象的constructor,可直接使用instanceof + else { + return obj instanceof func; + } + return false; + +} + +function makePrivate(proto, name) { + if (!supportDefineProperty) return; + + var member; + if (name.indexOf('__') == 0 && name.lastIndexOf('__') != name.length - 2) { + member = proto[name]; + Object.defineProperty(proto, name, { + get: function() { + if (this.constructor.prototype.hasOwnProperty(name)) { + return member; + } + }, + set: function(value) { + member = value; + } + }); + } +} + +function parent(self) { + var ownCls = self.__class__; // 拥有此方法的代码书写的类 + var name = arguments.callee.caller.__name__; // 方法名字 + var base, member; // 最后要执行的类和方法 + + if (!name) throw new Error('parent call error'); + + // parent应该调用“代码书写的方法所在的类的父同名方法” + // 而不是方法调用者实例的类的父同名方法 + // 比如C继承于B继承于A,当C的实例调用从B继承来的某方法时,其中调用了this.parent,应该直接调用到A上的同名方法,而不是B的。 + // 因此,这里通过hasOwnProperty,从当前类开始,向上找到同名方法的原始定义类 + while (ownCls && !ownCls.prototype.hasOwnProperty(name)) { + ownCls = ownCls.__base__; + } + + base = ownCls.__base__; + if (!base) throw new Error('base class not found in parent call'); + + var inProto = false; + if (base[name]) { + member = base[name]; + } else if (base.prototype[name]) { + member = base.prototype[name]; + inProto = true; + } + + if (!member || !member.apply) throw new Error('method not found in parent call'); + + if (inProto) { + return member.apply(self, Array.prototype.slice.call(arguments, 1)); + } else { + return member.apply(base, arguments); + } +} + +function Type() { + +} + +Type.__class__ = Type; + +Type.setTo = function(cls, name, member) { + cls[name] = cls.prototype[name] = member; +}; + +Type.__new__ = function(metaclass, name, base, dict) { + var cls = function() { + if (prototyping) return; + this.__class__ = cls; + var value = this.initialize? this.initialize.apply(this, arguments) : null; + return value; + }; + + var proto = Object.__new__(base); + cls.prototype = proto; + cls.prototype.constructor = cls; + cls.prototype.__properties__ = {}; + + for (var key in metaclass.prototype) { + cls[key] = metaclass.prototype[key]; + } + // Object.keys(metaclass.prototype).forEach(function(key) { + // cls[key] = metaclass.prototype[key]; + // }); + // cls.__proto__ = Object.create(base); + Object.keys(base).forEach(function(key) { + // private + if (key.indexOf('__') == 0 && key.lastIndexOf('__') != key.length - 2) { + return + } + cls[key] = base[key]; + }); + + cls.__base__ = base; + cls.__class__ = metaclass; + cls.__metaclass__ = metaclass; + cls.__dict__ = {}; + + (dict.__mixins__ || []).reverse().forEach(function(mixin) { + var chain = [mixin]; + var base = mixin; + while ((base = base.__base__)) { + chain.unshift(base); + } + chain.forEach(function(one) { + var dict, proto; + if (one.__dict__) { + dict = one.__dict__; + } else { + dict = {}; + proto = one.prototype; + Object.keys(proto).forEach(function(key) { + if (typeOf(proto[key]) == 'function') { + dict[key] = staticmethod(proto[key]); + } else { + dict[key] = proto[key]; + } + }); + } + Object.keys(dict).forEach(function(k) { + metaclass.prototype.__setattr__.call(cls, k, dict[k]); + }); + }); + }); + + Object.keys(dict).forEach(function(k) { + metaclass.prototype.__setattr__.call(cls, k, dict[k]); + }); + + cls.prototype.get = getter; + cls.prototype.set = setter; + + delete dict; + + return cls; +}; + +Type.prototype.initialize = function() { +}; + +Type.prototype.__setattr__ = function(name, member) { + var cls = this; + var proto = cls.prototype; + var memberType; + + // 动态添加的成员也可以在dict上找到 + cls.__dict__[name] = member; + + if (name == '__new__') { + member = staticmethod(member); + } + + if (member != undefined) { + if (!member.__class__ && typeof member == 'function') { + member = cls.__metaclass__.prototype.__defaultmethodtype__(member); + } + memberType = member.__class__ || nontypemember; + } else { + memberType = nontypemember; + } + + memberType.setTo(cls, name, member); + + makePrivate(proto, name); +}; + +Type.prototype.__defaultmethodtype__ = instancemethod; + +var prototyping = false; +Object.__new__ = function(cls) { + if (Object.create) { + return Object.create(cls.prototype); + } else { + prototyping = true; + var p = new cls; + prototyping = false; + return p; + } +}; + +function Class() { + var args = arguments; + var length = args.length; + if (length < 1) throw new Error('bad arguments'); + + // name + var name = null; + + // base + var base = length > 1? args[0] : Object; + if (typeof base != 'function' && typeof base != 'object') { + throw new Error('base is not function or object'); + } + + // dict + var dict = args[length - 1], factory; + if (typeof dict != 'function' && typeof dict != 'object') { + throw new Error('constructor is not function or object'); + } + if (dict instanceof Function) { + factory = dict; + dict = {}; + factory.call(dict); + } + + var metaclass = dict.__metaclass__ || base.__metaclass__ || Type; + + // 创建&初始化 + var cls = metaclass.__new__(metaclass, name, base, dict); + + if (!cls || typeof cls != 'function') { + throw new Error('__new__ method should return cls'); + } + + metaclass.prototype.initialize.call(cls, name, base, dict); + + return cls; +} + +exports.Class = Class; +exports.Type = Type; +exports.staticmethod = staticmethod; +exports.property = property; +exports.parent = parent; +exports.instanceOf = instanceOf; +exports.typeOf = typeOf; +exports.install = function(target) { + if (!target) target = global; + ['Class', 'Type', 'classmethod', 'staticmethod', 'property'].forEach(function(name) { + target[name] = exports[name]; + }) +}; + +return exports; + +}); \ No newline at end of file diff --git a/package.json b/package.json index 32af2ee..b6a765c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oop", - "version": "1.0.0", + "version": ".0.1.0", "devDependencies": { "grunt-contrib-uglify": "~0.2.0", "grunt": "~0.4.1", From c2cca184449f69deb8f11c5565e176f005e04075 Mon Sep 17 00:00:00 2001 From: goto100 Date: Tue, 3 Sep 2013 16:36:20 +0800 Subject: [PATCH 04/13] abc --- abc.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/abc.json b/abc.json index 70a0e3c..b1310a3 100644 --- a/abc.json +++ b/abc.json @@ -1,13 +1,13 @@ { "name": "oop", "version": "0.1", - "desc": "", + "desc": "OOP库", "cover": "", "tag":"oop", "author": { "name": "goto100", "email": "yiyu.ljw@taobao.com", - "page": "" + "page": "http://github.com/goto100" }, "type": "kissy-gallery", "type-url": "http://gallery.kissyui.com/guide" From 39e779897a88abd99b44da40c1cb6ccfccfd6bf5 Mon Sep 17 00:00:00 2001 From: goto100 Date: Tue, 3 Sep 2013 17:11:59 +0800 Subject: [PATCH 05/13] build from lib/oop.js --- 0.1/build/index-min.js | 4 +- 0.1/build/index.js | 488 ++++++++++++++++++++++++++++++++++++++--- 0.1/index.js | 29 --- Gruntfile.js | 2 +- index.js | 461 -------------------------------------- lib/oop.js | 4 + 6 files changed, 465 insertions(+), 523 deletions(-) delete mode 100644 0.1/index.js delete mode 100644 index.js diff --git a/0.1/build/index-min.js b/0.1/build/index-min.js index 87fc8fc..d9d1d76 100644 --- a/0.1/build/index-min.js +++ b/0.1/build/index-min.js @@ -1,3 +1,3 @@ -/*! oop - v0.1 - 2013-09-03 4:32:09 PM +/*! oop - v0.1 - 2013-09-03 5:11:21 PM * Copyright (c) 2013 goto100; Licensed */ -KISSY.add("gallery/oop/0.1/index",function(a,b,c){function d(a){var b=this;d.superclass.constructor.call(b,a)}return b.all,a.extend(d,c,{},{ATTRS:{}}),d},{requires:["node","base"]}); \ No newline at end of file +KISSY.add("gallery/oop/lib/oop",function(){function a(a){return{__class__:arguments.callee,__func__:a}}function b(a){return{__class__:arguments.callee,__func__:a}}function c(a,b){var c={__class__:arguments.callee,fget:a,fset:b};return c}function d(){}function e(a){return f(a.__metaclass__,i)?"type":typeof a}function f(a,b){if("function"!=typeof b)throw new Error("bad arguments.");var c;if("function"!=typeof a)return a instanceof b;if(c=a.__class__)do if(c===b)return!0;while(c=c.__base__);return!1}function g(a,b){if(k){var c;0==b.indexOf("__")&&b.lastIndexOf("__")!=b.length-2&&(c=a[b],Object.defineProperty(a,b,{get:function(){return this.constructor.prototype.hasOwnProperty(b)?c:void 0},set:function(a){c=a}}))}}function h(a){var b,c,d=a.__class__,e=arguments.callee.caller.__name__;if(!e)throw new Error("parent call error");for(;d&&!d.prototype.hasOwnProperty(e);)d=d.__base__;if(b=d.__base__,!b)throw new Error("base class not found in parent call");var f=!1;if(b[e]?c=b[e]:b.prototype[e]&&(c=b.prototype[e],f=!0),!c||!c.apply)throw new Error("method not found in parent call");return f?c.apply(a,Array.prototype.slice.call(arguments,1)):c.apply(b,arguments)}function i(){}function j(){var a=arguments,b=a.length;if(1>b)throw new Error("bad arguments");var c=null,d=b>1?a[0]:Object;if("function"!=typeof d&&"object"!=typeof d)throw new Error("base is not function or object");var e,f=a[b-1];if("function"!=typeof f&&"object"!=typeof f)throw new Error("constructor is not function or object");f instanceof Function&&(e=f,f={},e.call(f));var g=f.__metaclass__||d.__metaclass__||i,h=g.__new__(g,c,d,f);if(!h||"function"!=typeof h)throw new Error("__new__ method should return cls");return g.prototype.initialize.call(h,c,d,f),h}var k=!0;try{Object.defineProperty({},"a",{value:1})}catch(l){k=!1}Object.keys||(Object.keys=function(a){var b=[];if(void 0===a||null===a)return b;for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){for(var c=0;c - * @module oop - **/ -KISSY.add('gallery/oop/0.1/index',function (S, Node,Base) { - var EMPTY = ''; - var $ = Node.all; - /** - * - * @class Oop - * @constructor - * @extends Base - */ - function Oop(comConfig) { - var self = this; - //调用父类构造函数 - Oop.superclass.constructor.call(self, comConfig); - } - S.extend(Oop, Base, /** @lends Oop.prototype*/{ - - }, {ATTRS : /** @lends Oop*/{ - - }}); - return Oop; -}, {requires:['node', 'base']}); - - - +KISSY.add('gallery/oop/lib/oop',function() { + +// 无法通过 Object.defineProperty 判断是否支持,IE8 有此方法,但无法设置普通对象 +var supportDefineProperty = true; +try { + Object.defineProperty({}, 'a', {value: 1}); +} catch(e) { + supportDefineProperty = false; +} + +if (!Object.keys) { + Object.keys = function(o) { + var result = []; + if (o === undefined || o === null) { + return result; + } + + // 在Safari 5.0.2(7533.18.5)中,在这里用for in遍历parent会将prototype属性遍历出来,导致原型被指向一个错误的对象 + // 经过试验,在Safari下,仅仅通过 obj.prototype.xxx = xxx 这样的方式就会导致 prototype 变成自定义属性,会被 for in 出来 + // 而其他浏览器仅仅是在重新指向prototype时,类似 obj.prototype = {} 这样的写法才会出现这个情况 + // 因此,在使用时一定要注意 + for (var name in o) { + if (o.hasOwnProperty(name)) { + result.push(name); + } + } + + return result; + }; +} + +if (!Array.prototype.forEach) { + Array.prototype.forEach = function(fn, bind) { + for (var i = 0; i < this.length; i++) { + fn.call(bind, this[i], i, this); + } + }; +} + +if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function(str) { + for (var i = 0; i < this.length; i++) { + if (str === this[i]) { + return i; + } + } + return -1; + }; +} + +if (!Function.prototype.bind) { + Function.prototype.bind = function(object) { + var method = this; + var args = Array.prototype.slice.call(arguments, 1); + return function() { + return method.apply(object, args.concat(Array.prototype.slice.call(arguments))); + }; + }; +} + +function extend(obj, properties, ov) { + var filter = null; + if (typeof ov == 'function') { + filter = ov; + } else if (ov === true || typeof ov === 'undefined') { + filter = function(prop, dest, src) { + return true; + }; + } else { + filter = function(prop, dest, src) { + return !(prop in dest); + }; + } + + for (var property in properties) { + if (filter(property, obj, properties)) { + obj[property] = properties[property]; + } + } + if (properties && properties.hasOwnProperty('call') && filter(obj, properties, 'call')) { + obj.call = properties.call; + } + + return obj; +} + +// 仿照 mootools 的overloadsetter +// 返回一个 key/value 这种形式的function参数的包装,使其支持{key1: value1, key2: value2} 这种传参形式 +function overloadsetter(usePlural) { + var func; + function setter(a, b) { + if (a === null) return this; + if (usePlural || typeof a != 'string') { + for (var k in a) func.call(this, k, a[k]); + } else { + func.call(this, a, b); + } + return this; + }; + + if (typeof usePlural == 'function') { + func = usePlural; + usePlural = false; + } + + if (func) { + return setter; + } else { + return function(f) { + func = f; + return setter; + } + } +}; + +var getter = supportDefineProperty? function(name) { + return this[name]; +} : function(name) { + return this['__' + name + '_get'](); +}; + +var setter = supportDefineProperty? function(name, value) { + return this[name] = value; +} : function(name, value) { + return this['__' + name + '_set'](value); +} + +function instancemethod(func) { + return { + __class__: arguments.callee, + __func__: func + }; +} + +instancemethod.setTo = function(cls, name, member) { + var proto = cls.prototype; + member.__func__.__name__ = name; + proto[name] = member.__func__; +}; + +function staticmethod(func) { + return { + __class__: arguments.callee, + __func__: func + }; +} + +staticmethod.setTo = function(cls, name, member) { + var proto = cls.prototype; + cls[name] = proto[name] = member.__func__; +}; + +function property(fget, fset) { + var describer = { + __class__: arguments.callee, + fget: fget, + fset: fset + }; + return describer; +} + +property.setTo = function(cls, name, member) { + var proto = cls.prototype; + member.enumerable = true; + var type = cls.__metaclass__.prototype.__defaultmethodtype__; + if (member.fget) { + type.setTo(cls, '__' + name + '_get', type(member.fget)); + member.get = function() { + return this['__' + name + '_get'](); + }; + } + if (member.fset) { + type.setTo(cls, '__' + name + '_set', type(member.fset)); + member.set = function(value) { + return this['__' + name + '_set'](value); + }; + } + proto.__properties__[name] = member; + if (supportDefineProperty) { + Object.defineProperty(proto, name, member); + } +}; + +function nontypemember() {} + +nontypemember.setTo = function(cls, name, member) { + var proto = cls.prototype; + cls[name] = proto[name] = member; +}; + +function typeOf(obj) { + if (instanceOf(obj.__metaclass__, Type)) { + return 'type'; + } else { + return typeof obj; + } +} + +function instanceOf(obj, func) { + if (typeof func != 'function') { + throw new Error('bad arguments.'); + } + + var cls; + + // 查询一个func的constructor,js中的function是没有原型继承的,只能通过递归查询。 + // 一般来说就是Type + if (typeof obj == 'function') { + // 遍历实例的创建者继承链,找是否与func相同 + cls = obj.__class__; + if (cls) { + do { + if (cls === func) return true; + } while (cls = cls.__base__); + } + } + // 查询普通对象的constructor,可直接使用instanceof + else { + return obj instanceof func; + } + return false; + +} + +function makePrivate(proto, name) { + if (!supportDefineProperty) return; + + var member; + if (name.indexOf('__') == 0 && name.lastIndexOf('__') != name.length - 2) { + member = proto[name]; + Object.defineProperty(proto, name, { + get: function() { + if (this.constructor.prototype.hasOwnProperty(name)) { + return member; + } + }, + set: function(value) { + member = value; + } + }); + } +} + +function parent(self) { + var ownCls = self.__class__; // 拥有此方法的代码书写的类 + var name = arguments.callee.caller.__name__; // 方法名字 + var base, member; // 最后要执行的类和方法 + + if (!name) throw new Error('parent call error'); + + // parent应该调用“代码书写的方法所在的类的父同名方法” + // 而不是方法调用者实例的类的父同名方法 + // 比如C继承于B继承于A,当C的实例调用从B继承来的某方法时,其中调用了this.parent,应该直接调用到A上的同名方法,而不是B的。 + // 因此,这里通过hasOwnProperty,从当前类开始,向上找到同名方法的原始定义类 + while (ownCls && !ownCls.prototype.hasOwnProperty(name)) { + ownCls = ownCls.__base__; + } + + base = ownCls.__base__; + if (!base) throw new Error('base class not found in parent call'); + + var inProto = false; + if (base[name]) { + member = base[name]; + } else if (base.prototype[name]) { + member = base.prototype[name]; + inProto = true; + } + + if (!member || !member.apply) throw new Error('method not found in parent call'); + + if (inProto) { + return member.apply(self, Array.prototype.slice.call(arguments, 1)); + } else { + return member.apply(base, arguments); + } +} + +function Type() { + +} + +Type.__class__ = Type; + +Type.setTo = function(cls, name, member) { + cls[name] = cls.prototype[name] = member; +}; + +Type.__new__ = function(metaclass, name, base, dict) { + var cls = function() { + if (prototyping) return; + this.__class__ = cls; + var value = this.initialize? this.initialize.apply(this, arguments) : null; + return value; + }; + + var proto = Object.__new__(base); + cls.prototype = proto; + cls.prototype.constructor = cls; + cls.prototype.__properties__ = {}; + + for (var key in metaclass.prototype) { + cls[key] = metaclass.prototype[key]; + } + // Object.keys(metaclass.prototype).forEach(function(key) { + // cls[key] = metaclass.prototype[key]; + // }); + // cls.__proto__ = Object.create(base); + Object.keys(base).forEach(function(key) { + // private + if (key.indexOf('__') == 0 && key.lastIndexOf('__') != key.length - 2) { + return + } + cls[key] = base[key]; + }); + + cls.__base__ = base; + cls.__class__ = metaclass; + cls.__metaclass__ = metaclass; + cls.__dict__ = {}; + + (dict.__mixins__ || []).reverse().forEach(function(mixin) { + var chain = [mixin]; + var base = mixin; + while ((base = base.__base__)) { + chain.unshift(base); + } + chain.forEach(function(one) { + var dict, proto; + if (one.__dict__) { + dict = one.__dict__; + } else { + dict = {}; + proto = one.prototype; + Object.keys(proto).forEach(function(key) { + if (typeOf(proto[key]) == 'function') { + dict[key] = staticmethod(proto[key]); + } else { + dict[key] = proto[key]; + } + }); + } + Object.keys(dict).forEach(function(k) { + metaclass.prototype.__setattr__.call(cls, k, dict[k]); + }); + }); + }); + + Object.keys(dict).forEach(function(k) { + metaclass.prototype.__setattr__.call(cls, k, dict[k]); + }); + + cls.prototype.get = getter; + cls.prototype.set = setter; + + delete dict; + + return cls; +}; + +Type.prototype.initialize = function() { +}; + +Type.prototype.__setattr__ = function(name, member) { + var cls = this; + var proto = cls.prototype; + var memberType; + + // 动态添加的成员也可以在dict上找到 + cls.__dict__[name] = member; + + if (name == '__new__') { + member = staticmethod(member); + } + + if (member != undefined) { + if (!member.__class__ && typeof member == 'function') { + member = cls.__metaclass__.prototype.__defaultmethodtype__(member); + } + memberType = member.__class__ || nontypemember; + } else { + memberType = nontypemember; + } + + memberType.setTo(cls, name, member); + + makePrivate(proto, name); +}; + +Type.prototype.__defaultmethodtype__ = instancemethod; + +var prototyping = false; +Object.__new__ = function(cls) { + if (Object.create) { + return Object.create(cls.prototype); + } else { + prototyping = true; + var p = new cls; + prototyping = false; + return p; + } +}; + +function Class() { + var args = arguments; + var length = args.length; + if (length < 1) throw new Error('bad arguments'); + + // name + var name = null; + + // base + var base = length > 1? args[0] : Object; + if (typeof base != 'function' && typeof base != 'object') { + throw new Error('base is not function or object'); + } + + // dict + var dict = args[length - 1], factory; + if (typeof dict != 'function' && typeof dict != 'object') { + throw new Error('constructor is not function or object'); + } + if (dict instanceof Function) { + factory = dict; + dict = {}; + factory.call(dict); + } + + var metaclass = dict.__metaclass__ || base.__metaclass__ || Type; + + // 创建&初始化 + var cls = metaclass.__new__(metaclass, name, base, dict); + + if (!cls || typeof cls != 'function') { + throw new Error('__new__ method should return cls'); + } + + metaclass.prototype.initialize.call(cls, name, base, dict); + + return cls; +} + +exports.Class = Class; +exports.Type = Type; +exports.staticmethod = staticmethod; +exports.property = property; +exports.parent = parent; +exports.instanceOf = instanceOf; +exports.typeOf = typeOf; +exports.install = function(target) { + if (!target) target = global; + ['Class', 'Type', 'classmethod', 'staticmethod', 'property'].forEach(function(name) { + target[name] = exports[name]; + }) +}; + +}) diff --git a/0.1/index.js b/0.1/index.js deleted file mode 100644 index da2b735..0000000 --- a/0.1/index.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @fileoverview - * @author goto100 - * @module oop - **/ -KISSY.add(function (S, Node,Base) { - var EMPTY = ''; - var $ = Node.all; - /** - * - * @class Oop - * @constructor - * @extends Base - */ - function Oop(comConfig) { - var self = this; - //调用父类构造函数 - Oop.superclass.constructor.call(self, comConfig); - } - S.extend(Oop, Base, /** @lends Oop.prototype*/{ - - }, {ATTRS : /** @lends Oop*/{ - - }}); - return Oop; -}, {requires:['node', 'base']}); - - - diff --git a/Gruntfile.js b/Gruntfile.js index aaff4ae..fdcd2f0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -27,7 +27,7 @@ module.exports = function(grunt) { main: { files: [ { - src: "<%= pkg.version %>/index.js", + src: "lib/oop.js", dest: "<%= pkg.version %>/build/index.js" } ] diff --git a/index.js b/index.js deleted file mode 100644 index a219fbb..0000000 --- a/index.js +++ /dev/null @@ -1,461 +0,0 @@ -KISSY.add('oop', function() { - -var exports = {}; - -// 无法通过 Object.defineProperty 判断是否支持,IE8 有此方法,但无法设置普通对象 -var supportDefineProperty = true; -try { - Object.defineProperty({}, 'a', {value: 1}); -} catch(e) { - supportDefineProperty = false; -} - -if (!Object.keys) { - Object.keys = function(o) { - var result = []; - if (o === undefined || o === null) { - return result; - } - - // 在Safari 5.0.2(7533.18.5)中,在这里用for in遍历parent会将prototype属性遍历出来,导致原型被指向一个错误的对象 - // 经过试验,在Safari下,仅仅通过 obj.prototype.xxx = xxx 这样的方式就会导致 prototype 变成自定义属性,会被 for in 出来 - // 而其他浏览器仅仅是在重新指向prototype时,类似 obj.prototype = {} 这样的写法才会出现这个情况 - // 因此,在使用时一定要注意 - for (var name in o) { - if (o.hasOwnProperty(name)) { - result.push(name); - } - } - - return result; - }; -} - -if (!Array.prototype.forEach) { - Array.prototype.forEach = function(fn, bind) { - for (var i = 0; i < this.length; i++) { - fn.call(bind, this[i], i, this); - } - }; -} - -if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function(str) { - for (var i = 0; i < this.length; i++) { - if (str === this[i]) { - return i; - } - } - return -1; - }; -} - -if (!Function.prototype.bind) { - Function.prototype.bind = function(object) { - var method = this; - var args = Array.prototype.slice.call(arguments, 1); - return function() { - return method.apply(object, args.concat(Array.prototype.slice.call(arguments))); - }; - }; -} - -function extend(obj, properties, ov) { - var filter = null; - if (typeof ov == 'function') { - filter = ov; - } else if (ov === true || typeof ov === 'undefined') { - filter = function(prop, dest, src) { - return true; - }; - } else { - filter = function(prop, dest, src) { - return !(prop in dest); - }; - } - - for (var property in properties) { - if (filter(property, obj, properties)) { - obj[property] = properties[property]; - } - } - if (properties && properties.hasOwnProperty('call') && filter(obj, properties, 'call')) { - obj.call = properties.call; - } - - return obj; -} - -// 仿照 mootools 的overloadsetter -// 返回一个 key/value 这种形式的function参数的包装,使其支持{key1: value1, key2: value2} 这种传参形式 -function overloadsetter(usePlural) { - var func; - function setter(a, b) { - if (a === null) return this; - if (usePlural || typeof a != 'string') { - for (var k in a) func.call(this, k, a[k]); - } else { - func.call(this, a, b); - } - return this; - }; - - if (typeof usePlural == 'function') { - func = usePlural; - usePlural = false; - } - - if (func) { - return setter; - } else { - return function(f) { - func = f; - return setter; - } - } -}; - -var getter = supportDefineProperty? function(name) { - return this[name]; -} : function(name) { - return this['__' + name + '_get'](); -}; - -var setter = supportDefineProperty? function(name, value) { - return this[name] = value; -} : function(name, value) { - return this['__' + name + '_set'](value); -} - -function instancemethod(func) { - return { - __class__: arguments.callee, - __func__: func - }; -} - -instancemethod.setTo = function(cls, name, member) { - var proto = cls.prototype; - member.__func__.__name__ = name; - proto[name] = member.__func__; -}; - -function staticmethod(func) { - return { - __class__: arguments.callee, - __func__: func - }; -} - -staticmethod.setTo = function(cls, name, member) { - var proto = cls.prototype; - cls[name] = proto[name] = member.__func__; -}; - -function property(fget, fset) { - var describer = { - __class__: arguments.callee, - fget: fget, - fset: fset - }; - return describer; -} - -property.setTo = function(cls, name, member) { - var proto = cls.prototype; - member.enumerable = true; - var type = cls.__metaclass__.prototype.__defaultmethodtype__; - if (member.fget) { - type.setTo(cls, '__' + name + '_get', type(member.fget)); - member.get = function() { - return this['__' + name + '_get'](); - }; - } - if (member.fset) { - type.setTo(cls, '__' + name + '_set', type(member.fset)); - member.set = function(value) { - return this['__' + name + '_set'](value); - }; - } - proto.__properties__[name] = member; - if (supportDefineProperty) { - Object.defineProperty(proto, name, member); - } -}; - -function nontypemember() {} - -nontypemember.setTo = function(cls, name, member) { - var proto = cls.prototype; - cls[name] = proto[name] = member; -}; - -function typeOf(obj) { - if (instanceOf(obj.__metaclass__, Type)) { - return 'type'; - } else { - return typeof obj; - } -} - -function instanceOf(obj, func) { - if (typeof func != 'function') { - throw new Error('bad arguments.'); - } - - var cls; - - // 查询一个func的constructor,js中的function是没有原型继承的,只能通过递归查询。 - // 一般来说就是Type - if (typeof obj == 'function') { - // 遍历实例的创建者继承链,找是否与func相同 - cls = obj.__class__; - if (cls) { - do { - if (cls === func) return true; - } while (cls = cls.__base__); - } - } - // 查询普通对象的constructor,可直接使用instanceof - else { - return obj instanceof func; - } - return false; - -} - -function makePrivate(proto, name) { - if (!supportDefineProperty) return; - - var member; - if (name.indexOf('__') == 0 && name.lastIndexOf('__') != name.length - 2) { - member = proto[name]; - Object.defineProperty(proto, name, { - get: function() { - if (this.constructor.prototype.hasOwnProperty(name)) { - return member; - } - }, - set: function(value) { - member = value; - } - }); - } -} - -function parent(self) { - var ownCls = self.__class__; // 拥有此方法的代码书写的类 - var name = arguments.callee.caller.__name__; // 方法名字 - var base, member; // 最后要执行的类和方法 - - if (!name) throw new Error('parent call error'); - - // parent应该调用“代码书写的方法所在的类的父同名方法” - // 而不是方法调用者实例的类的父同名方法 - // 比如C继承于B继承于A,当C的实例调用从B继承来的某方法时,其中调用了this.parent,应该直接调用到A上的同名方法,而不是B的。 - // 因此,这里通过hasOwnProperty,从当前类开始,向上找到同名方法的原始定义类 - while (ownCls && !ownCls.prototype.hasOwnProperty(name)) { - ownCls = ownCls.__base__; - } - - base = ownCls.__base__; - if (!base) throw new Error('base class not found in parent call'); - - var inProto = false; - if (base[name]) { - member = base[name]; - } else if (base.prototype[name]) { - member = base.prototype[name]; - inProto = true; - } - - if (!member || !member.apply) throw new Error('method not found in parent call'); - - if (inProto) { - return member.apply(self, Array.prototype.slice.call(arguments, 1)); - } else { - return member.apply(base, arguments); - } -} - -function Type() { - -} - -Type.__class__ = Type; - -Type.setTo = function(cls, name, member) { - cls[name] = cls.prototype[name] = member; -}; - -Type.__new__ = function(metaclass, name, base, dict) { - var cls = function() { - if (prototyping) return; - this.__class__ = cls; - var value = this.initialize? this.initialize.apply(this, arguments) : null; - return value; - }; - - var proto = Object.__new__(base); - cls.prototype = proto; - cls.prototype.constructor = cls; - cls.prototype.__properties__ = {}; - - for (var key in metaclass.prototype) { - cls[key] = metaclass.prototype[key]; - } - // Object.keys(metaclass.prototype).forEach(function(key) { - // cls[key] = metaclass.prototype[key]; - // }); - // cls.__proto__ = Object.create(base); - Object.keys(base).forEach(function(key) { - // private - if (key.indexOf('__') == 0 && key.lastIndexOf('__') != key.length - 2) { - return - } - cls[key] = base[key]; - }); - - cls.__base__ = base; - cls.__class__ = metaclass; - cls.__metaclass__ = metaclass; - cls.__dict__ = {}; - - (dict.__mixins__ || []).reverse().forEach(function(mixin) { - var chain = [mixin]; - var base = mixin; - while ((base = base.__base__)) { - chain.unshift(base); - } - chain.forEach(function(one) { - var dict, proto; - if (one.__dict__) { - dict = one.__dict__; - } else { - dict = {}; - proto = one.prototype; - Object.keys(proto).forEach(function(key) { - if (typeOf(proto[key]) == 'function') { - dict[key] = staticmethod(proto[key]); - } else { - dict[key] = proto[key]; - } - }); - } - Object.keys(dict).forEach(function(k) { - metaclass.prototype.__setattr__.call(cls, k, dict[k]); - }); - }); - }); - - Object.keys(dict).forEach(function(k) { - metaclass.prototype.__setattr__.call(cls, k, dict[k]); - }); - - cls.prototype.get = getter; - cls.prototype.set = setter; - - delete dict; - - return cls; -}; - -Type.prototype.initialize = function() { -}; - -Type.prototype.__setattr__ = function(name, member) { - var cls = this; - var proto = cls.prototype; - var memberType; - - // 动态添加的成员也可以在dict上找到 - cls.__dict__[name] = member; - - if (name == '__new__') { - member = staticmethod(member); - } - - if (member != undefined) { - if (!member.__class__ && typeof member == 'function') { - member = cls.__metaclass__.prototype.__defaultmethodtype__(member); - } - memberType = member.__class__ || nontypemember; - } else { - memberType = nontypemember; - } - - memberType.setTo(cls, name, member); - - makePrivate(proto, name); -}; - -Type.prototype.__defaultmethodtype__ = instancemethod; - -var prototyping = false; -Object.__new__ = function(cls) { - if (Object.create) { - return Object.create(cls.prototype); - } else { - prototyping = true; - var p = new cls; - prototyping = false; - return p; - } -}; - -function Class() { - var args = arguments; - var length = args.length; - if (length < 1) throw new Error('bad arguments'); - - // name - var name = null; - - // base - var base = length > 1? args[0] : Object; - if (typeof base != 'function' && typeof base != 'object') { - throw new Error('base is not function or object'); - } - - // dict - var dict = args[length - 1], factory; - if (typeof dict != 'function' && typeof dict != 'object') { - throw new Error('constructor is not function or object'); - } - if (dict instanceof Function) { - factory = dict; - dict = {}; - factory.call(dict); - } - - var metaclass = dict.__metaclass__ || base.__metaclass__ || Type; - - // 创建&初始化 - var cls = metaclass.__new__(metaclass, name, base, dict); - - if (!cls || typeof cls != 'function') { - throw new Error('__new__ method should return cls'); - } - - metaclass.prototype.initialize.call(cls, name, base, dict); - - return cls; -} - -exports.Class = Class; -exports.Type = Type; -exports.staticmethod = staticmethod; -exports.property = property; -exports.parent = parent; -exports.instanceOf = instanceOf; -exports.typeOf = typeOf; -exports.install = function(target) { - if (!target) target = global; - ['Class', 'Type', 'classmethod', 'staticmethod', 'property'].forEach(function(name) { - target[name] = exports[name]; - }) -}; - -return exports; - -}); \ No newline at end of file diff --git a/lib/oop.js b/lib/oop.js index 7cdffe0..1ccbc4f 100644 --- a/lib/oop.js +++ b/lib/oop.js @@ -1,3 +1,5 @@ +KISSY.add(function() { + // 无法通过 Object.defineProperty 判断是否支持,IE8 有此方法,但无法设置普通对象 var supportDefineProperty = true; try { @@ -451,3 +453,5 @@ exports.install = function(target) { target[name] = exports[name]; }) }; + +}) From aa04f54ef7022893efbc35a6e50c8658429d5fd5 Mon Sep 17 00:00:00 2001 From: goto100 Date: Thu, 5 Sep 2013 10:25:45 +0800 Subject: [PATCH 06/13] version in KISSY.add --- 0.1/build/index-min.js | 4 ++-- 0.1/build/index.js | 4 ++-- Gruntfile.js | 24 +++++++++++++----------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/0.1/build/index-min.js b/0.1/build/index-min.js index d9d1d76..1e2e244 100644 --- a/0.1/build/index-min.js +++ b/0.1/build/index-min.js @@ -1,3 +1,3 @@ -/*! oop - v0.1 - 2013-09-03 5:11:21 PM +/*! oop - v0.1 - 2013-09-05 10:25:04 AM * Copyright (c) 2013 goto100; Licensed */ -KISSY.add("gallery/oop/lib/oop",function(){function a(a){return{__class__:arguments.callee,__func__:a}}function b(a){return{__class__:arguments.callee,__func__:a}}function c(a,b){var c={__class__:arguments.callee,fget:a,fset:b};return c}function d(){}function e(a){return f(a.__metaclass__,i)?"type":typeof a}function f(a,b){if("function"!=typeof b)throw new Error("bad arguments.");var c;if("function"!=typeof a)return a instanceof b;if(c=a.__class__)do if(c===b)return!0;while(c=c.__base__);return!1}function g(a,b){if(k){var c;0==b.indexOf("__")&&b.lastIndexOf("__")!=b.length-2&&(c=a[b],Object.defineProperty(a,b,{get:function(){return this.constructor.prototype.hasOwnProperty(b)?c:void 0},set:function(a){c=a}}))}}function h(a){var b,c,d=a.__class__,e=arguments.callee.caller.__name__;if(!e)throw new Error("parent call error");for(;d&&!d.prototype.hasOwnProperty(e);)d=d.__base__;if(b=d.__base__,!b)throw new Error("base class not found in parent call");var f=!1;if(b[e]?c=b[e]:b.prototype[e]&&(c=b.prototype[e],f=!0),!c||!c.apply)throw new Error("method not found in parent call");return f?c.apply(a,Array.prototype.slice.call(arguments,1)):c.apply(b,arguments)}function i(){}function j(){var a=arguments,b=a.length;if(1>b)throw new Error("bad arguments");var c=null,d=b>1?a[0]:Object;if("function"!=typeof d&&"object"!=typeof d)throw new Error("base is not function or object");var e,f=a[b-1];if("function"!=typeof f&&"object"!=typeof f)throw new Error("constructor is not function or object");f instanceof Function&&(e=f,f={},e.call(f));var g=f.__metaclass__||d.__metaclass__||i,h=g.__new__(g,c,d,f);if(!h||"function"!=typeof h)throw new Error("__new__ method should return cls");return g.prototype.initialize.call(h,c,d,f),h}var k=!0;try{Object.defineProperty({},"a",{value:1})}catch(l){k=!1}Object.keys||(Object.keys=function(a){var b=[];if(void 0===a||null===a)return b;for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){for(var c=0;cb)throw new Error("bad arguments");var c=null,d=b>1?a[0]:Object;if("function"!=typeof d&&"object"!=typeof d)throw new Error("base is not function or object");var e,f=a[b-1];if("function"!=typeof f&&"object"!=typeof f)throw new Error("constructor is not function or object");f instanceof Function&&(e=f,f={},e.call(f));var g=f.__metaclass__||d.__metaclass__||i,h=g.__new__(g,c,d,f);if(!h||"function"!=typeof h)throw new Error("__new__ method should return cls");return g.prototype.initialize.call(h,c,d,f),h}var k=!0;try{Object.defineProperty({},"a",{value:1})}catch(l){k=!1}Object.keys||(Object.keys=function(a){var b=[];if(void 0===a||null===a)return b;for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){for(var c=0;c <%= pkg.author.name %>;' + ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n', + copy: { + main: { + files: [ + {src: ['lib/oop.js'], dest: '<%= pkg.version %>/index.js'}, + {src: ['<%= pkg.version %>/index.css'], dest: '<%= pkg.version %>/build/index.css'} + ] + } + }, + // kmc打包任务,默认情况,入口文件是index.js,可以自行添加入口文件,在files下面 // 添加 kmc: { @@ -27,7 +36,7 @@ module.exports = function(grunt) { main: { files: [ { - src: "lib/oop.js", + src: "<%= pkg.version %>/index.js", dest: "<%= pkg.version %>/build/index.js" } ] @@ -48,13 +57,6 @@ module.exports = function(grunt) { } } }, - copy: { - main: { - files: [ - {src: ['<%= pkg.version %>/index.css'], dest: '<%= pkg.version %>/build/index.css'} - ] - } - }, cssmin: { combine: { files: { @@ -65,9 +67,9 @@ module.exports = function(grunt) { }); // 使用到的任务,可以增加其他任务 - grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-kmc'); grunt.loadNpmTasks('grunt-contrib-cssmin'); - grunt.loadNpmTasks('grunt-contrib-copy'); - return grunt.registerTask('default', ['kmc', 'uglify']); + grunt.loadNpmTasks('grunt-contrib-uglify'); + return grunt.registerTask('default', ['copy', 'kmc', 'uglify']); }; \ No newline at end of file From 4493c730308f5b488fc136d604f7caae5112a9b2 Mon Sep 17 00:00:00 2001 From: goto100 Date: Thu, 5 Sep 2013 10:49:41 +0800 Subject: [PATCH 07/13] forget file --- 0.1/index.js | 457 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 457 insertions(+) create mode 100644 0.1/index.js diff --git a/0.1/index.js b/0.1/index.js new file mode 100644 index 0000000..1ccbc4f --- /dev/null +++ b/0.1/index.js @@ -0,0 +1,457 @@ +KISSY.add(function() { + +// 无法通过 Object.defineProperty 判断是否支持,IE8 有此方法,但无法设置普通对象 +var supportDefineProperty = true; +try { + Object.defineProperty({}, 'a', {value: 1}); +} catch(e) { + supportDefineProperty = false; +} + +if (!Object.keys) { + Object.keys = function(o) { + var result = []; + if (o === undefined || o === null) { + return result; + } + + // 在Safari 5.0.2(7533.18.5)中,在这里用for in遍历parent会将prototype属性遍历出来,导致原型被指向一个错误的对象 + // 经过试验,在Safari下,仅仅通过 obj.prototype.xxx = xxx 这样的方式就会导致 prototype 变成自定义属性,会被 for in 出来 + // 而其他浏览器仅仅是在重新指向prototype时,类似 obj.prototype = {} 这样的写法才会出现这个情况 + // 因此,在使用时一定要注意 + for (var name in o) { + if (o.hasOwnProperty(name)) { + result.push(name); + } + } + + return result; + }; +} + +if (!Array.prototype.forEach) { + Array.prototype.forEach = function(fn, bind) { + for (var i = 0; i < this.length; i++) { + fn.call(bind, this[i], i, this); + } + }; +} + +if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function(str) { + for (var i = 0; i < this.length; i++) { + if (str === this[i]) { + return i; + } + } + return -1; + }; +} + +if (!Function.prototype.bind) { + Function.prototype.bind = function(object) { + var method = this; + var args = Array.prototype.slice.call(arguments, 1); + return function() { + return method.apply(object, args.concat(Array.prototype.slice.call(arguments))); + }; + }; +} + +function extend(obj, properties, ov) { + var filter = null; + if (typeof ov == 'function') { + filter = ov; + } else if (ov === true || typeof ov === 'undefined') { + filter = function(prop, dest, src) { + return true; + }; + } else { + filter = function(prop, dest, src) { + return !(prop in dest); + }; + } + + for (var property in properties) { + if (filter(property, obj, properties)) { + obj[property] = properties[property]; + } + } + if (properties && properties.hasOwnProperty('call') && filter(obj, properties, 'call')) { + obj.call = properties.call; + } + + return obj; +} + +// 仿照 mootools 的overloadsetter +// 返回一个 key/value 这种形式的function参数的包装,使其支持{key1: value1, key2: value2} 这种传参形式 +function overloadsetter(usePlural) { + var func; + function setter(a, b) { + if (a === null) return this; + if (usePlural || typeof a != 'string') { + for (var k in a) func.call(this, k, a[k]); + } else { + func.call(this, a, b); + } + return this; + }; + + if (typeof usePlural == 'function') { + func = usePlural; + usePlural = false; + } + + if (func) { + return setter; + } else { + return function(f) { + func = f; + return setter; + } + } +}; + +var getter = supportDefineProperty? function(name) { + return this[name]; +} : function(name) { + return this['__' + name + '_get'](); +}; + +var setter = supportDefineProperty? function(name, value) { + return this[name] = value; +} : function(name, value) { + return this['__' + name + '_set'](value); +} + +function instancemethod(func) { + return { + __class__: arguments.callee, + __func__: func + }; +} + +instancemethod.setTo = function(cls, name, member) { + var proto = cls.prototype; + member.__func__.__name__ = name; + proto[name] = member.__func__; +}; + +function staticmethod(func) { + return { + __class__: arguments.callee, + __func__: func + }; +} + +staticmethod.setTo = function(cls, name, member) { + var proto = cls.prototype; + cls[name] = proto[name] = member.__func__; +}; + +function property(fget, fset) { + var describer = { + __class__: arguments.callee, + fget: fget, + fset: fset + }; + return describer; +} + +property.setTo = function(cls, name, member) { + var proto = cls.prototype; + member.enumerable = true; + var type = cls.__metaclass__.prototype.__defaultmethodtype__; + if (member.fget) { + type.setTo(cls, '__' + name + '_get', type(member.fget)); + member.get = function() { + return this['__' + name + '_get'](); + }; + } + if (member.fset) { + type.setTo(cls, '__' + name + '_set', type(member.fset)); + member.set = function(value) { + return this['__' + name + '_set'](value); + }; + } + proto.__properties__[name] = member; + if (supportDefineProperty) { + Object.defineProperty(proto, name, member); + } +}; + +function nontypemember() {} + +nontypemember.setTo = function(cls, name, member) { + var proto = cls.prototype; + cls[name] = proto[name] = member; +}; + +function typeOf(obj) { + if (instanceOf(obj.__metaclass__, Type)) { + return 'type'; + } else { + return typeof obj; + } +} + +function instanceOf(obj, func) { + if (typeof func != 'function') { + throw new Error('bad arguments.'); + } + + var cls; + + // 查询一个func的constructor,js中的function是没有原型继承的,只能通过递归查询。 + // 一般来说就是Type + if (typeof obj == 'function') { + // 遍历实例的创建者继承链,找是否与func相同 + cls = obj.__class__; + if (cls) { + do { + if (cls === func) return true; + } while (cls = cls.__base__); + } + } + // 查询普通对象的constructor,可直接使用instanceof + else { + return obj instanceof func; + } + return false; + +} + +function makePrivate(proto, name) { + if (!supportDefineProperty) return; + + var member; + if (name.indexOf('__') == 0 && name.lastIndexOf('__') != name.length - 2) { + member = proto[name]; + Object.defineProperty(proto, name, { + get: function() { + if (this.constructor.prototype.hasOwnProperty(name)) { + return member; + } + }, + set: function(value) { + member = value; + } + }); + } +} + +function parent(self) { + var ownCls = self.__class__; // 拥有此方法的代码书写的类 + var name = arguments.callee.caller.__name__; // 方法名字 + var base, member; // 最后要执行的类和方法 + + if (!name) throw new Error('parent call error'); + + // parent应该调用“代码书写的方法所在的类的父同名方法” + // 而不是方法调用者实例的类的父同名方法 + // 比如C继承于B继承于A,当C的实例调用从B继承来的某方法时,其中调用了this.parent,应该直接调用到A上的同名方法,而不是B的。 + // 因此,这里通过hasOwnProperty,从当前类开始,向上找到同名方法的原始定义类 + while (ownCls && !ownCls.prototype.hasOwnProperty(name)) { + ownCls = ownCls.__base__; + } + + base = ownCls.__base__; + if (!base) throw new Error('base class not found in parent call'); + + var inProto = false; + if (base[name]) { + member = base[name]; + } else if (base.prototype[name]) { + member = base.prototype[name]; + inProto = true; + } + + if (!member || !member.apply) throw new Error('method not found in parent call'); + + if (inProto) { + return member.apply(self, Array.prototype.slice.call(arguments, 1)); + } else { + return member.apply(base, arguments); + } +} + +function Type() { + +} + +Type.__class__ = Type; + +Type.setTo = function(cls, name, member) { + cls[name] = cls.prototype[name] = member; +}; + +Type.__new__ = function(metaclass, name, base, dict) { + var cls = function() { + if (prototyping) return; + this.__class__ = cls; + var value = this.initialize? this.initialize.apply(this, arguments) : null; + return value; + }; + + var proto = Object.__new__(base); + cls.prototype = proto; + cls.prototype.constructor = cls; + cls.prototype.__properties__ = {}; + + for (var key in metaclass.prototype) { + cls[key] = metaclass.prototype[key]; + } + // Object.keys(metaclass.prototype).forEach(function(key) { + // cls[key] = metaclass.prototype[key]; + // }); + // cls.__proto__ = Object.create(base); + Object.keys(base).forEach(function(key) { + // private + if (key.indexOf('__') == 0 && key.lastIndexOf('__') != key.length - 2) { + return + } + cls[key] = base[key]; + }); + + cls.__base__ = base; + cls.__class__ = metaclass; + cls.__metaclass__ = metaclass; + cls.__dict__ = {}; + + (dict.__mixins__ || []).reverse().forEach(function(mixin) { + var chain = [mixin]; + var base = mixin; + while ((base = base.__base__)) { + chain.unshift(base); + } + chain.forEach(function(one) { + var dict, proto; + if (one.__dict__) { + dict = one.__dict__; + } else { + dict = {}; + proto = one.prototype; + Object.keys(proto).forEach(function(key) { + if (typeOf(proto[key]) == 'function') { + dict[key] = staticmethod(proto[key]); + } else { + dict[key] = proto[key]; + } + }); + } + Object.keys(dict).forEach(function(k) { + metaclass.prototype.__setattr__.call(cls, k, dict[k]); + }); + }); + }); + + Object.keys(dict).forEach(function(k) { + metaclass.prototype.__setattr__.call(cls, k, dict[k]); + }); + + cls.prototype.get = getter; + cls.prototype.set = setter; + + delete dict; + + return cls; +}; + +Type.prototype.initialize = function() { +}; + +Type.prototype.__setattr__ = function(name, member) { + var cls = this; + var proto = cls.prototype; + var memberType; + + // 动态添加的成员也可以在dict上找到 + cls.__dict__[name] = member; + + if (name == '__new__') { + member = staticmethod(member); + } + + if (member != undefined) { + if (!member.__class__ && typeof member == 'function') { + member = cls.__metaclass__.prototype.__defaultmethodtype__(member); + } + memberType = member.__class__ || nontypemember; + } else { + memberType = nontypemember; + } + + memberType.setTo(cls, name, member); + + makePrivate(proto, name); +}; + +Type.prototype.__defaultmethodtype__ = instancemethod; + +var prototyping = false; +Object.__new__ = function(cls) { + if (Object.create) { + return Object.create(cls.prototype); + } else { + prototyping = true; + var p = new cls; + prototyping = false; + return p; + } +}; + +function Class() { + var args = arguments; + var length = args.length; + if (length < 1) throw new Error('bad arguments'); + + // name + var name = null; + + // base + var base = length > 1? args[0] : Object; + if (typeof base != 'function' && typeof base != 'object') { + throw new Error('base is not function or object'); + } + + // dict + var dict = args[length - 1], factory; + if (typeof dict != 'function' && typeof dict != 'object') { + throw new Error('constructor is not function or object'); + } + if (dict instanceof Function) { + factory = dict; + dict = {}; + factory.call(dict); + } + + var metaclass = dict.__metaclass__ || base.__metaclass__ || Type; + + // 创建&初始化 + var cls = metaclass.__new__(metaclass, name, base, dict); + + if (!cls || typeof cls != 'function') { + throw new Error('__new__ method should return cls'); + } + + metaclass.prototype.initialize.call(cls, name, base, dict); + + return cls; +} + +exports.Class = Class; +exports.Type = Type; +exports.staticmethod = staticmethod; +exports.property = property; +exports.parent = parent; +exports.instanceOf = instanceOf; +exports.typeOf = typeOf; +exports.install = function(target) { + if (!target) target = global; + ['Class', 'Type', 'classmethod', 'staticmethod', 'property'].forEach(function(name) { + target[name] = exports[name]; + }) +}; + +}) From 69f8ccbeaa9c7b8699b6d5a74a6920f50b3571bc Mon Sep 17 00:00:00 2001 From: goto100 Date: Thu, 5 Sep 2013 14:29:38 +0800 Subject: [PATCH 08/13] kissy loader --- lib/oop.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/oop.js b/lib/oop.js index 1ccbc4f..e0833a5 100644 --- a/lib/oop.js +++ b/lib/oop.js @@ -1,5 +1,7 @@ KISSY.add(function() { +var exports = {}; + // 无法通过 Object.defineProperty 判断是否支持,IE8 有此方法,但无法设置普通对象 var supportDefineProperty = true; try { @@ -454,4 +456,6 @@ exports.install = function(target) { }) }; +return exports; + }) From 9696927d2381a2a7ee848f296138a8a4e5e16bf4 Mon Sep 17 00:00:00 2001 From: goto100 Date: Thu, 5 Sep 2013 14:44:49 +0800 Subject: [PATCH 09/13] build --- 0.1/build/index-min.js | 4 ++-- 0.1/build/index.js | 4 ++++ 0.1/index.js | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/0.1/build/index-min.js b/0.1/build/index-min.js index 1e2e244..69e7144 100644 --- a/0.1/build/index-min.js +++ b/0.1/build/index-min.js @@ -1,3 +1,3 @@ -/*! oop - v0.1 - 2013-09-05 10:25:04 AM +/*! oop - v0.1 - 2013-09-05 2:44:41 PM * Copyright (c) 2013 goto100; Licensed */ -KISSY.add("gallery/oop/0.1/index",function(){function a(a){return{__class__:arguments.callee,__func__:a}}function b(a){return{__class__:arguments.callee,__func__:a}}function c(a,b){var c={__class__:arguments.callee,fget:a,fset:b};return c}function d(){}function e(a){return f(a.__metaclass__,i)?"type":typeof a}function f(a,b){if("function"!=typeof b)throw new Error("bad arguments.");var c;if("function"!=typeof a)return a instanceof b;if(c=a.__class__)do if(c===b)return!0;while(c=c.__base__);return!1}function g(a,b){if(k){var c;0==b.indexOf("__")&&b.lastIndexOf("__")!=b.length-2&&(c=a[b],Object.defineProperty(a,b,{get:function(){return this.constructor.prototype.hasOwnProperty(b)?c:void 0},set:function(a){c=a}}))}}function h(a){var b,c,d=a.__class__,e=arguments.callee.caller.__name__;if(!e)throw new Error("parent call error");for(;d&&!d.prototype.hasOwnProperty(e);)d=d.__base__;if(b=d.__base__,!b)throw new Error("base class not found in parent call");var f=!1;if(b[e]?c=b[e]:b.prototype[e]&&(c=b.prototype[e],f=!0),!c||!c.apply)throw new Error("method not found in parent call");return f?c.apply(a,Array.prototype.slice.call(arguments,1)):c.apply(b,arguments)}function i(){}function j(){var a=arguments,b=a.length;if(1>b)throw new Error("bad arguments");var c=null,d=b>1?a[0]:Object;if("function"!=typeof d&&"object"!=typeof d)throw new Error("base is not function or object");var e,f=a[b-1];if("function"!=typeof f&&"object"!=typeof f)throw new Error("constructor is not function or object");f instanceof Function&&(e=f,f={},e.call(f));var g=f.__metaclass__||d.__metaclass__||i,h=g.__new__(g,c,d,f);if(!h||"function"!=typeof h)throw new Error("__new__ method should return cls");return g.prototype.initialize.call(h,c,d,f),h}var k=!0;try{Object.defineProperty({},"a",{value:1})}catch(l){k=!1}Object.keys||(Object.keys=function(a){var b=[];if(void 0===a||null===a)return b;for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){for(var c=0;cb)throw new Error("bad arguments");var c=null,d=b>1?a[0]:Object;if("function"!=typeof d&&"object"!=typeof d)throw new Error("base is not function or object");var e,f=a[b-1];if("function"!=typeof f&&"object"!=typeof f)throw new Error("constructor is not function or object");f instanceof Function&&(e=f,f={},e.call(f));var g=f.__metaclass__||d.__metaclass__||i,h=g.__new__(g,c,d,f);if(!h||"function"!=typeof h)throw new Error("__new__ method should return cls");return g.prototype.initialize.call(h,c,d,f),h}var k={},l=!0;try{Object.defineProperty({},"a",{value:1})}catch(m){l=!1}Object.keys||(Object.keys=function(a){var b=[];if(void 0===a||null===a)return b;for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){for(var c=0;c Date: Wed, 11 Sep 2013 16:13:30 +0800 Subject: [PATCH 10/13] default install to window --- lib/oop.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/oop.js b/lib/oop.js index fbe7031..75e2c8c 100644 --- a/lib/oop.js +++ b/lib/oop.js @@ -459,7 +459,7 @@ exports.parent = parent; exports.instanceOf = instanceOf; exports.typeOf = typeOf; exports.install = function(target) { - if (!target) target = global; + if (!target) target = window; ['Class', 'Type', 'classmethod', 'staticmethod', 'property'].forEach(function(name) { target[name] = exports[name]; }) From f8ce6f86d147a60e83f0a6f08b3e737741bc996b Mon Sep 17 00:00:00 2001 From: goto100 Date: Wed, 11 Sep 2013 16:16:03 +0800 Subject: [PATCH 11/13] doc changed for gallery --- 0.1/build/index-min.js | 4 +-- 0.1/build/index.js | 77 +++++++++++++++++++++++------------------- 0.1/demo/index.html | 22 ++++++++++-- 0.1/guide/index.md | 9 +++-- 0.1/index.js | 77 +++++++++++++++++++++++------------------- 0.1/meta/alias.js | 2 +- 6 files changed, 113 insertions(+), 78 deletions(-) diff --git a/0.1/build/index-min.js b/0.1/build/index-min.js index 69e7144..14219ab 100644 --- a/0.1/build/index-min.js +++ b/0.1/build/index-min.js @@ -1,3 +1,3 @@ -/*! oop - v0.1 - 2013-09-05 2:44:41 PM +/*! oop - v0.1 - 2013-09-11 4:10:47 PM * Copyright (c) 2013 goto100; Licensed */ -KISSY.add("gallery/oop/0.1/index",function(){function a(a){return{__class__:arguments.callee,__func__:a}}function b(a){return{__class__:arguments.callee,__func__:a}}function c(a,b){var c={__class__:arguments.callee,fget:a,fset:b};return c}function d(){}function e(a){return f(a.__metaclass__,i)?"type":typeof a}function f(a,b){if("function"!=typeof b)throw new Error("bad arguments.");var c;if("function"!=typeof a)return a instanceof b;if(c=a.__class__)do if(c===b)return!0;while(c=c.__base__);return!1}function g(a,b){if(l){var c;0==b.indexOf("__")&&b.lastIndexOf("__")!=b.length-2&&(c=a[b],Object.defineProperty(a,b,{get:function(){return this.constructor.prototype.hasOwnProperty(b)?c:void 0},set:function(a){c=a}}))}}function h(a){var b,c,d=a.__class__,e=arguments.callee.caller.__name__;if(!e)throw new Error("parent call error");for(;d&&!d.prototype.hasOwnProperty(e);)d=d.__base__;if(b=d.__base__,!b)throw new Error("base class not found in parent call");var f=!1;if(b[e]?c=b[e]:b.prototype[e]&&(c=b.prototype[e],f=!0),!c||!c.apply)throw new Error("method not found in parent call");return f?c.apply(a,Array.prototype.slice.call(arguments,1)):c.apply(b,arguments)}function i(){}function j(){var a=arguments,b=a.length;if(1>b)throw new Error("bad arguments");var c=null,d=b>1?a[0]:Object;if("function"!=typeof d&&"object"!=typeof d)throw new Error("base is not function or object");var e,f=a[b-1];if("function"!=typeof f&&"object"!=typeof f)throw new Error("constructor is not function or object");f instanceof Function&&(e=f,f={},e.call(f));var g=f.__metaclass__||d.__metaclass__||i,h=g.__new__(g,c,d,f);if(!h||"function"!=typeof h)throw new Error("__new__ method should return cls");return g.prototype.initialize.call(h,c,d,f),h}var k={},l=!0;try{Object.defineProperty({},"a",{value:1})}catch(m){l=!1}Object.keys||(Object.keys=function(a){var b=[];if(void 0===a||null===a)return b;for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){for(var c=0;cb)throw new Error("bad arguments");var c=null,d=b>1?a[0]:Object;if("function"!=typeof d&&"object"!=typeof d)throw new Error("base is not function or object");var e,f=a[b-1];if("function"!=typeof f&&"object"!=typeof f)throw new Error("constructor is not function or object");f instanceof Function&&(e=f,f={},e.call(f));var g=f.__metaclass__||d.__metaclass__||i,h=g.__new__(g,c,d,f);if(!h||"function"!=typeof h)throw new Error("__new__ method should return cls");return g.prototype.initialize.call(h,c,d,f),h}var k={},l=!0;try{Object.defineProperty({},"a",{value:1})}catch(m){l=!1}Object.keys||(Object.keys=function(a){var b=[];if(void 0===a||null===a)return b;for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){for(var c=0;coop的demo }); } - S.use('gallery/oop/1.0/index', function (S, Oop) { - new Oop(); + S.use('gallery/oop/0.1/index', function (S, oop) { + var MyClass = new oop.Class({ + p: oop.property(function() { + return this.__p; + }, function(value) { + this.__p = String(value).toUpperCase(); + }), + m: function() { + console.log('called'); + }, + sm: oop.staticmethod(function() { + console.log('called'); + }) + }); + + var my = new MyClass(); + my.m(); // ==> called + MyClass.sm(); // ==> called + my.p = 'a'; + console.log(my.p) // ==> A }) diff --git a/0.1/guide/index.md b/0.1/guide/index.md index 7d72cba..1432ea9 100644 --- a/0.1/guide/index.md +++ b/0.1/guide/index.md @@ -1,15 +1,14 @@ ## 综述 -oop是。 - -* 版本:1.0 +* 版本:0.1 * 作者:goto100 * demo:[http://gallery.kissyui.com/oop/1.0/demo/index.html](http://gallery.kissyui.com/oop/1.0/demo/index.html) ## 初始化组件 - S.use('gallery/oop/1.0/index', function (S, Oop) { - var oop = new Oop(); + S.use('gallery/oop/0.1/index', function (S, oop) { + var MyClass = new oop.Class({ + }); }) ## API说明 diff --git a/0.1/index.js b/0.1/index.js index e0833a5..75e2c8c 100644 --- a/0.1/index.js +++ b/0.1/index.js @@ -243,39 +243,48 @@ function makePrivate(proto, name) { } } -function parent(self) { - var ownCls = self.__class__; // 拥有此方法的代码书写的类 - var name = arguments.callee.caller.__name__; // 方法名字 - var base, member; // 最后要执行的类和方法 - - if (!name) throw new Error('parent call error'); - - // parent应该调用“代码书写的方法所在的类的父同名方法” - // 而不是方法调用者实例的类的父同名方法 - // 比如C继承于B继承于A,当C的实例调用从B继承来的某方法时,其中调用了this.parent,应该直接调用到A上的同名方法,而不是B的。 - // 因此,这里通过hasOwnProperty,从当前类开始,向上找到同名方法的原始定义类 - while (ownCls && !ownCls.prototype.hasOwnProperty(name)) { - ownCls = ownCls.__base__; - } - - base = ownCls.__base__; - if (!base) throw new Error('base class not found in parent call'); - - var inProto = false; - if (base[name]) { - member = base[name]; - } else if (base.prototype[name]) { - member = base.prototype[name]; - inProto = true; - } - - if (!member || !member.apply) throw new Error('method not found in parent call'); - - if (inProto) { - return member.apply(self, Array.prototype.slice.call(arguments, 1)); - } else { - return member.apply(base, arguments); - } +function parent(obj) { + var func, found = []; + var args = Array.prototype.slice.call(arguments, 1); + + // parent = oop.parent.bind(arguments.callee) + if (typeof this == 'function' && this.__name__) { + func = this; + } + // oop.parent(self, 1, 2, 3); + else { + try { + func = arguments.callee.caller; + } catch(e) { + throw new Error('can\'t use parent in strict mode'); + } + while (func && found.indexOf(func) == -1 && !func.__name__) { + found.push(func); + func = func.caller; + } + } + + var ownCls = obj.__class__; // 拥有此方法的代码书写的类 + var name = func.__name__; // 方法名字 + var baseProto, member; // 最后要执行的类和方法 + + if (!name) throw new Error('parent call error'); + + // parent应该调用“代码书写的方法所在的类的父同名方法” + // 而不是方法调用者实例的类的父同名方法 + // 比如C继承于B继承于A,当C的实例调用从B继承来的某方法时,其中调用了this.parent,应该直接调用到A上的同名方法,而不是B的。 + // 因此,这里通过hasOwnProperty,从当前类开始,向上找到同名方法的原始定义类 + while (ownCls && !(ownCls.prototype[name] == func && ownCls.prototype.hasOwnProperty(name))) { + ownCls = ownCls.__base__; + } + + baseProto = ownCls.__base__.prototype; + if (!baseProto) throw new Error('base class not found in parent call'); + + member = baseProto[name]; + if (!member || !member.apply) throw new Error('method not found in parent call'); + + return member.apply(obj, args); } function Type() { @@ -450,7 +459,7 @@ exports.parent = parent; exports.instanceOf = instanceOf; exports.typeOf = typeOf; exports.install = function(target) { - if (!target) target = global; + if (!target) target = window; ['Class', 'Type', 'classmethod', 'staticmethod', 'property'].forEach(function(name) { target[name] = exports[name]; }) diff --git a/0.1/meta/alias.js b/0.1/meta/alias.js index 11710b0..f6f31b8 100644 --- a/0.1/meta/alias.js +++ b/0.1/meta/alias.js @@ -1,3 +1,3 @@ config({ - 'gallery/oop/index': {alias: ['gallery/oop/1.0/index']} + 'gallery/oop/index': {alias: ['gallery/oop/0.1/index']} }); \ No newline at end of file From 5d9210ae6ec921d3d0a7376e8ef2eabb2ee1238c Mon Sep 17 00:00:00 2001 From: goto100 Date: Wed, 11 Sep 2013 16:18:39 +0800 Subject: [PATCH 12/13] doc --- 0.1/guide/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/0.1/guide/index.md b/0.1/guide/index.md index 1432ea9..e597fec 100644 --- a/0.1/guide/index.md +++ b/0.1/guide/index.md @@ -12,3 +12,5 @@ }) ## API说明 + + 文档请移步 [github](https://github.com/ObjectJS/oop) From a1744a6fb02574305426e59abf5a668bf753e9b1 Mon Sep 17 00:00:00 2001 From: goto100 Date: Fri, 13 Sep 2013 11:47:03 +0800 Subject: [PATCH 13/13] merge master --- 0.1/build/index-min.js | 4 ++-- 0.1/build/index.js | 1 + 0.1/index.js | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/0.1/build/index-min.js b/0.1/build/index-min.js index 14219ab..45e963a 100644 --- a/0.1/build/index-min.js +++ b/0.1/build/index-min.js @@ -1,3 +1,3 @@ -/*! oop - v0.1 - 2013-09-11 4:10:47 PM +/*! oop - v0.1 - 2013-09-13 11:46:26 AM * Copyright (c) 2013 goto100; Licensed */ -KISSY.add("gallery/oop/0.1/index",function(){function a(a){return{__class__:arguments.callee,__func__:a}}function b(a){return{__class__:arguments.callee,__func__:a}}function c(a,b){var c={__class__:arguments.callee,fget:a,fset:b};return c}function d(){}function e(a){return f(a.__metaclass__,i)?"type":typeof a}function f(a,b){if("function"!=typeof b)throw new Error("bad arguments.");var c;if("function"!=typeof a)return a instanceof b;if(c=a.__class__)do if(c===b)return!0;while(c=c.__base__);return!1}function g(a,b){if(l){var c;0==b.indexOf("__")&&b.lastIndexOf("__")!=b.length-2&&(c=a[b],Object.defineProperty(a,b,{get:function(){return this.constructor.prototype.hasOwnProperty(b)?c:void 0},set:function(a){c=a}}))}}function h(a){var b,c=[],d=Array.prototype.slice.call(arguments,1);if("function"==typeof this&&this.__name__)b=this;else{try{b=arguments.callee.caller}catch(e){throw new Error("can't use parent in strict mode")}for(;b&&-1==c.indexOf(b)&&!b.__name__;)c.push(b),b=b.caller}var f,g,h=a.__class__,i=b.__name__;if(!i)throw new Error("parent call error");for(;h&&(h.prototype[i]!=b||!h.prototype.hasOwnProperty(i));)h=h.__base__;if(f=h.__base__.prototype,!f)throw new Error("base class not found in parent call");if(g=f[i],!g||!g.apply)throw new Error("method not found in parent call");return g.apply(a,d)}function i(){}function j(){var a=arguments,b=a.length;if(1>b)throw new Error("bad arguments");var c=null,d=b>1?a[0]:Object;if("function"!=typeof d&&"object"!=typeof d)throw new Error("base is not function or object");var e,f=a[b-1];if("function"!=typeof f&&"object"!=typeof f)throw new Error("constructor is not function or object");f instanceof Function&&(e=f,f={},e.call(f));var g=f.__metaclass__||d.__metaclass__||i,h=g.__new__(g,c,d,f);if(!h||"function"!=typeof h)throw new Error("__new__ method should return cls");return g.prototype.initialize.call(h,c,d,f),h}var k={},l=!0;try{Object.defineProperty({},"a",{value:1})}catch(m){l=!1}Object.keys||(Object.keys=function(a){var b=[];if(void 0===a||null===a)return b;for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){for(var c=0;cb)throw new Error("bad arguments");var c=null,d=b>1?a[0]:Object;if("function"!=typeof d&&"object"!=typeof d)throw new Error("base is not function or object");var e,f=a[b-1];if("function"!=typeof f&&"object"!=typeof f)throw new Error("constructor is not function or object");f instanceof Function&&(e=f,f={},e.call(f));var g=f.__metaclass__||d.__metaclass__||i,h=g.__new__(g,c,d,f);if(!h||"function"!=typeof h)throw new Error("__new__ method should return cls");return g.prototype.initialize.call(h,c,d,f),h}var k={},l=!0;try{Object.defineProperty({},"a",{value:1})}catch(m){l=!1}Object.keys||(Object.keys=function(a){var b=[];if(void 0===a||null===a)return b;for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){for(var c=0;c