8000 fix(b-link): `href` handling with live router (closes #5927) by jacobmllr95 · Pull Request #5934 · bootstrap-vue/bootstrap-vue · GitHub
[go: up one dir, main page]

Skip to content

fix(b-link): href handling with live router (closes #5927) #5934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

8000
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/link/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export const BLink = /*#__PURE__*/ Vue.extend({
computedHref() {
// We don't pass `this` as the first arg as we need reactivity of the props
const { to, href } = this
return computeHref({ to, href })
return computeHref({ to, href }, this.computedTag)
},
computedProps() {
const { prefetch } = this
Expand Down
2 changes: 1 addition & 1 deletion src/components/pagination-nav/pagination-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export const BPaginationNav = /*#__PURE__*/ Vue.extend({
try {
// Convert the `to` to a HREF via a temporary `a` tag
link = document.createElement('a')
link.href = computeHref({ to }, '/', '/')
link.href = computeHref({ to }, 'a', '/', '/')
// We need to add the anchor to the document to make sure the
// `pathname` is correctly detected in any browser (i.e. IE)
document.body.appendChild(link)
Expand Down
18 changes: 16 additions & 2 deletions src/utils/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { isArray, isNull, isPlainObject, isString, isUndefined } from './inspect
import { keys } from './object'
import { toString } from './string'

const ANCHOR_TAG = 'a'

// Method to replace reserved chars
const encodeReserveReplacer = c => '%' + c.charCodeAt(0).toString(16)

Expand Down Expand Up @@ -88,7 +90,7 @@ export const isRouterLink = tag => !!(tag && !isTag(tag, 'a'))
export const computeTag = ({ to, disabled, routerComponentName } = {}, thisOrParent) => {
const hasRouter = !!thisOrParent.$router
if (!hasRouter || (hasRouter && (disabled || !to))) {
return 'a'
return ANCHOR_TAG
}

// TODO:
Expand All @@ -105,12 +107,24 @@ export const computeTag = ({ to, disabled, routerComponentName } = {}, thisOrPar
export const computeRel = ({ target, rel } = {}) =>
target === '_blank' && isNull(rel) ? 'noopener' : rel || null

export const computeHref = ({ href, to } = {}, fallback = '#', toFallback = '/') => {
export const computeHref = (
{ href, to } = {},
tag = ANCHOR_TAG,
fallback = '#',
toFallback = '/'
) => {
// Return `href` when explicitly provided
if (href) {
return href
}

// We've checked for `$router` in `computeTag()`, so `isRouterLink()` indicates a live router
// When deferring to Vue Router's `<router-link>`, don't use the `href` attribute at all
// We return `null`, and then remove `href` from the attributes passed to `<router-link>`
if (isRouterLink(tag)) {
return null
}

// Fallback to `to` prop (if `to` is a string)
if (isString(to)) {
return to || toFallback
Expand Down
18 changes: 12 additions & 6 deletions src/utils/router.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,14 @@ describe('utils/router', () => {

it('parses nothing to default', async () => {
expect(computeHref()).toEqual('#')
expect(computeHref(undefined, '/', '')).toEqual('/')
expect(computeHref(undefined, '', '')).toEqual('')
expect(computeHref(undefined, undefined, '/', '')).toEqual('/')
expect(computeHref(undefined, undefined, '', '')).toEqual('')
})

it('returns null when tag is not `a`', async () => {
expect(computeHref({}, 'div')).toEqual(null)
expect(computeHref(undefined, 'div', '/', '')).toEqual(null)
expect(computeHref(undefined, 'span', '', '/')).toEqual(null)
})

it('returns href when both href and to provided', async () => {
Expand All @@ -124,8 +130,8 @@ describe('utils/router', () => {

it('parses empty `href` to default', async () => {
expect(computeHref({ href: '' })).toEqual('#')
expect(computeHref({ href: '' }, '/', '')).toEqual('/')
expect(computeHref({ href: '' }, '', '')).toEqual('')
expect(computeHref({ href: '' }, 'a', '/', '')).toEqual('/')
expect(computeHref({ href: '' }, 'a', '', '')).toEqual('')
})

it('parses `to` when string', async () => {
Expand Down Expand Up @@ -173,8 +179,8 @@ describe('utils/router', () => {

it('parses empty `to` to fallback default', async () => {
expect(computeHref({ to: {} })).toEqual('#')
expect(computeHref({ to: {} }, '#', '')).toEqual('#')
expect(computeHref({ to: {} }, '/', '#')).toEqual('/')
expect(computeHref({ to: {} }, 'a', '#', '')).toEqual('#')
expect(computeHref({ to: {} }, 'a', '/', '#')).toEqual('/')
})

it('parses complete `to`', async () => {
Expand Down
0