NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Anime OP/ED
// @version 0.10.6
// @description Get OP/ED by MAL
// @author ShaDream
// @match https://shikimori.org/*
// @match https://shikimori.one/*
// @match http://shikimori.one/*
// @match http://shikimori.org/*
// @connect myanimelist.net
// @updateURL https://openuserjs.org/meta/ShaDream/Anime_OPED.meta.js
// @copyright 2018, ShaDream (https://openuserjs.org/users/ShaDream)
// @downloadURL https://openuserjs.org/install/ShaDream/Anime_OPED.user.js
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @license MIT
// ==/UserScript==
var debug = !1, showMalCount = !1;
function log(message) {
debug && console.log(message)
}
const insertAfter = (elem, refElem) => refElem.parentNode.insertBefore(elem, refElem.nextSibling);
function get_anime_id() {
let full_url = window.location.href,
start = full_url.lastIndexOf('/') + 1;
for (; isNaN(parseInt(full_url[start]));) start++;
let number = "";
for (; !isNaN(parseInt(full_url[start]));) number += full_url[start], start++;
return number
}
function createMusic(elements, placeToAppend) {
elements.forEach(element => {
var sound = document.createElement("span");
sound.innerText = element, sound.className = "value sound", placeToAppend.appendChild(sound)
})
}
function musicConstructor(main, text, items) {
var container = document.createElement("div"),
addedClassName = "OP'S" === text ? " op" : " ed";
container.className = "sound-container" + addedClassName, main.appendChild(container);
var title = document.createElement("div");
title.innerText = text, title.className = "subheadline m5", container.appendChild(title), createMusic(items, container)
}
function createOPEDList(op, ed) {
if (0 != op.length || 0 != ed.length) {
// Create main div and paste in in a right place
var main = document.createElement("div"),
paste_after = document.getElementsByClassName("b-db_entry")[0];
//Create open button if needed
if (main.className = "main-sound-container", insertAfter(main, paste_after),
//Create content
musicConstructor(main, "OP'S", op), musicConstructor(main, "ED'S", ed), op.length > 4 || ed.length > 4) {
main.style.maxHeight = '150px';
var expand_container = document.createElement("div");
insertAfter(expand_container, main), expand_container.className = "b-height_shortener open-music";
var shade = document.createElement("div");
shade.className = "shade", expand_container.appendChild(shade);
var expander = document.createElement("div");
expander.className = "expand", expand_container.appendChild(expander);
var span = document.createElement('span');
span.innerText = "Развернуть", expander.appendChild(span), expand_container.onclick = function () {
expand_container.parentNode.removeChild(expand_container), main.style.animation = 'height 15s cubic-bezier(.19,1,.22,1) forwards'
}
}
//apply styles
createStyle()
}
}
function createStyle() {
// Here you can change style of all new elements
GM_addStyle(".main-sound-container{margin-bottom:15px; overflow:hidden}.sound-container{display:inline-block; vertical-align:top; width: 48%;}.op{margin-right:3%;}.sound{padding-top:5px; margin:5px; display: block;}.open-music{margin-bottom:15px;}@keyframes height {from{max-height:150px;} to {max-height: 5000px;}}")
}
function getMusic(doc, class_name) {
let music = Array.from(doc.querySelectorAll('.theme-songs.js-theme-songs.' + class_name + ' > table > tbody tr > td:nth-child(2)'));
return music.map(function(tr, index){
let songName = tr.querySelector('.theme-song-title')?.innerText;
if (!songName){
return tr.innerText.trim();
}
let songAuthor = tr.querySelector('.theme-song-artist').innerText;
let episodes = tr.querySelector('.theme-song-episode')?.innerText;
return `${index+1}. ${songName}${songAuthor} ${episodes?episodes:""}`;
});
}
function CreateUserScoresCount(doc) {
if (document.getElementById("shiki-score"), null !== document.getElementById("shiki-score") && showMalCount) {
var shikiRating = document.getElementsByClassName('score-source'),
count = doc.querySelector("#content > table > tbody > tr > td:nth-child(2) > div.js-scrollfix-bottom-rel > table > tbody > tr:nth-child(1) > td > div.pb16 > div.di-t.w100.mt12 > div.anime-detail-header-stats.di-tc.va-t > div.stats-block.po-r.clearfix > div.fl-l.score").getAttribute("data-user");
if (count = count.substring(0, count.length - 6), 0 != shikiRating.length) shikiRating[0].innerText = "На основе " + count + " оценок mal";
else {
var score = document.querySelector("#animes_show > section > div > div.menu-slide-outer.x199 > div > div > div.block > div.b-db_entry > div.c-about > div > div.c-info-right > div:nth-child(1) > div.scores > div"),
scoreCount = document.createElement('p');
scoreCount.className = 'score - source', scoreCount.style = "margin-bottom: 15px; text-align: center; color: rgb(123, 128, 132);", scoreCount.innerText = "На основе " + count + " оценок mal", insertAfter(scoreCount, score)
}
}
}
function loadMal() {
"use strict";
if (!isAnimePage() || isAdded()) return;
let url = "https://myanimelist.net/anime/" + get_anime_id();
log("Finding OP/ED."), GM_xmlhttpRequest({
method: "GET",
url: url,
onload: function (response) {
let doc = (new DOMParser).parseFromString(response.responseText, 'text/html');
createOPEDList(getMusic(doc, "opnening"), getMusic(doc, "ending")), CreateUserScoresCount(doc), log("OP/ED finded!");
}
})
}
function isAnimePage() {
return 0 === window.location.href.replace(/http.?:\/\/shikimori\..*\/animes\/[^\/]*/, "").length
}
function isAdded() {
return document.getElementsByClassName("main-sound-container").length > 0
}
function ready(fn) {
document.addEventListener('page:load', fn), document.addEventListener('turbolinks:load', fn), (document.attachEvent ? "complete" === document.readyState : "loading" !== document.readyState) ? fn() : document.addEventListener('DOMContentLoaded', fn)
}
ready(loadMal);