useHtmlLinks.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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 { useApplicationStore } from '#shared/stores/application.ts'
  5. import { isStandalone } from '#shared/utils/pwa.ts'
  6. const useHtmlLinks = (urlPrefix: '/desktop' | '/mobile') => {
  7. const router = useRouter()
  8. const application = useApplicationStore()
  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. const fqdnOrigin = `${window.location.protocol}//${application.config.fqdn}${
  28. window.location.port ? `:${window.location.port}` : ''
  29. }`
  30. try {
  31. const url = new URL(link.href)
  32. if (url.origin === window.location.origin || url.origin === fqdnOrigin) {
  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 = `${window.location.origin}${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 }