[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 /** 2 * Interactions used by the User Privacy tools in WordPress. 3 * 4 * @output wp-admin/js/privacy-tools.js 5 */ 6 7 // Privacy request action handling. 8 jQuery( function( $ ) { 9 var __ = wp.i18n.__, 10 copiedNoticeTimeout; 11 12 function setActionState( $action, state ) { 13 $action.children().addClass( 'hidden' ); 14 $action.children( '.' + state ).removeClass( 'hidden' ); 15 } 16 17 function clearResultsAfterRow( $requestRow ) { 18 $requestRow.removeClass( 'has-request-results' ); 19 20 if ( $requestRow.next().hasClass( 'request-results' ) ) { 21 $requestRow.next().remove(); 22 } 23 } 24 25 function appendResultsAfterRow( $requestRow, classes, summaryMessage, additionalMessages ) { 26 var itemList = '', 27 resultRowClasses = 'request-results'; 28 29 clearResultsAfterRow( $requestRow ); 30 31 if ( additionalMessages.length ) { 32 $.each( additionalMessages, function( index, value ) { 33 itemList = itemList + '<li>' + value + '</li>'; 34 }); 35 itemList = '<ul>' + itemList + '</ul>'; 36 } 37 38 $requestRow.addClass( 'has-request-results' ); 39 40 if ( $requestRow.hasClass( 'status-request-confirmed' ) ) { 41 resultRowClasses = resultRowClasses + ' status-request-confirmed'; 42 } 43 44 if ( $requestRow.hasClass( 'status-request-failed' ) ) { 45 resultRowClasses = resultRowClasses + ' status-request-failed'; 46 } 47 48 $requestRow.after( function() { 49 return '<tr class="' + resultRowClasses + '"><th colspan="5">' + 50 '<div class="notice inline notice-alt ' + classes + '">' + 51 '<p>' + summaryMessage + '</p>' + 52 itemList + 53 '</div>' + 54 '</td>' + 55 '</tr>'; 56 }); 57 } 58 59 $( '.export-personal-data-handle' ).on( 'click', function( event ) { 60 var $this = $( this ), 61 $action = $this.parents( '.export-personal-data' ), 62 $requestRow = $this.parents( 'tr' ), 63 $progress = $requestRow.find( '.export-progress' ), 64 $rowActions = $this.parents( '.row-actions' ), 65 requestID = $action.data( 'request-id' ), 66 nonce = $action.data( 'nonce' ), 67 exportersCount = $action.data( 'exporters-count' ), 68 sendAsEmail = $action.data( 'send-as-email' ) ? true : false; 69 70 event.preventDefault(); 71 event.stopPropagation(); 72 73 $rowActions.addClass( 'processing' ); 74 75 $action.trigger( 'blur' ); 76 clearResultsAfterRow( $requestRow ); 77 setExportProgress( 0 ); 78 79 function onExportDoneSuccess( zipUrl ) { 80 var summaryMessage = __( 'This user’s personal data export link was sent.' ); 81 82 if ( 'undefined' !== typeof zipUrl ) { 83 summaryMessage = __( 'This user’s personal data export file was downloaded.' ); 84 } 85 86 setActionState( $action, 'export-personal-data-success' ); 87 88 appendResultsAfterRow( $requestRow, 'notice-success', summaryMessage, [] ); 89 90 if ( 'undefined' !== typeof zipUrl ) { 91 window.location = zipUrl; 92 } else if ( ! sendAsEmail ) { 93 onExportFailure( __( 'No personal data export file was generated.' ) ); 94 } 95 96 setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 ); 97 } 98 99 function onExportFailure( errorMessage ) { 100 var summaryMessage = __( 'An error occurred while attempting to export personal data.' ); 101 102 setActionState( $action, 'export-personal-data-failed' ); 103 104 if ( errorMessage ) { 105 appendResultsAfterRow( $requestRow, 'notice-error', summaryMessage, [ errorMessage ] ); 106 } 107 108 setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 ); 109 } 110 111 function setExportProgress( exporterIndex ) { 112 var progress = ( exportersCount > 0 ? exporterIndex / exportersCount : 0 ), 113 progressString = Math.round( progress * 100 ).toString() + '%'; 114 115 $progress.html( progressString ); 116 } 117 118 function doNextExport( exporterIndex, pageIndex ) { 119 $.ajax( 120 { 121 url: window.ajaxurl, 122 data: { 123 action: 'wp-privacy-export-personal-data', 124 exporter: exporterIndex, 125 id: requestID, 126 page: pageIndex, 127 security: nonce, 128 sendAsEmail: sendAsEmail 129 }, 130 method: 'post' 131 } 132 ).done( function( response ) { 133 var responseData = response.data; 134 135 if ( ! response.success ) { 136 // e.g. invalid request ID. 137 setTimeout( function() { onExportFailure( response.data ); }, 500 ); 138 return; 139 } 140 141 if ( ! responseData.done ) { 142 setTimeout( doNextExport( exporterIndex, pageIndex + 1 ) ); 143 } else { 144 setExportProgress( exporterIndex ); 145 if ( exporterIndex < exportersCount ) { 146 setTimeout( doNextExport( exporterIndex + 1, 1 ) ); 147 } else { 148 setTimeout( function() { onExportDoneSuccess( responseData.url ); }, 500 ); 149 } 150 } 151 }).fail( function( jqxhr, textStatus, error ) { 152 // e.g. Nonce failure. 153 setTimeout( function() { onExportFailure( error ); }, 500 ); 154 }); 155 } 156 157 // And now, let's begin. 158 setActionState( $action, 'export-personal-data-processing' ); 159 doNextExport( 1, 1 ); 160 }); 161 162 $( '.remove-personal-data-handle' ).on( 'click', function( event ) { 163 var $this = $( this ), 164 $action = $this.parents( '.remove-personal-data' ), 165 $requestRow = $this.parents( 'tr' ), 166 $progress = $requestRow.find( '.erasure-progress' ), 167 $rowActions = $this.parents( '.row-actions' ), 168 requestID = $action.data( 'request-id' ), 169 nonce = $action.data( 'nonce' ), 170 erasersCount = $action.data( 'erasers-count' ), 171 hasRemoved = false, 172 hasRetained = false, 173 messages = []; 174 175 event.preventDefault(); 176 event.stopPropagation(); 177 178 $rowActions.addClass( 'processing' ); 179 180 $action.trigger( 'blur' ); 181 clearResultsAfterRow( $requestRow ); 182 setErasureProgress( 0 ); 183 184 function onErasureDoneSuccess() { 185 var summaryMessage = __( 'No personal data was found for this user.' ), 186 classes = 'notice-success'; 187 188 setActionState( $action, 'remove-personal-data-success' ); 189 190 if ( false === hasRemoved ) { 191 if ( false === hasRetained ) { 192 summaryMessage = __( 'No personal data was found for this user.' ); 193 } else { 194 summaryMessage = __( 'Personal data was found for this user but was not erased.' ); 195 classes = 'notice-warning'; 196 } 197 } else { 198 if ( false === hasRetained ) { 199 summaryMessage = __( 'All of the personal data found for this user was erased.' ); 200 } else { 201 summaryMessage = __( 'Personal data was found for this user but some of the personal data found was not erased.' ); 202 classes = 'notice-warning'; 203 } 204 } 205 appendResultsAfterRow( $requestRow, classes, summaryMessage, messages ); 206 207 setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 ); 208 } 209 210 function onErasureFailure() { 211 var summaryMessage = __( 'An error occurred while attempting to find and erase personal data.' ); 212 213 setActionState( $action, 'remove-personal-data-failed' ); 214 215 appendResultsAfterRow( $requestRow, 'notice-error', summaryMessage, [] ); 216 217 setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 ); 218 } 219 220 function setErasureProgress( eraserIndex ) { 221 var progress = ( erasersCount > 0 ? eraserIndex / erasersCount : 0 ), 222 progressString = Math.round( progress * 100 ).toString() + '%'; 223 224 $progress.html( progressString ); 225 } 226 227 function doNextErasure( eraserIndex, pageIndex ) { 228 $.ajax({ 229 url: window.ajaxurl, 230 data: { 231 action: 'wp-privacy-erase-personal-data', 232 eraser: eraserIndex, 233 id: requestID, 234 page: pageIndex, 235 security: nonce 236 }, 237 method: 'post' 238 }).done( function( response ) { 239 var responseData = response.data; 240 241 if ( ! response.success ) { 242 setTimeout( function() { onErasureFailure(); }, 500 ); 243 return; 244 } 245 if ( responseData.items_removed ) { 246 hasRemoved = hasRemoved || responseData.items_removed; 247 } 248 if ( responseData.items_retained ) { 249 hasRetained = hasRetained || responseData.items_retained; 250 } 251 if ( responseData.messages ) { 252 messages = messages.concat( responseData.messages ); 253 } 254 if ( ! responseData.done ) { 255 setTimeout( doNextErasure( eraserIndex, pageIndex + 1 ) ); 256 } else { 257 setErasureProgress( eraserIndex ); 258 if ( eraserIndex < erasersCount ) { 259 setTimeout( doNextErasure( eraserIndex + 1, 1 ) ); 260 } else { 261 setTimeout( function() { onErasureDoneSuccess(); }, 500 ); 262 } 263 } 264 }).fail( function() { 265 setTimeout( function() { onErasureFailure(); }, 500 ); 266 }); 267 } 268 269 // And now, let's begin. 270 setActionState( $action, 'remove-personal-data-processing' ); 271 272 doNextErasure( 1, 1 ); 273 }); 274 275 // Privacy Policy page, copy action. 276 $( document ).on( 'click', function( event ) { 277 var $parent, 278 range, 279 $target = $( event.target ), 280 copiedNotice = $target.siblings( '.success' ); 281 282 clearTimeout( copiedNoticeTimeout ); 283 284 if ( $target.is( 'button.privacy-text-copy' ) ) { 285 $parent = $target.closest( '.privacy-settings-accordion-panel' ); 286 287 if ( $parent.length ) { 288 try { 289 var documentPosition = document.documentElement.scrollTop, 290 bodyPosition = document.body.scrollTop; 291 292 // Setup copy. 293 window.getSelection().removeAllRanges(); 294 295 // Hide tutorial content to remove from copied content. 296 range = document.createRange(); 297 $parent.addClass( 'hide-privacy-policy-tutorial' ); 298 299 // Copy action. 300 range.selectNodeContents( $parent[0] ); 301 window.getSelection().addRange( range ); 302 document.execCommand( 'copy' ); 303 304 // Reset section. 305 $parent.removeClass( 'hide-privacy-policy-tutorial' ); 306 window.getSelection().removeAllRanges(); 307 308 // Return scroll position - see #49540. 309 if ( documentPosition > 0 && documentPosition !== document.documentElement.scrollTop ) { 310 document.documentElement.scrollTop = documentPosition; 311 } else if ( bodyPosition > 0 && bodyPosition !== document.body.scrollTop ) { 312 document.body.scrollTop = bodyPosition; 313 } 314 315 // Display and speak notice to indicate action complete. 316 copiedNotice.addClass( 'visible' ); 317 wp.a11y.speak( __( 'The suggested policy text has been copied to your clipboard.' ) ); 318 319 // Delay notice dismissal. 320 copiedNoticeTimeout = setTimeout( function() { 321 copiedNotice.removeClass( 'visible' ); 322 }, 3000 ); 323 } catch ( er ) {} 324 } 325 } 326 }); 327 328 // Label handling to focus the create page button on Privacy settings page. 329 $( 'body.options-privacy-php label[for=create-page]' ).on( 'click', function( e ) { 330 e.preventDefault(); 331 $( 'input#create-page' ).trigger( 'focus' ); 332 } ); 333 334 // Accordion handling in various new Privacy settings pages. 335 $( '.privacy-settings-accordion' ).on( 'click', '.privacy-settings-accordion-trigger', function() { 336 var isExpanded = ( 'true' === $( this ).attr( 'aria-expanded' ) ); 337 338 if ( isExpanded ) { 339 $( this ).attr( 'aria-expanded', 'false' ); 340 $( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', true ); 341 } else { 342 $( this ).attr( 'aria-expanded', 'true' ); 343 $( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', false ); 344 } 345 } ); 346 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Dec 25 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |