Greasy Fork

Greasy Fork is available in English.

AO3: Kudosed and seen history

Highlight or hide works you kudosed/marked as seen.

当前为 2014-10-17 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        AO3: Kudosed and seen history
// @description Highlight or hide works you kudosed/marked as seen.
// @namespace	
// @author	Min
// @version	1.0
// @grant       none
// @include     http://archiveofourown.org/*
// @include     https://archiveofourown.org/*
// ==/UserScript==

// STUFF HAPPENS BELOW //

(function($) {
	
	if (typeof(Storage) !== 'undefined') {
		
		var username = localStorage.getItem('kudoshistory_username');
		
		// if there's no saved username, look for it on the page or ask
		if (!username) {
			var userlink = $('#greeting').find('[href^="/users/"]');
			
			if (userlink.length) {
				var userlink_parts = userlink.attr('href').split('/');
				var username = userlink_parts[2];
				localStorage.setItem('kudoshistory_username', username);
			}
			else {
				var username = prompt('AO3: Kudosed and seen history\n\nYour AO3 username:');
				localStorage.setItem('kudoshistory_username', username);
			}
		}
		
		// check the 'hide seen works' setting
		var hide_seen = false;
		var hide_seen_set = localStorage.getItem('kudoshistory_hide');
		if (hide_seen_set == 'yes') {
			hide_seen = true;
		}
		
		// uncomment the next three lines if you need to clear your local lists (then comment them again after refreshing the page once)
		// localStorage.removeItem('kudoshistory_kudosed');
		// localStorage.removeItem('kudoshistory_checked');
		// localStorage.removeItem('kudoshistory_seen');

		var list_kudosed = localStorage.getItem('kudoshistory_kudosed');
		var list_checked = localStorage.getItem('kudoshistory_checked');
		var list_seen = localStorage.getItem('kudoshistory_seen');
		
		if (!list_kudosed) {
			var list_kudosed = ',';
		}
		if (!list_checked) {
			var list_checked = ',';
		}
		if (!list_seen) {
			var list_seen = ',';
		}
		
		$(document).ajaxStop(function() {
			localStorage.setItem('kudoshistory_kudosed', list_kudosed);
			localStorage.setItem('kudoshistory_checked', list_checked);
			localStorage.setItem('kudoshistory_seen', list_seen);
		});
		
		// add css rules for kudosed works
		addCss();
		
		// if there's a list of works or bookmarks, add menu
		var work_blurbs = $('li.work.blurb');
		var bookmark_blurbs = $('li.bookmark.blurb');
		
		if (work_blurbs.length || bookmark_blurbs.length) {
			addSeenMenu();
		}
		
		// for each work blurb
		$('li.work.blurb').each(function() {
			
			// get work id
			var work_id = $(this).attr('id').replace('work_', '');
			
			// if work id is on the kudosed list
			if (list_kudosed.indexOf(',' + work_id + ',') > -1) {
				$(this).addClass('has-kudos');
				list_kudosed = ',' + work_id + list_kudosed.replace(',' + work_id + ',', ',');
			}
			// if work id is on the seen list
			else if (list_seen.indexOf(',' + work_id + ',') > -1) {
				$(this).addClass('marked-seen');
				list_seen = ',' + work_id + list_seen.replace(',' + work_id + ',', ',');
			}
			// if work id is on the checked list
			else if (list_checked.indexOf(',' + work_id + ',') > -1) {
				list_checked = ',' + work_id + list_checked.replace(',' + work_id + ',', ',');
			}
			else {
				// add a div to the blurb that will house the kudos
				$(this).append('<div id="kudos_' + work_id + '" style="display: none"></div>');
				
				// retrieve a list of kudos from the work
				var work_url = 'http://archiveofourown.org/works/' + work_id + '/kudos #kudos';
				$('#kudos_' + work_id).load(work_url, function() {
					// check if there are kudos from the user
					var user_kudos = $('#kudos_' + work_id).find('[href="/users/' + username + '"]');
					
					if (user_kudos.length) {
						// highlight blurb and add work id to kudosed list
						$('#work_' + work_id).addClass('has-kudos');
						list_kudosed = ',' + work_id + list_kudosed;
					}
					else {
						// add work id to checked list
						list_checked = ',' + work_id + list_checked;
					}
				});
			}
		});
		
		// for each bookmark blurb
		$('li.bookmark.blurb').each(function() {
			
			// get bookmark and work ids
			var bookmark_id = $(this).attr('id').replace('bookmark_', '');
			var work_id = $(this).find('h4 a:first').attr('href').replace('/works/', '');
			
			// if work id is on the kudosed list
			if (list_kudosed.indexOf(',' + work_id + ',') > -1) {
				$(this).addClass('has-kudos');
				list_kudosed = ',' + work_id + list_kudosed.replace(',' + work_id + ',', ',');
			}
			// if work id is on the seen list
			else if (list_seen.indexOf(',' + work_id + ',') > -1) {
				$(this).addClass('marked-seen');
				list_seen = ',' + work_id + list_seen.replace(',' + work_id + ',', ',');
			}
			// if work id is on the checked list
			else if (list_checked.indexOf(',' + work_id + ',') > -1) {
				list_checked = ',' + work_id + list_checked.replace(',' + work_id + ',', ',');
			}
			else {
				// add a div to the blurb that will house the kudos
				$(this).append('<div id="kudos_' + work_id + '" style="display: none"></div>');
				
				// retrieve a list of kudos from the work
				var work_url = 'http://archiveofourown.org/works/' + work_id + '/kudos #kudos';
				$('#kudos_' + work_id).load(work_url, function() {
					// check if there are kudos from the user
					var user_kudos = $('#kudos_' + work_id).find('[href="/users/' + username + '"]');
					
					if (user_kudos.length) {
						// highlight blurb and add work id to kudosed list
						$('#bookmark_' + bookmark_id).addClass('has-kudos');
						list_kudosed = ',' + work_id + list_kudosed;
					}
					else {
						// add work id to checked list
						list_checked = ',' + work_id + list_checked;
					}
				});
			}
		});
		
		// if it's a work page
		if ($('#workskin').length) {
			
			// get work id
			var url_parts = location.pathname.split('/');
			var work_id = url_parts[2];
			
			// check if work id is on the seen list
			var is_seen = list_seen.indexOf(',' + work_id + ',');
			addSeenButtons();
			
			if (is_seen > -1) {
				$('dl.work.meta.group').addClass('marked-seen');
			}
			
			// if work id is on the kudosed list
			if (list_kudosed.indexOf(',' + work_id + ',') > -1) {
				$('dl.work.meta.group').addClass('has-kudos');
			}
			else {
				var found_kudos = false;
				
				// check if there are kudos from the user
				var user_kudos = $('#kudos').find('[href="/users/' + username + '"]');
				
				if (user_kudos.length) {
					// highlight blurb and add work id to kudosed list
					list_kudosed = ',' + work_id + list_kudosed;
					list_checked = list_checked.replace(',' + work_id + ',', ',');
					$('dl.work.meta.group').addClass('has-kudos');
					found_kudos = true;
				}
				else if (list_checked.indexOf(',' + work_id + ',') == -1) {
					// add work id to checked list
					list_checked = ',' + work_id + list_checked;
				}
					
				if (!found_kudos) {
					$('#new_kudo').click(function() {
						list_kudosed = ',' + work_id + list_kudosed;
						list_checked = list_checked.replace(',' + work_id + ',', ',');
						$('dl.work.meta.group').addClass('has-kudos');
						localStorage.setItem('kudoshistory_kudosed', list_kudosed);
						localStorage.setItem('kudoshistory_checked', list_checked);
					}); 
				}
			}
		}
		
		// keep the kudos and checked lists under 200k characters (~25k works)
		if (list_kudosed.length > 200000) {
			list_kudosed = list_kudosed.slice(0,180000);
			localStorage.setItem('kudoshistory_kudosed', list_kudosed);
		}
		if (list_checked.length > 200000) {
			list_checked = list_checked.slice(0,180000);
			localStorage.setItem('kudoshistory_checked', list_checked);
		}
		
		// keep the seen list under 1mil characters (~125k works)
		if (list_seen.length > 1000000) {
			list_seen = list_seen.slice(0,900000);
			localStorage.setItem('kudoshistory_seen', list_seen);
		}
		
		// save all lists
		localStorage.setItem('kudoshistory_kudosed', list_kudosed);
		localStorage.setItem('kudoshistory_checked', list_checked);
		localStorage.setItem('kudoshistory_seen', list_seen);
		
	}
	
	// mark all works on the page as seen
	function markPageSeen() {
		
		// for each work blurb
		$('li.work.blurb').each(function() {
			
			var work_id = $(this).attr('id').replace('work_', '');
			
			if (list_seen.indexOf(',' + work_id + ',') == -1) {
				$(this).addClass('marked-seen');
				list_seen = ',' + work_id + list_seen;
			}
		});
		
		// for each bookmark blurb
		$('li.bookmark.blurb').each(function() {
			
			var work_id = $(this).find('h4 a:first').attr('href').replace('/works/', '');
			
			if (list_seen.indexOf(',' + work_id + ',') == -1) {
				$(this).addClass('marked-seen');
				list_seen = ',' + work_id + list_seen;
			}
		});
		
		localStorage.setItem('kudoshistory_seen', list_seen);
	}
	
	// mark all works on the page as unseen
	function markPageUnseen() {
		
		// for each work blurb
		$('li.work.blurb').each(function() {
			
			var work_id = $(this).attr('id').replace('work_', '');
			
			if (list_seen.indexOf(',' + work_id + ',') > -1) {
				$(this).removeClass('marked-seen');
				list_seen = list_seen.replace(',' + work_id + ',', ',');
			}
		});
		
		// for each bookmark blurb
		$('li.bookmark.blurb').each(function() {
			
			var work_id = $(this).find('h4 a:first').attr('href').replace('/works/', '');
			
			if (list_seen.indexOf(',' + work_id + ',') > -1) {
				$(this).removeClass('marked-seen');
				list_seen = list_seen.replace(',' + work_id + ',', ',');
			}
		});
		
		localStorage.setItem('kudoshistory_seen', list_seen);
	}
	
	// add the seen/unseen buttons
	function addSeenButtons() {
		
		var seen_button1 = $('<li class="mark-seen"></li>').html('<a>Seen &check;</a>');
		var seen_button2 = seen_button1.clone();
		$('ul.actions').on('click', 'li.mark-seen', function() {
			list_seen = ',' + work_id + list_seen;
			localStorage.setItem('kudoshistory_seen', list_seen);
			$('dl.work.meta.group').addClass('marked-seen');
			seen_button1.replaceWith(unseen_button1);
			seen_button2.replaceWith(unseen_button2);
		});
		
		var unseen_button1 = $('<li class="mark-unseen"></li>').html('<a>Unseen &cross;</a>');
		var unseen_button2 = unseen_button1.clone();
		$('ul.actions').on('click', 'li.mark-unseen', function() {
			list_seen = list_seen.replace(',' + work_id + ',', ',');
			localStorage.setItem('kudoshistory_seen', list_seen);
			$('dl.work.meta.group').removeClass('marked-seen');
			unseen_button1.replaceWith(seen_button1);
			unseen_button2.replaceWith(seen_button2);
		});
		
		if (is_seen == -1) {
			$('li.bookmark').after(seen_button1);
			$('#new_kudo').parent().after(seen_button2);
		}
		else {
			$('li.bookmark').after(unseen_button1);
			$('#new_kudo').parent().after(unseen_button2);
		}
	}
		
	// attach the menu
	function addSeenMenu() {
		
		// get the header menu
		var header_menu = $('ul.primary.navigation.actions');
		
		// create and insert menu button
		var seen_menu = $('<li class="dropdown"></li>').html('<a>Seen works</a>');
		header_menu.find('li.search').before(seen_menu);
		
		// create and append dropdown menu
		var drop_menu = $('<ul class="menu dropdown-menu"></li>');
		seen_menu.append(drop_menu);
		
		// create button - mark page as seen
		var button_page_seen = $('<li></li>').html('<a>Mark this page as seen</a>');
		button_page_seen.click(function() {markPageSeen();});
		
		// create button - mark page as unseen
		var button_page_unseen = $('<li></li>').html('<a>Mark this page as unseen</a>');
		button_page_unseen.click(function() {markPageUnseen();});
		
		// create button - hide seen works
		var button_hide_yes = $('<li class="hide-yes"></li>').html('<a>Hide seen works: YES</a>');
		drop_menu.on('click', 'li.hide-yes', function() {
			localStorage.setItem('kudoshistory_hide', 'no');
			button_hide_yes.replaceWith(button_hide_no);
		});
		
		// create button - don't hide seen works
		var button_hide_no = $('<li class="hide-no"></li>').html('<a>Hide seen works: NO</a>');
		drop_menu.on('click', 'li.hide-no', function() {
			localStorage.setItem('kudoshistory_hide', 'yes');
			hide_seen = true;
			addCss();
			button_hide_no.replaceWith(button_hide_yes);
		});
		
		// append buttons to the dropdown menu
		drop_menu.append(button_page_seen);
		drop_menu.append(button_page_unseen);
		
		if (hide_seen) {
			drop_menu.append(button_hide_yes);
		}
		else {
			drop_menu.append(button_hide_no);
		}
	}
	
	// add css rules to page head
	function addCss() {
		var style = $('style');
		var css_highlight = '.has-kudos, .has-kudos.marked-seen {background: url("http://i.imgur.com/Rmyf262.png") left repeat-y; padding-left: 70px !important;}\
			.marked-seen {background: url("http://i.imgur.com/qdA6ylN.png") left repeat-y; padding-left: 70px !important;}';
		var css_hide = 'dl.has-kudos, dl.has-kudos.marked-seen {background: url("http://i.imgur.com/Rmyf262.png") left repeat-y; padding-left: 70px !important;}\
			dl.marked-seen {background: url("http://i.imgur.com/qdA6ylN.png") left repeat-y; padding-left: 70px !important;}\
			li.has-kudos, li.marked-seen {display: none !important;}';

		if (!style.length) {
			style = $('<style type="text/css"></style>').appendTo($('head'));
		}
		
		if (!hide_seen) {
			style.append(css_highlight);
		}
		else {
			style.append(css_hide);
		}
	}
})(jQuery);