您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Zählt die bereits geschauten/gelesenen Animes/Mangas und erlaubt es die Tabellen per Klick zusammenzuklappen bzw. sich mehr Details anzeigen zu lassen.
- // ==UserScript==
- // @name Proxer Statistics
- // @namespace https://greasyfork.org/de/users/83349-deimos
- // @version 1.31
- // @description Zählt die bereits geschauten/gelesenen Animes/Mangas und erlaubt es die Tabellen per Klick zusammenzuklappen bzw. sich mehr Details anzeigen zu lassen.
- // @author Deimos
- // @run-at document-start
- // @include http://proxer.me/*
- // @include https://proxer.me/*
- // @include http://www.proxer.me/*
- // @include https://www.proxer.me/*
- // @grant unsafeWindow
- // @history 1.31 Beheben von Cookie Problem, Beheben von nicht erkannten URLs
- // @history 1.30 Entferne Userscript Anker, Ergänze Novel, Zähle Medienkategorien dynamisch
- // @history 1.2 Script funktioniert auch im User-Control-Panel
- // @history 1.1 Einbinden des Userscript Anker von Blue.Reaper
- // @history 1.0 Zählen von Anime/Manga, anzeigen von Details, minimieren von Tabellen
- // ==/UserScript==
- //############## Initialisierung ####################
- var page = 0;
- var n_values = 12
- //guckt ob Cookie vorhanden ist und korrekted Format hat, ansonsten wird neuer erstellt
- var hv_values = checkCookie("hv_values", "v".repeat(n_values)); //v:= visible h:= hidden
- var dn_values = checkCookie("dn_values", "n".repeat(n_values)); //d:= details n:= no details
- //############################# Einbinden des Scripts #############################
- //startet das Script beim Laden der Seite und
- document.addEventListener('DOMContentLoaded', function(event) {
- waitForKeyElements ("#pageMetaAjax", applyChange, false);
- });
- function applyChange(){
- var path1 = window.location.pathname.split('/')[3]
- var path2 = window.location.search
- if(path1 == "anime" || path2.substring(0,8) === "?s=anime") ///User befindet sich auf Anime Verzeichnis
- {
- page = 0;
- tableListener();
- }
- else if(path1 == "manga" || path2.substring(0,8) === "?s=manga") ///User befindet sich auf Manga Verzeichnis
- {
- page = 1;
- tableListener();
- }
- else if(path1 == "novel" || path2.substring(0,8) === "?s=novel") ///User befindet sich auf Novel Verzeichnis
- {
- page = 2;
- tableListener();
- }
- }
- //############################# Hauptteil #############################
- //Ermitteln der Tabellenlänge und setzen der EventListener
- function tableListener()
- {
- var tables = document.getElementsByTagName("table");
- for(var i = 0; i<tables.length;i++){
- var tr = tables[i].rows;
- var l = 0;
- if(tr[2].getElementsByTagName("td")[0].innerHTML !== "Keine Einträge.")
- l = tr.length - 2;
- var message= ": " + l;
- //Anzahl anzeigen
- tr[0].getElementsByTagName("th")[0].innerHTML+= message;
- tr[0].addEventListener("click",action);
- tr[0].id ="tr"+(i+page*4);
- //Tabellen einklappen
- if(hv_values[i+page*4]=="h")
- hide(tr);
- //Details anzeigen
- if(dn_values[i+page*4]=="d")
- details(tr);
- }
- }
- //Auswahl ob "hide" oder "details", setzen des neuen Cookies
- function action(e)
- {
- var tr = this.parentElement.parentElement.rows;
- var xPosition = e.clientX;
- var rect = tr[0].getBoundingClientRect();
- var width = tr[0].offsetWidth;
- if(xPosition<width/2){
- details(tr);
- setCookie("dn_values",dn_values);
- }
- else{
- hide(tr);
- setCookie("hv_values",hv_values);
- }
- }
- //Anzeigen der genaueren Details der ausgewählten Tabelle
- function details(tr)
- {
- //Checke ob Einträge vorhanden sind
- if(!tr[2].getElementsByTagName("td")[2]){
- return false
- }
- var id = parseInt(tr[0].id.substring(2));
- var text = tr[0].getElementsByTagName("th")[0].innerHTML;
- //Details werden minimiert
- if(text.includes("<br>")){
- text = text.slice(0,text.indexOf("<br>"));
- tr[0].getElementsByTagName("th")[0].innerHTML = text;
- //Update des Status
- dn_values = dn_values.substring(0,id) + "n" + dn_values.substring(id+1, dn_values.length); //erstellen eines neuen Cookies
- return true;
- }
- var l = tr.length;
- var content = {}
- //Zähle verschieden Medientypen
- for(var e = 2; e<l; e++){
- var type = tr[e].getElementsByTagName("td")[2].innerHTML;
- if(type in content)
- content[type] +=1
- else
- content[type] =1
- }
- //Anzeigen
- var message= "";
- for(type in content){
- message += "<br> "+type.replace("<br>"," ")+": "+content[type]
- }
- tr[0].getElementsByTagName("th")[0].innerHTML+= message;
- //Update des Status
- dn_values = dn_values.substring(0,id) + "d" + dn_values.substring(id+1, dn_values.length);
- }
- //Einklappen der ausgewählten Tabelle
- function hide(tr)
- {
- var id = parseInt(tr[0].id.substring(2));
- var visibility;
- var char;
- if(tr[1].style.display == "none") {
- visibility = "table-row";
- char = "v";
- }
- else{
- visibility = "none";
- char = "h";
- }
- //Update des Status
- hv_values = hv_values.substring(0,id) + char + hv_values.substring(id+1, hv_values.length);
- for(var e = 1; e < tr.length; e++){
- tr[e].style.display = visibility;
- }
- }
- //############################# Cookies #############################
- function checkCookie(cname,ctext)
- {
- var cookie = getCookie(cname);
- if (cookie === "" || cookie.length != n_values)
- {
- cookie = ctext;
- setCookie(cname, cookie);
- }
- return cookie;
- }
- function getCookie(cname)
- {
- var name = cname + "=";
- var ca = document.cookie.split(";");
- for(var i = 0; i < ca.length; i++) {
- var c = ca[i];
- while (c.charAt(0) == ' ') {
- c = c.substring(1);
- }
- if (c.indexOf(name) === 0) {
- return c.substring(name.length, c.length);
- }
- }
- return "";
- }
- function setCookie(cname, cvalue)
- {
- var d = new Date();
- d.setTime(d.getTime() + (365*24*60*60*1000));
- var expires = "expires="+d.toUTCString();
- document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/" + ";SameSite=Strict;"
- }
- //############################### Hintergrund Thread #######################################
- //Code from: https://github.com/CoeJoder/waitForKeyElements.js
- //(Greasy Fork doesn't allow to include this project by "require")
- function waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals) {
- if (typeof waitOnce === "undefined") {
- waitOnce = true;
- }
- if (typeof interval === "undefined") {
- interval = 300;
- }
- if (typeof maxIntervals === "undefined") {
- maxIntervals = -1;
- }
- var targetNodes = (typeof selectorOrFunction === "function")
- ? selectorOrFunction()
- : document.querySelectorAll(selectorOrFunction);
- var targetsFound = targetNodes && targetNodes.length > 0;
- if (targetsFound) {
- targetNodes.forEach(function(targetNode) {
- var attrAlreadyFound = "data-userscript-alreadyFound";
- var alreadyFound = targetNode.getAttribute(attrAlreadyFound) || false;
- if (!alreadyFound) {
- var cancelFound = callback(targetNode);
- if (cancelFound) {
- targetsFound = false;
- }
- else {
- targetNode.setAttribute(attrAlreadyFound, true);
- }
- }
- });
- }
- if (maxIntervals !== 0 && !(targetsFound && waitOnce)) {
- maxIntervals -= 1;
- setTimeout(function() {
- waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals);
- }, interval);
- }
- }