// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_SEARCH_ENGINES_MODEL_SEARCH_ENGINE_TAB_HELPER_H_
#define IOS_CHROME_BROWSER_SEARCH_ENGINES_MODEL_SEARCH_ENGINE_TAB_HELPER_H_
#import "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "components/favicon/ios/web_favicon_driver.h"
#include "ios/web/public/web_state_observer.h"
#import "ios/web/public/web_state_user_data.h"
namespace web {
class WebState;
} // namespace web
// Creates TemplateURLs from attached WebState and adds them to
// TemplateURLService. To create a TemplateURL, 3 basic elements are needed:
// 1. A short name (e.g. "Google");
// 2. A keyword (e.g. "google.com");
// 3. A searchable URL (e.g. "https://google.com?name=a&q={searchTerms}").
//
// Both short name and keyword can be generated from navigation history. For
// searchable URL, there are 2 methods to create it:
// 1. If a OSDD(Open Search Description Document) <link> is found in page,
// use TemplateURLFetcher to download the XML file, parse it and get the
// searchable URL;
// 2. If a <form> is submitted in page, a searchable URL can be generated
// by analysing the <form>'s elements and concatenating "name" and
// "value" attributes of them.
//
// Both these 2 methods depends on injected JavaScript.
//
class SearchEngineTabHelper
: public web::WebStateObserver,
public web::WebStateUserData<SearchEngineTabHelper>,
public favicon::FaviconDriverObserver {
public:
SearchEngineTabHelper(const SearchEngineTabHelper&) = delete;
SearchEngineTabHelper& operator=(const SearchEngineTabHelper&) = delete;
~SearchEngineTabHelper() override;
// Saves the page `url` generated from a <form> submission to create the
// TemplateURL when the submission leads to a successful navigation.
void SetSearchableUrl(GURL url);
// Adds a TemplateURL by downloading and parsing the OSDD.
void AddTemplateURLByOSDD(const GURL& page_url, const GURL& osdd_url);
private:
friend class web::WebStateUserData<SearchEngineTabHelper>;
explicit SearchEngineTabHelper(web::WebState* web_state);
// Adds a TemplateURL by `searchable_url`.
void AddTemplateURLBySearchableURL(const GURL& searchable_url);
// WebStateObserver implementation.
void DidFinishNavigation(web::WebState* web_state,
web::NavigationContext* navigation_context) override;
void WebStateDestroyed(web::WebState* web_state) override;
// favicon::FaviconDriverObserver:
void OnFaviconUpdated(favicon::FaviconDriver* driver,
NotificationIconType notification_icon_type,
const GURL& icon_url,
bool icon_url_changed,
const gfx::Image& image) override;
// Manages observation relationship between `this` and WebFaviconDriver.
base::ScopedObservation<favicon::FaviconDriver,
favicon::FaviconDriverObserver>
favicon_driver_observation_{this};
// WebState this tab helper is attached to.
raw_ptr<web::WebState> web_state_ = nullptr;
// The searchable URL generated from <form> submission. This ivar is an empty
// GURL by default. If a web page has a searchable <form>, a searchable URL is
// generated by JavaScript when the <form> is submitted, and stored in this
// ivar. When the navigation triggered by the <form> submission finishes
// successfully, this ivar will be used to add a new TemplateURL and then it
// will be set to empty GURL again.
GURL searchable_url_;
WEB_STATE_USER_DATA_KEY_DECL();
};
#endif // IOS_CHROME_BROWSER_SEARCH_ENGINES_MODEL_SEARCH_ENGINE_TAB_HELPER_H_