some updates to page loading performance and general performance.

added a ServiceWorker which caches stuff
This commit is contained in:
2025-10-12 17:36:11 +02:00
parent a7847f6bff
commit ccabb5395c
9 changed files with 483 additions and 100 deletions

View File

@@ -8,6 +8,33 @@ body {
background: #fff;
}
/* Layout foundation: force the page to be full-height and use flex */
html {
height: 100%;
box-sizing: border-box;
}
*, *::before, *::after { box-sizing: inherit; }
body {
min-height: 100vh; /* robust against percentage height issues */
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
}
/* make the main content take remaining space */
main.container {
flex: 1 1 auto; /* grow and shrink as needed */
display: block; /* keep existing layout inside main */
}
/* allow footer to sit at bottom (if content short) */
footer {
margin-top: auto;
}
/* Mobile-specific adjustments */
@media (max-width: 768px) {
body {

3
css/prism.css Normal file
View File

@@ -0,0 +1,3 @@
/* PrismJS 1.30.0
https://prismjs.com/download#themes=prism-tomorrow&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+armasm+arturo+asciidoc+aspnet+asm6502+asmatmel+autohotkey+autoit+avisynth+avro-idl+awk+bash+basic+batch+bbcode+bbj+bicep+birb+bison+bnf+bqn+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+cilkc+cilkcpp+clojure+cmake+cobol+coffeescript+concurnas+csp+cooklang+coq+crystal+css-extras+csv+cue+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gap+gcode+gdscript+gedcom+gettext+gherkin+git+glsl+gn+linker-script+go+go-module+gradle+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+hoon+http+hpkp+hsts+ichigojam+icon+icu-message-format+idris+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keepalived+keyman+kotlin+kumir+kusto+latex+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+magma+makefile+markdown+markup-templating+mata+matlab+maxscript+mel+mermaid+metafont+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+odin+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plant-uml+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+cshtml+jsx+tsx+reason+regex+rego+renpy+rescript+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+stata+iecst+stylus+supercollider+swift+systemd+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+tremor+turtle+twig+typescript+typoscript+unrealscript+uorazor+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+web-idl+wgsl+wiki+wolfram+wren+xeora+xml-doc+xojo+xquery+yaml+yang+zig */
code[class*=language-],pre[class*=language-]{color:#ccc;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}

View File

@@ -1,47 +1,67 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" style="height:100%;margin:0;">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Auto Index</title>
<script src="../../js/shared/theme.js"></script>
<link rel="icon" type="image/x-icon" href="../../css/favicon/favicon.ico">
<link rel="stylesheet" href="../../css/indexer.css">
<!-- Preload + async load -->
<link rel="preload" as="style" href="/css/indexer.css" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/css/indexer.css"></noscript>
<link rel="icon" href="/css/favicon/favicon.ico" type="image/x-icon">
<!-- Defer theme toggle -->
<script src="/js/shared/theme.js" defer></script>
<script>
console.log("javascript is enabled! good!");
document.write('<h1 id="nojs" style="display: flex; align-items: center; cursor: pointer;" onclick="toggleDarkMode();"><img src="../../css/icons/folder.webp" alt="Folder icon" />Index of PyPost</h1>');
document.addEventListener("DOMContentLoaded", () => {
// Create heading dynamically
const h = document.createElement("h1");
h.id = "nojs";
h.innerHTML = '<img src="/css/icons/folder.webp" width="40" height="40" alt="📁" loading="lazy" style="margin-right:8px;">Index of PyPost';
h.onclick = toggleDarkMode;
document.body.prepend(h);
console.log("JavaScript enabled — index enhanced!");
});
</script>
<!-- Register service worker -->
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/js/post/sw.js').catch(console.error);
}
</script>
</head>
<body>
<main style="flex:1;">
<noscript>
<div style="display: inline-flex; align-items: center; flex-wrap: wrap;">
<img src="../../css/icons/script.webp" width="45" height="45" alt="Script icon" style="margin-right: 8px;" />
<h1 id="nojs" style="margin: 0;">Please enable Javascript!</h1>
<div style="display:inline-flex;align-items:center;flex-wrap:wrap;">
<img src="/css/icons/script.webp" width="45" height="45" alt="Script icon" style="margin-right:8px;">
<h1 style="margin:0;">Please enable JavaScript!</h1>
</div>
<p>
<i><strong>If you might be wondering, what does the Script do?</strong></i><br/>
<ul id="nonenormalul">
<li>It strips the .HTML ending from each file you see in the list below</li>
<li>It isn't necessary, but visually tweaks the page.</li>
<li>It enables the "Back" Function for Headers</li>
<li>It enables Searching and Sorting of the Page-Display</li>
<li>It is essential for downloading Markdown-Source</li>
<i><strong>If you might be wondering, what does the Script do?</strong></i><br>
<ul>
<li>Strips the .HTML ending from filenames</li>
<li>Enables search, sorting, and back navigation</li>
<li>Allows Markdown source downloads</li>
</ul>
</p>
</noscript>
<p id="available">
<img src="../../css/icons/available.webp" width="40" height="40" alt="Available icon" />
Available pages:
<p id="available" style="display:flex;align-items:center;gap:8px;">
<img src="/css/icons/available.webp" width="40" height="40" alt="Available" loading="lazy">
<span>Available pages:</span>
</p>
<!-- CONTENT -->
<!-- load scripts needed for indexer -->
<script src="../../js/normal.js"></script>
<script src="../../js/search.js" defer></script>
<script src="../../js/ulorder.js" defer></script>
<!-- Core scripts: async load -->
<script src="/js/normal.js" defer></script>
<script src="/js/search.js" defer></script>
<script src="/js/ulorder.js" defer></script>
</body>
</html>

View File

@@ -1,77 +1,82 @@
<!doctype html>
<html lang="en" style="height:100%; margin:0;">
<html lang="en" style="height:100%;margin:0;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>{{ title }}</title>
<link rel="stylesheet" href="../css/main.css">
<link rel="icon" type="image/x-icon" href="../css/favicon/favicon.ico">
<script src="../js/post/download.js" defer></script>
<!-- Prism.js CSS theme -->
<!--<link rel="preload" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism.min.css" rel="stylesheet" />-->
<!-- Load main stylesheet asynchronously -->
<link rel="preload" as="style" href="/css/main.css" onload="this.rel='stylesheet'">
<link rel="preload" as="style" href="/css/prism.css" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/css/main.css"></noscript>
<!-- Prism.js core + languages -->
<!--
<script rel="preload" src="https://cdn.jsdelivr.net/npm/prismjs/prism.min.js"></script>
<script rel="preload" src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-python.min.js"></script>
<script rel="preload" src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-javascript.min.js"></script>
-->
<link rel="icon" type="image/x-icon" href="/css/favicon/favicon.ico">
<!-- MathJAX for LaTeX Support -->
<!--
<script rel="preload" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" id="MathJax-script"></script>
-->
<!-- Local JS -->
<script src="/js/shared/theme.js"></script>
<script src="/js/post/download.js" defer></script>
<!-- Locally fetch the CDN -->
<link rel="stylesheet" href="/package/css/prism.min.css" />
<script rel="preload" src="/package/js/prism.min.js"></script>
<script rel="preload" src="/package/js/prism-python.min.js"></script>
<script rel="preload" async defer src="/package/js/mathjax.js"></script>
<!-- Prism (code highlighting) -->
<script src="/js/post/prism.js" defer></script>
<!-- remove if causing issues -->
<script src="../js/post/lazyimg.js"></script>
<script src="../js/shared/theme.js"></script>
<style>
a { text-decoration: none; color: #0066cc; }
</style>
<!-- Dynamic MathJax loader -->
<script>
document.addEventListener('DOMContentLoaded', () => {
const hasMath = /\$\$(.|[\r\n])*?\$\$|\$(?!\$)(.*?)\$/.test(document.body.innerHTML);
if (hasMath) {
const mj = document.createElement('script');
mj.src = '/package/js/mathjax.js';
mj.defer = true;
document.head.appendChild(mj);
}
});
</script>
<!-- Service worker registration -->
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/js/post/sw.js').catch(console.error);
}
</script>
</head>
<body style="display:flex; flex-direction:column; min-height:100%; margin:0;">
<main class="container" style="flex:1;">
<h1 onclick="window.location.href=window.location.origin" style="cursor:pointer; display:flex; align-items:center; gap:8px; font-size:1.5em; margin:0;">
<img loading="lazy" src="../css/icons/back.webp" width="32" height="32" alt="⬅" style="display:block;" />
<body>
<main class="container">
<h1 onclick="window.location.href=window.location.origin" style="cursor:pointer;display:flex;align-items:center;gap:8px;font-size:1.5em;margin:0;">
<img src="/css/icons/back.webp" width="32" height="32" alt="⬅" loading="lazy">
{{ title }} <noscript>(Enable JavaScript!)</noscript>
</h1>
<img loading="lazy" src="../css/icons/written.webp" width="32" height="32" alt="📄" loading="lazy" style="vertical-align: middle;padding-left:40px;cursor:pointer;" onclick="toggleDarkMode();" />
<div class="meta" style="display: inline;cursor:pointer;" onclick="toggleDarkMode();">
<img src="/css/icons/written.webp" width="32" height="32" alt="📄" loading="lazy" style="vertical-align:middle;padding-left:40px;cursor:pointer;" onclick="toggleDarkMode();" />
<div class="meta" style="display:inline;cursor:pointer;" onclick="toggleDarkMode();">
Written @{{ now }}
</div>
<hr style="margin:10px 0;" />
<hr style="margin:10px 0;">
<div class="html-content">
{{ html_body | safe }}
</div>
</main>
<footer style="margin-top:auto; width:100%;">
<hr style="margin:10px 0;" />
<img src="../css/icons/date.webp" width="16" height="16" alt="date" loading="lazy" style="vertical-align: middle;" />
{{ timestamp }}<br/>
<footer style="margin-top:auto;width:100%;">
<hr style="margin:10px 0;">
<img src="/css/icons/date.webp" width="16" height="16" alt="date" loading="lazy">
{{ timestamp }}<br>
<img src="../css/icons/magnifier.webp" width="16" height="16" alt="Hash1" loading="lazy" style="display:inline; vertical-align:middle;" />
Hash 1 (<b>UTF-8</b>)<i>:{{ hash1 }}</i><br />
<img src="/css/icons/magnifier.webp" width="16" height="16" alt="Hash1" loading="lazy">
Hash 1 (<b>UTF-8</b>)<i>:{{ hash1 }}</i><br>
<img src="../css/icons/magnifier.webp" width="16" height="16" alt="Hash2" loading="lazy" style="display:inline; vertical-align:middle;" />
Hash 2 (<b>Windows-1252</b>)<i>:{{ hash2 }}</i><br />
<img src="/css/icons/magnifier.webp" width="16" height="16" alt="Hash2" loading="lazy">
Hash 2 (<b>Windows-1252</b>)<i>:{{ hash2 }}</i><br>
<span style="display: inline-flex; align-items: center; gap: 8px;">
<img src="../css/icons/save.webp" width="16" height="16" alt="Save" loading="lazy" />
<a id="download-md">Download as Markdown <noscript>Enable JavaScript for downloads</noscript></a>
<span style="display:inline-flex;align-items:center;gap:8px;">
<img src="/css/icons/save.webp" width="16" height="16" alt="Save" loading="lazy">
<a id="download-md">Download as Markdown</a>
<span style="border-left: 1px solid #888; height: 16px;"></span> <!-- Vertical separator -->
<span style="border-left:1px solid #888;height:16px;"></span>
<img src="../css/icons/script.webp" width="16" height="16" alt="Script" loading="lazy" />
<a id="download-html">Download as HTML <noscript>Enable JavaScript for downloads</noscript></a>
<img src="/css/icons/script.webp" width="16" height="16" alt="Script" loading="lazy">
<a id="download-html">Download as HTML</a>
</span>
</footer>
</body>
</html>

300
js/post/prism.js Normal file

File diff suppressed because one or more lines are too long

32
js/post/sw.js Normal file
View File

@@ -0,0 +1,32 @@
const CACHE_NAME = 'offline-v1';
const ASSETS = [
'/css/main.css',
'/js/shared/theme.js',
'/js/post/download.js',
'/js/post/lazyimg.js',
'/package/js/prism.min.js',
'/package/js/prism-python.min.js',
'/package/js/mathjax.js',
'/css/icons/back.webp',
'/css/icons/written.webp',
'/css/icons/date.webp',
'/css/icons/magnifier.webp',
'/css/icons/save.webp',
'/css/icons/script.webp'
];
self.addEventListener('install', e => {
e.waitUntil(caches.open(CACHE_NAME).then(c => c.addAll(ASSETS)));
});
self.addEventListener('fetch', e => {
e.respondWith(
caches.match(e.request).then(res => res || fetch(e.request).then(resp => {
if (e.request.url.startsWith(self.location.origin)) {
const copy = resp.clone();
caches.open(CACHE_NAME).then(c => c.put(e.request, copy));
}
return resp;
}))
);
});

View File

@@ -193,8 +193,3 @@ Der Punkt wurde damit um die x-Achse um 45° gedreht.
* Durch **Multiplikation** kann man mehrere Drehungen kombinieren.
* Die Reihenfolge der Rotationen ist **nicht vertauschbar**.
* Bei $45^\circ$ erscheinen häufig die Werte $\frac{\sqrt{2}}{2}$ und $\frac{1}{2}$.
```python
def hello() -> str:
return "Hello"
```

Binary file not shown.

View File

@@ -29,6 +29,7 @@ CACHE_DIR = os.path.join(PROJECT_ROOT, "cache")
CDN_CACHE_DIR = os.path.join(CACHE_DIR, "cdn")
# CDN Resources to fetch and cache
# If you modify the HTML Template to use any CDN include it here
CDN_RESOURCES = {
"/package/css/prism.min.css": "https://cdn.jsdelivr.net/npm/prismjs/themes/prism.min.css",
"/package/js/prism.min.js": "https://cdn.jsdelivr.net/npm/prismjs/prism.min.js",