function advagg_split_css_string in Advanced CSS/JS Aggregation 7.2
Given a css string it will split it if it's over the selector limit.
Parameters
string $css_string: CSS string.
int $selector_limit: How many selectors can be grouped together.
Return value
array Array that contains the $media_query and the $css_array.
1 call to advagg_split_css_string()
- advagg_split_css_file in ./
advagg.inc - Given a file info array it will split the file up.
File
- ./
advagg.inc, line 1205 - Advanced CSS/JS aggregation module.
Code
function advagg_split_css_string($css_string, $selector_limit) {
// See if this css string is wrapped in a @media statement.
$media_query = '';
$media_query_pos = strpos($css_string, '@media');
if ($media_query_pos !== FALSE) {
// Get the opening bracket.
$open_bracket_pos = strpos($css_string, "{", $media_query_pos);
// Skip if there is a syntax error.
if ($open_bracket_pos === FALSE) {
return array();
}
$media_query = substr($css_string, $media_query_pos, $open_bracket_pos - $media_query_pos);
$css_string_inside = substr($css_string, $open_bracket_pos + 1);
}
else {
$css_string_inside = $css_string;
}
// Split CSS into selector chunks.
$split = preg_split('/(\\{.+?\\}|,)/si', $css_string_inside, -1, PREG_SPLIT_DELIM_CAPTURE);
$new_css_chunk = array(
0 => '',
);
$selector_chunk_counter = 0;
$counter = 0;
// Have the key value be the running selector count and put split array semi
// back together.
foreach ($split as $value) {
$new_css_chunk[$counter] .= $value;
if (strpos($value, '}') === FALSE) {
++$selector_chunk_counter;
}
else {
if ($counter + 1 < $selector_chunk_counter) {
$selector_chunk_counter += ($counter - $selector_chunk_counter + 1) / 2;
}
$counter = $selector_chunk_counter;
if (!isset($new_css_chunk[$counter])) {
$new_css_chunk[$counter] = '';
}
}
}
// Generate output array in this function.
$css_array = array();
$keys = array_keys($new_css_chunk);
$counter = 0;
$chunk_counter = 0;
foreach (array_keys($keys) as $key) {
// Get out of loop if at the end of the array.
if (!isset($keys[$key + 1])) {
break;
}
// Get values, keys and counts.
$this_value = $new_css_chunk[$keys[$key]];
$this_key = $keys[$key];
$next_key = $keys[$key + 1];
$this_selector_count = $next_key - $this_key;
// Single rule is bigger than the selector limit.
if ($this_selector_count > $selector_limit) {
// Get css rules for these selectors.
$open_bracket_pos = strpos($this_value, "{");
$css_rule = ' ' . substr($this_value, $open_bracket_pos);
// Split on selectors.
$split = preg_split('/(\\,)/si', $this_value, NULL, PREG_SPLIT_OFFSET_CAPTURE);
$index = 0;
$counter = 0;
while (isset($split[$index][1])) {
// Get starting and ending positions of the selectors given the selector
// limit.
$next_index = $index + $selector_limit - 1;
$start = $split[$index][1];
if (isset($split[$next_index][1])) {
$end = $split[$next_index][1];
}
else {
// Last one.
$temp = end($split);
$split_key = key($split);
$counter = $split_key % $selector_limit;
$end_open_bracket_pos = (int) strpos($temp[0], "{");
$end = $temp[1] + $end_open_bracket_pos;
}
// Extract substr.
$sub_this_value = substr($this_value, $start, $end - $start - 1) . $css_rule;
// Save substr.
++$chunk_counter;
$key_output = $selector_limit;
if (!empty($counter)) {
$key_output = $selector_limit - $counter;
}
$css_array["{$chunk_counter} {$key_output}"] = '';
if (!isset($css_array[$chunk_counter])) {
$css_array[$chunk_counter] = $sub_this_value;
}
else {
$css_array[$chunk_counter] .= $sub_this_value;
}
// Move counter.
$index = $next_index;
}
continue;
}
$counter += $this_selector_count;
if ($counter > $selector_limit) {
$key_output = $counter - $this_selector_count;
$css_array["{$chunk_counter} {$key_output}"] = '';
$counter = $next_key - $this_key;
++$chunk_counter;
}
if (!isset($css_array[$chunk_counter])) {
$css_array[$chunk_counter] = $this_value;
}
else {
$css_array[$chunk_counter] .= $this_value;
}
}
// Group into sets smaller than $selector_limit.
return array(
$media_query,
$css_array,
);
}