@massimo-cassandro/minimo 1.43.2 → 1.43.4

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.
@@ -2,6 +2,8 @@
2
2
 
3
3
  La versione della configurazione in uso è indicata dal commento `// v.N` alla riga 2 di `webpack.config.mjs` e di ogni file in `webpack-config-modules/`.
4
4
 
5
+ Dove non esiste il commento, si intende una configurazione v2 o precedente.
6
+
5
7
  Le versioni precedenti sono conservate in `archived/webpack-config-v2/` del repository di minimo.
6
8
 
7
9
  > **Alternativa rapida:** rilanciare `starter-install.sh` (è idempotente): i file diversi dai sorgenti vengono rinominati `OLD-<nome>` e sostituiti dalla nuova versione. Poi si riportano nel nuovo `webpack.config.mjs` le personalizzazioni del progetto (entry, glob dei contenuti, safelist, template html, regole custom) copiandole da `OLD-webpack.config.mjs`. Le istruzioni seguenti servono per aggiornare a mano un progetto già esistente.
@@ -30,6 +32,8 @@ Riepilogo delle modifiche:
30
32
 
31
33
  ### 1. Moduli in `webpack-config-modules/`
32
34
 
35
+ - aggiornare tutti i moduli con versione precedente a quella presente nello starter-kit
36
+ - cssnano non è più utilizzato, se presente effettuare un `npm uninstall`
33
37
  - **Aggiungere** `custom-props-purgecss-plugin.mjs`.
34
38
  - **Sostituire** `purgecss-setup.mjs` con la versione v3 (non gestisce più `variables` né `variablesSafelist`; la firma di `createPurgeCSSPlugins` non accetta più `variablesSafelist` e `variables`).
35
39
  - **Eliminare** `purgecss-variables-safelist.mjs` (sostituito dal plugin).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massimo-cassandro/minimo",
3
- "version": "1.43.2",
3
+ "version": "1.43.4",
4
4
  "description": "Light css framework & utilities",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -4,6 +4,7 @@ import './sf-macro.css';
4
4
  // TODO[epic=v2] in una v. 2 di minimo, rinominare wrapper_selector e row_selector in
5
5
  // wrapperClass e rowClass (NB: classi, non selettori, per uniformità con closeBtnClass/addBtnClass/containerClass
6
6
  // aggiunti sotto) e rendere tutti i parametri camelCase.
7
+ // TODO[epic=v2] rendere tutti i parametri camelCase, predisporre script di conversione automatica
7
8
  // TODO[epic=v2] valutare se rendere opzionale, tramite parametro, l'importazione statica
8
9
  // di sf-macro.css qui sopra (questione lasciata in sospeso).
9
10
 
@@ -20,6 +21,21 @@ import './sf-macro.css';
20
21
  * @param {((row: Element | null, closeBtn: Element | null) => void) | null} [options.del_callback=null] - Chiamata dopo la rimozione di una riga; riceve la riga rimossa (ormai scollegata) e il pulsante di chiusura. (default: null)
21
22
  * @param {boolean} [options.insertAtTop=false] - Se true, le nuove righe vengono inserite in cima. (default: false)
22
23
  * @returns {void}
24
+ *
25
+ * @example
26
+ * sf_macro({
27
+ * wrapper_selector: '.sf-macro-wrapper',
28
+ * row_selector: '.sf-macro-riga',
29
+ * closeBtnClass: 'sf-macro-close-btn',
30
+ * addBtnClass: 'sf-macro-riga-add',
31
+ * containerClass: 'sf-macro-container',
32
+ * insertAtTop: false,
33
+ * // addBtn è il pulsante di aggiunta (action_btn) su cui è avvenuto il click
34
+ * add_callback: (newRow, addBtn) => {},
35
+ * // closeBtn è il pulsante di rimozione (action_btn) su cui è avvenuto il click
36
+ * preDelCallback: async (row, closeBtn) => true,
37
+ * del_callback: (row, closeBtn) => {}
38
+ * });
23
39
  */
24
40
  export function sf_macro({
25
41
  wrapper_selector = '.sf-macro-wrapper',
@@ -1,6 +1,42 @@
1
1
  /*! minimo - buildPictureTag */
2
2
  import { classnames } from '../classnames.js';
3
3
 
4
+ /*
5
+ * TODO valori di `sizes` in rem/em: permettere di indicare `from` e `size` anche in unità relative
6
+ * (es. `'40rem'`), oltre ai px numerici, sia nell'attributo `sizes` sia nelle condizioni media.
7
+ * Da definire come calcolare le dimensioni in px dei candidati `srcset` (es. base font-size configurabile).
8
+ *
9
+ *
10
+ * TODO rivedere e semplificare l'intera funzione (parametri, normalizzazione di `sizes`, calcolo dei
11
+ * candidati) e ampliare gli esempi iniziali del JSDoc, coprendo un numero maggiore di casi d'uso.
12
+ *
13
+ *
14
+ * TODO URL autonomo per singola size (override di `baseSrc`) — da valutare
15
+ *
16
+ * Obiettivo: permettere che ogni candidato dello `srcset` (per entry di `sizes`) ignori `baseSrc`
17
+ * e usi un URL completamente autonomo.
18
+ *
19
+ * Ipotesi A (array parallelo): nuovo parametro `baseSrcset`, array di stringhe o `{src, isViewer}`;
20
+ * per ogni entry di `sizes` si usa `baseSrcset[i]` al posto di `baseSrc`; se manca o è null, si usa `baseSrc`.
21
+ * Se `isViewer` è true (default) si aggiungono i parametri `bb`/`q`/`f`, altrimenti l'URL è usato tal quale.
22
+ *
23
+ * Ipotesi B (consigliata): proprietà `src` direttamente nella entry di `sizes`,
24
+ * `{ from, size, src: string | {src, isViewer} }`, senza array parallelo.
25
+ * Contro: le entry con override non possono usare la scorciatoia numerica.
26
+ *
27
+ * Dubbi da sciogliere:
28
+ * - A vs B: in A `sizes` viene riordinato per breakpoint, quindi `baseSrcset[i]` richiede di tracciare
29
+ * l'indice originale prima del sort (fragile).
30
+ * - `isViewer: false` e `formats`: un URL non gestito dal viewer non può essere convertito in
31
+ * avif/webp/pjpg. Proposta: usarlo tal quale in tutti gli `srcset` (`source` e `img`), con il formato
32
+ * a carico di chi lo passa. Alternative: solo nell'`img` di fallback, oppure omettere i `source`.
33
+ * - `dpr`: un URL non-viewer non è ridimensionabile, quindi un solo candidato per entry
34
+ * (descrittore `w` = larghezza della size) invece di uno per densità.
35
+ * - `baseSrc` obbligatorio solo se almeno una entry non ha override (oggi `null` se manca).
36
+ * - Una stringa semplice vale come `{src, isViewer: true}`: per un URL non-viewer serve sempre l'oggetto.
37
+ * - Aggiornare JSDoc (typedef, `@param baseSrc`, `@example` con caso misto).
38
+ */
39
+
4
40
  /**
5
41
  * @typedef {Object} PictureSizeEntry
6
42
  * @property {number} [from] - Breakpoint (px) da cui si applica la size (condizione media `width >=`); omesso nell'(unica) entry predefinita mobile-first.
@@ -68,7 +104,7 @@ import { classnames } from '../classnames.js';
68
104
  * });
69
105
  *
70
106
  * @param {Object} args
71
- * @param {string} args.baseSrc - URL base dell'immagine (endpoint del viewer); i suoi parametri di query vengono conservati.
107
+ * @param {string} args.baseSrc - URL base dell'immagine (endpoint del viewer); i suoi parametri di query vengono conservati. Un URL relativo (es. `/img/abc123`) viene risolto rispetto alla location corrente; se relativo alla root (inizia con `/`, ma non con `//`), resta tale anche negli URL generati.
72
108
  * @param {(number | [number, number] | PictureSizeEntry)[]} [args.sizes=[250]] - Dimensioni renderizzate dell'immagine, in qualsiasi ordine. Ogni entry è un oggetto `{from, size}` (vedi {@link PictureSizeEntry}); un numero semplice o una coppia `[width, height]` è la scorciatoia per l'entry predefinita mobile-first (quella senza `from`), attesa esattamente una volta (default: [250])
73
109
  * @param {number|null} [args.ratio=null] - Aspect ratio predefinito (larghezza / altezza, come nella proprietà CSS `aspect-ratio`) usato per calcolare l'altezza delle size numeriche. Se null, l'altezza non viene calcolata: gli output legati all'altezza (attributo `height`, altezza nel parametro `bb`) vengono omessi e il viewer mantiene il ratio originale dell'immagine (default: null)
74
110
  * @param {number} [args.dpr=2] - Densità di pixel massima (intero): i candidati di `srcset` vengono generati per ogni densità da 1 a `dpr` (default: 2)
@@ -143,9 +179,13 @@ export function buildPictureTag({
143
179
  console.warn('[buildPictureTag] `sizes` must contain exactly one entry without `from` (the mobile-first default)');
144
180
  }
145
181
 
146
- const base_url = new URL(baseSrc)
182
+ // gli URL relativi (es. `/img/abc123`) vengono risolti rispetto alla location corrente
183
+ const base_url = new URL(baseSrc, globalThis.location?.href)
147
184
  ,searchParams = new URLSearchParams(base_url.search)
148
185
 
186
+ // baseSrc relativo alla root: negli URL generati viene omessa l'origine aggiunta per la risoluzione
187
+ ,isRootRelative = baseSrc.startsWith('/') && !baseSrc.startsWith('//')
188
+
149
189
  // dimensioni dei candidati srcset (una per ogni densità da 1 a `dpr`),
150
190
  // senza duplicati (per larghezza), in ordine crescente
151
191
  ,srcsetSizes = sizeEntries
@@ -200,10 +240,10 @@ export function buildPictureTag({
200
240
  searchParams.set('f', fmt);
201
241
 
202
242
  srcsetSizes.forEach(([w, h]) => {
203
- // TODO senza altezza `bb=<w>x` vale per questo viewer: prevedere altre convenzioni (es. imgix)
243
+ // TODO senza altezza `bb=<w>x` vale per il viewer di default: prevedere altre convenzioni (es. imgix)
204
244
  searchParams.set('bb', `${w}x${h ?? ''}`);
205
245
  base_url.search = searchParams.toString();
206
- srcsetArray.push(`${base_url.toString()} ${w}w`);
246
+ srcsetArray.push(`${isRootRelative? base_url.pathname + base_url.search : base_url.toString()} ${w}w`);
207
247
  });
208
248
 
209
249
  if(is_default_fmt) {