Skip to content

Commit

Permalink
Merge a0900b4 into e1d4d3d
Browse files Browse the repository at this point in the history
  • Loading branch information
valendesigns committed Nov 17, 2015
2 parents e1d4d3d + a0900b4 commit 91e4db2
Show file tree
Hide file tree
Showing 15 changed files with 736 additions and 8 deletions.
4 changes: 4 additions & 0 deletions .coveralls.yml
@@ -0,0 +1,4 @@
service_name: travis-ci
src_dir: .
coverage_clover: build/logs/clover.xml
json_path: build/logs/coveralls-upload.json
11 changes: 11 additions & 0 deletions .jscsrc
@@ -0,0 +1,11 @@
{
"preset": "wordpress",
"excludeFiles": [
"**/vendor/**",
"**/*.min.js",
"**/customize-partial-refresh-base.js",
"**/customize-partial-refresh-widgets-*.js",
"**/twentythirteen.js",
"**/node_modules/**"
]
}
6 changes: 6 additions & 0 deletions .jshintignore
@@ -0,0 +1,6 @@
**/vendor/**
**/*.min.js
**/customize-partial-refresh-base.js
**/customize-partial-refresh-widgets-*.js
**/twentythirteen.js
**/node_modules/**
5 changes: 5 additions & 0 deletions composer.json
@@ -0,0 +1,5 @@
{
"require-dev": {
"satooshi/php-coveralls": "dev-master"
}
}
7 changes: 4 additions & 3 deletions customize-partial-refresh.php
Expand Up @@ -27,7 +27,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

require_once( __DIR__ . '/php/class-wp-customize-partial-refresh-plugin.php' );
require_once( __DIR__ . '/php/class-wp-customize-partial-refresh-widgets.php' );
require_once( __DIR__ . '/php/class-wp-customize-partial-refresh-exception.php' );
require_once( dirname( __FILE__ ) . '/php/class-wp-customize-partial-refresh-plugin.php' );
require_once( dirname( __FILE__ ) . '/php/class-wp-customize-partial-refresh-settings.php' );
require_once( dirname( __FILE__ ) . '/php/class-wp-customize-partial-refresh-widgets.php' );
require_once( dirname( __FILE__ ) . '/php/class-wp-customize-partial-refresh-exception.php' );
$GLOBALS['wp_customize_partial_refresh_plugin'] = new WP_Customize_Partial_Refresh_Plugin();
2 changes: 1 addition & 1 deletion dev-lib
128 changes: 128 additions & 0 deletions js/customize-partial-refresh-settings.js
@@ -0,0 +1,128 @@
/* global jQuery, _customizePartialRefreshSettings, JSON, _ */
/* exported customizePartialRefreshSettings */
var customizePartialRefreshSettings = ( function( $ ) {
'use strict';

var self, api = wp.customize;

self = {
setting: null
};

$.extend( self, _customizePartialRefreshSettings );

/**
* Inject the functionality.
*/
self.init = function() {
api.bind( 'ready', function() {
self.onChangeSetting();
} );

api.bind( 'setting-partial', function( response ) {
var that = $( 'iframe' ).contents(),
value = $.trim( response );

$( self.setting.selector, that ).html( value );
} );
};

/**
* Change event for selective settings, requests a new value.
*/
self.onChangeSetting = function() {
$.each( self.settings, function( id, selector ) {

api( id, function( setting ) {

setting.bind( function() {
self.setting = {
id: id,
selector: selector
};
self.request();
} );
} );
} );
};

/**
* Request a new setting value.
*
* @return {jQuery.Deferred}
*/
self.request = function() {
var spinner = $( '#customize-header-actions .spinner' ),
active = 'is-active',
deferred = $.Deferred(),
req = self.debounceRequest();

spinner.addClass( active );

req.done( function( response ) {
deferred.resolve();
api.trigger( 'setting-partial', response );
spinner.removeClass( active );
} );

req.fail( function() {
deferred.reject.apply( deferred, arguments );
api.previewer.refresh();
spinner.removeClass( active );
} );

return deferred;
};

/**
* Debounce the requests, allowing setting changes made back-to-back to be sent together.
*
* @return {jQuery.Deferred}
*/
self.debounceRequest = ( function() {
var request, debouncedDeferreds = [];

request = _.debounce( function() {
var req, dirtyCustomized = {};

api.each( function( value, key ) {
if ( value._dirty ) {
dirtyCustomized[ key ] = value();
}
} );

req = wp.ajax.post( self.action, {
nonce: self.nonce,
setting_id: self.setting.id,
wp_customize: 'on',
customized: JSON.stringify( dirtyCustomized )
} );

req.done( function() {
var deferred;
while ( debouncedDeferreds.length ) {
deferred = debouncedDeferreds.shift();
deferred.resolveWith( req, arguments );
}
} );

req.fail( function() {
var deferred;
while ( debouncedDeferreds.length ) {
deferred = debouncedDeferreds.shift();
deferred.rejectWith( req, arguments );
}
} );

} );

return function() {
var deferred = $.Deferred();
debouncedDeferreds.push( deferred );
request();
return deferred;
};
}() );

self.init();
}( jQuery ) );
13 changes: 13 additions & 0 deletions php/class-wp-customize-partial-refresh-plugin.php
Expand Up @@ -19,6 +19,11 @@ class WP_Customize_Partial_Refresh_Plugin {
*/
public $dir_url = '';

/**
* @var WP_Customize_Partial_Refresh_Settings
*/
public $settings;

/**
* @var WP_Customize_Partial_Refresh_Widgets
*/
Expand Down Expand Up @@ -46,6 +51,7 @@ function __construct() {
add_action( 'wp_default_scripts', array( $this, 'register_scripts' ), 11 );
add_action( 'wp_default_styles', array( $this, 'register_styles' ), 11 );
add_action( 'init', array( $this, 'init' ) );
$this->settings = new WP_Customize_Partial_Refresh_Settings( $this );
$this->widgets = new WP_Customize_Partial_Refresh_Widgets( $this );
}

Expand Down Expand Up @@ -81,6 +87,13 @@ function register_scripts( $wp_scripts ) {
$in_footer = true;
$wp_scripts->add( $handle, $src, $deps, $this->get_version(), $in_footer );
$this->script_handles['widgets-pane'] = $handle;

$handle = 'customize-partial-refresh-settings';
$src = $this->get_dir_url( 'js/customize-partial-refresh-settings.js' );
$deps = array( 'jquery', 'wp-util' );
$in_footer = true;
$wp_scripts->add( $handle, $src, $deps, $this->get_version(), $in_footer );
$this->script_handles['settings'] = $handle;
}

/**
Expand Down
138 changes: 138 additions & 0 deletions php/class-wp-customize-partial-refresh-settings.php
@@ -0,0 +1,138 @@
<?php
/**
* Implements partial refresh for selective settings.
*/
class WP_Customize_Partial_Refresh_Settings {

/**
* Alias for the AJAX action.
*
* @type string
*/
const AJAX_ACTION = 'customize_partial_refresh_settings';

/**
* WP_Customize_Partial_Refresh_Plugin instance.
*
* @var WP_Customize_Partial_Refresh_Plugin
*/
public $plugin;

/**
* Contructor.
*/
public function __construct( WP_Customize_Partial_Refresh_Plugin $plugin ) {
$this->plugin = $plugin;
add_action( 'after_setup_theme', array( $this, 'init' ), 11 );
}

/**
* Initialize selective partial refresh.
*
* @action after_setup_theme
*/
public function init() {
if ( ! current_theme_supports( 'customize-partial-refresh', 'settings' ) ) {
return;
}
add_action( 'wp_ajax_' . self::AJAX_ACTION, array( $this, 'refresh' ) );
add_action( 'customize_controls_print_footer_scripts', array( $this, 'enqueue_scripts' ) );
}

/**
* Enqueue scripts.
*
* @action customize_controls_enqueue_scripts
*/
function enqueue_scripts() {
wp_enqueue_script( $this->plugin->script_handles['settings'] );

// Script data array.
$exports = array(
'nonce' => wp_create_nonce( self::AJAX_ACTION ),
'action' => self::AJAX_ACTION,
'settings' => $this->settings(),
);

// Export data to JS.
wp_scripts()->add_data(
$this->plugin->script_handles['settings'],
'data',
sprintf( 'var _customizePartialRefreshSettings = %s;', wp_json_encode( $exports ) )
);
}

/**
* An array of all the partial refresh settings.
*
* @return array
*/
public function settings() {
global $wp_customize;

$settings = array();
if ( $wp_customize ) {
foreach ( $wp_customize->settings() as $setting ) {
if ( empty( $setting->selector ) || 'partialRefresh' !== $setting->transport ) {
continue;
}
if ( $setting->check_capabilities() ) {
$settings[ $setting->id ] = $setting->selector;
}
}
}
return $settings;
}

/**
* Ajax request to return the settings partial value.
*
* @action wp_ajax_customize_partial_refresh_settings
*/
public function refresh() {
if ( ! check_ajax_referer( self::AJAX_ACTION, 'nonce', false ) ) {
status_header( 400 );
wp_send_json_error( 'bad_nonce' );
} else if ( ! current_user_can( 'customize' ) || ! is_customize_preview() ) {
status_header( 403 );
wp_send_json_error( 'customize_not_allowed' );
} else if ( ! isset( $_POST['setting_id'] ) ) {
status_header( 400 );
wp_send_json_error( 'missing_setting_id' );
} else if ( ! isset( $_POST['customized'] ) ) {
status_header( 400 );
wp_send_json_error( 'missing_customized' );
}

global $wp_customize;
$setting = $wp_customize->get_setting( $_POST['setting_id'] );

if ( ! $setting ) {
wp_send_json_error( 'setting_not_found' );
} else if ( empty( $setting->selector ) ) {
wp_send_json_error( 'setting_selector_not_found' );
}

/**
* Filter partial value for a successful AJAX request.
*
* @param mixed $partial The partial value. Default null.
* @param WP_Customize_Setting $setting WP_Customize_Setting instance.
*/
$partial = apply_filters( 'customize_partial_refresh_settings', null, $setting );

/**
* Filter partial value by setting ID for a successful AJAX request.
*
* @param mixed $partial The partial value. Default null.
* @param WP_Customize_Setting $setting WP_Customize_Setting instance.
*/
$partial = apply_filters( "customize_partial_refresh_{$setting->id}", $partial, $setting );

if ( null !== $partial ) {
wp_send_json_success( $partial );
} else {
wp_send_json_error( 'missing_required_filter' );
}
}
}
5 changes: 2 additions & 3 deletions php/class-wp-customize-partial-refresh-widgets.php
Expand Up @@ -80,7 +80,7 @@ function add_builtin_theme_support() {
* @param string $id_base
* @return bool
*/
function is_widget_partial_refreshable( $id_base) {
function is_widget_partial_refreshable( $id_base ) {
$partial_refreshable = false;
if ( in_array( $id_base, $this->core_widget_base_ids ) ) {
$partial_refreshable = true;
Expand Down Expand Up @@ -214,7 +214,7 @@ function customize_controls_enqueue_scripts() {
$wp_scripts->add_data(
$this->plugin->script_handles['widgets-pane'],
'data',
sprintf( 'var _wpCustomizePartialRefreshWidgets_exports = %s;', json_encode( $exports ) )
sprintf( 'var _wpCustomizePartialRefreshWidgets_exports = %s;', wp_json_encode( $exports ) )
);
}

Expand Down Expand Up @@ -411,5 +411,4 @@ public function log_rendered_widget( $widget ) {
$this->currently_rendered_other_rendered_widget_ids[] = $widget['id'];
}
}

}
1 change: 1 addition & 0 deletions phpcs.ruleset.xml
1 change: 1 addition & 0 deletions phpunit.xml.dist
2 changes: 1 addition & 1 deletion readme.md
Expand Up @@ -10,7 +10,7 @@ Refresh parts of a Customizer preview instead of reloading the entire page when
**Stable tag:** trunk (master)
**License:** [GPLv2 or later](http://www.gnu.org/licenses/gpl-2.0.html)

[![Build Status](https://travis-ci.org/xwp/wp-customize-partial-refresh.png?branch=master)](https://travis-ci.org/xwp/wp-customize-partial-refresh)
[![Build Status](https://travis-ci.org/xwp/wp-customize-partial-refresh.svg?branch=master)](https://travis-ci.org/xwp/wp-customize-partial-refresh) [![Coverage Status](https://coveralls.io/repos/xwp/wp-customize-partial-refresh/badge.svg?branch=master)](https://coveralls.io/github/xwp/wp-customize-partial-refresh)

## Description ##

Expand Down

0 comments on commit 91e4db2

Please sign in to comment.