${JSON.stringify(res, null, 2)}` 442 | } 443 | }) 444 | } 445 | 446 | function showSearchField (query) { 447 | const b = getCleanLyricsContainer() 448 | const div = b.appendChild(document.createElement('div')) 449 | div.style = 'padding:5px' 450 | div.appendChild(document.createTextNode('Search genius.com: ')) 451 | 452 | // Hide button 453 | const hideButton = div.appendChild(document.createElement('a')) 454 | hideButton.href = '#' 455 | hideButton.style = 'float: right; padding-right: 10px;' 456 | hideButton.appendChild(document.createTextNode('Hide')) 457 | hideButton.addEventListener('click', function hideButtonClick (ev) { 458 | ev.preventDefault() 459 | hideLyrics() 460 | }) 461 | 462 | const br = div.appendChild(document.createElement('br')) 463 | br.style.clear = 'right' 464 | 465 | div.style.paddingRight = '15px' 466 | const input = div.appendChild(document.createElement('input')) 467 | input.style = 'width:92%;border:0;border-radius:500px;padding:8px 5px 8px 25px;text-overflow:ellipsis' 468 | input.placeholder = 'Search genius.com...' 469 | if (query) { 470 | input.value = query 471 | } else if (genius.current.compoundTitle) { 472 | input.value = genius.current.compoundTitle.replace('\t', ' ') 473 | } else if (genius.current.artists && genius.current.title) { 474 | input.value = genius.current.artists + ' ' + genius.current.title 475 | } else if (genius.current.artists) { 476 | input.value = genius.current.artists 477 | } 478 | input.addEventListener('focus', function onSearchLyricsButtonFocus () { 479 | this.style.color = 'black' 480 | }) 481 | input.addEventListener('change', function onSearchLyricsButtonClick () { 482 | this.style.color = 'black' 483 | if (input.value) { 484 | startSearch(input.value, b) 485 | } 486 | }) 487 | input.addEventListener('keyup', function onSearchLyricsKeyUp (ev) { 488 | this.style.color = 'black' 489 | if (ev.code === 'Enter' || ev.code === 'NumpadEnter') { 490 | ev.preventDefault() 491 | if (input.value) { 492 | startSearch(input.value, b) 493 | } 494 | } 495 | }) 496 | input.focus() 497 | const mag = div.appendChild(document.createElement('div')) 498 | mag.style.marginTop = '-27px' 499 | mag.style.marginLeft = '3px' 500 | mag.appendChild(document.createTextNode('🔎')) 501 | } 502 | 503 | function addLyricsButton () { 504 | if (document.getElementById('showlyricsbutton')) { 505 | return 506 | } 507 | const b = document.createElement('div') 508 | b.setAttribute('id', 'showlyricsbutton') 509 | b.setAttribute('style', 'position:absolute; top: 0px; right:0px; font-size:14px; color:#ffff64; cursor:pointer; z-index:3000;') 510 | b.setAttribute('title', 'Load lyrics from genius.com') 511 | b.appendChild(document.createTextNode('🅖')) 512 | b.addEventListener('click', function onShowLyricsButtonClick () { 513 | genius.option.autoShow = true // Temporarily enable showing lyrics automatically on song change 514 | window.clearInterval(genius.iv.main) 515 | genius.iv.main = window.setInterval(main, 2000) 516 | b.remove() 517 | addLyrics(true) 518 | }) 519 | document.body.appendChild(b) 520 | if (b.clientWidth < 10) { 521 | b.setAttribute('style', 'position:absolute; top: 0px; right:0px; font-size:14px; background-color:#0007; color:#ffff64; cursor:pointer; z-index:3000;border:1px solid #ffff64;border-radius: 100%;padding: 0px 5px;font-size: 10px;') 522 | b.innerHTML = 'G' 523 | } 524 | } 525 | 526 | function configShowSpotifyLyrics (div) { 527 | // Input: Show lyrics from Spotify if no lyrics found on genius.com 528 | const id = 'input945455' 529 | 530 | const input = div.appendChild(document.createElement('input')) 531 | input.type = 'checkbox' 532 | input.id = id 533 | GM.getValue('show_spotify_lyrics', true).then(function (v) { 534 | input.checked = v 535 | }) 536 | 537 | const label = div.appendChild(document.createElement('label')) 538 | label.setAttribute('for', id) 539 | label.appendChild(document.createTextNode('Open lyrics from Spotify if no lyrics found on genius.com')) 540 | 541 | const onChange = function onChangeListener () { 542 | GM.setValue('show_spotify_lyrics', input.checked) 543 | } 544 | input.addEventListener('change', onChange) 545 | } 546 | 547 | function configSubmitSpotifyLyrics (div) { 548 | // Input: Submit lyrics from Spotify to genius.com 549 | const id = 'input337565' 550 | 551 | const input = div.appendChild(document.createElement('input')) 552 | input.type = 'checkbox' 553 | input.id = id 554 | input.setAttribute('title', '...in case Spotify has lyrics that genius.com does not have') 555 | GM.getValue('submit_spotify_lyrics', true).then(function (v) { 556 | input.checked = v 557 | }) 558 | 559 | const label = div.appendChild(document.createElement('label')) 560 | label.setAttribute('for', id) 561 | label.appendChild(document.createTextNode('Suggest to submit lyrics from Spotify to genius.com')) 562 | label.setAttribute('title', '...in case Spotify has lyrics that genius.com does not have') 563 | 564 | const onChange = function onChangeListener () { 565 | GM.setValue('submit_spotify_lyrics', input.checked) 566 | } 567 | input.addEventListener('change', onChange) 568 | } 569 | 570 | function configHideSpotifySuggestions (div) { 571 | // Input: Hide suggestions and hints from Spotify about new features 572 | const id = 'input875687' 573 | 574 | const input = div.appendChild(document.createElement('input')) 575 | input.type = 'checkbox' 576 | input.id = id 577 | input.setAttribute('title', 'Hide suggestions and hints from Spotify about new features') 578 | GM.getValue('hide_spotify_suggestions', true).then(function (v) { 579 | input.checked = v 580 | }) 581 | 582 | const label = div.appendChild(document.createElement('label')) 583 | label.setAttribute('for', id) 584 | label.appendChild(document.createTextNode('Hide suggestions and hints from Spotify about new features')) 585 | 586 | const onChange = function onChangeListener () { 587 | GM.setValue('hide_spotify_suggestions', input.checked) 588 | } 589 | input.addEventListener('change', onChange) 590 | } 591 | 592 | function configHideSpotifyNowPlayingView (div) { 593 | // Input: Hide "Now Playing View" 594 | const id = 'input12567826' 595 | 596 | const input = div.appendChild(document.createElement('input')) 597 | input.type = 'checkbox' 598 | input.id = id 599 | input.setAttribute('title', 'Hide Spotify\'s "Now Playing View"') 600 | GM.getValue('hide_spotify_now_playing_view', true).then(function (v) { 601 | input.checked = v 602 | }) 603 | 604 | const label = div.appendChild(document.createElement('label')) 605 | label.setAttribute('for', id) 606 | label.appendChild(document.createTextNode('Hide Spotify\'s "Now Playing View"')) 607 | 608 | const onChange = function onChangeListener () { 609 | GM.setValue('hide_spotify_now_playing_view', input.checked) 610 | } 611 | input.addEventListener('change', onChange) 612 | } 613 | 614 | function addCss () { 615 | document.head.appendChild(document.createElement('style')).innerHTML = ` 616 | .lyricsiframe { 617 | opacity:0.1; 618 | transition:opacity 2s; 619 | margin:0px; 620 | padding:0px; 621 | } 622 | .loadingspinnerholder { 623 | position:absolute; 624 | top:100px; 625 | left:100px; 626 | cursor:progress 627 | } 628 | .lyricsnavbar { 629 | background-color: rgb(80, 80, 80); 630 | background-image: linear-gradient(rgba(0, 0, 0, 0.6), rgb(18, 18, 18)); 631 | border-radius: 8px 8px 0px 0px; 632 | margin: 8px 0px 0px 0px; 633 | padding:0px 10px; 634 | } 635 | 636 | .lyricsnavbar span,.lyricsnavbar a:link,.lyricsnavbar a:visited { 637 | color: rgb(179, 179, 179); 638 | text-decoration:none; 639 | transition:color 400ms; 640 | } 641 | .lyricsnavbar a:hover,.lyricsnavbar span:hover { 642 | color:white; 643 | text-decoration:none; 644 | } 645 | .lyricsnavbar .second-line-separator,.lyricsnavbar .second-line-separator:hover { 646 | padding:0px 10px !important; 647 | color: transparent; 648 | vertical-align: text-bottom; 649 | } 650 | .geniushits li.tracklist-row { 651 | cursor:pointer 652 | } 653 | .geniushits li.tracklist-row:hover { 654 | background-color: #fff5; 655 | border-radius: 5px; 656 | } 657 | .geniushits li .geniushiticonout { 658 | display:inline-block; 659 | } 660 | .geniushits li:hover .geniushiticonout { 661 | display:none 662 | } 663 | .geniushits li .geniushiticonover { 664 | display:none 665 | } 666 | .geniushits li:hover .geniushiticonover { 667 | display:inline-block; 668 | padding-top:5px; 669 | } 670 | .geniushiticon { 671 | width:25px; 672 | height:2em; 673 | display:inline-block; 674 | vertical-align: top; 675 | } 676 | .geniushitname { 677 | display:inline-block; 678 | position: relative; 679 | overflow:hidden 680 | } 681 | .geniushitname .tracklist-name { 682 | font-size: 16px; 683 | font-weight: 400; 684 | color:white; 685 | } 686 | .geniushitname.runningtext .tracklist-name { 687 | display: inline-block; 688 | position: relative; 689 | animation: 3s linear 1s infinite normal runtext; 690 | } 691 | 692 | .geniushitname.runningtext:hover .tracklist-name { 693 | animation: none !important; 694 | } 695 | 696 | .geniushits .second-line-separator { 697 | opacity: 0.7 698 | } 699 | 700 | .geniushitname .geniusbadge { 701 | color: #121212; 702 | background-color: hsla(0,0%,100%,.6); 703 | border-radius: 2px; 704 | text-transform: uppercase; 705 | font-size: 9px; 706 | line-height: 10px; 707 | min-width: 16px; 708 | height: 16px; 709 | padding: 0 2px; 710 | margin: 0 3px; 711 | } 712 | 713 | @keyframes runtext { 714 | 0%, 25% { 715 | transform: translateX(0%); 716 | left: 0%; 717 | } 718 | 75%, 100% { 719 | transform: translateX(-100%); 720 | left: 100%; 721 | } 722 | } 723 | 724 | ` 725 | } 726 | 727 | function styleIframeContent () { 728 | if (genius.option.themeKey === 'genius' || genius.option.themeKey === 'geniusReact') { 729 | genius.style.enabled = true 730 | genius.style.setup = () => { 731 | genius.style.setup = null // run once; set variables to genius.styleProps 732 | if (genius.option.themeKey !== 'genius' && genius.option.themeKey !== 'geniusReact') { 733 | genius.style.enabled = false 734 | return false 735 | } 736 | return true 737 | } 738 | } else { 739 | genius.style.enabled = false 740 | genius.style.setup = null 741 | } 742 | } 743 | 744 | function main () { 745 | if (document.querySelector('.Root [data-testid="player-controls"] [data-testid="playback-progressbar"]') && document.querySelector(songTitleQuery)) { 746 | if (genius.option.autoShow) { 747 | addLyrics() 748 | } else { 749 | addLyricsButton() 750 | } 751 | } 752 | } 753 | 754 | if (document.location.hostname === 'genius.com') { 755 | // https://genius.com/songs/new 756 | fillGeniusForm() 757 | } else { 758 | window.setInterval(function removeAds () { 759 | // Remove "premium" button 760 | try { 761 | const button = document.querySelector('button[class^=Button][aria-label*=Premium]') 762 | if (button) { 763 | button.style.display = 'none' 764 | } 765 | } catch (e) { 766 | console.warn(e) 767 | } 768 | // Remove "install app" button 769 | try { 770 | const button = document.querySelector('a[href*="/download"]') 771 | if (button) { 772 | button.style.display = 'none' 773 | } 774 | } catch (e) { 775 | console.warn(e) 776 | } 777 | // Remove iframe "GET 3 MONTHS FREE" 778 | try { 779 | const iframe = document.querySelector('iframe[data-testid="inAppMessageIframe"]') 780 | if (iframe && iframe.contentDocument && iframe.contentDocument.body) { 781 | iframe.contentDocument.body.querySelectorAll('button').forEach(function (button) { 782 | if (button.parentNode.innerHTML.indexOf('Dismiss_action') !== -1) { 783 | button.click() 784 | } 785 | }) 786 | } 787 | } catch (e) { 788 | console.warn(e) 789 | } 790 | // Remove another iframe "GET 3 MONTHS FREE" 791 | try { 792 | const iframe = document.querySelector('.ReactModalPortal iframe[srcdoc*="/purchase/"]') 793 | if (iframe && iframe.contentDocument && iframe.contentDocument.body) { 794 | const dismissButtons = Array.from(iframe.contentDocument.body.querySelectorAll('button')).filter(b => b.textContent.toLowerCase().includes('dismiss')) 795 | if (dismissButtons.length) { 796 | dismissButtons[0].click() 797 | } 798 | const nonUrlButtons = Array.from(iframe.contentDocument.body.querySelectorAll('button')).filter(b => b.dataset.clickToActionAction !== 'URL') 799 | if (nonUrlButtons.length) { 800 | nonUrlButtons[0].click() 801 | } 802 | } 803 | } catch (e) { 804 | console.warn(e) 805 | } 806 | 807 | GM.getValue('hide_spotify_suggestions', true).then(function (hideSuggestions) { 808 | if (hideSuggestions) { 809 | // Remove hints and suggestions 810 | document.querySelectorAll('.encore-announcement-set button[class*="Button-"]').forEach(b => b.click()) 811 | // Check "show never again" 812 | document.querySelectorAll('#dont.show.onboarding.npv').forEach(c => (c.checked = true)) 813 | // Close bubble 814 | document.querySelectorAll('.tippy-box button[class*="Button-"]').forEach(b => b.click()) 815 | } 816 | }) 817 | 818 | GM.getValue('hide_spotify_now_playing_view', true).then(function (hideNowPlaying) { 819 | if (hideNowPlaying) { 820 | // Close "Now Playing View" 821 | // New: 2025-04 822 | document.querySelectorAll('[data-testid="control-button-npv"][data-active="true"]').forEach(function (b) { 823 | b.click() 824 | }) 825 | // Old: 2024-10 826 | document.querySelectorAll('#Desktop_PanelContainer_Id [data-testid="PanelHeader_CloseButton"] button[class*="Button-"]').forEach(function (b) { 827 | if (b.parentNode.previousElementSibling && b.parentNode.previousElementSibling.querySelector('button[data-testid="more-button"]')) { 828 | // Second button is the "Now Playing View" button but not in the "Queue view" 829 | b.click() 830 | } 831 | }) 832 | } 833 | }) 834 | }, 3000) 835 | 836 | genius = geniusLyrics({ 837 | GM, 838 | scriptName, 839 | scriptIssuesURL: 'https://github.com/cvzi/Spotify-Genius-Lyrics-userscript/issues', 840 | scriptIssuesTitle: 'Report problem: github.com/cvzi/Spotify-Genius-Lyrics-userscript/issues', 841 | domain: 'https://open.spotify.com', 842 | emptyURL: 'https://open.spotify.com/robots.txt', 843 | main, 844 | addCss, 845 | listSongs, 846 | showSearchField, 847 | addLyrics, 848 | hideLyrics, 849 | getCleanLyricsContainer, 850 | setFrameDimensions, 851 | initResize, 852 | onResize, 853 | config: [ 854 | configShowSpotifyLyrics, 855 | configSubmitSpotifyLyrics, 856 | configHideSpotifySuggestions, 857 | configHideSpotifyNowPlayingView 858 | ], 859 | toggleLyricsKey: { 860 | shiftKey: true, 861 | ctrlKey: false, 862 | altKey: false, 863 | key: 'L' 864 | }, 865 | onNoResults, 866 | onNewSongPlaying 867 | }) 868 | 869 | genius.option.enableStyleSubstitution = true 870 | genius.option.cacheHTMLRequest = true // 1 lyrics page consume 2XX KB [OR 25 ~ 50KB under ] 871 | 872 | genius.onThemeChanged.push(styleIframeContent) 873 | 874 | GM.registerMenuCommand(scriptName + ' - Show lyrics', () => addLyrics(true)) 875 | GM.registerMenuCommand(scriptName + ' - Options', () => genius.f.config()) 876 | GM.registerMenuCommand(scriptName + ' - Submit lyrics to Genius', () => submitLyricsFromMenu()) 877 | window.setInterval(updateAutoScroll, 1000) 878 | window.setInterval(improveLyricsPaywall, 10000) 879 | } 880 | -------------------------------------------------------------------------------- /archive/2023-08-28/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvzi/Spotify-Genius-Lyrics-userscript/081d6d9bda5cf664a8f97b2fd9cb147653093a78/archive/2023-08-28/screenshot.png -------------------------------------------------------------------------------- /archive/2023-08-28/screenshotReactGeniusTheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvzi/Spotify-Genius-Lyrics-userscript/081d6d9bda5cf664a8f97b2fd9cb147653093a78/archive/2023-08-28/screenshotReactGeniusTheme.png -------------------------------------------------------------------------------- /archive/2023-08-28/screenshotReactSpotifyTheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvzi/Spotify-Genius-Lyrics-userscript/081d6d9bda5cf664a8f97b2fd9cb147653093a78/archive/2023-08-28/screenshotReactSpotifyTheme.png -------------------------------------------------------------------------------- /keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvzi/Spotify-Genius-Lyrics-userscript/081d6d9bda5cf664a8f97b2fd9cb147653093a78/keyboard.png -------------------------------------------------------------------------------- /screenshotGeniusTheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvzi/Spotify-Genius-Lyrics-userscript/081d6d9bda5cf664a8f97b2fd9cb147653093a78/screenshotGeniusTheme.png -------------------------------------------------------------------------------- /screenshotSpotifyTheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvzi/Spotify-Genius-Lyrics-userscript/081d6d9bda5cf664a8f97b2fd9cb147653093a78/screenshotSpotifyTheme.png -------------------------------------------------------------------------------- /screenshotWhiteTheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvzi/Spotify-Genius-Lyrics-userscript/081d6d9bda5cf664a8f97b2fd9cb147653093a78/screenshotWhiteTheme.png --------------------------------------------------------------------------------