Split up a CSS string by @media queries.

Parameters

string $css: String of CSS.

Return value

array array of css with only media queries.

See also

http://stackoverflow.com/questions/14145620/regular-expression-for-mediā€¦

1 call to Files::parseMediaBlocks()
Files::splitCssFile in src/State/Files.php
Given a file info array it will split the file up.

File

src/State/Files.php, line 244

Class

Files
Provides AdvAgg with a file status state system using a key value store.

Namespace

Drupal\advagg\State

Code

private function parseMediaBlocks($css) {
    $media_blocks = [];
    $start = 0;
    $last_start = 0;
    // Using the string as an array throughout this function.
    // http://php.net/types.string#language.types.string.substr
    while (($start = strpos($css, "@media", $start)) !== FALSE) {
        // Stack to manage brackets.
        $s = [];
        // Get the first opening bracket.
        $i = strpos($css, "{", $start);
        // If $i is false, then there is probably a css syntax error.
        if ($i === FALSE) {
            continue;
        }
        // Push bracket onto stack.
        array_push($s, $css[$i]);
        // Move past first bracket.
        ++$i;
        // Find the closing bracket for the @media statement. But ensure we don't
        // overflow if there's an error.
        while (!empty($s) && isset($css[$i])) {
            // If the character is an opening bracket, push it onto the stack,
            // otherwise pop the stack.
            if ($css[$i] === "{") {
                array_push($s, "{");
            }
            elseif ($css[$i] === "}") {
                array_pop($s);
            }
            ++$i;
        }
        // Get CSS before @media and store it.
        if ($last_start != $start) {
            $insert = trim(substr($css, $last_start, $start - $last_start));
            if (!empty($insert)) {
                $media_blocks[] = $insert;
            }
        }
        // Cut @media block out of the css and store.
        $media_blocks[] = trim(substr($css, $start, $i - $start));
        // Set the new $start to the end of the block.
        $start = $i;
        $last_start = $start;
    }
    // Add in any remaining css rules after the last @media statement.
    if (strlen($css) > $last_start) {
        $insert = trim(substr($css, $last_start));
        if (!empty($insert)) {
            $media_blocks[] = $insert;
        }
    }
    return $media_blocks;
}