Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 87 additions & 7 deletions src/js/_enqueues/admin/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,15 @@ window.wp = window.wp || {};
*/
jQuery( function($) {
var stamp, visibility, $submitButtons, updateVisibility, updateText,
updateFieldsFromNativeTimestamp, setupNativeTimestampFields, updateNativeTimestampFields,
$textarea = $('#content'),
$document = $(document),
postId = $('#post_ID').val() || 0,
$submitpost = $('#submitpost'),
releaseLock = true,
$postVisibilitySelect = $('#post-visibility-select'),
$timestampdiv = $('#timestampdiv'),
$timestampEdit = $timestampdiv.closest( '.misc-pub-curtime' ).find( 'a.edit-timestamp' ),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the last commit, a.edit-timestamp is a sibling of #timestampdiv again, so the original $timestampdiv.siblings( 'a.edit-timestamp' ) works just as before. This variable is also cached once on page load, while the old code looked the link up on every click, so if a plugin re-renders the publish box, we now keep an old reference. Maybe we should revert the post.js part of the first commit and keep .siblings()? It would make the diff smaller.

$postStatusSelect = $('#post-status-select'),
isMac = window.navigator.platform ? window.navigator.platform.indexOf( 'Mac' ) !== -1 : false,
copyAttachmentURLClipboard = new ClipboardJS( '.copy-attachment-url.edit-media' ),
Expand Down Expand Up @@ -784,10 +786,10 @@ jQuery( function($) {
attemptedDate.getDate() != jj ||
attemptedDate.getMinutes() != mn
) {
$timestampdiv.find('.timestamp-wrap').addClass('form-invalid');
$timestampdiv.find( '.timestamp-wrap, .timestamp-native-wrap input' ).addClass( 'form-invalid' );
return false;
} else {
$timestampdiv.find('.timestamp-wrap').removeClass('form-invalid');
$timestampdiv.find( '.timestamp-wrap, .timestamp-native-wrap input' ).removeClass( 'form-invalid' );
}

// Determine what the publish should be depending on the date and post status.
Expand Down Expand Up @@ -866,6 +868,79 @@ jQuery( function($) {
return true;
};

updateFieldsFromNativeTimestamp = updateText;
updateNativeTimestampFields = function() {};

setupNativeTimestampFields = function() {
var dateInput = document.createElement( 'input' ),
timeInput = document.createElement( 'input' ),
$timestampwrap = $timestampdiv.find( '.timestamp-wrap' ),
$nativeTimestampWrap = $timestampdiv.find( '.timestamp-native-wrap' ),
$dateInput, $timeInput,
toDateValue, toTimeValue;

dateInput.setAttribute( 'type', 'date' );
timeInput.setAttribute( 'type', 'time' );
if (
'date' !== dateInput.type ||
'time' !== timeInput.type ||
! $timestampwrap.length ||
! $nativeTimestampWrap.length
) {
return;
}

toDateValue = function() {
return $( '#aa' ).val() + '-' +
( '00' + $( '#mm' ).val() ).slice( -2 ) + '-' +
( '00' + $( '#jj' ).val() ).slice( -2 );
};
Comment on lines +893 to +897

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mm and jj are padded to two digits here, but aa is not padded to four.


toTimeValue = function() {
return ( '00' + $( '#hh' ).val() ).slice( -2 ) + ':' +
( '00' + $( '#mn' ).val() ).slice( -2 );
};

$dateInput = $nativeTimestampWrap.find( '#publish-date-native' );
$timeInput = $nativeTimestampWrap.find( '#publish-time-native' );

updateFieldsFromNativeTimestamp = function() {
var dateMatches = $dateInput.val().match( /^(\d{4})-(\d{2})-(\d{2})$/ ),
timeMatches = $timeInput.val().match( /^(\d{2}):(\d{2})$/ );

$dateInput.toggleClass( 'form-invalid', ! dateMatches );
$timeInput.toggleClass( 'form-invalid', ! timeMatches );

if ( ! dateMatches || ! timeMatches ) {
$timestampwrap.addClass( 'form-invalid' );
return false;
}

$( '#aa' ).val( dateMatches[1] );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.val() does not fire a change event. So we might want to explicitly .trigger( 'change ).

$( '#mm' ).val( dateMatches[2] );
$( '#jj' ).val( dateMatches[3] );
$( '#hh' ).val( timeMatches[1] );
$( '#mn' ).val( timeMatches[2] );

// Seconds remain in the existing hidden field, matching the legacy timestamp UI.
return updateText();
};

updateNativeTimestampFields = function() {
$dateInput.val( toDateValue() );
$timeInput.val( toTimeValue() );
};

updateNativeTimestampFields();
$timestampdiv.addClass( 'has-native-timestamp-fields' );
$timestampwrap.hide();
$nativeTimestampWrap.removeAttr( 'hidden' );
$nativeTimestampWrap.find( 'input' ).on( 'change', updateFieldsFromNativeTimestamp );
$timestampwrap.find( 'input, select' ).on( 'change', updateNativeTimestampFields );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to the above, the .val() does not trigger change so this handler probably never runs

};

setupNativeTimestampFields();

// Show the visibility options and hide the toggle button when opened.
$( '#visibility .edit-visibility').on( 'click', function( e ) {
e.preventDefault();
Expand Down Expand Up @@ -924,10 +999,13 @@ jQuery( function($) {
});

// Edit publish time click.
$timestampdiv.siblings('a.edit-timestamp').on( 'click', function( event ) {
$timestampEdit.on( 'click', function( event ) {
if ( $timestampdiv.is( ':hidden' ) ) {
$timestampdiv.slideDown( 'fast', function() {
$( 'input, select', $timestampdiv.find( '.timestamp-wrap' ) ).first().trigger( 'focus' );
$timestampdiv.find( '.timestamp-native-wrap input, .timestamp-wrap input, .timestamp-wrap select' )
.filter( ':visible' )
.first()
.trigger( 'focus' );
} );
$(this).hide();
}
Expand All @@ -936,21 +1014,23 @@ jQuery( function($) {

// Cancel editing the publish time and hide the settings.
$timestampdiv.find('.cancel-timestamp').on( 'click', function( event ) {
$timestampdiv.slideUp('fast').siblings('a.edit-timestamp').show().trigger( 'focus' );
$timestampdiv.slideUp('fast');
$timestampEdit.show().trigger( 'focus' );
$('#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());
updateNativeTimestampFields();
updateText();
event.preventDefault();
});

// Save the changed timestamp.
$timestampdiv.find('.save-timestamp').on( 'click', function( event ) { // Crazyhorse branch - multiple OK cancels.
if ( updateText() ) {
if ( updateFieldsFromNativeTimestamp() ) {
$timestampdiv.slideUp('fast');
$timestampdiv.siblings('a.edit-timestamp').show().trigger( 'focus' );
$timestampEdit.show().trigger( 'focus' );
}
event.preventDefault();
});
Expand Down
78 changes: 78 additions & 0 deletions src/wp-admin/css/edit.css
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,45 @@ form#tags-filter {
height: auto !important;
}

.misc-pub-curtime {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this classname is used in more places than where this PR assumes:

  • The attachment submit box ("Uploaded on:")
  • The comment edit screen ("Submitted on:")

And a quick test reveals this is broken for the default comment on a fresh install:

Image

This may also mean there might be broader impact than we think (both core-wise and plugin-wise).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to reserve space for the Edit link here. With a longer translated timestamp, the max-content column takes most of the available width and pushes Edit outside the metabox.

display: grid;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be one more thing to check for back-compat: this element is now a grid container. Any element that a plugin adds as a direct child becomes a grid item and moves to a new row, instead of flowing inline as before. This may be harder to catch with https://wpdirectory.net/ FWIW.

grid-template-columns: auto minmax( 0, max-content ) minmax( 0, 1fr );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where we need to reserve space for the Edit link. With a longer translated timestamp, the max-content column takes most of the available width and pushes Edit outside the metabox. Perhaps auto minmax( 0, 1fr ) auto?

}

.misc-pub-curtime #timestamp {
grid-column: 2;
grid-row: 1;
min-width: 0;
}

.misc-pub-curtime:before {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this new pseudo-element also use: #8c8f94? The clock icon moved here, but the existing color rule still targets #timestamp:before, which is now disabled. So the clock is darker than the other icons in the publish box.

content: "\f145";
content: "\f145" / '';
font: normal 20px/1 dashicons;
grid-column: 1;
grid-row: 1;
margin-left: -1px;
padding-right: 3px;
position: relative;
top: -1px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.misc-pub-curtime .edit-timestamp {
grid-column: 3;
grid-row: 1;
margin-left: 4px;
}

.misc-pub-curtime .edit-timestamp-label {
white-space: nowrap;
}

.misc-pub-curtime #timestampdiv {
grid-column: 1 / -1;
}

#post-body .misc-pub-post-status:before,
#post-body #visibility:before,
.curtime #timestamp:before,
Expand Down Expand Up @@ -525,6 +564,10 @@ form#tags-filter {
top: -1px;
}

.misc-pub-curtime #timestamp:before {
content: none;
}

#post-body .misc-pub-uploadedby:before {
content: "\f110";
content: "\f110" / '';
Expand Down Expand Up @@ -562,6 +605,41 @@ form#tags-filter {
text-align: center;
}

#timestampdiv.has-native-timestamp-fields {
padding-top: 0;
}

#timestampdiv .timestamp-native-wrap {
margin: 3px 0 0;
}

#timestampdiv.has-native-timestamp-fields .timestamp-native-wrap {
display: grid;
gap: 8px;
}

#timestampdiv.has-native-timestamp-fields .timestamp-actions {
margin-top: 8px;
}

#timestampdiv .timestamp-native-wrap input {
box-sizing: border-box;
text-align: left;
width: 100%;
}

#timestampdiv .timestamp-native-wrap input.form-invalid,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe form-invalid is added to a parent element and form-required to the field itself. Here both classes are on the same input, so none of the existing selectors match, and we need this new rule with !important. If we put each native input in a small wrapper and add form-invalid to the wrapper instead, we can reuse the existing styles and delete this rule.

#timestampdiv .timestamp-native-wrap input.form-invalid:focus {
border-color: #d63638 !important;
box-shadow: 0 0 2px rgba(214, 54, 56, 0.8);
}

#timestampdiv .timestamp-site-time {
color: #646970;
font-size: 12px;
margin: -2px 0 0;
}

.notification-dialog {
position: fixed;
top: 30%;
Expand Down
2 changes: 1 addition & 1 deletion src/wp-admin/includes/meta-boxes.php
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ function post_submit_meta_box( $post, $args = array() ) {
<?php printf( $stamp, '<b>' . $date . '</b>' ); ?>
</span>
<a href="#edit_timestamp" class="edit-timestamp hide-if-no-js" role="button">
<span aria-hidden="true"><?php _e( 'Edit' ); ?></span>
<span aria-hidden="true" class="edit-timestamp-label"><?php _e( 'Edit' ); ?></span>
<span class="screen-reader-text">
<?php
/* translators: Hidden accessibility text. */
Expand Down
39 changes: 37 additions & 2 deletions src/wp-admin/includes/template.php
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,19 @@ function touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $multi = 0 ) {
$cur_hh = current_time( 'H' );
$cur_mn = current_time( 'i' );

$timezone = wp_timezone_string();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We call this every time now, but it's not used on the QuickEdit or comment screen. Should we move it where it's used? The if ( $for_post && ! $multi ) check.

if ( preg_match( '/^([+-])(\d{2}):(\d{2})$/', $timezone, $timezone_matches ) ) {
$offset_hours = (int) $timezone_matches[2];
$offset_minutes = $timezone_matches[3];

if ( 0 === $offset_hours && '00' === $offset_minutes ) {
$timezone = 'UTC';
} else {
$timezone = 'UTC' . $timezone_matches[1] . $offset_hours;
$timezone .= ( '00' === $offset_minutes ) ? '' : ':' . $offset_minutes;
}
}

$month = '<label><span class="screen-reader-text">' .
/* translators: Hidden accessibility text. */
__( 'Month' ) .
Expand Down Expand Up @@ -865,7 +878,29 @@ function touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $multi = 0 ) {
/* translators: 1: Month, 2: Day, 3: Year, 4: Hour, 5: Minute. */
printf( __( '%1$s %2$s, %3$s at %4$s:%5$s' ), $month, $day, $year, $hour, $minute );

echo '</div><input type="hidden" id="ss" name="ss" value="' . $ss . '" />';
echo '</div>';

if ( $for_post && ! $multi ) {
?>
<div class="timestamp-native-wrap hide-if-no-js" hidden>
<label for="publish-date-native" class="screen-reader-text"><?php _e( 'Date' ); ?></label>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two labels need a /* translators: Hidden accessibility text. */ comment above the strings, like the other screen reader strings in this function.

<input type="date" id="publish-date-native" class="form-required" value="<?php echo esc_attr( $aa . '-' . $mm . '-' . $jj ); ?>" />
<label for="publish-time-native" class="screen-reader-text"><?php _e( 'Time' ); ?></label>
<input type="time" id="publish-time-native" class="form-required" value="<?php echo esc_attr( $hh . ':' . $mn ); ?>" />
<p class="timestamp-site-time">
<?php
printf(
/* translators: %s: The site's timezone. */
__( 'Site time: %s' ),
'<span>' . esc_html( $timezone ) . '</span>'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this span necessary?

);
?>
</p>
</div>
<?php
}

echo '<input type="hidden" id="ss" name="ss" value="' . $ss . '" />';

if ( $multi ) {
return;
Expand All @@ -890,7 +925,7 @@ function touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $multi = 0 ) {
}
?>

<p>
<p class="timestamp-actions">
<a href="#edit_timestamp" class="save-timestamp hide-if-no-js button"><?php _e( 'OK' ); ?></a>
<a href="#edit_timestamp" class="cancel-timestamp hide-if-no-js button-cancel"><?php _e( 'Cancel' ); ?></a>
</p>
Expand Down
Loading