diff --git a/src/js/_enqueues/admin/post.js b/src/js/_enqueues/admin/post.js index d50fe6007d33b..e5adba5cfd579 100644 --- a/src/js/_enqueues/admin/post.js +++ b/src/js/_enqueues/admin/post.js @@ -303,6 +303,7 @@ window.wp = window.wp || {}; */ jQuery( function($) { var stamp, visibility, $submitButtons, updateVisibility, updateText, + updateFieldsFromNativeTimestamp, setupNativeTimestampFields, updateNativeTimestampFields, $textarea = $('#content'), $document = $(document), postId = $('#post_ID').val() || 0, @@ -310,6 +311,7 @@ jQuery( function($) { releaseLock = true, $postVisibilitySelect = $('#post-visibility-select'), $timestampdiv = $('#timestampdiv'), + $timestampEdit = $timestampdiv.closest( '.misc-pub-curtime' ).find( 'a.edit-timestamp' ), $postStatusSelect = $('#post-status-select'), isMac = window.navigator.platform ? window.navigator.platform.indexOf( 'Mac' ) !== -1 : false, copyAttachmentURLClipboard = new ClipboardJS( '.copy-attachment-url.edit-media' ), @@ -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. @@ -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 ); + }; + + 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] ); + $( '#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 ); + }; + + setupNativeTimestampFields(); + // Show the visibility options and hide the toggle button when opened. $( '#visibility .edit-visibility').on( 'click', function( e ) { e.preventDefault(); @@ -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(); } @@ -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(); }); diff --git a/src/wp-admin/css/edit.css b/src/wp-admin/css/edit.css index f1dd76ac31474..11c8a4d5e4114 100644 --- a/src/wp-admin/css/edit.css +++ b/src/wp-admin/css/edit.css @@ -479,6 +479,45 @@ form#tags-filter { height: auto !important; } +.misc-pub-curtime { + display: grid; + grid-template-columns: auto minmax( 0, max-content ) minmax( 0, 1fr ); +} + +.misc-pub-curtime #timestamp { + grid-column: 2; + grid-row: 1; + min-width: 0; +} + +.misc-pub-curtime:before { + 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, @@ -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" / ''; @@ -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, +#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%; diff --git a/src/wp-admin/includes/meta-boxes.php b/src/wp-admin/includes/meta-boxes.php index 535a00cd3fe94..6d4c72375f034 100644 --- a/src/wp-admin/includes/meta-boxes.php +++ b/src/wp-admin/includes/meta-boxes.php @@ -289,7 +289,7 @@ function post_submit_meta_box( $post, $args = array() ) { ' . $date . '' ); ?> - + ' . /* translators: Hidden accessibility text. */ __( 'Month' ) . @@ -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 ''; + echo ''; + + if ( $for_post && ! $multi ) { + ?> + + '; if ( $multi ) { return; @@ -890,7 +925,7 @@ function touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $multi = 0 ) { } ?> -

+