PageSourceSearch

https://www.mtu.edu/jssw.js

js mtu.edu collected 2026-09-24 08:24:36 UTC 9,130 bytes, 314 lines download raw bytes

1'use strict';
2const d = new Date();
3const staticCacheName =  'static_v-01';
4const pagesCacheName = 'pages_v-01';
5const imagesCacheName = 'images_v-02';
6const assetsCacheName = 'assets_v' + d.getMonth() + '' + d.getDate() + '-01';
7const maxPages = 50; // Maximum number of pages to cache
8const maxImages = 100; // Maximum number of images to cache
9const timeout = 3000; // Number of milliseconds before timing out
10
11const cacheList = [
12  staticCacheName,
13  pagesCacheName,
14  imagesCacheName,
15  assetsCacheName
16];
17
18
19function updateStaticCache() {
20  return caches.open(staticCacheName)
21    .then(staticCache => {
22      // These items won't block the installation of the Service Worker
23      staticCache.addAll([
24        '/mtu_resources/styles/n/print.css'
25      ]);
26      // These items must be caced for the Service Worker to complete installation
27      return staticCache.addAll([
28        '/offline/index.php'
29      ])
30    })
31    .catch(error=>{
32        console.log(error);
33    });
34}
35
36// Cache the page(s) that initiate the service worker
37function cacheClients() {
38  const pages = [];
39  return clients.matchAll({
40      includeUncontrolled: true
41    })
42    .then(allClients => {
43      for (const client of allClients) {
44        pages.push(client.url);
45      }
46    })
47    .then(() => {
48      caches.open(pagesCacheName)
49        .then(pagesCache => {
50          return pagesCache.addAll(pages);
51        });
52    })
53}
54
55// Remove caches whose name is no longer valid
56async function clearOldCaches() {
57  const cacheNames = await caches.keys();
58  return await Promise.all(
59    cacheNames.map(cacheName => {
60      if (!cacheList.includes(cacheName)) {
61        return caches.delete(cacheName);
62      }
63    })
64  );
65}
66
67// Remove old versions of a file in cache. 
68function clearStaleVersions(cacheName, url, version){
69    caches.open(cacheName)
70    .then( cache => {
71        cache.keys()
72        .then( keys=> {
73            keys.forEach( key => {
74                if ( 0 < key.url.indexOf( url ) ) {
75                    if ( 0 > key.url.indexOf( version )){
76                        cache.delete(key);
77                    }
78                }
79            })
80        })
81    } )
82}
83
84function trimCache(cacheName, maxItems) {
85  caches.open(cacheName)
86    .then(cache => {
87      cache.keys()
88        .then(keys => {
89          if (keys.length > maxItems) {
90            cache.delete(keys[0])
91              .then(() => {
92                trimCache(cacheName, maxItems)
93              });
94          }
95        });
96    });
97}
98
99// Install Service Worker fetchEvent Listener
100addEventListener('install', installEvent => {
101  installEvent.waitUntil(
102    // Update our static cache
103    updateStaticCache()
104    .then(() => {
105      return skipWaiting();
106    })
107  )
108})
109
110// Activate Service Worker fetchEvent Listener
111addEventListener('activate', fetchEvent => {
112  fetchEvent.waitUntil(
113    // Clear our old caches
114    clearOldCaches()
115    .then( () => {
116      // claim all open tabs with an updated service worker.
117      return clients.claim();
118    })
119  );
120});
121
122// Message fetchEvent Listener
123self.addEventListener('message', fetchEvent => {
124  if (fetchEvent.data.command == 'trimCaches') {
125    clearOldCaches();
126    trimCache(pagesCacheName, maxPages);
127    trimCache(imagesCacheName, maxImages);
128    trimCache(assetsCacheName, maxImages);
129  }
130});
131
132
133// Fetch fetchEvent Listener
134addEventListener('fetch', fetchEvent => {
135  const request = fetchEvent.request;
136  let url = new URL(request.url);
137  const blackList = ['google', 'ytimg', '.pdf', 'project.lib', 'addthis', '/webcams/cache', 'facebook', 'doubleclick', 'bing', '/tips/private', 'tip-line', 'streamingwebcams'];
138  let blackListed = false;
139  
140  // Ignore requests to some directories
141  blackList.forEach( term => {
142    if ( 0 < request.url.indexOf( term ) ) {
143      blackListed = true;
144    }
145  } );
146
147  if ( blackListed === true ) {
148    return;
149  }
150
151  // Check to make sure the request is good with a status 200. If not, return, it could be a redirect.
152  // If it isn't over https return.
153  if ( 0 > request.url.indexOf('https') ) {
154    return;
155  }
156
157  // Check to Cache css and js files
158  if ( url.href.match( /(\.css|\.js)/ ) ) {
159    // If it isn't from our website, a cdn, or jquery return.
160    if ( !url.href.match( /.+(cdn|mtu.edu|jquery)/ ) ) {
161      return;
162    }
163    // If it is from a cdn but it dosen't have an access-control policy return.
164    if ( url.href.match( /.+(cdn)/ ) 
165    && !request.headers.get( 'access-control-allow-origin' ) ) {
166      return;
167    }
168  }
169
170
171
172
173  // Ignore non-GET requests
174  if ( 'GET' !== request.method ) {
175    return;
176  }
177
178  if (request.headers.get('Accept').includes('text/html')) {
179
180    fetchEvent.respondWith(
181      new Promise(resolveWithResponse => {
182
183        const timer = setTimeout(() => {
184          // Time out: CACHE
185            caches.match(request)
186            .then(responseFromCache => {
187              if (responseFromCache) {
188                resolveWithResponse(responseFromCache);
189              }
190            })
191        }, timeout);
192
193        fetch(request)
194          .then(responseFromFetch => {
195            // NETWORK
196            clearTimeout(timer);
197            const copy = responseFromFetch.clone();
198            // Stash a copy of this page in the pages cache
199            try {
200              fetchEvent.waitUntil(
201                caches.open(pagesCacheName)
202                .then(pagesCache => {
203                  return pagesCache.put(request, copy);
204                })
205              );
206            } catch (error) {
207              console.warn(error);
208            }
209            return resolveWithResponse(responseFromFetch);
210          })
211          .catch(fetchError => {
212            clearTimeout(timer);
213            console.error(fetchError);
214            // CACHE or FALLBACK
215            caches.match(request)
216              .then(responseFromCache => {
217                return resolveWithResponse(
218                  responseFromCache || caches.match('./offline/index.php')
219                );
220              });
221          });
222      })
223    )
224    return;
225  }
226
227
228  if (0 < url.href.indexOf( '.css' ) || 0 < url.href.indexOf( '.js' ) ) {
229    let responseVersion;
230    fetchEvent.respondWith(
231      new Promise(resolveWithResponse => {
232
233        const timer = setTimeout(() => {
234          // Time out: CACHE
235            caches.match(request)
236            .then(responseFromCache => {
237              if (responseFromCache) {
238                resolveWithResponse(responseFromCache);
239              }
240            })
241        }, timeout);
242
243        fetch(request)
244          .then(responseFromFetch => {
245            // NETWORK
246            clearTimeout(timer);
247            const copy = responseFromFetch.clone();
248            // Stash a copy of this page in the pages cache
249            try {
250              fetchEvent.waitUntil(
251                caches.open(assetsCacheName)
252                .then(assetsCacheName => {
253                  return assetsCacheName.put(request, copy);
254                })
255              );
256            } catch (error) {
257              console.error(error);
258            }
259            return resolveWithResponse(responseFromFetch);
260          })
261          .catch(fetchError => {
262            clearTimeout(timer);
263            console.error(fetchError);
264            // CACHE or FALLBACK
265            caches.match(request)
266              .then(responseFromCache => {
267                return resolveWithResponse(responseFromCache);
268              });
269          });
270      })
271    )
272    return;
273  }
274
275  // For non-HTML requests, look in the cache first, fall back to the network
276  fetchEvent.respondWith(
277    caches.match(request)
278    .then(responseFromCache => {
279      // CACHE
280      return responseFromCache || fetch(request)
281        .then(responseFromFetch => {
282          // NETWORK
283          // If the request is for an image, stash a copy of this image in the images cache
284          if (request.url.match(/\.(jpe?g|png|gif|mapbox)/)) {
285            const copy = responseFromFetch.clone();
286            try {
287              fetchEvent.waitUntil(
288                caches.open(imagesCacheName)
289                .then(imagesCache => {
290                  return imagesCache.put(request, copy);
291                })
292              );
293            } catch (error) {
294              console.error(error);
295            }
296          }
297          return responseFromFetch;
298        })
299        .catch(fetchError => {
300          console.error(fetchError);
301          // FALLBACK
302          // show an offline placeholder
303          if (request.url.match(/\.(jpe?g|png|gif|mapbox)/)) {
304            return new Response('<svg role="img" aria-labelledby="offline-title" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title id="offline-title">Offline</title><g fill="none" fill-rule="evenodd"><path fill="#D8D8D8" d="M0 0h400v300H0z"/><text fill="#9B9B9B" font-family="Helvetica Neue,Arial,Helvetica,sans-serif" font-size="72" font-weight="bold"><tspan x="93" y="172">offline</tspan></text></g></svg>', {
305              headers: {
306                'Content-Type': 'image/svg+xml',
307                'Cache-Control': 'no-store'
308              }
309            });
310          }
311        });
312    })
313  );
314});

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.