1
+
import { RX_ENCODED_COMMA, RX_ENCODE_REVERSE, RX_PLUS, RX_QUERY_START } from '../constants/regex'
1
2
import { isTag } from './dom'
2
3
import { isArray, isNull, isPlainObject, isString, isUndefined } from './inspect'
3
4
import { keys } from './object'
4
5
import { toString } from './string'
5
6
6
-
const ANCHOR_TAG = 'a'
7
-
8
-
// Precompile RegExp
9
-
const commaRE = /%2C/g
10
-
const encodeReserveRE = /[!'()*]/g
11
-
const plusRE = /\+/g
12
-
const queryStartRE = /^(\?|#|&)/
13
-
14
7
// Method to replace reserved chars
15
8
const encodeReserveReplacer = c => '%' + c.charCodeAt(0).toString(16)
16
9
@@ -19,8 +12,8 @@ const encodeReserveReplacer = c => '%' + c.charCodeAt(0).toString(16)
19
12
// - preserve commas
20
13
const encode = str =>
21
14
encodeURIComponent(toString(str))
22
-
.replace(encodeReserveRE, encodeReserveReplacer)
23
-
.replace(commaRE, ',')
15
+
.replace(RX_ENCODE_REVERSE, encodeReserveReplacer)
16
+
.replace(RX_ENCODED_COMMA, ',')
24
17
25
18
const decode = decodeURIComponent
26
19
@@ -65,14 +58,14 @@ export const parseQuery = query => {
65
58
const parsed = {}
66
59
query = toString(query)
67
60
.trim()
68
-
.replace(queryStartRE, '')
61
+
.replace(RX_QUERY_START, '')
69
62
70
63
if (!query) {
71
64
return parsed
72
65
}
73
66
74
67
query.split('&').forEach(param => {
75
-
const parts = param.replace(plusRE, ' ').split('=')
68
+
const parts = param.replace(RX_PLUS, ' ').split('=')
76
69
const key = decode(parts.shift())
77
70
const val = parts.length > 0 ? decode(parts.join('=')) : null
78
71
@@ -90,12 +83,12 @@ export const parseQuery = query => {
90
83
91
84
export const isLink = props => !!(props.href || props.to)
92
85
93
-
export const isRouterLink = tag => !isTag(tag, ANCHOR_TAG)
86
+
export const isRouterLink = tag => !!(tag && !isTag(tag, 'a'))
94
87
95
88
export 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'
99
92
}
100
93
101
94
// TODO:
@@ -109,45 +102,26 @@ export const computeTag = ({ to, disabled, routerComponentName } = {}, thisOrPar
109
102
return routerComponentName || (thisOrParent.$nuxt ? 'nuxt-link' : 'router-link')
110
103
}
111
104
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
131
107
108
+
export const computeHref = ({ href, to } = {}, fallback = '#', toFallback = '/') => {
132
109
// Return `href` when explicitly provided
133
110
if (href) {
134
111
return href
135
112
}
136
113
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
151
125
}
152
126
153
127
// If nothing is provided return the fallback
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4