WP’s Customizer’s weird IFRAME Glitch

I’m not sure if this is a bug, but it’s so odd that I’ll leave a post here to remind myself about this. The Customizer has an odd behavior if you enter it via the big blue button on the Admin dashboard that reads “Customize Your Site”.

customize.php starts to load, and there’s a little spinner animation. Then, the URL changes to customize.php?changeset_uuid=…

This is happening via some javascript that I don’t entirely understand.

Then, what happens is the entire customizer experience gets loaded via an IFRAME. customize.php contains an IFRAME with SRC=”customize.php”.

This isn’t normal. Typically, customize.php has an IFRAME that contains the preview of the page, and that’s it.

In this unusual scenario, customize.php contains a customize.php, that then contains the preview.

Reaching out from inside.

I am working on a plugin that needs to display the wp.media dialogs within the customize.php. My code loads into the content’s page, not the customize.php page. My code is in an IFRAME. So I was reaching out into the Customizer IFRAME, with a reference like this “window.top.wp.media…”

This odd glitch caused the IFRAME I wanted to no longer be window.top, so when I entered the page via that blue button, my plugin wouldn’t work correctly.

In other words, my expected nesting was customize.php>IFRAME>my_code. The glitch added another IFRAME so the nesting became: customize.php>IFRAME>IFRAME>my_code.

So window.top refers to something else. I should have used window.parent.

It doesn’t happen in other scenarios.

If I reloaded the page, the page had only the one IFRAME. (The same URL produced a different page.)

If the link to customize.php had a return parameter, it would have only one IFRAME. Likewise, if I pasted the URL in, it wouldn’t alter the URL, and I’d have only one IFRAME.

What’s also odd was that the “Customize” link in the Admin dashboard’s menu, on the left edge, behaved as if I had pasted the URL in. It had only one IFRAME.

(I suspect that the big blue button’s click is intercepted or something, so that the customizer can load with the animated spinner.)

Symptoms

Initially, I thought that a script was forwarding the browser to a different URL. The debugger indicated this was not happning. So I thought maybe history.state changed, and then a bunch of objects in the wp.media namespace vanished.

So I was finding out if alterations to history.state could do this. They don’t; it’s against the spec. Then I was looking for handlers that altered something on a history state change event. Nothing there either.

The other symptom that I didn’t understand was that my handler that would search for/wait for an initializer function to become available within the IFRAME. Once it became available, it would call the initalizer.

I put in a console.log statement to report that it was waiting for the function to exist. When I clicked on the big blue button, it appeared that another, identical handler was continuing to execute, and not ever finding the initializer function.

In fact, that was exactly what was happening – the first handler was loaded in the topmost document, and would never find the initializer function. The second handler was loaded in the inner, middle IFRAME’s document, and found the initializer, and executed it. Then my code would run, refer to window.top.wp.media, and fail to find anything there.

Meanwhile, the first handler would keep running forever, never finding the initalizer function.