diff --git a/.dev-lib b/.dev-lib index 6c7ef38..40a78e7 100644 --- a/.dev-lib +++ b/.dev-lib @@ -1,2 +1,6 @@ WPCS_GIT_TREE=develop ASSETS_DIR=wp-assets + +if [[ ${TRAVIS_PHP_VERSION:0:3} == "5.2" ]] || [[ ${TRAVIS_PHP_VERSION:0:3} == "5.3" ]]; then + DEV_LIB_SKIP="$DEV_LIB_SKIP,phpcs" +fi diff --git a/.travis.yml b/.travis.yml index 5a82b06..1f54919 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,13 +17,13 @@ language: - node_js php: - - 5.3 + - 5.2 - 7.0 env: - WP_VERSION=trunk WP_MULTISITE=0 - WP_VERSION=latest WP_MULTISITE=0 - - WP_VERSION=4.6.1 WP_MULTISITE=0 + - WP_VERSION=4.7.6 WP_MULTISITE=0 - WP_VERSION=latest WP_MULTISITE=1 install: diff --git a/composer.json b/composer.json index 0777c41..d7087d2 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "xwp/wp-customize-posts", "description": "Manage posts and postmeta via the Customizer.", - "version": "0.8.7", + "version": "0.9.1", "type": "wordpress-plugin", "keywords": [ "customizer", "customize", "posts", "postmeta", "preview", "featured-image", "page-template" ], "homepage": "https://github.com/xwp/wp-customize-posts/", diff --git a/css/customize-posts.css b/css/customize-posts.css index c02d273..4c6c465 100644 --- a/css/customize-posts.css +++ b/css/customize-posts.css @@ -439,3 +439,10 @@ body.customize-posts-content-editor-pane-resize #customize-preview:before { content: "\f464"; top: -2px; } + +@media screen and (max-width:600px) { + .outer-section-open .select2-container, + .outer-section-open .select2-selection__clear { + z-index: auto !Important; + } +} diff --git a/css/edit-post-preview-customize.css b/css/edit-post-preview-customize.css index b554c55..accd732 100644 --- a/css/edit-post-preview-customize.css +++ b/css/edit-post-preview-customize.css @@ -6,7 +6,8 @@ #customize-header-actions #snapshot-save, #snapshot-status-button-wrapper, #snapshot-preview-link, -#snapshot-expand-button +#snapshot-expand-button, +#publish-settings { display: none !important; } diff --git a/customize-posts.php b/customize-posts.php index 5d68a8c..69efe7b 100644 --- a/customize-posts.php +++ b/customize-posts.php @@ -3,7 +3,7 @@ * Plugin Name: Customize Posts * Description: Manage posts and postmeta via the Customizer. * Plugin URI: https://github.com/xwp/wp-customize-posts/ - * Version: 0.8.7 + * Version: 0.9.1 * Author: XWP * Author URI: https://make.xwp.co/ * License: GPLv2+ diff --git a/dev-lib b/dev-lib index d8540c1..52874e4 160000 --- a/dev-lib +++ b/dev-lib @@ -1 +1 @@ -Subproject commit d8540c1f036c583f48af5f63c3f6d04db36c0db3 +Subproject commit 52874e44d9e737dfc8f1e9ca33381f45deb9b636 diff --git a/js/customize-featured-image.js b/js/customize-featured-image.js index fbbc236..4ba10c7 100644 --- a/js/customize-featured-image.js +++ b/js/customize-featured-image.js @@ -123,11 +123,6 @@ var CustomizeFeaturedImage = (function( api ) { } ); }; - control.active.set( true ); - control.active.validate = function validateForcingTrue() { - return true; - }; - // Register. api.control.add( control.id, control ); diff --git a/js/customize-page-template.js b/js/customize-page-template.js index bad52b7..052b28f 100644 --- a/js/customize-page-template.js +++ b/js/customize-page-template.js @@ -50,7 +50,7 @@ var CustomizePageTemplate = (function( api ) { * @returns {wp.customize.Control|null} The control. */ component.addControl = function( section ) { - var supports, control, controlId, settingId, isActiveCallback; + var supports, control, controlId, settingId; supports = api.Posts.data.postTypes[ section.params.post_type ].supports; if ( ! supports['page-attributes'] || 'page' !== section.params.post_type ) { @@ -103,13 +103,13 @@ var CustomizePageTemplate = (function( api ) { * * @returns {boolean} Is active. */ - isActiveCallback = function() { + function isActiveCallback() { var defaultSize = 1; if ( api.has( 'page_for_posts' ) && parseInt( api( 'page_for_posts' ).get(), 10 ) === section.params.post_id ) { return false; } return _.size( control.params.choices ) > defaultSize; - }; + } control.active.set( isActiveCallback() ); control.active.validate = isActiveCallback; api( 'page_for_posts', function( pageOnFrontSetting ) { diff --git a/js/customize-post-section.js b/js/customize-post-section.js index 3674b49..6421741 100644 --- a/js/customize-post-section.js +++ b/js/customize-post-section.js @@ -307,16 +307,17 @@ * unless the notification is specifically for this control's setting property. * * @this {wp.customize.Control} - * @param {string} code Notification code. - * @param {wp.customize.Notification} notification Notification object. + * @param {string|wp.customize.Notification} notification - Notification object to add. Alternatively code may be supplied, and in that case the second notificationObject argument must be supplied. + * @param {wp.customize.Notification} [notificationObject] - Notification to add when first argument is the code string. * @returns {wp.customize.Notification|null} Notification if not bypassed. */ - addPostFieldControlNotification: function addPostFieldControlNotification( code, notification ) { - var isSettingNotification, isSettingPropertyNotification; + addPostFieldControlNotification: function addPostFieldControlNotification( notification, notificationObject ) { + var isSettingNotification, isSettingPropertyNotification, code; + code = 'string' === typeof notification ? notification : notification.code; isSettingNotification = -1 !== code.indexOf( ':' ) || notification.setting; // Note that sniffing for ':' is deprecated as of #36944 & #37890. isSettingPropertyNotification = notification.data && notification.data.setting_property === this.setting_property; if ( isSettingPropertyNotification || ! isSettingNotification ) { - return api.Values.prototype.add.call( this, code, notification ); + return ( api.Notifications || api.Values ).prototype.add.call( this, notification, notificationObject ); } else { return null; } @@ -393,11 +394,6 @@ } } ); - // Override preview trying to de-activate control not present in preview context. See WP Trac #37270. - control.active.validate = function() { - return true; - }; - // Register. section.postFieldControls.post_title = control; api.control.add( control.id, control ); @@ -451,11 +447,6 @@ setting.bind( setPlaceholder ); } ); - // Override preview trying to de-activate control not present in preview context. See WP Trac #37270. - control.active.validate = function() { - return true; - }; - // Register. section.postFieldControls.post_name = control; api.control.add( control.id, control ); @@ -487,11 +478,6 @@ } } ); - // Override preview trying to de-activate control not present in preview context. See WP Trac #37270. - control.active.validate = function() { - return true; - }; - // Register. section.postFieldControls.post_status = control; api.control.add( control.id, control ); @@ -524,11 +510,6 @@ } } ); - // Override preview trying to de-activate control not present in preview context. See WP Trac #37270. - control.active.validate = function() { - return true; - }; - // Register. section.postFieldControls.post_date = control; api.control.add( control.id, control ); @@ -617,11 +598,6 @@ } } ); - // Override preview trying to de-activate control not present in preview context. See WP Trac #37270. - control.active.validate = function() { - return true; - }; - // Register. section.postFieldControls.post_excerpt = control; api.control.add( control.id, control ); @@ -686,11 +662,6 @@ } ); } - // Override preview trying to de-activate control not present in preview context. - control.active.validate = function() { - return true; - }; - // Register. section.postFieldControls.page_parent = control; api.control.add( control.id, control ); @@ -724,11 +695,6 @@ } } ); - // Override preview trying to de-activate control not present in preview context. See WP Trac #37270. - control.active.validate = function() { - return true; - }; - // Register. section.postFieldControls.menu_order = control; api.control.add( control.id, control ); @@ -761,11 +727,6 @@ } } ); - // Override preview trying to de-activate control not present in preview context. See WP Trac #37270. - control.active.validate = function() { - return true; - }; - // Register. section.postFieldControls.post_discussion_fields = control; api.control.add( control.id, control ); @@ -809,11 +770,6 @@ return data; }; - // Override preview trying to de-activate control not present in preview context. See WP Trac #37270. - control.active.validate = function() { - return true; - }; - // Register. section.postFieldControls.post_author = control; api.control.add( control.id, control ); @@ -826,19 +782,20 @@ }, /** - * Set up section notifications. + * Polyfill notifications API onto sections if not yet on WordPress 4.9 where it is defined in core. * + * @link * @returns {void} */ - setupSectionNotifications: function() { - var section = this, setting = api( section.id ), debouncedRenderNotifications, setPageForPostsNotice; - if ( ! setting.notifications ) { + polyfillNotifications: function() { + var section = this, debouncedRenderNotifications; + if ( section.notifications ) { return; } - // Add the notifications API. section.notifications = new api.Values({ defaultConstructor: api.Notification }); section.notificationsContainer = $( '
' ); + section.notifications.container = section.notificationsContainer; section.notificationsTemplate = wp.template( 'customize-post-section-notifications' ); section.container.find( '.customize-section-title' ).after( section.notificationsContainer ); section.getNotificationsContainerElement = function() { @@ -846,17 +803,6 @@ }; section.renderNotifications = api.Control.prototype.renderNotifications; - // Sync setting notifications into the section notifications - setting.notifications.bind( 'add', function( settingNotification ) { - var notification = new api.Notification( setting.id + ':' + settingNotification.code, settingNotification ); - if ( ! settingNotification.data || ! settingNotification.data.setting_property || ! api.control.has( section.id + '[' + settingNotification.data.setting_property + ']' ) ) { - section.notifications.add( notification.code, notification ); - } - } ); - setting.notifications.bind( 'remove', function( settingNotification ) { - section.notifications.remove( setting.id + ':' + settingNotification.code ); - } ); - /* * Render notifications when the collection is updated. * Note that this debounced/deferred rendering is needed for two reasons: @@ -872,9 +818,40 @@ } ); section.notifications.bind( 'remove', debouncedRenderNotifications ); section.renderNotifications(); + }, + + /** + * Set up section notifications. + * + * @returns {void} + */ + setupSectionNotifications: function() { + var section = this, setting = api( section.id ), setPageForPostsNotice, notificationTemplate; + if ( ! setting.notifications ) { + return; + } + + // Add the notifications API if not present. + section.polyfillNotifications(); + + // Sync setting notifications into the section notifications + setting.notifications.bind( 'add', function( settingNotification ) { + var notification = new api.Notification( setting.id + ':' + settingNotification.code, _.extend( {}, + settingNotification, + { + template: notificationTemplate + } + ) ); + if ( ! settingNotification.data || ! settingNotification.data.setting_property || ! api.control.has( section.id + '[' + settingNotification.data.setting_property + ']' ) ) { + section.notifications.add( notification.code, notification ); + } + } ); + setting.notifications.bind( 'remove', function( settingNotification ) { + section.notifications.remove( setting.id + ':' + settingNotification.code ); + } ); // Dismiss conflict block when clicking on button. - section.notificationsContainer.on( 'click', '.override-post-conflict', function( e ) { + section.notifications.container.on( 'click', '.override-post-conflict', function( e ) { var ourValue; e.preventDefault(); ourValue = _.clone( setting.get() ); @@ -890,6 +867,7 @@ } ); // Detect conflict errors. + notificationTemplate = wp.template( 'customize-post-field-notification' ); api.bind( 'error', function( response ) { var theirValue, ourValue, conflictedControls = []; diff --git a/js/customize-posts.js b/js/customize-posts.js index 4ee5edd..83bc7d1 100644 --- a/js/customize-posts.js +++ b/js/customize-posts.js @@ -571,7 +571,7 @@ * @return {void} */ component.focusControl = function focusControl( controlId ) { - var control, section, postSectionId, matches; + var control, section, postSectionId, matches, postId; /** * Attempt focus on the control. @@ -594,18 +594,33 @@ if ( ! matches ) { return; } - postSectionId = 'post[' + matches[1] + '][' + matches[2] + ']'; - section = api.section( postSectionId ); - if ( ! section || ! section.extended( component.PostSection ) ) { - return; + postId = parseInt( matches[2], 10 ); + postSectionId = 'post[' + matches[1] + '][' + String( postId ) + ']'; + + /** + * Expand and focus on control in section. + * + * @param {component.PostSection} postSection - Section. + * @returns {void} + */ + function sectionResolved( postSection ) { + postSection.expand(); + postSection.contentsEmbedded.done( function() { + var ms = 500; + + // @todo It is not clear why a delay is needed for focus to work. It could be due to focus failing during animation. + _.delay( tryFocus, ms ); + } ); } - section.expand(); - section.contentsEmbedded.done( function() { - var ms = 500; - // @todo It is not clear why a delay is needed for focus to work. It could be due to focus failing during animation. - _.delay( tryFocus, ms ); - } ); + section = api.section( postSectionId ); + if ( section ) { + sectionResolved( section ); + } else { + api.Posts.ensurePosts( [ postId ] ).done( function( data ) { + sectionResolved( data[ postId ].section ); + } ); + } }; /** diff --git a/package.json b/package.json index 2a6d5da..d997444 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "type": "git", "url": "https://github.com/xwp/wp-customize-posts.git" }, - "version": "0.8.7", + "version": "0.9.1", "license": "GPL-2.0+", "private": true, "devDependencies": { diff --git a/php/class-wp-customize-dynamic-control.php b/php/class-wp-customize-dynamic-control.php index 30901c7..dba072f 100644 --- a/php/class-wp-customize-dynamic-control.php +++ b/php/class-wp-customize-dynamic-control.php @@ -74,7 +74,7 @@ protected function content_template() { $data = $this->json(); ?> <# - _.defaults( data, ); + _.defaults( data, ); data.input_id = 'input-' + String( Math.random() ); #> <# if ( 'checkbox' === data.field_type ) { #> diff --git a/php/class-wp-customize-featured-image-controller.php b/php/class-wp-customize-featured-image-controller.php index 0ec4ca8..6d4343b 100644 --- a/php/class-wp-customize-featured-image-controller.php +++ b/php/class-wp-customize-featured-image-controller.php @@ -404,7 +404,7 @@ public function sanitize_setting( $attachment_id, WP_Customize_Postmeta_Setting * and the meta is registered wit WP_Customize_Featured_Image_Controller::sanitize_value() as the sanitize_callback(). * So $attachment_id is either a valid attachment ID, -1, or false. */ - if ( ! $is_valid ) { + if ( ! $is_valid ) { return $has_setting_validation ? new WP_Error( 'invalid_attachment_id', __( 'The attachment is invalid.', 'customize-posts' ) ) : null; } diff --git a/php/class-wp-customize-post-date-control.php b/php/class-wp-customize-post-date-control.php index f009b69..9ea6e48 100644 --- a/php/class-wp-customize-post-date-control.php +++ b/php/class-wp-customize-post-date-control.php @@ -60,12 +60,12 @@ protected function content_template() { $data = $this->json(); ?> <# - _.defaults( data, ); + _.defaults( data, ); data.input_id_base = 'input-' + String( Math.random() ); #> - () + ()
- - diff --git a/php/class-wp-customize-post-discussion-fields-control.php b/php/class-wp-customize-post-discussion-fields-control.php index 012dc02..40cfeb0 100644 --- a/php/class-wp-customize-post-discussion-fields-control.php +++ b/php/class-wp-customize-post-discussion-fields-control.php @@ -29,7 +29,7 @@ protected function content_template() { $data = $this->json(); ?> <# - _.defaults( data, ); + _.defaults( data, ); data.ping_status_input_id = 'input-' + String( Math.random() ); data.comment_status_input_id = 'input-' + String( Math.random() ); #> diff --git a/php/class-wp-customize-post-editor-control.php b/php/class-wp-customize-post-editor-control.php index e6a2ea2..95141b9 100644 --- a/php/class-wp-customize-post-editor-control.php +++ b/php/class-wp-customize-post-editor-control.php @@ -60,14 +60,14 @@ protected function content_template() { $data = $this->json(); ?> <# - _.defaults( data, ); + _.defaults( data, ); data.input_id = 'input-' + String( Math.random() ); #> <# if ( data.description ) { #> {{ data.description }} <# } #> - + post_password ) ) { /** This filter is documented in wp-includes/post-template.php */ - $protected_title_format = apply_filters( 'protected_title_format', __( 'Protected: %s', 'customize-posts' ), $post ); + $protected_title_format = apply_filters( + 'protected_title_format', + /* translators: %s is post title */ + __( 'Protected: %s', 'customize-posts' ), + $post + ); $rendered = sprintf( $protected_title_format, $rendered ); } elseif ( isset( $post->post_status ) && 'private' === $post->post_status ) { /** This filter is documented in wp-includes/post-template.php */ - $private_title_format = apply_filters( 'private_title_format', __( 'Private: %s', 'customize-posts' ), $post ); + $private_title_format = apply_filters( + 'private_title_format', + /* translators: %s is post title */ + __( 'Private: %s', 'customize-posts' ), + $post + ); $rendered = sprintf( $private_title_format, $rendered ); } diff --git a/php/class-wp-customize-post-setting.php b/php/class-wp-customize-post-setting.php index 2638b57..e6b026d 100644 --- a/php/class-wp-customize-post-setting.php +++ b/php/class-wp-customize-post-setting.php @@ -303,6 +303,7 @@ public function sanitize( $post_data ) { if ( $locked_user ) { $user = get_user_by( 'ID', $locked_user ); $error_message = sprintf( + /* translators: %s is user display name */ __( 'Post is currently locked by %s.', 'customize-posts' ), $user ? $user->display_name : __( '(unknown user)', 'customize-posts' ) ); @@ -323,6 +324,7 @@ public function sanitize( $post_data ) { if ( $is_update_conflict ) { $user = get_user_by( 'ID', get_post_meta( $this->post_id, '_edit_last', true ) ); $error_message = sprintf( + /* translators: %s is user display name */ __( 'Conflict due to concurrent post update by %s.', 'customize-posts' ), $user ? $user->display_name : __( '(unknown user)', 'customize-posts' ) ); diff --git a/php/class-wp-customize-post-status-control.php b/php/class-wp-customize-post-status-control.php index e7e08ba..1f88526 100644 --- a/php/class-wp-customize-post-status-control.php +++ b/php/class-wp-customize-post-status-control.php @@ -60,7 +60,7 @@ protected function content_template() { $data = $this->json(); ?> <# - _.defaults( data, ); + _.defaults( data, ); data.input_id = 'input-' + String( Math.random() ); #> @@ -85,8 +85,8 @@ protected function content_template() { <# } ); #> - - + + - - - - @@ -1050,6 +1065,18 @@ public function render_templates() { + + +