Changeset 40607
- Timestamp:
- 05/10/2017 08:03:01 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/admin-ajax.php
r38159 r40607 65 65 'press-this-add-category', 'crop-image', 'generate-password', 'save-wporg-username', 'delete-plugin', 66 66 'search-plugins', 'search-install-plugins', 'activate-plugin', 'update-theme', 'delete-theme', 67 'install-theme', 'get-post-thumbnail-html', 67 'install-theme', 'get-post-thumbnail-html', 'get-community-events', 68 68 ); 69 69 -
trunk/src/wp-admin/css/dashboard.css
r40556 r40607 302 302 } 303 303 304 /* Dashboard WordPress events */ 305 306 .community-events-errors { 307 margin: 0; 308 } 309 310 .community-events-loading { 311 padding: 10px 12px 8px; 312 } 313 314 .community-events { 315 margin-bottom: 6px; 316 padding: 0 12px; 317 } 318 319 .community-events .spinner { 320 float: none; 321 margin: 0; 322 padding-bottom: 3px; 323 } 324 325 .community-events-errors[aria-hidden="true"], 326 .community-events-errors *[aria-hidden="true"], 327 .community-events-loading[aria-hidden="true"], 328 .community-events[aria-hidden="true"], 329 .community-events *[aria-hidden="true"] { 330 display: none; 331 } 332 333 .community-events .activity-block:first-child, 334 .community-events h2 { 335 padding-top: 12px; 336 padding-bottom: 10px; 337 } 338 339 .community-events-form { 340 margin: 15px 0 5px; 341 } 342 343 .community-events-form .regular-text { 344 width: 40%; 345 height: 28px; 346 } 347 348 .community-events li.event-none { 349 border-left: 4px solid #0070AE; 350 } 351 352 .community-events-form label { 353 display: inline-block; 354 padding-bottom: 3px; 355 } 356 357 .community-events .activity-block > p { 358 margin-bottom: 0; 359 display: inline; 360 } 361 362 #community-events-submit { 363 margin-left: 2px; 364 } 365 366 .community-events .button-link:hover, 367 .community-events .button-link:active { 368 color: #00a0d2; 369 } 370 371 .community-events-cancel.button.button-link { 372 color: #0073aa; 373 text-decoration: underline; 374 margin-left: 2px; 375 } 376 377 .community-events ul { 378 background-color: #fafafa; 379 padding-left: 0; 380 padding-right: 0; 381 padding-bottom: 0; 382 } 383 384 .community-events li { 385 margin: 0; 386 padding: 8px 12px; 387 color: #72777c; 388 } 389 .community-events li:first-child { 390 border-top: 1px solid #eee; 391 } 392 393 .community-events li ~ li { 394 border-top: 1px solid #eee; 395 } 396 397 .community-events .activity-block.last { 398 border-bottom: 1px solid #eee; 399 padding-top: 0; 400 margin-top: -1px; 401 } 402 403 .community-events .event-info { 404 display: block; 405 } 406 407 .event-icon { 408 height: 18px; 409 padding-right: 10px; 410 width: 18px; 411 display: none; /* Hide on smaller screens */ 412 } 413 414 .event-icon:before { 415 color: #82878C; 416 font-size: 18px; 417 } 418 .event-meetup .event-icon:before { 419 content: "\f484"; 420 } 421 .event-wordcamp .event-icon:before { 422 content: "\f486"; 423 } 424 425 .community-events .event-title { 426 font-weight: 600; 427 display: block; 428 } 429 430 .community-events .event-date, 431 .community-events .event-time { 432 display: block; 433 } 434 435 .community-events-footer { 436 margin-top: 0; 437 margin-bottom: 0; 438 padding: 12px; 439 border-top: 1px solid #eee; 440 color: #ddd; 441 } 442 304 443 /* Dashboard WordPress news */ 305 444 … … 334 473 335 474 #dashboard_primary .rss-widget { 336 border-bottom: 1px solid #eee;337 475 font-size: 13px; 338 padding: 8px 12px 10px;476 padding: 0 12px 0; 339 477 } 340 478 … … 358 496 359 497 #dashboard_primary .rss-widget ul li { 360 margin-bottom: 8px; 498 padding: 4px 0; 499 margin: 0; 361 500 } 362 501 … … 875 1014 876 1015 a.rsswidget { 877 font-size: 1 4px;1016 font-size: 13px; 878 1017 font-weight: 600; 879 line-height: 1. 7em;1018 line-height: 1.4em; 880 1019 } 881 1020 … … 1087 1226 width: 30px; 1088 1227 margin: 4px 10px 5px 0; 1228 } 1229 1230 .community-events-toggle-location { 1231 height: 38px; 1232 } 1233 1234 .community-events-form .regular-text { 1235 height: 31px; 1089 1236 } 1090 1237 } … … 1111 1258 } 1112 1259 } 1260 1261 @media screen and (min-width: 355px) { 1262 .community-events .event-info { 1263 display: table-row; 1264 float: left; 1265 max-width: 59%; 1266 } 1267 1268 .event-icon, 1269 .event-icon[aria-hidden="true"] { 1270 display: table-cell; 1271 } 1272 1273 .event-info-inner { 1274 display: table-cell; 1275 } 1276 1277 .community-events .event-date-time { 1278 float: right; 1279 max-width: 39%; 1280 } 1281 1282 .community-events .event-date, 1283 .community-events .event-time { 1284 text-align: right; 1285 } 1286 } -
trunk/src/wp-admin/includes/ajax-actions.php
r40476 r40607 295 295 296 296 wp_die( wp_json_encode( $return ) ); 297 } 298 299 /** 300 * Handles AJAX requests for community events 301 * 302 * @since 4.8.0 303 */ 304 function wp_ajax_get_community_events() { 305 require_once( ABSPATH . 'wp-admin/includes/class-wp-community-events.php' ); 306 307 check_ajax_referer( 'community_events' ); 308 309 $search = isset( $_POST['location'] ) ? wp_unslash( $_POST['location'] ) : ''; 310 $timezone = isset( $_POST['timezone'] ) ? wp_unslash( $_POST['timezone'] ) : ''; 311 $user_id = get_current_user_id(); 312 $saved_location = get_user_option( 'community-events-location', $user_id ); 313 $events_client = new WP_Community_Events( $user_id, $saved_location ); 314 $events = $events_client->get_events( $search, $timezone ); 315 316 if ( is_wp_error( $events ) ) { 317 wp_send_json_error( array( 318 'error' => $events->get_error_message(), 319 ) ); 320 } else { 321 if ( isset( $events['location'] ) ) { 322 // Send only the data that the client will use. 323 $events['location'] = $events['location']['description']; 324 325 // Store the location network-wide, so the user doesn't have to set it on each site. 326 update_user_option( $user_id, 'community-events-location', $events['location'], true ); 327 } 328 329 wp_send_json_success( $events ); 330 } 297 331 } 298 332 -
trunk/src/wp-admin/includes/dashboard.php
r40556 r40607 53 53 } 54 54 55 // WordPress News56 wp_add_dashboard_widget( 'dashboard_primary', __( 'WordPress News' ), 'wp_dashboard_primary' );55 // WordPress Events and News 56 wp_add_dashboard_widget( 'dashboard_primary', __( 'WordPress Events and News' ), 'wp_dashboard_events_news' ); 57 57 58 58 if ( is_network_admin() ) { … … 128 128 /** This action is documented in wp-admin/edit-form-advanced.php */ 129 129 do_action( 'do_meta_boxes', $screen->id, 'side', '' ); 130 } 131 132 /** 133 * Gets the community events data that needs to be passed to dashboard.js. 134 * 135 * @since 4.8.0 136 * 137 * @return array The script data. 138 */ 139 function wp_get_community_events_script_data() { 140 require_once( ABSPATH . 'wp-admin/includes/class-wp-community-events.php' ); 141 142 $user_id = get_current_user_id(); 143 $user_location = get_user_option( 'community-events-location', $user_id ); 144 $events_client = new WP_Community_Events( $user_id, $user_location ); 145 146 $script_data = array( 147 'nonce' => wp_create_nonce( 'community_events' ), 148 'cache' => $events_client->get_cached_events(), 149 150 'l10n' => array( 151 'enter_closest_city' => __( 'Enter your closest city to find nearby events.' ), 152 'error_occurred_please_try_again' => __( 'An error occured. Please try again.' ), 153 154 /* 155 * These specific examples were chosen to highlight the fact that a 156 * state is not needed, even for cities whose name is not unique. 157 * It would be too cumbersome to include that in the instructions 158 * to the user, so it's left as an implication. 159 */ 160 /* translators: %s is the name of the city we couldn't locate. Replace the examples with cities in your locale, but test that they match the expected location before including them. Use endonyms (native locale names) whenever possible. */ 161 'could_not_locate_city' => __( "We couldn't locate %s. Please try another nearby city. For example: Kansas City; Springfield; Portland." ), 162 163 // This one is only used with wp.a11y.speak(), so it can/should be more brief. 164 /* translators: %s is the name of a city. */ 165 'city_updated' => __( 'City updated. Listing events near %s.' ), 166 ) 167 ); 168 169 return $script_data; 130 170 } 131 171 … … 1070 1110 } 1071 1111 1112 1113 /** 1114 * Renders the Events and News dashboard widget. 1115 * 1116 * @since 4.8.0 1117 */ 1118 function wp_dashboard_events_news() { 1119 wp_print_community_events_markup(); 1120 1121 ?> 1122 1123 <div class="wordpress-news hide-if-no-js"> 1124 <?php wp_dashboard_primary(); ?> 1125 </div> 1126 1127 <p class="community-events-footer"> 1128 <a href="https://make.wordpress.org/community/meetups-landing-page" target="_blank"> 1129 <?php _e( 'Meetups' ); ?> <span class="dashicons dashicons-external"></span> 1130 </a> 1131 1132 | 1133 1134 <a href="https://central.wordcamp.org/schedule/" target="_blank"> 1135 <?php _e( 'WordCamps' ); ?> <span class="dashicons dashicons-external"></span> 1136 </a> 1137 1138 | 1139 1140 <?php // translators: If a Rosetta site exists (e.g. https://es.wordpress.org/news/), then use that. Otherwise, leave untranslated. ?> 1141 <a href="<?php _e( 'https://wordpress.org/news/' ); ?>" target="_blank"> 1142 <?php _e( 'News' ); ?> <span class="dashicons dashicons-external"></span> 1143 </a> 1144 </p> 1145 1146 <?php 1147 } 1148 1149 /** 1150 * Prints the markup for the Community Events section of the Events and News Dashboard widget. 1151 * 1152 * @since 4.8.0 1153 */ 1154 function wp_print_community_events_markup() { 1155 $script_data = wp_get_community_events_script_data(); 1156 1157 ?> 1158 1159 <div class="community-events-errors notice notice-error inline hide-if-js"> 1160 <p class="hide-if-js"> 1161 <?php _e( 'This widget requires JavaScript.'); ?> 1162 </p> 1163 1164 <p class="community-events-error-occurred" aria-hidden="true"> 1165 <?php echo $script_data['l10n']['error_occurred_please_try_again']; ?> 1166 </p> 1167 1168 <p class="community-events-could-not-locate" aria-hidden="true"></p> 1169 </div> 1170 1171 <div class="community-events-loading hide-if-no-js"> 1172 <?php _e( 'Loading…'); ?> 1173 </div> 1174 1175 <?php 1176 /* 1177 * Hide the main element when the page first loads, because the content 1178 * won't be ready until wp.communityEvents.renderEventsTemplate() has run. 1179 */ 1180 ?> 1181 <div id="community-events" class="community-events" aria-hidden="true"> 1182 <div class="activity-block"> 1183 <p> 1184 <span id="community-events-location-message"></span> 1185 1186 <button class="button-link community-events-toggle-location" aria-label="<?php _e( 'Edit city'); ?>" aria-expanded="false"> 1187 <span class="dashicons dashicons-edit"></span> 1188 </button> 1189 </p> 1190 1191 <form class="community-events-form" aria-hidden="true" action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" method="post"> 1192 <label for="community-events-location"> 1193 <?php _e( 'City:' ); ?> 1194 </label> 1195 <?php /* translators: Replace with the name of a city in your locale that shows events. Use only the city name itself, without any region or country. Use the endonym instead of the English name. */ ?> 1196 <input id="community-events-location" class="regular-text" type="text" name="community-events-location" placeholder="<?php _e( 'Cincinnati' ); ?>" /> 1197 1198 <?php submit_button( __( 'Submit' ), 'secondary', 'community-events-submit', false ); ?> 1199 1200 <button class="community-events-cancel button button-link" type="button" aria-expanded="false"> 1201 <?php _e( 'Cancel' ); ?> 1202 </button> 1203 1204 <span class="spinner"></span> 1205 </form> 1206 </div> 1207 1208 <ul class="community-events-results activity-block last"></ul> 1209 </div> 1210 1211 <?php 1212 } 1213 1214 /** 1215 * Renders the events templates for the Event and News widget. 1216 * 1217 * @since 4.8.0 1218 */ 1219 function wp_print_community_events_templates() { 1220 $script_data = wp_get_community_events_script_data(); 1221 1222 ?> 1223 1224 <script id="tmpl-community-events-attend-event-near" type="text/template"> 1225 <?php printf( 1226 /* translators: %s is a placeholder for the name of a city. */ 1227 __( 'Attend an upcoming event near %s.' ), 1228 '<strong>{{ data.location }}</strong>' 1229 ); ?> 1230 </script> 1231 1232 <script id="tmpl-community-events-could-not-locate" type="text/template"> 1233 <?php printf( 1234 $script_data['l10n']['could_not_locate_city'], 1235 '<em>{{data.unknownCity}}</em>' 1236 ); ?> 1237 </script> 1238 1239 <script id="tmpl-community-events-event-list" type="text/template"> 1240 <# _.each( data.events, function( event ) { #> 1241 <li class="event event-{{ event.type }} wp-clearfix"> 1242 <div class="event-info"> 1243 <div class="dashicons event-icon" aria-hidden="true"></div> 1244 <div class="event-info-inner"> 1245 <a class="event-title" href="{{ event.url }}">{{ event.title }}</a> 1246 <span class="event-city">{{ event.location.location }}</span> 1247 </div> 1248 </div> 1249 1250 <div class="event-date-time"> 1251 <span class="event-date">{{ event.formatted_date }}</span> 1252 <# if ( 'meetup' === event.type ) { #> 1253 <span class="event-time">{{ event.formatted_time }}</span> 1254 <# } #> 1255 </div> 1256 </li> 1257 <# } ) #> 1258 </script> 1259 1260 <script id="tmpl-community-events-no-upcoming-events" type="text/template"> 1261 <li class="event-none"> 1262 <?php printf( 1263 /* translators: 1: the city the user searched for, 2: meetup organization documentation URL */ 1264 __( 'There aren’t any events scheduled near %1$s at the moment. Would you like to <a href="%2$s">organize one</a>?' ), 1265 '{{data.location}}', 1266 __( 'https://make.wordpress.org/community/handbook/meetup-organizer/welcome/' ) 1267 ); ?> 1268 </li> 1269 </script> 1270 1271 <?php 1272 } 1273 1072 1274 /** 1073 1275 * WordPress News dashboard widget. 1074 1276 * 1075 1277 * @since 2.7.0 1278 * @since 4.8.0 Removed popular plugins feed. 1076 1279 */ 1077 1280 function wp_dashboard_primary() { … … 1106 1309 'title' => apply_filters( 'dashboard_primary_title', __( 'WordPress Blog' ) ), 1107 1310 'items' => 1, 1108 'show_summary' => 1,1311 'show_summary' => 0, 1109 1312 'show_author' => 0, 1110 'show_date' => 1,1313 'show_date' => 0, 1111 1314 ), 1112 1315 'planet' => array( … … 1153 1356 ); 1154 1357 1155 if ( ( ! wp_disallow_file_mods( 'dashboard_widget' ) ) && ( ! is_multisite() && is_blog_admin() && current_user_can( 'install_plugins' ) ) || ( is_network_admin() && current_user_can( 'manage_network_plugins' ) && current_user_can( 'install_plugins' ) ) ) {1156 $feeds['plugins'] = array(1157 'link' => '',1158 'url' => array(1159 'popular' => 'http://wordpress.org/plugins/rss/browse/popular/',1160 ),1161 'title' => '',1162 'items' => 1,1163 'show_summary' => 0,1164 'show_author' => 0,1165 'show_date' => 0,1166 );1167 }1168 1169 1358 wp_dashboard_cached_rss_widget( 'dashboard_primary', 'wp_dashboard_primary_output', $feeds ); 1170 1359 } … … 1174 1363 * 1175 1364 * @since 3.8.0 1365 * @since 4.8.0 Removed popular plugins feed. 1176 1366 * 1177 1367 * @param string $widget_id Widget ID. … … 1182 1372 $args['type'] = $type; 1183 1373 echo '<div class="rss-widget">'; 1184 if ( $type === 'plugins' ) {1185 wp_dashboard_plugins_output( $args['url'], $args );1186 } else {1187 1374 wp_widget_rss_output( $args['url'], $args ); 1188 }1189 1375 echo "</div>"; 1190 1376 } 1191 }1192 1193 /**1194 * Display plugins text for the WordPress news widget.1195 *1196 * @since 2.5.01197 *1198 * @param string $rss The RSS feed URL.1199 * @param array $args Array of arguments for this RSS feed.1200 */1201 function wp_dashboard_plugins_output( $rss, $args = array() ) {1202 // Plugin feeds plus link to install them1203 $popular = fetch_feed( $args['url']['popular'] );1204 1205 if ( false === $plugin_slugs = get_transient( 'plugin_slugs' ) ) {1206 $plugin_slugs = array_keys( get_plugins() );1207 set_transient( 'plugin_slugs', $plugin_slugs, DAY_IN_SECONDS );1208 }1209 1210 echo '<ul>';1211 1212 foreach ( array( $popular ) as $feed ) {1213 if ( is_wp_error( $feed ) || ! $feed->get_item_quantity() )1214 continue;1215 1216 $items = $feed->get_items(0, 5);1217 1218 // Pick a random, non-installed plugin1219 while ( true ) {1220 // Abort this foreach loop iteration if there's no plugins left of this type1221 if ( 0 == count($items) )1222 continue 2;1223 1224 $item_key = array_rand($items);1225 $item = $items[$item_key];1226 1227 list($link, $frag) = explode( '#', $item->get_link() );1228 1229 $link = esc_url($link);1230 if ( preg_match( '|/([^/]+?)/?$|', $link, $matches ) )1231 $slug = $matches[1];1232 else {1233 unset( $items[$item_key] );1234 continue;1235 }1236 1237 // Is this random plugin's slug already installed? If so, try again.1238 reset( $plugin_slugs );1239 foreach ( $plugin_slugs as $plugin_slug ) {1240 if ( $slug == substr( $plugin_slug, 0, strlen( $slug ) ) ) {1241 unset( $items[$item_key] );1242 continue 2;1243 }1244 }1245 1246 // If we get to this point, then the random plugin isn't installed and we can stop the while().1247 break;1248 }1249 1250 // Eliminate some common badly formed plugin descriptions1251 while ( ( null !== $item_key = array_rand($items) ) && false !== strpos( $items[$item_key]->get_description(), 'Plugin Name:' ) )1252 unset($items[$item_key]);1253 1254 if ( !isset($items[$item_key]) )1255 continue;1256 1257 $raw_title = $item->get_title();1258 1259 $ilink = wp_nonce_url('plugin-install.php?tab=plugin-information&plugin=' . $slug, 'install-plugin_' . $slug) . '&TB_iframe=true&width=600&height=800';1260 echo '<li class="dashboard-news-plugin"><span>' . __( 'Popular Plugin' ) . ':</span> ' . esc_html( $raw_title ) .1261 ' <a href="' . $ilink . '" class="thickbox open-plugin-details-modal" aria-label="' .1262 /* translators: %s: plugin name */1263 esc_attr( sprintf( __( 'Install %s' ), $raw_title ) ) . '">(' . __( 'Install' ) . ')</a></li>';1264 1265 $feed->__destruct();1266 unset( $feed );1267 }1268 1269 echo '</ul>';1270 1377 } 1271 1378 -
trunk/src/wp-admin/includes/deprecated.php
r38470 r40607 1296 1296 1297 1297 /** 1298 * Display plugins text for the WordPress news widget. 1299 * 1300 * @since 2.5.0 1301 * @deprecated 4.8.0 1302 * 1303 * @param string $rss The RSS feed URL. 1304 * @param array $args Array of arguments for this RSS feed. 1305 */ 1306 function wp_dashboard_plugins_output( $rss, $args = array() ) { 1307 _deprecated_function( __FUNCTION__, '4.8.0' ); 1308 1309 // Plugin feeds plus link to install them 1310 $popular = fetch_feed( $args['url']['popular'] ); 1311 1312 if ( false === $plugin_slugs = get_transient( 'plugin_slugs' ) ) { 1313 $plugin_slugs = array_keys( get_plugins() ); 1314 set_transient( 'plugin_slugs', $plugin_slugs, DAY_IN_SECONDS ); 1315 } 1316 1317 echo '<ul>'; 1318 1319 foreach ( array( $popular ) as $feed ) { 1320 if ( is_wp_error( $feed ) || ! $feed->get_item_quantity() ) 1321 continue; 1322 1323 $items = $feed->get_items(0, 5); 1324 1325 // Pick a random, non-installed plugin 1326 while ( true ) { 1327 // Abort this foreach loop iteration if there's no plugins left of this type 1328 if ( 0 == count($items) ) 1329 continue 2; 1330 1331 $item_key = array_rand($items); 1332 $item = $items[$item_key]; 1333 1334 list($link, $frag) = explode( '#', $item->get_link() ); 1335 1336 $link = esc_url($link); 1337 if ( preg_match( '|/([^/]+?)/?$|', $link, $matches ) ) 1338 $slug = $matches[1]; 1339 else { 1340 unset( $items[$item_key] ); 1341 continue; 1342 } 1343 1344 // Is this random plugin's slug already installed? If so, try again. 1345 reset( $plugin_slugs ); 1346 foreach ( $plugin_slugs as $plugin_slug ) { 1347 if ( $slug == substr( $plugin_slug, 0, strlen( $slug ) ) ) { 1348 unset( $items[$item_key] ); 1349 continue 2; 1350 } 1351 } 1352 1353 // If we get to this point, then the random plugin isn't installed and we can stop the while(). 1354 break; 1355 } 1356 1357 // Eliminate some common badly formed plugin descriptions 1358 while ( ( null !== $item_key = array_rand($items) ) && false !== strpos( $items[$item_key]->get_description(), 'Plugin Name:' ) ) 1359 unset($items[$item_key]); 1360 1361 if ( !isset($items[$item_key]) ) 1362 continue; 1363 1364 $raw_title = $item->get_title(); 1365 1366 $ilink = wp_nonce_url('plugin-install.php?tab=plugin-information&plugin=' . $slug, 'install-plugin_' . $slug) . '&TB_iframe=true&width=600&height=800'; 1367 echo '<li class="dashboard-news-plugin"><span>' . __( 'Popular Plugin' ) . ':</span> ' . esc_html( $raw_title ) . 1368 ' <a href="' . $ilink . '" class="thickbox open-plugin-details-modal" aria-label="' . 1369 /* translators: %s: plugin name */ 1370 esc_attr( sprintf( __( 'Install %s' ), $raw_title ) ) . '">(' . __( 'Install' ) . ')</a></li>'; 1371 1372 $feed->__destruct(); 1373 unset( $feed ); 1374 } 1375 1376 echo '</ul>'; 1377 } 1378 1379 /** 1298 1380 * This was once used to move child posts to a new parent. 1299 1381 * -
trunk/src/wp-admin/includes/upgrade.php
r40296 r40607 565 565 if ( $wp_current_db_version < 37965 ) 566 566 upgrade_460(); 567 568 if ( $wp_current_db_version < 40500 ) { //todo update to commit for #40702 569 upgrade_480(); 570 } 567 571 568 572 maybe_disable_link_manager(); … … 1734 1738 1735 1739 /** 1740 * Executes changes made in WordPress 4.8.0. 1741 * 1742 * @ignore 1743 * @since 4.8.0 1744 * 1745 * @global int $wp_current_db_version Current database version. 1746 */ 1747 function upgrade_480() { 1748 global $wp_current_db_version; 1749 1750 if ( $wp_current_db_version < 40500 ) { // todo update to commit for #40702 1751 // This feature plugin was merged for #40702, so the plugin itself is no longer needed 1752 deactivate_plugins( array( 'nearby-wp-events/nearby-wordpress-events.php' ), true ); 1753 1754 // The markup stored in this transient changed for #40702 1755 delete_transient( 'dash_' . md5( 'dashboard_primary' . '_' . get_locale() ) ); 1756 } 1757 } 1758 1759 /** 1736 1760 * Executes network-level upgrade routines. 1737 1761 * -
trunk/src/wp-admin/index.php
r38899 r40607 16 16 17 17 wp_enqueue_script( 'dashboard' ); 18 wp_localize_script( 'dashboard', 'communityEventsData', wp_get_community_events_script_data() ); 19 18 20 if ( current_user_can( 'edit_theme_options' ) ) 19 21 wp_enqueue_script( 'customize-loader' ); … … 139 141 140 142 <?php 143 wp_print_community_events_templates(); 144 141 145 require( ABSPATH . 'wp-admin/admin-footer.php' ); -
trunk/src/wp-admin/js/dashboard.js
r34977 r40607 1 1 /* global pagenow, ajaxurl, postboxes, wpActiveEditor:true */ 2 2 var ajaxWidgets, ajaxPopulateWidgets, quickPressLoad; 3 window.wp = window.wp || {}; 3 4 4 5 jQuery(document).ready( function($) { … … 188 189 189 190 } ); 191 192 jQuery( function( $ ) { 193 'use strict'; 194 195 var communityEventsData = window.communityEventsData || {}; 196 197 var app = window.wp.communityEvents = { 198 initialized: false, 199 model: null, 200 201 /** 202 * Initializes the wp.communityEvents object. 203 * 204 * @since 4.8.0 205 */ 206 init: function() { 207 if ( app.initialized ) { 208 return; 209 } 210 211 var $container = $( '#community-events' ); 212 213 /* 214 * When JavaScript is disabled, the errors container is shown, so 215 * that "This widget requires Javascript" message can be seen. 216 * 217 * When JS is enabled, the container is hidden at first, and then 218 * revealed during the template rendering, if there actually are 219 * errors to show. 220 * 221 * The display indicator switches from `hide-if-js` to `aria-hidden` 222 * here in order to maintain consistency with all the other fields 223 * that key off of `aria-hidden` to determine their visibility. 224 * `aria-hidden` can't be used initially, because there would be no 225 * way to set it to false when JavaScript is disabled, which would 226 * prevent people from seeing the "This widget requires JavaScript" 227 * message. 228 */ 229 $( '.community-events-errors' ) 230 .attr( 'aria-hidden', true ) 231 .removeClass( 'hide-if-js' ); 232 233 $container.on( 'click', '.community-events-toggle-location, .community-events-cancel', app.toggleLocationForm ); 234 235 $container.on( 'submit', '.community-events-form', function( event ) { 236 event.preventDefault(); 237 238 app.getEvents( { 239 location: $( '#community-events-location' ).val() 240 }); 241 }); 242 243 if ( communityEventsData && communityEventsData.cache && communityEventsData.cache.location && communityEventsData.cache.events ) { 244 app.renderEventsTemplate( communityEventsData.cache, 'app' ); 245 } else { 246 app.getEvents(); 247 } 248 249 app.initialized = true; 250 }, 251 252 /** 253 * Toggles the visibility of the Edit Location form. 254 * 255 * @since 4.8.0 256 * 257 * @param {event|string} action 'show' or 'hide' to specify a state; 258 * Or an event object to flip between states 259 */ 260 toggleLocationForm: function( action ) { 261 var $toggleButton = $( '.community-events-toggle-location' ), 262 $cancelButton = $( '.community-events-cancel' ), 263 $form = $( '.community-events-form' ); 264 265 if ( 'object' === typeof action ) { 266 // Strict comparison doesn't work in this case. 267 action = 'true' == $toggleButton.attr( 'aria-expanded' ) ? 'hide' : 'show'; 268 } 269 270 if ( 'hide' === action ) { 271 $toggleButton.attr( 'aria-expanded', false ); 272 $cancelButton.attr( 'aria-expanded', false ); 273 $form.attr( 'aria-hidden', true ); 274 } else { 275 $toggleButton.attr( 'aria-expanded', true ); 276 $cancelButton.attr( 'aria-expanded', true ); 277 $form.attr( 'aria-hidden', false ); 278 } 279 }, 280 281 /** 282 * Sends REST API requests to fetch events for the widget. 283 * 284 * @since 4.8.0 285 * 286 * @param {object} requestParams 287 */ 288 getEvents: function( requestParams ) { 289 var initiatedBy, 290 app = this, 291 $spinner = $( '.community-events-form' ).children( '.spinner' ); 292 293 requestParams = requestParams || {}; 294 requestParams._wpnonce = communityEventsData.nonce; 295 requestParams.timezone = window.Intl ? window.Intl.DateTimeFormat().resolvedOptions().timeZone : ''; 296 297 initiatedBy = requestParams.location ? 'user' : 'app'; 298 299 $spinner.addClass( 'is-active' ); 300 301 wp.ajax.post( 'get-community-events', requestParams ) 302 .always( function() { 303 $spinner.removeClass( 'is-active' ); 304 }) 305 306 .done( function( response ) { 307 if ( 'no_location_available' === response.error ) { 308 if ( requestParams.location ) { 309 response.unknownCity = requestParams.location; 310 } else { 311 /* 312 * No location was passed, which means that this was an automatic query 313 * based on IP, locale, and timezone. Since the user didn't initiate it, 314 * it should fail silently. Otherwise, the error could confuse and/or 315 * annoy them. 316 */ 317 318 delete response.error; 319 } 320 } 321 app.renderEventsTemplate( response, initiatedBy ); 322 }) 323 324 .fail( function() { 325 app.renderEventsTemplate( { 326 'location' : false, 327 'error' : true 328 }, initiatedBy ); 329 }); 330 }, 331 332 /** 333 * Renders the template for the Events section of the Events & News widget. 334 * 335 * @since 4.8.0 336 * 337 * @param {Object} templateParams The various parameters that will get passed to wp.template 338 * @param {string} initiatedBy 'user' to indicate that this was triggered manually by the user; 339 * 'app' to indicate it was triggered automatically by the app itself. 340 */ 341 renderEventsTemplate: function( templateParams, initiatedBy ) { 342 var template, 343 elementVisibility, 344 l10nPlaceholder = /%(?:\d\$)?s/g, // Match `%s`, `%1$s`, `%2$s`, etc. 345 $locationMessage = $( '#community-events-location-message' ), 346 $results = $( '.community-events-results' ); 347 348 /* 349 * Hide all toggleable elements by default, to keep the logic simple. 350 * Otherwise, each block below would have to turn hide everything that 351 * could have been shown at an earlier point. 352 * 353 * The exception to that is that the .community-events container. It's hidden 354 * when the page is first loaded, because the content isn't ready yet, 355 * but once we've reached this point, it should always be shown. 356 */ 357 elementVisibility = { 358 '.community-events' : true, 359 '.community-events-loading' : false, 360 '.community-events-errors' : false, 361 '.community-events-error-occurred' : false, 362 '.community-events-could-not-locate' : false, 363 '#community-events-location-message' : false, 364 '.community-events-toggle-location' : false, 365 '.community-events-results' : false 366 }; 367 368 /* 369 * Determine which templates should be rendered and which elements 370 * should be displayed. 371 */ 372 if ( templateParams.location ) { 373 template = wp.template( 'community-events-attend-event-near' ); 374 $locationMessage.html( template( templateParams ) ); 375 376 if ( templateParams.events.length ) { 377 template = wp.template( 'community-events-event-list' ); 378 $results.html( template( templateParams ) ); 379 } else { 380 template = wp.template( 'community-events-no-upcoming-events' ); 381 $results.html( template( templateParams ) ); 382 } 383 wp.a11y.speak( communityEventsData.l10n.city_updated.replace( l10nPlaceholder, templateParams.location ) ); 384 385 elementVisibility['#community-events-location-message'] = true; 386 elementVisibility['.community-events-toggle-location'] = true; 387 elementVisibility['.community-events-results'] = true; 388 389 } else if ( templateParams.unknownCity ) { 390 template = wp.template( 'community-events-could-not-locate' ); 391 $( '.community-events-could-not-locate' ).html( template( templateParams ) ); 392 wp.a11y.speak( communityEventsData.l10n.could_not_locate_city.replace( l10nPlaceholder, templateParams.unknownCity ) ); 393 394 elementVisibility['.community-events-errors'] = true; 395 elementVisibility['.community-events-could-not-locate'] = true; 396 397 } else if ( templateParams.error && 'user' === initiatedBy ) { 398 /* 399 * Errors messages are only shown for requests that were initiated 400 * by the user, not for ones that were initiated by the app itself. 401 * Showing error messages for an event that user isn't aware of 402 * could be confusing or unnecessarily distracting. 403 */ 404 wp.a11y.speak( communityEventsData.l10n.error_occurred_please_try_again ); 405 406 elementVisibility['.community-events-errors'] = true; 407 elementVisibility['.community-events-error-occurred'] = true; 408 409 } else { 410 $locationMessage.text( communityEventsData.l10n.enter_closest_city ); 411 412 elementVisibility['#community-events-location-message'] = true; 413 elementVisibility['.community-events-toggle-location'] = true; 414 } 415 416 // Set the visibility of toggleable elements. 417 _.each( elementVisibility, function( isVisible, element ) { 418 $( element ).attr( 'aria-hidden', ! isVisible ); 419 }); 420 421 $( '.community-events-toggle-location' ).attr( 'aria-expanded', elementVisibility['.community-events-toggle-location'] ); 422 423 /* 424 * During the initial page load, the location form should be hidden 425 * by default if the user has saved a valid location during a previous 426 * session. It's safe to assume that they want to continue using that 427 * location, and displaying the form would unnecessarily clutter the 428 * widget. 429 */ 430 if ( 'app' === initiatedBy && templateParams.location ) { 431 app.toggleLocationForm( 'hide' ); 432 } else { 433 app.toggleLocationForm( 'show' ); 434 } 435 } 436 }; 437 438 if ( $( '#dashboard_primary' ).is( ':visible' ) ) { 439 app.init(); 440 } else { 441 $( document ).on( 'postbox-toggled', function( event, postbox ) { 442 var $postbox = $( postbox ); 443 444 if ( 'dashboard_primary' === $postbox.attr( 'id' ) && $postbox.is( ':visible' ) ) { 445 app.init(); 446 } 447 }); 448 } 449 }); -
trunk/src/wp-admin/network/index.php
r38721 r40607 55 55 56 56 wp_enqueue_script( 'dashboard' ); 57 wp_localize_script( 'dashboard', 'communityEventsData', wp_get_community_events_script_data() ); 57 58 wp_enqueue_script( 'plugin-install' ); 58 59 add_thickbox(); … … 74 75 </div><!-- wrap --> 75 76 76 <?php include( ABSPATH . 'wp-admin/admin-footer.php' ); ?> 77 <?php 78 wp_print_community_events_templates(); 79 include( ABSPATH . 'wp-admin/admin-footer.php' ); -
trunk/src/wp-includes/script-loader.php
r40283 r40607 725 725 ) ); 726 726 727 $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox' ), false, 1 );727 $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-util', 'wp-a11y' ), false, 1 ); 728 728 729 729 $scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" );
Note: See TracChangeset
for help on using the changeset viewer.