Greasy Fork is available in English.
Adds a button to copy lyrics from Genius.com
- // ==UserScript==
- // @name Copy Genius Lyrics
- // @namespace http://tampermonkey.net/
- // @version 1.1
- // @description Adds a button to copy lyrics from Genius.com
- // @match https://genius.com/*
- // @grant GM_addStyle
- // @license MIT
- // ==/UserScript==
- (function () {
- 'use strict';
- /** Error logging */
- const logError = (error, context) => console.error(`[Copy Genius Lyrics] Error in ${context}:`, error);
- /** Copies lyrics to clipboard */
- const copyLyrics = () => {
- try {
- const lyrics = [...document.querySelectorAll('[data-lyrics-container="true"]')]
- .map(container => container.innerText.trim())
- .join('\n\n');
- if (!lyrics) {
- showNotification('No lyrics found.');
- return;
- }
- navigator.clipboard.writeText(lyrics)
- .then(() => showNotification('Lyrics copied!'))
- .catch(error => {
- logError(error, 'copyLyrics (clipboard)');
- showNotification('Failed to copy.');
- });
- } catch (error) {
- logError(error, 'copyLyrics');
- showNotification('An error occurred.');
- }
- };
- /** Displays a notification message */
- const showNotification = (message) => {
- try {
- const notification = document.createElement('div');
- notification.className = 'copy-lyrics-notification';
- notification.textContent = message;
- document.body.appendChild(notification);
- setTimeout(() => {
- notification.style.opacity = '0';
- setTimeout(() => notification.remove(), 500);
- }, 2000);
- } catch (error) {
- logError(error, 'showNotification');
- }
- };
- /** Initializes the copy button and injects it into the DOM */
- const initCopyButton = () => {
- try {
- const button = document.createElement('button');
- button.id = 'copy-lyrics-button';
- button.textContent = 'Copy Lyrics';
- button.addEventListener('click', copyLyrics);
- const targetContainer = document.querySelector('.dRuelM'); // Update if Genius changes its class names
- if (targetContainer) {
- targetContainer.appendChild(button);
- } else {
- logError('Target container not found (dRuelM)', 'DOM initialization');
- }
- } catch (error) {
- logError(error, 'initCopyButton');
- }
- };
- /** Injects custom styles for the button and notification */
- const injectStyles = () => {
- GM_addStyle(`
- #copy-lyrics-button {
- margin-top: 10px;
- padding: 10px 15px;
- font-size: 16px;
- background-color: #1db954;
- color: white;
- border: none;
- border-radius: 5px;
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
- cursor: pointer;
- transition: background-color 0.2s ease-in-out;
- }
- #copy-lyrics-button:hover {
- background-color: #1ed760;
- }
- .copy-lyrics-notification {
- position: fixed;
- bottom: 20px;
- right: 20px;
- padding: 10px 20px;
- background-color: #1db954;
- color: white;
- font-size: 14px;
- border-radius: 5px;
- opacity: 0;
- animation: fadeInOut 2.5s forwards;
- z-index: 1000;
- }
- @keyframes fadeInOut {
- 0% { opacity: 0; transform: translateY(20px); }
- 10% { opacity: 1; transform: translateY(0); }
- 90% { opacity: 1; transform: translateY(0); }
- 100% { opacity: 0; transform: translateY(20px); }
- }
- `);
- };
- /** Initializes the script */
- const init = () => {
- injectStyles();
- initCopyButton();
- };
- // Run script after page load
- window.addEventListener('load', init);
- })();