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