Repository: vuejs/vue
Pull request: feat: support v-html for SVG elements

<!--
Please make sure to read the Pull Request Guidelines:
https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
-->

<!-- PULL REQUEST TEMPLATE -->
<!-- (Update "[ ]" to "[x]" to check a box) -->

**What kind of change does this PR introduce?** (check at least one)

- [ ] Bugfix
- [x] Feature
- [ ] Code style update
- [ ] Refactor
- [ ] Build-related changes
- [ ] Other, please describe:

**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [x] No

If yes, please describe the impact and migration path for existing applications:

**The PR fulfills these requirements:**

- [x] It's submitted to the `dev` branch for v2.x (or to a previous version branch), _not_ the `master` branch
- [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [x] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
- [x] New/updated tests are included

If adding a **new feature**, the PR's description includes:
- [x] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

Currently for older browsers (IE9~IE11) we cannot use `v-html` on SVG elements because they don't support `innerHTML` for SVG elements. While actually we can fix this without much effort and make it “just works”. As `innerHTML` is defined for `Element` interface (which `SVGElement` is derived from) [in the latest spec](https://w3c.github.io/DOM-Parsing/#dfn-innerhtml), I think it's reasonable to add this for `v-html`.

**Other information:**

Related issues: #5310 #5756

Since it's a browser-specific fix and we don't run tests for IE locally, I created a repo to demonstrate the fix: https://github.com/Justineo/v-html-svg

* With latest `vue` on `unpkg.com`, see: https://justineo.github.io/v-html-svg/test-original.html
* After the fix, see: https://justineo.github.io/v-html-svg/test-fixed.html

I've tested and it should now work in IE 9~IE 11.


Changed files:
filename: src/platforms/web/runtime/modules/dom-props.js
patch: @@ -1,6 +1,9 @@
 /* @flow */
 
 import { isDef, isUndef, extend, toNumber } from 'shared/util'
+import { isSVG } from 'web/util/index'
+
+let svgContainer
 
 function updateDOMProps (oldVnode: VNodeWithData, vnode: VNodeWithData) {
   if (isUndef(oldVnode.data.domProps) && isUndef(vnode.data.domProps)) {
@@ -55,6 +58,17 @@ function updateDOMProps (oldVnode: VNodeWithData, vnode: VNodeWithData) {
       if (shouldUpdateValue(elm, strCur)) {
         elm.value = strCur
       }
+    } else if (key === 'innerHTML' && isSVG(elm.tagName) && isUndef(elm.innerHTML)) {
+      // IE doesn't support innerHTML for SVG elements
+      svgContainer = svgContainer || document.createElement('div')
+      svgContainer.innerHTML = `<svg>${cur}</svg>`
+      const svg = svgContainer.firstChild
+      while (elm.firstChild) {
+        elm.removeChild(elm.firstChild)
+      }
+      while (svg.firstChild) {
+        elm.appendChild(svg.firstChild)
+      }
     } else {
       elm[key] = cur
     }