Source: lib/polyfill/aria.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.polyfill.Aria');
  7. goog.require('shaka.log');
  8. goog.require('shaka.polyfill');
  9. /**
  10. * @summary A polyfill to add support for the ARIAMixin interface mixin, for
  11. * browsers that do not implement it (e.g. Firefox).
  12. * Note that IE also does not support ARIAMixin, but this polyfill does not work
  13. * for that platform, as it relies on getters and setters.
  14. * @see https://w3c.github.io/aria/#ARIAMixin
  15. * @see https://developer.mozilla.org/en-US/docs/Web/API/Element
  16. * @export
  17. */
  18. shaka.polyfill.Aria = class {
  19. /**
  20. * Install the polyfill if needed.
  21. * @export
  22. */
  23. static install() {
  24. // eslint-disable-next-line no-restricted-syntax
  25. if (Object.getOwnPropertyDescriptor(Element.prototype, 'ariaHidden')) {
  26. shaka.log.info('Using native ARIAMixin interface.');
  27. return;
  28. }
  29. shaka.log.info('ARIAMixin interface not detected. Installing polyfill.');
  30. // Define a list of all of the ARIAMixin properties that we have externs
  31. // for.
  32. const attributes = [
  33. 'ariaHidden',
  34. 'ariaLabel',
  35. 'ariaPressed',
  36. 'ariaSelected',
  37. ];
  38. // Add each attribute, one by one.
  39. for (const attribute of attributes) {
  40. shaka.polyfill.Aria.addARIAMixinAttribute_(attribute);
  41. }
  42. }
  43. /**
  44. * Adds an attribute with the given name.
  45. * @param {string} name The name of the attribute, in camelCase.
  46. * @private
  47. */
  48. static addARIAMixinAttribute_(name) {
  49. const baseName = name.toLowerCase().replace(/^aria/, '');
  50. // NOTE: All the attributes listed in the method above begin with "aria".
  51. // However, to add extra protection against the possibility of XSS attacks
  52. // through this method, this enforces "aria-" at the beginning of the
  53. // snake-case name, even if somehow "aria" were missing from the input.
  54. const snakeCaseName = `aria-${baseName}`;
  55. /* eslint-disable no-restricted-syntax */
  56. Object.defineProperty(Element.prototype, name, {
  57. get() {
  58. const element = /** @type {!Element} */ (this);
  59. return element.getAttribute(snakeCaseName);
  60. },
  61. set(value) {
  62. const element = /** @type {!Element} */ (this);
  63. if (value == null || value == undefined) {
  64. element.removeAttribute(snakeCaseName);
  65. } else {
  66. element.setAttribute(snakeCaseName, value);
  67. }
  68. },
  69. });
  70. /* eslint-enable no-restricted-syntax */
  71. }
  72. };
  73. shaka.polyfill.register(shaka.polyfill.Aria.install);