Skip to content

Commit

Permalink
fix Wrong svg element processing in IE (close #1083) (#1095)
Browse files Browse the repository at this point in the history
  • Loading branch information
LavrovArtem authored Apr 24, 2017
1 parent d53bec5 commit 5c10a88
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 4 deletions.
40 changes: 36 additions & 4 deletions src/client/utils/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { remove as removeProcessingHeader } from '../../processing/script/header
import styleProcessor from '../../processing/style';
import { find, getTagName, isScriptElement } from './dom';
import { convertToProxyUrl, parseProxyUrl } from './url';
import { isIE, isMSEdge } from './browser';
import { hasIsNotClosedFlag } from '../sandbox/node/document/writer';
import * as urlResolver from './url-resolver';
import INTERNAL_PROPS from '../../processing/dom/internal-properties';
Expand All @@ -26,6 +27,9 @@ const WRAP_DOCTYPE_RE = /<!doctype([^>]*)>/ig;
const WRAP_DOCTYPE_TEMPLATE = `<${ FAKE_DOCTYPE_TAG_NAME }>$1</${ FAKE_DOCTYPE_TAG_NAME }>`;
const UNWRAP_DOCTYPE_RE = new RegExp(`<${ FAKE_DOCTYPE_TAG_NAME }>([\\S\\s]*?)</${ FAKE_DOCTYPE_TAG_NAME }>`, 'ig');

const FIND_SVG_RE = /<svg\s?[^>]*>/ig;
const FIND_NS_ATTRS_RE = /\s(?:NS[0-9]+:[^"']+('|")[\S\s]*?\1|[^:]+:NS[0-9]+=(?:""|''))/g;

export const INIT_SCRIPT_FOR_IFRAME_TEMPLATE = `
<script class="${ SHADOW_UI_CLASSNAME.selfRemovingScript }" type="text/javascript">
(function () {
Expand Down Expand Up @@ -91,12 +95,15 @@ function processHtmlInternal (html, process) {

container.innerHTML = html;

if (process(container))
html = container.innerHTML;
var processedHtml = process(container) ? container.innerHTML : html;

processedHtml = unwrapHtmlText(processedHtml);

html = unwrapHtmlText(html);
// NOTE: hack for IE (GH-1083)
if (isIE && !isMSEdge && html !== processedHtml)
processedHtml = removeExtraSvgNamespeces(html, processedHtml);

return html;
return processedHtml;
}

export function cleanUpHtml (html) {
Expand Down Expand Up @@ -213,3 +220,28 @@ export function processHtml (html, parentTag, prepareDom) {
return true;
});
}

function removeExtraSvgNamespeces (html, processedHtml) {
var initialSvgStrs = html.match(FIND_SVG_RE);
var index = 0;

if (!initialSvgStrs)
return processedHtml;

return processedHtml.replace(FIND_SVG_RE, svgStr => {
var initialSvgStr = initialSvgStrs[index];
var initialNSAttrs = initialSvgStr ? initialSvgStr.match(FIND_NS_ATTRS_RE) : null;

if (initialSvgStr)
index++;

return initialSvgStr ? svgStr.replace(FIND_NS_ATTRS_RE, () => {
var replacement = initialNSAttrs ? initialNSAttrs.join('') : '';

if (initialNSAttrs)
initialNSAttrs = null;

return replacement;
}) : svgStr;
});
}
43 changes: 43 additions & 0 deletions test/client/fixtures/sandbox/code-instrumentation/getters-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,46 @@ test('we should clean up hammerhead script and style for all elements(GH-1079)',
ok(checkProperty(innerHTML));
ok(checkProperty(outerHTML));
});

test('we should clean up html and remove extra namespaces from svg (GH-1083)', function () {
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
var a = document.createElement('a');
var div = document.createElement('div');
var nativeSvg = nativeMethods.createElementNS.call(document, 'http://www.w3.org/2000/svg', 'svg');
var nativeA = nativeMethods.createElement.call(document, 'a');
var nativeDiv = nativeMethods.createElement.call(document, 'div');

a.setAttribute('href', '/path');
nativeMethods.setAttribute.call(nativeA, 'href', '/path');

a.innerText = nativeA.innerHTML = 'link';

svg.appendChild(a);
nativeMethods.appendChild.call(nativeSvg, nativeA);

div.appendChild(svg);
nativeMethods.appendChild.call(nativeDiv, nativeSvg);

strictEqual(getProperty(div, 'innerHTML'), nativeDiv.innerHTML);

div.innerHTML = nativeDiv.innerHTML = '';

svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
nativeMethods.setAttribute.call(nativeSvg, 'xmlns:xlink', 'http://www.w3.org/1999/xlink');

div.appendChild(svg.cloneNode(true));
nativeMethods.appendChild.call(nativeDiv, nativeMethods.cloneNode.call(nativeSvg, true));

strictEqual(getProperty(div, 'innerHTML'), nativeDiv.innerHTML);

// NOTE: IE added additional attributes with namespaces
// such as 'xmlns:NS2=""', NS2:xmlns:ns1=""
// after setting div.innerHTML property
div.innerHTML = div.innerHTML;
nativeDiv.innerHTML = nativeDiv.innerHTML;

div.appendChild(svg);
nativeMethods.appendChild.call(nativeDiv, nativeSvg);

strictEqual(getProperty(div, 'innerHTML'), nativeDiv.innerHTML);
});

0 comments on commit 5c10a88

Please sign in to comment.