1+ import { RX_ENCODED_COMMA , RX_ENCODE_REVERSE , RX_PLUS , RX_QUERY_START } from '../constants/regex'
12import { isTag } from './dom'
23import { isArray , isNull , isPlainObject , isString , isUndefined } from './inspect'
34import { keys } from './object'
45import { toString } from './string'
56
6- const ANCHOR_TAG = 'a'
7-
8- // Precompile RegExp
9- const commaRE = / % 2 C / g
10- const encodeReserveRE = / [ ! ' ( ) * ] / g
11- const plusRE = / \+ / g
12- const queryStartRE = / ^ ( \? | # | & ) /
13-
147// Method to replace reserved chars
158const encodeReserveReplacer = c => '%' + c . charCodeAt ( 0 ) . toString ( 16 )
169
@@ -19,8 +12,8 @@ const encodeReserveReplacer = c => '%' + c.charCodeAt(0).toString(16)
1912// - preserve commas
2013const encode = str =>
2114 encodeURIComponent ( toString ( str ) )
22- . replace ( encodeReserveRE , encodeReserveReplacer )
23- . replace ( commaRE , ',' )
15+ . replace ( RX_ENCODE_REVERSE , encodeReserveReplacer )
16+ . replace ( RX_ENCODED_COMMA , ',' )
2417
2518const decode = decodeURIComponent
2619
@@ -65,14 +58,14 @@ export const parseQuery = query => {
6558 const parsed = { }
6659 query = toString ( query )
6760 . trim ( )
68- . replace ( queryStartRE , '' )
61+ . replace ( RX_QUERY_START , '' )
6962
7063 if ( ! query ) {
7164 return parsed
7265 }
7366
7467 query . split ( '&' ) . forEach ( param => {
75- const parts = param . replace ( plusRE , ' ' ) . split ( '=' )
68+ const parts = param . replace ( RX_PLUS , ' ' ) . split ( '=' )
7669 const key = decode ( parts . shift ( ) )
7770 const val = parts . length > 0 ? decode ( parts . join ( '=' ) ) : null
7871
@@ -90,12 +83,12 @@ export const parseQuery = query => {
9083
9184export const isLink = props => ! ! ( props . href || props . to )
9285
93- export const isRouterLink = tag => ! isTag ( tag , ANCHOR_TAG )
86+ export const isRouterLink = tag => ! ! ( tag && ! isTag ( tag , 'a' ) )
9487
9588export const computeTag = ( { to, disabled, routerComponentName } = { } , thisOrParent ) => {
96- const hasRouter = thisOrParent . $router
97- if ( ! hasRouter || ( hasRouter && disabled ) || ( hasRouter && ! to ) ) {
98- return ANCHOR_TAG
89+ const hasRouter = ! ! thisOrParent . $router
90+ if ( ! hasRouter || ( hasRouter && ( disabled || ! to ) ) ) {
91+ return 'a'
9992 }
10093
10194 // TODO:
@@ -109,45 +102,26 @@ export const computeTag = ({ to, disabled, routerComponentName } = {}, thisOrPar
109102 return routerComponentName || ( thisOrParent . $nuxt ? 'nuxt-link' : 'router-link' )
110103}
111104
112- export const computeRel = ( { target, rel } = { } ) => {
113- if ( target === '_blank' && isNull ( rel ) ) {
114- return 'noopener'
115- }
116- return rel || null
117- }
118-
119- export const computeHref = (
120- { href, to } = { } ,
121- tag = ANCHOR_TAG ,
122- fallback = '#' ,
123- toFallback = '/'
124- ) => {
125- // We've already checked the $router in computeTag(), so isRouterLink() indicates a live router.
126- // When deferring to Vue Router's router-link, don't use the href attribute at all.
127- // We return null, and then remove href from the attributes passed to router-link
128- if ( isRouterLink ( tag ) ) {
129- return null
130- }
105+ export const computeRel = ( { target, rel } = { } ) =>
106+ target === '_blank' && isNull ( rel ) ? 'noopener' : rel || null
131107
108+ export const computeHref = ( { href, to } = { } , fallback = '#' , toFallback = '/' ) => {
132109 // Return `href` when explicitly provided
133110 if ( href ) {
134111 return href
135112 }
136113
137- // Reconstruct `href` when `to` used, but no router
138- if ( to ) {
139- // Fallback to `to` prop (if `to` is a string)
140- if ( isString ( to ) ) {
141- return to || toFallback
142- }
143- // Fallback to `to.path + to.query + to.hash` prop (if `to` is an object)
144- if ( isPlainObject ( to ) && ( to . path || to . query || to . hash ) ) {
145- const path = toString ( to . path )
146- const query = stringifyQueryObj ( to . query )
147- let hash = toString ( to . hash )
148- hash = ! hash || hash . charAt ( 0 ) === '#' ? hash : `#${ hash } `
149- return `${ path } ${ query } ${ hash } ` || toFallback
150- }
114+ // Fallback to `to` prop (if `to` is a string)
115+ if ( isString ( to ) ) {
116+ return to || toFallback
117+ }
118+ // Fallback to `to.path' + `to.query` + `to.hash` prop (if `to` is an object)
119+ if ( isPlainObject ( to ) && ( to . path || to . query || to . hash ) ) {
120+ const path = toString ( to . path )
121+ const query = stringifyQueryObj ( to . query )
122+ let hash = toString ( to . hash )
123+ hash = ! hash || hash . charAt ( 0 ) === '#' ? hash : `#${ hash } `
124+ return `${ path } ${ query } ${ hash } ` || toFallback
151125 }
152126
153127 // If nothing is provided return the fallback
0 commit comments