-
Notifications
You must be signed in to change notification settings - Fork 3
/
selfish.js
146 lines (142 loc) · 4.75 KB
/
selfish.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* vim:set ts=2 sw=2 sts=2 expandtab */
/*jshint undef: true es5: true node: true devel: true evil: true
forin: true latedef: false supernew: true */
/*global define: true */
(typeof define !== "function" ? function($){ $(null, typeof exports !== 'undefined' ? exports : window); } : define)(function(require, exports) {
"use strict";
exports.Base = Object.freeze(Object.create(Object.prototype, {
/**
* Property representing a base prototype, object `this` prototype extends.
* If `this` object is an object created by `.new`, then `base` will be
* a prototype that, prototype of this extends. This property is intended to
* for calling methods of base / super prototype with out directly reference.
* @examples
*
* var Point = Base.extend({
* initialize: function Point(x, y) {
* point.x = x || 0;
* point.y = y || 0;
* },
* toString: function toString() {
* return this.x + ':' + this.y
* }
* });
*/
base: { value: Object.prototype },
/**
* Creates an object that inherits from `this` object (Analog of
* `new Object()`).
* @examples
*
* var Dog = Base.extend({
* bark: function bark() {
* return 'Ruff! Ruff!'
* }
* });
* var dog = Dog.new();
*/
'new': { value: function () {
var object = Object.create(this);
object.initialize.apply(object, arguments);
return object;
}},
initialize: { value: function Base() {
}},
/**
* Takes any number of argument objects and returns frozen, composite object
* that inherits from `this` object and combines all of the own properties of
* the argument objects. (Objects returned by this function are frozen as
* they are intended to be used as types).
*
* If two or more argument objects have own properties with the same name,
* the property is overridden, with precedence from right to left, implying,
* that properties of the object on the left are overridden by a same named
* property of the object on the right.
* @examples
*
* // ## Object composition ##
*
* var HEX = Base.extend({
* hex: function hex() {
* return '#' + this.color;
* }
* })
*
* var RGB = Base.extend({
* red: function red() {
* return parseInt(this.color.substr(0, 2), 16);
* },
* green: function green() {
* return parseInt(this.color.substr(2, 2), 16);
* },
* blue: function blue() {
* return parseInt(this.color.substr(4, 2), 16);
* }
* })
*
* var CMYK = Base.extend(RGB, {
* black: function black() {
* var color = Math.max(Math.max(this.red(), this.green()), this.blue());
* return (1 - color / 255).toFixed(4);
* },
* cyan: function cyan() {
* var K = this.black();
* return (((1 - this.red() / 255).toFixed(4) - K) / (1 - K)).toFixed(4);
* },
* magenta: function magenta() {
* var K = this.black();
* return (((1 - this.green() / 255).toFixed(4) - K) / (1 - K)).toFixed(4);
* },
* yellow: function yellow() {
* var K = this.black();
* return (((1 - this.blue() / 255).toFixed(4) - K) / (1 - K)).toFixed(4);
* }
* })
*
* var Color = Base.extend(HEX, RGB, CMYK, {
* initialize: function Color(color) {
* this.color = color;
* }
* });
*
* // ## Prototypal inheritance ##
*
* var Pixel = Color.extend({
* initialize: function Pixel(x, y, hex) {
* this.base.initialize.call(this, hex);
* this.x = x;
* this.y = y;
* },
* toString: function toString() {
* return this.x + ':' + this.y + '@' + this.hex();
* }
* });
*
* var pixel = Pixel.new(11, 23, 'CC3399')
* pixel.toString(); // 11:23@#CC3399
*
* pixel.red(); // 204
* pixel.green(); // 51
* pixel.blue(); // 153
*
* pixel.cyan(); // 0.0000
* pixel.magenta(); // 0.7500
* pixel.yellow(); // 0.2500
*
*/
extend: { value: function extend() {
// Defining an ES5 property descriptor map, where own property
// descriptors of all given objects are copied.
var descriptor = {};
Array.prototype.forEach.call(arguments, function (properties) {
Object.getOwnPropertyNames(properties).forEach(function(name) {
descriptor[name] = Object.getOwnPropertyDescriptor(properties, name);
});
});
// In addition `base` property is defined that points to a primary ancestor
// of the resulting object.
descriptor.base = { value: this };
return Object.freeze(Object.create(this, descriptor));
}}
}));
});