1var idbKeyval=function(e){"use strict";class t{constructor(e="keyval-store",t="keyval"){this.storeName=t,this._dbp=new Promise((r,n)=>{const o=indexedDB.open(e,1);o.onerror=(()=>n(o.error)),o.onsuccess=(()=>r(o.result)),o.onupgradeneeded=(()=>{o.result.createObjectStore(t)})})}_withIDBStore(e,t){return this._dbp.then(r=>new Promise((n,o)=>{const s=r.transaction(this.storeName,e);s.oncomplete=(()=>n()),s.onabort=s.onerror=(()=>o(s.error)),t(s.objectStore(this.storeName))}))}}let r;function n(){return r||(r=new t),r}return e.Store=t,e.get=function(e,t=n()){let r;return t._withIDBStore("readonly",t=>{r=t.get(e)}).then(()=>r.result)},e.set=function(e,t,r=n()){return r._withIDBStore("readwrite",r=>{r.put(t,e)})},e.del=function(e,t=n()){return t._withIDBStore("readwrite",t=>{t.delete(e)})},e.clear=function(e=n()){return e._withIDBStore("readwrite",e=>{e.clear()})},e.keys=function(e=n()){const t=[];return e._withIDBStore("readonly",e=>{(e.openKeyCursor||e.openCursor).call(e).onsuccess=function(){this.result&&(t.push(this.result.key),this.result.continue())}}).then(()=>t)},e}({}); 2 3vsm= vsm||{}; 4vsm.webpush ={}; 5vsm.webpush.enabled = false; 6vsm.webpush.error = ""; 7vsm.webpush.errorDescription = ""; 8vsm.webpush.tootTipTime=0; 9vsm.webpush.load = function (buttonid){ 10 var language = window.navigator.userLanguage || window.navigator.language; 11 language = language.split('-')[0].toLowerCase(); 12 if (typeof vsmlang != 'undefined') language=vsmlang; 13 if(language != 'es' && language != 'en') language = 'en'; 14 15 vsm.loadScript('/lib/web-push/notificationsErrors-'+language+'.js'); 16 17 18 if (!('serviceWorker' in navigator)) { 19 console.warn("Service workers are not supported by this browser"); 20 vsm.webpush.error= "notsupported"; 21 if (document.location.protocol == 'http:') vsm.webpush.error= "nossl"; 22 return; 23 } 24 25 if (!('PushManager' in window)) { 26 vsm.webpush.error= "notsupported"; 27 console.warn('Push notifications are not supported by this browser'); 28 return; 29 } 30 31 if (!('showNotification' in ServiceWorkerRegistration.prototype)) { 32 vsm.webpush.error= "notsupported"; 33 console.warn('Notifications are not supported by this browser'); 34 return; 35 } 36 37 // Check the current Notification permission. 38 // If its denied, the button should appears as such, until the user changes the permission manually 39 if (Notification.permission === 'denied') { 40 vsm.webpush.error= "denied"; 41 console.warn('Notifications are denied by the user'); 42 return; 43 } 44 45 if (buttonid && !vsm.object(buttonid)){ 46 console.error('#'+buttonid+' not found'); 47 return; 48 } 49 buttonid = vsm.object(buttonid); 50 swconfig = buttonid.getAttribute("data-swconfig"); 51 if (!swconfig) swconfig = 'swconfig'; 52 53 54 navigator.serviceWorker.register('/lib/web-push/serviceWorker.js',{scope:'/'}) 55 .then(() => { 56 vsm.webpush.enabled =true; 57 navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { 58 if(vsm.webpush[swconfig]) idbKeyval.set(swconfig,vsm.webpush[swconfig]); 59 serviceWorkerRegistration.pushManager.getSubscription() 60 .then(function(subscription) { 61 vsm.attachEvent(buttonid,'click',function(){vsm.webpush.updateSubscription(buttonid,buttonid.getAttribute('data-ot'),buttonid.getAttribute('data-oid'),true)}); 62 if (localStorage.getItem('subscription-'+buttonid.getAttribute('data-ot')+'-'+buttonid.getAttribute('data-oid'))) { 63 vsm.addClass(buttonid,'subscribed'); 64 }else{ 65 subscription=false; //No hay suscripción 66 } 67 if (!subscription){ 68 vsm.addClass(buttonid,'visible'); 69 vsm.addClass(document.body,'notification-button-enabled'); 70 vsm.tooltip.start(); 71 vsm.webpush.tootTipTime = setTimeout(function(){ 72 vsm.tooltip.show(buttonid); 73 vsm.overflow.checkAll(); //Chequea los overflow, por si el boton genera un more-button. 74 },3000); 75 var fcount = buttonid.getAttribute('data-force-count'); 76 if (fcount!=null){ //Fuerza la subscripción despues de X visitas, configurado en el boton 77 sc = localStorage.getItem('subscription-count'); 78 if (sc==null || sc>1000) sc=0; //Que no sea mas grande de 100 para que no generar elementos muy grandes 79 localStorage.setItem('subscription-count', parseInt(sc)+1); 80 if (fcount==0 || (sc>0 && sc%fcount==0)){ 81 vsm.webpush.updateSubscription(buttonid,buttonid.getAttribute('data-ot'),buttonid.getAttribute('data-oid')); 82 clearTimeout(vsm.webpush.tootTipTime); 83 } 84 } 85 86 }
86else{ //Actualiza la información cada 5 visitas, es por si se cambian las claves y por si hay alguna actualización 87 var fcount = buttonid.getAttribute('data-force-count'); 88 if (fcount!=null){ //Fuerza la subscripción despues de X visitas, configurado en el boton 89 sc = localStorage.getItem('subscription-count'); 90 if (sc==null || sc>1000) sc=0; //Que no sea mas grande de 100 para que no generar elementos muy grandes 91 localStorage.setItem('subscription-count', parseInt(sc)+1); 92 if (fcount==0 || (sc>0 && sc%fcount==0)){ 93 vsm.webpush.updateSubscription(buttonid,buttonid.getAttribute('data-ot'),buttonid.getAttribute('data-oid')); 94 } 95 } 96 } 97 }) 98 }) 99 return true; 100 }).catch(function(err) { 101 vsm.webpush.error = "register"; 102 vsm.webpush.errorDescription = err; 103 } 104 ); 105 106} 107 108vsm.webpush.getError= function(){ 109 if (vsm.webpush.errors[vsm.webpush.error]){ 110 return vsm.webpush.errors[vsm.webpush.error].replace('%1','<i>'+vsm.webpush.errorDescription+'</i>'); 111 }else if(vsm.webpush.errorDescription){ 112 return vsm.webpush.errorDescription; 113 }else{ 114 return "Unspecified error"; 115 } 116} 117vsm.webpush.updateSubscription = async function (buttonid, ot, oid, modal) { 118 var bg=false; 119 if (modal){ 120 var bg=document.createElement("div"); 121 document.body.appendChild(bg); 122 bg.style.position = 'fixed'; 123 bg.style.top = '0'; 124 bg.style.left = '0'; 125 bg.style.bottom= '0'; 126 bg.style.right= '0'; 127 bg.style.zIndex=10001; 128 bg.style.background= 'rgba(0,0,0,0.8)'; 129 } 130 131 vsm.removeClass(buttonid,'visible'); 132 vsm.removeClass(document.body,'notification-button-enabled'); 133 clearTimeout(vsm.webpush.tootTipTime); 134 vsm.tooltip.hide(); 135 vsm.overflow.checkAll(); //Chequea los overflow, por si el boton genere un more-button. 136 137 138 // 1. PEDIR PERMISO INMEDIATAMENTE (User Gesture) 139 // Esto es lo que Edge necesita ver vinculado al click de forma directa 140 let permission; 141 try { 142 permission = await Notification.requestPermission(); 143 } catch (e) { 144 // Soporte para navegadores muy viejos que no devuelven promesa 145 permission = await new Promise((res) => Notification.requestPermission(res)); 146 } 147 148 if (permission !== 'granted') { 149 console.warn('Permission not granted'); 150 return; 151 } 152 153 154 try { 155 const serviceWorkerRegistration = await navigator.serviceWorker.ready; 156 157 localStorage.setItem(`subscription-${ot}-${oid}`, 1); 158 vsm.addClass(buttonid, 'subscribed'); 159 160 const pushSubscription = await vsm.webpush.subscribe( 161 serviceWorkerRegistration, 162 ot, 163 oid, 164 vsm.webpush.applicationServerKey 165 ); 166 167 if (bg) document.body.removeChild(bg); 168 console.log('Successfully subscribed:', pushSubscription); 169 170 } catch (error) { 171 if (bg) document.body.removeChild(bg); 172 console.error('Error during subscription:', error.message); 173 } 174}; 175 176vsm.webpush.subscribe = function (serviceWorkerRegistration,ot,oid,applicationServerKey){ 177 const options = { 178 userVisibleOnly: true, 179 applicationServerKey: urlBase64ToUint8Array(applicationServerKey) 180 }; 181 return serviceWorkerRegistration.pushManager.subscribe(options).then((pushSubscription) => { 182 // Subscription was successful 183 // create subscription on your server 184 const key = pushSubscription.getKey('p256dh'); 185 const token = pushSubscription.getKey('auth'); 186 187 188 return fetch('/tools/webPushBrowser.php?method=update&ot='+ot+'&oid='+oid, { 189 method: 'POST', 190 body: JSON.stringify({ 191 endpoint: pushSubscription.endpoint, 192 key: key ? btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : null, 193 token: token ? btoa(String.fromCharCode.apply(null, new Uint8Array(token))) : null 194 }), 195 }).then(() => pushSubscription); 196 197 });
198 function urlBase64ToUint8Array(base64String) { 199 const padding = '='.repeat((4 - base64String.length % 4) % 4); 200 const base64 = (base64String + padding) 201 .replace(/\-/g, '+') 202 .replace(/_/g, '/'); 203 204 const rawData = self.atob(base64); 205 const outputArray = new Uint8Array(rawData.length); 206 207 for (let i = 0; i < rawData.length; ++i) { 208 outputArray[i] = rawData.charCodeAt(i); 209 } 210 return outputArray; 211 } 212}
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.