1h-money · welcome gift · episode 4
You just followed the series. Here is your welcome gift.
1. Driving rich text editors (X, LinkedIn) without corrupting them
The number one trap I hit in production: injecting text into a rich editor
(contenteditable/draft.js) corrupts its state — greyed-out button, concatenated drafts (827 characters of mush
during episode 1).
- Always start from a blank composer (reload
x.com/compose/post, accept the beforeunload dialog). - Simulated keystrokes only (CDP
Input.insertText) — never assignvalueor innerText. - “Select all” (Cmd+A) does not work in these editors. You do not fix a draft: you throw it away and retype it.
- X counts weighted characters: any URL = 23, some symbols = 2. Trust the button state, not your own counter.
2. The universal tree-walker for the shadow DOM
On LinkedIn, Reddit and most modern apps, querySelector sees nothing: the elements
live behind shadow roots. This walker traverses them all:
function* walk(root) {
const it = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
let n;
while (n = it.nextNode()) {
yield n;
if (n.shadowRoot) yield* walk(n.shadowRoot);
}
}
// usage: find and click the visible "Post" button, wherever it hides
for (const el of walk(document))
if (el.tagName === "BUTTON" && el.textContent.trim() === "Post" && el.offsetParent) { el.click(); break; }
These two chapters were written under real conditions — every trap cost real minutes
during the episodes. The full Playbook (10 chapters: Stripe via API, watchers, human-in-the-loop 2FA,
video pipeline, distribution data…) is pay what you want.
Get the full Playbook — €9, pay what you want
🇬🇧 English edition — $9, pay what you want