// ==UserScript==
// @name 泛微ecology9-IT助手
// @namespace https://huahan.cc/
// @homepageURL https://huahan.cc/cn/index.php
// @version 1.4.1
// @description 丸子的泛微ecology9-IT助手,让你维护泛微OA系统更加顺畅!
// @author Oneszhang 丸子
// @match http*://*/wui/*
// @match http*://*/spa/*
// @match http*://*/security/monitor/*
// @icon https://www.weaver.com.cn/img/favicon.ico
// @grant none
// @run-at document-end
// @noframes
// @license GPL-3.0
// ==/UserScript==
(function() {
'use strict';
const config = {
ecode: true,
engineerNavigation: true,
dataDictionary: true,
iconLibrary: true,
goFeedback: true,
mobilePage: true,
securityMonitor: true,
cacheMonitor: true,
selectList: true
};
const targetHashPath = '#/workflowengine/path/pathSet/pathDetail/formManage/editField';
// 监控hash变化并触发事件
function checkHashAndTriggerEvent() {
const currentHash = window.location.hash;
if (currentHash.includes(targetHashPath)) {
console.log('Target hash path detected:', currentHash);
setupMutationObserver(); // 初始化MutationObserver
appendIDToFieldPosition(); // 初次加载表格时添加ID到字段位置列后
}
}
// 监听哈希变化
window.addEventListener('hashchange', function() {
checkHashAndTriggerEvent();
});
// 初次加载页面时检查一次哈希
checkHashAndTriggerEvent();
// 等待表格加载的函数
function waitForTableLoad() {
const targetNode = document.querySelector('.wea-new-table');
if (!targetNode) {
// console.log('Table container not found, checking again in 500ms.');
setTimeout(waitForTableLoad, 500);
return;
}
const observer = new MutationObserver((mutations, obs) => {
const tableHeader = document.querySelector('.ant-table thead tr');
const tableBodyRows = document.querySelectorAll('.ant-table tbody tr');
if (tableHeader && tableBodyRows.length > 0) {
// console.log('Table structure found, executing code.');
appendIDToFieldPosition();
setupMutationObserver(); // 初始化MutationObserver,监控后续翻页等操作
obs.disconnect(); // 观察器不再需要,断开连接
}
});
observer.observe(targetNode, {
childList: true,
subtree: true
});
}
// 调用等待表格加载的函数
waitForTableLoad();
// 将ID值附加到字段位置列值后的函数
function appendIDToFieldPosition() {
const tableBodyRows = document.querySelectorAll('.ant-table tbody tr');
tableBodyRows.forEach((row) => {
const fieldPositionTd = row.querySelector('td:nth-child(4)'); // 第四列为字段位置列
const idTd = row.querySelector('td:last-child'); // 最后一列为ID列
if (fieldPositionTd && idTd && !fieldPositionTd.innerText.includes('(')) {
const idValue = idTd.getAttribute('stsdata');
fieldPositionTd.innerText += ` (${idValue})`;
}
});
// console.log('ID appended to Field Position column successfully.');
}
// 设置MutationObserver监控翻页或数据变化
function setupMutationObserver() {
const tableBody = document.querySelector('.ant-table tbody');
if (!tableBody) {
// console.log('Table body not found for MutationObserver.');
return;
}
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
// console.log('Table content changed, appending ID to Field Position column.');
appendIDToFieldPosition();
}
});
});
observer.observe(tableBody, { childList: true, subtree: true });
console.log('MutationObserver set up successfully.');
}
function addCssIfNotExists(url) {
const urlWithoutQuery = url.split('?')[0];
const links = document.head.getElementsByTagName('link');
for (let i = 0; i < links.length; i++) {
const linkHrefWithoutQuery = links[i].href.split('?')[0];
if (linkHrefWithoutQuery.includes(urlWithoutQuery)) {
return;
}
}
const linkElement = document.createElement('link');
linkElement.rel = 'stylesheet';
linkElement.href = url;
document.head.appendChild(linkElement);
}
function checkPathhash(fullPath) {
if (fullPath.includes('/spa/workflow/static4engine/engine.html#/main/workflowengine/form/selectList')) {
antd.message.info("点击你想查看id的 选择框 即可查看~",10);
}
}
function addStyle(css) {
const style = document.createElement('style');
style.textContent = css;
document.head.appendChild(style);
}
window.addEventListener('load', function() {
// console.log("ccccccccc");
var pathname = window.location.pathname;
var hash = window.location.hash;
var fullPath = pathname + hash;
checkPathhash(fullPath);
});
function initSecurityMonitorFeatures() {
// console.log("aaaaaaaaa");
var tableContainer = (document.querySelector(".listTable")? document.querySelector(".listTable").parentElement:(document.querySelector("iframe").contentDocument.querySelector(".listTable")? document.querySelector("iframe").contentDocument.querySelector(".listTable").parentElement:null));
var messageDiv = document.createElement("div");
messageDiv.style.textAlign = "left";
messageDiv.style.marginBottom = "10px";
messageDiv.style.fontSize = "14px";
messageDiv.style.color = "#333";
messageDiv.style.display = "flex";
messageDiv.style.justifyContent = "space-between";
messageDiv.style.alignItems = "center";
messageDiv.innerHTML = '<strong>提示:点击可疑次数、可疑时间可进行排序——泛微ecology9-IT助手</strong>';
tableContainer.parentElement.insertBefore(messageDiv, tableContainer);
var checkboxContainer = document.createElement("div");
checkboxContainer.style.display = "flex";
checkboxContainer.style.gap = "10px";
messageDiv.appendChild(checkboxContainer);
var hideIPCheckbox = createCheckbox("hideIPCheckbox", "隐藏已禁止IP", true);
checkboxContainer.appendChild(hideIPCheckbox);
var hideChinaIPCheckbox = createCheckbox("hideChinaIPCheckbox", "隐藏中国IP", true);
checkboxContainer.appendChild(hideChinaIPCheckbox);
var table = document.querySelector(".listTable")?document.querySelector(".listTable"):document.querySelector("iframe").contentDocument.querySelector(".listTable");
var headers = table.querySelectorAll("th");
var tbody = table.querySelector("tbody");
addSortFunction(headers[2], tbody, 3, 'number');
addSortFunction(headers[3], tbody, 4, 'date');
function toggleIPs() {
var rows = tbody.querySelectorAll("tr");
rows.forEach(function(row) {
var ipCell = row.querySelector("td:first-child span");
var locationCell = row.querySelector("td:nth-child(2)");
var isBanned = ipCell.style.backgroundColor === "rgb(240, 87, 87)";
var isChina = locationCell.textContent.includes("中国");
if ((isBanned && hideIPCheckbox.querySelector("input").checked) ||
(isChina && hideChinaIPCheckbox.querySelector("input").checked)) {
row.style.display = "none";
} else {
row.style.display = "";
}
});
}
hideIPCheckbox.querySelector("input").addEventListener("change", toggleIPs);
hideChinaIPCheckbox.querySelector("input").addEventListener("change", toggleIPs);
toggleIPs();
headers[2].click();
}
function createCheckbox(id, labelText, checked) {
var container = document.createElement("div");
var checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.id = id;
checkbox.checked = checked;
var label = document.createElement("label");
label.htmlFor = id;
label.appendChild(document.createTextNode(labelText));
container.appendChild(checkbox);
container.appendChild(label);
return container;
}
function addSortFunction(header, tbody, colIndex, type) {
header.style.cursor = "pointer";
header.addEventListener("click", function() {
var rows = Array.from(tbody.querySelectorAll("tr"));
var isAscending = header.classList.contains("asc");
rows.sort(function(a, b) {
var aValue = getValue(a, colIndex, type);
var bValue = getValue(b, colIndex, type);
return isAscending ? aValue - bValue : bValue - aValue;
});
tbody.innerHTML = "";
rows.forEach(function(row) {
tbody.appendChild(row);
});
header.classList.toggle("asc", !isAscending);
header.classList.toggle("desc", isAscending);
});
}
function getValue(row, colIndex, type) {
var cellValue = row.querySelector(`td:nth-child(${colIndex})`).innerText.trim();
if (type === 'number') {
return parseInt(cellValue);
} else if (type === 'date') {
return new Date(cellValue).getTime();
}
}
function interceptNetworkRequests() {
const originalXHROpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, ...args) {
this.addEventListener('readystatechange', function() {
// console.log("XHR",method,url);
if (this.readyState === 4 && this.status === 200 && url.includes('/api/ec/dev/table/datas')) {
const dataKey = new URLSearchParams(this.responseURL).get('dataKey');
if (dataKey) {
displayDebugButton(dataKey);
}
}
});
return originalXHROpen.apply(this, [method, url, ...args]);
};
const originalFetch = window.fetch;
window.fetch = function(resource, config) {
// console.log("aabbb",resource,"bbaaa",config);
if (config && config.method === 'POST' && config.headers) {
const params = new URLSearchParams(config.body);
const dataKey = params.get('dataKey');
if (dataKey) {
displayDebugButton(dataKey);
}
}
return originalFetch.apply(this, arguments)
.then(response => {
// console.log("response",response);
if (response.url.includes('/api/ec/dev/table/datas') && response.status === 200) {
response.clone().text().then(text => {
const params = new URLSearchParams(text);
const dataKey = params.get('dataKey');
if (dataKey) {
displayDebugButton(dataKey);
}
});
}else if (response.url.includes('/api/workflow/formManage/publicselect/editselectItem') && response.status === 200) {
response.clone().json().then(data => {
displayTable(data.datas);
}).catch(e => {
console.error('Failed to parse response JSON', e);
});
}
return response;
});
};
}
function displayDebugButton(dataKey) {
const debugButton = document.getElementById('debugButton');
debugButton.onclick = () => window.open(`/api/ec/dev/table/getxml?dataKey=${dataKey}`, '_blank');
debugButton.style.backgroundColor = '#2196F3';
debugButton.style.cursor = 'pointer';
let count = 0;
const blinkInterval = setInterval(() => {
debugButton.style.backgroundColor = count % 2 === 0 ? 'gray' : '#2196F3';
count++;
if (count >= 10) {
clearInterval(blinkInterval);
}
}, 400);
setTimeout(() => {
debugButton.onclick = null;
debugButton.style.cursor = 'not-allowed';
debugButton.style.backgroundColor = 'gray';
}, 10000);
}
function makeDraggable(element) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(element.id + "header")) {
document.getElementById(element.id + "header").onmousedown = dragMouseDown;
} else {
element.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;
element.style.top = (element.offsetTop - pos2) + "px";
element.style.left = (element.offsetLeft - pos1) + "px";
}
function closeDragElement() {
document.onmouseup = null;
document.onmousemove = null;
}
}
function displayTable(datas) {
if (!Array.isArray(datas)) {
console.error('Expected an array of datas');
return;
}
const datasCopy = datas.slice();
const sortedById = datasCopy.sort((a, b) => a.id - b.id);
const idToSid = {};
sortedById.forEach((data, index) => {
idToSid[data.id] = index;
});
const container = document.createElement('div');
container.className = 'onestool-draggable';
container.id = 'draggableContainer';
const closeButton = document.createElement('div');
closeButton.textContent = 'X';
closeButton.className = 'onestool-close';
closeButton.onclick = function() { container.remove(); };
container.appendChild(closeButton);
const table = document.createElement('table');
table.className = 'onestool-table';
container.appendChild(table);
const header = table.createTHead();
const headerRow = header.insertRow();
const headers = ['id', 'sid', 'optiontext', 'canel'];
headers.forEach(text => {
const cell = document.createElement('th');
cell.textContent = text;
headerRow.appendChild(cell);
});
const tbody = table.createTBody();
datas.forEach(data => {
const row = tbody.insertRow();
headers.forEach(key => {
const cell = row.insertCell();
cell.textContent = key === 'sid' ? idToSid[data.id] : data[key];
});
});
document.body.appendChild(container);
makeDraggable(container);
}
function createButton(text, onClick) {
const button = document.createElement('button');
button.textContent = text;
button.onclick = onClick;
Object.assign(button.style, {
width: '100%',
padding: '10px',
marginBottom: '10px',
backgroundColor: '#4CAF50',
color: 'white',
border: 'none',
borderRadius: '5px',
cursor: 'pointer'
});
return button;
}
function createIconLibraryButton() {
const button = document.createElement('button');
button.textContent = '图标库';
Object.assign(button.style, {
width: '100%',
padding: '10px',
marginBottom: '10px',
backgroundColor: '#4CAF50',
color: 'white',
border: 'none',
borderRadius: '5px',
cursor: 'pointer'
});
button.addEventListener('click', showIcons);
return button;
}
function showIcons() {
const modal = document.createElement('div');
modal.className = 'onestool-icon-modal';
const tabContainer = document.createElement('div');
tabContainer.className = 'onestool-tab-container';
const weviconTab = createTabButton('Wevicon', true);
const ecComiconTab = createTabButton('EcComicon', false);
tabContainer.appendChild(weviconTab);
tabContainer.appendChild(ecComiconTab);
const iconContainer = document.createElement('div');
iconContainer.id = 'icon-container';
modal.appendChild(tabContainer);
modal.appendChild(iconContainer);
const closeButton = document.createElement('button');
closeButton.textContent = '关闭';
closeButton.className = 'onestool-close-button';
closeButton.addEventListener('click', () => document.body.removeChild(modal));
modal.appendChild(closeButton);
document.body.appendChild(modal);
loadIcons('wevicon');
weviconTab.addEventListener('click', () => {
setActiveTab(weviconTab, ecComiconTab);
loadIcons('wevicon');
});
ecComiconTab.addEventListener('click', () => {
setActiveTab(ecComiconTab, weviconTab);
loadIcons('ecComicon');
});
}
function createTabButton(text, isActive) {
const button = document.createElement('button');
button.textContent = text;
button.className = `onestool-tab-button ${isActive ? 'active' : ''}`;
return button;
}
function setActiveTab(activeTab, inactiveTab) {
activeTab.classList.add('active');
inactiveTab.classList.remove('active');
}
function loadIcons(iconType) {
const url = iconType === 'wevicon' ? '/spa/theme/static/index.css' : '/cloudstore/resource/pc/com/v1/ecCom.min.css';
const iconRegex = iconType === 'wevicon' ? /\.wevicon-[^:]+:before\s*\{/g : /\.icon-[a-zA-Z0-9-]+:before\s*\{[^\}]*content\s*:\s*"\\[a-fA-F0-9]+"[^\}]*\}/g;
fetch(url)
.then(response => response.text())
.then(css => {
let match;
let iconsHtml = '<div class="onestool-icon-grid">';
while ((match = iconRegex.exec(css)) !== null) {
const iconClass = match[0].split(':')[0].slice(1);
iconsHtml += `
<div class="onestool-icon-item">
<i class="${iconClass} onestool-con-display"></i>
<div class="onestool-icon-name">${iconClass.replace(iconType === 'wevicon' ? 'wevicon-' : 'icon-', '')}</div>
</div>
`;
}
iconsHtml += '</div>';
document.getElementById('icon-container').innerHTML = iconsHtml;
})
.catch(error => {
console.error('Failed to fetch icon CSS:', error);
alert('Failed to load icon definitions.');
});
}
function createInfoCard(userInfo, workflowInfo, modeInfo) {
const card = document.createElement('div');
Object.assign(card.style, {
position: 'fixed',
bottom: '100px',
right: '10px',
width: '300px',
padding: '20px',
backgroundColor: '#f9f9f9',
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)',
borderRadius: '10px',
zIndex: '1000'
});
const createSection = (title, data) => {
const section = document.createElement('div');
const sectionTitle = document.createElement('h3');
sectionTitle.textContent = title;
section.appendChild(sectionTitle);
const sectionContent = document.createElement('div');
sectionContent.style.overflowY = 'auto';
if (data) {
for (const [key, value] of Object.entries(data)) {
const infoItem = document.createElement('p');
infoItem.textContent = `${key}: ${value}`;
sectionContent.appendChild(infoItem);
}
} else {
const infoItem = document.createElement('p');
infoItem.textContent = '无可用信息';
sectionContent.appendChild(infoItem);
}
section.appendChild(sectionContent);
return section;
};
if (userInfo) {
card.appendChild(createSection('用户信息', {
'部门ID.deptid': userInfo.deptid,
'部门名称.deptname': userInfo.deptname,
'分部ID.subcompanyid': userInfo.subcompanyid,
'分部名称.subcompanyname': userInfo.subcompanyname,
'用户语言.userLanguage': userInfo.userLanguage,
'用户ID.userid': userInfo.userid,
'用户名.username': userInfo.username
}));
}
if (workflowInfo) {
card.appendChild(createSection('流程信息', {
'请求ID.requestid': workflowInfo.requestid,
'流程ID.workflowid': workflowInfo.workflowid,
'节点ID.nodeid': workflowInfo.nodeid,
'表单ID.formid': workflowInfo.formid
}));
}
if (modeInfo) {
card.appendChild(createSection('建模信息', {
'数据ID.billid': modeInfo.billid,
'显示类型.type': modeInfo.type,
'模块ID.modeId': modeInfo.modeId,
'表单ID.formId': modeInfo.formId,
'模块名称.modeName': modeInfo.modeName,
'模块标题.modeTitle': modeInfo.modeTitle
}));
}
if (!userInfo && !workflowInfo && !modeInfo) {
card.appendChild(createSection('无可用信息', null));
}
const closeButton = document.createElement('button');
closeButton.textContent = '关闭';
Object.assign(closeButton.style, {
width: '100%',
padding: '10px',
backgroundColor: '#f44336',
color: 'white',
border: 'none',
borderRadius: '5px',
cursor: 'pointer',
marginTop: '10px'
});
closeButton.onclick = () => {
document.body.removeChild(card);
};
card.appendChild(closeButton);
document.body.appendChild(card);
}
function main() {
addCssIfNotExists('/spa/theme/static/index.css');
addCssIfNotExists('/cloudstore/resource/pc/com/v1/ecCom.min.css');
const togglecard = document.createElement('div');
Object.assign(togglecard.style, {
position: 'fixed',
bottom: '50px',
right: '10px',
width: '200px',
padding: '20px',
backgroundColor: '#f9f9f9',
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)',
borderRadius: '10px',
zIndex: '1000',
display: 'none'
});
if (config.ecode) {
togglecard.appendChild(createButton('打开ecode', () => window.open('/ecode', '_blank')));
}
if (config.mobilePage) {
togglecard.appendChild(createButton('打开移动端', () => window.open('/spa/portal/static4mobilelogin/index.html', '_blank')));
}
if (config.securityMonitor) {
togglecard.appendChild(createButton('安全包监控', () => window.open('/security/monitor/Monitor.jsp', '_blank')));
}
if (config.cacheMonitor) {
togglecard.appendChild(createButton('SQL缓存管理', () => window.open('/commcache/cacheMonitor.jsp', '_blank')));
}
if (config.selectList) {
togglecard.appendChild(createButton('公共选框ID', () => window.open('/spa/workflow/static4engine/engine.html#/main/workflowengine/form/selectList', '_blank')));
}
if (config.engineerNavigation) {
togglecard.appendChild(createButton('工程师导航', () => window.open('https://huahan.cc', '_blank')));
}
if (config.dataDictionary) {
togglecard.appendChild(createButton('数据字典', () => window.open('https://oneszhang.com/E9Sql/', '_blank')));
}
if (config.iconLibrary) {
togglecard.appendChild(createIconLibraryButton());
}
if (config.goFeedback) {
togglecard.appendChild(createButton('留言反馈', () => window.open('https://oneszhang.com/onestool.html', '_blank')));
}
if (window.location.pathname.includes('/security/monitor')) {
if (document.getElementById('updateRulesForm')) {
initSecurityMonitorFeatures();
}
if (typeof window.resetbanner === 'function') {
const originalResetBanner = window.resetbanner;
window.resetbanner = function(objid) {
originalResetBanner(objid);
if (objid === 4) {
const iframe = document.getElementById('iframeAlert');
iframe.addEventListener('load', function() {
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
if (iframeDoc.querySelector('.listTable')) {
initSecurityMonitorFeatures();
}
});
}
};
}
}
const allButtonContainer = document.createElement('div');
Object.assign(allButtonContainer.style, {
position: 'fixed',
bottom: '10px',
right: '10px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: '1001'
});
const toggleButton = document.createElement('div');
const toggleiconElement = document.createElement('i');
toggleiconElement.className = 'icon-New-Flow-menu';
toggleButton.appendChild(toggleiconElement);
Object.assign(toggleButton.style, {
width: '30px',
height: '30px',
backgroundColor: '#4CAF50',
color: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '50%',
cursor: 'pointer',
marginLeft: '10px'
});
toggleButton.onclick = () => togglecard.style.display = togglecard.style.display === 'none' ? 'block' : 'none';
const debugButton = document.createElement('div');
const debugiconElement = document.createElement('i');
debugiconElement.className = 'wevicon-menu-2--5731';
debugButton.appendChild(debugiconElement);
debugButton.id = 'debugButton';
Object.assign(debugButton.style, {
width: '30px',
height: '30px',
backgroundColor: 'gray',
color: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '50%',
cursor: 'not-allowed',
marginLeft: '10px'
});
const infoButton = document.createElement('div');
const infoiconElement = document.createElement('i');
infoiconElement.className = 'icon-coms02-Version';
infoButton.appendChild(infoiconElement);
infoButton.id = 'infoButton';
Object.assign(infoButton.style, {
width: '30px',
height: '30px',
backgroundColor: '#14b8a6',
color: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '50%',
cursor: 'pointer',
marginLeft: '10px'
});
infoButton.onclick = () => {
const userInfo = JSON.parse(localStorage.getItem('theme-account'));
const workflowInfo = (typeof wfform !== 'undefined' && wfform !== null && typeof wfform.getBaseInfo === 'function') ? wfform.getBaseInfo() : null;
const modeInfo = (typeof ModeForm !== 'undefined' && ModeForm !== null && typeof ModeForm.getCardUrlInfo === 'function') ? ModeForm.getCardUrlInfo() : null;
createInfoCard(userInfo, workflowInfo, modeInfo);
};
allButtonContainer.appendChild(debugButton);
allButtonContainer.appendChild(infoButton);
allButtonContainer.appendChild(toggleButton);
document.body.appendChild(togglecard);
document.body.appendChild(allButtonContainer);
interceptNetworkRequests();
}
addStyle(`
.onestool-icon-button {
position: fixed;
left: 10px;
bottom: 10px;
z-index: 9999;
padding: 10px 15px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.3s;
}
.onestool-icon-button:hover {
background-color: #45a049;
}
.onestool-icon-modal {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0,0,0,0.2);
width: 90%;
height: 90%;
overflow: auto;
z-index: 10000;
}
.onestool-icon-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
gap: 10px;
}
.onestool-icon-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 5px;
border: 1px solid #e0e0e0;
border-radius: 5px;
transition: box-shadow 0.3s;
height: 80px;
}
.onestool-icon-item:hover {
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.onestool-con-display {
font-size: 24px;
margin-bottom: 5px;
}
.onestool-icon-name {
font-size: 10px;
text-align: center;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
white-space: nowrap;
}
.onestool-close-button {
position: absolute;
right: 10px;
top: 10px;
background-color: #f44336;
color: white;
border: none;
padding: 5px 10px;
border-radius: 3px;
cursor: pointer;
transition: background-color 0.3s;
}
.onestool-close-button:hover {
background-color: #d32f2f;
}
.onestool-tab-container {
display: flex;
justify-content: center;
margin-bottom: 20px;
}
.onestool-tab-button {
padding: 10px 20px;
background-color: #f0f0f0;
border: none;
cursor: pointer;
transition: background-color 0.3s;
}
.onestool-tab-button:hover {
background-color: #e0e0e0;
}
.onestool-tab-button.active {
background-color: #4CAF50;
color: white;
}
.onestool-table {
border-collapse: collapse;
width: 100%;
}
.onestool-table, .onestool-table th, .onestool-table td {
border: 1px solid black;
padding: 5px;
}
.onestool-draggable {
position: absolute;
top: 10%;
left: 10%;
width: 80%;
background: white;
border: 1px solid black;
z-index: 10000;
}
.onestool-close {
cursor: pointer;
position: absolute;
top: 0;
right: 0;
padding: 5px 10px;
}
`);
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', main);
} else {
main();
}
})();