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

Unified Diff: third_party/WebKit/Source/core/dom/Document.cpp

Issue 2809733003: Move most of FrameLoader::CheckCompleted() to Document (Closed)
Patch Set: processingLoadEvent() as part of shouldComplete(), cleanup shouldComplete() 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/dom/Document.cpp
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 900666f02f56d32fe7f1f1e991e73235bb9842d9..b153d54178e3b233836606f57327b756970f7b9c 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -2787,12 +2787,11 @@ void Document::CancelParsing() {
DetachParser();
SetParsingState(kFinishedParsing);
SetReadyState(kComplete);
+ SuppressLoadEvent();
Nate Chapin 2017/04/11 23:25:49 Instead of the early-exit for a nullptr parser_ in
}
DocumentParser* Document::ImplicitOpen(
ParserSynchronizationPolicy parser_sync_policy) {
- DetachParser();
-
RemoveChildren();
Nate Chapin 2017/04/11 23:25:50 This can trigger events, which can in turn call do
DCHECK(!focused_element_);
@@ -2806,6 +2805,7 @@ DocumentParser* Document::ImplicitOpen(
parser_sync_policy = kForceSynchronousParsing;
}
+ DetachParser();
parser_sync_policy_ = parser_sync_policy;
parser_ = CreateParser();
DocumentParserTiming::From(*this).MarkParserStart();
@@ -2952,30 +2952,15 @@ void Document::close() {
!GetScriptableDocumentParser()->IsParsing())
return;
- if (DocumentParser* parser = parser_)
- parser->Finish();
-
- if (!frame_) {
- // Because we have no frame, we don't know if all loading has completed,
- // so we just call implicitClose() immediately. FIXME: This might fire
- // the load event prematurely
- // <http://bugs.webkit.org/show_bug.cgi?id=14568>.
- ImplicitClose();
- return;
- }
-
- frame_->Loader().CheckCompleted();
+ parser_->Finish();
+ if (!parser_ || !parser_->IsParsing())
+ SetReadyState(kComplete);
Nate Chapin 2017/04/11 23:25:50 There are cases where we want to SetReadyState(kCo
+ CheckCompleted();
}
void Document::ImplicitClose() {
DCHECK(!InStyleRecalc());
- if (ProcessingLoadEvent() || !parser_)
- return;
- if (GetFrame() &&
- GetFrame()->GetNavigationScheduler().LocationChangePending()) {
- SuppressLoadEvent();
- return;
- }
+ DCHECK(parser_);
load_event_progress_ = kLoadEventInProgress;
@@ -3055,6 +3040,70 @@ void Document::ImplicitClose() {
if (SvgExtensions())
AccessSVGExtensions().StartAnimations();
+
+ View()->HandleLoadCompleted();
Nate Chapin 2017/04/11 23:25:50 From FrameLoader::CheckCompleted(). It just needs
yhirano 2017/04/14 10:33:35 Hmm, there are cases where this line is not execut
Nate Chapin 2017/04/18 21:56:38 I'm not absolutely sure it's OK (though all the te
+}
+
+static bool AllDescendantsAreComplete(Frame* frame) {
+ if (!frame)
Nate Chapin 2017/04/11 23:25:50 Vacuously true! You can't have any descendants if
+ return true;
+ for (Frame* child = frame->Tree().FirstChild(); child;
+ child = child->Tree().TraverseNext(frame)) {
+ if (child->IsLoading())
+ return false;
+ }
+ return true;
+}
+
+bool Document::ShouldComplete() {
+ return parsing_state_ == kFinishedParsing && HaveImportsLoaded() &&
+ !fetcher_->BlockingRequestCount() && !IsDelayingLoadEvent() &&
+ load_event_progress_ != kLoadEventInProgress &&
+ AllDescendantsAreComplete(frame_);
+}
+
+void Document::CheckCompleted() {
+ if (!ShouldComplete())
+ return;
+
+ if (frame_) {
+ frame_->Client()->RunScriptsAtDocumentIdle();
+
+ // Injected scripts may have disconnected this frame.
+ if (!frame_)
+ return;
+
+ // Check again, because runScriptsAtDocumentIdle() may have delayed the load
+ // event.
+ if (!ShouldComplete())
+ return;
+ }
+
+ // OK, completed. Fire load completion events as needed.
+ SetReadyState(kComplete);
+ if (LoadEventStillNeeded())
+ ImplicitClose();
+
+ // The readystatechanged or load event may have disconnected this frame.
+ if (!frame_ || !frame_->IsAttached())
+ return;
+ frame_->GetNavigationScheduler().StartTimer();
+ // The document itself is complete, but if a child frame was restarted due to
+ // an event, this document is still considered to be in progress.
+ if (!AllDescendantsAreComplete(frame_))
+ return;
+
+ // No need to repeat if we've already notified this load as finished.
+ if (!Loader()->SentDidFinishLoad()) {
+ if (frame_->IsMainFrame())
+ ViewportDescription().ReportMobilePageStats(frame_);
+ Loader()->SetSentDidFinishLoad();
+ frame_->Client()->DispatchDidFinishLoad();
+ if (!frame_)
+ return;
+ }
+
+ frame_->Loader().DidFinishNavigation();
}
bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client,
@@ -5972,7 +6021,7 @@ void Document::DecrementLoadEventDelayCountAndCheckLoadEvent() {
--load_event_delay_count_;
if (!load_event_delay_count_ && GetFrame())
yhirano 2017/04/14 10:33:35 Is checking GetFrame() needed here?
Nate Chapin 2017/04/18 21:56:38 This is needed to ensure the DCHECK(parser_) isn't
- GetFrame()->Loader().CheckCompleted();
+ CheckCompleted();
}
void Document::CheckLoadEventSoon() {
@@ -5994,8 +6043,7 @@ bool Document::IsDelayingLoadEvent() {
}
void Document::LoadEventDelayTimerFired(TimerBase*) {
- if (GetFrame())
- GetFrame()->Loader().CheckCompleted();
+ CheckCompleted();
}
void Document::LoadPluginsSoon() {

Powered by Google App Engine
This is Rietveld 408576698