Explorar o código

fix #655 directives on placeholders for block instances are not compiled

Evan You %!s(int64=11) %!d(string=hai) anos
pai
achega
c14410cca0

+ 12 - 3
src/compiler/compile.js

@@ -25,11 +25,17 @@ var templateParser = require('../parsers/template')
  */
 
 module.exports = function compile (el, options, partial, asParent) {
+  var isBlock = el.nodeType === 11
   var params = !partial && options.paramAttributes
+  // if el is a fragment, this is a block instance
+  // and paramAttributes will be stored on the first
+  // element in the template. (excluding the _blockStart
+  // comment node)
+  var paramsEl = isBlock ? el.childNodes[1] : el
   var paramsLinkFn = params
-    ? compileParamAttributes(el, params, options)
+    ? compileParamAttributes(paramsEl, params, options)
     : null
-  var nodeLinkFn = el instanceof DocumentFragment
+  var nodeLinkFn = isBlock
     ? null
     : compileNode(el, options, asParent)
   var childLinkFn =
@@ -51,7 +57,10 @@ module.exports = function compile (el, options, partial, asParent) {
 
   return function link (vm, el) {
     var originalDirCount = vm._directives.length
-    if (paramsLinkFn) paramsLinkFn(vm, el)
+    if (paramsLinkFn) {
+      var paramsEl = isBlock ? el.childNodes[1] : el
+      paramsLinkFn(vm, paramsEl)
+    }
     // cache childNodes before linking parent, fix #657
     var childNodes = _.toArray(el.childNodes)
     if (nodeLinkFn) nodeLinkFn(vm, el)

+ 1 - 3
src/compiler/transclude.js

@@ -48,9 +48,7 @@ function transcludeTemplate (el, options) {
     if (options.replace) {
       if (frag.childNodes.length > 1) {
         transcludeContent(frag, rawContent)
-        // TODO: store directives on placeholder node
-        // and compile it somehow
-        // probably only check for v-with, v-ref & paramAttributes
+        _.copyAttributes(el, frag.firstChild)
         return frag
       } else {
         var replacer = frag.firstChild

+ 2 - 1
src/instance/compile.js

@@ -75,7 +75,8 @@ exports._compile = function (el) {
 exports._initElement = function (el) {
   if (el instanceof DocumentFragment) {
     this._isBlock = true
-    this.$el = this._blockStart = el.firstChild
+    this._blockStart = el.firstChild
+    this.$el = el.childNodes[1]
     this._blockEnd = el.lastChild
     this._blockFragment = el
   } else {

+ 14 - 7
test/unit/specs/api/dom_spec.js

@@ -41,7 +41,8 @@ if (_.inBrowser) {
       it('block instance', function () {
         vm2.$appendTo(parent, spy)
         expect(parent.childNodes.length).toBe(6)
-        expect(parent.childNodes[2]).toBe(vm2.$el)
+        expect(parent.childNodes[2]).toBe(vm2._blockStart)
+        expect(parent.childNodes[3]).toBe(vm2.$el)
         expect(parent.childNodes[3].tagName).toBe('P')
         expect(parent.childNodes[4].tagName).toBe('SPAN')
         expect(parent.childNodes[5]).toBe(vm2._blockEnd)
@@ -66,7 +67,8 @@ if (_.inBrowser) {
       it('block instance', function () {
         vm2.$prependTo(parent, spy)
         expect(parent.childNodes.length).toBe(6)
-        expect(parent.childNodes[0]).toBe(vm2.$el)
+        expect(parent.childNodes[0]).toBe(vm2._blockStart)
+        expect(parent.childNodes[1]).toBe(vm2.$el)
         expect(parent.childNodes[1].tagName).toBe('P')
         expect(parent.childNodes[2].tagName).toBe('SPAN')
         expect(parent.childNodes[3]).toBe(vm2._blockEnd)
@@ -74,7 +76,8 @@ if (_.inBrowser) {
         // empty
         vm2.$prependTo(empty, spy)
         expect(empty.childNodes.length).toBe(4)
-        expect(empty.childNodes[0]).toBe(vm2.$el)
+        expect(empty.childNodes[0]).toBe(vm2._blockStart)
+        expect(empty.childNodes[1]).toBe(vm2.$el)
         expect(empty.childNodes[1].tagName).toBe('P')
         expect(empty.childNodes[2].tagName).toBe('SPAN')
         expect(empty.childNodes[3]).toBe(vm2._blockEnd)
@@ -95,7 +98,8 @@ if (_.inBrowser) {
       it('block instance', function () {
         vm2.$before(sibling, spy)
         expect(parent.childNodes.length).toBe(6)
-        expect(parent.childNodes[1]).toBe(vm2.$el)
+        expect(parent.childNodes[1]).toBe(vm2._blockStart)
+        expect(parent.childNodes[2]).toBe(vm2.$el)
         expect(parent.childNodes[2].tagName).toBe('P')
         expect(parent.childNodes[3].tagName).toBe('SPAN')
         expect(parent.childNodes[4]).toBe(vm2._blockEnd)
@@ -123,7 +127,8 @@ if (_.inBrowser) {
       it('block instance', function () {
         vm2.$after(target, spy)
         expect(parent.childNodes.length).toBe(6)
-        expect(parent.childNodes[1]).toBe(vm2.$el)
+        expect(parent.childNodes[1]).toBe(vm2._blockStart)
+        expect(parent.childNodes[2]).toBe(vm2.$el)
         expect(parent.childNodes[2].tagName).toBe('P')
         expect(parent.childNodes[3].tagName).toBe('SPAN')
         expect(parent.childNodes[4]).toBe(vm2._blockEnd)
@@ -133,7 +138,8 @@ if (_.inBrowser) {
       it('block instance no next sibling', function () {
         vm2.$after(sibling, spy)
         expect(parent.childNodes.length).toBe(6)
-        expect(parent.childNodes[2]).toBe(vm2.$el)
+        expect(parent.childNodes[2]).toBe(vm2._blockStart)
+        expect(parent.childNodes[3]).toBe(vm2.$el)
         expect(parent.childNodes[3].tagName).toBe('P')
         expect(parent.childNodes[4].tagName).toBe('SPAN')
         expect(parent.childNodes[5]).toBe(vm2._blockEnd)
@@ -158,7 +164,8 @@ if (_.inBrowser) {
       it('block instance', function () {
         vm2.$before(sibling)
         expect(parent.childNodes.length).toBe(6)
-        expect(parent.childNodes[1]).toBe(vm2.$el)
+        expect(parent.childNodes[1]).toBe(vm2._blockStart)
+        expect(parent.childNodes[2]).toBe(vm2.$el)
         expect(parent.childNodes[2].tagName).toBe('P')
         expect(parent.childNodes[3].tagName).toBe('SPAN')
         expect(parent.childNodes[4]).toBe(vm2._blockEnd)

+ 6 - 6
test/unit/specs/api/lifecycle_spec.js

@@ -96,9 +96,9 @@ if (_.inBrowser) {
           data: { test: 'frag' }
         })
         vm.$mount(frag)
-        expect(vm.$el).toBe(vm._blockStart)
+        expect(vm.$el).toBe(vm._blockStart.nextSibling)
         expect(vm._blockFragment).toBe(frag)
-        expect(vm.$el.nextSibling.textContent).toBe('frag')
+        expect(vm.$el.textContent).toBe('frag')
       })
 
       it('replace fragment', function () {
@@ -106,12 +106,12 @@ if (_.inBrowser) {
         var vm = new Vue({
           replace: true,
           data: { test: 'hi!' },
-          template: '<div>{{test}}</div><div>{{test}}</div>'
+          template: '<div>{{test}}</div><div>{{test + "!"}}</div>'
         })
         vm.$mount(el)
-        expect(vm.$el.nextSibling).not.toBe(el)
-        expect(vm.$el.nextSibling.textContent).toBe('hi!')
-        expect(vm.$el.nextSibling.nextSibling.textContent).toBe('hi!')
+        expect(vm.$el).not.toBe(el)
+        expect(vm.$el.textContent).toBe('hi!')
+        expect(vm.$el.nextSibling.textContent).toBe('hi!!')
         expect(document.body.contains(el)).toBe(false)
         expect(document.body.lastChild).toBe(vm._blockEnd)
         vm.$remove()

+ 19 - 0
test/unit/specs/directives/with_spec.js

@@ -133,5 +133,24 @@ if (_.inBrowser) {
       expect(_.warn).toHaveBeenCalled()
     })
 
+    it('block instance with replace:true', function () {
+      var vm = new Vue({
+        el: el,
+        template: '<div v-component="test" v-with="b:a" c="{{d}}"></div>',
+        data: {
+          a: 'AAA',
+          d: 'DDD'
+        },
+        components: {
+          test: {
+            paramAttributes: ['c'],
+            template: '<p>{{b}}</p><p>{{c}}</p>',
+            replace: true
+          }
+        }
+      })
+      expect(el.innerHTML).toBe('<!--v-start--><p>AAA</p><p>DDD</p><!--v-end--><!--v-component-->')
+    })
+
   })
 }