Внедрите Javascript практически в любой веб-сайт
// ==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(); } }); })();