WordPress.org

Make WordPress Core

Changeset 31949


Ignore:
Timestamp:
04/01/2015 02:47:55 AM (6 years ago)
Author:
jorbin
Message:

Refine UI for FTP modal and shiny updates

Numerous changes to make the FTP modal experience a good one. These include:

  • Update HTML used by both the form here and the form on the standalone screen
  • Allow users to cancel FTP install
  • Focus locking in the modal
  • Focus on modal form on load
  • ARIA Attributes
  • Style Enhancements
  • Add low screen height (such as phone and some tablets) friendly experience for entering credentials

Props ericlewis, afercia
Fixes #31608

Location:
trunk/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/forms.css

    r31811 r31949  
    865865}
    866866
    867 .request-filesystem-credentials-dialog-content input[type="text"],
    868 .request-filesystem-credentials-dialog-content input[type="password"] {
    869     width: 85%;
    870 }
     867.request-filesystem-credentials-form input[type="text"],
     868.request-filesystem-credentials-form input[type="password"] {
     869    display: block;
     870}
     871
     872.request-filesystem-credentials-dialog input[type="text"],
     873.request-filesystem-credentials-dialog input[type="password"] {
     874    width: 100%;
     875}
     876
     877.request-filesystem-credentials-form .field-title {
     878    font-weight: 600;
     879}
     880
     881.request-filesystem-credentials-dialog label[for="hostname"],
     882.request-filesystem-credentials-dialog label[for="public_key"],
     883.request-filesystem-credentials-dialog label[for="private_key"] {
     884    display: block;
     885    margin-bottom: 1em;
     886}
     887
     888.request-filesystem-credentials-dialog .ftp-username,
     889.request-filesystem-credentials-dialog .ftp-password {
     890    float: left;
     891    width: 48%;
     892}
     893
     894.request-filesystem-credentials-dialog .ftp-password {
     895    margin-left: 4%;
     896}
     897
     898.request-filesystem-credentials-dialog .request-filesystem-credentials-action-buttons {
     899    text-align: right;
     900}
     901
     902.request-filesystem-credentials-dialog label[for="ftp"] {
     903    margin-right: 10px;
     904}
     905
     906#request-filesystem-credentials-dialog .button:not(:last-child) {
     907    margin-right: 10px;
     908}
     909
     910#request-filesystem-credentials-form .cancel-button {
     911    display: none;
     912}
     913
     914#request-filesystem-credentials-dialog .cancel-button {
     915    display: inline;
     916}
     917
    871918
    872919/* =Media Queries
     
    10991146        width: auto;
    11001147    }
     1148
     1149}
     1150
     1151@media only screen and (max-height: 480px) {
     1152    /*  Request Credentials */
     1153    .request-filesystem-credentials-dialog  .notification-dialog{
     1154        width: 100%;
     1155        height: 100%;
     1156        position: fixed;
     1157        top: 0;
     1158        margin: 0;
     1159        left: 0;
     1160        overflow-y: auto;
     1161    }
    11011162}
    11021163
  • trunk/src/wp-admin/includes/file.php

    r31936 r31949  
    11261126</script>
    11271127<form action="<?php echo esc_url( $form_post ) ?>" method="post">
    1128 <div>
    1129 <h3><?php _e('Connection Information') ?></h3>
    1130 <p><?php
     1128<div id="request-filesystem-credentials-form" class="request-filesystem-credentials-form">
     1129<h3 id="request-filesystem-credentials-title"><?php _e( 'Connection Information' ) ?></h3>
     1130<p id="request-filesystem-credentials-desc"><?php
    11311131    $label_user = __('Username');
    11321132    $label_pass = __('Password');
     
    11471147    _e('If you do not remember your credentials, you should contact your web host.');
    11481148?></p>
    1149 <table class="form-table">
    1150 <tr>
    1151 <th scope="row"><label for="hostname"><?php _e('Hostname') ?></label></th>
    1152 <td><input name="hostname" type="text" id="hostname" value="<?php echo esc_attr($hostname); if ( !empty($port) ) echo ":$port"; ?>"<?php disabled( defined('FTP_HOST') ); ?> size="40" /></td>
    1153 </tr>
    1154 
    1155 <tr>
    1156 <th scope="row"><label for="username"><?php echo $label_user; ?></label></th>
    1157 <td><input name="username" type="text" id="username" value="<?php echo esc_attr($username) ?>"<?php disabled( defined('FTP_USER') ); ?> size="40" /></td>
    1158 </tr>
    1159 
    1160 <tr>
    1161 <th scope="row"><label for="password"><?php echo $label_pass; ?></label></th>
    1162 <td><div><input name="password" type="password" id="password" value="<?php if ( defined('FTP_PASS') ) echo '*****'; ?>"<?php disabled( defined('FTP_PASS') ); ?> size="40" /></div>
    1163 <div><em><?php if ( ! defined('FTP_PASS') ) _e( 'This password will not be stored on the server.' ); ?></em></div></td>
    1164 </tr>
    1165 
     1149<label for="hostname">
     1150    <span class="field-title"><?php _e( 'Hostname' ) ?></span>
     1151    <input name="hostname" type="text" id="hostname" aria-describedby="request-filesystem-credentials-desc" class="code" placeholder="<?php esc_attr_e( __( 'example: www.mysite.com' ) ) ?>" value="<?php echo esc_attr($hostname); if ( !empty($port) ) echo ":$port"; ?>"<?php disabled( defined('FTP_HOST') ); ?> />
     1152</label>
     1153<div class="ftp-username">
     1154    <label for="username">
     1155        <span class="field-title"><?php echo $label_user; ?></span>
     1156        <input name="username" type="text" id="username" value="<?php echo esc_attr($username) ?>"<?php disabled( defined('FTP_USER') ); ?> />
     1157    </label>
     1158</div>
     1159<div class="ftp-password">
     1160    <label for="password">
     1161        <span class="field-title"><?php echo $label_pass; ?></span>
     1162        <input name="password" type="password" id="password" value="<?php if ( defined('FTP_PASS') ) echo '*****'; ?>"<?php disabled( defined('FTP_PASS') ); ?> />
     1163        <em><?php if ( ! defined('FTP_PASS') ) _e( 'This password will not be stored on the server.' ); ?></em>
     1164    </label>
     1165</div>
    11661166<?php if ( isset($types['ssh']) ) : ?>
    1167 <tr id="ssh_keys" style="<?php if ( 'ssh' != $connection_type ) echo 'display:none' ?>">
    1168 <th scope="row"><?php _e('Authentication Keys') ?>
    1169 <div class="key-labels textright">
    1170 <label for="public_key"><?php _e('Public Key:') ?></label ><br />
    1171 <label for="private_key"><?php _e('Private Key:') ?></label>
    1172 </div></th>
    1173 <td><br /><input name="public_key" type="text" id="public_key" value="<?php echo esc_attr($public_key) ?>"<?php disabled( defined('FTP_PUBKEY') ); ?> size="40" />
    1174     <br /><input name="private_key" type="text" id="private_key" value="<?php echo esc_attr($private_key) ?>"<?php disabled( defined('FTP_PRIKEY') ); ?> size="40" />
    1175 <div><?php _e('Enter the location on the server where the keys are located. If a passphrase is needed, enter that in the password field above.') ?></div></td>
    1176 </tr>
     1167<h4><?php _e('Authentication Keys') ?></h4>
     1168<label for="public_key">
     1169    <span class="field-title"><?php _e('Public Key:') ?></span>
     1170    <input name="public_key" type="text" id="public_key" aria-describedby="auth-keys-desc" value="<?php echo esc_attr($public_key) ?>"<?php disabled( defined('FTP_PUBKEY') ); ?> />
     1171</label>
     1172<label for="private_key">
     1173    <span class="field-title"><?php _e('Private Key:') ?></span>
     1174    <input name="private_key" type="text" id="private_key" value="<?php echo esc_attr($private_key) ?>"<?php disabled( defined('FTP_PRIKEY') ); ?> />
     1175</label>
     1176<span id="auth-keys-desc"><?php _e('Enter the location on the server where the public and private keys are located. If a passphrase is needed, enter that in the password field above.') ?></span>
    11771177<?php endif; ?>
    1178 
    1179 <tr>
    1180 <th scope="row"><?php _e('Connection Type') ?></th>
    1181 <td>
     1178<h4><?php _e('Connection Type') ?></h4>
    11821179<fieldset><legend class="screen-reader-text"><span><?php _e('Connection Type') ?></span></legend>
    11831180<?php
     
    11901187    <?php endforeach; ?>
    11911188</fieldset>
    1192 </td>
    1193 </tr>
    1194 </table>
    1195 
    11961189<?php
    11971190foreach ( (array) $extra_fields as $field ) {
     
    11991192        echo '<input type="hidden" name="' . esc_attr( $field ) . '" value="' . esc_attr( wp_unslash( $_POST[ $field ] ) ) . '" />';
    12001193}
    1201 submit_button( __( 'Proceed' ), 'button', 'upgrade' );
    12021194?>
     1195    <p class="request-filesystem-credentials-action-buttons">
     1196        <button class="button cancel-button" data-js-action="close" type="button"><?php _e( 'Cancel' ); ?></button>
     1197        <?php submit_button( __( 'Proceed' ), 'button', 'upgrade', false ); ?>
     1198    </p>
    12031199</div>
    12041200</form>
     
    12241220    <div id="request-filesystem-credentials-dialog" class="notification-dialog-wrap request-filesystem-credentials-dialog">
    12251221        <div class="notification-dialog-background"></div>
    1226         <div class="notification-dialog">
     1222        <div class="notification-dialog" role="dialog" aria-labelledby="request-filesystem-credentials-title" tabindex="0">
    12271223            <div class="request-filesystem-credentials-dialog-content">
    12281224                <?php request_filesystem_credentials( site_url() ); ?>
  • trunk/src/wp-admin/js/updates.js

    r31900 r31949  
    8080
    8181    /**
     82     * Store a jQuery reference to return focus to when exiting the request credentials modal.
     83     *
     84     * @since 4.2.0
     85     *
     86     * @var jQuery object
     87     */
     88    wp.updates.$elToReturnFocusToFromCredentialsModal = null;
     89
     90    /**
    8291     * Decrement update counts throughout the various menus.
    8392     *
     
    145154
    146155        $message.addClass( 'updating-message' );
     156        if ( $message.html() !== wp.updates.l10n.updating ){
     157            $message.data( 'originaltext', $message.html() );
     158        }
     159
    147160        $message.text( wp.updates.l10n.updating );
    148161        wp.a11y.speak( wp.updates.l10n.updatingMsg );
     
    248261     */
    249262    wp.updates.showErrorInCredentialsForm = function( message ) {
    250         var $notificationDialog = $( '.notification-dialog' );
    251 
    252         // Remove any existing error
    253         $notificationDialog.find( '.error' ).remove();
    254 
    255         $notificationDialog.find( 'h3' ).after( '<div class="error">' + message + '</div>' );
     263        var $modal = $( '.notification-dialog' );
     264
     265        // Remove any existing error.
     266        $modal.find( '.error' ).remove();
     267
     268        $modal.find( 'h3' ).after( '<div class="error">' + message + '</div>' );
    256269    };
    257270
     
    292305
    293306    /**
    294      * Request the users filesystem credentials if we don't have them already
    295      *
    296      * @since 4.2.0
    297      */
    298     wp.updates.requestFilesystemCredentials = function() {
     307     * Request the users filesystem credentials if we don't have them already.
     308     *
     309     * @since 4.2.0
     310     */
     311    wp.updates.requestFilesystemCredentials = function( event ) {
    299312        if ( wp.updates.updateDoneSuccessfully === false ) {
     313            /*
     314             * For the plugin install screen, return the focus to the install button
     315             * after exiting the credentials request modal.
     316             */
     317            if ( 'plugin-install' === pagenow && event ) {
     318                wp.updates.$elToReturnFocusToFromCredentialsModal = $( event.target );
     319            }
     320
    300321            wp.updates.updateLock = true;
    301             $( 'body' ).addClass( 'modal-open' );
    302             $( '#request-filesystem-credentials-dialog' ).show();
    303         }
     322
     323            wp.updates.requestForCredentialsModalOpen();
     324        }
     325    };
     326
     327    /**
     328     * Keydown handler for the request for credentials modal.
     329     *
     330     * Close the modal when the escape key is pressed.
     331     * Constrain keyboard navigation to inside the modal.
     332     *
     333     * @since 4.2.0
     334     */
     335    wp.updates.keydown = function( event ) {
     336        if ( 27 === event.keyCode ) {
     337            wp.updates.requestForCredentialsModalCancel();
     338        } else if ( 9 === event.keyCode ) {
     339            // #upgrade button must always be the last focusable element in the dialog.
     340            if ( event.target.id === 'upgrade' && ! event.shiftKey ) {
     341                $( '#hostname' ).focus();
     342                event.preventDefault();
     343            } else if ( event.target.id === 'hostname' && event.shiftKey ) {
     344                $( '#upgrade' ).focus();
     345                event.preventDefault();
     346            }
     347        }
     348    };
     349
     350    /**
     351     * Open the request for credentials modal.
     352     *
     353     * @since 4.2.0
     354     */
     355    wp.updates.requestForCredentialsModalOpen = function() {
     356        var $modal = $( '#request-filesystem-credentials-dialog' );
     357        $( 'body' ).addClass( 'modal-open' );
     358        $modal.show();
     359
     360        $modal.find( '#hostname' ).focus();
     361        $modal.keydown( wp.updates.keydown );
     362    };
     363
     364    /**
     365     * Close the request for credentials modal.
     366     *
     367     * @since 4.2.0
     368     */
     369    wp.updates.requestForCredentialsModalClose = function() {
     370        $( '#request-filesystem-credentials-dialog' ).hide();
     371        $( 'body' ).removeClass( 'modal-open' );
     372        wp.updates.$elToReturnFocusToFromCredentialsModal.focus();
     373    };
     374
     375    /**
     376     * The steps that need to happen when the modal is canceled out
     377     *
     378     * @since 4.2.0
     379     */
     380    wp.updates.requestForCredentialsModalCancel = function() {
     381        // no updateLock and no updateQueue means we already have cleared things up
     382        var slug, $message;
     383
     384        if( wp.updates.updateLock === false && wp.updates.updateQueue.length === 0 ){
     385            return;
     386        }
     387
     388        slug = wp.updates.updateQueue[0].data.slug,
     389
     390        // remove the lock, and clear the queue
     391        wp.updates.updateLock = false;
     392        wp.updates.updateQueue = [];
     393
     394        wp.updates.requestForCredentialsModalClose();
     395        if ( 'plugins' === pagenow || 'plugins-network' === pagenow ) {
     396            $message = $( '[data-slug="' + slug + '"]' ).next().find( '.update-message' );
     397        } else if ( 'plugin-install' === pagenow ) {
     398            $message = $( '.plugin-card-' + slug ).find( '.update-now' );
     399        }
     400
     401        $message.removeClass( 'updating-message' );
     402        $message.html( $message.data( 'originaltext' ) );
     403        wp.a11y.speak( wp.updates.l10n.updateCancel );
    304404    };
    305405
     
    323423            wp.updates.filesystemCredentials.ssh.privateKey = $('#private_key').val();
    324424
    325             $( '#request-filesystem-credentials-dialog' ).hide();
    326             $( 'body' ).removeClass( 'modal-open' );
     425            wp.updates.requestForCredentialsModalClose();
    327426
    328427            // Unlock and invoke the queue.
     
    333432        });
    334433
     434        // Close the request credentials modal when
     435        $( '#request-filesystem-credentials-dialog [data-js-action="close"], .notification-dialog-background' ).on( 'click', function() {
     436            wp.updates.requestForCredentialsModalCancel();
     437        });
     438
    335439        // Click handler for plugin updates in List Table view.
    336         $( '.plugin-update-tr .update-link' ).on( 'click', function( e ) {
     440        $( '.plugin-update-tr' ).on( 'click', '.update-link', function( e ) {
    337441            e.preventDefault();
    338442            if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.updateLock ) {
    339                 wp.updates.requestFilesystemCredentials();
    340             }
    341             var $row = $( e.target ).parents( '.plugin-update-tr' );
    342             wp.updates.updatePlugin( $row.data( 'plugin' ), $row.data( 'slug' ) );
     443                wp.updates.requestFilesystemCredentials( e );
     444            }
     445            var updateRow = $( e.target ).parents( '.plugin-update-tr' );
     446            // Return the user to the input box of the plugin's table row after closing the modal.
     447            wp.updates.$elToReturnFocusToFromCredentialsModal = $( '#' + updateRow.data( 'slug' ) ).find( '.check-column input' );
     448            wp.updates.updatePlugin( updateRow.data( 'plugin' ), updateRow.data( 'slug' ) );
    343449        } );
    344450
     
    361467        } );
    362468
    363         $( '.plugin-card .update-now' ).on( 'click', function( e ) {
     469        $( '.plugin-card' ).on( 'click', '.update-now', function( e ) {
    364470            e.preventDefault();
    365471            var $button = $( e.target );
     472
     473            if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.updateLock ) {
     474                wp.updates.requestFilesystemCredentials( e );
     475            }
     476
    366477            wp.updates.updatePlugin( $button.data( 'plugin' ), $button.data( 'slug' ) );
    367478        } );
  • trunk/src/wp-includes/script-loader.php

    r31905 r31949  
    530530                'updatingMsg'   => __( 'Updating... please wait.' ),
    531531                'updatedMsg'    => __( 'Update completed successfully.' ),
     532                'updateCancel'  => __( 'Update canceled' ),
    532533            )
    533534        ) );
Note: See TracChangeset for help on using the changeset viewer.