blob: b20375a50d9a45ad5918939aa44ebfede1f875f9 [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"
ape9991d52006-12-08 18:19:51 +000080#include "HTTPParsers.h"
andersca@apple.com9b9d83b2013-04-10 19:11:20 +000081#include "HistoryController.h"
weinig62f94be2007-07-18 20:37:20 +000082#include "HistoryItem.h"
cdumez@apple.com8b478c62016-01-23 01:04:59 +000083#include "IgnoreOpensDuringUnloadCountIncrementer.h"
commit-queue@webkit.org4c49a662011-01-02 22:27:10 +000084#include "InspectorController.h"
yurys@chromium.org389a6242011-01-12 13:06:42 +000085#include "InspectorInstrumentation.h"
yoav@yoav.ws1c12d5c2017-01-19 07:13:54 +000086#include "LinkLoader.h"
commit-queue@webkit.org3eeac492016-08-12 22:53:27 +000087#include "LoadTiming.h"
beidson@apple.com0c140b42013-01-17 00:45:30 +000088#include "LoaderStrategy.h"
beidson50c3bd82007-01-03 03:11:18 +000089#include "Logging.h"
weinig@apple.com13d777f2013-04-16 21:54:22 +000090#include "MemoryCache.h"
carlosgc@webkit.org32a60dd2016-11-10 14:24:26 +000091#include "MemoryRelease.h"
rniwa@webkit.orgf694bd62017-06-30 19:32:41 +000092#include "NavigationDisabler.h"
rniwa@webkit.org2c6d4eb2017-07-01 21:26:31 +000093#include "NavigationScheduler.h"
drousso@apple.com21748ed2018-10-08 18:25:52 +000094#include "Node.h"
achristensen@apple.come5945672016-06-13 21:58:53 +000095#include "Page.h"
ggaren@apple.com521f64b2009-09-24 05:53:23 +000096#include "PageTransitionEvent.h"
akling@apple.come6549f42016-12-01 16:15:27 +000097#include "PerformanceLogging.h"
beidson@apple.com0c140b42013-01-17 00:45:30 +000098#include "PlatformStrategies.h"
hausmann@webkit.org9999bb82008-03-10 11:52:27 +000099#include "PluginData.h"
andersca@apple.com641fef92009-01-06 22:57:25 +0000100#include "PluginDocument.h"
abarth@webkit.org401a3792013-03-03 10:12:59 +0000101#include "PolicyChecker.h"
andersca2b2c5ce2007-01-15 21:55:00 +0000102#include "ProgressTracker.h"
beidson50c3bd82007-01-03 03:11:18 +0000103#include "ResourceHandle.h"
beidson@apple.come3ea01d2015-07-02 18:33:23 +0000104#include "ResourceLoadInfo.h"
wilander@apple.com63f925f2016-10-06 17:40:12 +0000105#include "ResourceLoadObserver.h"
darinc370e7e2006-11-08 05:52:27 +0000106#include "ResourceRequest.h"
ossy@webkit.org66d8c0a2014-02-05 11:42:35 +0000107#include "SVGDocument.h"
108#include "SVGLocatable.h"
109#include "SVGNames.h"
ossy@webkit.org66d8c0a2014-02-05 11:42:35 +0000110#include "SVGViewElement.h"
111#include "SVGViewSpec.h"
weinig@apple.com79099002008-11-21 05:51:28 +0000112#include "ScriptController.h"
darin@chromium.org6b412472008-11-24 23:07:38 +0000113#include "ScriptSourceCode.h"
vsevik@chromium.org53bb0692012-01-18 20:59:10 +0000114#include "ScrollAnimator.h"
weinige06430a2007-10-19 20:53:22 +0000115#include "SecurityOrigin.h"
abarth@webkit.orgeea90662011-11-09 07:58:49 +0000116#include "SecurityPolicy.h"
darinc370e7e2006-11-08 05:52:27 +0000117#include "SegmentedString.h"
yurys@chromium.org832b9142010-08-05 12:36:31 +0000118#include "SerializedScriptValue.h"
darinc370e7e2006-11-08 05:52:27 +0000119#include "Settings.h"
cdumez@apple.comfdb89712018-06-11 20:52:31 +0000120#include "ShouldTreatAsContinuingLoad.h"
rniwa@webkit.org77c65702019-08-13 05:18:11 +0000121#include "StyleTreeResolver.h"
akling@apple.com7f81b1e2013-09-06 17:23:03 +0000122#include "SubframeLoader.h"
dbates@webkit.org3c1f25a2018-02-07 18:56:02 +0000123#include "SubresourceLoader.h"
darin@apple.com1b75e772010-06-15 22:20:34 +0000124#include "TextResourceDecoder.h"
beidson@apple.come3ea01d2015-07-02 18:33:23 +0000125#include "UserContentController.h"
commit-queue@webkit.org635dbdc2017-11-23 19:36:08 +0000126#include "UserGestureIndicator.h"
darin@apple.com1b75e772010-06-15 22:20:34 +0000127#include "WindowFeatures.h"
128#include "XMLDocumentParser.h"
commit-queue@webkit.org1d992932018-09-11 17:14:07 +0000129#include <dom/ScriptDisallowedScope.h>
achristensen@apple.comce5520e2017-09-25 22:33:19 +0000130#include <wtf/CompletionHandler.h>
keith_miller@apple.combb2f61c2018-12-01 03:28:36 +0000131#include <wtf/URL.h>
akling@apple.comf8515982013-09-02 18:50:01 +0000132#include <wtf/Ref.h>
beidson@apple.com1c9022b2018-03-21 00:05:58 +0000133#include <wtf/SetForScope.h>
darin@apple.com1b75e772010-06-15 22:20:34 +0000134#include <wtf/StdLibExtras.h>
simon.fraser@apple.com83325b92017-03-17 00:47:16 +0000135#include <wtf/SystemTracing.h>
darin@apple.com1b75e772010-06-15 22:20:34 +0000136#include <wtf/text/CString.h>
zimmermann@webkit.orgb5e11e62011-05-16 07:56:06 +0000137#include <wtf/text/WTFString.h>
darin@apple.com1b75e772010-06-15 22:20:34 +0000138
jcivelli@chromium.orgc2019dd2011-05-24 19:32:03 +0000139#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
jeremy@chromium.orgc4b86e32011-02-13 20:28:39 +0000140#include "Archive.h"
jeremy@chromium.orgc4b86e32011-02-13 20:28:39 +0000141#endif
142
enrica@apple.com53b08e52016-01-19 22:58:59 +0000143#if ENABLE(DATA_DETECTION)
144#include "DataDetection.h"
145#endif
146
ap@apple.com1e8475922018-10-18 21:38:50 +0000147#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000148#include "DocumentType.h"
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000149#include "ResourceLoader.h"
cdumez@apple.com0b0e88f2016-03-06 03:28:54 +0000150#include "RuntimeApplicationChecks.h"
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000151#endif
loislo@chromium.org82b9dde2012-09-12 13:16:31 +0000152
krollin@apple.comd54b5d72016-09-12 18:59:32 +0000153#define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), Network, "%p - FrameLoader::" fmt, this, ##__VA_ARGS__)
commit-queue@webkit.org6d635222016-03-08 06:44:59 +0000154
darinfa7a4e32006-10-30 00:37:02 +0000155namespace WebCore {
156
darin@apple.com1b75e772010-06-15 22:20:34 +0000157using namespace HTMLNames;
oliverb64e4082007-10-12 13:13:51 +0000158using namespace SVGNames;
darinc370e7e2006-11-08 05:52:27 +0000159
commit-queue@webkit.orgff400aa2011-03-10 23:43:48 +0000160static const char defaultAcceptHeader[] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
darinc370e7e2006-11-08 05:52:27 +0000161
darinc370e7e2006-11-08 05:52:27 +0000162bool isBackForwardLoadType(FrameLoadType type)
163{
164 switch (type) {
andersca@apple.comb50fcc32014-06-19 00:13:20 +0000165 case FrameLoadType::Standard:
166 case FrameLoadType::Reload:
167 case FrameLoadType::ReloadFromOrigin:
antti@apple.com5d0c5402017-03-17 19:52:49 +0000168 case FrameLoadType::ReloadExpiredOnly:
andersca@apple.comb50fcc32014-06-19 00:13:20 +0000169 case FrameLoadType::Same:
170 case FrameLoadType::RedirectWithLockedBackForwardList:
171 case FrameLoadType::Replace:
172 return false;
173 case FrameLoadType::Back:
174 case FrameLoadType::Forward:
175 case FrameLoadType::IndexedBackForward:
176 return true;
darinc370e7e2006-11-08 05:52:27 +0000177 }
178 ASSERT_NOT_REACHED();
179 return false;
180}
181
antti@apple.com5d0c5402017-03-17 19:52:49 +0000182bool isReload(FrameLoadType type)
183{
184 switch (type) {
185 case FrameLoadType::Reload:
186 case FrameLoadType::ReloadFromOrigin:
187 case FrameLoadType::ReloadExpiredOnly:
188 return true;
189 case FrameLoadType::Standard:
190 case FrameLoadType::Same:
191 case FrameLoadType::RedirectWithLockedBackForwardList:
192 case FrameLoadType::Replace:
193 case FrameLoadType::Back:
194 case FrameLoadType::Forward:
195 case FrameLoadType::IndexedBackForward:
196 return false;
197 }
198 ASSERT_NOT_REACHED();
199 return false;
200}
201
cjerdonek@webkit.org75d10692010-05-18 16:18:31 +0000202// This is not in the FrameLoader class to emphasize that it does not depend on
203// private FrameLoader data, and to avoid increasing the number of public functions
204// with access to private data. Since only this .cpp file needs it, making it
205// non-member lets us exclude it from the header file, thus keeping FrameLoader.h's
206// API simpler.
207//
cdumez@apple.comd6738dc2015-05-04 23:58:32 +0000208static bool isDocumentSandboxed(Frame& frame, SandboxFlags mask)
cjerdonek@webkit.org75d10692010-05-18 16:18:31 +0000209{
cdumez@apple.comd6738dc2015-05-04 23:58:32 +0000210 return frame.document() && frame.document()->isSandboxed(mask);
cjerdonek@webkit.org75d10692010-05-18 16:18:31 +0000211}
212
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +0000213struct ForbidPromptsScope {
214 ForbidPromptsScope(Page* page) : m_page(page)
215 {
216 if (!m_page)
217 return;
218 m_page->forbidPrompts();
219 }
220
221 ~ForbidPromptsScope()
222 {
223 if (!m_page)
224 return;
225 m_page->allowPrompts();
226 }
227
228 Page* m_page;
229};
230
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000231class FrameLoader::FrameProgressTracker {
cdumez@apple.coma738a882016-04-19 18:39:09 +0000232 WTF_MAKE_FAST_ALLOCATED;
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000233public:
weinig@apple.comeefc25d2013-11-08 22:42:27 +0000234 explicit FrameProgressTracker(Frame& frame)
235 : m_frame(frame)
236 , m_inProgress(false)
237 {
238 }
239
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000240 ~FrameProgressTracker()
241 {
jpfau@apple.com7907c6b2014-10-28 22:38:44 +0000242 if (m_inProgress && m_frame.page())
andersca@apple.comcd088792014-01-10 07:19:29 +0000243 m_frame.page()->progress().progressCompleted(m_frame);
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000244 }
245
246 void progressStarted()
247 {
akling@apple.com7f50aae2013-08-22 16:01:31 +0000248 ASSERT(m_frame.page());
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000249 if (!m_inProgress)
andersca@apple.comcd088792014-01-10 07:19:29 +0000250 m_frame.page()->progress().progressStarted(m_frame);
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000251 m_inProgress = true;
252 }
253
254 void progressCompleted()
255 {
256 ASSERT(m_inProgress);
akling@apple.com7f50aae2013-08-22 16:01:31 +0000257 ASSERT(m_frame.page());
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000258 m_inProgress = false;
andersca@apple.comcd088792014-01-10 07:19:29 +0000259 m_frame.page()->progress().progressCompleted(m_frame);
cdumez@apple.comc2b1e2a2019-09-04 03:13:45 +0000260 platformStrategies()->loaderStrategy()->pageLoadCompleted(*m_frame.page());
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000261 }
262
263private:
akling@apple.com7f50aae2013-08-22 16:01:31 +0000264 Frame& m_frame;
japhet@chromium.org7879dd72012-08-30 02:58:37 +0000265 bool m_inProgress;
266};
267
akling@apple.com7f50aae2013-08-22 16:01:31 +0000268FrameLoader::FrameLoader(Frame& frame, FrameLoaderClient& client)
darinfa7a4e32006-10-30 00:37:02 +0000269 : m_frame(frame)
ggaren1b09a122006-11-29 06:11:14 +0000270 , m_client(client)
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +0000271 , m_policyChecker(makeUnique<PolicyChecker>(frame))
272 , m_history(makeUnique<HistoryController>(frame))
akling@apple.com654fd9a2013-10-06 21:07:29 +0000273 , m_notifier(frame)
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +0000274 , m_subframeLoader(makeUnique<SubframeLoader>(frame))
weinig@apple.comeefc25d2013-11-08 22:42:27 +0000275 , m_mixedContentChecker(frame)
japhet@chromium.orgce6c1ba2012-11-28 19:30:48 +0000276 , m_state(FrameStateProvisional)
andersca@apple.comb50fcc32014-06-19 00:13:20 +0000277 , m_loadType(FrameLoadType::Standard)
darinfa7a4e32006-10-30 00:37:02 +0000278 , m_quickRedirectComing(false)
279 , m_sentRedirectNotification(false)
darinc370e7e2006-11-08 05:52:27 +0000280 , m_inStopAllLoaders(false)
darinc370e7e2006-11-08 05:52:27 +0000281 , m_isExecutingJavaScriptFormAction(false)
japhet@chromium.orgce6c1ba2012-11-28 19:30:48 +0000282 , m_didCallImplicitClose(true)
darinc370e7e2006-11-08 05:52:27 +0000283 , m_wasUnloadEventEmitted(false)
284 , m_isComplete(false)
darinc370e7e2006-11-08 05:52:27 +0000285 , m_needsClear(false)
andersca@apple.com574a7452014-11-21 20:10:13 +0000286 , m_checkTimer(*this, &FrameLoader::checkTimerFired)
darin@apple.comf53381b2009-09-23 23:27:01 +0000287 , m_shouldCallCheckCompleted(false)
288 , m_shouldCallCheckLoadComplete(false)
weinig@apple.comeefc25d2013-11-08 22:42:27 +0000289 , m_opener(nullptr)
beidson@apple.comac095c02009-08-18 01:37:56 +0000290 , m_loadingFromCachedPage(false)
beidson@apple.com1390a812013-07-20 06:43:51 +0000291 , m_currentNavigationHasShownBeforeUnloadConfirmPanel(false)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000292 , m_loadsSynchronously(false)
abarth@webkit.orgf2c54c22010-04-11 06:57:13 +0000293 , m_forcedSandboxFlags(SandboxNone)
darinfa7a4e32006-10-30 00:37:02 +0000294{
295}
296
297FrameLoader::~FrameLoader()
298{
weinig@apple.comeefc25d2013-11-08 22:42:27 +0000299 setOpener(nullptr);
cdumez@apple.comf6bbf482019-10-12 19:17:37 +0000300 detachFromAllOpenedFrames();
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +0000301
akling@apple.com7f50aae2013-08-22 16:01:31 +0000302 m_client.frameLoaderDestroyed();
diegohcg@webkit.org838e0a22010-09-04 14:48:30 +0000303
304 if (m_networkingContext)
305 m_networkingContext->invalidate();
darinfa7a4e32006-10-30 00:37:02 +0000306}
307
cdumez@apple.comf6bbf482019-10-12 19:17:37 +0000308void FrameLoader::detachFromAllOpenedFrames()
309{
310 for (auto& frame : m_openedFrames)
311 frame->loader().m_opener = nullptr;
312 m_openedFrames.clear();
313}
314
mrowe@apple.com5d92f2a2008-09-30 21:04:35 +0000315void FrameLoader::init()
mjs8d620d52007-05-10 12:31:42 +0000316{
darin@apple.com73006812011-06-29 20:46:33 +0000317 // This somewhat odd set of steps gives the frame an initial empty document.
achristensen@apple.comceccd772018-10-02 20:24:42 +0000318 setPolicyDocumentLoader(m_client.createDocumentLoader(ResourceRequest(URL({ }, emptyString())), SubstituteData()).ptr());
mjs8d620d52007-05-10 12:31:42 +0000319 setProvisionalDocumentLoader(m_policyDocumentLoader.get());
cdumez@apple.coma0010ff2018-12-13 23:17:44 +0000320 m_provisionalDocumentLoader->startLoadingMainResource();
jpfau@apple.comec9eb512014-07-10 01:13:45 +0000321
322 Ref<Frame> protect(m_frame);
akling@apple.com7f50aae2013-08-22 16:01:31 +0000323 m_frame.document()->cancelParsing();
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +0000324 m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument);
diegohcg@webkit.org838e0a22010-09-04 14:48:30 +0000325
akling@apple.com7f50aae2013-08-22 16:01:31 +0000326 m_networkingContext = m_client.createNetworkingContext();
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +0000327 m_progressTracker = makeUnique<FrameProgressTracker>(m_frame);
mjs8d620d52007-05-10 12:31:42 +0000328}
329
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000330void FrameLoader::initForSynthesizedDocument(const URL&)
331{
332 // FIXME: We need to initialize the document URL to the specified URL. Currently the URL is empty and hence
333 // FrameLoader::checkCompleted() will overwrite the URL of the document to be activeDocumentLoader()->documentURL().
334
achristensen@apple.comceccd772018-10-02 20:24:42 +0000335 auto loader = m_client.createDocumentLoader(ResourceRequest(URL({ }, emptyString())), SubstituteData());
beidson@apple.com10a537f2015-07-09 22:30:42 +0000336 loader->attachToFrame(m_frame);
utatane.tea@gmail.com84077632018-06-23 08:39:34 +0000337 loader->setResponse(ResourceResponse(URL(), "text/html"_s, 0, String()));
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000338 loader->setCommitted(true);
commit-queue@webkit.orgc7c21c92017-10-25 21:17:46 +0000339 setDocumentLoader(loader.ptr());
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000340
341 m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument);
342 m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
343 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
344 m_client.transitionToCommittedForNewPage();
345
346 m_didCallImplicitClose = true;
347 m_isComplete = true;
348 m_state = FrameStateComplete;
349 m_needsClear = true;
350
351 m_networkingContext = m_client.createNetworkingContext();
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +0000352 m_progressTracker = makeUnique<FrameProgressTracker>(m_frame);
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000353}
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000354
darinfa7a4e32006-10-30 00:37:02 +0000355void FrameLoader::setDefersLoading(bool defers)
356{
darin8207db42007-02-20 18:18:39 +0000357 if (m_documentLoader)
358 m_documentLoader->setDefersLoading(defers);
359 if (m_provisionalDocumentLoader)
360 m_provisionalDocumentLoader->setDefersLoading(defers);
361 if (m_policyDocumentLoader)
362 m_policyDocumentLoader->setDefersLoading(defers);
akling@apple.com672cb852013-08-22 20:27:27 +0000363 history().setDefersLoading(defers);
darin@apple.comf53381b2009-09-23 23:27:01 +0000364
365 if (!defers) {
akling@apple.com7f50aae2013-08-22 16:01:31 +0000366 m_frame.navigationScheduler().startTimer();
darin@apple.comf53381b2009-09-23 23:27:01 +0000367 startCheckCompleteTimer();
368 }
darinfa7a4e32006-10-30 00:37:02 +0000369}
370
rniwa@webkit.orgba12a012019-02-03 22:48:22 +0000371void FrameLoader::checkContentPolicy(const ResourceResponse& response, PolicyCheckIdentifier identifier, ContentPolicyDecisionFunction&& function)
achristensen@apple.comb8c49be2017-08-23 21:10:09 +0000372{
bfulgham@apple.com78e81d92018-06-25 21:29:50 +0000373 if (!activeDocumentLoader()) {
374 // Load was cancelled
rniwa@webkit.orgba12a012019-02-03 22:48:22 +0000375 function(PolicyAction::Ignore, identifier);
bfulgham@apple.com78e81d92018-06-25 21:29:50 +0000376 return;
377 }
378
rniwa@webkit.orgba12a012019-02-03 22:48:22 +0000379 // FIXME: Validate the policy check identifier.
commit-queue@webkit.orga4a9ce22019-04-10 22:56:35 +0000380 client().dispatchDecidePolicyForResponse(response, activeDocumentLoader()->request(), identifier, activeDocumentLoader()->downloadAttribute(), WTFMove(function));
achristensen@apple.comb8c49be2017-08-23 21:10:09 +0000381}
382
dbates@webkit.org7f3a9822017-06-22 19:45:10 +0000383void FrameLoader::changeLocation(FrameLoadRequest&& request)
mjsd40bfee2007-07-09 06:29:48 +0000384{
dbates@webkit.org7f3a9822017-06-22 19:45:10 +0000385 urlSelected(WTFMove(request), nullptr);
darinc370e7e2006-11-08 05:52:27 +0000386}
387
darin@apple.com0ce67df2019-06-17 01:48:13 +0000388void FrameLoader::urlSelected(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, Optional<NewFrameOpenerPolicy> openerPolicy, const AtomString& downloadAttribute, const SystemPreviewInfo& systemPreviewInfo, Optional<AdClickAttribution>&& adClickAttribution)
bfulgham@apple.com8f831542016-03-31 15:35:41 +0000389{
beidson@apple.com7034ec72017-07-06 00:01:53 +0000390 auto* frame = lexicalFrameFromCommonVM();
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +0000391 auto initiatedByMainFrame = frame && frame->isMainFrame() ? InitiatedByMainFrame::Yes : InitiatedByMainFrame::Unknown;
beidson@apple.com7034ec72017-07-06 00:01:53 +0000392
cdumez@apple.com6eda1ab2018-12-20 20:23:18 +0000393 NewFrameOpenerPolicy newFrameOpenerPolicy = openerPolicy.valueOr(shouldSendReferrer == NeverSendReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow);
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +0000394 urlSelected(FrameLoadRequest(*m_frame.document(), m_frame.document()->securityOrigin(), { url }, passedTarget, lockHistory, lockBackForwardList, shouldSendReferrer, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, shouldOpenExternalURLsPolicy, initiatedByMainFrame, DoNotReplaceDocumentIfJavaScriptURL, downloadAttribute, systemPreviewInfo), triggeringEvent, WTFMove(adClickAttribution));
bfulgham@apple.com8f831542016-03-31 15:35:41 +0000395}
396
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +0000397void FrameLoader::urlSelected(FrameLoadRequest&& frameRequest, Event* triggeringEvent, Optional<AdClickAttribution>&& adClickAttribution)
cjerdonek@webkit.org983777f2010-05-17 07:34:12 +0000398{
krollin@apple.come1810b62018-12-20 19:23:20 +0000399 RELEASE_LOG_IF_ALLOWED("urlSelected: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
400
akling@apple.comf8515982013-09-02 18:50:01 +0000401 Ref<Frame> protect(m_frame);
darin@apple.com1cf3d562010-12-07 16:23:03 +0000402
cdumez@apple.com6cbf70a2019-10-11 20:26:15 +0000403 if (m_frame.script().executeIfJavaScriptURL(frameRequest.resourceRequest().url(), frameRequest.shouldReplaceDocumentIfJavaScriptURL())) {
404 m_quickRedirectComing = false;
weinig@apple.com6b00e242008-01-08 01:30:27 +0000405 return;
cdumez@apple.com6cbf70a2019-10-11 20:26:15 +0000406 }
weinig@apple.com6b00e242008-01-08 01:30:27 +0000407
darin@apple.com1cf3d562010-12-07 16:23:03 +0000408 if (frameRequest.frameName().isEmpty())
akling@apple.com7f50aae2013-08-22 16:01:31 +0000409 frameRequest.setFrameName(m_frame.document()->baseTarget());
darinc370e7e2006-11-08 05:52:27 +0000410
darin@apple.com4cd1b242009-03-27 23:37:46 +0000411 addHTTPOriginIfNeeded(frameRequest.resourceRequest(), outgoingOrigin());
bfulgham@apple.comb30d7f82016-06-07 15:47:30 +0000412 m_frame.document()->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(frameRequest.resourceRequest(), ContentSecurityPolicy::InsecureRequestType::Navigation);
darin@apple.com4cd1b242009-03-27 23:37:46 +0000413
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +0000414 loadFrameRequest(WTFMove(frameRequest), triggeringEvent, { }, WTFMove(adClickAttribution));
darinc370e7e2006-11-08 05:52:27 +0000415}
416
darin@apple.com961f2a52016-12-31 09:51:29 +0000417void FrameLoader::submitForm(Ref<FormSubmission>&& submission)
darinc370e7e2006-11-08 05:52:27 +0000418{
darin@apple.comc04189e2017-01-18 05:17:17 +0000419 ASSERT(submission->method() == FormSubmission::Method::Post || submission->method() == FormSubmission::Method::Get);
dglazkov@chromium.org25a57e52010-06-20 21:00:35 +0000420
dglazkov@chromium.org996fc222010-06-21 16:36:40 +0000421 // FIXME: Find a good spot for these.
darin@apple.comc04189e2017-01-18 05:17:17 +0000422 ASSERT(!submission->state().sourceDocument().frame() || submission->state().sourceDocument().frame() == &m_frame);
dbates@webkit.org29908522017-01-07 07:14:03 +0000423
akling@apple.com7f50aae2013-08-22 16:01:31 +0000424 if (!m_frame.page())
adele@apple.comf3d6b892008-04-29 01:30:20 +0000425 return;
dbates@webkit.org29908522017-01-07 07:14:03 +0000426
dglazkov@chromium.org996fc222010-06-21 16:36:40 +0000427 if (submission->action().isEmpty())
darinc370e7e2006-11-08 05:52:27 +0000428 return;
429
cdumez@apple.comd6738dc2015-05-04 23:58:32 +0000430 if (isDocumentSandboxed(m_frame, SandboxForms)) {
mkwst@chromium.orgb10ebb432012-12-04 18:34:27 +0000431 // 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 +0000432 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 +0000433 return;
mkwst@chromium.orgb10ebb432012-12-04 18:34:27 +0000434 }
abarth@webkit.orgb8a10552009-12-02 02:40:35 +0000435
keith_miller@apple.combb2f61c2018-12-01 03:28:36 +0000436 if (WTF::protocolIsJavaScript(submission->action())) {
darin@apple.com5ffbb5c2013-09-27 16:39:41 +0000437 if (!m_frame.document()->contentSecurityPolicy()->allowFormAction(URL(submission->action())))
commit-queue@webkit.org78e860e2012-08-16 12:42:09 +0000438 return;
darinc370e7e2006-11-08 05:52:27 +0000439 m_isExecutingJavaScriptFormAction = true;
ap@apple.come6afcb62014-04-20 19:02:13 +0000440 Ref<Frame> protect(m_frame);
akling@apple.com7f50aae2013-08-22 16:01:31 +0000441 m_frame.script().executeIfJavaScriptURL(submission->action(), DoNotReplaceDocumentIfJavaScriptURL);
darinc370e7e2006-11-08 05:52:27 +0000442 m_isExecutingJavaScriptFormAction = false;
443 return;
444 }
445
darin@apple.comc04189e2017-01-18 05:17:17 +0000446 Frame* targetFrame = findFrameForNavigation(submission->target(), &submission->state().sourceDocument());
darin@apple.com0f88bda2009-04-02 00:30:50 +0000447 if (!targetFrame) {
commit-queue@webkit.org635dbdc2017-11-23 19:36:08 +0000448 if (!DOMWindow::allowPopUp(m_frame) && !UserGestureIndicator::processingUserGesture())
abarth@webkit.orgc72185c2010-04-09 06:43:19 +0000449 return;
450
darin@apple.comc04189e2017-01-18 05:17:17 +0000451 // FIXME: targetFrame can be null for two distinct reasons:
ap@apple.comf8c414e2013-08-13 03:44:57 +0000452 // 1. The frame was not found by name, so we should try opening a new window.
453 // 2. The frame was found, but navigating it was not allowed, e.g. by HTML5 sandbox or by origin checks.
454 // Continuing form submission makes no sense in the latter case.
455 // There is a repeat check after timer fires, so this is not a correctness issue.
456
akling@apple.com7f50aae2013-08-22 16:01:31 +0000457 targetFrame = &m_frame;
dglazkov@chromium.org996fc222010-06-21 16:36:40 +0000458 } else
459 submission->clearTarget();
460
darin@apple.com0f88bda2009-04-02 00:30:50 +0000461 if (!targetFrame->page())
darinc370e7e2006-11-08 05:52:27 +0000462 return;
darin@apple.com0f88bda2009-04-02 00:30:50 +0000463
464 // FIXME: We'd like to remove this altogether and fix the multiple form submission issue another way.
465
466 // We do not want to submit more than one form from the same page, nor do we want to submit a single
467 // form more than once. This flag prevents these from happening; not sure how other browsers prevent this.
ggaren@apple.com7a176e12015-11-12 01:48:27 +0000468 // The flag is reset in each time we start dispatching a new mouse or key down event, and
darin@apple.com0f88bda2009-04-02 00:30:50 +0000469 // also in setView since this part may get reused for a page from the back/forward cache.
470 // The form multi-submit logic here is only needed when we are submitting a form that affects this frame.
471
472 // FIXME: Frame targeting is only one of the ways the submission could end up doing something other
473 // than replacing this frame's content, so this check is flawed. On the other hand, the check is hardly
474 // needed any more now that we reset m_submittedFormURL on each mouse or key down event.
475
darin@apple.comfed4d162013-08-25 02:28:06 +0000476 if (m_frame.tree().isDescendantOf(targetFrame)) {
commit-queue@webkit.org43964052012-08-13 19:30:15 +0000477 if (m_submittedFormURL == submission->requestURL())
darin@apple.com0f88bda2009-04-02 00:30:50 +0000478 return;
commit-queue@webkit.org43964052012-08-13 19:30:15 +0000479 m_submittedFormURL = submission->requestURL();
darinc370e7e2006-11-08 05:52:27 +0000480 }
481
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +0000482 submission->setReferrer(outgoingReferrer());
dglazkov@chromium.org996fc222010-06-21 16:36:40 +0000483 submission->setOrigin(outgoingOrigin());
darinc370e7e2006-11-08 05:52:27 +0000484
darin@apple.com961f2a52016-12-31 09:51:29 +0000485 targetFrame->navigationScheduler().scheduleFormSubmission(WTFMove(submission));
darinc370e7e2006-11-08 05:52:27 +0000486}
487
commit-queue@webkit.orgfc5833b2011-02-23 06:58:46 +0000488void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy)
darinc370e7e2006-11-08 05:52:27 +0000489{
akling@apple.com7f50aae2013-08-22 16:01:31 +0000490 if (m_frame.document() && m_frame.document()->parser())
491 m_frame.document()->parser()->stopParsing();
mjs8d620d52007-05-10 12:31:42 +0000492
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +0000493 if (unloadEventPolicy != UnloadEventPolicyNone)
ggaren@apple.com7a176e12015-11-12 01:48:27 +0000494 dispatchUnloadEvents(unloadEventPolicy);
darinc370e7e2006-11-08 05:52:27 +0000495
darin@apple.com4d9d7182009-09-23 00:38:04 +0000496 m_isComplete = true; // to avoid calling completed() in finishedParsing()
ggarena57755c2007-07-09 21:08:10 +0000497 m_didCallImplicitClose = true; // don't want that one either
darinc370e7e2006-11-08 05:52:27 +0000498
akling@apple.com7f50aae2013-08-22 16:01:31 +0000499 if (m_frame.document() && m_frame.document()->parsing()) {
darinc370e7e2006-11-08 05:52:27 +0000500 finishedParsing();
akling@apple.com7f50aae2013-08-22 16:01:31 +0000501 m_frame.document()->setParsing(false);
darinc370e7e2006-11-08 05:52:27 +0000502 }
abarth@webkit.org55d49da2011-06-20 23:32:54 +0000503
darin@apple.com389af862016-11-14 03:22:31 +0000504 if (auto* document = m_frame.document()) {
mark.lam@apple.com45beb072012-12-12 23:04:20 +0000505 // FIXME: Should the DatabaseManager watch for something like ActiveDOMObject::stop() rather than being special-cased here?
darin@apple.com389af862016-11-14 03:22:31 +0000506 DatabaseManager::singleton().stopDatabases(*document, nullptr);
darinc370e7e2006-11-08 05:52:27 +0000507 }
508
cdumez@apple.com2d8d6082018-02-27 21:47:57 +0000509 policyChecker().stopCheck();
510
ap@apple.com3f0a0a12010-06-24 23:58:36 +0000511 // 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 +0000512 m_frame.navigationScheduler().cancel();
darinc370e7e2006-11-08 05:52:27 +0000513}
514
515void FrameLoader::stop()
516{
517 // http://bugs.webkit.org/show_bug.cgi?id=10854
518 // The frame's last ref may be removed and it will be deleted by checkCompleted().
akling@apple.comf8515982013-09-02 18:50:01 +0000519 Ref<Frame> protect(m_frame);
abarth@webkit.orgfd912902011-06-10 21:16:20 +0000520
akling@apple.com7f50aae2013-08-22 16:01:31 +0000521 if (DocumentParser* parser = m_frame.document()->parser()) {
abarth@webkit.orgfd912902011-06-10 21:16:20 +0000522 parser->stopParsing();
523 parser->finish();
524 }
darinc370e7e2006-11-08 05:52:27 +0000525}
526
ap@apple.come042b632013-05-17 20:04:43 +0000527void FrameLoader::willTransitionToCommitted()
528{
529 // This function is called when a frame is still fully in place (not cached, not detached), but will be replaced.
530
akling@apple.com7f50aae2013-08-22 16:01:31 +0000531 if (m_frame.editor().hasComposition()) {
ap@apple.come042b632013-05-17 20:04:43 +0000532 // The text was already present in DOM, so it's better to confirm than to cancel the composition.
akling@apple.com7f50aae2013-08-22 16:01:31 +0000533 m_frame.editor().confirmComposition();
ap@apple.comc9851362014-12-11 17:23:34 +0000534 if (EditorClient* editorClient = m_frame.editor().client()) {
akling@apple.com7f50aae2013-08-22 16:01:31 +0000535 editorClient->respondToChangedSelection(&m_frame);
ap@apple.comc9851362014-12-11 17:23:34 +0000536 editorClient->discardedComposition(&m_frame);
537 }
ap@apple.come042b632013-05-17 20:04:43 +0000538 }
539}
540
darinc370e7e2006-11-08 05:52:27 +0000541bool FrameLoader::closeURL()
542{
akling@apple.com672cb852013-08-22 20:27:27 +0000543 history().saveDocumentState();
stavila@adobe.comeb50d7c2014-12-17 10:14:32 +0000544
akling@apple.com7f50aae2013-08-22 16:01:31 +0000545 Document* currentDocument = m_frame.document();
stavila@adobe.comeb50d7c2014-12-17 10:14:32 +0000546 UnloadEventPolicy unloadEventPolicy;
547 if (m_frame.page() && m_frame.page()->chrome().client().isSVGImageChromeClient()) {
548 // If this is the SVGDocument of an SVGImage, no need to dispatch events or recalcStyle.
549 unloadEventPolicy = UnloadEventPolicyNone;
550 } else {
cdumez@apple.com9265dfe2019-10-17 01:44:16 +0000551 // Should only send the pagehide event here if the current document exists and has not been placed in the back/forward cache.
552 unloadEventPolicy = currentDocument && currentDocument->backForwardCacheState() == Document::NotInBackForwardCache ? UnloadEventPolicyUnloadAndPageHide : UnloadEventPolicyUnloadOnly;
stavila@adobe.comeb50d7c2014-12-17 10:14:32 +0000553 }
554
555 stopLoading(unloadEventPolicy);
beidson@apple.com212b7842009-09-03 00:55:18 +0000556
akling@apple.com7f50aae2013-08-22 16:01:31 +0000557 m_frame.editor().clearUndoRedoOperations();
darinc370e7e2006-11-08 05:52:27 +0000558 return true;
559}
560
abarth@webkit.org55d49da2011-06-20 23:32:54 +0000561bool FrameLoader::didOpenURL()
darinc370e7e2006-11-08 05:52:27 +0000562{
akling@apple.com7f50aae2013-08-22 16:01:31 +0000563 if (m_frame.navigationScheduler().redirectScheduledDuringLoad()) {
darinc370e7e2006-11-08 05:52:27 +0000564 // A redirect was scheduled before the document was created.
565 // This can happen when one frame changes another frame's location.
566 return false;
darin@apple.com0f88bda2009-04-02 00:30:50 +0000567 }
darinc370e7e2006-11-08 05:52:27 +0000568
akling@apple.com7f50aae2013-08-22 16:01:31 +0000569 m_frame.navigationScheduler().cancel();
570 m_frame.editor().clearLastEditCommand();
darinc370e7e2006-11-08 05:52:27 +0000571
572 m_isComplete = false;
ggarena57755c2007-07-09 21:08:10 +0000573 m_didCallImplicitClose = false;
darinc370e7e2006-11-08 05:52:27 +0000574
ap@webkit.orgfbfb0f92009-05-08 07:58:08 +0000575 // If we are still in the process of initializing an empty document then
576 // its frame is not in a consistent state for rendering, so avoid setJSStatusBarText
577 // since it may cause clients to attempt to render the frame.
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +0000578 if (!m_stateMachine.creatingInitialEmptyDocument()) {
akling@apple.com7f50aae2013-08-22 16:01:31 +0000579 DOMWindow* window = m_frame.document()->domWindow();
abarth@webkit.org13fe1e22012-08-16 22:29:48 +0000580 window->setStatus(String());
581 window->setDefaultStatus(String());
ap@webkit.orgfbfb0f92009-05-08 07:58:08 +0000582 }
darinc370e7e2006-11-08 05:52:27 +0000583
584 started();
585
586 return true;
587}
588
ap@webkit.orga0a19872008-02-05 09:34:18 +0000589void FrameLoader::didExplicitOpen()
darinc370e7e2006-11-08 05:52:27 +0000590{
591 m_isComplete = false;
ggarena57755c2007-07-09 21:08:10 +0000592 m_didCallImplicitClose = false;
darinc370e7e2006-11-08 05:52:27 +0000593
andersca@apple.com1752dba2007-12-14 22:06:50 +0000594 // Calling document.open counts as committing the first real document load.
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +0000595 if (!m_stateMachine.committedFirstRealDocumentLoad())
596 m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
cdumez@apple.com0af95e32019-04-16 23:07:35 +0000597
598 m_client.dispatchDidExplicitOpen(m_frame.document() ? m_frame.document()->url() : URL());
andersca@apple.com1752dba2007-12-14 22:06:50 +0000599
darinc370e7e2006-11-08 05:52:27 +0000600 // Prevent window.open(url) -- eg window.open("about:blank") -- from blowing away results
601 // from a subsequent window.document.open / window.document.write call.
dbates@webkit.orgef42d382010-01-25 19:20:06 +0000602 // Canceling redirection here works for all cases because document.open
darinc370e7e2006-11-08 05:52:27 +0000603 // implicitly precedes document.write.
akling@apple.com7f50aae2013-08-22 16:01:31 +0000604 m_frame.navigationScheduler().cancel();
darinc370e7e2006-11-08 05:52:27 +0000605}
606
darinc370e7e2006-11-08 05:52:27 +0000607
608void FrameLoader::cancelAndClear()
609{
akling@apple.com7f50aae2013-08-22 16:01:31 +0000610 m_frame.navigationScheduler().cancel();
darinc370e7e2006-11-08 05:52:27 +0000611
612 if (!m_isComplete)
613 closeURL();
614
akling@apple.com7f50aae2013-08-22 16:01:31 +0000615 clear(m_frame.document(), false);
616 m_frame.script().updatePlatformScriptObjects();
darinc370e7e2006-11-08 05:52:27 +0000617}
618
aestes@apple.com408782b2016-11-29 18:40:55 +0000619static inline bool shouldClearWindowName(const Frame& frame, const Document& newDocument)
620{
621 if (!frame.isMainFrame())
622 return false;
623
624 if (frame.loader().opener())
625 return false;
626
akling@apple.com6be0e972017-01-18 19:35:49 +0000627 return !newDocument.securityOrigin().isSameOriginAs(frame.document()->securityOrigin());
aestes@apple.com408782b2016-11-29 18:40:55 +0000628}
629
beidson@apple.comdc5cfa42019-07-01 20:29:20 +0000630void FrameLoader::clear(Document* newDocument, bool clearWindowProperties, bool clearScriptObjects, bool clearFrameView, WTF::Function<void()>&& handleDOMWindowCreation)
darinc370e7e2006-11-08 05:52:27 +0000631{
akling@apple.com7f50aae2013-08-22 16:01:31 +0000632 m_frame.editor().clear();
darinc370e7e2006-11-08 05:52:27 +0000633
beidson@apple.comdc5cfa42019-07-01 20:29:20 +0000634 bool neededClear = m_needsClear;
darinc370e7e2006-11-08 05:52:27 +0000635 m_needsClear = false;
beidson@apple.comdc5cfa42019-07-01 20:29:20 +0000636
cdumez@apple.com9265dfe2019-10-17 01:44:16 +0000637 if (neededClear && m_frame.document()->backForwardCacheState() != Document::InBackForwardCache) {
akling@apple.com7f50aae2013-08-22 16:01:31 +0000638 m_frame.document()->cancelParsing();
639 m_frame.document()->stopActiveDOMObjects();
timothy_horton@apple.com70d58d82014-07-26 18:45:04 +0000640 bool hadLivingRenderTree = m_frame.document()->hasLivingRenderTree();
641 m_frame.document()->prepareForDestruction();
642 if (hadLivingRenderTree)
simon.fraser@apple.com87cf1662018-09-08 20:19:22 +0000643 m_frame.document()->adjustFocusedNodeOnNodeRemoval(*m_frame.document());
darinc370e7e2006-11-08 05:52:27 +0000644 }
645
beidson@apple.comdc5cfa42019-07-01 20:29:20 +0000646 if (handleDOMWindowCreation)
647 handleDOMWindowCreation();
648
649 if (!neededClear)
650 return;
651
darinc370e7e2006-11-08 05:52:27 +0000652 // Do this after detaching the document so that the unload event works.
thatchera1e24df2007-09-14 23:53:29 +0000653 if (clearWindowProperties) {
commit-queue@webkit.org8599a762016-11-01 21:42:51 +0000654 InspectorInstrumentation::frameWindowDiscarded(m_frame, m_frame.document()->domWindow());
commit-queue@webkit.org8af5d212015-12-01 01:55:43 +0000655 m_frame.document()->domWindow()->resetUnlessSuspendedForDocumentSuspension();
cdumez@apple.com9265dfe2019-10-17 01:44:16 +0000656 m_frame.windowProxy().clearJSWindowProxiesNotMatchingDOMWindow(newDocument->domWindow(), m_frame.document()->backForwardCacheState() == Document::AboutToEnterBackForwardCache);
aestes@apple.com408782b2016-11-29 18:40:55 +0000657
658 if (shouldClearWindowName(m_frame, *newDocument))
utatane.tea@gmail.comc4579a02017-07-07 04:42:04 +0000659 m_frame.tree().setName(nullAtom());
weinigf9307632007-07-18 05:40:54 +0000660 }
darinc370e7e2006-11-08 05:52:27 +0000661
akling@apple.com7f50aae2013-08-22 16:01:31 +0000662 m_frame.selection().prepareForDestruction();
achristensen@apple.com09e70aa2017-04-27 16:42:13 +0000663 m_frame.eventHandler().clear();
bfulgham@apple.com46bde7c2016-04-07 21:15:34 +0000664
akling@apple.com7f50aae2013-08-22 16:01:31 +0000665 if (clearFrameView && m_frame.view())
666 m_frame.view()->clear();
eric@webkit.org0683d942008-08-06 10:01:35 +0000667
eric@webkit.org0683d942008-08-06 10:01:35 +0000668 // Do not drop the document before the ScriptController and view are cleared
669 // as some destructors might still try to access the document.
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +0000670 m_frame.setDocument(nullptr);
darinc370e7e2006-11-08 05:52:27 +0000671
akling@apple.com7f81b1e2013-09-06 17:23:03 +0000672 subframeLoader().clear();
eric@webkit.org0683d942008-08-06 10:01:35 +0000673
bfulgham@apple.com472a0342017-01-04 22:35:44 +0000674 if (clearWindowProperties)
cdumez@apple.com87a798a2018-04-19 04:02:30 +0000675 m_frame.windowProxy().setDOMWindow(newDocument->domWindow());
bfulgham@apple.com472a0342017-01-04 22:35:44 +0000676
antti90500a32007-09-27 23:56:17 +0000677 if (clearScriptObjects)
akling@apple.com7f50aae2013-08-22 16:01:31 +0000678 m_frame.script().clearScriptObjects();
eric@webkit.org0683d942008-08-06 10:01:35 +0000679
akling@apple.com7f50aae2013-08-22 16:01:31 +0000680 m_frame.script().enableEval();
abarth@webkit.org9d220b62012-06-09 19:35:02 +0000681
akling@apple.com7f50aae2013-08-22 16:01:31 +0000682 m_frame.navigationScheduler().clear();
darinc370e7e2006-11-08 05:52:27 +0000683
darin@apple.comf53381b2009-09-23 23:27:01 +0000684 m_checkTimer.stop();
685 m_shouldCallCheckCompleted = false;
686 m_shouldCallCheckLoadComplete = false;
abarth@webkit.org91289c32010-04-12 04:54:55 +0000687
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +0000688 if (m_stateMachine.isDisplayingInitialEmptyDocument() && m_stateMachine.committedFirstRealDocumentLoad())
689 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
darinc370e7e2006-11-08 05:52:27 +0000690}
691
692void FrameLoader::receivedFirstData()
693{
cdumez@apple.com8b7a0222018-12-20 04:41:11 +0000694 dispatchDidCommitLoad(WTF::nullopt);
jcivelli@chromium.org4b94add2011-11-19 08:45:01 +0000695 dispatchDidClearWindowObjectsInAllWorlds();
beidson@apple.com2a75a962012-04-24 18:12:55 +0000696 dispatchGlobalObjectAvailableInAllWorlds();
jcivelli@chromium.org4b94add2011-11-19 08:45:01 +0000697
darin8207db42007-02-20 18:18:39 +0000698 if (!m_documentLoader)
699 return;
abarth@webkit.org55d49da2011-06-20 23:32:54 +0000700
dbates@webkit.org66024662018-02-03 04:53:47 +0000701 auto& documentLoader = *m_documentLoader;
702 auto& title = documentLoader.title();
703 if (!title.string.isNull())
704 m_client.dispatchDidReceiveTitle(title);
705
darin@apple.comc04189e2017-01-18 05:17:17 +0000706 ASSERT(m_frame.document());
707 auto& document = *m_frame.document();
708
dbates@webkit.org66024662018-02-03 04:53:47 +0000709 LinkLoader::loadLinksFromHeader(documentLoader.response().httpHeaderField(HTTPHeaderName::Link), document.url(), document, LinkLoader::MediaAttributeCheck::MediaAttributeEmpty);
yoav@yoav.ws1c12d5c2017-01-19 07:13:54 +0000710
abarth@webkit.org55d49da2011-06-20 23:32:54 +0000711 double delay;
darin@apple.com47a20cb2014-04-27 16:06:27 +0000712 String urlString;
cdumez@apple.com63b7fdd2019-09-12 04:32:29 +0000713 if (!parseMetaHTTPEquivRefresh(documentLoader.response().httpHeaderField(HTTPHeaderName::Refresh), delay, urlString))
ape9991d52006-12-08 18:19:51 +0000714 return;
darin@apple.comc04189e2017-01-18 05:17:17 +0000715 auto completedURL = urlString.isEmpty() ? document.url() : document.completeURL(urlString);
keith_miller@apple.combb2f61c2018-12-01 03:28:36 +0000716 if (!WTF::protocolIsJavaScript(completedURL))
darin@apple.comc04189e2017-01-18 05:17:17 +0000717 m_frame.navigationScheduler().scheduleRedirect(document, delay, completedURL);
ddkilzer@apple.com70f15392014-04-01 19:21:34 +0000718 else {
darin@apple.comc04189e2017-01-18 05:17:17 +0000719 auto message = "Refused to refresh " + document.url().stringCenterEllipsizedToLength() + " to a javascript: URL";
dbates@webkit.org66024662018-02-03 04:53:47 +0000720 document.addConsoleMessage(MessageSource::Security, MessageLevel::Error, message);
ddkilzer@apple.com70f15392014-04-01 19:21:34 +0000721 }
darinc370e7e2006-11-08 05:52:27 +0000722}
723
darin@apple.com5ffbb5c2013-09-27 16:39:41 +0000724void FrameLoader::setOutgoingReferrer(const URL& url)
japhet@chromium.orgb254c9b2011-01-26 19:14:26 +0000725{
levin@chromium.org1a2fef42011-03-01 02:10:28 +0000726 m_outgoingReferrer = url.strippedForUseAsReferrer();
abarth@webkit.org412c54e2010-04-20 22:12:16 +0000727}
abarth@webkit.org91289c32010-04-12 04:54:55 +0000728
dbates@webkit.org123b1af2019-09-23 21:56:43 +0000729void FrameLoader::didBeginDocument(bool dispatch)
abarth@webkit.org412c54e2010-04-20 22:12:16 +0000730{
731 m_needsClear = true;
732 m_isComplete = false;
733 m_didCallImplicitClose = false;
akling@apple.com7f50aae2013-08-22 16:01:31 +0000734 m_frame.document()->setReadyState(Document::Loading);
abarth@webkit.org91289c32010-04-12 04:54:55 +0000735
736 if (m_pendingStateObject) {
darin@apple.com961f2a52016-12-31 09:51:29 +0000737 m_frame.document()->statePopped(*m_pendingStateObject);
cdumez@apple.comd839ea12015-07-04 19:42:18 +0000738 m_pendingStateObject = nullptr;
abarth@webkit.org91289c32010-04-12 04:54:55 +0000739 }
abarth@webkit.org91289c32010-04-12 04:54:55 +0000740
andersca@apple.com6c6fb4b2009-08-12 22:03:02 +0000741 if (dispatch)
aroben@apple.com11dd5262009-11-13 23:49:05 +0000742 dispatchDidClearWindowObjectsInAllWorlds();
abarth@webkit.org412c54e2010-04-20 22:12:16 +0000743
abarth@webkit.org622d9df2009-05-22 16:44:47 +0000744 updateFirstPartyForCookies();
dbates@webkit.org123b1af2019-09-23 21:56:43 +0000745 m_frame.document()->initContentSecurityPolicy();
darinc370e7e2006-11-08 05:52:27 +0000746
akling@apple.com1c29edbc2013-08-23 23:19:21 +0000747 const Settings& settings = m_frame.settings();
cdumez@apple.com0bb03ec2015-01-28 05:53:53 +0000748 m_frame.document()->cachedResourceLoader().setImagesEnabled(settings.areImagesEnabled());
749 m_frame.document()->cachedResourceLoader().setAutoLoadImages(settings.loadsImagesAutomatically());
aroben@apple.com3adf2452008-02-07 23:19:31 +0000750
collinj@webkit.org9c672f62008-09-19 04:15:14 +0000751 if (m_documentLoader) {
andersca@apple.com30391b42014-06-16 19:26:49 +0000752 String dnsPrefetchControl = m_documentLoader->response().httpHeaderField(HTTPHeaderName::XDNSPrefetchControl);
collinj@webkit.org9c672f62008-09-19 04:15:14 +0000753 if (!dnsPrefetchControl.isEmpty())
akling@apple.com7f50aae2013-08-22 16:01:31 +0000754 m_frame.document()->parseDNSPrefetchControlHeader(dnsPrefetchControl);
jochen@chromium.orgadec40f2011-02-09 17:03:38 +0000755
dbates@webkit.org41f504e2018-05-07 17:52:34 +0000756 m_frame.document()->contentSecurityPolicy()->didReceiveHeaders(ContentSecurityPolicyResponseHeaders(m_documentLoader->response()), referrer(), ContentSecurityPolicy::ReportParsingErrors::No);
commit-queue@webkit.org26a3a092012-10-18 19:53:58 +0000757
cdumez@apple.com7c12c6c2018-05-30 21:30:21 +0000758 String referrerPolicy = m_documentLoader->response().httpHeaderField(HTTPHeaderName::ReferrerPolicy);
759 if (!referrerPolicy.isNull())
760 m_frame.document()->processReferrerPolicy(referrerPolicy, ReferrerPolicySource::HTTPHeader);
761
andersca@apple.com30391b42014-06-16 19:26:49 +0000762 String headerContentLanguage = m_documentLoader->response().httpHeaderField(HTTPHeaderName::ContentLanguage);
commit-queue@webkit.org26a3a092012-10-18 19:53:58 +0000763 if (!headerContentLanguage.isEmpty()) {
764 size_t commaIndex = headerContentLanguage.find(',');
765 headerContentLanguage.truncate(commaIndex); // notFound == -1 == don't truncate
darin@apple.com940b9ea2017-11-25 02:44:45 +0000766 headerContentLanguage = stripLeadingAndTrailingHTMLSpaces(headerContentLanguage);
commit-queue@webkit.org26a3a092012-10-18 19:53:58 +0000767 if (!headerContentLanguage.isEmpty())
akling@apple.com7f50aae2013-08-22 16:01:31 +0000768 m_frame.document()->setContentLanguage(headerContentLanguage);
commit-queue@webkit.org26a3a092012-10-18 19:53:58 +0000769 }
collinj@webkit.org9c672f62008-09-19 04:15:14 +0000770 }
771
akling@apple.com672cb852013-08-22 20:27:27 +0000772 history().restoreDocumentState();
darinc370e7e2006-11-08 05:52:27 +0000773}
774
darinc370e7e2006-11-08 05:52:27 +0000775void FrameLoader::finishedParsing()
776{
simon.fraser@apple.com677f0422017-12-02 17:55:24 +0000777 LOG(Loading, "WebCoreLoading %s: Finished parsing", m_frame.tree().uniqueName().string().utf8().data());
778
akling@apple.com7f50aae2013-08-22 16:01:31 +0000779 m_frame.injectUserScripts(InjectAtDocumentEnd);
aestes@apple.come35644e2011-04-07 20:23:48 +0000780
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +0000781 if (m_stateMachine.creatingInitialEmptyDocument())
mjs8d620d52007-05-10 12:31:42 +0000782 return;
783
darinc370e7e2006-11-08 05:52:27 +0000784 // This can be called from the Frame's destructor, in which case we shouldn't protect ourselves
785 // 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 +0000786 // Null-checking the FrameView indicates whether or not we're in the destructor.
akling@apple.com7f50aae2013-08-22 16:01:31 +0000787 RefPtr<Frame> protector = m_frame.view() ? &m_frame : 0;
darinc370e7e2006-11-08 05:52:27 +0000788
akling@apple.com7f50aae2013-08-22 16:01:31 +0000789 m_client.dispatchDidFinishDocumentLoad();
darin@chromium.org1750e242008-12-08 18:13:25 +0000790
cdumez@apple.com6d7c65e2015-09-02 17:07:57 +0000791 scrollToFragmentWithParentBoundary(m_frame.document()->url());
792
darinc370e7e2006-11-08 05:52:27 +0000793 checkCompleted();
794
akling@apple.com7f50aae2013-08-22 16:01:31 +0000795 if (!m_frame.view())
darinc370e7e2006-11-08 05:52:27 +0000796 return; // We are being destroyed by something checkCompleted called.
797
798 // Check if the scrollbars are really needed for the content.
799 // If not, remove them, relayout, and repaint.
akling@apple.com7f50aae2013-08-22 16:01:31 +0000800 m_frame.view()->restoreScrollbar();
darinc370e7e2006-11-08 05:52:27 +0000801}
802
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +0000803void FrameLoader::loadDone(LoadCompletionType type)
darinc370e7e2006-11-08 05:52:27 +0000804{
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +0000805 if (type == LoadCompletionType::Finish)
806 checkCompleted();
807 else
808 scheduleCheckCompleted();
809}
810
811void FrameLoader::subresourceLoadDone(LoadCompletionType type)
812{
813 if (type == LoadCompletionType::Finish)
814 checkLoadComplete();
815 else
816 scheduleCheckLoadComplete();
darinc370e7e2006-11-08 05:52:27 +0000817}
818
darin@apple.com4d9d7182009-09-23 00:38:04 +0000819bool FrameLoader::allChildrenAreComplete() const
820{
darin@apple.comfed4d162013-08-25 02:28:06 +0000821 for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling()) {
andersca@apple.comdf550b92013-08-15 22:17:17 +0000822 if (!child->loader().m_isComplete)
darin@apple.com4d9d7182009-09-23 00:38:04 +0000823 return false;
824 }
825 return true;
826}
827
darin@apple.comf53381b2009-09-23 23:27:01 +0000828bool FrameLoader::allAncestorsAreComplete() const
829{
darin@apple.comfed4d162013-08-25 02:28:06 +0000830 for (Frame* ancestor = &m_frame; ancestor; ancestor = ancestor->tree().parent()) {
andersca@apple.comdf550b92013-08-15 22:17:17 +0000831 if (!ancestor->loader().m_isComplete)
darin@apple.comf53381b2009-09-23 23:27:01 +0000832 return false;
833 }
834 return true;
835}
836
darinc370e7e2006-11-08 05:52:27 +0000837void FrameLoader::checkCompleted()
838{
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +0000839 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isScriptAllowed());
darin@apple.comf53381b2009-09-23 23:27:01 +0000840 m_shouldCallCheckCompleted = false;
841
darinc370e7e2006-11-08 05:52:27 +0000842 // Have we completed before?
843 if (m_isComplete)
844 return;
rniwa@webkit.orgfcdf9db2018-05-04 23:58:04 +0000845
commit-queue@webkit.org4e024c52018-05-21 17:50:04 +0000846#if ENABLE(VIDEO)
rniwa@webkit.orgfcdf9db2018-05-04 23:58:04 +0000847 // FIXME: Remove this code once https://webkit.org/b/185284 is fixed.
848 if (HTMLMediaElement::isRunningDestructor()) {
849 ASSERT_NOT_REACHED();
850 scheduleCheckCompleted();
851 return;
852 }
commit-queue@webkit.org4e024c52018-05-21 17:50:04 +0000853#endif
darinc370e7e2006-11-08 05:52:27 +0000854
antti@apple.com079cbf52017-05-05 18:39:30 +0000855 // FIXME: It would be better if resource loads were kicked off after render tree update (or didn't complete synchronously).
856 // https://bugs.webkit.org/show_bug.cgi?id=171729
857 if (m_frame.document()->inRenderTreeUpdate()) {
858 scheduleCheckCompleted();
859 return;
860 }
861
darinc370e7e2006-11-08 05:52:27 +0000862 // Are we still parsing?
akling@apple.com7f50aae2013-08-22 16:01:31 +0000863 if (m_frame.document()->parsing())
darinc370e7e2006-11-08 05:52:27 +0000864 return;
865
866 // Still waiting for images/scripts?
cdumez@apple.com0bb03ec2015-01-28 05:53:53 +0000867 if (m_frame.document()->cachedResourceLoader().requestCount())
ap@webkit.orgf9b6eff2009-02-10 17:33:33 +0000868 return;
darinc370e7e2006-11-08 05:52:27 +0000869
eric.carlson@apple.com9c7fc722010-08-26 16:45:43 +0000870 // Still waiting for elements that don't go through a FrameLoader?
akling@apple.com7f50aae2013-08-22 16:01:31 +0000871 if (m_frame.document()->isDelayingLoadEvent())
eric.carlson@apple.com9c7fc722010-08-26 16:45:43 +0000872 return;
873
antti@apple.com9f4e3b22017-02-19 12:12:07 +0000874 auto* scriptableParser = m_frame.document()->scriptableDocumentParser();
875 if (scriptableParser && scriptableParser->hasScriptsWaitingForStylesheets())
876 return;
877
andreas.kling@nokia.com01f92442011-02-28 13:46:06 +0000878 // Any frame that hasn't completed yet?
879 if (!allChildrenAreComplete())
880 return;
881
darin@apple.comc2843002014-04-25 06:01:34 +0000882 // Important not to protect earlier in this function, because earlier parts
darin@apple.comfe9effd2014-04-25 06:02:42 +0000883 // of this function can be called in the frame's destructor, and it's not legal
darin@apple.comc2843002014-04-25 06:01:34 +0000884 // to ref an object while it's being destroyed.
885 Ref<Frame> protect(m_frame);
886
darinc370e7e2006-11-08 05:52:27 +0000887 // OK, completed.
888 m_isComplete = true;
cdumez@apple.comd839ea12015-07-04 19:42:18 +0000889 m_requestedHistoryItem = nullptr;
akling@apple.com7f50aae2013-08-22 16:01:31 +0000890 m_frame.document()->setReadyState(Document::Complete);
darinc370e7e2006-11-08 05:52:27 +0000891
ap@apple.com1e8475922018-10-18 21:38:50 +0000892#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +0000893 if (m_frame.document()->url().isEmpty()) {
894 // We need to update the document URL of a PDF document to be non-empty so that both back/forward history navigation
895 // between PDF pages and fragment navigation works. See <rdar://problem/9544769> for more details.
896 // FIXME: Is there a better place for this code, say DocumentLoader? Also, we should explicitly only update the URL
897 // of the document when it's a PDFDocument object instead of assuming that a Document object with an empty URL is a PDFDocument.
898 // FIXME: This code is incorrect for a synthesized document (which also has an empty URL). The URL for a synthesized
899 // document should be the URL specified to FrameLoader::initForSynthesizedDocument().
900 m_frame.document()->setURL(activeDocumentLoader()->documentURL());
901 }
902#endif
903
ggarena57755c2007-07-09 21:08:10 +0000904 checkCallImplicitClose(); // if we didn't do it before
darinc370e7e2006-11-08 05:52:27 +0000905
akling@apple.com7f50aae2013-08-22 16:01:31 +0000906 m_frame.navigationScheduler().startTimer();
darinc370e7e2006-11-08 05:52:27 +0000907
908 completed();
akling@apple.com7f50aae2013-08-22 16:01:31 +0000909 if (m_frame.page())
mjs8d620d52007-05-10 12:31:42 +0000910 checkLoadComplete();
darinc370e7e2006-11-08 05:52:27 +0000911}
912
andersca@apple.com574a7452014-11-21 20:10:13 +0000913void FrameLoader::checkTimerFired()
weinigc34c71c2007-03-09 16:05:37 +0000914{
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +0000915 checkCompletenessNow();
916}
917
918void FrameLoader::checkCompletenessNow()
919{
akling@apple.comf8515982013-09-02 18:50:01 +0000920 Ref<Frame> protect(m_frame);
commit-queue@webkit.org667ee8b2012-02-08 02:21:04 +0000921
akling@apple.com7f50aae2013-08-22 16:01:31 +0000922 if (Page* page = m_frame.page()) {
darin@apple.comf53381b2009-09-23 23:27:01 +0000923 if (page->defersLoading())
924 return;
925 }
926 if (m_shouldCallCheckCompleted)
927 checkCompleted();
928 if (m_shouldCallCheckLoadComplete)
929 checkLoadComplete();
930}
931
932void FrameLoader::startCheckCompleteTimer()
933{
934 if (!(m_shouldCallCheckCompleted || m_shouldCallCheckLoadComplete))
935 return;
936 if (m_checkTimer.isActive())
937 return;
cdumez@apple.combc919b02017-04-09 14:49:14 +0000938 m_checkTimer.startOneShot(0_s);
weinigc34c71c2007-03-09 16:05:37 +0000939}
940
941void FrameLoader::scheduleCheckCompleted()
942{
darin@apple.comf53381b2009-09-23 23:27:01 +0000943 m_shouldCallCheckCompleted = true;
944 startCheckCompleteTimer();
beidson398923b2007-07-31 20:29:02 +0000945}
946
947void FrameLoader::scheduleCheckLoadComplete()
948{
darin@apple.comf53381b2009-09-23 23:27:01 +0000949 m_shouldCallCheckLoadComplete = true;
950 startCheckCompleteTimer();
beidson398923b2007-07-31 20:29:02 +0000951}
952
ggarena57755c2007-07-09 21:08:10 +0000953void FrameLoader::checkCallImplicitClose()
darinc370e7e2006-11-08 05:52:27 +0000954{
akling@apple.com7f50aae2013-08-22 16:01:31 +0000955 if (m_didCallImplicitClose || m_frame.document()->parsing() || m_frame.document()->isDelayingLoadEvent())
darinc370e7e2006-11-08 05:52:27 +0000956 return;
957
darin@apple.com4d9d7182009-09-23 00:38:04 +0000958 if (!allChildrenAreComplete())
959 return; // still got a frame running -> too early
darinc370e7e2006-11-08 05:52:27 +0000960
ggarena57755c2007-07-09 21:08:10 +0000961 m_didCallImplicitClose = true;
darinc370e7e2006-11-08 05:52:27 +0000962 m_wasUnloadEventEmitted = false;
akling@apple.com7f50aae2013-08-22 16:01:31 +0000963 m_frame.document()->implicitClose();
darinc370e7e2006-11-08 05:52:27 +0000964}
965
darin@apple.com5ffbb5c2013-09-27 16:39:41 +0000966void FrameLoader::loadURLIntoChildFrame(const URL& url, const String& referer, Frame* childFrame)
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000967{
krollin@apple.come1810b62018-12-20 19:23:20 +0000968 RELEASE_LOG_IF_ALLOWED("loadURLIntoChildFrame: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
969
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000970 ASSERT(childFrame);
darin@apple.coma7e141f2009-03-06 17:22:07 +0000971
jcivelli@chromium.orgc2019dd2011-05-24 19:32:03 +0000972#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
darin@apple.com961f2a52016-12-31 09:51:29 +0000973 if (auto activeLoader = activeDocumentLoader()) {
974 if (auto subframeArchive = activeLoader->popArchiveForSubframe(childFrame->tree().uniqueName(), url)) {
975 childFrame->loader().loadArchive(RefPtr<Archive> { subframeArchive }.releaseNonNull());
976 return;
977 }
mihaip@chromium.orge5dbd372010-12-08 02:32:41 +0000978 }
darin@apple.com961f2a52016-12-31 09:51:29 +0000979#endif
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000980
darin@apple.coma7e141f2009-03-06 17:22:07 +0000981 // If we're moving in the back/forward list, we might want to replace the content
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000982 // of this child frame with whatever was there at that point.
darin@apple.com961f2a52016-12-31 09:51:29 +0000983 auto* parentItem = history().currentItem();
984 if (parentItem && parentItem->children().size() && isBackForwardLoadType(loadType()) && !m_frame.document()->loadEventFinished()) {
985 if (auto* childItem = parentItem->childItemWithTarget(childFrame->tree().uniqueName())) {
ap@apple.com4d286a92013-08-19 23:41:18 +0000986 childFrame->loader().m_requestedHistoryItem = childItem;
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +0000987 childFrame->loader().loadDifferentDocumentItem(*childItem, nullptr, loadType(), MayAttemptCacheOnlyLoadForFormSubmissionItem, ShouldTreatAsContinuingLoad::No);
mihaip@chromium.orge5dbd372010-12-08 02:32:41 +0000988 return;
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000989 }
990 }
991
beidson@apple.com7034ec72017-07-06 00:01:53 +0000992 auto* lexicalFrame = lexicalFrameFromCommonVM();
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +0000993 auto initiatedByMainFrame = lexicalFrame && lexicalFrame->isMainFrame() ? InitiatedByMainFrame::Yes : InitiatedByMainFrame::Unknown;
beidson@apple.com7034ec72017-07-06 00:01:53 +0000994
utatane.tea@gmail.com84077632018-06-23 08:39:34 +0000995 FrameLoadRequest frameLoadRequest { *m_frame.document(), m_frame.document()->securityOrigin(), { url }, "_self"_s, LockHistory::No, LockBackForwardList::Yes, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ShouldOpenExternalURLsPolicy::ShouldNotAllow, initiatedByMainFrame };
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +0000996 childFrame->loader().loadURL(WTFMove(frameLoadRequest), referer, FrameLoadType::RedirectWithLockedBackForwardList, nullptr, { }, WTF::nullopt, [] { });
beidson@apple.com47ef96f2015-05-29 16:38:13 +0000997}
beidson@apple.comf36a4a12008-03-25 17:11:16 +0000998
jcivelli@chromium.orgc2019dd2011-05-24 19:32:03 +0000999#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
darin@apple.com961f2a52016-12-31 09:51:29 +00001000
1001void FrameLoader::loadArchive(Ref<Archive>&& archive)
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001002{
krollin@apple.come1810b62018-12-20 19:23:20 +00001003 RELEASE_LOG_IF_ALLOWED("loadArchive: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
1004
japhet@chromium.orgac5cd4b2012-04-12 19:27:28 +00001005 ArchiveResource* mainResource = archive->mainResource();
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001006 ASSERT(mainResource);
1007 if (!mainResource)
1008 return;
beidson@apple.comceb7cba2015-05-19 22:22:51 +00001009
jh718.park@samsung.com9f99af52016-03-15 00:22:45 +00001010 ResourceResponse response(URL(), mainResource->mimeType(), mainResource->data().size(), mainResource->textEncoding());
1011 SubstituteData substituteData(&mainResource->data(), URL(), response, SubstituteData::SessionHistoryVisibility::Hidden);
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001012
1013 ResourceRequest request(mainResource->url());
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001014
darin@apple.com961f2a52016-12-31 09:51:29 +00001015 auto documentLoader = m_client.createDocumentLoader(request, substituteData);
1016 documentLoader->setArchive(WTFMove(archive));
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001017 load(documentLoader.get());
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001018}
darin@apple.com961f2a52016-12-31 09:51:29 +00001019
jcivelli@chromium.orgc2019dd2011-05-24 19:32:03 +00001020#endif // ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
beidson@apple.comf36a4a12008-03-25 17:11:16 +00001021
darinc370e7e2006-11-08 05:52:27 +00001022String FrameLoader::outgoingReferrer() const
1023{
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001024 // See http://www.whatwg.org/specs/web-apps/current-work/#fetching-resources
1025 // for why we walk the parent chain for srcdoc documents.
akling@apple.com7f50aae2013-08-22 16:01:31 +00001026 Frame* frame = &m_frame;
antti@apple.com1f5a2462016-12-14 18:54:28 +00001027 while (frame && frame->document()->isSrcdocDocument()) {
darin@apple.comfed4d162013-08-25 02:28:06 +00001028 frame = frame->tree().parent();
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001029 // Srcdoc documents cannot be top-level documents, by definition,
1030 // because they need to be contained in iframes with the srcdoc.
1031 ASSERT(frame);
1032 }
antti@apple.com1f5a2462016-12-14 18:54:28 +00001033 if (!frame)
1034 return emptyString();
andersca@apple.comdf550b92013-08-15 22:17:17 +00001035 return frame->loader().m_outgoingReferrer;
darinc370e7e2006-11-08 05:52:27 +00001036}
1037
abarth@webkit.orgfb074382008-10-05 19:12:30 +00001038String FrameLoader::outgoingOrigin() const
1039{
akling@apple.com6be0e972017-01-18 19:35:49 +00001040 return m_frame.document()->securityOrigin().toString();
abarth@webkit.orgfb074382008-10-05 19:12:30 +00001041}
1042
dbates@webkit.org28db74a2016-04-15 22:23:44 +00001043bool FrameLoader::checkIfFormActionAllowedByCSP(const URL& url, bool didReceiveRedirectResponse) const
commit-queue@webkit.org78e860e2012-08-16 12:42:09 +00001044{
1045 if (m_submittedFormURL.isEmpty())
1046 return true;
1047
dbates@webkit.org28db74a2016-04-15 22:23:44 +00001048 auto redirectResponseReceived = didReceiveRedirectResponse ? ContentSecurityPolicy::RedirectResponseReceived::Yes : ContentSecurityPolicy::RedirectResponseReceived::No;
commit-queue@webkit.org03af1952016-09-22 08:28:37 +00001049 return m_frame.document()->contentSecurityPolicy()->allowFormAction(url, redirectResponseReceived);
commit-queue@webkit.org78e860e2012-08-16 12:42:09 +00001050}
1051
darinc370e7e2006-11-08 05:52:27 +00001052Frame* FrameLoader::opener()
1053{
1054 return m_opener;
1055}
1056
1057void FrameLoader::setOpener(Frame* opener)
1058{
creis@chromium.org16d76c72012-12-04 17:39:26 +00001059 if (m_opener && !opener)
akling@apple.com7f50aae2013-08-22 16:01:31 +00001060 m_client.didDisownOpener();
creis@chromium.org16d76c72012-12-04 17:39:26 +00001061
rniwa@webkit.org2c6d4eb2017-07-01 21:26:31 +00001062 if (m_opener) {
1063 // When setOpener is called in ~FrameLoader, opener's m_frameLoader is already cleared.
1064 auto& openerFrameLoader = m_opener == &m_frame ? *this : m_opener->loader();
1065 openerFrameLoader.m_openedFrames.remove(&m_frame);
1066 }
cdumez@apple.com2e472362018-12-01 22:40:07 +00001067 if (opener) {
akling@apple.com7f50aae2013-08-22 16:01:31 +00001068 opener->loader().m_openedFrames.add(&m_frame);
cdumez@apple.com2e472362018-12-01 22:40:07 +00001069 if (auto* page = m_frame.page())
1070 page->setOpenedByDOMWithOpener();
1071 }
darinc370e7e2006-11-08 05:52:27 +00001072 m_opener = opener;
weinig343b6ff2007-08-07 03:08:53 +00001073
akling@apple.com7f50aae2013-08-22 16:01:31 +00001074 if (m_frame.document())
1075 m_frame.document()->initSecurityContext();
darinc370e7e2006-11-08 05:52:27 +00001076}
1077
eric@webkit.org4ffb1fe2010-09-03 04:28:12 +00001078// FIXME: This does not belong in FrameLoader!
darinc370e7e2006-11-08 05:52:27 +00001079void FrameLoader::handleFallbackContent()
1080{
akling@apple.com7f50aae2013-08-22 16:01:31 +00001081 HTMLFrameOwnerElement* owner = m_frame.ownerElement();
cdumez@apple.coma9c60c92014-10-02 19:39:41 +00001082 if (!is<HTMLObjectElement>(owner))
darinc370e7e2006-11-08 05:52:27 +00001083 return;
cdumez@apple.com72754ba2014-09-23 22:03:15 +00001084 downcast<HTMLObjectElement>(*owner).renderFallbackContent();
darinc370e7e2006-11-08 05:52:27 +00001085}
1086
1087void FrameLoader::provisionalLoadStarted()
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00001088{
1089 if (m_stateMachine.firstLayoutDone())
1090 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
achristensen@apple.com6fddc912018-10-18 21:16:52 +00001091 m_frame.navigationScheduler().cancel(NewLoadInProgress::Yes);
akling@apple.com7f50aae2013-08-22 16:01:31 +00001092 m_client.provisionalLoadStarted();
cdumez@apple.comef2c0152017-01-13 17:54:53 +00001093
1094 if (m_frame.isMainFrame()) {
sbarati@apple.comce7ec112018-04-17 15:57:32 +00001095 tracePoint(MainResourceLoadDidStartProvisional);
simon.fraser@apple.com83325b92017-03-17 00:47:16 +00001096
cdumez@apple.comef2c0152017-01-13 17:54:53 +00001097 if (auto* page = m_frame.page())
1098 page->didStartProvisionalLoad();
1099 }
darinc370e7e2006-11-08 05:52:27 +00001100}
1101
darinc370e7e2006-11-08 05:52:27 +00001102void FrameLoader::resetMultipleFormSubmissionProtection()
1103{
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001104 m_submittedFormURL = URL();
darinc370e7e2006-11-08 05:52:27 +00001105}
1106
abarth@webkit.org622d9df2009-05-22 16:44:47 +00001107void FrameLoader::updateFirstPartyForCookies()
darinc370e7e2006-11-08 05:52:27 +00001108{
darin@apple.comfed4d162013-08-25 02:28:06 +00001109 if (m_frame.tree().parent())
1110 setFirstPartyForCookies(m_frame.tree().parent()->document()->firstPartyForCookies());
darinc370e7e2006-11-08 05:52:27 +00001111 else
akling@apple.com7f50aae2013-08-22 16:01:31 +00001112 setFirstPartyForCookies(m_frame.document()->url());
darinc370e7e2006-11-08 05:52:27 +00001113}
1114
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001115void FrameLoader::setFirstPartyForCookies(const URL& url)
darinc370e7e2006-11-08 05:52:27 +00001116{
darin@apple.comfed4d162013-08-25 02:28:06 +00001117 for (Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext(&m_frame))
darin@apple.comaf8b1a92011-06-25 00:09:37 +00001118 frame->document()->setFirstPartyForCookies(url);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00001119
cdumez@apple.com0b8674fb2019-03-13 19:53:41 +00001120 RegistrableDomain registrableDomain(url);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00001121 for (Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext(&m_frame)) {
cdumez@apple.com0b8674fb2019-03-13 19:53:41 +00001122 if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(frame->document()->url()) || registrableDomain.matches(frame->document()->url()))
dbates@webkit.org940f0b82018-07-24 16:27:25 +00001123 frame->document()->setSiteForCookies(url);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00001124 }
darinc370e7e2006-11-08 05:52:27 +00001125}
1126
darin@apple.comd69216d2008-03-11 00:45:47 +00001127// This does the same kind of work that didOpenURL does, except it relies on the fact
darinc370e7e2006-11-08 05:52:27 +00001128// 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 +00001129void FrameLoader::loadInSameDocument(const URL& url, SerializedScriptValue* stateObject, bool isNewNavigation)
darinc370e7e2006-11-08 05:52:27 +00001130{
krollin@apple.come1810b62018-12-20 19:23:20 +00001131 RELEASE_LOG_IF_ALLOWED("loadInSameDocument: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
1132
beidson@apple.com08c61752009-12-03 19:04:40 +00001133 // If we have a state object, we cannot also be a new navigation.
1134 ASSERT(!stateObject || (stateObject && !isNewNavigation));
1135
1136 // Update the data source's request with the new URL to fake the URL change
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001137 URL oldURL = m_frame.document()->url();
akling@apple.com7f50aae2013-08-22 16:01:31 +00001138 m_frame.document()->setURL(url);
jochen@chromium.org7495f962012-05-04 16:43:03 +00001139 setOutgoingReferrer(url);
beidson@apple.com08c61752009-12-03 19:04:40 +00001140 documentLoader()->replaceRequestURLForSameDocumentNavigation(url);
1141 if (isNewNavigation && !shouldTreatURLAsSameAsCurrent(url) && !stateObject) {
1142 // NB: must happen after replaceRequestURLForSameDocumentNavigation(), since we add
1143 // based on the current request. Must also happen before we openURL and displace the
1144 // scroll position, since adding the BF item will save away scroll state.
1145
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00001146 // NB2: If we were loading a long, slow doc, and the user fragment navigated before
beidson@apple.com08c61752009-12-03 19:04:40 +00001147 // it was done, currItem is now set the that slow doc, and prevItem is whatever was
1148 // before it. Adding the b/f item will bump the slow doc down to prevItem, even
1149 // though its load is not yet done. I think this all works out OK, for one because
1150 // we have already saved away the scroll and doc state for the long slow load,
1151 // but it's not an obvious case.
1152
akling@apple.com672cb852013-08-22 20:27:27 +00001153 history().updateBackForwardListForFragmentScroll();
beidson@apple.com8127cdc2009-08-07 15:35:19 +00001154 }
1155
japhet@chromium.orgb254c9b2011-01-26 19:14:26 +00001156 bool hashChange = equalIgnoringFragmentIdentifier(url, oldURL) && url.fragmentIdentifier() != oldURL.fragmentIdentifier();
beidson@apple.com43a414c2010-03-19 18:25:21 +00001157
akling@apple.com672cb852013-08-22 20:27:27 +00001158 history().updateForSameDocumentNavigation();
britto@apple.com195cc0b2008-07-23 16:48:47 +00001159
1160 // 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 +00001161 if (hashChange)
akling@apple.com7f50aae2013-08-22 16:01:31 +00001162 m_frame.eventHandler().stopAutoscrollTimer();
beidson@apple.com08c61752009-12-03 19:04:40 +00001163
darinc370e7e2006-11-08 05:52:27 +00001164 // It's important to model this as a load that starts and immediately finishes.
1165 // Otherwise, the parent frame may think we never finished loading.
beidson@apple.com08c61752009-12-03 19:04:40 +00001166 started();
japhet@chromium.org48bb2602010-03-04 23:01:45 +00001167
dbates@webkit.org86a1c672018-08-10 17:39:53 +00001168 if (auto* ownerElement = m_frame.ownerElement()) {
1169 auto* ownerRenderer = ownerElement->renderer();
1170 auto* view = m_frame.view();
1171 if (is<RenderWidget>(ownerRenderer) && view)
1172 downcast<RenderWidget>(*ownerRenderer).setWidget(view);
1173 }
1174
japhet@chromium.org48bb2602010-03-04 23:01:45 +00001175 // We need to scroll to the fragment whether or not a hash change occurred, since
1176 // the user might have scrolled since the previous navigation.
simon.fraser@apple.comc79e4862017-03-08 20:01:15 +00001177 scrollToFragmentWithParentBoundary(url, isNewNavigation);
beidson@apple.com08c61752009-12-03 19:04:40 +00001178
darinc370e7e2006-11-08 05:52:27 +00001179 m_isComplete = false;
1180 checkCompleted();
beidson@apple.com08c61752009-12-03 19:04:40 +00001181
1182 if (isNewNavigation) {
1183 // This will clear previousItem from the rest of the frame tree that didn't
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00001184 // doing any loading. We need to make a pass on this now, since for fragment
1185 // navigation we'll not go through a real load and reach Completed state.
beidson@apple.com08c61752009-12-03 19:04:40 +00001186 checkLoadComplete();
1187 }
1188
akling@apple.com7f50aae2013-08-22 16:01:31 +00001189 m_client.dispatchDidNavigateWithinPage();
darin@chromium.orgfe279962010-03-16 17:26:59 +00001190
darin@apple.com961f2a52016-12-31 09:51:29 +00001191 m_frame.document()->statePopped(stateObject ? Ref<SerializedScriptValue> { *stateObject } : SerializedScriptValue::nullValue());
akling@apple.com7f50aae2013-08-22 16:01:31 +00001192 m_client.dispatchDidPopStateWithinPage();
beidson@apple.com08c61752009-12-03 19:04:40 +00001193
1194 if (hashChange) {
akling@apple.com7f50aae2013-08-22 16:01:31 +00001195 m_frame.document()->enqueueHashchangeEvent(oldURL, url);
1196 m_client.dispatchDidChangeLocationWithinPage();
beidson@apple.com08c61752009-12-03 19:04:40 +00001197 }
1198
1199 // FrameLoaderClient::didFinishLoad() tells the internal load delegate the load finished with no error
akling@apple.com7f50aae2013-08-22 16:01:31 +00001200 m_client.didFinishLoad();
darinc370e7e2006-11-08 05:52:27 +00001201}
1202
1203bool FrameLoader::isComplete() const
1204{
1205 return m_isComplete;
1206}
1207
darinc370e7e2006-11-08 05:52:27 +00001208void FrameLoader::completed()
1209{
akling@apple.comf8515982013-09-02 18:50:01 +00001210 Ref<Frame> protect(m_frame);
beidson@apple.coma5662512009-10-27 00:19:33 +00001211
darin@apple.comfed4d162013-08-25 02:28:06 +00001212 for (Frame* descendant = m_frame.tree().traverseNext(&m_frame); descendant; descendant = descendant->tree().traverseNext(&m_frame))
akling@apple.com9ce995f2013-08-21 20:54:20 +00001213 descendant->navigationScheduler().startTimer();
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00001214
darin@apple.comfed4d162013-08-25 02:28:06 +00001215 if (Frame* parent = m_frame.tree().parent())
andersca@apple.comdf550b92013-08-15 22:17:17 +00001216 parent->loader().checkCompleted();
beidson@apple.coma5662512009-10-27 00:19:33 +00001217
akling@apple.com7f50aae2013-08-22 16:01:31 +00001218 if (m_frame.view())
mmaxfield@apple.com6ebeece2014-12-09 21:03:54 +00001219 m_frame.view()->maintainScrollPositionAtAnchor(nullptr);
darinc370e7e2006-11-08 05:52:27 +00001220}
1221
1222void FrameLoader::started()
1223{
darin@apple.comfed4d162013-08-25 02:28:06 +00001224 for (Frame* frame = &m_frame; frame; frame = frame->tree().parent())
andersca@apple.comdf550b92013-08-15 22:17:17 +00001225 frame->loader().m_isComplete = false;
darinc370e7e2006-11-08 05:52:27 +00001226}
1227
achristensen@apple.comc41ad692019-01-31 21:23:44 +00001228void FrameLoader::prepareForLoadStart()
darinc370e7e2006-11-08 05:52:27 +00001229{
krollin@apple.comd54b5d72016-09-12 18:59:32 +00001230 RELEASE_LOG_IF_ALLOWED("prepareForLoadStart: Starting frame load (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
commit-queue@webkit.org6d635222016-03-08 06:44:59 +00001231
japhet@chromium.org7879dd72012-08-30 02:58:37 +00001232 m_progressTracker->progressStarted();
achristensen@apple.comc41ad692019-01-31 21:23:44 +00001233 m_client.dispatchDidStartProvisionalLoad();
1234
1235 if (AXObjectCache::accessibilityEnabled()) {
1236 if (AXObjectCache* cache = m_frame.document()->existingAXObjectCache()) {
1237 AXObjectCache::AXLoadingEvent loadingEvent = loadType() == FrameLoadType::Reload ? AXObjectCache::AXLoadingReloaded : AXObjectCache::AXLoadingStarted;
1238 cache->frameLoadingEventNotification(&m_frame, loadingEvent);
ossy@webkit.org451e9b02014-01-27 12:40:18 +00001239 }
achristensen@apple.comc41ad692019-01-31 21:23:44 +00001240 }
darinc370e7e2006-11-08 05:52:27 +00001241}
1242
1243void FrameLoader::setupForReplace()
1244{
akling@apple.com7f50aae2013-08-22 16:01:31 +00001245 m_client.revertToProvisionalState(m_documentLoader.get());
darinc370e7e2006-11-08 05:52:27 +00001246 setState(FrameStateProvisional);
1247 m_provisionalDocumentLoader = m_documentLoader;
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.come1810b62018-12-20 19:23:20 +00001254 RELEASE_LOG_IF_ALLOWED("loadFrameRequest: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
1255
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
akling@apple.com7f50aae2013-08-22 16:01:31 +00001271 String referrer = SecurityPolicy::generateReferrerHeader(m_frame.document()->referrerPolicy(), url, argsReferrer);
beidson@apple.comee119d42015-04-28 19:38:13 +00001272 if (request.shouldSendReferrer() == NeverSendReferrer)
anderscade5715d2007-01-06 00:55:49 +00001273 referrer = String();
beidson@apple.comee119d42015-04-28 19:38:13 +00001274
ggaren@apple.com78b4dc62009-01-30 23:09:43 +00001275 FrameLoadType loadType;
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00001276 if (request.resourceRequest().cachePolicy() == ResourceRequestCachePolicy::ReloadIgnoringCacheData)
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001277 loadType = FrameLoadType::Reload;
beidson@apple.comee119d42015-04-28 19:38:13 +00001278 else if (request.lockBackForwardList() == LockBackForwardList::Yes)
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001279 loadType = FrameLoadType::RedirectWithLockedBackForwardList;
ggaren@apple.com78b4dc62009-01-30 23:09:43 +00001280 else
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001281 loadType = FrameLoadType::Standard;
ggaren@apple.com78b4dc62009-01-30 23:09:43 +00001282
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00001283 auto completionHandler = [this, protectedFrame = makeRef(m_frame), formState = makeWeakPtr(formState.get()), frameName = request.frameName()] {
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001284 // FIXME: It's possible this targetFrame will not be the same frame that was targeted by the actual
1285 // load if frame names have changed.
1286 Frame* sourceFrame = formState ? formState->sourceDocument().frame() : &m_frame;
1287 if (!sourceFrame)
1288 sourceFrame = &m_frame;
1289 Frame* targetFrame = sourceFrame->loader().findFrameForNavigation(frameName);
1290 if (targetFrame && targetFrame != sourceFrame) {
1291 if (Page* page = targetFrame->page())
1292 page->chrome().focus();
1293 }
1294 };
ggaren@apple.com78b4dc62009-01-30 23:09:43 +00001295
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001296 if (request.resourceRequest().httpMethod() == "POST")
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00001297 loadPostRequest(WTFMove(request), referrer, loadType, event, WTFMove(formState), WTFMove(completionHandler));
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001298 else
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +00001299 loadURL(WTFMove(request), referrer, loadType, event, WTFMove(formState), WTFMove(adClickAttribution), WTFMove(completionHandler));
anderscade5715d2007-01-06 00:55:49 +00001300}
ddkilzer@apple.come6e7d422008-08-06 21:15:39 +00001301
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001302static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& currentFrame, InitiatedByMainFrame initiatedByMainFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
mitz@apple.comc99c7152015-07-17 21:16:09 +00001303{
commit-queue@webkit.org635dbdc2017-11-23 19:36:08 +00001304 if (UserGestureIndicator::processingUserGesture())
mitz@apple.comc99c7152015-07-17 21:16:09 +00001305 return ShouldOpenExternalURLsPolicy::ShouldAllow;
beidson@apple.com7034ec72017-07-06 00:01:53 +00001306
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001307 if (initiatedByMainFrame == InitiatedByMainFrame::Yes)
beidson@apple.com7034ec72017-07-06 00:01:53 +00001308 return propagatedPolicy;
1309
1310 if (!currentFrame.isMainFrame())
1311 return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
1312
mitz@apple.comc99c7152015-07-17 21:16:09 +00001313 return propagatedPolicy;
1314}
1315
beidson@apple.com7034ec72017-07-06 00:01:53 +00001316static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& currentFrame, const FrameLoadRequest& frameLoadRequest)
1317{
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001318 return shouldOpenExternalURLsPolicyToApply(currentFrame, frameLoadRequest.initiatedByMainFrame(), frameLoadRequest.shouldOpenExternalURLsPolicy());
beidson@apple.com7034ec72017-07-06 00:01:53 +00001319}
1320
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001321static void applyShouldOpenExternalURLsPolicyToNewDocumentLoader(Frame& frame, DocumentLoader& documentLoader, InitiatedByMainFrame initiatedByMainFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
beidson@apple.com7034ec72017-07-06 00:01:53 +00001322{
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001323 documentLoader.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(frame, initiatedByMainFrame, propagatedPolicy));
beidson@apple.com7034ec72017-07-06 00:01:53 +00001324}
1325
1326static void applyShouldOpenExternalURLsPolicyToNewDocumentLoader(Frame& frame, DocumentLoader& documentLoader, const FrameLoadRequest& frameLoadRequest)
1327{
1328 documentLoader.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(frame, frameLoadRequest));
1329}
1330
dbates@webkit.org872db612017-03-20 23:07:50 +00001331bool FrameLoader::isNavigationAllowed() const
1332{
beidson@apple.comb4571302019-08-08 15:54:37 +00001333 return m_pageDismissalEventBeingDispatched == PageDismissalType::None && !m_frame.script().willReplaceWithResultOfExecutingJavascriptURL() && NavigationDisabler::isNavigationAllowed(m_frame);
dbates@webkit.org872db612017-03-20 23:07:50 +00001334}
1335
pvollan@apple.com8f4bcd952018-02-01 04:18:38 +00001336bool FrameLoader::isStopLoadingAllowed() const
1337{
1338 return m_pageDismissalEventBeingDispatched == PageDismissalType::None;
1339}
1340
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +00001341void 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 +00001342{
krollin@apple.come1810b62018-12-20 19:23:20 +00001343 RELEASE_LOG_IF_ALLOWED("loadURL: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
1344
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001345 CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
cdumez@apple.com8ace63b2018-06-29 22:56:29 +00001346 if (m_inStopAllLoaders || m_inClearProvisionalLoadForPolicyCheck)
commit-queue@webkit.orgcd5cda22011-02-15 15:55:21 +00001347 return;
1348
jpfau@apple.com18da22e2014-06-19 00:20:25 +00001349 Ref<Frame> protect(m_frame);
1350
cdumez@apple.com3ed26742018-10-09 23:21:18 +00001351 // Anchor target is ignored when the download attribute is set since it will download the hyperlink rather than follow it.
1352 String effectiveFrameName = frameLoadRequest.downloadAttribute().isNull() ? frameLoadRequest.frameName() : String();
beidson@apple.combd66a782015-05-29 16:31:49 +00001353 AllowNavigationToInvalidURL allowNavigationToInvalidURL = frameLoadRequest.allowNavigationToInvalidURL();
1354 NewFrameOpenerPolicy openerPolicy = frameLoadRequest.newFrameOpenerPolicy();
1355 LockHistory lockHistory = frameLoadRequest.lockHistory();
andersca3513ce02007-05-17 08:38:44 +00001356 bool isFormSubmission = formState;
beidson@apple.combd66a782015-05-29 16:31:49 +00001357
1358 const URL& newURL = frameLoadRequest.resourceRequest().url();
weinig@apple.comc5002662007-12-12 07:26:19 +00001359 ResourceRequest request(newURL);
abarth@webkit.orgfb074382008-10-05 19:12:30 +00001360 if (!referrer.isEmpty()) {
anderscade5715d2007-01-06 00:55:49 +00001361 request.setHTTPReferrer(referrer);
yusukesuzuki@slowstart.orgae5a8bd2018-12-22 06:37:39 +00001362 auto referrerOrigin = SecurityOrigin::createFromString(referrer);
abarth@webkit.org48cade32008-10-23 09:43:34 +00001363 addHTTPOriginIfNeeded(request, referrerOrigin->toString());
abarth@webkit.orgfb074382008-10-05 19:12:30 +00001364 }
akling@apple.com52989472013-09-16 20:09:25 +00001365 if (&m_frame.tree().top() != &m_frame)
commit-queue@webkit.orgc4f892f2017-12-22 05:36:13 +00001366 request.setDomainForCachePartition(m_frame.tree().top().document()->domainForCachePartition());
antti@apple.comcab5da42017-02-09 11:09:28 +00001367
jochen@chromium.orgdac140c2011-08-01 21:18:49 +00001368 addExtraFieldsToRequest(request, newLoadType, true);
antti@apple.com5d0c5402017-03-17 19:52:49 +00001369 if (isReload(newLoadType))
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00001370 request.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
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
darin@apple.com0f88bda2009-04-02 00:30:50 +00001374 // The search for a target frame is done earlier in the case of form submission.
cdumez@apple.com3ed26742018-10-09 23:21:18 +00001375 Frame* targetFrame = isFormSubmission ? nullptr : findFrameForNavigation(effectiveFrameName);
akling@apple.com7f50aae2013-08-22 16:01:31 +00001376 if (targetFrame && targetFrame != &m_frame) {
dbates@webkit.org7f3a9822017-06-22 19:45:10 +00001377 frameLoadRequest.setFrameName("_self");
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +00001378 targetFrame->loader().loadURL(WTFMove(frameLoadRequest), referrer, newLoadType, event, WTFMove(formState), WTFMove(adClickAttribution), completionHandlerCaller.release());
darin@apple.com19c05e92009-03-30 17:26:16 +00001379 return;
1380 }
1381
dbates@webkit.org872db612017-03-20 23:07:50 +00001382 if (!isNavigationAllowed())
eric@webkit.org6cae31a2009-09-26 02:35:15 +00001383 return;
1384
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00001385 NavigationAction action { frameLoadRequest.requester(), request, frameLoadRequest.initiatedByMainFrame(), newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy(), frameLoadRequest.downloadAttribute() };
cdumez@apple.com05911a32018-10-23 17:54:34 +00001386 action.setLockHistory(lockHistory);
1387 action.setLockBackForwardList(frameLoadRequest.lockBackForwardList());
wilander@apple.com6ffdf8f2019-02-06 22:02:15 +00001388 if (adClickAttribution && m_frame.isMainFrame())
1389 action.setAdClickAttribution(WTFMove(*adClickAttribution));
anderscade5715d2007-01-06 00:55:49 +00001390
cdumez@apple.com3ed26742018-10-09 23:21:18 +00001391 if (!targetFrame && !effectiveFrameName.isEmpty()) {
beidson@apple.com7034ec72017-07-06 00:01:53 +00001392 action = action.copyWithShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, frameLoadRequest));
cdumez@apple.com3ed26742018-10-09 23:21:18 +00001393 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, ShouldContinue shouldContinue) mutable {
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00001394 continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001395 completionHandler();
andersca@apple.com096333f2013-11-07 21:37:36 +00001396 });
anderscade5715d2007-01-06 00:55:49 +00001397 return;
1398 }
1399
1400 RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
1401
weinig@apple.comc5002662007-12-12 07:26:19 +00001402 bool sameURL = shouldTreatURLAsSameAsCurrent(newURL);
yael.aharon@nokia.com79f69052010-12-30 19:31:00 +00001403 const String& httpMethod = request.httpMethod();
anderscade5715d2007-01-06 00:55:49 +00001404
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00001405 // Make sure to do scroll to fragment processing even if the URL is
anderscade5715d2007-01-06 00:55:49 +00001406 // exactly the same so pages with '#' links and DHTML side effects
1407 // work properly.
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00001408 if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, newLoadType, newURL)) {
cdumez@apple.com91e03bd2018-09-17 17:15:07 +00001409 oldDocumentLoader->setTriggeringAction(WTFMove(action));
andersca@apple.com97ab6d92013-10-21 22:55:14 +00001410 oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001411 policyChecker().stopCheck();
1412 policyChecker().setLoadType(newLoadType);
rniwa@webkit.orgba12a012019-02-03 22:48:22 +00001413 RELEASE_ASSERT(!isBackForwardLoadType(newLoadType) || history().provisionalItem());
cdumez@apple.com2e665842019-02-01 22:52:58 +00001414 policyChecker().checkNavigationPolicy(WTFMove(request), ResourceResponse { } /* redirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, NavigationPolicyDecision navigationPolicyDecision) {
1415 continueFragmentScrollAfterNavigationPolicy(request, navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad);
cdumez@apple.com82211942018-04-17 18:13:49 +00001416 }, PolicyDecisionMode::Synchronous);
andersca@apple.com096333f2013-11-07 21:37:36 +00001417 return;
1418 }
1419
dino@apple.comb8e413d2018-05-08 20:12:24 +00001420 // Must grab this now, since this load may stop the previous load and clear this flag.
andersca@apple.com096333f2013-11-07 21:37:36 +00001421 bool isRedirect = m_quickRedirectComing;
dino@apple.com0bebb3a2018-05-22 23:56:01 +00001422#if USE(SYSTEM_PREVIEW)
1423 bool isSystemPreview = frameLoadRequest.isSystemPreview();
dino@apple.com0bebb3a2018-05-22 23:56:01 +00001424 if (isSystemPreview)
dino@apple.comddfbca82019-09-13 21:43:18 +00001425 request.setSystemPreviewInfo(frameLoadRequest.systemPreviewInfo());
dino@apple.com0bebb3a2018-05-22 23:56:01 +00001426#endif
commit-queue@webkit.orga4a9ce22019-04-10 22:56:35 +00001427 loadWithNavigationAction(request, WTFMove(action), lockHistory, 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 +00001428 if (isRedirect) {
1429 m_quickRedirectComing = false;
1430 if (m_provisionalDocumentLoader)
1431 m_provisionalDocumentLoader->setIsClientRedirect(true);
1432 else if (m_policyDocumentLoader)
1433 m_policyDocumentLoader->setIsClientRedirect(true);
1434 } else if (sameURL && !isReload(newLoadType)) {
1435 // Example of this case are sites that reload the same URL with a different cookie
1436 // driving the generated content, or a master frame with links that drive a target
1437 // frame, where the user has clicked on the same link repeatedly.
1438 m_loadType = FrameLoadType::Same;
1439 }
1440 completionHandler();
1441 });
anderscade5715d2007-01-06 00:55:49 +00001442}
1443
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001444SubstituteData FrameLoader::defaultSubstituteDataForURL(const URL& url)
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001445{
1446 if (!shouldTreatURLAsSrcdocDocument(url))
1447 return SubstituteData();
darin@apple.comf9da7a72017-06-04 18:19:16 +00001448 auto& srcdoc = m_frame.ownerElement()->attributeWithoutSynchronization(srcdocAttr);
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001449 ASSERT(!srcdoc.isNull());
darin@apple.comf9da7a72017-06-04 18:19:16 +00001450 CString encodedSrcdoc = srcdoc.string().utf8();
beidson@apple.comceb7cba2015-05-19 22:22:51 +00001451
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00001452 ResourceResponse response(URL(), "text/html"_s, encodedSrcdoc.length(), "UTF-8"_s);
beidson@apple.comceb7cba2015-05-19 22:22:51 +00001453 return SubstituteData(SharedBuffer::create(encodedSrcdoc.data(), encodedSrcdoc.length()), URL(), response, SubstituteData::SessionHistoryVisibility::Hidden);
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00001454}
1455
dbates@webkit.org7f3a9822017-06-22 19:45:10 +00001456void FrameLoader::load(FrameLoadRequest&& request)
anderscade5715d2007-01-06 00:55:49 +00001457{
krollin@apple.come1810b62018-12-20 19:23:20 +00001458 RELEASE_LOG_IF_ALLOWED("load (FrameLoadRequest): frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
1459
cdumez@apple.com8ace63b2018-06-29 22:56:29 +00001460 if (m_inStopAllLoaders || m_inClearProvisionalLoadForPolicyCheck)
andersca8567b3d2007-03-21 05:46:49 +00001461 return;
simonjam@chromium.orgc98850b2012-11-28 01:07:36 +00001462
1463 if (!request.frameName().isEmpty()) {
1464 Frame* frame = findFrameForNavigation(request.frameName());
1465 if (frame) {
1466 request.setShouldCheckNewWindowPolicy(false);
andersca@apple.comdf550b92013-08-15 22:17:17 +00001467 if (&frame->loader() != this) {
dbates@webkit.org7f3a9822017-06-22 19:45:10 +00001468 frame->loader().load(WTFMove(request));
simonjam@chromium.orgc98850b2012-11-28 01:07:36 +00001469 return;
1470 }
1471 }
1472 }
1473
1474 if (request.shouldCheckNewWindowPolicy()) {
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00001475 NavigationAction action { request.requester(), request.resourceRequest(), InitiatedByMainFrame::Unknown, NavigationType::Other, request.shouldOpenExternalURLsPolicy() };
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00001476 policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request.resourceRequest()), { }, request.frameName(), [this] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) {
1477 continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
andersca@apple.com096333f2013-11-07 21:37:36 +00001478 });
1479
simonjam@chromium.orgc98850b2012-11-28 01:07:36 +00001480 return;
1481 }
1482
1483 if (!request.hasSubstituteData())
1484 request.setSubstituteData(defaultSubstituteDataForURL(request.resourceRequest().url()));
1485
gyuyoung.kim@webkit.orgc39073e2015-07-19 00:16:50 +00001486 Ref<DocumentLoader> loader = m_client.createDocumentLoader(request.resourceRequest(), request.substituteData());
jiewen_tan@apple.com32abaa62019-02-13 23:07:13 +00001487 loader->setAllowsWebArchiveForMainFrame(request.isRequestFromClientOrUserInput());
dbates@webkit.org8c917f22018-04-24 07:36:59 +00001488 addSameSiteInfoToRequestIfNeeded(loader->request());
beidson@apple.com7034ec72017-07-06 00:01:53 +00001489 applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, request);
beidson@apple.comd0558532015-05-28 04:52:25 +00001490
cdumez@apple.com4353b6e2018-10-26 05:06:24 +00001491 if (request.shouldTreatAsContinuingLoad()) {
cdumez@apple.com05911a32018-10-23 17:54:34 +00001492 loader->setClientRedirectSourceForHistory(request.clientRedirectSourceForHistory());
cdumez@apple.com4353b6e2018-10-26 05:06:24 +00001493 if (request.lockBackForwardList() == LockBackForwardList::Yes) {
1494 loader->setIsClientRedirect(true);
1495 m_loadType = FrameLoadType::RedirectWithLockedBackForwardList;
1496 }
cdumez@apple.com05911a32018-10-23 17:54:34 +00001497 }
1498
cdumez@apple.com3aedc032019-01-31 02:23:55 +00001499 SetForScope<LoadContinuingState> continuingLoadGuard(m_currentLoadContinuingState, request.shouldTreatAsContinuingLoad() ? LoadContinuingState::ContinuingWithRequest : LoadContinuingState::NotContinuing);
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001500 load(loader.get());
anderscade5715d2007-01-06 00:55:49 +00001501}
1502
commit-queue@webkit.orga4a9ce22019-04-10 22:56:35 +00001503void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, NavigationAction&& action, LockHistory lockHistory, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, const String& downloadAttribute, CompletionHandler<void()>&& completionHandler)
anderscade5715d2007-01-06 00:55:49 +00001504{
krollin@apple.come1810b62018-12-20 19:23:20 +00001505 RELEASE_LOG_IF_ALLOWED("loadWithNavigationAction: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
1506
gyuyoung.kim@webkit.orgc39073e2015-07-19 00:16:50 +00001507 Ref<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
commit-queue@webkit.orga4a9ce22019-04-10 22:56:35 +00001508 loader->setDownloadAttribute(downloadAttribute);
dbates@webkit.org9692a072017-07-12 18:01:19 +00001509 applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, action.initiatedByMainFrame(), action.shouldOpenExternalURLsPolicy());
beidson@apple.com87dc6312015-06-02 18:43:13 +00001510
mrowe@apple.combf5eaa62014-04-03 00:51:04 +00001511 if (lockHistory == LockHistory::Yes && m_documentLoader)
commit-queue@webkit.org63040d02011-03-26 00:30:40 +00001512 loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
anderscade5715d2007-01-06 00:55:49 +00001513
cdumez@apple.com91e03bd2018-09-17 17:15:07 +00001514 loader->setTriggeringAction(WTFMove(action));
anderscade5715d2007-01-06 00:55:49 +00001515 if (m_documentLoader)
1516 loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
1517
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001518 loadWithDocumentLoader(loader.ptr(), type, WTFMove(formState), allowNavigationToInvalidURL, ShouldTreatAsContinuingLoad::No, WTFMove(completionHandler));
anderscade5715d2007-01-06 00:55:49 +00001519}
1520
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001521void FrameLoader::load(DocumentLoader& newDocumentLoader)
anderscade5715d2007-01-06 00:55:49 +00001522{
krollin@apple.come1810b62018-12-20 19:23:20 +00001523 RELEASE_LOG_IF_ALLOWED("load (DocumentLoader): frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
1524
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001525 ResourceRequest& r = newDocumentLoader.request();
antti@apple.com4da613e2008-12-15 15:28:41 +00001526 addExtraFieldsToMainResourceRequest(r);
anderscade5715d2007-01-06 00:55:49 +00001527 FrameLoadType type;
1528
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001529 if (shouldTreatURLAsSameAsCurrent(newDocumentLoader.originalRequest().url())) {
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00001530 r.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001531 type = FrameLoadType::Same;
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001532 } else if (shouldTreatURLAsSameAsCurrent(newDocumentLoader.unreachableURL()) && isReload(m_loadType))
commit-queue@webkit.orgfb4593b2018-04-18 17:50:15 +00001533 type = m_loadType;
cdumez@apple.com3aedc032019-01-31 02:23:55 +00001534 else if (m_loadType == FrameLoadType::RedirectWithLockedBackForwardList && ((!newDocumentLoader.unreachableURL().isEmpty() && newDocumentLoader.substituteData().isValid()) || shouldTreatCurrentLoadAsContinuingLoad()))
aestes@apple.com176a9aa2016-07-08 20:14:34 +00001535 type = FrameLoadType::RedirectWithLockedBackForwardList;
jpfau@apple.com6e5a6052012-07-27 00:52:32 +00001536 else
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001537 type = FrameLoadType::Standard;
anderscade5715d2007-01-06 00:55:49 +00001538
1539 if (m_documentLoader)
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001540 newDocumentLoader.setOverrideEncoding(m_documentLoader->overrideEncoding());
anderscade5715d2007-01-06 00:55:49 +00001541
1542 // When we loading alternate content for an unreachable URL that we're
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001543 // visiting in the history list, we treat it as a reload so the history list
anderscade5715d2007-01-06 00:55:49 +00001544 // is appropriately maintained.
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001545 //
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001546 // FIXME: This seems like a dangerous overloading of the meaning of "FrameLoadType::Reload" ...
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001547 // shouldn't a more explicit type of reload be defined, that means roughly
1548 // "load without affecting history" ?
mjs2d326f52007-01-29 12:50:49 +00001549 if (shouldReloadToHandleUnreachableURL(newDocumentLoader)) {
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001550 // shouldReloadToHandleUnreachableURL returns true only when the original load type is back-forward.
commit-queue@webkit.org072ac242011-04-04 17:05:55 +00001551 // In this case we should save the document state now. Otherwise the state can be lost because load type is
1552 // changed and updateForBackForwardNavigation() will not be called when loading is committed.
akling@apple.com672cb852013-08-22 20:27:27 +00001553 history().saveDocumentAndScrollState();
commit-queue@webkit.org072ac242011-04-04 17:05:55 +00001554
andersca@apple.comb50fcc32014-06-19 00:13:20 +00001555 ASSERT(type == FrameLoadType::Standard);
1556 type = FrameLoadType::Reload;
anderscade5715d2007-01-06 00:55:49 +00001557 }
1558
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001559 loadWithDocumentLoader(&newDocumentLoader, type, nullptr, AllowNavigationToInvalidURL::Yes, ShouldTreatAsContinuingLoad::No);
anderscade5715d2007-01-06 00:55:49 +00001560}
1561
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001562void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, ShouldTreatAsContinuingLoad, CompletionHandler<void()>&& completionHandler)
anderscade5715d2007-01-06 00:55:49 +00001563{
krollin@apple.come1810b62018-12-20 19:23:20 +00001564 RELEASE_LOG_IF_ALLOWED("loadWithDocumentLoader: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
1565
inferno@chromium.org6e8e3472010-10-26 13:29:04 +00001566 // Retain because dispatchBeforeLoadEvent may release the last reference to it.
akling@apple.comf8515982013-09-02 18:50:01 +00001567 Ref<Frame> protect(m_frame);
inferno@chromium.org6e8e3472010-10-26 13:29:04 +00001568
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001569 CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
1570
akling@apple.com7f50aae2013-08-22 16:01:31 +00001571 ASSERT(m_client.hasWebView());
anderscade5715d2007-01-06 00:55:49 +00001572
1573 // Unfortunately the view must be non-nil, this is ultimately due
1574 // to parser requiring a FrameView. We should fix this dependency.
1575
akling@apple.com7f50aae2013-08-22 16:01:31 +00001576 ASSERT(m_frame.view());
anderscade5715d2007-01-06 00:55:49 +00001577
dbates@webkit.org872db612017-03-20 23:07:50 +00001578 if (!isNavigationAllowed())
abarth@webkit.org89fa3502009-09-21 02:30:12 +00001579 return;
1580
akling@apple.com7f50aae2013-08-22 16:01:31 +00001581 if (m_frame.document())
1582 m_previousURL = m_frame.document()->url();
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00001583
cdumez@apple.comeb4832c2017-02-08 15:39:38 +00001584 const URL& newURL = loader->request().url();
1585
jiewen_tan@apple.com1306fce2018-10-24 18:49:03 +00001586 // Only the first iframe navigation or the first iframe navigation after about:blank should be reported.
1587 // https://www.w3.org/TR/resource-timing-2/#resources-included-in-the-performanceresourcetiming-interface
keith_miller@apple.combb2f61c2018-12-01 03:28:36 +00001588 if (m_shouldReportResourceTimingToParentFrame && !m_previousURL.isNull() && m_previousURL != WTF::blankURL())
jiewen_tan@apple.com1306fce2018-10-24 18:49:03 +00001589 m_shouldReportResourceTimingToParentFrame = false;
1590
cdumez@apple.com4c54fa72014-12-18 18:42:27 +00001591 // Log main frame navigation types.
akling@apple.come6549f42016-12-01 16:15:27 +00001592 if (m_frame.isMainFrame()) {
cdumez@apple.comc518f7e2018-04-03 18:01:41 +00001593 if (auto* page = m_frame.page()) {
krollin@apple.come1810b62018-12-20 19:23:20 +00001594 RELEASE_LOG_IF_ALLOWED("loadWithDocumentLoader: main frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
cdumez@apple.com563f1dc2017-04-29 03:55:35 +00001595 page->mainFrameLoadStarted(newURL, type);
cdumez@apple.comc518f7e2018-04-03 18:01:41 +00001596 page->performanceLogging().didReachPointOfInterest(PerformanceLogging::MainFrameLoadStarted);
1597 }
akling@apple.come6549f42016-12-01 16:15:27 +00001598 }
cdumez@apple.com4c54fa72014-12-18 18:42:27 +00001599
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001600 policyChecker().setLoadType(type);
rniwa@webkit.orgba12a012019-02-03 22:48:22 +00001601 RELEASE_ASSERT(!isBackForwardLoadType(type) || history().provisionalItem());
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00001602 bool isFormSubmission = formState;
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001603
yael.aharon@nokia.com79f69052010-12-30 19:31:00 +00001604 const String& httpMethod = loader->request().httpMethod();
anderscade5715d2007-01-06 00:55:49 +00001605
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001606 if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, policyChecker().loadType(), newURL)) {
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00001607 RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00001608 NavigationAction action { *m_frame.document(), loader->request(), InitiatedByMainFrame::Unknown, policyChecker().loadType(), isFormSubmission };
anderscade5715d2007-01-06 00:55:49 +00001609
cdumez@apple.com91e03bd2018-09-17 17:15:07 +00001610 oldDocumentLoader->setTriggeringAction(WTFMove(action));
andersca@apple.com97ab6d92013-10-21 22:55:14 +00001611 oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001612 policyChecker().stopCheck();
rniwa@webkit.orgba12a012019-02-03 22:48:22 +00001613 RELEASE_ASSERT(!isBackForwardLoadType(policyChecker().loadType()) || history().provisionalItem());
cdumez@apple.com2e665842019-02-01 22:52:58 +00001614 policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), ResourceResponse { } /* redirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, NavigationPolicyDecision navigationPolicyDecision) {
1615 continueFragmentScrollAfterNavigationPolicy(request, navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad);
cdumez@apple.com82211942018-04-17 18:13:49 +00001616 }, PolicyDecisionMode::Synchronous);
andersca@apple.com096333f2013-11-07 21:37:36 +00001617 return;
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00001618 }
andersca@apple.com096333f2013-11-07 21:37:36 +00001619
1620 if (Frame* parent = m_frame.tree().parent())
1621 loader->setOverrideEncoding(parent->loader().documentLoader()->overrideEncoding());
1622
1623 policyChecker().stopCheck();
1624 setPolicyDocumentLoader(loader);
1625 if (loader->triggeringAction().isEmpty())
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00001626 loader->setTriggeringAction({ *m_frame.document(), loader->request(), InitiatedByMainFrame::Unknown, policyChecker().loadType(), isFormSubmission });
andersca@apple.com096333f2013-11-07 21:37:36 +00001627
1628 if (Element* ownerElement = m_frame.ownerElement()) {
1629 // We skip dispatching the beforeload event if we've already
1630 // committed a real document load because the event would leak
1631 // subsequent activity by the frame which the parent frame isn't
1632 // supposed to learn. For example, if the child frame navigated to
1633 // a new URL, the parent frame shouldn't learn the URL.
1634 if (!m_stateMachine.committedFirstRealDocumentLoad()
1635 && !ownerElement->dispatchBeforeLoadEvent(loader->request().url().string())) {
cdumez@apple.com2e665842019-02-01 22:52:58 +00001636 continueLoadAfterNavigationPolicy(loader->request(), formState.get(), NavigationPolicyDecision::IgnoreLoad, allowNavigationToInvalidURL);
andersca@apple.com096333f2013-11-07 21:37:36 +00001637 return;
1638 }
1639 }
1640
achristensen@apple.com6fddc912018-10-18 21:16:52 +00001641 m_frame.navigationScheduler().cancel(NewLoadInProgress::Yes);
cdumez@apple.com22fa18d2018-02-28 23:58:22 +00001642
cdumez@apple.com3aedc032019-01-31 02:23:55 +00001643 if (shouldTreatCurrentLoadAsContinuingLoad()) {
cdumez@apple.com2e665842019-02-01 22:52:58 +00001644 continueLoadAfterNavigationPolicy(loader->request(), formState.get(), NavigationPolicyDecision::ContinueLoad, allowNavigationToInvalidURL);
beidson@apple.com1c9022b2018-03-21 00:05:58 +00001645 return;
1646 }
1647
rniwa@webkit.orgba12a012019-02-03 22:48:22 +00001648 RELEASE_ASSERT(!isBackForwardLoadType(policyChecker().loadType()) || history().provisionalItem());
cdumez@apple.com2e665842019-02-01 22:52:58 +00001649 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 {
1650 continueLoadAfterNavigationPolicy(request, formState.get(), navigationPolicyDecision, allowNavigationToInvalidURL);
cdumez@apple.comb76757c2018-03-06 22:01:27 +00001651 completionHandler();
achristensen@apple.com10e4a7b2018-11-28 21:14:43 +00001652 }, PolicyDecisionMode::Asynchronous);
anderscade5715d2007-01-06 00:55:49 +00001653}
1654
cdumez@apple.com2e68bb42018-03-19 22:30:57 +00001655void FrameLoader::clearProvisionalLoadForPolicyCheck()
1656{
cdumez@apple.com8ace63b2018-06-29 22:56:29 +00001657 if (!m_policyDocumentLoader || !m_provisionalDocumentLoader || m_inClearProvisionalLoadForPolicyCheck)
cdumez@apple.com2e68bb42018-03-19 22:30:57 +00001658 return;
1659
cdumez@apple.com8ace63b2018-06-29 22:56:29 +00001660 SetForScope<bool> change(m_inClearProvisionalLoadForPolicyCheck, true);
cdumez@apple.com2e68bb42018-03-19 22:30:57 +00001661 m_provisionalDocumentLoader->stopLoading();
1662 setProvisionalDocumentLoader(nullptr);
1663}
1664
aroben@apple.com92cfa902008-04-16 19:19:00 +00001665void FrameLoader::reportLocalLoadFailed(Frame* frame, const String& url)
kmccullo23d362f2007-04-06 01:05:58 +00001666{
1667 ASSERT(!url.isEmpty());
aroben@apple.com92cfa902008-04-16 19:19:00 +00001668 if (!frame)
1669 return;
1670
joepeck@webkit.org1f45df92014-02-06 23:45:53 +00001671 frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to load local resource: " + url);
kmccullo23d362f2007-04-06 01:05:58 +00001672}
1673
bfulgham@apple.comb4c70932016-01-06 22:07:51 +00001674void FrameLoader::reportBlockedPortFailed(Frame* frame, const String& url)
1675{
1676 ASSERT(!url.isEmpty());
1677 if (!frame)
1678 return;
1679
1680 frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to use restricted network port: " + url);
1681}
1682
dbates@webkit.org3c1f25a2018-02-07 18:56:02 +00001683void FrameLoader::reportAuthenticationChallengeBlocked(Frame* frame, const URL& url, const String& reason)
1684{
1685 if (!frame)
1686 return;
1687
1688 frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, makeString("Blocked ", url.stringCenterEllipsizedToLength(), " from asking for credentials because ", reason, '.'));
1689}
1690
anderscade5715d2007-01-06 00:55:49 +00001691const ResourceRequest& FrameLoader::initialRequest() const
1692{
andersca@apple.com48ffa332008-03-13 19:08:06 +00001693 return activeDocumentLoader()->originalRequest();
anderscade5715d2007-01-06 00:55:49 +00001694}
1695
drousso@apple.com21748ed2018-10-08 18:25:52 +00001696bool FrameLoader::willLoadMediaElementURL(URL& url, Node& initiatorNode)
weinig@apple.com68935252009-10-07 02:48:12 +00001697{
ap@apple.com1e8475922018-10-18 21:38:50 +00001698#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00001699 // MobileStore depends on the iOS 4.0 era client delegate method because webView:resource:willSendRequest:redirectResponse:fromDataSource
1700 // 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 +00001701 if (IOSApplication::isMobileStore())
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00001702 return m_client.shouldLoadMediaElementURL(url);
1703#endif
1704
weinig@apple.com68935252009-10-07 02:48:12 +00001705 ResourceRequest request(url);
drousso@apple.com21748ed2018-10-08 18:25:52 +00001706 request.setInspectorInitiatorNodeIdentifier(InspectorInstrumentation::identifierForNode(initiatorNode));
weinig@apple.com68935252009-10-07 02:48:12 +00001707
1708 unsigned long identifier;
1709 ResourceError error;
1710 requestFromDelegate(request, identifier, error);
antti@apple.com021dc012014-09-04 20:00:11 +00001711 notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, ResourceResponse(url, String(), -1, String()), 0, -1, -1, error);
weinig@apple.com68935252009-10-07 02:48:12 +00001712
1713 url = request.url();
1714
1715 return error.isNull();
1716}
1717
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001718bool FrameLoader::shouldReloadToHandleUnreachableURL(DocumentLoader& docLoader)
anderscade5715d2007-01-06 00:55:49 +00001719{
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001720 URL unreachableURL = docLoader.unreachableURL();
anderscade5715d2007-01-06 00:55:49 +00001721
1722 if (unreachableURL.isEmpty())
1723 return false;
1724
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001725 if (!isBackForwardLoadType(policyChecker().loadType()))
anderscade5715d2007-01-06 00:55:49 +00001726 return false;
1727
1728 // We only treat unreachableURLs specially during the delegate callbacks
1729 // for provisional load errors and navigation policy decisions. The former
1730 // case handles well-formed URLs that can't be loaded, and the latter
1731 // case handles malformed URLs and unknown schemes. Loading alternate content
1732 // at other times behaves like a standard load.
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001733 if (policyChecker().delegateIsDecidingNavigationPolicy() || policyChecker().delegateIsHandlingUnimplementablePolicy())
mitz@apple.com6699e272015-05-01 23:47:03 +00001734 return m_policyDocumentLoader && unreachableURL == m_policyDocumentLoader->request().url();
anderscade5715d2007-01-06 00:55:49 +00001735
mitz@apple.com6699e272015-05-01 23:47:03 +00001736 return unreachableURL == m_provisionalLoadErrorBeingHandledURL;
anderscade5715d2007-01-06 00:55:49 +00001737}
1738
ggaren@apple.com3eaa7c02009-01-29 07:38:54 +00001739void FrameLoader::reloadWithOverrideEncoding(const String& encoding)
anderscade5715d2007-01-06 00:55:49 +00001740{
1741 if (!m_documentLoader)
1742 return;
1743
krollin@apple.come1810b62018-12-20 19:23:20 +00001744 RELEASE_LOG_IF_ALLOWED("reloadWithOverrideEncoding: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
1745
anderscade5715d2007-01-06 00:55:49 +00001746 ResourceRequest request = m_documentLoader->request();
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001747 URL unreachableURL = m_documentLoader->unreachableURL();
anderscade5715d2007-01-06 00:55:49 +00001748 if (!unreachableURL.isEmpty())
1749 request.setURL(unreachableURL);
1750
ap@apple.com8d5f01b2013-01-07 18:40:55 +00001751 // FIXME: If the resource is a result of form submission and is not cached, the form will be silently resubmitted.
1752 // We should ask the user for confirmation in this case.
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00001753 request.setCachePolicy(ResourceRequestCachePolicy::ReturnCacheDataElseLoad);
anderscade5715d2007-01-06 00:55:49 +00001754
gyuyoung.kim@webkit.orgc39073e2015-07-19 00:16:50 +00001755 Ref<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001756 applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, InitiatedByMainFrame::Unknown, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
beidson@apple.com87dc6312015-06-02 18:43:13 +00001757
gyuyoung.kim@webkit.orgc39073e2015-07-19 00:16:50 +00001758 setPolicyDocumentLoader(loader.ptr());
anderscade5715d2007-01-06 00:55:49 +00001759
1760 loader->setOverrideEncoding(encoding);
1761
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001762 loadWithDocumentLoader(loader.ptr(), FrameLoadType::Reload, { }, AllowNavigationToInvalidURL::Yes, ShouldTreatAsContinuingLoad::No);
anderscade5715d2007-01-06 00:55:49 +00001763}
1764
antti@apple.com5d0c5402017-03-17 19:52:49 +00001765void FrameLoader::reload(OptionSet<ReloadOption> options)
anderscade5715d2007-01-06 00:55:49 +00001766{
1767 if (!m_documentLoader)
1768 return;
1769
anderscade5715d2007-01-06 00:55:49 +00001770 // If a window is created by javascript, its main frame can have an empty but non-nil URL.
1771 // Reloading in this case will lose the current contents (see 4151001).
darin@chromium.org48246852008-11-04 19:40:56 +00001772 if (m_documentLoader->request().url().isEmpty())
anderscade5715d2007-01-06 00:55:49 +00001773 return;
1774
krollin@apple.come1810b62018-12-20 19:23:20 +00001775 RELEASE_LOG_IF_ALLOWED("reload: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
1776
anderscade5715d2007-01-06 00:55:49 +00001777 // Replace error-page URL with the URL we were trying to reach.
commit-queue@webkit.org2090e272012-06-28 16:05:43 +00001778 ResourceRequest initialRequest = m_documentLoader->request();
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00001779 URL unreachableURL = m_documentLoader->unreachableURL();
anderscade5715d2007-01-06 00:55:49 +00001780 if (!unreachableURL.isEmpty())
darin@chromium.org48246852008-11-04 19:40:56 +00001781 initialRequest.setURL(unreachableURL);
commit-queue@webkit.org2090e272012-06-28 16:05:43 +00001782
mrowe@apple.com713db2e2008-07-27 03:49:29 +00001783 // Create a new document loader for the reload, this will become m_documentLoader eventually,
1784 // but first it has to be the "policy" document loader, and then the "provisional" document loader.
gyuyoung.kim@webkit.orgc39073e2015-07-19 00:16:50 +00001785 Ref<DocumentLoader> loader = m_client.createDocumentLoader(initialRequest, defaultSubstituteDataForURL(initialRequest.url()));
jiewen_tan@apple.com32abaa62019-02-13 23:07:13 +00001786 loader->setAllowsWebArchiveForMainFrame(m_documentLoader->allowsWebArchiveForMainFrame());
dbates@webkit.orgdc3a7cf2017-07-12 17:12:07 +00001787 applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, InitiatedByMainFrame::Unknown, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
anderscade5715d2007-01-06 00:55:49 +00001788
antti@apple.com5d0c5402017-03-17 19:52:49 +00001789 loader->setUserContentExtensionsEnabled(!options.contains(ReloadOption::DisableContentBlockers));
achristensen@apple.comd40e0ba2015-10-14 20:03:14 +00001790
anderscade5715d2007-01-06 00:55:49 +00001791 ResourceRequest& request = loader->request();
1792
commit-queue@webkit.org4833ac52018-02-26 17:38:14 +00001793 // 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 +00001794 request.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
anderscade5715d2007-01-06 00:55:49 +00001795
dbates@webkit.org8c917f22018-04-24 07:36:59 +00001796 addSameSiteInfoToRequestIfNeeded(request);
1797
anderscade5715d2007-01-06 00:55:49 +00001798 // If we're about to re-post, set up action so the application can warn the user.
1799 if (request.httpMethod() == "POST")
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00001800 loader->setTriggeringAction({ *m_frame.document(), request, InitiatedByMainFrame::Unknown, NavigationType::FormResubmitted });
anderscade5715d2007-01-06 00:55:49 +00001801
1802 loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
antti@apple.com5d0c5402017-03-17 19:52:49 +00001803
1804 auto frameLoadTypeForReloadOptions = [] (auto options) {
antti@apple.comeb7081d2018-05-09 07:05:46 +00001805 if (options & ReloadOption::FromOrigin)
antti@apple.com5d0c5402017-03-17 19:52:49 +00001806 return FrameLoadType::ReloadFromOrigin;
antti@apple.comeb7081d2018-05-09 07:05:46 +00001807 if (options & ReloadOption::ExpiredOnly)
antti@apple.com5d0c5402017-03-17 19:52:49 +00001808 return FrameLoadType::ReloadExpiredOnly;
1809 return FrameLoadType::Reload;
1810 };
anderscade5715d2007-01-06 00:55:49 +00001811
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00001812 loadWithDocumentLoader(loader.ptr(), frameLoadTypeForReloadOptions(options), { }, AllowNavigationToInvalidURL::Yes, ShouldTreatAsContinuingLoad::No);
anderscade5715d2007-01-06 00:55:49 +00001813}
1814
ajuma@chromium.orgedd75742019-09-11 14:52:18 +00001815void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItemPolicy, StopLoadingPolicy stopLoadingPolicy)
darinc370e7e2006-11-08 05:52:27 +00001816{
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00001817 if (m_frame.document() && m_frame.document()->backForwardCacheState() == Document::InBackForwardCache)
cdumez@apple.coma0010ff2018-12-13 23:17:44 +00001818 return;
1819
ajuma@chromium.orgedd75742019-09-11 14:52:18 +00001820 if (stopLoadingPolicy == StopLoadingPolicy::PreventDuringUnloadEvents && !isStopLoadingAllowed())
weinig@apple.comf239bbf2009-04-09 18:30:32 +00001821 return;
1822
darinc370e7e2006-11-08 05:52:27 +00001823 // If this method is called from within this method, infinite recursion can occur (3442218). Avoid this.
1824 if (m_inStopAllLoaders)
1825 return;
pvollan@apple.com8f4bcd952018-02-01 04:18:38 +00001826
1827 // This method might dispatch events.
1828 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isScriptAllowed());
1829
inferno@chromium.orgbc05aa52012-08-06 16:30:40 +00001830 // Calling stopLoading() on the provisional document loader can blow away
1831 // the frame from underneath.
akling@apple.comf8515982013-09-02 18:50:01 +00001832 Ref<Frame> protect(m_frame);
darinc370e7e2006-11-08 05:52:27 +00001833
1834 m_inStopAllLoaders = true;
1835
akling@apple.com24f4d6c2013-09-08 08:17:10 +00001836 policyChecker().stopCheck();
darinc370e7e2006-11-08 05:52:27 +00001837
commit-queue@webkit.org987fd772011-01-21 18:26:42 +00001838 // If no new load is in progress, we should clear the provisional item from history
1839 // before we call stopLoading.
1840 if (clearProvisionalItemPolicy == ShouldClearProvisionalItem)
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00001841 history().setProvisionalItem(nullptr);
commit-queue@webkit.org987fd772011-01-21 18:26:42 +00001842
darin@apple.comfed4d162013-08-25 02:28:06 +00001843 for (RefPtr<Frame> child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
andersca@apple.comdf550b92013-08-15 22:17:17 +00001844 child->loader().stopAllLoaders(clearProvisionalItemPolicy);
darin7208e932007-02-13 17:52:53 +00001845 if (m_provisionalDocumentLoader)
commit-queue@webkit.orgfc5833b2011-02-23 06:58:46 +00001846 m_provisionalDocumentLoader->stopLoading();
beidson@apple.com46421212008-08-25 21:48:56 +00001847 if (m_documentLoader)
commit-queue@webkit.orgfc5833b2011-02-23 06:58:46 +00001848 m_documentLoader->stopLoading();
beidson@apple.com46421212008-08-25 21:48:56 +00001849
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00001850 setProvisionalDocumentLoader(nullptr);
darin7208e932007-02-13 17:52:53 +00001851
darinc370e7e2006-11-08 05:52:27 +00001852 m_inStopAllLoaders = false;
1853}
1854
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00001855void FrameLoader::stopForBackForwardCache()
cdumez@apple.come16aaf02019-10-03 22:16:46 +00001856{
cdumez@apple.come16aaf02019-10-03 22:16:46 +00001857 // Stop provisional loads in subframes (The one in the main frame is about to be committed).
1858 if (!m_frame.isMainFrame()) {
1859 if (m_provisionalDocumentLoader)
1860 m_provisionalDocumentLoader->stopLoading();
1861 setProvisionalDocumentLoader(nullptr);
1862 }
1863
1864 // Stop current loads.
1865 if (m_documentLoader)
1866 m_documentLoader->stopLoading();
1867
1868 for (RefPtr<Frame> child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00001869 child->loader().stopForBackForwardCache();
cdumez@apple.com6cbf70a2019-10-11 20:26:15 +00001870
cdumez@apple.com7e7b8792019-10-11 23:29:02 +00001871 // We cancel pending navigations & policy checks *after* cancelling loads because cancelling loads might end up
1872 // running script, which could schedule new navigations.
cdumez@apple.com6cbf70a2019-10-11 20:26:15 +00001873 policyChecker().stopCheck();
1874 m_frame.navigationScheduler().cancel();
cdumez@apple.come16aaf02019-10-03 22:16:46 +00001875}
1876
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00001877void FrameLoader::stopAllLoadersAndCheckCompleteness()
1878{
1879 stopAllLoaders();
1880
1881 if (!m_checkTimer.isActive())
1882 return;
1883
1884 m_checkTimer.stop();
1885 m_checkingLoadCompleteForDetachment = true;
1886 checkCompletenessNow();
1887 m_checkingLoadCompleteForDetachment = false;
1888}
1889
beidson398923b2007-07-31 20:29:02 +00001890void FrameLoader::stopForUserCancel(bool deferCheckLoadComplete)
mjs8d620d52007-05-10 12:31:42 +00001891{
bfulgham@apple.com98845d92016-05-17 01:09:27 +00001892 // Calling stopAllLoaders can cause the frame to be deallocated, including the frame loader.
1893 Ref<Frame> protectedFrame(m_frame);
1894
mjs8d620d52007-05-10 12:31:42 +00001895 stopAllLoaders();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00001896
ap@apple.com1e8475922018-10-18 21:38:50 +00001897#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00001898 // Lay out immediately when stopping to immediately clear the old page if we just committed this one
1899 // but haven't laid out/painted yet.
1900 // FIXME: Is this behavior specific to iOS? Or should we expose a setting to toggle this behavior?
1901 if (m_frame.view() && !m_frame.view()->didFirstLayout())
zalan@apple.com6116e6d2017-10-28 15:24:58 +00001902 m_frame.view()->layoutContext().layout();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00001903#endif
1904
beidson398923b2007-07-31 20:29:02 +00001905 if (deferCheckLoadComplete)
1906 scheduleCheckLoadComplete();
akling@apple.com7f50aae2013-08-22 16:01:31 +00001907 else if (m_frame.page())
mjs8d620d52007-05-10 12:31:42 +00001908 checkLoadComplete();
1909}
1910
darinc370e7e2006-11-08 05:52:27 +00001911DocumentLoader* FrameLoader::activeDocumentLoader() const
1912{
1913 if (m_state == FrameStateProvisional)
1914 return m_provisionalDocumentLoader.get();
1915 return m_documentLoader.get();
1916}
1917
darinc370e7e2006-11-08 05:52:27 +00001918bool FrameLoader::isLoading() const
1919{
darin8207db42007-02-20 18:18:39 +00001920 DocumentLoader* docLoader = activeDocumentLoader();
1921 if (!docLoader)
1922 return false;
japhet@chromium.org4bcb80b2012-03-26 20:34:00 +00001923 return docLoader->isLoading();
darinc370e7e2006-11-08 05:52:27 +00001924}
1925
mjs7545bb52007-05-15 08:24:53 +00001926bool FrameLoader::frameHasLoaded() const
1927{
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00001928 return m_stateMachine.committedFirstRealDocumentLoad() || (m_provisionalDocumentLoader && !m_stateMachine.creatingInitialEmptyDocument());
mjs7545bb52007-05-15 08:24:53 +00001929}
1930
darinc370e7e2006-11-08 05:52:27 +00001931void FrameLoader::setDocumentLoader(DocumentLoader* loader)
1932{
1933 if (!loader && !m_documentLoader)
1934 return;
cdumez@apple.coma0010ff2018-12-13 23:17:44 +00001935
1936 if (loader == m_documentLoader)
1937 return;
darinc370e7e2006-11-08 05:52:27 +00001938
1939 ASSERT(loader != m_documentLoader);
1940 ASSERT(!loader || loader->frameLoader() == this);
1941
akling@apple.com7f50aae2013-08-22 16:01:31 +00001942 m_client.prepareForDataSourceReplacement();
darinc3d26052007-03-22 18:17:12 +00001943 detachChildren();
japhet@chromium.orga9a58bb2012-09-01 01:09:02 +00001944
1945 // detachChildren() can trigger this frame's unload event, and therefore
1946 // script can run and do just about anything. For example, an unload event that calls
1947 // document.write("") on its parent frame can lead to a recursive detachChildren()
1948 // invocation for this frame. In that case, we can end up at this point with a
1949 // loader that hasn't been deleted but has been detached from its frame. Such a
1950 // DocumentLoader has been sufficiently detached that we'll end up in an inconsistent
1951 // state if we try to use it.
1952 if (loader && !loader->frame())
1953 return;
1954
darinc370e7e2006-11-08 05:52:27 +00001955 if (m_documentLoader)
1956 m_documentLoader->detachFromFrame();
1957
1958 m_documentLoader = loader;
1959}
1960
darinc370e7e2006-11-08 05:52:27 +00001961void FrameLoader::setPolicyDocumentLoader(DocumentLoader* loader)
1962{
1963 if (m_policyDocumentLoader == loader)
1964 return;
1965
darinc370e7e2006-11-08 05:52:27 +00001966 if (loader)
beidson@apple.com10a537f2015-07-09 22:30:42 +00001967 loader->attachToFrame(m_frame);
darinc370e7e2006-11-08 05:52:27 +00001968 if (m_policyDocumentLoader
1969 && m_policyDocumentLoader != m_provisionalDocumentLoader
1970 && m_policyDocumentLoader != m_documentLoader)
1971 m_policyDocumentLoader->detachFromFrame();
1972
1973 m_policyDocumentLoader = loader;
1974}
eric@webkit.org14774f42008-04-21 17:50:37 +00001975
darinc370e7e2006-11-08 05:52:27 +00001976void FrameLoader::setProvisionalDocumentLoader(DocumentLoader* loader)
1977{
1978 ASSERT(!loader || !m_provisionalDocumentLoader);
1979 ASSERT(!loader || loader->frameLoader() == this);
1980
1981 if (m_provisionalDocumentLoader && m_provisionalDocumentLoader != m_documentLoader)
1982 m_provisionalDocumentLoader->detachFromFrame();
1983
1984 m_provisionalDocumentLoader = loader;
1985}
1986
darinc370e7e2006-11-08 05:52:27 +00001987void FrameLoader::setState(FrameState newState)
akling@apple.come6549f42016-12-01 16:15:27 +00001988{
1989 FrameState oldState = m_state;
darinc370e7e2006-11-08 05:52:27 +00001990 m_state = newState;
1991
1992 if (newState == FrameStateProvisional)
1993 provisionalLoadStarted();
1994 else if (newState == FrameStateComplete) {
1995 frameLoadCompleted();
darinc370e7e2006-11-08 05:52:27 +00001996 if (m_documentLoader)
1997 m_documentLoader->stopRecordingResponses();
krollin@apple.come1810b62018-12-20 19:23:20 +00001998 if (m_frame.isMainFrame() && oldState != newState) {
1999 RELEASE_LOG_IF_ALLOWED("setState: main frame load completed (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
cdumez@apple.comc518f7e2018-04-03 18:01:41 +00002000 m_frame.page()->performanceLogging().didReachPointOfInterest(PerformanceLogging::MainFrameLoadCompleted);
krollin@apple.come1810b62018-12-20 19:23:20 +00002001 }
darinc370e7e2006-11-08 05:52:27 +00002002 }
2003}
2004
2005void FrameLoader::clearProvisionalLoad()
2006{
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00002007 setProvisionalDocumentLoader(nullptr);
japhet@chromium.org7879dd72012-08-30 02:58:37 +00002008 m_progressTracker->progressCompleted();
darinc370e7e2006-11-08 05:52:27 +00002009 setState(FrameStateComplete);
2010}
2011
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00002012void FrameLoader::commitProvisionalLoad()
beidson50c3bd82007-01-03 03:11:18 +00002013{
beidson50c3bd82007-01-03 03:11:18 +00002014 RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
akling@apple.comf8515982013-09-02 18:50:01 +00002015 Ref<Frame> protect(m_frame);
beidson@apple.com3a5e3b92009-01-27 08:05:59 +00002016
andersca@apple.come776c2f2014-01-18 01:47:19 +00002017 std::unique_ptr<CachedPage> cachedPage;
cdumez@apple.com67e10f72015-01-29 18:38:51 +00002018 if (m_loadingFromCachedPage && history().provisionalItem())
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002019 cachedPage = BackForwardCache::singleton().take(*history().provisionalItem(), m_frame.page());
akling@apple.com9663f4b2013-09-05 21:25:32 +00002020
cdumez@apple.com524b8aa2019-10-15 05:28:55 +00002021 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 +00002022 m_frame.document() ? m_frame.document()->url().stringCenterEllipsizedToLength().utf8().data() : "",
beidson@apple.com69caeee2018-04-20 04:55:32 +00002023 pdl ? pdl->url().stringCenterEllipsizedToLength().utf8().data() : "<no provisional DocumentLoader>", cachedPage.get());
beidson@apple.com3a5e3b92009-01-27 08:05:59 +00002024
ap@apple.come042b632013-05-17 20:04:43 +00002025 willTransitionToCommitted();
2026
cdumez@apple.coma0010ff2018-12-13 23:17:44 +00002027 if (!m_frame.tree().parent() && history().currentItem() && history().currentItem() != history().provisionalItem()) {
akling@apple.comaf7f33b2016-02-06 17:00:30 +00002028 // Check to see if we need to cache the page we are navigating away from into the back/forward cache.
2029 // 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 +00002030 BackForwardCache::singleton().addIfCacheable(*history().currentItem(), m_frame.page());
cdumez@apple.com8420ada2016-06-21 17:05:48 +00002031
carlosgc@webkit.org32a60dd2016-11-10 14:24:26 +00002032 WebCore::jettisonExpensiveObjectsOnTopLevelNavigation();
akling@apple.comaf7f33b2016-02-06 17:00:30 +00002033 }
2034
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002035 if (m_loadType != FrameLoadType::Replace)
beidson50c3bd82007-01-03 03:11:18 +00002036 closeOldDataSources();
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00002037
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00002038 if (!cachedPage && !m_stateMachine.creatingInitialEmptyDocument())
akling@apple.com7f50aae2013-08-22 16:01:31 +00002039 m_client.makeRepresentation(pdl.get());
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00002040
akling@apple.com9663f4b2013-09-05 21:25:32 +00002041 transitionToCommitted(cachedPage.get());
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00002042
abarth@webkit.orgf12783f2012-10-03 19:34:30 +00002043 if (pdl && m_documentLoader) {
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00002044 // Check if the destination page is allowed to access the previous page's timing information.
akling@apple.com6eea45d2014-12-17 01:48:38 +00002045 Ref<SecurityOrigin> securityOrigin(SecurityOrigin::create(pdl->request().url()));
akling@apple.com5a7607f2015-01-21 22:33:49 +00002046 m_documentLoader->timing().setHasSameOriginAsPreviousDocument(securityOrigin.get().canRequest(m_previousURL));
simonjam@chromium.org92bc9b02011-01-06 02:41:13 +00002047 }
2048
beidsonb72fe2e2007-05-03 21:35:24 +00002049 // Call clientRedirectCancelledOrFinished() here so that the frame load delegate is notified that the redirect's
beidson50c3bd82007-01-03 03:11:18 +00002050 // status has changed, if there was a redirect. The frame load delegate may have saved some state about
2051 // the redirect in its -webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:. Since we are
2052 // just about to commit a new page, there cannot possibly be a pending redirect at this point.
2053 if (m_sentRedirectNotification)
achristensen@apple.com6fddc912018-10-18 21:16:52 +00002054 clientRedirectCancelledOrFinished(NewLoadInProgress::No);
beidson50c3bd82007-01-03 03:11:18 +00002055
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00002056 if (cachedPage && cachedPage->document()) {
ap@apple.com1e8475922018-10-18 21:38:50 +00002057#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002058 // FIXME: CachedPage::restore() would dispatch viewport change notification. However UIKit expects load
2059 // commit to happen before any changes to viewport arguments and dealing with this there is difficult.
2060 m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(true);
2061#endif
dbates@webkit.orgcd75cb62017-03-15 22:44:59 +00002062 willRestoreFromCachedPage();
commit-queue@webkit.orgcbb6a492010-09-20 20:20:25 +00002063
carlosgc@webkit.org72eb7962016-01-12 08:23:36 +00002064 // Start request for the main resource and dispatch didReceiveResponse before the load is committed for
2065 // consistency with all other loads. See https://bugs.webkit.org/show_bug.cgi?id=150927.
2066 ResourceError mainResouceError;
2067 unsigned long mainResourceIdentifier;
2068 ResourceRequest mainResourceRequest(cachedPage->documentLoader()->request());
2069 requestFromDelegate(mainResourceRequest, mainResourceIdentifier, mainResouceError);
2070 notifier().dispatchDidReceiveResponse(cachedPage->documentLoader(), mainResourceIdentifier, cachedPage->documentLoader()->response());
2071
cdumez@apple.com8b7a0222018-12-20 04:41:11 +00002072 Optional<HasInsecureContent> hasInsecureContent = cachedPage->cachedMainFrame()->hasInsecureContent();
beidson@apple.com4322db02016-09-16 00:27:11 +00002073
cdumez@apple.com5c7c1f32019-01-16 20:40:02 +00002074 dispatchDidCommitLoad(hasInsecureContent);
2075
dbates@webkit.org1fecb922017-03-25 01:13:23 +00002076 // FIXME: This API should be turned around so that we ground CachedPage into the Page.
2077 cachedPage->restore(*m_frame.page());
commit-queue@webkit.org1686e5d2012-10-19 23:13:08 +00002078
ap@apple.com1e8475922018-10-18 21:38:50 +00002079#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002080 m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(false);
2081 m_frame.page()->chrome().dispatchViewportPropertiesDidChange(m_frame.page()->viewportArguments());
2082#endif
wenson_hsieh@apple.com0c724172018-05-15 01:07:36 +00002083 m_frame.page()->chrome().dispatchDisabledAdaptationsDidChange(m_frame.page()->disabledAdaptations());
darin@apple.com961f2a52016-12-31 09:51:29 +00002084
2085 auto& title = m_documentLoader->title();
2086 if (!title.string.isNull())
akling@apple.com7f50aae2013-08-22 16:01:31 +00002087 m_client.dispatchDidReceiveTitle(title);
commit-queue@webkit.orgcbb6a492010-09-20 20:20:25 +00002088
carlosgc@webkit.org72eb7962016-01-12 08:23:36 +00002089 // Send remaining notifications for the main resource.
2090 notifier().sendRemainingDelegateMessages(m_documentLoader.get(), mainResourceIdentifier, mainResourceRequest, ResourceResponse(),
2091 nullptr, static_cast<int>(m_documentLoader->response().expectedContentLength()), 0, mainResouceError);
2092
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00002093 checkCompleted();
akling@apple.com9663f4b2013-09-05 21:25:32 +00002094 } else
abarth@webkit.org55d49da2011-06-20 23:32:54 +00002095 didOpenURL();
beidson@apple.com3a5e3b92009-01-27 08:05:59 +00002096
darin@apple.comfed4d162013-08-25 02:28:06 +00002097 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 +00002098 m_frame.document() ? m_frame.document()->url().stringCenterEllipsizedToLength().utf8().data() : "");
beidson@apple.com3a5e3b92009-01-27 08:05:59 +00002099
Hironori.Fujii@sony.com2253a9d2018-07-02 01:52:14 +00002100 if (m_loadType == FrameLoadType::Standard && m_documentLoader && m_documentLoader->isClientRedirect())
akling@apple.com672cb852013-08-22 20:27:27 +00002101 history().updateForClientRedirect();
beidson@apple.com028c7a72009-02-11 22:01:22 +00002102
beidson@apple.comac095c02009-08-18 01:37:56 +00002103 if (m_loadingFromCachedPage) {
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002104 // 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 +00002105 if (auto* page = m_frame.page())
2106 page->chrome().didReceiveDocType(m_frame);
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002107 m_frame.document()->resume(ReasonForSuspension::BackForwardCache);
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002108
beidson@apple.com028c7a72009-02-11 22:01:22 +00002109 // Force a layout to update view size and thereby update scrollbars.
ap@apple.com1e8475922018-10-18 21:38:50 +00002110#if PLATFORM(IOS_FAMILY)
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002111 if (!m_client.forceLayoutOnRestoreFromBackForwardCache())
simon.fraser@apple.com72978b32014-03-09 18:14:07 +00002112 m_frame.view()->forceLayout();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002113#else
akling@apple.com7f50aae2013-08-22 16:01:31 +00002114 m_frame.view()->forceLayout();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002115#endif
beidson@apple.com028c7a72009-02-11 22:01:22 +00002116
carlosgc@webkit.org72eb7962016-01-12 08:23:36 +00002117 // Main resource delegates were already sent, so we skip the first response here.
2118 for (unsigned i = 1; i < m_documentLoader->responses().size(); ++i) {
2119 const auto& response = m_documentLoader->responses()[i];
beidson@apple.com028c7a72009-02-11 22:01:22 +00002120 // FIXME: If the WebKit client changes or cancels the request, this is not respected.
2121 ResourceError error;
2122 unsigned long identifier;
2123 ResourceRequest request(response.url());
2124 requestFromDelegate(request, identifier, error);
2125 // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
2126 // However, with today's computers and networking speeds, this won't happen in practice.
2127 // Could be an issue with a giant local file.
akling@apple.com654fd9a2013-10-06 21:07:29 +00002128 notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, response, 0, static_cast<int>(response.expectedContentLength()), 0, error);
beidson@apple.com028c7a72009-02-11 22:01:22 +00002129 }
beidson@apple.com028c7a72009-02-11 22:01:22 +00002130
beidson@apple.com028c7a72009-02-11 22:01:22 +00002131 // FIXME: Why only this frame and not parent frames?
2132 checkLoadCompleteForThisFrame();
2133 }
beidson50c3bd82007-01-03 03:11:18 +00002134}
2135
akling@apple.com9663f4b2013-09-05 21:25:32 +00002136void FrameLoader::transitionToCommitted(CachedPage* cachedPage)
beidson50c3bd82007-01-03 03:11:18 +00002137{
akling@apple.com7f50aae2013-08-22 16:01:31 +00002138 ASSERT(m_client.hasWebView());
beidson50c3bd82007-01-03 03:11:18 +00002139 ASSERT(m_state == FrameStateProvisional);
2140
2141 if (m_state != FrameStateProvisional)
2142 return;
2143
akling@apple.com7f50aae2013-08-22 16:01:31 +00002144 if (FrameView* view = m_frame.view()) {
bdakin@apple.com3fec69c2012-03-23 21:02:51 +00002145 if (ScrollAnimator* scrollAnimator = view->existingScrollAnimator())
bdakin@apple.com87235fc2012-03-23 20:36:31 +00002146 scrollAnimator->cancelAnimations();
2147 }
bdakin@apple.come0a38ad2011-03-15 18:30:41 +00002148
akling@apple.com7f50aae2013-08-22 16:01:31 +00002149 m_client.setCopiesOnScroll();
akling@apple.com672cb852013-08-22 20:27:27 +00002150 history().updateForCommit();
beidson50c3bd82007-01-03 03:11:18 +00002151
2152 // The call to closeURL() invokes the unload event handler, which can execute arbitrary
2153 // JavaScript. If the script initiates a new load, we need to abandon the current load,
2154 // or the two will stomp each other.
2155 DocumentLoader* pdl = m_provisionalDocumentLoader.get();
mjs8d620d52007-05-10 12:31:42 +00002156 if (m_documentLoader)
2157 closeURL();
beidson50c3bd82007-01-03 03:11:18 +00002158 if (pdl != m_provisionalDocumentLoader)
2159 return;
2160
beidson4a289132007-05-03 18:50:41 +00002161 if (m_documentLoader)
2162 m_documentLoader->stopLoadingSubresources();
2163 if (m_documentLoader)
2164 m_documentLoader->stopLoadingPlugIns();
2165
dbates@webkit.orgd77aa3f2017-05-03 16:58:04 +00002166 // Setting our document loader invokes the unload event handler of our child frames.
2167 // Script can do anything. If the script initiates a new load, we need to abandon the
2168 // current load or the two will stomp each other.
beidson4a289132007-05-03 18:50:41 +00002169 setDocumentLoader(m_provisionalDocumentLoader.get());
dbates@webkit.orgd77aa3f2017-05-03 16:58:04 +00002170 if (pdl != m_provisionalDocumentLoader)
2171 return;
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00002172 setProvisionalDocumentLoader(nullptr);
japhet@chromium.orga9a58bb2012-09-01 01:09:02 +00002173
dbates@webkit.orgec907882017-05-05 04:04:35 +00002174 // Nothing else can interrupt this commit - set the Provisional->Committed transition in stone
commit-queue@webkit.org1af3b432011-08-05 07:00:47 +00002175 setState(FrameStateCommittedPage);
beidson50c3bd82007-01-03 03:11:18 +00002176
2177 // Handle adding the URL to the back/forward list.
2178 DocumentLoader* dl = m_documentLoader.get();
beidson50c3bd82007-01-03 03:11:18 +00002179
2180 switch (m_loadType) {
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002181 case FrameLoadType::Forward:
2182 case FrameLoadType::Back:
2183 case FrameLoadType::IndexedBackForward:
2184 if (m_frame.page()) {
2185 // If the first load within a frame is a navigation within a back/forward list that was attached
2186 // without any of the items being loaded then we need to update the history in a similar manner as
2187 // for a standard load with the exception of updating the back/forward list (<rdar://problem/8091103>).
2188 if (!m_stateMachine.committedFirstRealDocumentLoad() && m_frame.isMainFrame())
2189 history().updateForStandardLoad(HistoryController::UpdateAllExceptBackForwardList);
mrowe@apple.com04fa4872010-06-16 02:23:45 +00002190
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002191 history().updateForBackForwardNavigation();
beidson50c3bd82007-01-03 03:11:18 +00002192
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002193 // For cached pages, CachedFrame::restore will take care of firing the popstate event with the history item's state object
2194 if (history().currentItem() && !cachedPage)
2195 m_pendingStateObject = history().currentItem()->stateObject();
mrowe@apple.com04fa4872010-06-16 02:23:45 +00002196
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002197 // Create a document view for this document, or used the cached view.
2198 if (cachedPage) {
2199 DocumentLoader* cachedDocumentLoader = cachedPage->documentLoader();
2200 ASSERT(cachedDocumentLoader);
beidson@apple.com10a537f2015-07-09 22:30:42 +00002201 cachedDocumentLoader->attachToFrame(m_frame);
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002202 m_client.transitionToCommittedFromCachedFrame(cachedPage->cachedMainFrame());
2203 } else
2204 m_client.transitionToCommittedForNewPage();
2205 }
2206 break;
beidson50c3bd82007-01-03 03:11:18 +00002207
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002208 case FrameLoadType::Reload:
2209 case FrameLoadType::ReloadFromOrigin:
antti@apple.com5d0c5402017-03-17 19:52:49 +00002210 case FrameLoadType::ReloadExpiredOnly:
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002211 case FrameLoadType::Same:
2212 case FrameLoadType::Replace:
2213 history().updateForReload();
2214 m_client.transitionToCommittedForNewPage();
2215 break;
beidson50c3bd82007-01-03 03:11:18 +00002216
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002217 case FrameLoadType::Standard:
2218 history().updateForStandardLoad();
2219 if (m_frame.view())
2220 m_frame.view()->setScrollbarsSuppressed(true);
2221 m_client.transitionToCommittedForNewPage();
2222 break;
beidson50c3bd82007-01-03 03:11:18 +00002223
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002224 case FrameLoadType::RedirectWithLockedBackForwardList:
2225 history().updateForRedirectWithLockedBackForwardList();
2226 m_client.transitionToCommittedForNewPage();
2227 break;
beidson50c3bd82007-01-03 03:11:18 +00002228 }
2229
weinig@apple.comee87b2f2013-10-05 23:59:58 +00002230 m_documentLoader->writer().setMIMEType(dl->responseMIMEType());
weinig92883332007-02-20 01:05:27 +00002231
beidson50c3bd82007-01-03 03:11:18 +00002232 // Tell the client we've committed this URL.
akling@apple.com7f50aae2013-08-22 16:01:31 +00002233 ASSERT(m_frame.view());
mjs8d620d52007-05-10 12:31:42 +00002234
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00002235 if (m_stateMachine.creatingInitialEmptyDocument())
mjs8d620d52007-05-10 12:31:42 +00002236 return;
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00002237
2238 if (!m_stateMachine.committedFirstRealDocumentLoad())
2239 m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
beidson50c3bd82007-01-03 03:11:18 +00002240}
2241
achristensen@apple.com6fddc912018-10-18 21:16:52 +00002242void FrameLoader::clientRedirectCancelledOrFinished(NewLoadInProgress newLoadInProgress)
darinc370e7e2006-11-08 05:52:27 +00002243{
2244 // Note that -webView:didCancelClientRedirectForFrame: is called on the frame load delegate even if
2245 // the redirect succeeded. We should either rename this API, or add a new method, like
2246 // -webView:didFinishClientRedirectForFrame:
akling@apple.com7f50aae2013-08-22 16:01:31 +00002247 m_client.dispatchDidCancelClientRedirect();
darinc370e7e2006-11-08 05:52:27 +00002248
achristensen@apple.com6fddc912018-10-18 21:16:52 +00002249 if (newLoadInProgress == NewLoadInProgress::No)
darinc370e7e2006-11-08 05:52:27 +00002250 m_quickRedirectComing = false;
2251
2252 m_sentRedirectNotification = false;
2253}
2254
utatane.tea@gmail.comeb3a8092018-02-23 04:18:17 +00002255void FrameLoader::clientRedirected(const URL& url, double seconds, WallTime fireDate, LockBackForwardList lockBackForwardList)
darinc370e7e2006-11-08 05:52:27 +00002256{
achristensen@apple.com6fddc912018-10-18 21:16:52 +00002257 m_client.dispatchWillPerformClientRedirect(url, seconds, fireDate, lockBackForwardList);
darinc370e7e2006-11-08 05:52:27 +00002258
2259 // Remember that we sent a redirect notification to the frame load delegate so that when we commit
2260 // the next provisional load, we can send a corresponding -webView:didCancelClientRedirectForFrame:
2261 m_sentRedirectNotification = true;
2262
darin@apple.com0f88bda2009-04-02 00:30:50 +00002263 // If a "quick" redirect comes in, we set a special mode so we treat the next
2264 // load as part of the original navigation. If we don't have a document loader, we have
darinc370e7e2006-11-08 05:52:27 +00002265 // 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 +00002266 // Loads triggered by JavaScript form submissions never count as quick redirects.
mrowe@apple.combf5eaa62014-04-03 00:51:04 +00002267 m_quickRedirectComing = (lockBackForwardList == LockBackForwardList::Yes || history().currentItemShouldBeReplaced()) && m_documentLoader && !m_isExecutingJavaScriptFormAction;
darinc370e7e2006-11-08 05:52:27 +00002268}
2269
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00002270bool FrameLoader::shouldReload(const URL& currentURL, const URL& destinationURL)
darinc370e7e2006-11-08 05:52:27 +00002271{
2272 // This function implements the rule: "Don't reload if navigating by fragment within
2273 // the same URL, but do reload if going to a new URL or to the same URL with no
2274 // fragment identifier at all."
beidson@apple.comee497252009-08-10 16:35:00 +00002275 if (!destinationURL.hasFragmentIdentifier())
darinc370e7e2006-11-08 05:52:27 +00002276 return true;
beidson@apple.comee497252009-08-10 16:35:00 +00002277 return !equalIgnoringFragmentIdentifier(currentURL, destinationURL);
darinc370e7e2006-11-08 05:52:27 +00002278}
2279
2280void FrameLoader::closeOldDataSources()
2281{
2282 // FIXME: Is it important for this traversal to be postorder instead of preorder?
2283 // If so, add helpers for postorder traversal, and use them. If not, then lets not
2284 // use a recursive algorithm here.
darin@apple.comfed4d162013-08-25 02:28:06 +00002285 for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
andersca@apple.comdf550b92013-08-15 22:17:17 +00002286 child->loader().closeOldDataSources();
darinc370e7e2006-11-08 05:52:27 +00002287
2288 if (m_documentLoader)
akling@apple.com7f50aae2013-08-22 16:01:31 +00002289 m_client.dispatchWillClose();
darinc370e7e2006-11-08 05:52:27 +00002290
akling@apple.com7f50aae2013-08-22 16:01:31 +00002291 m_client.setMainFrameDocumentReady(false); // stop giving out the actual DOMDocument to observers
darinc370e7e2006-11-08 05:52:27 +00002292}
2293
dbates@webkit.orgcd75cb62017-03-15 22:44:59 +00002294void FrameLoader::willRestoreFromCachedPage()
darinc370e7e2006-11-08 05:52:27 +00002295{
darin@apple.comfed4d162013-08-25 02:28:06 +00002296 ASSERT(!m_frame.tree().parent());
akling@apple.com7f50aae2013-08-22 16:01:31 +00002297 ASSERT(m_frame.page());
darin@apple.com0e83ab12013-09-28 17:19:04 +00002298 ASSERT(m_frame.isMainFrame());
darinc370e7e2006-11-08 05:52:27 +00002299
akling@apple.com7f50aae2013-08-22 16:01:31 +00002300 m_frame.navigationScheduler().cancel();
darinc370e7e2006-11-08 05:52:27 +00002301
2302 // We still have to close the previous part page.
2303 closeURL();
darinc370e7e2006-11-08 05:52:27 +00002304
2305 // Delete old status bar messages (if it _was_ activated on last URL).
akling@apple.com7f50aae2013-08-22 16:01:31 +00002306 if (m_frame.script().canExecuteScripts(NotAboutToExecuteScript)) {
2307 DOMWindow* window = m_frame.document()->domWindow();
abarth@webkit.org13fe1e22012-08-16 22:29:48 +00002308 window->setStatus(String());
2309 window->setDefaultStatus(String());
darinc370e7e2006-11-08 05:52:27 +00002310 }
beidson@apple.com028c7a72009-02-11 22:01:22 +00002311}
2312
beidson@apple.com913c7f82009-09-02 20:16:38 +00002313void FrameLoader::open(CachedFrameBase& cachedFrame)
beidson@apple.com028c7a72009-02-11 22:01:22 +00002314{
2315 m_isComplete = false;
2316
2317 // Don't re-emit the load event.
2318 m_didCallImplicitClose = true;
2319
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00002320 URL url = cachedFrame.url();
darinc370e7e2006-11-08 05:52:27 +00002321
abarth@webkit.org55d49da2011-06-20 23:32:54 +00002322 // FIXME: I suspect this block of code doesn't do anything.
benjamin@webkit.orgf726d632012-03-04 03:26:27 +00002323 if (url.protocolIsInHTTPFamily() && !url.host().isEmpty() && url.path().isEmpty())
weinig@apple.comc5002662007-12-12 07:26:19 +00002324 url.setPath("/");
abarth@webkit.org55d49da2011-06-20 23:32:54 +00002325
abarth@webkit.org91289c32010-04-12 04:54:55 +00002326 started();
rniwa@webkit.org77c65702019-08-13 05:18:11 +00002327 auto document = makeRef(*cachedFrame.document());
abarth@webkit.org23ea90a2012-08-14 19:47:59 +00002328 ASSERT(document->domWindow());
2329
rniwa@webkit.org77c65702019-08-13 05:18:11 +00002330 clear(document.ptr(), true, true, cachedFrame.isMainFrame());
abarth@webkit.org23ea90a2012-08-14 19:47:59 +00002331
cdumez@apple.comf0705d72019-07-01 21:55:03 +00002332 document->attachToCachedFrame(cachedFrame);
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002333 document->setBackForwardCacheState(Document::NotInBackForwardCache);
darinc370e7e2006-11-08 05:52:27 +00002334
2335 m_needsClear = true;
2336 m_isComplete = false;
ggarena57755c2007-07-09 21:08:10 +00002337 m_didCallImplicitClose = false;
Hironori.Fujii@sony.com27c57b42019-08-28 01:40:42 +00002338 setOutgoingReferrer(url);
kmccullo6b1b5c22007-05-24 20:06:56 +00002339
beidson@apple.com028c7a72009-02-11 22:01:22 +00002340 FrameView* view = cachedFrame.view();
2341
2342 // When navigating to a CachedFrame its FrameView should never be null. If it is we'll crash in creative ways downstream.
2343 ASSERT(view);
beidson@apple.com24f92a52009-09-03 00:07:51 +00002344 view->setWasScrolledByUser(false);
adachan@apple.com95f492a2009-08-24 19:55:23 +00002345
cdumez@apple.com8b7a0222018-12-20 04:41:11 +00002346 Optional<IntRect> previousViewFrameRect = m_frame.view() ? m_frame.view()->frameRect() : Optional<IntRect>(WTF::nullopt);
akling@apple.com7f50aae2013-08-22 16:01:31 +00002347 m_frame.setView(view);
cdumez@apple.com665ca3b2015-05-08 18:15:57 +00002348
2349 // Use the previous ScrollView's frame rect.
2350 if (previousViewFrameRect)
2351 view->setFrameRect(previousViewFrameRect.value());
dbates@webkit.org7259cf32018-08-21 16:50:20 +00002352
rniwa@webkit.org77c65702019-08-13 05:18:11 +00002353
2354 // Setting the document builds the render tree and runs post style resolution callbacks that can do anything,
2355 // including loading a child frame before its been re-attached to the frame tree as part of this restore.
2356 // For example, the HTML object element may load its content into a frame in a post style resolution callback.
2357 Style::PostResolutionCallbackDisabler disabler(document.get());
2358 WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
2359 NavigationDisabler disableNavigation { &m_frame };
2360
2361 m_frame.setDocument(document.copyRef());
dbates@webkit.org7259cf32018-08-21 16:50:20 +00002362
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002363 document->domWindow()->resumeFromBackForwardCache();
weinig@apple.com5367c412008-06-27 00:03:25 +00002364
abarth@webkit.org622d9df2009-05-22 16:44:47 +00002365 updateFirstPartyForCookies();
darinc370e7e2006-11-08 05:52:27 +00002366
beidson@apple.com028c7a72009-02-11 22:01:22 +00002367 cachedFrame.restore();
darinc370e7e2006-11-08 05:52:27 +00002368}
2369
darinc370e7e2006-11-08 05:52:27 +00002370bool FrameLoader::isHostedByObjectElement() const
2371{
akling@apple.com7f50aae2013-08-22 16:01:31 +00002372 HTMLFrameOwnerElement* owner = m_frame.ownerElement();
darinc370e7e2006-11-08 05:52:27 +00002373 return owner && owner->hasTagName(objectTag);
2374}
2375
darinc370e7e2006-11-08 05:52:27 +00002376bool FrameLoader::isReplacing() const
2377{
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002378 return m_loadType == FrameLoadType::Replace;
darinc370e7e2006-11-08 05:52:27 +00002379}
2380
2381void FrameLoader::setReplacing()
2382{
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002383 m_loadType = FrameLoadType::Replace;
darinc370e7e2006-11-08 05:52:27 +00002384}
2385
darinc370e7e2006-11-08 05:52:27 +00002386bool FrameLoader::subframeIsLoading() const
2387{
2388 // 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 +00002389 for (Frame* child = m_frame.tree().lastChild(); child; child = child->tree().previousSibling()) {
andersca@apple.comdf550b92013-08-15 22:17:17 +00002390 FrameLoader& childLoader = child->loader();
2391 DocumentLoader* documentLoader = childLoader.documentLoader();
darinc370e7e2006-11-08 05:52:27 +00002392 if (documentLoader && documentLoader->isLoadingInAPISense())
2393 return true;
andersca@apple.comdf550b92013-08-15 22:17:17 +00002394 documentLoader = childLoader.provisionalDocumentLoader();
darinc370e7e2006-11-08 05:52:27 +00002395 if (documentLoader && documentLoader->isLoadingInAPISense())
2396 return true;
andersca@apple.comdf550b92013-08-15 22:17:17 +00002397 documentLoader = childLoader.policyDocumentLoader();
mjs@apple.com17a175d2010-07-18 00:15:31 +00002398 if (documentLoader)
2399 return true;
darinc370e7e2006-11-08 05:52:27 +00002400 }
2401 return false;
2402}
2403
2404void FrameLoader::willChangeTitle(DocumentLoader* loader)
2405{
akling@apple.com7f50aae2013-08-22 16:01:31 +00002406 m_client.willChangeTitle(loader);
darinc370e7e2006-11-08 05:52:27 +00002407}
2408
2409FrameLoadType FrameLoader::loadType() const
2410{
2411 return m_loadType;
2412}
antti@apple.com4da613e2008-12-15 15:28:41 +00002413
antti@apple.com2b38ed12017-04-26 18:22:27 +00002414CachePolicy FrameLoader::subresourceCachePolicy(const URL& url) const
antti@apple.com4da613e2008-12-15 15:28:41 +00002415{
darin@apple.com30c194a2016-03-20 20:08:59 +00002416 if (Page* page = m_frame.page()) {
cdumez@apple.coma231c912019-10-16 18:24:25 +00002417 if (page->isResourceCachingDisabledByWebInspector())
darin@apple.com30c194a2016-03-20 20:08:59 +00002418 return CachePolicyReload;
2419 }
darin@apple.com0fdefc32016-03-18 07:56:20 +00002420
antti@apple.com4da613e2008-12-15 15:28:41 +00002421 if (m_isComplete)
2422 return CachePolicyVerify;
ap@webkit.org86b10982009-05-18 15:30:10 +00002423
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002424 if (m_loadType == FrameLoadType::ReloadFromOrigin)
antti@apple.com4da613e2008-12-15 15:28:41 +00002425 return CachePolicyReload;
ap@webkit.org86b10982009-05-18 15:30:10 +00002426
darin@apple.comfed4d162013-08-25 02:28:06 +00002427 if (Frame* parentFrame = m_frame.tree().parent()) {
antti@apple.com2b38ed12017-04-26 18:22:27 +00002428 CachePolicy parentCachePolicy = parentFrame->loader().subresourceCachePolicy(url);
antti@apple.com4da613e2008-12-15 15:28:41 +00002429 if (parentCachePolicy != CachePolicyVerify)
2430 return parentCachePolicy;
2431 }
slewis@apple.comef236f42011-05-25 23:00:45 +00002432
cdumez@apple.com74493162014-12-08 18:42:12 +00002433 switch (m_loadType) {
2434 case FrameLoadType::Reload:
antti@apple.com4da613e2008-12-15 15:28:41 +00002435 return CachePolicyRevalidate;
cdumez@apple.com74493162014-12-08 18:42:12 +00002436 case FrameLoadType::Back:
2437 case FrameLoadType::Forward:
2438 case FrameLoadType::IndexedBackForward:
joepeck@webkit.org853e6862010-11-18 17:59:53 +00002439 return CachePolicyHistoryBuffer;
cdumez@apple.com74493162014-12-08 18:42:12 +00002440 case FrameLoadType::ReloadFromOrigin:
2441 ASSERT_NOT_REACHED(); // Already handled above.
2442 return CachePolicyReload;
2443 case FrameLoadType::RedirectWithLockedBackForwardList:
2444 case FrameLoadType::Replace:
2445 case FrameLoadType::Same:
2446 case FrameLoadType::Standard:
antti@apple.com2b38ed12017-04-26 18:22:27 +00002447 return CachePolicyVerify;
antti@apple.com5d0c5402017-03-17 19:52:49 +00002448 case FrameLoadType::ReloadExpiredOnly:
antti@apple.com2b38ed12017-04-26 18:22:27 +00002449 // We know about expiration for HTTP and data. Do a normal reload otherwise.
2450 if (!url.protocolIsInHTTPFamily() && !url.protocolIsData())
2451 return CachePolicyReload;
cdumez@apple.com74493162014-12-08 18:42:12 +00002452 return CachePolicyVerify;
2453 }
ossy@webkit.org41788ca2014-12-08 19:30:19 +00002454
2455 RELEASE_ASSERT_NOT_REACHED();
2456 return CachePolicyVerify;
antti@apple.com4da613e2008-12-15 15:28:41 +00002457}
darinc370e7e2006-11-08 05:52:27 +00002458
aestes@apple.com5a4908d2019-06-07 06:09:40 +00002459void FrameLoader::dispatchDidFailProvisionalLoad(DocumentLoader& provisionalDocumentLoader, const ResourceError& error)
2460{
2461 m_provisionalLoadErrorBeingHandledURL = provisionalDocumentLoader.url();
2462
2463#if ENABLE(CONTENT_FILTERING)
2464 auto contentFilter = provisionalDocumentLoader.contentFilter();
2465 auto contentFilterWillContinueLoading = false;
2466#endif
2467
2468 auto willContinueLoading = WillContinueLoading::No;
2469 if (history().provisionalItem())
2470 willContinueLoading = WillContinueLoading::Yes;
2471#if ENABLE(CONTENT_FILTERING)
2472 if (contentFilter && contentFilter->willHandleProvisionalLoadFailure(error)) {
2473 willContinueLoading = WillContinueLoading::Yes;
2474 contentFilterWillContinueLoading = true;
2475 }
2476#endif
2477
2478 m_client.dispatchDidFailProvisionalLoad(error, willContinueLoading);
2479
2480#if ENABLE(CONTENT_FILTERING)
2481 if (contentFilterWillContinueLoading)
2482 contentFilter->handleProvisionalLoadFailure(error);
2483#endif
2484
2485 m_provisionalLoadErrorBeingHandledURL = { };
2486}
2487
andersca4422e372007-01-12 19:56:19 +00002488void FrameLoader::checkLoadCompleteForThisFrame()
2489{
akling@apple.com7f50aae2013-08-22 16:01:31 +00002490 ASSERT(m_client.hasWebView());
andersca4422e372007-01-12 19:56:19 +00002491
darin@apple.combe4d3dd2017-07-30 21:44:01 +00002492 // FIXME: Should this check be done in checkLoadComplete instead of here?
2493 // FIXME: Why does this one check need to be repeated here, and not the many others from checkCompleted?
2494 if (m_frame.document()->isDelayingLoadEvent())
2495 return;
2496
andersca4422e372007-01-12 19:56:19 +00002497 switch (m_state) {
2498 case FrameStateProvisional: {
jiewen_tan@apple.com8c36f622016-04-01 21:40:20 +00002499 // FIXME: Prohibiting any provisional load failures from being sent to clients
2500 // while handling provisional load failures is too heavy. For example, the current
2501 // load will fail to cancel another ongoing load. That might prevent clients' page
2502 // load state being handled properly.
mitz@apple.com6699e272015-05-01 23:47:03 +00002503 if (!m_provisionalLoadErrorBeingHandledURL.isEmpty())
andersca4422e372007-01-12 19:56:19 +00002504 return;
2505
2506 RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
2507 if (!pdl)
2508 return;
2509
2510 // If we've received any errors we may be stuck in the provisional state and actually complete.
2511 const ResourceError& error = pdl->mainDocumentError();
2512 if (error.isNull())
2513 return;
2514
2515 // Check all children first.
2516 RefPtr<HistoryItem> item;
akling@apple.com7f50aae2013-08-22 16:01:31 +00002517 if (Page* page = m_frame.page())
commit-queue@webkit.org21a48d82011-01-09 01:27:19 +00002518 if (isBackForwardLoadType(loadType()))
2519 // Reset the back forward list to the last committed history item at the top level.
akling@apple.com095b5442013-08-27 02:47:37 +00002520 item = page->mainFrame().loader().history().currentItem();
andersca4422e372007-01-12 19:56:19 +00002521
commit-queue@webkit.org987fd772011-01-21 18:26:42 +00002522 // Only reset if we aren't already going to a new provisional item.
akling@apple.com672cb852013-08-22 20:27:27 +00002523 bool shouldReset = !history().provisionalItem();
ap@apple.com421e9a12011-03-24 00:50:45 +00002524 if (!pdl->isLoadingInAPISense() || pdl->isStopping()) {
krollin@apple.come1810b62018-12-20 19:23:20 +00002525 RELEASE_LOG_IF_ALLOWED("checkLoadCompleteForThisFrame: Failed provisional load (frame = %p, main = %d, isTimeout = %d, isCancellation = %d, errorCode = %d)", &m_frame, m_frame.isMainFrame(), error.isTimeout(), error.isCancellation(), error.errorCode());
cdumez@apple.com41883a92019-04-23 15:38:11 +00002526
aestes@apple.com5a4908d2019-06-07 06:09:40 +00002527 dispatchDidFailProvisionalLoad(*pdl, error);
ap@apple.com09535d12011-03-24 00:48:30 +00002528 ASSERT(!pdl->isLoading());
andersca4422e372007-01-12 19:56:19 +00002529
eric@webkit.orgb562c402010-01-13 01:29:35 +00002530 // If we're in the middle of loading multipart data, we need to restore the document loader.
2531 if (isReplacing() && !m_documentLoader.get())
eric@webkit.org90747252010-01-12 18:10:14 +00002532 setDocumentLoader(m_provisionalDocumentLoader.get());
2533
andersca4422e372007-01-12 19:56:19 +00002534 // Finish resetting the load state, but only if another load hasn't been started by the
2535 // delegate callback.
2536 if (pdl == m_provisionalDocumentLoader)
2537 clearProvisionalLoad();
tonikitoo@webkit.orge94ac9b2009-11-16 15:38:19 +00002538 else if (activeDocumentLoader()) {
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00002539 URL unreachableURL = activeDocumentLoader()->unreachableURL();
andersca4422e372007-01-12 19:56:19 +00002540 if (!unreachableURL.isEmpty() && unreachableURL == pdl->request().url())
2541 shouldReset = false;
2542 }
2543 }
darine0cef432007-07-10 19:21:23 +00002544 if (shouldReset && item)
akling@apple.com7f50aae2013-08-22 16:01:31 +00002545 if (Page* page = m_frame.page()) {
achristensen@apple.com3a889f12018-10-16 15:58:10 +00002546 page->backForward().setCurrentItem(*item);
mitz@apple.combc843762008-12-08 21:18:11 +00002547 }
andersca4422e372007-01-12 19:56:19 +00002548 return;
2549 }
2550
2551 case FrameStateCommittedPage: {
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00002552 if (!m_documentLoader)
2553 return;
2554 if (m_documentLoader->isLoadingInAPISense() && !m_documentLoader->isStopping() && !m_checkingLoadCompleteForDetachment)
andersca4422e372007-01-12 19:56:19 +00002555 return;
2556
darin@apple.comaf8b1a92011-06-25 00:09:37 +00002557 setState(FrameStateComplete);
andersca4422e372007-01-12 19:56:19 +00002558
2559 // FIXME: Is this subsequent work important if we already navigated away?
2560 // Maybe there are bugs because of that, or extra work we can skip because
2561 // the new page is ready.
2562
akling@apple.com7f50aae2013-08-22 16:01:31 +00002563 m_client.forceLayoutForNonHTML();
andersca4422e372007-01-12 19:56:19 +00002564
2565 // If the user had a scroll point, scroll to it, overriding the anchor point if any.
akling@apple.com7f50aae2013-08-22 16:01:31 +00002566 if (m_frame.page()) {
antti@apple.com5d0c5402017-03-17 19:52:49 +00002567 if (isBackForwardLoadType(m_loadType) || isReload(m_loadType))
akling@apple.com672cb852013-08-22 20:27:27 +00002568 history().restoreScrollPositionAndViewState();
darin@apple.come10e1282010-10-30 00:44:33 +00002569 }
andersca4422e372007-01-12 19:56:19 +00002570
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00002571 if (m_stateMachine.creatingInitialEmptyDocument() || !m_stateMachine.committedFirstRealDocumentLoad())
mjs8d620d52007-05-10 12:31:42 +00002572 return;
2573
timothy_horton@apple.com346f8d72013-08-01 00:06:51 +00002574 m_progressTracker->progressCompleted();
eric.carlson@apple.com77b4a112014-10-30 19:04:29 +00002575 Page* page = m_frame.page();
2576 if (page) {
simon.fraser@apple.com83325b92017-03-17 00:47:16 +00002577 if (m_frame.isMainFrame()) {
sbarati@apple.comce7ec112018-04-17 15:57:32 +00002578 tracePoint(MainResourceLoadDidEnd);
cdumez@apple.comef2c0152017-01-13 17:54:53 +00002579 page->didFinishLoad();
simon.fraser@apple.com83325b92017-03-17 00:47:16 +00002580 }
andersca@apple.com7c0a3fc2012-05-01 22:22:25 +00002581 }
2582
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00002583 const ResourceError& error = m_documentLoader->mainDocumentError();
mario@webkit.org685258f2011-12-06 00:10:55 +00002584
2585 AXObjectCache::AXLoadingEvent loadingEvent;
2586 if (!error.isNull()) {
krollin@apple.comd54b5d72016-09-12 18:59:32 +00002587 RELEASE_LOG_IF_ALLOWED("checkLoadCompleteForThisFrame: Finished frame load with error (frame = %p, main = %d, isTimeout = %d, isCancellation = %d, errorCode = %d)", &m_frame, m_frame.isMainFrame(), error.isTimeout(), error.isCancellation(), error.errorCode());
akling@apple.com7f50aae2013-08-22 16:01:31 +00002588 m_client.dispatchDidFailLoad(error);
mario@webkit.org685258f2011-12-06 00:10:55 +00002589 loadingEvent = AXObjectCache::AXLoadingFailed;
2590 } else {
krollin@apple.com5c91c4e2016-09-20 20:03:45 +00002591 RELEASE_LOG_IF_ALLOWED("checkLoadCompleteForThisFrame: Finished frame load (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
enrica@apple.com53b08e52016-01-19 22:58:59 +00002592#if ENABLE(DATA_DETECTION)
rniwa@webkit.org2f150e72016-06-14 07:35:53 +00002593 auto* document = m_frame.document();
2594 if (m_frame.settings().dataDetectorTypes() != DataDetectorTypeNone && document) {
2595 if (auto* documentElement = document->documentElement()) {
2596 RefPtr<Range> documentRange = makeRange(firstPositionInNode(documentElement), lastPositionInNode(documentElement));
timothy_horton@apple.com688a9102016-07-07 03:03:42 +00002597 m_frame.setDataDetectionResults(DataDetection::detectContentInRange(documentRange, m_frame.settings().dataDetectorTypes(), m_client.dataDetectionContext()));
rniwa@webkit.org2f150e72016-06-14 07:35:53 +00002598 if (m_frame.isMainFrame())
2599 m_client.dispatchDidFinishDataDetection(m_frame.dataDetectionResults());
2600 }
enrica@apple.com53b08e52016-01-19 22:58:59 +00002601 }
2602#endif
enrica@apple.com4c36ad52016-01-23 00:24:02 +00002603 m_client.dispatchDidFinishLoad();
2604 loadingEvent = AXObjectCache::AXLoadingFinished;
mario@webkit.org685258f2011-12-06 00:10:55 +00002605 }
2606
2607 // Notify accessibility.
rniwa@webkit.org2f150e72016-06-14 07:35:53 +00002608 if (auto* document = m_frame.document()) {
2609 if (AXObjectCache* cache = document->existingAXObjectCache())
2610 cache->frameLoadingEventNotification(&m_frame, loadingEvent);
2611 }
andersca4422e372007-01-12 19:56:19 +00002612
beidson@apple.com4aecb3d2015-07-09 04:47:09 +00002613 // The above calls to dispatchDidFinishLoad() might have detached the Frame
2614 // from its Page and also might have caused Page to be deleted.
2615 // Don't assume 'page' is still available to use.
2616 if (m_frame.isMainFrame() && m_frame.page()) {
2617 ASSERT(&m_frame.page()->mainFrame() == &m_frame);
cdumez@apple.com10d0f252016-04-23 21:33:49 +00002618 m_frame.page()->diagnosticLoggingClient().logDiagnosticMessageWithResult(DiagnosticLoggingKeys::pageLoadedKey(), emptyString(), error.isNull() ? DiagnosticLoggingResultPass : DiagnosticLoggingResultFail, ShouldSample::Yes);
beidson@apple.com4aecb3d2015-07-09 04:47:09 +00002619 }
eric.carlson@apple.com77b4a112014-10-30 19:04:29 +00002620
andersca4422e372007-01-12 19:56:19 +00002621 return;
2622 }
2623
2624 case FrameStateComplete:
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002625 m_loadType = FrameLoadType::Standard;
beidson@apple.comd1418272009-01-30 17:30:47 +00002626 frameLoadCompleted();
andersca4422e372007-01-12 19:56:19 +00002627 return;
2628 }
2629
2630 ASSERT_NOT_REACHED();
2631}
andersca5d5f8022007-02-28 00:38:00 +00002632
ap@apple.com456d4652011-11-30 12:13:31 +00002633void FrameLoader::setOriginalURLForDownloadRequest(ResourceRequest& request)
2634{
jiewen_tan@apple.com82836202016-03-31 20:39:24 +00002635 // FIXME: Rename firstPartyForCookies back to mainDocumentURL. It was a mistake to think that it was only used for cookies.
2636 // The originalURL is defined as the URL of the page where the download was initiated.
jiewen_tan@apple.com65b38162016-12-22 00:04:11 +00002637 URL originalURL;
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002638 auto* initiator = m_frame.document();
2639 if (initiator) {
2640 originalURL = initiator->firstPartyForCookies();
jiewen_tan@apple.com65b38162016-12-22 00:04:11 +00002641 // If there is no main document URL, it means that this document is newly opened and just for download purpose.
2642 // 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 +00002643 if (originalURL.isEmpty() && opener() && opener()->document()) {
jiewen_tan@apple.com65b38162016-12-22 00:04:11 +00002644 originalURL = opener()->document()->firstPartyForCookies();
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002645 initiator = opener()->document();
2646 }
jiewen_tan@apple.com65b38162016-12-22 00:04:11 +00002647 }
jiewen_tan@apple.com82836202016-03-31 20:39:24 +00002648 // If the originalURL is the same as the requested URL, we are processing a download
2649 // initiated directly without a page and do not need to specify the originalURL.
2650 if (originalURL == request.url())
2651 request.setFirstPartyForCookies(URL());
2652 else
2653 request.setFirstPartyForCookies(originalURL);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002654 addSameSiteInfoToRequestIfNeeded(request, initiator);
ap@apple.com456d4652011-11-30 12:13:31 +00002655}
2656
antti@apple.com8e03f742018-11-09 19:47:15 +00002657void FrameLoader::didReachLayoutMilestone(OptionSet<LayoutMilestone> milestones)
darinc370e7e2006-11-08 05:52:27 +00002658{
darin@apple.com0e83ab12013-09-28 17:19:04 +00002659 ASSERT(m_frame.isMainFrame());
bdakin@apple.com7ce7e1b2013-08-12 21:37:06 +00002660
simon.fraser@apple.com625ae9e2016-08-19 18:10:23 +00002661 m_client.dispatchDidReachLayoutMilestone(milestones);
bdakin@apple.com3ab37372012-02-01 21:52:41 +00002662}
2663
bdakin@apple.come98caf12012-09-25 23:08:03 +00002664void FrameLoader::didFirstLayout()
2665{
ap@apple.com1e8475922018-10-18 21:38:50 +00002666#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00002667 // Only send layout-related delegate callbacks synchronously for the main frame to
2668 // avoid reentering layout for the main frame while delivering a layout-related delegate
2669 // callback for a subframe.
2670 if (&m_frame != &m_frame.page()->mainFrame())
2671 return;
2672#endif
akling@apple.com7f50aae2013-08-22 16:01:31 +00002673 if (m_frame.page() && isBackForwardLoadType(m_loadType))
akling@apple.com672cb852013-08-22 20:27:27 +00002674 history().restoreScrollPositionAndViewState();
bdakin@apple.come98caf12012-09-25 23:08:03 +00002675
2676 if (m_stateMachine.committedFirstRealDocumentLoad() && !m_stateMachine.isDisplayingInitialEmptyDocument() && !m_stateMachine.firstLayoutDone())
2677 m_stateMachine.advanceTo(FrameLoaderStateMachine::FirstLayoutDone);
2678}
2679
darinc370e7e2006-11-08 05:52:27 +00002680void FrameLoader::frameLoadCompleted()
2681{
beidson@apple.comd1418272009-01-30 17:30:47 +00002682 // Note: Can be called multiple times.
2683
akling@apple.com7f50aae2013-08-22 16:01:31 +00002684 m_client.frameLoadCompleted();
darinc370e7e2006-11-08 05:52:27 +00002685
akling@apple.com672cb852013-08-22 20:27:27 +00002686 history().updateForFrameLoadCompleted();
beidson@apple.comd1418272009-01-30 17:30:47 +00002687
darinc370e7e2006-11-08 05:52:27 +00002688 // After a canceled provisional load, firstLayoutDone is false.
2689 // Reset it to true if we're displaying a page.
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00002690 if (m_documentLoader && m_stateMachine.committedFirstRealDocumentLoad() && !m_stateMachine.isDisplayingInitialEmptyDocument() && !m_stateMachine.firstLayoutDone())
2691 m_stateMachine.advanceTo(FrameLoaderStateMachine::FirstLayoutDone);
darinc370e7e2006-11-08 05:52:27 +00002692}
2693
darinc370e7e2006-11-08 05:52:27 +00002694void FrameLoader::detachChildren()
2695{
cdumez@apple.com8b478c62016-01-23 01:04:59 +00002696 // detachChildren() will fire the unload event in each subframe and the
2697 // HTML specification states that the parent document's ignore-opens-during-unload counter while
2698 // this event is being fired in its subframes:
2699 // https://html.spec.whatwg.org/multipage/browsers.html#unload-a-document
2700 IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
2701
cdumez@apple.comf0705d72019-07-01 21:55:03 +00002702 // detachChildren() will fire the unload event in each subframe and the
2703 // HTML specification states that navigations should be prevented during the prompt to unload algorithm:
2704 // https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate
2705 std::unique_ptr<NavigationDisabler> navigationDisabler;
2706 if (m_frame.isMainFrame())
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +00002707 navigationDisabler = makeUnique<NavigationDisabler>(&m_frame);
cdumez@apple.comf0705d72019-07-01 21:55:03 +00002708
cdumez@apple.com6857a012017-03-02 23:43:09 +00002709 // Any subframe inserted by unload event handlers executed in the loop below will not get unloaded
2710 // because we create a copy of the subframes list before looping. Therefore, it would be unsafe to
2711 // allow loading of subframes at this point.
2712 SubframeLoadingDisabler subframeLoadingDisabler(m_frame.document());
2713
akling@apple.com72c1c362013-09-06 01:34:05 +00002714 Vector<Ref<Frame>, 16> childrenToDetach;
2715 childrenToDetach.reserveInitialCapacity(m_frame.tree().childCount());
darin@apple.comfed4d162013-08-25 02:28:06 +00002716 for (Frame* child = m_frame.tree().lastChild(); child; child = child->tree().previousSibling())
akling@apple.com72c1c362013-09-06 01:34:05 +00002717 childrenToDetach.uncheckedAppend(*child);
commit-queue@webkit.orgacddfad2015-09-30 05:53:51 +00002718 for (auto& child : childrenToDetach)
2719 child->loader().detachFromParent();
darinc370e7e2006-11-08 05:52:27 +00002720}
2721
darin@apple.com9ace8012017-01-23 06:24:18 +00002722void FrameLoader::closeAndRemoveChild(Frame& child)
beidson@apple.com028c7a72009-02-11 22:01:22 +00002723{
darin@apple.com9ace8012017-01-23 06:24:18 +00002724 child.tree().detachFromParent();
beidson@apple.com028c7a72009-02-11 22:01:22 +00002725
darin@apple.com9ace8012017-01-23 06:24:18 +00002726 child.setView(nullptr);
2727 if (child.ownerElement() && child.page())
2728 child.page()->decrementSubframeCount();
2729 child.willDetachPage();
2730 child.detachFromPage();
beidson@apple.com028c7a72009-02-11 22:01:22 +00002731
darin@apple.comfed4d162013-08-25 02:28:06 +00002732 m_frame.tree().removeChild(child);
beidson@apple.com028c7a72009-02-11 22:01:22 +00002733}
2734
darin@apple.comaf8b1a92011-06-25 00:09:37 +00002735// Called every time a resource is completely loaded or an error is received.
darinc370e7e2006-11-08 05:52:27 +00002736void FrameLoader::checkLoadComplete()
2737{
darin@apple.comf53381b2009-09-23 23:27:01 +00002738 m_shouldCallCheckLoadComplete = false;
2739
akling@apple.com72c1c362013-09-06 01:34:05 +00002740 if (!m_frame.page())
2741 return;
2742
darin@apple.com355b1522017-08-15 18:13:57 +00002743 ASSERT(m_client.hasWebView());
2744
anderscaa315d572007-03-13 01:09:53 +00002745 // FIXME: Always traversing the entire frame tree is a bit inefficient, but
2746 // is currently needed in order to null out the previous history item for all frames.
akling@apple.com72c1c362013-09-06 01:34:05 +00002747 Vector<Ref<Frame>, 16> frames;
darin@apple.com0e83ab12013-09-28 17:19:04 +00002748 for (Frame* frame = &m_frame.mainFrame(); frame; frame = frame->tree().traverseNext())
akling@apple.com72c1c362013-09-06 01:34:05 +00002749 frames.append(*frame);
2750
2751 // To process children before their parents, iterate the vector backwards.
jiewen_tan@apple.combe26fa32015-12-01 00:33:47 +00002752 for (auto frame = frames.rbegin(); frame != frames.rend(); ++frame) {
2753 if ((*frame)->page())
2754 (*frame)->loader().checkLoadCompleteForThisFrame();
2755 }
darinc370e7e2006-11-08 05:52:27 +00002756}
2757
2758int FrameLoader::numPendingOrLoadingRequests(bool recurse) const
2759{
2760 if (!recurse)
cdumez@apple.com0bb03ec2015-01-28 05:53:53 +00002761 return m_frame.document()->cachedResourceLoader().requestCount();
darinc370e7e2006-11-08 05:52:27 +00002762
2763 int count = 0;
darin@apple.comfed4d162013-08-25 02:28:06 +00002764 for (Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext(&m_frame))
cdumez@apple.com0bb03ec2015-01-28 05:53:53 +00002765 count += frame->document()->cachedResourceLoader().requestCount();
darinc370e7e2006-11-08 05:52:27 +00002766 return count;
2767}
2768
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00002769String FrameLoader::userAgent(const URL& url) const
darinc370e7e2006-11-08 05:52:27 +00002770{
drousso@apple.comc9a88bd2019-01-26 22:32:38 +00002771 String userAgent;
2772
2773 if (auto* documentLoader = m_frame.mainFrame().loader().activeDocumentLoader())
2774 userAgent = documentLoader->customUserAgent();
2775
2776 InspectorInstrumentation::applyUserAgentOverride(m_frame, userAgent);
2777
2778 if (!userAgent.isEmpty())
2779 return userAgent;
cdumez@apple.com96b28c82018-12-10 21:26:39 +00002780
seokju@webkit.orgcb8504d2014-01-09 17:19:34 +00002781 return m_client.userAgent(url);
darinc370e7e2006-11-08 05:52:27 +00002782}
rniwa@webkit.org15470912019-01-26 06:50:58 +00002783
2784String FrameLoader::userAgentForJavaScript(const URL& url) const
2785{
drousso@apple.comc9a88bd2019-01-26 22:32:38 +00002786 String userAgent;
2787
rniwa@webkit.org15470912019-01-26 06:50:58 +00002788 if (auto* documentLoader = m_frame.mainFrame().loader().activeDocumentLoader()) {
rniwa@webkit.orgaf0b1ae2019-01-29 07:15:00 +00002789 if (m_frame.settings().needsSiteSpecificQuirks())
2790 userAgent = documentLoader->customJavaScriptUserAgentAsSiteSpecificQuirks();
drousso@apple.comc9a88bd2019-01-26 22:32:38 +00002791 if (userAgent.isEmpty())
2792 userAgent = documentLoader->customUserAgent();
rniwa@webkit.org15470912019-01-26 06:50:58 +00002793 }
2794
drousso@apple.comc9a88bd2019-01-26 22:32:38 +00002795 InspectorInstrumentation::applyUserAgentOverride(m_frame, userAgent);
2796
2797 if (!userAgent.isEmpty())
2798 return userAgent;
2799
rniwa@webkit.org15470912019-01-26 06:50:58 +00002800 return m_client.userAgent(url);
2801}
megan_gardner@apple.comde788db2018-12-19 20:21:31 +00002802
2803String FrameLoader::navigatorPlatform() const
2804{
2805 if (auto* documentLoader = m_frame.mainFrame().loader().activeDocumentLoader()) {
2806 auto& customNavigatorPlatform = documentLoader->customNavigatorPlatform();
2807 if (!customNavigatorPlatform.isEmpty())
2808 return customNavigatorPlatform;
2809 }
2810 return String();
2811}
darinc370e7e2006-11-08 05:52:27 +00002812
ggaren@apple.com7a176e12015-11-12 01:48:27 +00002813void FrameLoader::dispatchOnloadEvents()
darinc370e7e2006-11-08 05:52:27 +00002814{
ggaren@apple.com7a176e12015-11-12 01:48:27 +00002815 m_client.dispatchDidDispatchOnloadEvents();
japhet@chromium.org92a952b2010-07-12 18:14:17 +00002816
darin@apple.comaf8b1a92011-06-25 00:09:37 +00002817 if (documentLoader())
ggaren@apple.com7a176e12015-11-12 01:48:27 +00002818 documentLoader()->dispatchOnloadEvents();
darinc370e7e2006-11-08 05:52:27 +00002819}
2820
2821void FrameLoader::frameDetached()
2822{
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00002823 // Calling stopAllLoadersAndCheckCompleteness() can cause the frame to be deallocated, including the frame loader.
bfulgham@apple.com98845d92016-05-17 01:09:27 +00002824 Ref<Frame> protectedFrame(m_frame);
2825
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00002826 if (m_checkTimer.isActive()) {
2827 m_checkTimer.stop();
2828 checkCompletenessNow();
2829 }
2830
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002831 if (m_frame.document()->backForwardCacheState() != Document::InBackForwardCache) {
rniwa@webkit.org1a1b5202018-06-01 22:30:02 +00002832 stopAllLoadersAndCheckCompleteness();
dbates@webkit.org6d862de2017-02-11 02:53:53 +00002833 m_frame.document()->stopActiveDOMObjects();
2834 }
2835
darinc370e7e2006-11-08 05:52:27 +00002836 detachFromParent();
2837}
2838
ggarenc04b2c52006-11-30 21:06:14 +00002839void FrameLoader::detachFromParent()
darinc370e7e2006-11-08 05:52:27 +00002840{
dbates@webkit.org6d862de2017-02-11 02:53:53 +00002841 // Calling stopAllLoaders() can cause the frame to be deallocated, including the frame loader.
akling@apple.coma34e5222013-09-10 03:44:05 +00002842 Ref<Frame> protect(m_frame);
ggarenc04b2c52006-11-30 21:06:14 +00002843
ggarenacf28742006-12-27 07:38:18 +00002844 closeURL();
akling@apple.com672cb852013-08-22 20:27:27 +00002845 history().saveScrollPositionAndViewStateToItem(history().currentItem());
ggarenc04b2c52006-11-30 21:06:14 +00002846 detachChildren();
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00002847 if (m_frame.document()->backForwardCacheState() != Document::InBackForwardCache) {
2848 // 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 +00002849 // because detachedChildren() will trigger the unload event handlers of any child frames, and those event
2850 // handlers might start a new subresource load in this frame.
ajuma@chromium.orgedd75742019-09-11 14:52:18 +00002851 stopAllLoaders(ShouldClearProvisionalItem, StopLoadingPolicy::AlwaysStopLoading);
dbates@webkit.org6d862de2017-02-11 02:53:53 +00002852 }
arobendfc56662007-06-21 01:37:24 +00002853
burg@cs.washington.edudbacfc12015-01-05 21:30:33 +00002854 InspectorInstrumentation::frameDetachedFromParent(m_frame);
arobendfc56662007-06-21 01:37:24 +00002855
beidson@apple.com24f92a52009-09-03 00:07:51 +00002856 detachViewsAndDocumentLoader();
2857
weinig@apple.comeefc25d2013-11-08 22:42:27 +00002858 m_progressTracker = nullptr;
japhet@chromium.org7879dd72012-08-30 02:58:37 +00002859
darin@apple.comfed4d162013-08-25 02:28:06 +00002860 if (Frame* parent = m_frame.tree().parent()) {
darin@apple.com9ace8012017-01-23 06:24:18 +00002861 parent->loader().closeAndRemoveChild(m_frame);
andersca@apple.comdf550b92013-08-15 22:17:17 +00002862 parent->loader().scheduleCheckCompleted();
darin@apple.combe4d3dd2017-07-30 21:44:01 +00002863 parent->loader().scheduleCheckLoadComplete();
weinigc34c71c2007-03-09 16:05:37 +00002864 } else {
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00002865 m_frame.setView(nullptr);
akling@apple.com7f50aae2013-08-22 16:01:31 +00002866 m_frame.willDetachPage();
2867 m_frame.detachFromPage();
ddkilzer3adeb2f2006-12-28 23:33:37 +00002868 }
ggarenc04b2c52006-11-30 21:06:14 +00002869}
beidson@apple.com24f92a52009-09-03 00:07:51 +00002870
2871void FrameLoader::detachViewsAndDocumentLoader()
2872{
akling@apple.com7f50aae2013-08-22 16:01:31 +00002873 m_client.detachedFromParent2();
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00002874 setDocumentLoader(nullptr);
akling@apple.com7f50aae2013-08-22 16:01:31 +00002875 m_client.detachedFromParent3();
beidson@apple.com24f92a52009-09-03 00:07:51 +00002876}
antti@apple.com4da613e2008-12-15 15:28:41 +00002877
2878void FrameLoader::addExtraFieldsToSubresourceRequest(ResourceRequest& request)
2879{
jochen@chromium.orgdac140c2011-08-01 21:18:49 +00002880 addExtraFieldsToRequest(request, m_loadType, false);
antti@apple.com4da613e2008-12-15 15:28:41 +00002881}
darinc370e7e2006-11-08 05:52:27 +00002882
antti@apple.com4da613e2008-12-15 15:28:41 +00002883void FrameLoader::addExtraFieldsToMainResourceRequest(ResourceRequest& request)
2884{
ap@apple.com8d5f01b2013-01-07 18:40:55 +00002885 // FIXME: Using m_loadType seems wrong for some callers.
2886 // If we are only preparing to load the main resource, that is previous load's load type!
jochen@chromium.orgdac140c2011-08-01 21:18:49 +00002887 addExtraFieldsToRequest(request, m_loadType, true);
bfulgham@apple.comb30d7f82016-06-07 15:47:30 +00002888
2889 // Upgrade-Insecure-Requests should only be added to main resource requests
2890 addHTTPUpgradeInsecureRequestsIfNeeded(request);
antti@apple.com4da613e2008-12-15 15:28:41 +00002891}
2892
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002893ResourceRequestCachePolicy FrameLoader::defaultRequestCachingPolicy(const ResourceRequest& request, FrameLoadType loadType, bool isMainResource)
beidson50c3bd82007-01-03 03:11:18 +00002894{
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002895 if (m_overrideCachePolicyForTesting)
2896 return m_overrideCachePolicyForTesting.value();
antti@apple.com5d0c5402017-03-17 19:52:49 +00002897
2898 if (isMainResource) {
2899 if (isReload(loadType) || request.isConditional())
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002900 return ResourceRequestCachePolicy::ReloadIgnoringCacheData;
antti@apple.com5d0c5402017-03-17 19:52:49 +00002901
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002902 return ResourceRequestCachePolicy::UseProtocolCachePolicy;
antti@apple.com5d0c5402017-03-17 19:52:49 +00002903 }
2904
2905 if (request.isConditional())
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002906 return ResourceRequestCachePolicy::ReloadIgnoringCacheData;
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002907
antti@apple.com5d0c5402017-03-17 19:52:49 +00002908 if (documentLoader()->isLoadingInAPISense()) {
2909 // If we inherit cache policy from a main resource, we use the DocumentLoader's
2910 // original request cache policy for two reasons:
2911 // 1. For POST requests, we mutate the cache policy for the main resource,
2912 // but we do not want this to apply to subresources
2913 // 2. Delegates that modify the cache policy using willSendRequest: should
2914 // not affect any other resources. Such changes need to be done
2915 // per request.
2916 ResourceRequestCachePolicy mainDocumentOriginalCachePolicy = documentLoader()->originalRequest().cachePolicy();
2917 // 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.
2918 // This policy is set on initial request too, but should not be inherited.
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002919 return (mainDocumentOriginalCachePolicy == ResourceRequestCachePolicy::ReturnCacheDataDontLoad) ? ResourceRequestCachePolicy::ReturnCacheDataElseLoad : mainDocumentOriginalCachePolicy;
antti@apple.com5d0c5402017-03-17 19:52:49 +00002920 }
2921
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002922 return ResourceRequestCachePolicy::UseProtocolCachePolicy;
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002923}
2924
2925void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadType loadType, bool isMainResource)
2926{
cdumez@apple.com3aedc032019-01-31 02:23:55 +00002927 // If the request came from a previous process due to process-swap-on-navigation then we should not modify the request.
2928 if (m_currentLoadContinuingState == LoadContinuingState::ContinuingWithRequest)
cdumez@apple.comfdb89712018-06-11 20:52:31 +00002929 return;
2930
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002931 // Don't set the cookie policy URL if it's already been set.
2932 // But make sure to set it on all requests regardless of protocol, as it has significance beyond the cookie policy (<rdar://problem/6616664>).
dbates@webkit.org2dc5b0d2019-02-21 23:54:40 +00002933 bool isMainFrameMainResource = isMainResource && m_frame.isMainFrame();
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002934 if (request.firstPartyForCookies().isEmpty()) {
dbates@webkit.org2dc5b0d2019-02-21 23:54:40 +00002935 if (isMainFrameMainResource)
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002936 request.setFirstPartyForCookies(request.url());
2937 else if (Document* document = m_frame.document())
2938 request.setFirstPartyForCookies(document->firstPartyForCookies());
2939 }
2940
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002941 if (request.isSameSiteUnspecified()) {
2942 auto* initiator = m_frame.document();
2943 if (isMainResource) {
2944 auto* ownerFrame = m_frame.tree().parent();
dbates@webkit.org1e858552018-06-30 02:11:01 +00002945 if (!ownerFrame && m_stateMachine.isDisplayingInitialEmptyDocument())
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002946 ownerFrame = m_opener;
2947 if (ownerFrame)
2948 initiator = ownerFrame->document();
2949 ASSERT(ownerFrame || m_frame.isMainFrame());
2950 }
2951 addSameSiteInfoToRequestIfNeeded(request, initiator);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002952 }
dbates@webkit.org2dc5b0d2019-02-21 23:54:40 +00002953 request.setIsTopSite(isMainFrameMainResource);
dbates@webkit.org8c917f22018-04-24 07:36:59 +00002954
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002955 Page* page = frame().page();
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002956 bool hasSpecificCachePolicy = request.cachePolicy() != ResourceRequestCachePolicy::UseProtocolCachePolicy;
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002957
cdumez@apple.coma231c912019-10-16 18:24:25 +00002958 if (page && page->isResourceCachingDisabledByWebInspector()) {
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002959 request.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002960 loadType = FrameLoadType::ReloadFromOrigin;
2961 } else if (!hasSpecificCachePolicy)
2962 request.setCachePolicy(defaultRequestCachingPolicy(request, loadType, isMainResource));
ap@apple.com8d5f01b2013-01-07 18:40:55 +00002963
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002964 // The remaining modifications are only necessary for HTTP and HTTPS.
2965 if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
2966 return;
antti@apple.com7c97e2c2015-03-19 05:21:40 +00002967
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00002968 if (!hasSpecificCachePolicy && request.cachePolicy() == ResourceRequestCachePolicy::ReloadIgnoringCacheData) {
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002969 if (loadType == FrameLoadType::Reload)
andersca@apple.coma96cf712014-06-14 17:49:44 +00002970 request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0");
andersca@apple.comb50fcc32014-06-19 00:13:20 +00002971 else if (loadType == FrameLoadType::ReloadFromOrigin) {
andersca@apple.coma96cf712014-06-14 17:49:44 +00002972 request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "no-cache");
2973 request.setHTTPHeaderField(HTTPHeaderName::Pragma, "no-cache");
japhet@chromium.org1e313142010-08-31 22:53:31 +00002974 }
2975 }
darin@apple.com0fdefc32016-03-18 07:56:20 +00002976
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002977 if (m_overrideResourceLoadPriorityForTesting)
2978 request.setPriority(m_overrideResourceLoadPriorityForTesting.value());
2979
Ms2ger@igalia.comc33b77c2017-11-10 16:41:03 +00002980 applyUserAgentIfNeeded(request);
commit-queue@webkit.org79f5a002016-10-11 10:53:22 +00002981
2982 if (isMainResource)
staikos@webkit.org159f11f2009-05-18 23:48:30 +00002983 request.setHTTPAccept(defaultAcceptHeader);
abarth@webkit.orgfb074382008-10-05 19:12:30 +00002984
2985 // Make sure we send the Origin header.
2986 addHTTPOriginIfNeeded(request, String());
ap@webkit.org113cb8c2008-12-05 14:43:53 +00002987
ap@apple.com9454f7c2013-06-20 20:06:02 +00002988 // Only set fallback array if it's still empty (later attempts may be incorrect, see bug 117818).
2989 if (request.responseContentDispositionEncodingFallbackArray().isEmpty()) {
2990 // Always try UTF-8. If that fails, try frame encoding (if any) and then the default.
akling@apple.com7f50aae2013-08-22 16:01:31 +00002991 request.setResponseContentDispositionEncodingFallbackArray("UTF-8", m_frame.document()->encoding(), m_frame.settings().defaultTextEncodingName());
ap@apple.com9454f7c2013-06-20 20:06:02 +00002992 }
abarth@webkit.orgfb074382008-10-05 19:12:30 +00002993}
2994
tony@chromium.orgc1443b72011-06-24 22:05:16 +00002995void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, const String& origin)
abarth@webkit.orgfb074382008-10-05 19:12:30 +00002996{
2997 if (!request.httpOrigin().isEmpty())
2998 return; // Request already has an Origin header.
2999
3000 // Don't send an Origin header for GET or HEAD to avoid privacy issues.
3001 // For example, if an intranet page has a hyperlink to an external web
3002 // site, we don't want to include the Origin of the request because it
3003 // will leak the internal host name. Similar privacy concerns have lead
3004 // to the widespread suppression of the Referer header at the network
3005 // layer.
3006 if (request.httpMethod() == "GET" || request.httpMethod() == "HEAD")
3007 return;
3008
3009 // For non-GET and non-HEAD methods, always send an Origin header so the
3010 // server knows we support this feature.
3011
3012 if (origin.isEmpty()) {
3013 // If we don't know what origin header to attach, we attach the value
3014 // for an empty origin.
abarth@webkit.org29f0c1a2011-11-05 01:32:07 +00003015 request.setHTTPOrigin(SecurityOrigin::createUnique()->toString());
tony@chromium.orgc1443b72011-06-24 22:05:16 +00003016 return;
abarth@webkit.orgfb074382008-10-05 19:12:30 +00003017 }
3018
3019 request.setHTTPOrigin(origin);
beidson50c3bd82007-01-03 03:11:18 +00003020}
3021
dbates@webkit.org8c917f22018-04-24 07:36:59 +00003022// 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>.
3023// The algorithm is ammended to treat URLs that inherit their security origin from their owner (e.g. about:blank)
3024// as same-site. This matches the behavior of Chrome and Firefox.
3025void FrameLoader::addSameSiteInfoToRequestIfNeeded(ResourceRequest& request, const Document* initiator)
3026{
3027 if (!request.isSameSiteUnspecified())
3028 return;
3029 if (!initiator) {
3030 request.setIsSameSite(true);
3031 return;
3032 }
3033 if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(request.url())) {
3034 request.setIsSameSite(true);
3035 return;
3036 }
cdumez@apple.com0b8674fb2019-03-13 19:53:41 +00003037 request.setIsSameSite(areRegistrableDomainsEqual(initiator->siteForCookies(), request.url()));
dbates@webkit.org8c917f22018-04-24 07:36:59 +00003038}
3039
bfulgham@apple.comb30d7f82016-06-07 15:47:30 +00003040void FrameLoader::addHTTPUpgradeInsecureRequestsIfNeeded(ResourceRequest& request)
3041{
3042 if (request.url().protocolIs("https")) {
3043 // FIXME: Identify HSTS cases and avoid adding the header. <https://bugs.webkit.org/show_bug.cgi?id=157885>
3044 return;
3045 }
3046
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00003047 request.setHTTPHeaderField(HTTPHeaderName::UpgradeInsecureRequests, "1"_s);
bfulgham@apple.comb30d7f82016-06-07 15:47:30 +00003048}
3049
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00003050void FrameLoader::loadPostRequest(FrameLoadRequest&& request, const String& referrer, FrameLoadType loadType, Event* event, RefPtr<FormState>&& formState, CompletionHandler<void()>&& completionHandler)
anderscade5715d2007-01-06 00:55:49 +00003051{
krollin@apple.come1810b62018-12-20 19:23:20 +00003052 RELEASE_LOG_IF_ALLOWED("loadPostRequest: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
3053
beidson@apple.combd66a782015-05-29 16:31:49 +00003054 String frameName = request.frameName();
3055 LockHistory lockHistory = request.lockHistory();
3056 AllowNavigationToInvalidURL allowNavigationToInvalidURL = request.allowNavigationToInvalidURL();
3057 NewFrameOpenerPolicy openerPolicy = request.newFrameOpenerPolicy();
3058
3059 const ResourceRequest& inRequest = request.resourceRequest();
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003060 const URL& url = inRequest.url();
mrowe@apple.com713db2e2008-07-27 03:49:29 +00003061 const String& contentType = inRequest.httpContentType();
abarth@webkit.orgfb074382008-10-05 19:12:30 +00003062 String origin = inRequest.httpOrigin();
mrowe@apple.com713db2e2008-07-27 03:49:29 +00003063
3064 ResourceRequest workingResourceRequest(url);
anderscade5715d2007-01-06 00:55:49 +00003065
3066 if (!referrer.isEmpty())
mrowe@apple.com713db2e2008-07-27 03:49:29 +00003067 workingResourceRequest.setHTTPReferrer(referrer);
abarth@webkit.orgfb074382008-10-05 19:12:30 +00003068 workingResourceRequest.setHTTPOrigin(origin);
mrowe@apple.com713db2e2008-07-27 03:49:29 +00003069 workingResourceRequest.setHTTPMethod("POST");
youenn.fablet@crf.canon.fr11cc6552016-01-22 14:51:16 +00003070 workingResourceRequest.setHTTPBody(inRequest.httpBody());
mrowe@apple.com713db2e2008-07-27 03:49:29 +00003071 workingResourceRequest.setHTTPContentType(contentType);
jochen@chromium.orgdac140c2011-08-01 21:18:49 +00003072 addExtraFieldsToRequest(workingResourceRequest, loadType, true);
anderscade5715d2007-01-06 00:55:49 +00003073
bfulgham@apple.comb30d7f82016-06-07 15:47:30 +00003074 if (Document* document = m_frame.document())
3075 document->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(workingResourceRequest, ContentSecurityPolicy::InsecureRequestType::Load);
3076
dbates@webkit.org9692a072017-07-12 18:01:19 +00003077 NavigationAction action { request.requester(), workingResourceRequest, request.initiatedByMainFrame(), loadType, true, event, request.shouldOpenExternalURLsPolicy(), request.downloadAttribute() };
anderscade5715d2007-01-06 00:55:49 +00003078
anderscade5715d2007-01-06 00:55:49 +00003079 if (!frameName.isEmpty()) {
darin@apple.com0f88bda2009-04-02 00:30:50 +00003080 // The search for a target frame is done earlier in the case of form submission.
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00003081 if (auto* targetFrame = formState ? nullptr : findFrameForNavigation(frameName)) {
commit-queue@webkit.orga4a9ce22019-04-10 22:56:35 +00003082 targetFrame->loader().loadWithNavigationAction(workingResourceRequest, WTFMove(action), lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, { }, WTFMove(completionHandler));
andersca@apple.com096333f2013-11-07 21:37:36 +00003083 return;
darin@chromium.org1e25ab72012-04-02 20:14:07 +00003084 }
andersca@apple.com096333f2013-11-07 21:37:36 +00003085
achristensen@apple.comb075c902018-07-27 22:29:58 +00003086 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, ShouldContinue shouldContinue) mutable {
bfulgham@apple.com657c5c72018-05-24 05:23:00 +00003087 continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
cdumez@apple.comb76757c2018-03-06 22:01:27 +00003088 completionHandler();
andersca@apple.com096333f2013-11-07 21:37:36 +00003089 });
3090 return;
3091 }
3092
3093 // must grab this now, since this load may stop the previous load and clear this flag
3094 bool isRedirect = m_quickRedirectComing;
commit-queue@webkit.orga4a9ce22019-04-10 22:56:35 +00003095 loadWithNavigationAction(workingResourceRequest, WTFMove(action), lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, { }, [this, isRedirect, protectedFrame = makeRef(m_frame), completionHandler = WTFMove(completionHandler)] () mutable {
cdumez@apple.comb76757c2018-03-06 22:01:27 +00003096 if (isRedirect) {
3097 m_quickRedirectComing = false;
3098 if (m_provisionalDocumentLoader)
3099 m_provisionalDocumentLoader->setIsClientRedirect(true);
3100 else if (m_policyDocumentLoader)
3101 m_policyDocumentLoader->setIsClientRedirect(true);
3102 }
3103 completionHandler();
3104 });
anderscade5715d2007-01-06 00:55:49 +00003105}
3106
youenn@apple.comb9709cc2018-04-16 21:50:26 +00003107unsigned 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 +00003108{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003109 ASSERT(m_frame.document());
3110 String referrer = SecurityPolicy::generateReferrerHeader(m_frame.document()->referrerPolicy(), request.url(), outgoingReferrer());
anderscade5715d2007-01-06 00:55:49 +00003111
3112 ResourceRequest initialRequest = request;
3113 initialRequest.setTimeoutInterval(10);
3114
anderscade5715d2007-01-06 00:55:49 +00003115 if (!referrer.isEmpty())
3116 initialRequest.setHTTPReferrer(referrer);
abarth@webkit.orgfb074382008-10-05 19:12:30 +00003117 addHTTPOriginIfNeeded(initialRequest, outgoingOrigin());
darine0cef432007-07-10 19:21:23 +00003118
darin@apple.com0e83ab12013-09-28 17:19:04 +00003119 initialRequest.setFirstPartyForCookies(m_frame.mainFrame().loader().documentLoader()->request().url());
japhet@chromium.org92a952b2010-07-12 18:14:17 +00003120
3121 addExtraFieldsToSubresourceRequest(initialRequest);
darine0cef432007-07-10 19:21:23 +00003122
anderscaec429f52007-01-13 01:44:24 +00003123 unsigned long identifier = 0;
anderscade5715d2007-01-06 00:55:49 +00003124 ResourceRequest newRequest(initialRequest);
3125 requestFromDelegate(newRequest, identifier, error);
3126
beidson@apple.come3ea01d2015-07-02 18:33:23 +00003127#if ENABLE(CONTENT_EXTENSIONS)
3128 if (error.isNull()) {
commit-queue@webkit.org8090ccb2015-10-06 08:18:08 +00003129 if (auto* page = m_frame.page()) {
commit-queue@webkit.org3d339842016-08-04 18:07:45 +00003130 if (m_documentLoader) {
achristensen@apple.comb80d3422019-04-26 17:03:15 +00003131 auto results = page->userContentProvider().processContentRuleListsForLoad(newRequest.url(), ContentExtensions::ResourceType::Raw, *m_documentLoader);
achristensen@apple.comd3edc2a2019-03-21 20:23:46 +00003132 bool blockedLoad = results.summary.blockedLoad;
3133 ContentExtensions::applyResultsToRequest(WTFMove(results), page, newRequest);
3134 if (blockedLoad) {
commit-queue@webkit.org3d339842016-08-04 18:07:45 +00003135 newRequest = { };
3136 error = ResourceError(errorDomainWebKitInternal, 0, initialRequest.url(), emptyString());
3137 response = { };
3138 data = nullptr;
3139 }
beidson@apple.come3ea01d2015-07-02 18:33:23 +00003140 }
3141 }
beidson@apple.come3ea01d2015-07-02 18:33:23 +00003142 }
3143#endif
3144
bfulgham@apple.comb30d7f82016-06-07 15:47:30 +00003145 m_frame.document()->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(newRequest, ContentSecurityPolicy::InsecureRequestType::Load);
3146
anderscade5715d2007-01-06 00:55:49 +00003147 if (error.isNull()) {
3148 ASSERT(!newRequest.isNull());
youenn.fablet@crf.canon.fr0aef67f2015-04-29 08:18:10 +00003149
darin@apple.comc04189e2017-01-18 05:17:17 +00003150 if (!documentLoader()->applicationCacheHost().maybeLoadSynchronously(newRequest, error, response, data)) {
youenn.fablet@crf.canon.fr0aef67f2015-04-29 08:18:10 +00003151 Vector<char> buffer;
youenn@apple.comb9709cc2018-04-16 21:50:26 +00003152 platformStrategies()->loaderStrategy()->loadResourceSynchronously(*this, identifier, newRequest, clientCredentialPolicy, options, originalRequestHeaders, error, response, buffer);
commit-queue@webkit.org08f38b92017-04-12 09:25:04 +00003153 data = SharedBuffer::create(WTFMove(buffer));
darin@apple.comc04189e2017-01-18 05:17:17 +00003154 documentLoader()->applicationCacheHost().maybeLoadFallbackSynchronously(newRequest, error, response, data);
cdumez@apple.com77085452017-06-30 18:18:19 +00003155 ResourceLoadObserver::shared().logSubresourceLoading(&m_frame, newRequest, response);
ap@webkit.orgfb96f8a2009-01-02 09:25:02 +00003156 }
anderscade5715d2007-01-06 00:55:49 +00003157 }
youenn.fablet@crf.canon.fr0aef67f2015-04-29 08:18:10 +00003158 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 +00003159 return identifier;
anderscade5715d2007-01-06 00:55:49 +00003160}
3161
anderscade5715d2007-01-06 00:55:49 +00003162const ResourceRequest& FrameLoader::originalRequest() const
3163{
3164 return activeDocumentLoader()->originalRequestCopy();
3165}
3166
japhet@chromium.org7f7bee42012-03-29 23:17:09 +00003167void FrameLoader::receivedMainResourceError(const ResourceError& error)
anderscade5715d2007-01-06 00:55:49 +00003168{
3169 // Retain because the stop may release the last reference to it.
akling@apple.comf8515982013-09-02 18:50:01 +00003170 Ref<Frame> protect(m_frame);
anderscade5715d2007-01-06 00:55:49 +00003171
3172 RefPtr<DocumentLoader> loader = activeDocumentLoader();
japhet@chromium.org7f7bee42012-03-29 23:17:09 +00003173 // FIXME: Don't want to do this if an entirely new load is going, so should check
3174 // that both data sources on the frame are either this or nil.
3175 stop();
akling@apple.com7f50aae2013-08-22 16:01:31 +00003176 if (m_client.shouldFallBack(error))
japhet@chromium.org7f7bee42012-03-29 23:17:09 +00003177 handleFallbackContent();
abarth@webkit.org1c893f42009-10-10 02:27:21 +00003178
lars8bf288d2007-10-04 08:45:12 +00003179 if (m_state == FrameStateProvisional && m_provisionalDocumentLoader) {
darin@apple.com4cd1b242009-03-27 23:37:46 +00003180 if (m_submittedFormURL == m_provisionalDocumentLoader->originalRequestCopy().url())
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003181 m_submittedFormURL = URL();
anttiac25cb42007-03-02 07:59:15 +00003182
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003183 // 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 +00003184 // transitioned to the new page (before WebFrameState == commit). The goal here is to restore any state
3185 // so that the existing view (that wenever got far enough to replace) can continue being used.
akling@apple.com672cb852013-08-22 20:27:27 +00003186 history().invalidateCurrentItemCachedPage();
anderscade5715d2007-01-06 00:55:49 +00003187
3188 // Call clientRedirectCancelledOrFinished here so that the frame load delegate is notified that the redirect's
3189 // status has changed, if there was a redirect. The frame load delegate may have saved some state about
3190 // the redirect in its -webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:. Since we are definitely
3191 // not going to use this provisional resource, as it was cancelled, notify the frame load delegate that the redirect
3192 // has ended.
3193 if (m_sentRedirectNotification)
achristensen@apple.com6fddc912018-10-18 21:16:52 +00003194 clientRedirectCancelledOrFinished(NewLoadInProgress::No);
anderscade5715d2007-01-06 00:55:49 +00003195 }
abarth@webkit.org1c893f42009-10-10 02:27:21 +00003196
japhet@chromium.org7f7bee42012-03-29 23:17:09 +00003197 checkCompleted();
akling@apple.com7f50aae2013-08-22 16:01:31 +00003198 if (m_frame.page())
japhet@chromium.org7f7bee42012-03-29 23:17:09 +00003199 checkLoadComplete();
anderscade5715d2007-01-06 00:55:49 +00003200}
3201
anderscade5715d2007-01-06 00:55:49 +00003202void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue)
3203{
anderscade5715d2007-01-06 00:55:49 +00003204 m_quickRedirectComing = false;
darin4e5519d2007-01-22 02:46:06 +00003205
3206 if (!shouldContinue)
3207 return;
3208
bfulgham@apple.com98845d92016-05-17 01:09:27 +00003209 // Calling stopLoading() on the provisional document loader can cause the underlying
3210 // frame to be deallocated.
3211 Ref<Frame> protectedFrame(m_frame);
3212
mihaip@chromium.orgd5123ba2011-09-16 02:16:46 +00003213 // If we have a provisional request for a different document, a fragment scroll should cancel it.
3214 if (m_provisionalDocumentLoader && !equalIgnoringFragmentIdentifier(m_provisionalDocumentLoader->request().url(), request.url())) {
3215 m_provisionalDocumentLoader->stopLoading();
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00003216 setProvisionalDocumentLoader(nullptr);
mihaip@chromium.orgd5123ba2011-09-16 02:16:46 +00003217 }
3218
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003219 bool isRedirect = m_quickRedirectComing || policyChecker().loadType() == FrameLoadType::RedirectWithLockedBackForwardList;
beidson@apple.com08c61752009-12-03 19:04:40 +00003220 loadInSameDocument(request.url(), 0, !isRedirect);
anderscade5715d2007-01-06 00:55:49 +00003221}
3222
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003223bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType loadType, const URL& url)
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00003224{
yael.aharon@nokia.com79f69052010-12-30 19:31:00 +00003225 // 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 +00003226 // currently displaying a frameset, or if the URL does not have a fragment.
3227 // These rules were originally based on what KHTML was doing in KHTMLPart::openURL.
3228
3229 // FIXME: What about load types other than Standard and Reload?
3230
darin@apple.com048cc3a2016-01-22 17:17:04 +00003231 return (!isFormSubmission || equalLettersIgnoringASCIICase(httpMethod, "get"))
antti@apple.com5d0c5402017-03-17 19:52:49 +00003232 && !isReload(loadType)
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003233 && loadType != FrameLoadType::Same
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003234 && m_frame.document()->backForwardCacheState() != Document::InBackForwardCache
akling@apple.com7f50aae2013-08-22 16:01:31 +00003235 && !shouldReload(m_frame.document()->url(), url)
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00003236 // We don't want to just scroll if a link from within a
3237 // frameset is trying to reload the frameset into _top.
akling@apple.com7f50aae2013-08-22 16:01:31 +00003238 && !m_frame.document()->isFrameSet();
ddkilzer@apple.com8c272a82008-07-12 21:33:52 +00003239}
3240
simon.fraser@apple.comc79e4862017-03-08 20:01:15 +00003241static bool itemAllowsScrollRestoration(HistoryItem* historyItem)
3242{
simon.fraser@apple.com804555f2017-11-29 20:41:47 +00003243 return !historyItem || historyItem->shouldRestoreScrollPosition();
simon.fraser@apple.comc79e4862017-03-08 20:01:15 +00003244}
3245
3246static bool isSameDocumentReload(bool isNewNavigation, FrameLoadType loadType)
3247{
3248 return !isNewNavigation && !isBackForwardLoadType(loadType);
3249}
3250
3251void FrameLoader::scrollToFragmentWithParentBoundary(const URL& url, bool isNewNavigation)
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00003252{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003253 FrameView* view = m_frame.view();
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00003254 if (!view)
3255 return;
3256
simon.fraser@apple.comc79e4862017-03-08 20:01:15 +00003257 if (isSameDocumentReload(isNewNavigation, m_loadType) || itemAllowsScrollRestoration(history().currentItem()))
3258 view->scrollToFragment(url);
tsepez@chromium.orgf8960562012-04-06 22:15:02 +00003259}
3260
beidson@apple.com7617ce72010-05-13 20:31:46 +00003261bool FrameLoader::shouldClose()
3262{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003263 Page* page = m_frame.page();
akling@apple.combd774812013-05-17 00:03:01 +00003264 if (!page)
3265 return true;
3266 if (!page->chrome().canRunBeforeUnloadConfirmPanel())
beidson@apple.com7617ce72010-05-13 20:31:46 +00003267 return true;
3268
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003269 // Store all references to each subframe in advance since beforeunload's event handler may modify frame
akling@apple.com72c1c362013-09-06 01:34:05 +00003270 Vector<Ref<Frame>, 16> targetFrames;
3271 targetFrames.append(m_frame);
darin@apple.comfed4d162013-08-25 02:28:06 +00003272 for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().traverseNext(&m_frame))
akling@apple.com72c1c362013-09-06 01:34:05 +00003273 targetFrames.append(*child);
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003274
3275 bool shouldClose = false;
3276 {
rniwa@webkit.orgf694bd62017-06-30 19:32:41 +00003277 NavigationDisabler navigationDisabler(&m_frame);
cdumez@apple.come4df29d2018-09-26 19:29:54 +00003278 IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003279 size_t i;
3280
3281 for (i = 0; i < targetFrames.size(); i++) {
darin@apple.comfed4d162013-08-25 02:28:06 +00003282 if (!targetFrames[i]->tree().isDescendantOf(&m_frame))
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003283 continue;
ggaren@apple.com7a176e12015-11-12 01:48:27 +00003284 if (!targetFrames[i]->loader().dispatchBeforeUnloadEvent(page->chrome(), this))
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003285 break;
3286 }
3287
3288 if (i == targetFrames.size())
3289 shouldClose = true;
3290 }
3291
aestes@apple.comc7f17612011-08-12 19:56:56 +00003292 if (!shouldClose)
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003293 m_submittedFormURL = URL();
aestes@apple.comc7f17612011-08-12 19:56:56 +00003294
beidson@apple.com1390a812013-07-20 06:43:51 +00003295 m_currentNavigationHasShownBeforeUnloadConfirmPanel = false;
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003296 return shouldClose;
3297}
3298
ggaren@apple.com7a176e12015-11-12 01:48:27 +00003299void FrameLoader::dispatchUnloadEvents(UnloadEventPolicy unloadEventPolicy)
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003300{
3301 if (!m_frame.document())
3302 return;
3303
ajuma@chromium.orgedd75742019-09-11 14:52:18 +00003304 if (m_pageDismissalEventBeingDispatched != PageDismissalType::None)
3305 return;
3306
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003307 // We store the frame's page in a local variable because the frame might get detached inside dispatchEvent.
3308 ForbidPromptsScope forbidPrompts(m_frame.page());
cdumez@apple.com8b478c62016-01-23 01:04:59 +00003309 IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003310
3311 if (m_didCallImplicitClose && !m_wasUnloadEventEmitted) {
3312 auto* currentFocusedElement = m_frame.document()->focusedElement();
3313 if (is<HTMLInputElement>(currentFocusedElement))
3314 downcast<HTMLInputElement>(*currentFocusedElement).endEditing();
3315 if (m_pageDismissalEventBeingDispatched == PageDismissalType::None) {
3316 if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) {
3317 m_pageDismissalEventBeingDispatched = PageDismissalType::PageHide;
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003318 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 +00003319 }
3320
3321 // FIXME: update Page Visibility state here.
3322 // https://bugs.webkit.org/show_bug.cgi?id=116770
3323
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003324 if (m_frame.document()->backForwardCacheState() == Document::NotInBackForwardCache) {
rniwa@webkit.org6c403742018-08-17 21:24:40 +00003325 Ref<Event> unloadEvent(Event::create(eventNames().unloadEvent, Event::CanBubble::No, Event::IsCancelable::No));
commit-queue@webkit.org3eeac492016-08-12 22:53:27 +00003326 // The DocumentLoader (and thus its LoadTiming) might get destroyed
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003327 // while dispatching the event, so protect it to prevent writing the end
3328 // time into freed memory.
3329 RefPtr<DocumentLoader> documentLoader = m_provisionalDocumentLoader;
3330 m_pageDismissalEventBeingDispatched = PageDismissalType::Unload;
commit-queue@webkit.org3eeac492016-08-12 22:53:27 +00003331 if (documentLoader && documentLoader->timing().startTime() && !documentLoader->timing().unloadEventStart() && !documentLoader->timing().unloadEventEnd()) {
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003332 auto& timing = documentLoader->timing();
3333 timing.markUnloadEventStart();
3334 m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
3335 timing.markUnloadEventEnd();
3336 } else
3337 m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
3338 }
3339 }
3340 m_pageDismissalEventBeingDispatched = PageDismissalType::None;
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003341 m_wasUnloadEventEmitted = true;
3342 }
3343
3344 // Dispatching the unload event could have made m_frame.document() null.
3345 if (!m_frame.document())
3346 return;
3347
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003348 if (m_frame.document()->backForwardCacheState() != Document::NotInBackForwardCache)
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003349 return;
3350
3351 // Don't remove event listeners from a transitional empty document (see bug 28716 for more information).
3352 bool keepEventListeners = m_stateMachine.isDisplayingInitialEmptyDocument() && m_provisionalDocumentLoader
3353 && m_frame.document()->isSecureTransitionTo(m_provisionalDocumentLoader->url());
3354
3355 if (!keepEventListeners)
3356 m_frame.document()->removeAllEventListeners();
3357}
3358
cdumez@apple.com6473cc42017-03-22 21:14:23 +00003359static bool shouldAskForNavigationConfirmation(Document& document, const BeforeUnloadEvent& event)
cdumez@apple.com60045462017-02-20 06:36:04 +00003360{
fred.wang@free.frd6e82742017-08-25 17:28:53 +00003361 // Confirmation dialog should not be displayed when the allow-modals flag is not set.
3362 if (document.isSandboxed(SandboxModals))
3363 return false;
3364
cdumez@apple.com72d8e4b2017-04-17 00:56:47 +00003365 bool userDidInteractWithPage = document.topDocument().userDidInteractWithPage();
cdumez@apple.com60045462017-02-20 06:36:04 +00003366 // Web pages can request we ask for confirmation before navigating by:
3367 // - Cancelling the BeforeUnloadEvent (modern way)
3368 // - Setting the returnValue attribute on the BeforeUnloadEvent to a non-empty string.
3369 // - Returning a non-empty string from the event handler, which is then set as returnValue
3370 // attribute on the BeforeUnloadEvent.
cdumez@apple.com6473cc42017-03-22 21:14:23 +00003371 return userDidInteractWithPage && (event.defaultPrevented() || !event.returnValue().isEmpty());
cdumez@apple.com60045462017-02-20 06:36:04 +00003372}
3373
ggaren@apple.com7a176e12015-11-12 01:48:27 +00003374bool FrameLoader::dispatchBeforeUnloadEvent(Chrome& chrome, FrameLoader* frameLoaderBeingNavigated)
rniwa@webkit.orgcf460072011-01-08 02:15:10 +00003375{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003376 DOMWindow* domWindow = m_frame.document()->domWindow();
beidson@apple.com7617ce72010-05-13 20:31:46 +00003377 if (!domWindow)
3378 return true;
3379
akling@apple.com7f50aae2013-08-22 16:01:31 +00003380 RefPtr<Document> document = m_frame.document();
cdumez@apple.comf9780832015-01-27 00:26:21 +00003381 if (!document->bodyOrFrameset())
beidson@apple.com7617ce72010-05-13 20:31:46 +00003382 return true;
beidson@apple.com1390a812013-07-20 06:43:51 +00003383
cdumez@apple.com32216e42015-11-12 07:28:57 +00003384 Ref<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
beidson@apple.com1390a812013-07-20 06:43:51 +00003385
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003386 {
ajuma@chromium.orgedd75742019-09-11 14:52:18 +00003387 SetForScope<PageDismissalType> change(m_pageDismissalEventBeingDispatched, PageDismissalType::BeforeUnload);
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003388 ForbidPromptsScope forbidPrompts(m_frame.page());
cdumez@apple.com32216e42015-11-12 07:28:57 +00003389 domWindow->dispatchEvent(beforeUnloadEvent, domWindow->document());
ggaren@apple.comfe41e1b2015-11-10 22:19:44 +00003390 }
beidson@apple.com1390a812013-07-20 06:43:51 +00003391
beidson@apple.com7617ce72010-05-13 20:31:46 +00003392 if (!beforeUnloadEvent->defaultPrevented())
akling@apple.come8090dd2016-08-31 16:32:44 +00003393 document->defaultEventHandler(beforeUnloadEvent.get());
cdumez@apple.com60045462017-02-20 06:36:04 +00003394
cdumez@apple.com6473cc42017-03-22 21:14:23 +00003395 if (!shouldAskForNavigationConfirmation(*document, beforeUnloadEvent))
beidson@apple.com7617ce72010-05-13 20:31:46 +00003396 return true;
3397
beidson@apple.com1390a812013-07-20 06:43:51 +00003398 // If the navigating FrameLoader has already shown a beforeunload confirmation panel for the current navigation attempt,
3399 // this frame is not allowed to cause another one to be shown.
3400 if (frameLoaderBeingNavigated->m_currentNavigationHasShownBeforeUnloadConfirmPanel) {
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00003401 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 +00003402 return true;
3403 }
3404
3405 // We should only display the beforeunload dialog for an iframe if its SecurityOrigin matches all
3406 // ancestor frame SecurityOrigins up through the navigating FrameLoader.
3407 if (frameLoaderBeingNavigated != this) {
darin@apple.comfed4d162013-08-25 02:28:06 +00003408 Frame* parentFrame = m_frame.tree().parent();
beidson@apple.com1390a812013-07-20 06:43:51 +00003409 while (parentFrame) {
3410 Document* parentDocument = parentFrame->document();
3411 if (!parentDocument)
3412 return true;
akling@apple.com6be0e972017-01-18 19:35:49 +00003413 if (!m_frame.document() || !m_frame.document()->securityOrigin().canAccess(parentDocument->securityOrigin())) {
utatane.tea@gmail.com84077632018-06-23 08:39:34 +00003414 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 +00003415 return true;
3416 }
3417
andersca@apple.comdf550b92013-08-15 22:17:17 +00003418 if (&parentFrame->loader() == frameLoaderBeingNavigated)
beidson@apple.com1390a812013-07-20 06:43:51 +00003419 break;
3420
darin@apple.comfed4d162013-08-25 02:28:06 +00003421 parentFrame = parentFrame->tree().parent();
beidson@apple.com1390a812013-07-20 06:43:51 +00003422 }
3423
3424 // The navigatingFrameLoader should always be in our ancestory.
3425 ASSERT(parentFrame);
andersca@apple.comdf550b92013-08-15 22:17:17 +00003426 ASSERT(&parentFrame->loader() == frameLoaderBeingNavigated);
beidson@apple.com1390a812013-07-20 06:43:51 +00003427 }
3428
3429 frameLoaderBeingNavigated->m_currentNavigationHasShownBeforeUnloadConfirmPanel = true;
3430
ch.dumez@sisa.samsung.com231386f2013-09-09 18:40:04 +00003431 String text = document->displayStringModifiedByEncoding(beforeUnloadEvent->returnValue());
darin@apple.com9ace8012017-01-23 06:24:18 +00003432 return chrome.runBeforeUnloadConfirmPanel(text, m_frame);
beidson@apple.com7617ce72010-05-13 20:31:46 +00003433}
3434
cdumez@apple.com2e665842019-02-01 22:52:58 +00003435void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest& request, FormState* formState, NavigationPolicyDecision navigationPolicyDecision, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
anderscade5715d2007-01-06 00:55:49 +00003436{
3437 // If we loaded an alternate page to replace an unreachableURL, we'll get in here with a
3438 // nil policyDataSource because loading the alternate page will have passed
3439 // through this method already, nested; otherwise, policyDataSource should still be set.
3440 ASSERT(m_policyDocumentLoader || !m_provisionalDocumentLoader->unreachableURL().isEmpty());
3441
akling@apple.com672cb852013-08-22 20:27:27 +00003442 bool isTargetItem = history().provisionalItem() ? history().provisionalItem()->isTargetItem() : false;
anderscade5715d2007-01-06 00:55:49 +00003443
aestes@apple.com47ac5e12014-08-18 17:48:48 +00003444 bool urlIsDisallowed = allowNavigationToInvalidURL == AllowNavigationToInvalidURL::No && !request.url().isValid();
cdumez@apple.com2e665842019-02-01 22:52:58 +00003445 bool canContinue = navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad && shouldClose() && !urlIsDisallowed;
anderscade5715d2007-01-06 00:55:49 +00003446
3447 if (!canContinue) {
krollin@apple.come1810b62018-12-20 19:23:20 +00003448 RELEASE_LOG_IF_ALLOWED("continueLoadAfterNavigationPolicy: can't continue loading frame due to the following reasons ("
3449 "frame = %p, "
3450 "main = %d, "
3451 "allowNavigationToInvalidURL = %d, "
3452 "requestURLIsValid = %d, "
cdumez@apple.com2e665842019-02-01 22:52:58 +00003453 "navigationPolicyDecision = %d)",
krollin@apple.come1810b62018-12-20 19:23:20 +00003454 &m_frame,
3455 m_frame.isMainFrame(),
3456 static_cast<int>(allowNavigationToInvalidURL),
3457 request.url().isValid(),
cdumez@apple.com2e665842019-02-01 22:52:58 +00003458 static_cast<int>(navigationPolicyDecision));
krollin@apple.come1810b62018-12-20 19:23:20 +00003459
anderscade5715d2007-01-06 00:55:49 +00003460 // If we were waiting for a quick redirect, but the policy delegate decided to ignore it, then we
3461 // need to report that the client redirect was cancelled.
aestes@apple.com47ac5e12014-08-18 17:48:48 +00003462 // FIXME: The client should be told about ignored non-quick redirects, too.
anderscade5715d2007-01-06 00:55:49 +00003463 if (m_quickRedirectComing)
achristensen@apple.com6fddc912018-10-18 21:16:52 +00003464 clientRedirectCancelledOrFinished(NewLoadInProgress::No);
anderscade5715d2007-01-06 00:55:49 +00003465
cdumez@apple.com2e665842019-02-01 22:52:58 +00003466 if (navigationPolicyDecision == NavigationPolicyDecision::StopAllLoads) {
3467 stopAllLoaders();
3468 m_checkTimer.stop();
3469 }
3470
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00003471 setPolicyDocumentLoader(nullptr);
cdumez@apple.comd6531852018-03-06 03:13:32 +00003472 checkCompleted();
cdumez@apple.com2e665842019-02-01 22:52:58 +00003473
3474 if (navigationPolicyDecision != NavigationPolicyDecision::StopAllLoads)
3475 checkLoadComplete();
anderscade5715d2007-01-06 00:55:49 +00003476
3477 // 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 +00003478 // problem that we have optimistically moved the b/f cursor already, so move it back. For sanity,
anderscade5715d2007-01-06 00:55:49 +00003479 // we only do this when punting a navigation for the target frame or top-level frame.
darin@apple.com0e83ab12013-09-28 17:19:04 +00003480 if ((isTargetItem || m_frame.isMainFrame()) && isBackForwardLoadType(policyChecker().loadType())) {
akling@apple.com7f50aae2013-08-22 16:01:31 +00003481 if (Page* page = m_frame.page()) {
achristensen@apple.comebfea932018-10-15 21:45:55 +00003482 if (HistoryItem* resetItem = m_frame.mainFrame().loader().history().currentItem())
achristensen@apple.com3a889f12018-10-16 15:58:10 +00003483 page->backForward().setCurrentItem(*resetItem);
darine0cef432007-07-10 19:21:23 +00003484 }
andersca@apple.comb85d6742011-03-04 03:21:07 +00003485 }
anderscade5715d2007-01-06 00:55:49 +00003486 return;
3487 }
3488
akling@apple.com24f4d6c2013-09-08 08:17:10 +00003489 FrameLoadType type = policyChecker().loadType();
commit-queue@webkit.org987fd772011-01-21 18:26:42 +00003490 // A new navigation is in progress, so don't clear the history's provisional item.
commit-queue@webkit.orgfc5833b2011-02-23 06:58:46 +00003491 stopAllLoaders(ShouldNotClearProvisionalItem);
beidson@apple.comc90a4422008-10-09 20:43:24 +00003492
3493 // <rdar://problem/6250856> - In certain circumstances on pages with multiple frames, stopAllLoaders()
3494 // might detach the current FrameLoader, in which case we should bail on this newly defunct load.
krollin@apple.come1810b62018-12-20 19:23:20 +00003495 if (!m_frame.page()) {
3496 RELEASE_LOG_IF_ALLOWED("continueLoadAfterNavigationPolicy: can't continue loading frame because it became defunct (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
beidson@apple.comc90a4422008-10-09 20:43:24 +00003497 return;
krollin@apple.come1810b62018-12-20 19:23:20 +00003498 }
timothy@apple.com8f207342009-04-11 05:31:05 +00003499
anderscade5715d2007-01-06 00:55:49 +00003500 setProvisionalDocumentLoader(m_policyDocumentLoader.get());
3501 m_loadType = type;
3502 setState(FrameStateProvisional);
3503
hs85.jeong@samsung.com13179142015-10-21 02:12:32 +00003504 setPolicyDocumentLoader(nullptr);
anderscade5715d2007-01-06 00:55:49 +00003505
cdumez@apple.com25743772015-08-17 22:57:27 +00003506 if (isBackForwardLoadType(type)) {
cdumez@apple.com10d0f252016-04-23 21:33:49 +00003507 auto& diagnosticLoggingClient = m_frame.page()->diagnosticLoggingClient();
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003508 if (history().provisionalItem() && history().provisionalItem()->isInBackForwardCache()) {
3509 diagnosticLoggingClient.logDiagnosticMessageWithResult(DiagnosticLoggingKeys::backForwardCacheKey(), DiagnosticLoggingKeys::retrievalKey(), DiagnosticLoggingResultPass, ShouldSample::Yes);
cdumez@apple.com25743772015-08-17 22:57:27 +00003510 loadProvisionalItemFromCachedPage();
krollin@apple.come1810b62018-12-20 19:23:20 +00003511 RELEASE_LOG_IF_ALLOWED("continueLoadAfterNavigationPolicy: can't continue loading frame because it will be loaded from cache (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
cdumez@apple.com25743772015-08-17 22:57:27 +00003512 return;
3513 }
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003514 diagnosticLoggingClient.logDiagnosticMessageWithResult(DiagnosticLoggingKeys::backForwardCacheKey(), DiagnosticLoggingKeys::retrievalKey(), DiagnosticLoggingResultFail, ShouldSample::Yes);
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00003515 }
anderscade5715d2007-01-06 00:55:49 +00003516
cdumez@apple.coma0010ff2018-12-13 23:17:44 +00003517 CompletionHandler<void()> completionHandler = [this, protectedFrame = makeRef(m_frame)] () mutable {
krollin@apple.come1810b62018-12-20 19:23:20 +00003518 if (!m_provisionalDocumentLoader) {
3519 RELEASE_LOG_IF_ALLOWED("continueLoadAfterNavigationPolicy completionHandler: Frame load canceled #1 (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
achristensen@apple.comb2d9e112017-09-25 19:18:50 +00003520 return;
krollin@apple.come1810b62018-12-20 19:23:20 +00003521 }
achristensen@apple.comb2d9e112017-09-25 19:18:50 +00003522
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003523 prepareForLoadStart();
beidson@apple.com02622332018-04-13 18:04:22 +00003524
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003525 // The load might be cancelled inside of prepareForLoadStart(), nulling out the m_provisionalDocumentLoader,
3526 // so we need to null check it again.
3527 if (!m_provisionalDocumentLoader) {
3528 RELEASE_LOG_IF_ALLOWED("prepareForLoadStart completionHandler: Frame load canceled #2 (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
3529 return;
3530 }
3531
3532 DocumentLoader* activeDocLoader = activeDocumentLoader();
3533 if (activeDocLoader && activeDocLoader->isLoadingMainResource()) {
3534 RELEASE_LOG_IF_ALLOWED("prepareForLoadStart completionHandler: Main frame already being loaded (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
3535 return;
3536 }
3537
3538 m_loadingFromCachedPage = false;
beidson@apple.com02622332018-04-13 18:04:22 +00003539
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003540 m_provisionalDocumentLoader->startLoadingMainResource();
achristensen@apple.comb2d9e112017-09-25 19:18:50 +00003541 };
3542
andersca@apple.com61e33322013-10-05 04:52:04 +00003543 if (!formState) {
achristensen@apple.comb2d9e112017-09-25 19:18:50 +00003544 completionHandler();
andersca@apple.com61e33322013-10-05 04:52:04 +00003545 return;
3546 }
3547
achristensen@apple.comb2d9e112017-09-25 19:18:50 +00003548 m_client.dispatchWillSubmitForm(*formState, WTFMove(completionHandler));
anderscade5715d2007-01-06 00:55:49 +00003549}
3550
anderscade5715d2007-01-06 00:55:49 +00003551void FrameLoader::continueLoadAfterNewWindowPolicy(const ResourceRequest& request,
beidson@apple.come9d460a2018-04-10 00:31:02 +00003552 FormState* formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy openerPolicy)
anderscade5715d2007-01-06 00:55:49 +00003553{
beidson@apple.come9d460a2018-04-10 00:31:02 +00003554 if (shouldContinue != ShouldContinue::Yes)
anderscade5715d2007-01-06 00:55:49 +00003555 return;
3556
akling@apple.com55cde012013-10-05 00:35:12 +00003557 Ref<Frame> frame(m_frame);
akling@apple.com7f50aae2013-08-22 16:01:31 +00003558 RefPtr<Frame> mainFrame = m_client.dispatchCreatePage(action);
anderscade5715d2007-01-06 00:55:49 +00003559 if (!mainFrame)
3560 return;
3561
commit-queue@webkit.org04df8422017-06-09 17:59:18 +00003562 SandboxFlags sandboxFlags = frame->loader().effectiveSandboxFlags();
3563 if (sandboxFlags & SandboxPropagatesToAuxiliaryBrowsingContexts)
3564 mainFrame->loader().forceSandboxFlags(sandboxFlags);
wilander@apple.com2d7ea242016-08-08 21:43:36 +00003565
cdumez@apple.comeec032f2017-04-05 13:36:47 +00003566 if (!equalIgnoringASCIICase(frameName, "_blank"))
darin@apple.comfed4d162013-08-25 02:28:06 +00003567 mainFrame->tree().setName(frameName);
kmccullo1f901212007-05-16 20:57:47 +00003568
eric@webkit.org5aee6762009-10-06 18:20:33 +00003569 mainFrame->page()->setOpenedByDOM();
akling@apple.com7f50aae2013-08-22 16:01:31 +00003570 mainFrame->loader().m_client.dispatchShow();
ap@apple.coma383f252015-02-14 18:16:00 +00003571 if (openerPolicy == NewFrameOpenerPolicy::Allow) {
cdumez@apple.com78141732014-11-04 23:00:48 +00003572 mainFrame->loader().setOpener(frame.ptr());
jochen@chromium.org235ee972012-05-09 22:13:12 +00003573 mainFrame->document()->setReferrerPolicy(frame->document()->referrerPolicy());
3574 }
beidson@apple.com87dc6312015-06-02 18:43:13 +00003575
cdumez@apple.com548d7bb2018-10-09 18:25:29 +00003576 NavigationAction newAction { *frame->document(), request, InitiatedByMainFrame::Unknown, NavigationType::Other, action.shouldOpenExternalURLsPolicy(), nullptr, action.downloadAttribute() };
cdumez@apple.com91e03bd2018-09-17 17:15:07 +00003577 mainFrame->loader().loadWithNavigationAction(request, WTFMove(newAction), LockHistory::No, FrameLoadType::Standard, formState, allowNavigationToInvalidURL);
anderscade5715d2007-01-06 00:55:49 +00003578}
3579
anderscaec429f52007-01-13 01:44:24 +00003580void FrameLoader::requestFromDelegate(ResourceRequest& request, unsigned long& identifier, ResourceError& error)
anderscade5715d2007-01-06 00:55:49 +00003581{
3582 ASSERT(!request.isNull());
3583
darine0cef432007-07-10 19:21:23 +00003584 identifier = 0;
akling@apple.com7f50aae2013-08-22 16:01:31 +00003585 if (Page* page = m_frame.page()) {
akling@apple.comeb67e0a2013-08-19 08:24:08 +00003586 identifier = page->progress().createUniqueIdentifier();
akling@apple.com654fd9a2013-10-06 21:07:29 +00003587 notifier().assignIdentifierToInitialRequest(identifier, m_documentLoader.get(), request);
darine0cef432007-07-10 19:21:23 +00003588 }
anderscaec429f52007-01-13 01:44:24 +00003589
anderscade5715d2007-01-06 00:55:49 +00003590 ResourceRequest newRequest(request);
akling@apple.com654fd9a2013-10-06 21:07:29 +00003591 notifier().dispatchWillSendRequest(m_documentLoader.get(), identifier, newRequest, ResourceResponse());
anderscade5715d2007-01-06 00:55:49 +00003592
3593 if (newRequest.isNull())
weinig@apple.com87a569c2008-05-18 01:21:20 +00003594 error = cancelledError(request);
anderscade5715d2007-01-06 00:55:49 +00003595 else
3596 error = ResourceError();
3597
3598 request = newRequest;
3599}
3600
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003601void FrameLoader::loadedResourceFromMemoryCache(CachedResource& resource, ResourceRequest& newRequest, ResourceError& error)
anderscade5715d2007-01-06 00:55:49 +00003602{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003603 Page* page = m_frame.page();
darin@apple.com837a78c2009-01-07 15:40:24 +00003604 if (!page)
anderscade5715d2007-01-06 00:55:49 +00003605 return;
3606
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003607 if (!resource.shouldSendResourceLoadCallbacks() || m_documentLoader->haveToldClientAboutLoad(resource.url()))
darin@apple.com837a78c2009-01-07 15:40:24 +00003608 return;
3609
japhet@chromium.org3e317182013-01-29 20:06:19 +00003610 // Main resource delegate messages are synthesized in MainResourceLoader, so we must not send them here.
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00003611 if (resource.type() == CachedResource::Type::MainResource)
japhet@chromium.org3e317182013-01-29 20:06:19 +00003612 return;
3613
darin@apple.com837a78c2009-01-07 15:40:24 +00003614 if (!page->areMemoryCacheClientCallsEnabled()) {
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003615 InspectorInstrumentation::didLoadResourceFromMemoryCache(*page, m_documentLoader.get(), &resource);
3616 m_documentLoader->recordMemoryCacheLoadForFutureClientNotification(resource.resourceRequest());
3617 m_documentLoader->didTellClientAboutLoad(resource.url());
darin@apple.com837a78c2009-01-07 15:40:24 +00003618 return;
3619 }
3620
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003621 if (m_client.dispatchDidLoadResourceFromMemoryCache(m_documentLoader.get(), newRequest, resource.response(), resource.encodedSize())) {
3622 InspectorInstrumentation::didLoadResourceFromMemoryCache(*page, m_documentLoader.get(), &resource);
3623 m_documentLoader->didTellClientAboutLoad(resource.url());
timothy@apple.com8f85dce2008-01-08 23:51:28 +00003624 return;
3625 }
3626
anderscaec429f52007-01-13 01:44:24 +00003627 unsigned long identifier;
aestes@apple.com0c8e1912013-04-06 03:09:25 +00003628 requestFromDelegate(newRequest, identifier, error);
joepeck@webkit.orge7d264d2017-03-09 03:35:13 +00003629
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003630 ResourceResponse response = resource.response();
joepeck@webkit.orge7d264d2017-03-09 03:35:13 +00003631 response.setSource(ResourceResponse::Source::MemoryCache);
cdumez@apple.comd038ecf2017-08-15 21:15:09 +00003632 notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, newRequest, response, 0, resource.encodedSize(), 0, error);
anderscade5715d2007-01-06 00:55:49 +00003633}
3634
Ms2ger@igalia.comc33b77c2017-11-10 16:41:03 +00003635void FrameLoader::applyUserAgentIfNeeded(ResourceRequest& request)
anderscade5715d2007-01-06 00:55:49 +00003636{
Ms2ger@igalia.comc33b77c2017-11-10 16:41:03 +00003637 if (!request.hasHTTPHeaderField(HTTPHeaderName::UserAgent)) {
3638 String userAgent = this->userAgent(request.url());
3639 ASSERT(!userAgent.isNull());
3640 request.setHTTPUserAgent(userAgent);
3641 }
anderscade5715d2007-01-06 00:55:49 +00003642}
3643
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003644bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, const URL& url, unsigned long requestIdentifier)
weinig@apple.com5af461c2009-04-08 22:16:23 +00003645{
akling@apple.com52989472013-09-16 20:09:25 +00003646 Frame& topFrame = m_frame.tree().top();
3647 if (&m_frame == &topFrame)
weinig@apple.com5af461c2009-04-08 22:16:23 +00003648 return false;
3649
mkwst@chromium.org97421c02013-03-28 08:59:00 +00003650 XFrameOptionsDisposition disposition = parseXFrameOptionsHeader(content);
3651
3652 switch (disposition) {
3653 case XFrameOptionsSameOrigin: {
yusukesuzuki@slowstart.orgae5a8bd2018-12-22 06:37:39 +00003654 auto origin = SecurityOrigin::create(url);
akling@apple.com52989472013-09-16 20:09:25 +00003655 if (!origin->isSameSchemeHostPort(topFrame.document()->securityOrigin()))
weinig@apple.com5af461c2009-04-08 22:16:23 +00003656 return true;
darin@apple.comfed4d162013-08-25 02:28:06 +00003657 for (Frame* frame = m_frame.tree().parent(); frame; frame = frame->tree().parent()) {
akling@apple.comfbea4062014-02-27 20:24:03 +00003658 if (!origin->isSameSchemeHostPort(frame->document()->securityOrigin()))
dbates@webkit.org250656a2018-05-12 04:11:16 +00003659 return true;
mkwst@chromium.orgf9d8fa02013-03-19 21:12:24 +00003660 }
mkwst@chromium.org97421c02013-03-28 08:59:00 +00003661 return false;
weinig@apple.com5af461c2009-04-08 22:16:23 +00003662 }
mkwst@chromium.org97421c02013-03-28 08:59:00 +00003663 case XFrameOptionsDeny:
3664 return true;
3665 case XFrameOptionsAllowAll:
3666 return false;
3667 case XFrameOptionsConflict:
joepeck@webkit.org1f45df92014-02-06 23:45:53 +00003668 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 +00003669 return true;
3670 case XFrameOptionsInvalid:
joepeck@webkit.org1f45df92014-02-06 23:45:53 +00003671 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 +00003672 return false;
psolanki@apple.come2dc3b92014-02-20 18:23:24 +00003673 case XFrameOptionsNone:
mkwst@chromium.org97421c02013-03-28 08:59:00 +00003674 return false;
3675 }
psolanki@apple.come2dc3b92014-02-20 18:23:24 +00003676 ASSERT_NOT_REACHED();
3677 return false;
weinig@apple.com5af461c2009-04-08 22:16:23 +00003678}
3679
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00003680void FrameLoader::loadProvisionalItemFromCachedPage()
beidson50c3bd82007-01-03 03:11:18 +00003681{
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003682 DocumentLoader* provisionalLoader = provisionalDocumentLoader();
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003683 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 +00003684
achristensen@apple.comc41ad692019-01-31 21:23:44 +00003685 prepareForLoadStart();
3686
3687 m_loadingFromCachedPage = true;
3688
3689 // Should have timing data from previous time(s) the page was shown.
3690 ASSERT(provisionalLoader->timing().startTime());
3691 provisionalLoader->resetTiming();
3692 provisionalLoader->timing().markStartTime();
3693
3694 provisionalLoader->setCommitted(true);
3695 commitProvisionalLoad();
beidson50c3bd82007-01-03 03:11:18 +00003696}
3697
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003698bool FrameLoader::shouldTreatURLAsSameAsCurrent(const URL& url) const
beidson50c3bd82007-01-03 03:11:18 +00003699{
akling@apple.com672cb852013-08-22 20:27:27 +00003700 if (!history().currentItem())
beidson50c3bd82007-01-03 03:11:18 +00003701 return false;
akling@apple.com672cb852013-08-22 20:27:27 +00003702 return url == history().currentItem()->url() || url == history().currentItem()->originalURL();
beidson50c3bd82007-01-03 03:11:18 +00003703}
3704
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003705bool FrameLoader::shouldTreatURLAsSrcdocDocument(const URL& url) const
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00003706{
darin@apple.com048cc3a2016-01-22 17:17:04 +00003707 if (!equalLettersIgnoringASCIICase(url.string(), "about:srcdoc"))
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00003708 return false;
akling@apple.com7f50aae2013-08-22 16:01:31 +00003709 HTMLFrameOwnerElement* ownerElement = m_frame.ownerElement();
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00003710 if (!ownerElement)
3711 return false;
3712 if (!ownerElement->hasTagName(iframeTag))
3713 return false;
rniwa@webkit.orgbda54a02016-07-18 00:39:37 +00003714 return ownerElement->hasAttributeWithoutSynchronization(srcdocAttr);
abarth@webkit.orgb2515fa2012-04-04 05:54:26 +00003715}
3716
darin@apple.com0ce67df2019-06-17 01:48:13 +00003717Frame* FrameLoader::findFrameForNavigation(const AtomString& name, Document* activeDocument)
weinig@apple.com77427802008-01-11 00:23:13 +00003718{
ap@apple.comf8c414e2013-08-13 03:44:57 +00003719 // FIXME: Eventually all callers should supply the actual activeDocument so we can call canNavigate with the right document.
3720 if (!activeDocument)
akling@apple.com7f50aae2013-08-22 16:01:31 +00003721 activeDocument = m_frame.document();
ap@apple.comf8c414e2013-08-13 03:44:57 +00003722
cdumez@apple.com6cb3eff2018-10-15 15:34:39 +00003723 auto* frame = m_frame.tree().find(name, activeDocument->frame() ? *activeDocument->frame() : m_frame);
3724
ap@apple.comf8c414e2013-08-13 03:44:57 +00003725 if (!activeDocument->canNavigate(frame))
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003726 return nullptr;
abarth@webkit.orgb46fdef2012-04-13 00:42:37 +00003727
darin@apple.com0f88bda2009-04-02 00:30:50 +00003728 return frame;
weinig@apple.com77427802008-01-11 00:23:13 +00003729}
3730
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003731void FrameLoader::loadSameDocumentItem(HistoryItem& item)
beidson@apple.com08c61752009-12-03 19:04:40 +00003732{
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003733 ASSERT(item.documentSequenceNumber() == history().currentItem()->documentSequenceNumber());
beidson@apple.com08c61752009-12-03 19:04:40 +00003734
aestes@apple.com8303b342016-02-19 09:29:44 +00003735 Ref<Frame> protect(m_frame);
3736
beidson@apple.com08c61752009-12-03 19:04:40 +00003737 // Save user view state to the current history item here since we don't do a normal load.
3738 // FIXME: Does form state need to be saved here too?
akling@apple.com672cb852013-08-22 20:27:27 +00003739 history().saveScrollPositionAndViewStateToItem(history().currentItem());
akling@apple.com7f50aae2013-08-22 16:01:31 +00003740 if (FrameView* view = m_frame.view())
beidson@apple.com08c61752009-12-03 19:04:40 +00003741 view->setWasScrolledByUser(false);
3742
achristensen@apple.com3a889f12018-10-16 15:58:10 +00003743 history().setCurrentItem(item);
beidson@apple.com08c61752009-12-03 19:04:40 +00003744
3745 // loadInSameDocument() actually changes the URL and notifies load delegates of a "fake" load
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003746 loadInSameDocument(item.url(), item.stateObject(), false);
beidson@apple.com08c61752009-12-03 19:04:40 +00003747
3748 // 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 +00003749 history().restoreScrollPositionAndViewState();
beidson@apple.com08c61752009-12-03 19:04:40 +00003750}
3751
abarth@webkit.org1c893f42009-10-10 02:27:21 +00003752// FIXME: This function should really be split into a couple pieces, some of
3753// which should be methods of HistoryController and some of which should be
3754// methods of FrameLoader.
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +00003755void FrameLoader::loadDifferentDocumentItem(HistoryItem& item, HistoryItem* fromItem, FrameLoadType loadType, FormSubmissionCacheLoadPolicy cacheLoadPolicy, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad)
beidson50c3bd82007-01-03 03:11:18 +00003756{
krollin@apple.come1810b62018-12-20 19:23:20 +00003757 RELEASE_LOG_IF_ALLOWED("loadDifferentDocumentItem: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
3758
bfulgham@apple.comd0c0fc82019-05-17 16:03:36 +00003759 Ref<Frame> protectedFrame(m_frame);
3760
jiewen_tan@apple.com71ef00e2018-12-04 23:01:29 +00003761 // History items should not be reported to the parent.
3762 m_shouldReportResourceTimingToParentFrame = false;
3763
beidson@apple.com08c61752009-12-03 19:04:40 +00003764 // Remember this item so we can traverse any child items as child frames load
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003765 history().setProvisionalItem(&item);
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00003766
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00003767 auto initiatedByMainFrame = InitiatedByMainFrame::Unknown;
3768
cdumez@apple.com3aedc032019-01-31 02:23:55 +00003769 SetForScope<LoadContinuingState> continuingLoadGuard(m_currentLoadContinuingState, shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::Yes ? LoadContinuingState::ContinuingWithHistoryItem : LoadContinuingState::NotContinuing);
beidson@apple.com69caeee2018-04-20 04:55:32 +00003770
cdumez@apple.com9265dfe2019-10-17 01:44:16 +00003771 if (CachedPage* cachedPage = BackForwardCache::singleton().get(item, m_frame.page())) {
mitz@apple.com4a604422014-11-13 23:22:50 +00003772 auto documentLoader = cachedPage->documentLoader();
cdumez@apple.com6478e4d2015-06-14 04:53:14 +00003773 m_client.updateCachedDocumentLoader(*documentLoader);
beidson@apple.com07c00cf2018-05-11 16:12:11 +00003774
3775 auto action = NavigationAction { *m_frame.document(), documentLoader->request(), initiatedByMainFrame, loadType, false };
3776 action.setTargetBackForwardItem(item);
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +00003777 action.setSourceBackForwardItem(fromItem);
beidson@apple.com07c00cf2018-05-11 16:12:11 +00003778 documentLoader->setTriggeringAction(WTFMove(action));
3779
mitz@apple.com4a604422014-11-13 23:22:50 +00003780 documentLoader->setLastCheckedRequest(ResourceRequest());
achristensen@apple.com22b9ddf2018-08-17 23:24:37 +00003781 loadWithDocumentLoader(documentLoader, loadType, { }, AllowNavigationToInvalidURL::Yes, shouldTreatAsContinuingLoad);
japhet@chromium.orgd48109c2010-06-04 17:41:26 +00003782 return;
beidson@apple.com08c61752009-12-03 19:04:40 +00003783 }
adele@apple.comf3d6b892008-04-29 01:30:20 +00003784
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003785 URL itemURL = item.url();
3786 URL itemOriginalURL = item.originalURL();
darin@apple.com5ffbb5c2013-09-27 16:39:41 +00003787 URL currentURL;
beidson0c345992007-02-13 08:59:33 +00003788 if (documentLoader())
weinig@apple.comc5002662007-12-12 07:26:19 +00003789 currentURL = documentLoader()->url();
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003790 RefPtr<FormData> formData = item.formData();
beidson50c3bd82007-01-03 03:11:18 +00003791
beidson@apple.com08c61752009-12-03 19:04:40 +00003792 ResourceRequest request(itemURL);
3793
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003794 if (!item.referrer().isNull())
3795 request.setHTTPReferrer(item.referrer());
dbates@webkit.orgae34b602015-08-05 16:05:55 +00003796
dbates@webkit.org9692a072017-07-12 18:01:19 +00003797 ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(m_frame, initiatedByMainFrame, item.shouldOpenExternalURLsPolicy());
dbates@webkit.orgae34b602015-08-05 16:05:55 +00003798 bool isFormSubmission = false;
3799 Event* event = nullptr;
3800
beidson@apple.com08c61752009-12-03 19:04:40 +00003801 // If this was a repost that failed the page cache, we might try to repost the form.
3802 NavigationAction action;
3803 if (formData) {
beidson@apple.com08c61752009-12-03 19:04:40 +00003804 request.setHTTPMethod("POST");
youenn.fablet@crf.canon.fr11cc6552016-01-22 14:51:16 +00003805 request.setHTTPBody(WTFMove(formData));
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003806 request.setHTTPContentType(item.formContentType());
yusukesuzuki@slowstart.orgae5a8bd2018-12-22 06:37:39 +00003807 auto securityOrigin = SecurityOrigin::createFromString(item.referrer());
beidson@apple.com08c61752009-12-03 19:04:40 +00003808 addHTTPOriginIfNeeded(request, securityOrigin->toString());
bfulgham@apple.comb30d7f82016-06-07 15:47:30 +00003809 addHTTPUpgradeInsecureRequestsIfNeeded(request);
beidson@apple.com08c61752009-12-03 19:04:40 +00003810
3811 // Make sure to add extra fields to the request after the Origin header is added for the FormData case.
3812 // See https://bugs.webkit.org/show_bug.cgi?id=22194 for more discussion.
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003813 addExtraFieldsToRequest(request, loadType, true);
beidson@apple.com08c61752009-12-03 19:04:40 +00003814
3815 // FIXME: Slight hack to test if the NSURL cache contains the page we're going to.
3816 // We want to know this before talking to the policy delegate, since it affects whether
3817 // we show the DoYouReallyWantToRepost nag.
3818 //
3819 // This trick has a small bug (3123893) where we might find a cache hit, but then
3820 // have the item vanish when we try to use it in the ensuing nav. This should be
3821 // extremely rare, but in that case the user will get an error on the navigation.
3822
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003823 if (cacheLoadPolicy == MayAttemptCacheOnlyLoadForFormSubmissionItem) {
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00003824 request.setCachePolicy(ResourceRequestCachePolicy::ReturnCacheDataDontLoad);
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00003825 action = { *m_frame.document(), request, initiatedByMainFrame, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy };
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003826 } else {
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00003827 request.setCachePolicy(ResourceRequestCachePolicy::ReturnCacheDataElseLoad);
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00003828 action = { *m_frame.document(), request, initiatedByMainFrame, NavigationType::FormResubmitted, shouldOpenExternalURLsPolicy, event };
beidson@apple.com08c61752009-12-03 19:04:40 +00003829 }
3830 } else {
3831 switch (loadType) {
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003832 case FrameLoadType::Reload:
commit-queue@webkit.orgea87ad82018-01-11 00:45:49 +00003833 case FrameLoadType::ReloadFromOrigin:
commit-queue@webkit.org4833ac52018-02-26 17:38:14 +00003834 case FrameLoadType::ReloadExpiredOnly:
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00003835 request.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003836 break;
3837 case FrameLoadType::Back:
3838 case FrameLoadType::Forward:
carlosgc@webkit.org2af15b72016-02-27 07:44:07 +00003839 case FrameLoadType::IndexedBackForward: {
cdumez@apple.com3e885d42016-03-15 20:01:39 +00003840#if PLATFORM(COCOA)
carlosgc@webkit.org2af15b72016-02-27 07:44:07 +00003841 bool allowStaleData = true;
3842#else
3843 bool allowStaleData = !item.wasRestoredFromSession();
3844#endif
3845 if (allowStaleData)
simon.fraser@apple.com90e96252018-07-09 23:54:18 +00003846 request.setCachePolicy(ResourceRequestCachePolicy::ReturnCacheDataElseLoad);
carlosgc@webkit.org2af15b72016-02-27 07:44:07 +00003847 item.setWasRestoredFromSession(false);
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003848 break;
carlosgc@webkit.org2af15b72016-02-27 07:44:07 +00003849 }
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003850 case FrameLoadType::Standard:
3851 case FrameLoadType::RedirectWithLockedBackForwardList:
3852 break;
3853 case FrameLoadType::Same:
antti@apple.com5d0c5402017-03-17 19:52:49 +00003854 case FrameLoadType::Replace:
andersca@apple.comb50fcc32014-06-19 00:13:20 +00003855 ASSERT_NOT_REACHED();
beidson@apple.com08c61752009-12-03 19:04:40 +00003856 }
3857
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003858 addExtraFieldsToRequest(request, loadType, true);
beidson@apple.com08c61752009-12-03 19:04:40 +00003859
jochen@chromium.org056b7fa2011-10-18 04:47:05 +00003860 ResourceRequest requestForOriginalURL(request);
3861 requestForOriginalURL.setURL(itemOriginalURL);
dbates@webkit.org9692a072017-07-12 18:01:19 +00003862 action = { *m_frame.document(), requestForOriginalURL, initiatedByMainFrame, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy };
jochen@chromium.org056b7fa2011-10-18 04:47:05 +00003863 }
3864
beidson@apple.com07c00cf2018-05-11 16:12:11 +00003865 action.setTargetBackForwardItem(item);
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +00003866 action.setSourceBackForwardItem(fromItem);
beidson@apple.com07c00cf2018-05-11 16:12:11 +00003867
cdumez@apple.com91e03bd2018-09-17 17:15:07 +00003868 loadWithNavigationAction(request, WTFMove(action), LockHistory::No, loadType, { }, AllowNavigationToInvalidURL::Yes);
beidson@apple.com08c61752009-12-03 19:04:40 +00003869}
3870
3871// Loads content into this frame, as specified by history item
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +00003872void FrameLoader::loadItem(HistoryItem& item, HistoryItem* fromItem, FrameLoadType loadType, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad)
beidson@apple.com08c61752009-12-03 19:04:40 +00003873{
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003874 m_requestedHistoryItem = &item;
akling@apple.com672cb852013-08-22 20:27:27 +00003875 HistoryItem* currentItem = history().currentItem();
cdumez@apple.comfea5cb92015-02-02 00:49:36 +00003876 bool sameDocumentNavigation = currentItem && item.shouldDoSameDocumentNavigationTo(*currentItem);
darin@chromium.orge71dd0f2009-04-17 20:31:17 +00003877
beidson@apple.com08c61752009-12-03 19:04:40 +00003878 if (sameDocumentNavigation)
mihaip@chromium.orge5dbd372010-12-08 02:32:41 +00003879 loadSameDocumentItem(item);
beidson@apple.com08c61752009-12-03 19:04:40 +00003880 else
cdumez@apple.com29f7c1e2019-03-13 20:32:48 +00003881 loadDifferentDocumentItem(item, fromItem, loadType, MayAttemptCacheOnlyLoadForFormSubmissionItem, shouldTreatAsContinuingLoad);
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003882}
3883
3884void FrameLoader::retryAfterFailedCacheOnlyMainResourceLoad()
3885{
3886 ASSERT(m_state == FrameStateProvisional);
3887 ASSERT(!m_loadingFromCachedPage);
cdumez@apple.com67e10f72015-01-29 18:38:51 +00003888 ASSERT(history().provisionalItem());
akling@apple.com672cb852013-08-22 20:27:27 +00003889 ASSERT(history().provisionalItem()->formData());
3890 ASSERT(history().provisionalItem() == m_requestedHistoryItem.get());
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003891
3892 FrameLoadType loadType = m_loadType;
achristensen@apple.comd9245762019-07-09 18:55:43 +00003893 HistoryItem* item = history().provisionalItem();
ap@apple.com8d5f01b2013-01-07 18:40:55 +00003894
3895 stopAllLoaders(ShouldNotClearProvisionalItem);
achristensen@apple.comd9245762019-07-09 18:55:43 +00003896 if (item)
3897 loadDifferentDocumentItem(*item, history().currentItem(), loadType, MayNotAttemptCacheOnlyLoadForFormSubmissionItem, ShouldTreatAsContinuingLoad::No);
3898 else {
3899 ASSERT_NOT_REACHED();
3900 RELEASE_LOG_ERROR(ResourceLoading, "Retrying load after failed cache-only main resource load failed because there is no provisional history item.");
3901 }
beidson50c3bd82007-01-03 03:11:18 +00003902}
3903
anderscac8ee2462007-01-05 22:26:32 +00003904ResourceError FrameLoader::cancelledError(const ResourceRequest& request) const
3905{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003906 ResourceError error = m_client.cancelledError(request);
youenn.fablet@crf.canon.fr156f9bb2016-06-09 06:55:26 +00003907 error.setType(ResourceError::Type::Cancellation);
weinig@apple.com87a569c2008-05-18 01:21:20 +00003908 return error;
anderscac8ee2462007-01-05 22:26:32 +00003909}
3910
commit-queue@webkit.org8090ccb2015-10-06 08:18:08 +00003911ResourceError FrameLoader::blockedByContentBlockerError(const ResourceRequest& request) const
3912{
3913 return m_client.blockedByContentBlockerError(request);
3914}
3915
bfulgham@apple.comb4c70932016-01-06 22:07:51 +00003916ResourceError FrameLoader::blockedError(const ResourceRequest& request) const
3917{
3918 ResourceError error = m_client.blockedError(request);
youenn.fablet@crf.canon.fr156f9bb2016-06-09 06:55:26 +00003919 error.setType(ResourceError::Type::Cancellation);
bfulgham@apple.comb4c70932016-01-06 22:07:51 +00003920 return error;
3921}
3922
aestes@apple.com176a9aa2016-07-08 20:14:34 +00003923#if ENABLE(CONTENT_FILTERING)
3924ResourceError FrameLoader::blockedByContentFilterError(const ResourceRequest& request) const
3925{
3926 ResourceError error = m_client.blockedByContentFilterError(request);
3927 error.setType(ResourceError::Type::General);
3928 return error;
3929}
3930#endif
3931
ap@apple.com1e8475922018-10-18 21:38:50 +00003932#if PLATFORM(IOS_FAMILY)
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00003933RetainPtr<CFDictionaryRef> FrameLoader::connectionProperties(ResourceLoader* loader)
3934{
3935 return m_client.connectionProperties(loader->documentLoader(), loader->identifier());
3936}
3937#endif
3938
dbates@webkit.org0fefad72017-10-19 18:46:22 +00003939ReferrerPolicy FrameLoader::effectiveReferrerPolicy() const
3940{
3941 if (auto* parentFrame = m_frame.tree().parent())
3942 return parentFrame->document()->referrerPolicy();
3943 if (m_opener)
3944 return m_opener->document()->referrerPolicy();
3945 return ReferrerPolicy::NoReferrerWhenDowngrade;
3946}
3947
andersca4422e372007-01-12 19:56:19 +00003948String FrameLoader::referrer() const
3949{
cdumez@apple.com327d6c62016-07-16 04:51:45 +00003950 return m_documentLoader ? m_documentLoader->request().httpReferrer() : emptyString();
andersca4422e372007-01-12 19:56:19 +00003951}
3952
aroben@apple.com11dd5262009-11-13 23:49:05 +00003953void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
lars1e1dad32007-01-23 10:28:38 +00003954{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003955 if (!m_frame.script().canExecuteScripts(NotAboutToExecuteScript))
thatcher10840e52007-09-22 00:49:09 +00003956 return;
3957
weinig@apple.com8f716032013-10-02 17:03:09 +00003958 Vector<Ref<DOMWrapperWorld>> worlds;
aroben@apple.com11dd5262009-11-13 23:49:05 +00003959 ScriptController::getAllWorlds(worlds);
cdumez@apple.com2f661202014-11-04 07:22:18 +00003960 for (auto& world : worlds)
3961 dispatchDidClearWindowObjectInWorld(world);
aroben@apple.com11dd5262009-11-13 23:49:05 +00003962}
3963
weinig@apple.com8f716032013-10-02 17:03:09 +00003964void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
aroben@apple.com11dd5262009-11-13 23:49:05 +00003965{
cdumez@apple.com87a798a2018-04-19 04:02:30 +00003966 if (!m_frame.script().canExecuteScripts(NotAboutToExecuteScript) || !m_frame.windowProxy().existingJSWindowProxy(world))
aroben@apple.com11dd5262009-11-13 23:49:05 +00003967 return;
3968
akling@apple.com7f50aae2013-08-22 16:01:31 +00003969 m_client.dispatchDidClearWindowObjectInWorld(world);
timothy@apple.comefb8ac12008-07-24 02:48:36 +00003970
akling@apple.com7f50aae2013-08-22 16:01:31 +00003971 if (Page* page = m_frame.page())
burg@cs.washington.edudbacfc12015-01-05 21:30:33 +00003972 page->inspectorController().didClearWindowObjectInWorld(m_frame, world);
loislo@chromium.orge971cb52011-02-08 17:32:44 +00003973
burg@cs.washington.edudbacfc12015-01-05 21:30:33 +00003974 InspectorInstrumentation::didClearWindowObjectInWorld(m_frame, world);
lars1e1dad32007-01-23 10:28:38 +00003975}
3976
beidson@apple.com2a75a962012-04-24 18:12:55 +00003977void FrameLoader::dispatchGlobalObjectAvailableInAllWorlds()
3978{
weinig@apple.com8f716032013-10-02 17:03:09 +00003979 Vector<Ref<DOMWrapperWorld>> worlds;
beidson@apple.com2a75a962012-04-24 18:12:55 +00003980 ScriptController::getAllWorlds(worlds);
cdumez@apple.com2f661202014-11-04 07:22:18 +00003981 for (auto& world : worlds)
3982 m_client.dispatchGlobalObjectAvailable(world);
beidson@apple.com2a75a962012-04-24 18:12:55 +00003983}
3984
abarth@webkit.org8b45d862011-11-05 21:55:59 +00003985SandboxFlags FrameLoader::effectiveSandboxFlags() const
abarth@webkit.orgb8a10552009-12-02 02:40:35 +00003986{
abarth@webkit.orgf2c54c22010-04-11 06:57:13 +00003987 SandboxFlags flags = m_forcedSandboxFlags;
darin@apple.comfed4d162013-08-25 02:28:06 +00003988 if (Frame* parentFrame = m_frame.tree().parent())
abarth@webkit.org8b45d862011-11-05 21:55:59 +00003989 flags |= parentFrame->document()->sandboxFlags();
akling@apple.com7f50aae2013-08-22 16:01:31 +00003990 if (HTMLFrameOwnerElement* ownerElement = m_frame.ownerElement())
abarth@webkit.orgb8a10552009-12-02 02:40:35 +00003991 flags |= ownerElement->sandboxFlags();
abarth@webkit.org8b45d862011-11-05 21:55:59 +00003992 return flags;
abarth@webkit.orgf5267a42010-01-10 08:14:05 +00003993}
abarth@webkit.orgb8a10552009-12-02 02:40:35 +00003994
lars1e1dad32007-01-23 10:28:38 +00003995void FrameLoader::didChangeTitle(DocumentLoader* loader)
3996{
akling@apple.com7f50aae2013-08-22 16:01:31 +00003997 m_client.didChangeTitle(loader);
lars1e1dad32007-01-23 10:28:38 +00003998
darin@apple.com719d29c2009-07-24 00:09:17 +00003999 if (loader == m_documentLoader) {
lars1e1dad32007-01-23 10:28:38 +00004000 // Must update the entries in the back-forward list too.
akling@apple.com672cb852013-08-22 20:27:27 +00004001 history().setCurrentItemTitle(loader->title());
lars1e1dad32007-01-23 10:28:38 +00004002 // This must go through the WebFrame because it has the right notion of the current b/f item.
akling@apple.com7f50aae2013-08-22 16:01:31 +00004003 m_client.setTitle(loader->title(), loader->urlForHistory());
4004 m_client.setMainFrameDocumentReady(true); // update observers with new DOMDocument
4005 m_client.dispatchDidReceiveTitle(loader->title());
lars1e1dad32007-01-23 10:28:38 +00004006 }
joepeck@webkit.orgd2ecf372013-12-04 18:20:37 +00004007
4008#if ENABLE(REMOTE_INSPECTOR)
4009 if (m_frame.isMainFrame())
4010 m_frame.page()->remoteInspectorInformationDidChange();
4011#endif
lars1e1dad32007-01-23 10:28:38 +00004012}
andersca4422e372007-01-12 19:56:19 +00004013
cdumez@apple.com8b7a0222018-12-20 04:41:11 +00004014void FrameLoader::dispatchDidCommitLoad(Optional<HasInsecureContent> initialHasInsecureContent)
arobendfc56662007-06-21 01:37:24 +00004015{
japhet@chromium.org61d4b9c2010-06-21 20:06:02 +00004016 if (m_stateMachine.creatingInitialEmptyDocument())
darin@apple.com87134f22007-12-05 22:58:41 +00004017 return;
4018
beidson@apple.com4322db02016-09-16 00:27:11 +00004019 m_client.dispatchDidCommitLoad(initialHasInsecureContent);
arobendfc56662007-06-21 01:37:24 +00004020
darin@apple.com0e83ab12013-09-28 17:19:04 +00004021 if (m_frame.isMainFrame()) {
akling@apple.com7f50aae2013-08-22 16:01:31 +00004022 m_frame.page()->resetSeenPlugins();
4023 m_frame.page()->resetSeenMediaEngines();
jer.noble@apple.com2d0a60a2012-10-18 18:12:57 +00004024 }
jer.noble@apple.com381b4672012-07-28 00:41:18 +00004025
burg@cs.washington.edudbacfc12015-01-05 21:30:33 +00004026 InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get());
commit-queue@webkit.org42b47872013-02-19 19:19:02 +00004027
joepeck@webkit.orgd2ecf372013-12-04 18:20:37 +00004028#if ENABLE(REMOTE_INSPECTOR)
akling@apple.comfbea4062014-02-27 20:24:03 +00004029 if (m_frame.isMainFrame())
joepeck@webkit.orgd2ecf372013-12-04 18:20:37 +00004030 m_frame.page()->remoteInspectorInformationDidChange();
4031#endif
arobendfc56662007-06-21 01:37:24 +00004032}
4033
darin@apple.com837a78c2009-01-07 15:40:24 +00004034void FrameLoader::tellClientAboutPastMemoryCacheLoads()
4035{
akling@apple.com7f50aae2013-08-22 16:01:31 +00004036 ASSERT(m_frame.page());
4037 ASSERT(m_frame.page()->areMemoryCacheClientCallsEnabled());
darin@apple.com837a78c2009-01-07 15:40:24 +00004038
4039 if (!m_documentLoader)
4040 return;
4041
jpfau@apple.com97c6a7f2013-02-26 00:49:17 +00004042 Vector<ResourceRequest> pastLoads;
darin@apple.com837a78c2009-01-07 15:40:24 +00004043 m_documentLoader->takeMemoryCacheLoadsForClientNotification(pastLoads);
4044
commit-queue@webkit.orgacddfad2015-09-30 05:53:51 +00004045 for (auto& pastLoad : pastLoads) {
4046 CachedResource* resource = MemoryCache::singleton().resourceForRequest(pastLoad, m_frame.page()->sessionID());
darin@apple.com837a78c2009-01-07 15:40:24 +00004047
4048 // FIXME: These loads, loaded from cache, but now gone from the cache by the time
4049 // Page::setMemoryCacheClientCallsEnabled(true) is called, will not be seen by the client.
4050 // Consider if there's some efficient way of remembering enough to deliver this client call.
4051 // We have the URL, but not the rest of the response or the length.
4052 if (!resource)
4053 continue;
4054
4055 ResourceRequest request(resource->url());
akling@apple.com7f50aae2013-08-22 16:01:31 +00004056 m_client.dispatchDidLoadResourceFromMemoryCache(m_documentLoader.get(), request, resource->response(), resource->encodedSize());
darin@apple.com837a78c2009-01-07 15:40:24 +00004057 }
4058}
4059
diegohcg@webkit.org838e0a22010-09-04 14:48:30 +00004060NetworkingContext* FrameLoader::networkingContext() const
4061{
4062 return m_networkingContext.get();
4063}
4064
antti@apple.coma6775c12013-04-05 21:19:56 +00004065void FrameLoader::loadProgressingStatusChanged()
4066{
antti@apple.com08536d12014-06-27 21:58:06 +00004067 if (auto* view = m_frame.mainFrame().view())
4068 view->loadProgressingStatusChanged();
antti@apple.coma6775c12013-04-05 21:19:56 +00004069}
4070
timothy_horton@apple.com88756d62013-05-30 06:24:36 +00004071void FrameLoader::forcePageTransitionIfNeeded()
4072{
akling@apple.com7f50aae2013-08-22 16:01:31 +00004073 m_client.forcePageTransitionIfNeeded();
timothy_horton@apple.com88756d62013-05-30 06:24:36 +00004074}
4075
antti@apple.com1229ead2015-03-30 21:09:14 +00004076void FrameLoader::clearTestingOverrides()
4077{
cdumez@apple.com8b7a0222018-12-20 04:41:11 +00004078 m_overrideCachePolicyForTesting = WTF::nullopt;
4079 m_overrideResourceLoadPriorityForTesting = WTF::nullopt;
antti@apple.com2c4a2a22015-08-14 14:08:59 +00004080 m_isStrictRawResourceValidationPolicyDisabledForTesting = false;
antti@apple.com1229ead2015-03-30 21:09:14 +00004081}
4082
commit-queue@webkit.org6d635222016-03-08 06:44:59 +00004083bool FrameLoader::isAlwaysOnLoggingAllowed() const
4084{
4085 return frame().isAlwaysOnLoggingAllowed();
4086}
4087
darin@apple.com90a0f152009-02-01 00:55:03 +00004088bool FrameLoaderClient::hasHTMLView() const
4089{
4090 return true;
4091}
4092
dbates@webkit.org7f3a9822017-06-22 19:45:10 +00004093RefPtr<Frame> createWindow(Frame& openerFrame, Frame& lookupFrame, FrameLoadRequest&& request, const WindowFeatures& features, bool& created)
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004094{
4095 ASSERT(!features.dialog || request.frameName().isEmpty());
4096
darin@apple.com14800c12014-04-27 04:09:45 +00004097 created = false;
4098
dbates@webkit.orgde972cd2018-01-24 22:11:19 +00004099 // FIXME: Provide line number information with respect to the opener's document.
keith_miller@apple.combb2f61c2018-12-01 03:28:36 +00004100 if (WTF::protocolIsJavaScript(request.resourceRequest().url()) && !openerFrame.document()->contentSecurityPolicy()->allowJavaScriptURLs(openerFrame.document()->url(), { }))
dbates@webkit.orgde972cd2018-01-24 22:11:19 +00004101 return nullptr;
4102
cdumez@apple.comeec032f2017-04-05 13:36:47 +00004103 if (!request.frameName().isEmpty() && !equalIgnoringASCIICase(request.frameName(), "_blank")) {
cdumez@apple.com468ca182015-05-15 05:07:22 +00004104 if (RefPtr<Frame> frame = lookupFrame.loader().findFrameForNavigation(request.frameName(), openerFrame.document())) {
cdumez@apple.comeec032f2017-04-05 13:36:47 +00004105 if (!equalIgnoringASCIICase(request.frameName(), "_self")) {
jochen@chromium.orgb2c684a2013-05-11 19:09:01 +00004106 if (Page* page = frame->page())
akling@apple.combd774812013-05-17 00:03:01 +00004107 page->chrome().focus();
jochen@chromium.orgb2c684a2013-05-11 19:09:01 +00004108 }
aestes@apple.com2038dcb2015-12-28 16:26:24 +00004109 return frame;
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004110 }
4111 }
4112
4113 // Sandboxed frames cannot open new auxiliary browsing contexts.
mkwst@chromium.orgb10ebb432012-12-04 18:34:27 +00004114 if (isDocumentSandboxed(openerFrame, SandboxPopups)) {
4115 // 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 +00004116 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 +00004117 return nullptr;
mkwst@chromium.orgb10ebb432012-12-04 18:34:27 +00004118 }
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004119
4120 // FIXME: Setting the referrer should be the caller's responsibility.
cdumez@apple.comd6738dc2015-05-04 23:58:32 +00004121 String referrer = SecurityPolicy::generateReferrerHeader(openerFrame.document()->referrerPolicy(), request.resourceRequest().url(), openerFrame.loader().outgoingReferrer());
jochen@chromium.orgc881e402013-02-28 21:45:58 +00004122 if (!referrer.isEmpty())
dbates@webkit.org7f3a9822017-06-22 19:45:10 +00004123 request.resourceRequest().setHTTPReferrer(referrer);
4124 FrameLoader::addHTTPOriginIfNeeded(request.resourceRequest(), openerFrame.loader().outgoingOrigin());
4125 FrameLoader::addHTTPUpgradeInsecureRequestsIfNeeded(request.resourceRequest());
dbates@webkit.org8c917f22018-04-24 07:36:59 +00004126 FrameLoader::addSameSiteInfoToRequestIfNeeded(request.resourceRequest(), openerFrame.document());
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004127
cdumez@apple.comd6738dc2015-05-04 23:58:32 +00004128 Page* oldPage = openerFrame.page();
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004129 if (!oldPage)
darin@apple.com14800c12014-04-27 04:09:45 +00004130 return nullptr;
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004131
beidson@apple.com7034ec72017-07-06 00:01:53 +00004132 ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(openerFrame, request);
dbates@webkit.orgc49c95d2017-07-12 17:25:37 +00004133 NavigationAction action { request.requester(), request.resourceRequest(), request.initiatedByMainFrame(), NavigationType::Other, shouldOpenExternalURLsPolicy };
dbates@webkit.org7f3a9822017-06-22 19:45:10 +00004134 Page* page = oldPage->chrome().createWindow(openerFrame, request, features, action);
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004135 if (!page)
darin@apple.com14800c12014-04-27 04:09:45 +00004136 return nullptr;
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004137
darin@apple.com14800c12014-04-27 04:09:45 +00004138 RefPtr<Frame> frame = &page->mainFrame();
4139
commit-queue@webkit.org04df8422017-06-09 17:59:18 +00004140 if (isDocumentSandboxed(openerFrame, SandboxPropagatesToAuxiliaryBrowsingContexts))
4141 frame->loader().forceSandboxFlags(openerFrame.document()->sandboxFlags());
abarth@webkit.org7155e252011-11-04 18:14:58 +00004142
cdumez@apple.comeec032f2017-04-05 13:36:47 +00004143 if (!equalIgnoringASCIICase(request.frameName(), "_blank"))
darin@apple.com14800c12014-04-27 04:09:45 +00004144 frame->tree().setName(request.frameName());
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004145
akling@apple.combd774812013-05-17 00:03:01 +00004146 page->chrome().setToolbarsVisible(features.toolBarVisible || features.locationBarVisible);
darin@apple.com14800c12014-04-27 04:09:45 +00004147
4148 if (!frame->page())
4149 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004150 page->chrome().setStatusbarVisible(features.statusBarVisible);
darin@apple.com14800c12014-04-27 04:09:45 +00004151
4152 if (!frame->page())
4153 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004154 page->chrome().setScrollbarsVisible(features.scrollbarsVisible);
darin@apple.com14800c12014-04-27 04:09:45 +00004155
4156 if (!frame->page())
4157 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004158 page->chrome().setMenubarVisible(features.menuBarVisible);
darin@apple.com14800c12014-04-27 04:09:45 +00004159
4160 if (!frame->page())
4161 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004162 page->chrome().setResizable(features.resizable);
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004163
4164 // 'x' and 'y' specify the location of the window, while 'width' and 'height'
kenneth@webkit.orgdc092f72012-11-14 11:05:20 +00004165 // specify the size of the viewport. We can only resize the window, so adjust
4166 // for the difference between the window size and the viewport size.
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004167
darin@apple.com14800c12014-04-27 04:09:45 +00004168 // FIXME: We should reconcile the initialization of viewport arguments between iOS and non-IOS.
ap@apple.com1e8475922018-10-18 21:38:50 +00004169#if !PLATFORM(IOS_FAMILY)
akling@apple.combd774812013-05-17 00:03:01 +00004170 FloatSize viewportSize = page->chrome().pageRect().size();
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00004171 FloatRect windowRect = page->chrome().windowRect();
andersca@apple.comc1242ad2015-08-13 17:37:27 +00004172 if (features.x)
4173 windowRect.setX(*features.x);
4174 if (features.y)
4175 windowRect.setY(*features.y);
ap@apple.com8d15a822013-08-09 23:25:11 +00004176 // Zero width and height mean using default size, not minumum one.
andersca@apple.comc1242ad2015-08-13 17:37:27 +00004177 if (features.width && *features.width)
4178 windowRect.setWidth(*features.width + (windowRect.width() - viewportSize.width()));
4179 if (features.height && *features.height)
4180 windowRect.setHeight(*features.height + (windowRect.height() - viewportSize.height()));
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004181
kenneth@webkit.orgdc092f72012-11-14 11:05:20 +00004182 // Ensure non-NaN values, minimum size as well as being within valid screen area.
darin@apple.com9ace8012017-01-23 06:24:18 +00004183 FloatRect newWindowRect = DOMWindow::adjustWindowRect(*page, windowRect);
kenneth@webkit.orgdc092f72012-11-14 11:05:20 +00004184
darin@apple.com14800c12014-04-27 04:09:45 +00004185 if (!frame->page())
4186 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004187 page->chrome().setWindowRect(newWindowRect);
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00004188#else
4189 // On iOS, width and height refer to the viewport dimensions.
4190 ViewportArguments arguments;
4191 // Zero width and height mean using default size, not minimum one.
andersca@apple.comc1242ad2015-08-13 17:37:27 +00004192 if (features.width && *features.width)
4193 arguments.width = *features.width;
4194 if (features.height && *features.height)
4195 arguments.height = *features.height;
darin@apple.com14800c12014-04-27 04:09:45 +00004196 frame->setViewportArguments(arguments);
dbates@webkit.org46a1c6f2013-12-19 18:10:07 +00004197#endif
4198
darin@apple.com14800c12014-04-27 04:09:45 +00004199 if (!frame->page())
4200 return nullptr;
akling@apple.combd774812013-05-17 00:03:01 +00004201 page->chrome().show();
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004202
4203 created = true;
aestes@apple.com2038dcb2015-12-28 16:26:24 +00004204 return frame;
cjerdonek@webkit.orge1d45412010-08-11 17:40:23 +00004205}
4206
timothy_horton@apple.com57a22212017-10-19 20:43:41 +00004207bool FrameLoader::shouldSuppressTextInputFromEditing() const
aestes@apple.com54c9cf52016-12-16 23:10:56 +00004208{
timothy_horton@apple.com57a22212017-10-19 20:43:41 +00004209 return m_frame.settings().shouldSuppressTextInputFromEditingDuringProvisionalNavigation() && m_state == FrameStateProvisional;
aestes@apple.com54c9cf52016-12-16 23:10:56 +00004210}
4211
ggaren58e230c2006-11-12 04:53:17 +00004212} // namespace WebCore