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

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

Issue 2837763003: Reland "Move most of FrameLoader::CheckCompleted() to Document" (Closed)
Patch Set: Fix comment typos Created 3 years, 7 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 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 if (Client()) { 447 if (Client()) {
448 ScriptForbiddenScope forbid_scripts; 448 ScriptForbiddenScope forbid_scripts;
449 Client()->DispatchDidFinishDocumentLoad(); 449 Client()->DispatchDidFinishDocumentLoad();
450 } 450 }
451 451
452 if (Client()) { 452 if (Client()) {
453 Client()->RunScriptsAtDocumentReady( 453 Client()->RunScriptsAtDocumentReady(
454 document_loader_ ? document_loader_->IsCommittedButEmpty() : true); 454 document_loader_ ? document_loader_->IsCommittedButEmpty() : true);
455 } 455 }
456 456
457 CheckCompleted(); 457 frame_->GetDocument()->CheckCompleted();
458 458
459 if (!frame_->View()) 459 if (!frame_->View())
460 return; 460 return;
461 461
462 // Check if the scrollbars are really needed for the content. If not, remove 462 // Check if the scrollbars are really needed for the content. If not, remove
463 // them, relayout, and repaint. 463 // them, relayout, and repaint.
464 frame_->View()->RestoreScrollbar(); 464 frame_->View()->RestoreScrollbar();
465 ProcessFragment(frame_->GetDocument()->Url(), document_loader_->LoadType(), 465 ProcessFragment(frame_->GetDocument()->Url(), document_loader_->LoadType(),
466 kNavigationToDifferentDocument); 466 kNavigationToDifferentDocument);
467 } 467 }
468 468
469 static bool AllDescendantsAreComplete(Frame* frame) {
470 for (Frame* child = frame->Tree().FirstChild(); child;
471 child = child->Tree().TraverseNext(frame)) {
472 if (child->IsLoading())
473 return false;
474 }
475 return true;
476 }
477
478 bool FrameLoader::AllAncestorsAreComplete() const { 469 bool FrameLoader::AllAncestorsAreComplete() const {
479 for (Frame* ancestor = frame_; ancestor; 470 for (Frame* ancestor = frame_; ancestor;
480 ancestor = ancestor->Tree().Parent()) { 471 ancestor = ancestor->Tree().Parent()) {
481 if (ancestor->IsLoading()) 472 if (ancestor->IsLoading())
482 return false; 473 return false;
483 } 474 }
484 return true; 475 return true;
485 } 476 }
486 477
487 static bool ShouldComplete(Document* document) { 478 void FrameLoader::DidFinishNavigation() {
488 if (!document->GetFrame()) 479 // We should have either finished the provisional or committed navigation if
489 return false; 480 // this is called. Only delcare the whole frame finished if neither is in
490 if (document->Parsing() || document->IsInDOMContentLoaded()) 481 // progress.
491 return false; 482 DCHECK(document_loader_->SentDidFinishLoad() || !HasProvisionalNavigation());
492 if (!document->HaveImportsLoaded()) 483 if (!document_loader_->SentDidFinishLoad() || HasProvisionalNavigation())
493 return false;
494 if (document->Fetcher()->BlockingRequestCount())
495 return false;
496 if (document->IsDelayingLoadEvent())
497 return false;
498 return AllDescendantsAreComplete(document->GetFrame());
499 }
500
501 static bool ShouldSendFinishNotification(LocalFrame* frame) {
502 // Don't send didFinishLoad more than once per DocumentLoader.
503 if (frame->Loader().GetDocumentLoader()->SentDidFinishLoad())
504 return false;
505
506 // We might have declined to run the load event due to an imminent
507 // content-initiated navigation.
508 if (!frame->GetDocument()->LoadEventFinished())
509 return false;
510
511 // An event might have restarted a child frame.
512 if (!AllDescendantsAreComplete(frame))
513 return false;
514
515 // Don't notify if the frame is being detached.
516 if (!frame->IsAttached())
517 return false;
518
519 return true;
520 }
521
522 static bool ShouldSendCompleteNotification(LocalFrame* frame) {
523 // FIXME: We might have already sent stop notifications and be re-completing.
524 if (!frame->IsLoading())
525 return false;
526 // Only send didStopLoading() if there are no navigations in progress at all,
527 // whether committed, provisional, or pending.
528 return frame->Loader().GetDocumentLoader()->SentDidFinishLoad() &&
529 !frame->Loader().HasProvisionalNavigation();
530 }
531
532 void FrameLoader::CheckCompleted() {
533 if (!ShouldComplete(frame_->GetDocument()))
534 return; 484 return;
535 485
536 if (Client()) { 486 if (frame_->IsLoading()) {
537 Client()->RunScriptsAtDocumentIdle();
538
539 // Injected scripts may have disconnected this frame.
540 if (!Client())
541 return;
542
543 // Check again, because runScriptsAtDocumentIdle() may have delayed the load
544 // event.
545 if (!ShouldComplete(frame_->GetDocument()))
546 return;
547 }
548
549 // OK, completed.
550 frame_->GetDocument()->SetReadyState(Document::kComplete);
551 if (frame_->GetDocument()->LoadEventStillNeeded())
552 frame_->GetDocument()->ImplicitClose();
553
554 frame_->GetNavigationScheduler().StartTimer();
555
556 if (frame_->View())
557 frame_->View()->HandleLoadCompleted();
558
559 // The readystatechanged or load event may have disconnected this frame.
560 if (!frame_->Client())
561 return;
562
563 if (ShouldSendFinishNotification(frame_)) {
564 // Report mobile vs. desktop page statistics. This will only report on
565 // Android.
566 if (frame_->IsMainFrame())
567 frame_->GetDocument()->GetViewportDescription().ReportMobilePageStats(
568 frame_);
569 document_loader_->SetSentDidFinishLoad();
570 Client()->DispatchDidFinishLoad();
571 // Finishing the load can detach the frame when running layout tests.
572 if (!frame_->Client())
573 return;
574 }
575
576 if (ShouldSendCompleteNotification(frame_)) {
577 progress_tracker_->ProgressCompleted(); 487 progress_tracker_->ProgressCompleted();
578 // Retry restoring scroll offset since finishing loading disables content 488 // Retry restoring scroll offset since finishing loading disables content
579 // size clamping. 489 // size clamping.
580 RestoreScrollPositionAndViewState(); 490 RestoreScrollPositionAndViewState();
581 if (document_loader_) 491 if (document_loader_)
582 document_loader_->SetLoadType(kFrameLoadTypeStandard); 492 document_loader_->SetLoadType(kFrameLoadTypeStandard);
583 frame_->DomWindow()->FinishedLoading(); 493 frame_->DomWindow()->FinishedLoading();
584 } 494 }
585 495
586 Frame* parent = frame_->Tree().Parent(); 496 Frame* parent = frame_->Tree().Parent();
587 if (parent && parent->IsLocalFrame()) 497 if (parent && parent->IsLocalFrame())
588 ToLocalFrame(parent)->Loader().CheckCompleted(); 498 ToLocalFrame(parent)->GetDocument()->CheckCompleted();
589 } 499 }
590 500
591 void FrameLoader::CheckTimerFired(TimerBase*) { 501 void FrameLoader::CheckTimerFired(TimerBase*) {
592 if (Page* page = frame_->GetPage()) { 502 if (Page* page = frame_->GetPage()) {
593 if (page->Suspended()) 503 if (page->Suspended())
594 return; 504 return;
595 } 505 }
596 CheckCompleted(); 506 frame_->GetDocument()->CheckCompleted();
597 } 507 }
598 508
599 void FrameLoader::ScheduleCheckCompleted() { 509 void FrameLoader::ScheduleCheckCompleted() {
600 if (!check_timer_.IsActive()) 510 if (!check_timer_.IsActive())
601 check_timer_.StartOneShot(0, BLINK_FROM_HERE); 511 check_timer_.StartOneShot(0, BLINK_FROM_HERE);
602 } 512 }
603 513
604 Frame* FrameLoader::Opener() { 514 Frame* FrameLoader::Opener() {
605 return Client() ? Client()->Opener() : 0; 515 return Client() ? Client()->Opener() : 0;
606 } 516 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 document_loader_->SetIsClientRedirect(client_redirect == 604 document_loader_->SetIsClientRedirect(client_redirect ==
695 ClientRedirectPolicy::kClientRedirect); 605 ClientRedirectPolicy::kClientRedirect);
696 if (history_item) 606 if (history_item)
697 document_loader_->SetItemForHistoryNavigation(history_item); 607 document_loader_->SetItemForHistoryNavigation(history_item);
698 UpdateForSameDocumentNavigation(url, kSameDocumentNavigationDefault, nullptr, 608 UpdateForSameDocumentNavigation(url, kSameDocumentNavigationDefault, nullptr,
699 kScrollRestorationAuto, frame_load_type, 609 kScrollRestorationAuto, frame_load_type,
700 initiating_document); 610 initiating_document);
701 611
702 document_loader_->GetInitialScrollState().was_scrolled_by_user = false; 612 document_loader_->GetInitialScrollState().was_scrolled_by_user = false;
703 613
704 CheckCompleted(); 614 frame_->GetDocument()->CheckCompleted();
705 615
706 frame_->DomWindow()->StatePopped(state_object 616 frame_->DomWindow()->StatePopped(state_object
707 ? std::move(state_object) 617 ? std::move(state_object)
708 : SerializedScriptValue::NullValue()); 618 : SerializedScriptValue::NullValue());
709 619
710 if (history_item) 620 if (history_item)
711 RestoreScrollPositionAndViewStateForLoadType(frame_load_type); 621 RestoreScrollPositionAndViewStateForLoadType(frame_load_type);
712 622
713 // We need to scroll to the fragment whether or not a hash change occurred, 623 // We need to scroll to the fragment whether or not a hash change occurred,
714 // since the user might have scrolled since the previous navigation. 624 // since the user might have scrolled since the previous navigation.
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 return; 984 return;
1075 985
1076 in_stop_all_loaders_ = true; 986 in_stop_all_loaders_ = true;
1077 987
1078 for (Frame* child = frame_->Tree().FirstChild(); child; 988 for (Frame* child = frame_->Tree().FirstChild(); child;
1079 child = child->Tree().NextSibling()) { 989 child = child->Tree().NextSibling()) {
1080 if (child->IsLocalFrame()) 990 if (child->IsLocalFrame())
1081 ToLocalFrame(child)->Loader().StopAllLoaders(); 991 ToLocalFrame(child)->Loader().StopAllLoaders();
1082 } 992 }
1083 993
1084 frame_->GetDocument()->SuppressLoadEvent(); 994 frame_->GetDocument()->CancelParsing();
1085 if (document_loader_) 995 if (document_loader_)
1086 document_loader_->Fetcher()->StopFetching(); 996 document_loader_->Fetcher()->StopFetching();
1087 frame_->GetDocument()->CancelParsing();
1088 if (!protect_provisional_loader_) 997 if (!protect_provisional_loader_)
1089 DetachDocumentLoader(provisional_document_loader_); 998 DetachDocumentLoader(provisional_document_loader_);
1090 999
1091 check_timer_.Stop(); 1000 check_timer_.Stop();
1092 frame_->GetNavigationScheduler().Cancel(); 1001 frame_->GetNavigationScheduler().Cancel();
1093 1002
1094 // It's possible that the above actions won't have stopped loading if load 1003 // It's possible that the above actions won't have stopped loading if load
1095 // completion had been blocked on parsing or if we were in the middle of 1004 // completion had been blocked on parsing or if we were in the middle of
1096 // committing an empty document. In that case, emulate a failed navigation. 1005 // committing an empty document. In that case, emulate a failed navigation.
1097 if (!provisional_document_loader_ && document_loader_ && 1006 if (!provisional_document_loader_ && document_loader_ &&
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 progress_tracker_.Clear(); 1233 progress_tracker_.Clear();
1325 } 1234 }
1326 1235
1327 TRACE_EVENT_OBJECT_DELETED_WITH_ID("loading", "FrameLoader", this); 1236 TRACE_EVENT_OBJECT_DELETED_WITH_ID("loading", "FrameLoader", this);
1328 detached_ = true; 1237 detached_ = true;
1329 } 1238 }
1330 1239
1331 void FrameLoader::DetachProvisionalDocumentLoader(DocumentLoader* loader) { 1240 void FrameLoader::DetachProvisionalDocumentLoader(DocumentLoader* loader) {
1332 DCHECK_EQ(loader, provisional_document_loader_); 1241 DCHECK_EQ(loader, provisional_document_loader_);
1333 DetachDocumentLoader(provisional_document_loader_); 1242 DetachDocumentLoader(provisional_document_loader_);
1243 DidFinishNavigation();
1334 } 1244 }
1335 1245
1336 bool FrameLoader::ShouldPerformFragmentNavigation(bool is_form_submission, 1246 bool FrameLoader::ShouldPerformFragmentNavigation(bool is_form_submission,
1337 const String& http_method, 1247 const String& http_method,
1338 FrameLoadType load_type, 1248 FrameLoadType load_type,
1339 const KURL& url) { 1249 const KURL& url) {
1340 // We don't do this if we are submitting a form with method other than "GET", 1250 // We don't do this if we are submitting a form with method other than "GET",
1341 // explicitly reloading, currently displaying a frameset, or if the URL does 1251 // explicitly reloading, currently displaying a frameset, or if the URL does
1342 // not have a fragment. 1252 // not have a fragment.
1343 return DeprecatedEqualIgnoringCase(http_method, HTTPNames::GET) && 1253 return DeprecatedEqualIgnoringCase(http_method, HTTPNames::GET) &&
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 // TODO(japhet): This is needed because the browser process DCHECKs if the 1760 // TODO(japhet): This is needed because the browser process DCHECKs if the
1851 // first entry we commit in a new frame has replacement set. It's unclear 1761 // first entry we commit in a new frame has replacement set. It's unclear
1852 // whether the DCHECK is right, investigate removing this special case. 1762 // whether the DCHECK is right, investigate removing this special case.
1853 bool replace_current_item = load_type == kFrameLoadTypeReplaceCurrentItem && 1763 bool replace_current_item = load_type == kFrameLoadTypeReplaceCurrentItem &&
1854 (!Opener() || !request.Url().IsEmpty()); 1764 (!Opener() || !request.Url().IsEmpty());
1855 loader->SetReplacesCurrentHistoryItem(replace_current_item); 1765 loader->SetReplacesCurrentHistoryItem(replace_current_item);
1856 return loader; 1766 return loader;
1857 } 1767 }
1858 1768
1859 } // namespace blink 1769 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698