R4 Utils

R4 Utils Library

Skrip ini tidak untuk dipasang secara langsung. Ini adalah pustaka skrip lain untuk disertakan dengan direktif meta // @require https://update.greatest.deepsurf.us/scripts/482597/1301960/R4%20Utils.js

  1. // ==UserScript==
  2. // @name R4 Utils
  3. // @description R4 Utils Library
  4. // @version 1.0.1
  5. // ==/UserScript==
  6. function R4Utils() {
  7.  
  8. /* ------------------------------------------------- */
  9. /* --------------fromHTML--------------------------- */
  10. /* ------------------------------------------------- */
  11.  
  12. function fromHTML(html, trim = true) {
  13. // Process the HTML string.
  14. html = trim ? html : html.trim();
  15. if (!html) return null;
  16. // Then set up a new template element.
  17. const template = document.createElement('template');
  18. template.innerHTML = html;
  19. const result = template.content.children;
  20. // Then return either an HTMLElement or HTMLCollection,
  21. // based on whether the input HTML had one or more roots.
  22. if (result.length === 1) return result[0];
  23. return result;
  24. }
  25.  
  26. /* ------------------------------------------------- */
  27. /* --------------transliterate---------------------- */
  28. /* ------------------------------------------------- */
  29.  
  30. function transliterate(word) {
  31. let answer = "";
  32. const a = {};
  33.  
  34. a["Ё"] = "YO";
  35. a["Й"] = "I";
  36. a["Ц"] = "TS";
  37. a["У"] = "U";
  38. a["К"] = "K";
  39. a["Е"] = "E";
  40. a["Н"] = "N";
  41. a["Г"] = "G";
  42. a["Ш"] = "SH";
  43. a["Щ"] = "SCH";
  44. a["З"] = "Z";
  45. a["Х"] = "H";
  46. a["Ъ"] = "'";
  47. a["ё"] = "yo";
  48. a["й"] = "i";
  49. a["ц"] = "ts";
  50. a["у"] = "u";
  51. a["к"] = "k";
  52. a["е"] = "e";
  53. a["н"] = "n";
  54. a["г"] = "g";
  55. a["ш"] = "sh";
  56. a["щ"] = "sch";
  57. a["з"] = "z";
  58. a["х"] = "h";
  59. a["ъ"] = "'";
  60. a["Ф"] = "F";
  61. a["Ы"] = "I";
  62. a["В"] = "V";
  63. a["А"] = "A";
  64. a["П"] = "P";
  65. a["Р"] = "R";
  66. a["О"] = "O";
  67. a["Л"] = "L";
  68. a["Д"] = "D";
  69. a["Ж"] = "ZH";
  70. a["Э"] = "E";
  71. a["ф"] = "f";
  72. a["ы"] = "i";
  73. a["в"] = "v";
  74. a["а"] = "a";
  75. a["п"] = "p";
  76. a["р"] = "r";
  77. a["о"] = "o";
  78. a["л"] = "l";
  79. a["д"] = "d";
  80. a["ж"] = "zh";
  81. a["э"] = "e";
  82. a["Я"] = "Ya";
  83. a["Ч"] = "CH";
  84. a["С"] = "S";
  85. a["М"] = "M";
  86. a["И"] = "I";
  87. a["Т"] = "T";
  88. a["Ь"] = "'";
  89. a["Б"] = "B";
  90. a["Ю"] = "YU";
  91. a["я"] = "ya";
  92. a["ч"] = "ch";
  93. a["с"] = "s";
  94. a["м"] = "m";
  95. a["и"] = "i";
  96. a["т"] = "t";
  97. a["ь"] = "'";
  98. a["б"] = "b";
  99. a["ю"] = "yu";
  100.  
  101. for (const i in word) {
  102. if (word.hasOwnProperty(i)) {
  103. answer += a[word[i]] === undefined ? word[i] : a[word[i]];
  104. }
  105. }
  106. return answer;
  107. }
  108.  
  109. /* ------------------------------------------------- */
  110. /* --------------slugify---------------------------- */
  111. /* ------------------------------------------------- */
  112.  
  113. function slugify(str) {
  114. return String(str)
  115. .normalize("NFKD") // split accented characters into their base characters and diacritical marks
  116. .replace(/[\u0300-\u036f]/g, "") // remove all the accents, which happen to be all in the \u03xx UNICODE block.
  117. .trim() // trim leading or trailing whitespace
  118. .toLowerCase() // convert to lowercase
  119. .replace(/[^a-z0-9 -]/g, "") // remove non-alphanumeric characters
  120. .replace(/\s+/g, "-") // replace spaces with hyphens
  121. .replace(/-+/g, "-"); // remove consecutive hyphens
  122. }
  123.  
  124. /* ------------------------------------------------- */
  125. /* --------------executeLocation-------------------- */
  126. /* ------------------------------------------------- */
  127.  
  128. class AsyncLock {
  129. constructor () {
  130. this.release = () => {}
  131. this.promise = Promise.resolve()
  132. }
  133. acquire () {
  134. this.promise = new Promise(resolve => this.release = resolve)
  135. }
  136. }
  137.  
  138. const execute_location_lock = new AsyncLock();
  139.  
  140. function executeLocation(func, vars = {}, prefix = "ExecuteLocation", lock = execute_location_lock) {
  141. return new Promise((resolve, reject) => {
  142.  
  143. // Wait for the lock to be released
  144. lock.promise.then(() => {
  145.  
  146. // Acquire the lock
  147. lock.acquire();
  148.  
  149. try {
  150. // Convert the function to a string of code
  151. const funcString = `(${func.toString()})()`;
  152.  
  153. // Define a new CustomEvent that will be dispatched when the function finishes executing
  154. const eventName = prefix + Math.random().toString(36).substring(7);
  155.  
  156. // Listen for the function executed event
  157. document.addEventListener(eventName, (event) => {
  158.  
  159. resolve(event.detail.result);
  160.  
  161. // Release the lock
  162. lock.release();
  163. });
  164.  
  165. // Convert the vars object to a string of code that defines these variables
  166. const varsString = Object.entries(vars).map(([name, value]) => {
  167. return `var ${name} = ${JSON.stringify(value)};`;
  168. }).join('');
  169.  
  170. // Use location.assign to execute the function in the global scope
  171. // The function result is sent as a CustomEvent
  172. location.assign(`javascript:(function() {
  173. ${varsString}
  174. const result = ${funcString};
  175. const event = new CustomEvent('${eventName}', { detail: { result: result } });
  176. document.dispatchEvent(event);
  177. })();void(0)`);
  178. } catch (e) {
  179. reject(e);
  180.  
  181. // Release the lock in case of an error
  182. lock.release();
  183.  
  184. }
  185. });
  186. });
  187. }
  188.  
  189. return {
  190. fromHTML,
  191. transliterate,
  192. slugify,
  193. executeLocation,
  194. };
  195. }