您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds shortcuts to get across the site faster
当前为
// ==UserScript== // @name Edio Hotkeys // @namespace http://tampermonkey.net/ // @version Alpha-v3 // @description Adds shortcuts to get across the site faster // @author Crowned Studios // @license CC BY-NC // @match https://www.myedio.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_cookieSet // @grant GM_cookieDelete // ==/UserScript== /* _ _ _ _ _____ | | | | | | | | _| __ \ | |__| | ___ | |_| | _____ _ _ ___ (_) | | | | __ |/ _ \| __| |/ / _ \ | | / __| | | | | | | | | (_) | |_| < __/ |_| \__ \ _| |__| | |_| |_|\___/ \__|_|\_\___|\__, |___/ (_)_____/ __/ | |___/ */ // === User Configurable Settings === // Set this to true to enable console logging, or false to disable it. const isLoggingEnabled = true; // === End Of Configurable Settings === (function() { 'use strict'; function logMessage(message) { if (isLoggingEnabled) { console.log(message); } } function saveLinkIfMatches() { const link = window.location.href; const matchPatterns = [ "https://www.myedio.com/learning/courses/", "/lessons/", "/summary/" ]; if (matchPatterns.every(pattern => link.includes(pattern))) { try { GM_setValue('siteLink', link); logMessage(`Link saved using GM_setValue: ${link}`); } catch (e) { logMessage("Error saving with GM_setValue, falling back to cookies..."); showErrorPopup(101, e.message); document.cookie = `siteLink=${link}; path=/; expires=${new Date(Date.now() + 86400000).toUTCString()}`; logMessage("Link saved to cookie: " + link); } } else { logMessage("Link does not match the pattern, not saved."); } } function getSavedLink() { return new Promise((resolve, reject) => { const gmLink = GM_getValue('siteLink', null); if (gmLink) { resolve(gmLink); } else { const cookieMatch = document.cookie.match(/siteLink=([^;]*)/); if (cookieMatch) { resolve(cookieMatch[1]); } else { showErrorPopup(102, "No site link found, or It was never saved."); reject("No site link found, or It was never saved."); } } }); } async function handleHotkeys(event) { if (event.altKey) { const key = event.key.toLowerCase(); switch (key) { case 'r': event.preventDefault(); try { const savedLink = await getSavedLink(); logMessage(`Redirecting to saved link: ${savedLink}`); window.location.href = savedLink; } catch (e) { logMessage(e); showErrorPopup(103, "Error redirecting to saved link."); } break; case 'c': event.preventDefault(); window.location.href = "https://www.myedio.com/calendar/day/"; break; case 'q': event.preventDefault(); window.location.href = "https://www.myedio.com/login/?sessionExpired=true"; break; case 'd': event.preventDefault(); window.location.href = "https://www.myedio.com/dashboard/"; break; case 'l': event.preventDefault(); alert("Test successful!"); break; default: handleCustomHotkeys(key); break; } } } function handleCustomHotkeys(key) { const customHotkeys = GM_getValue('customHotkeys', {}); if (customHotkeys[key]) { window.location.href = customHotkeys[key]; } } function showErrorPopup(errorNumber, errorMessage) { if (document.querySelector('.error-overlay')) return; const overlay = document.createElement('div'); overlay.classList.add('error-overlay'); const overlayContent = document.createElement('div'); overlayContent.classList.add('error-overlay-content'); overlayContent.innerHTML = ` <h2>Error ${errorNumber}</h2> <p>${errorMessage}</p> `; const closeButton = document.createElement('button'); closeButton.innerHTML = 'Close'; closeButton.addEventListener('click', () => { document.body.removeChild(overlay); document.body.removeChild(overlayBackground); document.body.style.overflow = ''; document.body.style.userSelect = ''; }); overlayContent.appendChild(closeButton); overlay.appendChild(overlayContent); document.body.appendChild(overlay); const overlayBackground = document.createElement('div'); overlayBackground.classList.add('error-overlay-background'); document.body.appendChild(overlayBackground); document.body.style.overflow = 'hidden'; document.body.style.userSelect = 'none'; } function addHotkeysElement() { if (document.querySelector('.c-navigation__item.hotkeys-item')) return; const newElement = document.createElement('li'); newElement.classList.add('c-navigation__item', 'hotkeys-item'); newElement.innerHTML = ` <a class="" target="" title="Hotkeys"> <span>Hotkeys</span> </a> `; const navigationElement = document.querySelector('.c-navigation'); if (navigationElement) navigationElement.appendChild(newElement); newElement.addEventListener('click', showHotkeysOverlay); observeSidebarToggle(newElement); } function observeSidebarToggle(hotkeysElement) { const toggleButton = document.querySelector('.c-button.-icon.c-sidebar__toggle'); if (toggleButton) { const observer = new MutationObserver(() => { const isExpanded = toggleButton.getAttribute('aria-expanded') === 'true'; const span = hotkeysElement.querySelector('span'); span.textContent = isExpanded ? 'Hotkeys' : 'HK'; }); observer.observe(toggleButton, { attributes: true, attributeFilter: ['aria-expanded'] }); } } function showHotkeysOverlay() { const overlay = document.createElement('div'); overlay.classList.add('hotkeys-overlay'); const overlayContent = document.createElement('div'); overlayContent.classList.add('hotkeys-overlay-content'); const userNameElement = document.querySelector('.c-avatar__name'); let userName = userNameElement ? userNameElement.textContent.trim() : "User"; function toTitleCase(str) { return str.replace(/\b\w/g, char => char.toUpperCase()); } userName = toTitleCase(userName); overlayContent.innerHTML = ` <h2>List of Hotkeys</h2> <p><strong>Logout:</strong> Alt + Q</p> <p><strong>Calendar:</strong> Alt + C</p> <p><strong>Dashboard:</strong> Alt + D</p> <p><strong>Return to Course Link:</strong> Alt + R</p> <p><strong>Test Key:</strong> Alt + L</p> <p><strong>Custom Hotkeys:</strong></p> <ul id="custom-hotkeys-list"></ul> <p>Hello ${userName}! You are running the Alpha version of <strong>Edio Hotkeys</strong>. There is still lots of development needed for this script, including one known error, but please enjoy what you currently have!</p> <button id="add-custom-hotkey">Add Custom Hotkey (Experimental)</button> `; const closeButton = document.createElement('button'); closeButton.innerHTML = 'Close'; closeButton.addEventListener('click', () => { document.body.removeChild(overlay); document.body.removeChild(overlayBackground); document.body.style.overflow = ''; document.body.style.userSelect = ''; }); overlayContent.appendChild(closeButton); overlay.appendChild(overlayContent); document.body.appendChild(overlay); const overlayBackground = document.createElement('div'); overlayBackground.classList.add('hotkeys-overlay-background'); document.body.appendChild(overlayBackground); document.body.style.overflow = 'hidden'; document.body.style.userSelect = 'none'; displayCustomHotkeys(); document.getElementById('add-custom-hotkey').addEventListener('click', addCustomHotkey); } function displayCustomHotkeys() { const customHotkeys = GM_getValue('customHotkeys', {}); const customHotkeysList = document.getElementById('custom-hotkeys-list'); customHotkeysList.innerHTML = ''; for (const [key, url] of Object.entries(customHotkeys)) { const li = document.createElement('li'); li.textContent = `Alt + ${key.toUpperCase()}: ${url}`; customHotkeysList.appendChild(li); } } function addCustomHotkey() { const key = prompt("Enter the key for the custom hotkey (e.g., 'n' for Alt+N):"); const url = prompt("Enter the URL to be associated with this hotkey:"); if (key && url) { const customHotkeys = GM_getValue('customHotkeys', {}); customHotkeys[key.toLowerCase()] = url; GM_setValue('customHotkeys', customHotkeys); displayCustomHotkeys(); } } const style = document.createElement('style'); style.innerHTML = ` .c-navigation__item.hotkeys-item a { display: flex; align-items: center; color: #333; font-size: 16px; text-decoration: none; padding: 10px; border-radius: 4px; transition: background-color 0.2s ease, transform 0.2s ease; cursor: pointer; } .c-navigation__item.hotkeys-item a:hover { background-color: #f4f4f4; transform: translateX(5px); cursor: pointer; } .hotkeys-overlay-background { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.8); z-index: 1000; pointer-events: none; } .hotkeys-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 1001; display: flex; justify-content: center; align-items: center; opacity: 0; animation: fadeIn 0.3s forwards; } .hotkeys-overlay-content { background: #ffffff; padding: 30px 25px; border-radius: 5px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); max-width: 600px; text-align: center; } .hotkeys-overlay-content h2 { margin-bottom: 20px; font-size: 24px; } .hotkeys-overlay-content p { margin-bottom: 15px; font-size: 16px; } .hotkeys-overlay-content ul { list-style: none; padding: 0; } .hotkeys-overlay-content ul li { margin-bottom: 5px; font-size: 16px; } .hotkeys-overlay-content button { background-color: #007BFF; color: white; border: none; padding: 10px 20px; font-size: 14px; cursor: pointer; border-radius: 4px; margin-top: 20px; } .hotkeys-overlay-content button:hover { background-color: #0056b3; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .error-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 1001; display: flex; justify-content: center; align-items: center; background-color: rgba(0, 0, 0, 0.8); } .error-overlay-content { background: #ffebee; padding: 20px; border-radius: 5px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); max-width: 500px; text-align: center; } .error-overlay-content h2 { margin-bottom: 15px; font-size: 20px; color: #d32f2f; } .error-overlay-content p { margin-bottom: 15px; font-size: 16px; color: #333; } .error-overlay-content button { background-color: #d32f2f; color: white; border: none; padding: 10px 20px; font-size: 14px; cursor: pointer; border-radius: 4px; margin-top: 10px; } .error-overlay-content button:hover { background-color: #b71c1c; } `; document.head.appendChild(style); saveLinkIfMatches(); window.addEventListener('keydown', handleHotkeys); setInterval(() => { addHotkeysElement(); }, 10); })();