您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Track any filterable listing.
当前为
// ==UserScript== // @name AO3: Tracking // @description Track any filterable listing. // @namespace https://greasyfork.org/en/scripts/8382-ao3-tracking // @author Min // @version 1.3.2 // @grant none // @require https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js // @include http://archiveofourown.org/* // @include https://archiveofourown.org/* // ==/UserScript== (function($) { if (typeof(Storage) !== 'undefined') { var tracked_list = ''; var tracked_array = []; loadList(); addCss(); addTrackedMenu(); var main = $('#main'); // if it's a listing of works or bookmarks if (main.hasClass('works-index') || main.hasClass('bookmarks-index')) { var is_tracked = false; var is_first_page = true; // get page url var location_url = location.href; // check if page is already tracked var array_index = tracked_array.indexOf(location_url); if (array_index > -1) { is_tracked = true; checkOpen(); } // make sure it's the first page of the listing var current_page = main.find('ol.pagination:first span.current'); if (current_page.length && current_page.text() !== '1') { is_first_page = false; } if (is_first_page) { addTrackButton(); } } // add "Mark all as vieved" button when all listing get checked $(document).ajaxStop(function() { if ($('#tracked-box').length && !$('#button-check').length) { $('#button-mark').css('visibility', 'visible'); } }); } // load the saved list function loadList() { tracked_list = localStorage.getItem('ao3tracking_list'); if (!tracked_list) { tracked_list = ''; } // make an array of the list if (tracked_list.length) { tracked_array = tracked_list.split(',,,'); } } // add current page to tracked listings function addToTracked() { var added = false; loadList(); // if there's less than 25 tracked if (tracked_array.length < 75) { // ask for name var heading = main.find('h2.heading:first'); var heading_link = heading.find('a'); if (heading_link.length) { var suggest = heading_link.text(); } else { var suggest = heading.text().replace(/\n/g, '').replace(/^\s+/, '').replace(/(.+of )?\d+ /, ''); } var listing_name = prompt('Name for the tracked listing:', suggest); if (listing_name !== '' && listing_name !== null) { // remove characters we don't want in the names listing_name = listing_name.replace(/,,,/g, ' '); var listing_count = heading.text().replace(/\n/g, '').replace(/^\s+/, '').replace(/.*\d+ - \d+ of /, '').replace(/(\d+)(.+)/, '$1'); // add name, url, count tracked_array.push(listing_name, location_url, listing_count); tracked_list = tracked_array.join(',,,'); // save the updated list localStorage.setItem('ao3tracking_list', tracked_list); added = true; } } else { alert("You're already tracking 25 listings. Remove some first."); } return added; } // remove a given url from tracked listings function removeFromTracked(url) { var removed = false; loadList(); var index = tracked_array.indexOf(url); // if the url is on the saved list if (index > -1) { // ask for confirmation var confirmed = confirm('Sure you want to remove "' + tracked_array[index-1] + '"?'); if (confirmed) { // remove name, url, count tracked_array.splice(index-1, 3); tracked_list = tracked_array.join(',,,'); // save the updated list localStorage.setItem('ao3tracking_list', tracked_list); removed = true; } } return removed; } // check open page for new works function checkOpen() { var heading = main.find('h2.heading:first'); // get a count of new works var current_count = parseInt(heading.text().replace(/\n/g, '').replace(/^\s+/, '').replace(/.*\d+ - \d+ of /, '').replace(/(\d+)(.+)/, '$1')); var saved_count = parseInt(tracked_array[array_index+1]); var new_count = current_count - saved_count; if (new_count !== 0) { heading.append(' <span id="new-works">(' + new_count + ' new)</span> <a id="mark-viewed">[mark viewed]</a>'); $('#mark-viewed').click(function() { loadList(); var array_index = tracked_array.indexOf(location_url); if (array_index > -1) { // update the count tracked_array[array_index+1] = current_count; tracked_list = tracked_array.join(',,,'); // save the updated list localStorage.setItem('ao3tracking_list', tracked_list); } $('#new-works').detach(); $(this).detach(); }); } } // check the tracked listings for new works function checkForNew() { // check if it's more than 8 hours since last check var last_check = localStorage.getItem('ao3tracking_lastcheck'); if (!last_check) { var last_check = 0; } else { last_check = parseInt(last_check); } var now = new Date(); now = now.getTime(); var wait = 28800000 - (now - last_check); if (wait < 0) { localStorage.setItem('ao3tracking_lastcheck', now); // for each tracked listing $('#tracked-box li.tracked-listing').each(function() { var tracked_url = $(this).find('a').attr('href'); var listing_id = $(this).attr('id'); tracked_url += ' #main h2.heading:first'; // load heading of the tracked page $(this).find('span.tracked-current').load(tracked_url, function() { var listing = $('#' + listing_id); // get a count of new works var current_count = parseInt(listing.find('span.tracked-current').text().replace(/\n/g, '').replace(/^\s+/, '').replace(/.*\d+ - \d+ of /, '').replace(/(\d+)(.+)/, '$1')); listing.find('span.tracked-current').html(current_count); var saved_count = parseInt(listing.find('span.tracked-saved').text()); var new_count = current_count - saved_count; listing.find('span.tracked-new').text('(' + new_count + ' new)'); if (new_count !== 0) { listing.find('span.tracked-new').addClass('new-stuff'); listing.parent().prepend(listing); } else { listing.find('span.tracked-new').addClass('no-new-stuff'); } }); }); } else { var hours = Math.floor(wait/3600000); var minutes = Math.ceil((wait%3600000)/60000); var warning = $('<p style="color: #990000;"></p>'); if (hours > 0) { warning.html('<strong>Please be kind to the AO3 servers!</strong> Wait ' + hours + ' hour(s) and ' + minutes + ' minute(s) more before another check.'); } else { warning.html('<strong>Please be kind to the AO3 servers!</strong> Wait ' + minutes + ' more minute(s) before another check.'); } $('#tracked-box p.actions').after(warning); } } // add the 'Track This' button function addTrackButton() { var work_filters = $('form.filters dd.submit.actions:first'); var track_this_button = $('<input type="button" value="Track This" class="track-this"></input>'); track_this_button.click(function() { var added = addToTracked(); if (added) { track_this_button.detach(); work_filters.prepend(untrack_this_button); } }); var untrack_this_button = $('<input type="button" value="Untrack This" class="track-this"></input>'); untrack_this_button.click(function() { var removed = removeFromTracked(location_url); if (removed) { untrack_this_button.detach(); work_filters.prepend(track_this_button); } }); // if the page is already tracked if (is_tracked) { work_filters.prepend(untrack_this_button); } // if it's not tracked else { work_filters.prepend(track_this_button); } } // rearrange things on the list function editList() { var box_list = $('#box-list'); box_list.find('li.tracked-listing').each(function() { $(this).prepend('<span class="up-arrow">↑</span> <span class="down-arrow">↓</span> <span class="cross">✗</span> '); }); box_list.on('click', 'span.up-arrow', function() { $(this).parent().prev().before($(this).parent()); }); box_list.on('click', 'span.down-arrow', function() { $(this).parent().next().after($(this).parent()); }); box_list.on('click', 'span.cross', function() { $(this).parent().detach(); }); } // save list after edits function saveList() { tracked_array = []; // get name, url, count for all listings $('#tracked-box li.tracked-listing').each(function() { var name = $(this).find('a').text(); var url = $(this).find('a').attr('href'); var count = $(this).find('span.tracked-saved').text(); tracked_array.push(name, url, count); }); // update and save the new list tracked_list = tracked_array.join(',,,'); localStorage.setItem('ao3tracking_list', tracked_list); // reload the box $('#tracked-box').detach(); $('#tracked-bg').detach(); showBox(); } // update the listings counts function markAllViewed() { loadList(); // get the current count for all listings $('#tracked-box li.tracked-listing').each(function() { var url = $(this).find('a').attr('href'); var current_count = $(this).find('span.tracked-current').text(); var index = tracked_array.indexOf(url); if (index > -1) { tracked_array[index+1] = current_count; } }); // update and save the new list tracked_list = tracked_array.join(',,,'); localStorage.setItem('ao3tracking_list', tracked_list); // reload the box $('#tracked-box').detach(); $('#tracked-bg').detach(); showBox(); } // show the box with tracked listings function showBox() { var tracked_bg = $('<div id="tracked-bg"></div>'); var tracked_box = $('<div id="tracked-box"></div>'); var box_buttons = $('<p class="actions"></p>'); var box_button_check = $('<input type="button" id="button-check" value="Check for new"></input>'); box_button_check.click(function() { box_button_edit.after(box_button_mark); checkForNew(); box_button_edit.detach(); box_button_check.detach(); }); var box_button_edit = $('<input type="button" id="button-edit" value="Edit list"></input>'); box_button_edit.click(function() { editList(); box_button_edit.after(box_button_save, box_button_cancel); box_button_check.detach(); box_button_edit.detach(); }); var box_button_save = $('<input type="button" id="button-save" value="Save list"></input>'); box_button_save.click(function() { saveList(); }); var box_button_cancel = $('<input type="button" id="button-cancel" value="Cancel edits"></input>'); box_button_cancel.click(function() { tracked_box.detach(); tracked_bg.detach(); showBox(); }); var box_button_mark = $('<input type="button" id="button-mark" style="visibility: hidden;" value="Mark all as viewed"></input>'); box_button_mark.click(function() { markAllViewed(); }); var box_button_close = $('<input type="button" id="button-close" value="Close"></input>'); box_button_close.click(function() { tracked_box.detach(); tracked_bg.detach(); }); var box_header = $('<h3></h3>').text('Tracked listings [' + tracked_array.length/3 + '/25]:'); var box_list = $('<ul id="box-list"></ul>'); tracked_box.append(box_buttons, box_header, box_list); // if there are saved listings if (tracked_array.length > 2) { for (var i = 0; i < tracked_array.length; i += 3) { var listing = $('<li id="tracked-listing-' + i/3 + '" class="tracked-listing"></li>').html('<a href="' + tracked_array[i+1] + '">' + tracked_array[i] + '</a> <span class="tracked-new"></span> <span class="tracked-saved">' + tracked_array[i+2] + '</span> <span class="tracked-current"></span>'); box_list.append(listing); } } else { var no_listings = $('<li style="opacity: 0.5; font-style: oblique;"></li>').html("you're not tracking anything yet!"); box_list.append(no_listings); box_button_check.css('visibility', 'hidden'); box_button_edit.css('visibility', 'hidden'); } box_buttons.append(box_button_check, box_button_edit, box_button_close); $('body').append(tracked_bg, tracked_box); } // attach the menu function addTrackedMenu() { // get the header menu var header_menu = $('ul.primary.navigation.actions'); // create and insert menu button var tracked_button = $('<input class="button" type="button" value="Tracked"></input>'); header_menu.find('#search').prepend(tracked_button); tracked_button.click(function() { if ($('#tracked-box').length == 0) { loadList(); showBox(); } }); } // add css rules to page head function addCss() { var style = $('<style type="text/css"></style>').appendTo($('head')); var css = '#tracked-box {position: fixed; top: 0px; bottom: 0px; left: 0px; right: 0px; width: 60%; height: 80%; max-width: 800px; margin: auto; overflow-y: auto; border: 10px solid #eee; box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.2); padding: 0 20px; background-color: #ffffff; z-index: 999;}\ #tracked-bg {position: fixed; width: 100%; height: 100%; background-color: #000000; opacity: 0.7; z-index: 998;}\ input[type="button"] {height: auto;}\ input.track-this {margin-bottom: 10px;}\ #tracked-box p.actions {float: none; text-align: left;}\ #button-save {font-weight: bold;}\ #button-close {float: right;}\ #tracked-box li span.tracked-new.new-stuff {font-weight: bold;}\ #tracked-box li span.tracked-new.no-new-stuff {opacity: 0.5;}\ #tracked-box li span.tracked-current, #tracked-box li span.tracked-saved {display: none;}\ #new-works {font-weight: bold;}'; style.append(css); } })(jQuery);