~prokop/rdck.dev

af4bdda8fd13d09c73ca702185c07e4ca326c25c — Prokop Randacek 1 year, 6 months ago c2aa306
lebka propaganda 1
M .gitignore => .gitignore +4 -4
@@ 1,4 1,4 @@
www
funlist.html
navbar.html
postlist.html
/www/
/funlist.html
/navbar.html
/postlist.html

A assets/posts/apple_firefox_meme.webp => assets/posts/apple_firefox_meme.webp +0 -0
A assets/rss.svg => assets/rss.svg +18 -0
@@ 0,0 1,18 @@
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<defs>
<linearGradient x1="0.085" y1="0.085" x2="0.915" y2="0.915" id="RSSg">
<stop offset="0.0" stop-color="#E3702D"/><stop offset="0.1071" stop-color="#EA7D31"/>
<stop offset="0.3503" stop-color="#F69537"/><stop offset="0.5" stop-color="#FB9E3A"/>
<stop offset="0.7016" stop-color="#EA7C31"/><stop offset="0.8866" stop-color="#DE642B"/>
<stop offset="1.0" stop-color="#D95B29"/>
</linearGradient>
</defs>
<rect width="256" height="256" rx="55" ry="55" x="0"  y="0"  fill="#CC5D15"/>
<rect width="246" height="246" rx="50" ry="50" x="5"  y="5"  fill="#F49C52"/>
<rect width="236" height="236" rx="47" ry="47" x="10" y="10" fill="url(#RSSg)"/>
<circle cx="68" cy="189" r="24" fill="#FFF"/>
<path d="M160 213h-34a82 82 0 0 0 -82 -82v-34a116 116 0 0 1 116 116z" fill="#FFF"/>
<path d="M184 213A140 140 0 0 0 44 73 V 38a175 175 0 0 1 175 175z" fill="#FFF"/>
</svg>

A assets/srht.svg => assets/srht.svg +5 -0
@@ 0,0 1,5 @@
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200z"/>
</svg>

M assets/styles.css => assets/styles.css +4 -0
@@ 97,6 97,10 @@ footer {
	font-size: 0.5em;
}

footer a img {
	height: 1em;
}

blockquote {
	background: #f9f9f9;
	border-left: 7px solid #ccc;

M build => build +26 -17
@@ 1,5 1,7 @@
#!/bin/sh

set -e

OUT_DIR=www

rm -rf $OUT_DIR


@@ 7,10 9,10 @@ mkdir $OUT_DIR

cp -r assets $OUT_DIR/

TITLE=rdck.dev
LINK_PREFIX=https://rdck.dev
export TITLE=rdck.dev
export LINK_PREFIX=https://rdck.dev

RSSFEED=$OUT_DIR/rss.xml
export RSSFEED=$OUT_DIR/rss.xml

function get_title() {
	cat $1 | grep "^# " | head -1 | sed 's/^# //'


@@ 33,7 35,7 @@ function generate_rss() {

	echo "<rss version=\"2.0\">
<channel>
<title>$TITLE</title>
<title>rdck.dev</title>
<link>$LINK_PREFIX</link>
<language>en-us</language>
<pubDate>`date -R`</pubDate>


@@ 45,6 47,7 @@ function generate_rss() {
<title>`get_title $f`</title>
<link>$LINK_PREFIX/`get_url $f`</link>
<pubDate>`get_date2 $f`</pubDate>
<description>`mmtt < $f | lowdown`</description>
</item>" >> $RSSFEED
	done



@@ 64,26 67,32 @@ function generate_list() {
	echo "</ul>" >> $2
}

generate_list ./fun ./funlist.html
generate_list ./posts ./postlist.html
function generate_navbar() {
	echo "<nav>" > $NAVBAR_HTML
	for f in `find content -type f -name '*.md' ! -name '404.md' ! -name 'index.md'`
	do
		NAME=`basename -s .md $f | awk '{ print toupper(substr($0,1,1)) substr($0,2) }'`
		URL=/`get_url $f`
		echo "<a href=\"$URL\">$NAME</a>" >> $NAVBAR_HTML
	done
	echo "</nav>" >> $NAVBAR_HTML
}

export POSTS_HTML=./postlist.html
export FUN_HTML=./funlist.html
export NAVBAR_HTML=./navbar.html

generate_list ./fun $FUN_HTML
generate_list ./posts $POSTS_HTML
generate_rss `find posts fun -name \*.md -type f`

# build navbar html
echo "<nav>" > ./navbar.html
for f in `find content -type f -name '*.md' ! -name '404.md' ! -name 'index.md'`
do
	NAME=`basename -s .md $f | awk '{ print toupper(substr($0,1,1)) substr($0,2) }'`
	URL=/`get_url $f`
	echo "<a href=\"$URL\">$NAME</a>" >> navbar.html
done
echo "</nav>" >> navbar.html
generate_navbar

# build html from md
for f in `find content posts fun -name \*.md`; do
	PART=$OUT_DIR/`basename -s .md $f`.part.html
	HTML=$OUT_DIR/`basename -s .md $f`.html
	POSTS_HTML=./postlist.html FUN_HTML=./funlist.html mmtt < $f | lowdown --html-no-skiphtml --html-no-escapehtml > $PART
	TITLE=rdck.dev CONTENT_HTML=$PART NAVBAR_HTML=./navbar.html mmtt < template.html > $HTML
	 mmtt < $f | lowdown --html-no-skiphtml --html-no-escapehtml > $PART
	TITLE=`get_title $f` CONTENT_HTML=$PART mmtt < template.html > $HTML
done


M content/index.md => content/index.md +4 -2
@@ 6,14 6,16 @@ My name is Prokop Randáček. I write code, like cats and play Factorio.

### Cool websites in alphabetical order

- [0D9E](https://0d9e.tech/)
- [Bear blog](https://bearblog.dev/)
- [Command Line Interface Guidelines](https://clig.dev)
- [Drew DeVault](https://drewdevault.com/)
- [Kubíkovo](https://chamik.eu/)
- [Lua](https://www.lua.org/)
- [LuaJIT](http://luajit.org/)
- [Marek Maškarinec](https://mrms.cz/)
- [Marian Šámal](https://mariansam.eu/)
- [Matěj Volf](https://matej.0d9e.tech/)
- [rxi](https://rxi.github.io/)
- [SourceHut](https://sourcehut.org)
- [SourceHut](https://sourcehut.org/)
- [Zig](https://ziglang.org/)


M fun/2022-03-06-wang.md => fun/2022-03-06-wang.md +0 -3
@@ 1,7 1,4 @@
<style>
html, body {
	margin: 0;
}
#grid {
	border-collapse: collapse;
}

A fun/2023-04-07-web-graph.md => fun/2023-04-07-web-graph.md +96 -0
@@ 0,0 1,96 @@
# web map

requires disabling cross-origin resource sharing.

<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>

<style>
#mynetwork {
	width: 100vh;
	height: 100vh;
	border: 1px solid lightgray;
}
</style>

<div id="mynetwork"></div>

<script type="text/javascript">

const nodes = new vis.DataSet([{ id: "rdck.dev", label: "rdck.dev", expanded: false, depth: 0 }]);
const edges = new vis.DataSet([]);

var container = document.getElementById('mynetwork');

var data = { nodes: nodes, edges: edges };

var options = { };

var network = new vis.Network(container, data, options);

async function fetchLinks(url) {
	try {
		const response = await fetch("https://" + url)
		const text = await response.text()
		const doc = new DOMParser().parseFromString(text, "text/html")
		return new Set(Array.from(doc.querySelectorAll("a"))
			.map(a => a.getAttribute("href"))
			.map(href => new URL(href, "https://" + url).hostname)
			.filter(a => a != "")
			.map(hostname => {
				const parts = hostname.split(".");
				return parts[parts.length - 2] + "." + parts[parts.length - 1];
			}));
	} catch (error) {
		console.error(error)
	}
	return new Set()
}

async function expandNode(nodeId) {
	const node = nodes.get(nodeId);

	if (node.expanded) return;

	const newLinks = await fetchLinks(node.id);
	node.expanded = true;
	nodes.update(node);

	newLinks.forEach(link => {
		if (!nodes.get(link)) {
			nodes.update({
				id: link,
				label: link,
				expanded: false,
				depth: node.depth + 1
			});
		}
		edges.update({ from: node.id, to: link });
		}
	);
}

network.on('click', (params) => {
	if (params.nodes.length) {
		expandNode(params.nodes[0]);
	}
});

async function expandAll() {
	const unexpandedNodes = nodes.get({
		filter: node => !node.expanded,
		fields: ['id']
	});

	for (const node of unexpandedNodes) {
		await expandNode(node.id);
	}
}

(async function() {
await expandAll();
await expandAll();
await expandAll();
})();

</script>


A post.txt => post.txt +9 -0
@@ 0,0 1,9 @@
# Posts

Sometimes I like to write something that is not code :D

Note that I disown anything I wrote more than 2 years ago.

------------------------------------------------------------------------

{:: cat \$POSTS_HTML ::}

A posts/2023-05-10-lebka-propaganda-1.md => posts/2023-05-10-lebka-propaganda-1.md +76 -0
@@ 0,0 1,76 @@
# Common web L

## Present

The overwhelming complexity of current web standards has narrowed down web
browsers to just 3 implementations: Chromium, Safari, and Frefox. Even
Microsoft, valued at 2 *trillion* dollars[1] with 100k developers[2], abandoned
maintaining its own web browser and switched to Blink.

Interestingly, Apple's uncompetitive browser restrictions are the last thing
keeping web browser diversity alive. Today's web development usually involves
maintaining compatibility with Chrome, Safari, and Firefox.

- Chrome, because it has the biggest usage share (65 %[3])
- Safari, because it is mandatory on Apple devices (19 %[3])
- Firefox, because you might as well while you are at it (2 %[3])

Supporting 2 platforms instead of 3 isn't a significant reduction in workload.
As seen by Firefox still being deemed worth the developer's time and effort to
support.

## Speculation

Imagine if Apple decided to abandon WebKit, joining forces with Chromium just
like Microsoft. Firefox would be in an even worse position than it is now. With
Chromium-based browsers dominating 94 %[3] of the web, few would care about the
remaining 6 %. The reduced need to distinguish between browser-specific behavior
and standard specified behavior would kill any browser that did not walk or
quack like Chrome.

This would enable Chrome to push non-standard behavior and custom features, such
as [Web
Bluetooth](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API),
[Shape Detection](https://developer.chrome.com/en/articles/shape-detection),
[WebUSB](https://developer.mozilla.org/en-US/docs/Web/API/WebUSB_API), and more.
It doesn't matter if they're experimental; if it works on Chrome, why not rely
on it? This trend would make it increasingly difficult for new browsers to
emerge. Competing with Chrome would mean not only implementing the entire
HTML/CSS/JS stack but also additional features like a face recognition API.

Of course, Apple isn't keeping WebKit alive to save Firefox; they talk about
"security" reasons[4]...

Ironically, *efforts to stop Apple from enforcing WebKit on iOS might be the
final nail in the Firefox coffin*.

![](assets/posts/apple_firefox_meme.webp)

## Present

Even Chromium and WebKit-based browsers aren't immune to these challenges. I
currently use the WebKit-based [qutebrowser](https://qutebrowser.org), but that
doesn't mean that things just work. To bypass the new generation of captchas on
sites like Hetzner or ChatGPT, I have to abandon qutebrowser and launch
Chromium. I didn't bother reaching out to OpenAI and Hetzner doesn't care:

> [...] we cannot support your current browser. The reason is that the use of
> this browser is very rare, and it is not viable for us to customize our
> website specifically for it. [...]

It is not enough that qutebrowser supports everything that Safari does, it has
to trick websites into thinking that it actually is Safari.

## Conclusion

The web is in a terrible state, and we need to do better. If only there was a
way to achieve 70% of web functionality with just 10% of the code. Removing the
technical debt, reducing complexity, improving modularity, embracing simplicity,
making it possible again for meere mortals to create homebrew
browsers[...](https://git.sr.ht/~prokop/lebka)

[1]: https://www.macrotrends.net/stocks/charts/MSFT/microsoft/net-worth
[2]: https://devblogs.microsoft.com/engineering-at-microsoft/welcome-to-the-engineering-at-microsoft-blog
[3]: https://en.wikipedia.org/wiki/Usage_share_of_web_browsers
[4]: https://www.macrumors.com/2022/02/25/should-apple-ban-rival-browser-engines