1 /*
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3 * 1999 Lars Knoll <knoll@kde.org>
4 * 1999 Antti Koivisto <koivisto@kde.org>
5 * 2000 Simon Hausmann <hausmann@kde.org>
6 * 2000 Stefan Schimanski <1Stein@gmx.de>
7 * 2001 George Staikos <staikos@kde.org>
8 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
9 * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
10 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
11 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
12 * Copyright (C) 2008 Google Inc.
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Library General Public
16 * License as published by the Free Software Foundation; either
17 * version 2 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public License
25 * along with this library; see the file COPYING.LIB. If not, write to
26 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 * Boston, MA 02110-1301, USA.
28 */
29
30 #include "config.h"
31 #include "core/frame/Frame.h"
32
33 #include "core/dom/DocumentType.h"
34 #include "core/events/Event.h"
35 #include "core/frame/LocalDOMWindow.h"
36 #include "core/frame/FrameDestructionObserver.h"
37 #include "core/frame/FrameHost.h"
38 #include "core/frame/Settings.h"
39 #include "core/html/HTMLFrameElementBase.h"
40 #include "core/inspector/InspectorInstrumentation.h"
41 #include "core/loader/EmptyClients.h"
42 #include "core/loader/FrameLoaderClient.h"
43 #include "core/page/Chrome.h"
44 #include "core/page/ChromeClient.h"
45 #include "core/page/EventHandler.h"
46 #include "core/page/FocusController.h"
47 #include "core/page/Page.h"
48 #include "core/rendering/RenderPart.h"
49 #include "public/platform/WebLayer.h"
50 #include "wtf/PassOwnPtr.h"
51 #include "wtf/RefCountedLeakCounter.h"
52
53 namespace WebCore {
54
55 using namespace HTMLNames;
56
57 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, frameCounter, ("Frame"));
58
Frame(FrameClient * client,FrameHost * host,FrameOwner * owner)59 Frame::Frame(FrameClient* client, FrameHost* host, FrameOwner* owner)
60 : m_treeNode(this)
61 , m_host(host)
62 , m_owner(owner)
63 , m_client(client)
64 , m_remotePlatformLayer(0)
65 {
66 ASSERT(page());
67
68 #ifndef NDEBUG
69 frameCounter.increment();
70 #endif
71
72 if (m_owner) {
73 page()->incrementSubframeCount();
74 if (m_owner->isLocal())
75 toHTMLFrameOwnerElement(m_owner)->setContentFrame(*this);
76 } else {
77 page()->setMainFrame(this);
78 }
79 }
80
~Frame()81 Frame::~Frame()
82 {
83 disconnectOwnerElement();
84 setDOMWindow(nullptr);
85
86 // FIXME: We should not be doing all this work inside the destructor
87
88 #ifndef NDEBUG
89 frameCounter.decrement();
90 #endif
91
92 HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
93 for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
94 (*it)->frameDestroyed();
95 }
96
addDestructionObserver(FrameDestructionObserver * observer)97 void Frame::addDestructionObserver(FrameDestructionObserver* observer)
98 {
99 m_destructionObservers.add(observer);
100 }
101
removeDestructionObserver(FrameDestructionObserver * observer)102 void Frame::removeDestructionObserver(FrameDestructionObserver* observer)
103 {
104 m_destructionObservers.remove(observer);
105 }
106
host() const107 FrameHost* Frame::host() const
108 {
109 return m_host;
110 }
111
page() const112 Page* Frame::page() const
113 {
114 if (m_host)
115 return &m_host->page();
116 return 0;
117 }
118
settings() const119 Settings* Frame::settings() const
120 {
121 if (m_host)
122 return &m_host->settings();
123 return 0;
124 }
125
setDOMWindow(PassRefPtrWillBeRawPtr<LocalDOMWindow> domWindow)126 void Frame::setDOMWindow(PassRefPtrWillBeRawPtr<LocalDOMWindow> domWindow)
127 {
128 if (m_domWindow)
129 m_domWindow->reset();
130 m_domWindow = domWindow;
131 }
132
emptyChromeClient()133 static ChromeClient& emptyChromeClient()
134 {
135 DEFINE_STATIC_LOCAL(EmptyChromeClient, client, ());
136 return client;
137 }
138
chromeClient() const139 ChromeClient& Frame::chromeClient() const
140 {
141 if (Page* page = this->page())
142 return page->chrome().client();
143 return emptyChromeClient();
144 }
145
ownerRenderer() const146 RenderPart* Frame::ownerRenderer() const
147 {
148 if (!deprecatedLocalOwner())
149 return 0;
150 RenderObject* object = deprecatedLocalOwner()->renderer();
151 if (!object)
152 return 0;
153 // FIXME: If <object> is ever fixed to disassociate itself from frames
154 // that it has started but canceled, then this can turn into an ASSERT
155 // since ownerElement() would be 0 when the load is canceled.
156 // https://bugs.webkit.org/show_bug.cgi?id=18585
157 if (!object->isRenderPart())
158 return 0;
159 return toRenderPart(object);
160 }
161
162
willDetachFrameHost()163 void Frame::willDetachFrameHost()
164 {
165 HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
166 for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
167 (*it)->willDetachFrameHost();
168
169 // FIXME: Page should take care of updating focus/scrolling instead of Frame.
170 // FIXME: It's unclear as to why this is called more than once, but it is,
171 // so page() could be null.
172 if (page() && page()->focusController().focusedFrame() == this)
173 page()->focusController().setFocusedFrame(nullptr);
174 }
175
detachFromFrameHost()176 void Frame::detachFromFrameHost()
177 {
178 m_host = 0;
179 }
180
isMainFrame() const181 bool Frame::isMainFrame() const
182 {
183 Page* page = this->page();
184 return page && this == page->mainFrame();
185 }
186
disconnectOwnerElement()187 void Frame::disconnectOwnerElement()
188 {
189 if (m_owner) {
190 if (m_owner->isLocal())
191 toHTMLFrameOwnerElement(m_owner)->clearContentFrame();
192 if (page())
193 page()->decrementSubframeCount();
194 }
195 m_owner = 0;
196 }
197
deprecatedLocalOwner() const198 HTMLFrameOwnerElement* Frame::deprecatedLocalOwner() const
199 {
200 return m_owner && m_owner->isLocal() ? toHTMLFrameOwnerElement(m_owner) : 0;
201 }
202
203 } // namespace WebCore
204