if ( empty( $attrs['rel'] ) ) {
if ( 'stylesheet' !== $attrs['rel'] ) {
if ( 'preload' !== $attrs['rel'] || empty( $attrs['as'] ) || 'style' !== $attrs['as'] ) {
if ( ! empty( $attrs['media'] ) && false !== strpos( $attrs['media'], 'print' ) ) {
if ( empty( $attrs['href'] ) ) {
// Check Google fonts hit
if ( false !== strpos( $attrs['href'], 'fonts.googleapis.com' ) ) {
$html = str_replace( $match[0], '', $html );
$debug_info = $attrs['href'];
// Dryrun will not load CSS but just drop them
$con = $this->cls( 'Optimizer' )->load_file( $attrs['href'] );
$attrs = Utility::parse_attr( $match[2] );
if ( ! empty( $attrs['media'] ) && false !== strpos( $attrs['media'], 'print' ) ) {
Debug2::debug2( '[CSS] Load inline CSS ' . substr( $match[3], 0, 100 ) . '...', $attrs );
$debug_info = '__INLINE__';
$con = Optimizer::minify_css( $con );
if ( $is_webp && $this->cls( 'Media' )->webp_support() ) {
$con = $this->cls( 'Media' )->replace_background_webp( $con );
if ( ! empty( $attrs['media'] ) && 'all' !== $attrs['media'] ) {
$con = '@media ' . $attrs['media'] . '{' . $con . "}\n";
$con = '/* ' . $debug_info . ' */' . $con;
$html = str_replace( $match[0], '', $html );
* Filter the comment content, add quotes to selector from whitelist. Return the json.
private function _filter_whitelist() {
$list = apply_filters( 'litespeed_ccss_whitelist', $this->conf( self::O_OPTM_CCSS_SELECTOR_WHITELIST ) );
foreach ( $list as $v ) {
if ( substr( $v, 0, 2 ) === '//' ) {
* Notify finished from server.
public function notify() {
// phpcs:ignore WordPress.Security.NonceVerification.Missing
$post_data = \json_decode( file_get_contents( 'php://input' ), true );
if ( is_null( $post_data ) ) {
// Fallback for form-encoded payloads
// phpcs:ignore WordPress.Security.NonceVerification.Missing
self::debug( 'notify() data', $post_data );
$this->_queue = $this->load_queue( 'ccss' );
list( $post_data ) = $this->cls( 'Cloud' )->extract_msg( $post_data, 'ccss' );
$notified_data = $post_data['data'];
if ( empty( $notified_data ) || ! is_array( $notified_data ) ) {
self::debug( '❌ notify exit: no notified data' );
return Cloud::err( 'no notified data' );
// Check if its in queue or not
foreach ( $notified_data as $v ) {
if ( empty( $v['request_url'] ) ) {
self::debug( '❌ notify bypass: no request_url', $v );
if ( empty( $v['queue_k'] ) ) {
self::debug( '❌ notify bypass: no queue_k', $v );
if ( empty( $this->_queue[ $v['queue_k'] ] ) ) {
self::debug( '❌ notify bypass: no this queue [q_k]' . $v['queue_k'] );
if ( ! empty( $v['data_ccss'] ) ) {
$is_mobile = $this->_queue[ $v['queue_k'] ]['is_mobile'];
$is_webp = $this->_queue[ $v['queue_k'] ]['is_webp'];
$this->_save_con( 'ccss', $v['data_ccss'], $v['queue_k'], $is_mobile, $is_webp );
unset( $this->_queue[ $v['queue_k'] ] );
self::debug( 'notify data handled, unset queue [q_k] ' . $v['queue_k'] );
$this->save_queue( 'ccss', $this->_queue );
self::debug( 'notified' );
return Cloud::ok( [ 'count' => $valid_i ] );
* Handle all request actions from main cls.
public function handler() {
$type = Router::verify_type();
case self::TYPE_GEN_CCSS:
case self::TYPE_CLEAR_Q_CCSS:
$this->clear_q( 'ccss' );