Linting di componenti personalizzati con l'endpoint REST

Link to Linting di componenti personalizzati con l'endpoint REST copied to clipboard

Una guida dettagliata all'utilizzo di axe DevTools Linter per il linting di componenti personalizzati con l'endpoint REST

Free Trial
Not for use with personal data

Questo articolo mostra come utilizzare l'endpoint REST di axe DevTools Linter per individuare errori di accessibilità nei componenti personalizzati.

important

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"
}
note

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"
      }
    }
  }
}
important

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"
}
note

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": []
  }
}
important

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>

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:

  1. Se si mappa questo custom-button componente direttamente a un button elemento, non verrà visualizzato alcun contenuto di testo sul pulsante. L'intento dell'autore del componente, tuttavia, è che l'attributo message venga utilizzato come contenuto di testo: <button> *valore dell'attributo message * </button>
  2. 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.

note

Il valore specificato con default dovrebbe essere una stringa.

Vedere anche