Skip to content

Commit

Permalink
Merge pull request #1663 from nteract/nteract-outputs-upgrade
Browse files Browse the repository at this point in the history
Upgrade @nteract/outputs
  • Loading branch information
BenRussert committed Jun 15, 2019
2 parents 1e9658d + 7de4afc commit 3e20663
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 82 deletions.
21 changes: 14 additions & 7 deletions lib/components/inspector.js
Expand Up @@ -2,12 +2,10 @@

import React from "react";
import { observer } from "mobx-react";
import { richestMimetype, transforms } from "@nteract/transforms";
import { RichMedia, Media } from "@nteract/outputs";

import { INSPECTOR_URI } from "./../utils";

const displayOrder = ["text/html", "text/markdown", "text/plain"];

import type Kernel from "./../kernel";

type Props = { store: { kernel: ?Kernel } };
Expand All @@ -21,10 +19,15 @@ const Inspector = observer(({ store: { kernel } }: Props) => {
if (!kernel) return hide();

const bundle = kernel.inspector.bundle;
const mimetype = richestMimetype(bundle, displayOrder, transforms);

if (!mimetype) return hide();
const Transform = transforms[mimetype];
if (
!bundle["text/html"] &&
!bundle["text/markdown"] &&
!bundle["text/plain"]
) {
return hide();
}

return (
<div
className="native-key-bindings"
Expand All @@ -33,7 +36,11 @@ const Inspector = observer(({ store: { kernel } }: Props) => {
fontSize: atom.config.get(`Hydrogen.outputAreaFontSize`) || "inherit"
}}
>
<Transform data={bundle[mimetype]} />
<RichMedia data={bundle}>
<Media.HTML />
<Media.Markdown />
<Media.Plain />
</RichMedia>
</div>
);
});
Expand Down
61 changes: 61 additions & 0 deletions lib/components/result-view/display.js
@@ -0,0 +1,61 @@
/* @flow */

import React from "react";
import { toJS } from "mobx";
import {
DisplayData,
ExecuteResult,
StreamText,
KernelOutputError,
Output,
Media,
RichMedia
} from "@nteract/outputs";
import PlotlyTransform from "@nteract/transform-plotly";
import { VegaLite1, VegaLite2, Vega2, Vega3 } from "@nteract/transform-vega";

type Props = { output: any };

// All supported media types for output go here
export const supportedMediaTypes = (
<RichMedia>
<Vega3 />
<Vega2 />
<PlotlyTransform />
<VegaLite2 />
<VegaLite1 />
<Media.Json />
<Media.JavaScript />
<Media.HTML />
<Media.Markdown />
<Media.LaTeX />
<Media.SVG />
<Media.Image />
<Media.Plain />
</RichMedia>
);

export function isTextOutputOnly(data: Object) {
const supported = React.Children.map(
supportedMediaTypes.props.children,
mediaComponent => mediaComponent.props.mediaType
);
const bundleMediaTypes = [...Object.keys(data)].filter(mediaType =>
supported.includes(mediaType)
);

return bundleMediaTypes.length === 1 && bundleMediaTypes[0] === "text/plain"
? true
: false;
}

export default function Display(props: Props) {
return (
<Output output={toJS(props.output)}>
<ExecuteResult expanded>{supportedMediaTypes}</ExecuteResult>
<DisplayData expanded>{supportedMediaTypes}</DisplayData>
<StreamText expanded />
<KernelOutputError expanded />
</Output>
);
}
15 changes: 2 additions & 13 deletions lib/components/result-view/history.js
@@ -1,14 +1,10 @@
/* @flow */

import React from "react";
import { toJS } from "mobx";
import { observer } from "mobx-react";
import { Output } from "@nteract/display-area";
import { richestMimetype } from "@nteract/transforms";
import Display from "./display";
import Slider from "react-rangeslider";

import { transforms, displayOrder } from "./transforms";

import type OutputStore from "../../store/output";

const counterStyle = {
Expand Down Expand Up @@ -52,14 +48,7 @@ const History = observer(({ store }: { store: OutputStore }) => {
fontSize: atom.config.get(`Hydrogen.outputAreaFontSize`) || "inherit"
}}
>
<Output
output={toJS(output)}
displayOrder={displayOrder}
transforms={transforms}
theme="light"
models={{}}
expanded
/>
<Display output={output} />
</div>
</div>
) : null;
Expand Down
15 changes: 4 additions & 11 deletions lib/components/result-view/list.js
Expand Up @@ -2,9 +2,7 @@

import React from "react";
import { observer } from "mobx-react";
import { toJS } from "mobx";
import { Display } from "@nteract/display-area";
import { transforms, displayOrder } from "./transforms";
import Display from "./display";

type Props = { outputs: Array<Object> };

Expand Down Expand Up @@ -41,14 +39,9 @@ class ScrollList extends React.Component<Props> {
this.el = el;
}}
>
<Display
outputs={toJS(this.props.outputs)}
displayOrder={displayOrder}
transforms={transforms}
theme="light"
models={{}}
expanded={true}
/>
{this.props.outputs.map((output, index) => (
<Display output={output} key={index} />
))}
</div>
);
}
Expand Down
16 changes: 5 additions & 11 deletions lib/components/result-view/result-view.js
Expand Up @@ -3,9 +3,8 @@
import { CompositeDisposable } from "atom";
import React from "react";
import { observer } from "mobx-react";
import { action, observable, toJS } from "mobx";
import { Display } from "@nteract/display-area";
import { transforms, displayOrder } from "./transforms";
import { action, observable } from "mobx";
import Display from "./display";
import Status from "./status";

import type OutputStore from "./../../store/output";
Expand Down Expand Up @@ -182,14 +181,9 @@ class ResultViewComponent extends React.Component<Props> {
overflowY: "auto"
}}
>
<Display
outputs={toJS(outputs)}
displayOrder={displayOrder}
transforms={transforms}
theme="light"
models={{}}
expanded
/>
{outputs.map((output, index) => (
<Display output={output} key={index} />
))}
</div>
{isPlain ? null : (
<div className="toolbar">
Expand Down
26 changes: 0 additions & 26 deletions lib/components/result-view/transforms.js

This file was deleted.

14 changes: 4 additions & 10 deletions lib/store/output.js
@@ -1,19 +1,14 @@
/* @flow */

import { action, computed, observable } from "mobx";
import { richestMimetype } from "@nteract/transforms";
import _ from "lodash";
import {
escapeCarriageReturn,
escapeCarriageReturnSafe
} from "escape-carriage";

import {
transforms,
displayOrder
} from "./../components/result-view/transforms";

import type { IObservableArray } from "mobx";

import { isTextOutputOnly } from "../components/result-view/display";
const outputTypes = ["execute_result", "display_data", "stream", "error"];

/**
Expand Down Expand Up @@ -96,9 +91,8 @@ export default class OutputStore {
case "execute_result":
case "display_data": {
const bundle = output.data;
const mimetype = richestMimetype(bundle, displayOrder, transforms);
return mimetype === "text/plain"
? isSingleLine(bundle[mimetype], availableSpace)
return isTextOutputOnly(bundle)
? isSingleLine(bundle["text/plain"], availableSpace)
: false;
}
case "stream": {
Expand Down
7 changes: 3 additions & 4 deletions package.json
Expand Up @@ -60,11 +60,10 @@
"@babel/runtime-corejs2": "^7.0.0",
"@jupyterlab/services": "^0.52.0",
"@nteract/commutable": "^7.0.0",
"@nteract/display-area": "^4.4.8",
"@nteract/outputs": "^2.1.5",
"@nteract/mathjax": "^3.0.1",
"@nteract/transform-plotly": "^3.2.5",
"@nteract/transform-vega": "^3.2.6",
"@nteract/transforms": "^4.4.7",
"@nteract/transform-plotly": "^5.0.0",
"@nteract/transform-vega": "^5.0.2",
"anser": "^1.4.4",
"atom-select-list": "^0.7.0",
"escape-carriage": "^1.2.0",
Expand Down
44 changes: 44 additions & 0 deletions spec/components/display-spec.js
@@ -0,0 +1,44 @@
"use babel";

import React from "react";
import Enzyme, { mount } from "enzyme";
import Adapter from "enzyme-adapter-react-16";

import Display, {
isTextOutputOnly,
supportedMediaTypes
} from "../../lib/components/result-view/display";

Enzyme.configure({ adapter: new Adapter() });

const testOutput = {
output_type: "display_data",
data: {
"text/html": "<p>This is some HTML that <b>WILL</b> render</p>",
"text/plain": "This is some plain text that WILL NOT render"
},
metadata: {}
};

describe("Display output", () => {
const wrapper = mount(<Display output={testOutput} />);
it("renders the richest supported output", () => {
expect(wrapper.find("Plain").exists()).toEqual(false);
expect(wrapper.find("HTML").exists()).toEqual(true);
});
});

describe("textOutputOnly", () => {
let plainBundle = {
"text/plain": "I'm very plain",
"text/output-not-supported": "This should be ignored"
};
let richerBundle = {
"text/plain": "I'm very plain",
"text/html": "<div>I am a little <b>richer</b>!</div>"
};
it("should return true if text is the richest supported output", () => {
expect(isTextOutputOnly(plainBundle)).toEqual(true);
expect(isTextOutputOnly(richerBundle)).toEqual(false);
});
});

0 comments on commit 3e20663

Please sign in to comment.