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

Side by Side 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All
7 * rights reserved. 7 * rights reserved.
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
9 * (http://www.torchmobile.com/) 9 * (http://www.torchmobile.com/)
10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. 10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
(...skipping 2769 matching lines...) Expand 10 before | Expand all | Expand 10 after
2780 return; 2780 return;
2781 parser_->Detach(); 2781 parser_->Detach();
2782 parser_.Clear(); 2782 parser_.Clear();
2783 DocumentParserTiming::From(*this).MarkParserDetached(); 2783 DocumentParserTiming::From(*this).MarkParserDetached();
2784 } 2784 }
2785 2785
2786 void Document::CancelParsing() { 2786 void Document::CancelParsing() {
2787 DetachParser(); 2787 DetachParser();
2788 SetParsingState(kFinishedParsing); 2788 SetParsingState(kFinishedParsing);
2789 SetReadyState(kComplete); 2789 SetReadyState(kComplete);
2790 SuppressLoadEvent();
Nate Chapin 2017/04/11 23:25:49 Instead of the early-exit for a nullptr parser_ in
2790 } 2791 }
2791 2792
2792 DocumentParser* Document::ImplicitOpen( 2793 DocumentParser* Document::ImplicitOpen(
2793 ParserSynchronizationPolicy parser_sync_policy) { 2794 ParserSynchronizationPolicy parser_sync_policy) {
2794 DetachParser();
2795
2796 RemoveChildren(); 2795 RemoveChildren();
Nate Chapin 2017/04/11 23:25:50 This can trigger events, which can in turn call do
2797 DCHECK(!focused_element_); 2796 DCHECK(!focused_element_);
2798 2797
2799 SetCompatibilityMode(kNoQuirksMode); 2798 SetCompatibilityMode(kNoQuirksMode);
2800 2799
2801 if (!ThreadedParsingEnabledForTesting()) { 2800 if (!ThreadedParsingEnabledForTesting()) {
2802 parser_sync_policy = kForceSynchronousParsing; 2801 parser_sync_policy = kForceSynchronousParsing;
2803 } else if (parser_sync_policy == kAllowAsynchronousParsing && 2802 } else if (parser_sync_policy == kAllowAsynchronousParsing &&
2804 IsPrefetchOnly()) { 2803 IsPrefetchOnly()) {
2805 // Prefetch must be synchronous. 2804 // Prefetch must be synchronous.
2806 parser_sync_policy = kForceSynchronousParsing; 2805 parser_sync_policy = kForceSynchronousParsing;
2807 } 2806 }
2808 2807
2808 DetachParser();
2809 parser_sync_policy_ = parser_sync_policy; 2809 parser_sync_policy_ = parser_sync_policy;
2810 parser_ = CreateParser(); 2810 parser_ = CreateParser();
2811 DocumentParserTiming::From(*this).MarkParserStart(); 2811 DocumentParserTiming::From(*this).MarkParserStart();
2812 SetParsingState(kParsing); 2812 SetParsingState(kParsing);
2813 SetReadyState(kLoading); 2813 SetReadyState(kLoading);
2814 2814
2815 return parser_; 2815 return parser_;
2816 } 2816 }
2817 2817
2818 HTMLElement* Document::body() const { 2818 HTMLElement* Document::body() const {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2945 2945
2946 close(); 2946 close();
2947 } 2947 }
2948 2948
2949 void Document::close() { 2949 void Document::close() {
2950 if (!GetScriptableDocumentParser() || 2950 if (!GetScriptableDocumentParser() ||
2951 !GetScriptableDocumentParser()->WasCreatedByScript() || 2951 !GetScriptableDocumentParser()->WasCreatedByScript() ||
2952 !GetScriptableDocumentParser()->IsParsing()) 2952 !GetScriptableDocumentParser()->IsParsing())
2953 return; 2953 return;
2954 2954
2955 if (DocumentParser* parser = parser_) 2955 parser_->Finish();
2956 parser->Finish(); 2956 if (!parser_ || !parser_->IsParsing())
2957 2957 SetReadyState(kComplete);
Nate Chapin 2017/04/11 23:25:50 There are cases where we want to SetReadyState(kCo
2958 if (!frame_) { 2958 CheckCompleted();
2959 // Because we have no frame, we don't know if all loading has completed,
2960 // so we just call implicitClose() immediately. FIXME: This might fire
2961 // the load event prematurely
2962 // <http://bugs.webkit.org/show_bug.cgi?id=14568>.
2963 ImplicitClose();
2964 return;
2965 }
2966
2967 frame_->Loader().CheckCompleted();
2968 } 2959 }
2969 2960
2970 void Document::ImplicitClose() { 2961 void Document::ImplicitClose() {
2971 DCHECK(!InStyleRecalc()); 2962 DCHECK(!InStyleRecalc());
2972 if (ProcessingLoadEvent() || !parser_) 2963 DCHECK(parser_);
2973 return;
2974 if (GetFrame() &&
2975 GetFrame()->GetNavigationScheduler().LocationChangePending()) {
2976 SuppressLoadEvent();
2977 return;
2978 }
2979 2964
2980 load_event_progress_ = kLoadEventInProgress; 2965 load_event_progress_ = kLoadEventInProgress;
2981 2966
2982 ScriptableDocumentParser* parser = GetScriptableDocumentParser(); 2967 ScriptableDocumentParser* parser = GetScriptableDocumentParser();
2983 well_formed_ = parser && parser->WellFormed(); 2968 well_formed_ = parser && parser->WellFormed();
2984 2969
2985 // We have to clear the parser, in case someone document.write()s from the 2970 // We have to clear the parser, in case someone document.write()s from the
2986 // onLoad event handler, as in Radar 3206524. 2971 // onLoad event handler, as in Radar 3206524.
2987 DetachParser(); 2972 DetachParser();
2988 2973
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3048 if (AXObjectCache* cache = AxObjectCache()) { 3033 if (AXObjectCache* cache = AxObjectCache()) {
3049 if (this == &AxObjectCacheOwner()) 3034 if (this == &AxObjectCacheOwner())
3050 cache->HandleLoadComplete(this); 3035 cache->HandleLoadComplete(this);
3051 else 3036 else
3052 cache->HandleLayoutComplete(this); 3037 cache->HandleLayoutComplete(this);
3053 } 3038 }
3054 } 3039 }
3055 3040
3056 if (SvgExtensions()) 3041 if (SvgExtensions())
3057 AccessSVGExtensions().StartAnimations(); 3042 AccessSVGExtensions().StartAnimations();
3043
3044 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
3045 }
3046
3047 static bool AllDescendantsAreComplete(Frame* frame) {
3048 if (!frame)
Nate Chapin 2017/04/11 23:25:50 Vacuously true! You can't have any descendants if
3049 return true;
3050 for (Frame* child = frame->Tree().FirstChild(); child;
3051 child = child->Tree().TraverseNext(frame)) {
3052 if (child->IsLoading())
3053 return false;
3054 }
3055 return true;
3056 }
3057
3058 bool Document::ShouldComplete() {
3059 return parsing_state_ == kFinishedParsing && HaveImportsLoaded() &&
3060 !fetcher_->BlockingRequestCount() && !IsDelayingLoadEvent() &&
3061 load_event_progress_ != kLoadEventInProgress &&
3062 AllDescendantsAreComplete(frame_);
3063 }
3064
3065 void Document::CheckCompleted() {
3066 if (!ShouldComplete())
3067 return;
3068
3069 if (frame_) {
3070 frame_->Client()->RunScriptsAtDocumentIdle();
3071
3072 // Injected scripts may have disconnected this frame.
3073 if (!frame_)
3074 return;
3075
3076 // Check again, because runScriptsAtDocumentIdle() may have delayed the load
3077 // event.
3078 if (!ShouldComplete())
3079 return;
3080 }
3081
3082 // OK, completed. Fire load completion events as needed.
3083 SetReadyState(kComplete);
3084 if (LoadEventStillNeeded())
3085 ImplicitClose();
3086
3087 // The readystatechanged or load event may have disconnected this frame.
3088 if (!frame_ || !frame_->IsAttached())
3089 return;
3090 frame_->GetNavigationScheduler().StartTimer();
3091 // The document itself is complete, but if a child frame was restarted due to
3092 // an event, this document is still considered to be in progress.
3093 if (!AllDescendantsAreComplete(frame_))
3094 return;
3095
3096 // No need to repeat if we've already notified this load as finished.
3097 if (!Loader()->SentDidFinishLoad()) {
3098 if (frame_->IsMainFrame())
3099 ViewportDescription().ReportMobilePageStats(frame_);
3100 Loader()->SetSentDidFinishLoad();
3101 frame_->Client()->DispatchDidFinishLoad();
3102 if (!frame_)
3103 return;
3104 }
3105
3106 frame_->Loader().DidFinishNavigation();
3058 } 3107 }
3059 3108
3060 bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client, 3109 bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client,
3061 bool is_reload, 3110 bool is_reload,
3062 bool& did_allow_navigation) { 3111 bool& did_allow_navigation) {
3063 if (!dom_window_) 3112 if (!dom_window_)
3064 return true; 3113 return true;
3065 3114
3066 if (!body()) 3115 if (!body())
3067 return true; 3116 return true;
(...skipping 2896 matching lines...) Expand 10 before | Expand all | Expand 10 after
5964 --load_event_delay_count_; 6013 --load_event_delay_count_;
5965 6014
5966 if (!load_event_delay_count_) 6015 if (!load_event_delay_count_)
5967 CheckLoadEventSoon(); 6016 CheckLoadEventSoon();
5968 } 6017 }
5969 6018
5970 void Document::DecrementLoadEventDelayCountAndCheckLoadEvent() { 6019 void Document::DecrementLoadEventDelayCountAndCheckLoadEvent() {
5971 DCHECK(load_event_delay_count_); 6020 DCHECK(load_event_delay_count_);
5972 --load_event_delay_count_; 6021 --load_event_delay_count_;
5973 6022
5974 if (!load_event_delay_count_ && GetFrame()) 6023 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
5975 GetFrame()->Loader().CheckCompleted(); 6024 CheckCompleted();
5976 } 6025 }
5977 6026
5978 void Document::CheckLoadEventSoon() { 6027 void Document::CheckLoadEventSoon() {
5979 if (GetFrame() && !load_event_delay_timer_.IsActive()) 6028 if (GetFrame() && !load_event_delay_timer_.IsActive())
5980 load_event_delay_timer_.StartOneShot(0, BLINK_FROM_HERE); 6029 load_event_delay_timer_.StartOneShot(0, BLINK_FROM_HERE);
5981 } 6030 }
5982 6031
5983 bool Document::IsDelayingLoadEvent() { 6032 bool Document::IsDelayingLoadEvent() {
5984 // Always delay load events until after garbage collection. 6033 // Always delay load events until after garbage collection.
5985 // This way we don't have to explicitly delay load events via 6034 // This way we don't have to explicitly delay load events via
5986 // incrementLoadEventDelayCount and decrementLoadEventDelayCount in 6035 // incrementLoadEventDelayCount and decrementLoadEventDelayCount in
5987 // Node destructors. 6036 // Node destructors.
5988 if (ThreadState::Current()->SweepForbidden()) { 6037 if (ThreadState::Current()->SweepForbidden()) {
5989 if (!load_event_delay_count_) 6038 if (!load_event_delay_count_)
5990 CheckLoadEventSoon(); 6039 CheckLoadEventSoon();
5991 return true; 6040 return true;
5992 } 6041 }
5993 return load_event_delay_count_; 6042 return load_event_delay_count_;
5994 } 6043 }
5995 6044
5996 void Document::LoadEventDelayTimerFired(TimerBase*) { 6045 void Document::LoadEventDelayTimerFired(TimerBase*) {
5997 if (GetFrame()) 6046 CheckCompleted();
5998 GetFrame()->Loader().CheckCompleted();
5999 } 6047 }
6000 6048
6001 void Document::LoadPluginsSoon() { 6049 void Document::LoadPluginsSoon() {
6002 // FIXME: Remove this timer once we don't need to compute layout to load 6050 // FIXME: Remove this timer once we don't need to compute layout to load
6003 // plugins. 6051 // plugins.
6004 if (!plugin_loading_timer_.IsActive()) 6052 if (!plugin_loading_timer_.IsActive())
6005 plugin_loading_timer_.StartOneShot(0, BLINK_FROM_HERE); 6053 plugin_loading_timer_.StartOneShot(0, BLINK_FROM_HERE);
6006 } 6054 }
6007 6055
6008 void Document::PluginLoadingTimerFired(TimerBase*) { 6056 void Document::PluginLoadingTimerFired(TimerBase*) {
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
6664 } 6712 }
6665 6713
6666 void showLiveDocumentInstances() { 6714 void showLiveDocumentInstances() {
6667 WeakDocumentSet& set = liveDocumentSet(); 6715 WeakDocumentSet& set = liveDocumentSet();
6668 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); 6716 fprintf(stderr, "There are %u documents currently alive:\n", set.size());
6669 for (blink::Document* document : set) 6717 for (blink::Document* document : set)
6670 fprintf(stderr, "- Document %p URL: %s\n", document, 6718 fprintf(stderr, "- Document %p URL: %s\n", document,
6671 document->Url().GetString().Utf8().Data()); 6719 document->Url().GetString().Utf8().Data());
6672 } 6720 }
6673 #endif 6721 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698