1
0
Fork 0

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:
Rigel Kent 2018-09-08 14:34:32 +02:00 committed by Chocobozzz
parent ecf06378ff
commit e78980ebd1
12 changed files with 32 additions and 80 deletions

View File

@ -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"
}
}

View File

@ -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>

View File

@ -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'

View File

@ -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>

View File

@ -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;

View File

@ -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>

View File

@ -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>

View File

@ -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;

View File

@ -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);
}

View File

@ -8,7 +8,9 @@
}
@mixin disable-outline {
outline: none;
&:focus:not(.focus-visible) {
outline: none;
}
&::-moz-focus-inner {
border: 0;

View File

@ -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"

View File

@ -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