feat: set target="_blank" on every anchor element in text blocks; closes #179
This commit is contained in:
parent
9e7dad6b8d
commit
ce6af994ea
|
@ -53,6 +53,7 @@ const EpisodeChannelContainer = styled.div`
|
|||
align-items: center;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 32px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} {
|
||||
margin-top: 24px;
|
||||
|
|
|
@ -66,6 +66,8 @@ const SearchBox = (props: SearchBoxProps) => {
|
|||
showModeSwitch = true,
|
||||
} = props
|
||||
|
||||
const hydrated = useHydrated()
|
||||
|
||||
const [filterTags, setFilterTags] = useQueryParam(
|
||||
'topic',
|
||||
withDefault(ArrayParam, []),
|
||||
|
@ -96,14 +98,9 @@ const SearchBox = (props: SearchBoxProps) => {
|
|||
const [whereResultsStick, setWhereResultsStick] = useState(0)
|
||||
const [showDetails, setShowDetails] = useState(false)
|
||||
const [detailsTop, setDetailsTop] = useState(0)
|
||||
const [mounted, setMounted] = useState(false)
|
||||
const [focused, setFocused] = useState(false)
|
||||
const [showClear, setShowClear] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true)
|
||||
return () => setMounted(false)
|
||||
}, [])
|
||||
const handleViewChange = async (n: string) => {
|
||||
setView(n)
|
||||
onViewChange(n)
|
||||
|
@ -185,8 +182,6 @@ const SearchBox = (props: SearchBoxProps) => {
|
|||
// if (query !== queryInput) setQuery(queryInput)
|
||||
// }, [focused, query, queryInput])
|
||||
|
||||
const hydrated = useHydrated()
|
||||
|
||||
return (
|
||||
<Container
|
||||
className={enlargeQuery ? 'active' : ''}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { LPE } from '../../../types/lpe.types'
|
||||
import { setAttributeOnHTML } from '../../../utils/html.utils'
|
||||
import { convertToIframe } from '../../../utils/string.utils'
|
||||
import { UnbodyResGoogleDocData, UnbodyResTextBlockData } from '../unbody.types'
|
||||
import { UnbodyDataTypeConfig } from './types'
|
||||
|
@ -16,7 +17,7 @@ export const TextBlockDataType: UnbodyDataTypeConfig<
|
|||
isMatch: (helpers, data, original, root) => data.__typename === 'TextBlock',
|
||||
|
||||
transform: (helpers, data, original, root) => {
|
||||
const { text = '', html = '' } = data
|
||||
let { text = '', html = '' } = data
|
||||
const labels: LPE.Post.ContentBlockLabel[] = []
|
||||
let embed: LPE.Post.TextBlockEmbed | null = null
|
||||
|
||||
|
@ -67,10 +68,23 @@ export const TextBlockDataType: UnbodyDataTypeConfig<
|
|||
}
|
||||
}
|
||||
|
||||
// set target="_blank" on anchor elements
|
||||
{
|
||||
const matches = Array.from(
|
||||
html.matchAll(/<a[^>]*href="http[^>]*"[^>]*>/gi),
|
||||
)
|
||||
|
||||
for (const match of matches) {
|
||||
const [anchorHTML] = match
|
||||
const newAnchorHTML = setAttributeOnHTML(anchorHTML, 'target', '_blank')
|
||||
html = html.replace(anchorHTML, newAnchorHTML)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id: data?._additional?.id || `${data.order}`,
|
||||
type: 'text',
|
||||
html: data.html,
|
||||
html,
|
||||
text: data.text || '',
|
||||
classNames: data.classNames,
|
||||
footnotes: data.footnotesObj,
|
||||
|
|
|
@ -38,6 +38,30 @@ export function extractAttributeFromHTML(
|
|||
)
|
||||
}
|
||||
|
||||
export const setAttributeOnHTML = (
|
||||
html: string,
|
||||
attribute: string,
|
||||
value: string,
|
||||
) => {
|
||||
let result = html.trim()
|
||||
const tagName = html.match(/^<([\w])+/)?.[0]?.slice(1)!
|
||||
const current = extractAttributeFromHTML(html, attribute)
|
||||
|
||||
if (current) {
|
||||
const currentAttribute = `${attribute}="${current}"`
|
||||
const index = html.indexOf(currentAttribute)
|
||||
|
||||
result =
|
||||
result.slice(0, index) + result.slice(index + currentAttribute.length + 1)
|
||||
}
|
||||
|
||||
result = `<${tagName} ${attribute}="${value}"${result.slice(
|
||||
tagName.length + 1,
|
||||
)}`
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export const isAuthorsParagraph = (html: string) => {
|
||||
const regex = /<a\s+[^>]*href="mailto:([^"]+)"[^>]*>([^<]+)<\/a>/g
|
||||
const matches = html.match(regex)
|
||||
|
|
Loading…
Reference in New Issue