Skip to content

Instantly share code, notes, and snippets.

@Hans5958
Last active January 4, 2026 00:03
Show Gist options
  • Select an option

  • Save Hans5958/69126992963f37f0ee0bde9760df1262 to your computer and use it in GitHub Desktop.

Select an option

Save Hans5958/69126992963f37f0ee0bde9760df1262 to your computer and use it in GitHub Desktop.
VocaDB Name Filler: Fills VocaDB/UtaiteDB/TouhouDB song name and shows the aliases and the artists from the linked original entry. Licensed under MIT. More info: https://gitlab.com/Hans5958-MWS/vocadb-docs/-/wikis/notes/web-scripts#name-filler
(async () => {
// Fetching and caching
const originalId = document.querySelector("a.btn-nomargin:nth-child(1)").href.split("S/")[1]
const cacheKey = "nf:" + originalId
const cachedRaw = sessionStorage.getItem(cacheKey)
const data = cachedRaw?.includes('{') ? JSON.parse(cachedRaw) : await fetch("//" + location.host + "/api/songs/" + originalId + "/for-edit").then((response) => response.json())
sessionStorage.setItem(cacheKey, JSON.stringify(data))
// Filling names; showing main language and aliases
const sameElStr = "div.editor-field > table > tbody"
const valueEl = i => document.querySelector(sameElStr + `> tr:nth-child(${i}) input:nth-child(1)`)
const keyEl = i => document.querySelector(sameElStr + `> tr:nth-child(${i}) > td`)
const choiceEl = i => document.querySelector(`div.editor-field:nth-child(2) > select > option:nth-child(${i})`)
const langs = ['Japanese', 'Romaji', 'English']
for (let i = 0; i < langs.length; i++) {
const lang = langs[i]
valueEl(i + 1).value = data.names.filter((el) => lang === el.language)[0]?.value || ''
if (data.defaultNameLanguage === lang) {
console.log(keyEl(i + 1))
keyEl(i + 1).style.fontWeight = '600 !important'
if (choiceEl(i + 2)) choiceEl(i + 2).style.fontWeight = '600'
}
}
// console.log("defaultNameLanguage:", data.defaultNameLanguage)
// console.log("Unspecified:", data.names.filter((el) => "Unspecified" === el.language).map(a => a.value))
const unspecified = data.names.filter((el) => "Unspecified" === el.language).map(a => a.value)
const aliasesLabelEl = document.querySelector('div.editor-field:nth-child(4) > span:nth-child(2)')
if (aliasesLabelEl && !aliasesLabelEl.querySelector('br')) {
aliasesLabelEl.innerHTML += "<br>" + unspecified.join('<br>')
}
// Showing artists
const artistListParentEl = document.querySelector(".editor-label .extraInfo, [id$=tabpane-artists] .span4:nth-child(2)")
const artistListEl = document.createElement("ul")
artistListEl.id = "nf-artists"
for (const existing of artistListParentEl.querySelectorAll("#" + artistListEl.id)) {
artistListParentEl.removeChild(existing)
}
data.artists.forEach(entry => {
const li = document.createElement("li")
const link = document.createElement("a")
const roles = entry.effectiveRoles
if (!entry.isCustomName) {
link.href = "/Ar/" + entry.artist.id
}
const roleInfo = ("Default" === roles ? "D: " + entry.artist?.artistType : roles)
const support = (entry.isSupport ? ", Support" : "")
link.textContent = entry.name + " (" + roleInfo + support + ")"
li.appendChild(link)
artistListEl.appendChild(li)
})
artistListParentEl.appendChild(artistListEl)
})()
(async()=>{const e=document.querySelector("a.btn-nomargin:nth-child(1)").href.split("S/")[1],t="nf:"+e,n=sessionStorage.getItem(t),o=n?.includes("{")?JSON.parse(n):await fetch("//"+location.host+"/api/songs/"+e+"/for-edit").then(e=>e.json());sessionStorage.setItem(t,JSON.stringify(o));const i="div.editor-field > table > tbody",l=e=>document.querySelector(i+`> tr:nth-child(${e}) input:nth-child(1)`),r=e=>document.querySelector(i+`> tr:nth-child(${e}) > td`),a=e=>document.querySelector(`div.editor-field:nth-child(2) > select > option:nth-child(${e})`),s=["Japanese","Romaji","English"];for(let e=0;e<s.length;e++){const t=s[e];l(e+1).value=o.names.filter(e=>t===e.language)[0]?.value||"",o.defaultNameLanguage===t&&(console.log(r(e+1)),r(e+1).style.fontWeight="600 !important",a(e+2)&&(a(e+2).style.fontWeight="600"))}const c=o.names.filter(e=>"Unspecified"===e.language).map(e=>e.value),d=document.querySelector("div.editor-field:nth-child(4) > span:nth-child(2)");d&&!d.querySelector("br")&&(d.innerHTML+="<br>"+c.join("<br>"));const h=document.querySelector(".editor-label .extraInfo, [id$=tabpane-artists] .span4:nth-child(2)"),u=document.createElement("ul");u.id="nf-artists";for(const e of h.querySelectorAll("#"+u.id))h.removeChild(e);o.artists.forEach(e=>{const t=document.createElement("li"),n=document.createElement("a"),o=e.effectiveRoles;e.isCustomName||(n.href="/Ar/"+e.artist.id);const i="Default"===o?"D: "+e.artist?.artistType:o,l=e.isSupport?", Support":"";n.textContent=e.name+" ("+i+l+")",t.appendChild(n),u.appendChild(t)}),h.appendChild(u)})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment