コード例 #1
0
ファイル: CSSMin.php プロジェクト: natebrunette/sphericalcow
 /**
  * Remaps CSS URL paths and automatically embeds data URIs for CSS rules
  * or url() values preceded by an / * @embed * / comment.
  *
  * @param string $source CSS data to remap
  * @param string $local File path where the source was read from
  * @param string $remote URL path to the file
  * @param bool $embedData If false, never do any data URI embedding,
  *   even if / * @embed * / is found.
  * @return string Remapped CSS data
  */
 public static function remap($source, $local, $remote, $embedData = true)
 {
     // High-level overview:
     // * For each CSS rule in $source that includes at least one url() value:
     //   * Check for an @embed comment at the start indicating that all URIs should be embedded
     //   * For each url() value:
     //     * Check for an @embed comment directly preceding the value
     //     * If either @embed comment exists:
     //       * Embedding the URL as data: URI, if it's possible / allowed
     //       * Otherwise remap the URL to work in generated stylesheets
     // Guard against trailing slashes, because "some/remote/../foo.png"
     // resolves to "some/remote/foo.png" on (some?) clients (bug 27052).
     if (substr($remote, -1) == '/') {
         $remote = substr($remote, 0, -1);
     }
     // Disallow U+007F DELETE, which is illegal anyway, and which
     // we use for comment placeholders.
     $source = str_replace("", "?", $source);
     // Replace all comments by a placeholder so they will not interfere with the remapping.
     // Warning: This will also catch on anything looking like the start of a comment between
     // quotation marks (e.g. "foo /* bar").
     $comments = array();
     $pattern = '/(?!' . CSSMin::EMBED_REGEX . ')(' . CSSMin::COMMENT_REGEX . ')/s';
     $source = preg_replace_callback($pattern, function ($match) use(&$comments) {
         $comments[] = $match[0];
         return CSSMin::PLACEHOLDER . (count($comments) - 1) . 'x';
     }, $source);
     // Note: This will not correctly handle cases where ';', '{' or '}'
     // appears in the rule itself, e.g. in a quoted string. You are advised
     // not to use such characters in file names. We also match start/end of
     // the string to be consistent in edge-cases ('@import url(…)').
     $pattern = '/(?:^|[;{])\\K[^;{}]*' . CSSMin::URL_REGEX . '[^;}]*(?=[;}]|$)/';
     $source = preg_replace_callback($pattern, function ($matchOuter) use($local, $remote, $embedData) {
         $rule = $matchOuter[0];
         // Check for global @embed comment and remove it. Allow other comments to be present
         // before @embed (they have been replaced with placeholders at this point).
         $embedAll = false;
         $rule = preg_replace('/^((?:\\s+|' . CSSMin::PLACEHOLDER . '(\\d+)x)*)' . CSSMin::EMBED_REGEX . '\\s*/', '$1', $rule, 1, $embedAll);
         // Build two versions of current rule: with remapped URLs
         // and with embedded data: URIs (where possible).
         $pattern = '/(?P<embed>' . CSSMin::EMBED_REGEX . '\\s*|)' . CSSMin::URL_REGEX . '/';
         $ruleWithRemapped = preg_replace_callback($pattern, function ($match) use($local, $remote) {
             $remapped = CSSMin::remapOne($match['file'], $match['query'], $local, $remote, false);
             return CSSMin::buildUrlValue($remapped);
         }, $rule);
         if ($embedData) {
             // Remember the occurring MIME types to avoid fallbacks when embedding some files.
             $mimeTypes = array();
             $ruleWithEmbedded = preg_replace_callback($pattern, function ($match) use($embedAll, $local, $remote, &$mimeTypes) {
                 $embed = $embedAll || $match['embed'];
                 $embedded = CSSMin::remapOne($match['file'], $match['query'], $local, $remote, $embed);
                 $url = $match['file'] . $match['query'];
                 $file = $local . $match['file'];
                 if (!CSSMin::isRemoteUrl($url) && !CSSMin::isLocalUrl($url) && file_exists($file)) {
                     $mimeTypes[CSSMin::getMimeType($file)] = true;
                 }
                 return CSSMin::buildUrlValue($embedded);
             }, $rule);
             // Are all referenced images SVGs?
             $needsEmbedFallback = $mimeTypes !== array('image/svg+xml' => true);
         }
         if (!$embedData || $ruleWithEmbedded === $ruleWithRemapped) {
             // We're not embedding anything, or we tried to but the file is not embeddable
             return $ruleWithRemapped;
         } elseif ($embedData && $needsEmbedFallback) {
             // Build 2 CSS properties; one which uses a data URI in place of the @embed comment, and
             // the other with a remapped and versioned URL with an Internet Explorer 6 and 7 hack
             // making it ignored in all browsers that support data URIs
             return "{$ruleWithEmbedded};{$ruleWithRemapped}!ie";
         } else {
             // Look ma, no fallbacks! This is for files which IE 6 and 7 don't support anyway: SVG.
             return $ruleWithEmbedded;
         }
     }, $source);
     // Re-insert comments
     $pattern = '/' . CSSMin::PLACEHOLDER . '(\\d+)x/';
     $source = preg_replace_callback($pattern, function ($match) use(&$comments) {
         return $comments[$match[1]];
     }, $source);
     return $source;
 }
コード例 #2
0
 /**
  * @dataProvider provideIsRemoteUrl
  * @cover CSSMin::isRemoteUrl
  */
 public function testIsRemoteUrl($expect, $url)
 {
     $this->assertEquals(CSSMin::isRemoteUrl($url), $expect);
 }
コード例 #3
0
ファイル: CSSMinTest.php プロジェクト: claudinec/galan-wiki
 public static function isRemoteUrl($maybeUrl)
 {
     return parent::isRemoteUrl($maybeUrl);
 }