Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: third_party/WebKit/Source/core/loader/FrameLoader.cpp

Issue 2809733003: Move most of FrameLoader::CheckCompleted() to Document (Closed)
Patch Set: Fix failing android test Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights
3 * reserved. 3 * reserved.
4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
5 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 5 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
6 * (http://www.torchmobile.com/) 6 * (http://www.torchmobile.com/)
7 * Copyright (C) 2008 Alp Toker <alp@atoker.com> 7 * Copyright (C) 2008 Alp Toker <alp@atoker.com>
8 * Copyright (C) Research In Motion Limited 2009. All rights reserved. 8 * Copyright (C) Research In Motion Limited 2009. All rights reserved.
9 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> 9 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com>
10 * Copyright (C) 2011 Google Inc. All rights reserved. 10 * Copyright (C) 2011 Google Inc. All rights reserved.
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 if (Client()) { 389 if (Client()) {
390 ScriptForbiddenScope forbid_scripts; 390 ScriptForbiddenScope forbid_scripts;
391 Client()->DispatchDidFinishDocumentLoad(); 391 Client()->DispatchDidFinishDocumentLoad();
392 } 392 }
393 393
394 if (Client()) { 394 if (Client()) {
395 Client()->RunScriptsAtDocumentReady( 395 Client()->RunScriptsAtDocumentReady(
396 document_loader_ ? document_loader_->IsCommittedButEmpty() : true); 396 document_loader_ ? document_loader_->IsCommittedButEmpty() : true);
397 } 397 }
398 398
399 CheckCompleted(); 399 frame_->GetDocument()->CheckCompleted();
400 400
401 if (!frame_->View()) 401 if (!frame_->View())
402 return; 402 return;
403 403
404 // Check if the scrollbars are really needed for the content. If not, remove 404 // Check if the scrollbars are really needed for the content. If not, remove
405 // them, relayout, and repaint. 405 // them, relayout, and repaint.
406 frame_->View()->RestoreScrollbar(); 406 frame_->View()->RestoreScrollbar();
407 ProcessFragment(frame_->GetDocument()->Url(), document_loader_->LoadType(), 407 ProcessFragment(frame_->GetDocument()->Url(), document_loader_->LoadType(),
408 kNavigationToDifferentDocument); 408 kNavigationToDifferentDocument);
409 } 409 }
410 410
411 static bool AllDescendantsAreComplete(Frame* frame) {
412 for (Frame* child = frame->Tree().FirstChild(); child;
413 child = child->Tree().TraverseNext(frame)) {
414 if (child->IsLoading())
415 return false;
416 }
417 return true;
418 }
419
420 bool FrameLoader::AllAncestorsAreComplete() const { 411 bool FrameLoader::AllAncestorsAreComplete() const {
421 for (Frame* ancestor = frame_; ancestor; 412 for (Frame* ancestor = frame_; ancestor;
422 ancestor = ancestor->Tree().Parent()) { 413 ancestor = ancestor->Tree().Parent()) {
423 if (ancestor->IsLoading()) 414 if (ancestor->IsLoading())
424 return false; 415 return false;
425 } 416 }
426 return true; 417 return true;
427 } 418 }
428 419
429 static bool ShouldComplete(Document* document) { 420 void FrameLoader::DidFinishNavigation() {
430 if (!document->GetFrame()) 421 // We should have either finished the provisional or committed navigation if
431 return false; 422 // this is called. Only delcare the whole frame finished if neither is in
432 if (document->Parsing() || document->IsInDOMContentLoaded()) 423 // progress.
433 return false; 424 DCHECK(document_loader_->SentDidFinishLoad() || !HasProvisionalNavigation());
434 if (!document->HaveImportsLoaded()) 425 if (!document_loader_->SentDidFinishLoad() || HasProvisionalNavigation())
435 return false;
436 if (document->Fetcher()->BlockingRequestCount())
437 return false;
438 if (document->IsDelayingLoadEvent())
439 return false;
440 return AllDescendantsAreComplete(document->GetFrame());
441 }
442
443 static bool ShouldSendFinishNotification(LocalFrame* frame) {
444 // Don't send didFinishLoad more than once per DocumentLoader.
445 if (frame->Loader().GetDocumentLoader()->SentDidFinishLoad())
446 return false;
447
448 // We might have declined to run the load event due to an imminent
449 // content-initiated navigation.
450 if (!frame->GetDocument()->LoadEventFinished())
451 return false;
452
453 // An event might have restarted a child frame.
454 if (!AllDescendantsAreComplete(frame))
455 return false;
456
457 // Don't notify if the frame is being detached.
458 if (!frame->IsAttached())
459 return false;
460
461 return true;
462 }
463
464 static bool ShouldSendCompleteNotification(LocalFrame* frame) {
465 // FIXME: We might have already sent stop notifications and be re-completing.
466 if (!frame->IsLoading())
467 return false;
468 // Only send didStopLoading() if there are no navigations in progress at all,
469 // whether committed, provisional, or pending.
470 return frame->Loader().GetDocumentLoader()->SentDidFinishLoad() &&
471 !frame->Loader().HasProvisionalNavigation();
472 }
473
474 void FrameLoader::CheckCompleted() {
475 if (!ShouldComplete(frame_->GetDocument()))
476 return; 426 return;
477 427
478 if (Client()) { 428 if (frame_->IsLoading()) {
479 Client()->RunScriptsAtDocumentIdle();
480
481 // Injected scripts may have disconnected this frame.
482 if (!Client())
483 return;
484
485 // Check again, because runScriptsAtDocumentIdle() may have delayed the load
486 // event.
487 if (!ShouldComplete(frame_->GetDocument()))
488 return;
489 }
490
491 // OK, completed.
492 frame_->GetDocument()->SetReadyState(Document::kComplete);
493 if (frame_->GetDocument()->LoadEventStillNeeded())
494 frame_->GetDocument()->ImplicitClose();
495
496 frame_->GetNavigationScheduler().StartTimer();
497
498 if (frame_->View())
499 frame_->View()->HandleLoadCompleted();
500
501 // The readystatechanged or load event may have disconnected this frame.
502 if (!frame_->Client())
503 return;
504
505 if (ShouldSendFinishNotification(frame_)) {
506 // Report mobile vs. desktop page statistics. This will only report on
507 // Android.
508 if (frame_->IsMainFrame())
509 frame_->GetDocument()->GetViewportDescription().ReportMobilePageStats(
510 frame_);
511 document_loader_->SetSentDidFinishLoad();
512 Client()->DispatchDidFinishLoad();
513 // Finishing the load can detach the frame when running layout tests.
514 if (!frame_->Client())
515 return;
516 }
517
518 if (ShouldSendCompleteNotification(frame_)) {
519 progress_tracker_->ProgressCompleted(); 429 progress_tracker_->ProgressCompleted();
520 // Retry restoring scroll offset since finishing loading disables content 430 // Retry restoring scroll offset since finishing loading disables content
521 // size clamping. 431 // size clamping.
522 RestoreScrollPositionAndViewState(); 432 RestoreScrollPositionAndViewState();
523 if (document_loader_) 433 if (document_loader_)
524 document_loader_->SetLoadType(kFrameLoadTypeStandard); 434 document_loader_->SetLoadType(kFrameLoadTypeStandard);
525 frame_->DomWindow()->FinishedLoading(); 435 frame_->DomWindow()->FinishedLoading();
526 } 436 }
527 437
528 Frame* parent = frame_->Tree().Parent(); 438 Frame* parent = frame_->Tree().Parent();
529 if (parent && parent->IsLocalFrame()) 439 if (parent && parent->IsLocalFrame())
530 ToLocalFrame(parent)->Loader().CheckCompleted(); 440 ToLocalFrame(parent)->GetDocument()->CheckCompleted();
531 } 441 }
532 442
533 void FrameLoader::CheckTimerFired(TimerBase*) { 443 void FrameLoader::CheckTimerFired(TimerBase*) {
534 if (Page* page = frame_->GetPage()) { 444 if (Page* page = frame_->GetPage()) {
535 if (page->Suspended()) 445 if (page->Suspended())
536 return; 446 return;
537 } 447 }
538 CheckCompleted(); 448 frame_->GetDocument()->CheckCompleted();
539 } 449 }
540 450
541 void FrameLoader::ScheduleCheckCompleted() { 451 void FrameLoader::ScheduleCheckCompleted() {
542 if (!check_timer_.IsActive()) 452 if (!check_timer_.IsActive())
543 check_timer_.StartOneShot(0, BLINK_FROM_HERE); 453 check_timer_.StartOneShot(0, BLINK_FROM_HERE);
544 } 454 }
545 455
546 Frame* FrameLoader::Opener() { 456 Frame* FrameLoader::Opener() {
547 return Client() ? Client()->Opener() : 0; 457 return Client() ? Client()->Opener() : 0;
548 } 458 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 document_loader_->SetIsClientRedirect(client_redirect == 546 document_loader_->SetIsClientRedirect(client_redirect ==
637 ClientRedirectPolicy::kClientRedirect); 547 ClientRedirectPolicy::kClientRedirect);
638 if (history_item) 548 if (history_item)
639 document_loader_->SetItemForHistoryNavigation(history_item); 549 document_loader_->SetItemForHistoryNavigation(history_item);
640 UpdateForSameDocumentNavigation(url, kSameDocumentNavigationDefault, nullptr, 550 UpdateForSameDocumentNavigation(url, kSameDocumentNavigationDefault, nullptr,
641 kScrollRestorationAuto, frame_load_type, 551 kScrollRestorationAuto, frame_load_type,
642 initiating_document); 552 initiating_document);
643 553
644 document_loader_->GetInitialScrollState().was_scrolled_by_user = false; 554 document_loader_->GetInitialScrollState().was_scrolled_by_user = false;
645 555
646 CheckCompleted(); 556 frame_->GetDocument()->CheckCompleted();
647 557
648 frame_->DomWindow()->StatePopped(state_object 558 frame_->DomWindow()->StatePopped(state_object
649 ? std::move(state_object) 559 ? std::move(state_object)
650 : SerializedScriptValue::NullValue()); 560 : SerializedScriptValue::NullValue());
651 561
652 if (history_item) 562 if (history_item)
653 RestoreScrollPositionAndViewStateForLoadType(frame_load_type); 563 RestoreScrollPositionAndViewStateForLoadType(frame_load_type);
654 564
655 // We need to scroll to the fragment whether or not a hash change occurred, 565 // We need to scroll to the fragment whether or not a hash change occurred,
656 // since the user might have scrolled since the previous navigation. 566 // since the user might have scrolled since the previous navigation.
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 return; 908 return;
999 909
1000 in_stop_all_loaders_ = true; 910 in_stop_all_loaders_ = true;
1001 911
1002 for (Frame* child = frame_->Tree().FirstChild(); child; 912 for (Frame* child = frame_->Tree().FirstChild(); child;
1003 child = child->Tree().NextSibling()) { 913 child = child->Tree().NextSibling()) {
1004 if (child->IsLocalFrame()) 914 if (child->IsLocalFrame())
1005 ToLocalFrame(child)->Loader().StopAllLoaders(); 915 ToLocalFrame(child)->Loader().StopAllLoaders();
1006 } 916 }
1007 917
1008 frame_->GetDocument()->SuppressLoadEvent(); 918 frame_->GetDocument()->CancelParsing();
1009 if (document_loader_) 919 if (document_loader_)
1010 document_loader_->Fetcher()->StopFetching(); 920 document_loader_->Fetcher()->StopFetching();
1011 frame_->GetDocument()->CancelParsing();
1012 if (!protect_provisional_loader_) 921 if (!protect_provisional_loader_)
1013 DetachDocumentLoader(provisional_document_loader_); 922 DetachDocumentLoader(provisional_document_loader_);
1014 923
1015 check_timer_.Stop(); 924 check_timer_.Stop();
1016 frame_->GetNavigationScheduler().Cancel(); 925 frame_->GetNavigationScheduler().Cancel();
1017 926
1018 // It's possible that the above actions won't have stopped loading if load 927 // It's possible that the above actions won't have stopped loading if load
1019 // completion had been blocked on parsing or if we were in the middle of 928 // completion had been blocked on parsing or if we were in the middle of
1020 // committing an empty document. In that case, emulate a failed navigation. 929 // committing an empty document. In that case, emulate a failed navigation.
1021 if (!provisional_document_loader_ && document_loader_ && 930 if (!provisional_document_loader_ && document_loader_ &&
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 progress_tracker_.Clear(); 1157 progress_tracker_.Clear();
1249 } 1158 }
1250 1159
1251 TRACE_EVENT_OBJECT_DELETED_WITH_ID("loading", "FrameLoader", this); 1160 TRACE_EVENT_OBJECT_DELETED_WITH_ID("loading", "FrameLoader", this);
1252 detached_ = true; 1161 detached_ = true;
1253 } 1162 }
1254 1163
1255 void FrameLoader::DetachProvisionalDocumentLoader(DocumentLoader* loader) { 1164 void FrameLoader::DetachProvisionalDocumentLoader(DocumentLoader* loader) {
1256 DCHECK_EQ(loader, provisional_document_loader_); 1165 DCHECK_EQ(loader, provisional_document_loader_);
1257 DetachDocumentLoader(provisional_document_loader_); 1166 DetachDocumentLoader(provisional_document_loader_);
1167 DidFinishNavigation();
1258 } 1168 }
1259 1169
1260 bool FrameLoader::ShouldPerformFragmentNavigation(bool is_form_submission, 1170 bool FrameLoader::ShouldPerformFragmentNavigation(bool is_form_submission,
1261 const String& http_method, 1171 const String& http_method,
1262 FrameLoadType load_type, 1172 FrameLoadType load_type,
1263 const KURL& url) { 1173 const KURL& url) {
1264 // We don't do this if we are submitting a form with method other than "GET", 1174 // We don't do this if we are submitting a form with method other than "GET",
1265 // explicitly reloading, currently displaying a frameset, or if the URL does 1175 // explicitly reloading, currently displaying a frameset, or if the URL does
1266 // not have a fragment. 1176 // not have a fragment.
1267 return DeprecatedEqualIgnoringCase(http_method, HTTPNames::GET) && 1177 return DeprecatedEqualIgnoringCase(http_method, HTTPNames::GET) &&
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
1774 // TODO(japhet): This is needed because the browser process DCHECKs if the 1684 // TODO(japhet): This is needed because the browser process DCHECKs if the
1775 // first entry we commit in a new frame has replacement set. It's unclear 1685 // first entry we commit in a new frame has replacement set. It's unclear
1776 // whether the DCHECK is right, investigate removing this special case. 1686 // whether the DCHECK is right, investigate removing this special case.
1777 bool replace_current_item = load_type == kFrameLoadTypeReplaceCurrentItem && 1687 bool replace_current_item = load_type == kFrameLoadTypeReplaceCurrentItem &&
1778 (!Opener() || !request.Url().IsEmpty()); 1688 (!Opener() || !request.Url().IsEmpty());
1779 loader->SetReplacesCurrentHistoryItem(replace_current_item); 1689 loader->SetReplacesCurrentHistoryItem(replace_current_item);
1780 return loader; 1690 return loader;
1781 } 1691 }
1782 1692
1783 } // namespace blink 1693 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/loader/FrameLoader.h ('k') | third_party/WebKit/Source/core/loader/NavigationScheduler.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698