mirror of
https://codeberg.org/vlw/victorwesterlund.com.git
synced 2025-09-14 11:33:41 +02:00
dev21w34a
This commit is contained in:
parent
6645f2b672
commit
49496c9bdc
6 changed files with 191 additions and 344 deletions
|
@ -1 +0,0 @@
|
||||||
www.victorwesterlund.com
|
|
|
@ -1,17 +0,0 @@
|
||||||
@font-face {
|
|
||||||
font-family: "Roboto Mono";
|
|
||||||
font-weight: 400;
|
|
||||||
src: local("Roboto Mono Regular"),
|
|
||||||
local("RobotoMono-Regular"),
|
|
||||||
url("../fonts/RobotoMono-Regular.woff2"),
|
|
||||||
url("../fonts/RobotoMono-Regular.ttf");
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Roboto Mono";
|
|
||||||
font-weight: 700;
|
|
||||||
src: local("Roboto Mono Bold"),
|
|
||||||
local("RobotoMono-Bold"),
|
|
||||||
url("../fonts/RobotoMono-Bold.woff2"),
|
|
||||||
url("../fonts/RobotoMono-Bold.ttf");
|
|
||||||
}
|
|
|
@ -1,15 +1,43 @@
|
||||||
@import url("fonts.css");
|
/* Copyright © Victor Westerlund - No libraries! 😲 */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--comp-background: 255,255,255;
|
--comp-background: 255,255,255;
|
||||||
--comp-highlight: 244,242,255;
|
--comp-contrast: 33,33,33;
|
||||||
--comp-accent: 33,33,33;
|
--comp-accent: 22,183,255;
|
||||||
|
|
||||||
--color-background: rgb(var(--comp-background));
|
--color-background: rgb(var(--comp-background));
|
||||||
--color-highlight: rgb(var(--comp-highlight));
|
--color-contrast: rgb(var(--comp-contrast));
|
||||||
--color-accent: rgb(var(--comp-accent));
|
--color-accent: rgb(var(--comp-accent));
|
||||||
|
|
||||||
--page-padding: 5vw;
|
--padding: 20px;
|
||||||
|
--border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--comp-background: 33,33,33;
|
||||||
|
--comp-contrast: 255,255,255;
|
||||||
|
--comp-accent: 255,255,255;
|
||||||
|
|
||||||
|
--color-background: rgb(var(--comp-background));
|
||||||
|
--color-contrast: rgb(var(--comp-contrast));
|
||||||
|
--color-accent: rgb(var(--comp-accent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Roboto Mono";
|
||||||
|
font-weight: 400;
|
||||||
|
src: local("Roboto Mono Regular"),
|
||||||
|
local("RobotoMono-Regular"),
|
||||||
|
url("../fonts/RobotoMono-Regular.woff2"),
|
||||||
|
url("../fonts/RobotoMono-Regular.ttf");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Roboto Mono";
|
||||||
|
font-weight: 700;
|
||||||
|
src: local("Roboto Mono Bold"),
|
||||||
|
local("RobotoMono-Bold"),
|
||||||
|
url("../fonts/RobotoMono-Bold.woff2"),
|
||||||
|
url("../fonts/RobotoMono-Bold.ttf");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Cornerstones -- */
|
/* -- Cornerstones -- */
|
||||||
|
@ -17,7 +45,7 @@
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: "Roboto Mono","Arial",sans-serif;
|
font-family: "Roboto Mono","Arial",sans-serif;
|
||||||
color: var(--color-accent);
|
color: var(--color-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
*::selection {
|
*::selection {
|
||||||
|
@ -26,17 +54,51 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body,
|
body {
|
||||||
main,
|
|
||||||
main > div {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
width: 200vw;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
main.active {
|
||||||
|
transform: translateX(-100vw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- */
|
||||||
|
|
||||||
|
.screen {
|
||||||
|
width: 100vw;
|
||||||
|
background-color: var(--color-background);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen .content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: calc(var(--padding) * 1.5);
|
||||||
|
padding-top: 0;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- Positioning -- */
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- */
|
/* ---- */
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
--size: 5em;
|
--size: 1em;
|
||||||
--skew: calc(var(--size) / 1.7);
|
--skew: calc(var(--size) / 1.7);
|
||||||
|
|
||||||
width: 0;
|
width: 0;
|
||||||
|
@ -51,192 +113,100 @@ main > div {
|
||||||
border-top: var(--size) solid rgba(var(--comp-accent),.3);
|
border-top: var(--size) solid rgba(var(--comp-accent),.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 1.42em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 span {
|
|
||||||
color: var(--color-background);
|
|
||||||
background-color: var(--color-accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Layout -- */
|
|
||||||
|
|
||||||
main {
|
|
||||||
--grid-spacing: 3vh;
|
|
||||||
|
|
||||||
margin: auto;
|
|
||||||
max-width: 200vh;
|
|
||||||
background: radial-gradient(circle, rgba(var(--comp-accent),.2) .1vh, var(--color-background) .1vh),url("../img/pattern.gif");
|
|
||||||
background-size: var(--grid-spacing) var(--grid-spacing),auto 90%;
|
|
||||||
background-position: 100% 100%;
|
|
||||||
background-repeat: repeat,no-repeat;
|
|
||||||
background-blend-mode: multiply;
|
|
||||||
image-rendering: pixelated;
|
|
||||||
image-rendering: -moz-crisp-edges;
|
|
||||||
}
|
|
||||||
|
|
||||||
main * {
|
|
||||||
image-rendering: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
main > div {
|
|
||||||
position: absolute;
|
|
||||||
width: 50%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- */
|
/* ---- */
|
||||||
|
|
||||||
#intro {
|
.button {
|
||||||
left: 0;
|
background-color: var(--color-contrast);
|
||||||
width: 100vh;
|
text-align: center;
|
||||||
|
padding: 25px;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button svg {
|
||||||
|
pointer-events: none;
|
||||||
|
fill: var(--color-contrast);
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button p {
|
||||||
|
pointer-events: none;
|
||||||
|
font-size: clamp(16px,5vw,22px);
|
||||||
|
color: var(--color-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.phantom {
|
||||||
|
background-color: rgba(var(--comp-contrast),.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.phantom p {
|
||||||
|
color: var(--color-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- Screens -- */
|
||||||
|
|
||||||
|
header {
|
||||||
|
--size: 100px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: var(--page-padding);
|
padding: var(--padding);
|
||||||
|
height: var(--size);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
z-index: 1;
|
gap: var(--padding);
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
#intro .inner {
|
header .hamburger {
|
||||||
display: flex;
|
width: calc(var(--size) - (var(--padding) * 2));
|
||||||
height: 100%;
|
height: calc(var(--size) - (var(--padding) * 2));
|
||||||
flex-direction: column;
|
box-sizing: border-box;
|
||||||
justify-content: space-between;
|
flex-shrink: 0;
|
||||||
|
padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#intro .logo {
|
header .hamburger div {
|
||||||
--size: 7vh;
|
|
||||||
margin-bottom: calc(var(--page-padding) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#intro .block {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 3vh;
|
height: 2px;
|
||||||
|
background: var(--color-contrast);
|
||||||
|
box-shadow: 0 -10px 0 0 var(--color-contrast), 0 10px 0 0 var(--color-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
#intro .block:last-child {
|
header .hamburger svg {
|
||||||
display: flex;
|
fill: none;
|
||||||
align-items: flex-end;
|
stroke: var(--color-contrast);
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-width: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#intro .block p {
|
header .spacer {
|
||||||
font-size: .7em;
|
width: 1px;
|
||||||
margin-bottom: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#intro .block p span {
|
|
||||||
margin-right: .9em;
|
|
||||||
background-color: var(--color-background);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- */
|
|
||||||
|
|
||||||
nav a {
|
|
||||||
text-decoration: none;
|
|
||||||
margin-right: 2em;
|
|
||||||
font-size: .9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav a::after {
|
|
||||||
content: "→";
|
|
||||||
padding-left: .5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- */
|
|
||||||
|
|
||||||
#myface {
|
|
||||||
right: 0;
|
|
||||||
width: 50%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#myface picture,
|
|
||||||
#myface img {
|
|
||||||
position: absolute;
|
|
||||||
height: 80%;
|
height: 80%;
|
||||||
bottom: 0;
|
background-color: rgba(var(--comp-contrast),.2);
|
||||||
pointer-events: none;
|
}
|
||||||
|
|
||||||
|
.dark header .spacer {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .logo {
|
||||||
|
--size: 25px;
|
||||||
|
margin-top: calc(var(--size) / 2);
|
||||||
|
margin-right: calc(var(--size) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- Screen > Landingpage -- */
|
||||||
|
|
||||||
|
/* -- Screen > Menu -- */
|
||||||
|
|
||||||
|
.screen.menu .content {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#myface img {
|
.screen.menu .button[data="contact"] {
|
||||||
height: 100%;
|
margin-top: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Size Queries -- */
|
|
||||||
|
|
||||||
@media (max-width: 1100px) {
|
|
||||||
:root {
|
|
||||||
--page-padding: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 7vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 5vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- */
|
|
||||||
|
|
||||||
main {
|
|
||||||
max-width: unset;
|
|
||||||
background-position: 100% 0;
|
|
||||||
background-size: var(--grid-spacing) var(--grid-spacing), auto 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- */
|
|
||||||
|
|
||||||
#intro {
|
|
||||||
width: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
#intro .logo {
|
|
||||||
--size: 10vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
#intro p {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
#intro .block p:last-of-type {
|
|
||||||
text-align: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
#myface {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- */
|
|
||||||
|
|
||||||
nav a {
|
|
||||||
text-decoration: none;
|
|
||||||
margin-right: 5vw;
|
|
||||||
font-size: 5vw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Accessibility -- */
|
|
||||||
|
|
||||||
@media (hover: hover) {
|
|
||||||
nav a:hover {
|
|
||||||
background: var(--color-highlight);
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
--comp-background: 0,0,0;
|
|
||||||
--comp-accent: 255,255,255;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +1,12 @@
|
||||||
// Register SW if supported by browser
|
function toggleMenu() {
|
||||||
if(navigator.serviceWorker) {
|
const speed = 200;
|
||||||
navigator.serviceWorker.register("sw.js",{
|
const menu = document.getElementsByTagName("main")[0];
|
||||||
scope: "/"
|
|
||||||
});
|
menu.style.setProperty("transition",`${speed}ms`);
|
||||||
|
menu.classList.toggle("active");
|
||||||
|
setTimeout(() => menu.style.removeProperty("transition"),speed + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const theme = window.matchMedia("(prefers-color-scheme: dark)");
|
for(const element of document.getElementsByClassName("hamburger")) {
|
||||||
|
element.addEventListener("click",() => toggleMenu());
|
||||||
// Set theme color
|
}
|
||||||
function updateTheme() {
|
|
||||||
// Get theme color from stylesheet
|
|
||||||
const color = window.getComputedStyle(document.body).getPropertyValue("--color-background");
|
|
||||||
document.querySelector("meta[name='theme-color']").setAttribute("content",color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set theme color and listen for changes
|
|
||||||
theme.addEventListener("change",updateTheme);
|
|
||||||
updateTheme(theme);
|
|
|
@ -1,4 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
<!-- Copyright © Victor Westerlund - No libraries! 😲 -->
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
@ -11,34 +12,37 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<div id="intro">
|
<div class="screen landingpage">
|
||||||
<div class="inner">
|
<header>
|
||||||
<div class="block">
|
<div class="hamburger center">
|
||||||
<div class="logo"></div>
|
<div></div>
|
||||||
<h1><span>victor westerlund</span></h1>
|
|
||||||
<h2><span>full-stack web developer</span></h2>
|
|
||||||
</div>
|
|
||||||
<div class="block">
|
|
||||||
<p><span>I create things with code. The things I've created for the public reside as open-source repositories on <a href="https://github.com/VictorWesterlund" ping="https://api.victorwesterlund/log/ping/" target="_blank">GitHub</a>, the rest you'll be lucky to hear about some day.</span></p>
|
|
||||||
<p><span>Other topics (seemingly irrelevant to programming) I find facinating include but is in no way limited to astronomy, psychology, sociology, economics, ...</span></p>
|
|
||||||
<p><span><strong>hello@victorwesterlund.com</strong></span>​(<a href="https://storage.googleapis.com/public.victorwesterlund.com/publickey.gpg" ping="https://api.victorwesterlund/log/ping/" target="_blank">PGP Key</a>)</p>
|
|
||||||
</div>
|
|
||||||
<div class="block">
|
|
||||||
<nav>
|
|
||||||
<!--<a href="#">contact</a>-->
|
|
||||||
<a href="https://github.com/VictorWesterlund" ping="https://api.victorwesterlund/log/ping/" target="_blank">github</a>
|
|
||||||
</nav>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="spacer"></div>
|
||||||
|
<div class="logo"></div>
|
||||||
|
<p>victor westerlund</p>
|
||||||
|
</header>
|
||||||
|
<div class="content">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="myface">
|
<div class="screen menu dark">
|
||||||
<picture>
|
<header>
|
||||||
<source srcset="assets/img/myface/highres.avif" type="image/avif" media="(min-width: 1920px)">
|
<div class="hamburger center">
|
||||||
<source srcset="assets/img/myface/highres.webp" type="image/webp" media="(min-width: 1920px)">
|
<svg xmlns="http://www.w3.org/2000/svg" width="28.548" height="22.828"><path d="M2.28 11.414h25.269M1.414 11.414l10-10M1.414 11.414l10 10"/></svg>
|
||||||
<source srcset="assets/img/myface/mediumres.avif" type="image/avif">
|
</div>
|
||||||
<source srcset="assets/img/myface/mediumres.webp" type="image/webp">
|
<div class="spacer"></div>
|
||||||
<img src="assets/img/myface/mediumres.png" type="image/png">
|
<div class="logo"></div>
|
||||||
</picture>
|
<p>victor westerlund</p>
|
||||||
|
</header>
|
||||||
|
<div class="content">
|
||||||
|
<div class="button phantom">
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
|
||||||
|
<p>contact me</p>
|
||||||
|
</div>
|
||||||
|
<div class="spacer"></div>
|
||||||
|
<div class="button phantom" data="contact">
|
||||||
|
<p>contact me</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<script src="assets/js/script.js" type="module"></script>
|
<script src="assets/js/script.js" type="module"></script>
|
||||||
|
|
102
public/sw.js
102
public/sw.js
|
@ -1,102 +0,0 @@
|
||||||
const version = "1628250171";
|
|
||||||
const root = "/";
|
|
||||||
|
|
||||||
let activeCaches = [
|
|
||||||
`content-${version}`
|
|
||||||
];
|
|
||||||
|
|
||||||
let cacheManifest = [
|
|
||||||
"index.html",
|
|
||||||
"assets/css/style.css",
|
|
||||||
"assets/css/fonts.css",
|
|
||||||
"assets/img/favicon.png",
|
|
||||||
"assets/img/pattern.gif",
|
|
||||||
"assets/fonts/RobotoMono-Bold.woff2",
|
|
||||||
"assets/fonts/RobotoMono-Regular.woff2",
|
|
||||||
"assets/js/script.js"
|
|
||||||
];
|
|
||||||
|
|
||||||
// Download assets and install ServiceWorker
|
|
||||||
self.addEventListener("install", event => {
|
|
||||||
event.waitUntil(
|
|
||||||
caches.open(`content-${version}`).then(cache => cache.addAll(cacheManifest.map(asset => {
|
|
||||||
// Append the root path to all assets
|
|
||||||
return root + asset;
|
|
||||||
})))
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wipe old assets from Cache Storage
|
|
||||||
self.addEventListener("activate", event => {
|
|
||||||
event.waitUntil(
|
|
||||||
// Delete inactive caches
|
|
||||||
caches.keys().then(cacheNames => {
|
|
||||||
return Promise.all(
|
|
||||||
cacheNames.map(cacheName => {
|
|
||||||
if(!activeCaches.includes(cacheName)) {
|
|
||||||
return caches.delete(cacheName);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fetch and cache an asset not defined in the manifest
|
|
||||||
async function fetchToCache(event) {
|
|
||||||
const networkFetch = fetch(event.request);
|
|
||||||
|
|
||||||
event.waitUntil(
|
|
||||||
networkFetch.then(response => {
|
|
||||||
const responseClone = response.clone();
|
|
||||||
caches.open("bucket").then(cache => cache.put(event.request, responseClone));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const response = await caches.match(event.request);
|
|
||||||
return response || networkFetch;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch and follow redirects without caching
|
|
||||||
async function fetchContent(url,i = 0) {
|
|
||||||
if(i >= 5) {
|
|
||||||
throw new Error("ERR_TOO_MANY_REDIRECTS");
|
|
||||||
}
|
|
||||||
|
|
||||||
return await fetch(url).then(response => {
|
|
||||||
if(response.redirected) {
|
|
||||||
i++;
|
|
||||||
return fetchContent(response.url,i);
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.addEventListener("fetch", event => {
|
|
||||||
const url = new URL(event.request.url);
|
|
||||||
const origin = (url.origin == location.origin) ? true : false; // Is same-origin
|
|
||||||
|
|
||||||
// Speed up TTFB by serving index file first
|
|
||||||
if(origin && url.pathname == "/") {
|
|
||||||
event.respondWith(caches.match(root + "index.html"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch cross-origin content using the network
|
|
||||||
if(!origin || (url.pathname.substring(1,7) != "assets")) {
|
|
||||||
event.respondWith(fetchContent(url.href));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get pattern.gif from generator. Fallback to cache on failure
|
|
||||||
if(origin && url.pathname.endsWith("pattern.gif")) {
|
|
||||||
const pattern = new Request(`${location.origin}${root}assets/img/pattern.php`);
|
|
||||||
event.respondWith(fetch(pattern).catch(() => caches.match(root + "assets/img/pattern.gif")));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Respond with content from cache or fetch and save
|
|
||||||
event.respondWith(
|
|
||||||
caches.match(event.request).then(response => response || fetchToCache(event))
|
|
||||||
);
|
|
||||||
});
|
|
Loading…
Add table
Reference in a new issue