Refactor custom button section: move .custom-buttons to a new position in the category description and add editing mode guard
This commit is contained in:
@@ -295,12 +295,155 @@ jQuery(document).ready(function ($) {
|
|||||||
$btnBox.removeClass('active')
|
$btnBox.removeClass('active')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
const buttons = document.querySelector('#category-description .custom-buttons');
|
|
||||||
const target = document.querySelector('.row.\\31 11');
|
|
||||||
if (buttons && target) {
|
|
||||||
target.parentNode.insertBefore(buttons, target);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* custom.js — LEKKIE przeniesienie sekcji .custom-buttons
|
||||||
|
Góra: klony top-level bloków (dzieci #category-description) z WYŁĄCZNIE .custom-buttons
|
||||||
|
Dół: oryginał bez sekcji .custom-buttons
|
||||||
|
NIE DZIAŁA podczas edycji w Elementor/Creative Elements.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// --- GUARD: nie uruchamiaj w trybie edycji (Elementor / Creative Elements) ---
|
||||||
|
function isEditing() {
|
||||||
|
var href = String(location.href || '');
|
||||||
|
var ref = String(document.referrer || '');
|
||||||
|
var topHref = '';
|
||||||
|
try { topHref = String(window.top.location.href || ''); } catch (e) { /* cross-origin fallback */ }
|
||||||
|
|
||||||
|
// Zbiorcza „słomka” do przeszukania (ramka, referrer, parent)
|
||||||
|
var haystack = (href + ' ' + ref + ' ' + topHref).toLowerCase();
|
||||||
|
|
||||||
|
// 1) Najpewniejsze: kontroler zaplecza CE
|
||||||
|
if (haystack.indexOf('controller=adminceeditor') !== -1) return true;
|
||||||
|
|
||||||
|
// 2) Podgląd/edycja elementora/CE
|
||||||
|
if (haystack.indexOf('elementor-preview') !== -1) return true;
|
||||||
|
|
||||||
|
// 3) Klasy/markery edytora na body w tej ramce
|
||||||
|
var body = document.body;
|
||||||
|
if (body && /\b(elementor-editor-active|ce-editor-active|ce-editing)\b/i.test(body.className)) return true;
|
||||||
|
|
||||||
|
// 4) Panele edytora w oknie nadrzędnym (gdy front leci w iframe)
|
||||||
|
if (window.self !== window.top) {
|
||||||
|
try {
|
||||||
|
if (window.top.document.querySelector('#elementor-panel, .elementor-panel, #ce-editor, .ce-editor, .ce-panel')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (e) { /* ignoruj brak dostępu */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5) Ręczny wyłącznik
|
||||||
|
if (window.__CE_DISABLE_MOVE === true) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wstaw ZARAZ po definicji isEditing()
|
||||||
|
if (isEditing()) return;
|
||||||
|
|
||||||
|
var SOURCE_SEL = '#category-description';
|
||||||
|
var TARGET_SEL = '.row.\\31 11'; // .row.111 (esc)
|
||||||
|
var WRAP_ID = 'moved-category-structure';
|
||||||
|
var BUTTON_SEC = 'section.custom-buttons, section.custom-buttons1';
|
||||||
|
var ANY_SEC = 'section'; // lub 'section.elementor-top-section' jeśli chcesz zawęzić
|
||||||
|
|
||||||
|
var didFinish = false;
|
||||||
|
var obs = null;
|
||||||
|
var debounceId = null;
|
||||||
|
|
||||||
|
function ensureWrapper(target) {
|
||||||
|
var wrap = document.getElementById(WRAP_ID);
|
||||||
|
if (!wrap) {
|
||||||
|
wrap = document.createElement('div');
|
||||||
|
wrap.id = WRAP_ID;
|
||||||
|
wrap.className = 'moved-category-structure';
|
||||||
|
target.parentNode.insertBefore(wrap, target);
|
||||||
|
}
|
||||||
|
return wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
function topLevelBlocks(src) {
|
||||||
|
var out = [];
|
||||||
|
for (var i = 0; i < src.children.length; i++) {
|
||||||
|
var el = src.children[i];
|
||||||
|
if (el.nodeType === 1) out.push(el);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cloneBlockWithOnlyButtons(block) {
|
||||||
|
var clone = block.cloneNode(true);
|
||||||
|
clone.querySelectorAll(ANY_SEC + ':not(.custom-buttons):not(.custom-buttons1)').forEach(function (sec) {
|
||||||
|
sec.remove();
|
||||||
|
});
|
||||||
|
clone.querySelectorAll('.ce-edit-btn, .ce-edit-outline').forEach(function (n) { n.remove(); });
|
||||||
|
if (!clone.querySelector(BUTTON_SEC)) return null;
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncOnce() {
|
||||||
|
if (didFinish) return true;
|
||||||
|
|
||||||
|
var src = document.querySelector(SOURCE_SEL);
|
||||||
|
var target = document.querySelector(TARGET_SEL);
|
||||||
|
if (!src || !target) return false;
|
||||||
|
|
||||||
|
var blocks = topLevelBlocks(src);
|
||||||
|
var blocksWithButtons = blocks.filter(function (b) { return !!b.querySelector(BUTTON_SEC); });
|
||||||
|
if (!blocksWithButtons.length) return false;
|
||||||
|
|
||||||
|
var wrap = ensureWrapper(target);
|
||||||
|
|
||||||
|
var frag = document.createDocumentFragment();
|
||||||
|
blocksWithButtons.forEach(function (b) {
|
||||||
|
var prunedClone = cloneBlockWithOnlyButtons(b);
|
||||||
|
if (prunedClone) frag.appendChild(prunedClone);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!frag.firstChild) return false;
|
||||||
|
|
||||||
|
while (wrap.firstChild) wrap.removeChild(wrap.firstChild);
|
||||||
|
wrap.appendChild(frag);
|
||||||
|
|
||||||
|
src.querySelectorAll(BUTTON_SEC).forEach(function (sec) {
|
||||||
|
if (sec && sec.parentNode) sec.parentNode.removeChild(sec);
|
||||||
|
});
|
||||||
|
|
||||||
|
didFinish = true;
|
||||||
|
if (obs) obs.disconnect();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function trySyncDebounced() {
|
||||||
|
if (debounceId) return;
|
||||||
|
debounceId = setTimeout(function () {
|
||||||
|
debounceId = null;
|
||||||
|
if (syncOnce() && obs) obs.disconnect();
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', trySyncDebounced, { once: true });
|
||||||
|
} else {
|
||||||
|
trySyncDebounced();
|
||||||
|
}
|
||||||
|
|
||||||
|
obs = new MutationObserver(trySyncDebounced);
|
||||||
|
obs.observe(document.body || document.documentElement, { childList: true, subtree: true });
|
||||||
|
|
||||||
|
if (window.prestashop && typeof window.prestashop.on === 'function') {
|
||||||
|
['updateProductList', 'updatedCart', 'updatedProduct'].forEach(function (ev) {
|
||||||
|
window.prestashop.on(ev, trySyncDebounced);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
(function hookHistory() {
|
||||||
|
var _ps = history.pushState, _rs = history.replaceState;
|
||||||
|
function onNav() { trySyncDebounced(); }
|
||||||
|
history.pushState = function () { _ps.apply(this, arguments); onNav(); };
|
||||||
|
history.replaceState = function () { _rs.apply(this, arguments); onNav(); };
|
||||||
|
window.addEventListener('popstate', onNav);
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
|||||||
Reference in New Issue
Block a user