@massimo-cassandro/minimo 1.33.0 → 1.33.2
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.
- package/README.md +2 -1
- package/dev-tools/starter-kit/source_files/{CLAUDE-frontend.md → app/CLAUDE.md} +1 -1
- package/dev-tools/starter-kit/source_files/app/assets/api_htaccess +20 -0
- package/dev-tools/starter-kit/source_files/{layout-critical.css → app/css/layout.critical.css} +1 -1
- package/dev-tools/starter-kit/source_files/app/css/layout.css +0 -0
- package/dev-tools/starter-kit/source_files/app/index.js +1 -0
- package/dev-tools/starter-kit/source_files/root/webpack-config-modules/inline-critical-css.mjs +41 -0
- package/dev-tools/starter-kit/{webpack-config-modules → source_files/root/webpack-config-modules}/purgecss-setup.mjs +1 -1
- package/dev-tools/starter-kit/{webpack.config.mjs → source_files/root/webpack.config.mjs} +50 -24
- package/dev-tools/starter-kit/starter-install.sh +163 -82
- package/dev-tools/stylelint-config/test/test.module.scss +9 -0
- package/package.json +1 -1
- package/snippets/php/iviewer.php +488 -0
- package/snippets/twig-symfony/ViewerController.php +549 -0
- package/src/custom-properties.css +29 -0
- package/src/minimo.css +3 -0
- package/src/utilities/dom-builder/dom-builder.js +9 -5
- package/src/web-components/json-table/json-table-component.js +387 -38
- package/src/web-components/json-table/json-table-component.module.css +190 -0
- package/src/web-components/json-table/json-table.minimo.tokens.mjs +195 -0
- package/src/web-components/json-table/readme.md +603 -82
- package/src/web-components/json-table/src/cell-content.js +136 -0
- package/src/web-components/json-table/src/content-utils.js +103 -0
- package/src/web-components/json-table/src/data-types.js +280 -0
- package/src/web-components/json-table/src/defaults.js +377 -58
- package/src/web-components/json-table/src/get-data.js +105 -10
- package/src/web-components/json-table/src/icons.js +80 -0
- package/src/web-components/json-table/src/info-section.js +85 -50
- package/src/web-components/json-table/src/main-builder.js +175 -52
- package/src/web-components/json-table/src/pagination.js +253 -0
- package/src/web-components/json-table/src/parse-cols.js +113 -0
- package/src/web-components/json-table/src/parse-rows.js +81 -0
- package/src/web-components/json-table/src/resolve-params.js +102 -32
- package/src/web-components/json-table/src/search.js +71 -0
- package/src/web-components/json-table/src/sorting.js +111 -0
- package/src/web-components/json-table/src/table-body.js +109 -0
- package/src/web-components/json-table/src/table-builder.js +152 -0
- package/src/web-components/json-table/src/table-tfoot.js +56 -0
- package/src/web-components/json-table/src/table-thead.js +183 -0
- package/src/web-components/json-table/src/update-info.js +43 -24
- package/src/web-components/s-datatable-component/{docs.md → readme.md} +5 -3
- package/src/web-components/s-datatable-component/s-datatable-component.js +1 -1
- package/types/global.d.ts +17 -3
- package/dev-tools/starter-kit/source_files/app_index.js +0 -1
- package/snippets/config-templates/_htaccess +0 -69
- package/snippets/config-templates/robots.txt +0 -5
- package/snippets/config-templates/rollup.config.mjs +0 -115
- /package/dev-tools/starter-kit/source_files/{_root_robots.txt → app/assets/robots.txt} +0 -0
- /package/dev-tools/starter-kit/source_files/{_root_htaccess → app/assets/root_htaccess} +0 -0
- /package/{src → dev-tools/starter-kit/source_files/app/css}/fonts.css +0 -0
- /package/dev-tools/starter-kit/source_files/{favicons-readme.md → app/favicons/favicons-readme.md} +0 -0
- /package/dev-tools/starter-kit/{webpack-template.ejs → source_files/app/tpl/index.ejs} +0 -0
- /package/dev-tools/starter-kit/source_files/{__project__.code-workspace → root/__project__.code-workspace} +0 -0
- /package/dev-tools/starter-kit/source_files/{_browserslistrc → root/_browserslistrc} +0 -0
- /package/dev-tools/starter-kit/source_files/{_editorconfig → root/_editorconfig} +0 -0
- /package/dev-tools/starter-kit/source_files/{_gitignore → root/_gitignore} +0 -0
- /package/dev-tools/starter-kit/source_files/{_prettierrc → root/_prettierrc} +0 -0
- /package/dev-tools/starter-kit/source_files/{eslint.config.mjs → root/eslint.config.mjs} +0 -0
- /package/dev-tools/starter-kit/source_files/{jsconfig.json → root/jsconfig.json} +0 -0
- /package/dev-tools/starter-kit/{package-tpl.json → source_files/root/package-tpl.json} +0 -0
- /package/dev-tools/starter-kit/source_files/{stylelint.config.mjs → root/stylelint.config.mjs} +0 -0
- /package/dev-tools/starter-kit/{webpack-config-modules → source_files/root/webpack-config-modules}/css-rules.mjs +0 -0
- /package/dev-tools/starter-kit/{webpack-config-modules → source_files/root/webpack-config-modules}/get-jsConfig-aliases.mjs +0 -0
- /package/dev-tools/starter-kit/{webpack-config-modules → source_files/root/webpack-config-modules}/mini-svg-data-uri-loader.cjs +0 -0
- /package/dev-tools/starter-kit/{webpack-config-modules → source_files/root/webpack-config-modules}/postcss.config.mjs +0 -0
- /package/dev-tools/starter-kit/{webpack-config-modules → source_files/root/webpack-config-modules}/purgecss-variables-safelist.mjs +0 -0
- /package/dev-tools/starter-kit/{webpack-config-modules → source_files/root/webpack-config-modules}/svg-rules.mjs +0 -0
- /package/dev-tools/starter-kit/{webpack-config-modules → source_files/root/webpack-config-modules}/svgo.config.mjs +0 -0
- /package/snippets/{config-templates/_github → _github}/dependabot.yml +0 -0
- /package/snippets/{error-pages/error-pages.js → error-pages.js} +0 -0
- /package/snippets/{config-templates/react → react}/offcanvas/offcanvas.jsx +0 -0
- /package/snippets/{config-templates/react → react}/offcanvas/offcanvas.module.scss +0 -0
- /package/snippets/{config-templates → root}/_hintrc.cjs +0 -0
- /package/snippets/{config-templates → root}/_npmignore +0 -0
- /package/snippets/{config-templates → root}/_npmrc +0 -0
- /package/snippets/{config-templates → root}/_stylelintignore +0 -0
- /package/snippets/{config-templates → root}/babel.config--react.json +0 -0
- /package/snippets/{config-templates → root}/babel.config--solidJS.json +0 -0
- /package/snippets/{ImgViewerController.php → twig-symfony/ImgViewerController.php} +0 -0
- /package/snippets/{UnsplashController.php → twig-symfony/UnsplashController.php} +0 -0
- /package/snippets/{config-templates → twig-symfony}/_env.local +0 -0
- /package/snippets/{error-pages → twig-symfony}/bundles/TwigBundle/Exception/error.html.twig +0 -0
- /package/snippets/{flash-messages.html.twig → twig-symfony/flash-messages.html.twig} +0 -0
- /package/snippets/{minimo-form-layout.html.twig → twig-symfony/minimo-form-layout.html.twig} +0 -0
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Controller;
|
|
4
|
+
|
|
5
|
+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
6
|
+
use Symfony\Component\Routing\Annotation\Route;
|
|
7
|
+
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
|
|
8
|
+
use Symfony\Component\HttpFoundation\Request;
|
|
9
|
+
use Symfony\Component\HttpFoundation\Response;
|
|
10
|
+
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
11
|
+
use Doctrine\Persistence\ManagerRegistry;
|
|
12
|
+
use App\Entity\Files\Files;
|
|
13
|
+
use App\Entity\Files\MarchiFamiglie;
|
|
14
|
+
use App\Entity\Files\MarchiTipologie;
|
|
15
|
+
use App\Entity\Files\MarchiFiles;
|
|
16
|
+
|
|
17
|
+
class ViewerController extends AbstractController
|
|
18
|
+
{
|
|
19
|
+
public function __construct(private \Doctrine\Persistence\ManagerRegistry $managerRegistry)
|
|
20
|
+
{
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#[Route('/viewer/marchi/{famigliaId}')]
|
|
24
|
+
public function marchi(Request $request, $famigliaId = null)
|
|
25
|
+
{
|
|
26
|
+
$em = $this->managerRegistry->getManager();
|
|
27
|
+
|
|
28
|
+
$get = $request->query->all();
|
|
29
|
+
|
|
30
|
+
$famiglia = $em->getRepository(MarchiFamiglie::class)->find($famigliaId);
|
|
31
|
+
|
|
32
|
+
if(!$famiglia instanceof \App\Entity\Files\MarchiFamiglie)
|
|
33
|
+
throw $this->createNotFoundException('Famiglia non trovata!!');
|
|
34
|
+
|
|
35
|
+
$tipoBitmap = $em->getRepository(MarchiTipologie::class)->find(1); // Bitmap
|
|
36
|
+
$tipoSvg = $em->getRepository(MarchiTipologie::class)->find(2); // Svg
|
|
37
|
+
|
|
38
|
+
$isSvg = false;
|
|
39
|
+
if(isset($get['svg']) && $get['svg']) {
|
|
40
|
+
|
|
41
|
+
# in prima battuta cerco l'svg predefinito
|
|
42
|
+
$file = $em->getRepository(MarchiFiles::class)->findOneBy(
|
|
43
|
+
array(
|
|
44
|
+
'famiglia' => $famiglia,
|
|
45
|
+
'predefinito' => 1,
|
|
46
|
+
'cancellato' => 0,
|
|
47
|
+
'tipologia' => $tipoSvg
|
|
48
|
+
),
|
|
49
|
+
array()
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
if($file !== null) {
|
|
53
|
+
|
|
54
|
+
$isSvg = true;
|
|
55
|
+
|
|
56
|
+
} else {
|
|
57
|
+
|
|
58
|
+
# se non trovo l'svg predefinito cerco il bitmap predefinito
|
|
59
|
+
$file = $em->getRepository(MarchiFiles::class)->findOneBy(
|
|
60
|
+
array(
|
|
61
|
+
'famiglia' => $famiglia,
|
|
62
|
+
'predefinito' => 1,
|
|
63
|
+
'cancellato' => 0,
|
|
64
|
+
'tipologia' => $tipoBitmap
|
|
65
|
+
),
|
|
66
|
+
array()
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
} else {
|
|
72
|
+
|
|
73
|
+
# cerco il bitmap predefinito
|
|
74
|
+
$file = $em->getRepository(MarchiFiles::class)->findOneBy(
|
|
75
|
+
array(
|
|
76
|
+
'famiglia' => $famiglia,
|
|
77
|
+
'predefinito' => 1,
|
|
78
|
+
'cancellato' => 0,
|
|
79
|
+
'tipologia' => $tipoBitmap
|
|
80
|
+
),
|
|
81
|
+
array()
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if($file !== null) {
|
|
87
|
+
|
|
88
|
+
if($isSvg) {
|
|
89
|
+
$params = array(
|
|
90
|
+
'id' => $file->getFile()->getId()
|
|
91
|
+
);
|
|
92
|
+
} else {
|
|
93
|
+
|
|
94
|
+
$params = array(
|
|
95
|
+
'id' => $file->getFile()->getId(),
|
|
96
|
+
'request' => $request
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# se non è richiesto un formato, lo forzo a png #
|
|
102
|
+
if(!array_key_exists('f', $get)) {
|
|
103
|
+
$request->query->set('f', 'png');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if(array_key_exists('og', $get)) {
|
|
107
|
+
if ($get['og'] == 'q') {
|
|
108
|
+
$request->query->set('og', 'q');
|
|
109
|
+
} elseif ($get['og'] == 'r') {
|
|
110
|
+
$request->query->set('og', 'r');
|
|
111
|
+
} else
|
|
112
|
+
$request->query->set('og', 'q');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return $this->forward('App\Controller\ViewerController::index', $params);
|
|
116
|
+
|
|
117
|
+
} else {
|
|
118
|
+
|
|
119
|
+
throw $this->createNotFoundException('Risorsa non trovata!!');
|
|
120
|
+
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @param raw: nessuna eleborazione (no image magick)
|
|
127
|
+
* @param crop: ritaglia l'immagine originale (prima dell'eventuale ridimensionamento con bb)
|
|
128
|
+
* secondo i parametri forniti: x,y (origine immagine), w,h (dimensioni ritaglio)
|
|
129
|
+
* es: crop=10,10,100,100 -> ritaglia un quadrato di 100px a partire dal punto 10,10
|
|
130
|
+
* @param bb: bounding box dell'area che deve contenere l'immagine ridimensionata (image magick)
|
|
131
|
+
* @param fd: forza dimensioni (utilizzato in coppia con bb)
|
|
132
|
+
* @param q: compression quality (ex jq)
|
|
133
|
+
* @param alpha: mantiene la trasparenza nelle png (default 0)
|
|
134
|
+
* @param bg: in combinazione con alpha=1 definisce il bkg color della png
|
|
135
|
+
* @param refresh: forza la rigenerazione dell'immagine
|
|
136
|
+
* @param f: definisce il formato dell'immagine: pjpeg (default), jpeg, gif, png, webp, ico
|
|
137
|
+
* @param ext: lascia inalterato il formato dell'immagine
|
|
138
|
+
* @param d: forza il download dell'immagine
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
// parametri get del viewer accettati
|
|
142
|
+
const ALLOWED_PARAMS = array('raw', 'bb', 'fd', 'q', 'alpha', 'bg', 'refresh', 'f', 'ext', 'd', 'crop');
|
|
143
|
+
// formati output
|
|
144
|
+
const ALLOWED_FORMATS = array(
|
|
145
|
+
'avif' => 'image/avif',
|
|
146
|
+
'pjpeg' => 'image/pjpeg',
|
|
147
|
+
'jpeg' => 'image/jpeg',
|
|
148
|
+
'jpg' => 'image/jpeg',
|
|
149
|
+
'png' => 'image/png',
|
|
150
|
+
'gif' => 'image/gif',
|
|
151
|
+
'webp' => 'image/webp',
|
|
152
|
+
'ico' => 'image/vnd.microsoft.icon'
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// formati preferiti per la scelta automatica in ordine di preferenza
|
|
156
|
+
// in loro mancanza il formato prefefinito è jpeg
|
|
157
|
+
// (NB: devono essere uguali alle chiavi di ALLOWED_FORMATS)
|
|
158
|
+
const PREFERRED_AUTO_FORMATS = ['avif', 'webp'];
|
|
159
|
+
|
|
160
|
+
// formati input accettati da Imagick (in aggiunta a quelli definiti in ALLOWED_FORMATS)
|
|
161
|
+
const ALLOWED_INPUT = ['bmp', 'tiff', 'tif'];
|
|
162
|
+
|
|
163
|
+
// parametro compression quality di default
|
|
164
|
+
const DEFAULT_COMPRESSION_QUALITY = 60;
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
#[Route('/viewer/{id}')]
|
|
168
|
+
public function index(Request $request, $id = null)
|
|
169
|
+
{
|
|
170
|
+
$em = $this->managerRegistry->getManager();
|
|
171
|
+
|
|
172
|
+
$get = $request->query->all();
|
|
173
|
+
|
|
174
|
+
// formati supportati dall'istanza imageMagick
|
|
175
|
+
$supported_formats = array_map("strtolower", \imagick::queryFormats());
|
|
176
|
+
|
|
177
|
+
// formati accettati dal browser
|
|
178
|
+
$accept = $request->server->get('HTTP_ACCEPT');
|
|
179
|
+
|
|
180
|
+
// format 'auto' default
|
|
181
|
+
if(!isset($get['f'])) {
|
|
182
|
+
$get['f'] ='auto';
|
|
183
|
+
} else {
|
|
184
|
+
$get['f'] = strtolower($get['f']);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// format 'auto' -> sceglie il formato migliore per il browser, se disponibile
|
|
188
|
+
if(isset($get['f']) && $get['f'] == 'auto') {
|
|
189
|
+
|
|
190
|
+
foreach(self::PREFERRED_AUTO_FORMATS as $f) {
|
|
191
|
+
if(strpos($accept, self::ALLOWED_FORMATS[$f]) !== false &&
|
|
192
|
+
in_array($f, array_keys(self::ALLOWED_FORMATS)) &&
|
|
193
|
+
in_array($f, $supported_formats)
|
|
194
|
+
) {
|
|
195
|
+
$get['f']=$f;
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if($get['f'] == 'auto') $get['f'] = 'jpeg';
|
|
202
|
+
|
|
203
|
+
## durata della cache di un file: 7gg ##
|
|
204
|
+
$cache_lifetime = 604800;
|
|
205
|
+
|
|
206
|
+
$params = $this->cleanParams($get);
|
|
207
|
+
|
|
208
|
+
$cache_params_str = "";
|
|
209
|
+
|
|
210
|
+
foreach($params as $kg => $g)
|
|
211
|
+
{
|
|
212
|
+
if($kg != 'refresh' && $kg != 'raw')
|
|
213
|
+
$cache_params_str .= '_' . $kg . $g;
|
|
214
|
+
}
|
|
215
|
+
// pulizia virgole del parametro crop
|
|
216
|
+
$cache_params_str = str_replace(',', '_', $cache_params_str);
|
|
217
|
+
|
|
218
|
+
if(!$id)
|
|
219
|
+
throw $this->createNotFoundException('Errore di configurazione!!');
|
|
220
|
+
|
|
221
|
+
$dbfile = $em->getRepository(Files::class)->findOneBy(
|
|
222
|
+
array('id' => $id, 'autenticazione' => 0),
|
|
223
|
+
array()
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
if($dbfile !== null) {
|
|
227
|
+
$folder = $this->getParameter('files_dir') . ((int)($dbfile->getId() / 1000));
|
|
228
|
+
$file = $folder . '/' . $dbfile->getId() . '_' . $dbfile->getNome();
|
|
229
|
+
|
|
230
|
+
$string = $dbfile->getNome();
|
|
231
|
+
|
|
232
|
+
$fileNm = substr($string, 0, strripos($string, '.'));
|
|
233
|
+
$fileExt = substr($string, strripos($string, '.') + 1, strlen($string)) ;
|
|
234
|
+
|
|
235
|
+
} else
|
|
236
|
+
throw $this->createNotFoundException('Risorsa non disponibile!!');
|
|
237
|
+
|
|
238
|
+
if($dbfile->getIsImg()) {
|
|
239
|
+
|
|
240
|
+
$disposition = isset($params['d']) ? 'attachment' : 'inline';
|
|
241
|
+
|
|
242
|
+
// if($this->getParameter('local_test') == true && isset($params['f']) && $params['f'] == 'webp') {
|
|
243
|
+
// unset($params['f']);
|
|
244
|
+
// }
|
|
245
|
+
|
|
246
|
+
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
|
247
|
+
|
|
248
|
+
## elaborazione immagine se ho dei parametri, non è settato raw ed ha un formato trattabile da imagick
|
|
249
|
+
if(!isset($params['raw']) && in_array($ext, array_merge(self::ALLOWED_INPUT, array_keys(self::ALLOWED_FORMATS)))) {
|
|
250
|
+
|
|
251
|
+
## se è richiesto un formato verifico cher sia tra quelli disponibili ##
|
|
252
|
+
if (isset($params['f']) && in_array(strtolower($params['f']), array_keys(self::ALLOWED_FORMATS))) {
|
|
253
|
+
$format = strtolower($params['f']);
|
|
254
|
+
} elseif (isset($params['ext']) && $params['ext']) {
|
|
255
|
+
## formato predefinito ##
|
|
256
|
+
$format = $ext;
|
|
257
|
+
} elseif (in_array($ext, array_keys(self::ALLOWED_FORMATS))) {
|
|
258
|
+
## formato predefinito ##
|
|
259
|
+
$format = $ext;
|
|
260
|
+
} else {
|
|
261
|
+
## formato predefinito ##
|
|
262
|
+
$format = 'pjpeg';
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
$filename = $fileNm . $cache_params_str . '.' . ($format == 'pjpeg' ? 'jpeg' : $format);
|
|
266
|
+
|
|
267
|
+
$cachefile = $this->getParameter('cache_dir') . $dbfile->getId() . '_' . $filename;
|
|
268
|
+
|
|
269
|
+
## definizione della qualità della compressione dell'immagine ##
|
|
270
|
+
$compressionQuality = isset($params['q']) && $params['q'] > 0 ? $params['q'] : self::DEFAULT_COMPRESSION_QUALITY;
|
|
271
|
+
|
|
272
|
+
## elaborazione con imagick per i seguenti casi:
|
|
273
|
+
## 1) non esiste il file nella cartella cache
|
|
274
|
+
## 2) la cache è scaduta
|
|
275
|
+
## 3) forzo il refresh
|
|
276
|
+
if(!file_exists($cachefile) || (filemtime($cachefile)+$cache_lifetime) < time() || isset($params['refresh'])) {
|
|
277
|
+
|
|
278
|
+
## inizializzazione imagick ##
|
|
279
|
+
$img = new \Imagick();
|
|
280
|
+
$img->readImage($file);
|
|
281
|
+
|
|
282
|
+
$img->stripImage();
|
|
283
|
+
|
|
284
|
+
if(isset($params['crop']) or isset($params['bb'])) {
|
|
285
|
+
// dimensioni originali
|
|
286
|
+
$ow = $img->getImageWidth();
|
|
287
|
+
$oh = $img->getImageHeight();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if(isset($params['crop'])) {
|
|
291
|
+
$crop_params = array_map( fn($val) => intval(trim($val)), explode(',', $params['crop']));
|
|
292
|
+
|
|
293
|
+
// devono essere presenti tutti e 4 i parametri e devono essere maggiori di zero
|
|
294
|
+
if(count($crop_params) != 4 or min($crop_params) < 0) {
|
|
295
|
+
throw $this->createNotFoundException('Errore di configurazione! (crop 1)');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
[$x,$y,$crop_w,$crop_h] = $crop_params;
|
|
299
|
+
|
|
300
|
+
// l'area ritagliata non può essere più grande dell'immagine
|
|
301
|
+
if($x + $crop_w > $ow or $y + $crop_h > $oh) {
|
|
302
|
+
throw $this->createNotFoundException('Errore di configurazione! (crop 2)');
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
$img->cropImage($crop_w, $crop_h, $x, $y);
|
|
306
|
+
|
|
307
|
+
// nuove dimensioni dell'immagine (corrispondono a $crop_w e $crop_h)
|
|
308
|
+
$ow = $img->getImageWidth();
|
|
309
|
+
$oh = $img->getImageHeight();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if(isset($params['bb'])) {
|
|
313
|
+
$bb_param = strtolower($params['bb']);
|
|
314
|
+
$pox = strpos($bb_param, 'x');
|
|
315
|
+
|
|
316
|
+
if($pox !== false) {
|
|
317
|
+
$b = ($pox > 0) ? substr($bb_param, 0, $pox) : 0;
|
|
318
|
+
$h = (($pox + 1) < strlen($bb_param)) ? substr($bb_param, $pox + 1) : 0;
|
|
319
|
+
|
|
320
|
+
$ob = $img->getImageWidth();
|
|
321
|
+
$oh = $img->getImageHeight();
|
|
322
|
+
|
|
323
|
+
// le nuove dimensioni non possono superare quelle originali
|
|
324
|
+
//if(!isset($params['fr'])) {
|
|
325
|
+
if($b > $ob) $b = $ob;
|
|
326
|
+
if($h > $oh) $h = $oh;
|
|
327
|
+
//}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if(isset($params['bb']) && isset($params['fd']) && $pox !== false && $b>0 && $h>0) {
|
|
333
|
+
|
|
334
|
+
if ($ob < $b && $oh < $h && ($b != 0 && $h != 0)) {
|
|
335
|
+
$nb = $ob;
|
|
336
|
+
$nh = $oh;
|
|
337
|
+
$r = $b > $h ? $h/$b : $b/$h;
|
|
338
|
+
if($nb > $nh)
|
|
339
|
+
$nh = $r * $nb;
|
|
340
|
+
else
|
|
341
|
+
$nb = $r * $nh;
|
|
342
|
+
$b = $nb;
|
|
343
|
+
$h = $nh;
|
|
344
|
+
}
|
|
345
|
+
$img->cropThumbnailImage($b, $h);
|
|
346
|
+
|
|
347
|
+
} elseif(isset($params['bb']) && $pox !== false) {
|
|
348
|
+
|
|
349
|
+
if($b != 0 || $h != 0) {
|
|
350
|
+
$nb = $ob;
|
|
351
|
+
$nh = $oh;
|
|
352
|
+
if($b != 0 && $b < $nb) {
|
|
353
|
+
$nh = ($b/$nb) * $nh;
|
|
354
|
+
$nb = $b;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if($h != 0 && $h < $nh) {
|
|
358
|
+
$nb = ($h/$nh) * $nb;
|
|
359
|
+
$nh = $h;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
$b = $nb;
|
|
363
|
+
$h = $nh;
|
|
364
|
+
|
|
365
|
+
}
|
|
366
|
+
$img->thumbnailImage($b, $h, true);
|
|
367
|
+
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
# structured data quadrata #
|
|
371
|
+
if(isset($params['og']) && $params['og'] == 'q') {
|
|
372
|
+
|
|
373
|
+
$img->scaleImage(600, 600, true);
|
|
374
|
+
$img->setImageBackgroundColor('white');
|
|
375
|
+
//$img = $img->flattenImages();
|
|
376
|
+
|
|
377
|
+
$size = 600;
|
|
378
|
+
$geometry = $img->getImageGeometry();
|
|
379
|
+
$width = $geometry['width'];
|
|
380
|
+
$height = $geometry['height'];
|
|
381
|
+
|
|
382
|
+
$img->cropImage($width, $height, 0, 0);
|
|
383
|
+
|
|
384
|
+
$img->extentImage($size, $size, -($size - $width) / 2, -($size - $height) / 2);
|
|
385
|
+
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
# structured data rettangolare #
|
|
389
|
+
if(isset($params['og']) && $params['og'] == 'r') {
|
|
390
|
+
|
|
391
|
+
$sizeW = 1000;
|
|
392
|
+
$sizeH = 500;
|
|
393
|
+
|
|
394
|
+
$img->scaleImage($sizeW, $sizeH, true);
|
|
395
|
+
$img->setImageBackgroundColor('white');
|
|
396
|
+
//$img = $img->flattenImages();
|
|
397
|
+
|
|
398
|
+
$geometry = $img->getImageGeometry();
|
|
399
|
+
$width = $geometry['width'];
|
|
400
|
+
$height = $geometry['height'];
|
|
401
|
+
|
|
402
|
+
$img->cropImage($width, $height, 0, 0);
|
|
403
|
+
|
|
404
|
+
$img->extentImage($sizeW, $sizeH, -($sizeW - $width) / 2, -($sizeH - $height) / 2);
|
|
405
|
+
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
## eseguo l'eventuale compressione solo nel caso di jpeg ##
|
|
409
|
+
if($compressionQuality && ($img->getImageMimeType() == 'image/jpeg')) {
|
|
410
|
+
|
|
411
|
+
$img->setImageCompressionQuality((int) $compressionQuality);
|
|
412
|
+
|
|
413
|
+
}
|
|
414
|
+
//$img->setImageAlphaChannel(\imagick::COMPOSITE_CLEAR);
|
|
415
|
+
//$img->setBackgroundColor(new \ImagickPixel('white'));
|
|
416
|
+
|
|
417
|
+
## definisco il formato dell'img ##
|
|
418
|
+
if(isset($params['f'])) {
|
|
419
|
+
|
|
420
|
+
$img->setImageFormat($format);
|
|
421
|
+
|
|
422
|
+
// $mimeType = $img->getImageMimeType();
|
|
423
|
+
$mimeType = self::ALLOWED_FORMATS[$format];
|
|
424
|
+
|
|
425
|
+
if ($format == 'ico') {
|
|
426
|
+
$img->setImageAlphaChannel(\imagick::COMPOSITE_CLEAR);
|
|
427
|
+
$img->setBackgroundColor(new \ImagickPixel('transparent'));
|
|
428
|
+
$img->cropThumbnailImage(16, 16);
|
|
429
|
+
$mimeType = 'image/vnd.microsoft.icon';
|
|
430
|
+
|
|
431
|
+
} elseif ($format == 'png') {
|
|
432
|
+
|
|
433
|
+
// $mimeType = 'png';
|
|
434
|
+
if(isset($params['alpha']) && isset($params['bg']) && preg_match('/[0-9a-f]{6}/i', $params['bg'])) {
|
|
435
|
+
$bgColor = '#' . $params['bg'];
|
|
436
|
+
## elimino la trasparenza ##
|
|
437
|
+
//$img->setImageAlphaChannel(\imagick::COMPOSITE_CLEAR);
|
|
438
|
+
$img->setImageBackgroundColor($bgColor);
|
|
439
|
+
$img = $img->flattenImages();
|
|
440
|
+
} else {
|
|
441
|
+
//$bgColor = '#ffffff';
|
|
442
|
+
//$img->setImageAlphaChannel(\imagick::COMPOSITE_CLEAR);
|
|
443
|
+
//$img->setBackgroundColor(new \ImagickPixel('transparent'));
|
|
444
|
+
|
|
445
|
+
$draw = new \ImagickDraw();
|
|
446
|
+
$draw->setStrokeAntialias(false);
|
|
447
|
+
|
|
448
|
+
$img->drawImage($draw);
|
|
449
|
+
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
} /* else {
|
|
454
|
+
|
|
455
|
+
$mimeType = 'image/jpeg';
|
|
456
|
+
|
|
457
|
+
} */
|
|
458
|
+
|
|
459
|
+
$img->writeImage($cachefile);
|
|
460
|
+
$img->clear();
|
|
461
|
+
$img->destroy();
|
|
462
|
+
|
|
463
|
+
} else {
|
|
464
|
+
|
|
465
|
+
// $mimeTypeArray = array(
|
|
466
|
+
// 'pjpeg' => 'image/jpeg',
|
|
467
|
+
// 'jpeg' => 'image/jpeg',
|
|
468
|
+
// 'jpg' => 'image/jpeg',
|
|
469
|
+
// 'png' => 'image/png',
|
|
470
|
+
// 'gif' => 'image/gif',
|
|
471
|
+
// 'webp' => 'image/webp',
|
|
472
|
+
// 'ico' => 'image/vnd.microsoft.icon'
|
|
473
|
+
// );
|
|
474
|
+
// $mimeType = $mimeTypeArray[$format];
|
|
475
|
+
$mimeType = self::ALLOWED_FORMATS[$format];
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
} else {
|
|
479
|
+
|
|
480
|
+
## nessuna elaborazione richiesta: servo il file originale ##
|
|
481
|
+
$cachefile = $file;
|
|
482
|
+
$filename = $fileNm . '.' . $fileExt;
|
|
483
|
+
|
|
484
|
+
if($ext == 'svg')
|
|
485
|
+
$mimeType = 'image/svg+xml';
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
} else {
|
|
489
|
+
|
|
490
|
+
## gestisco un documento
|
|
491
|
+
$cachefile = $file;
|
|
492
|
+
$mimeType = null;
|
|
493
|
+
$filename = $fileNm . '.' . $fileExt;
|
|
494
|
+
$disposition = 'inline';
|
|
495
|
+
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
$response = new BinaryFileResponse($cachefile);
|
|
499
|
+
$response->trustXSendfileTypeHeader();
|
|
500
|
+
|
|
501
|
+
if(isset($mimeType)) {
|
|
502
|
+
$response->headers->set('Content-Type', $mimeType);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
$response->headers->set('Content-Disposition', $disposition . '; filename = ' . $filename);
|
|
506
|
+
|
|
507
|
+
return $response;
|
|
508
|
+
|
|
509
|
+
//return array();
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
protected function cleanParams($params)
|
|
513
|
+
{
|
|
514
|
+
|
|
515
|
+
// compatibilità con vecchio parametro jq
|
|
516
|
+
if(isset($params['jq']) && !isset($params['q'])) {
|
|
517
|
+
$params['q'] = $params['jq'];
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
$array_filters = array('raw', 'bb', 'fd', 'jq', 'alpha', 'bg', 'refresh', 'f', 'd', 'ext', 'og');
|
|
521
|
+
|
|
522
|
+
#array_walk($params, create_function('&$val', '$val = trim($val);'));
|
|
523
|
+
// array_walk($params, function($val): string {
|
|
524
|
+
// return trim($val);
|
|
525
|
+
// });
|
|
526
|
+
|
|
527
|
+
// foreach ($params as $key => $value)
|
|
528
|
+
// {
|
|
529
|
+
// if (!(in_array($key, $array_filters) && $value)) {
|
|
530
|
+
// unset($params[$key]);
|
|
531
|
+
// }
|
|
532
|
+
// }
|
|
533
|
+
|
|
534
|
+
foreach ($params as $key => $value) {
|
|
535
|
+
if(!in_array($key, self::ALLOWED_PARAMS)) {
|
|
536
|
+
unset($params[$key]);
|
|
537
|
+
} else if($value) {
|
|
538
|
+
$params[$key] = trim($value);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if(isset($params['f'])) {
|
|
543
|
+
$params['f'] = strtolower($params['f']);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return $params;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
}
|
|
@@ -222,11 +222,40 @@
|
|
|
222
222
|
--inner-nav-gap: var(--size-lg);
|
|
223
223
|
--inner-nav-margin-block: var(--size-base);
|
|
224
224
|
|
|
225
|
+
--jt-bool-false-color: var(--status-danger-color);
|
|
226
|
+
--jt-bool-icon-size: 1.1em;
|
|
227
|
+
--jt-bool-true-color: var(--status-success-color);
|
|
228
|
+
--jt-busy-opacity: .5;
|
|
229
|
+
--jt-caption-color: var(--text-muted);
|
|
230
|
+
--jt-caption-font-size: var(--font-size-sm);
|
|
231
|
+
--jt-empty-color: var(--text-muted);
|
|
232
|
+
--jt-empty-padding-block: var(--size-sm);
|
|
225
233
|
--jt-info-color: var(--text-muted);
|
|
226
234
|
--jt-info-font-size: var(--font-size-sm);
|
|
227
235
|
--jt-info-gap: var(--size-sm);
|
|
228
236
|
--jt-info-outer-padding-block-end: var(--size-xs);
|
|
237
|
+
--jt-pagination-border-color: var(--table-border-color);
|
|
238
|
+
--jt-pagination-border-width: 1px;
|
|
239
|
+
--jt-pagination-btn-min-width: 2.2em;
|
|
240
|
+
--jt-pagination-btn-padding-block: var(--table-cell-padding-block);
|
|
241
|
+
--jt-pagination-btn-padding-inline: var(--table-cell-padding-inline);
|
|
242
|
+
--jt-pagination-current-background-color: var(--table-thead-background-color);
|
|
243
|
+
--jt-pagination-current-font-weight: var(--font-weight-semibold);
|
|
244
|
+
--jt-pagination-disabled-opacity: .5;
|
|
245
|
+
--jt-pagination-font-size: var(--font-size-sm);
|
|
246
|
+
--jt-pagination-hover-background-color: var(--table-body-tr-hover-bg-color);
|
|
247
|
+
--jt-pagination-icon-size: 1em;
|
|
248
|
+
--jt-pagination-line-height: var(--table-cell-line-height);
|
|
249
|
+
--jt-pagination-radius: var(--radius-xxs);
|
|
229
250
|
--jt-search-max-width: 20rem;
|
|
251
|
+
--jt-sort-btn-line-height: var(--table-cell-line-height);
|
|
252
|
+
--jt-sort-btn-padding-block: var(--table-cell-padding-block);
|
|
253
|
+
--jt-sort-btn-padding-inline: var(--table-cell-padding-inline);
|
|
254
|
+
--jt-sort-icon-gap: .4em;
|
|
255
|
+
--jt-sort-icon-none-opacity: .4;
|
|
256
|
+
--jt-sort-icon-size: 1em;
|
|
257
|
+
--jt-table-footer-padding-block-start: var(--size-xs);
|
|
258
|
+
--jt-thead-hover-background-color: color-mix(in srgb, var(--table-thead-background-color) 90%, var(--accent));
|
|
230
259
|
--jt-wrapper-margin-block: var(--size-md);
|
|
231
260
|
|
|
232
261
|
--line-height-base: 1.5;
|
package/src/minimo.css
CHANGED
|
@@ -24,7 +24,7 @@ import { parseDomString } from './parseDomString.js';
|
|
|
24
24
|
* arrays. Mutually exclusive with `tag`/`content`/`children`: when set (and `tag` is absent), every other
|
|
25
25
|
* property except `condition` and `callback` is ignored.
|
|
26
26
|
* @property {boolean} [condition=true] - When false, the element (or text node) is skipped. (default: true)
|
|
27
|
-
* @property {(
|
|
27
|
+
* @property {((el: HTMLElement|Text) => void) | null} [callback] - Callback invoked after the element (or text node) is created.
|
|
28
28
|
* @property {Array<DomBuilderItem|string|Node>} [children] - Configuration array for child elements. Accepts strings (shorthand per `parseDomString`), configuration objects, and/or `Node`s (an `Element`, a `DocumentFragment`, ...) inserted as-is.
|
|
29
29
|
*/
|
|
30
30
|
|
|
@@ -285,10 +285,14 @@ export function domBuilder(/** @type {Array<DomBuilderItem|string|Node>} */ stru
|
|
|
285
285
|
el.textContent = content;
|
|
286
286
|
|
|
287
287
|
} else if (typeof el.setHTML === 'function') {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
288
|
+
/* markup: sanitize via the native Sanitizer API, stripping <script>, event handler
|
|
289
|
+
attributes, javascript: URLs, etc. while still allowing harmless formatting tags
|
|
290
|
+
(<strong>, <em>, <a>, ...).
|
|
291
|
+
The empty sanitizer config keeps every element/attribute not in the built-in unsafe
|
|
292
|
+
baseline: without it the browser default configuration also removes `class`, `id`,
|
|
293
|
+
`style` and `data-*` attributes (observed in Chrome 152), breaking any markup string
|
|
294
|
+
that relies on CSS classes */
|
|
295
|
+
el.setHTML(content, { sanitizer: {} });
|
|
292
296
|
|
|
293
297
|
} else {
|
|
294
298
|
// Sanitizer API not supported by this browser: fall back to the historical,
|