fabric-rails 1.0.12 → 1.0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +16 -0
- data/README.md +1 -1
- data/lib/fabric/rails/version.rb +2 -2
- data/vendor/assets/javascripts/event.js +1909 -0
- data/vendor/assets/javascripts/fabric.js +64 -16464
- data/vendor/assets/javascripts/fabric/HEADER.js +31 -0
- data/vendor/assets/javascripts/fabric/canvas.class.js +1007 -0
- data/vendor/assets/javascripts/fabric/canvas_animation.mixin.js +113 -0
- data/vendor/assets/javascripts/fabric/canvas_events.mixin.js +482 -0
- data/vendor/assets/javascripts/fabric/canvas_gestures.mixin.js +79 -0
- data/vendor/assets/javascripts/fabric/canvas_serialization.mixin.js +311 -0
- data/vendor/assets/javascripts/fabric/circle.class.js +182 -0
- data/vendor/assets/javascripts/fabric/color.class.js +284 -0
- data/vendor/assets/javascripts/fabric/ellipse.class.js +169 -0
- data/vendor/assets/javascripts/fabric/freedrawing.class.js +256 -0
- data/vendor/assets/javascripts/fabric/gradient.class.js +211 -0
- data/vendor/assets/javascripts/fabric/group.class.js +556 -0
- data/vendor/assets/javascripts/fabric/image.class.js +418 -0
- data/vendor/assets/javascripts/fabric/image_filters.js +809 -0
- data/vendor/assets/javascripts/fabric/intersection.class.js +178 -0
- data/vendor/assets/javascripts/fabric/line.class.js +188 -0
- data/vendor/assets/javascripts/fabric/log.js +26 -0
- data/vendor/assets/javascripts/fabric/node.js +149 -0
- data/vendor/assets/javascripts/fabric/object.class.js +1068 -0
- data/vendor/assets/javascripts/fabric/object_geometry.mixin.js +308 -0
- data/vendor/assets/javascripts/fabric/object_interactivity.mixin.js +496 -0
- data/vendor/assets/javascripts/fabric/object_origin.mixin.js +207 -0
- data/vendor/assets/javascripts/fabric/object_straightening.mixin.js +94 -0
- data/vendor/assets/javascripts/fabric/observable.mixin.js +91 -0
- data/vendor/assets/javascripts/fabric/parser.js +750 -0
- data/vendor/assets/javascripts/fabric/path.class.js +794 -0
- data/vendor/assets/javascripts/fabric/path_group.class.js +240 -0
- data/vendor/assets/javascripts/fabric/pattern.class.js +69 -0
- data/vendor/assets/javascripts/fabric/point.class.js +327 -0
- data/vendor/assets/javascripts/fabric/polygon.class.js +184 -0
- data/vendor/assets/javascripts/fabric/polyline.class.js +157 -0
- data/vendor/assets/javascripts/fabric/rect.class.js +298 -0
- data/vendor/assets/javascripts/fabric/scout.js +45 -0
- data/vendor/assets/javascripts/fabric/shadow.class.js +70 -0
- data/vendor/assets/javascripts/fabric/stateful.js +88 -0
- data/vendor/assets/javascripts/fabric/static_canvas.class.js +1298 -0
- data/vendor/assets/javascripts/fabric/text.class.js +934 -0
- data/vendor/assets/javascripts/fabric/triangle.class.js +108 -0
- data/vendor/assets/javascripts/fabric/util/anim_ease.js +360 -0
- data/vendor/assets/javascripts/fabric/util/dom_event.js +237 -0
- data/vendor/assets/javascripts/fabric/util/dom_misc.js +245 -0
- data/vendor/assets/javascripts/fabric/util/dom_request.js +72 -0
- data/vendor/assets/javascripts/fabric/util/dom_style.js +71 -0
- data/vendor/assets/javascripts/fabric/util/lang_array.js +250 -0
- data/vendor/assets/javascripts/fabric/util/lang_class.js +97 -0
- data/vendor/assets/javascripts/fabric/util/lang_function.js +35 -0
- data/vendor/assets/javascripts/fabric/util/lang_object.js +34 -0
- data/vendor/assets/javascripts/fabric/util/lang_string.js +60 -0
- data/vendor/assets/javascripts/fabric/util/misc.js +406 -0
- data/vendor/assets/javascripts/json2.js +491 -0
- metadata +53 -2
@@ -0,0 +1,72 @@
|
|
1
|
+
(function(){
|
2
|
+
|
3
|
+
function addParamToUrl(url, param) {
|
4
|
+
return url + (/\?/.test(url) ? '&' : '?') + param;
|
5
|
+
}
|
6
|
+
|
7
|
+
var makeXHR = (function() {
|
8
|
+
var factories = [
|
9
|
+
function() { return new ActiveXObject("Microsoft.XMLHTTP"); },
|
10
|
+
function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
|
11
|
+
function() { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); },
|
12
|
+
function() { return new XMLHttpRequest(); }
|
13
|
+
];
|
14
|
+
for (var i = factories.length; i--; ) {
|
15
|
+
try {
|
16
|
+
var req = factories[i]();
|
17
|
+
if (req) {
|
18
|
+
return factories[i];
|
19
|
+
}
|
20
|
+
}
|
21
|
+
catch (err) { }
|
22
|
+
}
|
23
|
+
})();
|
24
|
+
|
25
|
+
function emptyFn() { }
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Cross-browser abstraction for sending XMLHttpRequest
|
29
|
+
* @method request
|
30
|
+
* @memberOf fabric.util
|
31
|
+
* @param {String} url URL to send XMLHttpRequest to
|
32
|
+
* @param {Object} [options] Options object
|
33
|
+
* @param {String} [options.method="GET"]
|
34
|
+
* @param {Function} options.onComplete Callback to invoke when request is completed
|
35
|
+
* @return {XMLHttpRequest} request
|
36
|
+
*/
|
37
|
+
function request(url, options) {
|
38
|
+
|
39
|
+
options || (options = { });
|
40
|
+
|
41
|
+
var method = options.method ? options.method.toUpperCase() : 'GET',
|
42
|
+
onComplete = options.onComplete || function() { },
|
43
|
+
xhr = makeXHR(),
|
44
|
+
body;
|
45
|
+
|
46
|
+
/** @ignore */
|
47
|
+
xhr.onreadystatechange = function() {
|
48
|
+
if (xhr.readyState === 4) {
|
49
|
+
onComplete(xhr);
|
50
|
+
xhr.onreadystatechange = emptyFn;
|
51
|
+
}
|
52
|
+
};
|
53
|
+
|
54
|
+
if (method === 'GET') {
|
55
|
+
body = null;
|
56
|
+
if (typeof options.parameters === 'string') {
|
57
|
+
url = addParamToUrl(url, options.parameters);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
xhr.open(method, url, true);
|
62
|
+
|
63
|
+
if (method === 'POST' || method === 'PUT') {
|
64
|
+
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
65
|
+
}
|
66
|
+
|
67
|
+
xhr.send(body);
|
68
|
+
return xhr;
|
69
|
+
}
|
70
|
+
|
71
|
+
fabric.util.request = request;
|
72
|
+
})();
|
@@ -0,0 +1,71 @@
|
|
1
|
+
(function () {
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Cross-browser wrapper for setting element's style
|
5
|
+
* @method setStyle
|
6
|
+
* @memberOf fabric.util
|
7
|
+
* @param {HTMLElement} element
|
8
|
+
* @param {Object} styles
|
9
|
+
* @return {HTMLElement} Element that was passed as a first argument
|
10
|
+
*/
|
11
|
+
function setStyle(element, styles) {
|
12
|
+
var elementStyle = element.style;
|
13
|
+
if (!elementStyle) {
|
14
|
+
return element;
|
15
|
+
}
|
16
|
+
if (typeof styles === 'string') {
|
17
|
+
element.style.cssText += ';' + styles;
|
18
|
+
return styles.indexOf('opacity') > -1
|
19
|
+
? setOpacity(element, styles.match(/opacity:\s*(\d?\.?\d*)/)[1])
|
20
|
+
: element;
|
21
|
+
}
|
22
|
+
for (var property in styles) {
|
23
|
+
if (property === 'opacity') {
|
24
|
+
setOpacity(element, styles[property]);
|
25
|
+
}
|
26
|
+
else {
|
27
|
+
var normalizedProperty = (property === 'float' || property === 'cssFloat')
|
28
|
+
? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat')
|
29
|
+
: property;
|
30
|
+
elementStyle[normalizedProperty] = styles[property];
|
31
|
+
}
|
32
|
+
}
|
33
|
+
return element;
|
34
|
+
}
|
35
|
+
|
36
|
+
var parseEl = fabric.document.createElement('div'),
|
37
|
+
supportsOpacity = typeof parseEl.style.opacity === 'string',
|
38
|
+
supportsFilters = typeof parseEl.style.filter === 'string',
|
39
|
+
reOpacity = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,
|
40
|
+
|
41
|
+
/** @ignore */
|
42
|
+
setOpacity = function (element) { return element; };
|
43
|
+
|
44
|
+
if (supportsOpacity) {
|
45
|
+
/** @ignore */
|
46
|
+
setOpacity = function(element, value) {
|
47
|
+
element.style.opacity = value;
|
48
|
+
return element;
|
49
|
+
};
|
50
|
+
}
|
51
|
+
else if (supportsFilters) {
|
52
|
+
/** @ignore */
|
53
|
+
setOpacity = function(element, value) {
|
54
|
+
var es = element.style;
|
55
|
+
if (element.currentStyle && !element.currentStyle.hasLayout) {
|
56
|
+
es.zoom = 1;
|
57
|
+
}
|
58
|
+
if (reOpacity.test(es.filter)) {
|
59
|
+
value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')');
|
60
|
+
es.filter = es.filter.replace(reOpacity, value);
|
61
|
+
}
|
62
|
+
else {
|
63
|
+
es.filter += ' alpha(opacity=' + (value * 100) + ')';
|
64
|
+
}
|
65
|
+
return element;
|
66
|
+
};
|
67
|
+
}
|
68
|
+
|
69
|
+
fabric.util.setStyle = setStyle;
|
70
|
+
|
71
|
+
})();
|
@@ -0,0 +1,250 @@
|
|
1
|
+
(function() {
|
2
|
+
|
3
|
+
var slice = Array.prototype.slice;
|
4
|
+
|
5
|
+
if (!Array.prototype.indexOf) {
|
6
|
+
/**
|
7
|
+
* Finds index of an element in an array
|
8
|
+
* @method indexOf
|
9
|
+
* @param {Any} searchElement
|
10
|
+
* @param {Number} [fromIndex]
|
11
|
+
*/
|
12
|
+
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
|
13
|
+
if (this === void 0 || this === null) {
|
14
|
+
throw new TypeError();
|
15
|
+
}
|
16
|
+
var t = Object(this), len = t.length >>> 0;
|
17
|
+
if (len === 0) {
|
18
|
+
return -1;
|
19
|
+
}
|
20
|
+
var n = 0;
|
21
|
+
if (arguments.length > 0) {
|
22
|
+
n = Number(arguments[1]);
|
23
|
+
if (n !== n) { // shortcut for verifying if it's NaN
|
24
|
+
n = 0;
|
25
|
+
}
|
26
|
+
else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
|
27
|
+
n = (n > 0 || -1) * Math.floor(Math.abs(n));
|
28
|
+
}
|
29
|
+
}
|
30
|
+
if (n >= len) {
|
31
|
+
return -1;
|
32
|
+
}
|
33
|
+
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
|
34
|
+
for (; k < len; k++) {
|
35
|
+
if (k in t && t[k] === searchElement) {
|
36
|
+
return k;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
return -1;
|
40
|
+
};
|
41
|
+
}
|
42
|
+
|
43
|
+
if (!Array.prototype.forEach) {
|
44
|
+
/**
|
45
|
+
* Iterates an array, invoking callback for each element
|
46
|
+
* @method forEach
|
47
|
+
* @param {Function} fn Callback to invoke for each element
|
48
|
+
* @param {Object} [context] Context to invoke callback in
|
49
|
+
*/
|
50
|
+
Array.prototype.forEach = function(fn, context) {
|
51
|
+
for (var i = 0, len = this.length >>> 0; i < len; i++) {
|
52
|
+
if (i in this) {
|
53
|
+
fn.call(context, this[i], i, this);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
};
|
57
|
+
}
|
58
|
+
|
59
|
+
if (!Array.prototype.map) {
|
60
|
+
/**
|
61
|
+
* Returns a result of iterating over an array, invoking callback for each element
|
62
|
+
* @method map
|
63
|
+
* @param {Function} fn Callback to invoke for each element
|
64
|
+
* @param {Object} [context] Context to invoke callback in
|
65
|
+
*/
|
66
|
+
Array.prototype.map = function(fn, context) {
|
67
|
+
var result = [ ];
|
68
|
+
for (var i = 0, len = this.length >>> 0; i < len; i++) {
|
69
|
+
if (i in this) {
|
70
|
+
result[i] = fn.call(context, this[i], i, this);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
return result;
|
74
|
+
};
|
75
|
+
}
|
76
|
+
|
77
|
+
if (!Array.prototype.every) {
|
78
|
+
/**
|
79
|
+
* Returns true if a callback returns truthy value for all elements in an array
|
80
|
+
* @method every
|
81
|
+
* @param {Function} fn Callback to invoke for each element
|
82
|
+
* @param {Object} [context] Context to invoke callback in
|
83
|
+
*/
|
84
|
+
Array.prototype.every = function(fn, context) {
|
85
|
+
for (var i = 0, len = this.length >>> 0; i < len; i++) {
|
86
|
+
if (i in this && !fn.call(context, this[i], i, this)) {
|
87
|
+
return false;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
return true;
|
91
|
+
};
|
92
|
+
}
|
93
|
+
|
94
|
+
if (!Array.prototype.some) {
|
95
|
+
/**
|
96
|
+
* Returns true if a callback returns truthy value for at least one element in an array
|
97
|
+
* @method every
|
98
|
+
* @param {Function} fn Callback to invoke for each element
|
99
|
+
* @param {Object} [context] Context to invoke callback in
|
100
|
+
*/
|
101
|
+
Array.prototype.some = function(fn, context) {
|
102
|
+
for (var i = 0, len = this.length >>> 0; i < len; i++) {
|
103
|
+
if (i in this && fn.call(context, this[i], i, this)) {
|
104
|
+
return true;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
return false;
|
108
|
+
};
|
109
|
+
}
|
110
|
+
|
111
|
+
if (!Array.prototype.filter) {
|
112
|
+
/**
|
113
|
+
* Returns the result of iterating over elements in an array
|
114
|
+
* @method filter
|
115
|
+
* @param {Function} fn Callback to invoke for each element
|
116
|
+
* @param {Object} [context] Context to invoke callback in
|
117
|
+
*/
|
118
|
+
Array.prototype.filter = function(fn, context) {
|
119
|
+
var result = [ ], val;
|
120
|
+
for (var i = 0, len = this.length >>> 0; i < len; i++) {
|
121
|
+
if (i in this) {
|
122
|
+
val = this[i]; // in case fn mutates this
|
123
|
+
if (fn.call(context, val, i, this)) {
|
124
|
+
result.push(val);
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
return result;
|
129
|
+
};
|
130
|
+
}
|
131
|
+
|
132
|
+
if (!Array.prototype.reduce) {
|
133
|
+
/**
|
134
|
+
* Returns "folded" (reduced) result of iterating over elements in an array
|
135
|
+
* @method filter
|
136
|
+
* @param {Function} fn Callback to invoke for each element
|
137
|
+
* @param {Object} [context] Context to invoke callback in
|
138
|
+
*/
|
139
|
+
Array.prototype.reduce = function(fn /*, initial*/) {
|
140
|
+
var len = this.length >>> 0,
|
141
|
+
i = 0,
|
142
|
+
rv;
|
143
|
+
|
144
|
+
if (arguments.length > 1) {
|
145
|
+
rv = arguments[1];
|
146
|
+
}
|
147
|
+
else {
|
148
|
+
do {
|
149
|
+
if (i in this) {
|
150
|
+
rv = this[i++];
|
151
|
+
break;
|
152
|
+
}
|
153
|
+
// if array contains no values, no initial value to return
|
154
|
+
if (++i >= len) {
|
155
|
+
throw new TypeError();
|
156
|
+
}
|
157
|
+
}
|
158
|
+
while (true);
|
159
|
+
}
|
160
|
+
for (; i < len; i++) {
|
161
|
+
if (i in this) {
|
162
|
+
rv = fn.call(null, rv, this[i], i, this);
|
163
|
+
}
|
164
|
+
}
|
165
|
+
return rv;
|
166
|
+
};
|
167
|
+
}
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Invokes method on all items in a given array
|
171
|
+
* @method invoke
|
172
|
+
* @memberOf fabric.util.array
|
173
|
+
* @param {Array} array Array to iterate over
|
174
|
+
* @param {String} method Name of a method to invoke
|
175
|
+
*/
|
176
|
+
function invoke(array, method) {
|
177
|
+
var args = slice.call(arguments, 2), result = [ ];
|
178
|
+
for (var i = 0, len = array.length; i < len; i++) {
|
179
|
+
result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]);
|
180
|
+
}
|
181
|
+
return result;
|
182
|
+
}
|
183
|
+
|
184
|
+
/**
|
185
|
+
* Finds maximum value in array (not necessarily "first" one)
|
186
|
+
* @method max
|
187
|
+
* @memberOf fabric.util.array
|
188
|
+
* @param {Array} array Array to iterate over
|
189
|
+
* @param {String} byProperty
|
190
|
+
*/
|
191
|
+
function max(array, byProperty) {
|
192
|
+
if (!array || array.length === 0) return undefined;
|
193
|
+
|
194
|
+
var i = array.length - 1,
|
195
|
+
result = byProperty ? array[i][byProperty] : array[i];
|
196
|
+
if (byProperty) {
|
197
|
+
while (i--) {
|
198
|
+
if (array[i][byProperty] >= result) {
|
199
|
+
result = array[i][byProperty];
|
200
|
+
}
|
201
|
+
}
|
202
|
+
}
|
203
|
+
else {
|
204
|
+
while (i--) {
|
205
|
+
if (array[i] >= result) {
|
206
|
+
result = array[i];
|
207
|
+
}
|
208
|
+
}
|
209
|
+
}
|
210
|
+
return result;
|
211
|
+
}
|
212
|
+
|
213
|
+
/**
|
214
|
+
* Finds minimum value in array (not necessarily "first" one)
|
215
|
+
* @method min
|
216
|
+
* @memberOf fabric.util.array
|
217
|
+
* @param {Array} array Array to iterate over
|
218
|
+
* @param {String} byProperty
|
219
|
+
*/
|
220
|
+
function min(array, byProperty) {
|
221
|
+
if (!array || array.length === 0) return undefined;
|
222
|
+
|
223
|
+
var i = array.length - 1,
|
224
|
+
result = byProperty ? array[i][byProperty] : array[i];
|
225
|
+
|
226
|
+
if (byProperty) {
|
227
|
+
while (i--) {
|
228
|
+
if (array[i][byProperty] < result) {
|
229
|
+
result = array[i][byProperty];
|
230
|
+
}
|
231
|
+
}
|
232
|
+
}
|
233
|
+
else {
|
234
|
+
while (i--) {
|
235
|
+
if (array[i] < result) {
|
236
|
+
result = array[i];
|
237
|
+
}
|
238
|
+
}
|
239
|
+
}
|
240
|
+
return result;
|
241
|
+
}
|
242
|
+
|
243
|
+
/** @namespace */
|
244
|
+
fabric.util.array = {
|
245
|
+
invoke: invoke,
|
246
|
+
min: min,
|
247
|
+
max: max
|
248
|
+
};
|
249
|
+
|
250
|
+
})();
|
@@ -0,0 +1,97 @@
|
|
1
|
+
(function() {
|
2
|
+
|
3
|
+
var slice = Array.prototype.slice, emptyFunction = function() { };
|
4
|
+
|
5
|
+
var IS_DONTENUM_BUGGY = (function(){
|
6
|
+
for (var p in { toString: 1 }) {
|
7
|
+
if (p === 'toString') return false;
|
8
|
+
}
|
9
|
+
return true;
|
10
|
+
})();
|
11
|
+
|
12
|
+
/** @ignore */
|
13
|
+
var addMethods = function(klass, source, parent) {
|
14
|
+
for (var property in source) {
|
15
|
+
|
16
|
+
if (property in klass.prototype &&
|
17
|
+
typeof klass.prototype[property] === 'function' &&
|
18
|
+
(source[property] + '').indexOf('callSuper') > -1) {
|
19
|
+
|
20
|
+
klass.prototype[property] = (function(property) {
|
21
|
+
return function() {
|
22
|
+
|
23
|
+
var superclass = this.constructor.superclass;
|
24
|
+
this.constructor.superclass = parent;
|
25
|
+
var returnValue = source[property].apply(this, arguments);
|
26
|
+
this.constructor.superclass = superclass;
|
27
|
+
|
28
|
+
if (property !== 'initialize') {
|
29
|
+
return returnValue;
|
30
|
+
}
|
31
|
+
};
|
32
|
+
})(property);
|
33
|
+
}
|
34
|
+
else {
|
35
|
+
klass.prototype[property] = source[property];
|
36
|
+
}
|
37
|
+
|
38
|
+
if (IS_DONTENUM_BUGGY) {
|
39
|
+
if (source.toString !== Object.prototype.toString) {
|
40
|
+
klass.prototype.toString = source.toString;
|
41
|
+
}
|
42
|
+
if (source.valueOf !== Object.prototype.valueOf) {
|
43
|
+
klass.prototype.valueOf = source.valueOf;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
};
|
48
|
+
|
49
|
+
function Subclass() { }
|
50
|
+
|
51
|
+
function callSuper(methodName) {
|
52
|
+
var fn = this.constructor.superclass.prototype[methodName];
|
53
|
+
return (arguments.length > 1)
|
54
|
+
? fn.apply(this, slice.call(arguments, 1))
|
55
|
+
: fn.call(this);
|
56
|
+
}
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Helper for creation of "classes". Note that pr
|
60
|
+
* @method createClass
|
61
|
+
* @param parent optional "Class" to inherit from
|
62
|
+
* @param properties Properties shared by all instances of this class
|
63
|
+
* (be careful modifying objects defined here as this would affect all instances)
|
64
|
+
* @memberOf fabric.util
|
65
|
+
*/
|
66
|
+
function createClass() {
|
67
|
+
var parent = null,
|
68
|
+
properties = slice.call(arguments, 0);
|
69
|
+
|
70
|
+
if (typeof properties[0] === 'function') {
|
71
|
+
parent = properties.shift();
|
72
|
+
}
|
73
|
+
function klass() {
|
74
|
+
this.initialize.apply(this, arguments);
|
75
|
+
}
|
76
|
+
|
77
|
+
klass.superclass = parent;
|
78
|
+
klass.subclasses = [ ];
|
79
|
+
|
80
|
+
if (parent) {
|
81
|
+
Subclass.prototype = parent.prototype;
|
82
|
+
klass.prototype = new Subclass();
|
83
|
+
parent.subclasses.push(klass);
|
84
|
+
}
|
85
|
+
for (var i = 0, length = properties.length; i < length; i++) {
|
86
|
+
addMethods(klass, properties[i], parent);
|
87
|
+
}
|
88
|
+
if (!klass.prototype.initialize) {
|
89
|
+
klass.prototype.initialize = emptyFunction;
|
90
|
+
}
|
91
|
+
klass.prototype.constructor = klass;
|
92
|
+
klass.prototype.callSuper = callSuper;
|
93
|
+
return klass;
|
94
|
+
}
|
95
|
+
|
96
|
+
fabric.util.createClass = createClass;
|
97
|
+
})();
|