Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
debugger.js361 linesDownload Raw Back to shared
1docReady(() => {2  if (!EVALEX_TRUSTED) {3    initPinBox();4  }5  // if we are in console mode, show the console.6  if (CONSOLE_MODE && EVALEX) {7    createInteractiveConsole();8  }9 10  const frames = document.querySelectorAll("div.traceback div.frame");11  if (EVALEX) {12    addConsoleIconToFrames(frames);13  }14  addEventListenersToElements(document.querySelectorAll("div.detail"), "click", () =>15    document.querySelector("div.traceback").scrollIntoView(false)16  );17  addToggleFrameTraceback(frames);18  addToggleTraceTypesOnClick(document.querySelectorAll("h2.traceback"));19  addInfoPrompt(document.querySelectorAll("span.nojavascript"));20  wrapPlainTraceback();21});22 23function addToggleFrameTraceback(frames) {24  frames.forEach((frame) => {25    frame.addEventListener("click", () => {26      frame.getElementsByTagName("pre")[0].parentElement.classList.toggle("expanded");27    });28  })29}30 31 32function wrapPlainTraceback() {33  const plainTraceback = document.querySelector("div.plain textarea");34  const wrapper = document.createElement("pre");35  const textNode = document.createTextNode(plainTraceback.textContent);36  wrapper.appendChild(textNode);37  plainTraceback.replaceWith(wrapper);38}39 40function initPinBox() {41  document.querySelector(".pin-prompt form").addEventListener(42    "submit",43    function (event) {44      event.preventDefault();45      const pin = encodeURIComponent(this.pin.value);46      const encodedSecret = encodeURIComponent(SECRET);47      const btn = this.btn;48      btn.disabled = true;49 50      fetch(51        `${document.location}?__debugger__=yes&cmd=pinauth&pin=${pin}&s=${encodedSecret}`52      )53        .then((res) => res.json())54        .then(({auth, exhausted}) => {55          if (auth) {56            EVALEX_TRUSTED = true;57            fadeOut(document.getElementsByClassName("pin-prompt")[0]);58          } else {59            alert(60              `Error: ${61                exhausted62                  ? "too many attempts.  Restart server to retry."63                  : "incorrect pin"64              }`65            );66          }67        })68        .catch((err) => {69          alert("Error: Could not verify PIN.  Network error?");70          console.error(err);71        })72        .finally(() => (btn.disabled = false));73    },74    false75  );76}77 78function promptForPin() {79  if (!EVALEX_TRUSTED) {80    const encodedSecret = encodeURIComponent(SECRET);81    fetch(82      `${document.location}?__debugger__=yes&cmd=printpin&s=${encodedSecret}`83    );84    const pinPrompt = document.getElementsByClassName("pin-prompt")[0];85    fadeIn(pinPrompt);86    document.querySelector('.pin-prompt input[name="pin"]').focus();87  }88}89 90/**91 * Helper function for shell initialization92 */93function openShell(consoleNode, target, frameID) {94  promptForPin();95  if (consoleNode) {96    slideToggle(consoleNode);97    return consoleNode;98  }99  let historyPos = 0;100  const history = [""];101  const consoleElement = createConsole();102  const output = createConsoleOutput();103  const form = createConsoleInputForm();104  const command = createConsoleInput();105 106  target.parentNode.appendChild(consoleElement);107  consoleElement.append(output);108  consoleElement.append(form);109  form.append(command);110  command.focus();111  slideToggle(consoleElement);112 113  form.addEventListener("submit", (e) => {114    handleConsoleSubmit(e, command, frameID).then((consoleOutput) => {115      output.append(consoleOutput);116      command.focus();117      consoleElement.scrollTo(0, consoleElement.scrollHeight);118      const old = history.pop();119      history.push(command.value);120      if (typeof old !== "undefined") {121        history.push(old);122      }123      historyPos = history.length - 1;124      command.value = "";125    });126  });127 128  command.addEventListener("keydown", (e) => {129    if (e.key === "l" && e.ctrlKey) {130      output.innerText = "--- screen cleared ---";131    } else if (e.key === "ArrowUp" || e.key === "ArrowDown") {132      // Handle up arrow and down arrow.133      if (e.key === "ArrowUp" && historyPos > 0) {134        e.preventDefault();135        historyPos--;136      } else if (e.key === "ArrowDown" && historyPos < history.length - 1) {137        historyPos++;138      }139      command.value = history[historyPos];140    }141    return false;142  });143 144  return consoleElement;145}146 147function addEventListenersToElements(elements, event, listener) {148  elements.forEach((el) => el.addEventListener(event, listener));149}150 151/**152 * Add extra info153 */154function addInfoPrompt(elements) {155  for (let i = 0; i < elements.length; i++) {156    elements[i].innerHTML =157      "<p>To switch between the interactive traceback and the plaintext " +158      'one, you can click on the "Traceback" headline. From the text ' +159      "traceback you can also create a paste of it. " +160      (!EVALEX161        ? ""162        : "For code execution mouse-over the frame you want to debug and " +163          "click on the console icon on the right side." +164          "<p>You can execute arbitrary Python code in the stack frames and " +165          "there are some extra helpers available for introspection:" +166          "<ul><li><code>dump()</code> shows all variables in the frame" +167          "<li><code>dump(obj)</code> dumps all that's known about the object</ul>");168    elements[i].classList.remove("nojavascript");169  }170}171 172function addConsoleIconToFrames(frames) {173  for (let i = 0; i < frames.length; i++) {174    let consoleNode = null;175    const target = frames[i];176    const frameID = frames[i].id.substring(6);177 178    for (let j = 0; j < target.getElementsByTagName("pre").length; j++) {179      const img = createIconForConsole();180      img.addEventListener("click", (e) => {181        e.stopPropagation();182        consoleNode = openShell(consoleNode, target, frameID);183        return false;184      });185      target.getElementsByTagName("pre")[j].append(img);186    }187  }188}189 190function slideToggle(target) {191  target.classList.toggle("active");192}193 194/**195 * toggle traceback types on click.196 */197function addToggleTraceTypesOnClick(elements) {198  for (let i = 0; i < elements.length; i++) {199    elements[i].addEventListener("click", () => {200      document.querySelector("div.traceback").classList.toggle("hidden");201      document.querySelector("div.plain").classList.toggle("hidden");202    });203    elements[i].style.cursor = "pointer";204    document.querySelector("div.plain").classList.toggle("hidden");205  }206}207 208function createConsole() {209  const consoleNode = document.createElement("pre");210  consoleNode.classList.add("console");211  consoleNode.classList.add("active");212  return consoleNode;213}214 215function createConsoleOutput() {216  const output = document.createElement("div");217  output.classList.add("output");218  output.innerHTML = "[console ready]";219  return output;220}221 222function createConsoleInputForm() {223  const form = document.createElement("form");224  form.innerHTML = "&gt;&gt;&gt; ";225  return form;226}227 228function createConsoleInput() {229  const command = document.createElement("input");230  command.type = "text";231  command.setAttribute("autocomplete", "off");232  command.setAttribute("spellcheck", false);233  command.setAttribute("autocapitalize", "off");234  command.setAttribute("autocorrect", "off");235  return command;236}237 238function createIconForConsole() {239  const img = document.createElement("img");240  img.setAttribute("src", "?__debugger__=yes&cmd=resource&f=console.png");241  img.setAttribute("title", "Open an interactive python shell in this frame");242  return img;243}244 245function createExpansionButtonForConsole() {246  const expansionButton = document.createElement("a");247  expansionButton.setAttribute("href", "#");248  expansionButton.setAttribute("class", "toggle");249  expansionButton.innerHTML = "&nbsp;&nbsp;";250  return expansionButton;251}252 253function createInteractiveConsole() {254  const target = document.querySelector("div.console div.inner");255  while (target.firstChild) {256    target.removeChild(target.firstChild);257  }258  openShell(null, target, 0);259}260 261function handleConsoleSubmit(e, command, frameID) {262  // Prevent page from refreshing.263  e.preventDefault();264 265  return new Promise((resolve) => {266    // Get input command.267    const cmd = command.value;268 269    // Setup GET request.270    const urlPath = "";271    const params = {272      __debugger__: "yes",273      cmd: cmd,274      frm: frameID,275      s: SECRET,276    };277    const paramString = Object.keys(params)278      .map((key) => {279        return "&" + encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);280      })281      .join("");282 283    fetch(urlPath + "?" + paramString)284      .then((res) => {285        return res.text();286      })287      .then((data) => {288        const tmp = document.createElement("div");289        tmp.innerHTML = data;290        resolve(tmp);291 292        // Handle expandable span for long list outputs.293        // Example to test: list(range(13))294        let wrapperAdded = false;295        const wrapperSpan = document.createElement("span");296        const expansionButton = createExpansionButtonForConsole();297 298        tmp.querySelectorAll("span.extended").forEach((spanToWrap) => {299          const parentDiv = spanToWrap.parentNode;300          if (!wrapperAdded) {301            parentDiv.insertBefore(wrapperSpan, spanToWrap);302            wrapperAdded = true;303          }304          parentDiv.removeChild(spanToWrap);305          wrapperSpan.append(spanToWrap);306          spanToWrap.hidden = true;307 308          expansionButton.addEventListener("click", (event) => {309            event.preventDefault();310            spanToWrap.hidden = !spanToWrap.hidden;311            expansionButton.classList.toggle("open");312            return false;313          });314        });315 316        // Add expansion button at end of wrapper.317        if (wrapperAdded) {318          wrapperSpan.append(expansionButton);319        }320      })321      .catch((err) => {322        console.error(err);323      });324    return false;325  });326}327 328function fadeOut(element) {329  element.style.opacity = 1;330 331  (function fade() {332    element.style.opacity -= 0.1;333    if (element.style.opacity < 0) {334      element.style.display = "none";335    } else {336      requestAnimationFrame(fade);337    }338  })();339}340 341function fadeIn(element, display) {342  element.style.opacity = 0;343  element.style.display = display || "block";344 345  (function fade() {346    let val = parseFloat(element.style.opacity) + 0.1;347    if (val <= 1) {348      element.style.opacity = val;349      requestAnimationFrame(fade);350    }351  })();352}353 354function docReady(fn) {355  if (document.readyState === "complete" || document.readyState === "interactive") {356    setTimeout(fn, 1);357  } else {358    document.addEventListener("DOMContentLoaded", fn);359  }360}361 
codekingpro/portable-devtools · Team Ai