serenade 0.3.0.1 → 0.4.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,2351 +1,2457 @@
1
1
  /**
2
- * Serenade.js JavaScript Framework v0.3.0
3
- * Revision: 7e7103d7f5
2
+ * Serenade.js JavaScript Framework v0.4.0
3
+ * Revision: 5301262146
4
4
  * http://github.com/elabs/serenade.js
5
5
  *
6
6
  * Copyright 2011, Jonas Nicklas, Elabs AB
7
7
  * Released under the MIT License
8
8
  */
9
9
  (function(root) {
10
- var Serenade = function() {
11
- function require(path){ return require[path]; }
12
- require['./events'] = new function() {
13
- var exports = this;
14
- (function() {
15
- var __slice = [].slice;
16
-
17
- exports.Events = {
18
- bind: function(ev, callback) {
19
- var calls, evs, name, _i, _len;
20
- evs = ev.split(' ');
21
- calls = this.hasOwnProperty('_callbacks') && this._callbacks || (this._callbacks = {});
22
- for (_i = 0, _len = evs.length; _i < _len; _i++) {
23
- name = evs[_i];
24
- calls[name] || (calls[name] = []);
25
- calls[name].push(callback);
26
- }
27
- return this;
28
- },
29
- one: function(ev, callback) {
30
- return this.bind(ev, function() {
31
- this.unbind(ev, arguments.callee);
32
- return callback.apply(this, arguments);
33
- });
34
- },
35
- trigger: function() {
36
- var args, callback, ev, list, _i, _len, _ref;
37
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
38
- ev = args.shift();
39
- list = this.hasOwnProperty('_callbacks') && ((_ref = this._callbacks) != null ? _ref[ev] : void 0);
40
- if (!list) {
41
- return false;
42
- }
43
- for (_i = 0, _len = list.length; _i < _len; _i++) {
44
- callback = list[_i];
45
- callback.apply(this, args);
46
- }
47
- return true;
48
- },
49
- unbind: function(ev, callback) {
50
- var cb, i, list, _i, _len, _ref;
51
- if (!ev) {
52
- this._callbacks = {};
53
- return this;
54
- }
55
- list = (_ref = this._callbacks) != null ? _ref[ev] : void 0;
56
- if (!list) {
57
- return this;
58
- }
59
- if (!callback) {
60
- delete this._callbacks[ev];
61
- return this;
62
- }
63
- for (i = _i = 0, _len = list.length; _i < _len; i = ++_i) {
64
- cb = list[i];
65
- if (!(cb === callback)) {
66
- continue;
67
- }
68
- list = list.slice();
69
- list.splice(i, 1);
70
- this._callbacks[ev] = list;
71
- break;
72
- }
73
- return this;
74
- }
75
- };
76
-
77
- exports.NodeEvents = {
78
- bindEvent: function(to, name, fun) {
79
- if (to != null ? to.bind : void 0) {
80
- this.boundEvents || (this.boundEvents = []);
81
- this.boundEvents.push({
82
- to: to,
83
- name: name,
84
- fun: fun
85
- });
86
- return to.bind(name, fun);
87
- }
88
- },
89
- unbindEvents: function() {
90
- var fun, name, node, to, _i, _j, _len, _len1, _ref, _ref1, _ref2, _results;
91
- if (typeof this.trigger === "function") {
92
- this.trigger("unload");
93
- }
94
- _ref = this.nodes();
95
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
96
- node = _ref[_i];
97
- node.unbindEvents();
98
- }
99
- if (this.boundEvents) {
100
- _ref1 = this.boundEvents;
101
- _results = [];
102
- for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
103
- _ref2 = _ref1[_j], to = _ref2.to, name = _ref2.name, fun = _ref2.fun;
104
- _results.push(to.unbind(name, fun));
105
- }
106
- return _results;
107
- }
108
- }
109
- };
110
-
111
- }).call(this);
112
-
113
- };require['./helpers'] = new function() {
114
- var exports = this;
115
- (function() {
116
- var Helpers,
117
- __hasProp = {}.hasOwnProperty;
118
-
119
- Helpers = {
120
- prefix: "_prop_",
121
- extend: function(target, source) {
122
- var key, value, _results;
123
- _results = [];
124
- for (key in source) {
125
- if (!__hasProp.call(source, key)) continue;
126
- value = source[key];
127
- _results.push(target[key] = value);
128
- }
129
- return _results;
130
- },
131
- format: function(model, key) {
132
- var formatter, value, _ref;
133
- value = model[key];
134
- formatter = (_ref = model[Helpers.prefix + key]) != null ? _ref.format : void 0;
135
- if (typeof formatter === 'function') {
136
- return formatter.call(this, value);
137
- } else {
138
- return value;
139
- }
140
- },
141
- isArray: function(object) {
142
- return Object.prototype.toString.call(object) === "[object Array]";
143
- },
144
- pairToObject: function(one, two) {
145
- var temp;
146
- temp = {};
147
- temp[one] = two;
148
- return temp;
149
- },
150
- serializeObject: function(object) {
151
- var item, _i, _len, _results;
152
- if (object && typeof object.toJSON === 'function') {
153
- return object.toJSON();
154
- } else if (Helpers.isArray(object)) {
155
- _results = [];
156
- for (_i = 0, _len = object.length; _i < _len; _i++) {
157
- item = object[_i];
158
- _results.push(Helpers.serializeObject(item));
159
- }
160
- return _results;
161
- } else {
162
- return object;
163
- }
164
- },
165
- capitalize: function(word) {
166
- return word.slice(0, 1).toUpperCase() + word.slice(1);
167
- }
168
- };
169
-
170
- Helpers.extend(exports, Helpers);
171
-
172
- }).call(this);
173
-
174
- };require['./cache'] = new function() {
175
- var exports = this;
176
- (function() {
177
- var Cache, serializeObject;
178
-
179
- serializeObject = require('./helpers').serializeObject;
180
-
181
- Cache = {
182
- _storage: typeof window !== "undefined" && window !== null ? window.localStorage : void 0,
183
- _identityMap: {},
184
- get: function(ctor, id) {
185
- var name, _ref;
186
- name = ctor.uniqueId();
187
- if (name && id) {
188
- return ((_ref = this._identityMap[name]) != null ? _ref[id] : void 0) || this.retrieve(ctor, id);
189
- }
190
- },
191
- set: function(ctor, id, obj) {
192
- var name, _base;
193
- name = ctor.uniqueId();
194
- if (name && id) {
195
- (_base = this._identityMap)[name] || (_base[name] = {});
196
- return this._identityMap[name][id] = obj;
197
- }
198
- },
199
- unset: function(ctor, id) {
200
- var name, _base;
201
- name = ctor.uniqueId();
202
- if (name && id) {
203
- (_base = this._identityMap)[name] || (_base[name] = {});
204
- return delete this._identityMap[name][id];
205
- }
206
- },
207
- store: function(ctor, id, obj) {
208
- var name;
209
- name = ctor.uniqueId();
210
- if (name && id && (typeof JSON !== "undefined" && JSON !== null)) {
211
- return this._storage.setItem("" + name + "_" + id, JSON.stringify(serializeObject(obj)));
212
- }
213
- },
214
- retrieve: function(ctor, id) {
215
- var data, name;
216
- name = ctor.uniqueId();
217
- if (name && id && ctor.localStorage && (typeof JSON !== "undefined" && JSON !== null)) {
218
- data = this._storage.getItem("" + name + "_" + id);
219
- if (data) {
220
- return new ctor(JSON.parse(data), true);
221
- }
222
- }
223
- }
224
- };
225
-
226
- exports.Cache = Cache;
227
-
228
- }).call(this);
229
-
230
- };require['./collection'] = new function() {
231
- var exports = this;
232
- (function() {
233
- var Events, extend, isArrayIndex, serializeObject, _ref,
234
- __slice = [].slice;
235
-
236
- Events = require('./events').Events;
237
-
238
- _ref = require('./helpers'), extend = _ref.extend, serializeObject = _ref.serializeObject;
239
-
240
- isArrayIndex = function(index) {
241
- return ("" + index).match(/^\d+$/);
242
- };
243
-
244
- exports.Collection = (function() {
245
- var fun, _i, _len, _ref1;
246
-
247
- Collection.name = 'Collection';
248
-
249
- extend(Collection.prototype, Events);
10
+ /* Jison generated parser */
11
+ var parser = (function(){
12
+ var parser = {trace: function trace() { },
13
+ yy: {},
14
+ symbols_: {"error":2,"Root":3,"Element":4,"ElementIdentifier":5,"AnyIdentifier":6,"#":7,".":8,"[":9,"]":10,"PropertyList":11,"WHITESPACE":12,"Text":13,"INDENT":14,"ChildList":15,"OUTDENT":16,"TextList":17,"Bound":18,"STRING_LITERAL":19,"Child":20,"TERMINATOR":21,"IfInstruction":22,"Instruction":23,"Helper":24,"Property":25,"=":26,"!":27,":":28,"-":29,"VIEW":30,"COLLECTION":31,"UNLESS":32,"IN":33,"IDENTIFIER":34,"IF":35,"ElseInstruction":36,"ELSE":37,"@":38,"$accept":0,"$end":1},
15
+ terminals_: {2:"error",7:"#",8:".",9:"[",10:"]",12:"WHITESPACE",14:"INDENT",16:"OUTDENT",19:"STRING_LITERAL",21:"TERMINATOR",26:"=",27:"!",28:":",29:"-",30:"VIEW",31:"COLLECTION",32:"UNLESS",33:"IN",34:"IDENTIFIER",35:"IF",37:"ELSE",38:"@"},
16
+ productions_: [0,[3,0],[3,1],[5,1],[5,3],[5,2],[5,2],[5,3],[4,1],[4,3],[4,4],[4,3],[4,4],[17,1],[17,3],[13,1],[13,1],[15,1],[15,3],[20,1],[20,1],[20,1],[20,1],[20,1],[11,1],[11,3],[25,3],[25,3],[25,4],[25,4],[25,3],[25,3],[23,5],[23,5],[23,5],[23,5],[23,4],[24,3],[24,3],[24,4],[22,5],[22,4],[22,2],[36,6],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[18,2],[18,1]],
17
+ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
250
18
 
251
- function Collection(list) {
252
- var index, val, _i, _len;
253
- for (index = _i = 0, _len = list.length; _i < _len; index = ++_i) {
254
- val = list[index];
255
- this[index] = val;
256
- }
257
- this.length = (list != null ? list.length : void 0) || 0;
19
+ var $0 = $$.length - 1;
20
+ switch (yystate) {
21
+ case 1:this.$ = null;
22
+ break;
23
+ case 2:return this.$
24
+ break;
25
+ case 3:this.$ = {
26
+ name: $$[$0],
27
+ classes: []
28
+ };
29
+ break;
30
+ case 4:this.$ = {
31
+ name: $$[$0-2],
32
+ id: $$[$0],
33
+ classes: []
34
+ };
35
+ break;
36
+ case 5:this.$ = {
37
+ name: 'div',
38
+ id: $$[$0],
39
+ classes: []
40
+ };
41
+ break;
42
+ case 6:this.$ = {
43
+ name: 'div',
44
+ classes: [$$[$0]]
45
+ };
46
+ break;
47
+ case 7:this.$ = (function () {
48
+ $$[$0-2].classes.push($$[$0]);
49
+ return $$[$0-2];
50
+ }());
51
+ break;
52
+ case 8:this.$ = {
53
+ name: $$[$0].name,
54
+ id: $$[$0].id,
55
+ classes: $$[$0].classes,
56
+ properties: [],
57
+ children: [],
58
+ type: 'element'
59
+ };
60
+ break;
61
+ case 9:this.$ = $$[$0-2];
62
+ break;
63
+ case 10:this.$ = (function () {
64
+ $$[$0-3].properties = $$[$0-1];
65
+ return $$[$0-3];
66
+ }());
67
+ break;
68
+ case 11:this.$ = (function () {
69
+ $$[$0-2].children = $$[$0-2].children.concat($$[$0]);
70
+ return $$[$0-2];
71
+ }());
72
+ break;
73
+ case 12:this.$ = (function () {
74
+ $$[$0-3].children = $$[$0-3].children.concat($$[$0-1]);
75
+ return $$[$0-3];
76
+ }());
77
+ break;
78
+ case 13:this.$ = [$$[$0]];
79
+ break;
80
+ case 14:this.$ = $$[$0-2].concat($$[$0]);
81
+ break;
82
+ case 15:this.$ = {
83
+ type: 'text',
84
+ value: $$[$0],
85
+ bound: true
86
+ };
87
+ break;
88
+ case 16:this.$ = {
89
+ type: 'text',
90
+ value: $$[$0],
91
+ bound: false
92
+ };
93
+ break;
94
+ case 17:this.$ = [].concat($$[$0]);
95
+ break;
96
+ case 18:this.$ = $$[$0-2].concat($$[$0]);
97
+ break;
98
+ case 19:this.$ = $$[$0];
99
+ break;
100
+ case 20:this.$ = $$[$0];
101
+ break;
102
+ case 21:this.$ = $$[$0];
103
+ break;
104
+ case 22:this.$ = $$[$0];
105
+ break;
106
+ case 23:this.$ = $$[$0];
107
+ break;
108
+ case 24:this.$ = [$$[$0]];
109
+ break;
110
+ case 25:this.$ = $$[$0-2].concat($$[$0]);
111
+ break;
112
+ case 26:this.$ = {
113
+ name: $$[$0-2],
114
+ value: $$[$0],
115
+ bound: true,
116
+ scope: 'attribute'
117
+ };
118
+ break;
119
+ case 27:this.$ = {
120
+ name: $$[$0-2],
121
+ value: $$[$0],
122
+ bound: true,
123
+ scope: 'attribute'
124
+ };
125
+ break;
126
+ case 28:this.$ = {
127
+ name: $$[$0-3],
128
+ value: $$[$0-1],
129
+ bound: true,
130
+ scope: 'attribute',
131
+ preventDefault: true
132
+ };
133
+ break;
134
+ case 29:this.$ = {
135
+ name: $$[$0-3],
136
+ value: $$[$0-1],
137
+ bound: true,
138
+ scope: 'attribute',
139
+ preventDefault: true
140
+ };
141
+ break;
142
+ case 30:this.$ = {
143
+ name: $$[$0-2],
144
+ value: $$[$0],
145
+ bound: false,
146
+ scope: 'attribute'
147
+ };
148
+ break;
149
+ case 31:this.$ = (function () {
150
+ $$[$0].scope = $$[$0-2];
151
+ return $$[$0];
152
+ }());
153
+ break;
154
+ case 32:this.$ = {
155
+ children: [],
156
+ type: 'view',
157
+ argument: $$[$0]
158
+ };
159
+ break;
160
+ case 33:this.$ = {
161
+ children: [],
162
+ type: 'collection',
163
+ argument: $$[$0]
164
+ };
165
+ break;
166
+ case 34:this.$ = {
167
+ children: [],
168
+ type: 'unless',
169
+ argument: $$[$0]
170
+ };
171
+ break;
172
+ case 35:this.$ = {
173
+ children: [],
174
+ type: 'in',
175
+ argument: $$[$0]
176
+ };
177
+ break;
178
+ case 36:this.$ = (function () {
179
+ $$[$0-3].children = $$[$0-1];
180
+ return $$[$0-3];
181
+ }());
182
+ break;
183
+ case 37:this.$ = {
184
+ command: $$[$0],
185
+ "arguments": [],
186
+ children: [],
187
+ type: 'helper'
188
+ };
189
+ break;
190
+ case 38:this.$ = (function () {
191
+ $$[$0-2]["arguments"].push($$[$0]);
192
+ return $$[$0-2];
193
+ }());
194
+ break;
195
+ case 39:this.$ = (function () {
196
+ $$[$0-3].children = $$[$0-1];
197
+ return $$[$0-3];
198
+ }());
199
+ break;
200
+ case 40:this.$ = {
201
+ children: [],
202
+ type: 'if',
203
+ argument: $$[$0]
204
+ };
205
+ break;
206
+ case 41:this.$ = (function () {
207
+ $$[$0-3].children = $$[$0-1];
208
+ return $$[$0-3];
209
+ }());
210
+ break;
211
+ case 42:this.$ = (function () {
212
+ $$[$0-1]["else"] = $$[$0];
213
+ return $$[$0-1];
214
+ }());
215
+ break;
216
+ case 43:this.$ = {
217
+ "arguments": [],
218
+ children: $$[$0-1],
219
+ type: 'else'
220
+ };
221
+ break;
222
+ case 44:this.$ = $$[$0];
223
+ break;
224
+ case 45:this.$ = $$[$0];
225
+ break;
226
+ case 46:this.$ = $$[$0];
227
+ break;
228
+ case 47:this.$ = $$[$0];
229
+ break;
230
+ case 48:this.$ = $$[$0];
231
+ break;
232
+ case 49:this.$ = $$[$0];
233
+ break;
234
+ case 50:this.$ = $$[$0];
235
+ break;
236
+ case 51:this.$ = (function () {}());
237
+ break;
238
+ }
239
+ },
240
+ table: [{1:[2,1],3:1,4:2,5:3,6:4,7:[1,5],8:[1,6],30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9]},{1:[3]},{1:[2,2],9:[1,13],12:[1,14],14:[1,15]},{1:[2,8],8:[1,16],9:[2,8],12:[2,8],14:[2,8],16:[2,8],21:[2,8]},{1:[2,3],7:[1,17],8:[2,3],9:[2,3],12:[2,3],14:[2,3],16:[2,3],21:[2,3]},{6:18,30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9]},{6:19,30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9]},{1:[2,44],7:[2,44],8:[2,44],9:[2,44],10:[2,44],12:[2,44],14:[2,44],16:[2,44],21:[2,44],26:[2,44],27:[2,44],28:[2,44],29:[2,44]},{1:[2,45],7:[2,45],8:[2,45],9:[2,45],10:[2,45],12:[2,45],14:[2,45],16:[2,45],21:[2,45],26:[2,45],27:[2,45],28:[2,45],29:[2,45]},{1:[2,46],7:[2,46],8:[2,46],9:[2,46],10:[2,46],12:[2,46],14:[2,46],16:[2,46],21:[2,46],26:[2,46],27:[2,46],28:[2,46],29:[2,46]},{1:[2,47],7:[2,47],8:[2,47],9:[2,47],10:[2,47],12:[2,47],14:[2,47],16:[2,47],21:[2,47],26:[2,47],27:[2,47],28:[2,47],29:[2,47]},{1:[2,48],7:[2,48],8:[2,48],9:[2,48],10:[2,48],12:[2,48],14:[2,48],16:[2,48],21:[2,48],26:[2,48],27:[2,48],28:[2,48],29:[2,48]},{1:[2,49],7:[2,49],8:[2,49],9:[2,49],10:[2,49],12:[2,49],14:[2,49],16:[2,49],21:[2,49],26:[2,49],27:[2,49],28:[2,49],29:[2,49]},{6:23,10:[1,20],11:21,25:22,30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9]},{13:24,18:25,19:[1,26],38:[1,27]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:36,15:28,17:34,18:25,19:[1,26],20:29,22:31,23:32,24:33,29:[1,35],30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9],38:[1,27]},{6:37,30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9]},{6:38,30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9]},{1:[2,5],8:[2,5],9:[2,5],12:[2,5],14:[2,5],16:[2,5],21:[2,5]},{1:[2,6],8:[2,6],9:[2,6],12:[2,6],14:[2,6],16:[2,6],21:[2,6]},{1:[2,9],9:[2,9],12:[2,9],14:[2,9],16:[2,9],21:[2,9]},{10:[1,39],12:[1,40]},{10:[2,24],12:[2,24]},{26:[1,41],28:[1,42]},{1:[2,11],9:[2,11],12:[2,11],14:[2,11],16:[2,11],21:[2,11]},{1:[2,15],9:[2,15],12:[2,15],14:[2,15],16:[2,15],21:[2,15]},{1:[2,16],9:[2,16],12:[2,16],14:[2,16],16:[2,16],21:[2,16]},{1:[2,51],6:43,9:[2,51],10:[2,51],12:[2,51],14:[2,51],16:[2,51],21:[2,51],27:[2,51],29:[2,51],30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9]},{16:[1,44],21:[1,45]},{16:[2,17],21:[2,17]},{9:[1,13],12:[1,14],14:[1,15],16:[2,19],21:[2,19]},{14:[1,46],16:[2,20],21:[2,20],29:[1,48],36:47},{14:[1,49],16:[2,21],21:[2,21]},{12:[1,50],14:[1,51],16:[2,22],21:[2,22]},{12:[1,52],16:[2,23],21:[2,23]},{12:[1,53]},{12:[2,13],16:[2,13],21:[2,13]},{1:[2,7],8:[2,7],9:[2,7],12:[2,7],14:[2,7],16:[2,7],21:[2,7]},{1:[2,4],8:[2,4],9:[2,4],12:[2,4],14:[2,4],16:[2,4],21:[2,4]},{1:[2,10],9:[2,10],12:[2,10],14:[2,10],16:[2,10],21:[2,10]},{6:23,25:54,30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9]},{6:55,18:56,19:[1,57],30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9],38:[1,27]},{6:23,25:58,30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9]},{1:[2,50],9:[2,50],10:[2,50],12:[2,50],14:[2,50],16:[2,50],21:[2,50],27:[2,50],29:[2,50]},{1:[2,12],9:[2,12],12:[2,12],14:[2,12],16:[2,12],21:[2,12]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:36,17:34,18:25,19:[1,26],20:59,22:31,23:32,24:33,29:[1,35],30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9],38:[1,27]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:36,15:60,17:34,18:25,19:[1,26],20:29,22:31,23:32,24:33,29:[1,35],30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9],38:[1,27]},{14:[2,42],16:[2,42],21:[2,42],29:[2,42]},{12:[1,61]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:36,15:62,17:34,18:25,19:[1,26],20:29,22:31,23:32,24:33,29:[1,35],30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9],38:[1,27]},{13:63,18:25,19:[1,26],38:[1,27]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:36,15:64,17:34,18:25,19:[1,26],20:29,22:31,23:32,24:33,29:[1,35],30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9],38:[1,27]},{13:65,18:25,19:[1,26],38:[1,27]},{30:[1,67],31:[1,68],32:[1,69],33:[1,70],34:[1,71],35:[1,66]},{10:[2,25],12:[2,25]},{10:[2,26],12:[2,26],27:[1,72]},{10:[2,27],12:[2,27],27:[1,73]},{10:[2,30],12:[2,30]},{10:[2,31],12:[2,31]},{16:[2,18],21:[2,18]},{16:[1,74],21:[1,45]},{37:[1,75]},{16:[1,76],21:[1,45]},{12:[2,38],14:[2,38],16:[2,38],21:[2,38]},{16:[1,77],21:[1,45]},{12:[2,14],16:[2,14],21:[2,14]},{12:[1,78]},{12:[1,79]},{12:[1,80]},{12:[1,81]},{12:[1,82]},{12:[2,37],14:[2,37],16:[2,37],21:[2,37]},{10:[2,28],12:[2,28]},{10:[2,29],12:[2,29]},{14:[2,41],16:[2,41],21:[2,41],29:[2,41]},{14:[1,83]},{14:[2,36],16:[2,36],21:[2,36]},{12:[2,39],14:[2,39],16:[2,39],21:[2,39]},{18:84,38:[1,27]},{19:[1,85]},{18:86,38:[1,27]},{18:87,38:[1,27]},{18:88,38:[1,27]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:36,15:89,17:34,18:25,19:[1,26],20:29,22:31,23:32,24:33,29:[1,35],30:[1,7],31:[1,8],32:[1,10],33:[1,11],34:[1,12],35:[1,9],38:[1,27]},{14:[2,40],16:[2,40],21:[2,40],29:[2,40]},{14:[2,32],16:[2,32],21:[2,32]},{14:[2,33],16:[2,33],21:[2,33]},{14:[2,34],16:[2,34],21:[2,34]},{14:[2,35],16:[2,35],21:[2,35]},{16:[1,90],21:[1,45]},{14:[2,43],16:[2,43],21:[2,43],29:[2,43]}],
241
+ defaultActions: {},
242
+ parseError: function parseError(str, hash) {
243
+ throw new Error(str);
244
+ },
245
+ parse: function parse(input) {
246
+ var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
247
+ this.lexer.setInput(input);
248
+ this.lexer.yy = this.yy;
249
+ this.yy.lexer = this.lexer;
250
+ this.yy.parser = this;
251
+ if (typeof this.lexer.yylloc == "undefined")
252
+ this.lexer.yylloc = {};
253
+ var yyloc = this.lexer.yylloc;
254
+ lstack.push(yyloc);
255
+ var ranges = this.lexer.options && this.lexer.options.ranges;
256
+ if (typeof this.yy.parseError === "function")
257
+ this.parseError = this.yy.parseError;
258
+ function popStack(n) {
259
+ stack.length = stack.length - 2 * n;
260
+ vstack.length = vstack.length - n;
261
+ lstack.length = lstack.length - n;
258
262
  }
259
-
260
- Collection.prototype.get = function(index) {
261
- return this[index];
262
- };
263
-
264
- Collection.prototype.set = function(index, value) {
265
- this[index] = value;
266
- if (isArrayIndex(index)) {
267
- this.length = Math.max(this.length, index + 1);
268
- }
269
- this.trigger("change:" + index, value);
270
- this.trigger("set", index, value);
271
- this.trigger("change", this);
272
- return value;
273
- };
274
-
275
- Collection.prototype.update = function(list) {
276
- var index, old, val, _, _i, _len;
277
- old = this.clone();
278
- for (index in this) {
279
- _ = this[index];
280
- if (isArrayIndex(index)) {
281
- delete this[index];
263
+ function lex() {
264
+ var token;
265
+ token = self.lexer.lex() || 1;
266
+ if (typeof token !== "number") {
267
+ token = self.symbols_[token] || token;
282
268
  }
283
- }
284
- for (index = _i = 0, _len = list.length; _i < _len; index = ++_i) {
285
- val = list[index];
286
- this[index] = val;
287
- }
288
- this.length = (list != null ? list.length : void 0) || 0;
289
- this.trigger("update", old, this);
290
- this.trigger("change", this);
291
- return list;
292
- };
293
-
294
- Collection.prototype.sortBy = function(attribute) {
295
- return this.sort(function(a, b) {
296
- if (a[attribute] < b[attribute]) {
297
- return -1;
269
+ return token;
270
+ }
271
+ var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
272
+ while (true) {
273
+ state = stack[stack.length - 1];
274
+ if (this.defaultActions[state]) {
275
+ action = this.defaultActions[state];
298
276
  } else {
299
- return 1;
300
- }
301
- });
302
- };
303
-
304
- Collection.prototype.includes = function(item) {
305
- return this.indexOf(item) >= 0;
306
- };
307
-
308
- Collection.prototype.find = function(fun) {
309
- var item, _i, _len;
310
- for (_i = 0, _len = this.length; _i < _len; _i++) {
311
- item = this[_i];
312
- if (fun(item)) {
313
- return item;
277
+ if (symbol === null || typeof symbol == "undefined") {
278
+ symbol = lex();
279
+ }
280
+ action = table[state] && table[state][symbol];
314
281
  }
315
- }
316
- };
317
-
318
- Collection.prototype.insertAt = function(index, value) {
319
- Array.prototype.splice.call(this, index, 0, value);
320
- this.trigger("insert", index, value);
321
- this.trigger("change", this);
322
- return value;
323
- };
324
-
325
- Collection.prototype.deleteAt = function(index) {
326
- var value;
327
- value = this[index];
328
- Array.prototype.splice.call(this, index, 1);
329
- this.trigger("delete", index, value);
330
- this.trigger("change", this);
331
- return value;
332
- };
333
-
334
- Collection.prototype["delete"] = function(item) {
335
- var index;
336
- index = this.indexOf(item);
337
- if (index !== -1) {
338
- return this.deleteAt(index);
339
- }
340
- };
341
-
342
- Collection.prototype.first = function() {
343
- return this[0];
344
- };
345
-
346
- Collection.prototype.last = function() {
347
- return this[this.length - 1];
348
- };
349
-
350
- Collection.prototype.toArray = function() {
351
- var array, index, val;
352
- array = [];
353
- for (index in this) {
354
- val = this[index];
355
- if (isArrayIndex(index)) {
356
- array[index] = val;
282
+ if (typeof action === "undefined" || !action.length || !action[0]) {
283
+ var errStr = "";
357
284
  }
358
- }
359
- return array;
360
- };
361
-
362
- Collection.prototype.clone = function() {
363
- return new Collection(this.toArray());
364
- };
365
-
366
- Collection.prototype.push = function(element) {
367
- this[this.length++] = element;
368
- this.trigger("add", element);
369
- this.trigger("change", this);
370
- return element;
371
- };
372
-
373
- Collection.prototype.pop = function() {
374
- return this.deleteAt(this.length - 1);
375
- };
376
-
377
- Collection.prototype.unshift = function(item) {
378
- return this.insertAt(0, item);
379
- };
380
-
381
- Collection.prototype.shift = function() {
382
- return this.deleteAt(0);
383
- };
384
-
385
- Collection.prototype.splice = function() {
386
- var deleteCount, deleted, list, old, start;
387
- start = arguments[0], deleteCount = arguments[1], list = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
388
- old = this.clone();
389
- deleted = Array.prototype.splice.apply(this, [start, deleteCount].concat(__slice.call(list)));
390
- this.trigger("update", old, this);
391
- this.trigger("change", this);
392
- return new Collection(deleted);
393
- };
394
-
395
- Collection.prototype.sort = function(fun) {
396
- var old;
397
- old = this.clone();
398
- Array.prototype.sort.call(this, fun);
399
- this.trigger("update", old, this);
400
- this.trigger("change", this);
401
- return this;
402
- };
403
-
404
- Collection.prototype.reverse = function() {
405
- var old;
406
- old = this.clone();
407
- Array.prototype.reverse.call(this);
408
- this.trigger("update", old, this);
409
- this.trigger("change", this);
410
- return this;
411
- };
412
-
413
- _ref1 = ["forEach", "indexOf", "lastIndexOf", "join", "every", "some", "reduce", "reduceRight"];
414
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
415
- fun = _ref1[_i];
416
- Collection.prototype[fun] = Array.prototype[fun];
417
- }
418
-
419
- Collection.prototype.map = function() {
420
- var args;
421
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
422
- return new Collection(Array.prototype.map.apply(this, args));
423
- };
424
-
425
- Collection.prototype.filter = function() {
426
- var args;
427
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
428
- return new Collection(Array.prototype.filter.apply(this, args));
429
- };
430
-
431
- Collection.prototype.slice = function() {
432
- var args, _ref2;
433
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
434
- return new Collection((_ref2 = this.toArray()).slice.apply(_ref2, args));
435
- };
436
-
437
- Collection.prototype.concat = function() {
438
- var arg, args, _ref2;
439
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
440
- args = (function() {
441
- var _j, _len1, _results;
442
- _results = [];
443
- for (_j = 0, _len1 = args.length; _j < _len1; _j++) {
444
- arg = args[_j];
445
- if (arg instanceof Collection) {
446
- _results.push(arg.toArray());
447
- } else {
448
- _results.push(arg);
449
- }
285
+ if (action[0] instanceof Array && action.length > 1) {
286
+ throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
450
287
  }
451
- return _results;
452
- })();
453
- return new Collection((_ref2 = this.toArray()).concat.apply(_ref2, args));
454
- };
455
-
456
- Collection.prototype.toString = function() {
457
- return this.toArray().toString();
458
- };
459
-
460
- Collection.prototype.toLocaleString = function() {
461
- return this.toArray().toLocaleString();
462
- };
463
-
464
- Collection.prototype.toJSON = function() {
465
- return serializeObject(this.toArray());
466
- };
467
-
468
- return Collection;
469
-
470
- })();
471
-
472
- }).call(this);
473
-
474
- };require['./association_collection'] = new function() {
475
- var exports = this;
476
- (function() {
477
- var AssociationCollection, Collection,
478
- __hasProp = {}.hasOwnProperty,
479
- __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; },
480
- __slice = [].slice;
481
-
482
- Collection = require('./collection').Collection;
483
-
484
- AssociationCollection = (function(_super) {
485
-
486
- __extends(AssociationCollection, _super);
487
-
488
- AssociationCollection.name = 'AssociationCollection';
489
-
490
- function AssociationCollection(owner, options, list) {
491
- var item;
492
- this.owner = owner;
493
- this.options = options;
494
- AssociationCollection.__super__.constructor.call(this, (function() {
495
- var _i, _len, _results;
496
- _results = [];
497
- for (_i = 0, _len = list.length; _i < _len; _i++) {
498
- item = list[_i];
499
- _results.push(this._convert(item));
288
+ switch (action[0]) {
289
+ case 1:
290
+ stack.push(symbol);
291
+ vstack.push(this.lexer.yytext);
292
+ lstack.push(this.lexer.yylloc);
293
+ stack.push(action[1]);
294
+ symbol = null;
295
+ if (!preErrorSymbol) {
296
+ yyleng = this.lexer.yyleng;
297
+ yytext = this.lexer.yytext;
298
+ yylineno = this.lexer.yylineno;
299
+ yyloc = this.lexer.yylloc;
300
+ if (recovering > 0)
301
+ recovering--;
302
+ } else {
303
+ symbol = preErrorSymbol;
304
+ preErrorSymbol = null;
305
+ }
306
+ break;
307
+ case 2:
308
+ len = this.productions_[action[1]][1];
309
+ yyval.$ = vstack[vstack.length - len];
310
+ yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
311
+ if (ranges) {
312
+ yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
313
+ }
314
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
315
+ if (typeof r !== "undefined") {
316
+ return r;
317
+ }
318
+ if (len) {
319
+ stack = stack.slice(0, -1 * len * 2);
320
+ vstack = vstack.slice(0, -1 * len);
321
+ lstack = lstack.slice(0, -1 * len);
322
+ }
323
+ stack.push(this.productions_[action[1]][0]);
324
+ vstack.push(yyval.$);
325
+ lstack.push(yyval._$);
326
+ newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
327
+ stack.push(newState);
328
+ break;
329
+ case 3:
330
+ return true;
500
331
  }
501
- return _results;
502
- }).call(this));
503
332
  }
333
+ return true;
334
+ }
335
+ };
336
+ ;function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
337
+ return new Parser;
338
+ })();
339
+ if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
340
+ exports.parser = parser;
341
+ exports.Parser = parser.Parser;
342
+ exports.parse = function () { return parser.parse.apply(parser, arguments); }
343
+ exports.main = function commonjsMain(args) {
344
+ if (!args[1])
345
+ throw new Error('Usage: '+args[0]+' FILE');
346
+ var source, cwd;
347
+ if (typeof process !== 'undefined') {
348
+ source = require('fs').readFileSync(require('path').resolve(args[1]), "utf8");
349
+ } else {
350
+ source = require("file").path(require("file").cwd()).join(args[1]).read({charset: "utf-8"});
351
+ }
352
+ return exports.parser.parse(source);
353
+ }
354
+ if (typeof module !== 'undefined' && require.main === module) {
355
+ exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
356
+ }
357
+ }var AssociationCollection, COMMENT, Cache, Collection, Compile, DynamicNode, Event, IDENTIFIER, KEYWORDS, LITERAL, Lexer, MULTI_DENT, Model, Node, Property, PropertyAccessor, PropertyDefinition, STRING, Serenade, View, WHITESPACE, capitalize, compile, compileAll, def, defineEvent, defineProperty, extend, format, getValue, globalDependencies, idCounter, isArray, isArrayIndex, normalize, pairToObject, safeDelete, safePush, serializeObject, settings, triggerGlobal,
358
+ __hasProp = {}.hasOwnProperty,
359
+ __slice = [].slice,
360
+ __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; },
361
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
362
+
363
+ settings = {
364
+ async: false
365
+ };
504
366
 
505
- AssociationCollection.prototype.set = function(index, item) {
506
- return AssociationCollection.__super__.set.call(this, index, this._convert(item));
507
- };
508
-
509
- AssociationCollection.prototype.push = function(item) {
510
- return AssociationCollection.__super__.push.call(this, this._convert(item));
511
- };
512
-
513
- AssociationCollection.prototype.update = function(list) {
514
- var item;
515
- return AssociationCollection.__super__.update.call(this, (function() {
516
- var _i, _len, _results;
517
- _results = [];
518
- for (_i = 0, _len = list.length; _i < _len; _i++) {
519
- item = list[_i];
520
- _results.push(this._convert(item));
521
- }
522
- return _results;
523
- }).call(this));
524
- };
525
-
526
- AssociationCollection.prototype.splice = function() {
527
- var deleteCount, item, list, start;
528
- start = arguments[0], deleteCount = arguments[1], list = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
529
- list = (function() {
530
- var _i, _len, _results;
531
- _results = [];
532
- for (_i = 0, _len = list.length; _i < _len; _i++) {
533
- item = list[_i];
534
- _results.push(this._convert(item));
535
- }
536
- return _results;
537
- }).call(this);
538
- return AssociationCollection.__super__.splice.apply(this, [start, deleteCount].concat(__slice.call(list)));
539
- };
540
-
541
- AssociationCollection.prototype.insertAt = function(index, item) {
542
- return AssociationCollection.__super__.insertAt.call(this, index, this._convert(item));
543
- };
544
-
545
- AssociationCollection.prototype._convert = function(item) {
546
- if (item.constructor === Object && this.options.as) {
547
- item = new (this.options.as())(item);
548
- }
549
- if (this.options.inverseOf && item[this.options.inverseOf] !== this.owner) {
550
- item[this.options.inverseOf] = this.owner;
551
- }
552
- return item;
553
- };
554
-
555
- return AssociationCollection;
556
-
557
- })(Collection);
558
-
559
- exports.AssociationCollection = AssociationCollection;
560
-
561
- }).call(this);
562
-
563
- };require['./properties'] = new function() {
564
- var exports = this;
565
- (function() {
566
- var AssociationCollection, Associations, Collection, Events, Properties, addDependencies, addGlobalDependencies, exp, extend, globalDependencies, pairToObject, prefix, serializeObject, triggerChangesTo, triggerGlobal, _ref,
567
- __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
568
- __hasProp = {}.hasOwnProperty;
367
+ def = Object.defineProperty;
368
+
369
+ extend = function(target, source, enumerable) {
370
+ var key, value, _results;
371
+ if (enumerable == null) {
372
+ enumerable = true;
373
+ }
374
+ _results = [];
375
+ for (key in source) {
376
+ if (!__hasProp.call(source, key)) continue;
377
+ value = source[key];
378
+ if (enumerable) {
379
+ _results.push(target[key] = value);
380
+ } else {
381
+ _results.push(def(target, key, {
382
+ value: value,
383
+ configurable: true
384
+ }));
385
+ }
386
+ }
387
+ return _results;
388
+ };
569
389
 
570
- Collection = require('./collection').Collection;
390
+ format = function(model, key) {
391
+ if (model[key + "_property"]) {
392
+ return model[key + "_property"].format();
393
+ } else {
394
+ return model[key];
395
+ }
396
+ };
571
397
 
572
- AssociationCollection = require('./association_collection').AssociationCollection;
398
+ isArray = function(object) {
399
+ return Object.prototype.toString.call(object) === "[object Array]";
400
+ };
573
401
 
574
- Events = require('./events').Events;
402
+ pairToObject = function(one, two) {
403
+ var temp;
404
+ temp = {};
405
+ temp[one] = two;
406
+ return temp;
407
+ };
575
408
 
576
- _ref = require('./helpers'), prefix = _ref.prefix, pairToObject = _ref.pairToObject, serializeObject = _ref.serializeObject, extend = _ref.extend;
409
+ serializeObject = function(object) {
410
+ var item, _i, _len, _results;
411
+ if (object && typeof object.toJSON === 'function') {
412
+ return object.toJSON();
413
+ } else if (isArray(object)) {
414
+ _results = [];
415
+ for (_i = 0, _len = object.length; _i < _len; _i++) {
416
+ item = object[_i];
417
+ _results.push(serializeObject(item));
418
+ }
419
+ return _results;
420
+ } else {
421
+ return object;
422
+ }
423
+ };
577
424
 
578
- exp = /^_prop_/;
425
+ capitalize = function(word) {
426
+ return word.slice(0, 1).toUpperCase() + word.slice(1);
427
+ };
579
428
 
580
- globalDependencies = {};
429
+ safePush = function(object, collection, item) {
430
+ if (!object[collection] || object[collection].indexOf(item) === -1) {
431
+ if (object.hasOwnProperty(collection)) {
432
+ return object[collection].push(item);
433
+ } else if (object[collection]) {
434
+ return def(object, collection, {
435
+ value: [item].concat(object[collection])
436
+ });
437
+ } else {
438
+ return def(object, collection, {
439
+ value: [item]
440
+ });
441
+ }
442
+ }
443
+ };
581
444
 
582
- addGlobalDependencies = function(object, dependency, names) {
583
- var name, subname, type, _i, _len, _ref1, _ref2, _results;
584
- if (!object["_glb_" + dependency]) {
585
- object["_glb_" + dependency] = true;
586
- _results = [];
587
- for (_i = 0, _len = names.length; _i < _len; _i++) {
588
- name = names[_i];
589
- if (name.match(/\./)) {
590
- type = "singular";
591
- _ref1 = name.split("."), name = _ref1[0], subname = _ref1[1];
592
- } else if (name.match(/:/)) {
593
- type = "collection";
594
- _ref2 = name.split(":"), name = _ref2[0], subname = _ref2[1];
595
- }
596
- if (subname) {
597
- globalDependencies[subname] || (globalDependencies[subname] = []);
598
- _results.push(globalDependencies[subname].push({
599
- object: object,
600
- dependency: dependency,
601
- subname: subname,
602
- name: name,
603
- type: type
604
- }));
605
- } else {
606
- _results.push(void 0);
607
- }
608
- }
609
- return _results;
445
+ safeDelete = function(object, collection, item) {
446
+ var index;
447
+ if (object[collection] && (index = object[collection].indexOf(item)) !== -1) {
448
+ if (!object.hasOwnProperty(collection)) {
449
+ def(object, collection, {
450
+ value: [].concat(object[collection])
451
+ });
610
452
  }
611
- };
453
+ return object[collection].splice(index, 1);
454
+ }
455
+ };
612
456
 
613
- addDependencies = function(object, dependency, names) {
614
- var name, subname, _i, _len, _name, _ref1, _results;
615
- names = [].concat(names);
616
- _results = [];
617
- for (_i = 0, _len = names.length; _i < _len; _i++) {
618
- name = names[_i];
619
- if (name.match(/[:\.]/)) {
620
- _ref1 = name.split(/[:\.]/), name = _ref1[0], subname = _ref1[1];
621
- }
622
- object[_name = "_dep_" + name] || (object[_name] = []);
623
- if (__indexOf.call(object["_dep_" + name], dependency) < 0) {
624
- _results.push(object["_dep_" + name].push(dependency));
625
- } else {
626
- _results.push(void 0);
627
- }
457
+ Event = (function() {
458
+
459
+ function Event(object, name, options) {
460
+ this.object = object;
461
+ this.name = name;
462
+ this.options = options;
463
+ this.prop = "_s_" + this.name + "_listeners";
464
+ this.queueName = "_s_" + name + "_queue";
465
+ this.async = "async" in this.options ? this.options.async : settings.async;
466
+ }
467
+
468
+ Event.prototype.trigger = function() {
469
+ var args, _base,
470
+ _this = this;
471
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
472
+ this.queue.push(args);
473
+ if (this.async) {
474
+ return (_base = this.queue).timeout || (_base.timeout = setTimeout((function() {
475
+ return _this.resolve();
476
+ }), 0));
477
+ } else {
478
+ return this.resolve();
628
479
  }
629
- return _results;
630
480
  };
631
481
 
632
- triggerGlobal = function(object, names) {
633
- var dependency, name, _i, _len, _results;
634
- _results = [];
635
- for (_i = 0, _len = names.length; _i < _len; _i++) {
636
- name = names[_i];
637
- if (globalDependencies[name]) {
638
- _results.push((function() {
639
- var _j, _len1, _ref1, _results1;
640
- _ref1 = globalDependencies[name];
641
- _results1 = [];
642
- for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
643
- dependency = _ref1[_j];
644
- if (dependency.type === "singular") {
645
- if (object === dependency.object.get(dependency.name)) {
646
- _results1.push(triggerChangesTo(dependency.object, [dependency.dependency]));
647
- } else {
648
- _results1.push(void 0);
649
- }
650
- } else if (dependency.type === "collection") {
651
- if (__indexOf.call(dependency.object.get(dependency.name), object) >= 0) {
652
- _results1.push(triggerChangesTo(dependency.object, [dependency.dependency]));
653
- } else {
654
- _results1.push(void 0);
655
- }
656
- } else {
657
- _results1.push(void 0);
658
- }
659
- }
660
- return _results1;
661
- })());
662
- } else {
663
- _results.push(void 0);
664
- }
482
+ Event.prototype.bind = function(fun) {
483
+ if (this.options.bind) {
484
+ this.options.bind.call(this.object, fun);
665
485
  }
666
- return _results;
486
+ return safePush(this.object, this.prop, fun);
667
487
  };
668
488
 
669
- triggerChangesTo = function(object, names) {
670
- var changes, findDependencies, name, value, _i, _j, _len, _len1, _results;
671
- findDependencies = function(name) {
672
- var dependencies, dependency, _i, _len, _results;
673
- dependencies = object["_dep_" + name];
674
- if (dependencies) {
675
- _results = [];
676
- for (_i = 0, _len = dependencies.length; _i < _len; _i++) {
677
- dependency = dependencies[_i];
678
- if (__indexOf.call(names, dependency) < 0) {
679
- names.push(dependency);
680
- _results.push(findDependencies(dependency));
681
- } else {
682
- _results.push(void 0);
683
- }
684
- }
685
- return _results;
686
- }
489
+ Event.prototype.one = function(fun) {
490
+ var unbind,
491
+ _this = this;
492
+ unbind = function(fun) {
493
+ return _this.unbind(fun);
687
494
  };
688
- for (_i = 0, _len = names.length; _i < _len; _i++) {
689
- name = names[_i];
690
- findDependencies(name);
691
- }
692
- changes = {};
693
- for (_j = 0, _len1 = names.length; _j < _len1; _j++) {
694
- name = names[_j];
695
- changes[name] = object.get(name);
696
- }
697
- object.trigger("change", changes);
698
- triggerGlobal(object, names);
699
- _results = [];
700
- for (name in changes) {
701
- if (!__hasProp.call(changes, name)) continue;
702
- value = changes[name];
703
- _results.push(object.trigger("change:" + name, value));
704
- }
705
- return _results;
495
+ return this.bind(function() {
496
+ unbind(arguments.callee);
497
+ return fun.apply(this, arguments);
498
+ });
706
499
  };
707
500
 
708
- Properties = {
709
- property: function(name, options) {
710
- if (options == null) {
711
- options = {};
712
- }
713
- this[prefix + name] = options;
714
- this[prefix + name].name = name;
715
- if (this.hasOwnProperty(name)) {
716
- this.set(name, this[name]);
717
- }
718
- if (options.dependsOn) {
719
- addDependencies(this, name, options.dependsOn);
720
- }
721
- Object.defineProperty(this, name, {
722
- get: function() {
723
- return Properties.get.call(this, name);
724
- },
725
- set: function(value) {
726
- return Properties.set.call(this, name, value);
727
- },
728
- configurable: true
729
- });
730
- if (typeof options.serialize === 'string') {
731
- return this.property(options.serialize, {
732
- get: function() {
733
- return this.get(name);
734
- },
735
- set: function(v) {
736
- return this.set(name, v);
737
- },
738
- configurable: true
501
+ Event.prototype.unbind = function(fun) {
502
+ safeDelete(this.object, this.prop, fun);
503
+ if (this.options.unbind) {
504
+ return this.options.unbind.call(this.object, fun);
505
+ }
506
+ };
507
+
508
+ Event.prototype.resolve = function() {
509
+ var args, perform, _i, _len, _ref,
510
+ _this = this;
511
+ perform = function(args) {
512
+ if (_this.object[_this.prop]) {
513
+ return _this.object[_this.prop].forEach(function(fun) {
514
+ return fun.apply(_this.object, args);
739
515
  });
740
516
  }
741
- },
742
- collection: function(name, options) {
743
- if (options == null) {
744
- options = {};
745
- }
746
- extend(options, {
747
- get: function() {
748
- var _this = this;
749
- if (!this.attributes[name]) {
750
- this.attributes[name] = new Collection([]);
751
- this.attributes[name].bind('change', function() {
752
- return triggerChangesTo(_this, [name]);
753
- });
754
- }
755
- return this.attributes[name];
756
- },
757
- set: function(value) {
758
- return this.get(name).update(value);
759
- }
760
- });
761
- return this.property(name, options);
762
- },
763
- set: function(attributes, value) {
764
- var name, names, _ref1;
765
- if (typeof attributes === 'string') {
766
- attributes = pairToObject(attributes, value);
767
- }
768
- names = [];
769
- for (name in attributes) {
770
- value = attributes[name];
771
- names.push(name);
772
- this.attributes || (this.attributes = {});
773
- if (!this[prefix + name]) {
774
- Properties.property.call(this, name);
775
- }
776
- if ((_ref1 = this[prefix + name]) != null ? _ref1.set : void 0) {
777
- this[prefix + name].set.call(this, value);
778
- } else {
779
- this.attributes[name] = value;
780
- }
781
- }
782
- return triggerChangesTo(this, names);
783
- },
784
- get: function(name) {
785
- var _ref1, _ref2, _ref3;
786
- if ((_ref1 = this[prefix + name]) != null ? _ref1.dependsOn : void 0) {
787
- addGlobalDependencies(this, name, [].concat(this[prefix + name].dependsOn));
788
- }
789
- this.attributes || (this.attributes = {});
790
- if ((_ref2 = this[prefix + name]) != null ? _ref2.get : void 0) {
791
- return this[prefix + name].get.call(this);
792
- } else if (((_ref3 = this[prefix + name]) != null ? _ref3.hasOwnProperty("default") : void 0) && !this.attributes.hasOwnProperty(name)) {
793
- return this[prefix + name]["default"];
794
- } else {
795
- return this.attributes[name];
796
- }
797
- },
798
- toJSON: function() {
799
- var key, name, options, serialized, value, _ref1;
800
- serialized = {};
801
- for (name in this) {
802
- options = this[name];
803
- if (name.match(exp)) {
804
- if (typeof options.serialize === 'string') {
805
- serialized[options.serialize] = serializeObject(this.get(options.name));
806
- } else if (typeof options.serialize === 'function') {
807
- _ref1 = options.serialize.call(this), key = _ref1[0], value = _ref1[1];
808
- serialized[key] = serializeObject(value);
809
- } else if (options.serialize) {
810
- serialized[options.name] = serializeObject(this.get(options.name));
811
- }
812
- }
517
+ };
518
+ if (this.options.optimize) {
519
+ perform(this.options.optimize(this.queue));
520
+ } else {
521
+ _ref = this.queue;
522
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
523
+ args = _ref[_i];
524
+ perform(args);
813
525
  }
814
- return serialized;
815
526
  }
527
+ return this.queue = [];
816
528
  };
817
529
 
818
- extend(Properties, Events);
530
+ def(Event.prototype, "listeners", {
531
+ get: function() {
532
+ return this.object[this.prop];
533
+ }
534
+ });
819
535
 
820
- Associations = {
821
- belongsTo: function(name, attributes) {
822
- if (attributes == null) {
823
- attributes = {};
536
+ def(Event.prototype, "queue", {
537
+ get: function() {
538
+ if (!this.object.hasOwnProperty(this.queueName)) {
539
+ this.queue = [];
824
540
  }
825
- extend(attributes, {
826
- set: function(model) {
827
- var previous;
828
- if (model.constructor === Object && attributes.as) {
829
- model = new (attributes.as())(model);
830
- }
831
- previous = this.attributes[name];
832
- this.attributes[name] = model;
833
- if (attributes.inverseOf && !model[attributes.inverseOf].includes(this)) {
834
- if (previous) {
835
- previous[attributes.inverseOf]["delete"](this);
836
- }
837
- return model[attributes.inverseOf].push(this);
838
- }
839
- }
840
- });
841
- this.property(name, attributes);
842
- return this.property(name + 'Id', {
843
- get: function() {
844
- var _ref1;
845
- return (_ref1 = this.get(name)) != null ? _ref1.id : void 0;
846
- },
847
- set: function(id) {
848
- if (id != null) {
849
- return this.set(name, attributes.as().find(id));
850
- }
851
- },
852
- dependsOn: name,
853
- serialize: attributes.serializeId
854
- });
541
+ return this.object[this.queueName];
855
542
  },
856
- hasMany: function(name, attributes) {
857
- if (attributes == null) {
858
- attributes = {};
859
- }
860
- extend(attributes, {
861
- get: function() {
862
- var _this = this;
863
- if (!this.attributes[name]) {
864
- this.attributes[name] = new AssociationCollection(this, attributes, []);
865
- this.attributes[name].bind('change', function() {
866
- return triggerChangesTo(_this, [name]);
867
- });
868
- }
869
- return this.attributes[name];
870
- },
871
- set: function(value) {
872
- return this.get(name).update(value);
873
- }
874
- });
875
- this.property(name, attributes);
876
- return this.property(name + 'Ids', {
877
- get: function() {
878
- return new Collection(this.get(name)).map(function(item) {
879
- return item != null ? item.id : void 0;
880
- });
881
- },
882
- set: function(ids) {
883
- var id, objects;
884
- objects = (function() {
885
- var _i, _len, _results;
886
- _results = [];
887
- for (_i = 0, _len = ids.length; _i < _len; _i++) {
888
- id = ids[_i];
889
- _results.push(attributes.as().find(id));
890
- }
891
- return _results;
892
- })();
893
- return this.get(name).update(objects);
894
- },
895
- dependsOn: name,
896
- serialize: attributes.serializeIds
543
+ set: function(val) {
544
+ return def(this.object, this.queueName, {
545
+ value: val,
546
+ configurable: true
897
547
  });
898
548
  }
899
- };
900
-
901
- exports.Properties = Properties;
902
-
903
- exports.Associations = Associations;
549
+ });
904
550
 
905
- exports.globalDependencies = globalDependencies;
551
+ return Event;
906
552
 
907
- }).call(this);
553
+ })();
908
554
 
909
- };require['./model'] = new function() {
910
- var exports = this;
911
- (function() {
912
- var Associations, Cache, Model, Properties, capitalize, extend, idCounter, _ref, _ref1,
913
- __hasProp = {}.hasOwnProperty,
914
- __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; },
915
- __slice = [].slice;
555
+ defineEvent = function(object, name, options) {
556
+ if (options == null) {
557
+ options = {};
558
+ }
559
+ return def(object, name, {
560
+ configurable: true,
561
+ get: function() {
562
+ return new Event(this, name, options);
563
+ }
564
+ });
565
+ };
916
566
 
917
- Cache = require('./cache').Cache;
567
+ Cache = {
568
+ _identityMap: {},
569
+ get: function(ctor, id) {
570
+ var name, _ref;
571
+ name = ctor.uniqueId();
572
+ if (name && id) {
573
+ return (_ref = this._identityMap[name]) != null ? _ref[id] : void 0;
574
+ }
575
+ },
576
+ set: function(ctor, id, obj) {
577
+ var name, _base;
578
+ name = ctor.uniqueId();
579
+ if (name && id) {
580
+ (_base = this._identityMap)[name] || (_base[name] = {});
581
+ return this._identityMap[name][id] = obj;
582
+ }
583
+ },
584
+ unset: function(ctor, id) {
585
+ var name, _base;
586
+ name = ctor.uniqueId();
587
+ if (name && id) {
588
+ (_base = this._identityMap)[name] || (_base[name] = {});
589
+ return delete this._identityMap[name][id];
590
+ }
591
+ }
592
+ };
918
593
 
919
- _ref = require('./properties'), Associations = _ref.Associations, Properties = _ref.Properties;
594
+ isArrayIndex = function(index) {
595
+ return ("" + index).match(/^\d+$/);
596
+ };
920
597
 
921
- _ref1 = require('./helpers'), extend = _ref1.extend, capitalize = _ref1.capitalize;
598
+ Collection = (function() {
599
+ var fun, _i, _len, _ref;
922
600
 
923
- idCounter = 1;
601
+ defineEvent(Collection.prototype, "change_set");
924
602
 
925
- Model = (function() {
603
+ defineEvent(Collection.prototype, "change_add");
926
604
 
927
- Model.name = 'Model';
605
+ defineEvent(Collection.prototype, "change_update");
928
606
 
929
- extend(Model.prototype, Properties);
607
+ defineEvent(Collection.prototype, "change_insert");
930
608
 
931
- extend(Model.prototype, Associations);
609
+ defineEvent(Collection.prototype, "change_delete");
932
610
 
933
- Model.property = function() {
934
- var _ref2;
935
- return (_ref2 = this.prototype).property.apply(_ref2, arguments);
936
- };
611
+ defineEvent(Collection.prototype, "change");
937
612
 
938
- Model.collection = function() {
939
- var _ref2;
940
- return (_ref2 = this.prototype).collection.apply(_ref2, arguments);
941
- };
613
+ function Collection(list) {
614
+ var index, val, _i, _len;
615
+ if (list == null) {
616
+ list = [];
617
+ }
618
+ for (index = _i = 0, _len = list.length; _i < _len; index = ++_i) {
619
+ val = list[index];
620
+ this[index] = val;
621
+ }
622
+ this.length = (list != null ? list.length : void 0) || 0;
623
+ }
942
624
 
943
- Model.belongsTo = function() {
944
- var _ref2;
945
- return (_ref2 = this.prototype).belongsTo.apply(_ref2, arguments);
946
- };
625
+ Collection.prototype.get = function(index) {
626
+ return this[index];
627
+ };
947
628
 
948
- Model.hasMany = function() {
949
- var _ref2;
950
- return (_ref2 = this.prototype).hasMany.apply(_ref2, arguments);
951
- };
629
+ Collection.prototype.set = function(index, value) {
630
+ this[index] = value;
631
+ if (isArrayIndex(index)) {
632
+ this.length = Math.max(this.length, index + 1);
633
+ }
634
+ this.change_set.trigger(index, value);
635
+ this.change.trigger(this);
636
+ return value;
637
+ };
952
638
 
953
- Model.find = function(id) {
954
- return Cache.get(this, id) || new this({
955
- id: id
956
- });
957
- };
639
+ Collection.prototype.update = function(list) {
640
+ var index, old, val, _, _i, _len;
641
+ old = this.clone();
642
+ for (index in this) {
643
+ _ = this[index];
644
+ if (isArrayIndex(index)) {
645
+ delete this[index];
646
+ }
647
+ }
648
+ for (index = _i = 0, _len = list.length; _i < _len; index = ++_i) {
649
+ val = list[index];
650
+ this[index] = val;
651
+ }
652
+ this.length = (list != null ? list.length : void 0) || 0;
653
+ this.change_update.trigger(old, this);
654
+ this.change.trigger(this);
655
+ return list;
656
+ };
958
657
 
959
- Model.property('id', {
960
- serialize: true,
961
- set: function(val) {
962
- Cache.unset(this.constructor, this.attributes.id);
963
- Cache.set(this.constructor, val, this);
964
- return this.attributes.id = val;
658
+ Collection.prototype.sortBy = function(attribute) {
659
+ return this.sort(function(a, b) {
660
+ if (a[attribute] < b[attribute]) {
661
+ return -1;
662
+ } else {
663
+ return 1;
965
664
  }
966
665
  });
666
+ };
967
667
 
968
- Model.extend = function(ctor) {
969
- var New;
970
- return New = (function(_super) {
971
-
972
- __extends(New, _super);
668
+ Collection.prototype.includes = function(item) {
669
+ return this.indexOf(item) >= 0;
670
+ };
973
671
 
974
- New.name = 'New';
672
+ Collection.prototype.find = function(fun) {
673
+ var item, _i, _len;
674
+ for (_i = 0, _len = this.length; _i < _len; _i++) {
675
+ item = this[_i];
676
+ if (fun(item)) {
677
+ return item;
678
+ }
679
+ }
680
+ };
975
681
 
976
- function New() {
977
- var val;
978
- val = New.__super__.constructor.apply(this, arguments);
979
- if (val) {
980
- return val;
981
- }
982
- if (ctor) {
983
- ctor.apply(this, arguments);
984
- }
985
- }
682
+ Collection.prototype.insertAt = function(index, value) {
683
+ Array.prototype.splice.call(this, index, 0, value);
684
+ this.change_insert.trigger(index, value);
685
+ this.change.trigger(this);
686
+ return value;
687
+ };
986
688
 
987
- return New;
689
+ Collection.prototype.deleteAt = function(index) {
690
+ var value;
691
+ value = this[index];
692
+ Array.prototype.splice.call(this, index, 1);
693
+ this.change_delete.trigger(index, value);
694
+ this.change.trigger(this);
695
+ return value;
696
+ };
988
697
 
989
- })(this);
990
- };
698
+ Collection.prototype["delete"] = function(item) {
699
+ var index;
700
+ index = this.indexOf(item);
701
+ if (index !== -1) {
702
+ return this.deleteAt(index);
703
+ }
704
+ };
991
705
 
992
- Model.delegate = function() {
993
- var name, names, options, to, _i, _j, _len, _results,
994
- _this = this;
995
- names = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), options = arguments[_i++];
996
- to = options.to;
997
- _results = [];
998
- for (_j = 0, _len = names.length; _j < _len; _j++) {
999
- name = names[_j];
1000
- _results.push((function(name) {
1001
- var propName;
1002
- propName = name;
1003
- if (options.prefix) {
1004
- propName = to + capitalize(name);
1005
- }
1006
- if (options.suffix) {
1007
- propName = propName + capitalize(to);
1008
- }
1009
- return _this.property(propName, {
1010
- dependsOn: "" + to + "." + name,
1011
- get: function() {
1012
- var _ref2;
1013
- return (_ref2 = this[to]) != null ? _ref2[name] : void 0;
1014
- }
1015
- });
1016
- })(name));
1017
- }
1018
- return _results;
1019
- };
706
+ Collection.prototype.first = function() {
707
+ return this[0];
708
+ };
1020
709
 
1021
- Model.uniqueId = function() {
1022
- if (!(this._uniqueId && this._uniqueGen === this)) {
1023
- this._uniqueId = (idCounter += 1);
1024
- this._uniqueGen = this;
1025
- }
1026
- return this._uniqueId;
1027
- };
710
+ Collection.prototype.last = function() {
711
+ return this[this.length - 1];
712
+ };
1028
713
 
1029
- function Model(attributes, bypassCache) {
1030
- var fromCache,
1031
- _this = this;
1032
- if (bypassCache == null) {
1033
- bypassCache = false;
1034
- }
1035
- if (!bypassCache) {
1036
- if (attributes != null ? attributes.id : void 0) {
1037
- fromCache = Cache.get(this.constructor, attributes.id);
1038
- if (fromCache) {
1039
- fromCache.set(attributes);
1040
- return fromCache;
1041
- } else {
1042
- Cache.set(this.constructor, attributes.id, this);
1043
- }
1044
- }
1045
- }
1046
- if (this.constructor.localStorage) {
1047
- this.bind('saved', function() {
1048
- return Cache.store(_this.constructor, _this.get('id'), _this);
1049
- });
1050
- if (this.constructor.localStorage !== 'save') {
1051
- this.bind('change', function() {
1052
- return Cache.store(_this.constructor, _this.get('id'), _this);
1053
- });
1054
- }
714
+ Collection.prototype.toArray = function() {
715
+ var array, index, val;
716
+ array = [];
717
+ for (index in this) {
718
+ val = this[index];
719
+ if (isArrayIndex(index)) {
720
+ array[index] = val;
1055
721
  }
1056
- this.set(attributes);
1057
722
  }
723
+ return array;
724
+ };
1058
725
 
1059
- Model.prototype.save = function() {
1060
- return this.trigger('saved');
1061
- };
726
+ Collection.prototype.clone = function() {
727
+ return new Collection(this.toArray());
728
+ };
729
+
730
+ Collection.prototype.push = function(element) {
731
+ this[this.length++] = element;
732
+ this.change_add.trigger(element);
733
+ this.change.trigger(this);
734
+ return element;
735
+ };
1062
736
 
1063
- return Model;
737
+ Collection.prototype.pop = function() {
738
+ return this.deleteAt(this.length - 1);
739
+ };
1064
740
 
1065
- })();
741
+ Collection.prototype.unshift = function(item) {
742
+ return this.insertAt(0, item);
743
+ };
1066
744
 
1067
- exports.Model = Model;
745
+ Collection.prototype.shift = function() {
746
+ return this.deleteAt(0);
747
+ };
1068
748
 
1069
- }).call(this);
749
+ Collection.prototype.splice = function() {
750
+ var deleteCount, deleted, list, old, start;
751
+ start = arguments[0], deleteCount = arguments[1], list = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
752
+ old = this.clone();
753
+ deleted = Array.prototype.splice.apply(this, [start, deleteCount].concat(__slice.call(list)));
754
+ this.change_update.trigger(old, this);
755
+ this.change.trigger(this);
756
+ return new Collection(deleted);
757
+ };
1070
758
 
1071
- };require['./serenade'] = new function() {
1072
- var exports = this;
1073
- (function() {
1074
- var Cache, Properties, Serenade, extend, format, globalDependencies, _ref, _ref1;
759
+ Collection.prototype.sort = function(fun) {
760
+ var old;
761
+ old = this.clone();
762
+ Array.prototype.sort.call(this, fun);
763
+ this.change_update.trigger(old, this);
764
+ this.change.trigger(this);
765
+ return this;
766
+ };
1075
767
 
1076
- Cache = require('./cache').Cache;
768
+ Collection.prototype.reverse = function() {
769
+ var old;
770
+ old = this.clone();
771
+ Array.prototype.reverse.call(this);
772
+ this.change_update.trigger(old, this);
773
+ this.change.trigger(this);
774
+ return this;
775
+ };
1077
776
 
1078
- _ref = require('./helpers'), extend = _ref.extend, format = _ref.format;
777
+ _ref = ["forEach", "indexOf", "lastIndexOf", "join", "every", "some", "reduce", "reduceRight"];
778
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
779
+ fun = _ref[_i];
780
+ Collection.prototype[fun] = Array.prototype[fun];
781
+ }
1079
782
 
1080
- _ref1 = require("./properties"), Properties = _ref1.Properties, globalDependencies = _ref1.globalDependencies;
783
+ Collection.prototype.map = function() {
784
+ var args;
785
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
786
+ return new Collection(Array.prototype.map.apply(this, args));
787
+ };
1081
788
 
1082
- Serenade = function(attributes) {
1083
- if (this === root) {
1084
- return new Serenade(attributes);
1085
- }
1086
- this.set(attributes);
1087
- return this;
789
+ Collection.prototype.filter = function() {
790
+ var args;
791
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
792
+ return new Collection(Array.prototype.filter.apply(this, args));
1088
793
  };
1089
794
 
1090
- extend(Serenade.prototype, Properties);
795
+ Collection.prototype.slice = function() {
796
+ var args, _ref1;
797
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
798
+ return new Collection((_ref1 = this.toArray()).slice.apply(_ref1, args));
799
+ };
1091
800
 
1092
- extend(Serenade, {
1093
- VERSION: '0.3.0',
1094
- _views: {},
1095
- _controllers: {},
1096
- document: typeof window !== "undefined" && window !== null ? window.document : void 0,
1097
- format: format,
1098
- view: function(nameOrTemplate, template) {
1099
- var View;
1100
- View = require('./view').View;
1101
- if (template) {
1102
- return this._views[nameOrTemplate] = new View(nameOrTemplate, template);
1103
- } else {
1104
- return new View(void 0, nameOrTemplate);
1105
- }
1106
- },
1107
- render: function(name, model, controller, parent, skipCallback) {
1108
- return this._views[name].render(model, controller, parent, skipCallback);
1109
- },
1110
- controller: function(name, klass) {
1111
- return this._controllers[name] = klass;
1112
- },
1113
- controllerFor: function(name) {
1114
- return this._controllers[name];
1115
- },
1116
- clearIdentityMap: function() {
1117
- return Cache._identityMap = {};
1118
- },
1119
- clearLocalStorage: function() {
1120
- return Cache._storage.clear();
1121
- },
1122
- clearCache: function() {
1123
- var key, value, _i, _len, _results;
1124
- Serenade.clearIdentityMap();
1125
- Serenade.clearLocalStorage();
801
+ Collection.prototype.concat = function() {
802
+ var arg, args, _ref1;
803
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
804
+ args = (function() {
805
+ var _j, _len1, _results;
1126
806
  _results = [];
1127
- for (key = _i = 0, _len = globalDependencies.length; _i < _len; key = ++_i) {
1128
- value = globalDependencies[key];
1129
- _results.push(delete globalDependencies[key]);
807
+ for (_j = 0, _len1 = args.length; _j < _len1; _j++) {
808
+ arg = args[_j];
809
+ if (arg instanceof Collection) {
810
+ _results.push(arg.toArray());
811
+ } else {
812
+ _results.push(arg);
813
+ }
1130
814
  }
1131
815
  return _results;
1132
- },
1133
- unregisterAll: function() {
1134
- Serenade._views = {};
1135
- return Serenade._controllers = {};
1136
- },
1137
- Events: require('./events').Events,
1138
- Model: require('./model').Model,
1139
- Collection: require('./collection').Collection,
1140
- Helpers: {}
1141
- });
1142
-
1143
- exports.Serenade = Serenade;
1144
-
1145
- exports.compile = function() {
1146
- var document, fs, window;
1147
- document = require("jsdom").jsdom(null, null, {});
1148
- fs = require("fs");
1149
- window = document.createWindow();
1150
- Serenade.document = document;
1151
- return function(env) {
1152
- var element, html, model, viewName;
1153
- model = env.model;
1154
- viewName = env.filename.split('/').reverse()[0].replace(/\.serenade$/, '');
1155
- Serenade.view(viewName, fs.readFileSync(env.filename).toString());
1156
- element = Serenade.render(viewName, model, {});
1157
- document.body.appendChild(element);
1158
- html = document.body.innerHTML;
1159
- if (env.doctype !== false) {
1160
- html = "<!DOCTYPE html>\n" + html;
1161
- }
1162
- return html;
1163
- };
816
+ })();
817
+ return new Collection((_ref1 = this.toArray()).concat.apply(_ref1, args));
1164
818
  };
1165
819
 
1166
- }).call(this);
1167
-
1168
- };require['./lexer'] = new function() {
1169
- var exports = this;
1170
- (function() {
1171
- var COMMENT, IDENTIFIER, KEYWORDS, LITERAL, Lexer, MULTI_DENT, STRING, WHITESPACE,
1172
- __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
1173
-
1174
- IDENTIFIER = /^[a-zA-Z][a-zA-Z0-9\-_]*/;
820
+ Collection.prototype.toString = function() {
821
+ return this.toArray().toString();
822
+ };
1175
823
 
1176
- LITERAL = /^[\[\]=\:\-!#\.@]/;
824
+ Collection.prototype.toLocaleString = function() {
825
+ return this.toArray().toLocaleString();
826
+ };
1177
827
 
1178
- STRING = /^"((?:\\.|[^"])*)"/;
828
+ Collection.prototype.toJSON = function() {
829
+ return serializeObject(this.toArray());
830
+ };
1179
831
 
1180
- MULTI_DENT = /^(?:\r?\n[^\r\n\S]*)+/;
832
+ return Collection;
1181
833
 
1182
- WHITESPACE = /^[^\r\n\S]+/;
834
+ })();
1183
835
 
1184
- COMMENT = /^\s*\/\/[^\n]*/;
836
+ AssociationCollection = (function(_super) {
837
+
838
+ __extends(AssociationCollection, _super);
839
+
840
+ function AssociationCollection(owner, options, list) {
841
+ var _this = this;
842
+ this.owner = owner;
843
+ this.options = options;
844
+ this._convert.apply(this, __slice.call(list).concat([function() {
845
+ var items;
846
+ items = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
847
+ return AssociationCollection.__super__.constructor.call(_this, items);
848
+ }]));
849
+ }
850
+
851
+ AssociationCollection.prototype.set = function(index, item) {
852
+ var _this = this;
853
+ return this._convert(item, function(item) {
854
+ return AssociationCollection.__super__.set.call(_this, index, item);
855
+ });
856
+ };
1185
857
 
1186
- KEYWORDS = ["IF", "ELSE", "COLLECTION", "IN", "VIEW", "UNLESS"];
858
+ AssociationCollection.prototype.push = function(item) {
859
+ var _this = this;
860
+ return this._convert(item, function(item) {
861
+ return AssociationCollection.__super__.push.call(_this, item);
862
+ });
863
+ };
1187
864
 
1188
- Lexer = (function() {
865
+ AssociationCollection.prototype.update = function(list) {
866
+ var _this = this;
867
+ return this._convert.apply(this, __slice.call(list).concat([function() {
868
+ var items;
869
+ items = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
870
+ return AssociationCollection.__super__.update.call(_this, items);
871
+ }]));
872
+ };
1189
873
 
1190
- Lexer.name = 'Lexer';
874
+ AssociationCollection.prototype.splice = function() {
875
+ var deleteCount, list, start,
876
+ _this = this;
877
+ start = arguments[0], deleteCount = arguments[1], list = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
878
+ return this._convert.apply(this, __slice.call(list).concat([function() {
879
+ var items;
880
+ items = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
881
+ return AssociationCollection.__super__.splice.apply(_this, [start, deleteCount].concat(__slice.call(items)));
882
+ }]));
883
+ };
1191
884
 
1192
- function Lexer() {}
885
+ AssociationCollection.prototype.insertAt = function(index, item) {
886
+ var _this = this;
887
+ return this._convert(item, function(item) {
888
+ return AssociationCollection.__super__.insertAt.call(_this, index, item);
889
+ });
890
+ };
1193
891
 
1194
- Lexer.prototype.tokenize = function(code, opts) {
1195
- var tag;
1196
- if (opts == null) {
1197
- opts = {};
1198
- }
1199
- this.code = code.replace(/^\s*/, '').replace(/\s*$/, '');
1200
- this.line = opts.line || 0;
1201
- this.indent = 0;
1202
- this.indents = [];
1203
- this.ends = [];
1204
- this.tokens = [];
1205
- this.i = 0;
1206
- while (this.chunk = this.code.slice(this.i)) {
1207
- this.i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.stringToken() || this.literalToken();
1208
- }
1209
- while (tag = this.ends.pop()) {
1210
- if (tag === 'OUTDENT') {
1211
- this.token('OUTDENT');
892
+ AssociationCollection.prototype._convert = function() {
893
+ var fn, item, items, returnValue, _i, _j, _len;
894
+ items = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), fn = arguments[_i++];
895
+ items = (function() {
896
+ var _j, _len, _results;
897
+ _results = [];
898
+ for (_j = 0, _len = items.length; _j < _len; _j++) {
899
+ item = items[_j];
900
+ if ((item != null ? item.constructor : void 0) === Object && this.options.as) {
901
+ _results.push(item = new (this.options.as())(item));
1212
902
  } else {
1213
- this.error("missing " + tag);
903
+ _results.push(item);
1214
904
  }
1215
905
  }
1216
- while (this.tokens[0][0] === "TERMINATOR") {
1217
- this.tokens.shift();
1218
- }
1219
- while (this.tokens[this.tokens.length - 1][0] === "TERMINATOR") {
1220
- this.tokens.pop();
1221
- }
1222
- return this.tokens;
1223
- };
1224
-
1225
- Lexer.prototype.commentToken = function() {
1226
- var match;
1227
- if (match = COMMENT.exec(this.chunk)) {
1228
- return match[0].length;
1229
- } else {
1230
- return 0;
1231
- }
1232
- };
1233
-
1234
- Lexer.prototype.whitespaceToken = function() {
1235
- var match;
1236
- if (match = WHITESPACE.exec(this.chunk)) {
1237
- this.token('WHITESPACE', match[0].length);
1238
- return match[0].length;
1239
- } else {
1240
- return 0;
906
+ return _results;
907
+ }).call(this);
908
+ returnValue = fn.apply(null, items);
909
+ for (_j = 0, _len = items.length; _j < _len; _j++) {
910
+ item = items[_j];
911
+ if (this.options.inverseOf && item[this.options.inverseOf] !== this.owner) {
912
+ item[this.options.inverseOf] = this.owner;
1241
913
  }
1242
- };
1243
-
1244
- Lexer.prototype.token = function(tag, value) {
1245
- return this.tokens.push([tag, value, this.line]);
1246
- };
914
+ }
915
+ return returnValue;
916
+ };
1247
917
 
1248
- Lexer.prototype.identifierToken = function() {
1249
- var match, name;
1250
- if (match = IDENTIFIER.exec(this.chunk)) {
1251
- name = match[0].toUpperCase();
1252
- if (name === "ELSE" && this.last(this.tokens, 2)[0] === "TERMINATOR") {
1253
- this.tokens.splice(this.tokens.length - 3, 1);
1254
- }
1255
- if (__indexOf.call(KEYWORDS, name) >= 0) {
1256
- this.token(name, match[0]);
1257
- } else {
1258
- this.token('IDENTIFIER', match[0]);
918
+ return AssociationCollection;
919
+
920
+ })(Collection);
921
+
922
+ globalDependencies = {};
923
+
924
+ triggerGlobal = function(target, names) {
925
+ var dependency, name, object, subname, type, _i, _len, _results;
926
+ _results = [];
927
+ for (_i = 0, _len = names.length; _i < _len; _i++) {
928
+ name = names[_i];
929
+ if (globalDependencies.hasOwnProperty(name)) {
930
+ _results.push((function() {
931
+ var _j, _len1, _ref, _ref1, _ref2, _ref3, _results1;
932
+ _ref = globalDependencies[name];
933
+ _results1 = [];
934
+ for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
935
+ _ref1 = _ref[_j], name = _ref1.name, type = _ref1.type, object = _ref1.object, subname = _ref1.subname, dependency = _ref1.dependency;
936
+ if (type === "singular") {
937
+ if (target === object[name]) {
938
+ _results1.push((_ref2 = object[dependency + "_property"]) != null ? typeof _ref2.trigger === "function" ? _ref2.trigger(object) : void 0 : void 0);
939
+ } else {
940
+ _results1.push(void 0);
941
+ }
942
+ } else if (type === "collection") {
943
+ if (__indexOf.call(object[name], target) >= 0) {
944
+ _results1.push((_ref3 = object[dependency + "_property"]) != null ? typeof _ref3.trigger === "function" ? _ref3.trigger(object) : void 0 : void 0);
945
+ } else {
946
+ _results1.push(void 0);
947
+ }
948
+ } else {
949
+ _results1.push(void 0);
950
+ }
1259
951
  }
1260
- return match[0].length;
1261
- } else {
1262
- return 0;
1263
- }
1264
- };
1265
-
1266
- Lexer.prototype.stringToken = function() {
1267
- var match;
1268
- if (match = STRING.exec(this.chunk)) {
1269
- this.token('STRING_LITERAL', match[1]);
1270
- return match[0].length;
1271
- } else {
1272
- return 0;
1273
- }
1274
- };
952
+ return _results1;
953
+ })());
954
+ } else {
955
+ _results.push(void 0);
956
+ }
957
+ }
958
+ return _results;
959
+ };
1275
960
 
1276
- Lexer.prototype.lineToken = function() {
1277
- var diff, indent, match, prev, size;
1278
- if (!(match = MULTI_DENT.exec(this.chunk))) {
1279
- return 0;
961
+ PropertyDefinition = (function() {
962
+
963
+ function PropertyDefinition(name, options) {
964
+ var _i, _len, _ref;
965
+ this.name = name;
966
+ extend(this, options);
967
+ this.dependencies = [];
968
+ this.localDependencies = [];
969
+ this.globalDependencies = [];
970
+ if (this.dependsOn) {
971
+ _ref = [].concat(this.dependsOn);
972
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
973
+ name = _ref[_i];
974
+ this.addDependency(name);
1280
975
  }
1281
- indent = match[0];
1282
- this.line += this.count(indent, '\n');
1283
- prev = this.last(this.tokens, 1);
1284
- size = indent.length - 1 - indent.lastIndexOf('\n');
1285
- diff = size - this.indent;
1286
- if (size === this.indent) {
1287
- this.newlineToken();
1288
- } else if (size > this.indent) {
1289
- this.token('INDENT');
1290
- this.indents.push(diff);
1291
- this.ends.push('OUTDENT');
1292
- } else {
1293
- while (diff < 0) {
1294
- this.ends.pop();
1295
- diff += this.indents.pop();
1296
- this.token('OUTDENT');
1297
- }
1298
- this.token('TERMINATOR', '\n');
976
+ }
977
+ this.async = "async" in options ? options.async : settings.async;
978
+ this.eventOptions = {
979
+ async: this.async,
980
+ bind: function() {
981
+ return this[name];
982
+ },
983
+ optimize: function(queue) {
984
+ return queue[queue.length - 1];
985
+ }
986
+ };
987
+ }
988
+
989
+ PropertyDefinition.prototype.addDependency = function(name) {
990
+ var subname, type, _ref, _ref1;
991
+ if (this.dependencies.indexOf(name) === -1) {
992
+ this.dependencies.push(name);
993
+ if (name.match(/\./)) {
994
+ type = "singular";
995
+ _ref = name.split("."), name = _ref[0], subname = _ref[1];
996
+ } else if (name.match(/:/)) {
997
+ type = "collection";
998
+ _ref1 = name.split(":"), name = _ref1[0], subname = _ref1[1];
999
+ }
1000
+ this.localDependencies.push(name);
1001
+ if (this.localDependencies.indexOf(name) === -1) {
1002
+ this.localDependencies.push(name);
1003
+ }
1004
+ if (type) {
1005
+ return this.globalDependencies.push({
1006
+ subname: subname,
1007
+ name: name,
1008
+ type: type
1009
+ });
1299
1010
  }
1300
- this.indent = size;
1301
- return indent.length;
1302
- };
1011
+ }
1012
+ };
1303
1013
 
1304
- Lexer.prototype.literalToken = function() {
1305
- var match;
1306
- if (match = LITERAL.exec(this.chunk)) {
1307
- this.token(match[0]);
1308
- return 1;
1309
- } else {
1310
- return this.error("Unexpected token '" + (this.chunk.charAt(0)) + "'");
1311
- }
1312
- };
1014
+ return PropertyDefinition;
1313
1015
 
1314
- Lexer.prototype.newlineToken = function() {
1315
- if (this.tag() !== 'TERMINATOR') {
1316
- return this.token('TERMINATOR', '\n');
1317
- }
1318
- };
1016
+ })();
1319
1017
 
1320
- Lexer.prototype.tag = function(index, tag) {
1321
- var tok;
1322
- return (tok = this.last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]);
1323
- };
1018
+ PropertyAccessor = (function() {
1324
1019
 
1325
- Lexer.prototype.value = function(index, val) {
1326
- var tok;
1327
- return (tok = this.last(this.tokens, index)) && (val ? tok[1] = val : tok[1]);
1328
- };
1020
+ function PropertyAccessor(definition, object) {
1021
+ this.definition = definition;
1022
+ this.object = object;
1023
+ this.name = this.definition.name;
1024
+ this.valueName = "_s_" + this.name + "_val";
1025
+ this.event = new Event(this.object, this.name + "_change", this.definition.eventOptions);
1026
+ }
1329
1027
 
1330
- Lexer.prototype.error = function(message) {
1331
- var chunk;
1332
- chunk = this.code.slice(Math.max(0, this.i - 10), Math.min(this.code.length, this.i + 10));
1333
- throw SyntaxError("" + message + " on line " + (this.line + 1) + " near " + (JSON.stringify(chunk)));
1334
- };
1028
+ PropertyAccessor.prototype.set = function(value) {
1029
+ if (typeof value === "function") {
1030
+ return this.definition.get = value;
1031
+ } else {
1032
+ if (this.definition.set) {
1033
+ this.definition.set.call(this.object, value);
1034
+ } else {
1035
+ def(this.object, this.valueName, {
1036
+ value: value,
1037
+ configurable: true
1038
+ });
1039
+ }
1040
+ return this.trigger();
1041
+ }
1042
+ };
1335
1043
 
1336
- Lexer.prototype.count = function(string, substr) {
1337
- var num, pos;
1338
- num = pos = 0;
1339
- if (!substr.length) {
1340
- return 1 / 0;
1044
+ PropertyAccessor.prototype.get = function() {
1045
+ var listener, value,
1046
+ _this = this;
1047
+ this.registerGlobal();
1048
+ if (this.definition.get) {
1049
+ listener = function(name) {
1050
+ return _this.definition.addDependency(name);
1051
+ };
1052
+ if (!("dependsOn" in this.definition)) {
1053
+ this.object._s_property_access.bind(listener);
1341
1054
  }
1342
- while (pos = 1 + string.indexOf(substr, pos)) {
1343
- num++;
1055
+ value = this.definition.get.call(this.object);
1056
+ if (!("dependsOn" in this.definition)) {
1057
+ this.object._s_property_access.unbind(listener);
1344
1058
  }
1345
- return num;
1346
- };
1347
-
1348
- Lexer.prototype.last = function(array, back) {
1349
- return array[array.length - (back || 0) - 1];
1350
- };
1351
-
1352
- return Lexer;
1353
-
1354
- })();
1355
-
1356
- exports.Lexer = Lexer;
1357
-
1358
- }).call(this);
1359
-
1360
- };require['./node'] = new function() {
1361
- var exports = this;
1362
- (function() {
1363
- var Collection, Events, Node, NodeEvents, Serenade, extend, _ref;
1364
-
1365
- Serenade = require('./serenade').Serenade;
1059
+ } else {
1060
+ value = this.object[this.valueName];
1061
+ }
1062
+ this.object._s_property_access.trigger(this.name);
1063
+ return value;
1064
+ };
1366
1065
 
1367
- _ref = require('./events'), Events = _ref.Events, NodeEvents = _ref.NodeEvents;
1066
+ PropertyAccessor.prototype.format = function() {
1067
+ if (typeof this.definition.format === "function") {
1068
+ return this.definition.format.call(this.object, this.get());
1069
+ } else {
1070
+ return this.get();
1071
+ }
1072
+ };
1368
1073
 
1369
- extend = require('./helpers').extend;
1074
+ PropertyAccessor.prototype.registerGlobal = function() {
1075
+ var name, subname, type, _i, _len, _ref, _ref1, _results;
1076
+ if (!this.object["_s_glb_" + this.name]) {
1077
+ def(this.object, "_s_glb_" + this.name, {
1078
+ value: true,
1079
+ configurable: true
1080
+ });
1081
+ _ref = this.definition.globalDependencies;
1082
+ _results = [];
1083
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1084
+ _ref1 = _ref[_i], name = _ref1.name, type = _ref1.type, subname = _ref1.subname;
1085
+ globalDependencies[subname] || (globalDependencies[subname] = []);
1086
+ _results.push(globalDependencies[subname].push({
1087
+ object: this.object,
1088
+ subname: subname,
1089
+ name: name,
1090
+ type: type,
1091
+ dependency: this.name
1092
+ }));
1093
+ }
1094
+ return _results;
1095
+ }
1096
+ };
1370
1097
 
1371
- Collection = require('./collection').Collection;
1098
+ PropertyAccessor.prototype.trigger = function() {
1099
+ var changes, name, names, value, _i, _len, _ref, _results;
1100
+ names = [this.name].concat(this.dependents);
1101
+ changes = {};
1102
+ for (_i = 0, _len = names.length; _i < _len; _i++) {
1103
+ name = names[_i];
1104
+ changes[name] = this.object[name];
1105
+ }
1106
+ if ((_ref = this.object.changed) != null) {
1107
+ if (typeof _ref.trigger === "function") {
1108
+ _ref.trigger(changes);
1109
+ }
1110
+ }
1111
+ triggerGlobal(this.object, names);
1112
+ _results = [];
1113
+ for (name in changes) {
1114
+ if (!__hasProp.call(changes, name)) continue;
1115
+ value = changes[name];
1116
+ _results.push(this.object[name + "_property"].event.trigger(value));
1117
+ }
1118
+ return _results;
1119
+ };
1372
1120
 
1373
- Node = (function() {
1121
+ PropertyAccessor.prototype.bind = function(fun) {
1122
+ return this.event.bind(fun);
1123
+ };
1374
1124
 
1375
- Node.name = 'Node';
1125
+ PropertyAccessor.prototype.unbind = function(fun) {
1126
+ return this.event.unbind(fun);
1127
+ };
1376
1128
 
1377
- extend(Node.prototype, Events);
1129
+ PropertyAccessor.prototype.one = function(fun) {
1130
+ return this.event.one(fun);
1131
+ };
1378
1132
 
1379
- extend(Node.prototype, NodeEvents);
1133
+ def(PropertyAccessor.prototype, "dependents", {
1134
+ get: function() {
1135
+ var deps, findDependencies,
1136
+ _this = this;
1137
+ deps = [];
1138
+ findDependencies = function(name) {
1139
+ var property, _i, _len, _ref, _ref1, _results;
1140
+ _ref = _this.object._s_properties;
1141
+ _results = [];
1142
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1143
+ property = _ref[_i];
1144
+ if ((_ref1 = property.name, __indexOf.call(deps, _ref1) < 0) && __indexOf.call(property.localDependencies, name) >= 0) {
1145
+ deps.push(property.name);
1146
+ _results.push(findDependencies(property.name));
1147
+ } else {
1148
+ _results.push(void 0);
1149
+ }
1150
+ }
1151
+ return _results;
1152
+ };
1153
+ findDependencies(this.name);
1154
+ return deps;
1155
+ }
1156
+ });
1380
1157
 
1381
- function Node(ast, element) {
1382
- this.ast = ast;
1383
- this.element = element;
1384
- this.children = new Collection([]);
1158
+ def(PropertyAccessor.prototype, "listeners", {
1159
+ get: function() {
1160
+ return this.event.listeners;
1385
1161
  }
1162
+ });
1386
1163
 
1387
- Node.prototype.append = function(inside) {
1388
- return inside.appendChild(this.element);
1389
- };
1164
+ return PropertyAccessor;
1390
1165
 
1391
- Node.prototype.insertAfter = function(after) {
1392
- return after.parentNode.insertBefore(this.element, after.nextSibling);
1393
- };
1166
+ })();
1394
1167
 
1395
- Node.prototype.remove = function() {
1396
- var _ref1;
1397
- this.unbindEvents();
1398
- return (_ref1 = this.element.parentNode) != null ? _ref1.removeChild(this.element) : void 0;
1399
- };
1168
+ defineProperty = function(object, name, options) {
1169
+ var definition;
1170
+ if (options == null) {
1171
+ options = {};
1172
+ }
1173
+ definition = new PropertyDefinition(name, options);
1174
+ safePush(object, "_s_properties", definition);
1175
+ defineEvent(object, "_s_property_access");
1176
+ def(object, name, {
1177
+ get: function() {
1178
+ return this[name + "_property"].get();
1179
+ },
1180
+ set: function(value) {
1181
+ return this[name + "_property"].set(value);
1182
+ },
1183
+ configurable: true,
1184
+ enumerable: "enumerable" in options ? options.enumerable : true
1185
+ });
1186
+ def(object, name + "_property", {
1187
+ get: function() {
1188
+ return new PropertyAccessor(definition, this);
1189
+ },
1190
+ configurable: true
1191
+ });
1192
+ if (typeof options.serialize === 'string') {
1193
+ defineProperty(object, options.serialize, {
1194
+ get: function() {
1195
+ return this[name];
1196
+ },
1197
+ set: function(v) {
1198
+ return this[name] = v;
1199
+ },
1200
+ configurable: true
1201
+ });
1202
+ }
1203
+ if ("value" in options) {
1204
+ return object[name] = options.value;
1205
+ }
1206
+ };
1400
1207
 
1401
- Node.prototype.lastElement = function() {
1402
- return this.element;
1403
- };
1208
+ idCounter = 1;
1404
1209
 
1405
- Node.prototype.nodes = function() {
1406
- return this.children;
1407
- };
1210
+ Model = (function() {
1408
1211
 
1409
- return Node;
1212
+ defineEvent(Model.prototype, "saved");
1410
1213
 
1411
- })();
1214
+ defineEvent(Model.prototype, "changed", {
1215
+ optimize: function(queue) {
1216
+ var item, result, _i, _len;
1217
+ result = {};
1218
+ for (_i = 0, _len = queue.length; _i < _len; _i++) {
1219
+ item = queue[_i];
1220
+ extend(result, item[0]);
1221
+ }
1222
+ return [result];
1223
+ }
1224
+ });
1412
1225
 
1413
- exports.Node = Node;
1226
+ Model.belongsTo = function() {
1227
+ var _ref;
1228
+ return (_ref = this.prototype).belongsTo.apply(_ref, arguments);
1229
+ };
1414
1230
 
1415
- }).call(this);
1231
+ Model.hasMany = function() {
1232
+ var _ref;
1233
+ return (_ref = this.prototype).hasMany.apply(_ref, arguments);
1234
+ };
1416
1235
 
1417
- };require['./dynamic_node'] = new function() {
1418
- var exports = this;
1419
- (function() {
1420
- var Collection, DynamicNode, NodeEvents, Serenade, extend;
1236
+ Model.identityMap = true;
1421
1237
 
1422
- Serenade = require('./serenade').Serenade;
1238
+ Model.find = function(id) {
1239
+ return Cache.get(this, id) || new this({
1240
+ id: id
1241
+ });
1242
+ };
1423
1243
 
1424
- Collection = require('./collection').Collection;
1244
+ Model.extend = function(ctor) {
1245
+ var New;
1246
+ return New = (function(_super) {
1425
1247
 
1426
- extend = require('./helpers').extend;
1248
+ __extends(New, _super);
1427
1249
 
1428
- NodeEvents = require('./events').NodeEvents;
1250
+ function New() {
1251
+ var val;
1252
+ val = New.__super__.constructor.apply(this, arguments);
1253
+ if (val) {
1254
+ return val;
1255
+ }
1256
+ if (ctor) {
1257
+ ctor.apply(this, arguments);
1258
+ }
1259
+ }
1429
1260
 
1430
- DynamicNode = (function() {
1261
+ return New;
1431
1262
 
1432
- DynamicNode.name = 'DynamicNode';
1263
+ })(this);
1264
+ };
1433
1265
 
1434
- extend(DynamicNode.prototype, NodeEvents);
1266
+ Model.property = function() {
1267
+ var name, names, options, _i, _j, _len, _results;
1268
+ names = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), options = arguments[_i++];
1269
+ if (typeof options === "string") {
1270
+ names.push(options);
1271
+ options = {};
1272
+ }
1273
+ _results = [];
1274
+ for (_j = 0, _len = names.length; _j < _len; _j++) {
1275
+ name = names[_j];
1276
+ _results.push(defineProperty(this.prototype, name, options));
1277
+ }
1278
+ return _results;
1279
+ };
1435
1280
 
1436
- function DynamicNode(ast) {
1437
- this.ast = ast;
1438
- this.anchor = Serenade.document.createTextNode('');
1439
- this.nodeSets = new Collection([]);
1281
+ Model.properties = function() {
1282
+ var name, names, _i, _len, _results;
1283
+ names = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
1284
+ _results = [];
1285
+ for (_i = 0, _len = names.length; _i < _len; _i++) {
1286
+ name = names[_i];
1287
+ _results.push(this.property(name));
1440
1288
  }
1289
+ return _results;
1290
+ };
1441
1291
 
1442
- DynamicNode.prototype.nodes = function() {
1443
- var node, nodes, set, _i, _j, _len, _len1, _ref;
1444
- nodes = [];
1445
- _ref = this.nodeSets;
1446
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1447
- set = _ref[_i];
1448
- for (_j = 0, _len1 = set.length; _j < _len1; _j++) {
1449
- node = set[_j];
1450
- nodes.push(node);
1292
+ Model.delegate = function() {
1293
+ var names, options, to, _i,
1294
+ _this = this;
1295
+ names = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), options = arguments[_i++];
1296
+ to = options.to;
1297
+ return names.forEach(function(name) {
1298
+ var propName;
1299
+ propName = name;
1300
+ if (options.prefix === true) {
1301
+ propName = to + capitalize(name);
1302
+ } else if (options.prefix) {
1303
+ propName = options.prefix + capitalize(name);
1304
+ }
1305
+ if (options.suffix === true) {
1306
+ propName = propName + capitalize(to);
1307
+ } else if (options.suffix) {
1308
+ propName = propName + options.suffix;
1309
+ }
1310
+ return _this.property(propName, {
1311
+ dependsOn: "" + to + "." + name,
1312
+ get: function() {
1313
+ var _ref;
1314
+ return (_ref = this[to]) != null ? _ref[name] : void 0;
1315
+ },
1316
+ set: function(value) {
1317
+ var _ref;
1318
+ return (_ref = this[to]) != null ? _ref[name] = value : void 0;
1319
+ }
1320
+ });
1321
+ });
1322
+ };
1323
+
1324
+ Model.collection = function(name, options) {
1325
+ if (options == null) {
1326
+ options = {};
1327
+ }
1328
+ extend(options, {
1329
+ get: function() {
1330
+ var valueName,
1331
+ _this = this;
1332
+ valueName = "_s_" + name + "_val";
1333
+ if (!this[valueName]) {
1334
+ this[valueName] = new Collection([]);
1335
+ this[valueName].change.bind(function() {
1336
+ return _this[name + "_property"].trigger();
1337
+ });
1451
1338
  }
1339
+ return this[valueName];
1340
+ },
1341
+ set: function(value) {
1342
+ return this[name].update(value);
1452
1343
  }
1453
- return nodes;
1454
- };
1344
+ });
1345
+ this.property(name, options);
1346
+ return this.property(name + 'Count', {
1347
+ get: function() {
1348
+ return this[name].length;
1349
+ },
1350
+ dependsOn: name
1351
+ });
1352
+ };
1455
1353
 
1456
- DynamicNode.prototype.rebuild = function() {
1457
- var last, node, _i, _len, _ref, _results;
1458
- if (this.anchor.parentNode) {
1459
- last = this.anchor;
1460
- _ref = this.nodes();
1461
- _results = [];
1462
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1463
- node = _ref[_i];
1464
- node.insertAfter(last);
1465
- _results.push(last = node.lastElement());
1354
+ Model.belongsTo = function(name, attributes) {
1355
+ if (attributes == null) {
1356
+ attributes = {};
1357
+ }
1358
+ extend(attributes, {
1359
+ set: function(model) {
1360
+ var previous, valueName;
1361
+ valueName = "_s_" + name + "_val";
1362
+ if (model && model.constructor === Object && attributes.as) {
1363
+ model = new (attributes.as())(model);
1364
+ }
1365
+ previous = this[valueName];
1366
+ this[valueName] = model;
1367
+ if (attributes.inverseOf && !model[attributes.inverseOf].includes(this)) {
1368
+ if (previous) {
1369
+ previous[attributes.inverseOf]["delete"](this);
1370
+ }
1371
+ return model[attributes.inverseOf].push(this);
1466
1372
  }
1467
- return _results;
1468
1373
  }
1469
- };
1374
+ });
1375
+ this.property(name, attributes);
1376
+ return this.property(name + 'Id', {
1377
+ get: function() {
1378
+ var _ref;
1379
+ return (_ref = this[name]) != null ? _ref.id : void 0;
1380
+ },
1381
+ set: function(id) {
1382
+ if (id != null) {
1383
+ return this[name] = attributes.as().find(id);
1384
+ }
1385
+ },
1386
+ dependsOn: name,
1387
+ serialize: attributes.serializeId
1388
+ });
1389
+ };
1470
1390
 
1471
- DynamicNode.prototype.replace = function(sets) {
1472
- var set;
1473
- this.clear();
1474
- this.nodeSets.update((function() {
1475
- var _i, _len, _results;
1476
- _results = [];
1477
- for (_i = 0, _len = sets.length; _i < _len; _i++) {
1478
- set = sets[_i];
1479
- _results.push(new Collection(set));
1391
+ Model.hasMany = function(name, attributes) {
1392
+ if (attributes == null) {
1393
+ attributes = {};
1394
+ }
1395
+ extend(attributes, {
1396
+ get: function() {
1397
+ var valueName,
1398
+ _this = this;
1399
+ valueName = "_s_" + name + "_val";
1400
+ if (!this[valueName]) {
1401
+ this[valueName] = new AssociationCollection(this, attributes, []);
1402
+ this[valueName].change.bind(function() {
1403
+ return _this[name + "_property"].trigger();
1404
+ });
1480
1405
  }
1481
- return _results;
1482
- })());
1483
- return this.rebuild();
1484
- };
1406
+ return this[valueName];
1407
+ },
1408
+ set: function(value) {
1409
+ return this[name].update(value);
1410
+ }
1411
+ });
1412
+ this.property(name, attributes);
1413
+ this.property(name + 'Ids', {
1414
+ get: function() {
1415
+ return new Collection(this[name]).map(function(item) {
1416
+ return item != null ? item.id : void 0;
1417
+ });
1418
+ },
1419
+ set: function(ids) {
1420
+ var id, objects;
1421
+ objects = (function() {
1422
+ var _i, _len, _results;
1423
+ _results = [];
1424
+ for (_i = 0, _len = ids.length; _i < _len; _i++) {
1425
+ id = ids[_i];
1426
+ _results.push(attributes.as().find(id));
1427
+ }
1428
+ return _results;
1429
+ })();
1430
+ return this[name].update(objects);
1431
+ },
1432
+ dependsOn: name,
1433
+ serialize: attributes.serializeIds
1434
+ });
1435
+ return this.property(name + 'Count', {
1436
+ get: function() {
1437
+ return this[name].length;
1438
+ },
1439
+ dependsOn: name
1440
+ });
1441
+ };
1485
1442
 
1486
- DynamicNode.prototype.appendNodeSet = function(nodes) {
1487
- return this.insertNodeSet(this.nodeSets.length, nodes);
1488
- };
1443
+ Model.selection = function(name, options) {
1444
+ if (options == null) {
1445
+ options = {};
1446
+ }
1447
+ this.property(name, {
1448
+ get: function() {
1449
+ return this[options.from].filter(function(item) {
1450
+ return item[options.filter];
1451
+ });
1452
+ },
1453
+ dependsOn: "" + options.from + ":" + options.filter
1454
+ });
1455
+ return this.property(name + 'Count', {
1456
+ get: function() {
1457
+ return this[name].length;
1458
+ },
1459
+ dependsOn: name
1460
+ });
1461
+ };
1489
1462
 
1490
- DynamicNode.prototype.deleteNodeSet = function(index) {
1491
- var node, _i, _len, _ref;
1492
- _ref = this.nodeSets[index];
1493
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1494
- node = _ref[_i];
1495
- node.remove();
1463
+ Model.uniqueId = function() {
1464
+ if (!(this._uniqueId && this._uniqueGen === this)) {
1465
+ this._uniqueId = (idCounter += 1);
1466
+ this._uniqueGen = this;
1467
+ }
1468
+ return this._uniqueId;
1469
+ };
1470
+
1471
+ Model.property('id', {
1472
+ serialize: true,
1473
+ set: function(val) {
1474
+ Cache.unset(this.constructor, this.id);
1475
+ Cache.set(this.constructor, val, this);
1476
+ return def(this, "_s_id_val", {
1477
+ value: val,
1478
+ configurable: true
1479
+ });
1480
+ },
1481
+ get: function() {
1482
+ return this._s_id_val;
1483
+ }
1484
+ });
1485
+
1486
+ function Model(attributes) {
1487
+ var fromCache;
1488
+ if (this.constructor.identityMap && (attributes != null ? attributes.id : void 0)) {
1489
+ fromCache = Cache.get(this.constructor, attributes.id);
1490
+ if (fromCache) {
1491
+ fromCache.set(attributes);
1492
+ return fromCache;
1493
+ } else {
1494
+ Cache.set(this.constructor, attributes.id, this);
1496
1495
  }
1497
- return this.nodeSets.deleteAt(index);
1498
- };
1496
+ }
1497
+ this.set(attributes);
1498
+ }
1499
1499
 
1500
- DynamicNode.prototype.insertNodeSet = function(index, nodes) {
1501
- var last, node, _i, _len, _ref, _ref1;
1502
- last = ((_ref = this.nodeSets[index - 1]) != null ? (_ref1 = _ref.last()) != null ? _ref1.lastElement() : void 0 : void 0) || this.anchor;
1503
- for (_i = 0, _len = nodes.length; _i < _len; _i++) {
1504
- node = nodes[_i];
1505
- node.insertAfter(last);
1506
- last = node.lastElement();
1500
+ Model.prototype.set = function(attributes) {
1501
+ var name, value, _results;
1502
+ _results = [];
1503
+ for (name in attributes) {
1504
+ if (!__hasProp.call(attributes, name)) continue;
1505
+ value = attributes[name];
1506
+ if (!(name in this)) {
1507
+ defineProperty(this, name);
1507
1508
  }
1508
- return this.nodeSets.insertAt(index, new Collection(nodes));
1509
- };
1509
+ _results.push(this[name] = value);
1510
+ }
1511
+ return _results;
1512
+ };
1510
1513
 
1511
- DynamicNode.prototype.clear = function() {
1512
- var node, _i, _len, _ref;
1513
- _ref = this.nodes();
1514
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1515
- node = _ref[_i];
1516
- node.remove();
1514
+ Model.prototype.save = function() {
1515
+ return this.saved.trigger();
1516
+ };
1517
+
1518
+ Model.prototype.toJSON = function() {
1519
+ var key, property, serialized, value, _i, _len, _ref, _ref1;
1520
+ serialized = {};
1521
+ _ref = this._s_properties;
1522
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1523
+ property = _ref[_i];
1524
+ if (typeof property.serialize === 'string') {
1525
+ serialized[property.serialize] = serializeObject(this[property.name]);
1526
+ } else if (typeof property.serialize === 'function') {
1527
+ _ref1 = property.serialize.call(this), key = _ref1[0], value = _ref1[1];
1528
+ serialized[key] = serializeObject(value);
1529
+ } else if (property.serialize) {
1530
+ serialized[property.name] = serializeObject(this[property.name]);
1517
1531
  }
1518
- return this.nodeSets.update([]);
1519
- };
1532
+ }
1533
+ return serialized;
1534
+ };
1520
1535
 
1521
- DynamicNode.prototype.remove = function() {
1522
- this.unbindEvents();
1523
- this.clear();
1524
- return this.anchor.parentNode.removeChild(this.anchor);
1525
- };
1536
+ Model.prototype.toString = function() {
1537
+ return JSON.stringify(this.toJSON());
1538
+ };
1526
1539
 
1527
- DynamicNode.prototype.append = function(inside) {
1528
- inside.appendChild(this.anchor);
1529
- return this.rebuild();
1530
- };
1540
+ return Model;
1531
1541
 
1532
- DynamicNode.prototype.insertAfter = function(after) {
1533
- after.parentNode.insertBefore(this.anchor, after.nextSibling);
1534
- return this.rebuild();
1535
- };
1542
+ })();
1536
1543
 
1537
- DynamicNode.prototype.lastElement = function() {
1538
- var _ref, _ref1;
1539
- return ((_ref = this.nodeSets.last()) != null ? (_ref1 = _ref.last()) != null ? _ref1.lastElement() : void 0 : void 0) || this.anchor;
1540
- };
1544
+ IDENTIFIER = /^[a-zA-Z][a-zA-Z0-9\-_]*/;
1541
1545
 
1542
- return DynamicNode;
1546
+ LITERAL = /^[\[\]=\:\-!#\.@]/;
1543
1547
 
1544
- })();
1548
+ STRING = /^"((?:\\.|[^"])*)"/;
1545
1549
 
1546
- exports.DynamicNode = DynamicNode;
1550
+ MULTI_DENT = /^(?:\r?\n[^\r\n\S]*)+/;
1547
1551
 
1548
- }).call(this);
1552
+ WHITESPACE = /^[^\r\n\S]+/;
1549
1553
 
1550
- };require['./compile'] = new function() {
1551
- var exports = this;
1552
- (function() {
1553
- var Collection, Compile, DynamicNode, Node, Property, Serenade, compile, compileAll, format, getValue;
1554
+ COMMENT = /^\s*\/\/[^\n]*/;
1554
1555
 
1555
- Serenade = require('./serenade').Serenade;
1556
+ KEYWORDS = ["IF", "ELSE", "COLLECTION", "IN", "VIEW", "UNLESS"];
1556
1557
 
1557
- Collection = require('./collection').Collection;
1558
+ Lexer = (function() {
1558
1559
 
1559
- Node = require('./node').Node;
1560
+ function Lexer() {}
1560
1561
 
1561
- DynamicNode = require('./dynamic_node').DynamicNode;
1562
+ Lexer.prototype.tokenize = function(code, opts) {
1563
+ var tag;
1564
+ if (opts == null) {
1565
+ opts = {};
1566
+ }
1567
+ this.code = code.replace(/^\s*/, '').replace(/\s*$/, '');
1568
+ this.line = opts.line || 0;
1569
+ this.indent = 0;
1570
+ this.indents = [];
1571
+ this.ends = [];
1572
+ this.tokens = [];
1573
+ this.i = 0;
1574
+ while (this.chunk = this.code.slice(this.i)) {
1575
+ this.i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.stringToken() || this.literalToken();
1576
+ }
1577
+ while (tag = this.ends.pop()) {
1578
+ if (tag === 'OUTDENT') {
1579
+ this.token('OUTDENT');
1580
+ } else {
1581
+ this.error("missing " + tag);
1582
+ }
1583
+ }
1584
+ while (this.tokens[0][0] === "TERMINATOR") {
1585
+ this.tokens.shift();
1586
+ }
1587
+ while (this.tokens[this.tokens.length - 1][0] === "TERMINATOR") {
1588
+ this.tokens.pop();
1589
+ }
1590
+ return this.tokens;
1591
+ };
1562
1592
 
1563
- format = require('./helpers').format;
1593
+ Lexer.prototype.commentToken = function() {
1594
+ var match;
1595
+ if (match = COMMENT.exec(this.chunk)) {
1596
+ return match[0].length;
1597
+ } else {
1598
+ return 0;
1599
+ }
1600
+ };
1564
1601
 
1565
- getValue = function(ast, model) {
1566
- if (ast.bound && ast.value) {
1567
- return format(model, ast.value);
1568
- } else if (ast.value != null) {
1569
- return ast.value;
1602
+ Lexer.prototype.whitespaceToken = function() {
1603
+ var match;
1604
+ if (match = WHITESPACE.exec(this.chunk)) {
1605
+ this.token('WHITESPACE', match[0].length);
1606
+ return match[0].length;
1570
1607
  } else {
1571
- return model;
1608
+ return 0;
1572
1609
  }
1573
1610
  };
1574
1611
 
1575
- Property = {
1576
- style: function(ast, node, model, controller) {
1577
- var update;
1578
- update = function() {
1579
- return node.element.style[ast.name] = getValue(ast, model);
1580
- };
1581
- update();
1582
- if (ast.bound) {
1583
- return node.bindEvent(model, "change:" + ast.value, update);
1584
- }
1585
- },
1586
- event: function(ast, node, model, controller) {
1587
- return node.element.addEventListener(ast.name, function(e) {
1588
- if (ast.preventDefault) {
1589
- e.preventDefault();
1590
- }
1591
- return controller[ast.value](model, node.element, e);
1592
- });
1593
- },
1594
- binding: function(ast, node, model, controller) {
1595
- var domUpdated, element, handler, modelUpdated, _ref;
1596
- element = node.element;
1597
- ((_ref = node.ast.name) === "input" || _ref === "textarea" || _ref === "select") || (function() {
1598
- throw SyntaxError("invalid node type " + node.ast.name + " for two way binding");
1599
- })();
1600
- ast.value || (function() {
1601
- throw SyntaxError("cannot bind to whole model, please specify an attribute to bind to");
1602
- })();
1603
- domUpdated = function() {
1604
- return model[ast.value] = element.type === "checkbox" ? element.checked : element.type === "radio" ? element.checked ? element.getAttribute("value") : void 0 : element.value;
1605
- };
1606
- modelUpdated = function() {
1607
- var val;
1608
- val = model[ast.value];
1609
- if (element.type === "checkbox") {
1610
- return element.checked = !!val;
1611
- } else if (element.type === "radio") {
1612
- if (val === element.getAttribute("value")) {
1613
- return element.checked = true;
1614
- }
1615
- } else {
1616
- if (val === void 0) {
1617
- val = "";
1618
- }
1619
- if (element.value !== val) {
1620
- return element.value = val;
1621
- }
1622
- }
1623
- };
1624
- modelUpdated();
1625
- node.bindEvent(model, "change:" + ast.value, modelUpdated);
1626
- if (ast.name === "binding") {
1627
- handler = function(e) {
1628
- if (element.form === (e.target || e.srcElement)) {
1629
- return domUpdated();
1630
- }
1631
- };
1632
- Serenade.document.addEventListener("submit", handler, true);
1633
- return node.bind("unload", function() {
1634
- return Serenade.document.removeEventListener("submit", handler, true);
1635
- });
1636
- } else {
1637
- return element.addEventListener(ast.name, domUpdated);
1638
- }
1639
- },
1640
- attribute: function(ast, node, model, controller) {
1641
- var element, update;
1642
- if (ast.name === "binding") {
1643
- return Property.binding(ast, node, model, controller);
1644
- }
1645
- element = node.element;
1646
- update = function() {
1647
- var classes, value;
1648
- value = getValue(ast, model);
1649
- if (ast.name === 'value') {
1650
- return element.value = value || '';
1651
- } else if (node.ast.name === 'input' && ast.name === 'checked') {
1652
- return element.checked = !!value;
1653
- } else if (ast.name === 'class') {
1654
- classes = node.ast.classes;
1655
- if (value !== void 0) {
1656
- classes = classes.concat(value);
1657
- }
1658
- if (classes.length) {
1659
- return element.className = classes.join(' ');
1660
- } else {
1661
- element.className = '';
1662
- return element.removeAttribute(ast.name);
1663
- }
1664
- } else if (value === void 0) {
1665
- return element.removeAttribute(ast.name);
1666
- } else {
1667
- if (value === 0) {
1668
- value = "0";
1669
- }
1670
- return element.setAttribute(ast.name, value);
1671
- }
1672
- };
1673
- if (ast.bound) {
1674
- node.bindEvent(model, "change:" + ast.value, update);
1612
+ Lexer.prototype.token = function(tag, value) {
1613
+ return this.tokens.push([tag, value, this.line]);
1614
+ };
1615
+
1616
+ Lexer.prototype.identifierToken = function() {
1617
+ var match, name;
1618
+ if (match = IDENTIFIER.exec(this.chunk)) {
1619
+ name = match[0].toUpperCase();
1620
+ if (name === "ELSE" && this.last(this.tokens, 2)[0] === "TERMINATOR") {
1621
+ this.tokens.splice(this.tokens.length - 3, 1);
1675
1622
  }
1676
- return update();
1677
- },
1678
- on: function(ast, node, model, controller) {
1679
- var _ref;
1680
- if ((_ref = ast.name) === "load" || _ref === "unload") {
1681
- return node.bind(ast.name, function() {
1682
- return controller[ast.value](model, node.element);
1683
- });
1623
+ if (__indexOf.call(KEYWORDS, name) >= 0) {
1624
+ this.token(name, match[0]);
1684
1625
  } else {
1685
- throw new SyntaxError("unkown lifecycle event '" + ast.name + "'");
1626
+ this.token('IDENTIFIER', match[0]);
1686
1627
  }
1628
+ return match[0].length;
1629
+ } else {
1630
+ return 0;
1687
1631
  }
1688
1632
  };
1689
1633
 
1690
- Compile = {
1691
- element: function(ast, model, controller) {
1692
- var action, child, childNode, element, node, property, _i, _j, _len, _len1, _ref, _ref1, _ref2;
1693
- element = Serenade.document.createElement(ast.name);
1694
- node = new Node(ast, element);
1695
- if (ast.id) {
1696
- element.setAttribute('id', ast.id);
1697
- }
1698
- if ((_ref = ast.classes) != null ? _ref.length : void 0) {
1699
- element.setAttribute('class', ast.classes.join(' '));
1700
- }
1701
- _ref1 = ast.children;
1702
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
1703
- child = _ref1[_i];
1704
- childNode = compile(child, model, controller);
1705
- childNode.append(element);
1706
- node.children.push(childNode);
1707
- }
1708
- _ref2 = ast.properties;
1709
- for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
1710
- property = _ref2[_j];
1711
- action = Property[property.scope];
1712
- if (action) {
1713
- action(property, node, model, controller);
1714
- } else {
1715
- throw SyntaxError("" + property.scope + " is not a valid scope");
1716
- }
1717
- }
1718
- node.trigger("load");
1719
- return node;
1720
- },
1721
- view: function(ast, model, parent) {
1722
- var controller, skipCallback;
1723
- controller = Serenade.controllerFor(ast["arguments"][0]);
1724
- if (!controller) {
1725
- skipCallback = true;
1726
- controller = parent;
1727
- }
1728
- return Serenade._views[ast["arguments"][0]].node(model, controller, parent, skipCallback);
1729
- },
1730
- helper: function(ast, model, controller) {
1731
- var context, element, helperFunction, render;
1732
- render = function(model, controller) {
1733
- var child, fragment, node, _i, _len, _ref;
1734
- if (model == null) {
1735
- model = model;
1736
- }
1737
- if (controller == null) {
1738
- controller = controller;
1739
- }
1740
- fragment = Serenade.document.createDocumentFragment();
1741
- _ref = ast.children;
1742
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1743
- child = _ref[_i];
1744
- node = compile(child, model, controller);
1745
- node.append(fragment);
1746
- }
1747
- return fragment;
1748
- };
1749
- helperFunction = Serenade.Helpers[ast.command] || (function() {
1750
- throw SyntaxError("no helper " + ast.command + " defined");
1751
- })();
1752
- context = {
1753
- render: render,
1754
- model: model,
1755
- controller: controller
1756
- };
1757
- element = helperFunction.apply(context, ast["arguments"]);
1758
- return new Node(ast, element);
1759
- },
1760
- text: function(ast, model, controller) {
1761
- var getText, node, textNode;
1762
- getText = function() {
1763
- var value;
1764
- value = getValue(ast, model);
1765
- if (value === 0) {
1766
- value = "0";
1767
- }
1768
- return value || "";
1769
- };
1770
- textNode = Serenade.document.createTextNode(getText());
1771
- node = new Node(ast, textNode);
1772
- if (ast.bound) {
1773
- node.bindEvent(model, "change:" + ast.value, function() {
1774
- return textNode.nodeValue = getText();
1775
- });
1776
- }
1777
- return node;
1778
- },
1779
- collection: function(ast, model, controller) {
1780
- var collection, compileItem, dynamic, item,
1781
- _this = this;
1782
- compileItem = function(item) {
1783
- return compileAll(ast.children, item, controller);
1784
- };
1785
- dynamic = new DynamicNode(ast);
1786
- collection = model[ast["arguments"][0]];
1787
- if (typeof collection.bind === "function") {
1788
- dynamic.bindEvent(collection, 'set', function() {
1789
- var item;
1790
- return dynamic.replace((function() {
1791
- var _i, _len, _results;
1792
- _results = [];
1793
- for (_i = 0, _len = collection.length; _i < _len; _i++) {
1794
- item = collection[_i];
1795
- _results.push(compileItem(item));
1796
- }
1797
- return _results;
1798
- })());
1799
- });
1800
- dynamic.bindEvent(collection, 'update', function() {
1801
- var item;
1802
- return dynamic.replace((function() {
1803
- var _i, _len, _results;
1804
- _results = [];
1805
- for (_i = 0, _len = collection.length; _i < _len; _i++) {
1806
- item = collection[_i];
1807
- _results.push(compileItem(item));
1808
- }
1809
- return _results;
1810
- })());
1811
- });
1812
- dynamic.bindEvent(collection, 'add', function(item) {
1813
- return dynamic.appendNodeSet(compileItem(item));
1814
- });
1815
- dynamic.bindEvent(collection, 'insert', function(index, item) {
1816
- return dynamic.insertNodeSet(index, compileItem(item));
1817
- });
1818
- dynamic.bindEvent(collection, 'delete', function(index) {
1819
- return dynamic.deleteNodeSet(index);
1820
- });
1634
+ Lexer.prototype.stringToken = function() {
1635
+ var match;
1636
+ if (match = STRING.exec(this.chunk)) {
1637
+ this.token('STRING_LITERAL', match[1]);
1638
+ return match[0].length;
1639
+ } else {
1640
+ return 0;
1641
+ }
1642
+ };
1643
+
1644
+ Lexer.prototype.lineToken = function() {
1645
+ var diff, indent, match, prev, size;
1646
+ if (!(match = MULTI_DENT.exec(this.chunk))) {
1647
+ return 0;
1648
+ }
1649
+ indent = match[0];
1650
+ this.line += this.count(indent, '\n');
1651
+ prev = this.last(this.tokens, 1);
1652
+ size = indent.length - 1 - indent.lastIndexOf('\n');
1653
+ diff = size - this.indent;
1654
+ if (size === this.indent) {
1655
+ this.newlineToken();
1656
+ } else if (size > this.indent) {
1657
+ this.token('INDENT');
1658
+ this.indents.push(diff);
1659
+ this.ends.push('OUTDENT');
1660
+ } else {
1661
+ while (diff < 0) {
1662
+ this.ends.pop();
1663
+ diff += this.indents.pop();
1664
+ this.token('OUTDENT');
1821
1665
  }
1822
- dynamic.replace((function() {
1823
- var _i, _len, _results;
1824
- _results = [];
1825
- for (_i = 0, _len = collection.length; _i < _len; _i++) {
1826
- item = collection[_i];
1827
- _results.push(compileItem(item));
1828
- }
1829
- return _results;
1830
- })());
1831
- return dynamic;
1832
- },
1833
- "in": function(ast, model, controller) {
1834
- return Compile.bound(ast, model, controller, function(dynamic, value) {
1835
- if (value) {
1836
- return dynamic.replace([compileAll(ast.children, value, controller)]);
1837
- } else {
1838
- return dynamic.clear();
1839
- }
1840
- });
1841
- },
1842
- "if": function(ast, model, controller) {
1843
- return Compile.bound(ast, model, controller, function(dynamic, value) {
1844
- if (value) {
1845
- return dynamic.replace([compileAll(ast.children, model, controller)]);
1846
- } else if (ast["else"]) {
1847
- return dynamic.replace([compileAll(ast["else"].children, model, controller)]);
1848
- } else {
1849
- return dynamic.clear();
1850
- }
1851
- });
1852
- },
1853
- unless: function(ast, model, controller) {
1854
- return Compile.bound(ast, model, controller, function(dynamic, value) {
1855
- var child, nodes;
1856
- if (value) {
1857
- return dynamic.clear();
1858
- } else {
1859
- nodes = (function() {
1860
- var _i, _len, _ref, _results;
1861
- _ref = ast.children;
1862
- _results = [];
1863
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1864
- child = _ref[_i];
1865
- _results.push(compile(child, model, controller));
1866
- }
1867
- return _results;
1868
- })();
1869
- return dynamic.replace([nodes]);
1870
- }
1871
- });
1872
- },
1873
- bound: function(ast, model, controller, callback) {
1874
- var dynamic, update;
1875
- dynamic = new DynamicNode(ast);
1876
- update = function() {
1877
- var value;
1878
- value = model[ast["arguments"][0]];
1879
- return callback(dynamic, value);
1880
- };
1881
- update();
1882
- dynamic.bindEvent(model, "change:" + ast["arguments"][0], update);
1883
- return dynamic;
1666
+ this.token('TERMINATOR', '\n');
1667
+ }
1668
+ this.indent = size;
1669
+ return indent.length;
1670
+ };
1671
+
1672
+ Lexer.prototype.literalToken = function() {
1673
+ var match;
1674
+ if (match = LITERAL.exec(this.chunk)) {
1675
+ this.token(match[0]);
1676
+ return 1;
1677
+ } else {
1678
+ return this.error("Unexpected token '" + (this.chunk.charAt(0)) + "'");
1679
+ }
1680
+ };
1681
+
1682
+ Lexer.prototype.newlineToken = function() {
1683
+ if (this.tag() !== 'TERMINATOR') {
1684
+ return this.token('TERMINATOR', '\n');
1884
1685
  }
1885
1686
  };
1886
1687
 
1887
- compile = function(ast, model, controller) {
1888
- return Compile[ast.type](ast, model, controller);
1688
+ Lexer.prototype.tag = function(index, tag) {
1689
+ var tok;
1690
+ return (tok = this.last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]);
1889
1691
  };
1890
1692
 
1891
- compileAll = function(asts, model, controller) {
1892
- var ast, _i, _len, _results;
1893
- _results = [];
1894
- for (_i = 0, _len = asts.length; _i < _len; _i++) {
1895
- ast = asts[_i];
1896
- _results.push(Compile[ast.type](ast, model, controller));
1693
+ Lexer.prototype.value = function(index, val) {
1694
+ var tok;
1695
+ return (tok = this.last(this.tokens, index)) && (val ? tok[1] = val : tok[1]);
1696
+ };
1697
+
1698
+ Lexer.prototype.error = function(message) {
1699
+ var chunk;
1700
+ chunk = this.code.slice(Math.max(0, this.i - 10), Math.min(this.code.length, this.i + 10));
1701
+ throw SyntaxError("" + message + " on line " + (this.line + 1) + " near " + (JSON.stringify(chunk)));
1702
+ };
1703
+
1704
+ Lexer.prototype.count = function(string, substr) {
1705
+ var num, pos;
1706
+ num = pos = 0;
1707
+ if (!substr.length) {
1708
+ return 1 / 0;
1897
1709
  }
1898
- return _results;
1710
+ while (pos = 1 + string.indexOf(substr, pos)) {
1711
+ num++;
1712
+ }
1713
+ return num;
1899
1714
  };
1900
1715
 
1901
- exports.compile = compile;
1716
+ Lexer.prototype.last = function(array, back) {
1717
+ return array[array.length - (back || 0) - 1];
1718
+ };
1902
1719
 
1903
- }).call(this);
1720
+ return Lexer;
1904
1721
 
1905
- };require['./parser'] = new function() {
1906
- var exports = this;
1907
- /* Jison generated parser */
1908
- var parser = (function(){
1909
- ;
1910
- var parser = {trace: function trace() { },
1911
- yy: {},
1912
- symbols_: {"error":2,"Root":3,"Element":4,"ElementIdentifier":5,"AnyIdentifier":6,"#":7,".":8,"[":9,"]":10,"PropertyList":11,"WHITESPACE":12,"Text":13,"INDENT":14,"ChildList":15,"OUTDENT":16,"TextList":17,"Bound":18,"STRING_LITERAL":19,"Child":20,"TERMINATOR":21,"IfInstruction":22,"Instruction":23,"Property":24,"=":25,"!":26,":":27,"-":28,"VIEW":29,"COLLECTION":30,"UNLESS":31,"IN":32,"IDENTIFIER":33,"IF":34,"ElseInstruction":35,"ELSE":36,"@":37,"$accept":0,"$end":1},
1913
- terminals_: {2:"error",7:"#",8:".",9:"[",10:"]",12:"WHITESPACE",14:"INDENT",16:"OUTDENT",19:"STRING_LITERAL",21:"TERMINATOR",25:"=",26:"!",27:":",28:"-",29:"VIEW",30:"COLLECTION",31:"UNLESS",32:"IN",33:"IDENTIFIER",34:"IF",36:"ELSE",37:"@"},
1914
- productions_: [0,[3,0],[3,1],[5,1],[5,3],[5,2],[5,2],[5,3],[4,1],[4,3],[4,4],[4,3],[4,4],[17,1],[17,3],[13,1],[13,1],[15,1],[15,3],[20,1],[20,1],[20,1],[20,1],[11,1],[11,3],[24,3],[24,3],[24,4],[24,4],[24,3],[24,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,4],[22,3],[22,3],[22,4],[22,2],[35,6],[6,1],[6,1],[6,1],[6,1],[6,1],[6,1],[18,2],[18,1]],
1915
- performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
1722
+ })();
1916
1723
 
1917
- var $0 = $$.length - 1;
1918
- switch (yystate) {
1919
- case 1:this.$ = null;
1920
- break;
1921
- case 2:return this.$
1922
- break;
1923
- case 3:this.$ = {
1924
- name: $$[$0],
1925
- classes: []
1926
- };
1927
- break;
1928
- case 4:this.$ = {
1929
- name: $$[$0-2],
1930
- id: $$[$0],
1931
- classes: []
1932
- };
1933
- break;
1934
- case 5:this.$ = {
1935
- name: 'div',
1936
- id: $$[$0],
1937
- classes: []
1938
- };
1939
- break;
1940
- case 6:this.$ = {
1941
- name: 'div',
1942
- classes: [$$[$0]]
1943
- };
1944
- break;
1945
- case 7:this.$ = (function () {
1946
- $$[$0-2].classes.push($$[$0]);
1947
- return $$[$0-2];
1948
- }());
1949
- break;
1950
- case 8:this.$ = {
1951
- name: $$[$0].name,
1952
- id: $$[$0].id,
1953
- classes: $$[$0].classes,
1954
- properties: [],
1955
- children: [],
1956
- type: 'element'
1957
- };
1958
- break;
1959
- case 9:this.$ = $$[$0-2];
1960
- break;
1961
- case 10:this.$ = (function () {
1962
- $$[$0-3].properties = $$[$0-1];
1963
- return $$[$0-3];
1964
- }());
1965
- break;
1966
- case 11:this.$ = (function () {
1967
- $$[$0-2].children = $$[$0-2].children.concat($$[$0]);
1968
- return $$[$0-2];
1969
- }());
1970
- break;
1971
- case 12:this.$ = (function () {
1972
- $$[$0-3].children = $$[$0-3].children.concat($$[$0-1]);
1973
- return $$[$0-3];
1974
- }());
1975
- break;
1976
- case 13:this.$ = [$$[$0]];
1977
- break;
1978
- case 14:this.$ = $$[$0-2].concat($$[$0]);
1979
- break;
1980
- case 15:this.$ = {
1981
- type: 'text',
1982
- value: $$[$0],
1983
- bound: true
1984
- };
1985
- break;
1986
- case 16:this.$ = {
1987
- type: 'text',
1988
- value: $$[$0],
1989
- bound: false
1990
- };
1991
- break;
1992
- case 17:this.$ = [].concat($$[$0]);
1993
- break;
1994
- case 18:this.$ = $$[$0-2].concat($$[$0]);
1995
- break;
1996
- case 19:this.$ = $$[$0];
1997
- break;
1998
- case 20:this.$ = $$[$0];
1999
- break;
2000
- case 21:this.$ = $$[$0];
2001
- break;
2002
- case 22:this.$ = $$[$0];
2003
- break;
2004
- case 23:this.$ = [$$[$0]];
2005
- break;
2006
- case 24:this.$ = $$[$0-2].concat($$[$0]);
2007
- break;
2008
- case 25:this.$ = {
2009
- name: $$[$0-2],
2010
- value: $$[$0],
2011
- bound: true,
2012
- scope: 'attribute'
2013
- };
2014
- break;
2015
- case 26:this.$ = {
2016
- name: $$[$0-2],
2017
- value: $$[$0],
2018
- bound: true,
2019
- scope: 'attribute'
2020
- };
2021
- break;
2022
- case 27:this.$ = {
2023
- name: $$[$0-3],
2024
- value: $$[$0-1],
2025
- bound: true,
2026
- scope: 'attribute',
2027
- preventDefault: true
2028
- };
2029
- break;
2030
- case 28:this.$ = {
2031
- name: $$[$0-3],
2032
- value: $$[$0-1],
2033
- bound: true,
2034
- scope: 'attribute',
2035
- preventDefault: true
2036
- };
2037
- break;
2038
- case 29:this.$ = {
2039
- name: $$[$0-2],
2040
- value: $$[$0],
2041
- bound: false,
2042
- scope: 'attribute'
2043
- };
2044
- break;
2045
- case 30:this.$ = (function () {
2046
- $$[$0].scope = $$[$0-2];
2047
- return $$[$0];
2048
- }());
2049
- break;
2050
- case 31:this.$ = {
2051
- "arguments": [],
2052
- children: [],
2053
- type: 'view'
2054
- };
2055
- break;
2056
- case 32:this.$ = {
2057
- "arguments": [],
2058
- children: [],
2059
- type: 'collection'
2060
- };
2061
- break;
2062
- case 33:this.$ = {
2063
- "arguments": [],
2064
- children: [],
2065
- type: 'unless'
2066
- };
2067
- break;
2068
- case 34:this.$ = {
2069
- "arguments": [],
2070
- children: [],
2071
- type: 'in'
2072
- };
2073
- break;
2074
- case 35:this.$ = {
2075
- command: $$[$0],
2076
- "arguments": [],
2077
- children: [],
2078
- type: 'helper'
2079
- };
2080
- break;
2081
- case 36:this.$ = (function () {
2082
- $$[$0-2]["arguments"].push($$[$0].value);
2083
- return $$[$0-2];
2084
- }());
2085
- break;
2086
- case 37:this.$ = (function () {
2087
- $$[$0-3].children = $$[$0-1];
2088
- return $$[$0-3];
2089
- }());
2090
- break;
2091
- case 38:this.$ = {
2092
- "arguments": [],
2093
- children: [],
2094
- type: 'if'
2095
- };
2096
- break;
2097
- case 39:this.$ = (function () {
2098
- $$[$0-2]["arguments"].push($$[$0].value);
2099
- return $$[$0-2];
2100
- }());
2101
- break;
2102
- case 40:this.$ = (function () {
2103
- $$[$0-3].children = $$[$0-1];
2104
- return $$[$0-3];
2105
- }());
2106
- break;
2107
- case 41:this.$ = (function () {
2108
- $$[$0-1]["else"] = $$[$0];
2109
- return $$[$0-1];
2110
- }());
2111
- break;
2112
- case 42:this.$ = {
2113
- "arguments": [],
2114
- children: $$[$0-1],
2115
- type: 'else'
2116
- };
2117
- break;
2118
- case 43:this.$ = $$[$0];
2119
- break;
2120
- case 44:this.$ = $$[$0];
2121
- break;
2122
- case 45:this.$ = $$[$0];
2123
- break;
2124
- case 46:this.$ = $$[$0];
2125
- break;
2126
- case 47:this.$ = $$[$0];
2127
- break;
2128
- case 48:this.$ = $$[$0];
2129
- break;
2130
- case 49:this.$ = $$[$0];
2131
- break;
2132
- case 50:this.$ = (function () {}());
2133
- break;
2134
- }
2135
- },
2136
- table: [{1:[2,1],3:1,4:2,5:3,6:4,7:[1,5],8:[1,6],29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9]},{1:[3]},{1:[2,2],9:[1,13],12:[1,14],14:[1,15]},{1:[2,8],8:[1,16],9:[2,8],12:[2,8],14:[2,8],16:[2,8],21:[2,8]},{1:[2,3],7:[1,17],8:[2,3],9:[2,3],12:[2,3],14:[2,3],16:[2,3],21:[2,3]},{6:18,29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9]},{6:19,29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9]},{1:[2,43],7:[2,43],8:[2,43],9:[2,43],10:[2,43],12:[2,43],14:[2,43],16:[2,43],21:[2,43],25:[2,43],26:[2,43],27:[2,43],28:[2,43]},{1:[2,44],7:[2,44],8:[2,44],9:[2,44],10:[2,44],12:[2,44],14:[2,44],16:[2,44],21:[2,44],25:[2,44],26:[2,44],27:[2,44],28:[2,44]},{1:[2,45],7:[2,45],8:[2,45],9:[2,45],10:[2,45],12:[2,45],14:[2,45],16:[2,45],21:[2,45],25:[2,45],26:[2,45],27:[2,45],28:[2,45]},{1:[2,46],7:[2,46],8:[2,46],9:[2,46],10:[2,46],12:[2,46],14:[2,46],16:[2,46],21:[2,46],25:[2,46],26:[2,46],27:[2,46],28:[2,46]},{1:[2,47],7:[2,47],8:[2,47],9:[2,47],10:[2,47],12:[2,47],14:[2,47],16:[2,47],21:[2,47],25:[2,47],26:[2,47],27:[2,47],28:[2,47]},{1:[2,48],7:[2,48],8:[2,48],9:[2,48],10:[2,48],12:[2,48],14:[2,48],16:[2,48],21:[2,48],25:[2,48],26:[2,48],27:[2,48],28:[2,48]},{6:23,10:[1,20],11:21,24:22,29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9]},{13:24,18:25,19:[1,26],37:[1,27]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:35,15:28,17:33,18:25,19:[1,26],20:29,22:31,23:32,28:[1,34],29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9],37:[1,27]},{6:36,29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9]},{6:37,29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9]},{1:[2,5],8:[2,5],9:[2,5],12:[2,5],14:[2,5],16:[2,5],21:[2,5]},{1:[2,6],8:[2,6],9:[2,6],12:[2,6],14:[2,6],16:[2,6],21:[2,6]},{1:[2,9],9:[2,9],12:[2,9],14:[2,9],16:[2,9],21:[2,9]},{10:[1,38],12:[1,39]},{10:[2,23],12:[2,23]},{25:[1,40],27:[1,41]},{1:[2,11],9:[2,11],12:[2,11],14:[2,11],16:[2,11],21:[2,11]},{1:[2,15],9:[2,15],12:[2,15],14:[2,15],16:[2,15],21:[2,15],28:[2,15]},{1:[2,16],9:[2,16],12:[2,16],14:[2,16],16:[2,16],21:[2,16],28:[2,16]},{1:[2,50],6:42,9:[2,50],10:[2,50],12:[2,50],14:[2,50],16:[2,50],21:[2,50],26:[2,50],28:[2,50],29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9]},{16:[1,43],21:[1,44]},{16:[2,17],21:[2,17]},{9:[1,13],12:[1,14],14:[1,15],16:[2,19],21:[2,19]},{12:[1,45],14:[1,46],16:[2,20],21:[2,20],28:[1,48],35:47},{12:[1,49],14:[1,50],16:[2,21],21:[2,21]},{12:[1,51],16:[2,22],21:[2,22]},{12:[1,52]},{12:[2,13],16:[2,13],21:[2,13]},{1:[2,7],8:[2,7],9:[2,7],12:[2,7],14:[2,7],16:[2,7],21:[2,7]},{1:[2,4],8:[2,4],9:[2,4],12:[2,4],14:[2,4],16:[2,4],21:[2,4]},{1:[2,10],9:[2,10],12:[2,10],14:[2,10],16:[2,10],21:[2,10]},{6:23,24:53,29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9]},{6:54,18:55,19:[1,56],29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9],37:[1,27]},{6:23,24:57,29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9]},{1:[2,49],9:[2,49],10:[2,49],12:[2,49],14:[2,49],16:[2,49],21:[2,49],26:[2,49],28:[2,49]},{1:[2,12],9:[2,12],12:[2,12],14:[2,12],16:[2,12],21:[2,12]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:35,17:33,18:25,19:[1,26],20:58,22:31,23:32,28:[1,34],29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9],37:[1,27]},{13:59,18:25,19:[1,26],37:[1,27]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:35,15:60,17:33,18:25,19:[1,26],20:29,22:31,23:32,28:[1,34],29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9],37:[1,27]},{12:[2,41],14:[2,41],16:[2,41],21:[2,41],28:[2,41]},{12:[1,61]},{13:62,18:25,19:[1,26],37:[1,27]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:35,15:63,17:33,18:25,19:[1,26],20:29,22:31,23:32,28:[1,34],29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9],37:[1,27]},{13:64,18:25,19:[1,26],37:[1,27]},{29:[1,66],30:[1,67],31:[1,68],32:[1,69],33:[1,70],34:[1,65]},{10:[2,24],12:[2,24]},{10:[2,25],12:[2,25],26:[1,71]},{10:[2,26],12:[2,26],26:[1,72]},{10:[2,29],12:[2,29]},{10:[2,30],12:[2,30]},{16:[2,18],21:[2,18]},{12:[2,39],14:[2,39],16:[2,39],21:[2,39],28:[2,39]},{16:[1,73],21:[1,44]},{36:[1,74]},{12:[2,36],14:[2,36],16:[2,36],21:[2,36]},{16:[1,75],21:[1,44]},{12:[2,14],16:[2,14],21:[2,14]},{12:[2,38],14:[2,38],16:[2,38],21:[2,38],28:[2,38]},{12:[2,31],14:[2,31],16:[2,31],21:[2,31]},{12:[2,32],14:[2,32],16:[2,32],21:[2,32]},{12:[2,33],14:[2,33],16:[2,33],21:[2,33]},{12:[2,34],14:[2,34],16:[2,34],21:[2,34]},{12:[2,35],14:[2,35],16:[2,35],21:[2,35]},{10:[2,27],12:[2,27]},{10:[2,28],12:[2,28]},{12:[2,40],14:[2,40],16:[2,40],21:[2,40],28:[2,40]},{14:[1,76]},{12:[2,37],14:[2,37],16:[2,37],21:[2,37]},{4:30,5:3,6:4,7:[1,5],8:[1,6],13:35,15:77,17:33,18:25,19:[1,26],20:29,22:31,23:32,28:[1,34],29:[1,7],30:[1,8],31:[1,10],32:[1,11],33:[1,12],34:[1,9],37:[1,27]},{16:[1,78],21:[1,44]},{12:[2,42],14:[2,42],16:[2,42],21:[2,42],28:[2,42]}],
2137
- defaultActions: {},
2138
- parseError: function parseError(str, hash) {
2139
- throw new Error(str);
2140
- },
2141
- parse: function parse(input) {
2142
- var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
2143
- this.lexer.setInput(input);
2144
- this.lexer.yy = this.yy;
2145
- this.yy.lexer = this.lexer;
2146
- if (typeof this.lexer.yylloc == "undefined")
2147
- this.lexer.yylloc = {};
2148
- var yyloc = this.lexer.yylloc;
2149
- lstack.push(yyloc);
2150
- if (typeof this.yy.parseError === "function")
2151
- this.parseError = this.yy.parseError;
2152
- function popStack(n) {
2153
- stack.length = stack.length - 2 * n;
2154
- vstack.length = vstack.length - n;
2155
- lstack.length = lstack.length - n;
1724
+ Node = (function() {
1725
+
1726
+ defineEvent(Node.prototype, "load");
1727
+
1728
+ defineEvent(Node.prototype, "unload");
1729
+
1730
+ function Node(ast, element) {
1731
+ this.ast = ast;
1732
+ this.element = element;
1733
+ this.children = new Collection([]);
1734
+ this.boundClasses = new Collection([]);
1735
+ }
1736
+
1737
+ Node.prototype.append = function(inside) {
1738
+ return inside.appendChild(this.element);
1739
+ };
1740
+
1741
+ Node.prototype.insertAfter = function(after) {
1742
+ return after.parentNode.insertBefore(this.element, after.nextSibling);
1743
+ };
1744
+
1745
+ Node.prototype.remove = function() {
1746
+ var _ref;
1747
+ this.unbindEvents();
1748
+ return (_ref = this.element.parentNode) != null ? _ref.removeChild(this.element) : void 0;
1749
+ };
1750
+
1751
+ Node.prototype.lastElement = function() {
1752
+ return this.element;
1753
+ };
1754
+
1755
+ Node.prototype.nodes = function() {
1756
+ return this.children;
1757
+ };
1758
+
1759
+ Node.prototype.bindEvent = function(event, fun) {
1760
+ if (event) {
1761
+ this.boundEvents || (this.boundEvents = []);
1762
+ this.boundEvents.push({
1763
+ event: event,
1764
+ fun: fun
1765
+ });
1766
+ return event.bind(fun);
2156
1767
  }
2157
- function lex() {
2158
- var token;
2159
- token = self.lexer.lex() || 1;
2160
- if (typeof token !== "number") {
2161
- token = self.symbols_[token] || token;
2162
- }
2163
- return token;
1768
+ };
1769
+
1770
+ Node.prototype.unbindEvents = function() {
1771
+ var event, fun, node, _i, _j, _len, _len1, _ref, _ref1, _ref2, _results;
1772
+ this.unload.trigger();
1773
+ _ref = this.nodes();
1774
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1775
+ node = _ref[_i];
1776
+ node.unbindEvents();
2164
1777
  }
2165
- var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
2166
- while (true) {
2167
- state = stack[stack.length - 1];
2168
- if (this.defaultActions[state]) {
2169
- action = this.defaultActions[state];
2170
- } else {
2171
- if (symbol == null)
2172
- symbol = lex();
2173
- action = table[state] && table[state][symbol];
2174
- }
2175
- if (typeof action === "undefined" || !action.length || !action[0]) {
2176
- if (!recovering) {
2177
- expected = [];
2178
- for (p in table[state])
2179
- if (this.terminals_[p] && p > 2) {
2180
- expected.push("'" + this.terminals_[p] + "'");
2181
- }
2182
- var errStr = "";
2183
- if (this.lexer.showPosition) {
2184
- errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + this.terminals_[symbol] + "'";
2185
- } else {
2186
- errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
2187
- }
2188
- this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
2189
- }
2190
- }
2191
- if (action[0] instanceof Array && action.length > 1) {
2192
- throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
2193
- }
2194
- switch (action[0]) {
2195
- case 1:
2196
- stack.push(symbol);
2197
- vstack.push(this.lexer.yytext);
2198
- lstack.push(this.lexer.yylloc);
2199
- stack.push(action[1]);
2200
- symbol = null;
2201
- if (!preErrorSymbol) {
2202
- yyleng = this.lexer.yyleng;
2203
- yytext = this.lexer.yytext;
2204
- yylineno = this.lexer.yylineno;
2205
- yyloc = this.lexer.yylloc;
2206
- if (recovering > 0)
2207
- recovering--;
2208
- } else {
2209
- symbol = preErrorSymbol;
2210
- preErrorSymbol = null;
2211
- }
2212
- break;
2213
- case 2:
2214
- len = this.productions_[action[1]][1];
2215
- yyval.$ = vstack[vstack.length - len];
2216
- yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
2217
- r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
2218
- if (typeof r !== "undefined") {
2219
- return r;
2220
- }
2221
- if (len) {
2222
- stack = stack.slice(0, -1 * len * 2);
2223
- vstack = vstack.slice(0, -1 * len);
2224
- lstack = lstack.slice(0, -1 * len);
2225
- }
2226
- stack.push(this.productions_[action[1]][0]);
2227
- vstack.push(yyval.$);
2228
- lstack.push(yyval._$);
2229
- newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
2230
- stack.push(newState);
2231
- break;
2232
- case 3:
2233
- return true;
2234
- }
1778
+ if (this.boundEvents) {
1779
+ _ref1 = this.boundEvents;
1780
+ _results = [];
1781
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
1782
+ _ref2 = _ref1[_j], event = _ref2.event, fun = _ref2.fun;
1783
+ _results.push(event.unbind(fun));
1784
+ }
1785
+ return _results;
2235
1786
  }
2236
- return true;
2237
- }
2238
- };
2239
- return parser;
2240
- })();
2241
- if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
2242
- exports.parser = parser;
2243
- exports.parse = function () { return parser.parse.apply(parser, arguments); }
2244
- exports.main = function commonjsMain(args) {
2245
- if (!args[1])
2246
- throw new Error('Usage: '+args[0]+' FILE');
2247
- if (typeof process !== 'undefined') {
2248
- var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
1787
+ };
1788
+
1789
+ Node.prototype.updateClass = function() {
1790
+ var classes;
1791
+ classes = this.ast.classes;
1792
+ if (this.attributeClasses) {
1793
+ classes = classes.concat(this.attributeClasses);
1794
+ }
1795
+ if (this.boundClasses.length) {
1796
+ classes = classes.concat(this.boundClasses.toArray());
1797
+ }
1798
+ if (classes.length) {
1799
+ return this.element.className = classes.join(' ');
2249
1800
  } else {
2250
- var cwd = require("file").path(require("file").cwd());
2251
- var source = cwd.join(args[1]).read({charset: "utf-8"});
1801
+ return this.element.removeAttribute("class");
2252
1802
  }
2253
- return exports.parser.parse(source);
2254
- }
2255
- if (typeof module !== 'undefined' && require.main === module) {
2256
- exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
2257
- }
2258
- }
2259
- };require['./view'] = new function() {
2260
- var exports = this;
2261
- (function() {
2262
- var Lexer, Serenade, View, compile, parser,
2263
- __slice = [].slice;
1803
+ };
2264
1804
 
2265
- parser = require('./parser').parser;
1805
+ return Node;
2266
1806
 
2267
- Lexer = require('./lexer').Lexer;
1807
+ })();
2268
1808
 
2269
- compile = require('./compile').compile;
1809
+ DynamicNode = (function(_super) {
2270
1810
 
2271
- Serenade = require('./serenade').Serenade;
1811
+ __extends(DynamicNode, _super);
2272
1812
 
2273
- parser.lexer = {
2274
- lex: function() {
2275
- var tag, _ref;
2276
- _ref = this.tokens[this.pos++] || [''], tag = _ref[0], this.yytext = _ref[1], this.yylineno = _ref[2];
2277
- return tag;
2278
- },
2279
- setInput: function(tokens) {
2280
- this.tokens = tokens;
2281
- return this.pos = 0;
2282
- },
2283
- upcomingInput: function() {
2284
- return "";
1813
+ function DynamicNode(ast) {
1814
+ this.ast = ast;
1815
+ this.anchor = Serenade.document.createTextNode('');
1816
+ this.nodeSets = new Collection([]);
1817
+ }
1818
+
1819
+ DynamicNode.prototype.nodes = function() {
1820
+ var node, nodes, set, _i, _j, _len, _len1, _ref;
1821
+ nodes = [];
1822
+ _ref = this.nodeSets;
1823
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1824
+ set = _ref[_i];
1825
+ for (_j = 0, _len1 = set.length; _j < _len1; _j++) {
1826
+ node = set[_j];
1827
+ nodes.push(node);
1828
+ }
1829
+ }
1830
+ return nodes;
1831
+ };
1832
+
1833
+ DynamicNode.prototype.rebuild = function() {
1834
+ var last, node, _i, _len, _ref, _results;
1835
+ if (this.anchor.parentNode) {
1836
+ last = this.anchor;
1837
+ _ref = this.nodes();
1838
+ _results = [];
1839
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1840
+ node = _ref[_i];
1841
+ node.insertAfter(last);
1842
+ _results.push(last = node.lastElement());
1843
+ }
1844
+ return _results;
2285
1845
  }
2286
1846
  };
2287
1847
 
2288
- View = (function() {
1848
+ DynamicNode.prototype.replace = function(sets) {
1849
+ var set;
1850
+ this.clear();
1851
+ this.nodeSets.update((function() {
1852
+ var _i, _len, _results;
1853
+ _results = [];
1854
+ for (_i = 0, _len = sets.length; _i < _len; _i++) {
1855
+ set = sets[_i];
1856
+ _results.push(new Collection(set));
1857
+ }
1858
+ return _results;
1859
+ })());
1860
+ return this.rebuild();
1861
+ };
2289
1862
 
2290
- View.name = 'View';
1863
+ DynamicNode.prototype.appendNodeSet = function(nodes) {
1864
+ return this.insertNodeSet(this.nodeSets.length, nodes);
1865
+ };
2291
1866
 
2292
- function View(name, view) {
2293
- this.name = name;
2294
- this.view = view;
1867
+ DynamicNode.prototype.deleteNodeSet = function(index) {
1868
+ var node, _i, _len, _ref;
1869
+ _ref = this.nodeSets[index];
1870
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1871
+ node = _ref[_i];
1872
+ node.remove();
2295
1873
  }
1874
+ return this.nodeSets.deleteAt(index);
1875
+ };
2296
1876
 
2297
- View.prototype.parse = function() {
2298
- if (typeof this.view === 'string') {
2299
- try {
2300
- return this.view = parser.parse(new Lexer().tokenize(this.view));
2301
- } catch (e) {
2302
- if (this.name) {
2303
- e.message = "In view '" + this.name + "': " + e.message;
2304
- }
2305
- throw e;
1877
+ DynamicNode.prototype.insertNodeSet = function(index, nodes) {
1878
+ var last, node, _i, _len, _ref, _ref1;
1879
+ last = ((_ref = this.nodeSets[index - 1]) != null ? (_ref1 = _ref.last()) != null ? _ref1.lastElement() : void 0 : void 0) || this.anchor;
1880
+ for (_i = 0, _len = nodes.length; _i < _len; _i++) {
1881
+ node = nodes[_i];
1882
+ node.insertAfter(last);
1883
+ last = node.lastElement();
1884
+ }
1885
+ return this.nodeSets.insertAt(index, new Collection(nodes));
1886
+ };
1887
+
1888
+ DynamicNode.prototype.clear = function() {
1889
+ var node, _i, _len, _ref;
1890
+ _ref = this.nodes();
1891
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1892
+ node = _ref[_i];
1893
+ node.remove();
1894
+ }
1895
+ return this.nodeSets.update([]);
1896
+ };
1897
+
1898
+ DynamicNode.prototype.remove = function() {
1899
+ this.unbindEvents();
1900
+ this.clear();
1901
+ return this.anchor.parentNode.removeChild(this.anchor);
1902
+ };
1903
+
1904
+ DynamicNode.prototype.append = function(inside) {
1905
+ inside.appendChild(this.anchor);
1906
+ return this.rebuild();
1907
+ };
1908
+
1909
+ DynamicNode.prototype.insertAfter = function(after) {
1910
+ after.parentNode.insertBefore(this.anchor, after.nextSibling);
1911
+ return this.rebuild();
1912
+ };
1913
+
1914
+ DynamicNode.prototype.lastElement = function() {
1915
+ var _ref, _ref1;
1916
+ return ((_ref = this.nodeSets.last()) != null ? (_ref1 = _ref.last()) != null ? _ref1.lastElement() : void 0 : void 0) || this.anchor;
1917
+ };
1918
+
1919
+ return DynamicNode;
1920
+
1921
+ })(Node);
1922
+
1923
+ getValue = function(ast, model) {
1924
+ if (ast.bound && ast.value) {
1925
+ return format(model, ast.value);
1926
+ } else if (ast.value != null) {
1927
+ return ast.value;
1928
+ } else {
1929
+ return model;
1930
+ }
1931
+ };
1932
+
1933
+ Property = {
1934
+ style: function(ast, node, model, controller) {
1935
+ var update;
1936
+ update = function() {
1937
+ return node.element.style[ast.name] = getValue(ast, model);
1938
+ };
1939
+ update();
1940
+ if (ast.bound) {
1941
+ return node.bindEvent(model["" + ast.value + "_property"], update);
1942
+ }
1943
+ },
1944
+ event: function(ast, node, model, controller) {
1945
+ return node.element.addEventListener(ast.name, function(e) {
1946
+ if (ast.preventDefault) {
1947
+ e.preventDefault();
1948
+ }
1949
+ return controller[ast.value](node.element, model, e);
1950
+ });
1951
+ },
1952
+ "class": function(ast, node, model, controller) {
1953
+ var update;
1954
+ update = function() {
1955
+ if (model[ast.value]) {
1956
+ node.boundClasses.push(ast.name);
1957
+ } else {
1958
+ node.boundClasses["delete"](ast.name);
1959
+ }
1960
+ return node.updateClass();
1961
+ };
1962
+ update();
1963
+ return node.bindEvent(model["" + ast.value + "_property"], update);
1964
+ },
1965
+ binding: function(ast, node, model, controller) {
1966
+ var domUpdated, element, handler, modelUpdated, _ref;
1967
+ element = node.element;
1968
+ ((_ref = node.ast.name) === "input" || _ref === "textarea" || _ref === "select") || (function() {
1969
+ throw SyntaxError("invalid node type " + node.ast.name + " for two way binding");
1970
+ })();
1971
+ ast.value || (function() {
1972
+ throw SyntaxError("cannot bind to whole model, please specify an attribute to bind to");
1973
+ })();
1974
+ domUpdated = function() {
1975
+ return model[ast.value] = element.type === "checkbox" ? element.checked : element.type === "radio" ? element.checked ? element.getAttribute("value") : void 0 : element.value;
1976
+ };
1977
+ modelUpdated = function() {
1978
+ var val;
1979
+ val = model[ast.value];
1980
+ if (element.type === "checkbox") {
1981
+ return element.checked = !!val;
1982
+ } else if (element.type === "radio") {
1983
+ if (val === element.getAttribute("value")) {
1984
+ return element.checked = true;
2306
1985
  }
2307
1986
  } else {
2308
- return this.view;
1987
+ if (val === void 0) {
1988
+ val = "";
1989
+ }
1990
+ if (element.value !== val) {
1991
+ return element.value = val;
1992
+ }
2309
1993
  }
2310
1994
  };
2311
-
2312
- View.prototype.render = function() {
2313
- var args;
2314
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
2315
- return this.node.apply(this, args).element;
1995
+ modelUpdated();
1996
+ node.bindEvent(model["" + ast.value + "_property"], modelUpdated);
1997
+ if (ast.name === "binding") {
1998
+ handler = function(e) {
1999
+ if (element.form === (e.target || e.srcElement)) {
2000
+ return domUpdated();
2001
+ }
2002
+ };
2003
+ Serenade.document.addEventListener("submit", handler, true);
2004
+ return node.unload.bind(function() {
2005
+ return Serenade.document.removeEventListener("submit", handler, true);
2006
+ });
2007
+ } else {
2008
+ return element.addEventListener(ast.name, domUpdated);
2009
+ }
2010
+ },
2011
+ attribute: function(ast, node, model, controller) {
2012
+ var element, update;
2013
+ if (ast.name === "binding") {
2014
+ return Property.binding(ast, node, model, controller);
2015
+ }
2016
+ element = node.element;
2017
+ update = function() {
2018
+ var value;
2019
+ value = getValue(ast, model);
2020
+ if (ast.name === 'value') {
2021
+ return element.value = value || '';
2022
+ } else if (node.ast.name === 'input' && ast.name === 'checked') {
2023
+ return element.checked = !!value;
2024
+ } else if (ast.name === 'class') {
2025
+ node.attributeClasses = value;
2026
+ return node.updateClass();
2027
+ } else if (value === void 0) {
2028
+ return element.removeAttribute(ast.name);
2029
+ } else {
2030
+ if (value === 0) {
2031
+ value = "0";
2032
+ }
2033
+ return element.setAttribute(ast.name, value);
2034
+ }
2316
2035
  };
2036
+ if (ast.bound) {
2037
+ node.bindEvent(model["" + ast.value + "_property"], update);
2038
+ }
2039
+ return update();
2040
+ },
2041
+ on: function(ast, node, model, controller) {
2042
+ var _ref;
2043
+ if ((_ref = ast.name) === "load" || _ref === "unload") {
2044
+ return node[ast.name].bind(function() {
2045
+ return controller[ast.value](node.element, model);
2046
+ });
2047
+ } else {
2048
+ throw new SyntaxError("unkown lifecycle event '" + ast.name + "'");
2049
+ }
2050
+ }
2051
+ };
2317
2052
 
2318
- View.prototype.node = function(model, controller, parent, skipCallback) {
2319
- var node;
2320
- if (this.name) {
2321
- controller || (controller = Serenade.controllerFor(this.name, model));
2053
+ Compile = {
2054
+ element: function(ast, model, controller) {
2055
+ var action, child, childNode, element, node, property, _i, _j, _len, _len1, _ref, _ref1, _ref2;
2056
+ element = Serenade.document.createElement(ast.name);
2057
+ node = new Node(ast, element);
2058
+ if (ast.id) {
2059
+ element.setAttribute('id', ast.id);
2060
+ }
2061
+ if ((_ref = ast.classes) != null ? _ref.length : void 0) {
2062
+ element.setAttribute('class', ast.classes.join(' '));
2063
+ }
2064
+ _ref1 = ast.children;
2065
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
2066
+ child = _ref1[_i];
2067
+ childNode = compile(child, model, controller);
2068
+ childNode.append(element);
2069
+ node.children.push(childNode);
2070
+ }
2071
+ _ref2 = ast.properties;
2072
+ for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
2073
+ property = _ref2[_j];
2074
+ action = Property[property.scope];
2075
+ if (action) {
2076
+ action(property, node, model, controller);
2077
+ } else {
2078
+ throw SyntaxError("" + property.scope + " is not a valid scope");
2322
2079
  }
2323
- controller || (controller = {});
2324
- if (typeof controller === "function") {
2325
- controller = new controller(model, parent);
2080
+ }
2081
+ node.load.trigger();
2082
+ return node;
2083
+ },
2084
+ view: function(ast, model, parent) {
2085
+ var controller, skipCallback;
2086
+ controller = Serenade.controllerFor(ast.argument);
2087
+ if (!controller) {
2088
+ skipCallback = true;
2089
+ controller = parent;
2090
+ }
2091
+ return Serenade._views[ast.argument].node(model, controller, parent, skipCallback);
2092
+ },
2093
+ helper: function(ast, model, controller) {
2094
+ var argument, context, dynamic, helperFunction, render, update, _i, _len, _ref;
2095
+ dynamic = new DynamicNode(ast);
2096
+ render = function(model, controller) {
2097
+ var child, fragment, node, _i, _len, _ref;
2098
+ if (model == null) {
2099
+ model = model;
2100
+ }
2101
+ if (controller == null) {
2102
+ controller = controller;
2103
+ }
2104
+ fragment = Serenade.document.createDocumentFragment();
2105
+ _ref = ast.children;
2106
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2107
+ child = _ref[_i];
2108
+ node = compile(child, model, controller);
2109
+ node.append(fragment);
2110
+ }
2111
+ return fragment;
2112
+ };
2113
+ helperFunction = Serenade.Helpers[ast.command] || (function() {
2114
+ throw SyntaxError("no helper " + ast.command + " defined");
2115
+ })();
2116
+ context = {
2117
+ render: render,
2118
+ model: model,
2119
+ controller: controller
2120
+ };
2121
+ update = function() {
2122
+ var args, element, nodes;
2123
+ args = ast["arguments"].map(function(a) {
2124
+ if (a.bound) {
2125
+ return model[a.value];
2126
+ } else {
2127
+ return a.value;
2128
+ }
2129
+ });
2130
+ nodes = (function() {
2131
+ var _i, _len, _ref, _results;
2132
+ _ref = normalize(helperFunction.apply(context, args));
2133
+ _results = [];
2134
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2135
+ element = _ref[_i];
2136
+ _results.push(new Node(ast, element));
2137
+ }
2138
+ return _results;
2139
+ })();
2140
+ return dynamic.replace([nodes]);
2141
+ };
2142
+ _ref = ast["arguments"];
2143
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2144
+ argument = _ref[_i];
2145
+ if (argument.bound === true) {
2146
+ dynamic.bindEvent(model["" + argument.value + "_property"], update);
2326
2147
  }
2327
- node = compile(this.parse(), model, controller);
2328
- if (!skipCallback) {
2329
- if (typeof controller.loaded === "function") {
2330
- controller.loaded(model, node.element);
2148
+ }
2149
+ update();
2150
+ return dynamic;
2151
+ },
2152
+ text: function(ast, model, controller) {
2153
+ var getText, node, textNode;
2154
+ getText = function() {
2155
+ var value;
2156
+ value = getValue(ast, model);
2157
+ if (value === 0) {
2158
+ value = "0";
2159
+ }
2160
+ return value || "";
2161
+ };
2162
+ textNode = Serenade.document.createTextNode(getText());
2163
+ node = new Node(ast, textNode);
2164
+ if (ast.bound) {
2165
+ node.bindEvent(model["" + ast.value + "_property"], function() {
2166
+ return textNode.nodeValue = getText();
2167
+ });
2168
+ }
2169
+ return node;
2170
+ },
2171
+ collection: function(ast, model, controller) {
2172
+ var collection, compileItem, dynamic, update,
2173
+ _this = this;
2174
+ compileItem = function(item) {
2175
+ return compileAll(ast.children, item, controller);
2176
+ };
2177
+ update = function(dynamic, collection) {
2178
+ var item;
2179
+ return dynamic.replace((function() {
2180
+ var _i, _len, _results;
2181
+ _results = [];
2182
+ for (_i = 0, _len = collection.length; _i < _len; _i++) {
2183
+ item = collection[_i];
2184
+ _results.push(compileItem(item));
2185
+ }
2186
+ return _results;
2187
+ })());
2188
+ };
2189
+ dynamic = this.bound(ast, model, controller, update);
2190
+ collection = model[ast.argument];
2191
+ dynamic.bindEvent(collection['change_set'], function() {
2192
+ var item;
2193
+ return dynamic.replace((function() {
2194
+ var _i, _len, _results;
2195
+ _results = [];
2196
+ for (_i = 0, _len = collection.length; _i < _len; _i++) {
2197
+ item = collection[_i];
2198
+ _results.push(compileItem(item));
2199
+ }
2200
+ return _results;
2201
+ })());
2202
+ });
2203
+ dynamic.bindEvent(collection['change_update'], function() {
2204
+ var item;
2205
+ return dynamic.replace((function() {
2206
+ var _i, _len, _results;
2207
+ _results = [];
2208
+ for (_i = 0, _len = collection.length; _i < _len; _i++) {
2209
+ item = collection[_i];
2210
+ _results.push(compileItem(item));
2331
2211
  }
2212
+ return _results;
2213
+ })());
2214
+ });
2215
+ dynamic.bindEvent(collection['change_add'], function(item) {
2216
+ return dynamic.appendNodeSet(compileItem(item));
2217
+ });
2218
+ dynamic.bindEvent(collection['change_insert'], function(index, item) {
2219
+ return dynamic.insertNodeSet(index, compileItem(item));
2220
+ });
2221
+ dynamic.bindEvent(collection['change_delete'], function(index) {
2222
+ return dynamic.deleteNodeSet(index);
2223
+ });
2224
+ return dynamic;
2225
+ },
2226
+ "in": function(ast, model, controller) {
2227
+ return this.bound(ast, model, controller, function(dynamic, value) {
2228
+ if (value) {
2229
+ return dynamic.replace([compileAll(ast.children, value, controller)]);
2230
+ } else {
2231
+ return dynamic.clear();
2232
+ }
2233
+ });
2234
+ },
2235
+ "if": function(ast, model, controller) {
2236
+ return this.bound(ast, model, controller, function(dynamic, value) {
2237
+ if (value) {
2238
+ return dynamic.replace([compileAll(ast.children, model, controller)]);
2239
+ } else if (ast["else"]) {
2240
+ return dynamic.replace([compileAll(ast["else"].children, model, controller)]);
2241
+ } else {
2242
+ return dynamic.clear();
2243
+ }
2244
+ });
2245
+ },
2246
+ unless: function(ast, model, controller) {
2247
+ return this.bound(ast, model, controller, function(dynamic, value) {
2248
+ var child, nodes;
2249
+ if (value) {
2250
+ return dynamic.clear();
2251
+ } else {
2252
+ nodes = (function() {
2253
+ var _i, _len, _ref, _results;
2254
+ _ref = ast.children;
2255
+ _results = [];
2256
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2257
+ child = _ref[_i];
2258
+ _results.push(compile(child, model, controller));
2259
+ }
2260
+ return _results;
2261
+ })();
2262
+ return dynamic.replace([nodes]);
2332
2263
  }
2333
- return node;
2264
+ });
2265
+ },
2266
+ bound: function(ast, model, controller, callback) {
2267
+ var dynamic, update;
2268
+ dynamic = new DynamicNode(ast);
2269
+ update = function() {
2270
+ var value;
2271
+ value = model[ast.argument];
2272
+ return callback(dynamic, value);
2334
2273
  };
2274
+ update();
2275
+ dynamic.bindEvent(model["" + ast.argument + "_property"], update);
2276
+ return dynamic;
2277
+ }
2278
+ };
2279
+
2280
+ normalize = function(val) {
2281
+ var reduction;
2282
+ if (!val) {
2283
+ return [];
2284
+ }
2285
+ reduction = function(aggregate, element) {
2286
+ var child, div, _i, _len, _ref;
2287
+ if (typeof element === "string") {
2288
+ div = Serenade.document.createElement("div");
2289
+ div.innerHTML = element;
2290
+ _ref = div.children;
2291
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2292
+ child = _ref[_i];
2293
+ aggregate.push(child);
2294
+ }
2295
+ } else {
2296
+ aggregate.push(element);
2297
+ }
2298
+ return aggregate;
2299
+ };
2300
+ return [].concat(val).reduce(reduction, []);
2301
+ };
2302
+
2303
+ compile = function(ast, model, controller) {
2304
+ return Compile[ast.type](ast, model, controller);
2305
+ };
2306
+
2307
+ compileAll = function(asts, model, controller) {
2308
+ var ast, _i, _len, _results;
2309
+ _results = [];
2310
+ for (_i = 0, _len = asts.length; _i < _len; _i++) {
2311
+ ast = asts[_i];
2312
+ _results.push(compile(ast, model, controller));
2313
+ }
2314
+ return _results;
2315
+ };
2316
+
2317
+ parser.lexer = {
2318
+ lex: function() {
2319
+ var tag, _ref;
2320
+ _ref = this.tokens[this.pos++] || [''], tag = _ref[0], this.yytext = _ref[1], this.yylineno = _ref[2];
2321
+ return tag;
2322
+ },
2323
+ setInput: function(tokens) {
2324
+ this.tokens = tokens;
2325
+ return this.pos = 0;
2326
+ },
2327
+ upcomingInput: function() {
2328
+ return "";
2329
+ }
2330
+ };
2331
+
2332
+ View = (function() {
2333
+
2334
+ function View(name, view) {
2335
+ this.name = name;
2336
+ this.view = view;
2337
+ }
2338
+
2339
+ View.prototype.parse = function() {
2340
+ if (typeof this.view === 'string') {
2341
+ try {
2342
+ return this.view = parser.parse(new Lexer().tokenize(this.view));
2343
+ } catch (e) {
2344
+ if (this.name) {
2345
+ e.message = "In view '" + this.name + "': " + e.message;
2346
+ }
2347
+ throw e;
2348
+ }
2349
+ } else {
2350
+ return this.view;
2351
+ }
2352
+ };
2335
2353
 
2336
- return View;
2354
+ View.prototype.render = function() {
2355
+ var args;
2356
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
2357
+ return this.node.apply(this, args).element;
2358
+ };
2337
2359
 
2338
- })();
2360
+ View.prototype.node = function(model, controller, parent, skipCallback) {
2361
+ var node;
2362
+ if (this.name) {
2363
+ controller || (controller = Serenade.controllerFor(this.name, model));
2364
+ }
2365
+ controller || (controller = {});
2366
+ if (typeof controller === "function") {
2367
+ controller = new controller(model, parent);
2368
+ }
2369
+ node = compile(this.parse(), model, controller);
2370
+ if (!skipCallback) {
2371
+ if (typeof controller.loaded === "function") {
2372
+ controller.loaded(node.element, model);
2373
+ }
2374
+ }
2375
+ return node;
2376
+ };
2339
2377
 
2340
- exports.View = View;
2378
+ return View;
2341
2379
 
2342
- }).call(this);
2380
+ })();
2343
2381
 
2382
+ Serenade = function(wrapped) {
2383
+ var key, object, value;
2384
+ object = Object.create(wrapped);
2385
+ for (key in wrapped) {
2386
+ value = wrapped[key];
2387
+ defineProperty(object, key, {
2388
+ value: value
2389
+ });
2390
+ }
2391
+ return object;
2344
2392
  };
2345
- return require['./serenade'].Serenade
2346
- }();
2347
2393
 
2348
- if(typeof define === 'function' && define.amd) {
2349
- define(function() { return Serenade });
2350
- } else { root.Serenade = Serenade }
2394
+ extend(Serenade, {
2395
+ VERSION: '0.4.0',
2396
+ _views: {},
2397
+ _controllers: {},
2398
+ document: typeof window !== "undefined" && window !== null ? window.document : void 0,
2399
+ format: format,
2400
+ defineProperty: defineProperty,
2401
+ defineEvent: defineEvent,
2402
+ asyncEvents: false,
2403
+ view: function(nameOrTemplate, template) {
2404
+ if (template) {
2405
+ return this._views[nameOrTemplate] = new View(nameOrTemplate, template);
2406
+ } else {
2407
+ return new View(void 0, nameOrTemplate);
2408
+ }
2409
+ },
2410
+ render: function(name, model, controller, parent, skipCallback) {
2411
+ return this._views[name].render(model, controller, parent, skipCallback);
2412
+ },
2413
+ controller: function(name, klass) {
2414
+ return this._controllers[name] = klass;
2415
+ },
2416
+ controllerFor: function(name) {
2417
+ return this._controllers[name];
2418
+ },
2419
+ clearIdentityMap: function() {
2420
+ return Cache._identityMap = {};
2421
+ },
2422
+ clearLocalStorage: function() {
2423
+ return Cache._storage.clear();
2424
+ },
2425
+ clearCache: function() {
2426
+ var key, value, _i, _len, _results;
2427
+ Serenade.clearIdentityMap();
2428
+ Serenade.clearLocalStorage();
2429
+ _results = [];
2430
+ for (key = _i = 0, _len = globalDependencies.length; _i < _len; key = ++_i) {
2431
+ value = globalDependencies[key];
2432
+ _results.push(delete globalDependencies[key]);
2433
+ }
2434
+ return _results;
2435
+ },
2436
+ unregisterAll: function() {
2437
+ Serenade._views = {};
2438
+ return Serenade._controllers = {};
2439
+ },
2440
+ Model: Model,
2441
+ Collection: Collection,
2442
+ Cache: Cache,
2443
+ View: View,
2444
+ Helpers: {}
2445
+ });
2446
+
2447
+ def(Serenade, "async", {
2448
+ get: function() {
2449
+ return settings.async;
2450
+ },
2451
+ set: function(value) {
2452
+ return settings.async = value;
2453
+ }
2454
+ });
2455
+ ;
2456
+ root.Serenade = Serenade;
2351
2457
  }(this));