Skip to content

Commit 2dedcea

Browse files
committed
mb_add_remix_credit_links: Support "edit of" links
1 parent 613586b commit 2dedcea

File tree

1 file changed

+58
-18
lines changed

1 file changed

+58
-18
lines changed

mb_add_remix_credit_links.user.js

+58-18
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@
3232
const TitleRemixRegexp =
3333
/^\s*(.+)\s+\(\s*(.+)\s+(?:(?:re-?)?(?:[dr]ub|edit|mix)|re-?(?:model|shuffle|work)).*\)/i;
3434

35+
/* Examples of track titles this regex should match:
36+
*
37+
* Iceolate (12″ extended mix)
38+
* Zone 12 (extended mix)
39+
* Punks in the City (disco edit)
40+
* Individualists (7inch version)
41+
* Wicked Games (radio edit)
42+
* Respectness (dub version)
43+
* Barcelona (extended version)
44+
*/
45+
const TitleEditRegexp =
46+
/^\s*(.+)\s+\(\s*(?:(?:(?:7|10|12)\s*(?:['")]|inch)?)?\s*(?:extended|disco|dub|radio)?\s*(?:edit|mix|version))\s*\)/i;
47+
3548
// This code is based on:
3649
// https://stackoverflow.com/questions/42795059/programmatically-fill-reactjs-form
3750
function setElementValue(element, value, event = 'input') {
@@ -75,24 +88,32 @@ function addRemixCreditLinks() {
7588

7689
for (const recording of recordings) {
7790
const title = recording.querySelector('bdi').innerText;
78-
const matches = TitleRemixRegexp.exec(title);
79-
if (matches === null) {
91+
const remixMatches = TitleRemixRegexp.exec(title);
92+
const editMatches = TitleEditRegexp.exec(title);
93+
if (!remixMatches && !editMatches) {
8094
continue;
8195
}
8296

83-
const linkTypes = {};
97+
let linkTypes = {};
8498
// find existing relationship types for this recording
8599
for (const link of recording.getElementsByClassName('link-phrase')) {
86100
linkTypes[link.innerText] = 1;
87101
}
88102

103+
let trackArtists = Array.from(
104+
recording.querySelectorAll('td > a[href^="/artist"] bdi')
105+
).map(bdi => bdi.innerText);
106+
if (!trackArtists.length) {
107+
trackArtists = releaseArtists;
108+
}
109+
89110
let button = document.createElement('button');
90-
if (linkTypes['remixer:']) {
111+
if (!remixMatches || linkTypes['remixer:']) {
91112
button.className = 'add-item with-label btn disabled';
92-
} else {
113+
} else if (remixMatches) {
93114
button.className = 'add-item with-label';
94115
button.onclick = addRemixCreditClickHandler;
95-
button.setAttribute('data-remixer', matches[2]);
116+
button.setAttribute('data-remixer', remixMatches[2]);
96117
}
97118

98119
button.innerHTML = `
@@ -102,17 +123,13 @@ function addRemixCreditLinks() {
102123
recording.appendChild(document.createTextNode('\n'));
103124

104125
button = document.createElement('button');
105-
if (linkTypes['remix of:']) {
126+
if (!remixMatches || linkTypes['remix of:']) {
106127
button.className = 'add-item with-label btn disabled';
107-
} else {
108-
let trackArtists = Array.from(
109-
recording.querySelectorAll('td > a[href^="/artist"] bdi')
110-
).map(bdi => bdi.innerText);
111-
if (!trackArtists.length) {
112-
trackArtists = releaseArtists;
113-
}
128+
} else if (remixMatches) {
114129
// recording search will be pre-filled with title and artists to improve the results
115-
const recordingQuery = `${matches[1]} ${trackArtists.join(' ')}`;
130+
const recordingQuery = `${remixMatches[1]} ${trackArtists.join(
131+
' '
132+
)}`;
116133

117134
button.className = 'add-item with-label';
118135
button.onclick = addRemixCreditClickHandler;
@@ -123,6 +140,25 @@ function addRemixCreditLinks() {
123140
Add "remix of" credit
124141
`;
125142
recording.appendChild(button);
143+
144+
button = document.createElement('button');
145+
if (!editMatches || linkTypes['edit of:']) {
146+
button.className = 'add-item with-label btn disabled';
147+
} else if (editMatches) {
148+
// recording search will be pre-filled with title and artists to improve the results
149+
const recordingQuery = `${editMatches[1]} ${trackArtists.join(
150+
' '
151+
)}`;
152+
153+
button.className = 'add-item with-label';
154+
button.onclick = addRemixCreditClickHandler;
155+
button.setAttribute('data-edit-of', recordingQuery);
156+
}
157+
158+
button.innerHTML = `
159+
Add "edit of" credit
160+
`;
161+
recording.appendChild(button);
126162
}
127163
}
128164

@@ -132,6 +168,7 @@ function addRemixCreditClickHandler(event) {
132168
const recording = this.parentElement;
133169
const remixer = this.getAttribute('data-remixer');
134170
const remixOf = this.getAttribute('data-remix-of');
171+
const editOf = this.getAttribute('data-edit-of');
135172

136173
const addRel = recording.querySelector('button.add-relationship');
137174
addRel.click();
@@ -157,7 +194,7 @@ function addRemixCreditClickHandler(event) {
157194
}, 100);
158195
}
159196
}, 250);
160-
} else if (remixOf) {
197+
} else if (remixOf || editOf) {
161198
// wait 250ms for the dialog to be added to the DOM
162199
window.setTimeout(function () {
163200
const dialog = document.getElementById('add-relationship-dialog');
@@ -169,11 +206,14 @@ function addRemixCreditClickHandler(event) {
169206
const linkType = dialog.querySelector(
170207
'input.relationship-type'
171208
);
172-
setElementValue(linkType, 'remix of / has remixes');
209+
setElementValue(
210+
linkType,
211+
remixOf ? 'remix of / has remixes' : 'edit of / edits'
212+
);
173213
tabToConfirmFirstOption(linkType);
174214

175215
const name = dialog.querySelector('input.relationship-target');
176-
setElementValue(name, remixOf);
216+
setElementValue(name, remixOf || editOf);
177217
const search =
178218
name.parentElement.querySelector('button.search');
179219
if (search) {

0 commit comments

Comments
 (0)