From 06a863efcab8c60e46015d0354c34deca77f48c8 Mon Sep 17 00:00:00 2001 From: Adam Boro Date: Thu, 10 Dec 2020 09:35:27 +0100 Subject: [PATCH 1/7] feat: add above header placement option (#292) Part of #260 --- includes/class-newspack-popups-inserter.php | 64 ++++++++++++---- includes/class-newspack-popups-model.php | 84 +++++++++++++++------ src/editor/ColorsSidebar.js | 6 +- src/editor/FrequencySidebar.js | 4 +- src/editor/Sidebar.js | 60 ++++++++------- src/editor/StatusSidebar.js | 7 +- src/editor/utils.js | 7 ++ 7 files changed, 158 insertions(+), 74 deletions(-) diff --git a/includes/class-newspack-popups-inserter.php b/includes/class-newspack-popups-inserter.php index d27d9724..75ea6ad5 100755 --- a/includes/class-newspack-popups-inserter.php +++ b/includes/class-newspack-popups-inserter.php @@ -30,9 +30,10 @@ final class Newspack_Popups_Inserter { /** * Retrieve the appropriate popups for the current post. * + * @param bool $skip_above_header Skip above header placement popups. * @return array Popup objects. */ - public static function popups_for_post() { + public static function popups_for_post( $skip_above_header = false ) { // Inject campaigns only in posts, pages, and CPTs that explicitly opt in. if ( ! in_array( get_post_type(), @@ -53,8 +54,19 @@ public static function popups_for_post() { return [ Newspack_Popups_Model::retrieve_preview_popup( Newspack_Popups::previewed_popup_id() ) ]; } - // 1. Get all inline popups. + // Campaigns disabled for this page. + if ( self::assess_has_disabled_popups() ) { + return []; + } + + // 1. Get all inline, above header popups. $popups_to_maybe_display = Newspack_Popups_Model::retrieve_inline_popups(); + if ( false === $skip_above_header ) { + $popups_to_maybe_display = array_merge( + $popups_to_maybe_display, + Newspack_Popups_Model::retrieve_above_header_popups() + ); + } // 2. Get the overlay popup/s. There can be only one displayed, unless in test mode. @@ -80,8 +92,8 @@ public static function popups_for_post() { $found_popup = Newspack_Popups_Model::retrieve_popup_by_id( $sitewide_default ); if ( $found_popup && - // Prevent inline sitewide default from being added - all inline popups are there. - 'inline' !== $found_popup['options']['placement'] + // Prevent non-overlay sitewide default from being added. + Newspack_Popups_Model::is_overlay( $found_popup ) ) { array_push( $popups_to_maybe_display, @@ -96,7 +108,7 @@ public static function popups_for_post() { $popups_to_maybe_display_deduped = array_filter( $popups_to_maybe_display, function ( $campaign ) use ( &$has_overlay ) { - if ( 'inline' !== $campaign['options']['placement'] ) { + if ( Newspack_Popups_Model::is_overlay( $campaign ) ) { if ( $has_overlay ) { return false; } else { @@ -129,6 +141,7 @@ public function __construct() { add_action( 'after_header', [ $this, 'insert_popups_after_header' ] ); // This is a Newspack theme hook. When used with other themes, popups won't be inserted on archive pages. add_action( 'wp_head', [ $this, 'insert_popups_amp_access' ] ); add_action( 'wp_head', [ $this, 'register_amp_scripts' ] ); + add_action( 'before_header', [ $this, 'inject_above_header_popup' ] ); // Always enqueue scripts, since this plugin's scripts are handling pageview sending via GTAG. add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); @@ -173,9 +186,8 @@ function() { * Process popups and insert into post and page content if needed. * * @param string $content The content of the post. - * @param bool $enqueue_assets Whether assets should be enqueued. */ - public static function insert_popups_in_content( $content = '', $enqueue_assets = true ) { + public static function insert_popups_in_content( $content = '' ) { // Avoid duplicate execution. if ( true === self::$the_content_has_rendered ) { return $content; @@ -201,11 +213,6 @@ public static function insert_popups_in_content( $content = '', $enqueue_assets return $content; } - // Campaigns disabled for this page. - if ( self::assess_has_disabled_popups() ) { - return $content; - } - // If the current post is a Campaign, ignore. if ( Newspack_Popups::NEWSPACK_PLUGINS_CPT == get_post_type() ) { return $content; @@ -239,16 +246,21 @@ public static function insert_popups_in_content( $content = '', $enqueue_assets $inline_popups = []; $overlay_popups = []; foreach ( $popups as $popup ) { - if ( 'inline' === $popup['options']['placement'] ) { + if ( Newspack_Popups_Model::is_inline( $popup ) ) { $percentage = intval( $popup['options']['trigger_scroll_progress'] ) / 100; $popup['precise_position'] = $total_length * $percentage; $popup['is_inserted'] = false; $inline_popups[] = $popup; - } else { + } elseif ( Newspack_Popups_Model::is_overlay( $popup ) ) { $overlay_popups[] = $popup; } } + // Return early if there are no popups to insert. This can happen if e.g. the only popup is an above header one. + if ( empty( $inline_popups ) && empty( $overlay_popups ) ) { + return $content; + } + // 2. Iterate overall blocks and insert inline campaigns. $pos = 0; $output = ''; @@ -292,7 +304,7 @@ public static function insert_popups_after_header() { return; } - $popups = self::popups_for_post(); + $popups = self::popups_for_post( true ); if ( ! empty( $popups ) ) { foreach ( $popups as $popup ) { @@ -330,6 +342,26 @@ public static function enqueue_scripts() { \wp_enqueue_style( 'newspack-popups-view' ); } + /** + * The popup shortcode function. + */ + public static function inject_above_header_popup() { + $previewed_popup_id = Newspack_Popups::previewed_popup_id(); + $popups = []; + if ( $previewed_popup_id ) { + $popups = [ Newspack_Popups_Model::retrieve_preview_popup( $previewed_popup_id ) ]; + } else { + $popups = Newspack_Popups_Model::retrieve_above_header_popups(); + } + if ( ! empty( $popups ) ) { + foreach ( $popups as $popup ) { + if ( $previewed_popup_id || self::should_display( $popup ) ) { + echo Newspack_Popups_Model::generate_popup( $popup ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } + } + } + /** * The popup shortcode function. * @@ -356,7 +388,7 @@ public static function popup_shortcode( $atts = array() ) { public static function create_single_popup_access_payload( $popup ) { $popup_id_string = Newspack_Popups_Model::canonize_popup_id( esc_attr( $popup['id'] ) ); $frequency = $popup['options']['frequency']; - if ( 'inline' !== $popup['options']['placement'] && 'always' === $frequency ) { + if ( Newspack_Popups_Model::is_overlay( $popup ) && 'always' === $frequency ) { $frequency = 'once'; } return [ diff --git a/includes/class-newspack-popups-model.php b/includes/class-newspack-popups-model.php index b9ac3c65..8650cfd6 100644 --- a/includes/class-newspack-popups-model.php +++ b/includes/class-newspack-popups-model.php @@ -11,6 +11,12 @@ * API endpoints */ final class Newspack_Popups_Model { + /** + * Possible placements of overlay popups. + * + * @var array + */ + protected static $overlay_placements = [ 'top', 'bottom', 'center' ]; /** * Retrieve all Popups (first 100). @@ -31,7 +37,7 @@ public static function retrieve_popups( $include_unpublished = false ) { foreach ( $popups as &$popup ) { // UI will not allow for setting inline as sitewide default, but there may be // legacy popups from before this update. - if ( 'inline' !== $popup['options']['placement'] ) { + if ( self::is_overlay( $popup ) ) { $popup['sitewide_default'] = absint( $sitewide_default_id ) === absint( $popup['id'] ); } } @@ -57,7 +63,7 @@ public static function set_sitewide_popup( $id ) { } // Such update will not be permitted by the UI, but it's handled just to be explicit about it. - if ( 'inline' === $popup['options']['placement'] ) { + if ( self::is_inline( $popup ) ) { return new \WP_Error( 'newspack_popups_inline_sitewide', esc_html__( 'An inline Campaign cannot be a sitewide default.', 'newspack-popups' ), @@ -153,7 +159,7 @@ public static function set_popup_options( $id, $options ) { update_post_meta( $id, $key, $value ); break; case 'placement': - if ( ! in_array( $value, [ 'center', 'top', 'bottom', 'inline' ] ) ) { + if ( ! in_array( $value, array_merge( self::$overlay_placements, [ 'inline', 'above_header' ] ) ) ) { return new \WP_Error( 'newspack_popups_invalid_option_value', esc_html__( 'Invalid placement value.', 'newspack-popups' ), @@ -211,8 +217,8 @@ public static function retrieve_overlay_test_popups() { 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query [ 'key' => 'placement', - 'value' => 'inline', - 'compare' => '!=', + 'value' => self::$overlay_placements, + 'compare' => 'IN', ], [ 'key' => 'frequency', @@ -243,14 +249,32 @@ public static function retrieve_category_overlay_popup() { 'category__in' => array_column( $post_categories, 'term_id' ), 'meta_key' => 'placement', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value - 'meta_value' => 'inline', - 'meta_compare' => '!=', + 'meta_value' => self::$overlay_placements, + 'meta_compare' => 'IN', ]; $popups = self::retrieve_popups_with_query( new WP_Query( $args ) ); return count( $popups ) > 0 ? $popups[0] : null; } + /** + * Retrieve above header popups. + * + * @return array Popup objects. + */ + public static function retrieve_above_header_popups() { + $args = [ + 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'post_status' => 'publish', + 'meta_key' => 'placement', + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value + 'meta_value' => 'above_header', + 'meta_compare' => '=', + ]; + + return self::retrieve_popups_with_query( new WP_Query( $args ) ); + } + /** * Retrieve popup preview CPT post. * @@ -386,18 +410,21 @@ public static function create_popup_object( $campaign_post, $include_categories return $popup; } - switch ( $popup['options']['trigger_type'] ) { - case 'scroll': - $popup['options']['trigger_delay'] = 0; - break; - case 'time': - default: - $popup['options']['trigger_scroll_progress'] = 0; - break; - }; - if ( ! in_array( $popup['options']['placement'], [ 'top', 'bottom' ], true ) ) { - $popup['options']['placement'] = 'center'; + if ( self::is_overlay( $popup ) ) { + switch ( $popup['options']['trigger_type'] ) { + case 'scroll': + $popup['options']['trigger_delay'] = 0; + break; + case 'time': + default: + $popup['options']['trigger_scroll_progress'] = 0; + break; + }; + if ( ! in_array( $popup['options']['placement'], [ 'top', 'bottom' ], true ) ) { + $popup['options']['placement'] = 'center'; + } } + return $popup; } @@ -438,9 +465,25 @@ protected static function get_delay( $popup ) { * @return boolean True if it is an inline popup. */ public static function is_inline( $popup ) { + if ( ! isset( $popup['options'], $popup['options']['placement'] ) ) { + return false; + } return 'inline' === $popup['options']['placement']; } + /** + * Is it an overlay popup or not. + * + * @param object $popup The popup object. + * @return boolean True if it is an overlay popup. + */ + public static function is_overlay( $popup ) { + if ( ! isset( $popup['options'], $popup['options']['placement'] ) ) { + return false; + } + return in_array( $popup['options']['placement'], self::$overlay_placements, true ); + } + /** * Does the popup have newsletter prompt? * @@ -557,7 +600,7 @@ protected static function get_analytics_events( $popup, $body, $element_id ) { $has_link = preg_match( '/ { - const isInline = 'inline' === placement; - // On component mount. useEffect(() => { updateEditorColors( background_color ); @@ -36,7 +34,7 @@ const ColorsSidebar = ( { onChange={ value => onMetaFieldChange( 'background_color', value || '#FFFFFF' ) } label={ __( 'Background Color' ) } /> - { ! isInline && ( + { isOverlay && ( { +const FrequencySidebar = ( { frequency, onMetaFieldChange, isOverlay, utm_suppression } ) => { return ( diff --git a/src/editor/Sidebar.js b/src/editor/Sidebar.js index 956b1596..8e3dc849 100644 --- a/src/editor/Sidebar.js +++ b/src/editor/Sidebar.js @@ -17,12 +17,12 @@ const Sidebar = ( { trigger_scroll_progress, trigger_delay, trigger_type, + isOverlay, + isInlinePlacement, } ) => { - const isInline = 'inline' === placement; - const updatePlacement = value => { onMetaFieldChange( 'placement', value ); - if ( value !== 'inline' && frequency === 'always' ) { + if ( ! isInlinePlacement( value ) && frequency === 'always' ) { onMetaFieldChange( 'frequency', 'once' ); } }; @@ -31,32 +31,33 @@ const Sidebar = ( { { - if ( value ) { - return updatePlacement( 'inline' ); - } - updatePlacement( 'center' ); - } } + checked={ ! isOverlay } + onChange={ value => updatePlacement( value ? 'inline' : 'center' ) } /> - onMetaFieldChange( 'display_title', value ) } + - { ! isInline && ( + { isOverlay && ( - ) } - { isInline && ( + { placement === 'inline' && ( ) } + onMetaFieldChange( 'display_title', value ) } + /> ); }; diff --git a/src/editor/StatusSidebar.js b/src/editor/StatusSidebar.js index fdf1c541..94620bb6 100644 --- a/src/editor/StatusSidebar.js +++ b/src/editor/StatusSidebar.js @@ -15,12 +15,11 @@ const StatusSidebar = ( { frequency, newspack_popups_is_sitewide_default, onMetaFieldChange, - placement, + isOverlay, removeNotice, onSitewideDefaultChange, } ) => { const isTest = 'test' === frequency; - const isInline = 'inline' === placement; const createTestNotice = () => { createNotice( @@ -62,11 +61,11 @@ const StatusSidebar = ( { onMetaFieldChange( 'frequency', 'once' ); } } /> - { ! isInline && ( + { isOverlay && ( onSitewideDefaultChange( value ) } /> ) } diff --git a/src/editor/utils.js b/src/editor/utils.js index 20018a87..fbefdc61 100644 --- a/src/editor/utils.js +++ b/src/editor/utils.js @@ -21,6 +21,11 @@ export const optionsFieldsSelector = select => { utm_suppression, selected_segment_id, } = meta || {}; + + const isInlinePlacement = placementValue => + [ 'inline', 'above_header' ].indexOf( placementValue ) >= 0; + const isOverlay = ! isInlinePlacement( placement ); + return { background_color, dismiss_text, @@ -38,6 +43,8 @@ export const optionsFieldsSelector = select => { trigger_type, utm_suppression, selected_segment_id, + isInlinePlacement, + isOverlay, }; }; From d2c473bc3f610953183e8abd319edbea1133dbad Mon Sep 17 00:00:00 2001 From: Adam Boro Date: Thu, 10 Dec 2020 11:06:04 +0100 Subject: [PATCH 2/7] fix: insert time-triggered overlay campaigns above header (#297) Closes #4 --- includes/class-newspack-popups-inserter.php | 61 ++++++-------------- includes/class-newspack-popups-model.php | 64 +++++++++++++-------- tests/test-insertion.php | 9 ++- 3 files changed, 66 insertions(+), 68 deletions(-) diff --git a/includes/class-newspack-popups-inserter.php b/includes/class-newspack-popups-inserter.php index 75ea6ad5..58de6a95 100755 --- a/includes/class-newspack-popups-inserter.php +++ b/includes/class-newspack-popups-inserter.php @@ -30,10 +30,9 @@ final class Newspack_Popups_Inserter { /** * Retrieve the appropriate popups for the current post. * - * @param bool $skip_above_header Skip above header placement popups. * @return array Popup objects. */ - public static function popups_for_post( $skip_above_header = false ) { + public static function popups_for_post() { // Inject campaigns only in posts, pages, and CPTs that explicitly opt in. if ( ! in_array( get_post_type(), @@ -59,14 +58,8 @@ public static function popups_for_post( $skip_above_header = false ) { return []; } - // 1. Get all inline, above header popups. + // 1. Get all inline popups. $popups_to_maybe_display = Newspack_Popups_Model::retrieve_inline_popups(); - if ( false === $skip_above_header ) { - $popups_to_maybe_display = array_merge( - $popups_to_maybe_display, - Newspack_Popups_Model::retrieve_above_header_popups() - ); - } // 2. Get the overlay popup/s. There can be only one displayed, unless in test mode. @@ -120,16 +113,10 @@ function ( $campaign ) use ( &$has_overlay ) { } ); - $popups_to_display = array_filter( + return array_filter( $popups_to_maybe_display_deduped, [ __CLASS__, 'should_display' ] ); - - if ( ! empty( $popups_to_display ) ) { - return $popups_to_display; - } - - return []; } /** @@ -141,7 +128,7 @@ public function __construct() { add_action( 'after_header', [ $this, 'insert_popups_after_header' ] ); // This is a Newspack theme hook. When used with other themes, popups won't be inserted on archive pages. add_action( 'wp_head', [ $this, 'insert_popups_amp_access' ] ); add_action( 'wp_head', [ $this, 'register_amp_scripts' ] ); - add_action( 'before_header', [ $this, 'inject_above_header_popup' ] ); + add_action( 'before_header', [ $this, 'insert_before_header' ] ); // Always enqueue scripts, since this plugin's scripts are handling pageview sending via GTAG. add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); @@ -224,7 +211,7 @@ public static function insert_popups_in_content( $content = '' ) { return $content; } - $popups = self::popups_for_post(); + $popups = array_filter( self::popups_for_post(), [ 'Newspack_Popups_Model', 'should_be_inserted_in_page_content' ] ); if ( empty( $popups ) ) { return $content; @@ -303,13 +290,19 @@ public static function insert_popups_after_header() { if ( is_singular() ) { return; } + $popups = array_filter( self::popups_for_post(), [ 'Newspack_Popups_Model', 'should_be_inserted_in_page_content' ] ); + foreach ( $popups as $popup ) { + echo Newspack_Popups_Model::generate_popup( $popup ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } - $popups = self::popups_for_post( true ); - - if ( ! empty( $popups ) ) { - foreach ( $popups as $popup ) { - echo Newspack_Popups_Model::generate_popup( $popup ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - } + /** + * Insert popups markup before header. + */ + public static function insert_before_header() { + $before_header_popups = array_filter( self::popups_for_post(), [ 'Newspack_Popups_Model', 'should_be_inserted_above_page_header' ] ); + foreach ( $before_header_popups as $popup ) { + echo Newspack_Popups_Model::generate_popup( $popup ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } } @@ -342,26 +335,6 @@ public static function enqueue_scripts() { \wp_enqueue_style( 'newspack-popups-view' ); } - /** - * The popup shortcode function. - */ - public static function inject_above_header_popup() { - $previewed_popup_id = Newspack_Popups::previewed_popup_id(); - $popups = []; - if ( $previewed_popup_id ) { - $popups = [ Newspack_Popups_Model::retrieve_preview_popup( $previewed_popup_id ) ]; - } else { - $popups = Newspack_Popups_Model::retrieve_above_header_popups(); - } - if ( ! empty( $popups ) ) { - foreach ( $popups as $popup ) { - if ( $previewed_popup_id || self::should_display( $popup ) ) { - echo Newspack_Popups_Model::generate_popup( $popup ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - } - } - } - } - /** * The popup shortcode function. * diff --git a/includes/class-newspack-popups-model.php b/includes/class-newspack-popups-model.php index 8650cfd6..4a6498f0 100644 --- a/includes/class-newspack-popups-model.php +++ b/includes/class-newspack-popups-model.php @@ -18,6 +18,13 @@ final class Newspack_Popups_Model { */ protected static $overlay_placements = [ 'top', 'bottom', 'center' ]; + /** + * Possible placements of inline popups. + * + * @var array + */ + protected static $inline_placements = [ 'inline', 'above_header' ]; + /** * Retrieve all Popups (first 100). * @@ -159,7 +166,7 @@ public static function set_popup_options( $id, $options ) { update_post_meta( $id, $key, $value ); break; case 'placement': - if ( ! in_array( $value, array_merge( self::$overlay_placements, [ 'inline', 'above_header' ] ) ) ) { + if ( ! in_array( $value, array_merge( self::$overlay_placements, self::$inline_placements ) ) ) { return new \WP_Error( 'newspack_popups_invalid_option_value', esc_html__( 'Invalid placement value.', 'newspack-popups' ), @@ -171,6 +178,8 @@ public static function set_popup_options( $id, $options ) { } update_post_meta( $id, $key, $value ); break; + case 'trigger_type': + case 'trigger_scroll_progress': case 'utm_suppression': case 'selected_segment_id': update_post_meta( $id, $key, esc_attr( $value ) ); @@ -195,11 +204,12 @@ public static function set_popup_options( $id, $options ) { */ public static function retrieve_inline_popups() { $args = [ - 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, - 'post_status' => 'publish', - 'meta_key' => 'placement', + 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'post_status' => 'publish', + 'meta_key' => 'placement', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value - 'meta_value' => 'inline', + 'meta_value' => self::$inline_placements, + 'meta_compare' => 'IN', ]; return self::retrieve_popups_with_query( new WP_Query( $args ) ); @@ -257,24 +267,6 @@ public static function retrieve_category_overlay_popup() { return count( $popups ) > 0 ? $popups[0] : null; } - /** - * Retrieve above header popups. - * - * @return array Popup objects. - */ - public static function retrieve_above_header_popups() { - $args = [ - 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, - 'post_status' => 'publish', - 'meta_key' => 'placement', - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value - 'meta_value' => 'above_header', - 'meta_compare' => '=', - ]; - - return self::retrieve_popups_with_query( new WP_Query( $args ) ); - } - /** * Retrieve popup preview CPT post. * @@ -471,6 +463,32 @@ public static function is_inline( $popup ) { return 'inline' === $popup['options']['placement']; } + /** + * Get popups which should be inserted above page header. + * + * @param object $popup The popup object. + * @return boolean True if the popup should be inserted above page header. + */ + public static function should_be_inserted_above_page_header( $popup ) { + if ( self::is_inline( $popup ) ) { + return 'above_header' === $popup['options']['placement']; + } else { + // Insert time-triggered overlay popups above the header, this way they will be + // visible before scrolling below the fold. + return 'time' === $popup['options']['trigger_type']; + } + } + + /** + * Get popups which should be inserted in page content. + * + * @param object $popup The popup object. + * @return boolean True if the popup should be inserted in page content. + */ + public static function should_be_inserted_in_page_content( $popup ) { + return self::should_be_inserted_above_page_header( $popup ) === false; + } + /** * Is it an overlay popup or not. * diff --git a/tests/test-insertion.php b/tests/test-insertion.php index 2e22363f..ef8bbdd9 100755 --- a/tests/test-insertion.php +++ b/tests/test-insertion.php @@ -29,7 +29,14 @@ public function setUp() { // phpcs:ignore Squiz.Commenting.FunctionComment.Missi // Set the popup as sitewide default. Newspack_Popups_Model::set_sitewide_popup( self::$popup_id ); // Set popup frequency from default 'test'. - Newspack_Popups_Model::set_popup_options( self::$popup_id, [ 'frequency' => 'once' ] ); + Newspack_Popups_Model::set_popup_options( + self::$popup_id, + [ + 'frequency' => 'once', + 'trigger_type' => 'scroll', + 'trigger_scroll_progress' => 0, + ] + ); // Reset internal duplicate-prevention. Newspack_Popups_Inserter::$the_content_has_rendered = false; } From de904f87b1aac8baf6aaa00493edd98514527a72 Mon Sep 17 00:00:00 2001 From: Jefferson Rabb Date: Thu, 10 Dec 2020 11:02:52 -0500 Subject: [PATCH 3/7] Feat/campaigns taxonomy (#343) * fix: longstanding typo in cpt constant * feat: campaign groups taxonomy * fix: more typo corrections --- includes/class-newspack-popups-inserter.php | 2 +- includes/class-newspack-popups-model.php | 10 ++-- includes/class-newspack-popups-settings.php | 4 +- includes/class-newspack-popups.php | 65 +++++++++++++++------ tests/test-api.php | 2 +- tests/test-insertion.php | 2 +- tests/test-model.php | 2 +- 7 files changed, 57 insertions(+), 30 deletions(-) diff --git a/includes/class-newspack-popups-inserter.php b/includes/class-newspack-popups-inserter.php index 58de6a95..af460ac6 100755 --- a/includes/class-newspack-popups-inserter.php +++ b/includes/class-newspack-popups-inserter.php @@ -201,7 +201,7 @@ public static function insert_popups_in_content( $content = '' ) { } // If the current post is a Campaign, ignore. - if ( Newspack_Popups::NEWSPACK_PLUGINS_CPT == get_post_type() ) { + if ( Newspack_Popups::NEWSPACK_POPUPS_CPT == get_post_type() ) { return $content; } diff --git a/includes/class-newspack-popups-model.php b/includes/class-newspack-popups-model.php index 4a6498f0..43b1cafa 100644 --- a/includes/class-newspack-popups-model.php +++ b/includes/class-newspack-popups-model.php @@ -33,7 +33,7 @@ final class Newspack_Popups_Model { */ public static function retrieve_popups( $include_unpublished = false ) { $args = [ - 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'post_type' => Newspack_Popups::NEWSPACK_POPUPS_CPT, 'post_status' => $include_unpublished ? [ 'publish', 'draft' ] : 'publish', 'posts_per_page' => 100, ]; @@ -204,7 +204,7 @@ public static function set_popup_options( $id, $options ) { */ public static function retrieve_inline_popups() { $args = [ - 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'post_type' => Newspack_Popups::NEWSPACK_POPUPS_CPT, 'post_status' => 'publish', 'meta_key' => 'placement', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value @@ -222,7 +222,7 @@ public static function retrieve_inline_popups() { */ public static function retrieve_overlay_test_popups() { $args = [ - 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'post_type' => Newspack_Popups::NEWSPACK_POPUPS_CPT, 'post_status' => 'publish', 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query [ @@ -253,7 +253,7 @@ public static function retrieve_category_overlay_popup() { } $args = [ - 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'post_type' => Newspack_Popups::NEWSPACK_POPUPS_CPT, 'posts_per_page' => 1, 'post_status' => 'publish', 'category__in' => array_column( $post_categories, 'term_id' ), @@ -309,7 +309,7 @@ public static function retrieve_preview_popup( $post_id ) { */ public static function retrieve_popup_by_id( $post_id, $include_drafts = false ) { $args = [ - 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'post_type' => Newspack_Popups::NEWSPACK_POPUPS_CPT, 'posts_per_page' => 1, 'p' => $post_id, ]; diff --git a/includes/class-newspack-popups-settings.php b/includes/class-newspack-popups-settings.php index 5f5c9fab..09986c57 100644 --- a/includes/class-newspack-popups-settings.php +++ b/includes/class-newspack-popups-settings.php @@ -26,7 +26,7 @@ public static function init() { */ public static function add_plugin_page() { add_submenu_page( - 'edit.php?post_type=' . Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'edit.php?post_type=' . Newspack_Popups::NEWSPACK_POPUPS_CPT, __( 'Campaigns Settings', 'newspack-popups' ), __( 'Settings', 'newspack-popups' ), 'manage_options', @@ -137,7 +137,7 @@ public static function is_non_interactive() { public static function admin_enqueue_scripts() { $screen = get_current_screen(); - if ( Newspack_Popups::NEWSPACK_PLUGINS_CPT . '_page_' . self::NEWSPACK_POPUPS_SETTINGS_PAGE !== $screen->base ) { + if ( Newspack_Popups::NEWSPACK_POPUPS_CPT . '_page_' . self::NEWSPACK_POPUPS_SETTINGS_PAGE !== $screen->base ) { return; } diff --git a/includes/class-newspack-popups.php b/includes/class-newspack-popups.php index 3f764d24..50671395 100644 --- a/includes/class-newspack-popups.php +++ b/includes/class-newspack-popups.php @@ -12,8 +12,9 @@ */ final class Newspack_Popups { - const NEWSPACK_PLUGINS_CPT = 'newspack_popups_cpt'; + const NEWSPACK_POPUPS_CPT = 'newspack_popups_cpt'; const NEWSPACK_POPUPS_SITEWIDE_DEFAULT = 'newspack_popups_sitewide_default'; + const NEWSPACK_POPUPS_TAXONOMY = 'newspack_popups_taxonomy'; const NEWSPACK_POPUP_PREVIEW_QUERY_PARAM = 'newspack_popups_preview_id'; @@ -48,10 +49,11 @@ public function __construct() { add_action( 'admin_notices', [ __CLASS__, 'api_config_missing_notice' ] ); add_action( 'init', [ __CLASS__, 'register_cpt' ] ); add_action( 'init', [ __CLASS__, 'register_meta' ] ); + add_action( 'init', [ __CLASS__, 'register_taxonomy' ] ); add_action( 'enqueue_block_editor_assets', [ __CLASS__, 'enqueue_block_editor_assets' ] ); add_filter( 'display_post_states', [ __CLASS__, 'display_post_states' ], 10, 2 ); add_action( 'rest_api_init', [ __CLASS__, 'rest_api_init' ] ); - add_action( 'save_post_' . self::NEWSPACK_PLUGINS_CPT, [ __CLASS__, 'popup_default_fields' ], 10, 3 ); + add_action( 'save_post_' . self::NEWSPACK_POPUPS_CPT, [ __CLASS__, 'popup_default_fields' ], 10, 3 ); if ( filter_input( INPUT_GET, 'newspack_popups_preview_id', FILTER_SANITIZE_STRING ) ) { add_filter( 'show_admin_bar', [ __CLASS__, 'hide_admin_bar_for_preview' ], 10, 2 ); // phpcs:ignore WordPressVIPMinimum.UserExperience.AdminBarRemoval.RemovalDetected @@ -96,7 +98,7 @@ public static function register_cpt() { 'taxonomies' => [ 'category', 'post_tag' ], 'menu_icon' => 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSIjYTBhNWFhIiBkPSJNMTEuOTkgMTguNTRsLTcuMzctNS43M0wzIDE0LjA3bDkgNyA5LTctMS42My0xLjI3LTcuMzggNS43NHpNMTIgMTZsNy4zNi01LjczTDIxIDlsLTktNy05IDcgMS42MyAxLjI3TDEyIDE2eiIvPjwvc3ZnPgo=', ]; - \register_post_type( self::NEWSPACK_PLUGINS_CPT, $cpt_args ); + \register_post_type( self::NEWSPACK_POPUPS_CPT, $cpt_args ); } /** @@ -107,7 +109,7 @@ public static function register_meta() { 'post', 'trigger_type', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'string', 'single' => true, @@ -118,7 +120,7 @@ public static function register_meta() { 'post', 'trigger_scroll_progress', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'integer', 'single' => true, @@ -129,7 +131,7 @@ public static function register_meta() { 'post', 'trigger_delay', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'integer', 'single' => true, @@ -141,7 +143,7 @@ public static function register_meta() { 'post', 'frequency', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'string', 'single' => true, @@ -153,7 +155,7 @@ public static function register_meta() { 'post', 'placement', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'string', 'single' => true, @@ -165,7 +167,7 @@ public static function register_meta() { 'post', 'utm_suppression', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'string', 'single' => true, @@ -177,7 +179,7 @@ public static function register_meta() { 'post', 'background_color', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'string', 'single' => true, @@ -189,7 +191,7 @@ public static function register_meta() { 'post', 'overlay_color', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'string', 'single' => true, @@ -201,7 +203,7 @@ public static function register_meta() { 'post', 'overlay_opacity', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'integer', 'single' => true, @@ -213,7 +215,7 @@ public static function register_meta() { 'post', 'dismiss_text', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'string', 'single' => true, @@ -225,7 +227,7 @@ public static function register_meta() { 'post', 'dismiss_text_alignment', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'string', 'single' => true, @@ -237,7 +239,7 @@ public static function register_meta() { 'post', 'display_title', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'boolean', 'single' => true, @@ -249,7 +251,7 @@ public static function register_meta() { 'post', 'selected_segment_id', [ - 'object_subtype' => self::NEWSPACK_PLUGINS_CPT, + 'object_subtype' => self::NEWSPACK_POPUPS_CPT, 'show_in_rest' => true, 'type' => 'string', 'single' => true, @@ -270,6 +272,31 @@ public static function register_meta() { ); } + /** + * Register Campaigns taxonomy. + */ + public static function register_taxonomy() { + $taxonomy_args = [ + 'labels' => [ + 'name' => __( 'Campaign Groups', 'newspack-popups' ), + 'singular_name' => __( 'Campaign Group', 'newspack-popups' ), + 'add_new_item' => __( 'Add Campaign Group', 'newspack-popups' ), + ], + 'hierarchical' => false, + 'public' => false, + 'rewrite' => false, // phpcs:ignore Squiz.PHP.CommentedOutCode.Found [ 'hierarchical' => true, 'slug' => $prefix . '/category' ] + 'show_in_menu' => false, + 'show_in_rest' => true, + 'show_tagcloud' => false, + 'show_ui' => true, + ]; + + register_taxonomy( self::NEWSPACK_POPUPS_TAXONOMY, [ self::NEWSPACK_POPUPS_CPT ], $taxonomy_args ); + + // Better safe than sorry: https://developer.wordpress.org/reference/functions/register_taxonomy/#more-information. + register_taxonomy_for_object_type( self::NEWSPACK_POPUPS_TAXONOMY, [ self::NEWSPACK_POPUPS_CPT ] ); + } + /** * Get preview post permalink. */ @@ -304,7 +331,7 @@ public static function preview_post_permalink() { public static function enqueue_block_editor_assets() { $screen = get_current_screen(); - if ( self::NEWSPACK_PLUGINS_CPT !== $screen->post_type ) { + if ( self::NEWSPACK_POPUPS_CPT !== $screen->post_type ) { if ( 'page' !== $screen->post_type || 'post' !== $screen->post_type ) { // Script for global settings. \wp_enqueue_script( @@ -350,7 +377,7 @@ public static function enqueue_block_editor_assets() { * @param WP_Post $post The current post object. */ public static function display_post_states( $post_states, $post ) { - if ( self::NEWSPACK_PLUGINS_CPT !== $post->post_type ) { + if ( self::NEWSPACK_POPUPS_CPT !== $post->post_type ) { return $post_states; } $post_status_object = get_post_status_object( $post->post_status ); @@ -398,7 +425,7 @@ public static function previewed_popup_id( $url = null ) { */ public static function rest_api_init() { register_rest_field( - [ self::NEWSPACK_PLUGINS_CPT ], + [ self::NEWSPACK_POPUPS_CPT ], 'newspack_popups_is_sitewide_default', [ 'get_callback' => function( $post ) { diff --git a/tests/test-api.php b/tests/test-api.php index 7b481177..0e1363e7 100644 --- a/tests/test-api.php +++ b/tests/test-api.php @@ -63,7 +63,7 @@ public static function wpSetUpBeforeClass() { // phpcs:ignore Squiz.Commenting.F public static function create_test_popup( $options, $post_content = 'Faucibus placerat senectus metus molestie varius tincidunt.' ) { // phpcs:ignore Squiz.Commenting.FunctionComment.Missing $popup_id = self::factory()->post->create( [ - 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'post_type' => Newspack_Popups::NEWSPACK_POPUPS_CPT, 'post_title' => 'Platea fames', 'post_content' => $post_content, ] diff --git a/tests/test-insertion.php b/tests/test-insertion.php index ef8bbdd9..73f77059 100755 --- a/tests/test-insertion.php +++ b/tests/test-insertion.php @@ -21,7 +21,7 @@ public function setUp() { // phpcs:ignore Squiz.Commenting.FunctionComment.Missi ); self::$popup_id = self::factory()->post->create( [ - 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'post_type' => Newspack_Popups::NEWSPACK_POPUPS_CPT, 'post_title' => 'Platea fames', 'post_content' => self::$popup_content, ] diff --git a/tests/test-model.php b/tests/test-model.php index 17e1e892..53892590 100644 --- a/tests/test-model.php +++ b/tests/test-model.php @@ -14,7 +14,7 @@ class ModelTest extends WP_UnitTestCase { public static function wpSetUpBeforeClass() { // phpcs:ignore Squiz.Commenting.FunctionComment.Missing self::$popup_id = self::factory()->post->create( [ - 'post_type' => Newspack_Popups::NEWSPACK_PLUGINS_CPT, + 'post_type' => Newspack_Popups::NEWSPACK_POPUPS_CPT, 'post_title' => 'Platea fames', 'post_content' => 'Faucibus placerat senectus.', ] From fa7dc05649f9fcbf66cc95b51cafc34acb1ad8df Mon Sep 17 00:00:00 2001 From: Derrick Koo Date: Fri, 11 Dec 2020 10:11:29 -0700 Subject: [PATCH 4/7] feat: render a preview of the dismiss button in the editor (#336) * feat: render a preview of the dismiss button in the editor Uses block list filter to render a preview of the dismiss button text (and alignment) at the end of the block list in the editor. * fix: only render preview after last block * chore: remove unused module imports * feat: use DOM to render dismiss preview in the right spot The filters provided by the block editor are not sufficient to render the dismiss preview via React, so let's just use DOM for now. * fix: render preview even when Dismiss Button Settings sidebar is closed * fix: lint error (hooks must be used within a React component) --- src/editor/index.js | 7 ++-- src/editor/style.scss | 6 +++ src/editor/withDismissButtonPreview.js | 51 ++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 src/editor/withDismissButtonPreview.js diff --git a/src/editor/index.js b/src/editor/index.js index 6c478bea..26943ede 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -6,8 +6,8 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { withSelect, withDispatch } from '@wordpress/data'; import { compose } from '@wordpress/compose'; +import { withSelect, withDispatch } from '@wordpress/data'; import { registerPlugin } from '@wordpress/plugins'; import { PluginDocumentSettingPanel, PluginPostStatusInfo } from '@wordpress/edit-post'; @@ -22,6 +22,7 @@ import SegmentationSidebar from './SegmentationSidebar'; import DismissSidebar from './DismissSidebar'; import ColorsSidebar from './ColorsSidebar'; import Preview from './Preview'; +import withDismissButtonPreview from './withDismissButtonPreview'; import './style.scss'; // Action dispatchers for the sidebar components. @@ -110,14 +111,14 @@ registerPlugin( 'newspack-popups-segmentation', { } ); registerPlugin( 'newspack-popups-dismiss', { - render: () => ( + render: withDismissButtonPreview( () => ( - ), + ) ), icon: null, } ); diff --git a/src/editor/style.scss b/src/editor/style.scss index 65419e79..4112efc8 100644 --- a/src/editor/style.scss +++ b/src/editor/style.scss @@ -10,4 +10,10 @@ margin-top: 4px; } } + + &__not-interested-button-preview { + cursor: not-allowed; + font-size: 0.7em; + text-decoration: underline; + } } diff --git a/src/editor/withDismissButtonPreview.js b/src/editor/withDismissButtonPreview.js new file mode 100644 index 00000000..a79a7104 --- /dev/null +++ b/src/editor/withDismissButtonPreview.js @@ -0,0 +1,51 @@ +/** + * Higher-order component that appends a preview of the dismiss button to the block editor. + */ + +/** + * WordPress dependencies + */ +import { createHigherOrderComponent } from '@wordpress/compose'; +import { useSelect } from '@wordpress/data'; +import { useEffect } from '@wordpress/element'; + +const withDismissButtonPreview = createHigherOrderComponent( OriginalComponent => { + return props => { + const meta = useSelect( select => select( 'core/editor' ).getEditedPostAttribute( 'meta' ) ); + const { dismiss_text, dismiss_text_alignment } = meta; + + // Render a preview of the dismiss button at the end of the block content area. + useEffect(() => { + if ( ! dismiss_text ) { + return; + } + + const alignClass = 'has-text-align-' + ( dismiss_text_alignment || 'center' ); + + let dismissButtonPreview = document.querySelector( + '.newspack-popups__not-interested-button-preview' + ); + + if ( ! dismissButtonPreview ) { + const rootContainer = document.querySelector( + '.block-editor-block-list__layout.is-root-container' + ); + + if ( rootContainer ) { + dismissButtonPreview = document.createElement( 'div' ); + rootContainer.appendChild( dismissButtonPreview ); + } + } + + if ( dismissButtonPreview ) { + dismissButtonPreview.className = + 'newspack-popups__not-interested-button-preview wp-block ' + alignClass; + dismissButtonPreview.textContent = dismiss_text; + } + }, [ dismiss_text, dismiss_text_alignment ]); + + return ; + }; +} ); + +export default withDismissButtonPreview; From da4b26ae3e4b62e03ed7c22cd067e1e6f00383b6 Mon Sep 17 00:00:00 2001 From: Jefferson Rabb Date: Fri, 11 Dec 2020 14:43:38 -0500 Subject: [PATCH 5/7] feat: make campaign groups a hierarchical taxonomy (#344) --- includes/class-newspack-popups.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-newspack-popups.php b/includes/class-newspack-popups.php index 50671395..01fd6f06 100644 --- a/includes/class-newspack-popups.php +++ b/includes/class-newspack-popups.php @@ -282,7 +282,7 @@ public static function register_taxonomy() { 'singular_name' => __( 'Campaign Group', 'newspack-popups' ), 'add_new_item' => __( 'Add Campaign Group', 'newspack-popups' ), ], - 'hierarchical' => false, + 'hierarchical' => true, 'public' => false, 'rewrite' => false, // phpcs:ignore Squiz.PHP.CommentedOutCode.Found [ 'hierarchical' => true, 'slug' => $prefix . '/category' ] 'show_in_menu' => false, From ce7aa98a409d7b45a9100d5d3faa75e7c7a7b51b Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Mon, 14 Dec 2020 10:26:48 +0100 Subject: [PATCH 6/7] feat(editor): hide post visibility selector private and password protected campaigns don't apply to campaigns --- src/editor/style.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/editor/style.scss b/src/editor/style.scss index 4112efc8..edc8b96c 100644 --- a/src/editor/style.scss +++ b/src/editor/style.scss @@ -1,4 +1,5 @@ -.block-editor-post-preview__button-toggle { +.block-editor-post-preview__button-toggle, +.edit-post-post-visibility { display: none; } From 69472f342c5a58e7e6064cd87361cdb7d73c3997 Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Mon, 14 Dec 2020 11:17:04 +0100 Subject: [PATCH 7/7] fix: editor colors --- src/editor/ColorsSidebar.js | 64 +++++++++++--------------- src/editor/EditorAdditions.js | 57 +++++++++++++++++++++++ src/editor/index.js | 47 +++++++------------ src/editor/style.scss | 4 ++ src/editor/utils.js | 17 +++---- src/editor/withDismissButtonPreview.js | 51 -------------------- 6 files changed, 111 insertions(+), 129 deletions(-) create mode 100644 src/editor/EditorAdditions.js delete mode 100644 src/editor/withDismissButtonPreview.js diff --git a/src/editor/ColorsSidebar.js b/src/editor/ColorsSidebar.js index f9aeefbc..a87ca9b3 100644 --- a/src/editor/ColorsSidebar.js +++ b/src/editor/ColorsSidebar.js @@ -6,52 +6,40 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { Fragment, useEffect } from '@wordpress/element'; +import { Fragment } from '@wordpress/element'; import { RangeControl } from '@wordpress/components'; import { ColorPaletteControl } from '@wordpress/block-editor'; -/** - * Internal dependencies - */ -import { updateEditorColors } from './utils'; - const ColorsSidebar = ( { background_color, onMetaFieldChange, overlay_opacity, overlay_color, isOverlay, -} ) => { - // On component mount. - useEffect(() => { - updateEditorColors( background_color ); - }, [ background_color ]); - - return ( - - onMetaFieldChange( 'background_color', value || '#FFFFFF' ) } - label={ __( 'Background Color' ) } - /> - { isOverlay && ( - - onMetaFieldChange( 'overlay_color', value || '#000000' ) } - label={ __( 'Overlay Color' ) } - /> - onMetaFieldChange( 'overlay_opacity', value ) } - min={ 0 } - max={ 100 } - /> - - ) } - - ); -}; +} ) => ( + + onMetaFieldChange( 'background_color', value || '#FFFFFF' ) } + label={ __( 'Background Color' ) } + /> + { isOverlay && ( + + onMetaFieldChange( 'overlay_color', value || '#000000' ) } + label={ __( 'Overlay Color' ) } + /> + onMetaFieldChange( 'overlay_opacity', value ) } + min={ 0 } + max={ 100 } + /> + + ) } + +); export default ColorsSidebar; diff --git a/src/editor/EditorAdditions.js b/src/editor/EditorAdditions.js new file mode 100644 index 00000000..2e00c6bf --- /dev/null +++ b/src/editor/EditorAdditions.js @@ -0,0 +1,57 @@ +/** + * Popup-related editor changes. + */ + +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { useEffect } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { updateEditorColors } from './utils'; + +const EditorAdditions = () => { + const meta = useSelect( select => select( 'core/editor' ).getEditedPostAttribute( 'meta' ) ); + const { dismiss_text, dismiss_text_alignment, background_color } = meta; + + // Update editor colors to match popup colors. + useEffect(() => { + updateEditorColors( background_color ); + }, [ background_color ]); + + // Render a preview of the dismiss button at the end of the block content area. + useEffect(() => { + if ( ! dismiss_text ) { + return; + } + + const alignClass = 'has-text-align-' + ( dismiss_text_alignment || 'center' ); + + let dismissButtonPreview = document.querySelector( + '.newspack-popups__not-interested-button-preview' + ); + + if ( ! dismissButtonPreview ) { + const rootContainer = document.querySelector( + '.block-editor-block-list__layout.is-root-container' + ); + + if ( rootContainer ) { + dismissButtonPreview = document.createElement( 'div' ); + rootContainer.appendChild( dismissButtonPreview ); + } + } + + if ( dismissButtonPreview ) { + dismissButtonPreview.className = + 'newspack-popups__not-interested-button-preview wp-block ' + alignClass; + dismissButtonPreview.textContent = dismiss_text; + } + }, [ dismiss_text, dismiss_text_alignment ]); + return null; +}; + +export default EditorAdditions; diff --git a/src/editor/index.js b/src/editor/index.js index 26943ede..c4c6a76e 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -22,7 +22,7 @@ import SegmentationSidebar from './SegmentationSidebar'; import DismissSidebar from './DismissSidebar'; import ColorsSidebar from './ColorsSidebar'; import Preview from './Preview'; -import withDismissButtonPreview from './withDismissButtonPreview'; +import EditorAdditions from './EditorAdditions'; import './style.scss'; // Action dispatchers for the sidebar components. @@ -40,36 +40,18 @@ const mapDispatchToProps = dispatch => { }; }; -// Connect data to components. -const StatusSidebarWithData = compose( [ - withSelect( optionsFieldsSelector ), - withDispatch( mapDispatchToProps ), -] )( StatusSidebar ); - -const SidebarWithData = compose( [ +const connectData = compose( [ withSelect( optionsFieldsSelector ), withDispatch( mapDispatchToProps ), -] )( Sidebar ); +] ); -const FrequencySidebarWithData = compose( [ - withSelect( optionsFieldsSelector ), - withDispatch( mapDispatchToProps ), -] )( FrequencySidebar ); - -const SegmentationSidebarWithData = compose( [ - withSelect( optionsFieldsSelector ), - withDispatch( mapDispatchToProps ), -] )( SegmentationSidebar ); - -const DismissSidebarWithData = compose( [ - withSelect( optionsFieldsSelector ), - withDispatch( mapDispatchToProps ), -] )( DismissSidebar ); - -const ColorsSidebarWithData = compose( [ - withSelect( optionsFieldsSelector ), - withDispatch( mapDispatchToProps ), -] )( ColorsSidebar ); +// Connect data to components. +const StatusSidebarWithData = connectData( StatusSidebar ); +const SidebarWithData = connectData( Sidebar ); +const FrequencySidebarWithData = connectData( FrequencySidebar ); +const SegmentationSidebarWithData = connectData( SegmentationSidebar ); +const DismissSidebarWithData = connectData( DismissSidebar ); +const ColorsSidebarWithData = connectData( ColorsSidebar ); // Register components. registerPlugin( 'newspack-popups-status', { render: StatusSidebarWithData } ); @@ -111,14 +93,14 @@ registerPlugin( 'newspack-popups-segmentation', { } ); registerPlugin( 'newspack-popups-dismiss', { - render: withDismissButtonPreview( () => ( + render: () => ( - ) ), + ), icon: null, } ); @@ -134,6 +116,11 @@ registerPlugin( 'newspack-popups-colors', { icon: null, } ); +registerPlugin( 'newspack-popups-editor', { + render: EditorAdditions, + icon: null, +} ); + // Add a button in post status section const PluginPostStatusInfoTest = () => ( diff --git a/src/editor/style.scss b/src/editor/style.scss index edc8b96c..0938feac 100644 --- a/src/editor/style.scss +++ b/src/editor/style.scss @@ -3,6 +3,10 @@ display: none; } +.editor-post-title__input::placeholder { + color: var( --newspack-popups-editor-placeholder-color, #7d7d7d ) !important; +} + .newspack-popups { &__status-options { margin: 1rem 0; diff --git a/src/editor/utils.js b/src/editor/utils.js index fbefdc61..7b76fbd1 100644 --- a/src/editor/utils.js +++ b/src/editor/utils.js @@ -71,8 +71,8 @@ export const updateEditorColors = backgroundColor => { if ( ! backgroundColor ) { return; } - const blackColor = '#000'; - const whiteColor = '#fff'; + const blackColor = '#000000'; + const whiteColor = '#ffffff'; const backgroundColorRGB = hexToRGB( backgroundColor ); const blackRGB = hexToRGB( blackColor ); @@ -91,22 +91,19 @@ export const updateEditorColors = backgroundColor => { const foregroundColor = contrastRatio > 5 ? blackColor : whiteColor; - const editorStylesEl = document.querySelector( '.edit-post-visual-editor.editor-styles-wrapper' ); + const editorStylesEl = document.querySelector( '.editor-styles-wrapper' ); const editorPostTitleEl = document.querySelector( '.wp-block.editor-post-title__block .editor-post-title__input' ); - const editorPostTitlePlaceholderEl = document.querySelector( - '.wp-block.editor-post-title__block .editor-post-title__input::placeholder' - ); - if ( editorStylesEl ) { editorStylesEl.style.backgroundColor = backgroundColor; editorStylesEl.style.color = foregroundColor; } if ( editorPostTitleEl ) { editorPostTitleEl.style.color = foregroundColor; - } - if ( editorPostTitlePlaceholderEl ) { - editorPostTitlePlaceholderEl.style.color = foregroundColor; + editorPostTitleEl.style.setProperty( + '--newspack-popups-editor-placeholder-color', + `${ foregroundColor }80` + ); } }; diff --git a/src/editor/withDismissButtonPreview.js b/src/editor/withDismissButtonPreview.js deleted file mode 100644 index a79a7104..00000000 --- a/src/editor/withDismissButtonPreview.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Higher-order component that appends a preview of the dismiss button to the block editor. - */ - -/** - * WordPress dependencies - */ -import { createHigherOrderComponent } from '@wordpress/compose'; -import { useSelect } from '@wordpress/data'; -import { useEffect } from '@wordpress/element'; - -const withDismissButtonPreview = createHigherOrderComponent( OriginalComponent => { - return props => { - const meta = useSelect( select => select( 'core/editor' ).getEditedPostAttribute( 'meta' ) ); - const { dismiss_text, dismiss_text_alignment } = meta; - - // Render a preview of the dismiss button at the end of the block content area. - useEffect(() => { - if ( ! dismiss_text ) { - return; - } - - const alignClass = 'has-text-align-' + ( dismiss_text_alignment || 'center' ); - - let dismissButtonPreview = document.querySelector( - '.newspack-popups__not-interested-button-preview' - ); - - if ( ! dismissButtonPreview ) { - const rootContainer = document.querySelector( - '.block-editor-block-list__layout.is-root-container' - ); - - if ( rootContainer ) { - dismissButtonPreview = document.createElement( 'div' ); - rootContainer.appendChild( dismissButtonPreview ); - } - } - - if ( dismissButtonPreview ) { - dismissButtonPreview.className = - 'newspack-popups__not-interested-button-preview wp-block ' + alignClass; - dismissButtonPreview.textContent = dismiss_text; - } - }, [ dismiss_text, dismiss_text_alignment ]); - - return ; - }; -} ); - -export default withDismissButtonPreview;