blob: c5d1a219a3cef4d26e921e2aaf78fd64faca1bf9 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/web/web_state_update_browser_agent.h"
#import "ios/web/public/ui/crw_web_view_proxy.h"
#import "ios/web/public/ui/crw_web_view_scroll_view_proxy.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
BROWSER_USER_DATA_KEY_IMPL(WebStateUpdateBrowserAgent)
WebStateUpdateBrowserAgent::WebStateUpdateBrowserAgent(Browser* browser)
: web_state_list_(browser->GetWebStateList()) {
web_state_list_observation_.Observe(web_state_list_);
// All the BrowserAgent are attached to the Browser during the creation,
// the WebStateList must be empty at this point.
DCHECK(web_state_list_->empty())
<< "WebStateUpdateBrowserAgent created for a Browser with a non-empty "
"WebStateList.";
}
WebStateUpdateBrowserAgent::~WebStateUpdateBrowserAgent() {}
#pragma mark - Public
void WebStateUpdateBrowserAgent::UpdateWebStateScrollViewOffset(
CGFloat toolbar_height) {
if (!web_state_list_) {
return;
}
for (int index = 0; index < web_state_list_->count(); ++index) {
web::WebState* web_state = web_state_list_->GetWebStateAt(index);
CRWWebViewScrollViewProxy* scroll_proxy =
web_state->GetWebViewProxy().scrollViewProxy;
CGPoint scroll_offset = scroll_proxy.contentOffset;
scroll_offset.y += toolbar_height;
scroll_proxy.contentOffset = scroll_offset;
}
}
#pragma mark - WebStateListObserver
void WebStateUpdateBrowserAgent::WebStateListDidChange(
WebStateList* web_state_list,
const WebStateListChange& change,
const WebStateSelection& selection) {
switch (change.type()) {
case WebStateListChange::Type::kSelectionOnly:
// TODO(crbug.com/1442546): Move the implementation from
// WebStateActivatedAt() to here. Note that here is reachable only when
// `reason` == ActiveWebStateChangeReason::Activated.
break;
case WebStateListChange::Type::kDetach: {
// Inform the detached web state that it is no longer visible.
const WebStateListChangeDetach& detach_change =
change.As<WebStateListChangeDetach>();
web::WebState* detached_web_state = detach_change.detached_web_state();
if (detached_web_state->IsRealized()) {
detached_web_state->WasHidden();
detached_web_state->SetKeepRenderProcessAlive(false);
}
break;
}
case WebStateListChange::Type::kMove:
// Do nothing when a WebState is moved.
break;
case WebStateListChange::Type::kReplace:
// Do nothing when a WebState is replaced.
break;
case WebStateListChange::Type::kInsert:
// Do nothing when a WebState is inserted.
break;
}
}
void WebStateUpdateBrowserAgent::WebStateActivatedAt(
WebStateList* web_state_list,
web::WebState* old_web_state,
web::WebState* new_web_state,
int active_index,
ActiveWebStateChangeReason reason) {
// Inform the old web state that it is no longer visible.
if (old_web_state) {
old_web_state->WasHidden();
old_web_state->SetKeepRenderProcessAlive(false);
}
if (new_web_state) {
new_web_state->GetWebViewProxy().scrollViewProxy.clipsToBounds = NO;
}
}
void WebStateUpdateBrowserAgent::WebStateListDestroyed(
WebStateList* web_state_list) {
// Stop observing web state list.
web_state_list_observation_.Reset();
}