Migrate all <img>-based icons to inline SVG via PHP helper

Replace every <img src="/assets/icons/..."> with <?= icon('name') ?>
across 26 template files. The PHP helper inlines the SVG markup into the
DOM so CSS color cascades naturally through fill="currentColor".

- Add src/icon.php helper: reads SVG file, sets width/height to 1em,
  injects aria-hidden, supports optional CSS class
- Fix 12 icon SVGs that had hardcoded fill="#000000" or missing fill attr
- Replace search.svg with Phosphor fill-based magnifying glass
- Add explicit SVG sizes for admin header nav icons (16px/20px)
- Scope public search icon CSS to form[role=search]:not(.header-search-form)
  to avoid breaking admin header layout; change stroke to fill
- Remove <img> filter: brightness(0) invert(1) hacks from admin.css
This commit is contained in:
Pontoporeia
2026-06-21 17:23:37 +02:00
parent b1774e6e97
commit dfde88eaa5
42 changed files with 166 additions and 108 deletions

View File

@@ -45,7 +45,7 @@ if ($totalStale === 0 && $totalFiles === 0): ?>
<div id="tmp-cleanup-stats-wrapper">
<details class="n-section" open>
<summary>
<img src="/assets/icons/paint-brush-household.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('paint-brush-household') ?>
Fichiers temporaires
</summary>
<p style="margin:0;color:var(--accent-green)">✓ Aucun fichier temporaire.</p>
@@ -56,13 +56,13 @@ if ($totalStale === 0 && $totalFiles === 0): ?>
<div id="tmp-cleanup-stats-wrapper">
<details class="n-section" open>
<summary>
<img src="/assets/icons/paint-brush-household.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('paint-brush-household') ?>
Fichiers temporaires <span class="n-meta"><?= htmlspecialchars($summaryMeta) ?></span>
</summary>
<?php if ($fpStale > 0): ?>
<p class="n-heading">
<img src="/assets/icons/paint-brush-household.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('paint-brush-household') ?>
Téléversements abandonnés
</p>
<table class="n-table">
@@ -80,7 +80,7 @@ if ($totalStale === 0 && $totalFiles === 0): ?>
hx-target="#tmp-cleanup-stats-wrapper"
hx-swap="outerHTML"
hx-indicator="#tmp-cleanup-stats-wrapper">
<img src="/assets/icons/trash.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('trash') ?>
Supprimer
</button>
</td>
@@ -92,7 +92,7 @@ if ($totalStale === 0 && $totalFiles === 0): ?>
<?php if ($trStale > 0): ?>
<p class="n-heading">
<img src="/assets/icons/trash.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('trash') ?>
Corbeille
</p>
<table class="n-table">
@@ -110,7 +110,7 @@ if ($totalStale === 0 && $totalFiles === 0): ?>
hx-target="#tmp-cleanup-stats-wrapper"
hx-swap="outerHTML"
hx-indicator="#tmp-cleanup-stats-wrapper">
<img src="/assets/icons/trash.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('trash') ?>
Supprimer
</button>
</td>

View File

@@ -20,7 +20,7 @@ if (!($d['configured'] ?? false)): ?>
<div id="peertube-orphans-wrapper">
<details id="peertube-orphans-col" class="n-section" open>
<summary>
<img src="/assets/icons/video.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('video') ?>
Vidéos PeerTube orphelines
</summary>
<div id="peertube-orphans-stats">
@@ -34,7 +34,7 @@ if (!($d['configured'] ?? false)): ?>
<div id="peertube-orphans-wrapper">
<details id="peertube-orphans-col" class="n-section" open>
<summary>
<img src="/assets/icons/video.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('video') ?>
Vidéos PeerTube orphelines
</summary>
<div id="peertube-orphans-stats">
@@ -47,7 +47,7 @@ if (!($d['configured'] ?? false)): ?>
<div id="peertube-orphans-wrapper">
<details id="peertube-orphans-col" class="n-section" open>
<summary>
<img src="/assets/icons/video.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('video') ?>
Vidéos PeerTube orphelines <span class="n-meta"><?= (int)($d['orphan_count'] ?? 0) ?> vidéos orphelines</span>
</summary>
<div id="peertube-orphans-stats">
@@ -70,7 +70,7 @@ if (!($d['configured'] ?? false)): ?>
hx-swap="outerHTML"
hx-trigger="click"
hx-indicator="#peertube-orphans-wrapper">
<img src="/assets/icons/trash.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('trash') ?>
Supprimer
</button>
</td>
@@ -87,7 +87,7 @@ if (!($d['configured'] ?? false)): ?>
<?php if (($d['stale_count'] ?? 0) > 0): ?>
<details id="peertube-stale-section" class="n-section" open>
<summary>
<img src="/assets/icons/warning-diamond.svg" width="14" height="14" alt="" aria-hidden="true">
<?= icon('warning-diamond') ?>
Références DB obsolètes <span class="n-meta"><?= $d['stale_count'] ?></span>
</summary>
<p style="margin:0 0 var(--space-sm) 0;font-size:0.85em;color:var(--text-secondary)">Ces UUID sont référencés en base de données mais n'existent plus sur la chaîne PeerTube. Les TFE liés affichent des liens morts.</p>

View File

@@ -28,19 +28,19 @@ try {
<strong><span id="langues-selected-count">0</span> langue(s) sélectionnée(s)</strong>
<div class="admin-bulk-btns">
<button type="button" class="btn btn--sm btn--secondary" onclick="languesCancelSelection()" title="Annuler la sélection">
<img src="/assets/icons/x-close.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('x-close') ?>
Annuler
</button>
<button type="button" class="btn btn--sm btn--red admin-btn-delete"
onclick="languesConfirmBulkDelete()"
title="Supprimer les langues sélectionnées">
<img src="/assets/icons/trash.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('trash') ?>
Supprimer
</button>
<button type="button" class="btn btn--sm btn--warning admin-btn-merge"
onclick="languesConfirmBulkMerge()"
title="Fusionner les langues sélectionnées">
<img src="/assets/icons/link-chain.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('link-chain') ?>
Fusionner
</button>
</div>
@@ -74,7 +74,7 @@ try {
<span class="tag-name-cell"><?= htmlspecialchars($lang['name']) ?></span>
<button type="button" class="admin-icon-btn admin-icon-btn--edit" title="Renommer"
onclick="languesStartRename(<?= (int)$lang['id'] ?>)">
<img src="/assets/icons/pencil-note.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('pencil-note') ?>
</button>
</td>
<td class="admin-tags-count" style="width:1%;white-space:nowrap"><?= (int)$lang['thesis_count'] ?></td>
@@ -87,7 +87,7 @@ try {
<input type="hidden" name="language_id" value="<?= (int)$lang['id'] ?>">
<button type="button" class="admin-icon-btn admin-icon-btn--delete" title="Supprimer"
onclick="languesConfirmDelete(this, <?= htmlspecialchars(json_encode($lang['name']), ENT_QUOTES) ?>)">
<img src="/assets/icons/trash.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('trash') ?>
</button>
</form>
</div>

View File

@@ -28,19 +28,19 @@ try {
<strong><span id="motscles-selected-count">0</span> mot(s)-clé(s) sélectionné(s)</strong>
<div class="admin-bulk-btns">
<button type="button" class="btn btn--sm btn--secondary" onclick="motsclesCancelSelection()" title="Annuler la sélection">
<img src="/assets/icons/x-close.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('x-close') ?>
Annuler
</button>
<button type="button" class="btn btn--sm btn--red admin-btn-delete"
onclick="motsclesConfirmBulkDelete()"
title="Supprimer les mots-clés sélectionnés">
<img src="/assets/icons/trash.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('trash') ?>
Supprimer
</button>
<button type="button" class="btn btn--sm btn--warning admin-btn-merge"
onclick="motsclesConfirmBulkMerge()"
title="Fusionner les mots-clés sélectionnés">
<img src="/assets/icons/link-chain.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('link-chain') ?>
Fusionner
</button>
</div>
@@ -74,7 +74,7 @@ try {
<span class="tag-name-cell"><?= htmlspecialchars($tag['name']) ?></span>
<button type="button" class="admin-icon-btn admin-icon-btn--edit" title="Renommer"
onclick="motsclesStartRename(<?= (int)$tag['id'] ?>)">
<img src="/assets/icons/pencil-note.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('pencil-note') ?>
</button>
</td>
<td class="admin-tags-count" style="width:1%;white-space:nowrap"><?= (int)$tag['thesis_count'] ?></td>
@@ -87,7 +87,7 @@ try {
<input type="hidden" name="tag_id" value="<?= (int)$tag['id'] ?>">
<button type="button" class="admin-icon-btn admin-icon-btn--delete" title="Supprimer"
onclick="motsclesConfirmDelete(this, <?= htmlspecialchars(json_encode($tag['name']), ENT_QUOTES) ?>)">
<img src="/assets/icons/trash.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('trash') ?>
</button>
</form>
</div>

View File

@@ -88,18 +88,18 @@ $rootDirs = ['tfe', 'these', 'frart', 'documents', 'theses'];
function fileIcon(string $ext): string {
$ext = strtolower($ext);
if ($ext === 'pdf') {
return '<img src="/assets/icons/file-text-audio.svg" width="24" height="24" alt="" aria-hidden="true">';
return icon('file-text-audio');
}
if (in_array($ext, ['zip', 'tar', 'gz', 'bz2', 'xz', '7z', 'rar'], true)) {
return '<img src="/assets/icons/file-doc.svg" width="24" height="24" alt="" aria-hidden="true">';
return icon('file-doc');
}
// Default text-file icon for all other extensions
return '<img src="/assets/icons/file-lines.svg" width="24" height="24" alt="" aria-hidden="true">';
return icon('file-lines');
}
// SVG folder icon (same for all directories)
function folderIcon(): string {
return '<img src="/assets/icons/folder.svg" width="24" height="24" alt="" aria-hidden="true">';
return icon('folder');
}
?>
<div id="file-browser-container" class="file-browser">

View File

@@ -98,7 +98,7 @@ if (empty($orphans)) {
<?= $v['linkedTo'] !== null ? 'disabled title="Déjà liée au TFE ' . htmlspecialchars($v['linkedTo']) . '"' : '' ?>
>
<span class="file-browser-icon">
<img src="/assets/icons/arrow-circle-left.svg" width="24" height="24" alt="" aria-hidden="true">
<?= icon('arrow-circle-left') ?>
</span>
<span class="file-browser-name"><?= htmlspecialchars($v['name']) ?></span>
<span class="file-browser-size"><?= !empty($v['createdAt']) ? substr($v['createdAt'], 0, 10) : '' ?></span>

View File

@@ -95,7 +95,7 @@ $rows = [
onclick="this.closest('dialog').close()"
title="Fermer"
aria-label="Fermer">
<img src="/assets/icons/x-circle.svg" width="24" height="24" alt="" aria-hidden="true">
<?= icon('x-circle') ?>
</button>
</div>

View File

@@ -32,7 +32,7 @@ try {
<button type="button" class="btn btn--sm btn--warning admin-btn-merge"
onclick="tagsConfirmBulkMerge()"
title="Fusionner les mots-clés sélectionnés">
<img src="/assets/icons/link-chain.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('link-chain') ?>
Fusionner
</button>
</div>
@@ -65,7 +65,7 @@ try {
<span class="tag-name-cell"><?= htmlspecialchars($tag['name']) ?></span>
<button type="button" class="admin-icon-btn admin-icon-btn--edit" title="Renommer"
onclick="tagsStartRename(<?= (int)$tag['id'] ?>)">
<img src="/assets/icons/pencil-note.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('pencil-note') ?>
</button>
</td>
<td class="admin-tags-count" style="width:1%;white-space:nowrap"><?= (int)$tag['thesis_count'] ?></td>
@@ -77,7 +77,7 @@ try {
<input type="hidden" name="tag_id" value="<?= (int)$tag['id'] ?>">
<button type="button" class="admin-icon-btn admin-icon-btn--delete" title="Supprimer"
onclick="tagsConfirmDelete(this, <?= htmlspecialchars(json_encode($tag['name']), ENT_QUOTES) ?>)">
<img src="/assets/icons/trash.svg" width="32" height="32" alt="" aria-hidden="true">
<?= icon('trash') ?>
</button>
</form>
</div>