-
Notifications
You must be signed in to change notification settings - Fork 274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Query API] Use the exact redirect URL provided in the ?url= query param #1945
Conversation
This PR: * Replaces the `wp_redirect()` call with `header("Location: ")` to ensure support for all valid redirection URLs. * Adds a timeout before probing for the embedded Playground `iframe` URL when the `load` event handler runs. ### Ditching `wp_redirect()` The `wp_redirect()` call was introduced in #1856 to handle the post-autologin redirect. Unfortunately, it strips valid sequences such as `%0A` and `%0D` from the redirection URL. This isn't useful in Playground and breaks valid use-cases such as using the `?url=` parameter to initialize `html-api-debugger` with a valid HTML markup containing newlines. ### Timeout before probing `contentWindow.location.href` When navigating to a page with %0A sequences (encoded newlines) in the query string, the `location.href` property of the iframe's content window doesn't seem to reflect them. Everything else is in place, but not the %0A sequences. Weirdly, these sequences are available after the next event loop tick – hence the `setTimeout(0)`. The exact cause is unclear to me. The WHATWG HTML Standard [1] has a few hints: * Current and active session history entries may get out of sync for iframes. * Documents inside iframes have "is delaying load events" set to true. But there doesn't seem to be any concrete explanation and no recommended remediation. If anyone has a clue, please share it in a GitHub issue or start a new PR. [1] https://html.spec.whatwg.org/multipage/document-sequences.html#nav-active-history-entry ## Testing instructions CI tests aside, try this: 1. Go to http://localhost:5400/website-server/?plugin=html-api-debugger&url=%2Fwp-admin%2Fadmin.php%3Fpage%3Dhtml-api-debugger%26html%3D%253Cdiv%253E%250A1%250A2%250A3%250A%253C%252Fdiv%253E&wp=6.6&php=8.0&networking=no&language=&multisite=no&random=pf3oq1y3vx 2. Confirm the "address bar" on the Playground page reflects the actual, correct URL: `/wp-admin/admin.php?page=html-api-debugger&html=%3Cdiv%3E%0A1%0A2%0A3%0A%3C%2Fdiv%3E` 3. Confirm you can see the following HTML ``` <div> 1 2 3 </div> ``` cc @sirreal @bgrgicak
*/ | ||
// Get the content window while e.currentTarget is available. | ||
// It will be undefined on the next event loop tick. | ||
const contentWindow = e.currentTarget!.contentWindow; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be related to the async event handler?
I've done some testing (not on playground) and with an async event handler the behavior seemed less reliable. However, with the sync event handler, e.target.contentWindow.location.href
seemed to reliably be the expected value.
I don't know whether target
/currentTarget
matters, I suspect not, but target
seemed to work well in my testing the load event on the iframe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the information is lost after the await
. I was thinking it's related to React and how it clears currentTarget
after the synchronous event handler returns, but now that I think about it, React shouldn't be in the mix here. You may be right about the target
/currentTarget
– was the latter affected by bubbling?
// Get the content window while e.currentTarget is available. | ||
// It will be undefined on the next event loop tick. | ||
const contentWindow = e.currentTarget!.contentWindow; | ||
await new Promise((resolve) => setTimeout(resolve, 0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't work in Safari and Firefox.
Locally in Safari, it started working when I increased the timeout to 10, but that doesn't mean the exact timeout will always work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot! I wonder what's the root cause of this behavior. A setInterval
and polling twice per second would likely solve this, but I'm hesitant of just throwing it in without fully understanding the problem.
Oh wow, synchronizing navigables histories is an entire thing: https://html.spec.whatwg.org/dev/browsing-the-web.html#centralized-modifications-of-session-history |
What that boils down to is:
|
// We need to use the html-api-debugger plugin to test this because | ||
// most wp-admin pages enforce a redirect to a sanitized (broken) | ||
// version of the URL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this because of the login redirect Playground does, or is it a WordPress redirect that sanitizes the URL?
home_url($redirect_url), | ||
302 | ||
); | ||
$redirect_url = home_url($redirect_url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adamziel we don't need to force this to a absolute URL anymore because we have a a fix for the relative URL redirects in Safari.
$redirect_url = home_url($redirect_url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope that you don't mind, that I merged trunk into your PR and resolved the conflict with the Safari redirect fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adamziel your test blueprint is throwing a boot error because of the HTML in the URL. I also checked trunk an the same is happening.
Thanks for rebasing @bgrgicak! The test link is failing indeed, not good!
I'm confused by the "because of the HTML in the URL" part. What do you mean? How is that causing a failure? |
Bumping |
Ignore that part, when I tested the blueprint, removing the Later I also realized it was related to the WP versions, but it was late and I wanted to do more research in the morning before commenting anything. I ran the Webkit test locally a couple of times and it passes locally. |
Its minimum version was changed to latest (6.7) and does rely on new functionality. Sorry it broke the test! |
I've disabled that e2e test also in Safari. Let's get the fix in and keep monitoring the problem in Firefox and Safari. It's such a weird issue with close to no reading material out there and I can't think of any other solution anyway. |
This PR:
wp_redirect()
call withheader("Location: ")
to ensure support for all valid redirection URLs.iframe
URL when theload
event handler runs.Ditching
wp_redirect()
The
wp_redirect()
call was introduced in #1856 to handle the post-autologin redirect. Unfortunately, it strips valid sequences such as%0A
and%0D
from the redirection URL. This isn't useful in Playground and breaks valid use-cases such as using the?url=
parameter to initializehtml-api-debugger
with a valid HTML markup containing newlines.Timeout before probing
contentWindow.location.href
When navigating to a page with %0A sequences (encoded newlines) in the query string, the
location.href
property of the iframe's content window doesn't seem to reflect them. Everything else is in place, but not the %0A sequences.Weirdly, these sequences are available after the next event loop tick – hence the
setTimeout(0)
.The exact cause is unclear to me. The WHATWG HTML Standard [1] has a few hints:
But there doesn't seem to be any concrete explanation and no recommended remediation. If anyone has a clue, please share it in a GitHub issue or start a new PR.
[1] https://html.spec.whatwg.org/multipage/document-sequences.html#nav-active-history-entry
Testing instructions
CI tests aside, try this:
/wp-admin/admin.php?page=html-api-debugger&html=%3Cdiv%3E%0A1%0A2%0A3%0A%3C%2Fdiv%3E
cc @sirreal @bgrgicak