1/* 2026-06 Designer upgrade fix â menu */ 2 3// ========================================================================== 4// FEIM PREVIEW 5// ========================================================================== 6// 7// Nové / neschválené úpravy. 8// 9// Preview je: 10// - *.upgates.shop 11// - nebo ?upgtest=1 12// 13// Na ostrém webu se tento soubor nesmà projevit. 14// ========================================================================== 15 16(function () { 17 18 function isPreview() { 19 return ( 20 /\.upgates\.shop$/.test(location.hostname) || 21 new URLSearchParams(location.search).get('upgtest') === '1' 22 ); 23 } 24 25 if (!isPreview()) return; 26 27// DOÄASNà DIAGNOSTIKA MENU 28(function () { 29 const start = performance.now(); 30 31 const observer = new MutationObserver(() => { 32 const menu = document.querySelector('ul.top-menu.Menu'); 33 if (!menu) return; 34 35 console.log( 36 'FEIM MENU', 37 Math.round(performance.now() - start) + ' ms', 38 { 39 classes: menu.className, 40 children: menu.children.length, 41 items: [...menu.children].map(el => 42 (el.textContent || '').trim().replace(/\s+/g, ' ').slice(0, 50) 43 ) 44 } 45 ); 46 }); 47 48 observer.observe(document.documentElement, { 49 childList: true, 50 subtree: true, 51 attributes: true, 52 attributeFilter: ['class'] 53 }); 54 55 setTimeout(() => observer.disconnect(), 5000); 56})(); 57 58 // ========================================================================== 59 // DETAIL PRODUKTU â NÃKUPNà BOX V1 60 // ========================================================================== 61 // 62 // PREVIEW ONLY 63 // - použÃvá existujÃcà HTML z product_text2 64 // - nepÅepisuje data 65 // - zachovává nativnà Upgates formuláŠ/ koÅ¡Ãk 66 // - texty nejsou fixnÃ, pÅebÃrajà se z CZ/SK obsahu 67 // ========================================================================== 68 69 (function initFeimProductBuyboxV1() { 70 71 const form = document.querySelector('#frm-productForm'); 72 const prices = document.querySelector('.sh--prices-additional'); 73 74 // Nejsme na vhodném detailu produktu 75 if (!form || !prices) return; 76 77 // Již inicializováno 78 if (form.classList.contains('feim-buybox-v1')) return; 79 80 const warehouse = document.querySelector('.table-warehouse'); 81 const nativePrice = form.querySelector('.pd-prices'); 82 83 const productText2 = 84 document.querySelector('#snippet--productText2Ajax'); 85 86 const priceRows = [...prices.children]; 87 88 const recommendedRow = priceRows[0] || null; 89 const currentRow = priceRows[1] || null; 90 const lowestRow = priceRows[2] || null; 91 92 // ------------------------------------------------------------------------ 93 // CENOVà ÅÃDKY 94 // ------------------------------------------------------------------------ 95 96 recommendedRow?.classList.add('feim-price-recommended'); 97 currentRow?.classList.add('feim-price-current'); 98 lowestRow?.classList.add('feim-price-lowest'); 99 100 // Aktuálnà cena jako prvnà 101 if (currentRow) { 102 prices.prepend(currentRow); 103 } 104 105 // Cenový blok pÅesuneme pÅed dostupnost 106 const availability = 107 form.querySelector('#snippet--availabilityAjax'); 108 109 if (availability) { 110 form.insertBefore(prices, availability); 111 } else { 112 form.prepend(prices); 113 } 114 115 // Nativnà duplicitu hlavnà ceny schováme 116 if (nativePrice) { 117 nativePrice.classList.add('feim-buybox-v1-native-price'); 118 } 119 120 // ------------------------------------------------------------------------ 121 // DETAIL SKLADOVOSTI 122 // ------------------------------------------------------------------------ 123 124 if (warehouse) { 125 126 const warehouseTitle = 127 warehouse.querySelector('h5')?.textContent.trim() || ''; 128 129 const details = document.createElement('details'); 130 131 details.className = 'feim-buybox-v1-warehouse'; 132 133 const summary = document.createElement('summary'); 134 summary.textContent = warehouseTitle; 135 136 const content = document.createElement('div'); 137 content.className = 'feim-buybox-v1-warehouse-content'; 138 139 content.appendChild(warehouse); 140 141 details.appendChild(summary); 142 details.appendChild(content); 143 144 form.appendChild(details); 145 } 146 147 form.classList.add('feim-buybox-v1'); 148 149 // Pokud po pÅesunutà obsahu product_text2 nic nezůstalo, 150 // původnà prázdný wrapper schováme. 151 if ( 152 productText2 && 153 !productText2.textContent.trim() 154 ) { 155 productText2.classList.add('feim-buybox-v1-empty-source'); 156 } 157 158 159 // ------------------------------------------------------------------------ 160 // CSS â zatÃm pÅÃmo v preview JS 161 // ------------------------------------------------------------------------ 162 163 const STYLE_ID = 'feim-buybox-v1-style'; 164 165 if (!document.getElementById(STYLE_ID)) { 166 167 const style = document.createElement('style'); 168 style.id = STYLE_ID; 169 170 style.textContent = ` 171 172 /* ============================================================== 173 FEIM BUYBOX V1 174 ============================================================== */ 175 176 #frm-productForm.feim-buybox-v1 { 177 width: 100%; 178 padding: 22px !important; 179 margin: 0 0 24px !important; 180 background: #f7f7f7; 181 border: 0 !important; 182 border-radius: 8px; 183 box-shadow: 0 5px 18px rgba(0, 0, 0, .06); 184 text-align: left; 185 } 186 187 188 /* -------------------------------------------------------------- 189 CENY 190 -------------------------------------------------------------- */ 191 192 #frm-productForm.feim-buybox-v1 193 .sh--prices-additional { 194 margin: 0 0 18px !important; 195 padding: 0 !important; 196 } 197 198 #frm-productForm.feim-buybox-v1 199 .sh--prices-additional p { 200 margin: 0 !important; 201 } 202 203 #frm-productForm.feim-buybox-v1 204 .feim-price-current { 205 font-size: 0; 206 line-height: 1.2; 207 margin-bottom: 7px !important; 208 } 209 210 #frm-productForm.feim-buybox-v1 211 .feim-price-current strong { 212 display: inline-block; 213 font-size: 32px !important; 214 line-height: 1.15; 215 font-weight: 700; 216 color: #3e3e3e; 217 } 218 219 #frm-productForm.feim-buybox-v1 220 .feim-price-current .c-da { 221 display: inline-block !important; 222 margin-left: 12px !important; 223 font-size: 14px !important; 224 font-weight: 600; 225 color: #718747 !important; 226 vertical-align: middle; 227 } 228 229 #frm-productForm.feim-buybox-v1 230 .feim-price-recommended { 231 margin-top: 5px !important; 232 font-size: 13px; 233 font-weight: 400; 234 color: #999; 235 } 236 237 #frm-productForm.feim-buybox-v1 238 .feim-price-recommended s { 239 color: #999; 240 text-decoration: none; 241 } 242 243 #frm-productForm.feim-buybox-v1 244 .feim-price-lowest { 245 margin-top: 4px !important; 246 font-size: 12px; 247 color: #666; 248 } 249 250 251 /* -------------------------------------------------------------- 252 DOSTUPNOST 253 -------------------------------------------------------------- */ 254 255 #frm-productForm.feim-buybox-v1 256 #snippet--availabilityAjax { 257 margin: 18px 0 !important; 258 padding: 13px 15px !important; 259 background: #eef4e8 !important; 260 border-radius: 4px; 261 } 262 263 #frm-productForm.feim-buybox-v1 264 .availability { 265 color: #6f8746 !important; 266 font-weight: 700; 267 } 268 269 #frm-productForm.feim-buybox-v1 270 .pd-availability-note { 271 color: #777 !important; 272 font-size: 13px; 273 } 274 275 276 /* -------------------------------------------------------------- 277 KOÅ ÃK 278 -------------------------------------------------------------- */ 279 280 #frm-productForm.feim-buybox-v1 281 .pd-quantity { 282 margin-bottom: 0 !important; 283 } 284 285 #frm-productForm.feim-buybox-v1 286 .AddToCartButton, 287 #frm-productForm.feim-buybox-v1 288 .AddToCartButtonInitialized { 289 min-height: 48px; 290 border-radius: 5px; 291 font-size: 16px; 292 } 293 294 295 /* -------------------------------------------------------------- 296 DETAIL SKLADOVOSTI 297 -------------------------------------------------------------- */ 298 299 #frm-productForm.feim-buybox-v1 300 .feim-buybox-v1-warehouse { 301 margin-top: 18px; 302 padding-top: 14px; 303 border-top: 1px solid #e1e1e1; 304 } 305 306 #frm-productForm.feim-buybox-v1 307 .feim-buybox-v1-warehouse summary { 308 cursor: pointer; 309 font-size: 14px; 310 font-weight: 600; 311 color: #444; 312 } 313 314 #frm-productForm.feim-buybox-v1 315 .feim-buybox-v1-warehouse-content { 316 margin-top: 12px; 317 } 318 319 #frm-productForm.feim-buybox-v1 320 .table-warehouse { 321 margin: 0 !important; 322 } 323 324 #frm-productForm.feim-buybox-v1 325 .table-warehouse > h5 { 326 display: none !important; 327 } 328 329 330 /* -------------------------------------------------------------- 331 PÅ®VODNà DUPLICITY 332 -------------------------------------------------------------- */ 333 334 #frm-productForm.feim-buybox-v1 335 .feim-buybox-v1-native-price { 336 display: none !important; 337 } 338 339 .feim-buybox-v1-empty-source { 340 display: none !important; 341 } 342 343 344 /* -------------------------------------------------------------- 345 MOBIL â zatÃm pouze bezpeÄný základ 346 finálnÄ doladÃme po kontrole preview 347 -------------------------------------------------------------- */ 348 349 @media (max-width: 767px) { 350 351 #frm-productForm.feim-buybox-v1 { 352 padding: 16px !important; 353 } 354 355 #frm-productForm.feim-buybox-v1 356 .feim-price-current strong { 357 font-size: 28px !important; 358 } 359 360 #frm-productForm.feim-buybox-v1 361 .feim-price-current .c-da { 362 margin-left: 8px !important; 363 font-size: 13px !important; 364 } 365 } 366 `; 367 368 document.head.appendChild(style); 369 } 370 371 })(); 372 373 // ========================================================================== 374 // DETAIL PRODUKTU â DESKTOP DOLADÄNà V1 375 // ========================================================================== 376 377 (function initFeimProductDetailPolishV1() { 378 379 const info = document.querySelector('.pd-info'); 380 381 const form = 382 document.querySelector('#frm-productForm.feim-buybox-v1'); 383 384 if (!info || !form) return; 385 386 const availability = 387 form.querySelector('#snippet--availabilityAjax'); 388 389 const warehouse = 390 form.querySelector('.feim-buybox-v1-warehouse'); 391 392 const logo = 393 info.querySelector('.pd-short-desc-img'); 394 395 const code = 396 info.querySelector('#snippet--codeAjax'); 397 398 const contact = 399 info.querySelector('aside.help'); 400 401 402 // ------------------------------------------------------------------------ 403 // DETAIL SKLADOVOSTI POD DOSTUPNOST 404 // ------------------------------------------------------------------------ 405 406 if (availability && warehouse) { 407 availability.after(warehouse); 408 } 409 410 411 // ------------------------------------------------------------------------ 412 // POMOCNà TÅÃDY 413 // ------------------------------------------------------------------------ 414 415 info.classList.add('feim-final-info'); 416 logo?.classList.add('feim-final-logo'); 417 code?.classList.add('feim-final-code'); 418 contact?.classList.add('feim-final-contact'); 419 420 421 // ------------------------------------------------------------------------ 422 // MNOŽSTEVNà SLEVY â CZ / SK 423 // ------------------------------------------------------------------------ 424 425 if (!form.querySelector('.feim-volume-discount')) { 426 427 const lang = 428 (document.documentElement.lang || '').toLowerCase(); 429 430 const isCz = 431 location.hostname.endsWith('.cz') || 432 lang.startsWith('cs') || 433 lang.startsWith('cz'); 434 435 const discountLink = document.createElement('a'); 436 437 discountLink.className = 'feim-volume-discount'; 438 439 discountLink.href = isCz 440 ? 'https://www.feim.cz/news/vice-svetla-vice-vyhod' 441 : 'https://www.feim.sk/news/viac-svetla-viac-vyhod'; 442 443 discountLink.textContent = isCz 444 ? 'Využijte množstevnà slevy až do 7 %' 445 : 'Využite množstevné zľavy až do 7 %'; 446 447 form.appendChild(discountLink); 448 } 449 450 451 // ------------------------------------------------------------------------ 452 // PREVIEW CSS 453 // ------------------------------------------------------------------------ 454 455 const STYLE_ID = 'feim-product-detail-polish-v1-style'; 456 457 if (document.getElementById(STYLE_ID)) return; 458 459 const style = document.createElement('style'); 460 style.id = STYLE_ID; 461 462 style.textContent = ` 463 464 #frm-productForm.feim-buybox-v1 465 .feim-volume-discount { 466 display: block; 467 width: 100%; 468 text-align: right; 469 font-size: 13px; 470 line-height: 1.2; 471 font-weight: 600; 472 color: #444; 473 text-decoration: underline; 474 } 475 476 477 @media (min-width: 992px) { 478 479 .pd-info.feim-final-info { 480 position: relative !important; 481 row-gap: 0 !important; 482 gap: 0 !important; 483 } 484 485 486 /* BUYBOX */ 487 488 #frm-productForm.feim-buybox-v1 { 489 padding: 13px !important; 490 margin: 0 0 5px !important; 491 } 492 493 #frm-productForm.feim-buybox-v1 494 .sh--prices-additional { 495 margin-bottom: 0 !important; 496 } 497 498 #frm-productForm.feim-buybox-v1 499 .feim-price-current { 500 margin-bottom: 1px !important; 501 } 502 503 #frm-productForm.feim-buybox-v1 504 .feim-price-recommended, 505 #frm-productForm.feim-buybox-v1 506 .feim-price-lowest { 507 margin-top: 0 !important; 508 } 509 510 511 /* SKLADEM */ 512 513 #frm-productForm.feim-buybox-v1 514 #snippet--availabilityAjax { 515 margin: 0 0 2px !important; 516 padding: 8px 11px !important; 517 } 518 519 520 /* DETAIL SKLADOVOSTI */ 521 522 #frm-productForm.feim-buybox-v1 523 .feim-buybox-v1-warehouse { 524 margin: 0 0 3px !important; 525 padding: 0 11px 3px !important; 526 border: 0 !important; 527 } 528 529 #frm-productForm.feim-buybox-v1 530 .feim-buybox-v1-warehouse summary { 531 font-size: 12px !important; 532 } 533 534 535 /* KOÅ ÃK */ 536 537 #frm-productForm.feim-buybox-v1 538 .pd-quantity, 539 #frm-productForm.feim-buybox-v1 540 .pd-tocart { 541 margin-top: 0 !important; 542 margin-bottom: 0 !important; 543 } 544 545 #frm-productForm.feim-buybox-v1 546 .AddToCartButton, 547 #frm-productForm.feim-buybox-v1 548 .AddToCartButtonInitialized { 549 min-height: 42px !important; 550 } 551 552 553 /* MNOŽSTEVNà SLEVY */ 554 555 #frm-productForm.feim-buybox-v1 556 .feim-volume-discount { 557 margin-top: -5px !important; 558 } 559 560 561 /* Å TÃTKY */ 562 563 .pd-info.feim-final-info 564 #snippet--labelsAjax { 565 width: 100% !important; 566 margin-left: -18px !important; 567 padding-left: 0 !important; 568 justify-content: flex-start !important; 569 } 570 571 .pd-info.feim-final-info 572 #snippet--labelsAjax .labels { 573 margin-left: 0 !important; 574 padding-left: 0 !important; 575 justify-content: flex-start !important; 576 } 577 578 579 /* RL LOGO */ 580 581 .pd-info.feim-final-info 582 .pd-short-desc-img.feim-final-logo { 583 position: absolute !important; 584 top: -5px !important; 585 right: -2px !important; 586 z-index: 5; 587 588 display: block !important; 589 float: none !important; 590 591 width: auto !important; 592 max-width: none !important; 593 594 margin: 0 !important; 595 padding: 0 !important; 596 } 597 598 .pd-info.feim-final-info 599 .pd-short-desc
599-img.feim-final-logo img { 600 display: block !important; 601 width: 54px !important; 602 height: auto !important; 603 margin: 0 !important; 604 } 605 606 607 /* KÃD / EAN / HMOTNOST / DOPRAVA */ 608 609 #snippet--codeAjax.feim-final-code { 610 width: 100% !important; 611 margin: 4px 0 0 !important; 612 padding: 0 !important; 613 justify-content: flex-start !important; 614 text-align: left !important; 615 } 616 617 618 /* KONTAKT */ 619 620 .pd-info.feim-final-info 621 aside.help.feim-final-contact { 622 position: relative !important; 623 left: -24px !important; 624 625 width: 100% !important; 626 627 margin-top: 14px !important; 628 padding: 0 !important; 629 630 align-self: flex-start !important; 631 justify-content: flex-start !important; 632 text-align: left !important; 633 } 634 635 .pd-info.feim-final-info 636 aside.help.feim-final-contact .row { 637 margin-left: 0 !important; 638 margin-right: 0 !important; 639 } 640 641 .pd-info.feim-final-info 642 aside.help.feim-final-contact [class*="col-"] { 643 padding-left: 0 !important; 644 } 645 } 646 `; 647 648 document.head.appendChild(style); 649 650 })(); 651 652 // ========================================================================== 653 // BANNERY MEZI PRODUKTY 654 // ========================================================================== 655 // 656 // Zdroj bannerů: 657 // #banner-1 658 // #banner-2 659 // 660 // Zdrojové bannery jsou schované v HTML / Custom Boxu. 661 // 662 // Pozice: 663 // banner 1 = 7. pozice 664 // banner 2 = 13. pozice 665 // 666 // Po schválenÃ: 667 // - pÅesunout tuto funkcionalitu do produkÄnÃho FEIM JS 668 // - odstranit preview guard 669 // ========================================================================== 670 671 (function initCategoryBanners() { 672 673 const STYLE_ID = 'feim-category-banners-preview-style'; 674 const BANNER_CLASS = 'feim-category-banner'; 675 676 // ------------------------------------------------------------------------ 677 // CSS 678 // ------------------------------------------------------------------------ 679 680 if (!document.getElementById(STYLE_ID)) { 681 const style = document.createElement('style'); 682 683 style.id = STYLE_ID; 684 685 style.textContent = ` 686 .${BANNER_CLASS} { 687 padding: 0 !important; 688 overflow: hidden !important; 689 display: flex !important; 690 } 691 692 .${BANNER_CLASS} > p { 693 display: flex !important; 694 width: 100% !important; 695 height: 100% !important; 696 margin: 0 !important; 697 } 698 699 .${BANNER_CLASS} a { 700 display: flex !important; 701 width: 100% !important; 702 height: 100% !important; 703 } 704 705 .${BANNER_CLASS} img { 706 display: block !important; 707 width: 100% !important; 708 height: 100% !important; 709 object-fit: cover !important; 710 margin: 0 !important; 711 } 712 `; 713 714 document.head.appendChild(style); 715 } 716 717 718 // ------------------------------------------------------------------------ 719 // Vloženà bannerů 720 // ------------------------------------------------------------------------ 721 722 function insertBanners() { 723 724 const source1 = document.querySelector('#banner-1'); 725 const source2 = document.querySelector('#banner-2'); 726 727 const products = [ 728 ...document.querySelectorAll( 729 'article[data-product-id], .p-i[data-product-id]' 730 ) 731 ]; 732 733 if (!source1 || !source2 || products.length < 12) { 734 return false; 735 } 736 737 // Bannery už jsou vložené 738 if (document.querySelectorAll('.' + BANNER_CLASS).length === 2) { 739 return true; 740 } 741 742 // Ãklid pÅÃpadných zbytků po pÅekreslenà gridu 743 document 744 .querySelectorAll('.' + BANNER_CLASS) 745 .forEach(el => el.remove()); 746 747 748 function createBanner(source, number) { 749 750 const banner = document.createElement('article'); 751 752 // PÅevzetà gridových tÅÃd produktové karty 753 banner.className = 754 products[0].className + 755 ' upg-support-in-grid ' + 756 BANNER_CLASS + 757 ' feim-category-banner-' + 758 number; 759 760 // VložÃme pouze obsah skrytého zdrojového banneru 761 banner.innerHTML = source.innerHTML; 762 763 return banner; 764 } 765 766 767 // Banner 1 = 7. pozice 768 products[6].before( 769 createBanner(source1, 1) 770 ); 771 772 773 // Banner 2 = 13. pozice 774 // 775 // Prvnà banner už zabere jedno mÃsto v gridu, 776 // proto vkládáme pÅed původnà 12. produkt. 777 products[11].before( 778 createBanner(source2, 2) 779 ); 780 781 return true; 782 } 783 784 785 // Prvnà pokus 786 insertBanners(); 787 788 789 // ------------------------------------------------------------------------ 790 // Pojistka proti pÅekreslenà produktového gridu Upgates 791 // ------------------------------------------------------------------------ 792
793 let checks = 0; 794 795 const timer = setInterval(function () { 796 797 checks++; 798 799 insertBanners(); 800 801 if (checks >= 10) { 802 clearInterval(timer); 803 } 804 805 }, 500); 806 807 })(); 808 809})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.