diff options
Diffstat (limited to 'src/content/dependencies/linkContribution.js')
-rw-r--r-- | src/content/dependencies/linkContribution.js | 192 |
1 files changed, 66 insertions, 126 deletions
diff --git a/src/content/dependencies/linkContribution.js b/src/content/dependencies/linkContribution.js index 1a51c387..c658d461 100644 --- a/src/content/dependencies/linkContribution.js +++ b/src/content/dependencies/linkContribution.js @@ -1,145 +1,85 @@ -import {empty, stitchArrays} from '#sugar'; - export default { contentDependencies: [ + 'generateContributionTooltip', 'generateTextWithTooltip', - 'generateTooltip', 'linkArtist', - 'linkExternalAsIcon', ], extraDependencies: ['html', 'language'], - relations(relation, contribution) { - const relations = {}; + relations: (relation, contribution) => ({ + artistLink: + relation('linkArtist', contribution.artist), - relations.artistLink = - relation('linkArtist', contribution.artist); + textWithTooltip: + relation('generateTextWithTooltip'), - relations.textWithTooltip = - relation('generateTextWithTooltip'); + tooltip: + relation('generateContributionTooltip', contribution), + }), - relations.tooltip = - relation('generateTooltip'); + data: (contribution) => ({ + annotation: contribution.annotation, + urls: contribution.artist.urls, + }), - if (!empty(contribution.artist.urls)) { - relations.artistIcons = - contribution.artist.urls - .map(url => relation('linkExternalAsIcon', url)); - } + slots: { + showAnnotation: {type: 'boolean', default: false}, + showExternalLinks: {type: 'boolean', default: false}, + showChronology: {type: 'boolean', default: false}, - return relations; - }, + trimAnnotation: {type: 'boolean', default: false}, - data(contribution) { - return { - contribution: contribution.annotation, - urls: contribution.artist.urls, - }; - }, - - slots: { - showContribution: {type: 'boolean', default: false}, - showIcons: {type: 'boolean', default: false}, preventWrapping: {type: 'boolean', default: true}, + preventTooltip: {type: 'boolean', default: false}, - iconMode: { - validate: v => v.is('inline', 'tooltip'), - default: 'inline' - }, + chronologyKind: {type: 'string'}, }, - generate(data, relations, slots, {html, language}) { - const hasContribution = !!(slots.showContribution && data.contribution); - const hasExternalIcons = !!(slots.showIcons && relations.artistIcons); - - const parts = ['misc.artistLink']; - const options = {}; - - options.artist = - (hasExternalIcons && slots.iconMode === 'tooltip' - ? relations.textWithTooltip.slots({ - customInteractionCue: true, - - text: - relations.artistLink.slots({ - attributes: {class: 'text-with-tooltip-interaction-cue'}, - }), - - tooltip: - relations.tooltip.slots({ - attributes: - {class: ['icons', 'icons-tooltip']}, - - contentAttributes: - {[html.joinChildren]: ''}, - - content: - stitchArrays({ - icon: relations.artistIcons, - url: data.urls, - }).map(({icon, url}) => { - icon.setSlots({ - context: 'artist', - withText: true, - }); - - let platformText = - language.formatExternalLink(url, { - context: 'artist', - style: 'platform', - }); - - // This is a pretty ridiculous hack, but we currently - // don't have a way of telling formatExternalLink to *not* - // use the fallback string, which just formats the URL as - // its host/domain... so is technically detectable. - if (platformText.toString() === (new URL(url)).host) { - platformText = - language.$('misc.artistLink.noExternalLinkPlatformName'); - } - - const platformSpan = - html.tag('span', {class: 'icon-platform'}, - platformText); - - return [icon, platformSpan]; - }), - }), - }) - : relations.artistLink); - - if (hasContribution) { - parts.push('withContribution'); - options.contrib = data.contribution; - } - - if (hasExternalIcons && slots.iconMode === 'inline') { - parts.push('withExternalLinks'); - options.links = - html.tag('span', {class: ['icons', 'icons-inline']}, - {[html.noEdgeWhitespace]: true}, - language.formatUnitList( - relations.artistIcons - .slice(0, 4) - .map(icon => icon.slot('context', 'artist')))); - } - - const contributionPart = - language.formatString(...parts, options); - - if (!hasContribution && !hasExternalIcons) { - return contributionPart; - } - - return ( - html.tag('span', {class: 'contribution'}, - {[html.noEdgeWhitespace]: true}, - - parts.length > 1 && - slots.preventWrapping && - {class: 'nowrap'}, - - contributionPart)); - }, + generate: (data, relations, slots, {html, language}) => + html.tag('span', {class: 'contribution'}, + {[html.noEdgeWhitespace]: true}, + + slots.preventWrapping && + {class: 'nowrap'}, + + language.encapsulate('misc.artistLink', workingCapsule => { + const workingOptions = {}; + + // Filling slots early is necessary to actually give the tooltip + // content. Otherwise, the coming-up html.isBlank() always reports + // the tooltip as blank! + relations.tooltip.setSlots({ + showExternalLinks: slots.showExternalLinks, + showChronology: slots.showChronology, + chronologyKind: slots.chronologyKind, + }); + + workingOptions.artist = + (html.isBlank(relations.tooltip) || slots.preventTooltip + ? relations.artistLink + : relations.textWithTooltip.slots({ + customInteractionCue: true, + + text: + relations.artistLink.slots({ + attributes: {class: 'text-with-tooltip-interaction-cue'}, + }), + + tooltip: + relations.tooltip, + })); + + const annotation = + (slots.trimAnnotation + ? data.annotation?.replace(/^edits for wiki(: )?/, '') + : data.annotation); + + if (slots.showAnnotation && annotation) { + workingCapsule += '.withContribution'; + workingOptions.contrib = annotation; + } + + return language.formatString(workingCapsule, workingOptions); + })), }; |