exojs 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+