Начинающий
- Статус
- Онлайн
- Регистрация
- 15 Окт 2023
- Сообщения
- 51
- Реакции
- 5

Есть отладчик и просвет меню.
JavaScript:
// ==UserScript==
// @name Menu v1
// @namespace http://tampermonkey.net/
// @version 1.0
// @description MeniCastom
// @author QQloxi
// @match *://*/*
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(function() {
'use strict';
// Logger class for debugging
class Logger {
constructor() {
this.logs = [];
this.debuggerEnabled = GM_getValue('debuggerEnabled', false);
this.debuggerWindow = null;
}
log(message, type = 'info') {
const timestamp = new Date().toLocaleTimeString();
this.logs.push({ timestamp, message, type });
if (this.debuggerEnabled && this.debuggerWindow) {
this.updateDebugger();
}
}
error(message) {
this.log(message, 'error');
}
updateDebugger() {
const logContainer = this.debuggerWindow.querySelector('.debugger-content');
if (logContainer) {
logContainer.innerHTML = this.logs.map(log =>
`<div class="log-${log.type}">[${log.timestamp}] ${log.message}</div>`
).join('');
logContainer.scrollTop = logContainer.scrollHeight;
}
}
toggleDebugger() {
this.debuggerEnabled = !this.debuggerEnabled;
GM_setValue('debuggerEnabled', this.debuggerEnabled);
this.log(`Debugger ${this.debuggerEnabled ? 'enabled' : 'disabled'}`);
if (this.debuggerEnabled && !this.debuggerWindow) {
this.createDebuggerWindow();
} else if (!this.debuggerEnabled && this.debuggerWindow) {
this.debuggerWindow.remove();
this.debuggerWindow = null;
}
}
createDebuggerWindow() {
if (this.debuggerWindow) return; // Prevent cloning
this.debuggerWindow = document.createElement('div');
this.debuggerWindow.className = 'space-debugger';
this.debuggerWindow.innerHTML = `
<div class="debugger-header">🌌 Debugger</div>
<div class="debugger-content"></div>
`;
document.body.appendChild(this.debuggerWindow);
// Restore saved dimensions or use default
const savedDimensions = GM_getValue('debuggerDimensions', { width: '350px', height: '250px' });
this.debuggerWindow.style.width = savedDimensions.width;
this.debuggerWindow.style.height = savedDimensions.height;
// Save dimensions on resize
const resizeObserver = new ResizeObserver(() => {
GM_setValue('debuggerDimensions', {
width: this.debuggerWindow.style.width,
height: this.debuggerWindow.style.height
});
this.log(`Debugger resized to ${this.debuggerWindow.style.width} x ${this.debuggerWindow.style.height}`);
});
resizeObserver.observe(this.debuggerWindow);
this.makeDraggable(this.debuggerWindow, this.debuggerWindow.querySelector('.debugger-header'));
this.updateDebugger();
this.log('Debugger window created');
}
makeDraggable(element, handle) {
let isDragging = false;
let initialX, initialY;
handle.addEventListener('mousedown', (e) => {
isDragging = true;
const rect = element.getBoundingClientRect();
initialX = e.clientX - rect.left;
initialY = e.clientY - rect.top;
e.preventDefault();
});
document.addEventListener('mousemove', (e) => {
if (isDragging) {
element.style.left = `${e.clientX - initialX}px`;
element.style.top = `${e.clientY - initialY}px`;
if (element.classList.contains('dm-menu')) {
element.style.transform = 'scale(1)';
}
}
});
document.addEventListener('mouseup', () => {
if (isDragging && element.classList.contains('dm-menu')) {
GM_setValue('menuPosition', {
left: element.style.left,
top: element.style.top
});
}
isDragging = false;
});
}
}
// Initialize logger
const logger = new Logger();
// Create menu
let menu = null;
function createMenu() {
if (menu) return;
menu = document.createElement('div');
menu.className = 'dm-menu';
menu.innerHTML = `
<div class="dm-menu-header">🌌 Space Menu</div>
<div class="dm-menu-item" data-action="action1">🌑 Action 1</div>
<div class="dm-menu-item" data-action="action2">🌑 Action 2</div>
<div class="dm-menu-footer">
<input type="range" min="0" max="100" value="${GM_getValue('opacity', 100)}" class="opacity-slider">
<label class="debugger-toggle">
<input type="checkbox" class="debugger-slider" ${logger.debuggerEnabled ? 'checked' : ''}>
<span class="slider"></span>
</label>
</div>
`;
document.body.appendChild(menu);
// Restore saved position
const savedPosition = GM_getValue('menuPosition', null);
if (savedPosition) {
menu.style.left = savedPosition.left;
menu.style.top = savedPosition.top;
} else {
menu.style.left = '50%';
menu.style.top = '50%';
menu.style.transform = 'translate(-50%, -50%)';
}
// Restore saved opacity
const savedOpacity = GM_getValue('opacity', 100);
menu.style.opacity = savedOpacity / 100;
logger.makeDraggable(menu, menu.querySelector('.dm-menu-header'));
logger.log('Menu created');
// Restore debugger state without cloning
if (logger.debuggerEnabled && !logger.debuggerWindow) {
logger.createDebuggerWindow();
}
}
// Toggle menu visibility
function toggleMenu() {
if (!menu) {
createMenu();
menu.classList.add('visible');
} else if (menu.classList.contains('visible')) {
menu.classList.remove('visible');
setTimeout(() => {
menu.remove();
menu = null;
}, 300); // Matches transition duration
} else {
createMenu();
menu.classList.add('visible');
}
logger.log(`Menu ${menu && menu.classList.contains('visible') ? 'shown' : 'hidden'}`);
}
// Handle Insert key press
document.addEventListener('keydown', (e) => {
if (e.key === 'Insert') {
e.preventDefault();
toggleMenu();
}
});
// Menu item actions
document.addEventListener('click', (e) => {
const item = e.target.closest('.dm-menu-item');
if (item) {
const action = item.dataset.action;
logger.log(`Menu item clicked: ${action}`);
switch (action) {
case 'action1':
logger.log('Action 1 executed');
alert('Action 1 triggered!');
break;
case 'action2':
logger.log('Action 2 executed');
alert('Action 2 triggered!');
break;
}
}
});
// Debugger toggle slider
document.addEventListener('change', (e) => {
if (e.target.classList.contains('debugger-slider')) {
logger.toggleDebugger();
}
});
// Opacity slider handler
document.addEventListener('input', (e) => {
if (e.target.classList.contains('opacity-slider')) {
const value = e.target.value;
if (menu) {
menu.style.opacity = value / 100;
GM_setValue('opacity', value);
logger.log(`Opacity changed to ${value}%`);
}
}
});
// Error handling
window.addEventListener('error', (e) => {
logger.error(`Error: ${e.message} at ${e.filename}:${e.lineno}`);
});
// Add styles
GM_addStyle(`
.dm-menu, .space-debugger {
position: fixed;
background: linear-gradient(135deg, #1e1b4d 0%, #2a2a72 50%, #3b1a5a 100%);
border-radius: 12px;
padding: 15px;
box-shadow: 0 0 20px rgba(138, 43, 226, 0.5);
z-index: 10000;
user-select: none;
border: 1px solid rgba(147, 112, 219, 0.5);
animation: pulseGlow 3s ease-in-out infinite;
}
@keyframes pulseGlow {
0%, 100% { box-shadow: 0 0 20px rgba(138, 43, 226, 0.5); }
50% { box-shadow: 0 0 30px rgba(138, 43, 226, 0.7); }
}
.dm-menu {
width: 250px;
opacity: 0;
transform: scale(0.8);
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
will-change: opacity, transform;
}
.dm-menu.visible {
display: block;
opacity: 1;
transform: scale(1);
}
.space-debugger {
min-width: 200px;
max-width: 600px;
min-height: 150px;
max-height: 400px;
resize: both;
overflow: hidden;
display: block;
}
.dm-menu-header, .debugger-header {
font-size: 12px;
color: #e6e6fa;
padding: 8px 12px;
font-weight: bold;
text-align: center;
background: rgba(75, 0, 130, 0.2);
border-radius: 8px;
margin-bottom: 10px;
cursor: move;
}
.dm-menu-item {
padding: 10px 12px;
color: #dcdcdc;
border-radius: 6px;
transition: all 0.3s ease;
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
background: rgba(255, 255, 255, 0.05);
margin: 4px 0;
cursor: pointer;
}
.dm-menu-item:hover {
background: linear-gradient(90deg, rgba(138, 43, 226, 0.4), rgba(75, 0, 130, 0.4));
color: #ffffff;
transform: scale(1.05) translateX(8px);
}
.dm-menu-item:active {
transform: scale(0.95);
}
.dm-menu-footer {
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px solid rgba(147, 112, 219, 0.5);
}
.opacity-slider {
width: 60%;
-webkit-appearance: none;
height: 5px;
background: #9370db;
border-radius: 5px;
outline: none;
opacity: 0.7;
transition: opacity 0.3s ease;
}
.opacity-slider:hover {
opacity: 1;
}
.opacity-slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 15px;
height: 15px;
border-radius: 50%;
background: #e6e6fa;
cursor: pointer;
box-shadow: 0 0 8px rgba(186, 85, 211, 0.5);
}
.debugger-toggle {
width: 40px;
height: 20px;
position: relative;
display: inline-block;
}
.debugger-slider {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #2f3136;
transition: 0.4s;
border-radius: 20px;
border: 1px solid #9370db;
}
.slider:before {
position: absolute;
content: "";
height: 14px;
width: 14px;
left: 3px;
bottom: 2px;
background-color: #e6e6fa;
transition: 0.4s;
border-radius: 50%;
box-shadow: 0 0 5px rgba(186, 85, 211, 0.5);
}
.debugger-slider:checked + .slider {
background-color: #ba55d3;
}
.debugger-slider:checked + .slider:before {
transform: translateX(20px);
}
.debugger-content {
padding: 10px;
height: calc(100% - 40px);
overflow-y: auto;
font-size: 12px;
color: #dcdcdc;
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
white-space: normal;
max-width: 100%;
box-sizing: border-box;
background: rgba(255, 255, 255, 0.05);
border-radius: 6px;
}
.log-info {
color: #e6e6fa;
}
.log-error {
color: #ff6b6b;
}
.debugger-content::-webkit-scrollbar {
width: 8px;
}
.debugger-content::-webkit-scrollbar-track {
background: #1e1b4d;
border-radius: 4px;
}
.debugger-content::-webkit-scrollbar-thumb {
background: #9370db;
border-radius: 4px;
}
.debugger-content::-webkit-scrollbar-thumb:hover {
background: #ba55d3;
}
`);
logger.log('Script initialized');
})();