Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Commit

Permalink
Add inline function support
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelw committed Jun 3, 2014
1 parent f6e1ba2 commit 9864d7b
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 32 deletions.
70 changes: 41 additions & 29 deletions src/polymer-expressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@
} else if (!this.computed) {
var path = Path.get(this.property.name);

this.valueFn_ = function(model, observer) {
var context = object(model, observer);
this.valueFn_ = function(model, observer, filterRegistry) {
var context = object(model, observer, filterRegistry);

if (observer)
observer.addPath(context, path);
Expand All @@ -154,9 +154,9 @@
// Computed property.
var property = this.property;

this.valueFn_ = function(model, observer) {
var context = object(model, observer);
var propName = property(model, observer);
this.valueFn_ = function(model, observer, filterRegistry) {
var context = object(model, observer, filterRegistry);
var propName = property(model, observer, filterRegistry);
if (observer)
observer.addPath(context, [propName]);

Expand Down Expand Up @@ -189,16 +189,16 @@
}

Filter.prototype = {
transform: function(value, toModelDirection, filterRegistry, model,
observer) {
transform: function(model, observer, filterRegistry, toModelDirection,
initialArgs) {
var fn = filterRegistry[this.name];
var context = model;
if (fn) {
context = undefined;
} else {
fn = context[this.name];
if (!fn) {
console.error('Cannot find filter: ' + this.name);
console.error('Cannot find function or filter: ' + this.name);
return;
}
}
Expand All @@ -213,14 +213,13 @@
}

if (typeof fn != 'function') {
console.error('No ' + (toModelDirection ? 'toModel' : 'toDOM') +
' found on' + this.name);
console.error('Cannot find function or filter: ' + this.name);
return;
}

var args = [value];
var args = initialArgs || [];
for (var i = 0; i < this.args.length; i++) {
args[i + 1] = getFn(this.args[i])(model, observer);
args.push(getFn(this.args[i])(model, observer, filterRegistry));
}

return fn.apply(context, args);
Expand Down Expand Up @@ -274,8 +273,8 @@

argument = getFn(argument);

return function(model, observer) {
return unaryOperators[op](argument(model, observer));
return function(model, observer, filterRegistry) {
return unaryOperators[op](argument(model, observer, filterRegistry));
};
},

Expand All @@ -286,9 +285,9 @@
left = getFn(left);
right = getFn(right);

return function(model, observer) {
return binaryOperators[op](left(model, observer),
right(model, observer));
return function(model, observer, filterRegistry) {
return binaryOperators[op](left(model, observer, filterRegistry),
right(model, observer, filterRegistry));
};
},

Expand All @@ -297,9 +296,10 @@
consequent = getFn(consequent);
alternate = getFn(alternate);

return function(model, observer) {
return test(model, observer) ?
consequent(model, observer) : alternate(model, observer);
return function(model, observer, filterRegistry) {
return test(model, observer, filterRegistry) ?
consequent(model, observer, filterRegistry) :
alternate(model, observer, filterRegistry);
}
},

Expand All @@ -316,6 +316,17 @@
return ex;
},

createCallExpression: function(expression, args) {
if (!(expression instanceof IdentPath))
throw Error('Only identifier function invocations are allowed');

var filter = new Filter(expression.name, args);

return function(model, observer, filterRegistry) {
return filter.transform(model, observer, filterRegistry, false);
};
},

createLiteral: function(token) {
return new Literal(token.value);
},
Expand All @@ -324,10 +335,10 @@
for (var i = 0; i < elements.length; i++)
elements[i] = getFn(elements[i]);

return function(model, observer) {
return function(model, observer, filterRegistry) {
var arr = []
for (var i = 0; i < elements.length; i++)
arr.push(elements[i](model, observer));
arr.push(elements[i](model, observer, filterRegistry));
return arr;
}
},
Expand All @@ -343,10 +354,11 @@
for (var i = 0; i < properties.length; i++)
properties[i].value = getFn(properties[i].value);

return function(model, observer) {
return function(model, observer, filterRegistry) {
var obj = {};
for (var i = 0; i < properties.length; i++)
obj[properties[i].key] = properties[i].value(model, observer);
obj[properties[i].key] =
properties[i].value(model, observer, filterRegistry);
return obj;
}
},
Expand Down Expand Up @@ -437,10 +449,10 @@
},

getValue: function(model, observer, filterRegistry) {
var value = getFn(this.expression)(model, observer);
var value = getFn(this.expression)(model, observer, filterRegistry);
for (var i = 0; i < this.filters.length; i++) {
value = this.filters[i].transform(value, false, filterRegistry, model,
observer);
value = this.filters[i].transform(model, observer, filterRegistry,
false, [value]);
}

return value;
Expand All @@ -449,8 +461,8 @@
setValue: function(model, newValue, filterRegistry) {
var count = this.filters ? this.filters.length : 0;
while (count-- > 0) {
newValue = this.filters[count].transform(newValue, true, filterRegistry,
model);
newValue = this.filters[count].transform(model, undefined,
filterRegistry, true, [newValue]);
}

if (this.expression.setValue)
Expand Down
54 changes: 54 additions & 0 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,45 @@ suite('PolymerExpressions', function() {
});
});

test('Inline functions', function(done) {
var div = createTestHtml(
'<template bind="{{ }}">' +
'{{ addTwo(2, 3) + addTwo(a, b) }}:{{ minus(addTwo(a, b), c) }}' +
'</template>');

var model = {
a: 4,
b: 5,
c: 3,
addTwo: function(a, b) {
assert.strictEqual(this, model);
return a + b;
},
minus: function(a, amount) {
assert.strictEqual(this, model);
return a - amount;
}
};

recursivelySetTemplateModel(div, model);

then(function() {
assert.equal('14:6', div.childNodes[1].textContent);

model.a = 10;
}).then(function() {
assert.equal('20:12', div.childNodes[1].textContent);

model.c = 10;

}).then(function() {
assert.equal('20:5', div.childNodes[1].textContent);

done();
});
});


test('Expression execution count', function(done) {
var div = createTestHtml(
'<template bind>' +
Expand Down Expand Up @@ -1668,6 +1707,21 @@ suite('PolymerExpressions', function() {
});
});

test('Inline function parsing', function() {
assert.isDefined(getExpression_('a(1, 2)'));
assert.isDefined(getExpression_('a(b + c, d + e)'));
assert.isDefined(getExpression_('a(true) + b(false)'));
assert.throws(function() {
getExpression_('a.b()');
});
assert.throws(function() {
getExpression_('a[1]()');
});
assert.throws(function() {
getExpression_('(a + b)()');
});
});

test('Dynamic deps path expressions', function() {
assert.isFalse(getExpression_('a + b').dynamicDeps);
assert.isFalse(getExpression_('a + b > 3 + hello["kitty"]').dynamicDeps);
Expand Down
11 changes: 8 additions & 3 deletions third_party/esprima/esprima.js
Original file line number Diff line number Diff line change
Expand Up @@ -752,17 +752,22 @@
}

function parseLeftHandSideExpression() {
var expr, property;
var expr, args, property;

expr = parsePrimaryExpression();

while (match('.') || match('[')) {
while (true) {
if (match('[')) {
property = parseComputedMember();
expr = delegate.createMemberExpression('[', expr, property);
} else {
} else if (match('.')) {
property = parseNonComputedMember();
expr = delegate.createMemberExpression('.', expr, property);
} else if (match('(')) {
args = parseArguments();
expr = delegate.createCallExpression(expr, args);
} else {
break;
}
}

Expand Down

0 comments on commit 9864d7b

Please sign in to comment.