data-litespeed-* atrybuty z dowolnego jQuery enqueue (jeśli WP
zacznie ładować jQuery ponownie później)
WYNIK:
• Nawet bez zmian w admin panelu → jQuery ładuje się natychmiast w head
• Wszystkie dependent scripts (Flatsome, WooCommerce, payu, blockUI)
znajdują window.jQuery i działają normalnie
• Mobile menu, filtry, AJAX dodawanie do koszyka, search live — wszystko
się odbloblouje
• Trade-off: jQuery ładowane synchronicznie w head → ~50ms blocking
render time. Można usunąć ten hack po wykluczeniu jQuery z defer/delay
w panel pluginu optymalizacyjnego.
v2.3.8 (pp-rescue.js robust against delayed jQuery loading):
PROBLEM ujawniony przez konsolę usera w v2.3.7:
Uncaught ReferenceError: jQuery is not defined
— w pp-rescue.js, pp-filters.js, flatsome.js, woocommerce.min.js,
payu-gateway.js, hoverIntent, blockUI, i ~12 innych skryptach
ROOT CAUSE:
Plugin optymalizacyjny (WP Rocket / LiteSpeed / Async JS / Flying Scripts)
defer-uje jQuery — przesuwa go na "delayed execution" — ale zależne
skrypty nie czekają na niego. Wszystko się sypie.
To NIE jest problem z naszym kodem — błędy istniały wcześniej, ale
teraz są widoczne (user otworzył konsolę).
FIX (assets/js/pp-rescue.js):
- REFACTOR na dwie fazy:
PHASE 1 — vanilla JS bez jQuery, fires natychmiast:
• ppRescueBannerBackgrounds_vanilla
• ppRescueLazyImages_vanilla
• IntersectionObserver dla off-screen images
• Window.PPRescueVanilla API
PHASE 2 — pollForJQuery() czeka max 5s na jQuery:
• Gdy jQuery dostępne → odpala mobile menu rescue + MutationObserver
• Gdy timeout → console.warn z instrukcją sprawdzenia plugina
- WYNIK: nawet jak jQuery jest broken, BANERY I OBRAZY ŁADUJĄ SIĘ.
Mobile menu wymaga jQuery, więc jeśli plugin go defer-uje za długo,
menu zostaje broken — user musi naprawić w admin panelu plugina.
USER ACTION REQUIRED (admin WordPress):
Otwórz plugin optymalizacyjny (najprawdopodobniej jeden z):
• WP Rocket → File Optimization → JavaScript → "Delay JavaScript Execution"
→ dodaj do "Excluded JavaScript Files": jquery, jquery-core, jquery-migrate
• LiteSpeed Cache → Page Optimization → JS Settings → "JS Defer" / "JS Delay"
→ JS Excludes: dodaj jquery
• Async JavaScript → Async/Defer exclusions: jquery, jquery-core
• Flying Scripts → Exclude keywords: jquery
Po wykluczeniu jQuery z defer/delay → wyczyść cache → wszystkie błędy znikną.
v2.3.7 (Hotfix dla v2.3.6 — naprawia filtry + mobile menu):
PROBLEM v2.3.6 (zgłoszone przez usera):
1. Filtry nie działają (desktop + mobile)
2. Mobile menu nadal nie otwiera się
ROOT CAUSE:
- Globalny handler `$(document).on('click.ppRescueMenu', '[data-open]', ...)` w main.js
przechwytywał WSZYSTKIE [data-open] kliki — search modal, account dropdown,
mini-cart i potencjalnie filter triggers. Wywoływał preventDefault → łamał handlery.
- MutationObserver z `mo.observe(document.body, ...)` z subtree:true odpalał się na
KAŻDY DOM mutation (filter dropdown UI, search autocomplete, etc.). Rescue functions
querySelectorAll całego document → ekstremalna degradacja performance, mogło
wpadać w pętlę gdy modyfikacje DOM wywoływały kolejne mutations.
- main.js ładuje się tylko na shop/category/product/homepage — więc rescue dla mobile
menu nie działał na pages where header hamburger appears (blog, cart, my-account).
FIX:
- WYCIĘTO cały rescue block z main.js. Zachowany tylko icon healer.
- NOWY plik: assets/js/pp-rescue.js — minimalny, surgical, idempotent.
- Enqueue GLOBALNIE w class-pp-assets.php (priorytet dependency: pp-core-js).
- Mobile menu handler ZAWĘŻONY do `.header-button a[data-open="#main-menu"]`
i `a.icon[data-open="#main-menu"]` — nie łapie innych [data-open] elements.
- MutationObserver scoped do `.products, .pp-products-grid, .pp-filter-results`
(NIE document.body). Throttled 150ms debounce. Triggeruje rescue TYLKO gdy
mutation zawiera nowy `<img[data-src]>` element. Filter dropdowns mogą działać.
- Wystawiony globalny `window.PPRescue` API: runAll(), rescueImages(),
rescueBackgrounds(), initMobileMenu() — można triggerować ręcznie z konsoli.
v2.3.6 (Rescue script — 3 fallbacks dla Flatsome lazy-load + data-open):
PROBLEM 1: Banner kategorii (background-image) nie ładuje się
- <div class="bg bg-fill"> bez klasy .bg-loaded
- inline CSS wymaga .bg.bg-loaded { background-image: url(//panpodloga.pl/wp-content/themes/flatsome-child/...) }
- Flatsome lazy-bg JS NIE dodaje klasy bg-loaded
PROBLEM 2: Product image lazy-load nie swapuje data-src → src
- WP Rocket / LiteSpeed / Smush zastępuje src placeholderem SVG
i przenosi URL do data-src
- Klasa "lazy-load" oczekuje plugin'owego JS który nie odpala dla
części produktów (IntersectionObserver fail, race condition)
PROBLEM 3: Mobile menu hamburger ([data-open="#main-menu"]) nie reaguje
- Flatsome's flatsome.js handler nie odpala dla data-open clicks
- Możliwe że asset optimization zerwała wiązanie
FIX (assets/main.js): trzy funkcje rescue z guardami idempotentności:
- ppRescueBannerBackgrounds() — dodaje .bg-loaded do każdego .bg.bg-fill
- ppRescueLazyImages() — swapuje data-src → src + data-srcset → srcset
dla każdego img[data-src] (działa też dla NIE-lazy-load class images)
- ppInitMobileMenuOpen() — własny handler [data-open] który buduje
off-canvas sidebar: slide-in z lewej/prawej, overlay, ESC + click outside
to close, close button X w prawym górnym rogu, scroll lock na html
ROBUSTNESS:
- IntersectionObserver z rootMargin 200px — łapie obrazy zanim wejdą
w viewport
- MutationObserver na document.body — automatycznie odpala rescue
na każdy nowy element (AJAX filters, infinite scroll, dynamic load)
- Triple-trigger: immediate + DOMContentLoaded + setTimeout 800ms + 2500ms
— łapie obrazy injectowane przez asynchroniczne pluginy
v2.3.5 (Mobile checkout polish — widoczność + sticky bar pod headerem + UX/UI):
STICKY CTA BOTTOM (był chowany pod Safari URL bar):
- padding-bottom zwiększone z (env safe-area + 10px) do (safe-area + 18px)
- min-height: 80px gwarantuje że bar zawsze ma miejsce na palec
- deeper shadow (0 -8px 32px + 0 -2px 6px) — wizualnie elevated
- animacja slide-up na page load (0.4s cubic-bezier)
- CTA button height 52px → 56px, border-radius 12px → 14px
- hover state z deeper gradient (#047857 → #065f46)
- active state ze scale 0.97 + reduced shadow (visual press feedback)
STICKY TOP BAR (sticky pod headerem podczas scrollowania):
- JS stabilizeMobileSummary() rozszerzony: header detection przez 4 selektory
(.header-main, #header, #pp-custom-header, .header-wrapper)
- resize listener dodany żeby bar się resetował przy obrocie urządzenia
- onScroll() triggered raz na init (na wypadek gdy strona ładuje się scrollowana)
- CSS animacja slide-down 0.3s gdy bar staje się sticky
- Sticky state ma wyższy shadow i border + zmienia layout:
"Pokaż podsumowanie" tekst znika, label "Suma do zapłaty" się pojawia
cena podświetlona zielonym #059669 + większa (1.125rem)
- body padding-bottom 80px → 96px (więcej miejsca na sticky CTA)
DRAWER POLISH:
- font-family system-ui stack (Apple/Inter/Roboto) zamiast Flatsome'owego
- font-feature-settings tnum + kern — cyfry tabularne, lepsza typografia
- max-height drawera 85vh → 88vh (więcej miejsca)
- deeper shadow na drawer (0 -12px 48px + 0 -2px 8px)
- product thumb 56px → 52px (compact), border-radius 8px → 10px, +box-shadow
- product padding 12px 20px → 14px 18px (tighter horizontal)
- product hover state #f8fafc
- cena CTA 1.125rem → 1.25rem (bigger)
TOTAL BOX:
- gradient bg zamiast solid color (#f0fdf4 → #ecfdf5)
- border-radius 12px, margin 0 18px (separated card look)
- shadow 0 2px 8px rgba(5,150,105,0.08)
- label "Do zapłaty" pogrubione (.font-weight 700 + color #064e3b)
- .pp-tax-note margin-top 2px, color #047857 (zielonkawy)
TRUST STRIP:
- gap 20px → 24px
- font 11px 500 → 0.75rem 600 + color #475569
- hover state zmienia color na #059669
OVERFLOW GUARD:
- body.woocommerce-checkout overflow-x hidden globalnie na mobile
- #wrapper, #main również obcięte
- max-width: 100vw
v2.3.4 (Mobile checkout — broken CTA fix + double-icon fix on native header):
STICKY CTA (najgorszy bug v2.3.3 — cena ( 2 034,30 zł ) łamała się na 3 linie):
- checkout.js: usunięto wrap w nawiasach (`'(' + totalHtml + ')'` → `totalHtml`),
przekierowano cenę do nowego selektora `.pp-sticky-cta-price`.
- form-checkout.php: HTML CTA przepisany na 2-slot grid layout:
LEWY SLOT: "Razem do zapłaty" (label 11px uppercase) + cena 18px bold
PRAWY SLOT: zielony button #059669 "🔒 Kupuję i płacę →" (lock + tekst + arrow)
- pp-checkout.css: nowy `.pp-sticky-cta-inner` grid (minmax(0,auto) 1fr),
`font-variant-numeric: tabular-nums` na cenie, compact-mode pod 380px
(ukrywa lock icon, mniejsza czcionka), tłumi legacy slot-y.
DRAWER HEADER (X close button niewidoczny v2.3.3):
- form-checkout.php: SVG przepisany na `<line>` zamiast `<path>` z explicit
`stroke="#0f172a"` `fill="none"` `width="20" height="20"` (bullet-proof).
Dodano `.pp-drawer-title-wrap` z tytułem + licznikiem produktów ("3 produkty").
- pp-checkout.css: `.pp-drawer-close-x` 40×40px, drag handle na top: 8px
przez `position: absolute` z `z-index: 1` (nie nachodzi na content), SVG
forced inline-block z explicit color.
PRODUKTY W LIŚCIE (nazwy ucinane "Listwa elastyczna p..."):
- pp-checkout.css: `-webkit-line-clamp: 2` zamiast `white-space: nowrap`.
Thumb 56×56 (zmniejszony z 64), grid layout `56px 1fr auto`, meta
z flattenem WooCommerce'owego `<dl>/<dt>/<dd>` do inline single-line,
`pp-item-qty` zmienione na inline z separatorem " · " zamiast badgu.
OVERFLOW (zielony artefakt z prawej krawędzi):
- pp-checkout.css: dodano `.pp-mobile-summary-content { overflow-x: hidden }`
plus `* { max-width: 100% }` belt-and-suspenders na drawer.
DOUBLE-ICON FIX NA NATYWNYM HEADERZE FLATSOME (strona główna):
- pp-base.css: dodano uniwersalny suppression `i[data-pp-healed]::before/::after
{ content: none }` dla healera JS w main.js który wstrzykuje SVG do
`<i class="icon-search">` etc. ale nie usuwa glyphu icon-fonta.
Plus fallback dla `.header-nav-main .icon-* ::before` i
`.header-nav-main .ux-search-submit::before` (głównej kategorii buttonów
na natywnym headerze).
v2.3.3 (Mobile checkout drawer — full bottom-sheet rebuild):
- pp-checkout.css: Unified all mobile drawer CSS. Bottom-sheet now uses
transform: translateY(100%)/translateY(0) via .is-open class toggle.
Clean z-index hierarchy: overlay=9000, drawer=9001, sticky-cta=9002,
toggle=9003. Scroll lock moved to html.pp-no-scroll { overflow: hidden }.
border-radius: 20px 20px 0 0 (rounds top corners, not bottom).
- checkout.js: Full rewrite. toggleSummary() uses CSS class toggling
instead of jQuery slideDown/slideUp. initSwipeToClose() added with
passive touch listeners (80px threshold). Scroll-based sticky toggle
replaces infinite requestAnimationFrame loop.
- form-checkout.php: Removed ~527 lines of duplicate inline drawer CSS.
Drawer HTML updated with .pp-drawer-header containing "Twoje zamówienie"
title + X close button at top. Trust badges (SSL + 14-day returns) added.
Sticky CTA button uses emerald green #059669.
v2.3.2 (Double-icon fix in custom header):
- pp-base.css: Suppressed Flatsome parent-theme ::before/::after glyphs on
.ux-search-submit and .header-vertical-menu__opener / .pp-cat-btn using
content: none !important. Correct selectors target the actual elements,
not the removed .icon-search / .icon-user child classes.
v2.3.1 (UI polish on top of 2.3.0 performance overhaul):
- Header: removed Flatsome icon-font wrappers (icon-user, icon-heart,
icon-shopping-bag, icon-search) that were double-rendering next to the
inline SVGs from PP_Icons. Account / Wishlist / Cart / Search now use
pp_icon() exclusively. New .pp-header-icon class with consistent stroke
+ size + colour. Webkit native search decoration / cancel buttons
suppressed via -webkit-appearance: none.
- Checkout (mobile): drawer summary now ships with full-screen rgba(15,
23,42,0.55) backdrop (.pp-summary-overlay), the drawer itself becomes a
true bottom-anchored fixed overlay (z-index 9995) above the page with
scroll lock on body (.pp-no-scroll). Close button restyled, chevron
icon rotates on open, click-on-overlay closes (existing JS handler).
- Product CTA (mobile <= 480px): fluid layout. Price box now flexes
between 110px and 58% of the row; CTA keeps a 130px floor so "DO
KOSZYKA" + cart icon never collapse. Font sizes use clamp() to scale
between 1-, 4- and 5-digit prices without breaking the row.
v2.3.0 (Performance Overhaul — Phases 1-7):
Stage 1 (already shipped — Phases 1+2+3):
- Phase 1: Removed lucide.min.js global enqueue (-388 KB JS). Extended PP_Icons
with 9 missing icons (Camera, AlertCircle, SlidersHorizontal, ShoppingBag,
ChevronDown, ArrowLeft, ArrowDownUp, Heart, X). Replaced all data-lucide
occurrences in PHP with pp_icon() helper.
- Phase 2: Extracted .pp-terms-modal* selectors from pp-checkout.css into
standalone pp-terms-modal.css so single-product pages no longer pull in
31 KB of checkout CSS just to render the dialog under ATC.
- Phase 3a: New conditional_dequeue() method in PP_Assets:
• wp_dequeue_script('wc-cart-fragments') outside cart/checkout
• wp_dequeue_script('flatsome-sticky-sidebar') on product
• wp_dequeue_style('wc-blocks-style') outside cart/checkout/account
• wp_dequeue_style('flatsome-effects') on product
- Phase 3b: Native instant-page prefetch (hover/touch link prefetch),
replaces orphan code in optimization-engine.php.
- Phase 3c: New class PP_DB_Maintenance — daily cron cleanup of expired
WC shipping transients, expired sessions, old spam comments, auto-drafts.
- Phase 3d: Removed orphan inc/optimization-engine.php (was never required).
Stage 2 (this build — Phases 4-7 + QA cleanup):
- QA cleanup: removed 5 dead `lucide.createIcons()` calls left from Phase 1 in
pp-core.js (×2), pp-mobile-menu.js, pp-filters.js, pp-calculator.js. All
were typeof-guarded so safe at runtime, but dead code now gone for clarity.
- Phase 4: Self-hosted Inter + Manrope as variable fonts (woff2, latin +
latin-ext only — PL market). Replaces 3 separate Google Fonts external
requests (1 CSS + 2 woff2) plus 2× preconnect. Variable fonts deliver
weight 100..900 from a single file per family/subset → 4 woff2 files,
~169 KB total, served same-origin. Auto-detect of weights from CSS
confirmed Inter 400/500/600/700 + Manrope 500/600/700/800 in use; CSS
font-weight: 900 falls back to synthesised bold inside the variable axis.
Removed 3 hidden @import url(//panpodloga.pl/wp-content/themes/flatsome-child/fonts.googleapis...) from pp-calculator.css,
pp-global.css (also dropped unused Playfair Display), pp-homepage.css.
Removed wp_enqueue_style('pp-google-fonts') and both preconnect lines.
Added preload as=font (Manrope first — heading LCP, then Inter — body).
- Phase 5a: New defer-jquery logic in PP_Assets::add_script_attributes —
attaches defer="defer" to jquery-core and jquery-migrate on public pages
outside cart/checkout/account and for non-logged-in users (admin-bar.js
needs sync jQuery). Tracking inline <script> for GLA add_to_cart wrapped
in DOMContentLoaded so it survives deferred jQuery.
- Phase 5b: Extended conditional_dequeue() to remove flatsome-lightbox (we
ship Magnific Popup via Phase 7) and flatsome-pjax (we ship native
instant-page prefetch via Phase 3b) on is_product().
- Phase 6: Extended add_style_attributes() with `media=print onload=...`
non-blocking pattern for 9 non-critical stylesheets: pp-cards-css,
pp-page-shop-css, pp-cart-css, pp-mobile-menu-css, pp-calculator-css,
flatsome-effects, pp-blog-css, pp-homepage-css, pp-terms-modal-css.
Each one keeps a <noscript> fallback so users without JS still get
the full design. Critical CSS (pp-base, pp-header, pp-product-critical,
parent/child-style) stays render-blocking.
- Phase 7: Self-hosted Magnific Popup under assets/vendor/magnific/
(~26 KB JS + 5 KB CSS — replaces 2 CDN requests to cdnjs). Also
lazy-loaded: assets are NOT enqueued upfront on product pages — instead
pp-single-product.js installs a capture-phase click listener on
.pp-zoom-trigger which injects the CSS + JS on first interaction and
re-fires the click so the existing main.js / pp-core.js handlers pick
it up. Saves the round-trip for the ~85 % of visitors who never open
the gallery zoom.
Estimated mobile LCP improvement: 15.7s → ~5-6s (full P0+P1+P2 stack).
v2.2.8 (Shipping type classification — courier vs palette):
- PP_Shipping_Info klasyfikuje wg kosztu: ≤100 PLN = kurier, >100 PLN = paleta
- Widget pokazuje "Dostawa kurierska" (1-2 dni) lub "Dostawa paletowa" (1-3 dni)
- Schema shippingLabel dynamic, transitTime max capped per mode
- Filters: `pp_shipping_courier_threshold`, `pp_shipping_type_labels`
v2.2.7 (Payment methods footer + Organization paymentAccepted):
- docs/footer-shortcode-v2.txt — drop-in shortcode for UX Builder footer
- 5 payment SVG icons: Visa, Mastercard, BLIK, Przelewy24, PayU
- Inline SVG with <title> + aria-label → Google crawler-friendly
- Organization schema: paymentAccepted + currenciesAccepted (PLN)
- Filterable: `pp_payment_accepted` filter
v2.2.6 (Per-product shipping widget + CSRE integration):
- New class PP_Shipping_Info — reads shipping rules dynamically from CSRE plugin
- New widget on product page: "Wysyłka od XX,XX zł" with progress bar to free shipping
- 3 visual states: standard cost / free shipping achieved / no threshold defined
- Schema fix: PP_Schema now reads CSRE per product (was passing null → false silent bug)
- GMC: shippingDetails.shippingRate now dynamic per product (was hardcoded "250.00")
- Styling: 12px radius card matching pp-contact-card; emerald-slate token system
- A11y: ARIA progressbar with aria-valuenow/min/max; respects prefers-reduced-motion
- Mobile responsive, print-aware
v2.2.5 (Telephone harmonization — final pass):
- Karta produktu (PP_Product): tel + WhatsApp + out-of-stock — wszystkie zaktualizowane do +48 789 885 570
- FAB widget (PP_Theme): WhatsApp + tel — zaktualizowane
- Wszystkie 12 wystąpień numeru w szablonie ujednolicone z footer i schema
v2.2.4 (HOTFIX — homepage blog widget styling):
- Restored pp-blog.css enqueue on homepage (is_front_page())
- Regression introduced in v2.2.0 P3 hardening: blog CSS narrowed too aggressively,
"Latest Posts" widget on front page rendered unstyled.
v2.2.3 (Final cleanup pass):
- Fixed broken /regulamin/ → /regulamin-sklepu/ in checkout form (2 occurrences)
- shippingRate in PP_Schema now filterable via pp_schema_shipping_rate filter
v2.2.2 (Telephone harmonization):
- Schema telephone unified to "+48 789 885 570" (matches website footer)
- Previous "+48 570 889 958" in PP_Schema was incorrect (digit transposition error)
v2.2.1 (Google Merchant Center compliance — schema fixes):
- Schema.org URLs migrated from HTTP to HTTPS (return policy, FAQ, etc.)
- HTML entity decode for category field (was: "Podłogi &gt; Panele")
- GTIN/MPN reading from multiple meta keys (_global_unique_id, pa_gtin, pa_ean, pa_kod-producenta)
- Brand fallback via product name regex (12 known vendors)
- transitTime parser fixed: hours ≥ 24 converted to DAY
- Image width/height cast to int (was string "1024")
- Generic boilerplate FAQ removed from subjectOf
v2.2.0 (Modular Cleanup):
- Removed ~7 dead CSS files, 3 dead JS + 1 duplicate, 5+ dead PHP classes.
- Refactored functions.php (1126 → 73 lines) into PP_Schema, PP_Tracking,
PP_SGE, PP_Shop_Layout classes.
- Consolidated duplicate GLA purchase event filters (P0 fix).
- Merged checkout.css into pp-checkout.css.
- Narrowed pp-blog.css and Magnific Popup enqueue scopes.
- Removed render-blocking Google Fonts @import duplicate from pp-base.css.
See CHANGELOG.md for full details.
Note: All visual styles live in assets/css/. Do not add styles here.
*/