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

Boost: refactor Critical CSS: Part 1 #22163

Merged
merged 121 commits into from
Jan 31, 2022
Merged
Show file tree
Hide file tree
Changes from 97 commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
4df09b6
Move Critical CSS Recommendation to own class
karthikax Dec 7, 2021
52c8893
Add changelog
karthikax Dec 7, 2021
51bb0c9
After recommendation refactor fix
pyronaur Dec 7, 2021
b9d596c
Move constants filter inside CSS Recommendations class
pyronaur Dec 7, 2021
69c188c
Move on_uninstall
pyronaur Dec 7, 2021
9a93e71
Refactor Critical CSS recommendation
karthikax Dec 8, 2021
9a2bf24
Remove legacy Recommendation
karthikax Dec 8, 2021
3cd1b51
Refactor get notifications for abstraction
karthikax Dec 8, 2021
64cbf72
Refactor inheritance aware notification key
karthikax Dec 8, 2021
910c975
Refactor module constructors to on_prepare
karthikax Dec 9, 2021
b2be2b9
Remove non-existing class from comment
pyronaur Dec 8, 2021
2ee198c
Refactor Notifications to OptionsArray
karthikax Dec 9, 2021
29ce1d2
Merge branch 'refactor/boost-critical-css' of github.com:Automattic/j…
karthikax Dec 9, 2021
c01f6c6
Dump generation related functions into Generator class
pyronaur Dec 9, 2021
6ce9cdd
Go ahead, make a mess.
pyronaur Dec 9, 2021
1849901
Re-add handle_css_proxy
pyronaur Dec 9, 2021
48a9159
Move: api_get_critical_css_status
pyronaur Dec 9, 2021
5c916e2
Add critically bad comments
pyronaur Dec 9, 2021
8f823d4
Remove module is_initialized
karthikax Dec 10, 2021
dfa4930
Clarify method name: get_current_request_css
pyronaur Dec 10, 2021
71b7e0f
Create a dedicated method to display Critical CSS
pyronaur Dec 10, 2021
f0fec8c
Whoops - wrong condition.
pyronaur Dec 10, 2021
831d997
Move & De-duplicate AMP Compatibility
pyronaur Dec 10, 2021
2af3a56
Refactor AMP conditions to separate file
karthikax Dec 10, 2021
12b2622
Move Providers
pyronaur Dec 10, 2021
12dbf1b
Create a class to manage Critical CSS Paths
pyronaur Dec 10, 2021
3ce3ea2
Add module initialized action
karthikax Dec 10, 2021
60451d4
Move generator out of the main Critical CSS class
pyronaur Dec 10, 2021
8dc42b5
Fix missing providers
pyronaur Dec 10, 2021
5fc4d5e
Remove the need to inject providers
pyronaur Dec 10, 2021
6317dd3
Clean up backslash
pyronaur Dec 10, 2021
cf007d5
Remove an unused import
pyronaur Dec 10, 2021
cd48f94
Remove comments
pyronaur Dec 10, 2021
05c1b5d
Move recommendations out of the main Critical CSS Class
pyronaur Dec 10, 2021
c4986b4
Clean up recommendations class
pyronaur Dec 10, 2021
9256e66
Clean up Options and Recommendations
pyronaur Dec 10, 2021
c7d1281
Reorganize REST_API Class
pyronaur Dec 10, 2021
25ed0c7
Simplify REST API Class
pyronaur Dec 10, 2021
792f198
Add a regression note (!)
pyronaur Dec 10, 2021
fbd2399
De-nest config array
pyronaur Dec 10, 2021
252a12b
Few more comment cleanups
pyronaur Dec 10, 2021
c29bafe
Experiment: Abstract API Class
pyronaur Dec 10, 2021
fffddcc
Merge branch 'master' into refactor/boost-critical-css
karthikax Dec 13, 2021
152be97
Implement `request-generate` using Boost_API
pyronaur Dec 22, 2021
968dcd5
Generator Success & Error endpoints
pyronaur Dec 22, 2021
8ebde19
Fix typos, simplify endpoint method
pyronaur Dec 22, 2021
4648ee2
PSR4
pyronaur Dec 22, 2021
a978121
Move Recommendations to Boost API
pyronaur Dec 22, 2021
e0c2cdb
API -> REST_API
pyronaur Dec 22, 2021
4ffcc27
Add nonces to REST API
pyronaur Dec 22, 2021
62c0367
Speculative generality
pyronaur Dec 22, 2021
89ff0db
Cleanup
pyronaur Dec 22, 2021
28be845
Fix missing nonce regression
pyronaur Dec 22, 2021
976f318
Merge remote-tracking branch 'origin/master' into refactor/boost-crit…
pyronaur Dec 22, 2021
fb16f9f
Auto-fix phpcs errors
karthikax Jan 4, 2022
d2e693e
Add Docblock comments
karthikax Jan 4, 2022
1843cc6
Update Classes to PascalCase
karthikax Jan 5, 2022
8d1bef5
Merge branch 'master' into refactor/boost-critical-css
karthikax Jan 5, 2022
ab8d901
Refactor amp compatibility
karthikax Jan 5, 2022
0354259
Merge branch 'master' into refactor/boost-critical-css
karthikax Jan 10, 2022
dcd871e
Fix class module unit test
karthikax Jan 10, 2022
1f59019
Revert Update Classes to PascalCase
karthikax Jan 11, 2022
7b092d3
Merge branch 'master' into refactor/boost-critical-css
karthikax Jan 11, 2022
6fe31b6
Improve how the option list object is described
pyronaur Jan 11, 2022
bc59b62
Clarify the collection code a bit
pyronaur Jan 11, 2022
3692988
Disable autoloading on recommendations
pyronaur Jan 11, 2022
7d2565d
Clarify collection comments
pyronaur Jan 11, 2022
31cc4a7
Clean-up comments
pyronaur Jan 11, 2022
f51a6b1
Improve comments and phpDoc hints
pyronaur Jan 11, 2022
0fd1d87
Revert "Add Docblock comments"
pyronaur Jan 12, 2022
70c6803
Config ID's aren't used anymore
pyronaur Jan 12, 2022
73b3615
Remove unused method
pyronaur Jan 12, 2022
060f501
Remove unmodified methods
pyronaur Jan 12, 2022
2d52c89
Refactor the config class
pyronaur Jan 12, 2022
ad909d9
Replicate lazy images in both Jetpack and Boost
pyronaur Jan 12, 2022
35a0ee1
Remove dead code
pyronaur Jan 12, 2022
08f9215
Move connection related code to connection class
pyronaur Jan 12, 2022
f619172
Remove unused meta tag
pyronaur Jan 12, 2022
34002cc
Typo
pyronaur Jan 12, 2022
5287f9b
Refactor Critical CSS REST API
pyronaur Jan 13, 2022
a05036e
Update the namespaces to match the new file structure
pyronaur Jan 13, 2022
6b3f987
Restore behavior: ensure the module is initialized
pyronaur Jan 13, 2022
0174f65
Revert "Restore behavior: ensure the module is initialized"
pyronaur Jan 14, 2022
6f2be9b
Remove todos - no longer a required feature
pyronaur Jan 14, 2022
739b4bc
Move Critical CSS REST API files
pyronaur Jan 14, 2022
cf70c71
Boost_API -> REST_API
pyronaur Jan 14, 2022
a84b5f5
Simplify Critical CSS REST API initialization
pyronaur Jan 14, 2022
aff3037
Cleanup
pyronaur Jan 14, 2022
46b7423
A step towards a modular REST API
pyronaur Jan 14, 2022
1947431
A step towards modular modules
pyronaur Jan 14, 2022
d5ae9d7
Move module filtering to a dedicated method
pyronaur Jan 14, 2022
8038970
Rename Module to Module_Toggle
pyronaur Jan 17, 2022
9cf4f19
Create a Module calss that deals with module setup
pyronaur Jan 17, 2022
7b2a9f9
Make REST_API Route registration more elegant
pyronaur Jan 17, 2022
aa10845
Move module toggling to the the new REST API format
pyronaur Jan 17, 2022
de0f519
Move modules out of main plugin class
pyronaur Jan 17, 2022
4b6b4a6
Update comments
pyronaur Jan 17, 2022
8854abd
Cleanup comments
pyronaur Jan 19, 2022
38960a4
Mass rename
pyronaur Jan 19, 2022
a8cd102
Toggle_Module -> Optimization_Status
pyronaur Jan 19, 2022
03d69c9
Modules -> Features & Optimizations
pyronaur Jan 19, 2022
489c56a
Merge remote-tracking branch 'origin/master' into refactor/boost-crit…
pyronaur Jan 20, 2022
fe0c0e1
Silence php8 error
pyronaur Jan 20, 2022
6ec59cb
Unit test fix
pyronaur Jan 20, 2022
09bd4d8
Fix module tests
pyronaur Jan 20, 2022
c262e9f
phpcs autofix
pyronaur Jan 20, 2022
c398ccb
Fix phpcs errors & warnings
pyronaur Jan 20, 2022
65283da
Clean up optimization status tracking
pyronaur Jan 20, 2022
6367679
state -> status
pyronaur Jan 20, 2022
4aaa81f
Simplify uninstall
pyronaur Jan 20, 2022
1352b1d
Add missing namespaces
pyronaur Jan 20, 2022
9226329
Fix CLI for e2e tests
pyronaur Jan 20, 2022
c7c69b2
Seamlessly migrate to the new options format.
pyronaur Jan 21, 2022
967ce52
Protect against recursion
pyronaur Jan 21, 2022
2a28b05
Add Has_Setup and Setup classes
pyronaur Jan 21, 2022
1f32532
Improve how Optimization objects are initialized
pyronaur Jan 24, 2022
507e4f0
[not verified] Fix: return statement was left over after refactoring
pyronaur Jan 24, 2022
b7401e5
Allow any unused parameters which start with _, to allow for implemen…
Jan 28, 2022
8893c9c
Catch errors that occur when queuing up Critical CSS generation, so t…
Jan 28, 2022
970f6e3
Merge branch 'master' into refactor/boost-critical-css
Jan 31, 2022
ce453af
Skip lazy-image tests until reinstated later
Jan 31, 2022
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
3 changes: 3 additions & 0 deletions projects/plugins/boost/.phpcs.dir.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@
</properties>
</rule>

<rule ref="WordPress.Files.FileName.InvalidClassFileName">
<severity>0</severity>
</rule>
</ruleset>
118 changes: 63 additions & 55 deletions projects/plugins/boost/app/admin/class-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
use Automattic\Jetpack_Boost\Lib\Analytics;
use Automattic\Jetpack_Boost\Lib\Environment_Change_Detector;
use Automattic\Jetpack_Boost\Lib\Speed_Score;
use Automattic\Jetpack_Boost\Modules\Modules;
use Automattic\Jetpack_Boost\REST_API\Permissions\Nonce;

/**
* Class Admin
Expand Down Expand Up @@ -45,7 +47,7 @@ class Admin {
*
* @var Jetpack_Boost Plugin.
*/
pyronaur marked this conversation as resolved.
Show resolved Hide resolved
private $jetpack_boost;
private $modules;

/**
* Speed_Score class instance.
Expand All @@ -61,14 +63,13 @@ class Admin {
*
* @since 1.0.0
*/
public function __construct( Jetpack_Boost $jetpack_boost ) {
$this->jetpack_boost = $jetpack_boost;
$this->speed_score = new Speed_Score( $jetpack_boost );
public function __construct( Modules $modules ) {
$this->modules = $modules;
$this->speed_score = new Speed_Score( $modules );
Environment_Change_Detector::init();

add_action( 'init', array( new Analytics(), 'init' ) );
add_filter( 'plugin_action_links_' . JETPACK_BOOST_PLUGIN_BASE, array( $this, 'plugin_page_settings_link' ) );
add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );
add_action( 'admin_notices', array( $this, 'show_notices' ) );
add_action( 'wp_ajax_set_show_rating_prompt', array( $this, 'handle_set_show_rating_prompt' ) );
add_filter( 'jetpack_boost_js_constants', array( $this, 'add_js_constants' ) );
Expand Down Expand Up @@ -102,7 +103,7 @@ public function enqueue_styles() {
$internal_path = apply_filters( 'jetpack_boost_asset_internal_path', 'app/assets/dist/' );

wp_enqueue_style(
$this->jetpack_boost->get_plugin_name() . '-css',
'jetpack-boost-css',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this!

plugins_url( $internal_path . 'jetpack-boost.css', JETPACK_BOOST_PATH ),
array( 'wp-components' ),
JETPACK_BOOST_VERSION
Expand All @@ -117,7 +118,7 @@ public function enqueue_styles() {
public function enqueue_scripts() {
$internal_path = apply_filters( 'jetpack_boost_asset_internal_path', 'app/assets/dist/' );

$admin_js_handle = $this->jetpack_boost->get_plugin_name() . '-admin';
$admin_js_handle = 'jetpack-boost-admin';

wp_register_script(
$admin_js_handle,
Expand All @@ -127,15 +128,31 @@ public function enqueue_scripts() {
true
);

$active_modules = array_keys( $this->modules->get_active_modules() );
$available_modules = array_keys( $this->modules->get_modules() );

/**
* @TODO: This config here ia bit incorrect - JavaScript relies on config module containing all the modules, even the disabled ones.
* But that doesn't make much sense, since we're already passing all the available modules separately.
* The "constants" should be cleaned up a bit, but out of scope at the moment.
* The config system should be cleaned up a bit further.
*/
$module_config = array();
foreach ( $available_modules as $module_slug ) {
$module_config[ $module_slug ] = array(
'enabled' => in_array( $module_slug, $active_modules, true ),
);
}

// Prepare configuration constants for JavaScript.
$constants = array(
'version' => JETPACK_BOOST_VERSION,
'api' => array(
'namespace' => JETPACK_BOOST_REST_NAMESPACE,
'prefix' => JETPACK_BOOST_REST_PREFIX,
),
'modules' => $this->jetpack_boost->get_available_modules(),
'config' => $this->jetpack_boost->config()->get_data(),
'modules' => $available_modules,
'config' => $module_config,
'locale' => get_locale(),
'site' => array(
'url' => get_home_url(),
Expand All @@ -146,6 +163,15 @@ public function enqueue_scripts() {
'preferences' => array(
'showRatingPrompt' => $this->get_show_rating_prompt(),
),


/**
* A bit of necessary magic,
* Explained more in the Nonce class.
*
* Nonces are automatically generated when registering routes.
*/
'nonces' => Nonce::get_generated_nonces(),
);

// Give each module an opportunity to define extra constants.
Expand Down Expand Up @@ -179,7 +205,7 @@ public function plugin_page_settings_link( $links ) {
*/
public function render_settings() {
wp_localize_script(
$this->jetpack_boost->get_plugin_name() . '-admin',
'jetpack-boost-admin',
'wpApiSettings',
array(
'root' => esc_url_raw( rest_url() ),
Expand All @@ -200,48 +226,6 @@ public function check_for_permissions() {
return current_user_can( 'manage_options' );
}

/**
* Register REST routes for settings.
*
* @return void
*/
public function register_rest_routes() {
// Activate and deactivate a module.
register_rest_route(
JETPACK_BOOST_REST_NAMESPACE,
JETPACK_BOOST_REST_PREFIX . '/module/(?P<slug>[a-z\-]+)/status',
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'set_module_status' ),
'permission_callback' => array( $this, 'check_for_permissions' ),
)
);
}

/**
* Handler for the /module/(?P<slug>[a-z\-]+)/status endpoint.
*
* @param \WP_REST_Request $request The request object.
*
* @return \WP_REST_Response|\WP_Error The response.
*/
public function set_module_status( $request ) {
$params = $request->get_json_params();

if ( ! isset( $params['status'] ) ) {
return new \WP_Error(
'jetpack_boost_error_missing_module_status_param',
__( 'Missing status param', 'jetpack-boost' )
);
}

$module_slug = $request['slug'];
$this->jetpack_boost->set_module_status( (bool) $params['status'], $module_slug );

return rest_ensure_response(
$this->jetpack_boost->get_module_status( $module_slug )
);
}

/**
* Show any admin notices from enabled modules.
Expand All @@ -250,13 +234,13 @@ public function show_notices() {
// Determine if we're already on the settings page.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$on_settings_page = isset( $_GET['page'] ) && self::MENU_SLUG === $_GET['page'];
$notices = $this->jetpack_boost->get_admin_notices();
$notices = $this->get_admin_notices();

// Filter out any that have been dismissed, unless newer than the dismissal.
$dismissed_notices = \get_option( self::DISMISSED_NOTICE_OPTION, array() );
$notices = array_filter(
$notices,
function ( $notice ) use ( $dismissed_notices ) {
function( $notice ) use ( $dismissed_notices ) {
$notice_slug = $notice->get_slug();

return ! in_array( $notice_slug, $dismissed_notices, true );
Expand All @@ -281,7 +265,7 @@ function ( $notice ) use ( $dismissed_notices ) {
* @return array List of notice ids.
*/
private function get_shown_admin_notice_ids() {
$notices = $this->jetpack_boost->get_admin_notices();
$notices = $this->get_admin_notices();
$ids = array();
foreach ( $notices as $notice ) {
$ids[] = $notice->get_id();
Expand All @@ -290,6 +274,30 @@ private function get_shown_admin_notice_ids() {
return $ids;
}

/**
* Returns a list of admin notices to show. Asks each module to provide admin notices the user needs to see.
* @TODO: This is still a code smell. We're carrying the whole modules instance just to get a list of admin notices.
*
* @return \Automattic\Jetpack_Boost\Admin\Admin_Notice[]
*/
public function get_admin_notices() {
$all_notices = array();

foreach ( $this->modules->get_active_modules() as $module ) {

if( ! method_exists( $module, 'get_admin_notices' ) ) {
continue;
}
$module_notices = $module->get_admin_notices();

if ( ! empty( $module_notices ) ) {
$all_notices = array_merge( $all_notices, $module_notices );
}
}

return $all_notices;
}

/**
* Check for a GET parameter used to dismiss an admin notice.
*
Expand Down
4 changes: 3 additions & 1 deletion projects/plugins/boost/app/assets/src/js/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ declare global {
connection: ConnectionStatus;
criticalCssStatus?: CriticalCssStatus;
showRatingPromptNonce?: string;
criticalCssDismissRecommendationsNonce?: string;
criticalCssDismissedRecommendations: string[];
site: {
url: string;
Expand All @@ -44,6 +43,9 @@ declare global {
};
config: ModulesState;
shownAdminNoticeIds: string[];
nonces: {
[ key: string ]: string;
};
};

// Critical CSS Generator library.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { writable, derived } from 'svelte/store';
/**
* Internal dependencies
*/
import api from '../api/api';
import { CriticalCssErrorDetails, criticalCssStatus } from './critical-css-status';
import type { JSONObject } from '../utils/json-types';
import { objectFilter } from '../utils/object-filter';
import { sortByFrequency } from '../utils/sort-by-frequency';
import { makeAdminAjaxRequest } from '../utils/make-admin-ajax-request';
import { castToString } from '../utils/cast-to-string';

const importantProviders = [
Expand Down Expand Up @@ -118,10 +118,9 @@ export function setDismissalError( title: string, error: JSONObject ): void {
* @param {string} key Key of recommendation to dismiss.
*/
export async function dismissRecommendation( key: string ): Promise< void > {
await makeAdminAjaxRequest( {
action: 'dismiss_recommendations',
await api.post( '/recommendations/dismiss', {
providerKey: key,
nonce: Jetpack_Boost.criticalCssDismissRecommendationsNonce,
nonce: Jetpack_Boost.nonces[ 'recommendations/dismiss' ],
} );
dismissed.update( keys => [ ...keys, key ] );
}
Expand All @@ -130,9 +129,8 @@ export async function dismissRecommendation( key: string ): Promise< void > {
* Clear all the dismissed recommendations.
*/
export async function clearDismissedRecommendations(): Promise< void > {
await makeAdminAjaxRequest( {
action: 'reset_dismissed_recommendations',
nonce: Jetpack_Boost.criticalCssDismissRecommendationsNonce,
await api.post( '/recommendations/reset', {
nonce: Jetpack_Boost.nonces[ 'recommendations/reset' ],
} );
dismissed.set( [] );
}
Expand Down
Loading