UNPKG

7 kBJavaScriptView Raw
1"use strict";var _interopRequireWildcard=require("@babel/runtime/helpers/interopRequireWildcard");exports.__esModule=true;exports.default=void 0;var _react=_interopRequireWildcard(require("react"));var _router=require("../next-server/lib/router/router");var _router2=require("./router");var _useIntersection=require("./use-intersection");const prefetched={};function prefetch(router,href,as,options){if(typeof window==='undefined'||!router)return;if(!(0,_router.isLocalURL)(href))return;// Prefetch the JSON page if asked (only in the client)
2// We need to handle a prefetch error here since we may be
3// loading with priority which can reject but we don't
4// want to force navigation since this is only a prefetch
5router.prefetch(href,as,options).catch(err=>{if(process.env.NODE_ENV!=='production'){// rethrow to show invalid URL errors
6throw err;}});const curLocale=options&&typeof options.locale!=='undefined'?options.locale:router&&router.locale;// Join on an invalid URI character
7prefetched[href+'%'+as+(curLocale?'%'+curLocale:'')]=true;}function isModifiedEvent(event){const{target}=event.currentTarget;return target&&target!=='_self'||event.metaKey||event.ctrlKey||event.shiftKey||event.altKey||// triggers resource download
8event.nativeEvent&&event.nativeEvent.which===2;}function linkClicked(e,router,href,as,replace,shallow,scroll,locale){const{nodeName}=e.currentTarget;if(nodeName==='A'&&(isModifiedEvent(e)||!(0,_router.isLocalURL)(href))){// ignore click for browser’s default behavior
9return;}e.preventDefault();// avoid scroll for urls with anchor refs
10if(scroll==null&&as.indexOf('#')>=0){scroll=false;}// replace state instead of push if prop is present
11router[replace?'replace':'push'](href,as,{shallow,locale,scroll});}function Link(props){if(process.env.NODE_ENV!=='production'){function createPropError(args){return new Error(`Failed prop type: The prop \`${args.key}\` expects a ${args.expected} in \`<Link>\`, but got \`${args.actual}\` instead.`+(typeof window!=='undefined'?"\nOpen your browser's console to view the Component stack trace.":''));}// TypeScript trick for type-guarding:
12const requiredPropsGuard={href:true};const requiredProps=Object.keys(requiredPropsGuard);requiredProps.forEach(key=>{if(key==='href'){if(props[key]==null||typeof props[key]!=='string'&&typeof props[key]!=='object'){throw createPropError({key,expected:'`string` or `object`',actual:props[key]===null?'null':typeof props[key]});}}else{// TypeScript trick for type-guarding:
13// eslint-disable-next-line @typescript-eslint/no-unused-vars
14const _=key;}});// TypeScript trick for type-guarding:
15const optionalPropsGuard={as:true,replace:true,scroll:true,shallow:true,passHref:true,prefetch:true,locale:true};const optionalProps=Object.keys(optionalPropsGuard);optionalProps.forEach(key=>{const valType=typeof props[key];if(key==='as'){if(props[key]&&valType!=='string'&&valType!=='object'){throw createPropError({key,expected:'`string` or `object`',actual:valType});}}else if(key==='locale'){if(props[key]&&valType!=='string'){throw createPropError({key,expected:'`string`',actual:valType});}}else if(key==='replace'||key==='scroll'||key==='shallow'||key==='passHref'||key==='prefetch'){if(props[key]!=null&&valType!=='boolean'){throw createPropError({key,expected:'`boolean`',actual:valType});}}else{// TypeScript trick for type-guarding:
16// eslint-disable-next-line @typescript-eslint/no-unused-vars
17const _=key;}});// This hook is in a conditional but that is ok because `process.env.NODE_ENV` never changes
18// eslint-disable-next-line react-hooks/rules-of-hooks
19const hasWarned=_react.default.useRef(false);if(props.prefetch&&!hasWarned.current){hasWarned.current=true;console.warn('Next.js auto-prefetches automatically based on viewport. The prefetch attribute is no longer needed. More: https://nextjs.org/docs/messages/prefetch-true-deprecated');}}const p=props.prefetch!==false;const router=(0,_router2.useRouter)();const{href,as}=_react.default.useMemo(()=>{const[resolvedHref,resolvedAs]=(0,_router.resolveHref)(router,props.href,true);return{href:resolvedHref,as:props.as?(0,_router.resolveHref)(router,props.as):resolvedAs||resolvedHref};},[router,props.href,props.as]);let{children,replace,shallow,scroll,locale}=props;// Deprecated. Warning shown by propType check. If the children provided is a string (<Link>example</Link>) we wrap it in an <a> tag
20if(typeof children==='string'){children=/*#__PURE__*/_react.default.createElement("a",null,children);}// This will return the first child, if multiple are provided it will throw an error
21let child;if(process.env.NODE_ENV==='development'){try{child=_react.Children.only(children);}catch(err){throw new Error(`Multiple children were passed to <Link> with \`href\` of \`${props.href}\` but only one child is supported https://nextjs.org/docs/messages/link-multiple-children`+(typeof window!=='undefined'?"\nOpen your browser's console to view the Component stack trace.":''));}}else{child=_react.Children.only(children);}const childRef=child&&typeof child==='object'&&child.ref;const[setIntersectionRef,isVisible]=(0,_useIntersection.useIntersection)({rootMargin:'200px'});const setRef=_react.default.useCallback(el=>{setIntersectionRef(el);if(childRef){if(typeof childRef==='function')childRef(el);else if(typeof childRef==='object'){childRef.current=el;}}},[childRef,setIntersectionRef]);(0,_react.useEffect)(()=>{const shouldPrefetch=isVisible&&p&&(0,_router.isLocalURL)(href);const curLocale=typeof locale!=='undefined'?locale:router&&router.locale;const isPrefetched=prefetched[href+'%'+as+(curLocale?'%'+curLocale:'')];if(shouldPrefetch&&!isPrefetched){prefetch(router,href,as,{locale:curLocale});}},[as,href,isVisible,locale,p,router]);const childProps={ref:setRef,onClick:e=>{if(child.props&&typeof child.props.onClick==='function'){child.props.onClick(e);}if(!e.defaultPrevented){linkClicked(e,router,href,as,replace,shallow,scroll,locale);}}};childProps.onMouseEnter=e=>{if(!(0,_router.isLocalURL)(href))return;if(child.props&&typeof child.props.onMouseEnter==='function'){child.props.onMouseEnter(e);}prefetch(router,href,as,{priority:true});};// If child is an <a> tag and doesn't have a href attribute, or if the 'passHref' property is
22// defined, we specify the current 'href', so that repetition is not needed by the user
23if(props.passHref||child.type==='a'&&!('href'in child.props)){const curLocale=typeof locale!=='undefined'?locale:router&&router.locale;// we only render domain locales if we are currently on a domain locale
24// so that locale links are still visitable in development/preview envs
25const localeDomain=router&&router.isLocaleDomain&&(0,_router.getDomainLocale)(as,curLocale,router&&router.locales,router&&router.domainLocales);childProps.href=localeDomain||(0,_router.addBasePath)((0,_router.addLocale)(as,curLocale,router&&router.defaultLocale));}return/*#__PURE__*/_react.default.cloneElement(child,childProps);}var _default=Link;exports.default=_default;
26//# sourceMappingURL=link.js.map
\No newline at end of file