UNPKG

@trailstash/ultra

Version:

A web based tool for making MapLibre GL maps with data from sources such as Overpass, GeoJSON, GPX, KML, TCX, etc

106 lines (102 loc) 2.92 kB
import { h } from "../lib/dom.js"; const style = new CSSStyleSheet(); style.replace(` :host { display: block; } textarea { display: block; height: 100%; width: 100%; margin: 0; padding: 5px; border: 0; box-sizing: border-box; } `); export class CodeEditor extends HTMLElement { static observedAttributes = ["source"]; get source() { return this.getAttribute("source"); } set source(value) { return this.setAttribute("source", value); } constructor() { super(); } attributeChangedCallback(name, oldValue, newValue) { if (oldValue != newValue) { this.dispatchEvent(new Event("change")); } if (this.refs && this.refs.textarea.value !== newValue) { this.refs.textarea.value = newValue; } } connectedCallback() { const shadow = this.attachShadow({ mode: "open" }); shadow.adoptedStyleSheets.push(style); const textarea = h("textarea", { autofocus: this.autofocus, spellcheck: false, autocapitalize: "off", value: this.source, }); this.refs = { textarea }; this.refs.textarea.selectionStart = 0; this.refs.textarea.selectionEnd = 0; shadow.appendChild(textarea); textarea.addEventListener("dragenter", (e) => { e.preventDefault(); }); textarea.addEventListener("dragover", (e) => { e.preventDefault(); }); textarea.addEventListener("drop", async (e) => { e.preventDefault(); const item = e.dataTransfer.items[0]; if (item.kind === "file") { this.source = await item.getAsFile().text(); } else { this.source = e.dataTransfer.getData("text/plain"); } }); textarea.addEventListener("keydown", (e) => { const start = e.target.selectionStart; const end = e.target.selectionEnd; const textFromLastNewLine = start === 0 ? "" : e.target.value.slice( e.target.value.slice(0, start).lastIndexOf("\n") + 1, ); const leadingWhitespace = textFromLastNewLine.match(/^([ \t])+/)?.[0] || ""; if (e.key == "Tab") { e.preventDefault(); e.target.value = e.target.value.substring(0, start) + " " + e.target.value.substring(end); e.target.selectionStart = e.target.selectionEnd = start + 2; } if (e.key == "Enter") { e.preventDefault(); if (e.ctrlKey) { this.dispatchEvent(new Event("run")); } else { e.target.value = e.target.value.substring(0, start) + "\n" + leadingWhitespace + e.target.value.substring(end); e.target.selectionStart = e.target.selectionEnd = start + 1 + leadingWhitespace.length; } } }); textarea.addEventListener("keyup", (e) => { this.source = e.target.value; }); } }