Poprawki w skryptach JavaScript oraz aktualizacja rozmiaru pliku w synchronizacji FTP

This commit is contained in:
2025-10-31 15:38:54 +01:00
parent a0018a65f3
commit a5c3266443
3 changed files with 370 additions and 7 deletions

View File

@@ -117,11 +117,17 @@
},
"google-merchant_id-1.xml": {
"type": "-",
"size": 18781948,
"size": 18540350,
"lmtime": 0,
"modified": true
},
".htaccess": {
"type": "-",
"size": 87379,
"lmtime": 0,
"modified": true
},
".htaccess.2025-10-16-1760598489": {
"type": "-",
"size": 87360,
"lmtime": 0,

View File

@@ -2864,7 +2864,6 @@ var Review = {
".bootstrap-touchspin-up, .bootstrap-touchspin-down, .remove-from-cart",
function (e) {
e.preventDefault()
e.stopPropagation()
var url_call = ""
var $input = $(e.currentTarget)

View File

@@ -191,7 +191,7 @@ $(document).ready(function() {
paymentRequestLock = true;
setTimeout(() => paymentRequestLock = false, 1000); // odblokuj po sekundzie
let payment_module = $(this).data('module-name');
let payment_module = $(this).val();
$.ajax({
type: "POST",
url: pdgoogleanalytycs4pro_ajax_link,
@@ -487,7 +487,7 @@ $(document).ready(function() {
// qty up > stadard theme ps 17
$('body').on("click", "button.bootstrap-touchspin-up", function(e) {
let qty_input = $(this).parent().parent().find('input.js-cart-line-product-quantity'),
let qty_input = $(this).parent().parent().find('input.cart-line-product-quantity'),
updat_url = qty_input.attr('data-update-url'),
url_params = PdParseQuery(updat_url),
iso_code = prestashop.currency.iso_code;
@@ -536,9 +536,9 @@ $(document).ready(function() {
});
// qty down > stadard theme ps 17
$('body').on("click", "button.bootstrap-touchspin-down", function(e) {
$( 'body' ).on( "click", "button.bootstrap-touchspin-down", function(e) {
let qty_input = $(this).parent().parent().find('input.js-cart-line-product-quantity'),
let qty_input = $(this).parent().parent().find('input.cart-line-product-quantity'),
updat_url = qty_input.attr('data-update-url'),
url_params = PdParseQuery(updat_url),
iso_code = prestashop.currency.iso_code;
@@ -841,4 +841,362 @@ $(document).ready(function() {
}
return query;
}
});
});
/* GA4: view_item_list + select_item (homepage + PDP) — finalna wersja */
(function (window, document) {
'use strict';
if (window.__ga4ItemListInit) return;
window.__ga4ItemListInit = true;
// === Funkcje wspólne ===
function isHomepage() {
var b = document.body;
return b && (b.id === 'index' || b.classList.contains('page-index') || b.classList.contains('index'));
}
function isProductPage() {
var b = document.body;
return b && (b.id === 'product' || b.classList.contains('page-product'));
}
function parsePrice(str) {
if (!str) return;
var s = String(str).replace(/\u00A0/g, ' ')
.replace(/zł|PLN/gi, '')
.trim()
.replace(/\s/g, '')
.replace(',', '.');
var p = parseFloat(s);
return isNaN(p) ? undefined : p;
}
function getPathSegment(url, idx) {
try {
var u = new URL(url, window.location.origin);
var seg = u.pathname.split('/').filter(Boolean);
return seg[idx] || undefined;
} catch (e) {
return;
}
}
function gtagEvent(name, params) {
if (typeof window.gtag === 'function') {
window.gtag('event', name, params || {});
} else {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'gtag_event_name': name,
'gtag_event_params': params || {}
});
}
}
function collectItems(section, cfg) {
var nodes = section.querySelectorAll(cfg.cardSelector);
var items = [];
nodes.forEach(function (card, i) {
var id = card.getAttribute('data-id-product');
var varId = card.getAttribute('data-id-product-attribute');
var nameEl = card.querySelector(cfg.nameSelector);
var name = nameEl ? nameEl.textContent.trim() : undefined;
var urlEl = card.querySelector(cfg.urlSelector);
var url = urlEl ? urlEl.getAttribute('href') : undefined;
var priceEl = card.querySelector(cfg.priceSelector);
var price = parsePrice(priceEl ? priceEl.textContent : '');
var item_category = url ? decodeURIComponent(getPathSegment(url, 0) || '') : undefined;
var item = {
item_id: id || undefined,
item_name: name || undefined,
index: i + 1,
item_list_id: cfg.list_id,
item_list_name: cfg.list_name,
price: price,
currency: 'PLN'
};
if (item_category) item.item_category = item_category;
if (varId && varId !== '0') item.item_variant = varId;
items.push(item);
});
return items;
}
function sendViewItemList(items, cfg) {
gtagEvent('view_item_list', {
item_list_id: cfg.list_id,
item_list_name: cfg.list_name,
items: items
});
}
function wireSelectItem(section, cfg) {
section.addEventListener('click', function (e) {
var anchor = e.target.closest(cfg.clickAnchorSelector);
if (!anchor) return;
var card = anchor.closest(cfg.cardSelector);
if (!card) return;
var nodes = section.querySelectorAll(cfg.cardSelector);
var idx = Array.prototype.indexOf.call(nodes, card);
if (idx < 0) return;
var items = collectItems(section, cfg);
var item = items[idx];
if (!item) return;
gtagEvent('select_item', {
item_list_id: cfg.list_id,
item_list_name: cfg.list_name,
items: [item]
});
});
}
// === Inicjalizacja sekcji ===
function initSection(cfg) {
if (cfg.when && !cfg.when()) return;
var section = document.querySelector(cfg.sectionSelector);
if (!section || section.__viewItemListSent) return;
var send = function () {
if (section.__viewItemListSent) return;
var items = collectItems(section, cfg);
if (items.length) {
sendViewItemList(items, cfg);
section.__viewItemListSent = true;
}
};
// homepage — dopiero po widoczności; PDP — od razu
if (cfg.deferByScroll) {
if ('IntersectionObserver' in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
send();
io.disconnect();
}
});
}, { threshold: [0.5] });
io.observe(section);
} else {
if (document.readyState === 'loading')
document.addEventListener('DOMContentLoaded', send);
else send();
}
} else {
// natychmiast
send();
}
wireSelectItem(section, cfg);
}
// === Konfiguracje sekcji ===
var COMMON = {
cardSelector: '.product-miniature.js-product-miniature',
urlSelector: 'a.thumbnail.product-thumbnail',
priceSelector: '.product-price-and-shipping [itemprop="price"].price, .product-price-and-shipping .price',
clickAnchorSelector: '.product-miniature a'
};
// Homepage — "Super oferty" (tylko po widoczności)
var cfgFeatured = Object.assign({}, COMMON, {
when: isHomepage,
sectionSelector: 'section.featured-products',
list_name: 'Super oferty',
list_id: 'featured-products',
nameSelector: '[itemprop="name"]',
deferByScroll: true
});
// PDP — "Zobacz także" (natychmiast)
var cfgAccessories = Object.assign({}, COMMON, {
when: isProductPage,
sectionSelector: 'section.product-accessories',
list_name: 'Zobacz także',
list_id: 'product-accessories',
nameSelector: '[itemprop="name"]',
deferByScroll: false
});
// PDP — "Podobne produkty z tej samej kategorii" (natychmiast)
var cfgCategoryRelated = Object.assign({}, COMMON, {
when: isProductPage,
sectionSelector: 'section.category-products',
list_name: 'Podobne produkty z tej samej kategorii',
list_id: 'category-related',
nameSelector: '.product-title, [itemprop="name"]',
deferByScroll: false
});
// === Start ===
function start() {
initSection(cfgFeatured);
initSection(cfgAccessories);
initSection(cfgCategoryRelated);
}
if (document.readyState === 'loading')
document.addEventListener('DOMContentLoaded', start);
else
start();
})(window, document);
/* GA4: view_promotion + select_promotion dla #bonslick (homepage) */
(function (window, document) {
'use strict';
if (window.__ga4PromoInit) return;
window.__ga4PromoInit = true;
function isHomepage() {
var b = document.body;
return !!b && (b.id === 'index' || b.classList.contains('page-index') || b.classList.contains('index'));
}
if (!isHomepage()) return;
// gtag fallback do dataLayer, gdyby gtag nie był gotowy
function gtagEvent(name, params) {
if (typeof window.gtag === 'function') {
window.gtag('event', name, params || {});
} else {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'gtag_event_name': name,
'gtag_event_params': params || {}
});
}
}
var ROOT_SEL = '#bonslick';
var LINK_SEL = 'li.slick-slide:not(.slick-cloned) a.link-bonslick';
var ANY_LINK = 'a.link-bonslick';
var LOCATION = 'homepage_bonslick';
var sentView = false;
// Pomocnicze: wydłub nazwę kreatywu z <img> albo z src
function getCreativeName(imgEl) {
if (!imgEl) return undefined;
var alt = imgEl.getAttribute('alt');
if (alt && alt.trim()) return alt.trim();
var src = imgEl.getAttribute('data-src') || imgEl.getAttribute('src') || '';
if (!src) return undefined;
try {
var base = src.split('/').pop();
return base ? base.split('?')[0] : undefined;
} catch (e) { return undefined; }
}
// Zbierz unikalne slajdy (bez .slick-cloned) -> items[] do view_promotion
function collectPromoItems(container) {
var items = [];
var seenKey = Object.create(null);
var links = container.querySelectorAll(LINK_SEL);
links.forEach(function (a, i) {
var href = a.getAttribute('href') || '';
var title = a.getAttribute('title') || '';
var img = a.querySelector('img');
var creative = getCreativeName(img);
// klucz unikalności (href + creative)
var key = (href || '') + '|' + (creative || '');
if (seenKey[key]) return;
seenKey[key] = true;
items.push({
promotion_id: href || undefined, // ID jako docelowy URL
promotion_name: (title || creative || '').trim() || undefined,
creative_name: creative || undefined,
creative_slot: String(i + 1), // pozycja w sliderze (bez klonów)
location_id: LOCATION
});
});
return items;
}
// Przy kliknięciu w JEDEN slajd => select_promotion z 1 itemem
function buildClickedItem(anchor) {
var href = anchor.getAttribute('href') || '';
var title = anchor.getAttribute('title') || '';
var img = anchor.querySelector('img');
var creative = getCreativeName(img);
// Ustal slot z indeksu slajdu (bez klonów jeśli się da)
var li = anchor.closest('li.slick-slide');
var slot = undefined;
if (li) {
var container = anchor.closest(ROOT_SEL) || document;
var list = Array.prototype.slice.call(container.querySelectorAll(LINK_SEL));
var idx = list.indexOf(anchor);
if (idx >= 0) slot = String(idx + 1);
}
return [{
promotion_id: href || undefined,
promotion_name: (title || creative || '').trim() || undefined,
creative_name: creative || undefined,
creative_slot: slot,
location_id: LOCATION
}];
}
function fireViewPromotion(container) {
if (sentView) return;
var items = collectPromoItems(container);
if (!items.length) return;
gtagEvent('view_promotion', { items: items });
sentView = true;
}
function init() {
var root = document.querySelector(ROOT_SEL);
if (!root) return;
// 1) view_promotion: gdy slider wejdzie >=50% w viewport (po wyświetleniu)
if ('IntersectionObserver' in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
fireViewPromotion(root);
io.disconnect();
}
});
}, { threshold: [0.5] });
io.observe(root);
} else {
// Fallback: wyślij po DOMContentLoaded (slider zwykle jest nad foldem)
fireViewPromotion(root);
}
// 2) select_promotion: delegacja kliknięcia (obsłuży także klony)
root.addEventListener('click', function (e) {
var a = e.target.closest(ANY_LINK);
if (!a || !root.contains(a)) return;
var items = buildClickedItem(a);
if (!items || !items.length) return;
gtagEvent('select_promotion', { items: items });
});
// 3) Gdy slick doda slajdy asynchronicznie — lekki watchdog z MutationObserver
if ('MutationObserver' in window) {
var mo = new MutationObserver(function () {
// jeśli jeszcze nie poszło, a pojawiły się slajdy — spróbuj wysłać
if (!sentView) {
var hasSlides = root.querySelector(LINK_SEL);
if (hasSlides && !('IntersectionObserver' in window)) {
fireViewPromotion(root);
}
}
});
mo.observe(root, { childList: true, subtree: true });
// rozłącz po wysłaniu
var stopWhenSent = setInterval(function(){
if (sentView) { mo.disconnect(); clearInterval(stopWhenSent); }
}, 1500);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})(window, document);