Commit d79180bd authored by dimich@chromium.org's avatar dimich@chromium.org

When a live iframe element is moved between pages, it still depends on the old page.

https://bugs.webkit.org/show_bug.cgi?id=34382

Reviewed by David Levin.

WebCore:

Test: fast/frames/iframe-reparenting-new-page.html

* html/HTMLFrameElementBase.cpp:
(WebCore::HTMLFrameElementBase::setName):
Move the code setting the frame name into a separate function.

(WebCore::HTMLFrameElementBase::setNameAndOpenURL):
(WebCore::HTMLFrameElementBase::updateLiveFrame):
Update frame tree, reset page in the contentFrame and re-set the name.

(WebCore::HTMLFrameElementBase::insertedIntoDocument):
* html/HTMLFrameElementBase.h:

* page/Frame.cpp:
(WebCore::Frame::setPage):
* page/Frame.h: Add setPage method. It is only currently used when iframe is
                moved between pages (so the ASSERT(m_ownerElement).

LayoutTests:

* fast/frames/iframe-reparenting-new-page-expected.txt: Added.
* fast/frames/iframe-reparenting-new-page.html: Added.
* fast/frames/resources/iframe-reparenting-new-page-1.html: Added.
* fast/frames/resources/iframe-reparenting-new-page-2.html: Added.
* fast/frames/resources/iframe-reparenting-new-page-iframe.html: Added.

git-svn-id: svn://svn.chromium.org/blink/trunk@54194 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 2a253af3
2010-02-01 Dmitry Titov <dimich@chromium.org>
Reviewed by David Levin.
When a live iframe element is moved between pages, it still depends on the old page.
https://bugs.webkit.org/show_bug.cgi?id=34382
* fast/frames/iframe-reparenting-new-page-expected.txt: Added.
* fast/frames/iframe-reparenting-new-page.html: Added.
* fast/frames/resources/iframe-reparenting-new-page-1.html: Added.
* fast/frames/resources/iframe-reparenting-new-page-2.html: Added.
* fast/frames/resources/iframe-reparenting-new-page-iframe.html: Added.
2010-02-01 Brady Eidson <beidson@apple.com>
Reviewed by Tim Hatcher.
......
The test verifies that the timer in iframe continues firing after iframe is adopted into a new window and the original window was closed.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS successfullyParsed is true
TEST COMPLETE
PASS Loaded iframe in window 1.
PASS iframe.contentWindow.counter is 1
PASS Loaded page 2.
PASS Page 2 adopted the iframe.
PASS Iframe transferred.
PASS iframe.contentWindow.counter is 2
PASS window2.location.href is iframe.contentWindow.parent.location.href
PASS Page 1 is closed.
PASS Received the timer beat from the adopted iframe - exiting.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<link rel="stylesheet" href="../js/resources/js-test-style.css">
<script src="../js/resources/js-test-pre.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script src="script-tests/iframe-reparenting-new-page.js"></script>
<script src="../js/resources/js-test-post.js"></script>
</body>
</html>
<html>
<body>
Page 1<br>
<iframe id="iframe" src="iframe-reparenting-new-page-iframe.html"></iframe>
</body>
</html>
<html>
<script>
window.adoptIframe = function(iframe)
{
document.adoptNode(iframe);
document.body.appendChild(iframe);
opener.testPassed("Page 2 adopted the iframe.")
}
</script>
<body>
Page 2<br>
</body>
</html>
<html>
<script>
window.counter = 0;
function tick()
{
if (window.finish)
finish();
}
function start()
{
window.setInterval(tick, 50);
}
</script>
<body onload="start()">
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<link rel="stylesheet" href="../js/resources/js-test-style.css">
<script src="../js/resources/js-test-pre.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script src="YOUR_JS_FILE_HERE"></script>
<script src="../js/resources/js-test-post.js"></script>
</body>
</html>
description(
"The test verifies that the timer in iframe continues firing after iframe is adopted into a new window and the original window was closed."
);
var window1, iframe, window2;
function finish()
{
testPassed("Received the timer beat from the adopted iframe - exiting.")
window2.close();
if (window.layoutTestController)
layoutTestController.notifyDone();
}
function page1Unloaded()
{
testPassed("Page 1 is closed.");
// Give the iframe a function to call from the timer.
iframe.contentWindow.finish = finish;
}
function transferIframe()
{
testPassed("Loaded page 2.");
window2.adoptIframe(iframe);
testPassed("Iframe transferred.");
iframe.contentWindow.counter++;
shouldBe("iframe.contentWindow.counter", "2");
shouldBe("window2.location.href", "iframe.contentWindow.parent.location.href");
window1.onunload = page1Unloaded;
window1.close();
}
function window1Loaded()
{
iframe = window1.document.getElementById("iframe");
testPassed("Loaded iframe in window 1.");
iframe.contentWindow.counter++;
shouldBe("iframe.contentWindow.counter", "1");
window2 = window.open("iframe-reparenting-new-page-2.html", "_blank");
window2.addEventListener("load", transferIframe, false);
}
if (window.layoutTestController) {
layoutTestController.waitUntilDone();
layoutTestController.setCanOpenWindows();
}
window1 = window.open("resources/iframe-reparenting-new-page-1.html", "_blank");
window1.addEventListener("load", window1Loaded, false);
var successfullyParsed = true;
2010-02-01 Dmitry Titov <dimich@chromium.org>
Reviewed by David Levin.
When a live iframe element is moved between pages, it still depends on the old page.
https://bugs.webkit.org/show_bug.cgi?id=34382
Test: fast/frames/iframe-reparenting-new-page.html
* html/HTMLFrameElementBase.cpp:
(WebCore::HTMLFrameElementBase::setName):
Move the code setting the frame name into a separate function.
(WebCore::HTMLFrameElementBase::setNameAndOpenURL):
(WebCore::HTMLFrameElementBase::updateLiveFrame):
Update frame tree, reset page in the contentFrame and re-set the name.
(WebCore::HTMLFrameElementBase::insertedIntoDocument):
* html/HTMLFrameElementBase.h:
* page/Frame.cpp:
(WebCore::Frame::setPage):
* page/Frame.h: Add setPage method. It is only currently used when iframe is
moved between pages (so the ASSERT(m_ownerElement).
2010-02-01 Brady Eidson <beidson@apple.com>
Reviewed by Tim Hatcher.
......
......@@ -150,7 +150,7 @@ void HTMLFrameElementBase::parseMappedAttribute(MappedAttribute *attr)
HTMLFrameOwnerElement::parseMappedAttribute(attr);
}
void HTMLFrameElementBase::setNameAndOpenURL()
void HTMLFrameElementBase::setName()
{
m_frameName = getAttribute(nameAttr);
if (m_frameName.isNull())
......@@ -158,7 +158,11 @@ void HTMLFrameElementBase::setNameAndOpenURL()
if (Frame* parentFrame = document()->frame())
m_frameName = parentFrame->tree()->uniqueChildName(m_frameName);
}
void HTMLFrameElementBase::setNameAndOpenURL()
{
setName();
openURL();
}
......@@ -167,6 +171,38 @@ void HTMLFrameElementBase::setNameAndOpenURLCallback(Node* n)
static_cast<HTMLFrameElementBase*>(n)->setNameAndOpenURL();
}
// Used when live frame is moved in DOM, potentially to another page.
void HTMLFrameElementBase::updateLiveFrame()
{
ASSERT(m_remainsAliveOnRemovalFromTree);
setName();
Frame* frame = contentFrame();
if (!frame)
return;
// Switch page.
Page* oldPage = frame->page();
Page* newPage = document()->page();
if (oldPage != newPage) {
if (oldPage->focusController()->focusedFrame() == frame)
oldPage->focusController()->setFocusedFrame(0);
frame->setPage(document()->page());
}
// Update the frame tree.
Frame* oldParentFrame = frame->tree()->parent();
Frame* newParentFrame = document()->frame();
if (oldParentFrame != newParentFrame) {
if (oldParentFrame)
oldParentFrame->tree()->removeChild(frame);
if (newParentFrame)
newParentFrame->tree()->appendChild(frame);
}
}
void HTMLFrameElementBase::insertedIntoDocument()
{
HTMLFrameOwnerElement::insertedIntoDocument();
......@@ -175,6 +211,9 @@ void HTMLFrameElementBase::insertedIntoDocument()
// Othewise, a synchronous load that executed JavaScript would see incorrect
// (0) values for the frame's renderer-dependent properties, like width.
m_shouldOpenURLAfterAttach = true;
if (m_remainsAliveOnRemovalFromTree)
updateLiveFrame();
}
void HTMLFrameElementBase::removedFromDocument()
......
......@@ -66,10 +66,12 @@ private:
virtual void willRemove();
void checkAttachedTimerFired(Timer<HTMLFrameElementBase>*);
void updateLiveFrame();
bool viewSourceMode() const { return m_viewSource; }
void setNameAndOpenURL();
void setName();
void openURL();
static void setNameAndOpenURLCallback(Node*);
......
......@@ -1588,6 +1588,22 @@ Page* Frame::page() const
return m_page;
}
void Frame::setPage(Page* page)
{
ASSERT(m_ownerElement);
if (m_page == page)
return;
if (m_page)
m_page->decrementFrameCount();
m_page = page;
if (page)
page->incrementFrameCount();
}
void Frame::detachFromPage()
{
m_page = 0;
......
......@@ -75,6 +75,7 @@ namespace WebCore {
void init();
Page* page() const;
void setPage(Page*);
void detachFromPage();
HTMLFrameOwnerElement* ownerElement() const;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment