Browse Source

tests for transclusion

Evan You 11 years ago
parent
commit
f38d395b8f

+ 1 - 0
src/compile/transclude.js

@@ -66,6 +66,7 @@ function transcludeTemplate (el, options) {
       }
     } else {
       el.appendChild(frag)
+      transcludeContent(el)
       return el
     }
   }

+ 7 - 0
src/instance/compile.js

@@ -1,3 +1,4 @@
+var _ = require('../util')
 var Directive = require('../directive')
 var compile = require('../compile/compile')
 var transclude = require('../compile/transclude')
@@ -12,6 +13,7 @@ var transclude = require('../compile/transclude')
  * Otherwise we need to call transclude/compile/link here.
  *
  * @param {Element} el
+ * @return {Element}
  */
 
 exports._compile = function (el) {
@@ -20,11 +22,16 @@ exports._compile = function (el) {
     this._initElement(el)
     options._linker(this, el)
   } else {
+    var raw = el
     el = transclude(el, options)
     this._initElement(el)
     var linker = compile(el, options)
     linker(this, el)
+    if (options.replace) {
+      _.replace(raw, el)
+    }
   }
+  return el
 }
 
 /**

+ 3 - 1
src/util/dom.js

@@ -91,7 +91,9 @@ exports.prepend = function (el, target) {
 
 exports.replace = function (target, el) {
   var parent = target.parentNode
-  parent.replaceChild(el, target)
+  if (parent) {
+    parent.replaceChild(el, target)
+  }
 }
 
 /**

+ 33 - 0
test/unit/specs/api/lifecycle_spec.js

@@ -46,6 +46,23 @@ if (_.inBrowser) {
         vm.$mount('#none-exist')
         expect(_.warn).toHaveBeenCalled()
       })
+
+      it('replace', function () {
+        el.className = 'replace-test'
+        document.body.appendChild(el)
+        var vm = new Vue({
+          replace: true,
+          data: { test: 'hi!' },
+          template: '<div>{{test}}</div>'
+        })
+        vm.$mount(el)
+        expect(vm.$el).not.toBe(el)
+        expect(vm.$el.textContent).toBe('hi!')
+        expect(document.body.contains(el)).toBe(false)
+        expect(document.body.lastChild).toBe(vm.$el)
+        expect(vm.$el.className).toBe('replace-test')
+        document.body.removeChild(vm.$el)
+      })
       
       it('precompiled linker', function () {
         var linker = compile(el, Vue.options)
@@ -71,6 +88,22 @@ if (_.inBrowser) {
         expect(vm.$el.nextSibling.textContent).toBe('frag')
       })
 
+      it('replace fragment', function () {
+        document.body.appendChild(el)
+        var vm = new Vue({
+          replace: true,
+          data: { test: 'hi!' },
+          template: '<div>{{test}}</div><div>{{test}}</div>'
+        })
+        vm.$mount(el)
+        expect(vm.$el).not.toBe(el)
+        expect(vm.$el.nextSibling.textContent).toBe('hi!')
+        expect(vm.$el.nextSibling.nextSibling.textContent).toBe('hi!')
+        expect(document.body.contains(el)).toBe(false)
+        expect(document.body.lastChild).toBe(vm._blockEnd)
+        vm.$remove()
+      })
+
       it('hooks', function () {
         var hooks = ['created', 'beforeCompile', 'compiled', 'attached', 'ready']
         var options = {

+ 5 - 0
test/unit/specs/compile/compile_spec.js

@@ -0,0 +1,5 @@
+var compile = require('../../../../src/compile/compile')
+
+describe('Compile', function () {
+  // body...
+})

+ 91 - 0
test/unit/specs/compile/transclude_spec.js

@@ -0,0 +1,91 @@
+var transclude = require('../../../../src/compile/transclude')
+var _ = require('../../../../src/util')
+
+if (_.inBrowser) {
+  describe('Transclude', function () {
+
+    var el, options
+    beforeEach(function () {
+      el = document.createElement('div')
+      options = {}
+      spyOn(_, 'warn')
+    })
+
+    it('normal', function () {
+      var res = transclude(el, options)
+      expect(res).toBe(el)
+    })
+
+    it('template', function () {
+      options.template = '{{hi}}'
+      var res = transclude(el, options)
+      expect(res).toBe(el)
+      expect(res.innerHTML).toBe('{{hi}}')
+    })
+
+    it('template invalid', function () {
+      options.template = '#non-existent-stuff'
+      var res = transclude(el, options)
+      expect(res).toBeUndefined()
+      expect(_.warn).toHaveBeenCalled()
+    })
+
+    it('template replace', function () {
+      el.className = 'hello'
+      options.template = '<div>{{hi}}</div>'
+      options.replace = true
+      var res = transclude(el, options)
+      expect(res).not.toBe(el)
+      expect(res.tagName).toBe('DIV')
+      expect(res.className).toBe('hello')
+      expect(res.innerHTML).toBe('{{hi}}')
+    })
+
+    it('block instance', function () {
+      var frag = document.createDocumentFragment()
+      frag.appendChild(el)
+      var res = transclude(frag, options)
+      expect(res).toBe(frag)
+      expect(res.childNodes.length).toBe(3)
+      expect(res.firstChild.nodeType).toBe(8)
+      expect(res.lastChild.nodeType).toBe(8)
+    })
+
+    it('content transclusion', function () {
+      el.innerHTML = '<p>hi</p>'
+      options.template = '<div><content></content></div>'
+      var res = transclude(el, options)
+      expect(res.firstChild.tagName).toBe('DIV')
+      expect(res.firstChild.firstChild.tagName).toBe('P')
+      expect(res.firstChild.firstChild.textContent).toBe('hi')
+    })
+
+    it('fallback content', function () {
+      options.template = '<content><p>fallback</p></content>'
+      var res = transclude(el, options)
+      expect(res.firstChild.tagName).toBe('P')
+      expect(res.firstChild.textContent).toBe('fallback')
+    })
+
+    it('content transclusion with replace', function () {
+      el.innerHTML = '<p>hi</p>'
+      options.template = '<div><div><content></content></div></div>'
+      options.replace = true
+      var res = transclude(el, options)
+      expect(res).not.toBe(el)
+      expect(res.firstChild.tagName).toBe('DIV')
+      expect(res.firstChild.firstChild.tagName).toBe('P')
+      expect(res.firstChild.firstChild.textContent).toBe('hi')
+    })
+
+    it('block instance content transclusion', function () {
+      el.innerHTML = '<p>hi</p><span>ho</span>'
+      options.template = '<div></div><content select="p"></content><content select="span"></content>'
+      var res = transclude(el, options)
+      expect(res.firstChild.tagName).toBe('DIV')
+      expect(res.childNodes[1].tagName).toBe('P')
+      expect(res.childNodes[2].tagName).toBe('SPAN')
+    })
+
+  })
+}

+ 3 - 3
test/unit/specs/transition_spec.js

@@ -345,7 +345,7 @@ if (_.inBrowser && !_.isIE9) {
         var cleanupSpy = jasmine.createSpy('js cleanup')
         var leaveSpy = jasmine.createSpy('js leave')
         def.enter = function (el, done) {
-          var to = setTimeout(done, 10)
+          var to = setTimeout(done, 30)
           return function () {
             clearTimeout(to)
             cleanupSpy()
@@ -363,8 +363,8 @@ if (_.inBrowser && !_.isIE9) {
           setTimeout(function () {
             expect(cb).not.toHaveBeenCalled()
             done()
-          }, 10)
-        }, 1)
+          }, 30)
+        }, 15)
       })
 
     })