1/** 2 * Price-tag relocation that also works when the target element 3 * is injected later by other JavaScript. 4 * 5 * Requirements: 6 * â jQuery 1.7+ (for on/ready) 7 * â Modern browsers that support MutationObserver 8 */ 9jQuery(function ($) { 10 11 //--------------------------------------------------------------------------- 12 // Public bootstrap 13 //--------------------------------------------------------------------------- 14 relocateAllPriceTags(); // try once at load 15 $(document.body).on('updated_cart_totals', // Woo fallback 16 relocateAllPriceTags); 17 18 //--------------------------------------------------------------------------- 19 // Helpers 20 //--------------------------------------------------------------------------- 21 22 /** 23 * Iterate over every element that owns a data-append-target attribute 24 * and (re)locate its surrounding .viabill-pricetag-wrap. 25 */ 26 function relocateAllPriceTags () { 27 $('[data-append-target]').each(function () { 28 const $tag = $(this); 29 const target = $tag.data('append-target'); 30 31 // Skip if weâve already handled this tag once 32 if ($tag.data('vb-attached') || !target) { return; } 33 34 relocateOnePriceTag($tag, target.trim()); 35 }); 36 } 37 38 /** 39 * Move one price-tag wrapper next to/before/after its selector. 40 * If the selector is not present yet, watch until it is. 41 */ 42 function relocateOnePriceTag ($tag, targetSpec) { 43 let selector = targetSpec; 44 let insertAfter = false; 45 let insertFirst = false; 46 47 // Parse modifiers like ".my-class:first:after" 48 if (selector.includes(':after')) { 49 insertAfter = true; 50 selector = selector.replace(':after', '').trim(); 51 } 52 if (selector.includes(':first')) { 53 insertFirst = true; 54 selector = selector.replace(':first', '').trim(); 55 } 56 57 const $wrap = $tag.closest('.viabill-pricetag-wrap'); 58 59 /** 60 * Perform the actual DOM move exactly once. 61 */ 62 const insert = () => { 63 if ($wrap.data('vb-inserted')) { return; } // safety 64 65 if (insertAfter) { 66 insertFirst ? $(selector).first().after($wrap) 67 : $(selector).after($wrap); 68 } else { 69 insertFirst ? $(selector).first().before($wrap) 70 : $(selector).before($wrap); 71 } 72 73 $tag.addClass('viabill-pricetag'); 74 $wrap.data('vb-inserted', true); 75 $tag.data('vb-attached', true); 76 77 // Let ViaBill recalc its price if needed 78 $tag[0].dispatchEvent(new CustomEvent('vb-update-price')); 79 }; 80 81 // Case 1 â target already exists - insert immediately 82 if ($(selector).length) { 83 insert(); 84 return; 85 } 86 87 // Case 2 â target not yet in DOM - observe until it appears 88 const obs = new MutationObserver(() => { 89 if ($(selector).length) { 90 insert(); 91 obs.disconnect(); 92 } 93 }); 94 95 obs.observe(document.body, { childList: true, subtree: true }); 96 97 // Fallback for very old browsers (no MutationObserver) 98 if (!('MutationObserver' in window)) { 99 const intId = setInterval(() => { 100 if ($(selector).length) { 101 insert(); 102 clearInterval(intId); 103 } 104 }, 250); 105 } 106 } 107 108}); 109
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.