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


Built from https://develop.svn.wordpress.org/trunk@31949


git-svn-id: http://core.svn.wordpress.org/trunk@31928 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Aaron Jorbin 2015-04-01 02:48:28 +00:00
parent e053979219
commit 8f99fbeb8d
11 changed files with 297 additions and 67 deletions

View File

@ -864,11 +864,58 @@ table.form-table td .updated p {
margin: 25px;
}
.request-filesystem-credentials-dialog-content input[type="text"],
.request-filesystem-credentials-dialog-content input[type="password"] {
width: 85%;
.request-filesystem-credentials-form input[type="text"],
.request-filesystem-credentials-form input[type="password"] {
display: block;
}
.request-filesystem-credentials-dialog input[type="text"],
.request-filesystem-credentials-dialog input[type="password"] {
width: 100%;
}
.request-filesystem-credentials-form .field-title {
font-weight: 600;
}
.request-filesystem-credentials-dialog label[for="hostname"],
.request-filesystem-credentials-dialog label[for="public_key"],
.request-filesystem-credentials-dialog label[for="private_key"] {
display: block;
margin-bottom: 1em;
}
.request-filesystem-credentials-dialog .ftp-username,
.request-filesystem-credentials-dialog .ftp-password {
float: right;
width: 48%;
}
.request-filesystem-credentials-dialog .ftp-password {
margin-right: 4%;
}
.request-filesystem-credentials-dialog .request-filesystem-credentials-action-buttons {
text-align: left;
}
.request-filesystem-credentials-dialog label[for="ftp"] {
margin-left: 10px;
}
#request-filesystem-credentials-dialog .button:not(:last-child) {
margin-left: 10px;
}
#request-filesystem-credentials-form .cancel-button {
display: none;
}
#request-filesystem-credentials-dialog .cancel-button {
display: inline;
}
/* =Media Queries
-------------------------------------------------------------- */
@ -1098,6 +1145,20 @@ table.form-table td .updated p {
max-width: 400px;
width: auto;
}
}
@media only screen and (max-height: 480px) {
/* Request Credentials */
.request-filesystem-credentials-dialog .notification-dialog{
width: 100%;
height: 100%;
position: fixed;
top: 0;
margin: 0;
right: 0;
overflow-y: auto;
}
}
/* Smartphone */

View File

@ -864,11 +864,58 @@ table.form-table td .updated p {
margin: 25px;
}
.request-filesystem-credentials-dialog-content input[type="text"],
.request-filesystem-credentials-dialog-content input[type="password"] {
width: 85%;
.request-filesystem-credentials-form input[type="text"],
.request-filesystem-credentials-form input[type="password"] {
display: block;
}
.request-filesystem-credentials-dialog input[type="text"],
.request-filesystem-credentials-dialog input[type="password"] {
width: 100%;
}
.request-filesystem-credentials-form .field-title {
font-weight: 600;
}
.request-filesystem-credentials-dialog label[for="hostname"],
.request-filesystem-credentials-dialog label[for="public_key"],
.request-filesystem-credentials-dialog label[for="private_key"] {
display: block;
margin-bottom: 1em;
}
.request-filesystem-credentials-dialog .ftp-username,
.request-filesystem-credentials-dialog .ftp-password {
float: left;
width: 48%;
}
.request-filesystem-credentials-dialog .ftp-password {
margin-left: 4%;
}
.request-filesystem-credentials-dialog .request-filesystem-credentials-action-buttons {
text-align: right;
}
.request-filesystem-credentials-dialog label[for="ftp"] {
margin-right: 10px;
}
#request-filesystem-credentials-dialog .button:not(:last-child) {
margin-right: 10px;
}
#request-filesystem-credentials-form .cancel-button {
display: none;
}
#request-filesystem-credentials-dialog .cancel-button {
display: inline;
}
/* =Media Queries
-------------------------------------------------------------- */
@ -1098,6 +1145,20 @@ table.form-table td .updated p {
max-width: 400px;
width: auto;
}
}
@media only screen and (max-height: 480px) {
/* Request Credentials */
.request-filesystem-credentials-dialog .notification-dialog{
width: 100%;
height: 100%;
position: fixed;
top: 0;
margin: 0;
left: 0;
overflow-y: auto;
}
}
/* Smartphone */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1125,9 +1125,9 @@ jQuery(function($){
-->
</script>
<form action="<?php echo esc_url( $form_post ) ?>" method="post">
<div>
<h3><?php _e('Connection Information') ?></h3>
<p><?php
<div id="request-filesystem-credentials-form" class="request-filesystem-credentials-form">
<h3 id="request-filesystem-credentials-title"><?php _e( 'Connection Information' ) ?></h3>
<p id="request-filesystem-credentials-desc"><?php
$label_user = __('Username');
$label_pass = __('Password');
_e('To perform the requested action, WordPress needs to access your web server.');
@ -1146,39 +1146,36 @@ jQuery(function($){
}
_e('If you do not remember your credentials, you should contact your web host.');
?></p>
<table class="form-table">
<tr>
<th scope="row"><label for="hostname"><?php _e('Hostname') ?></label></th>
<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>
</tr>
<tr>
<th scope="row"><label for="username"><?php echo $label_user; ?></label></th>
<td><input name="username" type="text" id="username" value="<?php echo esc_attr($username) ?>"<?php disabled( defined('FTP_USER') ); ?> size="40" /></td>
</tr>
<tr>
<th scope="row"><label for="password"><?php echo $label_pass; ?></label></th>
<td><div><input name="password" type="password" id="password" value="<?php if ( defined('FTP_PASS') ) echo '*****'; ?>"<?php disabled( defined('FTP_PASS') ); ?> size="40" /></div>
<div><em><?php if ( ! defined('FTP_PASS') ) _e( 'This password will not be stored on the server.' ); ?></em></div></td>
</tr>
<label for="hostname">
<span class="field-title"><?php _e( 'Hostname' ) ?></span>
<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') ); ?> />
</label>
<div class="ftp-username">
<label for="username">
<span class="field-title"><?php echo $label_user; ?></span>
<input name="username" type="text" id="username" value="<?php echo esc_attr($username) ?>"<?php disabled( defined('FTP_USER') ); ?> />
</label>
</div>
<div class="ftp-password">
<label for="password">
<span class="field-title"><?php echo $label_pass; ?></span>
<input name="password" type="password" id="password" value="<?php if ( defined('FTP_PASS') ) echo '*****'; ?>"<?php disabled( defined('FTP_PASS') ); ?> />
<em><?php if ( ! defined('FTP_PASS') ) _e( 'This password will not be stored on the server.' ); ?></em>
</label>
</div>
<?php if ( isset($types['ssh']) ) : ?>
<tr id="ssh_keys" style="<?php if ( 'ssh' != $connection_type ) echo 'display:none' ?>">
<th scope="row"><?php _e('Authentication Keys') ?>
<div class="key-labels textright">
<label for="public_key"><?php _e('Public Key:') ?></label ><br />
<label for="private_key"><?php _e('Private Key:') ?></label>
</div></th>
<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" />
<br /><input name="private_key" type="text" id="private_key" value="<?php echo esc_attr($private_key) ?>"<?php disabled( defined('FTP_PRIKEY') ); ?> size="40" />
<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>
</tr>
<h4><?php _e('Authentication Keys') ?></h4>
<label for="public_key">
<span class="field-title"><?php _e('Public Key:') ?></span>
<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') ); ?> />
</label>
<label for="private_key">
<span class="field-title"><?php _e('Private Key:') ?></span>
<input name="private_key" type="text" id="private_key" value="<?php echo esc_attr($private_key) ?>"<?php disabled( defined('FTP_PRIKEY') ); ?> />
</label>
<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>
<?php endif; ?>
<tr>
<th scope="row"><?php _e('Connection Type') ?></th>
<td>
<h4><?php _e('Connection Type') ?></h4>
<fieldset><legend class="screen-reader-text"><span><?php _e('Connection Type') ?></span></legend>
<?php
$disabled = disabled( (defined('FTP_SSL') && FTP_SSL) || (defined('FTP_SSH') && FTP_SSH), true, false );
@ -1189,17 +1186,16 @@ jQuery(function($){
</label>
<?php endforeach; ?>
</fieldset>
</td>
</tr>
</table>
<?php
foreach ( (array) $extra_fields as $field ) {
if ( isset( $_POST[ $field ] ) )
echo '<input type="hidden" name="' . esc_attr( $field ) . '" value="' . esc_attr( wp_unslash( $_POST[ $field ] ) ) . '" />';
}
submit_button( __( 'Proceed' ), 'button', 'upgrade' );
?>
<p class="request-filesystem-credentials-action-buttons">
<button class="button cancel-button" data-js-action="close" type="button"><?php _e( 'Cancel' ); ?></button>
<?php submit_button( __( 'Proceed' ), 'button', 'upgrade', false ); ?>
</p>
</div>
</form>
<?php
@ -1223,7 +1219,7 @@ function wp_print_request_filesystem_credentials_modal() {
?>
<div id="request-filesystem-credentials-dialog" class="notification-dialog-wrap request-filesystem-credentials-dialog">
<div class="notification-dialog-background"></div>
<div class="notification-dialog">
<div class="notification-dialog" role="dialog" aria-labelledby="request-filesystem-credentials-title" tabindex="0">
<div class="request-filesystem-credentials-dialog-content">
<?php request_filesystem_credentials( site_url() ); ?>
<div>

View File

@ -78,6 +78,15 @@ window.wp = window.wp || {};
*/
wp.updates.updateQueue = [];
/**
* Store a jQuery reference to return focus to when exiting the request credentials modal.
*
* @since 4.2.0
*
* @var jQuery object
*/
wp.updates.$elToReturnFocusToFromCredentialsModal = null;
/**
* Decrement update counts throughout the various menus.
*
@ -144,6 +153,10 @@ window.wp = window.wp || {};
}
$message.addClass( 'updating-message' );
if ( $message.html() !== wp.updates.l10n.updating ){
$message.data( 'originaltext', $message.html() );
}
$message.text( wp.updates.l10n.updating );
wp.a11y.speak( wp.updates.l10n.updatingMsg );
@ -247,12 +260,12 @@ window.wp = window.wp || {};
* @since 4.2.0
*/
wp.updates.showErrorInCredentialsForm = function( message ) {
var $notificationDialog = $( '.notification-dialog' );
var $modal = $( '.notification-dialog' );
// Remove any existing error
$notificationDialog.find( '.error' ).remove();
// Remove any existing error.
$modal.find( '.error' ).remove();
$notificationDialog.find( 'h3' ).after( '<div class="error">' + message + '</div>' );
$modal.find( 'h3' ).after( '<div class="error">' + message + '</div>' );
};
/**
@ -291,18 +304,105 @@ window.wp = window.wp || {};
/**
* Request the users filesystem credentials if we don't have them already
* Request the users filesystem credentials if we don't have them already.
*
* @since 4.2.0
*/
wp.updates.requestFilesystemCredentials = function() {
wp.updates.requestFilesystemCredentials = function( event ) {
if ( wp.updates.updateDoneSuccessfully === false ) {
/*
* For the plugin install screen, return the focus to the install button
* after exiting the credentials request modal.
*/
if ( 'plugin-install' === pagenow && event ) {
wp.updates.$elToReturnFocusToFromCredentialsModal = $( event.target );
}
wp.updates.updateLock = true;
$( 'body' ).addClass( 'modal-open' );
$( '#request-filesystem-credentials-dialog' ).show();
wp.updates.requestForCredentialsModalOpen();
}
};
/**
* Keydown handler for the request for credentials modal.
*
* Close the modal when the escape key is pressed.
* Constrain keyboard navigation to inside the modal.
*
* @since 4.2.0
*/
wp.updates.keydown = function( event ) {
if ( 27 === event.keyCode ) {
wp.updates.requestForCredentialsModalCancel();
} else if ( 9 === event.keyCode ) {
// #upgrade button must always be the last focusable element in the dialog.
if ( event.target.id === 'upgrade' && ! event.shiftKey ) {
$( '#hostname' ).focus();
event.preventDefault();
} else if ( event.target.id === 'hostname' && event.shiftKey ) {
$( '#upgrade' ).focus();
event.preventDefault();
}
}
};
/**
* Open the request for credentials modal.
*
* @since 4.2.0
*/
wp.updates.requestForCredentialsModalOpen = function() {
var $modal = $( '#request-filesystem-credentials-dialog' );
$( 'body' ).addClass( 'modal-open' );
$modal.show();
$modal.find( '#hostname' ).focus();
$modal.keydown( wp.updates.keydown );
};
/**
* Close the request for credentials modal.
*
* @since 4.2.0
*/
wp.updates.requestForCredentialsModalClose = function() {
$( '#request-filesystem-credentials-dialog' ).hide();
$( 'body' ).removeClass( 'modal-open' );
wp.updates.$elToReturnFocusToFromCredentialsModal.focus();
};
/**
* The steps that need to happen when the modal is canceled out
*
* @since 4.2.0
*/
wp.updates.requestForCredentialsModalCancel = function() {
// no updateLock and no updateQueue means we already have cleared things up
var slug, $message;
if( wp.updates.updateLock === false && wp.updates.updateQueue.length === 0 ){
return;
}
slug = wp.updates.updateQueue[0].data.slug,
// remove the lock, and clear the queue
wp.updates.updateLock = false;
wp.updates.updateQueue = [];
wp.updates.requestForCredentialsModalClose();
if ( 'plugins' === pagenow || 'plugins-network' === pagenow ) {
$message = $( '[data-slug="' + slug + '"]' ).next().find( '.update-message' );
} else if ( 'plugin-install' === pagenow ) {
$message = $( '.plugin-card-' + slug ).find( '.update-now' );
}
$message.removeClass( 'updating-message' );
$message.html( $message.data( 'originaltext' ) );
wp.a11y.speak( wp.updates.l10n.updateCancel );
};
$( document ).ready( function() {
/*
* Check whether a user needs to submit filesystem credentials based on whether
@ -322,8 +422,7 @@ window.wp = window.wp || {};
wp.updates.filesystemCredentials.ssh.publicKey = $('#public_key').val();
wp.updates.filesystemCredentials.ssh.privateKey = $('#private_key').val();
$( '#request-filesystem-credentials-dialog' ).hide();
$( 'body' ).removeClass( 'modal-open' );
wp.updates.requestForCredentialsModalClose();
// Unlock and invoke the queue.
wp.updates.updateLock = false;
@ -332,14 +431,21 @@ window.wp = window.wp || {};
return false;
});
// Close the request credentials modal when
$( '#request-filesystem-credentials-dialog [data-js-action="close"], .notification-dialog-background' ).on( 'click', function() {
wp.updates.requestForCredentialsModalCancel();
});
// Click handler for plugin updates in List Table view.
$( '.plugin-update-tr .update-link' ).on( 'click', function( e ) {
$( '.plugin-update-tr' ).on( 'click', '.update-link', function( e ) {
e.preventDefault();
if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.updateLock ) {
wp.updates.requestFilesystemCredentials();
wp.updates.requestFilesystemCredentials( e );
}
var $row = $( e.target ).parents( '.plugin-update-tr' );
wp.updates.updatePlugin( $row.data( 'plugin' ), $row.data( 'slug' ) );
var updateRow = $( e.target ).parents( '.plugin-update-tr' );
// Return the user to the input box of the plugin's table row after closing the modal.
wp.updates.$elToReturnFocusToFromCredentialsModal = $( '#' + updateRow.data( 'slug' ) ).find( '.check-column input' );
wp.updates.updatePlugin( updateRow.data( 'plugin' ), updateRow.data( 'slug' ) );
} );
$( '#bulk-action-form' ).on( 'submit', function( e ) {
@ -360,9 +466,14 @@ window.wp = window.wp || {};
}
} );
$( '.plugin-card .update-now' ).on( 'click', function( e ) {
$( '.plugin-card' ).on( 'click', '.update-now', function( e ) {
e.preventDefault();
var $button = $( e.target );
if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.updateLock ) {
wp.updates.requestFilesystemCredentials( e );
}
wp.updates.updatePlugin( $button.data( 'plugin' ), $button.data( 'slug' ) );
} );

File diff suppressed because one or more lines are too long

View File

@ -529,6 +529,7 @@ function wp_default_scripts( &$scripts ) {
'updateFailed' => __( 'Update failed.' ),
'updatingMsg' => __( 'Updating... please wait.' ),
'updatedMsg' => __( 'Update completed successfully.' ),
'updateCancel' => __( 'Update canceled' ),
)
) );

View File

@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
$wp_version = '4.2-beta3-31948';
$wp_version = '4.2-beta3-31949';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.