1
1
/*
2
- VueJS v0.7.2
3
- (c) 2013 Evan You
2
+ VueJS v0.7.3
3
+ (c) 2014 Evan You
4
4
License: MIT
5
5
*/
6
6
; ( function ( ) {
@@ -441,6 +441,7 @@ ViewModel.transition = function (id, transition) {
441
441
}
442
442
443
443
ViewModel . extend = extend
444
+ ViewModel . nextTick = utils . nextTick
444
445
445
446
/**
446
447
* Expose the main ViewModel class
@@ -1042,15 +1043,15 @@ CompilerProto.compile = function (node, root) {
1042
1043
if ( repeatExp = utils . attr ( node , 'repeat' ) ) {
1043
1044
1044
1045
// repeat block cannot have v-id at the same time.
1045
- directive = Directive . parse ( config . attrs . repeat , repeatExp , compiler , node )
1046
+ directive = Directive . parse ( ' repeat' , repeatExp , compiler , node )
1046
1047
if ( directive ) {
1047
1048
compiler . bindDirective ( directive )
1048
1049
}
1049
1050
1050
1051
// v-component has 2nd highest priority
1051
1052
} else if ( ! root && ( componentExp = utils . attr ( node , 'component' ) ) ) {
1052
1053
1053
- directive = Directive . parse ( config . attrs . component , componentExp , compiler , node )
1054
+ directive = Directive . parse ( ' component' , componentExp , compiler , node )
1054
1055
if ( directive ) {
1055
1056
// component directive is a bit different from the others.
1056
1057
// when it has no argument, it should be treated as a
@@ -1093,28 +1094,44 @@ CompilerProto.compile = function (node, root) {
1093
1094
* Compile a normal node
1094
1095
*/
1095
1096
CompilerProto . compileNode = function ( node ) {
1096
- var i , j , attrs = node . attributes
1097
+ var i , j ,
1098
+ attrs = node . attributes ,
1099
+ prefix = config . prefix + '-'
1097
1100
// parse if has attributes
1098
1101
if ( attrs && attrs . length ) {
1099
- var attr , valid , exps , exp
1102
+ var attr , isDirective , exps , exp , directive
1100
1103
// loop through all attributes
1101
1104
i = attrs . length
1102
1105
while ( i -- ) {
1103
1106
attr = attrs [ i ]
1104
- valid = false
1105
- exps = Directive . split ( attr . value )
1106
- // loop through clauses (separated by ",")
1107
- // inside each attribute
1108
- j = exps . length
1109
- while ( j -- ) {
1110
- exp = exps [ j ]
1111
- var directive = Directive . parse ( attr . name , exp , this , node )
1112
- if ( directive ) {
1113
- valid = true
1114
- this . bindDirective ( directive )
1107
+ isDirective = false
1108
+
1109
+ if ( attr . name . indexOf ( prefix ) === 0 ) {
1110
+ // a directive - split, parse and bind it.
1111
+ isDirective = true
1112
+ exps = Directive . split ( attr . value )
1113
+ // loop through clauses (separated by ",")
1114
+ // inside each attribute
1115
+ j = exps . length
1116
+ while ( j -- ) {
1117
+ exp = exps [ j ]
1118
+ directive = Directive . parse ( attr . name . slice ( prefix . length ) , exp , this , node )
1119
+ if ( directive ) {
1120
+ this . bindDirective ( directive )
1121
+ }
1122
+ }
1123
+ } else {
1124
+ // non directive attribute, check interpolation tags
1125
+ exp = TextParser . parseAttr ( attr . value )
1126
+ if ( exp ) {
1127
+ directive = Directive . parse ( 'attr' , attr . name + ':' + exp , this , node )
1128
+ if ( directive ) {
1129
+ this . bindDirective ( directive )
1130
+ }
1115
1131
}
1116
1132
}
1117
- if ( valid ) node . removeAttribute ( attr . name )
1133
+
1134
+ if ( isDirective ) node . removeAttribute ( attr . name )
1118
1135
}
1119
1136
}
1120
1137
// recursively compile childNodes
@@ -1132,8 +1149,7 @@ CompilerProto.compileNode = function (node) {
1132
1149
CompilerProto . compileTextNode = function ( node ) {
1133
1150
var tokens = TextParser . parse ( node . nodeValue )
1134
1151
if ( ! tokens ) return
1135
- var dirname = config . attrs . text ,
1136
- el , token , directive
1152
+ var el , token , directive
1137
1153
for ( var i = 0 , l = tokens . length ; i < l ; i ++ ) {
1138
1154
token = tokens [ i ]
1139
1155
if ( token . key ) { // a binding
@@ -1146,7 +1162,7 @@ CompilerProto.compileTextNode = function (node) {
1146
1162
}
1147
1163
} else { // a binding
1148
1164
el = document . createTextNode ( '' )
1149
- directive = Directive . parse ( dirname , token . key , this , el )
1165
+ directive = Directive . parse ( 'text' , token . key , this , el )
1150
1166
if ( directive ) {
1151
1167
this . bindDirective ( directive )
1152
1168
}
@@ -1478,7 +1494,15 @@ def(VMProto, '$set', function (key, value) {
1478
1494
* fire callback with new value
1479
1495
*/
1480
1496
def ( VMProto , '$watch' , function ( key , callback ) {
1481
- this . $compiler . observer . on ( 'change:' + key , callback )
1497
+ var self = this
1498
+ function on ( ) {
1499
+ var args = arguments
1500
+ utils . nextTick ( function ( ) {
1501
+ callback . apply ( self , args )
1502
+ } )
1503
+ }
1504
+ callback . _fn = on
1505
+ self . $compiler . observer . on ( 'change:' + key , on )
1482
1506
} )
1483
1507
1484
1508
/**
@@ -1490,7 +1514,7 @@ def(VMProto, '$unwatch', function (key, callback) {
1490
1514
// by checking the length of arguments
1491
1515
var args = [ 'change:' + key ] ,
1492
1516
ob = this . $compiler . observer
1493
- if ( callback ) args . push ( callback )
1517
+ if ( callback ) args . push ( callback . _fn )
1494
1518
ob . off . apply ( ob , args )
1495
1519
} )
1496
1520
@@ -1518,20 +1542,20 @@ def(VMProto, '$broadcast', function () {
1518
1542
/**
1519
1543
* emit an event that propagates all the way up to parent VMs.
1520
1544
*/
1521
- def ( VMProto , '$emit ' , function ( ) {
1545
+ def ( VMProto , '$dispatch ' , function ( ) {
1522
1546
var compiler = this . $compiler ,
1523
1547
emitter = compiler . emitter ,
1524
1548
parent = compiler . parentCompiler
1525
1549
emitter . emit . apply ( emitter , arguments )
1526
1550
if ( parent ) {
1527
- parent . vm . $emit . apply ( parent . vm , arguments )
1551
+ parent . vm . $dispatch . apply ( parent . vm , arguments )
1528
1552
}
1529
1553
} )
1530
1554
1531
1555
/**
1532
1556
* delegate on/off/once to the compiler's emitter
1533
1557
*/
1534
- ; [ 'on' , 'off' , 'once' ] . forEach ( function ( method ) {
1558
+ ; [ 'emit' , ' on', 'off' , 'once' ] . forEach ( function ( method ) {
1535
1559
def ( VMProto , '$' + method , function ( ) {
1536
1560
var emitter = this . $compiler . emitter
1537
1561
emitter [ method ] . apply ( emitter , arguments )
@@ -2016,8 +2040,7 @@ module.exports = {
2016
2040
}
2017
2041
} ) ;
2018
2042
require . register ( "vue/src/directive.js" , function ( exports , require , module ) {
2019
- var config = require ( './config' ) ,
2020
- utils = require ( './utils' ) ,
2043
+ var utils = require ( './utils' ) ,
2021
2044
directives = require ( './directives' ) ,
2022
2045
filters = require ( './filters' ) ,
2023
2046
@@ -2219,10 +2242,6 @@ Directive.split = function (exp) {
2219
2242
*/
2220
2243
Directive . parse = function ( dirname , expression , compiler , node ) {
2221
2244
2222
- var prefix = config . prefix + '-'
2223
- if ( dirname . indexOf ( prefix ) !== 0 ) return
2224
- dirname = dirname . slice ( prefix . length )
2225
-
2226
2245
var dir = compiler . getOption ( 'directives' , dirname ) || directives [ dirname ]
2227
2246
if ( ! dir ) return utils . warn ( 'unknown directive: ' + dirname )
2228
2247
@@ -2394,26 +2413,40 @@ module.exports = {
2394
2413
require . register ( "vue/src/text-parser.js" , function ( exports , require , module ) {
2395
2414
var BINDING_RE = / \{ \{ ( .+ ?) \} \} /
2396
2415
2397
- module . exports = {
2416
+ /**
2417
+ * Parse a piece of text, return an array of tokens
2418
+ */
2419
+ function parse ( text ) {
2420
+ if ( ! BINDING_RE . test ( text ) ) return null
2421
+ var m , i , tokens = [ ]
2422
+ /* jshint boss: true */
2423
+ while ( m = text . match ( BINDING_RE ) ) {
2424
+ i = m . index
2425
+ if ( i > 0 ) tokens . push ( text . slice ( 0 , i ) )
2426
+ tokens . push ( { key : m [ 1 ] . trim ( ) } )
2427
+ text = text . slice ( i + m [ 0 ] . length )
2428
+ }
2429
+ if ( text . length ) tokens . push ( text )
2430
+ return tokens
2431
+ }
2398
2432
2399
- /**
2400
- * Parse a piece of text, return an array of tokens
2401
- */
2402
- parse : function ( text ) {
2403
- if ( ! BINDING_RE . test ( text ) ) return null
2404
- var m , i , tokens = [ ]
2405
- /* jshint boss: true */
2406
- while ( m = text . match ( BINDING_RE ) ) {
2407
- i = m . index
2408
- if ( i > 0 ) tokens . push ( text . slice ( 0 , i ) )
2409
- tokens . push ( { key : m [ 1 ] . trim ( ) } )
2410
- text = text . slice ( i + m [ 0 ] . length )
2411
- }
2412
- if ( text . length ) tokens . push ( text )
2413
- return tokens
2433
+ /**
2434
+ * Parse an attribute value with possible interpolation tags
2435
+ * return a Directive-friendly expression
2436
+ */
2437
+ function parseAttr ( attr ) {
2438
+ var tokens = parse ( attr )
2439
+ if ( ! tokens ) return null
2440
+ var res = [ ] , token
2441
+ for ( var i = 0 , l = tokens . length ; i < l ; i ++ ) {
2442
+ token = tokens [ i ]
2443
+ res . push ( token . key || ( '"' + token + '"' ) )
2414
2444
}
2415
-
2445
+ return res . join ( '+' )
2416
2446
}
2447
+
2448
+ exports . parse = parse
2449
+ exports . parseAttr = parseAttr
2417
2450
} ) ;
2418
2451
require . register ( "vue/src/deps-parser.js" , function ( exports , require , module ) {
2419
2452
var Emitter = require ( './emitter' ) ,
@@ -2426,13 +2459,13 @@ var Emitter = require('./emitter'),
2426
2459
*/
2427
2460
function catchDeps ( binding ) {
2428
2461
if ( binding . isFn ) return
2429
- utils . log ( '\n─ ' + binding . key )
2462
+ utils . log ( '\n- ' + binding . key )
2430
2463
var got = utils . hash ( )
2431
2464
observer . on ( 'get' , function ( dep ) {
2432
2465
var has = got [ dep . key ]
2433
2466
if ( has && has . compiler === dep . compiler ) return
2434
2467
got [ dep . key ] = dep
2435
- utils . log ( ' └─ ' + dep . key )
2468
+ utils . log ( ' - ' + dep . key )
2436
2469
binding . deps . push ( dep )
2437
2470
dep . subs . push ( binding )
2438
2471
} )
@@ -2983,7 +3016,7 @@ module.exports = {
2983
3016
self . hasTrans = el . hasAttribute ( config . attrs . transition )
2984
3017
2985
3018
// create a comment node as a reference node for DOM insertions
2986
- self . ref = document . createComment ( config . prefix + '-repeat-' + self . arg )
3019
+ self . ref = document . createComment ( config . prefix + '-repeat-' + self . key )
2987
3020
ctn . insertBefore ( self . ref , el )
2988
3021
ctn . removeChild ( el )
2989
3022
@@ -3206,16 +3239,29 @@ module.exports = {
3206
3239
? 'change'
3207
3240
: 'input'
3208
3241
3209
- // determin the attribute to change when updating
3242
+ // determine the attribute to change when updating
3210
3243
var attr = self . attr = type === 'checkbox'
3211
3244
? 'checked'
3212
3245
: ( tag === 'INPUT' || tag === 'SELECT' || tag === 'TEXTAREA' )
3213
3246
? 'value'
3214
3247
: 'innerHTML'
3215
3248
3249
+ if ( self . filters ) {
3250
+ var compositionLock = false
3251
+ this . cLock = function ( ) {
3252
+ compositionLock = true
3253
+ }
3254
+ this . cUnlock = function ( ) {
3255
+ compositionLock = false
3256
+ }
3257
+ el . addEventListener ( 'compositionstart' , this . cLock )
3258
+ el . addEventListener ( 'compositionend' , this . cUnlock )
3259
+ }
3260
+
3216
3261
// attach listener
3217
3262
self . set = self . filters
3218
3263
? function ( ) {
3264
+ if ( compositionLock ) return
3219
3265
// if this directive has filters
3220
3266
// we need to let the vm.$set trigger
3221
3267
// update() so filters are applied.
@@ -3239,7 +3285,9 @@ module.exports = {
3239
3285
// no filters, don't let it trigger update()
3240
3286
self . lock = true
3241
3287
self . vm . $set ( self . key , el [ attr ] )
3242
- self . lock = false
3288
+ utils . nextTick ( function ( ) {
3289
+ self . lock = false
3290
+ } )
3243
3291
}
3244
3292
el . addEventListener ( self . event , self . set )
3245
3293
@@ -3289,10 +3337,15 @@ module.exports = {
3289
3337
} ,
3290
3338
3291
3339
unbind : function ( ) {
3292
- this . el . removeEventListener ( this . event , this . set )
3340
+ var el = this . el
3341
+ el . removeEventListener ( this . event , this . set )
3342
+ if ( this . filters ) {
3343
+ el . removeEventListener ( 'compositionstart' , this . cLock )
3344
+ el . removeEventListener ( 'compositionend' , this . cUnlock )
3345
+ }
3293
3346
if ( isIE9 ) {
3294
- this . el . removeEventListener ( 'cut' , this . onCut )
3295
- this . el . removeEventListener ( 'keyup' , this . onDel )
3347
+ el . removeEventListener ( 'cut' , this . onCut )
3348
+ el . removeEventListener ( 'keyup' , this . onDel )
3296
3349
}
3297
3350
}
3298
3351
}
@@ -3338,7 +3391,8 @@ module.exports = {
3338
3391
require . alias ( "component-emitter/index.js" , "vue/deps/emitter/index.js" ) ;
3339
3392
require . alias ( "component-emitter/index.js" , "emitter/index.js" ) ;
3340
3393
3341
- require . alias ( "vue/src/main.js" , "vue/index.js" ) ; if ( typeof exports == "object" ) {
3394
+ require . alias ( "vue/src/main.js" , "vue/index.js" ) ;
3395
+ if ( typeof exports == "object" ) {
3342
3396
module . exports = require ( "vue" ) ;
3343
3397
} else if ( typeof define == "function" && define . amd ) {
3344
3398
define ( function ( ) { return require ( "vue" ) ; } ) ;
0 commit comments