Browse Source

fix fragment caching for SVG elements in IE (fix #2406)

Evan You 10 years ago
parent
commit
aa23fdc7da
3 changed files with 28 additions and 2 deletions
  1. 2 2
      src/fragment/factory.js
  2. 18 0
      src/util/dom.js
  3. 8 0
      test/unit/specs/util/dom_spec.js

+ 2 - 2
src/fragment/factory.js

@@ -1,5 +1,5 @@
 import { compile } from '../compiler/index'
-import { isTemplate } from '../util/index'
+import { isTemplate, getOuterHTML } from '../util/index'
 import { parseTemplate, cloneNode } from '../parsers/template'
 import Fragment from './fragment'
 import Cache from '../cache'
@@ -29,7 +29,7 @@ export default function FragmentFactory (vm, el) {
   var linker
   var cid = vm.constructor.cid
   if (cid > 0) {
-    var cacheId = cid + (isString ? el : el.outerHTML)
+    var cacheId = cid + (isString ? el : getOuterHTML(el))
     linker = linkerCache.get(cacheId)
     if (!linker) {
       linker = compile(template, vm.$options, true)

+ 18 - 0
src/util/dom.js

@@ -414,3 +414,21 @@ export function removeNodeRange (start, end, vm, frag, cb) {
 export function isFragment (node) {
   return node && node.nodeType === 11
 }
+
+/**
+ * Get outerHTML of elements, taking care
+ * of SVG elements in IE as well.
+ *
+ * @param {Element} el
+ * @return {String}
+ */
+
+export function getOuterHTML (el) {
+  if (el.outerHTML) {
+    return el.outerHTML
+  } else {
+    var container = document.createElement('div')
+    container.appendChild(el.cloneNode(true))
+    return container.innerHTML
+  }
+}

+ 8 - 0
test/unit/specs/util/dom_spec.js

@@ -115,4 +115,12 @@ describe('Util - DOM', function () {
     _.addClass(el, 'bb')
     expect(el.getAttribute('class')).toBe('cc bb')
   })
+
+  it('getOuterHTML for SVG', function () {
+    var el = document.createElementNS('http://www.w3.org/2000/svg', 'circle')
+    el.setAttribute('class', 'aa bb cc')
+    var html = _.getOuterHTML(el)
+    var re = /<circle (xmlns="http:\/\/www\.w3\.org\/2000\/svg"\s)?class="aa bb cc"(\s?\/>|><\/circle>)/
+    expect(re.test(html)).toBe(true)
+  })
 })