Poprawki w skryptach JavaScript oraz aktualizacja rozmiaru pliku w synchronizacji FTP
This commit is contained in:
8
.vscode/ftp-kr.sync.cache.json
vendored
8
.vscode/ftp-kr.sync.cache.json
vendored
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user