Skip to content

Instantly share code, notes, and snippets.

@khalby786
Last active January 2, 2022 13:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save khalby786/3fffeddbe121411acbdc73b34867c295 to your computer and use it in GitHub Desktop.
Save khalby786/3fffeddbe121411acbdc73b34867c295 to your computer and use it in GitHub Desktop.
Userscript that deletes *all* the assets in your Glitch project
// ==UserScript==
// @name Glitch Delete All Assets
// @namespace http://khaleelgibran.com/
// @version 0.1
// @description mass-deletes your glitch project's assets
// @author Khaleel Gibran <khalby786@gmail.com>
// @match https://glitch.com/edit/*
// @icon https://glitch.com/favicon.ico
// @run-at document-start
// ==/UserScript==
// a few notes...
// 1. `application` is a global variable available in the editor (glitch.com/edit) which lets you basically do everyhing,
// including access to the CodeMirror editor object
// 2. this userscript partially depends on UI changes (MutationObserver to detect change in class name),
// so if Glitch ever redesigns their UI, this userscript might break
// 3. special kudos to Nassinger#7687 for building a userscript to change the Glitch editor themes which had code
// dealing with the detecting whether the editor loaded, without which this userscript wouldn't work
// https://discord.com/channels/648206265759301649/648497303178706944/886502866846625843 (Coding on Glitch Discord server)
// 4. Deleting an asset is still vague, however the asset's JSON property remains in .glitch-assets
// and a field `deleted: true` is added
const $ = (selector, startNode = document) => [
...document.querySelectorAll(selector),
];
function onEditorLoaded(wrap) {
console.log("editor loaded");
let sidebar = $("#sidebar-files");
let assetButton = sidebar[0].children[0].children[0].children[0];
assetButton.addEventListener("click", () => {
console.log("assets clicked!");
});
const observer = new MutationObserver((mutations) => {
if (mutations[0].target.classList.contains("active")) {
if (application.assetsWrapVisible() === true) {
let assetsWrap = $(".assets-wrap")[0];
let buttonBar = assetsWrap.getElementsByClassName(
"editor-helper-contents"
)[0];
let newButton = document.createElement("button");
newButton.setAttribute("class", "button");
newButton.innerText = "Delete All Assets";
buttonBar.appendChild(newButton);
newButton.addEventListener("click", () => {
let assets = application.assets();
if (
confirm(
"Are you sure you want to delete all the assets of this project?"
) === true
) {
try {
assets.forEach((asset) => application.deleteAsset(asset));
alert("Deleted assets!");
console.log("Deleted assets!");
} catch (err) {
console.error(err);
alert(
"Something went wrong, try again? (Error in DevTools console)"
);
}
}
});
disconnectObserver();
}
}
});
function disconnectObserver() {
observer.disconnect();
}
observer.observe(assetButton, {
attributes: true,
attributeFilter: ["class"],
childList: false,
characterData: false,
});
}
document.addEventListener("DOMContentLoaded", () => {
const container = $(".editor-container")[0];
const observer = new MutationObserver((mutations) => {
mutations.forEach(({ addedNodes }) => {
if (!addedNodes.length) return;
if (addedNodes[0].matches(".editor-wrap")) onEditorLoaded(addedNodes[0]);
});
});
observer.observe(container, { childList: true });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment