diff options
-rw-r--r-- | src/content/dependencies/linkExternal.js | 55 | ||||
-rw-r--r-- | src/content/dependencies/transformContent.js | 7 | ||||
-rw-r--r-- | src/static/site6.css | 8 | ||||
-rw-r--r-- | src/strings-default.yaml | 5 |
4 files changed, 62 insertions, 13 deletions
diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js index 7a97762c..188c1f0d 100644 --- a/src/content/dependencies/linkExternal.js +++ b/src/content/dependencies/linkExternal.js @@ -24,6 +24,11 @@ export default { default: 'generic', }, + indicateExternal: { + type: 'boolean', + default: false, + }, + tab: { validate: v => v.is('default', 'separate'), default: 'default', @@ -31,29 +36,55 @@ export default { }, generate(data, slots, {html, language}) { - const linkAttributes = html.attributes(); - let linkContent = slots.content; - - if (html.isBlank(linkContent)) { - linkContent = - language.formatExternalLink(data.url, { - style: slots.style, - context: slots.context, - }); - } + let formattedLink = + language.formatExternalLink(data.url, { + style: slots.style, + context: slots.context, + }); // Fall back to platform if nothing matched the desired style. - if (html.isBlank(linkContent) && slots.style !== 'platform') { - linkContent = + if (html.isBlank(formattedLink) && slots.style !== 'platform') { + formattedLink = language.formatExternalLink(data.url, { style: 'platform', context: slots.context, }); } + const linkAttributes = html.attributes(); + const linkContent = + (html.isBlank(slots.content) + ? formattedLink + : slots.content); + linkAttributes.set('class', 'external-link'); linkAttributes.set('href', data.url); + if (slots.indicateExternal) { + linkAttributes.add('class', 'indicate-external'); + + let titleText; + if (slots.tab === 'separate') { + if (html.isBlank(slots.content)) { + titleText = + language.$('misc.external.opensInNewTab.annotation'); + } else { + titleText = + language.$('misc.external.opensInNewTab', { + link: formattedLink, + annotation: + language.$('misc.external.opensInNewTab.annotation'), + }); + } + } else if (!html.isBlank(slots.content)) { + titleText = formattedLink; + } + + if (titleText) { + linkAttributes.set('title', titleText.toString()); + } + } + if (slots.tab === 'separate') { linkAttributes.set('target', '_blank'); } diff --git a/src/content/dependencies/transformContent.js b/src/content/dependencies/transformContent.js index d7b57ffd..e64aeb57 100644 --- a/src/content/dependencies/transformContent.js +++ b/src/content/dependencies/transformContent.js @@ -342,7 +342,12 @@ export default { const {label} = node.data; const externalLink = relations.externalLinks[externalLinkIndex++]; - externalLink.setSlot('content', label); + externalLink.setSlots({ + indicateExternal: true, + tab: 'separate', + style: 'platform', + content: label, + }); return {type: 'processed-external-link', data: externalLink}; } diff --git a/src/static/site6.css b/src/static/site6.css index 3d707f2c..83a066cd 100644 --- a/src/static/site6.css +++ b/src/static/site6.css @@ -472,6 +472,14 @@ a:not([href]):hover { white-space: nowrap; } +.external-link.indicate-external::after { + content: ' ➚'; +} + +.external-link.indicate-external:hover::after { + color: white; +} + .nav-main-links .nav-link.current > span.nav-link-content > a { font-weight: 800; } diff --git a/src/strings-default.yaml b/src/strings-default.yaml index 8cf3a734..46aeee86 100644 --- a/src/strings-default.yaml +++ b/src/strings-default.yaml @@ -504,6 +504,11 @@ misc: withHandle: "{PLATFORM} ({HANDLE})" + opensInNewTab: + _: "{LINK} ({ANNOTATION})" + annotation: + "opens in new tab" + appleMusic: "Apple Music" artstation: "ArtStation" bandcamp: "Bandcamp" |