fist version
This commit is contained in:
parent
99d66d38ac
commit
fd41f8558f
402
LMSGuides助手-源码.user.js
Executable file
402
LMSGuides助手-源码.user.js
Executable file
@ -0,0 +1,402 @@
|
||||
// ==UserScript==
|
||||
// @name LMSGuides助手-源码
|
||||
// @version 1.3.2
|
||||
// @description 要有远大的理想,也要有脚踏实地的本领
|
||||
// @author 小钊
|
||||
// @match *://10.90.53.11:5090/*
|
||||
// @homepageURL https://www.zxqblog.cn
|
||||
// @grant GM_registerMenuCommand
|
||||
// @grant GM_unregisterMenuCommand
|
||||
// @grant GM_setValue
|
||||
// @grant GM_getValue
|
||||
// @grant GM_deleteValue
|
||||
// ==/UserScript==
|
||||
|
||||
/* 更新日志
|
||||
1.3.1
|
||||
修复
|
||||
复制到实体机功能无法使用
|
||||
1.3.2
|
||||
修复
|
||||
1.实验报告->文本样式->预定义格式被识别为代码导致添加按钮的bug
|
||||
2.复制到虚拟机/实体机成功的提示无法切换
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
// 通用样式定义
|
||||
// 复制到虚拟机的样式
|
||||
const buttonStyle = `
|
||||
.copy-vm-btn {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
padding: 5px 10px;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
z-index: 100;
|
||||
}
|
||||
.copy-vm-btn:hover {
|
||||
background-color: #45a049;
|
||||
}
|
||||
/* pre标签容器样式 */
|
||||
.pre-container {
|
||||
position: relative;
|
||||
}
|
||||
/* 鼠标悬浮时显示按钮 */
|
||||
.pre-container:hover .copy-vm-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
const styleSheet = document.createElement("style");
|
||||
styleSheet.textContent = buttonStyle;
|
||||
document.head.appendChild(styleSheet);
|
||||
// 设置页面的开关样式
|
||||
const switchStyles = {
|
||||
position: 'relative',
|
||||
width: '50px',
|
||||
height: '24px',
|
||||
appearance: 'none',
|
||||
outline: 'none',
|
||||
borderRadius: '12px',
|
||||
backgroundColor: '#ccc',
|
||||
cursor: 'pointer',
|
||||
verticalAlign: 'middle'
|
||||
};
|
||||
const sliderStyles = {
|
||||
position: 'absolute',
|
||||
top: '2px',
|
||||
left: '2px',
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
borderRadius: '50%',
|
||||
backgroundColor: '#fff',
|
||||
transition: 'all 0.3s'
|
||||
};
|
||||
// -------------------------------------
|
||||
// 注册脚本菜单
|
||||
GM_registerMenuCommand("设置", showSettingsPopup);
|
||||
// -------------------------------------
|
||||
// 免责说明
|
||||
window.addEventListener('load', function(event) {
|
||||
if (!GM_getValue('mianzeshenming',false)){
|
||||
// 如果检测到没有同意协议则渲染免责协议窗口
|
||||
document.body.innerHTML = '';
|
||||
const mzsf = document.createElement('div');
|
||||
Object.assign(mzsf.style, {
|
||||
position: 'fixed',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
padding: '20px',
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: '8px',
|
||||
boxShadow: '0 4px 8px rgba(0,0,0,0.2)',
|
||||
zIndex: '1000',
|
||||
width: '300px'
|
||||
});
|
||||
|
||||
// 标题与提示渲染
|
||||
const title = document.createElement('h2');
|
||||
title.textContent = '免责协议';
|
||||
mzsf.appendChild(title);
|
||||
const tips = document.createElement('p');
|
||||
tips.textContent = "请合理使用此脚本,造成一切损失与作者无关!同意协议后点击刷新进行页面刷新,如果不同意协议请删除此脚本并刷新网页"
|
||||
tips.style.marginTop = '10px';
|
||||
tips.style.marginBottom = '10px'
|
||||
mzsf.appendChild(tips);
|
||||
|
||||
// 开关渲染
|
||||
// 复制到虚拟机开关
|
||||
mzsf.appendChild(createSwitch('同意免责协议', 'mianzeshenming'));
|
||||
|
||||
// 刷新按钮渲染
|
||||
const sxButton = document.createElement('button');
|
||||
sxButton.textContent = '刷新';
|
||||
Object.assign(sxButton.style, {
|
||||
marginTop: '15px',
|
||||
padding: '8px 16px',
|
||||
backgroundColor: '#f44336',
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
cursor: 'pointer'
|
||||
});
|
||||
sxButton.onclick = function() {
|
||||
location.reload()
|
||||
};
|
||||
|
||||
mzsf.appendChild(sxButton);
|
||||
document.body.appendChild(mzsf);
|
||||
}else {
|
||||
// 否则渲染设置窗口
|
||||
if (!GM_getValue("CopyToVM_Switch_Status",false) && !GM_getValue("Autoground_Switch_Status",false) && !GM_getValue("Select_Switch_Status",false) && !GM_getValue("NoOneShowsetting",false)) {
|
||||
// 如果所有的配置项均未配置,则显示配置窗口
|
||||
GM_setValue("NoOneShowsetting", true);
|
||||
showSettingsPopup();
|
||||
}
|
||||
}
|
||||
})
|
||||
// -------------------------------------
|
||||
// 函数部分
|
||||
// 设置->创建开关 函数
|
||||
function createSwitch(label, storageKey, onChange) {
|
||||
const container = document.createElement('div');
|
||||
container.style.marginBottom = '15px';
|
||||
|
||||
const switchLabel = document.createElement('label');
|
||||
switchLabel.textContent = label;
|
||||
switchLabel.style.marginRight = '10px';
|
||||
switchLabel.style.fontWeight = 'normal';
|
||||
|
||||
const switchInput = document.createElement('input');
|
||||
switchInput.type = 'checkbox';
|
||||
Object.assign(switchInput.style, switchStyles);
|
||||
|
||||
const slider = document.createElement('span');
|
||||
Object.assign(slider.style, sliderStyles);
|
||||
switchInput.appendChild(slider);
|
||||
|
||||
// 初始状态
|
||||
const isChecked = GM_getValue(storageKey, false);
|
||||
switchInput.name = storageKey;
|
||||
switchInput.checked = isChecked;
|
||||
switchInput.style.backgroundColor = isChecked ? '#4CAF50' : '#ccc';
|
||||
slider.style.transform = isChecked ? 'translateX(26px)' : 'translateX(0)';
|
||||
|
||||
// 事件处理
|
||||
switchInput.addEventListener('change', function() {
|
||||
const checked = this.checked;
|
||||
this.style.backgroundColor = checked ? '#4CAF50' : '#ccc';
|
||||
slider.style.transform = checked ? 'translateX(26px)' : 'translateX(0)';
|
||||
GM_setValue(storageKey, checked);
|
||||
if (onChange) onChange(checked);
|
||||
});
|
||||
|
||||
container.appendChild(switchLabel);
|
||||
container.appendChild(switchInput);
|
||||
return container;
|
||||
}
|
||||
// 设置->主界面 函数
|
||||
function showSettingsPopup() {
|
||||
// 确保之前的弹窗被移除
|
||||
const existingPopup = document.querySelector('div[style*="position: fixed; top: 50%; left: 50%;"]');
|
||||
if (existingPopup) {
|
||||
document.body.removeChild(existingPopup);
|
||||
}
|
||||
const popup = document.createElement('div');
|
||||
Object.assign(popup.style, {
|
||||
position: 'fixed',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
padding: '20px',
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: '8px',
|
||||
boxShadow: '0 4px 8px rgba(0,0,0,0.2)',
|
||||
zIndex: '1000',
|
||||
width: '300px'
|
||||
});
|
||||
|
||||
// 标题与提示渲染
|
||||
const title = document.createElement('h2');
|
||||
title.textContent = '设置';
|
||||
popup.appendChild(title);
|
||||
const tip_list = ["启动立马生效,关闭刷新生效","复制到虚拟机优先级高于复制到实体机"];
|
||||
const tips = document.createElement('p');
|
||||
tips.textContent = tip_list[0];
|
||||
tips.id = "setting_tip";
|
||||
tips.style.marginTop = '10px';
|
||||
tips.style.marginBottom = '10px'
|
||||
popup.appendChild(tips);
|
||||
let tip_id = 1
|
||||
const tip_initer = setInterval(() => {
|
||||
tip_id = tip_id==1 ? 0 : 1;
|
||||
document.getElementById("setting_tip").innerHTML = tip_list[tip_id];
|
||||
}, 1000)
|
||||
|
||||
|
||||
// 开关渲染
|
||||
// 复制到虚拟机开关
|
||||
popup.appendChild(createSwitch('复制到虚拟机', 'CopyToVM_Switch_Status'));
|
||||
// 实验报告滚动
|
||||
popup.appendChild(createSwitch('实验报告自动滚动到底', 'Autoground_Switch_Status'));
|
||||
// 移除复制限制
|
||||
popup.appendChild(createSwitch('移除移除选择、复制、剪切操作的限制', 'Select_Switch_Status'));
|
||||
// 复制到实体机开关
|
||||
popup.appendChild(createSwitch('复制到实体机', 'CopyToTrue_Switch_Status'));
|
||||
|
||||
// 关闭按钮渲染
|
||||
const closeButton = document.createElement('button');
|
||||
closeButton.textContent = '关闭';
|
||||
Object.assign(closeButton.style, {
|
||||
marginTop: '15px',
|
||||
padding: '8px 16px',
|
||||
backgroundColor: '#f44336',
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
cursor: 'pointer'
|
||||
});
|
||||
closeButton.onclick = function() {
|
||||
document.body.removeChild(popup);
|
||||
clearInterval(tip_initer)
|
||||
};
|
||||
|
||||
popup.appendChild(closeButton);
|
||||
document.body.appendChild(popup);
|
||||
}
|
||||
// 主功能->弹窗函数
|
||||
function notification(text) {
|
||||
const notification = document.createElement('div');
|
||||
notification.style.cssText = `
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
padding: 10px 20px;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
z-index: 10000;
|
||||
`;
|
||||
notification.textContent = text;
|
||||
document.body.appendChild(notification);
|
||||
setTimeout(() => notification.remove(), 2000);
|
||||
}
|
||||
// 复制到虚拟机功能 -> 复制到虚拟机 函数
|
||||
function sendToVirtualMachine(text) {
|
||||
if (GM_getValue("CopyToVM_Switch_Status",false)){
|
||||
console.log("text"+text)
|
||||
const code = "code:"+text
|
||||
document.getElementById("tool_content").contentWindow.postMessage(code, "*");
|
||||
}else if (GM_getValue("CopyToTrue_Switch_Status",false)) {
|
||||
mycopy(text);
|
||||
}
|
||||
return true
|
||||
}
|
||||
// 复制到实体机功能 -> 复制到实体机 函数
|
||||
function mycopy(data) {
|
||||
const TEXT_PLAIN = "text/plain";
|
||||
const TEXT_HTML = "text/html";
|
||||
const COPY = "copy";
|
||||
const opt = Object.prototype.toString;
|
||||
const execCopyCommand = (data) => {
|
||||
const textarea = document.createElement("textarea");
|
||||
const handler = (event) => {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
event.clipboardData && event.clipboardData.setData(key, value);
|
||||
}
|
||||
};
|
||||
textarea.addEventListener(COPY, handler, true);
|
||||
textarea.style.position = "fixed";
|
||||
textarea.style.left = "-999999999px";
|
||||
textarea.style.top = "-999999999px";
|
||||
textarea.value = data[TEXT_PLAIN] || " ";
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
document.execCommand("copy");
|
||||
textarea.removeEventListener(COPY, handler);
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
function isString(value) {
|
||||
return opt.call(value) === "[object String]";
|
||||
}
|
||||
const isEmptyContent = (data) => {
|
||||
if (!data)
|
||||
return true;
|
||||
return isString(data) ? !data : !data[TEXT_PLAIN];
|
||||
};
|
||||
const params = isString(data) ? { [TEXT_PLAIN]: data } : data;
|
||||
const plainText = params[TEXT_PLAIN];
|
||||
if (!plainText)
|
||||
return false;
|
||||
if (navigator.clipboard && window.ClipboardItem) {
|
||||
const dataItems = {};
|
||||
for (const [key, value] of Object.entries(params)) {
|
||||
const blob = new Blob([value], { type: key });
|
||||
dataItems[key] = blob;
|
||||
}
|
||||
navigator.clipboard.write([new ClipboardItem(dataItems)]).catch(() => {
|
||||
execCopyCommand(params);
|
||||
});
|
||||
} else {
|
||||
execCopyCommand(params);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// -------------------------------------
|
||||
// 定时器部分
|
||||
// 页面加载时移除选择、复制、剪切操作的限制
|
||||
setInterval(() => {
|
||||
if (GM_getValue("Select_Switch_Status",false)) {
|
||||
document.onselectstart = function(event) {return true;};
|
||||
document.oncopy = function(event) {return true;};
|
||||
document.oncut = function(event) {return true;};
|
||||
var elements = document.querySelectorAll('[class^=" language-"]');
|
||||
elements.forEach(function(element) {element.style.cssText = '';});
|
||||
}
|
||||
}, 1000)
|
||||
// 复制到虚拟/虚拟机按钮渲染
|
||||
setInterval(() => {
|
||||
if (GM_getValue("CopyToVM_Switch_Status",false)||GM_getValue("CopyToTrue_Switch_Status",false)){
|
||||
const btn_type = GM_getValue("CopyToVM_Switch_Status") ? ["虚拟",'Vm'] : ["实体","Tr"];
|
||||
document.querySelectorAll('pre[class^=" language-"]').forEach(pre => {
|
||||
// 元素存在且状态正确
|
||||
if (pre.getAttribute('data-type-button')==btn_type[1]) return;
|
||||
// 元素存在且状态不正确
|
||||
if (pre.getAttribute('data-type-button') != null && pre.getAttribute('data-type-button')!=btn_type[1]) {
|
||||
pre.setAttribute('data-type-button', btn_type[1]);
|
||||
const btns = document.getElementsByClassName('copy-vm-btn')
|
||||
Array.from(btns).forEach(btn=>{
|
||||
btn.innerHTML = `复制到${btn_type[0]}机`;
|
||||
btn.onclick = function() {
|
||||
const success = sendToVirtualMachine(pre.textContent);
|
||||
if (success) {notification(`已复制到${btn_type[0]}机!`);}
|
||||
};
|
||||
})
|
||||
return
|
||||
};
|
||||
// 元素不存在
|
||||
console.log("不正确")
|
||||
const container = document.createElement('div');
|
||||
container.className = 'pre-container';
|
||||
pre.parentNode.insertBefore(container, pre);
|
||||
container.appendChild(pre);
|
||||
const button = document.createElement('button');
|
||||
button.className = 'copy-vm-btn';
|
||||
pre.setAttribute('data-type-button', btn_type[1]);
|
||||
button.textContent = `复制到${btn_type[0]}机`
|
||||
button.onclick = function() {
|
||||
const success = sendToVirtualMachine(pre.textContent);
|
||||
if (success) {notification(`已复制到${btn_type[0]}机!`);}
|
||||
};
|
||||
container.appendChild(button);
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
// 点击实验报告滚动到最下面
|
||||
setInterval(() => {
|
||||
if (GM_getValue("Autoground_Switch_Status",false)) {
|
||||
try {
|
||||
document.querySelector("#assignment-report").addEventListener('click', function() {
|
||||
const lastElement =document.getElementById("report_area_ifr").contentDocument.querySelector("#tinymce p:last-child")
|
||||
if (lastElement) {
|
||||
lastElement.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
inline: 'nearest'
|
||||
});
|
||||
}
|
||||
});
|
||||
}catch {}
|
||||
}
|
||||
}, 1000)
|
||||
})();
|
Loading…
x
Reference in New Issue
Block a user