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

Last change on this file since 77937 was 77780, checked in by arno@…, 6 years ago

Correction des spip-gradient en roba sous MSIE.

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