Add more robust styling
Signed-off-by: Jacob Kiers <jacob@jacobkiers.net>
This commit is contained in:
7
public/equilibrium-light.min.css
vendored
Normal file
7
public/equilibrium-light.min.css
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
Theme: Equilibrium Light
|
||||
Author: Carlo Abelli
|
||||
License: ~ MIT (or more permissive) [via base16-schemes-source]
|
||||
Maintainer: @highlightjs/core-team
|
||||
Version: 2021.05.0
|
||||
*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#43474e;background:#f5f0e7}.hljs ::selection{color:#d8d4cb}.hljs-comment{color:#73777f}.hljs-tag{color:#5a5f66}.hljs-operator,.hljs-punctuation,.hljs-subst{color:#43474e}.hljs-operator{opacity:.7}.hljs-bullet,.hljs-deletion,.hljs-name,.hljs-selector-tag,.hljs-template-variable,.hljs-variable{color:#d02023}.hljs-attr,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol,.hljs-variable.constant_{color:#bf3e05}.hljs-class .hljs-title,.hljs-title,.hljs-title.class_{color:#9d6f00}.hljs-strong{font-weight:700;color:#9d6f00}.hljs-addition,.hljs-code,.hljs-string,.hljs-title.class_.inherited__{color:#637200}.hljs-built_in,.hljs-doctag,.hljs-keyword.hljs-atrule,.hljs-quote,.hljs-regexp{color:#007a72}.hljs-attribute,.hljs-function .hljs-title,.hljs-section,.hljs-title.function_,.ruby .hljs-property{color:#0073b5}.diff .hljs-meta,.hljs-keyword,.hljs-template-tag,.hljs-type{color:#4e66b6}.hljs-emphasis{color:#4e66b6;font-style:italic}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#c42775}.hljs-meta .hljs-keyword,.hljs-meta-keyword{font-weight:700}
|
1131
public/highlight.min.js
vendored
Normal file
1131
public/highlight.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
173
public/index.html
Normal file
173
public/index.html
Normal file
@@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Blog over DNS</title>
|
||||
<link rel="stylesheet" href="equilibrium-light.min.css">
|
||||
<script src="highlight.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<script>
|
||||
class Content {
|
||||
content = "";
|
||||
type = "";
|
||||
metaData = {};
|
||||
index;
|
||||
|
||||
/***
|
||||
* @param content string
|
||||
* @param type string
|
||||
* @param index Index
|
||||
*/
|
||||
constructor(content, type, index)
|
||||
{
|
||||
this.content = content;
|
||||
this.type = type;
|
||||
this.index = index;
|
||||
this.metaData = index.metaData;
|
||||
}
|
||||
}
|
||||
|
||||
class Index
|
||||
{
|
||||
mimeType = "";
|
||||
chunks = 0;
|
||||
hashAlgorithm = "";
|
||||
hash = "";
|
||||
metaData = {};
|
||||
|
||||
constructor(mimeType, chunks, hash, hashAlgorithm, metaData = {})
|
||||
{
|
||||
this.mimeType = mimeType;
|
||||
this.chunks = chunks;
|
||||
this.hashAlgorithm = hashAlgorithm;
|
||||
this.hash = hash;
|
||||
this.metaData = metaData
|
||||
}
|
||||
}
|
||||
|
||||
const dohServer = "https://cloudflare-dns.com/dns-query?ct=application/dns-json&type=TXT&name=";
|
||||
const baseDomain = "hod.experiments.jacobkiers.net";
|
||||
|
||||
async function readUrl(domain) {
|
||||
var index = await fetchIndex(`${domain}.${baseDomain}`);
|
||||
|
||||
var chunk_promises = [];
|
||||
for(i = 0; i < index.chunks; i++)
|
||||
{
|
||||
chunk_promises[i] = fetchChunk(i, index.hash);
|
||||
}
|
||||
|
||||
const chunks = await Promise.all(chunk_promises);
|
||||
const base64 = chunks.reduce((built, current) => built += current);
|
||||
|
||||
const content = atob(base64);
|
||||
return handleContent(new Content(content, index.mimeType, index));
|
||||
}
|
||||
|
||||
async function fetchChunk(id, hash)
|
||||
{
|
||||
const domain = `${id}.${hash}.${baseDomain}`;
|
||||
return await fetchData(domain);
|
||||
}
|
||||
|
||||
async function fetchData(domain)
|
||||
{
|
||||
const json = await fetch(`${dohServer}${domain}`)
|
||||
.then(response => response.json());
|
||||
const raw_data = json.Answer[0].data;
|
||||
const data = raw_data.replaceAll(/[\s\"]/g, '');
|
||||
return data;
|
||||
}
|
||||
|
||||
async function fetchIndex(domain)
|
||||
{
|
||||
const index = await fetchData(domain);
|
||||
|
||||
let ret = {};
|
||||
let items = index.split(';');
|
||||
items.forEach(item => {
|
||||
let md = item.split('=');
|
||||
let key = md[0];
|
||||
let value = md[1];
|
||||
|
||||
ret[key] = value;
|
||||
});
|
||||
|
||||
const metadata = JSON.parse(atob(ret["m"]));
|
||||
return new Index(ret["t"], ret["c"], ret["h"], ret["ha"], metadata);
|
||||
}
|
||||
|
||||
function handleContent(content)
|
||||
{
|
||||
if (!content instanceof Content) {
|
||||
console.log("Not valid content in handleContent.")
|
||||
return;
|
||||
}
|
||||
|
||||
switch(content.type)
|
||||
{
|
||||
case "text/javascript":
|
||||
return handleJavascript(content);
|
||||
|
||||
case "text/markdown":
|
||||
return handleMarkdown(content);
|
||||
|
||||
default:
|
||||
console.log(`handleContent() does not know how to parse ${content.type}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function handleJavascript(content)
|
||||
{
|
||||
console.log("Got some javascript!");
|
||||
const scripts = document.getElementById("scripts");
|
||||
const new_script = document.createElement("script");
|
||||
new_script.text = content.content;
|
||||
|
||||
scripts.appendChild(new_script);
|
||||
}
|
||||
|
||||
async function handleMarkdown(content)
|
||||
{
|
||||
console.log("Got me some markdown!");
|
||||
marked.setOptions({
|
||||
highlight: function(code, lang) {
|
||||
const avialable_languages = hljs.listLanguages();
|
||||
const has_language = hljs.getLanguage(lang);
|
||||
if (typeof has_language === "undefined") return code;
|
||||
const result = hljs.highlight(code, { language: lang, ignoreIllegals: true});
|
||||
return result.value;
|
||||
},
|
||||
});
|
||||
|
||||
if (typeof content.metaData.title !== "undefined") document.title = content.metaData.title;
|
||||
document.getElementById("post").innerHTML = marked(content.content);
|
||||
let title = document.createElement("h1");
|
||||
title.innerHTML = content.metaData.title;
|
||||
document.getElementById("post").prepend(title)
|
||||
document.getElementById("nojs").remove();
|
||||
|
||||
if (typeof Verifier !== "undefined") {
|
||||
await (new Verifier()).verify(content);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="post"></div>
|
||||
<div id="verification"></div>
|
||||
<div id="nojs">
|
||||
<h1>HTML over DNS</h1>
|
||||
<p>The content of this page is fetched using DNS over HTTP. Since that requires Javascript, please enable that to see the content.</p>
|
||||
</div>
|
||||
<div id="scripts">
|
||||
<script>
|
||||
readUrl("scripts-verifier-js").then(
|
||||
() => readUrl("posts-2021-08-17-serving-blog-content-over-dns-md")
|
||||
);
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
Reference in New Issue
Block a user