UNPKG

@dodona/papyros

Version:

Scratchpad for multiple programming languages in the browser.

170 lines (165 loc) 6.67 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, state } from "lit/decorators.js"; import { PapyrosElement } from "./PapyrosElement"; import { css, html } from "lit"; import { createRef, ref } from "lit/directives/ref.js"; import { CODE_TAB } from "../state/InputOutput"; import { arrayBufferToBase64, isTextMimeType } from "../../util/Util"; import "./code_runner/Code"; import "./code_runner/RunState"; import "./code_runner/ButtonLint"; import "./EditorTabs"; import "./FileViewer"; let CodeRunner = class CodeRunner extends PapyrosElement { constructor() { super(...arguments); this.dragOver = false; this.dropZoneRef = createRef(); this.onDragOver = (e) => { e.preventDefault(); e.stopPropagation(); if (this.papyros.debugger.active) return; if (!this.dragOver) this.dragOver = true; }; this.onDragLeave = (e) => { const dropZone = this.dropZoneRef.value; // Only react if leaving the drop zone, not moving between children if (e.relatedTarget && (dropZone === null || dropZone === void 0 ? void 0 : dropZone.contains(e.relatedTarget))) return; this.dragOver = false; }; this.onDrop = (e) => { e.preventDefault(); e.stopPropagation(); this.dragOver = false; if (this.papyros.debugger.active || !e.dataTransfer) return; for (const file of Array.from(e.dataTransfer.files)) { this.readAndAddFile(file); } if (e.dataTransfer.types.includes("text/uri-list")) { const uriList = e.dataTransfer.getData("text/uri-list"); const urls = uriList .split(/\r?\n/) .map((line) => line.trim()) .filter((line) => line && !line.startsWith("#")); for (const url of urls) { void this.papyros.runner.fetchAndAddUrl(url); } } }; } static get styles() { return css ` :host { width: 100%; display: flex; flex-direction: column; border-radius: 0.5rem; } .drop-zone { display: flex; flex-direction: column; flex-grow: 1; min-height: 0; position: relative; } .drop-zone.drag-over::after { content: ""; position: absolute; inset: 0; border: 2px dashed var(--md-sys-color-primary); border-radius: 0.5rem; background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent); pointer-events: none; z-index: 10; } .editor { flex-grow: 1; min-height: 0; position: relative; } p-run-state { position: absolute; bottom: 0; right: 6px; background-color: var(--md-sys-color-surface-container); padding: 0.25rem 1rem; border-top-right-radius: 1rem; border-top-left-radius: 1rem; } p-button-lint { background-color: var(--md-sys-color-surface-container); } `; } firstUpdated() { const dropZone = this.dropZoneRef.value; if (!dropZone) return; // Use capture phase so we intercept before CodeMirror handles the drop dropZone.addEventListener("dragover", this.onDragOver, true); dropZone.addEventListener("dragleave", this.onDragLeave, true); dropZone.addEventListener("drop", this.onDrop, true); } disconnectedCallback() { super.disconnectedCallback(); const dropZone = this.dropZoneRef.value; if (!dropZone) return; dropZone.removeEventListener("dragover", this.onDragOver, true); dropZone.removeEventListener("dragleave", this.onDragLeave, true); dropZone.removeEventListener("drop", this.onDrop, true); } readAndAddFile(file) { const reader = new FileReader(); if (isTextMimeType(file.type)) { reader.onload = () => { this.papyros.runner.upsertFile(file.name, reader.result, false); }; reader.readAsText(file); } else { reader.onload = () => { this.papyros.runner.upsertFile(file.name, arrayBufferToBase64(reader.result), true); }; reader.readAsArrayBuffer(file); } } render() { const files = this.papyros.debugger.active ? this.papyros.debugger.debugFiles : this.papyros.io.files; const activeTab = this.papyros.io.activeEditorTab; const activeFile = files.find((f) => f.name === activeTab); return html ` <div ${ref(this.dropZoneRef)} class="drop-zone ${this.dragOver ? "drag-over" : ""}"> <p-editor-tabs .papyros=${this.papyros} .files=${files}></p-editor-tabs> <div class="editor"> ${activeTab === CODE_TAB ? html `<p-code .papyros=${this.papyros}></p-code>` : html `<p-file-viewer .papyros=${this.papyros} .file=${activeFile}></p-file-viewer>`} ${this.papyros.runner.stateMessage ? html `<p-run-state .papyros=${this.papyros}></p-run-state>` : ""} </div> <p-button-lint .papyros=${this.papyros}> <slot name="buttons"></slot> </p-button-lint> </div> `; } }; __decorate([ state() ], CodeRunner.prototype, "dragOver", void 0); CodeRunner = __decorate([ customElement("p-code-runner") ], CodeRunner); export { CodeRunner }; //# sourceMappingURL=CodeRunner.js.map