# Plan d'amélioration – Shaarli Professional Theme (`shaarli-pro`) > Objectif : transformer le thème actuel, riche en fonctionnalités mais encore très artisanal, en une solution **professionnelle**, **sécurisée**, **maintenable**, **performante** et **accessible**. Ce plan repose sur une analyse statique complète du code (README, rapport d'analyse existant, templates, CSS, JS, comparaison avec le thème `default` officiel de Shaarli). --- ## 1. Synthèse de l'état actuel ### 1.1 Métriques | Fichier / catégorie | Taille | Remarque | |---|---|---| | `js/script.js` | ~3 620 lignes | Thème, navigation, recherche, lecteur, multi-sélection, etc. | | `js/custom_views.js` | ~6 160 lignes | Notes, todos, archive, color picker, background studio | | `js/shaarit-rules.js` | 377 lignes | Règles métier ShaarIt (tags, détection, URLs) | | `css/style.css` | ~4 700 lignes | Design system principal | | `css/custom_views.css` | ~1 780 lignes | Styles des vues notes/todos | | `css/themes.css` | ~1 680 lignes | 16 palettes de couleurs | | Templates HTML | ~40 fichiers | Dont plusieurs non documentés | | Tests / CI / lint | 0 | Aucun outil d'assurance qualité | ### 1.2 Forces à préserver - UI moderne, cohérente, avec sidebar + header. - Mode clair/sombre et système de thèmes multiples. - Fonctionnalités avancées : notes, todos, archive, lecteur média, multi-sélection, recherche Spotlight. - Variables CSS et design system en place. - Utilisation de `localStorage` pour la persistance locale. ### 1.3 Appréciation globale Le thème vaut **~6,5 / 10** en termes de professionnalisation. Il est fonctionnellement abouti, mais accumule de la dette technique : failles XSS potentielles, code monolithique, duplication, dépendances externes non maîtrisées, absence de tests et documentation obsolète. --- ## 2. Problèmes critiques – à traiter en priorité (Phase 1) Ces points bloquent une mise en production professionnelle. ### 2.1 Sécurité | Problème | Fichier(s) | Risque | Action | |---|---|---|---| | **XSS via `innerHTML`** sur descriptions, previews, lecteur popup, tags | `js/script.js` (l. 1547, 1603, 2151…), `js/custom_views.js` (passim) | Exécution de code si un bookmark contient du HTML/JS malveillant | Tout contenu dynamique doit passer par `textContent` ou être échappé avec `escapeHtml`. Remplacer `innerHTML` par `innerText` / création DOM sécurisée. | | **Génération de code JavaScript en chaîne** pour la popup lecteur | `js/script.js` `buildPlayerHTML()` (l. 2523–3053) | Injection possible si titre/URL contiennent des quotes ou du code | Supprimer `buildPlayerHTML()` ; utiliser le template `player.html` existant ou un composant DOM réel. | | **Persistance de la configuration via un bookmark privé** (`shaarit_config`) | `js/script.js` `ShaaritThemeConfig` (l. 7–154) | Fuite de config, pollution de la base, risque si un attaquant crée un bookmark avec ce tag | Remplacer par `localStorage` uniquement, ou par un vrai plugin backend dédié. | | **URLs internes fixes vers `shaarit.app`** | `js/shaarit-rules.js` (l. 142–148), `js/script.js`, `migrate-todos.php` | Dépendance externe, fuite de données, rupture si le domaine change | Rendre les schémas d'URLs internes configurables (`note://`, `todo://`, ou URLs relatives). | | **Script PHP de migration dans le thème** | `migrate-todos.php` | Modification directe de la base, pas de contrôle d'accès, exécutable via web | Supprimer du thème ; en faire un plugin admin ou un script CLI documenté hors `tpl/`. | | **`descEl.innerHTML` utilisé comme source de Markdown** | `js/custom_views.js` (l. 2422, 2492, 4239) | Récupère le HTML rendu par Shaarli, potentiellement exécutable | Utiliser `textContent` comme source unique. | ### 2.2 Bugs et instabilités | Problème | Fichier(s) | Action | |---|---|---| | **`player.html` n'est jamais utilisé** mais dupliqué en JS | `player.html`, `js/script.js` | Supprimer `player.html` si inutile, ou l'utiliser comme cible de la popup. | | **Template officiel `pluginscontent.html` absent** | `tpl/default/pluginscontent.html` | Ajouter `pluginscontent.html` pour ne pas casser les plugins qui utilisent `plugin_content`. | | **Gestion d'erreurs `fetch` insuffisante** | `js/script.js`, `js/custom_views.js` | Ajouter des `try/catch`, vérifier `response.ok`, informer l'utilisateur en cas d'échec. | | **Écouteurs d'événements ajoutés mais jamais supprimés** | `js/script.js` (102 `addEventListener`), `js/custom_views.js` (104) | Nettoyer les listeners dans les modales, popups, sidebars mobile. | | **`tools_plugin` inclus deux fois** | `tools.html` (l. 217 et 283) | Ne garder qu'une seule zone. | | **Hidden tags stockés uniquement dans `localStorage`** | `hidden-tags.html`, `tools.html` | Per-browser, non synchronisés. Persister côté serveur (plugin) ou au minimum documenter la limitation. | | **Sélecteurs DOM très longs et fragiles** | `css/style.css`, JS | Raccourcir et utiliser des classes sémantiques (BEM ou équivalent). | ### 2.3 Compatibilité avec Shaarli officiel - Le thème `default` utilise `{$version_hash}` pour le cache-busting ; `shaarli-pro` utilise des versions codées en dur (`v=1.0.5`, etc.) qui ne correspondent pas à `theme_info.php` (`1.0.0`). - OpenGraph et `apple-touch-icon` sont absents du `includes.html` alors que le thème officiel les fournit. - Les templates officiels utilisent systématiquement `{'key'|t}` pour l'internationalisation ; `shaarli-pro` mélange français, anglais et textes en dur. --- ## 3. Points non finis / fonctionnalités à finaliser ### 3.1 Vue Archive - `initArchiveView()` existe (`js/custom_views.js`) mais l'expérience semble moins aboutie que Notes/Todos (moins de styles dédiés, pas de création d'archive explicite). - **Action** : finaliser l'UI archive ou fusionner avec une fonction "archiver" depuis la vue Notes. ### 3.2 Gestion des tags cachés - Double implémentation : `hidden-tags.html` et le panneau dans `tools.html`. - La logique est dupliquée entre `js/script.js` (chargement) et le script inline de `hidden-tags.html`. - **Action** : centraliser la liste des tags système, définir une source unique (idéalement côté serveur via un plugin). ### 3.3 Lecteur média - Le lecteur inline et la popup partagent un état via `localStorage` et `BroadcastChannel`, ce qui est complexe. - `player.html` n'est pas utilisé. - **Action** : choisir une architecture unique (inline OU popup via un vrai template) et la stabiliser. ### 3.4 Panneau des thèmes - `themes.css` charge 16 palettes (37 Ko) même si l'utilisateur n'en utilise qu'une. - **Action** : charger dynamiquement le CSS du thème actif, ou au minimum splitter `themes.css` par thème. ### 3.5 README et documentation - Le README annonce une "Structure du Projet" incomplète : il omet `custom_views.js/css`, `themes.css`, `player.html`, `hidden-tags.html`, `install.html`, `migrate-todos.php`, `shaarit-rules.js`, `backgrounds-manifest.json`, les fonds d'écran `note-bg-*`. - **Action** : réécrire le README, ajouter un CHANGELOG et un guide de contribution. --- ## 4. Axes d'amélioration structurants ### 4.1 Qualité et maintenabilité du code 1. **Modulariser le JavaScript** - Découper `script.js` en modules thématiques : `theme.js`, `search.js`, `media-player.js`, `bulk-actions.js`, `editor.js`, `mobile-nav.js`. - Découper `custom_views.js` en : `notes.js`, `todos.js`, `archive.js`, `palette.js`, `background-studio.js`. 2. **Supprimer les `console.log` de debug** (calendar, pin, theme sync, etc.). 3. **Uniformiser la gestion des erreurs** : toutes les fonctions `async` doivent avoir un `try/catch` et un retour utilisateur. 4. **Réduire la spécificité CSS** : éviter les sélecteurs de plus de 3 niveaux, nettoyer les `!important` (26 dans `custom_views.css`). 5. **Dédupliquer la navigation** sidebar / header, soit via un template partagé, soit via génération JS à partir d'un tableau de liens. ### 4.2 Performance 1. **Mettre en place un build frontend** (Vite, Webpack ou Rollup) pour : - minifier JS/CSS, - splitter les thèmes, - ajouter des hashes de cache-busting, - héberger localement les polices et les icônes si possible. 2. **Charger `custom_views.js` uniquement sur les pages concernées** (actuellement chargé partout via `includes.html`). 3. **Remplacer l'`@import` Google Fonts** par un `` ou des polices locales. 4. **Optimiser les images** de fond (`note-bg-*`) : WebP/AVIF, redimensionnement, lazy-loading. 5. **Supprimer le CSS mort** avec un outil comme PurgeCSS ou un audit manuel des classes. ### 4.3 Accessibilité (a11y) 1. **Rendre les modales focus-trap** (recherche, filtres, QR code, notes, todos). 2. **Utiliser `aria-selected`** sur les boutons de mode de recherche et les onglets. 3. **Ajouter `prefers-reduced-motion`** pour désactiver les animations. 4. **Vérifier tous les contrastes** (notamment `--tag-green-text` signalé comme limite). 5. **Ajouter des skip-links** et s'assurer que tous les boutons icônes ont un `aria-label` explicite. 6. **Remplacer les emojis utilisés comme indicateurs** (📌 dans `linklist.html`) par des icônes sémantiques. ### 4.4 Internationalisation (i18n) 1. **Extraire toutes les chaînes** des templates vers le format Shaarli : `{'Ma clé'|t}`. 2. Faire de même pour les textes générés en JS (labels de boutons, messages d'erreur, placeholders). 3. Documenter les nouvelles clés de traduction ajoutées. ### 4.5 Architecture des fonctionnalités ShaarIt 1. **Rendre les règles ShaarIt configurables** : le serveur Shaarli, pas `shaarit.app`, doit être la source de vérité pour les URLs internes. 2. **Ne plus utiliser des tags comme base de données** pour stocker la config thème ; utiliser `localStorage` ou un plugin backend. 3. **Réfléchir à un backend dédié** pour notes/todos (plugin PHP) afin d'éviter les contournements par bookmarks et `fetch` sur les formulaires d'édition. --- ## 5. Nouvelles idées à intégrer (par ordre de valeur) | Idée | Intérêt | Complexité | |---|---|---| | **Service Worker / PWA** (offline, manifest, icônes) | Professionnalisation forte, usage mobile | Moyenne | | **Tests E2E avec Playwright** (recherche, thème, multi-sélection, lecteur) | Garantie de non-régression | Moyenne | | **CI/CD GitHub Actions** (lint, build, tests, release) | Qualité continue | Faible | | **ESLint + Stylelint + Prettier** | Maintenabilité, style cohérent | Faible | | **Mode haut contraste** (`prefers-contrast`) | Accessibilité | Faible | | **Amélioration du lecteur** : playlist, historique, gestion des erreurs | UX | Moyenne | | **Recherche serveur** pour les grosses collections (au lieu de parser le DOM) | Performance | Moyenne/forte | | **API côté serveur** pour notes/todos/tags cachés | Sécurité, fiabilité | Forte | | **Dashboard de statistiques** plus riche dans Tools | UX | Moyenne | | **Documentation technique auto-générée** (JSDoc, Storybook-like) | Maintenabilité | Moyenne | --- ## 6. Roadmap recommandée ### Phase 1 – Sécurité et stabilité (2 à 3 semaines) - [ ] Audit XSS : remplacer tous les `innerHTML` à risque par du DOM sécurisé. - [ ] Supprimer ou sécuriser `buildPlayerHTML()` ; utiliser `player.html` ou un composant DOM. - [ ] Retirer `migrate-todos.php` du thème (plugin/CLI séparé). - [ ] Remplacer la persistance "bookmark config" par `localStorage` pur ou un plugin backend. - [ ] Ajouter le template `pluginscontent.html` manquant. - [ ] Nettoyer les `console.log` de debug. - [ ] Gestion d'erreurs robuste sur tous les `fetch`. - [ ] Tests manuels complets sur une instance Shaarli propre. ### Phase 2 – Qualité et maintenabilité (2 à 3 semaines) - [ ] Découper `script.js` et `custom_views.js` en modules thématiques. - [ ] Refactoriser la navigation sidebar/header pour supprimer la duplication. - [ ] Unifier le CSS variables et supprimer les variables mortes. - [ ] Extraire les textes en dur vers `{'key'|t}`. - [ ] Mettre en place ESLint + Stylelint + Prettier. - [ ] Réécrire le README et ajouter un CHANGELOG. ### Phase 3 – Performance et accessibilité (1 à 2 semaines) - [ ] Mettre en place un build (minification, hash, split des thèmes). - [ ] Charger `custom_views.js` à la demande. - [ ] Optimiser les polices et icônes (local/swap). - [ ] Audit a11y complet (modales, contrastes, reduced-motion). - [ ] Optimiser les images de fond. ### Phase 4 – Évolutions (selon les priorités utilisateur) - [ ] PWA / Service Worker. - [ ] Tests E2E Playwright. - [ ] CI/CD GitHub Actions. - [ ] Backend plugin pour notes/todos/config. - [ ] Améliorations du lecteur (playlist, historique). --- ## 7. Critères de validation Pour considérer le thème comme professionnel, les critères suivants doivent être atteints : 1. **Sécurité** : aucune alerte critique (XSS, injection, `eval`, `document.write`) ; contenu utilisateur toujours échappé. 2. **Stabilité** : aucune erreur JS en console sur les parcours principaux (login, liste, ajout, édition, recherche, notes, todos, tools). 3. **Compatibilité** : tous les templates officiels sont présents ou justifiés ; les plugins standard fonctionnent. 4. **Performance** : score Lighthouse > 90 sur Performance et Accessibilité (sur une instance de référence). 5. **Maintenabilité** : code modularisé, linté, documenté. 6. **Internationalisation** : toutes les chaînes utilisateur passent par le système de traduction Shaarli. 7. **Tests** : tests E2E critiques passants (recherche, multi-sélection, changement de thème, lecteur). --- ## 8. Premières actions immédiates (si vous voulez démarrer demain) 1. Corriger les failles XSS dans `js/script.js::renderResults`, `js/custom_views.js` et la popup lecteur. 2. Supprimer `migrate-todos.php` du dossier thème. 3. Décider de l'avenir de la persistance thème : `localStorage` uniquement ou plugin backend ? 4. Créer `pluginscontent.html`. 5. Nettoyer les `console.log` restants. 6. Mettre à jour le README avec la structure réelle. --- *Plan rédigé le 8 août 2026. Il doit être affiné avec les retours utilisateurs et les contraintes réelles de déploiement (version de Shaarli, hébergement, usage du mobile).*