Procházet zdrojové kódy

fix(compiler-dom): fix in-browser attribute value decoding w/ html tags

fix #3001
Evan You před 4 roky
rodič
revize
669037277b

+ 41 - 0
packages/compiler-dom/__tests__/decoderHtmlBrowser.spec.ts

@@ -0,0 +1,41 @@
+import { decodeHtmlBrowser } from '../src/decodeHtmlBrowser'
+
+describe('decodeHtmlBrowser', () => {
+  it('should decode HTML correctly', () => {
+    expect(decodeHtmlBrowser(' abc  123 ')).toBe(' abc  123 ')
+
+    expect(decodeHtmlBrowser('&')).toBe('&')
+    expect(decodeHtmlBrowser('&')).toBe('&')
+    expect(decodeHtmlBrowser('&')).toBe('&')
+
+    expect(decodeHtmlBrowser('<')).toBe('<')
+    expect(decodeHtmlBrowser('&lt;')).toBe('<')
+    expect(decodeHtmlBrowser('&amp;lt;')).toBe('&lt;')
+
+    expect(decodeHtmlBrowser('>')).toBe('>')
+    expect(decodeHtmlBrowser('&gt;')).toBe('>')
+    expect(decodeHtmlBrowser('&amp;gt;')).toBe('&gt;')
+
+    expect(decodeHtmlBrowser('&nbsp;')).toBe('\u00a0')
+    expect(decodeHtmlBrowser('&quot;')).toBe('"')
+    expect(decodeHtmlBrowser('&apos;')).toBe("'")
+
+    expect(decodeHtmlBrowser('&Eacute;')).toBe('\u00c9')
+    expect(decodeHtmlBrowser('&#xc9;')).toBe('\u00c9')
+    expect(decodeHtmlBrowser('&#201;')).toBe('\u00c9')
+
+    // #3001 html tags inside attribute values
+    expect(decodeHtmlBrowser('<strong>Text</strong>', true)).toBe(
+      '<strong>Text</strong>'
+    )
+    expect(decodeHtmlBrowser('<strong>&amp;</strong>', true)).toBe(
+      '<strong>&</strong>'
+    )
+    expect(
+      decodeHtmlBrowser(
+        '<strong>&lt;strong&gt;&amp;&lt;/strong&gt;</strong>',
+        true
+      )
+    ).toBe('<strong><strong>&</strong></strong>')
+  })
+})

+ 11 - 3
packages/compiler-dom/src/decodeHtmlBrowser.ts

@@ -2,7 +2,15 @@
 
 let decoder: HTMLDivElement
 
-export function decodeHtmlBrowser(raw: string): string {
-  ;(decoder || (decoder = document.createElement('div'))).innerHTML = raw
-  return decoder.textContent as string
+export function decodeHtmlBrowser(raw: string, asAttr = false): string {
+  if (!decoder) {
+    decoder = document.createElement('div')
+  }
+  if (asAttr) {
+    decoder.innerHTML = `<div foo="${raw.replace(/"/g, '&quot;')}">`
+    return decoder.children[0].getAttribute('foo') as string
+  } else {
+    decoder.innerHTML = raw
+    return decoder.textContent as string
+  }
 }