Commit 33e547db authored by japhet@chromium.org's avatar japhet@chromium.org

Prepare for remote->local frame swap

The plan is to create a LocalFrame that is loosely tied to an existing RemoteFrame but is not really attached to the FrameTree. The LocalFrame will begin loading, and when it commits, it will be swapped into where the RemotFrame was. This adds sufficient logic to actually support that swap (and to maintain the intermediate semi-attached state while the LocalFrame is provisional).

BUG=422583

Review URL: https://codereview.chromium.org/643333002

git-svn-id: svn://svn.chromium.org/blink/trunk@183908 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent bd46e33c
......@@ -76,6 +76,7 @@ public:
virtual void disconnectOwnerElement();
FrameOwner* owner() const;
void setOwner(FrameOwner* owner) { m_owner = owner; }
HTMLFrameOwnerElement* deprecatedLocalOwner() const;
// FIXME: LocalDOMWindow and Document should both be moved to LocalFrame
......
......@@ -42,10 +42,6 @@ bool WebFrame::swap(WebFrame* frame)
if (!oldFrame->host())
return false;
// The frame being swapped in should not have a Frame associated
// with it yet.
ASSERT(!toCoreFrame(frame));
if (m_parent) {
if (m_parent->m_firstChild == this)
m_parent->m_firstChild = frame;
......@@ -79,7 +75,11 @@ bool WebFrame::swap(WebFrame* frame)
// increments of connected subframes.
FrameOwner* owner = oldFrame->owner();
oldFrame->disconnectOwnerElement();
if (frame->isWebLocalFrame()) {
if (toCoreFrame(frame)) {
ASSERT(owner == toCoreFrame(frame)->owner());
if (owner->isLocal())
toHTMLFrameOwnerElement(owner)->setContentFrame(*toCoreFrame(frame));
} else if (frame->isWebLocalFrame()) {
toWebLocalFrameImpl(frame)->initializeCoreFrame(oldFrame->host(), owner, oldFrame->tree().name(), nullAtom);
} else {
toWebRemoteFrameImpl(frame)->initializeCoreFrame(oldFrame->host(), owner, oldFrame->tree().name());
......@@ -146,6 +146,11 @@ void WebFrame::removeChild(WebFrame* child)
toCoreFrame(this)->host()->decrementSubframeCount();
}
void WebFrame::setParent(WebFrame* parent)
{
m_parent = parent;
}
WebFrame* WebFrame::parent() const
{
return m_parent;
......
......@@ -205,6 +205,7 @@
#include "web/WebDataSourceImpl.h"
#include "web/WebDevToolsAgentPrivate.h"
#include "web/WebPluginContainerImpl.h"
#include "web/WebRemoteFrameImpl.h"
#include "web/WebViewImpl.h"
#include "wtf/CurrentTime.h"
#include "wtf/HashMap.h"
......@@ -1800,6 +1801,20 @@ void WebLocalFrameImpl::loadJavaScriptURL(const KURL& url)
frame()->loader().replaceDocumentWhileExecutingJavaScriptURL(scriptResult, ownerDocument.get());
}
void WebLocalFrameImpl::initializeToReplaceRemoteFrame(WebRemoteFrame* oldWebFrame)
{
Frame* oldFrame = toCoreFrame(oldWebFrame);
OwnPtr<FrameOwner> tempOwner = adoptPtr(new PlaceholderFrameOwner());
m_frame = LocalFrame::create(&m_frameLoaderClientImpl, oldFrame->host(), tempOwner.get());
m_frame->setOwner(oldFrame->owner());
m_frame->tree().setName(oldFrame->tree().name());
setParent(oldWebFrame->parent());
// We must call init() after m_frame is assigned because it is referenced
// during init(). Note that this may dispatch JS events; the frame may be
// detached after init() returns.
m_frame->init();
}
void WebLocalFrameImpl::sendPings(const WebNode& linkNode, const WebURL& destinationURL)
{
ASSERT(frame());
......
......@@ -221,6 +221,7 @@ public:
virtual WebString layerTreeAsText(bool showDebugInfo = false) const override;
// WebLocalFrame methods:
virtual void initializeToReplaceRemoteFrame(WebRemoteFrame*) override;
virtual void sendPings(const WebNode& linkNode, const WebURL& destinationURL) override;
virtual bool isLoading() const override;
virtual bool isResourceLoadInProgress() const override;
......
......@@ -5,7 +5,6 @@
#include "config.h"
#include "web/WebRemoteFrameImpl.h"
#include "core/frame/FrameOwner.h"
#include "core/frame/FrameView.h"
#include "core/frame/RemoteFrame.h"
#include "core/frame/Settings.h"
......@@ -76,20 +75,7 @@ void RemoteBridgeFrameOwner::dispatchLoad()
// FIXME: Implement. Most likely goes through m_frame->client().
}
// FIXME: This is just a placeholder frame owner to supply to RemoteFrame when
// the parent is also a remote frame. Strictly speaking, this shouldn't be
// necessary, since a remote frame shouldn't ever need to communicate with a
// remote parent (there are no sandbox flags to retrieve in this case, nor can
// the RemoteFrame itself load a document). In most circumstances, the check for
// frame->owner() can be replaced with a check for frame->tree().parent(). Once
// that's done, this class can be removed.
class PlaceholderFrameOwner : public NoBaseWillBeGarbageCollectedFinalized<PlaceholderFrameOwner>, public FrameOwner {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(PlaceholderFrameOwner);
public:
virtual bool isLocal() const override;
virtual SandboxFlags sandboxFlags() const override;
virtual void dispatchLoad() override;
};
} // namespace
bool PlaceholderFrameOwner::isLocal() const
{
......@@ -98,17 +84,13 @@ bool PlaceholderFrameOwner::isLocal() const
SandboxFlags PlaceholderFrameOwner::sandboxFlags() const
{
ASSERT_NOT_REACHED();
return 0;
}
void PlaceholderFrameOwner::dispatchLoad()
{
ASSERT_NOT_REACHED();
}
} // namespace
WebRemoteFrame* WebRemoteFrame::create(WebRemoteFrameClient* client)
{
WebRemoteFrameImpl* frame = new WebRemoteFrameImpl(client);
......
......@@ -5,6 +5,7 @@
#ifndef WebRemoteFrameImpl_h
#define WebRemoteFrameImpl_h
#include "core/frame/FrameOwner.h"
#include "platform/heap/Handle.h"
#include "public/web/WebRemoteFrame.h"
#include "public/web/WebRemoteFrameClient.h"
......@@ -20,6 +21,21 @@ class FrameOwner;
class RemoteFrame;
class WebViewImpl;
// FIXME: This is just a placeholder frame owner to supply to RemoteFrame when
// the parent is also a remote frame. Strictly speaking, this shouldn't be
// necessary, since a remote frame shouldn't ever need to communicate with a
// remote parent (there are no sandbox flags to retrieve in this case, nor can
// the RemoteFrame itself load a document). In most circumstances, the check for
// frame->owner() can be replaced with a check for frame->tree().parent(). Once
// that's done, this class can be removed.
class PlaceholderFrameOwner : public NoBaseWillBeGarbageCollectedFinalized<PlaceholderFrameOwner>, public FrameOwner {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(PlaceholderFrameOwner);
public:
virtual bool isLocal() const override;
virtual SandboxFlags sandboxFlags() const override;
virtual void dispatchLoad() override;
};
class WebRemoteFrameImpl final : public RefCountedWillBeGarbageCollectedFinalized<WebRemoteFrameImpl>, public WebRemoteFrame {
public:
explicit WebRemoteFrameImpl(WebRemoteFrameClient*);
......
......@@ -667,6 +667,12 @@ protected:
WebFrame();
virtual ~WebFrame();
// Sets the parent WITHOUT fulling adding it to the frame tree.
// Used to lie to a local frame that is replacing a remote frame,
// so it can properly start a navigation but wait to swap until
// commit-time.
void setParent(WebFrame*);
private:
friend class OpenedFrameTracker;
......
......@@ -32,6 +32,13 @@ public:
// the given element is not a frame, iframe or if the frame is empty.
BLINK_EXPORT static WebLocalFrame* fromFrameOwnerElement(const WebElement&);
// Initialization ---------------------------------------------------------
// Used when we might swap from a remote frame to a local frame.
// Creates a provisional, semi-attached frame that will be fully
// swapped into the frame tree if it commits.
virtual void initializeToReplaceRemoteFrame(WebRemoteFrame*) = 0;
// Navigation Ping --------------------------------------------------------
virtual void sendPings(const WebNode& linkNode, const WebURL& destinationURL) = 0;
......
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