Evan You 10 лет назад
Родитель
Сommit
ff9c6b09bb

+ 1 - 0
flow/compiler.js

@@ -1,5 +1,6 @@
 declare type CompilerOptions = {
   warn?: Function,
+  isIE?: boolean,
   expectHTML?: boolean,
   preserveWhitespace?: boolean,
   modules?: Array<ModuleOptions>,

+ 6 - 3
src/compiler/parser/html-parser.js

@@ -212,18 +212,21 @@ export function parseHTML (html, handler) {
 
     const unary = isUnaryTag(tagName) || tagName === 'html' && lastTag === 'head' || !!unarySlash
 
-    const attrs = match.attrs.map(function (args) {
+    const l = match.attrs.length
+    const attrs = new Array(l)
+    for (let i = 0; i < l; i++) {
+      const args = match.attrs[i]
       // hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778
       if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) {
         if (args[3] === '') { delete args[3] }
         if (args[4] === '') { delete args[4] }
         if (args[5] === '') { delete args[5] }
       }
-      return {
+      attrs[i] = {
         name: args[1],
         value: decodeHTML(args[3] || args[4] || args[5] || '')
       }
-    })
+    }
 
     if (!unary) {
       stack.push({ tag: tagName, attrs: attrs })

+ 26 - 8
src/compiler/parser/index.js

@@ -64,6 +64,15 @@ export function parse (
       }
 
       tag = tag.toLowerCase()
+
+      // check namespace.
+      // inherit parent ns if there is one
+      const ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag)
+      // handle IE svg bug
+      if (options.isIE && ns === 'svg') {
+        attrs = guardIESVGBug(attrs)
+      }
+
       const element: ASTElement = {
         type: 1,
         tag,
@@ -72,6 +81,9 @@ export function parse (
         parent: currentParent,
         children: []
       }
+      if (ns) {
+        element.ns = ns
+      }
 
       if (isForbiddenTag(element)) {
         element.forbidden = true
@@ -82,14 +94,6 @@ export function parse (
         )
       }
 
-      // check namespace.
-      // inherit parent ns if there is one
-      let ns
-      if ((ns = currentParent && currentParent.ns) ||
-          (ns = platformGetTagNamespace(tag))) {
-        element.ns = ns
-      }
-
       if (!inPre) {
         processPre(element)
         if (element.pre) {
@@ -395,3 +399,17 @@ function isForbiddenTag (el): boolean {
     ))
   )
 }
+
+const ieNSBug = /^xmlns:NS\d+/
+const ieNSPrefix = /^NS\d+:/
+function guardIESVGBug (attrs) {
+  const res = []
+  for (let i = 0; i < attrs.length; i++) {
+    const attr = attrs[i]
+    if (!ieNSBug.test(attr.name)) {
+      attr.name = attr.name.replace(ieNSPrefix, '')
+      res.push(attr)
+    }
+  }
+  return res
+}

+ 2 - 1
src/entries/web-compiler.js

@@ -5,7 +5,7 @@ import { warn } from 'core/util/debug'
 import { compile as baseCompile } from 'compiler/index'
 import modules from 'web/compiler/modules/index'
 import directives from 'web/compiler/directives/index'
-import { isReservedTag, isUnaryTag, mustUseProp, getTagNamespace } from 'web/util/index'
+import { isIE, isReservedTag, isUnaryTag, mustUseProp, getTagNamespace } from 'web/util/index'
 
 // detect possible CSP restriction
 /* istanbul ignore if */
@@ -34,6 +34,7 @@ const cache1: { [key: string]: CompiledFunctions } = Object.create(null)
 const cache2: { [key: string]: CompiledFunctions } = Object.create(null)
 
 export const baseOptions: CompilerOptions = {
+  isIE,
   expectHTML: true,
   preserveWhitespace: true,
   modules,

+ 1 - 0
src/platforms/web/util/index.js

@@ -7,6 +7,7 @@ export * from './class'
 export * from './element'
 
 const UA = inBrowser && window.navigator.userAgent.toLowerCase()
+export const isIE = UA && /msie|trident/.test(UA)
 export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
 export const isAndroid = UA && UA.indexOf('android') > 0
 

+ 7 - 10
test/unit/features/options/el.spec.js

@@ -42,18 +42,15 @@ describe('Options el', () => {
   })
 
   it('svg element', () => {
-    const ns = 'http://www.w3.org/2000/svg'
-    const el = document.createElementNS(ns, 'svg')
-    const text = document.createElementNS(ns, 'text')
-    text.setAttribute(':x', 'x')
-    text.setAttribute(':y', 'y')
-    text.setAttribute(':fill', 'color')
-    text.textContent = '{{text}}'
-    el.appendChild(text)
+    const parent = document.createElement('div')
+    parent.innerHTML = '<svg><text :x="x" :y="y" :fill="color">{{ text }}</text></svg>'
     const vm = new Vue({
-      el,
+      el: parent.childNodes[0],
       data: {
-        x: 64, y: 128, color: 'red', text: 'svg text'
+        x: 64,
+        y: 128,
+        color: 'red',
+        text: 'svg text'
       }
     })
     expect(vm.$el.tagName).toBe('svg')

+ 1 - 1
test/unit/features/transition/transition.spec.js

@@ -4,7 +4,7 @@ import { nextFrame } from 'web/runtime/modules/transition'
 
 if (!isIE9) {
   describe('Transition system', () => {
-    const duration = 20
+    const duration = 50
     insertCSS(`
       .test {
         -webkit-transition: opacity ${duration}ms ease;