WordPress.org

Make WordPress Core

Changeset 41390


Ignore:
Timestamp:
09/19/2017 05:39:37 AM (22 months 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.