mirror of
https://github.com/transatoshi-mw/grin-web-wallet.git
synced 2025-10-06 15:52:47 +00:00
524 lines
15 KiB
JavaScript
Executable File
524 lines
15 KiB
JavaScript
Executable File
// Use strict
|
|
"use strict";
|
|
|
|
|
|
// Classes
|
|
|
|
// Service worker installer class
|
|
class ServiceWorkerInstaller {
|
|
|
|
// Public
|
|
|
|
// Constructor
|
|
constructor(version) {
|
|
|
|
// Set version
|
|
this.version = version;
|
|
|
|
// Set service worker to no service worker
|
|
this.serviceWorker = ServiceWorkerInstaller.NO_SERVICE_WORKER;
|
|
|
|
// Set allow updates
|
|
this.allowUpdates = false;
|
|
|
|
// Check if not an extension and not loading from file
|
|
if(Common.isExtension() === false && location["protocol"] !== Common.FILE_PROTOCOL) {
|
|
|
|
// Check if service workers are supported
|
|
if(typeof navigator === "object" && navigator !== null && "serviceWorker" in navigator === true) {
|
|
|
|
// Set installation status to installing
|
|
this.installationStatus = ServiceWorkerInstaller.INSTALLING_STATUS;
|
|
|
|
// Check if document is complete
|
|
if(document["readyState"] === "complete")
|
|
|
|
// Register
|
|
this.register();
|
|
|
|
// Otherwise
|
|
else {
|
|
|
|
// Set self
|
|
var self = this;
|
|
|
|
// Window load event
|
|
$(window).on("load", function() {
|
|
|
|
// Register
|
|
self.register();
|
|
});
|
|
}
|
|
}
|
|
|
|
// Otherwise
|
|
else {
|
|
|
|
// Set installation status to unsupported
|
|
this.installationStatus = ServiceWorkerInstaller.UNSUPPORTED_STATUS;
|
|
}
|
|
}
|
|
|
|
// Otherwise
|
|
else {
|
|
|
|
// Set installation status to unsupported
|
|
this.installationStatus = ServiceWorkerInstaller.UNSUPPORTED_STATUS;
|
|
}
|
|
}
|
|
|
|
// Get installation status
|
|
getInstallationStatus() {
|
|
|
|
// Return installation status
|
|
return this.installationStatus;
|
|
}
|
|
|
|
// Installing status
|
|
static get INSTALLING_STATUS() {
|
|
|
|
// Return installing status
|
|
return 0;
|
|
}
|
|
|
|
// Unsupported status
|
|
static get UNSUPPORTED_STATUS() {
|
|
|
|
// Return unsupported status
|
|
return ServiceWorkerInstaller.INSTALLING_STATUS + 1;
|
|
}
|
|
|
|
// Installed status
|
|
static get INSTALLED_STATUS() {
|
|
|
|
// Return installed status
|
|
return ServiceWorkerInstaller.UNSUPPORTED_STATUS + 1;
|
|
}
|
|
|
|
// Failed status
|
|
static get FAILED_STATUS() {
|
|
|
|
// Return failed status
|
|
return ServiceWorkerInstaller.INSTALLED_STATUS + 1;
|
|
}
|
|
|
|
// Install succeeded event
|
|
static get INSTALL_SUCCEEDED_EVENT() {
|
|
|
|
// Return install succeeded event
|
|
return "ServiceWorkerInstallerInstallSucceededEvent";
|
|
}
|
|
|
|
// Install failed event
|
|
static get INSTALL_FAILED_EVENT() {
|
|
|
|
// Return install failed event
|
|
return "ServiceWorkerInstallerInstallFailedEvent";
|
|
}
|
|
|
|
// Update available event
|
|
static get UPDATE_AVAILABLE_EVENT() {
|
|
|
|
// Return update available event
|
|
return "ServiceWorkerInstallerUpdateAvailableEvent";
|
|
}
|
|
|
|
// Private
|
|
|
|
// Register
|
|
register() {
|
|
|
|
// Set self
|
|
var self = this;
|
|
|
|
// Register service worker
|
|
navigator["serviceWorker"].register(getResource(ServiceWorkerInstaller.FILE_LOCATION), {
|
|
|
|
// Scope
|
|
"scope": ServiceWorkerInstaller.SCOPE
|
|
|
|
// Check if registration was successful
|
|
}).then(function(registration) {
|
|
|
|
// Set service worker to registration
|
|
self.serviceWorker = registration;
|
|
|
|
// Try
|
|
try {
|
|
|
|
// Save last update timestamp in local storage
|
|
localStorage.setItem(ServiceWorkerInstaller.SERVICE_WORKER_LAST_UPDATE_TIMESTAMP_LOCAL_STORAGE_NAME, Common.getCurrentTimestamp().toFixed());
|
|
}
|
|
|
|
// Catch errors
|
|
catch(error) {
|
|
|
|
// Trigger a fatal error
|
|
new FatalError(FatalError.LOCAL_STORAGE_ERROR);
|
|
|
|
// Return
|
|
return;
|
|
}
|
|
|
|
// Get active service worker
|
|
var activeServiceWorker = self.serviceWorker["active"];
|
|
|
|
// Check if there is no existing active service worker
|
|
if(activeServiceWorker === ServiceWorkerInstaller.NO_ACTIVE_SERVICE_WORKER) {
|
|
|
|
// Get installing service worker
|
|
var installingServiceWorker = self.serviceWorker["installing"];
|
|
|
|
// Check if a service worker is installing
|
|
if(installingServiceWorker !== ServiceWorkerInstaller.NO_INSTALLING_SERVICE_WORKER) {
|
|
|
|
// Save initial state change function
|
|
var initialStateChangeFunction = installingServiceWorker["onstatechange"];
|
|
|
|
// Installing service worker state change event
|
|
installingServiceWorker["onstatechange"] = function(event) {
|
|
|
|
// Check if installing service worker's state is activated
|
|
if(event["target"]["state"] === ServiceWorkerInstaller.ACTIVATED_STATE) {
|
|
|
|
// Restore initial state change function
|
|
installingServiceWorker["onstatechange"] = initialStateChangeFunction;
|
|
|
|
// Set installation status to installed
|
|
self.installationStatus = ServiceWorkerInstaller.INSTALLED_STATUS;
|
|
|
|
// Trigger install succeeded event
|
|
$(self).trigger(ServiceWorkerInstaller.INSTALL_SUCCEEDED_EVENT);
|
|
|
|
// Service worker update found event
|
|
self.serviceWorker["onupdatefound"] = function() {
|
|
|
|
// Get installing service worker
|
|
installingServiceWorker = self.serviceWorker["installing"];
|
|
|
|
// Check if a service worker is installing
|
|
if(installingServiceWorker !== ServiceWorkerInstaller.NO_INSTALLING_SERVICE_WORKER) {
|
|
|
|
// Save initial state change function
|
|
initialStateChangeFunction = installingServiceWorker["onstatechange"];
|
|
|
|
// Installing service worker state change event
|
|
installingServiceWorker["onstatechange"] = function(event) {
|
|
|
|
// Check if installing service worker's state is activated
|
|
if(event["target"]["state"] === ServiceWorkerInstaller.ACTIVATED_STATE) {
|
|
|
|
// Restore initial state change function
|
|
installingServiceWorker["onstatechange"] = initialStateChangeFunction;
|
|
|
|
// Trigger update available event
|
|
$(self).trigger(ServiceWorkerInstaller.UPDATE_AVAILABLE_EVENT);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
// Set allow updates
|
|
self.allowUpdates = true;
|
|
}
|
|
|
|
// Otherwise check if service worker's state is redundant
|
|
else if(event["target"]["state"] === ServiceWorkerInstaller.REDUNDANT_STATE) {
|
|
|
|
// Restore initial state change function
|
|
installingServiceWorker["onstatechange"] = initialStateChangeFunction;
|
|
|
|
// Set installation status to failed
|
|
self.installationStatus = ServiceWorkerInstaller.FAILED_STATUS;
|
|
|
|
// Trigger install failed event
|
|
$(self).trigger(ServiceWorkerInstaller.INSTALL_FAILED_EVENT);
|
|
}
|
|
};
|
|
}
|
|
|
|
// Otherwise
|
|
else {
|
|
|
|
// Set installation status to failed
|
|
self.installationStatus = ServiceWorkerInstaller.FAILED_STATUS;
|
|
|
|
// Trigger install failed event
|
|
$(self).trigger(ServiceWorkerInstaller.INSTALL_FAILED_EVENT);
|
|
}
|
|
}
|
|
|
|
// Otherwise
|
|
else {
|
|
|
|
// Service worker message event
|
|
navigator["serviceWorker"]["onmessage"] = function(event) {
|
|
|
|
// Check if active service worker is the current version
|
|
if(event["data"] === self.version.getVersion()) {
|
|
|
|
// Set installation status to installed
|
|
self.installationStatus = ServiceWorkerInstaller.INSTALLED_STATUS;
|
|
|
|
// Trigger install succeeded event
|
|
$(self).trigger(ServiceWorkerInstaller.INSTALL_SUCCEEDED_EVENT);
|
|
|
|
// Service worker update found event
|
|
self.serviceWorker["onupdatefound"] = function() {
|
|
|
|
// Get installing service worker
|
|
installingServiceWorker = self.serviceWorker["installing"];
|
|
|
|
// Check if a service worker is installing
|
|
if(installingServiceWorker !== ServiceWorkerInstaller.NO_INSTALLING_SERVICE_WORKER) {
|
|
|
|
// Save initial state change function
|
|
initialStateChangeFunction = installingServiceWorker["onstatechange"];
|
|
|
|
// Installing service worker state change event
|
|
installingServiceWorker["onstatechange"] = function(event) {
|
|
|
|
// Check if installing service worker's state is activated
|
|
if(event["target"]["state"] === ServiceWorkerInstaller.ACTIVATED_STATE) {
|
|
|
|
// Restore initial state change function
|
|
installingServiceWorker["onstatechange"] = initialStateChangeFunction;
|
|
|
|
// Trigger update available event
|
|
$(self).trigger(ServiceWorkerInstaller.UPDATE_AVAILABLE_EVENT);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
// Set allow updates
|
|
self.allowUpdates = true;
|
|
}
|
|
|
|
// Otherwise
|
|
else {
|
|
|
|
// Service worker update found event
|
|
self.serviceWorker["onupdatefound"] = function() {
|
|
|
|
// Get installing service worker
|
|
var installingServiceWorker = self.serviceWorker["installing"];
|
|
|
|
// Check if a service worker is installing
|
|
if(installingServiceWorker !== ServiceWorkerInstaller.NO_INSTALLING_SERVICE_WORKER) {
|
|
|
|
// Save initial state change function
|
|
var initialStateChangeFunction = installingServiceWorker["onstatechange"];
|
|
|
|
// Installing service worker state change event
|
|
installingServiceWorker["onstatechange"] = function(event) {
|
|
|
|
// Check if installing service worker's state is activated
|
|
if(event["target"]["state"] === ServiceWorkerInstaller.ACTIVATED_STATE) {
|
|
|
|
// Restore initial state change function
|
|
installingServiceWorker["onstatechange"] = initialStateChangeFunction;
|
|
|
|
// Set installation status to installed
|
|
self.installationStatus = ServiceWorkerInstaller.INSTALLED_STATUS;
|
|
|
|
// Trigger install succeeded event
|
|
$(self).trigger(ServiceWorkerInstaller.INSTALL_SUCCEEDED_EVENT);
|
|
|
|
// Service worker update found event
|
|
self.serviceWorker["onupdatefound"] = function() {
|
|
|
|
// Get installing service worker
|
|
installingServiceWorker = self.serviceWorker["installing"];
|
|
|
|
// Check if a service worker is installing
|
|
if(installingServiceWorker !== ServiceWorkerInstaller.NO_INSTALLING_SERVICE_WORKER) {
|
|
|
|
// Save initial state change function
|
|
initialStateChangeFunction = installingServiceWorker["onstatechange"];
|
|
|
|
// Installing service worker state change event
|
|
installingServiceWorker["onstatechange"] = function(event) {
|
|
|
|
// Check if installing service worker's state is activated
|
|
if(event["target"]["state"] === ServiceWorkerInstaller.ACTIVATED_STATE) {
|
|
|
|
// Restore initial state change function
|
|
installingServiceWorker["onstatechange"] = initialStateChangeFunction;
|
|
|
|
// Trigger update available event
|
|
$(self).trigger(ServiceWorkerInstaller.UPDATE_AVAILABLE_EVENT);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
// Set allow updates
|
|
self.allowUpdates = true;
|
|
}
|
|
|
|
// Otherwise check if service worker's state is redundant
|
|
else if(event["target"]["state"] === ServiceWorkerInstaller.REDUNDANT_STATE) {
|
|
|
|
// Restore initial state change function
|
|
installingServiceWorker["onstatechange"] = initialStateChangeFunction;
|
|
|
|
// Set installation status to failed
|
|
self.installationStatus = ServiceWorkerInstaller.FAILED_STATUS;
|
|
|
|
// Trigger install failed event
|
|
$(self).trigger(ServiceWorkerInstaller.INSTALL_FAILED_EVENT);
|
|
}
|
|
};
|
|
}
|
|
|
|
// Otherwise
|
|
else {
|
|
|
|
// Set installation status to failed
|
|
self.installationStatus = ServiceWorkerInstaller.FAILED_STATUS;
|
|
|
|
// Trigger install failed event
|
|
$(self).trigger(ServiceWorkerInstaller.INSTALL_FAILED_EVENT);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
// Request version from active service worker
|
|
activeServiceWorker.postMessage("");
|
|
}
|
|
|
|
// Set interval
|
|
setInterval(function() {
|
|
|
|
// Check for updates
|
|
self.checkForUpdates();
|
|
|
|
}, ServiceWorkerInstaller.CHECK_FOR_UPDATES_INTERVAL_SECONDS * Common.MILLISECONDS_IN_A_SECOND);
|
|
|
|
// Catch errors
|
|
}).catch(function(error) {
|
|
|
|
// Set installation status to failed
|
|
self.installationStatus = ServiceWorkerInstaller.FAILED_STATUS;
|
|
|
|
// Trigger install failed event
|
|
$(self).trigger(ServiceWorkerInstaller.INSTALL_FAILED_EVENT);
|
|
});
|
|
}
|
|
|
|
// Check for updates
|
|
checkForUpdates() {
|
|
|
|
// Get last update timestamp from local storage
|
|
var lastUpdateTimestamp = localStorage.getItem(ServiceWorkerInstaller.SERVICE_WORKER_LAST_UPDATE_TIMESTAMP_LOCAL_STORAGE_NAME);
|
|
|
|
// Check if time to check for an update
|
|
if(lastUpdateTimestamp === Common.INVALID_LOCAL_STORAGE_ITEM || parseInt(lastUpdateTimestamp, Common.DECIMAL_NUMBER_BASE) <= Common.getCurrentTimestamp() - ServiceWorkerInstaller.UPDATE_EXPIRATION_SECONDS) {
|
|
|
|
// Try
|
|
try {
|
|
|
|
// Save last update timestamp in local storage
|
|
localStorage.setItem(ServiceWorkerInstaller.SERVICE_WORKER_LAST_UPDATE_TIMESTAMP_LOCAL_STORAGE_NAME, Common.getCurrentTimestamp().toFixed());
|
|
}
|
|
|
|
// Catch errors
|
|
catch(error) {
|
|
|
|
// Trigger a fatal error
|
|
new FatalError(FatalError.LOCAL_STORAGE_ERROR);
|
|
|
|
// Return
|
|
return;
|
|
}
|
|
|
|
// Check if service worker exists and updates are allowed
|
|
if(this.serviceWorker !== ServiceWorkerInstaller.NO_SERVICE_WORKER && this.allowUpdates === true) {
|
|
|
|
// Update service worker and catch errors
|
|
this.serviceWorker.update().catch(function(error) {
|
|
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// No service worker
|
|
static get NO_SERVICE_WORKER() {
|
|
|
|
// Return no service worker
|
|
return null;
|
|
}
|
|
|
|
// File location
|
|
static get FILE_LOCATION() {
|
|
|
|
// Return file location
|
|
return "./scripts/service_worker.js";
|
|
}
|
|
|
|
// Scope
|
|
static get SCOPE() {
|
|
|
|
// Return scope
|
|
return "./";
|
|
}
|
|
|
|
// Service worker Last update timestamp local storage name
|
|
static get SERVICE_WORKER_LAST_UPDATE_TIMESTAMP_LOCAL_STORAGE_NAME() {
|
|
|
|
// Return service worker last update timestamp local storage name
|
|
return "Service Worker Last Update Timestamp";
|
|
}
|
|
|
|
// Check for updates interval seconds
|
|
static get CHECK_FOR_UPDATES_INTERVAL_SECONDS() {
|
|
|
|
// Return check for updates interval seconds
|
|
return 2 * Common.MINUTES_IN_AN_HOUR * Common.SECONDS_IN_A_MINUTE;
|
|
}
|
|
|
|
// Update expiration seconds
|
|
static get UPDATE_EXPIRATION_SECONDS() {
|
|
|
|
// Return update expiration seconds
|
|
return 1 * Common.HOURS_IN_A_DAY * Common.MINUTES_IN_AN_HOUR * Common.SECONDS_IN_A_MINUTE;
|
|
}
|
|
|
|
// Activated state
|
|
static get ACTIVATED_STATE() {
|
|
|
|
// Return activated state
|
|
return "activated";
|
|
}
|
|
|
|
// Redundant state
|
|
static get REDUNDANT_STATE() {
|
|
|
|
// Return redundant state
|
|
return "redundant";
|
|
}
|
|
|
|
// No active service worker
|
|
static get NO_ACTIVE_SERVICE_WORKER() {
|
|
|
|
// Return no active service worker
|
|
return null;
|
|
}
|
|
|
|
// No installing service worker
|
|
static get NO_INSTALLING_SERVICE_WORKER() {
|
|
|
|
// Return no installing service worker
|
|
return ServiceWorkerInstaller.NO_ACTIVE_SERVICE_WORKER;
|
|
}
|
|
}
|
|
|
|
|
|
// Main function
|
|
|
|
// Set global object's service worker installer
|
|
globalThis["ServiceWorkerInstaller"] = ServiceWorkerInstaller;
|