Greasy Fork is available in English.

InjectJS

Inject Javascript into almost any website.

  1. // ==UserScript==
  2. // @name InjectJS
  3. // @namespace http://github.com/YTXaos/InjectJS
  4. // @version 1.30
  5. // @description Inject Javascript into almost any website.
  6. // @description:es Inyecte Javascript en casi cualquier sitio web
  7. // @description:fr Injectez Javascript dans presque tous les sites Web
  8. // @description:de Fügen Sie Javascript in fast jede Website ein
  9. // @description:ja ほぼすべてのウェブサイトにジャバスクリとを挿入する
  10. // @description:la Javascript in inject paene omnem website
  11. // @description:ru Внедрите Javascript практически в любой веб-сайт
  12. // @author YTXaos
  13. // @match *://*/*
  14. // @match file:///*
  15. // @icon https://raw.githubusercontent.com/YTXaos/InjectJS/main/assets/logo.png
  16. // @grant GM_addElement
  17. // @grant GM_getResourceText
  18. // @grant GM_getResourceURL
  19. // @license MIT
  20. // @require https://code.jquery.com/jquery-3.6.0.min.js
  21. // @resource MainCSS https://raw.githubusercontent.com/YTXaos/InjectJS/main/assets/main.css
  22. // @resource OptionsHTML https://raw.githubusercontent.com/YTXaos/InjectJS/main/pages/options.html
  23. // @resource OptionsJS https://raw.githubusercontent.com/YTXaos/InjectJS/main/options.js
  24. // @resource Fontawesome https://raw.githubusercontent.com/YTXaos/InjectJS/main/assets/fontawesome.css
  25. // @resource MainIcon https://raw.githubusercontent.com/YTXaos/InjectJS/main/assets/logov2.png
  26. // ==/UserScript==
  27.  
  28. (function() {
  29. "use strict";
  30. const url = location.href,
  31. origin = location.origin;
  32. /**
  33. * @param {string} item Specify what item to look for in the options.
  34. * @returns {string} True or false if found, false boolean if not.
  35. */
  36. function Option(item) {
  37. if(localStorage.getItem(`inject-js:${item}`)) {
  38. return localStorage.getItem(`inject-js:${item}`).toString();
  39. } else {
  40. return false;
  41. }
  42. }
  43. /**
  44. * Create a log node.
  45. * @param {string} type The type of log to create.
  46. * @param {string} msg The message to output in the logs.
  47. */
  48. function createLog(type, msg) {
  49. const elm = document.querySelector(".js-injector-logs");
  50. let msg_type;
  51. type === "warning" && (msg_type = "WARN") || (msg_type = type.toUpperCase());
  52. elm.innerHTML += `
  53. <div class="js-log ${type}">
  54. [InjectJS&nbsp;<span class="time-date"></span>&nbsp;${msg_type}]:&nbsp;
  55. <span class="js-log-message">
  56. ${msg}
  57. </span>
  58. </div>`;
  59. }
  60. const logs = {
  61. info(msg) { createLog("info", msg); },
  62. warn(msg) { createLog("warning", msg); },
  63. error(msg) { createLog("error", msg); }
  64. }
  65. /**
  66. * Check whether the page the user is on is equivalent to param "page".
  67. * @param {string} page Specify what URL to check for.
  68. * @param {boolean} exact Whether it should check for the exact URL or relative.
  69. * @returns {boolean} True or false
  70. */
  71. function onURL(page, exact) {
  72. if(exact) {
  73. return url === `${origin}${page}`;
  74. } else {
  75. return url.includes(page);
  76. }
  77. }
  78. if(Option("disable") == "true") {
  79. document.addEventListener("keyup", function(e) {
  80. e.preventDefault();
  81. if(e.ctrlKey && e.key === ".") {
  82. localStorage.setItem("inject-js:disable", false);
  83. location.reload();
  84. }
  85. });
  86. return;
  87. }
  88. if(onURL("/inject-js/", true)) {
  89. location = "https://github.com/YTXaos/InjectJS";
  90. }
  91. Option("startup_log") == "true" && (console.info("InjectJS Loaded. Press Ctrl + Q to topen"));
  92. const popup = document.createElement("div"),
  93. log = document.createElement("div");
  94. GM_addElement(document.head, "style", { textContent: GM_getResourceText("MainCSS") });
  95. log.setAttribute("class", "js-injector-logs");
  96. log.innerHTML = '<span class="js-logs-close" title="Close" id="js-close">&times;</span>';
  97. log.style.display = "none";
  98. popup.setAttribute("class", "js-injector-popup");
  99. popup.style.display = "none";
  100. popup.innerHTML = `<label class="js-inject-header">
  101. <div class="js-logo-needle" style="background-image: url(${GM_getResourceURL("MainIcon")})">.....</div>
  102. Inject<span class="js-logo">JS</span>
  103. </label>
  104. <textarea placeholder="Your code here" class="js-code-inject" spellcheck="false" data-gramm="false" data-gramm_editor="false" data-enable-grammarly="false" id="js-code-inject"></textarea>
  105. <div class="js-btns-section">
  106. <button class="execute-code" disabled>Execute</button>
  107. <button class="js-options-btn">Options</button>
  108. </div>
  109. <div class="js-btns-column">
  110. <button class="show-js-logs">Logs</button>
  111. </div>`;
  112. document.body.append(log);
  113. document.body.prepend(popup);
  114.  
  115. function OptionsPage() {
  116. $("link[rel=stylesheet], style, script").remove();
  117. document.title = "InjectJS Options";
  118. document.body.innerHTML = GM_getResourceText("OptionsHTML");
  119. GM_addElement(document.head, "script", { textContent: GM_getResourceText("OptionsJS") });
  120. }
  121. const code = document.querySelector(".js-code-inject"),
  122. btn = document.querySelector(".execute-code"), option_btn = document.querySelector(".js-options-btn"), log_btn = document.querySelector(".show-js-logs");
  123. code.addEventListener("input", CheckCode);
  124. log_btn.addEventListener("click", function() {
  125. document.querySelector(".js-injector-logs").setAttribute("style", "display: flex !important");
  126. document.getElementById("js-close").addEventListener("click", function() {
  127. document.querySelector(".js-injector-logs").setAttribute("style", "");
  128. });
  129. });
  130. if(Option("disable_syntax") != "true") { code.addEventListener("keydown", Syntax); }
  131. btn.addEventListener("click", InjectCode);
  132. option_btn.addEventListener("click", () => { location = "/inject-js/options"; });
  133. /**
  134. * Syntax properties for autocomplete "(", "{", and strings.
  135. * @param {event} e Returns an event to handle accordingly.
  136. */
  137. function Syntax(e) {
  138. if(e.key === "{") {
  139. e.preventDefault();
  140. const start = code.selectionStart,
  141. end = code.selectionEnd,
  142. selection = code.value.substring(start, end),
  143. replace = `${code.value.substring(0, start)}{\n${selection}\n}${code.value.substring(end)}`;
  144. code.value = replace;
  145. code.focus();
  146. code.selectionEnd = end + 2;
  147. }
  148. if(e.key === "(") {
  149. e.preventDefault();
  150. const start = code.selectionStart,
  151. end = code.selectionEnd,
  152. selection = code.value.substring(start, end),
  153. replace = `${code.value.substring(0, start)}(${selection})${code.value.substring(end)}`;
  154. code.value = replace;
  155. code.focus();
  156. code.selectionEnd = end + 1;
  157. }
  158. if(e.which === 222) {
  159. e.preventDefault();
  160. const start = code.selectionStart,
  161. end = code.selectionEnd,
  162. selection = code.value.substring(start, end),
  163. replace = `${code.value.substring(0, start)}${e.key}${selection}${e.key}${code.value.substring(end)}`;
  164. code.value = replace;
  165. code.focus();
  166. code.selectionEnd = end + 1;
  167. }
  168. }
  169. function CheckCode() {
  170. const code = document.querySelector(".js-code-inject");
  171. if(code.value.length < 5) {
  172. btn.setAttribute("disabled", "disabled");
  173. } else {
  174. btn.removeAttribute("disabled");
  175. }
  176. }
  177.  
  178. function InjectCode() {
  179. try {
  180. eval(code.value);
  181. } catch (e) {
  182. if(Option("alert_errors") == "true") {
  183. alert(e.message);
  184. } else {
  185. logs.error(e);
  186. }
  187. }
  188. }
  189.  
  190. function ShowInjector() {
  191. dragElement(document.querySelector(".js-injector-popup"));
  192. /**
  193. * Makes an elemenet draggable around the screen.
  194. * @param {string} elmnt Select an element from the DOM to become draggable
  195. */
  196. function dragElement(elmnt) {
  197. var pos1 = 0,
  198. pos2 = 0,
  199. pos3 = 0,
  200. pos4 = 0;
  201. if(document.querySelector(".js-inject-header")) {
  202. document.querySelector(".js-inject-header").onmousedown = dragMouseDown;
  203. } else {
  204. elmnt.onmousedown = dragMouseDown;
  205. }
  206.  
  207. function dragMouseDown(e) {
  208. e = e || window.event;
  209. e.preventDefault();
  210. pos3 = e.clientX;
  211. pos4 = e.clientY;
  212. document.onmouseup = closeDragElement;
  213. document.onmousemove = elementDrag;
  214. }
  215.  
  216. function elementDrag(e) {
  217. e = e || window.event;
  218. e.preventDefault();
  219. pos1 = pos3 - e.clientX;
  220. pos2 = pos4 - e.clientY;
  221. pos3 = e.clientX;
  222. pos4 = e.clientY;
  223. elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
  224. elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
  225. }
  226.  
  227. function closeDragElement() {
  228. document.onmouseup = null;
  229. document.onmousemove = null;
  230. }
  231. }
  232. popup.classList.toggle("show");
  233. }
  234. if(onURL("/inject-js/options", true)) {
  235. OptionsPage();
  236. }
  237. document.addEventListener("keyup", function(e) {
  238. e.preventDefault();
  239. if(e.ctrlKey && e.key === "q") {
  240. ShowInjector();
  241. }
  242. });
  243. })();