try to improve TutorDBOps
当前为
// ==UserScript==
// @name TutorDBOps Helper
// @namespace http://tpdbops.tutorabc.com/
// @version 0.6
// @description try to improve TutorDBOps
// @author Tex
// @match http://tpdbops.tutorabc.com/mysqlmanage/select_*
// @icon https://www.google.com/s2/favicons?domain=tutorabc.com
// @grant none
// ==/UserScript==
(function() {
const isMssqlPage = location.pathname.includes('mssql');
const dbopsStorage = {
prefix: isMssqlPage ? 'dbops-mssql-' : 'dbops-mysql-',
set:(key, value) => localStorage.setItem(dbopsStorage.prefix+key, value),
get:(key) => localStorage.getItem(dbopsStorage.prefix+key),
}
function addCss(cssString) {
const head = document.getElementsByTagName('head')[0];
const newCss = document.createElement('style');
newCss.type = "text/css";
newCss.innerHTML = cssString;
head.appendChild(newCss);
}
function loadScript(url, callback) {
if(!url) return;
const head = document.getElementsByTagName('head')[0];
const script = document.createElement('script');
head.appendChild(script);
script.src = url;
script.onload = script.onreadystagechange = function() {
console.log('loaded:', url);
callback && callback();
}
}
const searchBtn = document.getElementById("search");
function submitSql() {
searchBtn.click();
}
function collapse(showLeftArea) {
// hide sidebar
const sidebar = document.querySelector("#container > aside");
sidebar.style.width = showLeftArea? '230px' : '0px';
sidebar.style.opacity = showLeftArea? '1' : '0';
sidebar.style['z-index'] = showLeftArea? 'unset' : '-1';
// remove right area margin left
const rightblock = document.querySelector("#container > section");
rightblock.style['margin-left'] = showLeftArea ? '230px':'0px';
}
function aceLoadCallback() {
ace.config.loadModule('ace/ext/textarea', function(m) {
const textArea = document.querySelector("form div > textarea");
m.transformTextarea(textArea, {fontSize: '14px', mode: isMssqlPage ? 'sqlserver':'mysql', theme: 'cobalt', showPrintMargin: false });
})
}
loadScript('https://ajaxorg.github.io/ace-builds/src-noconflict/ace.js', aceLoadCallback);
const storageVal = dbopsStorage.get('showLeftArea');
let showLeftArea = storageVal === 'true' ?? true;
collapse(showLeftArea)
function toggleRightArea() {
// toggle state
showLeftArea = !showLeftArea;
dbopsStorage.set('showLeftArea',showLeftArea);
collapse(showLeftArea)
}
const hint = document.querySelector("div.box.box-success > form > table > tbody > tr > td:nth-child(2)");
hint.style.display = 'none';
const executePlanBtn = document.querySelector("div.box.box-success > form > table > tbody > tr > td:nth-child(1) > div > div > button:nth-child(7)")
const hostTitle = document.querySelector("form > div.box-header.with-border.table_sort_form > a:nth-child(1) > input");
const dbTitle = document.querySelector("form > div.box-header.with-border.table_sort_form > a:nth-child(3) > input");
if(executePlanBtn) executePlanBtn.innerText="查看執行計畫";
searchBtn.innerText="執行"
hostTitle.value="主機 (雙擊輸入框清空)"
dbTitle.value="資料庫"
const hostSelector = document.querySelector("#doc-vld-post-1");
const dbSelector = document.querySelector("#doc-vld-level-1")
const storedHost = dbopsStorage.get('host');
const storedDB = dbopsStorage.get('db');
const hosts = Array.from(hostSelector.children).map(e => e.value);
const hostInput = document.createElement('input');
hostInput.setAttribute("list", "hostlist");
hostInput.id='hosts';
hostInput.name='hosts';
hostInput.placeholder="請選擇主機";
hostInput.className="topInput"
hostInput.ondblclick = (e) => {
e.target.value='';
}
if(storedHost) hostInput.value = storedHost;
const hostDataList = document.createElement('datalist');
hostDataList.id = 'hostlist';
hosts.forEach(e => {
const op = document.createElement('option');
op.value = e;
hostDataList.appendChild(op)
});
const hostAnchor = document.querySelector("form > div.box-header.with-border.table_sort_form > a:nth-child(1)");
hostAnchor.parentNode.insertBefore(hostDataList, hostAnchor.nextSibling);
hostAnchor.parentNode.insertBefore(hostInput, hostAnchor.nextSibling);
//hostSelector.remove();
hostSelector.style.display="none";
hostSelector.removeAttribute("required");
hostSelector.name="hh";
function updateDBInput(val, callback) {
fetch('http://tpdbops.tutorabc.com/mysqlmanage/ipdbname/'+val)
.then(r => r.json())
.then(dbs => {
dbDataList.replaceChildren(null);
dbInput.value='';
dbs.forEach((e, index) => {
const op = document.createElement('option');
op.value = e;
dbDataList.appendChild(op)
})
const dbAnchor = document.querySelector("form > div.box-header.with-border.table_sort_form > a:nth-child(5)");
dbAnchor.parentNode.insertBefore(dbDataList, dbAnchor.nextSibling);
dbAnchor.parentNode.insertBefore(dbInput, dbAnchor.nextSibling);
callback();
})
}
const dbInput = document.createElement('input');
dbInput.setAttribute("list", "dblist");
dbInput.id='dbs';
dbInput.name='dbs';
dbInput.placeholder="請選擇資料庫";
dbInput.className="topInput"
dbInput.ondblclick = (e) => {
e.target.value='';
}
if(storedHost && storedDB) {
updateDBInput(storedHost, () => {dbInput.value = storedDB})
};
const dbDataList = document.createElement('datalist');
dbDataList.id='dblist'
hostInput.onchange = (e) => {
dbopsStorage.set('host',e.target.value);
updateDBInput(e.target.value)
hostSelector.value=e.target.value;
}
dbInput.onchange = (e) => {
dbopsStorage.set('db',e.target.value);
dbSelector.value=e.target.value;
}
//dbSelector.remove();
dbSelector.style.display="none";
dbSelector.removeAttribute("required");
dbSelector.name="dd";
// autofocus sql textarea
const sqlTextArea = document.querySelector("form > table > tbody > tr > td:nth-child(1) > div > div > textarea")
sqlTextArea.focus();
// enroll event
document.onkeydown = function(e) {
if(e.code === 'Enter' && e.ctrlKey) {
submitSql();
}
if(e.code === 'KeyB' && e.ctrlKey) {
toggleRightArea();
}
}
addCss(`
* {
font-family: Consolas;
font-weight: bold;
font-size: 14px;
}
.form-group, div.box.box-success > form > table {
width: 100%;
}
textarea.form-control {
width: 100% !important;
height: 60vh;
}
table.table-hover, small{
transform: rotateX(180deg);
}
.box-footer {
transform: rotateX(180deg);
}
.box-footer ~ .box-footer{
margin-top: 30px;
overflow: unset !important;
overflow-x: auto !important;
}
.box-footer table {
width: 99%;
margin: 0 auto;
}
.topInput {
margin-left: 10px;
width: 250px;
}
.table_sort_form > a:nth-child(1) > input {
cursor: default;
}
.table_sort_form > a:nth-child(3) > input {
cursor: default;
}
form > table > tbody > tr > td:nth-child(1) > div > div > div {
width: 100% !important;
]
`)
})();