888c8a42 by Michael Richards

Merge pull request #30 from mikeric/simplify-binding-routines-access

Simplify binding routines access
2 parents fe3613de 04be1776
...@@ -81,13 +81,17 @@ Set the `preloadData` option to `true` or `false` depending on if you want the b ...@@ -81,13 +81,17 @@ Set the `preloadData` option to `true` or `false` depending on if you want the b
81 81
82 ## Extend 82 ## Extend
83 83
84 You can extend Rivets.js by adding your own custom data bindings (routines). Just pass `rivets.register` an identifier and a routine function. Routine functions take two arguments, `el` which is the DOM element and `value` which is the incoming value of the attribute being bound to. 84 Rivets.js comes with only the most commonly used bindings and encourages developers to add their own that are specific to the needs of their application. Rivets.js is extended by adding your own custom binding routines. *Binding routines* are the functions that run when an observed attribute changes. Their sole concern is to describe what happens to the element when a new value comes in.
85 85
86 So let's say we wanted a `data-color` binding that sets the element's colour. Here's what that might look like: 86 All binding routines are available on the `rivets.routines` object so it's easy to extend by adding/removing them from that object. Let's say we wanted a `data-color` binding that sets the element's colour, here's what the routine function for that might look like:
87 87
88 rivets.register('color', function(el, value){ 88 rivets.routines.color = function(el, value) {
89 el.style.color = value; 89 el.style.color = value;
90 }); 90 };
91
92 With that routine defined, the following binding will update the elements color when `model.color` changes:
93
94 <span data-color="model.color">COLOR</span>
91 95
92 #### Available bindings out-of-the-box 96 #### Available bindings out-of-the-box
93 97
......
...@@ -280,6 +280,7 @@ ...@@ -280,6 +280,7 @@
280 }; 280 };
281 281
282 rivets = { 282 rivets = {
283 routines: Rivets.routines,
283 configure: function(options) { 284 configure: function(options) {
284 var property, value, _results; 285 var property, value, _results;
285 if (options == null) { 286 if (options == null) {
...@@ -292,9 +293,6 @@ ...@@ -292,9 +293,6 @@
292 } 293 }
293 return _results; 294 return _results;
294 }, 295 },
295 register: function(identifier, routine) {
296 return Rivets.routines[identifier] = routine;
297 },
298 bind: function(el, models) { 296 bind: function(el, models) {
299 var view; 297 var view;
300 if (models == null) { 298 if (models == null) {
......
1 (function(){var a,b,c,d,e,f,g,h,i=function(a,b){return function(){return a.apply(b,arguments)}},j=[].indexOf||function(a){for(var b=0,c=this.length;b<c;b++)if(b in this&&this[b]===a)return b;return-1};a={},String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),a.Binding=function(){function c(c,d,f,g,h,j){this.el=c,this.type=d,this.bindType=f,this.model=g,this.keypath=h,this.formatters=j!=null?j:[],this.unbind=i(this.unbind,this),this.publish=i(this.publish,this),this.bind=i(this.bind,this),this.set=i(this.set,this),this.bindType==="event"?this.routine=e(this.type):this.routine=a.routines[this.type]||b(this.type)}return c.prototype.set=function(b){var c,d,e,f;f=this.formatters;for(d=0,e=f.length;d<e;d++)c=f[d],b=a.config.formatters[c](b);return this.bindType==="event"?(this.routine(this.el,b,this.currentListener),this.currentListener=b):this.routine(this.el,b)},c.prototype.bind=function(){a.config.adapter.subscribe(this.model,this.keypath,this.set),a.config.preloadData&&this.set(a.config.adapter.read(this.model,this.keypath));if(this.bindType==="bidirectional")return d(this.el,"change",this.publish)},c.prototype.publish=function(b){var c;return c=b.target||b.srcElement,a.config.adapter.publish(this.model,this.keypath,f(c))},c.prototype.unbind=function(){a.config.adapter.unsubscribe(this.model,this.keypath,this.set);if(this.bindType==="bidirectional")return this.el.removeEventListener("change",this.publish)},c}(),a.View=function(){function b(a,b){this.el=a,this.models=b,this.unbind=i(this.unbind,this),this.bind=i(this.bind,this),this.build=i(this.build,this),this.bindingRegExp=i(this.bindingRegExp,this),this.el.jquery&&(this.el=this.el.get(0)),this.build()}return b.prototype.bindingRegExp=function(){var b;return b=a.config.prefix,b?new RegExp("^data-"+b+"-"):/^data-/},b.prototype.build=function(){var b,d,e,f,g,h,i,k,l=this;this.bindings=[],b=this.bindingRegExp(),d=/^on-/,f=function(e){var f,g,h,i,k,m,n,o,p,q,r,s;r=e.attributes,s=[];for(p=0,q=r.length;p<q;p++)f=r[p],b.test(f.name)?(g="attribute",o=f.name.replace(b,""),n=function(){var a,b,c,d;c=f.value.split("|"),d=[];for(a=0,b=c.length;a<b;a++)m=c[a],d.push(m.trim());return d}(),k=n.shift().split("."),i=l.models[k.shift()],h=k.join("."),d.test(o)?(o=o.replace(d,""),g="event"):j.call(c,o)>=0&&(g="bidirectional"),s.push(l.bindings.push(new a.Binding(e,o,g,i,h,n)))):s.push(void 0);return s},f(this.el),i=this.el.getElementsByTagName("*"),k=[];for(g=0,h=i.length;g<h;g++)e=i[g],k.push(f(e));return k},b.prototype.bind=function(){var a,b,c,d,e;d=this.bindings,e=[];for(b=0,c=d.length;b<c;b++)a=d[b],e.push(a.bind());return e},b.prototype.unbind=function(){var a,b,c,d,e;d=this.bindings,e=[];for(b=0,c=d.length;b<c;b++)a=d[b],e.push(a.unbind());return e},b}(),d=function(a,b,c){return window.addEventListener?a.addEventListener(b,c):a.attachEvent(b,c)},h=function(a,b,c){return window.removeEventListener?a.removeEventListener(b,c):a.detachEvent(b,c)},f=function(a){switch(a.type){case"text":case"textarea":case"password":case"select-one":return a.value;case"checkbox":case"radio":return a.checked}},e=function(a){return function(b,c,e){c&&d(b,a,c);if(e)return h(b,a,e)}},b=function(a){return function(b,c){return c?b.setAttribute(a,c):b.removeAttribute(a)}},c=["value","checked","unchecked","selected","unselected"],a.routines={enabled:function(a,b){return a.disabled=!b},disabled:function(a,b){return a.disabled=!!b},checked:function(a,b){return a.checked=!!b},unchecked:function(a,b){return a.checked=!b},selected:function(a,b){return a.selected=!!b},unselected:function(a,b){return a.selected=!b},show:function(a,b){return a.style.display=b?"":"none"},hide:function(a,b){return a.style.display=b?"none":""},html:function(a,b){return a.innerHTML=b||""},value:function(a,b){return a.value=b},text:function(a,b){return a.innerText!=null?a.innerText=b||"":a.textContent=b||""}},a.config={preloadData:!0},g={configure:function(b){var c,d,e;b==null&&(b={}),e=[];for(c in b)d=b[c],e.push(a.config[c]=d);return e},register:function(b,c){return a.routines[b]=c},bind:function(b,c){var d;return c==null&&(c={}),d=new a.View(b,c),d.bind(),d}},typeof module!="undefined"&&module!==null?module.exports=g:this.rivets=g}).call(this);
...\ No newline at end of file ...\ No newline at end of file
1 (function(){var a,b,c,d,e,f,g,h,i=function(a,b){return function(){return a.apply(b,arguments)}},j=[].indexOf||function(a){for(var b=0,c=this.length;b<c;b++)if(b in this&&this[b]===a)return b;return-1};a={},String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),a.Binding=function(){function c(c,d,f,g,h,j){this.el=c,this.type=d,this.bindType=f,this.model=g,this.keypath=h,this.formatters=j!=null?j:[],this.unbind=i(this.unbind,this),this.publish=i(this.publish,this),this.bind=i(this.bind,this),this.set=i(this.set,this),this.bindType==="event"?this.routine=e(this.type):this.routine=a.routines[this.type]||b(this.type)}return c.prototype.set=function(b){var c,d,e,f;f=this.formatters;for(d=0,e=f.length;d<e;d++)c=f[d],b=a.config.formatters[c](b);return this.bindType==="event"?(this.routine(this.el,b,this.currentListener),this.currentListener=b):this.routine(this.el,b)},c.prototype.bind=function(){a.config.adapter.subscribe(this.model,this.keypath,this.set),a.config.preloadData&&this.set(a.config.adapter.read(this.model,this.keypath));if(this.bindType==="bidirectional")return d(this.el,"change",this.publish)},c.prototype.publish=function(b){var c;return c=b.target||b.srcElement,a.config.adapter.publish(this.model,this.keypath,f(c))},c.prototype.unbind=function(){a.config.adapter.unsubscribe(this.model,this.keypath,this.set);if(this.bindType==="bidirectional")return this.el.removeEventListener("change",this.publish)},c}(),a.View=function(){function b(a,b){this.el=a,this.models=b,this.unbind=i(this.unbind,this),this.bind=i(this.bind,this),this.build=i(this.build,this),this.bindingRegExp=i(this.bindingRegExp,this),this.el.jquery&&(this.el=this.el.get(0)),this.build()}return b.prototype.bindingRegExp=function(){var b;return b=a.config.prefix,b?new RegExp("^data-"+b+"-"):/^data-/},b.prototype.build=function(){var b,d,e,f,g,h,i,k,l=this;this.bindings=[],b=this.bindingRegExp(),d=/^on-/,f=function(e){var f,g,h,i,k,m,n,o,p,q,r,s;r=e.attributes,s=[];for(p=0,q=r.length;p<q;p++)f=r[p],b.test(f.name)?(g="attribute",o=f.name.replace(b,""),n=function(){var a,b,c,d;c=f.value.split("|"),d=[];for(a=0,b=c.length;a<b;a++)m=c[a],d.push(m.trim());return d}(),k=n.shift().split("."),i=l.models[k.shift()],h=k.join("."),d.test(o)?(o=o.replace(d,""),g="event"):j.call(c,o)>=0&&(g="bidirectional"),s.push(l.bindings.push(new a.Binding(e,o,g,i,h,n)))):s.push(void 0);return s},f(this.el),i=this.el.getElementsByTagName("*"),k=[];for(g=0,h=i.length;g<h;g++)e=i[g],k.push(f(e));return k},b.prototype.bind=function(){var a,b,c,d,e;d=this.bindings,e=[];for(b=0,c=d.length;b<c;b++)a=d[b],e.push(a.bind());return e},b.prototype.unbind=function(){var a,b,c,d,e;d=this.bindings,e=[];for(b=0,c=d.length;b<c;b++)a=d[b],e.push(a.unbind());return e},b}(),d=function(a,b,c){return window.addEventListener?a.addEventListener(b,c):a.attachEvent(b,c)},h=function(a,b,c){return window.removeEventListener?a.removeEventListener(b,c):a.detachEvent(b,c)},f=function(a){switch(a.type){case"text":case"textarea":case"password":case"select-one":return a.value;case"checkbox":case"radio":return a.checked}},e=function(a){return function(b,c,e){c&&d(b,a,c);if(e)return h(b,a,e)}},b=function(a){return function(b,c){return c?b.setAttribute(a,c):b.removeAttribute(a)}},c=["value","checked","unchecked","selected","unselected"],a.routines={enabled:function(a,b){return a.disabled=!b},disabled:function(a,b){return a.disabled=!!b},checked:function(a,b){return a.checked=!!b},unchecked:function(a,b){return a.checked=!b},selected:function(a,b){return a.selected=!!b},unselected:function(a,b){return a.selected=!b},show:function(a,b){return a.style.display=b?"":"none"},hide:function(a,b){return a.style.display=b?"none":""},html:function(a,b){return a.innerHTML=b||""},value:function(a,b){return a.value=b},text:function(a,b){return a.innerText!=null?a.innerText=b||"":a.textContent=b||""}},a.config={preloadData:!0},g={routines:a.routines,configure:function(b){var c,d,e;b==null&&(b={}),e=[];for(c in b)d=b[c],e.push(a.config[c]=d);return e},bind:function(b,c){var d;return c==null&&(c={}),d=new a.View(b,c),d.bind(),d}},typeof module!="undefined"&&module!==null?module.exports=g:this.rivets=g}).call(this);
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -175,16 +175,14 @@ Rivets.config = ...@@ -175,16 +175,14 @@ Rivets.config =
175 175
176 # The rivets module. This is the public interface that gets exported. 176 # The rivets module. This is the public interface that gets exported.
177 rivets = 177 rivets =
178 # Used for setting configuration options. 178 # Exposes the core binding routines that can be extended or stripped down.
179 routines: Rivets.routines
180
181 # Sets configuration options by merging an object literal.
179 configure: (options={}) -> 182 configure: (options={}) ->
180 for property, value of options 183 for property, value of options
181 Rivets.config[property] = value 184 Rivets.config[property] = value
182 185
183 # Registers a new binding routine that can be used immediately in views. This
184 # is used for adding custom binding routines.
185 register: (identifier, routine) ->
186 Rivets.routines[identifier] = routine
187
188 # Binds a set of model objects to a parent DOM element. Returns a Rivets.View 186 # Binds a set of model objects to a parent DOM element. Returns a Rivets.View
189 # instance. 187 # instance.
190 bind: (el, models = {}) -> 188 bind: (el, models = {}) ->
......