( function( $ ) { /* Internal shorthand */ var api = wp.customize; /** * Helper class for the main Customizer interface. * * @since 1.2.0 * @class FLCustomizer */ FLCustomizer = { /** * Initializes our custom logic for the Customizer. * * @since 1.2.0 * @method init */ init: function() { FLCustomizer._initEvents(); FLCustomizer._initToggles(); FLCustomizer._initFonts(); FLCustomizer._initPresets(); FLCustomizer._initCodeEditors(); FLCustomizer._initSliderControl(); FLCustomizer._initCheckboxMultiple(); FLCustomizer._initHeadingControls(); FLCustomizer._initResponsiveControls(); }, /** * Initializes custom events for the Customizer. * * @since 1.3.3 * @method _initEvents */ _initEvents: function() { $( '.fl-preview-button' ).on( 'click', function() { wp.customize.previewer.refresh(); } ); }, /** * Initializes the logic for showing and hiding controls * when a setting changes. * * @since 1.2.0 * @access private * @method _initToggles */ _initToggles: function() { // Loop through each setting. $.each(FLCustomizerToggles, function( settingId, toggles ) { // Get the setting object. api( settingId, function( setting ) { // Loop though the toggles for the setting. $.each( toggles, function( i, toggle ) { // Loop through the controls for the toggle. $.each( toggle.controls, function( k, controlId ) { // Get the control object. api.control( controlId, function( control ) { // Define the visibility callback. var visibility = function( to ) { control.container.toggle( toggle.callback( to ) ); }; // Init visibility. visibility( setting.get() ); // Bind the visibility callback to the setting. setting.bind( visibility ); }); }); }); }); }); }, /** * Initializes logic for font controls. * * @since 1.2.0 * @access private * @method _initFonts */ _initFonts: function() { $( '.customize-control-font select' ).each( FLCustomizer._initFont ); }, /** * Initializes logic for a single font control. * * @since 1.2.0 * @access private * @method _initFont */ _initFont: function() { var select = $( this ), link = select.data( 'customize-setting-link' ), weight = select.data( 'connected-control' ); if ( 'undefined' != typeof weight ) { api( link ).bind( FLCustomizer._fontSelectChange ); FLCustomizer._setFontWeightOptions.apply( api( link ), [ true ] ); } }, /** * Callback for when a font control changes. * * @since 1.2.0 * @access private * @method _fontSelectChange */ _fontSelectChange: function() { FLCustomizer._setFontWeightOptions.apply( this, [ false ] ); }, /** * Sets the options for a font weight control when a * font family control changes. * * @since 1.2.0 * @access private * @method _setFontWeightOptions * @param {Boolean} init Whether or not we're initializing this font weight control. */ _setFontWeightOptions: function( init ) { var i = 0, fontSelect = api.control( this.id ).container.find( 'select' ), fontValue = this(), selected = '', weightKey = fontSelect.data( 'connected-control' ), weightSelect = api.control( weightKey ).container.find( 'select' ), weightValue = init ? weightSelect.val() : '400', weightObject = null, weightOptions = '', weightMap = FLFontFamilies.weights; if ( 'undefined' != typeof FLFontFamilies.system[ fontValue ] ) { weightObject = FLFontFamilies.system[ fontValue ].weights; } else if ( 'undefined' != typeof FLFontFamilies.google[ fontValue ] ) { weightObject = FLFontFamilies.google[ fontValue ]; } else { return false; } for ( ; i < weightObject.length; i++ ) { if ( 0 === i && -1 === $.inArray( weightValue, weightObject ) ) { weightValue = weightObject[ 0 ]; selected = ' selected="selected"'; } else { selected = weightObject[ i ] == weightValue ? ' selected="selected"' : ''; } weightOptions += ''; } weightSelect.html( weightOptions ); if ( ! init ) { api( weightKey ).set( '' ); api( weightKey ).set( weightValue ); } }, /** * Initializes logic for settings presets. * * @since 1.2.0 * @access private * @method _initPresets */ _initPresets: function() { if ( typeof api.control( 'fl-preset' ) !== 'undefined' ) { api.control( 'fl-preset' ).container.find( 'select' ).on( 'change', FLCustomizer._presetChange ); } }, /** * Callback for when the preset control changes. * * @since 1.2.0 * @access private * @method _presetChange */ _presetChange: function() { var val = $( this ).val(), settings = $.extend( {}, FLCustomizerPresetDefaults, FLCustomizerPresets[ val ].settings ), control = null, picker = null; // Loop the settings. for ( key in settings ) { // Get the control instance. control = api.control.instance( key ); // Set the preset setting. control.setting.set( settings[ key ] ); // Update the color picker if a color control. picker = control.container.find( '.color-picker-hex' ); if ( picker.length > 0 ) { picker.wpColorPicker( 'color', settings[ key ] ); } } }, /** * Initializes code editor controls. * * @since 1.3.3 * @method _initCodeEditors */ _initCodeEditors: function() { ace.require( 'ace/ext/language_tools' ); $( '.fl-code-editor' ).each( function() { var editDiv = $( this ), editMode = editDiv.data( 'mode' ), editTextarea = editDiv.siblings( 'textarea' ), editor = ace.edit( editDiv[0] ); editTextarea.hide(); editor.$blockScrolling = Infinity; editor.renderer.setShowGutter( false ); editor.getSession().setValue( editTextarea.val() ); editor.getSession().setMode( 'ace/mode/' + editMode ); editor.setOptions({ enableBasicAutocompletion: true, enableLiveAutocompletion: true, enableSnippets: false }); editor.getSession().on( 'change', function( e ) { editTextarea.val( editor.getSession().getValue() ).trigger( 'change' ); }); } ); }, /** * Initializes the slider control. * * @since 1.5.0 * @method _initSliderControl */ _initSliderControl: function() { $( '.customize-control-slider .fl-slider-reset' ).click( function () { var $slider = $( this ).closest( 'label' ).find( 'input' ), $text_input = $( this ).closest( 'label' ).find( '#fl-range-value-input' ); default_value = $slider.data( 'reset_value' ); $slider.val( default_value ); $slider.change(); $text_input.val( default_value ); }); $( '.customize-control-slider input[type=range]' ).each(function() { var $slider = $(this), $text_input = $( this ).closest( 'label' ).find( '#fl-range-value-input' ), value = $slider.attr( 'value' ), min = $slider.attr( 'min' ); $slider.on('input', function () { value = $slider.attr( 'value' ); $text_input.val( value ); }); $text_input.on('keyup change', function(){ $slider.val($text_input.val()); $slider.change(); }); $text_input.on('focusout', function(){ if ( parseInt( $text_input.val() ) < min ) { $text_input.val( min ); $slider.change(); } }); }); }, /** * Initializes the multiple checkbox * * @since 1.5.3 * @method _initCheckboxMultiple */ _initCheckboxMultiple: function() { $( '.customize-control-checkbox-multiple input[type="checkbox"]' ).each(function(){ var $checkbox = $(this); $checkbox.on('change', function() { checkbox_values = $checkbox.parents( '.customize-control' ).find( 'input[type="checkbox"]:checked' ).map( function() { return this.value; } ).get().join( ',' ); $checkbox.parents( '.customize-control' ).find( 'input[type="hidden"]' ).val( checkbox_values ).trigger( 'change' ); }); }); }, /** * Initializes heading controls behavior * * @since 1.7 * @method _initHeadingControls */ _initHeadingControls: function() { // The controls we want to reposition var keys = [ 'fl-h1-font-size', 'fl-h1-line-height', 'fl-h1-letter-spacing', 'fl-h1-line' ], a = 5.0; // The new starting priority var controls = keys.map( function( key, i ) { var control = api.control( key ); return { i: i, key: key, control: control, initPriority: control.priority(), titlePriority: a + ( i * .1 ), } }); api( 'fl-heading-style', function( setting ) { // Initial positioning FLCustomizer._positionHeading1Controls( setting.get(), controls ); // On fl-heading-style changed setting.bind( function( value ) { FLCustomizer._positionHeading1Controls( value, controls ); } ); }); }, /** * Position the h1 controls based on which fl-heading-style option is selected. */ _positionHeading1Controls: function( value, controls ) { controls.map( function( item, i ) { var priority = 'title' === value ? item.titlePriority : item.initPriority; item.control.priority( priority ); }); }, _initResponsiveControls: function() { $( '.fl-responsive-customize-control' ).not('.desktop').hide(); var sendPreviewedDevice = function () { var previewedDevice = api.previewedDevice.get(), newDevice = 'tablet' == previewedDevice ? 'medium' : previewedDevice; api.previewer.send( 'previewed-device', newDevice ); } // Send the initial previewed device when preview is ready. api.previewer.bind( 'ready', sendPreviewedDevice ); api.previewedDevice.bind( function( new_device ) { new_device = 'tablet' == new_device ? 'medium' : new_device; $( '.fl-responsive-customize-control' ).hide(); $( '.fl-responsive-customize-control.' + new_device ).show(); sendPreviewedDevice(); }); }, }; $( function() { FLCustomizer.init(); } ); })( jQuery );