vendor/assets/javascripts/emerson/view.js in emerson-0.0.3 vs vendor/assets/javascripts/emerson/view.js in emerson-0.0.4
- old
+ new
@@ -7,18 +7,30 @@
// Emerson Extension
// --------------------------------------------------------------------------
// ### Emerson.view module
// Entry point for defining a new View.
- var define = ns.view = function(name, setup) {
- return (library[name] = construct(name, setup || {}));
+ var view = ns.view = function(name, setup) {
+ return (views[name] = construct(name, setup || {}));
};
+ // ### Emerson.trait module
+ // Entry point for defining a new "trait".
+ //
+ // A trait can be thought of as a set of related behaviors and is essentially
+ // a special form of view.
+ //
+ // Traits have the additional capability of responding to an optional "mode"
+ // at intialization.
+ var trait = ns.trait = function(name, setup) {
+ return (traits[name] = construct(name, setup || {}));
+ };
+
// ### Module API
// * `ns` is a reference to the namespace.
// * `init` is a hook for initializing the module.
- _.extend(define, {
+ _.extend(view, {
ns : ns,
init : function init() {
configure();
$('body').view();
}
@@ -34,25 +46,21 @@
// ### $.view
//
// $.view(key);
//
// Accessor for defined Views.
+ $.view = function(key) {
+ return views[key];
+ };
+
+ // ### $.trait
//
- // Note that, while it is possible to manually execute View methods on an
- // object like so:
+ // $.trait(key);
//
- // $.view(key).fn.method.apply(object, arguments);
- //
- // such usage is not recommended as it:
- //
- // 1. circumvents the intentional transience provided by the framework.
- // 2. is likely to cause issues in that the called method will be working
- // with a non-initialized/-decorated object which may not have the
- // expected API.
- //
- $.view = function(key) {
- return library[key];
+ // Accessor for defined Traits. See `$.view`.
+ $.trait = function(key) {
+ return traits[key];
};
// ### $.fn.view
//
// $(target).view()
@@ -70,18 +78,16 @@
var as_view = element.add(element.find(selectors.view)).filter(selectors.view);
var as_trait = element.add(element.find(selectors.traits)).filter(selectors.traits);
_.each(as_view, function(html) {
var element = $(html);
- attach.apply(element, [element.data(attrs.view)]);
+ attach.call(element, views, [element.data(attrs.view)]);
});
_.each(as_trait, function(html) {
var element = $(html);
- attach.apply(element, _.map(element.data(attrs.traits).split(/\s+/), function(key) {
- return [':', key].join('');
- }));
+ attach.call(element, traits, element.data(attrs.traits).split(/\s+/), true);
});
});
return this;
};
@@ -119,12 +125,16 @@
// @private
var selectors = {};
// Storage place for the defined Views.
// @private
- var library = {};
+ var views = {};
+ // Storage place for the defined Traits.
+ // @private
+ var traits = {};
+
// Storage place for attachments made.
// @private
var attachments = {};
// emerson id, for tracking attachments.
@@ -164,29 +174,38 @@
return sub;
}
// ### attach
- // Given a (complex) list of keys, search the library for applicable View and
- // Trait definitions to apply to the object.
+ // Given a (complex) list of keys, search the libraries for applicable View
+ // and Trait definitions to apply to the object.
//
// Keeps track of which definitions have been applied, and does not re-apply.
//
// NOTE: `this`, in this call, should be a baselib-extended object containing
// a single element. e.g.,
//
// _.each($(selector), function(element) {
- // attach.apply($(element), [key, [subkey]]);
+ // attach.apply($(element), views, [key, [subkey]]);
// });
- function attach() {
+ //
+ // The `mode_p` predicate argument indicates whether the view type may accept
+ // a "mode", which should be true for traits (not for views).
+ function attach(library, keys, mode_p) {
var self = this, def;
var id = eid(this[0]);
- _.each(_.flatten(arguments), function(key) {
- var set = (attachments[key] || (attachments[key] = []));
- var built, init, events;
+ _.each(_.flatten(keys), function(key) {
+ var mode, match, built, init, events, set;
+ if(mode_p && (match = /^([^(]+)\((.+)\)/.exec(key))) {
+ key = match[1];
+ mode = match[2];
+ }
+
+ set = (attachments[key] || (attachments[key] = []));
+
if(_.include(set, id)) {
return; // do not re-apply.
}
// Build an instance, attach event handlers, initialize and record.
@@ -197,11 +216,11 @@
_.each(events, function(handler, key) {
bind(built, key, handler);
});
- init.call(built);
+ init.call(built, mode);
set.push(id);
}
});
return this;
@@ -218,12 +237,20 @@
// 'click' : handler,
// 'focus' : handler
// },
// document : { // bind document, for events
// 'click' : handler // fired outside of the view
+ // 'selector' : { // TODO
+ // 'click' : handler
+ // }
// }
// }
// });
+ //
+ // Emerson event handling differs from that of, say, stock jQuery in that
+ // `this` within the context of the handler will be a view instance. The
+ // event argument is unadultered, allowing access to the full set of targets
+ // as defined by the baselib (e.g., jQuery).
//
// Note that, in the document-binding case, an event like `click` would be a
// bad idea. A more useful (and less costly) use case would be a form of
// pub/sub.
//