Skip to content

Instantly share code, notes, and snippets.

@westc
westc / wol-reader.bookmarklet.js
Last active November 4, 2026 16:56
Bookmarklet code for showing a reader on WOL.jw.org.
/* WOL Reader: reads a wol.jw.org page aloud, sentence by sentence, with optional scripture reading.
Paste into the DevTools console on any wol.jw.org page and press Enter, then press ▶ (or K).
Keys: K = play/pause J / L = previous / next sentence Shift+J / Shift+L = previous / next paragraph
V = read the most recent scripture reference now Esc = stop
Alt+click a sentence to start reading there.
Alt+click a scripture link to hear that scripture read.
*/
(() => {
'use strict';
@westc
westc / growl.js
Created September 25, 2026 02:11
Enables showing a growl like temporary popup.
const growl = (() => {
let styleEl;
let container;
function ensureUI() {
if (!styleEl) {
styleEl = document.createElement('style');
styleEl.textContent = `
.growl-container {
@westc
westc / debounce.js
Created August 28, 2026 19:51
Creates a debounced function with an immediate side-effect callback and a maximum wait time (throttle) ceiling.
/**
* Creates a debounced function with an immediate side-effect callback
* and a maximum wait time (throttle) ceiling.
*
* @param {Object} options - Configuration options for the debounce.
* @param {number} options.waitMS - The delay in milliseconds to wait after the
* last call before execution.
* @param {Function} options.afterWait - The primary callback executed after the
* debounce or maxWait period.
* @param {Function} [options.immediate] - Optional function invoked immediately
@westc
westc / Animated YourJS Logo.svg
Last active July 4, 2026 03:51
Animated YourJS SVG Logos
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@westc
westc / showBox.js
Last active July 4, 2026 01:40
A lightweight, zero-dependency asynchronous modal prompt library for the browser built on vanilla JS and HTML5 <dialog>. Features strict object-based button bindings, dynamic form field generation, keyboard shortcut captures (Enter/Esc), and automatic theme matching with explicit runtime overrides. Completely encapsulated within a single global …
/**
* @typedef {Object} FieldOption
* @property {string} [value] - The underlying data value for the option. Defaults to the label if omitted.
* @property {string} label - The visible text display for the option.
*/
/**
* @typedef {Object} BoxField
* @property {string} label - The unique identifier and visible text label for the form field.
* @property {string} [description] - Optional subtext or instructions displayed below the label.
@westc
westc / poll.js
Created June 2, 2026 23:30
A simple way to poll for something in JS.
/**
* @typedef poll__options
* @property {((criteriaResult: any) => void)=} callback
* Optional. If not specified then `poll` returns a promise that will resolve once `criteria` returns a `true`-ish value.
* @property {number} [timeout=50]
* Optional. Number of milliseconds between one call to criteria and the next (excluding the initial which is immediate). Defaults to `50`.
* @property {boolean} [ignoreErrors=false]
* Optional. Whether or not an error coming from `criteria` will be ignored. Defaults to `false`.
*/
/**
@westc
westc / fromUniqueBase.js
Created May 18, 2026 23:36
Convert numbers to custom bases using unique characters and convert back to numbers using custom bases.
/**
* @overload
* @param {string} uniqueBaseChars
* @returns {(str: string) => number}
*/
/**
* @overload
* @param {string} uniqueBaseChars
* @param {string} str
* @returns {number}
@westc
westc / Advanced JSDoc Annotations.md
Created May 10, 2026 05:23
Great examples of advanced JSDoc annotations.

Dynamic Return Based On Object Key/Value Pairs

/**
 * @typedef {{
 *   text: {text: string};
 *   numbers: {number: number};
 *   date: {date: string, time: string};
 * }} ColumnTypeMap
 */
@westc
westc / dedupe.js
Created May 5, 2026 22:35
dedupe() - Takes an array and removes all of the duplicate values determined by the specified hash function. This can be used to make an array of unique values but the uniqueness should rely more on underlying values or properties.
/**
* Takes an array and removes all of the duplicate values determined by the
* specified hash function.
* @template {any[]} T
* @param {T} array
* @param {(value: T[number], index: number, array: T) => any} hash
* @returns {T}
*/
function dedupe(array, hash) {
const hashedValues = new Set();
@westc
westc / sortJSON.js
Last active May 5, 2026 22:28
sortJSON() - Converts a JS value to canonical a JSON string that will be the same every time regardless of the order in which the keys are defined in the underlying objects.
/**
* @license Copyright 2026 - Chris West - MIT Licensed
* @see https://gist.github.com/westc/f1bf5453b74a055bb4013f4e23da96eb
*
* Converts a JS value to a canonical JSON string that will be the same every
* time regardless of the order in which the keys are defined in the underlying
* objects.
* @param {any} value
* A JavaScript value, usually an object or array, to be converted.
* @param {Parameters<typeof JSON.stringify>[1]} replacer