| // Copyright 2017 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/ui/fullscreen/fullscreen_web_state_observer.h" |
| |
| #import "base/check_op.h" |
| #import "base/ios/ios_util.h" |
| #import "ios/chrome/browser/ui/fullscreen/fullscreen_content_adjustment_util.h" |
| #import "ios/chrome/browser/ui/fullscreen/fullscreen_mediator.h" |
| #import "ios/chrome/browser/ui/fullscreen/fullscreen_model.h" |
| #import "ios/chrome/browser/ui/fullscreen/fullscreen_web_view_proxy_observer.h" |
| #import "ios/chrome/browser/ui/fullscreen/scoped_fullscreen_disabler.h" |
| #import "ios/public/provider/chrome/browser/fullscreen/fullscreen_api.h" |
| #import "ios/web/common/url_util.h" |
| #import "ios/web/public/navigation/navigation_context.h" |
| #import "ios/web/public/navigation/navigation_item.h" |
| #import "ios/web/public/navigation/navigation_manager.h" |
| #import "ios/web/public/security/ssl_status.h" |
| #import "ios/web/public/ui/crw_web_view_proxy.h" |
| #import "ios/web/public/web_state.h" |
| |
| FullscreenWebStateObserver::FullscreenWebStateObserver( |
| FullscreenController* controller, |
| FullscreenModel* model, |
| FullscreenMediator* mediator) |
| : controller_(controller), |
| model_(model), |
| mediator_(mediator), |
| web_view_proxy_observer_([[FullscreenWebViewProxyObserver alloc] |
| initWithModel:model_ |
| mediator:mediator]) { |
| DCHECK(controller_); |
| DCHECK(model_); |
| } |
| |
| FullscreenWebStateObserver::~FullscreenWebStateObserver() = default; |
| |
| void FullscreenWebStateObserver::SetWebState(web::WebState* web_state) { |
| if (web_state_ == web_state) |
| return; |
| if (web_state_) |
| web_state_->RemoveObserver(this); |
| web_state_ = web_state; |
| if (web_state_) { |
| web_state_->AddObserver(this); |
| // The toolbar should be visible whenever the current tab changes. |
| model_->ResetForNavigation(); |
| } |
| mediator_->SetWebState(web_state); |
| // Update the scroll view replacement handler's proxy. |
| web_view_proxy_observer_.proxy = |
| web_state_ ? web_state_->GetWebViewProxy() : nil; |
| } |
| |
| void FullscreenWebStateObserver::WasShown(web::WebState* web_state) { |
| // Show the toolbars when a WebState is shown. |
| model_->ResetForNavigation(); |
| } |
| |
| void FullscreenWebStateObserver::DidFinishNavigation( |
| web::WebState* web_state, |
| web::NavigationContext* navigation_context) { |
| const GURL& navigation_url = navigation_context->GetUrl(); |
| bool url_changed = web::GURLByRemovingRefFromGURL(navigation_url) != |
| web::GURLByRemovingRefFromGURL(last_navigation_url_); |
| last_navigation_url_ = navigation_url; |
| |
| // Due to limitations in WKWebView's rendering, different MIME types must be |
| // inset using different techniques: |
| // - PDFs need to be inset using the scroll view's `contentInset` property or |
| // the floating page indicator is laid out incorrectly. |
| // - For normal pages, using `contentInset` breaks the layout of fixed- |
| // position DOM elements, so top padding must be accomplished by updating |
| // the WKWebView's frame. |
| bool is_pdf = web_state->GetContentsMimeType() == "application/pdf"; |
| id<CRWWebViewProxy> web_view_proxy = web_state->GetWebViewProxy(); |
| web_view_proxy.shouldUseViewContentInset = is_pdf; |
| |
| model_->SetResizesScrollView( |
| !is_pdf && !ios::provider::IsFullscreenSmoothScrollingSupported()); |
| |
| model_->SetScrollViewHeight(web_state->GetView().bounds.size.height); |
| |
| // Only reset the model for document-changing navigations or same-document |
| // navigations that update the visible URL. |
| if (!navigation_context->IsSameDocument() || url_changed) { |
| model_->ResetForNavigation(); |
| } |
| } |
| |
| void FullscreenWebStateObserver::DidStartLoading(web::WebState* web_state) { |
| // This is done to show the toolbar when navigating to a page that is |
| // considered as being in the SameDocument by the NavigationContext, so the |
| // toolbar isn't shown in the DidFinishNavigation. For example this is |
| // needed to load AMP pages from Google Search Result Page. |
| controller_->ExitFullscreen(); |
| } |
| |
| void FullscreenWebStateObserver::WebStateDestroyed(web::WebState* web_state) { |
| DCHECK_EQ(web_state, web_state_); |
| SetWebState(nullptr); |
| } |