From 116a447a0a222d9eff2cdd57999e294373e400b9 Mon Sep 17 00:00:00 2001 From: SuperSaltyGamer Date: Tue, 6 Feb 2024 19:47:48 +0200 Subject: [PATCH] [musicbrainz-works] Refactor bus --- dist/musicbrainz-works.user.js | 7 +-- src/musicbrainz-works/bus.ts | 14 ++++++ src/musicbrainz-works/modules/iswcnet.ts | 25 ++++++----- src/musicbrainz-works/modules/minc.ts | 46 ++++++++------------ src/musicbrainz-works/modules/musicbrainz.ts | 17 +++++--- 5 files changed, 59 insertions(+), 50 deletions(-) diff --git a/dist/musicbrainz-works.user.js b/dist/musicbrainz-works.user.js index e0b143e..2b00325 100644 --- a/dist/musicbrainz-works.user.js +++ b/dist/musicbrainz-works.user.js @@ -17,6 +17,7 @@ // @updateURL https://notabug.org/SuperSaltyGamer/ame/raw/main/dist/musicbrainz-works.user.js // ==/UserScript== -(function(l){typeof define=="function"&&define.amd?define(l):l()})(function(){"use strict";function l(e){return new Promise(t=>{setTimeout(t,e)})}function T(e){const t=document.createElement("template");return t.innerHTML=e,t.content.firstElementChild}function E(e,t){return new Promise(n=>{const o=t==null?void 0:t.waitSelector,i=(t==null?void 0:t.timeout)??3e3;if(i!==0){const s=document.querySelector(e);if(s){n(s);return}}const r=setTimeout(()=>{i!==0&&(a.disconnect(),n(null))},i),a=new MutationObserver(s=>{for(const h of s)for(const u of Array.from(h.addedNodes))if(u instanceof Element&&u.matches(o??e)){i!==0&&(a.disconnect(),clearTimeout(r)),n(o?document.querySelector(e):u);return}});a.observe(document.body,{childList:!0,subtree:!0})})}function g(e,t){new MutationObserver(async o=>{for(const i of o)for(const r of i.addedNodes){if(!(r instanceof HTMLElement))continue;const a=r.matches(e)?r:r.querySelector(e);a&&await t(a)}}).observe(document.body,{childList:!0,subtree:!0})}function d(e,t){return document.evaluate(t,e,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}function b(e,t){const n=document.evaluate(t,e,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);return Array.from({length:n.snapshotLength},(o,i)=>n.snapshotItem(i))}var c=(e=>(e.Work="work",e))(c||{});function m(e,t){if(document.visibilityState==="visible")return t==null?GM.deleteValue(e):(console.info("setBusValue",e,t),GM.setValue(e,{value:t,timestamp:new Date().getTime()+60*1e3}))}async function f(e){if(document.visibilityState!=="visible")return null;const t=await GM.getValue(e);return!t||(await m(e,null),t.timestamp":44,">":44,"?":45,"?":45,"⁇":45,"!":46,"!":46,"‼":46},W=Object.entries(S).reduce((e,[t,n])=>(n in e||(e[n]=[]),e[n].push(t),e),{});function q(e){const t=S[e];return t?W[t]??[e]:[e]}function M(e){return e=e.replace(/[\\^$*+?.()|[\]{}]/g,"\\$&").replace(/[\s・]+/g,"").split("").map(t=>`[${q(t).join("")}]`).join("\\s{0,4}"),new RegExp(e,"gi")}function z(e){return e}function w(e,t){if(e instanceof HTMLInputElement){Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value").set.call(e,t),e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("focusout",{bubbles:!0}));return}if(e instanceof HTMLSelectElement){Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,"value").set.call(e,t),e.dispatchEvent(new Event("change",{bubbles:!0})),e.dispatchEvent(new Event("focusout",{bubbles:!0}));return}}async function P(){g("a[class^='LandingPage_languageButton__']",()=>{location.href="/search"})}async function L(){const e=await f(c.Work);try{if((e==null?void 0:e.iswc)==null)return;const t=document.querySelector("#iswc"),n=document.querySelector("button[type='submit']");if(t.value===e.iswc)return;w(t,e.iswc),n==null||n.click(),await E("[class^='Search_sectionTitle__']");const o=document.querySelector("[id='View More']");o.click(),await l(100);const i=d(document,"//button[.='Copy work codes']");i==null?o.after(T('
Install Bulk copy-paste work codes for better integration.
')):i.click(),e.sources.push(location.href)}finally{await m(c.Work,e)}}function R(){const e=document.querySelector(".logo > a");e&&(e.href=`${location.origin}/search`)}async function _(){const e=document.querySelector("#kyokunm"),t=document.querySelector("#search-by-track-and-artist"),n=await f(c.Work);n!=null&&n.name&&(e.value=n.name,t.click())}async function A(){for(const t of document.querySelectorAll(".saku-detail-link")){const n=document.createElement("a");n.href=`/saku/detail/?${t.getAttribute("data-href")}`,n.innerHTML=t.innerHTML,t.replaceWith(n)}const e=await f(c.Work);try{const t=document.querySelector("#kyokunm"),n=document.querySelector("#search-by-track-and-artist");if(e!=null&&e.name&&t.value!==e.name){t.value=e.name,n.click();return}}finally{await m(c.Work,e)}}async function x(){var t,n,o,i,r,a,s,h;const e=await f(c.Work);try{if(e==null)return;const u=((n=(t=d(document,"//h2/text()"))==null?void 0:t.nodeValue)==null?void 0:n.trim())||null,y=((i=(o=d(document,"//h3/text()[.!='-']"))==null?void 0:o.nodeValue)==null?void 0:i.replaceAll(" ",""))||null,v=((a=(r=d(document,"//a[@href='#jasrac']/following-sibling::*/span[2][.!='']"))==null?void 0:r.innerText)==null?void 0:a.trim())||null,G=((h=(s=d(document,"//a[@href='#nextone']/following-sibling::*/span[2][.!='']"))==null?void 0:s.innerText)==null?void 0:h.trim())||null,N=new Set(b(document,"//td[contains(., '作詞')]/parent::tr/*[2]").map(p=>p.innerText.trim()).filter(Boolean)),I=new Set(b(document,"//td[contains(., '作曲')]/parent::tr/*[2]").map(p=>p.innerText.trim()).filter(Boolean)),j=new Set(b(document,"//td[contains(., '出版者')]/parent::tr/*[2]").map(p=>p.innerText.trim()).filter(Boolean));y&&(e.iswc=y),e.lyricists=Array.from(N),e.composers=Array.from(I),e.publishers=Array.from(j)}finally{await m(c.Work,e)}}function O(){g("#add-relationship-dialog",e=>{const t=d(e,"//td[.='Work']/following-sibling::td//button");setTimeout(()=>{t==null||t.click()},100)}),g("ul[role='listbox'][id^='relationship-target'] > li:first-child",e=>{if(e.innerText.includes("Click here to try again")){setTimeout(()=>{e.click()},100);return}for(const t of B())e.innerHTML=e.innerHTML.replaceAll(M(t),n=>{const o=document.createElement("mark");return o.innerText=n,o.outerHTML})})}async function H(){const e=document.querySelector("#id-edit-work\\.name"),t=document.querySelector("input[name='edit-work.iswcs.0']"),n=document.querySelector("#id-edit-work\\.edit_note"),o=await f(c.Work);if(await m(c.Work,{name:e.value||null,iswc:t.value||null,lyricists:[],composers:[],publishers:[],sources:[]}),o==null)return;o.iswc&&(t.value=o.iswc),n.value=o.sources.join(` -`)+` -`;for(const r of o.composers)await k("artist","composed / composer",r);for(const r of o.lyricists)await k("artist","lyrics / lyricist",r);for(const r of o.publishers)await k("label","published / publisher",r);const i=document.querySelector("#ROpdebee_MB_Paste_Work");i==null||i.click()}function B(){return new Set(Array.from(document.body.querySelectorAll("a[href^='/artist/'][title]")).map(e=>e.innerText.trim()))}async function k(e,t,n){document.querySelector("button.add-relationship").click();const i=await E("#add-relationship-dialog");if(i==null)return;const r=i.querySelector("select.entity-type");w(r,e);const a=i.querySelector("input.relationship-type");w(a,t),i.querySelector("li.option-item").click();const s=i.querySelector(".relationship-target input");w(s,n),await l(300),i.querySelector(".relationship-target button").click(),await new Promise(u=>{const y=i.querySelector("button.negative"),v=i.querySelector("button.positive");y.addEventListener("click",()=>u()),v.addEventListener("click",()=>u())}),await l(300)}const V="";GM.addStyle(V);const D=new URLSearchParams(location.search);window.addEventListener("focus",async()=>{var e;await l(100),document.hasFocus()&&(location.host.endsWith("musicbrainz.org")?location.pathname.startsWith("/release/")&&location.pathname.endsWith("/edit-relationships")?await O():(location.pathname.startsWith("/work/")&&location.pathname.endsWith("/edit")||location.pathname.startsWith("/dialog")&&((e=D.get("path"))!=null&&e.startsWith("/work/create")))&&await H():location.host.endsWith("minc.or.jp")?(await R(),location.pathname.startsWith("/search")?await _():location.pathname.startsWith("/music/list")?await A():location.pathname.startsWith("/saku/detail")&&await x()):location.host.endsWith("cisac.org")&&(await P(),location.pathname.startsWith("/search")&&await L()))}),window.dispatchEvent(new Event("focus"))}); +(function(l){typeof define=="function"&&define.amd?define(l):l()})(function(){"use strict";function l(e){return new Promise(t=>{setTimeout(t,e)})}function P(e){const t=document.createElement("template");return t.innerHTML=e,t.content.firstElementChild}function k(e,t){return new Promise(n=>{const o=t==null?void 0:t.waitSelector,i=(t==null?void 0:t.timeout)??3e3;if(i!==0){const s=document.querySelector(e);if(s){n(s);return}}const r=setTimeout(()=>{i!==0&&(a.disconnect(),n(null))},i),a=new MutationObserver(s=>{for(const m of s)for(const c of Array.from(m.addedNodes))if(c instanceof Element&&c.matches(o??e)){i!==0&&(a.disconnect(),clearTimeout(r)),n(o?document.querySelector(e):c);return}});a.observe(document.body,{childList:!0,subtree:!0})})}function h(e,t){new MutationObserver(async o=>{for(const i of o)for(const r of i.addedNodes){if(!(r instanceof HTMLElement))continue;const a=r.matches(e)?r:r.querySelector(e);a&&await t(a)}}).observe(document.body,{childList:!0,subtree:!0})}function d(e,t){return document.evaluate(t,e,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}function b(e,t){const n=document.evaluate(t,e,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);return Array.from({length:n.snapshotLength},(o,i)=>n.snapshotItem(i))}var u=(e=>(e.Work="work",e))(u||{});function E(e,t){if(document.visibilityState==="visible")return t==null?GM.deleteValue(e):(console.info("setBusValue",e,t),GM.setValue(e,{value:t,timestamp:new Date().getTime()+60*1e3}))}async function v(e){if(document.visibilityState!=="visible")return null;const t=await GM.getValue(e);return!t||(await E(e,null),t.timestamp":44,">":44,"?":45,"?":45,"⁇":45,"!":46,"!":46,"‼":46},L=Object.entries(T).reduce((e,[t,n])=>(n in e||(e[n]=[]),e[n].push(t),e),{});function R(e){const t=T[e];return t?L[t]??[e]:[e]}function A(e){return e=e.replace(/[\\^$*+?.()|[\]{}]/g,"\\$&").replace(/[\s・]+/g,"").split("").map(t=>`[${R(t).join("")}]`).join("\\s{0,4}"),new RegExp(e,"gi")}function G(e){return e}function w(e,t){if(e instanceof HTMLInputElement){Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value").set.call(e,t),e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("focusout",{bubbles:!0}));return}if(e instanceof HTMLSelectElement){Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,"value").set.call(e,t),e.dispatchEvent(new Event("change",{bubbles:!0})),e.dispatchEvent(new Event("focusout",{bubbles:!0}));return}}async function x(){h("a[class^='LandingPage_languageButton__']",()=>{location.href="/search"}),h("div[class^='Search_resultsContainer__'] div[class^='AlertMessage_text__']",()=>{location.href="/"})}function O(){return p(u.Work,async e=>{if(!e.iswc)return;const t=document.querySelector("#iswc"),n=document.querySelector("button[type='submit']");if(t.value===e.iswc)return;w(t,e.iswc),n==null||n.click(),await k("[class^='Search_sectionTitle__']");const o=document.querySelector("[id='View More']");o.click(),await l(100);const i=d(document,"//button[.='Copy work codes']");i?(i.click(),e.workCodes=!0):o.after(P('
Install Bulk copy-paste work codes for better integration.
'))})}function H(){const e=document.querySelector(".logo > a");e&&(e.href=`${location.origin}/search`)}function B(){return p(u.Work,async e=>{if(!e.name)return;const t=document.querySelector("#kyokunm"),n=document.querySelector("#search-by-track-and-artist");t.value=e.name,n.click()})}function V(){for(const e of document.querySelectorAll(".saku-detail-link")){const t=document.createElement("a");t.href=`/saku/detail/?${e.getAttribute("data-href")}`,t.innerHTML=e.innerHTML,e.replaceWith(t)}return p(u.Work,async e=>{const t=document.querySelector("#kyokunm"),n=document.querySelector("#search-by-track-and-artist");!e.name||t.value===e.name||(t.value=e.name,n.click())})}function C(){return p(u.Work,async e=>{var m,c,y,g,W,M,q,_;const t=((c=(m=d(document,"//h2/text()"))==null?void 0:m.nodeValue)==null?void 0:c.trim())||null,n=((g=(y=d(document,"//h3/text()[.!='-']"))==null?void 0:y.nodeValue)==null?void 0:g.replaceAll(" ",""))||null,o=((M=(W=d(document,"//a[@href='#jasrac']/following-sibling::*/span[2][.!='']"))==null?void 0:W.innerText)==null?void 0:M.trim())||null,i=((_=(q=d(document,"//a[@href='#nextone']/following-sibling::*/span[2][.!='']"))==null?void 0:q.innerText)==null?void 0:_.trim())||null,r=new Set(b(document,"//td[contains(., '作詞')]/parent::tr/*[2]").map(f=>f.innerText.trim()).filter(Boolean)),a=new Set(b(document,"//td[contains(., '作曲')]/parent::tr/*[2]").map(f=>f.innerText.trim()).filter(Boolean)),s=new Set(b(document,"//td[contains(., '出版者')]/parent::tr/*[2]").map(f=>f.innerText.trim()).filter(Boolean));n&&(e.iswc=n),e.lyricists=Array.from(r),e.composers=Array.from(a),e.publishers=Array.from(s)})}function D(){h("#add-relationship-dialog",e=>{const t=d(e,"//td[.='Work']/following-sibling::td//button");setTimeout(()=>{t==null||t.click()},100)}),h("ul[role='listbox'][id^='relationship-target'] > li:first-child",e=>{if(e.innerText.includes("Click here to try again")){setTimeout(()=>{e.click()},100);return}for(const t of z())e.innerHTML=e.innerHTML.replaceAll(A(t),n=>{const o=document.createElement("mark");return o.innerText=n,o.outerHTML})})}async function N(){const e=document.querySelector("#id-edit-work\\.name"),t=document.querySelector("input[name='edit-work.iswcs.0']"),n=document.querySelector("#id-edit-work\\.edit_note"),o=await v(u.Work);if(await E(u.Work,{name:e.value||null,iswc:t.value||null,lyricists:[],composers:[],publishers:[],sources:[],workCodes:!1}),!!o){if(o.workCodes){const i=document.querySelector("#ROpdebee_MB_Paste_Work");i==null||i.click()}o.iswc&&(t.value=o.iswc),o.sources.length&&(n.value=`Filled out with of Ame (MusicBrainz - Works): +${o.sources.join(` +`)} +`);for(const i of o.composers)await S("artist","composed / composer",i);for(const i of o.lyricists)await S("artist","lyrics / lyricist",i);for(const i of o.publishers)await S("label","published / publisher",i)}}function z(){return new Set(Array.from(document.body.querySelectorAll("a[href^='/artist/'][title]")).map(e=>e.innerText.trim()))}async function S(e,t,n){document.querySelector("button.add-relationship").click();const i=await k("#add-relationship-dialog");if(!i)return;const r=i.querySelector("select.entity-type");w(r,e);const a=i.querySelector("input.relationship-type");w(a,t),i.querySelector("li.option-item").click();const s=i.querySelector(".relationship-target input");w(s,n),await l(300),i.querySelector(".relationship-target button").click(),await new Promise(c=>{const y=i.querySelector("button.negative"),g=i.querySelector("button.positive");y.addEventListener("click",()=>c()),g.addEventListener("click",()=>c())}),await l(300)}const I="";GM.addStyle(I);const j=new URLSearchParams(location.search);window.addEventListener("focus",async()=>{var e;await l(100),document.hasFocus()&&(location.host.endsWith("musicbrainz.org")?location.pathname.startsWith("/release/")&&location.pathname.endsWith("/edit-relationships")?await D():(location.pathname.startsWith("/work/")&&location.pathname.endsWith("/edit")||location.pathname.startsWith("/dialog")&&((e=j.get("path"))!=null&&e.startsWith("/work/create")))&&await N():location.host.endsWith("minc.or.jp")?(await H(),location.pathname.startsWith("/search")?await B():location.pathname.startsWith("/music/list")?await V():location.pathname.startsWith("/saku/detail")&&await C()):location.host.endsWith("cisac.org")&&(await x(),location.pathname.startsWith("/search")&&await O()))}),window.dispatchEvent(new Event("focus"))}); diff --git a/src/musicbrainz-works/bus.ts b/src/musicbrainz-works/bus.ts index 80061e3..18532f6 100644 --- a/src/musicbrainz-works/bus.ts +++ b/src/musicbrainz-works/bus.ts @@ -18,6 +18,7 @@ interface Work { composers: string[] publishers: string[] sources: string[] + workCodes: boolean } export function setBusValue(type: T, value: MessageValues[T] | null) { @@ -39,3 +40,16 @@ export async function getBusValue(type: T): Promi console.info("getBusValue", type, container); return container.value; } + +export async function updateBusValue(type: T, cb: (value: MessageValues[T]) => void): Promise { + const value = await getBusValue(type); + if (!value) return; + + try { + await cb(value); + } catch (err) { + console.error(err); + } finally { + await setBusValue(type, value); + } +} diff --git a/src/musicbrainz-works/modules/iswcnet.ts b/src/musicbrainz-works/modules/iswcnet.ts index fbb1828..a61fdbb 100644 --- a/src/musicbrainz-works/modules/iswcnet.ts +++ b/src/musicbrainz-works/modules/iswcnet.ts @@ -1,19 +1,23 @@ import { fromHTML, observeQuerySelector, pathSelector, waitQuerySelector } from "../../common/dom"; import { sleep } from "../../common/misc"; -import { MessageType, getBusValue, setBusValue } from "../bus"; +import { MessageType, updateBusValue } from "../bus"; import { setReactInputValue } from "../utils"; export async function onIswcNetPages() { + // Skip language selection after captcha. observeQuerySelector("a[class^='LandingPage_languageButton__']", () => { location.href = "/search"; }); + + // Skip to captcha on error. + observeQuerySelector("div[class^='Search_resultsContainer__'] div[class^='AlertMessage_text__']", () => { + location.href = "/"; + }); } -export async function onIswcNetSearchPage() { - const work = await getBusValue(MessageType.Work); - - try { - if (work?.iswc == null) return; +export function onIswcNetSearchPage() { + return updateBusValue(MessageType.Work, async (work) => { + if (!work.iswc) return; const iswcEl = document.querySelector("#iswc")!; const searchEl = document.querySelector("button[type='submit']")!; @@ -31,14 +35,11 @@ export async function onIswcNetSearchPage() { await sleep(100); const copyEl = pathSelector(document, "//button[.='Copy work codes']"); - if (copyEl == null) { + if (!copyEl) { moreEl.after(fromHTML(`
Install Bulk copy-paste work codes for better integration.
`)); } else { copyEl.click(); + work.workCodes = true; } - - work.sources.push(location.href); - } finally { - await setBusValue(MessageType.Work, work); - } + }); } diff --git a/src/musicbrainz-works/modules/minc.ts b/src/musicbrainz-works/modules/minc.ts index 6a678c7..46278f2 100644 --- a/src/musicbrainz-works/modules/minc.ts +++ b/src/musicbrainz-works/modules/minc.ts @@ -1,23 +1,24 @@ import { pathSelector, pathSelectorAll } from "../../common/dom"; -import { MessageType, getBusValue, setBusValue } from "../bus"; +import { MessageType, updateBusValue } from "../bus"; export function onMincPages() { const logoEl = document.querySelector(".logo > a"); if (logoEl) logoEl.href = `${location.origin}/search`; } -export async function onMincSearchPage() { - const workNameEl = document.querySelector("#kyokunm")!; - const searchWorkEl = document.querySelector("#search-by-track-and-artist")!; +export function onMincSearchPage() { + return updateBusValue(MessageType.Work, async (work) => { + if (!work.name) return; + + const workNameEl = document.querySelector("#kyokunm")!; + const searchWorkEl = document.querySelector("#search-by-track-and-artist")!; - const work = await getBusValue(MessageType.Work); - if (work?.name) { workNameEl.value = work.name; searchWorkEl.click(); - } + }); } -export async function onMincWorkListPage() { +export function onMincWorkListPage() { for (const buttonEl of document.querySelectorAll(".saku-detail-link")) { const anchorEl = document.createElement("a"); anchorEl.href = `/saku/detail/?${buttonEl.getAttribute("data-href")}`; @@ -25,28 +26,19 @@ export async function onMincWorkListPage() { buttonEl.replaceWith(anchorEl); } - const work = await getBusValue(MessageType.Work); - - try { + return updateBusValue(MessageType.Work, async (work) => { const workNameEl = document.querySelector("#kyokunm")!; const searchWorkEl = document.querySelector("#search-by-track-and-artist")!; - if (work?.name && workNameEl.value !== work.name) { - workNameEl.value = work.name; - searchWorkEl.click(); - return; - } - } finally { - await setBusValue(MessageType.Work, work); - } + if (!work.name || workNameEl.value === work.name) return; + + workNameEl.value = work.name; + searchWorkEl.click(); + }); } -export async function onMincWorkPage() { - const work = await getBusValue(MessageType.Work); - - try { - if (work == null) return; - +export function onMincWorkPage() { + return updateBusValue(MessageType.Work, async (work) => { const name = pathSelector(document, "//h2/text()")?.nodeValue?.trim() || null; const iswc = pathSelector(document, "//h3/text()[.!='-']")?.nodeValue?.replaceAll(" ", "") || null; const jasrac = pathSelector(document, "//a[@href='#jasrac']/following-sibling::*/span[2][.!='']")?.innerText?.trim() || null; @@ -59,7 +51,5 @@ export async function onMincWorkPage() { work.lyricists = Array.from(lyricists); work.composers = Array.from(composers); work.publishers = Array.from(publishers); - } finally { - await setBusValue(MessageType.Work, work); - } + }); } diff --git a/src/musicbrainz-works/modules/musicbrainz.ts b/src/musicbrainz-works/modules/musicbrainz.ts index eb66af2..8e904e2 100644 --- a/src/musicbrainz-works/modules/musicbrainz.ts +++ b/src/musicbrainz-works/modules/musicbrainz.ts @@ -43,19 +43,22 @@ export async function onMusicBrainzEditWorkPage() { lyricists: [], composers: [], publishers: [], - sources: [] + sources: [], + workCodes: false }); - if (work == null) return; + if (!work) return; + + if (work.workCodes) { + const pasteWorkCodesEl = document.querySelector("#ROpdebee_MB_Paste_Work"); + pasteWorkCodesEl?.click(); + } if (work.iswc) iswcEl.value = work.iswc; - noteEl.value = work.sources.join("\n") + "\n"; + if (work.sources.length) noteEl.value = `Filled out with of Ame (MusicBrainz - Works):\n${work.sources.join("\n")}\n`; for (const composer of work.composers) await addRelationship("artist", "composed / composer", composer); for (const lyricist of work.lyricists) await addRelationship("artist", "lyrics / lyricist", lyricist); for (const publisher of work.publishers) await addRelationship("label", "published / publisher", publisher); - - const pasteWorkCodesEl = document.querySelector("#ROpdebee_MB_Paste_Work"); - pasteWorkCodesEl?.click(); } function getArtistsOnPage(): Set { @@ -67,7 +70,7 @@ async function addRelationship(relatedType: string, relationshipType: string, va addRelationshipEl.click(); const dialogEl = await waitQuerySelector("#add-relationship-dialog"); - if (dialogEl == null) return; + if (!dialogEl) return; const relatedTypeEl = dialogEl.querySelector("select.entity-type")!; setReactInputValue(relatedTypeEl, relatedType);