Here is a Handy Tool for Edge / Chrome. It removes readonly, disabled fields toggles contenteditable Attribute on body tag and can import and export form data for quick form autofill.
// ==UserScript==
// @name Universal Handy Web Tools Panel
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Gifts handy buttons: remove readonly/disabled, toggle contenteditable, export/import forms as JSON!
// @author You
// @match *://*/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// ---- CSS for floating tools ----
const css = `
#hwt-btn {
position: fixed;
bottom: 20px; left: 20px;
z-index: 99999; background: #0b6dff;
color: #fff; border: none; border-radius: 10px;
font-size: 18px; padding: 10px 18px;
cursor: pointer; box-shadow: 0 5px 20px #0003;
transition: background .2s;
}
#hwt-btn:hover { background: #094aaf; }
#hwt-panel {
position: fixed; bottom: 80px; left: -500px;
width: 220px; background: #f9f9fd;
border: 1px solid #dde; border-radius: 10px;
box-shadow: 0 8px 24px #0005;
padding: 16px 13px; z-index: 99998;
display: flex; flex-direction: column; gap: 14px;
transition: left .36s cubic-bezier(.67,1.4,.5,1);
}
#hwt-panel.open { left: 20px; }
.hwt-tool-btn {
background: #16a75c;
color: #fff; border: none;
border-radius: 6px; font-size: 15px;
padding: 7px 10px;
cursor: pointer; transition: background .15s;
}
.hwt-tool-btn:hover { background: #0e7a40; }
#hwt-export-link {
color: #007aaa; text-decoration: underline;
font-size: 13px; margin-top: 2px; cursor: pointer;
background: none !important; border: none !important; padding: 0;
}
#hwt-file-input { display: none; }
/* Hide on print */
@media print {
#hwt-btn, #hwt-panel { display:none!important; visibility:hidden!important;}
}
`;
const style = document.createElement('style');
style.textContent = css;
document.head.appendChild(style);
// ---- Main Button ----
const mainBtn = document.createElement('button');
mainBtn.id = 'hwt-btn'
mainBtn.textContent = '🛠️ Tools';
document.body.appendChild(mainBtn);
// ---- Tools panel ----
const panel = document.createElement('div');
panel.id = 'hwt-panel';
document.body.appendChild(panel);
// ---- In-page non-blocking alert ----
function toast(msg) {
const div = document.createElement('div');
div.style.cssText = 'position:fixed;top:48%;left:50%;transform:translate(-50%,-50%);background:#222;color:#fff;padding:15px 32px;border-radius:9px;box-shadow:0 7px 17px #0003;z-index:200000;font-size:18px;opacity:0;transition:opacity .2s;';
div.textContent = msg;
document.body.appendChild(div);
setTimeout(()=>{div.style.opacity='1'},10);
setTimeout(()=>{
div.style.opacity='0';
div.addEventListener('transitionend', ()=>div.remove());
},1800);
}
// ---- Tool actions ----
function removeReadonly() {
let n = 0;
document.querySelectorAll('input[readonly],textarea[readonly]').forEach(el=>{
el.removeAttribute('readonly'); n++;
});
toast(`Removed readonly from ${n} fields.`);
}
function removeDisabled() {
let n = 0;
document.querySelectorAll('[disabled]').forEach(el=>{
el.removeAttribute('disabled'); n++;
});
toast(`Removed disabled from ${n} elements.`);
}
let bodyEditable = false;
function toggleContentEditable() {
bodyEditable = !bodyEditable;
document.body.contentEditable = bodyEditable ? 'true' : 'false';
document.designMode = bodyEditable ? 'on' : 'off';
toast(bodyEditable ? 'Page is editable.' : 'Page edit mode OFF.');
}
function getInputData() {
const obj = {};
document.querySelectorAll('input[name],textarea[name],select[name]').forEach(el => {
const name = el.name;
// Handle checkboxes/radios
if (el.type === 'checkbox') {
obj[name] = el.checked;
} else if (el.type === 'radio') {
if (el.checked) obj[name] = el.value;
} else {
obj[name] = el.value;
}
});
// Fallback to ID for those without name
document.querySelectorAll('input[id]:not([name]),textarea[id]:not([name]),select[id]:not([name])').forEach(el=>{
if(!(el.id in obj)) {
if(el.type === 'checkbox') {
obj[el.id] = el.checked;
} else if(el.type==='radio') {
if(el.checked) obj[el.id]=el.value;
} else {
obj[el.id] = el.value;
}
}
})
return obj;
}
// ---- Export action ----
function exportInputs() {
const data = getInputData();
const blob = new Blob([JSON.stringify(data, null, 2)], {type: 'application/json'});
const url = URL.createObjectURL(blob);
// Download simulation
const a = document.createElement('a');
a.href = url;
a.download = 'form_data.json';
document.body.appendChild(a);
a.click();
setTimeout(()=>{URL.revokeObjectURL(url);a.remove();}, 300);
toast('Exported input fields as JSON!');
}
// ---- Import & autofill ----
let importInput = document.createElement('input');
importInput.type = 'file';
importInput.accept = '.json,application/json';
importInput.id = 'hwt-file-input';
document.body.append(importInput);
function fillImported(json) {
let n = 0;
for (const [k,v] of Object.entries(json)) {
// try name first for all types of fields, fallback to id
let els = document.querySelectorAll(`[name='${CSS.escape(k)}'],#${CSS.escape(k)}`);
if (!els.length) continue;
els.forEach(el=>{
if (el.type === 'checkbox') {
el.checked = !!v;
n++;
} else if (el.type === 'radio') {
if (el.value == v) { el.checked = true; n++; }
} else if (el.tagName === 'SELECT' || el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') {
el.value = v;
n++;
}
});
}
toast(n ? `Filled ${n} field${n===1?'':'s'}.` : 'No matching fields found in form.');
}
importInput.addEventListener('change', async e => {
const file = importInput.files[0];
if (!file) return;
try {
const txt = await file.text();
const json = JSON.parse(txt);
fillImported(json);
} catch {
toast("Invalid JSON file.");
}
importInput.value = "";
});
// ---- UI Buttons ----
const btnRemoveRo = document.createElement('button');
btnRemoveRo.className = 'hwt-tool-btn';
btnRemoveRo.textContent = 'Remove All Readonly';
btnRemoveRo.onclick = removeReadonly;
const btnRemoveDis = document.createElement('button');
btnRemoveDis.className = 'hwt-tool-btn';
btnRemoveDis.textContent = 'Remove All Disabled';
btnRemoveDis.onclick = removeDisabled;
const btnToggleEditable = document.createElement('button');
btnToggleEditable.className = 'hwt-tool-btn';
btnToggleEditable.textContent = 'Toggle Edit Page';
btnToggleEditable.onclick = toggleContentEditable;
const btnExport = document.createElement('button');
btnExport.className = 'hwt-tool-btn';
btnExport.textContent = 'Export Inputs as JSON';
btnExport.onclick = exportInputs;
const btnImport = document.createElement('button');
btnImport.className = 'hwt-tool-btn';
btnImport.textContent = 'Import & Fill Inputs';
btnImport.onclick = ()=>importInput.click();
panel.appendChild(btnRemoveRo);
panel.appendChild(btnRemoveDis);
panel.appendChild(btnToggleEditable);
panel.appendChild(btnExport);
panel.appendChild(btnImport);
// ---- Panel Slide Toggle ----
mainBtn.onclick = ()=>{ panel.classList.toggle('open') };
// ---- Click-away to close panel ----
document.addEventListener('mousedown', e=>{
if (
!panel.contains(e.target) &&
!mainBtn.contains(e.target) &&
panel.classList.contains('open')
) { panel.classList.remove('open'); }
});
// ---- Hide tools panel on print (JS layer for extra safety) ----
window.addEventListener('beforeprint', ()=>{
mainBtn.style.display='none';
panel.style.display='none';
});
window.addEventListener('afterprint', ()=>{
mainBtn.style.display='';
panel.style.display='';
});
})();