Проверка обязательных свойств

aria-query — это специализированная библиотека для работы с ARIA-ролями и свойствами в JavaScript. Она предоставляет структуру данных и утилиты для проверки соответствия элементов DOM спецификациям WAI-ARIA. Центральными объектами библиотеки являются ARIA roles, ARIA properties/attributes, а также mappings, связывающие роли с поддерживаемыми свойствами.

ARIA roles и свойства

В ARIA различают несколько типов ролей:

  • Widget roles — интерактивные элементы (button, checkbox, slider, tab и др.).
  • Document structure roles — структурные элементы документа (article, region, heading).
  • Landmark roles — участки страницы для навигации (banner, main, navigation, complementary).

Каждая роль может иметь обязательные свойства (required properties) и поддерживаемые свойства (supported properties). Обязательные свойства должны присутствовать в элементе DOM, чтобы роль считалась корректно реализованной.

Например, роль slider требует наличие свойства aria-valuemin, aria-valuemax и aria-valuenow. Без этих свойств элемент не будет корректно интерпретирован вспомогательными технологиями.

Структура данных в aria-query

Библиотека предоставляет несколько ключевых коллекций:

  • Roles — карта всех ролей с их характеристиками. Каждая роль описывается объектом с полями:

    • name — название роли
    • requiredProps — список обязательных свойств
    • supportedProps — список дополнительных поддерживаемых свойств
    • abstract — булевое значение, указывающее, что роль абстрактная и не должна использоваться напрямую
  • Properties — карта ARIA-свойств с их типами и допустимыми значениями (string, token, boolean, tristate и др.).

Эти структуры позволяют динамически проверять корректность разметки и валидировать элементы на соответствие спецификации ARIA.

Проверка обязательных свойств

Получение роли элемента

Для проверки обязательных свойств сначала необходимо определить роль элемента. Aria-query предоставляет объект roles с методами для поиска по имени:

import { roles } from 'aria-query';

const role = roles.get('slider'); 
console.log(role.requiredProps); 
// ['aria-valuemin', 'aria-valuemax', 'aria-valuenow']

Если роль не найдена, проверка свойств невозможна, так как нет информации о требованиях.

Валидация DOM-элемента

Для проверки конкретного элемента используется сопоставление его атрибутов с обязательными свойствами роли:

function validateRequiredProps(element) {
  const roleName = element.getAttribute('role');
  const role = roles.get(roleName);
  
  if (!role) return false; // неизвестная роль

  return role.requiredProps.every(prop => element.hasAttribute(prop));
}

const slider = document.querySelector('#volumeSlider');
console.log(validateRequiredProps(slider)); // true или false

Метод every гарантирует, что все обязательные свойства присутствуют, что является ключевым требованием для корректной реализации ARIA-ролей.

Особенности проверки

  1. Абстрактные роли Абстрактные роли (abstract: true) не проверяются на обязательные свойства, так как они не предназначены для использования в DOM. Пример: range — базовая роль для slider и spinbutton.

  2. Наследование свойств Некоторые роли наследуют обязательные свойства от родительских ролей. В aria-query это учитывается через поле superClass. При проверке необходимо учитывать не только requiredProps текущей роли, но и свойства из superClass.

  3. Типы свойств Свойства могут иметь разные типы: string, integer, boolean и token. Для обязательных свойств важна не только их наличность, но и корректность значения. Например, aria-valuenow для slider должен быть числом между aria-valuemin и aria-valuemax.

function validatePropTypes(element, role) {
  return role.requiredProps.every(prop => {
    const value = element.getAttribute(prop);
    const type = role.props[prop]?.type;
    if (!type) return true; // неизвестный тип
    switch(type) {
      case 'integer': return !isNaN(parseInt(value, 10));
      case 'boolean': return value === 'true' || value === 'false';
      default: return typeof value === 'string';
    }
  });
}
  1. Вспомогательные функции aria-query предоставляет готовые объекты для итерации и фильтрации ролей и свойств. Это облегчает автоматическую генерацию проверок, например, для линтеров и тестов доступности.
import { roles } from 'aria-query';

const widgets = Array.from(roles)
  .filter(([name, data]) => data.superClass.has('widget'))
  .map(([name]) => name);

console.log(widgets); 
// ['button', 'checkbox', 'slider', 'tab', ...]

Практическое применение

Проверка обязательных свойств необходима для:

  • Валидации компонентных библиотек UI
  • Автоматической генерации предупреждений линтеров для доступности
  • Тестирования пользовательских интерфейсов на соответствие спецификации WAI-ARIA

Правильная реализация гарантирует, что вспомогательные технологии смогут корректно взаимодействовать с интерактивными элементами, повышая общую доступность интерфейса.

Оптимизация проверки

Для больших приложений рекомендуется кэшировать результаты проверки, чтобы избежать повторных обращений к DOM и коллекциям roles. Также можно создавать универсальные функции-валидаторы для всех виджетов, что упрощает поддержку и тестирование компонентов.

const cachedValidation = new Map();

function isValidElement(element) {
  const roleName = element.getAttribute('role');
  if (cachedValidation.has(roleName)) return cachedValidation.get(roleName);

  const role = roles.get(roleName);
  if (!role) return false;

  const result = role.requiredProps.every(prop => element.hasAttribute(prop));
  cachedValidation.set(roleName, result);
  return result;
}

Эта стратегия позволяет эффективно проверять обязательные свойства даже на больших страницах с множеством интерактивных элементов.