From a455c80f0346b1d436352541e87c3d268ca3d492 Mon Sep 17 00:00:00 2001 From: miripiruni Date: Fri, 4 Jan 2013 01:11:02 +0400 Subject: [PATCH 01/13] Version 2.12 --- plugin/lib/csscomb.php | 137 +++++++++++++++++++++++++++-------------- 1 file changed, 92 insertions(+), 45 deletions(-) diff --git a/plugin/lib/csscomb.php b/plugin/lib/csscomb.php index 70bad94..45db351 100644 --- a/plugin/lib/csscomb.php +++ b/plugin/lib/csscomb.php @@ -1,13 +1,17 @@ + * @license MIT + * @web http://csscomb.com/ */ - + error_reporting(E_ALL); - + class csscomb{ var $sort_order = Array(), @@ -24,6 +28,8 @@ class csscomb{ 'expressions' => null, // если найдены data uri, то эта переменная станет массивом... 'datauri' => null, + // если найдены интерполированные переменные, то эта переменная станет массивом + 'interpolations' => null, // если найдены CSS-хаки мешающие парсить, то эта переменная станет массивом... 'hacks' => null, // если найдены комментарии содержащие { или } мешающие парсить, @@ -125,18 +131,18 @@ class csscomb{ "-webkit-border-radius", "-moz-border-radius", "border-radius", + "-webkit-border-top-left-radius", + "-moz-border-radius-topleft", + "border-top-left-radius", "-webkit-border-top-right-radius", - "-moz-border-top-right-radius", + "-moz-border-radius-topright", "border-top-right-radius", "-webkit-border-bottom-right-radius", - "-moz-border-bottom-right-radius", + "-moz-border-radius-bottomright", "border-bottom-right-radius", "-webkit-border-bottom-left-radius", - "-moz-border-bottom-left-radius", + "-moz-border-radius-bottomleft", "border-bottom-left-radius", - "-webkit-border-top-left-radius", - "-moz-border-top-left-radius", - "border-top-left-radius", "-webkit-border-image", "-moz-border-image", "-o-border-image", @@ -362,7 +368,7 @@ class csscomb{ "-ms-animation-direction", "-o-animation-direction", "animation-direction", - "pointer-event", + "pointer-events", "unicode-bidi", "direction", "-webkit-columns", @@ -597,7 +603,7 @@ class csscomb{ "-webkit-hyphens", "-moz-hyphens", "hyphens", - "pointer-event" + "pointer-events" ], [ "opacity", @@ -629,18 +635,18 @@ class csscomb{ "-webkit-border-radius", "-moz-border-radius", "border-radius", + "-webkit-border-top-left-radius", + "-moz-border-radius-topleft", + "border-top-left-radius", "-webkit-border-top-right-radius", - "-moz-border-top-right-radius", + "-moz-border-radius-topright", "border-top-right-radius", "-webkit-border-bottom-right-radius", - "-moz-border-bottom-right-radius", + "-moz-border-radius-bottomright", "border-bottom-right-radius", "-webkit-border-bottom-left-radius", - "-moz-border-bottom-left-radius", + "-moz-border-radius-bottomleft", "border-bottom-left-radius", - "-webkit-border-top-left-radius", - "-moz-border-top-left-radius", - "border-top-left-radius", "-webkit-border-image", "-moz-border-image", "-o-border-image", @@ -721,11 +727,25 @@ class csscomb{ /** * @param string css - * @param boolean debug - * @param json custom_sort_order JSON expected - * @return string + * @param boolean debug, OPTIONAL + * @param json custom_sort_order JSON expected, OPTIONAL + * @return string|false * * @TODO: https://github.com/miripiruni/CSScomb/issues/21 + * + * Example: + * + * + * require_once 'PATH_TO_CSScomb/csscomb.php'; + * + * $c = new csscomb(); + * $result_code = $c->csscomb( + * 'div {margin-top:0; color: red; display: inline;}', + * false, + * $MY_JSON_SORT_ORDER + * ); + * + * */ function csscomb($css = '', $debug = false, $custom_sort_order = null) { $this->output = $debug ? true : false; @@ -877,18 +897,27 @@ function preprocess() { endwhile; } - // 4. Закрываем сложности парсинга {} + // 4. Interpolated variables + preg_match_all('@(\#|\@){.*?}@ismx', $this->code['edited'], $this->code['interpolations']); + foreach ($this->code['interpolations'][0] as $key => $value) { + $pos = strpos($this->code['edited'], $value); + if ($pos !== false) { + $this->code['edited'] = substr_replace($this->code['edited'],"interpolation".$key.'__',$pos,strlen($value)); + } + } + + // 5. Закрываем сложности парсинга {} $this->code['edited'] = str_replace('{}', '{ }', $this->code['edited']); - // 5. Закрываем сложности с отсутствующей последней ; перед } + // 6. Закрываем сложности с отсутствующей последней ; перед } $this->code['edited'] = preg_replace('@(.*?[^\s;\{\}\/\*])(\s*?})@', '$1;$2', $this->code['edited']); // Убираем ; у последнего инлайнового комментария // Инлайновый комментарий может идти только после фигурной скобки или ; $this->code['edited'] = preg_replace('@([;\{\}]+\s*?//.*?);(\s*?})@', '$1$2', $this->code['edited']); // Убираем ; у интерполированных переменных - $this->code['edited'] = preg_replace('@(#\{\$.*?)[;](\s*?\})@', '$1$2', $this->code['edited']); + $this->code['edited'] = preg_replace('/((#\{\$|\@\{).*?)[;](\s*?\})/', '$1$3', $this->code['edited']); - // 6. Комментарии + // 7. Комментарии if (preg_match_all('@ ( \s* @@ -899,7 +928,7 @@ function preprocess() { ) @ismx', $this->code['edited'], $test)) { - // 6.1. Закомментировано одно или несколько свойств: повторяющийся паттерн *:*; \s*? + // 7.1. Закомментировано одно или несколько свойств: повторяющийся паттерн *:*; \s*? if (preg_match_all('@ (\s*) /\* @@ -948,7 +977,7 @@ function preprocess() { } } - // 6.2. Обрывки закомментированных деклараций: присутствует { или } + // 7.2. Обрывки закомментированных деклараций: присутствует { или } if (preg_match_all('@ \s*? /\* @@ -983,7 +1012,7 @@ function preprocess() { } } - // 7. Entities + // 8. Entities if (preg_match_all('@ \& \#? @@ -1092,15 +1121,30 @@ function parse_root($css = '') { * */ function parse_child($value = '') { + $block_imports = array(); // 1. Ищем «детей» (вложенные селекторы) preg_match_all('@ - [^\};]*?[\s]*?\{((([^\{\}]+)|(?R))*)\} + [^};]*? + { + ( + ( + ([^\{\}]+)|(?R) + )* + ) + } @ismx', $value, $nested); - // Убираем из выборки интерполированные переменные - foreach ($nested[0] as $nested_key => $nested_value) { - if (strpos($nested_value, '#{$')) { - unset($nested[0][$nested_key]); + // TODO: возможно, вынести отдельной функцией, т.к. часто повторяется + foreach ($nested[0] as $key => &$nest) { + $value = str_replace($nest, '', $value); + if(strpos(trim($nest), '@include') === 0) { + $value = str_replace($nest, '', $value); + $old_nest = $nested[1][$key]; + $new_nest = $this->parse_child($nested[1][$key]); + $nest = str_replace($old_nest, $new_nest, $nest); + $block_imports[] = $nest; + unset($nested[0][$key]); + unset($nested[1][$key]); } } @@ -1108,12 +1152,6 @@ function parse_child($value = '') { // TODO: убрать, если без этого можно обойтись $nested_string = implode('', $nested[0]); - // Удаляем «детей» из общей строки - // TODO: возможно, вынести отдельной функцией, т.к. часто повторяется - foreach ($nested[0] as &$nest) { - $value = str_replace($nest, '', $value); - } - // Рекурсия, ahoj! // Сортируем содержимое «детей» foreach ($nested[1] as &$child) { @@ -1140,7 +1178,7 @@ function parse_child($value = '') { // Включения, следующие сразу за { preg_match_all('@ - ^\s*\@[^;]+?[;] + (^\s*\@[^;]+?[;])|(^\s*\.[^;:]+?[;]) @isx', $value, $first_imports); foreach ($first_imports[0] as &$first_import) { $value = str_replace($first_import, '', $value); @@ -1148,12 +1186,15 @@ function parse_child($value = '') { // Все остальные preg_match_all('@ - [;\{\}]+(\s*\@[^;]+?[;]) + (?<=[;}])(\s*\@[^;]+?[;])|(?<=[;}])(\s*\.[^;:]+?[;]) @ismx', $value, $imports); // Удаляем их из общей строки foreach ($imports[1] as &$import) { $value = str_replace($import, '', $value); } + foreach ($imports[2] as &$import) { + $value = str_replace($import, '', $value); + } // 4. Выносим простые свойства в массив $properties preg_match_all('@ @@ -1173,7 +1214,7 @@ function parse_child($value = '') { // 6. Склеиваем всё обратно в следующем порядке: // переменные, включения, простые свойства, вложенные {} - $value = implode('', $vars[0]).implode('', $first_imports[0]).implode('', $imports[1]).implode('', $props).$nested_string.$value; + $value = implode('', $vars[0]).implode('', $first_imports[0]).implode('', $imports[1]).implode('', $imports[2]).implode('', $block_imports).implode('', $props).$nested_string.$value; return $value; } @@ -1443,7 +1484,13 @@ function postprocess() { } } - // 4. Удаляем искусственно созданные 'commented__' + // 4. Interpolated variables + preg_match_all('#interpolation(\d)__#ismx', $this->code['resorted'], $new_vars); + foreach ($new_vars[1] as $key => $value) { + $this->code['resorted'] = str_replace($new_vars[0][$key], $this->code['interpolations'][0][$key], $this->code['resorted']); + } + + // 5. Удаляем искусственно созданные 'commented__' while(strpos($this->code['resorted'], 'commented__') !== FALSE) { $this->code['resorted'] = preg_replace( '# @@ -1458,7 +1505,7 @@ function postprocess() { ); } - // 5. Удаляем искусственно созданные 'brace__' + // 6. Удаляем искусственно созданные 'brace__' if (is_array($this->code['braces'])) { // если были обнаружены и вырезаны хаки foreach ($this->code['braces'] as $key => $val) { if (strpos($this->code['resorted'], 'brace__'.$key.'{') !== FALSE) { From e572e2edca19c6ba16dcda2b0f46074c33e8512f Mon Sep 17 00:00:00 2001 From: miripiruni Date: Mon, 17 Jun 2013 11:07:22 +0400 Subject: [PATCH 02/13] Version updated: 2.13 --- plugin/lib/csscomb.php | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/plugin/lib/csscomb.php b/plugin/lib/csscomb.php index 45db351..a583f4a 100644 --- a/plugin/lib/csscomb.php +++ b/plugin/lib/csscomb.php @@ -4,7 +4,7 @@ * * Tool for sorting CSS properties in specific order * - * @version 2.12 (build e784736-1301040046) + * @version 2.13 (build bb516f2-1306162139) * @author Vyacheslav Oliyanchuk (miripiruni) * @license MIT * @web http://csscomb.com/ @@ -213,8 +213,13 @@ class csscomb{ "-ms-background-position-y", "background-position-x", "background-position-y", + "-webkit-background-clip", + "-moz-background-clip", "background-clip", "background-origin", + "-webkit-background-size", + "-moz-background-size", + "-o-background-size", "background-size", "background-repeat", "box-decoration-break", @@ -687,8 +692,13 @@ class csscomb{ "-ms-background-position-x", "background-position-y", "-ms-background-position-y", + "-webkit-background-clip", + "-moz-background-clip", "background-clip", "background-origin", + "-webkit-background-size", + "-moz-background-size", + "-o-background-size", "background-size", "box-decoration-break", "-webkit-box-shadow", @@ -903,7 +913,7 @@ function preprocess() { $pos = strpos($this->code['edited'], $value); if ($pos !== false) { $this->code['edited'] = substr_replace($this->code['edited'],"interpolation".$key.'__',$pos,strlen($value)); - } + } } // 5. Закрываем сложности парсинга {} @@ -1089,7 +1099,14 @@ function parse_rules() { if ($this->mode === 'properties') { $this->code['edited'] = "\n".$this->code['edited']; $this->code['resorted'] = $this->parse_child($this->code['edited']); - $this->code['resorted'] = substr($this->code['resorted'], 1); + // Remove first line if it's empty + if (strpos($this->code['resorted'], "\n") === 0) { + $this->code['resorted'] = substr($this->code['resorted'], 1); + } + // Remove all new lines if css initially didn't have any + if (substr_count($this->code['edited'], "\n") === 1) { + $this->code['resorted'] = str_replace("\n", '', $this->code['resorted']); + } } } @@ -1180,15 +1197,15 @@ function parse_child($value = '') { preg_match_all('@ (^\s*\@[^;]+?[;])|(^\s*\.[^;:]+?[;]) @isx', $value, $first_imports); - foreach ($first_imports[0] as &$first_import) { - $value = str_replace($first_import, '', $value); - } // Все остальные preg_match_all('@ (?<=[;}])(\s*\@[^;]+?[;])|(?<=[;}])(\s*\.[^;:]+?[;]) @ismx', $value, $imports); // Удаляем их из общей строки + foreach ($first_imports[0] as &$first_import) { + $value = str_replace($first_import, '', $value); + } foreach ($imports[1] as &$import) { $value = str_replace($import, '', $value); } @@ -1204,14 +1221,14 @@ function parse_child($value = '') { @ismx', $value, $properties); // Удаляем их из общей строки foreach ($properties[0] as &$property) { - $value = str_replace($property, '', $value); + $value = str_replace($property, '', $value); } // Сортируем свойства $props = $properties[0]; $props = $this->resort_properties($props); // 5. Если осталось ещё что-то, оставляем «как есть» - + // 6. Склеиваем всё обратно в следующем порядке: // переменные, включения, простые свойства, вложенные {} $value = implode('', $vars[0]).implode('', $first_imports[0]).implode('', $imports[1]).implode('', $imports[2]).implode('', $block_imports).implode('', $props).$nested_string.$value; @@ -1432,7 +1449,11 @@ function resort_properties($prop) { if (count($resorted) > 0) { // Если свойства разделены на группы $resorted = $this->separate_property_group($resorted); } - if (count($undefined) > 0) { + if ( + count($undefined) > 0 AND + // проверяем, что $undefined[0] не начинается с пустой строки + substr_count(substr($undefined[0], 0, 2), "\n\n") === 0 + ) { $undefined[0] = "\n".$undefined[0]; } } @@ -1500,7 +1521,7 @@ function postprocess() { .*?[^;] ;) #ismx', - '/* $1 */', + '/*$1*/', $this->code['resorted'] ); } From 4871f44ef4cb6563623f2a0ad00f2233984d7eb5 Mon Sep 17 00:00:00 2001 From: Tony Ganch Date: Mon, 8 Jul 2013 22:56:58 +0400 Subject: [PATCH 03/13] Version update: 2.14 --- plugin/lib/csscomb.php | 234 +++++++++++++++-------------------------- 1 file changed, 87 insertions(+), 147 deletions(-) diff --git a/plugin/lib/csscomb.php b/plugin/lib/csscomb.php index a583f4a..d0a7cbb 100644 --- a/plugin/lib/csscomb.php +++ b/plugin/lib/csscomb.php @@ -4,7 +4,7 @@ * * Tool for sorting CSS properties in specific order * - * @version 2.13 (build bb516f2-1306162139) + * @version 2.14 (build 57f634a-1307080853) * @author Vyacheslav Oliyanchuk (miripiruni) * @license MIT * @web http://csscomb.com/ @@ -30,6 +30,10 @@ class csscomb{ 'datauri' => null, // если найдены интерполированные переменные, то эта переменная станет массивом 'interpolations' => null, + // Игнорируем комментарии + 'comments' => null, + 'inlinecomments' => null, + 'magicComments' => null, // если найдены CSS-хаки мешающие парсить, то эта переменная станет массивом... 'hacks' => null, // если найдены комментарии содержащие { или } мешающие парсить, @@ -908,119 +912,56 @@ function preprocess() { } // 4. Interpolated variables - preg_match_all('@(\#|\@){.*?}@ismx', $this->code['edited'], $this->code['interpolations']); - foreach ($this->code['interpolations'][0] as $key => $value) { - $pos = strpos($this->code['edited'], $value); - if ($pos !== false) { - $this->code['edited'] = substr_replace($this->code['edited'],"interpolation".$key.'__',$pos,strlen($value)); - } + preg_match_all('@(\#|\@){.*?}@ismx', $this->code['edited'], $this->code['interpolations'], PREG_SET_ORDER); + foreach ($this->code['interpolations'] as $key => $value) { + $this->code['edited'] = str_replace($value[0], 'interpolation'.$key.'__', $this->code['edited']); + } + + // X. Temporally remove comments + // Magic comment + preg_match_all('@ + (\s*\/\*\s*csscomb:\s*false\s*\*\/.*?\/\*\s*csscomb:\s*true\s*\*\/) + | + (\s*\/\/\s*csscomb:\s*false[\n\r].*?\/\/\s*csscomb:\s*true[^\n\S\r]*) + @ismx', $this->code['edited'], + $this->code['magicComments'], PREG_SET_ORDER); + foreach ($this->code['magicComments'] as $key => $value) { + $this->code['edited'] = str_replace($value[0], "\nmagic: comment".$key.'__;', $this->code['edited']); + } + // Comments + preg_match_all('@ + ([\n\r]\s*/\*.*?\*/)+ + | + (^\s*/\*.*?\*/)+ + | + ([\n\r]\s*//[^\n\r]*)+ + | + (^\s*//[^\n\r]*)+ + @ismx', $this->code['edited'], $this->code['comments'], PREG_SET_ORDER); + foreach ($this->code['comments'] as $key => $value) { + $this->code['edited'] = str_replace($value[0], 'comment'.$key.'__', $this->code['edited']); + } + // Inline comments + preg_match_all('@ + [^\S\n\r]*/\*.*?\*/([^\n\S\r]*/\*.*?\*/)* + | + (?code['edited'], $this->code['inlinecomments'], PREG_SET_ORDER); + foreach ($this->code['inlinecomments'] as $key => $value) { + $this->code['edited'] = str_replace($value[0], 'inlinecomment'.$key.'__', $this->code['edited']); } // 5. Закрываем сложности парсинга {} $this->code['edited'] = str_replace('{}', '{ }', $this->code['edited']); // 6. Закрываем сложности с отсутствующей последней ; перед } - $this->code['edited'] = preg_replace('@(.*?[^\s;\{\}\/\*])(\s*?})@', '$1;$2', $this->code['edited']); + $this->code['edited'] = preg_replace('@(.*?[^\s;\{\}\/\*_])(\s*?})@', '$1;$2', $this->code['edited']); // Убираем ; у последнего инлайнового комментария // Инлайновый комментарий может идти только после фигурной скобки или ; $this->code['edited'] = preg_replace('@([;\{\}]+\s*?//.*?);(\s*?})@', '$1$2', $this->code['edited']); // Убираем ; у интерполированных переменных $this->code['edited'] = preg_replace('/((#\{\$|\@\{).*?)[;](\s*?\})/', '$1$3', $this->code['edited']); - // 7. Комментарии - if (preg_match_all('@ - ( - \s* - /\* - .*?[^\*/] - \*/ - (\s/\*\*/)? - ) - @ismx', $this->code['edited'], $test)) { - - // 7.1. Закомментировано одно или несколько свойств: повторяющийся паттерн *:*; \s*? - if (preg_match_all('@ - (\s*) - /\* - (.*?[^\*/]) - \*+/ - (\ {0,1}/\*\*/)? - @ismx', $this->code['edited'], $comments)) { - - $new_comments = Array(); - $old_comments = $comments[0]; - - foreach ($comments[2] as $key => $comment) { - if ( // если комментарий содержит ; и : - strpos($comment, ':') !== FALSE AND - strpos($comment, ';') !== FALSE - - ) { - preg_match_all('@ - (\s*) - ( - .+?[^;] - ; - ) - @ismx', $comment, $properties); - - $new_comment = ''; - foreach ($properties[2] as $property) { - $new_comment .= $comments[1][$key]."commented__".$property; - } - $new_comments[] = $new_comment; - } - else { - // если нет : или ;, то считаем что это текстовый комментарий - // и копируем его в том виде, в каком он был. - $new_comments[] = $comments[0][$key]; - } - - - } - - foreach ($old_comments as $key => $old_comment) { - $this->code['edited'] = str_replace( - $old_comments[$key], - $new_comments[$key], - $this->code['edited']); - } - } - - // 7.2. Обрывки закомментированных деклараций: присутствует { или } - if (preg_match_all('@ - \s*? - /\* - ( - .*?[^\*/] - )*? - \*+/ - @ismx', $this->code['edited'], $comments)) { - - $new_comments = Array(); - $old_comments = $comments[0]; - - foreach ($comments[0] as $key => $comment) { - if (strpos($comment, '}') !== FALSE OR strpos($comment, '{') !== FALSE) { - $new_comment = ''; - if (strpos($comment, '}') !== FALSE) { $new_comment .= '}'; } - $new_comment .= "brace__".$key; - if (strpos($comment, '{') !== FALSE) { $new_comment .= '{'; } - $new_comments[$key] = $new_comment; - $this->code['braces'][$key] = $comment; - } - } - - foreach ($new_comments as $key => $new_comment) { - if (strlen($new_comment) > 0) { - $this->code['edited'] = str_replace( - $old_comments[$key], - $new_comment, - $this->code['edited']); - } - } - } - } // 8. Entities if (preg_match_all('@ @@ -1181,9 +1122,9 @@ function parse_child($value = '') { // 2. Выносим переменные в отдельный массив $vars preg_match_all('@ - (\s*/\*[^\*/]*?\*/)? - (\s*//.*?)? + (comment\d*__)* \s*(\$|\@)[^;\}]+?:[^;]+?; + (inlinecomment\d*__)* @ismx', $value, $vars); // Удаляем их из общей строки foreach ($vars[0] as $var) { @@ -1195,29 +1136,32 @@ function parse_child($value = '') { // Включения, следующие сразу за { preg_match_all('@ - (^\s*\@[^;]+?[;])|(^\s*\.[^;:]+?[;]) + (^\s*(comment\d*__)*\s*\@[^;]+?[;](inlinecomment\d*__)*) + | + (^\s*(comment\d*__)*\s*\.[^;:]+?[;](inlinecomment\d*__)*) @isx', $value, $first_imports); // Все остальные preg_match_all('@ - (?<=[;}])(\s*\@[^;]+?[;])|(?<=[;}])(\s*\.[^;:]+?[;]) + (?<=inlinecomment\d__|[;}]) + ((comment\d*__)?\s*\@[^;]+?[;](inlinecomment\d*__)?) + | + (?<=inlinecomment\d__|[;}]) + ((comment\d*__)?\s*\.[^;:]+?[;](inlinecomment\d*__)?) @ismx', $value, $imports); // Удаляем их из общей строки foreach ($first_imports[0] as &$first_import) { $value = str_replace($first_import, '', $value); } - foreach ($imports[1] as &$import) { - $value = str_replace($import, '', $value); - } - foreach ($imports[2] as &$import) { + foreach ($imports[0] as &$import) { $value = str_replace($import, '', $value); } // 4. Выносим простые свойства в массив $properties preg_match_all('@ + (comment\d*__)? \s*[^;]+?:[^;]+?; - (\s*/\*.*?[^\*/]\*/)? - (\s{0,1}/\*\*/)? + (inlinecomment\d*__)? @ismx', $value, $properties); // Удаляем их из общей строки foreach ($properties[0] as &$property) { @@ -1227,11 +1171,9 @@ function parse_child($value = '') { $props = $properties[0]; $props = $this->resort_properties($props); - // 5. Если осталось ещё что-то, оставляем «как есть» - // 6. Склеиваем всё обратно в следующем порядке: // переменные, включения, простые свойства, вложенные {} - $value = implode('', $vars[0]).implode('', $first_imports[0]).implode('', $imports[1]).implode('', $imports[2]).implode('', $block_imports).implode('', $props).$nested_string.$value; + $value = implode('', $vars[0]).implode('', $first_imports[0]).implode('', $imports[0]).implode('', $block_imports).implode('', $props).$nested_string.$value; return $value; } @@ -1252,7 +1194,6 @@ function parse_properties($css = '') { ^ (.*?) ( - #(\s*/\*.*\*/;)*? \s*? } ) @@ -1303,8 +1244,7 @@ function parse_properties($css = '') { ^ (.*?) - (\s*?) - (/\* .* \*/) + (inlinecomment\d*__) (.*) $ @@ -1312,8 +1252,7 @@ function parse_properties($css = '') { if ( count($matches) === 5 and // все распарсилось как надо - strlen($matches[1]) === 0 and // комментарий действительно идет первым - strpos($matches[2], "\n") !== 0 // перед комментарием нет переноса строки, следовательно предпологаем, что он относится к скобке с селектором + strlen($matches[1]) === 0 // комментарий действительно идет первым ) { $first_spaces = $matches[2]; $first_comment = $matches[3]; @@ -1330,10 +1269,7 @@ function parse_properties($css = '') { .[^;]* ; ( # На этой же строке (после ;) может быть комментарий. Он тоже пригодится. - \s* - /\* - .*?[^\*/] - \*/ + inlinecomment\d*__ ) ? (\s{0,1}/\*\*/)? @@ -1361,8 +1297,7 @@ function parse_properties($css = '') { .[^;]* # все что угодно, но не ; ; ( # На этой же строке (после ;) может быть комментарий. Он тоже пригодится. - \s* - /\* .* \*/ + inlinecomment\d*__ ) *? ) @@ -1406,9 +1341,7 @@ function resort_properties($prop) { * Пробел в начале добавляется специально, чтобы избежать совпадений по вхождению * одной строки в другую. Например: top не должно совпадать с border-top */ - strpos(' '.trim($property), ' '.$k.':') !== FALSE OR - strpos(' '.trim($property), ' commented__'.$k.':') !== FALSE - + strpos(' '.trim($property), ' '.$k.':') !== FALSE ) { $through_number = $this->get_through_number($k); // определяем "сквозной" порядковый номер if ($through_number !== false) $index = $through_number; @@ -1421,8 +1354,7 @@ function resort_properties($prop) { foreach ($this->sort_order as $pos => $key) { if ( // пробел в начале добавляется специально. - strpos(' '.trim($property), ' '.$key.':') !== FALSE OR - strpos(' '.trim($property), ' commented__'.$key.':') !== FALSE + strpos(' '.trim($property), ' '.$key.':') !== FALSE ) { $index = $pos; } @@ -1506,26 +1438,34 @@ function postprocess() { } // 4. Interpolated variables - preg_match_all('#interpolation(\d)__#ismx', $this->code['resorted'], $new_vars); - foreach ($new_vars[1] as $key => $value) { - $this->code['resorted'] = str_replace($new_vars[0][$key], $this->code['interpolations'][0][$key], $this->code['resorted']); + if (is_array($this->code['interpolations'])) { // если были обнаружены и вырезаны data uri + foreach ($this->code['interpolations'] as $key => $val) { + $this->code['resorted'] = str_replace('interpolation'.$key.'__', $val[0], $this->code['resorted']); // заменяем значение expression обратно + } + } + // Magic comments + if (is_array($this->code['magicComments'])) { + foreach ($this->code['magicComments'] as $key => $val) { + $this->code['resorted'] = str_replace("\nmagic: comment".$key.'__;', $val[0], $this->code['resorted']); + } } - // 5. Удаляем искусственно созданные 'commented__' - while(strpos($this->code['resorted'], 'commented__') !== FALSE) { - $this->code['resorted'] = preg_replace( - '# - commented__ - (.*?[^:] - : - .*?[^;] - ;) - #ismx', - '/*$1*/', - $this->code['resorted'] - ); + + // Comments + if (is_array($this->code['inlinecomments'])) { // если были обнаружены и вырезаны data uri + foreach ($this->code['inlinecomments'] as $key => $val) { + $this->code['resorted'] = str_replace('inlinecomment'.$key.'__', $val[0], $this->code['resorted']); // заменяем значение expression обратно + } + } + if (is_array($this->code['comments'])) { // если были обнаружены и вырезаны data uri + foreach ($this->code['comments'] as $key => $val) { + if (strpos($this->code['resorted'], 'comment'.$key.'__') > -1) { + $this->code['resorted'] = str_replace('comment'.$key.'__', $val[0], $this->code['resorted']); // заменяем значение expression обратно + } + } } + // 6. Удаляем искусственно созданные 'brace__' if (is_array($this->code['braces'])) { // если были обнаружены и вырезаны хаки foreach ($this->code['braces'] as $key => $val) { From 2a79eac920dca80655eb3151f1cd921c03063f46 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 16 May 2015 23:00:19 +1200 Subject: [PATCH 04/13] Removed PHP related code --- plugin/exec.php | 6 - plugin/lib/csscomb.php | 1581 ---------------------------------------- 2 files changed, 1587 deletions(-) delete mode 100644 plugin/exec.php delete mode 100644 plugin/lib/csscomb.php diff --git a/plugin/exec.php b/plugin/exec.php deleted file mode 100644 index d565eaa..0000000 --- a/plugin/exec.php +++ /dev/null @@ -1,6 +0,0 @@ -csscomb($input); -?> diff --git a/plugin/lib/csscomb.php b/plugin/lib/csscomb.php deleted file mode 100644 index d0a7cbb..0000000 --- a/plugin/lib/csscomb.php +++ /dev/null @@ -1,1581 +0,0 @@ - - * @license MIT - * @web http://csscomb.com/ - */ - -error_reporting(E_ALL); - -class csscomb{ - - var $sort_order = Array(), - $code = Array( - // оригинальный код, без изменений, то, что пришло на вход - 'original' => null, - // код, который может меняться в процессе выполнения алгоритма пересортировки - 'edited' => null, - // TODO: избавиться от resorted - // конечный, пересортированный CSS-код - 'resorted' => null, - // если найдены expression, то эта переменная станет массивом, ячейки которого - // будут содержать код каждого найденного expression - 'expressions' => null, - // если найдены data uri, то эта переменная станет массивом... - 'datauri' => null, - // если найдены интерполированные переменные, то эта переменная станет массивом - 'interpolations' => null, - // Игнорируем комментарии - 'comments' => null, - 'inlinecomments' => null, - 'magicComments' => null, - // если найдены CSS-хаки мешающие парсить, то эта переменная станет массивом... - 'hacks' => null, - // если найдены комментарии содержащие { или } мешающие парсить, - // то эта переменная станет массивом. - 'braces' => null, - // если найдены entities мешающие парсить, то эта переменная станет массивом. - 'entities' => null - ), - - // В переменной $mode лежит режим работы с CSS-кодом. Возможны следующие значения: - // css-file - только CSS-код - // style-attribute - найден атрибут style="..." - // properties - не найдено фигурных скобок, зато присутствуют точки с запятой и двоеточия. - $mode = 'properties', - - $default_sort_order = '[ - "position", - "top", - "right", - "bottom", - "left", - "z-index", - "display", - "visibility", - "-webkit-flex-direction", - "-moz-flex-direction", - "-ms-flex-direction", - "-o-flex-direction", - "flex-direction", - "-webkit-flex-order", - "-moz-flex-order", - "-ms-flex-order", - "-o-flex-order", - "flex-order", - "-webkit-flex-pack", - "-moz-flex-pack", - "-ms-flex-pack", - "-o-flex-pack", - "flex-pack", - "float", - "clear", - "-webkit-flex-align", - "-moz-flex-align", - "-ms-flex-align", - "-o-flex-align", - "flex-align", - "overflow", - "-ms-overflow-x", - "-ms-overflow-y", - "overflow-x", - "overflow-y", - "clip", - "-webkit-box-sizing", - "-moz-box-sizing", - "box-sizing", - "margin", - "margin-top", - "margin-right", - "margin-bottom", - "margin-left", - "padding", - "padding-top", - "padding-right", - "padding-bottom", - "padding-left", - "min-width", - "min-height", - "max-width", - "max-height", - "width", - "height", - "outline", - "outline-width", - "outline-style", - "outline-color", - "outline-offset", - "border", - "border-spacing", - "border-collapse", - "border-width", - "border-style", - "border-color", - "border-top", - "border-top-width", - "border-top-style", - "border-top-color", - "border-right", - "border-right-width", - "border-right-style", - "border-right-color", - "border-bottom", - "border-bottom-width", - "border-bottom-style", - "border-bottom-color", - "border-left", - "border-left-width", - "border-left-style", - "border-left-color", - "-webkit-border-radius", - "-moz-border-radius", - "border-radius", - "-webkit-border-top-left-radius", - "-moz-border-radius-topleft", - "border-top-left-radius", - "-webkit-border-top-right-radius", - "-moz-border-radius-topright", - "border-top-right-radius", - "-webkit-border-bottom-right-radius", - "-moz-border-radius-bottomright", - "border-bottom-right-radius", - "-webkit-border-bottom-left-radius", - "-moz-border-radius-bottomleft", - "border-bottom-left-radius", - "-webkit-border-image", - "-moz-border-image", - "-o-border-image", - "border-image", - "-webkit-border-image-source", - "-moz-border-image-source", - "-o-border-image-source", - "border-image-source", - "-webkit-border-image-slice", - "-moz-border-image-slice", - "-o-border-image-slice", - "border-image-slice", - "-webkit-border-image-width", - "-moz-border-image-width", - "-o-border-image-width", - "border-image-width", - "-webkit-border-image-outset", - "-moz-border-image-outset", - "-o-border-image-outset", - "border-image-outset", - "-webkit-border-image-repeat", - "-moz-border-image-repeat", - "-o-border-image-repeat", - "border-image-repeat", - "-webkit-border-top-image", - "-moz-border-top-image", - "-o-border-top-image", - "border-top-image", - "-webkit-border-right-image", - "-moz-border-right-image", - "-o-border-right-image", - "border-right-image", - "-webkit-border-bottom-image", - "-moz-border-bottom-image", - "-o-border-bottom-image", - "border-bottom-image", - "-webkit-border-left-image", - "-moz-border-left-image", - "-o-border-left-image", - "border-left-image", - "-webkit-border-corner-image", - "-moz-border-corner-image", - "-o-border-corner-image", - "border-corner-image", - "-webkit-border-top-left-image", - "-moz-border-top-left-image", - "-o-border-top-left-image", - "border-top-left-image", - "-webkit-border-top-right-image", - "-moz-border-top-right-image", - "-o-border-top-right-image", - "border-top-right-image", - "-webkit-border-bottom-right-image", - "-moz-border-bottom-right-image", - "-o-border-bottom-right-image", - "border-bottom-right-image", - "-webkit-border-bottom-left-image", - "-moz-border-bottom-left-image", - "-o-border-bottom-left-image", - "border-bottom-left-image", - "background", - "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader", - "background-color", - "background-image", - "background-attachment", - "background-position", - "-ms-background-position-x", - "-ms-background-position-y", - "background-position-x", - "background-position-y", - "-webkit-background-clip", - "-moz-background-clip", - "background-clip", - "background-origin", - "-webkit-background-size", - "-moz-background-size", - "-o-background-size", - "background-size", - "background-repeat", - "box-decoration-break", - "-webkit-box-shadow", - "-moz-box-shadow", - "box-shadow", - "color", - "table-layout", - "caption-side", - "empty-cells", - "list-style", - "list-style-position", - "list-style-type", - "list-style-image", - "quotes", - "content", - "counter-increment", - "counter-reset", - "-ms-writing-mode", - "vertical-align", - "text-align", - "-webkit-text-align-last", - "-moz-text-align-last", - "-ms-text-align-last", - "text-align-last", - "text-decoration", - "text-emphasis", - "text-emphasis-position", - "text-emphasis-style", - "text-emphasis-color", - "text-indent", - "-ms-text-justify", - "text-justify", - "text-outline", - "text-transform", - "text-wrap", - "-ms-text-overflow", - "text-overflow", - "text-overflow-ellipsis", - "text-overflow-mode", - "text-shadow", - "white-space", - "word-spacing", - "-ms-word-wrap", - "word-wrap", - "-ms-word-break", - "word-break", - "-moz-tab-size", - "-o-tab-size", - "tab-size", - "-webkit-hyphens", - "-moz-hyphens", - "hyphens", - "letter-spacing", - "font", - "font-weight", - "font-style", - "font-variant", - "font-size-adjust", - "font-stretch", - "font-size", - "font-family", - "src", - "line-height", - "opacity", - "-ms-filter:\'progid:DXImageTransform.Microsoft.Alpha", - "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity", - "-ms-interpolation-mode", - "-webkit-filter", - "-ms-filter", - "filter", - "resize", - "cursor", - "nav-index", - "nav-up", - "nav-right", - "nav-down", - "nav-left", - "-webkit-transition", - "-moz-transition", - "-ms-transition", - "-o-transition", - "transition", - "-webkit-transition-delay", - "-moz-transition-delay", - "-ms-transition-delay", - "-o-transition-delay", - "transition-delay", - "-webkit-transition-timing-function", - "-moz-transition-timing-function", - "-ms-transition-timing-function", - "-o-transition-timing-function", - "transition-timing-function", - "-webkit-transition-duration", - "-moz-transition-duration", - "-ms-transition-duration", - "-o-transition-duration", - "transition-duration", - "-webkit-transition-property", - "-moz-transition-property", - "-ms-transition-property", - "-o-transition-property", - "transition-property", - "-webkit-transform", - "-moz-transform", - "-ms-transform", - "-o-transform", - "transform", - "-webkit-transform-origin", - "-moz-transform-origin", - "-ms-transform-origin", - "-o-transform-origin", - "transform-origin", - "-webkit-animation", - "-moz-animation", - "-ms-animation", - "-o-animation", - "animation", - "-webkit-animation-name", - "-moz-animation-name", - "-ms-animation-name", - "-o-animation-name", - "animation-name", - "-webkit-animation-duration", - "-moz-animation-duration", - "-ms-animation-duration", - "-o-animation-duration", - "animation-duration", - "-webkit-animation-play-state", - "-moz-animation-play-state", - "-ms-animation-play-state", - "-o-animation-play-state", - "animation-play-state", - "-webkit-animation-timing-function", - "-moz-animation-timing-function", - "-ms-animation-timing-function", - "-o-animation-timing-function", - "animation-timing-function", - "-webkit-animation-delay", - "-moz-animation-delay", - "-ms-animation-delay", - "-o-animation-delay", - "animation-delay", - "-webkit-animation-iteration-count", - "-moz-animation-iteration-count", - "-ms-animation-iteration-count", - "-o-animation-iteration-count", - "animation-iteration-count", - "-webkit-animation-direction", - "-moz-animation-direction", - "-ms-animation-direction", - "-o-animation-direction", - "animation-direction", - "pointer-events", - "unicode-bidi", - "direction", - "-webkit-columns", - "-moz-columns", - "columns", - "-webkit-column-span", - "-moz-column-span", - "column-span", - "-webkit-column-width", - "-moz-column-width", - "column-width", - "-webkit-column-count", - "-moz-column-count", - "column-count", - "-webkit-column-fill", - "-moz-column-fill", - "column-fill", - "-webkit-column-gap", - "-moz-column-gap", - "column-gap", - "-webkit-column-rule", - "-moz-column-rule", - "column-rule", - "-webkit-column-rule-width", - "-moz-column-rule-width", - "column-rule-width", - "-webkit-column-rule-style", - "-moz-column-rule-style", - "column-rule-style", - "-webkit-column-rule-color", - "-moz-column-rule-color", - "column-rule-color", - "break-before", - "break-inside", - "break-after", - "page-break-before", - "page-break-inside", - "page-break-after", - "orphans", - "widows", - "-ms-zoom", - "zoom", - "max-zoom", - "min-zoom", - "user-zoom", - "orientation" - ]', - - $yandex_sort_order = '[ - [ - "position", - "z-index", - "top", - "right", - "bottom", - "left" - ], - [ - "display", - "visibility", - "float", - "clear", - "overflow", - "overflow-x", - "overflow-y", - "-ms-overflow-x", - "-ms-overflow-y", - "clip", - "zoom", - "flex-direction", - "flex-order", - "flex-pack", - "flex-align" - ], - [ - "-webkit-box-sizing", - "-moz-box-sizing", - "box-sizing", - "width", - "min-width", - "max-width", - "height", - "min-height", - "max-height", - "margin", - "margin-top", - "margin-right", - "margin-bottom", - "margin-left", - "padding", - "padding-top", - "padding-right", - "padding-bottom", - "padding-left" - ], - [ - "table-layout", - "empty-cells", - "caption-side", - "border-spacing", - "border-collapse", - "list-style", - "list-style-position", - "list-style-type", - "list-style-image" - ], - [ - "content", - "quotes", - "counter-reset", - "counter-increment", - "resize", - "cursor", - "nav-index", - "nav-up", - "nav-right", - "nav-down", - "nav-left", - "-webkit-transition", - "-moz-transition", - "-ms-transition", - "-o-transition", - "transition", - "-webkit-transition-delay", - "-moz-transition-delay", - "-ms-transition-delay", - "-o-transition-delay", - "transition-delay", - "-webkit-transition-timing-function", - "-moz-transition-timing-function", - "-ms-transition-timing-function", - "-o-transition-timing-function", - "transition-timing-function", - "-webkit-transition-duration", - "-moz-transition-duration", - "-ms-transition-duration", - "-o-transition-duration", - "transition-duration", - "-webkit-transition-property", - "-moz-transition-property", - "-ms-transition-property", - "-o-transition-property", - "transition-property", - "-webkit-transform", - "-moz-transform", - "-ms-transform", - "-o-transform", - "transform", - "-webkit-transform-origin", - "-moz-transform-origin", - "-ms-transform-origin", - "-o-transform-origin", - "transform-origin", - "-webkit-animation", - "-moz-animation", - "-ms-animation", - "-o-animation", - "animation", - "-webkit-animation-name", - "-moz-animation-name", - "-ms-animation-name", - "-o-animation-name", - "animation-name", - "-webkit-animation-duration", - "-moz-animation-duration", - "-ms-animation-duration", - "-o-animation-duration", - "animation-duration", - "-webkit-animation-play-state", - "-moz-animation-play-state", - "-ms-animation-play-state", - "-o-animation-play-state", - "animation-play-state", - "-webkit-animation-timing-function", - "-moz-animation-timing-function", - "-ms-animation-timing-function", - "-o-animation-timing-function", - "animation-timing-function", - "-webkit-animation-delay", - "-moz-animation-delay", - "-ms-animation-delay", - "-o-animation-delay", - "animation-delay", - "-webkit-animation-iteration-count", - "-moz-animation-iteration-count", - "-ms-animation-iteration-count", - "-o-animation-iteration-count", - "animation-iteration-count", - "-webkit-animation-iteration-count", - "-moz-animation-iteration-count", - "-ms-animation-iteration-count", - "-o-animation-iteration-count", - "animation-iteration-count", - "-webkit-animation-direction", - "-moz-animation-direction", - "-ms-animation-direction", - "-o-animation-direction", - "animation-direction", - "text-align", - "-webkit-text-align-last", - "-moz-text-align-last", - "-ms-text-align-last", - "text-align-last", - "vertical-align", - "white-space", - "text-decoration", - "text-emphasis", - "text-emphasis-color", - "text-emphasis-style", - "text-emphasis-position", - "text-indent", - "-ms-text-justify", - "text-justify", - "text-transform", - "letter-spacing", - "word-spacing", - "-ms-writing-mode", - "text-outline", - "text-transform", - "text-wrap", - "text-overflow", - "-ms-text-overflow", - "text-overflow-ellipsis", - "text-overflow-mode", - "-ms-word-wrap", - "word-wrap", - "word-break", - "-ms-word-break", - "-moz-tab-size", - "-o-tab-size", - "tab-size", - "-webkit-hyphens", - "-moz-hyphens", - "hyphens", - "pointer-events" - ], - [ - "opacity", - "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity", - "-ms-filter:\'progid:DXImageTransform.Microsoft.Alpha", - "-ms-interpolation-mode", - "color", - "border", - "border-collapse", - "border-width", - "border-style", - "border-color", - "border-top", - "border-top-width", - "border-top-style", - "border-top-color", - "border-right", - "border-right-width", - "border-right-style", - "border-right-color", - "border-bottom", - "border-bottom-width", - "border-bottom-style", - "border-bottom-color", - "border-left", - "border-left-width", - "border-left-style", - "border-left-color", - "-webkit-border-radius", - "-moz-border-radius", - "border-radius", - "-webkit-border-top-left-radius", - "-moz-border-radius-topleft", - "border-top-left-radius", - "-webkit-border-top-right-radius", - "-moz-border-radius-topright", - "border-top-right-radius", - "-webkit-border-bottom-right-radius", - "-moz-border-radius-bottomright", - "border-bottom-right-radius", - "-webkit-border-bottom-left-radius", - "-moz-border-radius-bottomleft", - "border-bottom-left-radius", - "-webkit-border-image", - "-moz-border-image", - "-o-border-image", - "border-image", - "-webkit-border-image-source", - "-moz-border-image-source", - "-o-border-image-source", - "border-image-source", - "-webkit-border-image-slice", - "-moz-border-image-slice", - "-o-border-image-slice", - "border-image-slice", - "-webkit-border-image-width", - "-moz-border-image-width", - "-o-border-image-width", - "border-image-width", - "-webkit-border-image-outset", - "-moz-border-image-outset", - "-o-border-image-outset", - "border-image-outset", - "-webkit-border-image-repeat", - "-moz-border-image-repeat", - "-o-border-image-repeat", - "border-image-repeat", - "outline", - "outline-width", - "outline-style", - "outline-color", - "outline-offset", - "background", - "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader", - "background-color", - "background-image", - "background-repeat", - "background-attachment", - "background-position", - "background-position-x", - "-ms-background-position-x", - "background-position-y", - "-ms-background-position-y", - "-webkit-background-clip", - "-moz-background-clip", - "background-clip", - "background-origin", - "-webkit-background-size", - "-moz-background-size", - "-o-background-size", - "background-size", - "box-decoration-break", - "-webkit-box-shadow", - "-moz-box-shadow", - "box-shadow", - "-webkit-box-shadow", - "-moz-box-shadow", - "box-shadow", - "-webkit-box-shadow", - "-moz-box-shadow", - "box-shadow", - "-webkit-box-shadow", - "-moz-box-shadow", - "box-shadow", - "filter:progid:DXImageTransform.Microsoft.gradient", - "-ms-filter:\'progid:DXImageTransform.Microsoft.gradient", - "text-shadow" - ], - [ - "font", - "font-family", - "font-size", - "font-weight", - "font-style", - "font-variant", - "font-size-adjust", - "font-stretch", - "font-effect", - "font-emphasize", - "font-emphasize-position", - "font-emphasize-style", - "font-smooth", - "line-height" - ] - ]'; - - /** - * @param string css - * @param boolean debug, OPTIONAL - * @param json custom_sort_order JSON expected, OPTIONAL - * @return string|false - * - * @TODO: https://github.com/miripiruni/CSScomb/issues/21 - * - * Example: - * - * - * require_once 'PATH_TO_CSScomb/csscomb.php'; - * - * $c = new csscomb(); - * $result_code = $c->csscomb( - * 'div {margin-top:0; color: red; display: inline;}', - * false, - * $MY_JSON_SORT_ORDER - * ); - * - * - */ - function csscomb($css = '', $debug = false, $custom_sort_order = null) { - $this->output = $debug ? true : false; - - if ($css && is_string($css)) { - $this->code['original'] = $this->code['edited'] = $css; - $this->set_mode(); - $this->set_sort_order($custom_sort_order); - $this->preprocess(); - $this->parse_rules(); - $this->postprocess(); - return $this->end_of_process(); - } else { - return false; - } - } - - - /** - * Функция устанавливает $this->sort_order - * - * @param json_array {string/JSON} - * - */ - function set_sort_order($json_array = null) { - $this->sort_order = json_decode($this->default_sort_order); - - if ($json_array !== null) { - $custom_sort_order = json_decode($json_array); - if (is_array($custom_sort_order) AND count($custom_sort_order) > 0) { - $this->sort_order = $custom_sort_order; - } - } - - if ($json_array === 'yandex') { - $this->sort_order = json_decode($this->yandex_sort_order); - //switch(json_last_error()) { - //case JSON_ERROR_DEPTH: - //echo 'JSON parse error: Достигнута максимальная глубина стека'; - //break; - //case JSON_ERROR_STATE_MISMATCH: - //echo 'JSON parse error: Некорректные разряды или не совпадение режимов'; - //break; - //case JSON_ERROR_CTRL_CHAR: - //echo 'JSON parse error: Некорректный управляющий символ'; - //break; - //case JSON_ERROR_SYNTAX: - //echo 'JSON parse error: Синтаксическая ошибка, не корректный JSON'; - //break; - //} - } - } - - - /** - * Функция устанавливает $this->mode - * - * @TODO: а если и тег -
- -
'; - } - - if ($this->output === false) return $this->code['resorted']; - } - - - function log($before, $after) { - echo ' - -
'.$before.'';
-        echo '
'; - echo '
'; - echo ''.var_dump($after).'
'; - } - - - - /** - * Возвращает сквозной прядковый номер элемента двумерного массива так, как если бы этот массив был одномерным - * @param {string} - * @return {bool|int} - */ - private function get_through_number($value) { - $i = 0; - foreach ($this->sort_order as $property_group) { - foreach ($property_group as $key => $val) { - if ($val == $value) return $i; - else $i++; - } - } - return false; - } - - /** - * Разделяет свойства на группы пустой строкой - * Внимание: вызывать только когда есть разделение на группы, иначе вернет входной массив без изменений - * @param {array} - * @return {array} - */ - private function separate_property_group($properties) { - if (is_array($this->sort_order[0])) { // Если в настройках нет разбиения на группы, то выводим входной массив без изменений - foreach ($properties as $key => &$property) { - $property = preg_replace('@\n\s*?(\n\s*?)@ismx', '$1', $property); - $array = explode(':', $property); - $prop_name[$key] = trim($array[0]); - } - foreach ($this->sort_order as $group_num => $property_group) { // Перебираем группы свойств - $intersect = array_intersect($prop_name, $property_group); - if (count($intersect) > 0) { - $num = array_keys($intersect); - $last_key = null; - foreach ($num as $n) { - $last_key = $n; - } - if ($properties[$last_key] !== end($properties)) { - $properties[$last_key] = $properties[$last_key]."\n"; - } - } - } - } - return $properties; - } - -} - From 32e11b77210472af7b577a74674ab5f708eae1d0 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 16 May 2015 23:00:31 +1200 Subject: [PATCH 05/13] Refactored to use nodejs csscomb --- plugin/csscomb.vim | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugin/csscomb.vim b/plugin/csscomb.vim index 2592300..1cc9c7a 100644 --- a/plugin/csscomb.vim +++ b/plugin/csscomb.vim @@ -7,9 +7,13 @@ let g:CSScombPluginDir = fnamemodify(expand(""), ":h") function! g:CSScomb(count, line1, line2) - let content = join(getline(a:line1, a:line2), "\n") - let res = system("php ".fnameescape(g:CSScombPluginDir."/exec.php"), content) - let lines = split(res, "\n") + let content = getline(a:line1, a:line2) + + let tempFile = tempname() . '.' . &filetype + call writefile(content, tempFile) + system('csscomb ' . shellescape(tempFile)) + let lines = readfile(tempFile) + call setline(a:line1, lines) endfunction From 1dd89d982ea04f38912a5a87e86f5d437097503a Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 16 May 2015 23:03:08 +1200 Subject: [PATCH 06/13] Updated readme --- README.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 574ee18..6e3c826 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,11 @@ For more info, online demo and tests see [csscomb.com](http://csscomb.com/) ## The Requirements -CSScomb is written in pure PHP, without any external libraries or dependencies. -See details at [wiki](https://github.com/miripiruni/CSScomb/wiki/Requirements). +CSScomb is written in pure JavaScript. Install with: +```BASH +npm install -g csscomb +``` ## Installation @@ -29,6 +31,16 @@ Add this to .vimrc: Bundle 'git://github.com/miripiruni/CSScomb-for-Vim.git' ``` +### With NeoBundle +Add this to .vimrc: +``` +NeoBundle 'faceleg/vim-csscomb', { + \ 'build': { + \ 'unix': 'npm install -g csscomb', + \ 'mac': 'npm install -g csscomb' + \ }} +``` + ### Manual without plugins manager ``` git clone https://github.com/miripiruni/CSScomb-for-Vim.git csscomb @@ -40,3 +52,12 @@ Vim command: ``` :CSScomb ``` + +## Suggested Configuration + +```VIML +"mnemonic: 'beatify css' +autocmd FileType css noremap bc :CSScomb +" Automatically comb your CSS on save +autocmd BufWritePre,FileWritePre *.css,*.scss,*.sass silent! :CSScomb +``` From 0c9a3e746ebacd9d8b660457964765019fbacdae Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 16 May 2015 23:10:30 +1200 Subject: [PATCH 07/13] Added mistakenly omitted call --- plugin/csscomb.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/csscomb.vim b/plugin/csscomb.vim index 1cc9c7a..0d274a8 100644 --- a/plugin/csscomb.vim +++ b/plugin/csscomb.vim @@ -11,7 +11,7 @@ function! g:CSScomb(count, line1, line2) let tempFile = tempname() . '.' . &filetype call writefile(content, tempFile) - system('csscomb ' . shellescape(tempFile)) + call system('csscomb ' . shellescape(tempFile)) let lines = readfile(tempFile) call setline(a:line1, lines) From d6a3b4828e0ce8550bf83443e94eb9237ec2c680 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 24 May 2015 08:51:08 +1200 Subject: [PATCH 08/13] Fixed repo references in README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6e3c826..4949821 100644 --- a/README.md +++ b/README.md @@ -22,19 +22,19 @@ npm install -g csscomb ``` cd ~/.vim/bundle -git clone https://github.com/miripiruni/CSScomb-for-Vim.git +git clone https://github.com/csscomb/vim-csscomb.git ``` ### With Vundle Add this to .vimrc: ``` -Bundle 'git://github.com/miripiruni/CSScomb-for-Vim.git' +Bundle 'git://github.com/csscomb/vim-csscomb.git' ``` ### With NeoBundle Add this to .vimrc: ``` -NeoBundle 'faceleg/vim-csscomb', { +NeoBundle 'csscomb/vim-csscomb', { \ 'build': { \ 'unix': 'npm install -g csscomb', \ 'mac': 'npm install -g csscomb' @@ -43,7 +43,7 @@ NeoBundle 'faceleg/vim-csscomb', { ### Manual without plugins manager ``` -git clone https://github.com/miripiruni/CSScomb-for-Vim.git csscomb +git clone https://github.com/csscomb/vim-csscomb.git csscomb cp -r csscomb/plugin/* ~/.vim/plugin/ ``` From 3a5b3ac072c542ffd87c3510c024964e5e53f942 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 24 May 2015 08:53:20 +1200 Subject: [PATCH 09/13] Updated suggested mapping comment --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4949821..2076e6c 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Vim command: ## Suggested Configuration ```VIML -"mnemonic: 'beatify css' +" Map bc to run CSScomb. bc stands for beautify css autocmd FileType css noremap bc :CSScomb " Automatically comb your CSS on save autocmd BufWritePre,FileWritePre *.css,*.scss,*.sass silent! :CSScomb From f8afcc7c2816cb0f46a36840c49a6b14551156b4 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 24 May 2015 09:01:26 +1200 Subject: [PATCH 10/13] Output csscomb error if there was one, do not attempt to update file content if error --- plugin/csscomb.vim | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugin/csscomb.vim b/plugin/csscomb.vim index 0d274a8..dae1b6b 100644 --- a/plugin/csscomb.vim +++ b/plugin/csscomb.vim @@ -11,10 +11,13 @@ function! g:CSScomb(count, line1, line2) let tempFile = tempname() . '.' . &filetype call writefile(content, tempFile) - call system('csscomb ' . shellescape(tempFile)) - let lines = readfile(tempFile) - - call setline(a:line1, lines) + let systemOutput = system('csscomb ' . shellescape(tempFile)) + if len(systemOutput) + echoerr split(systemOutput, "\n")[1] + else + let lines = readfile(tempFile) + call setline(a:line1, lines) + endif endfunction command! -nargs=? -range=% CSScomb :call g:CSScomb(, , , ) From 7f48e70a10a8736b2e7bcef0487a7c3f3e8df83a Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 25 May 2015 11:21:39 +1200 Subject: [PATCH 11/13] Updated readme with less support, removed build config portion of NeoBundle --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2076e6c..5fd4c0e 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,7 @@ Bundle 'git://github.com/csscomb/vim-csscomb.git' ### With NeoBundle Add this to .vimrc: ``` -NeoBundle 'csscomb/vim-csscomb', { - \ 'build': { - \ 'unix': 'npm install -g csscomb', - \ 'mac': 'npm install -g csscomb' - \ }} +NeoBundle 'csscomb/vim-csscomb' ``` ### Manual without plugins manager @@ -59,5 +55,5 @@ Vim command: " Map bc to run CSScomb. bc stands for beautify css autocmd FileType css noremap bc :CSScomb " Automatically comb your CSS on save -autocmd BufWritePre,FileWritePre *.css,*.scss,*.sass silent! :CSScomb +autocmd BufWritePre,FileWritePre *.css,*.less,*.scss,*.sass silent! :CSScomb ``` From 6317c8ffdf15dd29f1c06d5879d67dac6b840c22 Mon Sep 17 00:00:00 2001 From: Tony Ganch Date: Sat, 6 Jun 2015 03:07:03 +0200 Subject: [PATCH 12/13] Remove outdated docs --- doc/csscomb.txt | 71 ------------------------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 doc/csscomb.txt diff --git a/doc/csscomb.txt b/doc/csscomb.txt deleted file mode 100644 index 289ffba..0000000 --- a/doc/csscomb.txt +++ /dev/null @@ -1,71 +0,0 @@ -*csscomb.txt* CSScomb for Vim - -Vim plugin author: Aleksandr Batsuev -CSScomb author: Vyacheslav Oliyancuk -WebSite: http://csscomb.com -Repository: http://github.com/miripiruni/CSScomb-for-Vim - -============================================================================== -CONTENTS *csscomb-contents* - -About |csscomb-about| -Custom sort order |csscomb-custom-sort-order| -Install |csscomb-install| -Usage |csscomb-usage| - -============================================================================== -ABOUT *csscomb-about* - -The algorithm of CSScomb simulates web-technologist's actions upon working -with CSS-code to the limit. Usually to re-order code you move lines over each -other considering comments in the code, multilines records of property values, -hacks and everything that could be found in the real file. CSScomb reproduces -these actions for you. This means that the parser "thinks" as a person editing -the text, not as a blind robot parsing CSS. - -For more info, online demo and tests see http://csscomb.com - -What can CSScomb do? - -* Sorts CSS-properties within the selectors according to the settings. - -* Treats the initial formatting of style sheets carefully. - -* Sorts commented properties as if they are not commented. - -* Moves down unknown properties in the order they are met within the selector. - E.g.: he\ight: 100% and similar will be taken as the unknown ones. - -* Successfully parses @media ... {...} and any other constructions with @. - -* Successfully parses expressions and then moves them to the end of the - properties in the order they are met within the framework of properties of - one selector. - -============================================================================== -CUSTOM SORT ORDER *csscomb-custom-sort-order* - -For adjusting plugins use one-dimensional and two-dimensional JSON arrays. -In case of two-dimensional arrays the properties will be divided into groups -with an empty line. In plugins you should pick open file csscomb.php - -============================================================================== -INSTALL *csscomb-install* - -With Pathogen - cd ~/.vim/bundle - git clone https://github.com/miripiruni/csscomb-for-vim.git - -With Vundle - Add to .vimrc: - Bundle 'git://github.com/miripiruni/csscomb-for-vim.git' - -Manual without plugins manager - git clone https://github.com/miripiruni/CSScomb-for-Vim.git csscomb - cp -r csscomb/plugin/* ~/.vim/plugin/ - -============================================================================== -USAGE *csscomb-usage* - -For CSS resort you can use ':CSScomb' command. -Also you can select a part of CSS file and type ':CSScomb'. From d4c493da96ccc95bf2509b90ce14a09a5e343b9b Mon Sep 17 00:00:00 2001 From: Gertjan Reynaert Date: Mon, 24 Aug 2015 09:57:11 +0200 Subject: [PATCH 13/13] Fix vim configuration for auto-combing --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5fd4c0e..dca0269 100644 --- a/README.md +++ b/README.md @@ -55,5 +55,5 @@ Vim command: " Map bc to run CSScomb. bc stands for beautify css autocmd FileType css noremap bc :CSScomb " Automatically comb your CSS on save -autocmd BufWritePre,FileWritePre *.css,*.less,*.scss,*.sass silent! :CSScomb +autocmd BufWritePre,FileWritePre *.css,*.less,*.scss,*.sass silent! :CSScomb ```