Greasy Fork 还支持 简体中文。

Jpdb custom components

Allows custom components for kanji

目前為 2022-09-10 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Jpdb custom components
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.0.2
  5. // @description Allows custom components for kanji
  6. // @author Calonca
  7. // @match https://jpdb.io/kanji/*
  8. // @match https://jpdb.io/review
  9. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  10. // @require http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
  11. // @run-at document-start
  12. // @grant GM_addStyle
  13. // @grant GM_setValue
  14. // @grant GM_getValue
  15. // @license GPLv2
  16. // ==/UserScript==
  17.  
  18. (function() {
  19. 'use strict';
  20. function getCCList(mnemonic){//returns custom component array from mnemonic
  21. if (mnemonic == null){
  22. return [];
  23. }else {
  24. let componetsPharagraph =
  25. Array.from(mnemonic.childNodes)
  26. .filter(p=>p.nodeName=="P")
  27. .map(p=>p.innerHTML)
  28. .find(t=>t.includes("Composed of: "));
  29. return componetsPharagraph.substring(componetsPharagraph.indexOf(':') + 2).split(",");
  30. }
  31. }
  32. function addComponents(){
  33. let mnemonicHTML = document.getElementsByClassName("mnemonic")[0];
  34. const componentsList = document.getElementsByClassName("subsection-composed-of-kanji")[0].getElementsByClassName("subsection")[0].childNodes;
  35. const componentsLen = componentsList.length;
  36.  
  37. let customSpellingList = getCCList(mnemonicHTML);
  38. const customSpellingLen = customSpellingList.length;
  39. if (customSpellingLen>0){
  40. let nodesToRemove = componentsLen-customSpellingLen;
  41. console.log(nodesToRemove);
  42. //Removes nodes if the custom componets are less then the original ones
  43. for (let i=0;i<nodesToRemove;i++){
  44. componentsList[0].parentNode.removeChild(componentsList[customSpellingLen])
  45. }
  46. //Replaces the kanji/radical/spelling and the keyword/description
  47. for (let i=0;i<customSpellingLen;i++){
  48.  
  49. if (i>=componentsLen){//Duplicates nodes if we have more custom componets then the original ones
  50. componentsList[0].parentNode.appendChild(componentsList[0].cloneNode(true));
  51. }
  52. let plain = componentsList[i].querySelector(".spelling .plain");
  53. plain.innerHTML = customSpellingList[i];
  54. plain.href = "/kanji/"+customSpellingList[i]+"#a"
  55.  
  56. //Gets the keyword for each compnent
  57. $.get( plain.href, function( data ) {
  58. let doc22 = $(data);
  59. let containerBugFix = doc22[24];
  60. let desc = containerBugFix.querySelector(".vbox.gap .subsection").innerHTML;
  61. componentsList[i].querySelector(".description").innerHTML = desc;
  62. });
  63.  
  64. }
  65. }
  66. }
  67.  
  68. if(window.location.href.indexOf("https://jpdb.io/kanji") > -1) {
  69. addComponents();
  70. } else if (window.location.href.indexOf("https://jpdb.io/review#a") > -1){//If reviewing wait for mnemonic to show up before adding the components
  71. waitForKeyElements (
  72. ".mnemonic"
  73. , addComponents
  74. );
  75. }
  76. })();
  77.  
  78.  
  79. //Put the function here instead of requires due to GreasyFolk rules, original can be found at https://gist.github.com/BrockA/2625891
  80. /*--- waitForKeyElements(): A utility function, for Greasemonkey scripts,
  81. that detects and handles AJAXed content.
  82.  
  83. Usage example:
  84.  
  85. waitForKeyElements (
  86. "div.comments"
  87. , commentCallbackFunction
  88. );
  89.  
  90. //--- Page-specific function to do what we want when the node is found.
  91. function commentCallbackFunction (jNode) {
  92. jNode.text ("This comment changed by waitForKeyElements().");
  93. }
  94.  
  95. IMPORTANT: This function requires your script to have loaded jQuery.
  96. */
  97. function waitForKeyElements (
  98. selectorTxt, /* Required: The jQuery selector string that
  99. specifies the desired element(s).
  100. */
  101. actionFunction, /* Required: The code to run when elements are
  102. found. It is passed a jNode to the matched
  103. element.
  104. */
  105. bWaitOnce, /* Optional: If false, will continue to scan for
  106. new elements even after the first match is
  107. found.
  108. */
  109. iframeSelector /* Optional: If set, identifies the iframe to
  110. search.
  111. */
  112. ) {
  113. var targetNodes, btargetsFound;
  114.  
  115. if (typeof iframeSelector == "undefined")
  116. targetNodes = $(selectorTxt);
  117. else
  118. targetNodes = $(iframeSelector).contents ()
  119. .find (selectorTxt);
  120.  
  121. if (targetNodes && targetNodes.length > 0) {
  122. btargetsFound = true;
  123. /*--- Found target node(s). Go through each and act if they
  124. are new.
  125. */
  126. targetNodes.each ( function () {
  127. var jThis = $(this);
  128. var alreadyFound = jThis.data ('alreadyFound') || false;
  129.  
  130. if (!alreadyFound) {
  131. //--- Call the payload function.
  132. var cancelFound = actionFunction (jThis);
  133. if (cancelFound)
  134. btargetsFound = false;
  135. else
  136. jThis.data ('alreadyFound', true);
  137. }
  138. } );
  139. }
  140. else {
  141. btargetsFound = false;
  142. }
  143.  
  144. //--- Get the timer-control variable for this selector.
  145. var controlObj = waitForKeyElements.controlObj || {};
  146. var controlKey = selectorTxt.replace (/[^\w]/g, "_");
  147. var timeControl = controlObj [controlKey];
  148.  
  149. //--- Now set or clear the timer as appropriate.
  150. if (btargetsFound && bWaitOnce && timeControl) {
  151. //--- The only condition where we need to clear the timer.
  152. clearInterval (timeControl);
  153. delete controlObj [controlKey]
  154. }
  155. else {
  156. //--- Set a timer, if needed.
  157. if ( ! timeControl) {
  158. timeControl = setInterval ( function () {
  159. waitForKeyElements ( selectorTxt,
  160. actionFunction,
  161. bWaitOnce,
  162. iframeSelector
  163. );
  164. },
  165. 300
  166. );
  167. controlObj [controlKey] = timeControl;
  168. }
  169. }
  170. waitForKeyElements.controlObj = controlObj;
  171. }
  172.