: 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
let frame = self.mediaFile._frames.json;
if (frame !== undefined) {
frame = frame.content.get();
frame.collection.props.set({ignore: (+new Date())});
frame.options.selection.reset();
openLibrary = async () => {
api.Spinner.showLoader();
const opt = themifyBuilder.i18n.lottie_lib;
await Themify.loadJs(Themify.url + 'js/admin/modules/lottie-library', !!window.TF_LottieLibrary);
await TF_LottieLibrary.run(input, opt, themifyBuilder.nonce);
input.tfOff('change', updateWpMedia, {passive: true, once: true})
.tfOn('change', updateWpMedia, {passive: true, once: true});
api.Spinner.showLoader('done');
api.Spinner.showLoader('error');
browse.tfOn(_CLICK_, async e => {
.innerHTML = themifyBuilder.i18n.lottie_lib.browse;
input.tfOn('change', e => {
_callback(e.currentTarget, true);
fileWrap.querySelector('.tb_input').appendChild(browse);
self.afterRun.push(() => {
_callback(input, false, vals.fid);
const wrapper = input.closest('.tb_row_js_wrapper');
if (wrapper.parentNode.tfClass('tb_lottie_export')[0] === undefined) {
const exportBtn = createElement('button',{class: 'builder_button tb_text_button tb_lottie_export',type:'button'},i18n.lottie.exp);
exportBtn.tfOn(_CLICK_, e => {
const opt = api.Forms.serialize('tb_options_setting', false);
if (k !== 'actions' && k !== 'loop') {
const html = '<tf-lottie data-lazy="1" class="tf_w tf_lazy"><template>' + JSON.stringify(opt) + '</template></tf-lottie>',
msg = i18n.lottie.copy.replaceAll('%html%', '<textarea style="border:0;outline:0;resize:none;display:inline-table;font-weight:bold;margin-top:20px" readonly class="tf_w">' + html + '</textarea>');
api.LiteLightBox.alert(msg);
const textarea = api.LiteLightBox.el.tfTag('textarea')[0],
textarea.tfOn(e.type, select, {passive: true});
wrapper.after(exportBtn);
wrap.tfOn(_CLICK_, function (e) {
e.stopImmediatePropagation();
const input = e.target.closest('label').tfTag('input')[0];
if (input.checked === true) {
input.value = input.dataset.value;
Themify.triggerEvent(input, 'change');
return self.radioGenerate('icon_radio', data);
const context = item.classList.contains('tb_radio_dnd') ? item.closest('.tb_repeatable_field_content') : (item.closest('.tb_tab,.tb_expanded_opttions') || api.LightBox.el),
elements = item.parentNode.parentNode.tfTag('input'),
groups = context.tfClass('tb_group_element_' + selected);
for (let i = elements.length - 1; i > -1; --i) {
let v = elements[i].value;
let g = context.tfClass('tb_group_element_' + v);
for (let j = g.length - 1; j > -1; --j) {
g[j].style.display = 'none';
for (let j = groups.length - 1; j > -1; --j) {
groups[j].style.display = '';
const wrap = self.getEl(id);
const items = wrap.tfTag('input'),
is_icon = wrap.classList.contains('tb_icon_radio');
for (let i = items.length - 1; i > -1; --i) {
if (items[i].value === v) {
const def = wrap.dataset.default;
found = wrap.querySelector('[value="' + def + '"]');
if (is_icon === false && found === null) {
if (is_icon === false && wrap.classList.contains('tb_option_radio_enable')) {
this.controlChange(found);
} else if (is_icon === true) {
for (let i = items.length - 1; i > -1; --i) {
items[i].checked = false;
return self.radioGenerate('radio', data);
return self.checkboxGenerate('icon_checkbox', data);
const wrap = self.getEl(id);
const items = wrap.tfTag('input'),
js_wrap = wrap.classList.contains('tb_option_checkbox_enable');
v = v?.toString().split('|') || [];
for (let i = items.length - 1; i > -1; --i) {
items[i].checked = v.includes(items[i].value);
this.controlChange(items[i]);
const el = item.classList.contains('tb_radio_dnd') ? item.closest('.tb_repeatable_field_content') : api.LightBox.el,
parent = item.parentNode.parentNode,
items = parent.tfTag('input'),
is_revert = parent.classList.contains('tb_option_checkbox_revert');
for (let i = items.length - 1; i > -1; --i) {
let ch = el.tfClass('tb_checkbox_element_' + items[i].value),
is_checked = items[i].checked;
for (let j = ch.length - 1; j > -1; --j) {
ch[j].classList.toggle('_tb_hide_binding', !((is_revert === true && is_checked === false) || (is_revert === false && is_checked === true)));
return self.checkboxGenerate('checkbox', data);
radioGenerate(type, data) {
const d = createDocumentFragment(),
wrapper = createElement('',{class:'tb_radio_wrap',tabindex:-1}),
is_icon = 'icon_radio' === type,
options = this.getOptions(data),
v = this.getStyleVal(data.id),
js_wrap = data.option_js === true,
_default = data.default ?? false,
if (data.new_line !== undefined) {
wrapper.className += ' tb_new_line';
wrapper.className += ' tb_count_' + len;
wrapper.className += ' tb_option_radio_enable';
wrapper.className += ' tb_icon_radio';
toggle = data.no_toggle===undefined;
if (this.is_repeat === true) {
wrapper.className += this.is_sort === true ? ' tb_lb_sort_child' : ' tb_lb_option_child';
id = 'tb_' + Math.random().toString(36).substr(2, 7);
wrapper.dataset.inputId = data.id;
wrapper.className += ' tb_lb_option';
wrapper.id = id = data.id;
if (_default !== false) {
wrapper.dataset.default = _default;
else if ( is_icon === false && v === undefined && options[0] ) {
_default = options[0].value;
if (data.before !== undefined) {
d.appendChild(createTextNode(data.before));
for (let i = 0; i < len; ++i) {
n = i18n[opt.name] || opt.name,
label = createElement('label',opt.class),
ch = createElement('input',{type:'radio',name:id,value:opt.value});
ch.dataset.value = opt.value;
if (this.is_repeat === true) {
if (data.class !== undefined) {
ch.className = cl.join(' ');
if (opt.disable === true) {
if (v === opt.value || (v === undefined && _default === opt.value)) {
ch.tfOn('change', function () {
this.parentNode.parentNode.blur();
self.radio.controlChange(this);
if (opt.icon !== undefined) {
let icon_wrap = createElement('span','tb_icon_wrapper');
icon_wrap.innerHTML = opt.icon;
label.appendChild(icon_wrap);
if (opt.label_class !== undefined) {
label.className += opt.label_class;
label.appendChild(createElement('span','themify_tooltip',n));
} else if (n !== undefined) {
label.appendChild(createElement('span','',n));
wrapper.appendChild(label);
this._initControl(ch, data);
wrapper.tfOn(_CLICK_, function (e) {
if ('LABEL' === e.target.parentNode.tagName) {
if (data.after !== undefined) {
d.appendChild(self.after(data));
if (data.description !== undefined) {
d.appendChild(self.description(data.description));
if (is_icon === true && toggle === true) {
self.icon_radio.controlChange(wrapper);
this._radioChange.push(() => {
for (let i = 0, len = checked.length; i < len; ++i) {
self.radio.controlChange(checked[i]);
checkboxGenerate(type, data) {
const d = createDocumentFragment(),
wrapper = createElement('','tb_checkbox_wrap'),
options = this.getOptions(data),
is_icon = 'icon_checkbox' === type,
js_wrap = data.option_js === true,
let v = this.getStyleVal(data.id),
if (data.new_line === false) {
wrapper.className += ' tb_one_row';
wrapper.className += ' tb_count_' + len;
wrapper.className += ' tb_option_checkbox_enable';
if (data.reverse !== undefined) {
wrapper.className += ' tb_option_checkbox_revert';
if (this.is_repeat === true) {
wrapper.className += this.is_sort === true ? ' tb_lb_sort_child' : ' tb_lb_option_child';
wrapper.dataset.inputId = data.id;
wrapper.className += ' tb_lb_option';
if (data.wrap_checkbox !== undefined) {
wrapper.className += ' ' + data.wrap_checkbox;
if (data.default !== undefined) {
is_array = Array.isArray(_default);
v = v.toString().split('|');
wrapper.className += ' tb_icon_checkbox';
if (data.before !== undefined) {
d.appendChild(createTextNode(data.before));
for (let i = 0; i < len; ++i) {
n = i18n[opt.value] || opt.value,
label = createElement('label'),
ch = createElement('input',{type:'checkbox',class:'tb_checkbox',value:opt.name});
ch.checked = (v !== false && v?.includes(opt.name)) || (_default === opt.name || (is_array === true && _default.includes(opt.name)));
if (data.class !== undefined) {
ch.className += ' ' + data.class;
ch.tfOn('change', function () {
self.checkbox.controlChange(this);
if (data.id === 'hide_anchor') {
api.activeModel.options(ch, 'hide_anchor');
label.insertAdjacentHTML('beforeend', opt.icon);
label.appendChild(createElement('span','themify_tooltip',n));
} else if (n !== undefined) {
label.appendChild(createTextNode(n));
if (opt.help !== undefined) {
let hasHelp = createElement('','tb_checkbox_help');
hasHelp.append(label, this.help(opt.help));
wrapper.appendChild(label);
this._initControl(ch, data);
if (data.id === 'hide_anchor') {
wrapper.tfOn(_CLICK_, e => {
if (data.after !== undefined) {
if ((data.label === undefined || data.label === '') && (data.help !== undefined && data.help !== '')) {
wrapper.className += ' contains-help';
wrapper.appendChild(this.after(data));
d.appendChild(this.after(data));
if (data.description !== undefined) {
d.appendChild(this.description(data.description));
this.afterRun.push(() => {
for (let i = 0, len = chekboxes.length; i < len; ++i) {
self.checkbox.controlChange(chekboxes[i]);
const f = createDocumentFragment(),
input = createElement('input',{type:'text',class:'themify-datepicker fullwidth',autocomplete:'off',readonly:''}),
clear = createElement('button',{type:'button',class:'themify-datepicker-clear tf_close'}),
return topWindow.jQuery.fn.themifyDatetimepicker
? topWindow.jQuery.fn.themifyDatetimepicker
: topWindow.jQuery.fn.datetimepicker;
get_datePicker().call($(input), 'hide');
const datePicker = get_datePicker();
const pickerData = data.picker?? {};
clear.tfOn(_CLICK_, function (e) {
input.dispatchEvent(new Event('change'));
this.style.display = 'none';
datePicker.call($(input), {
showTimepicker: !!(data.timepicker === undefined || data.timepicker),
dateFormat: pickerData.dateformat || 'yy-mm-dd',
timeFormat: pickerData.timeformat || 'HH:mm:ss',
stepMinute: pickerData.stepMinute || 5,
stepSecond: pickerData.stepSecond || 5,
controlType: pickerData.timecontrol || 'select',
separator: pickerData.timeseparator || ' ',
clear.style.display = v === '' ? 'none' : 'block';
input.dispatchEvent(new Event('change'));
beforeShow(input, instance) {
instance.dpDiv.addClass('themify-datepicket-panel');
const r = input.getBoundingClientRect();
top: r.top + input.offsetHeight,
body.tfOn(_CLICK_, hide_picker, {once: true});
body.tfOff(_CLICK_, hide_picker, {once: true});
if (self.is_repeat === true) {
input.className += self.is_sort === true ? ' tb_lb_sort_child' : ' tb_lb_option_child';
input.dataset.inputId = data.id;
input.className += ' tb_lb_option';
if (self.values[data.id] !== undefined) {
input.value = self.values[data.id];
if (data.class !== undefined) {
input.className += ' ' + data.class;
clear.style.display = 'none';