0f074f08 by Michael Richards

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

1 parent 038cffc7
......@@ -10,11 +10,12 @@
Binding.name = 'Binding';
function Binding(el, type, context, keypath) {
function Binding(el, type, context, keypath, formatters) {
this.el = el;
this.type = type;
this.context = context;
this.keypath = keypath;
this.formatters = formatters != null ? formatters : [];
this.bind = __bind(this.bind, this);
this.set = __bind(this.set, this);
......@@ -23,10 +24,18 @@
}
Binding.prototype.set = function(value) {
var formatter, _i, _len, _ref;
if (value == null) {
value = null;
}
return this.routine(this.el, value || Rivets.config.adapter.read(this.context, this.keypath));
if (value || (value = Rivets.config.adapter.read(this.context, this.keypath))) {
_ref = this.formatters;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
formatter = _ref[_i];
value = Rivets.config.formatters[formatter](value);
}
return this.routine(this.el, value);
}
};
Binding.prototype.bind = function() {
......@@ -76,7 +85,7 @@
};
View.prototype.build = function() {
var attribute, context, dataRegExp, keypath, node, path, type, _i, _len, _ref, _results;
var attribute, context, dataRegExp, keypath, node, path, pipes, type, _i, _len, _ref, _results;
this.bindings = [];
_ref = this.el.getElementsByTagName('*');
_results = [];
......@@ -91,10 +100,13 @@
dataRegExp = new RegExp(this.data, 'g');
if (this.bindingRegExp().test(attribute.name)) {
type = attribute.name.replace(this.bindingRegExp(), '');
path = attribute.value.split('.');
pipes = attribute.value.split('|').map(function(pipe) {
return pipe.trim();
});
path = pipes.shift().split('.');
context = this.contexts[path.shift()];
keypath = path.join('.');
_results1.push(this.bindings.push(new Rivets.Binding(node, type, context, keypath)));
_results1.push(this.bindings.push(new Rivets.Binding(node, type, context, keypath, pipes)));
} else {
_results1.push(void 0);
}
......
......@@ -11,13 +11,17 @@ class Rivets.Binding
# All information about the binding is passed into the constructor; the DOM
# element, the type of binding, the context object and the keypath at which to
# listen to for changes.
constructor: (@el, @type, @context, @keypath) ->
constructor: (@el, @type, @context, @keypath, @formatters = []) ->
@routine = Rivets.bindings[@type] || attributeBinding @type
# Sets a value for this binding. Basically just runs the routine on the
# element with a suplied value.
# element with a suplied value and applies any formatters.
set: (value = null) =>
@routine @el, value || Rivets.config.adapter.read @context, @keypath
if value or= Rivets.config.adapter.read @context, @keypath
for formatter in @formatters
value = Rivets.config.formatters[formatter] value
@routine @el, value
# Subscribes to the context object for changes on the specific keypath.
# Conditionally also does the inverse and listens to the element for changes
......@@ -51,10 +55,12 @@ class Rivets.View
dataRegExp = new RegExp(@data, 'g')
if @bindingRegExp().test attribute.name
type = attribute.name.replace @bindingRegExp(), ''
path = attribute.value.split '.'
pipes = attribute.value.split('|').map (pipe) -> pipe.trim()
path = pipes.shift().split '.'
context = @contexts[path.shift()]
keypath = path.join '.'
@bindings.push new Rivets.Binding node, type, context, keypath
@bindings.push new Rivets.Binding node, type, context, keypath, pipes
# Binds all of the current bindings for this view.
bind: =>
......