Favoriten Modul auf der Startseite für eine bessere Übersicht.
// ==UserScript==
// @name BS Favoriten Modul
// @namespace http://bs.to/
// @version 1.0.1
// @description Favoriten Modul auf der Startseite für eine bessere Übersicht.
// @author Seker61
// @match https://bs.to/
// @icon https://www.google.com/s2/favicons?domain=bs.to
// @grant none
// ==/UserScript==
(function () {
// Insert CSS Block
const css = document.createElement('style');
css.innerHTML = `
/* CSS for BS Favoriten Modul */
.unfold {
height: auto !important;
}
.serie .frame {
overflow: auto;
height: 27px;
min-height: 27px;
}
.serie .frame ul li {
margin: 1px;
}
#favoritesLinks > li {
padding: 2px 2px 2px 8px;
display: grid;
grid-template-columns: 25px 1fr 50%;
align-items: center;
}
#filter {
float: right;
width: 50%;
display: flex;
justify-content: space-between;
}
#filter > div > label {
display: inline-block;
width: auto;
}
#filter > div:hover > label,
#filter > div:hover > input {
text-decoration: underline;
cursor: pointer;
}
.hideSpecial,
.hideWatched {
display: none;
}
#columnFavorites {
width: 100%;
}
.prio {
color: gold;
}
`;
document.getElementsByTagName('head')[0].appendChild(css);
// Insert JS Block
const js = document.createElement('script');
js.innerHTML = `
// JS for BS Favoriten Modul
let lStorage = JSON.parse(localStorage.getItem('bs_favorite_modul'));
function unfold() {
const classFrame = document.getElementsByClassName('frame');
const classUnfold = document.getElementsByClassName('frame unfold');
if (classUnfold.length === 0) {
for (const e of classFrame) {
e.classList.add('unfold');
}
store('unfold', 'checked');
} else {
for (const e of classFrame) {
e.classList.remove('unfold');
}
store('unfold', '');
}
}
function hideWatched() {
const classWatched = document.getElementsByClassName('watched');
const classHidden = document.getElementsByClassName('watched hideWatched');
if (classHidden.length === 0) {
for (const e of classWatched) {
e.classList.add('hideWatched');
}
store('hideWatched', 'checked');
} else {
for (const e of classWatched) {
e.classList.remove('hideWatched');
}
store('hideWatched', '');
}
}
function hideSpecials() {
const classS0 = document.getElementsByClassName('s0');
const classS0Hide = document.getElementsByClassName('s0 hideSpecial');
if (classS0Hide.length === 0) {
for (const e of classS0) {
if (e.children[0].innerHTML === 'Specials') {
e.classList.add('hideSpecial');
}
}
store('hideSpecial', 'checked');
} else {
for (const e of classS0) {
e.classList.remove('hideSpecial');
}
store('hideSpecial', '');
}
}
function changePrio(element) {
const link = element.parentElement.querySelector('a').href;
if (lStorage.prioList.filter((word) => word === link).length > 0) {
element.classList.remove('prio');
lStorage.prioList = lStorage.prioList.filter((word) => word !== link);
save(lStorage);
movePrios();
return;
}
element.classList.add('prio');
lStorage.prioList.push(link);
save(lStorage);
movePrios();
}
function store(key, value) {
lStorage[key] = value;
save(lStorage);
}
function save(data) {
localStorage.setItem('bs_favorite_modul', JSON.stringify(data));
}
function movePrios() {
const prios = document.getElementsByClassName('prio');
const nonPrios = document.querySelectorAll('.fa-star:not(.prio)');
const favoritesLinks = document.getElementById('favoritesLinks');
const names = {
prio: [],
nonPrio: [],
};
if (prios !== 0) {
for (const element of prios) {
names.prio.push(element.parentElement.children[1].innerText);
}
for (const element of nonPrios) {
names.nonPrio.push(element.parentElement.children[1].innerText);
}
names.prio.sort((a, b) => {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
names.nonPrio.sort((a, b) => {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
names.prio.forEach((e) => {
const parentOfElement = getElementByText(
'#favoritesLinks > li > a',
e,
).parentElement;
favoritesLinks.appendChild(parentOfElement);
});
names.nonPrio.forEach((e) => {
const parentOfElement = getElementByText(
'#favoritesLinks > li > a',
e,
).parentElement;
favoritesLinks.appendChild(parentOfElement);
});
}
}
function getElementByText(selector, text) {
const selectedElements = document.querySelectorAll(selector);
for (const element of selectedElements) {
if (element.innerText === text) {
return element;
}
}
}
`;
document.getElementsByTagName('head')[0].appendChild(js);
// read localStorage
let lStorage = JSON.parse(localStorage.getItem('bs_favorite_modul'));
// Init localStorage
if (lStorage === null || lStorage === 'null') {
lStorage = {
unfold: '',
hideWatched: '',
hideSpecial: '',
prioList: [],
};
save(lStorage);
}
// Insert Table Favorite
const sectionHome = document.getElementsByClassName('home');
const listOfFavorite = document.getElementById('other-series-nav').getElementsByTagName('ul');
const counter = listOfFavorite[0].children.length - 1;
const favorites = document.createElement('div');
favorites.id = 'columnFavorites';
favorites.classList.add('column');
const favoritesInnerHTML = `
<section>
<header>
<h3>Favoriten (${counter})</h3>
<div id='filter'>
<div>
<input type='checkbox' id='hideSpecials' onclick='hideSpecials()' ${lStorage.hideSpecial}>
<label for='hideSpecials'> Specials</label>
</div>
<div>
<input type='checkbox' id='hideWatched' onclick='hideWatched()' ${lStorage.hideWatched}>
<label for='hideWatched'> Watched</label>
</div>
<div>
<input type='checkbox' id='unfold' onclick='unfold()' ${lStorage.unfold}>
<label for='unfold'> Unfold</label>
</div>
</header>
<div>
<ul class='serie' id='favoritesLinks'>${listOfFavorite[0].innerHTML}</ul>
</div>
</section>
</div>
`;
favorites.innerHTML = favoritesInnerHTML;
// Delete Serienvorschläge and fetch Data
const fetchedObjects = [];
const favoriteListItems = favorites.querySelectorAll('#favoritesLinks')[0].children;
Array.from(favoriteListItems).forEach((element) => {
if (element.innerText === 'Serienvorschläge') {
element.remove();
} else {
fetchedObjects.push(loadDataFromLink(element.children[0].href, element));
}
});
Promise.all(fetchedObjects).then((e) => {
sectionHome[0].appendChild(favorites);
if (lStorage.unfold === 'checked') {
unfold();
}
if (lStorage.hideWatched === 'checked') {
hideWatched();
}
if (lStorage.hideSpecial === 'checked') {
hideSpecials();
}
movePrios();
});
}());
function loadDataFromLink(url, element, fetchOject, e) {
(e || window.event).preventDefault();
return fetch(url, { credentials: 'same-origin' })
.then((response) => response.text())
.then((html) => {
const parser = new DOMParser();
const htmlDocument = parser.parseFromString(html, 'text/html');
const episodes = htmlDocument.querySelectorAll('.episodes > tbody > tr');
const episodesWatched = htmlDocument.querySelectorAll('.episodes > tbody > tr.watched');
const star = document.createElement('i');
star.classList.add('fas', 'fa-star');
lStorage.prioList.forEach((prioItem) => {
if (prioItem === element.childNodes[0].href) {
star.classList.add('prio');
}
});
star.onclick = function () {
changePrio(this);
};
element.appendChild(htmlDocument.querySelector('#seasons'));
element.insertBefore(star, element.childNodes[0]);
if (episodes.length === episodesWatched.length) {
element.getElementsByClassName('s1')[0].classList.add('watched');
}
})
.catch((error) => {
console.warn(error);
});
}