@@ -21,18 +21,19 @@ module.exports = compile
21
21
22
22
function compile ( el , options , partial , transcluded ) {
23
23
var isBlock = el . nodeType === 11
24
- var params = ! partial && options . paramAttributes
25
- // if el is a fragment, this is a block instance
26
- // and paramAttributes will be stored on the first
27
- // element in the template. (excluding the _blockStart
28
- // comment node)
29
- var paramsEl = isBlock ? el . childNodes [ 1 ] : el
30
- var paramsLinkFn = params
31
- ? compileParamAttributes ( paramsEl , params , options )
24
+ // link function for param attributes.
25
+ var params = options . paramAttributes
26
+ var paramsLinkFn = params && ! partial && ! transcluded && ! isBlock
27
+ ? compileParamAttributes ( el , params , options )
32
28
: null
29
+ // link function for the node itself.
30
+ // if this is a block instance, we return a link function
31
+ // for the attributes found on the container, if any.
32
+ // options._containerAttrs are collected during transclusion.
33
33
var nodeLinkFn = isBlock
34
- ? null
34
+ ? compileBlockContainer ( options . _containerAttrs , params , options )
35
35
: compileNode ( el , options )
36
+ // link function for the childNodes
36
37
var childLinkFn =
37
38
! ( nodeLinkFn && nodeLinkFn . terminal ) &&
38
39
el . tagName !== 'SCRIPT' &&
@@ -41,22 +42,21 @@ function compile (el, options, partial, transcluded) {
41
42
: null
42
43
43
44
/**
44
- * A linker function to be called on a already compiled
45
- * piece of DOM, which instantiates all directive
45
+ * A composite linker function to be called on a already
46
+ * compiled piece of DOM, which instantiates all directive
46
47
* instances.
47
48
*
48
49
* @param {Vue } vm
49
50
* @param {Element|DocumentFragment } el
50
51
* @return {Function|undefined }
51
52
*/
52
53
53
- function linkFn ( vm , el ) {
54
+ function compositeLinkFn ( vm , el ) {
54
55
var originalDirCount = vm . _directives . length
55
56
var parentOriginalDirCount =
56
57
vm . $parent && vm . $parent . _directives . length
57
58
if ( paramsLinkFn ) {
58
- var paramsEl = isBlock ? el . childNodes [ 1 ] : el
59
- paramsLinkFn ( vm , paramsEl )
59
+ paramsLinkFn ( vm , el )
60
60
}
61
61
// cache childNodes before linking parent, fix #657
62
62
var childNodes = _ . toArray ( el . childNodes )
@@ -102,10 +102,44 @@ function compile (el, options, partial, transcluded) {
102
102
// transcluded linkFns are terminal, because it takes
103
103
// over the entire sub-tree.
104
104
if ( transcluded ) {
105
- linkFn . terminal = true
105
+ compositeLinkFn . terminal = true
106
106
}
107
107
108
- return linkFn
108
+ return compositeLinkFn
109
+ }
110
+
111
+ /**
112
+ * Compile the attributes found on a "block container" -
113
+ * i.e. the container node in the parent tempate of a block
114
+ * instance. We are only concerned with v-with and
115
+ * paramAttributes here.
116
+ *
117
+ * @param {Object } attrs - a map of attr name/value pairs
118
+ * @param {Array } params - param attributes list
119
+ * @param {Object } options
120
+ * @return {Function }
121
+ */
122
+
123
+ function compileBlockContainer ( attrs , params , options ) {
124
+ if ( ! attrs ) return null
125
+ var paramsLinkFn = params
126
+ ? compileParamAttributes ( attrs , params , options )
127
+ : null
128
+ var withVal = attrs [ config . prefix + 'with' ]
129
+ var withLinkFn = null
130
+ if ( withVal ) {
131
+ var descriptor = dirParser . parse ( withVal ) [ 0 ]
132
+ var def = options . directives [ 'with' ]
133
+ withLinkFn = function ( vm , el ) {
134
+ vm . _bindDir ( 'with' , el , descriptor , def )
135
+ }
136
+ }
137
+ return function blockContainerLinkFn ( vm ) {
138
+ // explicitly passing null to the linkers
139
+ // since v-with doesn't need a real element
140
+ if ( paramsLinkFn ) paramsLinkFn ( vm , null )
141
+ if ( withLinkFn ) withLinkFn ( vm , null )
142
+ }
109
143
}
110
144
111
145
/**
@@ -363,14 +397,15 @@ function makeChildLinkFn (linkFns) {
363
397
* Compile param attributes on a root element and return
364
398
* a paramAttributes link function.
365
399
*
366
- * @param {Element } el
400
+ * @param {Element|Object } el
367
401
* @param {Array } attrs
368
402
* @param {Object } options
369
403
* @return {Function } paramsLinkFn
370
404
*/
371
405
372
406
function compileParamAttributes ( el , attrs , options ) {
373
407
var params = [ ]
408
+ var isEl = el . nodeType
374
409
var i = attrs . length
375
410
var name , value , param
376
411
while ( i -- ) {
@@ -384,15 +419,15 @@ function compileParamAttributes (el, attrs, options) {
384
419
'http://vuejs.org/api/options.html#paramAttributes'
385
420
)
386
421
}
387
- value = el . getAttribute ( name )
422
+ value = isEl ? el . getAttribute ( name ) : el [ name ]
388
423
if ( value !== null ) {
389
424
param = {
390
425
name : name ,
391
426
value : value
392
427
}
393
428
var tokens = textParser . parse ( value )
394
429
if ( tokens ) {
395
- el . removeAttribute ( name )
430
+ if ( isEl ) el . removeAttribute ( name )
396
431
if ( tokens . length > 1 ) {
397
432
_ . warn (
398
433
'Invalid param attribute binding: "' +
0 commit comments