CSSmin::extract_data_urls PHP Method

extract_data_urls() private method

Utility method to replace all data urls with tokens before we start compressing, to avoid performance issues running some of the subsequent regexes against large strings chunks.
private extract_data_urls ( string $css ) : string
$css string
return string
    private function extract_data_urls($css)
    {
        // Leave data urls alone to increase parse performance.
        $max_index = strlen($css) - 1;
        $append_index = $index = $last_index = $offset = 0;
        $sb = array();
        $pattern = '/url\\(\\s*(["\']?)data\\:/i';
        // Since we need to account for non-base64 data urls, we need to handle
        // ' and ) being part of the data string. Hence switching to indexOf,
        // to determine whether or not we have matching string terminators and
        // handling sb appends directly, instead of using matcher.append* methods.
        while (preg_match($pattern, $css, $m, 0, $offset)) {
            $index = $this->index_of($css, $m[0], $offset);
            $last_index = $index + strlen($m[0]);
            $start_index = $index + 4;
            // "url(".length()
            $end_index = $last_index - 1;
            $terminator = $m[1];
            // ', " or empty (not quoted)
            $found_terminator = FALSE;
            if (strlen($terminator) === 0) {
                $terminator = ')';
            }
            while ($found_terminator === FALSE && $end_index + 1 <= $max_index) {
                $end_index = $this->index_of($css, $terminator, $end_index + 1);
                // endIndex == 0 doesn't really apply here
                if ($end_index > 0 && substr($css, $end_index - 1, 1) !== '\\') {
                    $found_terminator = TRUE;
                    if (')' != $terminator) {
                        $end_index = $this->index_of($css, ')', $end_index);
                    }
                }
            }
            // Enough searching, start moving stuff over to the buffer
            $sb[] = $this->str_slice($css, $append_index, $index);
            if ($found_terminator) {
                $token = $this->str_slice($css, $start_index, $end_index);
                // remove whitespace, except if $token contains <svg, which needs whitepace left as is
                if (strpos($token, "<svg") === false && strpos($token, 'svg+xml') === false) {
                    $token = preg_replace('/\\s+/', '', $token);
                }
                $this->preserved_tokens[] = $token;
                $preserver = 'url(' . self::TOKEN . (count($this->preserved_tokens) - 1) . '___)';
                $sb[] = $preserver;
                $append_index = $end_index + 1;
            } else {
                // No end terminator found, re-add the whole match. Should we throw/warn here?
                $sb[] = $this->str_slice($css, $index, $last_index);
                $append_index = $last_index;
            }
            $offset = $last_index;
        }
        $sb[] = $this->str_slice($css, $append_index);
        return implode('', $sb);
    }