/* jQuery deparam is an extraction of the deparam method from Ben Alman's jQuery BBQ http://benalman.com/projects/jquery-bbq-plugin/ */ function BlogsyLinkField($el) { this.$el = $el; // Adjust the selector to get the container const setupEventListeners = () => { this.$el.on( 'click', 'a[data-name="add"]', onClickEdit ); this.$el.on( 'click', 'a[data-name="edit"]', onClickEdit ); this.$el.on( 'click', 'a[data-name="remove"]', onClickRemove ); this.$el.on( 'change', '.link-node', onChange ); if (typeof wpLink !== 'undefined') { wpLink.init(); // Initialize wpLink if it's not already initialized } } const control = () => { return this.$el; } const node = () => { return this.$el.find( '.link-node' ); } const getValue = (e) => { var $node = node(); if ( ! $node.attr( 'href' )) { return false; } return { title: $node.html(), url: $node.attr( 'href' ), target: $node.attr( 'target' ) }; } const setValue = (val,e) => { val = val || { title: '', url: '', target: '' }; var $div = control(); var $node = node(); $div.removeClass( '-value -external' ); if (val.url) { $div.addClass( '-value' ); } if (val.target === '_blank') { $div.addClass( '-external' ); } this.$el.find( '.link-title' ).html( val.title ); var url = val ?.url ?.length > 25 ? val.url.substring( 0, 22 ) + '...' : val.url this.$el.find( '.link-url' ).attr( 'href', val.url ).html( url ).attr( 'title', val.url ); $node.html( val.title ); $node.attr( 'href', val.url ); $node.attr( 'target', val.target ); this.$el.find( '.input-title' ).val( val.title ); this.$el.find( '.input-target' ).val( val.target ); this.$el.find( '.input-url' ).val( val.url ).trigger( 'change' ); } const onClickEdit = (e) => { e.preventDefault(); open(); } const onClickRemove = (e) => { e.preventDefault(); setValue( false ); } const onChange = (e) => { var val = getValue( e ); setValue( val,e ); } const getNodeValue = () => { var $node = node(); return { title: $node.html(), url: $node.attr( 'href' ), target: $node.attr( 'target' ) }; } const setNodeValue = (val) => { var $node = node(); $node.text( val.title ); $node.attr( 'href', val.url ); $node.attr( 'target', val.target ); $node.trigger( 'change' ); } const getInputValue = () => { return { title: jQuery( '#wp-link-text' ).val(), url: jQuery( '#wp-link-url' ).val(), target: jQuery( '#wp-link-target' ).prop( 'checked' ) ? '_blank' : '' }; } const setInputValue = (val) => { jQuery( '#wp-link-text' ).val( val.title ); jQuery( '#wp-link-url' ).val( val.url ); jQuery( '#wp-link-target' ).prop( 'checked', val.target === '_blank' ); } const open = () => { jQuery( document ).on( 'wplink-open', onOpen ); jQuery( document ).on( 'wplink-close', onClose ); var $textarea = jQuery( '' ); if ( ! jQuery( '#blogsy-link-textarea' ).length) { jQuery( 'body' ).append( $textarea ); } var val = getNodeValue(); wpLink.open( 'blogsy-link-textarea', val.url, val.title, null ); } const onOpen = () => { // always show title (WP will hide title if empty) jQuery( '#wp-link-wrap' ).addClass( 'has-text-field' ); // set inputs jQuery( document ).one( 'click', '#wp-link-submit', onWPLinkInsert ); var val = getNodeValue(); setInputValue( val ); // Update button text. if (val.url && wpLinkL10n) { jQuery( '#wp-link-submit' ).val( wpLinkL10n.update ); } } const onClose = () => { var $submit = jQuery( '#wp-link-submit' ); var isSubmit = $submit.is( ':hover' ) || $submit.is( ':focus' ); // Set value if (isSubmit) { var val = getInputValue(); setNodeValue( val ); } // Cleanup. jQuery( document ).off( 'wplink-open' ); jQuery( document ).off( 'wplink-close' ); jQuery( '#blogsy-link-textarea' ).remove(); } const onWPLinkInsert = (e) => { e.stopPropagation(); var data = getInputValue(); if (data.url) { var val = { title: data.title, url: data.url, target: data.target }; setNodeValue( val ); } }; return { init: function () { setupEventListeners(); } } } ( function ( $ ) { $.deparam = function ( params, coerce ) { var obj = {}, coerce_types = { 'true': ! 0, 'false': ! 1, 'null': null }; // Iterate over all name=value pairs. $.each( params.replace( /\+/g, ' ' ).split( '&' ), function ( j, v ) { var param = v.split( '=' ), key = decodeURIComponent( param[0] ), val, cur = obj, i = 0, // If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it // into its component parts. keys = key.split( '][' ), keys_last = keys.length - 1; // If the first keys part contains [ and the last ends with ], then [] // are correctly balanced. if ( /\[/.test( keys[0] ) && /\]$/.test( keys[keys_last] ) ) { // Remove the trailing ] from the last keys part. keys[keys_last] = keys[keys_last].replace( /\]$/, '' ); // Split first keys part into two parts on the [ and add them back onto // the beginning of the keys array. keys = keys.shift().split( '[' ).concat( keys ); keys_last = keys.length - 1; } else { // Basic 'foo' style key. keys_last = 0; } // Are we dealing with a name=value pair, or just a name? if ( 2 === param.length ) { val = decodeURIComponent( param[1] ); // Coerce values. if ( coerce ) { val = val && ! isNaN( val ) ? +val // number : 'undefined' === val ? undefined // undefined : coerce_types[val] !== undefined ? coerce_types[val] // true, false, null : val; // string } if ( keys_last ) { // Complex key, build deep object structure based on a few rules: // * The 'cur' pointer starts at the object top-level. // * [] = array push (n is set to array length), [n] = array if n is // numeric, otherwise object. // * If at the last keys part, set the value. // * For each keys part, if the current level is undefined create an // object or array based on the type of the next keys part. // * Move the 'cur' pointer to the next level. // * Rinse & repeat. for ( ; i <= keys_last; i++ ) { key = '' === keys[i] ? cur.length : keys[i]; cur = cur[key] = i < keys_last ? cur[key] || ( keys[i + 1] && isNaN( keys[i + 1] ) ? {} : []) : val; } } else { // Simple key, even simpler rules, since only scalars and shallow // arrays are allowed. if ( $.isArray( obj[key] ) ) { // val is already an array, so push on the next value. obj[key].push( val ); } else if ( obj[key] !== undefined ) { // val isn't an array, but since a second value has been specified, // convert val into an array. obj[key] = [ obj[key], val ]; } else { // val is a scalar. obj[key] = val; } } } else if ( key ) { // No value was defined, so set something meaningful. obj[key] = coerce ? undefined : ''; } } ); return obj; }; }( jQuery ) ); // COLOR ALPHA ----------------------------- /** * Alpha Color Picker JS */ ( function ( $ ) { /** * Override the stock color.js toString() method to add support for * outputting RGBa or Hex. */ if (typeof Color !== 'undefined') { Color.prototype.toString = function ( flag ) { // If our no-alpha flag has been passed in, output RGBa value with 100% opacity. // This is used to set the background color on the opacity slider during color changes. if ( 'no-alpha' == flag ) { return this.toCSS( 'rgba', '1' ).replace( /\s+/g, '' ); } // If we have a proper opacity value, output RGBa. if ( 1 > this._alpha ) { return this.toCSS( 'rgba', this._alpha ).replace( /\s+/g, '' ); } // Proceed with stock color.js hex output. var hex = parseInt( this._color, 10 ).toString( 16 ); if ( this.error ) { return ''; } if ( 6 > hex.length ) { for ( var i = 6 - hex.length - 1; 0 <= i; i-- ) { hex = '0' + hex; } } return '#' + hex; }; } /** * Given an RGBa, RGB, or hex color value, return the alpha channel value. */ function acp_get_alpha_value_from_color( value ) { var alphaVal; // Remove all spaces from the passed in value to help our RGBa regex. value = value.replace( / /g, '' ); if ( value.match( /rgba\(\d+\,\d+\,\d+\,([^\)]+)\)/ ) ) { alphaVal = parseFloat( value.match( /rgba\(\d+\,\d+\,\d+\,([^\)]+)\)/ )[1] ).toFixed( 2 ) * 100; alphaVal = parseInt( alphaVal ); } else { alphaVal = 100; } return alphaVal; } /** * Force update the alpha value of the color picker object and maybe the alpha slider. */ function acp_update_alpha_value_on_color_input( alpha, $input, $alphaSlider, update_slider ) { var iris, colorPicker, color; iris = $input.data( 'a8cIris' ); colorPicker = $input.data( 'wpWpColorPicker' ); // Set the alpha value on the Iris object. iris._color._alpha = alpha; // Store the new color value. color = iris._color.toString(); // Set the value of the input. $input.val( color ); $input.trigger( 'color_change' ); // Update the background color of the color picker. colorPicker.toggler.css( { 'background-color': color } ); // Maybe update the alpha slider itself. if ( update_slider ) { acp_update_alpha_value_on_alpha_slider( alpha, $alphaSlider ); } // Update the color value of the color picker object. $input.wpColorPicker( 'color', color ); } /** * Update the slider handle position and label. */ function acp_update_alpha_value_on_alpha_slider( alpha, $alphaSlider ) { $alphaSlider.slider( 'value', alpha ); $alphaSlider.find( '.ui-slider-handle' ).text( alpha.toString() ); } $.fn.alphaColorPicker = function () { return this.each( function () { // Scope the vars. var $input, startingColor, paletteInput, showOpacity, defaultColor, palette, colorPickerOptions, $container, $alphaSlider, alphaVal, sliderOptions; // Store the input. $input = $( this ); // We must wrap the input now in order to get our a top level class // around the HTML added by wpColorPicker(). $input.wrap( '
' ); // Get some data off the input. paletteInput = $input.attr( 'data-palette' ) || 'true'; showOpacity = $input.attr( 'data-show-opacity' ) || 'true'; defaultColor = $input.attr( 'data-default-color' ) || ''; // Process the palette. if ( -1 !== paletteInput.indexOf( '|' ) ) { palette = paletteInput.split( '|' ); } else if ( 'false' == paletteInput ) { palette = false; } else { palette = true; } // Get a clean starting value for the option. startingColor = $input.val().replace( /\s+/g, '' ); // startingColor = $input.val().replace( '#', '' ); // If we don't yet have a value, use the default color. if ( '' == startingColor ) { startingColor = defaultColor; } // Set up the options that we'll pass to wpColorPicker(). colorPickerOptions = { change: function ( event, ui ) { var key, value, alpha, $transparency; key = $input.attr( 'data-customize-setting-link' ); value = $input.wpColorPicker( 'color' ); // Set the opacity value on the slider handle when the default color button is clicked. if ( defaultColor == value ) { alpha = acp_get_alpha_value_from_color( value ); $alphaSlider.find( '.ui-slider-handle' ).text( alpha ); } // If we're in the Customizer, send an ajax request to wp.customize // to trigger the Save action. if ( 'undefined' != typeof wp.customize ) { wp.customize( key, function ( obj ) { obj.set( value ); } ); } $transparency = $container.find( '.transparency' ); // Always show the background color of the opacity slider at 100% opacity. $transparency.css( 'background-color', ui.color.toString( 'no-alpha' ) ); $input.trigger( 'color_change' ); }, clear: function () { var key = $input.attr( 'data-customize-setting-link' ) || ''; if ( key && '' !== key ) { if ( 'undefined' != typeof wp.customize ) { wp.customize( key, function ( obj ) { obj.set( '' ); } ); } } $input.val( '' ); $input.trigger( 'color_change' ); }, palettes: palette // Use the passed in palette. }; // Create the colorpicker. $input.wpColorPicker( colorPickerOptions ); $container = $input.parents( '.wp-picker-container:first' ); // Insert our opacity slider. $( '
' + '
' + '
' + '
' + '
' + '
' ).appendTo( $container.find( '.wp-picker-holder' ) ); $alphaSlider = $container.find( '.alpha-slider' ); // If starting value is in format RGBa, grab the alpha channel. alphaVal = acp_get_alpha_value_from_color( startingColor ); // Set up jQuery UI slider() options. sliderOptions = { create: function ( event, ui ) { var value = $( this ).slider( 'value' ); // Set up initial values. $( this ).find( '.ui-slider-handle' ).text( value ); $( this ).siblings( '.transparency ' ).css( 'background-color', startingColor ); }, value: alphaVal, range: 'max', step: 1, min: 0, max: 100, animate: 300 }; // Initialize jQuery UI slider with our options. $alphaSlider.slider( sliderOptions ); // Maybe show the opacity on the handle. if ( 'true' == showOpacity ) { $alphaSlider.find( '.ui-slider-handle' ).addClass( 'show-opacity' ); } // Bind event handlers for the click zones. $container.find( '.min-click-zone' ).on( 'click', function () { acp_update_alpha_value_on_color_input( 0, $input, $alphaSlider, true ); } ); $container.find( '.max-click-zone' ).on( 'click', function () { acp_update_alpha_value_on_color_input( 100, $input, $alphaSlider, true ); } ); // Bind event handler for clicking on a palette color. $container.find( '.iris-palette' ).on( 'click', function () { var color, alpha; color = $( this ).css( 'background-color' ); alpha = acp_get_alpha_value_from_color( color ); acp_update_alpha_value_on_alpha_slider( alpha, $alphaSlider ); // Sometimes Iris doesn't set a perfect background-color on the palette, // for example rgba(20, 80, 100, 0.3) becomes rgba(20, 80, 100, 0.298039). // To compensante for this we round the opacity value on RGBa colors here // and save it a second time to the color picker object. if ( 100 != alpha ) { color = color.replace( /[^,]+(?=\))/, ( alpha / 100 ).toFixed( 2 ) ); } $input.wpColorPicker( 'color', color ); } ); // Bind event handler for clicking on the 'Default' button. $container.find( '.button.wp-picker-default' ).on( 'click', function () { var alpha = acp_get_alpha_value_from_color( defaultColor ); acp_update_alpha_value_on_alpha_slider( alpha, $alphaSlider ); } ); // Bind event handler for typing or pasting into the input. $input.on( 'input', function () { var value = $( this ).val(); var alpha = acp_get_alpha_value_from_color( value ); acp_update_alpha_value_on_alpha_slider( alpha, $alphaSlider ); } ); // Update all the things when the slider is interacted with. $alphaSlider.slider().on( 'slide', function ( event, ui ) { var alpha = parseFloat( ui.value ) / 100.0; acp_update_alpha_value_on_color_input( alpha, $input, $alphaSlider, false ); // Change value shown on slider handle. $( this ).find( '.ui-slider-handle' ).text( ui.value ); } ); } ); }; }( jQuery ) ); // WP COLOR ALPHA customizer ----------------------------- ( function ( api, $ ) { api.controlConstructor['alpha-color'] = api.Control.extend( { ready: function () { var control = this; $( '.alpha-color-control', control.container ).alphaColorPicker( { clear: function ( event, ui ) { } } ); } } ); }( wp.customize, jQuery ) ); // WP REPEATERABLE Customizer ----------------------------- ( function ( api, $ ) { api.controlConstructor['blogsy-repeater'] = api.Control.extend( { ready: function () { var control = this; setTimeout( function () { control._init(); }, 2500 ); }, eval: function ( valueIs, valueShould, operator ) { switch ( operator ) { case 'not_in': valueShould = valueShould.split( ',' ); if ( 0 > $.inArray( valueIs, valueShould ) ) { return true; } else { return false; } break; case 'in': valueShould = valueShould.split( ',' ); if ( -1 < $.inArray( valueIs, valueShould ) ) { return true; } else { return false; } break; case '!=': return valueIs != valueShould; case '<=': return valueIs <= valueShould; case '<': return valueIs < valueShould; case '>=': return valueIs >= valueShould; case '>': return valueIs > valueShould; case '==': case '=': return valueIs == valueShould; break; } }, compare: function ( value1, cond, value2 ) { var equal = false; var _v; switch ( cond ) { case '===': equal = ( value1 === value2 ) ? true : false; break; case '>': equal = ( value1 > value2 ) ? true : false; break; case '<': equal = ( value1 < value2 ) ? true : false; break; case '!=': equal = ( value1 != value2 ) ? true : false; break; case 'empty': _v = _.clone( value1 ); if ( _.isObject( _v ) || _.isArray( _v ) ) { _.each( _v, function ( v, i ) { if ( _.isEmpty( v ) ) { delete _v[i]; } } ); equal = _.isEmpty( _v ) ? true : false; } else { equal = _.isNull( _v ) || '' == _v ? true : false; } break; case 'not_empty': _v = _.clone( value1 ); if ( _.isObject( _v ) || _.isArray( _v ) ) { _.each( _v, function ( v, i ) { if ( _.isEmpty( v ) ) { delete _v[i]; } } ); } equal = _.isEmpty( _v ) ? false : true; break; default: equal = ( value1 == value2 ) ? true : false; } return equal; }, multiple_compare: function ( list, values ) { var control = this; var check = true; try { var test = list[0]; check = true; if ( _.isString( test ) ) { check = false; var cond = list[1]; var cond_val = list[2]; var value; if ( ! _.isUndefined( values[test] ) ) { value = values[test]; check = control.compare( value, cond, cond_val ); } } else if ( _.isArray( test ) ) { check = true; _.each( list, function ( req ) { var cond_key = req[0]; var cond_cond = req[1]; var cond_val = req[2]; var t_val = values[cond_key]; if ( _.isUndefined( t_val ) ) { t_val = ''; } if ( ! control.compare( t_val, cond_cond, cond_val ) ) { check = false; } } ); } } catch ( e ) { check = false; } return check; }, conditionize: function ( $context ) { var control = this; if ( $context.hasClass( 'conditionized' ) ) { return; } $context.addClass( 'conditionized' ); var $fields = $( '.field--item', $context ); $context.on( 'change condition_check', 'input, select, textarea', function ( e ) { var f = $( '.form', $context ); var data = $( 'input, textarea, select', f ).serialize(); data = jQuery.deparam( data ); var fieldData = {}; if ( _.isObject( data ) ) { _.each( data._items, function ( value ) { fieldData = value; } ); } $fields.each( function () { var $field = $( this ); var check = true; var req = $field.attr( 'data-cond' ) || false; if ( ! _.isUndefined( req ) && req ) { req = JSON.parse( req ); check = control.multiple_compare( req, fieldData ); if ( ! check ) { $field.hide().addClass( 'cond-hide' ).removeClass( 'cond-show' ); } else { $field.slideDown().removeClass( 'cond-hide' ).addClass( 'cond-show' ); } } } ); } ); /** * Current support one level only */ $( 'input, select, textarea', $context ).eq( 0 ).trigger( 'condition_check' ); }, remove_editor: function ( $context ) { }, editor: function ( $textarea ) { }, _init: function () { var control = this; var default_data = control.params.fields; var values; try { if ( 'string' == typeof control.params.value ) { values = JSON.parse( control.params.value ); } else { values = control.params.value; } } catch ( e ) { values = {}; } var max_item = 0; // unlimited var limited_mg = control.params.limited_msg || ''; if ( ! isNaN( parseInt( control.params.max_item ) ) ) { max_item = parseInt( control.params.max_item ); } if ( 'no' === control.params.changeable ) { // control.container.addClass( 'no-changeable' ); } /** * Toggle show/hide item */ control.container.on( 'click', '.widget .widget-action, .widget .repeat-control-close, .widget-title', function ( e ) { e.preventDefault(); var p = $( this ).closest( '.widget' ); if ( p.hasClass( 'explained' ) ) { $( '.widget-inside', p ).slideUp( 200, 'linear', function () { $( '.widget-inside', p ).removeClass( 'show' ).addClass( 'hide' ); p.removeClass( 'explained' ); } ); } else { $( '.widget-inside', p ).slideDown( 200, 'linear', function () { $( '.widget-inside', p ).removeClass( 'hide' ).addClass( 'show' ); p.addClass( 'explained' ); } ); } } ); /** * Remove repeater item */ control.container.on( 'click', '.repeat-control-remove', function ( e ) { e.preventDefault(); var $context = $( this ).closest( '.repeatable-customize-control' ); $( 'body' ).trigger( 'repeat-control-remove-item', [ $context ] ); control.remove_editor( $context ); $context.remove(); control.rename(); control.updateValue(); control._check_max_item(); } ); /** * Get customizer control data * * @returns {*} */ control.getData = function () { var f = $( '.form-data', control.container ); var data = $( 'input, textarea, select', f ).serialize(); return JSON.stringify( data ); }; /** * Update repeater value */ control.updateValue = function () { var data = control.getData(); // $("[data-hidden-value]", control.container).val(data); // $("[data-hidden-value]", control.container).trigger('change'); control.setting.set( data ); }; control.update_value = function () { var self = this, value = {}, option; self.container.find( '[data-option]' ).each( function () { option = $( this ).data( 'option' ); if ( 'background-size' === option || 'background-attachment' === option ) { value[option] = $( this ).is( ':checked' ) ? $( this ).val() : value[option]; } else { value[option] = $( this ).val(); } } ); self.setting.set( value ); }; /** * Rename repeater item */ control.rename = function () { $( '.list-repeatable li', control.container ).each( function ( index ) { var li = $( this ); $( 'input, textarea, select', li ).each( function () { var input = $( this ); var name = input.attr( 'data-repeat-name' ) || undefined; if ( 'undefined' !== typeof name ) { name = name.replace( /__i__/g, index ); input.attr( 'name', name ); } } ); } ); }; control.autocorrect_range_input_number = function ( input_number, timeout ) { var range_input = input_number, range = range_input.parent().find( 'input[type="range"]' ), value = parseFloat( range_input.val() ), reset = parseFloat( range.find( '.blogsy-reset-range' ).attr( 'data-reset_value' ) ), step = parseFloat( range_input.attr( 'step' ) ), min = parseFloat( range_input.attr( 'min' ) ), max = parseFloat( range_input.attr( 'max' ) ); clearTimeout( timeout ); timeout = setTimeout( function () { if ( isNaN( value ) ) { range_input.val( reset ); range.val( reset ).trigger( 'change' ); return; } if ( 1 <= step && 0 !== value % 1 ) { value = Math.round( value ); range_input.val( value ); range.val( value ).trigger( 'change' ); } if ( value > max ) { range_input.val( max ); range.val( max ).trigger( 'change' ); } if ( value < min ) { range_input.val( min ); range.val( min ).trigger( 'change' ); } }, timeout ); range.val( value ).trigger( 'change' ); control.updateValue(); }; if ( ! window._upload_blogsy ) { // var insertImage = wp.media.controller.Library.extend({ // defaults : _.defaults({ // id: 'insert-image', // title: 'Insert Image Url', // allowLocalEdits: true, // displaySettings: true, // displayUserSettings: true, // multiple : false, // type : 'image'//audio, video, application/pdf, ... etc // }, wp.media.controller.Library.prototype.defaults ) // }); window._upload_blogsy = wp.media( { title: wp.media.view.l10n.addMedia, multiple: false // frame : 'post' // library: {type: 'all' }, // button : { text : 'Insert' } } ); } window._upload_blogsy.on( 'close', function () { // get selections and save to hidden input plus other AJAX stuff etc. var selection = window._upload_blogsy.state().get( 'selection' ); } ); window.media_current = {}; window.media_btn = {}; window._upload_blogsy.on( 'select', function () { // Grab our attachment selection and construct a JSON representation of the model. var media_attachment = window._upload_blogsy.state().get( 'selection' ).first().toJSON(); $( '.image_id', window.media_current ).val( media_attachment.id ); var preview, img_url; img_url = media_attachment.url; $( '.current', window.media_current ).removeClass( 'hide' ).addClass( 'show' ); $( '.image_url', window.media_current ).val( img_url ); if ( 'image' == media_attachment.type ) { preview = ''; $( '.thumbnail-image', window.media_current ).html( preview ); } $( '.remove-button', window.media_current ).show(); $( '.image_id', window.media_current ).trigger( 'change' ); try { window.media_btn.text( window.media_btn.attr( 'data-change-txt' ) ); } catch ( e ) { } } ); control.handleMedia = function ( $context ) { $( '.item-media', $context ).each( function () { var _item = $( this ); // when remove item $( '.remove-button', _item ).on( 'click', function ( e ) { e.preventDefault(); $( '.image_id, .image_url', _item ).val( '' ); $( '.thumbnail-image', _item ).html( '' ); $( '.current', _item ).removeClass( 'show' ).addClass( 'hide' ); $( this ).hide(); $( '.upload-button', _item ).text( $( '.upload-button', _item ).attr( 'data-add-txt' ) ); $( '.image_id', _item ).trigger( 'change' ); } ); // when upload item $( '.upload-button, .attachment-media-view', _item ).on( 'click', function ( e ) { e.preventDefault(); window.media_current = _item; window.media_btn = $( this ); window._upload_blogsy.open(); } ); } ); }; control.handleGradient = function ( $context ) { var control = this, setting = control.setting.get(), range, range_input, value, blogsy_range_input_number_timeout, popup_content = control.container.find( '.popup-content' ); // Range controls. $( '.item-gradient', $context ).each( function () { var _item = $( this ); _item.find( '.blogsy-range-wrapper' ).each( function () { var $this = $( this ); $this.rangeControl( { id: control.params.id + '-' + $this.data( 'option-id' ), option: $this.data( 'option-id' ), value: setting[$this.data( 'options-id' )], responsive: control.params.responsive, change: function () { control.update_value(); } } ); // Change the text value $this.find( 'input.blogsy-range-input' ).on( 'change keyup', function () { control.autocorrect_range_input_number( $( this ), 1000, blogsy_range_input_number_timeout ); } ).on( 'focusout', function () { control.autocorrect_range_input_number( $( this ), 0, blogsy_range_input_number_timeout ); } ); } ); // Visibility deps. _item.on( 'change', '[data-option="background-type"], [data-option="gradient-type"]', function () { var field = $( this ).attr( 'data-option' ); _item.find( '[data-dep-field="' + field + '"]' ).hide(); _item.find( '[data-dep-field="' + field + '"][data-dep-value="' + $( this ).val() + '"]' ).show(); } ); _item.find( '[data-option="background-type"], [data-option="gradient-type"]' ).trigger( 'change' ); _item.on( 'change', '.blogsy-select-wrapper', function () { control.update_value(); } ); } ); }; control.handleBackground = function ( $context ) { var control = this, setting = control.setting.get(), range, range_input, value, blogsy_range_input_number_timeout, popup_content = control.container.find( '.popup-content' ); // Range controls. $( '.item-design-options', $context ).each( function () { var _item = $( this ); _item.find( '.blogsy-range-wrapper' ).each( function () { var $this = $( this ); $this.rangeControl( { id: control.params.id + '-' + $this.data( 'option-id' ), option: $this.data( 'option-id' ), value: setting[$this.data( 'options-id' )], responsive: control.params.responsive, change: function () { control.update_value(); } } ); // Change the text value $this.find( 'input.blogsy-range-input' ).on( 'change keyup', function () { control.autocorrect_range_input_number( $( this ), 1000, blogsy_range_input_number_timeout ); } ).on( 'focusout', function () { control.autocorrect_range_input_number( $( this ), 0, blogsy_range_input_number_timeout ); } ); } ); // Visibility deps. _item.on( 'change', '[data-option="background-type"], [data-option="gradient-type"]', function () { var field = $( this ).attr( 'data-option' ); _item.find( '[data-dep-field="' + field + '"]' ).hide(); _item.find( '[data-dep-field="' + field + '"][data-dep-value="' + $( this ).val() + '"]' ).show(); } ); _item.find( '[data-option="background-type"], [data-option="gradient-type"]' ).trigger( 'change' ); _item.on( 'change', '.blogsy-select-wrapper', function () { control.update_value(); } ); // Advanced panel. _item.find( '.popup-link' ).on( 'click', function () { popup_content.toggleClass( 'hidden' ); $( this ).toggleClass( 'active' ); $( this ).siblings( '.reset-defaults' ).toggleClass( 'active' ); // Close the panel on outside click. $( 'body' ).on( 'click', outside_click_close ); } ); var outside_click_close = function ( e ) { if ( ! $( e.target ).closest( '.customize-save-button-wrapper' ).length && ! _item.has( $( e.target ).closest( '.popup-link' ) ).length && ! _item.has( $( e.target ).closest( '.popup-content' ) ).length && ! popup_content.hasClass( 'hidden' ) && ! $( e.target ).closest( '.reset-defaults' ).length ) { popup_content.addClass( 'hidden' ); _item.find( '.popup-link' ).removeClass( 'active' ); _item.find( '.reset-defaults' ).removeClass( 'active' ); $( 'body' ).off( 'click', outside_click_close ); } }; // Hide unnecessary controls. _item.find( '.background-image-advanced' ).hide(); // Background-Repeat. _item.on( 'change', '.background-repeat select', function () { control.update_value(); } ); // Background-Size. _item.on( 'change click', '.background-size input', function () { control.update_value(); } ); // Background-Attachment. _item.on( 'change click', '.background-attachment input', function () { control.update_value(); } ); // Background-Image. _item.on( 'click', '.background-image-upload-button', function ( e ) { $( 'body' ).off( 'click', outside_click_close ); var image = wp.media( { multiple: false, title: control.params.l10n.image.select_image, button: { text: control.params.l10n.image.use_image } } ).open().on( 'select', function () { // This will return the selected image from the Media Uploader, the result is an object. var uploadedImage = image.state().get( 'selection' ).first(), uploadedImageJSON = uploadedImage.toJSON(), previewImage, imageUrl, imageID, imageWidth, imageHeight, preview, removeButton; if ( ! _.isUndefined( uploadedImageJSON.sizes ) ) { if ( ! _.isUndefined( uploadedImageJSON.sizes.medium ) ) { previewImage = uploadedImageJSON.sizes.medium.url; } else if ( ! _.isUndefined( uploadedImageJSON.sizes.thumbnail ) ) { previewImage = uploadedImageJSON.sizes.thumbnail.url; } else if ( ! _.isUndefined( uploadedImageJSON.sizes.full ) ) { previewImage = uploadedImageJSON.sizes.full.url; } else { previewImage = uploadedImageJSON.url; } } else { previewImage = uploadedImageJSON.url; } imageUrl = uploadedImageJSON.url; imageID = uploadedImageJSON.id; imageWidth = uploadedImageJSON.width; imageHeight = uploadedImageJSON.height; // Show extra controls if the value has an image. if ( '' !== imageUrl ) { _item.find( '.background-image-advanced' ).show(); _item.find( '.advanced-settings' ).removeClass( 'hidden' ).addClass( 'up' ); } _item.find( '[data-option="background-image"]' ).val( imageUrl ); _item.find( '[data-option="background-image-id"]' ).val( imageID ); control.update_value(); preview = _item.find( '.placeholder, .thumbnail' ); removeButton = _item.find( '.background-image-upload-remove-button' ); if ( preview.length ) { preview.removeClass().addClass( 'thumbnail thumbnail-image' ).html( '' ); } if ( removeButton.length ) { removeButton.show(); } setTimeout( function () { $( 'body' ).on( 'click', outside_click_close ); }, 100 ); } ); e.preventDefault(); } ); _item.on( 'click', '.background-image-upload-remove-button', function ( e ) { var preview, removeButton; e.preventDefault(); _item.find( '[data-option="background-image"]' ).val( '' ); _item.find( '[data-option="background-image-id"]' ).val( '' ); control.update_value(); preview = _item.find( '.placeholder, .thumbnail' ); removeButton = _item.find( '.background-image-upload-remove-button' ); // Hide unnecessary controls. _item.find( '.background-image-advanced' ).hide(); _item.find( '.advanced-settings' ).addClass( 'hidden' ).removeClass( 'up' ); if ( preview.length ) { preview.removeClass().addClass( 'placeholder' ).html( control.params.l10n.image.placeholder ); } if ( removeButton.length ) { removeButton.hide(); } } ); _item.on( 'click', '.advanced-settings', function ( e ) { $( this ).toggleClass( 'up' ); _item.find( '.background-image-advanced' ).toggle(); } ); // Spacing field. // Linked button _item.on( 'click', '.blogsy-spacing-linked', function () { // Set up variables var $this = $( this ); // Remove linked class $this.closest( 'ul' ).find( '.spacing-input' ).removeClass( 'linked' ); // Remove class $this.parent( '.spacing-link-values' ).removeClass( 'unlinked' ); } ); // Unlinked button _item.on( 'click', '.blogsy-spacing-unlinked', function () { // Set up variables var $this = $( this ); // Remove linked class $this.closest( 'ul' ).find( '.spacing-input' ).addClass( 'linked' ); // Remove class $this.parent( '.spacing-link-values' ).addClass( 'unlinked' ); } ); // Values linked inputs _item.on( 'input', '.linked input', function () { var $val = $( this ).val(); $( this ).closest( '.spacing-input' ).siblings( '.linked' ).find( 'input' ).val( $val ).change(); } ); // Store new inputs _item.on( 'change input', '.spacing-input input', function () { control.update_value(); } ); // Reset default. _item.find( '.reset-defaults' ).on( 'click', function () { var item, option_id; _item.find( '[data-option]' ).each( function () { item = $( this ); option_id = item.data( 'option' ); if ( 'background-size' === option_id || 'background-attachment' === option_id ) { item.prop( 'checked', false ); if ( ( option_id in control.params.default ) && control.params.default[option_id] === item.val() ) { item.prop( 'checked', true ); } } else { item.val( control.params.default[item.data( 'option' )] ).trigger( 'change' ); } } ); _item.find( '.background-image-upload-remove-button' ).click(); control.update_value(); } ); } ); }; control.linkPicker = function ( $context ) { if (item_link = $context.find( '.blogsy-field-link' )) { const a = new BlogsyLinkField( item_link ); a.init(); } } /** * Init color picker * * @param $context */ control.colorPicker = function ( $context ) { // Add Color Picker to all inputs that have 'color-field' class $( '.c-color', $context ).wpColorPicker( { change: function ( event, ui ) { setTimeout(() => { control.updateValue(); }, 0); }, clear: function ( event, ui ) { setTimeout(() => { control.updateValue(); }, 0); }, } ); $( '.c-coloralpha', $context ).each( function () { var input = $( this ); var c = input.val(); // c = c.replace('#', ''); input.removeAttr( 'value' ); input.prop( 'value', c ); input.alphaColorPicker( { change: function ( event, ui ) { setTimeout(() => { control.updateValue(); }, 0); }, clear: function ( event, ui ) { setTimeout(() => { control.updateValue(); }, 0); } } ); } ); }; /** * Live title events * * @param $context */ control.actions = function ( $context ) { if ( control.params.live_title_id ) { if ( ! $context.attr( 'data-title-format' ) ) { $context.attr( 'data-title-format', control.params.title_format ); } var format = $context.attr( 'data-title-format' ) || ''; // Custom for special ID if ( 'blogsy_section_order_styling' === control.id ) { if ( 'click' !== $context.find( 'input.add_by' ).val() ) { format = '[live_title]'; } } // Live title if ( control.params.live_title_id && 0 < $( '[data-live-id=\'' + control.params.live_title_id + '\']', $context ).length ) { var v = ''; if ( $( '[data-live-id=\'' + control.params.live_title_id + '\']', $context ).is( '.select-one' ) ) { v = $( '[data-live-id=\'' + control.params.live_title_id + '\']', $context ).find( 'option:selected' ).eq( 0 ).text(); } else if( $( '[data-live-id=\'' + control.params.live_title_id + '\']', $context ).is( '.input-url' ) ) { v = $( '[data-live-id=\'' + control.params.live_title_id + '\']', $context ).prev().val(); } else { v = $( '[data-live-id=\'' + control.params.live_title_id + '\']', $context ).eq( 0 ).val(); } if ( '' == v ) { v = control.params.default_empty_title; } if ( '' !== format ) { v = format.replace( '[live_title]', v ); } $( '.widget-title .live-title', $context ).text( v ); $context.on( 'keyup change', '[data-live-id=\'' + control.params.live_title_id + '\']', function () { var v = ''; var format = $context.attr( 'data-title-format' ) || ''; // custom for special ID if ( 'blogsy_section_order_styling' === control.id ) { if ( 'click' !== $context.find( 'input.add_by' ).val() ) { format = '[live_title]'; } } if ( $( this ).is( '.select-one' ) ) { v = $( this ).find( 'option:selected' ).eq( 0 ).text(); } else if( $( this ).is( '.input-url' ) ){ v = $( this ).prev().val(); }else { v = $( this ).val(); } if ( '' == v ) { v = control.params.default_empty_title; } if ( '' !== format ) { v = format.replace( '[live_title]', v ); } $( '.widget-title .live-title', $context ).text( v ); } ); } else { } } else { // $('.widget-title .live-title', $context).text( control.params.title_format ); } }; /** * Check limit number item * * @private */ control._check_max_item = function () { var n = $( '.list-repeatable > li.repeatable-customize-control', control.container ).length; if ( n >= max_item ) { $( '.repeatable-actions', control.container ).hide(); if ( 0 >= $( '.limited-msg', control.container ).length ) { if ( '' !== limited_mg ) { var msg = $( '

' ); msg.html( limited_mg ); msg.insertAfter( $( '.repeatable-actions', control.container ) ); msg.show(); } } else { $( '.limited-msg', control.container ).show(); } } else { $( '.repeatable-actions', control.container ).show(); $( '.limited-msg', control.container ).hide(); } }; /** * Function that loads the Mustache template */ control.repeaterTemplate = _.memoize( function () { var compiled, /* * Underscore's default ERB-style templates are incompatible with PHP * when asp_tags is enabled, so WordPress uses Mustache-inspired templating syntax. * * @see trac ticket #22344. */ options = { evaluate: /<#([\s\S]+?)#>/g, interpolate: /\{\{\{([\s\S]+?)\}\}\}/g, escape: /\{\{([^\}]+?)\}\}(?!\})/g, variable: 'data' }; return function ( data ) { if ( 'undefined' === typeof window.repeater_item_tpl ) { window.repeater_item_tpl = $( '#repeatable-js-item-tpl' ).html(); } compiled = _.template( window.repeater_item_tpl, null, options ); return compiled( data ); }; } ); control.template = control.repeaterTemplate(); /** * Init item events * * @param $context */ control.intItem = function ( $context ) { control.rename(); control.conditionize( $context ); control.colorPicker( $context ); control.linkPicker( $context ); control.handleMedia( $context ); control.handleGradient( $context ); control.handleBackground( $context ); // Special check element $( '[data-live-id="section_id"]', $context ).each( function () { $( this ).closest( '.repeatable-customize-control' ).addClass( 'section-' + $( this ).val() ); if ( 'map' === $( this ).val() ) { $context.addClass( 'show-display-field-only' ); } } ); // Custom for special IDs if ( 'blogsy_section_order_styling' === control.id ) { if ( 'click' !== $context.find( 'input.add_by' ).val() ) { $context.addClass( 'no-changeable' ); // Remove because we never use $( '.item-editor textarea', $context ).remove(); } else { $context.find( '.item-title' ).removeClass( 'item-hidden ' ); $context.find( '.item-title input[type="hidden"]' ).attr( 'type', 'text' ); $context.find( '.item-section_id' ).removeClass( 'item-hidden ' ); $context.find( '.item-section_id input[type="hidden"]' ).attr( 'type', 'text' ); } } // Setup editor $( '.item-editor textarea', $context ).each( function () { control.editor( $( this ) ); } ); // Setup editor $( 'body' ).trigger( 'repeater-control-init-item', [ $context ] ); }; /** * Drag to sort items */ $( '.list-repeatable', control.container ).sortable( { handle: '.widget-title', //containment: ".customize-control-repeatable", containment: control.container, // placeholder: "sortable-placeholder", update: function ( event, ui ) { control.rename(); control.updateValue(); } } ); /** * Create existing items */ _templateData = $.extend( true, {}, control.params.fields ); var _templateData; $.each( values, function ( i, _values ) { _values = values[i]; if ( _values ) { for ( var j in _values ) { if ( _templateData.hasOwnProperty( j ) && _values.hasOwnProperty( j ) ) { _templateData[j].value = _values[j]; } } } var $html = $( control.template( _templateData ) ); $( '.list-repeatable', control.container ).append( $html ); control.intItem( $html ); control.actions( $html ); } ); /** * Add new item */ control.container.on( 'click', '.add-new-repeat-item', function () { var $html = $( control.template( default_data ) ); $( '.list-repeatable', control.container ).append( $html ); // add unique ID for section if id_key is set if ( '' !== control.params.id_key ) { $html.find( '.item-' + control.params.id_key ).find( 'input' ).val( 'sid' + ( new Date().getTime() ) ); } $html.find( 'input.add_by' ).val( 'click' ); control.intItem( $html ); control.actions( $html ); control.updateValue(); control._check_max_item(); } ); /** * Update repeater data when any events fire. */ $( '.list-repeatable', control.container ).on( 'keyup change color_change', 'input, select, textarea', function ( e ) { control.updateValue(); } ); control._check_max_item(); } } ); }( wp.customize, jQuery ) ); /** * Icon picker */ jQuery( document ).ready( function ( $ ) { window.editing_icon = false; var icon_picker = $( '

' ); var options_font_type = '', icon_group = ''; $.each( Blogsy_Icon_Picker.fonts, function ( key, font ) { font = $.extend( {}, { url: '', name: '', prefix: '', icons: '' }, font ); $( '' ) .appendTo( 'head' ) .attr( { type: 'text/css', rel: 'stylesheet' } ) .attr( 'id', 'customizer-icon-' + key ) .attr( 'href', font.url ); options_font_type += ''; var icons_array = font.icons.split( '|' ); icon_group += ''; } ); icon_picker.find( '.c-icon-search input' ).attr( 'placeholder', Blogsy_Icon_Picker.search ); icon_picker.find( '.c-icon-type' ).html( options_font_type ); icon_picker.find( '.c-icon-list' ).append( icon_group ); $( '.wp-full-overlay' ).append( icon_picker ); // Change icon type $( 'body' ).on( 'change', 'select.c-icon-type', function () { var t = $( this ).val(); icon_picker.find( '.ic-icons-group' ).hide(); icon_picker.find( '.ic-icons-group[data-group-name="' + t + '"]' ).show(); } ); icon_picker.find( 'select.c-icon-type' ).trigger( 'change' ); // When type to search $( 'body' ).on( 'keyup', '.c-icon-search input', function () { var v = $( this ).val(); if ( '' == v ) { $( '.c-icon-list span' ).show(); } else { $( '.c-icon-list span' ).hide(); try { $( '.c-icon-list span[data-name*="' + v + '"]' ).show(); } catch ( e ) { } } } ); // Edit icon $( 'body' ).on( 'click', '.icon-wrapper', function ( e ) { e.preventDefault(); var icon = $( this ); window.editing_icon = icon; icon_picker.addClass( 'ic-active' ); $( 'body' ).find( '.icon-wrapper' ).removeClass( 'icon-editing' ); icon.addClass( 'icon-editing' ); } ); // Remove icon $( 'body' ).on( 'click', '.item-icon .remove-icon', function ( e ) { e.preventDefault(); var item = $( this ).closest( '.item-icon' ); item.find( '.icon-wrapper input' ).val( '' ); item.find( '.icon-wrapper input' ).trigger( 'change' ); item.find( '.icon-wrapper i' ).attr( 'class', '' ); $( 'body' ).find( '.icon-wrapper' ).removeClass( 'icon-editing' ); } ); // Selected icon $( 'body' ).on( 'click', '.c-icon-list span', function ( e ) { e.preventDefault(); var icon_name = $( this ).attr( 'data-name' ) || ''; if ( window.editing_icon ) { window.editing_icon.find( 'i' ).attr( 'class', '' ).addClass( $( this ).find( 'i' ).attr( 'class' ) ); window.editing_icon.find( 'input' ).val( icon_name ).trigger( 'change' ); } icon_picker.removeClass( 'ic-active' ); window.editing_icon = false; $( 'body' ).find( '.icon-wrapper' ).removeClass( 'icon-editing' ); } ); $( document ).mouseup( function ( e ) { if ( window.editing_icon ) { if ( ! window.editing_icon.is( e.target ) // if the target of the click isn't the container... && 0 === window.editing_icon.has( e.target ).length // ... nor a descendant of the container && ( ! icon_picker.is( e.target ) && 0 === icon_picker.has( e.target ).length ) ) { icon_picker.removeClass( 'ic-active' ); // window.editing_icon = false; } } } ); } );