Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/web_contents/web_contents_impl.h" | 5 #include "content/browser/web_contents/web_contents_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 | 114 |
| 115 #if defined(OS_MACOSX) | 115 #if defined(OS_MACOSX) |
| 116 #include "base/mac/foundation_util.h" | 116 #include "base/mac/foundation_util.h" |
| 117 #endif | 117 #endif |
| 118 | 118 |
| 119 namespace content { | 119 namespace content { |
| 120 namespace { | 120 namespace { |
| 121 | 121 |
| 122 const int kMinimumDelayBetweenLoadingUpdatesMS = 100; | 122 const int kMinimumDelayBetweenLoadingUpdatesMS = 100; |
| 123 | 123 |
| 124 // This matches what Blink's ProgressTracker has traditionally used for a | |
| 125 // minimum progress value. | |
| 126 const double kMinimumLoadingProgress = 0.1; | |
| 127 | 124 |
| 128 const char kDotGoogleDotCom[] = ".google.com"; | 125 const char kDotGoogleDotCom[] = ".google.com"; |
| 129 | 126 |
| 130 #if defined(OS_ANDROID) | 127 #if defined(OS_ANDROID) |
| 131 const char kWebContentsAndroidKey[] = "web_contents_android"; | 128 const char kWebContentsAndroidKey[] = "web_contents_android"; |
| 132 #endif // OS_ANDROID | 129 #endif // OS_ANDROID |
| 133 | 130 |
| 134 base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> > | 131 base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> > |
| 135 g_created_callbacks = LAZY_INSTANCE_INITIALIZER; | 132 g_created_callbacks = LAZY_INSTANCE_INITIALIZER; |
| 136 | 133 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 156 } | 153 } |
| 157 | 154 |
| 158 // Helper function for retrieving all the sites in a frame tree. | 155 // Helper function for retrieving all the sites in a frame tree. |
| 159 bool CollectSites(BrowserContext* context, | 156 bool CollectSites(BrowserContext* context, |
| 160 std::set<GURL>* sites, | 157 std::set<GURL>* sites, |
| 161 FrameTreeNode* node) { | 158 FrameTreeNode* node) { |
| 162 sites->insert(SiteInstance::GetSiteForURL(context, node->current_url())); | 159 sites->insert(SiteInstance::GetSiteForURL(context, node->current_url())); |
| 163 return true; | 160 return true; |
| 164 } | 161 } |
| 165 | 162 |
| 163 // Helper function for retrieving the total loading progress and number of | |
|
nasko
2015/02/23 16:54:43
nit: I like the "used with FrameTree::ForEach()" p
Fabrice (no longer in Chrome)
2015/02/23 20:02:06
Done.
| |
| 164 // frames in a frame tree. | |
| 165 bool CollectLoadProgress(double* progress, | |
| 166 int* frame_count, | |
| 167 FrameTreeNode* node) { | |
| 168 *progress += node->loading_progress(); | |
| 169 (*frame_count)++; | |
| 170 return true; | |
| 171 } | |
| 172 | |
| 173 // Helper function used with FrameTree::ForEach() to check if at least one of | |
| 174 // the nodes is loading. | |
| 175 bool IsNodeLoading(bool* is_loading, FrameTreeNode* node) { | |
| 176 if (node->is_loading()) { | |
| 177 // There is at least one node loading, abort traversal. | |
| 178 *is_loading = true; | |
| 179 return false; | |
| 180 } | |
| 181 return true; | |
| 182 } | |
| 183 | |
| 166 bool ForEachFrameInternal( | 184 bool ForEachFrameInternal( |
| 167 const base::Callback<void(RenderFrameHost*)>& on_frame, | 185 const base::Callback<void(RenderFrameHost*)>& on_frame, |
| 168 FrameTreeNode* node) { | 186 FrameTreeNode* node) { |
| 169 on_frame.Run(node->current_frame_host()); | 187 on_frame.Run(node->current_frame_host()); |
| 170 return true; | 188 return true; |
| 171 } | 189 } |
| 172 | 190 |
| 173 bool ForEachPendingFrameInternal( | 191 bool ForEachPendingFrameInternal( |
| 174 const base::Callback<void(RenderFrameHost*)>& on_frame, | 192 const base::Callback<void(RenderFrameHost*)>& on_frame, |
| 175 FrameTreeNode* node) { | 193 FrameTreeNode* node) { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 this, | 344 this, |
| 327 this, | 345 this, |
| 328 this), | 346 this), |
| 329 is_loading_(false), | 347 is_loading_(false), |
| 330 is_load_to_different_document_(false), | 348 is_load_to_different_document_(false), |
| 331 crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING), | 349 crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING), |
| 332 crashed_error_code_(0), | 350 crashed_error_code_(0), |
| 333 waiting_for_response_(false), | 351 waiting_for_response_(false), |
| 334 load_state_(net::LOAD_STATE_IDLE, base::string16()), | 352 load_state_(net::LOAD_STATE_IDLE, base::string16()), |
| 335 loading_total_progress_(0.0), | 353 loading_total_progress_(0.0), |
| 336 loading_frames_in_progress_(0), | |
| 337 upload_size_(0), | 354 upload_size_(0), |
| 338 upload_position_(0), | 355 upload_position_(0), |
| 339 displayed_insecure_content_(false), | 356 displayed_insecure_content_(false), |
| 340 has_accessed_initial_document_(false), | 357 has_accessed_initial_document_(false), |
| 341 capturer_count_(0), | 358 capturer_count_(0), |
| 342 should_normally_be_visible_(true), | 359 should_normally_be_visible_(true), |
| 343 is_being_destroyed_(false), | 360 is_being_destroyed_(false), |
| 344 notify_disconnection_(false), | 361 notify_disconnection_(false), |
| 345 dialog_manager_(NULL), | 362 dialog_manager_(NULL), |
| 346 is_showing_before_unload_dialog_(false), | 363 is_showing_before_unload_dialog_(false), |
| (...skipping 2476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2823 FOR_EACH_OBSERVER( | 2840 FOR_EACH_OBSERVER( |
| 2824 WebContentsObserver, observers_, DidFinishLoad(rfh, validated_url)); | 2841 WebContentsObserver, observers_, DidFinishLoad(rfh, validated_url)); |
| 2825 } | 2842 } |
| 2826 | 2843 |
| 2827 void WebContentsImpl::OnDidStartLoading(bool to_different_document) { | 2844 void WebContentsImpl::OnDidStartLoading(bool to_different_document) { |
| 2828 if (!HasValidFrameSource()) | 2845 if (!HasValidFrameSource()) |
| 2829 return; | 2846 return; |
| 2830 | 2847 |
| 2831 RenderFrameHostImpl* rfh = | 2848 RenderFrameHostImpl* rfh = |
| 2832 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); | 2849 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
| 2833 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id(); | 2850 |
| 2851 // Update pending rfh in the frame tree node if necessary. | |
| 2852 if (rfh->frame_tree_node()->pending_frame_host() != rfh) { | |
|
nasko
2015/02/23 16:54:43
Pending RFH has a very precise meaning and it does
Fabrice (no longer in Chrome)
2015/02/23 20:02:06
Done.
| |
| 2853 rfh->frame_tree_node()->set_pending_frame_host(rfh); | |
| 2854 rfh->frame_tree_node()->set_is_loading(false); | |
| 2855 rfh->frame_tree_node()->set_loading_progress( | |
| 2856 FrameTreeNode::kLoadingProgressNotStarted); | |
| 2857 } | |
| 2834 | 2858 |
| 2835 // Any main frame load to a new document should reset the load progress, since | 2859 // Any main frame load to a new document should reset the load progress, since |
| 2836 // it will replace the current page and any frames. | 2860 // it will replace the current page and any frames. |
| 2837 if (to_different_document && !rfh->GetParent()) { | 2861 if (to_different_document && !rfh->GetParent()) { |
| 2838 ResetLoadProgressState(); | 2862 ResetLoadProgressState(); |
| 2839 loading_frames_in_progress_ = 0; | |
| 2840 rfh->frame_tree_node()->set_is_loading(false); | 2863 rfh->frame_tree_node()->set_is_loading(false); |
| 2864 rfh->frame_tree_node()->set_loading_progress( | |
| 2865 FrameTreeNode::kLoadingProgressNotStarted); | |
| 2841 } | 2866 } |
| 2842 | 2867 |
| 2843 // It is possible to get multiple calls to OnDidStartLoading that don't have | 2868 // It is possible to get multiple calls to OnDidStartLoading that don't have |
| 2844 // corresponding calls to OnDidStopLoading: | 2869 // corresponding calls to OnDidStopLoading: |
| 2845 // - With "swappedout://" URLs, this happens when a RenderView gets swapped | 2870 // - With "swappedout://" URLs, this happens when a RenderView gets swapped |
| 2846 // out for a cross-process navigation, and it turns into a placeholder for | 2871 // out for a cross-process navigation, and it turns into a placeholder for |
| 2847 // one being rendered in a different process. | 2872 // one being rendered in a different process. |
| 2848 // - Also, there might be more than one RenderFrameHost sharing the same | 2873 // - Also, there might be more than one RenderFrameHost sharing the same |
| 2849 // FrameTreeNode (and thus sharing its ID) each sending a start. | 2874 // FrameTreeNode (and thus sharing its ID) each sending a start. |
| 2850 // - But in the future, once clamy@ moves navigation network requests to the | 2875 // - But in the future, once clamy@ moves navigation network requests to the |
| 2851 // browser process, there's a good chance that callbacks about starting and | 2876 // browser process, there's a good chance that callbacks about starting and |
| 2852 // stopping will all be handled by the browser. When that happens, there | 2877 // stopping will all be handled by the browser. When that happens, there |
| 2853 // should no longer be a start/stop call imbalance. TODO(avi): When this | 2878 // should no longer be a start/stop call imbalance. TODO(avi): When this |
| 2854 // future arrives, update this code to not allow this case. | 2879 // future arrives, update this code to not allow this case. |
| 2855 if (rfh->frame_tree_node()->is_loading()) | 2880 if (rfh->frame_tree_node()->is_loading()) |
| 2856 return; | 2881 return; |
| 2857 | 2882 |
| 2858 DCHECK_GE(loading_frames_in_progress_, 0); | 2883 if (!IsFrameTreeLoading()) |
| 2859 if (loading_frames_in_progress_ == 0) | |
| 2860 DidStartLoading(rfh, to_different_document); | 2884 DidStartLoading(rfh, to_different_document); |
| 2861 | 2885 |
| 2862 ++loading_frames_in_progress_; | |
| 2863 rfh->frame_tree_node()->set_is_loading(true); | 2886 rfh->frame_tree_node()->set_is_loading(true); |
| 2887 rfh->frame_tree_node()->set_loading_progress( | |
| 2888 FrameTreeNode::kLoadingProgressMinimum); | |
| 2864 | 2889 |
| 2865 // Notify the RenderFrameHostManager of the event. | 2890 // Notify the RenderFrameHostManager of the event. |
| 2866 rfh->frame_tree_node()->render_manager()->OnDidStartLoading(); | 2891 rfh->frame_tree_node()->render_manager()->OnDidStartLoading(); |
| 2867 | 2892 |
| 2868 loading_progresses_[render_frame_id] = kMinimumLoadingProgress; | |
| 2869 SendLoadProgressChanged(); | 2893 SendLoadProgressChanged(); |
| 2870 } | 2894 } |
| 2871 | 2895 |
| 2872 void WebContentsImpl::OnDidStopLoading() { | 2896 void WebContentsImpl::OnDidStopLoading() { |
| 2873 if (!HasValidFrameSource()) | 2897 if (!HasValidFrameSource()) |
| 2874 return; | 2898 return; |
| 2875 | 2899 |
| 2876 RenderFrameHostImpl* rfh = | 2900 RenderFrameHostImpl* rfh = |
| 2877 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); | 2901 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
| 2878 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id(); | 2902 |
| 2903 // StopLoading was called for an older navigation, ignore. | |
| 2904 if (rfh->frame_tree_node()->pending_frame_host() != rfh) | |
| 2905 return; | |
| 2906 | |
| 2907 DCHECK(rfh->frame_tree_node()->is_loading()); | |
| 2879 rfh->frame_tree_node()->set_is_loading(false); | 2908 rfh->frame_tree_node()->set_is_loading(false); |
| 2880 | 2909 |
| 2881 if (loading_progresses_.find(render_frame_id) != loading_progresses_.end()) { | 2910 // This method should never be called when the frame is not loading. |
|
nasko
2015/02/23 16:54:43
A DCHECK is warranted every time we have a "should
Fabrice (no longer in Chrome)
2015/02/23 20:02:06
This got shuffled around, the comment is at the pr
| |
| 2882 // Load stopped while we were still tracking load. Make sure we update | 2911 rfh->frame_tree_node()->set_loading_progress( |
| 2883 // progress based on this frame's completion. | 2912 FrameTreeNode::kLoadingProgressDone); |
| 2884 loading_progresses_[render_frame_id] = 1.0; | 2913 |
| 2885 SendLoadProgressChanged(); | 2914 // Update progress based on this frame's completion. |
| 2886 // Then we clean-up our states. | 2915 SendLoadProgressChanged(); |
| 2887 if (loading_total_progress_ == 1.0) | 2916 // Then clean-up the states. |
| 2888 ResetLoadProgressState(); | 2917 if (loading_total_progress_ == 1.0) |
| 2889 } | 2918 ResetLoadProgressState(); |
| 2890 | 2919 |
| 2891 // Notify the RenderFrameHostManager of the event. | 2920 // Notify the RenderFrameHostManager of the event. |
| 2892 rfh->frame_tree_node()->render_manager()->OnDidStopLoading(); | 2921 rfh->frame_tree_node()->render_manager()->OnDidStopLoading(); |
| 2893 | 2922 |
| 2894 // TODO(japhet): This should be a DCHECK, but the pdf plugin sometimes | 2923 if (!IsFrameTreeLoading()) |
| 2895 // calls DidStopLoading() without a matching DidStartLoading(). | |
| 2896 if (loading_frames_in_progress_ == 0) | |
| 2897 return; | |
| 2898 --loading_frames_in_progress_; | |
| 2899 if (loading_frames_in_progress_ == 0) | |
| 2900 DidStopLoading(rfh); | 2924 DidStopLoading(rfh); |
| 2901 } | 2925 } |
| 2902 | 2926 |
| 2903 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { | 2927 void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) { |
| 2904 if (!HasValidFrameSource()) | 2928 if (!HasValidFrameSource()) |
| 2905 return; | 2929 return; |
| 2906 | 2930 |
| 2907 RenderFrameHostImpl* rfh = | 2931 RenderFrameHostImpl* rfh = |
| 2908 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); | 2932 static_cast<RenderFrameHostImpl*>(render_frame_message_source_); |
| 2909 int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id(); | |
| 2910 | 2933 |
| 2911 loading_progresses_[render_frame_id] = load_progress; | 2934 rfh->frame_tree_node()->set_loading_progress(load_progress); |
| 2912 | 2935 |
| 2913 // We notify progress change immediately for the first and last updates. | 2936 // We notify progress change immediately for the first and last updates. |
| 2914 // Also, since the message loop may be pretty busy when a page is loaded, it | 2937 // Also, since the message loop may be pretty busy when a page is loaded, it |
| 2915 // might not execute a posted task in a timely manner so we make sure to | 2938 // might not execute a posted task in a timely manner so we make sure to |
| 2916 // immediately send progress report if enough time has passed. | 2939 // immediately send progress report if enough time has passed. |
| 2917 base::TimeDelta min_delay = | 2940 base::TimeDelta min_delay = |
| 2918 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); | 2941 base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS); |
| 2919 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || | 2942 if (load_progress == 1.0 || loading_last_progress_update_.is_null() || |
| 2920 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { | 2943 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) { |
| 2921 // If there is a pending task to send progress, it is now obsolete. | 2944 // If there is a pending task to send progress, it is now obsolete. |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3383 Details<std::pair<NavigationEntry*, bool> >(&details)); | 3406 Details<std::pair<NavigationEntry*, bool> >(&details)); |
| 3384 | 3407 |
| 3385 return true; | 3408 return true; |
| 3386 } | 3409 } |
| 3387 | 3410 |
| 3388 void WebContentsImpl::SendLoadProgressChanged() { | 3411 void WebContentsImpl::SendLoadProgressChanged() { |
| 3389 loading_last_progress_update_ = base::TimeTicks::Now(); | 3412 loading_last_progress_update_ = base::TimeTicks::Now(); |
| 3390 double progress = 0.0; | 3413 double progress = 0.0; |
| 3391 int frame_count = 0; | 3414 int frame_count = 0; |
| 3392 | 3415 |
| 3393 for (LoadingProgressMap::iterator it = loading_progresses_.begin(); | 3416 frame_tree_.ForEach( |
| 3394 it != loading_progresses_.end(); | 3417 base::Bind(&CollectLoadProgress, &progress, &frame_count)); |
| 3395 ++it) { | |
| 3396 progress += it->second; | |
| 3397 ++frame_count; | |
| 3398 } | |
| 3399 if (frame_count == 0) | |
| 3400 return; | |
| 3401 progress /= frame_count; | 3418 progress /= frame_count; |
| 3402 DCHECK(progress <= 1.0); | 3419 DCHECK(progress <= 1.0); |
| 3403 | 3420 |
| 3404 if (progress <= loading_total_progress_) | 3421 if (progress <= loading_total_progress_) |
| 3405 return; | 3422 return; |
| 3406 loading_total_progress_ = progress; | 3423 loading_total_progress_ = progress; |
| 3407 | 3424 |
| 3408 if (delegate_) | 3425 if (delegate_) |
| 3409 delegate_->LoadProgressChanged(this, progress); | 3426 delegate_->LoadProgressChanged(this, progress); |
| 3410 } | 3427 } |
| 3411 | 3428 |
| 3412 void WebContentsImpl::ResetLoadProgressState() { | 3429 void WebContentsImpl::ResetLoadProgressState() { |
| 3413 loading_progresses_.clear(); | |
| 3414 loading_total_progress_ = 0.0; | 3430 loading_total_progress_ = 0.0; |
| 3415 loading_weak_factory_.InvalidateWeakPtrs(); | 3431 loading_weak_factory_.InvalidateWeakPtrs(); |
| 3416 loading_last_progress_update_ = base::TimeTicks(); | 3432 loading_last_progress_update_ = base::TimeTicks(); |
| 3417 } | 3433 } |
| 3418 | 3434 |
| 3419 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host, | 3435 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host, |
| 3420 RenderViewHost* new_host) { | 3436 RenderViewHost* new_host) { |
| 3421 // After sending out a swap notification, we need to send a disconnect | 3437 // After sending out a swap notification, we need to send a disconnect |
| 3422 // notification so that clients that pick up a pointer to |this| can NULL the | 3438 // notification so that clients that pick up a pointer to |this| can NULL the |
| 3423 // pointer. See Bug 1230284. | 3439 // pointer. See Bug 1230284. |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3720 | 3736 |
| 3721 SetIsLoading(rvh, false, true, NULL); | 3737 SetIsLoading(rvh, false, true, NULL); |
| 3722 NotifyDisconnected(); | 3738 NotifyDisconnected(); |
| 3723 SetIsCrashed(status, error_code); | 3739 SetIsCrashed(status, error_code); |
| 3724 | 3740 |
| 3725 // Reset the loading progress. TODO(avi): What does it mean to have a | 3741 // Reset the loading progress. TODO(avi): What does it mean to have a |
| 3726 // "renderer crash" when there is more than one renderer process serving a | 3742 // "renderer crash" when there is more than one renderer process serving a |
| 3727 // webpage? Once this function is called at a more granular frame level, we | 3743 // webpage? Once this function is called at a more granular frame level, we |
| 3728 // probably will need to more granularly reset the state here. | 3744 // probably will need to more granularly reset the state here. |
| 3729 ResetLoadProgressState(); | 3745 ResetLoadProgressState(); |
| 3730 loading_frames_in_progress_ = 0; | |
| 3731 | 3746 |
| 3732 FOR_EACH_OBSERVER(WebContentsObserver, | 3747 FOR_EACH_OBSERVER(WebContentsObserver, |
| 3733 observers_, | 3748 observers_, |
| 3734 RenderProcessGone(GetCrashedStatus())); | 3749 RenderProcessGone(GetCrashedStatus())); |
| 3735 } | 3750 } |
| 3736 | 3751 |
| 3737 void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) { | 3752 void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) { |
| 3738 FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh)); | 3753 FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh)); |
| 3739 } | 3754 } |
| 3740 | 3755 |
| (...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4512 FrameTreeNode* node = frame_tree_.root(); | 4527 FrameTreeNode* node = frame_tree_.root(); |
| 4513 node->render_manager()->ResumeResponseDeferredAtStart(); | 4528 node->render_manager()->ResumeResponseDeferredAtStart(); |
| 4514 } | 4529 } |
| 4515 | 4530 |
| 4516 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { | 4531 void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { |
| 4517 force_disable_overscroll_content_ = force_disable; | 4532 force_disable_overscroll_content_ = force_disable; |
| 4518 if (view_) | 4533 if (view_) |
| 4519 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); | 4534 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); |
| 4520 } | 4535 } |
| 4521 | 4536 |
| 4537 bool WebContentsImpl::IsFrameTreeLoading() { | |
| 4538 bool is_loading = false; | |
| 4539 frame_tree_.ForEach(base::Bind(&IsNodeLoading, &is_loading)); | |
| 4540 return is_loading; | |
| 4541 } | |
| 4542 | |
| 4522 } // namespace content | 4543 } // namespace content |
| OLD | NEW |