mirror of
https://github.com/atom/atom.git
synced 2026-01-15 01:48:15 -05:00
This adds support for accessing native extensions in web workers, though it may not work quite how we need it to just yet. Figured we'd bank an upgrade anyway.
243 lines
7.3 KiB
C++
243 lines
7.3 KiB
C++
#include <sstream>
|
|
#include <iostream>
|
|
#include <assert.h>
|
|
#include "include/cef_path_util.h"
|
|
#include "include/cef_process_util.h"
|
|
#include "include/cef_task.h"
|
|
#include "include/cef_runnable.h"
|
|
#include "include/cef_trace.h"
|
|
#include "cef_types.h"
|
|
#include "native/atom_cef_client.h"
|
|
#include "cef_v8.h"
|
|
|
|
#define REQUIRE_UI_THREAD() assert(CefCurrentlyOn(TID_UI));
|
|
#define REQUIRE_IO_THREAD() assert(CefCurrentlyOn(TID_IO));
|
|
#define REQUIRE_FILE_THREAD() assert(CefCurrentlyOn(TID_FILE));
|
|
|
|
AtomCefClient::AtomCefClient(){
|
|
}
|
|
|
|
AtomCefClient::AtomCefClient(bool handlePasteboardCommands) {
|
|
m_HandlePasteboardCommands = handlePasteboardCommands;
|
|
}
|
|
|
|
AtomCefClient::~AtomCefClient() {
|
|
}
|
|
|
|
bool AtomCefClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
|
|
CefProcessId source_process,
|
|
CefRefPtr<CefProcessMessage> message) {
|
|
std::string name = message->GetName().ToString();
|
|
CefRefPtr<CefListValue> argumentList = message->GetArgumentList();
|
|
int messageId = argumentList->GetInt(0);
|
|
|
|
if (name == "open") {
|
|
bool hasArguments = argumentList->GetSize() > 1;
|
|
hasArguments ? Open(argumentList->GetString(1)) : Open();
|
|
}
|
|
if (name == "openUnstable") {
|
|
bool hasArguments = argumentList->GetSize() > 1;
|
|
hasArguments ? OpenUnstable(argumentList->GetString(1)) : OpenUnstable();
|
|
}
|
|
else if (name == "newWindow") {
|
|
NewWindow();
|
|
}
|
|
else if (name == "toggleDevTools") {
|
|
ToggleDevTools(browser);
|
|
}
|
|
else if (name == "showDevTools") {
|
|
ShowDevTools(browser);
|
|
}
|
|
else if (name == "confirm") {
|
|
std::string message = argumentList->GetString(1).ToString();
|
|
std::string detailedMessage = argumentList->GetString(2).ToString();
|
|
std::vector<std::string> buttonLabels(argumentList->GetSize() - 3);
|
|
for (int i = 3; i < argumentList->GetSize(); i++) {
|
|
buttonLabels[i - 3] = argumentList->GetString(i).ToString();
|
|
}
|
|
|
|
Confirm(messageId, message, detailedMessage, buttonLabels, browser);
|
|
}
|
|
else if (name == "showSaveDialog") {
|
|
ShowSaveDialog(messageId, browser);
|
|
}
|
|
else if (name == "focus") {
|
|
GetBrowser()->GetHost()->SetFocus(true);
|
|
}
|
|
else if (name == "exit") {
|
|
Exit(argumentList->GetInt(1));
|
|
}
|
|
else if (name == "log") {
|
|
std::string message = argumentList->GetString(1).ToString();
|
|
Log(message.c_str());
|
|
}
|
|
else if (name == "beginTracing") {
|
|
BeginTracing();
|
|
}
|
|
else if (name == "endTracing") {
|
|
EndTracing();
|
|
}
|
|
else if (name == "show") {
|
|
Show(browser);
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void AtomCefClient::OnBeforeContextMenu(
|
|
CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
CefRefPtr<CefContextMenuParams> params,
|
|
CefRefPtr<CefMenuModel> model) {
|
|
|
|
model->Clear();
|
|
model->AddItem(MENU_ID_USER_FIRST, "&Toggle DevTools");
|
|
}
|
|
|
|
bool AtomCefClient::OnContextMenuCommand(
|
|
CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
CefRefPtr<CefContextMenuParams> params,
|
|
int command_id,
|
|
EventFlags event_flags) {
|
|
|
|
if (command_id == MENU_ID_USER_FIRST) {
|
|
ToggleDevTools(browser);
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool AtomCefClient::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
|
|
const CefString& message,
|
|
const CefString& source,
|
|
int line) {
|
|
REQUIRE_UI_THREAD();
|
|
Log(message.ToString().c_str());
|
|
return true;
|
|
}
|
|
|
|
bool AtomCefClient::OnKeyEvent(CefRefPtr<CefBrowser> browser,
|
|
const CefKeyEvent& event,
|
|
CefEventHandle os_event) {
|
|
if (event.modifiers == EVENTFLAG_COMMAND_DOWN && event.unmodified_character == 'r') {
|
|
browser->SendProcessMessage(PID_RENDERER, CefProcessMessage::Create("reload"));
|
|
}
|
|
if (m_HandlePasteboardCommands && event.modifiers == EVENTFLAG_COMMAND_DOWN && event.unmodified_character == 'x') {
|
|
browser->GetFocusedFrame()->Cut();
|
|
}
|
|
if (m_HandlePasteboardCommands && event.modifiers == EVENTFLAG_COMMAND_DOWN && event.unmodified_character == 'c') {
|
|
browser->GetFocusedFrame()->Copy();
|
|
}
|
|
if (m_HandlePasteboardCommands && event.modifiers == EVENTFLAG_COMMAND_DOWN && event.unmodified_character == 'v') {
|
|
browser->GetFocusedFrame()->Paste();
|
|
}
|
|
else if (event.modifiers == (EVENTFLAG_COMMAND_DOWN | EVENTFLAG_ALT_DOWN) && event.unmodified_character == 'i') {
|
|
ToggleDevTools(browser);
|
|
} else if (event.modifiers == EVENTFLAG_COMMAND_DOWN && event.unmodified_character == '`') {
|
|
FocusNextWindow();
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void AtomCefClient::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
|
// REQUIRE_UI_THREAD(); // When uncommented this fails when app is terminated
|
|
m_Browser = NULL;
|
|
}
|
|
|
|
void AtomCefClient::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
|
REQUIRE_UI_THREAD();
|
|
|
|
AutoLock lock_scope(this);
|
|
if (!m_Browser.get()) {
|
|
m_Browser = browser;
|
|
}
|
|
|
|
GetBrowser()->GetHost()->SetFocus(true);
|
|
}
|
|
|
|
void AtomCefClient::OnLoadError(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
ErrorCode errorCode,
|
|
const CefString& errorText,
|
|
const CefString& failedUrl) {
|
|
REQUIRE_UI_THREAD();
|
|
frame->LoadString(std::string(errorText) + "<br />" + std::string(failedUrl), failedUrl);
|
|
}
|
|
|
|
void AtomCefClient::BeginTracing() {
|
|
if (CefCurrentlyOn(TID_UI)) {
|
|
class Client : public CefTraceClient,
|
|
public CefRunFileDialogCallback {
|
|
public:
|
|
explicit Client(CefRefPtr<AtomCefClient> handler)
|
|
: handler_(handler),
|
|
trace_data_("{\"traceEvents\":["),
|
|
first_(true) {
|
|
}
|
|
|
|
virtual void OnTraceDataCollected(const char* fragment,
|
|
size_t fragment_size) OVERRIDE {
|
|
if (first_)
|
|
first_ = false;
|
|
else
|
|
trace_data_.append(",");
|
|
trace_data_.append(fragment, fragment_size);
|
|
}
|
|
|
|
virtual void OnEndTracingComplete() OVERRIDE {
|
|
REQUIRE_UI_THREAD();
|
|
trace_data_.append("]}");
|
|
|
|
handler_->GetBrowser()->GetHost()->RunFileDialog(
|
|
FILE_DIALOG_SAVE, CefString(), "/tmp/atom-trace.txt", std::vector<CefString>(),
|
|
this);
|
|
}
|
|
|
|
virtual void OnFileDialogDismissed(
|
|
CefRefPtr<CefBrowserHost> browser_host,
|
|
const std::vector<CefString>& file_paths) OVERRIDE {
|
|
if (!file_paths.empty())
|
|
handler_->Save(file_paths.front(), trace_data_);
|
|
}
|
|
|
|
private:
|
|
CefRefPtr<AtomCefClient> handler_;
|
|
std::string trace_data_;
|
|
bool first_;
|
|
|
|
IMPLEMENT_REFCOUNTING(Callback);
|
|
};
|
|
|
|
CefBeginTracing(new Client(this), CefString());
|
|
} else {
|
|
CefPostTask(TID_UI, NewCefRunnableMethod(this, &AtomCefClient::BeginTracing));
|
|
}
|
|
}
|
|
|
|
void AtomCefClient::EndTracing() {
|
|
if (CefCurrentlyOn(TID_UI)) {
|
|
CefEndTracingAsync();
|
|
} else {
|
|
CefPostTask(TID_UI, NewCefRunnableMethod(this, &AtomCefClient::BeginTracing));
|
|
}
|
|
}
|
|
|
|
bool AtomCefClient::Save(const std::string& path, const std::string& data) {
|
|
FILE* f = fopen(path.c_str(), "w");
|
|
if (!f)
|
|
return false;
|
|
fwrite(data.c_str(), data.size(), 1, f);
|
|
fclose(f);
|
|
return true;
|
|
}
|