diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css index 3234eb6249..adbd862be8 100644 --- a/src/wp-admin/css/customize-controls.css +++ b/src/wp-admin/css/customize-controls.css @@ -565,8 +565,8 @@ p.customize-section-description { } .customize-control select { - min-width: 50%; - max-width: 100%; + width: 100%; + max-width: 300px; height: 28px; line-height: 28px; } @@ -587,6 +587,7 @@ p.customize-section-description { display: block; font-style: italic; line-height: 18px; + margin-top: 0; margin-bottom: 5px; } @@ -674,6 +675,54 @@ p.customize-section-description { float: left; } +#available-menu-items .accordion-section-content .new-content-item, +.customize-control-dropdown-pages .new-content-item { + width: -webkit-calc(100% - 30px); + width: calc(100% - 30px); + padding: 8px 15px; + position: absolute; + bottom: 0; + z-index: 10; + background: #eee; + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} + +.customize-control-dropdown-pages .new-content-item { + width: 100%; + max-width: 300px; + padding: 5px 0 5px 1px; + position: relative; +} + +#available-menu-items .new-content-item .create-item-input, +.customize-control-dropdown-pages .new-content-item .create-item-input { + -webkit-box-flex: 10; + -webkit-flex-grow: 10; + -moz-box-flex: 10; + -ms-flex-positive: 10; + -ms-flex: 10; + flex-grow: 10; +} + +#available-menu-items .new-content-item .add-content, +.customize-control-dropdown-pages .new-content-item .add-content { + margin: 2px 0 2px 6px; + -webkit-box-flex: 10; + -webkit-flex-grow: 10; + -moz-box-flex: 10; + -ms-flex-positive: 10; + -ms-flex: 10; + flex-grow: 1; +} + +.customize-control-dropdown-pages .new-content-item .create-item-input.invalid { + border: 1px solid #f00; +} + #customize-preview iframe { width: 100%; height: 100%; diff --git a/src/wp-admin/css/customize-nav-menus.css b/src/wp-admin/css/customize-nav-menus.css index 1386fe0940..a63df15975 100644 --- a/src/wp-admin/css/customize-nav-menus.css +++ b/src/wp-admin/css/customize-nav-menus.css @@ -572,41 +572,6 @@ padding: 0 15px 15px 15px; } -#available-menu-items .accordion-section-content .new-content-item { - width: -webkit-calc(100% - 30px); - width: calc(100% - 30px); - padding: 8px 15px; - position: absolute; - bottom: 0; - z-index: 10; - background: #eee; - display: -webkit-box; - display: -moz-box; - display: -ms-flexbox; - display: -webkit-flex; - display: flex; -} - -#available-menu-items .new-content-item .create-item-input { - -webkit-box-flex: 10; - -webkit-flex-grow: 10; - -moz-box-flex: 10; - -ms-flex-positive: 10; - -ms-flex: 10; - flex-grow: 10; - margin-left: 5px; - padding: 4.5px; -} -#available-menu-items .new-content-item .add-content { - padding-left: 6px; - -webkit-box-flex: 10; - -webkit-flex-grow: 10; - -moz-box-flex: 10; - -ms-flex-positive: 10; - -ms-flex: 10; - flex-grow: 1; -} - #available-menu-items .menu-item-tpl { margin: 0; } diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index a23a130c0b..90b8411fb6 100644 --- a/src/wp-admin/js/customize-controls.js +++ b/src/wp-admin/js/customize-controls.js @@ -2516,9 +2516,28 @@ /** * Triggered when the control's markup has been injected into the DOM. * - * @abstract + * @returns {void} */ - ready: function() {}, + ready: function() { + var control = this, newItem; + if ( 'dropdown-pages' === control.params.type && control.params.allow_addition ) { + newItem = control.container.find( '.new-content-item' ); + newItem.hide(); // Hide in JS to preserve flex display when showing. + control.container.on( 'click', '.add-new-toggle', function( e ) { + $( e.currentTarget ).slideUp( 180 ); + newItem.slideDown( 180 ); + newItem.find( '.create-item-input' ).focus(); + }); + control.container.on( 'click', '.add-content', function() { + control.addNewPage(); + }); + control.container.on( 'keyup', '.create-item-input', function( e ) { + if ( 13 === e.which ) { // Enter + control.addNewPage(); + } + }); + } + }, /** * Get the element inside of a control's container that contains the validation error message. @@ -2736,6 +2755,73 @@ control.container.html( template( control.params ) ); } } + }, + + /** + * Add a new page to a dropdown-pages control reusing menus code for this. + * + * @since 4.7.0 + * @access private + * @returns {void} + */ + addNewPage: function () { + var control = this, promise, toggle, container, input, title, select; + + if ( 'dropdown-pages' !== control.params.type || ! control.params.allow_addition || ! api.Menus ) { + return; + } + + toggle = control.container.find( '.add-new-toggle' ); + container = control.container.find( '.new-content-item' ); + input = control.container.find( '.create-item-input' ); + title = input.val(); + select = control.container.find( 'select' ); + + if ( ! title ) { + input.addClass( 'invalid' ); + return; + } + + input.removeClass( 'invalid' ); + input.attr( 'disabled', 'disabled' ); + + // The menus functions add the page, publish when appropriate, and also add the new page to the dropdown-pages controls. + promise = api.Menus.insertAutoDraftPost( { + post_title: title, + post_type: 'page' + } ); + promise.done( function( data ) { + var availableItem, $content, itemTemplate; + + // Prepare the new page as an available menu item. + // See api.Menus.submitNew(). + availableItem = new api.Menus.AvailableItemModel( { + 'id': 'post-' + data.post_id, // Used for available menu item Backbone models. + 'title': title, + 'type': 'page', + 'type_label': api.Menus.data.l10n.page_label, + 'object': 'post_type', + 'object_id': data.post_id, + 'url': data.url + } ); + + // Add the new item to the list of available menu items. + api.Menus.availableMenuItemsPanel.collection.add( availableItem ); + $content = $( '#available-menu-items-post_type-page' ).find( '.available-menu-items-list' ); + itemTemplate = wp.template( 'available-menu-item' ); + $content.prepend( itemTemplate( availableItem.attributes ) ); + + // Focus the select control. + select.focus(); + control.setting.set( String( data.post_id ) ); // Triggers a preview refresh and updates the setting. + + // Reset the create page form. + container.slideUp( 180 ); + toggle.slideDown( 180 ); + } ) + .always( function() { + input.val( '' ).removeAttr( 'disabled' ); + } ); } }); diff --git a/src/wp-admin/js/customize-nav-menus.js b/src/wp-admin/js/customize-nav-menus.js index 9981cc92ef..6024739059 100644 --- a/src/wp-admin/js/customize-nav-menus.js +++ b/src/wp-admin/js/customize-nav-menus.js @@ -101,7 +101,6 @@ request.done( function( response ) { if ( response.post_id ) { - deferred.resolve( response ); api.Menus.insertedAutoDrafts.push( response.post_id ); api( 'nav_menus_created_posts' ).set( _.clone( api.Menus.insertedAutoDrafts ) ); @@ -121,6 +120,7 @@ } } ); } + deferred.resolve( response ); } } ); diff --git a/src/wp-includes/class-wp-customize-control.php b/src/wp-includes/class-wp-customize-control.php index e8482b2df0..c45af67d8f 100644 --- a/src/wp-includes/class-wp-customize-control.php +++ b/src/wp-includes/class-wp-customize-control.php @@ -114,6 +114,15 @@ class WP_Customize_Control { */ public $input_attrs = array(); + /** + * Show UI for adding new content, currently only used for the dropdown-pages control. + * + * @since 4.7.0 + * @access public + * @var array + */ + public $allow_addition = false; + /** * @deprecated It is better to just call the json() method * @access public @@ -296,6 +305,10 @@ class WP_Customize_Control { $this->json['label'] = $this->label; $this->json['description'] = $this->description; $this->json['instanceNumber'] = $this->instance_number; + + if ( 'dropdown-pages' === $this->type ) { + $this->json['allow_addition'] = $this->allow_addition; + } } /** @@ -554,10 +567,34 @@ class WP_Customize_Control { // Hackily add in the data link parameter. $dropdown = str_replace( '', $auto_draft_page_options . '', $dropdown ); + } + } + echo $dropdown; ?> - allow_addition && current_user_can( 'publish_pages' ) && current_user_can( 'edit_theme_options' ) ) : // Currently tied to menus functionality. ?> + +