react-aria
Version:
Spectrum UI components in React
1 lines • 11.3 kB
Source Map (JSON)
{"mappings":"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","sources":["packages/react-aria/src/utils/openLink.tsx"],"sourcesContent":["/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {focusWithoutScrolling} from './focusWithoutScrolling';\nimport {Href, LinkDOMProps, RouterOptions} from '@react-types/shared';\nimport {isFirefox, isIPad, isMac, isWebKit} from './platform';\nimport React, {\n createContext,\n DOMAttributes,\n JSX,\n MouseEvent as ReactMouseEvent,\n ReactNode,\n useContext,\n useMemo\n} from 'react';\n\ninterface Router {\n isNative: boolean;\n open: (\n target: Element,\n modifiers: Modifiers,\n href: Href,\n routerOptions: RouterOptions | undefined\n ) => void;\n useHref: (href: Href) => string;\n}\n\nconst RouterContext = createContext<Router>({\n isNative: true,\n open: openSyntheticLink,\n useHref: href => href\n});\n\ninterface RouterProviderProps {\n navigate: (path: Href, routerOptions: RouterOptions | undefined) => void;\n useHref?: (href: Href) => string;\n children: ReactNode;\n}\n\n/**\n * A RouterProvider accepts a `navigate` function from a framework or client side router,\n * and provides it to all nested React Aria links to enable client side navigation.\n */\nexport function RouterProvider(props: RouterProviderProps): JSX.Element {\n let {children, navigate, useHref} = props;\n\n let ctx = useMemo(\n () => ({\n isNative: false,\n open: (\n target: Element,\n modifiers: Modifiers,\n href: Href,\n routerOptions: RouterOptions | undefined\n ) => {\n getSyntheticLink(target, link => {\n if (shouldClientNavigate(link, modifiers)) {\n navigate(href, routerOptions);\n } else {\n openLink(link, modifiers);\n }\n });\n },\n useHref: useHref || (href => href)\n }),\n [navigate, useHref]\n );\n\n return <RouterContext.Provider value={ctx}>{children}</RouterContext.Provider>;\n}\n\nexport function useRouter(): Router {\n return useContext(RouterContext);\n}\n\ninterface Modifiers {\n metaKey?: boolean;\n ctrlKey?: boolean;\n altKey?: boolean;\n shiftKey?: boolean;\n}\n\nexport function shouldClientNavigate(link: HTMLAnchorElement, modifiers: Modifiers): boolean {\n // Use getAttribute here instead of link.target. Firefox will default link.target to \"_parent\" when inside an iframe.\n let target = link.getAttribute('target');\n return (\n (!target || target === '_self') &&\n link.origin === location.origin &&\n !link.hasAttribute('download') &&\n !modifiers.metaKey && // open in new tab (mac)\n !modifiers.ctrlKey && // open in new tab (windows)\n !modifiers.altKey && // download\n !modifiers.shiftKey\n );\n}\n\nexport function openLink(target: HTMLAnchorElement, modifiers: Modifiers, setOpening = true): void {\n let {metaKey, ctrlKey, altKey, shiftKey} = modifiers;\n\n // Firefox does not recognize keyboard events as a user action by default, and the popup blocker\n // will prevent links with target=\"_blank\" from opening. However, it does allow the event if the\n // Command/Control key is held, which opens the link in a background tab. This seems like the best we can do.\n // See https://bugzilla.mozilla.org/show_bug.cgi?id=257870 and https://bugzilla.mozilla.org/show_bug.cgi?id=746640.\n if (isFirefox() && window.event?.type?.startsWith('key') && target.target === '_blank') {\n if (isMac()) {\n metaKey = true;\n } else {\n ctrlKey = true;\n }\n }\n\n // WebKit does not support firing click events with modifier keys, but does support keyboard events.\n // https://github.com/WebKit/WebKit/blob/c03d0ac6e6db178f90923a0a63080b5ca210d25f/Source/WebCore/html/HTMLAnchorElement.cpp#L184\n let event =\n isWebKit() && isMac() && !isIPad() && process.env.NODE_ENV !== 'test'\n ? // @ts-ignore - keyIdentifier is a non-standard property, but it's what webkit expects\n new KeyboardEvent('keydown', {keyIdentifier: 'Enter', metaKey, ctrlKey, altKey, shiftKey})\n : new MouseEvent('click', {\n metaKey,\n ctrlKey,\n altKey,\n shiftKey,\n detail: 1,\n bubbles: true,\n cancelable: true\n });\n (openLink as any).isOpening = setOpening;\n focusWithoutScrolling(target);\n target.dispatchEvent(event);\n (openLink as any).isOpening = false;\n}\n// https://github.com/parcel-bundler/parcel/issues/8724\n(openLink as any).isOpening = false;\n\nfunction getSyntheticLink(target: Element, open: (link: HTMLAnchorElement) => void) {\n if (target instanceof HTMLAnchorElement) {\n open(target);\n } else if (target.hasAttribute('data-href')) {\n let link = document.createElement('a');\n link.href = target.getAttribute('data-href')!;\n if (target.hasAttribute('data-target')) {\n link.target = target.getAttribute('data-target')!;\n }\n if (target.hasAttribute('data-rel')) {\n link.rel = target.getAttribute('data-rel')!;\n }\n if (target.hasAttribute('data-download')) {\n link.download = target.getAttribute('data-download')!;\n }\n if (target.hasAttribute('data-ping')) {\n link.ping = target.getAttribute('data-ping')!;\n }\n if (target.hasAttribute('data-referrer-policy')) {\n link.referrerPolicy = target.getAttribute('data-referrer-policy')!;\n }\n target.appendChild(link);\n open(link);\n target.removeChild(link);\n }\n}\n\nfunction openSyntheticLink(target: Element, modifiers: Modifiers) {\n getSyntheticLink(target, link => openLink(link, modifiers));\n}\n\nexport function useSyntheticLinkProps(props: LinkDOMProps): DOMAttributes<HTMLElement> {\n let router = useRouter();\n const href = router.useHref(props.href ?? '');\n return {\n 'data-href': props.href ? href : undefined,\n 'data-target': props.target,\n 'data-rel': props.rel,\n 'data-download': props.download,\n 'data-ping': props.ping,\n 'data-referrer-policy': props.referrerPolicy\n } as DOMAttributes<HTMLElement>;\n}\n\n/** @deprecated - For backward compatibility. */\nexport function getSyntheticLinkProps(props: LinkDOMProps): DOMAttributes<HTMLElement> {\n return {\n 'data-href': props.href,\n 'data-target': props.target,\n 'data-rel': props.rel,\n 'data-download': props.download,\n 'data-ping': props.ping,\n 'data-referrer-policy': props.referrerPolicy\n } as DOMAttributes<HTMLElement>;\n}\n\nexport function useLinkProps(props?: LinkDOMProps): LinkDOMProps {\n let router = useRouter();\n const href = router.useHref(props?.href ?? '');\n let linkProps: LinkDOMProps = {};\n if (props) {\n for (let key of ['href', 'target', 'rel', 'download', 'ping', 'referrerPolicy']) {\n if (key in props) {\n linkProps[key] = key === 'href' ? href : props[key];\n }\n }\n }\n return linkProps;\n}\n\nexport function handleLinkClick(\n e: ReactMouseEvent,\n router: Router,\n href: Href | undefined,\n routerOptions: RouterOptions | undefined\n): void {\n // If a custom router is provided, prevent default and forward if this link should client navigate.\n if (\n !router.isNative &&\n e.currentTarget instanceof HTMLAnchorElement &&\n e.currentTarget.href &&\n // If props are applied to a router Link component, it may have already prevented default.\n !e.isDefaultPrevented() &&\n shouldClientNavigate(e.currentTarget, e) &&\n href\n ) {\n e.preventDefault();\n router.open(e.currentTarget, e, href, routerOptions);\n }\n}\n"],"names":[],"version":3,"file":"openLink.mjs.map"}