Skip to content

Instantly share code, notes, and snippets.

@mzywiol
Last active December 29, 2023 13:16
Show Gist options
  • Save mzywiol/574b0d66c318530b1fb4 to your computer and use it in GitHub Desktop.
Save mzywiol/574b0d66c318530b1fb4 to your computer and use it in GitHub Desktop.
GreaseMonkey script to copy song lyrics from popular lyrics websites with just one click! Click on a button next to the song text and it'll get copied in its entirety to your clipboard. Works with: lyrics.wikia, A-Z Lyrics, Direct Lyrics, Songtexte, Genius.com, Musixmatch, Lyricsmode, Lyricsfreak, Tekstowo.pl, Sing365. Additionally, it removes f…
// ==UserScript==
// @name Copy lyrics
// @namespace xz
// @description Copy lyrics from popular lyrics websites
// @include http://lyrics.wikia.com/*
// @include http://www.azlyrics.com/*
// @include http://www.directlyrics.com/*
// @include http://www.songtexte.com/*
// @include *genius.com*
// @include *www.musixmatch.com/lyrics/*
// @include *www.lyricsmode.com/lyrics/*
// @include *www.lyricsfreak.com/*
// @include *www.sing365.com/*
// @include *www.tekstowo.pl/piosenka*
// @include *google*/search*lyrics*
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js
// @version 1
// @grant none
// ==/UserScript==
var host = location.hostname;
var lyricboxSelector = undefined;
var triggerSelector = undefined;
var buttonLeft = "30px";
var buttonTop = "30px";
var cleanup = stripHTML;
function replaceAll(string, search, replacement) {
return string.replace(new RegExp(search, 'g'), replacement);
};
function stripScripts(html) {
return replaceAll(html, "<script>.*<\/script>", "");
}
function stripComments(html) {
return replaceAll(html, "<!.*>", "");
}
function stripTags(html) {
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
function joinSoftEnters(html) {
return replaceAll(html, "\n", "");
}
function newlinesFromBr(html) {
return replaceAll(html, "<br\/?>", "\n");
}
function stripHTML(text) {
return stripTags(stripComments(stripScripts(fixEnters(text))));
}
function fixEnters(text) {
return newlinesFromBr(joinSoftEnters(text));
}
function copyLyricsToTextarea(sourceElem, targetId, cleanup) {
var target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = cleanup(sourceElem.innerHTML);
return target;
}
function copyToClipboard(elem, cleanup) {
// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
var target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
var target = copyLyricsToTextarea(elem, targetId, cleanup);
}
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
return succeed;
}
$(function() { (function ($) {
if (host.contains("google")) {
jQuery("a:contains('MetroLyrics')").parentsUntil("div.g").remove()
return 0;
}
switch (host) {
case "lyrics.wikia.com":
lyricboxSelector = "div.lyricbox";
break;
case "www.azlyrics.com":
lyricboxSelector = "div.ringtone ~ div:first";
break;
case "www.directlyrics.com":
triggerSelector = "div.lyricsselect";
lyricboxSelector = "div.lyricsselect p";
buttonTop = "100px";
buttonLeft = "640px";
break;
case "www.songtexte.com":
lyricboxSelector = "div#lyrics";
buttonTop = "150px";
buttonLeft = "50px";
break;
case "genius.com":
lyricboxSelector = "div.song_body-lyrics lyrics";
buttonTop = "10px";
buttonLeft = "490px";
break;
case "www.musixmatch.com":
triggerSelector = "div.container";
lyricboxSelector = "p.mxm-lyrics__content";
cleanup = stripTags;
break;
case "www.lyricsmode.com":
triggerSelector = "div.inner-song-page-content";
lyricboxSelector = "p#lyrics_text";
buttonLeft = "500px";
break;
case "www.lyricsfreak.com":
lyricboxSelector = "div.lyrictxt";
buttonTop = "10px";
buttonLeft = "430px";
break;
case "www.sing365.com":
lyricboxSelector = "div#main section";
triggerSelector = "h1";
buttonTop = "0px";
buttonLeft = "-120px";
cleanup = function(text) {
var text = text.substring(0, text.indexOf("<a")).substring(text.lastIndexOf("</script>") + 9);
return stripHTML(text);
};
break;
case "www.tekstowo.pl":
lyricboxSelector = "div.song-text";
buttonTop = "550px";
buttonLeft = "300px";
cleanup = function(text) {
var text = text.substring(text.indexOf("</h2>") + 5, text.indexOf("<a"));
return stripHTML(text);
};
break;
}
// copy lyrics upon clicking on them on the page
// jQuery(triggerSelector || lyricboxSelector).click(function() {
// if (copyToClipboard(jQuery(lyricboxSelector)[0], cleanup)) {
// window.alert("Lyrics successfully copied!");
// }
// });
// create button on page to copy lyrics
var copyLyricsButton = document.createElement("input");
copyLyricsButton.type = "button";
copyLyricsButton.value = "Copy lyrics";
copyLyricsButton.style.cssText = [
"position: absolute",
"left: " + buttonLeft,
"top: " + buttonTop,
"width: 100px",
"height: 100px",
"border-radius: 50%",
"background-color: #97f",
"border: 4px outset #b9f",
"color: black",
"font-weight: bold",
"font-size: 20px",
"white-space: normal",
"z-index: 1000"
].join(";");
copyLyricsButton.id = "__xz__copyLyricsButton__";
jQuery(triggerSelector || lyricboxSelector).append(copyLyricsButton);
jQuery("input#__xz__copyLyricsButton__").click(function() {
if (copyToClipboard(jQuery(lyricboxSelector)[0], cleanup)) {
var button = jQuery(this);
button.css("background-color", "green");
button.css("border-color", "#2f2");
button.attr("value", "Copied!");
} else {
var button = jQuery(this);
button.css("background-color", "red");
button.css("border-color", "#f22");
button.attr("value", "Failed to copy.");
}
});
})(jQuery)});
@mzywiol
Copy link
Author

mzywiol commented Mar 19, 2016

Added support for Sing365 and commented out alternate trigger for copying: a button that shows up on lyrics page. It's commented out since it's not placed properly on all supported pages. May need to add custop placement coordinates for some pages.

@mzywiol
Copy link
Author

mzywiol commented Mar 25, 2016

Update: added support for Tekstowo.pl and switched to the button trigger as default, instead of clicking on song text.
For some reason Musixmatch doesn't want to cooperate with the button. Will investigate.

@AKASGaming
Copy link

Will this be updated some more? It doesn't work with Musixmatch right now :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment