1/* ============================================================ 2 bebemamae.com, script de anuncios R7 3 Versao 1.5.0, 18/09/2026 4 5 NOVIDADE DESTA VERSAO: o refresh de anuncio deixa de cair em 6 cima do toque do usuario. 7 8 POR QUE: o Debug View do Cloudflare (janelas de 24h de 15 a 18/09) 9 mostrou que o pior elemento de INP nao e mais a imagem destacada 10 (352 a 600ms), e sim o paragrafo do meio da materia, 11 p.wp-block-paragraph, entre 744ms e 2.088ms. Paragrafo de texto 12 nao tem handler nenhum, entao esse tempo nao e processamento, e 13 presentation delay: a main thread esta ocupada quando o toque 14 chega. O que ocupa ela no meio do artigo e o refresh dos slots 15 r7_texto_1..5, disparado por setTimeout cru a cada 30s. 16 17 COMO: o refresh continua acontecendo na mesma quantidade, mas 18 (a) espera 1,2s depois do ultimo toque do usuario e 19 (b) roda dentro de requestIdleCallback, ou seja, numa janela 20 ociosa da main thread. O timeout de 4s garante que ele acontece 21 de qualquer jeito, e MAX_DEFER_MS impede adiamento infinito em 22 quem fica tocando na tela sem parar. 23 24 IMPACTO EM RECEITA: nenhum esperado. O numero de refreshes nao 25 muda, so o instante, com atraso maximo de poucos segundos. 26 27 PARA REVERTER: troque USE_IDLE_REFRESH para false. O comportamento 28 volta a ser exatamente o da 1.4.1. 29 PARA AJUSTAR: mexa em INTERACTION_QUIET_MS (quanto tempo de silencio 30 exigir depois do toque) ou em IDLE_TIMEOUT_MS (teto da espera ociosa). 31 32 HERDADO DA 1.4.1: carregamento adaptativo. Em aparelhos de pouca 33 memoria, r7_texto_4 e r7_texto_5 nao sao carregados e os containers 34 sao removidos do DOM. Usa apenas navigator.deviceMemory, que nao 35 existe no Safari do iPhone, entao iPhone nunca e degradado. 36 Para reverter essa parte: LOW_END_ENABLED para false. 37 ============================================================ */ 38 39window.googletag = window.googletag || { cmd: [] }; 40 41var anchor_slot; 42var REFRESH_KEY = 'refresh'; 43var REFRESH_VALUE = 'true'; 44 45/* ---------- carregamento adaptativo, configuracao ---------- */ 46 47var LOW_END_ENABLED = true; 48var LOW_END_MAX_MEMORY_GB = 4; // deviceMemory <= 4 49var SLOTS_TO_DROP = ['r7_texto_4', 'r7_texto_5']; // os mais profundos 50 51function isLowEndDevice() { 52 if (!LOW_END_ENABLED) return false; 53 var mem = navigator.deviceMemory; 54 // Sem a API (iPhone e navegadores antigos): tratar como normal. 55 if (typeof mem !== 'number') return false; 56 return mem <= LOW_END_MAX_MEMORY_GB; 57} 58 59var IS_LOW_END = isLowEndDevice(); 60 61// Exposto para o snippet de medicao de INP poder marcar o evento. 62window.__bmLowEnd = IS_LOW_END; 63 64function shouldLoadSlot(slotId) { 65 if (!IS_LOW_END) return true; 66 return SLOTS_TO_DROP.indexOf(slotId) === -1; 67} 68 69/* ---------- refresh ocioso, configuracao ---------- */ 70 71var USE_IDLE_REFRESH = true; // false volta ao comportamento da 1.4.1 72var INTERACTION_QUIET_MS = 1200; // silencio exigido depois do ultimo toque 73var IDLE_TIMEOUT_MS = 4000; // teto da espera por janela ociosa 74var MAX_DEFER_MS = 10000; // teto total do adiamento, protege a receita 75 76var lastInteractionAt = 0; 77 78// capture: true garante que marcamos o toque mesmo que algum script 79// de terceiro chame stopPropagation no caminho. 80// passive: true garante que este listener nunca atrasa o scroll. 81['pointerdown', 'keydown', 'touchstart'].forEach(function (evt) { 82 window.addEventListener(evt, function () { 83 lastInteractionAt = Date.now(); 84 }, { passive: true, capture: true }); 85}); 86 87function doRefresh(slot) { 88 googletag.pubads().refresh([slot]); 89} 90 91function refreshWhenIdle(slot, deadline) { 92 if (!USE_IDLE_REFRESH) { 93 doRefresh(slot); 94 return; 95 } 96 97 if (!deadline) deadline = Date.now() + MAX_DEFER_MS; 98 99 var since = Date.now() - lastInteractionAt; 100 101 // Usuario tocou agora ha pouco: adia, mas nunca alem do deadline. 102 if (since < INTERACTION_QUIET_MS && Date.now() < deadline) { 103 setTimeout(function () { 104 refreshWhenIdle(slot, deadline); 105 }, INTERACTION_QUIET_MS - since); 106 return; 107 } 108 109 if (typeof window.requestIdleCallback === 'function') { 110 window.requestIdleCallback(function () { 111 doRefresh(slot); 112 }, { timeout: IDLE_TIMEOUT_MS }); 113 } else { 114 // Safari antigo nao tem requestIdleCallback: refresh direto. 115 doRefresh(slot); 116 } 117} 118 119/* ---------- definicao dos slots ---------- */ 120 121googletag.cmd.push(function () { 122 var mapping_top = googletag.sizeMapping()
123 .addSize([980, 200], [[970, 250], [970, 90]]) 124 .addSize([0, 0], [[320, 50], [320, 100]]) 125 .build(); 126 127 var mapping_middle = googletag.sizeMapping() 128 .addSize([980, 200], [[728, 90], [300, 250], [336, 280]]) 129 .addSize([0, 0], [[320, 50], [320, 100], [300, 250], [336, 280]]) 130 .build(); 131 132 googletag.defineSlot('7542,40069432/parceiros/bebemamae', [[970, 250], [970, 90], [320, 50], [320, 100]], 'r7_header') 133 .defineSizeMapping(mapping_top) 134 .setTargeting(REFRESH_KEY, REFRESH_VALUE) 135 .setTargeting('refreshed_slot', 'false') 136 .addService(googletag.pubads()); 137 138 ['r7_texto_1', 'r7_texto_2', 'r7_texto_3', 'r7_texto_4', 'r7_texto_5'].forEach(function (slotId) { 139 if (!shouldLoadSlot(slotId)) return; 140 googletag.defineSlot('/7542,40069432/parceiros/bebemamae', [[728, 90], [300, 250], [336, 280], [320, 50], [320, 100]], slotId) 141 .defineSizeMapping(mapping_middle) 142 .setTargeting(REFRESH_KEY, REFRESH_VALUE) 143 .setTargeting('refreshed_slot', 'false') 144 .addService(googletag.pubads()); 145 }); 146 147 anchor_slot = googletag.defineOutOfPageSlot('/7542,40069432/parceiros/bebemamae', googletag.enums.OutOfPageFormat.BOTTOM_ANCHOR); 148 149 if (anchor_slot) { 150 anchor_slot.setTargeting(REFRESH_KEY, REFRESH_VALUE).setTargeting('refreshed_slot', 'false').addService(googletag.pubads()); 151 } else { } 152 153 var SECONDS_TO_WAIT_AFTER_VIEWABILITY = 30; 154 googletag.pubads().addEventListener('impressionViewable', function (event) { 155 var slot = event.slot; 156 if (slot.getTargeting(REFRESH_KEY).indexOf(REFRESH_VALUE) > -1) { 157 slot.setTargeting('refreshed_slot', 'true'); 158 setTimeout(function () { 159 refreshWhenIdle(slot); 160 }, SECONDS_TO_WAIT_AFTER_VIEWABILITY * 1000); 161 } 162 }); 163 164 googletag.pubads().enableLazyLoad({ 165 fetchMarginPercent: 30, 166 renderMarginPercent: 25, 167 mobileScaling: 1 168 }); 169 170 googletag.pubads().setTargeting('executed', 'ads'); 171 // Permite separar no relatorio do GAM o que foi servido em aparelho fraco. 172 googletag.pubads().setTargeting('device_tier', IS_LOW_END ? 'low' : 'normal'); 173 googletag.pubads().setCentering(true); 174 googletag.enableServices(); 175 176 googletag.display(anchor_slot); 177}); 178 179/* ---------- exibicao ---------- */ 180 181function appendAd(adUnitID) { 182 var existingDiv = document.getElementById(adUnitID); 183 184 if (existingDiv) { 185 googletag.cmd.push(function () { 186 googletag.display(adUnitID); 187 }); 188 } 189} 190 191// Remove do DOM o container do slot descartado e o rotulo 192// "Link Patrocinado" que vem imediatamente antes dele, para nao 193// sobrar espaco em branco nem texto orfao. 194function removeSlotContainer(slotId) { 195 var div = document.getElementById(slotId); 196 if (!div) return; 197 198 // O rotulo "Link Patrocinado" vem imediatamente antes da div do slot. 199 // previousElementSibling ignora comentarios e nos de texto, entao o 200 // comentario <!--R7 banner -->
200 nao atrapalha a busca. 201 var previo = div.previousElementSibling; 202 if (previo && previo.classList && previo.classList.contains('links-patrocinados-label')) { 203 previo.parentNode.removeChild(previo); 204 } 205 206 var wrapper = div.parentNode; 207 div.parentNode.removeChild(div); 208 209 // O Ad Inserter envolve cada bloco num container proprio, por exemplo 210 // .publicidade-4, e esse container tem altura definida. Se ele ficar, 211 // sobra espaco em branco no lugar do anuncio removido. 212 // So removemos se ele tiver ficado realmente vazio, para nao levar junto 213 // nenhum conteudo que nao seja nosso. 214 if (wrapper && typeof wrapper.className === 'string' && 215 /publicidade|code-block|ai-viewport/i.test(wrapper.className) && 216 wrapper.children.length === 0 && 217 wrapper.parentNode) { 218 wrapper.parentNode.removeChild(wrapper); 219 } 220} 221 222// So chamar depois que o DOM inteiro existir: as divs r7_texto_1..5 223// sao inseridas pelo Ad Inserter no meio do artigo, ou seja, depois 224// deste script no HTML. 225function displayAllR7Ads() { 226 appendAd('r7_header'); 227 228 ['r7_texto_1', 'r7_texto_2', 'r7_texto_3', 'r7_texto_4', 'r7_texto_5'].forEach(function (slotId) { 229 if (shouldLoadSlot(slotId)) { 230 appendAd(slotId); 231 } else { 232 removeSlotContainer(slotId); 233 } 234 }); 235} 236 237if (document.readyState === 'loading') { 238 document.addEventListener('DOMContentLoaded', displayAllR7Ads); 239} else { 240 displayAllR7Ads(); 241}
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.