Skip to content

Commit b9ab204

Browse files
committed
Merge branch 'diverted247-patch-1' into dev
2 parents f39703d + 7aa02e1 commit b9ab204

File tree

9 files changed

+170
-46
lines changed

9 files changed

+170
-46
lines changed

component.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"src/observer.js",
1919
"src/directive.js",
2020
"src/exp-parser.js",
21+
"src/template-parser.js",
2122
"src/text-parser.js",
2223
"src/deps-parser.js",
2324
"src/filters.js",
@@ -34,4 +35,4 @@
3435
"src/directives/partial.js",
3536
"src/directives/view.js"
3637
]
37-
}
38+
}

src/fragment.js

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,29 +30,12 @@ map.rect = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">','</svg>'
3030

3131
var TAG_RE = /<([\w:]+)/
3232

33-
module.exports = function (template) {
34-
35-
if (typeof template !== 'string') {
36-
return template
37-
}
38-
39-
// template by ID
40-
if (template.charAt(0) === '#') {
41-
var templateNode = document.getElementById(template.slice(1))
42-
if (!templateNode) return
43-
// if its a template tag and the browser supports it,
44-
// its content is already a document fragment!
45-
if (templateNode.tagName === 'TEMPLATE' && templateNode.content) {
46-
return templateNode.content
47-
}
48-
template = templateNode.innerHTML
49-
}
50-
33+
module.exports = function (templateString) {
5134
var frag = document.createDocumentFragment(),
52-
m = TAG_RE.exec(template)
35+
m = TAG_RE.exec(templateString)
5336
// text only
5437
if (!m) {
55-
frag.appendChild(document.createTextNode(template))
38+
frag.appendChild(document.createTextNode(templateString))
5639
return frag
5740
}
5841

@@ -63,7 +46,7 @@ module.exports = function (template) {
6346
suffix = wrap[2],
6447
node = document.createElement('div')
6548

66-
node.innerHTML = prefix + template.trim() + suffix
49+
node.innerHTML = prefix + templateString.trim() + suffix
6750
while (depth--) node = node.lastChild
6851

6952
// one element

src/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ assetTypes.forEach(function (type) {
3030
}
3131
if (!value) return hash[id]
3232
if (type === 'partial') {
33-
value = utils.toFragment(value)
33+
value = utils.parseTemplateOption(value)
3434
} else if (type === 'component') {
3535
value = utils.toConstructor(value)
3636
} else if (type === 'filter') {

src/template-parser.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
var toFragment = require('./fragment');
2+
3+
/**
4+
* Parses a template string or node and normalizes it into a
5+
* a node that can be used as a partial of a template option
6+
*
7+
* Possible values include
8+
* id selector: '#some-template-id'
9+
* template string: '<div><span>my template</span></div>'
10+
* DocumentFragment object
11+
* Node object of type Template
12+
*/
13+
module.exports = function(template) {
14+
var templateNode;
15+
16+
if (template instanceof window.DocumentFragment) {
17+
// if the template is already a document fragment -- do nothing
18+
return template
19+
}
20+
21+
if (typeof template === 'string') {
22+
// template by ID
23+
if (template.charAt(0) === '#') {
24+
templateNode = document.getElementById(template.slice(1))
25+
if (!templateNode) return
26+
} else {
27+
return toFragment(template)
28+
}
29+
} else if (template.nodeType) {
30+
templateNode = template
31+
} else {
32+
return
33+
}
34+
35+
// if its a template tag and the browser supports it,
36+
// its content is already a document fragment!
37+
if (templateNode.tagName === 'TEMPLATE' && templateNode.content) {
38+
return templateNode.content
39+
}
40+
41+
if (templateNode.tagName === 'SCRIPT') {
42+
return toFragment(templateNode.innerHTML)
43+
}
44+
45+
return toFragment(templateNode.outerHTML);
46+
}

src/utils.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ var utils = module.exports = {
3232
*/
3333
toFragment: require('./fragment'),
3434

35+
/**
36+
* Parse the various types of template options
37+
*/
38+
parseTemplateOption: require('./template-parser.js'),
39+
3540
/**
3641
* get a value from an object keypath
3742
*/
@@ -226,7 +231,7 @@ var utils = module.exports = {
226231
}
227232
if (partials) {
228233
for (key in partials) {
229-
partials[key] = utils.toFragment(partials[key])
234+
partials[key] = utils.parseTemplateOption(partials[key])
230235
}
231236
}
232237
if (filters) {
@@ -235,7 +240,7 @@ var utils = module.exports = {
235240
}
236241
}
237242
if (template) {
238-
options.template = utils.toFragment(template)
243+
options.template = utils.parseTemplateOption(template)
239244
}
240245
},
241246

src/viewmodel.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,24 @@ var Compiler = require('./compiler'),
1616
* and a few reserved methods
1717
*/
1818
function ViewModel (options) {
19-
// just compile. options are passed directly to compiler
19+
// compile if options passed, if false return. options are passed directly to compiler
20+
if (options === false) return
2021
new Compiler(this, options)
2122
}
2223

2324
// All VM prototype methods are inenumerable
2425
// so it can be stringified/looped through as raw data
2526
var VMProto = ViewModel.prototype
2627

28+
/**
29+
* init allows config compilation after instantiation:
30+
* var a = new Vue(false)
31+
* a.init(config)
32+
*/
33+
def(VMProto, '$init', function (options) {
34+
new Compiler(this, options)
35+
})
36+
2737
/**
2838
* Convenience function to get a value from
2939
* a keypath
@@ -81,8 +91,8 @@ def(VMProto, '$unwatch', function (key, callback) {
8191
/**
8292
* unbind everything, remove everything
8393
*/
84-
def(VMProto, '$destroy', function () {
85-
this.$compiler.destroy()
94+
def(VMProto, '$destroy', function (noRemove) {
95+
this.$compiler.destroy(noRemove)
8696
})
8797

8898
/**
@@ -177,4 +187,4 @@ function query (el) {
177187
: el
178188
}
179189

180-
module.exports = ViewModel
190+
module.exports = ViewModel

test/.jshintrc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
"mockHTMLEvent": true,
2424
"mockMouseEvent": true,
2525
"mockKeyEvent": true,
26-
"casper": true
26+
"casper": true,
27+
"beforeEach": true,
28+
"afterEach": true
2729
}
2830
}

test/unit/specs/utils.js

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
/* global cleanupMocks, appendMock */
2+
13
describe('Utils', function () {
4+
afterEach(cleanupMocks)
25

36
var utils = require('vue/src/utils'),
47
config = require('vue/src/config')
@@ -215,28 +218,14 @@ describe('Utils', function () {
215218

216219
describe('toFragment', function () {
217220

218-
it('should convert a string tempalte to a documentFragment', function () {
221+
it('should convert a string template to a documentFragment', function () {
219222
var template = '<div class="a">hi</div><p>ha</p>',
220223
frag = utils.toFragment(template)
221224
assert.ok(frag instanceof window.DocumentFragment)
222225
assert.equal(frag.querySelector('.a').textContent, 'hi')
223226
assert.equal(frag.querySelector('p').textContent, 'ha')
224227
})
225228

226-
it('should also work if the string is an ID selector', function () {
227-
var id = 'utils-template-to-fragment',
228-
template = '<div class="a">hi</div><p>ha</p>',
229-
el = document.createElement('template')
230-
el.id = id
231-
el.innerHTML = template
232-
document.getElementById('test').appendChild(el)
233-
234-
var frag = utils.toFragment('#' + id)
235-
assert.ok(frag instanceof window.DocumentFragment)
236-
assert.equal(frag.querySelector('.a').textContent, 'hi')
237-
assert.equal(frag.querySelector('p').textContent, 'ha')
238-
})
239-
240229
it('should work with table elements', function () {
241230
var frag = utils.toFragment('<td></td>')
242231
assert.ok(frag instanceof window.DocumentFragment)
@@ -252,6 +241,75 @@ describe('Utils', function () {
252241

253242
})
254243

244+
describe('parseTemplateOption', function () {
245+
246+
afterEach(cleanupMocks)
247+
248+
it('should convert a string template to a documentFragment', function () {
249+
var template = '<div class="a">hi</div><p>ha</p>',
250+
frag = utils.parseTemplateOption(template)
251+
assert.ok(frag instanceof window.DocumentFragment)
252+
assert.equal(frag.querySelector('.a').textContent, 'hi')
253+
assert.equal(frag.querySelector('p').textContent, 'ha')
254+
})
255+
256+
describe('id selector', function() {
257+
it('should work with a TEMPLATE tag', function() {
258+
var id = 'utils-template-parse-template-option-template-tag',
259+
template = '<div class="a">hi</div><p>ha</p>',
260+
el = document.createElement('template')
261+
el.id = id
262+
el.innerHTML = template
263+
appendMock(el)
264+
265+
var frag = utils.parseTemplateOption('#' + id)
266+
assert.ok(frag instanceof window.DocumentFragment)
267+
assert.equal(frag.querySelector('.a').textContent, 'hi')
268+
assert.equal(frag.querySelector('p').textContent, 'ha')
269+
})
270+
271+
it('should work with a DIV tag', function() {
272+
var id = 'utils-template-parse-template-option-div-tag',
273+
template = '<div class="a">hi</div><p>ha</p>',
274+
el = document.createElement('div')
275+
el.id = id
276+
el.innerHTML = template
277+
appendMock(el)
278+
279+
var frag = utils.parseTemplateOption('#' + id)
280+
assert.ok(frag instanceof window.DocumentFragment)
281+
assert.equal(frag.querySelector('.a').textContent, 'hi')
282+
assert.equal(frag.querySelector('p').textContent, 'ha')
283+
})
284+
})
285+
286+
describe('when passed a Node', function() {
287+
it('should work with a TEMPLATE tag', function() {
288+
var el = document.createElement('template')
289+
el.innerHTML = '<div class="a">hi</div><p>ha</p>'
290+
291+
var frag = utils.parseTemplateOption(el)
292+
assert.ok(frag instanceof window.DocumentFragment)
293+
assert.equal(frag.querySelector('.a').textContent, 'hi')
294+
assert.equal(frag.querySelector('p').textContent, 'ha')
295+
})
296+
297+
it('should work with a DIV tag', function() {
298+
var el = document.createElement('div')
299+
el.innerHTML = '<span class="a">hi</span><p>ha</p>'
300+
301+
var frag = utils.parseTemplateOption(el)
302+
assert.ok(frag instanceof window.DocumentFragment)
303+
304+
assert.equal(frag.firstChild.outerHTML, el.outerHTML)
305+
assert.equal(frag.querySelector('.a').textContent, 'hi')
306+
assert.equal(frag.querySelector('p').textContent, 'ha')
307+
})
308+
})
309+
310+
311+
})
312+
255313
describe('toConstructor', function () {
256314

257315
it('should convert an non-VM object to a VM constructor', function () {
@@ -270,6 +328,17 @@ describe('Utils', function () {
270328

271329
describe('processOptions', function () {
272330

331+
beforeEach(function() {
332+
var id = 'utils-template-to-fragment',
333+
template = '<div class="a">hi</div><p>ha</p>',
334+
el = document.createElement('template')
335+
el.id = id
336+
el.innerHTML = template
337+
appendMock(el)
338+
})
339+
340+
afterEach(cleanupMocks)
341+
273342
var options = {
274343
partials: {
275344
a: '#utils-template-to-fragment',

test/unit/utils/prepare.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,18 @@ function mock (id, html, attrs) {
77
el.setAttribute(attr, attrs[attr])
88
}
99
}
10-
document.getElementById('test').appendChild(el)
10+
appendMock(el)
1111
return el
1212
}
1313

14+
function appendMock(el) {
15+
document.getElementById('test').appendChild(el)
16+
}
17+
18+
function cleanupMocks() {
19+
document.getElementById('test').innerHTML = ''
20+
}
21+
1422
function mockHTMLEvent (type) {
1523
var e = document.createEvent('HTMLEvents')
1624
e.initEvent(type, true, true)

0 commit comments

Comments
 (0)