8 |
8 |
9 jQuery( document ).ready( function( $ ) { |
9 jQuery( document ).ready( function( $ ) { |
10 |
10 |
11 var __ = wp.i18n.__, |
11 var __ = wp.i18n.__, |
12 _n = wp.i18n._n, |
12 _n = wp.i18n._n, |
13 sprintf = wp.i18n.sprintf; |
13 sprintf = wp.i18n.sprintf, |
14 |
14 data, |
15 var data; |
15 clipboard = new ClipboardJS( '.site-health-copy-buttons .copy-button' ), |
16 var clipboard = new ClipboardJS( '.site-health-copy-buttons .copy-button' ); |
16 isDebugTab = $( '.health-check-body.health-check-debug-tab' ).length, |
17 var isDebugTab = $( '.health-check-body.health-check-debug-tab' ).length; |
17 pathsSizesSection = $( '#health-check-accordion-block-wp-paths-sizes' ), |
18 var pathsSizesSection = $( '#health-check-accordion-block-wp-paths-sizes' ); |
18 successTimeout; |
19 |
19 |
20 // Debug information copy section. |
20 // Debug information copy section. |
21 clipboard.on( 'success', function( e ) { |
21 clipboard.on( 'success', function( e ) { |
22 var $wrapper = $( e.trigger ).closest( 'div' ); |
22 var triggerElement = $( e.trigger ), |
23 $( '.success', $wrapper ).addClass( 'visible' ); |
23 successElement = $( '.success', triggerElement.closest( 'div' ) ); |
24 |
24 |
25 wp.a11y.speak( __( 'Site information has been added to your clipboard.' ) ); |
25 // Clear the selection and move focus back to the trigger. |
|
26 e.clearSelection(); |
|
27 // Handle ClipboardJS focus bug, see https://github.com/zenorocha/clipboard.js/issues/680 |
|
28 triggerElement.focus(); |
|
29 |
|
30 // Show success visual feedback. |
|
31 clearTimeout( successTimeout ); |
|
32 successElement.removeClass( 'hidden' ); |
|
33 |
|
34 // Hide success visual feedback after 3 seconds since last success. |
|
35 successTimeout = setTimeout( function() { |
|
36 successElement.addClass( 'hidden' ); |
|
37 // Remove the visually hidden textarea so that it isn't perceived by assistive technologies. |
|
38 if ( clipboard.clipboardAction.fakeElem && clipboard.clipboardAction.removeFake ) { |
|
39 clipboard.clipboardAction.removeFake(); |
|
40 } |
|
41 }, 3000 ); |
|
42 |
|
43 // Handle success audible feedback. |
|
44 wp.a11y.speak( __( 'Site information has been copied to your clipboard.' ) ); |
26 } ); |
45 } ); |
27 |
46 |
28 // Accordion handling in various areas. |
47 // Accordion handling in various areas. |
29 $( '.health-check-accordion' ).on( 'click', '.health-check-accordion-trigger', function() { |
48 $( '.health-check-accordion' ).on( 'click', '.health-check-accordion-trigger', function() { |
30 var isExpanded = ( 'true' === $( this ).attr( 'aria-expanded' ) ); |
49 var isExpanded = ( 'true' === $( this ).attr( 'aria-expanded' ) ); |
46 goodIssuesWrapper.toggleClass( 'hidden' ); |
65 goodIssuesWrapper.toggleClass( 'hidden' ); |
47 $( this ).attr( 'aria-expanded', ! goodIssuesWrapper.hasClass( 'hidden' ) ); |
66 $( this ).attr( 'aria-expanded', ! goodIssuesWrapper.hasClass( 'hidden' ) ); |
48 } ); |
67 } ); |
49 |
68 |
50 /** |
69 /** |
51 * Append a new issue to the issue list. |
70 * Appends a new issue to the issue list. |
52 * |
71 * |
53 * @since 5.2.0 |
72 * @since 5.2.0 |
54 * |
73 * |
55 * @param {Object} issue The issue data. |
74 * @param {Object} issue The issue data. |
56 */ |
75 */ |
57 function AppendIssue( issue ) { |
76 function appendIssue( issue ) { |
58 var template = wp.template( 'health-check-issue' ), |
77 var template = wp.template( 'health-check-issue' ), |
59 issueWrapper = $( '#health-check-issues-' + issue.status ), |
78 issueWrapper = $( '#health-check-issues-' + issue.status ), |
60 heading, |
79 heading, |
61 count; |
80 count; |
62 |
81 |
63 SiteHealth.site_status.issues[ issue.status ]++; |
82 SiteHealth.site_status.issues[ issue.status ]++; |
64 |
83 |
65 count = SiteHealth.site_status.issues[ issue.status ]; |
84 count = SiteHealth.site_status.issues[ issue.status ]; |
66 |
85 |
67 if ( 'critical' === issue.status ) { |
86 if ( 'critical' === issue.status ) { |
68 heading = sprintf( _n( '%s Critical issue', '%s Critical issues', count ), '<span class="issue-count">' + count + '</span>' ); |
87 heading = sprintf( |
|
88 _n( '%s critical issue', '%s critical issues', count ), |
|
89 '<span class="issue-count">' + count + '</span>' |
|
90 ); |
69 } else if ( 'recommended' === issue.status ) { |
91 } else if ( 'recommended' === issue.status ) { |
70 heading = sprintf( _n( '%s Recommended improvement', '%s Recommended improvements', count ), '<span class="issue-count">' + count + '</span>' ); |
92 heading = sprintf( |
|
93 _n( '%s recommended improvement', '%s recommended improvements', count ), |
|
94 '<span class="issue-count">' + count + '</span>' |
|
95 ); |
71 } else if ( 'good' === issue.status ) { |
96 } else if ( 'good' === issue.status ) { |
72 heading = sprintf( _n( '%s Item with no issues detected', '%s Items with no issues detected', count ), '<span class="issue-count">' + count + '</span>' ); |
97 heading = sprintf( |
|
98 _n( '%s item with no issues detected', '%s items with no issues detected', count ), |
|
99 '<span class="issue-count">' + count + '</span>' |
|
100 ); |
73 } |
101 } |
74 |
102 |
75 if ( heading ) { |
103 if ( heading ) { |
76 $( '.site-health-issue-count-title', issueWrapper ).html( heading ); |
104 $( '.site-health-issue-count-title', issueWrapper ).html( heading ); |
77 } |
105 } |
78 |
106 |
79 $( '.issues', '#health-check-issues-' + issue.status ).append( template( issue ) ); |
107 $( '.issues', '#health-check-issues-' + issue.status ).append( template( issue ) ); |
80 } |
108 } |
81 |
109 |
82 /** |
110 /** |
83 * Update site health status indicator as asynchronous tests are run and returned. |
111 * Updates site health status indicator as asynchronous tests are run and returned. |
84 * |
112 * |
85 * @since 5.2.0 |
113 * @since 5.2.0 |
86 */ |
114 */ |
87 function RecalculateProgression() { |
115 function recalculateProgression() { |
88 var r, c, pct; |
116 var r, c, pct; |
89 var $progress = $( '.site-health-progress' ); |
117 var $progress = $( '.site-health-progress' ); |
90 var $progressCount = $progress.find( '.site-health-progress-count' ); |
118 var $wrapper = $progress.closest( '.site-health-progress-wrapper' ); |
|
119 var $progressLabel = $( '.site-health-progress-label', $wrapper ); |
91 var $circle = $( '.site-health-progress svg #bar' ); |
120 var $circle = $( '.site-health-progress svg #bar' ); |
92 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 ); |
121 var totalTests = parseInt( SiteHealth.site_status.issues.good, 0 ) + |
93 var failedTests = parseInt( SiteHealth.site_status.issues.recommended, 0 ) + ( parseInt( SiteHealth.site_status.issues.critical, 0 ) * 1.5 ); |
122 parseInt( SiteHealth.site_status.issues.recommended, 0 ) + |
|
123 ( parseInt( SiteHealth.site_status.issues.critical, 0 ) * 1.5 ); |
|
124 var failedTests = ( parseInt( SiteHealth.site_status.issues.recommended, 0 ) * 0.5 ) + |
|
125 ( parseInt( SiteHealth.site_status.issues.critical, 0 ) * 1.5 ); |
94 var val = 100 - Math.ceil( ( failedTests / totalTests ) * 100 ); |
126 var val = 100 - Math.ceil( ( failedTests / totalTests ) * 100 ); |
95 |
127 |
96 if ( 0 === totalTests ) { |
128 if ( 0 === totalTests ) { |
97 $progress.addClass( 'hidden' ); |
129 $progress.addClass( 'hidden' ); |
98 return; |
130 return; |
99 } |
131 } |
100 |
132 |
101 $progress.removeClass( 'loading' ); |
133 $wrapper.removeClass( 'loading' ); |
102 |
134 |
103 r = $circle.attr( 'r' ); |
135 r = $circle.attr( 'r' ); |
104 c = Math.PI * ( r * 2 ); |
136 c = Math.PI * ( r * 2 ); |
105 |
137 |
106 if ( 0 > val ) { |
138 if ( 0 > val ) { |
120 |
152 |
121 if ( 1 > parseInt( SiteHealth.site_status.issues.recommended, 0 ) ) { |
153 if ( 1 > parseInt( SiteHealth.site_status.issues.recommended, 0 ) ) { |
122 $( '#health-check-issues-recommended' ).addClass( 'hidden' ); |
154 $( '#health-check-issues-recommended' ).addClass( 'hidden' ); |
123 } |
155 } |
124 |
156 |
125 if ( 50 <= val ) { |
157 if ( 80 <= val && 0 === parseInt( SiteHealth.site_status.issues.critical, 0 ) ) { |
126 $circle.addClass( 'orange' ).removeClass( 'red' ); |
158 $wrapper.addClass( 'green' ).removeClass( 'orange' ); |
127 } |
159 |
128 |
160 $progressLabel.text( __( 'Good' ) ); |
129 if ( 90 <= val ) { |
161 wp.a11y.speak( __( 'All site health tests have finished running. Your site is looking good, and the results are now available on the page.' ) ); |
130 $circle.addClass( 'green' ).removeClass( 'orange' ); |
162 } else { |
131 } |
163 $wrapper.addClass( 'orange' ).removeClass( 'green' ); |
132 |
164 |
133 if ( 100 === val ) { |
165 $progressLabel.text( __( 'Should be improved' ) ); |
134 $( '.site-status-all-clear' ).removeClass( 'hide' ); |
166 wp.a11y.speak( __( 'All site health tests have finished running. There are items that should be addressed, and the results are now available on the page.' ) ); |
135 $( '.site-status-has-issues' ).addClass( 'hide' ); |
167 } |
136 } |
|
137 |
|
138 $progressCount.text( val + '%' ); |
|
139 |
168 |
140 if ( ! isDebugTab ) { |
169 if ( ! isDebugTab ) { |
141 $.post( |
170 $.post( |
142 ajaxurl, |
171 ajaxurl, |
143 { |
172 { |
180 |
208 |
181 $.post( |
209 $.post( |
182 ajaxurl, |
210 ajaxurl, |
183 data, |
211 data, |
184 function( response ) { |
212 function( response ) { |
185 AppendIssue( response.data ); |
213 /** This filter is documented in wp-admin/includes/class-wp-site-health.php */ |
|
214 appendIssue( wp.hooks.applyFilters( 'site_status_test_result', response.data ) ); |
186 maybeRunNextAsyncTest(); |
215 maybeRunNextAsyncTest(); |
187 } |
216 } |
188 ); |
217 ); |
189 |
218 |
190 return false; |
219 return false; |
191 } ); |
220 } ); |
192 } |
221 } |
193 |
222 |
194 if ( doCalculation ) { |
223 if ( doCalculation ) { |
195 RecalculateProgression(); |
224 recalculateProgression(); |
196 } |
225 } |
197 } |
226 } |
198 |
227 |
199 if ( 'undefined' !== typeof SiteHealth && ! isDebugTab ) { |
228 if ( 'undefined' !== typeof SiteHealth && ! isDebugTab ) { |
200 if ( 0 === SiteHealth.site_status.direct.length && 0 === SiteHealth.site_status.async.length ) { |
229 if ( 0 === SiteHealth.site_status.direct.length && 0 === SiteHealth.site_status.async.length ) { |
201 RecalculateProgression(); |
230 recalculateProgression(); |
202 } else { |
231 } else { |
203 SiteHealth.site_status.issues = { |
232 SiteHealth.site_status.issues = { |
204 'good': 0, |
233 'good': 0, |
205 'recommended': 0, |
234 'recommended': 0, |
206 'critical': 0 |
235 'critical': 0 |
207 }; |
236 }; |
208 } |
237 } |
209 |
238 |
210 if ( 0 < SiteHealth.site_status.direct.length ) { |
239 if ( 0 < SiteHealth.site_status.direct.length ) { |
211 $.each( SiteHealth.site_status.direct, function() { |
240 $.each( SiteHealth.site_status.direct, function() { |
212 AppendIssue( this ); |
241 appendIssue( this ); |
213 } ); |
242 } ); |
214 } |
243 } |
215 |
244 |
216 if ( 0 < SiteHealth.site_status.async.length ) { |
245 if ( 0 < SiteHealth.site_status.async.length ) { |
217 data = { |
246 data = { |
256 updateDirSizes( response.data || {} ); |
285 updateDirSizes( response.data || {} ); |
257 } ).always( function() { |
286 } ).always( function() { |
258 var delay = ( new Date().getTime() ) - timestamp; |
287 var delay = ( new Date().getTime() ) - timestamp; |
259 |
288 |
260 $( '.health-check-wp-paths-sizes.spinner' ).css( 'visibility', 'hidden' ); |
289 $( '.health-check-wp-paths-sizes.spinner' ).css( 'visibility', 'hidden' ); |
261 RecalculateProgression(); |
290 recalculateProgression(); |
262 |
291 |
263 if ( delay > 3000 ) { |
292 if ( delay > 3000 ) { |
264 // We have announced that we're waiting. |
293 /* |
265 // Announce that we're ready after giving at least 3 seconds for the first announcement |
294 * We have announced that we're waiting. |
266 // to be read out, or the two may collide. |
295 * Announce that we're ready after giving at least 3 seconds |
|
296 * for the first announcement to be read out, or the two may collide. |
|
297 */ |
267 if ( delay > 6000 ) { |
298 if ( delay > 6000 ) { |
268 delay = 0; |
299 delay = 0; |
269 } else { |
300 } else { |
270 delay = 6500 - delay; |
301 delay = 6500 - delay; |
271 } |
302 } |
282 } ); |
313 } ); |
283 } |
314 } |
284 |
315 |
285 function updateDirSizes( data ) { |
316 function updateDirSizes( data ) { |
286 var copyButton = $( 'button.button.copy-button' ); |
317 var copyButton = $( 'button.button.copy-button' ); |
287 var clipdoardText = copyButton.attr( 'data-clipboard-text' ); |
318 var clipboardText = copyButton.attr( 'data-clipboard-text' ); |
288 |
319 |
289 $.each( data, function( name, value ) { |
320 $.each( data, function( name, value ) { |
290 var text = value.debug || value.size; |
321 var text = value.debug || value.size; |
291 |
322 |
292 if ( typeof text !== 'undefined' ) { |
323 if ( typeof text !== 'undefined' ) { |
293 clipdoardText = clipdoardText.replace( name + ': loading...', name + ': ' + text ); |
324 clipboardText = clipboardText.replace( name + ': loading...', name + ': ' + text ); |
294 } |
325 } |
295 } ); |
326 } ); |
296 |
327 |
297 copyButton.attr( 'data-clipboard-text', clipdoardText ); |
328 copyButton.attr( 'data-clipboard-text', clipboardText ); |
298 |
329 |
299 pathsSizesSection.find( 'td[class]' ).each( function( i, element ) { |
330 pathsSizesSection.find( 'td[class]' ).each( function( i, element ) { |
300 var td = $( element ); |
331 var td = $( element ); |
301 var name = td.attr( 'class' ); |
332 var name = td.attr( 'class' ); |
302 |
333 |