Skip to content

Instantly share code, notes, and snippets.

@jesus2099
Created November 19, 2012 16:23
Show Gist options
  • Save jesus2099/4111606 to your computer and use it in GitHub Desktop.
Save jesus2099/4111606 to your computer and use it in GitHub Desktop.
autoselecting normal text on mouse hover experiment (works after 666 milliseconds)
// ==UserScript==
// @name MB. entity icons + shorten and embelish MB links
// @version 2012.1105.1202+autoselect
// @description musicbrainz.org: In some pages like edits, blog, forums, chatlogs, tickets, annotations, etc. it will prefix entity links with an icon, shorten and embelish all sorts of MB links (entities, tickets, bugs, edits, etc.).
// @namespace http://userscripts.org/scripts/show/131731
// @author Tristan DANIEL (PATATE12 aka. jesus2099/shamo)
// @licence CC BY-NC-SA 3.0 FR (http://creativecommons.org/licenses/by-nc-sa/3.0/fr/)
// @grant none
// @match *://*.musicbrainz.org/*
// @run-at document-end
// ==/UserScript==
if(self.location.href.match(/^https?:\/\/([^.]+\.)?musicbrainz\.org\/.*$/)){/*@matchopera*/(function(){"use strict";
/* -------- CONFIGURATION START (don't edit above) -------- */
var confirmIfMoreThan = 2000;/*-1 to never confirm*/
var autoselect = true;
/* -------- CONFIGURATION END (don't edit below) -------- */
var userjs = "jesus2099userjs131731";
var MBS = self.location.protocol+"//"+self.location.host.replace(/^([^.]+\.)?(musicbrainz\.org)$/, "$2");
var dialogprefix = "..:: ENTITY ICONS :: LINK EMBELISHER ::..\n\n";
var to, tonode;
var entities = {
"artist": {"path":"/artist/", "icon":"artist"},
"work": {"path":"/work/", "icon":"blank"},
"release-group": {"path":"/release-group/", "icon":"release_group"},
"release": {"path":"/release/", "icon":"release"},
"recording": {"path":"/recording/", "icon":"recording"},
"track": {"path":"/track/", "icon":"recording"},
"label": {"path":"/label/", "icon":"label"},
"edit": {"path":"/edit/", "id": "[0-9]+", "label":"edit\u00a0#%id%"},
"classic.edit": {"path":"/show/edit/?editid=", "id": "[0-9]+", "label":"edit\u00a0#%id%"},
"user": {"path":"/user/", "id": ".+"},
"classic.user": {"path":"/show/user/?username=", "id": ".+"},
"bug": {"fullpath":"http://bugs.musicbrainz.org/ticket/", "id": "[0-9]+", "label":"#%id%"},
"ticket": {"fullpath":"http://tickets.musicbrainz.org/browse/", "id": "[A-Za-z]+-[0-9]+", "label":"%id%"},
};
document.head.appendChild(document.createElement("style")).setAttribute("type", "text/css");
var ss = document.styleSheets[document.styleSheets.length-1];
ss.insertRule("a."+userjs+" {text-shadow:1px 1px 2px silver;white-space:nowrap}", ss.cssRules.length);
for (var ent in entities) {
if (entities.hasOwnProperty(ent)) {
var u = (entities[ent].fullpath?entities[ent].fullpath:"musicbrainz.org"+entities[ent].path.replace("?", "\\?"));
var c = userjs+ent;
if (entities[ent].icon) {
ss.insertRule("a."+c+"::before {content:url("+MBS+"/static/images/entity/"+entities[ent].icon+".png)!important;margin-right:4px!important;vertical-align:-25%!important;}", ss.cssRules.length);
}
var as;
if (entities[ent].fullpath) {
as = document.querySelectorAll("a[href^='"+u+"']");
}
else if (self.location.href.match(new RegExp("^https?://(test\.|beta\.|classic\.)?musicbrainz\.org"))) {
as = document.querySelectorAll(
"table.details a[href*='://"+u+"'], "+
"table.details a[href*='://test."+u+"'], "+
"table.details a[href*='://beta."+u+"'], "+
"table.details a[href*='://classic."+u+"'][href$='.html'], "+
"div.annotation a[href*='://"+u+"'], "+
"div.annotation a[href*='://test."+u+"'], "+
"div.annotation a[href*='://beta."+u+"'], "+
"div.annotation a[href*='://classic."+u+"'][href$='.html'], "+
"div[class^='edit-'] a[href*='://"+u+"'], "+
"div[class^='edit-'] a[href*='://test."+u+"'], "+
"div[class^='edit-'] a[href*='://beta."+u+"'], "+
"div[class^='edit-'] a[href*='://classic."+u+"'][href$='.html']"
);
}
else {
as = document.querySelectorAll(
"a[href*='://"+u+"'], "+
"a[href*='://test."+u+"'], "+
"a[href*='://beta."+u+"'], "+
"a[href*='://classic."+u+"'][href$='.html']"
);
}
if (confirmIfMoreThan < 0 || (as.length <= confirmIfMoreThan || as.length > confirmIfMoreThan && confirm(dialogprefix+"There are "+as.length+" "+ent.toUpperCase()+"S to decorate on this page.\nThis can take a great while.\n\nPress OK if you still want to decorate those "+ent+"s or\npress CANCEL if you want to skip it this time."))) {
for (var a=0; a<as.length; a++) {
var href, id;
if (
(href = as[a].getAttribute("href")) &&
(id = href.match(new RegExp(u+"("+(entities[ent].id?entities[ent].id:"[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}")+")(?:\.html)?(/[a-z_-]+)?(?:.*(#[a-z0-9_-]+))?$", "i"))) &&
!as[a].querySelector("img:not(.rendericon)")
) {
var altserv = href.match(/^https?:\/\/(?:(test|beta|classic)\.)/);
as[a].className += " "+c;
if (autoselect) {
as[a].addEventListener("mouseover", function(e) { tonode = this; to = setTimeout(selectNode, 666); }, false);
as[a].addEventListener("mouseout", function(e) { if (to) { clearTimeout(to); clearSelection(); to = null; } }, false);
}
if (as[a].textContent == href || /*forums*/as[a].textContent == href.substr(0, 39)+" \u2026 "+href.substr(-10) || /*edit-notes*/as[a].textContent == href.substr(0, 48)+"\u2026") {
as[a].className += " "+userjs;
var text = (entities[ent].label?entities[ent].label.replace(/%id%/, id[1]):id[1]) + (id[2]?"\u00a0"+id[2]:"") + (id[3]?"\u00a0#":"");
if (text) {
as[a].replaceChild(document.createTextNode(text), as[a].firstChild);
as[a].setAttribute("title", ent);
}
if (altserv) {
as[a].insertBefore(document.createElement("code").appendChild(document.createTextNode(altserv[1]+"\u00a0")).parentNode, as[a].firstChild);
}
}
}
}
}
}
}
function selectNode(n) { /* (I fixed) http://bytes.com/topic/javascript/answers/598274-javascript-select-text-mouseover#post2360143 */
var selection, range, doc, win;
var node = n?n:tonode;
if (node) {
if (
(doc = node.ownerDocument) &&
(win = doc.defaultView) &&
typeof win.getSelection != "undefined" &&
typeof doc.createRange != "undefined" &&
(selection = self.getSelection()) &&
typeof selection.removeAllRanges != "undefined"
) {
range = doc.createRange();
range.selectNode(node);
range.setStart(node.firstChild, 0);
range.setEnd(node.lastChild, node.lastChild.textContent.length);
selection.removeAllRanges();
selection.addRange(range);
}
else if (
document.body &&
typeof document.body.createTextRange != "undefined" &&
(range = document.body.createTextRange())
) {
range.moveToElementText(node);
range.select();
}
}
}
function clearSelection() {
if (document.selection) document.selection.empty();
else if (self.getSelection) self.getSelection().removeAllRanges();
}
})();}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment