Permalink
Browse files

Functions are now not executed by default. New backward compatibility…

… configuration
  • Loading branch information...
Jean-Christophe Cazeaux
Jean-Christophe Cazeaux committed Feb 9, 2016
1 parent f9d0a45 commit 02cfbddf7dcd195051551f0e40468a8d1eaf422c
Showing with 53 additions and 5 deletions.
  1. +1 −0 gulpfile.js
  2. +17 −1 spec/rivets/binding.js
  3. +19 −0 spec/rivets/formatters.js
  4. +1 −0 spec/runner.html
  5. +4 −3 src/bindings.coffee
  6. +6 −0 src/formatters.coffee
  7. +5 −1 src/rivets.coffee
@@ -18,6 +18,7 @@ source = [
'src/view.coffee',
'src/bindings.coffee',
'src/binders.coffee',
'src/formatters.coffee',
'src/adapter.coffee',
'src/export.coffee'
]
@@ -124,12 +124,28 @@ describe('Rivets.Binding', function() {
binding.set('sweater')
binding.binder.routine.calledWith(el, 'awesome sweater').should.be.true
})
})

describe('functions in bindings', function() {
it('does not call methods by default', function() {
sinon.spy(binding.binder, 'routine')
var fn = function() {};
binding.set(fn)
binding.binder.routine.calledWith(el, fn).should.be.true
})

it('calls methods with the object as context', function() {
it('does calls methods with model if backward compatibility is set', function() {
rivets.configure({
bindingAutoexecuteFunctions:true
})
binding.model = {foo: 'bar'}
sinon.spy(binding.binder, 'routine')
binding.set(function() { return this.foo })
binding.binder.routine.calledWith(el, binding.model.foo).should.be.true
// Back to default !!
rivets.configure({
bindingAutoexecuteFunctions:false
})
})
})

@@ -0,0 +1,19 @@
describe("Rivets.formatters", function() {
var context

describe("call", function() {
var model

beforeEach(function() {
model = {
fn: function(arg1, arg2) {
return '' + arg1 + arg2;
}
}
})

it("calls function with arguments", function() {
rivets.formatters['call'](model.fn, 'foo', 'bar').should.equal('foobar')
})
})
});
@@ -21,6 +21,7 @@

<script src="lib/mock.data.js"></script>
<script src="rivets/binders.js"></script>
<script src="rivets/formatters.js"></script>
<script src="rivets/binding.js"></script>
<script src="rivets/component_binding.js"></script>
<script src="rivets/functional.js"></script>
@@ -65,9 +65,9 @@ class Rivets.Binding
observer.value()

if formatter?.read instanceof Function
value = formatter.read value, processedArgs...
value = formatter.read.call @model, value, processedArgs...
else if formatter instanceof Function
value = formatter value, processedArgs...
value = formatter.call @model, value, processedArgs...

value

@@ -79,7 +79,8 @@ class Rivets.Binding
# Sets the value for the binding. This Basically just runs the binding routine
# with the suplied value formatted.
set: (value) =>
value = if value instanceof Function and !@binder.function
# Since 0.9 : doesn't execute function unless backward compatibility is active
value = if (value instanceof Function and !@binder.function and Rivets.public.bindingAutoexecuteFunctions)
@formattedValue value.call @model
else
@formattedValue value
@@ -0,0 +1,6 @@
# Core formatters for function handling

# Calls a function with arguments
Rivets.public.formatters['call'] = (value, args...) ->
value.call @, args...

This comment has been minimized.

@benadamstyles

benadamstyles Feb 9, 2016

Collaborator

Just wondered what the rationale was for choosing the this context here? Just wondering what your thinking is here.

This comment has been minimized.

@jccazeaux

jccazeaux Feb 10, 2016

Contributor

Natural context of the function called by this formatter will be the current object on which it was defined. If model is

{
  obj: {
    name:'foo',
    getName: function(){ return this.name }
  }
}

And a template

{ obj.getName | call }

The result must be foo. So getName context has to be obj. The code is here to guarantee it. It works with this code
Hope it's clear

This comment has been minimized.

@benadamstyles

benadamstyles Feb 10, 2016

Collaborator

Yep that's very clear, thanks


@@ -5,7 +5,8 @@ Rivets =
'templateDelimiters'
'rootInterface'
'preloadData'
'handler'
'handler',
'bindingAutoexecuteFunctions'
]

extensions: [
@@ -41,6 +42,9 @@ Rivets =
# Preload data by default.
preloadData: true,

# Auto execution of functions in bindings. Set true to act like rivets 0.8.
bindingAutoexecuteFunctions: false,

# Alias for index in rv-each binder
iterationAlias : (modelName) ->
return '%' + modelName + '%'

0 comments on commit 02cfbdd

Please sign in to comment.