mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-11 04:48:44 +03:00
980c5d6b11
* Open the dev tools console * Call `atom.beginTracing()` * Do stuff * Call `atom.endTracing()` * Save the file somewhere * Open `about:tracing` in chrome and load the file * Inspect away!
238 lines
7.1 KiB
C++
238 lines
7.1 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 "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();
|
|
}
|
|
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 == "beginTracing") {
|
|
BeginTracing();
|
|
}
|
|
else if (name == "endTracing") {
|
|
EndTracing();
|
|
}
|
|
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 == KEY_META && event.unmodified_character == 'r') {
|
|
browser->SendProcessMessage(PID_RENDERER, CefProcessMessage::Create("reload"));
|
|
}
|
|
if (m_HandlePasteboardCommands && event.modifiers == KEY_META && event.unmodified_character == 'x') {
|
|
browser->GetFocusedFrame()->Cut();
|
|
}
|
|
if (m_HandlePasteboardCommands && event.modifiers == KEY_META && event.unmodified_character == 'c') {
|
|
browser->GetFocusedFrame()->Copy();
|
|
}
|
|
if (m_HandlePasteboardCommands && event.modifiers == KEY_META && event.unmodified_character == 'v') {
|
|
browser->GetFocusedFrame()->Paste();
|
|
}
|
|
else if (event.modifiers == (KEY_META | KEY_ALT) && event.unmodified_character == 'i') {
|
|
ToggleDevTools(browser);
|
|
} else if (event.modifiers == KEY_META && event.unmodified_character == '`') {
|
|
FocusNextWindow();
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void AtomCefClient::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
// TODO: Ask Marshal. This was in cefclient... was there a good reason?
|
|
// if(m_BrowserHwnd == browser->GetWindowHandle()) {
|
|
// // Free the browser pointer so that the browser can be destroyed
|
|
// m_Browser = NULL;
|
|
// }
|
|
|
|
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;
|
|
} |