- // ==UserScript==
- // @name InjectJS
- // @namespace http://github.com/YTXaos/InjectJS
- // @version 1.30
- // @description Inject Javascript into almost any website.
- // @description:es Inyecte Javascript en casi cualquier sitio web
- // @description:fr Injectez Javascript dans presque tous les sites Web
- // @description:de Fügen Sie Javascript in fast jede Website ein
- // @description:ja ほぼすべてのウェブサイトにジャバスクリとを挿入する
- // @description:la Javascript in inject paene omnem website
- // @description:ru Внедрите Javascript практически в любой веб-сайт
- // @author YTXaos
- // @match *://*/*
- // @match file:///*
- // @icon https://raw.githubusercontent.com/YTXaos/InjectJS/main/assets/logo.png
- // @grant GM_addElement
- // @grant GM_getResourceText
- // @grant GM_getResourceURL
- // @license MIT
- // @require https://code.jquery.com/jquery-3.6.0.min.js
- // @resource MainCSS https://raw.githubusercontent.com/YTXaos/InjectJS/main/assets/main.css
- // @resource OptionsHTML https://raw.githubusercontent.com/YTXaos/InjectJS/main/pages/options.html
- // @resource OptionsJS https://raw.githubusercontent.com/YTXaos/InjectJS/main/options.js
- // @resource Fontawesome https://raw.githubusercontent.com/YTXaos/InjectJS/main/assets/fontawesome.css
- // @resource MainIcon https://raw.githubusercontent.com/YTXaos/InjectJS/main/assets/logov2.png
- // ==/UserScript==
-
- (function() {
- "use strict";
- const url = location.href,
- origin = location.origin;
- /**
- * @param {string} item Specify what item to look for in the options.
- * @returns {string} True or false if found, false boolean if not.
- */
- function Option(item) {
- if(localStorage.getItem(`inject-js:${item}`)) {
- return localStorage.getItem(`inject-js:${item}`).toString();
- } else {
- return false;
- }
- }
- /**
- * Create a log node.
- * @param {string} type The type of log to create.
- * @param {string} msg The message to output in the logs.
- */
- function createLog(type, msg) {
- const elm = document.querySelector(".js-injector-logs");
- let msg_type;
- type === "warning" && (msg_type = "WARN") || (msg_type = type.toUpperCase());
- elm.innerHTML += `
- <div class="js-log ${type}">
- [InjectJS <span class="time-date"></span> ${msg_type}]:
- <span class="js-log-message">
- ${msg}
- </span>
- </div>`;
- }
- const logs = {
- info(msg) { createLog("info", msg); },
- warn(msg) { createLog("warning", msg); },
- error(msg) { createLog("error", msg); }
- }
- /**
- * Check whether the page the user is on is equivalent to param "page".
- * @param {string} page Specify what URL to check for.
- * @param {boolean} exact Whether it should check for the exact URL or relative.
- * @returns {boolean} True or false
- */
- function onURL(page, exact) {
- if(exact) {
- return url === `${origin}${page}`;
- } else {
- return url.includes(page);
- }
- }
- if(Option("disable") == "true") {
- document.addEventListener("keyup", function(e) {
- e.preventDefault();
- if(e.ctrlKey && e.key === ".") {
- localStorage.setItem("inject-js:disable", false);
- location.reload();
- }
- });
- return;
- }
- if(onURL("/inject-js/", true)) {
- location = "https://github.com/YTXaos/InjectJS";
- }
- Option("startup_log") == "true" && (console.info("InjectJS Loaded. Press Ctrl + Q to topen"));
- const popup = document.createElement("div"),
- log = document.createElement("div");
- GM_addElement(document.head, "style", { textContent: GM_getResourceText("MainCSS") });
- log.setAttribute("class", "js-injector-logs");
- log.innerHTML = '<span class="js-logs-close" title="Close" id="js-close">×</span>';
- log.style.display = "none";
- popup.setAttribute("class", "js-injector-popup");
- popup.style.display = "none";
- popup.innerHTML = `<label class="js-inject-header">
- <div class="js-logo-needle" style="background-image: url(${GM_getResourceURL("MainIcon")})">.....</div>
- Inject<span class="js-logo">JS</span>
- </label>
- <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>
- <div class="js-btns-section">
- <button class="execute-code" disabled>Execute</button>
- <button class="js-options-btn">Options</button>
- </div>
- <div class="js-btns-column">
- <button class="show-js-logs">Logs</button>
- </div>`;
- document.body.append(log);
- document.body.prepend(popup);
-
- function OptionsPage() {
- $("link[rel=stylesheet], style, script").remove();
- document.title = "InjectJS Options";
- document.body.innerHTML = GM_getResourceText("OptionsHTML");
- GM_addElement(document.head, "script", { textContent: GM_getResourceText("OptionsJS") });
- }
- const code = document.querySelector(".js-code-inject"),
- btn = document.querySelector(".execute-code"), option_btn = document.querySelector(".js-options-btn"), log_btn = document.querySelector(".show-js-logs");
- code.addEventListener("input", CheckCode);
- log_btn.addEventListener("click", function() {
- document.querySelector(".js-injector-logs").setAttribute("style", "display: flex !important");
- document.getElementById("js-close").addEventListener("click", function() {
- document.querySelector(".js-injector-logs").setAttribute("style", "");
- });
- });
- if(Option("disable_syntax") != "true") { code.addEventListener("keydown", Syntax); }
- btn.addEventListener("click", InjectCode);
- option_btn.addEventListener("click", () => { location = "/inject-js/options"; });
- /**
- * Syntax properties for autocomplete "(", "{", and strings.
- * @param {event} e Returns an event to handle accordingly.
- */
- function Syntax(e) {
- if(e.key === "{") {
- e.preventDefault();
- const start = code.selectionStart,
- end = code.selectionEnd,
- selection = code.value.substring(start, end),
- replace = `${code.value.substring(0, start)}{\n${selection}\n}${code.value.substring(end)}`;
- code.value = replace;
- code.focus();
- code.selectionEnd = end + 2;
- }
- if(e.key === "(") {
- e.preventDefault();
- const start = code.selectionStart,
- end = code.selectionEnd,
- selection = code.value.substring(start, end),
- replace = `${code.value.substring(0, start)}(${selection})${code.value.substring(end)}`;
- code.value = replace;
- code.focus();
- code.selectionEnd = end + 1;
- }
- if(e.which === 222) {
- e.preventDefault();
- const start = code.selectionStart,
- end = code.selectionEnd,
- selection = code.value.substring(start, end),
- replace = `${code.value.substring(0, start)}${e.key}${selection}${e.key}${code.value.substring(end)}`;
- code.value = replace;
- code.focus();
- code.selectionEnd = end + 1;
- }
- }
- function CheckCode() {
- const code = document.querySelector(".js-code-inject");
- if(code.value.length < 5) {
- btn.setAttribute("disabled", "disabled");
- } else {
- btn.removeAttribute("disabled");
- }
- }
-
- function InjectCode() {
- try {
- eval(code.value);
- } catch (e) {
- if(Option("alert_errors") == "true") {
- alert(e.message);
- } else {
- logs.error(e);
- }
- }
- }
-
- function ShowInjector() {
- dragElement(document.querySelector(".js-injector-popup"));
- /**
- * Makes an elemenet draggable around the screen.
- * @param {string} elmnt Select an element from the DOM to become draggable
- */
- function dragElement(elmnt) {
- var pos1 = 0,
- pos2 = 0,
- pos3 = 0,
- pos4 = 0;
- if(document.querySelector(".js-inject-header")) {
- document.querySelector(".js-inject-header").onmousedown = dragMouseDown;
- } else {
- elmnt.onmousedown = dragMouseDown;
- }
-
- function dragMouseDown(e) {
- e = e || window.event;
- e.preventDefault();
- pos3 = e.clientX;
- pos4 = e.clientY;
- document.onmouseup = closeDragElement;
- document.onmousemove = elementDrag;
- }
-
- function elementDrag(e) {
- e = e || window.event;
- e.preventDefault();
- pos1 = pos3 - e.clientX;
- pos2 = pos4 - e.clientY;
- pos3 = e.clientX;
- pos4 = e.clientY;
- elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
- elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
- }
-
- function closeDragElement() {
- document.onmouseup = null;
- document.onmousemove = null;
- }
- }
- popup.classList.toggle("show");
- }
- if(onURL("/inject-js/options", true)) {
- OptionsPage();
- }
- document.addEventListener("keyup", function(e) {
- e.preventDefault();
- if(e.ctrlKey && e.key === "q") {
- ShowInjector();
- }
- });
- })();