From 4f651b41cae76025dff3e1e4e708c4dc49e880c2 Mon Sep 17 00:00:00 2001 From: alistair3149 Date: Sun, 23 Oct 2022 16:37:43 -0400 Subject: [PATCH] =?UTF-8?q?feat(pwa):=20=E2=9C=A8=20add=20basic=20support?= =?UTF-8?q?=20for=20service=20worker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is super basic and experimental. It will be expanded upon in the future, but for now it will satisfy the requirement for PWA --- resources/skins.citizen.scripts/skin.js | 39 +++++++++++++++++---- resources/skins.citizen.serviceWorker/sw.js | 13 +++++++ skin.json | 9 +++++ 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 resources/skins.citizen.serviceWorker/sw.js diff --git a/resources/skins.citizen.scripts/skin.js b/resources/skins.citizen.scripts/skin.js index e493e56d..035baa38 100644 --- a/resources/skins.citizen.scripts/skin.js +++ b/resources/skins.citizen.scripts/skin.js @@ -80,6 +80,30 @@ function onTitleHidden( document ) { } } +/** + * Register service worker + * + * @return {void} + */ +function registerServiceWorker() { + const scriptPath = mw.config.get( 'wgScriptPath' ); + + // Only allow serviceWorker when the scriptPath is at root because of its scope + // I can't figure out how to add the Service-Worker-Allowed HTTP header to change the default scope + if ( scriptPath === '' ) { + if ( 'serviceWorker' in navigator ) { + const SW_MODULE_NAME = 'skins.citizen.serviceWorker', + version = mw.loader.moduleRegistry[ SW_MODULE_NAME ].version, + // HACK: Faking a RL link + swUrl = scriptPath + + '/load.php?modules=' + SW_MODULE_NAME + + '&only=scripts&raw=true&skin=citizen&version=' + version; + + navigator.serviceWorker.register( swUrl, { scope: '/' } ); + } + } +} + /** * @param {Window} window * @return {void} @@ -87,21 +111,18 @@ function onTitleHidden( document ) { function main( window ) { const search = require( './search.js' ); - const tocContainer = document.getElementById( 'toc' ); - enableCssAnimations( window.document ); search.init( window ); onTitleHidden( window.document ); - window.addEventListener( 'beforeunload', () => { - document.documentElement.classList.add( 'citizen-loading' ); - }, false ); - + // Set up checkbox hacks bind(); bindCloseOnUnload(); // Handle ToC // TODO: There must be a cleaner way to do this + const tocContainer = document.getElementById( 'toc' ); + if ( tocContainer ) { const toc = require( './tableOfContents.js' ); toc.init(); @@ -115,6 +136,12 @@ function main( window ) { } mw.loader.load( 'skins.citizen.preferences' ); + + // Set up loading indicator + window.addEventListener( 'beforeunload', () => { + document.documentElement.classList.add( 'citizen-loading' ); + }, false ); + registerServiceWorker(); } if ( document.readyState === 'interactive' || document.readyState === 'complete' ) { diff --git a/resources/skins.citizen.serviceWorker/sw.js b/resources/skins.citizen.serviceWorker/sw.js new file mode 100644 index 00000000..eca94bf5 --- /dev/null +++ b/resources/skins.citizen.serviceWorker/sw.js @@ -0,0 +1,13 @@ +// TODO: Make it actually do something +// See https://gerrit.wikimedia.org/r/c/mediawiki/extensions/MobileFrontend/+/273388/ +self.addEventListener( 'install', ( event ) => { + console.log( 'Service worker installed' ); +} ); + +self.addEventListener( 'activate', ( event ) => { + console.log( 'Service worker activated' ); +} ); + +self.addEventListener( 'fetch', ( event ) => { + console.log( 'Service worker fetch' ); +} ); \ No newline at end of file diff --git a/skin.json b/skin.json index a5cc97ce..33a3f28e 100644 --- a/skin.json +++ b/skin.json @@ -263,6 +263,15 @@ "mobile" ] }, + "skins.citizen.serviceWorker": { + "scripts": [ + "resources/skins.citizen.serviceWorker/sw.js" + ], + "targets": [ + "desktop", + "mobile" + ] + }, "skins.citizen.icons": { "class": "ResourceLoaderImageModule", "selector": "{name}",