: 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
e.stopImmediatePropagation();
const v = input.value.trim() || '',
style = doc.tfId(css_id),
err = topWindow.CodeMirror.lint.css(v, {
const answer = await api.LiteLightBox.confirm({
msg: themifyBuilder.i18n.broken_code.replace('%s','CSS')
input.value = builder.customCss || '';
obj=await api.Helper.codeMirror(input,'css',{autofocus:true} );
obj.editor.on('change', cm=> {
const v = cm.getValue().trim();
let el = doc.tfId(css_id);
el = createElement('style',{id:css_id});
doc.head.appendChild(el);
saveBtn.tfOn(_CLICK_,save);
Themify.on('tb_save_lb',save)
.on('themify_builder_lightbox_close', () => {
lb.classList.remove('tb_custom_css_lightbox');
saveBtn.tfOff(_CLICK_,save,{once:true});
Themify.off('tb_save_lb',save);
if(api.Builder.get(1)===undefined){
this.el.tfClass('custom_css')[0].classList.toggle('active',!!builder.customCss);
target.classList.remove('active');
input=saveBtn=obj=builder=null;
async previewBuilder(e) {
builder=api.Builder.get().el;
item.classList.toggle('active');
api.isPreview = !api.isPreview;
if(!api.isVisual && isFrontend){
await this.backendMode(e);
topWindowDoc.tfId('tb_iframe').style.height = '';
bodyCl.toggle('tb_preview_only');
bodyCl.toggle('themify_builder_active');
topBodyCl.toggle('tb_preview_only');
api.ToolBar.el.classList.toggle('tb_preview_only');
api.MainPanel.el.classList.toggle('tb_preview_only');
for (let row_inner = builder.tfClass('row_inner'),i = row_inner.length - 1; i > -1; --i) {
if (row_inner[i].childElementCount === 1 && row_inner[i].tfClass('active_module')[0] === undefined) {
let column = row_inner[i].tfClass('module_column')[0];
if (column !== undefined) {
let mcolumn = Registry.get(column.dataset.cid);
if (mcolumn && Object.keys(mcolumn.get('styling')).length === 0) {
let row = row_inner[i].closest('.module_row'),
mrow = Registry.get(row.dataset.cid);
if (mrow && Object.keys(mrow.get('styling')).length === 0) {
row.classList.add('tf_hide');
for (let rows = builder.querySelectorAll('.tf_hide.module_row'),i = rows.length - 1; i > -1; --i) {
rows[i].classList.remove('tf_hide');
for(let items = builder.querySelectorAll('[data-cid]'),i=items.length-1;i>-1;--i){
Registry.get(items[i].dataset.cid)?.previewVisibility();
item.draggable=!api.isPreview;
const bpPoints = themify_vars.breakpoints,
wrap=this.el.tfClass('breakpoint_switcher')[0];
for (let bp in bpPoints) {
let ul=createElement('ul',{class:'submenu devices tf_hide tf_abs_t',tabindex:-1}),
first=createElement('li','','Breakpoint Settings'),
devices = 'mobile' === bp ? mobile : tablet;
first.dataset.width='mobile' === bp ? val :val[1];
first.dataset.height='tablet' === bp?bpPoints.tablet_landscape[1]:val[0];
let size = 'tablet_landscape' === bp ? [devices[d][1],devices[d][0]] : devices[d];
ul.appendChild(createElement('li',{'data-width':size[0],'data-height':size[1]},i18n[d]+' ('+size[0]+'X'+size[1]+')'));
wrap.tfClass(bp)[0].appendChild(ul);
{width:w,height:h}=item.dataset;
this.el.tfClass('selected_device')[0]?.classList.remove('selected_device');
item.classList.add('selected_device');
return this.switchToBreakpoint(1 * w, 1 * h);
let breakpoint = 'desktop',
if (item.classList.contains('breakpoint-tablet')) {
} else if (item.classList.contains('breakpoint-tablet_landscape')) {
breakpoint = 'tablet_landscape';
} else if (item.classList.contains('breakpoint-mobile')) {
if (api.activeBreakPoint === breakpoint) {
// Already in this breakpoint, so return
w = breakpoint !== 'desktop' ? api.Utils.getBPWidth(breakpoint) - 1 : '';
return this.switchToBreakpoint(w, '');
if (this.scrollY !== window.scrollY) {
window.scroll(0, this.scrollY);
if (this.scrollY !== topWindow.scrollY) {
topWindow.scroll(0, this.scrollY);
switchToBreakpoint(w, h) {
return new Promise(resolve => {
if(topBodyCl.contains('tb_start_change_mode')){
let breakpoint = 'desktop',
prevBreakPoint = api.activeBreakPoint,
iframe=topWindowDoc.tfId('tb_iframe');
const bpPoints = themify_vars.breakpoints;
for (let i in bpPoints) {
if (Array.isArray(bpPoints[i])) {
if (bpPoints[i][0] <= w && w <= bpPoints[i][1]) {
} else if (w <= bpPoints[i]) {
if (api.isDocked !== false && 'tablet_landscape' === breakpoint) {
const wspace = topBody.tfClass('tb_workspace_container').offsetWidth;
w = wspace; // make preview fit the screen when dock mode active
if (iframe!==null && w === iframe.style.width && h === iframe.style.height) {
api.ActionBar.disable=true;
let willChange = w !== '' ? 'width' : '';
willChange += h !== '' ? (willChange !== '' ? ',height' : '') : '';
iframe.style.willChange = willChange;
let classses = [bodyCl, topBodyCl, this.el.classList,api.MainPanel.el.classList, api.SmallPanel.el.classList],
viewportElement,//need to keep scroll position,to avoid scroll jumping
is_resizing = iframe?.classList.contains('tb_resizing_start'),
for (let i = items.length - 1; i > -1; --i) {
items[i].style.display = '';
bodyCl.toggle('tf_scrollbar', breakpoint !== 'desktop');
//this.el.tfClass('compact_switcher')[0].tfTag('svg')[0].className = item.tfTag('svg')[0].className;
for (let i = classses.length - 1; i > -1; --i) {
cls.remove('builder-breakpoint-' + prevBreakPoint);
cls.toggle('tb_responsive_mode', breakpoint !== 'desktop');
cls.add('builder-breakpoint-' + breakpoint);
Themify.trigger('themify_builder_change_mode', [prevBreakPoint, breakpoint]);
api.scrollTo=api.ActionBar.disable = classses = viewportElement= iframe=items = is_resizing=prevBreakPoint = breakpoint = null;
iframe.style.willChange = '';
if (breakpoint === 'desktop') {
topBody.style.height = '';
topWindow.tfOff('scroll', this._iframeScroll, {
window.tfOff('scroll', this._iframeScroll, {
if (breakpoint !== 'desktop') {
topWindow.tfOn('scroll', this._iframeScroll, {
window.tfOn('scroll', this._iframeScroll, {
if(!api.scrollTo && viewportElement){
api.scrollTo=viewportElement;
api.Utils.scrollTo(api.scrollTo);
for (let i = classses.length - 1; i > -1; --i) {
classses[i].remove('tb_start_animate');
iframe.style.transition='';
api.Utils.onResize(true).then(() => {
api.Utils.setColumnsCount(doc.tfClass('module_column'));
if(breakpoint==='desktop'){
this.el.tfClass('selected_device')[0]?.classList.remove('selected_device');
api.Utils.scrollTo(api.scrollTo);//maybe js change position
topWindow.scroll(0,window.scrollY);
for (let i = classses.length - 1; i > -1; --i) {
classses[i].remove('tb_start_change_mode');
zoom=api.zoomMeta && ~~api.zoomMeta!==100?this.zoom({item:this.el.tfClass('zoom_toggle')[0]}):Promise.resolve();
// disable zoom if active
api.activeBreakPoint = breakpoint;
viewportElement=api.liveStylingInstance.el?api.liveStylingInstance.el:doc.elementFromPoint((Themify.w/2)-20, this.el.offsetHeight);
//hide the hidden rows for fast resizing
const childs = api.Builder.get().el.children,
if (el !== null && el !== undefined) {
const off = el.getBoundingClientRect();
if ((off.bottom < 0 && off.top < 0) || off.top > Themify.h) {
el.style.display = 'none';
for (let i = childs.length - 1; i > -1; --i) {
fillHidden(doc.tfId('headerwrap'));
fillHidden(doc.tfId('footerwrap'));
for (let i = classses.length - 1; i > -1; --i) {
classses[i].add('tb_start_animate', 'tb_start_change_mode'); //disable all transitions
iframe.tfOn('transitionend', callback,{passive:true,once:true})
if (doc.readyState === 'interactive' || doc.readyState === 'complete') {
doc.tfOn('DOMContentLoaded', ()=>{
}, {once: true, passive: true});
})(tb_app,_CLICK_,body,topBody,bodyCl,topThemify,topWindowDoc);