diff options
-rw-r--r-- | src/content/dependencies/generateContributionLinks.js | 23 | ||||
-rw-r--r-- | src/content/dependencies/generateIconForURL.js | 51 | ||||
-rw-r--r-- | src/misc-templates.js | 46 | ||||
-rw-r--r-- | test/unit/content/dependencies/generateContributionLinks.js | 93 |
4 files changed, 103 insertions, 110 deletions
diff --git a/src/content/dependencies/generateContributionLinks.js b/src/content/dependencies/generateContributionLinks.js index a79c8234..18bc409d 100644 --- a/src/content/dependencies/generateContributionLinks.js +++ b/src/content/dependencies/generateContributionLinks.js @@ -3,37 +3,40 @@ import {empty} from '../../util/sugar.js'; export default { contentDependencies: [ 'linkArtist', + 'generateIconForURL', ], extraDependencies: [ 'html', - 'iconifyURL', 'language', ], - relations(relation, contributions) { + relations(relation, contributions, {showIcons = false} = {}) { const relations = {}; relations.artistLinks = contributions.map(({who}) => relation('linkArtist', who)); + if (showIcons) { + relations.artistIcons = + contributions.map(({who}) => + who.urls.map(url => + relation('generateIconForURL', url))); + } + return relations; }, data(contributions, { showContribution = false, showIcons = false, - }) { + } = {}) { const data = {}; - data.showContribution = showContribution; - data.showIcons = showIcons; - data.contributionData = contributions.map(({who, what}) => ({ hasContributionPart: !!(showContribution && what), hasExternalPart: !!(showIcons && !empty(who.urls)), - artistUrls: who.urls, contribution: showContribution && what, })); @@ -42,23 +45,21 @@ export default { generate(data, relations, { html, - iconifyURL, language, }) { return language.formatConjunctionList( data.contributionData.map(({ hasContributionPart, hasExternalPart, - artistUrls, contribution, }, index) => { const artistLink = relations.artistLinks[index]; + const artistIcons = relations.artistIcons?.[index]; const externalLinks = hasExternalPart && html.tag('span', {[html.noEdgeWhitespace]: true, class: 'icons'}, - language.formatUnitList( - artistUrls.map(url => iconifyURL(url, {language})))); + language.formatUnitList(artistIcons)); return ( (hasContributionPart diff --git a/src/content/dependencies/generateIconForURL.js b/src/content/dependencies/generateIconForURL.js new file mode 100644 index 00000000..4473ccbf --- /dev/null +++ b/src/content/dependencies/generateIconForURL.js @@ -0,0 +1,51 @@ +const BANDCAMP_DOMAINS = [ + 'bc.s3m.us', + 'music.solatrux.com', +]; + +const MASTODON_DOMAINS = [ + 'types.pl', +]; + +export default { + extraDependencies: ['html', 'language', 'to'], + + data(url) { + return {url}; + }, + + generate(data, {html, language, to}) { + const domain = new URL(data.url).hostname; + const [id, msg] = ( + domain.includes('bandcamp.com') + ? ['bandcamp', language.$('misc.external.bandcamp')] + : BANDCAMP_DOMAINS.includes(domain) + ? ['bandcamp', language.$('misc.external.bandcamp.domain', {domain})] + : MASTODON_DOMAINS.includes(domain) + ? ['mastodon', language.$('misc.external.mastodon.domain', {domain})] + : domain.includes('youtu') + ? ['youtube', language.$('misc.external.youtube')] + : domain.includes('soundcloud') + ? ['soundcloud', language.$('misc.external.soundcloud')] + : domain.includes('tumblr.com') + ? ['tumblr', language.$('misc.external.tumblr')] + : domain.includes('twitter.com') + ? ['twitter', language.$('misc.external.twitter')] + : domain.includes('deviantart.com') + ? ['deviantart', language.$('misc.external.deviantart')] + : domain.includes('instagram.com') + ? ['instagram', language.$('misc.external.bandcamp')] + : domain.includes('newgrounds.com') + ? ['newgrounds', language.$('misc.external.newgrounds')] + : ['globe', language.$('misc.external.domain', {domain})]); + + return html.tag('a', + {href: data.url, class: 'icon'}, + html.tag('svg', [ + html.tag('title', msg), + html.tag('use', { + href: to('shared.staticFile', `icons.svg#icon-${id}`), + }), + ])); + }, +}; diff --git a/src/misc-templates.js b/src/misc-templates.js index 11a95c7c..39e62ddf 100644 --- a/src/misc-templates.js +++ b/src/misc-templates.js @@ -18,10 +18,6 @@ import { sortChronologically, } from './util/wiki-data.js'; -const BANDCAMP_DOMAINS = ['bc.s3m.us', 'music.solatrux.com']; - -const MASTODON_DOMAINS = ['types.pl']; - // "Additional Files" listing function unbound_generateAdditionalFilesShortcut(additionalFiles, { @@ -337,48 +333,6 @@ function unbound_fancifyFlashURL(url, flash, { : link); } -function unbound_iconifyURL(url, { - html, - language, - to, -}) { - const domain = new URL(url).hostname; - const [id, msg] = ( - domain.includes('bandcamp.com') - ? ['bandcamp', language.$('misc.external.bandcamp')] - : BANDCAMP_DOMAINS.includes(domain) - ? ['bandcamp', language.$('misc.external.bandcamp.domain', {domain})] - : MASTODON_DOMAINS.includes(domain) - ? ['mastodon', language.$('misc.external.mastodon.domain', {domain})] - : domain.includes('youtu') - ? ['youtube', language.$('misc.external.youtube')] - : domain.includes('soundcloud') - ? ['soundcloud', language.$('misc.external.soundcloud')] - : domain.includes('tumblr.com') - ? ['tumblr', language.$('misc.external.tumblr')] - : domain.includes('twitter.com') - ? ['twitter', language.$('misc.external.twitter')] - : domain.includes('deviantart.com') - ? ['deviantart', language.$('misc.external.deviantart')] - : domain.includes('instagram.com') - ? ['instagram', language.$('misc.external.bandcamp')] - : domain.includes('newgrounds.com') - ? ['newgrounds', language.$('misc.external.newgrounds')] - : ['globe', language.$('misc.external.domain', {domain})]); - - return html.tag('a', - { - href: url, - class: 'icon', - }, - html.tag('svg', [ - html.tag('title', msg), - html.tag('use', { - href: to('shared.staticFile', `icons.svg#icon-${id}`), - }), - ])); -} - // Grids function unbound_getGridHTML({ diff --git a/test/unit/content/dependencies/generateContributionLinks.js b/test/unit/content/dependencies/generateContributionLinks.js index a0bb64ec..5ed8f782 100644 --- a/test/unit/content/dependencies/generateContributionLinks.js +++ b/test/unit/content/dependencies/generateContributionLinks.js @@ -2,28 +2,28 @@ import t from 'tap'; import {testContentFunctions} from '../../../lib/content-function.js'; t.test('generateContributionLinks (unit)', async t => { - await testContentFunctions(t, 'generateContributionLinks (unit 1)', async (t, evaluate) => { - const artist1 = { - name: 'Clark Powell', - urls: ['https://soundcloud.com/plazmataz'], - }; - - const artist2 = { - name: 'Grounder & Scratch', - urls: [], - }; - - const artist3 = { - name: 'Toby Fox', - urls: ['https://tobyfox.bandcamp.com/', 'https://toby.fox/'], - }; - - const contributions = [ - {who: artist1, what: null}, - {who: artist2, what: 'Snooping'}, - {who: artist3, what: 'Arrangement'}, - ]; + const artist1 = { + name: 'Clark Powell', + urls: ['https://soundcloud.com/plazmataz'], + }; + + const artist2 = { + name: 'Grounder & Scratch', + urls: [], + }; + + const artist3 = { + name: 'Toby Fox', + urls: ['https://tobyfox.bandcamp.com/', 'https://toby.fox/'], + }; + + const contributions = [ + {who: artist1, what: null}, + {who: artist2, what: 'Snooping'}, + {who: artist3, what: 'Arrangement'}, + ]; + await testContentFunctions(t, 'generateContributionLinks (unit 1)', async (t, evaluate) => { const config = { showContribution: true, showIcons: true, @@ -44,46 +44,29 @@ t.test('generateContributionLinks (unit)', async t => { // This can be tweaked to return a specific (mocked) template // for each artist if we need to test for slots in the future. - generate: mock.function(() => 'artist link') + generate: mock.function('linkArtist.generate', () => 'artist link') .repeat(3), }, + + generateIconForURL: { + data: mock.function('generateIconForURL.data', () => ({})) + .args([artist1.urls[0]]).next() + .args([artist3.urls[0]]).next() + .args([artist3.urls[1]]), + + generate: mock.function('generateIconForURL.generate', () => 'icon') + .repeat(3), + } })), }); evaluate({ name: 'generateContributionLinks', args: [contributions, config], - extraDependencies: evaluate.mock(mock => ({ - iconifyURL: mock.function(() => 'icon') - .args([artist1.urls[0], undefined]).next() - .args([artist3.urls[0], undefined]).next() - .args([artist3.urls[1], undefined]), - })), }); }); await testContentFunctions(t, 'generateContributionLinks (unit 2)', async (t, evaluate) => { - const artist1 = { - name: 'Clark Powell', - urls: ['https://soundcloud.com/plazmataz'], - }; - - const artist2 = { - name: 'Grounder & Scratch', - urls: [], - }; - - const artist3 = { - name: 'Toby Fox', - urls: ['https://tobyfox.bandcamp.com/', 'https://toby.fox/'], - }; - - const contributions = [ - {who: artist1, what: null}, - {who: artist2, what: 'Snooping'}, - {who: artist3, what: 'Arrangement'}, - ]; - const config = { showContribution: false, showIcons: false, @@ -105,16 +88,20 @@ t.test('generateContributionLinks (unit)', async t => { generate: mock.function(() => 'artist link') .repeat(3), }, + + generateIconForURL: { + data: mock.function('generateIconForURL.data', () => ({})) + .neverCalled(), + + generate: mock.function('generateIconForURL.generate', () => 'icon') + .neverCalled(), + }, })), }); evaluate({ name: 'generateContributionLinks', args: [contributions, config], - extraDependencies: evaluate.mock(mock => ({ - iconifyURL: mock.function(() => 'icon') - .neverCalled(), - })), }); }); }); |