fix: replace v-html with conditional rendering in torrent details view (#513)

This commit is contained in:
Tadas Vosylius 2022-10-16 20:08:36 +03:00 committed by GitHub
parent b6207996c6
commit 6d873e76fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 33 deletions

View file

@ -139,19 +139,34 @@
<td :class="commonStyle">
{{ $t('modals.detail.pageInfo.trackers') }}
</td>
<td> {{ torrent.tracker }} </td>
<td>
<span v-for="trackersPart in splitString(torrent.tracker)">
<a v-if="stringContainsUrl(trackersPart)" _target="blank" :href="trackersPart">{{ trackersPart }}</a>
<span v-else>{{ trackersPart }}</span>
</span>
</td>
</tr>
<tr v-if="createdBy">
<td :class="commonStyle">
{{ $t('modals.detail.pageInfo.createdBy') }}
</td>
<td> {{ createdBy }} </td>
<td>
<span v-for="createdByPart in splitString(createdBy)">
<a v-if="stringContainsUrl(createdByPart)" _target="blank" :href="createdByPart">{{ createdByPart }}</a>
<span v-else>{{ createdByPart }}</span>
</span>
</td>
</tr>
<tr v-if="comment">
<td :class="commonStyle">
{{ $t('torrent.comments') | titleCase }}
</td>
<td> {{ comment }} </td>
<td>
<span v-for="commentPart in splitString(comment)">
<a v-if="stringContainsUrl(commentPart)" _target="blank" :href="commentPart">{{ commentPart }}</a>
<span v-else>{{ commentPart }}</span>
</span>
</td>
</tr>
<tr>
@ -232,6 +247,7 @@
<script>
import { FullScreenModal } from '@/mixins'
import qbit from '@/services/qbit'
import { splitByUrl, stringContainsUrl } from '@/helpers'
export default {
name: 'Info',
@ -300,6 +316,12 @@ export default {
ctx.fillRect((data.length - rectWidth), 0, rectWidth, canvas.height)
}
}
},
stringContainsUrl(string) {
return stringContainsUrl(string)
},
splitString(string) {
return splitByUrl(string)
}
}
}

View file

@ -130,12 +130,4 @@ export function limitToValue(value) {
return value
}
Vue.filter('limitToValue', limitToValue)
export function transformUrlToHref(string) {
const expression = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi
return string.replace(expression, '<a href="$1" target="_blank">$1</a>')
}
Vue.filter('transformUrlToHref', transformUrlToHref)
Vue.filter('limitToValue', limitToValue)

View file

@ -121,3 +121,37 @@ export function getHostName(url) {
return ''
}
}
const urlRegExp = new RegExp(/(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi)
export function splitByUrl(string) {
const urls = string.match(urlRegExp)
let resultArray = []
if (urls) {
urls.forEach(function (url) {
let tmpResult
if (resultArray.length === 0) {
tmpResult = string.toString().split(url)
} else {
tmpResult = resultArray[resultArray.length - 1].toString().split(url)
resultArray.pop()
}
tmpResult.splice(1, 0, url)
resultArray = [...resultArray, ...tmpResult]
})
} else {
resultArray[0] = string
}
resultArray = resultArray.filter(element => {
return element !== ''
})
return resultArray
}
export function stringContainsUrl(string) {
return urlRegExp.test(string)
}

View file

@ -1,28 +1,8 @@
import { titleCase, transformUrlToHref } from '../../src/filters'
import { titleCase } from '../../src/filters'
describe('Filters', () => {
it('titleCase', () => {
expect(titleCase('test')).toEqual('Test')
expect(titleCase('hello there')).toEqual('Hello There')
})
describe('transformUrlToHref()', () => {
it('should not transform anything', () => {
expect(transformUrlToHref('test')).toEqual('test')
})
it('should transform string where http/https is found', () => {
expect(transformUrlToHref('test http://test.something')).toEqual('test <a href="http://test.something" target="_blank">http://test.something</a>')
expect(transformUrlToHref('123456 test@345 https://something.else')).toEqual('123456 test@345 <a href="https://something.else" target="_blank">https://something.else</a>')
})
it('should transform string where only www is found', () => {
expect(transformUrlToHref('test www.test.something')).toEqual('test <a href="www.test.something" target="_blank">www.test.something</a>')
})
it('should transform string where both www and http/https are found', () => {
expect(transformUrlToHref('test http://www.test.something')).toEqual('test <a href="http://www.test.something" target="_blank">http://www.test.something</a>')
expect(transformUrlToHref('test https://www.something.else')).toEqual('test <a href="https://www.something.else" target="_blank">https://www.something.else</a>')
})
})
})

View file

@ -0,0 +1,27 @@
import { splitByUrl } from '../../src/helpers'
describe('Helpers', () => {
describe('splitByUrl()', () => {
it('should not split anything', () => {
expect(splitByUrl('test')).toEqual(['test'])
})
it('should split to array if http/https is found', () => {
expect(splitByUrl('test http://test.something')).toEqual(['test ', 'http://test.something'])
expect(splitByUrl('123456 test@345 https://something.else test@@!!#789')).toEqual(['123456 test@345 ', 'https://something.else', ' test@@!!#789'])
})
it('should split to array if www is found', () => {
expect(splitByUrl('test www.test.something')).toEqual(['test ', 'www.test.something'])
})
it('should split to array where both www and http/https are found', () => {
expect(splitByUrl('test http://www.test.something')).toEqual(['test ', 'http://www.test.something'])
expect(splitByUrl('test https://www.something.else')).toEqual(['test ', 'https://www.something.else'])
})
it('should split correctly if more than one url exists', () => {
expect(splitByUrl('test http://www.test.something some string and https://onemoreurl.com')).toEqual(['test ', 'http://www.test.something', ' some string and ', 'https://onemoreurl.com'])
})
})
})