83 lines
2.7 KiB
JavaScript
83 lines
2.7 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow
|
|
*/
|
|
|
|
/* globals MSApp */
|
|
|
|
import {SVG_NAMESPACE} from './DOMNamespaces';
|
|
import {enableTrustedTypesIntegration} from 'shared/ReactFeatureFlags';
|
|
|
|
// SVG temp container for IE lacking innerHTML
|
|
let reusableSVGContainer: HTMLElement;
|
|
|
|
function setInnerHTMLImpl(
|
|
node: Element,
|
|
html: {valueOf(): {toString(): string, ...}, ...},
|
|
): void {
|
|
if (node.namespaceURI === SVG_NAMESPACE) {
|
|
if (__DEV__) {
|
|
if (enableTrustedTypesIntegration) {
|
|
// TODO: reconsider the text of this warning and when it should show
|
|
// before enabling the feature flag.
|
|
if (typeof trustedTypes !== 'undefined') {
|
|
console.error(
|
|
"Using 'dangerouslySetInnerHTML' in an svg element with " +
|
|
'Trusted Types enabled in an Internet Explorer will cause ' +
|
|
'the trusted value to be converted to string. Assigning string ' +
|
|
"to 'innerHTML' will throw an error if Trusted Types are enforced. " +
|
|
"You can try to wrap your svg element inside a div and use 'dangerouslySetInnerHTML' " +
|
|
'on the enclosing div instead.',
|
|
);
|
|
}
|
|
}
|
|
}
|
|
if (!('innerHTML' in node)) {
|
|
// IE does not have innerHTML for SVG nodes, so instead we inject the
|
|
// new markup in a temp node and then move the child nodes across into
|
|
// the target node
|
|
reusableSVGContainer =
|
|
reusableSVGContainer || document.createElement('div');
|
|
reusableSVGContainer.innerHTML =
|
|
'<svg>' + html.valueOf().toString() + '</svg>';
|
|
const svgNode = reusableSVGContainer.firstChild;
|
|
while (node.firstChild) {
|
|
node.removeChild(node.firstChild);
|
|
}
|
|
// $FlowFixMe[incompatible-use]
|
|
// $FlowFixMe[incompatible-type]
|
|
while (svgNode.firstChild) {
|
|
node.appendChild(svgNode.firstChild);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
node.innerHTML = (html: any);
|
|
}
|
|
|
|
let setInnerHTML: (
|
|
node: Element,
|
|
html: {valueOf(): {toString(): string, ...}, ...},
|
|
) => void = setInnerHTMLImpl;
|
|
// $FlowFixMe[cannot-resolve-name]
|
|
if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
|
|
/**
|
|
* Create a function which has 'unsafe' privileges (required by windows8 apps)
|
|
*/
|
|
setInnerHTML = function (
|
|
node: Element,
|
|
html: {valueOf(): {toString(): string, ...}, ...},
|
|
): void {
|
|
// $FlowFixMe[cannot-resolve-name]
|
|
return MSApp.execUnsafeLocalFunction(function () {
|
|
return setInnerHTMLImpl(node, html);
|
|
});
|
|
};
|
|
}
|
|
|
|
export default setInnerHTML;
|