Draft Tools

Adds useful features to Cracked.io's new-thread page.

目前为 2023-04-14 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/464022/1175809/Draft%20Tools.js

  1. // ==UserScript==
  2. // @name Draft Tools
  3. // @namespace https://leaked.wiki
  4. // @version 2
  5. // @description Adds useful features to Cracked.io's new-thread page.
  6. // @author Sango
  7. // @match *://cracked.io/newthread.php?fid=*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=cracked.io
  9. // @grant none
  10. // @updateURL https://greasyfork.org/scripts/464022-draft-tools/code/Draft%20Tools.js
  11. // @downloadURL https://greasyfork.org/scripts/464022-draft-tools/code/Draft%20Tools.js
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16. document.querySelector("html").insertAdjacentHTML("beforeend", `
  17. <div id="DraftInput" class="modal" style="display:none;">
  18. <table>
  19. <tbody id="draft_inputs">
  20. </tbody>
  21. </table>
  22. </div>
  23.  
  24. <div id="Sango" class="modal" style="display:none;">
  25. <div class="tborder" style="width:500px">
  26. <div class="thead">
  27. <strong>Your Draft Templates</strong>
  28. </div>
  29. </div>
  30. </div>
  31. <style>.cke_bottom{display: block;}</style>
  32. `);
  33.  
  34. var src = `
  35. var message = ""; var title = ""; var matches = [];
  36. function show_modal(e) {
  37. message = e.closest("#Sango .trow1").querySelector(".message_plain").textContent;
  38. console.log(message);
  39. title = e.closest("#Sango .trow1").querySelector('.message_title').textContent;
  40. matches = (title+message).match(/(?<=\{)([A-Za-z0-9_]*?)(?=\})/gm);
  41. matches = [...new Set(matches)];
  42. document.querySelector('#draft_inputs').innerHTML = '<tr><td class="thead"><strong>Draft Text Input</strong></td></tr>';
  43. for (const match of matches) {
  44. document.querySelector('#draft_inputs').innerHTML += '<tr><td class="trow1"><input type="text" id="'+match+'" class="textbox" placeholder="'+match.replace(/_/g, " ")+'"/></td></tr>';
  45. }
  46. document.querySelector('#draft_inputs').innerHTML += '<tr><td class="trow1" style="text-align: center;"><a href="#close-modal" rel="modal:close""><input type="button" class="button" value="Inject" onclick="inject()"></td></a></td></tr>';
  47. $("#DraftInput").modal({ keepelement: !0 });
  48. return false;
  49. };
  50.  
  51. function show_preview(e) {
  52. var id = e.closest("#Sango .trow1").id;
  53. document.querySelectorAll('#Sango .trow1:not(#'+id+') .message_preview').forEach(function(preview) {
  54. preview.style.display = "none";
  55. });
  56. $('#Sango .trow1#'+id+' .message_preview').toggle();
  57. return false;
  58. };
  59.  
  60. function inject() {
  61. document.querySelectorAll('#draft_inputs input[type="text"]').forEach(function(input) {
  62. var matchID = input.id;
  63. var matchVal = input.value;
  64. var regex = "{"+matchID+"}";
  65. regex = new RegExp(regex,'gm');
  66. message=message.replace(regex, matchVal);
  67. title=title.replace(regex, matchVal);
  68. });
  69. // apply gradients
  70. message = processGradientInput(message);
  71. var source_mode = false;
  72. if (!document.querySelector('textarea.cke_source')) {
  73. source_mode = true;
  74. document.querySelector(".cke_button__source").click();
  75. }
  76. var message_val = document.querySelector('textarea.cke_source').value || "";
  77. document.querySelector('textarea.cke_source').value = message_val+' '+message;
  78. document.querySelector('input[name=subject]').value = title;
  79. if (source_mode === true) {
  80. setTimeout(function() {
  81. document.querySelector(".cke_button__source").click();
  82. }, 100);
  83. }
  84. }
  85.  
  86. function bbGradient(text, colors) {
  87. var output = "";
  88. var rainbow = ['#FF2323', '#FF23F2', '#A133FF', '#326CFF', '#23EDFF', '#23FFA4', '#23FF23', '#FFF723', '#FF8B23'];
  89. if (colors === "rainbow") colors = rainbow;
  90. colors = colors.map(color => (color === 'random' ? rainbow[Math.floor(Math.random() * rainbow.length)] : (!color.startsWith("#") ? '#'+color : color)));
  91. var colorCount = colors.length;
  92. var colorIncrement = 1 / (colorCount - 1);
  93. var textLength = text.length;
  94. for (var i = 0; i < textLength; i++) {
  95. var colorIndex = Math.floor(i * (colorCount - 1) / textLength);
  96. var colorPercent = (i * (colorCount - 1) / textLength) % 1;
  97. var colorStart = colors[colorIndex];
  98. var colorEnd = colors[colorIndex + 1] || colorStart;
  99. var color = lerpColor(colorStart, colorEnd, colorPercent);
  100. output += "[color=" + color + "]" + text.charAt(i) + "[/color]";
  101. }
  102. return output;
  103. }
  104.  
  105. function lerpColor(color1, color2, percent) {
  106. var validHex = /^#([0-9A-F]{3}){1,2}$/i;
  107. if (!validHex.test(color1)) color1 = "#FFFFFF";
  108. if (!validHex.test(color2)) color2 = "#FFFFFF";
  109.  
  110. var r1 = parseInt(color1.substring(1, 3), 16);
  111. var g1 = parseInt(color1.substring(3, 5), 16);
  112. var b1 = parseInt(color1.substring(5, 7), 16);
  113. var r2 = parseInt(color2.substring(1, 3), 16);
  114. var g2 = parseInt(color2.substring(3, 5), 16);
  115. var b2 = parseInt(color2.substring(5, 7), 16);
  116. var r = Math.round((1 - percent) * r1 + percent * r2).toString(16);
  117. var g = Math.round((1 - percent) * g1 + percent * g2).toString(16);
  118. var b = Math.round((1 - percent) * b1 + percent * b2).toString(16);
  119. return "#" + padZero(r) + padZero(g) + padZero(b);
  120. }
  121.  
  122. function padZero(str) {
  123. return str.length == 1 ? "0" + str : str;
  124. }
  125.  
  126. function processGradientInput(input) {
  127. const regex = /\\[gradient(?:=(rainbow|.*?))?\\](.+?)\\[\\/gradient\\]/gm;
  128. let match = regex.exec(input);
  129. while (match != null) {
  130. console.log(match);
  131. let colors = [];
  132. let text = match[2];
  133. if (!Boolean(match[1])) {
  134. colors = ["random", "random", "random"];
  135. } else if (match[1] === 'rainbow') {
  136. colors = "rainbow";
  137. } else {
  138. colors = match[1].split(',').map(color=>color.trim())
  139. }
  140. text = bbGradient(text, colors);
  141. input = input.replace(match[0], text);
  142. match = regex.exec(input);
  143. }
  144. return input;
  145. }
  146.  
  147. var xhr = new XMLHttpRequest();
  148. xhr.open('GET', 'https://cracked.io/usercp2.php?action=get_templates', true);
  149. xhr.onload = function() {
  150. if (xhr.readyState === xhr.DONE) {
  151. if (xhr.status === 200) {
  152. var data = xhr.responseText;
  153. var parser = new DOMParser();
  154. var doc = parser.parseFromString(data, 'text/html');
  155. var rows = doc.querySelectorAll('.trow1');
  156. var sangoDiv = document.querySelector('#Sango > .tborder');
  157. rows.forEach(function(row) {
  158. row.querySelector('span.insert_link').setAttribute('onclick', 'show_modal(this)');
  159. row.querySelector('span.preview_link').setAttribute('onclick', 'show_preview(this)');
  160. sangoDiv.appendChild(row);
  161. });
  162. } else { alert("Draft Tools Error: Failed to retreive templates."); }
  163. }
  164. };
  165. xhr.send(null);
  166. `;
  167. const script = document.createElement('script');
  168. script.textContent = src;
  169. document.body.appendChild(script);
  170.  
  171. document.querySelector("a[title='Drafts Templates']").setAttribute("rel", "");
  172. document.querySelector("a[title='Drafts Templates']").setAttribute("onclick", "$('#Sango').modal({ keepelement: !0 });return false;");
  173. })();