Skip to content

Commit 9dc45ea

Browse files
author
Evan You
committed
sd-on can now execute expressions
1 parent 3dc6089 commit 9dc45ea

File tree

6 files changed

+44
-22
lines changed

6 files changed

+44
-22
lines changed

src/binding.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
* which has multiple directive instances on the DOM
66
* and multiple computed property dependents
77
*/
8-
function Binding (compiler, key, isExp) {
8+
function Binding (compiler, key, isExp, isFn) {
99
this.value = undefined
1010
this.isExp = !!isExp
11+
this.isFn = isFn
1112
this.root = !this.isExp && key.indexOf('.') === -1
1213
this.compiler = compiler
1314
this.key = key

src/compiler.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ CompilerProto.bindDirective = function (directive) {
368368

369369
if (directive.isExp) {
370370
// expression bindings are always created on current compiler
371-
binding = compiler.createBinding(key, true)
371+
binding = compiler.createBinding(key, true, directive.isFn)
372372
} else if (ownerCompiler.vm.hasOwnProperty(baseKey)) {
373373
// If the directive's owner compiler's VM has the key,
374374
// it belongs there. Create the binding if it's not already
@@ -415,28 +415,32 @@ CompilerProto.bindDirective = function (directive) {
415415
/**
416416
* Create binding and attach getter/setter for a key to the viewmodel object
417417
*/
418-
CompilerProto.createBinding = function (key, isExp) {
418+
CompilerProto.createBinding = function (key, isExp, isFn) {
419419

420420
var compiler = this,
421421
bindings = compiler.bindings,
422-
binding = new Binding(compiler, key, isExp)
422+
binding = new Binding(compiler, key, isExp, isFn)
423423

424424
if (isExp) {
425425
// a complex expression binding
426426
// we need to generate an anonymous computed property for it
427427
var result = ExpParser.parse(key)
428428
if (result) {
429429
log(' created anonymous binding: ' + key)
430-
binding.value = { get: result.getter }
430+
binding.value = isFn
431+
? result.getter
432+
: { get: result.getter }
431433
compiler.markComputed(binding)
432434
compiler.exps.push(binding)
433435
// need to create the bindings for keys
434436
// that do not exist yet
435-
var i = result.paths.length, v
436-
while (i--) {
437-
v = result.paths[i]
438-
if (!bindings[v]) {
439-
compiler.rootCompiler.createBinding(v)
437+
if (result.paths) {
438+
var i = result.paths.length, v
439+
while (i--) {
440+
v = result.paths[i]
441+
if (!bindings[v]) {
442+
compiler.rootCompiler.createBinding(v)
443+
}
440444
}
441445
}
442446
} else {
@@ -548,8 +552,12 @@ CompilerProto.markComputed = function (binding) {
548552
vm = this.vm
549553
binding.isComputed = true
550554
// bind the accessors to the vm
551-
value.get = value.get.bind(vm)
552-
if (value.set) value.set = value.set.bind(vm)
555+
if (binding.isFn) {
556+
binding.value = value.bind(vm)
557+
} else {
558+
value.get = value.get.bind(vm)
559+
if (value.set) value.set = value.set.bind(vm)
560+
}
553561
// keep track for dep parsing later
554562
this.computed.push(binding)
555563
}

src/deps-parser.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var Emitter = require('./emitter'),
77
* by recording the getters triggered when evaluating it.
88
*/
99
function catchDeps (binding) {
10+
if (binding.isFn) return
1011
utils.log('\n─ ' + binding.key)
1112
var depsHash = utils.hash()
1213
observer.on('get', function (dep) {

src/directive.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,17 @@ DirProto.refresh = function (value) {
142142
// pass element and viewmodel info to the getter
143143
// enables context-aware bindings
144144
if (value) this.value = value
145-
value = this.value.get({
146-
el: this.el,
147-
vm: this.vm
148-
})
149-
if (value !== undefined && value === this.computedValue) return
150-
this.computedValue = value
145+
146+
if (this.isFn) {
147+
value = this.value
148+
} else {
149+
value = this.value.get({
150+
el: this.el,
151+
vm: this.vm
152+
})
153+
if (value !== undefined && value === this.computedValue) return
154+
this.computedValue = value
155+
}
151156
this.apply(value)
152157
}
153158

src/directives/on.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ function delegateCheck (current, top, identifier) {
1212

1313
module.exports = {
1414

15+
isFn: true,
16+
1517
bind: function () {
1618
if (this.compiler.repeat) {
1719
// attach an identifier to the el
@@ -23,7 +25,6 @@ module.exports = {
2325
},
2426

2527
update: function (handler) {
26-
2728
this.unbind(true)
2829
if (typeof handler !== 'function') {
2930
return utils.warn('Directive "on" expects a function value.')

src/exp-parser.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ var KEYWORDS =
1111
',package,private,protected,public,short,static,super,synchronized' +
1212
',throws,transient,volatile' +
1313
// ECMA 5 - use strict
14-
',arguments,let,yield',
14+
',arguments,let,yield' +
15+
// skip
16+
',window',
1517

1618
KEYWORDS_RE = new RegExp(["\\b" + KEYWORDS.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g'),
1719
REMOVE_RE = /\/\*(?:.|\n)*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|'[^']*'|"[^"]*"|[\s\t\n]*\.[\s\t\n]*[$\w\.]+/g,
@@ -52,9 +54,14 @@ module.exports = {
5254
* created as bindings.
5355
*/
5456
parse: function (exp) {
57+
/* jshint evil: true */
5558
// extract variable names
5659
var vars = getVariables(exp)
57-
if (!vars.length) return null
60+
if (!vars.length) {
61+
return {
62+
getter: new Function('return ' + exp)
63+
}
64+
}
5865
var args = [],
5966
v, i, keyPrefix,
6067
l = vars.length,
@@ -73,7 +80,6 @@ module.exports = {
7380
))
7481
}
7582
args = 'var ' + args.join(',') + ';return ' + exp
76-
/* jshint evil: true */
7783
return {
7884
getter: new Function(args),
7985
paths: getPaths(exp, Object.keys(hash))

0 commit comments

Comments
 (0)