User:Suffusion of Yellow/AnonSettings/sw.js

// DO NOT INSTALL THIS IN YOUR common.js! const DEFAULT_SETTINGS = { skin : "vector", nologin : true }; const CONFIG_SRC = "https://en.wikipedia.org/w/index.php?title=User:Suffusion_of_Yellow/AnonSettings/config.js&action=raw&ctype=text/javascript";

function saveSettings(settings) { return self.caches.open("anonsettings") .then(cache => cache.put("/anonsettings/data", new Response(JSON.stringify(settings)))); }

function getSettings { return self.caches.open("anonsettings") .then(cache => cache.match("/anonsettings/data")) .then(settings => settings ? settings.json : DEFAULT_SETTINGS); }

function injectSettingsScript(response, settings) { return response.text .then(text => new Response(text.replace(			/<\/body>\s*<\/html>\s*$/,			` const ANON_SETTINGS=${JSON.stringify(settings)};  $&`), { headers : response.headers })); }

function getResponse(event, url, settings) { // Unregister if attempting to log in	if (settings.nologin && url.pathname == "/w/index.php" && url.searchParams.get("title") == "Special:UserLogin") { return self.registration.unregister .then( => fetch(event.request)); }

if (settings.skin && !url.searchParams.get("useskin")) url.searchParams.set("useskin", settings.skin); if (settings.lang && !url.searchParams.get("uselang")) url.searchParams.set("uselang", settings.lang); if (settings.gadget && !url.searchParams.get("withgadget")) url.searchParams.set("withgadget", settings.gadget);

let options = {}; for (let option of ["method", "headers", "credentials", "cache", "redirect", "referrer", "referrerPolicy", "integrity"]) if (option in event.request) options[option] = event.request[option];

if (url.pathname == "/wiki/User:Suffusion_of_Yellow/AnonSettings/Setup") { return fetch(new Request(url, options)) .then(response => injectSettingsScript(response, settings)) .catch(e => getErrorResponse(e)); }

if (event.request.method == "GET" || event.request.method == "HEAD") return fetch(new Request(url, options)).catch(e => getErrorResponse(e));

return event.request.blob .then(body => {			options.body = body;			return fetch(new Request(url, options)).catch(e => getErrorResponse(e));		}); }

function getErrorResponse(err) { if (!self.navigator.userAgent.includes("Firefox")) return null; // Trigger network error in client

// Apparently Firefox will "helpfully" remove the ServiceWorker after // too many network errors. So send a fake 503 response instead. return new Response(`AnonSettings: ${err}`, {		status: 503	}); }

// Flush out any buggy old versions, at least while still in development self.addEventListener('install', event => {	self.skipWaiting; }); self.addEventListener('activate', event => {	event.waitUntil(self.clients.claim); });

self.addEventListener('message', event => {	if (event.data && event.data.settings)		event.waitUntil(saveSettings(event.data.settings)); });

self.addEventListener('fetch', event => {	let url = new URL(event.request.url);

if (url.origin !== self.location.origin) return;

// Safe mode means "no user scripts", which I guess should include this one if (url.searchParams.get("safemode")) return;

// Hack to detect an already logged-in session. This is the only // non-"navigate" request we look at and we don't modify it	if (url.pathname == "/w/load.php" && url.searchParams.get("modules") && url.searchParams.get("modules").split("|").includes("user")) { event.waitUntil(getSettings.then(settings => { if (settings.nologin) self.registration.unregister; }));		return; }

// Ignore JS, CSS, etc.	if (event.request.mode !== "navigate") return;

// Don't add irritating warnings to every API help page... if (!url.pathname.match(/^\/w\/index.php$|^\/$|^\/wiki/)) return;

// Fallback uninstallation link, in case the settings page fails to load if (url.pathname == "/wiki/User:Suffusion_of_Yellow/AnonSettings/Uninstall" ) {

event.respondWith(self.registration.unregister						 .then( => Response.redirect("/"))); return; }

// Default response if offline if (!self.navigator.onLine) return;

event.respondWith(getSettings.then(settings => getResponse(event, url, settings))); }); // DO NOT INSTALL THIS IN YOUR common.js!