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);