#ifndef CONTENT_PUBLIC_BROWSER_WEB_UI_H_
#define CONTENT_PUBLIC_BROWSER_WEB_UI_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/strings/string_piece.h"
#include "base/values.h"
#include "content/common/content_export.h"
#include "ui/base/page_transition_types.h"
class GURL;
namespace content {
class RenderFrameHost;
class WebContents;
class WebUIController;
class WebUIMessageHandler;
class CONTENT_EXPORT WebUI {
public:
typedef const void* TypeID;
static const TypeID kNoWebUI;
static std::u16string GetJavascriptCall(
base::StringPiece function_name,
base::span<const base::ValueView> arg_list);
virtual ~WebUI() {}
virtual WebContents* GetWebContents() = 0;
virtual WebUIController* GetController() = 0;
virtual void SetController(std::unique_ptr<WebUIController> controller) = 0;
virtual RenderFrameHost* GetRenderFrameHost() = 0;
virtual float GetDeviceScaleFactor() = 0;
virtual const std::u16string& GetOverriddenTitle() = 0;
virtual void OverrideTitle(const std::u16string& title) = 0;
virtual int GetBindings() = 0;
virtual void SetBindings(int bindings) = 0;
virtual const std::vector<std::string>& GetRequestableSchemes() = 0;
virtual void AddRequestableScheme(const char* scheme) = 0;
virtual void AddMessageHandler(
std::unique_ptr<WebUIMessageHandler> handler) = 0;
using MessageCallback =
base::RepeatingCallback<void(const base::Value::List&)>;
virtual void RegisterMessageCallback(base::StringPiece message,
MessageCallback callback) = 0;
template <typename... Args>
void RegisterHandlerCallback(
base::StringPiece message,
base::RepeatingCallback<void(Args...)> callback) {
RegisterMessageCallback(
message, base::BindRepeating(
&Call<std::index_sequence_for<Args...>, Args...>::Impl,
callback, message));
}
virtual void ProcessWebUIMessage(const GURL& source_url,
const std::string& message,
base::Value::List args) = 0;
virtual bool CanCallJavascript() = 0;
virtual void CallJavascriptFunctionUnsafe(
base::StringPiece function_name) = 0;
virtual void CallJavascriptFunctionUnsafe(
base::StringPiece function_name,
base::span<const base::ValueView> args) = 0;
template <typename... Args>
void CallJavascriptFunctionUnsafe(base::StringPiece function_name,
const base::ValueView arg1,
const Args&... arg) {
base::ValueView args[] = {arg1, arg...};
CallJavascriptFunctionUnsafe(function_name, args);
}
virtual std::vector<std::unique_ptr<WebUIMessageHandler>>*
GetHandlersForTesting() = 0;
private:
template <typename T>
static T GetValue(const base::Value& value);
template <typename Is, typename... Args>
struct Call;
template <size_t... Is, typename... Args>
struct Call<std::index_sequence<Is...>, Args...> {
static void Impl(base::RepeatingCallback<void(Args...)> callback,
base::StringPiece message,
const base::Value::List& list) {
CHECK_EQ(list.size(), sizeof...(Args)) << message;
callback.Run(GetValue<Args>(list[Is])...);
}
};
};
template <>
inline bool WebUI::GetValue<bool>(const base::Value& value) {
return value.GetBool();
}
template <>
inline int WebUI::GetValue<int>(const base::Value& value) {
return value.GetInt();
}
template <>
inline const std::string& WebUI::GetValue<const std::string&>(
const base::Value& value) {
return value.GetString();
}
template <>
inline const base::Value::Dict& WebUI::GetValue<const base::Value::Dict&>(
const base::Value& value) {
return value.GetDict();
}
template <>
inline const base::Value::List& WebUI::GetValue<const base::Value::List&>(
const base::Value& value) {
return value.GetList();
}
}
#endif