import React = require("react"); import ReactDOM = require("react-dom"); import { bubbleHTMLIframeEvents, Point } from "tandem-common"; import { Consumer } from "react-dnd/lib/DragDropContext"; export class Isolate extends React.Component< { inheritCSS?: boolean; onMouseDown?: any; onKeyDown?: any; onLoad?: any; scrollPosition?: Point; children: any; ignoreInputEvents?: boolean; translateMousePositions?: boolean; onScroll?: any; scrolling?: boolean; style?: any; onWheel?: any; onDragOver?: any; className?: string; onDrop?: any; }, any > { private _mountElement: any; private _iframe: HTMLIFrameElement; private _dragDropManager: any; componentDidMount() { if (window["$synthetic"]) { return; } this._dragDropManager.getBackend().addEventListeners(this.window); if (this.props.inheritCSS) { const head = this.head; const tags = [ ...Array.prototype.slice.call( document.getElementsByTagName("style"), 0 ), ...Array.prototype.slice.call(document.getElementsByTagName("link"), 0) ]; Array.prototype.forEach.call(tags, function(style) { head.appendChild(style.cloneNode(true)); }); } this.body.appendChild((this._mountElement = document.createElement("div"))); if (this.props.onMouseDown) { this.body.addEventListener("mousedown", this.props.onMouseDown); } if (this.props.onKeyDown) { this.body.addEventListener("keydown", this.props.onKeyDown); } this._render(); this._addListeners(); } componentWillUnmount() { if (this._dragDropManager) { this._dragDropManager.getBackend().removeEventListeners(this.window); } } componentDidUpdate() { this._render(); const scrollPosition = this.props.scrollPosition as Point; if (this.window && scrollPosition) { if ( scrollPosition.left !== this.window.scrollX || scrollPosition.top !== this.window.scrollY ) { this.window.scrollTo(scrollPosition.left, scrollPosition.top); } } } get window(): Window { return this._iframe && this._iframe.contentWindow; } get head() { return this.window.document.head; } get body() { return this.window.document.body; } onLoad = () => { if (this.props.onLoad) this.props.onLoad(); }; _render() { if (window["$synthetic"]) return; if (this.props.children && this._mountElement) { ReactDOM.render(this.props.children, this._mountElement); } } _addListeners() { bubbleHTMLIframeEvents(this._iframe, { ignoreInputEvents: this.props.ignoreInputEvents, translateMousePositions: this.props.translateMousePositions }); } onWheel = event => { this.props.onWheel(event); }; onScroll = event => { if (this.props.onScroll) this.props.onScroll(event); if (this.props.scrolling === false) { const db = this._iframe.contentDocument; db.body.scrollLeft = db.body.scrollTop = 0; } }; setIframe = (iframe: HTMLIFrameElement) => { this._iframe = iframe; }; receiveDragDropManager(manager: any) { if (this._dragDropManager) { return; } this._dragDropManager = manager; } onTouchMove = () => {}; render() { // TODO - eventually want to use iframes. Currently not supported though. if (window["$synthetic"]) { return {this.props.children}; } return ( {({ dragDropManager }) => { this.receiveDragDropManager(dragDropManager); return (