emerson 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore
CHANGED
data/lib/emerson/version.rb
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
}
|
22
22
|
|
23
23
|
// Current version of the library. Keep in sync with `package.json`.
|
24
|
-
Emerson.VERSION = '0.0.
|
24
|
+
Emerson.VERSION = '0.0.7';
|
25
25
|
|
26
26
|
// Reference the base lib (one of jQuery, Zepto or Ender) as $.
|
27
27
|
var $ = Emerson.base = (root.jQuery || root.Zepto || root.ender);
|
@@ -79,12 +79,12 @@
|
|
79
79
|
var as_trait = element.add(element.find(selectors.traits)).filter(selectors.traits);
|
80
80
|
|
81
81
|
_.each(as_view, function(html) {
|
82
|
-
var element = $(html);
|
82
|
+
var element = $(html); // why jQuery here, if $sub() in a moment?
|
83
83
|
attach.call(element, views, [element.data(attrs.view)]);
|
84
84
|
});
|
85
85
|
|
86
86
|
_.each(as_trait, function(html) {
|
87
|
-
var element = $(html);
|
87
|
+
var element = $(html); // why jQuery here, if $sub() in a moment?
|
88
88
|
attach.call(element, traits, element.data(attrs.traits).split(/\s+/), true);
|
89
89
|
});
|
90
90
|
});
|
@@ -97,21 +97,68 @@
|
|
97
97
|
// --------------------------------------------------------------------------
|
98
98
|
|
99
99
|
// ### View constructor.
|
100
|
-
//
|
101
100
|
// View instances are "subclasses" of the base lib object, decorated with our
|
102
101
|
// View.prototype and the provided definition.
|
103
102
|
function View() {}
|
104
103
|
|
105
|
-
// View
|
104
|
+
// ### View setup definition.
|
106
105
|
_.extend(View, {
|
107
106
|
setup : {
|
108
107
|
initialize : function() {},
|
108
|
+
connected : false,
|
109
109
|
subscribe : {}
|
110
110
|
}
|
111
111
|
});
|
112
112
|
|
113
|
-
// View
|
114
|
-
|
113
|
+
// ### View prototype definition.
|
114
|
+
// **TODO**: Add specs for #connect & #outlet.
|
115
|
+
//
|
116
|
+
// * `connect` specifies which, if any, `outlets` should be registered as
|
117
|
+
// methods on the instance.
|
118
|
+
//
|
119
|
+
// false - do not connect any outlets (default)
|
120
|
+
// true - connect all outlets
|
121
|
+
// [outlet(s)] - connect the named outlets.
|
122
|
+
//
|
123
|
+
// * `outlet` returns descendent element(s) with matching a `data-outlet`
|
124
|
+
// attribute. This may be used for a given outlet whether or not it has
|
125
|
+
// been "connected". Outlets are useful as a means of allowing for View
|
126
|
+
// and Trait definitions with somewhat flexible DOM. Rather than using
|
127
|
+
// specific selectors (or polluting the `class` attribute), the DOM for
|
128
|
+
// a given instance indicates which nodes should match for the View.
|
129
|
+
_.extend(View.prototype, {
|
130
|
+
connect : function(config) {
|
131
|
+
var self = this;
|
132
|
+
var outlets = this.find('[data-outlet]');
|
133
|
+
|
134
|
+
if(config === true) {
|
135
|
+
_.each(outlets, function(subject) {
|
136
|
+
var outlet = $(subject);
|
137
|
+
|
138
|
+
self[outlet.data('outlet')] = function() {
|
139
|
+
return outlet;
|
140
|
+
};
|
141
|
+
});
|
142
|
+
}
|
143
|
+
else if($.isArray(config)) {
|
144
|
+
_.each(config, function(key) {
|
145
|
+
var outlet = self.find('[data-outlet="' + key + '"]');
|
146
|
+
|
147
|
+
if(outlet.length) {
|
148
|
+
self[key] = function() {
|
149
|
+
return outlet;
|
150
|
+
};
|
151
|
+
}
|
152
|
+
});
|
153
|
+
}
|
154
|
+
|
155
|
+
return this;
|
156
|
+
},
|
157
|
+
|
158
|
+
outlet : function(key) {
|
159
|
+
return this.find('[data-outlet="' + key + '"]');
|
160
|
+
}
|
161
|
+
});
|
115
162
|
|
116
163
|
|
117
164
|
// Internal Implementation
|
@@ -195,7 +242,7 @@
|
|
195
242
|
var id = eid(this[0]);
|
196
243
|
|
197
244
|
_.each(_.flatten(keys), function(key) {
|
198
|
-
var mode, match, built, init, events, set;
|
245
|
+
var mode, match, built, init, events, set, setup;
|
199
246
|
|
200
247
|
if(mode_p && (match = /^([^(]+)\((.+)\)/.exec(key))) {
|
201
248
|
key = match[1];
|
@@ -208,17 +255,17 @@
|
|
208
255
|
return; // do not re-apply.
|
209
256
|
}
|
210
257
|
|
211
|
-
// Build an instance,
|
258
|
+
// Build an instance, connect outlets, bind events, init and record.
|
212
259
|
if(def = library[key]) {
|
213
|
-
|
214
|
-
|
215
|
-
|
260
|
+
setup = def.setup;
|
261
|
+
built = def(self, self.context);
|
262
|
+
built.connect(setup.connected);
|
216
263
|
|
217
|
-
_.each(
|
264
|
+
_.each(setup.subscribe, function(handler, key) {
|
218
265
|
bind(built, key, handler);
|
219
266
|
});
|
220
267
|
|
221
|
-
|
268
|
+
setup.initialize.call(built, mode);
|
222
269
|
set.push(id);
|
223
270
|
}
|
224
271
|
});
|
@@ -231,17 +278,20 @@
|
|
231
278
|
//
|
232
279
|
// Emerson.view(key, {
|
233
280
|
// subscribe : {
|
234
|
-
// 'click' : handler,
|
235
|
-
// 'click focus' : handler,
|
236
|
-
// 'selector' : {
|
281
|
+
// 'click' : handler, // simple
|
282
|
+
// 'click focus' : handler, // multiple event types
|
283
|
+
// 'selector' : { // specific child target
|
237
284
|
// 'click' : handler,
|
238
285
|
// 'focus' : handler
|
239
286
|
// },
|
240
|
-
// document : {
|
241
|
-
// 'click' : handler
|
242
|
-
// 'selector' : {
|
287
|
+
// document : { // bind document, for events
|
288
|
+
// 'click' : handler // fired outside of the view
|
289
|
+
// 'selector' : {
|
243
290
|
// 'click' : handler
|
244
|
-
// }
|
291
|
+
// }
|
292
|
+
// },
|
293
|
+
// 'outlet:name' : { // a custom key to specify a
|
294
|
+
// 'click' : handler // defined outlet as the scope
|
245
295
|
// }
|
246
296
|
// }
|
247
297
|
// });
|
@@ -251,31 +301,38 @@
|
|
251
301
|
// event argument is unadultered, allowing access to the full set of targets
|
252
302
|
// as defined by the baselib (e.g., jQuery).
|
253
303
|
//
|
254
|
-
//
|
255
|
-
//
|
256
|
-
//
|
304
|
+
// **Special notes regarding document-bound handlers**:
|
305
|
+
//
|
306
|
+
// Binding an event like `click` (without selector scope) to the document
|
307
|
+
// would likely be a bad idea. A more useful (and less costly) use case
|
308
|
+
// would be a sort of pub/sub. For example, view "A" could trigger an event
|
309
|
+
// indicating that it has rendered a new instance, to which "B" (elsewhere)
|
310
|
+
// would listen in order to update, say, a count of instances of "A".
|
257
311
|
//
|
258
|
-
//
|
259
|
-
//
|
260
|
-
|
261
|
-
function bind(instance, key, handler, selector) {
|
312
|
+
// Additionally, event handlers bound to the document will not be cleaned
|
313
|
+
// up when the associated view instance is removed.
|
314
|
+
function bind(instance, key, handler, selector, binder) {
|
262
315
|
if($.isPlainObject(handler)) {
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
}
|
267
|
-
else {
|
268
|
-
if(selector === 'document') {
|
269
|
-
$(document).on(key, function() {
|
270
|
-
return handler.apply(instance, arguments);
|
316
|
+
if(key === 'document') {
|
317
|
+
_.each(handler, function(subhandler, subkey) {
|
318
|
+
bind(instance, subkey, subhandler, undefined, $(document));
|
271
319
|
});
|
272
320
|
}
|
273
321
|
else {
|
274
|
-
|
275
|
-
|
322
|
+
_.each(handler, function(subhandler, subkey) {
|
323
|
+
bind(instance, subkey, subhandler, key, binder);
|
276
324
|
});
|
277
325
|
}
|
278
326
|
}
|
327
|
+
else {
|
328
|
+
if(/^outlet/.test(selector)) {
|
329
|
+
selector = '[data-outlet="' + selector.split(':')[1] + '"]';
|
330
|
+
}
|
331
|
+
|
332
|
+
(binder || instance).on(key, selector, function() { // selector may be undefined
|
333
|
+
return handler.apply(instance, arguments);
|
334
|
+
});
|
335
|
+
}
|
279
336
|
}
|
280
337
|
|
281
338
|
// ### $sub
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emerson
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-16 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: transcendent views
|
15
15
|
email:
|