/**
* File epsilon.js.
*
*
* Epsilon Framework
*/
(function ($) {
var EpsilonFramework = {};
EpsilonFramework.rangeSliders = function (selector) {
var context = $(selector),
slider = context.find('.ss-slider'),
input = context.find('.rl-slider'),
input_id = input.attr('id'),
id = slider.attr('id'),
min = $('#' + id).attr('data-attr-min'),
max = $('#' + id).attr('data-attr-max'),
step = $('#' + id).attr('data-attr-step');
$('#' + id).slider({
value: $('#' + input_id).attr('value'),
range: 'min',
min : parseFloat(min),
max : parseFloat(max),
step : parseFloat(step),
slide: function (event, ui) {
$('#' + input_id).attr('value', ui.value).change();
}
});
$(input).on('focus', function () {
$(this).blur();
});
$('#' + input_id).attr('value', ($('#' + id).slider("value")));
$('#' + input_id).change(function () {
$('#' + id).slider({
value: $(this).val()
});
});
};
EpsilonFramework.typography = {
/**
* Selectize instance
*/
_selectize: null,
/**
* K/V Pair
*/
_linkedFonts: {},
/**
* Initiate function
* @private
*/
_init: function () {
var selector = $('.epsilon-typography-container');
if ( selector.length ) {
var self = this,
numbers = $('.epsilon-number-field');
$.each(selector, function () {
var container = $(this),
uniqueId = container.attr('data-unique-id'),
selects = container.find('select'),
inputs = container.find('.epsilon-typography-input');
/**
* Instantiate the selectize javascript plugin
* and the input type number
*/
try {
self._selectize = selects.selectize();
$.each(selects, function () {
self._linkedFonts[ $(selects[ 0 ]).attr('id') ] = $(selects[ 1 ]).attr('id');
});
}
catch ( err ) {
/**
* In case the selectize plugin is not loaded, raise an error
*/
console.warn('selectize not yet loaded');
}
/**
* On triggering the change event, create a json with the values and send it to the preview window
*/
inputs.on('change', function () {
var val = EpsilonFramework.typography._parseJson(inputs, uniqueId);
$('#hidden_input_' + uniqueId).val(val).trigger('change');
});
});
$.each(numbers, function () {
EpsilonFramework.typography._number($(this));
});
/**
* Add/subtract from the input type number fields
*/
$('.incrementor').on('click', function (e) {
e.preventDefault();
EpsilonFramework.typography._calcValue($(this));
});
/**
* Don't allow a value smaller than 0 in number fields
*/
numbers.find('input').on('change', function () {
if ( $(this).val() < 0 ) {
$(this).val(0).trigger('change');
}
});
$.each(self._linkedFonts, function ($id, $target) {
$('#' + $id).on('change', function () {
if ( $(this).val() === 'Select font' || $(this).val() === 'default_font' ) {
EpsilonFramework.typography._setSelects($(this).val(), $target, true);
}
EpsilonFramework.typography._setSelects($(this).val(), $target, false);
});
});
/**
* Reset button
*/
$('.epsilon-typography-default').on('click', function (e) {
e.preventDefault();
var element = $(this);
EpsilonFramework.typography._resetDefault(element);
});
}
},
/**
*
* @param value
* @param target
* @param reset
* @private
*/
_setSelects: function (value, target, reset) {
var data = {
'action': 'epsilon_retrieve_font_weights',
'class' : 'Epsilon_Typography',
'args' : value
},
selectize = $('#' + target),
instance = selectize[ 0 ].selectize;
if ( reset ) {
instance.clear();
instance.clearOptions();
instance.load(function (callback) {
var obj = { 'text': 'Theme default', 'value': 'initial' };
callback(obj);
});
instance.setValue('initial');
return;
}
jQuery.ajax({
dataType: 'json',
type : 'POST',
url : WPUrls.ajaxurl,
data : data,
complete: function (json) {
var json = $.parseJSON(json.responseText);
instance.clear();
instance.clearOptions();
instance.load(function (callback) {
callback(json);
});
instance.setValue('initial');
}
});
},
/**
* Reset defaults
*
* @param element
* @private
*/
_resetDefault: function (element) {
var container = $(element).parent(),
uniqueId = container.attr('data-unique-id'),
selects = container.find('select'),
inputs = container.find('inputs');
var fontFamily = selects[ 0 ].selectize,
fontWeight = selects[ 1 ].selectize,
fontStyle = selects[ 2 ].selectize;
var object = {
action: 'epsilon_generate_typography_css',
class : 'Epsilon_Typography',
id : uniqueId,
data : {
'selectors': $('#selectors_' + uniqueId).val(),
'json' : {}
}
},
api = wp.customize;
fontFamily.setValue('default_font');
fontStyle.setValue('initial');
if ( $('#' + uniqueId + '-font-size').length ) {
$('#' + uniqueId + '-font-size').val('15').trigger('blur');
object.data.json[ 'font-size' ] = '15';
}
if ( $('#' + uniqueId + '-line-height').length ) {
$('#' + uniqueId + '-line-height').val('22').trigger('change').trigger('blur');
object.data.json[ 'line-height' ] = '22';
}
object.data.json[ 'font-family' ] = 'default_font';
object.data.json[ 'font-weight' ] = 'initial';
object.data.json[ 'font-style' ] = 'initial';
api.previewer.send('update-inline-css', object);
},
/**
* parse/create the json and send it to the preview window
*
* @param inputs
* @param id
* @private
*/
_parseJson: function (inputs, id) {
var object = {
action: 'epsilon_generate_typography_css',
class : 'Epsilon_Typography',
id : id,
data : {
'selectors': $('#selectors_' + id).val(),
'json' : {}
}
},
api = wp.customize;
$.each(inputs, function (index, value) {
var key = $(value).attr('id'),
replace = id + '-';
key = key.replace(replace, '');
object.data[ 'json' ][ key ] = $(value).val();
});
api.previewer.send('update-inline-css', object);
return JSON.stringify(object.data);
},
/**
* Initiate the Number fields
*
* @param el
* @private
*/
_number: function (el) {
var input = el.find('input');
input.on('blur keypress keyup change', function () {
var unit = $(this).siblings('span');
if ( $(this).val() > 99 ) {
unit.animate({ 'left': 35 }, 0);
} else {
unit.animate({ 'left': 25 }, 0);
}
});
el.append('' +
'');
},
/**
* Calculate the value of the input number fields
*
* @param el
* @private
*/
_calcValue: function (el) {
var input = $(el.siblings('input')),
unit = input.siblings('span');
switch ( $(el).attr('data-increment') ) {
case 'up':
if ( input.val() == 99 ) {
unit.animate({ 'left': 35 }, 10);
}
input.val(parseInt(input.val()) + 1).trigger('change');
break;
case 'down':
if ( input.val() == 0 ) {
return;
}
if ( input.val() == 100 ) {
unit.animate({ 'left': 25 }, 10);
}
input.val(parseInt(input.val()) - 1).trigger('change');
break;
}
}
};
/**
* Recommended action section scripting
*
* @type {{_init: _init, dismissActions: dismissActions, dismissPlugins: dismissPlugins}}
*/
EpsilonFramework.recommendedActions = {
/**
* Initiate the click actions
*
* @private
*/
_init: function () {
var context = $('.control-section-epsilon-section-recommended-actions'),
dismissPlugin = context.find('.epsilon-recommended-plugin-button'),
dismissAction = context.find('.epsilon-dismiss-required-action');
/**
* Dismiss actions
*/
this.dismissActions(dismissAction);
/**
* Dismiss plugins
*/
this.dismissPlugins(dismissPlugin);
},
/**
* Dismiss actions function, hides the container and shows the next one while changing the INDEX in the title
* @param selectors
*/
dismissActions: function (selectors) {
selectors.on('click', function () {
/**
* During ajax, we lose scope - so declare "self"
* @type {*}
*/
var self = $(this),
/**
* Get the container
*/
container = self.parents('.epsilon-recommended-actions-container'),
/**
* Get the current index
*
* @type {Number}
*/
index = parseInt(container.attr('data-index')),
/**
* Get the title
*
* @type {*}
*/
title = container.parents('.control-section-epsilon-section-recommended-actions').find('h3'),
/**
* Get the indew from the notice
*
* @type {*}
*/
notice = title.find('.epsilon-actions-count > .current-index'),
/**
* Get the total
*
* @type {Number}
*/
total = parseInt(notice.attr('data-total')),
/**
* Get the next element ( this will be shown next )
*/
next = container.next(),
/**
* Create the args object for the AJAX call
*
* action [ Class, Method Name ]
* args [ parameters to be sent to method ]
*
* @type {{action: [*], args: {id: *, option: *}}}
*/
args = {
'action': [ 'Epsilon_Framework', 'dismiss_required_action' ],
'args' : {
'id' : $(this).attr('id'),
'option': $(this).attr('data-option')
}
};
/**
* Initiate the AJAX function
*
* Note that the Epsilon_Framework class, has the following method :
*
* public function epsilon_framework_ajax_action(){};
*
* which is used as a proxy to gather $_POST data, verify it
* and call the needed function, in this case : Epsilon_Framework::dismiss_required_action()
*
*/
$.ajax({
type : "POST",
data : { action: 'epsilon_framework_ajax_action', args: args },
dataType: "json",
url : WPUrls.ajaxurl,
success : function (data) {
/**
* In case everything is ok, we start changing things
*/
if ( data.status && data.message === 'ok' ) {
/**
* If it's the last element, show plugins
*/
if ( total <= index ) {
var replace = title.find('.section-title'),
plugins = $('.epsilon-recommended-plugins'),
replaceText = replace.attr('data-social');
if ( plugins.length ) {
replaceText = replace.attr('data-plugin_text');
}
title.find('.epsilon-actions-count').remove();
replace.text(replaceText);
}
/**
* Else, just change the index
*/
else {
notice.text(index + 1);
}
/**
* Fade the current element and show the next one.
* We don't need to remove it at this time. Leave it to for server side
*/
container.fadeOut('200', function () {
next.css({ opacity: 1, height: 'initial' }).fadeIn('200');
})
}
},
/**
* Throw errors
*
* @param jqXHR
* @param textStatus
* @param errorThrown
*/
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR + " :: " + textStatus + " :: " + errorThrown);
}
});
});
},
/**
* Dismiss plugins function, hides the container and shows the next one while changing the INDEX in the title
* @param selectors
*/
dismissPlugins: function (selectors) {
selectors.on('click', function () {
/**
* During ajax, we lose scope - so declare "self"
* @type {*}
*/
var self = $(this),
/**
* Get the container
*/
container = self.parents('.epsilon-recommended-plugins'),
/**
* Get the next element (this will be shown next)
*/
next = container.next(),
/**
* Get the title
*
* @type {*}
*/
title = container.parents('.control-section-epsilon-section-recommended-actions').find('h3'),
/**
* Create the args object for the AJAX call
*
* action [ Class, Method Name ]
* args [ parameters to be sent to method ]
*
* @type {{action: [*], args: {id: *, option: *}}}
*/
args = {
'action': [ 'Epsilon_Framework', 'dismiss_required_action' ],
'args' : {
'id' : $(this).attr('id'),
'option': $(this).attr('data-option')
}
};
$.ajax({
type : "POST",
data : { action: 'epsilon_framework_ajax_action', args: args },
dataType: "json",
url : WPUrls.ajaxurl,
success : function (data) {
/**
* In case everything is ok, we start changing things
*/
if ( data.status && data.message === 'ok' ) {
/**
* Fade the current element and show the next one.
* We don't need to remove it at this time. Leave it to for server side
*/
container.fadeOut('200', function () {
if ( next.is('p') ) {
var replace = title.find('.section-title'),
replaceText = replace.attr('data-social');
replace.text(replaceText);
}
next.css({ opacity: 1, height: 'initial' }).fadeIn('200');
})
}
},
/**
* Throw errors
*
* @param jqXHR
* @param textStatus
* @param errorThrown
*/
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR + " :: " + textStatus + " :: " + errorThrown);
}
});
});
}
};
/**
* Color scheme generator
*
*/
EpsilonFramework.colorSchemes = function () {
/**
* Set variables
*/
var context = $('.epsilon-color-scheme');
if ( !context.length ) {
return;
}
var options = context.find('.epsilon-color-scheme-option'),
input = context.parent().find('.epsilon-color-scheme-input'),
json = $.parseJSON(options.first().find('input').val()),
api = wp.customize,
colorSettings = [],
css = {
action: 'epsilon_generate_color_scheme_css',
class : 'Epsilon_Color_Scheme',
id : '',
data : {}
};
$.each(json, function (index, value) {
colorSettings.push(index);
});
function updateCSS() {
_.each(colorSettings, function (setting) {
css.data[ setting ] = api(setting)();
});
api.previewer.send('update-inline-css', css)
}
_.each(colorSettings, function (setting) {
api(setting, function (setting) {
setting.bind(updateCSS);
});
});
/**
* On clicking a color scheme, update the color pickers
*/
$('.epsilon-color-scheme-option').on('click', function () {
var val = $(this).attr('data-color-id'),
json = $.parseJSON($(this).find('input').val());
/**
* find the customizer options
*/
$.each(json, function (index, value) {
colorSettings.push(index);
/**
* Set values
*/
wp.customize(index).set(value);
});
/**
* Remove the selected class from siblings
*/
$(this).siblings('.epsilon-color-scheme-option').removeClass('selected');
/**
* Make active the current selection
*/
$(this).addClass('selected');
/**
* Trigger change
*/
input.val(val).change();
_.each(colorSettings, function (setting) {
api(setting, function (setting) {
setting.bind(updateCSS());
});
});
});
};
/**
* Load the range sliders for the widget updates
*/
$(document).on('widget-updated widget-added', function (a, selector) {
EpsilonFramework.rangeSliders(selector);
});
if ( typeof(wp) !== 'undefined' ) {
if ( typeof(wp.customize) !== 'undefined' ) {
wp.customize.bind('ready', function () {
EpsilonFramework.typography._init();
EpsilonFramework.colorSchemes();
EpsilonFramework.recommendedActions._init();
});
wp.customize.sectionConstructor[ 'epsilon-section-pro' ] = wp.customize.Section.extend({
attachEvents : function () {
},
isContextuallyActive: function () {
return true;
}
});
wp.customize.sectionConstructor[ 'epsilon-section-recommended-actions' ] = wp.customize.Section.extend({
attachEvents : function () {
},
isContextuallyActive: function () {
return true;
}
});
}
}
})(jQuery);