: 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
((api,_CLICK_,body,topBody,bodyCl,topThemify,topWindowDoc) => {
const {isFrontend,Registry}=api;
const topSvg=topWindowDoc.tfId('tf_svg');
const defs=topSvg.firstChild,
st=defs.querySelector('#tf_fonts_style'),
f=createDocumentFragment();
doc.tfId('tf_fonts_style').textContent+=st.textContent;
for(let ch=defs.children,i=ch.length-1;i>-1;--i){
doc.tfId('tf_svg').firstChild.appendChild(f);
const root = doc.tfId('tb_main_toolbar_root'),
fr = root.firstElementChild,
bpSt=createElement('style'),
fragment=createDocumentFragment(),
svg=doc.tfId('tf_svg').cloneNode(true);
for(let bp=api.breakpointsReverse,i=bp.length-1;i>-1;--i){
cssText+='--tb_bp_'+bp[i]+':'+api.Utils.getBPWidth(bp[i])+'px;';
bpSt.textContent=':root{'+cssText+'}';
body.appendChild(bpSt.cloneNode(true));
topBody.appendChild(svg.cloneNode(true));
fragment.append(doc.tfId('tf_lazy_common').cloneNode(true),svg.cloneNode(true));
if (fr) { // shadowrootmode="open" isn't support
mode: fr.getAttribute('shadowrootmode')
}).appendChild(fr.content);
root.shadowRoot.prepend(fragment);
topBody.appendChild(root);
this.el = root.shadowRoot.tfId('toolbar');
const combineCss=this.el.getRootNode().querySelector('#module_combine_style');
topWindowDoc.head.prepend(bpSt,combineCss.cloneNode(true));
doc.tfId('themify-builder-admin-ui-css').before(combineCss.cloneNode(true));
Themify.on('themify_builder_ready',()=>{
(doc.tfId('tb_canvas_block') || doc.tfClass('tb_active_builder')[0]).before(root);
Themify.trigger('tb_toolbar_loaded');
requestAnimationFrame(()=>{
requestAnimationFrame(()=>{
body.prepend(api.MainPanel.el.getRootNode().querySelector('#module_drag_grids_style').cloneNode(true));
topThemify.loadCss(Themify.url + 'themify-metabox/css/themify.minicolors');
topThemify.loadCss(Themify.builder_url + 'css/editor/themify-combobox');
'.revision_btn': 'initRevision',
'.duplicate': 'duplicate',
'.tf_close': 'panelClose',
'.breakpoint_switch': 'breakpointSwitcher',
'.devices': 'deviceSwitcher',
'.custom_css': 'addCustomCSS',
'.preview': 'previewBuilder',
'.backend_mode':'backendMode',
'.mode input': 'modChange'
const sel = Object.keys(events[e.type]),
item = e.target.closest(sel);
for (let i = 0; i < sel.length; ++i) {
if (item.matches(sel[i])) {
const f = events[e.type][sel[i]];
api.Drag(api.Builder.get().el);
api.Utils.updateDocumentSize();
localStorage.removeItem('tb_mode');//deprecated
topThemify.on('tfsmartresize',e=>{
Themify.trigger('tfsmartresize',e);
this._setPopularDevices();
}, true,api.is_builder_ready)
.trigger('tb_toolbar_style_ready');
(new ResizeObserver(entries =>{
cancelAnimationFrame(req);
const el=entries[0].target;
req = requestAnimationFrame(() => {
el.classList.toggle('compact_menu',el.getBoundingClientRect().width<=800);
const fr=createDocumentFragment(),
toolbarRoot = this.el.getRootNode(),
commonCss = toolbarRoot.querySelector('#tf_lazy_common'),
svgCss = toolbarRoot.querySelector('#tf_svg'),
baseCss = toolbarRoot.querySelector('#tf_base');
fr.append(commonCss.cloneNode(true),svgCss.cloneNode(true),baseCss.cloneNode(true));
const isDarkSet=localStorage.getItem('tb_dark_mode');
if (isDarkSet==='1' || (isDarkSet!=='-1' && window.matchMedia('(prefers-color-scheme:dark)').matches)) {
this.el.tfClass('dark_mode')[0].checked = true;
this._changeDarkMode(true);
if (localStorage.getItem('tb_inline_editor')) {
api.inlineEditor = false;
this.el.tfClass('inline_editor_mode')[0].checked = false;
if (localStorage.getItem('tb_right_click')) {
this.el.tfClass('right_click_mode')[0].checked = false;
api.MainPanel.openFloat();
doc.head.insertAdjacentHTML('afterbegin', '<base target="_parent">');
topWindow.tfOn('beforeunload',e => {
if(this.preventBeforeMsg!==true && api.Builder.get().isSaved===false && api.undoManager.hasUndo()){
return e.returnValue='Are you sure';
return new Promise(resolve=>{
const pr= api.Builder.get().isSaved===false && api.undoManager.hasUndo()?
api.LiteLightBox.confirm({
}):Promise.resolve('no');
else if (answer === 'no') {
this.preventBeforeMsg=true;
topWindow.location.reload();
if (target.classList.contains('load_revision')) {
api.Spinner.showLoader();
await Promise.all([Themify.loadJs(api.componentsURL +'revisions',window.TB_Revisions), topThemify.loadCss(Themify.builder_url + 'css/editor/components/revisions')]);
await TB_Revisions.init(target);
if (target.classList.contains('load_revision')) {
const ul=target.closest('ul');
if (target.classList.contains('load_layout')) {
api.Spinner.showLoader();
await Promise.all([Themify.loadJs(api.componentsURL + 'layouts',!!window.TB_Layouts), topThemify.loadCss(Themify.builder_url + 'css/editor/components/layouts')]);
await TB_Layouts.init(target);
if (target.hasAttribute('data-type')) {
api.Spinner.showLoader();
await Themify.loadJs(api.componentsURL + 'import',!!window.TB_Import);
await TB_Import.init(target);
api.Spinner.showLoader();
await Promise.all([Themify.loadJs(api.componentsURL + 'export',!!window.TB_Export),api.Helper.loadJsZip()]);
api.Spinner.showLoader();
await Themify.loadJs(api.componentsURL + 'help',!!window.TB_Help);
await api.LightBox.save();
const cl=this.el.tfClass('backend_mode')[0].classList;
if(!cl.contains('working')){
api.Spinner.showLoader();
await window.TB_BuilderContentLightbox?.saveAll();
const builder=api.Builder.get(),
backendUi = doc.tfId(id),
adminui = doc.tfId( 'themify-builder-admin-ui-css'),
paddingMode=this.el.tfClass('padding_dragging_mode')[0],
inlineMode=this.el.tfClass('inline_editor_mode')[0],
prms.push(Themify.loadCss(Themify.builder_url + 'css/editor/backend-mode',id,null,adminui.nextSibling));
backendUi.disabled=api.isVisual;
paddingMode.checked=inlineMode.checked=api.inlineEditor=false;
paddingMode.disabled=inlineMode.disabled=true;
api.liveStylingInstance.reset();
api.inlineEditor = inlineMode.checked=!localStorage.getItem('tb_inline_editor');
paddingMode.checked=!localStorage.getItem('tb_disable_padding_dragging');
paddingMode.disabled=inlineMode.disabled=false;
cl.toggle('active',!isVisual);
bodyCl.toggle('themify_builder_active',isVisual);
for(let i=docs.length-1;i>-1;--i){
docs[i].classList.toggle('tb_backend_mode',!isVisual);
paddingMode.closest('.switch-wrapper').classList.toggle('disabled',!isVisual);
inlineMode.closest('.switch-wrapper').classList.toggle('disabled',!isVisual);
Themify.trigger('tb_inline_editor_changed');
prms.push(builder.reLoad({builder_data:data,custom_css:builder.customCss},false,false));
api.Module.loadBackendLightbox('preload');
e.target.closest('.tree').classList.contains('active')?api.Tree.close():api.Tree.open();
const answer=await api.LiteLightBox.confirm({msg:'confirm_on_duplicate_page'});
await api.Builder.get().save();
api.Spinner.showLoader('show');
const resp=await api.LocalFetch({
action: 'tb_duplicate_page',
tb_is_admin: !api.isVisual?1:0
await api.Spinner.showLoader('done');
topWindow.location.href=url.replaceAll('&', '&');
api.Spinner.showLoader('error');
TF_Notification.showHide('error',e,4000);
const cl = e.item.classList,
checked = e.item.checked === true;
if (cl.contains('right_click_mode')) {
checked ? localStorage.removeItem('tb_right_click') : localStorage.setItem('tb_right_click', 1);
else if (cl.contains('padding_dragging_mode')) {
checked ? localStorage.removeItem('tb_disable_padding_dragging') : localStorage.setItem('tb_disable_padding_dragging', 1);
else if (cl.contains('dark_mode')) {
localStorage.setItem('tb_dark_mode', checked?1:-1);
this._changeDarkMode(checked);
const areas=topBody.querySelectorAll('.tf_cdm textarea');
for(let i=areas.length-1;i>-1;--i){
areas[i].tf_mirror?.setDarkMode(checked);
else if (cl.contains('inline_editor_mode')) {
localStorage.removeItem('tb_inline_editor');
localStorage.setItem('tb_inline_editor', 1);
api.inlineEditor = checked;
Themify.trigger('tb_inline_editor_changed');
_changeDarkMode(enabled){
const file = doc.tfId('tb_dark_mode_style'),
topFile = isFrontend ? topWindowDoc.getElementById('tb_dark_mode_style') : null;
const adminui = doc.tfId( 'themify-builder-admin-ui-css');
Themify.loadCss(Themify.builder_url + 'css/editor/darkmode-ui','tb_dark_mode_style',null,adminui.nextSibling);
topThemify.loadCss(Themify.builder_url + 'css/editor/darkmode-ui','tb_dark_mode_style',null,topWindowDoc.querySelector('link[href*="/components/lightbox."]').nextSibling);
file.disabled = !enabled;
topFile.disabled = !enabled;
const link = e.item.getAttribute('href');
Themify.trigger('tb_switch_frontend',[link]);
topWindow.location.href = link;
await api.LightBox.save();
await window.TB_BuilderContentLightbox?.saveAll();
if(api.LayoutPart?.item){
await api.LayoutPart.item.save();
await api.LayoutPart.item.close();
await api.Builder.get().save();
return new Promise(resolve=>{
if (isFrontend && 'desktop' === api.activeBreakPoint) {
let zoom_size = item.dataset.zoom.toString() || '100',
canvas = topBody.tfClass('tb_iframe')[0],
parent= item.closest('.zoom_menu'),
zoomItems = parent.querySelectorAll('.submenu .zoom'),
zoomToggle = parent.tfClass('zoom_toggle')[0].parentNode;
if (item.classList.contains('zoom_toggle')) {
zoom_size = api.zoomMeta || zoom_size !== '100' ? '100' : '50';
if (api.zoomMeta === zoom_size || (zoom_size === '100' && !api.zoomMeta)) {
for (let i = zoomItems.length - 1; i > -1; --i) {
zoomItems[i].parentNode.classList.toggle('selected_zoom',zoom_size!=='100' && zoomItems[i].dataset.zoom === zoom_size);
canvas.tfOn('transitionend', () => {
api.Utils.onResize(true);
if (zoom_size !== '100') {
const scale = '50' === zoom_size ? 2 : 1.25;
canvas.parentNode.classList.add('tb_zoom_bg');
height = Math.max(topWindow.innerHeight * scale, 600) + 'px';
api.zoomMeta = zoom_size;
zoomToggle.classList.toggle('selected_zoom', api.zoomMeta);
bodyCl.toggle('tb_zoom_only', api.zoomMeta);
canvas.parentNode.style.height = height;
canvas.classList.remove('tb_zooming_50', 'tb_zooming_75');
if (zoom_size !== '100') {
canvas.classList.add('tb_zooming_' + zoom_size);
await api.LightBox.save();
value: api.Builder.get().id
target=e.target.closest('.custom_css'),
box = target.getBoundingClientRect();
target.classList.add('active');
api.LightBox.el.classList.add('tb_custom_css_lightbox');
let lb=await api.LightBox.setStandAlone(box.left, box.top).open(options),
input = lb.querySelector('#custom_css'),
saveBtn=lb.tfClass('builder_save_button')[0],
builder=api.Builder.get(),
css_id = 'tb_custom_css_'+builder.id,