From bad238355e19c4fef5e5f3b41df88fa9b1b84aaa Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Tue, 21 Nov 2023 07:31:45 -0400 Subject: content, client, css: generateAdditionalNamesBox --- .../dependencies/generateAdditionalNamesBox.js | 48 ++++++++++++++++++++++ src/content/dependencies/generatePageLayout.js | 38 +++++++++-------- src/content/dependencies/generateTrackInfoPage.js | 8 ++++ 3 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 src/content/dependencies/generateAdditionalNamesBox.js (limited to 'src/content') diff --git a/src/content/dependencies/generateAdditionalNamesBox.js b/src/content/dependencies/generateAdditionalNamesBox.js new file mode 100644 index 00000000..f7fa3b00 --- /dev/null +++ b/src/content/dependencies/generateAdditionalNamesBox.js @@ -0,0 +1,48 @@ +import {stitchArrays} from '#sugar'; + +export default { + contentDependencies: ['transformContent'], + extraDependencies: ['html', 'language'], + + relations: (relation, additionalNames) => ({ + names: + additionalNames.map(({name}) => + relation('transformContent', name)), + + annotations: + additionalNames.map(({annotation}) => + (annotation + ? relation('transformContent', annotation) + : null)), + }), + + generate: (relations, {html, language}) => { + const names = + relations.names.map(name => + html.tag('span', {class: 'additional-name'}, + name.slot('mode', 'inline'))); + + const annotations = + relations.annotations.map(annotation => + (annotation + ? html.tag('span', {class: 'annotation'}, + language.$('misc.additionalNames.item.annotation', { + annotation: + annotation.slot('mode', 'inline'), + })) + : null)); + + return html.tag('div', {id: 'additional-names-box'}, [ + html.tag('p', + language.$('misc.additionalNames.title')), + + html.tag('ul', + stitchArrays({name: names, annotation: annotations}) + .map(({name, annotation}) => + html.tag('li', + (annotation + ? language.$('misc.additionalNames.item.withAnnotation', {name, annotation}) + : language.$('misc.additionalNames.item', {name}))))), + ]); + }, +}; diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js index 95551f3e..7dee8cc3 100644 --- a/src/content/dependencies/generatePageLayout.js +++ b/src/content/dependencies/generatePageLayout.js @@ -108,6 +108,8 @@ export default { title: {type: 'html'}, showWikiNameInTitle: {type: 'boolean', default: true}, + additionalNames: {type: 'html'}, + cover: {type: 'html'}, socialEmbed: {type: 'html'}, @@ -222,22 +224,25 @@ export default { const colors = getColors(slots.color ?? data.wikiColor); const hasSocialEmbed = !html.isBlank(slots.socialEmbed); - let titleHTML = null; - - if (!html.isBlank(slots.title)) { - switch (slots.headingMode) { - case 'sticky': - titleHTML = - relations.stickyHeadingContainer.slots({ - title: slots.title, - cover: slots.cover, - }); - break; - case 'static': - titleHTML = html.tag('h1', slots.title); - break; - } - } + const titleContentsHTML = + (html.isBlank(slots.title) + ? null + : html.isBlank(slots.additionalNames) + ? language.sanitize(slots.title) + : html.tag('a', { + href: '#additional-names-box', + title: language.$('misc.additionalNames.tooltip').toString(), + }, language.sanitize(slots.title))); + + const titleHTML = + (html.isBlank(slots.title) + ? null + : slots.headingMode === 'sticky' + ? relations.stickyHeadingContainer.slots({ + title: titleContentsHTML, + cover: slots.cover, + }) + : html.tag('h1', titleContentsHTML)); let footerContent = slots.footerContent; @@ -254,6 +259,7 @@ export default { titleHTML, slots.cover, + slots.additionalNames, html.tag('div', { diff --git a/src/content/dependencies/generateTrackInfoPage.js b/src/content/dependencies/generateTrackInfoPage.js index 93334948..180e5c29 100644 --- a/src/content/dependencies/generateTrackInfoPage.js +++ b/src/content/dependencies/generateTrackInfoPage.js @@ -6,6 +6,7 @@ import getChronologyRelations from '../util/getChronologyRelations.js'; export default { contentDependencies: [ 'generateAdditionalFilesShortcut', + 'generateAdditionalNamesBox', 'generateAlbumAdditionalFilesList', 'generateAlbumNavAccent', 'generateAlbumSidebar', @@ -106,6 +107,11 @@ export default { list: relation('generateAlbumAdditionalFilesList', album, additionalFiles), }); + if (!empty(track.additionalNames)) { + relations.additionalNamesBox = + relation('generateAdditionalNamesBox', track.additionalNames); + } + if (track.hasUniqueCoverArt || album.hasCoverArt) { relations.cover = relation('generateTrackCoverArtwork', track); @@ -300,6 +306,8 @@ export default { title: language.$('trackPage.title', {track: data.name}), headingMode: 'sticky', + additionalNames: relations.additionalNamesBox ?? null, + color: data.color, styleRules: [relations.albumStyleRules], -- cgit 1.3.0-6-gf8a5 From c11edada828dc734cce6988e5819630a73326085 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 21 Jul 2023 20:06:32 -0300 Subject: content, test: linkContribution: tooltip icons --- .../generateReleaseInfoContributionsLine.js | 1 + src/content/dependencies/linkContribution.js | 79 ++++++++++++++++------ 2 files changed, 61 insertions(+), 19 deletions(-) (limited to 'src/content') diff --git a/src/content/dependencies/generateReleaseInfoContributionsLine.js b/src/content/dependencies/generateReleaseInfoContributionsLine.js index 1fa8dcca..2e6c4709 100644 --- a/src/content/dependencies/generateReleaseInfoContributionsLine.js +++ b/src/content/dependencies/generateReleaseInfoContributionsLine.js @@ -35,6 +35,7 @@ export default { link.slots({ showContribution: slots.showContribution, showIcons: slots.showIcons, + iconMode: 'tooltip', }))), }); }, diff --git a/src/content/dependencies/linkContribution.js b/src/content/dependencies/linkContribution.js index 8e42f247..5bc398de 100644 --- a/src/content/dependencies/linkContribution.js +++ b/src/content/dependencies/linkContribution.js @@ -20,7 +20,6 @@ export default { if (!empty(contribution.who.urls)) { relations.artistIcons = contribution.who.urls - .slice(0, 4) .map(url => relation('linkExternalAsIcon', url)); } @@ -37,37 +36,79 @@ export default { showContribution: {type: 'boolean', default: false}, showIcons: {type: 'boolean', default: false}, preventWrapping: {type: 'boolean', default: true}, + + iconMode: { + validate: v => v.is('inline', 'tooltip'), + default: 'inline' + }, }, generate(data, relations, slots, {html, language}) { - const hasContributionPart = !!(slots.showContribution && data.what); - const hasExternalPart = !!(slots.showIcons && relations.artistIcons); - - const externalLinks = hasExternalPart && - html.tag('span', - {[html.noEdgeWhitespace]: true, class: 'icons'}, - language.formatUnitList(relations.artistIcons)); + const hasContribution = !!(slots.showContribution && data.what); + const hasExternalIcons = !!(slots.showIcons && relations.artistIcons); const parts = ['misc.artistLink']; const options = {artist: relations.artistLink}; - if (hasContributionPart) { + if (hasContribution) { parts.push('withContribution'); options.contrib = data.what; } - if (hasExternalPart) { + if (hasExternalIcons && slots.iconMode === 'inline') { parts.push('withExternalLinks'); - options.links = externalLinks; + options.links = + html.tag('span', + { + [html.noEdgeWhitespace]: true, + class: ['icons', 'icons-inline'], + }, + language.formatUnitList( + relations.artistIcons + .slice(0, 4))); } - const content = language.formatString(parts.join('.'), options); + let content = language.formatString(parts.join('.'), options); - return ( - (parts.length > 1 && slots.preventWrapping - ? html.tag('span', - {[html.noEdgeWhitespace]: true, class: 'nowrap'}, - content) - : content)); - }, + if (hasExternalIcons && slots.iconMode === 'tooltip') { + content = [ + content, + html.tag('span', + { + [html.noEdgeWhitespace]: true, + class: ['icons', 'icons-tooltip'], + inert: true, + }, + html.tag('span', + { + [html.noEdgeWhitespace]: true, + [html.joinChildren]: '', + class: 'icons-tooltip-content', + }, + relations.artistIcons)), + ]; + } + + if (hasContribution || hasExternalIcons) { + content = + html.tag('span', { + [html.noEdgeWhitespace]: true, + [html.joinChildren]: '', + + class: [ + 'contribution', + + hasExternalIcons && + slots.iconMode === 'tooltip' && + 'has-tooltip', + + parts.length > 1 && + slots.preventWrapping && + 'nowrap', + ], + }, content); + } + + return content; + } }; -- cgit 1.3.0-6-gf8a5 From a1d50400b858e40471bc1bb78408d69d39907c5f Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Tue, 14 Nov 2023 20:05:48 -0400 Subject: content: generateContributionList: use tooltip style contrib icons --- src/content/dependencies/generateContributionList.js | 1 + 1 file changed, 1 insertion(+) (limited to 'src/content') diff --git a/src/content/dependencies/generateContributionList.js b/src/content/dependencies/generateContributionList.js index 731cfba5..6401e65e 100644 --- a/src/content/dependencies/generateContributionList.js +++ b/src/content/dependencies/generateContributionList.js @@ -16,5 +16,6 @@ export default { showIcons: true, showContribution: true, preventWrapping: false, + iconMode: 'tooltip', })))), }; -- cgit 1.3.0-6-gf8a5 From 0202375db8ccd03d98ed6c2ffbb800b67c026639 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 23 Nov 2023 09:16:23 -0400 Subject: content, css: vertical tooltips + basic external parsing --- src/content/dependencies/linkContribution.js | 14 +- src/content/dependencies/linkExternalAsIcon.js | 265 +++++++++++++++++++++---- 2 files changed, 235 insertions(+), 44 deletions(-) (limited to 'src/content') diff --git a/src/content/dependencies/linkContribution.js b/src/content/dependencies/linkContribution.js index 5bc398de..ef61c766 100644 --- a/src/content/dependencies/linkContribution.js +++ b/src/content/dependencies/linkContribution.js @@ -1,15 +1,8 @@ import {empty} from '#sugar'; export default { - contentDependencies: [ - 'linkArtist', - 'linkExternalAsIcon', - ], - - extraDependencies: [ - 'html', - 'language', - ], + contentDependencies: ['linkArtist', 'linkExternalAsIcon'], + extraDependencies: ['html', 'language'], relations(relation, contribution) { const relations = {}; @@ -85,7 +78,8 @@ export default { [html.joinChildren]: '', class: 'icons-tooltip-content', }, - relations.artistIcons)), + relations.artistIcons + .map(icon => icon.slot('withText', true)))), ]; } diff --git a/src/content/dependencies/linkExternalAsIcon.js b/src/content/dependencies/linkExternalAsIcon.js index cd168992..d3ed9122 100644 --- a/src/content/dependencies/linkExternalAsIcon.js +++ b/src/content/dependencies/linkExternalAsIcon.js @@ -1,6 +1,202 @@ -// TODO: Define these as extra dependencies and pass them somewhere -const BANDCAMP_DOMAINS = ['bc.s3m.us', 'music.solatrux.com']; -const MASTODON_DOMAINS = ['types.pl']; +import {stitchArrays} from '#sugar'; + +const fallbackDescriptor = { + icon: 'globe', + string: 'external', + + normal: 'domain', + compact: 'domain', +}; + +// TODO: Define all this stuff in data! +const externalSpec = [ + { + matchDomain: 'bandcamp.com', + + icon: 'bandcamp', + string: 'bandcamp', + + compact: 'handle', + + handle: {domain: /^[^.]*/}, + }, + + { + matchDomains: ['bc.s3m.us', 'music.solatrux.com'], + + icon: 'bandcamp', + string: 'bandcamp', + + normal: 'domain', + compact: 'domain', + }, + + { + matchDomains: ['types.pl'], + + icon: 'mastodon', + string: 'mastodon', + + compact: 'domain', + }, + + { + matchDomains: ['youtube.com', 'youtu.be'], + + icon: 'youtube', + string: 'youtube', + + compact: 'handle', + + handle: { + pathname: /^(@.*?)\/?$/, + }, + }, + + { + matchDomain: 'soundcloud.com', + + icon: 'soundcloud', + string: 'soundcloud', + + compact: 'handle', + + handle: /[^/]*\/?$/, + }, + + { + matchDomain: 'tumblr.com', + + icon: 'tumblr', + string: 'tumblr', + + compact: 'handle', + + handle: {domain: /^[^.]*/}, + }, + + { + matchDomain: 'twitter.com', + + icon: 'twitter', + string: 'twitter', + + compact: 'handle', + + handle: { + prefix: '@', + pathname: /^@?.*\/?$/, + }, + }, + + { + matchDomain: 'deviantart.com', + + icon: 'deviantart', + string: 'deviantart', + }, + + { + matchDomain: 'instagram.com', + + icon: 'instagram', + string: 'instagram', + }, + + { + matchDomain: 'newgrounds.com', + + icon: 'newgrounds', + string: 'newgrounds', + }, +]; + +function determineLinkText(url, descriptor, {language}) { + const prefix = 'misc.external'; + + const { + hostname: domain, + pathname, + } = new URL(url); + + let normal = null; + let compact = null; + + const place = language.$(prefix, descriptor.string); + + if (descriptor.normal === 'domain') { + normal = language.$(prefix, 'withDomain', {place, domain}); + } + + if (descriptor.compact === 'domain') { + compact = domain.replace(/^www\./, ''); + } + + let handle = null; + + if (descriptor.handle) { + let regexen = []; + let tests = []; + + let handlePrefix = ''; + + if (descriptor.handle instanceof RegExp) { + regexen.push(descriptor.handle); + tests.push(url); + } else { + for (const [key, value] of Object.entries(descriptor.handle)) { + switch (key) { + case 'prefix': + handlePrefix = value; + continue; + + case 'url': + tests.push(url); + break; + + case 'domain': + case 'hostname': + tests.push(domain); + break; + + case 'path': + case 'pathname': + tests.push(pathname.slice(1)); + break; + + default: + tests.push(''); + break; + } + + regexen.push(value); + } + } + + for (const {regex, test} of stitchArrays({ + regex: regexen, + test: tests, + })) { + const match = test.match(regex); + if (match) { + handle = handlePrefix + (match[1] ?? match[0]); + break; + } + } + } + + if (descriptor.compact === 'handle') { + compact = handle; + } + + if (normal === 'handle' && handle) { + normal = language.$(prefix, 'withHandle', {place, handle}); + } + + normal ??= language.$(prefix, descriptor.string); + + return {normal, compact}; +} export default { extraDependencies: ['html', 'language', 'to'], @@ -9,38 +205,39 @@ export default { 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})]); + slots: { + withText: {type: 'boolean'}, + }, + + generate(data, slots, {html, language, to}) { + const {hostname: domain} = new URL(data.url); + + const descriptor = + externalSpec.find(({matchDomain, matchDomains}) => { + const compare = d => domain.includes(d); + if (matchDomain && compare(matchDomain)) return true; + if (matchDomains && matchDomains.some(compare)) return true; + return false; + }) ?? fallbackDescriptor; + + const {normal: normalText, compact: compactText} = + determineLinkText(data.url, descriptor, {language}); return html.tag('a', - {href: data.url, class: 'icon'}, - html.tag('svg', [ - html.tag('title', msg), - html.tag('use', { - href: to('shared.staticIcon', id), - }), - ])); + {href: data.url, class: ['icon', slots.withText && 'has-text']}, + [ + html.tag('svg', [ + !slots.withText && + html.tag('title', normalText), + + html.tag('use', { + href: to('shared.staticIcon', descriptor.icon), + }), + ]), + + slots.withText && + html.tag('span', {class: 'icon-text'}, + compactText ?? normalText), + ]); }, }; -- cgit 1.3.0-6-gf8a5 From 8f17782a5f2adbafd031b269195879eb7f79e05f Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 23 Nov 2023 11:16:48 -0400 Subject: data, content: extract external link parsing into nicer interface --- src/content/dependencies/linkExternalAsIcon.js | 223 +------------------------ 1 file changed, 7 insertions(+), 216 deletions(-) (limited to 'src/content') diff --git a/src/content/dependencies/linkExternalAsIcon.js b/src/content/dependencies/linkExternalAsIcon.js index d3ed9122..58bd896d 100644 --- a/src/content/dependencies/linkExternalAsIcon.js +++ b/src/content/dependencies/linkExternalAsIcon.js @@ -1,237 +1,28 @@ -import {stitchArrays} from '#sugar'; - -const fallbackDescriptor = { - icon: 'globe', - string: 'external', - - normal: 'domain', - compact: 'domain', -}; - -// TODO: Define all this stuff in data! -const externalSpec = [ - { - matchDomain: 'bandcamp.com', - - icon: 'bandcamp', - string: 'bandcamp', - - compact: 'handle', - - handle: {domain: /^[^.]*/}, - }, - - { - matchDomains: ['bc.s3m.us', 'music.solatrux.com'], - - icon: 'bandcamp', - string: 'bandcamp', - - normal: 'domain', - compact: 'domain', - }, - - { - matchDomains: ['types.pl'], - - icon: 'mastodon', - string: 'mastodon', - - compact: 'domain', - }, - - { - matchDomains: ['youtube.com', 'youtu.be'], - - icon: 'youtube', - string: 'youtube', - - compact: 'handle', - - handle: { - pathname: /^(@.*?)\/?$/, - }, - }, - - { - matchDomain: 'soundcloud.com', - - icon: 'soundcloud', - string: 'soundcloud', - - compact: 'handle', - - handle: /[^/]*\/?$/, - }, - - { - matchDomain: 'tumblr.com', - - icon: 'tumblr', - string: 'tumblr', - - compact: 'handle', - - handle: {domain: /^[^.]*/}, - }, - - { - matchDomain: 'twitter.com', - - icon: 'twitter', - string: 'twitter', - - compact: 'handle', - - handle: { - prefix: '@', - pathname: /^@?.*\/?$/, - }, - }, - - { - matchDomain: 'deviantart.com', - - icon: 'deviantart', - string: 'deviantart', - }, - - { - matchDomain: 'instagram.com', - - icon: 'instagram', - string: 'instagram', - }, - - { - matchDomain: 'newgrounds.com', - - icon: 'newgrounds', - string: 'newgrounds', - }, -]; - -function determineLinkText(url, descriptor, {language}) { - const prefix = 'misc.external'; - - const { - hostname: domain, - pathname, - } = new URL(url); - - let normal = null; - let compact = null; - - const place = language.$(prefix, descriptor.string); - - if (descriptor.normal === 'domain') { - normal = language.$(prefix, 'withDomain', {place, domain}); - } - - if (descriptor.compact === 'domain') { - compact = domain.replace(/^www\./, ''); - } - - let handle = null; - - if (descriptor.handle) { - let regexen = []; - let tests = []; - - let handlePrefix = ''; - - if (descriptor.handle instanceof RegExp) { - regexen.push(descriptor.handle); - tests.push(url); - } else { - for (const [key, value] of Object.entries(descriptor.handle)) { - switch (key) { - case 'prefix': - handlePrefix = value; - continue; - - case 'url': - tests.push(url); - break; - - case 'domain': - case 'hostname': - tests.push(domain); - break; - - case 'path': - case 'pathname': - tests.push(pathname.slice(1)); - break; - - default: - tests.push(''); - break; - } - - regexen.push(value); - } - } - - for (const {regex, test} of stitchArrays({ - regex: regexen, - test: tests, - })) { - const match = test.match(regex); - if (match) { - handle = handlePrefix + (match[1] ?? match[0]); - break; - } - } - } - - if (descriptor.compact === 'handle') { - compact = handle; - } - - if (normal === 'handle' && handle) { - normal = language.$(prefix, 'withHandle', {place, handle}); - } - - normal ??= language.$(prefix, descriptor.string); - - return {normal, compact}; -} - export default { extraDependencies: ['html', 'language', 'to'], - data(url) { - return {url}; - }, + data: (url) => ({url}), slots: { withText: {type: 'boolean'}, }, generate(data, slots, {html, language, to}) { - const {hostname: domain} = new URL(data.url); - - const descriptor = - externalSpec.find(({matchDomain, matchDomains}) => { - const compare = d => domain.includes(d); - if (matchDomain && compare(matchDomain)) return true; - if (matchDomains && matchDomains.some(compare)) return true; - return false; - }) ?? fallbackDescriptor; + const {url} = data; - const {normal: normalText, compact: compactText} = - determineLinkText(data.url, descriptor, {language}); + const normalText = language.formatExternalLink(url, {style: 'normal'}); + const compactText = language.formatExternalLink(url, {style: 'compact'}); + const iconId = language.formatExternalLink(url, {style: 'icon-id'}); return html.tag('a', - {href: data.url, class: ['icon', slots.withText && 'has-text']}, + {href: url, class: ['icon', slots.withText && 'has-text']}, [ html.tag('svg', [ !slots.withText && html.tag('title', normalText), html.tag('use', { - href: to('shared.staticIcon', descriptor.icon), + href: to('shared.staticIcon', iconId), }), ]), -- cgit 1.3.0-6-gf8a5 From c5e02f9d314118a534fd0e942d87e74864674498 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 23 Nov 2023 17:42:49 -0400 Subject: content: *mostly* port linkExternal to language.formatExternalLink --- src/content/dependencies/linkExternal.js | 64 ++++---------------------------- 1 file changed, 8 insertions(+), 56 deletions(-) (limited to 'src/content') diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js index 5de612e2..7f090084 100644 --- a/src/content/dependencies/linkExternal.js +++ b/src/content/dependencies/linkExternal.js @@ -1,7 +1,3 @@ -// TODO: Define these as extra dependencies and pass them somewhere -const BANDCAMP_DOMAINS = ['bc.s3m.us', 'music.solatrux.com']; -const MASTODON_DOMAINS = ['types.pl']; - export default { extraDependencies: ['html', 'language', 'wikiData'], @@ -27,6 +23,13 @@ export default { }, generate(data, slots, {html, language}) { + return ( + html.tag('a', + {href: data.url, class: 'nowrap'}, + language.formatExternalLink(data.url, {style: 'platform'}))); + }, + + /* let isLocal; let domain; let pathname; @@ -49,25 +52,6 @@ export default { isLocal = true; } - const link = html.tag('a', - { - href: data.url, - class: 'nowrap', - }, - - // truly unhinged indentation here - isLocal - ? language.$('misc.external.local') - - : domain.includes('bandcamp.com') - ? language.$('misc.external.bandcamp') - - : BANDCAMP_DOMAINS.includes(domain) - ? language.$('misc.external.bandcamp.domain', {domain}) - - : MASTODON_DOMAINS.includes(domain) - ? language.$('misc.external.mastodon.domain', {domain}) - : domain.includes('youtu') ? slots.mode === 'album' ? data.url.includes('list=') @@ -75,38 +59,6 @@ export default { : language.$('misc.external.youtube.fullAlbum') : language.$('misc.external.youtube') - : domain.includes('soundcloud') - ? language.$('misc.external.soundcloud') - - : domain.includes('tumblr.com') - ? language.$('misc.external.tumblr') - - : domain.includes('twitter.com') - ? language.$('misc.external.twitter') - - : domain.includes('deviantart.com') - ? language.$('misc.external.deviantart') - - : domain.includes('wikipedia.org') - ? language.$('misc.external.wikipedia') - - : domain.includes('poetryfoundation.org') - ? language.$('misc.external.poetryFoundation') - - : domain.includes('instagram.com') - ? language.$('misc.external.instagram') - - : domain.includes('patreon.com') - ? language.$('misc.external.patreon') - - : domain.includes('spotify.com') - ? language.$('misc.external.spotify') - - : domain.includes('newgrounds.com') - ? language.$('misc.external.newgrounds') - - : domain); - switch (slots.mode) { case 'flash': { const wrap = content => @@ -136,5 +88,5 @@ export default { default: return link; } - } + */ }; -- cgit 1.3.0-6-gf8a5 From 0ee5269cd196cd14f06aac6c586e7104159eac74 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 23 Nov 2023 17:47:18 -0400 Subject: content: implement "local" links much more rudimentarily --- src/content/dependencies/linkExternal.js | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'src/content') diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js index 7f090084..1b81efcc 100644 --- a/src/content/dependencies/linkExternal.js +++ b/src/content/dependencies/linkExternal.js @@ -30,28 +30,6 @@ export default { }, /* - let isLocal; - let domain; - let pathname; - - try { - const url = new URL(data.url); - domain = url.hostname; - pathname = url.pathname; - } catch (error) { - // No support for relative local URLs yet, sorry! (I.e, local URLs must - // be absolute relative to the domain name in order to work.) - isLocal = true; - domain = null; - pathname = null; - } - - // isLocal also applies for URLs which match the 'Canonical Base' under - // wiki-info.yaml, if present. - if (data.canonicalDomain && domain === data.canonicalDomain) { - isLocal = true; - } - : domain.includes('youtu') ? slots.mode === 'album' ? data.url.includes('list=') -- cgit 1.3.0-6-gf8a5 From 8c69ef2b14c4719fa0cd0c7daca27c613167b7ca Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 23 Nov 2023 18:52:04 -0400 Subject: content: contextual external links --- .../dependencies/generateAlbumReleaseInfo.js | 2 +- .../dependencies/generateAlbumSidebarGroupBox.js | 5 ++++- src/content/dependencies/generateArtistInfoPage.js | 5 ++++- src/content/dependencies/generateFlashInfoPage.js | 2 +- src/content/dependencies/generateGroupInfoPage.js | 5 ++++- .../dependencies/generateTrackReleaseInfo.js | 5 ++++- src/content/dependencies/linkContribution.js | 5 +++-- src/content/dependencies/linkExternal.js | 14 +++++++++++--- src/content/dependencies/linkExternalAsIcon.js | 21 ++++++++++++++++----- src/content/dependencies/linkExternalFlash.js | 4 ++++ 10 files changed, 52 insertions(+), 16 deletions(-) (limited to 'src/content') diff --git a/src/content/dependencies/generateAlbumReleaseInfo.js b/src/content/dependencies/generateAlbumReleaseInfo.js index d6405283..4b819091 100644 --- a/src/content/dependencies/generateAlbumReleaseInfo.js +++ b/src/content/dependencies/generateAlbumReleaseInfo.js @@ -94,7 +94,7 @@ export default { links: language.formatDisjunctionList( relations.externalLinks - .map(link => link.slot('mode', 'album'))), + .map(link => link.slot('context', 'album'))), })), ]); }, diff --git a/src/content/dependencies/generateAlbumSidebarGroupBox.js b/src/content/dependencies/generateAlbumSidebarGroupBox.js index 331ddaba..f3705450 100644 --- a/src/content/dependencies/generateAlbumSidebarGroupBox.js +++ b/src/content/dependencies/generateAlbumSidebarGroupBox.js @@ -66,7 +66,10 @@ export default { !empty(relations.externalLinks) && html.tag('p', language.$('releaseInfo.visitOn', { - links: language.formatDisjunctionList(relations.externalLinks), + links: + language.formatDisjunctionList( + relations.externalLinks + .map(link => link.slot('context', 'group'))), })), slots.mode === 'album' && diff --git a/src/content/dependencies/generateArtistInfoPage.js b/src/content/dependencies/generateArtistInfoPage.js index 03bc0af5..ac9209a7 100644 --- a/src/content/dependencies/generateArtistInfoPage.js +++ b/src/content/dependencies/generateArtistInfoPage.js @@ -161,7 +161,10 @@ export default { sec.visit && html.tag('p', language.$('releaseInfo.visitOn', { - links: language.formatDisjunctionList(sec.visit.externalLinks), + links: + language.formatDisjunctionList( + sec.visit.externalLinks + .map(link => link.slot('context', 'artist'))), })), sec.artworks?.artistGalleryLink && diff --git a/src/content/dependencies/generateFlashInfoPage.js b/src/content/dependencies/generateFlashInfoPage.js index 09c6b37c..c60f9696 100644 --- a/src/content/dependencies/generateFlashInfoPage.js +++ b/src/content/dependencies/generateFlashInfoPage.js @@ -133,7 +133,7 @@ export default { links: language.formatDisjunctionList( relations.externalLinks - .map(link => link.slot('mode', 'flash'))), + .map(link => link.slot('context', 'flash'))), })), sec.featuredTracks && [ diff --git a/src/content/dependencies/generateGroupInfoPage.js b/src/content/dependencies/generateGroupInfoPage.js index 0583755e..05df33fb 100644 --- a/src/content/dependencies/generateGroupInfoPage.js +++ b/src/content/dependencies/generateGroupInfoPage.js @@ -107,7 +107,10 @@ export default { sec.info.visitLinks && html.tag('p', language.$('releaseInfo.visitOn', { - links: language.formatDisjunctionList(sec.info.visitLinks), + links: + language.formatDisjunctionList( + sec.info.visitLinks + .map(link => link.slot('context', 'group'))), })), html.tag('blockquote', diff --git a/src/content/dependencies/generateTrackReleaseInfo.js b/src/content/dependencies/generateTrackReleaseInfo.js index 9a7478ca..c347dbce 100644 --- a/src/content/dependencies/generateTrackReleaseInfo.js +++ b/src/content/dependencies/generateTrackReleaseInfo.js @@ -77,7 +77,10 @@ export default { html.tag('p', (relations.externalLinks ? language.$('releaseInfo.listenOn', { - links: language.formatDisjunctionList(relations.externalLinks), + links: + language.formatDisjunctionList( + relations.externalLinks + .map(link => link.slot('context', 'track'))), }) : language.$('releaseInfo.listenOn.noLinks', { name: html.tag('i', data.name), diff --git a/src/content/dependencies/linkContribution.js b/src/content/dependencies/linkContribution.js index ef61c766..790afa4f 100644 --- a/src/content/dependencies/linkContribution.js +++ b/src/content/dependencies/linkContribution.js @@ -58,7 +58,8 @@ export default { }, language.formatUnitList( relations.artistIcons - .slice(0, 4))); + .slice(0, 4) + .map(icon => icon.slot('context', 'artist')))); } let content = language.formatString(parts.join('.'), options); @@ -79,7 +80,7 @@ export default { class: 'icons-tooltip-content', }, relations.artistIcons - .map(icon => icon.slot('withText', true)))), + .map(icon => icon.slots({context: 'artist', withText: true})))), ]; } diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js index 1b81efcc..e51ea89e 100644 --- a/src/content/dependencies/linkExternal.js +++ b/src/content/dependencies/linkExternal.js @@ -1,3 +1,5 @@ +import {isExternalLinkContext} from '#external-links'; + export default { extraDependencies: ['html', 'language', 'wikiData'], @@ -16,8 +18,11 @@ export default { }, slots: { - mode: { - validate: v => v.is('generic', 'album', 'flash'), + context: { + // This awkward syntax is because the slot descriptor validator can't + // differentiate between a function that returns a validator (the usual + // syntax) and a function that is itself a validator. + validate: () => isExternalLinkContext, default: 'generic', }, }, @@ -26,7 +31,10 @@ export default { return ( html.tag('a', {href: data.url, class: 'nowrap'}, - language.formatExternalLink(data.url, {style: 'platform'}))); + language.formatExternalLink(data.url, { + style: 'platform', + context: slots.context, + }))); }, /* diff --git a/src/content/dependencies/linkExternalAsIcon.js b/src/content/dependencies/linkExternalAsIcon.js index 58bd896d..357c835c 100644 --- a/src/content/dependencies/linkExternalAsIcon.js +++ b/src/content/dependencies/linkExternalAsIcon.js @@ -1,21 +1,32 @@ +import {isExternalLinkContext} from '#external-links'; + export default { extraDependencies: ['html', 'language', 'to'], data: (url) => ({url}), slots: { + context: { + // This awkward syntax is because the slot descriptor validator can't + // differentiate between a function that returns a validator (the usual + // syntax) and a function that is itself a validator. + validate: () => isExternalLinkContext, + default: 'generic', + }, + withText: {type: 'boolean'}, }, generate(data, slots, {html, language, to}) { - const {url} = data; + const format = style => + language.formatExternalLink(data.url, {style, context: slots.context}); - const normalText = language.formatExternalLink(url, {style: 'normal'}); - const compactText = language.formatExternalLink(url, {style: 'compact'}); - const iconId = language.formatExternalLink(url, {style: 'icon-id'}); + const normalText = format('normal'); + const compactText = format('compact'); + const iconId = format('icon-id'); return html.tag('a', - {href: url, class: ['icon', slots.withText && 'has-text']}, + {href: data.url, class: ['icon', slots.withText && 'has-text']}, [ html.tag('svg', [ !slots.withText && diff --git a/src/content/dependencies/linkExternalFlash.js b/src/content/dependencies/linkExternalFlash.js index 65158ff8..e2147da1 100644 --- a/src/content/dependencies/linkExternalFlash.js +++ b/src/content/dependencies/linkExternalFlash.js @@ -1,6 +1,8 @@ // Note: This function is seriously hard-coded for HSMusic, with custom // presentation of links to Homestuck flashes hosted various places. +// This also appears to be dead code, apart from a single snapshot test?? + export default { contentDependencies: ['linkExternal'], extraDependencies: ['html', 'language'], @@ -22,6 +24,8 @@ export default { const {link} = relations; const {url, page} = data; + link.setSlot('context', 'flash'); + return html.tag('span', {class: 'nowrap'}, -- cgit 1.3.0-6-gf8a5 From face11b98dbaa866055718b7731f61a21fcf9088 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 23 Nov 2023 21:01:27 -0400 Subject: content: linkExternal: make direct wrapper for formatExternalLink --- src/content/dependencies/linkExternal.js | 78 ++++++-------------------------- 1 file changed, 15 insertions(+), 63 deletions(-) (limited to 'src/content') diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js index e51ea89e..4941e48a 100644 --- a/src/content/dependencies/linkExternal.js +++ b/src/content/dependencies/linkExternal.js @@ -1,78 +1,30 @@ -import {isExternalLinkContext} from '#external-links'; +import {isExternalLinkContext, isExternalLinkStyle} from '#external-links'; export default { extraDependencies: ['html', 'language', 'wikiData'], - sprawl: ({wikiInfo}) => ({wikiInfo}), - - data(sprawl, url) { - const data = {url}; - - const {canonicalBase} = sprawl.wikiInfo; - if (canonicalBase) { - const {hostname: canonicalDomain} = new URL(canonicalBase); - Object.assign(data, {canonicalDomain}); - } - - return data; - }, + data: (url) => ({url}), slots: { - context: { + style: { // This awkward syntax is because the slot descriptor validator can't // differentiate between a function that returns a validator (the usual // syntax) and a function that is itself a validator. + validate: () => isExternalLinkStyle, + default: 'platform', + }, + + context: { validate: () => isExternalLinkContext, default: 'generic', }, }, - generate(data, slots, {html, language}) { - return ( - html.tag('a', - {href: data.url, class: 'nowrap'}, - language.formatExternalLink(data.url, { - style: 'platform', - context: slots.context, - }))); - }, - - /* - : domain.includes('youtu') - ? slots.mode === 'album' - ? data.url.includes('list=') - ? language.$('misc.external.youtube.playlist') - : language.$('misc.external.youtube.fullAlbum') - : language.$('misc.external.youtube') - - switch (slots.mode) { - case 'flash': { - const wrap = content => - html.tag('span', {class: 'nowrap'}, content); - - if (domain.includes('homestuck.com')) { - const match = pathname.match(/\/story\/(.*)\/?/); - if (match) { - if (isNaN(Number(match[1]))) { - return wrap(language.$('misc.external.flash.homestuck.secret', {link})); - } else { - return wrap(language.$('misc.external.flash.homestuck.page', { - link, - page: match[1], - })); - } - } - } else if (domain.includes('bgreco.net')) { - return wrap(language.$('misc.external.flash.bgreco', {link})); - } else if (domain.includes('youtu')) { - return wrap(language.$('misc.external.flash.youtube', {link})); - } - - return link; - } - - default: - return link; - } - */ + generate: (data, slots, {html, language}) => + html.tag('a', + {href: data.url, class: 'nowrap'}, + language.formatExternalLink(data.url, { + style: slots.style, + context: slots.context, + })), }; -- cgit 1.3.0-6-gf8a5 From 370aab15cb6ba60c95b33f7c4a1ed9b6daf51d98 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 23 Nov 2023 21:02:07 -0400 Subject: content: generateFlashInfoPage: use 'normal' style links --- src/content/dependencies/generateFlashInfoPage.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/content') diff --git a/src/content/dependencies/generateFlashInfoPage.js b/src/content/dependencies/generateFlashInfoPage.js index c60f9696..919996a2 100644 --- a/src/content/dependencies/generateFlashInfoPage.js +++ b/src/content/dependencies/generateFlashInfoPage.js @@ -132,8 +132,11 @@ export default { language.$('releaseInfo.playOn', { links: language.formatDisjunctionList( - relations.externalLinks - .map(link => link.slot('context', 'flash'))), + relations.externalLinks.map(link => + link.slots({ + context: 'flash', + style: 'normal', + }))), })), sec.featuredTracks && [ -- cgit 1.3.0-6-gf8a5 From db786c25a9fafc4cac37b108b4ea433019741c07 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 23 Nov 2023 21:33:15 -0400 Subject: content, external-links: minor fixes --- src/content/dependencies/generateAlbumReleaseInfo.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/content') diff --git a/src/content/dependencies/generateAlbumReleaseInfo.js b/src/content/dependencies/generateAlbumReleaseInfo.js index 4b819091..dd5baab9 100644 --- a/src/content/dependencies/generateAlbumReleaseInfo.js +++ b/src/content/dependencies/generateAlbumReleaseInfo.js @@ -94,7 +94,11 @@ export default { links: language.formatDisjunctionList( relations.externalLinks - .map(link => link.slot('context', 'album'))), + .map(link => + link.slots({ + context: 'album', + style: 'normal', + }))), })), ]); }, -- cgit 1.3.0-6-gf8a5 From 3898fbe9380c7a8bc745eff548b112ad2e9c605b Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 24 Nov 2023 13:40:52 -0400 Subject: content, test: remove unused linkExternalFlash function --- src/content/dependencies/linkExternalFlash.js | 45 --------------------------- 1 file changed, 45 deletions(-) delete mode 100644 src/content/dependencies/linkExternalFlash.js (limited to 'src/content') diff --git a/src/content/dependencies/linkExternalFlash.js b/src/content/dependencies/linkExternalFlash.js deleted file mode 100644 index e2147da1..00000000 --- a/src/content/dependencies/linkExternalFlash.js +++ /dev/null @@ -1,45 +0,0 @@ -// Note: This function is seriously hard-coded for HSMusic, with custom -// presentation of links to Homestuck flashes hosted various places. - -// This also appears to be dead code, apart from a single snapshot test?? - -export default { - contentDependencies: ['linkExternal'], - extraDependencies: ['html', 'language'], - - relations(relation, url) { - return { - link: relation('linkExternal', url), - }; - }, - - data(url, flash) { - return { - url, - page: flash.page, - }; - }, - - generate(data, relations, {html, language}) { - const {link} = relations; - const {url, page} = data; - - link.setSlot('context', 'flash'); - - return html.tag('span', - {class: 'nowrap'}, - - url.includes('homestuck.com') - ? isNaN(Number(page)) - ? language.$('misc.external.flash.homestuck.secret', {link}) - : language.$('misc.external.flash.homestuck.page', {link, page}) - - : url.includes('bgreco.net') - ? language.$('misc.external.flash.bgreco', {link}) - - : url.includes('youtu') - ? language.$('misc.external.flash.youtube', {link}) - - : link); - }, -}; -- cgit 1.3.0-6-gf8a5 From 45fba07af02d4f161cce494b683918bc76453b82 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 24 Nov 2023 14:39:06 -0400 Subject: content: linkExternal: default to 'normal' style --- src/content/dependencies/generateArtistInfoPage.js | 7 +++++-- src/content/dependencies/generateFlashInfoPage.js | 7 ++----- src/content/dependencies/linkExternal.js | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/content') diff --git a/src/content/dependencies/generateArtistInfoPage.js b/src/content/dependencies/generateArtistInfoPage.js index ac9209a7..be9f9b86 100644 --- a/src/content/dependencies/generateArtistInfoPage.js +++ b/src/content/dependencies/generateArtistInfoPage.js @@ -163,8 +163,11 @@ export default { language.$('releaseInfo.visitOn', { links: language.formatDisjunctionList( - sec.visit.externalLinks - .map(link => link.slot('context', 'artist'))), + sec.visit.externalLinks.map(link => + link.slots({ + context: 'artist', + mode: 'platform', + }))), })), sec.artworks?.artistGalleryLink && diff --git a/src/content/dependencies/generateFlashInfoPage.js b/src/content/dependencies/generateFlashInfoPage.js index 919996a2..c60f9696 100644 --- a/src/content/dependencies/generateFlashInfoPage.js +++ b/src/content/dependencies/generateFlashInfoPage.js @@ -132,11 +132,8 @@ export default { language.$('releaseInfo.playOn', { links: language.formatDisjunctionList( - relations.externalLinks.map(link => - link.slots({ - context: 'flash', - style: 'normal', - }))), + relations.externalLinks + .map(link => link.slot('context', 'flash'))), })), sec.featuredTracks && [ diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js index 4941e48a..0a079614 100644 --- a/src/content/dependencies/linkExternal.js +++ b/src/content/dependencies/linkExternal.js @@ -11,7 +11,7 @@ export default { // differentiate between a function that returns a validator (the usual // syntax) and a function that is itself a validator. validate: () => isExternalLinkStyle, - default: 'platform', + default: 'normal', }, context: { -- cgit 1.3.0-6-gf8a5