Forráskód Böngészése

fix: handle encoded tabs and newlines in attributes for Chrome a[href] and IE/Edge

fix #6828, fix #6916
Evan You 8 éve
szülő
commit
cfd73c2386

+ 2 - 1
flow/compiler.js

@@ -14,7 +14,8 @@ declare type CompilerOptions = {
   preserveWhitespace?: boolean;
   isFromDOM?: boolean;
   shouldDecodeTags?: boolean;
-  shouldDecodeNewlines?: boolean;
+  shouldDecodeNewlines?:  boolean;
+  shouldDecodeNewlinesForHref?: boolean;
 
   // for ssr optimization compiler
   scopeId?: string;

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

@@ -39,10 +39,11 @@ const decodingMap = {
   '>': '>',
   '"': '"',
   '&': '&',
-  '
': '\n'
+  '
': '\n',
+  '	': '\t'
 }
 const encodedAttr = /&(?:lt|gt|quot|amp);/g
-const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10);/g
+const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10|#9);/g
 
 // #5992
 const isIgnoreNewlineTag = makeMap('pre,textarea', true)
@@ -233,12 +234,12 @@ export function parseHTML (html, options) {
         if (args[5] === '') { delete args[5] }
       }
       const value = args[3] || args[4] || args[5] || ''
+      const shouldDecodeNewlines = tagName === 'a' && args[1] === 'href'
+        ? options.shouldDecodeNewlinesForHref
+        : options.shouldDecodeNewlines
       attrs[i] = {
         name: args[1],
-        value: decodeAttr(
-          value,
-          options.shouldDecodeNewlines
-        )
+        value: decodeAttr(value, shouldDecodeNewlines)
       }
     }
 

+ 1 - 0
src/compiler/parser/index.js

@@ -107,6 +107,7 @@ export function parse (
     isUnaryTag: options.isUnaryTag,
     canBeLeftOpenTag: options.canBeLeftOpenTag,
     shouldDecodeNewlines: options.shouldDecodeNewlines,
+    shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
     shouldKeepComment: options.comments,
     start (tag, attrs, unary) {
       // check namespace.

+ 2 - 1
src/platforms/web/entry-runtime-with-compiler.js

@@ -6,8 +6,8 @@ import { mark, measure } from 'core/util/perf'
 
 import Vue from './runtime/index'
 import { query } from './util/index'
-import { shouldDecodeNewlines } from './util/compat'
 import { compileToFunctions } from './compiler/index'
+import { shouldDecodeNewlines, shouldDecodeNewlinesForHref } from './util/compat'
 
 const idToTemplate = cached(id => {
   const el = query(id)
@@ -64,6 +64,7 @@ Vue.prototype.$mount = function (
 
       const { render, staticRenderFns } = compileToFunctions(template, {
         shouldDecodeNewlines,
+        shouldDecodeNewlinesForHref,
         delimiters: options.delimiters,
         comments: options.comments
       }, this)

+ 9 - 7
src/platforms/web/util/compat.js

@@ -3,12 +3,14 @@
 import { inBrowser } from 'core/util/index'
 
 // check whether current browser encodes a char inside attribute values
-function shouldDecode (content: string, encoded: string): boolean {
-  const div = document.createElement('div')
-  div.innerHTML = `<div a="${content}"/>`
-  return div.innerHTML.indexOf(encoded) > 0
+let div
+function getShouldDecode (href: boolean): boolean {
+  div = div || document.createElement('div')
+  div.innerHTML = href ? `<a href="\n"/>` : `<div a="\n"/>`
+  return div.innerHTML.indexOf('&#10;') > 0
 }
 
-// #3663
-// IE encodes newlines inside attribute values while other browsers don't
-export const shouldDecodeNewlines = inBrowser ? shouldDecode('\n', '&#10;') : false
+// #3663: IE encodes newlines inside attribute values while other browsers don't
+export const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false
+// #6828: chrome encodes content in a[href]
+export const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false