diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2020-01-10 19:50:48 +0100 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-01-21 10:08:10 +0100 |
commit | 7738273b808f0ff1494f18c4cc13553505e6ac6d (patch) | |
tree | e751a2282ffb9d5f1f4e556ca865e06ed4426710 | |
parent | aa0f19635ae4632e286de1599fc24f95f32a108c (diff) | |
download | PeerTube-7738273b808f0ff1494f18c4cc13553505e6ac6d.tar.gz PeerTube-7738273b808f0ff1494f18c4cc13553505e6ac6d.tar.zst PeerTube-7738273b808f0ff1494f18c4cc13553505e6ac6d.zip |
Accessibility fixes for #2149
14 files changed, 32 insertions, 19 deletions
diff --git a/client/src/app/+admin/users/user-edit/user-edit.component.html b/client/src/app/+admin/users/user-edit/user-edit.component.html index 6282d48a4..4ff4d0d12 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.component.html +++ b/client/src/app/+admin/users/user-edit/user-edit.component.html | |||
@@ -30,7 +30,7 @@ | |||
30 | <div class="form-group" *ngIf="isCreation()"> | 30 | <div class="form-group" *ngIf="isCreation()"> |
31 | <label i18n for="password">Password</label> | 31 | <label i18n for="password">Password</label> |
32 | <input | 32 | <input |
33 | type="password" id="password" | 33 | type="password" id="password" autocomplete="new-password" |
34 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 34 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" |
35 | > | 35 | > |
36 | <div *ngIf="formErrors.password" class="form-error"> | 36 | <div *ngIf="formErrors.password" class="form-error"> |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.html b/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.html index 5492cdf22..76886c73e 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.html +++ b/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.html | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | <div class="form-group"> | 25 | <div class="form-group"> |
26 | <input | 26 | <input |
27 | type="password" id="password" i18n-placeholder placeholder="Your password" | 27 | type="password" id="password" i18n-placeholder placeholder="Your password" autocomplete="off" |
28 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 28 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" |
29 | > | 29 | > |
30 | <div *ngIf="formErrors['password']" class="form-error"> | 30 | <div *ngIf="formErrors['password']" class="form-error"> |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html index a39061ee3..cec70c6b5 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html +++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | <label i18n for="current-password">Change password</label> | 5 | <label i18n for="current-password">Change password</label> |
6 | <input | 6 | <input |
7 | type="password" id="current-password" i18n-placeholder placeholder="Current password" | 7 | type="password" id="current-password" i18n-placeholder placeholder="Current password" autocomplete="current-password" |
8 | formControlName="current-password" [ngClass]="{ 'input-error': formErrors['current-password'] }" | 8 | formControlName="current-password" [ngClass]="{ 'input-error': formErrors['current-password'] }" |
9 | > | 9 | > |
10 | <div *ngIf="formErrors['current-password']" class="form-error"> | 10 | <div *ngIf="formErrors['current-password']" class="form-error"> |
@@ -12,7 +12,7 @@ | |||
12 | </div> | 12 | </div> |
13 | 13 | ||
14 | <input | 14 | <input |
15 | type="password" id="new-password" i18n-placeholder placeholder="New password" | 15 | type="password" id="new-password" i18n-placeholder placeholder="New password" autocomplete="new-password" |
16 | formControlName="new-password" [ngClass]="{ 'input-error': formErrors['new-password'] }" | 16 | formControlName="new-password" [ngClass]="{ 'input-error': formErrors['new-password'] }" |
17 | > | 17 | > |
18 | <div *ngIf="formErrors['new-password']" class="form-error"> | 18 | <div *ngIf="formErrors['new-password']" class="form-error"> |
@@ -20,7 +20,7 @@ | |||
20 | </div> | 20 | </div> |
21 | 21 | ||
22 | <input | 22 | <input |
23 | type="password" id="new-confirmed-password" i18n-placeholder placeholder="Confirm new password" | 23 | type="password" id="new-confirmed-password" i18n-placeholder placeholder="Confirm new password" autocomplete="new-password" |
24 | formControlName="new-confirmed-password" | 24 | formControlName="new-confirmed-password" |
25 | > | 25 | > |
26 | <div *ngIf="formErrors['new-confirmed-password']" class="form-error"> | 26 | <div *ngIf="formErrors['new-confirmed-password']" class="form-error"> |
diff --git a/client/src/app/+signup/+register/register-step-user.component.html b/client/src/app/+signup/+register/register-step-user.component.html index 4381702ae..a2a657660 100644 --- a/client/src/app/+signup/+register/register-step-user.component.html +++ b/client/src/app/+signup/+register/register-step-user.component.html | |||
@@ -51,7 +51,7 @@ | |||
51 | <div class="form-group"> | 51 | <div class="form-group"> |
52 | <label for="password" i18n>Password</label> | 52 | <label for="password" i18n>Password</label> |
53 | <input | 53 | <input |
54 | type="password" id="password" i18n-placeholder placeholder="Password" | 54 | type="password" id="password" i18n-placeholder placeholder="Password" autocomplete="new-password" |
55 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 55 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" |
56 | > | 56 | > |
57 | <div *ngIf="formErrors.password" class="form-error"> | 57 | <div *ngIf="formErrors.password" class="form-error"> |
diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts index c1dc25aaf..f4fe14662 100644 --- a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts +++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts | |||
@@ -72,7 +72,7 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On | |||
72 | .getVideoChannelVideos(this.videoChannel, newPagination, this.sort) | 72 | .getVideoChannelVideos(this.videoChannel, newPagination, this.sort) |
73 | .pipe( | 73 | .pipe( |
74 | tap(({ total }) => { | 74 | tap(({ total }) => { |
75 | this.titlePage = this.i18n('Published {{total}} videos', { total }) | 75 | this.titlePage = this.i18n(`{total, plural, =1 {Published 1 video} other {Published ${total} videos}}`, { total }) |
76 | }) | 76 | }) |
77 | ) | 77 | ) |
78 | } | 78 | } |
diff --git a/client/src/app/+video-channels/video-channels.component.html b/client/src/app/+video-channels/video-channels.component.html index 8ab79526d..065fc2c04 100644 --- a/client/src/app/+video-channels/video-channels.component.html +++ b/client/src/app/+video-channels/video-channels.component.html | |||
@@ -20,7 +20,7 @@ | |||
20 | <my-subscribe-button #subscribeButton [videoChannels]="[videoChannel]"></my-subscribe-button> | 20 | <my-subscribe-button #subscribeButton [videoChannels]="[videoChannel]"></my-subscribe-button> |
21 | </div> | 21 | </div> |
22 | </div> | 22 | </div> |
23 | <div i18n class="actor-followers">{{ videoChannel.followersCount }} subscribers</div> | 23 | <div class="actor-followers" i18n>{videoChannel.followersCount, plural, =1 {1 subscriber} other {{{ videoChannel.followersCount }} subscribers}}</div> |
24 | 24 | ||
25 | <a [routerLink]="[ '/accounts', videoChannel.ownerBy ]" i18n-title title="Go the owner account page" class="actor-owner"> | 25 | <a [routerLink]="[ '/accounts', videoChannel.ownerBy ]" i18n-title title="Go the owner account page" class="actor-owner"> |
26 | <span i18n>Created by {{ videoChannel.ownerBy }}</span> | 26 | <span i18n>Created by {{ videoChannel.ownerBy }}</span> |
diff --git a/client/src/app/header/header.component.html b/client/src/app/header/header.component.html index 599861817..1bdfe9858 100644 --- a/client/src/app/header/header.component.html +++ b/client/src/app/header/header.component.html | |||
@@ -1,5 +1,5 @@ | |||
1 | <input | 1 | <input |
2 | type="text" id="search-video" name="search-video" i18n-placeholder placeholder="Search videos, channels…" | 2 | type="text" id="search-video" name="search-video" [attr.aria-label]="ariaLabelTextForSearch" i18n-placeholder placeholder="Search videos, channels…" |
3 | [(ngModel)]="searchValue" (keyup.enter)="doSearch()" | 3 | [(ngModel)]="searchValue" (keyup.enter)="doSearch()" |
4 | > | 4 | > |
5 | <span (click)="doSearch()" class="icon icon-search"></span> | 5 | <span (click)="doSearch()" class="icon icon-search"></span> |
diff --git a/client/src/app/header/header.component.ts b/client/src/app/header/header.component.ts index 580535669..5fd122930 100644 --- a/client/src/app/header/header.component.ts +++ b/client/src/app/header/header.component.ts | |||
@@ -5,6 +5,7 @@ import { getParameterByName } from '../shared/misc/utils' | |||
5 | import { AuthService, ServerService, Notifier } from '@app/core' | 5 | import { AuthService, ServerService, Notifier } from '@app/core' |
6 | import { of } from 'rxjs' | 6 | import { of } from 'rxjs' |
7 | import { ServerConfig } from '@shared/models' | 7 | import { ServerConfig } from '@shared/models' |
8 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
8 | 9 | ||
9 | @Component({ | 10 | @Component({ |
10 | selector: 'my-header', | 11 | selector: 'my-header', |
@@ -14,6 +15,7 @@ import { ServerConfig } from '@shared/models' | |||
14 | 15 | ||
15 | export class HeaderComponent implements OnInit { | 16 | export class HeaderComponent implements OnInit { |
16 | searchValue = '' | 17 | searchValue = '' |
18 | ariaLabelTextForSearch = '' | ||
17 | 19 | ||
18 | private serverConfig: ServerConfig | 20 | private serverConfig: ServerConfig |
19 | 21 | ||
@@ -23,10 +25,13 @@ export class HeaderComponent implements OnInit { | |||
23 | private auth: AuthService, | 25 | private auth: AuthService, |
24 | private serverService: ServerService, | 26 | private serverService: ServerService, |
25 | private authService: AuthService, | 27 | private authService: AuthService, |
26 | private notifier: Notifier | 28 | private notifier: Notifier, |
29 | private i18n: I18n | ||
27 | ) {} | 30 | ) {} |
28 | 31 | ||
29 | ngOnInit () { | 32 | ngOnInit () { |
33 | this.ariaLabelTextForSearch = this.i18n('Search videos, channels') | ||
34 | |||
30 | this.router.events | 35 | this.router.events |
31 | .pipe( | 36 | .pipe( |
32 | filter(e => e instanceof NavigationEnd), | 37 | filter(e => e instanceof NavigationEnd), |
diff --git a/client/src/app/login/login.component.html b/client/src/app/login/login.component.html index 162f44ded..6c6a41c4a 100644 --- a/client/src/app/login/login.component.html +++ b/client/src/app/login/login.component.html | |||
@@ -51,7 +51,7 @@ | |||
51 | <label i18n for="password">Password</label> | 51 | <label i18n for="password">Password</label> |
52 | <div> | 52 | <div> |
53 | <input | 53 | <input |
54 | type="password" name="password" id="password" i18n-placeholder placeholder="Password" required tabindex="2" | 54 | type="password" name="password" id="password" i18n-placeholder placeholder="Password" required tabindex="2" autocomplete="current-password" |
55 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 55 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" |
56 | > | 56 | > |
57 | <a i18n class="forgot-password-button" (click)="openForgotPasswordModal()" title="Click here to reset your password">I forgot my password</a> | 57 | <a i18n class="forgot-password-button" (click)="openForgotPasswordModal()" title="Click here to reset your password">I forgot my password</a> |
diff --git a/client/src/app/reset-password/reset-password.component.html b/client/src/app/reset-password/reset-password.component.html index 8398be091..af30af4a0 100644 --- a/client/src/app/reset-password/reset-password.component.html +++ b/client/src/app/reset-password/reset-password.component.html | |||
@@ -7,7 +7,7 @@ | |||
7 | <div class="form-group"> | 7 | <div class="form-group"> |
8 | <label i18n for="password">Password</label> | 8 | <label i18n for="password">Password</label> |
9 | <input | 9 | <input |
10 | type="password" name="password" id="password" i18n-placeholder placeholder="Password" required | 10 | type="password" name="password" id="password" i18n-placeholder placeholder="Password" required autocomplete="new-password" |
11 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 11 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" |
12 | > | 12 | > |
13 | <div *ngIf="formErrors.password" class="form-error"> | 13 | <div *ngIf="formErrors.password" class="form-error"> |
@@ -18,7 +18,7 @@ | |||
18 | <div class="form-group"> | 18 | <div class="form-group"> |
19 | <label i18n for="password-confirm">Confirm password</label> | 19 | <label i18n for="password-confirm">Confirm password</label> |
20 | <input | 20 | <input |
21 | type="password" name="password-confirm" id="password-confirm" i18n-placeholder placeholder="Confirmed password" required | 21 | type="password" name="password-confirm" id="password-confirm" i18n-placeholder placeholder="Confirmed password" required autocomplete="new-password" |
22 | formControlName="password-confirm" [ngClass]="{ 'input-error': formErrors['password-confirm'] }" | 22 | formControlName="password-confirm" [ngClass]="{ 'input-error': formErrors['password-confirm'] }" |
23 | > | 23 | > |
24 | <div *ngIf="formErrors['password-confirm']" class="form-error"> | 24 | <div *ngIf="formErrors['password-confirm']" class="form-error"> |
diff --git a/client/src/app/shared/images/global-icon.component.ts b/client/src/app/shared/images/global-icon.component.ts index 17186cff4..806aca347 100644 --- a/client/src/app/shared/images/global-icon.component.ts +++ b/client/src/app/shared/images/global-icon.component.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { ChangeDetectionStrategy, Component, ElementRef, Input, OnInit } from '@angular/core' | 1 | import { ChangeDetectionStrategy, Component, ElementRef, Input, OnInit } from '@angular/core' |
2 | import { HooksService } from '@app/core/plugins/hooks.service' | 2 | import { HooksService } from '@app/core/plugins/hooks.service' |
3 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
3 | 4 | ||
4 | const icons = { | 5 | const icons = { |
5 | 'add': require('!!raw-loader?!../../../assets/images/global/add.svg'), | 6 | 'add': require('!!raw-loader?!../../../assets/images/global/add.svg'), |
@@ -70,8 +71,7 @@ export class GlobalIconComponent implements OnInit { | |||
70 | ) { } | 71 | ) { } |
71 | 72 | ||
72 | async ngOnInit () { | 73 | async ngOnInit () { |
73 | const nativeElement = this.el.nativeElement | 74 | const nativeElement = this.el.nativeElement as HTMLElement |
74 | |||
75 | nativeElement.innerHTML = await this.hooks.wrapFun( | 75 | nativeElement.innerHTML = await this.hooks.wrapFun( |
76 | this.getSVGContent.bind(this), | 76 | this.getSVGContent.bind(this), |
77 | { name: this.iconName }, | 77 | { name: this.iconName }, |
diff --git a/client/src/app/shared/video/video-thumbnail.component.html b/client/src/app/shared/video/video-thumbnail.component.html index 7e71a390b..b63085b81 100644 --- a/client/src/app/shared/video/video-thumbnail.component.html +++ b/client/src/app/shared/video/video-thumbnail.component.html | |||
@@ -1,8 +1,8 @@ | |||
1 | <a | 1 | <a |
2 | [routerLink]="getVideoRouterLink()" [queryParams]="queryParams" [attr.title]="video.name" | 2 | [routerLink]="getVideoRouterLink()" [queryParams]="queryParams" [title]="video.name" |
3 | class="video-thumbnail" | 3 | class="video-thumbnail" |
4 | > | 4 | > |
5 | <img alt="" [attr.aria-labelledby]="video.name" [attr.src]="getImageUrl()" [ngClass]="{ 'blur-filter': nsfw }" /> | 5 | <img alt="" [attr.aria-label]="video.name" [attr.src]="getImageUrl()" [ngClass]="{ 'blur-filter': nsfw }" /> |
6 | 6 | ||
7 | <div *ngIf="displayWatchLaterPlaylist" class="video-thumbnail-actions-overlay"> | 7 | <div *ngIf="displayWatchLaterPlaylist" class="video-thumbnail-actions-overlay"> |
8 | <ng-container *ngIf="inWatchLaterPlaylist !== true"> | 8 | <ng-container *ngIf="inWatchLaterPlaylist !== true"> |
diff --git a/client/src/sass/primeng-custom.scss b/client/src/sass/primeng-custom.scss index 9aa4d980c..238cb8454 100644 --- a/client/src/sass/primeng-custom.scss +++ b/client/src/sass/primeng-custom.scss | |||
@@ -8,6 +8,7 @@ | |||
8 | font-family: 'Glyphicons Halflings'; | 8 | font-family: 'Glyphicons Halflings'; |
9 | text-decoration: none !important; | 9 | text-decoration: none !important; |
10 | color: var(--mainForegroundColor) !important; | 10 | color: var(--mainForegroundColor) !important; |
11 | font-display: swap; | ||
11 | } | 12 | } |
12 | 13 | ||
13 | my-edit-button, | 14 | my-edit-button, |
diff --git a/server/lib/client-html.ts b/server/lib/client-html.ts index e59505614..1d8a08ed0 100644 --- a/server/lib/client-html.ts +++ b/server/lib/client-html.ts | |||
@@ -26,7 +26,9 @@ export class ClientHtml { | |||
26 | } | 26 | } |
27 | 27 | ||
28 | static async getDefaultHTMLPage (req: express.Request, res: express.Response, paramLang?: string) { | 28 | static async getDefaultHTMLPage (req: express.Request, res: express.Response, paramLang?: string) { |
29 | const html = await ClientHtml.getIndexHTML(req, res, paramLang) | 29 | const html = paramLang |
30 | ? await ClientHtml.getIndexHTML(req, res, paramLang) | ||
31 | : await ClientHtml.getIndexHTML(req, res) | ||
30 | 32 | ||
31 | let customHtml = ClientHtml.addTitleTag(html) | 33 | let customHtml = ClientHtml.addTitleTag(html) |
32 | customHtml = ClientHtml.addDescriptionTag(customHtml) | 34 | customHtml = ClientHtml.addDescriptionTag(customHtml) |
@@ -98,6 +100,7 @@ export class ClientHtml { | |||
98 | 100 | ||
99 | let html = buffer.toString() | 101 | let html = buffer.toString() |
100 | 102 | ||
103 | if (paramLang) html = ClientHtml.addHtmlLang(html, paramLang) | ||
101 | html = ClientHtml.addCustomCSS(html) | 104 | html = ClientHtml.addCustomCSS(html) |
102 | html = await ClientHtml.addAsyncPluginCSS(html) | 105 | html = await ClientHtml.addAsyncPluginCSS(html) |
103 | 106 | ||
@@ -106,7 +109,7 @@ export class ClientHtml { | |||
106 | return html | 109 | return html |
107 | } | 110 | } |
108 | 111 | ||
109 | private static getIndexPath (req: express.Request, res: express.Response, paramLang?: string) { | 112 | private static getIndexPath (req: express.Request, res: express.Response, paramLang: string) { |
110 | let lang: string | 113 | let lang: string |
111 | 114 | ||
112 | // Check param lang validity | 115 | // Check param lang validity |
@@ -129,6 +132,10 @@ export class ClientHtml { | |||
129 | return join(__dirname, '../../../client/dist/' + buildFileLocale(lang) + '/index.html') | 132 | return join(__dirname, '../../../client/dist/' + buildFileLocale(lang) + '/index.html') |
130 | } | 133 | } |
131 | 134 | ||
135 | private static addHtmlLang (htmlStringPage: string, paramLang: string) { | ||
136 | return htmlStringPage.replace('<html>', `<html lang="${paramLang}">`) | ||
137 | } | ||
138 | |||
132 | private static addTitleTag (htmlStringPage: string, title?: string) { | 139 | private static addTitleTag (htmlStringPage: string, title?: string) { |
133 | let text = title || CONFIG.INSTANCE.NAME | 140 | let text = title || CONFIG.INSTANCE.NAME |
134 | if (title) text += ` - ${CONFIG.INSTANCE.NAME}` | 141 | if (title) text += ` - ${CONFIG.INSTANCE.NAME}` |