L’utilisation de Shadow DOM sur une page Web donnée a toujours posé des problèmes aux gestionnaires de mots de passe car les champs « shadow » sont masqués pour les appels DOM normaux, ce qui signifie que le remplissage automatique ne peut pas marcher pour un identifiant de connexion, un formulaire d’adresse, ou toute autre donnée qui pourrait être pertinente pour la page donnée. Grâce aux ingénieurs de Dashlane, cette limitation a été surmontée, ouvrant la voie à une expérience encore meilleure sur un plus large éventail de sites Web qu’auparavant.
Le Shadow DOM est une technologie Web standard mise en œuvre par tous les navigateurs modernes (Chrome, Firefox, Edge, Opera, Safari, sur ordinateur et sur mobile) qui vous permet de compartimenter le markup et les comportements Web. En bref, chaque composant (avec son balisage interne, ses styles et ses comportements basés sur JavaScript) est attaché à un élément hôte (l’hôte fantôme) qui « cache » tout le contenu interne (le DOM fantôme) des appels DOM réguliers. Par exemple, les appels à document.querySelectorAll()
.
Dashlane is a leading Password Manager and data protection provider. Users can install Dashlane on their mobile devices or as an extension to their Web browsers on desktop and laptop computers.
Comment fonctionne un gestionnaire de mots de passe comme Dashlane dans une page Web ?
Tout cela est basé sur la plate-forme Web et en particulier sur les requêtes DOM (Document Object Model) qui nous permettent de parcourir une arborescence de documents, d’interroger des éléments dans cette arborescence, etc.
Comme nous l’avons évoqué en introduction, le contenu interne d’un Shadow DOM est complètement « caché » des appels DOM normaux. Si on prend un Shadow DOM d’hôte <div id= »host »> et contenant par exemple un <input id= »username » class= »loginField »> :
document.querySelector(".loginField")
répondra null
document.getElementById("username")
répondra null
document.getElementById("host").firstElementChild
répondra null
Vous pouvez facilement voir le Shadow DOM en action en utilisant l’inspecteur de votre navigateur préféré. Dans la capture d’écran ci-dessous (Chrome), vous pouvez voir le formulaire de connexion d’une banque bien connue et une vue de son balisage. Celui-ci utilise un Shadow DOM qui est visible dans la capture d’écran de l’inspecteur.
C’est pourquoi tous les gestionnaires de mots de passe sur le marché (jusqu’à récemment), y compris Dashlane, échouent silencieusement mais totalement à analyser et remplir automatiquement les pages Web utilisant un Shadow DOM pour leurs pages de connexion ou d’inscription. Nous ne voyons tout simplement pas ces formulaires via des appels DOM réguliers.
Il y a longtemps, CSS Selectors disposait d’un « shadow-piercing combinator ». Quelle était cette bête ?
Dans une page Web normale, c’est-à-dire une page Web qui n’utilise pas du tout Shadow DOM, vous pouvez sélectionner tous les champs de saisie de texte à l’intérieur d’un élément div via le sélecteur CSS suivant :
div input[type="text"]
Mais, comme nous l’avons vu ci-dessus, si votre document a un <div> contenant un shadow host lui-même contenant un shadow <input type= »text »>, le sélecteur ci-dessus ne le verra pas. Le combinateur /deep/ corrigeait ce manque :
div /deep/
input[type="text"]
Ce sélecteur « perce l’ombre » grâce au combinateur /deep/. Les Shadow boundaries, c’est-à-dire les murs de visibilité entre les Shadow hosts et leur Shadow DOM interne sont traversés par /deep/.
/deep/ était alors parfait pour trouver des formulaires et des champs de formulaire dans toutes les pages Web, y compris celles utilisant Shadow DOM. Malheureusement, /deep/ a été officiellement abandonné et supprimé des implémentations (navigateurs Web) en 2017, invoquant des raisons de performances et, je cite, des « violations d’encapsulation ».
Cette dépréciation a laissé les fournisseurs d’applications tiers comme Dashlane sans option native pour interroger les éléments à l’intérieur d’un Shadow DOM.
Mais Shadow DOM est à la mode ces jours-ci car il est assez pratique pour architecturer un site web en termes de composants réutilisables.
Le nombre de sites Web populaires utilisant Shadow DOM augmente lentement mais régulièrement, ce qui signifie qu’il y avait de plus en plus de pages Web que Dashlane ne pouvait pas remplir automatiquement. Parce que nous nous soucions de l’expérience de nos clients et parce que nous devons faire face au Web dans toute sa diversité glorieuse (et parfois étrange), nous avons dû, à Dashlane, essayer à nouveau de traiter avec des sites Web basés sur Shadow DOM.
Si les requêtes natives de perçage d’ombre ne sont plus possibles, y a-t-il quelque chose que nous puissions faire via JavaScript et d’autres appels réguliers ? En résumé, la réponse est oui.
Nous avons alors commencé à écrire du code simulant le combinateur /deep/ mentionné ci-dessus pour interroger des éléments même s’ils sont contenus dans un Shadow DOM, avec quelques restrictions mineures et inoffensives. L’algorithme de base était simple :
De même, nous avons dû écrire notre propre code pour faire d’autres appels qui traversent les Shadow DOM comme Node.parentNode
ou Node.firstChild.
Ça a marché. Assez bien, en fait. Mais les performances de cette tentative étaient sous-optimales sur les pages Web avec un balisage très complexe ou utilisant des DOM Shadow imbriqués (composants à l’intérieur de composants) car la détection de tous les hôtes Shadow à l’intérieur d’un document n’est pas facile. Il n’y a pas de pseudo-classe CSS qui pourrait nous aider à détecter les Shadow hosts à la vitesse native, par exemple. Un NodeIterator récupérant tous les nœuds de type Element et ayant un attribut shadowRoot non nul est alors le meilleur choix et ce choix peut être coûteux, très coûteux.
Shadow DOM a donc continué d’être un problème pour nous, et pour nos clients.
Quelques mois ont passé et une nouvelle idée a émergé pour soulager la douleur. Nous avons considérablement optimisé l’algorithme ci-dessus pour le rendre beaucoup plus rapide tout en ayant un impact négligeable sur les pages Web n’utilisant pas Shadow DOM. Pour décrire notre paysage actuel, notre moteur de Machine Learning analyse et classe habituellement un formulaire Web ordinaire en 20 millisecondes en moyenne et en 5 millisecondes en pointe… La classification d’un champ de formulaire unique est effectuée après analyse en 160 microsecondes en moyenne… Nous sommes rapides, très rapides.
Au total, cette nouvelle implémentation a atteint un niveau de performances qui la rendait très acceptable du seul point de vue qui compte vraiment, celui du client : impact négligeable sur les pages Web classiques et vitesse plus que raisonnable sur les pages utilisant Shadow DOM.
Quelques conclusions importantes doivent être tirées de cette exploration en deux étapes :
Nous sommes ravis de vous annoncer que Dashlane va désormais encore plus loin dans les pages Web, en trouvant et en reconnaissant les formulaires Web dans les Web components et le Shadow DOM pour vous offrir une expérience de remplissage automatique encore meilleure !