1/** 2 * Ersetzt im Checkout (Standard 5-Step und OPC) den angezeigten Preis einer 3 * als "Preis auf Anfrage" markierten Versandart durch einen Hinweistext. 4 * 5 * Arbeitet bewusst themeunabhängig über einen MutationObserver + Regex statt 6 * über feste Template-Selektoren, da sich order-carrier.tpl je nach Theme 7 * unterscheidet. Wer lieber direkt im Theme-Template arbeitet: siehe README, 8 * dort steht die alternative {if $carrier.sl_price_on_request}-Variante. 9 */ 10(function () { 11 'use strict'; 12 13 if (!window.sl_carrier_priceonrequestCarriers || !window.sl_carrier_priceonrequestCarriers.length) { 14 return; 15 } 16 17 var CARRIER_IDS = window.sl_carrier_priceonrequestCarriers.map(function (id) { 18 return String(id); 19 }); 20 var LABEL = window.sl_carrier_priceonrequestText || 'Preis auf Anfrage'; 21 var PRICE_PATTERN = /(\d+[.,]\d{2})\s?(â¬|EUR)/i; 22 var PROCESSED_ATTR = 'data-por-processed'; 23 24 function getCarrierIds(input) { 25 // Werte wie "3,", "3,5," oder "3,5" (eine Carrier-ID pro Paket bei 26 // mehreren Paketen/Delivery-Options) in ein sauberes Array zerlegen. 27 return String(input.value) 28 .split(',') 29 .map(function (id) { 30 return id.trim(); 31 }) 32 .filter(function (id) { 33 return id !== ''; 34 }); 35 } 36 37 function matchesPriceOnRequest(input) { 38 var ids = getCarrierIds(input); 39 return ids.some(function (id) { 40 return CARRIER_IDS.indexOf(id) !== -1; 41 }); 42 } 43 44 function findPriceContainer(input) { 45 var el = input.closest('tr').getElementsByClassName('text-md-right'); 46 return el[0]; 47 // Bis zu 4 Ebenen nach oben nach einem Container mit Preistext suchen. 48 var el = input.closest('tr, li, .carrier-container, .delivery-option, label') || input.parentElement; 49 var depth = 0; 50 while (el && depth < 4) { 51 if (PRICE_PATTERN.test(el.textContent)) { 52 return el; 53 } 54 el = el.parentElement; 55 depth++; 56 } 57 return null; 58 } 59 60 function replacePriceText(container) { 61 // Nur Text-Knoten anfassen, damit Icons/Inputs erhalten bleiben. 62 var walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, null, false); 63 var node; 64 while ((node = walker.nextNode())) { 65 if (PRICE_PATTERN.test(node.nodeValue)) { 66 node.nodeValue = node.nodeValue.replace(PRICE_PATTERN, LABEL); 67 } 68 } 69 container.classList.add('price-on-request'); 70 } 71 72 function process() { 73 var inputs = document.querySelectorAll( 74 'input[name="id_carrier"], input[name^="id_carrier"], input[name^="delivery_option"]' 75 ); 76 77 inputs.forEach(function (input) { 78 79 if (!matchesPriceOnRequest(input)) { 80 return; 81 } 82 if (input.getAttribute(PROCESSED_ATTR)) { 83 return; 84 } 85 86 var container = findPriceContainer(input); 87 if (container) { 88 //replacePriceText(container); 89 container.innerHTML = LABEL; 90 } 91 input.setAttribute(PROCESSED_ATTR, '1'); 92 }); 93 } 94 95 document.addEventListener('DOMContentLoaded', function () { 96 process(); 97 98 var observer = new MutationObserver(function () { 99 process(); 100 }); 101 observer.observe(document.body, { childList: true, subtree: true }); 102 }); 103})();
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.