serenade 0.4.0 → 0.4.1

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,6 +1,6 @@
1
1
  /**
2
- * Serenade.js JavaScript Framework v0.4.0
3
- * Revision: 5301262146
2
+ * Serenade.js JavaScript Framework v0.4.1
3
+ * Revision: ae7d321b18
4
4
  * http://github.com/elabs/serenade.js
5
5
  *
6
6
  * Copyright 2011, Jonas Nicklas, Elabs AB
@@ -11,9 +11,9 @@
11
11
  var parser = (function(){
12
12
  var parser = {trace: function trace() { },
13
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]],
14
+ symbols_: {"error":2,"Root":3,"ChildList":4,"ElementIdentifier":5,"AnyIdentifier":6,"#":7,".":8,"Element":9,"[":10,"]":11,"PropertyList":12,"WHITESPACE":13,"Text":14,"INDENT":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:".",10:"[",11:"]",13:"WHITESPACE",15:"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],[9,1],[9,3],[9,4],[9,3],[9,4],[17,1],[17,3],[14,1],[14,1],[4,1],[4,3],[20,1],[20,1],[20,1],[20,1],[20,1],[12,1],[12,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
17
  performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
18
18
 
19
19
  var $0 = $$.length - 1;
@@ -237,7 +237,7 @@ case 51:this.$ = (function () {}());
237
237
  break;
238
238
  }
239
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]}],
240
+ table: [{1:[2,1],3:1,4:2,5:9,6:12,7:[1,13],8:[1,14],9:4,14:11,17:8,18:15,19:[1,16],20:3,22:5,23:6,24:7,29:[1,10],30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19],38:[1,23]},{1:[3]},{1:[2,2],21:[1,24]},{1:[2,17],16:[2,17],21:[2,17]},{1:[2,19],10:[1,25],13:[1,26],15:[1,27],16:[2,19],21:[2,19]},{1:[2,20],15:[1,28],16:[2,20],21:[2,20],29:[1,30],36:29},{1:[2,21],15:[1,31],16:[2,21],21:[2,21]},{1:[2,22],13:[1,32],15:[1,33],16:[2,22],21:[2,22]},{1:[2,23],13:[1,34],16:[2,23],21:[2,23]},{1:[2,8],8:[1,35],10:[2,8],13:[2,8],15:[2,8],16:[2,8],21:[2,8]},{13:[1,36]},{1:[2,13],13:[2,13],16:[2,13],21:[2,13]},{1:[2,3],7:[1,37],8:[2,3],10:[2,3],13:[2,3],15:[2,3],16:[2,3],21:[2,3]},{6:38,30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19]},{6:39,30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19]},{1:[2,15],10:[2,15],13:[2,15],15:[2,15],16:[2,15],21:[2,15]},{1:[2,16],10:[2,16],13:[2,16],15:[2,16],16:[2,16],21:[2,16]},{1:[2,44],7:[2,44],8:[2,44],10:[2,44],11:[2,44],13:[2,44],15:[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],10:[2,45],11:[2,45],13:[2,45],15:[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],10:[2,46],11:[2,46],13:[2,46],15:[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],10:[2,47],11:[2,47],13:[2,47],15:[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],10:[2,48],11:[2,48],13:[2,48],15:[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],10:[2,49],11:[2,49],13:[2,49],15:[2,49],16:[2,49],21:[2,49],26:[2,49],27:[2,49],28:[2,49],29:[2,49]},{1:[2,51],6:40,10:[2,51],11:[2,51],13:[2,51],15:[2,51],16:[2,51],21:[2,51],27:[2,51],29:[2,51],30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19]},{5:9,6:12,7:[1,13],8:[1,14],9:4,14:11,17:8,18:15,19:[1,16],20:41,22:5,23:6,24:7,29:[1,10],30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19],38:[1,23]},{6:45,11:[1,42],12:43,25:44,30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19]},{14:46,18:15,19:[1,16],38:[1,23]},{4:47,5:9,6:12,7:[1,13],8:[1,14],9:4,14:11,17:8,18:15,19:[1,16],20:3,22:5,23:6,24:7,29:[1,10],30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19],38:[1,23]},{4:48,5:9,6:12,7:[1,13],8:[1,14],9:4,14:11,17:8,18:15,19:[1,16],20:3,22:5,23:6,24:7,29:[1,10],30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19],38:[1,23]},{1:[2,42],15:[2,42],16:[2,42],21:[2,42],29:[2,42]},{13:[1,49]},{4:50,5:9,6:12,7:[1,13],8:[1,14],9:4,14:11,17:8,18:15,19:[1,16],20:3,22:5,23:6,24:7,29:[1,10],30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19],38:[1,23]},{14:51,18:15,19:[1,16],38:[1,23]},{4:52,5:9,6:12,7:[1,13],8:[1,14],9:4,14:11,17:8,18:15,19:[1,16],20:3,22:5,23:6,24:7,29:[1,10],30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19],38:[1,23]},{14:53,18:15,19:[1,16],38:[1,23]},{6:54,30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19]},{30:[1,56],31:[1,57],32:[1,58],33:[1,59],34:[1,60],35:[1,55]},{6:61,30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19]},{1:[2,5],8:[2,5],10:[2,5],13:[2,5],15:[2,5],16:[2,5],21:[2,5]},{1:[2,6],8:[2,6],10:[2,6],13:[2,6],15:[2,6],16:[2,6],21:[2,6]},{1:[2,50],10:[2,50],11:[2,50],13:[2,50],15:[2,50],16:[2,50],21:[2,50],27:[2,50],29:[2,50]},{1:[2,18],16:[2,18],21:[2,18]},{1:[2,9],10:[2,9],13:[2,9],15:[2,9],16:[2,9],21:[2,9]},{11:[1,62],13:[1,63]},{11:[2,24],13:[2,24]},{26:[1,64],28:[1,65]},{1:[2,11],10:[2,11],13:[2,11],15:[2,11],16:[2,11],21:[2,11]},{16:[1,66],21:[1,24]},{16:[1,67],21:[1,24]},{37:[1,68]},{16:[1,69],21:[1,24]},{1:[2,38],13:[2,38],15:[2,38],16:[2,38],21:[2,38]},{16:[1,70],21:[1,24]},{1:[2,14],13:[2,14],16:[2,14],21:[2,14]},{1:[2,7],8:[2,7],10:[2,7],13:[2,7],15:[2,7],16:[2,7],21:[2,7]},{13:[1,71]},{13:[1,72]},{13:[1,73]},{13:[1,74]},{13:[1,75]},{1:[2,37],13:[2,37],15:[2,37],16:[2,37],21:[2,37]},{1:[2,4],8:[2,4],10:[2,4],13:[2,4],15:[2,4],16:[2,4],21:[2,4]},{1:[2,10],10:[2,10],13:[2,10],15:[2,10],16:[2,10],21:[2,10]},{6:45,25:76,30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19]},{6:77,18:78,19:[1,79],30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19],38:[1,23]},{6:45,25:80,30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19]},{1:[2,12],10:[2,12],13:[2,12],15:[2,12],16:[2,12],21:[2,12]},{1:[2,41],15:[2,41],16:[2,41],21:[2,41],29:[2,41]},{15:[1,81]},{1:[2,36],15:[2,36],16:[2,36],21:[2,36]},{1:[2,39],13:[2,39],15:[2,39],16:[2,39],21:[2,39]},{18:82,38:[1,23]},{19:[1,83]},{18:84,38:[1,23]},{18:85,38:[1,23]},{18:86,38:[1,23]},{11:[2,25],13:[2,25]},{11:[2,26],13:[2,26],27:[1,87]},{11:[2,27],13:[2,27],27:[1,88]},{11:[2,30],13:[2,30]},{11:[2,31],13:[2,31]},{4:89,5:9,6:12,7:[1,13],8:[1,14],9:4,14:11,17:8,18:15,19:[1,16],20:3,22:5,23:6,24:7,29:[1,10],30:[1,17],31:[1,18],32:[1,20],33:[1,21],34:[1,22],35:[1,19],38:[1,23]},{1:[2,40],15:[2,40],16:[2,40],21:[2,40],29:[2,40]},{1:[2,32],15:[2,32],16:[2,32],21:[2,32]},{1:[2,33],15:[2,33],16:[2,33],21:[2,33]},{1:[2,34],15:[2,34],16:[2,34],21:[2,34]},{1:[2,35],15:[2,35],16:[2,35],21:[2,35]},{11:[2,28],13:[2,28]},{11:[2,29],13:[2,29]},{16:[1,90],21:[1,24]},{1:[2,43],15:[2,43],16:[2,43],21:[2,43],29:[2,43]}],
241
241
  defaultActions: {},
242
242
  parseError: function parseError(str, hash) {
243
243
  throw new Error(str);
@@ -354,7 +354,7 @@ exports.main = function commonjsMain(args) {
354
354
  if (typeof module !== 'undefined' && require.main === module) {
355
355
  exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
356
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,
357
+ }var AssociationCollection, COMMENT, Cache, Collection, Compile, CompiledView, DynamicNode, Event, IDENTIFIER, KEYWORDS, LITERAL, Lexer, MULTI_DENT, Model, Node, Property, PropertyAccessor, PropertyDefinition, STRING, Serenade, View, WHITESPACE, assignUnlessEqual, capitalize, compile, def, defineEvent, defineOptions, defineProperty, extend, format, getValue, globalDependencies, idCounter, isArray, isArrayIndex, merge, normalize, pairToObject, safeDelete, safePush, serializeObject, settings, triggerGlobal,
358
358
  __hasProp = {}.hasOwnProperty,
359
359
  __slice = [].slice,
360
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; },
@@ -366,25 +366,54 @@ settings = {
366
366
 
367
367
  def = Object.defineProperty;
368
368
 
369
+ defineOptions = function(object, name) {
370
+ return def(object, name, {
371
+ get: function() {
372
+ var options;
373
+ if (!this.hasOwnProperty("_" + name)) {
374
+ options = name in Object.getPrototypeOf(this) ? Object.create(Object.getPrototypeOf(this)[name]) : {};
375
+ def(this, "_" + name, {
376
+ configurable: true,
377
+ writable: true,
378
+ value: options
379
+ });
380
+ }
381
+ return this["_" + name];
382
+ }
383
+ });
384
+ };
385
+
369
386
  extend = function(target, source, enumerable) {
370
- var key, value, _results;
387
+ var key, value;
371
388
  if (enumerable == null) {
372
389
  enumerable = true;
373
390
  }
374
- _results = [];
375
391
  for (key in source) {
376
392
  if (!__hasProp.call(source, key)) continue;
377
393
  value = source[key];
378
394
  if (enumerable) {
379
- _results.push(target[key] = value);
395
+ target[key] = value;
380
396
  } else {
381
- _results.push(def(target, key, {
397
+ def(target, key, {
382
398
  value: value,
383
399
  configurable: true
384
- }));
400
+ });
385
401
  }
386
402
  }
387
- return _results;
403
+ return target;
404
+ };
405
+
406
+ assignUnlessEqual = function(object, prop, value) {
407
+ if (object[prop] !== value) {
408
+ return object[prop] = value;
409
+ }
410
+ };
411
+
412
+ merge = function(target, source, enumerable) {
413
+ if (enumerable == null) {
414
+ enumerable = true;
415
+ }
416
+ return extend(extend({}, target, enumerable), source, enumerable);
388
417
  };
389
418
 
390
419
  format = function(model, key) {
@@ -460,11 +489,18 @@ Event = (function() {
460
489
  this.object = object;
461
490
  this.name = name;
462
491
  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
492
  }
467
493
 
494
+ def(Event.prototype, "async", {
495
+ get: function() {
496
+ if ("async" in this.options) {
497
+ return this.options.async;
498
+ } else {
499
+ return settings.async;
500
+ }
501
+ }
502
+ });
503
+
468
504
  Event.prototype.trigger = function() {
469
505
  var args, _base,
470
506
  _this = this;
@@ -483,7 +519,7 @@ Event = (function() {
483
519
  if (this.options.bind) {
484
520
  this.options.bind.call(this.object, fun);
485
521
  }
486
- return safePush(this.object, this.prop, fun);
522
+ return safePush(this.object._s, "listeners_" + this.name, fun);
487
523
  };
488
524
 
489
525
  Event.prototype.one = function(fun) {
@@ -499,7 +535,7 @@ Event = (function() {
499
535
  };
500
536
 
501
537
  Event.prototype.unbind = function(fun) {
502
- safeDelete(this.object, this.prop, fun);
538
+ safeDelete(this.object._s, "listeners_" + this.name, fun);
503
539
  if (this.options.unbind) {
504
540
  return this.options.unbind.call(this.object, fun);
505
541
  }
@@ -509,9 +545,9 @@ Event = (function() {
509
545
  var args, perform, _i, _len, _ref,
510
546
  _this = this;
511
547
  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);
548
+ if (_this.listeners) {
549
+ return _this.listeners.forEach(function(listener) {
550
+ return listener.apply(_this.object, args);
515
551
  });
516
552
  }
517
553
  };
@@ -529,22 +565,19 @@ Event = (function() {
529
565
 
530
566
  def(Event.prototype, "listeners", {
531
567
  get: function() {
532
- return this.object[this.prop];
568
+ return this.object._s["listeners_" + this.name];
533
569
  }
534
570
  });
535
571
 
536
572
  def(Event.prototype, "queue", {
537
573
  get: function() {
538
- if (!this.object.hasOwnProperty(this.queueName)) {
574
+ if (!this.object._s.hasOwnProperty("queue_" + this.name)) {
539
575
  this.queue = [];
540
576
  }
541
- return this.object[this.queueName];
577
+ return this.object._s["queue_" + this.name];
542
578
  },
543
579
  set: function(val) {
544
- return def(this.object, this.queueName, {
545
- value: val,
546
- configurable: true
547
- });
580
+ return this.object._s["queue_" + this.name] = val;
548
581
  }
549
582
  });
550
583
 
@@ -556,6 +589,9 @@ defineEvent = function(object, name, options) {
556
589
  if (options == null) {
557
590
  options = {};
558
591
  }
592
+ if (!("_s" in object)) {
593
+ defineOptions(object, "_s");
594
+ }
559
595
  return def(object, name, {
560
596
  configurable: true,
561
597
  get: function() {
@@ -703,13 +739,17 @@ Collection = (function() {
703
739
  }
704
740
  };
705
741
 
706
- Collection.prototype.first = function() {
707
- return this[0];
708
- };
742
+ def(Collection.prototype, "first", {
743
+ get: function() {
744
+ return this[0];
745
+ }
746
+ });
709
747
 
710
- Collection.prototype.last = function() {
711
- return this[this.length - 1];
712
- };
748
+ def(Collection.prototype, "last", {
749
+ get: function() {
750
+ return this[this.length - 1];
751
+ }
752
+ });
713
753
 
714
754
  Collection.prototype.toArray = function() {
715
755
  var array, index, val;
@@ -974,18 +1014,24 @@ PropertyDefinition = (function() {
974
1014
  this.addDependency(name);
975
1015
  }
976
1016
  }
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
1017
  }
988
1018
 
1019
+ def(PropertyDefinition.prototype, "eventOptions", {
1020
+ get: function() {
1021
+ var name;
1022
+ name = this.name;
1023
+ return {
1024
+ async: this.async != null ? this.async : settings.async,
1025
+ bind: function() {
1026
+ return this[name];
1027
+ },
1028
+ optimize: function(queue) {
1029
+ return queue[queue.length - 1];
1030
+ }
1031
+ };
1032
+ }
1033
+ });
1034
+
989
1035
  PropertyDefinition.prototype.addDependency = function(name) {
990
1036
  var subname, type, _ref, _ref1;
991
1037
  if (this.dependencies.indexOf(name) === -1) {
@@ -1021,18 +1067,22 @@ PropertyAccessor = (function() {
1021
1067
  this.definition = definition;
1022
1068
  this.object = object;
1023
1069
  this.name = this.definition.name;
1024
- this.valueName = "_s_" + this.name + "_val";
1070
+ this.valueName = "val_" + this.name;
1025
1071
  this.event = new Event(this.object, this.name + "_change", this.definition.eventOptions);
1026
1072
  }
1027
1073
 
1028
1074
  PropertyAccessor.prototype.set = function(value) {
1075
+ var val;
1029
1076
  if (typeof value === "function") {
1030
1077
  return this.definition.get = value;
1031
1078
  } else {
1079
+ if (this.definition.changed) {
1080
+ val = this.get();
1081
+ }
1032
1082
  if (this.definition.set) {
1033
1083
  this.definition.set.call(this.object, value);
1034
1084
  } else {
1035
- def(this.object, this.valueName, {
1085
+ def(this.object._s, this.valueName, {
1036
1086
  value: value,
1037
1087
  configurable: true
1038
1088
  });
@@ -1045,21 +1095,24 @@ PropertyAccessor = (function() {
1045
1095
  var listener, value,
1046
1096
  _this = this;
1047
1097
  this.registerGlobal();
1048
- if (this.definition.get) {
1098
+ if (this.definition.get && !(this.definition.cache && this.valueName in this.object._s)) {
1049
1099
  listener = function(name) {
1050
1100
  return _this.definition.addDependency(name);
1051
1101
  };
1052
1102
  if (!("dependsOn" in this.definition)) {
1053
- this.object._s_property_access.bind(listener);
1103
+ this.object._s.property_access.bind(listener);
1054
1104
  }
1055
1105
  value = this.definition.get.call(this.object);
1106
+ if (this.definition.cache) {
1107
+ this.object._s[this.valueName] = value;
1108
+ }
1056
1109
  if (!("dependsOn" in this.definition)) {
1057
- this.object._s_property_access.unbind(listener);
1110
+ this.object._s.property_access.unbind(listener);
1058
1111
  }
1059
1112
  } else {
1060
- value = this.object[this.valueName];
1113
+ value = this.object._s[this.valueName];
1061
1114
  }
1062
- this.object._s_property_access.trigger(this.name);
1115
+ this.object._s.property_access.trigger(this.name);
1063
1116
  return value;
1064
1117
  };
1065
1118
 
@@ -1073,11 +1126,8 @@ PropertyAccessor = (function() {
1073
1126
 
1074
1127
  PropertyAccessor.prototype.registerGlobal = function() {
1075
1128
  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
- });
1129
+ if (!this.object._s["glb_" + this.name]) {
1130
+ this.object._s["glb_" + this.name] = true;
1081
1131
  _ref = this.definition.globalDependencies;
1082
1132
  _results = [];
1083
1133
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -1096,26 +1146,36 @@ PropertyAccessor = (function() {
1096
1146
  };
1097
1147
 
1098
1148
  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);
1149
+ var changes, name, prop, value, _i, _len, _ref, _ref1;
1150
+ this.clearCache();
1151
+ if (this.hasChanged()) {
1152
+ value = this.get();
1153
+ changes = {};
1154
+ _ref = this.dependents;
1155
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1156
+ name = _ref[_i];
1157
+ if (name !== this.name) {
1158
+ changes[name] = this.object[name];
1159
+ }
1109
1160
  }
1161
+ this.event.trigger(value);
1162
+ for (name in changes) {
1163
+ if (!__hasProp.call(changes, name)) continue;
1164
+ value = changes[name];
1165
+ prop = this.object[name + "_property"];
1166
+ prop.clearCache();
1167
+ if (prop.hasChanged()) {
1168
+ prop.event.trigger(value);
1169
+ }
1170
+ }
1171
+ changes[this.name] = value;
1172
+ if ((_ref1 = this.object.changed) != null) {
1173
+ if (typeof _ref1.trigger === "function") {
1174
+ _ref1.trigger(changes);
1175
+ }
1176
+ }
1177
+ return triggerGlobal(this.object, Object.keys(changes));
1110
1178
  }
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
1179
  };
1120
1180
 
1121
1181
  PropertyAccessor.prototype.bind = function(fun) {
@@ -1137,7 +1197,7 @@ PropertyAccessor = (function() {
1137
1197
  deps = [];
1138
1198
  findDependencies = function(name) {
1139
1199
  var property, _i, _len, _ref, _ref1, _results;
1140
- _ref = _this.object._s_properties;
1200
+ _ref = _this.object._s.properties;
1141
1201
  _results = [];
1142
1202
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1143
1203
  property = _ref[_i];
@@ -1161,6 +1221,27 @@ PropertyAccessor = (function() {
1161
1221
  }
1162
1222
  });
1163
1223
 
1224
+ PropertyAccessor.prototype.clearCache = function() {
1225
+ if (this.definition.cache && this.definition.get) {
1226
+ return delete this.object._s[this.valueName];
1227
+ }
1228
+ };
1229
+
1230
+ PropertyAccessor.prototype.hasChanged = function() {
1231
+ var changed, oldValueName, value;
1232
+ if (this.definition.changed === false) {
1233
+ return false;
1234
+ } else if (this.definition.changed) {
1235
+ value = this.get();
1236
+ oldValueName = "old_val_" + this.name;
1237
+ changed = this.object._s.hasOwnProperty(oldValueName) ? this.definition.changed.call(this.object, this.object._s[oldValueName], value) : true;
1238
+ this.object._s[oldValueName] = value;
1239
+ return changed;
1240
+ } else {
1241
+ return true;
1242
+ }
1243
+ };
1244
+
1164
1245
  return PropertyAccessor;
1165
1246
 
1166
1247
  })();
@@ -1171,8 +1252,11 @@ defineProperty = function(object, name, options) {
1171
1252
  options = {};
1172
1253
  }
1173
1254
  definition = new PropertyDefinition(name, options);
1174
- safePush(object, "_s_properties", definition);
1175
- defineEvent(object, "_s_property_access");
1255
+ if (!("_s" in object)) {
1256
+ defineOptions(object, "_s");
1257
+ }
1258
+ safePush(object._s, "properties", definition);
1259
+ defineEvent(object._s, "property_access");
1176
1260
  def(object, name, {
1177
1261
  get: function() {
1178
1262
  return this[name + "_property"].get();
@@ -1209,30 +1293,6 @@ idCounter = 1;
1209
1293
 
1210
1294
  Model = (function() {
1211
1295
 
1212
- defineEvent(Model.prototype, "saved");
1213
-
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
- });
1225
-
1226
- Model.belongsTo = function() {
1227
- var _ref;
1228
- return (_ref = this.prototype).belongsTo.apply(_ref, arguments);
1229
- };
1230
-
1231
- Model.hasMany = function() {
1232
- var _ref;
1233
- return (_ref = this.prototype).hasMany.apply(_ref, arguments);
1234
- };
1235
-
1236
1296
  Model.identityMap = true;
1237
1297
 
1238
1298
  Model.find = function(id) {
@@ -1278,15 +1338,8 @@ Model = (function() {
1278
1338
  return _results;
1279
1339
  };
1280
1340
 
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));
1288
- }
1289
- return _results;
1341
+ Model.event = function(name, options) {
1342
+ return defineEvent(this.prototype, name, options);
1290
1343
  };
1291
1344
 
1292
1345
  Model.delegate = function() {
@@ -1295,7 +1348,7 @@ Model = (function() {
1295
1348
  names = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), options = arguments[_i++];
1296
1349
  to = options.to;
1297
1350
  return names.forEach(function(name) {
1298
- var propName;
1351
+ var propName, propOptions;
1299
1352
  propName = name;
1300
1353
  if (options.prefix === true) {
1301
1354
  propName = to + capitalize(name);
@@ -1307,8 +1360,8 @@ Model = (function() {
1307
1360
  } else if (options.suffix) {
1308
1361
  propName = propName + options.suffix;
1309
1362
  }
1310
- return _this.property(propName, {
1311
- dependsOn: "" + to + "." + name,
1363
+ propOptions = merge(options, {
1364
+ dependsOn: options.dependsOn || ("" + to + "." + name),
1312
1365
  get: function() {
1313
1366
  var _ref;
1314
1367
  return (_ref = this[to]) != null ? _ref[name] : void 0;
@@ -1318,31 +1371,33 @@ Model = (function() {
1318
1371
  return (_ref = this[to]) != null ? _ref[name] = value : void 0;
1319
1372
  }
1320
1373
  });
1374
+ return _this.property(propName, propOptions);
1321
1375
  });
1322
1376
  };
1323
1377
 
1324
1378
  Model.collection = function(name, options) {
1379
+ var propOptions;
1325
1380
  if (options == null) {
1326
1381
  options = {};
1327
1382
  }
1328
- extend(options, {
1383
+ propOptions = merge(options, {
1329
1384
  get: function() {
1330
1385
  var valueName,
1331
1386
  _this = this;
1332
- valueName = "_s_" + name + "_val";
1333
- if (!this[valueName]) {
1334
- this[valueName] = new Collection([]);
1335
- this[valueName].change.bind(function() {
1387
+ valueName = "val_" + name;
1388
+ if (!this._s[valueName]) {
1389
+ this._s[valueName] = new Collection([]);
1390
+ this._s[valueName].change.bind(function() {
1336
1391
  return _this[name + "_property"].trigger();
1337
1392
  });
1338
1393
  }
1339
- return this[valueName];
1394
+ return this._s[valueName];
1340
1395
  },
1341
1396
  set: function(value) {
1342
1397
  return this[name].update(value);
1343
1398
  }
1344
1399
  });
1345
- this.property(name, options);
1400
+ this.property(name, propOptions);
1346
1401
  return this.property(name + 'Count', {
1347
1402
  get: function() {
1348
1403
  return this[name].length;
@@ -1351,28 +1406,29 @@ Model = (function() {
1351
1406
  });
1352
1407
  };
1353
1408
 
1354
- Model.belongsTo = function(name, attributes) {
1355
- if (attributes == null) {
1356
- attributes = {};
1409
+ Model.belongsTo = function(name, options) {
1410
+ var propOptions;
1411
+ if (options == null) {
1412
+ options = {};
1357
1413
  }
1358
- extend(attributes, {
1414
+ propOptions = merge(options, {
1359
1415
  set: function(model) {
1360
1416
  var previous, valueName;
1361
- valueName = "_s_" + name + "_val";
1362
- if (model && model.constructor === Object && attributes.as) {
1363
- model = new (attributes.as())(model);
1417
+ valueName = "val_" + name;
1418
+ if (model && model.constructor === Object && options.as) {
1419
+ model = new (options.as())(model);
1364
1420
  }
1365
- previous = this[valueName];
1366
- this[valueName] = model;
1367
- if (attributes.inverseOf && !model[attributes.inverseOf].includes(this)) {
1421
+ previous = this._s[valueName];
1422
+ this._s[valueName] = model;
1423
+ if (options.inverseOf && !model[options.inverseOf].includes(this)) {
1368
1424
  if (previous) {
1369
- previous[attributes.inverseOf]["delete"](this);
1425
+ previous[options.inverseOf]["delete"](this);
1370
1426
  }
1371
- return model[attributes.inverseOf].push(this);
1427
+ return model[options.inverseOf].push(this);
1372
1428
  }
1373
1429
  }
1374
1430
  });
1375
- this.property(name, attributes);
1431
+ this.property(name, propOptions);
1376
1432
  return this.property(name + 'Id', {
1377
1433
  get: function() {
1378
1434
  var _ref;
@@ -1380,36 +1436,37 @@ Model = (function() {
1380
1436
  },
1381
1437
  set: function(id) {
1382
1438
  if (id != null) {
1383
- return this[name] = attributes.as().find(id);
1439
+ return this[name] = options.as().find(id);
1384
1440
  }
1385
1441
  },
1386
1442
  dependsOn: name,
1387
- serialize: attributes.serializeId
1443
+ serialize: options.serializeId
1388
1444
  });
1389
1445
  };
1390
1446
 
1391
- Model.hasMany = function(name, attributes) {
1392
- if (attributes == null) {
1393
- attributes = {};
1447
+ Model.hasMany = function(name, options) {
1448
+ var propOptions;
1449
+ if (options == null) {
1450
+ options = {};
1394
1451
  }
1395
- extend(attributes, {
1452
+ propOptions = merge(options, {
1396
1453
  get: function() {
1397
1454
  var valueName,
1398
1455
  _this = this;
1399
- valueName = "_s_" + name + "_val";
1400
- if (!this[valueName]) {
1401
- this[valueName] = new AssociationCollection(this, attributes, []);
1402
- this[valueName].change.bind(function() {
1456
+ valueName = "val_" + name;
1457
+ if (!this._s[valueName]) {
1458
+ this._s[valueName] = new AssociationCollection(this, options, []);
1459
+ this._s[valueName].change.bind(function() {
1403
1460
  return _this[name + "_property"].trigger();
1404
1461
  });
1405
1462
  }
1406
- return this[valueName];
1463
+ return this._s[valueName];
1407
1464
  },
1408
1465
  set: function(value) {
1409
1466
  return this[name].update(value);
1410
1467
  }
1411
1468
  });
1412
- this.property(name, attributes);
1469
+ this.property(name, propOptions);
1413
1470
  this.property(name + 'Ids', {
1414
1471
  get: function() {
1415
1472
  return new Collection(this[name]).map(function(item) {
@@ -1423,14 +1480,14 @@ Model = (function() {
1423
1480
  _results = [];
1424
1481
  for (_i = 0, _len = ids.length; _i < _len; _i++) {
1425
1482
  id = ids[_i];
1426
- _results.push(attributes.as().find(id));
1483
+ _results.push(options.as().find(id));
1427
1484
  }
1428
1485
  return _results;
1429
1486
  })();
1430
1487
  return this[name].update(objects);
1431
1488
  },
1432
1489
  dependsOn: name,
1433
- serialize: attributes.serializeIds
1490
+ serialize: options.serializeIds
1434
1491
  });
1435
1492
  return this.property(name + 'Count', {
1436
1493
  get: function() {
@@ -1441,10 +1498,11 @@ Model = (function() {
1441
1498
  };
1442
1499
 
1443
1500
  Model.selection = function(name, options) {
1501
+ var propOptions;
1444
1502
  if (options == null) {
1445
1503
  options = {};
1446
1504
  }
1447
- this.property(name, {
1505
+ propOptions = merge(options, {
1448
1506
  get: function() {
1449
1507
  return this[options.from].filter(function(item) {
1450
1508
  return item[options.filter];
@@ -1452,6 +1510,7 @@ Model = (function() {
1452
1510
  },
1453
1511
  dependsOn: "" + options.from + ":" + options.filter
1454
1512
  });
1513
+ this.property(name, propOptions);
1455
1514
  return this.property(name + 'Count', {
1456
1515
  get: function() {
1457
1516
  return this[name].length;
@@ -1473,13 +1532,24 @@ Model = (function() {
1473
1532
  set: function(val) {
1474
1533
  Cache.unset(this.constructor, this.id);
1475
1534
  Cache.set(this.constructor, val, this);
1476
- return def(this, "_s_id_val", {
1477
- value: val,
1478
- configurable: true
1479
- });
1535
+ return this._s.val_id = val;
1480
1536
  },
1481
1537
  get: function() {
1482
- return this._s_id_val;
1538
+ return this._s.val_id;
1539
+ }
1540
+ });
1541
+
1542
+ Model.event("saved");
1543
+
1544
+ Model.event("changed", {
1545
+ optimize: function(queue) {
1546
+ var item, result, _i, _len;
1547
+ result = {};
1548
+ for (_i = 0, _len = queue.length; _i < _len; _i++) {
1549
+ item = queue[_i];
1550
+ extend(result, item[0]);
1551
+ }
1552
+ return [result];
1483
1553
  }
1484
1554
  });
1485
1555
 
@@ -1518,7 +1588,7 @@ Model = (function() {
1518
1588
  Model.prototype.toJSON = function() {
1519
1589
  var key, property, serialized, value, _i, _len, _ref, _ref1;
1520
1590
  serialized = {};
1521
- _ref = this._s_properties;
1591
+ _ref = this._s.properties;
1522
1592
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1523
1593
  property = _ref[_i];
1524
1594
  if (typeof property.serialize === 'string') {
@@ -1748,9 +1818,12 @@ Node = (function() {
1748
1818
  return (_ref = this.element.parentNode) != null ? _ref.removeChild(this.element) : void 0;
1749
1819
  };
1750
1820
 
1751
- Node.prototype.lastElement = function() {
1752
- return this.element;
1753
- };
1821
+ def(Node.prototype, "lastElement", {
1822
+ configurable: true,
1823
+ get: function() {
1824
+ return this.element;
1825
+ }
1826
+ });
1754
1827
 
1755
1828
  Node.prototype.nodes = function() {
1756
1829
  return this.children;
@@ -1795,8 +1868,9 @@ Node = (function() {
1795
1868
  if (this.boundClasses.length) {
1796
1869
  classes = classes.concat(this.boundClasses.toArray());
1797
1870
  }
1871
+ classes.sort();
1798
1872
  if (classes.length) {
1799
- return this.element.className = classes.join(' ');
1873
+ return assignUnlessEqual(this.element, "className", classes.join(' '));
1800
1874
  } else {
1801
1875
  return this.element.removeAttribute("class");
1802
1876
  }
@@ -1839,7 +1913,7 @@ DynamicNode = (function(_super) {
1839
1913
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1840
1914
  node = _ref[_i];
1841
1915
  node.insertAfter(last);
1842
- _results.push(last = node.lastElement());
1916
+ _results.push(last = node.lastElement);
1843
1917
  }
1844
1918
  return _results;
1845
1919
  }
@@ -1876,11 +1950,11 @@ DynamicNode = (function(_super) {
1876
1950
 
1877
1951
  DynamicNode.prototype.insertNodeSet = function(index, nodes) {
1878
1952
  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;
1953
+ last = ((_ref = this.nodeSets[index - 1]) != null ? (_ref1 = _ref.last) != null ? _ref1.lastElement : void 0 : void 0) || this.anchor;
1880
1954
  for (_i = 0, _len = nodes.length; _i < _len; _i++) {
1881
1955
  node = nodes[_i];
1882
1956
  node.insertAfter(last);
1883
- last = node.lastElement();
1957
+ last = node.lastElement;
1884
1958
  }
1885
1959
  return this.nodeSets.insertAt(index, new Collection(nodes));
1886
1960
  };
@@ -1911,10 +1985,13 @@ DynamicNode = (function(_super) {
1911
1985
  return this.rebuild();
1912
1986
  };
1913
1987
 
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
- };
1988
+ def(DynamicNode.prototype, "lastElement", {
1989
+ configurable: true,
1990
+ get: function() {
1991
+ var _ref, _ref1;
1992
+ return ((_ref = this.nodeSets.last) != null ? (_ref1 = _ref.last) != null ? _ref1.lastElement : void 0 : void 0) || this.anchor;
1993
+ }
1994
+ });
1918
1995
 
1919
1996
  return DynamicNode;
1920
1997
 
@@ -1934,7 +2011,7 @@ Property = {
1934
2011
  style: function(ast, node, model, controller) {
1935
2012
  var update;
1936
2013
  update = function() {
1937
- return node.element.style[ast.name] = getValue(ast, model);
2014
+ return assignUnlessEqual(node.element.style, ast.name, getValue(ast, model));
1938
2015
  };
1939
2016
  update();
1940
2017
  if (ast.bound) {
@@ -1953,7 +2030,9 @@ Property = {
1953
2030
  var update;
1954
2031
  update = function() {
1955
2032
  if (model[ast.value]) {
1956
- node.boundClasses.push(ast.name);
2033
+ if (!node.boundClasses.includes(ast.name)) {
2034
+ node.boundClasses.push(ast.name);
2035
+ }
1957
2036
  } else {
1958
2037
  node.boundClasses["delete"](ast.name);
1959
2038
  }
@@ -1987,9 +2066,7 @@ Property = {
1987
2066
  if (val === void 0) {
1988
2067
  val = "";
1989
2068
  }
1990
- if (element.value !== val) {
1991
- return element.value = val;
1992
- }
2069
+ return assignUnlessEqual(element, "value", val);
1993
2070
  }
1994
2071
  };
1995
2072
  modelUpdated();
@@ -2018,19 +2095,23 @@ Property = {
2018
2095
  var value;
2019
2096
  value = getValue(ast, model);
2020
2097
  if (ast.name === 'value') {
2021
- return element.value = value || '';
2098
+ return assignUnlessEqual(element, "value", value || '');
2022
2099
  } else if (node.ast.name === 'input' && ast.name === 'checked') {
2023
- return element.checked = !!value;
2100
+ return assignUnlessEqual(element, "checked", !!value);
2024
2101
  } else if (ast.name === 'class') {
2025
2102
  node.attributeClasses = value;
2026
2103
  return node.updateClass();
2027
2104
  } else if (value === void 0) {
2028
- return element.removeAttribute(ast.name);
2105
+ if (element.hasAttribute(ast.name)) {
2106
+ return element.removeAttribute(ast.name);
2107
+ }
2029
2108
  } else {
2030
2109
  if (value === 0) {
2031
2110
  value = "0";
2032
2111
  }
2033
- return element.setAttribute(ast.name, value);
2112
+ if (element.getAttribute(ast.name) !== value) {
2113
+ return element.setAttribute(ast.name, value);
2114
+ }
2034
2115
  }
2035
2116
  };
2036
2117
  if (ast.bound) {
@@ -2052,7 +2133,7 @@ Property = {
2052
2133
 
2053
2134
  Compile = {
2054
2135
  element: function(ast, model, controller) {
2055
- var action, child, childNode, element, node, property, _i, _j, _len, _len1, _ref, _ref1, _ref2;
2136
+ var action, child, element, node, property, _i, _j, _len, _len1, _ref, _ref1, _ref2;
2056
2137
  element = Serenade.document.createElement(ast.name);
2057
2138
  node = new Node(ast, element);
2058
2139
  if (ast.id) {
@@ -2061,12 +2142,11 @@ Compile = {
2061
2142
  if ((_ref = ast.classes) != null ? _ref.length : void 0) {
2062
2143
  element.setAttribute('class', ast.classes.join(' '));
2063
2144
  }
2064
- _ref1 = ast.children;
2145
+ node.children = compile(ast.children, model, controller);
2146
+ _ref1 = node.children;
2065
2147
  for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
2066
2148
  child = _ref1[_i];
2067
- childNode = compile(child, model, controller);
2068
- childNode.append(element);
2069
- node.children.push(childNode);
2149
+ child.append(element);
2070
2150
  }
2071
2151
  _ref2 = ast.properties;
2072
2152
  for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
@@ -2082,19 +2162,21 @@ Compile = {
2082
2162
  return node;
2083
2163
  },
2084
2164
  view: function(ast, model, parent) {
2085
- var controller, skipCallback;
2165
+ var controller, dynamic, skipCallback;
2086
2166
  controller = Serenade.controllerFor(ast.argument);
2087
2167
  if (!controller) {
2088
2168
  skipCallback = true;
2089
2169
  controller = parent;
2090
2170
  }
2091
- return Serenade._views[ast.argument].node(model, controller, parent, skipCallback);
2171
+ dynamic = new DynamicNode(ast);
2172
+ dynamic.replace([Serenade._views[ast.argument].nodes(model, controller, parent, skipCallback)]);
2173
+ return dynamic;
2092
2174
  },
2093
2175
  helper: function(ast, model, controller) {
2094
2176
  var argument, context, dynamic, helperFunction, render, update, _i, _len, _ref;
2095
2177
  dynamic = new DynamicNode(ast);
2096
2178
  render = function(model, controller) {
2097
- var child, fragment, node, _i, _len, _ref;
2179
+ var child, children, fragment, _i, _len;
2098
2180
  if (model == null) {
2099
2181
  model = model;
2100
2182
  }
@@ -2102,11 +2184,10 @@ Compile = {
2102
2184
  controller = controller;
2103
2185
  }
2104
2186
  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);
2187
+ children = compile(ast.children, model, controller);
2188
+ for (_i = 0, _len = children.length; _i < _len; _i++) {
2189
+ child = children[_i];
2190
+ child.append(fragment);
2110
2191
  }
2111
2192
  return fragment;
2112
2193
  };
@@ -2163,7 +2244,7 @@ Compile = {
2163
2244
  node = new Node(ast, textNode);
2164
2245
  if (ast.bound) {
2165
2246
  node.bindEvent(model["" + ast.value + "_property"], function() {
2166
- return textNode.nodeValue = getText();
2247
+ return assignUnlessEqual(textNode, "nodeValue", getText());
2167
2248
  });
2168
2249
  }
2169
2250
  return node;
@@ -2172,7 +2253,7 @@ Compile = {
2172
2253
  var collection, compileItem, dynamic, update,
2173
2254
  _this = this;
2174
2255
  compileItem = function(item) {
2175
- return compileAll(ast.children, item, controller);
2256
+ return compile(ast.children, item, controller);
2176
2257
  };
2177
2258
  update = function(dynamic, collection) {
2178
2259
  var item;
@@ -2226,7 +2307,7 @@ Compile = {
2226
2307
  "in": function(ast, model, controller) {
2227
2308
  return this.bound(ast, model, controller, function(dynamic, value) {
2228
2309
  if (value) {
2229
- return dynamic.replace([compileAll(ast.children, value, controller)]);
2310
+ return dynamic.replace([compile(ast.children, value, controller)]);
2230
2311
  } else {
2231
2312
  return dynamic.clear();
2232
2313
  }
@@ -2235,9 +2316,9 @@ Compile = {
2235
2316
  "if": function(ast, model, controller) {
2236
2317
  return this.bound(ast, model, controller, function(dynamic, value) {
2237
2318
  if (value) {
2238
- return dynamic.replace([compileAll(ast.children, model, controller)]);
2319
+ return dynamic.replace([compile(ast.children, model, controller)]);
2239
2320
  } else if (ast["else"]) {
2240
- return dynamic.replace([compileAll(ast["else"].children, model, controller)]);
2321
+ return dynamic.replace([compile(ast["else"].children, model, controller)]);
2241
2322
  } else {
2242
2323
  return dynamic.clear();
2243
2324
  }
@@ -2245,31 +2326,26 @@ Compile = {
2245
2326
  },
2246
2327
  unless: function(ast, model, controller) {
2247
2328
  return this.bound(ast, model, controller, function(dynamic, value) {
2248
- var child, nodes;
2329
+ var nodes;
2249
2330
  if (value) {
2250
2331
  return dynamic.clear();
2251
2332
  } 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
- })();
2333
+ nodes = compile(ast.children, model, controller);
2262
2334
  return dynamic.replace([nodes]);
2263
2335
  }
2264
2336
  });
2265
2337
  },
2266
2338
  bound: function(ast, model, controller, callback) {
2267
- var dynamic, update;
2339
+ var dynamic, lastValue, update;
2268
2340
  dynamic = new DynamicNode(ast);
2341
+ lastValue = {};
2269
2342
  update = function() {
2270
2343
  var value;
2271
2344
  value = model[ast.argument];
2272
- return callback(dynamic, value);
2345
+ if (value !== lastValue) {
2346
+ callback(dynamic, value);
2347
+ }
2348
+ return lastValue = value;
2273
2349
  };
2274
2350
  update();
2275
2351
  dynamic.bindEvent(model["" + ast.argument + "_property"], update);
@@ -2283,7 +2359,7 @@ normalize = function(val) {
2283
2359
  return [];
2284
2360
  }
2285
2361
  reduction = function(aggregate, element) {
2286
- var child, div, _i, _len, _ref;
2362
+ var child, div, _i, _j, _len, _len1, _ref, _ref1;
2287
2363
  if (typeof element === "string") {
2288
2364
  div = Serenade.document.createElement("div");
2289
2365
  div.innerHTML = element;
@@ -2292,6 +2368,12 @@ normalize = function(val) {
2292
2368
  child = _ref[_i];
2293
2369
  aggregate.push(child);
2294
2370
  }
2371
+ } else if (element.nodeName === "#document-fragment") {
2372
+ _ref1 = element.childNodes;
2373
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
2374
+ child = _ref1[_j];
2375
+ aggregate.push(child);
2376
+ }
2295
2377
  } else {
2296
2378
  aggregate.push(element);
2297
2379
  }
@@ -2300,16 +2382,12 @@ normalize = function(val) {
2300
2382
  return [].concat(val).reduce(reduction, []);
2301
2383
  };
2302
2384
 
2303
- compile = function(ast, model, controller) {
2304
- return Compile[ast.type](ast, model, controller);
2305
- };
2306
-
2307
- compileAll = function(asts, model, controller) {
2385
+ compile = function(asts, model, controller) {
2308
2386
  var ast, _i, _len, _results;
2309
2387
  _results = [];
2310
2388
  for (_i = 0, _len = asts.length; _i < _len; _i++) {
2311
2389
  ast = asts[_i];
2312
- _results.push(compile(ast, model, controller));
2390
+ _results.push(Compile[ast.type](ast, model, controller));
2313
2391
  }
2314
2392
  return _results;
2315
2393
  };
@@ -2329,6 +2407,41 @@ parser.lexer = {
2329
2407
  }
2330
2408
  };
2331
2409
 
2410
+ CompiledView = (function() {
2411
+
2412
+ function CompiledView(nodes) {
2413
+ this.nodes = nodes;
2414
+ }
2415
+
2416
+ CompiledView.prototype.remove = function() {
2417
+ var node, _i, _len, _ref, _results;
2418
+ _ref = this.nodes;
2419
+ _results = [];
2420
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2421
+ node = _ref[_i];
2422
+ _results.push(node.remove());
2423
+ }
2424
+ return _results;
2425
+ };
2426
+
2427
+ def(CompiledView.prototype, "fragment", {
2428
+ enumerable: true,
2429
+ get: function() {
2430
+ var fragment, node, _i, _len, _ref;
2431
+ fragment = Serenade.document.createDocumentFragment();
2432
+ _ref = this.nodes;
2433
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2434
+ node = _ref[_i];
2435
+ node.append(fragment);
2436
+ }
2437
+ return fragment;
2438
+ }
2439
+ });
2440
+
2441
+ return CompiledView;
2442
+
2443
+ })();
2444
+
2332
2445
  View = (function() {
2333
2446
 
2334
2447
  function View(name, view) {
@@ -2354,11 +2467,11 @@ View = (function() {
2354
2467
  View.prototype.render = function() {
2355
2468
  var args;
2356
2469
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
2357
- return this.node.apply(this, args).element;
2470
+ return this.compile.apply(this, args).fragment;
2358
2471
  };
2359
2472
 
2360
- View.prototype.node = function(model, controller, parent, skipCallback) {
2361
- var node;
2473
+ View.prototype.nodes = function(model, controller, parent, skipCallback) {
2474
+ var nodes;
2362
2475
  if (this.name) {
2363
2476
  controller || (controller = Serenade.controllerFor(this.name, model));
2364
2477
  }
@@ -2366,13 +2479,21 @@ View = (function() {
2366
2479
  if (typeof controller === "function") {
2367
2480
  controller = new controller(model, parent);
2368
2481
  }
2369
- node = compile(this.parse(), model, controller);
2482
+ nodes = compile(this.parse(), model, controller);
2370
2483
  if (!skipCallback) {
2371
2484
  if (typeof controller.loaded === "function") {
2372
- controller.loaded(node.element, model);
2485
+ controller.loaded.apply(controller, __slice.call(nodes.map(function(node) {
2486
+ return node.element;
2487
+ })).concat([model]));
2373
2488
  }
2374
2489
  }
2375
- return node;
2490
+ return nodes;
2491
+ };
2492
+
2493
+ View.prototype.compile = function() {
2494
+ var args;
2495
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
2496
+ return new CompiledView(this.nodes.apply(this, args));
2376
2497
  };
2377
2498
 
2378
2499
  return View;
@@ -2392,7 +2513,7 @@ Serenade = function(wrapped) {
2392
2513
  };
2393
2514
 
2394
2515
  extend(Serenade, {
2395
- VERSION: '0.4.0',
2516
+ VERSION: '0.4.1',
2396
2517
  _views: {},
2397
2518
  _controllers: {},
2398
2519
  document: typeof window !== "undefined" && window !== null ? window.document : void 0,
@@ -2419,13 +2540,9 @@ extend(Serenade, {
2419
2540
  clearIdentityMap: function() {
2420
2541
  return Cache._identityMap = {};
2421
2542
  },
2422
- clearLocalStorage: function() {
2423
- return Cache._storage.clear();
2424
- },
2425
2543
  clearCache: function() {
2426
2544
  var key, value, _i, _len, _results;
2427
2545
  Serenade.clearIdentityMap();
2428
- Serenade.clearLocalStorage();
2429
2546
  _results = [];
2430
2547
  for (key = _i = 0, _len = globalDependencies.length; _i < _len; key = ++_i) {
2431
2548
  value = globalDependencies[key];
@@ -1,4 +1,4 @@
1
1
  module Serenade
2
2
  # Serenade.js version this gem is bundled with.
3
- VERSION = "0.4.0"
3
+ VERSION = "0.4.1"
4
4
  end
@@ -6,7 +6,7 @@ describe Serenade do
6
6
  describe Serenade::Renderer do
7
7
  describe "#parse" do
8
8
  it "returns a parsed Sereande template" do
9
- result = Serenade::Renderer.new("foo", 'h1 "Hello world"').parse
9
+ result = Serenade::Renderer.new("foo", 'h1 "Hello world"').parse[0]
10
10
  result["name"].should eq "h1"
11
11
  result["children"][0]["type"].should eq "text"
12
12
  result["children"][0]["value"].should eq "Hello world"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serenade
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,88 +10,88 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-15 00:00:00.000000000 Z
13
+ date: 2013-02-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: execjs
17
- prerelease: false
18
17
  requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
19
  requirements:
20
20
  - - ! '>='
21
21
  - !ruby/object:Gem::Version
22
22
  version: 0.3.0
23
- none: false
24
23
  type: :runtime
24
+ prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
26
27
  requirements:
27
28
  - - ! '>='
28
29
  - !ruby/object:Gem::Version
29
30
  version: 0.3.0
30
- none: false
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: multi_json
33
- prerelease: false
34
33
  requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
35
  requirements:
36
36
  - - ! '>='
37
37
  - !ruby/object:Gem::Version
38
38
  version: '0'
39
- none: false
40
39
  type: :runtime
40
+ prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
42
43
  requirements:
43
44
  - - ! '>='
44
45
  - !ruby/object:Gem::Version
45
46
  version: '0'
46
- none: false
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- prerelease: false
50
49
  requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
51
  requirements:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.0'
55
- none: false
56
55
  type: :development
56
+ prerelease: false
57
57
  version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
58
59
  requirements:
59
60
  - - ~>
60
61
  - !ruby/object:Gem::Version
61
62
  version: '2.0'
62
- none: false
63
63
  - !ruby/object:Gem::Dependency
64
64
  name: sprockets
65
- prerelease: false
66
65
  requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
67
  requirements:
68
68
  - - ~>
69
69
  - !ruby/object:Gem::Version
70
70
  version: '2.0'
71
- none: false
72
71
  type: :development
72
+ prerelease: false
73
73
  version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
74
75
  requirements:
75
76
  - - ~>
76
77
  - !ruby/object:Gem::Version
77
78
  version: '2.0'
78
- none: false
79
79
  - !ruby/object:Gem::Dependency
80
80
  name: rails
81
- prerelease: false
82
81
  requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
83
  requirements:
84
84
  - - ~>
85
85
  - !ruby/object:Gem::Version
86
86
  version: '3.1'
87
- none: false
88
87
  type: :development
88
+ prerelease: false
89
89
  version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
90
91
  requirements:
91
92
  - - ~>
92
93
  - !ruby/object:Gem::Version
93
94
  version: '3.1'
94
- none: false
95
95
  description: ! '- Use serenade.js with the Rails asset pipeline.
96
96
 
97
97
  - Use serenade.js with any sprockets application (middlemanapp, sinatra).
@@ -129,20 +129,20 @@ rdoc_options: []
129
129
  require_paths:
130
130
  - lib
131
131
  required_ruby_version: !ruby/object:Gem::Requirement
132
+ none: false
132
133
  requirements:
133
134
  - - ! '>='
134
135
  - !ruby/object:Gem::Version
135
136
  version: '0'
136
- none: false
137
137
  required_rubygems_version: !ruby/object:Gem::Requirement
138
+ none: false
138
139
  requirements:
139
140
  - - ! '>='
140
141
  - !ruby/object:Gem::Version
141
142
  version: '0'
142
- none: false
143
143
  requirements: []
144
144
  rubyforge_project:
145
- rubygems_version: 1.8.24
145
+ rubygems_version: 1.8.25
146
146
  signing_key:
147
147
  specification_version: 3
148
148
  summary: Serenade.js for Ruby, Rails, and Sprockets