mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-02-14 12:15:12 +00:00
Sandbox HTML and JavaScript outputs in iFrame
This commit is contained in:
parent
d8fe4ed77f
commit
9aeb349d74
@ -1,16 +1,14 @@
|
|||||||
// Manages all the redux logic for the notebook nteract code
|
// Manages all the redux logic for the notebook nteract code
|
||||||
// TODO: Merge with NotebookClient?
|
// TODO: Merge with NotebookClient?
|
||||||
import { NotebookWorkspaceConnectionInfo } from "../../Contracts/DataModels";
|
|
||||||
import * as Constants from "../../Common/Constants";
|
|
||||||
import { CdbAppState, makeCdbRecord } from "./NotebookComponent/types";
|
|
||||||
|
|
||||||
// Vendor modules
|
// Vendor modules
|
||||||
import {
|
import {
|
||||||
actions,
|
actions,
|
||||||
AppState,
|
AppState,
|
||||||
createHostRef,
|
ContentRecord, createHostRef,
|
||||||
createKernelspecsRef,
|
createKernelspecsRef,
|
||||||
makeAppRecord,
|
HostRecord,
|
||||||
|
HostRef,
|
||||||
|
IContentProvider, KernelspecsRef, makeAppRecord,
|
||||||
makeCommsRecord,
|
makeCommsRecord,
|
||||||
makeContentsRecord,
|
makeContentsRecord,
|
||||||
makeEditorsRecord,
|
makeEditorsRecord,
|
||||||
@ -18,24 +16,22 @@ import {
|
|||||||
makeHostsRecord,
|
makeHostsRecord,
|
||||||
makeJupyterHostRecord,
|
makeJupyterHostRecord,
|
||||||
makeStateRecord,
|
makeStateRecord,
|
||||||
makeTransformsRecord,
|
makeTransformsRecord
|
||||||
ContentRecord,
|
|
||||||
HostRecord,
|
|
||||||
HostRef,
|
|
||||||
KernelspecsRef,
|
|
||||||
IContentProvider,
|
|
||||||
} from "@nteract/core";
|
} from "@nteract/core";
|
||||||
|
import { configOption, createConfigCollection, defineConfigOption } from "@nteract/mythic-configuration";
|
||||||
import { Media } from "@nteract/outputs";
|
import { Media } from "@nteract/outputs";
|
||||||
import TransformVDOM from "@nteract/transform-vdom";
|
import TransformVDOM from "@nteract/transform-vdom";
|
||||||
import * as Immutable from "immutable";
|
import * as Immutable from "immutable";
|
||||||
import { Store, AnyAction, MiddlewareAPI, Middleware, Dispatch } from "redux";
|
|
||||||
|
|
||||||
import configureStore from "./NotebookComponent/store";
|
|
||||||
|
|
||||||
import { Notification } from "react-notification-system";
|
import { Notification } from "react-notification-system";
|
||||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import { AnyAction, Dispatch, Middleware, MiddlewareAPI, Store } from "redux";
|
||||||
|
import * as Constants from "../../Common/Constants";
|
||||||
|
import { NotebookWorkspaceConnectionInfo } from "../../Contracts/DataModels";
|
||||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||||
import { configOption, createConfigCollection, defineConfigOption } from "@nteract/mythic-configuration";
|
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
|
import configureStore from "./NotebookComponent/store";
|
||||||
|
import { CdbAppState, makeCdbRecord } from "./NotebookComponent/types";
|
||||||
|
import IFrameHTML from "./NotebookRenderer/outputs/IFrameHTML";
|
||||||
|
import IFrameJavaScript from "./NotebookRenderer/outputs/IFrameJavaScript";
|
||||||
|
|
||||||
export type KernelSpecsDisplay = { name: string; displayName: string };
|
export type KernelSpecsDisplay = { name: string; displayName: string };
|
||||||
|
|
||||||
@ -168,8 +164,8 @@ export class NotebookClientV2 {
|
|||||||
"application/vnd.vega.v5+json": NullTransform,
|
"application/vnd.vega.v5+json": NullTransform,
|
||||||
"application/vdom.v1+json": TransformVDOM,
|
"application/vdom.v1+json": TransformVDOM,
|
||||||
"application/json": Media.Json,
|
"application/json": Media.Json,
|
||||||
"application/javascript": Media.JavaScript,
|
"application/javascript": IFrameJavaScript,
|
||||||
"text/html": Media.HTML,
|
"text/html": IFrameHTML,
|
||||||
"text/markdown": Media.Markdown,
|
"text/markdown": Media.Markdown,
|
||||||
"text/latex": Media.LaTeX,
|
"text/latex": Media.LaTeX,
|
||||||
"image/svg+xml": Media.SVG,
|
"image/svg+xml": Media.SVG,
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/**
|
||||||
|
* The HTML string that will be rendered.
|
||||||
|
*/
|
||||||
|
data: string;
|
||||||
|
/**
|
||||||
|
* The media type associated with the HTML
|
||||||
|
* string. This defaults to text/html.
|
||||||
|
*/
|
||||||
|
mediaType: "text/html";
|
||||||
|
}
|
||||||
|
|
||||||
|
const StyledIFrame = styled.iframe`
|
||||||
|
width: 100%;
|
||||||
|
border-style: unset;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export class IFrameHTML extends React.PureComponent<Props> {
|
||||||
|
static defaultProps = {
|
||||||
|
data: "",
|
||||||
|
mediaType: "text/html"
|
||||||
|
};
|
||||||
|
|
||||||
|
frame?: HTMLIFrameElement;
|
||||||
|
|
||||||
|
appendChildDOM(): void {
|
||||||
|
if (!this.frame) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.frame.contentDocument.open();
|
||||||
|
this.frame.contentDocument.write(this.props.data);
|
||||||
|
this.frame.contentDocument.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount(): void {
|
||||||
|
this.appendChildDOM();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(): void {
|
||||||
|
this.appendChildDOM();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<StyledIFrame
|
||||||
|
ref={frame => this.frame = frame}
|
||||||
|
allow="accelerometer; autoplay; camera; gyroscope; magnetometer; microphone; xr-spatial-tracking"
|
||||||
|
sandbox="allow-downloads allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-popups-to-escape-sandbox"
|
||||||
|
onLoad={() => this.onFrameLoaded()} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onFrameLoaded() {
|
||||||
|
this.frame.height = (this.frame.contentDocument.body.scrollHeight + 4) + "px";
|
||||||
|
this.frame.contentDocument.body.style.margin = "0px";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IFrameHTML;
|
@ -0,0 +1,28 @@
|
|||||||
|
import React from "react";
|
||||||
|
import IFrameHTML from "./IFrameHTML";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/**
|
||||||
|
* The JavaScript code that we would like to execute.
|
||||||
|
*/
|
||||||
|
data: string;
|
||||||
|
/**
|
||||||
|
* The media type associated with our component.
|
||||||
|
*/
|
||||||
|
mediaType: "text/javascript";
|
||||||
|
}
|
||||||
|
|
||||||
|
export class IFrameJavaScript extends React.PureComponent<Props> {
|
||||||
|
static defaultProps = {
|
||||||
|
data: "",
|
||||||
|
mediaType: "application/javascript"
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<IFrameHTML data={`<script>${this.props.data}</script>`} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IFrameJavaScript;
|
Loading…
x
Reference in New Issue
Block a user