900

Recite.

  1. // ==UserScript==
  2. // @name 900
  3. // @namespace derjoker
  4. // @version 0.7.2
  5. // @description Recite.
  6. // @author Feng Ya
  7. // @match https://github.com/derjoker/900/blob/master/Deutsch.md
  8. // @grant GM_addStyle
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // Your code here...
  15.  
  16. const LOCAL_INDEX = 'LOCAL_INDEX';
  17.  
  18. const localIndex = parseInt(window.localStorage.getItem(LOCAL_INDEX), 10);
  19.  
  20. GM_addStyle(`
  21. .card-container {
  22. font-size: 1.6em;
  23. text-align: center;
  24. margin-top: 0.6em;
  25. padding: 0.8em;
  26. border: black 1px solid;
  27. }
  28. .card > div {
  29. font-size: 0.6em;
  30. padding: 0.8em;
  31. }
  32. .highlight {
  33. background: rgba(255, 242, 51, 0.298);
  34. }
  35. .mask {
  36. color: rgba(255, 242, 51, 0.298);
  37. }
  38. `);
  39.  
  40. const regex = /[\wäöüß]+/gi;
  41.  
  42. function replace(node, percent) {
  43. if (node.nodeType === 1) percent = 1;
  44. const html = node.textContent.replace(regex, match => {
  45. return Math.random() > percent
  46. ? match
  47. : `<span class="highlight mask">${match}</span>`;
  48. });
  49. // ELEMENT_NODE
  50. if (node.nodeType === 1) {
  51. node.innerHTML = html;
  52. return node.outerHTML;
  53. }
  54. // TEXT_NODE
  55. if (node.nodeType === 3) return html;
  56.  
  57. return '';
  58. }
  59.  
  60. function transform(el, percent) {
  61. // const clone = el.cloneNode(true);
  62. // console.log(clone.childNodes);
  63.  
  64. const childNodes = [];
  65. el.childNodes.forEach(child => {
  66. childNodes.push(replace(child, percent));
  67. });
  68. el.innerHTML = childNodes.join('');
  69. }
  70.  
  71. const items = document.querySelectorAll('li > p');
  72.  
  73. const file = document.querySelector('.file');
  74. file.insertAdjacentHTML(
  75. 'beforebegin',
  76. '<section class="card-container"></section>'
  77. );
  78.  
  79. const container = document.querySelector('.card-container');
  80. container.innerHTML = `
  81. <div class="prev"></div>
  82. <div class="card"></div>
  83. <div class="next"></div>
  84. `;
  85.  
  86. const card = document.querySelector('.card');
  87.  
  88. function display(index) {
  89. index = (index + items.length) % items.length;
  90. window.localStorage.setItem(LOCAL_INDEX, index);
  91.  
  92. const item = items[index];
  93. const clone = item.cloneNode(true);
  94. card.innerHTML = `<div>${index + 1}/${items.length}</div>`;
  95. card.appendChild(clone);
  96. transform(clone, 0.2);
  97. }
  98.  
  99. let index = localIndex >= 0 ? localIndex : 0;
  100.  
  101. function next() {
  102. index += 1;
  103. display(index);
  104. }
  105.  
  106. function prev() {
  107. index -= 1;
  108. display(index);
  109. }
  110.  
  111. function toggle() {
  112. document.querySelectorAll('.highlight').forEach(highlight => {
  113. highlight.classList.toggle('mask');
  114. });
  115. }
  116.  
  117. let mode = false;
  118.  
  119. function toggleMode() {
  120. mode = !mode;
  121.  
  122. if (mode) {
  123. file.style.display = 'none';
  124. container.style.display = '';
  125. } else {
  126. file.style.display = '';
  127. container.style.display = 'none';
  128. items[index].scrollIntoView();
  129. }
  130. }
  131.  
  132. display(index);
  133. container.style.display = 'none';
  134. items[index].scrollIntoView();
  135.  
  136. container.addEventListener('click', event => {
  137. toggle();
  138. });
  139.  
  140. items.forEach((item, i) => {
  141. item.addEventListener('click', event => {
  142. index = i;
  143. display(index);
  144. toggleMode();
  145. });
  146. });
  147.  
  148. document.body.addEventListener('keydown', event => {
  149. if (event.key === 'x') {
  150. event.preventDefault();
  151. toggleMode();
  152. }
  153.  
  154. if (!mode) return;
  155. if (event.key === 'n' || event.key === 'j') {
  156. event.preventDefault();
  157. next();
  158. }
  159. if (event.key === 'p' || event.key === 'k') {
  160. event.preventDefault();
  161. prev();
  162. }
  163. if (event.key === 'r') {
  164. event.preventDefault();
  165. display(index);
  166. }
  167. if (event.key === ' ') {
  168. event.preventDefault();
  169. toggle();
  170. }
  171. });
  172. })();