WaniKani Markdown Notes

Allows you to write Markdown in the notes, which will be rendered as HTML when the page loads.

当前为 2016-01-01 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name WaniKani Markdown Notes
  3. // @namespace rfindley
  4. // @description Allows you to write Markdown in the notes, which will be rendered as HTML when the page loads.
  5. // @version 1.3
  6. // @require https://cdnjs.cloudflare.com/ajax/libs/showdown/1.3.0/showdown.min.js
  7. // @include https://www.wanikani.com/level*
  8. // @include https://www.wanikani.com/radical*
  9. // @include https://www.wanikani.com/kanji*
  10. // @include https://www.wanikani.com/vocabulary*
  11. // @include https://www.wanikani.com/review/session*
  12. // @copyright 2013, Jeshua
  13. // @run-at document-end
  14. // @grant none
  15. // ==/UserScript==
  16.  
  17. wkmdnotes = {};
  18.  
  19. (function() {
  20. /**
  21. * Render the given markdown text.
  22. */
  23. function render(text) {
  24. // Do some custom replacements.
  25. text = text.replace(/#kan#/g, '<span class="kanji-highlight highlight-kanji" rel="tooltip" data-original-title="Kanji">');
  26. text = text.replace(/#\/kan#/g, '</span>');
  27.  
  28. text = text.replace(/#rad#/g, '<span class="radical-highlight highlight-radical" rel="tooltip" data-original-title="Radical">');
  29. text = text.replace(/#\/rad#/g, '</span>');
  30.  
  31. text = text.replace(/#read#/g, '<span class="reading-highlight highlight-reading" rel="tooltip" data-original-title="Reading">');
  32. text = text.replace(/#\/read#/g, '</span>');
  33.  
  34. text = text.replace(/#voc#/g, '<span class="vocabulary-highlight highlight-vocabulary" rel="tooltip" data-original-title="Vocabulary">');
  35. text = text.replace(/#\/voc#/g, '</span>');
  36.  
  37. text = text.replace(/~br~/g, '<br>'); // For backward compatibility
  38.  
  39. // Render the rest as markdown.
  40. return (new showdown.Converter()).makeHtml(text);
  41. }
  42.  
  43. /**
  44. * Find all of the tooltips in the given container and tooltipify them.
  45. */
  46. function activateTooltips(container) {
  47. if (container.tooltip) {
  48. container.find('span[rel="tooltip"]').tooltip();
  49. }
  50. }
  51.  
  52. /**
  53. * Setup the given note field with the required callbacks.
  54. */
  55. function setupNoteField(note) {
  56. // Save the markdown and render the content.
  57. note.data('noteContent', note.html().replace(/<br>/g,'\n'));
  58. note.html(render(note.html()));
  59. activateTooltips(note);
  60.  
  61. note.click(function(e) {
  62. if (e.target.tagName.toLowerCase() === 'textarea') {
  63. return;
  64. }
  65.  
  66. // If the target is the div, they are going from display --> edit.
  67. if (e.target.tagName.toLowerCase() !== 'button') {
  68. var interval = setInterval(function() {
  69. // If we can find a textarea, they must have clicked to edit the text field.
  70. // So, we want to display the markdown content.
  71. if (note.find('textarea')) {
  72. clearInterval(interval);
  73. if (note.data('noteContent') === 'Click to add note') {
  74. note.find('textarea').val('');
  75. } else {
  76. note.find('textarea').val(note.data('noteContent'));
  77. }
  78. }
  79. }, 50);
  80. }
  81.  
  82. // Otherwise, they are going from edit --> display.
  83. else {
  84. var textarea = note.find('textarea');
  85. var str = textarea.val().replace(/\n/g,'~br~');
  86. textarea.html(str);
  87. console.log('str='+str);
  88. var interval = setInterval(function() {
  89. // Keep waiting until there is no text area. Then, save the changed markdown
  90. // value to the data. Also re-render the note.
  91. if (note.find('textarea').length === 0) {
  92. clearInterval(interval);
  93. note.data('noteContent', note.html().replace(/<br>/g,'\n'));
  94. note.html(render(note.html()));
  95. activateTooltips(note);
  96. }
  97. }, 50);
  98. }
  99. });
  100. }
  101. function main() {
  102. // Convert the text in the meaning note.
  103. var noteFields = ['.note-meaning', '.note-reading'];
  104. $.each(noteFields, function(i, noteSelector) {
  105. // During reviews, we have to wait for the field to be added to the dom first.
  106. // Then, we can add a listener to the note selector.
  107. $('#option-item-info').click(function() {
  108. var interval = setInterval(function() {
  109. if ($(noteSelector).length !== 0) {
  110. clearInterval(interval);
  111. setupNoteField($(noteSelector));
  112. }
  113. }, 50);
  114. });
  115.  
  116. // Setup the note field if it is on the page already.
  117. //setupNoteField($(noteSelector));
  118. });
  119. }
  120. // Run startup() after window.onload event.
  121. if (document.readyState === 'complete')
  122. main();
  123. else
  124. window.addEventListener("load", main, false);
  125. })(wkmdnotes);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址