UNPKG

3.31 kBJavaScriptView Raw
1import * as Util from './Util';
2
3// @class Class
4// @aka L.Class
5
6// @section
7// @uninheritable
8
9// Thanks to John Resig and Dean Edwards for inspiration!
10
11export function Class() {}
12
13Class.extend = function (props) {
14
15 // @function extend(props: Object): Function
16 // [Extends the current class](#class-inheritance) given the properties to be included.
17 // Returns a Javascript function that is a class constructor (to be called with `new`).
18 var NewClass = function () {
19
20 // call the constructor
21 if (this.initialize) {
22 this.initialize.apply(this, arguments);
23 }
24
25 // call all constructor hooks
26 this.callInitHooks();
27 };
28
29 var parentProto = NewClass.__super__ = this.prototype;
30
31 var proto = Util.create(parentProto);
32 proto.constructor = NewClass;
33
34 NewClass.prototype = proto;
35
36 // inherit parent's statics
37 for (var i in this) {
38 if (this.hasOwnProperty(i) && i !== 'prototype' && i !== '__super__') {
39 NewClass[i] = this[i];
40 }
41 }
42
43 // mix static properties into the class
44 if (props.statics) {
45 Util.extend(NewClass, props.statics);
46 delete props.statics;
47 }
48
49 // mix includes into the prototype
50 if (props.includes) {
51 checkDeprecatedMixinEvents(props.includes);
52 Util.extend.apply(null, [proto].concat(props.includes));
53 delete props.includes;
54 }
55
56 // merge options
57 if (proto.options) {
58 props.options = Util.extend(Util.create(proto.options), props.options);
59 }
60
61 // mix given properties into the prototype
62 Util.extend(proto, props);
63
64 proto._initHooks = [];
65
66 // add method for calling all hooks
67 proto.callInitHooks = function () {
68
69 if (this._initHooksCalled) { return; }
70
71 if (parentProto.callInitHooks) {
72 parentProto.callInitHooks.call(this);
73 }
74
75 this._initHooksCalled = true;
76
77 for (var i = 0, len = proto._initHooks.length; i < len; i++) {
78 proto._initHooks[i].call(this);
79 }
80 };
81
82 return NewClass;
83};
84
85
86// @function include(properties: Object): this
87// [Includes a mixin](#class-includes) into the current class.
88Class.include = function (props) {
89 Util.extend(this.prototype, props);
90 return this;
91};
92
93// @function mergeOptions(options: Object): this
94// [Merges `options`](#class-options) into the defaults of the class.
95Class.mergeOptions = function (options) {
96 Util.extend(this.prototype.options, options);
97 return this;
98};
99
100// @function addInitHook(fn: Function): this
101// Adds a [constructor hook](#class-constructor-hooks) to the class.
102Class.addInitHook = function (fn) { // (Function) || (String, args...)
103 var args = Array.prototype.slice.call(arguments, 1);
104
105 var init = typeof fn === 'function' ? fn : function () {
106 this[fn].apply(this, args);
107 };
108
109 this.prototype._initHooks = this.prototype._initHooks || [];
110 this.prototype._initHooks.push(init);
111 return this;
112};
113
114function checkDeprecatedMixinEvents(includes) {
115 if (typeof L === 'undefined' || !L || !L.Mixin) { return; }
116
117 includes = Util.isArray(includes) ? includes : [includes];
118
119 for (var i = 0; i < includes.length; i++) {
120 if (includes[i] === L.Mixin.Events) {
121 console.warn('Deprecated include of L.Mixin.Events: ' +
122 'this property will be removed in future releases, ' +
123 'please inherit from L.Evented instead.', new Error().stack);
124 }
125 }
126}