mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-10-09 16:26:44 +00:00
chore: improve webview code style
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
|
||||
#if defined(WEBVIEW_PLATFORM_WINDOWS) && defined(WEBVIEW_EDGE)
|
||||
|
||||
#include "ui/modmanui.h"
|
||||
#include "Web/UiAssets.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <format>
|
||||
@@ -18,25 +18,33 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr auto MOD_MAN_URL_PREFIX = "modman://localhost/";
|
||||
|
||||
std::unordered_map<std::string, UiFile> assetLookup;
|
||||
|
||||
std::string wide_string_to_string(const std::wstring& wide_string)
|
||||
std::string WideStringToString(const std::wstring& wideString)
|
||||
{
|
||||
if (wide_string.empty())
|
||||
{
|
||||
if (wideString.empty())
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, wide_string.data(), (int)wide_string.size(), nullptr, 0, nullptr, nullptr);
|
||||
if (size_needed <= 0)
|
||||
{
|
||||
throw std::runtime_error("WideCharToMultiByte() failed: " + std::to_string(size_needed));
|
||||
}
|
||||
const auto sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, wideString.data(), static_cast<int>(wideString.size()), nullptr, 0, nullptr, nullptr);
|
||||
if (sizeNeeded <= 0)
|
||||
throw std::runtime_error(std::format("WideCharToMultiByte() failed: {}", sizeNeeded));
|
||||
|
||||
std::string result(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wide_string.data(), (int)wide_string.size(), result.data(), size_needed, nullptr, nullptr);
|
||||
std::string result(sizeNeeded, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wideString.data(), static_cast<int>(wideString.size()), result.data(), sizeNeeded, nullptr, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring StringToWideString(const std::string& string)
|
||||
{
|
||||
if (string.empty())
|
||||
return L"";
|
||||
|
||||
const auto sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, string.data(), static_cast<int>(string.size()), nullptr, 0);
|
||||
if (sizeNeeded <= 0)
|
||||
throw std::runtime_error(std::format("MultiByteToWideChar() failed: {}", sizeNeeded));
|
||||
|
||||
std::wstring result(sizeNeeded, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, string.data(), static_cast<int>(string.size()), result.data(), sizeNeeded);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -45,22 +53,89 @@ namespace
|
||||
std::wstringstream wss;
|
||||
|
||||
wss << std::format(L"Content-Length: {}\n", contentLength);
|
||||
|
||||
if (assetName.ends_with(".html"))
|
||||
{
|
||||
wss << L"Content-Type: text/html\n";
|
||||
}
|
||||
else if (assetName.ends_with(".js"))
|
||||
{
|
||||
wss << L"Content-Type: text/javascript\n";
|
||||
}
|
||||
else if (assetName.ends_with(".css"))
|
||||
{
|
||||
wss << L"Content-Type: text/css\n";
|
||||
}
|
||||
wss << L"Content-Type: " << StringToWideString(GetMimeTypeForFileName(assetName));
|
||||
|
||||
return wss.str();
|
||||
}
|
||||
|
||||
HRESULT HandleResourceRequested(ICoreWebView2_22* core22, IUnknown* args)
|
||||
{
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2WebResourceRequestedEventArgs2> webResourceRequestArgs;
|
||||
if (SUCCEEDED(args->QueryInterface(IID_PPV_ARGS(&webResourceRequestArgs))))
|
||||
{
|
||||
COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS requestSourceKind = COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_ALL;
|
||||
if (!SUCCEEDED(webResourceRequestArgs->get_RequestedSourceKind(&requestSourceKind)))
|
||||
{
|
||||
std::cerr << "Failed to get requested source kind\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2WebResourceRequest> request;
|
||||
if (!SUCCEEDED(webResourceRequestArgs->get_Request(&request)))
|
||||
{
|
||||
std::cerr << "Failed to get request\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
LPWSTR wUri;
|
||||
if (!SUCCEEDED(request->get_Uri(&wUri)))
|
||||
{
|
||||
std::cerr << "Failed to get uri\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2Environment> environment;
|
||||
if (!SUCCEEDED(core22->get_Environment(&environment)))
|
||||
{
|
||||
std::cerr << "Failed to get environment\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2WebResourceResponse> response;
|
||||
|
||||
const auto uri = WideStringToString(wUri);
|
||||
bool fileFound = false;
|
||||
if (uri.starts_with(edge::URL_PREFIX))
|
||||
{
|
||||
const auto asset = uri.substr(std::char_traits<char>::length(edge::URL_PREFIX) - 1);
|
||||
|
||||
const auto foundUiFile = assetLookup.find(asset);
|
||||
if (foundUiFile != assetLookup.end())
|
||||
{
|
||||
const Microsoft::WRL::ComPtr<IStream> responseStream =
|
||||
SHCreateMemStream(static_cast<const BYTE*>(foundUiFile->second.data), foundUiFile->second.dataSize);
|
||||
|
||||
const auto headers = HeadersForAssetName(asset, foundUiFile->second.dataSize);
|
||||
if (!SUCCEEDED(environment->CreateWebResourceResponse(responseStream.Get(), 200, L"OK", headers.data(), &response)))
|
||||
{
|
||||
std::cerr << "Failed to create web resource\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
fileFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileFound)
|
||||
{
|
||||
if (!SUCCEEDED(environment->CreateWebResourceResponse(nullptr, 404, L"Not found", L"", &response)))
|
||||
{
|
||||
std::cerr << "Failed to create web resource\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(webResourceRequestArgs->put_Response(response.Get())))
|
||||
{
|
||||
std::cerr << "Failed to put response\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace edge
|
||||
@@ -92,74 +167,16 @@ namespace edge
|
||||
}
|
||||
|
||||
EventRegistrationToken token;
|
||||
core->add_WebResourceRequested(Microsoft::WRL::Callback<ICoreWebView2WebResourceRequestedEventHandler>(
|
||||
[core22](ICoreWebView2* sender, IUnknown* args) -> HRESULT
|
||||
{
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2WebResourceRequestedEventArgs2> webResourceRequestArgs;
|
||||
if (SUCCEEDED(args->QueryInterface(IID_PPV_ARGS(&webResourceRequestArgs))))
|
||||
{
|
||||
COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS requestSourceKind =
|
||||
COREWEBVIEW2_WEB_RESOURCE_REQUEST_SOURCE_KINDS_ALL;
|
||||
if (!SUCCEEDED(webResourceRequestArgs->get_RequestedSourceKind(&requestSourceKind)))
|
||||
{
|
||||
std::cerr << "Failed to get requested source kind\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2WebResourceRequest> request;
|
||||
if (!SUCCEEDED(webResourceRequestArgs->get_Request(&request)))
|
||||
{
|
||||
std::cerr << "Failed to get request\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
LPWSTR wUri;
|
||||
if (!SUCCEEDED(request->get_Uri(&wUri)))
|
||||
{
|
||||
std::cerr << "Failed to get uri\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2Environment> environment;
|
||||
if (!SUCCEEDED(core22->get_Environment(&environment)))
|
||||
{
|
||||
std::cerr << "Failed to get environment\n";
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<ICoreWebView2WebResourceResponse> response;
|
||||
|
||||
const auto uri = wide_string_to_string(wUri);
|
||||
bool fileFound = false;
|
||||
if (uri.starts_with(MOD_MAN_URL_PREFIX))
|
||||
{
|
||||
const auto asset = uri.substr(std::char_traits<char>::length(MOD_MAN_URL_PREFIX));
|
||||
|
||||
const auto foundUiFile = assetLookup.find(asset);
|
||||
if (foundUiFile != assetLookup.end())
|
||||
{
|
||||
Microsoft::WRL::ComPtr<IStream> response_stream = SHCreateMemStream(
|
||||
static_cast<const BYTE*>(foundUiFile->second.data), foundUiFile->second.dataSize);
|
||||
|
||||
const auto headers = HeadersForAssetName(asset, foundUiFile->second.dataSize);
|
||||
environment->CreateWebResourceResponse(response_stream.Get(), 200, L"OK", headers.data(), &response);
|
||||
fileFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileFound)
|
||||
{
|
||||
environment->CreateWebResourceResponse(nullptr, 404, L"Not found", L"", &response);
|
||||
}
|
||||
|
||||
webResourceRequestArgs->put_Response(response.Get());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return S_FALSE;
|
||||
})
|
||||
.Get(),
|
||||
&token);
|
||||
if (!SUCCEEDED(core->add_WebResourceRequested(Microsoft::WRL::Callback<ICoreWebView2WebResourceRequestedEventHandler>(
|
||||
[core22](ICoreWebView2* sender, IUnknown* args) -> HRESULT
|
||||
{
|
||||
return HandleResourceRequested(core22.Get(), args);
|
||||
})
|
||||
.Get(),
|
||||
&token)))
|
||||
{
|
||||
std::cerr << "Failed to add resource requested filter\n";
|
||||
}
|
||||
}
|
||||
} // namespace edge
|
||||
|
||||
|
@@ -12,7 +12,9 @@
|
||||
|
||||
namespace edge
|
||||
{
|
||||
constexpr auto URL_PREFIX = "http://modman.local/";
|
||||
|
||||
void InstallCustomProtocolHandler(webview::webview& wv);
|
||||
}
|
||||
} // namespace edge
|
||||
|
||||
#endif
|
||||
|
@@ -20,43 +20,17 @@ namespace
|
||||
{
|
||||
std::unordered_map<std::string, UiFile> assetLookup;
|
||||
|
||||
const char* ContentTypeForAssetName(const std::string& assetName)
|
||||
{
|
||||
const char* mimeType;
|
||||
|
||||
if (assetName.ends_with(".html"))
|
||||
{
|
||||
mimeType = "text/html";
|
||||
}
|
||||
else if (assetName.ends_with(".js"))
|
||||
{
|
||||
mimeType = "text/javascript";
|
||||
}
|
||||
else if (assetName.ends_with(".css"))
|
||||
{
|
||||
mimeType = "text/css";
|
||||
}
|
||||
else
|
||||
{
|
||||
mimeType = "application/octet-stream";
|
||||
}
|
||||
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
void ModManUriSchemeRequestCb(WebKitURISchemeRequest* request, gpointer user_data)
|
||||
{
|
||||
const gchar* asset = webkit_uri_scheme_request_get_path(request);
|
||||
|
||||
std::cout << std::format("Modman request: {}\n", asset);
|
||||
|
||||
const auto foundUiFile = assetLookup.find(asset);
|
||||
if (foundUiFile != assetLookup.end())
|
||||
{
|
||||
gsize stream_length = foundUiFile->second.dataSize;
|
||||
GInputStream* stream = g_memory_input_stream_new_from_data(foundUiFile->second.data, foundUiFile->second.dataSize, nullptr);
|
||||
|
||||
webkit_uri_scheme_request_finish(request, stream, stream_length, ContentTypeForAssetName(foundUiFile->second.filename));
|
||||
webkit_uri_scheme_request_finish(request, stream, stream_length, GetMimeTypeForFileName(foundUiFile->second.filename));
|
||||
g_object_unref(stream);
|
||||
}
|
||||
else
|
||||
@@ -67,24 +41,6 @@ namespace
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void OnResourceLoadStarted(WebKitWebView* self, WebKitWebResource* resource, WebKitURIRequest* request, gpointer user_data)
|
||||
{
|
||||
std::cout << webkit_uri_request_get_http_method(request) << " " << webkit_uri_request_get_uri(request) << "\n";
|
||||
|
||||
std::string uri(webkit_uri_request_get_uri(request));
|
||||
if (uri.starts_with("http://"))
|
||||
{
|
||||
uri = std::format("modman://{}", uri.substr(7));
|
||||
}
|
||||
else if (uri.starts_with("https://"))
|
||||
{
|
||||
uri = std::format("modman://{}", uri.substr(8));
|
||||
}
|
||||
|
||||
std::cout << std::format("Setting uri: {}\n", uri);
|
||||
webkit_uri_request_set_uri(request, uri.c_str());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace gtk
|
||||
@@ -97,8 +53,6 @@ namespace gtk
|
||||
|
||||
assetLookup = BuildUiFileLookup();
|
||||
|
||||
g_signal_connect(webView, "resource-load-started", G_CALLBACK(OnResourceLoadStarted), NULL);
|
||||
|
||||
webkit_web_context_register_uri_scheme(context, "modman", ModManUriSchemeRequestCb, NULL, nullptr);
|
||||
}
|
||||
} // namespace gtk
|
||||
|
@@ -12,7 +12,9 @@
|
||||
|
||||
namespace gtk
|
||||
{
|
||||
constexpr auto URL_PREFIX = "modman://localhost/";
|
||||
|
||||
void InstallCustomProtocolHandler(webview::webview& wv);
|
||||
}
|
||||
} // namespace gtk
|
||||
|
||||
#endif
|
||||
|
@@ -13,3 +13,19 @@ std::unordered_map<std::string, UiFile> BuildUiFileLookup()
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* GetMimeTypeForFileName(const std::string& fileName)
|
||||
{
|
||||
const char* mimeType;
|
||||
|
||||
if (fileName.ends_with(".html"))
|
||||
mimeType = "text/html";
|
||||
else if (fileName.ends_with(".js"))
|
||||
mimeType = "text/javascript";
|
||||
else if (fileName.ends_with(".css"))
|
||||
mimeType = "text/css";
|
||||
else
|
||||
mimeType = "application/octet-stream";
|
||||
|
||||
return mimeType;
|
||||
}
|
||||
|
@@ -6,3 +6,4 @@
|
||||
#include <unordered_map>
|
||||
|
||||
std::unordered_map<std::string, UiFile> BuildUiFileLookup();
|
||||
const char* GetMimeTypeForFileName(const std::string& fileName);
|
||||
|
@@ -7,9 +7,12 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <format>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
#ifdef _WIN32
|
||||
int WINAPI WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*nCmdShow*/)
|
||||
{
|
||||
@@ -55,13 +58,12 @@ int main()
|
||||
|
||||
#if defined(WEBVIEW_PLATFORM_WINDOWS) && defined(WEBVIEW_EDGE)
|
||||
edge::InstallCustomProtocolHandler(w);
|
||||
#endif
|
||||
|
||||
#if defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)
|
||||
w.navigate(edge::URL_PREFIX + "index.html"s);
|
||||
#elif defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)
|
||||
gtk::InstallCustomProtocolHandler(w);
|
||||
w.navigate(gtk::URL_PREFIX + "index.html"s);
|
||||
#endif
|
||||
|
||||
w.navigate("modman://localhost/index.html");
|
||||
w.run();
|
||||
}
|
||||
catch (const webview::exception& e)
|
||||
|
Reference in New Issue
Block a user