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

Add page reloading in offline.php templates #697

Merged
merged 8 commits into from
Feb 24, 2022
44 changes: 44 additions & 0 deletions wp-includes/template.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,47 @@ function wp_service_worker_error_details_template( $output = '' ) {
function wp_service_worker_error_message_placeholder() {
echo '<p><!--WP_SERVICE_WORKER_ERROR_MESSAGE--></p>';
}

/**
* Reload the offline page and check if user comes online.
*
* @since 0.7
*/
function wp_service_worker_offline_page_reload() {
if ( ! is_offline() ) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be useful to also do the reload in the case of server being down.

Also, something else that comes to mind: what happens if the error page is served in response to a POST request? If so, each reload will cause a re-POST message from the browser and that's probably not desired.

Suggested change
if ( ! is_offline() ) {
if ( ! is_offline() || ! is_500() || 'GET' !== $_SERVER['REQUEST_METHOD'] ) {

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for pointing this out. For sure we need to check the method of the request. I have implemented these changes.

Copy link
Collaborator

Choose a reason for hiding this comment

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

As part of #728, I just realized that this check will never do anything:

if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'GET' !== $_SERVER['REQUEST_METHOD'] ) {
return;
}

This is because the offline template is always fetched via a GET request by the service worker when it is installing, so it will never not be GET. We need an alternative way of preventing the code from running on responses to non-GET requests.

Contrary to what I thought above, each reload does not cause the browser re-POST message: #728 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe I've addressed this via #763

Copy link
Collaborator

Choose a reason for hiding this comment

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

See #763

return;
}
?>
<script>
thelovekesh marked this conversation as resolved.
Show resolved Hide resolved
/**
* Listen to changes in the network state, reload when online.
* This handles the case when the device is completely offline.
*/
window.addEventListener('online', () => {
window.location.reload();
});

/**
* Check if the server is responding and reload the page if it is.
* This handles the case when the device is online, but the server is offline or misbehaving.
*/
async function checkNetworkAndReload() {
try {
const response = await fetch('.', {method: 'HEAD'});
thelovekesh marked this conversation as resolved.
Show resolved Hide resolved
// Verify we get a valid response from the server
if (response.status >= 200 && response.status < 500) {
window.location.reload();
return;
}
} catch {
console.log('User is offline');
}
window.setTimeout(checkNetworkAndReload, 2500);
thelovekesh marked this conversation as resolved.
Show resolved Hide resolved
}
checkNetworkAndReload();
thelovekesh marked this conversation as resolved.
Show resolved Hide resolved
</script>
<?php
}

add_action( 'wp_footer', 'wp_service_worker_offline_page_reload' );
add_action( 'error_footer', 'wp_service_worker_offline_page_reload' );