-
-
Save obiPlabon/1c27460668ff41f71774e7a5ccaebc49 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global jQuery, wp */ | |
jQuery( function( $ ) { | |
var initializeAllClocks, initializeClock; | |
/** | |
* Find clocks. | |
* | |
* @param [container] Scoping element for finding clock elements. | |
* @returns {void} | |
*/ | |
initializeAllClocks = function( container ) { | |
$( container || document.body ).find( '.wpse-247251-clock' ).each( function() { | |
initializeClock( $( this ) ); | |
} ); | |
}; | |
/** | |
* Initialize clock. | |
* | |
* @param {jQuery} clockElement Clock element. | |
* @returns {void} | |
*/ | |
initializeClock = function( clockElement ) { | |
var timeoutId, populateTime; | |
if ( clockElement.data( 'initialized' ) ) { | |
return; | |
} | |
populateTime = function() { | |
clockElement.text( new Date().toString() ); | |
}; | |
timeoutId = setInterval( function() { | |
// Stop interval when element is no longer in the DOM. | |
if ( ! $.contains( document, clockElement[0] ) ) { | |
clearInterval( timeoutId ); | |
return; | |
} | |
populateTime(); | |
}, 1000 ); | |
populateTime(); | |
clockElement.data( 'initialized', true ); | |
}; | |
initializeAllClocks(); | |
// Re-initialize clocks when a partial is updated in the customizer preview. | |
if ( 'undefined' !== typeof wp && 'undefined' !== typeof wp.customize && 'undefined' !== typeof wp.customize.selectiveRefresh ) { | |
wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) { | |
initializeAllClocks( $( placement.container ) ); | |
} ); | |
} | |
} ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.widget.color-scheme-dark, | |
.widget.color-scheme-dark h2, | |
.widget.color-scheme-dark p { | |
color: white !important; | |
background: navy !important; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.widget.color-scheme-light, | |
.widget.color-scheme-light h2, | |
.widget.color-scheme-light p { | |
color: black !important; | |
background: palevioletred !important; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global jQuery, wp */ | |
jQuery( function( $ ) { | |
var initializeAllCountdowns, initializeCountdown; | |
/** | |
* Find countdowns. | |
* | |
* @param [container] Scoping element for finding countdown elements. | |
* @returns {void} | |
*/ | |
initializeAllCountdowns = function( container ) { | |
$( container || document.body ).find( '.wpse-247251-countdown' ).each( function() { | |
initializeCountdown( $( this ) ); | |
} ); | |
}; | |
/** | |
* Initialize countdown. | |
* | |
* @param {jQuery} countdownElement Countdown element. | |
* @returns {void} | |
*/ | |
initializeCountdown = function( countdownElement ) { | |
var timeoutId, populateCountdown; | |
if ( countdownElement.data( 'initialized' ) ) { | |
return; | |
} | |
populateCountdown = function() { | |
var now, newYearDate; | |
now = new Date(); | |
newYearDate = new Date( now.getFullYear() + 1, 0, 1, 0, 0, 0 ); | |
countdownElement.text( 'T-' + String( Math.floor( ( newYearDate.valueOf() - now.valueOf() ) / 1000 ) ) ); | |
}; | |
timeoutId = setInterval( function() { | |
// Stop interval when element is no longer in the DOM. | |
if ( ! $.contains( document, countdownElement[0] ) ) { | |
clearInterval( timeoutId ); | |
return; | |
} | |
populateCountdown(); | |
}, 1000 ); | |
populateCountdown(); | |
countdownElement.data( 'initialized', true ); | |
}; | |
initializeAllCountdowns(); | |
// Re-initialize countdowns when a partial is updated in the customizer preview. | |
if ( 'undefined' !== typeof wp && 'undefined' !== typeof wp.customize && 'undefined' !== typeof wp.customize.selectiveRefresh ) { | |
wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) { | |
initializeAllCountdowns( $( placement.container ) ); | |
} ); | |
} | |
} ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global wp, _ */ | |
/* exported WPSE_247251 */ | |
var WPSE_247251 = (function( api ) { | |
var component = { | |
data: { | |
enqueued_styles: {}, | |
enqueued_scripts: {} | |
} | |
}; | |
/** | |
* Init. | |
* | |
* @param {object} data Data exported from PHP. | |
* @returns {void} | |
*/ | |
component.init = function init( data ) { | |
if ( data ) { | |
_.extend( component.data, data ); | |
} | |
api.selectiveRefresh.bind( 'render-partials-response', component.handleRenderPartialsResponse ); | |
}; | |
/** | |
* Handle render-partials-response event, requesting full refresh if newly-enqueued styles/styles differ. | |
* | |
* @param {object} response Response. | |
* @returns {void} | |
*/ | |
component.handleRenderPartialsResponse = function handleRenderPartialsResponse( response ) { | |
if ( ! response.wpse_247251 ) { | |
return; | |
} | |
if ( ! _.isEqual( component.data.enqueued_styles, response.wpse_247251.enqueued_styles ) ) { | |
api.selectiveRefresh.requestFullRefresh(); | |
} | |
if ( ! _.isEqual( component.data.enqueued_scripts, response.wpse_247251.enqueued_scripts ) ) { | |
api.selectiveRefresh.requestFullRefresh(); | |
} | |
}; | |
return component; | |
})( wp.customize ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: WPSE 247251: Initiating Full Refresh when Selective Refresh Enqueues Different Styles | |
* Author: Weston Ruter, XWP | |
* Author URI: https://make.xwp.co/ | |
* Plugin URI: http://wordpress.stackexchange.com/questions/247251/how-to-mix-partial-and-full-page-refresh-in-the-same-section-of-the-customizer | |
* | |
* Copyright (c) 2016 XWP (https://make.xwp.co/) | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License, version 2 or, at | |
* your discretion, any later version, as published by the Free | |
* Software Foundation. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program; if not, write to the Free Software | |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
* | |
* @package WPSE_247251 | |
*/ | |
namespace WPSE_247251; | |
/** | |
* Class Plugin | |
*/ | |
class Plugin { | |
/** | |
* Example widget. | |
* | |
* @var Example_Widget | |
*/ | |
public $widget; | |
/** | |
* Plugin registered style handles. | |
* | |
* @var array | |
*/ | |
public $registered_style_handles = array(); | |
/** | |
* Plugin registered script handles. | |
* | |
* @var array | |
*/ | |
public $registered_script_handles = array(); | |
/** | |
* Add hooks. | |
*/ | |
function add_hooks() { | |
add_action( 'widgets_init', array( $this, 'register_widget' ) ); | |
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_dependencies' ) ); | |
add_action( 'customize_render_partials_before', array( $this, 'enqueue_selective_refresh_dependencies' ), 100 ); | |
add_filter( 'customize_render_partials_response', array( $this, 'filter_customize_render_partials_response' ) ); | |
} | |
/** | |
* Register widget. | |
*/ | |
function register_widget() { | |
$this->widget = new Example_Widget(); | |
register_widget( $this->widget ); | |
} | |
/** | |
* Enqueue dependencies. | |
*/ | |
function enqueue_dependencies() { | |
$light_color_scheme_style_handle = 'wpse-247251-color-scheme-light'; | |
$src = plugin_dir_url( __FILE__ ) . 'color-scheme-light.css'; | |
wp_register_style( $light_color_scheme_style_handle, $src ); | |
$dark_color_scheme_style_handle = 'wpse-247251-color-scheme-dark'; | |
$src = plugin_dir_url( __FILE__ ) . 'color-scheme-dark.css'; | |
wp_register_style( $dark_color_scheme_style_handle, $src ); | |
$clock_behavior_script_handle = 'wpse-247251-clock-behavior'; | |
$src = plugin_dir_url( __FILE__ ) . 'clock-behavior.js'; | |
$deps = array( 'jquery' ); | |
if ( is_customize_preview() ) { | |
$deps[] = 'customize-selective-refresh'; | |
} | |
wp_register_script( $clock_behavior_script_handle, $src, $deps ); | |
$countdown_behavior_script_handle = 'wpse-247251-countdown-behavior'; | |
$src = plugin_dir_url( __FILE__ ) . 'countdown-behavior.js'; | |
$deps = array( 'jquery' ); | |
if ( is_customize_preview() ) { | |
$deps[] = 'customize-selective-refresh'; | |
} | |
wp_register_script( $countdown_behavior_script_handle, $src, $deps ); | |
$this->registered_style_handles = array( $light_color_scheme_style_handle, $dark_color_scheme_style_handle ); | |
$this->registered_script_handles = array( $clock_behavior_script_handle, $countdown_behavior_script_handle ); | |
// Enqueue dependencies only if they are used by widgets. | |
$instances = $this->widget->get_settings(); | |
foreach ( wp_get_sidebars_widgets() as $sidebar => $sidebar_widgets ) { | |
foreach ( $sidebar_widgets as $widget_id ) { | |
if ( ! preg_match( '/^' . Example_Widget::ID_BASE . '-(?P<number>\d+)$/', $widget_id, $matches ) ) { | |
continue; | |
} | |
if ( ! isset( $instances[ $matches['number'] ] ) ) { | |
continue; | |
} | |
$instance = array_merge( $this->widget->default_instance, $instances[ $matches['number'] ] ); | |
if ( 'light' === $instance['color_scheme'] ) { | |
wp_enqueue_style( $light_color_scheme_style_handle ); | |
} elseif ( 'dark' === $instance['color_scheme'] ) { | |
wp_enqueue_style( $dark_color_scheme_style_handle ); | |
} | |
if ( 'clock' === $instance['behavior'] ) { | |
wp_enqueue_script( $clock_behavior_script_handle ); | |
} elseif ( 'countdown' === $instance['behavior'] ) { | |
wp_enqueue_script( $countdown_behavior_script_handle ); | |
} | |
} | |
} | |
// Enqueue helper script for listening to selective refresh events. | |
if ( is_customize_preview() ) { | |
$preview_handle = 'wpse-247251-customize-preview'; | |
$src = plugin_dir_url( __FILE__ ) . 'customize-preview.js'; | |
$deps = array( 'customize-selective-refresh' ); | |
wp_enqueue_script( $preview_handle, $src, $deps ); | |
// Export which widget styles specifically where enqueued. | |
wp_add_inline_script( | |
$preview_handle, | |
sprintf( 'WPSE_247251.init( %s )', wp_json_encode( $this->get_enqueued_dependencies() ) ), | |
'after' | |
); | |
} | |
} | |
/** | |
* Get enqueued dependencies. | |
* | |
* @return array Enqueued dependencies. | |
*/ | |
public function get_enqueued_dependencies() { | |
$data = array( | |
'enqueued_styles' => array(), | |
'enqueued_scripts' => array(), | |
); | |
foreach ( $this->registered_style_handles as $style_handle ) { | |
if ( wp_style_is( $style_handle, 'enqueued' ) ) { | |
$data['enqueued_styles'][ $style_handle ] = true; | |
} | |
} | |
foreach ( $this->registered_script_handles as $script_handle ) { | |
if ( wp_script_is( $script_handle, 'enqueued' ) ) { | |
$data['enqueued_styles'][ $script_handle ] = true; | |
} | |
} | |
return $data; | |
} | |
/** | |
* Enqueue scripts in selective refresh responses. | |
* | |
* Core should do this eventually, hence the conditional. See core docs | |
* for the `customize_render_partials_before` action. | |
*/ | |
function enqueue_selective_refresh_dependencies() { | |
if ( ! did_action( 'wp_enqueue_scripts' ) ) { | |
wp_enqueue_scripts(); | |
} | |
} | |
/** | |
* Export the enqueued styles in the selective refresh response. | |
* | |
* Note that core should eventually include the enqueued scripts/styles by | |
* default. See docs for the `customize_render_partials_response` filter. | |
* | |
* @param array $response Response. | |
* @return array Response. | |
*/ | |
function filter_customize_render_partials_response( $response ) { | |
$response['wpse_247251'] = $this->get_enqueued_dependencies(); | |
return $response; | |
} | |
} | |
/** | |
* Class Example_Widget | |
*/ | |
class Example_Widget extends \WP_Widget { | |
const ID_BASE = 'wpse_247251'; | |
/** | |
* Default instance. | |
* | |
* @var array | |
*/ | |
public $default_instance; | |
/** | |
* Sets up a new widget instance. | |
*/ | |
public function __construct() { | |
$widget_ops = array( | |
'classname' => 'widget_wpse_247251', | |
'description' => __( 'WPSE 247251', 'wpse-247251' ), | |
'customize_selective_refresh' => true, | |
); | |
$this->default_instance = array( | |
'title' => '', | |
'color_scheme' => 'light', | |
'behavior' => 'clock', | |
); | |
parent::__construct( self::ID_BASE, __( 'WPSE 247251', 'wpse-247251' ), $widget_ops ); | |
} | |
/** | |
* Outputs the content for the current widget. | |
* | |
* @param array $args Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'. | |
* @param array $instance Settings for the current Text widget instance. | |
*/ | |
public function widget( $args, $instance ) { | |
$instance = wp_parse_args( (array) $instance, $this->default_instance ); | |
if ( empty( $instance['title'] ) ) { | |
$instance['title'] = __( 'WPSE Example', 'wpse-247251' ); | |
} | |
/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ | |
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base ); | |
$args['before_widget'] = preg_replace( | |
'/(?<=class=")/', | |
esc_attr( 'color-scheme-' . $instance['color_scheme'] . ' ' ), | |
$args['before_widget'], | |
1 | |
); | |
echo $args['before_widget']; | |
printf( '<div class="color-scheme-%s">', esc_attr( $instance['color_scheme'] ) ); | |
echo $args['before_title'] . $title . $args['after_title']; | |
echo '<p>' . esc_html__( 'This widget demonstrates how full refresh can be invoked when selective refresh returns with different scripts or styles being enqueued.', 'wpse-247251' ) . '</p>'; | |
if ( 'clock' === $instance['behavior'] ) { | |
echo '<p>' . esc_html__( 'Clock: ', 'wpse-247251' ) . '<span class="wpse-247251-clock">' . esc_html__( 'Loading...', 'wpse-247251' ) . '</span></p>'; | |
} elseif ( 'countdown' === $instance['behavior'] ) { | |
echo '<p>' . esc_html__( 'New Year Countdown: ', 'wpse-247251' ) . '<span class="wpse-247251-countdown">' . esc_html__( 'Loading...', 'wpse-247251' ) . '</span> ' . esc_html__( '(seconds)', 'wpse-247251' ) . '</p>'; | |
} | |
echo $args['after_widget']; | |
} | |
/** | |
* Handles updating settings. | |
* | |
* @param array $new_instance New settings for this instance. | |
* @param array $old_instance Old settings for this instance. | |
* @return array Instance. | |
*/ | |
public function update( $new_instance, $old_instance ) { | |
$instance = $old_instance; | |
$instance['title'] = sanitize_text_field( $new_instance['title'] ); | |
if ( in_array( $new_instance['color_scheme'], array( 'light', 'dark' ), true ) ) { | |
$instance['color_scheme'] = $new_instance['color_scheme']; | |
} | |
if ( in_array( $new_instance['behavior'], array( 'clock', 'countdown' ), true ) ) { | |
$instance['behavior'] = $new_instance['behavior']; | |
} | |
return $instance; | |
} | |
/** | |
* Form. | |
* | |
* @param array $instance Instance. | |
* @returns void | |
*/ | |
function form( $instance ) { | |
$instance = wp_parse_args( (array) $instance, $this->default_instance ); | |
$color_scheme_options = array( | |
'light' => __( 'Light', 'wpse-247251' ), | |
'dark' => __( 'Dark', 'wpse-247251' ), | |
); | |
$behavior_options = array( | |
'clock' => __( 'Clock', 'wpse-247251' ), | |
'countdown' => __( 'Countdown', 'wpse-247251' ), | |
); | |
?> | |
<p> | |
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:', 'wpse-247251' ); ?></label> | |
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $instance['title'] ); ?>"/> | |
</p> | |
<p> | |
<label for="<?php echo $this->get_field_id( 'color_scheme' ); ?>"><?php esc_html_e( 'Color Scheme:', 'wpse-247251' ); ?></label> | |
<select id="<?php echo $this->get_field_id( 'color_scheme' ); ?>" name="<?php echo $this->get_field_name( 'color_scheme' ); ?>"> | |
<?php foreach ( $color_scheme_options as $value => $text ) : ?> | |
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $instance['color_scheme'], $value ) ?>><?php echo esc_html( $text ); ?></option> | |
<?php endforeach; ?> | |
</select> | |
</p> | |
<p> | |
<label for="<?php echo $this->get_field_id( 'behavior' ); ?>"><?php esc_html_e( 'Behavior:', 'wpse-247251' ); ?></label> | |
<select id="<?php echo $this->get_field_id( 'behavior' ); ?>" name="<?php echo $this->get_field_name( 'behavior' ); ?>"> | |
<?php foreach ( $behavior_options as $value => $text ) : ?> | |
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $instance['behavior'], $value ) ?>><?php echo esc_html( $text ); ?></option> | |
<?php endforeach; ?> | |
</select> | |
</p> | |
<?php | |
} | |
} | |
$wpse_247251_plugin = new Plugin(); | |
add_action( 'plugins_loaded', array( $wpse_247251_plugin, 'add_hooks' ) ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment