// ==UserScript== // @name Blanket Permission highlighting // @namespace https://brickgrass.uk // @version 2.8 // @description Highlights authors on ao3 who have a blanket permission statement // @author BrickGrass // @include https://archiveofourown.org/* // @require http://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js // @require https://cdn.jsdelivr.net/npm/js-cookie@rc/dist/js.cookie.min.js // @updateURL https://raw.githubusercontent.com/BrickGrass/Blanket-Permission-Highlighter/master/highlight.pub.user.js // @downloadURL https://raw.githubusercontent.com/BrickGrass/Blanket-Permission-Highlighter/master/highlight.pub.user.js // @grant GM.setValue // @grant GM.getValue // @grant GM.listValues // @grant GM.deleteValue // @grant GM.registerMenuCommand // @require https://raw.githubusercontent.com/BrickGrass/Blanket-Permission-Highlighter/master/extension-src/constants.js // @require https://raw.githubusercontent.com/BrickGrass/Blanket-Permission-Highlighter/master/extension-src/cookies.js // @require https://raw.githubusercontent.com/BrickGrass/Blanket-Permission-Highlighter/master/extension-src/caching.js // @require https://raw.githubusercontent.com/BrickGrass/Blanket-Permission-Highlighter/master/extension-src/settings.js // @require https://raw.githubusercontent.com/BrickGrass/Blanket-Permission-Highlighter/master/extension-src/waitForKeyElements.js // ==/UserScript== var users = {}; // Checks if a user is in the local cache, returns true if user found in cache, false if not // If the user is in the cache, the callback is called with exists to set their bp status async function check_storage(username, context, callback) { if (username === "orphan_account") { callback.call(context, {exists: orphan_bp_enabled}); return true; } var entry = await GM.getValue(username); entry = read_storage(entry); if (entry.hasOwnProperty("exists") && entry.exists) { if (entry.age > _1_day_ago) { callback.call(context, {exists: true}); return true; } } else if (entry.hasOwnProperty("exists") && !entry.exists) { if (entry.age > _1_day_ago) { callback.call(context, {exists: false}); return true; } } // user not found in cache and is not orphan account, api must be checked return false; } // Checks the local cache and then the single user api endpoint to see if a user has bp async function bp_exists(username, context, callback) { const in_storage = await check_storage(username, context, callback) if (in_storage) { return; } $.ajax( `https://brickgrass.uk/bp_api/author_exists/${username}`, {context: context} ).done(callback).done(function(data) { if (storage_enabled) { if (data.exists) { GM.setValue(username, JSON.stringify([true, Date.now()])); } else { GM.setValue(username, JSON.stringify([false, Date.now()])); } } }); } // Check if a user has an fpslist.org entry, returns the url if so function bp_fetch(username, callback) { $.ajax( `https://brickgrass.uk/bp_api/author_data/${username}` ).done(callback); } function minimise_article(article) { if (!minimise_articles) { // Old article hiding behaviour $(article).css({display: "none"}); return } // Minimisation of articles $(article).children().each(function () { if ($(this).is("div.header.module")) { $(this).after("Unhide non-bp work") $(this).css({"min-height": 0}); var article_title = $(this).children("h4.heading")[0]; $(article_title).css({"margin-left": 0}); var article_fandoms = $(this).children("h5.fandoms.heading")[0]; $(article_fandoms).css({display: "none"}); var article_req_tags = $(this).children("ul.required-tags")[0]; $(article_req_tags).css({display: "none"}); var article_datetime = $(this).children("p.datetime")[0]; $(article_datetime).css({top: 0}); return; } $(this).css({display: "none"}); }); $("a.bp-unhide-article").on("click", function (event) { event.preventDefault(); var hidden_article = $(this).closest("li[role=article]"); $(hidden_article).children().each(function () { if ($(this).is("div.header.module")) { $(this).css({"min-height": ""}); var article_title = $(this).children("h4.heading")[0]; $(article_title).css({"margin-left": ""}); var article_fandoms = $(this).children("h5.fandoms.heading")[0]; $(article_fandoms).css({display: ""}); var article_req_tags = $(this).children("ul.required-tags")[0]; $(article_req_tags).css({display: ""}); var article_datetime = $(this).children("p.datetime")[0]; $(article_datetime).css({top: ""}); } $(this).css({display: ""}); }); $(this).css({display: "none"}); }); } // Highlights the username links of bp authors, and minimises/hides works based on filtering settings function modify_style(data) { if (data.exists) { for (const tag of this.tags) { $(tag).css({color: highlight_colour}); } } else { if (!filtering_enabled) { return; } for (const tag of this.tags) { if (!($(tag).attr("rel") === "author")) { continue; } var article = $(tag).closest("li[role=article]"); minimise_article(article); } } } $(document).ready(async function() { // Remove expired keys from storage clear_storage(); // If storage is disabled, fully clear storage if (!storage_enabled) { clear_all_storage(); } // Add custom css let head = document.getElementsByTagName('head')[0]; if (head) { let style = document.createElement('style'); style.setAttribute('type', 'text/css'); style.textContent = css; head.appendChild(style); } // Add filter to ao3 filter form, update cookie on every change event $(".filters .options > ul").append(ao3_filter_html); $(".filters .more.group > dl").prepend(`