|
1 |
| -/* |
2 |
| -* Extended Javascript Inheritance |
3 |
| -* for supporting overridable getters and setters |
4 |
| -* By Lukas Klinzing |
5 |
| -* |
6 |
| -* Based on the great John Resigs Simple Base.js |
7 |
| -* -------------------------------- |
8 |
| -* Base.js |
9 |
| -* Simple JavaScript Inheritance |
10 |
| -* By John Resig http://ejohn.org/ |
11 |
| -* MIT Licensed. |
12 |
| -* |
13 |
| -*/ |
| 1 | +/* |
| 2 | + * Extended Javascript Inheritance |
| 3 | + * for supporting overridable getters and setters |
| 4 | + * By Lukas Klinzing |
| 5 | + * |
| 6 | + * Based on the great John Resigs Simple Base.js |
| 7 | + * -------------------------------- |
| 8 | + * Base.js |
| 9 | + * Simple JavaScript Inheritance |
| 10 | + * By John Resig http://ejohn.org/ |
| 11 | + * MIT Licensed. |
| 12 | + * |
| 13 | + * -------------------------------- |
| 14 | + * Replaced deprecated functions __defineGetter__, __defineSetter__, __lookupGetter__ |
| 15 | + * with new ECMAScript standards (supporting all browsers + ie) |
| 16 | + * By Eray Hanoglu |
| 17 | + * MIT Licensed. |
| 18 | + */ |
| 19 | + |
14 | 20 | // Inspired by base2 and Prototype
|
15 | 21 | (function () {
|
16 | 22 |
|
17 | 23 | var root = this;
|
18 | 24 |
|
19 | 25 | var initializing = false,
|
20 |
| - fnTest = /xyz/.test(function () { xyz; }) ? /\b_super\b/ : /.*/; |
| 26 | + fnTest = /xyz/.test(function () { |
| 27 | + /** |
| 28 | + * This is a function where type checking is disabled. |
| 29 | + * @suppress {suspiciousCode} |
| 30 | + */ |
| 31 | + xyz; |
| 32 | + }) ? /\b_super\b/ : /.*/; |
21 | 33 |
|
22 | 34 | // The base Class implementation (does nothing)
|
23 | 35 | var Class = function () {
|
|
47 | 59 | // but on the super-class
|
48 | 60 | this._super = function () {
|
49 | 61 | if (superFn) return superFn.apply(self, (arguments.length > 0 ? arguments : args));
|
50 |
| - } |
| 62 | + return null; |
| 63 | + }; |
51 | 64 | // The method only need to be bound temporarily, so we
|
52 | 65 | // remove it when we're done executing
|
53 | 66 | var ret = fn.apply(this, arguments);
|
|
58 | 71 | };
|
59 | 72 |
|
60 | 73 | var override = function (name, fn, source, target) {
|
| 74 | + var descriptor; |
61 | 75 | if (typeof (fn) == "function" && typeof (source[name]) == "function" && fnTest.test(fn)) {
|
62 | 76 | target[name] = fnOverride(name, fn, source[name]);
|
63 | 77 | } else if (fn && (fn.get || fn.set)) {
|
64 |
| - var sGetter = source.__lookupGetter__(name), |
65 |
| - sSetter = source.__lookupSetter__(name); |
66 |
| - if (fn.get) |
67 |
| - target.__defineGetter__(name, sGetter && fnTest.test(fn.get) ? fnOverride(name, fn.get, sGetter) : fn.get); |
68 |
| - if (fn.set) |
69 |
| - target.__defineSetter__(name, sSetter && fnTest.test(fn.set) ? fnOverride(name, fn.set, sSetter) : fn.set); |
| 78 | + var obj1 = Object.getOwnPropertyDescriptor(source, name), |
| 79 | + sGetter = (obj1 && obj1.get), |
| 80 | + sSetter = (obj1 && obj1.set); |
| 81 | + |
| 82 | + descriptor = {configurable: true, enumerable: true}; |
| 83 | + if (fn.get) descriptor.get = (sGetter && fnTest.test(fn.get) ? fnOverride(name, fn.get, sGetter) : fn.get); |
| 84 | + if (fn.set) descriptor.set = (sSetter && fnTest.test(fn.set) ? fnOverride(name, fn.set, sSetter) : fn.set); |
| 85 | + Object.defineProperty(target, name, descriptor); |
70 | 86 | } else {
|
71 | 87 | if (target[name]) delete target[name];
|
72 |
| - target[name] = fn; |
73 |
| - } |
74 |
| - } |
| 88 | + target[name] = fn; } |
| 89 | + }; |
75 | 90 |
|
76 | 91 | //Setters and Getters must be copied from _super unless they are going to be overriden
|
77 | 92 | //seems like "prototype = new this" doesnt copy getters and setters to the new prototype
|
78 | 93 | //this one is inspired (borrowed) from John Resigs post on "JavaScript Getters and Setters"
|
79 | 94 | //http://ejohn.org/blog/javascript-getters-and-setters/
|
80 |
| - for (var name in _super) { |
81 |
| - var g = _super.__lookupGetter__(name), |
82 |
| - s = _super.__lookupSetter__(name), |
83 |
| - og = prop.__lookupGetter__(name), |
84 |
| - os = prop.__lookupSetter__(name); |
85 |
| - |
86 |
| - if ((g && !og) || (s && !os)) { |
87 |
| - if (g) |
88 |
| - prototype.__defineGetter__(name, g); |
89 |
| - if (s) |
90 |
| - prototype.__defineSetter__(name, s); |
| 95 | + var name, obj1, obj2; |
| 96 | + for (name in _super) { |
| 97 | + |
| 98 | + if (_super.hasOwnProperty(name)) { |
| 99 | + obj1 = Object.getOwnPropertyDescriptor(_super, name); |
| 100 | + obj2 = Object.getOwnPropertyDescriptor(prop, name); |
| 101 | + var g = (obj1 && obj1.get), |
| 102 | + s = (obj1 && obj1.set), |
| 103 | + og = (obj2 && obj2.get), |
| 104 | + os = (obj2 && obj2.set); |
| 105 | + |
| 106 | + if ((g && !og) || (s && !os)) { |
| 107 | + var descriptor = {configurable: true, enumerable: true}; |
| 108 | + if (g) descriptor.get = g; |
| 109 | + if (s) descriptor.set = s; |
| 110 | + Object.defineProperty(prototype, name, descriptor); |
| 111 | + } |
91 | 112 | }
|
92 | 113 | }
|
93 | 114 |
|
94 |
| - |
95 | 115 | // Copy the properties over onto the new prototype
|
96 |
| - for (var name in prop) { |
97 |
| - |
98 |
| - var getter = prop.__lookupGetter__(name), |
99 |
| - setter = prop.__lookupSetter__(name); |
100 |
| - var options = (getter || setter) ? { get: getter, set: setter} : prop[name]; |
101 |
| - override(name, options, _super, prototype); |
102 |
| - |
| 116 | + for (name in prop) { |
| 117 | + |
| 118 | + if (prop.hasOwnProperty(name)) { |
| 119 | + obj1 = Object.getOwnPropertyDescriptor(prop, name); |
| 120 | + var getter = obj1.get, |
| 121 | + setter = obj1.set; |
| 122 | + var options = (getter || setter) ? { get: getter, set: setter} : prop[name]; |
| 123 | + override(name, options, _super, prototype); |
| 124 | + } |
103 | 125 | }
|
104 | 126 |
|
105 | 127 | // The dummy class constructor
|
|
0 commit comments