WordPress / wordpress-playground

Run WordPress in the browser via WebAssembly PHP
https://w.org/playground/
GNU General Public License v2.0
1.64k stars 257 forks source link

Can't link to Playground from inside Playground iframe #961

Open marcarmengou opened 9 months ago

marcarmengou commented 9 months ago

When using Playground (https://playground.wordpress.net/) and visits the Playground front-end in a new tab, a scope is generated.

Example: https://playground.wordpress.net/scope:x.xxxxxxxxxxxxxxxx/

The scope generates problems because if a user tries to place a Query API param (?plugin=toys-for-playground) the Playground will not load correctly.

Example: https://playground.wordpress.net/scope:x.xxxxxxxxxxxxxxxx/?plugin=toys-for-playground

But placing the scope at the end of the url Playground does load the url correctly:

Example: https://playground.wordpress.net/?plugin=toys-for-playground/scope:x.xxxxxxxxxxxxxxxx/

A simple way to experience this problem yourself is by using the Toys for Playground plugin. This plugin has several tools that help the user to build urls for Playground through the Query API.

If follow this link and click on the Playground button of any plugin, will see that the scope is placed between the domain and the string, avoiding the correct construction of the Playground.

https://playground.wordpress.net/?plugin=toys-for-playground&networking=yes&url=/wp-admin/plugin-install.php&mode=seamless

This only happens when testing the plugin on Playground, if you use the plugin locally or on a live site, as no scopes will be generated, the url is constructed correctly.

adamziel commented 9 months ago

The root cause is:

  1. The link is https://playground.wordpress.net/?plugin=classic-editor&url=/wp-admin/&mode=seamless
  2. The link is clicked inside of a Playground iframe, which is controlled by the service worker
  3. The service worker force-adds a scope via a 301 redirect. This is desired in the general case – I remember struggling with WordPress links leading to the domain root / instead of the path where the site is installed, like /scope:34879.

CleanShot 2024-01-30 at 10 24 25@2x

The general solution here could be to prevent the 301 redirection when intentionally loading Playground inside the controlled iframe. However, this gets us into a land of controlled iframes inside controlled iframes and considering all the consequences of those. Let's explore that in https://github.com/WordPress/wordpress-playground/issues/981.

A more tactical solution here would be to fix just those links. I'm playing with a few ideas right now.

adamziel commented 9 months ago

I don't think the service worker can be fooled with markup tricks. For example, I tried <button onclick="window.open('https://playground.wordpress.net?plugin=akismet', '_blank')" class="button button-primary" target="_blank">Playground</a>, but it still went through the same 301 redirect.

I think the only solution is to actually link to a different domain. Here's two ways to do that:

  1. Replace playground.wordpress.net with wasm.wordpress.net – it's another domain pointing to the same place. Note this will likely require an adjustment in a few months as that domain may get repurposed.
  2. Got through a referer hiding service like https://href.li/?https://playground.wordpress.net/?plugin=jetpack&mode=seamless – the problematic part is that href.li doesn't seem to like using the url query parameter so no bueno with redirection. Maybe there's another one, though.