Linting de componentes personalizados con el endpoint REST
Tutorial sobre cómo usar axe DevTools Linter para lintear componentes personalizados con el punto final REST
Este artículo muestra cómo utilizar el punto final REST de axe DevTools Linter para lintear y encontrar errores de accesibilidad en componentes personalizados.
Este artículo es para los usuarios del punto final REST de axe DevTools Linter. Si usa la extensión axe Accessibility Linter para VS Code o el complemento para JetBrains, consulte Linting de componentes personalizados con la extensión axe Accessibility Linter para VS Code o el complemento para JetBrains para obtener más información.
Prerrequisitos
Necesitará acceso a la versión SaaS o a una versión en las instalaciones de axe DevTools Linter. Consulte Obtener una clave de API SaaS de axe DevTools Linter o Configurar la edición local de axe DevTools Linter para obtener más información.
También necesitarás una herramienta REST que:
- Puede enviar solicitudes POST
- Puede agregar encabezados (para la versión SaaS de axe DevTools Linter)
Authorization
- Permite crear cuerpos de solicitud JSON
Tutorial sobre el linting de componentes personalizados
Cuando usa axe DevTools Linter para realizar linting en el código fuente, proporciona un cuerpo JSON que contiene el código fuente y la configuración en su solicitud HTTP. Por ejemplo, el siguiente HTML muestra el uso del elemento img
:
<img src="path/to/image.jpg"/>
(Este es un ejemplo muy simplificado solo para demostrar el linting en lugar de un ejemplo real).
El cuerpo JSON de la solicitud que se enviará a axe DevTools Linter se vería así:
{
"source": "<img src=\"path/to/image.jpg\"/>",
"filename": "image-demo.html"
}
Envía este JSON a axe DevTools Linter como una solicitud REST POST al endpoint /linter-source
. Para obtener más información, consulte El endpoint de Lint en la documentación de referencia.
Para seguir este tutorial, puede utilizar cualquier herramienta REST que pueda enviar solicitudes POST con cuerpos de solicitud JSON. Los siguientes ejemplos muestran el cuerpo de la solicitud enviada a axe DevTools Linter y el cuerpo de la respuesta JSON, que muestra los errores de accesibilidad encontrados por axe DevTools Linter.
Debido a que este elemento no tiene un atributo, recibirá un error de accesibilidad de axe DevTools Linter: img
alt
{
"report": {
"errors": [
{
"column": 1,
"description": "Ensures <img> elements have alternate text or a role of none or presentation",
"endColumn": 31,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/image-alt?application=axe-linter",
"lineContent": "<img src=\"path/to/image.jpg\"/>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "image-alt"
}
]
}
}
Un componente de imagen personalizado
El siguiente ejemplo muestra un componente personalizado: custom-image
<custom-image src="path/to/image.jpg"></custom-image>
Para enviar el HTML a axe DevTools Linter mediante una solicitud POST, utilice lo siguiente como cuerpo JSON:
{
"source": "<custom-image src=\"path/to/image.jpg\"></custom-image>",
"filename": "custom-image.html"
}
El servidor responde sin errores de accesibilidad porque no hay una asignación entre custom-image
y img
, por lo que axe DevTools Linter no puede marcar la falta de un atributo alt
:
{
"report": {
"errors": []
}
}
Mapeo de custom-image
a img
Si proporciona una asignación entre custom-image
y img
, axe DevTools Linter puede asignar su componente personalizado como un elemento HTML estándar y localizar errores de accesibilidad. Puede especificar la asignación mediante la opción de configuración (parte del objeto): global-components
config
{
"config": {
"global-components": {
"custom-image": "img"
}
},
"filename": "c-image.html",
"source": "<custom-image src=\"path/to/image.jpg\"></custom-image>\n\n"
}
Axe DevTools Linter ahora responde con lo siguiente:
{
"report": {
"errors": [
{
"column": 1,
"description": "Ensures <img> elements have alternate text or a role of none or presentation",
"endColumn": 54,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/image-alt?application=axe-linter",
"lineContent": "<custom-image src=\"path/to/image.jpg\"></custom-image>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "image-alt"
}
]
}
}
También puede indicar la misma asignación que la anterior con cualquiera de estas sintaxis:
{
"config": {
"global-components": {
"custom-image": {
"element": "img"
}
}
}
}
O, alternativamente, abreviando element
como el
:
{
"config": {
"global-components": {
"custom-image": {
"el": "img"
}
}
}
}
Cuando se utiliza una asignación de elementos como la que se muestra arriba, todos los atributos del componente personalizado se copian al elemento emitido, y ese elemento emitido se somete a linting.
Cómo solucionar el problema de la accesibilidad
Puede agregar un atributo a su alt
custom-image
para solucionar el problema de accesibilidad (como se muestra a continuación con el cuerpo JSON de la solicitud):
{
"config": {
"global-components": {
"custom-image": "img"
}
},
"filename": "c-image.html",
"source": "<custom-image src=\"path/to/image.jpg\" alt=\"alt text\"></custom-image>\n\n"
}
El servidor responde con la siguiente matriz vacía porque su componente personalizado tiene el atributo requerido (que se copió, junto con todos los demás atributos del componente, al elemento emitido): errors
alt
** custom-image
img
{
"report": {
"errors": []
}
}
Asignación del atributo alternative-text
Si su componente de imagen personalizado utiliza un atributo diferente para indicar texto alternativo, puede especificar ese atributo en la configuración. Por ejemplo, supongamos que su componente usa un atributo en lugar de otro, como se muestra a continuación: custom-image
alternative-text
alt
<custom-image src="path/to/image.jpg" alternative-text="alt text"></custom-image>
En este caso, puede especificar una asignación entre el atributo alternative-text
y el atributo alt
como se muestra con la matriz attributes
en el cuerpo de la solicitud JSON que se muestra a continuación:
{
"config": {
"global-components": {
"custom-image": {
"element": "img",
"attributes": [
{
"alternative-text": "alt"
}
]
}
}
},
"filename": "c-image.html",
"source": "<custom-image src=\"path/to/image.jpg\" alternative-text=\"alt text\"></custom-image>\n\n"
}
Tenga en cuenta que la configuración difiere ligeramente de la asignación anterior de un componente personalizado a un elemento HTML. global-components
Con elementos, utiliza una asignación de una cadena ("custom-image") a otra cadena ("img"). Con la inclusión de la matriz attributes
, ahora debe utilizar la propiedad element
(o el
) para especificar el elemento HTML emitido.
axe DevTools Linter responde con lo siguiente porque su atributo ha satisfecho la regla: alt-text
alternative-text
{
"report": {
"errors": []
}
}
Debido a que especificó la matriz attributes
en la configuración, cuando el servidor asigna de custom-image
a img
, solo los atributos especificados en la matriz attributes
se copian al elemento HTML emitido.
También puede abreviar attributes
como attrs
:
{
"config": {
"global-components": {
"custom-image": {
"attrs": [
{
"alternative-text": "alt"
}
],
"element": "img"
}
}
}
}
Valores de atributos especiales: <text>
, aria-*
and <element>
Supongamos que utiliza un componente de la siguiente manera: custom-button
<custom-button aria-controls="expand-region" aria-expanded="false" aria-colindex="1" message="Show Region"></custom-button>
(El botón personalizado, utilizando JavaScript y CSS que no están incluidos aquí, ocultará y mostrará un div
.)
Hay dos problemas con este uso:
- Si asigna este componente directamente a un elemento, no se mostrará ningún contenido de texto en el botón.
custom-button
button
Sin embargo, la intención del autor del componente es que el atributomessage
se utilice como contenido de texto:<button>
*valor del atributomessage
*</button>
- El elemento emitido tiene un rol implícito de
button
, por lo que el atributo es incorrecto y debe eliminarse.button
aria-colindex
Si envía el código anterior a axe DevTools Linter (sin asignación), recibirá esta respuesta: global-components
{
"report": {
"errors": []
}
}
El valor especial <text>
Para abordar el primer problema (contenido de texto del elemento que proviene de un atributo), puede utilizar el valor especial que asigna un atributo al contenido de texto del elemento emitido. button
message
<text>
En este caso, el texto del message
atributo debe copiarse al contenido de texto del button
elemento emitido.
Para configurar la solicitud para alertar a axe DevTools Linter de que el atributo message
debe considerarse como contenido de texto para el elemento HTML button
, puede usar el valor especial <text>
y enviar la siguiente solicitud:
{
"config": {
"global-components": {
"custom-button": {
"attributes": [
{
"message": "<text>"
}
],
"element": "button"
}
}
},
"filename": "aria-button.html",
"source": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>\n"
}
Debido a que definió el atributo message
como <text>
, le indicó a axe DevTools Linter que considere ese atributo como reemplazo del contenido textual del elemento HTML button
con el valor del atributo message
.
Desafortunadamente, al usar el array, el único atributo que se pasó al elemento emitido fue el único atributo; cualquier atributo que no esté en el array no se pasa. attributes
button
message
attributes
Esto significa que el servidor no detectó lo incorrecto. aria-colindex
Usando aria-*
Puede utilizar el valor especial aria-*
para pasar todos los atributos ARIA, como se muestra a continuación:
{
"config": {
"global-components": {
"custom-button": {
"attributes": [
{
"message": "<text>"
},
"aria-*"
],
"element": "button"
}
}
},
"filename": "aria-button.html",
"source": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>\n"
}
El servidor responde con:
{
"report": {
"errors": [
{
"column": 1,
"description": "Ensures ARIA attributes are allowed for an element's role",
"endColumn": 124,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/aria-allowed-attr?application=axe-linter",
"lineContent": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "aria-allowed-attr"
}
]
}
}
Este error se produce porque el elemento button
tiene un role="button"
implícito y usar aria-colindex
no es válido con botones. Con atributo aria-*
, all ARIA attributes are copied to the emitted element; this includes copying the invalid aria-colindex
.
<element>
Con componentes complejos, es posible que desees emitir un elemento HTML diferente al elemento predeterminado en casos específicos. Por ejemplo, es posible que tenga un componente de botón que normalmente se comporta como un botón y, en otros estados, como una imagen de marcador de posición. El valor <element>
le permite especificar un atributo en su componente personalizado que determina el elemento emitido.
{
"config": {
"global-components": {
"my-button": {
"element": "button",
"attributes": [
{
"use": "<element>"
},
'src',
'alt'
]
}
}
},
"filename": "aria-button.html",
"source": "<my-button use=\"img\" src=\"globe.jpg\"></my-button>"
}
En este caso, el atributo use
en el componente my-button
indica el elemento a emitir. Debido a que el elemento img
emitido no contiene alt
un atributo, recibirá un error:
{
"report": {
"errors": [
{
"ruleId": "image-alt",
"helpURL": "https://dequeuniversity.com/rules/axe/4.10/image-alt?application=axe-linter",
"description": "Images must have alternative text",
"lineNumber": 1,
"column": 1,
"linterType": "html",
"lineContent": "<my-button use=\"img\" src=\"globe.jpg\"></my-button>",
"endColumn": 50
}
]
}
}
Pasar todos los atributos implícitamente
Tenga en cuenta que si solo hubiera utilizado la asignación de elementos (donde la asignación no utiliza la matriz), todos los atributos se copiarían, de manera predeterminada, al elemento como se muestra a continuación: attributes
button
{
"config": {
"global-components": {
"custom-button": "button"
}
},
"filename": "aria-button.html",
"source": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>\n"
}
Con esta respuesta del servidor, puede ver que todos los atributos de custom-button
se verifican para detectar problemas de accesibilidad y se encuentran dos errores:
{
"report": {
"errors": [
{
"column": 1,
"description": "Ensures ARIA attributes are allowed for an element's role",
"endColumn": 124,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/aria-allowed-attr?application=axe-linter",
"lineContent": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "aria-allowed-attr"
},
{
"column": 1,
"description": "Ensures buttons have discernible text",
"endColumn": 124,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/button-name?application=axe-linter",
"lineContent": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "button-name"
}
]
}
}
El ejemplo anterior muestra que un primer paso práctico al comenzar a analizar componentes personalizados sería comenzar con un mapeo de elementos (copiando así todos los atributos al elemento HTML estándar emitido) y luego ver qué atributos necesitan agregarse a la configuración (si los atributos del componente personalizado deben mapearse a diferentes atributos o si necesita usar <text>
o aria-*
).
Atributos predeterminados
Los atributos predeterminados le permiten establecer valores para los atributos en su archivo de configuración en lugar de asignar un atributo a otro. Por ejemplo, la siguiente configuración de muestra muestra un componente asignado a un elemento con un tipo de menú: custom-menu
li
role
**
{
"config": {
"global-components": {
"custom-menu": {
"element": "li",
"attributes": [
{
"role": {
"name": null,
"default": "menu"
}
}
]
}
}
}
}
Debido a que el atributo role
tiene un valor predeterminado de menú, establecido en el archivo de configuración, los usuarios no necesitan especificar un atributo role
cuando usan el componente custom-menu
en su código. La implicación es que la implementación de su componente personalizado crea estos atributos en el elemento de salida y establece sus valores en lugar de requerir que los usuarios los establezcan cuando usan su componente.
De manera opcional, el valor name
se establece en null
en la configuración, lo que hace que axe DevTools Linter ignore cualquier role
atributos que los usuarios hayan especificado en custom-menu
el código analizado.
El valor especificado con default
debe ser una cadena.
Consulte también
- Referencia de API REST de axe DevTools Linter contiene más información sobre el uso de los distintos puntos finales REST proporcionados por axe DevTools Linter.
- Cómo obtener una clave API SaaS de axe DevTools Linter muestra cómo obtener una clave API para usar la versión de software como servicio (SaaS) de axe DevTools Linter.