Compatibilité des principales couches dans les outils pour les développeurs Chrome

Alina Varkki
Alina Varkki

Les outils pour les développeurs Chrome prennent désormais en charge les éléments de la couche supérieure, ce qui permet aux développeurs de déboguer plus facilement leur code utilisant ces éléments.

Cet article décrit les éléments de la couche supérieure, comment les outils de développement aident à visualiser le contenu de la couche supérieure pour comprendre et déboguer la structure DOM qui contient les éléments de la couche supérieure, et comment la compatibilité avec les couches supérieures des outils de développement est implémentée.

Que sont les éléments de la couche supérieure et des éléments de la couche supérieure ?

Que se passe-t-il exactement en interne lorsque vous ouvrez un <dialog> en tant que fenêtre modale ? 🤔

Il est placé dans une couche supérieure. Le contenu de la couche supérieure s'affiche au-dessus de tout autre contenu. Par exemple, une boîte de dialogue modale doit apparaître au-dessus de tout autre contenu DOM. Ainsi, le navigateur affiche automatiquement cet élément dans un "calque supérieur" au lieu de forcer les auteurs à lutter manuellement contre le z-index. Un élément de la couche supérieure apparaît au-dessus d'un élément, même avec le z-index le plus élevé.

La couche supérieure peut être décrite comme "la couche d'empilement la plus élevée". Chaque document est associé à une seule fenêtre d'affichage et, par conséquent, à un calque supérieur. Plusieurs éléments peuvent se trouver à la fois dans la couche supérieure. Lorsque cela se produit, ils s'empilent les uns sur les autres, le dernier en haut. En d'autres termes, tous les éléments de la couche supérieure sont placés dans une pile LIFO (last in, first out) dans la couche supérieure.

L'élément <dialog> n'est pas le seul élément que le navigateur affiche dans un calque supérieur. Actuellement, les éléments du calque supérieur sont les pop-overs, les boîtes de dialogue modales et les éléments en mode plein écran.

Examinez l'implémentation de la boîte de dialogue suivante:

<main>
  <button onclick="window.dialog.showModal();">Open Dialog</button>
</main>
<dialog id="dialog"></dialog>

Voici une démonstration avec quelques boîtes de dialogue dont le fond est appliqué aux arrière-plans (arrière-plans décrits ci-dessous):

Qu'est-ce qu'un fond ?

Heureusement, il existe un moyen de personnaliser le contenu sous l'élément de la couche supérieure.

Chaque élément de la couche supérieure possède un pseudo-élément CSS appelé backdrop.

Il s'agit d'une zone de la taille de la fenêtre d'affichage qui s'affiche immédiatement sous n'importe quel élément du calque supérieur. Le pseudo-élément ::backdrop permet d'obscurcir, de styliser ou de masquer complètement tout ce qui se trouve en dessous de l'élément lorsqu'il est le plus haut dans la couche supérieure.

Lorsque vous créez plusieurs éléments en mode modal, le navigateur affiche le fond juste en dessous de l'élément situé au premier plan et au-dessus des autres éléments en plein écran.

Voici comment appliquer un style à un fond:

/* The browser displays the backdrop only when the dialog.showModal() function opens the dialog.*/
dialog::backdrop {
    background: rgba(255,0,0,.25);
}

Comment afficher uniquement le premier Backdrop ?

Chaque élément de la couche supérieure a un fond qui appartient à une pile de couches supérieure. Ces arrière-plans sont conçus pour se chevaucher. Par conséquent, si l'opacité d'un arrière-plan n'est pas de 100%, les fonds situés en dessous sont visibles.

Si seul le premier fond de la pile supérieure doit être visible, vous pouvez y parvenir en suivant les identifiants des éléments dans la pile supérieure.

Si l'élément ajouté n'est pas le premier de la couche supérieure, la fonction appelée lorsque l'élément est placé dans la couche supérieure applique une classe hiddenBackdrop à ::backdrop. Cette classe est supprimée lorsque l'élément est retiré de la couche supérieure.

Examinez le code dans cet exemple de démonstration:

Conception d'assistance pour les couches supérieures dans les outils de développement

La compatibilité des outils de développement avec la couche supérieure aide les développeurs à comprendre le concept de la couche supérieure et à visualiser comment celle-ci évolue. Ces fonctionnalités aident les développeurs à identifier les éléments suivants:

  • Les éléments de la couche supérieure à tout moment et leur ordre.
  • Élément situé en haut de la pile à tout moment.

En outre, la compatibilité des couches supérieure avec les outils de développement permet de visualiser la position du pseudo-élément Backdrop dans la pile supérieure. Bien qu'il ne s'agisse pas d'un élément arborescent, il joue un rôle important dans le fonctionnement de la couche supérieure et peut être utile aux développeurs.

Grâce aux fonctionnalités de prise en charge de la couche supérieure, vous pouvez:

  1. Observez à tout moment quels éléments se trouvent dans la pile de la couche supérieure. La pile de représentation de la couche supérieure change de manière dynamique à mesure que des éléments sont ajoutés ou supprimés de la couche supérieure.
  2. Voir la position de l'élément dans la pile de la couche supérieure.
  3. Passez du pseudo-élément Backdrop de l'élément de la couche supérieure ou de l'élément de fond dans l'arborescence au pseudo-élément Backdrop qui se trouve dans le conteneur de représentation de la couche supérieure, puis à l'arrière.

Voyons comment utiliser ces fonctionnalités.

Conteneur de la couche supérieure

Pour vous aider à visualiser les éléments de la couche supérieure, les outils de développement ajoutent un conteneur de la couche supérieure à l'arborescence d'éléments. Il se trouve après la balise de fermeture </html>.

Ce conteneur vous permet d'observer à tout moment les éléments de la pile supérieure. Le conteneur de la couche supérieure est une liste de liens vers les éléments de la couche supérieure et leurs arrière-plans. La pile de représentation de la couche supérieure change de manière dynamique à mesure que des éléments sont ajoutés ou supprimés de la couche supérieure.

Pour trouver les éléments de la couche supérieure dans l'arborescence d'éléments ou le conteneur de la couche supérieure, cliquez sur les liens de la représentation de l'élément de la couche supérieure dans le conteneur de la couche supérieure vers le même élément dans l'arborescence d'éléments, puis vers l'arrière.

Pour passer de l'élément de conteneur de la couche supérieure à l'élément d'arborescence de la couche supérieure, cliquez sur le bouton Afficher à côté de l'élément dans le conteneur de la couche supérieure.

Passer du lien du conteneur de la couche supérieure à l&#39;élément.

Pour passer de l'élément de l'arborescence de la couche supérieure au lien du conteneur de la couche supérieure, cliquez sur le badge Couche supérieure à côté de l'élément.

Passer d&#39;un élément au lien du conteneur de la couche supérieure.

Vous pouvez désactiver n'importe quel badge, y compris celui de la couche supérieure. Pour désactiver les badges, effectuez un clic droit sur le badge, sélectionnez Paramètres du badge, puis décochez les cases des badges que vous souhaitez masquer.

Désactivation du badge.

Ordre des éléments dans la pile supérieure

Le conteneur de la couche supérieure affiche les éléments tels qu'ils apparaissent dans la pile, mais dans l'ordre inverse. La partie supérieure de l'élément de pile est le dernier élément de la liste des éléments du conteneur de la couche supérieure. Cela signifie que le dernier élément de la liste de conteneurs de la couche supérieure est l'élément avec lequel vous pouvez actuellement interagir dans le document.

Les badges situés à côté des éléments de l'arborescence indiquent si les éléments appartiennent à la couche supérieure et contiennent le numéro de position d'un élément dans la pile.

Dans cette capture d'écran, la pile de la couche supérieure se compose de deux éléments, le second en haut de la pile. Si vous supprimez le deuxième élément, le premier est déplacé vers le haut.

Ordre des éléments dans la pile.

Backdrops dans le conteneur de la couche supérieure

Comme indiqué ci-dessus, chaque élément de la couche supérieure possède un pseudo-élément CSS appelé "Backdrop". Vous pouvez styliser cet élément. Il est donc utile de l'inspecter également et de voir sa représentation.

Dans l'arborescence des éléments, un élément Backdrop se trouve avant la balise de fermeture de l'élément auquel il appartient. Toutefois, dans le conteneur de la couche supérieure, un lien Backdrop s'affiche juste au-dessus de l'élément de la couche supérieure auquel il appartient.

Position de la pile Backdrop.

Modifications apportées à l'arborescence DOM

ElementsTreeElement, la classe chargée de créer et de gérer les éléments individuels de l'arborescence DOM dans les outils de développement, n'était pas suffisante pour implémenter un conteneur de couche supérieure.

Pour afficher le conteneur de la couche supérieure en tant que nœud dans l'arborescence, nous avons ajouté une classe qui crée des nœuds d'éléments d'arborescence DevTools. Auparavant, la classe chargée de créer l'arborescence des éléments DevTools initialisé chaque TreeElement avec DOMNode, qui est une classe avec un backendNodeId et d'autres propriétés liées au backend. backendNodeId, à son tour, est attribué sur le backend.

Le nœud de conteneur de la couche supérieure, qui a une liste de liens vers les éléments de la couche supérieure, doit se comporter comme un nœud d'élément d'arborescence standard. Toutefois, ce nœud n'est pas un "réel" nœud DOM et le backend n'a pas besoin de créer le nœud de conteneur de la couche supérieure.

Pour créer un nœud d'interface qui représente la couche supérieure, nous avons ajouté un nouveau type de nœud frontend créé sans DOMNode. Cet élément de conteneur de couche supérieure est le premier nœud d'interface sans DOMNode, ce qui signifie qu'il n'existe que sur l'interface, et que le backend ne le connaît pas. Pour avoir le même comportement que les autres nœuds, nous avons créé une classe TopLayerContainer qui étend la classe UI.TreeOutline.TreeElement en charge du comportement des nœuds frontend.

Pour obtenir l'emplacement souhaité, la classe qui affiche un élément associe TopLayerContainer en tant que frère suivant de la balise <html>.

Un nouveau badge du calque supérieur indique que l'élément se trouve dans le calque supérieur et sert de lien vers le raccourci de cet élément dans l'élément TopLayerContainer.

Conception initiale

Au début, le plan consistait à dupliquer les éléments de la couche supérieure dans le conteneur de la couche supérieure au lieu de créer une liste de liens vers ces éléments. Nous n'avons pas implémenté cette solution en raison du fonctionnement de la récupération des éléments enfants des éléments dans les outils de développement. Chaque élément dispose d'un pointeur parent utilisé pour récupérer les éléments enfants, et il est impossible d'en avoir plusieurs. Par conséquent, nous ne pouvons pas avoir un nœud qui se développe correctement et qui contient tous les enfants à plusieurs endroits de l'arborescence. En général, le système n'a pas été créé en tenant compte des sous-arborescences en double.

La compromission à laquelle nous sommes parvenus consistait à créer des liens vers les nœuds DOM frontend au lieu de dupliquer ces nœuds. La classe chargée de créer des liens vers des éléments dans les outils de développement est ShortcutTreeElement, qui étend la classe UI.TreeOutline.TreeElement. ShortcutTreeElement a le même comportement que les autres éléments d'arborescence DOM des outils de développement, mais ne possède pas de nœud correspondant au niveau du backend et comporte un bouton associé à un ElementsTreeElement. Chaque ShortcutTreeElement au nœud de la couche supérieure possède un ShortcutTreeElement enfant qui est lié à la représentation d'un pseudo-élément ::backdrop dans l'arborescence DOM des outils de développement.

Conception initiale:

Conception initiale.

Modifications apportées au protocole CDP (Chrome DevTools Protocol)

Pour bénéficier de la compatibilité avec la couche supérieure, vous devez modifier le CDP (Chrome DevTools Protocol). CDP sert de protocole de communication entre les outils de développement et Chromium.

Nous devons ajouter les éléments suivants:

  • Commande à appeler depuis l'interface à tout moment.
  • Événement à déclencher sur l'interface depuis le backend.

CDP: commande DOM.getTopLayerElements

Pour afficher les éléments actuels de la couche supérieure, nous avons besoin d'une nouvelle commande CDP expérimentale qui renvoie une liste des ID de nœud des éléments qui se trouvent dans la couche supérieure. Les outils de développement appellent cette commande chaque fois que les outils de développement sont ouverts ou lorsque les éléments de la couche supérieure changent. La commande se présente comme suit :

  # Returns NodeIds of the current top layer elements.
  # Top layer renders closest to the user within a viewport, therefore, its elements always
  # appear on top of all other content.
  experimental command getTopLayerElements
    returns
      # NodeIds of the top layer elements.
      array of NodeId nodeIds

CDP: événement DOM.topLayerElementsUpdated

Pour obtenir la liste à jour des éléments du calque supérieur, chaque modification de ces éléments doit déclencher un événement CDP expérimental. Cet événement informe l'interface de la modification, qui appelle ensuite la commande DOM.getTopLayerElements et reçoit la nouvelle liste d'éléments.

L'événement ressemble à ceci :

  # Called by the change of the top layer elements.
  experimental event topLayerElementsUpdated

Considérations relatives au CDP

Il existait plusieurs options pour implémenter la prise en charge du CDP de la couche supérieure. Nous avons également envisagé de créer un événement qui renverrait la liste des éléments de la couche supérieure au lieu d'informer simplement l'interface de l'ajout ou de la suppression d'un élément de la couche supérieure.

Nous pourrions également créer deux événements au lieu de la commande: topLayerElementAdded et topLayerElementRemoved. Dans ce cas, nous recevions un élément et devrions gérer le tableau des éléments de la couche supérieure au niveau de l'interface.

Actuellement, un événement d'interface appelle la commande getTopLayerElements pour obtenir la liste des éléments mis à jour. Si nous devions envoyer une liste d'éléments ou un élément spécifique ayant provoqué la modification chaque fois qu'un événement est déclenché, nous pourrions éviter une étape d'appel de la commande. Toutefois, dans ce cas, l'interface perd le contrôle des éléments à transférer.

Nous l'avons implémentée de cette manière, car à notre avis, il est préférable que l'interface décide quand demander les nœuds de la couche supérieure. Par exemple, si la couche supérieure est réduite dans l'interface utilisateur ou si l'utilisateur utilise un panneau des outils de développement qui ne comporte pas l'arborescence d'éléments, il n'est pas nécessaire d'obtenir les nœuds supplémentaires qui pourraient être plus loin dans l'arborescence.