Changeset 49146
- Timestamp:
- 10/14/2020 06:19:43 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/js/_enqueues/wp/dashboard.js
r48168 r49146 267 267 268 268 var communityEventsData = window.communityEventsData || {}, 269 dateI18n = wp.date.dateI18n, 270 format = wp.date.format, 271 sprintf = wp.i18n.sprintf, 272 __ = wp.i18n.__, 273 _x = wp.i18n._x, 269 274 app; 270 275 … … 442 447 app.renderEventsTemplate({ 443 448 'location' : false, 449 'events' : [], 444 450 'error' : true 445 451 }, initiatedBy ); … … 465 471 $locationMessage = $( '#community-events-location-message' ), 466 472 $results = $( '.community-events-results' ); 473 474 templateParams.events = app.populateDynamicEventFields( 475 templateParams.events, 476 communityEventsData.time_format 477 ); 467 478 468 479 /* … … 577 588 app.toggleLocationForm( 'show' ); 578 589 } 590 }, 591 592 /** 593 * Populate event fields that have to be calculated on the fly. 594 * 595 * These can't be stored in the database, because they're dependent on 596 * the user's current time zone, locale, etc. 597 * 598 * @since 5.6.0 599 * 600 * @param {Array} rawEvents The events that should have dynamic fields added to them. 601 * @param {string} timeFormat A time format acceptable by `wp.date.dateI18n()`. 602 * 603 * @returns {Array} 604 */ 605 populateDynamicEventFields: function( rawEvents, timeFormat ) { 606 // Clone the parameter to avoid mutating it, so that this can remain a pure function. 607 var populatedEvents = JSON.parse( JSON.stringify( rawEvents ) ); 608 609 $.each( populatedEvents, function( index, event ) { 610 var timeZone = app.getTimeZone( event.start_unix_timestamp * 1000 ); 611 612 event.user_formatted_date = app.getFormattedDate( 613 event.start_unix_timestamp * 1000, 614 event.end_unix_timestamp * 1000, 615 timeZone 616 ); 617 618 event.user_formatted_time = dateI18n( 619 timeFormat, 620 event.start_unix_timestamp * 1000, 621 timeZone 622 ); 623 624 event.timeZoneAbbreviation = app.getTimeZoneAbbreviation( event.start_unix_timestamp * 1000 ); 625 } ); 626 627 return populatedEvents; 628 }, 629 630 /** 631 * Returns the user's local/browser time zone, in a form suitable for `wp.date.i18n()`. 632 * 633 * @since 5.6.0 634 * 635 * @param startTimestamp 636 * 637 * @returns {string|number} 638 */ 639 getTimeZone: function( startTimestamp ) { 640 /* 641 * Prefer a name like `Europe/Helsinki`, since that automatically tracks daylight savings. This 642 * doesn't need to take `startTimestamp` into account for that reason. 643 */ 644 var timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; 645 646 /* 647 * Fall back to an offset for IE11, which declares the property but doesn't assign a value. 648 */ 649 if ( 'undefined' === typeof timeZone ) { 650 /* 651 * It's important to use the _event_ time, not the _current_ 652 * time, so that daylight savings time is accounted for. 653 */ 654 timeZone = app.getFlippedTimeZoneOffset( startTimestamp ); 655 } 656 657 return timeZone; 658 }, 659 660 /** 661 * Get intuitive time zone offset. 662 * 663 * `Data.prototype.getTimezoneOffset()` returns a positive value for time zones 664 * that are _behind_ UTC, and a _negative_ value for ones that are ahead. 665 * 666 * See https://stackoverflow.com/questions/21102435/why-does-javascript-date-gettimezoneoffset-consider-0500-as-a-positive-off. 667 * 668 * @since 5.6.0 669 * 670 * @param {number} startTimestamp 671 * 672 * @returns {number} 673 */ 674 getFlippedTimeZoneOffset: function( startTimestamp ) { 675 return new Date( startTimestamp ).getTimezoneOffset() * -1; 676 }, 677 678 /** 679 * Get a short time zone name, like `PST`. 680 * 681 * @since 5.6.0 682 * 683 * @param {number} startTimestamp 684 * 685 * @returns {string} 686 */ 687 getTimeZoneAbbreviation: function( startTimestamp ) { 688 var timeZoneAbbreviation, 689 eventDateTime = new Date( startTimestamp ); 690 691 /* 692 * Leaving the `locales` argument undefined is important, so that the browser 693 * displays the abbreviation that's most appropriate for the current locale. For 694 * some that will be `UTC{+|-}{n}`, and for others it will be a code like `PST`. 695 * 696 * This doesn't need to take `startTimestamp` into account, because a name like 697 * `America/Chicago` automatically tracks daylight savings. 698 */ 699 var shortTimeStringParts = eventDateTime.toLocaleTimeString( undefined, { timeZoneName : 'short' } ).split( ' ' ); 700 701 if ( 3 === shortTimeStringParts.length ) { 702 timeZoneAbbreviation = shortTimeStringParts[2]; 703 } 704 705 if ( 'undefined' === typeof timeZoneAbbreviation ) { 706 /* 707 * It's important to use the _event_ time, not the _current_ 708 * time, so that daylight savings time is accounted for. 709 */ 710 var timeZoneOffset = app.getFlippedTimeZoneOffset( startTimestamp ), 711 sign = -1 === Math.sign( timeZoneOffset ) ? '' : '+'; 712 713 // translators: Used as part of a string like `GMT+5` in the Events Widget. 714 timeZoneAbbreviation = _x( 'GMT', 'Events widget offset prefix' ) + sign + ( timeZoneOffset / 60 ); 715 } 716 717 return timeZoneAbbreviation; 718 }, 719 720 /** 721 * Format a start/end date in the user's local time zone and locale. 722 * 723 * @since 5.6.0 724 * 725 * @param {int} startDate The Unix timestamp in milliseconds when the the event starts. 726 * @param {int} endDate The Unix timestamp in milliseconds when the the event ends. 727 * @param {string} timeZone A time zone string or offset which is parsable by `wp.date.i18n()`. 728 * 729 * @returns {string} 730 */ 731 getFormattedDate: function( startDate, endDate, timeZone ) { 732 var formattedDate; 733 734 /* 735 * The `date_format` option is not used because it's important 736 * in this context to keep the day of the week in the displayed date, 737 * so that users can tell at a glance if the event is on a day they 738 * are available, without having to open the link. 739 * 740 * The case of crossing a year boundary is intentionally not handled. 741 * It's so rare in practice that it's not worth the complexity 742 * tradeoff. The _ending_ year should be passed to 743 * `multiple_month_event`, though, just in case. 744 */ 745 /* translators: Date format for upcoming events on the dashboard. Include the day of the week. See https://www.php.net/manual/datetime.format.php */ 746 var singleDayEvent = __( 'l, M j, Y' ), 747 /* translators: Date string for upcoming events. 1: Month, 2: Starting day, 3: Ending day, 4: Year. */ 748 multipleDayEvent = __( '%1$s %2$d–%3$d, %4$d' ), 749 /* translators: Date string for upcoming events. 1: Starting month, 2: Starting day, 3: Ending month, 4: Ending day, 5: Ending year. */ 750 multipleMonthEvent = __( '%1$s %2$d – %3$s %4$d, %5$d' ); 751 752 // Detect single-day events. 753 if ( ! endDate || format( 'Y-m-d', startDate ) === format( 'Y-m-d', endDate ) ) { 754 formattedDate = dateI18n( singleDayEvent, startDate, timeZone ); 755 756 // Multiple day events. 757 } else if ( format( 'Y-m', startDate ) === format( 'Y-m', endDate ) ) { 758 formattedDate = sprintf( 759 multipleDayEvent, 760 dateI18n( _x( 'F', 'upcoming events month format' ), startDate, timeZone ), 761 dateI18n( _x( 'j', 'upcoming events day format' ), startDate, timeZone ), 762 dateI18n( _x( 'j', 'upcoming events day format' ), endDate, timeZone ), 763 dateI18n( _x( 'Y', 'upcoming events year format' ), endDate, timeZone ) 764 ); 765 766 // Multi-day events that cross a month boundary. 767 } else { 768 formattedDate = sprintf( 769 multipleMonthEvent, 770 dateI18n( _x( 'F', 'upcoming events month format' ), startDate, timeZone ), 771 dateI18n( _x( 'j', 'upcoming events day format' ), startDate, timeZone ), 772 dateI18n( _x( 'F', 'upcoming events month format' ), endDate, timeZone ), 773 dateI18n( _x( 'j', 'upcoming events day format' ), endDate, timeZone ), 774 dateI18n( _x( 'Y', 'upcoming events year format' ), endDate, timeZone ) 775 ); 776 } 777 778 return formattedDate; 579 779 } 580 780 }; -
trunk/src/wp-admin/includes/class-wp-community-events.php
r49145 r49146 78 78 * 79 79 * @since 4.8.0 80 * @since 5.6.0 Response no longer contains formatted date field. They're added 81 * in `wp.communityEvents.populateDynamicEventFields()` now. 80 82 * 81 83 * @param string $location_search Optional. City name to help determine the location. … … 166 168 167 169 $response_body['events'] = $this->trim_events( $response_body['events'] ); 168 $response_body = $this->format_event_data_time( $response_body );169 170 170 171 return $response_body; … … 345 346 * 346 347 * @since 4.8.0 348 * @since 5.6.0 Response no longer contains formatted date field. They're added 349 * in `wp.communityEvents.populateDynamicEventFields()` now. 347 350 * 348 351 * @return array|false An array containing `location` and `events` items … … 356 359 } 357 360 358 return $ this->format_event_data_time( $cached_response );361 return $cached_response; 359 362 } 360 363 … … 373 376 */ 374 377 protected function format_event_data_time( $response_body ) { 378 _deprecated_function( 379 __METHOD__, 380 '5.6.0', 381 'This is no longer used by Core, and only kept for backwards-compatibility.' 382 ); 383 375 384 if ( isset( $response_body['events'] ) ) { 376 385 foreach ( $response_body['events'] as $key => $event ) { -
trunk/src/wp-admin/includes/dashboard.php
r49123 r49146 1390 1390 1391 1391 <div class="event-date-time"> 1392 <span class="event-date">{{ event. formatted_date }}</span>1392 <span class="event-date">{{ event.user_formatted_date }}</span> 1393 1393 <# if ( 'meetup' === event.type ) { #> 1394 <span class="event-time">{{ event.formatted_time }}</span> 1394 <span class="event-time"> 1395 {{ event.user_formatted_time }} {{ event.timeZoneAbbreviation }} 1396 </span> 1395 1397 <# } #> 1396 1398 </div> -
trunk/src/wp-includes/script-loader.php
r49109 r49146 1309 1309 $scripts->set_translations( 'wp-color-picker' ); 1310 1310 1311 $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-util', 'wp-a11y' ), false, 1 ); 1311 $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-util', 'wp-a11y', 'wp-date' ), false, 1 ); 1312 $scripts->set_translations( 'dashboard' ); 1312 1313 1313 1314 $scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" ); … … 1756 1757 'nonce' => wp_create_nonce( 'community_events' ), 1757 1758 'cache' => $events_client->get_cached_events(), 1759 'time_format' => get_option( 'time_format' ), 1758 1760 1759 1761 'l10n' => array( -
trunk/tests/qunit/index.html
r49107 r49146 86 86 87 87 <!-- Tested files --> 88 <script src="../../build/wp-admin/js/dashboard.js"></script> 88 89 <script src="../../build/wp-admin/js/password-strength-meter.js"></script> 90 <script src="../../build/wp-admin/js/postbox.js"></script> 91 <script src="../../build/wp-includes/js/dist/vendor/moment.js"></script> 92 <script src="../../build/wp-includes/js/dist/date.js"></script> 93 <script src="../../build/wp-includes/js/dist/i18n.js"></script> 89 94 <script src="../../build/wp-includes/js/customize-base.js"></script> 90 95 <script src="../../build/wp-includes/js/customize-models.js"></script> … … 143 148 <script src="wp-admin/js/customize-base.js"></script> 144 149 <script src="wp-admin/js/customize-header.js"></script> 150 <script src="wp-admin/js/dashboard.js"></script> 145 151 <script src="wp-includes/js/shortcode.js"></script> 146 152 <script src="wp-includes/js/api-request.js"></script>
Note: See TracChangeset
for help on using the changeset viewer.