diff --git a/src/scripts/lib/clay-config.js b/src/scripts/lib/clay-config.js index 7badb62..b8c17b4 100644 --- a/src/scripts/lib/clay-config.js +++ b/src/scripts/lib/clay-config.js @@ -193,7 +193,18 @@ ClayConfig.registerComponent = function(component) { var _component = _.copyObj(component); if (typeof _component.manipulator === 'string') { _component.manipulator = manipulators[component.manipulator]; + + if (!_component.manipulator) { + throw new Error('The manipulator: ' + component.manipulator + + ' does not exist in the built-in manipulators.'); + } } + + if (typeof _component.manipulator.set !== 'function' || + typeof _component.manipulator.get !== 'function') { + throw new Error('The manipulator must have both a `get` and `set` method'); + } + componentStore[_component.name] = _component; }; diff --git a/src/scripts/lib/clay-events.js b/src/scripts/lib/clay-events.js index fc5378f..643544e 100644 --- a/src/scripts/lib/clay-events.js +++ b/src/scripts/lib/clay-events.js @@ -1,7 +1,7 @@ 'use strict'; var $ = require('../vendor/minified/minified').$; - +var _ = require('../vendor/minified/minified')._; /** * Attaches event methods to the context. * Call with ClayEvents.call(yourObject, $eventTarget) @@ -11,48 +11,51 @@ var $ = require('../vendor/minified/minified').$; */ function ClayEvents($eventTarget) { var self = this; - var _eventProxies = {}; + var _eventProxies = []; /** - * Attach an event listener to the item. This proxies minified.js' on. - * If you are using a native event like "change", consider using "|change" instead - * as this will allow the native events to still work - * @see {@link http://minifiedjs.com/api/on.html|.on()} + * prefixes events with "|" * @param {string} events - * @param {function} handler - * @returns {object} + * @returns {string} + * @private */ - self.on = function(events, handler) { - var _events = events.split(' ').map(function(event) { + var _transformEventNames = function(events) { + return events.split(' ').map(function(event) { return '|' + event.replace(/^\|/, ''); }).join(' '); - var self = this; - _eventProxies[handler] = function() { - handler.apply(self, arguments); - }; - $eventTarget.on(_events, _eventProxies[handler]); - return self; + }; + + var _registerEventProxy = function(handler, proxy) { + var eventProxy = _.find(_eventProxies, function(item) { + return item.handler === handler ? item : null; + }); + + if (!eventProxy) { + eventProxy = { handler: handler, proxy: proxy }; + _eventProxies.push(eventProxy); + } + return eventProxy.proxy; + }; + + var _getEventProxy = function(handler) { + return _.find(_eventProxies, function(item) { + return item.handler === handler ? item.proxy : null; + }); }; /** - * Attach an event listener to the item. This proxies minified.js' one. - * If you are using a native event like "change", consider using "|change" instead - * as this will allow the native events to still work - * @see {@link http://minifiedjs.com/api/one.html|.one()} - * @param {string} events + * Attach an event listener to the item. + * @param {string} events - a space separated list of events * @param {function} handler - * @returns {object} + * @returns {ClayEvents} */ - self.one = function(events, handler) { - var _events = events.split(' ').map(function(event) { - return '|' + event.replace(/^\|/, ''); - }).join(' '); + self.on = function(events, handler) { + var _events = _transformEventNames(events); var self = this; - _eventProxies[handler] = function(event) { + var _proxy = _registerEventProxy(handler, function() { handler.apply(self, arguments); - $.off(_eventProxies[handler]); - }; - $eventTarget.on(_events, _eventProxies[handler]); + }); + $eventTarget.on(_events, _proxy); return self; }; @@ -60,10 +63,13 @@ function ClayEvents($eventTarget) { * Remove the given event handler. * @see {@link http://minifiedjs.com/api/off.html|$.off()} * @param {function} handler - * @returns {object} + * @returns {ClayEvents} */ self.off = function(handler) { - $.off(_eventProxies[handler]); + var _proxy = _getEventProxy(handler); + if (_proxy) { + $.off(_proxy); + } return self; }; @@ -73,7 +79,7 @@ function ClayEvents($eventTarget) { * @param {object} [eventObj] - an object to pass to the event handler, * provided the handler does not have custom arguments. * @see {@link http://minifiedjs.com/api/trigger.html|.trigger()} - * @returns {object} + * @returns {ClayEvents} */ self.trigger = function(name, eventObj) { $eventTarget.trigger(name, eventObj); diff --git a/src/scripts/vendor/minified/minified.js b/src/scripts/vendor/minified/minified.js index 36a8715..05b4061 100644 --- a/src/scripts/vendor/minified/minified.js +++ b/src/scripts/vendor/minified/minified.js @@ -1,7 +1,8 @@ // minified.js config start -- use this comment to re-create a configuration in the Builder // - Only sections add, always, amdsupport, copyobj, dollardollar, -// - each, eachobj, error, extend, format, formathtml, get, ht, html, isobject, -// - off, on, ready, request, select, set, template, trigger, underscore, wait. +// - each, eachobj, error, extend, find, format, formathtml, get, ht, html, +// - isobject, off, on, ready, request, select, set, template, trigger, underscore, +// - wait. // WARNING! This file is autogenerated from minified-master.js and others. @@ -1549,6 +1550,69 @@ define('minified', function() { */ 'each': listBind(each), + /*$ + * @id find + * @group LIST + * @requires + * @configurable default + * @name .find() + * @altname _.find() + * @syntax list.find(findFunc) + * @syntax list.find(element) + * @syntax list.find(findFunc, startIndex) + * @syntax list.find(element, startIndex) + * @syntax _.find(list, findFunc) + * @syntax _.find(list, element) + * @syntax _.find(list, findFunc, startIndex) + * @syntax _.find(list, element, startIndex) + * @module WEB, UTIL + * Finds a specific value in the list. There are two ways of calling find(): + *
+ * var i = _(1, 2, -4, 5, 2, -1).find(function(value, index) { if (value < 0) return index; }); // returns 2
+ *
+
+ * @example Finds the index of the first 5 in the array:
+ * + * var i = _.find([3, 6, 7, 6, 5, 4, 5], 5); // returns 4 (index of first 5) + *+ * + * @example Determines the position of the element with the id '#wanted' among all li elements: + *
+ * var elementIndex = $('li').find($$('#wanted'));
+ *
+ *
+ * @example Goes through the elements to find the first div that has the class 'myClass', and returns this element:
+ *
+ * var myClassElement = $('div').find(function(e) { if ($(e).is('.myClass')) return e; });
+ *
+ *
+ * @param list A list to use as input. Can be an array, a ##list#Minified list## or any other array-like structure with
+ * length property.
+ * @param findFunc The callback function(item, index) that will be invoked for every list item until it returns a non-null value:
+ *