1/* 2Companion de "dormir" scripts e iframes de analitica/marketing (ver 3app_code/pS.Core/Security/TrackingScriptCloak.cs y el metodo 4IframeSeguimiento de web/DesktopModules/InmoBS3/layouts/inmuebles/WebInmobiliariaBase.cs). 5 6Motivo: PD Cookie Consent 1.5.4 intenta impedir la ejecucion de Google 7Analytics/Ads (GTM, gtag), Meta/Facebook Pixel, iframes de YouTube/Visita 8Virtual, etc. enganchandose al evento "beforescriptexecute", que Chrome y el 9resto de navegadores basados en Chromium ya no disparan (retirado). El 10selector sigue mostrando el aviso y "sabe" que deberia bloquear esos 11servicios, pero nunca llega a impedir que se ejecuten/carguen: la etiqueta 12carga igual, con o sin rechazo. 13 14En vez de bloquear DESPUES de que el recurso ya se ha cargado (imposible sin 15ese evento), el servidor sirve: 16 - los <script> de seguimiento como type="text/plain" (un tipo que el 17 navegador nunca ejecuta), 18 - los <iframe> de YouTube/Visita Virtual sin "src" (con "data-pdcc-src"), 19ambos marcados con "data-pdcc-cloak". Este companion los reactiva por su 20cuenta, leyendo la MISMA cookie "pd_cc" que ya mantiene PD Cookie Consent: 21 22 - accepted === true -> se activan todos 23 - blockList[].actived === true (por dominio) -> se activa solo ese servicio 24 - en cualquier otro caso -> se queda dormido (los 25 iframes muestran ademas un aviso con boton para cargarlo solo ese) 26 27No hace falta correr esto antes de que el navegador parsee la pagina: nada 28de esto se autoejecuta/autocarga, asi que no hay ninguna carrera que ganar. 29Basta con activarlo en DOMContentLoaded, y de nuevo cada vez que el 30visitante decide algo en el selector (igual que avisoSinCookies.js: PD 31Cookie Consent solo recarga la pagina al Aceptar/Guardar configuracion, asi 32que en la practica esto ultimo solo importa si algun dia dejase de recargar). 33 34Textos sin acentos a proposito (fichero ASCII puro, sin BOM, para no arriesgar 35la codificacion de un .js legacy servido tal cual desde disco). 36*/ 37(function () { 38 'use strict'; 39 40 var COOKIE = 'pd_cc'; 41 var SELECTOR_SCRIPTS_DORMIDOS = 'script[type="text/plain"][data-pdcc-cloak]'; 42 var SELECTOR_IFRAMES_DORMIDOS = 'iframe[data-pdcc-cloak]'; 43 44 var TEXTOS = { 45 es: { aviso: 'Este contenido esta bloqueado por tu configuracion de cookies.', boton: 'Aceptar y cargar' }, 46 ca: { aviso: 'Aquest contingut esta bloquejat per la teva configuracio de cookies.', boton: 'Acceptar i carregar' }, 47 en: { aviso: 'This content is blocked by your cookie settings.', boton: 'Accept and load' }, 48 eu: { aviso: 'Eduki hau blokeatuta dago zure cookie-ezarpenengatik.', boton: 'Onartu eta kargatu' }, 49 gl: { aviso: 'Este contido esta bloqueado pola tua configuracion de cookies.', boton: 'Aceptar e cargar' } 50 }; 51 52 function textos() { 53 var lang = (document.documentElement.lang || 'es').toLowerCase(); 54 if (lang.indexOf('-') !== -1) lang = lang.split('-')[0]; 55 return TEXTOS[lang] || TEXTOS.es; 56 } 57 58 // Mismo parseo que usa avisoSinCookies.js para la cookie de PD Cookie Consent. 59 function estadoCookies() { 60 var partes = decodeURIComponent(document.cookie).split(';'); 61 for (var i = 0; i < partes.length; i++) { 62 var parte = partes[i]; 63 while (parte.charAt(0) === ' ') parte = parte.substring(1); 64 if (parte.indexOf(COOKIE + '=') === 0) { 65 try { 66 return JSON.parse(parte.substring(COOKIE.length + 1)); 67 } catch (e) { 68 return null; 69 } 70 } 71 } 72 return null; 73 } 74 75 function permitido(elemento, estado) { 76 if (!estado) return false; 77 if (estado.accepted === true) return true; 78 79 var lista = estado.blockList; 80 if (!lista || !lista.length) return false; 81 82 var src = elemento.getAttribute('src') || elemento.getAttribute('data-pdcc-src') || ''; 83 var texto = elemento.textContent || ''; 84 85 // Contenido de terceros que PDCC no cataloga como servicio propio (URL 86 // libre de un proveedor de tour virtual, por ejemplo): no hay categoria 87 // con la que emparejar por dominio. Si el visitante ha activado al menos 88 // una categoria no esencial y guardado configuracion (no ha dejado todo 89 // rechazado), se trata como consentido en espiritu: exigir ademas 90 // "Aceptar todas" para ver un video ya aceptado seria mas friccion de la 91 // que pide la ley. 92 var hayAlgunaCategoriaAceptada = false;
93 94 for (var i = 0; i < lista.length; i++) { 95 var item = lista[i]; 96 if (!item || item.actived !== true) continue; 97 hayAlgunaCategoriaAceptada = true; 98 var patron = item.domain || item.contain; 99 if (!patron) continue; 100 if ((src && src.indexOf(patron) !== -1) || (texto && texto.indexOf(patron) !== -1)) { 101 return true; 102 } 103 } 104 return hayAlgunaCategoriaAceptada; 105 } 106 107 // Sustituye el <script type="text/plain"> por uno normal: cambiar solo el 108 // atributo "type" de un nodo ya insertado NO lo ejecuta, un <script> solo 109 // se ejecuta si el navegador lo ve nacer ya con un tipo ejecutable. 110 function activaScript(viejo) { 111 var nuevo = document.createElement('script'); 112 for (var i = 0; i < viejo.attributes.length; i++) { 113 var attr = viejo.attributes[i]; 114 if (attr.name === 'type' || attr.name === 'data-pdcc-cloak') continue; 115 nuevo.setAttribute(attr.name, attr.value); 116 } 117 if (!viejo.hasAttribute('src')) { 118 nuevo.textContent = viejo.textContent; 119 } 120 viejo.parentNode.replaceChild(nuevo, viejo); 121 } 122 123 function activaIframe(iframe) { 124 var aviso = iframe.parentNode && iframe.parentNode.querySelector 125 ? iframe.parentNode.querySelector('.pdccIframeAviso') 126 : null; 127 if (aviso && aviso.parentNode) aviso.parentNode.removeChild(aviso); 128 129 iframe.setAttribute('src', iframe.getAttribute('data-pdcc-src')); 130 iframe.removeAttribute('data-pdcc-cloak'); 131 } 132 133 // Envuelve el iframe dormido en un contenedor con posicion relativa y le 134 // superpone un aviso con boton. El boton carga SOLO ese iframe (consentimiento 135 // puntual para ese contenido concreto), sin tocar la cookie ni recargar: no 136 // hace falta pasar por el selector completo para ver un unico video/tour. 137 function creaAviso(iframe) { 138 var wrap = document.createElement('div'); 139 wrap.className = 'pdccIframeWrap'; 140 // El iframe de YouTube lleva class="embed-responsive-item" (Bootstrap: 141 // position:absolute;width:100%;height:100%, posicionado respecto al 142 // ".embed-responsive" que lo envuelve). Al meter el wrap en medio, el wrap 143 // pasa a ser el ancestro posicionado mas cercano: tiene que ocupar el mismo 144 // hueco que ocupaba el iframe, o el video/aviso queda con altura 0. 145 if (iframe.classList.contains('embed-responsive-item')) { 146 wrap.className += ' pdccIframeWrap-absoluto'; 147 } 148 iframe.parentNode.insertBefore(wrap, iframe); 149 wrap.appendChild(iframe); 150 151 var t = textos(); 152 var aviso = document.createElement('div'); 153 aviso.className = 'pdccIframeAviso'; 154 155 var texto = document.createElement('p'); 156 texto.className = 'pdccIframeAviso-texto'; 157 texto.appendChild(document.createTextNode(t.aviso)); 158 159 var boton = document.createElement('button'); 160 boton.type = 'button'; 161 boton.className = 'pdccIframeAviso-btn'; 162 boton.appendChild(document.createTextNode(t.boton)); 163 boton.addEventListener('click', function () { 164 activaIframe(iframe); 165 }); 166 167 aviso.appendChild(texto); 168 aviso.appendChild(boton); 169 wrap.appendChild(aviso); 170 } 171 172 function reactivaPermitidos() { 173 var scripts = document.querySelectorAll(SELECTOR_SCRIPTS_DORMIDOS); 174 var iframes = document.querySelectorAll(SELECTOR_IFRAMES_DORMIDOS); 175 if (!scripts.length && !iframes.length) return; 176 177 var estado = estadoCookies(); 178 179 for (var i = 0; i < scripts.length; i++) { 180 if (permitido(scripts[i], estado)) activaScript(scripts[i]); 181 } 182 183 for (var j = 0; j < iframes.length; j++) { 184 if (permitido(iframes[j], estado)) activaIframe(iframes[j]); 185 else creaAviso(iframes[j]); 186 } 187 } 188 189 if (document.readyState === 'loading') { 190 document.addEventListener('DOMContentLoaded', reactivaPermitidos); 191 } else { 192 reactivaPermitidos(); 193 } 194})();
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.