• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "WebFrameProxy.h"
28 
29 #include "WebCertificateInfo.h"
30 #include "WebContext.h"
31 #include "WebFormSubmissionListenerProxy.h"
32 #include "WebFramePolicyListenerProxy.h"
33 #include "WebPageMessages.h"
34 #include "WebPageProxy.h"
35 #include <WebCore/DOMImplementation.h>
36 #include <WebCore/Image.h>
37 #include <wtf/text/WTFString.h>
38 
39 using namespace WebCore;
40 using namespace std;
41 
42 namespace WebKit {
43 
WebFrameProxy(WebPageProxy * page,uint64_t frameID)44 WebFrameProxy::WebFrameProxy(WebPageProxy* page, uint64_t frameID)
45     : m_page(page)
46     , m_parentFrame(0)
47     , m_nextSibling(0)
48     , m_previousSibling(0)
49     , m_firstChild(0)
50     , m_lastChild(0)
51     , m_loadState(LoadStateFinished)
52     , m_isFrameSet(false)
53     , m_frameID(frameID)
54 {
55     WebContext::statistics().wkFrameCount++;
56 }
57 
~WebFrameProxy()58 WebFrameProxy::~WebFrameProxy()
59 {
60     WebContext::statistics().wkFrameCount--;
61 }
62 
disconnect()63 void WebFrameProxy::disconnect()
64 {
65     m_page = 0;
66     m_parentFrame = 0;
67     m_nextSibling = 0;
68     m_previousSibling = 0;
69     m_firstChild = 0;
70     m_lastChild = 0;
71 
72     if (m_activeListener) {
73         m_activeListener->invalidate();
74         m_activeListener = 0;
75     }
76 }
77 
isMainFrame() const78 bool WebFrameProxy::isMainFrame() const
79 {
80     if (!m_page)
81         return false;
82 
83     return this == m_page->mainFrame();
84 }
85 
stopLoading() const86 void WebFrameProxy::stopLoading() const
87 {
88     if (!m_page)
89         return;
90 
91     if (!m_page->isValid())
92         return;
93 
94     m_page->process()->send(Messages::WebPage::StopLoadingFrame(m_frameID), m_page->pageID());
95 }
96 
canProvideSource() const97 bool WebFrameProxy::canProvideSource() const
98 {
99     return isDisplayingMarkupDocument();
100 }
101 
canShowMIMEType(const String & mimeType) const102 bool WebFrameProxy::canShowMIMEType(const String& mimeType) const
103 {
104     if (!m_page)
105         return false;
106 
107     if (m_page->canShowMIMEType(mimeType))
108         return true;
109 
110 #if PLATFORM(MAC)
111     // On Mac, we can show PDFs in the main frame.
112     if (isMainFrame() && !mimeType.isEmpty())
113         return WebContext::pdfAndPostScriptMIMETypes().contains(mimeType);
114 #endif
115 
116     return false;
117 }
118 
isDisplayingStandaloneImageDocument() const119 bool WebFrameProxy::isDisplayingStandaloneImageDocument() const
120 {
121     return Image::supportsType(m_MIMEType);
122 }
123 
isDisplayingMarkupDocument() const124 bool WebFrameProxy::isDisplayingMarkupDocument() const
125 {
126     // FIXME: This check should be moved to somewhere in WebCore.
127     // FIXME: This returns false when displaying a web archive.
128     return m_MIMEType == "text/html" || m_MIMEType == "image/svg+xml" || DOMImplementation::isXMLMIMEType(m_MIMEType);
129 }
130 
didStartProvisionalLoad(const String & url)131 void WebFrameProxy::didStartProvisionalLoad(const String& url)
132 {
133     ASSERT(m_loadState == LoadStateFinished);
134     ASSERT(m_provisionalURL.isEmpty());
135     m_loadState = LoadStateProvisional;
136     m_provisionalURL = url;
137 }
138 
didReceiveServerRedirectForProvisionalLoad(const String & url)139 void WebFrameProxy::didReceiveServerRedirectForProvisionalLoad(const String& url)
140 {
141     ASSERT(m_loadState == LoadStateProvisional);
142     m_provisionalURL = url;
143 }
144 
didFailProvisionalLoad()145 void WebFrameProxy::didFailProvisionalLoad()
146 {
147     ASSERT(m_loadState == LoadStateProvisional);
148     m_loadState = LoadStateFinished;
149     m_provisionalURL = String();
150 }
151 
didCommitLoad(const String & contentType,const PlatformCertificateInfo & certificateInfo)152 void WebFrameProxy::didCommitLoad(const String& contentType, const PlatformCertificateInfo& certificateInfo)
153 {
154     ASSERT(m_loadState == LoadStateProvisional);
155     m_loadState = LoadStateCommitted;
156     m_url = m_provisionalURL;
157     m_provisionalURL = String();
158     m_title = String();
159     m_MIMEType = contentType;
160     m_isFrameSet = false;
161     m_certificateInfo = WebCertificateInfo::create(certificateInfo);
162 }
163 
didFinishLoad()164 void WebFrameProxy::didFinishLoad()
165 {
166     ASSERT(m_loadState == LoadStateCommitted);
167     ASSERT(m_provisionalURL.isEmpty());
168     m_loadState = LoadStateFinished;
169 }
170 
didFailLoad()171 void WebFrameProxy::didFailLoad()
172 {
173     ASSERT(m_loadState == LoadStateCommitted);
174     ASSERT(m_provisionalURL.isEmpty());
175     m_loadState = LoadStateFinished;
176     m_title = String();
177 }
178 
didSameDocumentNavigation(const String & url)179 void WebFrameProxy::didSameDocumentNavigation(const String& url)
180 {
181     m_url = url;
182 }
183 
didChangeTitle(const String & title)184 void WebFrameProxy::didChangeTitle(const String& title)
185 {
186     m_title = title;
187 }
188 
appendChild(WebFrameProxy * child)189 void WebFrameProxy::appendChild(WebFrameProxy* child)
190 {
191     ASSERT(child->page() == page());
192     ASSERT(!child->m_parentFrame);
193     ASSERT(!child->m_nextSibling);
194     ASSERT(!child->m_previousSibling);
195 
196     child->m_parentFrame = this;
197 
198     WebFrameProxy* oldLast = m_lastChild;
199     m_lastChild = child;
200 
201     if (oldLast) {
202         ASSERT(!oldLast->m_nextSibling);
203         child->m_previousSibling = oldLast;
204         oldLast->m_nextSibling = child;
205     } else
206         m_firstChild = child;
207 }
208 
removeChild(WebFrameProxy * child)209 void WebFrameProxy::removeChild(WebFrameProxy* child)
210 {
211     child->m_parentFrame = 0;
212 
213     WebFrameProxy*& newLocationForNext = m_firstChild == child ? m_firstChild : child->m_previousSibling->m_nextSibling;
214     WebFrameProxy*& newLocationForPrevious = m_lastChild == child ? m_lastChild : child->m_nextSibling->m_previousSibling;
215     swap(newLocationForNext, child->m_nextSibling);
216     swap(newLocationForPrevious, child->m_previousSibling);
217     child->m_previousSibling = 0;
218     child->m_nextSibling = 0;
219 }
220 
isDescendantOf(const WebFrameProxy * ancestor) const221 bool WebFrameProxy::isDescendantOf(const WebFrameProxy* ancestor) const
222 {
223     if (!ancestor)
224         return false;
225 
226     if (m_page != ancestor->m_page)
227         return false;
228 
229     for (const WebFrameProxy* frame = this; frame; frame = frame->m_parentFrame) {
230         if (frame == ancestor)
231             return true;
232     }
233 
234     return false;
235 }
236 
dumpFrameTreeToSTDOUT(unsigned indent)237 void WebFrameProxy::dumpFrameTreeToSTDOUT(unsigned indent)
238 {
239     if (!indent && m_parentFrame)
240         printf("NOTE: Printing subtree.\n");
241 
242     for (unsigned i = 0; i < indent; ++i)
243         printf(" ");
244     printf("| FRAME %d %s\n", (int)m_frameID, m_url.utf8().data());
245 
246     for (WebFrameProxy* child = m_firstChild; child; child = child->m_nextSibling)
247         child->dumpFrameTreeToSTDOUT(indent + 4);
248 }
249 
didRemoveFromHierarchy()250 void WebFrameProxy::didRemoveFromHierarchy()
251 {
252     if (m_parentFrame)
253         m_parentFrame->removeChild(this);
254 }
255 
childFrames()256 PassRefPtr<ImmutableArray> WebFrameProxy::childFrames()
257 {
258     if (!m_firstChild)
259         return ImmutableArray::create();
260 
261     Vector<RefPtr<APIObject> > vector;
262     for (WebFrameProxy* child = m_firstChild; child; child = child->m_nextSibling)
263         vector.append(child);
264 
265     return ImmutableArray::adopt(vector);
266 }
267 
receivedPolicyDecision(WebCore::PolicyAction action,uint64_t listenerID)268 void WebFrameProxy::receivedPolicyDecision(WebCore::PolicyAction action, uint64_t listenerID)
269 {
270     if (!m_page)
271         return;
272 
273     ASSERT(m_activeListener);
274     ASSERT(m_activeListener->listenerID() == listenerID);
275     m_page->receivedPolicyDecision(action, this, listenerID);
276 }
277 
setUpPolicyListenerProxy(uint64_t listenerID)278 WebFramePolicyListenerProxy* WebFrameProxy::setUpPolicyListenerProxy(uint64_t listenerID)
279 {
280     if (m_activeListener)
281         m_activeListener->invalidate();
282     m_activeListener = WebFramePolicyListenerProxy::create(this, listenerID);
283     return static_cast<WebFramePolicyListenerProxy*>(m_activeListener.get());
284 }
285 
setUpFormSubmissionListenerProxy(uint64_t listenerID)286 WebFormSubmissionListenerProxy* WebFrameProxy::setUpFormSubmissionListenerProxy(uint64_t listenerID)
287 {
288     if (m_activeListener)
289         m_activeListener->invalidate();
290     m_activeListener = WebFormSubmissionListenerProxy::create(this, listenerID);
291     return static_cast<WebFormSubmissionListenerProxy*>(m_activeListener.get());
292 }
293 
getWebArchive(PassRefPtr<DataCallback> callback)294 void WebFrameProxy::getWebArchive(PassRefPtr<DataCallback> callback)
295 {
296     if (!m_page) {
297         callback->invalidate();
298         return;
299     }
300 
301     m_page->getWebArchiveOfFrame(this, callback);
302 }
303 
getMainResourceData(PassRefPtr<DataCallback> callback)304 void WebFrameProxy::getMainResourceData(PassRefPtr<DataCallback> callback)
305 {
306     if (!m_page) {
307         callback->invalidate();
308         return;
309     }
310 
311     m_page->getMainResourceDataOfFrame(this, callback);
312 }
313 
getResourceData(WebURL * resourceURL,PassRefPtr<DataCallback> callback)314 void WebFrameProxy::getResourceData(WebURL* resourceURL, PassRefPtr<DataCallback> callback)
315 {
316     if (!m_page) {
317         callback->invalidate();
318         return;
319     }
320 
321     m_page->getResourceDataFromFrame(this, resourceURL, callback);
322 }
323 
324 } // namespace WebKit
325