Skip to content

Commit da385ad

Browse files
committed
fix #484 Safari nested <template> clone fail
1 parent 5888e21 commit da385ad

File tree

5 files changed

+43
-4
lines changed

5 files changed

+43
-4
lines changed

gruntfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ module.exports = function (grunt) {
5151
},
5252
browsers: {
5353
options: {
54-
browsers: ['Chrome', 'Firefox'],
54+
browsers: ['Chrome', 'Firefox', 'Safari'],
5555
reporters: ['progress']
5656
}
5757
},

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"karma-firefox-launcher": "^0.1.3",
3434
"karma-jasmine": "^0.2.2",
3535
"karma-phantomjs-launcher": "^0.1.4",
36+
"karma-safari-launcher": "^0.1.1",
3637
"karma-sauce-launcher": "^0.2.10",
3738
"semver": "^4.0.3",
3839
"shell-task": "^1.0.0",

src/directives/component.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var _ = require('../util')
22
var Watcher = require('../watcher')
3+
var templateParser = require('../parse/template')
34

45
module.exports = {
56

@@ -131,7 +132,7 @@ module.exports = {
131132
}
132133
if (this.Ctor && !this.childVM) {
133134
this.childVM = this.vm.$addChild({
134-
el: this.el.cloneNode(true)
135+
el: templateParser.clone(this.el)
135136
}, this.Ctor)
136137
if (this.keepAlive) {
137138
this.cache[this.ctorId] = this.childVM

src/directives/repeat.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ module.exports = {
280280
// resolve constructor
281281
var Ctor = this.Ctor || this.resolveCtor(data, meta)
282282
var vm = this.vm.$addChild({
283-
el: this.template.cloneNode(true),
283+
el: templateParser.clone(this.template),
284284
_linker: this._linker,
285285
_meta: meta,
286286
data: data,

src/parse/template.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
var Cache = require('../cache')
22
var templateCache = new Cache(100)
33

4+
/**
5+
* Test for the presence of the Safari template cloning bug
6+
* https://bugs.webkit.org/show_bug.cgi?id=137755
7+
*/
8+
9+
var hasBrokenTemplate = (function () {
10+
var a = document.createElement('div')
11+
a.innerHTML = '<template>1</template>'
12+
return !a.cloneNode(true).firstChild.innerHTML
13+
})()
14+
415
var map = {
516
_default : [0, '', ''],
617
legend : [1, '<fieldset>', '</fieldset>'],
@@ -127,6 +138,32 @@ function nodeToFragment (node) {
127138
: stringToFragment(node.innerHTML)
128139
}
129140

141+
/**
142+
* Deal with Safari cloning nested <template> bug by
143+
* manually cloning all template instances.
144+
*
145+
* @param {Element|DocumentFragment} node
146+
* @return {Element|DocumentFragment}
147+
*/
148+
149+
exports.clone = function (node) {
150+
var res = node.cloneNode(true)
151+
if (hasBrokenTemplate) {
152+
var templates = node.querySelectorAll('template')
153+
if (templates.length) {
154+
var cloned = res.querySelectorAll('template')
155+
var i = cloned.length
156+
while (i--) {
157+
cloned[i].parentNode.replaceChild(
158+
templates[i].cloneNode(true),
159+
cloned[i]
160+
)
161+
}
162+
}
163+
}
164+
return res
165+
}
166+
130167
/**
131168
* Process the template option and normalizes it into a
132169
* a DocumentFragment that can be used as a partial or a
@@ -176,6 +213,6 @@ exports.parse = function (template, clone) {
176213
}
177214

178215
return frag && clone
179-
? frag.cloneNode(true)
216+
? exports.clone(frag)
180217
: frag
181218
}

0 commit comments

Comments
 (0)