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.
- data/lib/assets/javascripts/serenade.js +340 -223
- data/lib/serenade/version.rb +1 -1
- data/spec/serenade_spec.rb +1 -1
- metadata +20 -20
@@ -1,6 +1,6 @@
|
|
1
1
|
/**
|
2
|
-
* Serenade.js JavaScript Framework v0.4.
|
3
|
-
* Revision:
|
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,"
|
15
|
-
terminals_: {2:"error",7:"#",8:".",
|
16
|
-
productions_: [0,[3,0],[3,1],[5,1],[5,3],[5,2],[5,2],[5,3],[
|
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:
|
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,
|
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
|
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
|
-
|
395
|
+
target[key] = value;
|
380
396
|
} else {
|
381
|
-
|
397
|
+
def(target, key, {
|
382
398
|
value: value,
|
383
399
|
configurable: true
|
384
|
-
})
|
400
|
+
});
|
385
401
|
}
|
386
402
|
}
|
387
|
-
return
|
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.
|
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.
|
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.
|
513
|
-
return _this.
|
514
|
-
return
|
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.
|
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.
|
574
|
+
if (!this.object._s.hasOwnProperty("queue_" + this.name)) {
|
539
575
|
this.queue = [];
|
540
576
|
}
|
541
|
-
return this.object[this.
|
577
|
+
return this.object._s["queue_" + this.name];
|
542
578
|
},
|
543
579
|
set: function(val) {
|
544
|
-
return
|
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
|
707
|
-
|
708
|
-
|
742
|
+
def(Collection.prototype, "first", {
|
743
|
+
get: function() {
|
744
|
+
return this[0];
|
745
|
+
}
|
746
|
+
});
|
709
747
|
|
710
|
-
Collection.prototype
|
711
|
-
|
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 = "
|
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.
|
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.
|
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.
|
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["
|
1077
|
-
|
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,
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
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.
|
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
|
-
|
1175
|
-
|
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.
|
1282
|
-
|
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
|
-
|
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
|
-
|
1383
|
+
propOptions = merge(options, {
|
1329
1384
|
get: function() {
|
1330
1385
|
var valueName,
|
1331
1386
|
_this = this;
|
1332
|
-
valueName = "
|
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,
|
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,
|
1355
|
-
|
1356
|
-
|
1409
|
+
Model.belongsTo = function(name, options) {
|
1410
|
+
var propOptions;
|
1411
|
+
if (options == null) {
|
1412
|
+
options = {};
|
1357
1413
|
}
|
1358
|
-
|
1414
|
+
propOptions = merge(options, {
|
1359
1415
|
set: function(model) {
|
1360
1416
|
var previous, valueName;
|
1361
|
-
valueName = "
|
1362
|
-
if (model && model.constructor === Object &&
|
1363
|
-
model = new (
|
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 (
|
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[
|
1425
|
+
previous[options.inverseOf]["delete"](this);
|
1370
1426
|
}
|
1371
|
-
return model[
|
1427
|
+
return model[options.inverseOf].push(this);
|
1372
1428
|
}
|
1373
1429
|
}
|
1374
1430
|
});
|
1375
|
-
this.property(name,
|
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] =
|
1439
|
+
return this[name] = options.as().find(id);
|
1384
1440
|
}
|
1385
1441
|
},
|
1386
1442
|
dependsOn: name,
|
1387
|
-
serialize:
|
1443
|
+
serialize: options.serializeId
|
1388
1444
|
});
|
1389
1445
|
};
|
1390
1446
|
|
1391
|
-
Model.hasMany = function(name,
|
1392
|
-
|
1393
|
-
|
1447
|
+
Model.hasMany = function(name, options) {
|
1448
|
+
var propOptions;
|
1449
|
+
if (options == null) {
|
1450
|
+
options = {};
|
1394
1451
|
}
|
1395
|
-
|
1452
|
+
propOptions = merge(options, {
|
1396
1453
|
get: function() {
|
1397
1454
|
var valueName,
|
1398
1455
|
_this = this;
|
1399
|
-
valueName = "
|
1400
|
-
if (!this[valueName]) {
|
1401
|
-
this[valueName] = new AssociationCollection(this,
|
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,
|
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(
|
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:
|
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
|
-
|
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
|
1477
|
-
value: val,
|
1478
|
-
configurable: true
|
1479
|
-
});
|
1535
|
+
return this._s.val_id = val;
|
1480
1536
|
},
|
1481
1537
|
get: function() {
|
1482
|
-
return this.
|
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.
|
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
|
1752
|
-
|
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
|
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
|
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
|
1915
|
-
|
1916
|
-
|
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
|
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.
|
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
|
-
|
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
|
2098
|
+
return assignUnlessEqual(element, "value", value || '');
|
2022
2099
|
} else if (node.ast.name === 'input' && ast.name === 'checked') {
|
2023
|
-
return element
|
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
|
-
|
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
|
-
|
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,
|
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
|
-
|
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
|
-
|
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
|
-
|
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,
|
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
|
-
|
2106
|
-
for (_i = 0, _len =
|
2107
|
-
child =
|
2108
|
-
|
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
|
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
|
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([
|
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([
|
2319
|
+
return dynamic.replace([compile(ast.children, model, controller)]);
|
2239
2320
|
} else if (ast["else"]) {
|
2240
|
-
return dynamic.replace([
|
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
|
2329
|
+
var nodes;
|
2249
2330
|
if (value) {
|
2250
2331
|
return dynamic.clear();
|
2251
2332
|
} else {
|
2252
|
-
nodes = (
|
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
|
-
|
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(
|
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(
|
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.
|
2470
|
+
return this.compile.apply(this, args).fragment;
|
2358
2471
|
};
|
2359
2472
|
|
2360
|
-
View.prototype.
|
2361
|
-
var
|
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
|
-
|
2482
|
+
nodes = compile(this.parse(), model, controller);
|
2370
2483
|
if (!skipCallback) {
|
2371
2484
|
if (typeof controller.loaded === "function") {
|
2372
|
-
controller.loaded(
|
2485
|
+
controller.loaded.apply(controller, __slice.call(nodes.map(function(node) {
|
2486
|
+
return node.element;
|
2487
|
+
})).concat([model]));
|
2373
2488
|
}
|
2374
2489
|
}
|
2375
|
-
return
|
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.
|
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];
|
data/lib/serenade/version.rb
CHANGED
data/spec/serenade_spec.rb
CHANGED
@@ -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.
|
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-
|
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.
|
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
|