Skip to content

Commit 4871f44

Browse files
committed
Version update: 2.14
1 parent e572e2e commit 4871f44

File tree

1 file changed

+87
-147
lines changed

1 file changed

+87
-147
lines changed

plugin/lib/csscomb.php

Lines changed: 87 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Tool for sorting CSS properties in specific order
66
*
7-
* @version 2.13 (build bb516f2-1306162139)
7+
* @version 2.14 (build 57f634a-1307080853)
88
* @author Vyacheslav Oliyanchuk (miripiruni) <mail@csscomb.com>
99
* @license MIT
1010
* @web http://csscomb.com/
@@ -30,6 +30,10 @@ class csscomb{
3030
'datauri' => null,
3131
// если найдены интерполированные переменные, то эта переменная станет массивом
3232
'interpolations' => null,
33+
// Игнорируем комментарии
34+
'comments' => null,
35+
'inlinecomments' => null,
36+
'magicComments' => null,
3337
// если найдены CSS-хаки мешающие парсить, то эта переменная станет массивом...
3438
'hacks' => null,
3539
// если найдены комментарии содержащие { или } мешающие парсить,
@@ -908,119 +912,56 @@ function preprocess() {
908912
}
909913

910914
// 4. Interpolated variables
911-
preg_match_all('@(\#|\@){.*?}@ismx', $this->code['edited'], $this->code['interpolations']);
912-
foreach ($this->code['interpolations'][0] as $key => $value) {
913-
$pos = strpos($this->code['edited'], $value);
914-
if ($pos !== false) {
915-
$this->code['edited'] = substr_replace($this->code['edited'],"interpolation".$key.'__',$pos,strlen($value));
916-
}
915+
preg_match_all('@(\#|\@){.*?}@ismx', $this->code['edited'], $this->code['interpolations'], PREG_SET_ORDER);
916+
foreach ($this->code['interpolations'] as $key => $value) {
917+
$this->code['edited'] = str_replace($value[0], 'interpolation'.$key.'__', $this->code['edited']);
918+
}
919+
920+
// X. Temporally remove comments
921+
// Magic comment
922+
preg_match_all('@
923+
(\s*\/\*\s*csscomb:\s*false\s*\*\/.*?\/\*\s*csscomb:\s*true\s*\*\/)
924+
|
925+
(\s*\/\/\s*csscomb:\s*false[\n\r].*?\/\/\s*csscomb:\s*true[^\n\S\r]*)
926+
@ismx', $this->code['edited'],
927+
$this->code['magicComments'], PREG_SET_ORDER);
928+
foreach ($this->code['magicComments'] as $key => $value) {
929+
$this->code['edited'] = str_replace($value[0], "\nmagic: comment".$key.'__;', $this->code['edited']);
930+
}
931+
// Comments
932+
preg_match_all('@
933+
([\n\r]\s*/\*.*?\*/)+
934+
|
935+
(^\s*/\*.*?\*/)+
936+
|
937+
([\n\r]\s*//[^\n\r]*)+
938+
|
939+
(^\s*//[^\n\r]*)+
940+
@ismx', $this->code['edited'], $this->code['comments'], PREG_SET_ORDER);
941+
foreach ($this->code['comments'] as $key => $value) {
942+
$this->code['edited'] = str_replace($value[0], 'comment'.$key.'__', $this->code['edited']);
943+
}
944+
// Inline comments
945+
preg_match_all('@
946+
[^\S\n\r]*/\*.*?\*/([^\n\S\r]*/\*.*?\*/)*
947+
|
948+
(?<!:)[^\S\n\r]*//[^\n\r]*
949+
@ismx', $this->code['edited'], $this->code['inlinecomments'], PREG_SET_ORDER);
950+
foreach ($this->code['inlinecomments'] as $key => $value) {
951+
$this->code['edited'] = str_replace($value[0], 'inlinecomment'.$key.'__', $this->code['edited']);
917952
}
918953

919954
// 5. Закрываем сложности парсинга {}
920955
$this->code['edited'] = str_replace('{}', '{ }', $this->code['edited']);
921956

922957
// 6. Закрываем сложности с отсутствующей последней ; перед }
923-
$this->code['edited'] = preg_replace('@(.*?[^\s;\{\}\/\*])(\s*?})@', '$1;$2', $this->code['edited']);
958+
$this->code['edited'] = preg_replace('@(.*?[^\s;\{\}\/\*_])(\s*?})@', '$1;$2', $this->code['edited']);
924959
// Убираем ; у последнего инлайнового комментария
925960
// Инлайновый комментарий может идти только после фигурной скобки или ;
926961
$this->code['edited'] = preg_replace('@([;\{\}]+\s*?//.*?);(\s*?})@', '$1$2', $this->code['edited']);
927962
// Убираем ; у интерполированных переменных
928963
$this->code['edited'] = preg_replace('/((#\{\$|\@\{).*?)[;](\s*?\})/', '$1$3', $this->code['edited']);
929964

930-
// 7. Комментарии
931-
if (preg_match_all('@
932-
(
933-
\s*
934-
/\*
935-
.*?[^\*/]
936-
\*/
937-
(\s/\*\*/)?
938-
)
939-
@ismx', $this->code['edited'], $test)) {
940-
941-
// 7.1. Закомментировано одно или несколько свойств: повторяющийся паттерн *:*; \s*?
942-
if (preg_match_all('@
943-
(\s*)
944-
/\*
945-
(.*?[^\*/])
946-
\*+/
947-
(\ {0,1}/\*\*/)?
948-
@ismx', $this->code['edited'], $comments)) {
949-
950-
$new_comments = Array();
951-
$old_comments = $comments[0];
952-
953-
foreach ($comments[2] as $key => $comment) {
954-
if ( // если комментарий содержит ; и :
955-
strpos($comment, ':') !== FALSE AND
956-
strpos($comment, ';') !== FALSE
957-
958-
) {
959-
preg_match_all('@
960-
(\s*)
961-
(
962-
.+?[^;]
963-
;
964-
)
965-
@ismx', $comment, $properties);
966-
967-
$new_comment = '';
968-
foreach ($properties[2] as $property) {
969-
$new_comment .= $comments[1][$key]."commented__".$property;
970-
}
971-
$new_comments[] = $new_comment;
972-
}
973-
else {
974-
// если нет : или ;, то считаем что это текстовый комментарий
975-
// и копируем его в том виде, в каком он был.
976-
$new_comments[] = $comments[0][$key];
977-
}
978-
979-
980-
}
981-
982-
foreach ($old_comments as $key => $old_comment) {
983-
$this->code['edited'] = str_replace(
984-
$old_comments[$key],
985-
$new_comments[$key],
986-
$this->code['edited']);
987-
}
988-
}
989-
990-
// 7.2. Обрывки закомментированных деклараций: присутствует { или }
991-
if (preg_match_all('@
992-
\s*?
993-
/\*
994-
(
995-
.*?[^\*/]
996-
)*?
997-
\*+/
998-
@ismx', $this->code['edited'], $comments)) {
999-
1000-
$new_comments = Array();
1001-
$old_comments = $comments[0];
1002-
1003-
foreach ($comments[0] as $key => $comment) {
1004-
if (strpos($comment, '}') !== FALSE OR strpos($comment, '{') !== FALSE) {
1005-
$new_comment = '';
1006-
if (strpos($comment, '}') !== FALSE) { $new_comment .= '}'; }
1007-
$new_comment .= "brace__".$key;
1008-
if (strpos($comment, '{') !== FALSE) { $new_comment .= '{'; }
1009-
$new_comments[$key] = $new_comment;
1010-
$this->code['braces'][$key] = $comment;
1011-
}
1012-
}
1013-
1014-
foreach ($new_comments as $key => $new_comment) {
1015-
if (strlen($new_comment) > 0) {
1016-
$this->code['edited'] = str_replace(
1017-
$old_comments[$key],
1018-
$new_comment,
1019-
$this->code['edited']);
1020-
}
1021-
}
1022-
}
1023-
}
1024965

1025966
// 8. Entities
1026967
if (preg_match_all('@
@@ -1181,9 +1122,9 @@ function parse_child($value = '') {
11811122

11821123
// 2. Выносим переменные в отдельный массив $vars
11831124
preg_match_all('@
1184-
(\s*/\*[^\*/]*?\*/)?
1185-
(\s*//.*?)?
1125+
(comment\d*__)*
11861126
\s*(\$|\@)[^;\}]+?:[^;]+?;
1127+
(inlinecomment\d*__)*
11871128
@ismx', $value, $vars);
11881129
// Удаляем их из общей строки
11891130
foreach ($vars[0] as $var) {
@@ -1195,29 +1136,32 @@ function parse_child($value = '') {
11951136

11961137
// Включения, следующие сразу за {
11971138
preg_match_all('@
1198-
(^\s*\@[^;]+?[;])|(^\s*\.[^;:]+?[;])
1139+
(^\s*(comment\d*__)*\s*\@[^;]+?[;](inlinecomment\d*__)*)
1140+
|
1141+
(^\s*(comment\d*__)*\s*\.[^;:]+?[;](inlinecomment\d*__)*)
11991142
@isx', $value, $first_imports);
12001143

12011144
// Все остальные
12021145
preg_match_all('@
1203-
(?<=[;}])(\s*\@[^;]+?[;])|(?<=[;}])(\s*\.[^;:]+?[;])
1146+
(?<=inlinecomment\d__|[;}])
1147+
((comment\d*__)?\s*\@[^;]+?[;](inlinecomment\d*__)?)
1148+
|
1149+
(?<=inlinecomment\d__|[;}])
1150+
((comment\d*__)?\s*\.[^;:]+?[;](inlinecomment\d*__)?)
12041151
@ismx', $value, $imports);
12051152
// Удаляем их из общей строки
12061153
foreach ($first_imports[0] as &$first_import) {
12071154
$value = str_replace($first_import, '', $value);
12081155
}
1209-
foreach ($imports[1] as &$import) {
1210-
$value = str_replace($import, '', $value);
1211-
}
1212-
foreach ($imports[2] as &$import) {
1156+
foreach ($imports[0] as &$import) {
12131157
$value = str_replace($import, '', $value);
12141158
}
12151159

12161160
// 4. Выносим простые свойства в массив $properties
12171161
preg_match_all('@
1162+
(comment\d*__)?
12181163
\s*[^;]+?:[^;]+?;
1219-
(\s*/\*.*?[^\*/]\*/)?
1220-
(\s{0,1}/\*\*/)?
1164+
(inlinecomment\d*__)?
12211165
@ismx', $value, $properties);
12221166
// Удаляем их из общей строки
12231167
foreach ($properties[0] as &$property) {
@@ -1227,11 +1171,9 @@ function parse_child($value = '') {
12271171
$props = $properties[0];
12281172
$props = $this->resort_properties($props);
12291173

1230-
// 5. Если осталось ещё что-то, оставляем «как есть»
1231-
12321174
// 6. Склеиваем всё обратно в следующем порядке:
12331175
// переменные, включения, простые свойства, вложенные {}
1234-
$value = implode('', $vars[0]).implode('', $first_imports[0]).implode('', $imports[1]).implode('', $imports[2]).implode('', $block_imports).implode('', $props).$nested_string.$value;
1176+
$value = implode('', $vars[0]).implode('', $first_imports[0]).implode('', $imports[0]).implode('', $block_imports).implode('', $props).$nested_string.$value;
12351177
return $value;
12361178
}
12371179

@@ -1252,7 +1194,6 @@ function parse_properties($css = '') {
12521194
^
12531195
(.*?)
12541196
(
1255-
#(\s*/\*.*\*/;)*?
12561197
\s*?
12571198
}
12581199
)
@@ -1303,17 +1244,15 @@ function parse_properties($css = '') {
13031244
13041245
^
13051246
(.*?)
1306-
(\s*?)
1307-
(/\* .* \*/)
1247+
(inlinecomment\d*__)
13081248
(.*)
13091249
$
13101250
13111251
@ismx', $properties, $matches);
13121252

13131253
if (
13141254
count($matches) === 5 and // все распарсилось как надо
1315-
strlen($matches[1]) === 0 and // комментарий действительно идет первым
1316-
strpos($matches[2], "\n") !== 0 // перед комментарием нет переноса строки, следовательно предпологаем, что он относится к скобке с селектором
1255+
strlen($matches[1]) === 0 // комментарий действительно идет первым
13171256
) {
13181257
$first_spaces = $matches[2];
13191258
$first_comment = $matches[3];
@@ -1330,10 +1269,7 @@ function parse_properties($css = '') {
13301269
.[^;]*
13311270
;
13321271
( # На этой же строке (после ;) может быть комментарий. Он тоже пригодится.
1333-
\s*
1334-
/\*
1335-
.*?[^\*/]
1336-
\*/
1272+
inlinecomment\d*__
13371273
)
13381274
?
13391275
(\s{0,1}/\*\*/)?
@@ -1361,8 +1297,7 @@ function parse_properties($css = '') {
13611297
.[^;]* # все что угодно, но не ;
13621298
;
13631299
( # На этой же строке (после ;) может быть комментарий. Он тоже пригодится.
1364-
\s*
1365-
/\* .* \*/
1300+
inlinecomment\d*__
13661301
)
13671302
*?
13681303
)
@@ -1406,9 +1341,7 @@ function resort_properties($prop) {
14061341
* Пробел в начале добавляется специально, чтобы избежать совпадений по вхождению
14071342
* одной строки в другую. Например: top не должно совпадать с border-top
14081343
*/
1409-
strpos(' '.trim($property), ' '.$k.':') !== FALSE OR
1410-
strpos(' '.trim($property), ' commented__'.$k.':') !== FALSE
1411-
1344+
strpos(' '.trim($property), ' '.$k.':') !== FALSE
14121345
) {
14131346
$through_number = $this->get_through_number($k); // определяем "сквозной" порядковый номер
14141347
if ($through_number !== false) $index = $through_number;
@@ -1421,8 +1354,7 @@ function resort_properties($prop) {
14211354
foreach ($this->sort_order as $pos => $key) {
14221355
if (
14231356
// пробел в начале добавляется специально.
1424-
strpos(' '.trim($property), ' '.$key.':') !== FALSE OR
1425-
strpos(' '.trim($property), ' commented__'.$key.':') !== FALSE
1357+
strpos(' '.trim($property), ' '.$key.':') !== FALSE
14261358
) {
14271359
$index = $pos;
14281360
}
@@ -1506,26 +1438,34 @@ function postprocess() {
15061438
}
15071439

15081440
// 4. Interpolated variables
1509-
preg_match_all('#interpolation(\d)__#ismx', $this->code['resorted'], $new_vars);
1510-
foreach ($new_vars[1] as $key => $value) {
1511-
$this->code['resorted'] = str_replace($new_vars[0][$key], $this->code['interpolations'][0][$key], $this->code['resorted']);
1441+
if (is_array($this->code['interpolations'])) { // если были обнаружены и вырезаны data uri
1442+
foreach ($this->code['interpolations'] as $key => $val) {
1443+
$this->code['resorted'] = str_replace('interpolation'.$key.'__', $val[0], $this->code['resorted']); // заменяем значение expression обратно
1444+
}
1445+
}
1446+
// Magic comments
1447+
if (is_array($this->code['magicComments'])) {
1448+
foreach ($this->code['magicComments'] as $key => $val) {
1449+
$this->code['resorted'] = str_replace("\nmagic: comment".$key.'__;', $val[0], $this->code['resorted']);
1450+
}
15121451
}
15131452

1514-
// 5. Удаляем искусственно созданные 'commented__'
1515-
while(strpos($this->code['resorted'], 'commented__') !== FALSE) {
1516-
$this->code['resorted'] = preg_replace(
1517-
'#
1518-
commented__
1519-
(.*?[^:]
1520-
:
1521-
.*?[^;]
1522-
;)
1523-
#ismx',
1524-
'/*$1*/',
1525-
$this->code['resorted']
1526-
);
1453+
1454+
// Comments
1455+
if (is_array($this->code['inlinecomments'])) { // если были обнаружены и вырезаны data uri
1456+
foreach ($this->code['inlinecomments'] as $key => $val) {
1457+
$this->code['resorted'] = str_replace('inlinecomment'.$key.'__', $val[0], $this->code['resorted']); // заменяем значение expression обратно
1458+
}
1459+
}
1460+
if (is_array($this->code['comments'])) { // если были обнаружены и вырезаны data uri
1461+
foreach ($this->code['comments'] as $key => $val) {
1462+
if (strpos($this->code['resorted'], 'comment'.$key.'__') > -1) {
1463+
$this->code['resorted'] = str_replace('comment'.$key.'__', $val[0], $this->code['resorted']); // заменяем значение expression обратно
1464+
}
1465+
}
15271466
}
15281467

1468+
15291469
// 6. Удаляем искусственно созданные 'brace__'
15301470
if (is_array($this->code['braces'])) { // если были обнаружены и вырезаны хаки
15311471
foreach ($this->code['braces'] as $key => $val) {

0 commit comments

Comments
 (0)