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

Side by Side Diff: third_party/WebKit/Source/core/dom/Document.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) 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 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 contains_validity_style_rules_(false), 481 contains_validity_style_rules_(false),
482 contains_plugins_(false), 482 contains_plugins_(false),
483 ignore_destructive_write_count_(0), 483 ignore_destructive_write_count_(0),
484 throw_on_dynamic_markup_insertion_count_(0), 484 throw_on_dynamic_markup_insertion_count_(0),
485 markers_(new DocumentMarkerController(*this)), 485 markers_(new DocumentMarkerController(*this)),
486 update_focus_appearance_timer_( 486 update_focus_appearance_timer_(
487 TaskRunnerHelper::Get(TaskType::kUnspecedTimer, this), 487 TaskRunnerHelper::Get(TaskType::kUnspecedTimer, this),
488 this, 488 this,
489 &Document::UpdateFocusAppearanceTimerFired), 489 &Document::UpdateFocusAppearanceTimerFired),
490 css_target_(nullptr), 490 css_target_(nullptr),
491 load_event_progress_(kLoadEventNotRun), 491 load_event_progress_(kLoadEventCompleted),
492 start_time_(CurrentTime()), 492 start_time_(CurrentTime()),
493 script_runner_(ScriptRunner::Create(this)), 493 script_runner_(ScriptRunner::Create(this)),
494 xml_version_("1.0"), 494 xml_version_("1.0"),
495 xml_standalone_(kStandaloneUnspecified), 495 xml_standalone_(kStandaloneUnspecified),
496 has_xml_declaration_(0), 496 has_xml_declaration_(0),
497 design_mode_(false), 497 design_mode_(false),
498 is_running_exec_command_(false), 498 is_running_exec_command_(false),
499 has_annotated_regions_(false), 499 has_annotated_regions_(false),
500 annotated_regions_dirty_(false), 500 annotated_regions_dirty_(false),
501 document_classes_(document_classes), 501 document_classes_(document_classes),
(...skipping 2269 matching lines...) Expand 10 before | Expand all | Expand 10 after
2771 RemoveAllEventListenersRecursively(); 2771 RemoveAllEventListenersRecursively();
2772 ResetTreeScope(); 2772 ResetTreeScope();
2773 if (frame_) 2773 if (frame_)
2774 frame_->Selection().Clear(); 2774 frame_->Selection().Clear();
2775 ImplicitOpen(kForceSynchronousParsing); 2775 ImplicitOpen(kForceSynchronousParsing);
2776 if (ScriptableDocumentParser* parser = GetScriptableDocumentParser()) 2776 if (ScriptableDocumentParser* parser = GetScriptableDocumentParser())
2777 parser->SetWasCreatedByScript(true); 2777 parser->SetWasCreatedByScript(true);
2778 2778
2779 if (frame_) 2779 if (frame_)
2780 frame_->Loader().DidExplicitOpen(); 2780 frame_->Loader().DidExplicitOpen();
2781 if (load_event_progress_ != kLoadEventInProgress &&
2782 PageDismissalEventBeingDispatched() == kNoDismissal)
2783 load_event_progress_ = kLoadEventNotRun;
2784 } 2781 }
2785 2782
2786 void Document::DetachParser() { 2783 void Document::DetachParser() {
2787 if (!parser_) 2784 if (!parser_)
2788 return; 2785 return;
2789 parser_->Detach(); 2786 parser_->Detach();
2790 parser_.Clear(); 2787 parser_.Clear();
2791 DocumentParserTiming::From(*this).MarkParserDetached(); 2788 DocumentParserTiming::From(*this).MarkParserDetached();
2792 } 2789 }
2793 2790
2794 void Document::CancelParsing() { 2791 void Document::CancelParsing() {
2795 DetachParser(); 2792 DetachParser();
2796 SetParsingState(kFinishedParsing); 2793 SetParsingState(kFinishedParsing);
2797 SetReadyState(kComplete); 2794 SetReadyState(kComplete);
2795 SuppressLoadEvent();
2798 } 2796 }
2799 2797
2800 DocumentParser* Document::ImplicitOpen( 2798 DocumentParser* Document::ImplicitOpen(
2801 ParserSynchronizationPolicy parser_sync_policy) { 2799 ParserSynchronizationPolicy parser_sync_policy) {
2802 DetachParser();
2803
2804 RemoveChildren(); 2800 RemoveChildren();
2805 DCHECK(!focused_element_); 2801 DCHECK(!focused_element_);
2806 2802
2807 SetCompatibilityMode(kNoQuirksMode); 2803 SetCompatibilityMode(kNoQuirksMode);
2808 2804
2809 if (!ThreadedParsingEnabledForTesting()) { 2805 if (!ThreadedParsingEnabledForTesting()) {
2810 parser_sync_policy = kForceSynchronousParsing; 2806 parser_sync_policy = kForceSynchronousParsing;
2811 } else if (parser_sync_policy == kAllowAsynchronousParsing && 2807 } else if (parser_sync_policy == kAllowAsynchronousParsing &&
2812 IsPrefetchOnly()) { 2808 IsPrefetchOnly()) {
2813 // Prefetch must be synchronous. 2809 // Prefetch must be synchronous.
2814 parser_sync_policy = kForceSynchronousParsing; 2810 parser_sync_policy = kForceSynchronousParsing;
2815 } 2811 }
2816 2812
2813 DetachParser();
2817 parser_sync_policy_ = parser_sync_policy; 2814 parser_sync_policy_ = parser_sync_policy;
2818 parser_ = CreateParser(); 2815 parser_ = CreateParser();
2819 DocumentParserTiming::From(*this).MarkParserStart(); 2816 DocumentParserTiming::From(*this).MarkParserStart();
2820 SetParsingState(kParsing); 2817 SetParsingState(kParsing);
2821 SetReadyState(kLoading); 2818 SetReadyState(kLoading);
2819 if (load_event_progress_ != kLoadEventInProgress &&
2820 PageDismissalEventBeingDispatched() == kNoDismissal) {
2821 load_event_progress_ = kLoadEventNotRun;
2822 }
2822 2823
2823 return parser_; 2824 return parser_;
2824 } 2825 }
2825 2826
2826 HTMLElement* Document::body() const { 2827 HTMLElement* Document::body() const {
2827 if (!documentElement() || !isHTMLHtmlElement(documentElement())) 2828 if (!documentElement() || !isHTMLHtmlElement(documentElement()))
2828 return 0; 2829 return 0;
2829 2830
2830 for (HTMLElement* child = 2831 for (HTMLElement* child =
2831 Traversal<HTMLElement>::FirstChild(*documentElement()); 2832 Traversal<HTMLElement>::FirstChild(*documentElement());
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2953 2954
2954 close(); 2955 close();
2955 } 2956 }
2956 2957
2957 void Document::close() { 2958 void Document::close() {
2958 if (!GetScriptableDocumentParser() || 2959 if (!GetScriptableDocumentParser() ||
2959 !GetScriptableDocumentParser()->WasCreatedByScript() || 2960 !GetScriptableDocumentParser()->WasCreatedByScript() ||
2960 !GetScriptableDocumentParser()->IsParsing()) 2961 !GetScriptableDocumentParser()->IsParsing())
2961 return; 2962 return;
2962 2963
2963 if (DocumentParser* parser = parser_) 2964 parser_->Finish();
2964 parser->Finish(); 2965 if (!parser_ || !parser_->IsParsing())
2965 2966 SetReadyState(kComplete);
2966 if (!frame_) { 2967 CheckCompleted();
2967 // Because we have no frame, we don't know if all loading has completed,
2968 // so we just call implicitClose() immediately. FIXME: This might fire
2969 // the load event prematurely
2970 // <http://bugs.webkit.org/show_bug.cgi?id=14568>.
2971 ImplicitClose();
2972 return;
2973 }
2974
2975 frame_->Loader().CheckCompleted();
2976 } 2968 }
2977 2969
2978 void Document::ImplicitClose() { 2970 void Document::ImplicitClose() {
2979 DCHECK(!InStyleRecalc()); 2971 DCHECK(!InStyleRecalc());
2980 if (ProcessingLoadEvent() || !parser_) 2972 DCHECK(parser_);
2981 return;
2982 if (GetFrame() &&
2983 GetFrame()->GetNavigationScheduler().LocationChangePending()) {
2984 SuppressLoadEvent();
2985 return;
2986 }
2987 2973
2988 load_event_progress_ = kLoadEventInProgress; 2974 load_event_progress_ = kLoadEventInProgress;
2989 2975
2990 ScriptableDocumentParser* parser = GetScriptableDocumentParser(); 2976 ScriptableDocumentParser* parser = GetScriptableDocumentParser();
2991 well_formed_ = parser && parser->WellFormed(); 2977 well_formed_ = parser && parser->WellFormed();
2992 2978
2993 // We have to clear the parser, in case someone document.write()s from the 2979 // We have to clear the parser, in case someone document.write()s from the
2994 // onLoad event handler, as in Radar 3206524. 2980 // onLoad event handler, as in Radar 3206524.
2995 DetachParser(); 2981 DetachParser();
2996 2982
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3058 cache->HandleLoadComplete(this); 3044 cache->HandleLoadComplete(this);
3059 else 3045 else
3060 cache->HandleLayoutComplete(this); 3046 cache->HandleLayoutComplete(this);
3061 } 3047 }
3062 } 3048 }
3063 3049
3064 if (SvgExtensions()) 3050 if (SvgExtensions())
3065 AccessSVGExtensions().StartAnimations(); 3051 AccessSVGExtensions().StartAnimations();
3066 } 3052 }
3067 3053
3054 static bool AllDescendantsAreComplete(Frame* frame) {
3055 if (!frame)
3056 return true;
3057 for (Frame* child = frame->Tree().FirstChild(); child;
3058 child = child->Tree().TraverseNext(frame)) {
3059 if (child->IsLoading())
3060 return false;
3061 }
3062 return true;
3063 }
3064
3065 bool Document::ShouldComplete() {
3066 return parsing_state_ == kFinishedParsing && HaveImportsLoaded() &&
3067 !fetcher_->BlockingRequestCount() && !IsDelayingLoadEvent() &&
3068 load_event_progress_ != kLoadEventInProgress &&
3069 AllDescendantsAreComplete(frame_);
3070 }
3071
3072 void Document::CheckCompleted() {
3073 if (!ShouldComplete())
3074 return;
3075
3076 if (frame_) {
3077 frame_->Client()->RunScriptsAtDocumentIdle();
3078
3079 // Injected scripts may have disconnected this frame.
3080 if (!frame_)
3081 return;
3082
3083 // Check again, because runScriptsAtDocumentIdle() may have delayed the load
3084 // event.
3085 if (!ShouldComplete())
3086 return;
3087 }
3088
3089 // OK, completed. Fire load completion events as needed.
3090 SetReadyState(kComplete);
3091 if (LoadEventStillNeeded())
3092 ImplicitClose();
3093
3094 // The readystatechanged or load event may have disconnected this frame.
3095 if (!frame_ || !frame_->IsAttached())
3096 return;
3097 frame_->GetNavigationScheduler().StartTimer();
3098 View()->HandleLoadCompleted();
3099 // The document itself is complete, but if a child frame was restarted due to
3100 // an event, this document is still considered to be in progress.
3101 if (!AllDescendantsAreComplete(frame_))
3102 return;
3103
3104 // No need to repeat if we've already notified this load as finished.
3105 if (!Loader()->SentDidFinishLoad()) {
3106 if (frame_->IsMainFrame())
3107 ViewportDescription().ReportMobilePageStats(frame_);
3108 Loader()->SetSentDidFinishLoad();
3109 frame_->Client()->DispatchDidFinishLoad();
3110 if (!frame_)
3111 return;
3112 }
3113
3114 frame_->Loader().DidFinishNavigation();
3115 }
3116
3068 bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client, 3117 bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client,
3069 bool is_reload, 3118 bool is_reload,
3070 bool& did_allow_navigation) { 3119 bool& did_allow_navigation) {
3071 if (!dom_window_) 3120 if (!dom_window_)
3072 return true; 3121 return true;
3073 3122
3074 if (!body()) 3123 if (!body())
3075 return true; 3124 return true;
3076 3125
3077 if (ProcessingBeforeUnload()) 3126 if (ProcessingBeforeUnload())
(...skipping 2931 matching lines...) Expand 10 before | Expand all | Expand 10 after
6009 --load_event_delay_count_; 6058 --load_event_delay_count_;
6010 6059
6011 if (!load_event_delay_count_) 6060 if (!load_event_delay_count_)
6012 CheckLoadEventSoon(); 6061 CheckLoadEventSoon();
6013 } 6062 }
6014 6063
6015 void Document::DecrementLoadEventDelayCountAndCheckLoadEvent() { 6064 void Document::DecrementLoadEventDelayCountAndCheckLoadEvent() {
6016 DCHECK(load_event_delay_count_); 6065 DCHECK(load_event_delay_count_);
6017 --load_event_delay_count_; 6066 --load_event_delay_count_;
6018 6067
6019 if (!load_event_delay_count_ && GetFrame()) 6068 if (!load_event_delay_count_)
6020 GetFrame()->Loader().CheckCompleted(); 6069 CheckCompleted();
6021 } 6070 }
6022 6071
6023 void Document::CheckLoadEventSoon() { 6072 void Document::CheckLoadEventSoon() {
6024 if (GetFrame() && !load_event_delay_timer_.IsActive()) 6073 if (GetFrame() && !load_event_delay_timer_.IsActive())
6025 load_event_delay_timer_.StartOneShot(0, BLINK_FROM_HERE); 6074 load_event_delay_timer_.StartOneShot(0, BLINK_FROM_HERE);
6026 } 6075 }
6027 6076
6028 bool Document::IsDelayingLoadEvent() { 6077 bool Document::IsDelayingLoadEvent() {
6029 // Always delay load events until after garbage collection. 6078 // Always delay load events until after garbage collection.
6030 // This way we don't have to explicitly delay load events via 6079 // This way we don't have to explicitly delay load events via
6031 // incrementLoadEventDelayCount and decrementLoadEventDelayCount in 6080 // incrementLoadEventDelayCount and decrementLoadEventDelayCount in
6032 // Node destructors. 6081 // Node destructors.
6033 if (ThreadState::Current()->SweepForbidden()) { 6082 if (ThreadState::Current()->SweepForbidden()) {
6034 if (!load_event_delay_count_) 6083 if (!load_event_delay_count_)
6035 CheckLoadEventSoon(); 6084 CheckLoadEventSoon();
6036 return true; 6085 return true;
6037 } 6086 }
6038 return load_event_delay_count_; 6087 return load_event_delay_count_;
6039 } 6088 }
6040 6089
6041 void Document::LoadEventDelayTimerFired(TimerBase*) { 6090 void Document::LoadEventDelayTimerFired(TimerBase*) {
6042 if (GetFrame()) 6091 CheckCompleted();
6043 GetFrame()->Loader().CheckCompleted();
6044 } 6092 }
6045 6093
6046 void Document::LoadPluginsSoon() { 6094 void Document::LoadPluginsSoon() {
6047 // FIXME: Remove this timer once we don't need to compute layout to load 6095 // FIXME: Remove this timer once we don't need to compute layout to load
6048 // plugins. 6096 // plugins.
6049 if (!plugin_loading_timer_.IsActive()) 6097 if (!plugin_loading_timer_.IsActive())
6050 plugin_loading_timer_.StartOneShot(0, BLINK_FROM_HERE); 6098 plugin_loading_timer_.StartOneShot(0, BLINK_FROM_HERE);
6051 } 6099 }
6052 6100
6053 void Document::PluginLoadingTimerFired(TimerBase*) { 6101 void Document::PluginLoadingTimerFired(TimerBase*) {
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
6701 } 6749 }
6702 6750
6703 void showLiveDocumentInstances() { 6751 void showLiveDocumentInstances() {
6704 WeakDocumentSet& set = liveDocumentSet(); 6752 WeakDocumentSet& set = liveDocumentSet();
6705 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); 6753 fprintf(stderr, "There are %u documents currently alive:\n", set.size());
6706 for (blink::Document* document : set) 6754 for (blink::Document* document : set)
6707 fprintf(stderr, "- Document %p URL: %s\n", document, 6755 fprintf(stderr, "- Document %p URL: %s\n", document,
6708 document->Url().GetString().Utf8().data()); 6756 document->Url().GetString().Utf8().data());
6709 } 6757 }
6710 #endif 6758 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698