useHtmlLinks.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { useEventListener } from '@vueuse/core'
  3. import { useRouter } from 'vue-router'
  4. import { isStandalone } from '#shared/utils/pwa.ts'
  5. import { useBaseUrl } from './useBaseUrl.ts'
  6. const useHtmlLinks = (urlPrefix: '/desktop' | '/mobile') => {
  7. const { baseUrl } = useBaseUrl()
  8. const router = useRouter()
  9. const getRedirectRoute = (url: URL): string | undefined => {
  10. if (url.pathname.startsWith(urlPrefix)) {
  11. return url.href.slice(`${url.origin}${urlPrefix}`.length)
  12. }
  13. const route = router.resolve(`/${url.hash.slice(1)}${url.search}`)
  14. if (route.name !== 'Error') {
  15. return route.fullPath
  16. }
  17. }
  18. const openLink = (target: string, path: string) => {
  19. // keep links inside PWA inside the app
  20. if (!isStandalone() && target && target !== '_self') {
  21. window.open(`${urlPrefix}${path}`, target)
  22. } else {
  23. router.push(path)
  24. }
  25. }
  26. const handleLinkClick = (link: HTMLAnchorElement, event: Event) => {
  27. try {
  28. const url = new URL(link.href)
  29. if (
  30. url.origin === window.location.origin ||
  31. url.origin === baseUrl.value
  32. ) {
  33. const redirectRoute = getRedirectRoute(url)
  34. if (redirectRoute) {
  35. event.preventDefault()
  36. return openLink(link.target, redirectRoute)
  37. }
  38. }
  39. if (link.hasAttribute('external')) return
  40. if (!link.target) {
  41. event.preventDefault()
  42. window.open(link.href)
  43. }
  44. } catch {
  45. // skip
  46. }
  47. }
  48. // user links has fqdn in its href, but if it changes the link becomes invalid
  49. // to bypass that we replace the href with the correct one
  50. const patchUserMentionLinks = (link: HTMLAnchorElement) => {
  51. const userId = link.dataset.mentionUserId
  52. if (!userId) return
  53. link.href = `${baseUrl.value}${urlPrefix}/users/${userId}`
  54. }
  55. const setupLinksHandlers = (element: HTMLDivElement) => {
  56. element.querySelectorAll('a').forEach((link) => {
  57. if ('__handled' in link) return
  58. Object.defineProperty(link, '__handled', { value: true })
  59. patchUserMentionLinks(link)
  60. useEventListener(link, 'click', (event) => handleLinkClick(link, event))
  61. })
  62. }
  63. return {
  64. setupLinksHandlers,
  65. }
  66. }
  67. export { useHtmlLinks }