Ticket #33052: 33052.diff
| File 33052.diff, 13.4 KB (added by , 11 years ago) |
|---|
-
src/wp-admin/css/customize-controls.css
diff --git src/wp-admin/css/customize-controls.css src/wp-admin/css/customize-controls.css index b35bc3b..c5f784d 100644
body { 123 123 color: #0073aa; 124 124 } 125 125 126 #customize-controls .customize-info .customize-panel-description { 126 #customize-controls .customize-info .customize-panel-description, 127 #customize-controls .no-widget-areas-rendered-notice { 127 128 color: #555; 128 129 display: none; 129 130 background: #fff; 130 131 padding: 12px 15px; 131 132 border-top: 1px solid #ddd; 132 133 } 134 #customize-controls .no-widget-areas-rendered-notice { 135 font-style: italic; 136 } 137 #customize-controls .customize-info .customize-panel-description.open + .no-widget-areas-rendered-notice { 138 border-top: none; 139 } 133 140 134 141 #customize-controls .customize-info .customize-panel-description p:first-child { 135 142 margin-top: 0; -
src/wp-admin/js/customize-controls.js
diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js index 35f6a7b..132229f 100644
378 378 }, 379 379 380 380 /** 381 * @param {Boolean} expanded 382 * @param {Object} [params] 383 * @returns {Boolean} false if state already applied 381 * Handle the toggle logic for expand/collapse. 382 * 383 * @param {Boolean} expanded - The new state to apply. 384 * @param {Object} [params] - Object containing options for expand/collapse. 385 * @param {Function} [params.completeCallback] - Function to call when expansion/collapse is complete. 386 * @returns {Boolean} false if state already applied or active state is false 384 387 */ 385 _toggleExpanded: function ( expanded, params ) {386 var self = this;388 _toggleExpanded: function( expanded, params ) { 389 var instance = this, previousCompleteCallback; 387 390 params = params || {}; 388 var section = this, previousCompleteCallback = params.completeCallback; 389 params.completeCallback = function () { 391 previousCompleteCallback = params.completeCallback; 392 393 // Short-circuit expand() if the instance is not active. 394 if ( expanded && ! instance.active() ) { 395 return false; 396 } 397 398 params.completeCallback = function() { 390 399 if ( previousCompleteCallback ) { 391 previousCompleteCallback.apply( section, arguments );400 previousCompleteCallback.apply( instance, arguments ); 392 401 } 393 402 if ( expanded ) { 394 section.container.trigger( 'expanded' );403 instance.container.trigger( 'expanded' ); 395 404 } else { 396 section.container.trigger( 'collapsed' );405 instance.container.trigger( 'collapsed' ); 397 406 } 398 407 }; 399 if ( ( expanded && this.expanded.get() ) || ( ! expanded && ! this.expanded.get() ) ) {408 if ( ( expanded && instance.expanded.get() ) || ( ! expanded && ! instance.expanded.get() ) ) { 400 409 params.unchanged = true; 401 self.onChangeExpanded( self.expanded.get(), params );410 instance.onChangeExpanded( instance.expanded.get(), params ); 402 411 return false; 403 412 } else { 404 413 params.unchanged = false; 405 this.expandedArgumentsQueue.push( params );406 this.expanded.set( expanded );414 instance.expandedArgumentsQueue.push( params ); 415 instance.expanded.set( expanded ); 407 416 return true; 408 417 } 409 418 }, 410 419 411 420 /** 412 421 * @param {Object} [params] 413 * @returns {Boolean} false if already expanded 422 * @returns {Boolean} false if already expanded or if inactive. 414 423 */ 415 424 expand: function ( params ) { 416 425 return this._toggleExpanded( true, params ); … … 418 427 419 428 /** 420 429 * @param {Object} [params] 421 * @returns {Boolean} false if already collapsed 430 * @returns {Boolean} false if already collapsed. 422 431 */ 423 432 collapse: function ( params ) { 424 433 return this._toggleExpanded( false, params ); … … 539 548 }; 540 549 section.panel.bind( inject ); 541 550 inject( section.panel.get() ); // Since a section may never get a panel, assume that it won't ever get one 551 552 section.deferred.embedded.done(function() { 553 // Fix the top margin after reflow. 554 api.bind( 'pane-contents-reflowed', _.debounce( function() { 555 section._recalculateTopMargin(); 556 }, 100 ) ); 557 }); 542 558 }, 543 559 544 560 /** … … 646 662 // Fix the height after browser resize. 647 663 $( window ).on( 'resize.customizer-section', _.debounce( resizeContentHeight, 100 ) ); 648 664 649 // Fix the top margin after reflow. 650 api.bind( 'pane-contents-reflowed', _.debounce( function() { 651 var offset = ( content.offset().top - headerActionsHeight ); 652 if ( 0 < offset ) { 653 content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - offset ) ); 654 } 655 }, 100 ) ); 665 section._recalculateTopMargin(); 656 666 }; 657 667 } 658 668 … … 693 703 args.completeCallback(); 694 704 } 695 705 } 706 }, 707 708 /** 709 * Recalculate the top margin. 710 * 711 * @since 4.4.0 712 * @private 713 */ 714 _recalculateTopMargin: function() { 715 var section = this, content, offset, headerActionsHeight; 716 content = section.container.find( '.accordion-section-content' ); 717 if ( 0 === content.length ) { 718 return; 719 } 720 headerActionsHeight = $( '#customize-header-actions' ).height(); 721 offset = ( content.offset().top - headerActionsHeight ); 722 if ( 0 < offset ) { 723 content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - offset ) ); 724 } 696 725 } 697 726 }); 698 727 … … 1155 1184 parentContainer.append( panel.container ); 1156 1185 panel.renderContent(); 1157 1186 } 1187 1188 api.bind( 'pane-contents-reflowed', _.debounce( function() { 1189 panel._recalculateTopMargin(); 1190 }, 100 ) ); 1191 1158 1192 panel.deferred.embedded.resolve(); 1159 1193 }, 1160 1194 … … 1253 1287 * @param {Boolean} expanded 1254 1288 * @param {Object} args 1255 1289 * @param {Boolean} args.unchanged 1256 * @param { Callback} args.completeCallback1290 * @param {Function} args.completeCallback 1257 1291 */ 1258 1292 onChangeExpanded: function ( expanded, args ) { 1259 1293 … … 1268 1302 // Note: there is a second argument 'args' passed 1269 1303 var position, scroll, 1270 1304 panel = this, 1271 section = panel.container.closest( '.accordion-section' ), // This is actually the panel.1272 overlay = section.closest( '.wp-full-overlay' ),1273 container = section.closest( '.wp-full-overlay-sidebar-content' ),1305 accordionSection = panel.container.closest( '.accordion-section' ), 1306 overlay = accordionSection.closest( '.wp-full-overlay' ), 1307 container = accordionSection.closest( '.wp-full-overlay-sidebar-content' ), 1274 1308 siblings = container.find( '.open' ), 1275 1309 topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ), 1276 backBtn = section.find( '.customize-panel-back' ),1277 panelTitle = section.find( '.accordion-section-title' ).first(),1278 content = section.find( '.control-panel-content' ),1310 backBtn = accordionSection.find( '.customize-panel-back' ), 1311 panelTitle = accordionSection.find( '.accordion-section-title' ).first(), 1312 content = accordionSection.find( '.control-panel-content' ), 1279 1313 headerActionsHeight = $( '#customize-header-actions' ).height(); 1280 1314 1281 1315 if ( expanded ) { … … 1297 1331 position = content.offset().top; 1298 1332 scroll = container.scrollTop(); 1299 1333 content.css( 'margin-top', ( headerActionsHeight - position - scroll ) ); 1300 section.addClass( 'current-panel' );1334 accordionSection.addClass( 'current-panel' ); 1301 1335 overlay.addClass( 'in-sub-panel' ); 1302 1336 container.scrollTop( 0 ); 1303 1337 if ( args.completeCallback ) { … … 1307 1341 topPanel.attr( 'tabindex', '-1' ); 1308 1342 backBtn.attr( 'tabindex', '0' ); 1309 1343 backBtn.focus(); 1310 1311 // Fix the top margin after reflow. 1312 api.bind( 'pane-contents-reflowed', _.debounce( function() { 1313 content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - ( content.offset().top - headerActionsHeight ) ) ); 1314 }, 100 ) ); 1344 panel._recalculateTopMargin(); 1315 1345 } else { 1316 1346 siblings.removeClass( 'open' ); 1317 section.removeClass( 'current-panel' );1347 accordionSection.removeClass( 'current-panel' ); 1318 1348 overlay.removeClass( 'in-sub-panel' ); 1319 1349 content.delay( 180 ).hide( 0, function() { 1320 1350 content.css( 'margin-top', 'inherit' ); // Reset … … 1330 1360 }, 1331 1361 1332 1362 /** 1363 * Recalculate the top margin. 1364 * 1365 * @since 4.4.0 1366 * @private 1367 */ 1368 _recalculateTopMargin: function() { 1369 var panel = this, headerActionsHeight, content, accordionSection; 1370 headerActionsHeight = $( '#customize-header-actions' ).height(); 1371 accordionSection = panel.container.closest( '.accordion-section' ) 1372 content = accordionSection.find( '.control-panel-content' ); 1373 content.css( 'margin-top', ( parseInt( content.css( 'margin-top' ), 10 ) - ( content.offset().top - headerActionsHeight ) ) ); 1374 }, 1375 1376 /** 1333 1377 * Render the panel from its JS template, if it exists. 1334 1378 * 1335 1379 * The panel's container must already exist in the DOM. -
src/wp-admin/js/customize-widgets.js
diff --git src/wp-admin/js/customize-widgets.js src/wp-admin/js/customize-widgets.js index 6a640e0..e7c82f2 100644
1432 1432 } ); 1433 1433 1434 1434 /** 1435 * wp.customize.Widgets.WidgetsPanel 1436 * 1437 * Customizer panel containing the widget area sections. 1438 * 1439 * @since 4.4.0 1440 */ 1441 api.Widgets.WidgetsPanel = api.Panel.extend({ 1442 1443 /** 1444 * Add and manage the display of the no-rendered-areas notice. 1445 * 1446 * @since 4.4.0 1447 */ 1448 ready: function () { 1449 var panel = this; 1450 1451 api.Panel.prototype.ready.call( panel ); 1452 1453 panel.deferred.embedded.done(function() { 1454 var panelMetaContainer, noRenderedAreasNotice, shouldShowNotice; 1455 panelMetaContainer = panel.container.find( '.panel-meta' ); 1456 noRenderedAreasNotice = $( '<div></div>', { 1457 'class': 'no-widget-areas-rendered-notice', 1458 text: l10n.noAreasRendered 1459 }); 1460 panelMetaContainer.append( noRenderedAreasNotice ); 1461 1462 shouldShowNotice = function() { 1463 return ( 0 === _.filter( panel.sections(), function( section ) { 1464 return section.active(); 1465 } ).length ); 1466 }; 1467 1468 /* 1469 * Defer setting visibility of no-rendered-areas-notice until 1470 * preview finishes loading since this is when the active 1471 * sections become available. 1472 */ 1473 api.previewer.deferred.active.done( function () { 1474 noRenderedAreasNotice.toggle( shouldShowNotice() ); 1475 1476 // Update the visibility of the notice whenever a reflow happens. 1477 api.bind( 'pane-contents-reflowed', function() { 1478 api.previewer.deferred.active.done( function () { 1479 if ( shouldShowNotice() ) { 1480 noRenderedAreasNotice.slideDown( 'fast' ); 1481 } else { 1482 noRenderedAreasNotice.slideUp( 'fast' ); 1483 } 1484 }); 1485 }); 1486 }); 1487 }); 1488 }, 1489 1490 /** 1491 * Allow an active widgets panel to be contextually active even when it has no active sections (widget areas). 1492 * 1493 * This ensures that the widgets panel appears even when there are no 1494 * sidebars displayed on the URL currently being previewed. 1495 * 1496 * @since 4.4.0 1497 * 1498 * @returns {boolean} 1499 */ 1500 isContextuallyActive: function() { 1501 var panel = this; 1502 return panel.active(); 1503 } 1504 }); 1505 1506 /** 1435 1507 * wp.customize.Widgets.SidebarSection 1436 1508 * 1437 1509 * Customizer section representing a widget area widget … … 1894 1966 } 1895 1967 } ); 1896 1968 1897 // Register models for custom section and control types 1969 // Register models for custom panel, section, and control types 1970 $.extend( api.panelConstructor, { 1971 widgets: api.Widgets.WidgetsPanel 1972 }); 1898 1973 $.extend( api.sectionConstructor, { 1899 1974 sidebar: api.Widgets.SidebarSection 1900 1975 }); -
src/wp-includes/class-wp-customize-widgets.php
diff --git src/wp-includes/class-wp-customize-widgets.php src/wp-includes/class-wp-customize-widgets.php index 8569228..77a0518 100644
final class WP_Customize_Widgets { 355 355 } 356 356 357 357 $this->manager->add_panel( 'widgets', array( 358 'title' => __( 'Widgets' ), 359 'description' => __( 'Widgets are independent sections of content that can be placed into widgetized areas provided by your theme (commonly called sidebars).' ), 360 'priority' => 110, 358 'type' => 'widgets', 359 'title' => __( 'Widgets' ), 360 'description' => __( 'Widgets are independent sections of content that can be placed into widgetized areas provided by your theme (commonly called sidebars).' ), 361 'priority' => 110, 362 'active_callback' => array( $this, 'is_panel_active' ), 361 363 ) ); 362 364 363 365 foreach ( $sidebars_widgets as $sidebar_id => $sidebar_widget_ids ) { … … final class WP_Customize_Widgets { 455 457 } 456 458 457 459 /** 460 * Return whether the widgets panel is active, based on whether there are sidebars registered. 461 * 462 * @since 4.4.0 463 * @access public 464 * 465 * @see WP_Customize_Panel::$active_callback 466 * 467 * @global array $wp_registered_sidebars 468 * @return bool Active. 469 */ 470 public function is_panel_active() { 471 global $wp_registered_sidebars; 472 return ! empty( $wp_registered_sidebars ); 473 } 474 475 /** 458 476 * Covert a widget_id into its corresponding Customizer setting ID (option name). 459 477 * 460 478 * @since 3.9.0 … … final class WP_Customize_Widgets { 655 673 'error' => __( 'An error has occurred. Please reload the page and try again.' ), 656 674 'widgetMovedUp' => __( 'Widget moved up' ), 657 675 'widgetMovedDown' => __( 'Widget moved down' ), 676 'noAreasRendered' => __( 'There are no widget areas currently rendered in the preview. Navigate in the preview to a template that makes use of a widget area in order to access its widgets here.' ), 658 677 ), 659 678 'tpl' => array( 660 679 'widgetReorderNav' => $widget_reorder_nav_tpl,