Skip to content

Instantly share code, notes, and snippets.

@daliborgogic
Last active November 6, 2019 12:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daliborgogic/55e25126a93f4f332658a59e73f84711 to your computer and use it in GitHub Desktop.
Save daliborgogic/55e25126a93f4f332658a59e73f84711 to your computer and use it in GitHub Desktop.
Mark external links (UX). internal let router handle.
<template>
<div v-html="content" />
</template>
<script>
export default {
props: {
content: {
type: String,
default: ''
}
},
watch: { content: 'contentUpdated' },
mounted() { this.addListeners() },
beforeDestroy() { this.removeListeners() },
methods: {
navigate(event) {
const href = event.target.getAttribute('href')
if (href && href[0] === '/') {
event.preventDefault()
this.$router.push(href)
}
},
contentUpdated() {
this.removeListeners()
this.$nextTick(() => {
this.addListeners()
})
},
addListeners() {
this._links = this.$el.getElementsByTagName('a')
for (let i = 0; i < this._links.length; i++) {
const href = this._links[i].getAttribute('href')
const target = this._links[i].getAttribute('target')
if (href && href[0] !== '/') {
this._links[i].insertAdjacentHTML('beforeend', '<svg class="external" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/></svg>')
}
// For improved security `rel="noopener"` will be added if target is `_blank`
// https://github.com/mathiasbynens/rel-noopener/
if (target && target === '_blank') {
this._links[i].setAttribute('rel', 'noopener')
}
this._links[i].addEventListener('click', this.navigate, false)
}
},
removeListeners() {
for (let i = 0; i < this._links.length; i++) {
this._links[i].removeEventListener('click', this.navigate, false)
}
this._links = []
}
}
}
</script>
<style lang="stylus" scoped>
>>> p
font-size rem(14px)
line-height 1.714
font-weight 400
>>> a
color $blue
text-decoration none
>>> .external
margin-left 4px
fill $blue
vertical-align middle
transform translateY(-1px)
</style>
<template>
<Content :content="content" />
<template>
<script>
import Content from 'Content'
export default {
components: { Content },
data () {
return {
content: '<p>Lorem ipsum dolor sit amet, consectetur <code>npm --version</code> elit, sed do <a href=\"/internal\">internal</a> tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat</p><p><strong>Lorem ipsum dolor sit amet, consectetur adipiscing elit</strong>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco <a href=\"https:/example.com\">external</a> nisi ut aliquip ex ea commodo consequat.</p>'
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment