exojs 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,11 @@
1
- // Generated by CoffeeScript 1.6.1
2
1
  (function() {
3
2
  var Exo, Node, StateMachine;
4
3
 
5
4
  Exo = this.Exo = {};
6
5
 
7
- Exo.VERSION = '0.1.0';
6
+ Exo.VERSION = '0.1.2';
8
7
 
9
- if (typeof module !== "undefined" && module !== null) {
10
- module.exports = Exo;
11
- }
8
+ if (typeof module !== "undefined" && module !== null) module.exports = Exo;
12
9
 
13
10
  StateMachine = (function() {
14
11
 
@@ -20,17 +17,15 @@
20
17
 
21
18
  function StateMachine(opts) {
22
19
  var currentState, currentTransition, initialState, states, transitions, validate;
23
- if (opts == null) {
24
- opts = {};
25
- }
20
+ if (opts == null) opts = {};
26
21
  states = opts.states || [];
27
22
  transitions = opts.transitions || [];
28
23
  (validate = function() {
29
24
  var sCheck, tCheck, tStates, transition, unique;
30
25
  unique = function(a) {
31
- var key, output, value, _i, _ref, _results;
26
+ var key, output, value, _ref, _results;
32
27
  output = {};
33
- for (key = _i = 0, _ref = a.length; 0 <= _ref ? _i < _ref : _i > _ref; key = 0 <= _ref ? ++_i : --_i) {
28
+ for (key = 0, _ref = a.length; 0 <= _ref ? key < _ref : key > _ref; 0 <= _ref ? key++ : key--) {
34
29
  output[a[key]] = a[key];
35
30
  }
36
31
  _results = [];
@@ -117,7 +112,6 @@
117
112
  The Class Methods are used internally by the framework.
118
113
  */
119
114
 
120
-
121
115
  Node = (function() {
122
116
 
123
117
  Node.__currentId = 0;
@@ -141,7 +135,6 @@
141
135
  Generate the next unique node ID string.
142
136
  */
143
137
 
144
-
145
138
  Node.nextId = function() {
146
139
  Node.__currentId = Node.__currentId + 1;
147
140
  return Node.__currentId;
@@ -152,12 +145,9 @@
152
145
  @param [Node] node
153
146
  */
154
147
 
155
-
156
148
  Node.activate = function(node) {
157
149
  var parent, sibling;
158
- if (this.lineageIsBusy(node) || node.isActivated()) {
159
- return false;
160
- }
150
+ if (this.lineageIsBusy(node) || node.isActivated()) return false;
161
151
  if (parent = node.parent()) {
162
152
  if (parent.isActivated()) {
163
153
  if (parent.mode() === Node.Modes.EXCLUSIVE) {
@@ -170,9 +160,7 @@
170
160
  }
171
161
  }
172
162
  } else {
173
- if (!parent.childrenCanActivate()) {
174
- return false;
175
- }
163
+ if (!parent.childrenCanActivate()) return false;
176
164
  parent.setOnActivatedAction({
177
165
  node: node,
178
166
  transition: Node.Transitions.ACTIVATE
@@ -188,7 +176,6 @@
188
176
  @param [Node] node
189
177
  */
190
178
 
191
-
192
179
  Node.deactivate = function(node) {
193
180
  var child, _i, _len, _ref;
194
181
  if (node.isActivated() && !this.lineageIsBusy(node)) {
@@ -217,7 +204,6 @@
217
204
  @param [Node] node
218
205
  */
219
206
 
220
-
221
207
  Node.toggle = function(node) {
222
208
  if (node.isActivated()) {
223
209
  return this.deactivate(node);
@@ -231,17 +217,12 @@
231
217
  @param [Node] node
232
218
  */
233
219
 
234
-
235
220
  Node.lineageIsBusy = function(node) {
236
221
  var parent;
237
222
  if (parent = node.parent()) {
238
- if (parent.isBusy()) {
239
- return true;
240
- }
223
+ if (parent.isBusy()) return true;
241
224
  while (parent = parent.parent()) {
242
- if (parent.isBusy()) {
243
- return true;
244
- }
225
+ if (parent.isBusy()) return true;
245
226
  }
246
227
  }
247
228
  return false;
@@ -252,15 +233,10 @@
252
233
  @param [Node] node
253
234
  */
254
235
 
255
-
256
236
  Node.onNodeActivated = function(node) {
257
237
  var action;
258
- if (node.parent()) {
259
- node.parent().onChildActivated(node);
260
- }
261
- if (action = node.onActivatedAction()) {
262
- return this.processAction(action);
263
- }
238
+ if (node.parent()) node.parent().onChildActivated(node);
239
+ if (action = node.onActivatedAction()) return this.processAction(action);
264
240
  };
265
241
 
266
242
  /*
@@ -268,12 +244,9 @@
268
244
  @param [Node] node
269
245
  */
270
246
 
271
-
272
247
  Node.onNodeDeactivated = function(node) {
273
248
  var action, _ref;
274
- if (node.parent()) {
275
- node.parent().onChildDeactivated(node);
276
- }
249
+ if (node.parent()) node.parent().onChildDeactivated(node);
277
250
  if (action = node.onDeactivatedAction()) {
278
251
  return this.processAction(action);
279
252
  } else if ((_ref = node.parent()) != null ? _ref.defaultChild() : void 0) {
@@ -286,7 +259,6 @@
286
259
  @param [Object] action
287
260
  */
288
261
 
289
-
290
262
  Node.processAction = function(action) {
291
263
  if (action.transition === Node.Transitions.ACTIVATE) {
292
264
  return this.activate(action.node);
@@ -304,12 +276,9 @@
304
276
  @option options [Boolean] childrenCanActivate If true, this node can be activated by it's children. Defaults to true.
305
277
  */
306
278
 
307
-
308
279
  function Node(opts) {
309
- var child, node, _i, _j, _len, _len1, _ref, _ref1;
310
- if (opts == null) {
311
- opts = {};
312
- }
280
+ var child, node, _i, _j, _len, _len2, _ref, _ref2;
281
+ if (opts == null) opts = {};
313
282
  this._parent = null;
314
283
  this._childMap = {};
315
284
  this._defaultChild = null;
@@ -319,9 +288,9 @@
319
288
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
320
289
  node = _ref[_i];
321
290
  node.setParent(this);
322
- _ref1 = opts.children;
323
- for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
324
- child = _ref1[_j];
291
+ _ref2 = opts.children;
292
+ for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
293
+ child = _ref2[_j];
325
294
  this.addChild(child);
326
295
  }
327
296
  }
@@ -341,7 +310,6 @@
341
310
  Returns the id of the node. By default this is a generated unique String value.
342
311
  */
343
312
 
344
-
345
313
  Node.prototype.nodeId = function() {
346
314
  return this._nId;
347
315
  };
@@ -350,7 +318,6 @@
350
318
  Manually set the node ID. Caution: If multiple children of a node are given the same ID only one instance will persist.
351
319
  */
352
320
 
353
-
354
321
  Node.prototype.setNodeId = function(nid) {
355
322
  var _ref;
356
323
  if ((_ref = this._parent) != null) {
@@ -363,12 +330,9 @@
363
330
  Returns the internal state-machine instance.
364
331
  */
365
332
 
366
-
367
333
  Node.prototype.sm = function() {
368
334
  var _this = this;
369
- if (this._smRef) {
370
- return this._smRef;
371
- }
335
+ if (this._smRef) return this._smRef;
372
336
  this._smRef = new Exo.StateMachine({
373
337
  states: [Node.States.DEACTIVATED, Node.States.ACTIVATED],
374
338
  initialState: this._initialState,
@@ -399,7 +363,6 @@
399
363
  Children call this function on their parent when their node ID has been manually changed.
400
364
  */
401
365
 
402
-
403
366
  Node.prototype.onChildIdUpdated = function(oldId, newId, child) {
404
367
  delete this._childMap[oldId];
405
368
  return this._childMap[newId] = child;
@@ -411,7 +374,6 @@
411
374
  with a reference to the sibling.
412
375
  */
413
376
 
414
-
415
377
  Node.prototype.setOnActivatedAction = function(action) {
416
378
  return this._onActivatedAction = action;
417
379
  };
@@ -420,7 +382,6 @@
420
382
  A getter to read the onActivatedAction value.
421
383
  */
422
384
 
423
-
424
385
  Node.prototype.onActivatedAction = function() {
425
386
  return this._onActivatedAction;
426
387
  };
@@ -429,7 +390,6 @@
429
390
  Used by the framework to chain sequences of Node deactivation.
430
391
  */
431
392
 
432
-
433
393
  Node.prototype.setOnDeactivatedAction = function(action) {
434
394
  return this._onDeactivatedAction = action;
435
395
  };
@@ -438,7 +398,6 @@
438
398
  Get the onDeactivatedAction value.
439
399
  */
440
400
 
441
-
442
401
  Node.prototype.onDeactivatedAction = function() {
443
402
  return this._onDeactivatedAction;
444
403
  };
@@ -447,7 +406,6 @@
447
406
  Get the childrenCanActivate setting.
448
407
  */
449
408
 
450
-
451
409
  Node.prototype.childrenCanActivate = function() {
452
410
  return this._childrenCanActivate;
453
411
  };
@@ -457,7 +415,6 @@
457
415
  @param [String] mode
458
416
  */
459
417
 
460
-
461
418
  Node.prototype.setMode = function(m) {
462
419
  return this._mode = m;
463
420
  };
@@ -466,7 +423,6 @@
466
423
  Get the mode.
467
424
  */
468
425
 
469
-
470
426
  Node.prototype.mode = function() {
471
427
  return this._mode;
472
428
  };
@@ -476,7 +432,6 @@
476
432
  @param [Node] node
477
433
  */
478
434
 
479
-
480
435
  Node.prototype.setParent = function(node) {
481
436
  return this._parent = node;
482
437
  };
@@ -485,7 +440,6 @@
485
440
  Get the parent Node.
486
441
  */
487
442
 
488
-
489
443
  Node.prototype.parent = function() {
490
444
  return this._parent;
491
445
  };
@@ -495,7 +449,6 @@
495
449
  @param [Node] node
496
450
  */
497
451
 
498
-
499
452
  Node.prototype.addChild = function(node) {
500
453
  if (node === null || typeof node === 'undefined') {
501
454
  throw new Error("ExoReferenceError -> addChild: " + node + " is not a valid Exo.Node");
@@ -512,7 +465,6 @@
512
465
  @param [Node] node
513
466
  */
514
467
 
515
-
516
468
  Node.prototype.removeChild = function(node) {
517
469
  return delete this._childMap[node.nodeId()];
518
470
  };
@@ -523,7 +475,6 @@
523
475
  @param [Node] node
524
476
  */
525
477
 
526
-
527
478
  Node.prototype.setDefaultChild = function(node) {
528
479
  return this._defaultChild = node;
529
480
  };
@@ -532,7 +483,6 @@
532
483
  Get the default child Node.
533
484
  */
534
485
 
535
-
536
486
  Node.prototype.defaultChild = function() {
537
487
  return this._defaultChild;
538
488
  };
@@ -541,7 +491,6 @@
541
491
  An alias of childrenAsArray
542
492
  */
543
493
 
544
-
545
494
  Node.prototype.children = function() {
546
495
  return this.childrenAsArray();
547
496
  };
@@ -550,7 +499,6 @@
550
499
  Get the children of this node as an Array.
551
500
  */
552
501
 
553
-
554
502
  Node.prototype.childrenAsArray = function(obj) {
555
503
  var arr, child, id, _ref;
556
504
  arr = [];
@@ -566,7 +514,6 @@
566
514
  Get an Array of activated child nodes.
567
515
  */
568
516
 
569
-
570
517
  Node.prototype.activatedChildren = function() {
571
518
  return this.children().filter(function(n) {
572
519
  return n.isActivated();
@@ -578,7 +525,6 @@
578
525
  @param [String] id
579
526
  */
580
527
 
581
-
582
528
  Node.prototype.childById = function(id) {
583
529
  return this._childMap[id];
584
530
  };
@@ -588,20 +534,15 @@
588
534
  @param [String] id
589
535
  */
590
536
 
591
-
592
537
  Node.prototype.descendantById = function(id) {
593
538
  var child, descendant, _i, _len, _ref;
594
539
  child = this.childById(id);
595
- if (child) {
596
- return child;
597
- }
540
+ if (child) return child;
598
541
  _ref = this.children();
599
542
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
600
543
  child = _ref[_i];
601
544
  descendant = child.getDescendantById(id);
602
- if (descendant) {
603
- return descendant;
604
- }
545
+ if (descendant) return descendant;
605
546
  }
606
547
  };
607
548
 
@@ -609,7 +550,6 @@
609
550
  Get an Array of Node instances that have the same parent as this instance.
610
551
  */
611
552
 
612
-
613
553
  Node.prototype.siblings = function() {
614
554
  var ownId;
615
555
  ownId = this.nodeId();
@@ -625,7 +565,6 @@
625
565
  Get a boolean stating if this Node instance is in the 'activated' state.
626
566
  */
627
567
 
628
-
629
568
  Node.prototype.isActivated = function() {
630
569
  return this.sm().currentState() === Node.States.ACTIVATED;
631
570
  };
@@ -634,7 +573,6 @@
634
573
  Get a boolean stating if this Node instance is currently transitioning.
635
574
  */
636
575
 
637
-
638
576
  Node.prototype.isTransitioning = function() {
639
577
  return this.sm().isTransitioning();
640
578
  };
@@ -644,11 +582,8 @@
644
582
  Note: Child transition status will only be included if mode == Node.Modes.Exclusive
645
583
  */
646
584
 
647
-
648
585
  Node.prototype.isBusy = function() {
649
- if (this.isTransitioning()) {
650
- return true;
651
- }
586
+ if (this.isTransitioning()) return true;
652
587
  if (this.mode() === Node.Modes.EXCLUSIVE) {
653
588
  if (this.children().filter(function(n) {
654
589
  return n.isBusy();
@@ -663,7 +598,6 @@
663
598
  Get a boolean stating if any of the children of this node are transitioning.
664
599
  */
665
600
 
666
-
667
601
  Node.prototype.haveBusyChildren = function() {
668
602
  return this.children().filter(function(n) {
669
603
  return n.isBusy();
@@ -675,7 +609,6 @@
675
609
  @param [String] transition
676
610
  */
677
611
 
678
-
679
612
  Node.prototype.attemptTransition = function(t) {
680
613
  return this.sm().attemptTransition(t);
681
614
  };
@@ -684,7 +617,6 @@
684
617
  Attempt to activate this Node instance.
685
618
  */
686
619
 
687
-
688
620
  Node.prototype.activate = function() {
689
621
  return Node.activate(this);
690
622
  };
@@ -693,7 +625,6 @@
693
625
  Attempt to deactivate this Node instance.
694
626
  */
695
627
 
696
-
697
628
  Node.prototype.deactivate = function() {
698
629
  return Node.deactivate(this);
699
630
  };
@@ -702,7 +633,6 @@
702
633
  Attempt to toggle this Node instance.
703
634
  */
704
635
 
705
-
706
636
  Node.prototype.toggle = function() {
707
637
  return Node.toggle(this);
708
638
  };
@@ -711,7 +641,6 @@
711
641
  Attempt to deactivate all children of this Node instance.
712
642
  */
713
643
 
714
-
715
644
  Node.prototype.deactivateChildren = function() {
716
645
  var child, _i, _len, _ref, _results;
717
646
  _ref = this.children();
@@ -727,7 +656,6 @@
727
656
  Should be called when the activate transition is done. Can be overridden.
728
657
  */
729
658
 
730
-
731
659
  Node.prototype.onActivated = function() {
732
660
  this.sm().onTransitionComplete();
733
661
  Node.onNodeActivated(this);
@@ -738,7 +666,6 @@
738
666
  Should be called when the deactivate transition is done. Can be overridden.
739
667
  */
740
668
 
741
-
742
669
  Node.prototype.onDeactivated = function() {
743
670
  this.sm().onTransitionComplete();
744
671
  Node.onNodeDeactivated(this);
@@ -749,14 +676,12 @@
749
676
  Is called before doActivate. Can be overridden.
750
677
  */
751
678
 
752
-
753
679
  Node.prototype.beforeActivate = function() {};
754
680
 
755
681
  /*
756
682
  Called when the activate transition should begin. Can be overridden.
757
683
  */
758
684
 
759
-
760
685
  Node.prototype.doActivate = function() {
761
686
  return this.onActivated();
762
687
  };
@@ -765,14 +690,12 @@
765
690
  Is called before doDectivate. Can be overridden.
766
691
  */
767
692
 
768
-
769
693
  Node.prototype.beforeDeactivate = function() {};
770
694
 
771
695
  /*
772
696
  Called when the deactivate transition should begin. Can be overridden.
773
697
  */
774
698
 
775
-
776
699
  Node.prototype.doDeactivate = function() {
777
700
  return this.onDeactivated();
778
701
  };
@@ -781,14 +704,12 @@
781
704
  Called when a child Node of this instance has been activated.
782
705
  */
783
706
 
784
-
785
707
  Node.prototype.onChildActivated = function(child) {};
786
708
 
787
709
  /*
788
710
  Called when a child Node of this instance has been deactivated.
789
711
  */
790
712
 
791
-
792
713
  Node.prototype.onChildDeactivated = function(child) {};
793
714
 
794
715
  return Node;
@@ -1,9 +1,9 @@
1
1
  (function() {
2
- var CSSTransitioner, Controller, List, Model, Spine, _base, _base2,
2
+ var CSSTransitioner, Controller, DOMInflator, DOMOrganizer, List, Model, Spine, _base, _base2, _base3, _base4, _base5, _base6,
3
3
  __hasProp = Object.prototype.hasOwnProperty,
4
4
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; },
5
- __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
6
- __slice = Array.prototype.slice;
5
+ __slice = Array.prototype.slice,
6
+ __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
7
7
 
8
8
  Spine = this.Spine || require('spine');
9
9
 
@@ -16,6 +16,7 @@
16
16
  if (opts == null) opts = {};
17
17
  this._nodeOpts = opts;
18
18
  this._node = null;
19
+ this.filters = this.constructor.filters || {};
19
20
  this.node().beforeActivate = function() {
20
21
  var _ref;
21
22
  _this.trigger('beforeActivate', _this);
@@ -44,9 +45,29 @@
44
45
  if (opts.mode) delete opts.mode;
45
46
  if (opts.children) delete opts.children;
46
47
  Controller.__super__.constructor.call(this, opts);
47
- this.prepare();
48
+ this.callWithFilters('prepare');
48
49
  }
49
50
 
51
+ Controller.prototype.callWithFilters = function() {
52
+ var args, methName;
53
+ methName = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
54
+ this.callFilter("before_" + methName);
55
+ this[methName].apply(this, args);
56
+ return this.callFilter("after_" + methName);
57
+ };
58
+
59
+ Controller.prototype.callFilter = function(methName) {
60
+ var funcName, _i, _len, _ref, _results;
61
+ if (!this.filters[methName]) return;
62
+ _ref = this.filters[methName];
63
+ _results = [];
64
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
65
+ funcName = _ref[_i];
66
+ _results.push(this[funcName].call(this));
67
+ }
68
+ return _results;
69
+ };
70
+
50
71
  Controller.prototype.node = function() {
51
72
  if (!this._node) {
52
73
  this._node = new Exo.Node(this._nodeOpts);
@@ -203,11 +224,17 @@
203
224
  }
204
225
  };
205
226
 
227
+ /*
228
+ Erase the current DOM children and render
229
+ all items in the collection.
230
+ */
231
+
206
232
  List.prototype.renderTemplates = function(collection) {
207
233
  var el, html, item, templates, _i, _len, _results;
208
234
  templates = this.templates || {
209
235
  "default": this.template
210
236
  };
237
+ this.html('');
211
238
  _results = [];
212
239
  for (_i = 0, _len = collection.length; _i < _len; _i++) {
213
240
  item = collection[_i];
@@ -236,11 +263,11 @@
236
263
 
237
264
  List.prototype.getOrCreateChild = function(item, controller, opts) {
238
265
  var child;
239
- child = this.childById(item.constructor.className + item.id);
266
+ child = this.childById(item.constructor.className + item.cid);
240
267
  if (!child) {
241
268
  child = new controller(opts);
242
269
  this.addChild(child);
243
- child.setNodeId(item.constructor.className + item.id);
270
+ child.setNodeId(item.constructor.className + item.cid);
244
271
  child.prepareWithModel(item);
245
272
  this.append(child);
246
273
  $(child.el).data('item', item);
@@ -254,7 +281,7 @@
254
281
  orphans = children.filter(function(child) {
255
282
  var _ref;
256
283
  return _ref = child.nodeId(), __indexOf.call(collection.map(function(item) {
257
- return item.constructor.className + item.id;
284
+ return item.constructor.className + item.cid;
258
285
  }), _ref) < 0;
259
286
  });
260
287
  _results = [];
@@ -347,26 +374,32 @@
347
374
 
348
375
  CSSTransitioner = {
349
376
  cssTransitionEndEvents: 'transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd',
350
- cssActiveClass: 'active',
377
+ cssActivateClass: 'active',
378
+ cssDeactivateClass: void 0,
351
379
  cssTransitionDelay: 10,
352
380
  doActivate: function() {
353
- return this.cssStartTransition('addClass', this.onActivated);
381
+ if (this.cssDeactivateClass) this.el.removeClass(this.cssDeactivateClass);
382
+ return this.cssStartTransition('addClass', this.cssActivateClass, this.onActivated);
354
383
  },
355
384
  doDeactivate: function() {
356
- return this.cssStartTransition('removeClass', this.onDeactivated);
385
+ if (this.cssDeactivateClass) {
386
+ return this.cssStartTransition('addClass', this.cssDeactivateClass, this.onDeactivated);
387
+ } else {
388
+ return this.cssStartTransition('removeClass', this.cssActivateClass, this.onDeactivated);
389
+ }
357
390
  },
358
- cssListen: function(callback) {
391
+ cssListen: function(callback, className) {
359
392
  var _this = this;
360
- return this.el.on(this.cssTransitionEndEvents, function() {
393
+ return $(this.el).bind(this.cssTransitionEndEvents, function() {
361
394
  callback.call(_this);
362
395
  return _this.el.off(_this.cssTransitionEndEvents);
363
396
  });
364
397
  },
365
- cssStartTransition: function(mutatorFunc, callback) {
398
+ cssStartTransition: function(mutatorFunc, className, callback) {
366
399
  var _this = this;
367
- this.cssListen(callback);
400
+ this.cssListen(callback, className);
368
401
  return this.delay(function() {
369
- return _this.el[mutatorFunc].call(_this.el, _this.cssActiveClass);
402
+ return _this.el[mutatorFunc].call(_this.el, className);
370
403
  }, this.cssTransitionDelay);
371
404
  }
372
405
  };
@@ -385,4 +418,206 @@
385
418
  module.exports = CSSTransitioner;
386
419
  }
387
420
 
421
+ DOMInflator = {
422
+ included: function() {
423
+ var _base3;
424
+ return ((_base3 = (this.filters || (this.filters = {})))['before_prepare'] || (_base3['before_prepare'] = [])).push('inflateFromDOM');
425
+ },
426
+ inflateFromDOM: function() {
427
+ var classNames, collection, dashifiedClassNames, elements, selectors,
428
+ _this = this;
429
+ console.log('inflateFromDOM!');
430
+ if (typeof this['deactivateAndKillOrphans'] !== 'function') return;
431
+ classNames = [];
432
+ if (this.modelClass) {
433
+ classNames = [this.modelClass.className];
434
+ } else if (this.modelClasses) {
435
+ classNames = this.modelClasses.map(function(modelClass) {
436
+ return modelClass.className;
437
+ });
438
+ }
439
+ if (!(classNames.length > 0)) throw "No Model Classes specified!";
440
+ dashifiedClassNames = classNames.map(function(className) {
441
+ return _this.dashify(className);
442
+ });
443
+ selectors = dashifiedClassNames.map(function(className) {
444
+ return "[data-" + className + "-id]";
445
+ });
446
+ elements = this.el.find.call(this.el, selectors.join(', ')).filter(function(i) {
447
+ var className, _i, _len;
448
+ for (_i = 0, _len = dashifiedClassNames.length; _i < _len; _i++) {
449
+ className = dashifiedClassNames[_i];
450
+ if ($(this).data("" + className + "-id")) return true;
451
+ }
452
+ });
453
+ collection = elements.map(function(index, el) {
454
+ var className, downcaseName, id, _i, _len;
455
+ id = void 0;
456
+ for (_i = 0, _len = classNames.length; _i < _len; _i++) {
457
+ className = classNames[_i];
458
+ downcaseName = className[0].toLowerCase() + className.slice(1);
459
+ if (id = $(el).data("" + downcaseName + "Id")) break;
460
+ }
461
+ if (!id) throw "Invalid DOM";
462
+ return _this.inflateModel($(el), className);
463
+ });
464
+ if (this.template || this.templates) {
465
+ return this.tagElements(collection);
466
+ } else if (this.controller || this.controllers) {
467
+ return this.createControllers(collection);
468
+ }
469
+ },
470
+ /*
471
+ Tag existing DOM elements that should be represented by
472
+ rendered templates.
473
+ */
474
+ tagElements: function(collection) {
475
+ var el, model, _i, _len, _results;
476
+ _results = [];
477
+ for (_i = 0, _len = collection.length; _i < _len; _i++) {
478
+ model = collection[_i];
479
+ el = this.el.find("[data-" + (this.dashify(model.constructor.className)) + "-id]");
480
+ _results.push(this.tagElement(el, model));
481
+ }
482
+ return _results;
483
+ },
484
+ /*
485
+ Create controllers for existing DOM elements and add them
486
+ to the Exo hierarchy, tag them with corresponding models.
487
+ */
488
+ createControllers: function(collection) {
489
+ var child, controllerClass, controllers, el, model, _i, _len, _results;
490
+ if (!(this.controller || this.controllers)) {
491
+ throw 'No controllers specified!';
492
+ }
493
+ controllers = this.controllers || {
494
+ "default": this.controller
495
+ };
496
+ _results = [];
497
+ for (_i = 0, _len = collection.length; _i < _len; _i++) {
498
+ model = collection[_i];
499
+ controllerClass = controllers['default'] || controllers[model.constructor.className];
500
+ el = this.el.find("[data-" + (this.dashify(model.constructor.className)) + "-id]");
501
+ this.tagElement(el, model);
502
+ child = new controllerClass({
503
+ el: el,
504
+ model: model,
505
+ initialState: Exo.Node.States.ACTIVATED
506
+ });
507
+ _results.push(this.addChild(child));
508
+ }
509
+ return _results;
510
+ },
511
+ tagElement: function(el, model) {
512
+ return $(el).data('item', model);
513
+ },
514
+ inflateModel: function(el, modelClassName) {
515
+ var attr, attributes, className, id, model, modelClass, targetEl, _i, _len, _ref;
516
+ if (this.modelClass) {
517
+ modelClass = this.modelClass;
518
+ } else if (this.modelClasses) {
519
+ modelClass = this.modelClasses.filter(function(item) {
520
+ return item.className === modelClassName;
521
+ })[0];
522
+ } else {
523
+ throw "No Model Class specified!";
524
+ }
525
+ if (!modelClass) return;
526
+ className = this.dashify(modelClass.className);
527
+ id = el.attr("data-" + className + "-id");
528
+ attributes = {
529
+ id: id
530
+ };
531
+ _ref = modelClass.attributes;
532
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
533
+ attr = _ref[_i];
534
+ if (targetEl = el.find("[data-" + className + "-attribute='" + attr + "']")[0]) {
535
+ attributes[attr] = $(targetEl).text();
536
+ }
537
+ }
538
+ model = new modelClass(attributes);
539
+ model.constructor.records[model.id] = model;
540
+ return model;
541
+ },
542
+ /*
543
+ Take a CamelCase model class-name and return
544
+ a dashified version: camel-case.
545
+ @param [String] string
546
+ */
547
+ dashify: function(name) {
548
+ var first;
549
+ first = true;
550
+ return name.replace(/[A-Z]/g, function(match) {
551
+ if (!first) {
552
+ return "-" + (match.toLowerCase());
553
+ } else {
554
+ first = false;
555
+ return match.toLowerCase();
556
+ }
557
+ });
558
+ }
559
+ };
560
+
561
+ if (typeof Exo !== "undefined" && Exo !== null) Exo.Spine || (Exo.Spine = {});
562
+
563
+ if (typeof Exo !== "undefined" && Exo !== null) {
564
+ (_base3 = Exo.Spine).Modules || (_base3.Modules = {});
565
+ }
566
+
567
+ if (typeof Exo !== "undefined" && Exo !== null) {
568
+ (_base4 = Exo.Spine.Modules).DOMInflator || (_base4.DOMInflator = DOMInflator);
569
+ }
570
+
571
+ if (typeof module !== "undefined" && module !== null) {
572
+ module.exports = DOMInflator;
573
+ }
574
+
575
+ DOMOrganizer = {
576
+ reorganizeDOM: function() {
577
+ var child, el, getElAt, index, prev, _len, _ref, _results,
578
+ _this = this;
579
+ if (this.children().filter(function(child) {
580
+ return child.isDeactivating();
581
+ }).length !== 0) {
582
+ return;
583
+ }
584
+ getElAt = function(index) {
585
+ var child, model;
586
+ model = _this.collection[index];
587
+ child = _this.childById("" + model.constructor.className + model.cid);
588
+ return child.el;
589
+ };
590
+ _ref = this.collection;
591
+ _results = [];
592
+ for (index = 0, _len = _ref.length; index < _len; index++) {
593
+ child = _ref[index];
594
+ if (el = getElAt(index)) {
595
+ if (index === 0) {
596
+ _results.push($(this.el).prepend(el));
597
+ } else {
598
+ prev = getElAt(index - 1);
599
+ _results.push(el.insertAfter(prev));
600
+ }
601
+ } else {
602
+ _results.push(void 0);
603
+ }
604
+ }
605
+ return _results;
606
+ }
607
+ };
608
+
609
+ if (typeof Exo !== "undefined" && Exo !== null) Exo.Spine || (Exo.Spine = {});
610
+
611
+ if (typeof Exo !== "undefined" && Exo !== null) {
612
+ (_base5 = Exo.Spine).Modules || (_base5.Modules = {});
613
+ }
614
+
615
+ if (typeof Exo !== "undefined" && Exo !== null) {
616
+ (_base6 = Exo.Spine.Modules).DOMOrganizer || (_base6.DOMOrganizer = DOMOrganizer);
617
+ }
618
+
619
+ if (typeof module !== "undefined" && module !== null) {
620
+ module.exports = DOMOrganizer;
621
+ }
622
+
388
623
  }).call(this);
data/lib/exojs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ExoJS
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,24 +1,28 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: exojs
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.2
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.2.0
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Jonathan Pettersson
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-31 00:00:00.000000000 Z
12
+
13
+ date: 2013-04-11 00:00:00 Z
13
14
  dependencies: []
14
- description: Gives you easy access to the latest stable version of the Exo.js JavaScript
15
- library, for use in Middleman, Rails or other Sprockets capable applications.
16
- email:
15
+
16
+ description: Gives you easy access to the latest stable version of the Exo.js JavaScript library, for use in Middleman, Rails or other Sprockets capable applications.
17
+ email:
17
18
  - jonathan@spacetofu.com
18
19
  executables: []
20
+
19
21
  extensions: []
22
+
20
23
  extra_rdoc_files: []
21
- files:
24
+
25
+ files:
22
26
  - .gitignore
23
27
  - Gemfile
24
28
  - README.md
@@ -30,26 +34,30 @@ files:
30
34
  - lib/exojs/version.rb
31
35
  homepage: https://github.com/jpettersson/exojs-gem
32
36
  licenses: []
37
+
33
38
  post_install_message:
34
39
  rdoc_options: []
35
- require_paths:
40
+
41
+ require_paths:
36
42
  - lib
37
- required_ruby_version: !ruby/object:Gem::Requirement
43
+ required_ruby_version: !ruby/object:Gem::Requirement
38
44
  none: false
39
- requirements:
40
- - - ! '>='
41
- - !ruby/object:Gem::Version
42
- version: '0'
43
- required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
50
  none: false
45
- requirements:
46
- - - ! '>='
47
- - !ruby/object:Gem::Version
48
- version: '0'
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
49
55
  requirements: []
56
+
50
57
  rubyforge_project: exojs
51
- rubygems_version: 1.8.24
58
+ rubygems_version: 1.8.25
52
59
  signing_key:
53
60
  specification_version: 3
54
61
  summary: Serves you the Exo.js library through Sprockets
55
62
  test_files: []
63
+