Skip to content
Permalink
Browse files
REGRESSION (r195605): ASSERTION FAILED: !NoEventDispatchAssertion::is…
…EventDispatchForbidden()

when pressing the back button on a page with a focused subframe
https://bugs.webkit.org/show_bug.cgi?id=156033
<rdar://problem/25446561>

Reviewed by Chris Dumez.

Source/WebCore:

Fixes an assertion failure when navigating back, by pressing the browser back button, to
the previous page from a page with a focused subframe.

Following r195605 (https://bugs.webkit.org/show_bug.cgi?id=153449), the responsibility for
dispatching a DOM pagehide event moved from CachedFrame to PageCache and we now instantiate
a NoEventDispatchAssertion object to enforce the invariant that no additional DOM events are
dispatched as part of adding a page to the page cache. When adding a page with a focused
subframe to the page cache we focus its main frame, which implicitly defocuses the subframe
and dispatches a DOM blur event at it. Therefore an assertion failure occurs when dispatching
this DOM blur event (because a NoEventDispatchAssertion object was allocated on the stack).

Test: fast/history/back-from-page-with-focused-iframe.html

* history/CachedFrame.cpp:
(WebCore::CachedFrame::CachedFrame): Move logic to focus the main frame from here...
* history/PageCache.cpp:
(WebCore::PageCache::addIfCacheable): to here such that any DOM blur and focus events
are dispatched before instantiate the NoEventDispatchAssertion object and enter the page
cache.

LayoutTests:

Add a test to ensure that when navigating back from a page with a focused <iframe> f, a DOM
blur event is dispatched to f, a DOM focus event is dispatched at the main frame and that
an assertion failure does not occur (only applicable in a debug build).

* fast/history/back-from-page-with-focused-iframe-expected.txt: Added.
* fast/history/back-from-page-with-focused-iframe.html: Added.

Canonical link: https://commits.webkit.org/174211@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198924 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
dydz committed Mar 31, 2016
1 parent cb564fc commit 6da141754928a0c16f8b0d1b35b1824aeb371b9a
Showing 6 changed files with 106 additions and 4 deletions.
@@ -1,3 +1,19 @@
2016-03-31 Daniel Bates <dabates@apple.com>

REGRESSION (r195605): ASSERTION FAILED: !NoEventDispatchAssertion::isEventDispatchForbidden()
when pressing the back button on a page with a focused subframe
https://bugs.webkit.org/show_bug.cgi?id=156033
<rdar://problem/25446561>

Reviewed by Chris Dumez.

Add a test to ensure that when navigating back from a page with a focused <iframe> f, a DOM
blur event is dispatched to f, a DOM focus event is dispatched at the main frame and that
an assertion failure does not occur (only applicable in a debug build).

* fast/history/back-from-page-with-focused-iframe-expected.txt: Added.
* fast/history/back-from-page-with-focused-iframe.html: Added.

2016-03-31 Chris Dumez <cdumez@apple.com>

REGRESSION (r191180): Safari does not send Referer Header to iframe src in certain situations
@@ -0,0 +1,9 @@
ALERT: /iframe blurred/
ALERT: /main frame focused/
This test PASSED if there is no assertion failure and you see two JavaScript alerts with messages "iframe blurred" and "main frame focused" in order. Otherwise, it FAILED.

============== Back Forward List ==============
curr-> (file test):fast/history/back-from-page-with-focused-iframe.html **nav target**
data:text/html,<!DOCTYPE html><html><iframe srcdoc="<script> window.onfocus = function() { window.onblur = function () { alert(/iframe blurred/); }; window.top.onfocus = function () { alert(/main frame focused/); }; window.top.history.back(); }; window.focus(); </script>"></iframe></html> **nav target**
about:srcdoc (in frame "<!--framePath //<!--frame0-->-->")
===============================================
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<script>
function runTest()
{
var test = [
'<!DOCTYPE html>',
'<html>',
'<iframe srcdoc="<script>',
' window.onfocus = function() {',
' window.onblur = function () { alert(/iframe blurred/); };',
' window.top.onfocus = function () { alert(/main frame focused/); };',
' window.top.history.back();',
' };',
' window.focus();',
' <' + '/script>">',
'</iframe>',
'</html>',
].join("");
window.location.href = "data:text/html," + test;
}

window.onpageshow = function (pageTransitionEvent)
{
if (pageTransitionEvent.persisted) {
// Navigated back to this page
if (window.testRunner)
testRunner.notifyDone();
} else {
// Newly loaded
if (window.testRunner) {
testRunner.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
testRunner.dumpAsText();
testRunner.dumpBackForwardList();
testRunner.waitUntilDone();
}
window.setTimeout(runTest, 0); // Navigate on a zero timer to create a history entry.
}
}
</script>
</head>
<body>
<p>This test PASSED if there is no assertion failure and you see two JavaScript alerts with messages &quot;iframe blurred&quot; and &quot;main frame focused&quot; in order. Otherwise, it FAILED.</p>
</body>
</html>
@@ -1,3 +1,32 @@
2016-03-31 Daniel Bates <dabates@apple.com>

REGRESSION (r195605): ASSERTION FAILED: !NoEventDispatchAssertion::isEventDispatchForbidden()
when pressing the back button on a page with a focused subframe
https://bugs.webkit.org/show_bug.cgi?id=156033
<rdar://problem/25446561>

Reviewed by Chris Dumez.

Fixes an assertion failure when navigating back, by pressing the browser back button, to
the previous page from a page with a focused subframe.

Following r195605 (https://bugs.webkit.org/show_bug.cgi?id=153449), the responsibility for
dispatching a DOM pagehide event moved from CachedFrame to PageCache and we now instantiate
a NoEventDispatchAssertion object to enforce the invariant that no additional DOM events are
dispatched as part of adding a page to the page cache. When adding a page with a focused
subframe to the page cache we focus its main frame, which implicitly defocuses the subframe
and dispatches a DOM blur event at it. Therefore an assertion failure occurs when dispatching
this DOM blur event (because a NoEventDispatchAssertion object was allocated on the stack).

Test: fast/history/back-from-page-with-focused-iframe.html

* history/CachedFrame.cpp:
(WebCore::CachedFrame::CachedFrame): Move logic to focus the main frame from here...
* history/PageCache.cpp:
(WebCore::PageCache::addIfCacheable): to here such that any DOM blur and focus events
are dispatched before instantiate the NoEventDispatchAssertion object and enter the page
cache.

2016-03-31 Chris Dumez <cdumez@apple.com>

REGRESSION (r191180): Safari does not send Referer Header to iframe src in certain situations
@@ -33,7 +33,6 @@
#include "DocumentLoader.h"
#include "EventNames.h"
#include "ExceptionCode.h"
#include "FocusController.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "FrameView.h"
@@ -147,9 +146,6 @@ CachedFrame::CachedFrame(Frame& frame)
ASSERT(m_documentLoader);
ASSERT(m_view);

if (frame.page()->focusController().focusedFrame() == &frame)
frame.page()->focusController().setFocusedFrame(&frame.mainFrame());

// Custom scrollbar renderers will get reattached when the document comes out of the page cache
m_view->detachCustomScrollbars();

@@ -37,6 +37,7 @@
#include "DiagnosticLoggingKeys.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "FocusController.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "FrameView.h"
@@ -392,6 +393,11 @@ void PageCache::addIfCacheable(HistoryItem& item, Page* page)
// Make sure all the documents know they are being added to the PageCache.
setInPageCache(*page, true);

// Focus the main frame, defocusing a focused subframe (if we have one). We do this here,
// before the page enters the page cache, while we still can dispatch DOM blur/focus events.
if (page->focusController().focusedFrame())
page->focusController().setFocusedFrame(&page->mainFrame());

// Fire the pagehide event in all frames.
firePageHideEventRecursively(page->mainFrame());

0 comments on commit 6da1417

Please sign in to comment.