Skip to content

Commit 8653cc4

Browse files
committed
feat(split links): add bulk URL copy buttons to a-tisket
The originally created the script to be able to quickly add the links provided by a-tisket to an existing release. These buttons make it more convenient to copy them.
1 parent 13b7f5c commit 8653cc4

File tree

3 files changed

+60
-14
lines changed

3 files changed

+60
-14
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Display all tracks and releases on which a recording appears from the release pa
7272

7373
## MB: QoL: Paste multiple external links at once
7474

75-
Paste multiple external links at once into the external link editor. Input is split on whitespace (newlines, tabs, spaces, etc.) and fed into the link editor separately.
75+
Paste multiple external links at once into the external link editor. Input is split on whitespace (newlines, tabs, spaces, etc.) and fed into the link editor separately. Additionally adds handy bulk Copy buttons to a-tisket release and artist URLs.
7676

7777
[![Install](https://img.shields.io/badge/dynamic/json?label=install&query=%24.version&url=https%3A%2F%2Fraw.github.com%2FROpdebee%2Fmb-userscripts%2Fdist%2Fmb_multi_external_links.metadata.json&logo=tampermonkey&style=for-the-badge&color=informational)](https://raw.github.com/ROpdebee/mb-userscripts/dist/mb_multi_external_links.user.js)
7878
[![Source](https://img.shields.io/badge/source-grey?style=for-the-badge&logo=github)](src/mb_multi_external_links)

src/mb_multi_external_links/index.ts renamed to src/mb_multi_external_links/index.tsx

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ function insertCheckboxElements(editor: ExternalLinks, checkboxElmt: HTMLInputEl
110110
checkboxElmt.style.marginLeft = `${marginLeft}px`;
111111
}
112112

113-
async function run(windowInstance: Window): Promise<void> {
113+
async function initSplitter(windowInstance: Window): Promise<void> {
114114
// This element should be present even before React is initialized. Checking
115115
// for its existence enables us to skip attempting to find the link input on
116116
// edit pages that don't have external links, without having to exclude
@@ -136,7 +136,7 @@ function onIframeAdded(iframe: HTMLIFrameElement): void {
136136
LOGGER.debug(`Initialising on iframe ${iframe.src}`);
137137

138138
onAddEntityDialogLoaded(iframe, () => {
139-
logFailure(run(iframe.contentWindow!));
139+
logFailure(initSplitter(iframe.contentWindow!));
140140
});
141141
}
142142

@@ -162,6 +162,46 @@ function listenForIframes(): void {
162162
});
163163
}
164164

165-
logFailure(run(window));
165+
function attachLinkSplitter(): void {
166+
logFailure(initSplitter(window));
167+
listenForIframes();
168+
}
169+
170+
const insertAtisketCopyButtons = ((): (() => void) => {
171+
function createButton(textGetter: () => string): HTMLButtonElement {
172+
const btn = <button
173+
type="button"
174+
onClick={(): void => {
175+
logFailure(navigator.clipboard.writeText(textGetter()));
176+
btn.textContent = '(copied)';
177+
setTimeout(() => btn.textContent = 'Copy', 1500);
178+
}}
179+
style={{
180+
marginLeft: '1ex',
181+
}}
182+
>Copy</button> as HTMLButtonElement;
183+
return btn;
184+
}
185+
186+
function getArtistLinks(): string {
187+
const urls = qsa<HTMLAnchorElement>('.prop.artists a:not(.mb)').map((a) => a.href);
188+
return urls.join('\n');
189+
}
166190

167-
listenForIframes();
191+
function getReleaseLinks(): string {
192+
const urls = qsa<HTMLAnchorElement>('section#mba-links a').map((a) => a.href);
193+
return urls.join('\n');
194+
}
195+
196+
return (): void => {
197+
qsMaybe('.prop.artists div')?.prepend(createButton(getArtistLinks));
198+
qsMaybe('section#mba-links > h2')?.append(createButton(getReleaseLinks));
199+
};
200+
})();
201+
202+
203+
if (document.location.hostname === 'musicbrainz.org' || document.location.hostname.endsWith('.musicbrainz.org')) {
204+
attachLinkSplitter();
205+
} else if (document.location.hostname === 'atisket.pulsewidth.org.uk' || document.location.hostname === 'etc.marlonob.info') {
206+
insertAtisketCopyButtons();
207+
}
Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
import type { UserscriptMetadata } from '@lib/util/metadata';
22
import { transformMBMatchURL } from '@lib/util/metadata';
33

4+
const mbMatchedUrls = [
5+
'*/edit',
6+
'*/edit?*',
7+
'release/*/edit-relationships*',
8+
'*/add',
9+
'*/add?*',
10+
'*/create',
11+
'*/create?*',
12+
].map((path) => transformMBMatchURL(path));
13+
414
const metadata: UserscriptMetadata = {
515
name: 'MB: QoL: Paste multiple external links at once',
616
description: 'Enables pasting multiple links, separated by whitespace, into the external link editor.',
717
'run-at': 'document-end',
818
match: [
9-
'*/edit',
10-
'*/edit?*',
11-
'release/*/edit-relationships*',
12-
'*/add',
13-
'*/add?*',
14-
'*/create',
15-
'*/create?*',
16-
].map((path) => transformMBMatchURL(path)),
17-
blurb: 'Paste multiple external links at once into the external link editor. Input is split on whitespace (newlines, tabs, spaces, etc.) and fed into the link editor separately.',
19+
...mbMatchedUrls,
20+
'*://atisket.pulsewidth.org.uk/*',
21+
'*://etc.marlonob.info/atisket/*',
22+
],
23+
blurb: 'Paste multiple external links at once into the external link editor. Input is split on whitespace (newlines, tabs, spaces, etc.) and fed into the link editor separately. Additionally adds handy bulk Copy buttons to a-tisket release and artist URLs.',
1824
};
1925

2026
export default metadata;

0 commit comments

Comments
 (0)