├── LICENSE └── ShikiRating.user.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 ImoutoChan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ShikiRating.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Shiki Rating 3 | // @namespace http://shikimori.org/ 4 | // @version 2.8.3 5 | // @description Rating from shiki users 6 | // @author ImoutoChan 7 | // @match http://shikimori.org/* 8 | // @match https://shikimori.org/* 9 | // @match http://shikimori.one/* 10 | // @match https://shikimori.one/* 11 | // @match http://shikimori.me/* 12 | // @match https://shikimori.me/* 13 | // @downloadURL https://github.com/ImoutoChan/shiki-rating-userscript/raw/master/ShikiRating.user.js 14 | // @updateURL https://github.com/ImoutoChan/shiki-rating-userscript/raw/master/ShikiRating.user.js 15 | // @license MIT 16 | // @grant none 17 | // ==/UserScript== 18 | 19 | var debug = false; 20 | 21 | function log(message) { 22 | if (!debug) { 23 | return; 24 | } 25 | console.log('ShikiRating: ' + message); 26 | } 27 | 28 | function getLocale() { 29 | return document.querySelector('body').getAttribute('data-locale'); 30 | } 31 | 32 | function needAddRating(urlpart) { 33 | return urlpart === "/animes" || 34 | urlpart === "/mangas" || 35 | urlpart === "/ranobe"; 36 | } 37 | 38 | function removeLastClass(domElement) { 39 | var classes = domElement.classList; 40 | classes.remove(classes.item(classes.length - 1)); 41 | } 42 | 43 | function setNoData(domElement) { 44 | var noData = document.createElement('p'); 45 | noData.classList.add('b-nothing_here'); 46 | noData.innerText = getLocale() === 'ru' 47 | ? `Недостаточно данных` 48 | : `Insufficient data`; 49 | 50 | domElement.innerHTML = ''; 51 | domElement.appendChild(noData); 52 | 53 | domElement.style.textAlign = 'center'; 54 | domElement.style.color = '#7b8084'; 55 | domElement.style.marginTop = '15px'; 56 | } 57 | 58 | function appendShikiRating() { 59 | 'use strict'; 60 | 61 | var urlpart = window.location.pathname.substring(0,7); 62 | log(urlpart); 63 | 64 | if (!needAddRating(urlpart)) { 65 | log('wrong page'); 66 | return; 67 | } 68 | 69 | if (document.querySelector("#shiki-score") !== null) { 70 | log('already created'); 71 | return; 72 | } 73 | 74 | if (document.querySelector(".scores > .b-rate") === null) { 75 | log("can't find default rating"); 76 | return; 77 | } 78 | 79 | // get current rating element 80 | var malRate = document.querySelector(".scores > .b-rate"); 81 | malRate.setAttribute('id', 'mal-score'); 82 | 83 | // clone it to new element 84 | var newShikiRate = malRate.cloneNode(true); 85 | newShikiRate.setAttribute('id', 'shiki-score'); 86 | 87 | // append cloned rating to parent container 88 | var rateContainer = document.querySelector(".scores"); 89 | rateContainer.appendChild(newShikiRate); 90 | 91 | // load scores stats 92 | var scoreDataJson = document.querySelector("#rates_scores_stats").getAttribute("data-stats"); 93 | var scoreData = JSON.parse(scoreDataJson); 94 | log(scoreDataJson); 95 | 96 | // set no data lable 97 | if (scoreData === null || scoreData.length === 0) { 98 | setNoData(newShikiRate); 99 | return; 100 | } 101 | 102 | // calculate shiki rating 103 | var sumScore = 0; 104 | var totalCount = 0; 105 | for (var i = 0; i < scoreData.length; i++) { 106 | sumScore += scoreData[i][1] * scoreData[i][0]; 107 | totalCount += scoreData[i][1] * 1; 108 | } 109 | var shikiScore = sumScore / totalCount; 110 | var shikiScoreDigit = Math.round(shikiScore); 111 | log(shikiScore); 112 | 113 | // set number value 114 | var scoreElement = newShikiRate.querySelector("div.text-score > div.score-value"); 115 | scoreElement.innerHTML = shikiScore.toFixed(2); 116 | removeLastClass(scoreElement); 117 | scoreElement.classList.add("score-" + shikiScoreDigit); 118 | 119 | // set stars calue 120 | var starElement = newShikiRate.querySelector("div.stars-container > div.stars.score"); 121 | removeLastClass(starElement); 122 | starElement.style.color = '#456'; 123 | starElement.classList.add("score-" + shikiScoreDigit); 124 | 125 | // load labels 126 | var labelData = getLocale() === 'ru' ? 127 | {"0":"","1":"Хуже некуда","2":"Ужасно","3":"Очень плохо","4":"Плохо","5":"Более-менее","6":"Нормально","7":"Хорошо","8":"Отлично","9":"Великолепно","10":"Эпик вин!"} : 128 | {"0":"","1":"Worst Ever","2":"Terrible","3":"Very Bad","4":"Bad","5":"So-so","6":"Fine","7":"Good","8":"Excellent","9":"Great","10":"Masterpiece!"}; 129 | 130 | // set label under score 131 | newShikiRate.querySelector("div.text-score > div.score-notice").textContent = labelData[shikiScoreDigit]; 132 | 133 | // set mal description label 134 | var malLabel = getLocale() === 'ru' ? 'На основе оценок mal' : 'From MAL users'; 135 | malRate.insertAdjacentHTML('afterend', '
' + malLabel + '
'); 136 | 137 | // set shiki description label 138 | var shikiCountLabel = '' + totalCount + ''; 139 | shikiCountLabel = (getLocale() === 'ru') 140 | ? 'На основе ' + shikiCountLabel + ' оценок shiki' 141 | : 'From ' + shikiCountLabel + ' shiki users'; 142 | newShikiRate.insertAdjacentHTML('afterend', '' + shikiCountLabel + '
'); 143 | 144 | // set style for mal description label 145 | var malScoreLabelElement = document.querySelector('.score-source'); 146 | malScoreLabelElement.style.marginBottom = '15px'; 147 | malScoreLabelElement.style.textAlign = 'center'; 148 | malScoreLabelElement.style.color = '#7b8084'; 149 | 150 | // set style for shiki description label 151 | var shikiScoreLabelElement = document.querySelector('.score-counter'); 152 | shikiScoreLabelElement.style.textAlign = 'center'; 153 | shikiScoreLabelElement.style.color = '#7b8084'; 154 | } 155 | 156 | function ready(fn) { 157 | document.addEventListener('page:load', fn); 158 | document.addEventListener('turbolinks:load', fn); 159 | 160 | if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading"){ 161 | fn(); 162 | } else { 163 | document.addEventListener('DOMContentLoaded', fn); 164 | } 165 | } 166 | 167 | ready(appendShikiRating); 168 | --------------------------------------------------------------------------------