您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Easily remove games from your itch.io collections from within the "Add to Collection" modal of a game.
// ==UserScript== // @name Itch.io Simple Remove from Collection // @namespace https://github.com/refatK // @version 1.0.1 // @homepageURL https://github.com/refatK/Itch.io-Simple-Remove-from-Collection // @description Easily remove games from your itch.io collections from within the "Add to Collection" modal of a game. // @author RefatK // @license MIT // @match *://itch.io/* // @match *://*.itch.io/* // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js // @grant unsafeWindow // @grant GM.xmlHttpRequest // @connect itch.io // @run-at document-end // ==/UserScript== /* jshint esversion: 8 */ /* global $, Itch */ $(document).ready(function () { const GAME_URL_REGEX = "/https:\/\/.+\.itch\.io/g" const bodyObserver = new MutationObserver(OnBodyChange); const lightboxObserver = new MutationObserver(OnLightboxChange) var _gameId var _csrf // --- ON LOAD --- _csrf = GetCsrf() let pageUrl = window.location.href if (IsAddToCollectionPage(pageUrl)) { if (!IsGameInAnyCollection()) { return } let gameCreator = GetUserFromGamePage(pageUrl) let gameName = GetGameNameFromGamePage(pageUrl) GetGameIdFromItchApi(gameCreator, gameName).then(AddAndEnableRemoveButtons()) } else { // wait for add-to-collection lightbox to load on any other page bodyObserver.observe($("body")[0], { childList: true }) } // --- EVENTS --- // On click "Add To Collection" button for a game $('div, #user_tools').on('click', 'a.add_to_collection_btn', function () { _gameId = GetGameIdFromGameCell(this) }); function OnBodyChange() { // observe lightbox div once loaded on the page if ($("div#lightbox_container").length > 0) { lightboxObserver.observe($("div#lightbox_container")[0], { childList: true }) // lightbox container stays loaded now, so we can stop observing for it to load bodyObserver.disconnect() } } // On the lightbox being loaded on the page function OnLightboxChange() { if (!IsGameInAnyCollection()) { return } AddAndEnableRemoveButtons() } // --- HELPER FUNCTIONS --- function GetCsrf() { return $("meta[name=csrf_token]").attr("value") } function IsGameInAnyCollection() { return $("ul.already_in").length > 0 } function GetGameIdFromGameCell(addToCollectionBtn) { let pageUrl = window.location.href let gameId = "" let gameCell = addToCollectionBtn.closest('div.game_cell') if (gameCell) { gameId = $(gameCell).attr("data-game_id") } else { gameId = $("meta[name='itch:path']").attr("content").replace("games/", "") } return gameId } async function GetGameIdFromItchApi(gameCreator, gameName) { await $.getScript( "https://static.itch.io/api.js" ) // Used to get game id return new Promise(function (resolve, reject) { Itch.getGameData({ user: gameCreator, game: gameName, onComplete: function (data) { if ('errors' in data) { console.error(`ERROR: Could not find game "${this.user}" by ${this.game}.`) console.error(data) reject() } _gameId = data.id resolve(_gameId) } }) }) } function AddRemoveButtonUi(collectionLinkEl) { let collectionId = collectionLinkEl.find("a").prop("href").split("/")[4] const removeHTML = $(`<a class="remove_from_coll_btn button outline" title="Remove the game from the collection." value="${collectionId}">❌</a>`) removeHTML.css({ "margin-right": "5px", "display": "inline", "padding": "4px" }); collectionLinkEl.prepend(removeHTML) } function PostRemoveGameFromCollection(collectionId, gameId, csrf_token, elToHideOnSuccess) { GM.xmlHttpRequest({ method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, url: `https://itch.io/collection/${collectionId}/remove/${gameId}`, data: `csrf_token=${csrf_token}`, onload: function (res) { let resJson = JSON.parse(res.responseText) if (resJson.removed) { elToHideOnSuccess.remove() } else { console.error(res.responseText) } }, }); } function AddAndEnableRemoveButtons() { $('li.already_in_row').each(function (i) { AddRemoveButtonUi($('li.already_in_row').eq(i)) }) // Add click event for the newly added remove buttons $('.remove_from_coll_btn').click(function (e) { let collId = $(this).attr("value") PostRemoveGameFromCollection(collId, _gameId, _csrf, $(this).closest('li.already_in_row')) }) } function IsAddToCollectionPage(url) { return url.includes("add-to-collection") } function GetUserFromGamePage(url) { if (url.includes("?source=game")) { return url.split("/")[2].split(".")[0] } else { return url.split("/")[4] } } function GetGameNameFromGamePage(url) { if (url.includes("?source=game")) { return url.split("/")[3] } else { return url.split("/")[5] } } });
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址