33 private const PLACEHOLDER =
"\x7fPLACEHOLDER\x7f";
46 'jpe' =>
'image/jpeg',
47 'jpeg' =>
'image/jpeg',
48 'jpg' =>
'image/jpeg',
50 'tif' =>
'image/tiff',
51 'tiff' =>
'image/tiff',
52 'xbm' =>
'image/x-xbitmap',
53 'svg' =>
'image/svg+xml',
64 $stripped = preg_replace(
'/' . self::COMMENT_REGEX .
'/s',
'',
$source );
68 $rFlags = PREG_OFFSET_CAPTURE | PREG_SET_ORDER;
69 if ( preg_match_all(
'/' . self::getUrlRegex() .
'/J', $stripped,
$matches, $rFlags ) ) {
71 $url = $match[
'file'][0];
75 substr( $url, 0, 2 ) ===
'//' ||
76 parse_url( $url, PHP_URL_SCHEME )
82 $anchor = strpos( $url,
'#' );
83 if ( $anchor !==
false ) {
84 $url = substr( $url, 0, $anchor );
92 $files[] =
$path . $url;
115 if ( $ie8Compat && filesize(
$file ) >= self::DATA_URI_SIZE_LIMIT ) {
119 if (
$type ===
null ) {
145 $contents = preg_replace(
"/<\\?xml.*?\\?>/",
'', $contents );
147 if ( preg_match(
'/^[\r\n\t\x20-\x7e]+$/', $contents ) ) {
150 $encoded = rawurlencode( $contents );
152 $encoded = strtr( $encoded, [
162 $encoded = preg_replace(
'/ {2,}/',
' ', $encoded );
164 $encoded = preg_replace(
'/^ | $/',
'', $encoded );
166 $uri =
'data:' .
$type .
',' . $encoded;
167 if ( !$ie8Compat || strlen( $uri ) < self::DATA_URI_SIZE_LIMIT ) {
173 $uri =
'data:' .
$type .
';base64,' . base64_encode( $contents );
174 if ( !$ie8Compat || strlen( $uri ) < self::DATA_URI_SIZE_LIMIT ) {
190 $value = strtr( $value, [
"\0" =>
"\u{FFFD}",
'\\' =>
'\\\\',
'"' =>
'\\"' ] );
191 $value = preg_replace_callback(
'/[\x01-\x1f\x7f]/',
function ( $match ) {
192 return '\\' . base_convert( ord( $match[0] ), 10, 16 ) .
' ';
194 return '"' . $value .
'"';
203 $ext = strtolower( pathinfo(
$file, PATHINFO_EXTENSION ) );
204 return self::$mimeTypes[
$ext] ?? mime_content_type( realpath(
$file ) );
220 if ( preg_match(
'!^[\w:@/~.%+;,?&=-]+$!', $url ) ) {
223 return 'url("' . strtr( $url, [
'\\' =>
'\\\\',
'"' =>
'\\"' ] ) .
'")';
238 public static function remap(
$source, $local, $remote, $embedData =
true ) {
250 if ( substr( $remote, -1 ) ==
'/' ) {
251 $remote = substr( $remote, 0, -1 );
263 $pattern =
'/(?!' . self::EMBED_REGEX .
')(' . self::COMMENT_REGEX .
')/s';
265 $source = preg_replace_callback(
267 function ( $match ) use ( &$comments ) {
268 $comments[] = $match[ 0 ];
269 return self::PLACEHOLDER . ( count( $comments ) - 1 ) .
'x';
280 $source = preg_replace_callback(
282 function ( $matchOuter ) use ( $local, $remote, $embedData ) {
283 $rule = $matchOuter[0];
288 $rule = preg_replace(
302 $pattern =
'/(?P<embed>' . self::EMBED_REGEX .
'\s*|)' .
self::getUrlRegex() .
'/J';
304 $ruleWithRemapped = preg_replace_callback(
306 function ( $match ) use ( $local, $remote ) {
307 $remapped =
self::remapOne( $match[
'file'], $match[
'query'], $local, $remote,
false );
317 $ruleWithEmbedded = preg_replace_callback(
319 function ( $match ) use ( $embedAll, $local, $remote, &
$mimeTypes ) {
320 $embed = $embedAll || $match[
'embed'];
329 $url = $match[
'file'] . $match[
'query'];
330 $file =
"{$local}/{$match['file']}";
332 !self::isRemoteUrl( $url ) && !self::isLocalUrl( $url )
333 && file_exists(
$file )
347 if ( !$embedData || $ruleWithEmbedded === $ruleWithRemapped ) {
349 return $ruleWithRemapped;
352 return $ruleWithEmbedded;
357 $pattern =
'/' . self::PLACEHOLDER .
'(\d+)x/';
358 $source = preg_replace_callback( $pattern,
function ( $match ) use ( &$comments ) {
359 return $comments[ $match[1] ];
372 if ( substr( $maybeUrl, 0, 2 ) ===
'//' || parse_url( $maybeUrl, PHP_URL_SCHEME ) ) {
385 return isset( $maybeUrl[1] ) && $maybeUrl[0] ===
'/' && $maybeUrl[1] !==
'/';
394 if ( $urlRegex ===
null ) {
397 'url\(\s*(?P<file>[^\s\'"][^\?\)]+?)(?P<query>\?[^\)]*?|)\s*\)' .
399 '|url\(\s*\'(?P<file>[^\?\']+?)(?P<query>\?[^\']*?|)\'\s*\)' .
401 '|url\(\s*"(?P<file>[^\?"]+?)(?P<query>\?[^"]*?|)"\s*\)' .
419 $url =
$file . $query;
423 if ( self::isLocalUrl( $url ) && function_exists(
'wfExpandUrl' ) ) {
431 self::isRemoteUrl( $url ) ||
432 self::isLocalUrl( $url ) ||
433 substr( $url, 0, 1 ) ===
'#'
438 if ( $local ===
false ) {
440 $url = $remote .
'/' . $url;
443 $url =
"{$remote}/{$file}";
445 $localFile =
"{$local}/{$file}";
446 if ( file_exists( $localFile ) ) {
449 if ( $data !==
false ) {
453 if ( class_exists( OutputPage::class ) ) {
454 $url = OutputPage::transformFilePath( $remote, $local,
$file );
458 $url .=
'?' . substr( md5_file( $localFile ), 0, 5 );
464 if ( function_exists(
'wfRemoveDotSegments' ) ) {
479 [
'; ',
': ',
' {',
'{ ',
', ',
'} ',
';}',
'( ',
' )',
'[ ',
' ]' ],
480 [
';',
':',
'{',
'{',
',',
'}',
'}',
'(',
')',
'[',
']' ],
481 preg_replace( [
'/\s+/',
'/\/\*.*?\*\//s' ], [
' ',
'' ], $css )
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfRemoveDotSegments( $urlPath)
Remove all dot-segments in the provided URL path.
static serializeStringValue( $value)
Serialize a string (escape and quote) for use as a CSS string value.
static buildUrlValue( $url)
Build a CSS 'url()' value for the given URL, quoting parentheses (and other funny characters) and esc...
static encodeImageAsDataURI( $file, $type=null, $ie8Compat=true)
Encode an image file as a data URI.
static getMimeType( $file)
static string[] $mimeTypes
List of common image files extensions and MIME-types.
static isRemoteUrl( $maybeUrl)
Is this CSS rule referencing a remote URL?
static getLocalFileReferences( $source, $path)
Get a list of local files referenced in a stylesheet (includes non-existent files).
static encodeStringAsDataURI( $contents, $type, $ie8Compat=true)
Encode file contents as a data URI with chosen MIME type.
static minify( $css)
Removes whitespace from CSS data.
static isLocalUrl( $maybeUrl)
Is this CSS rule referencing a local URL?
static remapOne( $file, $query, $local, $remote, $embed)
Remap or embed a CSS URL path.
const DATA_URI_SIZE_LIMIT
Internet Explorer data URI length limit.
static remap( $source, $local, $remote, $embedData=true)
Remaps CSS URL paths and automatically embeds data URIs for CSS rules or url() values preceded by an ...
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
if(!is_readable( $file)) $ext