: 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
f.append(self._initControl(input, data), clear);
if (data.after !== undefined) {
f.appendChild(self.after(data));
if (data.description !== undefined) {
f.appendChild(self.description(data.description));
if (this._loaded === null) {
topThemify.loadCss(Themify.url + 'themify-metabox/css/jquery-ui-timepicker.min');
topThemify.loadJs(Themify.includesURL + 'js/jquery/ui/datepicker.min', topWindow.jQuery.fn.datepicker !== undefined, themify_vars.wp).then(() => {
topThemify.loadJs(Themify.url + 'themify-metabox/js/jquery-ui-timepicker.min', topWindow.jQuery.fn.themifyDatetimepicker !== undefined || topWindow.jQuery.fn.datetimepicker !== undefined, '1.6.3').then(() => {
setTimeout(callback, 10);
self.afterRun.push(init);
self.afterRun.push(callback);
_controlChange(self, gradient, input, clear, type, angle, circle, text, update) {
let angleV = self.getStyleVal(angle.id);
if (angleV === undefined || angleV === '') {
value = self.getStyleVal(id),
onChange(stringGradient, cssGradient) {
stringGradient = cssGradient = '';
input.value = stringGradient;
Themify.triggerEvent(input, 'themify_builder_gradient_change', {val: cssGradient});
let typeV = self.getStyleVal(type.id);
if (typeV === undefined || typeV === '') {
$gradient.ThemifyGradient(args);
const instance = $gradient.data('themifyGradient'),
let p = angle.parentNode;
if (!p.classList.contains('tb_angle_container')) {
text.style.display = p.style.display = val === 'radial' ? 'none' : '';
circle.parentNode.style.display = val === 'radial' ? '' : 'none';
instance.settings = {...instance.settings, ...args};
instance.settings.type = typeV;
instance.settings.circle = circle.checked;
clear.tfOn(_CLICK_, e => {
e.stopImmediatePropagation();
instance.settings.gradient = $.ThemifyGradient.default;
type.tfOn('change', function () {
circle.tfOn('change', function () {
instance.setRadialCircle(this.checked);
angle.tfOn('keyup', function () {
let val = parseInt(this.value);
gradient.appendChild(clear);
callback(self.getStyleVal(type.id));
const nid = id + '-gradient',
const angle = self.getEl(nid + '-angle'),
type = self.getEl(nid + '-type'),
circle = self.getEl(id + '-circle-radial');
this._controlChange(self, input.previousElementSibling, input, null, type, angle, circle.tfClass('tb_checkbox')[0], circle.previousElementSibling, true);
wrap = createElement('','themify-gradient-field tf_w tf_rel'),
text = createElement('span','',i18n.rotation),
gradient = createElement('','tb_gradient_container tf_w'),
input = createElement('input',{type:'hidden',class:'themify-gradient tb_lb_option',id:id+ '-gradient','data-id':id}),
clear = createElement('button',{type:'button',class:'tb_clear_gradient tf_close'}),
select = self.select.render({
class: 'themify-gradient-type',
id: id + '-gradient-type',
if (data.option_js !== undefined) {
wrap.className += ' tb_group_element_gradient';
clear.appendChild(createElement('span','themify_tooltip',i18n.clear_gradient));
const angleData = api.Helper.cloneObject(data);
angleData.id = id + '-gradient-angle';
const angleWarp = self.angle.render(angleData, self);
wrap.append(select, angleWarp, text, self.checkboxGenerate('checkbox',
id: id + '-circle-radial',
options: [{name: '1', value: 'circle_radial'}]
self._initControl(input, data);
self.afterRun.push(() => {
this._controlChange(self, gradient, input, clear, wrap.querySelector('.themify-gradient-type'), angleWarp.tfClass('tb_angle_input')[0], wrap.tfClass('tb_checkbox')[0], text);
self.radio.update(id, self.getStyleVal(id), self);
{value: data.s + '_solid', name: 'solid'},
{value: data.g + '_gradient', name: 'gradient'}
radioWrap = self.radioGenerate('radio', roptions),
radio = radioWrap.querySelector('.tb_lb_option'),
colorData = api.Helper.cloneObject(data);
colorData.type = 'color';
colorData.prop = 'color';
colorData.wrap_class = 'tb_group_element_' + data.s + '_solid';
const color = self.create([colorData]);
colorData.wrap_class = 'tb_group_element_' + data.g + '_gradient';
colorData.type = 'gradient';
colorData.prop = 'background-image';
const gradient = self.create([colorData]);
self.afterRun.push(() => {
const field = radio.parentNode.closest('.tb_field');
field.parentNode.insertBefore(color, field.nextElementSibling);
field.parentNode.insertBefore(gradient, field.nextElementSibling);
self.radio.update(id + '-type', self.getStyleVal(id + '-type'), self);
self.mediaFile.update(id, v, self);
self.gradient.update(id, v, self);
const el = self.getEl(id);
let p = el.closest('.tb_tab'),
imageOpt = p.tfClass('tb_image_options'),
eid = p.tfClass('tb_gradient_image_color')[0].tfClass('tfminicolors-input')[0].id;
self.color.update(eid, self.getStyleVal(eid), self);
for (let i = 0; i < imageOpt.length; ++i) {
eid = imageOpt[i].tfClass('tb_lb_option')[0].id;
self.select.update(eid, self.getStyleVal(eid), self);
const wrap = createElement('','tb_image_gradient_field'),
imageWrap = createElement('', 'tb_group_element_image tf_w tf_rel');
wrap.appendChild(self.radioGenerate('radio',
{name: 'image', value: 'image'},
{name: 'gradient', value: 'gradient'}
if (data.option_js === undefined) {
if (data.binding === undefined) {
const extend = api.Helper.cloneObject(data);
imageWrap.appendChild(self.mediaFile.render('image', api.Helper.cloneObject(extend), self));
wrap.appendChild(imageWrap);
extend.type = 'gradient';
wrap.appendChild(self.gradient.render(extend, self));
self.afterRun.push(() => {
wrap_class: 'tb_group_element_image tf_w tf_rel',
extend.prop = 'background-color';
extend.wrap_class = 'tb_gradient_image_color';
extend.id = extend.colorId;
group.options.push(api.Helper.cloneObject(extend));
extend.prop = 'background-mode';
extend.wrap_class = 'tb_image_options';
extend.id = extend.repeatId;
group.options.push(api.Helper.cloneObject(extend));
extend.prop = 'background-position';
extend.wrap_class = 'tb_image_options';
extend.type = 'position_box';
extend.id = extend.posId;
group.options.push(api.Helper.cloneObject(extend));
imageWrap.parentNode.closest('.tb_field').after(self.create([group]));
el.tfOn(_CLICK_, function (e) {
const selected = e.target.closest('a');
const items = this.tfClass('tfl-icon');
for (let i = items.length - 1; i > -1; --i) {
items[i].classList.remove('selected');
selected.classList.add('selected');
Themify.triggerEvent(this, 'change', {val: selected.id});
const input = self.getEl(id);
const items = input.tfClass('tfl-icon');
for (let i = items.length - 1; i > -1; --i) {
items[i].classList.toggle('selected', v === items[i].id);
let def = input.dataset.default;
def = def === undefined ? items[0] : def.querySelector('#' + def);
def.classList.add('selected');
let p = createElement('','themify-layout-icon'),
options = self.getOptions(data),
v = self.getStyleVal(data.id);
if (data.color === true && data.transparent === true) {
options.push({img: 'transparent', value: 'transparent', label: i18n.transparent});
if (self.is_repeat === true) {
p.className += self.is_sort === true ? ' tb_lb_sort_child' : ' tb_lb_option_child';
p.dataset.inputId = data.id;
p.className += ' tb_lb_option';
if (data.class !== undefined) {
p.className += ' ' + data.class;
if(data.default!==undefined){
const def = api.activeModel.type === 'module' ? api.activeModel.getPreviewSettings() : null;
v = def?.[data.id] ?? (options[0].value || '');
self.settings[data.id] = v;
for (let i = 0; i < options.length; ++i) {
let {value:optV='',img,label} = options[i],
a = createElement('a',{href:'#',class:'tfl-icon',id:optV}),
tooltip = createElement('span','themify_tooltip',(i18n[label] || label)),
if (v === optV.toString()) {
a.className += ' selected';
if (data.mode === 'sprite' && !img.includes('.png')) {
sprite = createElement('span','tb_sprite');
if (img.includes('http')) {
sprite.style.backgroundImage = 'url(' + img + ')';
sprite.className += ' tb_' + img;
sprite.alt = i18n[label] || label;
sprite.src = img.includes('http') ? img : Themify.builder_url + 'editor/img/' + img;
a.append(sprite, tooltip);
if (self.component === 'row' && (data.id === 'row_width' || data.id === 'row_height')) {
api.activeModel.options(p, data.type);
self._initControl(p, data);
if (this.data.length === 0) {
api.Spinner.showLoader();
this.data = await api.LocalFetch({action: 'tb_get_library_items'});
api.Spinner.showLoader('done');
api.Spinner.showLoader('error');
const s = self.values[data.id],
d = createDocumentFragment(),
selectWrap = self.select.render(data, self),
edit = createElement('a'),
add = createElement('a'),
select = selectWrap.querySelector('select');
const currentLayoutId = api.LayoutPart?.id ? api.LayoutPart.id.toString() : null,
select.appendChild(createElement('option'));
for (let i = 0; i < arr.length; ++i) {
if (currentLayoutId !== arr[i].id.toString()) {
let opt = createElement('option',{value:arr[i].post_name},arr[i].post_title);
if (s === arr[i].post_name) {
d.append(selectWrap, createElement('br'));
add.className = 'add_new tf_plus_icon tb_icon_btn tf_rel';
add.textContent = i18n.nlayout;
edit.target = add.target = '_blank';
edit.className = 'tb_icon_btn';
edit.href = data.edit_url;
edit.append(api.Helper.getIcon('ti-folder'), createTextNode(i18n.mlayout));
const label = data.label??'f',
txt = i18n[label]?? label;
seperator = data.wrap_class !== undefined ? createElement() : createDocumentFragment();
seperator.append(createElement('hr'), createElement('h4','',txt));
if (data.wrap_class !== undefined) {
seperator.className = data.wrap_class;
} else if (data.html !== undefined) {
const tmp = createElement();
tmp.innerHTML = data.html;
seperator = tmp.firstChild;
if (data.wrap_class !== undefined) {
seperator.className = data.wrap_class;
seperator = createElement('hr');
if (data.wrap_class !== undefined) {
seperator.className = data.wrap_class;
const div = createElement('','tb_template_fields'),
div.appendChild(createElement('h4','',i18n[data.title] || data.title));
for (let i = 0; i < data.fields.length; i++) {
div.appendChild(createElement('span','',data.fields[ i ]));
const temp = createElement();
temp.innerHTML = i18n[data.extra] || data.extra;
div.appendChild(temp.firstChild);
if (target) { /* element to recieve the text */
if (e.target.tagName === 'SPAN') {
const targetEl = self.getEl(target);
const position = targetEl.selectionStart;
targetEl.value = targetEl.value.substring( 0, position ) + ' ' + e.target.textContent + targetEl.value.substring( position, targetEl.value.length );
Themify.triggerEvent(targetEl, 'keyup');