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

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

Retour de pie.htc, mais désactivante par
define("_UTILISER_PIE_HTC", false);

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) $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 "transition";
218                case "transition-property";
219                case "transition-duration";
220                case "transition-timing-function";
221                case "transition-delay";
222                        $ret = "-moz-$style:$val;";
223                        $ret .= "-webkit-$style:$val;";
224                        $ret .= "-ms-$style:$val;";
225                        $ret .= "-o-$style:$val;";
226                        $ret .= "$style:$val;";
227               
228                        break;
229                case "clear";
230                        $ret = "zoom:1;\n";
231                        $ret .= ". :before,. :after  {content:\"\";\ndisplay:block;overflow:hidden;}\n";
232                        $ret .= ". :after{clear:both;}\n";
233                        break;
234        }
235       
236       
237        return $ret;
238
239       
240}
241
242function css_imbriques_pseudo($css) {
243       
244        $css = preg_replace_callback(",\-spip\-([a-z\-]*)\ *\:\ *([^\;]*)\ *\;,", "css_imbriques_traiter_spip", $css);
245       
246        return $css;
247}
248
249function css_imbriques_forcer_position($css) {
250        if (_UTILISER_PIE_HTC)  {
251                if (preg_match("/border[a-z\-]*\-radius|box\-shadow/", $css) && !preg_match("/position\ ?\:/", $css)) {
252                        $css .= "position:relative;";
253                }
254        }
255        return $css;
256}
257
258
259function extraire_filters_ie($css) {
260        if (preg_match_all(",filter\:(.*)\;,", $css, $regs)) {
261                $filtres = "filter:".join($regs[1], ", ").";";
262               
263                $css = preg_replace(",filter\:(.*)\;,", "", $css);
264                $css .= $filtres;
265        }
266        return $css;
267}
268
269function css_imbriques_decouper ($css) {
270       
271       
272        $css = preg_replace(",\n[\t\ ]*,", "\n", trim($css));
273        $css = preg_replace(",\n+,", "\n", $css);
274       
275        // Remettre les criteres multilignes sur une ligne
276        $css = preg_replace("#\,\ *\n#", ", ", $css);
277       
278
279        // Virer les commentaires (source d'erreurs, et on ne sait plus ou les placer puisqu'on reorganise la bazar)
280        $css = preg_replace('#(/\*[^*]*\*+([^/*][^*]*\*+)*/)#', '', $css);
281        $css = preg_replace('#\n(\ \t)*\{#', ' {', $css);
282
283
284        // placer l'ensemble dans une fausse classe globale pour pouvoir la traiter d'un coup a la fin
285        $css = "   {\n$css\n}";
286       
287        $css = css_imbriques_pseudo($css);
288       
289        while (preg_match ("/([^\{\n]*)\{([^\{]*)\}/U", $css, $regs)) {
290               
291                        $intitule = trim($regs[1]);
292
293                        if (preg_match(",^@media,", $intitule)) $intitule .= " media@";
294
295                                               
296                        $def = trim($regs[2]);
297                        $def = css_imbriques_forcer_position($def);
298
299
300
301                        $chaine = $regs[0];
302                        $pos = strpos($css, $chaine);
303                        $debut = substr($css, 0, $pos);
304                        $fin = substr($css, $pos + strlen($chaine), strlen($css));
305
306
307                        if (preg_match("#\,#", $intitule)) {
308                                $entrees = explode(",", $intitule);
309                               
310                                $ret = "";
311                               
312                                foreach ($entrees as $intitule) {
313                                        $intitule = trim($intitule);
314                                       
315//                                      echo "<li>$intitule</li>";
316                                       
317                                        $ret .= "$intitule { $def }\n";
318                                       
319                                       
320                                }
321                                                               
322                                $css = $debut.$ret.$fin;
323                               
324//                              echo "<pre>$css </pre><hr>";
325                               
326                        } else {
327                       
328                               
329               
330                                $compteur ++;
331                       
332                                $classe[$compteur] = $intitule;
333                                $definition[$compteur] = trim($regs[2]);
334                               
335//                              echo "<li>".$classe[$compteur];
336                               
337                               
338                                preg_match_all("/\[\[([0-9]*)\]\]/", $definition[$compteur], $sous);
339                                foreach($sous[1] as $enfant) {
340                                        $enfants[$compteur][] = $enfant;
341                                }
342       
343                                $definition[$compteur] = extraire_filters_ie(css_imbriques_forcer_position(preg_replace("#[\ \n]*\[\[[0-9]*\]\][\ \n]*#", "", $definition[$compteur])));
344//                              echo "<li>".$definition[$compteur];
345//                              $def = extraire_filters_ie($def);
346       
347                               
348                               
349                               
350                               
351                                $css = $debut."[[$compteur]]".$fin;
352                        }
353                       
354//                      $css = str_replace($regs[0][$num], "[[$compteur]]", $css);
355                       
356               
357        }
358
359       
360        $css = "";
361       
362        $css = css_contruire($css, $compteur, "", $classe, $enfants, $definition);
363
364
365       
366       
367        // Derniere passe: "minifier" les CSS
368        $css = preg_replace(",\n,", "", $css);
369        $css = preg_replace(",\t,", "", $css);
370        $css = preg_replace(",\},", "}\n", $css);
371
372        // Rechercher les media_queries
373        $css = preg_replace_callback(",(.*(@media .* media@).*)\{(.*)\}\n?,", "css_imbriques_traiter_media", $css);
374        if (count($GLOBALS["css_imbriques_medias_queries"]) > 0) {
375                foreach($GLOBALS["css_imbriques_medias_queries"] as $k=>$val) {
376                        $css .= $k ."{\n". $val . "}\n";
377                }
378        }
379
380
381        return $css;
382}
383
384
385function css_imbriques_traiter_media($reg) {
386        $query = $reg[2];
387        $query = trim(substr(trim($query), 0, strlen($query) - 6));
388       
389        $intitule = str_replace($reg[2], "", $reg[1]);
390        $intitule = trim(preg_replace(",\ +,", " ", $intitule));
391       
392       
393        $definition = $reg[3];
394
395        $GLOBALS["css_imbriques_medias_queries"]["$query"] .= $intitule."{".$definition."}\n";
396        return;
397}
398
399function css_imbriques ($css) {
400
401        $path = dirname(url_absolue($css))."/"; // pour mettre sur les images   
402       
403               
404
405        // 2.
406        $dir_var = sous_repertoire (_DIR_VAR, 'cache-css');
407        $f = $dir_var
408                . substr(md5($css), 0,20) . '_imbriques.css';
409
410
411        // la css peut etre distante (url absolue !)
412        if (preg_match(",^http:,i",$css)){
413                include_spip('inc/distant');
414                $contenu = recuperer_page($css);
415                if (!$contenu) return $css;
416        }
417        else {
418                if ((@filemtime($f) > @filemtime($css))
419                        AND ($GLOBALS['var_mode'] != 'recalcul'))
420                        return $f;
421                if (!lire_fichier($css, $contenu))
422                        return $css;
423        }
424
425        $contenu = css_imbriques_decouper ($contenu);
426
427        // passer les url relatives a la css d'origine en url absolues
428        $contenu = preg_replace(",url\s*\(\s*['\"]?([^'\"/][^:]*)['\"]?\s*\),UimsS",
429                "url($path\\1)",$contenu);
430        // virer les fausses url absolues que l'on a mis dans les import
431        if (count($src_faux_abs))
432                $contenu = str_replace(array_keys($src_faux_abs),$src_faux_abs,$contenu);
433
434        ecrire_fichier ("$f.gz", $contenu, true);
435        if (!ecrire_fichier($f, $contenu))
436                return $css;
437
438        return $f;
439}
440
441?>
Note: See TracBrowser for help on using the repository browser.