Wunschliste


(() => { const bulkBtn = document.getElementById("pm-bulk-add"); if (!bulkBtn) return; const sleep = (ms) => new Promise(r => setTimeout(r, ms)); const setBusy = (busy) => { bulkBtn.disabled = busy; bulkBtn.style.opacity = busy ? "0.7" : "1"; }; // Add-to-cart-Erkennung (Heuristik) const looksLikeAddToCart = (el) => { if (!(el instanceof HTMLElement)) return false; if (el.id === "pm-bulk-add") return false; if (el.dataset.pmBulkDone === "1") return false; if (el.disabled) return false; const txt = (el.innerText || "").trim().toLowerCase(); const okText = txt === "in den warenkorb" || txt.includes("in den warenkorb") || txt.includes("warenkorb") || txt.includes("add to cart") || txt.includes("add to basket"); const okAttr = el.matches([ '[data-add-to-basket]', '[data-testing="add-to-basket"]', '.add-to-basket', '.add-to-cart', '.btn-add-to-basket', '.basket-button' ].join(",")); return okAttr || okText; }; const isVisible = (el) => { const r = el.getBoundingClientRect(); return r.width > 0 && r.height > 0; }; // Immer den nächsten Button frisch holen (robust gegen Re-Renders) const getNextAddButton = () => { const candidates = Array.from(document.querySelectorAll("button, a")) .filter(looksLikeAddToCart) .filter(isVisible); return candidates[0] || null; }; // Modal schließen über den von dir genannten Selector const closeModal = async () => { // Warten bis Modal evtl. geöffnet ist await sleep(80); // plenty/mobile: Modal über ".modal-header .close" const closeBtn = document.querySelector(".modal.show .modal-header .close, .modal.in .modal-header .close, .modal-header .close"); if (closeBtn && isVisible(closeBtn) && !closeBtn.disabled) { closeBtn.click(); await sleep(180); return; } // Fallbacks (falls close in anderem Markup steckt) const fallback = document.querySelector( '.modal.show [data-bs-dismiss="modal"], .modal.show [data-dismiss="modal"], .modal.show .btn-close' ); if (fallback && isVisible(fallback) && !fallback.disabled) { fallback.click(); await sleep(180); return; } // Backdrop-Fallback const backdrop = document.querySelector(".modal-backdrop.show, .modal-backdrop.in"); if (backdrop) { backdrop.click(); await sleep(180); } }; const runBulkAdd = async () => { setBusy(true); const MAX_ITEMS = 200; let processed = 0; try { while (processed < MAX_ITEMS) { const btn = getNextAddButton(); if (!btn) break; // Markieren vor Klick, damit Re-Renders den Fortschritt nicht verlieren btn.dataset.pmBulkDone = "1"; try { btn.scrollIntoView({ block: "center", inline: "nearest" }); } catch (_) {} await sleep(120); btn.click(); processed++; // Zeit für Request + Modal-Open await sleep(420); // Modal schließen, sonst blockiert Mobile-UI weitere Klicks await closeModal(); // Zeit für Basket-Update / Animation await sleep(320); } } catch (err) { console.error("[pm-bulk-add]", err); } finally { setBusy(false); } }; bulkBtn.addEventListener("click", (e) => { e.preventDefault(); runBulkAdd(); }); })();