diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index 2d7f3bad4a..5d0b30bb4b 100644 --- a/src/wp-admin/js/customize-controls.js +++ b/src/wp-admin/js/customize-controls.js @@ -157,18 +157,40 @@ defaultActiveArguments: { duration: 'fast', completeCallback: $.noop }, defaultExpandedArguments: { duration: 'fast', completeCallback: $.noop }, containerType: 'container', + defaults: { + title: '', + description: '', + priority: 100, + type: 'default', + content: null, + active: true, + instanceNumber: null + }, /** * @since 4.1.0 * - * @param {String} id - * @param {Object} options + * @param {string} id - The ID for the container. + * @param {object} options - Object containing one property: params. + * @param {object} options.params - Object containing the following properties. + * @param {string} options.params.title - Title shown when panel is collapsed and expanded. + * @param {string=} [options.params.description] - Description shown at the top of the panel. + * @param {number=100} [options.params.priority] - The sort priority for the panel. + * @param {string=default} [options.params.type] - The type of the panel. See wp.customize.panelConstructor. + * @param {string=} [options.params.content] - The markup to be used for the panel container. If empty, a JS template is used. + * @param {boolean=true} [options.params.active] - Whether the panel is active or not. */ initialize: function ( id, options ) { var container = this; container.id = id; - container.params = {}; - $.extend( container, options || {} ); + options = options || {}; + + options.params = _.defaults( + options.params || {}, + container.defaults + ); + + $.extend( container, options ); container.templateSelector = 'customize-' + container.containerType + '-' + container.params.type; container.container = $( container.params.content ); if ( 0 === container.container.length ) { @@ -202,7 +224,7 @@ api.utils.bubbleChildValueChanges( container, [ 'priority', 'active' ] ); - container.priority.set( isNaN( container.params.priority ) ? 100 : container.params.priority ); + container.priority.set( container.params.priority ); container.active.set( container.params.active ); container.expanded.set( false ); }, @@ -386,9 +408,11 @@ if ( 0 !== $( '#tmpl-' + container.templateSelector ).length ) { template = wp.template( container.templateSelector ); - if ( template && container.container ) { - return $.trim( template( container.params ) ); - } + } else { + template = wp.template( 'customize-' + container.containerType + '-default' ); + } + if ( template && container.container ) { + return $.trim( template( container.params ) ); } return '
'; @@ -403,12 +427,32 @@ */ api.Section = Container.extend({ containerType: 'section', + defaults: { + title: '', + description: '', + priority: 100, + type: 'default', + content: null, + active: true, + instanceNumber: null, + panel: null, + customizeAction: '' + }, /** * @since 4.1.0 * - * @param {String} id - * @param {Array} options + * @param {string} id - The ID for the section. + * @param {object} options - Object containing one property: params. + * @param {object} options.params - Object containing the following properties. + * @param {string} options.params.title - Title shown when section is collapsed and expanded. + * @param {string=} [options.params.description] - Description shown at the top of the section. + * @param {number=100} [options.params.priority] - The sort priority for the section. + * @param {string=default} [options.params.type] - The type of the section. See wp.customize.sectionConstructor. + * @param {string=} [options.params.content] - The markup to be used for the section container. If empty, a JS template is used. + * @param {boolean=true} [options.params.active] - Whether the section is active or not. + * @param {string} options.params.panel - The ID for the panel this section is associated with. + * @param {string=} [options.params.customizeAction] - Additional context information shown before the section title when expanded. */ initialize: function ( id, options ) { var section = this; @@ -1009,8 +1053,15 @@ /** * @since 4.1.0 * - * @param {String} id - * @param {Object} options + * @param {string} id - The ID for the panel. + * @param {object} options - Object containing one property: params. + * @param {object} options.params - Object containing the following properties. + * @param {string} options.params.title - Title shown when panel is collapsed and expanded. + * @param {string=} [options.params.description] - Description shown at the top of the panel. + * @param {number=100} [options.params.priority] - The sort priority for the panel. + * @param {string=default} [options.params.type] - The type of the panel. See wp.customize.panelConstructor. + * @param {string=} [options.params.content] - The markup to be used for the panel container. If empty, a JS template is used. + * @param {boolean=true} [options.params.active] - Whether the panel is active or not. */ initialize: function ( id, options ) { var panel = this; @@ -1216,9 +1267,11 @@ // Add the content to the container. if ( 0 !== $( '#tmpl-' + panel.templateSelector + '-content' ).length ) { template = wp.template( panel.templateSelector + '-content' ); - if ( template && panel.container ) { - panel.container.find( '.accordion-sub-container' ).html( template( panel.params ) ); - } + } else { + template = wp.template( 'customize-panel-default-content' ); + } + if ( template && panel.container ) { + panel.container.find( '.accordion-sub-container' ).html( template( panel.params ) ); } } }); diff --git a/tests/qunit/fixtures/customize-settings.js b/tests/qunit/fixtures/customize-settings.js index 5ef44a1873..bc92c4c7b1 100644 --- a/tests/qunit/fixtures/customize-settings.js +++ b/tests/qunit/fixtures/customize-settings.js @@ -57,7 +57,16 @@ window._wpCustomizeSettings = { 'priority': 110, 'title': 'Fixture titleless panel using template', 'type': 'titleless' - } + }, + 'fixture-panel-reusing-default-template': { + 'active': true, + 'description': 'Lorem ipsum', + 'instanceNumber': 3, + 'priority': 110, + 'title': 'Fixture panel of custom type re-using default template', + 'type': 'reusing-default-template' + }, + 'fixture-panel-without-params': {} }, 'sections': { 'fixture-section': { @@ -87,7 +96,17 @@ window._wpCustomizeSettings = { 'priority': 20, 'title': 'Fixture titleless section using template', 'type': 'titleless' - } + }, + 'fixture-section-reusing-default-template': { + 'active': true, + 'description': '', + 'instanceNumber': 4, + 'panel': 'fixture-panel', + 'priority': 20, + 'title': 'Fixture section of custom type re-using default template', + 'type': 'reusing-default-template' + }, + 'fixture-section-without-params': {} }, 'settings': { 'fixture-setting': { diff --git a/tests/qunit/wp-admin/js/customize-controls.js b/tests/qunit/wp-admin/js/customize-controls.js index 215d46802f..6ca4908499 100644 --- a/tests/qunit/wp-admin/js/customize-controls.js +++ b/tests/qunit/wp-admin/js/customize-controls.js @@ -136,6 +136,37 @@ jQuery( window ).load( function (){ ok( 0 === section.container.find( '> .accordion-section-title' ).length ); ok( 1 === section.container.find( '> .accordion-section-content' ).length ); } ); + module( 'Customizer Custom Type Section Lacking Specific Template' ); + test( 'Fixture section has expected content', function () { + var id = 'fixture-section-reusing-default-template', section; + section = wp.customize.section( id ); + ok( ! section.params.content ); + ok( !! section.container ); + ok( section.container.is( '.control-section.control-section-' + section.params.type ) ); + ok( 1 === section.container.find( '> .accordion-section-title' ).length ); + ok( 1 === section.container.find( '> .accordion-section-content' ).length ); + } ); + module( 'Customizer Section lacking any params' ); + test( 'Fixture section has default params supplied', function () { + var id = 'fixture-section-without-params', section, defaultParams; + section = wp.customize.section( id ); + defaultParams = { + title: '', + description: '', + priority: 100, + panel: null, + type: 'default', + content: null, + active: true, + instanceNumber: null, + customizeAction: '' + }; + jQuery.each( defaultParams, function ( key, value ) { + ok( 'undefined' !== typeof section.params[ key ] ); + equal( value, section.params[ key ] ); + } ); + } ); + // Begin panels. module( 'Customizer Panel in Fixture' ); @@ -199,6 +230,34 @@ jQuery( window ).load( function (){ ok( 1 === panel.container.find( '> .control-panel-content' ).length ); } ); + module( 'Customizer Custom Type Panel Lacking Specific Template' ); + test( 'Fixture panel has expected content', function () { + var id = 'fixture-panel-reusing-default-template', panel; + panel = wp.customize.panel( id ); + ok( ! panel.params.content ); + ok( !! panel.container ); + ok( panel.container.is( '.control-panel.control-panel-' + panel.params.type ) ); + ok( 1 === panel.container.find( '> .accordion-section-title' ).length ); + ok( 1 === panel.container.find( '> .control-panel-content' ).length ); + } ); + module( 'Customizer Panel lacking any params' ); + test( 'Fixture panel has default params supplied', function () { + var id = 'fixture-panel-without-params', panel, defaultParams; + panel = wp.customize.panel( id ); + defaultParams = { + title: '', + description: '', + priority: 100, + type: 'default', + content: null, + active: true, + instanceNumber: null + }; + jQuery.each( defaultParams, function ( key, value ) { + ok( 'undefined' !== typeof panel.params[ key ] ); + equal( value, panel.params[ key ] ); + } ); + } ); module( 'Dynamically-created Customizer Setting Model' ); settingId = 'new_blogname';