mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-14 15:56:38 +03:00
f1c0468f70
### ARIA attributes - Add `aria-hidden="true"` to all decorative SVG icons (`icon.js`) - Implement missing `aria-label` for ad controls (`skip_ad_button.js`, `ad_info.js`) - Add `aria-pressed` to toggle buttons (mute, fullscreen, pip, loop, statistics, remote, stereoscopic) - Remove incorrect `aria-pressed` from one-shot action button (`recenter_vr.js`) - Add `role="menu"`, `aria-haspopup`, `aria-expanded` to menus (`overflow_menu.js`, `settings_menu.js`, `context_menu.js`) - Add `role="menuitemradio"` and `aria-checked` to selection menus (resolution, language, text, playback rate, etc.) - Add `role="toolbar"` to control panel (`controls.js`) - Add `role="heading"` to content title (`content_title.js`) ### Focus management - Restore focus to trigger button when menus close - Maintain focus on fullscreen button after toggle ### CSS - Add `forced-colors` media query for Windows high contrast mode ### Other - Add `alt=""` to seek bar thumbnail image - Add `aria-hidden="true"` to watermark canvas - Add accessibility unit tests for ARIA attributes - Remove redundant `aria-hidden` from checkmark icon (`ui_utils.js`) - Add ARIA terms to project spell-check dictionary Issue https://github.com/shaka-project/shaka-player/issues/3146
142 lines
3.3 KiB
JavaScript
142 lines
3.3 KiB
JavaScript
/*! @license
|
|
* Shaka Player
|
|
* Copyright 2016 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
goog.provide('shaka.ui.Icon');
|
|
|
|
goog.require('shaka.util.Dom');
|
|
|
|
/**
|
|
* @final
|
|
* @export
|
|
*/
|
|
shaka.ui.Icon = class {
|
|
/**
|
|
* @param {?HTMLElement} parent
|
|
* @param {?(shaka.extern.UIIcon | string)=} icon
|
|
*/
|
|
constructor(parent, icon) {
|
|
this.parent = parent;
|
|
|
|
/** @private {!SVGElement} */
|
|
this.svg_ = shaka.util.Dom.createSVGElement('svg');
|
|
|
|
this.svg_.classList.add('shaka-ui-icon');
|
|
// Screen reader should ignore icon text.
|
|
// all icons should have this attribute
|
|
this.svg_.ariaHidden = 'true';
|
|
this.svg_.setAttribute('viewBox', '0 -960 960 960');
|
|
|
|
if (icon) {
|
|
this.use(icon);
|
|
}
|
|
|
|
if (this.parent) {
|
|
parent.appendChild(this.svg_);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If a single string is passed, it is treated as an SVG path
|
|
* @param {shaka.extern.UIIcon | string} icon
|
|
* @export
|
|
*/
|
|
use(icon) {
|
|
// check if it is empty string or null or undefined
|
|
if (!icon) {
|
|
return;
|
|
}
|
|
|
|
// remove all previous path elements
|
|
this.emptyChildNodes_();
|
|
|
|
if (typeof icon == 'string') {
|
|
this.svg_.style.setProperty('font-size', '');
|
|
this.applyInlinedSVG_(icon, null);
|
|
} else if (typeof icon == 'object') {
|
|
const url = icon['url'];
|
|
const path = icon['path'];
|
|
const viewBox = icon['viewBox'];
|
|
const size = icon['size'];
|
|
|
|
this.svg_.style.setProperty('font-size', size ? size + 'px': '');
|
|
|
|
if (url) {
|
|
// let handle the background-color (icon color) by CSS
|
|
this.svg_.style.setProperty('background-color', 'currentColor');
|
|
this.svg_.style.setProperty('mask-image', `url("${url}")`);
|
|
} else if (path) {
|
|
this.applyInlinedSVG_(path, viewBox);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return {!SVGElement}
|
|
* @export
|
|
*/
|
|
getSvgElement() {
|
|
return this.svg_;
|
|
}
|
|
|
|
/**
|
|
* @return {string}
|
|
* @export
|
|
*/
|
|
getDataUrl() {
|
|
const serializer = new XMLSerializer();
|
|
const svgString = serializer.serializeToString(this.svg_);
|
|
const encoded = window.btoa(svgString);
|
|
return `url("data:image/svg+xml;base64,${encoded}")`;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param {string | Array<string>} path
|
|
* @param {?string} viewBox
|
|
* @private
|
|
*/
|
|
applyInlinedSVG_(path, viewBox) {
|
|
// do not need a background color if mask-image isn't using
|
|
this.svg_.style.setProperty('background-color', 'transparent');
|
|
this.svg_.style.setProperty('mask-image', '');
|
|
this.svg_.setAttribute('viewBox', viewBox || '0 -960 960 960');
|
|
|
|
if (Array.isArray(path)) {
|
|
for (let i = 0, l = path.length; i < l; i++) {
|
|
this.addPath_(path[i]);
|
|
}
|
|
} else if (path) {
|
|
this.addPath_(path);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a path element, call `emptyChildNodes()` first to clean previous
|
|
* path elements.
|
|
* @param {string} path
|
|
* @private
|
|
*/
|
|
addPath_(path) {
|
|
const el = shaka.util.Dom.createSVGElement('path');
|
|
el.setAttribute('d', path);
|
|
this.svg_.appendChild(el);
|
|
}
|
|
|
|
/**
|
|
* Remove all the child nodes from svg element
|
|
* @private
|
|
*/
|
|
emptyChildNodes_() {
|
|
const childNodes = this.svg_.childNodes;
|
|
for (let i = 0, l = childNodes.length, child; i < l; i++) {
|
|
child = childNodes[i];
|
|
if (child instanceof SVGPathElement) {
|
|
child.remove();
|
|
}
|
|
}
|
|
}
|
|
};
|