1
0
Fork 0
-----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEExEqtY4NnkSypPt1XWDphLYkBWb4FAmYOnnUACgkQWDphLYkB
 Wb5TswgA1XteuRNiDzzxn9DIkOCnifuI4V0VGlH+QbKVeVkET/ILnwEtTDLixb2W
 LxNVC0RxqL+e7rVMikVJaA2g8AX/KlUv4dSIEF/vO6b8iTCKr5Zy+Mq/JZocXVzx
 1eRsAear+ZlTFefFwEgAYQjhFtWj+T/ioBxpU8Eh2lZaEC73j9w2ChqR6de1GTGB
 eL6W3qxYl7l6ZfRIjBYVSzPz01VqbJERWb/NOJrTPaNz1DLeIfgp8A7GkuNdvjci
 GizIjEb8BRyQjxEREwzkTNY48XaOEN/cZcas9xf2q9p/vIfKyfQ1+VHYx8xJyv6m
 emOtFRU+ySCryhGeDQK9h45kChrtmA==
 =uz6l
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQJMBAABCAA3FiEEGCBYi9NGimfngx9dVTwOu+tdXwgFAmYxZ+wZHGtvdG92YWxl
 eGFyaWFuQGdtYWlsLmNvbQAKCRBVPA67611fCLERD/QJYPZ1t5mV/5sTwSk9BOUy
 8SiRNzjcJ2i6Hwxg5PnhDh1P8iQ7HLa0dojBwiXSx1fOxmDjL5Q+K4x68JvHOTzz
 xLiq2qAopqjTDpDD6UxMmXkZeXyWTB4gAOs+5/IE3bBIuiGws/VPlioEZpvkAQYn
 doSfeod95DkOyJ1SBTmkzSe0jVWvgIodQsHxFo25SKLgWZZi3pSAuL3lPAB0THkX
 C2GIabSzszlVPdxiIrCOpvZlhoyM4v97EsPh/mMctHFIpoImvcfoCdNdhJKvxgVv
 0/92eQlg/MPNi0Ec7cexyEt5Ud3TPUwBP6RalIcTd5CviGf2EmcGmkx2ulIxtAwQ
 nuHTO+vp82jtvT+g/uVu23zxZVvkpx0zL9f0zujn8v/+WA5yf0IjcoN7KskrqD1S
 ERqpeHoVexxbCBd9CPvsnY0K2EspL7E1WeVbrI9SM1fS5cqBNpYFLmruZVLShFmd
 F8Fxgiz79vBluRYV2yc7ih2hdnh8v6heqnyqkaFMI1ShWphkmDMGC9u+AqRyS6yX
 T+L5AJAioTGCE1k9cgq6WSC3A2v2dNfL3NCxAPtqoQerFjWKw2jQ2euCa6lqKUwI
 FbFZlFtyVP4kg9Q9LGxSEVM3rAzTvyP93rXgSTWRWhZOvCrKveJ6b05XmZDlzR84
 gFsS/arK57X8nGF0s4o6
 =+i0l
 -----END PGP SIGNATURE-----

Merge tag 'v6.0.4' into changes

v6.0.4
This commit is contained in:
Alex Kotov 2024-05-01 01:51:37 +04:00
commit 6064db4335
20 changed files with 45 additions and 104 deletions

View file

@ -1,5 +1,17 @@
# Changelog # Changelog
## v6.0.4
### IMPORTANT NOTES
* If you upgrade from PeerTube **< v6.0.0**, please follow v6.0.0 IMPORTANT NOTES
* If you upgrade from PeerTube **v6.0.0**, please follow v6.0.1 IMPORTANT NOTES
### SECURITY
* **Important:** Prevent XSS injection in embed. Thanks [Syst3m0ver](https://www.linkedin.com/in/ahmed-hasnaoui-790618180)!
## v6.0.3 ## v6.0.3
### IMPORTANT NOTES ### IMPORTANT NOTES

View file

@ -1,6 +1,6 @@
{ {
"name": "peertube-client", "name": "peertube-client",
"version": "6.0.3", "version": "6.0.4",
"private": true, "private": true,
"license": "AGPL-3.0", "license": "AGPL-3.0",
"author": { "author": {

View file

@ -11,7 +11,6 @@ import { AppComponent } from './app.component'
import { CoreModule, PluginService, RedirectService, ServerService } from './core' import { CoreModule, PluginService, RedirectService, ServerService } from './core'
import { EmptyComponent } from './empty.component' import { EmptyComponent } from './empty.component'
import { HeaderComponent, SearchTypeaheadComponent, SuggestionComponent } from './header' import { HeaderComponent, SearchTypeaheadComponent, SuggestionComponent } from './header'
import { HighlightPipe } from './header/highlight.pipe'
import { polyfillICU } from './helpers' import { polyfillICU } from './helpers'
import { LanguageChooserComponent, MenuComponent, NotificationComponent } from './menu' import { LanguageChooserComponent, MenuComponent, NotificationComponent } from './menu'
import { AccountSetupWarningModalComponent } from './modal/account-setup-warning-modal.component' import { AccountSetupWarningModalComponent } from './modal/account-setup-warning-modal.component'
@ -58,7 +57,6 @@ export function loadConfigFactory (server: ServerService, pluginService: PluginS
HeaderComponent, HeaderComponent,
SearchTypeaheadComponent, SearchTypeaheadComponent,
SuggestionComponent, SuggestionComponent,
HighlightPipe,
AccountSetupWarningModalComponent, AccountSetupWarningModalComponent,
CustomModalComponent, CustomModalComponent,

View file

@ -1,54 +0,0 @@
import { PipeTransform, Pipe } from '@angular/core'
import { SafeHtml } from '@angular/platform-browser'
// Thanks https://gist.github.com/adamrecsko/0f28f474eca63e0279455476cc11eca7#gistcomment-2917369
@Pipe({ name: 'highlight' })
export class HighlightPipe implements PipeTransform {
/* use this for single match search */
static SINGLE_MATCH = 'Single-Match'
/* use this for single match search with a restriction that target should start with search string */
static SINGLE_AND_STARTS_WITH_MATCH = 'Single-And-StartsWith-Match'
/* use this for global search */
static MULTI_MATCH = 'Multi-Match'
transform (
contentString: string = null,
stringToHighlight: string = null,
option = 'Single-And-StartsWith-Match',
caseSensitive = false,
highlightStyleName = 'search-highlight'
): SafeHtml {
if (stringToHighlight && contentString && option) {
let regex: any = ''
const caseFlag: string = !caseSensitive ? 'i' : ''
switch (option) {
case 'Single-Match': {
regex = new RegExp(stringToHighlight, caseFlag)
break
}
case 'Single-And-StartsWith-Match': {
regex = new RegExp('^' + stringToHighlight, caseFlag)
break
}
case 'Multi-Match': {
regex = new RegExp(stringToHighlight, 'g' + caseFlag)
break
}
default: {
// default will be a global case-insensitive match
regex = new RegExp(stringToHighlight, 'gi')
}
}
const replaced = contentString.replace(
regex,
(match) => `<span class="${highlightStyleName}">${match}</span>`
)
return replaced
} else {
return contentString
}
}
}

View file

@ -7,8 +7,10 @@
<div <div
class="flex-auto overflow-hidden text-start no-wrap css-truncate css-truncate-target" class="flex-auto overflow-hidden text-start no-wrap css-truncate css-truncate-target"
[attr.aria-label]="result.text" [innerHTML]="result.text | highlight : highlight" [attr.aria-label]="result.text"
></div> >
{{ result.text }}
</div>
<div class="border rounded flex-shrink-0 px-1 bg-gray text-gray-light ms-1 f6"> <div class="border rounded flex-shrink-0 px-1 bg-gray text-gray-light ms-1 f6">
<span *ngIf="result.type === 'search-instance'" i18n>In this instance's network</span> <span *ngIf="result.type === 'search-instance'" i18n>In this instance's network</span>

View file

@ -62,8 +62,8 @@ export class ConfirmComponent implements OnInit {
this.confirmButtonText = confirmButtonText || $localize`Confirm` this.confirmButtonText = confirmButtonText || $localize`Confirm`
this.html.toSafeHtml(message) this.html.toSafeHtml(message)
.then(message => { .then(html => {
this.message = message this.message = html
this.showModal() this.showModal()
}) })

View file

@ -29,7 +29,7 @@ class PeerTubeLinkButton extends Component {
createEl () { createEl () {
const el = videojs.dom.createEl('a', { const el = videojs.dom.createEl('a', {
href: this.buildLink(), href: this.buildLink(),
innerHTML: this.options_.instanceName, innerText: this.options_.instanceName,
title: this.player().localize('Video page (new window)'), title: this.player().localize('Video page (new window)'),
className: 'vjs-peertube-link', className: 'vjs-peertube-link',
target: '_blank' target: '_blank'

View file

@ -37,7 +37,7 @@ class PeerTubeDockComponent extends Component {
const title = videojs.dom.createEl('div', { const title = videojs.dom.createEl('div', {
className: 'peertube-dock-title', className: 'peertube-dock-title',
title: this.options_.title, title: this.options_.title,
innerHTML: this.options_.title innerText: this.options_.title
}) })
elWrapperTitleDescription.appendChild(title) elWrapperTitleDescription.appendChild(title)
@ -47,7 +47,7 @@ class PeerTubeDockComponent extends Component {
const description = videojs.dom.createEl('div', { const description = videojs.dom.createEl('div', {
className: 'peertube-dock-description', className: 'peertube-dock-description',
title: this.options_.description, title: this.options_.description,
innerHTML: this.options_.description innerText: this.options_.description
}) })
elWrapperTitleDescription.appendChild(description) elWrapperTitleDescription.appendChild(description)

View file

@ -22,19 +22,16 @@ class PlaylistButton extends ClickableComponent {
createEl () { createEl () {
this.wrapper = super.createEl('div', { this.wrapper = super.createEl('div', {
className: 'vjs-playlist-button', className: 'vjs-playlist-button',
innerHTML: '',
tabIndex: -1 tabIndex: -1
}) as HTMLElement }) as HTMLElement
const icon = super.createEl('div', { const icon = super.createEl('div', {
className: 'vjs-playlist-icon', className: 'vjs-playlist-icon',
innerHTML: '',
tabIndex: -1 tabIndex: -1
}) })
this.playlistInfoElement = super.createEl('div', { this.playlistInfoElement = super.createEl('div', {
className: 'vjs-playlist-info', className: 'vjs-playlist-info',
innerHTML: '',
tabIndex: -1 tabIndex: -1
}) as HTMLElement }) as HTMLElement
@ -47,7 +44,7 @@ class PlaylistButton extends ClickableComponent {
} }
update () { update () {
this.playlistInfoElement.innerHTML = this.options_.getCurrentPosition() + '/' + this.options_.playlist.videosLength this.playlistInfoElement.innerText = this.options_.getCurrentPosition() + '/' + this.options_.playlist.videosLength
this.wrapper.title = this.player().localize('Playlist: {1}', [ this.options_.playlist.displayName ]) this.wrapper.title = this.player().localize('Playlist: {1}', [ this.options_.playlist.displayName ])
} }

View file

@ -36,8 +36,7 @@ class PlaylistMenuItem extends Component {
createEl () { createEl () {
const li = super.createEl('li', { const li = super.createEl('li', {
className: 'vjs-playlist-menu-item', className: 'vjs-playlist-menu-item'
innerHTML: ''
}) as HTMLElement }) as HTMLElement
if (!this.options_.element.video) { if (!this.options_.element.video) {
@ -50,7 +49,7 @@ class PlaylistMenuItem extends Component {
const position = super.createEl('div', { const position = super.createEl('div', {
className: 'item-position', className: 'item-position',
innerHTML: this.options_.element.position innerText: this.options_.element.position
}) })
positionBlock.appendChild(position) positionBlock.appendChild(position)
@ -92,12 +91,12 @@ class PlaylistMenuItem extends Component {
}) })
const title = super.createEl('div', { const title = super.createEl('div', {
innerHTML: videoElement.video.name, innerText: videoElement.video.name,
className: 'title' className: 'title'
}) })
const channel = super.createEl('div', { const channel = super.createEl('div', {
innerHTML: videoElement.video.channel.displayName, innerText: videoElement.video.channel.displayName,
className: 'channel' className: 'channel'
}) })
@ -111,7 +110,7 @@ class PlaylistMenuItem extends Component {
if (videoElement.stopTimestamp) html += ' - ' + secondsToTime(videoElement.stopTimestamp) if (videoElement.stopTimestamp) html += ' - ' + secondsToTime(videoElement.stopTimestamp)
const timestamps = super.createEl('div', { const timestamps = super.createEl('div', {
innerHTML: html, innerText: html,
className: 'timestamps' className: 'timestamps'
}) })
@ -125,7 +124,7 @@ class PlaylistMenuItem extends Component {
private buildUnavailableVideo (li: HTMLElement) { private buildUnavailableVideo (li: HTMLElement) {
const block = super.createEl('div', { const block = super.createEl('div', {
className: 'item-unavailable', className: 'item-unavailable',
innerHTML: this.player().localize('Unavailable video') innerTExt: this.player().localize('Unavailable video')
}) })
li.appendChild(block) li.appendChild(block)

View file

@ -73,7 +73,6 @@ class PlaylistMenu extends Component {
const menu = super.createEl('div', { const menu = super.createEl('div', {
className: 'vjs-playlist-menu', className: 'vjs-playlist-menu',
innerHTML: '',
tabIndex: -1 tabIndex: -1
}) })
@ -84,13 +83,13 @@ class PlaylistMenu extends Component {
const headerLeft = super.createEl('div') const headerLeft = super.createEl('div')
const leftTitle = super.createEl('div', { const leftTitle = super.createEl('div', {
innerHTML: this.options_.playlist.displayName, innerText: this.options_.playlist.displayName,
className: 'title' className: 'title'
}) })
const playlistChannel = this.options_.playlist.videoChannel const playlistChannel = this.options_.playlist.videoChannel
const leftSubtitle = super.createEl('div', { const leftSubtitle = super.createEl('div', {
innerHTML: playlistChannel innerText: playlistChannel
? this.player().localize('By {1}', [ playlistChannel.displayName ]) ? this.player().localize('By {1}', [ playlistChannel.displayName ])
: '', : '',
className: 'channel' className: 'channel'

View file

@ -20,7 +20,6 @@ class SettingsDialog extends Component {
return super.createEl('div', { return super.createEl('div', {
className: 'vjs-settings-dialog vjs-modal-overlay', className: 'vjs-settings-dialog vjs-modal-overlay',
innerHTML: '',
tabIndex: -1 tabIndex: -1
}, { }, {
'role': 'dialog', 'role': 'dialog',

View file

@ -7,7 +7,6 @@ class SettingsPanelChild extends Component {
createEl () { createEl () {
return super.createEl('div', { return super.createEl('div', {
className: 'vjs-settings-panel-child', className: 'vjs-settings-panel-child',
innerHTML: '',
tabIndex: -1 tabIndex: -1
}) })
} }

View file

@ -7,7 +7,6 @@ class SettingsPanel extends Component {
createEl () { createEl () {
return super.createEl('div', { return super.createEl('div', {
className: 'vjs-settings-panel', className: 'vjs-settings-panel',
innerHTML: '',
tabIndex: -1 tabIndex: -1
}) })
} }

View file

@ -285,15 +285,15 @@ class StatsCard extends Component {
if (player.muted()) volume += player.localize(' (muted)') if (player.muted()) volume += player.localize(' (muted)')
const networkActivity = playerNetworkInfo.downloadSpeed const networkActivity = playerNetworkInfo.downloadSpeed
? `${playerNetworkInfo.downloadSpeed} &dArr; / ${playerNetworkInfo.uploadSpeed} &uArr;` ? `${playerNetworkInfo.downloadSpeed} \u21D3 / ${playerNetworkInfo.uploadSpeed} \u21D1`
: undefined : undefined
let totalTransferred = playerNetworkInfo.totalDownloaded let totalTransferred = playerNetworkInfo.totalDownloaded
? `${playerNetworkInfo.totalDownloaded} &dArr;` ? `${playerNetworkInfo.totalDownloaded} \u21D3`
: '' : ''
if (playerNetworkInfo.totalUploaded) { if (playerNetworkInfo.totalUploaded) {
totalTransferred += `/ ${playerNetworkInfo.totalUploaded} &uArr;` totalTransferred += `/ ${playerNetworkInfo.totalUploaded} \u21D1`
} }
const downloadBreakdown = playerNetworkInfo.downloadedFromServer const downloadBreakdown = playerNetworkInfo.downloadedFromServer
@ -337,16 +337,16 @@ class StatsCard extends Component {
el.root.style.display = 'block' el.root.style.display = 'block'
if (el.value.innerHTML === value) return if (el.value.innerText === value) return
el.value.innerHTML = value el.value.innerText = value
} }
private buildInfoRow (labelText: string, valueHTML?: string) { private buildInfoRow (labelText: string) {
const root = videojs.dom.createEl('div') as HTMLElement const root = videojs.dom.createEl('div') as HTMLElement
root.style.display = 'none' root.style.display = 'none'
const label = videojs.dom.createEl('div', { innerText: labelText }) as HTMLElement const label = videojs.dom.createEl('div', { innerText: labelText }) as HTMLElement
const value = videojs.dom.createEl('span', { innerHTML: valueHTML }) as HTMLElement const value = videojs.dom.createEl('span') as HTMLElement
root.appendChild(label) root.appendChild(label)
root.appendChild(value) root.appendChild(value)

View file

@ -121,7 +121,7 @@ export class EndCard extends Component {
this.autoplayRing.setAttribute('stroke-dasharray', `${this.dashOffsetStart}`) this.autoplayRing.setAttribute('stroke-dasharray', `${this.dashOffsetStart}`)
this.autoplayRing.setAttribute('stroke-dashoffset', `${-this.dashOffsetStart}`) this.autoplayRing.setAttribute('stroke-dashoffset', `${-this.dashOffsetStart}`)
this.title.innerHTML = this.options_.getTitle() this.title.innerText = this.options_.getTitle()
if (this.totalTicks === 0) { if (this.totalTicks === 0) {
return cb(false) return cb(false)

View file

@ -60,15 +60,6 @@
.peertube-dock-description { .peertube-dock-description {
font-size: 11px; font-size: 11px;
line-height: 1.5; line-height: 1.5;
.text::before {
@include margin-right(4px);
}
.text::after {
@include margin-left(4px);
transform: scale(-1, 1);
}
} }
@media screen and (max-width: $screen-width-750) { @media screen and (max-width: $screen-width-750) {

View file

@ -69,14 +69,14 @@ export class PlayerHTML {
videoPasswordBlock.style.display = 'flex' videoPasswordBlock.style.display = 'flex'
const videoPasswordTitle = document.getElementById('video-password-title') const videoPasswordTitle = document.getElementById('video-password-title')
videoPasswordTitle.innerHTML = translatedTitle videoPasswordTitle.innerText = translatedTitle
const videoPasswordMessage = document.getElementById('video-password-content') const videoPasswordMessage = document.getElementById('video-password-content')
videoPasswordMessage.innerHTML = translatedMessage videoPasswordMessage.innerText = translatedMessage
if (incorrectPassword) { if (incorrectPassword) {
const videoPasswordError = document.getElementById('video-password-error') const videoPasswordError = document.getElementById('video-password-error')
videoPasswordError.innerHTML = peertubeTranslate('Incorrect password, please enter a correct password', translations) videoPasswordError.innerText = peertubeTranslate('Incorrect password, please enter a correct password', translations)
videoPasswordError.style.transform = 'scale(1.2)' videoPasswordError.style.transform = 'scale(1.2)'
setTimeout(() => { setTimeout(() => {
@ -85,7 +85,7 @@ export class PlayerHTML {
} }
const videoPasswordSubmitButton = document.getElementById('video-password-submit') const videoPasswordSubmitButton = document.getElementById('video-password-submit')
videoPasswordSubmitButton.innerHTML = peertubeTranslate('Watch Video', translations) videoPasswordSubmitButton.innerText = peertubeTranslate('Watch Video', translations)
const videoPasswordInput = document.getElementById('video-password-input') as HTMLInputElement const videoPasswordInput = document.getElementById('video-password-input') as HTMLInputElement
videoPasswordInput.placeholder = peertubeTranslate('Password', translations) videoPasswordInput.placeholder = peertubeTranslate('Password', translations)

View file

@ -436,7 +436,7 @@ export class PlayerOptionsBuilder {
: undefined : undefined
const description = this.hasWarningTitle() && this.hasP2PEnabled() const description = this.hasWarningTitle() && this.hasP2PEnabled()
? '<span class="text">' + peertubeTranslate('Watching this video may reveal your IP address to others.') + '</span>' ? peertubeTranslate('Watching this video may reveal your IP address to others.')
: undefined : undefined
if (!title && !description) return if (!title && !description) return

View file

@ -1,7 +1,7 @@
{ {
"name": "peertube", "name": "peertube",
"description": "PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.", "description": "PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.",
"version": "6.0.3", "version": "6.0.4",
"private": true, "private": true,
"licence": "AGPL-3.0", "licence": "AGPL-3.0",
"engines": { "engines": {