/* ==UserStyle==
@name           12.08 Détection de tabindex
@namespace      www.vayssiere.fr/philippe/accessibilite/stylus
@version        0.2.0
@description    Détecte, signale et compte les tabindex positifs. Également les tabindex nuls ou négatifs.
@author         Philippe Vayssière
@license        AGPL 3.0
==/UserStyle== */

/*
  TABINDEX - Détection des tabindex en tous genres.

  - Détecte les tabindex >0 mais aussi valeur nulle ou sans valeur ou ~chaîne non numérique ou < -1 (avec :not(), entre autres)
  - Affichage assez détaillé en sidebar (à la base même technique que les styles d'A42, avec ici en bonus :has() et le hack CSS toggle custom properties)
    - comptages
    - ❌ ou ✅ (avec la limitation des éléments cachés quand même pris en compte par :has())
  - Montre tous les tabindex avec commentaire selon leur nature

  @date           2023-04-18
*/

* {
  box-sizing: border-box;
}

/*
  Amélioration du message figé à droite avec le "hack" Custom Properties CSS initial et :has().
  Limitation : cela cible aussi les éléments cachés contrairement à CSS counter, donc on peut avoir 0 tabindex avec quand même la croix...
*/
:root {
  --tabindex-gt0-msg: "✅";
}

:root:has([tabindex]:not(:where([tabindex="-1"], [tabindex="0"]))) {
  --tabindex-gt0-msg: "❌";
}

/* Styles communs des messages via ::pseudo */
[tabindex]::after {
  display: inline-block !important;
  padding-inline: 8px;
  font-size: 16px !important;
  font-weight: bold !important;
  color: purple !important;
  background: #f2f2f2 !important;
}

[tabindex] {
  counter-increment: tabindex-total;
  outline: 3px solid blue !important;
}

/* Cible les tabindex positifs (et bizarres) */
[tabindex]:not(:where([tabindex="-1"], [tabindex="0"])) {
  counter-increment: tabindex-gt0 tabindex-total;
  background-image: linear-gradient(30deg, black 0 5%, yellow 0 10%, black 0 15%, yellow 0 20%, transparent 0 100%) !important;
  outline: 3px solid red !important;
}

[tabindex="0"] {
  counter-increment: tabindex-zero tabindex-total;
  outline: 3px solid orange !important;
}

[tabindex="-1"] {
  counter-increment: tabindex-js tabindex-total;
  outline: 3px solid darkgreen !important;
}

[tabindex]:not(:where([tabindex="-1"], [tabindex="0"]))::after {
  content: '⌨ tabindex="' attr(tabindex) '" >0 ❌' !important;
}

/* Weird: negative not being -1 */
[tabindex^="-"]:not([tabindex="-1"])::after {
  content: 'tabindex="' attr(tabindex) '" < -1 ❌' !important;
}

/* Weird: without value or empty string */
[tabindex=""][tabindex=""]::after {
  content: 'tabindex="" ❌ (empty string)' !important;
}

/* Weird value (no value ?? or no digit) */
[tabindex]:not(:is(
  [tabindex*="1"],
  [tabindex*="2"],
  [tabindex*="3"],
  [tabindex*="4"],
  [tabindex*="5"],
  [tabindex*="6"],
  [tabindex*="7"],
  [tabindex*="8"],
  [tabindex*="9"],
  [tabindex*="0"]
))::after {
  content: 'tabindex="' attr(tabindex) '" ❌ (weird value)' !important;
}

/* Comptage */
html {
  counter-reset: tabindex-gt0 tabindex-zero tabindex-js tabindex-total;
}

/* Affichage sur le côté droit */
html::after {
  content:
    counter(tabindex-gt0) " unwelcomed tabindex " var(--tabindex-gt0-msg) "\A(positive, empty or weird values)\A\A"
    "and\A"
    counter(tabindex-zero) " tabindex=\"0\"\A"
    counter(tabindex-js) " tabindex=\"-1\"\A\A"
    "Total " counter(tabindex-total) " tabindex (not hidden)";
  position: fixed !important;
  top: 20vh !important;
  right: 0 !important;
  z-index: 123456 !important;
  white-space: pre !important;
  width: 400px !important;
  min-height: 200px;
  border: 2px solid white;
  border-right: 0;
  padding: 16px !important;
  line-height: 1.2;
  font-family: consolas, monospace !important;
  font-size: 20px !important;
  font-weight: bold;
  letter-spacing: 0.3px;
  color: #fff !important;
  background: purple linear-gradient(to right, #606, purple) !important;
  box-shadow: 0 0 0 2px purple; /* avec border : double bordure blanc / purple */
}
