${language.$("redirectPage.title", { title })}
-${language.$("redirectPage.infoLine", { +
${language.$('redirectPage.title', {title})}
+${language.$('redirectPage.infoLine', { target: `${target}`, })}
From c75b029160248b6935e5c0f5156cc7a870311e82 Mon Sep 17 00:00:00 2001
From: "(quasar) nebula" Choose a link to go to a random page in that category or album! If your browser doesn't support relatively modern JavaScript or you've disabled it, these links won't work - sorry. ${language.$(
- "releaseInfo.additionalFiles.heading",
+ 'releaseInfo.additionalFiles.heading',
{
additionalFiles: language.countAdditionalFiles(fileCount, {
unit: true,
@@ -57,14 +57,14 @@ export function generateAdditionalFilesList(
${language.$("albumCommentaryPage.infoLine", {
+ ${language.$('albumCommentaryPage.infoLine', {
words: `${language.formatWordCount(words, {
unit: true,
})}`,
entries: `${language.countCommentaryEntries(
entries.length,
- { unit: true }
+ {unit: true}
)}`,
})} ${language.$("commentaryIndex.infoLine", {
+ ${language.$('commentaryIndex.infoLine', {
words: `${language.formatWordCount(totalWords, {
unit: true,
})}`,
entries: `${language.countCommentaryEntries(
totalEntries,
- { unit: true }
+ {unit: true}
)}`,
})} ${language.$("commentaryIndex.albumList.title")} ${language.$('commentaryIndex.albumList.title')}
${[
album.artistContribs.length &&
- language.$("releaseInfo.by", {
+ language.$('releaseInfo.by', {
artists: getArtistString(
album.artistContribs,
{
@@ -169,7 +169,7 @@ export function write(album, { wikiData }) {
),
}),
album.coverArtistContribs.length &&
- language.$("releaseInfo.coverArtBy", {
+ language.$('releaseInfo.coverArtBy', {
artists: getArtistString(
album.coverArtistContribs,
{
@@ -179,7 +179,7 @@ export function write(album, { wikiData }) {
),
}),
album.wallpaperArtistContribs.length &&
- language.$("releaseInfo.wallpaperArtBy", {
+ language.$('releaseInfo.wallpaperArtBy', {
artists: getArtistString(
album.wallpaperArtistContribs,
{
@@ -189,7 +189,7 @@ export function write(album, { wikiData }) {
),
}),
album.bannerArtistContribs.length &&
- language.$("releaseInfo.bannerArtBy", {
+ language.$('releaseInfo.bannerArtBy', {
artists: getArtistString(
album.bannerArtistContribs,
{
@@ -199,23 +199,23 @@ export function write(album, { wikiData }) {
),
}),
album.date &&
- language.$("releaseInfo.released", {
+ language.$('releaseInfo.released', {
date: language.formatDate(album.date),
}),
album.coverArtDate &&
+album.coverArtDate !== +album.date &&
- language.$("releaseInfo.artReleased", {
+ language.$('releaseInfo.artReleased', {
date: language.formatDate(album.coverArtDate),
}),
- language.$("releaseInfo.duration", {
+ language.$('releaseInfo.duration', {
duration: language.formatDuration(
albumDuration,
- { approximate: album.tracks.length > 1 }
+ {approximate: album.tracks.length > 1}
),
}),
]
.filter(Boolean)
- .join("
')[0],
+ dependencies: ['description'],
+ compute: ({description}) => description.split('
')[0],
},
},
albums: {
- flags: { expose: true },
+ flags: {expose: true},
expose: {
- dependencies: ["albumData"],
- compute: ({ albumData, [Group.instance]: group }) =>
+ dependencies: ['albumData'],
+ compute: ({albumData, [Group.instance]: group}) =>
albumData?.filter((album) => album.groups.includes(group)) ?? [],
},
},
color: {
- flags: { expose: true },
+ flags: {expose: true},
expose: {
- dependencies: ["groupCategoryData"],
+ dependencies: ['groupCategoryData'],
- compute: ({ groupCategoryData, [Group.instance]: group }) =>
+ compute: ({groupCategoryData, [Group.instance]: group}) =>
groupCategoryData.find((category) => category.groups.includes(group))
?.color ?? null,
},
},
category: {
- flags: { expose: true },
+ flags: {expose: true},
expose: {
- dependencies: ["groupCategoryData"],
- compute: ({ groupCategoryData, [Group.instance]: group }) =>
+ dependencies: ['groupCategoryData'],
+ compute: ({groupCategoryData, [Group.instance]: group}) =>
groupCategoryData.find((category) => category.groups.includes(group)) ??
null,
},
@@ -1203,7 +1200,7 @@ Group.propertyDescriptors = {
GroupCategory.propertyDescriptors = {
// Update & expose
- name: Thing.common.name("Unnamed Group Category"),
+ name: Thing.common.name('Unnamed Group Category'),
color: Thing.common.color(),
groupsByRef: Thing.common.referenceList(Group),
@@ -1215,8 +1212,8 @@ GroupCategory.propertyDescriptors = {
// Expose only
groups: Thing.common.dynamicThingsFromReferenceList(
- "groupsByRef",
- "groupData",
+ 'groupsByRef',
+ 'groupData',
find.group
),
};
@@ -1226,7 +1223,7 @@ GroupCategory.propertyDescriptors = {
ArtTag.propertyDescriptors = {
// Update & expose
- name: Thing.common.name("Unnamed Art Tag"),
+ name: Thing.common.name('Unnamed Art Tag'),
directory: Thing.common.directory(),
color: Thing.common.color(),
isContentWarning: Thing.common.flag(false),
@@ -1240,16 +1237,16 @@ ArtTag.propertyDescriptors = {
// Previously known as: (tag).things
taggedInThings: {
- flags: { expose: true },
+ flags: {expose: true},
expose: {
- dependencies: ["albumData", "trackData"],
- compute: ({ albumData, trackData, [ArtTag.instance]: artTag }) =>
+ dependencies: ['albumData', 'trackData'],
+ compute: ({albumData, trackData, [ArtTag.instance]: artTag}) =>
sortAlbumsTracksChronologically(
[...albumData, ...trackData].filter((thing) =>
thing.artTags?.includes(artTag)
),
- { getDate: (o) => o.coverArtDate }
+ {getDate: (o) => o.coverArtDate}
),
},
},
@@ -1260,7 +1257,7 @@ ArtTag.propertyDescriptors = {
NewsEntry.propertyDescriptors = {
// Update & expose
- name: Thing.common.name("Unnamed News Entry"),
+ name: Thing.common.name('Unnamed News Entry'),
directory: Thing.common.directory(),
date: Thing.common.simpleDate(),
@@ -1269,12 +1266,12 @@ NewsEntry.propertyDescriptors = {
// Expose only
contentShort: {
- flags: { expose: true },
+ flags: {expose: true},
expose: {
- dependencies: ["content"],
+ dependencies: ['content'],
- compute: ({ content }) => content.split('
')[0],
+ compute: ({content}) => content.split('
')[0],
},
},
};
@@ -1284,15 +1281,15 @@ NewsEntry.propertyDescriptors = {
StaticPage.propertyDescriptors = {
// Update & expose
- name: Thing.common.name("Unnamed Static Page"),
+ name: Thing.common.name('Unnamed Static Page'),
nameShort: {
- flags: { update: true, expose: true },
- update: { validate: isName },
+ flags: {update: true, expose: true},
+ update: {validate: isName},
expose: {
- dependencies: ["name"],
- transform: (value, { name }) => value ?? name,
+ dependencies: ['name'],
+ transform: (value, {name}) => value ?? name,
},
},
@@ -1310,7 +1307,7 @@ HomepageLayout.propertyDescriptors = {
sidebarContent: Thing.common.simpleString(),
rows: {
- flags: { update: true, expose: true },
+ flags: {update: true, expose: true},
update: {
validate: validateArrayItems(validateInstanceOf(HomepageLayoutRow)),
@@ -1321,13 +1318,13 @@ HomepageLayout.propertyDescriptors = {
HomepageLayoutRow.propertyDescriptors = {
// Update & expose
- name: Thing.common.name("Unnamed Homepage Row"),
+ name: Thing.common.name('Unnamed Homepage Row'),
type: {
- flags: { update: true, expose: true },
+ flags: {update: true, expose: true},
update: {
- validate(value) {
+ validate() {
throw new Error(`'type' property validator must be overridden`);
},
},
@@ -1350,10 +1347,10 @@ HomepageLayoutAlbumsRow.propertyDescriptors = {
// Update & expose
type: {
- flags: { update: true, expose: true },
+ flags: {update: true, expose: true},
update: {
validate(value) {
- if (value !== "albums") {
+ if (value !== 'albums') {
throw new TypeError(`Expected 'albums'`);
}
@@ -1366,25 +1363,25 @@ HomepageLayoutAlbumsRow.propertyDescriptors = {
sourceAlbumsByRef: Thing.common.referenceList(Album),
countAlbumsFromGroup: {
- flags: { update: true, expose: true },
- update: { validate: isCountingNumber },
+ flags: {update: true, expose: true},
+ update: {validate: isCountingNumber},
},
actionLinks: {
- flags: { update: true, expose: true },
- update: { validate: validateArrayItems(isString) },
+ flags: {update: true, expose: true},
+ update: {validate: validateArrayItems(isString)},
},
// Expose only
sourceGroup: Thing.common.dynamicThingFromSingleReference(
- "sourceGroupByRef",
- "groupData",
+ 'sourceGroupByRef',
+ 'groupData',
find.group
),
sourceAlbums: Thing.common.dynamicThingsFromReferenceList(
- "sourceAlbumsByRef",
- "albumData",
+ 'sourceAlbumsByRef',
+ 'albumData',
find.album
),
};
@@ -1394,18 +1391,18 @@ HomepageLayoutAlbumsRow.propertyDescriptors = {
Flash.propertyDescriptors = {
// Update & expose
- name: Thing.common.name("Unnamed Flash"),
+ name: Thing.common.name('Unnamed Flash'),
directory: {
- flags: { update: true, expose: true },
- update: { validate: isDirectory },
+ flags: {update: true, expose: true},
+ update: {validate: isDirectory},
// Flashes expose directory differently from other Things! Their
// default directory is dependent on the page number (or ID), not
// the name.
expose: {
- dependencies: ["page"],
- transform(directory, { page }) {
+ dependencies: ['page'],
+ transform(directory, {page}) {
if (directory === null && page === null) return null;
else if (directory === null) return page;
else return directory;
@@ -1414,8 +1411,8 @@ Flash.propertyDescriptors = {
},
page: {
- flags: { update: true, expose: true },
- update: { validate: oneOf(isString, isNumber) },
+ flags: {update: true, expose: true},
+ update: {validate: oneOf(isString, isNumber)},
expose: {
transform: (value) => (value === null ? null : value.toString()),
@@ -1424,7 +1421,7 @@ Flash.propertyDescriptors = {
date: Thing.common.simpleDate(),
- coverArtFileExtension: Thing.common.fileExtension("jpg"),
+ coverArtFileExtension: Thing.common.fileExtension('jpg'),
contributorContribsByRef: Thing.common.contribsByRef(),
@@ -1440,32 +1437,32 @@ Flash.propertyDescriptors = {
// Expose only
- contributorContribs: Thing.common.dynamicContribs("contributorContribsByRef"),
+ contributorContribs: Thing.common.dynamicContribs('contributorContribsByRef'),
featuredTracks: Thing.common.dynamicThingsFromReferenceList(
- "featuredTracksByRef",
- "trackData",
+ 'featuredTracksByRef',
+ 'trackData',
find.track
),
act: {
- flags: { expose: true },
+ flags: {expose: true},
expose: {
- dependencies: ["flashActData"],
+ dependencies: ['flashActData'],
- compute: ({ flashActData, [Flash.instance]: flash }) =>
+ compute: ({flashActData, [Flash.instance]: flash}) =>
flashActData.find((act) => act.flashes.includes(flash)) ?? null,
},
},
color: {
- flags: { expose: true },
+ flags: {expose: true},
expose: {
- dependencies: ["flashActData"],
+ dependencies: ['flashActData'],
- compute: ({ flashActData, [Flash.instance]: flash }) =>
+ compute: ({flashActData, [Flash.instance]: flash}) =>
flashActData.find((act) => act.flashes.includes(flash))?.color ?? null,
},
},
@@ -1485,7 +1482,7 @@ Flash[S.serializeDescriptors] = {
FlashAct.propertyDescriptors = {
// Update & expose
- name: Thing.common.name("Unnamed Flash Act"),
+ name: Thing.common.name('Unnamed Flash Act'),
color: Thing.common.color(),
anchor: Thing.common.simpleString(),
jump: Thing.common.simpleString(),
@@ -1500,8 +1497,8 @@ FlashAct.propertyDescriptors = {
// Expose only
flashes: Thing.common.dynamicThingsFromReferenceList(
- "flashesByRef",
- "flashData",
+ 'flashesByRef',
+ 'flashData',
find.flash
),
};
@@ -1511,16 +1508,16 @@ FlashAct.propertyDescriptors = {
WikiInfo.propertyDescriptors = {
// Update & expose
- name: Thing.common.name("Unnamed Wiki"),
+ name: Thing.common.name('Unnamed Wiki'),
// Displayed in nav bar.
nameShort: {
- flags: { update: true, expose: true },
- update: { validate: isName },
+ flags: {update: true, expose: true},
+ update: {validate: isName},
expose: {
- dependencies: ["name"],
- transform: (value, { name }) => value ?? name,
+ dependencies: ['name'],
+ transform: (value, {name}) => value ?? name,
},
},
@@ -1532,13 +1529,13 @@ WikiInfo.propertyDescriptors = {
footerContent: Thing.common.simpleString(),
defaultLanguage: {
- flags: { update: true, expose: true },
- update: { validate: isLanguageCode },
+ flags: {update: true, expose: true},
+ update: {validate: isLanguageCode},
},
canonicalBase: {
- flags: { update: true, expose: true },
- update: { validate: isURL },
+ flags: {update: true, expose: true},
+ update: {validate: isURL},
},
divideTrackListsByGroupsByRef: Thing.common.referenceList(Group),
@@ -1557,8 +1554,8 @@ WikiInfo.propertyDescriptors = {
// Expose only
divideTrackListsByGroups: Thing.common.dynamicThingsFromReferenceList(
- "divideTrackListsByGroupsByRef",
- "groupData",
+ 'divideTrackListsByGroupsByRef',
+ 'groupData',
find.group
),
};
@@ -1566,10 +1563,10 @@ WikiInfo.propertyDescriptors = {
// -> Language
const intlHelper = (constructor, opts) => ({
- flags: { expose: true },
+ flags: {expose: true},
expose: {
- dependencies: ["code", "intlCode"],
- compute: ({ code, intlCode }) => {
+ dependencies: ['code', 'intlCode'],
+ compute: ({code, intlCode}) => {
const constructCode = intlCode ?? code;
if (!constructCode) return null;
return Reflect.construct(constructor, [constructCode, opts]);
@@ -1584,8 +1581,8 @@ Language.propertyDescriptors = {
// from other languages (similar to how "Directory" operates in many data
// objects).
code: {
- flags: { update: true, expose: true },
- update: { validate: isLanguageCode },
+ flags: {update: true, expose: true},
+ update: {validate: isLanguageCode},
},
// Human-readable name. This should be the language's own native name, not
@@ -1596,11 +1593,11 @@ Language.propertyDescriptors = {
// Usually this will be the same as the language's general code, but it
// may be overridden to provide Intl constructors an alternative value.
intlCode: {
- flags: { update: true, expose: true },
- update: { validate: isLanguageCode },
+ flags: {update: true, expose: true},
+ update: {validate: isLanguageCode},
expose: {
- dependencies: ["code"],
- transform: (intlCode, { code }) => intlCode ?? code,
+ dependencies: ['code'],
+ transform: (intlCode, {code}) => intlCode ?? code,
},
},
@@ -1617,13 +1614,13 @@ Language.propertyDescriptors = {
// Mapping of translation keys to values (strings). Generally, don't
// access this object directly - use methods instead.
strings: {
- flags: { update: true, expose: true },
- update: { validate: (t) => typeof t === "object" },
+ flags: {update: true, expose: true},
+ update: {validate: (t) => typeof t === 'object'},
expose: {
- dependencies: ["inheritedStrings"],
- transform(strings, { inheritedStrings }) {
+ dependencies: ['inheritedStrings'],
+ transform(strings, {inheritedStrings}) {
if (strings || inheritedStrings) {
- return { ...(inheritedStrings ?? {}), ...(strings ?? {}) };
+ return {...(inheritedStrings ?? {}), ...(strings ?? {})};
} else {
return null;
}
@@ -1634,8 +1631,8 @@ Language.propertyDescriptors = {
// May be provided to specify "default" strings, generally (but not
// necessarily) inherited from another Language object.
inheritedStrings: {
- flags: { update: true, expose: true },
- update: { validate: (t) => typeof t === "object" },
+ flags: {update: true, expose: true},
+ update: {validate: (t) => typeof t === 'object'},
},
// Update only
@@ -1644,20 +1641,20 @@ Language.propertyDescriptors = {
// Expose only
- intl_date: intlHelper(Intl.DateTimeFormat, { full: true }),
+ intl_date: intlHelper(Intl.DateTimeFormat, {full: true}),
intl_number: intlHelper(Intl.NumberFormat),
- intl_listConjunction: intlHelper(Intl.ListFormat, { type: "conjunction" }),
- intl_listDisjunction: intlHelper(Intl.ListFormat, { type: "disjunction" }),
- intl_listUnit: intlHelper(Intl.ListFormat, { type: "unit" }),
- intl_pluralCardinal: intlHelper(Intl.PluralRules, { type: "cardinal" }),
- intl_pluralOrdinal: intlHelper(Intl.PluralRules, { type: "ordinal" }),
+ intl_listConjunction: intlHelper(Intl.ListFormat, {type: 'conjunction'}),
+ intl_listDisjunction: intlHelper(Intl.ListFormat, {type: 'disjunction'}),
+ intl_listUnit: intlHelper(Intl.ListFormat, {type: 'unit'}),
+ intl_pluralCardinal: intlHelper(Intl.PluralRules, {type: 'cardinal'}),
+ intl_pluralOrdinal: intlHelper(Intl.PluralRules, {type: 'ordinal'}),
validKeys: {
- flags: { expose: true },
+ flags: {expose: true},
expose: {
- dependencies: ["strings", "inheritedStrings"],
- compute: ({ strings, inheritedStrings }) =>
+ dependencies: ['strings', 'inheritedStrings'],
+ compute: ({strings, inheritedStrings}) =>
Array.from(
new Set([
...Object.keys(inheritedStrings ?? {}),
@@ -1668,12 +1665,12 @@ Language.propertyDescriptors = {
},
strings_htmlEscaped: {
- flags: { expose: true },
+ flags: {expose: true},
expose: {
- dependencies: ["strings", "inheritedStrings", "escapeHTML"],
- compute({ strings, inheritedStrings, escapeHTML }) {
+ dependencies: ['strings', 'inheritedStrings', 'escapeHTML'],
+ compute({strings, inheritedStrings, escapeHTML}) {
if (!(strings || inheritedStrings) || !escapeHTML) return null;
- const allStrings = { ...(inheritedStrings ?? {}), ...(strings ?? {}) };
+ const allStrings = {...(inheritedStrings ?? {}), ...(strings ?? {})};
return Object.fromEntries(
Object.entries(allStrings).map(([k, v]) => [k, escapeHTML(v)])
);
@@ -1683,12 +1680,12 @@ Language.propertyDescriptors = {
};
const countHelper = (stringKey, argName = stringKey) =>
- function (value, { unit = false } = {}) {
+ function (value, {unit = false} = {}) {
return this.$(
unit
? `count.${stringKey}.withUnit.` + this.getUnitForm(value)
: `count.${stringKey}`,
- { [argName]: this.formatNumber(value) }
+ {[argName]: this.formatNumber(value)}
);
};
@@ -1704,7 +1701,7 @@ Object.assign(Language.prototype, {
},
getUnitForm(value) {
- this.assertIntlAvailable("intl_pluralCardinal");
+ this.assertIntlAvailable('intl_pluralCardinal');
return this.intl_pluralCardinal.select(value);
},
@@ -1738,7 +1735,7 @@ Object.assign(Language.prototype, {
// like, who cares, dude?) Also, this is an array, 8ecause it's handy
// for the iterating we're a8out to do.
const processedArgs = Object.entries(args).map(([k, v]) => [
- k.replace(/[A-Z]/g, "_$&").toUpperCase(),
+ k.replace(/[A-Z]/g, '_$&').toUpperCase(),
v,
]);
@@ -1758,55 +1755,55 @@ Object.assign(Language.prototype, {
},
formatDate(date) {
- this.assertIntlAvailable("intl_date");
+ this.assertIntlAvailable('intl_date');
return this.intl_date.format(date);
},
formatDateRange(startDate, endDate) {
- this.assertIntlAvailable("intl_date");
+ this.assertIntlAvailable('intl_date');
return this.intl_date.formatRange(startDate, endDate);
},
- formatDuration(secTotal, { approximate = false, unit = false } = {}) {
+ formatDuration(secTotal, {approximate = false, unit = false} = {}) {
if (secTotal === 0) {
- return this.formatString("count.duration.missing");
+ return this.formatString('count.duration.missing');
}
const hour = Math.floor(secTotal / 3600);
const min = Math.floor((secTotal - hour * 3600) / 60);
const sec = Math.floor(secTotal - hour * 3600 - min * 60);
- const pad = (val) => val.toString().padStart(2, "0");
+ const pad = (val) => val.toString().padStart(2, '0');
- const stringSubkey = unit ? ".withUnit" : "";
+ const stringSubkey = unit ? '.withUnit' : '';
const duration =
hour > 0
- ? this.formatString("count.duration.hours" + stringSubkey, {
+ ? this.formatString('count.duration.hours' + stringSubkey, {
hours: hour,
minutes: pad(min),
seconds: pad(sec),
})
- : this.formatString("count.duration.minutes" + stringSubkey, {
+ : this.formatString('count.duration.minutes' + stringSubkey, {
minutes: min,
seconds: pad(sec),
});
return approximate
- ? this.formatString("count.duration.approximate", { duration })
+ ? this.formatString('count.duration.approximate', {duration})
: duration;
},
formatIndex(value) {
- this.assertIntlAvailable("intl_pluralOrdinal");
+ this.assertIntlAvailable('intl_pluralOrdinal');
return this.formatString(
- "count.index." + this.intl_pluralOrdinal.select(value),
- { index: value }
+ 'count.index.' + this.intl_pluralOrdinal.select(value),
+ {index: value}
);
},
formatNumber(value) {
- this.assertIntlAvailable("intl_number");
+ this.assertIntlAvailable('intl_number');
return this.intl_number.format(value);
},
@@ -1817,70 +1814,70 @@ Object.assign(Language.prototype, {
const words =
value > 1000
- ? this.formatString("count.words.thousand", { words: num })
- : this.formatString("count.words", { words: num });
+ ? this.formatString('count.words.thousand', {words: num})
+ : this.formatString('count.words', {words: num});
return this.formatString(
- "count.words.withUnit." + this.getUnitForm(value),
- { words }
+ 'count.words.withUnit.' + this.getUnitForm(value),
+ {words}
);
},
// Conjunction list: A, B, and C
formatConjunctionList(array) {
- this.assertIntlAvailable("intl_listConjunction");
+ this.assertIntlAvailable('intl_listConjunction');
return this.intl_listConjunction.format(array);
},
// Disjunction lists: A, B, or C
formatDisjunctionList(array) {
- this.assertIntlAvailable("intl_listDisjunction");
+ this.assertIntlAvailable('intl_listDisjunction');
return this.intl_listDisjunction.format(array);
},
// Unit lists: A, B, C
formatUnitList(array) {
- this.assertIntlAvailable("intl_listUnit");
+ this.assertIntlAvailable('intl_listUnit');
return this.intl_listUnit.format(array);
},
// File sizes: 42.5 kB, 127.2 MB, 4.13 GB, 998.82 TB
formatFileSize(bytes) {
- if (!bytes) return "";
+ if (!bytes) return '';
bytes = parseInt(bytes);
- if (isNaN(bytes)) return "";
+ if (isNaN(bytes)) return '';
const round = (exp) => Math.round(bytes / 10 ** (exp - 1)) / 10;
if (bytes >= 10 ** 12) {
- return this.formatString("count.fileSize.terabytes", {
+ return this.formatString('count.fileSize.terabytes', {
terabytes: round(12),
});
} else if (bytes >= 10 ** 9) {
- return this.formatString("count.fileSize.gigabytes", {
+ return this.formatString('count.fileSize.gigabytes', {
gigabytes: round(9),
});
} else if (bytes >= 10 ** 6) {
- return this.formatString("count.fileSize.megabytes", {
+ return this.formatString('count.fileSize.megabytes', {
megabytes: round(6),
});
} else if (bytes >= 10 ** 3) {
- return this.formatString("count.fileSize.kilobytes", {
+ return this.formatString('count.fileSize.kilobytes', {
kilobytes: round(3),
});
} else {
- return this.formatString("count.fileSize.bytes", { bytes });
+ return this.formatString('count.fileSize.bytes', {bytes});
}
},
// TODO: These are hard-coded. Is there a better way?
- countAdditionalFiles: countHelper("additionalFiles", "files"),
- countAlbums: countHelper("albums"),
- countCommentaryEntries: countHelper("commentaryEntries", "entries"),
- countContributions: countHelper("contributions"),
- countCoverArts: countHelper("coverArts"),
- countTimesReferenced: countHelper("timesReferenced"),
- countTimesUsed: countHelper("timesUsed"),
- countTracks: countHelper("tracks"),
+ countAdditionalFiles: countHelper('additionalFiles', 'files'),
+ countAlbums: countHelper('albums'),
+ countCommentaryEntries: countHelper('commentaryEntries', 'entries'),
+ countContributions: countHelper('contributions'),
+ countCoverArts: countHelper('coverArts'),
+ countTimesReferenced: countHelper('timesReferenced'),
+ countTimesUsed: countHelper('timesUsed'),
+ countTracks: countHelper('tracks'),
});
diff --git a/src/data/validators.js b/src/data/validators.js
index eab26896..8d922399 100644
--- a/src/data/validators.js
+++ b/src/data/validators.js
@@ -1,13 +1,13 @@
-// @format
+/** @format */
-import { withAggregate } from "../util/sugar.js";
+import {withAggregate} from '../util/sugar.js';
-import { color, ENABLE_COLOR, decorateTime } from "../util/cli.js";
+import {color, ENABLE_COLOR} from '../util/cli.js';
-import { inspect as nodeInspect } from "util";
+import {inspect as nodeInspect} from 'util';
function inspect(value) {
- return nodeInspect(value, { colors: ENABLE_COLOR });
+ return nodeInspect(value, {colors: ENABLE_COLOR});
}
// Basic types (primitives)
@@ -24,11 +24,11 @@ function isType(value, type) {
}
export function isBoolean(value) {
- return isType(value, "boolean");
+ return isType(value, 'boolean');
}
export function isNumber(value) {
- return isType(value, "number");
+ return isType(value, 'number');
}
export function isPositive(number) {
@@ -86,7 +86,7 @@ export function isWholeNumber(number) {
}
export function isString(value) {
- return isType(value, "string");
+ return isType(value, 'string');
}
export function isStringNonEmpty(value) {
@@ -116,7 +116,7 @@ export function isDate(value) {
}
export function isObject(value) {
- isType(value, "object");
+ isType(value, 'object');
// Note: Please remember that null is always a valid value for properties
// held by a CacheableObject. This assertion is exclusively for use in other
@@ -127,7 +127,7 @@ export function isObject(value) {
}
export function isArray(value) {
- if (typeof value !== "object" || value === null || !Array.isArray(value))
+ if (typeof value !== 'object' || value === null || !Array.isArray(value))
throw new TypeError(`Expected an array, got ${value}`);
return true;
@@ -156,7 +156,7 @@ export function validateArrayItems(itemValidator) {
return (array) => {
isArray(array);
- withAggregate({ message: "Errors validating array items" }, ({ wrap }) => {
+ withAggregate({message: 'Errors validating array items'}, ({wrap}) => {
array.forEach(wrap(fn));
});
@@ -173,7 +173,7 @@ export function validateInstanceOf(constructor) {
export function isColor(color) {
isStringNonEmpty(color);
- if (color.startsWith("#")) {
+ if (color.startsWith('#')) {
if (![1 + 3, 1 + 4, 1 + 6, 1 + 8].includes(color.length))
throw new TypeError(
`Expected #rgb, #rgba, #rrggbb, or #rrggbbaa, got length ${color.length}`
@@ -192,7 +192,7 @@ export function isCommentary(commentary) {
return isString(commentary);
}
-const isArtistRef = validateReference("artist");
+const isArtistRef = validateReference('artist');
export function validateProperties(spec) {
const specEntries = Object.entries(spec);
@@ -205,8 +205,8 @@ export function validateProperties(spec) {
throw new TypeError(`Expected an object, got array`);
withAggregate(
- { message: `Errors validating object properties` },
- ({ call }) => {
+ {message: `Errors validating object properties`},
+ ({call}) => {
for (const [specKey, specValidator] of specEntries) {
call(() => {
const value = object[specKey];
@@ -229,7 +229,7 @@ export function validateProperties(spec) {
throw new Error(
`Unknown keys present (${
unknownKeys.length
- }): [${unknownKeys.join(", ")}]`
+ }): [${unknownKeys.join(', ')}]`
);
});
}
@@ -273,7 +273,7 @@ export function isDimensions(dimensions) {
export function isDirectory(directory) {
isStringNonEmpty(directory);
- if (directory.match(/[^a-zA-Z0-9_\-]/))
+ if (directory.match(/[^a-zA-Z0-9_-]/))
throw new TypeError(
`Expected only letters, numbers, dash, and underscore, got "${directory}"`
);
@@ -291,7 +291,7 @@ export function isDuration(duration) {
export function isFileExtension(string) {
isStringNonEmpty(string);
- if (string[0] === ".")
+ if (string[0] === '.')
throw new TypeError(`Expected no dot (.) at the start of file extension`);
if (string.match(/[^a-zA-Z0-9_]/))
@@ -321,7 +321,7 @@ export function isURL(string) {
return true;
}
-export function validateReference(type = "track") {
+export function validateReference(type = 'track') {
return (ref) => {
isStringNonEmpty(ref);
@@ -332,7 +332,7 @@ export function validateReference(type = "track") {
if (!match) throw new TypeError(`Malformed reference`);
const {
- groups: { typePart, directoryPart },
+ groups: {typePart, directoryPart},
} = match;
if (typePart && typePart !== type)
@@ -348,7 +348,7 @@ export function validateReference(type = "track") {
};
}
-export function validateReferenceList(type = "") {
+export function validateReferenceList(type = '') {
return validateArrayItems(validateReference(type));
}
diff --git a/src/data/yaml.js b/src/data/yaml.js
index 5058bb39..a4255764 100644
--- a/src/data/yaml.js
+++ b/src/data/yaml.js
@@ -1,13 +1,13 @@
-// @format
-//
+/** @format */
+
// yaml.js - specification for HSMusic YAML data file format and utilities for
// loading and processing YAML files and documents
-import * as path from "path";
-import yaml from "js-yaml";
+import * as path from 'path';
+import yaml from 'js-yaml';
-import { readFile } from "fs/promises";
-import { inspect as nodeInspect } from "util";
+import {readFile} from 'fs/promises';
+import {inspect as nodeInspect} from 'util';
import {
Album,
@@ -19,16 +19,15 @@ import {
GroupCategory,
HomepageLayout,
HomepageLayoutAlbumsRow,
- HomepageLayoutRow,
NewsEntry,
StaticPage,
Thing,
Track,
TrackGroup,
WikiInfo,
-} from "./things.js";
+} from './things.js';
-import { color, ENABLE_COLOR, logInfo, logWarn } from "../util/cli.js";
+import {color, ENABLE_COLOR, logInfo, logWarn} from '../util/cli.js';
import {
decorateErrorWithIndex,
@@ -36,36 +35,36 @@ import {
openAggregate,
showAggregate,
withAggregate,
-} from "../util/sugar.js";
+} from '../util/sugar.js';
import {
sortAlbumsTracksChronologically,
sortAlphabetically,
sortChronologically,
-} from "../util/wiki-data.js";
+} from '../util/wiki-data.js';
-import find, { bindFind } from "../util/find.js";
-import { findFiles } from "../util/io.js";
+import find, {bindFind} from '../util/find.js';
+import {findFiles} from '../util/io.js';
// --> General supporting stuff
function inspect(value) {
- return nodeInspect(value, { colors: ENABLE_COLOR });
+ return nodeInspect(value, {colors: ENABLE_COLOR});
}
// --> YAML data repository structure constants
-export const WIKI_INFO_FILE = "wiki-info.yaml";
-export const BUILD_DIRECTIVE_DATA_FILE = "build-directives.yaml";
-export const HOMEPAGE_LAYOUT_DATA_FILE = "homepage.yaml";
-export const ARTIST_DATA_FILE = "artists.yaml";
-export const FLASH_DATA_FILE = "flashes.yaml";
-export const NEWS_DATA_FILE = "news.yaml";
-export const ART_TAG_DATA_FILE = "tags.yaml";
-export const GROUP_DATA_FILE = "groups.yaml";
-export const STATIC_PAGE_DATA_FILE = "static-pages.yaml";
+export const WIKI_INFO_FILE = 'wiki-info.yaml';
+export const BUILD_DIRECTIVE_DATA_FILE = 'build-directives.yaml';
+export const HOMEPAGE_LAYOUT_DATA_FILE = 'homepage.yaml';
+export const ARTIST_DATA_FILE = 'artists.yaml';
+export const FLASH_DATA_FILE = 'flashes.yaml';
+export const NEWS_DATA_FILE = 'news.yaml';
+export const ART_TAG_DATA_FILE = 'tags.yaml';
+export const GROUP_DATA_FILE = 'groups.yaml';
+export const STATIC_PAGE_DATA_FILE = 'static-pages.yaml';
-export const DATA_ALBUM_DIRECTORY = "album";
+export const DATA_ALBUM_DIRECTORY = 'album';
// --> Document processing functions
@@ -119,7 +118,7 @@ function makeProcessDocument(
);
const decorateErrorWithName = (fn) => {
- const nameField = propertyFieldMapping["name"];
+ const nameField = propertyFieldMapping['name'];
if (!nameField) return fn;
return (document) => {
@@ -168,8 +167,8 @@ function makeProcessDocument(
const thing = Reflect.construct(thingClass, []);
withAggregate(
- { message: `Errors applying ${color.green(thingClass.name)} properties` },
- ({ call }) => {
+ {message: `Errors applying ${color.green(thingClass.name)} properties`},
+ ({call}) => {
for (const [property, value] of Object.entries(sourceProperties)) {
call(() => (thing[property] = value));
}
@@ -184,7 +183,7 @@ makeProcessDocument.UnknownFieldsError = class UnknownFieldsError extends (
Error
) {
constructor(fields) {
- super(`Unknown fields present: ${fields.join(", ")}`);
+ super(`Unknown fields present: ${fields.join(', ')}`);
this.fields = fields;
}
};
@@ -192,72 +191,72 @@ makeProcessDocument.UnknownFieldsError = class UnknownFieldsError extends (
export const processAlbumDocument = makeProcessDocument(Album, {
fieldTransformations: {
Artists: parseContributors,
- "Cover Artists": parseContributors,
- "Default Track Cover Artists": parseContributors,
- "Wallpaper Artists": parseContributors,
- "Banner Artists": parseContributors,
+ 'Cover Artists': parseContributors,
+ 'Default Track Cover Artists': parseContributors,
+ 'Wallpaper Artists': parseContributors,
+ 'Banner Artists': parseContributors,
Date: (value) => new Date(value),
- "Date Added": (value) => new Date(value),
- "Cover Art Date": (value) => new Date(value),
- "Default Track Cover Art Date": (value) => new Date(value),
+ 'Date Added': (value) => new Date(value),
+ 'Cover Art Date': (value) => new Date(value),
+ 'Default Track Cover Art Date': (value) => new Date(value),
- "Banner Dimensions": parseDimensions,
+ 'Banner Dimensions': parseDimensions,
- "Additional Files": parseAdditionalFiles,
+ 'Additional Files': parseAdditionalFiles,
},
propertyFieldMapping: {
- name: "Album",
+ name: 'Album',
- color: "Color",
- directory: "Directory",
- urls: "URLs",
+ color: 'Color',
+ directory: 'Directory',
+ urls: 'URLs',
- artistContribsByRef: "Artists",
- coverArtistContribsByRef: "Cover Artists",
- trackCoverArtistContribsByRef: "Default Track Cover Artists",
+ artistContribsByRef: 'Artists',
+ coverArtistContribsByRef: 'Cover Artists',
+ trackCoverArtistContribsByRef: 'Default Track Cover Artists',
- coverArtFileExtension: "Cover Art File Extension",
- trackCoverArtFileExtension: "Track Art File Extension",
+ coverArtFileExtension: 'Cover Art File Extension',
+ trackCoverArtFileExtension: 'Track Art File Extension',
- wallpaperArtistContribsByRef: "Wallpaper Artists",
- wallpaperStyle: "Wallpaper Style",
- wallpaperFileExtension: "Wallpaper File Extension",
+ wallpaperArtistContribsByRef: 'Wallpaper Artists',
+ wallpaperStyle: 'Wallpaper Style',
+ wallpaperFileExtension: 'Wallpaper File Extension',
- bannerArtistContribsByRef: "Banner Artists",
- bannerStyle: "Banner Style",
- bannerFileExtension: "Banner File Extension",
- bannerDimensions: "Banner Dimensions",
+ bannerArtistContribsByRef: 'Banner Artists',
+ bannerStyle: 'Banner Style',
+ bannerFileExtension: 'Banner File Extension',
+ bannerDimensions: 'Banner Dimensions',
- date: "Date",
- trackArtDate: "Default Track Cover Art Date",
- coverArtDate: "Cover Art Date",
- dateAddedToWiki: "Date Added",
+ date: 'Date',
+ trackArtDate: 'Default Track Cover Art Date',
+ coverArtDate: 'Cover Art Date',
+ dateAddedToWiki: 'Date Added',
- hasCoverArt: "Has Cover Art",
- hasTrackArt: "Has Track Art",
- hasTrackNumbers: "Has Track Numbers",
- isMajorRelease: "Major Release",
- isListedOnHomepage: "Listed on Homepage",
+ hasCoverArt: 'Has Cover Art',
+ hasTrackArt: 'Has Track Art',
+ hasTrackNumbers: 'Has Track Numbers',
+ isMajorRelease: 'Major Release',
+ isListedOnHomepage: 'Listed on Homepage',
- groupsByRef: "Groups",
- artTagsByRef: "Art Tags",
- commentary: "Commentary",
+ groupsByRef: 'Groups',
+ artTagsByRef: 'Art Tags',
+ commentary: 'Commentary',
- additionalFiles: "Additional Files",
+ additionalFiles: 'Additional Files',
},
});
export const processTrackGroupDocument = makeProcessDocument(TrackGroup, {
fieldTransformations: {
- "Date Originally Released": (value) => new Date(value),
+ 'Date Originally Released': (value) => new Date(value),
},
propertyFieldMapping: {
- name: "Group",
- color: "Color",
- dateOriginallyReleased: "Date Originally Released",
+ name: 'Group',
+ color: 'Color',
+ dateOriginallyReleased: 'Date Originally Released',
},
});
@@ -265,60 +264,60 @@ export const processTrackDocument = makeProcessDocument(Track, {
fieldTransformations: {
Duration: getDurationInSeconds,
- "Date First Released": (value) => new Date(value),
- "Cover Art Date": (value) => new Date(value),
+ 'Date First Released': (value) => new Date(value),
+ 'Cover Art Date': (value) => new Date(value),
Artists: parseContributors,
Contributors: parseContributors,
- "Cover Artists": parseContributors,
+ 'Cover Artists': parseContributors,
- "Additional Files": parseAdditionalFiles,
+ 'Additional Files': parseAdditionalFiles,
},
propertyFieldMapping: {
- name: "Track",
+ name: 'Track',
- directory: "Directory",
- duration: "Duration",
- urls: "URLs",
+ directory: 'Directory',
+ duration: 'Duration',
+ urls: 'URLs',
- coverArtDate: "Cover Art Date",
- coverArtFileExtension: "Cover Art File Extension",
- dateFirstReleased: "Date First Released",
- hasCoverArt: "Has Cover Art",
- hasURLs: "Has URLs",
+ coverArtDate: 'Cover Art Date',
+ coverArtFileExtension: 'Cover Art File Extension',
+ dateFirstReleased: 'Date First Released',
+ hasCoverArt: 'Has Cover Art',
+ hasURLs: 'Has URLs',
- referencedTracksByRef: "Referenced Tracks",
- artistContribsByRef: "Artists",
- contributorContribsByRef: "Contributors",
- coverArtistContribsByRef: "Cover Artists",
- artTagsByRef: "Art Tags",
- originalReleaseTrackByRef: "Originally Released As",
+ referencedTracksByRef: 'Referenced Tracks',
+ artistContribsByRef: 'Artists',
+ contributorContribsByRef: 'Contributors',
+ coverArtistContribsByRef: 'Cover Artists',
+ artTagsByRef: 'Art Tags',
+ originalReleaseTrackByRef: 'Originally Released As',
- commentary: "Commentary",
- lyrics: "Lyrics",
+ commentary: 'Commentary',
+ lyrics: 'Lyrics',
- additionalFiles: "Additional Files",
+ additionalFiles: 'Additional Files',
},
- ignoredFields: ["Sampled Tracks"],
+ ignoredFields: ['Sampled Tracks'],
});
export const processArtistDocument = makeProcessDocument(Artist, {
propertyFieldMapping: {
- name: "Artist",
+ name: 'Artist',
- directory: "Directory",
- urls: "URLs",
- hasAvatar: "Has Avatar",
- avatarFileExtension: "Avatar File Extension",
+ directory: 'Directory',
+ urls: 'URLs',
+ hasAvatar: 'Has Avatar',
+ avatarFileExtension: 'Avatar File Extension',
- aliasNames: "Aliases",
+ aliasNames: 'Aliases',
- contextNotes: "Context Notes",
+ contextNotes: 'Context Notes',
},
- ignoredFields: ["Dead URLs"],
+ ignoredFields: ['Dead URLs'],
});
export const processFlashDocument = makeProcessDocument(Flash, {
@@ -329,26 +328,26 @@ export const processFlashDocument = makeProcessDocument(Flash, {
},
propertyFieldMapping: {
- name: "Flash",
+ name: 'Flash',
- directory: "Directory",
- page: "Page",
- date: "Date",
- coverArtFileExtension: "Cover Art File Extension",
+ directory: 'Directory',
+ page: 'Page',
+ date: 'Date',
+ coverArtFileExtension: 'Cover Art File Extension',
- featuredTracksByRef: "Featured Tracks",
- contributorContribsByRef: "Contributors",
- urls: "URLs",
+ featuredTracksByRef: 'Featured Tracks',
+ contributorContribsByRef: 'Contributors',
+ urls: 'URLs',
},
});
export const processFlashActDocument = makeProcessDocument(FlashAct, {
propertyFieldMapping: {
- name: "Act",
- color: "Color",
- anchor: "Anchor",
- jump: "Jump",
- jumpColor: "Jump Color",
+ name: 'Act',
+ color: 'Color',
+ anchor: 'Anchor',
+ jump: 'Jump',
+ jumpColor: 'Jump Color',
},
});
@@ -358,66 +357,66 @@ export const processNewsEntryDocument = makeProcessDocument(NewsEntry, {
},
propertyFieldMapping: {
- name: "Name",
- directory: "Directory",
- date: "Date",
- content: "Content",
+ name: 'Name',
+ directory: 'Directory',
+ date: 'Date',
+ content: 'Content',
},
});
export const processArtTagDocument = makeProcessDocument(ArtTag, {
propertyFieldMapping: {
- name: "Tag",
- directory: "Directory",
- color: "Color",
- isContentWarning: "Is CW",
+ name: 'Tag',
+ directory: 'Directory',
+ color: 'Color',
+ isContentWarning: 'Is CW',
},
});
export const processGroupDocument = makeProcessDocument(Group, {
propertyFieldMapping: {
- name: "Group",
- directory: "Directory",
- description: "Description",
- urls: "URLs",
+ name: 'Group',
+ directory: 'Directory',
+ description: 'Description',
+ urls: 'URLs',
},
});
export const processGroupCategoryDocument = makeProcessDocument(GroupCategory, {
propertyFieldMapping: {
- name: "Category",
- color: "Color",
+ name: 'Category',
+ color: 'Color',
},
});
export const processStaticPageDocument = makeProcessDocument(StaticPage, {
propertyFieldMapping: {
- name: "Name",
- nameShort: "Short Name",
- directory: "Directory",
+ name: 'Name',
+ nameShort: 'Short Name',
+ directory: 'Directory',
- content: "Content",
- stylesheet: "Style",
+ content: 'Content',
+ stylesheet: 'Style',
- showInNavigationBar: "Show in Navigation Bar",
+ showInNavigationBar: 'Show in Navigation Bar',
},
});
export const processWikiInfoDocument = makeProcessDocument(WikiInfo, {
propertyFieldMapping: {
- name: "Name",
- nameShort: "Short Name",
- color: "Color",
- description: "Description",
- footerContent: "Footer Content",
- defaultLanguage: "Default Language",
- canonicalBase: "Canonical Base",
- divideTrackListsByGroupsByRef: "Divide Track Lists By Groups",
- enableFlashesAndGames: "Enable Flashes & Games",
- enableListings: "Enable Listings",
- enableNews: "Enable News",
- enableArtTagUI: "Enable Art Tag UI",
- enableGroupUI: "Enable Group UI",
+ name: 'Name',
+ nameShort: 'Short Name',
+ color: 'Color',
+ description: 'Description',
+ footerContent: 'Footer Content',
+ defaultLanguage: 'Default Language',
+ canonicalBase: 'Canonical Base',
+ divideTrackListsByGroupsByRef: 'Divide Track Lists By Groups',
+ enableFlashesAndGames: 'Enable Flashes & Games',
+ enableListings: 'Enable Listings',
+ enableNews: 'Enable News',
+ enableArtTagUI: 'Enable Art Tag UI',
+ enableGroupUI: 'Enable Group UI',
},
});
@@ -425,10 +424,10 @@ export const processHomepageLayoutDocument = makeProcessDocument(
HomepageLayout,
{
propertyFieldMapping: {
- sidebarContent: "Sidebar Content",
+ sidebarContent: 'Sidebar Content',
},
- ignoredFields: ["Homepage"],
+ ignoredFields: ['Homepage'],
}
);
@@ -437,9 +436,9 @@ export function makeProcessHomepageLayoutRowDocument(rowClass, spec) {
...spec,
propertyFieldMapping: {
- name: "Row",
- color: "Color",
- type: "Type",
+ name: 'Row',
+ color: 'Color',
+ type: 'Type',
...spec.propertyFieldMapping,
},
});
@@ -448,16 +447,16 @@ export function makeProcessHomepageLayoutRowDocument(rowClass, spec) {
export const homepageLayoutRowTypeProcessMapping = {
albums: makeProcessHomepageLayoutRowDocument(HomepageLayoutAlbumsRow, {
propertyFieldMapping: {
- sourceGroupByRef: "Group",
- countAlbumsFromGroup: "Count",
- sourceAlbumsByRef: "Albums",
- actionLinks: "Actions",
+ sourceGroupByRef: 'Group',
+ countAlbumsFromGroup: 'Count',
+ sourceAlbumsByRef: 'Albums',
+ actionLinks: 'Actions',
},
}),
};
export function processHomepageLayoutRowDocument(document) {
- const type = document["Type"];
+ const type = document['Type'];
const match = Object.entries(homepageLayoutRowTypeProcessMapping).find(
([key]) => key === type
@@ -473,15 +472,15 @@ export function processHomepageLayoutRowDocument(document) {
// --> Utilities shared across document parsing functions
export function getDurationInSeconds(string) {
- if (typeof string === "number") {
+ if (typeof string === 'number') {
return string;
}
- if (typeof string !== "string") {
+ if (typeof string !== 'string') {
throw new TypeError(`Expected a string or number, got ${string}`);
}
- const parts = string.split(":").map((n) => parseInt(n));
+ const parts = string.split(':').map((n) => parseInt(n));
if (parts.length === 3) {
return parts[0] * 3600 + parts[1] * 60 + parts[2];
} else if (parts.length === 2) {
@@ -499,16 +498,16 @@ export function parseAdditionalFiles(array) {
}
return array.map((item) => ({
- title: item["Title"],
- description: item["Description"] ?? null,
- files: item["Files"],
+ title: item['Title'],
+ description: item['Description'] ?? null,
+ files: item['Files'],
}));
}
export function parseCommentary(text) {
if (text) {
- const lines = String(text).split("\n");
- if (!lines[0].replace(/<\/b>/g, "").includes(":
${chunks
.map(
- ({ dateAddedToWiki, chunk: albums }) => fixWS`
+ ({dateAddedToWiki, chunk: albums}) => fixWS`
`;
},
},
{
- directory: "artists/by-name",
- stringsKey: "listArtists.byName",
+ directory: 'artists/by-name',
+ stringsKey: 'listArtists.byName',
- data({ wikiData }) {
+ data({wikiData}) {
return sortAlphabetically(wikiData.artistData.slice()).map((artist) => ({
artist,
contributions: getArtistNumContributions(artist),
}));
},
- row({ artist, contributions }, { link, language }) {
- return language.$("listingPage.listArtists.byName.item", {
+ row({artist, contributions}, {link, language}) {
+ return language.$('listingPage.listArtists.byName.item', {
artist: link.artist(artist),
contributions: language.countContributions(contributions, {
unit: true,
@@ -152,10 +152,10 @@ const listingSpec = [
},
{
- directory: "artists/by-contribs",
- stringsKey: "listArtists.byContribs",
+ directory: 'artists/by-contribs',
+ stringsKey: 'listArtists.byContribs',
- data({ wikiData }) {
+ data({wikiData}) {
return {
toTracks: wikiData.artistData
.map((artist) => ({
@@ -165,7 +165,7 @@ const listingSpec = [
(artist.tracksAsArtist?.length ?? 0),
}))
.sort((a, b) => b.contributions - a.contributions)
- .filter(({ contributions }) => contributions),
+ .filter(({contributions}) => contributions),
toArtAndFlashes: wikiData.artistData
.map((artist) => ({
@@ -180,7 +180,7 @@ const listingSpec = [
: 0),
}))
.sort((a, b) => b.contributions - a.contributions)
- .filter(({ contributions }) => contributions),
+ .filter(({contributions}) => contributions),
// This is a kinda naughty hack, 8ut like, it's the only place
// we'd 8e passing wikiData to html() otherwise, so like....
@@ -189,54 +189,54 @@ const listingSpec = [
};
},
- html({ toTracks, toArtAndFlashes, showAsFlashes }, { link, language }) {
+ html({toTracks, toArtAndFlashes, showAsFlashes}, {link, language}) {
return fixWS`
${language.$(
- "listingPage.misc.trackContributors"
+ 'listingPage.misc.trackContributors'
)}
${toTracks
- .map(({ artist, contributions }) =>
+ .map(({artist, contributions}) =>
language.$(
- "listingPage.listArtists.byContribs.item",
+ 'listingPage.listArtists.byContribs.item',
{
artist: link.artist(artist),
contributions: language.countContributions(
contributions,
- { unit: true }
+ {unit: true}
),
}
)
)
.map((row) => `
${language.$(
- "listingPage.misc" +
+ 'listingPage.misc' +
(showAsFlashes
- ? ".artAndFlashContributors"
- : ".artContributors")
+ ? '.artAndFlashContributors'
+ : '.artContributors')
)}
${toArtAndFlashes
- .map(({ artist, contributions }) =>
+ .map(({artist, contributions}) =>
language.$(
- "listingPage.listArtists.byContribs.item",
+ 'listingPage.listArtists.byContribs.item',
{
artist: link.artist(artist),
contributions: language.countContributions(
contributions,
- { unit: true }
+ {unit: true}
),
}
)
)
.map((row) => `
${language.$(
- "listingPage.misc.trackContributors"
+ 'listingPage.misc.trackContributors'
)}
${toTracks
- .map(({ artist, date }) =>
+ .map(({artist, date}) =>
language.$(
- "listingPage.listArtists.byLatest.item",
+ 'listingPage.listArtists.byLatest.item',
{
artist: link.artist(artist),
date: language.formatDate(date),
@@ -376,21 +376,21 @@ const listingSpec = [
)
)
.map((row) => `
${language.$(
- "listingPage.misc" +
+ 'listingPage.misc' +
(showAsFlashes
- ? ".artAndFlashContributors"
- : ".artContributors")
+ ? '.artAndFlashContributors'
+ : '.artContributors')
)}
${toArtAndFlashes
- .map(({ artist, date }) =>
+ .map(({artist, date}) =>
language.$(
- "listingPage.listArtists.byLatest.item",
+ 'listingPage.listArtists.byLatest.item',
{
artist: link.artist(artist),
date: language.formatDate(date),
@@ -398,7 +398,7 @@ const listingSpec = [
)
)
.map((row) => `
${groupCategoryData
.map(
(category) => fixWS`
`;
},
},
{
- directory: "groups/by-albums",
- stringsKey: "listGroups.byAlbums",
- condition: ({ wikiData }) => wikiData.wikiInfo.enableGroupUI,
+ directory: 'groups/by-albums',
+ stringsKey: 'listGroups.byAlbums',
+ condition: ({wikiData}) => wikiData.wikiInfo.enableGroupUI,
- data({ wikiData }) {
+ data({wikiData}) {
return wikiData.groupData
- .map((group) => ({ group, albums: group.albums.length }))
+ .map((group) => ({group, albums: group.albums.length}))
.sort((a, b) => b.albums - a.albums);
},
- row({ group, albums }, { link, language }) {
- return language.$("listingPage.listGroups.byAlbums.item", {
+ row({group, albums}, {link, language}) {
+ return language.$('listingPage.listGroups.byAlbums.item', {
group: link.groupInfo(group),
- albums: language.countAlbums(albums, { unit: true }),
+ albums: language.countAlbums(albums, {unit: true}),
});
},
},
{
- directory: "groups/by-tracks",
- stringsKey: "listGroups.byTracks",
- condition: ({ wikiData }) => wikiData.wikiInfo.enableGroupUI,
+ directory: 'groups/by-tracks',
+ stringsKey: 'listGroups.byTracks',
+ condition: ({wikiData}) => wikiData.wikiInfo.enableGroupUI,
- data({ wikiData }) {
+ data({wikiData}) {
return wikiData.groupData
.map((group) => ({
group,
@@ -504,20 +504,20 @@ const listingSpec = [
.sort((a, b) => b.tracks - a.tracks);
},
- row({ group, tracks }, { link, language }) {
- return language.$("listingPage.listGroups.byTracks.item", {
+ row({group, tracks}, {link, language}) {
+ return language.$('listingPage.listGroups.byTracks.item', {
group: link.groupInfo(group),
- tracks: language.countTracks(tracks, { unit: true }),
+ tracks: language.countTracks(tracks, {unit: true}),
});
},
},
{
- directory: "groups/by-duration",
- stringsKey: "listGroups.byDuration",
- condition: ({ wikiData }) => wikiData.wikiInfo.enableGroupUI,
+ directory: 'groups/by-duration',
+ stringsKey: 'listGroups.byDuration',
+ condition: ({wikiData}) => wikiData.wikiInfo.enableGroupUI,
- data({ wikiData }) {
+ data({wikiData}) {
return wikiData.groupData
.map((group) => ({
group,
@@ -528,8 +528,8 @@ const listingSpec = [
.sort((a, b) => b.duration - a.duration);
},
- row({ group, duration }, { link, language }) {
- return language.$("listingPage.listGroups.byDuration.item", {
+ row({group, duration}, {link, language}) {
+ return language.$('listingPage.listGroups.byDuration.item', {
group: link.groupInfo(group),
duration: language.formatDuration(duration),
});
@@ -537,11 +537,11 @@ const listingSpec = [
},
{
- directory: "groups/by-latest-album",
- stringsKey: "listGroups.byLatest",
- condition: ({ wikiData }) => wikiData.wikiInfo.enableGroupUI,
+ directory: 'groups/by-latest-album',
+ stringsKey: 'listGroups.byLatest',
+ condition: ({wikiData}) => wikiData.wikiInfo.enableGroupUI,
- data({ wikiData }) {
+ data({wikiData}) {
return sortChronologically(
wikiData.groupData
.map((group) => {
@@ -572,8 +572,8 @@ const listingSpec = [
).reverse();
},
- row({ group, date }, { link, language }) {
- return language.$("listingPage.listGroups.byLatest.item", {
+ row({group, date}, {link, language}) {
+ return language.$('listingPage.listGroups.byLatest.item', {
group: link.groupInfo(group),
date: language.formatDate(date),
});
@@ -581,33 +581,33 @@ const listingSpec = [
},
{
- directory: "tracks/by-name",
- stringsKey: "listTracks.byName",
+ directory: 'tracks/by-name',
+ stringsKey: 'listTracks.byName',
- data({ wikiData }) {
+ data({wikiData}) {
return sortAlphabetically(wikiData.trackData.slice());
},
- row(track, { link, language }) {
- return language.$("listingPage.listTracks.byName.item", {
+ row(track, {link, language}) {
+ return language.$('listingPage.listTracks.byName.item', {
track: link.track(track),
});
},
},
{
- directory: "tracks/by-album",
- stringsKey: "listTracks.byAlbum",
- data: ({ wikiData }) => wikiData.albumData,
+ directory: 'tracks/by-album',
+ stringsKey: 'listTracks.byAlbum',
+ data: ({wikiData}) => wikiData.albumData,
- html(albumData, { link, language }) {
+ html(albumData, {link, language}) {
return fixWS`
${albumData
.map(
(album) => fixWS`
`;
},
},
{
- directory: "tracks/by-date",
- stringsKey: "listTracks.byDate",
+ directory: 'tracks/by-date',
+ stringsKey: 'listTracks.byDate',
- data({ wikiData }) {
+ data({wikiData}) {
return chunkByProperties(
sortChronologically(wikiData.trackData.filter((t) => t.date)),
- ["album", "date"]
+ ['album', 'date']
);
},
- html(chunks, { link, language }) {
+ html(chunks, {link, language}) {
return fixWS`
${chunks
.map(
- ({ album, date, chunk: tracks }) => fixWS`
+ ({album, date, chunk: tracks}) => fixWS`
`;
},
},
{
- directory: "tracks/by-duration",
- stringsKey: "listTracks.byDuration",
+ directory: 'tracks/by-duration',
+ stringsKey: 'listTracks.byDuration',
- data({ wikiData }) {
+ data({wikiData}) {
return wikiData.trackData
- .map((track) => ({ track, duration: track.duration }))
- .filter(({ duration }) => duration > 0)
+ .map((track) => ({track, duration: track.duration}))
+ .filter(({duration}) => duration > 0)
.sort((a, b) => b.duration - a.duration);
},
- row({ track, duration }, { link, language }) {
- return language.$("listingPage.listTracks.byDuration.item", {
+ row({track, duration}, {link, language}) {
+ return language.$('listingPage.listTracks.byDuration.item', {
track: link.track(track),
duration: language.formatDuration(duration),
});
@@ -704,10 +704,10 @@ const listingSpec = [
},
{
- directory: "tracks/by-duration-in-album",
- stringsKey: "listTracks.byDurationInAlbum",
+ directory: 'tracks/by-duration-in-album',
+ stringsKey: 'listTracks.byDurationInAlbum',
- data({ wikiData }) {
+ data({wikiData}) {
return wikiData.albumData.map((album) => ({
album,
tracks: album.tracks
@@ -716,14 +716,14 @@ const listingSpec = [
}));
},
- html(albums, { link, language }) {
+ html(albums, {link, language}) {
return fixWS`
${albums
.map(
- ({ album, tracks }) => fixWS`
+ ({album, tracks}) => fixWS`
`;
},
},
{
- directory: "tracks/by-times-referenced",
- stringsKey: "listTracks.byTimesReferenced",
+ directory: 'tracks/by-times-referenced',
+ stringsKey: 'listTracks.byTimesReferenced',
- data({ wikiData }) {
+ data({wikiData}) {
return wikiData.trackData
.map((track) => ({
track,
timesReferenced: track.referencedByTracks.length,
}))
- .filter(({ timesReferenced }) => timesReferenced > 0)
+ .filter(({timesReferenced}) => timesReferenced > 0)
.sort((a, b) => b.timesReferenced - a.timesReferenced);
},
- row({ track, timesReferenced }, { link, language }) {
- return language.$("listingPage.listTracks.byTimesReferenced.item", {
+ row({track, timesReferenced}, {link, language}) {
+ return language.$('listingPage.listTracks.byTimesReferenced.item', {
track: link.track(track),
timesReferenced: language.countTimesReferenced(timesReferenced, {
unit: true,
@@ -777,25 +777,25 @@ const listingSpec = [
},
{
- directory: "tracks/in-flashes/by-album",
- stringsKey: "listTracks.inFlashes.byAlbum",
- condition: ({ wikiData }) => wikiData.wikiInfo.enableFlashesAndGames,
+ directory: 'tracks/in-flashes/by-album',
+ stringsKey: 'listTracks.inFlashes.byAlbum',
+ condition: ({wikiData}) => wikiData.wikiInfo.enableFlashesAndGames,
- data({ wikiData }) {
+ data({wikiData}) {
return chunkByProperties(
wikiData.trackData.filter((t) => t.featuredInFlashes?.length > 0),
- ["album"]
+ ['album']
);
},
- html(chunks, { link, language }) {
+ html(chunks, {link, language}) {
return fixWS`
${chunks
.map(
- ({ album, chunk: tracks }) => fixWS`
+ ({album, chunk: tracks}) => fixWS`
`;
},
},
{
- directory: "tracks/in-flashes/by-flash",
- stringsKey: "listTracks.inFlashes.byFlash",
- condition: ({ wikiData }) => wikiData.wikiInfo.enableFlashesAndGames,
- data: ({ wikiData }) => wikiData.flashData,
+ directory: 'tracks/in-flashes/by-flash',
+ stringsKey: 'listTracks.inFlashes.byFlash',
+ condition: ({wikiData}) => wikiData.wikiInfo.enableFlashesAndGames,
+ data: ({wikiData}) => wikiData.flashData,
- html(flashData, { link, language }) {
+ html(flashData, {link, language}) {
return fixWS`
${sortChronologically(flashData.slice())
.map(
(flash) => fixWS`
`;
},
},
{
- directory: "tracks/with-lyrics",
- stringsKey: "listTracks.withLyrics",
+ directory: 'tracks/with-lyrics',
+ stringsKey: 'listTracks.withLyrics',
- data({ wikiData }) {
+ data({wikiData}) {
return wikiData.albumData
.map((album) => ({
album,
tracks: album.tracks.filter((t) => t.lyrics),
}))
- .filter(({ tracks }) => tracks.length > 0);
+ .filter(({tracks}) => tracks.length > 0);
},
- html(chunks, { link, language }) {
+ html(chunks, {link, language}) {
return fixWS`
${chunks
.map(
- ({ album, tracks }) => fixWS`
+ ({album, tracks}) => fixWS`
`;
},
},
{
- directory: "tags/by-name",
- stringsKey: "listTags.byName",
- condition: ({ wikiData }) => wikiData.wikiInfo.enableArtTagUI,
+ directory: 'tags/by-name',
+ stringsKey: 'listTags.byName',
+ condition: ({wikiData}) => wikiData.wikiInfo.enableArtTagUI,
- data({ wikiData }) {
+ data({wikiData}) {
return sortAlphabetically(
wikiData.artTagData.filter((tag) => !tag.isContentWarning)
- ).map((tag) => ({ tag, timesUsed: tag.taggedInThings?.length }));
+ ).map((tag) => ({tag, timesUsed: tag.taggedInThings?.length}));
},
- row({ tag, timesUsed }, { link, language }) {
- return language.$("listingPage.listTags.byName.item", {
+ row({tag, timesUsed}, {link, language}) {
+ return language.$('listingPage.listTags.byName.item', {
tag: link.tag(tag),
- timesUsed: language.countTimesUsed(timesUsed, { unit: true }),
+ timesUsed: language.countTimesUsed(timesUsed, {unit: true}),
});
},
},
{
- directory: "tags/by-uses",
- stringsKey: "listTags.byUses",
- condition: ({ wikiData }) => wikiData.wikiInfo.enableArtTagUI,
+ directory: 'tags/by-uses',
+ stringsKey: 'listTags.byUses',
+ condition: ({wikiData}) => wikiData.wikiInfo.enableArtTagUI,
- data({ wikiData }) {
+ data({wikiData}) {
return wikiData.artTagData
.filter((tag) => !tag.isContentWarning)
- .map((tag) => ({ tag, timesUsed: tag.taggedInThings?.length }))
+ .map((tag) => ({tag, timesUsed: tag.taggedInThings?.length}))
.sort((a, b) => b.timesUsed - a.timesUsed);
},
- row({ tag, timesUsed }, { link, language }) {
- return language.$("listingPage.listTags.byUses.item", {
+ row({tag, timesUsed}, {link, language}) {
+ return language.$('listingPage.listTags.byUses.item', {
tag: link.tag(tag),
- timesUsed: language.countTimesUsed(timesUsed, { unit: true }),
+ timesUsed: language.countTimesUsed(timesUsed, {unit: true}),
});
},
},
{
- directory: "random",
- stringsKey: "other.randomPages",
+ directory: 'random',
+ stringsKey: 'other.randomPages',
- data: ({ wikiData }) => ({
+ data: ({wikiData}) => ({
officialAlbumData: wikiData.officialAlbumData,
fandomAlbumData: wikiData.fandomAlbumData,
}),
html: (
- { officialAlbumData, fandomAlbumData },
- { getLinkThemeString, language }
+ {officialAlbumData, fandomAlbumData},
+ {getLinkThemeString, language}
) => fixWS`
${additionalFiles
.map(
- ({ title, description, files }) => fixWS`
+ ({title, description, files}) => fixWS`
`;
}
@@ -100,22 +100,22 @@ export function generateAdditionalFilesList(
export function getArtistString(
artists,
- { iconifyURL, link, language, showIcons = false, showContrib = false }
+ {iconifyURL, link, language, showIcons = false, showContrib = false}
) {
return language.formatConjunctionList(
- artists.map(({ who, what }) => {
- const { urls, directory, name } = who;
+ artists.map(({who, what}) => {
+ const {urls, directory, name} = who;
return [
link.artist(who),
showContrib && what && `(${what})`,
showIcons &&
urls?.length &&
`(${language.formatUnitList(
- urls.map((url) => iconifyURL(url, { language }))
+ urls.map((url) => iconifyURL(url, {language}))
)})`,
]
.filter(Boolean)
- .join(" ");
+ .join(' ');
})
);
}
@@ -125,7 +125,7 @@ export function getArtistString(
export function generateChronologyLinks(
currentThing,
{
- dateKey = "date",
+ dateKey = 'date',
contribKey,
getThings,
headingString,
@@ -135,28 +135,28 @@ export function generateChronologyLinks(
wikiData,
}
) {
- const { albumData } = wikiData;
+ const {albumData} = wikiData;
const contributions = currentThing[contribKey];
if (!contributions) {
- return "";
+ return '';
}
if (contributions.length > 8) {
return `
${files
@@ -72,7 +72,7 @@ export function generateAdditionalFilesList(
const size = getFileSize(file);
return size
? `
${language.$(
- "misc.contentWarnings.reveal"
+ 'misc.contentWarnings.reveal'
)}`
);
}
-export function getRevealStringFromTags(tags, { language }) {
+export function getRevealStringFromTags(tags, {language}) {
return (
tags &&
tags.some((tag) => tag.isContentWarning) &&
@@ -229,7 +229,7 @@ export function getRevealStringFromTags(tags, { language }) {
language.formatUnitList(
tags.filter((tag) => tag.isContentWarning).map((tag) => tag.name)
),
- { language }
+ {language}
)
);
}
@@ -247,7 +247,7 @@ export function generateCoverLink({
alt,
tags = [],
}) {
- const { wikiInfo } = wikiData;
+ const {wikiInfo} = wikiData;
if (!src && path) {
src = to(...path);
@@ -262,22 +262,22 @@ export function generateCoverLink({
${img({
src,
alt,
- thumb: "medium",
- id: "cover-art",
+ thumb: 'medium',
+ id: 'cover-art',
link: true,
square: true,
- reveal: getRevealStringFromTags(tags, { language }),
+ reveal: getRevealStringFromTags(tags, {language}),
})}
${
wikiInfo.enableArtTagUI &&
tags.filter((tag) => !tag.isContentWarning).length &&
fixWS`
`
}
@@ -288,9 +288,9 @@ export function generateCoverLink({
// CSS & color shenanigans
export function getThemeString(color, additionalVariables = []) {
- if (!color) return "";
+ if (!color) return '';
- const { primary, dim, bg } = getColors(color);
+ const {primary, dim, bg} = getColors(color);
const variables = [
`--primary-color: ${primary}`,
@@ -299,19 +299,19 @@ export function getThemeString(color, additionalVariables = []) {
...additionalVariables,
].filter(Boolean);
- if (!variables.length) return "";
+ if (!variables.length) return '';
return (
- `:root {\n` + variables.map((line) => ` ` + line + ";\n").join("") + `}`
+ `:root {\n` + variables.map((line) => ` ` + line + ';\n').join('') + `}`
);
}
-export function getAlbumStylesheet(album, { to }) {
+export function getAlbumStylesheet(album, {to}) {
return [
album.wallpaperArtistContribs.length &&
fixWS`
body::before {
background-image: url("${to(
- "media.albumWallpaper",
+ 'media.albumWallpaper',
album.directory,
album.wallpaperFileExtension
)}");
@@ -326,31 +326,31 @@ export function getAlbumStylesheet(album, { to }) {
`,
]
.filter(Boolean)
- .join("\n");
+ .join('\n');
}
// Divided track lists
export function generateTrackListDividedByGroups(
tracks,
- { getTrackItem, language, wikiData }
+ {getTrackItem, language, wikiData}
) {
- const { divideTrackListsByGroups: groups } = wikiData.wikiInfo;
+ const {divideTrackListsByGroups: groups} = wikiData.wikiInfo;
if (!groups?.length) {
return html.tag(
- "ul",
+ 'ul',
tracks.map((t) => getTrackItem(t))
);
}
const lists = Object.fromEntries(
- groups.map((group) => [group.directory, { group, tracks: [] }])
+ groups.map((group) => [group.directory, {group, tracks: []}])
);
const other = [];
for (const track of tracks) {
- const { album } = track;
+ const {album} = track;
const group = groups.find((g) => g.albums.includes(album));
if (group) {
lists[group.directory].tracks.push(track);
@@ -361,26 +361,26 @@ export function generateTrackListDividedByGroups(
const ddul = (tracks) => fixWS`
- ${tracks.map((t) => getTrackItem(t)).join("\n")}
+ ${tracks.map((t) => getTrackItem(t)).join('\n')}
${language.$("albumCommentaryPage.title", {
+
${language.$('albumCommentaryPage.title', {
album: link.album(album),
})}
- ${language.$(
- "albumCommentaryPage.entry.title.albumCommentary"
+ 'albumCommentaryPage.entry.title.albumCommentary'
)}
${transformMultiline(album.commentary)}
@@ -73,7 +73,7 @@ export function write(album, { wikiData }) {
.map(
(track) => fixWS`
`
)
- .join("\n")}
+ .join('\n')}
${language.$(
- "albumCommentaryPage.entry.title.trackCommentary",
+ 'albumCommentaryPage.entry.title.trackCommentary',
{
track: link.track(track),
}
@@ -85,22 +85,22 @@ export function write(album, { wikiData }) {
${language.$("commentaryIndex.title")}
- ${language.$('commentaryIndex.title')}
+
${data
.map(
- ({ album, entries, words }) => fixWS`
+ ({album, entries, words}) => fixWS`
${language.$("albumPage.title", {
+
${language.$('albumPage.title', {
album: album.name,
})}
\n")}
+ .join('
\n')}
\n")}
${language.$("releaseInfo.listenOn", { + `
${language.$('releaseInfo.listenOn', { links: language.formatDisjunctionList( album.urls.map((url) => - fancifyURL(url, { album: true }) + fancifyURL(url, {album: true}) ) ), })}
` @@ -263,32 +263,32 @@ export function write(album, { wikiData }) { tracks, }) => fixWS`
${[
- language.$("releaseInfo.addedToWiki", {
+ language.$('releaseInfo.addedToWiki', {
date: language.formatDate(
album.dateAddedToWiki
),
}),
]
.filter(Boolean)
- .join("
\n")}
+ .join('
\n')}
${language.$("releaseInfo.artistCommentary")}
+${language.$('releaseInfo.artistCommentary')}
${transformMultiline(album.commentary)}@@ -348,16 +348,16 @@ export function write(album, { wikiData }) { }), nav: { - linkContainerClasses: ["nav-links-hierarchy"], + linkContainerClasses: ['nav-links-hierarchy'], links: [ - { toHome: true }, + {toHome: true}, { - html: language.$("albumPage.nav.album", { - album: link.album(album, { class: "current" }), + html: language.$('albumPage.nav.album', { + album: link.album(album, {class: 'current'}), }), }, ], - bottomRowContent: generateAlbumNavLinks(album, null, { language }), + bottomRowContent: generateAlbumNavLinks(album, null, {language}), content: generateAlbumChronologyLinks(album, null, { generateChronologyLinks, }), @@ -380,14 +380,7 @@ export function write(album, { wikiData }) { export function generateAlbumSidebar( album, currentTrack, - { - fancifyURL, - getLinkThemeString, - link, - language, - transformMultiline, - wikiData, - } + {fancifyURL, getLinkThemeString, link, language, transformMultiline, wikiData} ) { const listTag = getAlbumListTag(album); @@ -400,41 +393,41 @@ export function generateAlbumSidebar( }]; */ - const { trackGroups } = album; + const {trackGroups} = album; const trackToListItem = (track) => html.tag( - "li", - { class: track === currentTrack && "current" }, - language.$("albumSidebar.trackList.item", { + 'li', + {class: track === currentTrack && 'current'}, + language.$('albumSidebar.trackList.item', { track: link.track(track), }) ); const nameOrDefault = (isDefaultTrackGroup, name) => isDefaultTrackGroup - ? language.$("albumSidebar.trackList.fallbackGroupName") + ? language.$('albumSidebar.trackList.fallbackGroupName') : name; const trackListPart = fixWS`
${language.$("releaseInfo.visitOn", { + `
${language.$('releaseInfo.visitOn', { links: language.formatDisjunctionList( group.urls.map((url) => fancifyURL(url)) ), @@ -495,7 +488,7 @@ export function generateAlbumSidebar( ${ next && `
${language.$( - "albumSidebar.groupBox.next", + 'albumSidebar.groupBox.next', { album: link.album(next), } @@ -504,7 +497,7 @@ export function generateAlbumSidebar( ${ previous && `
${language.$( - "albumSidebar.groupBox.previous", + 'albumSidebar.groupBox.previous', { album: link.album(previous), } @@ -517,7 +510,7 @@ export function generateAlbumSidebar( if (groupParts.length) { if (currentTrack) { - const combinedGroupPart = groupParts.join("\n
${language.$("releaseInfo.note")}
+${language.$('releaseInfo.note')}
${transformMultiline(contextNotes)}@@ -393,41 +393,41 @@ export function write(artist, { wikiData }) { } ${ urls?.length && - `
${language.$("releaseInfo.visitOn", { + `
${language.$('releaseInfo.visitOn', { links: language.formatDisjunctionList( - urls.map((url) => fancifyURL(url, { language })) + urls.map((url) => fancifyURL(url, {language})) ), })}
` } ${ hasGallery && - `${language.$("artistPage.viewArtGallery", { + `
${language.$('artistPage.viewArtGallery', { link: link.artistGallery(artist, { text: language.$( - "artistPage.viewArtGallery.link" + 'artistPage.viewArtGallery.link' ), }), })}
` } -${language.$("misc.jumpTo.withLinks", { +
${language.$('misc.jumpTo.withLinks', { links: language.formatUnitList( [ allTracks.length && `${language.$( - "artistPage.trackList.title" + 'artistPage.trackList.title' )}`, artThingsAll.length && `${language.$( - "artistPage.artList.title" + 'artistPage.artList.title' )}`, wikiInfo.enableFlashesAndGames && flashes.length && `${language.$( - "artistPage.flashList.title" + 'artistPage.flashList.title' )}`, commentaryThings.length && `${language.$( - "artistPage.commentaryList.title" + 'artistPage.commentaryList.title' )}`, ].filter(Boolean) ), @@ -436,22 +436,22 @@ export function write(artist, { wikiData }) { allTracks.length && fixWS`
${language.$( - "artistPage.contributedDurationLine", + 'artistPage.contributedDurationLine', { artist: artist.name, duration: language.formatDuration( totalDuration, - { approximate: true, unit: true } + {approximate: true, unit: true} ), } )}
-${language.$("artistPage.musicGroupsLine", { +
${language.$('artistPage.musicGroupsLine', { groups: language.formatUnitList( - musicGroups.map(({ group, contributions }) => - language.$("artistPage.groupsLine.item", { + musicGroups.map(({group, contributions}) => + language.$('artistPage.groupsLine.item', { group: link.groupInfo(group), contributions: language.countContributions( @@ -468,25 +468,25 @@ export function write(artist, { wikiData }) { artThingsAll.length && fixWS`
${language.$( - "artistPage.viewArtGallery.orBrowseList", + 'artistPage.viewArtGallery.orBrowseList', { link: link.artistGallery(artist, { text: language.$( - "artistPage.viewArtGallery.link" + 'artistPage.viewArtGallery.link' ), }), } )}
` } -${language.$("artistPage.artGroupsLine", { +
${language.$('artistPage.artGroupsLine', { groups: language.formatUnitList( - artGroups.map(({ group, contributions }) => - language.$("artistPage.groupsLine.item", { + artGroups.map(({group, contributions}) => + language.$('artistPage.groupsLine.item', { group: link.groupInfo(group), contributions: language.countContributions( @@ -499,9 +499,9 @@ export function write(artist, { wikiData }) {
${language.$( - "artistGalleryPage.infoLine", + 'artistGalleryPage.infoLine', { coverArts: language.countCoverArts( artThingsGallery.length, - { unit: true } + {unit: true} ), } )}
${language.$("releaseInfo.released", { +
${language.$('releaseInfo.released', { date: language.formatDate(flash.date), })}
${ (flash.page || flash.urls?.length) && - `${language.$("releaseInfo.playOn", { + `
${language.$('releaseInfo.playOn', { links: language.formatDisjunctionList( [ flash.page && getFlashLink(flash), @@ -69,15 +69,15 @@ export function write(flash, { wikiData }) { fixWS`
Tracks featured in ${flash.name.replace( /\.$/, - "" + '' )}:
${language.$("releaseInfo.contributors")}
+${language.$('releaseInfo.contributors')}
${language.$("misc.jumpTo")}
+${language.$('misc.jumpTo')}
${language.$("releaseInfo.visitOn", { + `
${language.$('releaseInfo.visitOn', { links: language.formatDisjunctionList( - group.urls.map((url) => fancifyURL(url, { language })) + group.urls.map((url) => fancifyURL(url, {language})) ), })}
` }${transformMultiline(group.description)}-
${language.$("groupInfoPage.viewAlbumGallery", { +
${language.$('groupInfoPage.viewAlbumGallery', { link: link.groupGallery(group, { - text: language.$("groupInfoPage.viewAlbumGallery.link"), + text: language.$('groupInfoPage.viewAlbumGallery.link'), }), })}
${language.$(
- "groupGalleryPage.infoLine",
+ 'groupGalleryPage.infoLine',
{
tracks: `${language.countTracks(tracks.length, {
unit: true,
@@ -165,16 +165,16 @@ export function write(group, { wikiData }) {
wikiInfo.enableGroupUI &&
wikiInfo.enableListings &&
html.tag(
- "p",
- { class: "quick-info" },
- language.$("groupGalleryPage.anotherGroupLine", {
+ 'p',
+ {class: 'quick-info'},
+ language.$('groupGalleryPage.anotherGroupLine', {
link: link.listing(
listingSpec.find(
- (l) => l.directory === "groups/by-category"
+ (l) => l.directory === 'groups/by-category'
),
{
text: language.$(
- "groupGalleryPage.anotherGroupLine.link"
+ 'groupGalleryPage.anotherGroupLine.link'
),
}
),
@@ -222,45 +222,45 @@ export function write(group, { wikiData }) {
function generateGroupSidebar(
currentGroup,
isGallery,
- { getLinkThemeString, link, language, wikiData }
+ {getLinkThemeString, link, language, wikiData}
) {
- const { groupCategoryData, wikiInfo } = wikiData;
+ const {groupCategoryData, wikiInfo} = wikiData;
if (!wikiInfo.enableGroupUI) {
return null;
}
- const linkKey = isGallery ? "groupGallery" : "groupInfo";
+ const linkKey = isGallery ? 'groupGallery' : 'groupInfo';
return {
content: fixWS`
- __GENERATE_NEWS__ __GENERATE_NEWS__ News requested in content description but this feature isn't enabled ${language.$("listingIndex.infoLine", {
+ ${language.$('listingIndex.infoLine', {
wiki: wikiInfo.name,
tracks: `${language.countTracks(trackData.length, {
unit: true,
@@ -125,7 +125,7 @@ export function writeTargetless({ wikiData }) {
})}`,
})} ${language.$("listingIndex.exploreList")} ${language.$('listingIndex.exploreList')} ${language.$("newsEntryPage.published", {
+ ${language.$('newsEntryPage.published', {
date: language.formatDate(entry.date),
})} ${link.newsEntry(entry, {
text: language.$(
- "newsIndex.entry.viewRest"
+ 'newsIndex.entry.viewRest'
),
})} ${language.$("tagPage.infoLine", {
+ ${language.$('tagPage.infoLine', {
coverArts: language.countCoverArts(things.length, {
unit: true,
}),
@@ -83,24 +83,24 @@ export function write(tag, { wikiData }) {
function generateTagNav(
tag,
- { generatePreviousNextLinks, link, language, wikiData }
+ {generatePreviousNextLinks, link, language, wikiData}
) {
const previousNextLinks = generatePreviousNextLinks(tag, {
data: wikiData.artTagData.filter((tag) => !tag.isContentWarning),
- linkKey: "tag",
+ linkKey: 'tag',
});
return {
- linkContainerClasses: ["nav-links-hierarchy"],
+ linkContainerClasses: ['nav-links-hierarchy'],
links: [
- { toHome: true },
+ {toHome: true},
wikiData.wikiInfo.enableListings && {
- path: ["localized.listingIndex"],
- title: language.$("listingIndex.title"),
+ path: ['localized.listingIndex'],
+ title: language.$('listingIndex.title'),
},
{
- html: language.$("tagPage.nav.tag", {
- tag: link.tag(tag, { class: "current" }),
+ html: language.$('tagPage.nav.tag', {
+ tag: link.tag(tag, {class: 'current'}),
}),
},
/*
diff --git a/src/page/track.js b/src/page/track.js
index 5827197d..a9758ec2 100644
--- a/src/page/track.js
+++ b/src/page/track.js
@@ -1,37 +1,37 @@
-// @format
-//
+/** @format */
+
// Track page specification.
// Imports
-import fixWS from "fix-whitespace";
+import fixWS from 'fix-whitespace';
import {
generateAlbumChronologyLinks,
generateAlbumNavLinks,
generateAlbumSecondaryNav,
generateAlbumSidebar,
-} from "./album.js";
+} from './album.js';
-import * as html from "../util/html.js";
+import * as html from '../util/html.js';
-import { bindOpts } from "../util/sugar.js";
+import {bindOpts} from '../util/sugar.js';
import {
getTrackCover,
getAlbumListTag,
sortChronologically,
-} from "../util/wiki-data.js";
+} from '../util/wiki-data.js';
// Page exports
-export function targets({ wikiData }) {
+export function targets({wikiData}) {
return wikiData.trackData;
}
-export function write(track, { wikiData }) {
- const { groupData, wikiInfo } = wikiData;
- const { album, referencedByTracks, referencedTracks, otherReleases } = track;
+export function write(track, {wikiData}) {
+ const {groupData, wikiInfo} = wikiData;
+ const {album, referencedByTracks, referencedTracks, otherReleases} = track;
const listTag = getAlbumListTag(album);
@@ -50,12 +50,12 @@ export function write(track, { wikiData }) {
);
}
- const unbound_getTrackItem = (track, { getArtistString, link, language }) =>
+ const unbound_getTrackItem = (track, {getArtistString, link, language}) =>
html.tag(
- "li",
- language.$("trackList.item.withArtists", {
+ 'li',
+ language.$('trackList.item.withArtists', {
track: link.track(track),
- by: `${language.$("trackList.item.withArtists.by", {
+ by: `${language.$('trackList.item.withArtists.by', {
artists: getArtistString(track.artistContribs),
})}`,
})
@@ -63,46 +63,46 @@ export function write(track, { wikiData }) {
const unbound_generateTrackList = (
tracks,
- { getArtistString, link, language }
+ {getArtistString, link, language}
) =>
html.tag(
- "ul",
+ 'ul',
tracks.map((track) =>
- unbound_getTrackItem(track, { getArtistString, link, language })
+ unbound_getTrackItem(track, {getArtistString, link, language})
)
);
const hasCommentary =
track.commentary || otherReleases.some((t) => t.commentary);
- const generateCommentary = ({ link, language, transformMultiline }) =>
+ const generateCommentary = ({link, language, transformMultiline}) =>
transformMultiline(
[
track.commentary,
...otherReleases.map((track) =>
track.commentary
- ?.split("\n")
- .filter((line) => line.replace(/<\/b>/g, "").includes(":"))
+ ?.split('\n')
+ .filter((line) => line.replace(/<\/b>/g, '').includes(':'))
.map(
(line) => fixWS`
${line}
${language.$(
- "releaseInfo.artistCommentary.seeOriginalRelease",
+ 'releaseInfo.artistCommentary.seeOriginalRelease',
{
original: link.track(track),
}
)}
`
)
- .join("\n")
+ .join('\n')
),
]
.filter(Boolean)
- .join("\n")
+ .join('\n')
);
const data = {
- type: "data",
- path: ["track", track.directory],
+ type: 'data',
+ path: ['track', track.directory],
data: ({
serializeContribs,
serializeCover,
@@ -145,19 +145,19 @@ export function write(track, { wikiData }) {
// they don't get parsed and displayed, generally speaking), so
// override the link argument so that artist "links" just show
// their names.
- link: { artist: (artist) => artist.name },
+ link: {artist: (artist) => artist.name},
});
- if (!hasArtists && !hasCoverArtists) return "";
+ if (!hasArtists && !hasCoverArtists) return '';
return language.formatString(
- "trackPage.socialEmbed.body" +
- [hasArtists && ".withArtists", hasCoverArtists && ".withCoverArtists"]
+ 'trackPage.socialEmbed.body' +
+ [hasArtists && '.withArtists', hasCoverArtists && '.withCoverArtists']
.filter(Boolean)
- .join(""),
+ .join(''),
Object.fromEntries(
[
- hasArtists && ["artists", getArtistString(track.artistContribs)],
+ hasArtists && ['artists', getArtistString(track.artistContribs)],
hasCoverArtists && [
- "coverArtists",
+ 'coverArtists',
getArtistString(track.coverArtistContribs),
],
].filter(Boolean)
@@ -166,8 +166,8 @@ export function write(track, { wikiData }) {
};
const page = {
- type: "page",
- path: ["track", track.directory],
+ type: 'page',
+ path: ['track', track.directory],
page: ({
absoluteTo,
fancifyURL,
@@ -196,24 +196,23 @@ export function write(track, { wikiData }) {
const cover = getTrackCover(track);
return {
- title: language.$("trackPage.title", { track: track.name }),
- stylesheet: getAlbumStylesheet(album, { to }),
+ title: language.$('trackPage.title', {track: track.name}),
+ stylesheet: getAlbumStylesheet(album, {to}),
theme: getThemeString(track.color, [
`--album-directory: ${album.directory}`,
`--track-directory: ${track.directory}`,
]),
socialEmbed: {
- heading: language.$("trackPage.socialEmbed.heading", {
+ heading: language.$('trackPage.socialEmbed.heading', {
album: track.album.name,
}),
- headingLink: absoluteTo("localized.album", album.directory),
- title: language.$("trackPage.socialEmbed.title", {
+ headingLink: absoluteTo('localized.album', album.directory),
+ title: language.$('trackPage.socialEmbed.title', {
track: track.name,
}),
- description: getSocialEmbedDescription({ getArtistString, language }),
- image:
- "/" + getTrackCover(track, { to: urls.from("shared.root").to }),
+ description: getSocialEmbedDescription({getArtistString, language}),
+ image: '/' + getTrackCover(track, {to: urls.from('shared.root').to}),
color: track.color,
},
@@ -234,23 +233,23 @@ export function write(track, { wikiData }) {
cover &&
generateCoverLink({
src: cover,
- alt: language.$("misc.alt.trackCover"),
+ alt: language.$('misc.alt.trackCover'),
tags: track.artTags,
})
}
-
${[
- language.$("releaseInfo.by", {
+ language.$('releaseInfo.by', {
artists: getArtistString(track.artistContribs, {
showContrib: true,
showIcons: true,
}),
}),
track.coverArtistContribs.length &&
- language.$("releaseInfo.coverArtBy", {
+ language.$('releaseInfo.coverArtBy', {
artists: getArtistString(
track.coverArtistContribs,
{
@@ -260,45 +259,45 @@ export function write(track, { wikiData }) {
),
}),
track.date &&
- language.$("releaseInfo.released", {
+ language.$('releaseInfo.released', {
date: language.formatDate(track.date),
}),
track.coverArtDate &&
+track.coverArtDate !== +track.date &&
- language.$("releaseInfo.artReleased", {
+ language.$('releaseInfo.artReleased', {
date: language.formatDate(track.coverArtDate),
}),
track.duration &&
- language.$("releaseInfo.duration", {
+ language.$('releaseInfo.duration', {
duration: language.formatDuration(
track.duration
),
}),
]
.filter(Boolean)
- .join(" ${
track.urls?.length
- ? language.$("releaseInfo.listenOn", {
+ ? language.$('releaseInfo.listenOn', {
links: language.formatDisjunctionList(
track.urls.map((url) =>
- fancifyURL(url, { language })
+ fancifyURL(url, {language})
)
),
})
- : language.$("releaseInfo.listenOn.noLinks")
+ : language.$('releaseInfo.listenOn.noLinks')
} ${language.$("releaseInfo.alsoReleasedAs")} ${language.$('releaseInfo.alsoReleasedAs')} ${language.$("releaseInfo.contributors")} ${language.$('releaseInfo.contributors')} ${language.$("releaseInfo.tracksReferenced", {
+ ${language.$('releaseInfo.tracksReferenced', {
track: `${track.name}`,
})} ${language.$("releaseInfo.tracksThatReference", {
+ ${language.$('releaseInfo.tracksThatReference', {
track: `${track.name}`,
})} ${language.$("releaseInfo.flashesThatFeature", {
+ ${language.$('releaseInfo.flashesThatFeature', {
track: `${track.name}`,
})} ${language.$("releaseInfo.lyrics")} ${language.$('releaseInfo.lyrics')} ${language.$("releaseInfo.artistCommentary")} ${language.$('releaseInfo.artistCommentary')} ${buildLine} ${language.$(
- "releaseInfo.from",
- { album: "" }
+ 'releaseInfo.from',
+ {album: ''}
)} ${language.$(
- "releaseInfo.by",
- { artists: "" }
+ 'releaseInfo.by',
+ {artists: ''}
)} ${language.$(
- "releaseInfo.coverArtBy",
- { artists: "" }
+ 'releaseInfo.coverArtBy',
+ {artists: ''}
)} ${language.$("redirectPage.infoLine", {
+ ${language.$('redirectPage.infoLine', {
target: `${target}`,
})}${language.$("groupSidebar.title")}
+ ${language.$('groupSidebar.title')}
${groupCategoryData
.map((category) =>
html.tag(
- "details",
+ 'details',
{
open: category === currentGroup.category,
- class: category === currentGroup.category && "current",
+ class: category === currentGroup.category && 'current',
},
[
html.tag(
- "summary",
- { style: getLinkThemeString(category.color) },
- language.$("groupSidebar.groupList.category", {
+ 'summary',
+ {style: getLinkThemeString(category.color)},
+ language.$('groupSidebar.groupList.category', {
category: `${category.name}`,
})
),
html.tag(
- "ul",
+ 'ul',
category.groups.map((group) =>
html.tag(
- "li",
+ 'li',
{
- class: group === currentGroup && "current",
+ class: group === currentGroup && 'current',
style: getLinkThemeString(group.color),
},
- language.$("groupSidebar.groupList.item", {
+ language.$('groupSidebar.groupList.item', {
group: link[linkKey](group),
})
)
@@ -269,7 +269,7 @@ function generateGroupSidebar(
]
)
)
- .join("\n")}
+ .join('\n')}
`,
};
@@ -286,18 +286,18 @@ function generateGroupNav(
wikiData,
}
) {
- const { groupData, wikiInfo } = wikiData;
+ const {groupData, wikiInfo} = wikiData;
if (!wikiInfo.enableGroupUI) {
- return { simple: true };
+ return {simple: true};
}
- const urlKey = isGallery ? "localized.groupGallery" : "localized.groupInfo";
- const linkKey = isGallery ? "groupGallery" : "groupInfo";
+ const urlKey = isGallery ? 'localized.groupGallery' : 'localized.groupInfo';
+ const linkKey = isGallery ? 'groupGallery' : 'groupInfo';
const infoGalleryLinks = generateInfoGalleryLinks(currentGroup, isGallery, {
- linkKeyGallery: "groupGallery",
- linkKeyInfo: "groupInfo",
+ linkKeyGallery: 'groupGallery',
+ linkKeyInfo: 'groupInfo',
});
const previousNextLinks = generatePreviousNextLinks(currentGroup, {
@@ -306,16 +306,16 @@ function generateGroupNav(
});
return {
- linkContainerClasses: ["nav-links-hierarchy"],
+ linkContainerClasses: ['nav-links-hierarchy'],
links: [
- { toHome: true },
+ {toHome: true},
wikiInfo.enableListings && {
- path: ["localized.listingIndex"],
- title: language.$("listingIndex.title"),
+ path: ['localized.listingIndex'],
+ title: language.$('listingIndex.title'),
},
{
- html: language.$("groupPage.nav.group", {
- group: link[linkKey](currentGroup, { class: "current" }),
+ html: language.$('groupPage.nav.group', {
+ group: link[linkKey](currentGroup, {class: 'current'}),
}),
},
{
diff --git a/src/page/homepage.js b/src/page/homepage.js
index 8d20accf..7701a73c 100644
--- a/src/page/homepage.js
+++ b/src/page/homepage.js
@@ -1,23 +1,23 @@
-// @format
-//
+/** @format */
+
// Homepage specification.
// Imports
-import fixWS from "fix-whitespace";
+import fixWS from 'fix-whitespace';
-import * as html from "../util/html.js";
+import * as html from '../util/html.js';
-import { getNewAdditions, getNewReleases } from "../util/wiki-data.js";
+import {getNewAdditions, getNewReleases} from '../util/wiki-data.js';
// Page exports
-export function writeTargetless({ wikiData }) {
- const { newsData, staticPageData, homepageLayout, wikiInfo } = wikiData;
+export function writeTargetless({wikiData}) {
+ const {newsData, staticPageData, homepageLayout, wikiInfo} = wikiData;
const page = {
- type: "page",
- path: ["home"],
+ type: 'page',
+ path: ['home'],
page: ({
getAlbumGridHTML,
getLinkThemeString,
@@ -35,7 +35,7 @@ export function writeTargetless({ wikiData }) {
},
main: {
- classes: ["top-index"],
+ classes: ['top-index'],
content: fixWS`
${wikiInfo.name}
${homepageLayout.rows
@@ -46,21 +46,21 @@ export function writeTargetless({ wikiData }) {
)}">
${row.name}
${
- row.type === "albums" &&
+ row.type === 'albums' &&
fixWS`
${language.$("homepage.news.title")}
+ ${language.$('homepage.news.title')}
${newsData
.slice(0, 3)
.map((entry, i) =>
html.tag(
- "article",
+ 'article',
{
class: [
- "news-entry",
- i === 0 && "first-news-entry",
+ 'news-entry',
+ i === 0 && 'first-news-entry',
],
},
fixWS`
@@ -143,42 +143,42 @@ export function writeTargetless({ wikiData }) {
entry.contentShort !== entry.content &&
link.newsEntry(entry, {
text: language.$(
- "homepage.news.entry.viewRest"
+ 'homepage.news.entry.viewRest'
),
})
}
`
)
)
- .join("\n")}
+ .join('\n')}
`
: `${language.$("listingIndex.title")}
- ${language.$('listingIndex.title')}
+
- ${link.listingIndex("", {
- text: language.$("listingIndex.title"),
+
${link.listingIndex('', {
+ text: language.$('listingIndex.title'),
})}
${generateLinkIndexForListings(currentListing, true, {
getLinkThemeString,
@@ -172,24 +172,24 @@ function generateSidebarForListings(
function generateLinkIndexForListings(
currentListing,
forSidebar,
- { getLinkThemeString, link, language, wikiData }
+ {getLinkThemeString, link, language, wikiData}
) {
- const { listingTargetSpec, wikiInfo } = wikiData;
+ const {listingTargetSpec, wikiInfo} = wikiData;
const filteredByCondition = listingTargetSpec
- .map(({ listings, ...rest }) => ({
+ .map(({listings, ...rest}) => ({
...rest,
- listings: listings.filter(({ condition: c }) => !c || c({ wikiData })),
+ listings: listings.filter(({condition: c}) => !c || c({wikiData})),
}))
- .filter(({ listings }) => listings.length > 0);
+ .filter(({listings}) => listings.length > 0);
const genUL = (listings) =>
html.tag(
- "ul",
+ 'ul',
listings.map((listing) =>
html.tag(
- "li",
- { class: [listing === currentListing && "current"] },
+ 'li',
+ {class: [listing === currentListing && 'current']},
link.listing(listing, {
text: language.$(`listingPage.${listing.stringsKey}.title.short`),
})
@@ -199,30 +199,30 @@ function generateLinkIndexForListings(
if (forSidebar) {
return filteredByCondition
- .map(({ title, listings }) =>
+ .map(({title, listings}) =>
html.tag(
- "details",
+ 'details',
{
open: !forSidebar || listings.includes(currentListing),
- class: listings.includes(currentListing) && "current",
+ class: listings.includes(currentListing) && 'current',
},
[
html.tag(
- "summary",
- { style: getLinkThemeString(wikiInfo.color) },
- html.tag("span", { class: "group-name" }, title({ language }))
+ 'summary',
+ {style: getLinkThemeString(wikiInfo.color)},
+ html.tag('span', {class: 'group-name'}, title({language}))
),
genUL(listings),
]
)
)
- .join("\n");
+ .join('\n');
} else {
return html.tag(
- "dl",
- filteredByCondition.flatMap(({ title, listings }) => [
- html.tag("dt", title({ language })),
- html.tag("dd", genUL(listings)),
+ 'dl',
+ filteredByCondition.flatMap(({title, listings}) => [
+ html.tag('dt', title({language})),
+ html.tag('dd', genUL(listings)),
])
);
}
diff --git a/src/page/news.js b/src/page/news.js
index b988e348..bf581e43 100644
--- a/src/page/news.js
+++ b/src/page/news.js
@@ -1,40 +1,40 @@
-// @format
-//
+/** @format */
+
// News entry & index page specifications.
// Imports
-import fixWS from "fix-whitespace";
+import fixWS from 'fix-whitespace';
// Page exports
-export function condition({ wikiData }) {
+export function condition({wikiData}) {
return wikiData.wikiInfo.enableNews;
}
-export function targets({ wikiData }) {
+export function targets({wikiData}) {
return wikiData.newsData;
}
-export function write(entry, { wikiData }) {
+export function write(entry, {wikiData}) {
const page = {
- type: "page",
- path: ["newsEntry", entry.directory],
+ type: 'page',
+ path: ['newsEntry', entry.directory],
page: ({
generatePreviousNextLinks,
link,
language,
transformMultiline,
}) => ({
- title: language.$("newsEntryPage.title", { entry: entry.name }),
+ title: language.$('newsEntryPage.title', {entry: entry.name}),
main: {
content: fixWS`
${language.$("newsEntryPage.title", {
+
${language.$('newsEntryPage.title', {
entry: entry.name,
})}
- ${language.$("newsIndex.title")}
+ ${language.$('newsIndex.title')}
${newsData
.map(
(entry) => fixWS`
@@ -79,19 +79,19 @@ export function writeTargetless({ wikiData }) {
entry.contentShort !== entry.content &&
`${language.$("tagPage.title", { tag: tag.name })}
- ${language.$('tagPage.title', {tag: tag.name})}
+ ${language.$("trackPage.title", {
+
${language.$('trackPage.title', {
track: track.name,
})}
\n")}
+ .join('
\n')}
${otherReleases
.map(
(track) => fixWS`
`
}
${
track.contributorContribs.length &&
fixWS`
-
${track.contributorContribs
.map(
@@ -323,18 +322,18 @@ export function write(track, { wikiData }) {
showIcons: true,
})}`
)
- .join("\n")}
+ .join('\n')}
`
}
${
referencedTracks.length &&
fixWS`
-
${flashesThatFeature
- .map(({ flash, as }) =>
+ .map(({flash, as}) =>
html.tag(
- "li",
- { class: as !== track && "rerelease" },
+ 'li',
+ {class: as !== track && 'rerelease'},
as === track
? language.$(
- "releaseInfo.flashesThatFeature.item",
+ 'releaseInfo.flashesThatFeature.item',
{
flash: link.flash(flash),
}
)
: language.$(
- "releaseInfo.flashesThatFeature.item.asDifferentRelease",
+ 'releaseInfo.flashesThatFeature.item.asDifferentRelease',
{
flash: link.flash(flash),
track: link.track(as),
@@ -383,14 +382,14 @@ export function write(track, { wikiData }) {
)
)
)
- .join("\n")}
+ .join('\n')}
`
}
${
track.lyrics &&
fixWS`
-
${transformLyrics(track.lyrics)}
@@ -399,7 +398,7 @@ export function write(track, { wikiData }) {
${
hasCommentary &&
fixWS`
-
${generateCommentary({
link,
@@ -422,23 +421,23 @@ export function write(track, { wikiData }) {
}),
nav: {
- linkContainerClasses: ["nav-links-hierarchy"],
+ linkContainerClasses: ['nav-links-hierarchy'],
links: [
- { toHome: true },
+ {toHome: true},
{
- path: ["localized.album", album.directory],
+ path: ['localized.album', album.directory],
title: album.name,
},
- listTag === "ol"
+ listTag === 'ol'
? {
- html: language.$("trackPage.nav.track.withNumber", {
+ html: language.$('trackPage.nav.track.withNumber', {
number: album.tracks.indexOf(track) + 1,
- track: link.track(track, { class: "current", to }),
+ track: link.track(track, {class: 'current', to}),
}),
}
: {
- html: language.$("trackPage.nav.track", {
- track: link.track(track, { class: "current", to }),
+ html: language.$('trackPage.nav.track', {
+ track: link.track(track, {class: 'current', to}),
}),
},
].filter(Boolean),
diff --git a/src/repl.js b/src/repl.js
index 5826d230..5a6334a1 100644
--- a/src/repl.js
+++ b/src/repl.js
@@ -1,53 +1,53 @@
-// @format
+/** @format */
-import * as os from "os";
-import * as path from "path";
-import * as repl from "repl";
-import { fileURLToPath } from "url";
-import { promisify } from "util";
+import * as os from 'os';
+import * as path from 'path';
+import * as repl from 'repl';
+import {fileURLToPath} from 'url';
+import {promisify} from 'util';
-import { quickLoadAllFromYAML } from "./data/yaml.js";
-import { logError, parseOptions } from "./util/cli.js";
-import { showAggregate } from "./util/sugar.js";
+import {quickLoadAllFromYAML} from './data/yaml.js';
+import {logError, parseOptions} from './util/cli.js';
+import {showAggregate} from './util/sugar.js';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
async function main() {
const miscOptions = await parseOptions(process.argv.slice(2), {
- "data-path": {
- type: "value",
+ 'data-path': {
+ type: 'value',
},
- "show-traces": {
- type: "flag",
+ 'show-traces': {
+ type: 'flag',
},
- "no-history": {
- type: "flag",
+ 'no-history': {
+ type: 'flag',
},
});
- const dataPath = miscOptions["data-path"] || process.env.HSMUSIC_DATA;
- const showAggregateTraces = miscOptions["show-traces"] ?? false;
- const disableHistory = miscOptions["no-history"] ?? false;
+ const dataPath = miscOptions['data-path'] || process.env.HSMUSIC_DATA;
+ const showAggregateTraces = miscOptions['show-traces'] ?? false;
+ const disableHistory = miscOptions['no-history'] ?? false;
if (!dataPath) {
logError`Expected --data-path option or HSMUSIC_DATA to be set`;
return;
}
- console.log("HSMusic data REPL");
+ console.log('HSMusic data REPL');
const wikiData = await quickLoadAllFromYAML(dataPath);
const replServer = repl.start();
- Object.assign(replServer.context, wikiData, { wikiData, WD: wikiData });
+ Object.assign(replServer.context, wikiData, {wikiData, WD: wikiData});
if (disableHistory) {
console.log(`\rInput history disabled (--no-history provided)`);
replServer.displayPrompt(true);
} else {
- const historyFile = path.join(os.homedir(), ".hsmusic_repl_history");
+ const historyFile = path.join(os.homedir(), '.hsmusic_repl_history');
replServer.setupHistory(historyFile, (err) => {
if (err) {
console.error(
diff --git a/src/static/client.js b/src/static/client.js
index d68358ba..8342eb15 100644
--- a/src/static/client.js
+++ b/src/static/client.js
@@ -1,5 +1,5 @@
-// @format
-//
+/** @format */
+
// This is the JS file that gets loaded on the client! It's only really used for
// the random track feature right now - the idea is we only use it for stuff
// that cannot 8e done at static-site compile time, 8y its fundamentally
@@ -7,9 +7,9 @@
//
// Upd8: As of 04/02/2021, it's now used for info cards too! Nice.
-import { getColors } from "../util/colors.js";
+import {getColors} from '../util/colors.js';
-import { getArtistNumContributions } from "../util/wiki-data.js";
+import {getArtistNumContributions} from '../util/wiki-data.js';
let albumData, artistData, flashData;
let officialAlbumData, fandomAlbumData, artistNames;
@@ -18,25 +18,25 @@ let ready = false;
// Localiz8tion nonsense ----------------------------------
-const language = document.documentElement.getAttribute("lang");
+const language = document.documentElement.getAttribute('lang');
let list;
-if (typeof Intl === "object" && typeof Intl.ListFormat === "function") {
+if (typeof Intl === 'object' && typeof Intl.ListFormat === 'function') {
const getFormat = (type) => {
- const formatter = new Intl.ListFormat(language, { type });
+ const formatter = new Intl.ListFormat(language, {type});
return formatter.format.bind(formatter);
};
list = {
- conjunction: getFormat("conjunction"),
- disjunction: getFormat("disjunction"),
- unit: getFormat("unit"),
+ conjunction: getFormat('conjunction'),
+ disjunction: getFormat('disjunction'),
+ unit: getFormat('unit'),
};
} else {
// Not a gr8 mock we've got going here, 8ut it's *mostly* language-free.
// We use the same mock for every list 'cuz we don't have any of the
// necessary CLDR info to appropri8tely distinguish 8etween them.
- const arbitraryMock = (array) => array.join(", ");
+ const arbitraryMock = (array) => array.join(', ');
list = {
conjunction: arbitraryMock,
@@ -47,8 +47,8 @@ if (typeof Intl === "object" && typeof Intl.ListFormat === "function") {
// Miscellaneous helpers ----------------------------------
-function rebase(href, rebaseKey = "rebaseLocalized") {
- const relative = (document.documentElement.dataset[rebaseKey] || ".") + "/";
+function rebase(href, rebaseKey = 'rebaseLocalized') {
+ const relative = (document.documentElement.dataset[rebaseKey] || '.') + '/';
if (relative) {
return relative + href;
} else {
@@ -65,16 +65,16 @@ function cssProp(el, key) {
}
function getRefDirectory(ref) {
- return ref.split(":")[1];
+ return ref.split(':')[1];
}
function getAlbum(el) {
- const directory = cssProp(el, "--album-directory");
+ const directory = cssProp(el, '--album-directory');
return albumData.find((album) => album.directory === directory);
}
function getFlash(el) {
- const directory = cssProp(el, "--flash-directory");
+ const directory = cssProp(el, '--flash-directory');
return flashData.find((flash) => flash.directory === directory);
}
@@ -88,17 +88,17 @@ const openFlash = (d) => rebase(`flash/${d}`);
function getTrackListAndIndex() {
const album = getAlbum(document.body);
- const directory = cssProp(document.body, "--track-directory");
+ const directory = cssProp(document.body, '--track-directory');
if (!directory && !album) return {};
- if (!directory) return { list: album.tracks };
+ if (!directory) return {list: album.tracks};
const trackIndex = album.tracks.findIndex(
(track) => track.directory === directory
);
- return { list: album.tracks, index: trackIndex };
+ return {list: album.tracks, index: trackIndex};
}
function openRandomTrack() {
- const { list } = getTrackListAndIndex();
+ const {list} = getTrackListAndIndex();
if (!list) return;
return openTrack(pick(list));
}
@@ -106,38 +106,38 @@ function openRandomTrack() {
function getFlashListAndIndex() {
const list = flashData.filter((flash) => !flash.act8r8k);
const flash = getFlash(document.body);
- if (!flash) return { list };
+ if (!flash) return {list};
const flashIndex = list.indexOf(flash);
- return { list, index: flashIndex };
+ return {list, index: flashIndex};
}
// TODO: This should also use urlSpec.
function fetchData(type, directory) {
- return fetch(rebase(`${type}/${directory}/data.json`, "rebaseData")).then(
+ return fetch(rebase(`${type}/${directory}/data.json`, 'rebaseData')).then(
(res) => res.json()
);
}
// JS-based links -----------------------------------------
-for (const a of document.body.querySelectorAll("[data-random]")) {
- a.addEventListener("click", (evt) => {
+for (const a of document.body.querySelectorAll('[data-random]')) {
+ a.addEventListener('click', (evt) => {
if (!ready) {
evt.preventDefault();
return;
}
setTimeout(() => {
- a.href = rebase("js-disabled");
+ a.href = rebase('js-disabled');
});
switch (a.dataset.random) {
- case "album":
+ case 'album':
return (a.href = openAlbum(pick(albumData).directory));
- case "album-in-fandom":
+ case 'album-in-fandom':
return (a.href = openAlbum(pick(fandomAlbumData).directory));
- case "album-in-official":
+ case 'album-in-official':
return (a.href = openAlbum(pick(officialAlbumData).directory));
- case "track":
+ case 'track':
return (a.href = openTrack(
getRefDirectory(
pick(
@@ -145,9 +145,9 @@ for (const a of document.body.querySelectorAll("[data-random]")) {
)
)
));
- case "track-in-album":
+ case 'track-in-album':
return (a.href = openTrack(getRefDirectory(pick(getAlbum(a).tracks))));
- case "track-in-fandom":
+ case 'track-in-fandom':
return (a.href = openTrack(
getRefDirectory(
pick(
@@ -158,7 +158,7 @@ for (const a of document.body.querySelectorAll("[data-random]")) {
)
)
));
- case "track-in-official":
+ case 'track-in-official':
return (a.href = openTrack(
getRefDirectory(
pick(
@@ -169,9 +169,9 @@ for (const a of document.body.querySelectorAll("[data-random]")) {
)
)
));
- case "artist":
+ case 'artist':
return (a.href = openArtist(pick(artistData).directory));
- case "artist-more-than-one-contrib":
+ case 'artist-more-than-one-contrib':
return (a.href = openArtist(
pick(
artistData.filter((artist) => getArtistNumContributions(artist) > 1)
@@ -181,51 +181,51 @@ for (const a of document.body.querySelectorAll("[data-random]")) {
});
}
-const next = document.getElementById("next-button");
-const previous = document.getElementById("previous-button");
-const random = document.getElementById("random-button");
+const next = document.getElementById('next-button');
+const previous = document.getElementById('previous-button');
+const random = document.getElementById('random-button');
const prependTitle = (el, prepend) => {
- const existing = el.getAttribute("title");
+ const existing = el.getAttribute('title');
if (existing) {
- el.setAttribute("title", prepend + " " + existing);
+ el.setAttribute('title', prepend + ' ' + existing);
} else {
- el.setAttribute("title", prepend);
+ el.setAttribute('title', prepend);
}
};
-if (next) prependTitle(next, "(Shift+N)");
-if (previous) prependTitle(previous, "(Shift+P)");
-if (random) prependTitle(random, "(Shift+R)");
+if (next) prependTitle(next, '(Shift+N)');
+if (previous) prependTitle(previous, '(Shift+P)');
+if (random) prependTitle(random, '(Shift+R)');
-document.addEventListener("keypress", (event) => {
+document.addEventListener('keypress', (event) => {
if (event.shiftKey) {
- if (event.charCode === "N".charCodeAt(0)) {
+ if (event.charCode === 'N'.charCodeAt(0)) {
if (next) next.click();
- } else if (event.charCode === "P".charCodeAt(0)) {
+ } else if (event.charCode === 'P'.charCodeAt(0)) {
if (previous) previous.click();
- } else if (event.charCode === "R".charCodeAt(0)) {
+ } else if (event.charCode === 'R'.charCodeAt(0)) {
if (random && ready) random.click();
}
}
});
-for (const reveal of document.querySelectorAll(".reveal")) {
- reveal.addEventListener("click", (event) => {
- if (!reveal.classList.contains("revealed")) {
- reveal.classList.add("revealed");
+for (const reveal of document.querySelectorAll('.reveal')) {
+ reveal.addEventListener('click', (event) => {
+ if (!reveal.classList.contains('revealed')) {
+ reveal.classList.add('revealed');
event.preventDefault();
event.stopPropagation();
}
});
}
-const elements1 = document.getElementsByClassName("js-hide-once-data");
-const elements2 = document.getElementsByClassName("js-show-once-data");
+const elements1 = document.getElementsByClassName('js-hide-once-data');
+const elements2 = document.getElementsByClassName('js-show-once-data');
-for (const element of elements1) element.style.display = "block";
+for (const element of elements1) element.style.display = 'block';
-fetch(rebase("data.json", "rebaseShared"))
+fetch(rebase('data.json', 'rebaseShared'))
.then((data) => data.json())
.then((data) => {
albumData = data.albumData;
@@ -233,17 +233,17 @@ fetch(rebase("data.json", "rebaseShared"))
flashData = data.flashData;
officialAlbumData = albumData.filter((album) =>
- album.groups.includes("group:official")
+ album.groups.includes('group:official')
);
fandomAlbumData = albumData.filter(
- (album) => !album.groups.includes("group:official")
+ (album) => !album.groups.includes('group:official')
);
artistNames = artistData
.filter((artist) => !artist.alias)
.map((artist) => artist.name);
- for (const element of elements1) element.style.display = "none";
- for (const element of elements2) element.style.display = "block";
+ for (const element of elements1) element.style.display = 'none';
+ for (const element of elements2) element.style.display = 'block';
ready = true;
});
@@ -260,13 +260,13 @@ let endFastHoverTimeout = null;
function colorLink(a, color) {
if (color) {
- const { primary, dim } = getColors(color);
- a.style.setProperty("--primary-color", primary);
- a.style.setProperty("--dim-color", dim);
+ const {primary, dim} = getColors(color);
+ a.style.setProperty('--primary-color', primary);
+ a.style.setProperty('--dim-color', dim);
}
}
-function link(a, type, { name, directory, color }) {
+function link(a, type, {name, directory, color}) {
colorLink(a, color);
a.innerText = name;
a.href = getLinkHref(type, directory);
@@ -284,14 +284,14 @@ function joinElements(type, elements) {
}
const infoCard = (() => {
- const container = document.getElementById("info-card-container");
+ const container = document.getElementById('info-card-container');
let cancelShow = false;
let hideTimeout = null;
let showing = false;
- container.addEventListener("mouseenter", cancelHide);
- container.addEventListener("mouseleave", readyHide);
+ container.addEventListener('mouseenter', cancelHide);
+ container.addEventListener('mouseleave', readyHide);
function show(type, target) {
cancelShow = false;
@@ -307,91 +307,91 @@ const infoCard = (() => {
const rect = target.getBoundingClientRect();
- container.style.setProperty("--primary-color", data.color);
+ container.style.setProperty('--primary-color', data.color);
- container.style.top = window.scrollY + rect.bottom + "px";
- container.style.left = window.scrollX + rect.left + "px";
+ container.style.top = window.scrollY + rect.bottom + 'px';
+ container.style.left = window.scrollX + rect.left + 'px';
// Use a short timeout to let a currently hidden (or not yet shown)
// info card teleport to the position set a8ove. (If it's currently
// shown, it'll transition to that position.)
setTimeout(() => {
- container.classList.remove("hide");
- container.classList.add("show");
+ container.classList.remove('hide');
+ container.classList.add('show');
}, 50);
// 8asic details.
- const nameLink = container.querySelector(".info-card-name a");
- link(nameLink, "track", data);
+ const nameLink = container.querySelector('.info-card-name a');
+ link(nameLink, 'track', data);
- const albumLink = container.querySelector(".info-card-album a");
- link(albumLink, "album", data.album);
+ const albumLink = container.querySelector('.info-card-album a');
+ link(albumLink, 'album', data.album);
- const artistSpan = container.querySelector(".info-card-artists span");
+ const artistSpan = container.querySelector('.info-card-artists span');
artistSpan.innerHTML = joinElements(
- "conjunction",
- data.artists.map(({ artist }) => {
- const a = document.createElement("a");
- a.href = getLinkHref("artist", artist.directory);
+ 'conjunction',
+ data.artists.map(({artist}) => {
+ const a = document.createElement('a');
+ a.href = getLinkHref('artist', artist.directory);
a.innerText = artist.name;
return a;
})
);
const coverArtistParagraph = container.querySelector(
- ".info-card-cover-artists"
+ '.info-card-cover-artists'
);
- const coverArtistSpan = coverArtistParagraph.querySelector("span");
+ const coverArtistSpan = coverArtistParagraph.querySelector('span');
if (data.coverArtists.length) {
- coverArtistParagraph.style.display = "block";
+ coverArtistParagraph.style.display = 'block';
coverArtistSpan.innerHTML = joinElements(
- "conjunction",
- data.coverArtists.map(({ artist }) => {
- const a = document.createElement("a");
- a.href = getLinkHref("artist", artist.directory);
+ 'conjunction',
+ data.coverArtists.map(({artist}) => {
+ const a = document.createElement('a');
+ a.href = getLinkHref('artist', artist.directory);
a.innerText = artist.name;
return a;
})
);
} else {
- coverArtistParagraph.style.display = "none";
+ coverArtistParagraph.style.display = 'none';
}
// Cover art.
const [containerNoReveal, containerReveal] = [
- container.querySelector(".info-card-art-container.no-reveal"),
- container.querySelector(".info-card-art-container.reveal"),
+ container.querySelector('.info-card-art-container.no-reveal'),
+ container.querySelector('.info-card-art-container.reveal'),
];
const [containerShow, containerHide] = data.cover.warnings.length
? [containerReveal, containerNoReveal]
: [containerNoReveal, containerReveal];
- containerHide.style.display = "none";
- containerShow.style.display = "block";
+ containerHide.style.display = 'none';
+ containerShow.style.display = 'block';
- const img = containerShow.querySelector(".info-card-art");
- img.src = rebase(data.cover.paths.small, "rebaseMedia");
+ const img = containerShow.querySelector('.info-card-art');
+ img.src = rebase(data.cover.paths.small, 'rebaseMedia');
- const imgLink = containerShow.querySelector("a");
+ const imgLink = containerShow.querySelector('a');
colorLink(imgLink, data.color);
- imgLink.href = rebase(data.cover.paths.original, "rebaseMedia");
+ imgLink.href = rebase(data.cover.paths.original, 'rebaseMedia');
if (containerShow === containerReveal) {
- const cw = containerShow.querySelector(".info-card-art-warnings");
+ const cw = containerShow.querySelector('.info-card-art-warnings');
cw.innerText = list.unit(data.cover.warnings);
- const reveal = containerShow.querySelector(".reveal");
- reveal.classList.remove("revealed");
+ const reveal = containerShow.querySelector('.reveal');
+ reveal.classList.remove('revealed');
}
});
}
function hide() {
- container.classList.remove("show");
- container.classList.add("hide");
+ container.classList.remove('show');
+ container.classList.add('hide');
cancelShow = true;
showing = false;
}
@@ -452,7 +452,7 @@ function makeInfoCardLinkHandlers(type) {
}
const infoCardLinkHandlers = {
- track: makeInfoCardLinkHandlers("track"),
+ track: makeInfoCardLinkHandlers('track'),
};
function addInfoCardLinkHandlers(type) {
@@ -471,5 +471,5 @@ function addInfoCardLinkHandlers(type) {
// localStorage.tryInfoCards = true;
//
if (localStorage.tryInfoCards) {
- addInfoCardLinkHandlers("track");
+ addInfoCardLinkHandlers('track');
}
diff --git a/src/static/lazy-loading.js b/src/static/lazy-loading.js
index 5ca9fb38..8f3e8cf5 100644
--- a/src/static/lazy-loading.js
+++ b/src/static/lazy-loading.js
@@ -1,5 +1,5 @@
-// @format
-//
+/** @format */
+
// Lazy loading! Roll your own. Woot.
// This file includes a 8unch of fall8acks and stuff like that, and is written
// with fairly Olden JavaScript(TM), so as to work on pretty much any 8rowser
@@ -27,15 +27,15 @@ function lazyLoadMain() {
// we'd 8e mutating its value just 8y interacting with the DOM elements it
// contains. A while loop works just fine, even though you'd think reading
// over this code that this would 8e an infinitely hanging loop. It isn't!
- var elements = document.getElementsByClassName("js-hide");
+ var elements = document.getElementsByClassName('js-hide');
while (elements.length) {
- elements[0].classList.remove("js-hide");
+ elements[0].classList.remove('js-hide');
}
- var lazyElements = document.getElementsByClassName("lazy");
+ var lazyElements = document.getElementsByClassName('lazy');
if (window.IntersectionObserver) {
observer = new IntersectionObserver(lazyLoad, {
- rootMargin: "200px",
+ rootMargin: '200px',
threshold: 1.0,
});
for (var i = 0; i < lazyElements.length; i++) {
@@ -44,10 +44,10 @@ function lazyLoadMain() {
} else {
for (var i = 0; i < lazyElements.length; i++) {
var element = lazyElements[i];
- var original = element.getAttribute("data-original");
- element.setAttribute("src", original);
+ var original = element.getAttribute('data-original');
+ element.setAttribute('src', original);
}
}
}
-document.addEventListener("DOMContentLoaded", lazyLoadMain);
+document.addEventListener('DOMContentLoaded', lazyLoadMain);
diff --git a/src/upd8.js b/src/upd8.js
index cff43135..8a5a2873 100755
--- a/src/upd8.js
+++ b/src/upd8.js
@@ -1,6 +1,5 @@
#!/usr/bin/env node
-
-// @format
+/** @format */
// HEY N8RDS!
//
@@ -33,18 +32,18 @@
// Oh yeah, like. Just run this through some relatively recent version of
// node.js and you'll 8e fine. ...Within the project root. O8viously.
-import * as path from "path";
-import { promisify } from "util";
-import { fileURLToPath } from "url";
+import * as path from 'path';
+import {promisify} from 'util';
+import {fileURLToPath} from 'url';
// I made this dependency myself! A long, long time ago. It is pro8a8ly my
// most useful li8rary ever. I'm not sure 8esides me actually uses it, though.
-import fixWS from "fix-whitespace";
+import fixWS from 'fix-whitespace';
// Wait nevermind, I forgot a8out why-do-kids-love-the-taste-of-cinnamon-toast-
// crunch. THAT is my 8est li8rary.
// It stands for "HTML Entities", apparently. Cursed.
-import he from "he";
+import he from 'he';
import {
copyFile,
@@ -54,25 +53,25 @@ import {
symlink,
writeFile,
unlink,
-} from "fs/promises";
+} from 'fs/promises';
-import { inspect as nodeInspect } from "util";
+import {inspect as nodeInspect} from 'util';
-import genThumbs from "./gen-thumbs.js";
-import { listingSpec, listingTargetSpec } from "./listing-spec.js";
-import urlSpec from "./url-spec.js";
-import * as pageSpecs from "./page/index.js";
+import genThumbs from './gen-thumbs.js';
+import {listingSpec, listingTargetSpec} from './listing-spec.js';
+import urlSpec from './url-spec.js';
+import * as pageSpecs from './page/index.js';
-import find, { bindFind } from "./util/find.js";
-import * as html from "./util/html.js";
-import unbound_link, { getLinkThemeString } from "./util/link.js";
-import { findFiles } from "./util/io.js";
+import find, {bindFind} from './util/find.js';
+import * as html from './util/html.js';
+import unbound_link, {getLinkThemeString} from './util/link.js';
+import {findFiles} from './util/io.js';
-import CacheableObject from "./data/cacheable-object.js";
+import CacheableObject from './data/cacheable-object.js';
-import { serializeThings } from "./data/serialize.js";
+import {serializeThings} from './data/serialize.js';
-import { Language } from "./data/things.js";
+import {Language} from './data/things.js';
import {
filterDuplicateDirectories,
@@ -81,7 +80,7 @@ import {
loadAndProcessDataDocuments,
sortWikiDataArrays,
WIKI_INFO_FILE,
-} from "./data/yaml.js";
+} from './data/yaml.js';
import {
fancifyFlashURL,
@@ -103,7 +102,7 @@ import {
getRevealStringFromWarnings,
getThemeString,
iconifyURL,
-} from "./misc-templates.js";
+} from './misc-templates.js';
import {
color,
@@ -114,9 +113,9 @@ import {
parseOptions,
progressPromiseAll,
ENABLE_COLOR,
-} from "./util/cli.js";
+} from './util/cli.js';
-import { validateReplacerSpec, transformInline } from "./util/replacer.js";
+import {validateReplacerSpec, transformInline} from './util/replacer.js';
import {
chunkByConditions,
@@ -130,7 +129,7 @@ import {
getKebabCase,
getTotalDuration,
getTrackCover,
-} from "./util/wiki-data.js";
+} from './util/wiki-data.js';
import {
serializeContribs,
@@ -139,7 +138,7 @@ import {
serializeGroupsForTrack,
serializeImagePaths,
serializeLink,
-} from "./util/serialize.js";
+} from './util/serialize.js';
import {
bindOpts,
@@ -155,23 +154,23 @@ import {
unique,
withAggregate,
withEntries,
-} from "./util/sugar.js";
+} from './util/sugar.js';
-import { generateURLs, thumb } from "./util/urls.js";
+import {generateURLs, thumb} from './util/urls.js';
// Pensive emoji!
import {
FANDOM_GROUP_DIRECTORY,
OFFICIAL_GROUP_DIRECTORY,
-} from "./util/magic-constants.js";
+} from './util/magic-constants.js';
-import FileSizePreloader from "./file-size-preloader.js";
+import FileSizePreloader from './file-size-preloader.js';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const CACHEBUST = 10;
-const DEFAULT_STRINGS_FILE = "strings-default.json";
+const DEFAULT_STRINGS_FILE = 'strings-default.json';
// Code that's common 8etween the 8uild code (i.e. upd8.js) and gener8ted
// site code should 8e put here. Which, uh, ~~only really means this one
@@ -180,20 +179,20 @@ const DEFAULT_STRINGS_FILE = "strings-default.json";
// Rather than hard code it, anything in this directory can 8e shared across
// 8oth ends of the code8ase.
// (This gets symlinked into the --data-path directory.)
-const UTILITY_DIRECTORY = "util";
+const UTILITY_DIRECTORY = 'util';
// Code that's used only in the static site! CSS, cilent JS, etc.
// (This gets symlinked into the --data-path directory.)
-const STATIC_DIRECTORY = "static";
+const STATIC_DIRECTORY = 'static';
// This exists adjacent to index.html for any page with oEmbed metadata.
-const OEMBED_JSON_FILE = "oembed.json";
+const OEMBED_JSON_FILE = 'oembed.json';
// Automatically copied (if present) from media directory to site root.
-const FAVICON_FILE = "favicon.ico";
+const FAVICON_FILE = 'favicon.ico';
function inspect(value) {
- return nodeInspect(value, { colors: ENABLE_COLOR });
+ return nodeInspect(value, {colors: ENABLE_COLOR});
}
// Shared varia8les! These are more efficient to access than a shared varia8le
@@ -222,38 +221,38 @@ function splitLines(text) {
const replacerSpec = {
album: {
- find: "album",
- link: "album",
+ find: 'album',
+ link: 'album',
},
- "album-commentary": {
- find: "album",
- link: "albumCommentary",
+ 'album-commentary': {
+ find: 'album',
+ link: 'albumCommentary',
},
artist: {
- find: "artist",
- link: "artist",
+ find: 'artist',
+ link: 'artist',
},
- "artist-gallery": {
- find: "artist",
- link: "artistGallery",
+ 'artist-gallery': {
+ find: 'artist',
+ link: 'artistGallery',
},
- "commentary-index": {
+ 'commentary-index': {
find: null,
- link: "commentaryIndex",
+ link: 'commentaryIndex',
},
date: {
find: null,
value: (ref) => new Date(ref),
- html: (date, { language }) =>
+ html: (date, {language}) =>
``,
},
flash: {
- find: "flash",
- link: "flash",
+ find: 'flash',
+ link: 'flash',
transformName(name, node, input) {
const nextCharacter = input[node.iEnd];
const lastCharacter = name[name.length - 1];
- if (![" ", "\n", "<"].includes(nextCharacter) && lastCharacter === ".") {
+ if (![' ', '\n', '<'].includes(nextCharacter) && lastCharacter === '.') {
return name.slice(0, -1);
} else {
return name;
@@ -261,69 +260,69 @@ const replacerSpec = {
},
},
group: {
- find: "group",
- link: "groupInfo",
+ find: 'group',
+ link: 'groupInfo',
},
- "group-gallery": {
- find: "group",
- link: "groupGallery",
+ 'group-gallery': {
+ find: 'group',
+ link: 'groupGallery',
},
home: {
find: null,
- link: "home",
+ link: 'home',
},
- "listing-index": {
+ 'listing-index': {
find: null,
- link: "listingIndex",
+ link: 'listingIndex',
},
listing: {
- find: "listing",
- link: "listing",
+ find: 'listing',
+ link: 'listing',
},
media: {
find: null,
- link: "media",
+ link: 'media',
},
- "news-index": {
+ 'news-index': {
find: null,
- link: "newsIndex",
+ link: 'newsIndex',
},
- "news-entry": {
- find: "newsEntry",
- link: "newsEntry",
+ 'news-entry': {
+ find: 'newsEntry',
+ link: 'newsEntry',
},
root: {
find: null,
- link: "root",
+ link: 'root',
},
site: {
find: null,
- link: "site",
+ link: 'site',
},
static: {
- find: "staticPage",
- link: "staticPage",
+ find: 'staticPage',
+ link: 'staticPage',
},
string: {
find: null,
value: (ref) => ref,
- html: (ref, { language, args }) => language.$(ref, args),
+ html: (ref, {language, args}) => language.$(ref, args),
},
tag: {
- find: "artTag",
- link: "tag",
+ find: 'artTag',
+ link: 'tag',
},
track: {
- find: "track",
- link: "track",
+ find: 'track',
+ link: 'track',
},
};
-if (!validateReplacerSpec(replacerSpec, { find, link: unbound_link })) {
+if (!validateReplacerSpec(replacerSpec, {find, link: unbound_link})) {
process.exit();
}
-function parseAttributes(string, { to }) {
+function parseAttributes(string, {to}) {
const attributes = Object.create(null);
const skipWhitespace = (i) => {
const ws = /\s/;
@@ -345,7 +344,7 @@ function parseAttributes(string, { to }) {
const aEnd = i + string.slice(i).match(/[\s=]|$/).index;
const attribute = string.slice(aStart, aEnd);
i = skipWhitespace(aEnd);
- if (string[i] === "=") {
+ if (string[i] === '=') {
i = skipWhitespace(i + 1);
let end, endOffset;
if (string[i] === '"' || string[i] === "'") {
@@ -353,15 +352,15 @@ function parseAttributes(string, { to }) {
endOffset = 1;
i++;
} else {
- end = "\\s";
+ end = '\\s';
endOffset = 0;
}
const vStart = i;
const vEnd = i + string.slice(i).match(new RegExp(`${end}|$`)).index;
const value = string.slice(vStart, vEnd);
i = vEnd + endOffset;
- if (attribute === "src" && value.startsWith("media/")) {
- attributes[attribute] = to("media.path", value.slice("media/".length));
+ if (attribute === 'src' && value.startsWith('media/')) {
+ attributes[attribute] = to('media.path', value.slice('media/'.length));
} else {
attributes[attribute] = value;
}
@@ -372,9 +371,9 @@ function parseAttributes(string, { to }) {
return Object.fromEntries(
Object.entries(attributes).map(([key, val]) => [
key,
- val === "true"
+ val === 'true'
? true
- : val === "false"
+ : val === 'false'
? false
: val === key
? true
@@ -386,13 +385,13 @@ function parseAttributes(string, { to }) {
function joinLineBreaks(sourceLines) {
const outLines = [];
- let lineSoFar = "";
+ let lineSoFar = '';
for (let i = 0; i < sourceLines.length; i++) {
const line = sourceLines[i];
lineSoFar += line;
- if (!line.endsWith("
");
+ outLines.push('');
}
- return outLines.join("\n");
+ return outLines.join('\n');
}
-function transformLyrics(text, { transformInline, transformMultiline }) {
+function transformLyrics(text, {transformInline, transformMultiline}) {
// Different from transformMultiline 'cuz it joins multiple lines together
// with line 8reaks (
")) {
+ if (!line.endsWith('
')) {
outLines.push(lineSoFar);
- lineSoFar = "";
+ lineSoFar = '';
}
}
@@ -403,14 +402,14 @@ function joinLineBreaks(sourceLines) {
return outLines;
}
-function transformMultiline(text, { parseAttributes, transformInline }) {
+function transformMultiline(text, {parseAttributes, transformInline}) {
// Heck yes, HTML magics.
text = transformInline(text.trim());
const outLines = [];
- const indentString = " ".repeat(4);
+ const indentString = ' '.repeat(4);
let levelIndents = [];
const openLevel = (indent) => {
@@ -418,13 +417,13 @@ function transformMultiline(text, { parseAttributes, transformInline }) {
// correct, we have to append the at the end of the existing
// previous
');
} else {
// closing the final list level! no need for indent here
- outLines.push("");
+ outLines.push('');
}
};
@@ -448,19 +447,19 @@ function transformMultiline(text, { parseAttributes, transformInline }) {
let lines = splitLines(text);
lines = joinLineBreaks(lines);
for (let line of lines) {
- const imageLine = line.startsWith("/g, (match, attributes) =>
img({
lazy: true,
link: true,
- thumb: "medium",
+ thumb: 'medium',
...parseAttributes(attributes),
})
);
let indentThisLine = 0;
let lineContent = line;
- let lineTag = "p";
+ let lineTag = 'p';
const listMatch = line.match(/^( *)- *(.*)$/);
if (listMatch) {
@@ -498,7 +497,7 @@ function transformMultiline(text, { parseAttributes, transformInline }) {
// finally, set variables for appending content line
indentThisLine = levelIndents.length;
lineContent = listMatch[2];
- lineTag = "li";
+ lineTag = 'li';
} else {
// not a list item! close any existing list levels
while (levelIndents.length) closeLevel();
@@ -510,27 +509,27 @@ function transformMultiline(text, { parseAttributes, transformInline }) {
// is a quote! open a blockquote tag if it doesnt already exist
if (!inBlockquote) {
inBlockquote = true;
- outLines.push("";
+ outLines[outLines.length - 1] = previousLine.slice(0, -5) + '
';
} else {
// if the previous line isn't a list item, this is the opening of
// the first list level, so no need for indent
- outLines.push("
");
+ outLines.push('
');
}
levelIndents.push(indent);
};
@@ -432,10 +431,10 @@ function transformMultiline(text, { parseAttributes, transformInline }) {
levelIndents.pop();
if (levelIndents.length) {
// closing a sublist, so close the list item containing it too
- outLines.push(indentString.repeat(levelIndents.length) + "
");
+ outLines.push('
');
}
// let some escaped symbols display as the normal symbol, since the
// point of escaping them is just to avoid having them be treated as
// syntax markers!
if (lineContent.match(/( *)\\-/)) {
- lineContent = lineContent.replace("\\-", "-");
+ lineContent = lineContent.replace('\\-', '-');
} else if (lineContent.match(/( *)\\>/)) {
- lineContent = lineContent.replace("\\>", ">");
+ lineContent = lineContent.replace('\\>', '>');
}
}
- if (lineTag === "p") {
+ if (lineTag === 'p') {
// certain inline element tags should still be postioned within a
// paragraph; other elements (e.g. headings) should be added as-is
const elementMatch = line.match(/^<(.*?)[ >]/);
@@ -538,40 +537,40 @@ function transformMultiline(text, { parseAttributes, transformInline }) {
elementMatch &&
!imageLine &&
![
- "a",
- "abbr",
- "b",
- "bdo",
- "br",
- "cite",
- "code",
- "data",
- "datalist",
- "del",
- "dfn",
- "em",
- "i",
- "img",
- "ins",
- "kbd",
- "mark",
- "output",
- "picture",
- "q",
- "ruby",
- "samp",
- "small",
- "span",
- "strong",
- "sub",
- "sup",
- "svg",
- "time",
- "var",
- "wbr",
+ 'a',
+ 'abbr',
+ 'b',
+ 'bdo',
+ 'br',
+ 'cite',
+ 'code',
+ 'data',
+ 'datalist',
+ 'del',
+ 'dfn',
+ 'em',
+ 'i',
+ 'img',
+ 'ins',
+ 'kbd',
+ 'mark',
+ 'output',
+ 'picture',
+ 'q',
+ 'ruby',
+ 'samp',
+ 'small',
+ 'span',
+ 'strong',
+ 'sub',
+ 'sup',
+ 'svg',
+ 'time',
+ 'var',
+ 'wbr',
].includes(elementMatch[1])
) {
- lineTag = "";
+ lineTag = '';
}
}
@@ -592,43 +591,43 @@ function transformMultiline(text, { parseAttributes, transformInline }) {
// if still in a blockquote, close its tag
if (inBlockquote) {
inBlockquote = false;
- outLines.push("');
}
indentThisLine = 1;
lineContent = quoteMatch[1];
} else if (inBlockquote) {
// not a quote! close a blockquote tag if it exists
inBlockquote = false;
- outLines.push("
");
+ outLines.push('
); transformMultiline treats each line as its own
// complete paragraph (or list, etc).
// If it looks like old data, then like, oh god.
// Use the normal transformMultiline tool.
- if (text.includes("
outLines.push(`
";
+ buildLine += '
';
}
buildLine += line;
} else if (buildLine.length) {
addLine();
- buildLine = "";
+ buildLine = '';
}
}
if (buildLine.length) {
addLine();
}
- return outLines.join("\n");
+ return outLines.join('\n');
}
function stringifyThings(thingData) {
@@ -638,7 +637,7 @@ function stringifyThings(thingData) {
function img({
src,
alt,
- noSrcText = "",
+ noSrcText = '',
thumb: thumbKey,
reveal,
id,
@@ -650,13 +649,13 @@ function img({
square = false,
}) {
const willSquare = square;
- const willLink = typeof link === "string" || link;
+ const willLink = typeof link === 'string' || link;
const originalSrc = src;
const thumbSrc = src && (thumbKey ? thumb[thumbKey](src) : src);
const imgAttributes = html.attributes({
- id: link ? "" : id,
+ id: link ? '' : id,
class: className,
alt,
width,
@@ -701,21 +700,21 @@ function img({
}
if (willSquare) {
- wrapped = html.tag("div", { class: "square-content" }, wrapped);
+ wrapped = html.tag('div', {class: 'square-content'}, wrapped);
wrapped = html.tag(
- "div",
- { class: ["square", hide && !willLink && "js-hide"] },
+ 'div',
+ {class: ['square', hide && !willLink && 'js-hide']},
wrapped
);
}
if (willLink) {
wrapped = html.tag(
- "a",
+ 'a',
{
id,
- class: ["box", hide && "js-hide"],
- href: typeof link === "string" ? link : originalSrc,
+ class: ['box', hide && 'js-hide'],
+ href: typeof link === 'string' ? link : originalSrc,
},
wrapped
);
@@ -727,16 +726,16 @@ function img({
function validateWritePath(path, urlGroup) {
if (!Array.isArray(path)) {
- return { error: `Expected array, got ${path}` };
+ return {error: `Expected array, got ${path}`};
}
- const { paths } = urlGroup;
+ const {paths} = urlGroup;
const definedKeys = Object.keys(paths);
const specifiedKey = path[0];
if (!definedKeys.includes(specifiedKey)) {
- return { error: `Specified key ${specifiedKey} isn't defined` };
+ return {error: `Specified key ${specifiedKey} isn't defined`};
}
const expectedArgs = paths[specifiedKey].match(/<>/g)?.length ?? 0;
@@ -748,54 +747,54 @@ function validateWritePath(path, urlGroup) {
};
}
- return { success: true };
+ return {success: true};
}
function validateWriteObject(obj) {
- if (typeof obj !== "object") {
- return { error: `Expected object, got ${typeof obj}` };
+ if (typeof obj !== 'object') {
+ return {error: `Expected object, got ${typeof obj}`};
}
- if (typeof obj.type !== "string") {
- return { error: `Expected type to be string, got ${obj.type}` };
+ if (typeof obj.type !== 'string') {
+ return {error: `Expected type to be string, got ${obj.type}`};
}
switch (obj.type) {
- case "legacy": {
- if (typeof obj.write !== "function") {
- return { error: `Expected write to be string, got ${obj.write}` };
+ case 'legacy': {
+ if (typeof obj.write !== 'function') {
+ return {error: `Expected write to be string, got ${obj.write}`};
}
break;
}
- case "page": {
+ case 'page': {
const path = validateWritePath(obj.path, urlSpec.localized);
if (path.error) {
- return { error: `Path validation failed: ${path.error}` };
+ return {error: `Path validation failed: ${path.error}`};
}
- if (typeof obj.page !== "function") {
- return { error: `Expected page to be function, got ${obj.content}` };
+ if (typeof obj.page !== 'function') {
+ return {error: `Expected page to be function, got ${obj.content}`};
}
break;
}
- case "data": {
+ case 'data': {
const path = validateWritePath(obj.path, urlSpec.data);
if (path.error) {
- return { error: `Path validation failed: ${path.error}` };
+ return {error: `Path validation failed: ${path.error}`};
}
- if (typeof obj.data !== "function") {
- return { error: `Expected data to be function, got ${obj.data}` };
+ if (typeof obj.data !== 'function') {
+ return {error: `Expected data to be function, got ${obj.data}`};
}
break;
}
- case "redirect": {
+ case 'redirect': {
const fromPath = validateWritePath(obj.fromPath, urlSpec.localized);
if (fromPath.error) {
return {
@@ -805,22 +804,22 @@ function validateWriteObject(obj) {
const toPath = validateWritePath(obj.toPath, urlSpec.localized);
if (toPath.error) {
- return { error: `Path (toPath) validation failed: ${toPath.error}` };
+ return {error: `Path (toPath) validation failed: ${toPath.error}`};
}
- if (typeof obj.title !== "function") {
- return { error: `Expected title to be function, got ${obj.title}` };
+ if (typeof obj.title !== 'function') {
+ return {error: `Expected title to be function, got ${obj.title}`};
}
break;
}
default: {
- return { error: `Unknown type: ${obj.type}` };
+ return {error: `Unknown type: ${obj.type}`};
}
}
- return { success: true };
+ return {success: true};
}
/*
@@ -836,9 +835,9 @@ async function writeData(subKey, directory, data) {
const writePage = {};
writePage.to =
- ({ baseDirectory, pageSubKey, paths }) =>
+ ({baseDirectory, pageSubKey, paths}) =>
(targetFullKey, ...args) => {
- const [groupKey, subKey] = targetFullKey.split(".");
+ const [groupKey, subKey] = targetFullKey.split('.');
let path = paths.subdirectoryPrefix;
let from;
@@ -847,27 +846,27 @@ writePage.to =
// When linking to *outside* the localized area of the site, we need to
// make sure the result is correctly relative to the 8ase directory.
if (
- groupKey !== "localized" &&
- groupKey !== "localizedDefaultLanguage" &&
+ groupKey !== 'localized' &&
+ groupKey !== 'localizedDefaultLanguage' &&
baseDirectory
) {
- from = "localizedWithBaseDirectory." + pageSubKey;
+ from = 'localizedWithBaseDirectory.' + pageSubKey;
to = targetFullKey;
- } else if (groupKey === "localizedDefaultLanguage" && baseDirectory) {
+ } else if (groupKey === 'localizedDefaultLanguage' && baseDirectory) {
// Special case for specifically linking *from* a page with base
// directory *to* a page without! Used for the language switcher and
// hopefully nothing else oh god.
- from = "localizedWithBaseDirectory." + pageSubKey;
- to = "localized." + subKey;
- } else if (groupKey === "localizedDefaultLanguage") {
+ from = 'localizedWithBaseDirectory.' + pageSubKey;
+ to = 'localized.' + subKey;
+ } else if (groupKey === 'localizedDefaultLanguage') {
// Linking to the default, except surprise, we're already IN the default
// (no baseDirectory set).
- from = "localized." + pageSubKey;
- to = "localized." + subKey;
+ from = 'localized.' + pageSubKey;
+ to = 'localized.' + subKey;
} else {
// If we're linking inside the localized area (or there just is no
// 8ase directory), the 8ase directory doesn't matter.
- from = "localized." + pageSubKey;
+ from = 'localized.' + pageSubKey;
to = targetFullKey;
}
@@ -890,13 +889,13 @@ writePage.html = (
wikiData,
}
) => {
- const { wikiInfo } = wikiData;
+ const {wikiInfo} = wikiData;
let {
- title = "",
+ title = '',
meta = {},
- theme = "",
- stylesheet = "",
+ theme = '',
+ stylesheet = '',
showWikiNameInTitle = true,
@@ -912,45 +911,45 @@ writePage.html = (
socialEmbed = {},
} = pageInfo;
- body.style ??= "";
+ body.style ??= '';
theme = theme || getThemeString(wikiInfo.color);
banner ||= {};
banner.classes ??= [];
- banner.src ??= "";
- banner.position ??= "";
+ banner.src ??= '';
+ banner.position ??= '';
banner.dimensions ??= [0, 0];
main.classes ??= [];
- main.content ??= "";
+ main.content ??= '';
sidebarLeft ??= {};
sidebarRight ??= {};
for (const sidebar of [sidebarLeft, sidebarRight]) {
sidebar.classes ??= [];
- sidebar.content ??= "";
+ sidebar.content ??= '';
sidebar.collapse ??= true;
}
nav.classes ??= [];
- nav.content ??= "";
- nav.bottomRowContent ??= "";
+ nav.content ??= '';
+ nav.bottomRowContent ??= '';
nav.links ??= [];
nav.linkContainerClasses ??= [];
secondaryNav ??= {};
- secondaryNav.content ??= "";
- secondaryNav.content ??= "";
+ secondaryNav.content ??= '';
+ secondaryNav.content ??= '';
footer.classes ??= [];
footer.content ??= wikiInfo.footerContent
? transformMultiline(wikiInfo.footerContent)
- : "";
+ : '';
footer.content +=
- "\n" +
+ '\n' +
getFooterLocalizationLinks(paths.pathname, {
defaultLanguage,
languages,
@@ -960,13 +959,13 @@ writePage.html = (
});
const canonical = wikiInfo.canonicalBase
- ? wikiInfo.canonicalBase + (paths.pathname === "/" ? "" : paths.pathname)
- : "";
+ ? wikiInfo.canonicalBase + (paths.pathname === '/' ? '' : paths.pathname)
+ : '';
const localizedCanonical = wikiInfo.canonicalBase
- ? Object.entries(localizedPaths).map(([code, { pathname }]) => ({
+ ? Object.entries(localizedPaths).map(([code, {pathname}]) => ({
lang: code,
- href: wikiInfo.canonicalBase + (pathname === "/" ? "" : pathname),
+ href: wikiInfo.canonicalBase + (pathname === '/' ? '' : pathname),
}))
: [];
@@ -976,9 +975,9 @@ writePage.html = (
const mainHTML =
main.content &&
html.tag(
- "main",
+ 'main',
{
- id: "content",
+ id: 'content',
class: main.classes,
},
main.content
@@ -987,9 +986,9 @@ writePage.html = (
const footerHTML =
footer.content &&
html.tag(
- "footer",
+ 'footer',
{
- id: "footer",
+ id: 'footer',
class: footer.classes,
},
footer.content
@@ -997,18 +996,18 @@ writePage.html = (
const generateSidebarHTML = (
id,
- { content, multiple, classes, collapse = true, wide = false }
+ {content, multiple, classes, collapse = true, wide = false}
) =>
content
? html.tag(
- "div",
+ 'div',
{
id,
class: [
- "sidebar-column",
- "sidebar",
- wide && "wide",
- !collapse && "no-hide",
+ 'sidebar-column',
+ 'sidebar',
+ wide && 'wide',
+ !collapse && 'no-hide',
...classes,
],
},
@@ -1016,28 +1015,28 @@ writePage.html = (
)
: multiple
? html.tag(
- "div",
+ 'div',
{
id,
class: [
- "sidebar-column",
- "sidebar-multiple",
- wide && "wide",
- !collapse && "no-hide",
+ 'sidebar-column',
+ 'sidebar-multiple',
+ wide && 'wide',
+ !collapse && 'no-hide',
],
},
multiple.map((content) =>
- html.tag("div", { class: ["sidebar", ...classes] }, content)
+ html.tag('div', {class: ['sidebar', ...classes]}, content)
)
)
- : "";
+ : '';
- const sidebarLeftHTML = generateSidebarHTML("sidebar-left", sidebarLeft);
- const sidebarRightHTML = generateSidebarHTML("sidebar-right", sidebarRight);
+ const sidebarLeftHTML = generateSidebarHTML('sidebar-left', sidebarLeft);
+ const sidebarRightHTML = generateSidebarHTML('sidebar-right', sidebarRight);
if (nav.simple) {
- nav.linkContainerClasses = ["nav-links-hierarchy"];
- nav.links = [{ toHome: true }, { toCurrentPage: true }];
+ nav.linkContainerClasses = ['nav-links-hierarchy'];
+ nav.links = [{toHome: true}, {toCurrentPage: true}];
}
const links = (nav.links || []).filter(Boolean);
@@ -1048,7 +1047,7 @@ writePage.html = (
const prev = links[i - 1];
const next = links[i + 1];
- let { title: linkTitle } = cur;
+ let {title: linkTitle} = cur;
if (cur.toHome) {
linkTitle ??= wikiInfo.nameShort;
@@ -1058,7 +1057,7 @@ writePage.html = (
let partContent;
- if (typeof cur.html === "string") {
+ if (typeof cur.html === 'string') {
if (!cur.html) {
logWarn`Empty HTML in nav link ${JSON.stringify(cur)}`;
console.trace();
@@ -1066,11 +1065,11 @@ writePage.html = (
partContent = cur.html;
} else {
const attributes = {
- class: (cur.toCurrentPage || i === links.length - 1) && "current",
+ class: (cur.toCurrentPage || i === links.length - 1) && 'current',
href: cur.toCurrentPage
- ? ""
+ ? ''
: cur.toHome
- ? to("localized.home")
+ ? to('localized.home')
: cur.path
? to(...cur.path)
: cur.href
@@ -1087,12 +1086,12 @@ writePage.html = (
)})`
);
}
- partContent = html.tag("a", attributes, linkTitle);
+ partContent = html.tag('a', attributes, linkTitle);
}
const part = html.tag(
- "span",
- { class: cur.divider === false && "no-divider" },
+ 'span',
+ {class: cur.divider === false && 'no-divider'},
partContent
);
@@ -1100,35 +1099,35 @@ writePage.html = (
}
const navHTML = html.tag(
- "nav",
+ 'nav',
{
[html.onlyIfContent]: true,
- id: "header",
+ id: 'header',
class: [
...nav.classes,
- links.length && "nav-has-main-links",
- nav.content && "nav-has-content",
- nav.bottomRowContent && "nav-has-bottom-row",
+ links.length && 'nav-has-main-links',
+ nav.content && 'nav-has-content',
+ nav.bottomRowContent && 'nav-has-bottom-row',
],
},
[
links.length &&
html.tag(
- "div",
- { class: ["nav-main-links", ...nav.linkContainerClasses] },
+ 'div',
+ {class: ['nav-main-links', ...nav.linkContainerClasses]},
navLinkParts
),
- nav.content && html.tag("div", { class: "nav-content" }, nav.content),
+ nav.content && html.tag('div', {class: 'nav-content'}, nav.content),
nav.bottomRowContent &&
- html.tag("div", { class: "nav-bottom-row" }, nav.bottomRowContent),
+ html.tag('div', {class: 'nav-bottom-row'}, nav.bottomRowContent),
]
);
const secondaryNavHTML = html.tag(
- "nav",
+ 'nav',
{
[html.onlyIfContent]: true,
- id: "secondary-nav",
+ id: 'secondary-nav',
class: secondaryNav.classes,
},
[secondaryNav.content]
@@ -1144,12 +1143,12 @@ writePage.html = (
banner.position &&
bannerSrc &&
html.tag(
- "div",
+ 'div',
{
- id: "banner",
+ id: 'banner',
class: banner.classes,
},
- html.tag("img", {
+ html.tag('img', {
src: bannerSrc,
alt: banner.alt,
width: banner.dimensions[0] || 1100,
@@ -1159,18 +1158,18 @@ writePage.html = (
const layoutHTML = [
navHTML,
- banner.position === "top" && bannerHTML,
+ banner.position === 'top' && bannerHTML,
secondaryNavHTML,
html.tag(
- "div",
- { class: ["layout-columns", !collapseSidebars && "vertical-when-thin"] },
+ 'div',
+ {class: ['layout-columns', !collapseSidebars && 'vertical-when-thin']},
[sidebarLeftHTML, mainHTML, sidebarRightHTML]
),
- banner.position === "bottom" && bannerHTML,
+ banner.position === 'bottom' && bannerHTML,
footerHTML,
]
.filter(Boolean)
- .join("\n");
+ .join('\n');
const infoCardHTML = fixWS`
${language.$("redirectPage.title", { title })}
- ${language.$('redirectPage.title', {title})}
+