bunite-core 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,116 @@
1
+ #pragma once
2
+
3
+ #include <algorithm>
4
+ #include <cctype>
5
+ #include <cstring>
6
+ #include <string>
7
+
8
+ class BuniteResponseFilter : public CefResponseFilter {
9
+ public:
10
+ explicit BuniteResponseFilter(std::string script)
11
+ : script_(std::move(script)) {}
12
+
13
+ bool InitFilter() override {
14
+ buffer_.clear();
15
+ output_offset_ = 0;
16
+ injected_ = false;
17
+ return true;
18
+ }
19
+
20
+ FilterStatus Filter(
21
+ void* data_in,
22
+ size_t data_in_size,
23
+ size_t& data_in_read,
24
+ void* data_out,
25
+ size_t data_out_size,
26
+ size_t& data_out_written
27
+ ) override {
28
+ if (data_in_size > 0) {
29
+ buffer_.append(static_cast<const char*>(data_in), data_in_size);
30
+ data_in_read = data_in_size;
31
+ } else {
32
+ data_in_read = 0;
33
+ }
34
+
35
+ if (!injected_) {
36
+ tryInject();
37
+ if (!injected_ && data_in_size == 0 && !script_.empty() && output_offset_ == 0) {
38
+ buffer_.insert(0, "<script>\n" + escapeInlineScript(script_) + "\n</script>\n");
39
+ injected_ = true;
40
+ }
41
+ }
42
+
43
+ const size_t remaining = buffer_.size() - output_offset_;
44
+ const size_t copy_size = std::min(remaining, data_out_size);
45
+ if (copy_size > 0) {
46
+ std::memcpy(data_out, buffer_.data() + output_offset_, copy_size);
47
+ output_offset_ += copy_size;
48
+ }
49
+ data_out_written = copy_size;
50
+
51
+ if (data_in_size == 0 && output_offset_ >= buffer_.size()) {
52
+ return RESPONSE_FILTER_DONE;
53
+ }
54
+ return RESPONSE_FILTER_NEED_MORE_DATA;
55
+ }
56
+
57
+ private:
58
+ static std::string lowercase(std::string value) {
59
+ std::transform(
60
+ value.begin(),
61
+ value.end(),
62
+ value.begin(),
63
+ [](unsigned char ch) { return static_cast<char>(std::tolower(ch)); }
64
+ );
65
+ return value;
66
+ }
67
+
68
+ static std::string escapeInlineScript(const std::string& script) {
69
+ std::string escaped = script;
70
+ std::string::size_type offset = 0;
71
+ while ((offset = escaped.find("</script", offset)) != std::string::npos) {
72
+ escaped.replace(offset, 8, "<\\/script");
73
+ offset += 9;
74
+ }
75
+ return escaped;
76
+ }
77
+
78
+ void tryInject() {
79
+ if (injected_ || script_.empty()) {
80
+ return;
81
+ }
82
+
83
+ const std::string lowered = lowercase(buffer_);
84
+ std::string tag = "<script>\n" + escapeInlineScript(script_) + "\n</script>\n";
85
+
86
+ auto inject_after = [&](const std::string& token) -> bool {
87
+ const auto start = lowered.find(token);
88
+ if (start == std::string::npos) {
89
+ return false;
90
+ }
91
+ const auto end = buffer_.find('>', start);
92
+ if (end == std::string::npos) {
93
+ return false;
94
+ }
95
+ buffer_.insert(end + 1, tag);
96
+ injected_ = true;
97
+ return true;
98
+ };
99
+
100
+ if (inject_after("<head") || inject_after("<html")) {
101
+ return;
102
+ }
103
+
104
+ if (buffer_.size() > 1024 && output_offset_ == 0) {
105
+ buffer_.insert(0, tag);
106
+ injected_ = true;
107
+ }
108
+ }
109
+
110
+ std::string script_;
111
+ std::string buffer_;
112
+ size_t output_offset_ = 0;
113
+ bool injected_ = false;
114
+
115
+ IMPLEMENT_REFCOUNTING(BuniteResponseFilter);
116
+ };
@@ -0,0 +1,119 @@
1
+ #pragma once
2
+
3
+ #include <stdbool.h>
4
+ #include <stdint.h>
5
+
6
+ #include "callbacks.h"
7
+
8
+ #if defined(_WIN32)
9
+ #define BUNITE_EXPORT __declspec(dllexport)
10
+ #else
11
+ #define BUNITE_EXPORT __attribute__((visibility("default")))
12
+ #endif
13
+
14
+ #ifdef __cplusplus
15
+ extern "C" {
16
+ #endif
17
+
18
+ BUNITE_EXPORT bool bunite_init(
19
+ const char* process_helper_path,
20
+ const char* cef_dir,
21
+ bool hide_console,
22
+ bool popup_blocking,
23
+ const char* chromium_flags_json
24
+ );
25
+ BUNITE_EXPORT void bunite_run_loop(void);
26
+ BUNITE_EXPORT void bunite_quit(void);
27
+ BUNITE_EXPORT void bunite_free_cstring(const char* value);
28
+ BUNITE_EXPORT void bunite_set_webview_event_handler(BuniteWebviewEventHandler handler);
29
+ BUNITE_EXPORT void bunite_set_window_event_handler(BuniteWindowEventHandler handler);
30
+
31
+ BUNITE_EXPORT void* bunite_window_create(
32
+ uint32_t window_id,
33
+ double x,
34
+ double y,
35
+ double width,
36
+ double height,
37
+ const char* title,
38
+ const char* title_bar_style,
39
+ bool transparent,
40
+ bool hidden,
41
+ bool minimized,
42
+ bool maximized
43
+ );
44
+ BUNITE_EXPORT void bunite_window_show(void* window_ptr);
45
+ BUNITE_EXPORT void bunite_window_close(void* window_ptr);
46
+ BUNITE_EXPORT void bunite_window_set_title(void* window_ptr, const char* title);
47
+ BUNITE_EXPORT void bunite_window_minimize(void* window_ptr);
48
+ BUNITE_EXPORT void bunite_window_unminimize(void* window_ptr);
49
+ BUNITE_EXPORT bool bunite_window_is_minimized(void* window_ptr);
50
+ BUNITE_EXPORT void bunite_window_maximize(void* window_ptr);
51
+ BUNITE_EXPORT void bunite_window_unmaximize(void* window_ptr);
52
+ BUNITE_EXPORT bool bunite_window_is_maximized(void* window_ptr);
53
+ BUNITE_EXPORT void bunite_window_set_frame(
54
+ void* window_ptr,
55
+ double x,
56
+ double y,
57
+ double width,
58
+ double height
59
+ );
60
+
61
+ BUNITE_EXPORT void* bunite_view_create(
62
+ uint32_t view_id,
63
+ void* window_ptr,
64
+ const char* url,
65
+ const char* html,
66
+ const char* preload,
67
+ const char* views_root,
68
+ const char* navigation_rules_json,
69
+ double x,
70
+ double y,
71
+ double width,
72
+ double height,
73
+ bool auto_resize,
74
+ bool sandbox
75
+ );
76
+ BUNITE_EXPORT void bunite_view_load_url(void* view_ptr, const char* url);
77
+ BUNITE_EXPORT void bunite_view_load_html(void* view_ptr, const char* html);
78
+ BUNITE_EXPORT void bunite_register_view_route(const char* path);
79
+ BUNITE_EXPORT void bunite_unregister_view_route(const char* path);
80
+ BUNITE_EXPORT void bunite_complete_route_request(uint32_t request_id, const char* html);
81
+ BUNITE_EXPORT void bunite_view_set_visible(void* view_ptr, bool visible);
82
+ BUNITE_EXPORT void bunite_view_set_bounds(
83
+ void* view_ptr,
84
+ double x,
85
+ double y,
86
+ double width,
87
+ double height
88
+ );
89
+ BUNITE_EXPORT void bunite_view_set_anchor(void* view_ptr, int mode, double inset);
90
+ BUNITE_EXPORT void bunite_view_go_back(void* view_ptr);
91
+ BUNITE_EXPORT void bunite_view_reload(void* view_ptr);
92
+ BUNITE_EXPORT void bunite_view_remove(void* view_ptr);
93
+ BUNITE_EXPORT void bunite_view_open_devtools(void* view_ptr);
94
+ BUNITE_EXPORT void bunite_view_close_devtools(void* view_ptr);
95
+ BUNITE_EXPORT void bunite_view_toggle_devtools(void* view_ptr);
96
+ BUNITE_EXPORT void bunite_complete_permission_request(uint32_t request_id, uint32_t state);
97
+ BUNITE_EXPORT int32_t bunite_show_message_box(
98
+ const char* type,
99
+ const char* title,
100
+ const char* message,
101
+ const char* detail,
102
+ const char* buttons,
103
+ int32_t default_id,
104
+ int32_t cancel_id
105
+ );
106
+ BUNITE_EXPORT uint32_t bunite_show_browser_message_box(
107
+ const char* type,
108
+ const char* title,
109
+ const char* message,
110
+ const char* detail,
111
+ const char* buttons,
112
+ int32_t default_id,
113
+ int32_t cancel_id
114
+ );
115
+ BUNITE_EXPORT void bunite_cancel_browser_message_box(uint32_t request_id);
116
+
117
+ #ifdef __cplusplus
118
+ }
119
+ #endif
@@ -0,0 +1,89 @@
1
+ #pragma once
2
+
3
+ #include <cstdint>
4
+ #include <map>
5
+ #include <mutex>
6
+ #include <optional>
7
+ #include <set>
8
+ #include <string>
9
+
10
+ namespace bunite {
11
+
12
+ class WebviewContentStorage {
13
+ public:
14
+ static WebviewContentStorage& instance() {
15
+ static WebviewContentStorage storage;
16
+ return storage;
17
+ }
18
+
19
+ void set(uint32_t webview_id, std::string content) {
20
+ std::lock_guard<std::mutex> lock(mutex_);
21
+ content_[webview_id] = std::move(content);
22
+ }
23
+
24
+ std::string get(uint32_t webview_id) const {
25
+ std::lock_guard<std::mutex> lock(mutex_);
26
+ const auto it = content_.find(webview_id);
27
+ return it == content_.end() ? std::string{} : it->second;
28
+ }
29
+
30
+ void remove(uint32_t webview_id) {
31
+ std::lock_guard<std::mutex> lock(mutex_);
32
+ content_.erase(webview_id);
33
+ }
34
+
35
+ private:
36
+ WebviewContentStorage() = default;
37
+
38
+ mutable std::mutex mutex_;
39
+ std::map<uint32_t, std::string> content_;
40
+ };
41
+
42
+ // Tracks which views:// paths have registered dynamic handlers on the Bun side.
43
+ // The actual handler function lives in JS; this only stores the set of registered paths
44
+ // and completed route responses.
45
+ class ViewsRouteStorage {
46
+ public:
47
+ static ViewsRouteStorage& instance() {
48
+ static ViewsRouteStorage storage;
49
+ return storage;
50
+ }
51
+
52
+ void registerRoute(const std::string& path) {
53
+ std::lock_guard<std::mutex> lock(mutex_);
54
+ registered_.insert(path);
55
+ }
56
+
57
+ void unregisterRoute(const std::string& path) {
58
+ std::lock_guard<std::mutex> lock(mutex_);
59
+ registered_.erase(path);
60
+ }
61
+
62
+ bool hasRoute(const std::string& path) const {
63
+ std::lock_guard<std::mutex> lock(mutex_);
64
+ return registered_.count(path) > 0;
65
+ }
66
+
67
+ void setResponse(uint32_t request_id, std::string content) {
68
+ std::lock_guard<std::mutex> lock(mutex_);
69
+ responses_[request_id] = std::move(content);
70
+ }
71
+
72
+ std::optional<std::string> takeResponse(uint32_t request_id) {
73
+ std::lock_guard<std::mutex> lock(mutex_);
74
+ const auto it = responses_.find(request_id);
75
+ if (it == responses_.end()) return std::nullopt;
76
+ auto result = std::move(it->second);
77
+ responses_.erase(it);
78
+ return result;
79
+ }
80
+
81
+ private:
82
+ ViewsRouteStorage() = default;
83
+
84
+ mutable std::mutex mutex_;
85
+ std::set<std::string> registered_;
86
+ std::map<uint32_t, std::string> responses_;
87
+ };
88
+
89
+ } // namespace bunite