Skip to content

fix(dock): open off-site menu items in a new browser tab#247

Merged
epeicher merged 1 commit into
trunkfrom
fix/dock-cross-origin-new-tab
May 19, 2026
Merged

fix(dock): open off-site menu items in a new browser tab#247
epeicher merged 1 commit into
trunkfrom
fix/dock-cross-origin-new-tab

Conversation

@epeicher

@epeicher epeicher commented May 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • WordPress.com injects admin menu items (Hosting, Upgrades, …) that point at https://wordpress.com/... URLs — cross-origin to the wpcomstaging.com wp-admin host. Clicking those dock tiles produced a blank window.
  • Root cause: withChromelessParam() (src/window/dom.ts:76-83) returns null for cross-origin URLs, and the iframe at src/window/dom.ts:548 then falls back to about:blank. The dock click path never filtered for off-site URLs.
  • Fix: add a shared tryOpenExternalUrl() helper and call it from every opener path the user can reach from the shell. Cross-origin URLs open in a new browser tab (_blank, noopener,noreferrer); same-origin URLs are unchanged.

What changed

  • src/external-url.ts — new shared helper.
  • src/external-url.test.ts — 5 unit tests covering same-origin / relative / cross-origin / unparseable URLs.
  • src/dock.ts — call helper from openPage (primary click), openNewInstance (peek + card), and the dock: desktop-icon branch.
  • src/desktop-icons.ts — refactor the inline cross-origin check to use the shared helper (no behavior change here, just dedup).

The check is generic — no WP.com-specific patterns — so any plugin that registers an off-site admin link (Jetpack Cloud, Akismet portals, etc.) gets the same handling.

Test plan

  • npm run lint — clean
  • npx tsc --noEmit — clean
  • npm run test:js — 1444/1444 passing (5 new tests for tryOpenExternalUrl)
  • npm run build — clean
  • Reproduced on local dev with a fake WP.com-style menu item (add_menu_page( …, 'https://example.com/foo', … )) — tile opens the URL in a new tab; same-origin tiles still open as iframe windows.
  • Verified by reporter on a WP.com staging site (Hosting + Upgrades) — both open in a new tab.
Open WordPress Playground Preview

WordPress.com injects admin menu entries that point at
`wordpress.com/...` URLs (Hosting, Upgrades), which are cross-origin
to the wp-admin host on wpcomstaging.com. Clicking those tiles fed
the URL into the iframe path, where `withChromelessParam()`'s same-
origin gate returned null and the iframe fell through to
`about:blank` — a blank window the user couldn't recover from.

Add a shared `tryOpenExternalUrl()` helper and call it at every
opener entry point a user can reach from the shell:

  - dock primary click (`openPage`)
  - dock peek "+" ghost card (`openNewInstance`)
  - dock-promoted desktop-icon click (the `dock:` id branch)
  - desktop icon double-click (was already inlined here; now uses
    the shared helper)

Cross-origin URLs route to `window.open(url, '_blank',
'noopener,noreferrer')`, matching what classic admin does when the
same item is clicked. Same-origin and relative URLs fall through to
the existing iframe path unchanged. The check is generic — no
WordPress.com-specific logic — so Jetpack Cloud, Akismet portals,
and any future plugin with an off-site admin link get the same
handling for free.
@github-actions

Copy link
Copy Markdown
Contributor

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

@epeicher epeicher merged commit 97f231e into trunk May 19, 2026
5 checks passed
@epeicher epeicher deleted the fix/dock-cross-origin-new-tab branch May 19, 2026 16:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant