1(function ($) { 2 'use strict'; 3 4 function adHasVisibleContent($ad) { 5 if (!$ad || !$ad.length) return false; 6 var hasIframe = $ad.find('iframe, object, embed').filter(function () { 7 return ($(this).width() > 1 || $(this).height() > 1 || this.offsetHeight > 1 || this.offsetWidth > 1); 8 }).length > 0; 9 var hasImage = $ad.find('img').filter(function () { 10 return this.complete && this.naturalWidth > 1 && this.naturalHeight > 1; 11 }).length > 0; 12 var text = $.trim($ad.clone().children('script,style').remove().end().text()); 13 return hasIframe || hasImage || text.length > 5; 14 } 15 16 function hasSmartAdSlot($ad) { 17 return $ad.is('[data-h24-ad-format]') || $ad.find('[id^="sas_"]').length > 0; 18 } 19 20 function cleanEmptyAds(finalPass) { 21 $('.h24-ad-content, .h24-smartad, .h24-ad-watch, [data-module="h24-ad-content"]').each(function () { 22 var $ad = $(this); 23 var loaded = adHasVisibleContent($ad); 24 var smartSlot = hasSmartAdSlot($ad); 25 26 if (loaded) { 27 $ad.removeClass('h24-ad-empty').attr('aria-hidden', 'false'); 28 $ad.find('.h24-smartad').attr('data-h24-ad-state', 'loaded'); 29 return; 30 } 31 32 // Keep async SmartAdServer slots available during the first checks. 33 // On the final pass, or when ad blockers leave only empty SAS containers, 34 // hide the full wrapper to remove white gaps. 35 if (smartSlot && !finalPass) { 36 if (!$ad.hasClass('h24-ad-empty')) { 37 $ad.attr('aria-hidden', 'false'); 38 } 39 return; 40 } 41 42 if (finalPass || !smartSlot) { 43 $ad.addClass('h24-ad-empty').attr('aria-hidden', 'true'); 44 } 45 }); 46 } 47 48 function preventDoubleImages() { 49 $('.h24-placeholder, .h24-loadmore-image-box, .h24-left-latest-media').each(function () { 50 var $box = $(this); 51 var seen = {}; 52 $box.find('img').each(function () { 53 var key = $(this).attr('src') || $(this).attr('data-src') || ''; 54 if (key && seen[key]) { 55 $(this).remove(); 56 return; 57 } 58 if (key) { 59 seen[key] = true; 60 } 61 }); 62 if ($box.find('img').length) { 63 $box.addClass('h24-placeholder--has-image h24-has-real-image'); 64 $box.css('background-image', 'none'); 65 } 66 }); 67 68 // Some lazy placeholders are printed as a sibling above the real image. 69 $('.h24-ranking-profile-media-small-picture, .h24-ranking-profile-media-zone-left').each(function () { 70 var $media = $(this); 71 if ($media.find('img').length) { 72 $media.find('.h24-placeholder').not(':has(img)').remove(); 73 $media.addClass('h24-media-loaded'); 74 } 75 }); 76 } 77 78 window.h24CleanEmptyAds = cleanEmptyAds; 79 window.h24PreventDoubleImages = preventDoubleImages; 80 81 $(function () { 82 preventDoubleImages(); 83 cleanEmptyAds(false); 84 setTimeout(function () { cleanEmptyAds(false); }, 2500); 85 setTimeout(function () { cleanEmptyAds(false); }, 6500); 86 setTimeout(function () { cleanEmptyAds(true); }, 8000); 87 setTimeout(function () { cleanEmptyAds(true); }, 16000); 88 89 if ('MutationObserver' in window) { 90 var observer = new MutationObserver(function () { 91 clearTimeout(window.h24AdCleanTimer); 92 window.h24AdCleanTimer = setTimeout(function () { 93 preventDoubleImages(); 94 cleanEmptyAds(false); 95 }, 500); 96 }); 97 observer.observe(document.body, { childList: true, subtree: true }); 98 } 99 }); 100})(jQuery);
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.