@@ -2,19 +2,51 @@ const info = require('property-information')
2
2
3
3
const rootKeys = [ 'class-name' , 'class' , 'style' ]
4
4
5
- function propsToData ( props , doc ) {
5
+ const rxOn = / ^ @ | ^ v - o n : /
6
+ const rxBind = / ^ : | ^ v - b i n d : /
7
+ const rxModel = / ^ v - m o d e l /
8
+ const nativeInputs = [ 'select' , 'textarea' , 'input' ]
9
+
10
+ function evalInContext ( code , context ) {
11
+ return new Function ( "with(this) { return (" + code + ") }" ) . call ( context )
12
+ }
13
+
14
+ function propsToData ( node , doc ) {
15
+ const { tag, props } = node
6
16
return Object . keys ( props ) . reduce ( function ( data , key ) {
7
17
const k = key . replace ( / .* : / , '' )
8
18
let obj = rootKeys . includes ( k ) ? data : data . attrs
9
19
const value = props [ key ]
10
20
const { attribute } = info . find ( info . html , key )
11
-
12
- if ( key === 'v-bind' ) {
13
- const val = value in doc ? doc [ value ] : eval ( `(${ value } )` )
21
+ const native = nativeInputs . includes ( tag )
22
+
23
+ if ( rxModel . test ( key ) && value in doc && ! native ) {
24
+ const mods = key . replace ( rxModel , '' )
25
+ . split ( '.' )
26
+ . filter ( d => d )
27
+ . reduce ( ( d , k ) => ( d [ k ] = true , d ) , { } )
28
+
29
+ // As of yet we don't resolve custom v-model field/event names from components
30
+ const field = 'value'
31
+ const event = mods . lazy ? 'change' : 'input'
32
+ const processor =
33
+ mods . number ? ( d => + d ) :
34
+ mods . trim ? ( d => d . trim ( ) ) :
35
+ d => d
36
+
37
+ obj [ field ] = evalInContext ( value , doc )
38
+ data . on = data . on || { }
39
+ data . on [ event ] = e => doc [ value ] = processor ( e )
40
+ } else if ( key === 'v-bind' ) {
41
+ const val = value in doc ? doc [ value ] : evalInContext ( value , doc )
14
42
obj = Object . assign ( obj , val )
15
- } else if ( key . indexOf ( ':' ) === 0 || key . indexOf ( 'v-bind:' ) === 0 ) {
16
- key = key . replace ( 'v-bind:' , '' ) . replace ( ':' , '' )
17
- obj [ key ] = value in doc ? doc [ value ] : eval ( `(${ value } )` )
43
+ } else if ( rxOn . test ( key ) ) {
44
+ key = key . replace ( rxOn , '' )
45
+ data . on = data . on || { }
46
+ data . on [ key ] = evalInContext ( value , doc )
47
+ } else if ( rxBind . test ( key ) ) {
48
+ key = key . replace ( rxBind , '' )
49
+ obj [ key ] = value in doc ? doc [ value ] : evalInContext ( value , doc )
18
50
} else if ( Array . isArray ( value ) ) {
19
51
obj [ attribute ] = value . join ( ' ' )
20
52
} else {
@@ -56,7 +88,7 @@ function processNode (node, h, doc) {
56
88
}
57
89
58
90
const slotData = slotsToData ( node || { } , h , doc )
59
- const propData = propsToData ( node . props , doc )
91
+ const propData = propsToData ( node || { } , doc )
60
92
const data = Object . assign ( { } , slotData , propData )
61
93
62
94
/**
0 commit comments