0f074f08 by Michael Richards

Implement piping mechanism for applying formatters defined in Rivets.config.formatters.

1 parent 038cffc7
...@@ -10,11 +10,12 @@ ...@@ -10,11 +10,12 @@
10 10
11 Binding.name = 'Binding'; 11 Binding.name = 'Binding';
12 12
13 function Binding(el, type, context, keypath) { 13 function Binding(el, type, context, keypath, formatters) {
14 this.el = el; 14 this.el = el;
15 this.type = type; 15 this.type = type;
16 this.context = context; 16 this.context = context;
17 this.keypath = keypath; 17 this.keypath = keypath;
18 this.formatters = formatters != null ? formatters : [];
18 this.bind = __bind(this.bind, this); 19 this.bind = __bind(this.bind, this);
19 20
20 this.set = __bind(this.set, this); 21 this.set = __bind(this.set, this);
...@@ -23,10 +24,18 @@ ...@@ -23,10 +24,18 @@
23 } 24 }
24 25
25 Binding.prototype.set = function(value) { 26 Binding.prototype.set = function(value) {
27 var formatter, _i, _len, _ref;
26 if (value == null) { 28 if (value == null) {
27 value = null; 29 value = null;
28 } 30 }
29 return this.routine(this.el, value || Rivets.config.adapter.read(this.context, this.keypath)); 31 if (value || (value = Rivets.config.adapter.read(this.context, this.keypath))) {
32 _ref = this.formatters;
33 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
34 formatter = _ref[_i];
35 value = Rivets.config.formatters[formatter](value);
36 }
37 return this.routine(this.el, value);
38 }
30 }; 39 };
31 40
32 Binding.prototype.bind = function() { 41 Binding.prototype.bind = function() {
...@@ -76,7 +85,7 @@ ...@@ -76,7 +85,7 @@
76 }; 85 };
77 86
78 View.prototype.build = function() { 87 View.prototype.build = function() {
79 var attribute, context, dataRegExp, keypath, node, path, type, _i, _len, _ref, _results; 88 var attribute, context, dataRegExp, keypath, node, path, pipes, type, _i, _len, _ref, _results;
80 this.bindings = []; 89 this.bindings = [];
81 _ref = this.el.getElementsByTagName('*'); 90 _ref = this.el.getElementsByTagName('*');
82 _results = []; 91 _results = [];
...@@ -91,10 +100,13 @@ ...@@ -91,10 +100,13 @@
91 dataRegExp = new RegExp(this.data, 'g'); 100 dataRegExp = new RegExp(this.data, 'g');
92 if (this.bindingRegExp().test(attribute.name)) { 101 if (this.bindingRegExp().test(attribute.name)) {
93 type = attribute.name.replace(this.bindingRegExp(), ''); 102 type = attribute.name.replace(this.bindingRegExp(), '');
94 path = attribute.value.split('.'); 103 pipes = attribute.value.split('|').map(function(pipe) {
104 return pipe.trim();
105 });
106 path = pipes.shift().split('.');
95 context = this.contexts[path.shift()]; 107 context = this.contexts[path.shift()];
96 keypath = path.join('.'); 108 keypath = path.join('.');
97 _results1.push(this.bindings.push(new Rivets.Binding(node, type, context, keypath))); 109 _results1.push(this.bindings.push(new Rivets.Binding(node, type, context, keypath, pipes)));
98 } else { 110 } else {
99 _results1.push(void 0); 111 _results1.push(void 0);
100 } 112 }
......
...@@ -11,13 +11,17 @@ class Rivets.Binding ...@@ -11,13 +11,17 @@ class Rivets.Binding
11 # All information about the binding is passed into the constructor; the DOM 11 # All information about the binding is passed into the constructor; the DOM
12 # element, the type of binding, the context object and the keypath at which to 12 # element, the type of binding, the context object and the keypath at which to
13 # listen to for changes. 13 # listen to for changes.
14 constructor: (@el, @type, @context, @keypath) -> 14 constructor: (@el, @type, @context, @keypath, @formatters = []) ->
15 @routine = Rivets.bindings[@type] || attributeBinding @type 15 @routine = Rivets.bindings[@type] || attributeBinding @type
16 16
17 # Sets a value for this binding. Basically just runs the routine on the 17 # Sets a value for this binding. Basically just runs the routine on the
18 # element with a suplied value. 18 # element with a suplied value and applies any formatters.
19 set: (value = null) => 19 set: (value = null) =>
20 @routine @el, value || Rivets.config.adapter.read @context, @keypath 20 if value or= Rivets.config.adapter.read @context, @keypath
21 for formatter in @formatters
22 value = Rivets.config.formatters[formatter] value
23
24 @routine @el, value
21 25
22 # Subscribes to the context object for changes on the specific keypath. 26 # Subscribes to the context object for changes on the specific keypath.
23 # Conditionally also does the inverse and listens to the element for changes 27 # Conditionally also does the inverse and listens to the element for changes
...@@ -51,10 +55,12 @@ class Rivets.View ...@@ -51,10 +55,12 @@ class Rivets.View
51 dataRegExp = new RegExp(@data, 'g') 55 dataRegExp = new RegExp(@data, 'g')
52 if @bindingRegExp().test attribute.name 56 if @bindingRegExp().test attribute.name
53 type = attribute.name.replace @bindingRegExp(), '' 57 type = attribute.name.replace @bindingRegExp(), ''
54 path = attribute.value.split '.' 58 pipes = attribute.value.split('|').map (pipe) -> pipe.trim()
59 path = pipes.shift().split '.'
55 context = @contexts[path.shift()] 60 context = @contexts[path.shift()]
56 keypath = path.join '.' 61 keypath = path.join '.'
57 @bindings.push new Rivets.Binding node, type, context, keypath 62
63 @bindings.push new Rivets.Binding node, type, context, keypath, pipes
58 64
59 # Binds all of the current bindings for this view. 65 # Binds all of the current bindings for this view.
60 bind: => 66 bind: =>
......