blob: ce0297717297d1666c054d45fb1bda28dc3be7b7 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/tabs/tab_helper_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
#include "base/feature_list.h"
#import "components/favicon/ios/web_favicon_driver.h"
#include "components/history/core/browser/top_sites.h"
#import "components/history/ios/browser/web_state_top_sites_observer.h"
#include "components/keyed_service/core/service_access_type.h"
#import "components/language/ios/browser/ios_language_detection_tab_helper.h"
#import "ios/chrome/browser/autofill/autofill_tab_helper.h"
#import "ios/chrome/browser/autofill/form_suggestion_tab_helper.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/favicon/favicon_service_factory.h"
#import "ios/chrome/browser/find_in_page/find_tab_helper.h"
#include "ios/chrome/browser/history/history_service_factory.h"
#include "ios/chrome/browser/history/history_tab_helper.h"
#include "ios/chrome/browser/history/top_sites_factory.h"
#import "ios/chrome/browser/infobars/infobar_manager_impl.h"
#include "ios/chrome/browser/itunes_urls/itunes_urls_flag.h"
#import "ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper.h"
#import "ios/chrome/browser/metrics/ukm_url_recorder.h"
#import "ios/chrome/browser/passwords/password_tab_helper.h"
#include "ios/chrome/browser/reading_list/reading_list_model_factory.h"
#import "ios/chrome/browser/reading_list/reading_list_web_state_observer.h"
#import "ios/chrome/browser/search_engines/feature_flags.h"
#import "ios/chrome/browser/search_engines/search_engine_tab_helper.h"
#import "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h"
#import "ios/chrome/browser/snapshots/snapshot_tab_helper.h"
#include "ios/chrome/browser/ssl/captive_portal_features.h"
#import "ios/chrome/browser/ssl/captive_portal_metrics_tab_helper.h"
#import "ios/chrome/browser/ssl/insecure_input_tab_helper.h"
#import "ios/chrome/browser/ssl/ios_security_state_tab_helper.h"
#import "ios/chrome/browser/store_kit/store_kit_tab_helper.h"
#import "ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.h"
#import "ios/chrome/browser/tabs/legacy_tab_helper.h"
#import "ios/chrome/browser/tabs/tab.h"
#import "ios/chrome/browser/translate/chrome_ios_translate_client.h"
#import "ios/chrome/browser/ui/ui_feature_flags.h"
#import "ios/chrome/browser/voice/voice_search_navigations_tab_helper.h"
#import "ios/chrome/browser/web/blocked_popup_tab_helper.h"
#import "ios/chrome/browser/web/features.h"
#import "ios/chrome/browser/web/font_size_tab_helper.h"
#import "ios/chrome/browser/web/image_fetch_tab_helper.h"
#import "ios/chrome/browser/web/java_script_console/java_script_console_tab_helper.h"
#import "ios/chrome/browser/web/load_timing_tab_helper.h"
#import "ios/chrome/browser/web/network_activity_indicator_tab_helper.h"
#import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
#import "ios/chrome/browser/web/tab_id_tab_helper.h"
#import "ios/public/provider/chrome/browser/chrome_browser_provider.h"
#import "ios/web/public/web_state/web_state.h"
void AttachTabHelpers(web::WebState* web_state, bool for_prerender) {
// Tab's WebStateObserver callbacks expect VoiceSearchNavigationTabHelper's
// callbacks to be executed first so that state stays in sync.
// TODO(crbug.com/778416): Remove this ordering requirement by relying solely
// on the tab helper without going through Tab.
VoiceSearchNavigationTabHelper::CreateForWebState(web_state);
// TabIdHelper sets up the tab ID which is required for the creation of the
// Tab by LegacyTabHelper.
TabIdTabHelper::CreateForWebState(web_state);
LegacyTabHelper::CreateForWebState(web_state);
Tab* tab = LegacyTabHelper::GetTabForWebState(web_state);
DCHECK(tab);
ios::ChromeBrowserState* browser_state =
ios::ChromeBrowserState::FromBrowserState(web_state->GetBrowserState());
// IOSChromeSessionTabHelper sets up the session ID used by other helpers,
// so it needs to be created before them.
IOSChromeSessionTabHelper::CreateForWebState(web_state);
NSString* tab_id = TabIdTabHelper::FromWebState(web_state)->tab_id();
NetworkActivityIndicatorTabHelper::CreateForWebState(web_state, tab_id);
IOSChromeSyncedTabDelegate::CreateForWebState(web_state);
InfoBarManagerImpl::CreateForWebState(web_state);
IOSSecurityStateTabHelper::CreateForWebState(web_state);
BlockedPopupTabHelper::CreateForWebState(web_state);
FindTabHelper::CreateForWebState(web_state);
StoreKitTabHelper::CreateForWebState(web_state);
JavaScriptConsoleTabHelper::CreateForWebState(tab.webState);
if (base::FeatureList::IsEnabled(kITunesUrlsStoreKitHandling)) {
ITunesUrlsHandlerTabHelper::CreateForWebState(web_state);
}
HistoryTabHelper::CreateForWebState(web_state);
LoadTimingTabHelper::CreateForWebState(web_state);
if (base::FeatureList::IsEnabled(kCaptivePortalMetrics)) {
CaptivePortalMetricsTabHelper::CreateForWebState(web_state);
}
if (base::FeatureList::IsEnabled(web::kWebPageTextAccessibility)) {
FontSizeTabHelper::CreateForWebState(web_state);
}
if (base::FeatureList::IsEnabled(kCopyImage)) {
ImageFetchTabHelper::CreateForWebState(web_state);
}
ReadingListModel* model =
ReadingListModelFactory::GetForBrowserState(browser_state);
ReadingListWebStateObserver::CreateForWebState(web_state, model);
ios::ChromeBrowserState* original_browser_state =
browser_state->GetOriginalChromeBrowserState();
favicon::WebFaviconDriver::CreateForWebState(
web_state,
ios::FaviconServiceFactory::GetForBrowserState(
original_browser_state, ServiceAccessType::IMPLICIT_ACCESS));
history::WebStateTopSitesObserver::CreateForWebState(
web_state,
ios::TopSitesFactory::GetForBrowserState(original_browser_state).get());
PasswordTabHelper::CreateForWebState(web_state);
AutofillTabHelper::CreateForWebState(web_state, nullptr);
// Depends on favicon::WebFaviconDriver, must be created after it.
if (base::FeatureList::IsEnabled(kCustomSearchEngines)) {
SearchEngineTabHelper::CreateForWebState(web_state);
}
FormSuggestionTabHelper::CreateForWebState(web_state, @[
PasswordTabHelper::FromWebState(web_state)->GetSuggestionProvider(),
AutofillTabHelper::FromWebState(web_state)->GetSuggestionProvider(),
]);
InsecureInputTabHelper::CreateForWebState(web_state);
ukm::InitializeSourceUrlRecorderForWebState(web_state);
// TODO(crbug.com/794115): pre-rendered WebState have lots of unnecessary
// tab helpers for historical reasons. For the moment, AttachTabHelpers
// allows to inhibit the creation of some of them. Once PreloadController
// has been refactored to only create the necessary tab helpers, this
// condition can be removed.
if (!for_prerender) {
SnapshotTabHelper::CreateForWebState(web_state, tab_id);
PagePlaceholderTabHelper::CreateForWebState(web_state);
}
// Allow the embedder to attach tab helpers.
ios::GetChromeBrowserProvider()->AttachTabHelpers(web_state, tab);
}