Skip to content

Commit

Permalink
Merge pull request #125 from xwp/tweak/integrations-flag
Browse files Browse the repository at this point in the history
Separate service worker integrations from core and hide them behind feature flag
  • Loading branch information
westonruter authored Feb 4, 2019
2 parents 641b831 + f732221 commit 351eeec
Show file tree
Hide file tree
Showing 18 changed files with 209 additions and 143 deletions.
91 changes: 91 additions & 0 deletions integrations/functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
/**
* Service Worker functions related to integrations.
*
* These are experimental and therefore kept separate from the service worker core code.
*
* @since 0.2
*
* @package PWA
*/

/**
* Registers all default service workers.
*
* @since 0.2
*
* @param WP_Service_Worker_Scripts $scripts Instance to register service worker behavior with.
*/
function wp_default_service_workers( $scripts ) {
$scripts->base_url = site_url();
$scripts->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : '';
$scripts->default_version = get_bloginfo( 'version' );

$integrations = array(
'wp-site-icon' => new WP_Service_Worker_Site_Icon_Integration(),
'wp-custom-logo' => new WP_Service_Worker_Custom_Logo_Integration(),
'wp-custom-header' => new WP_Service_Worker_Custom_Header_Integration(),
'wp-custom-background' => new WP_Service_Worker_Custom_Background_Integration(),
'wp-scripts' => new WP_Service_Worker_Scripts_Integration(),
'wp-styles' => new WP_Service_Worker_Styles_Integration(),
'wp-fonts' => new WP_Service_Worker_Fonts_Integration(),
);

if ( ! SCRIPT_DEBUG ) {
$integrations['wp-admin-assets'] = new WP_Service_Worker_Admin_Assets_Integration();
}

/**
* Filters the service worker integrations to initialize.
*
* @since 0.2
*
* @param array $integrations Array of $slug => $integration pairs, where $integration is an instance
* of a class that implements the WP_Service_Worker_Integration interface.
*/
$integrations = apply_filters( 'wp_service_worker_integrations', $integrations );

foreach ( $integrations as $slug => $integration ) {
if ( ! $integration instanceof WP_Service_Worker_Integration ) {
_doing_it_wrong(
__FUNCTION__,
sprintf(
/* translators: 1: integration slug, 2: interface name */
esc_html__( 'The integration with slug %1$s does not implement the %2$s interface.', 'pwa' ),
esc_html( $slug ),
'WP_Service_Worker_Integration'
),
'0.2'
);
continue;
}

$scope = $integration->get_scope();
$priority = $integration->get_priority();
switch ( $scope ) {
case WP_Service_Workers::SCOPE_FRONT:
add_action( 'wp_front_service_worker', array( $integration, 'register' ), $priority, 1 );
break;
case WP_Service_Workers::SCOPE_ADMIN:
add_action( 'wp_admin_service_worker', array( $integration, 'register' ), $priority, 1 );
break;
case WP_Service_Workers::SCOPE_ALL:
add_action( 'wp_front_service_worker', array( $integration, 'register' ), $priority, 1 );
add_action( 'wp_admin_service_worker', array( $integration, 'register' ), $priority, 1 );
break;
default:
$valid_scopes = array( WP_Service_Workers::SCOPE_FRONT, WP_Service_Workers::SCOPE_ADMIN, WP_Service_Workers::SCOPE_ALL );
_doing_it_wrong(
__FUNCTION__,
sprintf(
/* translators: 1: integration slug, 2: a comma-separated list of valid scopes */
esc_html__( 'Scope for integration %1$s must be one out of %2$s.', 'pwa' ),
esc_html( $slug ),
esc_html( implode( ', ', $valid_scopes ) )
),
'0.1'
);
}
}
}
add_action( 'wp_default_service_workers', 'wp_default_service_workers' );
57 changes: 41 additions & 16 deletions pwa.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,6 @@ function _pwa_incorrect_plugin_slug_admin_notice() {
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-caching-routes-component.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-caching-routes.php';

/** WP_Service_Worker_Integration Interface */
require_once PWA_PLUGIN_DIR . '/wp-includes/integrations/interface-wp-service-worker-integration.php';

/** WP_Service_Worker_Base_Integration Class */
require_once PWA_PLUGIN_DIR . '/wp-includes/integrations/class-wp-service-worker-base-integration.php';

/** WP_Service_Worker_Integration Implementation Classes */
require_once PWA_PLUGIN_DIR . '/wp-includes/integrations/class-wp-service-worker-site-icon-integration.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/integrations/class-wp-service-worker-custom-logo-integration.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/integrations/class-wp-service-worker-custom-header-integration.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/integrations/class-wp-service-worker-custom-background-integration.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/integrations/class-wp-service-worker-scripts-integration.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/integrations/class-wp-service-worker-styles-integration.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/integrations/class-wp-service-worker-fonts-integration.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/integrations/class-wp-service-worker-admin-assets-integration.php';

/** WordPress Service Worker Functions */
require_once PWA_PLUGIN_DIR . '/wp-includes/service-workers.php';

Expand Down Expand Up @@ -132,6 +116,47 @@ function _pwa_incorrect_plugin_slug_admin_notice() {
/** Hooks to add for when accessing admin. */
require_once PWA_PLUGIN_DIR . '/wp-admin/admin.php';

/**
* Load service worker integrations.
*
* @since 0.2.0
*/
function pwa_load_service_worker_integrations() {
/**
* Filters whether service worker integrations should be enabled.
*
* As these are experimental, they are kept separate from the service worker core code and hidden behind a feature flag.
*
* Instead of using this filter, you can also use a constant `WP_SERVICE_WORKER_INTEGRATIONS_ENABLED`.
*
* @since 0.2
*
* @param bool $enabled Whether or not service worker integrations are enabled.
*/
if ( ! apply_filters( 'wp_service_worker_integrations_enabled', defined( 'WP_SERVICE_WORKER_INTEGRATIONS_ENABLED' ) && WP_SERVICE_WORKER_INTEGRATIONS_ENABLED ) ) {
return;
}
/** WP_Service_Worker_Integration Interface */
require_once PWA_PLUGIN_DIR . '/integrations/interface-wp-service-worker-integration.php';

/** WP_Service_Worker_Base_Integration Class */
require_once PWA_PLUGIN_DIR . '/integrations/class-wp-service-worker-base-integration.php';

/** WP_Service_Worker_Integration Implementation Classes */
require_once PWA_PLUGIN_DIR . '/integrations/class-wp-service-worker-site-icon-integration.php';
require_once PWA_PLUGIN_DIR . '/integrations/class-wp-service-worker-custom-logo-integration.php';
require_once PWA_PLUGIN_DIR . '/integrations/class-wp-service-worker-custom-header-integration.php';
require_once PWA_PLUGIN_DIR . '/integrations/class-wp-service-worker-custom-background-integration.php';
require_once PWA_PLUGIN_DIR . '/integrations/class-wp-service-worker-scripts-integration.php';
require_once PWA_PLUGIN_DIR . '/integrations/class-wp-service-worker-styles-integration.php';
require_once PWA_PLUGIN_DIR . '/integrations/class-wp-service-worker-fonts-integration.php';
require_once PWA_PLUGIN_DIR . '/integrations/class-wp-service-worker-admin-assets-integration.php';

/** WordPress Service Worker Integration Functions */
require_once PWA_PLUGIN_DIR . '/integrations/functions.php';
}
add_action( 'plugins_loaded', 'pwa_load_service_worker_integrations' );

$wp_web_app_manifest = new WP_Web_App_Manifest();
$wp_web_app_manifest->init();

Expand Down
20 changes: 20 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,25 @@ add_action( 'wp_admin_service_worker', 'register_baz_service_worker_script' );

See [labeled GitHub issues](https://github.com/xwp/pwa-wp/issues?q=label%3Aservice-workers) and see WordPress core tracking ticket [#36995](https://core.trac.wordpress.org/ticket/36995).

### Integrations ###
The plugin bundles several experimental integrations that are kept separate from the service worker core code. These integrations act as examples and proof-of-concept to achieve certain goals. While all of them are generally applicable and recommended to truly benefit from service workers, they are not crucial for the core API.

All these integrations are hidden behind a feature flag. To enable them, you can either set a constant `WP_SERVICE_WORKER_INTEGRATIONS_ENABLED` in your `wp-config.php` and set it to true, or add a one-liner must-use plugin:

<pre lang=php>
<?php
/*
Plugin Name: Enable Service Worker Integrations
Plugin URI: https://github.com/xwp/pwa-wp
Description: Enables the experimental service worker integrations in the PWA plugin.
Version: 1.0.0
Author: XWP, Google, and contributors
Author URI: https://github.com/xwp/pwa-wp
*/
add_filter( 'wp_service_worker_integrations_enabled', '__return_true' );
</pre>

### Caching ###
Service Workers in the feature plugin are using [Workbox](https://developers.google.com/web/tools/workbox/) to power a higher-level PHP abstraction for themes and plugins to indicate the routes and the caching strategies in a declarative way. Since only one handler can be used per one route then conflicts are also detected and reported in console when using debug mode.

Expand Down Expand Up @@ -243,6 +262,7 @@ In case of submitting a comment and being offline (failing to fetch) the request
Here is a list of all available actions and filters added by the feature plugin.

**Filters:**
- `wp_service_worker_integrations_enabled`: Filters whether the experimental integrations should be enabled.
- `wp_service_worker_integrations`: Filters the service worker integrations to initialize.
- Has one argument: `$integrations` which is an array of `$slug` => `$integration pairs, where $integration is an instance of a class that implements the WP_Service_Worker_Integration interface.`
- `wp_service_worker_skip_waiting`: Filters whether the service worker should update automatically when a new version is available.
Expand Down
20 changes: 20 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,25 @@ add_action( 'wp_admin_service_worker', 'register_baz_service_worker_script' );

See [labeled GitHub issues](https://github.com/xwp/pwa-wp/issues?q=label%3Aservice-workers) and see WordPress core tracking ticket [#36995](https://core.trac.wordpress.org/ticket/36995).

= Integrations =
The plugin bundles several experimental integrations that are kept separate from the service worker core code. These integrations act as examples and proof-of-concept to achieve certain goals. While all of them are generally applicable and recommended to truly benefit from service workers, they are not crucial for the core API.

All these integrations are hidden behind a feature flag. To enable them, you can either set a constant `WP_SERVICE_WORKER_INTEGRATIONS_ENABLED` in your `wp-config.php` and set it to true, or add a one-liner must-use plugin:

<pre lang=php>
<?php
/*
Plugin Name: Enable Service Worker Integrations
Plugin URI: https://github.com/xwp/pwa-wp
Description: Enables the experimental service worker integrations in the PWA plugin.
Version: 1.0.0
Author: XWP, Google, and contributors
Author URI: https://github.com/xwp/pwa-wp
*/

add_filter( 'wp_service_worker_integrations_enabled', '__return_true' );
</pre>

= Caching =
Service Workers in the feature plugin are using [Workbox](https://developers.google.com/web/tools/workbox/) to power a higher-level PHP abstraction for themes and plugins to indicate the routes and the caching strategies in a declarative way. Since only one handler can be used per one route then conflicts are also detected and reported in console when using debug mode.

Expand Down Expand Up @@ -243,6 +262,7 @@ In case of submitting a comment and being offline (failing to fetch) the request
Here is a list of all available actions and filters added by the feature plugin.

**Filters:**
- `wp_service_worker_integrations_enabled`: Filters whether the experimental integrations should be enabled.
- `wp_service_worker_integrations`: Filters the service worker integrations to initialize.
- Has one argument: `$integrations` which is an array of `$slug` => `$integration pairs, where $integration is an instance of a class that implements the WP_Service_Worker_Integration interface.`
- `wp_service_worker_skip_waiting`: Filters whether the service worker should update automatically when a new version is available.
Expand Down
9 changes: 0 additions & 9 deletions wp-includes/class-wp-service-workers.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,6 @@ public function serve_request() {
/**
* Fires before serving the frontend service worker, when its scripts should be registered, caching routes established, and assets precached.
*
* The following integrations are hooked into this action by default: 'wp-site-icon', 'wp-custom-logo', 'wp-custom-header', 'wp-custom-background',
* 'wp-scripts', 'wp-styles', and 'wp-fonts'. This default behavior can be disabled with code such as the following, for disabling the
* 'wp-custom-header' integration:
*
* add_filter( 'wp_service_worker_integrations', function( $integrations ) {
* unset( $integrations['wp-custom-header'] );
* return $integrations;
* } );
*
* @since 0.2
*
* @param WP_Service_Worker_Scripts $scripts Instance to register service worker behavior with.
Expand Down
1 change: 0 additions & 1 deletion wp-includes/default-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
add_action( 'wp_head', 'wp_add_error_template_no_robots' );
add_filter( 'pre_get_document_title', 'WP_Service_Worker_Navigation_Routing_Component::filter_title_for_streaming_header' );
add_action( 'error_head', 'wp_add_error_template_no_robots' );
add_action( 'wp_default_service_workers', 'wp_default_service_workers' );

add_action( 'admin_init', 'wp_disable_script_concatenation' );

Expand Down
117 changes: 0 additions & 117 deletions wp-includes/service-workers.php
Original file line number Diff line number Diff line change
Expand Up @@ -240,86 +240,6 @@ function wp_service_worker_json_encode( $data ) {
return wp_json_encode( $data, 128 | 64 /* JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES */ );
}

/**
* Registers all default service workers.
*
* @since 0.2
*
* @param WP_Service_Worker_Scripts $scripts Instance to register service worker behavior with.
*/
function wp_default_service_workers( $scripts ) {
$scripts->base_url = site_url();
$scripts->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : '';
$scripts->default_version = get_bloginfo( 'version' );

$integrations = array(
'wp-site-icon' => new WP_Service_Worker_Site_Icon_Integration(),
'wp-custom-logo' => new WP_Service_Worker_Custom_Logo_Integration(),
'wp-custom-header' => new WP_Service_Worker_Custom_Header_Integration(),
'wp-custom-background' => new WP_Service_Worker_Custom_Background_Integration(),
'wp-scripts' => new WP_Service_Worker_Scripts_Integration(),
'wp-styles' => new WP_Service_Worker_Styles_Integration(),
'wp-fonts' => new WP_Service_Worker_Fonts_Integration(),
);

if ( ! SCRIPT_DEBUG ) {
$integrations['wp-admin-assets'] = new WP_Service_Worker_Admin_Assets_Integration();
}

/**
* Filters the service worker integrations to initialize.
*
* @since 0.2
*
* @param array $integrations Array of $slug => $integration pairs, where $integration is an instance
* of a class that implements the WP_Service_Worker_Integration interface.
*/
$integrations = apply_filters( 'wp_service_worker_integrations', $integrations );

foreach ( $integrations as $slug => $integration ) {
if ( ! $integration instanceof WP_Service_Worker_Integration ) {
_doing_it_wrong(
__FUNCTION__,
sprintf(
/* translators: 1: integration slug, 2: interface name */
esc_html__( 'The integration with slug %1$s does not implement the %2$s interface.', 'pwa' ),
esc_html( $slug ),
'WP_Service_Worker_Integration'
),
'0.2'
);
continue;
}

$scope = $integration->get_scope();
$priority = $integration->get_priority();
switch ( $scope ) {
case WP_Service_Workers::SCOPE_FRONT:
add_action( 'wp_front_service_worker', array( $integration, 'register' ), $priority, 1 );
break;
case WP_Service_Workers::SCOPE_ADMIN:
add_action( 'wp_admin_service_worker', array( $integration, 'register' ), $priority, 1 );
break;
case WP_Service_Workers::SCOPE_ALL:
add_action( 'wp_front_service_worker', array( $integration, 'register' ), $priority, 1 );
add_action( 'wp_admin_service_worker', array( $integration, 'register' ), $priority, 1 );
break;
default:
$valid_scopes = array( WP_Service_Workers::SCOPE_FRONT, WP_Service_Workers::SCOPE_ADMIN, WP_Service_Workers::SCOPE_ALL );
_doing_it_wrong(
__FUNCTION__,
sprintf(
/* translators: 1: integration slug, 2: a comma-separated list of valid scopes */
esc_html__( 'Scope for integration %1$s must be one out of %2$s.', 'pwa' ),
esc_html( $slug ),
esc_html( implode( ', ', $valid_scopes ) )
),
'0.1'
);
}
}
}

/**
* Disables concatenating scripts to leverage caching the assets via Service Worker instead.
*/
Expand Down Expand Up @@ -408,40 +328,3 @@ function wp_service_worker_skip_waiting() {
*/
return (bool) apply_filters( 'wp_service_worker_skip_waiting', true );
}

/**
* Get service worker error messages.
*
* @return array Array of error messages: default, comment.
*/
function wp_service_worker_get_error_messages() {
return apply_filters(
'wp_service_worker_error_messages',
array(
'default' => __( 'Please check your internet connection, and try again.', 'pwa' ),
'error' => __( 'Something prevented the page from being rendered. Please try again.', 'pwa' ),
'comment' => __( 'Your comment will be submitted once you are back online!', 'pwa' ),
)
);
}

/**
* Display service worker error details template.
*
* @param string $output Error details template output.
*/
function wp_service_worker_error_details_template( $output = '' ) {
if ( empty( $output ) ) {
$output = '<details id="error-details"><summary>' . esc_html__( 'More Details', 'pwa' ) . '</summary>{{{error_details_iframe}}}</details>';
}
echo '<!--WP_SERVICE_WORKER_ERROR_TEMPLATE_BEGIN-->'; // WPCS: XSS OK.
echo wp_kses_post( $output );
echo '<!--WP_SERVICE_WORKER_ERROR_TEMPLATE_END-->'; // WPCS: XSS OK.
}

/**
* Display service worker error message template tag.
*/
function wp_service_worker_error_message_placeholder() {
echo '<p><!--WP_SERVICE_WORKER_ERROR_MESSAGE--></p>'; // WPCS: XSS OK.
}
Loading

0 comments on commit 351eeec

Please sign in to comment.