From 44ed41a7f60849ea3b2f63430138b2642aab0824 Mon Sep 17 00:00:00 2001 From: Tyler Barna <57914086+tylerbarna@users.noreply.github.com> Date: Fri, 28 Jun 2024 12:35:17 -0500 Subject: [PATCH] Circulars: Open Automatically Formatted Hyperlinks in New Tab (#2383) --- .../nested-checkboxes/NestedCheckboxes.tsx | 4 ++-- .../AstroData.components.tsx | 3 +++ .../AstroDataContext.tsx | 18 +++++++++++++++--- .../rehypeAutolinkLiteral.ts | 6 +++++- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/app/components/nested-checkboxes/NestedCheckboxes.tsx b/app/components/nested-checkboxes/NestedCheckboxes.tsx index b44b307f3..14cef7644 100644 --- a/app/components/nested-checkboxes/NestedCheckboxes.tsx +++ b/app/components/nested-checkboxes/NestedCheckboxes.tsx @@ -47,7 +47,7 @@ function NestedCheckboxNode({ nodes.map((node) => node.defaultChecked || false) ) - const isExternal = link && isExternalLink(link) + const external = link && isExternalLink(link) function updateParent() { if (topLevelRef.current) { @@ -85,7 +85,7 @@ function NestedCheckboxNode({ className="usa-link" to={link} target="_blank" - rel={isExternal ? 'noopener' : undefined} + rel={external ? 'noopener' : undefined} onClick={(e) => { e.stopPropagation() }} diff --git a/app/routes/circulars.$circularId.($version)/AstroData.components.tsx b/app/routes/circulars.$circularId.($version)/AstroData.components.tsx index 5f499fb7c..146e62a97 100644 --- a/app/routes/circulars.$circularId.($version)/AstroData.components.tsx +++ b/app/routes/circulars.$circularId.($version)/AstroData.components.tsx @@ -54,6 +54,7 @@ export function Arxiv({ children, value }: JSX.IntrinsicElements['data']) { return ( fetchTooltipData('arxiv', value)} label={({ title, year, authors }) => ( <> @@ -74,6 +75,7 @@ export function Doi({ children, value }: JSX.IntrinsicElements['data']) { return ( fetchTooltipData('doi', value)} label={({ authors, pub, year, title }) => ( <> @@ -94,6 +96,7 @@ export function Tns({ children, value }: JSX.IntrinsicElements['data']) { return ( fetchTooltipData('tns', value)} label={({ ra, dec, names }) => ( <> diff --git a/app/routes/circulars.$circularId.($version)/AstroDataContext.tsx b/app/routes/circulars.$circularId.($version)/AstroDataContext.tsx index a143823d3..1db18a064 100644 --- a/app/routes/circulars.$circularId.($version)/AstroDataContext.tsx +++ b/app/routes/circulars.$circularId.($version)/AstroDataContext.tsx @@ -31,16 +31,26 @@ export const AstroDataContext = createContext({}) */ export const AstroDataLink = forwardRef( ( - { children, className, rel: origRel, ...props }: Omit, + { + children, + className, + rel: origRel, + external, + ...props + }: Omit & { external?: boolean }, ref: Ref ) => { const context = useContext(AstroDataContext) - const rel = [origRel, context.rel].filter(Boolean).join(' ') || undefined + const target = external ? '_blank' : context.target + const rel = + [origRel, context.rel, external ? 'external noopener' : ''] + .filter(Boolean) + .join(' ') || undefined return ( ({ }: Omit[0], 'ref'> & { fetch: () => T label: (resolved: Awaited) => ReactNode + external?: boolean }) { return ( ({ } asCustom={AstroDataLink} + external={Boolean(external)} > {children} diff --git a/app/routes/circulars.$circularId.($version)/rehypeAutolinkLiteral.ts b/app/routes/circulars.$circularId.($version)/rehypeAutolinkLiteral.ts index f253bdc88..dd0dabd38 100644 --- a/app/routes/circulars.$circularId.($version)/rehypeAutolinkLiteral.ts +++ b/app/routes/circulars.$circularId.($version)/rehypeAutolinkLiteral.ts @@ -20,7 +20,11 @@ const regexp = new RegExp( function autolinkLiteral(tree: Parameters[0]) { findAndReplace( tree, - [regexp, (href: string) => h('a', { rel: 'external', href }, href)], + [ + regexp, + (href: string) => + h('a', { rel: 'external noopener', href, target: '_blank' }, href), + ], { ignore: ['data'] } ) return tree