source: spip-zone/_plugins_/css_imbriques/css_imbriques_fonctions.php @ 64420

Last change on this file since 64420 was 64420, checked in by arno@…, 7 years ago

Compat SPIP 3

File size: 12.0 KB
Line 
1<?php
2if (!defined('_ECRIRE_INC_VERSION')) return;
3
4
5if (!defined("_UTILISER_PIE_HTC")) define("_UTILISER_PIE_HTC", true);
6
7
8$GLOBALS["css_imbriques_medias_queries"] = array();
9
10// filtre couleur_rgba converti une mention de couleur hexadecimale
11// en couleur semi_transparente rgba
12// [(#COULEUR_HEX|couleur_rgba{0.5})]
13function DEFINIR_couleur_rgba () {
14        function couleur_rgba($couleur, $alpha) {
15                include_spip("inc/filtres_images_lib_mini");
16                $couleurs = _couleur_hex_to_dec($couleur);
17
18                $red = $couleurs["red"];
19                $green = $couleurs["green"];
20                $blue = $couleurs["blue"];
21               
22                return "rgba($red, $green, $blue, $alpha)";
23        }
24}
25
26if (!function_exists('couleur_rgba')) {
27        DEFINIR_couleur_rgba ();
28}
29
30
31
32function css_inserer_tab($def) {
33        $def = preg_replace(",\n,", "\n\t", $def);
34       
35        return "\t".$def;
36}
37
38
39function css_contruire($css, $niveau, $chemin, $classe, $enfants, $definition) {
40
41        $intitule = trim($classe[$niveau]);
42        if (substr($intitule, 0, 2) == ". ") {
43                $intitule = substr($intitule, 2, strlen($intitule));
44                $chemin = $chemin.$intitule;
45        }
46        else {
47                $chemin = trim($chemin ." ".$intitule);
48        }
49       
50        $def = $definition[$niveau];
51       
52        if (strlen($def) > 0) {
53//              echo "<li><b>$chemin</b>";
54//              echo "<br>$def";
55               
56                $def = css_inserer_tab($def);
57       
58                if ( strlen(trim($chemin)) > 0 ) $ret = "\n".$chemin." {\n".$def."\n}";
59//              echo "<pre>$css</pre>";
60        }
61       
62
63        if ($enfants[$niveau]) {
64                foreach($enfants[$niveau] as $num) {
65                        $ret .= css_contruire($css, $num, $chemin, $classe, $enfants, $definition);
66       
67                }
68        }
69       
70        return $ret;
71}
72
73function css_imbriques_couleurs_ie ($coul) {
74        if (preg_match(",^\#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$,", $coul, $conv)) {
75                $coul = "#".$conv[1].$conv[1].$conv[2].$conv[2].$conv[3].$conv[3];
76        }
77       
78        return $coul;
79}
80
81function css_imbriques_conv_dec255 ($coul) {
82        $coul = trim ($coul);
83       
84        if (preg_match(",(.*)\%$,", $coul, $pourcent)) {
85                $coul = round($pourcent[1] * 255 / 100);
86        }
87        return $coul;
88}
89
90function css_imbriques_traiter_spip($regs) {
91        // -spip-box-sizing
92        // -spip-font-smoothing
93       
94        if (_UTILISER_PIE_HTC) {
95                if (function_exists(chemin)) $pie = url_absolue(chemin("PIE.htc"));
96                else $pie = url_absolue(find_in_path("PIE.htc"));
97        }
98
99       
100        $style = $regs[1];
101        $val = trim($regs[2]);
102        switch($style) {
103                case "border-radius" :
104                        $ret = "-webkit-border-radius:$val;";
105                        $ret .= "-moz-border-radius:$val;";
106                        $ret .= "border-radius:$val;";
107                        if (_UTILISER_PIE_HTC) $ret .= "behavior: url($pie);";
108                        break;
109                case "border-top-right-radius" :
110                        $ret = "-webkit-border-top-right-radius:$val;";
111                        $ret .= "-moz-border-radius-topright:$val;";
112                        $ret .= "border-top-right-radius:$val;";
113                        if (_UTILISER_PIE_HTC) $ret .= "behavior: url($pie);";
114                        break;
115                case "border-top-left-radius" :
116                        $ret = "-webkit-border-top-left-radius:$val;";
117                        $ret .= "-moz-border-radius-topleft:$val;";
118                        $ret .= "border-top-left-radius:$val;";
119                        if (_UTILISER_PIE_HTC) $ret .= "behavior: url($pie);";
120                        break;
121                case "border-bottom-right-radius" :
122                        $ret = "-webkit-border-bottom-right-radius:$val;";
123                        $ret .= "-moz-border-radius-bottomright:$val;";
124                        $ret .= "border-bottom-right-radius:$val;";
125                        if (_UTILISER_PIE_HTC) $ret .= "behavior: url($pie);";
126                        break;
127                case "border-bottom-left-radius" :
128                        $ret = "-webkit-border-bottom-left-radius:$val;";
129                        $ret .= "-moz-border-radius-bottomleft:$val;";
130                        $ret .= "border-bottom-left-radius:$val;";
131                        if (_UTILISER_PIE_HTC) $ret .= "behavior: url($pie);";
132                        break;
133                       
134                case "opacity" :
135                        $val_ie = round($val * 100);
136                        $ret = "-webkit-opacity:$val;";
137                        $ret .= "-moz-opacity:$val;";
138                        $ret .= "opacity:$val;";
139                        $ret .= "filter:alpha(opacity=$val_ie);";
140                        //$ret .= "-ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(opacity=$val_ie)\";zoom:1;";
141                        break; 
142                case "text-shadow":
143                        $ret .= "text-shadow:$val;";
144                        if (preg_match(",(\-?[0-9]+)px\ *(\-?[0-9]+)px\ *([0-9]+)px\ *(#?[0-9a-zA-Z]*),", $val, $val_ie)) {
145                                $x = $val_ie[1];
146                                $y = $val_ie[2];
147                                $s = $val_ie[3];
148                                $coul = $val_ie[4];
149                        }
150                       
151                        if ($x == 0 && $y == 0) {
152                                $ret .= "zoom:1; filter:progid:DXImageTransform.Microsoft.Glow(Color=$coul,Strength=$s);";
153                        }
154                       
155                        break;
156                case "box-shadow": 
157                        $ret = "-webkit-box-shadow:$val;";
158                        $ret .= "-moz-box-shadow:$val;";
159                        $ret .= "box-shadow:$val;";
160                        if (_UTILISER_PIE_HTC) $ret .= "behavior: url($pie);";
161                        break;
162                case "background-color":
163                        if (preg_match(",(rgba?)[\ \t]*\(([^\,]*)\,([^\,]*)\,([^\,]*)\,?([^\,]*)?\),", $val, $couls)) {
164                                $rgba = trim($couls[1]);
165                                $r = css_imbriques_conv_dec255($couls[2]);
166                                $g = css_imbriques_conv_dec255($couls[3]);
167                                $b = css_imbriques_conv_dec255($couls[4]);
168                                $a = trim($couls[5]);
169
170                                $red = dechex($r);
171                                $green = dechex($g);
172                                $blue = dechex($b);
173                                $alpha = dechex(round($a * 255));
174                               
175                                if (strlen($red) == 1) $red = "0".$red;
176                                if (strlen($green) == 1) $green = "0".$green;
177                                if (strlen($blue) == 1) $blue = "0".$blue;
178                                if (strlen($alpha) == 1) $alpha = "0".$alpha;
179
180                                //$ret = "background-color: #$red$green$blue;";
181                                if ($rgba == "rgba") {
182                                        $ret .= "background-color: rgba($r,$g,$b,$a);";
183                                        $ret .= "filter:  progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#$alpha$red$green$blue', endColorstr='#$alpha$red$green$blue');";
184                                } else {
185                                        $ret = "background-color: #$red$green$blue;";
186                                }
187                        }
188                        break;
189                case "gradient": 
190                        // -spip-gradient: top, #000000, #ffffff;
191                        // directions: "top" (vertical) ou "left" (horizontal)
192                        if (preg_match("#\ ?(.*)\ ?\,\ ?(.*)\ ?\,\ ?(.*)\ ?#", $val, $conv)) {
193                                $dir = strtolower($conv[1]);
194                                $debut = $conv[2];
195                                $fin = $conv[3];
196                               
197                                $debut_ie = css_imbriques_couleurs_ie($debut);
198                                $fin_ie = css_imbriques_couleurs_ie($fin);
199
200                                // $ret = "background: $debut;";
201                               
202                                if ($dir == "top") {
203                                        $ret = "background: -webkit-gradient(linear, left top, left bottom, from($debut), to($fin));";
204                                        $ret .= "background-image: -webkit-linear-gradient(top, $debut, $fin);";
205                                        $ret .= "background-image: -moz-linear-gradient(top, $debut, $fin);";
206                                        $ret .= "background-image: -ms-linear-gradient(top, $debut, $fin);";
207                                        $ret .= "background-image: -o-linear-gradient(top, $debut, $fin);";
208                                        $ret .= "background-image: linear-gradient(top, $debut, $fin);";
209                                        $ret .= "filter:  progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='$debut_ie', endColorstr='$fin_ie');";
210                                        // La version IE8 n'a pas l'air necessaire
211                                        //$ret .= "-ms-filter: \"progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='$debut_ie', endColorstr='$fin_ie')\";";
212                                }
213                                else {
214                                        $ret = "background: -webkit-gradient(linear, left top, right top, from($debut), to($fin));";
215                                        $ret .= "background-image: -moz-linear-gradient(left, $debut, $fin);";
216                                        $ret .= "filter:  progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='$debut_ie', endColorstr='$fin_ie');";
217                                        //$ret .= "-ms-filter: \"progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='$debut_ie', endColorstr='$fin_ie')\";";
218                                }
219                        }
220                        break;
221                case "clear";
222                        $ret = "zoom:1;\n";
223                        $ret .= ". :before,. :after  {content:\"\";\ndisplay:block;overflow:hidden;}\n";
224                        $ret .= ". :after{clear:both;}\n";
225                        break;
226                default:
227                        $ret = "-moz-$style:$val;";
228                        $ret .= "-webkit-$style:$val;";
229                        $ret .= "-khtml-$style:$val;";
230                        $ret .= "-ms-$style:$val;";
231                        $ret .= "-o-$style:$val;";
232                        $ret .= "$style:$val;";
233                       
234        }
235        return $ret;
236
237       
238}
239
240function css_imbriques_pseudo($css) {
241       
242        $css = preg_replace_callback(",\-spip\-([a-z\-]*)\ *\:\ *([^\;]*)\ *\;,", "css_imbriques_traiter_spip", $css);
243       
244        return $css;
245}
246
247function css_imbriques_forcer_position($css) {
248        if (_UTILISER_PIE_HTC)  {
249                if (preg_match("/border[a-z\-]*\-radius|box\-shadow/", $css) && !preg_match("/position\ ?\:/", $css)) {
250                        $css .= "position:relative;";
251                }
252        }
253        return $css;
254}
255
256
257function extraire_filters_ie($css) {
258        if (preg_match_all(",filter\:(.*)\;,", $css, $regs)) {
259                $filtres = "filter:".join($regs[1], ", ").";";
260               
261                $css = preg_replace(",filter\:(.*)\;,", "", $css);
262                $css .= $filtres;
263        }
264        return $css;
265}
266
267function css_imbriques_decouper ($css) {
268       
269       
270        $css = preg_replace(",\n[\t\ ]*,", "\n", trim($css));
271        $css = preg_replace(",\n+,", "\n", $css);
272       
273        // Remettre les criteres multilignes sur une ligne
274        $css = preg_replace("#\,\ *\n#", ", ", $css);
275       
276
277        // Virer les commentaires (source d'erreurs, et on ne sait plus ou les placer puisqu'on reorganise la bazar)
278        $css = preg_replace('#(/\*[^*]*\*+([^/*][^*]*\*+)*/)#', '', $css);
279        $css = preg_replace('#\n(\ \t)*\{#', ' {', $css);
280
281
282        // placer l'ensemble dans une fausse classe globale pour pouvoir la traiter d'un coup a la fin
283        $css = "   {\n$css\n}";
284       
285        $css = css_imbriques_pseudo($css);
286       
287        while (preg_match ("/([^\{\n]*)\{([^\{]*)\}/U", $css, $regs)) {
288               
289                        $intitule = trim($regs[1]);
290
291                        if (preg_match(",^@media,", $intitule)) $intitule .= " media@";
292
293                                               
294                        $def = trim($regs[2]);
295                        $def = css_imbriques_forcer_position($def);
296
297
298
299                        $chaine = $regs[0];
300                        $pos = strpos($css, $chaine);
301                        $debut = substr($css, 0, $pos);
302                        $fin = substr($css, $pos + strlen($chaine), strlen($css));
303
304
305                        if (preg_match("#\,#", $intitule)) {
306                                $entrees = explode(",", $intitule);
307                               
308                                $ret = "";
309                               
310                                foreach ($entrees as $intitule) {
311                                        $intitule = trim($intitule);
312                                       
313//                                      echo "<li>$intitule</li>";
314                                       
315                                        $ret .= "$intitule { $def }\n";
316                                       
317                                       
318                                }
319                                                               
320                                $css = $debut.$ret.$fin;
321                               
322//                              echo "<pre>$css </pre><hr>";
323                               
324                        } else {
325                       
326                               
327               
328                                $compteur ++;
329                       
330                                $classe[$compteur] = $intitule;
331                                $definition[$compteur] = trim($regs[2]);
332                               
333//                              echo "<li>".$classe[$compteur];
334                               
335                               
336                                preg_match_all("/\[\[([0-9]*)\]\]/", $definition[$compteur], $sous);
337                                foreach($sous[1] as $enfant) {
338                                        $enfants[$compteur][] = $enfant;
339                                }
340       
341                                $definition[$compteur] = extraire_filters_ie(css_imbriques_forcer_position(preg_replace("#[\ \n]*\[\[[0-9]*\]\][\ \n]*#", "", $definition[$compteur])));
342//                              echo "<li>".$definition[$compteur];
343//                              $def = extraire_filters_ie($def);
344       
345                               
346                               
347                               
348                               
349                                $css = $debut."[[$compteur]]".$fin;
350                        }
351                       
352//                      $css = str_replace($regs[0][$num], "[[$compteur]]", $css);
353                       
354               
355        }
356
357       
358        $css = "";
359       
360        $css = css_contruire($css, $compteur, "", $classe, $enfants, $definition);
361
362
363       
364       
365        // Derniere passe: "minifier" les CSS
366        $css = preg_replace(",\n,", "", $css);
367        $css = preg_replace(",\t,", "", $css);
368        $css = preg_replace(",\},", "}\n", $css);
369
370        // Rechercher les media_queries
371        $css = preg_replace_callback(",(.*(@media .* media@).*)\{(.*)\}\n?,", "css_imbriques_traiter_media", $css);
372        if (count($GLOBALS["css_imbriques_medias_queries"]) > 0) {
373                foreach($GLOBALS["css_imbriques_medias_queries"] as $k=>$val) {
374                        $css .= $k ."{\n". $val . "}\n";
375                }
376        }
377
378
379        return $css;
380}
381
382
383function css_imbriques_traiter_media($reg) {
384        $query = $reg[2];
385        $query = trim(substr(trim($query), 0, strlen($query) - 6));
386       
387        $intitule = str_replace($reg[2], "", $reg[1]);
388        $intitule = trim(preg_replace(",\ +,", " ", $intitule));
389       
390       
391        $definition = $reg[3];
392
393        $GLOBALS["css_imbriques_medias_queries"]["$query"] .= $intitule."{".$definition."}\n";
394        return;
395}
396
397function css_imbriques ($css) {
398
399        $path = dirname(url_absolue($css))."/"; // pour mettre sur les images   
400       
401               
402
403        // 2.
404        $dir_var = sous_repertoire (_DIR_VAR, 'cache-css');
405        $f = $dir_var
406                . substr(md5($css), 0,20) . '_imbriques.css';
407
408
409        // la css peut etre distante (url absolue !)
410        if (preg_match(",^http:,i",$css)){
411                include_spip('inc/distant');
412                $contenu = recuperer_page($css);
413                if (!$contenu) return $css;
414        }
415        else {
416                if ((@filemtime($f) > @filemtime($css))
417                        AND ($GLOBALS['var_mode'] != 'recalcul'))
418                        return $f;
419                if (!lire_fichier($css, $contenu))
420                        return $css;
421        }
422
423        $contenu = css_imbriques_decouper ($contenu);
424
425        // passer les url relatives a la css d'origine en url absolues
426        $contenu = preg_replace(",url\s*\(\s*['\"]?([^'\"/][^:]*)['\"]?\s*\),UimsS",
427                "url($path\\1)",$contenu);
428        // virer les fausses url absolues que l'on a mis dans les import
429        if (count($src_faux_abs))
430                $contenu = str_replace(array_keys($src_faux_abs),$src_faux_abs,$contenu);
431
432        ecrire_fichier ("$f.gz", $contenu, true);
433        if (!ecrire_fichier($f, $contenu))
434                return $css;
435
436        return $f;
437}
438
439?>
Note: See TracBrowser for help on using the repository browser.