rapport de commit pour shaarli-pro: ajout de fichiers CSS et JS personnalisés pour les vues personnalisées, et modifications des fichiers includes.html et page.header.html pour intégrer ces nouvelles fonctionnalités.
This commit is contained in:
parent
209614bb23
commit
1aa05548a8
367
rapport-analyse-theme-shaarli.md
Normal file
367
rapport-analyse-theme-shaarli.md
Normal file
@ -0,0 +1,367 @@
|
||||
# Rapport d'Analyse - Thème Shaarli Professional
|
||||
|
||||
> **Date d'analyse :** 14 février 2026
|
||||
> **Thème analysé :** `shaarli-pro` (Professional v1.0.0)
|
||||
> **Auteur :** Antigravity
|
||||
> **Fichiers analysés :** 39 templates, CSS (~3746 lignes), JS (~1968 lignes)
|
||||
|
||||
---
|
||||
|
||||
## 1. Vue d'ensemble
|
||||
|
||||
Le thème **Professional** est un thème moderne et riche en fonctionnalités pour Shaarli. Il propose :
|
||||
- Layout sidebar + header avec mode clair/sombre
|
||||
- Recherche type "Spotlight"
|
||||
- Trois vues de liens (Grid/List/Compact)
|
||||
- Lecteur média intégré
|
||||
- Vues spéciales pour Tâches et Notes
|
||||
- Multi-sélection avec actions groupées
|
||||
|
||||
---
|
||||
|
||||
## 2. Points Forts ✨
|
||||
|
||||
| Aspect | Évaluation |
|
||||
|--------|------------|
|
||||
| **Architecture CSS** | Variables CSS bien structurées avec support dark/light mode |
|
||||
| **Typographie** | Police Inter (Google Fonts) pour une bonne lisibilité |
|
||||
| **Responsive** | Media queries présentes pour mobile/tablette |
|
||||
| **Accessibilité** | `:focus-visible` implémenté, contraste vérifié |
|
||||
| **Performance** | Lazy loading sur les images, debounce sur la recherche |
|
||||
| **UX** | Animations fluides, feedback visuel, persistance localStorage |
|
||||
| **Modularité** | Code JS séparé en fonctionnalités (custom_views.js) |
|
||||
|
||||
---
|
||||
|
||||
## 3. Problèmes Critiques à Corriger 🚨
|
||||
|
||||
### 3.1 Sécurité - XSS Possible dans la Recherche
|
||||
|
||||
**Fichier :** [`shaarli-pro/js/script.js`](shaarli-pro/js/script.js:63)
|
||||
|
||||
```javascript
|
||||
// LIGNE 63 - Problème : highlightMatch utilise innerHTML sans échappement
|
||||
function highlightMatch(text, query) {
|
||||
if (!query || query.length === 0) return text;
|
||||
const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
const regex = new RegExp(`(${escapedQuery})`, 'gi');
|
||||
return text.replace(regex, '<mark>$1</mark>'); // ⚠️ XSS si text contient du HTML
|
||||
}
|
||||
```
|
||||
|
||||
**Correction recommandée :**
|
||||
```javascript
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
function highlightMatch(text, query) {
|
||||
if (!query || query.length === 0) return escapeHtml(text);
|
||||
const escapedText = escapeHtml(text);
|
||||
const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
const regex = new RegExp(`(${escapedQuery})`, 'gi');
|
||||
return escapedText.replace(regex, '<mark>$1</mark>');
|
||||
}
|
||||
```
|
||||
|
||||
**Priorité :** 🔴 Haute
|
||||
|
||||
---
|
||||
|
||||
### 3.2 CSS - Variables Non Définies dans custom_views.css
|
||||
|
||||
**Fichier :** [`shaarli-pro/css/custom_views.css`](shaarli-pro/css/custom_views.css:29)
|
||||
|
||||
```css
|
||||
/* LIGNES 29-30 - Variables avec fallback mais non définies globalement */
|
||||
.todo-sidebar {
|
||||
background-color: var(--background-secondary, #f8f9fa);
|
||||
border-right: 1px solid var(--border-color, #e2e8f0);
|
||||
```
|
||||
|
||||
**Problème :** Les variables `--background-secondary` et `--border-color` n'existent pas dans [`style.css`](shaarli-pro/css/style.css:10). Seules `--bg-body` et `--border` sont définies.
|
||||
|
||||
**Correction :**
|
||||
```css
|
||||
.todo-sidebar {
|
||||
background-color: var(--bg-sidebar);
|
||||
border-right: 1px solid var(--border);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.3 JS - Injection de Code dans le Lecteur Média
|
||||
|
||||
**Fichier :** [`shaarli-pro/js/script.js`](shaarli-pro/js/script.js:1500)
|
||||
|
||||
Le code généré dynamiquement pour la popup média utilise `document.write` avec des chaînes concaténées, ce qui peut être risqué si le titre contient des caractères spéciaux.
|
||||
|
||||
**Recommandation :** Utiliser `textContent` au lieu d'`innerHTML` pour les titres dynamiques.
|
||||
|
||||
---
|
||||
|
||||
## 4. Problèmes de Maintenabilité 🛠️
|
||||
|
||||
### 4.1 Répartition linguistique incohérente
|
||||
|
||||
**Constat :** Mélange de français et d'anglais dans l'interface :
|
||||
|
||||
| Français | Anglais |
|
||||
|----------|---------|
|
||||
| Épinglés | All Bookmarks |
|
||||
| Mes Tâches | Tag Cloud |
|
||||
| LISTES | Navigation |
|
||||
|
||||
**Recommandation :** Standardiser sur une seule langue ou utiliser le système de traduction de Shaarli avec `{'key'|t}`.
|
||||
|
||||
**Fichiers concernés :**
|
||||
- [`shaarli-pro/page.header.html`](shaarli-pro/page.header.html:24) - Lignes 24, 40, 41, 44
|
||||
- [`shaarli-pro/js/custom_views.js`](shaarli-pro/js/custom_views.js:55)
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Duplication de Code dans le Header
|
||||
|
||||
**Fichier :** [`shaarli-pro/page.header.html`](shaarli-pro/page.header.html:17)
|
||||
|
||||
La navigation est définie deux fois :
|
||||
1. Dans la sidebar (lignes 17-63)
|
||||
2. Dans le header-top (lignes 102-132)
|
||||
|
||||
**Impact :** Difficulté de maintenance, risque d'incohérence.
|
||||
|
||||
**Recommandation :** Créer un template partagé ou générer dynamiquement via JS.
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Sélecteurs CSS Trop Spécifiques
|
||||
|
||||
**Fichier :** [`shaarli-pro/css/style.css`](shaarli-pro/css/style.css:1)
|
||||
|
||||
```css
|
||||
/* Exemple de spécificité excessive */
|
||||
.app-layout .main-content .content-container .linklist .link-outer .link-content .link-header .link-title
|
||||
```
|
||||
|
||||
**Impact :** Difficulté à surcharger les styles, CSS lourd.
|
||||
|
||||
**Recommandation :** Utiliser une méthodologie BEM ou limiter la profondeur à 3 niveaux maximum.
|
||||
|
||||
---
|
||||
|
||||
## 5. Problèmes de Performance ⚡
|
||||
|
||||
### 5.1 CSS Non Minifié et Très Volumineux
|
||||
|
||||
**Constat :** 3746 lignes de CSS non minifié, beaucoup de redondances possibles.
|
||||
|
||||
**Recommandations :**
|
||||
- Utiliser un outil comme PurgeCSS pour éliminer le CSS inutilisé
|
||||
- Minifier le CSS pour la production
|
||||
- Séparer le CSS critique du non-critique
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Requêtes Google Fonts (Blocage potentiel)
|
||||
|
||||
**Fichier :** [`shaarli-pro/css/style.css`](shaarli-pro/css/style.css:2)
|
||||
|
||||
```css
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
||||
```
|
||||
|
||||
**Problème :** `@import` bloque le rendu. Si Google Fonts est indisponible, le site attend.
|
||||
|
||||
**Solution :**
|
||||
```css
|
||||
/* Utiliser font-display: swap et précharger */
|
||||
```
|
||||
|
||||
Ou héberger localement les polices.
|
||||
|
||||
---
|
||||
|
||||
### 5.3 JS - Écouteurs d'Événements Non Nettoyés
|
||||
|
||||
**Fichier :** [`shaarli-pro/js/script.js`](shaarli-pro/js/script.js:1)
|
||||
|
||||
Plusieurs écouteurs sont ajoutés mais jamais supprimés, ce qui peut causer des fuites mémoire sur une SPA.
|
||||
|
||||
---
|
||||
|
||||
## 6. Problèmes d'Accessibilité ♿
|
||||
|
||||
### 6.1 Boutons sans Libellé Accessible
|
||||
|
||||
**Fichier :** [`shaarli-pro/linklist.html`](shaarli-pro/linklist.html:17)
|
||||
|
||||
```html
|
||||
<button class="view-toggle-btn active" id="view-grid-btn" title="Grid">
|
||||
<i class="mdi mdi-view-grid"></i>
|
||||
</button>
|
||||
```
|
||||
|
||||
**Problème :** Pas de `aria-label`, seulement un `title`.
|
||||
|
||||
**Correction :**
|
||||
```html
|
||||
<button class="view-toggle-btn active" id="view-grid-btn" aria-label="Afficher en grille">
|
||||
<i class="mdi mdi-view-grid" aria-hidden="true"></i>
|
||||
</button>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6.2 Contraste de Couleur Insuffisant
|
||||
|
||||
**Fichier :** [`shaarli-pro/css/style.css`](shaarli-pro/css/style.css:36)
|
||||
|
||||
```css
|
||||
.tag-green-text: #065f46; /* Sur fond #d1fae5 = ratio 4.5:1 (limite) */
|
||||
```
|
||||
|
||||
**Recommandation :** Vérifier tous les ratios avec l'outil WebAIM Contrast Checker.
|
||||
|
||||
---
|
||||
|
||||
### 6.3 Formulaire sans Association Label/Input explicite
|
||||
|
||||
**Fichier :** [`shaarli-pro/editlink.html`](shaarli-pro/editlink.html:18)
|
||||
|
||||
Certains champs utilisent des labels mais pas d'attribut `for` explicite ou d'`id` correspondant.
|
||||
|
||||
---
|
||||
|
||||
## 7. Bonnes Pratiques Non Respectées 📋
|
||||
|
||||
### 7.1 Pas de Versioning des Assets
|
||||
|
||||
**Fichier :** [`shaarli-pro/includes.html`](shaarli-pro/includes.html:25)
|
||||
|
||||
```html
|
||||
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/style.css#" />
|
||||
```
|
||||
|
||||
**Problème :** Pas de cache-busting (le `#` ne sert pas à grand-chose).
|
||||
|
||||
**Recommandation :** Ajouter un paramètre de version :
|
||||
```html
|
||||
<link rel="stylesheet" href="{$asset_path}/css/style.css?v={$theme_version}" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7.2 Commentaires en Français et Anglais Mélangés
|
||||
|
||||
**Exemple :**
|
||||
```html
|
||||
<!-- {* ----- barre outils ----- *} -->
|
||||
<!-- {* ----- résultats de recherche par tags ----- *} -->
|
||||
```
|
||||
|
||||
**Recommandation :** Standardiser sur l'anglais pour les commentaires.
|
||||
|
||||
---
|
||||
|
||||
### 7.3 Variables PHP dans les Commentaires HTML
|
||||
|
||||
**Fichier :** [`shaarli-pro/page.header.html`](shaarli-pro/page.header.html:1)
|
||||
|
||||
```html
|
||||
<!--
|
||||
{$isCalledFromBookmarklet=isset($_GET['source']) && $_GET['source'] == 'bookmarklet'}
|
||||
-->
|
||||
```
|
||||
|
||||
**Problème :** Cette logique pourrait être dans le contrôleur plutôt que dans la vue.
|
||||
|
||||
---
|
||||
|
||||
## 8. Améliorations Recommandées ⭐
|
||||
|
||||
### 8.1 Implémenter un Service Worker pour le Offline
|
||||
|
||||
```javascript
|
||||
// Ajouter dans un fichier sw.js
|
||||
self.addEventListener('fetch', event => {
|
||||
// Stratégie cache-first pour les assets statiques
|
||||
});
|
||||
```
|
||||
|
||||
### 8.2 Ajouter des Animations Réduites pour `prefers-reduced-motion`
|
||||
|
||||
```css
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
* {
|
||||
animation-duration: 0.01ms !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8.3 Implémenter un Mode Haut Contraste
|
||||
|
||||
```css
|
||||
@media (prefers-contrast: high) {
|
||||
:root {
|
||||
--border: #000;
|
||||
--text-main: #000;
|
||||
--primary: #0000ff;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8.4 Ajouter des Tests avec Playwright
|
||||
|
||||
Recommandation d'ajouter des tests E2E pour les fonctionnalités critiques :
|
||||
- Changement de thème clair/sombre
|
||||
- Recherche Spotlight
|
||||
- Multi-sélection
|
||||
- Lecteur média
|
||||
|
||||
---
|
||||
|
||||
## 9. Tableau Récapitulatif des Actions
|
||||
|
||||
| Priorité | Problème | Fichier(s) | Effort |
|
||||
|----------|----------|------------|--------|
|
||||
| 🔴 Haute | XSS dans highlightMatch | `js/script.js:63` | 30 min |
|
||||
| 🔴 Haute | Variables CSS inexistantes | `css/custom_views.css:29` | 15 min |
|
||||
| 🟡 Moyenne | Standardiser la langue | `page.header.html`, `custom_views.js` | 1h |
|
||||
| 🟡 Moyenne | Ajouter aria-labels | `linklist.html`, `page.header.html` | 45 min |
|
||||
| 🟡 Moyenne | Nettoyer écouteurs JS | `js/script.js` | 1h30 |
|
||||
| 🟢 Basse | Cache-busting assets | `includes.html` | 15 min |
|
||||
| 🟢 Basse | Réduire spécificité CSS | `css/style.css` | 2h |
|
||||
| 🟢 Basse | Précharger les polices | `includes.html` | 15 min |
|
||||
|
||||
---
|
||||
|
||||
## 10. Métriques du Thème
|
||||
|
||||
| Métrique | Valeur | Recommandation |
|
||||
|----------|--------|----------------|
|
||||
| Taille CSS | ~130 KB | Minifier → ~25 KB |
|
||||
| Taille JS | ~75 KB | Minifier → ~20 KB |
|
||||
| Requêtes externes | 2 (Google Fonts, MDI) | Réduire ou héberger |
|
||||
| Templates HTML | 39 | Bien structuré |
|
||||
| Complexité CSS | Élevée | Refactoriser par composants |
|
||||
|
||||
---
|
||||
|
||||
## 11. Conclusion
|
||||
|
||||
Le thème **Professional** est visuellement abouti et fonctionnellement riche. Cependant, il présente **des failles de sécurité (XSS) à corriger impérativement** avant toute mise en production.
|
||||
|
||||
Les principaux points d'attention sont :
|
||||
1. **Sécurité** - Corriger les failles XSS
|
||||
2. **Accessibilité** - Ajouter les labels ARIA et vérifier les contrastes
|
||||
3. **Performance** - Minifier et optimiser les assets
|
||||
4. **Maintenance** - Standardiser la langue et réduire la duplication
|
||||
|
||||
**Note globale :** 7.5/10 (8.5/10 après corrections des points critiques)
|
||||
|
||||
---
|
||||
|
||||
*Rapport généré automatiquement par analyse statique du code.*
|
||||
Loading…
x
Reference in New Issue
Block a user