mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-07-04 17:20:07 +00:00
Customize: Require opt-in for selective refresh of widgets.
* Introduces `customize-selective-refresh-widgets` theme support feature and adds to themes. * Introduces `customize_selective_refresh` arg for `WP_Widget::$widget_options` and adds to all core widgets. * Remove `selective_refresh` from being a component that can be removed via `customize_loaded_components` filter. * Add `WP_Customize_Widgets::get_selective_refreshable_widgets()` and `WP_Customize_Widgets::is_widget_selective_refreshable()`. * Fix default `selector` for `Partial` instances. * Implement and improve Masronry sidebar refresh logic in Twenty Thirteen and Twenty Fourteen, including preservation of initial widget position after refresh. * Re-initialize ME.js when refreshing `Twenty_Fourteen_Ephemera_Widget`. See #27355. Fixes #35855. git-svn-id: https://develop.svn.wordpress.org/trunk@37040 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -61,6 +61,15 @@ final class WP_Customize_Widgets {
|
||||
*/
|
||||
protected $old_sidebars_widgets = array();
|
||||
|
||||
/**
|
||||
* Mapping of widget ID base to whether it supports selective refresh.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $selective_refreshable_widgets;
|
||||
|
||||
/**
|
||||
* Mapping of setting type to setting ID pattern.
|
||||
*
|
||||
@@ -69,8 +78,8 @@ final class WP_Customize_Widgets {
|
||||
* @var array
|
||||
*/
|
||||
protected $setting_id_patterns = array(
|
||||
'widget_instance' => '/^(widget_.+?)(?:\[(\d+)\])?$/',
|
||||
'sidebar_widgets' => '/^sidebars_widgets\[(.+?)\]$/',
|
||||
'widget_instance' => '/^widget_(?P<id_base>.+?)(?:\[(?P<widget_number>\d+)\])?$/',
|
||||
'sidebar_widgets' => '/^sidebars_widgets\[(?P<sidebar_id>.+?)\]$/',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -111,6 +120,46 @@ final class WP_Customize_Widgets {
|
||||
add_action( 'customize_preview_init', array( $this, 'selective_refresh_init' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* List whether each registered widget can be use selective refresh.
|
||||
*
|
||||
* If the theme does not support the customize-selective-refresh-widgets feature,
|
||||
* then this will always return an empty array.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Mapping of id_base to support. If theme doesn't support
|
||||
* selective refresh, an empty array is returned.
|
||||
*/
|
||||
public function get_selective_refreshable_widgets() {
|
||||
global $wp_widget_factory;
|
||||
if ( ! current_theme_supports( 'customize-selective-refresh-widgets' ) ) {
|
||||
return array();
|
||||
}
|
||||
if ( ! isset( $this->selective_refreshable_widgets ) ) {
|
||||
$this->selective_refreshable_widgets = array();
|
||||
foreach ( $wp_widget_factory->widgets as $wp_widget ) {
|
||||
$this->selective_refreshable_widgets[ $wp_widget->id_base ] = ! empty( $wp_widget->widget_options['customize_selective_refresh'] );
|
||||
}
|
||||
}
|
||||
return $this->selective_refreshable_widgets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a widget supports selective refresh.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id_base Widget ID Base.
|
||||
* @return bool Whether the widget can be selective refreshed.
|
||||
*/
|
||||
public function is_widget_selective_refreshable( $id_base ) {
|
||||
$selective_refreshable_widgets = $this->get_selective_refreshable_widgets();
|
||||
return ! empty( $selective_refreshable_widgets[ $id_base ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the widget setting type given a setting ID.
|
||||
*
|
||||
@@ -119,7 +168,7 @@ final class WP_Customize_Widgets {
|
||||
*
|
||||
* @staticvar array $cache
|
||||
*
|
||||
* @param $setting_id Setting ID.
|
||||
* @param string $setting_id Setting ID.
|
||||
* @return string|void Setting type.
|
||||
*/
|
||||
protected function get_setting_type( $setting_id ) {
|
||||
@@ -690,7 +739,7 @@ final class WP_Customize_Widgets {
|
||||
'widgetReorderNav' => $widget_reorder_nav_tpl,
|
||||
'moveWidgetArea' => $move_widget_area_tpl,
|
||||
),
|
||||
'selectiveRefresh' => isset( $this->manager->selective_refresh ),
|
||||
'selectiveRefreshableWidgets' => $this->get_selective_refreshable_widgets(),
|
||||
);
|
||||
|
||||
foreach ( $settings['registeredWidgets'] as &$registered_widget ) {
|
||||
@@ -771,16 +820,17 @@ final class WP_Customize_Widgets {
|
||||
$args = array(
|
||||
'type' => 'option',
|
||||
'capability' => 'edit_theme_options',
|
||||
'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh',
|
||||
'default' => array(),
|
||||
);
|
||||
|
||||
if ( preg_match( $this->setting_id_patterns['sidebar_widgets'], $id, $matches ) ) {
|
||||
$args['sanitize_callback'] = array( $this, 'sanitize_sidebar_widgets' );
|
||||
$args['sanitize_js_callback'] = array( $this, 'sanitize_sidebar_widgets_js_instance' );
|
||||
$args['transport'] = current_theme_supports( 'customize-selective-refresh-widgets' ) ? 'postMessage' : 'refresh';
|
||||
} elseif ( preg_match( $this->setting_id_patterns['widget_instance'], $id, $matches ) ) {
|
||||
$args['sanitize_callback'] = array( $this, 'sanitize_widget_instance' );
|
||||
$args['sanitize_js_callback'] = array( $this, 'sanitize_widget_js_instance' );
|
||||
$args['transport'] = $this->is_widget_selective_refreshable( $matches['id_base'] ) ? 'postMessage' : 'refresh';
|
||||
}
|
||||
|
||||
$args = array_merge( $args, $overrides );
|
||||
@@ -893,7 +943,7 @@ final class WP_Customize_Widgets {
|
||||
'multi_number' => ( $args['_add'] === 'multi' ) ? $args['_multi_num'] : false,
|
||||
'is_disabled' => $is_disabled,
|
||||
'id_base' => $id_base,
|
||||
'transport' => isset( $this->manager->selective_refresh ) ? 'postMessage' : 'refresh',
|
||||
'transport' => $this->is_widget_selective_refreshable( $id_base ) ? 'postMessage' : 'refresh',
|
||||
'width' => $wp_registered_widget_controls[$widget['id']]['width'],
|
||||
'height' => $wp_registered_widget_controls[$widget['id']]['height'],
|
||||
'is_wide' => $this->is_wide_widget( $widget['id'] ),
|
||||
@@ -1025,6 +1075,7 @@ final class WP_Customize_Widgets {
|
||||
*/
|
||||
public function customize_preview_enqueue() {
|
||||
wp_enqueue_script( 'customize-preview-widgets' );
|
||||
wp_enqueue_style( 'customize-preview' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1060,6 +1111,7 @@ final class WP_Customize_Widgets {
|
||||
*/
|
||||
public function export_preview_data() {
|
||||
global $wp_registered_sidebars, $wp_registered_widgets;
|
||||
|
||||
// Prepare Customizer settings to pass to JavaScript.
|
||||
$settings = array(
|
||||
'renderedSidebars' => array_fill_keys( array_unique( $this->rendered_sidebars ), true ),
|
||||
@@ -1069,7 +1121,7 @@ final class WP_Customize_Widgets {
|
||||
'l10n' => array(
|
||||
'widgetTooltip' => __( 'Shift-click to edit this widget.' ),
|
||||
),
|
||||
'selectiveRefresh' => isset( $this->manager->selective_refresh ),
|
||||
'selectiveRefreshableWidgets' => $this->get_selective_refreshable_widgets(),
|
||||
);
|
||||
foreach ( $settings['registeredWidgets'] as &$registered_widget ) {
|
||||
unset( $registered_widget['callback'] ); // may not be JSON-serializeable
|
||||
@@ -1479,6 +1531,9 @@ final class WP_Customize_Widgets {
|
||||
* @return array (Maybe) modified partial arguments.
|
||||
*/
|
||||
public function customize_dynamic_partial_args( $partial_args, $partial_id ) {
|
||||
if ( ! current_theme_supports( 'customize-selective-refresh-widgets' ) ) {
|
||||
return $partial_args;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^widget\[(?P<widget_id>.+)\]$/', $partial_id, $matches ) ) {
|
||||
if ( false === $partial_args ) {
|
||||
@@ -1506,33 +1561,15 @@ final class WP_Customize_Widgets {
|
||||
* @access public
|
||||
*/
|
||||
public function selective_refresh_init() {
|
||||
if ( ! isset( $this->manager->selective_refresh ) ) {
|
||||
if ( ! current_theme_supports( 'customize-selective-refresh-widgets' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'customize_preview_enqueue_deps' ) );
|
||||
add_filter( 'dynamic_sidebar_params', array( $this, 'filter_dynamic_sidebar_params' ) );
|
||||
add_filter( 'wp_kses_allowed_html', array( $this, 'filter_wp_kses_allowed_data_attributes' ) );
|
||||
add_action( 'dynamic_sidebar_before', array( $this, 'start_dynamic_sidebar' ) );
|
||||
add_action( 'dynamic_sidebar_after', array( $this, 'end_dynamic_sidebar' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues scripts for the Customizer preview.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function customize_preview_enqueue_deps() {
|
||||
if ( isset( $this->manager->selective_refresh ) ) {
|
||||
$script = wp_scripts()->registered['customize-preview-widgets'];
|
||||
$script->deps[] = 'customize-selective-refresh';
|
||||
}
|
||||
|
||||
wp_enqueue_script( 'customize-preview-widgets' );
|
||||
wp_enqueue_style( 'customize-preview' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject selective refresh data attributes into widget container elements.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user