-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Editor: Enhance classic editor timestamp fields with native controls (continues #12275) #13050
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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' ), | ||
| $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 ); | ||
| }; | ||
|
Comment on lines
+893
to
+897
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| 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] ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| $( '#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 ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Related to the above, the |
||
| }; | ||
|
|
||
| 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(); | ||
| }); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -479,6 +479,45 @@ form#tags-filter { | |
| height: auto !important; | ||
| } | ||
|
|
||
| .misc-pub-curtime { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
And a quick test reveals this is broken for the default comment on a fresh install:
This may also mean there might be broader impact than we think (both core-wise and plugin-wise).
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| display: grid; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| } | ||
|
|
||
| .misc-pub-curtime #timestamp { | ||
| grid-column: 2; | ||
| grid-row: 1; | ||
| min-width: 0; | ||
| } | ||
|
|
||
| .misc-pub-curtime:before { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this new pseudo-element also use: |
||
| 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, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe |
||
| #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%; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 ( 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' ) . | ||
|
|
@@ -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> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These two labels need a |
||
| <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>' | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
|
|
@@ -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> | ||
|
|
||

There was a problem hiding this comment.
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-timestampis a sibling of#timestampdivagain, 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.