Skip to content

Commit

Permalink
Same lame react hydrate workaround (delay) #596 #773
Browse files Browse the repository at this point in the history
  • Loading branch information
jesus2099 committed Jul 31, 2023
1 parent 87c7929 commit e540156
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 139 deletions.
166 changes: 85 additions & 81 deletions mb_FUNKEY-ILLUSTRATED-RECORDS.user.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ==UserScript==
// @name mb. FUNKEY ILLUSTRATED RECORDS
// @version 2023.4.20
// @version 2023.8.1
// @description musicbrainz.org: CAA front cover art archive pictures/images (release groups and releases) Big illustrated discography and/or inline everywhere possible without cluttering the pages
// @namespace https://github.com/jesus2099/konami-command
// @supportURL https://github.com/jesus2099/konami-command/labels/mb_FUNKEY-ILLUSTRATED-RECORDS
Expand All @@ -23,7 +23,7 @@
// @exclude *.org/*/*/edit
// @exclude *.org/*/*/edit?*
// @exclude *.org/cdtoc/remove*
// @run-at document-end
// @run-at document-idle
// ==/UserScript==
"use strict";

Expand Down Expand Up @@ -59,93 +59,97 @@ if (caaIcons.length > 0) {
loadCaaIcon(caaIcons[ci]);
}
}
var imgurls = [];
for (var t = 0; t < types.length; t++) {
// TODO: rglink smallpic is often broken by React, though
var as = document.querySelectorAll("tr > td a[href^='/" + types[t] + "/']:not([href$='/cover-art']), div#page.fullwidth ul:not(.tabs) > li a[href^='/" + types[t] + "/']:not([href$='/cover-art']), tr > td > span[class^='rglink'] + a[href^='/" + types[t] + "/']:not([href$='/cover-art'])");
var istable, istablechecked, artistcol;
for (var a = 0; a < as.length; a++) {
var imgurl = as[a].getAttribute("href").match(new RegExp("^/" + types[t] + "/(" + GUID + ")$"));
if (imgurl) {
imgurl = "//coverartarchive.org/" + types[t] + "/" + imgurl[1] + "/front";
if (!istablechecked) {
istable = getParent(as[0], "table");
if (istable) { artistcol = document.evaluate(".//thead/tr/th[contains(./text(), 'Artist') or contains(./a/text(), 'Artist')]", istable, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength == 1; }
istablechecked = true;
}
// SMALL PICS
// ----------
if (smallpics && !self.location.pathname.match(/(open_)?edits$/) && !self.location.pathname.match(/^\/search\/edits/)) {
if (types[t] == "release-group") {
var CAALoader = new XMLHttpRequest();
CAALoader.addEventListener("load", function(event) {
if (this.status == 200) {
var RGCAA = JSON.parse(this.responseText);
if (RGCAA.images.length > 0) {
var releaseGroupOrSpanMp = include_span_mp(this.releaseGroup);
// insert small pic after ratings
var insertPoint = releaseGroupOrSpanMp;
if (
releaseGroupOrSpanMp.previousSibling // is not first element
&& releaseGroupOrSpanMp.previousSibling.matches // is not text node
&& releaseGroupOrSpanMp.previousSibling.matches("span.caa-icon") // is CAA icon
) {
// insert before CAA icon to enable its CSS hiding
insertPoint = releaseGroupOrSpanMp.previousSibling;
// React hydrate imposes delay
var reactHydratePage = location.pathname.match(/^\/release\//);
setTimeout(function() {
var imgurls = [];
for (var t = 0; t < types.length; t++) {
// TODO: rglink smallpic is often broken by React, though
var as = document.querySelectorAll("tr > td a[href^='/" + types[t] + "/']:not([href$='/cover-art']), div#page.fullwidth ul:not(.tabs) > li a[href^='/" + types[t] + "/']:not([href$='/cover-art']), tr > td > span[class^='rglink'] + a[href^='/" + types[t] + "/']:not([href$='/cover-art'])");
var istable, istablechecked, artistcol;
for (var a = 0; a < as.length; a++) {
var imgurl = as[a].getAttribute("href").match(new RegExp("^/" + types[t] + "/(" + GUID + ")$"));
if (imgurl) {
imgurl = "//coverartarchive.org/" + types[t] + "/" + imgurl[1] + "/front";
if (!istablechecked) {
istable = getParent(as[0], "table");
if (istable) { artistcol = document.evaluate(".//thead/tr/th[contains(./text(), 'Artist') or contains(./a/text(), 'Artist')]", istable, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength == 1; }
istablechecked = true;
}
// SMALL PICS
// ----------
if (smallpics && !self.location.pathname.match(/(open_)?edits$/) && !self.location.pathname.match(/^\/search\/edits/)) {
if (types[t] == "release-group") {
var CAALoader = new XMLHttpRequest();
CAALoader.addEventListener("load", function(event) {
if (this.status == 200) {
var RGCAA = JSON.parse(this.responseText);
if (RGCAA.images.length > 0) {
var releaseGroupOrSpanMp = include_span_mp(this.releaseGroup);
// insert small pic after ratings
var insertPoint = releaseGroupOrSpanMp;
if (
releaseGroupOrSpanMp.previousSibling // is not first element
&& releaseGroupOrSpanMp.previousSibling.matches // is not text node
&& releaseGroupOrSpanMp.previousSibling.matches("span.caa-icon") // is CAA icon
) {
// insert before CAA icon to enable its CSS hiding
insertPoint = releaseGroupOrSpanMp.previousSibling;
}
loadCaaIcon(releaseGroupOrSpanMp.parentNode.insertBefore(
createTag("a",
{a: {
href: RGCAA.release + "/cover-art",
ref: this.releaseGroup.getAttribute("href"),
title: RGCAA.images.length + " image" + (RGCAA.images.length != 1 ? "s" : "") + " found in this release"
}},
createTag("span", {a: {class: "caa-icon " + userjs}})
),
insertPoint).firstChild
);
}
loadCaaIcon(releaseGroupOrSpanMp.parentNode.insertBefore(
createTag("a",
{a: {
href: RGCAA.release + "/cover-art",
ref: this.releaseGroup.getAttribute("href"),
title: RGCAA.images.length + " image" + (RGCAA.images.length != 1 ? "s" : "") + " found in this release"
}},
createTag("span", {a: {class: "caa-icon " + userjs}})
),
insertPoint).firstChild
);
} else {
console.log("Error " + this.status + " (" + this.statusText + ") for " + this.releaseGroup);
}
} else {
});
CAALoader.addEventListener("error", function(event) {
console.log("Error " + this.status + " (" + this.statusText + ") for " + this.releaseGroup);
}
});
CAALoader.addEventListener("error", function(event) {
console.log("Error " + this.status + " (" + this.statusText + ") for " + this.releaseGroup);
});
CAALoader.releaseGroup = as[a];
CAALoader.open("GET", "https://coverartarchive.org" + as[a].getAttribute("href").match(new RegExp("/release-group/" + GUID)), true);
CAALoader.send(null);
});
CAALoader.releaseGroup = as[a];
CAALoader.open("GET", "https://coverartarchive.org" + as[a].getAttribute("href").match(new RegExp("/release-group/" + GUID)), true);
CAALoader.send(null);
}
}
}
// TODO: I think there is no longer any UL LI, now only TABLE TR, I guess but not sure...
var box = getParent(as[a], "table") || getParent(as[a], "ul");
box.addEventListener("mouseover", updateBig);
box.addEventListener("mouseout", updateBig);
// BIG PICS
// --------
if (bigpics && (box = box.previousSibling && box.previousSibling.tagName == "DIV" && box.previousSibling.classList.contains(userjs + "bigbox") ? box.previousSibling : box.parentNode.insertBefore(createTag("div", {a: {class: userjs + "bigbox"}}), box))) {
if (!self.location.pathname.match(/\/recordings/) || self.location.pathname.match(/\/recordings/) && imgurls.indexOf(imgurl) < 0) {
var artisttd = artistcol && getSibling(getParent(as[a], "td"), "td");
// textContent is faster but shows <script> content. artisttd contains React? <script> when pending AC edits. https://kellegous.com/j/2013/02/27/innertext-vs-textcontent/
box.appendChild(createTag("a", {a: {href: as[a].getAttribute("href"), title: as[a].textContent + (artisttd ? "\n" + artisttd.innerText.trim() : "")}, s: {display: "inline-block", height: "100%", margin: "8px 8px 4px 4px"}}, [
"⌛",
createTag("img", {
a: {src: imgurl + "-250", alt: as[a].textContent},
s: {verticalAlign: "middle", display: "none", maxHeight: "125px", boxShadow: "1px 1px 4px black"},
e: {
load: function(event) { removeNode(this.parentNode.firstChild); this.style.setProperty("display", "inline"); },
error: function(event) { removeNode(this.parentNode); },
mouseover: updateA,
mouseout: updateA
}
})
]));
imgurls.push(imgurl);
// TODO: I think there is no longer any UL LI, now only TABLE TR, I guess but not sure...
var box = getParent(as[a], "table") || getParent(as[a], "ul");
box.addEventListener("mouseover", updateBig);
box.addEventListener("mouseout", updateBig);
// BIG PICS
// --------
if (bigpics && (box = box.previousSibling && box.previousSibling.tagName == "DIV" && box.previousSibling.classList.contains(userjs + "bigbox") ? box.previousSibling : box.parentNode.insertBefore(createTag("div", {a: {class: userjs + "bigbox"}}), box))) {
if (!self.location.pathname.match(/\/recordings/) || self.location.pathname.match(/\/recordings/) && imgurls.indexOf(imgurl) < 0) {
var artisttd = artistcol && getSibling(getParent(as[a], "td"), "td");
// textContent is faster but shows <script> content. artisttd contains React? <script> when pending AC edits. https://kellegous.com/j/2013/02/27/innertext-vs-textcontent/
box.appendChild(createTag("a", {a: {href: as[a].getAttribute("href"), title: as[a].textContent + (artisttd ? "\n" + artisttd.innerText.trim() : "")}, s: {display: "inline-block", height: "100%", margin: "8px 8px 4px 4px"}}, [
"⌛",
createTag("img", {
a: {src: imgurl + "-250", alt: as[a].textContent},
s: {verticalAlign: "middle", display: "none", maxHeight: "125px", boxShadow: "1px 1px 4px black"},
e: {
load: function(event) { removeNode(this.parentNode.firstChild); this.style.setProperty("display", "inline"); },
error: function(event) { removeNode(this.parentNode); },
mouseover: updateA,
mouseout: updateA
}
})
]));
imgurls.push(imgurl);
}
}
}
}
}
}
}, reactHydratePage ? 1000 : 10);

function updateA(event) {
var ah = this.parentNode.getAttribute("href");
Expand Down
119 changes: 61 additions & 58 deletions mb_INLINE-STUFF.user.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ==UserScript==
// @name mb. INLINE STUFF
// @version 2023.7.20
// @version 2023.8.1
// @description musicbrainz.org: Release page: Inline recording names, comments, ISRC and AcoustID. Direct CAA add link if none. Highlight duplicates in releases and edits. Recording page: millisecond display, spot track length and title variations.
// @namespace https://github.com/jesus2099/konami-command
// @supportURL https://github.com/jesus2099/konami-command/labels/mb_INLINE-STUFF
Expand Down Expand Up @@ -69,70 +69,73 @@ css.insertRule("div#content." + userjs + "hide-recdis table.tbl.medium span." +
if (pagecat) {
switch (pagecat) {
case "release":
// CAA tab / Add link
var CAAtab = document.querySelector("div.tabs > ul.tabs > li > a[href$='/cover-art']");
if (CAAtab && CAAtab.textContent.match(/\(0\)$/)) {
CAAtab.setAttribute("href", CAAtab.getAttribute("href").replace(/cover-art/, "add-cover-art"));
CAAtab.style.setProperty("background-color", "#FF6");
CAAtab.replaceChild(document.createTextNode("Add Cover Art"), CAAtab.firstChild);
}
// Tracklist stuff
css.insertRule("a[" + userjs + "recname] { text-shadow: 1px 2px 2px #999; color: maroon }", 0);
if (contractFingerPrints) {
css.insertRule("div.ars[class^='ars AcoustID'] code { display: inline-block; overflow-x: hidden; vertical-align: bottom; width: 6ch}", 0);
}
if (pageMbid && (tracksHtml = document.querySelectorAll("div#content table.tbl.medium > tbody > tr[id]:not(.subh)")).length > 0) {
if (recUseInRelationshipLink || recAddToMergeLink) {
for (var ith = 0; ith < tracksHtml.length; ith++) {
var toolzone = tracksHtml[ith].querySelector("td.treleases");
if (toolzone) {
toolzone = toolzone.appendChild(document.createElement("div"));
toolzone.className = userjs + "toolzone";
toolzone.style.setProperty("display", "none");
var rec = tracksHtml[ith].querySelector(css_recording);
if (recUseInRelationshipLink && rec) {
toolzone.appendChild(createA(recUseInRelationshipLink, rec.getAttribute("href") + "/relate", "Use this recording in a relationship…"));
}
var rat = tracksHtml[ith].querySelector("span.star-rating a.set-rating");
if (recAddToMergeLink && rat) {
if (recUseInRelationshipLink) { toolzone.appendChild(document.createElement("br")); }
toolzone.appendChild(createA(recAddToMergeLink, "/recording/merge_queue?add-to-merge=" + rat.getAttribute("href").match(/id=([0-9]+)/)[1], "Merge this recording…"));
// React hydrate clumsy workaround
setTimeout(function() {
// CAA tab / Add link
var CAAtab = document.querySelector("div.tabs > ul.tabs > li > a[href$='/cover-art']");
if (CAAtab && CAAtab.textContent.match(/\(0\)$/)) {
CAAtab.setAttribute("href", CAAtab.getAttribute("href").replace(/cover-art/, "add-cover-art"));
CAAtab.style.setProperty("background-color", "#FF6");
CAAtab.replaceChild(document.createTextNode("Add Cover Art"), CAAtab.firstChild);
}
// Tracklist stuff
css.insertRule("a[" + userjs + "recname] { text-shadow: 1px 2px 2px #999; color: maroon }", 0);
if (contractFingerPrints) {
css.insertRule("div.ars[class^='ars AcoustID'] code { display: inline-block; overflow-x: hidden; vertical-align: bottom; width: 6ch}", 0);
}
if (pageMbid && (tracksHtml = document.querySelectorAll("div#content table.tbl.medium > tbody > tr[id]:not(.subh)")).length > 0) {
if (recUseInRelationshipLink || recAddToMergeLink) {
for (var ith = 0; ith < tracksHtml.length; ith++) {
var toolzone = tracksHtml[ith].querySelector("td.treleases");
if (toolzone) {
toolzone = toolzone.appendChild(document.createElement("div"));
toolzone.className = userjs + "toolzone";
toolzone.style.setProperty("display", "none");
var rec = tracksHtml[ith].querySelector(css_recording);
if (recUseInRelationshipLink && rec) {
toolzone.appendChild(createA(recUseInRelationshipLink, rec.getAttribute("href") + "/relate", "Use this recording in a relationship…"));
}
var rat = tracksHtml[ith].querySelector("span.star-rating a.set-rating");
if (recAddToMergeLink && rat) {
if (recUseInRelationshipLink) { toolzone.appendChild(document.createElement("br")); }
toolzone.appendChild(createA(recAddToMergeLink, "/recording/merge_queue?add-to-merge=" + rat.getAttribute("href").match(/id=([0-9]+)/)[1], "Merge this recording…"));
}
toolzone = toolzone.parentNode.appendChild(document.createElement("div"));
toolzone.className = userjs + "editbutt";
toolzone.style.setProperty("display", "none");
toolzone.appendChild(createA("Edit", rec.getAttribute("href") + "/edit", "Edit this recording"));
toolzone = toolzone.parentNode.appendChild(document.createElement("div"));
toolzone.className = userjs + "openEdits";
toolzone.style.setProperty("display", "none");
toolzone.appendChild(createA("Open", rec.getAttribute("href") + "/open_edits", "Recording open edits"));
toolzone.appendChild(document.createTextNode(" "));
toolzone.appendChild(createA("edits", rec.getAttribute("href") + "/edits", "Recording edit history"));
}
toolzone = toolzone.parentNode.appendChild(document.createElement("div"));
toolzone.className = userjs + "editbutt";
toolzone.style.setProperty("display", "none");
toolzone.appendChild(createA("Edit", rec.getAttribute("href") + "/edit", "Edit this recording"));
toolzone = toolzone.parentNode.appendChild(document.createElement("div"));
toolzone.className = userjs + "openEdits";
toolzone.style.setProperty("display", "none");
toolzone.appendChild(createA("Open", rec.getAttribute("href") + "/open_edits", "Recording open edits"));
toolzone.appendChild(document.createTextNode(" "));
toolzone.appendChild(createA("edits", rec.getAttribute("href") + "/edits", "Recording edit history"));
}
var works = tracksHtml[ith].querySelectorAll(css_work);
if (works) {
for (var w = 0; w < works.length; w++) {
var workid = works[w].getAttribute("href").match(new RegExp("/work/(" + str_GUID + ")$"));
if (workid) {
if (!shownworks[workid[1]]) {
shownworks[workid[1]] = 0;
shownworks.count++;
var works = tracksHtml[ith].querySelectorAll(css_work);
if (works) {
for (var w = 0; w < works.length; w++) {
var workid = works[w].getAttribute("href").match(new RegExp("/work/(" + str_GUID + ")$"));
if (workid) {
if (!shownworks[workid[1]]) {
shownworks[workid[1]] = 0;
shownworks.count++;
}
shownworks[workid[1]]++;
}
shownworks[workid[1]]++;
}
}
}
}
idCount("Track", tracksHtml.length);
if (shownworks.count > 0) { idCount("Work", shownworks.count); }
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = isrcFish;
coolBubble.info("Loading “" + document.querySelector("h1").textContent + "” shadow release…");
xhr.open("GET", MBS + releasewsURL.replace(/%s/, pageMbid), true);
xhr.overrideMimeType("text/xml");
xhr.send(null);
}
idCount("Track", tracksHtml.length);
if (shownworks.count > 0) { idCount("Work", shownworks.count); }
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = isrcFish;
coolBubble.info("Loading “" + document.querySelector("h1").textContent + "” shadow release…");
xhr.open("GET", MBS + releasewsURL.replace(/%s/, pageMbid), true);
xhr.overrideMimeType("text/xml");
xhr.send(null);
}
}, 1000);
break;
case "isrc":
if (formatISRC) {
Expand Down

0 comments on commit e540156

Please sign in to comment.