From 0638ecf00ea05e74b7ffe95800f74cb81af72edc Mon Sep 17 00:00:00 2001 From: Aristeides Stathopoulos Date: Thu, 25 May 2017 20:24:57 +0300 Subject: [PATCH] see #1333 --- .../class-kirki-modules-postmessage.php | 117 +++++++- modules/postmessage/postmessage.js | 261 ------------------ 2 files changed, 113 insertions(+), 265 deletions(-) diff --git a/modules/postmessage/class-kirki-modules-postmessage.php b/modules/postmessage/class-kirki-modules-postmessage.php index 05dc96d8c..970bf4bd0 100644 --- a/modules/postmessage/class-kirki-modules-postmessage.php +++ b/modules/postmessage/class-kirki-modules-postmessage.php @@ -20,6 +20,15 @@ */ class Kirki_Modules_PostMessage { + /** + * The script. + * + * @access protected + * @since 3.0.0 + * @var string + */ + protected $script =''; + /** * Constructor. * @@ -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(\'\');}'; + + // 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; } } diff --git a/modules/postmessage/postmessage.js b/modules/postmessage/postmessage.js index f7f11b150..e69de29bb 100644 --- a/modules/postmessage/postmessage.js +++ b/modules/postmessage/postmessage.js @@ -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( '' ); - - // 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 . 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( '' ); - } - jQuery( '#kirki-customizer-postmessage' + setting.replace( /\[/g, '-' ).replace( /\]/g, '' ) ).text( css ); - }, 100 ); - }); - } - }); - }); - }); - } -}; - -// Init. -jQuery( document ).ready( function() { - kirkiPostMessage.init(); -});