: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
ul = createElement('ul', 'tb_seperate_items tf_inline_b tb_has_opposite'),
range = api.Helper.cloneObject(data),
for (let i = 0; i < 2; ++i) {
let li = createElement('li');
range.id = data[items[i]];
range.prop = items[i] === 'topId' ? 'margin-top' : 'margin-bottom';
range.class = 'tb_multi_field tb_range_' + (items[i] === 'topId' ? 'top' : 'bottom');
range.tooltip = items[i] === 'topId' ? i18n.top : i18n.bottom;
li.appendChild(self.range.render(range, self));
let opposite = createElement('li','tb_seperate_opposite tb_opposite_top');
opposite.appendChild(self.checkboxGenerate('checkbox',
id: range.id + '_opp_top',
class: 'style_apply_oppositive',
let ch_op = opposite.querySelector('.style_apply_oppositive');
ch_op.tfOn('change', function (e) {
self.margin._bindingOppositive(this, true);
.parentNode.insertBefore(createElement('','tb_oppositive_state'), ch_op.nextSibling);
ul.appendChild(opposite);
self._stylesData[data[items[i]]] = self.styles[data[items[i]]] = {id: data[items[i]], type: data.type, prop: (items[i] === 'topId' ? 'margin-top' : 'margin-bottom'), selector: data.selector};
_bindingOppositive(el, init) {
const li = el.closest('.tb_seperate_opposite'),
isLeft = li.classList.contains('tb_opposite_left'),
firstItem = isLeft === true ? li.nextElementSibling : li.previousElementSibling,
isChecked = el.checked === true,
dir = this._getOppositiveDir(firstItem.tfClass('tb_range')[0]),
field = p.tfClass('tb_range_' + dir)[0],
u = field.closest('li').tfClass('tb_unit')[0];
if (isChecked === true) {
field.dataset.v = field.value;
const firstInput = firstItem.tfClass('tb_range')[0],
if (v !== '' || v2 === '') {
u.value = firstItem.tfClass('tb_unit')[0].value;
firstItem.tfClass('tb_unit')[0].value = u.value;
const v = field.dataset.v;
Themify.triggerEvent(field, 'keyup');
const p = el.closest('.tb_has_opposite');
if (!p.hasAttribute('data-checked')) {
const input = self.getEl(el.id.replace(/_unit$/ig, '')),
dir = this._getOppositiveDir(input),
isBorder = input.classList.contains('tb_is_border_radius'),
chClass = dir === 'top' || (isBorder === true && dir === 'right') || (isBorder === false && dir === 'bottom') ? 'top' : 'left';
if (p.tfClass('tb_opposite_' + chClass)[0].tfClass('style_apply_oppositive')[0].checked === true) {
p.tfClass('tb_range_' + dir)[0].closest('li').tfClass('tb_unit')[0].value = el.value;
let opp = cl.contains('tb_range_top') ? 'bottom' : (cl.contains('tb_range_bottom') ? 'top' : (cl.contains('tb_range_left') ? 'right' : 'left'));
if (cl.contains('tb_is_border_radius')) {
} else if (opp === 'top') {
} else if (opp === 'left') {
const li = el.closest('li'),
if (!p.hasAttribute('data-checked')) {
const dir = this._getOppositiveDir(el),
isBorder = el.classList.contains('tb_is_border_radius'),
ch = dir === 'top' || (isBorder === true && dir === 'right') || (isBorder === false && dir === 'bottom') ? p.tfClass('tb_opposite_top')[0] : p.tfClass('tb_opposite_left')[0];
if (ch.tfClass('style_apply_oppositive')[0].checked === true) {
p.tfClass('tb_range_' + dir)[0].value = el.value;
_apply_all(item, trigger) {
const ul = item.closest('.tb_input').tfClass('tb_seperate_items')[0],
first = ul.tfTag('li')[0],
isChecked = item.checked === true;
if (isChecked === true) {
ul.removeAttribute('data-checked');
text = ul.dataset.toptext || i18n.top;
Themify.triggerEvent(first.tfClass('tb_multi_field')[0], 'keyup');
first.tfClass('tb_tooltip_up')[0].textContent = text;
const options = ['top', 'right', 'bottom', 'left'],
checkbox_id = 'checkbox_' + id + '_apply_all',
ch = self.getEl(checkbox_id),
apply_all = ch ? ch.tfClass('style_apply_all')[0] : null;
for (let i = 3; i > -1; --i) {
let nid = id + '_' + options[i],
self.range.update(nid, self.getStyleVal(nid), self);
if (!apply_all || apply_all.checked !== true) {
let oppositiveId = id + '_opp_' + options[i],
ch_oppositive = self.getEl(oppositiveId);
if (ch_oppositive !== null) {
ch_oppositive.tfClass('style_apply_oppositive')[0].checked = !!self.getStyleVal(oppositiveId);
self.checkbox.update(checkbox_id, self.getStyleVal(checkbox_id), self);
this._apply_all(apply_all);
return self.createMarginPadding(data.type, data);
return self.createMarginPadding(data.type, data);
const options = ['hOffset', 'vOffset', 'blur', 'spread'],
color_id = id + '_color',
checkbox_id = id + '_inset';
for (let i = 3; i > -1; --i) {
let nid = id + '_' + options[i],
self.range.update(nid, self.getStyleVal(nid), self);
self.color.update(color_id, self.getStyleVal(color_id), self);
self.checkbox.update(checkbox_id, self.getStyleVal(checkbox_id), self);
const {selector,prop,id} = data,
units: {px: {min: -200, max: 200}, em: {max: 40}}
units: {px: {min: -200, max: 200}, em: {max: 40}}
units: {px: {max: 300}, em: {max: 40}}
units: {px: {min: -200, max: 200}, em: {min: -10, max: 40}}
ul = createElement('ul','tb_seperate_items tb_shadow_inputs'),
range = api.Helper.cloneObject(data),
f = createDocumentFragment();
range.class = 'tb_shadow_field';
for (let rangeField in ranges) {
if (ranges[rangeField] !== undefined) {
let rField = ranges[rangeField],
li = createElement('li'),
prop_id = id + '_' + rangeField;
range.tooltip = rField.label;
range.units = rField.units;
range.selector = selector;
li.appendChild(self.range.render(range, self));
self.styles[prop_id] = {prop: prop, selector: selector};
let prop_id = id + '_color';
const li = createElement('li','tb_shadow_color'),
color = {id: prop_id, type: 'color', class: range.class, selector: selector};
self.styles[prop_id] = {prop: prop, selector: selector, type: 'color'};
li.appendChild(self.color.render(color, self));
{value: 'in_sh', name: 'inset'}
self.styles[prop_id] = {prop: prop, selector: selector};
f.append(ul, self.checkboxGenerate('checkbox', coptions));
const options = ['hShadow', 'vShadow', 'blur'],
color_id = id + '_color';
for (let i = 2; i > -1; --i) {
let nid = id + '_' + options[i],
self.range.update(nid, self.getStyleVal(nid), self);
self.color.update(color_id, self.getStyleVal(color_id), self);
const {selector,prop,id} = data,
units: {px: {min: -200, max: 200}, em: {max: 40}}
units: {px: {min: -200, max: 200}, em: {max: 40}}
units: {px: {max: 300}, em: {max: 40}}
ul = createElement('ul','tb_seperate_items tb_shadow_inputs'),
li = createElement('li','tb_shadow_color'),
color = {id: prop_id, type: 'color', class: 'tb_shadow_field', selector: selector},
range = api.Helper.cloneObject(data);
range.class = 'tb_shadow_field';
for (let rangeField in ranges) {
if (ranges.hasOwnProperty(rangeField)) {
let rField = ranges[rangeField],
li = createElement('li'),
prop_id = id + '_' + rangeField;
range.tooltip = rField.label;
range.units = rField.units;
li.appendChild(self.range.render(range, self));
self.styles[prop_id] = {prop: prop, selector: selector};
self.styles[prop_id] = {prop: prop, selector: selector, type: 'color'};
li.appendChild(self.color.render(color, self));
data.options??= self.getOptions('border_radius');
data.wrap_class??= 'border-radius-options';
return self.createMarginPadding(data.type, data);
self.styles[ data.id + '-c' ] = self.styles[ data.id + '-w' ] =self.styles[ data.id + '-s' ] = data.selector;
options: self.getOptions('border'),
const {parentNode:p,value:v} = item,
items = p.parentNode.children;
for (let i = items.length - 1; i > -1; --i) {
items[i].classList.toggle('_tb_hide_binding', v === 'none');
_apply_all(border, item) {
const items = item.tfTag('input'),
disable = (is_all, event)=> {
for (let i = items.length - 1; i > -1; --i) {
items[i].parentNode.classList.toggle('_tb_disable', is_all && items[i].value !== 'all');
border.dataset.checked = 1;
border.removeAttribute('data-checked');
Themify.triggerEvent(border.children[0].tfTag('select')[0], 'change');
for (let i = items.length - 1; i > -1; --i) {
items[i].tfOn('change', function () {
disable(this.value === 'all', true);
if (items[i].checked === true && items[i].value === 'all') {
const options = ['top', 'right', 'bottom', 'left'],
for (let i = 0; i < 4; ++i) {
let nid = id + '_' + options[i],
color_id = nid + '_color',
style_id = nid + '_style',
range_id = nid + '_width';
self.color.update(color_id, self.getStyleVal(color_id), self);
self.select.update(style_id, self.getStyleVal(style_id), self);
this._changeControl(self.getEl(style_id));
self.range.update(range_id, self.getStyleVal(range_id), self);
self.radio.update(radio_id, self.getStyleVal(radio_id), self);
const options = ['top', 'right', 'bottom', 'left'],
ul = createElement('ul', 'tb_seperate_items tb_borders tb_group_element_border'),
selector = data.selector,
select = api.Helper.cloneObject(data),
radio = api.Helper.cloneObject(data),
d = createDocumentFragment();
{value: 'all', name: 'all', class: 'style_apply_all ', icon: '<i class="tic-border-all"></i>', label_class: 'tb_radio_label_borders'}
radio.id = orig_id + '-type';
select.options = self.getOptions('border');
for (let i = 0; i < 4; ++i) {
let li = createElement('li','tb_group_element_' + options[i]),
id = orig_id + '_' + options[i];
radio.options.push({value: options[i], name: options[i], icon: '<i class="tic-border-' + options[i] + '"></i>', label_class: 'tb_radio_label_borders'});
if (options[i] === 'top') {
li.className += ' tb_group_element_all';
self.styles[id + '_color'] = {prop: 'border-' + options[i], selector: selector};
select.id = id + '_color';
select.class = 'border_color';
li.appendChild(self.color.render(select, self));
self.styles[id + '_width'] = {prop: 'border-' + options[i], selector: selector};
select.id = id + '_width';
select.class = 'border_width';
select.units = {px: {max: 300}};
li.appendChild(self.range.render(select, self));
self.styles[id + '_style'] = {prop: 'border-' + options[i], selector: selector};
select.id = id + '_style';
select.class = 'border_style tb_multi_field';
let border_select = self.select.render(select, self),
select_item = border_select.querySelector('select');
li.appendChild(border_select);
select_item.tfOn('change', function () {
_this._changeControl(this);
if (select_item.value === 'none') {
_this._changeControl(select_item);
d.appendChild(self.radioGenerate('icon_radio', radio, self));
_this._apply_all(ul, d.querySelector('#' + radio.id));
const label = data.label || 'sl_opt',
/* backward compatibility for old predefined speed values */
// Backward compatibility #9463
if (['crossfade', 'cover-fade', 'uncover-fade'].includes(self.values.effect_slider)) {
self.values.effect_slider = 'fade';
if ( speeds[ self.values.speed_opt_slider ] ) {
self.values.speed_opt_slider = speeds[ self.values.speed_opt_slider ];
label: i18n[label] || label,
options: data.options || self.getOptions('slider_options'),
wrap_class: data.wrap_class