Skip to content

Commit

Permalink
Support separate storages.
Browse files Browse the repository at this point in the history
john-preston committed Apr 25, 2024
1 parent 7c346c6 commit 81f15a7
Showing 8 changed files with 132 additions and 11 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ get_filename_component(src_loc . REALPATH)

nice_target_sources(lib_webview ${src_loc}
PRIVATE
webview/webview_common.h
webview/webview_data_stream.h
webview/webview_data_stream_memory.cpp
webview/webview_data_stream_memory.h
15 changes: 15 additions & 0 deletions webview/platform/linux/webview_linux.cpp
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
//
#include "webview/platform/linux/webview_linux.h"

#include "base/random.h"
#include "webview/platform/linux/webview_linux_webkitgtk.h"

namespace Webview {
@@ -22,8 +23,22 @@ bool NavigateToDataSupported() {
return false;
}

bool SeparateStorageIdSupported() {
return true;
}

std::unique_ptr<Interface> CreateInstance(Config config) {
return WebKitGTK::CreateInstance(std::move(config));
}

std::string GenerateStorageToken() {
constexpr auto kSize = 16;
auto result = std::string(kSize, ' ');
base::RandomFill(result.data(), result.size());
return result;
}

void ClearStorageDataByToken(const std::string &token) {
}

} // namespace Webview
51 changes: 51 additions & 0 deletions webview/platform/mac/webview_mac.mm
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@
constexpr auto kDataUrlScheme = std::string_view("desktop-app-resource");
constexpr auto kFullDomain = std::string_view("desktop-app-resource://domain/");
constexpr auto kPartsCacheLimit = 32 * 1024 * 1024;
constexpr auto kUuidSize = 16;

[[nodiscard]] NSString *stdToNS(std::string_view value) {
return [[NSString alloc]
@@ -301,6 +302,23 @@ void taskDone(

};

[[nodiscard]] NSUUID *UuidFromToken(const std::string &token) {
const auto bytes = reinterpret_cast<const unsigned char*>(token.data());
return (token.size() == kUuidSize)
? [[NSUUID alloc] initWithUUIDBytes:bytes]
: nil;
}

[[nodiscard]] std::string UuidToToken(NSUUID *uuid) {
if (!uuid) {
return std::string();
}
auto result = std::string(kUuidSize, ' ');
const auto bytes = reinterpret_cast<unsigned char*>(result.data());
[uuid getUUIDBytes:bytes];
return result;
}

Instance::Instance(Config config) {
const auto weak = base::make_weak(this);
const auto handleDataRequest = [=](id<WKURLSchemeTask> task, bool started) {
@@ -316,6 +334,13 @@ void taskDone(
_handler = [[Handler alloc] initWithMessageHandler:config.messageHandler navigationStartHandler:config.navigationStartHandler navigationDoneHandler:config.navigationDoneHandler dialogHandler:config.dialogHandler dataRequested:handleDataRequest];
_dataRequestHandler = std::move(config.dataRequestHandler);
[configuration setURLSchemeHandler:_handler forURLScheme:stdToNS(kDataUrlScheme)];
if (@available(macOS 14, *)) {
if (config.userDataToken != LegacyStorageIdToken().toStdString()) {
NSUUID *uuid = UuidFromToken(config.userDataToken);
[configuration setWebsiteDataStore:[WKWebsiteDataStore dataStoreForIdentifier:uuid]];
[uuid release];
}
}
_webview = [[WKWebView alloc] initWithFrame:NSZeroRect configuration:configuration];
if (@available(macOS 13.3, *)) {
_webview.inspectable = config.debug ? YES : NO;
@@ -698,11 +723,37 @@ bool NavigateToDataSupported() {
return true;
}

bool SeparateStorageIdSupported() {
return true;
}

std::unique_ptr<Interface> CreateInstance(Config config) {
if (!Supported()) {
return nullptr;
}
return std::make_unique<Instance>(std::move(config));
}

std::string GenerateStorageToken() {
return UuidToToken([NSUUID UUID]);
}

void ClearStorageDataByToken(const std::string &token) {
if (@available(macOS 14, *)) {
if (!token.empty() && token != LegacyStorageIdToken().toStdString()) {
if (NSUUID *uuid = UuidFromToken(token)) {
// removeDataStoreForIdentifier crashes without that (if not created first).
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
[configuration setWebsiteDataStore:[WKWebsiteDataStore dataStoreForIdentifier:uuid]];
[configuration release];

[WKWebsiteDataStore
removeDataStoreForIdentifier:uuid
completionHandler:^(NSError *error) {}];
[uuid release];
}
}
}
}

} // namespace Webview
15 changes: 15 additions & 0 deletions webview/platform/win/webview_win.cpp
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
//
#include "webview/platform/win/webview_win.h"

#include "base/random.h"
#include "base/platform/base_platform_info.h"
#include "webview/platform/win/webview_windows_edge_chromium.h"
#include "webview/platform/win/webview_windows_edge_html.h"
@@ -36,6 +37,10 @@ bool NavigateToDataSupported() {
return EdgeChromium::Supported();
}

bool SeparateStorageIdSupported() {
return EdgeChromium::Supported();
}

std::unique_ptr<Interface> CreateInstance(Config config) {
if (!Platform::IsWindows8Point1OrGreater()) {
return nullptr;
@@ -46,4 +51,14 @@ std::unique_ptr<Interface> CreateInstance(Config config) {
return EdgeHtml::CreateInstance(config);
}

std::string GenerateStorageToken() {
constexpr auto kSize = 16;
auto result = std::string(kSize, ' ');
base::RandomFill(result.data(), result.size());
return result;
}

void ClearStorageDataByToken(const std::string &token) {
}

} // namespace Webview
39 changes: 39 additions & 0 deletions webview/webview_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//
#pragma once

#include "base/basic_types.h"

#include <QByteArray>
#include <QString>
#include <QColor>

namespace Webview {

struct StorageId {
QString path;
QByteArray token;

explicit operator bool() const {
return !path.isEmpty() && !token.isEmpty();
}
};

[[nodiscard]] inline QByteArray LegacyStorageIdToken() {
return "<legacy>"_q;
}

struct ThemeParams {
QColor opaqueBg;
QColor scrollBg;
QColor scrollBgOver;
QColor scrollBarBg;
QColor scrollBarBgOver;
QByteArray json;
};

} // namespace Webview
3 changes: 2 additions & 1 deletion webview/webview_embed.cpp
Original file line number Diff line number Diff line change
@@ -99,7 +99,8 @@ bool Window::createWebView(QWidget *parent, const WindowConfig &config) {
.navigationDoneHandler = navigationDoneHandler(),
.dialogHandler = dialogHandler(),
.dataRequestHandler = dataRequestHandler(),
.userDataPath = config.userDataPath.toStdString(),
.userDataPath = config.storageId.path.toStdString(),
.userDataToken = config.storageId.token.toStdString(),
.debug = OptionWebviewDebugEnabled.value(),
});
}
3 changes: 2 additions & 1 deletion webview/webview_embed.h
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@

#include "base/unique_qptr.h"
#include "base/basic_types.h"
#include "webview/webview_common.h"

#include <rpl/lifetime.h>
#include <QColor>
@@ -29,7 +30,7 @@ enum class DataResult;

struct WindowConfig {
QColor opaqueBg;
QString userDataPath;
StorageId storageId;
};

class Window final {
16 changes: 7 additions & 9 deletions webview/webview_interface.h
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@
//
#pragma once

#include "webview/webview_common.h"

#include <memory>
#include <string>
#include <optional>
@@ -21,15 +23,6 @@ namespace Webview {

class DataStream;

struct ThemeParams {
QColor opaqueBg;
QColor scrollBg;
QColor scrollBgOver;
QColor scrollBarBg;
QColor scrollBarBgOver;
QByteArray json;
};

class Interface {
public:
virtual ~Interface() = default;
@@ -102,6 +95,7 @@ struct Config {
std::function<DialogResult(DialogArgs)> dialogHandler;
std::function<DataResult(DataRequest)> dataRequestHandler;
std::string userDataPath;
std::string userDataToken;
bool debug = false;
};

@@ -124,8 +118,12 @@ void ParseRangeHeaderFor(DataRequest &request, std::string_view header);
}
[[nodiscard]] bool SupportsEmbedAfterCreate();
[[nodiscard]] bool NavigateToDataSupported();
[[nodiscard]] bool SeparateStorageIdSupported();

// HWND on Windows, nullptr on macOS, GtkWindow on Linux.
[[nodiscard]] std::unique_ptr<Interface> CreateInstance(Config config);

[[nodiscard]] std::string GenerateStorageToken();
void ClearStorageDataByToken(const std::string &token);

} // namespace Webview

0 comments on commit 81f15a7

Please sign in to comment.