您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Annotates radical, kanji and vocab pages with SRS colours. Original script by jeshuamorrissey.
当前为
// ==UserScript== // @name WaniKani Item Annotator // @namespace mempo // @description Annotates radical, kanji and vocab pages with SRS colours. Original script by jeshuamorrissey. // @author Mempo // @version 1.1 // @include http://www.wanikani.com/radical* // @include http://www.wanikani.com/kanji* // @include http://www.wanikani.com/vocabulary* // @include http://www.wanikani.com/account* // @include https://www.wanikani.com/radical* // @include https://www.wanikani.com/kanji* // @include https://www.wanikani.com/vocabulary* // @include https://www.wanikani.com/account* // @grant none // ==/UserScript== console.log('@@@@ start of WaniKani Item Annotator'); var apiKey = $.jStorage.get('WIA_apiKey'); if(apiKey === null){ //not initialized yet console.log('#### no apiKey found'); if (window.location.href.indexOf('account') != - 1) { apiKey = "" + retrieveAPIkey(); console.log('@@@@@' + apiKey); $.jStorage.set('WIA_apiKey', apiKey); } else { var okcancel = confirm('WaniKani Item Annotator has no API key entered!\nPress OK to go to your settings page and retrieve your API key!'); if (okcancel == true) { window.location = 'https://www.wanikani.com/account'; return; } } } console.log('#### apiKey is: ' + apiKey); // Determine which API call we are going to make. var target = 'kanji'; if (window.location.href.indexOf('vocabulary') >= 0) { target = 'vocabulary'; } else if (window.location.href.indexOf('radicals') >= 0) { target = 'radicals'; } console.log('@@@ target is: ' + target); // Load the API data. $.get(apiURL(target), function(xhr) { // Parse the response. console.log("######"); console.log(xhr); // Build up an item mapping from Kanji --> Information var itemMapping = {}; // Get the actual request information. If the target is vocabulary, for some reason // we have to got an additional level into 'request_information.general'. This is // probably to account for specialised vocab which will be added later. var information = xhr.requested_information; if (target === 'vocabulary') { information = information.general; } for (var i in information) { var item = information[i]; // Extract the character (Kanji) from the item. var character = item.character; // If we are looking at radicals, use the meaning instead (convert the meaning to // the 'user friendly' format). if (target === 'radicals') { character = item.meaning.toLowerCase(); } // Get the SRS level from the item. The 'user_specific' object will be `null` if the item // hasn't been unlocked yet. In this case, just set the SRS level to `null`. var srs = null; if (item.user_specific) { srs = item.user_specific.srs; } // Build the mapping for this character. itemMapping[character] = { 'srs': srs }; } // Actually do stuff with this mapping. main(itemMapping, target); }); /** * Mapping of SRS --> Object, where the object contains a series * of transformation colors. These transformations will be applied * via the element.style property, so should have priority. */ var newColors = { 'apprentice': { 'background': '#f100a0', 'border': '#f100a0', 'gradient_start': '#f0a', 'gradient_end': '#dd0093' }, 'guru': { 'background': '#882d9e', 'border': '#882d9e', 'gradient_start': '#aa38c6', 'gradient_end': '#882d9e' }, 'master': { 'background': '#294ddb', 'border': '#294ddb', 'gradient_start': '#5571e2', 'gradient_end': '#294ddb' }, 'enlighten': { 'background': '#0093dd', 'border': '#0093dd', 'gradient_start': '#0af', 'gradient_end': '#0093dd' }, 'burned': { 'background': '#434343', 'border': '#434343', 'gradient_start': '#555', 'gradient_end': '#434343' } }; /** * Main function: actually annotate the elements. Takes as input information from * the WK API as a mapping from Japanese Element --> Object. In this case, the * object need only contain the SRS level of the element. */ function main(itemMapping, target) { // Find all characters on the page. var elements = document.querySelectorAll('.character-item'); for (var i in elements) { var element = elements[i]; /* // If this isn't actually an element (could happen, who knows), just skip it. if (!element.querySelector || !element.style) { continue; } */ // Get the element containing the japanese information. var japaneseElement = element.querySelector('.character'); // The japanese value to look up in the item mapping is the text of this element. var japanese = japaneseElement.textContent; // If we happen to be looking at radicals, some of them use pictures instead. It is // simpler to use the radical meaning in this case (as there is only one meaning). // The meaning is stored in the last list element within the element (for some reason // there is a list element first). if (target === 'radicals') { var radicalLink = element.querySelector('a').getAttribute('href'); japanese = radicalLink.slice(radicalLink.lastIndexOf('/') + 1); //console.log('@@@@@ ' + japanese); } // Find the actual japanese SRS information. japanese = itemMapping[japanese]; //console.log(japanese); // If we couldn't find the SRS information for the element, or the element hasn't been unlocked // yet, just ignore it. if (!japanese.srs) { continue; } // Find the corresponding colors. var colors = newColors[japanese.srs]; // Actually change the properties. This was essentially taken from the elements already on the page. element.style['background'] = colors.background + ' linear-gradient(to bottom, ' + colors.gradient_start + ', ' + colors.gradient_end + ')'; element.style['borderColor'] = colors.border; } } function retrieveAPIkey() { var apiKey; for(var i=0;i<document.getElementsByClassName('span6').length;i++){ if(document.getElementsByClassName('span6')[i].getAttribute('placeholder')=="Key has not been generated") { apiKey = document.getElementsByClassName('span6') [i].getAttribute('value'); } } alert('API key was set to: ' + apiKey); if (apiKey) { return apiKey; } } function apiURL(target){ return 'https://www.wanikani.com/api/user/' + apiKey + '/' + target; }