WordPress.org

Make WordPress Core

Changeset 41390


Ignore:
Timestamp:
09/19/17 05:39:37 (5 weeks ago)
Author:
westonruter
Message:

Customize: Add notifications API to sections and panels.

  • Adds a notifications property to instances of wp.customize.Panel and wp.customize.Section.
  • Adds a setupNotifications() method to Panel, Section, and Control.
  • Adds a getNotificationsContainerElement() method to the Panel and Section classes, like Control has.
  • Replace hard-coded notification in header media section with a notification.
  • Limit rendering notifications to panels and sections that are expanded, and to controls that have an expanded section.

See #34893, #35210, #38778.
Fixes #38794.

Location:
trunk/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/customize-controls.css

    r41389 r41390  
    790790} 
    791791 
    792 .customize-control-notifications-container li.notice { 
     792#customize-controls .customize-control-notifications-container li.notice { 
    793793    list-style: none; 
    794794    margin: 0 0 6px 0; 
    795     padding: 4px 8px; 
     795    padding: 9px 14px; 
     796    overflow: hidden; 
     797} 
     798#customize-controls .customize-control-notifications-container .notice.is-dismissible { 
     799    padding-right: 38px; 
    796800} 
    797801 
     
    816820    top: 46px; 
    817821    width: 100%; 
     822    border-bottom: 1px solid #ddd; 
     823    display: block; 
     824    padding: 0; 
     825    margin: 0; 
     826} 
     827 
     828#customize-controls #customize-notifications-area, 
     829#customize-controls .customize-section-title > .customize-control-notifications-container, 
     830#customize-controls .panel-meta > .customize-control-notifications-container { 
    818831    max-height: 210px; 
    819832    overflow-x: hidden; 
    820833    overflow-y: auto; 
    821     border-bottom: 1px solid #ddd; 
    822     display: block; 
    823     padding: 0; 
     834} 
     835 
     836#customize-controls #customize-notifications-area > ul, 
     837#customize-controls #customize-notifications-area .notice, 
     838#customize-controls .panel-meta > .customize-control-notifications-container, 
     839#customize-controls .panel-meta > .customize-control-notifications-container .notice, 
     840#customize-controls .customize-section-title > .customize-control-notifications-container, 
     841#customize-controls .customize-section-title > .customize-control-notifications-container .notice { 
    824842    margin: 0; 
    825843} 
    826  
    827 #customize-controls #customize-notifications-area > ul, 
    828 #customize-controls #customize-notifications-area .notice { 
    829     margin: 0; 
    830 } 
    831 #customize-controls #customize-notifications-area .notice { 
     844#customize-controls .panel-meta > .customize-control-notifications-container, 
     845#customize-controls .customize-section-title > .customize-control-notifications-container { 
     846    border-top: 1px solid #ddd; 
     847} 
     848#customize-controls #customize-notifications-area .notice, 
     849#customize-controls .panel-meta > .customize-control-notifications-container .notice, 
     850#customize-controls .customize-section-title > .customize-control-notifications-container .notice { 
    832851    padding: 9px 14px; 
    833852} 
    834 #customize-controls #customize-notifications-area .notice.is-dismissible { 
     853#customize-controls #customize-notifications-area .notice.is-dismissible, 
     854#customize-controls .panel-meta > .customize-control-notifications-container .notice.is-dismissible, 
     855#customize-controls .customize-section-title > .customize-control-notifications-container .notice.is-dismissible { 
    835856    padding-right: 38px; 
    836857} 
    837 #customize-controls #customize-notifications-area .notice + .notice { 
     858#customize-controls #customize-notifications-area .notice + .notice, 
     859#customize-controls .panel-meta > .customize-control-notifications-container .notice + .notice, 
     860#customize-controls .customize-section-title > .customize-control-notifications-container .notice + .notice { 
    838861    margin-top: 1px; 
    839862} 
  • trunk/src/wp-admin/js/customize-controls.js

    r41389 r41390  
    159159 
    160160            // Short-circuit if there are no changes to the notifications. 
    161             if ( _.isEqual( notifications, collection.previousNotifications ) ) { 
     161            if ( collection.container.is( collection.previousContainer ) && _.isEqual( notifications, collection.previousNotifications ) ) { 
    162162                return; 
    163163            } 
     
    186186 
    187187            collection.previousNotifications = notifications; 
     188            collection.previousContainer = collection.container; 
    188189            collection.trigger( 'rendered' ); 
    189190        } 
     
    627628 
    628629            $.extend( container, options ); 
     630            container.notifications = new api.Notifications(); 
    629631            container.templateSelector = 'customize-' + container.containerType + '-' + container.params.type; 
    630632            container.container = $( container.params.content ); 
     
    658660 
    659661            container.deferred.embedded.done( function () { 
     662                container.setupNotifications(); 
    660663                container.attachEvents(); 
    661664            }); 
     
    666669            container.active.set( container.params.active ); 
    667670            container.expanded.set( false ); 
     671        }, 
     672 
     673        /** 
     674         * Get the element that will contain the notifications. 
     675         * 
     676         * @since 4.9.0 
     677         * @returns {jQuery} Notification container element. 
     678         * @this {wp.customize.Control} 
     679         */ 
     680        getNotificationsContainerElement: function() { 
     681            var container = this; 
     682            return container.contentContainer.find( '.customize-control-notifications-container:first' ); 
     683        }, 
     684 
     685        /** 
     686         * Set up notifications. 
     687         * 
     688         * @since 4.9.0 
     689         * @returns {void} 
     690         */ 
     691        setupNotifications: function() { 
     692            var container = this, renderNotifications; 
     693            container.notifications.container = container.getNotificationsContainerElement(); 
     694 
     695            // Render notifications when they change and when the construct is expanded. 
     696            renderNotifications = function() { 
     697                if ( container.expanded.get() ) { 
     698                    container.notifications.render(); 
     699                } 
     700            }; 
     701            container.expanded.bind( renderNotifications ); 
     702            renderNotifications(); 
     703            container.notifications.bind( 'change', _.debounce( renderNotifications ) ); 
    668704        }, 
    669705 
     
    21632199            // After the control is embedded on the page, invoke the "ready" method. 
    21642200            control.deferred.embedded.done( function () { 
    2165                 var renderNotifications = function() { 
    2166                     control.notifications.render(); 
    2167                 }; 
    2168                 control.notifications.container = control.getNotificationsContainerElement(); 
    2169                 control.notifications.bind( 'rendered', function() { 
    2170                     var notifications = control.notifications.get(); 
    2171                     control.container.toggleClass( 'has-notifications', 0 !== notifications.length ); 
    2172                     control.container.toggleClass( 'has-error', 0 !== _.where( notifications, { type: 'error' } ).length ); 
    2173                 } ); 
    2174                 renderNotifications(); 
    2175                 control.notifications.bind( 'change', _.debounce( renderNotifications ) ); 
     2201                control.setupNotifications(); 
    21762202                control.ready(); 
    21772203            }); 
     
    22682294            } 
    22692295            return notificationsContainer; 
     2296        }, 
     2297 
     2298        /** 
     2299         * Set up notifications. 
     2300         * 
     2301         * @since 4.9.0 
     2302         * @returns {void} 
     2303         */ 
     2304        setupNotifications: function() { 
     2305            var control = this, renderNotificationsIfVisible, onSectionAssigned; 
     2306 
     2307            control.notifications.container = control.getNotificationsContainerElement(); 
     2308 
     2309            renderNotificationsIfVisible = function() { 
     2310                var sectionId = control.section(); 
     2311                if ( ! sectionId || ( api.section.has( sectionId ) && api.section( sectionId ).expanded() ) ) { 
     2312                    control.notifications.render(); 
     2313                } 
     2314            }; 
     2315 
     2316            control.notifications.bind( 'rendered', function() { 
     2317                var notifications = control.notifications.get(); 
     2318                control.container.toggleClass( 'has-notifications', 0 !== notifications.length ); 
     2319                control.container.toggleClass( 'has-error', 0 !== _.where( notifications, { type: 'error' } ).length ); 
     2320            } ); 
     2321 
     2322            onSectionAssigned = function( newSectionId, oldSectionId ) { 
     2323                if ( oldSectionId && api.section.has( oldSectionId ) ) { 
     2324                    api.section( oldSectionId ).expanded.unbind( renderNotificationsIfVisible ); 
     2325                } 
     2326                if ( newSectionId ) { 
     2327                    api.section( newSectionId, function( section ) { 
     2328                        section.expanded.bind( renderNotificationsIfVisible ); 
     2329                        renderNotificationsIfVisible(); 
     2330                    }); 
     2331                } 
     2332            }; 
     2333 
     2334            control.section.bind( onSectionAssigned ); 
     2335            onSectionAssigned( control.section.get() ); 
     2336            control.notifications.bind( 'change', _.debounce( renderNotificationsIfVisible ) ); 
    22702337        }, 
    22712338 
     
    58555922            headerVideoControl.deferred.embedded.done( function() { 
    58565923                var toggleNotice = function() { 
    5857                     var section = api.section( headerVideoControl.section() ), notice; 
     5924                    var section = api.section( headerVideoControl.section() ), noticeCode = 'video_header_not_available'; 
    58585925                    if ( ! section ) { 
    58595926                        return; 
    58605927                    } 
    5861                     notice = section.container.find( '.header-video-not-currently-previewable:first' ); 
    58625928                    if ( headerVideoControl.active.get() ) { 
    5863                         notice.stop().slideUp( 'fast' ); 
     5929                        section.notifications.remove( noticeCode ); 
    58645930                    } else { 
    5865                         notice.stop().slideDown( 'fast' ); 
     5931                        section.notifications.add( noticeCode, new api.Notification( noticeCode, { 
     5932                            type: 'info', 
     5933                            message: api.l10n.videoHeaderNotice 
     5934                        } ) ); 
    58665935                    } 
    58675936                }; 
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r41388 r41390  
    39293929            $description = '<p>' . __( 'If you add a video, the image will be used as a fallback while the video loads.' ) . '</p>'; 
    39303930 
    3931             // @todo Customizer sections should support having notifications just like controls do. See <https://core.trac.wordpress.org/ticket/38794>. 
    3932             $description .= '<div class="customize-control-notifications-container header-video-not-currently-previewable" style="display: none"><ul>'; 
    3933             $description .= '<li class="notice notice-info">' . __( 'This theme doesn\'t support video headers on this page. Navigate to the front page or another page that supports video headers.' ) . '</li>'; 
    3934             $description .= '</ul></div>'; 
    39353931            $width = absint( get_theme_support( 'custom-header', 'width' ) ); 
    39363932            $height = absint( get_theme_support( 'custom-header', 'height' ) ); 
  • trunk/src/wp-includes/class-wp-customize-panel.php

    r41162 r41390  
    372372                </div> 
    373373            <# } #> 
     374 
     375            <div class="customize-control-notifications-container"></div> 
    374376        </li> 
    375377        <?php 
  • trunk/src/wp-includes/class-wp-customize-section.php

    r41162 r41390  
    362362                            </div> 
    363363                        <# } #> 
     364 
     365                        <div class="customize-control-notifications-container"></div> 
    364366                    </div> 
    365367 
  • trunk/src/wp-includes/script-loader.php

    r41389 r41390  
    564564        'untitledBlogName'   => __( '(Untitled)' ), 
    565565        'serverSaveError'    => __( 'Failed connecting to the server. Please try saving again.' ), 
     566        'videoHeaderNotice'   => __( 'This theme doesn\'t support video headers on this page. Navigate to the front page or another page that supports video headers.' ), 
    566567        // Used for overriding the file types allowed in plupload. 
    567568        'allowedFiles'       => __( 'Allowed Files' ), 
Note: See TracChangeset for help on using the changeset viewer.