OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |