18C / Home Page

// ==UserScript==
// @name        Home Page
// @namespace   CCAU
// @description Automate course copies
// @match       https://*.instructure.com/courses/*/pages/home-page*/edit
// @version     0.2.1
// @author      Cappiebara
// @grant       none
// @license     GPL-3.0-or-later
// ==/UserScript==
"use strict";
(() => {
  // out/ccau.js
  function isAdmin() {
    const adminButton = document.querySelector("#global_nav_accounts_link");
    return adminButton ? true : false;
  }
  function getCourseID() {
    return window.location.href.match(/courses\/(\d+)/)?.[1] ?? "NO_COURSE_ID";
  }
  async function isLiveCourse() {
    const response = await fetch("https://se.instructure.com/api/v1/courses/" + getCourseID());
    const data = await response.json();
    if (!data.start_at) {
      return new Promise((resolve) => resolve(false));
    }
    return new Date(data.start_at) < /* @__PURE__ */ new Date();
  }
  function observeDOM(element, callback) {
    const observer = new MutationObserver(callback);
    observer.observe(element, {
      childList: true
    });
    return observer;
  }

  // out/homepage.js
  function getAltText(element) {
    const altText = element?.getAttribute("alt")?.toString();
    if (!altText) {
      return null;
    }
    if (altText.toLowerCase() === "start here") {
      return "START HERE";
    }
    const pattern = /Week \d{1,2}/;
    const arr = pattern.exec(altText);
    return arr ? arr[0] : null;
  }
  function relinkModuleButtons() {
    const iframe = document.querySelector("#wiki_page_body_ifr");
    const contentDocument = iframe?.contentDocument;
    if (!contentDocument) {
      throw new Error("Couldn't access iframe's content document");
    }
    const moduleButtons = Array.from(contentDocument.querySelectorAll("img[alt^='Week']"));
    const links = Array.from(document.querySelectorAll("div[data-testid='instructure_links-Link'] > div[role='button']"));
    moduleButtons.map((b) => [b, getAltText(b)]).filter((ba) => ba[1]).map((ba) => [ba[0], links.find((l) => l.innerText.startsWith(ba[1].toString()))]).forEach((bl) => {
      bl[0].click();
      bl[1]?.click();
    });
  }
  function addButton() {
    const slot = document.querySelector("span[data-testid='CloseButton_ContentTray']");
    const button = document.createElement("a");
    button.id = "ccau_relinkModuleButtons";
    button.textContent = "Re-Link Modules";
    button.classList.add("btn");
    button.setAttribute("tabindex", "0");
    button.addEventListener("click", relinkModuleButtons);
    if (!slot || slot?.innerHTML.includes(button.id)) {
      return;
    }
    slot?.insertAdjacentElement("afterbegin", button);
  }

  // out/index.js
  async function main() {
    if (!isAdmin()) {
      throw new Error("Only admins can use CCAU");
    }
    if (await isLiveCourse()) {
      throw new Error("CCAU is disabled in live courses");
    }
    observeDOM(document.body, () => setTimeout(addButton, 1e3));
  }
  main();
})();