blob: 59128beb87568d1f79f88456642c5591ceb12256 [file] [log] [blame]
darinfa7a4e32006-10-30 00:37:02 +00001/*
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00002 * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
hausmann@webkit.orgf6964472008-09-29 12:47:08 +00003 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
staikos@webkit.org159f11f2009-05-18 23:48:30 +00004 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
staikos@webkit.orgc7692122009-10-28 18:12:34 +00005 * Copyright (C) 2008 Alp Toker <alp@atoker.com>
6 * Copyright (C) Research In Motion Limited 2009. All rights reserved.
commit-queue@webkit.orgff400aa2011-03-10 23:43:48 +00007 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com>
commit-queue@webkit.org343b8a62011-09-21 01:49:03 +00008 * Copyright (C) 2011 Google Inc. All rights reserved.
darinfa7a4e32006-10-30 00:37:02 +00009 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
joepeck@webkit.org6d6a47c2014-03-06 19:33:51 +000015 * notice, this list of conditions and the following disclaimer.
darinfa7a4e32006-10-30 00:37:02 +000016 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
joepeck@webkit.org6d6a47c2014-03-06 19:33:51 +000018 * documentation and/or other materials provided with the distribution.
mjs@apple.com92047332014-03-15 04:08:27 +000019 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
darinfa7a4e32006-10-30 00:37:02 +000020 * its contributors may be used to endorse or promote products derived
joepeck@webkit.org6d6a47c2014-03-06 19:33:51 +000021 * from this software without specific prior written permission.
darinfa7a4e32006-10-30 00:37:02 +000022 *
23 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
darinc1116552006-10-30 20:05:39 +000035#include "config.h"
36#include "FrameLoader.h"
darinfa7a4e32006-10-30 00:37:02 +000037
mario@webkit.org685258f2011-12-06 00:10:55 +000038#include "AXObjectCache.h"
darin@chromium.orgdf437532009-08-05 00:18:28 +000039#include "ApplicationCacheHost.h"
cdumez@apple.com9265dfe2019-10-17 01:44:16 +000040#include "BackForwardCache.h"
darin@apple.come10e1282010-10-30 00:44:33 +000041#include "BackForwardController.h"
beidson@apple.com7617ce72010-05-13 20:31:46 +000042#include "BeforeUnloadEvent.h"
beidson448a6e72007-04-10 23:55:56 +000043#include "CachedPage.h"
darin@apple.come10e1282010-10-30 00:44:33 +000044#include "CachedResourceLoader.h"
ggaren52fd1072006-11-06 23:56:59 +000045#include "Chrome.h"
commit-queue@webkit.org52b68332011-06-07 16:20:07 +000046#include "ChromeClient.h"
beidson@apple.com7034ec72017-07-06 00:01:53 +000047#include "CommonVM.h"
aestes@apple.com176a9aa2016-07-08 20:14:34 +000048#include "ContentFilter.h"
achristensen@apple.comd3edc2a2019-03-21 20:23:46 +000049#include "ContentRuleListResults.h"
abarth@webkit.orgf921dee2011-03-26 11:59:34 +000050#include "ContentSecurityPolicy.h"
bfulgham@apple.combe0ac722019-05-20 00:48:59 +000051#include "CustomHeaderFields.h"
aroben@apple.com92cfa902008-04-16 19:19:00 +000052#include "DOMWindow.h"
mark.lam@apple.com45beb072012-12-12 23:04:20 +000053#include "DatabaseManager.h"
jer.noble@apple.com9e0f0602014-11-22 05:27:16 +000054#include "DiagnosticLoggingClient.h"
eric.carlson@apple.com77b4a112014-10-30 19:04:29 +000055#include "DiagnosticLoggingKeys.h"
darinc370e7e2006-11-08 05:52:27 +000056#include "Document.h"
darinc1116552006-10-30 20:05:39 +000057#include "DocumentLoader.h"
darinc370e7e2006-11-08 05:52:27 +000058#include "Editor.h"
anderscaf6232012006-11-15 00:36:50 +000059#include "EditorClient.h"
ggaren52fd1072006-11-06 23:56:59 +000060#include "Element.h"
darinf1bb0042006-12-01 22:46:21 +000061#include "Event.h"
weinig@apple.com13d777f2013-04-16 21:54:22 +000062#include "EventHandler.h"
darinc370e7e2006-11-08 05:52:27 +000063#include "EventNames.h"
ggaren52fd1072006-11-06 23:56:59 +000064#include "FloatRect.h"
darinc1116552006-10-30 20:05:39 +000065#include "FormState.h"
dglazkov@chromium.org25a57e52010-06-20 21:00:35 +000066#include "FormSubmission.h"
cdumez@apple.comc518f7e2018-04-03 18:01:41 +000067#include "Frame.h"
ggaren52fd1072006-11-06 23:56:59 +000068#include "FrameLoadRequest.h"
69#include "FrameLoaderClient.h"
diegohcg@webkit.org838e0a22010-09-04 14:48:30 +000070#include "FrameNetworkingContext.h"
ggaren52fd1072006-11-06 23:56:59 +000071#include "FrameTree.h"
darinc370e7e2006-11-08 05:52:27 +000072#include "FrameView.h"
akling@apple.comaf7f33b2016-02-06 17:00:30 +000073#include "GCController.h"
darinc370e7e2006-11-08 05:52:27 +000074#include "HTMLFormElement.h"
commit-queue@webkit.orge5739ca2012-11-15 19:39:50 +000075#include "HTMLInputElement.h"
darinc370e7e2006-11-08 05:52:27 +000076#include "HTMLNames.h"
77#include "HTMLObjectElement.h"
commit-queue@webkit.org26a3a092012-10-18 19:53:58 +000078#include "HTMLParserIdioms.h"
andersca@apple.coma96cf712014-06-14 17:49:44 +000079#include "HTTPHeaderNames.h"
commit-queue@webkit.orgf1fbce62020-01-01 11:25:53 +000080#include "HTTPHeaderValues.h"
ape9991d52006-12-08 18:19:51 +000081#include "HTTPParsers.h"
andersca@apple.com9b9d83b2013-04-10 19:11:20 +000082#include "HistoryController.h"
weinig62f94be2007-07-18 20:37:20 +000083#include "HistoryItem.h"
cdumez@apple.com8b478c62016-01-23 01:04:59 +000084#include "IgnoreOpensDuringUnloadCountIncrementer.h"
commit-queue@webkit.org4c49a662011-01-02 22:27:10 +000085#include "InspectorController.h"
yurys@chromium.org389a6242011-01-12 13:06:42 +000086#include "InspectorInstrumentation.h"
yoav@yoav.ws1c12d5c2017-01-19 07:13:54 +000087#include "LinkLoader.h"
commit-queue@webkit.org3eeac492016-08-12 22:53:27 +000088#include "LoadTiming.h"
beidson@apple.com0c140b42013-01-17 00:45:30 +000089#include "LoaderStrategy.h"
beidson50c3bd82007-01-03 03:11:18 +000090#include "Logging.h"
weinig@apple.com13d777f2013-04-16 21:54:22 +000091#include "MemoryCache.h"
carlosgc@webkit.org32a60dd2016-11-10 14:24:26 +000092#include "MemoryRelease.h"
rniwa@webkit.orgf694bd62017-06-30 19:32:41 +000093#include "NavigationDisabler.h"
rniwa@webkit.org2c6d4eb2017-07-01 21:26:31 +000094#include "NavigationScheduler.h"
drousso@apple.com21748ed2018-10-08 18:25:52 +000095#include "Node.h"
achristensen@apple.come5945672016-06-13 21:58:53 +000096#include "Page.h"
ggaren@apple.com521f64b2009-09-24 05:53:23 +000097#include "PageTransitionEvent.h"
akling@apple.come6549f42016-12-01 16:15:27 +000098#include "PerformanceLogging.h"
beidson@apple.com0c140b42013-01-17 00:45:30 +000099#include "PlatformStrategies.h"
hausmann@webkit.org9999bb82008-03-10 11:52:27 +0000100#include "PluginData.h"
andersca@apple.com641fef92009-01-06 22:57:25 +0000101#include "PluginDocument.h"
abarth@webkit.org401a3792013-03-03 10:12:59 +0000102#include "PolicyChecker.h"
andersca2b2c5ce2007-01-15 21:55:00 +0000103#include "ProgressTracker.h"
beidson50c3bd82007-01-03 03:11:18 +0000104#include "ResourceHandle.h"
beidson@apple.come3ea01d2015-07-02 18:33:23 +0000105#include "ResourceLoadInfo.h"
wilander@apple.com63f925f2016-10-06 17:40:12 +0000106#include "ResourceLoadObserver.h"
darinc370e7e2006-11-08 05:52:27 +0000107#include "ResourceRequest.h"
ossy@webkit.org66d8c0a2014-02-05 11:42:35 +0000108#include "SVGDocument.h"
109#include "SVGLocatable.h"
110#include "SVGNames.h"
ossy@webkit.org66d8c0a2014-02-05 11:42:35 +0000111#include "SVGViewElement.h"
112#include "SVGViewSpec.h"
weinig@apple.com79099002008-11-21 05:51:28 +0000113#include "ScriptController.h"
darin@chromium.org6b412472008-11-24 23:07:38 +0000114#include "ScriptSourceCode.h"
vsevik@chromium.org53bb0692012-01-18 20:59:10 +0000115#include "ScrollAnimator.h"
weinige06430a2007-10-19 20:53:22 +0000116#include "SecurityOrigin.h"
abarth@webkit.orgeea90662011-11-09 07:58:49 +0000117#include "SecurityPolicy.h"
darinc370e7e2006-11-08 05:52:27 +0000118#include "SegmentedString.h"
yurys@chromium.org832b9142010-08-05 12:36:31 +0000119#include "SerializedScriptValue.h"
darinc370e7e2006-11-08 05:52:27 +0000120#include "Settings.h"
cdumez@apple.comfdb89712018-06-11 20:52:31 +0000121#include "ShouldTreatAsContinuingLoad.h"
rniwa@webkit.org77c65702019-08-13 05:18:11 +0000122#include "StyleTreeResolver.h"
akling@apple.com7f81b1e2013-09-06 17:23:03 +0000123#include "SubframeLoader.h"
dbates@webkit.org3c1f25a2018-02-07 18:56:02 +0000124#include "SubresourceLoader.h"
darin@apple.com1b75e772010-06-15 22:20:34 +0000125#include "TextResourceDecoder.h"
beidson@apple.come3ea01d2015-07-02 18:33:23 +0000126#include "UserContentController.h"
commit-queue@webkit.org635dbdc2017-11-23 19:36:08 +0000127#include "UserGestureIndicator.h"
darin@apple.com1b75e772010-06-15 22:20:34 +0000128#include "WindowFeatures.h"
129#include "XMLDocumentParser.h"
commit-queue@webkit.org1d992932018-09-11 17:14:07 +0000130#include <dom/ScriptDisallowedScope.h>
achristensen@apple.comce5520e2017-09-25 22:33:19 +0000131#include <wtf/CompletionHandler.h>
keith_miller@apple.combb2f61c2018-12-01 03:28:36 +0000132#include <wtf/URL.h>
akling@apple.comf8515982013-09-02 18:50:01 +0000133#include <wtf/Ref.h>
beidson@apple.com1c9022b2018-03-21 00:05:58 +0000134#include <wtf/SetForScope.h>
darin@apple.com1b75e772010-06-15 22:20:34 +0000135#include <wtf/StdLibExtras.h>
simon.fraser@apple.com83325b92017-03-17 00:47:16 +0000136#include <wtf/SystemTracing.h>
darin@apple.com1b75e772010-06-15 22:20:34 +0000137#include <wtf/text/CString.h>
zimmermann@webkit.orgb5e11e62011-05-16 07:56:06 +0000138#include <wtf/text/WTFString.h>
darin@apple.com1b75e772010-06-15 22:20:34 +0000139
jcivelli@chromium.orgc2019dd2011-05-24 19:32:03 +0000140#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
jeremy@chromium.orgc4b86e32011-02-13 20:28:39 +0000141#include "Archive.h"
jeremy@chromium.orgc4b86e32011-02-13 20:28:39 +0000142#endif
143
enrica@apple.com53b08e52016-01-19 22:58:59 +0000144#if ENABLE(DATA_DETECTION)
145#include "DataDetection.h"
146#endif
147
ap@apple.com1e8475922018-10-18 21:38:50 +0000148#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000149#include "DocumentType.h"
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000150#include "ResourceLoader.h"
cdumez@apple.com0b0e88f2016-03-06 03:28:54 +0000151#include "RuntimeApplicationChecks.h"
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000152#endif
loislo@chromium.org82b9dde2012-09-12 13:16:31 +0000153
krollin@apple.comf26b56e2020-02-28 19:43:33 +0000154#define PAGE_ID ((pageID().valueOr(PageIdentifier())).toUInt64())
155#define FRAME_ID ((frameID().valueOr(FrameIdentifier())).toUInt64())
156#define FRAMELOADER_RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [pageID=%" PRIu64 ", frameID=%" PRIu64 ", main=%d] FrameLoader::" fmt, this, PAGE_ID, FRAME_ID, m_frame.isMainFrame(), ##__VA_ARGS__)
157#define FRAMELOADER_RELEASE_LOG_ERROR_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [pageID=%" PRIu64 ", frameID=%" PRIu64 ", main=%d] FrameLoader::" fmt, this, PAGE_ID, FRAME_ID, m_frame.isMainFrame(), ##__VA_ARGS__)
commit-queue@webkit.org6d635222016-03-08 06:44:59 +0000158
darinfa7a4e32006-10-30 00:37:02 +0000159namespace WebCore {
160
darin@apple.com1b75e772010-06-15 22:20:34 +0000161using namespace HTMLNames;
oliverb64e4082007-10-12 13:13:51 +0000162using namespace SVGNames;
darinc370e7e2006-11-08 05:52:27 +0000163
darinc370e7e2006-11-08 05:52:27 +0000164bool isBackForwardLoadType(FrameLoadType type)
165{
166 switch (type) {
andersca@apple.comb50fcc32014-06-19 00:13:20 +0000167 case FrameLoadType::Standard:
168 case FrameLoadType::Reload:
169 case FrameLoadType::ReloadFromOrigin:
antti@apple.com5d0c5402017-03-17 19:52:49 +0000170 case FrameLoadType::ReloadExpiredOnly:
andersca@apple.comb50fcc32014-06-19 00:13:20 +0000171 case FrameLoadType::Same:
172 case FrameLoadType::RedirectWithLockedBackForwardList:
173 case FrameLoadType::Replace:
174 return false;
175 case FrameLoadType::Back:
176 case FrameLoadType::Forward:
177 case FrameLoadType::IndexedBackForward:
178 return true;
darinc370e7e2006-11-08 05:52:27 +0000179 }
180 ASSERT_NOT_REACHED();
181 return false;
182}
183
antti@apple.com5d0c5402017-03-17 19:52:49 +0000184bool isReload(FrameLoadType type)
185{
186 switch (type) {
187 case FrameLoadType::Reload:
188 case FrameLoadType::ReloadFromOrigin:
189 case FrameLoadType::ReloadExpiredOnly:
190 return true;
191 case FrameLoadType::Standard:
192 case FrameLoadType::Same:
193 case FrameLoadType::RedirectWithLockedBackForwardList:
194 case FrameLoadType::Replace:
195 case FrameLoadType::Back:
196 case FrameLoadType::Forward:
197 case FrameLoadType::IndexedBackForward:
198 return false;
199 }
200 ASSERT_NOT_REACHED();
201 return false;
202}
203
cjerdonek@webkit.org75d10692010-05-18 16:18:31 +0000204// This is not in the FrameLoader class to emphasize that it does not depend on
205// private FrameLoader data, and to avoid increasing the number of public functions
206// with access to private data. Since only this .cpp file needs it, making it
207// non-member lets us exclude it from the header file, thus keeping FrameLoader.h's
208// API simpler.
209//
cdumez@apple.comd6738dc2015-05-04 23:58:32 +0000210static bool isDocumentSandboxed(Frame& frame, SandboxFlags mask)
cjerdonek@webkit.org75d10692010-05-18 16:18:31 +0000211{
cdumez@apple.comd6738dc2015-05-04 23:58:32 +0000212 return frame.document() && frame.document()->isSandboxed(mask);
cjerdonek@webkit.org75d10692010-05-18 16:18:31 +0000213}
214
cdumez@apple.comfc8fdf32019-12-06 21:05:12 +0000215class PageLevelForbidScope {
216protected:
217 explicit PageLevelForbidScope(Page* page)
218 : m_page(makeWeakPtr(page))
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +0000219 {
cdumez@apple.comfc8fdf32019-12-06 21:05:12 +0000220 }
221
222 ~PageLevelForbidScope() = default;
223
224 WeakPtr<Page> m_page;
225};
226
227struct ForbidPromptsScope : public PageLevelForbidScope {
228 explicit ForbidPromptsScope(Page* page)
229 : PageLevelForbidScope(page)
230 {
231 if (m_page)
232 m_page->forbidPrompts();
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +0000233 }
234
235 ~ForbidPromptsScope()
236 {
cdumez@apple.comfc8fdf32019-12-06 21:05:12 +0000237 if (m_page)
238 m_page->allowPrompts();
239 }
240};
241
242struct ForbidSynchronousLoadsScope : public PageLevelForbidScope {
243 explicit ForbidSynchronousLoadsScope(Page* page)
244 : PageLevelForbidScope(page)
245 {
246 if (m_page)
247 m_page->forbidSynchronousLoads();
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +0000248 }
249
cdumez@apple.comfc8fdf32019-12-06 21:05:12 +0000250 ~ForbidSynchronousLoadsScope()
251 {
252 if (m_page)
253 m_page->allowSynchronousLoads();
254 }
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +0000255};
256
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000257class FrameLoader::FrameProgressTracker {
cdumez@apple.coma738a882016-04-19 18:39:09 +0000258 WTF_MAKE_FAST_ALLOCATED;
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000259public:
weinig@apple.comeefc25d2013-11-08 22:42:27 +0000260 explicit FrameProgressTracker(Frame& frame)
261 : m_frame(frame)
262 , m_inProgress(false)
263 {
264 }
265
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000266 ~FrameProgressTracker()
267 {
jpfau@apple.com7907c6b2014-10-28 22:38:44 +0000268 if (m_inProgress && m_frame.page())
andersca@apple.comcd088792014-01-10 07:19:29 +0000269 m_frame.page()->progress().progressCompleted(m_frame);
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000270 }
271
272 void progressStarted()
273 {
akling@apple.com7f50aae2013-08-22 16:01:31 +0000274 ASSERT(m_frame.page());
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000275 if (!m_inProgress)
andersca@apple.comcd088792014-01-10 07:19:29 +0000276 m_frame.page()->progress().progressStarted(m_frame);
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000277 m_inProgress = true;
278 }
279
280 void progressCompleted()
281 {
282 ASSERT(m_inProgress);
akling@apple.com7f50aae2013-08-22 16:01:31 +0000283 ASSERT(m_frame.page());
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000284 m_inProgress = false;
andersca@apple.comcd088792014-01-10 07:19:29 +0000285 m_frame.page()->progress().progressCompleted(m_frame);
cdumez@apple.comc2b1e2a2019-09-04 03:13:45 +0000286 platformStrategies()->loaderStrategy()->pageLoadCompleted(*m_frame.page());
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000287 }
288
289private:
akling@apple.com7f50aae2013-08-22 16:01:31 +0000290 Frame& m_frame;
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000291 bool m_inProgress;
292};
293
youenn@apple.comee96d0f2020-03-18 13:59:23 +0000294FrameLoader::FrameLoader(Frame& frame, UniqueRef<FrameLoaderClient>&& client)
darinfa7a4e32006-10-30 00:37:02 +0000295 : m_frame(frame)
youenn@apple.comee96d0f2020-03-18 13:59:23 +0000296 , m_client(WTFMove(client))
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +0000297 , m_policyChecker(makeUnique<PolicyChecker>(frame))
298 , m_history(makeUnique<HistoryController>(frame))
akling@apple.com654fd9a2013-10-06 21:07:29 +0000299 , m_notifier(frame)
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +0000300 , m_subframeLoader(makeUnique<SubframeLoader>(frame))
weinig@apple.comeefc25d2013-11-08 22:42:27 +0000301 , m_mixedContentChecker(frame)
japhet@chromium.orgce6c1ba2012-11-28 19:30:48 +0000302 , m_state(FrameStateProvisional)
andersca@apple.comb50fcc32014-06-19 00:13:20 +0000303 , m_loadType(FrameLoadType::Standard)
darinfa7a4e32006-10-30 00:37:02 +0000304 , m_quickRedirectComing(false)
305 , m_sentRedirectNotification(false)
darinc370e7e2006-11-08 05:52:27 +0000306 , m_inStopAllLoaders(false)
darinc370e7e2006-11-08 05:52:27 +0000307 , m_isExecutingJavaScriptFormAction(false)
japhet@chromium.orgce6c1ba2012-11-28 19:30:48 +0000308 , m_didCallImplicitClose(true)
darinc370e7e2006-11-08 05:52:27 +0000309 , m_wasUnloadEventEmitted(false)
310 , m_isComplete(false)
darinc370e7e2006-11-08 05:52:27 +0000311 , m_needsClear(false)
andersca@apple.com574a7452014-11-21 20:10:13 +0000312 , m_checkTimer(*this, &FrameLoader::checkTimerFired)
darin@apple.comf53381b2009-09-23 23:27:01 +0000313 , m_shouldCallCheckCompleted(false)
314 , m_shouldCallCheckLoadComplete(false)
weinig@apple.comeefc25d2013-11-08 22:42:27 +0000315 , m_opener(nullptr)
beidson@apple.comac095c02009-08-18 01:37:56 +0000316 , m_loadingFromCachedPage(false)
beidson@apple.com1390a812013-07-20 06:43:51 +0000317 , m_currentNavigationHasShownBeforeUnloadConfirmPanel(false)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000318 , m_loadsSynchronously(false)
abarth@webkit.orgf2c54c22010-04-11 06:57:13 +0000319 , m_forcedSandboxFlags(SandboxNone)
darinfa7a4e32006-10-30 00:37:02 +0000320{
321}
322
323FrameLoader::~FrameLoader()
324{
weinig@apple.comeefc25d2013-11-08 22:42:27 +0000325 setOpener(nullptr);
cdumez@apple.comf6bbf482019-10-12 19:17:37 +0000326 detachFromAllOpenedFrames();
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +0000327
diegohcg@webkit.org838e0a22010-09-04 14:48:30 +0000328 if (m_networkingContext)
329 m_networkingContext->invalidate();
darinfa7a4e32006-10-30 00:37:02 +0000330}
331
cdumez@apple.comf6bbf482019-10-12 19:17:37 +0000332void FrameLoader::detachFromAllOpenedFrames()
333{
334 for (auto& frame : m_openedFrames)
335 frame->loader().m_opener = nullptr;
336 m_openedFrames.clear();
337}
338
mrowe@apple.com5d92f2a2008-09-30 21:04:35 +0000339void FrameLoader::init()
mjs8d620d52007-05-10 12:31:42 +0000340{
darin@apple.com73006812011-06-29 20:46:33 +0000341 // This somewhat odd set of steps gives the frame an initial empty document.
youenn@apple.comee96d0f2020-03-18 13:59:23 +0000342 setPolicyDocumentLoader(m_client->createDocumentLoader(ResourceRequest(URL({ }, emptyString())), SubstituteData()).ptr());
mjs8d620d52007-05-10 12:31:42 +0000343 setProvisionalDocumentLoader(m_policyDocumentLoader.get());
cdumez@apple.coma0010ff2018-12-13 23:17:44 +0000344 m_provisionalDocumentLoader->startLoadingMainResource();
jpfau@apple.comec9eb512014-07-10 01:13:45 +0000345
346 Ref<Frame> protect(m_frame);
akling@apple.com7f50aae2013-08-22 16:01:31 +0000347 m_frame.document()->cancelParsing();
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +0000348 m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument);
diegohcg@webkit.org838e0a22010-09-04 14:48:30 +0000349
youenn@apple.comee96d0f2020-03-18 13:59:23 +0000350 m_networkingContext = m_client->createNetworkingContext();
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +0000351 m_progressTracker = makeUnique<FrameProgressTracker>(m_frame);
mjs8d620d52007-05-10 12:31:42 +0000352}
353
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000354void FrameLoader::initForSynthesizedDocument(const URL&)
355{
356 // FIXME: We need to initialize the document URL to the specified URL. Currently the URL is empty and hence
357 // FrameLoader::checkCompleted() will overwrite the URL of the document to be activeDocumentLoader()->documentURL().
358
youenn@apple.comee96d0f2020-03-18 13:59:23 +0000359 auto loader = m_client->createDocumentLoader(ResourceRequest(URL({ }, emptyString())), SubstituteData());
beidson@apple.com10a537f2015-07-09 22:30:42 +0000360 loader->attachToFrame(m_frame);
utatane.tea@gmail.com84077632018-06-23 08:39:34 +0000361 loader->setResponse(ResourceResponse(URL(), "text/html"_s, 0, String()));
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000362 loader->setCommitted(true);
commit-queue@webkit.orgc7c21c92017-10-25 21:17:46 +0000363 setDocumentLoader(loader.ptr());
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000364
365 m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument);
366 m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
367 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
youenn@apple.comee96d0f2020-03-18 13:59:23 +0000368 m_client->transitionToCommittedForNewPage();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000369
370 m_didCallImplicitClose = true;
371 m_isComplete = true;
372 m_state = FrameStateComplete;
373 m_needsClear = true;
374
youenn@apple.comee96d0f2020-03-18 13:59:23 +0000375 m_networkingContext = m_client->createNetworkingContext();
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +0000376 m_progressTracker = makeUnique<FrameProgressTracker>(m_frame);
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000377}
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000378
krollin@apple.comf26b56e2020-02-28 19:43:33 +0000379Optional<PageIdentifier> FrameLoader::pageID() const
380{
381 return client().pageID();
382}
383
384Optional<FrameIdentifier> FrameLoader::frameID() const
385{
386 return client().frameID();
387}
388
darinfa7a4e32006-10-30 00:37:02 +0000389void FrameLoader::setDefersLoading(bool defers)
390{
darin8207db42007-02-20 18:18:39 +0000391 if (m_documentLoader)
392 m_documentLoader->setDefersLoading(defers);
393 if (m_provisionalDocumentLoader)
394 m_provisionalDocumentLoader->setDefersLoading(defers);
395 if (m_policyDocumentLoader)
396 m_policyDocumentLoader->setDefersLoading(defers);
akling@apple.com672cb852013-08-22 20:27:27 +0000397 history().setDefersLoading(defers);
darin@apple.comf53381b2009-09-23 23:27:01 +0000398
399 if (!defers) {
akling@apple.com7f50aae2013-08-22 16:01:31 +0000400 m_frame.navigationScheduler().startTimer();
darin@apple.comf53381b2009-09-23 23:27:01 +0000401 startCheckCompleteTimer();
402 }
darinfa7a4e32006-10-30 00:37:02 +0000403}
404
rniwa@webkit.orgba12a012019-02-03 22:48:22 +0000405void FrameLoader::checkContentPolicy(const ResourceResponse& response, PolicyCheckIdentifier identifier, ContentPolicyDecisionFunction&& function)
achristensen@apple.comb8c49be2017-08-23 21:10:09 +0000406{
bfulgham@apple.com78e81d92018-06-25 21:29:50 +0000407 if (!activeDocumentLoader()) {
408 // Load was cancelled
rniwa@webkit.orgba12a012019-02-03 22:48:22 +0000409 function(PolicyAction::Ignore, identifier);
bfulgham@apple.com78e81d92018-06-25 21:29:50 +0000410 return;
411 }
412
rniwa@webkit.orgba12a012019-02-03 22:48:22 +0000413 // FIXME: Validate the policy check identifier.
commit-queue@webkit.orga4a9ce22019-04-10 22:56:35 +0000414 client().dispatchDecidePolicyForResponse(response, activeDocumentLoader()->request(), identifier, activeDocumentLoader()->downloadAttribute(), WTFMove(function));
achristensen@apple.comb8c49be2017-08-23 21:10:09 +0000415}
416
commit-queue@webkit.org7a3c5522020-03-09 15:10:01 +0000417void FrameLoader::changeLocation(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, const ReferrerPolicy& referrerPolicy, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, Optional<NewFrameOpenerPolicy> openerPolicy, const AtomString& downloadAttribute, const SystemPreviewInfo& systemPreviewInfo, Optional<AdClickAttribution>&& adClickAttribution)
bfulgham@apple.com8f831542016-03-31 15:35:41 +0000418{
beidson@apple.com7034ec72017-07-06 00:01:53 +0000419 auto* frame = lexicalFrameFromCommonVM();
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +0000420 auto initiatedByMainFrame = frame && frame->isMainFrame() ? InitiatedByMainFrame::Yes : InitiatedByMainFrame::Unknown;
beidson@apple.com7034ec72017-07-06 00:01:53 +0000421
commit-queue@webkit.org8383b5f2020-03-02 11:36:00 +0000422 NewFrameOpenerPolicy newFrameOpenerPolicy = openerPolicy.valueOr(referrerPolicy == ReferrerPolicy::NoReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow);
commit-queue@webkit.org1b6bd842020-04-18 17:04:07 +0000423 FrameLoadRequest frameLoadRequest(*m_frame.document(), m_frame.document()->securityOrigin(), { url }, passedTarget, initiatedByMainFrame, downloadAttribute, systemPreviewInfo);
424 frameLoadRequest.setLockHistory(lockHistory);
425 frameLoadRequest.setLockBackForwardList(lockBackForwardList);
426 frameLoadRequest.setNewFrameOpenerPolicy(newFrameOpenerPolicy);
427 frameLoadRequest.setReferrerPolicy(referrerPolicy);
428 frameLoadRequest.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicy);
429 frameLoadRequest.disableShouldReplaceDocumentIfJavaScriptURL();
430 changeLocation(WTFMove(frameLoadRequest), triggeringEvent, WTFMove(adClickAttribution));
bfulgham@apple.com8f831542016-03-31 15:35:41 +0000431}
432
commit-queue@webkit.org7a3c5522020-03-09 15:10:01 +0000433void FrameLoader::changeLocation(FrameLoadRequest&& frameRequest, Event* triggeringEvent, Optional<AdClickAttribution>&& adClickAttribution)
cjerdonek@webkit.org983777f2010-05-17 07:34:12 +0000434{
commit-queue@webkit.org7a3c5522020-03-09 15:10:01 +0000435 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "changeLocation: frame load started");
commit-queue@webkit.org8a13ad32020-03-16 08:11:26 +0000436 ASSERT(frameRequest.resourceRequest().httpMethod() == "GET");
krollin@apple.come1810b62018-12-20 19:23:20 +0000437
akling@apple.comf8515982013-09-02 18:50:01 +0000438 Ref<Frame> protect(m_frame);
darin@apple.com1cf3d562010-12-07 16:23:03 +0000439
rniwa@webkit.orgadc76112019-12-17 23:35:18 +0000440 if (m_frame.script().executeIfJavaScriptURL(frameRequest.resourceRequest().url(), &frameRequest.requester().securityOrigin(), frameRequest.shouldReplaceDocumentIfJavaScriptURL())) {
cdumez@apple.com6cbf70a2019-10-11 20:26:15 +0000441 m_quickRedirectComing = false;
weinig@apple.com6b00e242008-01-08 01:30:27 +0000442 return;
cdumez@apple.com6cbf70a2019-10-11 20:26:15 +0000443 }
weinig@apple.com6b00e242008-01-08 01:30:27 +0000444
darin@apple.com1cf3d562010-12-07 16:23:03 +0000445 if (frameRequest.frameName().isEmpty())
akling@apple.com7f50aae2013-08-22 16:01:31 +0000446 frameRequest.setFrameName(m_frame.document()->baseTarget());
darinc370e7e2006-11-08 05:52:27 +0000447
bfulgham@apple.comb30d7f82016-06-07 15:47:30 +0000448 m_frame.document()->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(frameRequest.resourceRequest(), ContentSecurityPolicy::InsecureRequestType::Navigation);
darin@apple.com4cd1b242009-03-27 23:37:46 +0000449
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +0000450 loadFrameRequest(WTFMove(frameRequest), triggeringEvent, { }, WTFMove(adClickAttribution));
darinc370e7e2006-11-08 05:52:27 +0000451}
452
darin@apple.com961f2a52016-12-31 09:51:29 +0000453void FrameLoader::submitForm(Ref<FormSubmission>&& submission)
darinc370e7e2006-11-08 05:52:27 +0000454{
darin@apple.comc04189e2017-01-18 05:17:17 +0000455 ASSERT(submission->method() == FormSubmission::Method::Post || submission->method() == FormSubmission::Method::Get);
dglazkov@chromium.org25a57e52010-06-20 21:00:35 +0000456
dglazkov@chromium.org996fc222010-06-21 16:36:40 +0000457 // FIXME: Find a good spot for these.
darin@apple.comc04189e2017-01-18 05:17:17 +0000458 ASSERT(!submission->state().sourceDocument().frame() || submission->state().sourceDocument().frame() == &m_frame);
dbates@webkit.org29908522017-01-07 07:14:03 +0000459
akling@apple.com7f50aae2013-08-22 16:01:31 +0000460 if (!m_frame.page())
adele@apple.comf3d6b892008-04-29 01:30:20 +0000461 return;
dbates@webkit.org29908522017-01-07 07:14:03 +0000462
dglazkov@chromium.org996fc222010-06-21 16:36:40 +0000463 if (submission->action().isEmpty())
darinc370e7e2006-11-08 05:52:27 +0000464 return;
465
cdumez@apple.comd6738dc2015-05-04 23:58:32 +0000466 if (isDocumentSandboxed(m_frame, SandboxForms)) {
mkwst@chromium.orgb10ebb432012-12-04 18:34:27 +0000467 // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
joepeck@webkit.org1f45df92014-02-06 23:45:53 +0000468 m_frame.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Blocked form submission to '" + submission->action().stringCenterEllipsizedToLength() + "' because the form's frame is sandboxed and the 'allow-forms' permission is not set.");
abarth@webkit.orgb8a10552009-12-02 02:40:35 +0000469 return;
mkwst@chromium.orgb10ebb432012-12-04 18:34:27 +0000470 }
abarth@webkit.orgb8a10552009-12-02 02:40:35 +0000471
commit-queue@webkit.org39359f02020-04-25 21:28:45 +0000472 if (submission->action().protocolIsJavaScript()) {
darin@apple.com5ffbb5c2013-09-27 16:39:41 +0000473 if (!m_frame.document()->contentSecurityPolicy()->allowFormAction(URL(submission->action())))
commit-queue@webkit.org78e860e2012-08-16 12:42:09 +0000474 return;
darinc370e7e2006-11-08 05:52:27 +0000475 m_isExecutingJavaScriptFormAction = true;
ap@apple.come6afcb62014-04-20 19:02:13 +0000476 Ref<Frame> protect(m_frame);
rniwa@webkit.orgadc76112019-12-17 23:35:18 +0000477 m_frame.script().executeIfJavaScriptURL(submission->action(), nullptr, DoNotReplaceDocumentIfJavaScriptURL);
darinc370e7e2006-11-08 05:52:27 +0000478 m_isExecutingJavaScriptFormAction = false;
479 return;
480 }
481
darin@apple.comc04189e2017-01-18 05:17:17 +0000482 Frame* targetFrame = findFrameForNavigation(submission->target(), &submission->state().sourceDocument());
darin@apple.com0f88bda2009-04-02 00:30:50 +0000483 if (!targetFrame) {
commit-queue@webkit.org635dbdc2017-11-23 19:36:08 +0000484 if (!DOMWindow::allowPopUp(m_frame) && !UserGestureIndicator::processingUserGesture())
abarth@webkit.orgc72185c2010-04-09 06:43:19 +0000485 return;
486
darin@apple.comc04189e2017-01-18 05:17:17 +0000487 // FIXME: targetFrame can be null for two distinct reasons:
ap@apple.comf8c414e2013-08-13 03:44:57 +0000488 // 1. The frame was not found by name, so we should try opening a new window.
489 // 2. The frame was found, but navigating it was not allowed, e.g. by HTML5 sandbox or by origin checks.
490 // Continuing form submission makes no sense in the latter case.
491 // There is a repeat check after timer fires, so this is not a correctness issue.
492
akling@apple.com7f50aae2013-08-22 16:01:31 +0000493 targetFrame = &m_frame;
dglazkov@chromium.org996fc222010-06-21 16:36:40 +0000494 } else
495 submission->clearTarget();
496
darin@apple.com0f88bda2009-04-02 00:30:50 +0000497 if (!targetFrame->page())
darinc370e7e2006-11-08 05:52:27 +0000498 return;
darin@apple.com0f88bda2009-04-02 00:30:50 +0000499
cdumez@apple.comede5bd32019-12-20 00:28:57 +0000500 if (m_frame.tree().isDescendantOf(targetFrame))
commit-queue@webkit.org43964052012-08-13 19:30:15 +0000501 m_submittedFormURL = submission->requestURL();
darinc370e7e2006-11-08 05:52:27 +0000502
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +0000503 submission->setReferrer(outgoingReferrer());
commit-queue@webkit.org138b4142020-03-10 11:27:15 +0000504 submission->setOrigin(SecurityPolicy::generateOriginHeader(m_frame.document()->referrerPolicy(), submission->requestURL(), m_frame.document()->securityOrigin()));
darinc370e7e2006-11-08 05:52:27 +0000505
darin@apple.com961f2a52016-12-31 09:51:29 +0000506 targetFrame->navigationScheduler().scheduleFormSubmission(WTFMove(submission));
darinc370e7e2006-11-08 05:52:27 +0000507}
508
commit-queue@webkit.orgfc5833b2011-02-23 06:58:46 +0000509void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy)
darinc370e7e2006-11-08 05:52:27 +0000510{
akling@apple.com7f50aae2013-08-22 16:01:31 +0000511 if (m_frame.document() && m_frame.document()->parser())
512 m_frame.document()->parser()->stopParsing();
mjs8d620d52007-05-10 12:31:42 +0000513
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +0000514 if (unloadEventPolicy != UnloadEventPolicyNone)
ggaren@apple.com7a176e12015-11-12 01:48:27 +0000515 dispatchUnloadEvents(unloadEventPolicy);
darinc370e7e2006-11-08 05:52:27 +0000516
darin@apple.com4d9d7182009-09-23 00:38:04 +0000517 m_isComplete = true; // to avoid calling completed() in finishedParsing()
ggarena57755c2007-07-09 21:08:10 +0000518 m_didCallImplicitClose = true; // don't want that one either
darinc370e7e2006-11-08 05:52:27 +0000519
akling@apple.com7f50aae2013-08-22 16:01:31 +0000520 if (m_frame.document() && m_frame.document()->parsing()) {
darinc370e7e2006-11-08 05:52:27 +0000521 finishedParsing();
akling@apple.com7f50aae2013-08-22 16:01:31 +0000522 m_frame.document()->setParsing(false);
darinc370e7e2006-11-08 05:52:27 +0000523 }
abarth@webkit.org55d49da2011-06-20 23:32:54 +0000524
darin@apple.com389af862016-11-14 03:22:31 +0000525 if (auto* document = m_frame.document()) {
mark.lam@apple.com45beb072012-12-12 23:04:20 +0000526 // FIXME: Should the DatabaseManager watch for something like ActiveDOMObject::stop() rather than being special-cased here?
darin@apple.com389af862016-11-14 03:22:31 +0000527 DatabaseManager::singleton().stopDatabases(*document, nullptr);
darinc370e7e2006-11-08 05:52:27 +0000528 }
529
cdumez@apple.com2d8d6082018-02-27 21:47:57 +0000530 policyChecker().stopCheck();
531
ap@apple.com3f0a0a12010-06-24 23:58:36 +0000532 // FIXME: This will cancel redirection timer, which really needs to be restarted when restoring the frame from b/f cache.
akling@apple.com7f50aae2013-08-22 16:01:31 +0000533 m_frame.navigationScheduler().cancel();
darinc370e7e2006-11-08 05:52:27 +0000534}
535
536void FrameLoader::stop()
537{
538 // http://bugs.webkit.org/show_bug.cgi?id=10854
539 // The frame's last ref may be removed and it will be deleted by checkCompleted().
akling@apple.comf8515982013-09-02 18:50:01 +0000540 Ref<Frame> protect(m_frame);
abarth@webkit.orgfd912902011-06-10 21:16:20 +0000541
akling@apple.com7f50aae2013-08-22 16:01:31 +0000542 if (DocumentParser* parser = m_frame.document()->parser()) {
abarth@webkit.orgfd912902011-06-10 21:16:20 +0000543 parser->stopParsing();
544 parser->finish();
545 }
darinc370e7e2006-11-08 05:52:27 +0000546}
547
ap@apple.come042b632013-05-17 20:04:43 +0000548void FrameLoader::willTransitionToCommitted()
549{
550 // This function is called when a frame is still fully in place (not cached, not detached), but will be replaced.
shihchieh_lee@apple.com501b37c2020-04-28 16:36:38 +0000551 Document* document = m_frame.document();
552 if (!document)
553 return;
ap@apple.come042b632013-05-17 20:04:43 +0000554
shihchieh_lee@apple.com501b37c2020-04-28 16:36:38 +0000555 if (document->editor().hasComposition()) {
ap@apple.come042b632013-05-17 20:04:43 +0000556 // The text was already present in DOM, so it's better to confirm than to cancel the composition.
shihchieh_lee@apple.com501b37c2020-04-28 16:36:38 +0000557 document->editor().confirmComposition();
558 if (EditorClient* editorClient = document->editor().client()) {
akling@apple.com7f50aae2013-08-22 16:01:31 +0000559 editorClient->respondToChangedSelection(&m_frame);
ap@apple.comc9851362014-12-11 17:23:34 +0000560 editorClient->discardedComposition(&m_frame);
561 }
ap@apple.come042b632013-05-17 20:04:43 +0000562 }
563}
564
commit-queue@webkit.org8772f672020-04-13 08:24:39 +0000565void FrameLoader::closeURL()
darinc370e7e2006-11-08 05:52:27 +0000566{
akling@apple.com672cb852013-08-22 20:27:27 +0000567 history().saveDocumentState();
stavila@adobe.comeb50d7c2014-12-17 10:14:32 +0000568
shihchieh_lee@apple.com501b37c2020-04-28 16:36:38 +0000569 RefPtr<Document> currentDocument = m_frame.document();
stavila@adobe.comeb50d7c2014-12-17 10:14:32 +0000570 UnloadEventPolicy unloadEventPolicy;
571 if (m_frame.page() && m_frame.page()->chrome().client().isSVGImageChromeClient()) {
572 // If this is the SVGDocument of an SVGImage, no need to dispatch events or recalcStyle.
573 unloadEventPolicy = UnloadEventPolicyNone;
574 } else {
cdumez@apple.com9265dfe2019-10-17 01:44:16 +0000575 // Should only send the pagehide event here if the current document exists and has not been placed in the back/forward cache.
576 unloadEventPolicy = currentDocument && currentDocument->backForwardCacheState() == Document::NotInBackForwardCache ? UnloadEventPolicyUnloadAndPageHide : UnloadEventPolicyUnloadOnly;
stavila@adobe.comeb50d7c2014-12-17 10:14:32 +0000577 }
578
579 stopLoading(unloadEventPolicy);
beidson@apple.com212b7842009-09-03 00:55:18 +0000580
shihchieh_lee@apple.com501b37c2020-04-28 16:36:38 +0000581 if (currentDocument)
582 currentDocument->editor().clearUndoRedoOperations();
darinc370e7e2006-11-08 05:52:27 +0000583}
584
abarth@webkit.org55d49da2011-06-20 23:32:54 +0000585bool FrameLoader::didOpenURL()
darinc370e7e2006-11-08 05:52:27 +0000586{
akling@apple.com7f50aae2013-08-22 16:01:31 +0000587 if (m_frame.navigationScheduler().redirectScheduledDuringLoad()) {
darinc370e7e2006-11-08 05:52:27 +0000588 // A redirect was scheduled before the document was created.
589 // This can happen when one frame changes another frame's location.
590 return false;
darin@apple.com0f88bda2009-04-02 00:30:50 +0000591 }
darinc370e7e2006-11-08 05:52:27 +0000592
akling@apple.com7f50aae2013-08-22 16:01:31 +0000593 m_frame.navigationScheduler().cancel();
darinc370e7e2006-11-08 05:52:27 +0000594
595 m_isComplete = false;
ggarena57755c2007-07-09 21:08:10 +0000596 m_didCallImplicitClose = false;
darinc370e7e2006-11-08 05:52:27 +0000597
ap@webkit.orgfbfb0f92009-05-08 07:58:08 +0000598 // If we are still in the process of initializing an empty document then
599 // its frame is not in a consistent state for rendering, so avoid setJSStatusBarText
600 // since it may cause clients to attempt to render the frame.
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +0000601 if (!m_stateMachine.creatingInitialEmptyDocument()) {
akling@apple.com7f50aae2013-08-22 16:01:31 +0000602 DOMWindow* window = m_frame.document()->domWindow();
abarth@webkit.org13fe1e22012-08-16 22:29:48 +0000603 window->setStatus(String());
604 window->setDefaultStatus(String());
ap@webkit.orgfbfb0f92009-05-08 07:58:08 +0000605 }
darinc370e7e2006-11-08 05:52:27 +0000606
607 started();
608
609 return true;
610}
611
ap@webkit.orga0a19872008-02-05 09:34:18 +0000612void FrameLoader::didExplicitOpen()
darinc370e7e2006-11-08 05:52:27 +0000613{
614 m_isComplete = false;
ggarena57755c2007-07-09 21:08:10 +0000615 m_didCallImplicitClose = false;
darinc370e7e2006-11-08 05:52:27 +0000616
andersca@apple.com1752dba2007-12-14 22:06:50 +0000617 // Calling document.open counts as committing the first real document load.
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +0000618 if (!m_stateMachine.committedFirstRealDocumentLoad())
619 m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
cdumez@apple.com0af95e32019-04-16 23:07:35 +0000620
cdumez@apple.comc59c42d2019-10-30 18:36:22 +0000621 if (auto* document = m_frame.document())
youenn@apple.comee96d0f2020-03-18 13:59:23 +0000622 m_client->dispatchDidExplicitOpen(document->url(), document->contentType());
andersca@apple.com1752dba2007-12-14 22:06:50 +0000623
darinc370e7e2006-11-08 05:52:27 +0000624 // Prevent window.open(url) -- eg window.open("about:blank") -- from blowing away results
625 // from a subsequent window.document.open / window.document.write call.
dbates@webkit.orgef42d382010-01-25 19:20:06 +0000626 // Canceling redirection here works for all cases because document.open
darinc370e7e2006-11-08 05:52:27 +0000627 // implicitly precedes document.write.
akling@apple.com7f50aae2013-08-22 16:01:31 +0000628 m_frame.navigationScheduler().cancel();
darinc370e7e2006-11-08 05:52:27 +0000629}
630
darinc370e7e2006-11-08 05:52:27 +0000631
632void FrameLoader::cancelAndClear()
633{
akling@apple.com7f50aae2013-08-22 16:01:31 +0000634 m_frame.navigationScheduler().cancel();
darinc370e7e2006-11-08 05:52:27 +0000635
636 if (!m_isComplete)
637 closeURL();
638
akling@apple.com7f50aae2013-08-22 16:01:31 +0000639 clear(m_frame.document(), false);
640 m_frame.script().updatePlatformScriptObjects();
darinc370e7e2006-11-08 05:52:27 +0000641}
642
aestes@apple.com408782b2016-11-29 18:40:55 +0000643static inline bool shouldClearWindowName(const Frame& frame, const Document& newDocument)
644{
645 if (!frame.isMainFrame())
646 return false;
647
648 if (frame.loader().opener())
649 return false;
650
akling@apple.com6be0e972017-01-18 19:35:49 +0000651 return !newDocument.securityOrigin().isSameOriginAs(frame.document()->securityOrigin());
aestes@apple.com408782b2016-11-29 18:40:55 +0000652}
653
beidson@apple.comdc5cfa42019-07-01 20:29:20 +0000654void FrameLoader::clear(Document* newDocument, bool clearWindowProperties, bool clearScriptObjects, bool clearFrameView, WTF::Function<void()>&& handleDOMWindowCreation)
darinc370e7e2006-11-08 05:52:27 +0000655{
beidson@apple.comdc5cfa42019-07-01 20:29:20 +0000656 bool neededClear = m_needsClear;
darinc370e7e2006-11-08 05:52:27 +0000657 m_needsClear = false;
beidson@apple.comdc5cfa42019-07-01 20:29:20 +0000658
cdumez@apple.com9265dfe2019-10-17 01:44:16 +0000659 if (neededClear && m_frame.document()->backForwardCacheState() != Document::InBackForwardCache) {
akling@apple.com7f50aae2013-08-22 16:01:31 +0000660 m_frame.document()->cancelParsing();
661 m_frame.document()->stopActiveDOMObjects();
timothy_horton@apple.com70d58d82014-07-26 18:45:04 +0000662 bool hadLivingRenderTree = m_frame.document()->hasLivingRenderTree();
shihchieh_lee@apple.com501b37c2020-04-28 16:36:38 +0000663 m_frame.document()->willBeRemovedFromFrame();
timothy_horton@apple.com70d58d82014-07-26 18:45:04 +0000664 if (hadLivingRenderTree)
simon.fraser@apple.com87cf1662018-09-08 20:19:22 +0000665 m_frame.document()->adjustFocusedNodeOnNodeRemoval(*m_frame.document());
darinc370e7e2006-11-08 05:52:27 +0000666 }
667
beidson@apple.comdc5cfa42019-07-01 20:29:20 +0000668 if (handleDOMWindowCreation)
669 handleDOMWindowCreation();
670
671 if (!neededClear)
672 return;
673
darinc370e7e2006-11-08 05:52:27 +0000674 // Do this after detaching the document so that the unload event works.
thatchera1e24df2007-09-14 23:53:29 +0000675 if (clearWindowProperties) {
commit-queue@webkit.org8599a762016-11-01 21:42:51 +0000676 InspectorInstrumentation::frameWindowDiscarded(m_frame, m_frame.document()->domWindow());
commit-queue@webkit.org8af5d212015-12-01 01:55:43 +0000677 m_frame.document()->domWindow()->resetUnlessSuspendedForDocumentSuspension();
cdumez@apple.com9265dfe2019-10-17 01:44:16 +0000678 m_frame.windowProxy().clearJSWindowProxiesNotMatchingDOMWindow(newDocument->domWindow(), m_frame.document()->backForwardCacheState() == Document::AboutToEnterBackForwardCache);
aestes@apple.com408782b2016-11-29 18:40:55 +0000679
680 if (shouldClearWindowName(m_frame, *newDocument))
utatane.tea@gmail.comc4579a02017-07-07 04:42:04 +0000681 m_frame.tree().setName(nullAtom());
weinigf9307632007-07-18 05:40:54 +0000682 }
darinc370e7e2006-11-08 05:52:27 +0000683
achristensen@apple.com09e70aa2017-04-27 16:42:13 +0000684 m_frame.eventHandler().clear();
bfulgham@apple.com46bde7c2016-04-07 21:15:34 +0000685
akling@apple.com7f50aae2013-08-22 16:01:31 +0000686 if (clearFrameView && m_frame.view())
687 m_frame.view()->clear();
eric@webkit.org0683d942008-08-06 10:01:35 +0000688
eric@webkit.org0683d942008-08-06 10:01:35 +0000689 // Do not drop the document before the ScriptController and view are cleared
690 // as some destructors might still try to access the document.
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +0000691 m_frame.setDocument(nullptr);
darinc370e7e2006-11-08 05:52:27 +0000692
akling@apple.com7f81b1e2013-09-06 17:23:03 +0000693 subframeLoader().clear();
eric@webkit.org0683d942008-08-06 10:01:35 +0000694
bfulgham@apple.com472a0342017-01-04 22:35:44 +0000695 if (clearWindowProperties)
cdumez@apple.com87a798a2018-04-19 04:02:30 +0000696 m_frame.windowProxy().setDOMWindow(newDocument->domWindow());
bfulgham@apple.com472a0342017-01-04 22:35:44 +0000697
antti90500a32007-09-27 23:56:17 +0000698 if (clearScriptObjects)
akling@apple.com7f50aae2013-08-22 16:01:31 +0000699 m_frame.script().clearScriptObjects();
eric@webkit.org0683d942008-08-06 10:01:35 +0000700
akling@apple.com7f50aae2013-08-22 16:01:31 +0000701 m_frame.script().enableEval();
abarth@webkit.org9d220b62012-06-09 19:35:02 +0000702
akling@apple.com7f50aae2013-08-22 16:01:31 +0000703 m_frame.navigationScheduler().clear();
darinc370e7e2006-11-08 05:52:27 +0000704
darin@apple.comf53381b2009-09-23 23:27:01 +0000705 m_checkTimer.stop();
706 m_shouldCallCheckCompleted = false;
707 m_shouldCallCheckLoadComplete = false;
abarth@webkit.org91289c32010-04-12 04:54:55 +0000708
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +0000709 if (m_stateMachine.isDisplayingInitialEmptyDocument() && m_stateMachine.committedFirstRealDocumentLoad())
710 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
darinc370e7e2006-11-08 05:52:27 +0000711}
712
713void FrameLoader::receivedFirstData()
714{
commit-queue@webkit.orgc7d40872020-03-31 19:56:26 +0000715 auto protectedFrame = makeRef(m_frame);
716
achristensen@apple.come0301a32020-02-07 23:30:29 +0000717 dispatchDidCommitLoad(WTF::nullopt, WTF::nullopt);
jcivelli@chromium.org4b94add2011-11-19 08:45:01 +0000718 dispatchDidClearWindowObjectsInAllWorlds();
beidson@apple.com2a75a962012-04-24 18:12:55 +0000719 dispatchGlobalObjectAvailableInAllWorlds();
jcivelli@chromium.org4b94add2011-11-19 08:45:01 +0000720
darin8207db42007-02-20 18:18:39 +0000721 if (!m_documentLoader)
722 return;
abarth@webkit.org55d49da2011-06-20 23:32:54 +0000723
dbates@webkit.org66024662018-02-03 04:53:47 +0000724 auto& documentLoader = *m_documentLoader;
725 auto& title = documentLoader.title();
726 if (!title.string.isNull())
youenn@apple.comee96d0f2020-03-18 13:59:23 +0000727 m_client->dispatchDidReceiveTitle(title);
dbates@webkit.org66024662018-02-03 04:53:47 +0000728
darin@apple.comc04189e2017-01-18 05:17:17 +0000729 ASSERT(m_frame.document());
730 auto& document = *m_frame.document();
731
dbates@webkit.org66024662018-02-03 04:53:47 +0000732 LinkLoader::loadLinksFromHeader(documentLoader.response().httpHeaderField(HTTPHeaderName::Link), document.url(), document, LinkLoader::MediaAttributeCheck::MediaAttributeEmpty);
yoav@yoav.ws1c12d5c2017-01-19 07:13:54 +0000733
abarth@webkit.org55d49da2011-06-20 23:32:54 +0000734 double delay;
darin@apple.com47a20cb2014-04-27 16:06:27 +0000735 String urlString;
cdumez@apple.com63b7fdd2019-09-12 04:32:29 +0000736 if (!parseMetaHTTPEquivRefresh(documentLoader.response().httpHeaderField(HTTPHeaderName::Refresh), delay, urlString))
ape9991d52006-12-08 18:19:51 +0000737 return;
darin@apple.comc04189e2017-01-18 05:17:17 +0000738 auto completedURL = urlString.isEmpty() ? document.url() : document.completeURL(urlString);
commit-queue@webkit.org39359f02020-04-25 21:28:45 +0000739 if (!completedURL.protocolIsJavaScript())
darin@apple.comc04189e2017-01-18 05:17:17 +0000740 m_frame.navigationScheduler().scheduleRedirect(document, delay, completedURL);
ddkilzer@apple.com70f15392014-04-01 19:21:34 +0000741 else {
darin@apple.comc04189e2017-01-18 05:17:17 +0000742 auto message = "Refused to refresh " + document.url().stringCenterEllipsizedToLength() + " to a javascript: URL";
dbates@webkit.org66024662018-02-03 04:53:47 +0000743 document.addConsoleMessage(MessageSource::Security, MessageLevel::Error, message);
ddkilzer@apple.com70f15392014-04-01 19:21:34 +0000744 }
darinc370e7e2006-11-08 05:52:27 +0000745}
746
darin@apple.com5ffbb5c2013-09-27 16:39:41 +0000747void FrameLoader::setOutgoingReferrer(const URL& url)
japhet@chromium.orgb254c9b2011-01-26 19:14:26 +0000748{
levin@chromium.org1a2fef42011-03-01 02:10:28 +0000749 m_outgoingReferrer = url.strippedForUseAsReferrer();
abarth@webkit.org412c54e2010-04-20 22:12:16 +0000750}
abarth@webkit.org91289c32010-04-12 04:54:55 +0000751
dbates@webkit.org123b1af2019-09-23 21:56:43 +0000752void FrameLoader::didBeginDocument(bool dispatch)
abarth@webkit.org412c54e2010-04-20 22:12:16 +0000753{
754 m_needsClear = true;
755 m_isComplete = false;
756 m_didCallImplicitClose = false;
akling@apple.com7f50aae2013-08-22 16:01:31 +0000757 m_frame.document()->setReadyState(Document::Loading);
abarth@webkit.org91289c32010-04-12 04:54:55 +0000758
759 if (m_pendingStateObject) {
darin@apple.com961f2a52016-12-31 09:51:29 +0000760 m_frame.document()->statePopped(*m_pendingStateObject);
cdumez@apple.comd839ea12015-07-04 19:42:18 +0000761 m_pendingStateObject = nullptr;
abarth@webkit.org91289c32010-04-12 04:54:55 +0000762 }
abarth@webkit.org91289c32010-04-12 04:54:55 +0000763
andersca@apple.com6c6fb4b2009-08-12 22:03:02 +0000764 if (dispatch)
aroben@apple.com11dd5262009-11-13 23:49:05 +0000765 dispatchDidClearWindowObjectsInAllWorlds();
abarth@webkit.org412c54e2010-04-20 22:12:16 +0000766
abarth@webkit.org622d9df2009-05-22 16:44:47 +0000767 updateFirstPartyForCookies();
dbates@webkit.org123b1af2019-09-23 21:56:43 +0000768 m_frame.document()->initContentSecurityPolicy();
darinc370e7e2006-11-08 05:52:27 +0000769
akling@apple.com1c29edbc2013-08-23 23:19:21 +0000770 const Settings& settings = m_frame.settings();
cdumez@apple.com0bb03ec2015-01-28 05:53:53 +0000771 m_frame.document()->cachedResourceLoader().setImagesEnabled(settings.areImagesEnabled());
772 m_frame.document()->cachedResourceLoader().setAutoLoadImages(settings.loadsImagesAutomatically());
aroben@apple.com3adf2452008-02-07 23:19:31 +0000773
collinj@webkit.org9c672f62008-09-19 04:15:14 +0000774 if (m_documentLoader) {
andersca@apple.com30391b42014-06-16 19:26:49 +0000775 String dnsPrefetchControl = m_documentLoader->response().httpHeaderField(HTTPHeaderName::XDNSPrefetchControl);
collinj@webkit.org9c672f62008-09-19 04:15:14 +0000776 if (!dnsPrefetchControl.isEmpty())
akling@apple.com7f50aae2013-08-22 16:01:31 +0000777 m_frame.document()->parseDNSPrefetchControlHeader(dnsPrefetchControl);
jochen@chromium.orgadec40f2011-02-09 17:03:38 +0000778
dbates@webkit.org41f504e2018-05-07 17:52:34 +0000779 m_frame.document()->contentSecurityPolicy()->didReceiveHeaders(ContentSecurityPolicyResponseHeaders(m_documentLoader->response()), referrer(), ContentSecurityPolicy::ReportParsingErrors::No);
commit-queue@webkit.org26a3a092012-10-18 19:53:58 +0000780
cdumez@apple.com7c12c6c2018-05-30 21:30:21 +0000781 String referrerPolicy = m_documentLoader->response().httpHeaderField(HTTPHeaderName::ReferrerPolicy);
782 if (!referrerPolicy.isNull())
783 m_frame.document()->processReferrerPolicy(referrerPolicy, ReferrerPolicySource::HTTPHeader);
784
andersca@apple.com30391b42014-06-16 19:26:49 +0000785 String headerContentLanguage = m_documentLoader->response().httpHeaderField(HTTPHeaderName::ContentLanguage);
commit-queue@webkit.org26a3a092012-10-18 19:53:58 +0000786 if (!headerContentLanguage.isEmpty()) {
787 size_t commaIndex = headerContentLanguage.find(',');
788 headerContentLanguage.truncate(commaIndex); // notFound == -1 == don't truncate
darin@apple.com940b9ea2017-11-25 02:44:45 +0000789 headerContentLanguage = stripLeadingAndTrailingHTMLSpaces(headerContentLanguage);
commit-queue@webkit.org26a3a092012-10-18 19:53:58 +0000790 if (!headerContentLanguage.isEmpty())
akling@apple.com7f50aae2013-08-22 16:01:31 +0000791 m_frame.document()->setContentLanguage(headerContentLanguage);
commit-queue@webkit.org26a3a092012-10-18 19:53:58 +0000792 }
collinj@webkit.org9c672f62008-09-19 04:15:14 +0000793 }
794
akling@apple.com672cb852013-08-22 20:27:27 +0000795 history().restoreDocumentState();
darinc370e7e2006-11-08 05:52:27 +0000796}
797
darinc370e7e2006-11-08 05:52:27 +0000798void FrameLoader::finishedParsing()
799{
simon.fraser@apple.com677f0422017-12-02 17:55:24 +0000800 LOG(Loading, "WebCoreLoading %s: Finished parsing", m_frame.tree().uniqueName().string().utf8().data());
801
commit-queue@webkit.org11fed0a2020-04-04 00:44:31 +0000802 m_frame.injectUserScripts(UserScriptInjectionTime::DocumentEnd);
aestes@apple.come35644e2011-04-07 20:23:48 +0000803
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +0000804 if (m_stateMachine.creatingInitialEmptyDocument())
mjs8d620d52007-05-10 12:31:42 +0000805 return;
806
darinc370e7e2006-11-08 05:52:27 +0000807 // This can be called from the Frame's destructor, in which case we shouldn't protect ourselves
808 // because doing so will cause us to re-enter the destructor when protector goes out of scope.
beidson@apple.comf7eea402008-07-10 04:51:10 +0000809 // Null-checking the FrameView indicates whether or not we're in the destructor.
akling@apple.com7f50aae2013-08-22 16:01:31 +0000810 RefPtr<Frame> protector = m_frame.view() ? &m_frame : 0;
darinc370e7e2006-11-08 05:52:27 +0000811
youenn@apple.comee96d0f2020-03-18 13:59:23 +0000812 m_client->dispatchDidFinishDocumentLoad();
darin@chromium.org1750e242008-12-08 18:13:25 +0000813
cdumez@apple.com6d7c65e2015-09-02 17:07:57 +0000814 scrollToFragmentWithParentBoundary(m_frame.document()->url());
815
darinc370e7e2006-11-08 05:52:27 +0000816 checkCompleted();
817
akling@apple.com7f50aae2013-08-22 16:01:31 +0000818 if (!m_frame.view())
darinc370e7e2006-11-08 05:52:27 +0000819 return; // We are being destroyed by something checkCompleted called.
820
821 // Check if the scrollbars are really needed for the content.
822 // If not, remove them, relayout, and repaint.
akling@apple.com7f50aae2013-08-22 16:01:31 +0000823 m_frame.view()->restoreScrollbar();
darinc370e7e2006-11-08 05:52:27 +0000824}
825
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +0000826void FrameLoader::loadDone(LoadCompletionType type)
darinc370e7e2006-11-08 05:52:27 +0000827{
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +0000828 if (type == LoadCompletionType::Finish)
829 checkCompleted();
830 else
831 scheduleCheckCompleted();
832}
833
834void FrameLoader::subresourceLoadDone(LoadCompletionType type)
835{
836 if (type == LoadCompletionType::Finish)
837 checkLoadComplete();
838 else
839 scheduleCheckLoadComplete();
darinc370e7e2006-11-08 05:52:27 +0000840}
841
darin@apple.com4d9d7182009-09-23 00:38:04 +0000842bool FrameLoader::allChildrenAreComplete() const
843{
darin@apple.comfed4d162013-08-25 02:28:06 +0000844 for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling()) {
andersca@apple.comdf550b92013-08-15 22:17:17 +0000845 if (!child->loader().m_isComplete)
darin@apple.com4d9d7182009-09-23 00:38:04 +0000846 return false;
847 }
848 return true;
849}
850
darin@apple.comf53381b2009-09-23 23:27:01 +0000851bool FrameLoader::allAncestorsAreComplete() const
852{
darin@apple.comfed4d162013-08-25 02:28:06 +0000853 for (Frame* ancestor = &m_frame; ancestor; ancestor = ancestor->tree().parent()) {
andersca@apple.comdf550b92013-08-15 22:17:17 +0000854 if (!ancestor->loader().m_isComplete)
darin@apple.comf53381b2009-09-23 23:27:01 +0000855 return false;
856 }
857 return true;
858}
859
darinc370e7e2006-11-08 05:52:27 +0000860void FrameLoader::checkCompleted()
861{
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +0000862 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isScriptAllowed());
darin@apple.comf53381b2009-09-23 23:27:01 +0000863 m_shouldCallCheckCompleted = false;
864
darinc370e7e2006-11-08 05:52:27 +0000865 // Have we completed before?
866 if (m_isComplete)
867 return;
868
antti@apple.com079cbf52017-05-05 18:39:30 +0000869 // FIXME: It would be better if resource loads were kicked off after render tree update (or didn't complete synchronously).
870 // https://bugs.webkit.org/show_bug.cgi?id=171729
871 if (m_frame.document()->inRenderTreeUpdate()) {
872 scheduleCheckCompleted();
873 return;
874 }
875
darinc370e7e2006-11-08 05:52:27 +0000876 // Are we still parsing?
akling@apple.com7f50aae2013-08-22 16:01:31 +0000877 if (m_frame.document()->parsing())
darinc370e7e2006-11-08 05:52:27 +0000878 return;
879
880 // Still waiting for images/scripts?
cdumez@apple.com0bb03ec2015-01-28 05:53:53 +0000881 if (m_frame.document()->cachedResourceLoader().requestCount())
ap@webkit.orgf9b6eff2009-02-10 17:33:33 +0000882 return;
darinc370e7e2006-11-08 05:52:27 +0000883
eric.carlson@apple.com9c7fc722010-08-26 16:45:43 +0000884 // Still waiting for elements that don't go through a FrameLoader?
akling@apple.com7f50aae2013-08-22 16:01:31 +0000885 if (m_frame.document()->isDelayingLoadEvent())
eric.carlson@apple.com9c7fc722010-08-26 16:45:43 +0000886 return;
887
antti@apple.com9f4e3b22017-02-19 12:12:07 +0000888 auto* scriptableParser = m_frame.document()->scriptableDocumentParser();
889 if (scriptableParser && scriptableParser->hasScriptsWaitingForStylesheets())
890 return;
891
andreas.kling@nokia.com01f92442011-02-28 13:46:06 +0000892 // Any frame that hasn't completed yet?
893 if (!allChildrenAreComplete())
894 return;
895
darin@apple.comc2843002014-04-25 06:01:34 +0000896 // Important not to protect earlier in this function, because earlier parts
darin@apple.comfe9effd2014-04-25 06:02:42 +0000897 // of this function can be called in the frame's destructor, and it's not legal
darin@apple.comc2843002014-04-25 06:01:34 +0000898 // to ref an object while it's being destroyed.
899 Ref<Frame> protect(m_frame);
900
darinc370e7e2006-11-08 05:52:27 +0000901 // OK, completed.
902 m_isComplete = true;
cdumez@apple.comd839ea12015-07-04 19:42:18 +0000903 m_requestedHistoryItem = nullptr;
akling@apple.com7f50aae2013-08-22 16:01:31 +0000904 m_frame.document()->setReadyState(Document::Complete);
darinc370e7e2006-11-08 05:52:27 +0000905
ggarena57755c2007-07-09 21:08:10 +0000906 checkCallImplicitClose(); // if we didn't do it before
darinc370e7e2006-11-08 05:52:27 +0000907
akling@apple.com7f50aae2013-08-22 16:01:31 +0000908 m_frame.navigationScheduler().startTimer();
darinc370e7e2006-11-08 05:52:27 +0000909
910 completed();
akling@apple.com7f50aae2013-08-22 16:01:31 +0000911 if (m_frame.page())
mjs8d620d52007-05-10 12:31:42 +0000912 checkLoadComplete();
darinc370e7e2006-11-08 05:52:27 +0000913}
914
andersca@apple.com574a7452014-11-21 20:10:13 +0000915void FrameLoader::checkTimerFired()
weinigc34c71c2007-03-09 16:05:37 +0000916{
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +0000917 checkCompletenessNow();
918}
919
920void FrameLoader::checkCompletenessNow()
921{
akling@apple.comf8515982013-09-02 18:50:01 +0000922 Ref<Frame> protect(m_frame);
commit-queue@webkit.org667ee8b2012-02-08 02:21:04 +0000923
akling@apple.com7f50aae2013-08-22 16:01:31 +0000924 if (Page* page = m_frame.page()) {
darin@apple.comf53381b2009-09-23 23:27:01 +0000925 if (page->defersLoading())
926 return;
927 }
928 if (m_shouldCallCheckCompleted)
929 checkCompleted();
930 if (m_shouldCallCheckLoadComplete)
931 checkLoadComplete();
932}
933
934void FrameLoader::startCheckCompleteTimer()
935{
936 if (!(m_shouldCallCheckCompleted || m_shouldCallCheckLoadComplete))
937 return;
938 if (m_checkTimer.isActive())
939 return;
cdumez@apple.combc919b02017-04-09 14:49:14 +0000940 m_checkTimer.startOneShot(0_s);
weinigc34c71c2007-03-09 16:05:37 +0000941}
942
943void FrameLoader::scheduleCheckCompleted()
944{
darin@apple.comf53381b2009-09-23 23:27:01 +0000945 m_shouldCallCheckCompleted = true;
946 startCheckCompleteTimer();
beidson398923b2007-07-31 20:29:02 +0000947}
948
949void FrameLoader::scheduleCheckLoadComplete()
950{
darin@apple.comf53381b2009-09-23 23:27:01 +0000951 m_shouldCallCheckLoadComplete = true;
952 startCheckCompleteTimer();
beidson398923b2007-07-31 20:29:02 +0000953}
954
ggarena57755c2007-07-09 21:08:10 +0000955void FrameLoader::checkCallImplicitClose()
darinc370e7e2006-11-08 05:52:27 +0000956{
akling@apple.com7f50aae2013-08-22 16:01:31 +0000957 if (m_didCallImplicitClose || m_frame.document()->parsing() || m_frame.document()->isDelayingLoadEvent())
darinc370e7e2006-11-08 05:52:27 +0000958 return;
959
darin@apple.com4d9d7182009-09-23 00:38:04 +0000960 if (!allChildrenAreComplete())
961 return; // still got a frame running -> too early
darinc370e7e2006-11-08 05:52:27 +0000962
ggarena57755c2007-07-09 21:08:10 +0000963 m_didCallImplicitClose = true;
darinc370e7e2006-11-08 05:52:27 +0000964 m_wasUnloadEventEmitted = false;
akling@apple.com7f50aae2013-08-22 16:01:31 +0000965 m_frame.document()->implicitClose();
darinc370e7e2006-11-08 05:52:27 +0000966}
967
darin@apple.com5ffbb5c2013-09-27 16:39:41 +0000968void FrameLoader::loadURLIntoChildFrame(const URL& url, const String& referer, Frame* childFrame)
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000969{
krollin@apple.combdeaed72020-01-08 01:31:20 +0000970 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadURLIntoChildFrame: frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +0000971
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000972 ASSERT(childFrame);
darin@apple.coma7e141f2009-03-06 17:22:07 +0000973
jcivelli@chromium.orgc2019dd2011-05-24 19:32:03 +0000974#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
darin@apple.com961f2a52016-12-31 09:51:29 +0000975 if (auto activeLoader = activeDocumentLoader()) {
976 if (auto subframeArchive = activeLoader->popArchiveForSubframe(childFrame->tree().uniqueName(), url)) {
977 childFrame->loader().loadArchive(RefPtr<Archive> { subframeArchive }.releaseNonNull());
978 return;
979 }
mihaip@chromium.orge5dbd372010-12-08 02:32:41 +0000980 }
darin@apple.com961f2a52016-12-31 09:51:29 +0000981#endif
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000982
darin@apple.coma7e141f2009-03-06 17:22:07 +0000983 // If we're moving in the back/forward list, we might want to replace the content
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000984 // of this child frame with whatever was there at that point.
darin@apple.com961f2a52016-12-31 09:51:29 +0000985 auto* parentItem = history().currentItem();
986 if (parentItem && parentItem->children().size() && isBackForwardLoadType(loadType()) && !m_frame.document()->loadEventFinished()) {
987 if (auto* childItem = parentItem->childItemWithTarget(childFrame->tree().uniqueName())) {
ap@apple.com4d286a92013-08-19 23:41:18 +0000988 childFrame->loader().m_requestedHistoryItem = childItem;
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +0000989 childFrame->loader().loadDifferentDocumentItem(*childItem, nullptr, loadType(), MayAttemptCacheOnlyLoadForFormSubmissionItem, ShouldTreatAsContinuingLoad::No);
mihaip@chromium.orge5dbd372010-12-08 02:32:41 +0000990 return;
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000991 }
992 }
993
beidson@apple.com7034ec72017-07-06 00:01:53 +0000994 auto* lexicalFrame = lexicalFrameFromCommonVM();
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +0000995 auto initiatedByMainFrame = lexicalFrame && lexicalFrame->isMainFrame() ? InitiatedByMainFrame::Yes : InitiatedByMainFrame::Unknown;
beidson@apple.com7034ec72017-07-06 00:01:53 +0000996
commit-queue@webkit.org1b6bd842020-04-18 17:04:07 +0000997 FrameLoadRequest frameLoadRequest { *m_frame.document(), m_frame.document()->securityOrigin(), { url }, "_self"_s, initiatedByMainFrame };
998 frameLoadRequest.setNewFrameOpenerPolicy(NewFrameOpenerPolicy::Suppress);
999 frameLoadRequest.setLockBackForwardList(LockBackForwardList::Yes);
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +00001000 childFrame->loader().loadURL(WTFMove(frameLoadRequest), referer, FrameLoadType::RedirectWithLockedBackForwardList, nullptr, { }, WTF::nullopt, [] { });
beidson@apple.com47ef96f2015-05-29 16:38:13 +00001001}
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001002
jcivelli@chromium.orgc2019dd2011-05-24 19:32:03 +00001003#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
darin@apple.com961f2a52016-12-31 09:51:29 +00001004
1005void FrameLoader::loadArchive(Ref<Archive>&& archive)
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001006{
krollin@apple.combdeaed72020-01-08 01:31:20 +00001007 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadArchive: frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00001008
japhet@chromium.orgac5cd4b2012-04-12 19:27:28 +00001009 ArchiveResource* mainResource = archive->mainResource();
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001010 ASSERT(mainResource);
1011 if (!mainResource)
1012 return;
beidson@apple.comceb7cba2015-05-19 22:22:51 +00001013
jh718.park@samsung.com9f99af52016-03-15 00:22:45 +00001014 ResourceResponse response(URL(), mainResource->mimeType(), mainResource->data().size(), mainResource->textEncoding());
1015 SubstituteData substituteData(&mainResource->data(), URL(), response, SubstituteData::SessionHistoryVisibility::Hidden);
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001016
1017 ResourceRequest request(mainResource->url());
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001018
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001019 auto documentLoader = m_client->createDocumentLoader(request, substituteData);
darin@apple.com961f2a52016-12-31 09:51:29 +00001020 documentLoader->setArchive(WTFMove(archive));
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001021 load(documentLoader.get());
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001022}
darin@apple.com961f2a52016-12-31 09:51:29 +00001023
jcivelli@chromium.orgc2019dd2011-05-24 19:32:03 +00001024#endif // ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001025
darinc370e7e2006-11-08 05:52:27 +00001026String FrameLoader::outgoingReferrer() const
1027{
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001028 // See http://www.whatwg.org/specs/web-apps/current-work/#fetching-resources
1029 // for why we walk the parent chain for srcdoc documents.
akling@apple.com7f50aae2013-08-22 16:01:31 +00001030 Frame* frame = &m_frame;
antti@apple.com1f5a2462016-12-14 18:54:28 +00001031 while (frame && frame->document()->isSrcdocDocument()) {
darin@apple.comfed4d162013-08-25 02:28:06 +00001032 frame = frame->tree().parent();
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001033 // Srcdoc documents cannot be top-level documents, by definition,
1034 // because they need to be contained in iframes with the srcdoc.
1035 ASSERT(frame);
1036 }
antti@apple.com1f5a2462016-12-14 18:54:28 +00001037 if (!frame)
1038 return emptyString();
andersca@apple.comdf550b92013-08-15 22:17:17 +00001039 return frame->loader().m_outgoingReferrer;
darinc370e7e2006-11-08 05:52:27 +00001040}
1041
dbates@webkit.org28db74a2016-04-15 22:23:44 +00001042bool FrameLoader::checkIfFormActionAllowedByCSP(const URL& url, bool didReceiveRedirectResponse) const
commit-queue@webkit.org78e860e2012-08-16 12:42:09 +00001043{
1044 if (m_submittedFormURL.isEmpty())
1045 return true;
1046
dbates@webkit.org28db74a2016-04-15 22:23:44 +00001047 auto redirectResponseReceived = didReceiveRedirectResponse ? ContentSecurityPolicy::RedirectResponseReceived::Yes : ContentSecurityPolicy::RedirectResponseReceived::No;
commit-queue@webkit.org03af1952016-09-22 08:28:37 +00001048 return m_frame.document()->contentSecurityPolicy()->allowFormAction(url, redirectResponseReceived);
commit-queue@webkit.org78e860e2012-08-16 12:42:09 +00001049}
1050
darinc370e7e2006-11-08 05:52:27 +00001051Frame* FrameLoader::opener()
1052{
1053 return m_opener;
1054}
1055
1056void FrameLoader::setOpener(Frame* opener)
1057{
creis@chromium.org16d76c72012-12-04 17:39:26 +00001058 if (m_opener && !opener)
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001059 m_client->didDisownOpener();
creis@chromium.org16d76c72012-12-04 17:39:26 +00001060
rniwa@webkit.org2c6d4eb2017-07-01 21:26:31 +00001061 if (m_opener) {
1062 // When setOpener is called in ~FrameLoader, opener's m_frameLoader is already cleared.
1063 auto& openerFrameLoader = m_opener == &m_frame ? *this : m_opener->loader();
1064 openerFrameLoader.m_openedFrames.remove(&m_frame);
1065 }
cdumez@apple.com2e472362018-12-01 22:40:07 +00001066 if (opener) {
akling@apple.com7f50aae2013-08-22 16:01:31 +00001067 opener->loader().m_openedFrames.add(&m_frame);
cdumez@apple.com2e472362018-12-01 22:40:07 +00001068 if (auto* page = m_frame.page())
1069 page->setOpenedByDOMWithOpener();
1070 }
darinc370e7e2006-11-08 05:52:27 +00001071 m_opener = opener;
weinig343b6ff2007-08-07 03:08:53 +00001072
akling@apple.com7f50aae2013-08-22 16:01:31 +00001073 if (m_frame.document())
1074 m_frame.document()->initSecurityContext();
darinc370e7e2006-11-08 05:52:27 +00001075}
1076
eric@webkit.org4ffb1fe2010-09-03 04:28:12 +00001077// FIXME: This does not belong in FrameLoader!
darinc370e7e2006-11-08 05:52:27 +00001078void FrameLoader::handleFallbackContent()
1079{
akling@apple.com7f50aae2013-08-22 16:01:31 +00001080 HTMLFrameOwnerElement* owner = m_frame.ownerElement();
cdumez@apple.coma9c60c92014-10-02 19:39:41 +00001081 if (!is<HTMLObjectElement>(owner))
darinc370e7e2006-11-08 05:52:27 +00001082 return;
cdumez@apple.com72754ba2014-09-23 22:03:15 +00001083 downcast<HTMLObjectElement>(*owner).renderFallbackContent();
darinc370e7e2006-11-08 05:52:27 +00001084}
1085
1086void FrameLoader::provisionalLoadStarted()
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00001087{
1088 if (m_stateMachine.firstLayoutDone())
1089 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
achristensen@apple.com6fddc912018-10-18 21:16:52 +00001090 m_frame.navigationScheduler().cancel(NewLoadInProgress::Yes);
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001091 m_client->provisionalLoadStarted();
cdumez@apple.comef2c0152017-01-13 17:54:53 +00001092
1093 if (m_frame.isMainFrame()) {
sbarati@apple.comce7ec112018-04-17 15:57:32 +00001094 tracePoint(MainResourceLoadDidStartProvisional);
simon.fraser@apple.com83325b92017-03-17 00:47:16 +00001095
cdumez@apple.comef2c0152017-01-13 17:54:53 +00001096 if (auto* page = m_frame.page())
1097 page->didStartProvisionalLoad();
1098 }
darinc370e7e2006-11-08 05:52:27 +00001099}
1100
darinc370e7e2006-11-08 05:52:27 +00001101void FrameLoader::resetMultipleFormSubmissionProtection()
1102{
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001103 m_submittedFormURL = URL();
darinc370e7e2006-11-08 05:52:27 +00001104}
1105
abarth@webkit.org622d9df2009-05-22 16:44:47 +00001106void FrameLoader::updateFirstPartyForCookies()
darinc370e7e2006-11-08 05:52:27 +00001107{
darin@apple.comfed4d162013-08-25 02:28:06 +00001108 if (m_frame.tree().parent())
1109 setFirstPartyForCookies(m_frame.tree().parent()->document()->firstPartyForCookies());
darinc370e7e2006-11-08 05:52:27 +00001110 else
akling@apple.com7f50aae2013-08-22 16:01:31 +00001111 setFirstPartyForCookies(m_frame.document()->url());
darinc370e7e2006-11-08 05:52:27 +00001112}
1113
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001114void FrameLoader::setFirstPartyForCookies(const URL& url)
darinc370e7e2006-11-08 05:52:27 +00001115{
darin@apple.comfed4d162013-08-25 02:28:06 +00001116 for (Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext(&m_frame))
darin@apple.comaf8b1a92011-06-25 00:09:37 +00001117 frame->document()->setFirstPartyForCookies(url);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00001118
cdumez@apple.com0b8674fb2019-03-13 19:53:41 +00001119 RegistrableDomain registrableDomain(url);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00001120 for (Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext(&m_frame)) {
cdumez@apple.com0b8674fb2019-03-13 19:53:41 +00001121 if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(frame->document()->url()) || registrableDomain.matches(frame->document()->url()))
dbates@webkit.org940f0b82018-07-24 16:27:25 +00001122 frame->document()->setSiteForCookies(url);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00001123 }
darinc370e7e2006-11-08 05:52:27 +00001124}
1125
darin@apple.comd69216d2008-03-11 00:45:47 +00001126// This does the same kind of work that didOpenURL does, except it relies on the fact
darinc370e7e2006-11-08 05:52:27 +00001127// that a higher level already checked that the URLs match and the scrolling is the right thing to do.
darin@apple.com961f2a52016-12-31 09:51:29 +00001128void FrameLoader::loadInSameDocument(const URL& url, SerializedScriptValue* stateObject, bool isNewNavigation)
darinc370e7e2006-11-08 05:52:27 +00001129{
krollin@apple.combdeaed72020-01-08 01:31:20 +00001130 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadInSameDocument: frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00001131
beidson@apple.com08c61752009-12-03 19:04:40 +00001132 // If we have a state object, we cannot also be a new navigation.
1133 ASSERT(!stateObject || (stateObject && !isNewNavigation));
1134
1135 // Update the data source's request with the new URL to fake the URL change
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001136 URL oldURL = m_frame.document()->url();
akling@apple.com7f50aae2013-08-22 16:01:31 +00001137 m_frame.document()->setURL(url);
jochen@chromium.org7495f962012-05-04 16:43:03 +00001138 setOutgoingReferrer(url);
beidson@apple.com08c61752009-12-03 19:04:40 +00001139 documentLoader()->replaceRequestURLForSameDocumentNavigation(url);
1140 if (isNewNavigation && !shouldTreatURLAsSameAsCurrent(url) && !stateObject) {
1141 // NB: must happen after replaceRequestURLForSameDocumentNavigation(), since we add
1142 // based on the current request. Must also happen before we openURL and displace the
1143 // scroll position, since adding the BF item will save away scroll state.
1144
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00001145 // NB2: If we were loading a long, slow doc, and the user fragment navigated before
beidson@apple.com08c61752009-12-03 19:04:40 +00001146 // it was done, currItem is now set the that slow doc, and prevItem is whatever was
1147 // before it. Adding the b/f item will bump the slow doc down to prevItem, even
1148 // though its load is not yet done. I think this all works out OK, for one because
1149 // we have already saved away the scroll and doc state for the long slow load,
1150 // but it's not an obvious case.
1151
akling@apple.com672cb852013-08-22 20:27:27 +00001152 history().updateBackForwardListForFragmentScroll();
beidson@apple.com8127cdc2009-08-07 15:35:19 +00001153 }
darin@apple.com1e231d52020-04-25 18:01:55 +00001154
1155 bool hashChange = equalIgnoringFragmentIdentifier(url, oldURL) && !equalRespectingNullity(url.fragmentIdentifier(), oldURL.fragmentIdentifier());
1156
akling@apple.com672cb852013-08-22 20:27:27 +00001157 history().updateForSameDocumentNavigation();
britto@apple.com195cc0b2008-07-23 16:48:47 +00001158
1159 // If we were in the autoscroll/panScroll mode we want to stop it before following the link to the anchor
beidson@apple.com08c61752009-12-03 19:04:40 +00001160 if (hashChange)
akling@apple.com7f50aae2013-08-22 16:01:31 +00001161 m_frame.eventHandler().stopAutoscrollTimer();
beidson@apple.com08c61752009-12-03 19:04:40 +00001162
darinc370e7e2006-11-08 05:52:27 +00001163 // It's important to model this as a load that starts and immediately finishes.
1164 // Otherwise, the parent frame may think we never finished loading.
beidson@apple.com08c61752009-12-03 19:04:40 +00001165 started();
japhet@chromium.org48bb2602010-03-04 23:01:45 +00001166
dbates@webkit.org86a1c672018-08-10 17:39:53 +00001167 if (auto* ownerElement = m_frame.ownerElement()) {
1168 auto* ownerRenderer = ownerElement->renderer();
1169 auto* view = m_frame.view();
1170 if (is<RenderWidget>(ownerRenderer) && view)
1171 downcast<RenderWidget>(*ownerRenderer).setWidget(view);
1172 }
1173
japhet@chromium.org48bb2602010-03-04 23:01:45 +00001174 // We need to scroll to the fragment whether or not a hash change occurred, since
1175 // the user might have scrolled since the previous navigation.
simon.fraser@apple.comc79e4862017-03-08 20:01:15 +00001176 scrollToFragmentWithParentBoundary(url, isNewNavigation);
beidson@apple.com08c61752009-12-03 19:04:40 +00001177
darinc370e7e2006-11-08 05:52:27 +00001178 m_isComplete = false;
1179 checkCompleted();
beidson@apple.com08c61752009-12-03 19:04:40 +00001180
1181 if (isNewNavigation) {
1182 // This will clear previousItem from the rest of the frame tree that didn't
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00001183 // doing any loading. We need to make a pass on this now, since for fragment
1184 // navigation we'll not go through a real load and reach Completed state.
beidson@apple.com08c61752009-12-03 19:04:40 +00001185 checkLoadComplete();
1186 }
1187
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001188 m_client->dispatchDidNavigateWithinPage();
darin@chromium.orgfe279962010-03-16 17:26:59 +00001189
darin@apple.com961f2a52016-12-31 09:51:29 +00001190 m_frame.document()->statePopped(stateObject ? Ref<SerializedScriptValue> { *stateObject } : SerializedScriptValue::nullValue());
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001191 m_client->dispatchDidPopStateWithinPage();
beidson@apple.com08c61752009-12-03 19:04:40 +00001192
1193 if (hashChange) {
commit-queue@webkit.org39359f02020-04-25 21:28:45 +00001194 m_frame.document()->enqueueHashchangeEvent(oldURL.string(), url.string());
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001195 m_client->dispatchDidChangeLocationWithinPage();
beidson@apple.com08c61752009-12-03 19:04:40 +00001196 }
1197
1198 // FrameLoaderClient::didFinishLoad() tells the internal load delegate the load finished with no error
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001199 m_client->didFinishLoad();
darinc370e7e2006-11-08 05:52:27 +00001200}
1201
1202bool FrameLoader::isComplete() const
1203{
1204 return m_isComplete;
1205}
1206
darinc370e7e2006-11-08 05:52:27 +00001207void FrameLoader::completed()
1208{
akling@apple.comf8515982013-09-02 18:50:01 +00001209 Ref<Frame> protect(m_frame);
beidson@apple.coma5662512009-10-27 00:19:33 +00001210
darin@apple.comfed4d162013-08-25 02:28:06 +00001211 for (Frame* descendant = m_frame.tree().traverseNext(&m_frame); descendant; descendant = descendant->tree().traverseNext(&m_frame))
akling@apple.com9ce995f2013-08-21 20:54:20 +00001212 descendant->navigationScheduler().startTimer();
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00001213
darin@apple.comfed4d162013-08-25 02:28:06 +00001214 if (Frame* parent = m_frame.tree().parent())
andersca@apple.comdf550b92013-08-15 22:17:17 +00001215 parent->loader().checkCompleted();
beidson@apple.coma5662512009-10-27 00:19:33 +00001216
akling@apple.com7f50aae2013-08-22 16:01:31 +00001217 if (m_frame.view())
mmaxfield@apple.com6ebeece2014-12-09 21:03:54 +00001218 m_frame.view()->maintainScrollPositionAtAnchor(nullptr);
darinc370e7e2006-11-08 05:52:27 +00001219}
1220
1221void FrameLoader::started()
1222{
darin@apple.comfed4d162013-08-25 02:28:06 +00001223 for (Frame* frame = &m_frame; frame; frame = frame->tree().parent())
andersca@apple.comdf550b92013-08-15 22:17:17 +00001224 frame->loader().m_isComplete = false;
darinc370e7e2006-11-08 05:52:27 +00001225}
1226
achristensen@apple.comc41ad692019-01-31 21:23:44 +00001227void FrameLoader::prepareForLoadStart()
darinc370e7e2006-11-08 05:52:27 +00001228{
krollin@apple.combdeaed72020-01-08 01:31:20 +00001229 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "prepareForLoadStart: Starting frame load");
commit-queue@webkit.org6d635222016-03-08 06:44:59 +00001230
japhet@chromium.org7879dd72012-08-30 02:58:37 +00001231 m_progressTracker->progressStarted();
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001232 m_client->dispatchDidStartProvisionalLoad();
achristensen@apple.comc41ad692019-01-31 21:23:44 +00001233
1234 if (AXObjectCache::accessibilityEnabled()) {
1235 if (AXObjectCache* cache = m_frame.document()->existingAXObjectCache()) {
1236 AXObjectCache::AXLoadingEvent loadingEvent = loadType() == FrameLoadType::Reload ? AXObjectCache::AXLoadingReloaded : AXObjectCache::AXLoadingStarted;
1237 cache->frameLoadingEventNotification(&m_frame, loadingEvent);
ossy@webkit.org451e9b02014-01-27 12:40:18 +00001238 }
achristensen@apple.comc41ad692019-01-31 21:23:44 +00001239 }
darinc370e7e2006-11-08 05:52:27 +00001240}
1241
1242void FrameLoader::setupForReplace()
1243{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001244 m_client->revertToProvisionalState(m_documentLoader.get());
darinc370e7e2006-11-08 05:52:27 +00001245 setState(FrameStateProvisional);
1246 m_provisionalDocumentLoader = m_documentLoader;
krollin@apple.combdeaed72020-01-08 01:31:20 +00001247 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "setupForReplace: Setting provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
cdumez@apple.comd839ea12015-07-04 19:42:18 +00001248 m_documentLoader = nullptr;
darinc370e7e2006-11-08 05:52:27 +00001249 detachChildren();
1250}
1251
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +00001252void FrameLoader::loadFrameRequest(FrameLoadRequest&& request, Event* event, RefPtr<FormState>&& formState, Optional<AdClickAttribution>&& adClickAttribution)
dbates@webkit.org29908522017-01-07 07:14:03 +00001253{
krollin@apple.combdeaed72020-01-08 01:31:20 +00001254 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadFrameRequest: frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00001255
inferno@chromium.org670ab752011-07-13 18:51:44 +00001256 // Protect frame from getting blown away inside dispatchBeforeLoadEvent in loadWithDocumentLoader.
darin@apple.comc04189e2017-01-18 05:17:17 +00001257 auto protectFrame = makeRef(m_frame);
inferno@chromium.org670ab752011-07-13 18:51:44 +00001258
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001259 URL url = request.resourceRequest().url();
antti@apple.comc633dca2008-11-14 21:34:55 +00001260
akling@apple.com7f50aae2013-08-22 16:01:31 +00001261 ASSERT(m_frame.document());
dbates@webkit.org174ac712017-06-30 21:35:23 +00001262 if (!request.requesterSecurityOrigin().canDisplay(url)) {
akling@apple.com7f50aae2013-08-22 16:01:31 +00001263 reportLocalLoadFailed(&m_frame, url.stringCenterEllipsizedToLength());
darin@apple.com1cf3d562010-12-07 16:23:03 +00001264 return;
1265 }
1266
darin5a1e60e2007-04-17 19:58:16 +00001267 String argsReferrer = request.resourceRequest().httpReferrer();
jochen@chromium.org4761ef52011-11-21 10:29:55 +00001268 if (argsReferrer.isEmpty())
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001269 argsReferrer = outgoingReferrer();
antti@apple.comc633dca2008-11-14 21:34:55 +00001270
commit-queue@webkit.org8383b5f2020-03-02 11:36:00 +00001271 ReferrerPolicy referrerPolicy = request.referrerPolicy();
1272 if (referrerPolicy == ReferrerPolicy::EmptyString)
1273 referrerPolicy = m_frame.document()->referrerPolicy();
1274 String referrer = SecurityPolicy::generateReferrerHeader(referrerPolicy, url, argsReferrer);
beidson@apple.comee119d42015-04-28 19:38:13 +00001275
ggaren@apple.com78b4dc62009-01-30 23:09:43 +00001276 FrameLoadType loadType;
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00001277 if (request.resourceRequest().cachePolicy() == ResourceRequestCachePolicy::ReloadIgnoringCacheData)
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001278 loadType = FrameLoadType::Reload;
beidson@apple.comee119d42015-04-28 19:38:13 +00001279 else if (request.lockBackForwardList() == LockBackForwardList::Yes)
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001280 loadType = FrameLoadType::RedirectWithLockedBackForwardList;
ggaren@apple.com78b4dc62009-01-30 23:09:43 +00001281 else
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001282 loadType = FrameLoadType::Standard;
ggaren@apple.com78b4dc62009-01-30 23:09:43 +00001283
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00001284 auto completionHandler = [this, protectedFrame = makeRef(m_frame), formState = makeWeakPtr(formState.get()), frameName = request.frameName()] {
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001285 // FIXME: It's possible this targetFrame will not be the same frame that was targeted by the actual
1286 // load if frame names have changed.
1287 Frame* sourceFrame = formState ? formState->sourceDocument().frame() : &m_frame;
1288 if (!sourceFrame)
1289 sourceFrame = &m_frame;
1290 Frame* targetFrame = sourceFrame->loader().findFrameForNavigation(frameName);
1291 if (targetFrame && targetFrame != sourceFrame) {
1292 if (Page* page = targetFrame->page())
1293 page->chrome().focus();
1294 }
1295 };
ggaren@apple.com78b4dc62009-01-30 23:09:43 +00001296
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001297 if (request.resourceRequest().httpMethod() == "POST")
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00001298 loadPostRequest(WTFMove(request), referrer, loadType, event, WTFMove(formState), WTFMove(completionHandler));
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001299 else
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +00001300 loadURL(WTFMove(request), referrer, loadType, event, WTFMove(formState), WTFMove(adClickAttribution), WTFMove(completionHandler));
anderscade5715d2007-01-06 00:55:49 +00001301}
ddkilzer@apple.come6e7d422008-08-06 21:15:39 +00001302
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001303static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& currentFrame, InitiatedByMainFrame initiatedByMainFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
mitz@apple.comc99c7152015-07-17 21:16:09 +00001304{
commit-queue@webkit.org635dbdc2017-11-23 19:36:08 +00001305 if (UserGestureIndicator::processingUserGesture())
mitz@apple.comc99c7152015-07-17 21:16:09 +00001306 return ShouldOpenExternalURLsPolicy::ShouldAllow;
beidson@apple.com7034ec72017-07-06 00:01:53 +00001307
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001308 if (initiatedByMainFrame == InitiatedByMainFrame::Yes)
beidson@apple.com7034ec72017-07-06 00:01:53 +00001309 return propagatedPolicy;
1310
1311 if (!currentFrame.isMainFrame())
1312 return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
1313
mitz@apple.comc99c7152015-07-17 21:16:09 +00001314 return propagatedPolicy;
1315}
1316
beidson@apple.com7034ec72017-07-06 00:01:53 +00001317static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& currentFrame, const FrameLoadRequest& frameLoadRequest)
1318{
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001319 return shouldOpenExternalURLsPolicyToApply(currentFrame, frameLoadRequest.initiatedByMainFrame(), frameLoadRequest.shouldOpenExternalURLsPolicy());
beidson@apple.com7034ec72017-07-06 00:01:53 +00001320}
1321
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001322static void applyShouldOpenExternalURLsPolicyToNewDocumentLoader(Frame& frame, DocumentLoader& documentLoader, InitiatedByMainFrame initiatedByMainFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
beidson@apple.com7034ec72017-07-06 00:01:53 +00001323{
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001324 documentLoader.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(frame, initiatedByMainFrame, propagatedPolicy));
beidson@apple.com7034ec72017-07-06 00:01:53 +00001325}
1326
1327static void applyShouldOpenExternalURLsPolicyToNewDocumentLoader(Frame& frame, DocumentLoader& documentLoader, const FrameLoadRequest& frameLoadRequest)
1328{
1329 documentLoader.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(frame, frameLoadRequest));
1330}
1331
dbates@webkit.org872db612017-03-20 23:07:50 +00001332bool FrameLoader::isNavigationAllowed() const
1333{
beidson@apple.comb4571302019-08-08 15:54:37 +00001334 return m_pageDismissalEventBeingDispatched == PageDismissalType::None && !m_frame.script().willReplaceWithResultOfExecutingJavascriptURL() && NavigationDisabler::isNavigationAllowed(m_frame);
dbates@webkit.org872db612017-03-20 23:07:50 +00001335}
1336
pvollan@apple.com8f4bcd952018-02-01 04:18:38 +00001337bool FrameLoader::isStopLoadingAllowed() const
1338{
1339 return m_pageDismissalEventBeingDispatched == PageDismissalType::None;
1340}
1341
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +00001342void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& referrer, FrameLoadType newLoadType, Event* event, RefPtr<FormState>&& formState, Optional<AdClickAttribution>&& adClickAttribution, CompletionHandler<void()>&& completionHandler)
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001343{
krollin@apple.combdeaed72020-01-08 01:31:20 +00001344 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadURL: frame load started");
commit-queue@webkit.org8a13ad32020-03-16 08:11:26 +00001345 ASSERT(frameLoadRequest.resourceRequest().httpMethod() == "GET");
krollin@apple.come1810b62018-12-20 19:23:20 +00001346
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001347 CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
cdumez@apple.com8ace63b2018-06-29 22:56:29 +00001348 if (m_inStopAllLoaders || m_inClearProvisionalLoadForPolicyCheck)
commit-queue@webkit.orgcd5cda22011-02-15 15:55:21 +00001349 return;
1350
jpfau@apple.com18da22e2014-06-19 00:20:25 +00001351 Ref<Frame> protect(m_frame);
1352
cdumez@apple.com3ed26742018-10-09 23:21:18 +00001353 // Anchor target is ignored when the download attribute is set since it will download the hyperlink rather than follow it.
1354 String effectiveFrameName = frameLoadRequest.downloadAttribute().isNull() ? frameLoadRequest.frameName() : String();
andersca3513ce02007-05-17 08:38:44 +00001355 bool isFormSubmission = formState;
beidson@apple.combd66a782015-05-29 16:31:49 +00001356
commit-queue@webkit.orga6227742020-04-21 10:31:08 +00001357 // The search for a target frame is done earlier in the case of form submission.
1358 auto targetFrame = isFormSubmission ? nullptr : makeRefPtr(findFrameForNavigation(effectiveFrameName));
1359 if (targetFrame && targetFrame != &m_frame) {
1360 frameLoadRequest.setFrameName("_self");
1361 targetFrame->loader().loadURL(WTFMove(frameLoadRequest), referrer, newLoadType, event, WTFMove(formState), WTFMove(adClickAttribution), completionHandlerCaller.release());
1362 return;
1363 }
1364
beidson@apple.combd66a782015-05-29 16:31:49 +00001365 const URL& newURL = frameLoadRequest.resourceRequest().url();
weinig@apple.comc5002662007-12-12 07:26:19 +00001366 ResourceRequest request(newURL);
commit-queue@webkit.org34807862020-03-29 17:34:16 +00001367 if (!referrer.isEmpty())
anderscade5715d2007-01-06 00:55:49 +00001368 request.setHTTPReferrer(referrer);
commit-queue@webkit.org34807862020-03-29 17:34:16 +00001369
commit-queue@webkit.org627a2de2020-04-13 08:04:39 +00001370 addExtraFieldsToRequest(request, IsMainResource::Yes, newLoadType);
anderscade5715d2007-01-06 00:55:49 +00001371
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001372 ASSERT(newLoadType != FrameLoadType::Same);
anderscade5715d2007-01-06 00:55:49 +00001373
dbates@webkit.org872db612017-03-20 23:07:50 +00001374 if (!isNavigationAllowed())
eric@webkit.org6cae31a2009-09-26 02:35:15 +00001375 return;
1376
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00001377 NavigationAction action { frameLoadRequest.requester(), request, frameLoadRequest.initiatedByMainFrame(), newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy(), frameLoadRequest.downloadAttribute() };
commit-queue@webkit.orga6227742020-04-21 10:31:08 +00001378 action.setLockHistory(frameLoadRequest.lockHistory());
cdumez@apple.com05911a32018-10-23 17:54:34 +00001379 action.setLockBackForwardList(frameLoadRequest.lockBackForwardList());
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +00001380 if (adClickAttribution && m_frame.isMainFrame())
1381 action.setAdClickAttribution(WTFMove(*adClickAttribution));
anderscade5715d2007-01-06 00:55:49 +00001382
commit-queue@webkit.orga6227742020-04-21 10:31:08 +00001383 NewFrameOpenerPolicy openerPolicy = frameLoadRequest.newFrameOpenerPolicy();
1384 AllowNavigationToInvalidURL allowNavigationToInvalidURL = frameLoadRequest.allowNavigationToInvalidURL();
cdumez@apple.com3ed26742018-10-09 23:21:18 +00001385 if (!targetFrame && !effectiveFrameName.isEmpty()) {
beidson@apple.com7034ec72017-07-06 00:01:53 +00001386 action = action.copyWithShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, frameLoadRequest));
commit-queue@webkit.orge051df22020-01-01 02:27:01 +00001387 policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request), WTFMove(formState), effectiveFrameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, PolicyChecker::ShouldContinue shouldContinue) mutable {
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00001388 continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001389 completionHandler();
andersca@apple.com096333f2013-11-07 21:37:36 +00001390 });
anderscade5715d2007-01-06 00:55:49 +00001391 return;
1392 }
1393
1394 RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
1395
weinig@apple.comc5002662007-12-12 07:26:19 +00001396 bool sameURL = shouldTreatURLAsSameAsCurrent(newURL);
yael.aharon@nokia.com79f69052010-12-30 19:31:00 +00001397 const String& httpMethod = request.httpMethod();
anderscade5715d2007-01-06 00:55:49 +00001398
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00001399 // Make sure to do scroll to fragment processing even if the URL is
anderscade5715d2007-01-06 00:55:49 +00001400 // exactly the same so pages with '#' links and DHTML side effects
1401 // work properly.
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00001402 if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, newLoadType, newURL)) {
cdumez@apple.com91e03bd2018-09-17 17:15:07 +00001403 oldDocumentLoader->setTriggeringAction(WTFMove(action));
andersca@apple.com97ab6d92013-10-21 22:55:14 +00001404 oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001405 policyChecker().stopCheck();
1406 policyChecker().setLoadType(newLoadType);
rniwa@webkit.orgba12a012019-02-03 22:48:22 +00001407 RELEASE_ASSERT(!isBackForwardLoadType(newLoadType) || history().provisionalItem());
cdumez@apple.com2e665842019-02-01 22:52:58 +00001408 policyChecker().checkNavigationPolicy(WTFMove(request), ResourceResponse { } /* redirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, NavigationPolicyDecision navigationPolicyDecision) {
1409 continueFragmentScrollAfterNavigationPolicy(request, navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad);
cdumez@apple.com82211942018-04-17 18:13:49 +00001410 }, PolicyDecisionMode::Synchronous);
andersca@apple.com096333f2013-11-07 21:37:36 +00001411 return;
1412 }
1413
dino@apple.comb8e413d2018-05-08 20:12:24 +00001414 // Must grab this now, since this load may stop the previous load and clear this flag.
andersca@apple.com096333f2013-11-07 21:37:36 +00001415 bool isRedirect = m_quickRedirectComing;
dino@apple.com0bebb3a2018-05-22 23:56:01 +00001416#if USE(SYSTEM_PREVIEW)
1417 bool isSystemPreview = frameLoadRequest.isSystemPreview();
dino@apple.com0bebb3a2018-05-22 23:56:01 +00001418 if (isSystemPreview)
dino@apple.comddfbca82019-09-13 21:43:18 +00001419 request.setSystemPreviewInfo(frameLoadRequest.systemPreviewInfo());
dino@apple.com0bebb3a2018-05-22 23:56:01 +00001420#endif
commit-queue@webkit.org4a7ad282020-04-05 05:09:42 +00001421 loadWithNavigationAction(request, WTFMove(action), newLoadType, WTFMove(formState), allowNavigationToInvalidURL, frameLoadRequest.downloadAttribute(), [this, isRedirect, sameURL, newLoadType, protectedFrame = makeRef(m_frame), completionHandler = completionHandlerCaller.release()] () mutable {
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001422 if (isRedirect) {
1423 m_quickRedirectComing = false;
1424 if (m_provisionalDocumentLoader)
1425 m_provisionalDocumentLoader->setIsClientRedirect(true);
1426 else if (m_policyDocumentLoader)
1427 m_policyDocumentLoader->setIsClientRedirect(true);
1428 } else if (sameURL && !isReload(newLoadType)) {
1429 // Example of this case are sites that reload the same URL with a different cookie
1430 // driving the generated content, or a master frame with links that drive a target
1431 // frame, where the user has clicked on the same link repeatedly.
1432 m_loadType = FrameLoadType::Same;
1433 }
1434 completionHandler();
1435 });
anderscade5715d2007-01-06 00:55:49 +00001436}
1437
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001438SubstituteData FrameLoader::defaultSubstituteDataForURL(const URL& url)
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001439{
1440 if (!shouldTreatURLAsSrcdocDocument(url))
1441 return SubstituteData();
darin@apple.comf9da7a72017-06-04 18:19:16 +00001442 auto& srcdoc = m_frame.ownerElement()->attributeWithoutSynchronization(srcdocAttr);
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001443 ASSERT(!srcdoc.isNull());
darin@apple.comf9da7a72017-06-04 18:19:16 +00001444 CString encodedSrcdoc = srcdoc.string().utf8();
beidson@apple.comceb7cba2015-05-19 22:22:51 +00001445
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00001446 ResourceResponse response(URL(), "text/html"_s, encodedSrcdoc.length(), "UTF-8"_s);
beidson@apple.comceb7cba2015-05-19 22:22:51 +00001447 return SubstituteData(SharedBuffer::create(encodedSrcdoc.data(), encodedSrcdoc.length()), URL(), response, SubstituteData::SessionHistoryVisibility::Hidden);
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001448}
1449
dbates@webkit.org7f3a9822017-06-22 19:45:10 +00001450void FrameLoader::load(FrameLoadRequest&& request)
anderscade5715d2007-01-06 00:55:49 +00001451{
krollin@apple.combdeaed72020-01-08 01:31:20 +00001452 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "load (FrameLoadRequest): frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00001453
cdumez@apple.com8ace63b2018-06-29 22:56:29 +00001454 if (m_inStopAllLoaders || m_inClearProvisionalLoadForPolicyCheck)
andersca8567b3d2007-03-21 05:46:49 +00001455 return;
simonjam@chromium.orgc98850b2012-11-28 01:07:36 +00001456
1457 if (!request.frameName().isEmpty()) {
1458 Frame* frame = findFrameForNavigation(request.frameName());
1459 if (frame) {
1460 request.setShouldCheckNewWindowPolicy(false);
andersca@apple.comdf550b92013-08-15 22:17:17 +00001461 if (&frame->loader() != this) {
dbates@webkit.org7f3a9822017-06-22 19:45:10 +00001462 frame->loader().load(WTFMove(request));
simonjam@chromium.orgc98850b2012-11-28 01:07:36 +00001463 return;
1464 }
1465 }
1466 }
1467
1468 if (request.shouldCheckNewWindowPolicy()) {
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00001469 NavigationAction action { request.requester(), request.resourceRequest(), InitiatedByMainFrame::Unknown, NavigationType::Other, request.shouldOpenExternalURLsPolicy() };
commit-queue@webkit.orge051df22020-01-01 02:27:01 +00001470 policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request.resourceRequest()), { }, request.frameName(), [this] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, PolicyChecker::ShouldContinue shouldContinue) {
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00001471 continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
andersca@apple.com096333f2013-11-07 21:37:36 +00001472 });
1473
simonjam@chromium.orgc98850b2012-11-28 01:07:36 +00001474 return;
1475 }
1476
1477 if (!request.hasSubstituteData())
1478 request.setSubstituteData(defaultSubstituteDataForURL(request.resourceRequest().url()));
1479
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001480 Ref<DocumentLoader> loader = m_client->createDocumentLoader(request.resourceRequest(), request.substituteData());
jiewen_tan@apple.com32abaa62019-02-13 23:07:13 +00001481 loader->setAllowsWebArchiveForMainFrame(request.isRequestFromClientOrUserInput());
bfulgham@apple.com2eaf0ac2020-02-06 17:32:18 +00001482 loader->setAllowsDataURLsForMainFrame(request.isRequestFromClientOrUserInput());
dbates@webkit.org8c917f22018-04-24 07:36:59 +00001483 addSameSiteInfoToRequestIfNeeded(loader->request());
beidson@apple.com7034ec72017-07-06 00:01:53 +00001484 applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, request);
beidson@apple.comd0558532015-05-28 04:52:25 +00001485
cdumez@apple.com4353b6e2018-10-26 05:06:24 +00001486 if (request.shouldTreatAsContinuingLoad()) {
cdumez@apple.com05911a32018-10-23 17:54:34 +00001487 loader->setClientRedirectSourceForHistory(request.clientRedirectSourceForHistory());
cdumez@apple.com4353b6e2018-10-26 05:06:24 +00001488 if (request.lockBackForwardList() == LockBackForwardList::Yes) {
1489 loader->setIsClientRedirect(true);
1490 m_loadType = FrameLoadType::RedirectWithLockedBackForwardList;
1491 }
cdumez@apple.com05911a32018-10-23 17:54:34 +00001492 }
1493
cdumez@apple.com3aedc032019-01-31 02:23:55 +00001494 SetForScope<LoadContinuingState> continuingLoadGuard(m_currentLoadContinuingState, request.shouldTreatAsContinuingLoad() ? LoadContinuingState::ContinuingWithRequest : LoadContinuingState::NotContinuing);
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001495 load(loader.get());
anderscade5715d2007-01-06 00:55:49 +00001496}
1497
commit-queue@webkit.org4a7ad282020-04-05 05:09:42 +00001498void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, NavigationAction&& action, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, const String& downloadAttribute, CompletionHandler<void()>&& completionHandler)
anderscade5715d2007-01-06 00:55:49 +00001499{
krollin@apple.combdeaed72020-01-08 01:31:20 +00001500 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadWithNavigationAction: frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00001501
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001502 Ref<DocumentLoader> loader = m_client->createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
commit-queue@webkit.orga4a9ce22019-04-10 22:56:35 +00001503 loader->setDownloadAttribute(downloadAttribute);
dbates@webkit.org9692a072017-07-12 18:01:19 +00001504 applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, action.initiatedByMainFrame(), action.shouldOpenExternalURLsPolicy());
beidson@apple.com87dc6312015-06-02 18:43:13 +00001505
commit-queue@webkit.org4a7ad282020-04-05 05:09:42 +00001506 if (action.lockHistory() == LockHistory::Yes && m_documentLoader)
commit-queue@webkit.org63040d02011-03-26 00:30:40 +00001507 loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
anderscade5715d2007-01-06 00:55:49 +00001508
cdumez@apple.com91e03bd2018-09-17 17:15:07 +00001509 loader->setTriggeringAction(WTFMove(action));
anderscade5715d2007-01-06 00:55:49 +00001510 if (m_documentLoader)
1511 loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
1512
commit-queue@webkit.org372c2642020-04-03 16:53:48 +00001513 loadWithDocumentLoader(loader.ptr(), type, WTFMove(formState), allowNavigationToInvalidURL, WTFMove(completionHandler));
anderscade5715d2007-01-06 00:55:49 +00001514}
1515
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001516void FrameLoader::load(DocumentLoader& newDocumentLoader)
anderscade5715d2007-01-06 00:55:49 +00001517{
krollin@apple.combdeaed72020-01-08 01:31:20 +00001518 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "load (DocumentLoader): frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00001519
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001520 ResourceRequest& r = newDocumentLoader.request();
commit-queue@webkit.org53c0a6b2020-04-02 07:43:14 +00001521 // FIXME: Using m_loadType seems wrong here.
1522 // If we are only preparing to load the main resource, that is previous load's load type!
commit-queue@webkit.org627a2de2020-04-13 08:04:39 +00001523 addExtraFieldsToRequest(r, IsMainResource::Yes, m_loadType);
anderscade5715d2007-01-06 00:55:49 +00001524 FrameLoadType type;
1525
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001526 if (shouldTreatURLAsSameAsCurrent(newDocumentLoader.originalRequest().url())) {
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00001527 r.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001528 type = FrameLoadType::Same;
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001529 } else if (shouldTreatURLAsSameAsCurrent(newDocumentLoader.unreachableURL()) && isReload(m_loadType))
commit-queue@webkit.orgfb4593b2018-04-18 17:50:15 +00001530 type = m_loadType;
cdumez@apple.com3aedc032019-01-31 02:23:55 +00001531 else if (m_loadType == FrameLoadType::RedirectWithLockedBackForwardList && ((!newDocumentLoader.unreachableURL().isEmpty() && newDocumentLoader.substituteData().isValid()) || shouldTreatCurrentLoadAsContinuingLoad()))
aestes@apple.com176a9aa2016-07-08 20:14:34 +00001532 type = FrameLoadType::RedirectWithLockedBackForwardList;
jpfau@apple.com6e5a6052012-07-27 00:52:32 +00001533 else
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001534 type = FrameLoadType::Standard;
anderscade5715d2007-01-06 00:55:49 +00001535
1536 if (m_documentLoader)
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001537 newDocumentLoader.setOverrideEncoding(m_documentLoader->overrideEncoding());
anderscade5715d2007-01-06 00:55:49 +00001538
1539 // When we loading alternate content for an unreachable URL that we're
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001540 // visiting in the history list, we treat it as a reload so the history list
anderscade5715d2007-01-06 00:55:49 +00001541 // is appropriately maintained.
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001542 //
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001543 // FIXME: This seems like a dangerous overloading of the meaning of "FrameLoadType::Reload" ...
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001544 // shouldn't a more explicit type of reload be defined, that means roughly
1545 // "load without affecting history" ?
mjs2d326f52007-01-29 12:50:49 +00001546 if (shouldReloadToHandleUnreachableURL(newDocumentLoader)) {
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001547 // shouldReloadToHandleUnreachableURL returns true only when the original load type is back-forward.
commit-queue@webkit.org072ac242011-04-04 17:05:55 +00001548 // In this case we should save the document state now. Otherwise the state can be lost because load type is
1549 // changed and updateForBackForwardNavigation() will not be called when loading is committed.
akling@apple.com672cb852013-08-22 20:27:27 +00001550 history().saveDocumentAndScrollState();
commit-queue@webkit.org072ac242011-04-04 17:05:55 +00001551
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001552 ASSERT(type == FrameLoadType::Standard);
1553 type = FrameLoadType::Reload;
anderscade5715d2007-01-06 00:55:49 +00001554 }
1555
commit-queue@webkit.org372c2642020-04-03 16:53:48 +00001556 loadWithDocumentLoader(&newDocumentLoader, type, nullptr, AllowNavigationToInvalidURL::Yes);
anderscade5715d2007-01-06 00:55:49 +00001557}
1558
commit-queue@webkit.org372c2642020-04-03 16:53:48 +00001559void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, CompletionHandler<void()>&& completionHandler)
anderscade5715d2007-01-06 00:55:49 +00001560{
krollin@apple.combdeaed72020-01-08 01:31:20 +00001561 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadWithDocumentLoader: frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00001562
inferno@chromium.org6e8e3472010-10-26 13:29:04 +00001563 // Retain because dispatchBeforeLoadEvent may release the last reference to it.
akling@apple.comf8515982013-09-02 18:50:01 +00001564 Ref<Frame> protect(m_frame);
inferno@chromium.org6e8e3472010-10-26 13:29:04 +00001565
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001566 CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
1567
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001568 ASSERT(m_client->hasWebView());
anderscade5715d2007-01-06 00:55:49 +00001569
1570 // Unfortunately the view must be non-nil, this is ultimately due
1571 // to parser requiring a FrameView. We should fix this dependency.
1572
akling@apple.com7f50aae2013-08-22 16:01:31 +00001573 ASSERT(m_frame.view());
anderscade5715d2007-01-06 00:55:49 +00001574
dbates@webkit.org872db612017-03-20 23:07:50 +00001575 if (!isNavigationAllowed())
abarth@webkit.org89fa3502009-09-21 02:30:12 +00001576 return;
1577
akling@apple.com7f50aae2013-08-22 16:01:31 +00001578 if (m_frame.document())
1579 m_previousURL = m_frame.document()->url();
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00001580
cdumez@apple.comeb4832c2017-02-08 15:39:38 +00001581 const URL& newURL = loader->request().url();
1582
jiewen_tan@apple.com1306fce2018-10-24 18:49:03 +00001583 // Only the first iframe navigation or the first iframe navigation after about:blank should be reported.
1584 // https://www.w3.org/TR/resource-timing-2/#resources-included-in-the-performanceresourcetiming-interface
youenn@apple.com55cf9a22020-03-23 19:46:57 +00001585 if (m_shouldReportResourceTimingToParentFrame && !m_previousURL.isNull() && m_previousURL != aboutBlankURL())
jiewen_tan@apple.com1306fce2018-10-24 18:49:03 +00001586 m_shouldReportResourceTimingToParentFrame = false;
1587
cdumez@apple.com4c54fa72014-12-18 18:42:27 +00001588 // Log main frame navigation types.
akling@apple.come6549f42016-12-01 16:15:27 +00001589 if (m_frame.isMainFrame()) {
cdumez@apple.comc518f7e2018-04-03 18:01:41 +00001590 if (auto* page = m_frame.page()) {
krollin@apple.combdeaed72020-01-08 01:31:20 +00001591 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadWithDocumentLoader: main frame load started");
cdumez@apple.com563f1dc2017-04-29 03:55:35 +00001592 page->mainFrameLoadStarted(newURL, type);
cdumez@apple.comc518f7e2018-04-03 18:01:41 +00001593 page->performanceLogging().didReachPointOfInterest(PerformanceLogging::MainFrameLoadStarted);
1594 }
akling@apple.come6549f42016-12-01 16:15:27 +00001595 }
cdumez@apple.com4c54fa72014-12-18 18:42:27 +00001596
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001597 policyChecker().setLoadType(type);
rniwa@webkit.orgba12a012019-02-03 22:48:22 +00001598 RELEASE_ASSERT(!isBackForwardLoadType(type) || history().provisionalItem());
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00001599 bool isFormSubmission = formState;
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001600
yael.aharon@nokia.com79f69052010-12-30 19:31:00 +00001601 const String& httpMethod = loader->request().httpMethod();
anderscade5715d2007-01-06 00:55:49 +00001602
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001603 if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, policyChecker().loadType(), newURL)) {
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00001604 RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00001605 NavigationAction action { *m_frame.document(), loader->request(), InitiatedByMainFrame::Unknown, policyChecker().loadType(), isFormSubmission };
anderscade5715d2007-01-06 00:55:49 +00001606
cdumez@apple.com91e03bd2018-09-17 17:15:07 +00001607 oldDocumentLoader->setTriggeringAction(WTFMove(action));
andersca@apple.com97ab6d92013-10-21 22:55:14 +00001608 oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001609 policyChecker().stopCheck();
rniwa@webkit.orgba12a012019-02-03 22:48:22 +00001610 RELEASE_ASSERT(!isBackForwardLoadType(policyChecker().loadType()) || history().provisionalItem());
cdumez@apple.com2e665842019-02-01 22:52:58 +00001611 policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), ResourceResponse { } /* redirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, NavigationPolicyDecision navigationPolicyDecision) {
1612 continueFragmentScrollAfterNavigationPolicy(request, navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad);
cdumez@apple.com82211942018-04-17 18:13:49 +00001613 }, PolicyDecisionMode::Synchronous);
andersca@apple.com096333f2013-11-07 21:37:36 +00001614 return;
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00001615 }
andersca@apple.com096333f2013-11-07 21:37:36 +00001616
1617 if (Frame* parent = m_frame.tree().parent())
1618 loader->setOverrideEncoding(parent->loader().documentLoader()->overrideEncoding());
1619
1620 policyChecker().stopCheck();
1621 setPolicyDocumentLoader(loader);
1622 if (loader->triggeringAction().isEmpty())
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00001623 loader->setTriggeringAction({ *m_frame.document(), loader->request(), InitiatedByMainFrame::Unknown, policyChecker().loadType(), isFormSubmission });
andersca@apple.com096333f2013-11-07 21:37:36 +00001624
1625 if (Element* ownerElement = m_frame.ownerElement()) {
1626 // We skip dispatching the beforeload event if we've already
1627 // committed a real document load because the event would leak
1628 // subsequent activity by the frame which the parent frame isn't
1629 // supposed to learn. For example, if the child frame navigated to
1630 // a new URL, the parent frame shouldn't learn the URL.
1631 if (!m_stateMachine.committedFirstRealDocumentLoad()
1632 && !ownerElement->dispatchBeforeLoadEvent(loader->request().url().string())) {
cdumez@apple.com2e665842019-02-01 22:52:58 +00001633 continueLoadAfterNavigationPolicy(loader->request(), formState.get(), NavigationPolicyDecision::IgnoreLoad, allowNavigationToInvalidURL);
andersca@apple.com096333f2013-11-07 21:37:36 +00001634 return;
1635 }
1636 }
1637
achristensen@apple.com6fddc912018-10-18 21:16:52 +00001638 m_frame.navigationScheduler().cancel(NewLoadInProgress::Yes);
cdumez@apple.com22fa18d2018-02-28 23:58:22 +00001639
cdumez@apple.com3aedc032019-01-31 02:23:55 +00001640 if (shouldTreatCurrentLoadAsContinuingLoad()) {
cdumez@apple.com2e665842019-02-01 22:52:58 +00001641 continueLoadAfterNavigationPolicy(loader->request(), formState.get(), NavigationPolicyDecision::ContinueLoad, allowNavigationToInvalidURL);
beidson@apple.com1c9022b2018-03-21 00:05:58 +00001642 return;
1643 }
1644
rniwa@webkit.orgba12a012019-02-03 22:48:22 +00001645 RELEASE_ASSERT(!isBackForwardLoadType(policyChecker().loadType()) || history().provisionalItem());
cdumez@apple.com2e665842019-02-01 22:52:58 +00001646 policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), ResourceResponse { } /* redirectResponse */, loader, WTFMove(formState), [this, protectedFrame = makeRef(m_frame), allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, NavigationPolicyDecision navigationPolicyDecision) mutable {
1647 continueLoadAfterNavigationPolicy(request, formState.get(), navigationPolicyDecision, allowNavigationToInvalidURL);
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001648 completionHandler();
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001649 }, PolicyDecisionMode::Asynchronous);
anderscade5715d2007-01-06 00:55:49 +00001650}
1651
cdumez@apple.com2e68bb42018-03-19 22:30:57 +00001652void FrameLoader::clearProvisionalLoadForPolicyCheck()
1653{
cdumez@apple.com8ace63b2018-06-29 22:56:29 +00001654 if (!m_policyDocumentLoader || !m_provisionalDocumentLoader || m_inClearProvisionalLoadForPolicyCheck)
cdumez@apple.com2e68bb42018-03-19 22:30:57 +00001655 return;
1656
cdumez@apple.com8ace63b2018-06-29 22:56:29 +00001657 SetForScope<bool> change(m_inClearProvisionalLoadForPolicyCheck, true);
cdumez@apple.com2e68bb42018-03-19 22:30:57 +00001658 m_provisionalDocumentLoader->stopLoading();
krollin@apple.combdeaed72020-01-08 01:31:20 +00001659 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "clearProvisionalLoadForPolicyCheck: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
cdumez@apple.com2e68bb42018-03-19 22:30:57 +00001660 setProvisionalDocumentLoader(nullptr);
1661}
1662
aroben@apple.com92cfa902008-04-16 19:19:00 +00001663void FrameLoader::reportLocalLoadFailed(Frame* frame, const String& url)
kmccullo23d362f2007-04-06 01:05:58 +00001664{
1665 ASSERT(!url.isEmpty());
aroben@apple.com92cfa902008-04-16 19:19:00 +00001666 if (!frame)
1667 return;
1668
joepeck@webkit.org1f45df92014-02-06 23:45:53 +00001669 frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to load local resource: " + url);
kmccullo23d362f2007-04-06 01:05:58 +00001670}
1671
bfulgham@apple.comb4c70932016-01-06 22:07:51 +00001672void FrameLoader::reportBlockedPortFailed(Frame* frame, const String& url)
1673{
1674 ASSERT(!url.isEmpty());
1675 if (!frame)
1676 return;
1677
1678 frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to use restricted network port: " + url);
1679}
1680
dbates@webkit.org3c1f25a2018-02-07 18:56:02 +00001681void FrameLoader::reportAuthenticationChallengeBlocked(Frame* frame, const URL& url, const String& reason)
1682{
1683 if (!frame)
1684 return;
1685
1686 frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, makeString("Blocked ", url.stringCenterEllipsizedToLength(), " from asking for credentials because ", reason, '.'));
1687}
1688
anderscade5715d2007-01-06 00:55:49 +00001689const ResourceRequest& FrameLoader::initialRequest() const
1690{
andersca@apple.com48ffa332008-03-13 19:08:06 +00001691 return activeDocumentLoader()->originalRequest();
anderscade5715d2007-01-06 00:55:49 +00001692}
1693
drousso@apple.com21748ed2018-10-08 18:25:52 +00001694bool FrameLoader::willLoadMediaElementURL(URL& url, Node& initiatorNode)
weinig@apple.com68935252009-10-07 02:48:12 +00001695{
ap@apple.com1e8475922018-10-18 21:38:50 +00001696#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00001697 // MobileStore depends on the iOS 4.0 era client delegate method because webView:resource:willSendRequest:redirectResponse:fromDataSource
1698 // doesn't let them tell when a load request is coming from a media element. See <rdar://problem/8266916> for more details.
cdumez@apple.com0b0e88f2016-03-06 03:28:54 +00001699 if (IOSApplication::isMobileStore())
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001700 return m_client->shouldLoadMediaElementURL(url);
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00001701#endif
1702
weinig@apple.com68935252009-10-07 02:48:12 +00001703 ResourceRequest request(url);
drousso@apple.com21748ed2018-10-08 18:25:52 +00001704 request.setInspectorInitiatorNodeIdentifier(InspectorInstrumentation::identifierForNode(initiatorNode));
weinig@apple.com68935252009-10-07 02:48:12 +00001705
1706 unsigned long identifier;
1707 ResourceError error;
1708 requestFromDelegate(request, identifier, error);
antti@apple.com021dc012014-09-04 20:00:11 +00001709 notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, ResourceResponse(url, String(), -1, String()), 0, -1, -1, error);
weinig@apple.com68935252009-10-07 02:48:12 +00001710
1711 url = request.url();
1712
1713 return error.isNull();
1714}
1715
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001716bool FrameLoader::shouldReloadToHandleUnreachableURL(DocumentLoader& docLoader)
anderscade5715d2007-01-06 00:55:49 +00001717{
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001718 URL unreachableURL = docLoader.unreachableURL();
anderscade5715d2007-01-06 00:55:49 +00001719
1720 if (unreachableURL.isEmpty())
1721 return false;
1722
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001723 if (!isBackForwardLoadType(policyChecker().loadType()))
anderscade5715d2007-01-06 00:55:49 +00001724 return false;
1725
1726 // We only treat unreachableURLs specially during the delegate callbacks
1727 // for provisional load errors and navigation policy decisions. The former
1728 // case handles well-formed URLs that can't be loaded, and the latter
1729 // case handles malformed URLs and unknown schemes. Loading alternate content
1730 // at other times behaves like a standard load.
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001731 if (policyChecker().delegateIsDecidingNavigationPolicy() || policyChecker().delegateIsHandlingUnimplementablePolicy())
mitz@apple.com6699e272015-05-01 23:47:03 +00001732 return m_policyDocumentLoader && unreachableURL == m_policyDocumentLoader->request().url();
anderscade5715d2007-01-06 00:55:49 +00001733
mitz@apple.com6699e272015-05-01 23:47:03 +00001734 return unreachableURL == m_provisionalLoadErrorBeingHandledURL;
anderscade5715d2007-01-06 00:55:49 +00001735}
1736
ggaren@apple.com3eaa7c02009-01-29 07:38:54 +00001737void FrameLoader::reloadWithOverrideEncoding(const String& encoding)
anderscade5715d2007-01-06 00:55:49 +00001738{
1739 if (!m_documentLoader)
1740 return;
1741
krollin@apple.combdeaed72020-01-08 01:31:20 +00001742 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "reloadWithOverrideEncoding: frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00001743
anderscade5715d2007-01-06 00:55:49 +00001744 ResourceRequest request = m_documentLoader->request();
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001745 URL unreachableURL = m_documentLoader->unreachableURL();
anderscade5715d2007-01-06 00:55:49 +00001746 if (!unreachableURL.isEmpty())
1747 request.setURL(unreachableURL);
1748
ap@apple.com8d5f01b2013-01-07 18:40:55 +00001749 // FIXME: If the resource is a result of form submission and is not cached, the form will be silently resubmitted.
1750 // We should ask the user for confirmation in this case.
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00001751 request.setCachePolicy(ResourceRequestCachePolicy::ReturnCacheDataElseLoad);
anderscade5715d2007-01-06 00:55:49 +00001752
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001753 Ref<DocumentLoader> loader = m_client->createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001754 applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, InitiatedByMainFrame::Unknown, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
beidson@apple.com87dc6312015-06-02 18:43:13 +00001755
gyuyoung.kim@webkit.orgc39073e2015-07-19 00:16:50 +00001756 setPolicyDocumentLoader(loader.ptr());
anderscade5715d2007-01-06 00:55:49 +00001757
1758 loader->setOverrideEncoding(encoding);
1759
commit-queue@webkit.org372c2642020-04-03 16:53:48 +00001760 loadWithDocumentLoader(loader.ptr(), FrameLoadType::Reload, { }, AllowNavigationToInvalidURL::Yes);
anderscade5715d2007-01-06 00:55:49 +00001761}
1762
antti@apple.com5d0c5402017-03-17 19:52:49 +00001763void FrameLoader::reload(OptionSet<ReloadOption> options)
anderscade5715d2007-01-06 00:55:49 +00001764{
1765 if (!m_documentLoader)
1766 return;
1767
anderscade5715d2007-01-06 00:55:49 +00001768 // If a window is created by javascript, its main frame can have an empty but non-nil URL.
1769 // Reloading in this case will lose the current contents (see 4151001).
darin@chromium.org48246852008-11-04 19:40:56 +00001770 if (m_documentLoader->request().url().isEmpty())
anderscade5715d2007-01-06 00:55:49 +00001771 return;
1772
krollin@apple.combdeaed72020-01-08 01:31:20 +00001773 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "reload: frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00001774
anderscade5715d2007-01-06 00:55:49 +00001775 // Replace error-page URL with the URL we were trying to reach.
commit-queue@webkit.org2090e272012-06-28 16:05:43 +00001776 ResourceRequest initialRequest = m_documentLoader->request();
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001777 URL unreachableURL = m_documentLoader->unreachableURL();
anderscade5715d2007-01-06 00:55:49 +00001778 if (!unreachableURL.isEmpty())
darin@chromium.org48246852008-11-04 19:40:56 +00001779 initialRequest.setURL(unreachableURL);
commit-queue@webkit.org2090e272012-06-28 16:05:43 +00001780
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001781 // Create a new document loader for the reload, this will become m_documentLoader eventually,
1782 // but first it has to be the "policy" document loader, and then the "provisional" document loader.
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001783 Ref<DocumentLoader> loader = m_client->createDocumentLoader(initialRequest, defaultSubstituteDataForURL(initialRequest.url()));
jiewen_tan@apple.com32abaa62019-02-13 23:07:13 +00001784 loader->setAllowsWebArchiveForMainFrame(m_documentLoader->allowsWebArchiveForMainFrame());
bfulgham@apple.com2eaf0ac2020-02-06 17:32:18 +00001785 loader->setAllowsDataURLsForMainFrame(m_documentLoader->allowsDataURLsForMainFrame());
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001786 applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, InitiatedByMainFrame::Unknown, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
anderscade5715d2007-01-06 00:55:49 +00001787
antti@apple.com5d0c5402017-03-17 19:52:49 +00001788 loader->setUserContentExtensionsEnabled(!options.contains(ReloadOption::DisableContentBlockers));
achristensen@apple.comd40e0ba2015-10-14 20:03:14 +00001789
anderscade5715d2007-01-06 00:55:49 +00001790 ResourceRequest& request = loader->request();
1791
commit-queue@webkit.org4833ac52018-02-26 17:38:14 +00001792 // FIXME: We don't have a mechanism to revalidate the main resource without reloading at the moment.
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00001793 request.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
anderscade5715d2007-01-06 00:55:49 +00001794
dbates@webkit.org8c917f22018-04-24 07:36:59 +00001795 addSameSiteInfoToRequestIfNeeded(request);
1796
anderscade5715d2007-01-06 00:55:49 +00001797 // If we're about to re-post, set up action so the application can warn the user.
1798 if (request.httpMethod() == "POST")
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00001799 loader->setTriggeringAction({ *m_frame.document(), request, InitiatedByMainFrame::Unknown, NavigationType::FormResubmitted });
anderscade5715d2007-01-06 00:55:49 +00001800
1801 loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
antti@apple.com5d0c5402017-03-17 19:52:49 +00001802
1803 auto frameLoadTypeForReloadOptions = [] (auto options) {
antti@apple.comeb7081d2018-05-09 07:05:46 +00001804 if (options & ReloadOption::FromOrigin)
antti@apple.com5d0c5402017-03-17 19:52:49 +00001805 return FrameLoadType::ReloadFromOrigin;
antti@apple.comeb7081d2018-05-09 07:05:46 +00001806 if (options & ReloadOption::ExpiredOnly)
antti@apple.com5d0c5402017-03-17 19:52:49 +00001807 return FrameLoadType::ReloadExpiredOnly;
1808 return FrameLoadType::Reload;
1809 };
anderscade5715d2007-01-06 00:55:49 +00001810
commit-queue@webkit.org372c2642020-04-03 16:53:48 +00001811 loadWithDocumentLoader(loader.ptr(), frameLoadTypeForReloadOptions(options), { }, AllowNavigationToInvalidURL::Yes);
anderscade5715d2007-01-06 00:55:49 +00001812}
1813
ajuma@chromium.orgedd75742019-09-11 14:52:18 +00001814void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItemPolicy, StopLoadingPolicy stopLoadingPolicy)
darinc370e7e2006-11-08 05:52:27 +00001815{
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00001816 if (m_frame.document() && m_frame.document()->backForwardCacheState() == Document::InBackForwardCache)
cdumez@apple.coma0010ff2018-12-13 23:17:44 +00001817 return;
1818
ajuma@chromium.orgedd75742019-09-11 14:52:18 +00001819 if (stopLoadingPolicy == StopLoadingPolicy::PreventDuringUnloadEvents && !isStopLoadingAllowed())
weinig@apple.comf239bbf2009-04-09 18:30:32 +00001820 return;
1821
darinc370e7e2006-11-08 05:52:27 +00001822 // If this method is called from within this method, infinite recursion can occur (3442218). Avoid this.
1823 if (m_inStopAllLoaders)
1824 return;
pvollan@apple.com8f4bcd952018-02-01 04:18:38 +00001825
1826 // This method might dispatch events.
1827 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isScriptAllowed());
1828
inferno@chromium.orgbc05aa52012-08-06 16:30:40 +00001829 // Calling stopLoading() on the provisional document loader can blow away
1830 // the frame from underneath.
akling@apple.comf8515982013-09-02 18:50:01 +00001831 Ref<Frame> protect(m_frame);
darinc370e7e2006-11-08 05:52:27 +00001832
1833 m_inStopAllLoaders = true;
1834
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001835 policyChecker().stopCheck();
darinc370e7e2006-11-08 05:52:27 +00001836
commit-queue@webkit.org987fd772011-01-21 18:26:42 +00001837 // If no new load is in progress, we should clear the provisional item from history
1838 // before we call stopLoading.
1839 if (clearProvisionalItemPolicy == ShouldClearProvisionalItem)
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00001840 history().setProvisionalItem(nullptr);
commit-queue@webkit.org987fd772011-01-21 18:26:42 +00001841
darin@apple.comfed4d162013-08-25 02:28:06 +00001842 for (RefPtr<Frame> child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
andersca@apple.comdf550b92013-08-15 22:17:17 +00001843 child->loader().stopAllLoaders(clearProvisionalItemPolicy);
darin7208e932007-02-13 17:52:53 +00001844 if (m_provisionalDocumentLoader)
commit-queue@webkit.orgfc5833b2011-02-23 06:58:46 +00001845 m_provisionalDocumentLoader->stopLoading();
beidson@apple.com46421212008-08-25 21:48:56 +00001846 if (m_documentLoader)
commit-queue@webkit.orgfc5833b2011-02-23 06:58:46 +00001847 m_documentLoader->stopLoading();
commit-queue@webkit.org424bc412020-02-24 15:50:39 +00001848 if (m_frame.page() && !m_frame.page()->chrome().client().isSVGImageChromeClient())
1849 platformStrategies()->loaderStrategy()->browsingContextRemoved(frame());
beidson@apple.com46421212008-08-25 21:48:56 +00001850
krollin@apple.combdeaed72020-01-08 01:31:20 +00001851 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "stopAllLoaders: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00001852 setProvisionalDocumentLoader(nullptr);
darin7208e932007-02-13 17:52:53 +00001853
darinc370e7e2006-11-08 05:52:27 +00001854 m_inStopAllLoaders = false;
1855}
1856
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00001857void FrameLoader::stopForBackForwardCache()
cdumez@apple.come16aaf02019-10-03 22:16:46 +00001858{
cdumez@apple.come16aaf02019-10-03 22:16:46 +00001859 // Stop provisional loads in subframes (The one in the main frame is about to be committed).
1860 if (!m_frame.isMainFrame()) {
1861 if (m_provisionalDocumentLoader)
1862 m_provisionalDocumentLoader->stopLoading();
krollin@apple.combdeaed72020-01-08 01:31:20 +00001863 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "stopForBackForwardCache: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
cdumez@apple.come16aaf02019-10-03 22:16:46 +00001864 setProvisionalDocumentLoader(nullptr);
1865 }
1866
1867 // Stop current loads.
1868 if (m_documentLoader)
1869 m_documentLoader->stopLoading();
1870
1871 for (RefPtr<Frame> child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00001872 child->loader().stopForBackForwardCache();
cdumez@apple.com6cbf70a2019-10-11 20:26:15 +00001873
cdumez@apple.com7e7b8792019-10-11 23:29:02 +00001874 // We cancel pending navigations & policy checks *after* cancelling loads because cancelling loads might end up
1875 // running script, which could schedule new navigations.
cdumez@apple.com6cbf70a2019-10-11 20:26:15 +00001876 policyChecker().stopCheck();
1877 m_frame.navigationScheduler().cancel();
cdumez@apple.come16aaf02019-10-03 22:16:46 +00001878}
1879
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00001880void FrameLoader::stopAllLoadersAndCheckCompleteness()
1881{
1882 stopAllLoaders();
1883
1884 if (!m_checkTimer.isActive())
1885 return;
1886
1887 m_checkTimer.stop();
1888 m_checkingLoadCompleteForDetachment = true;
1889 checkCompletenessNow();
1890 m_checkingLoadCompleteForDetachment = false;
1891}
1892
beidson398923b2007-07-31 20:29:02 +00001893void FrameLoader::stopForUserCancel(bool deferCheckLoadComplete)
mjs8d620d52007-05-10 12:31:42 +00001894{
bfulgham@apple.com98845d92016-05-17 01:09:27 +00001895 // Calling stopAllLoaders can cause the frame to be deallocated, including the frame loader.
1896 Ref<Frame> protectedFrame(m_frame);
1897
mjs8d620d52007-05-10 12:31:42 +00001898 stopAllLoaders();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00001899
ap@apple.com1e8475922018-10-18 21:38:50 +00001900#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00001901 // Lay out immediately when stopping to immediately clear the old page if we just committed this one
1902 // but haven't laid out/painted yet.
1903 // FIXME: Is this behavior specific to iOS? Or should we expose a setting to toggle this behavior?
1904 if (m_frame.view() && !m_frame.view()->didFirstLayout())
zalan@apple.com6116e6d2017-10-28 15:24:58 +00001905 m_frame.view()->layoutContext().layout();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00001906#endif
1907
beidson398923b2007-07-31 20:29:02 +00001908 if (deferCheckLoadComplete)
1909 scheduleCheckLoadComplete();
akling@apple.com7f50aae2013-08-22 16:01:31 +00001910 else if (m_frame.page())
mjs8d620d52007-05-10 12:31:42 +00001911 checkLoadComplete();
1912}
1913
darinc370e7e2006-11-08 05:52:27 +00001914DocumentLoader* FrameLoader::activeDocumentLoader() const
1915{
1916 if (m_state == FrameStateProvisional)
1917 return m_provisionalDocumentLoader.get();
1918 return m_documentLoader.get();
1919}
1920
darinc370e7e2006-11-08 05:52:27 +00001921bool FrameLoader::isLoading() const
1922{
darin8207db42007-02-20 18:18:39 +00001923 DocumentLoader* docLoader = activeDocumentLoader();
1924 if (!docLoader)
1925 return false;
japhet@chromium.org4bcb80b2012-03-26 20:34:00 +00001926 return docLoader->isLoading();
darinc370e7e2006-11-08 05:52:27 +00001927}
1928
mjs7545bb52007-05-15 08:24:53 +00001929bool FrameLoader::frameHasLoaded() const
1930{
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00001931 return m_stateMachine.committedFirstRealDocumentLoad() || (m_provisionalDocumentLoader && !m_stateMachine.creatingInitialEmptyDocument());
mjs7545bb52007-05-15 08:24:53 +00001932}
1933
darinc370e7e2006-11-08 05:52:27 +00001934void FrameLoader::setDocumentLoader(DocumentLoader* loader)
1935{
1936 if (!loader && !m_documentLoader)
1937 return;
cdumez@apple.coma0010ff2018-12-13 23:17:44 +00001938
1939 if (loader == m_documentLoader)
1940 return;
darinc370e7e2006-11-08 05:52:27 +00001941
1942 ASSERT(loader != m_documentLoader);
1943 ASSERT(!loader || loader->frameLoader() == this);
1944
youenn@apple.comee96d0f2020-03-18 13:59:23 +00001945 m_client->prepareForDataSourceReplacement();
darinc3d26052007-03-22 18:17:12 +00001946 detachChildren();
japhet@chromium.orga9a58bb2012-09-01 01:09:02 +00001947
1948 // detachChildren() can trigger this frame's unload event, and therefore
1949 // script can run and do just about anything. For example, an unload event that calls
1950 // document.write("") on its parent frame can lead to a recursive detachChildren()
1951 // invocation for this frame. In that case, we can end up at this point with a
1952 // loader that hasn't been deleted but has been detached from its frame. Such a
1953 // DocumentLoader has been sufficiently detached that we'll end up in an inconsistent
1954 // state if we try to use it.
1955 if (loader && !loader->frame())
1956 return;
1957
darinc370e7e2006-11-08 05:52:27 +00001958 if (m_documentLoader)
1959 m_documentLoader->detachFromFrame();
1960
1961 m_documentLoader = loader;
1962}
1963
darinc370e7e2006-11-08 05:52:27 +00001964void FrameLoader::setPolicyDocumentLoader(DocumentLoader* loader)
1965{
1966 if (m_policyDocumentLoader == loader)
1967 return;
1968
darinc370e7e2006-11-08 05:52:27 +00001969 if (loader)
beidson@apple.com10a537f2015-07-09 22:30:42 +00001970 loader->attachToFrame(m_frame);
darinc370e7e2006-11-08 05:52:27 +00001971 if (m_policyDocumentLoader
1972 && m_policyDocumentLoader != m_provisionalDocumentLoader
1973 && m_policyDocumentLoader != m_documentLoader)
1974 m_policyDocumentLoader->detachFromFrame();
1975
1976 m_policyDocumentLoader = loader;
1977}
eric@webkit.org14774f42008-04-21 17:50:37 +00001978
darinc370e7e2006-11-08 05:52:27 +00001979void FrameLoader::setProvisionalDocumentLoader(DocumentLoader* loader)
1980{
krollin@apple.combdeaed72020-01-08 01:31:20 +00001981 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "setProvisionalDocumentLoader: Setting provisional document loader (m_provisionalDocumentLoader=%p)", loader);
1982
darinc370e7e2006-11-08 05:52:27 +00001983 ASSERT(!loader || !m_provisionalDocumentLoader);
1984 ASSERT(!loader || loader->frameLoader() == this);
1985
1986 if (m_provisionalDocumentLoader && m_provisionalDocumentLoader != m_documentLoader)
1987 m_provisionalDocumentLoader->detachFromFrame();
1988
1989 m_provisionalDocumentLoader = loader;
1990}
1991
darinc370e7e2006-11-08 05:52:27 +00001992void FrameLoader::setState(FrameState newState)
akling@apple.come6549f42016-12-01 16:15:27 +00001993{
1994 FrameState oldState = m_state;
darinc370e7e2006-11-08 05:52:27 +00001995 m_state = newState;
1996
1997 if (newState == FrameStateProvisional)
1998 provisionalLoadStarted();
1999 else if (newState == FrameStateComplete) {
2000 frameLoadCompleted();
darinc370e7e2006-11-08 05:52:27 +00002001 if (m_documentLoader)
2002 m_documentLoader->stopRecordingResponses();
krollin@apple.come1810b62018-12-20 19:23:20 +00002003 if (m_frame.isMainFrame() && oldState != newState) {
krollin@apple.combdeaed72020-01-08 01:31:20 +00002004 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "setState: main frame load completed");
cdumez@apple.comc518f7e2018-04-03 18:01:41 +00002005 m_frame.page()->performanceLogging().didReachPointOfInterest(PerformanceLogging::MainFrameLoadCompleted);
krollin@apple.come1810b62018-12-20 19:23:20 +00002006 }
darinc370e7e2006-11-08 05:52:27 +00002007 }
2008}
2009
2010void FrameLoader::clearProvisionalLoad()
2011{
krollin@apple.combdeaed72020-01-08 01:31:20 +00002012 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "clearProvisionalLoad: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00002013 setProvisionalDocumentLoader(nullptr);
japhet@chromium.org7879dd72012-08-30 02:58:37 +00002014 m_progressTracker->progressCompleted();
darinc370e7e2006-11-08 05:52:27 +00002015 setState(FrameStateComplete);
2016}
2017
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00002018void FrameLoader::commitProvisionalLoad()
beidson50c3bd82007-01-03 03:11:18 +00002019{
beidson50c3bd82007-01-03 03:11:18 +00002020 RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
akling@apple.comf8515982013-09-02 18:50:01 +00002021 Ref<Frame> protect(m_frame);
beidson@apple.com3a5e3b92009-01-27 08:05:59 +00002022
andersca@apple.come776c2f2014-01-18 01:47:19 +00002023 std::unique_ptr<CachedPage> cachedPage;
cdumez@apple.com67e10f72015-01-29 18:38:51 +00002024 if (m_loadingFromCachedPage && history().provisionalItem())
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002025 cachedPage = BackForwardCache::singleton().take(*history().provisionalItem(), m_frame.page());
akling@apple.com9663f4b2013-09-05 21:25:32 +00002026
cdumez@apple.com524b8aa2019-10-15 05:28:55 +00002027 LOG(BackForwardCache, "WebCoreLoading %s: About to commit provisional load from previous URL '%s' to new URL '%s' with cached page %p", m_frame.tree().uniqueName().string().utf8().data(),
akling@apple.com7f50aae2013-08-22 16:01:31 +00002028 m_frame.document() ? m_frame.document()->url().stringCenterEllipsizedToLength().utf8().data() : "",
beidson@apple.com69caeee2018-04-20 04:55:32 +00002029 pdl ? pdl->url().stringCenterEllipsizedToLength().utf8().data() : "<no provisional DocumentLoader>", cachedPage.get());
beidson@apple.com3a5e3b92009-01-27 08:05:59 +00002030
ap@apple.come042b632013-05-17 20:04:43 +00002031 willTransitionToCommitted();
2032
cdumez@apple.coma0010ff2018-12-13 23:17:44 +00002033 if (!m_frame.tree().parent() && history().currentItem() && history().currentItem() != history().provisionalItem()) {
akling@apple.comaf7f33b2016-02-06 17:00:30 +00002034 // Check to see if we need to cache the page we are navigating away from into the back/forward cache.
2035 // We are doing this here because we know for sure that a new page is about to be loaded.
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002036 BackForwardCache::singleton().addIfCacheable(*history().currentItem(), m_frame.page());
cdumez@apple.com8420ada2016-06-21 17:05:48 +00002037
carlosgc@webkit.org32a60dd2016-11-10 14:24:26 +00002038 WebCore::jettisonExpensiveObjectsOnTopLevelNavigation();
akling@apple.comaf7f33b2016-02-06 17:00:30 +00002039 }
2040
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002041 if (m_loadType != FrameLoadType::Replace)
beidson50c3bd82007-01-03 03:11:18 +00002042 closeOldDataSources();
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00002043
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00002044 if (!cachedPage && !m_stateMachine.creatingInitialEmptyDocument())
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002045 m_client->makeRepresentation(pdl.get());
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00002046
akling@apple.com9663f4b2013-09-05 21:25:32 +00002047 transitionToCommitted(cachedPage.get());
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00002048
abarth@webkit.orgf12783f2012-10-03 19:34:30 +00002049 if (pdl && m_documentLoader) {
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00002050 // Check if the destination page is allowed to access the previous page's timing information.
akling@apple.com6eea45d2014-12-17 01:48:38 +00002051 Ref<SecurityOrigin> securityOrigin(SecurityOrigin::create(pdl->request().url()));
akling@apple.com5a7607f2015-01-21 22:33:49 +00002052 m_documentLoader->timing().setHasSameOriginAsPreviousDocument(securityOrigin.get().canRequest(m_previousURL));
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00002053 }
2054
beidsonb72fe2e2007-05-03 21:35:24 +00002055 // Call clientRedirectCancelledOrFinished() here so that the frame load delegate is notified that the redirect's
beidson50c3bd82007-01-03 03:11:18 +00002056 // status has changed, if there was a redirect. The frame load delegate may have saved some state about
2057 // the redirect in its -webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:. Since we are
2058 // just about to commit a new page, there cannot possibly be a pending redirect at this point.
2059 if (m_sentRedirectNotification)
achristensen@apple.com6fddc912018-10-18 21:16:52 +00002060 clientRedirectCancelledOrFinished(NewLoadInProgress::No);
beidson50c3bd82007-01-03 03:11:18 +00002061
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00002062 if (cachedPage && cachedPage->document()) {
ap@apple.com1e8475922018-10-18 21:38:50 +00002063#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002064 // FIXME: CachedPage::restore() would dispatch viewport change notification. However UIKit expects load
2065 // commit to happen before any changes to viewport arguments and dealing with this there is difficult.
2066 m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(true);
2067#endif
dbates@webkit.orgcd75cb62017-03-15 22:44:59 +00002068 willRestoreFromCachedPage();
commit-queue@webkit.orgcbb6a492010-09-20 20:20:25 +00002069
carlosgc@webkit.org72eb7962016-01-12 08:23:36 +00002070 // Start request for the main resource and dispatch didReceiveResponse before the load is committed for
2071 // consistency with all other loads. See https://bugs.webkit.org/show_bug.cgi?id=150927.
2072 ResourceError mainResouceError;
2073 unsigned long mainResourceIdentifier;
2074 ResourceRequest mainResourceRequest(cachedPage->documentLoader()->request());
2075 requestFromDelegate(mainResourceRequest, mainResourceIdentifier, mainResouceError);
2076 notifier().dispatchDidReceiveResponse(cachedPage->documentLoader(), mainResourceIdentifier, cachedPage->documentLoader()->response());
2077
commit-queue@webkit.org511a9492020-03-12 18:28:40 +00002078 auto hasInsecureContent = cachedPage->cachedMainFrame()->hasInsecureContent();
commit-queue@webkit.orgfbfef682020-03-14 02:10:54 +00002079 auto usedLegacyTLS = cachedPage->cachedMainFrame()->usedLegacyTLS();
beidson@apple.com4322db02016-09-16 00:27:11 +00002080
achristensen@apple.come0301a32020-02-07 23:30:29 +00002081 dispatchDidCommitLoad(hasInsecureContent, usedLegacyTLS);
cdumez@apple.com5c7c1f32019-01-16 20:40:02 +00002082
dbates@webkit.org1fecb922017-03-25 01:13:23 +00002083 // FIXME: This API should be turned around so that we ground CachedPage into the Page.
2084 cachedPage->restore(*m_frame.page());
commit-queue@webkit.org1686e5d2012-10-19 23:13:08 +00002085
ap@apple.com1e8475922018-10-18 21:38:50 +00002086#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002087 m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(false);
2088 m_frame.page()->chrome().dispatchViewportPropertiesDidChange(m_frame.page()->viewportArguments());
2089#endif
wenson_hsieh@apple.com0c724172018-05-15 01:07:36 +00002090 m_frame.page()->chrome().dispatchDisabledAdaptationsDidChange(m_frame.page()->disabledAdaptations());
darin@apple.com961f2a52016-12-31 09:51:29 +00002091
2092 auto& title = m_documentLoader->title();
2093 if (!title.string.isNull())
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002094 m_client->dispatchDidReceiveTitle(title);
commit-queue@webkit.orgcbb6a492010-09-20 20:20:25 +00002095
carlosgc@webkit.org72eb7962016-01-12 08:23:36 +00002096 // Send remaining notifications for the main resource.
2097 notifier().sendRemainingDelegateMessages(m_documentLoader.get(), mainResourceIdentifier, mainResourceRequest, ResourceResponse(),
2098 nullptr, static_cast<int>(m_documentLoader->response().expectedContentLength()), 0, mainResouceError);
2099
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00002100 checkCompleted();
akling@apple.com9663f4b2013-09-05 21:25:32 +00002101 } else
abarth@webkit.org55d49da2011-06-20 23:32:54 +00002102 didOpenURL();
beidson@apple.com3a5e3b92009-01-27 08:05:59 +00002103
darin@apple.comfed4d162013-08-25 02:28:06 +00002104 LOG(Loading, "WebCoreLoading %s: Finished committing provisional load to URL %s", m_frame.tree().uniqueName().string().utf8().data(),
akling@apple.com7f50aae2013-08-22 16:01:31 +00002105 m_frame.document() ? m_frame.document()->url().stringCenterEllipsizedToLength().utf8().data() : "");
beidson@apple.com3a5e3b92009-01-27 08:05:59 +00002106
Hironori.Fujii@sony.com2253a9d2018-07-02 01:52:14 +00002107 if (m_loadType == FrameLoadType::Standard && m_documentLoader && m_documentLoader->isClientRedirect())
akling@apple.com672cb852013-08-22 20:27:27 +00002108 history().updateForClientRedirect();
beidson@apple.com028c7a72009-02-11 22:01:22 +00002109
beidson@apple.comac095c02009-08-18 01:37:56 +00002110 if (m_loadingFromCachedPage) {
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002111 // Note, didReceiveDocType is expected to be called for cached pages. See <rdar://problem/5906758> for more details.
darin@apple.com9ace8012017-01-23 06:24:18 +00002112 if (auto* page = m_frame.page())
2113 page->chrome().didReceiveDocType(m_frame);
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002114 m_frame.document()->resume(ReasonForSuspension::BackForwardCache);
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002115
beidson@apple.com028c7a72009-02-11 22:01:22 +00002116 // Force a layout to update view size and thereby update scrollbars.
ap@apple.com1e8475922018-10-18 21:38:50 +00002117#if PLATFORM(IOS_FAMILY)
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002118 if (!m_client->forceLayoutOnRestoreFromBackForwardCache())
simon.fraser@apple.com72978b32014-03-09 18:14:07 +00002119 m_frame.view()->forceLayout();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002120#else
akling@apple.com7f50aae2013-08-22 16:01:31 +00002121 m_frame.view()->forceLayout();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002122#endif
beidson@apple.com028c7a72009-02-11 22:01:22 +00002123
carlosgc@webkit.org72eb7962016-01-12 08:23:36 +00002124 // Main resource delegates were already sent, so we skip the first response here.
2125 for (unsigned i = 1; i < m_documentLoader->responses().size(); ++i) {
2126 const auto& response = m_documentLoader->responses()[i];
beidson@apple.com028c7a72009-02-11 22:01:22 +00002127 // FIXME: If the WebKit client changes or cancels the request, this is not respected.
2128 ResourceError error;
2129 unsigned long identifier;
2130 ResourceRequest request(response.url());
2131 requestFromDelegate(request, identifier, error);
2132 // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
2133 // However, with today's computers and networking speeds, this won't happen in practice.
2134 // Could be an issue with a giant local file.
akling@apple.com654fd9a2013-10-06 21:07:29 +00002135 notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, response, 0, static_cast<int>(response.expectedContentLength()), 0, error);
beidson@apple.com028c7a72009-02-11 22:01:22 +00002136 }
beidson@apple.com028c7a72009-02-11 22:01:22 +00002137
beidson@apple.com028c7a72009-02-11 22:01:22 +00002138 // FIXME: Why only this frame and not parent frames?
2139 checkLoadCompleteForThisFrame();
2140 }
beidson50c3bd82007-01-03 03:11:18 +00002141}
2142
akling@apple.com9663f4b2013-09-05 21:25:32 +00002143void FrameLoader::transitionToCommitted(CachedPage* cachedPage)
beidson50c3bd82007-01-03 03:11:18 +00002144{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002145 ASSERT(m_client->hasWebView());
beidson50c3bd82007-01-03 03:11:18 +00002146 ASSERT(m_state == FrameStateProvisional);
2147
2148 if (m_state != FrameStateProvisional)
2149 return;
2150
akling@apple.com7f50aae2013-08-22 16:01:31 +00002151 if (FrameView* view = m_frame.view()) {
bdakin@apple.com3fec69c2012-03-23 21:02:51 +00002152 if (ScrollAnimator* scrollAnimator = view->existingScrollAnimator())
bdakin@apple.com87235fc2012-03-23 20:36:31 +00002153 scrollAnimator->cancelAnimations();
2154 }
bdakin@apple.come0a38ad2011-03-15 18:30:41 +00002155
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002156 m_client->setCopiesOnScroll();
akling@apple.com672cb852013-08-22 20:27:27 +00002157 history().updateForCommit();
beidson50c3bd82007-01-03 03:11:18 +00002158
2159 // The call to closeURL() invokes the unload event handler, which can execute arbitrary
2160 // JavaScript. If the script initiates a new load, we need to abandon the current load,
2161 // or the two will stomp each other.
2162 DocumentLoader* pdl = m_provisionalDocumentLoader.get();
mjs8d620d52007-05-10 12:31:42 +00002163 if (m_documentLoader)
2164 closeURL();
beidson50c3bd82007-01-03 03:11:18 +00002165 if (pdl != m_provisionalDocumentLoader)
2166 return;
2167
beidson4a289132007-05-03 18:50:41 +00002168 if (m_documentLoader)
2169 m_documentLoader->stopLoadingSubresources();
2170 if (m_documentLoader)
2171 m_documentLoader->stopLoadingPlugIns();
2172
dbates@webkit.orgd77aa3f2017-05-03 16:58:04 +00002173 // Setting our document loader invokes the unload event handler of our child frames.
2174 // Script can do anything. If the script initiates a new load, we need to abandon the
2175 // current load or the two will stomp each other.
beidson4a289132007-05-03 18:50:41 +00002176 setDocumentLoader(m_provisionalDocumentLoader.get());
dbates@webkit.orgd77aa3f2017-05-03 16:58:04 +00002177 if (pdl != m_provisionalDocumentLoader)
2178 return;
krollin@apple.combdeaed72020-01-08 01:31:20 +00002179 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "transitionToCommitted: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00002180 setProvisionalDocumentLoader(nullptr);
japhet@chromium.orga9a58bb2012-09-01 01:09:02 +00002181
dbates@webkit.orgec907882017-05-05 04:04:35 +00002182 // Nothing else can interrupt this commit - set the Provisional->Committed transition in stone
commit-queue@webkit.org1af3b432011-08-05 07:00:47 +00002183 setState(FrameStateCommittedPage);
beidson50c3bd82007-01-03 03:11:18 +00002184
2185 // Handle adding the URL to the back/forward list.
2186 DocumentLoader* dl = m_documentLoader.get();
beidson50c3bd82007-01-03 03:11:18 +00002187
2188 switch (m_loadType) {
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002189 case FrameLoadType::Forward:
2190 case FrameLoadType::Back:
2191 case FrameLoadType::IndexedBackForward:
2192 if (m_frame.page()) {
2193 // If the first load within a frame is a navigation within a back/forward list that was attached
2194 // without any of the items being loaded then we need to update the history in a similar manner as
2195 // for a standard load with the exception of updating the back/forward list (<rdar://problem/8091103>).
2196 if (!m_stateMachine.committedFirstRealDocumentLoad() && m_frame.isMainFrame())
2197 history().updateForStandardLoad(HistoryController::UpdateAllExceptBackForwardList);
mrowe@apple.com04fa4872010-06-16 02:23:45 +00002198
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002199 history().updateForBackForwardNavigation();
beidson50c3bd82007-01-03 03:11:18 +00002200
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002201 // For cached pages, CachedFrame::restore will take care of firing the popstate event with the history item's state object
2202 if (history().currentItem() && !cachedPage)
2203 m_pendingStateObject = history().currentItem()->stateObject();
mrowe@apple.com04fa4872010-06-16 02:23:45 +00002204
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002205 // Create a document view for this document, or used the cached view.
2206 if (cachedPage) {
2207 DocumentLoader* cachedDocumentLoader = cachedPage->documentLoader();
2208 ASSERT(cachedDocumentLoader);
beidson@apple.com10a537f2015-07-09 22:30:42 +00002209 cachedDocumentLoader->attachToFrame(m_frame);
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002210 m_client->transitionToCommittedFromCachedFrame(cachedPage->cachedMainFrame());
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002211 } else
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002212 m_client->transitionToCommittedForNewPage();
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002213 }
2214 break;
beidson50c3bd82007-01-03 03:11:18 +00002215
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002216 case FrameLoadType::Reload:
2217 case FrameLoadType::ReloadFromOrigin:
antti@apple.com5d0c5402017-03-17 19:52:49 +00002218 case FrameLoadType::ReloadExpiredOnly:
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002219 case FrameLoadType::Same:
2220 case FrameLoadType::Replace:
2221 history().updateForReload();
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002222 m_client->transitionToCommittedForNewPage();
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002223 break;
beidson50c3bd82007-01-03 03:11:18 +00002224
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002225 case FrameLoadType::Standard:
2226 history().updateForStandardLoad();
2227 if (m_frame.view())
2228 m_frame.view()->setScrollbarsSuppressed(true);
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002229 m_client->transitionToCommittedForNewPage();
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002230 break;
beidson50c3bd82007-01-03 03:11:18 +00002231
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002232 case FrameLoadType::RedirectWithLockedBackForwardList:
2233 history().updateForRedirectWithLockedBackForwardList();
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002234 m_client->transitionToCommittedForNewPage();
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002235 break;
beidson50c3bd82007-01-03 03:11:18 +00002236 }
2237
weinig@apple.comee87b2f2013-10-05 23:59:58 +00002238 m_documentLoader->writer().setMIMEType(dl->responseMIMEType());
weinig92883332007-02-20 01:05:27 +00002239
beidson50c3bd82007-01-03 03:11:18 +00002240 // Tell the client we've committed this URL.
akling@apple.com7f50aae2013-08-22 16:01:31 +00002241 ASSERT(m_frame.view());
mjs8d620d52007-05-10 12:31:42 +00002242
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00002243 if (m_stateMachine.creatingInitialEmptyDocument())
mjs8d620d52007-05-10 12:31:42 +00002244 return;
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00002245
2246 if (!m_stateMachine.committedFirstRealDocumentLoad())
2247 m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
beidson50c3bd82007-01-03 03:11:18 +00002248}
2249
achristensen@apple.com6fddc912018-10-18 21:16:52 +00002250void FrameLoader::clientRedirectCancelledOrFinished(NewLoadInProgress newLoadInProgress)
darinc370e7e2006-11-08 05:52:27 +00002251{
2252 // Note that -webView:didCancelClientRedirectForFrame: is called on the frame load delegate even if
2253 // the redirect succeeded. We should either rename this API, or add a new method, like
2254 // -webView:didFinishClientRedirectForFrame:
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002255 m_client->dispatchDidCancelClientRedirect();
darinc370e7e2006-11-08 05:52:27 +00002256
achristensen@apple.com6fddc912018-10-18 21:16:52 +00002257 if (newLoadInProgress == NewLoadInProgress::No)
darinc370e7e2006-11-08 05:52:27 +00002258 m_quickRedirectComing = false;
2259
2260 m_sentRedirectNotification = false;
2261}
2262
utatane.tea@gmail.comeb3a8092018-02-23 04:18:17 +00002263void FrameLoader::clientRedirected(const URL& url, double seconds, WallTime fireDate, LockBackForwardList lockBackForwardList)
darinc370e7e2006-11-08 05:52:27 +00002264{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002265 m_client->dispatchWillPerformClientRedirect(url, seconds, fireDate, lockBackForwardList);
darinc370e7e2006-11-08 05:52:27 +00002266
2267 // Remember that we sent a redirect notification to the frame load delegate so that when we commit
2268 // the next provisional load, we can send a corresponding -webView:didCancelClientRedirectForFrame:
2269 m_sentRedirectNotification = true;
2270
darin@apple.com0f88bda2009-04-02 00:30:50 +00002271 // If a "quick" redirect comes in, we set a special mode so we treat the next
2272 // load as part of the original navigation. If we don't have a document loader, we have
darinc370e7e2006-11-08 05:52:27 +00002273 // no "original" load on which to base a redirect, so we treat the redirect as a normal load.
darin@apple.com0f88bda2009-04-02 00:30:50 +00002274 // Loads triggered by JavaScript form submissions never count as quick redirects.
mrowe@apple.combf5eaa62014-04-03 00:51:04 +00002275 m_quickRedirectComing = (lockBackForwardList == LockBackForwardList::Yes || history().currentItemShouldBeReplaced()) && m_documentLoader && !m_isExecutingJavaScriptFormAction;
darinc370e7e2006-11-08 05:52:27 +00002276}
2277
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00002278bool FrameLoader::shouldReload(const URL& currentURL, const URL& destinationURL)
darinc370e7e2006-11-08 05:52:27 +00002279{
2280 // This function implements the rule: "Don't reload if navigating by fragment within
2281 // the same URL, but do reload if going to a new URL or to the same URL with no
2282 // fragment identifier at all."
beidson@apple.comee497252009-08-10 16:35:00 +00002283 if (!destinationURL.hasFragmentIdentifier())
darinc370e7e2006-11-08 05:52:27 +00002284 return true;
beidson@apple.comee497252009-08-10 16:35:00 +00002285 return !equalIgnoringFragmentIdentifier(currentURL, destinationURL);
darinc370e7e2006-11-08 05:52:27 +00002286}
2287
2288void FrameLoader::closeOldDataSources()
2289{
2290 // FIXME: Is it important for this traversal to be postorder instead of preorder?
2291 // If so, add helpers for postorder traversal, and use them. If not, then lets not
2292 // use a recursive algorithm here.
darin@apple.comfed4d162013-08-25 02:28:06 +00002293 for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
andersca@apple.comdf550b92013-08-15 22:17:17 +00002294 child->loader().closeOldDataSources();
darinc370e7e2006-11-08 05:52:27 +00002295
2296 if (m_documentLoader)
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002297 m_client->dispatchWillClose();
darinc370e7e2006-11-08 05:52:27 +00002298
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002299 m_client->setMainFrameDocumentReady(false); // stop giving out the actual DOMDocument to observers
darinc370e7e2006-11-08 05:52:27 +00002300}
2301
dbates@webkit.orgcd75cb62017-03-15 22:44:59 +00002302void FrameLoader::willRestoreFromCachedPage()
darinc370e7e2006-11-08 05:52:27 +00002303{
darin@apple.comfed4d162013-08-25 02:28:06 +00002304 ASSERT(!m_frame.tree().parent());
akling@apple.com7f50aae2013-08-22 16:01:31 +00002305 ASSERT(m_frame.page());
darin@apple.com0e83ab12013-09-28 17:19:04 +00002306 ASSERT(m_frame.isMainFrame());
darinc370e7e2006-11-08 05:52:27 +00002307
akling@apple.com7f50aae2013-08-22 16:01:31 +00002308 m_frame.navigationScheduler().cancel();
darinc370e7e2006-11-08 05:52:27 +00002309
2310 // We still have to close the previous part page.
2311 closeURL();
darinc370e7e2006-11-08 05:52:27 +00002312
2313 // Delete old status bar messages (if it _was_ activated on last URL).
akling@apple.com7f50aae2013-08-22 16:01:31 +00002314 if (m_frame.script().canExecuteScripts(NotAboutToExecuteScript)) {
2315 DOMWindow* window = m_frame.document()->domWindow();
abarth@webkit.org13fe1e22012-08-16 22:29:48 +00002316 window->setStatus(String());
2317 window->setDefaultStatus(String());
darinc370e7e2006-11-08 05:52:27 +00002318 }
beidson@apple.com028c7a72009-02-11 22:01:22 +00002319}
2320
beidson@apple.com913c7f82009-09-02 20:16:38 +00002321void FrameLoader::open(CachedFrameBase& cachedFrame)
beidson@apple.com028c7a72009-02-11 22:01:22 +00002322{
2323 m_isComplete = false;
2324
2325 // Don't re-emit the load event.
2326 m_didCallImplicitClose = true;
2327
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00002328 URL url = cachedFrame.url();
darinc370e7e2006-11-08 05:52:27 +00002329
abarth@webkit.org55d49da2011-06-20 23:32:54 +00002330 // FIXME: I suspect this block of code doesn't do anything.
benjamin@webkit.orgf726d632012-03-04 03:26:27 +00002331 if (url.protocolIsInHTTPFamily() && !url.host().isEmpty() && url.path().isEmpty())
weinig@apple.comc5002662007-12-12 07:26:19 +00002332 url.setPath("/");
abarth@webkit.org55d49da2011-06-20 23:32:54 +00002333
abarth@webkit.org91289c32010-04-12 04:54:55 +00002334 started();
rniwa@webkit.org77c65702019-08-13 05:18:11 +00002335 auto document = makeRef(*cachedFrame.document());
abarth@webkit.org23ea90a2012-08-14 19:47:59 +00002336 ASSERT(document->domWindow());
2337
rniwa@webkit.org77c65702019-08-13 05:18:11 +00002338 clear(document.ptr(), true, true, cachedFrame.isMainFrame());
abarth@webkit.org23ea90a2012-08-14 19:47:59 +00002339
cdumez@apple.comf0705d72019-07-01 21:55:03 +00002340 document->attachToCachedFrame(cachedFrame);
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002341 document->setBackForwardCacheState(Document::NotInBackForwardCache);
darinc370e7e2006-11-08 05:52:27 +00002342
2343 m_needsClear = true;
2344 m_isComplete = false;
ggarena57755c2007-07-09 21:08:10 +00002345 m_didCallImplicitClose = false;
Hironori.Fujii@sony.com27c57b42019-08-28 01:40:42 +00002346 setOutgoingReferrer(url);
kmccullo6b1b5c22007-05-24 20:06:56 +00002347
beidson@apple.com028c7a72009-02-11 22:01:22 +00002348 FrameView* view = cachedFrame.view();
2349
2350 // When navigating to a CachedFrame its FrameView should never be null. If it is we'll crash in creative ways downstream.
2351 ASSERT(view);
beidson@apple.com24f92a52009-09-03 00:07:51 +00002352 view->setWasScrolledByUser(false);
adachan@apple.com95f492a2009-08-24 19:55:23 +00002353
cdumez@apple.com8b7a0222018-12-20 04:41:11 +00002354 Optional<IntRect> previousViewFrameRect = m_frame.view() ? m_frame.view()->frameRect() : Optional<IntRect>(WTF::nullopt);
akling@apple.com7f50aae2013-08-22 16:01:31 +00002355 m_frame.setView(view);
cdumez@apple.com665ca3b2015-05-08 18:15:57 +00002356
2357 // Use the previous ScrollView's frame rect.
2358 if (previousViewFrameRect)
2359 view->setFrameRect(previousViewFrameRect.value());
dbates@webkit.org7259cf32018-08-21 16:50:20 +00002360
rniwa@webkit.org77c65702019-08-13 05:18:11 +00002361
2362 // Setting the document builds the render tree and runs post style resolution callbacks that can do anything,
2363 // including loading a child frame before its been re-attached to the frame tree as part of this restore.
2364 // For example, the HTML object element may load its content into a frame in a post style resolution callback.
2365 Style::PostResolutionCallbackDisabler disabler(document.get());
2366 WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
2367 NavigationDisabler disableNavigation { &m_frame };
2368
2369 m_frame.setDocument(document.copyRef());
dbates@webkit.org7259cf32018-08-21 16:50:20 +00002370
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002371 document->domWindow()->resumeFromBackForwardCache();
weinig@apple.com5367c412008-06-27 00:03:25 +00002372
abarth@webkit.org622d9df2009-05-22 16:44:47 +00002373 updateFirstPartyForCookies();
darinc370e7e2006-11-08 05:52:27 +00002374
beidson@apple.com028c7a72009-02-11 22:01:22 +00002375 cachedFrame.restore();
darinc370e7e2006-11-08 05:52:27 +00002376}
2377
darinc370e7e2006-11-08 05:52:27 +00002378bool FrameLoader::isHostedByObjectElement() const
2379{
akling@apple.com7f50aae2013-08-22 16:01:31 +00002380 HTMLFrameOwnerElement* owner = m_frame.ownerElement();
darinc370e7e2006-11-08 05:52:27 +00002381 return owner && owner->hasTagName(objectTag);
2382}
2383
darinc370e7e2006-11-08 05:52:27 +00002384bool FrameLoader::isReplacing() const
2385{
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002386 return m_loadType == FrameLoadType::Replace;
darinc370e7e2006-11-08 05:52:27 +00002387}
2388
2389void FrameLoader::setReplacing()
2390{
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002391 m_loadType = FrameLoadType::Replace;
darinc370e7e2006-11-08 05:52:27 +00002392}
2393
darinc370e7e2006-11-08 05:52:27 +00002394bool FrameLoader::subframeIsLoading() const
2395{
2396 // It's most likely that the last added frame is the last to load so we walk backwards.
darin@apple.comfed4d162013-08-25 02:28:06 +00002397 for (Frame* child = m_frame.tree().lastChild(); child; child = child->tree().previousSibling()) {
andersca@apple.comdf550b92013-08-15 22:17:17 +00002398 FrameLoader& childLoader = child->loader();
2399 DocumentLoader* documentLoader = childLoader.documentLoader();
darinc370e7e2006-11-08 05:52:27 +00002400 if (documentLoader && documentLoader->isLoadingInAPISense())
2401 return true;
andersca@apple.comdf550b92013-08-15 22:17:17 +00002402 documentLoader = childLoader.provisionalDocumentLoader();
darinc370e7e2006-11-08 05:52:27 +00002403 if (documentLoader && documentLoader->isLoadingInAPISense())
2404 return true;
andersca@apple.comdf550b92013-08-15 22:17:17 +00002405 documentLoader = childLoader.policyDocumentLoader();
mjs@apple.com17a175d2010-07-18 00:15:31 +00002406 if (documentLoader)
2407 return true;
darinc370e7e2006-11-08 05:52:27 +00002408 }
2409 return false;
2410}
2411
2412void FrameLoader::willChangeTitle(DocumentLoader* loader)
2413{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002414 m_client->willChangeTitle(loader);
darinc370e7e2006-11-08 05:52:27 +00002415}
2416
2417FrameLoadType FrameLoader::loadType() const
2418{
2419 return m_loadType;
2420}
antti@apple.com4da613e2008-12-15 15:28:41 +00002421
antti@apple.com2b38ed12017-04-26 18:22:27 +00002422CachePolicy FrameLoader::subresourceCachePolicy(const URL& url) const
antti@apple.com4da613e2008-12-15 15:28:41 +00002423{
darin@apple.com30c194a2016-03-20 20:08:59 +00002424 if (Page* page = m_frame.page()) {
cdumez@apple.coma231c912019-10-16 18:24:25 +00002425 if (page->isResourceCachingDisabledByWebInspector())
darin@apple.com30c194a2016-03-20 20:08:59 +00002426 return CachePolicyReload;
2427 }
darin@apple.com0fdefc32016-03-18 07:56:20 +00002428
antti@apple.com4da613e2008-12-15 15:28:41 +00002429 if (m_isComplete)
2430 return CachePolicyVerify;
ap@webkit.org86b10982009-05-18 15:30:10 +00002431
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002432 if (m_loadType == FrameLoadType::ReloadFromOrigin)
antti@apple.com4da613e2008-12-15 15:28:41 +00002433 return CachePolicyReload;
ap@webkit.org86b10982009-05-18 15:30:10 +00002434
darin@apple.comfed4d162013-08-25 02:28:06 +00002435 if (Frame* parentFrame = m_frame.tree().parent()) {
antti@apple.com2b38ed12017-04-26 18:22:27 +00002436 CachePolicy parentCachePolicy = parentFrame->loader().subresourceCachePolicy(url);
antti@apple.com4da613e2008-12-15 15:28:41 +00002437 if (parentCachePolicy != CachePolicyVerify)
2438 return parentCachePolicy;
2439 }
slewis@apple.comef236f42011-05-25 23:00:45 +00002440
cdumez@apple.com74493162014-12-08 18:42:12 +00002441 switch (m_loadType) {
2442 case FrameLoadType::Reload:
antti@apple.com4da613e2008-12-15 15:28:41 +00002443 return CachePolicyRevalidate;
cdumez@apple.com74493162014-12-08 18:42:12 +00002444 case FrameLoadType::Back:
2445 case FrameLoadType::Forward:
2446 case FrameLoadType::IndexedBackForward:
joepeck@webkit.org853e6862010-11-18 17:59:53 +00002447 return CachePolicyHistoryBuffer;
cdumez@apple.com74493162014-12-08 18:42:12 +00002448 case FrameLoadType::ReloadFromOrigin:
2449 ASSERT_NOT_REACHED(); // Already handled above.
2450 return CachePolicyReload;
2451 case FrameLoadType::RedirectWithLockedBackForwardList:
2452 case FrameLoadType::Replace:
2453 case FrameLoadType::Same:
2454 case FrameLoadType::Standard:
antti@apple.com2b38ed12017-04-26 18:22:27 +00002455 return CachePolicyVerify;
antti@apple.com5d0c5402017-03-17 19:52:49 +00002456 case FrameLoadType::ReloadExpiredOnly:
antti@apple.com2b38ed12017-04-26 18:22:27 +00002457 // We know about expiration for HTTP and data. Do a normal reload otherwise.
2458 if (!url.protocolIsInHTTPFamily() && !url.protocolIsData())
2459 return CachePolicyReload;
cdumez@apple.com74493162014-12-08 18:42:12 +00002460 return CachePolicyVerify;
2461 }
ossy@webkit.org41788ca2014-12-08 19:30:19 +00002462
2463 RELEASE_ASSERT_NOT_REACHED();
2464 return CachePolicyVerify;
antti@apple.com4da613e2008-12-15 15:28:41 +00002465}
darinc370e7e2006-11-08 05:52:27 +00002466
aestes@apple.com5a4908d2019-06-07 06:09:40 +00002467void FrameLoader::dispatchDidFailProvisionalLoad(DocumentLoader& provisionalDocumentLoader, const ResourceError& error)
2468{
2469 m_provisionalLoadErrorBeingHandledURL = provisionalDocumentLoader.url();
2470
2471#if ENABLE(CONTENT_FILTERING)
2472 auto contentFilter = provisionalDocumentLoader.contentFilter();
2473 auto contentFilterWillContinueLoading = false;
2474#endif
2475
2476 auto willContinueLoading = WillContinueLoading::No;
2477 if (history().provisionalItem())
2478 willContinueLoading = WillContinueLoading::Yes;
2479#if ENABLE(CONTENT_FILTERING)
2480 if (contentFilter && contentFilter->willHandleProvisionalLoadFailure(error)) {
2481 willContinueLoading = WillContinueLoading::Yes;
2482 contentFilterWillContinueLoading = true;
2483 }
2484#endif
2485
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002486 m_client->dispatchDidFailProvisionalLoad(error, willContinueLoading);
aestes@apple.com5a4908d2019-06-07 06:09:40 +00002487
2488#if ENABLE(CONTENT_FILTERING)
2489 if (contentFilterWillContinueLoading)
2490 contentFilter->handleProvisionalLoadFailure(error);
2491#endif
2492
2493 m_provisionalLoadErrorBeingHandledURL = { };
2494}
2495
andersca4422e372007-01-12 19:56:19 +00002496void FrameLoader::checkLoadCompleteForThisFrame()
2497{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002498 ASSERT(m_client->hasWebView());
andersca4422e372007-01-12 19:56:19 +00002499
darin@apple.combe4d3dd2017-07-30 21:44:01 +00002500 // FIXME: Should this check be done in checkLoadComplete instead of here?
2501 // FIXME: Why does this one check need to be repeated here, and not the many others from checkCompleted?
2502 if (m_frame.document()->isDelayingLoadEvent())
2503 return;
2504
andersca4422e372007-01-12 19:56:19 +00002505 switch (m_state) {
2506 case FrameStateProvisional: {
jiewen_tan@apple.com8c36f622016-04-01 21:40:20 +00002507 // FIXME: Prohibiting any provisional load failures from being sent to clients
2508 // while handling provisional load failures is too heavy. For example, the current
2509 // load will fail to cancel another ongoing load. That might prevent clients' page
2510 // load state being handled properly.
mitz@apple.com6699e272015-05-01 23:47:03 +00002511 if (!m_provisionalLoadErrorBeingHandledURL.isEmpty())
andersca4422e372007-01-12 19:56:19 +00002512 return;
2513
2514 RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
2515 if (!pdl)
2516 return;
2517
2518 // If we've received any errors we may be stuck in the provisional state and actually complete.
2519 const ResourceError& error = pdl->mainDocumentError();
2520 if (error.isNull())
2521 return;
2522
2523 // Check all children first.
2524 RefPtr<HistoryItem> item;
akling@apple.com7f50aae2013-08-22 16:01:31 +00002525 if (Page* page = m_frame.page())
commit-queue@webkit.org21a48d82011-01-09 01:27:19 +00002526 if (isBackForwardLoadType(loadType()))
2527 // Reset the back forward list to the last committed history item at the top level.
akling@apple.com095b5442013-08-27 02:47:37 +00002528 item = page->mainFrame().loader().history().currentItem();
andersca4422e372007-01-12 19:56:19 +00002529
commit-queue@webkit.org987fd772011-01-21 18:26:42 +00002530 // Only reset if we aren't already going to a new provisional item.
akling@apple.com672cb852013-08-22 20:27:27 +00002531 bool shouldReset = !history().provisionalItem();
ap@apple.com421e9a12011-03-24 00:50:45 +00002532 if (!pdl->isLoadingInAPISense() || pdl->isStopping()) {
krollin@apple.combdeaed72020-01-08 01:31:20 +00002533 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "checkLoadCompleteForThisFrame: Failed provisional load (isTimeout = %d, isCancellation = %d, errorCode = %d)", error.isTimeout(), error.isCancellation(), error.errorCode());
cdumez@apple.com41883a92019-04-23 15:38:11 +00002534
aestes@apple.com5a4908d2019-06-07 06:09:40 +00002535 dispatchDidFailProvisionalLoad(*pdl, error);
ap@apple.com09535d12011-03-24 00:48:30 +00002536 ASSERT(!pdl->isLoading());
andersca4422e372007-01-12 19:56:19 +00002537
eric@webkit.orgb562c402010-01-13 01:29:35 +00002538 // If we're in the middle of loading multipart data, we need to restore the document loader.
2539 if (isReplacing() && !m_documentLoader.get())
eric@webkit.org90747252010-01-12 18:10:14 +00002540 setDocumentLoader(m_provisionalDocumentLoader.get());
2541
andersca4422e372007-01-12 19:56:19 +00002542 // Finish resetting the load state, but only if another load hasn't been started by the
2543 // delegate callback.
2544 if (pdl == m_provisionalDocumentLoader)
2545 clearProvisionalLoad();
tonikitoo@webkit.orge94ac9b2009-11-16 15:38:19 +00002546 else if (activeDocumentLoader()) {
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00002547 URL unreachableURL = activeDocumentLoader()->unreachableURL();
andersca4422e372007-01-12 19:56:19 +00002548 if (!unreachableURL.isEmpty() && unreachableURL == pdl->request().url())
2549 shouldReset = false;
2550 }
2551 }
darine0cef432007-07-10 19:21:23 +00002552 if (shouldReset && item)
akling@apple.com7f50aae2013-08-22 16:01:31 +00002553 if (Page* page = m_frame.page()) {
achristensen@apple.com3a889f12018-10-16 15:58:10 +00002554 page->backForward().setCurrentItem(*item);
mitz@apple.combc843762008-12-08 21:18:11 +00002555 }
andersca4422e372007-01-12 19:56:19 +00002556 return;
2557 }
2558
2559 case FrameStateCommittedPage: {
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00002560 if (!m_documentLoader)
2561 return;
2562 if (m_documentLoader->isLoadingInAPISense() && !m_documentLoader->isStopping() && !m_checkingLoadCompleteForDetachment)
andersca4422e372007-01-12 19:56:19 +00002563 return;
2564
darin@apple.comaf8b1a92011-06-25 00:09:37 +00002565 setState(FrameStateComplete);
andersca4422e372007-01-12 19:56:19 +00002566
2567 // FIXME: Is this subsequent work important if we already navigated away?
2568 // Maybe there are bugs because of that, or extra work we can skip because
2569 // the new page is ready.
2570
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002571 m_client->forceLayoutForNonHTML();
andersca4422e372007-01-12 19:56:19 +00002572
2573 // If the user had a scroll point, scroll to it, overriding the anchor point if any.
akling@apple.com7f50aae2013-08-22 16:01:31 +00002574 if (m_frame.page()) {
antti@apple.com5d0c5402017-03-17 19:52:49 +00002575 if (isBackForwardLoadType(m_loadType) || isReload(m_loadType))
akling@apple.com672cb852013-08-22 20:27:27 +00002576 history().restoreScrollPositionAndViewState();
darin@apple.come10e1282010-10-30 00:44:33 +00002577 }
andersca4422e372007-01-12 19:56:19 +00002578
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00002579 if (m_stateMachine.creatingInitialEmptyDocument() || !m_stateMachine.committedFirstRealDocumentLoad())
mjs8d620d52007-05-10 12:31:42 +00002580 return;
2581
timothy_horton@apple.com346f8d72013-08-01 00:06:51 +00002582 m_progressTracker->progressCompleted();
eric.carlson@apple.com77b4a112014-10-30 19:04:29 +00002583 Page* page = m_frame.page();
2584 if (page) {
simon.fraser@apple.com83325b92017-03-17 00:47:16 +00002585 if (m_frame.isMainFrame()) {
sbarati@apple.comce7ec112018-04-17 15:57:32 +00002586 tracePoint(MainResourceLoadDidEnd);
cdumez@apple.comef2c0152017-01-13 17:54:53 +00002587 page->didFinishLoad();
simon.fraser@apple.com83325b92017-03-17 00:47:16 +00002588 }
andersca@apple.com7c0a3fc2012-05-01 22:22:25 +00002589 }
2590
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00002591 const ResourceError& error = m_documentLoader->mainDocumentError();
mario@webkit.org685258f2011-12-06 00:10:55 +00002592
2593 AXObjectCache::AXLoadingEvent loadingEvent;
2594 if (!error.isNull()) {
krollin@apple.combdeaed72020-01-08 01:31:20 +00002595 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "checkLoadCompleteForThisFrame: Finished frame load with error (isTimeout = %d, isCancellation = %d, errorCode = %d)", error.isTimeout(), error.isCancellation(), error.errorCode());
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002596 m_client->dispatchDidFailLoad(error);
mario@webkit.org685258f2011-12-06 00:10:55 +00002597 loadingEvent = AXObjectCache::AXLoadingFailed;
2598 } else {
krollin@apple.combdeaed72020-01-08 01:31:20 +00002599 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "checkLoadCompleteForThisFrame: Finished frame load");
enrica@apple.com53b08e52016-01-19 22:58:59 +00002600#if ENABLE(DATA_DETECTION)
darin@apple.come729ead2020-04-27 15:05:00 +00002601 auto document = m_frame.document();
2602 auto types = m_frame.settings().dataDetectorTypes();
2603 if (document && static_cast<uint32_t>(types)) {
2604 m_frame.setDataDetectionResults(DataDetection::detectContentInRange(makeRangeSelectingNodeContents(*document), types, m_client->dataDetectionContext()));
2605 if (m_frame.isMainFrame())
2606 m_client->dispatchDidFinishDataDetection(m_frame.dataDetectionResults());
enrica@apple.com53b08e52016-01-19 22:58:59 +00002607 }
2608#endif
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002609 m_client->dispatchDidFinishLoad();
enrica@apple.com4c36ad52016-01-23 00:24:02 +00002610 loadingEvent = AXObjectCache::AXLoadingFinished;
mario@webkit.org685258f2011-12-06 00:10:55 +00002611 }
2612
2613 // Notify accessibility.
rniwa@webkit.org2f150e72016-06-14 07:35:53 +00002614 if (auto* document = m_frame.document()) {
2615 if (AXObjectCache* cache = document->existingAXObjectCache())
2616 cache->frameLoadingEventNotification(&m_frame, loadingEvent);
2617 }
andersca4422e372007-01-12 19:56:19 +00002618
beidson@apple.com4aecb3d2015-07-09 04:47:09 +00002619 // The above calls to dispatchDidFinishLoad() might have detached the Frame
2620 // from its Page and also might have caused Page to be deleted.
2621 // Don't assume 'page' is still available to use.
2622 if (m_frame.isMainFrame() && m_frame.page()) {
2623 ASSERT(&m_frame.page()->mainFrame() == &m_frame);
cdumez@apple.com10d0f252016-04-23 21:33:49 +00002624 m_frame.page()->diagnosticLoggingClient().logDiagnosticMessageWithResult(DiagnosticLoggingKeys::pageLoadedKey(), emptyString(), error.isNull() ? DiagnosticLoggingResultPass : DiagnosticLoggingResultFail, ShouldSample::Yes);
beidson@apple.com4aecb3d2015-07-09 04:47:09 +00002625 }
eric.carlson@apple.com77b4a112014-10-30 19:04:29 +00002626
andersca4422e372007-01-12 19:56:19 +00002627 return;
2628 }
2629
2630 case FrameStateComplete:
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002631 m_loadType = FrameLoadType::Standard;
beidson@apple.comd1418272009-01-30 17:30:47 +00002632 frameLoadCompleted();
andersca4422e372007-01-12 19:56:19 +00002633 return;
2634 }
2635
2636 ASSERT_NOT_REACHED();
2637}
andersca5d5f8022007-02-28 00:38:00 +00002638
ap@apple.com456d4652011-11-30 12:13:31 +00002639void FrameLoader::setOriginalURLForDownloadRequest(ResourceRequest& request)
2640{
jiewen_tan@apple.com82836202016-03-31 20:39:24 +00002641 // FIXME: Rename firstPartyForCookies back to mainDocumentURL. It was a mistake to think that it was only used for cookies.
2642 // The originalURL is defined as the URL of the page where the download was initiated.
jiewen_tan@apple.com65b38162016-12-22 00:04:11 +00002643 URL originalURL;
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002644 auto* initiator = m_frame.document();
2645 if (initiator) {
2646 originalURL = initiator->firstPartyForCookies();
jiewen_tan@apple.com65b38162016-12-22 00:04:11 +00002647 // If there is no main document URL, it means that this document is newly opened and just for download purpose.
2648 // In this case, we need to set the originalURL to this document's opener's main document URL.
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002649 if (originalURL.isEmpty() && opener() && opener()->document()) {
jiewen_tan@apple.com65b38162016-12-22 00:04:11 +00002650 originalURL = opener()->document()->firstPartyForCookies();
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002651 initiator = opener()->document();
2652 }
jiewen_tan@apple.com65b38162016-12-22 00:04:11 +00002653 }
jiewen_tan@apple.com82836202016-03-31 20:39:24 +00002654 // If the originalURL is the same as the requested URL, we are processing a download
2655 // initiated directly without a page and do not need to specify the originalURL.
2656 if (originalURL == request.url())
2657 request.setFirstPartyForCookies(URL());
2658 else
2659 request.setFirstPartyForCookies(originalURL);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002660 addSameSiteInfoToRequestIfNeeded(request, initiator);
ap@apple.com456d4652011-11-30 12:13:31 +00002661}
2662
antti@apple.com8e03f742018-11-09 19:47:15 +00002663void FrameLoader::didReachLayoutMilestone(OptionSet<LayoutMilestone> milestones)
darinc370e7e2006-11-08 05:52:27 +00002664{
darin@apple.com0e83ab12013-09-28 17:19:04 +00002665 ASSERT(m_frame.isMainFrame());
bdakin@apple.com7ce7e1b2013-08-12 21:37:06 +00002666
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002667 m_client->dispatchDidReachLayoutMilestone(milestones);
bdakin@apple.com3ab37372012-02-01 21:52:41 +00002668}
2669
bdakin@apple.come98caf12012-09-25 23:08:03 +00002670void FrameLoader::didFirstLayout()
2671{
ap@apple.com1e8475922018-10-18 21:38:50 +00002672#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002673 // Only send layout-related delegate callbacks synchronously for the main frame to
2674 // avoid reentering layout for the main frame while delivering a layout-related delegate
2675 // callback for a subframe.
2676 if (&m_frame != &m_frame.page()->mainFrame())
2677 return;
2678#endif
akling@apple.com7f50aae2013-08-22 16:01:31 +00002679 if (m_frame.page() && isBackForwardLoadType(m_loadType))
akling@apple.com672cb852013-08-22 20:27:27 +00002680 history().restoreScrollPositionAndViewState();
bdakin@apple.come98caf12012-09-25 23:08:03 +00002681
2682 if (m_stateMachine.committedFirstRealDocumentLoad() && !m_stateMachine.isDisplayingInitialEmptyDocument() && !m_stateMachine.firstLayoutDone())
2683 m_stateMachine.advanceTo(FrameLoaderStateMachine::FirstLayoutDone);
2684}
2685
zalan@apple.comfc7ad742020-03-04 14:53:01 +00002686void FrameLoader::didReachVisuallyNonEmptyState()
2687{
2688 ASSERT(m_frame.isMainFrame());
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002689 m_client->dispatchDidReachVisuallyNonEmptyState();
zalan@apple.comfc7ad742020-03-04 14:53:01 +00002690}
2691
darinc370e7e2006-11-08 05:52:27 +00002692void FrameLoader::frameLoadCompleted()
2693{
beidson@apple.comd1418272009-01-30 17:30:47 +00002694 // Note: Can be called multiple times.
2695
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002696 m_client->frameLoadCompleted();
darinc370e7e2006-11-08 05:52:27 +00002697
akling@apple.com672cb852013-08-22 20:27:27 +00002698 history().updateForFrameLoadCompleted();
beidson@apple.comd1418272009-01-30 17:30:47 +00002699
darinc370e7e2006-11-08 05:52:27 +00002700 // After a canceled provisional load, firstLayoutDone is false.
2701 // Reset it to true if we're displaying a page.
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00002702 if (m_documentLoader && m_stateMachine.committedFirstRealDocumentLoad() && !m_stateMachine.isDisplayingInitialEmptyDocument() && !m_stateMachine.firstLayoutDone())
2703 m_stateMachine.advanceTo(FrameLoaderStateMachine::FirstLayoutDone);
darinc370e7e2006-11-08 05:52:27 +00002704}
2705
darinc370e7e2006-11-08 05:52:27 +00002706void FrameLoader::detachChildren()
2707{
cdumez@apple.com8b478c62016-01-23 01:04:59 +00002708 // detachChildren() will fire the unload event in each subframe and the
2709 // HTML specification states that the parent document's ignore-opens-during-unload counter while
2710 // this event is being fired in its subframes:
2711 // https://html.spec.whatwg.org/multipage/browsers.html#unload-a-document
2712 IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
2713
cdumez@apple.comf0705d72019-07-01 21:55:03 +00002714 // detachChildren() will fire the unload event in each subframe and the
2715 // HTML specification states that navigations should be prevented during the prompt to unload algorithm:
2716 // https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate
2717 std::unique_ptr<NavigationDisabler> navigationDisabler;
2718 if (m_frame.isMainFrame())
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +00002719 navigationDisabler = makeUnique<NavigationDisabler>(&m_frame);
cdumez@apple.comf0705d72019-07-01 21:55:03 +00002720
cdumez@apple.com6857a012017-03-02 23:43:09 +00002721 // Any subframe inserted by unload event handlers executed in the loop below will not get unloaded
2722 // because we create a copy of the subframes list before looping. Therefore, it would be unsafe to
2723 // allow loading of subframes at this point.
2724 SubframeLoadingDisabler subframeLoadingDisabler(m_frame.document());
2725
akling@apple.com72c1c362013-09-06 01:34:05 +00002726 Vector<Ref<Frame>, 16> childrenToDetach;
2727 childrenToDetach.reserveInitialCapacity(m_frame.tree().childCount());
darin@apple.comfed4d162013-08-25 02:28:06 +00002728 for (Frame* child = m_frame.tree().lastChild(); child; child = child->tree().previousSibling())
akling@apple.com72c1c362013-09-06 01:34:05 +00002729 childrenToDetach.uncheckedAppend(*child);
commit-queue@webkit.orgacddfad2015-09-30 05:53:51 +00002730 for (auto& child : childrenToDetach)
2731 child->loader().detachFromParent();
darinc370e7e2006-11-08 05:52:27 +00002732}
2733
darin@apple.com9ace8012017-01-23 06:24:18 +00002734void FrameLoader::closeAndRemoveChild(Frame& child)
beidson@apple.com028c7a72009-02-11 22:01:22 +00002735{
darin@apple.com9ace8012017-01-23 06:24:18 +00002736 child.tree().detachFromParent();
beidson@apple.com028c7a72009-02-11 22:01:22 +00002737
darin@apple.com9ace8012017-01-23 06:24:18 +00002738 child.setView(nullptr);
2739 if (child.ownerElement() && child.page())
2740 child.page()->decrementSubframeCount();
2741 child.willDetachPage();
2742 child.detachFromPage();
beidson@apple.com028c7a72009-02-11 22:01:22 +00002743
darin@apple.comfed4d162013-08-25 02:28:06 +00002744 m_frame.tree().removeChild(child);
beidson@apple.com028c7a72009-02-11 22:01:22 +00002745}
2746
darin@apple.comaf8b1a92011-06-25 00:09:37 +00002747// Called every time a resource is completely loaded or an error is received.
darinc370e7e2006-11-08 05:52:27 +00002748void FrameLoader::checkLoadComplete()
2749{
darin@apple.comf53381b2009-09-23 23:27:01 +00002750 m_shouldCallCheckLoadComplete = false;
2751
akling@apple.com72c1c362013-09-06 01:34:05 +00002752 if (!m_frame.page())
2753 return;
2754
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002755 ASSERT(m_client->hasWebView());
darin@apple.com355b1522017-08-15 18:13:57 +00002756
anderscaa315d572007-03-13 01:09:53 +00002757 // FIXME: Always traversing the entire frame tree is a bit inefficient, but
2758 // is currently needed in order to null out the previous history item for all frames.
akling@apple.com72c1c362013-09-06 01:34:05 +00002759 Vector<Ref<Frame>, 16> frames;
darin@apple.com0e83ab12013-09-28 17:19:04 +00002760 for (Frame* frame = &m_frame.mainFrame(); frame; frame = frame->tree().traverseNext())
akling@apple.com72c1c362013-09-06 01:34:05 +00002761 frames.append(*frame);
2762
2763 // To process children before their parents, iterate the vector backwards.
jiewen_tan@apple.combe26fa32015-12-01 00:33:47 +00002764 for (auto frame = frames.rbegin(); frame != frames.rend(); ++frame) {
2765 if ((*frame)->page())
2766 (*frame)->loader().checkLoadCompleteForThisFrame();
2767 }
darinc370e7e2006-11-08 05:52:27 +00002768}
2769
2770int FrameLoader::numPendingOrLoadingRequests(bool recurse) const
2771{
2772 if (!recurse)
cdumez@apple.com0bb03ec2015-01-28 05:53:53 +00002773 return m_frame.document()->cachedResourceLoader().requestCount();
darinc370e7e2006-11-08 05:52:27 +00002774
2775 int count = 0;
darin@apple.comfed4d162013-08-25 02:28:06 +00002776 for (Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext(&m_frame))
cdumez@apple.com0bb03ec2015-01-28 05:53:53 +00002777 count += frame->document()->cachedResourceLoader().requestCount();
darinc370e7e2006-11-08 05:52:27 +00002778 return count;
2779}
2780
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00002781String FrameLoader::userAgent(const URL& url) const
darinc370e7e2006-11-08 05:52:27 +00002782{
drousso@apple.comc9a88bd2019-01-26 22:32:38 +00002783 String userAgent;
2784
rniwa@webkit.org15470912019-01-26 06:50:58 +00002785 if (auto* documentLoader = m_frame.mainFrame().loader().activeDocumentLoader()) {
rniwa@webkit.orgaf0b1ae2019-01-29 07:15:00 +00002786 if (m_frame.settings().needsSiteSpecificQuirks())
rniwa@webkit.org75b8f3e2019-12-04 04:28:10 +00002787 userAgent = documentLoader->customUserAgentAsSiteSpecificQuirks();
drousso@apple.comc9a88bd2019-01-26 22:32:38 +00002788 if (userAgent.isEmpty())
2789 userAgent = documentLoader->customUserAgent();
rniwa@webkit.org15470912019-01-26 06:50:58 +00002790 }
2791
drousso@apple.comc9a88bd2019-01-26 22:32:38 +00002792 InspectorInstrumentation::applyUserAgentOverride(m_frame, userAgent);
2793
2794 if (!userAgent.isEmpty())
2795 return userAgent;
2796
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002797 return m_client->userAgent(url);
rniwa@webkit.org15470912019-01-26 06:50:58 +00002798}
rniwa@webkit.org75b8f3e2019-12-04 04:28:10 +00002799
megan_gardner@apple.comde788db2018-12-19 20:21:31 +00002800String FrameLoader::navigatorPlatform() const
2801{
2802 if (auto* documentLoader = m_frame.mainFrame().loader().activeDocumentLoader()) {
2803 auto& customNavigatorPlatform = documentLoader->customNavigatorPlatform();
2804 if (!customNavigatorPlatform.isEmpty())
2805 return customNavigatorPlatform;
2806 }
2807 return String();
2808}
darinc370e7e2006-11-08 05:52:27 +00002809
ggaren@apple.com7a176e12015-11-12 01:48:27 +00002810void FrameLoader::dispatchOnloadEvents()
darinc370e7e2006-11-08 05:52:27 +00002811{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002812 m_client->dispatchDidDispatchOnloadEvents();
japhet@chromium.org92a952b2010-07-12 18:14:17 +00002813
darin@apple.comaf8b1a92011-06-25 00:09:37 +00002814 if (documentLoader())
ggaren@apple.com7a176e12015-11-12 01:48:27 +00002815 documentLoader()->dispatchOnloadEvents();
darinc370e7e2006-11-08 05:52:27 +00002816}
2817
2818void FrameLoader::frameDetached()
2819{
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00002820 // Calling stopAllLoadersAndCheckCompleteness() can cause the frame to be deallocated, including the frame loader.
bfulgham@apple.com98845d92016-05-17 01:09:27 +00002821 Ref<Frame> protectedFrame(m_frame);
2822
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00002823 if (m_checkTimer.isActive()) {
2824 m_checkTimer.stop();
2825 checkCompletenessNow();
2826 }
2827
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002828 if (m_frame.document()->backForwardCacheState() != Document::InBackForwardCache) {
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00002829 stopAllLoadersAndCheckCompleteness();
dbates@webkit.org6d862de2017-02-11 02:53:53 +00002830 m_frame.document()->stopActiveDOMObjects();
2831 }
2832
darinc370e7e2006-11-08 05:52:27 +00002833 detachFromParent();
2834}
2835
ggarenc04b2c52006-11-30 21:06:14 +00002836void FrameLoader::detachFromParent()
darinc370e7e2006-11-08 05:52:27 +00002837{
dbates@webkit.org6d862de2017-02-11 02:53:53 +00002838 // Calling stopAllLoaders() can cause the frame to be deallocated, including the frame loader.
akling@apple.coma34e5222013-09-10 03:44:05 +00002839 Ref<Frame> protect(m_frame);
ggarenc04b2c52006-11-30 21:06:14 +00002840
ggarenacf28742006-12-27 07:38:18 +00002841 closeURL();
akling@apple.com672cb852013-08-22 20:27:27 +00002842 history().saveScrollPositionAndViewStateToItem(history().currentItem());
ggarenc04b2c52006-11-30 21:06:14 +00002843 detachChildren();
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002844 if (m_frame.document()->backForwardCacheState() != Document::InBackForwardCache) {
2845 // stopAllLoaders() needs to be called after detachChildren() if the document is not in the back/forward cache,
dbates@webkit.org6d862de2017-02-11 02:53:53 +00002846 // because detachedChildren() will trigger the unload event handlers of any child frames, and those event
2847 // handlers might start a new subresource load in this frame.
ajuma@chromium.orgedd75742019-09-11 14:52:18 +00002848 stopAllLoaders(ShouldClearProvisionalItem, StopLoadingPolicy::AlwaysStopLoading);
dbates@webkit.org6d862de2017-02-11 02:53:53 +00002849 }
arobendfc56662007-06-21 01:37:24 +00002850
burg@cs.washington.edudbacfc12015-01-05 21:30:33 +00002851 InspectorInstrumentation::frameDetachedFromParent(m_frame);
arobendfc56662007-06-21 01:37:24 +00002852
beidson@apple.com24f92a52009-09-03 00:07:51 +00002853 detachViewsAndDocumentLoader();
2854
weinig@apple.comeefc25d2013-11-08 22:42:27 +00002855 m_progressTracker = nullptr;
japhet@chromium.org7879dd72012-08-30 02:58:37 +00002856
darin@apple.comfed4d162013-08-25 02:28:06 +00002857 if (Frame* parent = m_frame.tree().parent()) {
darin@apple.com9ace8012017-01-23 06:24:18 +00002858 parent->loader().closeAndRemoveChild(m_frame);
andersca@apple.comdf550b92013-08-15 22:17:17 +00002859 parent->loader().scheduleCheckCompleted();
darin@apple.combe4d3dd2017-07-30 21:44:01 +00002860 parent->loader().scheduleCheckLoadComplete();
weinigc34c71c2007-03-09 16:05:37 +00002861 } else {
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00002862 m_frame.setView(nullptr);
akling@apple.com7f50aae2013-08-22 16:01:31 +00002863 m_frame.willDetachPage();
2864 m_frame.detachFromPage();
ddkilzer3adeb2f2006-12-28 23:33:37 +00002865 }
ggarenc04b2c52006-11-30 21:06:14 +00002866}
beidson@apple.com24f92a52009-09-03 00:07:51 +00002867
2868void FrameLoader::detachViewsAndDocumentLoader()
2869{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002870 m_client->detachedFromParent2();
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00002871 setDocumentLoader(nullptr);
youenn@apple.comee96d0f2020-03-18 13:59:23 +00002872 m_client->detachedFromParent3();
beidson@apple.com24f92a52009-09-03 00:07:51 +00002873}
commit-queue@webkit.org53c0a6b2020-04-02 07:43:14 +00002874
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002875ResourceRequestCachePolicy FrameLoader::defaultRequestCachingPolicy(const ResourceRequest& request, FrameLoadType loadType, bool isMainResource)
beidson50c3bd82007-01-03 03:11:18 +00002876{
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002877 if (m_overrideCachePolicyForTesting)
2878 return m_overrideCachePolicyForTesting.value();
antti@apple.com5d0c5402017-03-17 19:52:49 +00002879
2880 if (isMainResource) {
2881 if (isReload(loadType) || request.isConditional())
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002882 return ResourceRequestCachePolicy::ReloadIgnoringCacheData;
antti@apple.com5d0c5402017-03-17 19:52:49 +00002883
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002884 return ResourceRequestCachePolicy::UseProtocolCachePolicy;
antti@apple.com5d0c5402017-03-17 19:52:49 +00002885 }
2886
2887 if (request.isConditional())
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002888 return ResourceRequestCachePolicy::ReloadIgnoringCacheData;
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002889
antti@apple.com5d0c5402017-03-17 19:52:49 +00002890 if (documentLoader()->isLoadingInAPISense()) {
2891 // If we inherit cache policy from a main resource, we use the DocumentLoader's
2892 // original request cache policy for two reasons:
2893 // 1. For POST requests, we mutate the cache policy for the main resource,
2894 // but we do not want this to apply to subresources
2895 // 2. Delegates that modify the cache policy using willSendRequest: should
2896 // not affect any other resources. Such changes need to be done
2897 // per request.
2898 ResourceRequestCachePolicy mainDocumentOriginalCachePolicy = documentLoader()->originalRequest().cachePolicy();
2899 // Back-forward navigations try to load main resource from cache only to avoid re-submitting form data, and start over (with a warning dialog) if that fails.
2900 // This policy is set on initial request too, but should not be inherited.
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002901 return (mainDocumentOriginalCachePolicy == ResourceRequestCachePolicy::ReturnCacheDataDontLoad) ? ResourceRequestCachePolicy::ReturnCacheDataElseLoad : mainDocumentOriginalCachePolicy;
antti@apple.com5d0c5402017-03-17 19:52:49 +00002902 }
2903
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002904 return ResourceRequestCachePolicy::UseProtocolCachePolicy;
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002905}
2906
commit-queue@webkit.org627a2de2020-04-13 08:04:39 +00002907void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, IsMainResource mainResource, FrameLoadType loadType)
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002908{
cdumez@apple.com3aedc032019-01-31 02:23:55 +00002909 // If the request came from a previous process due to process-swap-on-navigation then we should not modify the request.
2910 if (m_currentLoadContinuingState == LoadContinuingState::ContinuingWithRequest)
cdumez@apple.comfdb89712018-06-11 20:52:31 +00002911 return;
2912
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002913 // Don't set the cookie policy URL if it's already been set.
2914 // But make sure to set it on all requests regardless of protocol, as it has significance beyond the cookie policy (<rdar://problem/6616664>).
commit-queue@webkit.org627a2de2020-04-13 08:04:39 +00002915 bool isMainResource = mainResource == IsMainResource::Yes;
dbates@webkit.org2dc5b0d2019-02-21 23:54:40 +00002916 bool isMainFrameMainResource = isMainResource && m_frame.isMainFrame();
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002917 if (request.firstPartyForCookies().isEmpty()) {
dbates@webkit.org2dc5b0d2019-02-21 23:54:40 +00002918 if (isMainFrameMainResource)
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002919 request.setFirstPartyForCookies(request.url());
2920 else if (Document* document = m_frame.document())
2921 request.setFirstPartyForCookies(document->firstPartyForCookies());
2922 }
2923
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002924 if (request.isSameSiteUnspecified()) {
2925 auto* initiator = m_frame.document();
2926 if (isMainResource) {
2927 auto* ownerFrame = m_frame.tree().parent();
dbates@webkit.org1e858552018-06-30 02:11:01 +00002928 if (!ownerFrame && m_stateMachine.isDisplayingInitialEmptyDocument())
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002929 ownerFrame = m_opener;
2930 if (ownerFrame)
2931 initiator = ownerFrame->document();
2932 ASSERT(ownerFrame || m_frame.isMainFrame());
2933 }
2934 addSameSiteInfoToRequestIfNeeded(request, initiator);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002935 }
dbates@webkit.org2dc5b0d2019-02-21 23:54:40 +00002936 request.setIsTopSite(isMainFrameMainResource);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002937
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002938 Page* page = frame().page();
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002939 bool hasSpecificCachePolicy = request.cachePolicy() != ResourceRequestCachePolicy::UseProtocolCachePolicy;
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002940
cdumez@apple.coma231c912019-10-16 18:24:25 +00002941 if (page && page->isResourceCachingDisabledByWebInspector()) {
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002942 request.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002943 loadType = FrameLoadType::ReloadFromOrigin;
2944 } else if (!hasSpecificCachePolicy)
2945 request.setCachePolicy(defaultRequestCachingPolicy(request, loadType, isMainResource));
ap@apple.com8d5f01b2013-01-07 18:40:55 +00002946
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002947 // The remaining modifications are only necessary for HTTP and HTTPS.
2948 if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
2949 return;
antti@apple.com7c97e2c2015-03-19 05:21:40 +00002950
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002951 if (!hasSpecificCachePolicy && request.cachePolicy() == ResourceRequestCachePolicy::ReloadIgnoringCacheData) {
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002952 if (loadType == FrameLoadType::Reload)
commit-queue@webkit.orgf1fbce62020-01-01 11:25:53 +00002953 request.setHTTPHeaderField(HTTPHeaderName::CacheControl, HTTPHeaderValues::maxAge0());
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002954 else if (loadType == FrameLoadType::ReloadFromOrigin) {
commit-queue@webkit.orgf1fbce62020-01-01 11:25:53 +00002955 request.setHTTPHeaderField(HTTPHeaderName::CacheControl, HTTPHeaderValues::noCache());
2956 request.setHTTPHeaderField(HTTPHeaderName::Pragma, HTTPHeaderValues::noCache());
japhet@chromium.org1e313142010-08-31 22:53:31 +00002957 }
2958 }
darin@apple.com0fdefc32016-03-18 07:56:20 +00002959
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002960 if (m_overrideResourceLoadPriorityForTesting)
2961 request.setPriority(m_overrideResourceLoadPriorityForTesting.value());
2962
ap@apple.com9454f7c2013-06-20 20:06:02 +00002963 // Only set fallback array if it's still empty (later attempts may be incorrect, see bug 117818).
2964 if (request.responseContentDispositionEncodingFallbackArray().isEmpty()) {
2965 // Always try UTF-8. If that fails, try frame encoding (if any) and then the default.
akling@apple.com7f50aae2013-08-22 16:01:31 +00002966 request.setResponseContentDispositionEncodingFallbackArray("UTF-8", m_frame.document()->encoding(), m_frame.settings().defaultTextEncodingName());
ap@apple.com9454f7c2013-06-20 20:06:02 +00002967 }
abarth@webkit.orgfb074382008-10-05 19:12:30 +00002968}
2969
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002970// Implements the "'Same-site' and 'cross-site' Requests" algorithm from <https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-2.1>.
2971// The algorithm is ammended to treat URLs that inherit their security origin from their owner (e.g. about:blank)
2972// as same-site. This matches the behavior of Chrome and Firefox.
2973void FrameLoader::addSameSiteInfoToRequestIfNeeded(ResourceRequest& request, const Document* initiator)
2974{
2975 if (!request.isSameSiteUnspecified())
2976 return;
2977 if (!initiator) {
2978 request.setIsSameSite(true);
2979 return;
2980 }
2981 if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(request.url())) {
2982 request.setIsSameSite(true);
2983 return;
2984 }
cdumez@apple.com0b8674fb2019-03-13 19:53:41 +00002985 request.setIsSameSite(areRegistrableDomainsEqual(initiator->siteForCookies(), request.url()));
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002986}
2987
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00002988void FrameLoader::loadPostRequest(FrameLoadRequest&& request, const String& referrer, FrameLoadType loadType, Event* event, RefPtr<FormState>&& formState, CompletionHandler<void()>&& completionHandler)
anderscade5715d2007-01-06 00:55:49 +00002989{
krollin@apple.combdeaed72020-01-08 01:31:20 +00002990 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadPostRequest: frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00002991
beidson@apple.combd66a782015-05-29 16:31:49 +00002992 String frameName = request.frameName();
2993 LockHistory lockHistory = request.lockHistory();
2994 AllowNavigationToInvalidURL allowNavigationToInvalidURL = request.allowNavigationToInvalidURL();
2995 NewFrameOpenerPolicy openerPolicy = request.newFrameOpenerPolicy();
2996
2997 const ResourceRequest& inRequest = request.resourceRequest();
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00002998 const URL& url = inRequest.url();
mrowe@apple.com713db2e2008-07-27 03:49:29 +00002999 const String& contentType = inRequest.httpContentType();
abarth@webkit.orgfb074382008-10-05 19:12:30 +00003000 String origin = inRequest.httpOrigin();
mrowe@apple.com713db2e2008-07-27 03:49:29 +00003001
3002 ResourceRequest workingResourceRequest(url);
anderscade5715d2007-01-06 00:55:49 +00003003
3004 if (!referrer.isEmpty())
mrowe@apple.com713db2e2008-07-27 03:49:29 +00003005 workingResourceRequest.setHTTPReferrer(referrer);
abarth@webkit.orgfb074382008-10-05 19:12:30 +00003006 workingResourceRequest.setHTTPOrigin(origin);
mrowe@apple.com713db2e2008-07-27 03:49:29 +00003007 workingResourceRequest.setHTTPMethod("POST");
youenn.fablet@crf.canon.fr11cc6552016-01-22 14:51:16 +00003008 workingResourceRequest.setHTTPBody(inRequest.httpBody());
mrowe@apple.com713db2e2008-07-27 03:49:29 +00003009 workingResourceRequest.setHTTPContentType(contentType);
commit-queue@webkit.org627a2de2020-04-13 08:04:39 +00003010 addExtraFieldsToRequest(workingResourceRequest, IsMainResource::Yes, loadType);
anderscade5715d2007-01-06 00:55:49 +00003011
bfulgham@apple.comb30d7f82016-06-07 15:47:30 +00003012 if (Document* document = m_frame.document())
3013 document->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(workingResourceRequest, ContentSecurityPolicy::InsecureRequestType::Load);
3014
dbates@webkit.org9692a072017-07-12 18:01:19 +00003015 NavigationAction action { request.requester(), workingResourceRequest, request.initiatedByMainFrame(), loadType, true, event, request.shouldOpenExternalURLsPolicy(), request.downloadAttribute() };
commit-queue@webkit.org4a7ad282020-04-05 05:09:42 +00003016 action.setLockHistory(lockHistory);
anderscade5715d2007-01-06 00:55:49 +00003017
anderscade5715d2007-01-06 00:55:49 +00003018 if (!frameName.isEmpty()) {
darin@apple.com0f88bda2009-04-02 00:30:50 +00003019 // The search for a target frame is done earlier in the case of form submission.
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00003020 if (auto* targetFrame = formState ? nullptr : findFrameForNavigation(frameName)) {
commit-queue@webkit.org4a7ad282020-04-05 05:09:42 +00003021 targetFrame->loader().loadWithNavigationAction(workingResourceRequest, WTFMove(action), loadType, WTFMove(formState), allowNavigationToInvalidURL, { }, WTFMove(completionHandler));
andersca@apple.com096333f2013-11-07 21:37:36 +00003022 return;
darin@chromium.org1e25ab72012-04-02 20:14:07 +00003023 }
andersca@apple.com096333f2013-11-07 21:37:36 +00003024
commit-queue@webkit.orge051df22020-01-01 02:27:01 +00003025 policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(workingResourceRequest), WTFMove(formState), frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = WTFMove(completionHandler)] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, PolicyChecker::ShouldContinue shouldContinue) mutable {
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00003026 continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
cdumez@apple.comb76757c2018-03-06 22:01:27 +00003027 completionHandler();
andersca@apple.com096333f2013-11-07 21:37:36 +00003028 });
3029 return;
3030 }
3031
3032 // must grab this now, since this load may stop the previous load and clear this flag
3033 bool isRedirect = m_quickRedirectComing;
commit-queue@webkit.org4a7ad282020-04-05 05:09:42 +00003034 loadWithNavigationAction(workingResourceRequest, WTFMove(action), loadType, WTFMove(formState), allowNavigationToInvalidURL, { }, [this, isRedirect, protectedFrame = makeRef(m_frame), completionHandler = WTFMove(completionHandler)] () mutable {
cdumez@apple.comb76757c2018-03-06 22:01:27 +00003035 if (isRedirect) {
3036 m_quickRedirectComing = false;
3037 if (m_provisionalDocumentLoader)
3038 m_provisionalDocumentLoader->setIsClientRedirect(true);
3039 else if (m_policyDocumentLoader)
3040 m_policyDocumentLoader->setIsClientRedirect(true);
3041 }
3042 completionHandler();
3043 });
anderscade5715d2007-01-06 00:55:49 +00003044}
3045
youenn@apple.comb9709cc2018-04-16 21:50:26 +00003046unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& request, ClientCredentialPolicy clientCredentialPolicy, const FetchOptions& options, const HTTPHeaderMap& originalRequestHeaders, ResourceError& error, ResourceResponse& response, RefPtr<SharedBuffer>& data)
anderscade5715d2007-01-06 00:55:49 +00003047{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003048 ASSERT(m_frame.document());
3049 String referrer = SecurityPolicy::generateReferrerHeader(m_frame.document()->referrerPolicy(), request.url(), outgoingReferrer());
anderscade5715d2007-01-06 00:55:49 +00003050
3051 ResourceRequest initialRequest = request;
3052 initialRequest.setTimeoutInterval(10);
3053
anderscade5715d2007-01-06 00:55:49 +00003054 if (!referrer.isEmpty())
3055 initialRequest.setHTTPReferrer(referrer);
commit-queue@webkit.org1ae32ff2020-03-26 07:38:24 +00003056 if (doesRequestNeedHTTPOriginHeader(initialRequest)) {
3057 auto origin = SecurityPolicy::generateOriginHeader(m_frame.document()->referrerPolicy(), initialRequest.url(), m_frame.document()->securityOrigin());
3058 initialRequest.setHTTPOrigin(origin);
3059 }
darine0cef432007-07-10 19:21:23 +00003060
darin@apple.com0e83ab12013-09-28 17:19:04 +00003061 initialRequest.setFirstPartyForCookies(m_frame.mainFrame().loader().documentLoader()->request().url());
japhet@chromium.org92a952b2010-07-12 18:14:17 +00003062
commit-queue@webkit.org627a2de2020-04-13 08:04:39 +00003063 addExtraFieldsToRequest(initialRequest, IsMainResource::No);
darine0cef432007-07-10 19:21:23 +00003064
commit-queue@webkit.org84a72092020-04-23 20:37:54 +00003065 applyUserAgentIfNeeded(initialRequest);
3066
anderscaec429f52007-01-13 01:44:24 +00003067 unsigned long identifier = 0;
anderscade5715d2007-01-06 00:55:49 +00003068 ResourceRequest newRequest(initialRequest);
3069 requestFromDelegate(newRequest, identifier, error);
3070
beidson@apple.come3ea01d2015-07-02 18:33:23 +00003071#if ENABLE(CONTENT_EXTENSIONS)
3072 if (error.isNull()) {
commit-queue@webkit.org8090ccb2015-10-06 08:18:08 +00003073 if (auto* page = m_frame.page()) {
commit-queue@webkit.org3d339842016-08-04 18:07:45 +00003074 if (m_documentLoader) {
achristensen@apple.comb80d3422019-04-26 17:03:15 +00003075 auto results = page->userContentProvider().processContentRuleListsForLoad(newRequest.url(), ContentExtensions::ResourceType::Raw, *m_documentLoader);
achristensen@apple.comd3edc2a2019-03-21 20:23:46 +00003076 bool blockedLoad = results.summary.blockedLoad;
3077 ContentExtensions::applyResultsToRequest(WTFMove(results), page, newRequest);
3078 if (blockedLoad) {
commit-queue@webkit.org3d339842016-08-04 18:07:45 +00003079 newRequest = { };
3080 error = ResourceError(errorDomainWebKitInternal, 0, initialRequest.url(), emptyString());
3081 response = { };
3082 data = nullptr;
3083 }
beidson@apple.come3ea01d2015-07-02 18:33:23 +00003084 }
3085 }
beidson@apple.come3ea01d2015-07-02 18:33:23 +00003086 }
3087#endif
3088
bfulgham@apple.comb30d7f82016-06-07 15:47:30 +00003089 m_frame.document()->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(newRequest, ContentSecurityPolicy::InsecureRequestType::Load);
3090
anderscade5715d2007-01-06 00:55:49 +00003091 if (error.isNull()) {
3092 ASSERT(!newRequest.isNull());
youenn.fablet@crf.canon.fr0aef67f2015-04-29 08:18:10 +00003093
darin@apple.comc04189e2017-01-18 05:17:17 +00003094 if (!documentLoader()->applicationCacheHost().maybeLoadSynchronously(newRequest, error, response, data)) {
youenn.fablet@crf.canon.fr0aef67f2015-04-29 08:18:10 +00003095 Vector<char> buffer;
youenn@apple.comb9709cc2018-04-16 21:50:26 +00003096 platformStrategies()->loaderStrategy()->loadResourceSynchronously(*this, identifier, newRequest, clientCredentialPolicy, options, originalRequestHeaders, error, response, buffer);
commit-queue@webkit.org08f38b92017-04-12 09:25:04 +00003097 data = SharedBuffer::create(WTFMove(buffer));
darin@apple.comc04189e2017-01-18 05:17:17 +00003098 documentLoader()->applicationCacheHost().maybeLoadFallbackSynchronously(newRequest, error, response, data);
wilander@apple.coma4d606a2019-11-19 20:35:21 +00003099 ResourceLoadObserver::shared().logSubresourceLoading(&m_frame, newRequest, response,
3100 (isScriptLikeDestination(options.destination) ? ResourceLoadObserver::FetchDestinationIsScriptLike::Yes : ResourceLoadObserver::FetchDestinationIsScriptLike::No));
ap@webkit.orgfb96f8a2009-01-02 09:25:02 +00003101 }
anderscade5715d2007-01-06 00:55:49 +00003102 }
youenn.fablet@crf.canon.fr0aef67f2015-04-29 08:18:10 +00003103 notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, response, data ? data->data() : nullptr, data ? data->size() : 0, -1, error);
kmccullough@apple.com2a4950c2008-03-28 23:28:56 +00003104 return identifier;
anderscade5715d2007-01-06 00:55:49 +00003105}
3106
anderscade5715d2007-01-06 00:55:49 +00003107const ResourceRequest& FrameLoader::originalRequest() const
3108{
3109 return activeDocumentLoader()->originalRequestCopy();
3110}
3111
japhet@chromium.org7f7bee42012-03-29 23:17:09 +00003112void FrameLoader::receivedMainResourceError(const ResourceError& error)
anderscade5715d2007-01-06 00:55:49 +00003113{
3114 // Retain because the stop may release the last reference to it.
akling@apple.comf8515982013-09-02 18:50:01 +00003115 Ref<Frame> protect(m_frame);
anderscade5715d2007-01-06 00:55:49 +00003116
3117 RefPtr<DocumentLoader> loader = activeDocumentLoader();
japhet@chromium.org7f7bee42012-03-29 23:17:09 +00003118 // FIXME: Don't want to do this if an entirely new load is going, so should check
3119 // that both data sources on the frame are either this or nil.
3120 stop();
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003121 if (m_client->shouldFallBack(error))
japhet@chromium.org7f7bee42012-03-29 23:17:09 +00003122 handleFallbackContent();
abarth@webkit.org1c893f42009-10-10 02:27:21 +00003123
lars8bf288d2007-10-04 08:45:12 +00003124 if (m_state == FrameStateProvisional && m_provisionalDocumentLoader) {
darin@apple.com4cd1b242009-03-27 23:37:46 +00003125 if (m_submittedFormURL == m_provisionalDocumentLoader->originalRequestCopy().url())
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003126 m_submittedFormURL = URL();
anttiac25cb42007-03-02 07:59:15 +00003127
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003128 // We might have made a back/forward cache item, but now we're bailing out due to an error before we ever
anderscade5715d2007-01-06 00:55:49 +00003129 // transitioned to the new page (before WebFrameState == commit). The goal here is to restore any state
3130 // so that the existing view (that wenever got far enough to replace) can continue being used.
akling@apple.com672cb852013-08-22 20:27:27 +00003131 history().invalidateCurrentItemCachedPage();
anderscade5715d2007-01-06 00:55:49 +00003132
3133 // Call clientRedirectCancelledOrFinished here so that the frame load delegate is notified that the redirect's
3134 // status has changed, if there was a redirect. The frame load delegate may have saved some state about
3135 // the redirect in its -webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:. Since we are definitely
3136 // not going to use this provisional resource, as it was cancelled, notify the frame load delegate that the redirect
3137 // has ended.
3138 if (m_sentRedirectNotification)
achristensen@apple.com6fddc912018-10-18 21:16:52 +00003139 clientRedirectCancelledOrFinished(NewLoadInProgress::No);
anderscade5715d2007-01-06 00:55:49 +00003140 }
abarth@webkit.org1c893f42009-10-10 02:27:21 +00003141
japhet@chromium.org7f7bee42012-03-29 23:17:09 +00003142 checkCompleted();
akling@apple.com7f50aae2013-08-22 16:01:31 +00003143 if (m_frame.page())
japhet@chromium.org7f7bee42012-03-29 23:17:09 +00003144 checkLoadComplete();
anderscade5715d2007-01-06 00:55:49 +00003145}
3146
anderscade5715d2007-01-06 00:55:49 +00003147void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue)
3148{
anderscade5715d2007-01-06 00:55:49 +00003149 m_quickRedirectComing = false;
darin4e5519d2007-01-22 02:46:06 +00003150
3151 if (!shouldContinue)
3152 return;
3153
bfulgham@apple.com98845d92016-05-17 01:09:27 +00003154 // Calling stopLoading() on the provisional document loader can cause the underlying
3155 // frame to be deallocated.
3156 Ref<Frame> protectedFrame(m_frame);
3157
mihaip@chromium.orgd5123ba2011-09-16 02:16:46 +00003158 // If we have a provisional request for a different document, a fragment scroll should cancel it.
3159 if (m_provisionalDocumentLoader && !equalIgnoringFragmentIdentifier(m_provisionalDocumentLoader->request().url(), request.url())) {
3160 m_provisionalDocumentLoader->stopLoading();
krollin@apple.combdeaed72020-01-08 01:31:20 +00003161 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "continueFragmentScrollAfterNavigationPolicy: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00003162 setProvisionalDocumentLoader(nullptr);
mihaip@chromium.orgd5123ba2011-09-16 02:16:46 +00003163 }
3164
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003165 bool isRedirect = m_quickRedirectComing || policyChecker().loadType() == FrameLoadType::RedirectWithLockedBackForwardList;
beidson@apple.com08c61752009-12-03 19:04:40 +00003166 loadInSameDocument(request.url(), 0, !isRedirect);
anderscade5715d2007-01-06 00:55:49 +00003167}
3168
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003169bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType loadType, const URL& url)
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00003170{
yael.aharon@nokia.com79f69052010-12-30 19:31:00 +00003171 // We don't do this if we are submitting a form with method other than "GET", explicitly reloading,
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00003172 // currently displaying a frameset, or if the URL does not have a fragment.
3173 // These rules were originally based on what KHTML was doing in KHTMLPart::openURL.
3174
3175 // FIXME: What about load types other than Standard and Reload?
3176
darin@apple.com048cc3a2016-01-22 17:17:04 +00003177 return (!isFormSubmission || equalLettersIgnoringASCIICase(httpMethod, "get"))
antti@apple.com5d0c5402017-03-17 19:52:49 +00003178 && !isReload(loadType)
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003179 && loadType != FrameLoadType::Same
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003180 && m_frame.document()->backForwardCacheState() != Document::InBackForwardCache
akling@apple.com7f50aae2013-08-22 16:01:31 +00003181 && !shouldReload(m_frame.document()->url(), url)
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00003182 // We don't want to just scroll if a link from within a
3183 // frameset is trying to reload the frameset into _top.
akling@apple.com7f50aae2013-08-22 16:01:31 +00003184 && !m_frame.document()->isFrameSet();
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00003185}
3186
simon.fraser@apple.comc79e4862017-03-08 20:01:15 +00003187static bool itemAllowsScrollRestoration(HistoryItem* historyItem)
3188{
simon.fraser@apple.com804555f2017-11-29 20:41:47 +00003189 return !historyItem || historyItem->shouldRestoreScrollPosition();
simon.fraser@apple.comc79e4862017-03-08 20:01:15 +00003190}
3191
3192static bool isSameDocumentReload(bool isNewNavigation, FrameLoadType loadType)
3193{
3194 return !isNewNavigation && !isBackForwardLoadType(loadType);
3195}
3196
3197void FrameLoader::scrollToFragmentWithParentBoundary(const URL& url, bool isNewNavigation)
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00003198{
rniwa@webkit.org892a3762019-11-22 05:09:36 +00003199 auto view = makeRefPtr(m_frame.view());
3200 auto document = makeRefPtr(m_frame.document());
3201 if (!view || !document)
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00003202 return;
3203
rniwa@webkit.org892a3762019-11-22 05:09:36 +00003204 if (isSameDocumentReload(isNewNavigation, m_loadType) || itemAllowsScrollRestoration(history().currentItem())) {
3205 // https://html.spec.whatwg.org/multipage/browsing-the-web.html#try-to-scroll-to-the-fragment
3206 if (!document->haveStylesheetsLoaded())
3207 document->setGotoAnchorNeededAfterStylesheetsLoad(true);
3208 else
3209 view->scrollToFragment(url);
3210 }
3211
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00003212}
3213
beidson@apple.com7617ce72010-05-13 20:31:46 +00003214bool FrameLoader::shouldClose()
3215{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003216 Page* page = m_frame.page();
akling@apple.combd774812013-05-17 00:03:01 +00003217 if (!page)
3218 return true;
3219 if (!page->chrome().canRunBeforeUnloadConfirmPanel())
beidson@apple.com7617ce72010-05-13 20:31:46 +00003220 return true;
3221
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003222 // Store all references to each subframe in advance since beforeunload's event handler may modify frame
akling@apple.com72c1c362013-09-06 01:34:05 +00003223 Vector<Ref<Frame>, 16> targetFrames;
3224 targetFrames.append(m_frame);
darin@apple.comfed4d162013-08-25 02:28:06 +00003225 for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().traverseNext(&m_frame))
akling@apple.com72c1c362013-09-06 01:34:05 +00003226 targetFrames.append(*child);
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003227
3228 bool shouldClose = false;
3229 {
rniwa@webkit.orgf694bd62017-06-30 19:32:41 +00003230 NavigationDisabler navigationDisabler(&m_frame);
cdumez@apple.come4df29d2018-09-26 19:29:54 +00003231 IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003232 size_t i;
3233
3234 for (i = 0; i < targetFrames.size(); i++) {
darin@apple.comfed4d162013-08-25 02:28:06 +00003235 if (!targetFrames[i]->tree().isDescendantOf(&m_frame))
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003236 continue;
ggaren@apple.com7a176e12015-11-12 01:48:27 +00003237 if (!targetFrames[i]->loader().dispatchBeforeUnloadEvent(page->chrome(), this))
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003238 break;
3239 }
3240
3241 if (i == targetFrames.size())
3242 shouldClose = true;
3243 }
3244
aestes@apple.comc7f17612011-08-12 19:56:56 +00003245 if (!shouldClose)
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003246 m_submittedFormURL = URL();
aestes@apple.comc7f17612011-08-12 19:56:56 +00003247
beidson@apple.com1390a812013-07-20 06:43:51 +00003248 m_currentNavigationHasShownBeforeUnloadConfirmPanel = false;
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003249 return shouldClose;
3250}
3251
ggaren@apple.com7a176e12015-11-12 01:48:27 +00003252void FrameLoader::dispatchUnloadEvents(UnloadEventPolicy unloadEventPolicy)
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003253{
3254 if (!m_frame.document())
3255 return;
3256
ajuma@chromium.orgedd75742019-09-11 14:52:18 +00003257 if (m_pageDismissalEventBeingDispatched != PageDismissalType::None)
3258 return;
3259
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003260 // We store the frame's page in a local variable because the frame might get detached inside dispatchEvent.
3261 ForbidPromptsScope forbidPrompts(m_frame.page());
cdumez@apple.comfc8fdf32019-12-06 21:05:12 +00003262 ForbidSynchronousLoadsScope forbidSynchronousLoads(m_frame.page());
cdumez@apple.com8b478c62016-01-23 01:04:59 +00003263 IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003264
3265 if (m_didCallImplicitClose && !m_wasUnloadEventEmitted) {
3266 auto* currentFocusedElement = m_frame.document()->focusedElement();
3267 if (is<HTMLInputElement>(currentFocusedElement))
3268 downcast<HTMLInputElement>(*currentFocusedElement).endEditing();
3269 if (m_pageDismissalEventBeingDispatched == PageDismissalType::None) {
3270 if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) {
3271 m_pageDismissalEventBeingDispatched = PageDismissalType::PageHide;
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003272 m_frame.document()->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame.document()->backForwardCacheState() == Document::AboutToEnterBackForwardCache), m_frame.document());
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003273 }
3274
3275 // FIXME: update Page Visibility state here.
3276 // https://bugs.webkit.org/show_bug.cgi?id=116770
3277
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003278 if (m_frame.document()->backForwardCacheState() == Document::NotInBackForwardCache) {
rniwa@webkit.org6c403742018-08-17 21:24:40 +00003279 Ref<Event> unloadEvent(Event::create(eventNames().unloadEvent, Event::CanBubble::No, Event::IsCancelable::No));
commit-queue@webkit.org3eeac492016-08-12 22:53:27 +00003280 // The DocumentLoader (and thus its LoadTiming) might get destroyed
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003281 // while dispatching the event, so protect it to prevent writing the end
3282 // time into freed memory.
3283 RefPtr<DocumentLoader> documentLoader = m_provisionalDocumentLoader;
3284 m_pageDismissalEventBeingDispatched = PageDismissalType::Unload;
commit-queue@webkit.org3eeac492016-08-12 22:53:27 +00003285 if (documentLoader && documentLoader->timing().startTime() && !documentLoader->timing().unloadEventStart() && !documentLoader->timing().unloadEventEnd()) {
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003286 auto& timing = documentLoader->timing();
3287 timing.markUnloadEventStart();
3288 m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
3289 timing.markUnloadEventEnd();
3290 } else
3291 m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
3292 }
3293 }
3294 m_pageDismissalEventBeingDispatched = PageDismissalType::None;
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003295 m_wasUnloadEventEmitted = true;
3296 }
3297
3298 // Dispatching the unload event could have made m_frame.document() null.
3299 if (!m_frame.document())
3300 return;
3301
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003302 if (m_frame.document()->backForwardCacheState() != Document::NotInBackForwardCache)
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003303 return;
3304
3305 // Don't remove event listeners from a transitional empty document (see bug 28716 for more information).
3306 bool keepEventListeners = m_stateMachine.isDisplayingInitialEmptyDocument() && m_provisionalDocumentLoader
3307 && m_frame.document()->isSecureTransitionTo(m_provisionalDocumentLoader->url());
3308
3309 if (!keepEventListeners)
3310 m_frame.document()->removeAllEventListeners();
3311}
3312
cdumez@apple.com6473cc42017-03-22 21:14:23 +00003313static bool shouldAskForNavigationConfirmation(Document& document, const BeforeUnloadEvent& event)
cdumez@apple.com60045462017-02-20 06:36:04 +00003314{
fred.wang@free.frd6e82742017-08-25 17:28:53 +00003315 // Confirmation dialog should not be displayed when the allow-modals flag is not set.
3316 if (document.isSandboxed(SandboxModals))
3317 return false;
3318
cdumez@apple.com72d8e4b2017-04-17 00:56:47 +00003319 bool userDidInteractWithPage = document.topDocument().userDidInteractWithPage();
cdumez@apple.com60045462017-02-20 06:36:04 +00003320 // Web pages can request we ask for confirmation before navigating by:
3321 // - Cancelling the BeforeUnloadEvent (modern way)
3322 // - Setting the returnValue attribute on the BeforeUnloadEvent to a non-empty string.
3323 // - Returning a non-empty string from the event handler, which is then set as returnValue
3324 // attribute on the BeforeUnloadEvent.
cdumez@apple.com6473cc42017-03-22 21:14:23 +00003325 return userDidInteractWithPage && (event.defaultPrevented() || !event.returnValue().isEmpty());
cdumez@apple.com60045462017-02-20 06:36:04 +00003326}
3327
ggaren@apple.com7a176e12015-11-12 01:48:27 +00003328bool FrameLoader::dispatchBeforeUnloadEvent(Chrome& chrome, FrameLoader* frameLoaderBeingNavigated)
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003329{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003330 DOMWindow* domWindow = m_frame.document()->domWindow();
beidson@apple.com7617ce72010-05-13 20:31:46 +00003331 if (!domWindow)
3332 return true;
3333
akling@apple.com7f50aae2013-08-22 16:01:31 +00003334 RefPtr<Document> document = m_frame.document();
cdumez@apple.comf9780832015-01-27 00:26:21 +00003335 if (!document->bodyOrFrameset())
beidson@apple.com7617ce72010-05-13 20:31:46 +00003336 return true;
beidson@apple.com1390a812013-07-20 06:43:51 +00003337
cdumez@apple.com32216e42015-11-12 07:28:57 +00003338 Ref<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
beidson@apple.com1390a812013-07-20 06:43:51 +00003339
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003340 {
ajuma@chromium.orgedd75742019-09-11 14:52:18 +00003341 SetForScope<PageDismissalType> change(m_pageDismissalEventBeingDispatched, PageDismissalType::BeforeUnload);
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003342 ForbidPromptsScope forbidPrompts(m_frame.page());
cdumez@apple.comfc8fdf32019-12-06 21:05:12 +00003343 ForbidSynchronousLoadsScope forbidSynchronousLoads(m_frame.page());
cdumez@apple.com32216e42015-11-12 07:28:57 +00003344 domWindow->dispatchEvent(beforeUnloadEvent, domWindow->document());
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003345 }
beidson@apple.com1390a812013-07-20 06:43:51 +00003346
beidson@apple.com7617ce72010-05-13 20:31:46 +00003347 if (!beforeUnloadEvent->defaultPrevented())
akling@apple.come8090dd2016-08-31 16:32:44 +00003348 document->defaultEventHandler(beforeUnloadEvent.get());
cdumez@apple.com60045462017-02-20 06:36:04 +00003349
cdumez@apple.com6473cc42017-03-22 21:14:23 +00003350 if (!shouldAskForNavigationConfirmation(*document, beforeUnloadEvent))
beidson@apple.com7617ce72010-05-13 20:31:46 +00003351 return true;
3352
beidson@apple.com1390a812013-07-20 06:43:51 +00003353 // If the navigating FrameLoader has already shown a beforeunload confirmation panel for the current navigation attempt,
3354 // this frame is not allowed to cause another one to be shown.
3355 if (frameLoaderBeingNavigated->m_currentNavigationHasShownBeforeUnloadConfirmPanel) {
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00003356 document->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "Blocked attempt to show multiple beforeunload confirmation dialogs for the same navigation."_s);
beidson@apple.com1390a812013-07-20 06:43:51 +00003357 return true;
3358 }
3359
3360 // We should only display the beforeunload dialog for an iframe if its SecurityOrigin matches all
3361 // ancestor frame SecurityOrigins up through the navigating FrameLoader.
3362 if (frameLoaderBeingNavigated != this) {
darin@apple.comfed4d162013-08-25 02:28:06 +00003363 Frame* parentFrame = m_frame.tree().parent();
beidson@apple.com1390a812013-07-20 06:43:51 +00003364 while (parentFrame) {
3365 Document* parentDocument = parentFrame->document();
3366 if (!parentDocument)
3367 return true;
akling@apple.com6be0e972017-01-18 19:35:49 +00003368 if (!m_frame.document() || !m_frame.document()->securityOrigin().canAccess(parentDocument->securityOrigin())) {
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00003369 document->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "Blocked attempt to show beforeunload confirmation dialog on behalf of a frame with different security origin. Protocols, domains, and ports must match."_s);
beidson@apple.com1390a812013-07-20 06:43:51 +00003370 return true;
3371 }
3372
andersca@apple.comdf550b92013-08-15 22:17:17 +00003373 if (&parentFrame->loader() == frameLoaderBeingNavigated)
beidson@apple.com1390a812013-07-20 06:43:51 +00003374 break;
3375
darin@apple.comfed4d162013-08-25 02:28:06 +00003376 parentFrame = parentFrame->tree().parent();
beidson@apple.com1390a812013-07-20 06:43:51 +00003377 }
3378
3379 // The navigatingFrameLoader should always be in our ancestory.
3380 ASSERT(parentFrame);
andersca@apple.comdf550b92013-08-15 22:17:17 +00003381 ASSERT(&parentFrame->loader() == frameLoaderBeingNavigated);
beidson@apple.com1390a812013-07-20 06:43:51 +00003382 }
3383
3384 frameLoaderBeingNavigated->m_currentNavigationHasShownBeforeUnloadConfirmPanel = true;
3385
ch.dumez@sisa.samsung.com231386f2013-09-09 18:40:04 +00003386 String text = document->displayStringModifiedByEncoding(beforeUnloadEvent->returnValue());
darin@apple.com9ace8012017-01-23 06:24:18 +00003387 return chrome.runBeforeUnloadConfirmPanel(text, m_frame);
beidson@apple.com7617ce72010-05-13 20:31:46 +00003388}
3389
cdumez@apple.com2e665842019-02-01 22:52:58 +00003390void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest& request, FormState* formState, NavigationPolicyDecision navigationPolicyDecision, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
anderscade5715d2007-01-06 00:55:49 +00003391{
3392 // If we loaded an alternate page to replace an unreachableURL, we'll get in here with a
3393 // nil policyDataSource because loading the alternate page will have passed
3394 // through this method already, nested; otherwise, policyDataSource should still be set.
3395 ASSERT(m_policyDocumentLoader || !m_provisionalDocumentLoader->unreachableURL().isEmpty());
3396
akling@apple.com672cb852013-08-22 20:27:27 +00003397 bool isTargetItem = history().provisionalItem() ? history().provisionalItem()->isTargetItem() : false;
anderscade5715d2007-01-06 00:55:49 +00003398
aestes@apple.com47ac5e12014-08-18 17:48:48 +00003399 bool urlIsDisallowed = allowNavigationToInvalidURL == AllowNavigationToInvalidURL::No && !request.url().isValid();
cdumez@apple.com2e665842019-02-01 22:52:58 +00003400 bool canContinue = navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad && shouldClose() && !urlIsDisallowed;
anderscade5715d2007-01-06 00:55:49 +00003401
3402 if (!canContinue) {
krollin@apple.combdeaed72020-01-08 01:31:20 +00003403 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "continueLoadAfterNavigationPolicy: can't continue loading frame due to the following reasons ("
krollin@apple.come1810b62018-12-20 19:23:20 +00003404 "allowNavigationToInvalidURL = %d, "
3405 "requestURLIsValid = %d, "
cdumez@apple.com2e665842019-02-01 22:52:58 +00003406 "navigationPolicyDecision = %d)",
krollin@apple.come1810b62018-12-20 19:23:20 +00003407 static_cast<int>(allowNavigationToInvalidURL),
3408 request.url().isValid(),
cdumez@apple.com2e665842019-02-01 22:52:58 +00003409 static_cast<int>(navigationPolicyDecision));
krollin@apple.come1810b62018-12-20 19:23:20 +00003410
anderscade5715d2007-01-06 00:55:49 +00003411 // If we were waiting for a quick redirect, but the policy delegate decided to ignore it, then we
3412 // need to report that the client redirect was cancelled.
aestes@apple.com47ac5e12014-08-18 17:48:48 +00003413 // FIXME: The client should be told about ignored non-quick redirects, too.
anderscade5715d2007-01-06 00:55:49 +00003414 if (m_quickRedirectComing)
achristensen@apple.com6fddc912018-10-18 21:16:52 +00003415 clientRedirectCancelledOrFinished(NewLoadInProgress::No);
anderscade5715d2007-01-06 00:55:49 +00003416
cdumez@apple.com2e665842019-02-01 22:52:58 +00003417 if (navigationPolicyDecision == NavigationPolicyDecision::StopAllLoads) {
3418 stopAllLoaders();
3419 m_checkTimer.stop();
3420 }
3421
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00003422 setPolicyDocumentLoader(nullptr);
cdumez@apple.comd6531852018-03-06 03:13:32 +00003423 checkCompleted();
cdumez@apple.com2e665842019-02-01 22:52:58 +00003424
3425 if (navigationPolicyDecision != NavigationPolicyDecision::StopAllLoads)
3426 checkLoadComplete();
anderscade5715d2007-01-06 00:55:49 +00003427
3428 // If the navigation request came from the back/forward menu, and we punt on it, we have the
simon.fraser@apple.comc79e4862017-03-08 20:01:15 +00003429 // problem that we have optimistically moved the b/f cursor already, so move it back. For sanity,
anderscade5715d2007-01-06 00:55:49 +00003430 // we only do this when punting a navigation for the target frame or top-level frame.
darin@apple.com0e83ab12013-09-28 17:19:04 +00003431 if ((isTargetItem || m_frame.isMainFrame()) && isBackForwardLoadType(policyChecker().loadType())) {
akling@apple.com7f50aae2013-08-22 16:01:31 +00003432 if (Page* page = m_frame.page()) {
achristensen@apple.comebfea932018-10-15 21:45:55 +00003433 if (HistoryItem* resetItem = m_frame.mainFrame().loader().history().currentItem())
achristensen@apple.com3a889f12018-10-16 15:58:10 +00003434 page->backForward().setCurrentItem(*resetItem);
darine0cef432007-07-10 19:21:23 +00003435 }
andersca@apple.comb85d6742011-03-04 03:21:07 +00003436 }
anderscade5715d2007-01-06 00:55:49 +00003437 return;
3438 }
3439
akling@apple.com24f4d6c2013-09-08 08:17:10 +00003440 FrameLoadType type = policyChecker().loadType();
commit-queue@webkit.org987fd772011-01-21 18:26:42 +00003441 // A new navigation is in progress, so don't clear the history's provisional item.
commit-queue@webkit.orgfc5833b2011-02-23 06:58:46 +00003442 stopAllLoaders(ShouldNotClearProvisionalItem);
beidson@apple.comc90a4422008-10-09 20:43:24 +00003443
3444 // <rdar://problem/6250856> - In certain circumstances on pages with multiple frames, stopAllLoaders()
3445 // might detach the current FrameLoader, in which case we should bail on this newly defunct load.
krollin@apple.come1810b62018-12-20 19:23:20 +00003446 if (!m_frame.page()) {
krollin@apple.combdeaed72020-01-08 01:31:20 +00003447 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "continueLoadAfterNavigationPolicy: can't continue loading frame because it became defunct");
beidson@apple.comc90a4422008-10-09 20:43:24 +00003448 return;
krollin@apple.come1810b62018-12-20 19:23:20 +00003449 }
timothy@apple.com8f207342009-04-11 05:31:05 +00003450
anderscade5715d2007-01-06 00:55:49 +00003451 setProvisionalDocumentLoader(m_policyDocumentLoader.get());
krollin@apple.combdeaed72020-01-08 01:31:20 +00003452 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "continueLoadAfterNavigationPolicy: Setting provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
anderscade5715d2007-01-06 00:55:49 +00003453 m_loadType = type;
3454 setState(FrameStateProvisional);
3455
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00003456 setPolicyDocumentLoader(nullptr);
anderscade5715d2007-01-06 00:55:49 +00003457
cdumez@apple.com25743772015-08-17 22:57:27 +00003458 if (isBackForwardLoadType(type)) {
cdumez@apple.com10d0f252016-04-23 21:33:49 +00003459 auto& diagnosticLoggingClient = m_frame.page()->diagnosticLoggingClient();
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003460 if (history().provisionalItem() && history().provisionalItem()->isInBackForwardCache()) {
3461 diagnosticLoggingClient.logDiagnosticMessageWithResult(DiagnosticLoggingKeys::backForwardCacheKey(), DiagnosticLoggingKeys::retrievalKey(), DiagnosticLoggingResultPass, ShouldSample::Yes);
cdumez@apple.com25743772015-08-17 22:57:27 +00003462 loadProvisionalItemFromCachedPage();
krollin@apple.combdeaed72020-01-08 01:31:20 +00003463 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "continueLoadAfterNavigationPolicy: can't continue loading frame because it will be loaded from cache");
cdumez@apple.com25743772015-08-17 22:57:27 +00003464 return;
3465 }
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003466 diagnosticLoggingClient.logDiagnosticMessageWithResult(DiagnosticLoggingKeys::backForwardCacheKey(), DiagnosticLoggingKeys::retrievalKey(), DiagnosticLoggingResultFail, ShouldSample::Yes);
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00003467 }
anderscade5715d2007-01-06 00:55:49 +00003468
cdumez@apple.coma0010ff2018-12-13 23:17:44 +00003469 CompletionHandler<void()> completionHandler = [this, protectedFrame = makeRef(m_frame)] () mutable {
krollin@apple.come1810b62018-12-20 19:23:20 +00003470 if (!m_provisionalDocumentLoader) {
krollin@apple.combdeaed72020-01-08 01:31:20 +00003471 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "continueLoadAfterNavigationPolicy (completionHandler): Frame load canceled - no provisional document loader before prepareForLoadStart");
achristensen@apple.comb2d9e112017-09-25 19:18:50 +00003472 return;
krollin@apple.come1810b62018-12-20 19:23:20 +00003473 }
achristensen@apple.comb2d9e112017-09-25 19:18:50 +00003474
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003475 prepareForLoadStart();
beidson@apple.com02622332018-04-13 18:04:22 +00003476
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003477 // The load might be cancelled inside of prepareForLoadStart(), nulling out the m_provisionalDocumentLoader,
3478 // so we need to null check it again.
3479 if (!m_provisionalDocumentLoader) {
krollin@apple.combdeaed72020-01-08 01:31:20 +00003480 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "continueLoadAfterNavigationPolicy (completionHandler): Frame load canceled - no provisional document loader after prepareForLoadStart");
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003481 return;
3482 }
3483
3484 DocumentLoader* activeDocLoader = activeDocumentLoader();
3485 if (activeDocLoader && activeDocLoader->isLoadingMainResource()) {
krollin@apple.combdeaed72020-01-08 01:31:20 +00003486 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "continueLoadAfterNavigationPolicy (completionHandler): Main frame already being loaded");
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003487 return;
3488 }
3489
3490 m_loadingFromCachedPage = false;
beidson@apple.com02622332018-04-13 18:04:22 +00003491
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003492 m_provisionalDocumentLoader->startLoadingMainResource();
achristensen@apple.comb2d9e112017-09-25 19:18:50 +00003493 };
3494
andersca@apple.com61e33322013-10-05 04:52:04 +00003495 if (!formState) {
achristensen@apple.comb2d9e112017-09-25 19:18:50 +00003496 completionHandler();
andersca@apple.com61e33322013-10-05 04:52:04 +00003497 return;
3498 }
3499
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003500 m_client->dispatchWillSubmitForm(*formState, WTFMove(completionHandler));
anderscade5715d2007-01-06 00:55:49 +00003501}
3502
anderscade5715d2007-01-06 00:55:49 +00003503void FrameLoader::continueLoadAfterNewWindowPolicy(const ResourceRequest& request,
commit-queue@webkit.orge051df22020-01-01 02:27:01 +00003504 FormState* formState, const String& frameName, const NavigationAction& action, PolicyChecker::ShouldContinue shouldContinue, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy openerPolicy)
anderscade5715d2007-01-06 00:55:49 +00003505{
commit-queue@webkit.orge051df22020-01-01 02:27:01 +00003506 if (shouldContinue != PolicyChecker::ShouldContinue::Yes)
anderscade5715d2007-01-06 00:55:49 +00003507 return;
3508
akling@apple.com55cde012013-10-05 00:35:12 +00003509 Ref<Frame> frame(m_frame);
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003510 RefPtr<Frame> mainFrame = m_client->dispatchCreatePage(action);
anderscade5715d2007-01-06 00:55:49 +00003511 if (!mainFrame)
3512 return;
3513
commit-queue@webkit.org04df8422017-06-09 17:59:18 +00003514 SandboxFlags sandboxFlags = frame->loader().effectiveSandboxFlags();
3515 if (sandboxFlags & SandboxPropagatesToAuxiliaryBrowsingContexts)
3516 mainFrame->loader().forceSandboxFlags(sandboxFlags);
wilander@apple.com2d7ea242016-08-08 21:43:36 +00003517
cdumez@apple.comeec032f2017-04-05 13:36:47 +00003518 if (!equalIgnoringASCIICase(frameName, "_blank"))
darin@apple.comfed4d162013-08-25 02:28:06 +00003519 mainFrame->tree().setName(frameName);
kmccullo1f901212007-05-16 20:57:47 +00003520
eric@webkit.org5aee6762009-10-06 18:20:33 +00003521 mainFrame->page()->setOpenedByDOM();
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003522 mainFrame->loader().m_client->dispatchShow();
ap@apple.coma383f252015-02-14 18:16:00 +00003523 if (openerPolicy == NewFrameOpenerPolicy::Allow) {
cdumez@apple.com78141732014-11-04 23:00:48 +00003524 mainFrame->loader().setOpener(frame.ptr());
jochen@chromium.org235ee972012-05-09 22:13:12 +00003525 mainFrame->document()->setReferrerPolicy(frame->document()->referrerPolicy());
3526 }
beidson@apple.com87dc6312015-06-02 18:43:13 +00003527
cdumez@apple.com548d7bb2018-10-09 18:25:29 +00003528 NavigationAction newAction { *frame->document(), request, InitiatedByMainFrame::Unknown, NavigationType::Other, action.shouldOpenExternalURLsPolicy(), nullptr, action.downloadAttribute() };
commit-queue@webkit.org4a7ad282020-04-05 05:09:42 +00003529 mainFrame->loader().loadWithNavigationAction(request, WTFMove(newAction), FrameLoadType::Standard, formState, allowNavigationToInvalidURL);
anderscade5715d2007-01-06 00:55:49 +00003530}
3531
anderscaec429f52007-01-13 01:44:24 +00003532void FrameLoader::requestFromDelegate(ResourceRequest& request, unsigned long& identifier, ResourceError& error)
anderscade5715d2007-01-06 00:55:49 +00003533{
3534 ASSERT(!request.isNull());
3535
darine0cef432007-07-10 19:21:23 +00003536 identifier = 0;
akling@apple.com7f50aae2013-08-22 16:01:31 +00003537 if (Page* page = m_frame.page()) {
akling@apple.comeb67e0a2013-08-19 08:24:08 +00003538 identifier = page->progress().createUniqueIdentifier();
akling@apple.com654fd9a2013-10-06 21:07:29 +00003539 notifier().assignIdentifierToInitialRequest(identifier, m_documentLoader.get(), request);
darine0cef432007-07-10 19:21:23 +00003540 }
anderscaec429f52007-01-13 01:44:24 +00003541
anderscade5715d2007-01-06 00:55:49 +00003542 ResourceRequest newRequest(request);
akling@apple.com654fd9a2013-10-06 21:07:29 +00003543 notifier().dispatchWillSendRequest(m_documentLoader.get(), identifier, newRequest, ResourceResponse());
anderscade5715d2007-01-06 00:55:49 +00003544
3545 if (newRequest.isNull())
weinig@apple.com87a569c2008-05-18 01:21:20 +00003546 error = cancelledError(request);
anderscade5715d2007-01-06 00:55:49 +00003547 else
3548 error = ResourceError();
3549
3550 request = newRequest;
3551}
3552
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003553void FrameLoader::loadedResourceFromMemoryCache(CachedResource& resource, ResourceRequest& newRequest, ResourceError& error)
anderscade5715d2007-01-06 00:55:49 +00003554{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003555 Page* page = m_frame.page();
darin@apple.com837a78c2009-01-07 15:40:24 +00003556 if (!page)
anderscade5715d2007-01-06 00:55:49 +00003557 return;
3558
commit-queue@webkit.org39359f02020-04-25 21:28:45 +00003559 if (!resource.shouldSendResourceLoadCallbacks() || m_documentLoader->haveToldClientAboutLoad(resource.url().string()))
darin@apple.com837a78c2009-01-07 15:40:24 +00003560 return;
3561
japhet@chromium.org3e317182013-01-29 20:06:19 +00003562 // Main resource delegate messages are synthesized in MainResourceLoader, so we must not send them here.
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00003563 if (resource.type() == CachedResource::Type::MainResource)
japhet@chromium.org3e317182013-01-29 20:06:19 +00003564 return;
3565
darin@apple.com837a78c2009-01-07 15:40:24 +00003566 if (!page->areMemoryCacheClientCallsEnabled()) {
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003567 InspectorInstrumentation::didLoadResourceFromMemoryCache(*page, m_documentLoader.get(), &resource);
3568 m_documentLoader->recordMemoryCacheLoadForFutureClientNotification(resource.resourceRequest());
commit-queue@webkit.org39359f02020-04-25 21:28:45 +00003569 m_documentLoader->didTellClientAboutLoad(resource.url().string());
darin@apple.com837a78c2009-01-07 15:40:24 +00003570 return;
3571 }
3572
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003573 if (m_client->dispatchDidLoadResourceFromMemoryCache(m_documentLoader.get(), newRequest, resource.response(), resource.encodedSize())) {
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003574 InspectorInstrumentation::didLoadResourceFromMemoryCache(*page, m_documentLoader.get(), &resource);
commit-queue@webkit.org39359f02020-04-25 21:28:45 +00003575 m_documentLoader->didTellClientAboutLoad(resource.url().string());
timothy@apple.com8f85dce2008-01-08 23:51:28 +00003576 return;
3577 }
3578
anderscaec429f52007-01-13 01:44:24 +00003579 unsigned long identifier;
aestes@apple.com0c8e1912013-04-06 03:09:25 +00003580 requestFromDelegate(newRequest, identifier, error);
joepeck@webkit.orge7d264d2017-03-09 03:35:13 +00003581
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003582 ResourceResponse response = resource.response();
joepeck@webkit.orge7d264d2017-03-09 03:35:13 +00003583 response.setSource(ResourceResponse::Source::MemoryCache);
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003584 notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, newRequest, response, 0, resource.encodedSize(), 0, error);
anderscade5715d2007-01-06 00:55:49 +00003585}
3586
Ms2ger@igalia.comc33b77c2017-11-10 16:41:03 +00003587void FrameLoader::applyUserAgentIfNeeded(ResourceRequest& request)
anderscade5715d2007-01-06 00:55:49 +00003588{
Ms2ger@igalia.comc33b77c2017-11-10 16:41:03 +00003589 if (!request.hasHTTPHeaderField(HTTPHeaderName::UserAgent)) {
3590 String userAgent = this->userAgent(request.url());
3591 ASSERT(!userAgent.isNull());
3592 request.setHTTPUserAgent(userAgent);
3593 }
anderscade5715d2007-01-06 00:55:49 +00003594}
3595
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003596bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, const URL& url, unsigned long requestIdentifier)
weinig@apple.com5af461c2009-04-08 22:16:23 +00003597{
akling@apple.com52989472013-09-16 20:09:25 +00003598 Frame& topFrame = m_frame.tree().top();
3599 if (&m_frame == &topFrame)
weinig@apple.com5af461c2009-04-08 22:16:23 +00003600 return false;
3601
mkwst@chromium.org97421c02013-03-28 08:59:00 +00003602 XFrameOptionsDisposition disposition = parseXFrameOptionsHeader(content);
3603
3604 switch (disposition) {
3605 case XFrameOptionsSameOrigin: {
yusukesuzuki@slowstart.orgae5a8bd2018-12-22 06:37:39 +00003606 auto origin = SecurityOrigin::create(url);
akling@apple.com52989472013-09-16 20:09:25 +00003607 if (!origin->isSameSchemeHostPort(topFrame.document()->securityOrigin()))
weinig@apple.com5af461c2009-04-08 22:16:23 +00003608 return true;
darin@apple.comfed4d162013-08-25 02:28:06 +00003609 for (Frame* frame = m_frame.tree().parent(); frame; frame = frame->tree().parent()) {
akling@apple.comfbea4062014-02-27 20:24:03 +00003610 if (!origin->isSameSchemeHostPort(frame->document()->securityOrigin()))
dbates@webkit.org250656a2018-05-12 04:11:16 +00003611 return true;
mkwst@chromium.orgf9d8fa02013-03-19 21:12:24 +00003612 }
mkwst@chromium.org97421c02013-03-28 08:59:00 +00003613 return false;
weinig@apple.com5af461c2009-04-08 22:16:23 +00003614 }
mkwst@chromium.org97421c02013-03-28 08:59:00 +00003615 case XFrameOptionsDeny:
3616 return true;
3617 case XFrameOptionsAllowAll:
3618 return false;
3619 case XFrameOptionsConflict:
joepeck@webkit.org1f45df92014-02-06 23:45:53 +00003620 m_frame.document()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "Multiple 'X-Frame-Options' headers with conflicting values ('" + content + "') encountered when loading '" + url.stringCenterEllipsizedToLength() + "'. Falling back to 'DENY'.", requestIdentifier);
mkwst@chromium.org97421c02013-03-28 08:59:00 +00003621 return true;
3622 case XFrameOptionsInvalid:
joepeck@webkit.org1f45df92014-02-06 23:45:53 +00003623 m_frame.document()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "Invalid 'X-Frame-Options' header encountered when loading '" + url.stringCenterEllipsizedToLength() + "': '" + content + "' is not a recognized directive. The header will be ignored.", requestIdentifier);
mkwst@chromium.org97421c02013-03-28 08:59:00 +00003624 return false;
psolanki@apple.come2dc3b92014-02-20 18:23:24 +00003625 case XFrameOptionsNone:
mkwst@chromium.org97421c02013-03-28 08:59:00 +00003626 return false;
3627 }
psolanki@apple.come2dc3b92014-02-20 18:23:24 +00003628 ASSERT_NOT_REACHED();
3629 return false;
weinig@apple.com5af461c2009-04-08 22:16:23 +00003630}
3631
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00003632void FrameLoader::loadProvisionalItemFromCachedPage()
beidson50c3bd82007-01-03 03:11:18 +00003633{
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003634 DocumentLoader* provisionalLoader = provisionalDocumentLoader();
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003635 LOG(BackForwardCache, "FrameLoader::loadProvisionalItemFromCachedPage Loading provisional DocumentLoader %p with URL '%s' from CachedPage", provisionalDocumentLoader(), provisionalDocumentLoader()->url().stringCenterEllipsizedToLength().utf8().data());
beidson@apple.comac095c02009-08-18 01:37:56 +00003636
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003637 prepareForLoadStart();
3638
3639 m_loadingFromCachedPage = true;
3640
3641 // Should have timing data from previous time(s) the page was shown.
3642 ASSERT(provisionalLoader->timing().startTime());
3643 provisionalLoader->resetTiming();
3644 provisionalLoader->timing().markStartTime();
3645
3646 provisionalLoader->setCommitted(true);
3647 commitProvisionalLoad();
beidson50c3bd82007-01-03 03:11:18 +00003648}
3649
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003650bool FrameLoader::shouldTreatURLAsSameAsCurrent(const URL& url) const
beidson50c3bd82007-01-03 03:11:18 +00003651{
akling@apple.com672cb852013-08-22 20:27:27 +00003652 if (!history().currentItem())
beidson50c3bd82007-01-03 03:11:18 +00003653 return false;
akling@apple.com672cb852013-08-22 20:27:27 +00003654 return url == history().currentItem()->url() || url == history().currentItem()->originalURL();
beidson50c3bd82007-01-03 03:11:18 +00003655}
3656
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003657bool FrameLoader::shouldTreatURLAsSrcdocDocument(const URL& url) const
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00003658{
youenn@apple.com1779d582020-03-20 17:40:44 +00003659 if (!url.isAboutSrcDoc())
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00003660 return false;
akling@apple.com7f50aae2013-08-22 16:01:31 +00003661 HTMLFrameOwnerElement* ownerElement = m_frame.ownerElement();
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00003662 if (!ownerElement)
3663 return false;
3664 if (!ownerElement->hasTagName(iframeTag))
3665 return false;
rniwa@webkit.orgbda54a02016-07-18 00:39:37 +00003666 return ownerElement->hasAttributeWithoutSynchronization(srcdocAttr);
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00003667}
3668
darin@apple.com0ce67df2019-06-17 01:48:13 +00003669Frame* FrameLoader::findFrameForNavigation(const AtomString& name, Document* activeDocument)
weinig@apple.com77427802008-01-11 00:23:13 +00003670{
ap@apple.comf8c414e2013-08-13 03:44:57 +00003671 // FIXME: Eventually all callers should supply the actual activeDocument so we can call canNavigate with the right document.
3672 if (!activeDocument)
akling@apple.com7f50aae2013-08-22 16:01:31 +00003673 activeDocument = m_frame.document();
ap@apple.comf8c414e2013-08-13 03:44:57 +00003674
cdumez@apple.com6cb3eff2018-10-15 15:34:39 +00003675 auto* frame = m_frame.tree().find(name, activeDocument->frame() ? *activeDocument->frame() : m_frame);
3676
ap@apple.comf8c414e2013-08-13 03:44:57 +00003677 if (!activeDocument->canNavigate(frame))
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003678 return nullptr;
abarth@webkit.orgb46fdef2012-04-13 00:42:37 +00003679
darin@apple.com0f88bda2009-04-02 00:30:50 +00003680 return frame;
weinig@apple.com77427802008-01-11 00:23:13 +00003681}
3682
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003683void FrameLoader::loadSameDocumentItem(HistoryItem& item)
beidson@apple.com08c61752009-12-03 19:04:40 +00003684{
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003685 ASSERT(item.documentSequenceNumber() == history().currentItem()->documentSequenceNumber());
beidson@apple.com08c61752009-12-03 19:04:40 +00003686
aestes@apple.com8303b342016-02-19 09:29:44 +00003687 Ref<Frame> protect(m_frame);
3688
beidson@apple.com08c61752009-12-03 19:04:40 +00003689 // Save user view state to the current history item here since we don't do a normal load.
3690 // FIXME: Does form state need to be saved here too?
akling@apple.com672cb852013-08-22 20:27:27 +00003691 history().saveScrollPositionAndViewStateToItem(history().currentItem());
akling@apple.com7f50aae2013-08-22 16:01:31 +00003692 if (FrameView* view = m_frame.view())
beidson@apple.com08c61752009-12-03 19:04:40 +00003693 view->setWasScrolledByUser(false);
3694
achristensen@apple.com3a889f12018-10-16 15:58:10 +00003695 history().setCurrentItem(item);
beidson@apple.com08c61752009-12-03 19:04:40 +00003696
3697 // loadInSameDocument() actually changes the URL and notifies load delegates of a "fake" load
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003698 loadInSameDocument(item.url(), item.stateObject(), false);
beidson@apple.com08c61752009-12-03 19:04:40 +00003699
3700 // Restore user view state from the current history item here since we don't do a normal load.
akling@apple.com672cb852013-08-22 20:27:27 +00003701 history().restoreScrollPositionAndViewState();
beidson@apple.com08c61752009-12-03 19:04:40 +00003702}
3703
abarth@webkit.org1c893f42009-10-10 02:27:21 +00003704// FIXME: This function should really be split into a couple pieces, some of
3705// which should be methods of HistoryController and some of which should be
3706// methods of FrameLoader.
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +00003707void FrameLoader::loadDifferentDocumentItem(HistoryItem& item, HistoryItem* fromItem, FrameLoadType loadType, FormSubmissionCacheLoadPolicy cacheLoadPolicy, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad)
beidson50c3bd82007-01-03 03:11:18 +00003708{
krollin@apple.combdeaed72020-01-08 01:31:20 +00003709 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadDifferentDocumentItem: frame load started");
krollin@apple.come1810b62018-12-20 19:23:20 +00003710
bfulgham@apple.comd0c0fc82019-05-17 16:03:36 +00003711 Ref<Frame> protectedFrame(m_frame);
3712
jiewen_tan@apple.com71ef00e2018-12-04 23:01:29 +00003713 // History items should not be reported to the parent.
3714 m_shouldReportResourceTimingToParentFrame = false;
3715
beidson@apple.com08c61752009-12-03 19:04:40 +00003716 // Remember this item so we can traverse any child items as child frames load
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003717 history().setProvisionalItem(&item);
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00003718
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00003719 auto initiatedByMainFrame = InitiatedByMainFrame::Unknown;
3720
cdumez@apple.com3aedc032019-01-31 02:23:55 +00003721 SetForScope<LoadContinuingState> continuingLoadGuard(m_currentLoadContinuingState, shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::Yes ? LoadContinuingState::ContinuingWithHistoryItem : LoadContinuingState::NotContinuing);
beidson@apple.com69caeee2018-04-20 04:55:32 +00003722
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003723 if (CachedPage* cachedPage = BackForwardCache::singleton().get(item, m_frame.page())) {
mitz@apple.com4a604422014-11-13 23:22:50 +00003724 auto documentLoader = cachedPage->documentLoader();
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003725 m_client->updateCachedDocumentLoader(*documentLoader);
beidson@apple.com07c00cf2018-05-11 16:12:11 +00003726
3727 auto action = NavigationAction { *m_frame.document(), documentLoader->request(), initiatedByMainFrame, loadType, false };
3728 action.setTargetBackForwardItem(item);
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +00003729 action.setSourceBackForwardItem(fromItem);
beidson@apple.com07c00cf2018-05-11 16:12:11 +00003730 documentLoader->setTriggeringAction(WTFMove(action));
3731
mitz@apple.com4a604422014-11-13 23:22:50 +00003732 documentLoader->setLastCheckedRequest(ResourceRequest());
commit-queue@webkit.org372c2642020-04-03 16:53:48 +00003733 loadWithDocumentLoader(documentLoader, loadType, { }, AllowNavigationToInvalidURL::Yes);
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00003734 return;
beidson@apple.com08c61752009-12-03 19:04:40 +00003735 }
adele@apple.comf3d6b892008-04-29 01:30:20 +00003736
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003737 URL itemURL = item.url();
3738 URL itemOriginalURL = item.originalURL();
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003739 URL currentURL;
beidson0c345992007-02-13 08:59:33 +00003740 if (documentLoader())
weinig@apple.comc5002662007-12-12 07:26:19 +00003741 currentURL = documentLoader()->url();
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003742 RefPtr<FormData> formData = item.formData();
beidson50c3bd82007-01-03 03:11:18 +00003743
beidson@apple.com08c61752009-12-03 19:04:40 +00003744 ResourceRequest request(itemURL);
3745
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003746 if (!item.referrer().isNull())
3747 request.setHTTPReferrer(item.referrer());
dbates@webkit.orgae34b602015-08-05 16:05:55 +00003748
dbates@webkit.org9692a072017-07-12 18:01:19 +00003749 ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(m_frame, initiatedByMainFrame, item.shouldOpenExternalURLsPolicy());
dbates@webkit.orgae34b602015-08-05 16:05:55 +00003750 bool isFormSubmission = false;
3751 Event* event = nullptr;
3752
beidson@apple.com08c61752009-12-03 19:04:40 +00003753 // If this was a repost that failed the page cache, we might try to repost the form.
3754 NavigationAction action;
3755 if (formData) {
beidson@apple.com08c61752009-12-03 19:04:40 +00003756 request.setHTTPMethod("POST");
youenn.fablet@crf.canon.fr11cc6552016-01-22 14:51:16 +00003757 request.setHTTPBody(WTFMove(formData));
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003758 request.setHTTPContentType(item.formContentType());
commit-queue@webkit.org1ae32ff2020-03-26 07:38:24 +00003759 if (doesRequestNeedHTTPOriginHeader(request)) {
3760 auto securityOrigin = SecurityOrigin::createFromString(item.referrer());
3761 auto origin = SecurityPolicy::generateOriginHeader(m_frame.document()->referrerPolicy(), request.url(), securityOrigin);
3762 request.setHTTPOrigin(origin);
3763 }
beidson@apple.com08c61752009-12-03 19:04:40 +00003764
commit-queue@webkit.org627a2de2020-04-13 08:04:39 +00003765 addExtraFieldsToRequest(request, IsMainResource::Yes, loadType);
beidson@apple.com08c61752009-12-03 19:04:40 +00003766
3767 // FIXME: Slight hack to test if the NSURL cache contains the page we're going to.
3768 // We want to know this before talking to the policy delegate, since it affects whether
3769 // we show the DoYouReallyWantToRepost nag.
3770 //
3771 // This trick has a small bug (3123893) where we might find a cache hit, but then
3772 // have the item vanish when we try to use it in the ensuing nav. This should be
3773 // extremely rare, but in that case the user will get an error on the navigation.
3774
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003775 if (cacheLoadPolicy == MayAttemptCacheOnlyLoadForFormSubmissionItem) {
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00003776 request.setCachePolicy(ResourceRequestCachePolicy::ReturnCacheDataDontLoad);
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00003777 action = { *m_frame.document(), request, initiatedByMainFrame, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy };
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003778 } else {
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00003779 request.setCachePolicy(ResourceRequestCachePolicy::ReturnCacheDataElseLoad);
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00003780 action = { *m_frame.document(), request, initiatedByMainFrame, NavigationType::FormResubmitted, shouldOpenExternalURLsPolicy, event };
beidson@apple.com08c61752009-12-03 19:04:40 +00003781 }
3782 } else {
3783 switch (loadType) {
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003784 case FrameLoadType::Reload:
commit-queue@webkit.orgea87ad82018-01-11 00:45:49 +00003785 case FrameLoadType::ReloadFromOrigin:
commit-queue@webkit.org4833ac52018-02-26 17:38:14 +00003786 case FrameLoadType::ReloadExpiredOnly:
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00003787 request.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003788 break;
3789 case FrameLoadType::Back:
3790 case FrameLoadType::Forward:
carlosgc@webkit.org2af15b72016-02-27 07:44:07 +00003791 case FrameLoadType::IndexedBackForward: {
cdumez@apple.com3e885d42016-03-15 20:01:39 +00003792#if PLATFORM(COCOA)
carlosgc@webkit.org2af15b72016-02-27 07:44:07 +00003793 bool allowStaleData = true;
3794#else
3795 bool allowStaleData = !item.wasRestoredFromSession();
3796#endif
3797 if (allowStaleData)
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00003798 request.setCachePolicy(ResourceRequestCachePolicy::ReturnCacheDataElseLoad);
carlosgc@webkit.org2af15b72016-02-27 07:44:07 +00003799 item.setWasRestoredFromSession(false);
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003800 break;
carlosgc@webkit.org2af15b72016-02-27 07:44:07 +00003801 }
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003802 case FrameLoadType::Standard:
3803 case FrameLoadType::RedirectWithLockedBackForwardList:
3804 break;
3805 case FrameLoadType::Same:
antti@apple.com5d0c5402017-03-17 19:52:49 +00003806 case FrameLoadType::Replace:
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003807 ASSERT_NOT_REACHED();
beidson@apple.com08c61752009-12-03 19:04:40 +00003808 }
3809
commit-queue@webkit.org627a2de2020-04-13 08:04:39 +00003810 addExtraFieldsToRequest(request, IsMainResource::Yes, loadType);
beidson@apple.com08c61752009-12-03 19:04:40 +00003811
jochen@chromium.org056b7fa2011-10-18 04:47:05 +00003812 ResourceRequest requestForOriginalURL(request);
3813 requestForOriginalURL.setURL(itemOriginalURL);
dbates@webkit.org9692a072017-07-12 18:01:19 +00003814 action = { *m_frame.document(), requestForOriginalURL, initiatedByMainFrame, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy };
jochen@chromium.org056b7fa2011-10-18 04:47:05 +00003815 }
3816
beidson@apple.com07c00cf2018-05-11 16:12:11 +00003817 action.setTargetBackForwardItem(item);
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +00003818 action.setSourceBackForwardItem(fromItem);
beidson@apple.com07c00cf2018-05-11 16:12:11 +00003819
commit-queue@webkit.org4a7ad282020-04-05 05:09:42 +00003820 loadWithNavigationAction(request, WTFMove(action), loadType, { }, AllowNavigationToInvalidURL::Yes);
beidson@apple.com08c61752009-12-03 19:04:40 +00003821}
3822
3823// Loads content into this frame, as specified by history item
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +00003824void FrameLoader::loadItem(HistoryItem& item, HistoryItem* fromItem, FrameLoadType loadType, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad)
beidson@apple.com08c61752009-12-03 19:04:40 +00003825{
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003826 m_requestedHistoryItem = &item;
akling@apple.com672cb852013-08-22 20:27:27 +00003827 HistoryItem* currentItem = history().currentItem();
cdumez@apple.comfea5cb92015-02-02 00:49:36 +00003828 bool sameDocumentNavigation = currentItem && item.shouldDoSameDocumentNavigationTo(*currentItem);
darin@chromium.orge71dd0f2009-04-17 20:31:17 +00003829
beidson@apple.com08c61752009-12-03 19:04:40 +00003830 if (sameDocumentNavigation)
mihaip@chromium.orge5dbd372010-12-08 02:32:41 +00003831 loadSameDocumentItem(item);
beidson@apple.com08c61752009-12-03 19:04:40 +00003832 else
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +00003833 loadDifferentDocumentItem(item, fromItem, loadType, MayAttemptCacheOnlyLoadForFormSubmissionItem, shouldTreatAsContinuingLoad);
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003834}
3835
3836void FrameLoader::retryAfterFailedCacheOnlyMainResourceLoad()
3837{
3838 ASSERT(m_state == FrameStateProvisional);
3839 ASSERT(!m_loadingFromCachedPage);
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003840 ASSERT(history().provisionalItem());
akling@apple.com672cb852013-08-22 20:27:27 +00003841 ASSERT(history().provisionalItem()->formData());
3842 ASSERT(history().provisionalItem() == m_requestedHistoryItem.get());
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003843
3844 FrameLoadType loadType = m_loadType;
achristensen@apple.comd9245762019-07-09 18:55:43 +00003845 HistoryItem* item = history().provisionalItem();
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003846
3847 stopAllLoaders(ShouldNotClearProvisionalItem);
achristensen@apple.comd9245762019-07-09 18:55:43 +00003848 if (item)
3849 loadDifferentDocumentItem(*item, history().currentItem(), loadType, MayNotAttemptCacheOnlyLoadForFormSubmissionItem, ShouldTreatAsContinuingLoad::No);
3850 else {
3851 ASSERT_NOT_REACHED();
krollin@apple.comf26b56e2020-02-28 19:43:33 +00003852 FRAMELOADER_RELEASE_LOG_ERROR_IF_ALLOWED(ResourceLoading, "retryAfterFailedCacheOnlyMainResourceLoad: Retrying load after failed cache-only main resource load failed because there is no provisional history item.");
achristensen@apple.comd9245762019-07-09 18:55:43 +00003853 }
beidson50c3bd82007-01-03 03:11:18 +00003854}
3855
anderscac8ee2462007-01-05 22:26:32 +00003856ResourceError FrameLoader::cancelledError(const ResourceRequest& request) const
3857{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003858 ResourceError error = m_client->cancelledError(request);
youenn.fablet@crf.canon.fr156f9bb2016-06-09 06:55:26 +00003859 error.setType(ResourceError::Type::Cancellation);
weinig@apple.com87a569c2008-05-18 01:21:20 +00003860 return error;
anderscac8ee2462007-01-05 22:26:32 +00003861}
3862
commit-queue@webkit.org8090ccb2015-10-06 08:18:08 +00003863ResourceError FrameLoader::blockedByContentBlockerError(const ResourceRequest& request) const
3864{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003865 return m_client->blockedByContentBlockerError(request);
commit-queue@webkit.org8090ccb2015-10-06 08:18:08 +00003866}
3867
bfulgham@apple.comb4c70932016-01-06 22:07:51 +00003868ResourceError FrameLoader::blockedError(const ResourceRequest& request) const
3869{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003870 ResourceError error = m_client->blockedError(request);
youenn.fablet@crf.canon.fr156f9bb2016-06-09 06:55:26 +00003871 error.setType(ResourceError::Type::Cancellation);
bfulgham@apple.comb4c70932016-01-06 22:07:51 +00003872 return error;
3873}
3874
aestes@apple.com176a9aa2016-07-08 20:14:34 +00003875#if ENABLE(CONTENT_FILTERING)
3876ResourceError FrameLoader::blockedByContentFilterError(const ResourceRequest& request) const
3877{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003878 ResourceError error = m_client->blockedByContentFilterError(request);
aestes@apple.com176a9aa2016-07-08 20:14:34 +00003879 error.setType(ResourceError::Type::General);
3880 return error;
3881}
3882#endif
3883
ap@apple.com1e8475922018-10-18 21:38:50 +00003884#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00003885RetainPtr<CFDictionaryRef> FrameLoader::connectionProperties(ResourceLoader* loader)
3886{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003887 return m_client->connectionProperties(loader->documentLoader(), loader->identifier());
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00003888}
3889#endif
3890
dbates@webkit.org0fefad72017-10-19 18:46:22 +00003891ReferrerPolicy FrameLoader::effectiveReferrerPolicy() const
3892{
3893 if (auto* parentFrame = m_frame.tree().parent())
3894 return parentFrame->document()->referrerPolicy();
3895 if (m_opener)
3896 return m_opener->document()->referrerPolicy();
3897 return ReferrerPolicy::NoReferrerWhenDowngrade;
3898}
3899
andersca4422e372007-01-12 19:56:19 +00003900String FrameLoader::referrer() const
3901{
cdumez@apple.com327d6c62016-07-16 04:51:45 +00003902 return m_documentLoader ? m_documentLoader->request().httpReferrer() : emptyString();
andersca4422e372007-01-12 19:56:19 +00003903}
3904
aroben@apple.com11dd5262009-11-13 23:49:05 +00003905void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
lars1e1dad32007-01-23 10:28:38 +00003906{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003907 if (!m_frame.script().canExecuteScripts(NotAboutToExecuteScript))
thatcher10840e52007-09-22 00:49:09 +00003908 return;
3909
weinig@apple.com8f716032013-10-02 17:03:09 +00003910 Vector<Ref<DOMWrapperWorld>> worlds;
aroben@apple.com11dd5262009-11-13 23:49:05 +00003911 ScriptController::getAllWorlds(worlds);
cdumez@apple.com2f661202014-11-04 07:22:18 +00003912 for (auto& world : worlds)
3913 dispatchDidClearWindowObjectInWorld(world);
aroben@apple.com11dd5262009-11-13 23:49:05 +00003914}
3915
weinig@apple.com8f716032013-10-02 17:03:09 +00003916void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
aroben@apple.com11dd5262009-11-13 23:49:05 +00003917{
cdumez@apple.com87a798a2018-04-19 04:02:30 +00003918 if (!m_frame.script().canExecuteScripts(NotAboutToExecuteScript) || !m_frame.windowProxy().existingJSWindowProxy(world))
aroben@apple.com11dd5262009-11-13 23:49:05 +00003919 return;
3920
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003921 m_client->dispatchDidClearWindowObjectInWorld(world);
timothy@apple.comefb8ac12008-07-24 02:48:36 +00003922
akling@apple.com7f50aae2013-08-22 16:01:31 +00003923 if (Page* page = m_frame.page())
burg@cs.washington.edudbacfc12015-01-05 21:30:33 +00003924 page->inspectorController().didClearWindowObjectInWorld(m_frame, world);
loislo@chromium.orge971cb52011-02-08 17:32:44 +00003925
burg@cs.washington.edudbacfc12015-01-05 21:30:33 +00003926 InspectorInstrumentation::didClearWindowObjectInWorld(m_frame, world);
lars1e1dad32007-01-23 10:28:38 +00003927}
3928
beidson@apple.com2a75a962012-04-24 18:12:55 +00003929void FrameLoader::dispatchGlobalObjectAvailableInAllWorlds()
3930{
weinig@apple.com8f716032013-10-02 17:03:09 +00003931 Vector<Ref<DOMWrapperWorld>> worlds;
beidson@apple.com2a75a962012-04-24 18:12:55 +00003932 ScriptController::getAllWorlds(worlds);
cdumez@apple.com2f661202014-11-04 07:22:18 +00003933 for (auto& world : worlds)
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003934 m_client->dispatchGlobalObjectAvailable(world);
beidson@apple.com2a75a962012-04-24 18:12:55 +00003935}
3936
abarth@webkit.org8b45d862011-11-05 21:55:59 +00003937SandboxFlags FrameLoader::effectiveSandboxFlags() const
abarth@webkit.orgb8a10552009-12-02 02:40:35 +00003938{
abarth@webkit.orgf2c54c22010-04-11 06:57:13 +00003939 SandboxFlags flags = m_forcedSandboxFlags;
darin@apple.comfed4d162013-08-25 02:28:06 +00003940 if (Frame* parentFrame = m_frame.tree().parent())
abarth@webkit.org8b45d862011-11-05 21:55:59 +00003941 flags |= parentFrame->document()->sandboxFlags();
akling@apple.com7f50aae2013-08-22 16:01:31 +00003942 if (HTMLFrameOwnerElement* ownerElement = m_frame.ownerElement())
abarth@webkit.orgb8a10552009-12-02 02:40:35 +00003943 flags |= ownerElement->sandboxFlags();
abarth@webkit.org8b45d862011-11-05 21:55:59 +00003944 return flags;
abarth@webkit.orgf5267a42010-01-10 08:14:05 +00003945}
abarth@webkit.orgb8a10552009-12-02 02:40:35 +00003946
lars1e1dad32007-01-23 10:28:38 +00003947void FrameLoader::didChangeTitle(DocumentLoader* loader)
3948{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003949 m_client->didChangeTitle(loader);
lars1e1dad32007-01-23 10:28:38 +00003950
darin@apple.com719d29c2009-07-24 00:09:17 +00003951 if (loader == m_documentLoader) {
lars1e1dad32007-01-23 10:28:38 +00003952 // Must update the entries in the back-forward list too.
akling@apple.com672cb852013-08-22 20:27:27 +00003953 history().setCurrentItemTitle(loader->title());
lars1e1dad32007-01-23 10:28:38 +00003954 // This must go through the WebFrame because it has the right notion of the current b/f item.
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003955 m_client->setTitle(loader->title(), loader->urlForHistory());
3956 m_client->setMainFrameDocumentReady(true); // update observers with new DOMDocument
3957 m_client->dispatchDidReceiveTitle(loader->title());
lars1e1dad32007-01-23 10:28:38 +00003958 }
joepeck@webkit.orgd2ecf372013-12-04 18:20:37 +00003959
3960#if ENABLE(REMOTE_INSPECTOR)
3961 if (m_frame.isMainFrame())
3962 m_frame.page()->remoteInspectorInformationDidChange();
3963#endif
lars1e1dad32007-01-23 10:28:38 +00003964}
andersca4422e372007-01-12 19:56:19 +00003965
achristensen@apple.come0301a32020-02-07 23:30:29 +00003966void FrameLoader::dispatchDidCommitLoad(Optional<HasInsecureContent> initialHasInsecureContent, Optional<UsedLegacyTLS> initialUsedLegacyTLS)
arobendfc56662007-06-21 01:37:24 +00003967{
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00003968 if (m_stateMachine.creatingInitialEmptyDocument())
darin@apple.com87134f22007-12-05 22:58:41 +00003969 return;
3970
youenn@apple.comee96d0f2020-03-18 13:59:23 +00003971 m_client->dispatchDidCommitLoad(initialHasInsecureContent, initialUsedLegacyTLS);
arobendfc56662007-06-21 01:37:24 +00003972
darin@apple.com0e83ab12013-09-28 17:19:04 +00003973 if (m_frame.isMainFrame()) {
akling@apple.com7f50aae2013-08-22 16:01:31 +00003974 m_frame.page()->resetSeenPlugins();
3975 m_frame.page()->resetSeenMediaEngines();
jer.noble@apple.com2d0a60a2012-10-18 18:12:57 +00003976 }
jer.noble@apple.com381b4672012-07-28 00:41:18 +00003977
burg@cs.washington.edudbacfc12015-01-05 21:30:33 +00003978 InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get());
commit-queue@webkit.org42b47872013-02-19 19:19:02 +00003979
joepeck@webkit.orgd2ecf372013-12-04 18:20:37 +00003980#if ENABLE(REMOTE_INSPECTOR)
akling@apple.comfbea4062014-02-27 20:24:03 +00003981 if (m_frame.isMainFrame())
joepeck@webkit.orgd2ecf372013-12-04 18:20:37 +00003982 m_frame.page()->remoteInspectorInformationDidChange();
3983#endif
arobendfc56662007-06-21 01:37:24 +00003984}
3985
darin@apple.com837a78c2009-01-07 15:40:24 +00003986void FrameLoader::tellClientAboutPastMemoryCacheLoads()
3987{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003988 ASSERT(m_frame.page());
3989 ASSERT(m_frame.page()->areMemoryCacheClientCallsEnabled());
darin@apple.com837a78c2009-01-07 15:40:24 +00003990
3991 if (!m_documentLoader)
3992 return;
3993
jpfau@apple.com97c6a7f2013-02-26 00:49:17 +00003994 Vector<ResourceRequest> pastLoads;
darin@apple.com837a78c2009-01-07 15:40:24 +00003995 m_documentLoader->takeMemoryCacheLoadsForClientNotification(pastLoads);
3996
commit-queue@webkit.orgacddfad2015-09-30 05:53:51 +00003997 for (auto& pastLoad : pastLoads) {
3998 CachedResource* resource = MemoryCache::singleton().resourceForRequest(pastLoad, m_frame.page()->sessionID());
darin@apple.com837a78c2009-01-07 15:40:24 +00003999
4000 // FIXME: These loads, loaded from cache, but now gone from the cache by the time
4001 // Page::setMemoryCacheClientCallsEnabled(true) is called, will not be seen by the client.
4002 // Consider if there's some efficient way of remembering enough to deliver this client call.
4003 // We have the URL, but not the rest of the response or the length.
4004 if (!resource)
4005 continue;
4006
4007 ResourceRequest request(resource->url());
youenn@apple.comee96d0f2020-03-18 13:59:23 +00004008 m_client->dispatchDidLoadResourceFromMemoryCache(m_documentLoader.get(), request, resource->response(), resource->encodedSize());
darin@apple.com837a78c2009-01-07 15:40:24 +00004009 }
4010}
4011
diegohcg@webkit.org838e0a22010-09-04 14:48:30 +00004012NetworkingContext* FrameLoader::networkingContext() const
4013{
4014 return m_networkingContext.get();
4015}
4016
antti@apple.coma6775c12013-04-05 21:19:56 +00004017void FrameLoader::loadProgressingStatusChanged()
4018{
antti@apple.com08536d12014-06-27 21:58:06 +00004019 if (auto* view = m_frame.mainFrame().view())
4020 view->loadProgressingStatusChanged();
antti@apple.coma6775c12013-04-05 21:19:56 +00004021}
4022
zalan@apple.comfc7ad742020-03-04 14:53:01 +00004023void FrameLoader::completePageTransitionIfNeeded()
timothy_horton@apple.com88756d62013-05-30 06:24:36 +00004024{
youenn@apple.comee96d0f2020-03-18 13:59:23 +00004025 m_client->completePageTransitionIfNeeded();
timothy_horton@apple.com88756d62013-05-30 06:24:36 +00004026}
4027
antti@apple.com1229ead2015-03-30 21:09:14 +00004028void FrameLoader::clearTestingOverrides()
4029{
cdumez@apple.com8b7a0222018-12-20 04:41:11 +00004030 m_overrideCachePolicyForTesting = WTF::nullopt;
4031 m_overrideResourceLoadPriorityForTesting = WTF::nullopt;
antti@apple.com2c4a2a22015-08-14 14:08:59 +00004032 m_isStrictRawResourceValidationPolicyDisabledForTesting = false;
antti@apple.com1229ead2015-03-30 21:09:14 +00004033}
4034
commit-queue@webkit.org6d635222016-03-08 06:44:59 +00004035bool FrameLoader::isAlwaysOnLoggingAllowed() const
4036{
4037 return frame().isAlwaysOnLoggingAllowed();
4038}
4039
darin@apple.com90a0f152009-02-01 00:55:03 +00004040bool FrameLoaderClient::hasHTMLView() const
4041{
4042 return true;
4043}
4044
dbates@webkit.org7f3a9822017-06-22 19:45:10 +00004045RefPtr<Frame> createWindow(Frame& openerFrame, Frame& lookupFrame, FrameLoadRequest&& request, const WindowFeatures& features, bool& created)
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004046{
4047 ASSERT(!features.dialog || request.frameName().isEmpty());
commit-queue@webkit.org8a13ad32020-03-16 08:11:26 +00004048 ASSERT(request.resourceRequest().httpMethod() == "GET");
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004049
darin@apple.com14800c12014-04-27 04:09:45 +00004050 created = false;
4051
dbates@webkit.orgde972cd2018-01-24 22:11:19 +00004052 // FIXME: Provide line number information with respect to the opener's document.
commit-queue@webkit.org39359f02020-04-25 21:28:45 +00004053 if (request.resourceRequest().url().protocolIsJavaScript() && !openerFrame.document()->contentSecurityPolicy()->allowJavaScriptURLs(openerFrame.document()->url().string(), { }))
dbates@webkit.orgde972cd2018-01-24 22:11:19 +00004054 return nullptr;
4055
cdumez@apple.comeec032f2017-04-05 13:36:47 +00004056 if (!request.frameName().isEmpty() && !equalIgnoringASCIICase(request.frameName(), "_blank")) {
cdumez@apple.com468ca182015-05-15 05:07:22 +00004057 if (RefPtr<Frame> frame = lookupFrame.loader().findFrameForNavigation(request.frameName(), openerFrame.document())) {
cdumez@apple.comeec032f2017-04-05 13:36:47 +00004058 if (!equalIgnoringASCIICase(request.frameName(), "_self")) {
jochen@chromium.orgb2c684a2013-05-11 19:09:01 +00004059 if (Page* page = frame->page())
akling@apple.combd774812013-05-17 00:03:01 +00004060 page->chrome().focus();
jochen@chromium.orgb2c684a2013-05-11 19:09:01 +00004061 }
aestes@apple.com2038dcb2015-12-28 16:26:24 +00004062 return frame;
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004063 }
4064 }
4065
4066 // Sandboxed frames cannot open new auxiliary browsing contexts.
mkwst@chromium.orgb10ebb432012-12-04 18:34:27 +00004067 if (isDocumentSandboxed(openerFrame, SandboxPopups)) {
4068 // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
cdumez@apple.comd6738dc2015-05-04 23:58:32 +00004069 openerFrame.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Blocked opening '" + request.resourceRequest().url().stringCenterEllipsizedToLength() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
darin@apple.com14800c12014-04-27 04:09:45 +00004070 return nullptr;
mkwst@chromium.orgb10ebb432012-12-04 18:34:27 +00004071 }
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004072
4073 // FIXME: Setting the referrer should be the caller's responsibility.
cdumez@apple.comd6738dc2015-05-04 23:58:32 +00004074 String referrer = SecurityPolicy::generateReferrerHeader(openerFrame.document()->referrerPolicy(), request.resourceRequest().url(), openerFrame.loader().outgoingReferrer());
jochen@chromium.orgc881e402013-02-28 21:45:58 +00004075 if (!referrer.isEmpty())
dbates@webkit.org7f3a9822017-06-22 19:45:10 +00004076 request.resourceRequest().setHTTPReferrer(referrer);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00004077 FrameLoader::addSameSiteInfoToRequestIfNeeded(request.resourceRequest(), openerFrame.document());
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004078
cdumez@apple.comd6738dc2015-05-04 23:58:32 +00004079 Page* oldPage = openerFrame.page();
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004080 if (!oldPage)
darin@apple.com14800c12014-04-27 04:09:45 +00004081 return nullptr;
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004082
beidson@apple.com7034ec72017-07-06 00:01:53 +00004083 ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(openerFrame, request);
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00004084 NavigationAction action { request.requester(), request.resourceRequest(), request.initiatedByMainFrame(), NavigationType::Other, shouldOpenExternalURLsPolicy };
commit-queue@webkit.orgba637602020-03-16 07:20:28 +00004085 Page* page = oldPage->chrome().createWindow(openerFrame, features, action);
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004086 if (!page)
darin@apple.com14800c12014-04-27 04:09:45 +00004087 return nullptr;
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004088
darin@apple.com14800c12014-04-27 04:09:45 +00004089 RefPtr<Frame> frame = &page->mainFrame();
4090
commit-queue@webkit.org04df8422017-06-09 17:59:18 +00004091 if (isDocumentSandboxed(openerFrame, SandboxPropagatesToAuxiliaryBrowsingContexts))
4092 frame->loader().forceSandboxFlags(openerFrame.document()->sandboxFlags());
abarth@webkit.org7155e252011-11-04 18:14:58 +00004093
cdumez@apple.comeec032f2017-04-05 13:36:47 +00004094 if (!equalIgnoringASCIICase(request.frameName(), "_blank"))
darin@apple.com14800c12014-04-27 04:09:45 +00004095 frame->tree().setName(request.frameName());
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004096
akling@apple.combd774812013-05-17 00:03:01 +00004097 page->chrome().setToolbarsVisible(features.toolBarVisible || features.locationBarVisible);
darin@apple.com14800c12014-04-27 04:09:45 +00004098
4099 if (!frame->page())
4100 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004101 page->chrome().setStatusbarVisible(features.statusBarVisible);
darin@apple.com14800c12014-04-27 04:09:45 +00004102
4103 if (!frame->page())
4104 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004105 page->chrome().setScrollbarsVisible(features.scrollbarsVisible);
darin@apple.com14800c12014-04-27 04:09:45 +00004106
4107 if (!frame->page())
4108 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004109 page->chrome().setMenubarVisible(features.menuBarVisible);
darin@apple.com14800c12014-04-27 04:09:45 +00004110
4111 if (!frame->page())
4112 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004113 page->chrome().setResizable(features.resizable);
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004114
4115 // 'x' and 'y' specify the location of the window, while 'width' and 'height'
kenneth@webkit.orgdc092f72012-11-14 11:05:20 +00004116 // specify the size of the viewport. We can only resize the window, so adjust
4117 // for the difference between the window size and the viewport size.
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004118
darin@apple.com14800c12014-04-27 04:09:45 +00004119 // FIXME: We should reconcile the initialization of viewport arguments between iOS and non-IOS.
ap@apple.com1e8475922018-10-18 21:38:50 +00004120#if !PLATFORM(IOS_FAMILY)
akling@apple.combd774812013-05-17 00:03:01 +00004121 FloatSize viewportSize = page->chrome().pageRect().size();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00004122 FloatRect windowRect = page->chrome().windowRect();
andersca@apple.comc1242ad2015-08-13 17:37:27 +00004123 if (features.x)
4124 windowRect.setX(*features.x);
4125 if (features.y)
4126 windowRect.setY(*features.y);
clopez@igalia.com6251d342020-04-16 11:22:51 +00004127 // Zero width and height mean using default size, not minimum one.
andersca@apple.comc1242ad2015-08-13 17:37:27 +00004128 if (features.width && *features.width)
4129 windowRect.setWidth(*features.width + (windowRect.width() - viewportSize.width()));
4130 if (features.height && *features.height)
4131 windowRect.setHeight(*features.height + (windowRect.height() - viewportSize.height()));
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004132
clopez@igalia.com6251d342020-04-16 11:22:51 +00004133#if PLATFORM(GTK)
4134 FloatRect oldWindowRect = oldPage->chrome().windowRect();
4135 // Use the size of the previous window if there is no default size.
4136 if (!windowRect.width())
4137 windowRect.setWidth(oldWindowRect.width());
4138 if (!windowRect.height())
4139 windowRect.setHeight(oldWindowRect.height());
4140#endif
4141
kenneth@webkit.orgdc092f72012-11-14 11:05:20 +00004142 // Ensure non-NaN values, minimum size as well as being within valid screen area.
darin@apple.com9ace8012017-01-23 06:24:18 +00004143 FloatRect newWindowRect = DOMWindow::adjustWindowRect(*page, windowRect);
kenneth@webkit.orgdc092f72012-11-14 11:05:20 +00004144
darin@apple.com14800c12014-04-27 04:09:45 +00004145 if (!frame->page())
4146 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004147 page->chrome().setWindowRect(newWindowRect);
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00004148#else
4149 // On iOS, width and height refer to the viewport dimensions.
4150 ViewportArguments arguments;
4151 // Zero width and height mean using default size, not minimum one.
andersca@apple.comc1242ad2015-08-13 17:37:27 +00004152 if (features.width && *features.width)
4153 arguments.width = *features.width;
4154 if (features.height && *features.height)
4155 arguments.height = *features.height;
darin@apple.com14800c12014-04-27 04:09:45 +00004156 frame->setViewportArguments(arguments);
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00004157#endif
4158
darin@apple.com14800c12014-04-27 04:09:45 +00004159 if (!frame->page())
4160 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004161 page->chrome().show();
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004162
4163 created = true;
aestes@apple.com2038dcb2015-12-28 16:26:24 +00004164 return frame;
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004165}
4166
timothy_horton@apple.com57a22212017-10-19 20:43:41 +00004167bool FrameLoader::shouldSuppressTextInputFromEditing() const
aestes@apple.com54c9cf52016-12-16 23:10:56 +00004168{
timothy_horton@apple.com57a22212017-10-19 20:43:41 +00004169 return m_frame.settings().shouldSuppressTextInputFromEditingDuringProvisionalNavigation() && m_state == FrameStateProvisional;
aestes@apple.com54c9cf52016-12-16 23:10:56 +00004170}
4171
commit-queue@webkit.org95298582020-04-17 07:52:00 +00004172bool FrameLoader::arePluginsEnabled()
4173{
4174 return m_frame.settings().arePluginsEnabled();
4175}
4176
ggaren58e230c2006-11-12 04:53:17 +00004177} // namespace WebCore
krollin@apple.comf26b56e2020-02-28 19:43:33 +00004178
4179#undef PAGE_ID
4180#undef FRAME_ID