NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @namespace https://openuserjs.org/users/Frystix // @name FanFiction.net Utilities // @author Frystix // @description A collection of utilities related to fanfiction.net (Currently just work & author blocking) // @license MIT // @version 0.1.0 // @include http://www.fanfiction.net/* // @include https://www.fanfiction.net/* // @require http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js // @grant GM_setValue // @grant GM_getValue // @grant GM_listValues // @grant GM_deleteValue // ==/UserScript== // ==OpenUserJS== // @author Frystix // ==/OpenUserJS== (function($) { // Utility stuff, not all of it is in use yet. // So on my test env String.replace replaces all occurances, in browser it does it replaces the first, this fixes that String.prototype.replace = function(search, replacement) { return this.split(search).join(replacement); //return this.replace(new RegExp(search, 'g'), replacement); // This is significantly faster (~50%), but / is a special character so this doesn't work as I don't know regex or js }; String.prototype.count = function(char) { return this.length - this.replace(char, "").length; }; function getUrl() { return window.location.href; } function isUser(url) { if (url.substr(26, 3) === "/u/" && url.substr(0, 5) === "https") { return true; } else if (url.substr(25, 3) === "/u/") { return true; } else { return false; } } function isStory(url) { if (url.substr(26, 3) === "/s/" && url.substr(0, 5) === "https") { return true; } else if (url.substr(25, 3) === "/s/") { return true; } else { return false; } } function getUserId(url) { // rewrite to handle all 3 use cases if (url.substr(0, 5) === "https") { return url.substr(29, url.lastIndexOf("/") - 29); } else { return url.substr(28, url.lastIndexOf("/") - 28); } } function getStoryId(url) { // rewrite to handle all 3 use cases var modifier = 0; if (url.substr(0, 5) === "https") { modifier = 1; } if (url.count("/") > 4) { return url.substr(28 + modifier, url.lastIndexOf("/", url.lastIndexOf("/") - 1) - 28 - modifier); } else { return url.substr(28 + modifier); } } function UI_Init() { // Create dropdown menu // Bugs: Both this and Betas open at the same time. // Using .after instead of .append fixes that at the cost of a different bug $('#zmenu .xmenu_item:last-child') .append('<div class="dropdown xmenu_item"><a class="dropdown-toggle" data-toggle="dropdown">FFUtils <b class="caret"></b></a><ul class="dropdown-menu"><li class="disabled" style="text-align:center"><a href="#">General</a></li><li class="disabled" style="text-align:center"><a href="#">Debug</a></li></ul></div>'); var works = $('div.z-list'); for (var i = 0; i < works.length; i++) { $(works[i]).find('.z-padtop').append('<a href="javascript:void(0)" class="workblock blockwork">Block Work</a><a href="javascript:void(0)" class="workblock blockauthor">Block Author</a>'); } // Move block buttons slightly apart $('<style>').text('.workblock a {cursor:pointer;} a.workblock.blockauthor {margin-left: 15px;}').appendTo($('head')); // Hide blocked works var blockedStories = JSON.parse(GM_getValue('stories')); var blockedUsers = JSON.parse(GM_getValue('users')); for (var j = 0; j < works.length; j++) { var storyId = getStoryId("https://www.fanfiction.net" + $(works[j]).find('.stitle').attr('href')); var userId = getUserId($(works[j]).find('a[href*="/u/"]')[0].href); if ($.inArray(storyId, blockedStories) != -1) { $(works[j]).hide(); } if ($.inArray(userId, blockedUsers) != -1) { $(works[j]).hide(); } } return works; } function blockWork(work) { var id = getStoryId("https://www.fanfiction.net" + $(work).find('.stitle').attr('href')); var blocked = JSON.parse(GM_getValue('stories')); blocked.push(id); GM_setValue('stories', JSON.stringify(blocked)); GM_setValue('last_story', id); } function blockUser(user) { var id = getUserId(user.find('a[href*="/u/"]')[0].href); var blocked = JSON.parse(GM_getValue('users')); blocked.push(id); GM_setValue('users', JSON.stringify(blocked)); GM_setValue('last_user', id); } $(document).ready(function() { var works = UI_Init(); $('.workblock.blockwork').click(function() { var work = $(this).parents('div.z-list'); blockWork(work); $(work).hide(); }); $('.workblock.blockauthor').click(funcction() { // prompt user if certain var work = $(this).parents('div.z-list'); if (confirm('Are you sure you want to block ' + $(work).find('a[href*="/u/"]')[0].innerHTML + '?')) { blockUser(work); $(work).hide(); } }); }); })(window.jQuery);