Skip to content

Instantly share code, notes, and snippets.

View Haprog's full-sized avatar

Kari Söderholm Haprog

View GitHub Profile
Haprog / 01
Created May 20, 2023 09:31 — forked from bnutz/01
Installing Pi-Hole, Unbound and a WireGuard VPN server on a Raspberry Pi (via Docker)

Updated: 2022-07

Raspberry Pi-Hole VPN Setup

I wrote the first edition of this as a guide for myself at the end of 2017 - it was a mashup of Pi-Hole + PiVPN scripts and an IPsec script installed within a separate Raspian Docker image... and it actually worked!

But things have come a long way, and WireGuard happened - I've since streamlined and simplified my setup into a single Docker Compose script.

The steps below assume the following:

Haprog / deepQuerySelectorAll.js
Created May 5, 2021 08:36
A version of querySelectorAll() that also recursively looks into all shadow roots
* A version of querySelectorAll() that also recursively looks into all shadow roots.
* @param selector Selector
* @param root (Optional) Scope of the query (Element or Document). Defaults to the document.
* @returns
function deepQuerySelectorAll(selector, root) {
root = root || document;
const results = Array.from(root.querySelectorAll(selector));
const pushNestedResults = function (root) {
Haprog / lumo-css-variables.css
Created August 27, 2020 14:56
vaadin-lumo-styles CSS custom property declarations
* This file is intended as a workaround for IDEs (e.g. IntelliJ IDEA) to be
* able to detect the CSS custom properties (variables) declared by
* so that the IDE won't
* complain about unresolved custom properties and you get autocompletion
* for them.
* Usage:
* Save this file somewhere in your project where your IDE will find it.
Haprog /
Last active November 21, 2021 02:09
Googlebot User Agents

Keybase proof

I hereby claim:

  • I am haprog on github.
  • I am haprog ( on keybase.
  • I have a public key ASDRDMKacyX-eTdsoX-bvM9Ze-_vkyMUkG9dTNmqKeFPxAo

To claim this, I am signing this object:

Haprog / loadScript.js
Created January 17, 2018 03:47
Utility methods for loading a script.
* Load the given script.
* (appends a new <script> tag to the end of the main document's <head> tag)
* @param {string} src URL if the script to be loaded
* @param {?Object} props Properties to be set on the script (e.g. async, defer, onload, onerror)
* @param {?Object} attrs Attributes to be set on the script (e.g. id, data-*)
* @returns {Promise}
let loadScript = (src, props, attrs) => new Promise((resolve, reject) => {
Haprog / ratelimit.js
Created February 22, 2016 12:33
Rate Limiting JavaScript Function Call
// Returns a new function that will call the given "func" at most once every "wait" milliseconds.
// Based on debounce function from:
function rateLimit(func, wait) {
var waiting = false;
return function() {
if (!waiting) {
var waiting = true, context = this, args = arguments;
func.apply(context, args);
setTimeout(function(){ waiting = false; });