Skip to content

Commit a455c80

Browse files
committed
Version 2.12
1 parent 1032032 commit a455c80

File tree

1 file changed

+92
-45
lines changed

1 file changed

+92
-45
lines changed

plugin/lib/csscomb.php

Lines changed: 92 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) <[email protected]>
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",
@@ -362,7 +368,7 @@ class csscomb{
362368
"-ms-animation-direction",
363369
"-o-animation-direction",
364370
"animation-direction",
365-
"pointer-event",
371+
"pointer-events",
366372
"unicode-bidi",
367373
"direction",
368374
"-webkit-columns",
@@ -597,7 +603,7 @@ class csscomb{
597603
"-webkit-hyphens",
598604
"-moz-hyphens",
599605
"hyphens",
600-
"pointer-event"
606+
"pointer-events"
601607
],
602608
[
603609
"opacity",
@@ -629,18 +635,18 @@ class csscomb{
629635
"-webkit-border-radius",
630636
"-moz-border-radius",
631637
"border-radius",
638+
"-webkit-border-top-left-radius",
639+
"-moz-border-radius-topleft",
640+
"border-top-left-radius",
632641
"-webkit-border-top-right-radius",
633-
"-moz-border-top-right-radius",
642+
"-moz-border-radius-topright",
634643
"border-top-right-radius",
635644
"-webkit-border-bottom-right-radius",
636-
"-moz-border-bottom-right-radius",
645+
"-moz-border-radius-bottomright",
637646
"border-bottom-right-radius",
638647
"-webkit-border-bottom-left-radius",
639-
"-moz-border-bottom-left-radius",
648+
"-moz-border-radius-bottomleft",
640649
"border-bottom-left-radius",
641-
"-webkit-border-top-left-radius",
642-
"-moz-border-top-left-radius",
643-
"border-top-left-radius",
644650
"-webkit-border-image",
645651
"-moz-border-image",
646652
"-o-border-image",
@@ -721,11 +727,25 @@ class csscomb{
721727

722728
/**
723729
* @param string css
724-
* @param boolean debug
725-
* @param json custom_sort_order JSON expected
726-
* @return string
730+
* @param boolean debug, OPTIONAL
731+
* @param json custom_sort_order JSON expected, OPTIONAL
732+
* @return string|false
727733
*
728734
* @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+
*
729749
*/
730750
function csscomb($css = '', $debug = false, $custom_sort_order = null) {
731751
$this->output = $debug ? true : false;
@@ -877,18 +897,27 @@ function preprocess() {
877897
endwhile;
878898
}
879899

880-
// 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. Закрываем сложности парсинга {}
881910
$this->code['edited'] = str_replace('{}', '{ }', $this->code['edited']);
882911

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

891-
// 6. Комментарии
920+
// 7. Комментарии
892921
if (preg_match_all('@
893922
(
894923
\s*
@@ -899,7 +928,7 @@ function preprocess() {
899928
)
900929
@ismx', $this->code['edited'], $test)) {
901930

902-
// 6.1. Закомментировано одно или несколько свойств: повторяющийся паттерн *:*; \s*?
931+
// 7.1. Закомментировано одно или несколько свойств: повторяющийся паттерн *:*; \s*?
903932
if (preg_match_all('@
904933
(\s*)
905934
/\*
@@ -948,7 +977,7 @@ function preprocess() {
948977
}
949978
}
950979

951-
// 6.2. Обрывки закомментированных деклараций: присутствует { или }
980+
// 7.2. Обрывки закомментированных деклараций: присутствует { или }
952981
if (preg_match_all('@
953982
\s*?
954983
/\*
@@ -983,7 +1012,7 @@ function preprocess() {
9831012
}
9841013
}
9851014

986-
// 7. Entities
1015+
// 8. Entities
9871016
if (preg_match_all('@
9881017
\&
9891018
\#?
@@ -1092,28 +1121,37 @@ function parse_root($css = '') {
10921121
*
10931122
*/
10941123
function parse_child($value = '') {
1124+
$block_imports = array();
10951125
// 1. Ищем «детей» (вложенные селекторы)
10961126
preg_match_all('@
1097-
[^\};]*?[\s]*?\{((([^\{\}]+)|(?R))*)\}
1127+
[^};]*?
1128+
{
1129+
(
1130+
(
1131+
([^\{\}]+)|(?R)
1132+
)*
1133+
)
1134+
}
10981135
@ismx', $value, $nested);
10991136

1100-
// Убираем из выборки интерполированные переменные
1101-
foreach ($nested[0] as $nested_key => $nested_value) {
1102-
if (strpos($nested_value, '#{$')) {
1103-
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]);
11041148
}
11051149
}
11061150

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

1111-
// Удаляем «детей» из общей строки
1112-
// TODO: возможно, вынести отдельной функцией, т.к. часто повторяется
1113-
foreach ($nested[0] as &$nest) {
1114-
$value = str_replace($nest, '', $value);
1115-
}
1116-
11171155
// Рекурсия, ahoj!
11181156
// Сортируем содержимое «детей»
11191157
foreach ($nested[1] as &$child) {
@@ -1140,20 +1178,23 @@ function parse_child($value = '') {
11401178

11411179
// Включения, следующие сразу за {
11421180
preg_match_all('@
1143-
^\s*\@[^;]+?[;]
1181+
(^\s*\@[^;]+?[;])|(^\s*\.[^;:]+?[;])
11441182
@isx', $value, $first_imports);
11451183
foreach ($first_imports[0] as &$first_import) {
11461184
$value = str_replace($first_import, '', $value);
11471185
}
11481186

11491187
// Все остальные
11501188
preg_match_all('@
1151-
[;\{\}]+(\s*\@[^;]+?[;])
1189+
(?<=[;}])(\s*\@[^;]+?[;])|(?<=[;}])(\s*\.[^;:]+?[;])
11521190
@ismx', $value, $imports);
11531191
// Удаляем их из общей строки
11541192
foreach ($imports[1] as &$import) {
11551193
$value = str_replace($import, '', $value);
11561194
}
1195+
foreach ($imports[2] as &$import) {
1196+
$value = str_replace($import, '', $value);
1197+
}
11571198

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

11741215
// 6. Склеиваем всё обратно в следующем порядке:
11751216
// переменные, включения, простые свойства, вложенные {}
1176-
$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;
11771218
return $value;
11781219
}
11791220

@@ -1443,7 +1484,13 @@ function postprocess() {
14431484
}
14441485
}
14451486

1446-
// 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__'
14471494
while(strpos($this->code['resorted'], 'commented__') !== FALSE) {
14481495
$this->code['resorted'] = preg_replace(
14491496
'#
@@ -1458,7 +1505,7 @@ function postprocess() {
14581505
);
14591506
}
14601507

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

0 commit comments

Comments
 (0)