Skip to content

Commit d64ca73

Browse files
committed
Version 2.12
1 parent 2d3164c commit d64ca73

File tree

1 file changed

+97
-45
lines changed

1 file changed

+97
-45
lines changed

csscomb/libs/csscomb.php

Lines changed: 97 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
<?php
22
/**
33
* CSScomb
4-
* @version: 2.11 (build 3ded73c-1208080145)
5-
* @author: Vyacheslav Oliyanchuk (miripiruni)
6-
* @web: http://csscomb.com/
4+
*
5+
* Tool for sorting CSS properties in specific order
6+
*
7+
* @version 2.12 (build e784736-1301040046)
8+
* @author Vyacheslav Oliyanchuk (miripiruni) <mail@csscomb.com>
9+
* @license MIT
10+
* @web http://csscomb.com/
711
*/
8-
12+
913
error_reporting(E_ALL);
10-
14+
1115
class csscomb{
1216

1317
var $sort_order = Array(),
@@ -24,6 +28,8 @@ class csscomb{
2428
'expressions' => null,
2529
// если найдены data uri, то эта переменная станет массивом...
2630
'datauri' => null,
31+
// если найдены интерполированные переменные, то эта переменная станет массивом
32+
'interpolations' => null,
2733
// если найдены CSS-хаки мешающие парсить, то эта переменная станет массивом...
2834
'hacks' => null,
2935
// если найдены комментарии содержащие { или } мешающие парсить,
@@ -125,18 +131,18 @@ class csscomb{
125131
"-webkit-border-radius",
126132
"-moz-border-radius",
127133
"border-radius",
134+
"-webkit-border-top-left-radius",
135+
"-moz-border-radius-topleft",
136+
"border-top-left-radius",
128137
"-webkit-border-top-right-radius",
129-
"-moz-border-top-right-radius",
138+
"-moz-border-radius-topright",
130139
"border-top-right-radius",
131140
"-webkit-border-bottom-right-radius",
132-
"-moz-border-bottom-right-radius",
141+
"-moz-border-radius-bottomright",
133142
"border-bottom-right-radius",
134143
"-webkit-border-bottom-left-radius",
135-
"-moz-border-bottom-left-radius",
144+
"-moz-border-radius-bottomleft",
136145
"border-bottom-left-radius",
137-
"-webkit-border-top-left-radius",
138-
"-moz-border-top-left-radius",
139-
"border-top-left-radius",
140146
"-webkit-border-image",
141147
"-moz-border-image",
142148
"-o-border-image",
@@ -230,6 +236,8 @@ class csscomb{
230236
"-ms-writing-mode",
231237
"vertical-align",
232238
"text-align",
239+
"-webkit-text-align-last",
240+
"-moz-text-align-last",
233241
"-ms-text-align-last",
234242
"text-align-last",
235243
"text-decoration",
@@ -360,6 +368,7 @@ class csscomb{
360368
"-ms-animation-direction",
361369
"-o-animation-direction",
362370
"animation-direction",
371+
"pointer-events",
363372
"unicode-bidi",
364373
"direction",
365374
"-webkit-columns",
@@ -559,7 +568,8 @@ class csscomb{
559568
"-o-animation-direction",
560569
"animation-direction",
561570
"text-align",
562-
"text-align-last",
571+
"-webkit-text-align-last",
572+
"-moz-text-align-last",
563573
"-ms-text-align-last",
564574
"text-align-last",
565575
"vertical-align",
@@ -592,7 +602,8 @@ class csscomb{
592602
"tab-size",
593603
"-webkit-hyphens",
594604
"-moz-hyphens",
595-
"hyphens"
605+
"hyphens",
606+
"pointer-events"
596607
],
597608
[
598609
"opacity",
@@ -624,18 +635,18 @@ class csscomb{
624635
"-webkit-border-radius",
625636
"-moz-border-radius",
626637
"border-radius",
638+
"-webkit-border-top-left-radius",
639+
"-moz-border-radius-topleft",
640+
"border-top-left-radius",
627641
"-webkit-border-top-right-radius",
628-
"-moz-border-top-right-radius",
642+
"-moz-border-radius-topright",
629643
"border-top-right-radius",
630644
"-webkit-border-bottom-right-radius",
631-
"-moz-border-bottom-right-radius",
645+
"-moz-border-radius-bottomright",
632646
"border-bottom-right-radius",
633647
"-webkit-border-bottom-left-radius",
634-
"-moz-border-bottom-left-radius",
648+
"-moz-border-radius-bottomleft",
635649
"border-bottom-left-radius",
636-
"-webkit-border-top-left-radius",
637-
"-moz-border-top-left-radius",
638-
"border-top-left-radius",
639650
"-webkit-border-image",
640651
"-moz-border-image",
641652
"-o-border-image",
@@ -716,11 +727,25 @@ class csscomb{
716727

717728
/**
718729
* @param string css
719-
* @param boolean debug
720-
* @param json custom_sort_order JSON expected
721-
* @return string
730+
* @param boolean debug, OPTIONAL
731+
* @param json custom_sort_order JSON expected, OPTIONAL
732+
* @return string|false
722733
*
723734
* @TODO: https://github.com/miripiruni/CSScomb/issues/21
735+
*
736+
* Example:
737+
*
738+
* <code>
739+
* require_once 'PATH_TO_CSScomb/csscomb.php';
740+
*
741+
* $c = new csscomb();
742+
* $result_code = $c->csscomb(
743+
* 'div {margin-top:0; color: red; display: inline;}',
744+
* false,
745+
* $MY_JSON_SORT_ORDER
746+
* );
747+
* </code>
748+
*
724749
*/
725750
function csscomb($css = '', $debug = false, $custom_sort_order = null) {
726751
$this->output = $debug ? true : false;
@@ -872,18 +897,27 @@ function preprocess() {
872897
endwhile;
873898
}
874899

875-
// 4. Закрываем сложности парсинга {}
900+
// 4. Interpolated variables
901+
preg_match_all('@(\#|\@){.*?}@ismx', $this->code['edited'], $this->code['interpolations']);
902+
foreach ($this->code['interpolations'][0] as $key => $value) {
903+
$pos = strpos($this->code['edited'], $value);
904+
if ($pos !== false) {
905+
$this->code['edited'] = substr_replace($this->code['edited'],"interpolation".$key.'__',$pos,strlen($value));
906+
}
907+
}
908+
909+
// 5. Закрываем сложности парсинга {}
876910
$this->code['edited'] = str_replace('{}', '{ }', $this->code['edited']);
877911

878-
// 5. Закрываем сложности с отсутствующей последней ; перед }
912+
// 6. Закрываем сложности с отсутствующей последней ; перед }
879913
$this->code['edited'] = preg_replace('@(.*?[^\s;\{\}\/\*])(\s*?})@', '$1;$2', $this->code['edited']);
880914
// Убираем ; у последнего инлайнового комментария
881915
// Инлайновый комментарий может идти только после фигурной скобки или ;
882916
$this->code['edited'] = preg_replace('@([;\{\}]+\s*?//.*?);(\s*?})@', '$1$2', $this->code['edited']);
883917
// Убираем ; у интерполированных переменных
884-
$this->code['edited'] = preg_replace('@(#\{\$.*?)[;](\s*?\})@', '$1$2', $this->code['edited']);
918+
$this->code['edited'] = preg_replace('/((#\{\$|\@\{).*?)[;](\s*?\})/', '$1$3', $this->code['edited']);
885919

886-
// 6. Комментарии
920+
// 7. Комментарии
887921
if (preg_match_all('@
888922
(
889923
\s*
@@ -894,7 +928,7 @@ function preprocess() {
894928
)
895929
@ismx', $this->code['edited'], $test)) {
896930

897-
// 6.1. Закомментировано одно или несколько свойств: повторяющийся паттерн *:*; \s*?
931+
// 7.1. Закомментировано одно или несколько свойств: повторяющийся паттерн *:*; \s*?
898932
if (preg_match_all('@
899933
(\s*)
900934
/\*
@@ -943,7 +977,7 @@ function preprocess() {
943977
}
944978
}
945979

946-
// 6.2. Обрывки закомментированных деклараций: присутствует { или }
980+
// 7.2. Обрывки закомментированных деклараций: присутствует { или }
947981
if (preg_match_all('@
948982
\s*?
949983
/\*
@@ -978,7 +1012,7 @@ function preprocess() {
9781012
}
9791013
}
9801014

981-
// 7. Entities
1015+
// 8. Entities
9821016
if (preg_match_all('@
9831017
\&
9841018
\#?
@@ -1087,28 +1121,37 @@ function parse_root($css = '') {
10871121
*
10881122
*/
10891123
function parse_child($value = '') {
1124+
$block_imports = array();
10901125
// 1. Ищем «детей» (вложенные селекторы)
10911126
preg_match_all('@
1092-
[^\};]*?[\s]*?\{((([^\{\}]+)|(?R))*)\}
1127+
[^};]*?
1128+
{
1129+
(
1130+
(
1131+
([^\{\}]+)|(?R)
1132+
)*
1133+
)
1134+
}
10931135
@ismx', $value, $nested);
10941136

1095-
// Убираем из выборки интерполированные переменные
1096-
foreach ($nested[0] as $nested_key => $nested_value) {
1097-
if (strpos($nested_value, '#{$')) {
1098-
unset($nested[0][$nested_key]);
1137+
// TODO: возможно, вынести отдельной функцией, т.к. часто повторяется
1138+
foreach ($nested[0] as $key => &$nest) {
1139+
$value = str_replace($nest, '', $value);
1140+
if(strpos(trim($nest), '@include') === 0) {
1141+
$value = str_replace($nest, '', $value);
1142+
$old_nest = $nested[1][$key];
1143+
$new_nest = $this->parse_child($nested[1][$key]);
1144+
$nest = str_replace($old_nest, $new_nest, $nest);
1145+
$block_imports[] = $nest;
1146+
unset($nested[0][$key]);
1147+
unset($nested[1][$key]);
10991148
}
11001149
}
11011150

11021151
// Сохраняем всех «детей» в строку для последующей замены
11031152
// TODO: убрать, если без этого можно обойтись
11041153
$nested_string = implode('', $nested[0]);
11051154

1106-
// Удаляем «детей» из общей строки
1107-
// TODO: возможно, вынести отдельной функцией, т.к. часто повторяется
1108-
foreach ($nested[0] as &$nest) {
1109-
$value = str_replace($nest, '', $value);
1110-
}
1111-
11121155
// Рекурсия, ahoj!
11131156
// Сортируем содержимое «детей»
11141157
foreach ($nested[1] as &$child) {
@@ -1135,20 +1178,23 @@ function parse_child($value = '') {
11351178

11361179
// Включения, следующие сразу за {
11371180
preg_match_all('@
1138-
^\s*\@[^;]+?[;]
1181+
(^\s*\@[^;]+?[;])|(^\s*\.[^;:]+?[;])
11391182
@isx', $value, $first_imports);
11401183
foreach ($first_imports[0] as &$first_import) {
11411184
$value = str_replace($first_import, '', $value);
11421185
}
11431186

11441187
// Все остальные
11451188
preg_match_all('@
1146-
[;\{\}]+(\s*\@[^;]+?[;])
1189+
(?<=[;}])(\s*\@[^;]+?[;])|(?<=[;}])(\s*\.[^;:]+?[;])
11471190
@ismx', $value, $imports);
11481191
// Удаляем их из общей строки
11491192
foreach ($imports[1] as &$import) {
11501193
$value = str_replace($import, '', $value);
11511194
}
1195+
foreach ($imports[2] as &$import) {
1196+
$value = str_replace($import, '', $value);
1197+
}
11521198

11531199
// 4. Выносим простые свойства в массив $properties
11541200
preg_match_all('@
@@ -1168,7 +1214,7 @@ function parse_child($value = '') {
11681214

11691215
// 6. Склеиваем всё обратно в следующем порядке:
11701216
// переменные, включения, простые свойства, вложенные {}
1171-
$value = implode('', $vars[0]).implode('', $first_imports[0]).implode('', $imports[1]).implode('', $props).$nested_string.$value;
1217+
$value = implode('', $vars[0]).implode('', $first_imports[0]).implode('', $imports[1]).implode('', $imports[2]).implode('', $block_imports).implode('', $props).$nested_string.$value;
11721218
return $value;
11731219
}
11741220

@@ -1438,7 +1484,13 @@ function postprocess() {
14381484
}
14391485
}
14401486

1441-
// 4. Удаляем искусственно созданные 'commented__'
1487+
// 4. Interpolated variables
1488+
preg_match_all('#interpolation(\d)__#ismx', $this->code['resorted'], $new_vars);
1489+
foreach ($new_vars[1] as $key => $value) {
1490+
$this->code['resorted'] = str_replace($new_vars[0][$key], $this->code['interpolations'][0][$key], $this->code['resorted']);
1491+
}
1492+
1493+
// 5. Удаляем искусственно созданные 'commented__'
14421494
while(strpos($this->code['resorted'], 'commented__') !== FALSE) {
14431495
$this->code['resorted'] = preg_replace(
14441496
'#
@@ -1453,7 +1505,7 @@ function postprocess() {
14531505
);
14541506
}
14551507

1456-
// 5. Удаляем искусственно созданные 'brace__'
1508+
// 6. Удаляем искусственно созданные 'brace__'
14571509
if (is_array($this->code['braces'])) { // если были обнаружены и вырезаны хаки
14581510
foreach ($this->code['braces'] as $key => $val) {
14591511
if (strpos($this->code['resorted'], 'brace__'.$key.'{') !== FALSE) {

0 commit comments

Comments
 (0)