Skip to content

Commit

Permalink
feat(controls): Add WAI-ARIA support
Browse files Browse the repository at this point in the history
Add WAI-ARIA support

videogular#582
  • Loading branch information
Elecash committed Oct 6, 2017
1 parent 369f6cb commit abba642
Show file tree
Hide file tree
Showing 10 changed files with 13,329 additions and 19 deletions.
13,158 changes: 13,158 additions & 0 deletions docs/package-lock.json

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions docs/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,19 @@ <h2 class="section-title">Core Features</h2>
</p>
</div>
</li>
<li>
<input type="radio" name="core-features" id="aria">
<div class="core-features-item">
<label for="aria" class="core-features-label">
WAI-ARIA support
</label>
<p class="core-features-description">
Videogular has out-of-the-box <a href="https://www.w3.org/WAI/intro/aria" target="_blank">WAI-ARIA</a>
support for all buttons like play/pause, mute, fullscreen and more, but also for other components
like track selector, volume, scrub bar and so on.
</p>
</div>
</li>
</ul>
</section>
</article>
Expand Down
2 changes: 2 additions & 0 deletions fonts/videogular.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
line-height: 1;
display: flex;
align-items: center;
justify-content: center;
width: 50px;
font-size: 24px;

/* Better Font Rendering =========== */
Expand Down
25 changes: 23 additions & 2 deletions src/controls/vg-fullscreen/vg-fullscreen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'vg-fullscreen',
encapsulation: ViewEncapsulation.None,
template: `<div class="icon"
template: `
<div class="icon"
[class.vg-icon-fullscreen]="!isFullscreen"
[class.vg-icon-fullscreen_exit]="isFullscreen">
[class.vg-icon-fullscreen_exit]="isFullscreen"
tabindex="0"
role="button"
aria-label="fullscreen button"
[attr.aria-valuetext]="ariaValue">
</div>`,
styles: [ `
vg-fullscreen {
Expand Down Expand Up @@ -41,6 +46,8 @@ export class VgFullscreen implements OnInit, OnDestroy {

subscriptions: Subscription[] = [];

ariaValue = 'normal mode';

constructor(ref: ElementRef, public API: VgAPI, public fsAPI: VgFullscreenAPI) {
this.elem = ref.nativeElement;
this.subscriptions.push(this.fsAPI.onChangeFullscreen.subscribe(this.onChangeFullscreen.bind(this)));
Expand All @@ -60,11 +67,25 @@ export class VgFullscreen implements OnInit, OnDestroy {
}

onChangeFullscreen(fsState: boolean) {
this.ariaValue = fsState ? 'fullscren mode' : 'normal mode';
this.isFullscreen = fsState;
}

@HostListener('click')
onClick() {
this.changeFullscreenState();
}

@HostListener('keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
// On press Enter (13) or Space (32)
if (event.keyCode === 13 || event.keyCode === 32) {
event.preventDefault();
this.changeFullscreenState();
}
}

changeFullscreenState() {
let element = this.target;

if (this.target instanceof VgAPI) {
Expand Down
28 changes: 25 additions & 3 deletions src/controls/vg-mute/vg-mute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'vg-mute',
encapsulation: ViewEncapsulation.None,
template: `<div class="icon"
template: `
<div class="icon"
[class.vg-icon-volume_up]="getVolume() >= 0.75"
[class.vg-icon-volume_down]="getVolume() >= 0.25 && getVolume() < 0.75"
[class.vg-icon-volume_mute]="getVolume() > 0 && getVolume() < 0.25"
[class.vg-icon-volume_off]="getVolume() === 0">
[class.vg-icon-volume_off]="getVolume() === 0"
tabindex="0"
role="button"
aria-label="mute button"
[attr.aria-valuetext]="ariaValue">
</div>`,
styles: [ `
vg-mute {
Expand Down Expand Up @@ -43,6 +48,8 @@ export class VgMute implements OnInit, OnDestroy {

subscriptions: Subscription[] = [];

ariaValue = 'unmuted';

constructor(ref: ElementRef, public API: VgAPI) {
this.elem = ref.nativeElement;
}
Expand All @@ -63,6 +70,19 @@ export class VgMute implements OnInit, OnDestroy {

@HostListener('click')
onClick() {
this.changeMuteState();
}

@HostListener('keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
// On press Enter (13) or Space (32)
if (event.keyCode === 13 || event.keyCode === 32) {
event.preventDefault();
this.changeMuteState();
}
}

changeMuteState() {
let volume = this.getVolume();

if (volume === 0) {
Expand All @@ -75,7 +95,9 @@ export class VgMute implements OnInit, OnDestroy {
}

getVolume() {
return this.target ? this.target.volume : 0;
const volume = this.target ? this.target.volume : 0;
this.ariaValue = volume ? 'unmuted' : 'muted';
return volume;
}

ngOnDestroy() {
Expand Down
27 changes: 24 additions & 3 deletions src/controls/vg-play-pause/vg-play-pause.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'vg-play-pause',
encapsulation: ViewEncapsulation.None,
template: `<div class="icon"
template: `
<div class="icon"
[class.vg-icon-pause]="getState() === 'playing'"
[class.vg-icon-play_arrow]="getState() === 'paused' || getState() === 'ended'">
[class.vg-icon-play_arrow]="getState() === 'paused' || getState() === 'ended'"
tabindex="0"
role="button"
aria-label="play pause button"
[attr.aria-valuetext]="ariaValue">
</div>`,
styles: [ `
vg-play-pause {
Expand Down Expand Up @@ -40,6 +45,8 @@ export class VgPlayPause implements OnInit, OnDestroy {

subscriptions: Subscription[] = [];

ariaValue = VgStates.VG_PAUSED;

constructor(ref: ElementRef, public API: VgAPI) {
this.elem = ref.nativeElement;
}
Expand All @@ -59,6 +66,19 @@ export class VgPlayPause implements OnInit, OnDestroy {

@HostListener('click')
onClick() {
this.playPause();
}

@HostListener('keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
// On press Enter (13) or Space (32)
if (event.keyCode === 13 || event.keyCode === 32) {
event.preventDefault();
this.playPause();
}
}

playPause() {
let state = this.getState();

switch (state) {
Expand All @@ -74,7 +94,8 @@ export class VgPlayPause implements OnInit, OnDestroy {
}

getState() {
return this.target ? this.target.state : VgStates.VG_PAUSED;
this.ariaValue = this.target ? this.target.state : VgStates.VG_PAUSED;
return this.ariaValue;
}

ngOnDestroy() {
Expand Down
34 changes: 32 additions & 2 deletions src/controls/vg-playback-button/vg-playback-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'vg-playback-button',
encapsulation: ViewEncapsulation.None,
template: `{{getPlaybackRate()}}x`,
template: `
<span class="button"
tabindex="0"
role="button"
aria-label="playback speed button"
[attr.aria-valuetext]="ariaValue">
{{getPlaybackRate()}}x
</span>`,
styles: [ `
vg-playback-button {
-webkit-touch-callout: none;
Expand All @@ -22,6 +29,13 @@ import { Subscription } from 'rxjs/Subscription';
line-height: 50px;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
}
vg-playback-button .button {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
}
` ]
})
export class VgPlaybackButton implements OnInit, OnDestroy {
Expand All @@ -35,6 +49,8 @@ export class VgPlaybackButton implements OnInit, OnDestroy {

subscriptions: Subscription[] = [];

ariaValue = 1;

constructor(ref: ElementRef, public API: VgAPI) {
this.elem = ref.nativeElement;
this.playbackValues = [ '0.5', '1.0', '1.5', '2.0' ];
Expand All @@ -56,6 +72,19 @@ export class VgPlaybackButton implements OnInit, OnDestroy {

@HostListener('click')
onClick() {
this.updatePlaybackSpeed();
}

@HostListener('keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
// On press Enter (13) or Space (32)
if (event.keyCode === 13 || event.keyCode === 32) {
event.preventDefault();
this.updatePlaybackSpeed();
}
}

updatePlaybackSpeed() {
this.playbackIndex = ++this.playbackIndex % this.playbackValues.length;

if (this.target instanceof VgAPI) {
Expand All @@ -67,7 +96,8 @@ export class VgPlaybackButton implements OnInit, OnDestroy {
}

getPlaybackRate() {
return this.target ? this.target.playbackRate : 1.0;
this.ariaValue = this.target ? this.target.playbackRate : 1.0;
return this.ariaValue;
}

ngOnDestroy() {
Expand Down
44 changes: 43 additions & 1 deletion src/controls/vg-scrub-bar/vg-scrub-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,27 @@ import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'vg-scrub-bar',
encapsulation: ViewEncapsulation.None,
template: `<ng-content></ng-content>`,
template: `
<div class="scrubBar"
tabindex="0"
role="slider"
aria-label="scrub bar"
aria-level="polite"
[attr.aria-valuenow]="getPercentage()"
aria-valuemin="0"
aria-valuemax="100"
[attr.aria-valuetext]="getPercentage() + '%'">
<ng-content></ng-content>
</div>
`,
styles: [ `
vg-scrub-bar {
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
position: absolute;
width: 100%;
height: 5px;
Expand All @@ -28,6 +46,13 @@ import { Subscription } from 'rxjs/Subscription';
-ms-transition: bottom 1s, opacity 0.5s;
transition: bottom 1s, opacity 0.5s;
}
vg-scrub-bar .scrubBar {
position: relative;
display: flex;
flex-grow: 1;
align-items: center;
}
vg-controls vg-scrub-bar {
position: relative;
Expand Down Expand Up @@ -98,6 +123,7 @@ export class VgScrubBar implements OnInit, OnDestroy {

protected seekMove(offset: number) {
if (this.isSeeking) {
console.log(offset);
let percentage = Math.max(Math.min(offset * 100 / this.elem.scrollWidth, 99.9), 0);
this.target.time.current = percentage * this.target.time.total / 100;
this.target.seekTime(percentage, true);
Expand Down Expand Up @@ -207,6 +233,22 @@ export class VgScrubBar implements OnInit, OnDestroy {
}
}

@HostListener('keydown', ['$event'])
arrowAdjustVolume(event: KeyboardEvent) {
if (event.keyCode === 38 || event.keyCode === 39) {
event.preventDefault();
this.target.seekTime((this.target.time.current + 5000) / 1000, false);
}
else if (event.keyCode === 37 || event.keyCode === 40) {
event.preventDefault();
this.target.seekTime((this.target.time.current - 5000) / 1000, false);
}
}

getPercentage() {
return this.target ? ((this.target.time.current * 100) / this.target.time.total) + '%' : '0%';
}

onHideScrubBar(hide: boolean) {
this.hideScrubBar = hide;
}
Expand Down
13 changes: 7 additions & 6 deletions src/controls/vg-track-selector/vg-track-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ export interface Option {
template: `
<div class="container">
<div class="track-selected"
[class.vg-icon-closed_caption]="!trackSelected">
[class.vg-icon-closed_caption]="!trackSelected">
{{ trackSelected || '' }}
</div>
<select class="trackSelector" (change)="selectTrack($event.target.value)">
<select class="trackSelector"
(change)="selectTrack($event.target.value)"
tabindex="0"
aria-label="track selector"
[attr.aria-valuetext]="ariaValue">
<option
*ngFor="let track of tracks"
*ngFor="let track of tracks"
[value]="track.id"
[selected]="track.selected === true">
{{ track.label }}
Expand Down Expand Up @@ -63,9 +67,6 @@ export interface Option {
color: transparent;
font-size: 16px;
}
vg-track-selector select.trackSelector:focus {
outline: none;
}
vg-track-selector .track-selected {
position: absolute;
width: 100%;
Expand Down
4 changes: 2 additions & 2 deletions src/controls/vg-volume/vg-volume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ export class VgVolume implements OnInit, OnDestroy {

@HostListener('keydown', ['$event'])
arrowAdjustVolume(event: KeyboardEvent) {
if (event.keyCode == 38 || event.keyCode == 39) {
if (event.keyCode === 38 || event.keyCode === 39) {
event.preventDefault();
this.setVolume(Math.max(0, Math.min(100,(this.getVolume() * 100) + 10)));
}
else if (event.keyCode == 37 || event.keyCode == 40) {
else if (event.keyCode === 37 || event.keyCode === 40) {
event.preventDefault();
this.setVolume(Math.max(0, Math.min(100,(this.getVolume() * 100) - 10)));
}
Expand Down

0 comments on commit abba642

Please sign in to comment.