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);