Skip to content
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

Cross-origin window.focus() vs window.postMessage() #3506

Open
annevk opened this issue Feb 26, 2018 · 11 comments
Open

Cross-origin window.focus() vs window.postMessage() #3506

annevk opened this issue Feb 26, 2018 · 11 comments
Labels
interop Implementations are not interoperable with each other normative change topic: agent The interaction with JavaScript's agent and agent cluster concepts topic: serialize and transfer

Comments

@annevk
Copy link
Member

annevk commented Feb 26, 2018

In https://bugzilla.mozilla.org/show_bug.cgi?id=1440754 @bzbarsky presented an interesting case:

win.postMessage("hey", "*");
win.focus();

Under normal conditions you can expect the window to be focused before it gets a message. How is this ensured when they are actually in different processes?

As pointed out by @wanderview, similar scenarios can be constructed with MessageChannel.

Somewhat related: #3497.

cc @jgraham @mystor @smaug---- @csreis @Rnia @zetafunction

@annevk annevk added normative change interop Implementations are not interoperable with each other topic: serialize and transfer labels Feb 26, 2018
@bzbarsky
Copy link
Contributor

So I just tested Chrome with this testcase. Parent:

<iframe src="http://web.mit.edu/bzbarsky/www/testcases/windowproxy/focus-logger.html"></iframe>
<script>
  onload = () => {
    var kid = frames[0];
    kid.postMessage(null, "*");
    kid.focus();
  }
</script>

and child (from that link):

<script>
  var focused = false;
  onfocus = () => focused = true;
  onblur = () => focused = false;
  onmessage = () => console.log(`Child is focused: ${focused}`);
</script>

I see true logged normally but false logged when running with --site-per-process. Note that you can't have the two pages both be file://, apparently. That is, Chrome considers those not-same-origin but apparently not different "sites" for purposes of site-per-process. Hence the use of a http:// child; the parent can be placed on file://.

Oh, and if I reverse the order of the focus and postMessage calls in the --site-per-process case, I get true. So Chrome really is hitting this exact issue.

(As a side note, @mystor figured out that this is an issue, not me. I just filed the Gecko bug.)

@annevk
Copy link
Member Author

annevk commented Feb 26, 2018

Ah, go @mystor \o/

@csreis
Copy link

csreis commented Feb 26, 2018

Ah, yes, I think this is because we don't start the timer in the cross-process case. I wonder if we could post a task in that case similar to the same-process case, as suggested in https://bugzilla.mozilla.org/show_bug.cgi?id=1440754?

LocalDOMWindow starts a timer:
https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp?sq=package:chromium&l=609

RemoteDOMWindow just forwards the event to the browser process for dispatch to the right process:
https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp?sq=package:chromium&l=31

@zetafunction, what do you think?

@annevk annevk added the topic: agent The interaction with JavaScript's agent and agent cluster concepts label Feb 26, 2019
@annevk
Copy link
Member Author

annevk commented May 27, 2019

@bzbarsky @csreis @cdumez what would be a robust setup here that we can agree on and eventually specify?

One thought I had is that we queue all cross-agent actions within a task, message a copy of the queue and empty the queue end-of-task, and then dequeue the queue and run the actions on the other side. postMessage() would then incur another tick (as part of its action).

(If you message each action independently it seems the postMessage() could still complete prior to the focus().)

@bzbarsky
Copy link
Contributor

Presumably entering "spin the event loop" (possibly in cases where the HTML spec currently has "pause") would also flush out the queue?

My main worry there is the requirement for unbounded growth of the queue. Maybe it's not an issue in practice, though.

@annevk
Copy link
Member Author

annevk commented May 28, 2019

I suppose. I'm still somewhat hopeful we can remove "spin the event loop" as Chrome does not seem to have it (or at least for the various modal dialogs they appear to sometimes return early, rather than spin, and the other places where we permit spinning are hard to create tests for).

@dtapuska
Copy link
Contributor

@mustaqahmed

This might be a use case for delegating some permission temporarily on the postMessage. That was some of the TAG feedback received on #4364 The the focusing can be delegated to doing it inside the postMessage handler of the receiving frame.

@mustaqahmed
Copy link
Contributor

@annevk: Any chance your observations above is affected by async window.focus() in Chrome? See #5493.

@annevk
Copy link
Member Author

annevk commented Apr 29, 2020

You mean it queues a task? Does that depend on the caller?

@mustaqahmed
Copy link
Contributor

@annevk I am not sure at this point. Same-origin case may be different, I didn't dig into this. All I know that Chrome cross-origin focus requests go through browser so can't be synchronous. Let's discuss this in #5493.

@annevk
Copy link
Member Author

annevk commented May 5, 2020

Sorry, yeah, it's expected that with process isolation of sites focus() has to queue a task on some other agent, but this creates observable API behavior differences is indicated in OP. So a question is how to resolve that. We could formalize that cross-origin/site, regardless of process isolation of sites, focus() queues a task, or we could try something more complicated, but either way this is something that we ought to define properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interop Implementations are not interoperable with each other normative change topic: agent The interaction with JavaScript's agent and agent cluster concepts topic: serialize and transfer
Development

No branches or pull requests

5 participants