You are here

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,
  );
}