Greasy Fork is available in English.

Multi Profile AutoFill Script

Multi-profile autofill with draggable panel, collapsible menu, merge import, bulk edit

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

/* jshint esversion: 8 */
// ==UserScript==
// @name         Multi Profile AutoFill Script
// @namespace    http://tampermonkey.net/
// @version      6.1
// @description  Multi-profile autofill with draggable panel, collapsible menu, merge import, bulk edit
// @match        *://*/*
// @grant        GM_getValue
// @grant        GM_setValue
// @license      MIT
// ==/UserScript==

/*
MIT License with No Liability
Copyright (c) 2026 Shariar

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The software is provided "as is", without warranty of any kind, express or
implied, including but not limited to the warranties of merchantability,
fitness for a particular purpose, or non-infringement. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability, whether in an action of contract, tort, or otherwise, arising
from, out of, or in connection with the software or the use or other dealings
in the software.
*/

/*
⚠️ DISCLAIMER:
This script is for personal use to automate form-filling.
The author (Shariar) is not responsible for any misuse or damages
resulting from the use of this script.
Do not use for illegal activity.
*/

(async function () {
    'use strict';

    const STORAGE_KEY = "TM_Global_AutoFill_Profiles";
    const defaultProfiles = { "Default": {} };

    // ===== Load profiles globally =====
    async function loadProfiles() {
        const data = await GM_getValue(STORAGE_KEY, "{}");
        return Object.keys(JSON.parse(data)).length ? JSON.parse(data) : defaultProfiles;
    }

    // ===== Save profiles globally =====
    function saveProfiles(data) {
        GM_setValue(STORAGE_KEY, JSON.stringify(data));
    }

    // ===== Initialize profiles inside async function =====
    let profiles = await loadProfiles();
    let currentProfile = Object.keys(profiles)[0];

    // ===== Get Unique Key =====
    function getKey(el) {
        return el.name || el.id || el.placeholder || null;
    }

    // ===== Fill Form =====
    function fillForm() {
        const elements = document.querySelectorAll("input, textarea, select");
        elements.forEach(el => {
            const key = getKey(el);
            if (!key) return;
            const value = profiles[currentProfile][key];
            if (el.type === "checkbox") el.checked = !!value;
            else if (el.type === "radio") { if (value === el.value) el.checked = true; }
            else { if (value !== undefined) el.value = value; }
            el.dispatchEvent(new Event("input", { bubbles: true }));
            el.dispatchEvent(new Event("change", { bubbles: true }));
        });
    }

    // ===== Save From Page =====
    function saveFromPage() {
        const elements = document.querySelectorAll("input, textarea, select");
        elements.forEach(el => {
            const key = getKey(el);
            if (!key) return;
            if (el.type === "checkbox") profiles[currentProfile][key] = el.checked;
            else if (el.type === "radio") { if (el.checked) profiles[currentProfile][key] = el.value; }
            else profiles[currentProfile][key] = el.value;
        });
        saveProfiles(profiles);
        alert(`✅ Data saved to profile: ${currentProfile}`);
    }

    // ===== UI =====
    const panel = document.createElement("div");
    panel.style.position = "fixed";
    panel.style.bottom = "20px";
    panel.style.right = "20px";
    panel.style.background = "#222";
    panel.style.color = "#fff";
    panel.style.padding = "12px";
    panel.style.borderRadius = "8px";
    panel.style.zIndex = "9999";
    panel.style.width = "240px";
    panel.style.fontSize = "13px";

    panel.innerHTML = `
        <b>⚡ AutoFill</b><br><br>
        <select id="profileSelect" style="width:100%; margin-bottom:6px;"></select>
        <button id="fillBtn" style="width:100%; margin-bottom:5px;">Fill</button>
        <button id="saveBtn" style="width:100%; margin-bottom:5px;">Save From Page</button>
        <button id="addBtn" style="width:100%; margin-bottom:5px;">Add Profile</button>
        <button id="editBtn" style="width:100%; margin-bottom:5px;">Edit Profile</button>
        <button id="deleteBtn" style="width:100%; margin-bottom:5px;">Delete</button>
        <button id="logBtn" style="width:100%; margin-bottom:5px;">Log Profiles</button>
        <button id="exportBtn" style="width:100%; margin-bottom:5px;">Export Profiles</button>
        <button id="importBtn" style="width:100%;">Import Profiles</button>
        <input type="file" id="importFile" style="display:none;" accept=".json"/>
    `;

    document.body.appendChild(panel);

    // ===== Draggable panel =====
    let isDragging = false, offsetX = 0, offsetY = 0;
    panel.addEventListener("mousedown", (e) => {
        if (!["BUTTON", "SELECT", "INPUT", "TEXTAREA"].includes(e.target.tagName)) {
            isDragging = true;
            offsetX = e.clientX - panel.offsetLeft;
            offsetY = e.clientY - panel.offsetTop;
        }
    });
    document.addEventListener("mousemove", (e) => {
        if (isDragging) {
            panel.style.left = e.clientX - offsetX + "px";
            panel.style.top = e.clientY - offsetY + "px";
            panel.style.bottom = "auto";
            panel.style.right = "auto";
        }
    });
    document.addEventListener("mouseup", () => { isDragging = false; });

    // ===== Toggle collapsed menu button =====
    const toggleButton = document.createElement("button");
    toggleButton.innerHTML = "⚡ AutoFill";
    toggleButton.style.position = "fixed";
    toggleButton.style.bottom = "20px";
    toggleButton.style.right = "20px";
    toggleButton.style.zIndex = "9999";
    toggleButton.style.padding = "6px 10px";
    toggleButton.style.borderRadius = "6px";
    toggleButton.style.background = "#222";
    toggleButton.style.color = "#fff";
    toggleButton.style.cursor = "pointer";
    toggleButton.style.fontSize = "13px";
    document.body.appendChild(toggleButton);

    panel.style.display = "none"; // hide initially
    toggleButton.onclick = () => {
        panel.style.display = (panel.style.display === "none") ? "block" : "none";
    };
    document.addEventListener("click", (e) => {
        if (!panel.contains(e.target) && e.target !== toggleButton) {
            panel.style.display = "none";
        }
    });

    const profileSelect = document.getElementById("profileSelect");
    function refreshDropdown() {
        profileSelect.innerHTML = "";
        Object.keys(profiles).forEach(name => {
            const opt = document.createElement("option");
            opt.value = name;
            opt.textContent = name;
            profileSelect.appendChild(opt);
        });
        profileSelect.value = currentProfile;
    }
    refreshDropdown();
    profileSelect.onchange = function () { currentProfile = this.value; };

    // ===== Button Handlers =====
    document.getElementById("fillBtn").onclick = fillForm;
    document.getElementById("saveBtn").onclick = saveFromPage;
    document.getElementById("addBtn").onclick = () => {
        const name = prompt("Profile Name:");
        if (!name) return;
        profiles[name] = {};
        saveProfiles(profiles);
        currentProfile = name;
        refreshDropdown();
    };

    // ===== Edit Profile (Bulk Edit + Rename) =====
    document.getElementById("editBtn").onclick = () => {
        if (!currentProfile) return;
        const newName = prompt("Rename profile (leave blank to keep same):", currentProfile);
        if (newName && newName !== currentProfile) {
            profiles[newName] = profiles[currentProfile];
            delete profiles[currentProfile];
            currentProfile = newName;
        }
        const fields = profiles[currentProfile];
        let text = Object.entries(fields).map(([k,v]) => `${k}=${v}`).join("\n");
        const newText = prompt("Edit all fields (one per line: key=value):", text);
        if (newText !== null) {
            const newFields = {};
            newText.split("\n").forEach(line => {
                const [key, ...rest] = line.split("=");
                if (key) newFields[key.trim()] = rest.join("=").trim();
            });
            profiles[currentProfile] = newFields;
        }
        saveProfiles(profiles);
        refreshDropdown();
        alert(`✅ Profile "${currentProfile}" updated!`);
    };

    document.getElementById("deleteBtn").onclick = () => {
        if (Object.keys(profiles).length <= 1) {
            alert("At least one profile required!");
            return;
        }
        if (confirm("Delete this profile?")) {
            delete profiles[currentProfile];
            saveProfiles(profiles);
            currentProfile = Object.keys(profiles)[0];
            refreshDropdown();
        }
    };

    document.getElementById("logBtn").onclick = () => {
        console.log("📋 All Saved Profiles:", profiles);
        alert("✅ Profiles logged to console!");
    };

    // ===== Export & Import (Merge Import) =====
    const importFile = document.getElementById("importFile");
    document.getElementById("exportBtn").onclick = () => {
        const blob = new Blob([JSON.stringify(profiles, null, 2)], { type: "application/json" });
        const link = document.createElement("a");
        link.href = URL.createObjectURL(blob);
        link.download = "autofill_profiles_backup.json";
        link.click();
        alert("✅ Profiles exported!");
    };
    document.getElementById("importBtn").onclick = () => { importFile.click(); };
    importFile.onchange = function () {
        const file = this.files[0];
        if (!file) return;
        const reader = new FileReader();
        reader.onload = function (e) {
            try {
                const importedProfiles = JSON.parse(e.target.result);
                Object.keys(importedProfiles).forEach(name => { profiles[name] = importedProfiles[name]; });
                saveProfiles(profiles);
                currentProfile = Object.keys(profiles)[0];
                refreshDropdown();
                alert("✅ Profiles imported successfully (merged)!");
            } catch (err) {
                alert("❌ Invalid JSON file!");
            }
        };
        reader.readAsText(file);
    };

})();