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 12 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' => $invalid_license ? __( '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' ) : '',
Miraeld marked this conversation as resolved.
Show resolved Hide resolved
'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' => $invalid_license ? [] : [
'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
37 changes: 30 additions & 7 deletions inc/Engine/Optimization/DelayJS/Admin/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public function add_options( $options ): array {
/**
* 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 All @@ -58,9 +59,8 @@ public function set_option_on_update( $old_version ) {
return;
}

$options = $this->options_api->get( 'settings', [] );

$options['delay_js_exclusions'] = [];
$options = $this->options_api->get( 'settings', [] );
$old_custom_exclusions = $options['delay_js_exclusions'] ?? [];

if (
isset( $options['delay_js'] )
Expand All @@ -77,6 +77,7 @@ 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.
Expand All @@ -92,6 +93,11 @@ public function sanitize_options( $input, $settings ): array {
:
[];

$default_exclusions = self::get_safe_mode_exclusions();

$input['delay_js_exclusions'] = array_diff( $input['delay_js_exclusions'], $default_exclusions );
$input['delay_js_execution_safe_mode'] = $settings->sanitize_checkbox( $input, 'delay_js_execution_safe_mode' );

return $input;
}

Expand Down Expand Up @@ -135,6 +141,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 +170,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
13 changes: 12 additions & 1 deletion inc/Engine/Optimization/DelayJS/HTML.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,25 @@ 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,
[
'/jquery(-migrate)?-?([0-9.]+)?(.min|.slim|.slim.min)?.js(\?(.*))?( |\'|"|>)',
'js-(before|after)',
'(?:/wp-content/|/wp-includes/)(.*)',
]
Miraeld marked this conversation as resolved.
Show resolved Hide resolved
);
}

/**
* 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( 'array', 'rocket_delay_js_exclusions', $this->excluded );
Miraeld marked this conversation as resolved.
Show resolved Hide resolved
$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');
}
});
});
23 changes: 23 additions & 0 deletions tests/Fixtures/inc/Engine/Optimization/DelayJS/HTML/delayJs.php
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,7 @@ function wprRemoveCPCSS() {
'delay_js' => 1,
'delay_js_exclusions' => [],
'exclusions_list' => $exclusions_list,
'delay_js_safe_mode' => false,
],
'html' => $html,
'expected' => $html,
Expand All @@ -858,6 +859,7 @@ function wprRemoveCPCSS() {
'delay_js' => 1,
'delay_js_exclusions' => [],
'exclusions_list' => $exclusions_list,
'delay_js_safe_mode' => false,
],
'html' => $html,
'expected' => $html,
Expand All @@ -871,6 +873,7 @@ function wprRemoveCPCSS() {
'delay_js' => 1,
'delay_js_exclusions' => [],
'exclusions_list' => $exclusions_list,
'delay_js_safe_mode' => false,
],
'html' => $html,
'expected' => $html,
Expand All @@ -884,6 +887,7 @@ function wprRemoveCPCSS() {
'delay_js' => 0,
'delay_js_exclusions' => [],
'exclusions_list' => $exclusions_list,
'delay_js_safe_mode' => false,
],
'html' => $html,
'expected' => $html,
Expand All @@ -895,6 +899,7 @@ function wprRemoveCPCSS() {
'donotoptimize' => false,
'post-excluded' => false,
'delay_js' => 1,
'delay_js_safe_mode' => false,
'delay_js_exclusions' => [
'(?:/wp-content|/wp-includes/)(.*)',
'/jquery-?[0-9.]*(.min|.slim|.slim.min)?.js',
Expand All @@ -912,6 +917,7 @@ function wprRemoveCPCSS() {
'donotoptimize' => false,
'post-excluded' => false,
'delay_js' => 1,
'delay_js_safe_mode' => false,
'delay_js_exclusions' => [
'/wp-includes/js/comment-reply.min.js?ver=5.7',
'js-(after|extra)',
Expand All @@ -921,5 +927,22 @@ function wprRemoveCPCSS() {
'html' => $html,
'expected' => $delay_html,
],
'testShouldDelayJSWithSafeMode' => [
'config' => [
'bypass' => false,
'donotoptimize' => false,
'post-excluded' => false,
'delay_js' => 1,
'delay_js_safe_mode' => true,
'delay_js_exclusions' => [
// '/jquery(-migrate)?-?([0-9.]+)?(.min|.slim|.slim.min)?.js(\?(.*))?( |\'|"|>)?', // error with the regex of safe mode /jquery(-migrate)?-?([0-9.]+)?(.min|.slim|.slim.min)?.js(\?(.*))?( |\'|"|>)
// 'js-(before|after)',
// '(?:/wp-content/|/wp-includes/)(.*)',
],
'exclusions_list' => $exclusions_list,
],
'html' => $html,
'expected' => $delay_html_upgrade,
],
]
];
Original file line number Diff line number Diff line change
Expand Up @@ -579,5 +579,20 @@
'html' => $html,
'expected' => $delay_html_upgrade,
],
'testShouldDelayJSWithSafeMode' => [
'config' => [
'type' => 'front_page',
'bypass' => false,
'donotoptimize' => false,
'post-excluded' => false,
'delay_js' => 1,
'delay_js_safe_mode' => 1,
'delay_js_exclusions' => [
],
'exclusions' => $exclusions_list,
],
'html' => $html,
'expected' => $delay_html_upgrade,
],
]
];
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Test_DelayJs extends TestCase {
private $delay_js = 0;
private $delay_js_exclusions = [];
private $post;
private $delay_js_safemode = false;

public function set_up() {
parent::set_up();
Expand Down Expand Up @@ -57,6 +58,7 @@ public function testShouldReturnExpected( $config, $html, $expected ) {
$this->donotrocketoptimize = $config['donotoptimize'];
$this->delay_js = $config['delay_js'];
$this->delay_js_exclusions = $config['delay_js_exclusions'];
$this->delay_js_safemode = $config['delay_js_safemode'] ?? false;
$this->post = $this->goToContentType( $config );

if ( $config['post-excluded'] ) {
Expand All @@ -65,6 +67,7 @@ public function testShouldReturnExpected( $config, $html, $expected ) {

add_filter( 'pre_get_rocket_option_delay_js', [ $this, 'set_delay_js' ] );
add_filter( 'pre_get_rocket_option_delay_js_exclusions', [ $this, 'set_delay_js_exclusions' ] );
add_filter( 'pre_get_rocket_option_delay_js_execution_safe_mode', [ $this, 'set_delay_js_safe_mode' ] );

set_transient( 'wpr_dynamic_lists', $config['exclusions'], HOUR_IN_SECONDS );

Expand All @@ -85,4 +88,8 @@ public function set_delay_js() {
public function set_delay_js_exclusions() {
return $this->delay_js_exclusions;
}

public function set_delay_js_safe_mode() {
return $this->delay_js_safemode;
}
}
5 changes: 5 additions & 0 deletions tests/Unit/inc/Engine/Optimization/DelayJS/HTML/delayJs.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@
->atMost()
->once()
->andReturn( [] );
$this->options->shouldReceive('get')
->with('delay_js_execution_safe_mode', 0)
->atMost()
->once()
->andReturn($config['delay_js_safe_mode']);

$this->data_manager->shouldReceive( 'get_lists' )
->atMost()
Expand All @@ -81,9 +86,9 @@

$delay_js_html = new HTML( $this->options, $this->data_manager, $this->logger );

$this->assertSame(

Check failure on line 89 in tests/Unit/inc/Engine/Optimization/DelayJS/HTML/delayJs.php

View workflow job for this annotation

GitHub Actions / WP latest with PHP 8.3 on ubuntu-latest.

Failed asserting that two strings are identical.
$expected,
$delay_js_html->delay_js( $html )

Check failure on line 91 in tests/Unit/inc/Engine/Optimization/DelayJS/HTML/delayJs.php

View workflow job for this annotation

GitHub Actions / WP 5.8 with PHP 7.3 on ubuntu-latest.

Failed asserting that two strings are identical.

Check failure on line 91 in tests/Unit/inc/Engine/Optimization/DelayJS/HTML/delayJs.php

View workflow job for this annotation

GitHub Actions / WP 5.8 with PHP 7.4 on ubuntu-latest.

Failed asserting that two strings are identical.

Check failure on line 91 in tests/Unit/inc/Engine/Optimization/DelayJS/HTML/delayJs.php

View workflow job for this annotation

GitHub Actions / WP latest with PHP 8.1 on ubuntu-latest.

Failed asserting that two strings are identical.
);
}
}
Loading