@@ -10,8 +10,8 @@ var resolveAsset = _.resolveAsset
10
10
// special binding prefixes
11
11
var bindRE = / ^ v - b i n d : | ^ : /
12
12
var onRE = / ^ v - o n : | ^ @ /
13
- var literalRE = / \. l i t e r a l $ /
14
13
var argRE = / : ( .* ) $ /
14
+ var modifierRE = / \. [ ^ \. ] + / g
15
15
var transitionRE = / ^ ( v - b i n d : | : ) ? t r a n s i t i o n $ /
16
16
17
17
// terminal directives
@@ -480,8 +480,10 @@ function checkComponent (el, options) {
480
480
var descriptor = {
481
481
name : 'component' ,
482
482
expression : component . id ,
483
- literal : ! component . dynamic ,
484
- def : internalDirectives . component
483
+ def : internalDirectives . component ,
484
+ modifiers : {
485
+ literal : ! component . dynamic
486
+ }
485
487
}
486
488
var componentLinkFn = function ( vm , el , host , scope , frag ) {
487
489
vm . _bindDir ( descriptor , el , host , scope , frag )
@@ -568,34 +570,35 @@ function makeTerminalNodeLinkFn (el, dirName, value, options, def) {
568
570
function compileDirectives ( attrs , options ) {
569
571
var i = attrs . length
570
572
var dirs = [ ]
571
- var attr , name , raw , value , dirName , arg , dirDef , isLiteral , tokens
573
+ var attr , name , value , rawName , rawValue , dirName , arg , modifiers , dirDef , tokens
572
574
while ( i -- ) {
573
575
attr = attrs [ i ]
574
- name = attr . name
575
- raw = value = attr . value
576
+ name = rawName = attr . name
577
+ value = rawValue = attr . value
576
578
tokens = textParser . parse ( value )
579
+ // reset arg
580
+ arg = null
581
+ // check modifiers
582
+ modifiers = parseModifiers ( name )
583
+ name = name . replace ( modifierRE , '' )
577
584
578
585
// attribute interpolations
579
586
if ( tokens ) {
580
587
value = textParser . tokensToExp ( tokens )
581
- pushDir ( 'bind' , publicDirectives . bind , {
582
- arg : name ,
583
- interp : true
584
- } )
588
+ arg = name
589
+ pushDir ( 'bind' , publicDirectives . bind , true )
585
590
} else
586
591
587
592
// special attribute: transition
588
593
if ( transitionRE . test ( name ) ) {
589
- pushDir ( 'transition' , internalDirectives . transition , {
590
- literal : ! bindRE . test ( name )
591
- } )
594
+ modifiers . literal = ! bindRE . test ( name )
595
+ pushDir ( 'transition' , internalDirectives . transition )
592
596
} else
593
597
594
598
// event handlers
595
599
if ( onRE . test ( name ) ) {
596
- pushDir ( 'on' , publicDirectives . on , {
597
- arg : name . replace ( onRE , '' )
598
- } )
600
+ arg = name . replace ( onRE , '' )
601
+ pushDir ( 'on' , publicDirectives . on )
599
602
} else
600
603
601
604
// attribute bindings
@@ -604,19 +607,13 @@ function compileDirectives (attrs, options) {
604
607
if ( dirName === 'style' || dirName === 'class' ) {
605
608
pushDir ( dirName , internalDirectives [ dirName ] )
606
609
} else {
607
- pushDir ( 'bind' , publicDirectives . bind , {
608
- arg : dirName
609
- } )
610
+ arg = dirName
611
+ pushDir ( 'bind' , publicDirectives . bind )
610
612
}
611
613
} else
612
614
613
615
// normal directives
614
616
if ( name . indexOf ( 'v-' ) === 0 ) {
615
- // check literal
616
- isLiteral = literalRE . test ( name )
617
- if ( isLiteral ) {
618
- name = name . replace ( literalRE , '' )
619
- }
620
617
// check arg
621
618
arg = ( arg = name . match ( argRE ) ) && arg [ 1 ]
622
619
if ( arg ) {
@@ -637,14 +634,11 @@ function compileDirectives (attrs, options) {
637
634
}
638
635
639
636
if ( dirDef ) {
640
- if ( ! isLiteral && _ . isLiteral ( value ) ) {
637
+ if ( _ . isLiteral ( value ) ) {
641
638
value = _ . stripQuotes ( value )
642
- isLiteral = true
639
+ modifiers . literal = true
643
640
}
644
- pushDir ( dirName , dirDef , {
645
- arg : arg ,
646
- literal : isLiteral
647
- } )
641
+ pushDir ( dirName , dirDef )
648
642
}
649
643
}
650
644
}
@@ -654,30 +648,48 @@ function compileDirectives (attrs, options) {
654
648
*
655
649
* @param {String } dirName
656
650
* @param {Object|Function } def
657
- * @param {Object } [opts ]
651
+ * @param {Boolean } [interp ]
658
652
*/
659
653
660
- function pushDir ( dirName , def , opts ) {
654
+ function pushDir ( dirName , def , interp ) {
661
655
var parsed = dirParser . parse ( value )
662
- var dir = {
656
+ dirs . push ( {
663
657
name : dirName ,
664
- attr : name ,
665
- raw : raw ,
658
+ attr : rawName ,
659
+ raw : rawValue ,
666
660
def : def ,
661
+ arg : arg ,
662
+ modifiers : modifiers ,
667
663
expression : parsed . expression ,
668
- filters : parsed . filters
669
- }
670
- if ( opts ) {
671
- _ . extend ( dir , opts )
672
- }
673
- dirs . push ( dir )
664
+ filters : parsed . filters ,
665
+ interp : interp
666
+ } )
674
667
}
675
668
676
669
if ( dirs . length ) {
677
670
return makeNodeLinkFn ( dirs )
678
671
}
679
672
}
680
673
674
+ /**
675
+ * Parse modifiers from directive attribute name.
676
+ *
677
+ * @param {String } name
678
+ * @return {Object }
679
+ */
680
+
681
+ function parseModifiers ( name ) {
682
+ var res = Object . create ( null )
683
+ var match = name . match ( modifierRE )
684
+ if ( match ) {
685
+ var i = match . length
686
+ while ( i -- ) {
687
+ res [ match [ i ] . slice ( 1 ) ] = true
688
+ }
689
+ }
690
+ return res
691
+ }
692
+
681
693
/**
682
694
* Build a link function for all directives on a single node.
683
695
*
0 commit comments