Analizzare Componenti Personalizzati con l'Endpoint REST
Una guida per utilizzare Axe DevTools Linter per analizzare componenti personalizzati con l'endpoint REST
Questo articolo mostra come utilizzare l'endpoint REST di Axe DevTools Linter per trovare errori di accessibilità nei componenti personalizzati.
Questo articolo è per gli utenti dell'endpoint REST di Axe DevTools Linter. Se utilizzi l'estensione Axe Accessibility Linter per VS Code o il plugin per JetBrains, consulta Analizzare Componenti Personalizzati con l'Estensione Axe Accessibility Linter per VS Code o il Plugin per JetBrains per maggiori informazioni.
Prerequisiti
Avrai bisogno di accedere o alla versione SaaS o a una versione on-premises di Axe DevTools Linter. Consulta Ottenere una Chiave API di Axe DevTools Linter SaaS o Configurare la Versione On-Premises di Axe DevTools Linter per maggiori informazioni.
Avrai anche bisogno di uno strumento REST che:
- Possa inviare richieste POST
- Possa aggiungere intestazioni
Authorization(per la versione SaaS di Axe DevTools Linter) - Permetta di creare corpi di richiesta JSON
Guida all'Analisi di Componenti Personalizzati
Quando utilizzi Axe DevTools Linter per analizzare il codice sorgente, fornisci un corpo JSON contenente il sorgente e la configurazione nella tua richiesta HTTP. Ad esempio, il seguente HTML mostra l'uso dell'elemento img:
<img src="path/to/image.jpg"/>(Questo è un esempio molto semplificato solo per dimostrare l'analisi, piuttosto che un esempio reale.)
Il corpo JSON della richiesta da inviare ad Axe DevTools Linter sarebbe così:
{
"source": "<img src=\"path/to/image.jpg\"/>",
"filename": "image-demo.html"
}Invii questo JSON ad Axe DevTools Linter come una richiesta POST REST all'endpoint /linter-source. Per maggiori informazioni, consulta L'Endpoint di Analisi nella documentazione di riferimento.
Per seguire questa guida, puoi usare qualsiasi strumento REST che possa inviare richieste POST con corpi di richiesta JSON. Gli esempi seguenti mostrano il corpo della richiesta inviato ad Axe DevTools Linter e il corpo della risposta JSON, che mostra gli errori di accessibilità trovati da Axe DevTools Linter.
Poiché questo elemento img non ha un attributo alt, riceverai un errore di accessibilità da Axe DevTools Linter:
{
"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 Immagine Personalizzato
Il seguente esempio mostra un esempio di un componente personalizzato custom-image:
<custom-image src="path/to/image.jpg"></custom-image>Per inviare l'HTML a Axe DevTools Linter utilizzando una richiesta POST, usa il seguente come corpo JSON:
{
"source": "<custom-image src=\"path/to/image.jpg\"></custom-image>",
"filename": "custom-image.html"
}Il server risponde senza errori di accessibilità poiché non c'è alcuna mappatura tra custom-image e img, quindi Axe DevTools Linter non può evidenziare un attributo alt mancante:
{
"report": {
"errors": []
}
}Mappare custom-image a img
Se fornisci una mappatura tra custom-image e img, Axe DevTools Linter può mappare il tuo componente personalizzato come un elemento HTML standard e individuare errori di accessibilità. Puoi specificare la mappatura utilizzando l'opzione di configurazione global-components (parte dell'oggetto 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 ora risponde con quanto segue:
{
"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"
}
]
}
}Puoi anche indicare la stessa mappatura di cui sopra con una di queste sintassi:
{
"config": {
"global-components": {
"custom-image": {
"element": "img"
}
}
}
}Oppure, alternativamente, abbreviando element come el:
{
"config": {
"global-components": {
"custom-image": {
"el": "img"
}
}
}
}Quando utilizzi una mappatura degli elementi come mostrato sopra, tutti gli attributi del componente personalizzato vengono copiati all'elemento emesso, e quell'elemento emesso viene analizzato.
Risoluzione del Problema di Accessibilità
Puoi aggiungere un attributo alt al tuo custom-image per risolvere il problema di accessibilità (come mostrato di seguito con il corpo JSON della richiesta):
{
"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"
}Il server risponde con il seguente array vuoto errors perché il tuo componente personalizzato ha l'attributo richiesto alt (che è stato copiato—insieme a tutti altri attributi sul componente custom-image—all'elemento emesso img):
{
"report": {
"errors": []
}
}Mappare l'Attributo alternative-text
Se il tuo componente immagine personalizzato invece utilizza un attributo diverso per indicare il testo alternativo, puoi specificare quell'attributo nella configurazione. Ad esempio, supponi che il tuo componente custom-image utilizzi un attributo alternative-text invece di alt, come mostrato di seguito:
<custom-image src="path/to/image.jpg" alternative-text="alt text"></custom-image>In questo caso, potresti specificare una mappatura tra l'attributo alternative-text e l'attributo alt come mostrato con l'array attributes nel corpo della richiesta JSON mostrato di seguito:
{
"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"
}Nota che la configurazione global-components differisce leggermente dalla mappatura precedente di un componente personalizzato a un elemento HTML. Con solo elementi, usi una mappatura da una stringa ("custom-image") a un'altra stringa ("img"). Con l'inclusione dell'array attributes, ora devi utilizzare la proprietà element (o el) per specificare l'elemento HTML emesso.
Axe DevTools Linter risponde con quanto segue perché la regola alt-text è stata soddisfatta dal tuo attributo alternative-text:
{
"report": {
"errors": []
}
}Poiché hai specificato l'array attributes nella configurazione, quando il server effettua la mappatura da custom-image a img, solo gli attributi specificati nell'array attributes vengono copiati all'elemento HTML emesso.
Puoi anche abbreviare attributes come attrs:
{
"config": {
"global-components": {
"custom-image": {
"attrs": [
{
"alternative-text": "alt"
}
],
"element": "img"
}
}
}
}Valori Speciali degli Attributi: <text>, aria-* e <element>
Supponiamo che tu utilizzi un componente custom-button come segue:
<custom-button aria-controls="expand-region" aria-expanded="false" aria-colindex="1" message="Show Region"></custom-button>(Il pulsante personalizzato, utilizzando JavaScript e CSS non inclusi qui, mostrerà e nasconderà un div.)
Ci sono due problemi con questo utilizzo:
- Se mappi questo componente
custom-buttondirettamente a un elementobutton, non ci sarà contenuto testuale da mostrare sul pulsante. Tuttavia, l'intento dell'autore del componente è che l'attributomessagedovrebbe essere utilizzato come contenuto testuale:<button>valore dell'attributomessage</button> - L'elemento emesso
buttonha un ruolo implicito dibutton, quindi l'attributoaria-colindexè errato e dovrebbe essere rimosso.
Se invii il codice sopra all'Axe DevTools Linter (senza alcuna mappatura global-components), riceverai questa risposta:
{
"report": {
"errors": []
}
}Il valore speciale <text>
Per affrontare il primo problema (contenuto testuale per l'elemento button proveniente da un attributo message), puoi utilizzare il valore speciale <text> che mappa un attributo al contenuto testuale dell'elemento emesso. In questo caso, il testo dell'attributo message dovrebbe essere copiato nel contenuto testuale dell'elemento button emesso.
Per configurare la richiesta per avvisare Axe DevTools Linter che l'attributo message deve essere considerato come contenuto testuale per l'elemento HTML button, puoi utilizzare il valore speciale <text> e inviare la seguente richiesta:
{
"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"
}Poiché hai definito l'attributo message come <text>, hai detto ad Axe DevTools Linter di considerare quell'attributo come sostituto del contenuto testuale dell'elemento HTML button con il valore dell'attributo message.
Sfortunatamente, utilizzando l'array attributes, l'unico attributo che è stato trasmesso all'elemento button emesso era solo l'attributo message; qualsiasi attributo non presente nell'array attributes non viene trasmesso. Ciò significa che l'errato aria-colindex non è stato rilevato dal server.
Utilizzo di aria-*
Puoi utilizzare il valore speciale aria-* per trasferire tutti gli attributi ARIA, come mostrato di seguito:
{
"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"
}Il server risponde 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"
}
]
}
}Questo errore si verifica perché l'elemento button ha un role="button" implicito e l'utilizzo di aria-colindex non è valido con i pulsanti. Con aria-*, tutti gli attributi ARIA vengono copiati nell'elemento emesso; questo include la copia dell'attributo aria-colindex non valido.
<element>
Con componenti complessi, potresti voler emettere un elemento HTML diverso dall'elemento predefinito in casi specifici. Ad esempio, potresti avere un componente pulsante che in genere si comporta come un pulsante e, in altri stati, come un'immagine segnaposto. Il valore <element> ti consente di specificare un attributo sul tuo componente personalizzato che determina l'elemento emesso.
{
"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>"
}In questo caso, l'attributo use sul componente my-button indica quale elemento emettere. Poiché l'elemento img emesso non contiene un attributo alt, riceverai un errore:
{
"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
}
]
}
}Passaggio di tutti gli attributi implicitamente
Nota che se avessi usato solo la mappatura degli elementi (dove la mappatura non utilizza l'array attributes), tutti gli attributi sarebbero, per impostazione predefinita, copiati nell'elemento button come mostrato di seguito:
{
"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 questa risposta del server, puoi vedere che tutti gli attributi di custom-button vengono verificati per problemi di accessibilità e vengono trovati due errori:
{
"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"
}
]
}
}L'esempio sopra mostra che un primo passo pratico quando si inizia a verificare componenti personalizzati sarebbe quello di partire con una mappatura degli elementi (in questo modo copiando tutti gli attributi all'elemento HTML standard emesso) e poi vedere quali attributi devono essere aggiunti alla configurazione (se gli attributi del componente personalizzato devono essere mappati a diversi attributi o se è necessario utilizzare <text> o aria-*).
Attributi predefiniti
Gli attributi predefiniti ti permettono di impostare i valori per gli attributi nel tuo file di configurazione piuttosto che mappare un attributo a un altro. Ad esempio, la seguente configurazione di esempio mostra un componente custom-menu mappato a un elemento li con un role di menu:
{
"config": {
"global-components": {
"custom-menu": {
"element": "li",
"attributes": [
{
"role": {
"name": null,
"default": "menu"
}
}
]
}
}
}
}Poiché l'attributo role ha un valore predefinito di menu, impostato nel file di configurazione, gli utenti non devono specificare un attributo role quando utilizzano il componente custom-menu nel loro codice. L'implicazione è che l'implementazione del tuo componente personalizzato crea questi attributi sull'elemento di output e imposta i loro valori, piuttosto che richiedere agli utenti di impostarli quando usano il tuo componente.
Opzionalmente, il valore name è impostato a null nella configurazione, il che fa sì che Axe DevTools Linter ignori qualsiasi attributo role che gli utenti hanno specificato su custom-menu nel codice verificato.
Il valore specificato con default dovrebbe essere una stringa.
Analizzare le violazioni dei componenti personalizzati
Quando hai molti componenti personalizzati configurati, può essere difficile capire quali violazioni nella risposta provengono da mappature di componenti personalizzati rispetto all'HTML standard. Aggiungendo "properties": ["customName"] al corpo della richiesta fa sì che Axe DevTools Linter includa una proprietà customName su ogni errore che origina da un componente mappato personalizzato.
Basandosi sull'esempio custom-image sopra, aggiungendo "properties": ["customName"] alla richiesta:
{
"properties": ["customName"],
"config": {
"global-components": {
"custom-image": "img"
}
},
"filename": "c-image.html",
"source": "<custom-image src=\"path/to/image.jpg\"></custom-image>\n\n"
}La risposta ora include una proprietà customName sull'errore che mostra quale componente personalizzato ha innescato la violazione:
{
"report": {
"errors": [
{
"column": 1,
"customName": "custom-image",
"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"
}
]
}
}Gli errori dai componenti che non fanno parte di una mappatura personalizzata non avranno una proprietà customName.
Vedi anche
- Riferimento API REST di Axe DevTools Linter contiene più informazioni sull'utilizzo dei vari endpoint REST forniti da Axe DevTools Linter.
- Ottenere una chiave API per Axe DevTools Linter SaaS mostra come ottenere una chiave API per utilizzare la versione Software as a Service (SaaS) di Axe DevTools Linter.
