1(function (window, document) { 2 'use strict'; 3 4 if (window.fglAdsenseUnfilledCollapseInstalled) return; 5 window.fglAdsenseUnfilledCollapseInstalled = true; 6 7 var collapsedClass = 'fgl-manual-ad-unfilled'; 8 var manualSlotSelector = '.adsbygoogle[data-ad-slot]'; 9 var observer = null; 10 11 function installStyles() { 12 var style; 13 if (document.querySelector('style[data-fgl-manual-ad-collapse="1"]')) return; 14 style = document.createElement('style'); 15 style.setAttribute('data-fgl-manual-ad-collapse', '1'); 16 style.textContent = '.' + collapsedClass + '{display:none!important;width:0!important;' 17 + 'height:0!important;min-height:0!important;margin:0!important;padding:0!important;' 18 + 'border:0!important;overflow:hidden!important}'; 19 (document.head || document.documentElement).appendChild(style); 20 } 21 22 function isInfrastructure(node, slot) { 23 var tag, children, i; 24 if (!node || node === slot) return true; 25 if (node.nodeType === 3) return String(node.nodeValue || '').trim() === ''; 26 if (node.nodeType !== 1) return true; 27 tag = String(node.tagName || '').toLowerCase(); 28 if (tag === 'script' || tag === 'style' || tag === 'noscript' || tag === 'template') return true; 29 if (node.matches && node.matches(manualSlotSelector)) { 30 return node === slot; 31 } 32 children = node.childNodes || []; 33 for (i = 0; i < children.length; i++) { 34 if (!isInfrastructure(children[i], slot)) return false; 35 } 36 return true; 37 } 38 39 function trackCollapsedNode(node, slot) { 40 var slots = node._fglUnfilledManualAdSlots || []; 41 if (slots.indexOf(slot) === -1) slots.push(slot); 42 node._fglUnfilledManualAdSlots = slots; 43 node.classList.add(collapsedClass); 44 } 45 46 function releaseCollapsedNodes(slot) { 47 var nodes = slot._fglCollapsedAdNodes || [], i, node, slots, index; 48 for (i = 0; i < nodes.length; i++) { 49 node = nodes[i]; 50 slots = node._fglUnfilledManualAdSlots || []; 51 index = slots.indexOf(slot); 52 if (index !== -1) slots.splice(index, 1); 53 node._fglUnfilledManualAdSlots = slots; 54 if (!slots.length) node.classList.remove(collapsedClass); 55 } 56 slot._fglCollapsedAdNodes = []; 57 } 58 59 function collapseSlot(slot) { 60 var nodes = [], parent = slot.parentElement, depth = 0; 61 releaseCollapsedNodes(slot); 62 trackCollapsedNode(slot, slot); 63 nodes.push(slot); 64 while (parent && parent !== document.body && parent !== document.documentElement && depth < 6) { 65 if (!isInfrastructure(parent, slot)) break; 66 trackCollapsedNode(parent, slot); 67 nodes.push(parent); 68 parent = parent.parentElement; 69 depth++; 70 } 71 slot._fglCollapsedAdNodes = nodes; 72 } 73 74 function inspectSlot(slot) { 75 var status; 76 if (!slot || !slot.matches || !slot.matches(manualSlotSelector)) return; 77 status = String(slot.getAttribute('data-ad-status') || '').toLowerCase(); 78 if (status === 'unfilled') { 79 collapseSlot(slot); 80 } else { 81 // Only an explicit unfilled result owns collapsed nodes. This also 82 // keeps Google's unfill-optimized fallback and reused slots visible. 83 releaseCollapsedNodes(slot); 84 } 85 } 86 87 function inspectNode(node) { 88 var slots, i; 89 if (!node || node.nodeType !== 1) return; 90 inspectSlot(node); 91 if (!node.querySelectorAll) return; 92 slots = node.querySelectorAll(manualSlotSelector + '[data-ad-status]'); 93 for (i = 0; i < slots.length; i++) inspectSlot(slots[i]); 94 } 95 96 function revalidateCollapsedAncestors(node) { 97 var current = node; 98 var owners = []; 99 var slots; 100 var slot; 101 var i; 102 var depth = 0; 103 104 while (current && current.nodeType === 1 && depth < 8) { 105 slots = current._fglUnfilledManualAdSlots; 106 if (slots && slots.length) { 107 slots = slots.slice(0); 108 for (i = 0; i < slots.length; i++) { 109 slot = slots[i]; 110 if (owners.indexOf(slot) === -1) owners.push(slot); 111 } 112 } 113 current = current.parentElement; 114 depth++; 115 } 116 117 for (i = 0; i < owners.length; i++) { 118 slot = owners[i]; 119 if (!document.documentElement.contains(slot) || 120 String(slot.getAttribute('data-ad-status') || '').toLowerCase() !== 'unfilled') { 121 releaseCollapsedNodes(slot); 122 } else { 123 collapseSlot(slot); 124 } 125 } 126 } 127 128 function start() { 129 var root = document.documentElement || document.body; 130 if (!root || observer) return; 131 installStyles(); 132 inspectNode(root); 133 if (!window.MutationObserver) return; 134 observer = new MutationObserver(function (records) { 135 var i, j; 136 for (i = 0; i < records.length; i++) { 137 if (records[i].type === 'attributes') inspectSlot(records[i].target); 138 if (records[i].type === 'childList') { 139 revalidateCollapsedAncestors(records[i].target); 140 inspectNode(records[i].target); 141 } 142 for (j = 0; j < records[i].addedNodes.length; j++) inspectNode(records[i].addedNodes[j]); 143 } 144 }); 145 observer.observe(root, { 146 childList: true, 147 subtree: true, 148 attributes: true, 149 attributeFilter: ['data-ad-status'] 150 }); 151 } 152 153 window.fglInspectAdsenseUnfilledSlot = inspectSlot; 154 if (document.readyState === 'loading') { 155 document.addEventListener('DOMContentLoaded', start); 156 } else { 157 start(); 158 } 159}(window, document));
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.