UNPKG

@dodona/papyros

Version:

Scratchpad for multiple programming languages in the browser.

253 lines (242 loc) 10.2 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { customElement } from "lit/decorators.js"; import { css, html } from "lit"; import { OutputType, OUTPUT_TAB, TURTLE_TAB } from "../state/InputOutput"; import { PapyrosElement } from "./PapyrosElement"; import { tabButtonStyles } from "./shared-styles"; import "@material/web/icon/icon"; let Output = class Output extends PapyrosElement { static get styles() { return css ` :host { width: 100%; height: 100%; display: flex; flex-direction: column; } .tabs { display: flex; flex-direction: row; gap: 0.25rem; padding-top: 0.25rem; flex-shrink: 0; position: relative; z-index: 1; } .content { flex: 1; overflow: auto; container-type: size; padding: 0.75rem; background-color: var(--md-sys-color-surface-container-highest); } .content.turtle { margin-top: -1px; padding: 0; background-color: transparent; } img { max-width: 100%; max-height: 300px; display: block; margin: 0.5rem 0; } img.turtle { max-width: 100cqw; max-height: 100cqh; margin: 0; box-sizing: border-box; background-color: var(--md-sys-color-surface-container-highest); border: 1px solid var(--md-sys-color-outline-variant); } .turtle-placeholder { width: 400px; height: 400px; max-width: 100cqw; max-height: 100cqh; margin: 0; background-color: var(--md-sys-color-surface-container-highest); border: 1px solid var(--md-sys-color-outline-variant); } pre { font-family: monospace; margin: 0; } .error { color: var(--md-sys-color-error); } .place-holder { color: var(--md-sys-color-on-surface); opacity: 0.5; } md-icon { vertical-align: bottom; } ${tabButtonStyles} `; } get maxOutputLength() { if (this.papyros.debugger.active && this.papyros.debugger.debugOutputs !== undefined) { return this.papyros.debugger.debugOutputs; } return this.papyros.constants.maxOutputLength; } get outputs() { return this.papyros.io.output.slice(0, this.maxOutputLength); } get overflow() { return this.papyros.io.output.slice(this.maxOutputLength); } get showOverflowWarning() { return !this.papyros.debugger.active && this.papyros.io.output.length > this.maxOutputLength; } get downloadOverflowUrl() { const blob = new Blob(this.overflow.map((o) => { if (o.type === OutputType.img || o.type === OutputType.turtle) { return `[Image output of type ${o.contentType} omitted]\n`; } else if (o.type === OutputType.stdout) { return o.content; } else if (o.type === OutputType.stderr) { if (typeof o.content === "string") { return `Error: ${o.content}\n`; } else { const errorObject = o.content; let errorString = `Error: ${errorObject.name}\nInfo: ${errorObject.info}\nTraceback: ${errorObject.traceback}\n`; if (errorObject.where) { errorString += `Where: ${errorObject.where.trim()}\n`; } if (errorObject.what) { errorString += `What: ${errorObject.what.trim()}\n`; } if (errorObject.why) { errorString += `Why: ${errorObject.why.trim()}\n`; } return errorString; } } else { return "[Unsupported output type omitted]\n"; } }), { type: "text/plain" }); return URL.createObjectURL(blob); } get renderedOutputs() { let outputsToRender; if (this.papyros.io.activeOutputTab === TURTLE_TAB) { // Latest snapshot within this.outputs (which is sliced by the debugger's current // step via maxOutputLength) — so stepping the debugger shows the drawing build up. const lastIdx = this.outputs.findLastIndex((o) => o.type === OutputType.turtle); outputsToRender = lastIdx >= 0 ? [this.outputs[lastIdx]] : []; } else { outputsToRender = this.outputs.filter((o) => o.type !== OutputType.turtle); } return outputsToRender.map((o) => { var _a, _b, _c; if (o.type === OutputType.stdout) { return html `${o.content}`; } else if (o.type === OutputType.img) { const mimeType = (_a = o.contentType) !== null && _a !== void 0 ? _a : "image/png"; return html `<img src="data:${mimeType},${o.content}"></img>`; } else if (o.type === OutputType.turtle) { const mimeType = (_b = o.contentType) !== null && _b !== void 0 ? _b : "image/svg+xml;base64"; return html `<img class="turtle" src="data:${mimeType},${o.content}"></img>`; } else if (o.type === OutputType.stderr) { if (typeof o.content === "string") { return html `<span class="error">${o.content}</span>`; } else { const errorObject = o.content; const errorHTML = [ // an array to avoid unintentional spaces/newlines html `<md-icon title="${errorObject.info}"> ${this.papyros.constants.icons.help} </md-icon> ${errorObject.name} traceback: <md-icon title="${errorObject.traceback}"> ${this.papyros.constants.icons.info} </md-icon> `, html `<span class="where">${(_c = errorObject.where) === null || _c === void 0 ? void 0 : _c.trim()}</span> `, ]; if (errorObject.what) { errorHTML.push(html `<span class="what">${errorObject.what.trim()}</span> `); } if (errorObject.why) { errorHTML.push(html `<span class="why">${errorObject.why.trim()}</span> `); } return html `<span class="error">${errorHTML}</span>`; } } else { return html ``; // unsupported output type } }); } get showTurtleTab() { return this.papyros.io.hasTurtleOutput || this.papyros.io.activeOutputTab === TURTLE_TAB; } renderTabs() { const activeTab = this.papyros.io.activeOutputTab; return html ` <div class="tabs"> <button class=${activeTab === OUTPUT_TAB ? "active" : ""} @click=${() => this.papyros.io.selectOutputTab(OUTPUT_TAB)} > ${this.t("Papyros.output_tab_output")} </button> ${this.showTurtleTab ? html ` <button class=${activeTab === TURTLE_TAB ? "active" : ""} @click=${() => this.papyros.io.selectOutputTab(TURTLE_TAB)} > ${this.t("Papyros.output_tab_turtle")} </button> ` : html ``} </div> `; } render() { const activeTab = this.papyros.io.activeOutputTab; const rendered = this.renderedOutputs; const showPlaceholder = activeTab === OUTPUT_TAB && rendered.length === 0; const showTurtlePlaceholder = activeTab === TURTLE_TAB && rendered.length === 0; const showOverflow = activeTab === OUTPUT_TAB && this.showOverflowWarning; return html ` ${this.renderTabs()} <div class="content ${activeTab === TURTLE_TAB ? "turtle" : ""}"> ${showPlaceholder ? html `<pre class="place-holder">${this.t("Papyros.output_placeholder")}</pre>` : showTurtlePlaceholder ? html `<div class="turtle-placeholder"></div>` : html `<pre>${rendered}</pre>`} ${showOverflow ? html ` <p> ${this.t("Papyros.output_overflow")} <a href="${this.downloadOverflowUrl}" download="papyros_output.txt"> ${this.t("Papyros.output_overflow_download")} </a> </p> ` : html ``} </div> `; } }; Output = __decorate([ customElement("p-output") ], Output); export { Output }; //# sourceMappingURL=Output.js.map