2 votes

Dans Gmail, pourquoi ne peut-on pas cliquer sur le champ "A" avec du javascript ?

Je construis un outil d'accessibilité qui aide les personnes ayant un contrôle moteur limité à écrire des courriels, et j'ai donc besoin d'une focalisation programmatique sur le champ "To" (le premier champ de la fenêtre de composition de Gmail).

J'ai essayé différentes combinaisons des éléments suivants dans le panneau Chrome devtools, sur l'élément textarea et son parent. Rien ne semble faire bouger les choses.

setTimeout(() => {
    let el = document.querySelector('*[name="to"]');
    el.dispatchEvent(new MouseEvent('mouseover', {bubbles: true}));
    el.dispatchEvent(new MouseEvent('mousedown', {bubbles: true}));
    el.focus();
    el.dispatchEvent(new MouseEvent('mouseup', {bubbles: true}));
    el.click();
    console.log('done')
}, 5000)

Voici un exemple du balisage correspondant :

<div class="wO nr l1" style="">
    <input class="wA" tabindex="-1" aria-hidden="true">
    <textarea rows="1" id=":bw" class="vO" name="to" spellcheck="false" autocomplete="false" autocapitalize="off" autocorrect="off" tabindex="1" dir="ltr" aria-label="To" role="combobox" aria-autocomplete="list" style="width: 380px;"></textarea>
    <div class="aA6">
        <span>
            <div tabindex="1" style="background-color: transparent; width: 1px; height: 1px; position: absolute;"></div>
            <div tabindex="1" style="background-color: transparent; width: 1px; height: 1px; position: absolute;"></div>
            <span><span id=":8p" class="aB gQ pE" role="link" tabindex="1" data-tooltip="Add Cc recipients (Ctrl-Shift-C)" aria-label="Add Cc recipients (Ctrl-Shift-C)" style="user-select: none;">Cc</span><span id=":8o" class="aB  gQ pB" role="link" tabindex="1" data-tooltip="Add Bcc recipients (Ctrl-Shift-B)" aria-label="Add Bcc recipients (Ctrl-Shift-B)" style="user-select: none;">Bcc</span><span id=":aw" role="button" tabindex="1" aria-hidden="false" class="bcV Sz" style="display:none" data-tooltip="Some recipients use services that don't support encryption (click for details)" aria-label="Some recipients use services that don't support encryption (click for details)"></span></span><div tabindex="1" style="background-color: transparent; width: 1px; height: 1px; position: absolute;">
            </div>
        </span>
    </div>
</div>

3voto

Ilmari Karonen Points 20585

Lorsqu'ils ne sont pas focalisés, les champs "À", "Cc" et "Cci" de la fenêtre de composition de Gmail sont recouverts par un autre champ intitulé "Destinataires" :

Screenshot

Ce champ "Recipients" possède un gestionnaire d'événement qui le masque automatiquement, affiche les champs "To", "Cc" et "Bcc" et transfère le focus sur l'un d'entre eux. Pour activer le gestionnaire par programme, vous devez d'abord localiser le champ "Destinataires" et lui envoyer un événement de mise au point. Le code suivant a fait l'affaire pour moi sur la console Chrome, bien que je soupçonne que l'ID que j'ai utilisé ne soit pas stable :

let recipients = document.getElementById(':oa');  // not sure if this ID changes
recipients.dispatchEvent(new FocusEvent('focus'));

(Une fois qu'au moins une adresse électronique a été saisie dans les champs "To" / "Cc" / "Bcc", l'apparence du champ "Destinataires" change, cachant l'étiquette et affichant les adresses des destinataires à la place. Cependant, le même code semble toujours fonctionner pour activer le gestionnaire de l'événement "focus").


Ps. L'ID du nœud avec le gestionnaire de focus semble en effet changer. Je ne suis pas sûr de savoir comment le localiser de manière fiable - le code HTML n'offre pas grand-chose qui permette d'accrocher un sélecteur fiable :

<div id=":oa" class="aoD hl" tabindex="1" style="background-color: transparent;">
  <div id=":pm" class="oL aDm" style="">Recipients</div>
  <div id=":o7" class="bgW">
    <span id=":p0" role="button" tabindex="-1" aria-hidden="true" class="bcV Sz" style="display:none" data-tooltip="Some recipients use services that don't support encryption (click for details)" aria-label="Some recipients use services that don't support encryption (click for details)"></span>
  </div>
</div>

Il se peut que vous deviez recourir à des astuces XPath pour le localiser à l'aide du texte de l'étiquette comme ceci :

let recipients = document.evaluate("//div[text()='Recipients']/..", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

Mais même cela ne fonctionnera que si aucun destinataire n'a encore été saisi (lorsqu'il y en a, l'étiquette "Destinataires" est remplacée par la liste des destinataires), et cela risque également de ne pas fonctionner si la langue de l'interface de l'utilisateur n'est pas l'anglais. :(

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X