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

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

Tous les pseudo-style commençant par "-spip-" produit toutes les déclinaisons pour les différents navigateurs. Le plugin ne vérifie pas qu'ils existent réellement.

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