Skip to content

Commit

Permalink
Admin: Introduce the Site Health screens.
Browse files Browse the repository at this point in the history
The Site Health tool serves two purposes:
- Provide site owners with information to improve the performance, reliability, and security of their site.
- Collect comprehensive debug information about the site.

By encouraging site owners to maintain their site and adhere to modern best practices, we ultimately improve the software hygeine of both the WordPress ecosystem, and the open internet as a whole.

Props Clorith, hedgefield, melchoyce, xkon, karmatosed, jordesign, earnjam, ianbelanger, wpscholar, desrosj, pedromendonca, peterbooker, jcastaneda, garyj, soean, pento, timothyblynjacobs, zodiac1978, dgroddick, garrett-eclipse, netweb, tobifjellner, pixolin, afercia, joedolson, birgire.
See #46573.


git-svn-id: https://develop.svn.wordpress.org/trunk@44986 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
pento committed Mar 23, 2019
1 parent 7793e67 commit dad6b61
Show file tree
Hide file tree
Showing 13 changed files with 4,430 additions and 0 deletions.
1 change: 1 addition & 0 deletions Gruntfile.js
Expand Up @@ -263,6 +263,7 @@ module.exports = function(grunt) {
[ WORKING_DIR + 'wp-admin/js/tags-box.js' ]: [ './src/js/_enqueues/admin/tags-box.js' ],
[ WORKING_DIR + 'wp-admin/js/tags-suggest.js' ]: [ './src/js/_enqueues/admin/tags-suggest.js' ],
[ WORKING_DIR + 'wp-admin/js/tags.js' ]: [ './src/js/_enqueues/admin/tags.js' ],
[ WORKING_DIR + 'wp-admin/js/site-health.js' ]: [ './src/js/_enqueues/admin/site-health.js' ],
[ WORKING_DIR + 'wp-admin/js/theme-plugin-editor.js' ]: [ './src/js/_enqueues/wp/theme-plugin-editor.js' ],
[ WORKING_DIR + 'wp-admin/js/theme.js' ]: [ './src/js/_enqueues/wp/theme.js' ],
[ WORKING_DIR + 'wp-admin/js/updates.js' ]: [ './src/js/_enqueues/wp/updates.js' ],
Expand Down
229 changes: 229 additions & 0 deletions src/js/_enqueues/admin/site-health.js
@@ -0,0 +1,229 @@
/**
* Interactions used by the Site Health modules in WordPress.
*
* @output wp-admin/js/site-health.js
*/

/* global ajaxurl, SiteHealth, wp */

jQuery( document ).ready( function( $ ) {

var data;

// Debug information copy section.
$( '.health-check-copy-field' ).click( function( e ) {
var $textarea = $( '#system-information-' + $( this ).data( 'copy-field' ) + '-copy-field' ),
$wrapper = $( this ).closest( 'div' );

e.preventDefault();

$textarea.select();

if ( document.execCommand( 'copy' ) ) {
$( '.copy-field-success', $wrapper ).addClass( 'visible' );
$( this ).focus();

wp.a11y.speak( SiteHealth.string.site_info_copied, 'polite' );
}
} );

// Accordion handling in various areas.
$( '.health-check-accordion' ).on( 'click', '.health-check-accordion-trigger', function() {
var isExpanded = ( 'true' === $( this ).attr( 'aria-expanded' ) );

if ( isExpanded ) {
$( this ).attr( 'aria-expanded', 'false' );
$( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', true );
} else {
$( this ).attr( 'aria-expanded', 'true' );
$( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', false );
}
} );

$( '.health-check-accordion' ).on( 'keyup', '.health-check-accordion-trigger', function( e ) {
if ( '38' === e.keyCode.toString() ) {
$( '.health-check-accordion-trigger', $( this ).closest( 'dt' ).prevAll( 'dt' ) ).focus();
} else if ( '40' === e.keyCode.toString() ) {
$( '.health-check-accordion-trigger', $( this ).closest( 'dt' ).nextAll( 'dt' ) ).focus();
}
} );

// Site Health test handling.

$( '.site-health-view-passed' ).on( 'click', function() {
var goodIssuesWrapper = $( '#health-check-issues-good' );

goodIssuesWrapper.toggleClass( 'hidden' );
$( this ).attr( 'aria-expanded', ! goodIssuesWrapper.hasClass( 'hidden' ) );
} );

/**
* Append a new issue to the issue list.
*
* @since 5.2.0
*
* @param {Object} issue The issue data.
*/
function AppendIssue( issue ) {
var template = wp.template( 'health-check-issue' ),
issueWrapper = $( '#health-check-issues-' + issue.status ),
issueCounter = $( '.issue-count', issueWrapper );

SiteHealth.site_status.issues[ issue.status ]++;

issueCounter.text( SiteHealth.site_status.issues[ issue.status ] );
$( '.issues', '#health-check-issues-' + issue.status ).append( template( issue ) );
}

/**
* Update site health status indicator as asynchronous tests are run and returned.
*
* @since 5.2.0
*/
function RecalculateProgression() {
var r, c, pct;
var $progressBar = $( '#progressbar' );
var $circle = $( '#progressbar svg #bar' );
var totalTests = parseInt( SiteHealth.site_status.issues.good, 0 ) + parseInt( SiteHealth.site_status.issues.recommended, 0 ) + ( parseInt( SiteHealth.site_status.issues.critical, 0 ) * 1.5 );
var failedTests = parseInt( SiteHealth.site_status.issues.recommended, 0 ) + ( parseInt( SiteHealth.site_status.issues.critical, 0 ) * 1.5 );
var val = 100 - Math.ceil( ( failedTests / totalTests ) * 100 );

if ( 0 === totalTests ) {
$progressBar.addClass( 'hidden' );
return;
}

$progressBar.removeClass( 'loading' );

r = $circle.attr( 'r' );
c = Math.PI * ( r * 2 );

if ( 0 > val ) {
val = 0;
}
if ( 100 < val ) {
val = 100;
}

pct = ( ( 100 - val ) / 100 ) * c;

$circle.css({ strokeDashoffset: pct } );

if ( 1 > parseInt( SiteHealth.site_status.issues.critical, 0 ) ) {
$( '#health-check-issues-critical' ).addClass( 'hidden' );
}

if ( 1 > parseInt( SiteHealth.site_status.issues.recommended, 0 ) ) {
$( '#health-check-issues-recommended' ).addClass( 'hidden' );
}

if ( 50 <= val ) {
$circle.addClass( 'orange' ).removeClass( 'red' );
}

if ( 90 <= val ) {
$circle.addClass( 'green' ).removeClass( 'orange' );
}

if ( 100 === val ) {
$( '.site-status-all-clear' ).removeClass( 'hide' );
$( '.site-status-has-issues' ).addClass( 'hide' );
}

$progressBar.attr( 'data-pct', val );
$progressBar.attr( 'aria-valuenow', val );

$( '.health-check-body' ).attr( 'aria-hidden', false );

$.post(
ajaxurl,
{
'action': 'health-check-site-status-result',
'_wpnonce': SiteHealth.nonce.site_status_result,
'counts': SiteHealth.site_status.issues
}
);

wp.a11y.speak( SiteHealth.string.site_health_complete_screen_reader.replace( '%s', val + '%' ), 'polite' );
}

/**
* Queue the next asynchronous test when we're ready to run it.
*
* @since 5.2.0
*/
function maybeRunNextAsyncTest() {
var doCalculation = true;

if ( 1 <= SiteHealth.site_status.async.length ) {
$.each( SiteHealth.site_status.async, function() {
var data = {
'action': 'health-check-' + this.test.replace( '_', '-' ),
'_wpnonce': SiteHealth.nonce.site_status
};

if ( this.completed ) {
return true;
}

doCalculation = false;

this.completed = true;

$.post(
ajaxurl,
data,
function( response ) {
AppendIssue( response.data );
maybeRunNextAsyncTest();
}
);

return false;
} );
}

if ( doCalculation ) {
RecalculateProgression();
}
}

if ( 'undefined' !== typeof SiteHealth ) {
if ( 0 === SiteHealth.site_status.direct.length && 0 === SiteHealth.site_status.async.length ) {
RecalculateProgression();
} else {
SiteHealth.site_status.issues = {
'good': 0,
'recommended': 0,
'critical': 0
};
}

if ( 0 < SiteHealth.site_status.direct.length ) {
$.each( SiteHealth.site_status.direct, function() {
AppendIssue( this );
} );
}

if ( 0 < SiteHealth.site_status.async.length ) {
data = {
'action': 'health-check-' + SiteHealth.site_status.async[0].test.replace( '_', '-' ),
'_wpnonce': SiteHealth.nonce.site_status
};

SiteHealth.site_status.async[0].completed = true;

$.post(
ajaxurl,
data,
function( response ) {
AppendIssue( response.data );
maybeRunNextAsyncTest();
}
);
} else {
RecalculateProgression();
}
}

} );
5 changes: 5 additions & 0 deletions src/wp-admin/admin-ajax.php
Expand Up @@ -131,6 +131,11 @@
'edit-theme-plugin-file',
'wp-privacy-export-personal-data',
'wp-privacy-erase-personal-data',
'health-check-site-status-result',
'health-check-dotorg-communication',
'health-check-is-in-debug-mode',
'health-check-background-updates',
'health-check-loopback-requests',
);

// Deprecated
Expand Down

0 comments on commit dad6b61

Please sign in to comment.