diff --git a/cjs/mixin/inner-html.js b/cjs/mixin/inner-html.js
index ec106d80..9d3e3165 100644
--- a/cjs/mixin/inner-html.js
+++ b/cjs/mixin/inner-html.js
@@ -1,6 +1,6 @@
'use strict';
const {ELEMENT_NODE, DOCUMENT_FRAGMENT_NODE} = require('../shared/constants.js');
-const {CUSTOM_ELEMENTS} = require('../shared/symbols.js');
+const {CUSTOM_ELEMENTS, END, NEXT} = require('../shared/symbols.js');
const {parseFromString} = require('../shared/parse-from-string.js');
const {ignoreCase} = require('../shared/utils.js');
@@ -21,7 +21,22 @@ const setInnerHtml = (node, html) => {
const {constructor} = ownerDocument;
const document = new constructor;
document[CUSTOM_ELEMENTS] = ownerDocument[CUSTOM_ELEMENTS];
- const {childNodes} = parseFromString(document, ignoreCase(node), html);
+ const isHTML = ignoreCase(node);
+ // the content of an SVG element is SVG: closes, children are SVGElement
+ const isSVG = isHTML && 'ownerSVGElement' in node;
+ let {childNodes} = parseFromString(document, isHTML, isSVG ? `` : html);
+
+ if (isSVG) {
+ const svg = childNodes[0];
+ const ownerSVGElement = node.localName === 'svg' ? node : node.ownerSVGElement;
+ let {[NEXT]: next, [END]: end} = svg;
+ while (next !== end) {
+ if (next.nodeType === ELEMENT_NODE)
+ next.ownerSVGElement = ownerSVGElement;
+ next = next[NEXT];
+ }
+ childNodes = svg.childNodes;
+ }
node.replaceChildren(...childNodes.map(setOwnerDocument, ownerDocument));
};
diff --git a/esm/mixin/inner-html.js b/esm/mixin/inner-html.js
index ac37e8f7..7c25809b 100644
--- a/esm/mixin/inner-html.js
+++ b/esm/mixin/inner-html.js
@@ -1,5 +1,5 @@
import {ELEMENT_NODE, DOCUMENT_FRAGMENT_NODE} from '../shared/constants.js';
-import {CUSTOM_ELEMENTS} from '../shared/symbols.js';
+import {CUSTOM_ELEMENTS, END, NEXT} from '../shared/symbols.js';
import {parseFromString} from '../shared/parse-from-string.js';
import {ignoreCase} from '../shared/utils.js';
@@ -19,7 +19,22 @@ export const setInnerHtml = (node, html) => {
const {constructor} = ownerDocument;
const document = new constructor;
document[CUSTOM_ELEMENTS] = ownerDocument[CUSTOM_ELEMENTS];
- const {childNodes} = parseFromString(document, ignoreCase(node), html);
+ const isHTML = ignoreCase(node);
+ // the content of an SVG element is SVG: closes, children are SVGElement
+ const isSVG = isHTML && 'ownerSVGElement' in node;
+ let {childNodes} = parseFromString(document, isHTML, isSVG ? `` : html);
+
+ if (isSVG) {
+ const svg = childNodes[0];
+ const ownerSVGElement = node.localName === 'svg' ? node : node.ownerSVGElement;
+ let {[NEXT]: next, [END]: end} = svg;
+ while (next !== end) {
+ if (next.nodeType === ELEMENT_NODE)
+ next.ownerSVGElement = ownerSVGElement;
+ next = next[NEXT];
+ }
+ childNodes = svg.childNodes;
+ }
node.replaceChildren(...childNodes.map(setOwnerDocument, ownerDocument));
};
diff --git a/test/svg/element.js b/test/svg/element.js
index 4f5259ca..97a55d39 100644
--- a/test/svg/element.js
+++ b/test/svg/element.js
@@ -46,4 +46,20 @@ assert(svg.getAttribute('class'), 'a b c');
svg.setAttribute('class', 'd e');
assert(svg.getAttribute('class'), 'd e');
-assert(svg.namespaceURI, 'http://www.w3.org/2000/svg');
\ No newline at end of file
+assert(svg.namespaceURI, 'http://www.w3.org/2000/svg');
+
+// https://github.com/WebReflection/linkedom/issues/326
+({document} = parseHTML('
'));
+svg = document.querySelector('svg');
+svg.innerHTML = '';
+assert(svg.childNodes.length, 2, 'self-closing children are siblings');
+assert(svg.firstChild instanceof SVGElement, true, 'innerHTML children are SVG elements');
+assert(svg.firstChild.ownerSVGElement, svg, 'innerHTML children ownerSVGElement');
+assert(svg.innerHTML, '');
+
+svg.innerHTML = '';
+const g = svg.firstChild;
+g.innerHTML = '';
+assert(g.toString(), '', 'nested innerHTML');
+assert(g.firstChild.ownerSVGElement, svg, 'nested innerHTML ownerSVGElement');
+assert(g.lastChild.firstChild.ownerSVGElement, svg, 'deep innerHTML ownerSVGElement');