Skip to content

Commit

Permalink
Merge pull request #101 from Adamcake/custom-js-api
Browse files Browse the repository at this point in the history
Custom js api
  • Loading branch information
Adamcake authored Dec 29, 2024
2 parents c8e621d + 5aeeb42 commit f42224a
Show file tree
Hide file tree
Showing 14 changed files with 195 additions and 28 deletions.
11 changes: 8 additions & 3 deletions src/browser.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ Browser::Window::Window(CefRefPtr<Browser::Client> client, Browser::Details deta
browser_count(0), client(client.get()), show_devtools(show_devtools), details(details), window(nullptr), browser_view(nullptr), browser(nullptr), pending_child(nullptr), pending_delete(false)
{
fmt::print("[B] Browser::Window constructor, this={}\n", reinterpret_cast<uintptr_t>(this));
this->Init(url);
CefRefPtr<CefDictionaryValue> dict = nullptr;
if (details.has_custom_js) {
dict = CefDictionaryValue::Create();
dict->SetString("customjs", details.custom_js);
}
this->Init(url, dict);
}

Browser::Window::Window(CefRefPtr<Browser::Client> client, Browser::Details details, bool show_devtools):
Expand All @@ -39,10 +44,10 @@ Browser::Window::Window(CefRefPtr<Browser::Client> client, Browser::Details deta
fmt::print("[B] Browser::Window popup constructor, this={}\n", reinterpret_cast<uintptr_t>(this));
}

void Browser::Window::Init(CefString url) {
void Browser::Window::Init(CefString url, CefRefPtr<CefDictionaryValue> extra_info) {
CefBrowserSettings browser_settings;
browser_settings.background_color = CefColorSetARGB(0, 0, 0, 0);
this->browser_view = CefBrowserView::CreateBrowserView(this, url, browser_settings, nullptr, nullptr, this);
this->browser_view = CefBrowserView::CreateBrowserView(this, url, browser_settings, extra_info, nullptr, this);
CefWindow::CreateTopLevelWindow(this);
}

Expand Down
2 changes: 1 addition & 1 deletion src/browser.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace Browser {
Window(CefRefPtr<Browser::Client> client, Details, bool);

/// Initialise with a browser_view. Should be called from a constructor, if at all.
void Init(CefString);
void Init(CefString, CefRefPtr<CefDictionaryValue>);

/// Refreshes this browser, ignoring cache. Can be called from any thread in the browser process.
virtual void Refresh() const;
Expand Down
18 changes: 17 additions & 1 deletion src/browser/app.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ static void* shm_file;
static size_t shm_length;
static bool shm_inited = false;

static bool set_launcher_ui = false;
static bool has_custom_js = false;
static CefString custom_js;

class ArrayBufferReleaseCallbackFree: public CefV8ArrayBufferReleaseCallback {
void ReleaseBuffer(void* buffer) override {
::free(buffer);
Expand Down Expand Up @@ -52,12 +56,24 @@ CefRefPtr<CefLoadHandler> Browser::App::GetLoadHandler() {

void Browser::App::OnBrowserCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefDictionaryValue> dict) {
fmt::print("[R] OnBrowserCreated for browser {}\n", browser->GetIdentifier());
if (dict) {
if (dict->HasKey("launcher")) set_launcher_ui = dict->GetBool("launcher");
if (dict->HasKey("customjs")) {
custom_js = dict->GetString("customjs");
has_custom_js = true;
}
}
}

void Browser::App::OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) {
const CefRefPtr<CefV8Value> global = context->GetGlobal();
global->SetValue("s", CefV8Value::CreateFunction("s", this), V8_PROPERTY_ATTRIBUTE_READONLY);
global->SetValue("close", CefV8Value::CreateUndefined(), V8_PROPERTY_ATTRIBUTE_READONLY);
if (set_launcher_ui) {
global->SetValue("s", CefV8Value::CreateFunction("s", this), V8_PROPERTY_ATTRIBUTE_READONLY);
}
if (has_custom_js) {
frame->ExecuteJavaScript(custom_js, CefString(), int());
}
}

void Browser::App::OnUncaughtException(
Expand Down
20 changes: 18 additions & 2 deletions src/browser/client.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ constexpr bool SHOW_DEVTOOLS = true;
constexpr bool SHOW_DEVTOOLS = false;
#endif

constexpr Browser::Details LAUNCHER_DETAILS = {
const Browser::Details LAUNCHER_DETAILS = {
.preferred_width = 800,
.preferred_height = 608,
.center_on_open = true,
Expand Down Expand Up @@ -386,16 +386,25 @@ bool Browser::Client::IPCHandleMessage(int fd) {
_bolt_ipc_receive(fd, url, header.url_length);
url[header.url_length] = '\0';

char* custom_js = nullptr;
if (header.has_custom_js) {
custom_js = new char[header.custom_js_length];
_bolt_ipc_receive(fd, custom_js, header.custom_js_length);
}

CefRefPtr<ActivePlugin> plugin = this->GetPluginFromFDAndID(client, header.plugin_id);
Browser::Details details {
.preferred_width = header.w,
.preferred_height = header.h,
.center_on_open = true,
.resizeable = true,
.frame = true,
.has_custom_js = true,
.custom_js = CefString(custom_js),
};
plugin->windows.push_back(new Browser::PluginWindow(this, details, url, plugin, fd, &this->send_lock, header.window_id, header.plugin_id, false));
delete[] url;
delete[] custom_js;
break;
}
case IPC_MSG_CREATEBROWSER_OSR: {
Expand All @@ -405,12 +414,19 @@ bool Browser::Client::IPCHandleMessage(int fd) {
_bolt_ipc_receive(fd, url, header.url_length);
url[header.url_length] = '\0';

char* custom_js = nullptr;
if (header.has_custom_js) {
custom_js = new char[header.custom_js_length];
_bolt_ipc_receive(fd, custom_js, header.custom_js_length);
}

CefRefPtr<ActivePlugin> plugin = this->GetPluginFromFDAndID(client, header.plugin_id);
if (plugin) {
CefRefPtr<Browser::WindowOSR> window = new Browser::WindowOSR(CefString((char*)url), header.w, header.h, fd, this, &this->send_lock, header.pid, header.window_id, header.plugin_id, plugin);
CefRefPtr<Browser::WindowOSR> window = new Browser::WindowOSR(CefString((char*)url), header.w, header.h, fd, this, &this->send_lock, header.pid, header.window_id, header.plugin_id, plugin, custom_js);
plugin->windows_osr.push_back(window);
}
delete[] url;
delete[] custom_js;
break;
}
case IPC_MSG_CLOSEBROWSER_EXTERNAL: {
Expand Down
2 changes: 2 additions & 0 deletions src/browser/common.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ namespace Browser {
bool resizeable;
bool frame;
bool is_devtools = false;
bool has_custom_js = false;
CefString custom_js;
};

struct InternalFile {
Expand Down
5 changes: 4 additions & 1 deletion src/browser/window_launcher.cxx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "client.hxx"
#include "window_launcher.hxx"
#include "include/cef_values.h"
#include "include/internal/cef_types.h"
#include "resource_handler.hxx"
#include "request.hxx"
Expand Down Expand Up @@ -135,7 +136,9 @@ Browser::Launcher::Launcher(
this->plugin_config_path.append("plugins.json");
#endif

this->Init(this->BuildURL());
CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
dict->SetBool("launcher", true);
this->Init(this->BuildURL(), dict);
}

CefRefPtr<CefRequestHandler> Browser::Launcher::GetRequestHandler() {
Expand Down
9 changes: 7 additions & 2 deletions src/browser/window_osr.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static void SendUpdateMsg(BoltSocketType fd, std::mutex* send_lock, uint64_t id,
send_lock->unlock();
}

Browser::WindowOSR::WindowOSR(CefString url, int width, int height, BoltSocketType client_fd, Browser::Client* main_client, std::mutex* send_lock, int pid, uint64_t window_id, uint64_t plugin_id, CefRefPtr<FileManager::Directory> file_manager):
Browser::WindowOSR::WindowOSR(CefString url, int width, int height, BoltSocketType client_fd, Browser::Client* main_client, std::mutex* send_lock, int pid, uint64_t window_id, uint64_t plugin_id, CefRefPtr<FileManager::Directory> file_manager, const char* custom_js):
PluginRequestHandler(IPC_MSG_OSRBROWSERMESSAGE, send_lock),
deleted(false), pending_delete(false), pending_devtools(false), client_fd(client_fd), width(width), height(height), browser(nullptr), window_id(window_id),
plugin_id(plugin_id), main_client(main_client), stored(nullptr), remote_has_remapped(false), remote_is_idle(true), file_manager(file_manager)
Expand Down Expand Up @@ -69,7 +69,12 @@ Browser::WindowOSR::WindowOSR(CefString url, int width, int height, BoltSocketTy
window_info.SetAsWindowless(0);
CefBrowserSettings browser_settings;
browser_settings.background_color = CefColorSetARGB(0, 0, 0, 0);
CefBrowserHost::CreateBrowser(window_info, this, CefString(url), browser_settings, nullptr, nullptr);
CefRefPtr<CefDictionaryValue> dict = nullptr;
if (custom_js) {
dict = CefDictionaryValue::Create();
dict->SetString("customjs", custom_js);
}
CefBrowserHost::CreateBrowser(window_info, this, CefString(url), browser_settings, dict, nullptr);
}

bool Browser::WindowOSR::IsDeleted() {
Expand Down
2 changes: 1 addition & 1 deletion src/browser/window_osr.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace Browser {
struct Client;

struct WindowOSR: public CefClient, CefLifeSpanHandler, CefRenderHandler, PluginRequestHandler {
WindowOSR(CefString url, int width, int height, BoltSocketType client_fd, Client* main_client, std::mutex* send_lock, int pid, uint64_t window_id, uint64_t plugin_id, CefRefPtr<FileManager::Directory>);
WindowOSR(CefString url, int width, int height, BoltSocketType client_fd, Client* main_client, std::mutex* send_lock, int pid, uint64_t window_id, uint64_t plugin_id, CefRefPtr<FileManager::Directory>, const char* custom_js);

bool IsDeleted();

Expand Down
16 changes: 12 additions & 4 deletions src/browser/window_plugin.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@
#include <fmt/core.h>

struct InitTask: public CefTask {
InitTask(CefRefPtr<Browser::PluginWindow> window, const char* url): window(window), url(CefString(url)) {}
InitTask(CefRefPtr<Browser::PluginWindow> window, const char* url, bool has_custom_js, CefString& custom_js): window(window), url(CefString(url)), has_custom_js(has_custom_js) {
if (has_custom_js) this->custom_js = custom_js;
}
void Execute() override {
this->window->Init(this->url);
CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
if (this->has_custom_js) dict->SetString("customjs", this->custom_js);
this->window->Init(this->url, dict);
}
private:
CefRefPtr<Browser::PluginWindow> window;
CefString url;
CefString custom_js;
bool has_custom_js;
IMPLEMENT_REFCOUNTING(InitTask);
DISALLOW_COPY_AND_ASSIGN(InitTask);
};
Expand All @@ -23,9 +29,11 @@ Browser::PluginWindow::PluginWindow(CefRefPtr<Client> main_client, Details detai
file_manager(file_manager), client_fd(fd), window_id(id), plugin_id(plugin_id), closing(false), deleted(false)
{
if (CefCurrentlyOn(TID_UI)) {
this->Init(CefString(url));
CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
if (details.has_custom_js) dict->SetString("customjs", details.custom_js);
this->Init(CefString(url), dict);
} else {
CefPostTask(TID_UI, new InitTask(this, url));
CefPostTask(TID_UI, new InitTask(this, url, details.has_custom_js, details.custom_js));
}
}

Expand Down
35 changes: 35 additions & 0 deletions src/library/doc/doc.texi
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,21 @@ end
@end verbatim
@end example

@node functions-playerposition
@section playerposition

Returns a @ref{objects-point} representing the last known position of
the player, in world coordinates. This point relates to point (0,0,0) on
the player model, which is usually on the ground between the model's
feet during a normal standing animation. Also see
@ref{appendix-world-coordinates}.

@example lua
@verbatim
local worldpoint = bolt.playerposition()
@end verbatim
@end example

@node functions-gamewindowsize
@section gamewindowsize

Expand Down Expand Up @@ -505,9 +520,19 @@ must use '/' as file separators (if any). Otherwise, it will be treated
as a URL of an internet website. The same rules go for any navigations
or fetch requests made by the browser during its lifetime.

The optional 6th parameter is some javascript code which will be run in
an OnContextCreated callback. This is immediately after the V8 context
has been created, so the JavaScipt @code{window} object is available but
the DOM content is not yet loaded.

The following example shows an invocation without some custom JS
followed by one with some custom JS, to demonstrate that the parameter
is optional.

@example lua
@verbatim
local mybrowser = bolt.createwindow(800, 608, "https://bolt.adamcake.com")
local mybrowser = bolt.createwindow(800, 608, "https://bolt.adamcake.com", "window.myCustomFunction = (a, b) => a + b;")
@end verbatim
@end example

Expand All @@ -522,9 +547,19 @@ will be treated as a URL of an internet website. The same rules go for
any navigations or fetch requests made by the browser during its
lifetime.

The optional 6th parameter is some javascript code which will be run in
an OnContextCreated callback. This is immediately after the V8 context
has been created, so the JavaScipt @code{window} object is available but
the DOM content is not yet loaded.

The following example shows an invocation without some custom JS
followed by one with some custom JS, to demonstrate that the parameter
is optional.

@example lua
@verbatim
local mybrowser = bolt.createembeddedbrowser(50, 60, 800, 608, "https://bolt.adamcake.com")
local mybrowser = bolt.createembeddedbrowser(50, 60, 800, 608, "https://bolt.adamcake.com", "window.myCustomFunction = (a, b) => a + b;")
@end verbatim
@end example

Expand Down
Loading

0 comments on commit f42224a

Please sign in to comment.