Skip to content

Commit

Permalink
see #1333
Browse files Browse the repository at this point in the history
  • Loading branch information
aristath committed May 25, 2017
1 parent 6cbd2de commit 0638ecf
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 265 deletions.
117 changes: 113 additions & 4 deletions modules/postmessage/class-kirki-modules-postmessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@
*/
class Kirki_Modules_PostMessage {

/**
* The script.
*
* @access protected
* @since 3.0.0
* @var string
*/
protected $script ='';

/**
* Constructor.
*
Expand All @@ -37,15 +46,115 @@ public function __construct() {
*/
public function postmessage() {

wp_enqueue_script( 'kirki_auto_postmessage', trailingslashit( Kirki::$url ) . 'modules/postmessage/postmessage.js', array( 'customize-preview' ), false, true );
wp_enqueue_script( 'kirki_auto_postmessage', trailingslashit( Kirki::$url ) . 'modules/postmessage/postmessage.js', array( 'jquery', 'customize-preview' ), false, true );
$js_vars_fields = array();
$fields = Kirki::$fields;
foreach ( $fields as $field ) {
foreach ( $fields as $id => $field ) {
if ( isset( $field['transport'] ) && 'postMessage' === $field['transport'] && isset( $field['js_vars'] ) && ! empty( $field['js_vars'] ) && is_array( $field['js_vars'] ) && isset( $field['settings'] ) ) {
$js_vars_fields[ $field['settings'] ] = $field['js_vars'];
$this->script .= $this->script( $field );
}
}
wp_add_inline_script( 'kirki_auto_postmessage', $this->script, 'after' );

}

/**
* Generates script for a single js_var.
*
* @access protected
* @since 3.0.0
* @param array $args The arguments.
*/
protected function _script( $args ) {
$script = '';
$property_script = '';

$value_key = 'newval' . $args['index_key'];
$property_script .= $value_key . '=newval;';

// Make sure everything is defined to avoid "undefined index" errors.
$args = wp_parse_args( $args, array(
'element' => '',
'property' => '',
'prefix' => '',
'suffix' => '',
'units' => '',
'js_callback' => array( '', '' ),
'value_pattern' => '',
));

// Element should be a string.
if ( is_array( $args['element'] ) ) {
$args['element'] = implode( ',', $args['element'] );
}

// Make sure arguments that are passed-on to callbacks are strings.
if ( is_array( $args['js_callback'] ) ) {
if ( isset( $args['js_callback'][1] ) && is_array( $args['js_callback'][1] ) ) {
$args['js_callback'][1] = json_encode( $args['js_callback'][1] );
}
}
wp_localize_script( 'kirki_auto_postmessage', 'jsvars', $js_vars_fields );

// Apply callback to the value if a callback is defined.
if ( ! empty( $args['js_callback'][0] ) ) {
$script .= $value_key . '=' . $args['js_callback'][0] . '(' . $value_key . ',' . $args['js_callback'][1] . ');';
}

// Apply the value_pattern.
if ( '' !== $args['value_pattern'] ) {
$value_pattern = str_replace( '$', '\'+' . $value_key . '+\'', $value_key );
$script .= $value_key . '=' . trim( $value_pattern, '\'+' ) . ';';
}

// Apply prefix, units, suffix.
$value = $value_key;
if ( '' !== $args['prefix'] ) {
$value = $args['prefix'] . '+' . $value_key;
}
if ( '' !== $args['units'] || '' !== $args['suffix'] ) {
$value .= '+' . $args['units'] . $args['suffix'];
}
$scripts_array = array();
$scripts_array[ sanitize_key( $args['element'] ) ][ sanitize_key( $args['property'] ) ]['script'] = $property_script . $script;
$scripts_array[ sanitize_key( $args['element'] ) ][ sanitize_key( $args['property'] ) ]['css'] = $args['element'] . '{' . $args['property'] . ':\'+' . $value_key . '+\';}';

return $scripts_array;
}

/**
* Generates script for a single field.
*
* @access protected
* @since 3.0.0
* @param array $args The arguments.
*/
protected function script( $args ) {

$field_scripts = array();

$script = 'wp.customize(\'' . $args['settings'] . '\',function(value){value.bind(function(newval){';
// append unique style tag if not exist
// The style ID.
$style_id = 'kirki-postmessage-' . str_replace( array( '[', ']' ), '', $args['settings'] );
$script .= 'if(!jQuery(\'' . $style_id . '\').size()){jQuery(\'head\').append(\'<style id="' . $style_id . '"></style>\');}';

// Loop through the js_vars and generate the script.
foreach ( $args['js_vars'] as $key => $js_var ) {
$js_var['index_key'] = $key;
$field['scripts'][ $key ] = $this->_script( $js_var );
}
$combo_extra_script = '';
$combo_css_script = '';
foreach ( $field['scripts'] as $script_l1 ) {
foreach ( $script_l1 as $script_l2 ) {
foreach ( $script_l2 as $script_array ) {
$combo_extra_script .= $script_array['script'];
$combo_css_script .= $script_array['css'];
}
}
}
$script .= $combo_extra_script . 'jQuery(\'#' . $style_id . '\').text(\'' . $combo_css_script . '\');';
$script .= '});});';
return $script;
}
}
261 changes: 0 additions & 261 deletions modules/postmessage/postmessage.js
Original file line number Diff line number Diff line change
@@ -1,261 +0,0 @@
var kirkiPostMessage = {

/**
* Helper function to correctly get the font-weight from a variant
* when using a typography field.
*
* @since 3.0.0
* @param object value The value of the setting.
* @return int|string
*/
getFontWeight: function( value ) {
var calculated;

// Return 400 if invalid input.
if ( ! _.isString( value ) ) {
return 400;
}

// Get only digits. If non-numeric value, then return 400.
calculated = value.match( /\d/g );
return ( ! _.isObject( calculated ) ) ? 400 : calculated.join( '' );
},

/**
* Helper function to correctly get the vars with all defaults set.
*
* @since 3.0.0
* @param object jsVar The arguments of the jsVars we'll be using.
* @return object
*/
getVarComplete: function( jsVar ) {
return _.defaults( jsVar, {
element: '',
property: '',
prefix: '',
suffix: '',
units: '',
'function': 'css',
value_pattern: '$'
});
},

/**
* Make sure images have url("{image}") instead of just the URL.
*
* @since 3.0.0
* @param string property The CSS property to check against.
* @param string value The setting value.
* @return string
*/
applyBackgroundImage: function( property, value ) {
if ( 'background-image' === property && 0 > value.indexOf( 'url(' ) ) {
value = 'url("' + value + '")';
}
return value;
},

/**
* Adds google-fonts scripts and returns the CSS for the typography field.
*
* @since 3.0.0
* @param object value The setting value.
* @param object args The arguments we're using to auto-calculate the CSS.
* @return object
*/
applyTypography: function( value, args ) {
var $this = this,
subsetsString = '',
css = '';

// Early exit if this is not an object.
if ( ! _.isObject( value ) ) {
return;
}

// If 'font-family' is not defined then this is not a typography field.
if ( _.isUndefined( value['font-family'] ) ) {
return;
}

// Make sure variants and subsets are defined.
value.variant = ( _.isUndefined( value.variant ) ) ? 400 : value.variant;
value.subsets = ( _.isUndefined( value.subsets ) ) ? [] : value.subsets;
subsetsString = ( _.isObject( value.subsets ) ) ? ':' + value.subsets.join( ',' ) : '';

// Load the font using WenFontloader.
jQuery( 'head' ).append( '<script>if(!_.isUndefined(WebFont)){WebFont.load({google:{families:[\'' + value['font-family'] + ':' + value.variant + subsetsString + '\']}});}</script>' );

// Add the CSS.
css += args.element + '{font-weight:' + $this.getFontWeight( value.variant ) + '}';
css += ( -1 !== value.variant.indexOf( 'italic' ) ) ? args.element + '{font-style:italic;}' : args.element + '{font-style:normal;}';
return css;
},

/**
* Generates the CSS.
*
* @since 3.0.0
* @param mixed value The setting value.
* @param object args The arguments.
* @param string setting The setting we're checking.
* @return object
*/
generateCSS: function( value, args, setting ) {
var $this = this,
settings = window.wp.customize.get(),
css = '',
regex;

if ( _.isUndefined( value ) || _.isUndefined( args ) || _.isUndefined( setting ) ) {
return '';
}

// Value is string.
if ( _.isString( value ) ) {

// No need to proceed if empty.
if ( '' === value ) {
return '';
}

// WIP. Ignore.
if ( ! _.isUndefined( args.value_pattern ) && '' !== args.value_pattern && '$' !== args.value_pattern && ! _.isUndefined( args.replacements ) ) {
_.each( args.replacements, function( replace, search ) {
var item;
if ( 'this' === replace ) {
if ( _.isUndefined( settings ) || _.isUndefined( settings[ setting ] ) ) {
return; // Continue.
}
replace = settings[ setting ];
} else {
if ( -1 !== replace.indexOf( '[' ) ) {
item = replace.replace( ']', '' ).split( '[' );
if ( _.isUndefined( settings ) || _.isUndefined( settings[ item[0] ] ) || _.isUndefined( settings[ item[0] ][ item[1] ] ) ) {
return; // Continue.
}
replace = settings[ item[0] ][ item[1] ];
}
if ( _.isUndefined( settings ) || _.isUndefined( settings[ replace ] ) ) {
return; // Continue.
}
replace = settings[ replace ];
}
regex = new RegExp( search, 'g' );
args.value_pattern = args.value_pattern.replace( regex, replace );
});
args.value_pattern.replace( /\$/g, args.prefix + value + args.units + args.suffix );
}

// Calculate and return the CSS.
if ( ! _.isUndefined( args.value_pattern ) && '' !== args.value_pattern ) {
value = args.value_pattern.replace( /\$/g, args.prefix + value + args.units + args.suffix );
}
value = $this.applyBackgroundImage( args.property, value );

return args.element + '{' + args.property + ':' + value + ';}';

// Value is an object.
} else if ( _.isObject( value ) ) {
_.each( value, function( subVal, subKey ) {

// Make sure that if 'background-image' is used, it's properly formatted.
subVal = $this.applyBackgroundImage( subKey, subVal );

// Apply css and webfonts for typography controls.
css += $this.applyTypography( value, args );

// Hack for the "choice" argument.
if ( ! _.isUndefined( args.choice ) ) {
if ( args.choice === subKey ) {
css += args.element + '{' + args.property + ':' + args.prefix + subVal + args.units + args.suffix + ';}';
}
} else {

// Mostly used for padding, margin & position properties.
if ( _.contains( [ 'top', 'bottom', 'left', 'right' ], subKey ) ) {
css += args.element + '{' + args.property + '-' + subKey + ':' + args.prefix + subVal + args.units + args.suffix + ';}';
} else if ( 'subsets' !== subKey && 'variant' !== subKey ) {

// This is where most object-based fields will go.
css += args.element + '{' + subKey + ':' + args.prefix + subVal + args.units + args.suffix + ';}';
}
}
});
return css;
}
return '';
},

/**
* Loops our fields and does what needs to be done.
*
* @since 3.0.0
*/
init: function() {
var $this = this;
_.each( jsvars, function( jsVars, setting ) {
var css = '',
cssArray = {};

wp.customize( setting, function( value ) {
value.bind( function( newval ) {

if ( ! _.isUndefined( jsVars ) && 0 < jsVars.length ) {
_.each( jsVars, function( args, i ) {

// Make sure the object is properly formatted.
args = $this.getVarComplete( args );

// Add support for js_callback.
if ( _.isObject( args.js_callback ) && _.isFunction( args.js_callback[0] ) ) {
if ( ! _.isUndefined( args.js_callback[1] ) ) {
console.log( 'here' );
newval = window[ args.js_callback[0] ]( args.js_callback[1] );
} else {
newval = window[ args.js_callback[0] ]();
}
}

// If we're using "html" instead of "css" then add the HTML.
if ( _.isString( newval ) && 'html' === args['function'] ) {
if ( ! _.isUndefined( args.attr ) ) {
jQuery( args.element ).attr( args.attr, newval );
} else {
jQuery( args.element ).html( newval );
}
} else {

// Generate the CSS.
cssArray[ i ] = $this.generateCSS( newval, args, setting );
}
});

// Adds the CSS to the document.
_.each( cssArray, function( singleCSS ) {
css = '';
setTimeout( function() {

if ( '' !== singleCSS ) {
css += singleCSS;
}

// Attach to <head>. Make sure we have a stylesheet with the defined ID,
// and if we don't then add it.
if ( ! jQuery( '#kirki-customizer-postmessage' + setting.replace( /\[/g, '-' ).replace( /\]/g, '' ) ).size() ) {
jQuery( 'head' ).append( '<style id="kirki-customizer-postmessage' + setting.replace( /\[/g, '-' ).replace( /\]/g, '' ) + '"></style>' );
}
jQuery( '#kirki-customizer-postmessage' + setting.replace( /\[/g, '-' ).replace( /\]/g, '' ) ).text( css );
}, 100 );
});
}
});
});
});
}
};

// Init.
jQuery( document ).ready( function() {
kirkiPostMessage.init();
});

0 comments on commit 0638ecf

Please sign in to comment.