UNPKG

@nteract/outputs

Version:

components for rendering outputs

70 lines (69 loc) 2.6 kB
"use strict"; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const React = __importStar(require("react")); const styled_components_1 = __importDefault(require("styled-components")); const outputStyle_1 = __importDefault(require("../outputStyle")); // Note: createRange and Range must be polyfilled on older browsers with // https://github.com/timdown/rangy function createFragment(html) { /** * createFragment takes in an HTML string and outputs a DOM element that is * treated as if it originated on the page "like normal". * @type {Node} - https://developer.mozilla.org/en-US/docs/Web/API/Node */ // Create a range to ensure that scripts are invoked from within the HTML const range = document.createRange(); const fragment = range.createContextualFragment(html); return fragment; } const StyledDiv = styled_components_1.default.div ` ${outputStyle_1.default} `; class HTML extends React.PureComponent { componentDidMount() { // clear out all DOM element children // This matters on server side render otherwise we'll get both the `innerHTML`ed // version + the fragment version right after each other // In the desktop app (and successive loads with tools like commuter) this // will be a no-op if (!this.el) { return; } while (this.el.firstChild) { this.el.removeChild(this.el.firstChild); } // DOM element appended with a real DOM Node fragment this.el.appendChild(createFragment(this.props.data)); } componentDidUpdate() { if (!this.el) { return; } // clear out all DOM element children while (this.el.firstChild) { this.el.removeChild(this.el.firstChild); } this.el.appendChild(createFragment(this.props.data)); } render() { return (React.createElement(StyledDiv, { dangerouslySetInnerHTML: { __html: this.props.data }, ref: el => { this.el = el; } })); } } exports.HTML = HTML; HTML.defaultProps = { data: "", mediaType: "text/html" }; exports.default = HTML;