What's happening
When the bookmarklet runs on a page (e.g. ma.tt) and opens Press This in a popup with proxy/server-side scanning disabled, the popup loads but no scraped data ever arrives — title, content, images, embeds, and selection are all empty. With proxy enabled, the auto-scan masks the symptom partially, but the bookmarklet's own postMessage payload is silently dropped.
Repro
- Disable Direct Access Mode / proxy in Press This settings (or use any bookmarklet flow on a host where the auto-scan also fails — see below).
- Visit any third-party page, e.g.
https://ma.tt/2026/04/theopensource/.
- Highlight some text and click the Press This bookmarklet.
- The popup opens to
…/wp-admin/press-this.php?v=11&u=…&pm=1 but the editor stays empty — no title, no quote, no images, no embeds.
Root cause
src/App.js:256 rejects every postMessage whose origin doesn't match the popup's own origin:
async function handleMessage( event ) {
if ( event.origin !== window.location.origin ) {
return;
}
…
}
The bookmarklet runs on whatever page the user is on (any third-party site), so event.origin is always something like https://ma.tt, never the WordPress site's origin. Every legitimate bookmarklet message gets dropped.
When it broke
PR #100 ("Fix bookmarklet on mobile browsers", commit a55f050, Apr 3). The change came in under the commit "Harden window.name fallback and postMessage listener — Add event.origin check on the postMessage listener and a 1 MB size cap before parsing window.name."
The intent (don't let arbitrary pages forge press-this-data messages) is right; the check is wrong for this transport because the bookmarklet is cross-origin by definition.
Proposed fix
Validate the message source instead of its origin: only accept messages from window.opener (the bookmarklet's window, which holds the only reference to the popup it spawned). Something like:
if ( ! window.opener || event.source !== window.opener ) {
return;
}
That keeps the spoofing protection (random pages can't postMessage into this popup without being its opener) without rejecting the bookmarklet's legitimate cross-origin payload.
Worth adding a regression test for the postMessage path in tests/ so this doesn't silently regress again — the existing tests around #100 cover bookmarklet generation and window.name fallback but don't exercise the postMessage receive path end-to-end with a cross-origin sender.
Related observations (may be separate issues)
While debugging I also saw:
- The server-side
/press-this/v1/scrape endpoint surfaces a generic "The URL could not be retrieved" error when an upstream returns non-2xx. NYTimes (https://www.nytimes.com/live/...) returns 403 to the Press This/<version>; <home_url> user agent (DataDome). YouTube watch URLs also fail in some cases for me on a live site. Anti-bot pushback is largely external, but the UX could be friendlier (and a more browser-like UA might shake some loose).
- Clicking a YouTube thumbnail in the Scraped Media panel inserts a
core/embed block but no preview renders. Haven't fully root-caused — flagging in case it's related to the same content path.
Happy to send a PR for the postMessage fix.
What's happening
When the bookmarklet runs on a page (e.g.
ma.tt) and opens Press This in a popup with proxy/server-side scanning disabled, the popup loads but no scraped data ever arrives — title, content, images, embeds, and selection are all empty. With proxy enabled, the auto-scan masks the symptom partially, but the bookmarklet's own postMessage payload is silently dropped.Repro
https://ma.tt/2026/04/theopensource/.…/wp-admin/press-this.php?v=11&u=…&pm=1but the editor stays empty — no title, no quote, no images, no embeds.Root cause
src/App.js:256rejects every postMessage whose origin doesn't match the popup's own origin:The bookmarklet runs on whatever page the user is on (any third-party site), so
event.originis always something likehttps://ma.tt, never the WordPress site's origin. Every legitimate bookmarklet message gets dropped.When it broke
PR #100 ("Fix bookmarklet on mobile browsers", commit
a55f050, Apr 3). The change came in under the commit "Harden window.name fallback and postMessage listener — Add event.origin check on the postMessage listener and a 1 MB size cap before parsing window.name."The intent (don't let arbitrary pages forge
press-this-datamessages) is right; the check is wrong for this transport because the bookmarklet is cross-origin by definition.Proposed fix
Validate the message source instead of its origin: only accept messages from
window.opener(the bookmarklet's window, which holds the only reference to the popup it spawned). Something like:That keeps the spoofing protection (random pages can't
postMessageinto this popup without being its opener) without rejecting the bookmarklet's legitimate cross-origin payload.Worth adding a regression test for the postMessage path in
tests/so this doesn't silently regress again — the existing tests around #100 cover bookmarklet generation and window.name fallback but don't exercise the postMessage receive path end-to-end with a cross-origin sender.Related observations (may be separate issues)
While debugging I also saw:
/press-this/v1/scrapeendpoint surfaces a generic "The URL could not be retrieved" error when an upstream returns non-2xx. NYTimes (https://www.nytimes.com/live/...) returns 403 to thePress This/<version>; <home_url>user agent (DataDome). YouTube watch URLs also fail in some cases for me on a live site. Anti-bot pushback is largely external, but the UX could be friendlier (and a more browser-like UA might shake some loose).core/embedblock but no preview renders. Haven't fully root-caused — flagging in case it's related to the same content path.Happy to send a PR for the postMessage fix.