Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closes #7058: Implement DJE Safe Mode Feature #7081

Open
wants to merge 20 commits into
base: feature/3.18
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion assets/js/wpr-admin.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/js/wpr-admin.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/js/wpr-admin.min.js.map

Large diffs are not rendered by default.

37 changes: 30 additions & 7 deletions inc/Engine/Admin/Settings/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -512,9 +512,7 @@ private function assets_section() {
]
);

$delay_js_list_helper = esc_html__( 'If you have problems after activating this option, copy and paste the default exclusions to quickly resolve issues:', 'rocket' );
$delay_js_list_helper .= sprintf( '<br><pre><code>%1$s</code></pre><br>', implode( '<br>', DelayJSSettings::get_delay_js_default_exclusions() ) );
$delay_js_list_helper .= sprintf(
$delay_js_list_helper = sprintf(
// translators: %1$s = opening </a> tag, %2$s = closing </a> tag.
esc_html__( 'Also, please check our %1$sdocumentation%2$s for a list of compatibility exclusions.', 'rocket' ),
'<a href="' . esc_url( $delay_js_exclusions_beacon['url'] ) . '" target="_blank" rel="noopener">',
Expand Down Expand Up @@ -792,13 +790,38 @@ private function assets_section() {
],
'items' => $this->delayjs_sitelist->prepare_delayjs_ui_list(),
],
'delay_js_execution_safe_mode' => [
'type' => 'checkbox',
'label' => __( 'Delay JavaScript Execution safe mode', 'rocket' ),
// translators: %1$s = opening <a> tag, %2$s = closing </a> tag.
'description' => __( 'Delay JavaScript Execution safe mode temporarily resolves issues with Delay JavaScript execution but may reduce your PageSpeed Scores and performance. Contact support for help excluding problematic scripts to use this feature fully.', 'rocket' ),
'helper' => '',
'container_class' => [
'wpr-field--parent',
'wpr-NoPaddingBottom',
'wpr-field--children',
],
'section' => 'js',
'page' => 'file_optimization',
'parent' => 'delay_js',
'default' => 0,
'sanitize_callback' => 'sanitize_checkbox',
'input_attr' => [
'disabled' => 0,
],
'warning' => [
'title' => __( 'This will decrease the effect of Delay JavaScript Execution', 'rocket' ),
'description' => __( 'This mode temporarily resolves issues with Delay JavaScript execution but may reduce your PageSpeed Scores and performance. Contact support for help excluding problematic scripts to use this feature fully.', 'rocket' ),
'button_label' => __( 'Activate Safe Mode', 'rocket' ),
],
],
'delay_js_exclusions' => [
'type' => 'textarea',
'label' => __( 'Excluded JavaScript Files', 'rocket' ),
'description' => __( 'Specify URLs or keywords that can identify inline or JavaScript files to be excluded from delaying execution (one per line).', 'rocket' ),
'container_class' => [
'wpr-field--children',
],
'label' => __( 'Excluded JavaScript Files', 'rocket' ),
'description' => __( 'Specify URLs or keywords that can identify inline or JavaScript files to be excluded from delaying execution (one per line).', 'rocket' ),
'parent' => 'delay_js',
'section' => 'js',
'page' => 'file_optimization',
Expand All @@ -808,9 +831,9 @@ private function assets_section() {
'disabled' => get_rocket_option( 'delay_js' ) ? 0 : 1,
],
'helper' => DelayJSSettings::exclusion_list_has_default() ? $delay_js_found_list_helper : $delay_js_list_helper,
'placeholder' => '/wp-includes/js/jquery/jquery.min.js',
'placeholder' => '',
],
]
],
);
}

Expand Down
42 changes: 34 additions & 8 deletions inc/Engine/Optimization/DelayJS/Admin/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public function __construct( Options $options_api ) {
/**
* Add the delay JS options to the WP Rocket options array
*
* @since 3.18 Added delay_js_execution_safe_mode.
* @since 3.9 Removed delay_js_scripts key, added delay_js_exclusions.
* @since 3.7
*
Expand All @@ -37,15 +38,17 @@ public function __construct( Options $options_api ) {
public function add_options( $options ): array {
$options = (array) $options;

$options['delay_js'] = 0;
$options['delay_js_exclusions'] = [];
$options['delay_js'] = 0;
$options['delay_js_exclusions'] = [];
$options['delay_js_execution_safe_mode'] = 0;

return $options;
}

/**
* Sets the delay_js_exclusions default value for users with delay JS enabled on upgrade
*
* @since 3.18 Keep the custom delay js exclusions if there were before.
* @since 3.9 Sets the delay_js_exclusions default value if delay_js is 1
* @since 3.7
*
Expand Down Expand Up @@ -77,21 +80,27 @@ public function set_option_on_update( $old_version ) {
* Sanitizes delay JS options when saving the settings
*
* @since 3.9
* @since 3.18 Deletes safe mode exclusions from `delay_js_exclusions`.
*
* @param array $input Array of values submitted from the form.
* @param AdminSettings $settings Settings class instance.
*
* @return array
*/
public function sanitize_options( $input, $settings ): array {
$input['delay_js'] = $settings->sanitize_checkbox( $input, 'delay_js' );
$input['delay_js_exclusions'] =
$input['delay_js'] = $settings->sanitize_checkbox( $input, 'delay_js' );
$input['delay_js_execution_safe_mode'] = $settings->sanitize_checkbox( $input, 'delay_js_execution_safe_mode' );
$input['delay_js_exclusions'] =
! empty( $input['delay_js_exclusions'] )
?
rocket_sanitize_textarea_field( 'delay_js_exclusions', $input['delay_js_exclusions'] )
:
[];

$default_exclusions = self::get_safe_mode_exclusions();

$input['delay_js_exclusions'] = array_diff( $input['delay_js_exclusions'], $default_exclusions );

return $input;
}

Expand Down Expand Up @@ -135,6 +144,26 @@ public function maybe_disable_combine_js( $value, $old_value ): array {
return $value;
}


/**
* Get the list of default exclusions for the safe mode.
*
* This method returns an array of regular expressions that match JavaScript files
* and patterns which should be excluded from the delay JavaScript execution feature
* when the safe mode is enabled.
*
* @since 3.18
*
* @return array An array of regular expressions for safe mode exclusions.
*/
public static function get_safe_mode_exclusions(): array {
return [
'/jquery(-migrate)?-?([0-9.]+)?(.min|.slim|.slim.min)?.js(\?(.*))?( |\'|"|>)',
'js-(before|after)',
'(?:/wp-content/|/wp-includes/)(.*)',
];
}

/**
* Get default exclusion list.
*
Expand All @@ -144,10 +173,7 @@ public function maybe_disable_combine_js( $value, $old_value ): array {
*/
public static function get_delay_js_default_exclusions(): array {

$exclusions = [
'\/jquery(-migrate)?-?([0-9.]+)?(.min|.slim|.slim.min)?.js(\?(.*))?( |\'|"|>)',
'js-(before|after)',
];
$exclusions = self::get_safe_mode_exclusions();

$wp_content = wp_parse_url( content_url( '/' ), PHP_URL_PATH );
$wp_includes = wp_parse_url( includes_url( '/' ), PHP_URL_PATH );
Expand Down
10 changes: 9 additions & 1 deletion inc/Engine/Optimization/DelayJS/HTML.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace WP_Rocket\Engine\Optimization\DelayJS;

use WP_Rocket\Admin\Options_Data;
use WP_Rocket\Engine\Optimization\DelayJS\Admin\Settings;
use WP_Rocket\Engine\Optimization\DynamicLists\DefaultLists\DataManager;
use WP_Rocket\Engine\Optimization\RegexTrait;
use WP_Rocket\Engine\Support\CommentTrait;
Expand Down Expand Up @@ -101,14 +102,21 @@ public function delay_js( $html ): string {
$this->excluded = array_merge( $this->excluded, $this->options->get( 'delay_js_exclusions', [] ) );
$this->excluded = array_merge( $this->excluded, $this->options->get( 'delay_js_exclusions_selected_exclusions', [] ) );

if ( $this->options->get( 'delay_js_execution_safe_mode', 0 ) ) {
$this->excluded = array_merge(
$this->excluded,
Settings::get_safe_mode_exclusions()
);
}

/**
* Filters the delay JS exclusions array
*
* @since 3.9
*
* @param array $excluded Array of excluded patterns.
*/
$this->excluded = (array) apply_filters( 'rocket_delay_js_exclusions', $this->excluded );
$this->excluded = wpm_apply_filters_typed( 'string[]', 'rocket_delay_js_exclusions', $this->excluded );
$this->excluded = array_map(
function ( $value ) {
if ( ! is_string( $value ) ) {
Expand Down
10 changes: 10 additions & 0 deletions src/js/global/fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,14 @@ $(document).ready(function(){
$(checkbox).attr('checked', not_checked <= 0 ? 'checked' : null );
});
}

/**
* Delay JS Execution Safe Mode Field
*/
var $dje_safe_mode_checkbox = $('#delay_js_execution_safe_mode');
$('#delay_js').on('change', function () {
if ($(this).is(':not(:checked)') && $dje_safe_mode_checkbox.is(':checked')) {
$dje_safe_mode_checkbox.trigger('click');
}
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
'options' => [],
],
'expected' => [
'delay_js' => 0,
'delay_js_exclusions' => [],
'delay_js' => 0,
'delay_js_exclusions' => [],
'delay_js_execution_safe_mode' => 0,
]
],
'shouldReturnValidOptionsWithOptionsNotArray' => [
Expand All @@ -16,38 +17,43 @@
],
'expected' => [
'test_option',
'delay_js' => 0,
'delay_js_exclusions' => [],
'delay_js' => 0,
'delay_js_exclusions' => [],
'delay_js_execution_safe_mode' => 0,
]
],
'shouldOverrideOptions' => [
'input' => [
'options' => [
'delay_js' => 1,
'delay_js_exclusions' => [
'delay_js' => 1,
'delay_js_execution_safe_mode' => 0,
'delay_js_exclusions' => [
'any value'
]
],
],
'expected' => [
'delay_js' => 0,
'delay_js_exclusions' => []
'delay_js' => 0,
'delay_js_execution_safe_mode' => 0,
'delay_js_exclusions' => []
]
],
'shouldNotOverrideOtherOptions' => [
'input' => [
'options' => [
'test_option' => 1,
'delay_js' => 0,
'delay_js_exclusions' => [
'test_option' => 1,
'delay_js' => 0,
'delay_js_execution_safe_mode' => 0,
'delay_js_exclusions' => [
'any value'
]
],
],
'expected' => [
'test_option' => 1,
'delay_js' => 0,
'delay_js_exclusions' => [],
'test_option' => 1,
'delay_js' => 0,
'delay_js_execution_safe_mode' => 0,
'delay_js_exclusions' => [],
]
],
];
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
'input' => [],
'sanitized_input' => [
'delay_js' => 0,
'delay_js_exclusions' => null
'delay_js_exclusions' => null,
'delay_js_execution_safe_mode' => 0,
],
],
'expected' => [
'delay_js' => 0,
'delay_js_execution_safe_mode' => 0,
'delay_js_exclusions' => [],
],
],
Expand All @@ -20,7 +22,8 @@
'delay_js' => true,
'delay_js_exclusions' => "wp-content/themes/twentytwenty/script.js\n<script>\nGoogleAnalytics\ngtm\nwp-includes/.*.js",
'delay_js_exclusions_selected' => [],
'delay_js_exclusions_selected_exclusions' => []
'delay_js_exclusions_selected_exclusions' => [],
'delay_js_execution_safe_mode' => 0,
],
'sanitized_input' => [
'delay_js' => 1,
Expand All @@ -31,7 +34,8 @@
'wp-includes/(.*).js',
],
'delay_js_exclusions_selected' => [],
'delay_js_exclusions_selected_exclusions' => []
'delay_js_exclusions_selected_exclusions' => [],
'delay_js_execution_safe_mode' => 0,
],
],
'expected' => [
Expand All @@ -43,7 +47,8 @@
'wp-includes/(.*).js',
],
'delay_js_exclusions_selected' => [],
'delay_js_exclusions_selected_exclusions' => []
'delay_js_exclusions_selected_exclusions' => [],
'delay_js_execution_safe_mode' => 0,
],
],
'testShouldPreserveValueIfCorrectType' => [
Expand All @@ -58,7 +63,8 @@
'wp-includes/.*.js'
],
'delay_js_exclusions_selected' => [],
'delay_js_exclusions_selected_exclusions' => []
'delay_js_exclusions_selected_exclusions' => [],
'delay_js_execution_safe_mode' => 1,
],
'sanitized_input' => [
'delay_js' => 1,
Expand All @@ -69,7 +75,8 @@
'wp-includes/(.*).js',
],
'delay_js_exclusions_selected' => [],
'delay_js_exclusions_selected_exclusions' => []
'delay_js_exclusions_selected_exclusions' => [],
'delay_js_execution_safe_mode' => 1,
],
],
'expected' => [
Expand All @@ -81,7 +88,8 @@
'wp-includes/(.*).js',
],
'delay_js_exclusions_selected' => [],
'delay_js_exclusions_selected_exclusions' => []
'delay_js_exclusions_selected_exclusions' => [],
'delay_js_execution_safe_mode' => 1,
],
],
];
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
'expected' => [
'delay_js' => 0,
'delay_js_exclusions' => [],
'delay_js_execution_safe_mode' => 0,
]
],
'shouldReturnValidOptionsWithOptionsNotArray' => [
Expand All @@ -18,6 +19,7 @@
'test_option',
'delay_js' => 0,
'delay_js_exclusions' => [],
'delay_js_execution_safe_mode' => 0,
]
],
'shouldOverrideOptions' => [
Expand All @@ -26,12 +28,14 @@
'delay_js' => 1,
'delay_js_exclusions' => [
'any value'
]
],
'delay_js_execution_safe_mode' => 1,
],
],
'expected' => [
'delay_js' => 0,
'delay_js_exclusions' => [],
'delay_js_execution_safe_mode' => 0,
]
],
'shouldNotOverrideOtherOptions' => [
Expand All @@ -41,13 +45,15 @@
'delay_js' => 0,
'delay_js_exclusions' => [
'any value'
]
],
'delay_js_execution_safe_mode' => 0,
],
],
'expected' => [
'test_option' => 1,
'delay_js' => 0,
'delay_js_exclusions' => [],
'delay_js_execution_safe_mode' => 0,
]
],
];
Loading
Loading