Features
What you get when you install Giggles&Shit (GAS) v2.3.0. Implementation details for each item are linked into the Docusaurus docs.
🧰 Toolbar button injection
GAS finds GitHub's own formatting toolbar next to every markdown editor
([role="toolbar"], with an aria-label*="Formatting" fallback search up to 8
ancestors) and appends a 20×20 trollge button to it. Injection is deduplicated: a toolbar that
already has the button is never touched twice. API reference →
🖼️ Emoji picker
A floating panel (created lazily once, then reused) with a responsive grid of emoji cards —
image, name, and the exact tag it's going to insert (<img width="20px">). Images
are lazy-loaded; a dead image link dims to 35% opacity instead of breaking the panel.
Positioning is viewport-aware: it clamps horizontally and flips above the button when the bottom
edge would overflow. Usage guide →
⚛️ Dual insertion engines
- Textarea editors — the HTML string is spliced at the caret (or over the
selection) and written through the native prototype setter, followed by bubbling
inputandchangeevents. This is what keeps GitHub's React-controlled forms in sync. - Contenteditable editors — a real
Imagenode is inserted through the liveSelection/Range, caret collapsed after it, and anInputEvent('insertElement')is dispatched.
🔁 SPA-aware rescanning
GitHub rarely does full page loads — it navigates with Turbo. A MutationObserver on
document.body watches for added nodes and triggers a 100 ms-debounced rescan, so
editors that appear later (lazy comment boxes, new-issue forms, file editors) still get their
button. Architecture →
🫥 Polite, keyboard-friendly UX
- Toggle from the same button; close with
Esc, the × button, outside click, scroll or resize. - Real
<button>elements witharia-labels everywhere — tab order and screen readers work. - Toast confirmation on every insertion (
Inserted skull), auto-removed after 1.4s, never stacking. - Scroll listeners are
passive— no jank.
🔒 Zero permissions, zero residue
The script runs with @grant none: no privileged APIs, no
localStorage, no cookies, no telemetry. The script itself makes no network requests —
the only traffic it triggers is your browser fetching emoji images from
raw.githubusercontent.com (the same host GitHub's own avatars use). Uninstalling the
script removes every trace.
Userscript metadata →
🛠️ Built-in debug API
A single global — window.GAS — exposes live state for console debugging:
GAS.scan(), GAS.editors(), GAS.buttons(),
GAS.testButton(), GAS.gas(), GAS.close(). The startup banner
in the console even tells you they exist.
Debug API docs →
🎨 Bring your own memes
The emoji catalog is a plain array of {name, url} objects. Add yours in your
manager's script editor and reload — GIFs included.
Customization guide →