Reviewed By: bhamodi Differential Revision: D33331422 fbshipit-source-id: 016e8dcc0c0c7f1fc353a348b54fda0d5e2ddc01
120 lines
3.2 KiB
TypeScript
120 lines
3.2 KiB
TypeScript
/**
|
|
* 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.
|
|
*
|
|
* @format
|
|
*/
|
|
|
|
import React from 'react';
|
|
import {styled, colors, FlexColumn} from 'flipper';
|
|
|
|
const devToolsNodeId = (url: string) =>
|
|
`hermes-chromedevtools-out-of-react-node-${url.replace(/\W+/g, '-')}`;
|
|
|
|
// TODO: build abstraction of this: T62306732
|
|
// TODO: reuse reactdevtools/DevToolsEmbedder for this
|
|
const TARGET_CONTAINER_ID = 'flipper-out-of-contents-container'; // should be a hook in the future
|
|
|
|
function createDevToolsNode(
|
|
url: string,
|
|
marginTop: string | null,
|
|
): HTMLElement {
|
|
const existing = findDevToolsNode(url);
|
|
if (existing) {
|
|
return existing;
|
|
}
|
|
|
|
const wrapper = document.createElement('div');
|
|
wrapper.id = devToolsNodeId(url);
|
|
wrapper.style.height = '100%';
|
|
wrapper.style.width = '100%';
|
|
|
|
const iframe = document.createElement(
|
|
'webview',
|
|
) as unknown as HTMLIFrameElement;
|
|
iframe.style.height = '100%';
|
|
iframe.style.width = '100%';
|
|
|
|
// HACK: chrome-devtools:// is blocked by the sandbox but devtools:// isn't for some reason.
|
|
iframe.src = url.replace(/^chrome-/, '');
|
|
|
|
wrapper.appendChild(iframe);
|
|
|
|
if (marginTop) {
|
|
document.getElementById(TARGET_CONTAINER_ID)!.style.marginTop = marginTop;
|
|
}
|
|
|
|
document.getElementById(TARGET_CONTAINER_ID)!.appendChild(wrapper);
|
|
return wrapper;
|
|
}
|
|
|
|
function findDevToolsNode(url: string): HTMLElement | null {
|
|
return document.querySelector('#' + devToolsNodeId(url));
|
|
}
|
|
|
|
function attachDevTools(devToolsNode: HTMLElement) {
|
|
devToolsNode.style.display = 'block';
|
|
document.getElementById(TARGET_CONTAINER_ID)!.style.display = 'block';
|
|
document.getElementById(TARGET_CONTAINER_ID)!.parentElement!.style.display =
|
|
'block';
|
|
document.getElementById(TARGET_CONTAINER_ID)!.parentElement!.style.height =
|
|
'100%';
|
|
}
|
|
|
|
function detachDevTools(devToolsNode: HTMLElement | null) {
|
|
document.getElementById(TARGET_CONTAINER_ID)!.style.display = 'none';
|
|
document.getElementById(TARGET_CONTAINER_ID)!.parentElement!.style.display =
|
|
'none';
|
|
|
|
if (devToolsNode) {
|
|
devToolsNode.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
const EmptyContainer = styled(FlexColumn)({
|
|
height: '100%',
|
|
width: '100%',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
backgroundColor: colors.light02,
|
|
});
|
|
|
|
type ChromeDevToolsProps = {
|
|
url: string;
|
|
marginTop: string | null;
|
|
};
|
|
|
|
export default class ChromeDevTools extends React.Component<ChromeDevToolsProps> {
|
|
createDevTools(url: string, marginTop: string | null) {
|
|
const devToolsNode = createDevToolsNode(url, marginTop);
|
|
attachDevTools(devToolsNode);
|
|
}
|
|
|
|
hideDevTools(_url: string) {
|
|
detachDevTools(findDevToolsNode(this.props.url));
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.createDevTools(this.props.url, this.props.marginTop);
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.hideDevTools(this.props.url);
|
|
}
|
|
|
|
componentDidUpdate(prevProps: ChromeDevToolsProps) {
|
|
const oldUrl = prevProps.url;
|
|
const newUrl = this.props.url;
|
|
if (oldUrl != newUrl) {
|
|
this.hideDevTools(oldUrl);
|
|
this.createDevTools(newUrl, this.props.marginTop);
|
|
}
|
|
}
|
|
|
|
render() {
|
|
return <EmptyContainer />;
|
|
}
|
|
}
|