1/*
2 * Copyright (C) 2010, 2011 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 "APINavigation.h"
30#include "ProvisionalPageProxy.h"
31#include "WebCertificateInfo.h"
32#include "WebFramePolicyListenerProxy.h"
33#include "WebPageMessages.h"
34#include "WebPageProxy.h"
35#include "WebPasteboardProxy.h"
36#include "WebProcessPool.h"
37#include "WebsiteDataStore.h"
38#include "WebsitePoliciesData.h"
39#include <WebCore/Image.h>
40#include <WebCore/MIMETypeRegistry.h>
41#include <stdio.h>
42#include <wtf/text/WTFString.h>
43
44namespace WebKit {
45using namespace WebCore;
46
47WebFrameProxy::WebFrameProxy(WebPageProxy& page, uint64_t frameID)
48 : m_page(makeWeakPtr(page))
49 , m_isFrameSet(false)
50 , m_frameID(frameID)
51{
52 WebProcessPool::statistics().wkFrameCount++;
53}
54
55WebFrameProxy::~WebFrameProxy()
56{
57 WebProcessPool::statistics().wkFrameCount--;
58#if PLATFORM(GTK)
59 WebPasteboardProxy::singleton().didDestroyFrame(this);
60#endif
61}
62
63void WebFrameProxy::webProcessWillShutDown()
64{
65 m_page = nullptr;
66
67 if (m_activeListener) {
68 m_activeListener->ignore();
69 m_activeListener = nullptr;
70 }
71}
72
73bool WebFrameProxy::isMainFrame() const
74{
75 if (!m_page)
76 return false;
77
78 return this == m_page->mainFrame() || (m_page->provisionalPageProxy() && this == m_page->provisionalPageProxy()->mainFrame());
79}
80
81void WebFrameProxy::loadURL(const URL& url)
82{
83 if (!m_page)
84 return;
85
86 m_page->process().send(Messages::WebPage::LoadURLInFrame(url, m_frameID), m_page->pageID());
87}
88
89void WebFrameProxy::loadData(const IPC::DataReference& data, const String& MIMEType, const String& encodingName, const URL& baseURL)
90{
91 ASSERT(!isMainFrame());
92 if (!m_page)
93 return;
94
95 m_page->process().send(Messages::WebPage::LoadDataInFrame(data, MIMEType, encodingName, baseURL, m_frameID), m_page->pageID());
96}
97
98void WebFrameProxy::stopLoading() const
99{
100 if (!m_page)
101 return;
102
103 if (!m_page->hasRunningProcess())
104 return;
105
106 m_page->process().send(Messages::WebPage::StopLoadingFrame(m_frameID), m_page->pageID());
107}
108
109bool WebFrameProxy::canProvideSource() const
110{
111 return isDisplayingMarkupDocument();
112}
113
114bool WebFrameProxy::canShowMIMEType(const String& mimeType) const
115{
116 if (!m_page)
117 return false;
118
119 return m_page->canShowMIMEType(mimeType);
120}
121
122bool WebFrameProxy::isDisplayingStandaloneImageDocument() const
123{
124 return Image::supportsType(m_MIMEType);
125}
126
127bool WebFrameProxy::isDisplayingStandaloneMediaDocument() const
128{
129 return MIMETypeRegistry::isSupportedMediaMIMEType(m_MIMEType);
130}
131
132bool WebFrameProxy::isDisplayingMarkupDocument() const
133{
134 // FIXME: This should be a call to a single MIMETypeRegistry function; adding a new one if needed.
135 // FIXME: This is doing case sensitive comparisons on MIME types, should be using ASCII case insensitive instead.
136 return m_MIMEType == "text/html" || m_MIMEType == "image/svg+xml" || m_MIMEType == "application/x-webarchive" || MIMETypeRegistry::isXMLMIMEType(m_MIMEType);
137}
138
139bool WebFrameProxy::isDisplayingPDFDocument() const
140{
141 return MIMETypeRegistry::isPDFOrPostScriptMIMEType(m_MIMEType);
142}
143
144void WebFrameProxy::didStartProvisionalLoad(const URL& url)
145{
146 m_frameLoadState.didStartProvisionalLoad(url);
147}
148
149void WebFrameProxy::didExplicitOpen(const URL& url)
150{
151 m_frameLoadState.didExplicitOpen(url);
152}
153
154void WebFrameProxy::didReceiveServerRedirectForProvisionalLoad(const URL& url)
155{
156 m_frameLoadState.didReceiveServerRedirectForProvisionalLoad(url);
157}
158
159void WebFrameProxy::didFailProvisionalLoad()
160{
161 m_frameLoadState.didFailProvisionalLoad();
162}
163
164void WebFrameProxy::didCommitLoad(const String& contentType, WebCertificateInfo& certificateInfo, bool containsPluginDocument)
165{
166 m_frameLoadState.didCommitLoad();
167
168 m_title = String();
169 m_MIMEType = contentType;
170 m_isFrameSet = false;
171 m_certificateInfo = &certificateInfo;
172 m_containsPluginDocument = containsPluginDocument;
173}
174
175void WebFrameProxy::didFinishLoad()
176{
177 m_frameLoadState.didFinishLoad();
178}
179
180void WebFrameProxy::didFailLoad()
181{
182 m_frameLoadState.didFailLoad();
183}
184
185void WebFrameProxy::didSameDocumentNavigation(const URL& url)
186{
187 m_frameLoadState.didSameDocumentNotification(url);
188}
189
190void WebFrameProxy::didChangeTitle(const String& title)
191{
192 m_title = title;
193}
194
195WebFramePolicyListenerProxy& WebFrameProxy::setUpPolicyListenerProxy(CompletionHandler<void(PolicyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&&)>&& completionHandler, ShouldExpectSafeBrowsingResult expect)
196{
197 if (m_activeListener)
198 m_activeListener->ignore();
199 m_activeListener = WebFramePolicyListenerProxy::create([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (PolicyAction action, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning) mutable {
200 completionHandler(action, policies, processSwapRequestedByClient, WTFMove(safeBrowsingWarning));
201 m_activeListener = nullptr;
202 }, expect);
203 return *m_activeListener;
204}
205
206void WebFrameProxy::getWebArchive(Function<void (API::Data*, CallbackBase::Error)>&& callbackFunction)
207{
208 if (!m_page) {
209 callbackFunction(nullptr, CallbackBase::Error::Unknown);
210 return;
211 }
212
213 m_page->getWebArchiveOfFrame(this, WTFMove(callbackFunction));
214}
215
216void WebFrameProxy::getMainResourceData(Function<void (API::Data*, CallbackBase::Error)>&& callbackFunction)
217{
218 if (!m_page) {
219 callbackFunction(nullptr, CallbackBase::Error::Unknown);
220 return;
221 }
222
223 m_page->getMainResourceDataOfFrame(this, WTFMove(callbackFunction));
224}
225
226void WebFrameProxy::getResourceData(API::URL* resourceURL, Function<void (API::Data*, CallbackBase::Error)>&& callbackFunction)
227{
228 if (!m_page) {
229 callbackFunction(nullptr, CallbackBase::Error::Unknown);
230 return;
231 }
232
233 m_page->getResourceDataFromFrame(this, resourceURL, WTFMove(callbackFunction));
234}
235
236void WebFrameProxy::setUnreachableURL(const URL& unreachableURL)
237{
238 m_frameLoadState.setUnreachableURL(unreachableURL);
239}
240
241#if ENABLE(CONTENT_FILTERING)
242bool WebFrameProxy::didHandleContentFilterUnblockNavigation(const ResourceRequest& request)
243{
244 if (!m_contentFilterUnblockHandler.canHandleRequest(request)) {
245 m_contentFilterUnblockHandler = { };
246 return false;
247 }
248
249 RefPtr<WebPageProxy> page { m_page.get() };
250 ASSERT(page);
251 m_contentFilterUnblockHandler.requestUnblockAsync([page](bool unblocked) {
252 if (unblocked)
253 page->reload({ });
254 });
255 return true;
256}
257#endif
258
259#if PLATFORM(GTK)
260void WebFrameProxy::collapseSelection()
261{
262 if (!m_page)
263 return;
264
265 m_page->process().send(Messages::WebPage::CollapseSelectionInFrame(m_frameID), m_page->pageID());
266}
267#endif
268
269} // namespace WebKit
270