Linting di componenti personalizzati con l'endpoint REST
Una guida dettagliata all'utilizzo di axe DevTools Linter per il linting di componenti personalizzati con l'endpoint REST
Questo articolo mostra come utilizzare l'endpoint REST di axe DevTools Linter per individuare errori di accessibilità nei componenti personalizzati.
Questo articolo è destinato agli utenti dell'endpoint REST di axe DevTools Linter. Se si utilizza l'estensione axe Accessibility Linter per VS Code o il plugin per JetBrains, vedere Linting di componenti personalizzati con l'estensione axe Accessibility Linter per VS Code o il plugin per JetBrains per ulteriori informazioni.
Prerequisiti
Sarà necessario avere accesso alla versione SaaS o a una versione on-premise di axe DevTools Linter. Per ulteriori informazioni, vedere Ottenimento di una chiave API SaaS per axe DevTools Linter o Configurazione dell'edizione locale di axe DevTools Linter .
Avrai anche bisogno di uno strumento REST che:
- Può inviare richieste POST
- Può aggiungere intestazioni (per la versione SaaS di axe DevTools Linter)
Authorization
- Consente la creazione di corpi di richiesta JSON
Un passaggio passo-passo per il linting dei componenti personalizzati
Quando si utilizza axe DevTools Linter per eseguire il lint del codice sorgente, si fornisce un corpo JSON contenente il codice sorgente e la configurazione nella richiesta HTTP. Ad esempio, il seguente codice HTML mostra l'utilizzo dell'elemento img
:
<img src="path/to/image.jpg"/>
(Questo è un esempio molto semplificato solo per dimostrare il processo di linting, piuttosto che un esempio reale.)
Il corpo JSON della richiesta da inviare ad axe DevTools Linter apparirà così:
{
"source": "<img src=\"path/to/image.jpg\"/>",
"filename": "image-demo.html"
}
Si invia questo JSON a axe DevTools Linter come richiesta REST POST all'endpoint. /linter-source
Per ulteriori informazioni, vedere Lint Endpoint nella documentazione di riferimento.
Per seguire questa procedura dettagliata, puoi utilizzare qualsiasi strumento REST in grado di 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à rilevati da axe DevTools Linter.
Poiché questo img
elemento non ha un attributo alt
, verrà visualizzato 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
L'esempio seguente mostra un componente personalizzato: custom-image
<custom-image src="path/to/image.jpg"></custom-image>
Per inviare l'HTML ad axe DevTools Linter tramite una richiesta POST, utilizzare quanto segue come corpo JSON:
{
"source": "<custom-image src=\"path/to/image.jpg\"></custom-image>",
"filename": "custom-image.html"
}
Il server risponde senza errori di accessibilità perché non c'è alcuna mappatura tra custom-image
e img
, quindi axe DevTools Linter non può segnalare un attributo mancante alt
:
{
"report": {
"errors": []
}
}
Mappatura custom-image
con 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 gli errori di accessibilità. È possibile specificare la mappatura utilizzando l' global-components
opzione di configurazione (parte dell' config
oggetto):
{
"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"
}
]
}
}
È anche possibile indicare la stessa mappatura di cui sopra con una di queste sintassi:
{
"config": {
"global-components": {
"custom-image": {
"element": "img"
}
}
}
}
Oppure, in alternativa, abbreviando element
come el
:
{
"config": {
"global-components": {
"custom-image": {
"el": "img"
}
}
}
}
Quando si utilizza una mappatura degli elementi come quella mostrata sopra, tutti gli attributi del componente personalizzato vengono copiati nell'elemento emesso, il quale viene sottoposto a linting.
Risolvere il problema di accessibilità
Puoi aggiungere un alt
attributo 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 componente personalizzato ha l'attributo richiesto alt
(che è stato copiato, con tutti altri attributi sul custom-image
componente, nell'elemento emesso img
):
{
"report": {
"errors": []
}
}
Mappatura dell'attributo alternative-text
Se invece il componente immagine personalizzato utilizza un attributo diverso per indicare un testo alternativo, è possibile specificare tale attributo nella configurazione. Ad esempio, supponiamo che il tuo componente utilizzi un attributo invece di un altro, come mostrato di seguito: custom-image
alternative-text
alt
<custom-image src="path/to/image.jpg" alternative-text="alt text"></custom-image>
In questo caso, è possibile 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"
}
Si noti che la configurazione differisce leggermente dalla precedente mappatura di un componente personalizzato su un elemento HTML. global-components
Utilizzando solo elementi, si utilizza una mappatura da una stringa ("custom-image") a un'altra stringa ("img"). Con l'inclusione dell'array attributes
, ora è necessario utilizzare la proprietà element
(o el
) per specificare l'elemento HTML emesso.
axe DevTools Linter risponde con quanto segue perché la regola è stata soddisfatta dal vostro attributo. alt-text
alternative-text
{
"report": {
"errors": []
}
}
Poiché hai specificato l'array nella configurazione, quando il server esegue il mapping da a a, solo gli attributi specificati nell'array vengono copiati nell'elemento HTML emesso. attributes
custom-image
img
* attributes
*
Puoi anche abbreviare attributes
come attrs
:
{
"config": {
"global-components": {
"custom-image": {
"attrs": [
{
"alternative-text": "alt"
}
],
"element": "img"
}
}
}
}
Valori degli attributi speciali:, aria-
<element>
<element>
Supponiamo di utilizzare un custom-button
componente 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, nasconderà e mostrerà un div
.)
Ci sono due problemi con questo utilizzo:
- Se si mappa questo
custom-button
componente direttamente a unbutton
elemento, non verrà visualizzato alcun contenuto di testo sul pulsante. L'intento dell'autore del componente, tuttavia, è che l'attributomessage
venga utilizzato come contenuto di testo:<button>
*valore dell'attributomessage
*</button>
- L'elemento emesso ha un ruolo implicito di, quindi l'attributo non è corretto e dovrebbe essere rimosso.
button
button
aria-colindex
Se invii il codice sopra ad axe DevTools Linter (senza "mapping"), si riceve questa risposta: global-components
{
"report": {
"errors": []
}
}
Il valore speciale <text>
Per risolvere il primo problema (contenuto di testo per l'elemento button
proveniente da un attributo message
), è possibile utilizzare il valore speciale <text>
che mappa un attributo al contenuto di testo dell'elemento emesso. In questo caso, il testo dell'attributo message
dovrebbe essere copiato nel contenuto di testo dell'elemento emesso button
.
Per configurare la richiesta per avvisare axe DevTools Linter che l'attributo message
deve essere considerato come contenuto di testo 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 sostituzione del contenuto testuale dell'elemento HTML button
con il valore dell'attributo message
.
Sfortunatamente, utilizzando l' attributes
array, l'unico attributo che veniva passato all'elemento button
emesso era l' message
attributo; tutti gli attributi non presenti nell' attributes
array non venivano passati. Ciò significa che il server non ha rilevato l'errore aria-colindex
.
Utilizzo di aria-*
È possibile utilizzare il valore speciale aria-*
per passare 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 attributo implicito role="button"
e l'uso di questo attributo con i pulsanti non è valido. aria-colindex
Con l'attributo aria-*
, all ARIA attributes are copied to the emitted element; this includes copying the invalid aria-colindex
.
<element>
Nel caso di componenti complessi, in casi specifici potrebbe essere necessario emettere un elemento HTML diverso da quello predefinito. 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>
consente di specificare un attributo sul 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
del componente my-button
indica l'elemento da emettere. Poiché l'elemento emesso img
non contiene un attributo alt
, verrà visualizzato 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 implicito di tutti gli attributi
Tieni presente che se avessi utilizzato solo la mappatura degli elementi (dove la mappatura non utilizza l'array attributes
), tutti gli attributi verrebbero, 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 da custom-button
sono stati controllati per problemi di accessibilità e sono stati 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 riportato mostra che un primo passo pratico quando si inizia a eseguire il lint di componenti personalizzati sarebbe quello di iniziare con una mappatura degli elementi (copiando quindi tutti gli attributi nell'elemento HTML standard emesso) e quindi verificare quali attributi devono essere aggiunti alla configurazione (se gli attributi del componente personalizzato devono essere mappati su attributi diversi o se è necessario utilizzare <text>
o aria-*
).
Attributi predefiniti
Gli attributi predefiniti consentono di impostare i valori per gli attributi nel file di configurazione anziché mappare un attributo su 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. Ciò implica che l'implementazione del componente personalizzato crea questi attributi sull'elemento di output e ne imposta i valori anziché richiedere agli utenti di impostarli quando utilizzano il componente.
Facoltativamente, il valore name
viene impostato su null
nella configurazione, il che fa sì che axe DevTools Linter ignori tutti gli role
attributi che gli utenti hanno specificato custom-menu
nel codice sottoposto a linting.
Il valore specificato con default
dovrebbe essere una stringa.
Vedere anche
- axe DevTools Linter REST API Reference contiene maggiori informazioni sull'utilizzo dei vari endpoint REST forniti da axe DevTools Linter.
- Ottenere una chiave API SaaS per axe DevTools Linter mostra come ottenere una chiave API per utilizzare la versione Software as a Service (SaaS) di axe DevTools Linter.