use focus-visible polyfill to improve keyboard navigation
Only the homepage is concerned, but it should have decent keyboard navigation support now.
This commit is contained in:
parent
ecf06378ff
commit
e78980ebd1
12 changed files with 32 additions and 80 deletions
|
@ -159,6 +159,7 @@
|
|||
"webpack-cli": "^3.0.8",
|
||||
"webtorrent": "^0.102.1",
|
||||
"whatwg-fetch": "^2.0.4",
|
||||
"zone.js": "~0.8.5"
|
||||
"zone.js": "~0.8.5",
|
||||
"focus-visible": "^4.1.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<div class="sub-header-container">
|
||||
<my-menu *ngIf="isMenuDisplayed"></my-menu>
|
||||
|
||||
<div id="right-container" class="main-col container-fluid" [ngClass]="{ expanded: isMenuDisplayed === false }">
|
||||
<div id="content" tabindex="-1" class="main-col container-fluid" [ngClass]="{ expanded: isMenuDisplayed === false }">
|
||||
|
||||
<div class="main-row">
|
||||
<router-outlet></router-outlet>
|
||||
|
|
|
@ -6,6 +6,7 @@ import { ResetPasswordModule } from '@app/reset-password'
|
|||
import { MetaLoader, MetaModule, MetaStaticLoader, PageTitlePositioning } from '@ngx-meta/core'
|
||||
import { ClipboardModule } from 'ngx-clipboard'
|
||||
import { HotkeyModule, IHotkeyOptions } from 'angular2-hotkeys'
|
||||
import 'focus-visible'
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module'
|
||||
import { AppComponent } from './app.component'
|
||||
|
|
|
@ -85,10 +85,10 @@
|
|||
|
||||
<div class="footer d-flex justify-content-between">
|
||||
<span class="language">
|
||||
<span (click)="openLanguageChooser()" i18n-title title="Change the language" class="icon icon-language"></span>
|
||||
<span tabindex="0" (keyup.enter)="openLanguageChooser()" (click)="openLanguageChooser()" i18n-title title="Change the language" class="icon icon-language"></span>
|
||||
</span>
|
||||
<span class="color-palette">
|
||||
<span (click)="toggleDarkTheme()" i18n-title title="Toggle dark interface" class="icon icon-moonsun"></span>
|
||||
<span tabindex="0" (keyup.enter)="toggleDarkTheme()" (click)="toggleDarkTheme()" i18n-title title="Toggle dark interface" class="icon icon-moonsun"></span>
|
||||
</span>
|
||||
</div>
|
||||
</menu>
|
||||
|
|
|
@ -130,7 +130,7 @@ menu {
|
|||
transition: background-color .1s ease-in-out;
|
||||
@include disable-default-a-behaviour;
|
||||
|
||||
&:hover {
|
||||
&:hover, &.focus-visible {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
|
@ -202,6 +202,7 @@ menu {
|
|||
font-weight: $font-semibold;
|
||||
|
||||
.icon {
|
||||
@include disable-outline;
|
||||
@include icon(28px);
|
||||
opacity: 0.9;
|
||||
|
||||
|
|
|
@ -48,9 +48,9 @@
|
|||
<my-video-thumbnail [video]="result"></my-video-thumbnail>
|
||||
|
||||
<div class="video-info">
|
||||
<a class="video-info-name" [routerLink]="['/videos/watch', result.uuid]" [attr.title]="result.name">{{ result.name }}</a>
|
||||
<a tabindex="-1" class="video-info-name" [routerLink]="['/videos/watch', result.uuid]" [attr.title]="result.name">{{ result.name }}</a>
|
||||
<span i18n class="video-info-date-views">{{ result.publishedAt | myFromNow }} - {{ result.views | myNumberFormatter }} views</span>
|
||||
<a class="video-info-account" [routerLink]="[ '/accounts', result.byAccount ]">{{ result.byAccount }}</a>
|
||||
<a tabindex="-1" class="video-info-account" [routerLink]="[ '/accounts', result.byAccount ]">{{ result.byAccount }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
<div class="video-miniature-information">
|
||||
<a
|
||||
tabindex="-1"
|
||||
class="video-miniature-name"
|
||||
[routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur() }"
|
||||
>
|
||||
|
@ -11,10 +12,10 @@
|
|||
|
||||
<span i18n class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
|
||||
|
||||
<a *ngIf="displayOwnerAccount()" class="video-miniature-account" [routerLink]="[ '/accounts', video.byAccount ]">
|
||||
<a tabindex="-1" *ngIf="displayOwnerAccount()" class="video-miniature-account" [routerLink]="[ '/accounts', video.byAccount ]">
|
||||
{{ video.byAccount }}
|
||||
</a>
|
||||
<a *ngIf="displayOwnerVideoChannel()" class="video-miniature-channel" [routerLink]="[ '/video-channels', video.byVideoChannel ]">
|
||||
<a tabindex="-1" *ngIf="displayOwnerVideoChannel()" class="video-miniature-channel" [routerLink]="[ '/video-channels', video.byVideoChannel ]">
|
||||
{{ video.byVideoChannel }}
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
@include disable-outline;
|
||||
&.focus-visible {
|
||||
box-shadow: 0 0 0 2px var(--mainColor);
|
||||
}
|
||||
|
||||
img {
|
||||
width: $video-thumbnail-width;
|
||||
height: $video-thumbnail-height;
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
margin-bottom: 20px;
|
||||
|
||||
a {
|
||||
@include disable-default-a-behaviour;
|
||||
&:hover, &:focus:not(.focus-visible), &:active {
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
color: var(--mainForegroundColor);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
}
|
||||
|
||||
@mixin disable-outline {
|
||||
outline: none;
|
||||
&:focus:not(.focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&::-moz-focus-inner {
|
||||
border: 0;
|
||||
|
|
|
@ -189,46 +189,12 @@
|
|||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@angularclass/hmr/-/hmr-2.1.3.tgz#34e658ed3da37f23b0a200e2da5a89be92bb209f"
|
||||
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35":
|
||||
"@babel/code-frame@^7.0.0-beta.35":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8"
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.0.0"
|
||||
|
||||
"@babel/helper-module-imports@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d"
|
||||
dependencies:
|
||||
"@babel/types" "^7.0.0"
|
||||
|
||||
"@babel/helper-module-transforms@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0.tgz#b01ee7d543e81e8c3fc404b19c9f26acb6e4cf4c"
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
"@babel/helper-simple-access" "^7.0.0"
|
||||
"@babel/helper-split-export-declaration" "^7.0.0"
|
||||
"@babel/template" "^7.0.0"
|
||||
"@babel/types" "^7.0.0"
|
||||
lodash "^4.17.10"
|
||||
|
||||
"@babel/helper-plugin-utils@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250"
|
||||
|
||||
"@babel/helper-simple-access@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0.tgz#ff36a27983ae4c27122da2f7f294dced80ecbd08"
|
||||
dependencies:
|
||||
"@babel/template" "^7.0.0"
|
||||
"@babel/types" "^7.0.0"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813"
|
||||
dependencies:
|
||||
"@babel/types" "^7.0.0"
|
||||
|
||||
"@babel/highlight@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4"
|
||||
|
@ -237,34 +203,6 @@
|
|||
esutils "^2.0.2"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0.tgz#697655183394facffb063437ddf52c0277698775"
|
||||
|
||||
"@babel/plugin-transform-modules-commonjs@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0.tgz#20b906e5ab130dd8e456b694a94d9575da0fd41f"
|
||||
dependencies:
|
||||
"@babel/helper-module-transforms" "^7.0.0"
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
"@babel/helper-simple-access" "^7.0.0"
|
||||
|
||||
"@babel/template@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0.tgz#c2bc9870405959c89a9c814376a2ecb247838c80"
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
"@babel/parser" "^7.0.0"
|
||||
"@babel/types" "^7.0.0"
|
||||
|
||||
"@babel/types@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0.tgz#6e191793d3c854d19c6749989e3bc55f0e962118"
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
lodash "^4.17.10"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@neos21/bootstrap3-glyphicons@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@neos21/bootstrap3-glyphicons/-/bootstrap3-glyphicons-1.0.1.tgz#e5eeec43e0153d4b51effd9ecb58cdf7029924d7"
|
||||
|
@ -3299,6 +3237,10 @@ flush-write-stream@^1.0.0:
|
|||
inherits "^2.0.1"
|
||||
readable-stream "^2.0.4"
|
||||
|
||||
focus-visible@^4.1.5:
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/focus-visible/-/focus-visible-4.1.5.tgz#50b44e2e84c24b831ceca3cce84d57c2b311c855"
|
||||
|
||||
follow-redirects@^1.0.0:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.1.tgz#67a8f14f5a1f67f962c2c46469c79eaec0a90291"
|
||||
|
@ -8217,10 +8159,6 @@ to-fast-properties@^1.0.3:
|
|||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
|
||||
to-object-path@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
|
||||
|
|
|
@ -178,7 +178,7 @@ async function isVideoChannelOfAccountExist (channelId: number, user: UserModel,
|
|||
const videoChannel = await VideoChannelModel.loadAndPopulateAccount(channelId)
|
||||
if (videoChannel === null) {
|
||||
res.status(400)
|
||||
.json({ error: 'Unknown video video channel on this instance.' })
|
||||
.json({ error: 'Unknown video `video channel` on this instance.' })
|
||||
.end()
|
||||
|
||||
return false
|
||||
|
@ -191,7 +191,7 @@ async function isVideoChannelOfAccountExist (channelId: number, user: UserModel,
|
|||
const videoChannel = await VideoChannelModel.loadByIdAndAccount(channelId, user.Account.id)
|
||||
if (videoChannel === null) {
|
||||
res.status(400)
|
||||
.json({ error: 'Unknown video video channel for this account.' })
|
||||
.json({ error: 'Unknown video `video channel` for this account.' })
|
||||
.end()
|
||||
|
||||
return false
|
||||
|
|
Loading…
Reference in a new issue