UNPKG

10.7 kBJavaScriptView Raw
1/*! this - v0.1.7 - 2013-03-14 */(function () {
2 if (!Array.prototype.indexOf) {
3 /**
4 * Returns the first index at which a given element can be found in the array, or -1 if it is not present.
5 * @param searchElement {Object} Element to locate in the array.
6 * @param fromIndex {int} The index at which to begin the search. Defaults to 0,
7 * i.e. the whole array will be searched. If the index is greater than or equal to the length of the array,
8 * -1 is returned, i.e. the array will not be searched. If negative,
9 * it is taken as the offset from the end of the array.
10 * Note that even when the index is negative, the array is still searched from front to back.
11 * If the calculated index is less than 0, the whole array will be searched.
12 * @returns {Number}
13 * @memberOf Array.prototype
14 */
15 Array.prototype.indexOf = function (searchElement, fromIndex) {
16 var i, numberOfItems = this.length;
17
18 for (i = (fromIndex || 0); i < numberOfItems; i += 1) {
19 if (this[i] === searchElement) {
20 return i;
21 }
22 }
23
24 return -1;
25 };
26 }
27}());
28(function () {
29 /**
30 * Extends all methods and properties from the parsed Object.
31 * @param SuperClass {Function} The class you wish to inherit from.
32 * @returns {Function}
33 * @memberOf Function.prototype
34 * @example var BaseClass = function() {};
35 * var AdvancedClass = function() {};
36 * AdvancedClass.extend(BaseClass);
37 */
38 Function.prototype.extend = function (SuperClass) {
39 if (typeof SuperClass.constructor === 'function') {
40 this.prototype = new SuperClass();
41 this.prototype.constructor = this;
42 } else {
43 this.prototype = SuperClass;
44 this.prototype.constructor = this;
45 }
46
47 return this;
48 };
49
50 if (!Function.prototype.bind) {
51 (function () {
52 var slice = Array.prototype.slice;
53
54 /**
55 * Changes the scope of the function every time it is called.
56 * @memberOf Function.prototype
57 * @param scope
58 * @returns {Function} A new copy of the function bound to a scope.
59 * @example function myClickHandler(event)
60 * {
61 * alert(this);
62 * }
63 *
64 * var myElement = document.getElementById('myElement');
65 * myElement.onClick = myClickHandler.bind(this);
66 */
67 Function.prototype.bind = function (scope) {
68 var _this = this,
69 args;
70
71 if (arguments.length > 1) {
72 args = slice.call(arguments, 1);
73
74 return function () {
75 var allArgs = args;
76
77 if (arguments.length > 0) {
78 allArgs = args.concat(slice.call(arguments));
79 }
80
81 return _this.apply(scope, allArgs);
82 };
83 }
84
85 return function () {
86 if (arguments.length > 0) {
87 return _this.apply(scope, arguments);
88 }
89
90 return _this.call(scope);
91 };
92 };
93 }());
94 }
95
96 /**
97 * Remembers and caches the results of high process functions. And returns the result.
98 * @returns {Function} The new version of the Function object with memoizing capabilities.
99 * @memberOf Function.prototype
100 * @example function addNumbersTogether() {
101 * var i,
102 * numberOfArgs = arguments.length,
103 * result = 0;
104 *
105 * for (i = 0; i < numberOfArgs; i += 1) {
106 * result += arguments[i];
107 * }
108 *
109 * return result;
110 * }
111 *
112 * var memAddNumbersTogether = addNumberTogether.memoize();
113 * memAddNumbersTogether(1, 2, 3, 4);
114 */
115 Function.prototype.memoize = function () {
116 var cache = {},
117 originalFunction = this,
118 join = Array.prototype.join;
119
120 return function () {
121 var key = join.call(arguments);
122
123 if (!cache[key]) {
124 cache[key] = originalFunction.apply(this, arguments);
125 }
126
127 return cache[key];
128 };
129 };
130}());
131/**
132 * Creates a new instance of EventDispatcher. A low lever class for dispatching events from Function constructors.
133 * @class Base class for to extend for the dispatching system.
134 * @this {EventDispatcher}
135 * @see Event
136 * @example
137 * var MyClass = function() {};
138 * MyClass.extend(EventDispatcher);
139 *
140 * var myClass = new MyClass();
141 * myClass.addEventListener(Event.COMPLETE, myClass_completeHandler, this);
142 */
143var EventDispatcher = (function () {
144
145 /**
146 * Creates a new instance of EventDispatcher.
147 * @constructor
148 */
149 function EventDispatcher() {
150 /**
151 * @private
152 * @ignore
153 * @type Array
154 */
155 this._eventObjects = [];
156 }
157
158 EventDispatcher.TYPE_ERROR = 'The listener specified is not a function.';
159
160 /**
161 * Compares to string values.
162 * @param {*} valueA
163 * @param {*} valueB
164 * @returns {Boolean}
165 * @private
166 */
167 function isValueEqualToValue(valueA, valueB) {
168 return valueA === valueB;
169 }
170
171 /**
172 * Checks if params exist and match the correct types.
173 * @param {String} eventType
174 * @param {Function} listener
175 * @returns {Boolean}
176 * @private
177 * @throws {TypeError} The listener specified is not a function.
178 */
179 function hasCompleteEventParams(eventType, listener) {
180 var hasParams = eventType && listener,
181 isTypeString = typeof eventType === 'string',
182 isTypeFunction = typeof listener === 'function';
183
184 if (!isTypeFunction) {
185 throw new TypeError(EventDispatcher.TYPE_ERROR);
186 }
187
188 return hasParams && isTypeString && isTypeFunction;
189 }
190
191 /**
192 * Finds a listener based on type and function.
193 * @private
194 * @param {Array} eventObjects
195 * @param {String} eventType
196 * @param {Function} listener
197 * @returns {Object} Return null if no object matches.
198 */
199 function getEventObject(eventObjects, eventType, listener) {
200 var i, numberOfEvents = eventObjects.length;
201
202 for (i = 0; i < numberOfEvents; i += 1) {
203 if (isValueEqualToValue(eventObjects[i].type, eventType) &&
204 isValueEqualToValue(eventObjects[i].callback, listener)) {
205 return eventObjects[i];
206 }
207 }
208
209 return null;
210 }
211
212 /**
213 * Finds a listener based on type and function.
214 * @private
215 * @param {Array} eventObjects
216 * @param {String} eventType
217 * @returns {Boolean} Return null if no object matches.
218 */
219 function hasEventType(eventObjects, eventType) {
220 var i, numberOfEvents = eventObjects.length;
221
222 for (i = 0; i < numberOfEvents; i += 1) {
223 if (isValueEqualToValue(eventObjects[i].type, eventType)) {
224 return !!eventObjects[i];
225 }
226 }
227
228 return false;
229 }
230
231 /**
232 * Registers an event listener object with an EventDispatcher object
233 * so that the listener receives notification of an event.
234 * If you no longer need an event listener, remove it by calling removeEventListener(),
235 * or memory problems could result.
236 * @memberOf EventDispatcher.prototype
237 * @param {String} eventType The type of event.
238 * @param {Function} listener The listener function that processes the event.
239 * This function must accept an Event object as its only parameter and should return nothing.
240 * @param {Object} listenerScope The scope you want the listener function to be called with.
241 * @returns {Boolean} Returns true if event is added.
242 * @throws {TypeError} The listener specified is not a function.
243 */
244 EventDispatcher.prototype.addEventListener = function (eventType, listener, listenerScope) {
245 if (!hasCompleteEventParams(eventType, listener) ||
246 getEventObject(this._eventObjects, eventType, listener)) {
247 return false;
248 }
249
250 this._eventObjects.push({
251 type: eventType,
252 callback: listener,
253 listenerScope: listenerScope
254 });
255
256 return true;
257 };
258
259 /**
260 * Dispatches an event into the event flow.
261 * The event target is the EventDispatcher object upon which the dispatchEvent() method is called.
262 * @memberOf EventDispatcher.prototype
263 * @param {Object} event The Event object that is dispatched into the event flow.
264 * @returns {Boolean} A value of true if the event was successfully dispatched.
265 */
266 EventDispatcher.prototype.dispatchEvent = function (event) {
267 var i, numberOfEvents = this._eventObjects.length, hasDispatched = false;
268
269 for (i = 0; i < numberOfEvents; i += 1) {
270 if (isValueEqualToValue(this._eventObjects[i].type, event.type)) {
271 event.target = this;
272
273 this._eventObjects[i].callback.apply(this._eventObjects[i].listenerScope, [event]);
274
275 hasDispatched = true;
276 }
277 }
278
279 return hasDispatched;
280 };
281
282 /**
283 * Checks whether the EventDispatcher object has any listeners registered for a specific type of event.
284 * @memberOf EventDispatcher.prototype
285 * @param {String} eventType The type of event.
286 * @returns {Boolean}
287 */
288 EventDispatcher.prototype.hasEventListener = function (eventType) {
289 return hasEventType(this._eventObjects, eventType);
290 };
291
292 /**
293 * Removes a listener from the EventDispatcher object.
294 * If there is no matching listener registered with the EventDispatcher object,
295 * a call to this method has no effect.
296 * @memberOf EventDispatcher.prototype
297 * @param {String} eventType The type of event.
298 * @param {Function} listener The listener object to remove.
299 * @throws {TypeError} The listener specified is not a function.
300 */
301 EventDispatcher.prototype.removeEventListener = function (eventType, listener) {
302 var eventObject;
303
304 if (this.hasEventListener(eventType) &&
305 hasCompleteEventParams(eventType, listener)) {
306
307 eventObject = getEventObject(this._eventObjects, eventType, listener);
308 this._eventObjects.splice(this._eventObjects.indexOf(eventObject), 1);
309 }
310 };
311
312 return EventDispatcher;
313}());
\No newline at end of file