blog3000/Blog3000/Client/wwwroot/index.html

254 lines
9.4 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>blog3000 powered blog</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/site.css" rel="stylesheet" />
<link href="css/github-stylesheet.css" rel="stylesheet" />
<link href="manifest.json" rel="manifest" />
</head>
<body>
<app>Loading page (blazor-app, modern browser required for this to work)...</app>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script>navigator.serviceWorker.register('service-worker.js');</script>
<script>
window.Network = {
Init: function (interop) {
function handler() {
interop.invokeMethodAsync("Network.StatusChanged", navigator.onLine);
}
window.addEventListener('online', handler);
window.addEventListener('offline', handler);
if (!navigator.onLine) {
handler(navigator.onLine);
}
}
};
class MyCacheStorage {
// TODO: Improve SetException, pass object instead of string?
static async Create(cbObject, cacheId) {
try {
let i = new MyCacheStorage();
i.cacheId = cacheId;
i.myCache = await caches.open(cacheId);
window[cacheId] = i;
if (!await caches.has(cacheId)) {
//Should not occurr on a healthy system, was probably a red herring during debugging
/*
console.warn("Cache NOT " + cacheId + " created, retry in 1000ms");
setTimeout(() => {
caches.open(cacheId).then((c) => {
caches.has(cacheId).then((b) => {
if (!b) {
console.warn("Cache NOT " + cacheId + "created, giving up");
cbObject.invokeMethodAsync("SetResult", false);
}
else {
console.log("Cache: " + cacheId + " created");
cbObject.invokeMethodAsync("SetResult", true);
}
})
});
}, 1000);*/
console.log("Cache" + cacheId + " NOT created");
cbObject.invokeMethodAsync("SetResult", false);
}
else {
console.log("Cache: " + cacheId + " created");
cbObject.invokeMethodAsync("SetResult", true);
}
}
catch (e) {
console.warn(e);
cbObject.invokeMethodAsync("SetException", "" + e);
}
}
async CheckCache() {
if (!await caches.has(this.cacheId)) {
// Should only occur on cache reset e.g. during debugging!
console.log("Cache" + this.cacheId + " NOT found, reopening");
this.myCache = await caches.open(this.cacheId);
if (!await caches.has(this.cacheId)) {
console.log("Cache " + this.cacheId + " still NOT found, failing");
throw new ("Cache " + this.cacheId + " not openable/creatable");
}
}
}
async Add(cbObject, url) {
try {
await this.CheckCache();
await this.myCache.add(url);
//console.log("my-cache added to", url);
cbObject.invokeMethodAsync("SetResult", true);
}
catch (e) {
console.warn(e);
cbObject.invokeMethodAsync("SetException", "" + e);
}
}
async AddAll(cbObject, urls) {
try {
if (typeof (urls) === "string") urls = [urls];
await this.CheckCache();
await this.myCache.addAll(urls);
//console.log("my-cache added all to", urls);
cbObject.invokeMethodAsync("SetResult", true);
}
catch (e) {
console.warn(e, urls);
cbObject.invokeMethodAsync("SetException", "" + e);
}
}
async Delete(cbObject, url) {
try {
await this.CheckCache();
await this.myCache.delete(url);
//console.log("my-cache added to");
cbObject.invokeMethodAsync("SetResult", true);
}
catch (e) {
console.warn(e);
cbObject.invokeMethodAsync("SetException", "" + e);
}
}
async MatchAll(cbObject, filter) {
try {
// filter does not do contains-match, uri in cache
// includes host-part etc, therefore built in filtering can't be used
await this.CheckCache();
var responses = await this.myCache.matchAll(/*filter*/);
var matches = [];
responses.forEach(function (element, index, array) {
if (element.url.includes(filter)) {
matches.push(element.url);
}
});
//console.log(filter, matches);
cbObject.invokeMethodAsync("SetResult", matches);
}
catch (e) {
console.warn(e);
cbObject.invokeMethodAsync("SetException", "" + e);
}
}
/**
* check if all given "filters" are in cache
* @param cbObject
* @param filters
*/
async AreCached(cbObject, filters) {
try {
if (typeof (filters) === "string") filters = [filters];
// filter does not do contains-match, uri in cache
// includes host-part etc, therefore built in filtering can't be used
let res = true;
await this.CheckCache();
var responses = await this.myCache.matchAll(/*filter*/);
if (responses && filters) {
let match = null;
filters.forEach(f => {
responses.forEach(function (element, index, array) {
if (element.url.includes(f)) {
match = element.url;
return;
}
});
if (!match) {
res = false;
return;
}
});
}
console.log(filters, res);
cbObject.invokeMethodAsync("SetResult", res);
}
catch (e) {
console.warn(e);
cbObject.invokeMethodAsync("SetException", "" + e);
}
}
}
window.MyCacheStorage = MyCacheStorage;
</script>
<script>
/**
*
* @param uri
* @param name optional, only works for same-origin attributes, otherwise server will override
*/
window.downloadURI = function (uri, name) {
console.log("Preparing download of " + uri);
setTimeout(() => {
var link = document.createElement("a");
// If you don't know the name or want to use
// the webserver default set name = ''
if (name) {
link.setAttribute('download', name);
}
link.href = uri;
document.body.appendChild(link);
link.click();
link.remove();
}, 1000);
}
window.scrollElmIntoView = function (element) {
//console.log("YY", element);
if (element) {
var rect = element.getBoundingClientRect();
// Scroll only when not in view!
if (!(
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
)) element.scrollIntoView();
}
}
window.setTitle = function(txt) {
document.title = txt;
}
</script>
</body>
</html>