const EMBED_SIZE_LIMIT = 24576;
const URL_REGEX = 'url\(\s*[\'"]?(?P<file>[^\?\)\'"]*?)(?P<query>\?[^\)\'"]*?|)[\'"]?\s*\)';
const EMBED_REGEX = '\/\*\s*\@embed\s*\*\/';
+ const COMMENT_REGEX = '\/\*.*?\*\/';
/* Protected Static Members */
$remote = substr( $remote, 0, -1 );
}
+ // 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();
+ $placeholder = uniqid( '', true );
+
+ $pattern = '/(?!' . CSSMin::EMBED_REGEX . ')(' . CSSMin::COMMENT_REGEX . ')/s';
+
+ $source = preg_replace_callback(
+ $pattern,
+ function ( $match ) use ( &$comments, $placeholder ) {
+ $comments[] = $match[ 0 ];
+ return $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 . '[^;}]*(?=[;}]|$)/';
- return preg_replace_callback(
+ $source = preg_replace_callback(
$pattern,
function ( $matchOuter ) use ( $local, $remote, $embedData ) {
$rule = $matchOuter[0];
return $ruleWithRemapped;
}
}, $source );
+
+ // Re-insert comments
+ $pattern = '/' . $placeholder . '(\d+)x/';
+ $source = preg_replace_callback( $pattern, function( $match ) use ( &$comments ) {
+ return $comments[ $match[1] ];
+ }, $source );
+
+ return $source;
+
}
/**
'@import url(//localhost/styles.css?query=yes)',
'@import url(//localhost/styles.css?query=yes)',
),
+ array(
+ 'Simple case with comments before url',
+ 'foo { prop: /* some {funny;} comment */ url(bar.png); }',
+ 'foo { prop: /* some {funny;} comment */ url(http://localhost/w/bar.png); }',
+ ),
+ array(
+ 'Simple case with comments after url',
+ 'foo { prop: url(red.gif)/* some {funny;} comment */ ; }',
+ 'foo { prop: url(http://localhost/w/red.gif?timestamp)/* some {funny;} comment */ ; }',
+ ),
+ array(
+ 'Embedded file with comment before url',
+ 'foo { /* @embed */ background: /* some {funny;} comment */ url(red.gif); }',
+ "foo { background: /* some {funny;} comment */ url($red); background: /* some {funny;} comment */ url(http://localhost/w/red.gif?timestamp)!ie; }",
+ ),
+ array(
+ 'Embedded file with comments inside and outside the rule',
+ 'foo { /* @embed */ background: url(red.gif) /* some {foo;} comment */; /* some {bar;} comment */ }',
+ "foo { background: url($red) /* some {foo;} comment */; background: url(http://localhost/w/red.gif?timestamp) /* some {foo;} comment */!ie; /* some {bar;} comment */ }",
+ ),
+ array(
+ 'Embedded file with comment outside the rule',
+ 'foo { /* @embed */ background: url(red.gif); /* some {funny;} comment */ }',
+ "foo { background: url($red); background: url(http://localhost/w/red.gif?timestamp)!ie; /* some {funny;} comment */ }",
+ ),
+ array(
+ 'Rule with two urls, each with comments',
+ '{ background: /*asd*/ url(something.png); background: /*jkl*/ url(something.png); }',
+ '{ background: /*asd*/ url(http://localhost/w/something.png); background: /*jkl*/ url(http://localhost/w/something.png); }',
+ ),
+ array(
+ 'Sanity check for offending line from jquery.ui.theme.css (bug 60077)',
+ '.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; }',
+ '.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(http://localhost/w/images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; }',
+ ),
);
}