diff --git a/src/js/_enqueues/admin/application-passwords.js b/src/js/_enqueues/admin/application-passwords.js index c79cdb8b4037f..e69de29bb2d1d 100644 --- a/src/js/_enqueues/admin/application-passwords.js +++ b/src/js/_enqueues/admin/application-passwords.js @@ -1,219 +0,0 @@ -/** - * @output wp-admin/js/application-passwords.js - */ - -( function( $ ) { - var $appPassSection = $( '#application-passwords-section' ), - $newAppPassForm = $appPassSection.find( '.create-application-password' ), - $newAppPassField = $newAppPassForm.find( '.input' ), - $newAppPassButton = $newAppPassForm.find( '.button' ), - $appPassTwrapper = $appPassSection.find( '.application-passwords-list-table-wrapper' ), - $appPassTbody = $appPassSection.find( 'tbody' ), - $appPassTrNoItems = $appPassTbody.find( '.no-items' ), - $removeAllBtn = $( '#revoke-all-application-passwords' ), - tmplNewAppPass = wp.template( 'new-application-password' ), - tmplAppPassRow = wp.template( 'application-password-row' ), - userId = $( '#user_id' ).val(); - - $newAppPassButton.on( 'click', function( e ) { - e.preventDefault(); - - if ( $newAppPassButton.prop( 'aria-disabled' ) ) { - return; - } - - var name = $newAppPassField.val(); - - if ( 0 === name.length ) { - $newAppPassField.trigger( 'focus' ); - return; - } - - clearNotices(); - $newAppPassButton.prop( 'aria-disabled', true ).addClass( 'disabled' ); - - var request = { - name: name - }; - - /** - * Filters the request data used to create a new Application Password. - * - * @since 5.6.0 - * - * @param {Object} request The request data. - * @param {number} userId The id of the user the password is added for. - */ - request = wp.hooks.applyFilters( 'wp_application_passwords_new_password_request', request, userId ); - - wp.apiRequest( { - path: '/wp/v2/users/' + userId + '/application-passwords?_locale=user', - method: 'POST', - data: request - } ).always( function() { - $newAppPassButton.removeProp( 'aria-disabled' ).removeClass( 'disabled' ); - } ).done( function( response ) { - $newAppPassField.val( '' ); - $newAppPassButton.prop( 'disabled', false ); - - $newAppPassForm.after( tmplNewAppPass( { - name: response.name, - password: response.password - } ) ); - $( '.new-application-password-notice' ).attr( 'tabindex', '-1' ).trigger( 'focus' ); - - $appPassTbody.prepend( tmplAppPassRow( response ) ); - - $appPassTwrapper.show(); - $appPassTrNoItems.remove(); - - /** - * Fires after an application password has been successfully created. - * - * @since 5.6.0 - * - * @param {Object} response The response data from the REST API. - * @param {Object} request The request data used to create the password. - */ - wp.hooks.doAction( 'wp_application_passwords_created_password', response, request ); - } ).fail( handleErrorResponse ); - } ); - - $appPassTbody.on( 'click', '.delete', function( e ) { - e.preventDefault(); - - if ( ! window.confirm( wp.i18n.__( 'Are you sure you want to revoke this password? This action cannot be undone.' ) ) ) { - return; - } - - var $submitButton = $( this ), - $tr = $submitButton.closest( 'tr' ), - uuid = $tr.data( 'uuid' ); - - clearNotices(); - $submitButton.prop( 'disabled', true ); - - wp.apiRequest( { - path: '/wp/v2/users/' + userId + '/application-passwords/' + uuid + '?_locale=user', - method: 'DELETE' - } ).always( function() { - $submitButton.prop( 'disabled', false ); - } ).done( function( response ) { - if ( response.deleted ) { - if ( 0 === $tr.siblings().length ) { - $appPassTwrapper.hide(); - } - $tr.remove(); - - addNotice( wp.i18n.__( 'Application password revoked.' ), 'success' ).trigger( 'focus' ); - } - } ).fail( handleErrorResponse ); - } ); - - $removeAllBtn.on( 'click', function( e ) { - e.preventDefault(); - - if ( ! window.confirm( wp.i18n.__( 'Are you sure you want to revoke all passwords? This action cannot be undone.' ) ) ) { - return; - } - - var $submitButton = $( this ); - - clearNotices(); - $submitButton.prop( 'disabled', true ); - - wp.apiRequest( { - path: '/wp/v2/users/' + userId + '/application-passwords?_locale=user', - method: 'DELETE' - } ).always( function() { - $submitButton.prop( 'disabled', false ); - } ).done( function( response ) { - if ( response.deleted ) { - $appPassTbody.children().remove(); - $appPassSection.children( '.new-application-password' ).remove(); - $appPassTwrapper.hide(); - - addNotice( wp.i18n.__( 'All application passwords revoked.' ), 'success' ).trigger( 'focus' ); - } - } ).fail( handleErrorResponse ); - } ); - - $appPassSection.on( 'click', '.notice-dismiss', function( e ) { - e.preventDefault(); - var $el = $( this ).parent(); - $el.removeAttr( 'role' ); - $el.fadeTo( 100, 0, function () { - $el.slideUp( 100, function () { - $el.remove(); - $newAppPassField.trigger( 'focus' ); - } ); - } ); - } ); - - $newAppPassField.on( 'keypress', function ( e ) { - if ( 13 === e.which ) { - e.preventDefault(); - $newAppPassButton.trigger( 'click' ); - } - } ); - - // If there are no items, don't display the table yet. If there are, show it. - if ( 0 === $appPassTbody.children( 'tr' ).not( $appPassTrNoItems ).length ) { - $appPassTwrapper.hide(); - } - - /** - * Handles an error response from the REST API. - * - * @since 5.6.0 - * - * @param {jqXHR} xhr The XHR object from the ajax call. - * @param {string} textStatus The string categorizing the ajax request's status. - * @param {string} errorThrown The HTTP status error text. - */ - function handleErrorResponse( xhr, textStatus, errorThrown ) { - var errorMessage = errorThrown; - - if ( xhr.responseJSON && xhr.responseJSON.message ) { - errorMessage = xhr.responseJSON.message; - } - - addNotice( errorMessage, 'error' ); - } - - /** - * Displays a message in the Application Passwords section. - * - * @since 5.6.0 - * - * @param {string} message The message to display. - * @param {string} type The notice type. Either 'success' or 'error'. - * @returns {jQuery} The notice element. - */ - function addNotice( message, type ) { - var $notice = $( '
' ) - .attr( 'role', 'alert' ) - .attr( 'tabindex', '-1' ) - .addClass( 'is-dismissible notice notice-' + type ) - .append( $( '

' ).text( message ) ) - .append( - $( '' ) - .attr( 'type', 'button' ) - .addClass( 'notice-dismiss' ) - .append( $( '' ).addClass( 'screen-reader-text' ).text( wp.i18n.__( 'Dismiss this notice.' ) ) ) - ); - - $newAppPassForm.after( $notice ); - - return $notice; - } - - /** - * Clears notice messages from the Application Passwords section. - * - * @since 5.6.0 - */ - function clearNotices() { - $( '.notice', $appPassSection ).remove(); - } -}( jQuery ) ); diff --git a/src/js/_enqueues/admin/auth-app.js b/src/js/_enqueues/admin/auth-app.js index 99478d1824a2d..e69de29bb2d1d 100644 --- a/src/js/_enqueues/admin/auth-app.js +++ b/src/js/_enqueues/admin/auth-app.js @@ -1,165 +0,0 @@ -/** - * @output wp-admin/js/auth-app.js - */ - -/* global authApp */ - -( function( $, authApp ) { - var $appNameField = $( '#app_name' ), - $approveBtn = $( '#approve' ), - $rejectBtn = $( '#reject' ), - $form = $appNameField.closest( 'form' ), - context = { - userLogin: authApp.user_login, - successUrl: authApp.success, - rejectUrl: authApp.reject - }; - - $approveBtn.on( 'click', function( e ) { - var name = $appNameField.val(), - appId = $( 'input[name="app_id"]', $form ).val(); - - e.preventDefault(); - - if ( $approveBtn.prop( 'aria-disabled' ) ) { - return; - } - - if ( 0 === name.length ) { - $appNameField.trigger( 'focus' ); - return; - } - - $approveBtn.prop( 'aria-disabled', true ).addClass( 'disabled' ); - - var request = { - name: name - }; - - if ( appId.length > 0 ) { - request.app_id = appId; - } - - /** - * Filters the request data used to Authorize an Application Password request. - * - * @since 5.6.0 - * - * @param {Object} request The request data. - * @param {Object} context Context about the Application Password request. - * @param {string} context.userLogin The user's login username. - * @param {string} context.successUrl The URL the user will be redirected to after approving the request. - * @param {string} context.rejectUrl The URL the user will be redirected to after rejecting the request. - */ - request = wp.hooks.applyFilters( 'wp_application_passwords_approve_app_request', request, context ); - - wp.apiRequest( { - path: '/wp/v2/users/me/application-passwords?_locale=user', - method: 'POST', - data: request - } ).done( function( response, textStatus, jqXHR ) { - - /** - * Fires when an Authorize Application Password request has been successfully approved. - * - * In most cases, this should be used in combination with the {@see 'wp_authorize_application_password_form_approved_no_js'} - * action to ensure that both the JS and no-JS variants are handled. - * - * @since 5.6.0 - * - * @param {Object} response The response from the REST API. - * @param {string} response.password The newly created password. - * @param {string} textStatus The status of the request. - * @param {jqXHR} jqXHR The underlying jqXHR object that made the request. - */ - wp.hooks.doAction( 'wp_application_passwords_approve_app_request_success', response, textStatus, jqXHR ); - - var raw = authApp.success, - url, message, $notice; - - if ( raw ) { - url = raw + ( -1 === raw.indexOf( '?' ) ? '?' : '&' ) + - 'site_url=' + encodeURIComponent( authApp.site_url ) + - '&user_login=' + encodeURIComponent( authApp.user_login ) + - '&password=' + encodeURIComponent( response.password ); - - window.location = url; - } else { - message = wp.i18n.sprintf( - /* translators: %s: Application name. */ - '', - '' - ) + ' '; - $notice = $( '
' ) - .attr( 'role', 'alert' ) - .attr( 'tabindex', -1 ) - .addClass( 'notice notice-success notice-alt' ) - .append( $( '

' ).addClass( 'application-password-display' ).html( message ) ) - .append( '

' + wp.i18n.__( 'Be sure to save this in a safe location. You will not be able to retrieve it.' ) + '

' ); - - // We're using .text() to write the variables to avoid any chance of XSS. - $( 'strong', $notice ).text( response.name ); - $( 'input', $notice ).val( response.password ); - - $form.replaceWith( $notice ); - $notice.trigger( 'focus' ); - } - } ).fail( function( jqXHR, textStatus, errorThrown ) { - var errorMessage = errorThrown, - error = null; - - if ( jqXHR.responseJSON ) { - error = jqXHR.responseJSON; - - if ( error.message ) { - errorMessage = error.message; - } - } - - var $notice = $( '
' ) - .attr( 'role', 'alert' ) - .addClass( 'notice notice-error' ) - .append( $( '

' ).text( errorMessage ) ); - - $( 'h1' ).after( $notice ); - - $approveBtn.removeProp( 'aria-disabled', false ).removeClass( 'disabled' ); - - /** - * Fires when an Authorize Application Password request encountered an error when trying to approve the request. - * - * @since 5.6.0 - * @since 5.6.1 Corrected action name and signature. - * - * @param {Object|null} error The error from the REST API. May be null if the server did not send proper JSON. - * @param {string} textStatus The status of the request. - * @param {string} errorThrown The error message associated with the response status code. - * @param {jqXHR} jqXHR The underlying jqXHR object that made the request. - */ - wp.hooks.doAction( 'wp_application_passwords_approve_app_request_error', error, textStatus, errorThrown, jqXHR ); - } ); - } ); - - $rejectBtn.on( 'click', function( e ) { - e.preventDefault(); - - /** - * Fires when an Authorize Application Password request has been rejected by the user. - * - * @since 5.6.0 - * - * @param {Object} context Context about the Application Password request. - * @param {string} context.userLogin The user's login username. - * @param {string} context.successUrl The URL the user will be redirected to after approving the request. - * @param {string} context.rejectUrl The URL the user will be redirected to after rejecting the request. - */ - wp.hooks.doAction( 'wp_application_passwords_reject_app', context ); - - // @todo: Make a better way to do this so it feels like less of a semi-open redirect. - window.location = authApp.reject; - } ); - - $form.on( 'submit', function( e ) { - e.preventDefault(); - } ); -}( jQuery, authApp ) ); diff --git a/src/js/_enqueues/admin/comment.js b/src/js/_enqueues/admin/comment.js index b31f174bab5fe..e69de29bb2d1d 100644 --- a/src/js/_enqueues/admin/comment.js +++ b/src/js/_enqueues/admin/comment.js @@ -1,179 +0,0 @@ -/** - * @output wp-admin/js/comment.js - */ - -/* global postboxes */ - -/** - * Binds to the document ready event. - * - * @since 2.5.0 - * - * @param {jQuery} $ The jQuery object. - */ -jQuery( function($) { - - postboxes.add_postbox_toggles('comment'); - - var $timestampdiv = $('#timestampdiv'), - $timestamp = $( '#timestamp' ), - stamp = $timestamp.html(), - $timestampwrap = $timestampdiv.find( '.timestamp-wrap' ), - $edittimestamp = $timestampdiv.siblings( 'a.edit-timestamp' ); - - /** - * Adds event that opens the time stamp form if the form is hidden. - * - * @listens $edittimestamp:click - * - * @param {Event} event The event object. - * @return {void} - */ - $edittimestamp.on( 'click', function( event ) { - if ( $timestampdiv.is( ':hidden' ) ) { - // Slide down the form and set focus on the first field. - $timestampdiv.slideDown( 'fast', function() { - $( 'input, select', $timestampwrap ).first().trigger( 'focus' ); - } ); - $(this).hide(); - } - event.preventDefault(); - }); - - /** - * Resets the time stamp values when the cancel button is clicked. - * - * @listens .cancel-timestamp:click - * - * @param {Event} event The event object. - * @return {void} - */ - - $timestampdiv.find('.cancel-timestamp').on( 'click', function( event ) { - // Move focus back to the Edit link. - $edittimestamp.show().trigger( 'focus' ); - $timestampdiv.slideUp( 'fast' ); - $('#mm').val($('#hidden_mm').val()); - $('#jj').val($('#hidden_jj').val()); - $('#aa').val($('#hidden_aa').val()); - $('#hh').val($('#hidden_hh').val()); - $('#mn').val($('#hidden_mn').val()); - $timestamp.html( stamp ); - event.preventDefault(); - }); - - /** - * Sets the time stamp values when the ok button is clicked. - * - * @listens .save-timestamp:click - * - * @param {Event} event The event object. - * @return {void} - */ - $timestampdiv.find('.save-timestamp').on( 'click', function( event ) { // Crazyhorse branch - multiple OK cancels. - var aa = $('#aa').val(), mm = $('#mm').val(), jj = $('#jj').val(), hh = $('#hh').val(), mn = $('#mn').val(), - newD = new Date( aa, mm - 1, jj, hh, mn ); - - event.preventDefault(); - - if ( newD.getFullYear() != aa || (1 + newD.getMonth()) != mm || newD.getDate() != jj || newD.getMinutes() != mn ) { - $timestampwrap.addClass( 'form-invalid' ); - return; - } else { - $timestampwrap.removeClass( 'form-invalid' ); - } - - $timestamp.html( - wp.i18n.__( 'Submitted on:' ) + ' ' + - /* translators: 1: Month, 2: Day, 3: Year, 4: Hour, 5: Minute. */ - wp.i18n.__( '%1$s %2$s, %3$s at %4$s:%5$s' ) - .replace( '%1$s', $( 'option[value="' + mm + '"]', '#mm' ).attr( 'data-text' ) ) - .replace( '%2$s', parseInt( jj, 10 ) ) - .replace( '%3$s', aa ) - .replace( '%4$s', ( '00' + hh ).slice( -2 ) ) - .replace( '%5$s', ( '00' + mn ).slice( -2 ) ) + - ' ' - ); - - // Move focus back to the Edit link. - $edittimestamp.show().trigger( 'focus' ); - $timestampdiv.slideUp( 'fast' ); - }); - - var $commentparentdiv = $( '#comment-parent-div' ), - $commentparentdisplay = $( '#comment-parent-display' ), - originalcommentparentdisplay = $commentparentdisplay.html(), - $editcommentparent = $commentparentdiv.siblings( 'a.edit-comment-parent' ); - - /** - * Adds event that opens the parent comment form if the form is hidden. - * - * @since 7.1.0 - * - * @listens $editcommentparent:click - * - * @param {Event} event The event object. - * @return {void} - */ - $editcommentparent.on( 'click', function( event ) { - if ( $commentparentdiv.is( ':hidden' ) ) { - // Slide down the form and set focus on the parent field. - $commentparentdiv.slideDown( 'fast', function() { - $( '#comment_parent' ).trigger( 'focus' ); - } ); - $(this).hide(); - } - event.preventDefault(); - }); - - /** - * Resets the parent comment value when the cancel button is clicked. - * - * @since 7.1.0 - * - * @listens .cancel-comment-parent:click - * - * @param {Event} event The event object. - * @return {void} - */ - $commentparentdiv.find( '.cancel-comment-parent' ).on( 'click', function( event ) { - // Move focus back to the Edit link. - $editcommentparent.show().trigger( 'focus' ); - $commentparentdiv.slideUp( 'fast' ); - $( '#comment_parent' ).val( $( '#hidden_comment_parent' ).val() ); - $commentparentdisplay.html( originalcommentparentdisplay ); - event.preventDefault(); - }); - - /** - * Updates the parent comment display when the ok button is clicked. - * - * @since 7.1.0 - * - * @listens .save-comment-parent:click - * - * @param {Event} event The event object. - * @return {void} - */ - $commentparentdiv.find( '.save-comment-parent' ).on( 'click', function( event ) { - var $selected = $( '#comment_parent option:selected' ), - parentLabel = '0' === $selected.val() ? - /* translators: Displayed when a comment has no parent. */ - wp.i18n.__( 'None' ) : - $selected.data( 'author' ) || $selected.text(); - - event.preventDefault(); - - $commentparentdisplay.html( - wp.i18n.sprintf( - /* translators: %s: Parent comment link, or 'None'. */ - wp.i18n.__( 'In reply to: %s' ), - $( '' ).text( parentLabel ).prop( 'outerHTML' ) - ) - ); - - // Move focus back to the Edit link. - $editcommentparent.show().trigger( 'focus' ); - $commentparentdiv.slideUp( 'fast' ); - }); -}); diff --git a/src/js/_enqueues/admin/common.js b/src/js/_enqueues/admin/common.js index c3d49310e8897..e69de29bb2d1d 100644 --- a/src/js/_enqueues/admin/common.js +++ b/src/js/_enqueues/admin/common.js @@ -1,2597 +0,0 @@ -/** - * @output wp-admin/js/common.js - */ - -/* global setUserSetting, ajaxurl, alert, confirm, pagenow */ -/* global columns, screenMeta */ - -/** - * Adds common WordPress functionality to the window. - * - * @param {jQuery} $ jQuery object. - * @param {Object} window The window object. - * @param {mixed} undefined Unused. - */ -( function( $, window, undefined ) { - var $document = $( document ), - $window = $( window ), - $body = $( document.body ), - __ = wp.i18n.__, - sprintf = wp.i18n.sprintf; - -/** - * Throws an error for a deprecated property. - * - * @since 5.5.1 - * - * @param {string} propName The property that was used. - * @param {string} version The version of WordPress that deprecated the property. - * @param {string} replacement The property that should have been used. - */ -function deprecatedProperty( propName, version, replacement ) { - var message; - - if ( 'undefined' !== typeof replacement ) { - message = sprintf( - /* translators: 1: Deprecated property name, 2: Version number, 3: Alternative property name. */ - __( '%1$s is deprecated since version %2$s! Use %3$s instead.' ), - propName, - version, - replacement - ); - } else { - message = sprintf( - /* translators: 1: Deprecated property name, 2: Version number. */ - __( '%1$s is deprecated since version %2$s with no alternative available.' ), - propName, - version - ); - } - - window.console.warn( message ); -} - -/** - * Deprecate all properties on an object. - * - * @since 5.5.1 - * @since 5.6.0 Added the `version` parameter. - * - * @param {string} name The name of the object, i.e. commonL10n. - * @param {object} l10nObject The object to deprecate the properties on. - * @param {string} version The version of WordPress that deprecated the property. - * - * @return {object} The object with all its properties deprecated. - */ -function deprecateL10nObject( name, l10nObject, version ) { - var deprecatedObject = {}; - - Object.keys( l10nObject ).forEach( function( key ) { - var prop = l10nObject[ key ]; - var propName = name + '.' + key; - - if ( 'object' === typeof prop ) { - Object.defineProperty( deprecatedObject, key, { get: function() { - deprecatedProperty( propName, version, prop.alternative ); - return prop.func(); - } } ); - } else { - Object.defineProperty( deprecatedObject, key, { get: function() { - deprecatedProperty( propName, version, 'wp.i18n' ); - return prop; - } } ); - } - } ); - - return deprecatedObject; -} - -window.wp.deprecateL10nObject = deprecateL10nObject; - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 2.6.0 - * @deprecated 5.5.0 - */ -window.commonL10n = window.commonL10n || { - warnDelete: '', - dismiss: '', - collapseMenu: '', - expandMenu: '' -}; - -window.commonL10n = deprecateL10nObject( 'commonL10n', window.commonL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 3.3.0 - * @deprecated 5.5.0 - */ -window.wpPointerL10n = window.wpPointerL10n || { - dismiss: '' -}; - -window.wpPointerL10n = deprecateL10nObject( 'wpPointerL10n', window.wpPointerL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 4.3.0 - * @deprecated 5.5.0 - */ -window.userProfileL10n = window.userProfileL10n || { - warn: '', - warnWeak: '', - show: '', - hide: '', - cancel: '', - ariaShow: '', - ariaHide: '' -}; - -window.userProfileL10n = deprecateL10nObject( 'userProfileL10n', window.userProfileL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 4.9.6 - * @deprecated 5.5.0 - */ -window.privacyToolsL10n = window.privacyToolsL10n || { - noDataFound: '', - foundAndRemoved: '', - noneRemoved: '', - someNotRemoved: '', - removalError: '', - emailSent: '', - noExportFile: '', - exportError: '' -}; - -window.privacyToolsL10n = deprecateL10nObject( 'privacyToolsL10n', window.privacyToolsL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 3.6.0 - * @deprecated 5.5.0 - */ -window.authcheckL10n = { - beforeunload: '' -}; - -window.authcheckL10n = window.authcheckL10n || deprecateL10nObject( 'authcheckL10n', window.authcheckL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 2.8.0 - * @deprecated 5.5.0 - */ -window.tagsl10n = { - noPerm: '', - broken: '' -}; - -window.tagsl10n = window.tagsl10n || deprecateL10nObject( 'tagsl10n', window.tagsl10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 2.5.0 - * @deprecated 5.5.0 - */ -window.adminCommentsL10n = window.adminCommentsL10n || { - hotkeys_highlight_first: { - alternative: 'window.adminCommentsSettings.hotkeys_highlight_first', - func: function() { return window.adminCommentsSettings.hotkeys_highlight_first; } - }, - hotkeys_highlight_last: { - alternative: 'window.adminCommentsSettings.hotkeys_highlight_last', - func: function() { return window.adminCommentsSettings.hotkeys_highlight_last; } - }, - replyApprove: '', - reply: '', - warnQuickEdit: '', - warnCommentChanges: '', - docTitleComments: '', - docTitleCommentsCount: '' -}; - -window.adminCommentsL10n = deprecateL10nObject( 'adminCommentsL10n', window.adminCommentsL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 2.5.0 - * @deprecated 5.5.0 - */ -window.tagsSuggestL10n = window.tagsSuggestL10n || { - tagDelimiter: '', - removeTerm: '', - termSelected: '', - termAdded: '', - termRemoved: '' -}; - -window.tagsSuggestL10n = deprecateL10nObject( 'tagsSuggestL10n', window.tagsSuggestL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 3.5.0 - * @deprecated 5.5.0 - */ -window.wpColorPickerL10n = window.wpColorPickerL10n || { - clear: '', - clearAriaLabel: '', - defaultString: '', - defaultAriaLabel: '', - pick: '', - defaultLabel: '' -}; - -window.wpColorPickerL10n = deprecateL10nObject( 'wpColorPickerL10n', window.wpColorPickerL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 2.7.0 - * @deprecated 5.5.0 - */ -window.attachMediaBoxL10n = window.attachMediaBoxL10n || { - error: '' -}; - -window.attachMediaBoxL10n = deprecateL10nObject( 'attachMediaBoxL10n', window.attachMediaBoxL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 2.5.0 - * @deprecated 5.5.0 - */ -window.postL10n = window.postL10n || { - ok: '', - cancel: '', - publishOn: '', - publishOnFuture: '', - publishOnPast: '', - dateFormat: '', - showcomm: '', - endcomm: '', - publish: '', - schedule: '', - update: '', - savePending: '', - saveDraft: '', - 'private': '', - 'public': '', - publicSticky: '', - password: '', - privatelyPublished: '', - published: '', - saveAlert: '', - savingText: '', - permalinkSaved: '' -}; - -window.postL10n = deprecateL10nObject( 'postL10n', window.postL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 2.7.0 - * @deprecated 5.5.0 - */ -window.inlineEditL10n = window.inlineEditL10n || { - error: '', - ntdeltitle: '', - notitle: '', - comma: '', - saved: '' -}; - -window.inlineEditL10n = deprecateL10nObject( 'inlineEditL10n', window.inlineEditL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 2.7.0 - * @deprecated 5.5.0 - */ -window.plugininstallL10n = window.plugininstallL10n || { - plugin_information: '', - plugin_modal_label: '', - ays: '' -}; - -window.plugininstallL10n = deprecateL10nObject( 'plugininstallL10n', window.plugininstallL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 3.0.0 - * @deprecated 5.5.0 - */ -window.navMenuL10n = window.navMenuL10n || { - noResultsFound: '', - warnDeleteMenu: '', - saveAlert: '', - untitled: '' -}; - -window.navMenuL10n = deprecateL10nObject( 'navMenuL10n', window.navMenuL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 2.5.0 - * @deprecated 5.5.0 - */ -window.commentL10n = window.commentL10n || { - submittedOn: '', - dateFormat: '' -}; - -window.commentL10n = deprecateL10nObject( 'commentL10n', window.commentL10n, '5.5.0' ); - -/** - * Removed in 5.5.0, needed for back-compatibility. - * - * @since 2.9.0 - * @deprecated 5.5.0 - */ -window.setPostThumbnailL10n = window.setPostThumbnailL10n || { - setThumbnail: '', - saving: '', - error: '', - done: '' -}; - -window.setPostThumbnailL10n = deprecateL10nObject( 'setPostThumbnailL10n', window.setPostThumbnailL10n, '5.5.0' ); - -/** - * Removed in 6.5.0, needed for back-compatibility. - * - * @since 4.5.0 - * @deprecated 6.5.0 - */ -window.uiAutocompleteL10n = window.uiAutocompleteL10n || { - noResults: '', - oneResult: '', - manyResults: '', - itemSelected: '' -}; - -window.uiAutocompleteL10n = deprecateL10nObject( 'uiAutocompleteL10n', window.uiAutocompleteL10n, '6.5.0' ); - -/** - * Removed in 3.3.0, needed for back-compatibility. - * - * @since 2.7.0 - * @deprecated 3.3.0 - */ -window.adminMenu = { - init : function() {}, - fold : function() {}, - restoreMenuState : function() {}, - toggle : function() {}, - favorites : function() {} -}; - -// Show/hide/save table columns. -window.columns = { - - /** - * Initializes the column toggles in the screen options. - * - * Binds an onClick event to the checkboxes to show or hide the table columns - * based on their toggled state. And persists the toggled state. - * - * @since 2.7.0 - * - * @return {void} - */ - init : function() { - var that = this; - $('.hide-column-tog', '#adv-settings').on( 'click', function() { - var $t = $(this), column = $t.val(); - if ( $t.prop('checked') ) - that.checked(column); - else - that.unchecked(column); - - columns.saveManageColumnsState(); - }); - }, - - /** - * Saves the toggled state for the columns. - * - * Saves whether the columns should be shown or hidden on a page. - * - * @since 3.0.0 - * - * @return {void} - */ - saveManageColumnsState : function() { - var hidden = this.hidden(); - $.post( - ajaxurl, - { - action: 'hidden-columns', - hidden: hidden, - screenoptionnonce: $('#screenoptionnonce').val(), - page: pagenow - }, - function() { - wp.a11y.speak( __( 'Screen Options updated.' ) ); - } - ); - }, - - /** - * Makes a column visible and adjusts the column span for the table. - * - * @since 3.0.0 - * @param {string} column The column name. - * - * @return {void} - */ - checked : function(column) { - $('.column-' + column).removeClass( 'hidden' ); - this.colSpanChange(+1); - }, - - /** - * Hides a column and adjusts the column span for the table. - * - * @since 3.0.0 - * @param {string} column The column name. - * - * @return {void} - */ - unchecked : function(column) { - $('.column-' + column).addClass( 'hidden' ); - this.colSpanChange(-1); - }, - - /** - * Gets all hidden columns. - * - * @since 3.0.0 - * - * @return {string} The hidden column names separated by a comma. - */ - hidden : function() { - return $( '.manage-column[id]' ).filter( '.hidden' ).map(function() { - return this.id; - }).get().join( ',' ); - }, - - /** - * Gets the checked column toggles from the screen options. - * - * @since 3.0.0 - * - * @return {string} String containing the checked column names. - */ - useCheckboxesForHidden : function() { - this.hidden = function(){ - return $('.hide-column-tog').not(':checked').map(function() { - var id = this.id; - return id.substring( id, id.length - 5 ); - }).get().join(','); - }; - }, - - /** - * Adjusts the column span for the table. - * - * @since 3.1.0 - * - * @param {number} diff The modifier for the column span. - */ - colSpanChange : function(diff) { - var $t = $('table').find('.colspanchange'), n; - if ( !$t.length ) - return; - n = parseInt( $t.attr('colspan'), 10 ) + diff; - $t.attr('colspan', n.toString()); - } -}; - -$( function() { columns.init(); } ); - -/** - * Validates that the required form fields are not empty. - * - * @since 2.9.0 - * - * @param {jQuery} form The form to validate. - * - * @return {boolean} Returns true if all required fields are not an empty string. - */ -window.validateForm = function( form ) { - return !$( form ) - .find( '.form-required' ) - .filter( function() { return $( ':input:visible', this ).val() === ''; } ) - .addClass( 'form-invalid' ) - .find( ':input:visible' ) - .on( 'change', function() { $( this ).closest( '.form-invalid' ).removeClass( 'form-invalid' ); } ) - .length; -}; - -// Stub for doing better warnings. -/** - * Shows message pop-up notice or confirmation message. - * - * @since 2.7.0 - * - * @type {{warn: showNotice.warn, note: showNotice.note}} - * - * @return {void} - */ -window.showNotice = { - - /** - * Shows a delete confirmation pop-up message. - * - * @since 2.7.0 - * - * @return {boolean} Returns true if the message is confirmed. - */ - warn : function() { - if ( confirm( __( 'You are about to permanently delete these items from your site.\nThis action cannot be undone.\n\'Cancel\' to stop, \'OK\' to delete.' ) ) ) { - return true; - } - - return false; - }, - - /** - * Shows an alert message. - * - * @since 2.7.0 - * - * @param text The text to display in the message. - */ - note : function(text) { - alert(text); - } -}; - -/** - * Represents the functions for the meta screen options panel. - * - * @since 3.2.0 - * - * @type {{element: null, toggles: null, page: null, init: screenMeta.init, - * toggleEvent: screenMeta.toggleEvent, open: screenMeta.open, - * close: screenMeta.close}} - * - * @return {void} - */ -window.screenMeta = { - element: null, // #screen-meta - toggles: null, // .screen-meta-toggle - page: null, // #wpcontent - - /** - * Initializes the screen meta options panel. - * - * @since 3.2.0 - * - * @return {void} - */ - init: function() { - this.element = $('#screen-meta'); - this.toggles = $( '#screen-meta-links' ).find( '.show-settings' ); - this.page = $('#wpcontent'); - - this.toggles.on( 'click', this.toggleEvent ); - }, - - /** - * Toggles the screen meta options panel. - * - * @since 3.2.0 - * - * @return {void} - */ - toggleEvent: function() { - var panel = $( '#' + $( this ).attr( 'aria-controls' ) ); - - if ( !panel.length ) - return; - - if ( panel.is(':visible') ) - screenMeta.close( panel, $(this) ); - else - screenMeta.open( panel, $(this) ); - }, - - /** - * Opens the screen meta options panel. - * - * @since 3.2.0 - * - * @param {jQuery} panel The screen meta options panel div. - * @param {jQuery} button The toggle button. - * - * @return {void} - */ - open: function( panel, button ) { - - $( '#screen-meta-links' ).find( '.screen-meta-toggle' ).not( button.parent() ).css( 'visibility', 'hidden' ); - - panel.parent().show(); - - /** - * Sets the focus to the meta options panel and adds the necessary CSS classes. - * - * @since 3.2.0 - * - * @return {void} - */ - panel.slideDown( 'fast', function() { - panel.removeClass( 'hidden' ).trigger( 'focus' ); - button.addClass( 'screen-meta-active' ).attr( 'aria-expanded', true ); - }); - - $document.trigger( 'screen:options:open' ); - }, - - /** - * Closes the screen meta options panel. - * - * @since 3.2.0 - * - * @param {jQuery} panel The screen meta options panel div. - * @param {jQuery} button The toggle button. - * - * @return {void} - */ - close: function( panel, button ) { - /** - * Hides the screen meta options panel. - * - * @since 3.2.0 - * - * @return {void} - */ - panel.slideUp( 'fast', function() { - button.removeClass( 'screen-meta-active' ).attr( 'aria-expanded', false ); - $('.screen-meta-toggle').css('visibility', ''); - panel.parent().hide(); - panel.addClass( 'hidden' ); - }); - - $document.trigger( 'screen:options:close' ); - } -}; - -/** - * Initializes the help tabs in the help panel. - * - * @param {Event} e The event object. - * - * @return {void} - */ -$('.contextual-help-tabs').on( 'click', 'a', function(e) { - var link = $(this), - panel; - - e.preventDefault(); - - // Don't do anything if the click is for the tab already showing. - if ( link.is('.active a') ) - return false; - - // Links. - $('.contextual-help-tabs .active').removeClass('active'); - link.parent('li').addClass('active'); - - panel = $( link.attr('href') ); - - // Panels. - $('.help-tab-content').not( panel ).removeClass('active').hide(); - panel.addClass('active').show(); -}); - -/** - * Update custom permalink structure via buttons. - */ -var permalinkStructureFocused = false, - $permalinkStructure = $( '#permalink_structure' ), - $permalinkStructureInputs = $( '.permalink-structure input:radio' ), - $permalinkCustomSelection = $( '#custom_selection' ), - $availableStructureTags = $( '.form-table.permalink-structure .available-structure-tags button' ); - -// Change permalink structure input when selecting one of the common structures. -$permalinkStructureInputs.on( 'change', function() { - if ( 'custom' === this.value ) { - return; - } - - $permalinkStructure.val( this.value ); - - // Update button states after selection. - $availableStructureTags.each( function() { - changeStructureTagButtonState( $( this ) ); - } ); -} ); - -$permalinkStructure.on( 'click input', function() { - $permalinkCustomSelection.prop( 'checked', true ); -} ); - -// Check if the permalink structure input field has had focus at least once. -$permalinkStructure.on( 'focus', function( event ) { - permalinkStructureFocused = true; - $( this ).off( event ); -} ); - -/** - * Enables or disables a structure tag button depending on its usage. - * - * If the structure is already used in the custom permalink structure, - * it will be disabled. - * - * @param {Object} button Button jQuery object. - */ -function changeStructureTagButtonState( button ) { - if ( -1 !== $permalinkStructure.val().indexOf( button.text().trim() ) ) { - button.attr( 'data-label', button.attr( 'aria-label' ) ); - button.attr( 'aria-label', button.attr( 'data-used' ) ); - button.attr( 'aria-pressed', true ); - button.addClass( 'active' ); - } else if ( button.attr( 'data-label' ) ) { - button.attr( 'aria-label', button.attr( 'data-label' ) ); - button.attr( 'aria-pressed', false ); - button.removeClass( 'active' ); - } -} - -// Check initial button state. -$availableStructureTags.each( function() { - changeStructureTagButtonState( $( this ) ); -} ); - -// Observe permalink structure field and disable buttons of tags that are already present. -$permalinkStructure.on( 'change', function() { - $availableStructureTags.each( function() { - changeStructureTagButtonState( $( this ) ); - } ); -} ); - -$availableStructureTags.on( 'click', function() { - var permalinkStructureValue = $permalinkStructure.val(), - selectionStart = $permalinkStructure[ 0 ].selectionStart, - selectionEnd = $permalinkStructure[ 0 ].selectionEnd, - textToAppend = $( this ).text().trim(), - textToAnnounce, - newSelectionStart; - - if ( $( this ).hasClass( 'active' ) ) { - textToAnnounce = $( this ).attr( 'data-removed' ); - } else { - textToAnnounce = $( this ).attr( 'data-added' ); - } - - // Remove structure tag if already part of the structure. - if ( -1 !== permalinkStructureValue.indexOf( textToAppend ) ) { - permalinkStructureValue = permalinkStructureValue.replace( textToAppend + '/', '' ); - - $permalinkStructure.val( '/' === permalinkStructureValue ? '' : permalinkStructureValue ); - - // Announce change to screen readers. - $( '#custom_selection_updated' ).text( textToAnnounce ); - - // Disable button. - changeStructureTagButtonState( $( this ) ); - - return; - } - - // Input field never had focus, move selection to end of input. - if ( ! permalinkStructureFocused && 0 === selectionStart && 0 === selectionEnd ) { - selectionStart = selectionEnd = permalinkStructureValue.length; - } - - $permalinkCustomSelection.prop( 'checked', true ); - - // Prepend and append slashes if necessary. - if ( '/' !== permalinkStructureValue.substr( 0, selectionStart ).substr( -1 ) ) { - textToAppend = '/' + textToAppend; - } - - if ( '/' !== permalinkStructureValue.substr( selectionEnd, 1 ) ) { - textToAppend = textToAppend + '/'; - } - - // Insert structure tag at the specified position. - $permalinkStructure.val( permalinkStructureValue.substr( 0, selectionStart ) + textToAppend + permalinkStructureValue.substr( selectionEnd ) ); - - // Announce change to screen readers. - $( '#custom_selection_updated' ).text( textToAnnounce ); - - // Disable button. - changeStructureTagButtonState( $( this ) ); - - // If input had focus give it back with cursor right after appended text. - if ( permalinkStructureFocused && $permalinkStructure[0].setSelectionRange ) { - newSelectionStart = ( permalinkStructureValue.substr( 0, selectionStart ) + textToAppend ).length; - $permalinkStructure[0].setSelectionRange( newSelectionStart, newSelectionStart ); - $permalinkStructure.trigger( 'focus' ); - } -} ); - -$( function() { - var checks, first, last, checked, sliced, mobileEvent, transitionTimeout, focusedRowActions, - lastClicked = false, - pageInput = $('input.current-page'), - currentPage = pageInput.val(), - isIOS = /iPhone|iPad|iPod/.test( navigator.userAgent ), - isAndroid = navigator.userAgent.indexOf( 'Android' ) !== -1, - $adminMenuWrap = $( '#adminmenuwrap' ), - $wpwrap = $( '#wpwrap' ), - $adminmenu = $( '#adminmenu' ), - $overlay = $( '#wp-responsive-overlay' ), - $toolbar = $( '#wp-toolbar' ), - $toolbarPopups = $toolbar.find( 'a[aria-haspopup="true"]' ), - $sortables = $('.meta-box-sortables'), - wpResponsiveActive = false, - $adminbar = $( '#wpadminbar' ), - lastScrollPosition = 0, - pinnedMenuTop = false, - pinnedMenuBottom = false, - menuTop = 0, - menuState, - menuIsPinned = false, - height = { - window: $window.height(), - wpwrap: $wpwrap.height(), - adminbar: $adminbar.height(), - menu: $adminMenuWrap.height() - }, - $headerEnd = $( '.wp-header-end' ); - - /** - * Makes the fly-out submenu header clickable, when the menu is folded. - * - * @param {Event} e The event object. - * - * @return {void} - */ - $adminmenu.on('click.wp-submenu-head', '.wp-submenu-head', function(e){ - $(e.target).parent().siblings('a').get(0).click(); - }); - - /** - * Collapses the admin menu. - * - * @return {void} - */ - $( '#collapse-button' ).on( 'click.collapse-menu', function() { - var viewportWidth = getViewportWidth() || 961; - - // Reset any compensation for submenus near the bottom of the screen. - $('#adminmenu div.wp-submenu').css('margin-top', ''); - - if ( viewportWidth <= 960 ) { - if ( $body.hasClass('auto-fold') ) { - $body.removeClass('auto-fold').removeClass('folded'); - setUserSetting('unfold', 1); - setUserSetting('mfold', 'o'); - menuState = 'open'; - } else { - $body.addClass('auto-fold'); - setUserSetting('unfold', 0); - menuState = 'folded'; - } - } else { - if ( $body.hasClass('folded') ) { - $body.removeClass('folded'); - setUserSetting('mfold', 'o'); - menuState = 'open'; - } else { - $body.addClass('folded'); - setUserSetting('mfold', 'f'); - menuState = 'folded'; - } - } - - $document.trigger( 'wp-collapse-menu', { state: menuState } ); - }); - - /** - * Ensures an admin submenu is within the visual viewport. - * - * @since 4.1.0 - * - * @param {jQuery} $menuItem The parent menu item containing the submenu. - * - * @return {void} - */ - function adjustSubmenu( $menuItem ) { - var bottomOffset, pageHeight, adjustment, theFold, menutop, wintop, maxtop, - $submenu = $menuItem.find( '.wp-submenu' ); - - menutop = $menuItem.offset().top; - wintop = $window.scrollTop(); - maxtop = menutop - wintop - 30; // max = make the top of the sub almost touch admin bar. - - bottomOffset = menutop + $submenu.height() + 1; // Bottom offset of the menu. - pageHeight = $wpwrap.height(); // Height of the entire page. - adjustment = 60 + bottomOffset - pageHeight; - theFold = $window.height() + wintop - 50; // The fold. - - if ( theFold < ( bottomOffset - adjustment ) ) { - adjustment = bottomOffset - theFold; - } - - if ( adjustment > maxtop ) { - adjustment = maxtop; - } - - if ( adjustment > 1 && $('#wp-admin-bar-menu-toggle').is(':hidden') ) { - $submenu.css( 'margin-top', '-' + adjustment + 'px' ); - } else { - $submenu.css( 'margin-top', '' ); - } - } - - if ( 'ontouchstart' in window || /IEMobile\/[1-9]/.test(navigator.userAgent) ) { // Touch screen device. - // iOS Safari works with touchstart, the rest work with click. - mobileEvent = isIOS ? 'touchstart' : 'click'; - - /** - * Closes any open submenus when touch/click is not on the menu. - * - * @param {Event} e The event object. - * - * @return {void} - */ - $body.on( mobileEvent+'.wp-mobile-hover', function(e) { - if ( $adminmenu.data('wp-responsive') ) { - return; - } - - if ( ! $( e.target ).closest( '#adminmenu' ).length ) { - $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' ); - } - }); - - /** - * Handles the opening or closing the submenu based on the mobile click|touch event. - * - * @param {Event} event The event object. - * - * @return {void} - */ - $adminmenu.find( 'a.wp-has-submenu' ).on( mobileEvent + '.wp-mobile-hover', function( event ) { - var $menuItem = $(this).parent(); - - if ( $adminmenu.data( 'wp-responsive' ) ) { - return; - } - - /* - * Show the sub instead of following the link if: - * - the submenu is not open. - * - the submenu is not shown inline or the menu is not folded. - */ - if ( ! $menuItem.hasClass( 'opensub' ) && ( ! $menuItem.hasClass( 'wp-menu-open' ) || $menuItem.width() < 40 ) ) { - event.preventDefault(); - adjustSubmenu( $menuItem ); - $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' ); - $menuItem.addClass('opensub'); - } - }); - } - - if ( ! isIOS && ! isAndroid ) { - $adminmenu.find( 'li.wp-has-submenu' ).hoverIntent({ - - /** - * Opens the submenu when hovered over the menu item for desktops. - * - * @return {void} - */ - over: function() { - var $menuItem = $( this ), - $submenu = $menuItem.find( '.wp-submenu' ), - top = parseInt( $submenu.css( 'top' ), 10 ); - - if ( isNaN( top ) || top > -5 ) { // The submenu is visible. - return; - } - - if ( $adminmenu.data( 'wp-responsive' ) ) { - // The menu is in responsive mode, bail. - return; - } - - adjustSubmenu( $menuItem ); - $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' ); - $menuItem.addClass( 'opensub' ); - }, - - /** - * Closes the submenu when no longer hovering the menu item. - * - * @return {void} - */ - out: function(){ - if ( $adminmenu.data( 'wp-responsive' ) ) { - // The menu is in responsive mode, bail. - return; - } - - $( this ).removeClass( 'opensub' ).find( '.wp-submenu' ).css( 'margin-top', '' ); - }, - timeout: 200, - sensitivity: 7, - interval: 90 - }); - - /** - * Opens the submenu on when focused on the menu item. - * - * @param {Event} event The event object. - * - * @return {void} - */ - $adminmenu.on( 'focus.adminmenu', '.wp-submenu a', function( event ) { - if ( $adminmenu.data( 'wp-responsive' ) ) { - // The menu is in responsive mode, bail. - return; - } - - $( event.target ).closest( 'li.menu-top' ).addClass( 'opensub' ); - - /** - * Closes the submenu on blur from the menu item. - * - * @param {Event} event The event object. - * - * @return {void} - */ - }).on( 'blur.adminmenu', '.wp-submenu a', function( event ) { - if ( $adminmenu.data( 'wp-responsive' ) ) { - return; - } - - $( event.target ).closest( 'li.menu-top' ).removeClass( 'opensub' ); - - /** - * Adjusts the size for the submenu. - * - * @return {void} - */ - }).find( 'li.wp-has-submenu.wp-not-current-submenu' ).on( 'focusin.adminmenu', function() { - adjustSubmenu( $( this ) ); - }); - } - - /* - * The `.below-h2` class is here just for backward compatibility with plugins - * that are (incorrectly) using it. Do not use. Use `.inline` instead. See #34570. - * If '.wp-header-end' is found, append the notices after it otherwise - * after the first h1 or h2 heading found within the main content. - */ - if ( ! $headerEnd.length ) { - $headerEnd = $( '.wrap h1, .wrap h2' ).first(); - } - $( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd ); - - /** - * Makes notices dismissible. - * - * @since 4.4.0 - * - * @return {void} - */ - function makeNoticesDismissible() { - $( '.notice.is-dismissible' ).each( function() { - var $el = $( this ), - $button = $( '' ); - - if ( $el.find( '.notice-dismiss' ).length ) { - return; - } - - // Ensure plain text. - $button.find( '.screen-reader-text' ).text( __( 'Dismiss this notice.' ) ); - $button.on( 'click.wp-dismiss-notice', function( event ) { - event.preventDefault(); - $el.fadeTo( 100, 0, function() { - $el.slideUp( 100, function() { - $el.remove(); - }); - }); - }); - - $el.append( $button ); - }); - } - - $document.on( 'wp-updates-notice-added wp-plugin-install-error wp-plugin-update-error wp-plugin-delete-error wp-theme-install-error wp-theme-delete-error wp-notice-added', makeNoticesDismissible ); - - // Init screen meta. - screenMeta.init(); - - /** - * Checks a checkbox. - * - * This event needs to be delegated. Ticket #37973. - * - * @return {boolean} Returns whether a checkbox is checked or not. - */ - $body.on( 'click', 'tbody > tr > .check-column :checkbox', function( event ) { - // Shift click to select a range of checkboxes. - if ( 'undefined' == event.shiftKey ) { return true; } - if ( event.shiftKey ) { - if ( !lastClicked ) { return true; } - checks = $( lastClicked ).closest( 'form' ).find( ':checkbox' ).filter( ':visible:enabled' ); - first = checks.index( lastClicked ); - last = checks.index( this ); - checked = $(this).prop('checked'); - if ( 0 < first && 0 < last && first != last ) { - sliced = ( last > first ) ? checks.slice( first, last ) : checks.slice( last, first ); - sliced.prop( 'checked', function() { - if ( $(this).closest('tr').is(':visible') ) - return checked; - - return false; - }); - } - } - lastClicked = this; - - // Toggle the "Select all" checkboxes depending if the other ones are all checked or not. - var unchecked = $(this).closest('tbody').find('tr').find(':checkbox').filter(':visible:enabled').not(':checked'); - - /** - * Determines if all checkboxes are checked. - * - * @return {boolean} Returns true if there are no unchecked checkboxes. - */ - $(this).closest('table').children('thead, tfoot').find(':checkbox').prop('checked', function() { - return ( 0 === unchecked.length ); - }); - - return true; - }); - - /** - * Controls all the toggles on bulk toggle change. - * - * When the bulk checkbox is changed, all the checkboxes in the tables are changed accordingly. - * When the shift-button is pressed while changing the bulk checkbox the checkboxes in the table are inverted. - * - * This event needs to be delegated. Ticket #37973. - * - * @param {Event} event The event object. - * - * @return {boolean} - */ - $body.on( 'click.wp-toggle-checkboxes', 'thead .check-column :checkbox, tfoot .check-column :checkbox', function( event ) { - var $this = $(this), - $table = $this.closest( 'table' ), - controlChecked = $this.prop('checked'), - toggle = event.shiftKey || $this.data('wp-toggle'); - - $table.children( 'tbody' ).filter(':visible') - .children().children('.check-column').find(':checkbox') - /** - * Updates the checked state on the checkbox in the table. - * - * @return {boolean} True checks the checkbox, False unchecks the checkbox. - */ - .prop('checked', function() { - if ( $(this).is(':hidden,:disabled') ) { - return false; - } - - if ( toggle ) { - return ! $(this).prop( 'checked' ); - } else if ( controlChecked ) { - return true; - } - - return false; - }); - - $table.children('thead, tfoot').filter(':visible') - .children().children('.check-column').find(':checkbox') - - /** - * Syncs the bulk checkboxes on the top and bottom of the table. - * - * @return {boolean} True checks the checkbox, False unchecks the checkbox. - */ - .prop('checked', function() { - if ( toggle ) { - return false; - } else if ( controlChecked ) { - return true; - } - - return false; - }); - }); - - /** - * Marries a secondary control to its primary control. - * - * @param {jQuery} topSelector The top selector element. - * @param {jQuery} topSubmit The top submit element. - * @param {jQuery} bottomSelector The bottom selector element. - * @param {jQuery} bottomSubmit The bottom submit element. - * @return {void} - */ - function marryControls( topSelector, topSubmit, bottomSelector, bottomSubmit ) { - /** - * Updates the primary selector when the secondary selector is changed. - * - * @since 5.7.0 - * - * @return {void} - */ - function updateTopSelector() { - topSelector.val($(this).val()); - } - bottomSelector.on('change', updateTopSelector); - - /** - * Updates the secondary selector when the primary selector is changed. - * - * @since 5.7.0 - * - * @return {void} - */ - function updateBottomSelector() { - bottomSelector.val($(this).val()); - } - topSelector.on('change', updateBottomSelector); - - /** - * Triggers the primary submit when then secondary submit is clicked. - * - * @since 5.7.0 - * - * @return {void} - */ - function triggerSubmitClick(e) { - e.preventDefault(); - e.stopPropagation(); - - topSubmit.trigger('click'); - } - bottomSubmit.on('click', triggerSubmitClick); - } - - // Marry the secondary "Bulk actions" controls to the primary controls: - marryControls( $('#bulk-action-selector-top'), $('#doaction'), $('#bulk-action-selector-bottom'), $('#doaction2') ); - - // Marry the secondary "Change role to" controls to the primary controls: - marryControls( $('#new_role'), $('#changeit'), $('#new_role2'), $('#changeit2') ); - - var addAdminNotice = function( data ) { - var $notice = $( data.selector ), - $headerEnd = $( '.wp-header-end' ), - type, - dismissible, - $adminNotice; - - delete data.selector; - - dismissible = ( data.dismissible && data.dismissible === true ) ? ' is-dismissible' : ''; - type = ( data.type ) ? data.type : 'info'; - - $adminNotice = '

' + data.message + '

'; - - // Check if this admin notice already exists. - if ( ! $notice.length ) { - $notice = $( '#' + data.id ); - } - - if ( $notice.length ) { - $notice.replaceWith( $adminNotice ); - } else if ( $headerEnd.length ) { - $headerEnd.after( $adminNotice ); - } else { - if ( 'customize' === pagenow ) { - $( '.customize-themes-notifications' ).append( $adminNotice ); - } else { - $( '.wrap' ).find( '> h1' ).after( $adminNotice ); - } - } - - $document.trigger( 'wp-notice-added' ); - }; - - $( '.bulkactions' ).parents( 'form' ).on( 'submit', function( event ) { - var form = this, - submitterName = event.originalEvent && event.originalEvent.submitter ? event.originalEvent.submitter.name : false, - currentPageSelector = form.querySelector( '#current-page-selector' ); - - if ( currentPageSelector && currentPageSelector.defaultValue !== currentPageSelector.value ) { - return; // Pagination form submission. - } - - // Observe submissions from posts lists for 'bulk_action' or users lists for 'new_role'. - var bulkFieldRelations = { - 'bulk_action' : window.bulkActionObserverIds.bulk_action, - 'changeit' : window.bulkActionObserverIds.changeit - }; - if ( ! Object.keys( bulkFieldRelations ).includes( submitterName ) ) { - return; - } - - var values = new FormData(form); - var value = values.get( bulkFieldRelations[ submitterName ] ) || '-1'; - - // Check that the action is not the default one. - if ( value !== '-1' ) { - // Check that at least one item is selected. - var itemsSelected = form.querySelectorAll( '.wp-list-table tbody .check-column input[type="checkbox"]:checked' ); - - if ( itemsSelected.length > 0 ) { - return; - } - } - event.preventDefault(); - event.stopPropagation(); - $( 'html, body' ).animate( { scrollTop: 0 } ); - - var errorMessage = value !== '-1' ? - __( 'Please select at least one item to perform this action on.' ) : - __( 'Please select a bulk action to perform.' ); - addAdminNotice( { - id: value !== '-1' ? 'no-items-selected' : 'no-bulk-action-selected', - type: 'error', - message: errorMessage, - dismissible: true, - } ); - - wp.a11y.speak( errorMessage ); - }); - - /** - * Shows row actions on focus of its parent container element or any other elements contained within. - * - * @return {void} - */ - $( '#wpbody-content' ).on({ - focusin: function() { - clearTimeout( transitionTimeout ); - focusedRowActions = $( this ).find( '.row-actions' ); - // transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help. - $( '.row-actions' ).not( this ).removeClass( 'visible' ); - focusedRowActions.addClass( 'visible' ); - }, - focusout: function() { - // Tabbing between post title and .row-actions links needs a brief pause, otherwise - // the .row-actions div gets hidden in transit in some browsers (ahem, Firefox). - transitionTimeout = setTimeout( function() { - focusedRowActions.removeClass( 'visible' ); - }, 30 ); - } - }, '.table-view-list .has-row-actions' ); - - // Toggle list table rows on small screens. - $( 'tbody' ).on( 'click', '.toggle-row', function() { - $( this ).closest( 'tr' ).toggleClass( 'is-expanded' ); - }); - - $('#default-password-nag-no').on( 'click', function() { - setUserSetting('default_password_nag', 'hide'); - $('div.default-password-nag').hide(); - return false; - }); - - /** - * Handles tab keypresses in theme and plugin file editor textareas. - * - * @param {Event} e The event object. - * - * @return {void} - */ - $('#newcontent').on('keydown.wpevent_InsertTab', function(e) { - var el = e.target, selStart, selEnd, val, scroll, sel; - - // After pressing escape key (keyCode: 27), the tab key should tab out of the textarea. - if ( e.keyCode == 27 ) { - // When pressing Escape: Opera 12 and 27 blur form fields, IE 8 clears them. - e.preventDefault(); - $(el).data('tab-out', true); - return; - } - - // Only listen for plain tab key (keyCode: 9) without any modifiers. - if ( e.keyCode != 9 || e.ctrlKey || e.altKey || e.shiftKey ) - return; - - // After tabbing out, reset it so next time the tab key can be used again. - if ( $(el).data('tab-out') ) { - $(el).data('tab-out', false); - return; - } - - selStart = el.selectionStart; - selEnd = el.selectionEnd; - val = el.value; - - // If any text is selected, replace the selection with a tab character. - if ( document.selection ) { - el.focus(); - sel = document.selection.createRange(); - sel.text = '\t'; - } else if ( selStart >= 0 ) { - scroll = this.scrollTop; - el.value = val.substring(0, selStart).concat('\t', val.substring(selEnd) ); - el.selectionStart = el.selectionEnd = selStart + 1; - this.scrollTop = scroll; - } - - // Cancel the regular tab functionality, to prevent losing focus of the textarea. - if ( e.stopPropagation ) - e.stopPropagation(); - if ( e.preventDefault ) - e.preventDefault(); - }); - - // Reset page number variable for new filters/searches but not for bulk actions. See #17685. - if ( pageInput.length ) { - - /** - * Handles pagination variable when filtering the list table. - * - * Set the pagination argument to the first page when the post-filter form is submitted. - * This happens when pressing the 'filter' button on the list table page. - * - * The pagination argument should not be touched when the bulk action dropdowns are set to do anything. - * - * The form closest to the pageInput is the post-filter form. - * - * @return {void} - */ - pageInput.closest('form').on( 'submit', function() { - /* - * action = bulk action dropdown at the top of the table - */ - if ( $('select[name="action"]').val() == -1 && pageInput.val() == currentPage ) - pageInput.val('1'); - }); - } - - /** - * Resets the bulk actions when the search button is clicked. - * - * @return {void} - */ - $('.search-box input[type="search"], .search-box input[type="submit"]').on( 'mousedown', function () { - $('select[name^="action"]').val('-1'); - }); - - /** - * Scrolls into view when focus.scroll-into-view is triggered. - * - * @param {Event} e The event object. - * - * @return {void} - */ - $('#contextual-help-link, #show-settings-link').on( 'focus.scroll-into-view', function(e){ - if ( e.target.scrollIntoViewIfNeeded ) - e.target.scrollIntoViewIfNeeded(false); - }); - - /** - * Disables the submit upload buttons when no data is entered. - * - * @return {void} - */ - (function(){ - var button, input, form = $('form.wp-upload-form'); - - // Exit when no upload form is found. - if ( ! form.length ) - return; - - button = form.find('input[type="submit"]'); - input = form.find('input[type="file"]'); - - /** - * Determines if any data is entered in any file upload input. - * - * @since 3.5.0 - * - * @return {void} - */ - function toggleUploadButton() { - // When no inputs have a value, disable the upload buttons. - button.prop('disabled', '' === input.map( function() { - return $(this).val(); - }).get().join('')); - } - - // Update the status initially. - toggleUploadButton(); - // Update the status when any file input changes. - input.on('change', toggleUploadButton); - })(); - - /** - * Pins the menu while distraction-free writing is enabled. - * - * @param {Event} event Event data. - * - * @since 4.1.0 - * - * @return {void} - */ - function pinMenu( event ) { - var windowPos = $window.scrollTop(), - resizing = ! event || event.type !== 'scroll'; - - if ( isIOS || $adminmenu.data( 'wp-responsive' ) ) { - return; - } - - /* - * When the menu is higher than the window and smaller than the entire page. - * It should be adjusted to be able to see the entire menu. - * - * Otherwise it can be accessed normally. - */ - if ( height.menu + height.adminbar < height.window || - height.menu + height.adminbar + 20 > height.wpwrap ) { - unpinMenu(); - return; - } - - menuIsPinned = true; - - // If the menu is higher than the window, compensate on scroll. - if ( height.menu + height.adminbar > height.window ) { - // Check for overscrolling, this happens when swiping up at the top of the document in modern browsers. - if ( windowPos < 0 ) { - // Stick the menu to the top. - if ( ! pinnedMenuTop ) { - pinnedMenuTop = true; - pinnedMenuBottom = false; - - $adminMenuWrap.css({ - position: 'fixed', - top: '', - bottom: '' - }); - } - - return; - } else if ( windowPos + height.window > $document.height() - 1 ) { - // When overscrolling at the bottom, stick the menu to the bottom. - if ( ! pinnedMenuBottom ) { - pinnedMenuBottom = true; - pinnedMenuTop = false; - - $adminMenuWrap.css({ - position: 'fixed', - top: '', - bottom: 0 - }); - } - - return; - } - - if ( windowPos > lastScrollPosition ) { - // When a down scroll has been detected. - - // If it was pinned to the top, unpin and calculate relative scroll. - if ( pinnedMenuTop ) { - pinnedMenuTop = false; - // Calculate new offset position. - menuTop = $adminMenuWrap.offset().top - height.adminbar - ( windowPos - lastScrollPosition ); - - if ( menuTop + height.menu + height.adminbar < windowPos + height.window ) { - menuTop = windowPos + height.window - height.menu - height.adminbar; - } - - $adminMenuWrap.css({ - position: 'absolute', - top: menuTop, - bottom: '' - }); - } else if ( ! pinnedMenuBottom && $adminMenuWrap.offset().top + height.menu < windowPos + height.window ) { - // Pin it to the bottom. - pinnedMenuBottom = true; - - $adminMenuWrap.css({ - position: 'fixed', - top: '', - bottom: 0 - }); - } - } else if ( windowPos < lastScrollPosition ) { - // When a scroll up is detected. - - // If it was pinned to the bottom, unpin and calculate relative scroll. - if ( pinnedMenuBottom ) { - pinnedMenuBottom = false; - - // Calculate new offset position. - menuTop = $adminMenuWrap.offset().top - height.adminbar + ( lastScrollPosition - windowPos ); - - if ( menuTop + height.menu > windowPos + height.window ) { - menuTop = windowPos; - } - - $adminMenuWrap.css({ - position: 'absolute', - top: menuTop, - bottom: '' - }); - } else if ( ! pinnedMenuTop && $adminMenuWrap.offset().top >= windowPos + height.adminbar ) { - - // Pin it to the top. - pinnedMenuTop = true; - - $adminMenuWrap.css({ - position: 'fixed', - top: '', - bottom: '' - }); - } - } else if ( resizing ) { - // Window is being resized. - - pinnedMenuTop = pinnedMenuBottom = false; - - // Calculate the new offset. - menuTop = windowPos + height.window - height.menu - height.adminbar - 1; - - if ( menuTop > 0 ) { - $adminMenuWrap.css({ - position: 'absolute', - top: menuTop, - bottom: '' - }); - } else { - unpinMenu(); - } - } - } - - lastScrollPosition = windowPos; - } - - /** - * Determines the height of certain elements. - * - * @since 4.1.0 - * - * @return {void} - */ - function resetHeights() { - height = { - window: $window.height(), - wpwrap: $wpwrap.height(), - adminbar: $adminbar.height(), - menu: $adminMenuWrap.height() - }; - } - - /** - * Unpins the menu. - * - * @since 4.1.0 - * - * @return {void} - */ - function unpinMenu() { - if ( isIOS || ! menuIsPinned ) { - return; - } - - pinnedMenuTop = pinnedMenuBottom = menuIsPinned = false; - $adminMenuWrap.css({ - position: '', - top: '', - bottom: '' - }); - } - - /** - * Pins and unpins the menu when applicable. - * - * @since 4.1.0 - * - * @return {void} - */ - function setPinMenu() { - resetHeights(); - - if ( $adminmenu.data('wp-responsive') ) { - $body.removeClass( 'sticky-menu' ); - unpinMenu(); - } else if ( height.menu + height.adminbar > height.window ) { - pinMenu(); - $body.removeClass( 'sticky-menu' ); - } else { - $body.addClass( 'sticky-menu' ); - unpinMenu(); - } - } - - if ( ! isIOS ) { - $window.on( 'scroll.pin-menu', pinMenu ); - $document.on( 'tinymce-editor-init.pin-menu', function( event, editor ) { - editor.on( 'wp-autoresize', resetHeights ); - }); - } - - /** - * Changes the sortables and responsiveness of metaboxes. - * - * @since 3.8.0 - * - * @return {void} - */ - window.wpResponsive = { - - /** - * Initializes the wpResponsive object. - * - * @since 3.8.0 - * - * @return {void} - */ - init: function() { - var self = this; - - this.maybeDisableSortables = this.maybeDisableSortables.bind( this ); - - // Modify functionality based on custom activate/deactivate event. - $document.on( 'wp-responsive-activate.wp-responsive', function() { - self.activate(); - self.toggleAriaHasPopup( 'add' ); - }).on( 'wp-responsive-deactivate.wp-responsive', function() { - self.deactivate(); - self.toggleAriaHasPopup( 'remove' ); - }); - - $( '#wp-admin-bar-menu-toggle a' ).attr( 'aria-expanded', 'false' ); - - // Toggle sidebar when toggle is clicked. - $( '#wp-admin-bar-menu-toggle' ).on( 'click.wp-responsive', function( event ) { - event.preventDefault(); - - // Close any open toolbar submenus. - $adminbar.find( '.hover' ).removeClass( 'hover' ); - - $wpwrap.toggleClass( 'wp-responsive-open' ); - if ( $wpwrap.hasClass( 'wp-responsive-open' ) ) { - $(this).find('a').attr( 'aria-expanded', 'true' ); - $( '#adminmenu a:first' ).trigger( 'focus' ); - } else { - $(this).find('a').attr( 'aria-expanded', 'false' ); - } - } ); - - // Close sidebar when target moves outside of toggle and sidebar. - $( document ).on( 'click', function( event ) { - if ( ! $wpwrap.hasClass( 'wp-responsive-open' ) || ! document.hasFocus() ) { - return; - } - - var focusIsInToggle = $.contains( $( '#wp-admin-bar-menu-toggle' )[0], event.target ); - var focusIsInSidebar = $.contains( $( '#adminmenuwrap' )[0], event.target ); - - if ( ! focusIsInToggle && ! focusIsInSidebar ) { - $( '#wp-admin-bar-menu-toggle' ).trigger( 'click.wp-responsive' ); - } - } ); - - // Close sidebar when a keypress completes outside of toggle and sidebar. - $( document ).on( 'keyup', function( event ) { - var toggleButton = $( '#wp-admin-bar-menu-toggle' )[0]; - if ( ! $wpwrap.hasClass( 'wp-responsive-open' ) ) { - return; - } - if ( 27 === event.keyCode ) { - $( toggleButton ).trigger( 'click.wp-responsive' ); - $( toggleButton ).find( 'a' ).trigger( 'focus' ); - } else { - if ( 9 === event.keyCode ) { - var sidebar = $( '#adminmenuwrap' )[0]; - var focusedElement = event.relatedTarget || document.activeElement; - // A brief delay is required to allow focus to switch to another element. - setTimeout( function() { - var focusIsInToggle = $.contains( toggleButton, focusedElement ); - var focusIsInSidebar = $.contains( sidebar, focusedElement ); - - if ( ! focusIsInToggle && ! focusIsInSidebar ) { - $( toggleButton ).trigger( 'click.wp-responsive' ); - } - }, 10 ); - } - } - }); - - // Add menu events. - $adminmenu.on( 'click.wp-responsive', 'li.wp-has-submenu > a', function( event ) { - if ( ! $adminmenu.data('wp-responsive') ) { - return; - } - let state = ( 'false' === $( this ).attr( 'aria-expanded' ) ) ? 'true' : 'false'; - $( this ).parent( 'li' ).toggleClass( 'selected' ); - $( this ).attr( 'aria-expanded', state ); - $( this ).trigger( 'focus' ); - event.preventDefault(); - }); - - self.trigger(); - $document.on( 'wp-window-resized.wp-responsive', this.trigger.bind( this ) ); - - // This needs to run later as UI Sortable may be initialized when the document is ready. - $window.on( 'load.wp-responsive', this.maybeDisableSortables ); - $document.on( 'postbox-toggled', this.maybeDisableSortables ); - - // When the screen columns are changed, potentially disable sortables. - $( '#screen-options-wrap input' ).on( 'click', this.maybeDisableSortables ); - }, - - /** - * Disable sortables if there is only one metabox, or the screen is in one column mode. Otherwise, enable sortables. - * - * @since 5.3.0 - * - * @return {void} - */ - maybeDisableSortables: function() { - var width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? $window.width() : window.innerWidth; - - if ( - ( width <= 782 ) || - ( 1 >= $sortables.find( '.ui-sortable-handle:visible' ).length && jQuery( '.columns-prefs-1 input' ).prop( 'checked' ) ) - ) { - this.disableSortables(); - } else { - this.enableSortables(); - } - }, - - /** - * Changes properties of body and admin menu. - * - * Pins and unpins the menu and adds the auto-fold class to the body. - * Makes the admin menu responsive and disables the metabox sortables. - * - * @since 3.8.0 - * - * @return {void} - */ - activate: function() { - setPinMenu(); - - if ( ! $body.hasClass( 'auto-fold' ) ) { - $body.addClass( 'auto-fold' ); - } - - $adminmenu.data( 'wp-responsive', 1 ); - this.disableSortables(); - }, - - /** - * Changes properties of admin menu and enables metabox sortables. - * - * Pin and unpin the menu. - * Removes the responsiveness of the admin menu and enables the metabox sortables. - * - * @since 3.8.0 - * - * @return {void} - */ - deactivate: function() { - setPinMenu(); - $adminmenu.removeData('wp-responsive'); - - this.maybeDisableSortables(); - }, - - /** - * Toggles the aria-haspopup attribute for the responsive admin menu. - * - * The aria-haspopup attribute is only necessary for the responsive menu. - * See ticket https://core.trac.wordpress.org/ticket/43095 - * - * @since 6.6.0 - * - * @param {string} action Whether to add or remove the aria-haspopup attribute. - * - * @return {void} - */ - toggleAriaHasPopup: function( action ) { - var elements = $adminmenu.find( '[data-ariahaspopup]' ); - - if ( action === 'add' ) { - elements.each( function() { - $( this ).attr( 'aria-haspopup', 'menu' ).attr( 'aria-expanded', 'false' ); - } ); - - return; - } - - elements.each( function() { - $( this ).removeAttr( 'aria-haspopup' ).removeAttr( 'aria-expanded' ); - } ); - }, - - /** - * Sets the responsiveness and enables the overlay based on the viewport width. - * - * @since 3.8.0 - * - * @return {void} - */ - trigger: function() { - var viewportWidth = getViewportWidth(); - - // Exclude IE < 9, it doesn't support @media CSS rules. - if ( ! viewportWidth ) { - return; - } - - if ( viewportWidth <= 782 ) { - if ( ! wpResponsiveActive ) { - $document.trigger( 'wp-responsive-activate' ); - wpResponsiveActive = true; - } - } else { - if ( wpResponsiveActive ) { - $document.trigger( 'wp-responsive-deactivate' ); - wpResponsiveActive = false; - } - } - - if ( viewportWidth <= 480 ) { - this.enableOverlay(); - } else { - this.disableOverlay(); - } - - this.maybeDisableSortables(); - }, - - /** - * Inserts a responsive overlay and toggles the window. - * - * @since 3.8.0 - * - * @return {void} - */ - enableOverlay: function() { - if ( $overlay.length === 0 ) { - $overlay = $( '
' ) - .insertAfter( '#wpcontent' ) - .hide() - .on( 'click.wp-responsive', function() { - $toolbar.find( '.menupop.hover' ).removeClass( 'hover' ); - $( this ).hide(); - }); - } - - $toolbarPopups.on( 'click.wp-responsive', function() { - $overlay.show(); - }); - }, - - /** - * Disables the responsive overlay and removes the overlay. - * - * @since 3.8.0 - * - * @return {void} - */ - disableOverlay: function() { - $toolbarPopups.off( 'click.wp-responsive' ); - $overlay.hide(); - }, - - /** - * Disables sortables. - * - * @since 3.8.0 - * - * @return {void} - */ - disableSortables: function() { - if ( $sortables.length ) { - try { - $sortables.sortable( 'disable' ); - $sortables.find( '.ui-sortable-handle' ).addClass( 'is-non-sortable' ); - } catch ( e ) {} - } - }, - - /** - * Enables sortables. - * - * @since 3.8.0 - * - * @return {void} - */ - enableSortables: function() { - if ( $sortables.length ) { - try { - $sortables.sortable( 'enable' ); - $sortables.find( '.ui-sortable-handle' ).removeClass( 'is-non-sortable' ); - } catch ( e ) {} - } - } - }; - - /** - * Add an ARIA role `button` to elements that behave like UI controls when JavaScript is on. - * - * @since 4.5.0 - * - * @return {void} - */ - function aria_button_if_js() { - $( '.aria-button-if-js' ).attr( 'role', 'button' ); - } - - $( document ).on( 'ajaxComplete', function() { - aria_button_if_js(); - }); - - /** - * Get the viewport width. - * - * @since 4.7.0 - * - * @return {number|boolean} The current viewport width or false if the - * browser doesn't support innerWidth (IE < 9). - */ - function getViewportWidth() { - var viewportWidth = false; - - if ( window.innerWidth ) { - // On phones, window.innerWidth is affected by zooming. - viewportWidth = Math.max( window.innerWidth, document.documentElement.clientWidth ); - } - - return viewportWidth; - } - - /** - * Sets the admin menu collapsed/expanded state. - * - * Sets the global variable `menuState` and triggers a custom event passing - * the current menu state. - * - * @since 4.7.0 - * - * @return {void} - */ - function setMenuState() { - var viewportWidth = getViewportWidth() || 961; - - if ( viewportWidth <= 782 ) { - menuState = 'responsive'; - } else if ( $body.hasClass( 'folded' ) || ( $body.hasClass( 'auto-fold' ) && viewportWidth <= 960 && viewportWidth > 782 ) ) { - menuState = 'folded'; - } else { - menuState = 'open'; - } - - $document.trigger( 'wp-menu-state-set', { state: menuState } ); - } - - // Set the menu state when the window gets resized. - $document.on( 'wp-window-resized.set-menu-state', setMenuState ); - - /** - * Sets ARIA attributes on the collapse/expand menu button. - * - * When the admin menu is open or folded, updates the `aria-expanded` and - * `aria-label` attributes of the button to give feedback to assistive - * technologies. In the responsive view, the button is always hidden. - * - * @since 4.7.0 - * - * @return {void} - */ - $document.on( 'wp-menu-state-set wp-collapse-menu', function( event, eventData ) { - var $collapseButton = $( '#collapse-button' ), - ariaExpanded, ariaLabelText; - - if ( 'folded' === eventData.state ) { - ariaExpanded = 'false'; - ariaLabelText = __( 'Expand Main menu' ); - } else { - ariaExpanded = 'true'; - ariaLabelText = __( 'Collapse Main menu' ); - } - - $collapseButton.attr({ - 'aria-expanded': ariaExpanded, - 'aria-label': ariaLabelText - }); - }); - - window.wpResponsive.init(); - setPinMenu(); - setMenuState(); - makeNoticesDismissible(); - aria_button_if_js(); - - $document.on( 'wp-pin-menu wp-window-resized.pin-menu postboxes-columnchange.pin-menu postbox-toggled.pin-menu wp-collapse-menu.pin-menu wp-scroll-start.pin-menu', setPinMenu ); - - // Set initial focus on a specific element. - $( '.wp-initial-focus' ).trigger( 'focus' ); - - // Toggle update details on update-core.php. - $body.on( 'click', '.js-update-details-toggle', function() { - var $updateNotice = $( this ).closest( '.js-update-details' ), - $progressDiv = $( '#' + $updateNotice.data( 'update-details' ) ); - - /* - * When clicking on "Show details" move the progress div below the update - * notice. Make sure it gets moved just the first time. - */ - if ( ! $progressDiv.hasClass( 'update-details-moved' ) ) { - $progressDiv.insertAfter( $updateNotice ).addClass( 'update-details-moved' ); - } - - // Toggle the progress div visibility. - $progressDiv.toggle(); - // Toggle the Show Details button expanded state. - $( this ).attr( 'aria-expanded', $progressDiv.is( ':visible' ) ); - }); -}); - -/** - * Hides the update button for expired plugin or theme uploads. - * - * On the "Update plugin/theme from uploaded zip" screen, once the upload has expired, - * hides the "Replace current with uploaded" button and displays a warning. - * - * @since 5.5.0 - */ -$( function( $ ) { - var $overwrite, $warning; - - if ( ! $body.hasClass( 'update-php' ) ) { - return; - } - - $overwrite = $( 'a.update-from-upload-overwrite' ); - $warning = $( '.update-from-upload-expired' ); - - if ( ! $overwrite.length || ! $warning.length ) { - return; - } - - window.setTimeout( - function() { - $overwrite.hide(); - $warning.removeClass( 'hidden' ); - - if ( window.wp && window.wp.a11y ) { - window.wp.a11y.speak( $warning.text() ); - } - }, - 7140000 // 119 minutes. The uploaded file is deleted after 2 hours. - ); -} ); - -// Fire a custom jQuery event at the end of window resize. -( function() { - var timeout; - - /** - * Triggers the WP window-resize event. - * - * @since 3.8.0 - * - * @return {void} - */ - function triggerEvent() { - $document.trigger( 'wp-window-resized' ); - } - - /** - * Fires the trigger event again after 200 ms. - * - * @since 3.8.0 - * - * @return {void} - */ - function fireOnce() { - window.clearTimeout( timeout ); - timeout = window.setTimeout( triggerEvent, 200 ); - } - - $window.on( 'resize.wp-fire-once', fireOnce ); -}()); - -// Make Windows 8 devices play along nicely. -(function(){ - if ( '-ms-user-select' in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/) ) { - var msViewportStyle = document.createElement( 'style' ); - msViewportStyle.appendChild( - document.createTextNode( '@-ms-viewport{width:auto!important}' ) - ); - document.getElementsByTagName( 'head' )[0].appendChild( msViewportStyle ); - } -})(); - -}( jQuery, window )); - -/** - * Freeze animated plugin icons when reduced motion is enabled. - * - * When the user has enabled the 'prefers-reduced-motion' setting, this module - * stops animations for all GIFs on the page with the class 'plugin-icon' or - * plugin icon images in the update plugins table. - * - * @since 6.4.0 - */ -(function() { - // Private variables and methods. - var priv = {}, - pub = {}, - mediaQuery; - - // Initialize pauseAll to false; it will be set to true if reduced motion is preferred. - priv.pauseAll = false; - if ( window.matchMedia ) { - mediaQuery = window.matchMedia( '(prefers-reduced-motion: reduce)' ); - if ( ! mediaQuery || mediaQuery.matches ) { - priv.pauseAll = true; - } - } - - // Method to replace animated GIFs with a static frame. - priv.freezeAnimatedPluginIcons = function( img ) { - var coverImage = function() { - var width = img.width; - var height = img.height; - var canvas = document.createElement( 'canvas' ); - - // Set canvas dimensions. - canvas.width = width; - canvas.height = height; - - // Copy classes from the image to the canvas. - canvas.className = img.className; - - // Check if the image is inside a specific table. - var isInsideUpdateTable = img.closest( '#update-plugins-table' ); - - if ( isInsideUpdateTable ) { - // Transfer computed styles from image to canvas. - var computedStyles = window.getComputedStyle( img ), - i, max; - for ( i = 0, max = computedStyles.length; i < max; i++ ) { - var propName = computedStyles[ i ]; - var propValue = computedStyles.getPropertyValue( propName ); - canvas.style[ propName ] = propValue; - } - } - - // Draw the image onto the canvas. - canvas.getContext( '2d' ).drawImage( img, 0, 0, width, height ); - - // Set accessibility attributes on canvas. - canvas.setAttribute( 'aria-hidden', 'true' ); - canvas.setAttribute( 'role', 'presentation' ); - - // Insert canvas before the image and set the image to be near-invisible. - var parent = img.parentNode; - parent.insertBefore( canvas, img ); - img.style.opacity = 0.01; - img.style.width = '0px'; - img.style.height = '0px'; - }; - - // If the image is already loaded, apply the coverImage function. - if ( img.complete ) { - coverImage(); - } else { - // Otherwise, wait for the image to load. - img.addEventListener( 'load', coverImage, true ); - } - }; - - // Public method to freeze all relevant GIFs on the page. - pub.freezeAll = function() { - var images = document.querySelectorAll( '.plugin-icon, #update-plugins-table img' ); - for ( var x = 0; x < images.length; x++ ) { - if ( /\.gif(?:\?|$)/i.test( images[ x ].src ) ) { - priv.freezeAnimatedPluginIcons( images[ x ] ); - } - } - }; - - // Only run the freezeAll method if the user prefers reduced motion. - if ( true === priv.pauseAll ) { - pub.freezeAll(); - } - - // Listen for jQuery AJAX events. - ( function( $ ) { - if ( window.pagenow === 'plugin-install' ) { - // Only listen for ajaxComplete if this is the plugin-install.php page. - $( document ).ajaxComplete( function( event, xhr, settings ) { - - // Check if this is the 'search-install-plugins' request. - if ( settings.data && typeof settings.data === 'string' && settings.data.includes( 'action=search-install-plugins' ) ) { - // Recheck if the user prefers reduced motion. - if ( window.matchMedia ) { - var mediaQuery = window.matchMedia( '(prefers-reduced-motion: reduce)' ); - if ( mediaQuery.matches ) { - pub.freezeAll(); - } - } else { - // Fallback for browsers that don't support matchMedia. - if ( true === priv.pauseAll ) { - pub.freezeAll(); - } - } - } - } ); - } - } )( jQuery ); - - // Expose public methods. - return pub; -})(); - -/** - * Validate the delete-and-reassign users form and surface an accessible - * error summary instead of disabling the submit button. - * - * Disabled buttons can't be discovered by assistive technology, so rather - * than blocking submission we let the form submit, intercept it when content - * decisions are still missing, and present a focusable error summary that - * lists how many decisions remain and links straight to each one. - * - * Shared by both the single-site (wp-admin/users.php) and multisite/network - * (confirm_delete_users() in wp-admin/includes/ms.php) deletion forms. The two - * differ in markup: single site has one content decision per user, multisite - * has one decision per site a user belongs to (several radio groups per - * fieldset), and their reassign dropdowns use different "no selection" values. - * The logic below works per radio group so it covers both. - * - * @since 7.1.0 - */ -(function(){ - const { _n, sprintf } = wp.i18n; - const usersForm = document.querySelector( '.delete-and-reassign-users-form' ); - - // Check if the form exists and contains any radio buttons. - if ( ! usersForm || ! usersForm.querySelector( 'input[type="radio"]' ) ) { - return; - } - - const summaryId = 'delete-users-error-summary'; - - /** - * Whether a reassign dropdown has no user selected. - * - * The "Select a user" placeholder value differs between the forms: the - * single-site dropdown uses an empty string, the multisite one uses the - * wp_dropdown_users() default of '-1'. - * - * @param {HTMLSelectElement} select The reassign dropdown. - * @return {boolean} True when no real user is selected. - */ - function hasNoSelectedUser( select ) { - return '' === select.value || '-1' === select.value; - } - - /** - * Builds a human-readable label for a radio group's decision. - * - * Combines the fieldset legend (the user) with the site context that - * precedes the group on multisite, so each summary entry is identifiable. - * - * @param {HTMLElement} group The radio group (