Bug 1696323 - Return early when attempting to focus a remote iframe whose BrowsingContext is already the focused one. r=edgar

Differential Revision: https://phabricator.services.mozilla.com/D112534
This commit is contained in:
Henri Sivonen 2021-04-29 09:43:53 +00:00
Родитель d7df3958f6
Коммит e56b92eb66
14 изменённых файлов: 297 добавлений и 42 удалений

Просмотреть файл

@ -418,7 +418,7 @@ nsFocusManager::GetFocusedContentBrowsingContext(
nsresult nsFocusManager::SetFocusedWindowWithCallerType(
mozIDOMWindowProxy* aWindowToFocus, CallerType aCallerType,
uint64_t aActionId) {
LOGFOCUS(("<<SetFocusedWindow begin>>"));
LOGFOCUS(("<<SetFocusedWindow begin actionid: %lu>>", aActionId));
nsCOMPtr<nsPIDOMWindowOuter> windowToFocus =
nsPIDOMWindowOuter::From(aWindowToFocus);
@ -446,7 +446,7 @@ nsresult nsFocusManager::SetFocusedWindowWithCallerType(
RaiseWindow(rootWindow, aCallerType, aActionId);
}
LOGFOCUS(("<<SetFocusedWindow end>>"));
LOGFOCUS(("<<SetFocusedWindow end actionid: %lu>>", aActionId));
return NS_OK;
}
@ -670,8 +670,8 @@ void nsFocusManager::WindowRaised(mozIDOMWindowProxy* aWindow,
BrowsingContext* bc = window->GetBrowsingContext();
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
LOGFOCUS(("Window %p Raised [Currently: %p %p]", aWindow,
mActiveWindow.get(), mFocusedWindow.get()));
LOGFOCUS(("Window %p Raised [Currently: %p %p] actionid: %lu", aWindow,
mActiveWindow.get(), mFocusedWindow.get(), aActionId));
Document* doc = window->GetExtantDoc();
if (doc && doc->GetDocumentURI()) {
LOGFOCUS((" Raised Window: %p %s", aWindow,
@ -1011,8 +1011,8 @@ void nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow,
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
if (MOZ_LOG_TEST(gFocusLog, LogLevel::Debug)) {
LOGFOCUS(("Window %p Hidden [Currently: %p %p]", window.get(),
mActiveWindow.get(), mFocusedWindow.get()));
LOGFOCUS(("Window %p Hidden [Currently: %p %p] actionid: %lu", window.get(),
mActiveWindow.get(), mFocusedWindow.get(), aActionId));
nsAutoCString spec;
Document* doc = window->GetExtantDoc();
if (doc && doc->GetDocumentURI()) {
@ -1475,6 +1475,16 @@ void nsFocusManager::SetFocusInner(Element* aNewContent, int32_t aFlags,
// called during reflow, calling GetBrowsingContext() could cause frame
// loader initialization at a time when it isn't safe.
if (BrowsingContext* bc = flo->GetExtantBrowsingContext()) {
// If focus is already in the subtree rooted at bc, return early
// to match the single-process focus semantics. Otherwise, we'd
// blur and immediately refocus whatever is focused.
BrowsingContext* walk = focusedBrowsingContext;
while (walk) {
if (walk == bc) {
return;
}
walk = walk->GetParent();
}
browsingContextToFocus = bc;
}
}
@ -1668,8 +1678,9 @@ void nsFocusManager::SetFocusInner(Element* aNewContent, int32_t aFlags,
mFocusedElement.get()));
LOGFOCUS(
(" In Active Window: %d Moves to different BrowsingContext: %d "
"SendFocus: %d",
isElementInActiveWindow, focusMovesToDifferentBC, sendFocusEvent));
"SendFocus: %d actionid: %lu",
isElementInActiveWindow, focusMovesToDifferentBC, sendFocusEvent,
aActionId));
if (sendFocusEvent) {
Maybe<BlurredElementInfo> blurredInfo;
@ -2191,7 +2202,7 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear,
BrowsingContext* aAncestorBrowsingContextToFocus,
bool aIsLeavingDocument, bool aAdjustWidget,
Element* aElementToFocus, uint64_t aActionId) {
LOGFOCUS(("<<Blur begin>>"));
LOGFOCUS(("<<Blur begin actionid: %lu>>", aActionId));
// hold a reference to the focused content, which may be null
RefPtr<Element> element = mFocusedElement;
@ -2224,7 +2235,8 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear,
// Unclear if this ever happens.
LOGFOCUS(
("Ignored an attempt to null out focused BrowsingContext when "
"docShell is null due to a stale action id."));
"docShell is null due to a stale action id %lu.",
aActionId));
return true;
}
@ -2246,7 +2258,8 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear,
// Unclear if this ever happens.
LOGFOCUS(
("Ignored an attempt to null out focused BrowsingContext when "
"presShell is null due to a stale action id."));
"presShell is null due to a stale action id %lu.",
aActionId));
return true;
}
mFocusedElement = nullptr;
@ -2303,10 +2316,10 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear,
if (RefPtr<BrowserParent> browserParent =
windowGlobalParent->GetBrowserParent()) {
browserParent->Deactivate(windowBeingLowered, aActionId);
LOGFOCUS(("%s remote browser deactivated %p, %d",
LOGFOCUS(("%s remote browser deactivated %p, %d, actionid: %lu",
aContext == topLevelBrowsingContext ? "Top-level"
: "OOP iframe",
browserParent.get(), windowBeingLowered));
browserParent.get(), windowBeingLowered, aActionId));
}
}
});
@ -2315,8 +2328,8 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear,
// Same as above but for out-of-process iframes
if (BrowserBridgeChild* bbc = BrowserBridgeChild::GetFrom(element)) {
bbc->Deactivate(windowBeingLowered, aActionId);
LOGFOCUS(("Out-of-process iframe deactivated %p, %d", bbc,
windowBeingLowered));
LOGFOCUS(("Out-of-process iframe deactivated %p, %d, actionid: %lu", bbc,
windowBeingLowered, aActionId));
}
}
@ -2401,13 +2414,14 @@ void nsFocusManager::ActivateRemoteFrameIfNeeded(Element& aElement,
uint64_t aActionId) {
if (BrowserParent* remote = BrowserParent::GetFrom(&aElement)) {
remote->Activate(aActionId);
LOGFOCUS(("Remote browser activated %p", remote));
LOGFOCUS(("Remote browser activated %p, actionid: %lu", remote, aActionId));
}
// Same as above but for out-of-process iframes
if (BrowserBridgeChild* bbc = BrowserBridgeChild::GetFrom(&aElement)) {
bbc->Activate(aActionId);
LOGFOCUS(("Out-of-process iframe activated %p", bbc));
LOGFOCUS(
("Out-of-process iframe activated %p, actionid: %lu", bbc, aActionId));
}
}
@ -2416,7 +2430,7 @@ void nsFocusManager::Focus(
bool aIsNewDocument, bool aFocusChanged, bool aWindowRaised,
bool aAdjustWidget, uint64_t aActionId,
const Maybe<BlurredElementInfo>& aBlurredElementInfo) {
LOGFOCUS(("<<Focus begin>>"));
LOGFOCUS(("<<Focus begin actionid: %lu>>", aActionId));
if (!aWindow) {
return;
@ -2457,7 +2471,8 @@ void nsFocusManager::Focus(
aActionId, mActionIdForFocusedBrowsingContextInContent)) {
// Unclear if this ever happens.
LOGFOCUS(
("Ignored an attempt to focus an element due to stale action id."));
("Ignored an attempt to focus an element due to stale action id %lu.",
aActionId));
return;
}
}
@ -2496,8 +2511,9 @@ void nsFocusManager::Focus(
if (docm) {
LOGCONTENT(" from %s", docm->GetRootElement());
}
LOGFOCUS((" [Newdoc: %d FocusChanged: %d Raised: %d Flags: %x]",
aIsNewDocument, aFocusChanged, aWindowRaised, aFlags));
LOGFOCUS(
(" [Newdoc: %d FocusChanged: %d Raised: %d Flags: %x actionid: %lu]",
aIsNewDocument, aFocusChanged, aWindowRaised, aFlags, aActionId));
}
if (aIsNewDocument) {
@ -4801,8 +4817,8 @@ void nsFocusManager::SetFocusedBrowsingContextFromOtherProcess(
// Unclear if this ever happens.
LOGFOCUS(
("Ignored an attempt to set an in-process BrowsingContext [%p] as "
"focused from another process due to stale action id.",
aContext));
"focused from another process due to stale action id %lu.",
aContext, aActionId));
return;
}
if (aContext->IsInProcess()) {
@ -4814,8 +4830,8 @@ void nsFocusManager::SetFocusedBrowsingContextFromOtherProcess(
// was in-flight. Let's just ignore this.
LOGFOCUS(
("Ignored an attempt to set an in-process BrowsingContext [%p] as "
"focused from another process.",
aContext));
"focused from another process, actionid: %lu.",
aContext, aActionId));
return;
}
mFocusedBrowsingContextInContent = aContext;
@ -4865,8 +4881,8 @@ void nsFocusManager::SetActiveBrowsingContextInContent(
mActionIdForActiveBrowsingContextInContent)) {
LOGFOCUS(
("Ignored an attempt to set an in-process BrowsingContext [%p] as "
"the active browsing context due to a stale action id.",
aContext));
"the active browsing context due to a stale action id %lu.",
aContext, aActionId));
return;
}
@ -4909,8 +4925,8 @@ void nsFocusManager::SetActiveBrowsingContextFromOtherProcess(
mActionIdForActiveBrowsingContextInContent)) {
LOGFOCUS(
("Ignored an attempt to set active BrowsingContext [%p] from "
"another process due to a stale action id.",
aContext));
"another process due to a stale action id %lu.",
aContext, aActionId));
return;
}
if (aContext->IsInProcess()) {
@ -4922,8 +4938,8 @@ void nsFocusManager::SetActiveBrowsingContextFromOtherProcess(
// was in-flight. Let's just ignore this.
LOGFOCUS(
("Ignored an attempt to set an in-process BrowsingContext [%p] as "
"active from another process.",
aContext));
"active from another process. actionid: %lu",
aContext, aActionId));
return;
}
mActiveBrowsingContextInContentSetFromOtherProcess = true;
@ -4940,8 +4956,8 @@ void nsFocusManager::UnsetActiveBrowsingContextFromOtherProcess(
mActionIdForActiveBrowsingContextInContent)) {
LOGFOCUS(
("Ignored an attempt to unset the active BrowsingContext [%p] from "
"another process due to stale action id.",
aContext));
"another process due to stale action id: %lu.",
aContext, aActionId));
return;
}
if (mActiveBrowsingContextInContent == aContext) {
@ -4951,8 +4967,8 @@ void nsFocusManager::UnsetActiveBrowsingContextFromOtherProcess(
} else {
LOGFOCUS(
("Ignored an attempt to unset the active BrowsingContext [%p] from "
"another process.",
aContext));
"another process. actionid: %lu",
aContext, aActionId));
}
}
@ -4961,12 +4977,17 @@ void nsFocusManager::ReviseActiveBrowsingContext(
uint64_t aNewActionId) {
MOZ_ASSERT(XRE_IsContentProcess());
if (mActionIdForActiveBrowsingContextInContent == aOldActionId) {
LOGFOCUS(
("Revising the active BrowsingContext [%p]. old actionid: %lu, new "
"actionid: %lu",
aContext, aOldActionId, aNewActionId));
mActiveBrowsingContextInContent = aContext;
mActionIdForActiveBrowsingContextInContent = aNewActionId;
} else {
LOGFOCUS(
("Ignored a stale attempt to revise the active BrowsingContext [%p].",
aContext));
("Ignored a stale attempt to revise the active BrowsingContext [%p]. "
"old actionid: %lu, new actionid: %lu",
aContext, aOldActionId, aNewActionId));
}
}
@ -4975,13 +4996,18 @@ void nsFocusManager::ReviseFocusedBrowsingContext(
uint64_t aNewActionId) {
MOZ_ASSERT(XRE_IsContentProcess());
if (mActionIdForFocusedBrowsingContextInContent == aOldActionId) {
LOGFOCUS(
("Revising the focused BrowsingContext [%p]. old actionid: %lu, new "
"actionid: %lu",
aContext, aOldActionId, aNewActionId));
mFocusedBrowsingContextInContent = aContext;
mActionIdForFocusedBrowsingContextInContent = aNewActionId;
mFocusedElement = nullptr;
} else {
LOGFOCUS(
("Ignored a stale attempt to revise the focused BrowsingContext [%p].",
aContext));
("Ignored a stale attempt to revise the focused BrowsingContext [%p]. "
"old actionid: %lu, new actionid: %lu",
aContext, aOldActionId, aNewActionId));
}
}
@ -5011,6 +5037,7 @@ BrowsingContext* nsFocusManager::GetActiveBrowsingContextInChrome() {
}
void nsFocusManager::InsertNewFocusActionId(uint64_t aActionId) {
LOGFOCUS(("InsertNewFocusActionId %lu", aActionId));
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!mPendingActiveBrowsingContextActions.Contains(aActionId));
mPendingActiveBrowsingContextActions.AppendElement(aActionId);
@ -5103,6 +5130,7 @@ uint64_t nsFocusManager::GenerateFocusActionId() {
MOZ_ASSERT(contentChild);
contentChild->SendInsertNewFocusActionId(id);
}
LOGFOCUS(("GenerateFocusActionId %lu", id));
return id;
}
@ -5138,7 +5166,8 @@ void nsFocusManager::SetFocusedWindowInternal(nsPIDOMWindowOuter* aWindow,
// Unclear if this ever happens.
LOGFOCUS(
("Ignored an attempt to set an in-process BrowsingContext as "
"focused due to stale action id."));
"focused due to stale action id %lu.",
aActionId));
return;
}

Просмотреть файл

@ -28,6 +28,11 @@
using namespace mozilla::ipc;
mozilla::LazyLogModule gBrowserChildFocusLog("BrowserChildFocus");
#define LOGBROWSERCHILDFOCUS(args) \
MOZ_LOG(gBrowserChildFocusLog, mozilla::LogLevel::Debug, args)
namespace mozilla::dom {
BrowserBridgeChild::BrowserBridgeChild(BrowsingContext* aBrowsingContext,
@ -77,6 +82,8 @@ void BrowserBridgeChild::NavigateByKey(bool aForward,
}
void BrowserBridgeChild::Activate(uint64_t aActionId) {
LOGBROWSERCHILDFOCUS(
("BrowserBridgeChild::Activate actionid: %lu", aActionId));
Unused << SendActivate(aActionId);
}

Просмотреть файл

@ -1133,7 +1133,7 @@ void BrowserParent::HandleAccessKey(const WidgetKeyboardEvent& aEvent,
}
void BrowserParent::Activate(uint64_t aActionId) {
LOGBROWSERFOCUS(("Activate %p", this));
LOGBROWSERFOCUS(("Activate %p actionid: %lu", this, aActionId));
if (!mIsDestroyed) {
SetTopLevelWebFocus(this); // Intentionally inside "if"
Unused << SendActivate(aActionId);
@ -1141,7 +1141,7 @@ void BrowserParent::Activate(uint64_t aActionId) {
}
void BrowserParent::Deactivate(bool aWindowLowering, uint64_t aActionId) {
LOGBROWSERFOCUS(("Deactivate %p", this));
LOGBROWSERFOCUS(("Deactivate %p actionid: %lu", this, aActionId));
if (!aWindowLowering) {
UnsetTopLevelWebFocus(this); // Intentionally outside the next "if"
}

Просмотреть файл

@ -6772,6 +6772,7 @@ mozilla::ipc::IPCResult ContentParent::RecvWindowFocus(
("ParentIPC: Trying to send a message to dead or detached context"));
return IPC_OK();
}
LOGFOCUS(("ContentParent::RecvWindowFocus actionid: %lu", aActionId));
CanonicalBrowsingContext* context = aContext.get_canonical();
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
@ -6807,6 +6808,7 @@ mozilla::ipc::IPCResult ContentParent::RecvRaiseWindow(
("ParentIPC: Trying to send a message to dead or detached context"));
return IPC_OK();
}
LOGFOCUS(("ContentParent::RecvRaiseWindow actionid: %lu", aActionId));
CanonicalBrowsingContext* context = aContext.get_canonical();
@ -6826,6 +6828,9 @@ mozilla::ipc::IPCResult ContentParent::RecvAdjustWindowFocus(
("ParentIPC: Trying to send a message to dead or detached context"));
return IPC_OK();
}
LOGFOCUS(("ContentParent::RecvAdjustWindowFocus isVisible %d actionid: %lu",
aIsVisible, aActionId));
nsTHashMap<nsPtrHashKey<ContentParent>, bool> processes(2);
processes.InsertOrUpdate(this, true);
@ -6874,6 +6879,8 @@ mozilla::ipc::IPCResult ContentParent::RecvSetFocusedBrowsingContext(
("ParentIPC: Trying to send a message to dead or detached context"));
return IPC_OK();
}
LOGFOCUS(("ContentParent::RecvSetFocusedBrowsingContext actionid: %lu",
aActionId));
CanonicalBrowsingContext* context = aContext.get_canonical();
nsFocusManager* fm = nsFocusManager::GetFocusManager();
@ -6909,6 +6916,8 @@ mozilla::ipc::IPCResult ContentParent::RecvSetActiveBrowsingContext(
("ParentIPC: Trying to send a message to dead or detached context"));
return IPC_OK();
}
LOGFOCUS(
("ContentParent::RecvSetActiveBrowsingContext actionid: %lu", aActionId));
CanonicalBrowsingContext* context = aContext.get_canonical();
nsFocusManager* fm = nsFocusManager::GetFocusManager();
@ -6942,6 +6951,8 @@ mozilla::ipc::IPCResult ContentParent::RecvUnsetActiveBrowsingContext(
("ParentIPC: Trying to send a message to dead or detached context"));
return IPC_OK();
}
LOGFOCUS(("ContentParent::RecvUnsetActiveBrowsingContext actionid: %lu",
aActionId));
CanonicalBrowsingContext* context = aContext.get_canonical();
nsFocusManager* fm = nsFocusManager::GetFocusManager();
@ -6975,6 +6986,7 @@ mozilla::ipc::IPCResult ContentParent::RecvSetFocusedElement(
("ParentIPC: Trying to send a message to dead or detached context"));
return IPC_OK();
}
LOGFOCUS(("ContentParent::RecvSetFocusedElement"));
CanonicalBrowsingContext* context = aContext.get_canonical();
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
@ -6995,6 +7007,7 @@ mozilla::ipc::IPCResult ContentParent::RecvFinalizeFocusOuter(
("ParentIPC: Trying to send a message to dead or detached context"));
return IPC_OK();
}
LOGFOCUS(("ContentParent::RecvFinalizeFocusOuter"));
CanonicalBrowsingContext* context = aContext.get_canonical();
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
@ -7008,6 +7021,8 @@ mozilla::ipc::IPCResult ContentParent::RecvFinalizeFocusOuter(
mozilla::ipc::IPCResult ContentParent::RecvInsertNewFocusActionId(
uint64_t aActionId) {
LOGFOCUS(
("ContentParent::RecvInsertNewFocusActionId actionid: %lu", aActionId));
nsFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
fm->InsertNewFocusActionId(aActionId);
@ -7029,6 +7044,13 @@ mozilla::ipc::IPCResult ContentParent::RecvBlurToParent(
return IPC_OK();
}
LOGFOCUS(
("ContentParent::RecvBlurToParent isLeavingDocument %d adjustWidget %d "
"browsingContextToClearHandled %d ancestorBrowsingContextToFocusHandled "
"%d actionid: %lu",
aIsLeavingDocument, aAdjustWidget, aBrowsingContextToClearHandled,
aAncestorBrowsingContextToFocusHandled, aActionId));
CanonicalBrowsingContext* focusedBrowsingContext =
aFocusedBrowsingContext.get_canonical();

Просмотреть файл

@ -0,0 +1,20 @@
<!doctype html>
<meta charset=utf-8>
<title>Focus already focused iframe</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
setup({explicit_done:true});
var w = null;
window.onload = function() {
window.onmessage = function(e) {
test(function() {
assert_equals(e.data, "PASS", 'Check result');
}, "Check result");
w.close();
w = null;
done();
};
w = window.open("support/focus-already-focused-iframe-deep-different-site-outer.sub.html");
}
</script>

Просмотреть файл

@ -0,0 +1,20 @@
<!doctype html>
<meta charset=utf-8>
<title>Focus already focused iframe</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
setup({explicit_done:true});
var w = null;
window.onload = function() {
window.onmessage = function(e) {
test(function() {
assert_equals(e.data, "PASS", 'Check result');
}, "Check result");
w.close();
w = null;
done();
};
w = window.open("support/focus-already-focused-iframe-deep-same-site-outer.html");
}
</script>

Просмотреть файл

@ -0,0 +1,20 @@
<!doctype html>
<meta charset=utf-8>
<title>Focus already focused iframe</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
setup({explicit_done:true});
var w = null;
window.onload = function() {
window.onmessage = function(e) {
test(function() {
assert_equals(e.data, "PASS", 'Check result');
}, "Check result");
w.close();
w = null;
done();
};
w = window.open("support/focus-already-focused-iframe-different-site-outer.sub.html");
}
</script>

Просмотреть файл

@ -0,0 +1,20 @@
<!doctype html>
<meta charset=utf-8>
<title>Focus already focused iframe</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
setup({explicit_done:true});
var w = null;
window.onload = function() {
window.onmessage = function(e) {
test(function() {
assert_equals(e.data, "PASS", 'Check result');
}, "Check result");
w.close();
w = null;
done();
};
w = window.open("support/focus-already-focused-iframe-same-site-outer.html");
}
</script>

Просмотреть файл

@ -0,0 +1,21 @@
<!doctype html>
<meta charset="utf-8">
<title>Focus already focused iframe</title>
<script>
let failed = false;
window.onmessage = function(e) {
if (e.data == "focus") {
document.getElementsByTagName("iframe")[0].focus();
opener.step_timeout(function() {
if (failed) {
opener.postMessage("FAIL", "*");
} else {
opener.postMessage("PASS", "*");
}
}, 1500);
} else if (e.data == "FAIL") {
failed = true;
}
}
</script>
<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/focus-already-focused-iframe-middle.html"></iframe>

Просмотреть файл

@ -0,0 +1,21 @@
<!doctype html>
<meta charset="utf-8">
<title>Focus already focused iframe</title>
<script>
let failed = false;
window.onmessage = function(e) {
if (e.data == "focus") {
document.getElementsByTagName("iframe")[0].focus();
opener.step_timeout(function() {
if (failed) {
opener.postMessage("FAIL", "*");
} else {
opener.postMessage("PASS", "*");
}
}, 1500);
} else if (e.data == "FAIL") {
failed = true;
}
}
</script>
<iframe src="focus-already-focused-iframe-middle.html"></iframe>

Просмотреть файл

@ -0,0 +1,21 @@
<!doctype html>
<meta charset="utf-8">
<title>Focus already focused iframe</title>
<script>
let failed = false;
window.onmessage = function(e) {
if (e.data == "focus") {
document.getElementsByTagName("iframe")[0].focus();
opener.step_timeout(function() {
if (failed) {
opener.postMessage("FAIL", "*");
} else {
opener.postMessage("PASS", "*");
}
}, 1500);
} else if (e.data == "FAIL") {
failed = true;
}
}
</script>
<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/focus-already-focused-iframe-inner.html"></iframe>

Просмотреть файл

@ -0,0 +1,18 @@
<!doctype html>
<meta charset="utf-8">
<title>Focus already focused iframe</title>
<script>
let haveGottenFocus = false;
function gotFocus() {
if (haveGottenFocus) {
parent.postMessage("FAIL", "*");
} else {
haveGottenFocus = true;
parent.postMessage("focus", "*");
}
}
window.onload = function() {
document.getElementsByTagName("input")[0].focus();
}
</script>
<input onfocus="gotFocus();">

Просмотреть файл

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Middle</title>
<script>
window.onmessage = function(e) {
parent.postMessage(e.data, "*");
}
</script>
</head>
<body>
<iframe src="focus-already-focused-iframe-inner.html"></iframe>
</body>
</html>

Просмотреть файл

@ -0,0 +1,21 @@
<!doctype html>
<meta charset="utf-8">
<title>Focus already focused iframe</title>
<script>
let failed = false;
window.onmessage = function(e) {
if (e.data == "focus") {
document.getElementsByTagName("iframe")[0].focus();
opener.step_timeout(function() {
if (failed) {
opener.postMessage("FAIL", "*");
} else {
opener.postMessage("PASS", "*");
}
}, 1500);
} else if (e.data == "FAIL") {
failed = true;
}
}
</script>
<iframe src="focus-already-focused-iframe-inner.html"></iframe>