From d9bcc949cd35eaac9360bc0a98c6183334cb3903 Mon Sep 17 00:00:00 2001
From: MoyuScript <i@moyu.moe>
Date: Mon, 25 Nov 2019 20:55:28 -0800
Subject: [PATCH] fix: #1868 Clone node, Setting className for SVG element
 raises error (#2079)

* fix: #1868 Clone node, Setting className for SVG element raises error

* fix: svg element type information
---
 src/dom/document-cloner.ts                 | 10 +++++++++-
 src/dom/node-parser.ts                     |  3 ++-
 tests/reftests/images/svg/native_only.html |  5 ++++-
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/dom/document-cloner.ts b/src/dom/document-cloner.ts
index ae1c4cf..9603ef2 100644
--- a/src/dom/document-cloner.ts
+++ b/src/dom/document-cloner.ts
@@ -8,6 +8,7 @@ import {
     isScriptElement,
     isSelectElement,
     isStyleElement,
+    isSVGElementNode,
     isTextareaElement,
     isTextNode
 } from './node-parser';
@@ -409,10 +410,17 @@ export class DocumentCloner {
         });
 
         anonymousReplacedElement.className = `${PSEUDO_HIDE_ELEMENT_CLASS_BEFORE} ${PSEUDO_HIDE_ELEMENT_CLASS_AFTER}`;
-        clone.className +=
+        const newClassName =
             pseudoElt === PseudoElementType.BEFORE
                 ? ` ${PSEUDO_HIDE_ELEMENT_CLASS_BEFORE}`
                 : ` ${PSEUDO_HIDE_ELEMENT_CLASS_AFTER}`;
+
+        if (isSVGElementNode(clone)) {
+            clone.className.baseValue += newClassName;
+        } else {
+            clone.className += newClassName;
+        }
+
         return anonymousReplacedElement;
     }
 
diff --git a/src/dom/node-parser.ts b/src/dom/node-parser.ts
index 238115e..791247b 100644
--- a/src/dom/node-parser.ts
+++ b/src/dom/node-parser.ts
@@ -103,7 +103,8 @@ export const isTextNode = (node: Node): node is Text => node.nodeType === Node.T
 export const isElementNode = (node: Node): node is Element => node.nodeType === Node.ELEMENT_NODE;
 export const isHTMLElementNode = (node: Node): node is HTMLElement =>
     typeof (node as HTMLElement).style !== 'undefined';
-
+export const isSVGElementNode = (element: Element): element is SVGElement =>
+    typeof (element as SVGElement).className === 'object';
 export const isLIElement = (node: Element): node is HTMLLIElement => node.tagName === 'LI';
 export const isOLElement = (node: Element): node is HTMLOListElement => node.tagName === 'OL';
 export const isInputElement = (node: Element): node is HTMLInputElement => node.tagName === 'INPUT';
diff --git a/tests/reftests/images/svg/native_only.html b/tests/reftests/images/svg/native_only.html
index 8ab8f5d..a6a7c25 100644
--- a/tests/reftests/images/svg/native_only.html
+++ b/tests/reftests/images/svg/native_only.html
@@ -11,13 +11,16 @@
         body {
             font-family: Arial;
         }
+        svg:before {
+            content: " ";
+        }
     </style>
 </head>
 <body>
 <div>
     <img src="../../../assets/image.svg" />
     <img width="200" height="200" src='data:image/svg+xml,<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="306" height="296"><defs id="defs4" /><g transform="translate(-162.46995,-477.2863)" id="layer1"><path d="m 314.15745,481.69558 c -59.20089,0.53774 -114.80979,36.72219 -137.3125,95.34375 -29.39129,76.56693 8.83932,162.45246 85.40625,191.84375 l 34.03125,-88.6875 c -20.0678,-7.71358 -34.3125,-27.15324 -34.3125,-49.9375 0,-29.54723 23.95277,-53.5 53.5,-53.5 29.54723,0 53.5,23.95277 53.5,53.5 0,22.78426 -14.2447,42.22392 -34.3125,49.9375 l 34.03125,88.6875 c 39.29085,-15.08234 70.3239,-46.1154 85.40625,-85.40625 29.39129,-76.56693 -8.83932,-162.48371 -85.40625,-191.875 -17.94537,-6.88859 -36.40853,-10.07087 -54.53125,-9.90625 z" id="path2830" style="fill:#40aa54;fill-opacity:1;stroke:#20552a;stroke-width:7.99999952;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></svg>' />
-    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="306" height="296" id="svg2">
+    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="306" height="296" id="svg2" class="test">
         <defs id="defs4"/>
         <g transform="translate(-162.46995,-477.2863)" id="layer1">
             <path d="m 314.15745,481.69558 c -59.20089,0.53774 -114.80979,36.72219 -137.3125,95.34375 -29.39129,76.56693 8.83932,162.45246 85.40625,191.84375 l 34.03125,-88.6875 c -20.0678,-7.71358 -34.3125,-27.15324 -34.3125,-49.9375 0,-29.54723 23.95277,-53.5 53.5,-53.5 29.54723,0 53.5,23.95277 53.5,53.5 0,22.78426 -14.2447,42.22392 -34.3125,49.9375 l 34.03125,88.6875 c 39.29085,-15.08234 70.3239,-46.1154 85.40625,-85.40625 29.39129,-76.56693 -8.83932,-162.48371 -85.40625,-191.875 -17.94537,-6.88859 -36.40853,-10.07087 -54.53125,-9.90625 z"