File "class-slim.php"
Full Path: /home/theinspectionboy/public_html/suffolk/includes/class-slim.php
File size: 50.28 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Class and methods to eliminate unused JS/CSS.
*
* @link https://ewww.io/swis/
* @package SWIS_Performance
*/
namespace SWIS;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Enables plugin to Lazy Load images.
*/
final class Slim extends Base {
/**
* The list of JS/CSS assets and associated information.
*
* @var array
*/
private $assets = array();
/**
* The type of the current page.
*
* @var array
*/
private $content_type = '';
/**
* A list of registered content types.
*
* @var array
*/
private $content_types = array();
/**
* The URL path to the home page.
*
* @var string
*/
private $home_path = '';
/**
* Store asset dependencies.
*
* @var array
*/
private $deps = array();
/**
* A list of user-defined exclusions, populated by validate_user_exclusions().
*
* @access protected
* @var array $user_exclusions
*/
public $user_exclusions = array();
/**
* CSS/JS that should not ever be excluded.
*
* @var array
*/
private $whitelist = array( 'admin-bar', 'dashicons', 'swis-performance-slim' );
/**
* Register actions and filters for JS/CSS Slim.
*/
function __construct() {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
parent::__construct();
if ( ! is_admin() ) {
$permissions = apply_filters( 'swis_performance_admin_permissions', 'manage_options' );
add_action( 'admin_bar_init', array( $this, 'admin_bar_init' ) );
if ( current_user_can( $permissions ) && ( ! defined( 'SWIS_SLIM_DISABLE_FRONTEND_MENU' ) || ! SWIS_SLIM_DISABLE_FRONTEND_MENU ) ) {
add_action( 'wp_head', array( $this, 'dash_css' ) );
add_action( 'wp_head', array( $this, 'find_assets' ), 9999 );
add_action( 'wp_enqueue_scripts', array( $this, 'frontend_script' ) );
add_action( 'wp_footer', array( $this, 'find_assets' ), 9999 );
add_action( 'wp_footer', array( $this, 'dash_script' ), 9999 );
add_action( 'wp_footer', array( $this, 'display_assets' ), 10000 );
}
if ( $this->get_option( 'slim_js_css' ) || $this->get_option( 'optimize_fonts_list' ) ) {
add_action( 'template_redirect', array( $this, 'get_content_type' ) );
add_action( 'template_redirect', array( $this, 'maybe_remove_emoji' ), 11 );
add_filter( 'script_loader_src', array( $this, 'disable_assets' ), 10, 2 );
add_filter( 'style_loader_src', array( $this, 'disable_assets' ), 10, 2 );
$this->validate_user_exclusions();
}
}
add_action( 'wp_ajax_swis_slim_rule_edit', array( $this, 'edit_rule' ) );
}
/**
* Checks if admin bar is visible, then adds an action to add our menu item.
*/
function admin_bar_init() {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
if (
! current_user_can( apply_filters( 'swis_admin_permissions', 'edit_others_posts' ) ) ||
! is_admin_bar_showing() ||
! $this->is_frontend()
) {
return;
}
add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_menu_item' ), 100 );
}
/**
* Adds a resize detection button to the wp admin bar.
*
* @param object $wp_admin_bar The WP Admin Bar object, passed by reference.
*/
function add_admin_bar_menu_item( $wp_admin_bar ) {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
$wp_admin_bar->add_menu(
array(
'id' => 'swis',
'parent' => null,
'title' => '<span id="swis-slim-show-top"><span class="ab-icon"></span><span class="ab-label">' . __( 'SWIS', 'swis-performance' ) . '</span></span>',
)
);
if ( defined( 'SWIS_SLIM_DISABLE_FRONTEND_MENU' ) && SWIS_SLIM_DISABLE_FRONTEND_MENU ) {
return;
}
$wp_admin_bar->add_menu(
array(
'id' => 'swis-slim',
'parent' => 'swis',
'title' => '<span id="swis-slim-show"><span class="ab-item">' . __( 'Manage JS/CSS', 'swis-performance' ) . '</span></span>',
)
);
}
/**
* Enqueue JS needed for the front-end assets pane.
*/
function frontend_script() {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
wp_enqueue_script( 'swis-performance-slim', plugins_url( '/assets/slim.js', SWIS_PLUGIN_FILE ), array( 'jquery-core' ), SWIS_PLUGIN_VERSION, true );
wp_localize_script(
'swis-performance-slim',
'swisperformance_vars',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'_wpnonce' => wp_create_nonce( 'swis-performance-settings' ),
'invalid_response' => esc_html__( 'Received an invalid response from your website, please check for errors in the Developer Tools console of your browser.', 'swis-performance' ),
'remove_rule' => esc_html__( 'Are you sure you want to remove this rule?', 'swis-performance' ),
'removing_message' => esc_html__( 'Deleting...', 'swis-performance' ),
'saving_message' => esc_html__( 'Saving...', 'swis-performance' ),
)
);
}
/**
* Adds some dashicon CSS for our admin bar item.
*/
function dash_css() {
if ( ! $this->is_frontend() ) {
return;
}
$slim_css = file_get_contents( SWIS_PLUGIN_PATH . 'assets/swis.css' );
?>
<style>
<?php echo $slim_css; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
#wpadminbar #swis-slim-show-top, #wpadminbar #swis-slim-show {
cursor: pointer;
}
#wpadminbar #wp-admin-bar-swis .ab-icon:before {
content: '\f198';
top: 2px;
}
#swis-slim-close-pane {
/*border: 1px solid #aaa;
color: #6d6d6d;
cursor: pointer;*/
float: right;
font-size: 16px;
/*padding: 5px;*/
}
#swis-slim-close-pane:hover {
/*border: 1px solid #000;
color: #000;*/
}
#swis-slim-assets-pane {
background-color: #fff;
color: #000;
font-family: sans-serif;
padding: 15px;
}
#swis-slim-assets-pane h1 {
font-family: sans-serif;
font-size: 36px;
}
#swis-slim-assets-pane h2 {
font-family: sans-serif;
font-size: 30px;
}
.swis-slim-unscroll {
overflow: hidden;
}
.swis-slim-visible {
display: block;
position: fixed;
top: 32px;
left: 0;
bottom: 0;
overflow: scroll;
width: 100%;
height: calc(100% - 32px);
z-index: 99999;
}
.swis-slim-assets {
border: 1px solid #ddd;
border-collapse: collapse;
font-family: sans-serif;
width: 100%;
}
.swis-slim-assets th {
font-weight: 700;
}
.swis-slim-assets th, .swis-slim-assets td {
border: 1px solid #ddd;
font-family: sans-serif;
font-size: 16px;
padding: 8px;
}
.swis-slim-asset-active {
width: 75px;
}
.swis-slim-asset-size {
width: 100px;
}
.swis-slim-active-yes {
font-weight: bolder;
color: green;
}
.swis-slim-active-no {
font-weight: bolder;
color: red;
}
@media screen and (max-width: 782px) {
#wpadminbar li#wp-admin-bar-swis-slim{
display: block!important;
}
}
</style>
<?php
}
/**
* Adds the script for our admin bar action.
*/
function dash_script() {
if ( ! $this->is_frontend() ) {
return;
}
?>
<script>
function toggleSWISPane() {
var SWISPane = document.getElementById('swis-slim-assets-pane');
SWISPane.classList.toggle('swis-slim-hidden');
SWISPane.classList.toggle('swis-slim-visible');
document.body.classList.toggle('swis-slim-unscroll');
}
function addSWISClickers() {
document.getElementById('swis-slim-show-top').addEventListener('click', toggleSWISPane);
document.getElementById('swis-slim-show').addEventListener('click', toggleSWISPane);
document.getElementById('swis-slim-close-pane').addEventListener('click', toggleSWISPane);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', addSWISClickers);
} else {
addSWISClickers();
}
</script>
<?php
}
/**
* Handle a rule update via AJAX. Possible actions are "create", "update", and "delete".
*
* On success, returns the updated HTML for the rule to display, an error message otherwise.
*/
function edit_rule() {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
if ( empty( $_REQUEST['swis_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['swis_wpnonce'] ), 'swis-performance-settings' ) ) {
die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'swis-performance' ) ) ) );
}
if ( empty( $_POST['swis_slim_action'] ) ) {
die( wp_json_encode( array( 'error' => esc_html__( 'Invalid operation requested.', 'swis-performance' ) ) ) );
}
if ( empty( $_POST['swis_slim_handle'] ) ) {
die( wp_json_encode( array( 'error' => esc_html__( 'No handle provided.', 'swis-performance' ) ) ) );
}
$output = '';
$status = '';
$action = sanitize_text_field( wp_unslash( $_POST['swis_slim_action'] ) );
$mode = '';
if ( ! empty( $_POST['swis_slim_exclusions'] ) && ! empty( $_POST['swis_slim_mode'] ) && 'all' === $_POST['swis_slim_mode'] && empty( $_POST['swis_slim_frontend'] ) ) {
die( wp_json_encode( array( 'error' => esc_html__( 'Please select an option.', 'swis-performance' ) ) ) );
}
if ( ! empty( $_POST['swis_slim_exclusions'] ) && empty( $_POST['swis_slim_mode'] ) && ! empty( $_POST['swis_slim_frontend'] ) ) {
die( wp_json_encode( array( 'error' => esc_html__( 'Please select an option.', 'swis-performance' ) ) ) );
}
if ( ! empty( $_POST['swis_slim_current_page'] ) ) {
$this->current_page = trim( sanitize_text_field( wp_unslash( $_POST['swis_slim_current_page'] ) ) );
}
if ( ! empty( $_POST['swis_slim_exclusions'] ) && ! empty( $_POST['swis_slim_mode'] ) ) {
if ( 'include' === $_POST['swis_slim_mode'] ) {
$mode = '+';
}
if ( 'exclude' === $_POST['swis_slim_mode'] ) {
$mode = '-';
}
}
$this->validate_user_exclusions();
$user_exclusions = $this->get_option( 'slim_js_css' );
switch ( $action ) {
case 'create':
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$exclusions = ! empty( $_POST['swis_slim_exclusions'] ) && $mode ? swis()->settings->sanitize_textarea_exclusions( wp_unslash( $_POST['swis_slim_exclusions'] ), false ) : false;
$handle = sanitize_text_field( wp_unslash( $_POST['swis_slim_handle'] ) );
$new_rule = ( $exclusions && ! empty( $exclusions[0] ) ? $mode . $exclusions[0] . ':' : '' ) . $handle;
if ( $this->is_iterable( $this->user_exclusions ) && isset( $this->user_exclusions[ $handle ] ) ) {
die( wp_json_encode( array( 'error' => esc_html__( 'A rule already exists for that handle, edit the existing rule or remove it before adding a new rule.', 'swis-performance' ) ) ) );
}
$this->debug_message( "adding $new_rule to:" );
if ( $this->function_exists( 'print_r' ) ) {
$this->debug_message( print_r( $user_exclusions, true ) );
}
if ( empty( $user_exclusions ) ) {
$this->debug_message( 'adding as only rule' );
$user_exclusions = array( $new_rule );
} elseif ( is_array( $user_exclusions ) && 1 === count( $user_exclusions ) && empty( $user_exclusions[0] ) ) {
$this->debug_message( 'adding as only rule (because the existing one is empty)' );
$user_exclusions = array( $new_rule );
} else {
$this->debug_message( 'adding to existing rules' );
$user_exclusions[] = $new_rule;
}
$this->debug_message( 'now slim exclusions are:' );
if ( $this->function_exists( 'print_r' ) ) {
$this->debug_message( print_r( $user_exclusions, true ) );
}
$result = $this->set_option( 'slim_js_css', $user_exclusions );
if ( ! $result ) {
die( wp_json_encode( array( 'error' => esc_html__( 'Unable to save rule.', 'swis-performance' ) ) ) );
}
$output = $this->get_rule_html( $handle, $this->parse_slim_rule( $new_rule ) );
$status = $this->asset_disabled( '', $handle ) ? "<span class='swis-slim-active-no'>" . esc_html__( 'No', 'swis-performance' ) . '</span>' : "<span class='swis-slim-active-yes'>" . esc_html__( 'Yes', 'swis-performance' ) . '</span>';
break;
case 'update':
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$exclusions = ! empty( $_POST['swis_slim_exclusions'] ) ? swis()->settings->sanitize_textarea_exclusions( wp_unslash( $_POST['swis_slim_exclusions'] ), false ) : false;
$handle = sanitize_text_field( wp_unslash( $_POST['swis_slim_handle'] ) );
$new_rule = ( $exclusions && ! empty( $exclusions[0] ) ? $mode . $exclusions[0] . ':' : '' ) . $handle;
if ( ! $this->is_iterable( $this->user_exclusions ) || ! isset( $this->user_exclusions[ $handle ] ) ) {
die(
wp_json_encode(
array(
'error' => sprintf(
/* translators: %s: registered handle for a JS/CSS resource */
esc_html__( 'Could not find a match for %s to update.', 'swis-performance' ),
esc_html( $handle )
),
)
)
);
}
foreach ( $user_exclusions as $index => $user_exclusion ) {
$parsed_rule = $this->parse_slim_rule( $user_exclusion );
if ( ! empty( $parsed_rule['handle'] ) && $handle === $parsed_rule['handle'] ) {
$user_exclusions[ $index ] = $new_rule;
}
}
$this->debug_message( print_r( $user_exclusions, true ) );
$this->set_option( 'slim_js_css', $user_exclusions );
$output = $this->get_rule_html( $handle, $this->parse_slim_rule( $new_rule ) );
$status = $this->asset_disabled( '', $handle ) ? "<span class='swis-slim-active-no'>" . esc_html__( 'No', 'swis-performance' ) . '</span>' : "<span class='swis-slim-active-yes'>" . esc_html__( 'Yes', 'swis-performance' ) . '</span>';
break;
case 'delete':
$handle = sanitize_text_field( wp_unslash( $_POST['swis_slim_handle'] ) );
if ( ! $this->is_iterable( $this->user_exclusions ) || ! isset( $this->user_exclusions[ $handle ] ) ) {
die(
wp_json_encode(
array(
'error' => sprintf(
/* translators: %s: registered handle for a JS/CSS resource */
esc_html__( 'Could not find a match for %s to remove.', 'swis-performance' ),
esc_html( $handle )
),
)
)
);
}
foreach ( $user_exclusions as $index => $user_exclusion ) {
$parsed_rule = $this->parse_slim_rule( $user_exclusion );
if ( ! empty( $parsed_rule['handle'] ) && $handle === $parsed_rule['handle'] ) {
unset( $user_exclusions[ $index ] );
}
}
$this->set_option( 'slim_js_css', $user_exclusions );
$output = $this->get_rule_html( $handle, array() );
$status = "<span class='swis-slim-active-yes'>" . esc_html__( 'Yes', 'swis-performance' ) . '</span>';
break;
default:
die( wp_json_encode( array( 'error' => esc_html__( 'Unknown operation requested.', 'swis-performance' ) ) ) );
}
die(
wp_json_encode(
array(
'success' => 1,
'message' => $output,
'status' => $status,
)
)
);
}
/**
* Retrieve the HTML for a given rule.
*
* @param string $handle The CSS/JS handle.
* @param array $rule Exclusions and inclusions for the given $handle.
* @return string The HTML produced for Slim rule.
*/
private function get_rule_html( $handle, $rule ) {
ob_start();
// Nonce verification has already happened before we get here.
if ( empty( $_POST['swis_slim_frontend'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
if ( empty( $rule ) ) {
return '';
}
$this->display_backend_rule( $handle, $rule );
} else {
$this->display_frontend_rule_form( $handle, $rule );
}
return trim( ob_get_clean() );
}
/**
* Display the HTML for a given rule on the settings.
*
* @param string $handle The CSS/JS handle.
* @param array $rule Exclusions and inclusions for the given $handle.
*/
private function display_backend_rule( $handle, $rule ) {
$rule_id = preg_replace( '/[\W_]/', '', uniqid( '', true ) );
?>
<div id="swis-slim-rule-<?php echo esc_attr( $rule_id ); ?>" class="swis-slim-rule" data-slim-handle="<?php echo esc_attr( $handle ); ?>" data-slim-rule-id="<?php echo esc_attr( $rule_id ); ?>">
<?php if ( $rule['include'] ) : ?>
<?php
$includes = array();
foreach ( $rule['include'] as $include ) {
if ( 0 === strpos( $include, 'T>' ) ) {
$includes[] = '<i>' . substr( $include, 2 ) . '</i> ' . esc_html__( 'content type', 'swis-performance' );
} elseif ( '<home_page>' === $include ) {
$includes[] = esc_html__( 'home page', 'swis-performance' );
} else {
$includes[] = $include;
}
}
$raw_rule_parts = explode( ':', $rule['raw'] );
$raw_rule_html = ltrim( $raw_rule_parts[0], '+-' );
?>
<div class="swis-slim-rule-description">
<?php /* translators: %s: registered handle for a JS/CSS resource */ ?>
<?php printf( esc_html__( '%s disabled everywhere except:', 'swis-performance' ), '<strong>' . esc_html( $handle ) . '</strong>' ); ?>
<input style="display:none;" type="radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="include" checked />
<div class="swis-slim-pretty-rule">
<?php echo wp_kses_post( implode( ', ', $includes ) ); ?>
</div>
<div class="swis-slim-error-message"></div>
<div class="swis-slim-hidden">
<div class="swis-slim-raw-rule">
<input type="text" name="swis-slim-rule-exclusions-<?php echo esc_attr( $rule_id ); ?>" value="<?php echo esc_attr( $raw_rule_html ); ?>" />
<button type="button" class="button-primary swis-slim-rule-save"><?php esc_html_e( 'Save', 'swis-performance' ); ?></button>
</div>
<p class="swis-slim-edit-rule-description description">
<?php esc_html_e( 'Enter a comma-separated list of pages, URL patterns (use * as wildcard), or content types in the form T>post or T>page.', 'swis-performance' ); ?>
</p>
</div>
</div>
<div class="swis-slim-rule-actions">
<button type="button" class="button-link button-link-edit"><?php esc_html_e( 'Edit', 'swis-performance' ); ?></button>
|
<button type="button" class="button-link button-link-delete"><?php esc_html_e( 'Delete', 'swis-performance' ); ?></button>
</div>
<?php elseif ( $rule['exclude'] ) : ?>
<?php
$excludes = array();
foreach ( $rule['exclude'] as $exclude ) {
if ( 0 === strpos( $exclude, 'T>' ) ) {
$excludes[] = '<i>' . substr( $exclude, 2 ) . '</i> ' . esc_html__( 'content type', 'swis-performance' );
} elseif ( '<home_page>' === $exclude ) {
$excludes[] = esc_html__( 'home page', 'swis-performance' );
} else {
$excludes[] = $exclude;
}
}
$raw_rule_parts = explode( ':', $rule['raw'] );
$raw_rule_html = ltrim( $raw_rule_parts[0], '+-' );
?>
<div class="swis-slim-rule-description">
<?php /* translators: %s: A JS/CSS handle, like 'jquery-form' */ ?>
<?php printf( esc_html__( '%s disabled on:', 'swis-performance' ), '<strong>' . esc_html( $handle ) . '</strong>' ); ?><br>
<input style="display:none;" type="radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="exclude" checked />
<div class="swis-slim-pretty-rule">
<?php echo wp_kses_post( implode( ', ', $excludes ) ); ?>
</div>
<div class="swis-slim-error-message"></div>
<div class="swis-slim-hidden">
<div class="swis-slim-raw-rule">
<input type="text" name="swis-slim-rule-exclusions-<?php echo esc_attr( $rule_id ); ?>" value="<?php echo esc_attr( $raw_rule_html ); ?>" />
<button type="button" class="button-primary swis-slim-rule-save"><?php esc_html_e( 'Save', 'swis-performance' ); ?></button>
</div>
<p class="swis-slim-edit-rule-description description">
<?php esc_html_e( 'Enter a comma-separated list of pages, URL patterns (use * as wildcard), or content types in the form T>post or T>page.', 'swis-performance' ); ?>
</p>
</div>
</div>
<div class="swis-slim-rule-actions">
<button type="button" class="button-link button-link-edit"><?php esc_html_e( 'Edit', 'swis-performance' ); ?></button>
|
<button type="button" class="button-link button-link-delete"><?php esc_html_e( 'Delete', 'swis-performance' ); ?></button>
</div>
<?php else : ?>
<div class="swis-slim-rule-description">
<?php /* translators: %s: A JS/CSS handle, like 'jquery-form' */ ?>
<?php printf( esc_html__( '%s disabled everywhere', 'swis-performance' ), '<strong>' . esc_html( $handle ) . '</strong>' ); ?>
<input style="display:none;" type="radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="all" checked />
<div class="swis-slim-error-message"></div>
<div class="swis-slim-hidden">
<div class="swis-slim-column">
<div class="swis-slim-row">
<input type="radio" id="swis_slim_mode_include_<?php echo esc_attr( $rule_id ); ?>" class="swis-slim-radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="include" />
<strong><label for="swis_slim_mode_include_<?php echo esc_attr( $rule_id ); ?>"><?php esc_html_e( 'disable everywhere except:', 'swis-performance' ); ?></label></strong>
</div>
<div class="swis-slim-row">
<input type="radio" id="swis_slim_mode_exclude_<?php echo esc_attr( $rule_id ); ?>" class="swis-slim-radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="exclude" />
<strong><label for="swis_slim_mode_exclude_<?php echo esc_attr( $rule_id ); ?>"><?php esc_html_e( 'disable on:', 'swis-performance' ); ?></label></strong>
</div>
<div class="swis-slim-raw-rule">
<input type="text" name="swis-slim-rule-exclusions-<?php echo esc_attr( $rule_id ); ?>" value="" />
<button type="button" class="button-primary swis-slim-rule-save"><?php esc_html_e( 'Save', 'swis-performance' ); ?></button>
</div>
<p class="swis-slim-edit-rule-description description">
<?php esc_html_e( 'Enter a comma-separated list of pages, URL patterns (use * as wildcard), or content types in the form T>post or T>page.', 'swis-performance' ); ?>
</p>
</div>
</div>
</div>
<div class="swis-slim-rule-actions">
<button type="button" class="button-link button-link-edit"><?php esc_html_e( 'Add Exclusion', 'swis-performance' ); ?></button>
|
<button type="button" class="button-link button-link-delete"><?php esc_html_e( 'Delete', 'swis-performance' ); ?></button>
</div>
<?php endif; ?>
</div>
<?php
}
/**
* Display existing rules on the settings.
*/
public function display_backend_rules() {
$this->validate_user_exclusions();
if ( empty( $this->user_exclusions ) ) {
return;
}
foreach ( $this->user_exclusions as $handle => $rule ) {
$this->display_backend_rule( $handle, $rule );
}
}
/**
* Add more exclusions from third-party code.
*
* @param string $rule A handle or rule using our SLIM syntax.
*/
public function add_exclusion( $rule ) {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
if ( is_string( $rule ) ) {
$this->parse_slim_rule( $rule );
}
}
/**
* Validate the user-defined rules.
*/
function validate_user_exclusions() {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
$user_exclusions = $this->get_option( 'slim_js_css' );
if ( ! empty( $user_exclusions ) ) {
if ( is_string( $user_exclusions ) ) {
$user_exclusions = array( $user_exclusions );
}
if ( is_array( $user_exclusions ) ) {
foreach ( $user_exclusions as $exclusion ) {
if ( ! is_string( $exclusion ) ) {
continue;
}
$this->parse_slim_rule( $exclusion );
}
}
}
}
/**
* Parse a user-supplied slim rule into an array and append to $this->user_exclusions.
*
* @param string $rule The user-supplied rule.
* @return array The parsed array-style version of the rule.
*/
function parse_slim_rule( $rule ) {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
if ( ! $this->home_path ) {
$this->home_path = $this->parse_url( trailingslashit( get_home_url() ), PHP_URL_PATH );
$this->debug_message( 'the home path to match is ' . $this->home_path );
}
$rule = trim( str_replace( '\\', '/', $rule ) );
$raw = $rule;
if ( 0 === strpos( $rule, '+' ) || 0 === strpos( $rule, '-' ) ) {
$type = substr( $rule, 0, 1 );
$rule = ltrim( $rule, '+' );
$rule = ltrim( $rule, '-' );
if ( strpos( $rule, ':' ) ) {
$parts = explode( ':', $rule );
if ( empty( $parts[0] ) || empty( $parts[1] ) ) {
return;
}
$handle = $parts[1];
$except = explode( ',', $parts[0] );
if ( $this->is_iterable( $except ) ) {
foreach ( $except as $key => $page ) {
$this->debug_message( "comparing $page to home_path" );
if ( $page === $this->home_path ) {
$except[ $key ] = '<home_page>';
}
}
}
$this->user_exclusions[ $handle ] = array(
'handle' => $handle,
'include' => '-' !== $type ? $except : array(),
'exclude' => '-' === $type ? $except : array(),
'raw' => $raw,
);
return $this->user_exclusions[ $handle ];
}
} elseif ( false === strpos( $rule, ':' ) ) {
// Found an "exclude everywhere" rule.
$this->user_exclusions[ $rule ] = array(
'handle' => $rule,
'include' => array(),
'exclude' => array(),
/* translators: %s: A JS/CSS handle, like 'jquery-form' */
'raw' => sprintf( __( '%s disabled everywhere', 'swis-performance' ), $rule ),
);
return $this->user_exclusions[ $rule ];
}
}
/**
* Check if an asset is from an external site.
*
* @param string $url The asset URL.
* @return bool True for external asset, false for local asset.
*/
function is_external( $url ) {
if ( 0 === strpos( $url, '/' ) && 0 !== strpos( $url, '//' ) ) {
return false;
}
$asset_url_parts = $this->parse_url( $url );
$local_url_parts = $this->parse_url( get_site_url() );
if ( ! empty( $asset_url_parts['host'] ) && ! empty( $local_url_parts['host'] ) && 0 === strcasecmp( $asset_url_parts['host'], $local_url_parts['host'] ) ) {
return false;
}
return true;
}
/**
* Check size of asset.
*
* @param string $url The asset URL.
* @return string A human-readable size.
*/
function get_asset_size( $url ) {
$size = '';
$url_bits = explode( '?', $url );
$asset_path = ABSPATH . str_replace( get_site_url(), '', $this->prepend_url_scheme( $url_bits[0] ) );
if ( $url !== $asset_path && is_file( $asset_path ) ) {
$size = size_format( filesize( $asset_path ), 1 );
}
return $size;
}
/**
* Check to see which JS/CSS files have been registered for the current page.
*/
function find_assets() {
if ( ! $this->is_frontend() ) {
return;
}
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
$assets = array(
'js' => wp_scripts(),
'css' => wp_styles(),
);
$core_url = ! empty( $assets['js']->default_dirs[1] ) ? dirname( $assets['js']->default_dirs[1] ) : dirname( $assets['js']->default_dirs[0] );
$plugins_url = plugins_url();
$theme_url = get_theme_root_uri();
$this->debug_message( $core_url );
$this->debug_message( $plugins_url );
$this->debug_message( $theme_url );
foreach ( $assets as $type => $data ) {
foreach ( $data->done as $handle ) {
if ( ! in_array( $handle, $this->whitelist, true ) && ! empty( $data->registered[ $handle ] ) ) {
$url = $this->prepend_url_scheme( $data->registered[ $handle ]->src );
if ( false !== strpos( $url, $plugins_url ) ) {
$asset_source_type = 'plugins';
// Get the plugin folder name.
$plugin_path = ltrim( str_replace( $plugins_url, '', $url ), '/' );
$plugin_path = explode( '/', $plugin_path );
$plugin_dir = $plugin_path[0];
} elseif ( false !== strpos( $url, $theme_url ) ) {
$asset_source_type = 'theme';
} elseif ( false !== strpos( $url, $core_url ) || 'jquery' === $handle ) {
$asset_source_type = 'core';
} else {
$asset_source_type = 'misc';
}
$url_info = pathinfo( $url );
$asset = array(
'url' => $url,
'external' => (int) $this->is_external( $url ),
'filename' => ! empty( $url_info['basename'] ) ? $url_info['basename'] : $url,
'size' => $this->get_asset_size( $url ),
'disabled' => (int) $this->asset_disabled( $type, $handle ),
'deps' => isset( $data->registered[ $handle ]->deps ) ? $data->registered[ $handle ]->deps : array(),
);
if ( 'plugins' === $asset_source_type ) {
$this->assets[ $asset_source_type ][ $plugin_dir ][ $type ][ $handle ] = $asset;
} else {
$this->assets[ $asset_source_type ][ $type ][ $handle ] = $asset;
}
$this->deps[] = array(
'name' => $handle,
'deps' => $asset['deps'],
'type' => $type,
);
}
}
}
global $wp_version;
if ( version_compare( $wp_version, '4.2', '>=' ) ) {
$url = '/wp-includes/js/wp-emoji-release.min.js';
$this->assets['core']['js']['wp-emoji'] = array(
'url' => $url,
'external' => false,
'filename' => 'wp-emoji-release.min.js',
'size' => $this->get_asset_size( $url ),
'disabled' => (int) $this->asset_disabled( 'js', 'wp-emoji' ),
'deps' => array(),
);
}
}
/**
* Make sure protocol-relative URLs like //www.example.com/wp-includes/script.js get a scheme added.
*
* @param string $url The URL to potentially fix.
* @return string The properly-schemed URL.
*/
function prepend_url_scheme( $url ) {
if ( 0 === strpos( $url, '//' ) ) {
return ( is_ssl() ? 'https:' : 'http' ) . $url;
}
return $url;
}
/**
* Get registered content types.
*/
function get_content_types() {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
$this->content_types = get_post_types( array( 'public' => true ) );
}
/**
* Check the content type of the current page.
*/
function get_content_type() {
if ( is_singular() ) {
$this->content_type = get_post_type();
}
}
/**
* See if the current content type matches a content type rule.
*
* @param string $rule A content-type rule (prefixed with T>).
* @return bool True if the current type matches the rule, false otherwise.
*/
function check_content_type( $rule ) {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
if ( 0 === strpos( $rule, 'T>' ) ) {
$rule_content_type = substr( $rule, 2 );
$this->debug_message( "found rule content type: $rule_content_type" );
if ( $rule_content_type === $this->content_type ) {
return true;
}
}
return false;
}
/**
* Check if the user has disabled an asset for this particular page.
*
* @param string $type The type of asset: 'js' or 'css'.
* @param string $handle The handle/slug of the asset.
* @return bool True to suppress the asset for the current page, false otherwise.
*/
function asset_disabled( $type, $handle ) {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
$uri = $this->parse_url( add_query_arg( null, null ), PHP_URL_PATH );
if ( wp_doing_ajax() && ! empty( $_POST['swis_slim_frontend'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
if ( $this->current_page !== $uri ) {
$uri = $this->current_page;
}
}
$this->debug_message( "request uri is $uri" );
if ( 'jquery-migrate' === $handle && ! isset( $this->user_exclusions[ $handle ] ) && isset( $this->user_exclusions['jquery-core'] ) ) {
$this->debug_message( "using jquery-core exclusions for $handle" );
return $this->asset_disabled( $type, 'jquery-core' );
}
if ( 'jquery-core' === $handle && ! isset( $this->user_exclusions[ $handle ] ) && isset( $this->user_exclusions['jquery'] ) ) {
$this->debug_message( "using jquery exclusions for $handle" );
return $this->asset_disabled( $type, 'jquery' );
}
if ( isset( $this->user_exclusions[ $handle ] ) ) {
if ( empty( $this->user_exclusions[ $handle ]['include'] ) && empty( $this->user_exclusions[ $handle ]['exclude'] ) ) {
$this->debug_message( "site-wide rule triggered for $handle" );
return true;
}
if ( ! empty( $this->user_exclusions[ $handle ]['include'] ) ) {
foreach ( $this->user_exclusions[ $handle ]['include'] as $include ) {
if ( $this->check_content_type( $include ) ) {
$this->debug_message( "content-include rule triggered for $handle" );
return false;
}
if ( '<home_page>' === $include && $uri === $this->home_path ) {
$this->debug_message( "home page include rule triggered for $handle" );
return false;
}
if ( false !== strpos( $include, '*' ) && false === strpos( $include, '#' ) && preg_match( "#$include#", $uri ) ) {
$this->debug_message( "pattern-include ($include) rule triggered for $handle" );
return false;
} elseif ( $uri === $include ) {
$this->debug_message( "page-include ($include) rule triggered for $handle" );
return false;
}
}
return true;
}
if ( ! empty( $this->user_exclusions[ $handle ]['exclude'] ) ) {
foreach ( $this->user_exclusions[ $handle ]['exclude'] as $exclude ) {
if ( $this->check_content_type( $exclude ) ) {
$this->debug_message( "content-exclude rule triggered for $handle" );
return true;
}
if ( '<home_page>' === $exclude && $uri === $this->home_path ) {
$this->debug_message( "home page exclude rule triggered for $handle" );
return true;
}
if ( false !== strpos( $exclude, '*' ) && false === strpos( $exclude, '#' ) && preg_match( "#$exclude#", $uri ) ) {
$this->debug_message( "pattern-exclude ($exclude) rule triggered for $handle" );
return true;
} elseif ( $uri === $exclude ) {
$this->debug_message( "page-exclude ($exclude) rule triggered for $handle" );
return true;
}
}
}
}
$this->debug_message( "no rules matched for $handle" );
return false;
}
/**
* Remove JS/CSS files if the user has disabled them.
*
* @param string $url The address of the resource.
* @param string $handle The registered handle for the resource.
*/
function disable_assets( $url, $handle ) {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
$this->debug_message( "checking $url" );
$type = current_filter() === 'script_loader_src' ? 'js' : 'css';
if (
'jquery-core' === $handle &&
$this->is_frontend() &&
is_user_logged_in() &&
current_user_can( 'manage_options' ) &&
! defined( 'SWIS_SLIM_DISABLE_FRONTEND_MENU' )
) {
return $url;
}
return $this->asset_disabled( $type, $handle ) ? false : $url;
}
/**
* Disable emoji JS/CSS based on user preference.
*/
function maybe_remove_emoji() {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
if ( $this->asset_disabled( 'js', 'wp-emoji' ) ) {
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
}
}
/**
* Check to see if Emoji is enqueued.
*
* @return bool True if it is, false if it ain't.
*/
function is_emoji_active() {
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
return (bool) has_action( 'wp_head', 'print_emoji_detection_script' );
}
/**
* Get a list of dependent assets for any given asset.
*
* @param string $handle The asset handle/slug.
* @param string $type The asset type (js/css).
* @return array A list assets that depend on the $handle asset.
*/
function get_dependents( $handle, $type ) {
$dependents = array();
foreach ( $this->deps as $asset ) {
if ( in_array( $handle, $asset['deps'], true ) && $type === $asset['type'] && 'jquery' !== $asset['name'] ) {
$dependents[] = $asset['name'];
}
}
if ( 'jquery-core' === $handle && empty( $dependents ) ) {
return $this->get_dependents( 'jquery', 'js' );
}
if ( 'jquery-migrate' === $handle && empty( $dependents ) ) {
return $this->get_dependents( 'jquery', 'js' );
}
return $dependents;
}
/**
* Display a list of discovered JS/CSS files for the current page.
*/
function display_assets() {
if ( ! $this->is_frontend() ) {
return;
}
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
echo "<div id='swis-slim-assets-pane' class='swis-slim-hidden'>\n";
$this->get_content_types();
$this->sample_type = $this->get_content_type();
$this->current_page = $this->parse_url( add_query_arg( null, null ), PHP_URL_PATH );
$this->sample_page = '/example-page/';
$posts = get_posts( 'post_type=page&numberposts=1&fields=ids' );
if ( ! empty( $posts[0] ) ) {
$potential_sample = str_replace( get_home_url(), '', get_permalink( $posts[0] ) );
if ( ! empty( $potential_sample ) && false === strpos( $potential_sample, 'http' ) && $this->current_page !== $potential_sample ) {
$this->sample_page = $potential_sample;
}
}
if ( ! empty( $this->assets['core'] ) ) {
?>
<button id='swis-slim-close-pane' class="button-secondary">Hide JS/CSS</button>
<h1>
SWIS Performance
<?php $this->help_link( 'https://docs.ewww.io/article/97-disabling-unused-css-and-js' ); ?>
</h1>
<div style="display:none;" id="swis-slim-current-page"><?php echo esc_html( $this->current_page ); ?></div>
<ul>
<li><?php esc_html_e( 'Note that the list of CSS/JS file may be different on each page.', 'swis-performance' ); ?></li>
<li><?php esc_html_e( 'Always test your pages after each change.', 'swis-performance' ); ?></li>
<li><?php esc_html_e( 'Then, if something breaks, undo it by removing the last rule you added.', 'swis-performance' ); ?></li>
</ul>
<h2>
<?php esc_html_e( 'Core', 'swis-performance' ); ?>
</h2>
<table class='swis-slim-assets'>
<tr>
<th class='swis-slim-asset-active'><?php esc_html_e( 'Active', 'swis-performance' ); ?></th>
<th class='swis-slim-asset-details'><?php esc_html_e( 'Asset Details', 'swis-performance' ); ?></th>
<th class='swis-slim-asset-size'><?php esc_html_e( 'Size', 'swis-performance' ); ?></th>
</tr>
<?php
foreach ( $this->assets['core'] as $asset_type => $data ) {
foreach ( $data as $handle => $asset ) {
$this->display_asset_info( $handle, $asset, $asset_type );
}
}
?>
</table>
<?php
}
if ( ! empty( $this->assets['plugins'] ) ) {
?>
<h2>
<?php esc_html_e( 'Plugins', 'swis-performance' ); ?>
</h2>
<table class='swis-slim-assets'>
<tr>
<th class='swis-slim-asset-active'><?php esc_html_e( 'Active', 'swis-performance' ); ?></th>
<th class='swis-slim-asset-details'><?php esc_html_e( 'Asset Details', 'swis-performance' ); ?></th>
<th class='swis-slim-asset-size'><?php esc_html_e( 'Size', 'swis-performance' ); ?></th>
</tr>
<?php
foreach ( $this->assets['plugins'] as $plugin => $asset_types ) {
foreach ( $asset_types as $asset_type => $data ) {
foreach ( $data as $handle => $asset ) {
$this->display_asset_info( $handle, $asset, $asset_type );
}
}
}
?>
</table>
<?php
}
if ( ! empty( $this->assets['theme'] ) ) {
?>
<h2>
<?php esc_html_e( 'Theme', 'swis-performance' ); ?>
</h2>
<table class='swis-slim-assets'>
<tr>
<th class='swis-slim-asset-active'><?php esc_html_e( 'Active', 'swis-performance' ); ?></th>
<th class='swis-slim-asset-details'><?php esc_html_e( 'Asset Details', 'swis-performance' ); ?></th>
<th class='swis-slim-asset-size'><?php esc_html_e( 'Size', 'swis-performance' ); ?></th>
</tr>
<?php
foreach ( $this->assets['theme'] as $asset_type => $data ) {
foreach ( $data as $handle => $asset ) {
$this->display_asset_info( $handle, $asset, $asset_type );
}
}
?>
</table>
<?php
}
if ( ! empty( $this->assets['misc'] ) ) {
?>
<h2>
<?php esc_html_e( 'Miscellaneous', 'swis-performance' ); ?>
</h2>
<table class='swis-slim-assets'>
<tr>
<th class='swis-slim-asset-active'><?php esc_html_e( 'Active', 'swis-performance' ); ?></th>
<th class='swis-slim-asset-details'><?php esc_html_e( 'Asset Details', 'swis-performance' ); ?></th>
<th class='swis-slim-asset-size'><?php esc_html_e( 'Size', 'swis-performance' ); ?></th>
</tr>
<?php
foreach ( $this->assets['misc'] as $asset_type => $data ) {
foreach ( $data as $handle => $asset ) {
$this->display_asset_info( $handle, $asset, $asset_type );
}
}
?>
</table>
<?php
}
echo "</div>\n";
}
/**
* Display the table row for a particular asset.
*
* @param string $handle The asset handle.
* @param array $asset The asset information.
* @param string $type The asset type (js/css).
*/
function display_asset_info( $handle, $asset, $type ) {
$dependents = $this->get_dependents( $handle, $type );
if ( 'yoast-seo-adminbar' === $handle ) {
return;
}
if ( 'jquery-core' === $handle && empty( $dependents ) ) {
return;
}
if ( 'jquery-migrate' === $handle && empty( $dependents ) ) {
$jquery_dependents = $this->get_dependents( 'jquery-core', 'js' );
if ( empty( $dependents ) ) {
return;
}
}
if ( 'jquery' === $handle ) {
return;
}
if ( 0 === strpos( $asset['url'], '/' ) && 0 !== strpos( $asset['url'], '//' ) ) {
$asset['url'] = get_site_url() . $asset['url'];
}
$rule = isset( $this->user_exclusions[ $handle ] ) ? $this->user_exclusions[ $handle ] : array();
?>
<tr>
<td class="swis-slim-asset-status">
<?php echo $asset['disabled'] ? "<span class='swis-slim-active-no'>" . esc_html__( 'No', 'swis-performance' ) . '</span>' : "<span class='swis-slim-active-yes'>" . esc_html__( 'Yes', 'swis-performance' ) . '</span>'; ?>
</td>
<td>
<a class='swis-slim-link' href='<?php echo esc_url( $asset['url'] ); ?>' target='_blank'>
<?php echo $asset['external'] ? esc_html( $asset['url'] ) : esc_html( $asset['filename'] ); ?>
</a>
<div class='swis-slim-info'>
<div><?php echo '<strong>' . esc_html__( 'Handle:', 'swis-performance' ) . '</strong> ' . esc_html( $handle ); ?></div>
<?php if ( ! empty( $asset['deps'] ) ) : ?>
<div><?php echo '<strong>' . esc_html__( 'Requires:', 'swis-performance' ) . '</strong> ' . esc_html( implode( ', ', $asset['deps'] ) ); ?></div>
<?php endif; ?>
<?php if ( ! empty( $dependents ) ) : ?>
<div><?php echo '<strong>' . esc_html__( 'Required by:', 'swis-performance' ) . '</strong> ' . esc_html( implode( ', ', $dependents ) ); ?></div>
<?php endif; ?>
<?php $this->display_frontend_rule_form( $handle, $rule, $asset ); ?>
<?php if ( isset( $this->user_exclusions[ $handle ]['raw'] ) ) : ?>
<!-- <div>
<strong><?php echo esc_html__( 'Active rule:', 'swis-performance' ); ?></strong>
<?php echo esc_html( $this->user_exclusions[ $handle ]['raw'] ); ?>
</div> -->
<?php endif; ?>
<!-- <div class='swis-sample-rules'>
<strong><?php echo esc_html_e( 'Sample Rules:', 'swis-performance' ); ?></strong><br>
<?php echo esc_html__( 'Load on current page only:', 'swis-performance' ) . ' +' . esc_html( $this->current_page ) . ':' . esc_html( $handle ); ?><br>
<?php echo esc_html__( 'Disable on current page only:', 'swis-performance' ) . ' -' . esc_html( $this->current_page ) . ':' . esc_html( $handle ); ?><br>
<?php echo esc_html__( 'Disable everywhere:', 'swis-performance' ) . ' ' . esc_html( $handle ); ?><br>
<?php echo esc_html__( 'Separate multiple pages with commas:', 'swis-performance' ) . ' +' . esc_html( $this->current_page ) . ',' . esc_html( $this->sample_page ) . ':' . esc_html( $handle ); ?><br>
</div> -->
</div>
</td>
<td>
<?php echo esc_html( $asset['size'] ); ?>
</td>
</tr>
<?php
}
/**
* Display the HTML for a given rule on the settings.
*
* @param string $handle The CSS/JS handle.
* @param array $rule Parsed rule for the given $handle.
* @param array $asset Asset info for the given $handle.
*/
private function display_frontend_rule_form( $handle, $rule, $asset = array() ) {
$rule_id = preg_replace( '/[\W_]/', '', uniqid( '', true ) );
if ( empty( $asset ) ) {
$asset['disabled'] = $this->asset_disabled( '', $handle );
}
?>
<form class="swis-slim-rule" data-slim-handle="<?php echo esc_attr( $handle ); ?>" data-slim-rule-id="<?php echo esc_attr( $rule_id ); ?>">
<?php if ( ! empty( $rule['include'] ) ) : ?>
<?php
$includes = array();
foreach ( $rule['include'] as $include ) {
if ( 0 === strpos( $include, 'T>' ) ) {
$includes[] = '<i>' . substr( $include, 2 ) . '</i> ' . esc_html__( 'content type', 'swis-performance' );
} elseif ( '<home_page>' === $include ) {
$includes[] = esc_html__( 'home page', 'swis-performance' );
} else {
$includes[] = $include;
}
}
$raw_rule_parts = explode( ':', $rule['raw'] );
$raw_rule_html = ltrim( $raw_rule_parts[0], '+-' );
?>
<div class="swis-slim-rule-description">
<div class="swis-slim-rule-prefix">
<?php esc_html_e( 'Disabled everywhere except:', 'swis-performance' ); ?>
</div>
<input style="display:none;" type="radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="include" checked />
<div class="swis-slim-pretty-rule">
<?php echo wp_kses_post( implode( ', ', $includes ) ); ?>
</div>
<div class="swis-slim-error-message"></div>
<div class="swis-slim-hidden">
<div class="swis-slim-raw-rule">
<input type="text" name="swis-slim-rule-exclusions-<?php echo esc_attr( $rule_id ); ?>" value="<?php echo esc_attr( $raw_rule_html . ( $asset['disabled'] ? ',' . $this->current_page : '' ) ); ?>" />
</div>
<p class="swis-slim-edit-rule-description description">
<?php esc_html_e( 'Enter a comma-separated list of pages, URL patterns (use * as wildcard), or content types in the form T>post or T>page.', 'swis-performance' ); ?>
<button type="button" class="button-primary swis-slim-rule-save"><?php esc_html_e( 'Save', 'swis-performance' ); ?></button>
</p>
</div>
</div>
<div class="swis-slim-rule-actions">
<button type="button" class="button-secondary button-link-edit"><?php ( $asset['disabled'] ? esc_html_e( 'Add', 'swis-performance' ) : esc_html_e( 'Edit', 'swis-performance' ) ); ?></button>
<button type="button" class="button-danger button-link-delete"><?php esc_html_e( 'Delete', 'swis-performance' ); ?></button>
</div>
<?php elseif ( ! empty( $rule['exclude'] ) ) : ?>
<?php
$excludes = array();
foreach ( $rule['exclude'] as $exclude ) {
if ( 0 === strpos( $exclude, 'T>' ) ) {
$excludes[] = '<i>' . substr( $exclude, 2 ) . '</i> ' . esc_html__( 'content type', 'swis-performance' );
} elseif ( '<home_page>' === $exclude ) {
$excludes[] = esc_html__( 'home page', 'swis-performance' );
} else {
$excludes[] = $exclude;
}
}
$raw_rule_parts = explode( ':', $rule['raw'] );
$raw_rule_html = ltrim( $raw_rule_parts[0], '+-' );
?>
<div class="swis-slim-rule-description">
<div class="swis-slim-rule-prefix">
<?php esc_html_e( 'Disabled on:', 'swis-performance' ); ?>
</div>
<input style="display:none;" type="radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="exclude" checked />
<div class="swis-slim-pretty-rule">
<?php echo wp_kses_post( implode( ', ', $excludes ) ); ?>
</div>
<div class="swis-slim-error-message"></div>
<div class="swis-slim-hidden">
<div class="swis-slim-raw-rule">
<input type="text" name="swis-slim-rule-exclusions-<?php echo esc_attr( $rule_id ); ?>" value="<?php echo esc_attr( $raw_rule_html . ( $asset['disabled'] ? '' : ',' . $this->current_page ) ); ?>" />
</div>
<p class="swis-slim-edit-rule-description description">
<?php esc_html_e( 'Enter a comma-separated list of pages, URL patterns (use * as wildcard), or content types in the form T>post or T>page.', 'swis-performance' ); ?>
<button type="button" class="button-primary swis-slim-rule-save"><?php esc_html_e( 'Save', 'swis-performance' ); ?></button>
</p>
</div>
</div>
<div class="swis-slim-rule-actions">
<button type="button" class="button-secondary button-link-edit"><?php ( $asset['disabled'] ? esc_html_e( 'Edit', 'swis-performance' ) : esc_html_e( 'Add', 'swis-performance' ) ); ?></button>
<button type="button" class="button-danger button-link-delete"><?php esc_html_e( 'Delete', 'swis-performance' ); ?></button>
</div>
<?php elseif ( ! empty( $rule['raw'] ) ) : ?>
<div class="swis-slim-rule-description">
<div class="swis-slim-rule-prefix">
<?php esc_html_e( 'Disabled everywhere', 'swis-performance' ); ?>
</div>
<input style="display:none;" type="radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="all" checked />
<div class="swis-slim-error-message"></div>
</div>
<div class="swis-slim-rule-actions">
<button type="button" class="button-danger button-link-delete"><?php esc_html_e( 'Delete', 'swis-performance' ); ?></button>
</div>
<?php else : ?>
<div class="swis-slim-rule-description swis-slim-column">
<?php if ( 'jquery-migrate' === $handle && ! empty( $this->user_exclusions['jquery-core'] ) ) : ?>
<?php esc_html_e( 'Rules for jquery/jquery-core will automatically apply to jquery-migrate.', 'swis-performance' ); ?>
<?php endif; ?>
<div class="swis-slim-error-message"></div>
<div class="swis-slim-row">
<div class="swis-slim-reversible">
<div class="swis-slim-row">
<input type="radio" id="swis_slim_mode_exclude_<?php echo esc_attr( $rule_id ); ?>" class="swis-slim-radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="exclude" />
<strong><label for="swis_slim_mode_exclude_<?php echo esc_attr( $rule_id ); ?>"><?php esc_html_e( 'disable on this page', 'swis-performance' ); ?></label></strong>
</div>
<div class="swis-slim-row">
<input type="radio" id="swis_slim_mode_include_<?php echo esc_attr( $rule_id ); ?>" class="swis-slim-radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="include" />
<strong><label for="swis_slim_mode_include_<?php echo esc_attr( $rule_id ); ?>"><?php esc_html_e( 'disable everywhere except this page', 'swis-performance' ); ?></label></strong>
</div>
<div class="swis-slim-row">
<input type="radio" id="swis_slim_mode_all_<?php echo esc_attr( $rule_id ); ?>" class="swis-slim-radio" name="swis_slim_mode_<?php echo esc_attr( $rule_id ); ?>" value="all" />
<strong><label for="swis_slim_mode_all_<?php echo esc_attr( $rule_id ); ?>"><?php esc_html_e( 'disable everywhere', 'swis-performance' ); ?></label></strong>
</div>
</div>
<div class="swis-slim-rule-actions">
<button type="button" class="button-secondary swis-slim-rule-customize"><?php esc_html_e( 'Customize Rule', 'swis-performance' ); ?></button>
<button type="button" class="button-primary swis-slim-rule-add"><?php esc_html_e( 'Add Rule', 'swis-performance' ); ?></button>
</div>
</div>
<div class="swis-slim-column swis-slim-raw-rule">
<input style="display:none;" type="text" name="swis-slim-rule-exclusions-<?php echo esc_attr( $rule_id ); ?>" value="<?php echo esc_attr( $this->current_page ); ?>" />
<label style="display:none;" for="swis-slim-rule-exclusions-<?php echo esc_attr( $rule_id ); ?>">
<?php esc_html_e( 'Comma-separated list of pages, URL patterns (use * as wildcard), or content types in the form T>post or T>page.', 'swis-performance' ); ?>
</label>
</div>
</div>
<?php endif; ?>
</form>
<?php
}
}