humalis 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,6 +51,9 @@ ${entete(langues)}const CLE = ${chaine(CLE_LANGUE)};
51
51
  */
52
52
  function langueDeDepart(): Langue {
53
53
  if (typeof window === 'undefined') return LANGUES[0];
54
+ // Le prérendu (un navigateur automatisé) écrit les pages dans la langue de base du site,
55
+ // celle que les moteurs de recherche doivent lire, quelle que soit la langue de ce navigateur.
56
+ if (navigator.webdriver) return LANGUES[0];
54
57
  try {
55
58
  const gardee = localStorage.getItem(CLE);
56
59
  if (estLangue(gardee)) return gardee;
@@ -3,7 +3,7 @@ import { robotsTxt, manifeste, fichiersDuSite, balisesIcone, estExterne } from '
3
3
  import { sousActions } from '../../ri/actions.js';
4
4
  import { cssEcran } from './css-ecran.js';
5
5
  import { cssElements } from './css-elements.js';
6
- import { cssMouvement, animeAuDefilement, MOUVEMENT_WEB, NETTOYAGE_PRERENDU } from '../commun/mouvement.js';
6
+ import { cssMouvement, animeAuDefilement, MOUVEMENT_WEB, NETTOYAGE_PRERENDU, ENTETE_WEB, suitLEntete } from '../commun/mouvement.js';
7
7
  import { fichiersDesElements, dependancesDesElements, dependancesDeDeveloppement } from './widgets.js';
8
8
  import { fichiersGraphique, cssGraphique } from './graphique.js';
9
9
  import { cssTheme, changeLeTheme, modeParDefaut, themeTs, SCRIPT_THEME } from './theme.js';
@@ -79,6 +79,7 @@ export function genererProjetWeb(application, options) {
79
79
  // Le bloc « site » ou un « apercu » : chaque page pose ses balises de partage.
80
80
  ...(application.site || application.ecrans.some((e) => e.apercu) ? { publication: { site: application.site, adresse: options.adresse } } : {}),
81
81
  ...(application.langues ? { langues: application.langues } : {}),
82
+ ...(options.sources ? { reperes: options.sources } : {}),
82
83
  };
83
84
  let session = false;
84
85
  for (const c of application.composants) {
@@ -199,6 +200,10 @@ export function genererProjetWeb(application, options) {
199
200
  const defilementAnime = animeAuDefilement(codes);
200
201
  if (defilementAnime)
201
202
  fichiers.set('src/humalis/mouvement.ts', MOUVEMENT_WEB);
203
+ // « entete avec fixe », « hauteur ecran » : la hauteur de l'en-tête, suivie par un petit script.
204
+ const enteteSuivie = suitLEntete(codes);
205
+ if (enteteSuivie)
206
+ fichiers.set('src/humalis/entete.ts', ENTETE_WEB);
202
207
  // Le CSS de l'utilisateur, recopié tel quel (décision W8), chargé après
203
208
  // celui de Humalis pour pouvoir le redéfinir.
204
209
  const feuilles = [];
@@ -225,7 +230,7 @@ export function genererProjetWeb(application, options) {
225
230
  ...(ecran.reservee ? { reservee: { qui: ecran.reservee.qui, sinon: chemins.get(ecran.reservee.sinon) ?? '/' } } : {}),
226
231
  sansEntete: ecran.sansEntete,
227
232
  sansPied: ecran.sansPied,
228
- })), feuilles, application.partages.length > 0, session, introuvable?.page.composant, dispositions, utiliseDefilement, defilementAnime));
233
+ })), feuilles, application.partages.length > 0, session, introuvable?.page.composant, dispositions, utiliseDefilement, defilementAnime, enteteSuivie));
229
234
  for (const { page } of pages)
230
235
  fichiers.set(`src/pages/${page.composant}.tsx`, page.code);
231
236
  // Les images locales, recopiées là où le site les cherche (/images/…) : décision M5.
@@ -506,7 +511,7 @@ function lignesDeRoute(r, toutes, niveau, cheminParent) {
506
511
  lignes.push(`${espaces(0)}</Route>`);
507
512
  return lignes;
508
513
  }
509
- function mainTsx(routes, feuilles, partage, session, introuvable, dispositions = {}, defilement = false, mouvement = false) {
514
+ function mainTsx(routes, feuilles, partage, session, introuvable, dispositions = {}, defilement = false, mouvement = false, entete = false) {
510
515
  const imports = routes.map((r) => `import ${r.composant} from './pages/${r.composant}';`).join('\n');
511
516
  // Les pages qui ont le même en-tête et le même pied partagent une disposition ; une sous-page suit son parent.
512
517
  const groupes = new Map();
@@ -532,7 +537,7 @@ import { Messages } from './humalis/messages';${defilement ? "\nimport { Defilem
532
537
  ${session ? "import { Session } from './humalis/session';\n" : ''}${partage ? "import { Partage } from './humalis/partage';\n" : ''}${routes.some((r) => r.reservee) ? "import { Reservee } from './humalis/reservee';\n" : ''}${introuvable ? `import ${introuvable} from './pages/${introuvable}';` : "import Introuvable from './Introuvable';"}
533
538
  ${dispositions.entete || dispositions.pied ? "import Disposition from './Disposition';\n" : ''}${imports}
534
539
  import './humalis/styles.css';
535
- ${mouvement ? "import { observerLeDefilement } from './humalis/mouvement';\n" : ''}${feuilles.map((f) => `import './styles/${f}';\n`).join('')}
540
+ ${mouvement ? "import { observerLeDefilement } from './humalis/mouvement';\n" : ''}${entete ? "import { suivreLaHauteurDeLEntete } from './humalis/entete';\n" : ''}${feuilles.map((f) => `import './styles/${f}';\n`).join('')}
536
541
  // Un hébergeur statique sert /documentation/index.html pour /documentation/ :
537
542
  // le routeur lit l'adresse sans « index.html », comme le dossier.
538
543
  if (/\\/index\\.html$/.test(location.pathname)) {
@@ -548,7 +553,7 @@ ${routesTsx}
548
553
  </BrowserRouter>
549
554
  </StrictMode>,
550
555
  );
551
- ${mouvement ? '\n// Les animations « au defilement » attendent que l\'élément entre à l\'écran.\nobserverLeDefilement();\n' : ''}`;
556
+ ${mouvement ? '\n// Les animations « au defilement » attendent que l\'élément entre à l\'écran.\nobserverLeDefilement();\n' : ''}${entete ? '\n// « entete avec fixe », « hauteur ecran » : la hauteur de l\'en-tête.\nsuivreLaHauteurDeLEntete();\n' : ''}`;
552
557
  }
553
558
  /**
554
559
  * Les aides de navigation du code produit : le lien « actif », le défilement
@@ -584,7 +589,9 @@ export function Defilement() {
584
589
  const { pathname, hash } = useLocation();
585
590
  useEffect(() => {
586
591
  if (!hash) {
592
+ // La fenêtre, et la racine si le CSS du site en fait la zone qui défile (en-tête fixe au-dessus).
587
593
  window.scrollTo(0, 0);
594
+ document.getElementById('racine')?.scrollTo(0, 0);
588
595
  return;
589
596
  }
590
597
  const id = decodeURIComponent(hash.slice(1));
package/dist/cli.js CHANGED
@@ -163,11 +163,16 @@ function compile(arguments_) {
163
163
  const medias = lireMedias(application, chemin);
164
164
  if (!medias)
165
165
  return 1;
166
- const optionsWeb = { nom, adresse: adresse ?? 'http://localhost', source: basename(chemin), fichiersStyle, composantsReact, polices, images, medias };
166
+ // --diagnostics-port n'est passé que par « humalis developper » : le mode développement, où chaque
167
+ // élément porte son fichier et sa ligne Humalis (data-humalis-source). Jamais dans une compilation normale.
168
+ const portDiagnostics = option(arguments_, 'diagnostics-port');
169
+ const optionsWeb = {
170
+ nom, adresse: adresse ?? 'http://localhost', source: basename(chemin), fichiersStyle, composantsReact, polices, images, medias,
171
+ ...(portDiagnostics !== undefined ? { sources: fichiersDuProjet } : {}),
172
+ };
167
173
  const fichiers = composants
168
174
  ? genererComposantsWeb(application, optionsWeb)
169
175
  : genererProjetWeb(application, optionsWeb);
170
- const portDiagnostics = option(arguments_, 'diagnostics-port');
171
176
  if (portDiagnostics !== undefined && fichiers.has('index.html')) {
172
177
  const index = fichiers.get('index.html');
173
178
  fichiers.set('index.html', index.replace('</body>', `<script type="module" src="http://localhost:${portDiagnostics}/diagnostics.js"></script></body>`));
package/dist/fichiers.js CHANGED
@@ -5,6 +5,7 @@ import { ErreurSyntaxique } from './parser/erreurs.js';
5
5
  import { lireCsv } from './donnees/csv.js';
6
6
  import { lireJson } from './donnees/json.js';
7
7
  import { analyserSens } from './analyse/analyse.js';
8
+ import { verifierCss } from './analyse/css.js';
8
9
  import { construireRepresentation } from './ri/construire.js';
9
10
  /**
10
11
  * Plusieurs fichiers (trou G4) : les lignes du k-ième fichier utilisé sont
@@ -158,7 +159,26 @@ export function compilerProjet(principal, lire, sourcePrincipale) {
158
159
  }
159
160
  if (diagnostics.some((d) => d.gravite === 'erreur'))
160
161
  return fin();
161
- const analyse = analyserSens(programme);
162
+ const classesCss = new Set();
163
+ let cssIllisible = false;
164
+ for (const bloc of programme.styles) {
165
+ const resultat = verifierCss(bloc.css, bloc.ligne + 1);
166
+ for (const nom of resultat.classes)
167
+ classesCss.add(nom);
168
+ diagnostics.push(...resultat.diagnostics);
169
+ }
170
+ for (const fichier of programme.fichiersStyle) {
171
+ const contenu = lire(joindre(base, fichier.chemin));
172
+ if (contenu === undefined) {
173
+ cssIllisible = true;
174
+ continue;
175
+ }
176
+ const resultat = verifierCss(contenu, 1, fichier.chemin.replace(/^\.\//, ''));
177
+ for (const nom of resultat.classes)
178
+ classesCss.add(nom);
179
+ diagnostics.push(...resultat.diagnostics);
180
+ }
181
+ const analyse = analyserSens(programme, cssIllisible ? undefined : classesCss);
162
182
  diagnostics.push(...analyse.diagnostics);
163
183
  if (diagnostics.some((d) => d.gravite === 'erreur'))
164
184
  return fin();