429 lines · 14.1 KB
/* global window, document, fetch */
// Runs inside the sandboxed, opaque-origin editor frame. Plain browser JS: it is inlined into the frame
// HTML and allowed by CSP hash, so it must not import anything.
(function main() {
  "use strict";
  // The frame document is served by the forge itself; only its runtime origin is opaque.
  var forgeOrigin = new URL(window.location.href).origin;
  var parentOrigin = forgeOrigin;
  var apiBase = forgeOrigin;
  var token = null;
  var session = null;
  var files = [];
  var buffers = new Map();
  var deleted = new Set();
  var openTabs = [];
  var active = null;
  var collapsed = new Set();

  function $(id) {
    return document.getElementById(id);
  }

  function el(tag, attrs, children) {
    var node = document.createElement(tag);
    Object.keys(attrs || {}).forEach(function (key) {
      if (key === "text") node.textContent = attrs[key];
      else if (key === "style") node.style.cssText = attrs[key];
      else if (key.slice(0, 2) === "on") node.addEventListener(key.slice(2), attrs[key]);
      else node.setAttribute(key, attrs[key]);
    });
    (children || []).forEach(function (child) {
      if (child) node.appendChild(child);
    });
    return node;
  }

  function status(text, isError) {
    var bar = $("status-msg");
    bar.textContent = text;
    bar.className = isError ? "error" : "";