mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25db6e0bd8 | ||
|
|
cefe540ec0 | ||
|
|
8363a39a56 | ||
|
|
57ef6adbbd | ||
|
|
5ae9c633ca | ||
|
|
13c1b078f9 | ||
|
|
cd7b3dd291 | ||
|
|
bb42c2c7b6 | ||
|
|
af62b7b5c9 | ||
|
|
8f9a109fa6 | ||
|
|
05468cc3fa | ||
|
|
94d69777fa | ||
|
|
67144aaf2a | ||
|
|
d9efc3b4bf | ||
|
|
c32aac0a56 | ||
|
|
92b15c81e9 | ||
|
|
19d742de37 | ||
|
|
e8f33f51fb | ||
|
|
7f7cdbf775 | ||
|
|
7f42c0fa21 | ||
|
|
8306dc427a | ||
|
|
66b3972fbc | ||
|
|
790fba598e | ||
|
|
129159c895 | ||
|
|
f4c696b922 | ||
|
|
f54506acc0 | ||
|
|
4466082592 | ||
|
|
a8256a62e0 | ||
|
|
683917ae67 | ||
|
|
a22b9be681 | ||
|
|
3b20f2aced | ||
|
|
5d23b7468e | ||
|
|
d5b47d1059 | ||
|
|
47e9deeb9a | ||
|
|
6d6e75795f | ||
|
|
cc3066e746 | ||
|
|
0fcc0f3e0a | ||
|
|
3c186946eb | ||
|
|
31beee9599 | ||
|
|
912ed2ca10 | ||
|
|
c2352d3499 | ||
|
|
3a3b05b2f0 | ||
|
|
95a8f3fc70 | ||
|
|
34cd1435b4 | ||
|
|
d4be2da70e | ||
|
|
6dfa7b5383 | ||
|
|
94382cbaa2 | ||
|
|
981908c336 | ||
|
|
3ee054e316 | ||
|
|
f22d4bf0c0 | ||
|
|
d46e986e80 | ||
|
|
bd6d41bd87 | ||
|
|
4457edb1d3 | ||
|
|
2396b51cb6 | ||
|
|
317406f26d | ||
|
|
67a9931b55 | ||
|
|
ad851547e0 | ||
|
|
c4cbb5ecdb | ||
|
|
b97c22d4d7 | ||
|
|
fe631e6eeb | ||
|
|
1314b7c7e5 | ||
|
|
c026863d48 | ||
|
|
51d5ef9d86 | ||
|
|
16fb847009 | ||
|
|
cd8ceec62e | ||
|
|
98a9d8a9e3 | ||
|
|
4e2f242ad0 | ||
|
|
02bdace366 | ||
|
|
6ed538b952 | ||
|
|
dfbe158ca9 | ||
|
|
fb37b5720d | ||
|
|
57ab704300 | ||
|
|
4a310ad630 | ||
|
|
a9ad783bca | ||
|
|
b5c9fe78f1 | ||
|
|
e4bb456964 | ||
|
|
b45ed8d9a2 | ||
|
|
bdf73fcd4c | ||
|
|
3e720bd611 | ||
|
|
ad89a923e9 | ||
|
|
725115e0b5 | ||
|
|
419a14a63f | ||
|
|
d9102efff7 | ||
|
|
895ab49857 | ||
|
|
ebbb974aca | ||
|
|
8a6ba7c49f | ||
|
|
f98da217e1 | ||
|
|
2060acd914 | ||
|
|
014d80c359 | ||
|
|
9b7ad675c6 | ||
|
|
4d56281972 | ||
|
|
5584e3fd49 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,6 +6,7 @@
|
||||
/vendor/brightray/vendor/download/
|
||||
/vendor/python_26/
|
||||
/vendor/npm/
|
||||
/vendor/.gclient
|
||||
node_modules/
|
||||
*.xcodeproj
|
||||
*.swp
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -13,3 +13,6 @@
|
||||
[submodule "vendor/native_mate"]
|
||||
path = vendor/native_mate
|
||||
url = https://github.com/zcbenz/native-mate.git
|
||||
[submodule "vendor/crashpad"]
|
||||
path = vendor/crashpad
|
||||
url = https://github.com/atom/crashpad.git
|
||||
|
||||
10
atom.gyp
10
atom.gyp
@@ -4,7 +4,7 @@
|
||||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '0.27.0',
|
||||
'version%': '0.27.3',
|
||||
|
||||
'atom_source_root': '<!(["python", "tools/atom_source_root.py"])',
|
||||
},
|
||||
@@ -45,6 +45,7 @@
|
||||
'dependencies': [
|
||||
'<(project_name)_framework',
|
||||
'<(project_name)_helper',
|
||||
'vendor/breakpad/breakpad.gyp:dump_syms',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name)',
|
||||
@@ -275,7 +276,8 @@
|
||||
}], # OS=="win"
|
||||
['OS=="mac"', {
|
||||
'dependencies': [
|
||||
'vendor/breakpad/breakpad.gyp:breakpad',
|
||||
'vendor/crashpad/client/client.gyp:crashpad_client',
|
||||
'vendor/crashpad/handler/handler.gyp:crashpad_handler',
|
||||
],
|
||||
}], # OS=="mac"
|
||||
['OS=="linux"', {
|
||||
@@ -430,8 +432,7 @@
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources',
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/Inspector',
|
||||
'<(PRODUCT_DIR)/crash_report_sender.app',
|
||||
'<(PRODUCT_DIR)/crashpad_handler',
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -452,7 +453,6 @@
|
||||
'tools/mac/create-framework-subdir-symlinks.sh',
|
||||
'<(product_name) Framework',
|
||||
'Libraries',
|
||||
'Frameworks',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -70,10 +70,6 @@ void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
|
||||
menu_will_show_.Run();
|
||||
}
|
||||
|
||||
void Menu::AttachToWindow(Window* window) {
|
||||
window->window()->SetMenu(model_.get());
|
||||
}
|
||||
|
||||
void Menu::InsertItemAt(
|
||||
int index, int command_id, const base::string16& label) {
|
||||
model_->InsertItemAt(index, command_id, label);
|
||||
@@ -168,7 +164,6 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
|
||||
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
|
||||
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
|
||||
.SetMethod("attachToWindow", &Menu::AttachToWindow)
|
||||
.SetMethod("_popup", &Menu::Popup)
|
||||
.SetMethod("_popupAt", &Menu::PopupAt);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ class Menu : public mate::Wrappable,
|
||||
void ExecuteCommand(int command_id, int event_flags) override;
|
||||
void MenuWillShow(ui::SimpleMenuModel* source) override;
|
||||
|
||||
virtual void AttachToWindow(Window* window);
|
||||
virtual void Popup(Window* window) = 0;
|
||||
virtual void PopupAt(Window* window, int x, int y) = 0;
|
||||
|
||||
@@ -99,4 +98,27 @@ class Menu : public mate::Wrappable,
|
||||
|
||||
} // namespace atom
|
||||
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<ui::SimpleMenuModel*> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
ui::SimpleMenuModel** out) {
|
||||
// null would be tranfered to NULL.
|
||||
if (val->IsNull()) {
|
||||
*out = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
atom::api::Menu* menu;
|
||||
if (!Converter<atom::api::Menu*>::FromV8(isolate, val, &menu))
|
||||
return false;
|
||||
*out = menu->model();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_javascript_dialog_manager.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_dialog_helper.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
@@ -21,7 +19,6 @@
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/media/media_stream_devices_controller.h"
|
||||
#include "content/public/browser/favicon_status.h"
|
||||
#include "content/public/browser/guest_host.h"
|
||||
#include "content/public/browser/navigation_details.h"
|
||||
@@ -44,18 +41,52 @@
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<atom::api::SetSizeParams> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
atom::api::SetSizeParams* out) {
|
||||
mate::Dictionary params;
|
||||
if (!ConvertFromV8(isolate, val, ¶ms))
|
||||
return false;
|
||||
bool autosize;
|
||||
if (params.Get("enableAutoSize", &autosize))
|
||||
out->enable_auto_size.reset(new bool(true));
|
||||
gfx::Size size;
|
||||
if (params.Get("min", &size))
|
||||
out->min_size.reset(new gfx::Size(size));
|
||||
if (params.Get("max", &size))
|
||||
out->max_size.reset(new gfx::Size(size));
|
||||
if (params.Get("normal", &size))
|
||||
out->normal_size.reset(new gfx::Size(size));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
const int kDefaultWidth = 300;
|
||||
const int kDefaultHeight = 300;
|
||||
|
||||
v8::Persistent<v8::ObjectTemplate> template_;
|
||||
|
||||
// The wrapWebContents funtion which is implemented in JavaScript
|
||||
using WrapWebContentsCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
WrapWebContentsCallback g_wrap_web_contents;
|
||||
|
||||
// Get the window that has the |guest| embedded.
|
||||
NativeWindow* GetWindowFromGuest(const content::WebContents* guest) {
|
||||
WebViewManager::WebViewInfo info;
|
||||
if (WebViewManager::GetInfoForProcess(guest->GetRenderProcessHost(), &info))
|
||||
if (WebViewManager::GetInfoForWebContents(guest, &info))
|
||||
return NativeWindow::FromWebContents(info.embedder);
|
||||
else
|
||||
return nullptr;
|
||||
@@ -68,32 +99,39 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
|
||||
if (!context || !site_instance)
|
||||
return nullptr;
|
||||
|
||||
content::StoragePartition* storage_partition =
|
||||
content::BrowserContext::GetStoragePartition(
|
||||
context, site_instance);
|
||||
|
||||
DCHECK(storage_partition);
|
||||
auto storage_partition =
|
||||
content::BrowserContext::GetStoragePartition(context, site_instance);
|
||||
if (!storage_partition)
|
||||
return nullptr;
|
||||
|
||||
return storage_partition->GetServiceWorkerContext();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WebContents::WebContents(brightray::InspectableWebContents* web_contents)
|
||||
: WebContents(web_contents->GetWebContents()) {
|
||||
inspectable_web_contents_ = web_contents;
|
||||
}
|
||||
|
||||
WebContents::WebContents(content::WebContents* web_contents)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
: CommonWebContentsDelegate(false),
|
||||
content::WebContentsObserver(web_contents),
|
||||
guest_instance_id_(-1),
|
||||
element_instance_id_(-1),
|
||||
guest_opaque_(true),
|
||||
guest_host_(nullptr),
|
||||
auto_size_enabled_(false) {
|
||||
auto_size_enabled_(false),
|
||||
is_full_page_plugin_(false),
|
||||
inspectable_web_contents_(nullptr) {
|
||||
}
|
||||
|
||||
WebContents::WebContents(const mate::Dictionary& options)
|
||||
: guest_instance_id_(-1),
|
||||
element_instance_id_(-1),
|
||||
: CommonWebContentsDelegate(true),
|
||||
guest_instance_id_(-1),
|
||||
guest_opaque_(true),
|
||||
guest_host_(nullptr),
|
||||
auto_size_enabled_(false) {
|
||||
auto_size_enabled_(false),
|
||||
is_full_page_plugin_(false) {
|
||||
options.Get("guestInstanceId", &guest_instance_id_);
|
||||
|
||||
auto browser_context = AtomBrowserContext::Get();
|
||||
@@ -105,9 +143,11 @@ WebContents::WebContents(const mate::Dictionary& options)
|
||||
if (options.Get("isGuest", &is_guest) && is_guest)
|
||||
params.guest_delegate = this;
|
||||
|
||||
storage_.reset(brightray::InspectableWebContents::Create(params));
|
||||
Observe(storage_->GetWebContents());
|
||||
web_contents()->SetDelegate(this);
|
||||
auto web_contents = content::WebContents::Create(params);
|
||||
InitWithWebContents(web_contents, GetWindowFromGuest(web_contents));
|
||||
inspectable_web_contents_ = managed_web_contents();
|
||||
|
||||
Observe(GetWebContents());
|
||||
}
|
||||
|
||||
WebContents::~WebContents() {
|
||||
@@ -155,56 +195,7 @@ content::WebContents* WebContents::OpenURLFromTab(
|
||||
if (Emit("will-navigate", params.url))
|
||||
return nullptr;
|
||||
|
||||
content::NavigationController::LoadURLParams load_url_params(params.url);
|
||||
load_url_params.referrer = params.referrer;
|
||||
load_url_params.transition_type = params.transition;
|
||||
load_url_params.extra_headers = params.extra_headers;
|
||||
load_url_params.should_replace_current_entry =
|
||||
params.should_replace_current_entry;
|
||||
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
||||
load_url_params.transferred_global_request_id =
|
||||
params.transferred_global_request_id;
|
||||
load_url_params.should_clear_history_list = true;
|
||||
|
||||
web_contents()->GetController().LoadURLWithParams(load_url_params);
|
||||
return web_contents();
|
||||
}
|
||||
|
||||
content::JavaScriptDialogManager* WebContents::GetJavaScriptDialogManager(
|
||||
content::WebContents* source) {
|
||||
if (!dialog_manager_)
|
||||
dialog_manager_.reset(new AtomJavaScriptDialogManager);
|
||||
|
||||
return dialog_manager_.get();
|
||||
}
|
||||
|
||||
void WebContents::RunFileChooser(content::WebContents* guest,
|
||||
const content::FileChooserParams& params) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(GetWindowFromGuest(guest)));
|
||||
web_dialog_helper_->RunFileChooser(guest, params);
|
||||
}
|
||||
|
||||
void WebContents::EnumerateDirectory(content::WebContents* guest,
|
||||
int request_id,
|
||||
const base::FilePath& path) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(GetWindowFromGuest(guest)));
|
||||
web_dialog_helper_->EnumerateDirectory(guest, request_id, path);
|
||||
}
|
||||
|
||||
bool WebContents::CheckMediaAccessPermission(content::WebContents* web_contents,
|
||||
const GURL& security_origin,
|
||||
content::MediaStreamType type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebContents::RequestMediaAccessPermission(
|
||||
content::WebContents*,
|
||||
const content::MediaStreamRequest& request,
|
||||
const content::MediaResponseCallback& callback) {
|
||||
brightray::MediaStreamDevicesController controller(request, callback);
|
||||
controller.TakeAction();
|
||||
return CommonWebContentsDelegate::OpenURLFromTab(source, params);
|
||||
}
|
||||
|
||||
void WebContents::HandleKeyboardEvent(
|
||||
@@ -220,32 +211,13 @@ void WebContents::HandleKeyboardEvent(
|
||||
|
||||
void WebContents::EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) {
|
||||
auto window = GetWindowFromGuest(source);
|
||||
if (window) {
|
||||
window->SetHtmlApiFullscreen(true);
|
||||
window->NotifyWindowEnterHtmlFullScreen();
|
||||
source->GetRenderViewHost()->WasResized();
|
||||
Emit("enter-html-full-screen");
|
||||
}
|
||||
CommonWebContentsDelegate::EnterFullscreenModeForTab(source, origin);
|
||||
Emit("enter-html-full-screen");
|
||||
}
|
||||
|
||||
void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
|
||||
auto window = GetWindowFromGuest(source);
|
||||
if (window) {
|
||||
window->SetHtmlApiFullscreen(false);
|
||||
window->NotifyWindowLeaveHtmlFullScreen();
|
||||
source->GetRenderViewHost()->WasResized();
|
||||
Emit("leave-html-full-screen");
|
||||
}
|
||||
}
|
||||
|
||||
bool WebContents::IsFullscreenForTabOrPending(
|
||||
const content::WebContents* source) const {
|
||||
auto window = GetWindowFromGuest(source);
|
||||
if (window)
|
||||
return window->is_html_api_fullscreen();
|
||||
else
|
||||
return false;
|
||||
CommonWebContentsDelegate::ExitFullscreenModeForTab(source);
|
||||
Emit("leave-html-full-screen");
|
||||
}
|
||||
|
||||
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
|
||||
@@ -317,7 +289,7 @@ void WebContents::DidGetResourceResponseStart(
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
mate::Dictionary response_headers(isolate, v8::Object::New(isolate));
|
||||
|
||||
net::HttpResponseHeaders* headers = details.response_info.headers.get();
|
||||
net::HttpResponseHeaders* headers = details.headers.get();
|
||||
void* iter = nullptr;
|
||||
std::string key;
|
||||
std::string value;
|
||||
@@ -391,15 +363,11 @@ void WebContents::RenderViewReady() {
|
||||
// WebContents::GetRenderWidgetHostView will return the RWHV of an
|
||||
// interstitial page if one is showing at this time. We only want opacity
|
||||
// to apply to web pages.
|
||||
if (guest_opaque_) {
|
||||
web_contents()
|
||||
->GetRenderViewHost()
|
||||
->GetView()
|
||||
->SetBackgroundColorToDefault();
|
||||
} else {
|
||||
web_contents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
|
||||
SK_ColorTRANSPARENT);
|
||||
}
|
||||
auto render_view_host_view = web_contents()->GetRenderViewHost()->GetView();
|
||||
if (guest_opaque_)
|
||||
render_view_host_view->SetBackgroundColorToDefault();
|
||||
else
|
||||
render_view_host_view->SetBackgroundColor(SK_ColorTRANSPARENT);
|
||||
}
|
||||
|
||||
void WebContents::WebContentsDestroyed() {
|
||||
@@ -418,14 +386,6 @@ void WebContents::DidAttach(int guest_proxy_routing_id) {
|
||||
Emit("did-attach");
|
||||
}
|
||||
|
||||
void WebContents::ElementSizeChanged(const gfx::Size& size) {
|
||||
element_size_ = size;
|
||||
|
||||
// Only resize if needed.
|
||||
if (!size.IsEmpty())
|
||||
guest_host_->SizeContents(size);
|
||||
}
|
||||
|
||||
content::WebContents* WebContents::GetOwnerWebContents() const {
|
||||
return embedder_web_contents_;
|
||||
}
|
||||
@@ -445,11 +405,11 @@ void WebContents::WillAttach(content::WebContents* embedder_web_contents,
|
||||
int element_instance_id,
|
||||
bool is_full_page_plugin) {
|
||||
embedder_web_contents_ = embedder_web_contents;
|
||||
element_instance_id_ = element_instance_id;
|
||||
is_full_page_plugin_ = is_full_page_plugin;
|
||||
}
|
||||
|
||||
void WebContents::Destroy() {
|
||||
if (storage_) {
|
||||
if (is_guest() && managed_web_contents()) {
|
||||
// When force destroying the "destroyed" event is not emitted.
|
||||
WebContentsDestroyed();
|
||||
|
||||
@@ -458,7 +418,7 @@ void WebContents::Destroy() {
|
||||
guest_host_ = nullptr;
|
||||
|
||||
Observe(nullptr);
|
||||
storage_.reset();
|
||||
DestroyWebContents();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -543,26 +503,82 @@ void WebContents::ExecuteJavaScript(const base::string16& code) {
|
||||
web_contents()->GetMainFrame()->ExecuteJavaScript(code);
|
||||
}
|
||||
|
||||
void WebContents::OpenDevTools() {
|
||||
storage_->SetCanDock(false);
|
||||
storage_->ShowDevTools();
|
||||
void WebContents::OpenDevTools(mate::Arguments* args) {
|
||||
if (!inspectable_web_contents())
|
||||
return;
|
||||
bool detach = false;
|
||||
if (is_guest()) {
|
||||
detach = true;
|
||||
} else if (args && args->Length() == 1) {
|
||||
mate::Dictionary options;
|
||||
args->GetNext(&options) && options.Get("detach", &detach);
|
||||
}
|
||||
inspectable_web_contents()->SetCanDock(!detach);
|
||||
inspectable_web_contents()->ShowDevTools();
|
||||
}
|
||||
|
||||
void WebContents::CloseDevTools() {
|
||||
storage_->CloseDevTools();
|
||||
if (!inspectable_web_contents())
|
||||
return;
|
||||
inspectable_web_contents()->CloseDevTools();
|
||||
}
|
||||
|
||||
bool WebContents::IsDevToolsOpened() {
|
||||
return storage_->IsDevToolsViewShowing();
|
||||
if (!inspectable_web_contents())
|
||||
return false;
|
||||
return inspectable_web_contents()->IsDevToolsViewShowing();
|
||||
}
|
||||
|
||||
void WebContents::ToggleDevTools() {
|
||||
if (IsDevToolsOpened())
|
||||
CloseDevTools();
|
||||
else
|
||||
OpenDevTools(nullptr);
|
||||
}
|
||||
|
||||
void WebContents::InspectElement(int x, int y) {
|
||||
OpenDevTools();
|
||||
if (!inspectable_web_contents())
|
||||
return;
|
||||
OpenDevTools(nullptr);
|
||||
scoped_refptr<content::DevToolsAgentHost> agent(
|
||||
content::DevToolsAgentHost::GetOrCreateFor(storage_->GetWebContents()));
|
||||
content::DevToolsAgentHost::GetOrCreateFor(web_contents()));
|
||||
agent->InspectElement(x, y);
|
||||
}
|
||||
|
||||
void WebContents::InspectServiceWorker() {
|
||||
if (!inspectable_web_contents())
|
||||
return;
|
||||
for (const auto& agent_host : content::DevToolsAgentHost::GetOrCreateAll()) {
|
||||
if (agent_host->GetType() ==
|
||||
content::DevToolsAgentHost::TYPE_SERVICE_WORKER) {
|
||||
OpenDevTools(nullptr);
|
||||
inspectable_web_contents()->AttachTo(agent_host);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::HasServiceWorker(
|
||||
const base::Callback<void(bool)>& callback) {
|
||||
auto context = GetServiceWorkerContext(web_contents());
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
context->CheckHasServiceWorker(web_contents()->GetLastCommittedURL(),
|
||||
GURL::EmptyGURL(),
|
||||
callback);
|
||||
}
|
||||
|
||||
void WebContents::UnregisterServiceWorker(
|
||||
const base::Callback<void(bool)>& callback) {
|
||||
auto context = GetServiceWorkerContext(web_contents());
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
context->UnregisterServiceWorker(web_contents()->GetLastCommittedURL(),
|
||||
callback);
|
||||
}
|
||||
|
||||
void WebContents::Undo() {
|
||||
web_contents()->Undo();
|
||||
}
|
||||
@@ -612,31 +628,57 @@ bool WebContents::SendIPCMessage(const base::string16& channel,
|
||||
return Send(new AtomViewMsg_Message(routing_id(), channel, args));
|
||||
}
|
||||
|
||||
void WebContents::SetAutoSize(bool enabled,
|
||||
const gfx::Size& min_size,
|
||||
const gfx::Size& max_size) {
|
||||
void WebContents::SetSize(const SetSizeParams& params) {
|
||||
bool enable_auto_size =
|
||||
params.enable_auto_size ? *params.enable_auto_size : auto_size_enabled_;
|
||||
gfx::Size min_size = params.min_size ? *params.min_size : min_auto_size_;
|
||||
gfx::Size max_size = params.max_size ? *params.max_size : max_auto_size_;
|
||||
|
||||
if (params.normal_size)
|
||||
normal_size_ = *params.normal_size;
|
||||
|
||||
min_auto_size_ = min_size;
|
||||
min_auto_size_.SetToMin(max_size);
|
||||
max_auto_size_ = max_size;
|
||||
max_auto_size_.SetToMax(min_size);
|
||||
|
||||
enabled &= !min_auto_size_.IsEmpty() && !max_auto_size_.IsEmpty();
|
||||
if (!enabled && !auto_size_enabled_)
|
||||
return;
|
||||
|
||||
auto_size_enabled_ = enabled;
|
||||
|
||||
if (!attached())
|
||||
return;
|
||||
enable_auto_size &= !min_auto_size_.IsEmpty() && !max_auto_size_.IsEmpty();
|
||||
|
||||
content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
|
||||
if (auto_size_enabled_) {
|
||||
if (enable_auto_size) {
|
||||
// Autosize is being enabled.
|
||||
rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
|
||||
normal_size_.SetSize(0, 0);
|
||||
} else {
|
||||
rvh->DisableAutoResize(element_size_);
|
||||
guest_size_ = element_size_;
|
||||
GuestSizeChangedDueToAutoSize(guest_size_, element_size_);
|
||||
// Autosize is being disabled.
|
||||
// Use default width/height if missing from partially defined normal size.
|
||||
if (normal_size_.width() && !normal_size_.height())
|
||||
normal_size_.set_height(GetDefaultSize().height());
|
||||
if (!normal_size_.width() && normal_size_.height())
|
||||
normal_size_.set_width(GetDefaultSize().width());
|
||||
|
||||
gfx::Size new_size;
|
||||
if (!normal_size_.IsEmpty()) {
|
||||
new_size = normal_size_;
|
||||
} else if (!guest_size_.IsEmpty()) {
|
||||
new_size = guest_size_;
|
||||
} else {
|
||||
new_size = GetDefaultSize();
|
||||
}
|
||||
|
||||
if (auto_size_enabled_) {
|
||||
// Autosize was previously enabled.
|
||||
rvh->DisableAutoResize(new_size);
|
||||
GuestSizeChangedDueToAutoSize(guest_size_, new_size);
|
||||
} else {
|
||||
// Autosize was already disabled.
|
||||
guest_host_->SizeContents(new_size);
|
||||
}
|
||||
|
||||
guest_size_ = new_size;
|
||||
}
|
||||
|
||||
auto_size_enabled_ = enable_auto_size;
|
||||
}
|
||||
|
||||
void WebContents::SetAllowTransparency(bool allow) {
|
||||
@@ -658,36 +700,8 @@ void WebContents::SetAllowTransparency(bool allow) {
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::HasServiceWorker(
|
||||
const base::Callback<void(bool)>& callback) {
|
||||
auto context = GetServiceWorkerContext(web_contents());
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
context->CheckHasServiceWorker(web_contents()->GetLastCommittedURL(),
|
||||
GURL::EmptyGURL(),
|
||||
callback);
|
||||
}
|
||||
|
||||
void WebContents::UnregisterServiceWorker(
|
||||
const base::Callback<void(bool)>& callback) {
|
||||
auto context = GetServiceWorkerContext(web_contents());
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
context->UnregisterServiceWorker(web_contents()->GetLastCommittedURL(),
|
||||
callback);
|
||||
}
|
||||
|
||||
void WebContents::InspectServiceWorker() {
|
||||
for (const auto& agent_host : content::DevToolsAgentHost::GetOrCreateAll()) {
|
||||
if (agent_host->GetType() ==
|
||||
content::DevToolsAgentHost::TYPE_SERVICE_WORKER) {
|
||||
OpenDevTools();
|
||||
storage_->AttachTo(agent_host);
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool WebContents::IsGuest() const {
|
||||
return is_guest();
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||
@@ -714,6 +728,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
||||
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
||||
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
|
||||
.SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
|
||||
.SetMethod("inspectElement", &WebContents::InspectElement)
|
||||
.SetMethod("undo", &WebContents::Undo)
|
||||
.SetMethod("redo", &WebContents::Redo)
|
||||
@@ -727,9 +742,9 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||
.SetMethod("replace", &WebContents::Replace)
|
||||
.SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
|
||||
.SetMethod("_send", &WebContents::SendIPCMessage)
|
||||
.SetMethod("setAutoSize", &WebContents::SetAutoSize)
|
||||
.SetMethod("setSize", &WebContents::SetSize)
|
||||
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
|
||||
.SetMethod("isGuest", &WebContents::is_guest)
|
||||
.SetMethod("isGuest", &WebContents::IsGuest)
|
||||
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
|
||||
.SetMethod("unregisterServiceWorker",
|
||||
&WebContents::UnregisterServiceWorker)
|
||||
@@ -760,16 +775,46 @@ void WebContents::GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
|
||||
new_size.width(), new_size.height());
|
||||
}
|
||||
|
||||
gfx::Size WebContents::GetDefaultSize() const {
|
||||
if (is_full_page_plugin_) {
|
||||
// Full page plugins default to the size of the owner's viewport.
|
||||
return embedder_web_contents_->GetRenderWidgetHostView()
|
||||
->GetVisibleViewportSize();
|
||||
} else {
|
||||
return gfx::Size(kDefaultWidth, kDefaultHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<WebContents> WebContents::CreateFrom(
|
||||
v8::Isolate* isolate, brightray::InspectableWebContents* web_contents) {
|
||||
auto handle = mate::CreateHandle(isolate, new WebContents(web_contents));
|
||||
g_wrap_web_contents.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<WebContents> WebContents::CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents) {
|
||||
return mate::CreateHandle(isolate, new WebContents(web_contents));
|
||||
auto handle = mate::CreateHandle(isolate, new WebContents(web_contents));
|
||||
g_wrap_web_contents.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<WebContents> WebContents::Create(
|
||||
v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||
return mate::CreateHandle(isolate, new WebContents(options));
|
||||
auto handle = mate::CreateHandle(isolate, new WebContents(options));
|
||||
g_wrap_web_contents.Run(handle.ToV8());
|
||||
return handle;
|
||||
}
|
||||
|
||||
void SetWrapWebContents(const WrapWebContentsCallback& callback) {
|
||||
g_wrap_web_contents = callback;
|
||||
}
|
||||
|
||||
void ClearWrapWebContents() {
|
||||
g_wrap_web_contents.Reset();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -784,6 +829,8 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("create", &atom::api::WebContents::Create);
|
||||
dict.SetMethod("_setWrapWebContents", &atom::api::SetWrapWebContents);
|
||||
dict.SetMethod("_clearWrapWebContents", &atom::api::ClearWrapWebContents);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -9,10 +9,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "brightray/browser/default_web_contents_delegate.h"
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "content/public/browser/browser_plugin_guest_delegate.h"
|
||||
#include "content/public/common/favicon_url.h"
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/browser/gpu_data_manager_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
@@ -23,23 +22,39 @@ class InspectableWebContents;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomJavaScriptDialogManager;
|
||||
class WebDialogHelper;
|
||||
|
||||
namespace api {
|
||||
|
||||
// A struct of parameters for SetSize(). The parameters are all declared as
|
||||
// scoped pointers since they are all optional. Null pointers indicate that the
|
||||
// parameter has not been provided, and the last used value should be used. Note
|
||||
// that when |enable_auto_size| is true, providing |normal_size| is not
|
||||
// meaningful. This is because the normal size of the guestview is overridden
|
||||
// whenever autosizing occurs.
|
||||
struct SetSizeParams {
|
||||
SetSizeParams() {}
|
||||
~SetSizeParams() {}
|
||||
|
||||
scoped_ptr<bool> enable_auto_size;
|
||||
scoped_ptr<gfx::Size> min_size;
|
||||
scoped_ptr<gfx::Size> max_size;
|
||||
scoped_ptr<gfx::Size> normal_size;
|
||||
};
|
||||
|
||||
class WebContents : public mate::EventEmitter,
|
||||
public content::BrowserPluginGuestDelegate,
|
||||
public content::WebContentsDelegate,
|
||||
public CommonWebContentsDelegate,
|
||||
public content::WebContentsObserver,
|
||||
public content::GpuDataManagerObserver {
|
||||
public:
|
||||
// Create from an existing WebContents.
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate, brightray::InspectableWebContents* web_contents);
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
|
||||
@@ -64,13 +79,14 @@ class WebContents : public mate::EventEmitter,
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
void InsertCSS(const std::string& css);
|
||||
void ExecuteJavaScript(const base::string16& code);
|
||||
void OpenDevTools();
|
||||
void OpenDevTools(mate::Arguments* args);
|
||||
void CloseDevTools();
|
||||
bool IsDevToolsOpened();
|
||||
void ToggleDevTools();
|
||||
void InspectElement(int x, int y);
|
||||
void InspectServiceWorker();
|
||||
void HasServiceWorker(const base::Callback<void(bool)>&);
|
||||
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
|
||||
void InspectServiceWorker();
|
||||
|
||||
// Editing commands.
|
||||
void Undo();
|
||||
@@ -89,25 +105,26 @@ class WebContents : public mate::EventEmitter,
|
||||
bool SendIPCMessage(const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Toggles autosize mode for corresponding <webview>.
|
||||
void SetAutoSize(bool enabled,
|
||||
const gfx::Size& min_size,
|
||||
const gfx::Size& max_size);
|
||||
// Used to toggle autosize mode for this GuestView, and set both the automatic
|
||||
// and normal sizes.
|
||||
void SetSize(const SetSizeParams& params);
|
||||
|
||||
// Sets the transparency of the guest.
|
||||
void SetAllowTransparency(bool allow);
|
||||
|
||||
// Returns whether this is a guest view.
|
||||
bool is_guest() const { return guest_instance_id_ != -1; }
|
||||
bool IsGuest() const;
|
||||
|
||||
// Returns whether this guest has an associated embedder.
|
||||
bool attached() const { return !!embedder_web_contents_; }
|
||||
|
||||
content::WebContents* web_contents() const {
|
||||
return content::WebContentsObserver::web_contents();
|
||||
// Returns the current InspectableWebContents object, nullptr will be returned
|
||||
// if current WebContents can not beinspected, e.g. it is the devtools.
|
||||
brightray::InspectableWebContents* inspectable_web_contents() const {
|
||||
return inspectable_web_contents_;
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit WebContents(brightray::InspectableWebContents* web_contents);
|
||||
explicit WebContents(content::WebContents* web_contents);
|
||||
explicit WebContents(const mate::Dictionary& options);
|
||||
~WebContents();
|
||||
@@ -135,28 +152,12 @@ class WebContents : public mate::EventEmitter,
|
||||
content::WebContents* OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) override;
|
||||
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
|
||||
content::WebContents* source) override;
|
||||
void RunFileChooser(content::WebContents* web_contents,
|
||||
const content::FileChooserParams& params) override;
|
||||
void EnumerateDirectory(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
const base::FilePath& path) override;
|
||||
bool CheckMediaAccessPermission(content::WebContents* web_contents,
|
||||
const GURL& security_origin,
|
||||
content::MediaStreamType type) override;
|
||||
void RequestMediaAccessPermission(
|
||||
content::WebContents*,
|
||||
const content::MediaStreamRequest&,
|
||||
const content::MediaResponseCallback&) override;
|
||||
void HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
void EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) override;
|
||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||
bool IsFullscreenForTabOrPending(
|
||||
const content::WebContents* source) const override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void RenderViewDeleted(content::RenderViewHost*) override;
|
||||
@@ -196,7 +197,6 @@ class WebContents : public mate::EventEmitter,
|
||||
|
||||
// content::BrowserPluginGuestDelegate:
|
||||
void DidAttach(int guest_proxy_routing_id) final;
|
||||
void ElementSizeChanged(const gfx::Size& size) final;
|
||||
content::WebContents* GetOwnerWebContents() const final;
|
||||
void GuestSizeChanged(const gfx::Size& new_size) final;
|
||||
void SetGuestHost(content::GuestHost* guest_host) final;
|
||||
@@ -217,25 +217,23 @@ class WebContents : public mate::EventEmitter,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message);
|
||||
|
||||
// This method is invoked when the contents auto-resized to give the container
|
||||
// an opportunity to match it if it wishes.
|
||||
//
|
||||
// This gives the derived class an opportunity to inform its container element
|
||||
// or perform other actions.
|
||||
void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
|
||||
const gfx::Size& new_size);
|
||||
|
||||
scoped_ptr<WebDialogHelper> web_dialog_helper_;
|
||||
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
|
||||
// Returns the default size of the guestview.
|
||||
gfx::Size GetDefaultSize() const;
|
||||
|
||||
// Unique ID for a guest WebContents.
|
||||
int guest_instance_id_;
|
||||
|
||||
// |element_instance_id_| is an identifer that's unique to a particular
|
||||
// element.
|
||||
int element_instance_id_;
|
||||
|
||||
// Stores whether the contents of the guest can be transparent.
|
||||
bool guest_opaque_;
|
||||
|
||||
// Stores the WebContents that managed by this class.
|
||||
scoped_ptr<brightray::InspectableWebContents> storage_;
|
||||
|
||||
// The WebContents that attaches this guest view.
|
||||
content::WebContents* embedder_web_contents_;
|
||||
|
||||
@@ -258,6 +256,16 @@ class WebContents : public mate::EventEmitter,
|
||||
// The minimum size constraints of the container element in autosize mode.
|
||||
gfx::Size min_auto_size_;
|
||||
|
||||
// The size that will be used when autosize mode is disabled.
|
||||
gfx::Size normal_size_;
|
||||
|
||||
// Whether the guest view is inside a plugin document.
|
||||
bool is_full_page_plugin_;
|
||||
|
||||
// Current InspectableWebContents object, can be nullptr for WebContents of
|
||||
// devtools. It is a weak reference.
|
||||
brightray::InspectableWebContents* inspectable_web_contents_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
@@ -164,6 +165,26 @@ void Window::OnDevToolsFocus() {
|
||||
Emit("devtools-focused");
|
||||
}
|
||||
|
||||
void Window::OnDevToolsOpened() {
|
||||
Emit("devtools-opened");
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
auto handle =
|
||||
WebContents::CreateFrom(isolate, window_->GetDevToolsWebContents());
|
||||
devtools_web_contents_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
|
||||
void Window::OnDevToolsClosed() {
|
||||
Emit("devtools-closed");
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
devtools_web_contents_.Reset();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Window::New(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options) {
|
||||
@@ -355,26 +376,6 @@ bool Window::IsKiosk() {
|
||||
return window_->IsKiosk();
|
||||
}
|
||||
|
||||
void Window::OpenDevTools(bool can_dock) {
|
||||
window_->OpenDevTools(can_dock);
|
||||
}
|
||||
|
||||
void Window::CloseDevTools() {
|
||||
window_->CloseDevTools();
|
||||
}
|
||||
|
||||
bool Window::IsDevToolsOpened() {
|
||||
return window_->IsDevToolsOpened();
|
||||
}
|
||||
|
||||
void Window::InspectElement(int x, int y) {
|
||||
window_->InspectElement(x, y);
|
||||
}
|
||||
|
||||
void Window::InspectServiceWorker() {
|
||||
window_->InspectServiceWorker();
|
||||
}
|
||||
|
||||
void Window::FocusOnWebView() {
|
||||
window_->FocusOnWebView();
|
||||
}
|
||||
@@ -437,6 +438,10 @@ void Window::SetOverlayIcon(const gfx::Image& overlay,
|
||||
window_->SetOverlayIcon(overlay, description);
|
||||
}
|
||||
|
||||
void Window::SetMenu(ui::SimpleMenuModel* menu) {
|
||||
window_->SetMenu(menu);
|
||||
}
|
||||
|
||||
void Window::SetAutoHideMenuBar(bool auto_hide) {
|
||||
window_->SetAutoHideMenuBar(auto_hide);
|
||||
}
|
||||
@@ -467,13 +472,20 @@ bool Window::IsVisibleOnAllWorkspaces() {
|
||||
return window_->IsVisibleOnAllWorkspaces();
|
||||
}
|
||||
|
||||
mate::Handle<WebContents> Window::GetWebContents(v8::Isolate* isolate) const {
|
||||
return WebContents::CreateFrom(isolate, window_->GetWebContents());
|
||||
v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
|
||||
if (web_contents_.IsEmpty()) {
|
||||
auto handle =
|
||||
WebContents::CreateFrom(isolate, window_->managed_web_contents());
|
||||
web_contents_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, web_contents_);
|
||||
}
|
||||
|
||||
mate::Handle<WebContents> Window::GetDevToolsWebContents(
|
||||
v8::Isolate* isolate) const {
|
||||
return WebContents::CreateFrom(isolate, window_->GetDevToolsWebContents());
|
||||
v8::Local<v8::Value> Window::DevToolsWebContents(v8::Isolate* isolate) {
|
||||
if (devtools_web_contents_.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return v8::Local<v8::Value>::New(isolate, devtools_web_contents_);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -524,10 +536,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
|
||||
.SetMethod("_openDevTools", &Window::OpenDevTools)
|
||||
.SetMethod("closeDevTools", &Window::CloseDevTools)
|
||||
.SetMethod("isDevToolsOpened", &Window::IsDevToolsOpened)
|
||||
.SetMethod("inspectElement", &Window::InspectElement)
|
||||
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
|
||||
.SetMethod("blurWebView", &Window::BlurWebView)
|
||||
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
|
||||
@@ -535,6 +543,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("print", &Window::Print)
|
||||
.SetMethod("setProgressBar", &Window::SetProgressBar)
|
||||
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
|
||||
.SetMethod("_setMenu", &Window::SetMenu)
|
||||
.SetMethod("setAutoHideMenuBar", &Window::SetAutoHideMenuBar)
|
||||
.SetMethod("isMenuBarAutoHide", &Window::IsMenuBarAutoHide)
|
||||
.SetMethod("setMenuBarVisibility", &Window::SetMenuBarVisibility)
|
||||
@@ -547,9 +556,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("showDefinitionForSelection",
|
||||
&Window::ShowDefinitionForSelection)
|
||||
#endif
|
||||
.SetMethod("_getWebContents", &Window::GetWebContents)
|
||||
.SetMethod("_getDevToolsWebContents", &Window::GetDevToolsWebContents)
|
||||
.SetMethod("inspectServiceWorker", &Window::InspectServiceWorker);
|
||||
.SetProperty("webContents", &Window::WebContents)
|
||||
.SetProperty("devToolsWebContents", &Window::DevToolsWebContents);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -25,6 +25,10 @@ class Arguments;
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
class SimpleMenuModel;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NativeWindow;
|
||||
@@ -74,6 +78,8 @@ class Window : public mate::EventEmitter,
|
||||
void OnRendererUnresponsive() override;
|
||||
void OnRendererResponsive() override;
|
||||
void OnDevToolsFocus() override;
|
||||
void OnDevToolsOpened() override;
|
||||
void OnDevToolsClosed() override;
|
||||
|
||||
private:
|
||||
// APIs for NativeWindow.
|
||||
@@ -117,11 +123,6 @@ class Window : public mate::EventEmitter,
|
||||
void SetSkipTaskbar(bool skip);
|
||||
void SetKiosk(bool kiosk);
|
||||
bool IsKiosk();
|
||||
void OpenDevTools(bool can_dock);
|
||||
void CloseDevTools();
|
||||
bool IsDevToolsOpened();
|
||||
void InspectElement(int x, int y);
|
||||
void InspectServiceWorker();
|
||||
void FocusOnWebView();
|
||||
void BlurWebView();
|
||||
bool IsWebViewFocused();
|
||||
@@ -134,6 +135,7 @@ class Window : public mate::EventEmitter,
|
||||
void SetProgressBar(double progress);
|
||||
void SetOverlayIcon(const gfx::Image& overlay,
|
||||
const std::string& description);
|
||||
void SetMenu(ui::SimpleMenuModel* menu);
|
||||
void SetAutoHideMenuBar(bool auto_hide);
|
||||
bool IsMenuBarAutoHide();
|
||||
void SetMenuBarVisibility(bool visible);
|
||||
@@ -146,9 +148,11 @@ class Window : public mate::EventEmitter,
|
||||
void SetVisibleOnAllWorkspaces(bool visible);
|
||||
bool IsVisibleOnAllWorkspaces();
|
||||
|
||||
// APIs for WebContents.
|
||||
mate::Handle<WebContents> GetWebContents(v8::Isolate* isolate) const;
|
||||
mate::Handle<WebContents> GetDevToolsWebContents(v8::Isolate* isolate) const;
|
||||
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
v8::Global<v8::Value> devtools_web_contents_;
|
||||
|
||||
scoped_ptr<NativeWindow> window_;
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ EventEmitter = require('events').EventEmitter
|
||||
IDWeakMap = require 'id-weak-map'
|
||||
app = require 'app'
|
||||
ipc = require 'ipc'
|
||||
wrapWebContents = require('web-contents').wrap
|
||||
|
||||
BrowserWindow = process.atomBinding('window').BrowserWindow
|
||||
BrowserWindow::__proto__ = EventEmitter.prototype
|
||||
@@ -16,10 +15,6 @@ BrowserWindow::_init = ->
|
||||
menu = app.getApplicationMenu()
|
||||
@setMenu menu if menu?
|
||||
|
||||
@webContents = @getWebContents()
|
||||
@devToolsWebContents = null
|
||||
@webContents.once 'destroyed', => @webContents = null
|
||||
|
||||
# Remember the window ID.
|
||||
Object.defineProperty this, 'id',
|
||||
value: BrowserWindow.windows.add(this)
|
||||
@@ -40,35 +35,11 @@ BrowserWindow::_init = ->
|
||||
@once 'closed', =>
|
||||
BrowserWindow.windows.remove @id if BrowserWindow.windows.has @id
|
||||
|
||||
BrowserWindow::openDevTools = (options={}) ->
|
||||
options.detach ?= false
|
||||
@_openDevTools !options.detach
|
||||
|
||||
# Force devToolsWebContents to be created.
|
||||
@devToolsWebContents = @getDevToolsWebContents()
|
||||
@devToolsWebContents.once 'destroyed', => @devToolsWebContents = null
|
||||
|
||||
# Emit devtools events.
|
||||
@devToolsWebContents.once 'did-finish-load', => @emit 'devtools-opened'
|
||||
@devToolsWebContents.once 'destroyed', => @emit 'devtools-closed'
|
||||
|
||||
BrowserWindow::toggleDevTools = ->
|
||||
if @isDevToolsOpened() then @closeDevTools() else @openDevTools()
|
||||
|
||||
BrowserWindow::getWebContents = ->
|
||||
wrapWebContents @_getWebContents()
|
||||
|
||||
BrowserWindow::getDevToolsWebContents = ->
|
||||
wrapWebContents @_getDevToolsWebContents()
|
||||
|
||||
BrowserWindow::setMenu = (menu) ->
|
||||
if process.platform is 'darwin'
|
||||
throw new Error('BrowserWindow.setMenu is not available on OS X')
|
||||
|
||||
throw new TypeError('Invalid menu') unless menu?.constructor?.name is 'Menu'
|
||||
throw new TypeError('Invalid menu') unless menu is null or menu?.constructor?.name is 'Menu'
|
||||
|
||||
@menu = menu # Keep a reference of menu in case of GC.
|
||||
@menu.attachToWindow this
|
||||
@_setMenu menu
|
||||
|
||||
BrowserWindow.getAllWindows = ->
|
||||
windows = BrowserWindow.windows
|
||||
@@ -80,11 +51,11 @@ BrowserWindow.getFocusedWindow = ->
|
||||
|
||||
BrowserWindow.fromWebContents = (webContents) ->
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
return window for window in windows when webContents.equal window.webContents
|
||||
return window for window in windows when window.webContents?.equal webContents
|
||||
|
||||
BrowserWindow.fromDevToolsWebContents = (webContents) ->
|
||||
windows = BrowserWindow.getAllWindows()
|
||||
return window for window in windows when webContents.equal window.devToolsWebContents
|
||||
return window for window in windows when window.devToolsWebContents?.equal webContents
|
||||
|
||||
BrowserWindow.fromId = (id) ->
|
||||
BrowserWindow.windows.get id
|
||||
@@ -105,7 +76,12 @@ BrowserWindow::stop = -> @webContents.stop()
|
||||
BrowserWindow::getRoutingId = -> @webContents.getRoutingId()
|
||||
BrowserWindow::getProcessId = -> @webContents.getProcessId()
|
||||
BrowserWindow::isCrashed = -> @webContents.isCrashed()
|
||||
BrowserWindow::executeJavaScriptInDevTools = (code) ->
|
||||
@devToolsWebContents.executeJavaScript code
|
||||
BrowserWindow::executeJavaScriptInDevTools = (code) -> @devToolsWebContents?.executeJavaScript code
|
||||
BrowserWindow::openDevTools = -> @webContents.openDevTools.apply @webContents, arguments
|
||||
BrowserWindow::closeDevTools = -> @webContents.closeDevTools()
|
||||
BrowserWindow::isDevToolsOpened = -> @webContents.isDevToolsOpened()
|
||||
BrowserWindow::toggleDevTools = -> @webContents.toggleDevTools()
|
||||
BrowserWindow::inspectElement = -> @webContents.inspectElement.apply @webContents, arguments
|
||||
BrowserWindow::inspectServiceWorker = -> @webContents.inspectServiceWorker()
|
||||
|
||||
module.exports = BrowserWindow
|
||||
|
||||
@@ -130,10 +130,11 @@ Menu::_callMenuWillShow = ->
|
||||
|
||||
applicationMenu = null
|
||||
Menu.setApplicationMenu = (menu) ->
|
||||
throw new TypeError('Invalid menu') unless menu?.constructor is Menu
|
||||
throw new TypeError('Invalid menu') unless menu is null or menu.constructor is Menu
|
||||
applicationMenu = menu # Keep a reference.
|
||||
|
||||
if process.platform is 'darwin'
|
||||
return if menu is null
|
||||
menu._callMenuWillShow()
|
||||
bindings.setApplicationMenu menu
|
||||
else
|
||||
|
||||
@@ -3,9 +3,7 @@ NavigationController = require './navigation-controller'
|
||||
binding = process.atomBinding 'web_contents'
|
||||
ipc = require 'ipc'
|
||||
|
||||
module.exports.wrap = (webContents) ->
|
||||
return null unless webContents.isAlive()
|
||||
|
||||
wrapWebContents = (webContents) ->
|
||||
# webContents is an EventEmitter.
|
||||
webContents.__proto__ = EventEmitter.prototype
|
||||
|
||||
@@ -62,5 +60,8 @@ module.exports.wrap = (webContents) ->
|
||||
|
||||
webContents
|
||||
|
||||
binding._setWrapWebContents wrapWebContents
|
||||
process.once 'exit', binding._clearWrapWebContents
|
||||
|
||||
module.exports.create = (options={}) ->
|
||||
@wrap binding.create(options)
|
||||
binding.create(options)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_quota_permission_context.h"
|
||||
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
|
||||
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
@@ -22,7 +21,6 @@
|
||||
#include "content/public/browser/browser_ppapi_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/resource_dispatcher_host.h"
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
@@ -33,25 +31,41 @@ namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// The default routing id of WebContents.
|
||||
// In Electron each RenderProcessHost only has one WebContents, so this ID is
|
||||
// same for every WebContents.
|
||||
int kDefaultRoutingID = 2;
|
||||
|
||||
// Next navigation should not restart renderer process.
|
||||
bool g_suppress_renderer_process_restart = false;
|
||||
|
||||
struct FindByProcessId {
|
||||
explicit FindByProcessId(int child_process_id)
|
||||
: child_process_id_(child_process_id) {
|
||||
}
|
||||
|
||||
bool operator() (NativeWindow* const window) {
|
||||
content::WebContents* web_contents = window->GetWebContents();
|
||||
if (!web_contents)
|
||||
return false;
|
||||
|
||||
int id = window->GetWebContents()->GetRenderProcessHost()->GetID();
|
||||
return id == child_process_id_;
|
||||
}
|
||||
|
||||
int child_process_id_;
|
||||
// Find out the owner of the child process according to |process_id|.
|
||||
enum ProcessOwner {
|
||||
OWNER_NATIVE_WINDOW,
|
||||
OWNER_GUEST_WEB_CONTENTS,
|
||||
OWNER_NONE, // it might be devtools though.
|
||||
};
|
||||
ProcessOwner GetProcessOwner(int process_id,
|
||||
NativeWindow** window,
|
||||
WebViewManager::WebViewInfo* info) {
|
||||
auto web_contents = content::WebContents::FromRenderViewHost(
|
||||
content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
|
||||
if (!web_contents)
|
||||
return OWNER_NONE;
|
||||
|
||||
// First search for NativeWindow.
|
||||
for (auto native_window : *WindowList::GetInstance())
|
||||
if (web_contents == native_window->GetWebContents()) {
|
||||
*window = native_window;
|
||||
return OWNER_NATIVE_WINDOW;
|
||||
}
|
||||
|
||||
// Then search for guest WebContents.
|
||||
if (WebViewManager::GetInfoForWebContents(web_contents, info))
|
||||
return OWNER_GUEST_WEB_CONTENTS;
|
||||
|
||||
return OWNER_NONE;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -60,8 +74,7 @@ void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
|
||||
g_suppress_renderer_process_restart = true;
|
||||
}
|
||||
|
||||
AtomBrowserClient::AtomBrowserClient()
|
||||
: dying_render_process_(nullptr) {
|
||||
AtomBrowserClient::AtomBrowserClient() {
|
||||
}
|
||||
|
||||
AtomBrowserClient::~AtomBrowserClient() {
|
||||
@@ -83,15 +96,8 @@ content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
|
||||
return new AtomAccessTokenStore;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::ResourceDispatcherHostCreated() {
|
||||
resource_dispatcher_delegate_.reset(new AtomResourceDispatcherHostDelegate);
|
||||
content::ResourceDispatcherHost::Get()->SetDelegate(
|
||||
resource_dispatcher_delegate_.get());
|
||||
}
|
||||
|
||||
void AtomBrowserClient::OverrideWebkitPrefs(
|
||||
content::RenderViewHost* render_view_host,
|
||||
content::WebPreferences* prefs) {
|
||||
content::RenderViewHost* host, content::WebPreferences* prefs) {
|
||||
prefs->javascript_enabled = true;
|
||||
prefs->web_security_enabled = true;
|
||||
prefs->javascript_can_open_windows_automatically = true;
|
||||
@@ -109,18 +115,10 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
||||
prefs->allow_displaying_insecure_content = false;
|
||||
prefs->allow_running_insecure_content = false;
|
||||
|
||||
// Turn off web security for devtools.
|
||||
auto web_contents = content::WebContents::FromRenderViewHost(
|
||||
render_view_host);
|
||||
if (web_contents && web_contents->GetURL().SchemeIs("chrome-devtools")) {
|
||||
prefs->web_security_enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Custom preferences of guest page.
|
||||
auto process = render_view_host->GetProcess();
|
||||
auto web_contents = content::WebContents::FromRenderViewHost(host);
|
||||
WebViewManager::WebViewInfo info;
|
||||
if (WebViewManager::GetInfoForProcess(process, &info)) {
|
||||
if (WebViewManager::GetInfoForWebContents(web_contents, &info)) {
|
||||
prefs->web_security_enabled = !info.disable_web_security;
|
||||
return;
|
||||
}
|
||||
@@ -144,73 +142,37 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_instance->HasProcess())
|
||||
dying_render_process_ = current_instance->GetProcess();
|
||||
// Restart renderer process for all navigations except "javacript:" scheme.
|
||||
if (url.SchemeIs(url::kJavaScriptScheme))
|
||||
return;
|
||||
|
||||
// Restart renderer process for all navigations.
|
||||
*new_instance = content::SiteInstance::CreateForURL(browser_context, url);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
base::CommandLine* command_line,
|
||||
int child_process_id) {
|
||||
int process_id) {
|
||||
std::string process_type = command_line->GetSwitchValueASCII("type");
|
||||
if (process_type != "renderer")
|
||||
return;
|
||||
|
||||
WindowList* list = WindowList::GetInstance();
|
||||
NativeWindow* window = nullptr;
|
||||
NativeWindow* window;
|
||||
WebViewManager::WebViewInfo info;
|
||||
ProcessOwner owner = GetProcessOwner(process_id, &window, &info);
|
||||
|
||||
// Find the owner of this child process.
|
||||
WindowList::const_iterator iter = std::find_if(
|
||||
list->begin(), list->end(), FindByProcessId(child_process_id));
|
||||
if (iter != list->end())
|
||||
window = *iter;
|
||||
|
||||
// If the render process is a newly started one, which means the window still
|
||||
// uses the old going-to-be-swapped render process, then we try to find the
|
||||
// window from the swapped render process.
|
||||
if (!window && dying_render_process_) {
|
||||
int dying_process_id = dying_render_process_->GetID();
|
||||
WindowList::const_iterator iter = std::find_if(
|
||||
list->begin(), list->end(), FindByProcessId(dying_process_id));
|
||||
if (iter != list->end()) {
|
||||
window = *iter;
|
||||
child_process_id = dying_process_id;
|
||||
} else {
|
||||
// It appears that the dying process doesn't belong to a BrowserWindow,
|
||||
// then it might be a guest process, if it is we should update its
|
||||
// process ID in the WebViewManager.
|
||||
auto child_process = content::RenderProcessHost::FromID(child_process_id);
|
||||
// Update the process ID in webview guests.
|
||||
WebViewManager::UpdateGuestProcessID(dying_render_process_,
|
||||
child_process);
|
||||
}
|
||||
if (owner == OWNER_NATIVE_WINDOW) {
|
||||
window->AppendExtraCommandLineSwitches(command_line);
|
||||
} else if (owner == OWNER_GUEST_WEB_CONTENTS) {
|
||||
command_line->AppendSwitchASCII(
|
||||
switches::kGuestInstanceID, base::IntToString(info.guest_instance_id));
|
||||
command_line->AppendSwitchASCII(
|
||||
switches::kNodeIntegration, info.node_integration ? "true" : "false");
|
||||
if (info.plugins)
|
||||
command_line->AppendSwitch(switches::kEnablePlugins);
|
||||
if (!info.preload_script.empty())
|
||||
command_line->AppendSwitchPath(
|
||||
switches::kPreloadScript, info.preload_script);
|
||||
}
|
||||
|
||||
if (window) {
|
||||
window->AppendExtraCommandLineSwitches(command_line, child_process_id);
|
||||
} else {
|
||||
// Append commnad line arguments for guest web view.
|
||||
auto child_process = content::RenderProcessHost::FromID(child_process_id);
|
||||
WebViewManager::WebViewInfo info;
|
||||
if (WebViewManager::GetInfoForProcess(child_process, &info)) {
|
||||
command_line->AppendSwitchASCII(
|
||||
switches::kGuestInstanceID,
|
||||
base::IntToString(info.guest_instance_id));
|
||||
command_line->AppendSwitchASCII(
|
||||
switches::kNodeIntegration,
|
||||
info.node_integration ? "true" : "false");
|
||||
if (info.plugins)
|
||||
command_line->AppendSwitch(switches::kEnablePlugins);
|
||||
if (!info.preload_script.empty())
|
||||
command_line->AppendSwitchPath(
|
||||
switches::kPreloadScript,
|
||||
info.preload_script);
|
||||
}
|
||||
}
|
||||
|
||||
dying_render_process_ = nullptr;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::DidCreatePpapiPlugin(
|
||||
|
||||
@@ -15,8 +15,6 @@ class QuotaPermissionContext;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomResourceDispatcherHostDelegate;
|
||||
|
||||
class AtomBrowserClient : public brightray::BrowserClient {
|
||||
public:
|
||||
AtomBrowserClient();
|
||||
@@ -31,7 +29,6 @@ class AtomBrowserClient : public brightray::BrowserClient {
|
||||
content::SpeechRecognitionManagerDelegate*
|
||||
CreateSpeechRecognitionManagerDelegate() override;
|
||||
content::AccessTokenStore* CreateAccessTokenStore() override;
|
||||
void ResourceDispatcherHostCreated() override;
|
||||
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
|
||||
content::WebPreferences* prefs) override;
|
||||
std::string GetApplicationLocale() override;
|
||||
@@ -49,11 +46,6 @@ class AtomBrowserClient : public brightray::BrowserClient {
|
||||
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) override;
|
||||
|
||||
scoped_ptr<AtomResourceDispatcherHostDelegate> resource_dispatcher_delegate_;
|
||||
|
||||
// The render process which would be swapped out soon.
|
||||
content::RenderProcessHost* dying_render_process_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/resource_request_info.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomResourceDispatcherHostDelegate::AtomResourceDispatcherHostDelegate() {
|
||||
}
|
||||
|
||||
void AtomResourceDispatcherHostDelegate::OnResponseStarted(
|
||||
net::URLRequest* request,
|
||||
content::ResourceContext* resource_context,
|
||||
content::ResourceResponse* response,
|
||||
IPC::Sender* sender) {
|
||||
// Remove the "X-Frame-Options" from response headers for devtools.
|
||||
if (request->url().SchemeIs("chrome-devtools")) {
|
||||
net::HttpResponseHeaders* response_headers = request->response_headers();
|
||||
if (response_headers && response_headers->HasHeader("x-frame-options"))
|
||||
response_headers->RemoveHeader("x-frame-options");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,30 +0,0 @@
|
||||
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
|
||||
#define ATOM_BROWSER_ATOM_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "content/public/browser/resource_dispatcher_host_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomResourceDispatcherHostDelegate
|
||||
: public content::ResourceDispatcherHostDelegate {
|
||||
public:
|
||||
AtomResourceDispatcherHostDelegate();
|
||||
|
||||
// content::ResourceDispatcherHostDelegate:
|
||||
void OnResponseStarted(net::URLRequest* request,
|
||||
content::ResourceContext* resource_context,
|
||||
content::ResourceResponse* response,
|
||||
IPC::Sender* sender) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomResourceDispatcherHostDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
|
||||
342
atom/browser/common_web_contents_delegate.cc
Normal file
342
atom/browser/common_web_contents_delegate.cc
Normal file
@@ -0,0 +1,342 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/atom_javascript_dialog_manager.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "atom/browser/web_dialog_helper.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "chrome/browser/ui/browser_dialogs.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/common/renderer_preferences.h"
|
||||
#include "storage/browser/fileapi/isolated_context.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
struct FileSystem {
|
||||
FileSystem() {
|
||||
}
|
||||
FileSystem(const std::string& file_system_name,
|
||||
const std::string& root_url,
|
||||
const std::string& file_system_path)
|
||||
: file_system_name(file_system_name),
|
||||
root_url(root_url),
|
||||
file_system_path(file_system_path) {
|
||||
}
|
||||
|
||||
std::string file_system_name;
|
||||
std::string root_url;
|
||||
std::string file_system_path;
|
||||
};
|
||||
|
||||
std::string RegisterFileSystem(content::WebContents* web_contents,
|
||||
const base::FilePath& path,
|
||||
std::string* registered_name) {
|
||||
auto isolated_context = storage::IsolatedContext::GetInstance();
|
||||
std::string file_system_id = isolated_context->RegisterFileSystemForPath(
|
||||
storage::kFileSystemTypeNativeLocal,
|
||||
std::string(),
|
||||
path,
|
||||
registered_name);
|
||||
|
||||
content::ChildProcessSecurityPolicy* policy =
|
||||
content::ChildProcessSecurityPolicy::GetInstance();
|
||||
content::RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
|
||||
int renderer_id = render_view_host->GetProcess()->GetID();
|
||||
policy->GrantReadFileSystem(renderer_id, file_system_id);
|
||||
policy->GrantWriteFileSystem(renderer_id, file_system_id);
|
||||
policy->GrantCreateFileForFileSystem(renderer_id, file_system_id);
|
||||
policy->GrantDeleteFromFileSystem(renderer_id, file_system_id);
|
||||
|
||||
if (!policy->CanReadFile(renderer_id, path))
|
||||
policy->GrantReadFile(renderer_id, path);
|
||||
|
||||
return file_system_id;
|
||||
}
|
||||
|
||||
FileSystem CreateFileSystemStruct(
|
||||
content::WebContents* web_contents,
|
||||
const std::string& file_system_id,
|
||||
const std::string& registered_name,
|
||||
const std::string& file_system_path) {
|
||||
const GURL origin = web_contents->GetURL().GetOrigin();
|
||||
std::string file_system_name =
|
||||
storage::GetIsolatedFileSystemName(origin, file_system_id);
|
||||
std::string root_url = storage::GetIsolatedFileSystemRootURIString(
|
||||
origin, file_system_id, registered_name);
|
||||
return FileSystem(file_system_name, root_url, file_system_path);
|
||||
}
|
||||
|
||||
base::DictionaryValue* CreateFileSystemValue(const FileSystem& file_system) {
|
||||
base::DictionaryValue* file_system_value = new base::DictionaryValue();
|
||||
file_system_value->SetString("fileSystemName", file_system.file_system_name);
|
||||
file_system_value->SetString("rootURL", file_system.root_url);
|
||||
file_system_value->SetString("fileSystemPath", file_system.file_system_path);
|
||||
return file_system_value;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CommonWebContentsDelegate::CommonWebContentsDelegate(bool is_guest)
|
||||
: is_guest_(is_guest),
|
||||
owner_window_(nullptr),
|
||||
html_fullscreen_(false),
|
||||
native_fullscreen_(false) {
|
||||
}
|
||||
|
||||
CommonWebContentsDelegate::~CommonWebContentsDelegate() {
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::InitWithWebContents(
|
||||
content::WebContents* web_contents,
|
||||
NativeWindow* owner_window) {
|
||||
owner_window_ = owner_window;
|
||||
web_contents->SetDelegate(this);
|
||||
|
||||
// Tell renderer to handle all navigations in browser.
|
||||
auto preferences = web_contents->GetMutableRendererPrefs();
|
||||
preferences->browser_handles_non_local_top_level_requests = true;
|
||||
preferences->browser_handles_all_top_level_requests = true;
|
||||
web_contents->GetRenderViewHost()->SyncRendererPrefs();
|
||||
|
||||
// Create InspectableWebContents.
|
||||
web_contents_.reset(brightray::InspectableWebContents::Create(web_contents));
|
||||
web_contents_->SetDelegate(this);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DestroyWebContents() {
|
||||
web_contents_.reset();
|
||||
}
|
||||
|
||||
content::WebContents* CommonWebContentsDelegate::GetWebContents() const {
|
||||
if (!web_contents_)
|
||||
return nullptr;
|
||||
return web_contents_->GetWebContents();
|
||||
}
|
||||
|
||||
content::WebContents*
|
||||
CommonWebContentsDelegate::GetDevToolsWebContents() const {
|
||||
if (!web_contents_)
|
||||
return nullptr;
|
||||
return web_contents_->GetDevToolsWebContents();
|
||||
}
|
||||
|
||||
content::WebContents* CommonWebContentsDelegate::OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) {
|
||||
content::NavigationController::LoadURLParams load_url_params(params.url);
|
||||
load_url_params.referrer = params.referrer;
|
||||
load_url_params.transition_type = params.transition;
|
||||
load_url_params.extra_headers = params.extra_headers;
|
||||
load_url_params.should_replace_current_entry =
|
||||
params.should_replace_current_entry;
|
||||
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
||||
load_url_params.transferred_global_request_id =
|
||||
params.transferred_global_request_id;
|
||||
load_url_params.should_clear_history_list = true;
|
||||
|
||||
source->GetController().LoadURLWithParams(load_url_params);
|
||||
return source;
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::RequestToLockMouse(
|
||||
content::WebContents* web_contents,
|
||||
bool user_gesture,
|
||||
bool last_unlocked_by_target) {
|
||||
GetWebContents()->GotResponseToLockMouseRequest(true);
|
||||
}
|
||||
|
||||
bool CommonWebContentsDelegate::CanOverscrollContent() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CommonWebContentsDelegate::IsPopupOrPanel(
|
||||
const content::WebContents* source) const {
|
||||
return !is_guest_;
|
||||
}
|
||||
|
||||
content::JavaScriptDialogManager*
|
||||
CommonWebContentsDelegate::GetJavaScriptDialogManager(
|
||||
content::WebContents* source) {
|
||||
if (!dialog_manager_)
|
||||
dialog_manager_.reset(new AtomJavaScriptDialogManager);
|
||||
|
||||
return dialog_manager_.get();
|
||||
}
|
||||
|
||||
content::ColorChooser* CommonWebContentsDelegate::OpenColorChooser(
|
||||
content::WebContents* web_contents,
|
||||
SkColor color,
|
||||
const std::vector<content::ColorSuggestion>& suggestions) {
|
||||
return chrome::ShowColorChooser(web_contents, color);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::RunFileChooser(
|
||||
content::WebContents* guest,
|
||||
const content::FileChooserParams& params) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(owner_window_));
|
||||
web_dialog_helper_->RunFileChooser(guest, params);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::EnumerateDirectory(content::WebContents* guest,
|
||||
int request_id,
|
||||
const base::FilePath& path) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(owner_window_));
|
||||
web_dialog_helper_->EnumerateDirectory(guest, request_id, path);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::EnterFullscreenModeForTab(
|
||||
content::WebContents* source, const GURL& origin) {
|
||||
if (!owner_window_)
|
||||
return;
|
||||
SetHtmlApiFullscreen(true);
|
||||
owner_window_->NotifyWindowEnterHtmlFullScreen();
|
||||
source->GetRenderViewHost()->WasResized();
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::ExitFullscreenModeForTab(
|
||||
content::WebContents* source) {
|
||||
if (!owner_window_)
|
||||
return;
|
||||
SetHtmlApiFullscreen(false);
|
||||
owner_window_->NotifyWindowLeaveHtmlFullScreen();
|
||||
source->GetRenderViewHost()->WasResized();
|
||||
}
|
||||
|
||||
bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
|
||||
const content::WebContents* source) const {
|
||||
return html_fullscreen_;
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsSaveToFile(
|
||||
const std::string& url, const std::string& content, bool save_as) {
|
||||
base::FilePath path;
|
||||
PathsMap::iterator it = saved_files_.find(url);
|
||||
if (it != saved_files_.end() && !save_as) {
|
||||
path = it->second;
|
||||
} else {
|
||||
file_dialog::Filters filters;
|
||||
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
|
||||
if (!file_dialog::ShowSaveDialog(owner_window_, url, default_path,
|
||||
filters, &path)) {
|
||||
base::StringValue url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.canceledSaveURL", &url_value, nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
saved_files_[url] = path;
|
||||
base::WriteFile(path, content.data(), content.size());
|
||||
|
||||
// Notify devtools.
|
||||
base::StringValue url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.savedURL", &url_value, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsAppendToFile(
|
||||
const std::string& url, const std::string& content) {
|
||||
PathsMap::iterator it = saved_files_.find(url);
|
||||
if (it == saved_files_.end())
|
||||
return;
|
||||
base::AppendToFile(it->second, content.data(), content.size());
|
||||
|
||||
// Notify devtools.
|
||||
base::StringValue url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.appendedToURL", &url_value, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsAddFileSystem() {
|
||||
file_dialog::Filters filters;
|
||||
base::FilePath default_path;
|
||||
std::vector<base::FilePath> paths;
|
||||
int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
|
||||
if (!file_dialog::ShowOpenDialog(owner_window_, "", default_path,
|
||||
filters, flag, &paths))
|
||||
return;
|
||||
|
||||
base::FilePath path = paths[0];
|
||||
std::string registered_name;
|
||||
std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(),
|
||||
path,
|
||||
®istered_name);
|
||||
|
||||
WorkspaceMap::iterator it = saved_paths_.find(file_system_id);
|
||||
if (it != saved_paths_.end())
|
||||
return;
|
||||
|
||||
saved_paths_[file_system_id] = path;
|
||||
|
||||
FileSystem file_system = CreateFileSystemStruct(GetDevToolsWebContents(),
|
||||
file_system_id,
|
||||
registered_name,
|
||||
path.AsUTF8Unsafe());
|
||||
|
||||
scoped_ptr<base::StringValue> error_string_value(
|
||||
new base::StringValue(std::string()));
|
||||
scoped_ptr<base::DictionaryValue> file_system_value;
|
||||
if (!file_system.file_system_path.empty())
|
||||
file_system_value.reset(CreateFileSystemValue(file_system));
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.fileSystemAdded",
|
||||
error_string_value.get(),
|
||||
file_system_value.get(),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::DevToolsRemoveFileSystem(
|
||||
const std::string& file_system_path) {
|
||||
if (!web_contents_)
|
||||
return;
|
||||
|
||||
base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
|
||||
storage::IsolatedContext::GetInstance()->RevokeFileSystemByPath(path);
|
||||
|
||||
for (auto it = saved_paths_.begin(); it != saved_paths_.end(); ++it)
|
||||
if (it->second == path) {
|
||||
saved_paths_.erase(it);
|
||||
break;
|
||||
}
|
||||
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.fileSystemRemoved",
|
||||
&file_system_path_value,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::SetHtmlApiFullscreen(bool enter_fullscreen) {
|
||||
// Window is already in fullscreen mode, save the state.
|
||||
if (enter_fullscreen && owner_window_->IsFullscreen()) {
|
||||
native_fullscreen_ = true;
|
||||
html_fullscreen_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Exit html fullscreen state but not window's fullscreen mode.
|
||||
if (!enter_fullscreen && native_fullscreen_) {
|
||||
html_fullscreen_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
owner_window_->SetFullScreen(enter_fullscreen);
|
||||
html_fullscreen_ = enter_fullscreen;
|
||||
native_fullscreen_ = false;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
124
atom/browser/common_web_contents_delegate.h
Normal file
124
atom/browser/common_web_contents_delegate.h
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_COMMON_WEB_CONTENTS_DELEGATE_H_
|
||||
#define ATOM_BROWSER_COMMON_WEB_CONTENTS_DELEGATE_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "brightray/browser/default_web_contents_delegate.h"
|
||||
#include "brightray/browser/inspectable_web_contents_impl.h"
|
||||
#include "brightray/browser/inspectable_web_contents_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomJavaScriptDialogManager;
|
||||
class NativeWindow;
|
||||
class WebDialogHelper;
|
||||
|
||||
class CommonWebContentsDelegate
|
||||
: public brightray::DefaultWebContentsDelegate,
|
||||
public brightray::InspectableWebContentsDelegate {
|
||||
public:
|
||||
explicit CommonWebContentsDelegate(bool is_guest);
|
||||
virtual ~CommonWebContentsDelegate();
|
||||
|
||||
// Create a InspectableWebContents object and takes onwership of
|
||||
// |web_contents|.
|
||||
void InitWithWebContents(content::WebContents* web_contents,
|
||||
NativeWindow* owner_window);
|
||||
|
||||
// Destroy the managed InspectableWebContents object.
|
||||
void DestroyWebContents();
|
||||
|
||||
// Returns the WebContents managed by this delegate.
|
||||
content::WebContents* GetWebContents() const;
|
||||
|
||||
// Returns the WebContents of devtools.
|
||||
content::WebContents* GetDevToolsWebContents() const;
|
||||
|
||||
brightray::InspectableWebContents* managed_web_contents() const {
|
||||
return web_contents_.get();
|
||||
}
|
||||
|
||||
bool is_guest() const { return is_guest_; }
|
||||
|
||||
protected:
|
||||
// content::WebContentsDelegate:
|
||||
content::WebContents* OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) override;
|
||||
void RequestToLockMouse(content::WebContents* web_contents,
|
||||
bool user_gesture,
|
||||
bool last_unlocked_by_target) override;
|
||||
bool CanOverscrollContent() const override;
|
||||
bool IsPopupOrPanel(const content::WebContents* source) const override;
|
||||
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
|
||||
content::WebContents* source) override;
|
||||
content::ColorChooser* OpenColorChooser(
|
||||
content::WebContents* web_contents,
|
||||
SkColor color,
|
||||
const std::vector<content::ColorSuggestion>& suggestions) override;
|
||||
void RunFileChooser(content::WebContents* web_contents,
|
||||
const content::FileChooserParams& params) override;
|
||||
void EnumerateDirectory(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
const base::FilePath& path) override;
|
||||
void EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) override;
|
||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||
bool IsFullscreenForTabOrPending(
|
||||
const content::WebContents* source) const override;
|
||||
|
||||
// brightray::InspectableWebContentsDelegate:
|
||||
void DevToolsSaveToFile(const std::string& url,
|
||||
const std::string& content,
|
||||
bool save_as) override;
|
||||
void DevToolsAppendToFile(const std::string& url,
|
||||
const std::string& content) override;
|
||||
void DevToolsAddFileSystem() override;
|
||||
void DevToolsRemoveFileSystem(const std::string& file_system_path) override;
|
||||
|
||||
private:
|
||||
// Set fullscreen mode triggered by html api.
|
||||
void SetHtmlApiFullscreen(bool enter_fullscreen);
|
||||
|
||||
// Whether this is guest WebContents or NativeWindow.
|
||||
const bool is_guest_;
|
||||
|
||||
// The window that this WebContents belongs to.
|
||||
NativeWindow* owner_window_;
|
||||
|
||||
// Whether window is fullscreened by HTML5 api.
|
||||
bool html_fullscreen_;
|
||||
|
||||
// Whether window is fullscreened by window api.
|
||||
bool native_fullscreen_;
|
||||
|
||||
scoped_ptr<WebDialogHelper> web_dialog_helper_;
|
||||
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
|
||||
|
||||
// The stored InspectableWebContents object.
|
||||
// Notice that web_contents_ must be placed after dialog_manager_, so we can
|
||||
// make sure web_contents_ is destroyed before dialog_manager_, otherwise a
|
||||
// crash would happen.
|
||||
scoped_ptr<brightray::InspectableWebContents> web_contents_;
|
||||
|
||||
// Maps url to file path, used by the file requests sent from devtools.
|
||||
typedef std::map<std::string, base::FilePath> PathsMap;
|
||||
PathsMap saved_files_;
|
||||
|
||||
// Maps file system id to file path, used by the file system requests
|
||||
// sent from devtools.
|
||||
typedef std::map<std::string, base::FilePath> WorkspaceMap;
|
||||
WorkspaceMap saved_paths_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CommonWebContentsDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_COMMON_WEB_CONTENTS_DELEGATE_H_
|
||||
@@ -1,10 +1,7 @@
|
||||
var app = require('app');
|
||||
var Menu = require('menu');
|
||||
var MenuItem = require('menu-item');
|
||||
var BrowserWindow = require('browser-window');
|
||||
|
||||
var mainWindow = null;
|
||||
var menu = null;
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function() {
|
||||
@@ -15,221 +12,9 @@ app.on('ready', function() {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
resizable: false,
|
||||
'auto-hide-menu-bar': true,
|
||||
'use-content-size': true,
|
||||
});
|
||||
mainWindow.loadUrl('file://' + __dirname + '/index.html');
|
||||
mainWindow.focus();
|
||||
|
||||
if (process.platform == 'darwin') {
|
||||
var template = [
|
||||
{
|
||||
label: 'Electron',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About Electron',
|
||||
selector: 'orderFrontStandardAboutPanel:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Services',
|
||||
submenu: []
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Hide Electron',
|
||||
accelerator: 'Command+H',
|
||||
selector: 'hide:'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
selector: 'hideOtherApplications:'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
selector: 'unhideAllApplications:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: function() { app.quit(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'Command+Z',
|
||||
selector: 'undo:'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+Command+Z',
|
||||
selector: 'redo:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'Command+X',
|
||||
selector: 'cut:'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'Command+C',
|
||||
selector: 'copy:'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'Command+V',
|
||||
selector: 'paste:'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'Command+A',
|
||||
selector: 'selectAll:'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'Command+R',
|
||||
click: function() { mainWindow.restart(); }
|
||||
},
|
||||
{
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: 'Ctrl+Command+F',
|
||||
click: function() { mainWindow.setFullScreen(!mainWindow.isFullScreen()); }
|
||||
},
|
||||
{
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: 'Alt+Command+I',
|
||||
click: function() { mainWindow.toggleDevTools(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'Command+M',
|
||||
selector: 'performMiniaturize:'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'Command+W',
|
||||
selector: 'performClose:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
selector: 'arrangeInFront:'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
menu = Menu.buildFromTemplate(template);
|
||||
Menu.setApplicationMenu(menu);
|
||||
} else {
|
||||
var template = [
|
||||
{
|
||||
label: '&File',
|
||||
submenu: [
|
||||
{
|
||||
label: '&Open',
|
||||
accelerator: 'Ctrl+O',
|
||||
},
|
||||
{
|
||||
label: '&Close',
|
||||
accelerator: 'Ctrl+W',
|
||||
click: function() { mainWindow.close(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '&View',
|
||||
submenu: [
|
||||
{
|
||||
label: '&Reload',
|
||||
accelerator: 'Ctrl+R',
|
||||
click: function() { mainWindow.restart(); }
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Full Screen',
|
||||
accelerator: 'F11',
|
||||
click: function() { mainWindow.setFullScreen(!mainWindow.isFullScreen()); }
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Developer Tools',
|
||||
accelerator: 'Alt+Ctrl+I',
|
||||
click: function() { mainWindow.toggleDevTools(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
menu = Menu.buildFromTemplate(template);
|
||||
mainWindow.setMenu(menu);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,6 +2,8 @@ var app = require('app');
|
||||
var dialog = require('dialog');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var Menu = require('menu');
|
||||
var BrowserWindow = require('browser-window');
|
||||
|
||||
// Quit when all windows are closed and no other one is listening to this.
|
||||
app.on('window-all-closed', function() {
|
||||
@@ -29,6 +31,246 @@ for (var i in argv) {
|
||||
}
|
||||
}
|
||||
|
||||
// Create default menu.
|
||||
app.once('ready', function() {
|
||||
var template;
|
||||
if (process.platform == 'darwin') {
|
||||
template = [
|
||||
{
|
||||
label: 'Electron',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About Electron',
|
||||
selector: 'orderFrontStandardAboutPanel:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Services',
|
||||
submenu: []
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Hide Electron',
|
||||
accelerator: 'Command+H',
|
||||
selector: 'hide:'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Shift+H',
|
||||
selector: 'hideOtherApplications:'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
selector: 'unhideAllApplications:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: function() { app.quit(); }
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'Command+Z',
|
||||
selector: 'undo:'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+Command+Z',
|
||||
selector: 'redo:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'Command+X',
|
||||
selector: 'cut:'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'Command+C',
|
||||
selector: 'copy:'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'Command+V',
|
||||
selector: 'paste:'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'Command+A',
|
||||
selector: 'selectAll:'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'Command+R',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.reload();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: 'Ctrl+Command+F',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: 'Alt+Command+I',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.toggleDevTools();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'Command+M',
|
||||
selector: 'performMiniaturize:'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'Command+W',
|
||||
selector: 'performClose:'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
selector: 'arrangeInFront:'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
} else {
|
||||
template = [
|
||||
{
|
||||
label: '&File',
|
||||
submenu: [
|
||||
{
|
||||
label: '&Open',
|
||||
accelerator: 'Ctrl+O',
|
||||
},
|
||||
{
|
||||
label: '&Close',
|
||||
accelerator: 'Ctrl+W',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.close();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '&View',
|
||||
submenu: [
|
||||
{
|
||||
label: '&Reload',
|
||||
accelerator: 'Ctrl+R',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.reload();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Full Screen',
|
||||
accelerator: 'F11',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle &Developer Tools',
|
||||
accelerator: 'Alt+Ctrl+I',
|
||||
click: function() {
|
||||
var focusedWindow = BrowserWindow.getFocusedWindow();
|
||||
if (focusedWindow)
|
||||
focusedWindow.toggleDevTools();
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: function() { require('shell').openExternal('http://electron.atom.io') }
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme') }
|
||||
},
|
||||
{
|
||||
label: 'Community Discussions',
|
||||
click: function() { require('shell').openExternal('https://discuss.atom.io/c/electron') }
|
||||
},
|
||||
{
|
||||
label: 'Search Issues',
|
||||
click: function() { require('shell').openExternal('https://github.com/atom/electron/issues') }
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
var menu = Menu.buildFromTemplate(template);
|
||||
Menu.setApplicationMenu(menu);
|
||||
});
|
||||
|
||||
// Start the specified app if there is one specified in command line, otherwise
|
||||
// start the default app.
|
||||
if (option.file && !option.webdriver) {
|
||||
@@ -53,7 +295,7 @@ if (option.file && !option.webdriver) {
|
||||
} catch(e) {
|
||||
if (e.code == 'MODULE_NOT_FOUND') {
|
||||
app.focus();
|
||||
dialog.showErrorBox('Error opening app', 'The app provided is not a valid electron app, please read the docs on how to write one:\nhttps://github.com/atom/electron/tree/master/docs');
|
||||
dialog.showErrorBox('Error opening app', 'The app provided is not a valid electron app, please read the docs on how to write one:\nhttps://github.com/atom/electron/tree/master/docs\n\n' + e.toString());
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.error('App threw an error when running', e);
|
||||
|
||||
@@ -41,7 +41,6 @@ createGuest = (embedder, params) ->
|
||||
guest = webContents.create
|
||||
isGuest: true
|
||||
guestInstanceId: id
|
||||
storagePartitionId: params.storagePartitionId
|
||||
guestInstances[id] = {guest, embedder}
|
||||
|
||||
# Destroy guest when the embedder is gone or navigated.
|
||||
@@ -58,9 +57,14 @@ createGuest = (embedder, params) ->
|
||||
delete @attachParams
|
||||
|
||||
@viewInstanceId = params.instanceId
|
||||
min = width: params.minwidth, height: params.minheight
|
||||
max = width: params.maxwidth, height: params.maxheight
|
||||
@setAutoSize params.autosize, min, max
|
||||
@setSize
|
||||
normal:
|
||||
width: params.elementWidth, height: params.elementHeight
|
||||
enableAutoSize: params.autosize
|
||||
min:
|
||||
width: params.minwidth, height: params.minheight
|
||||
max:
|
||||
width: params.maxwidth, height: params.maxheight
|
||||
|
||||
if params.src
|
||||
opts = {}
|
||||
@@ -123,7 +127,7 @@ destroyGuest = (embedder, id) ->
|
||||
delete reverseEmbedderElementsMap[id]
|
||||
delete embedderElementsMap[key]
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, type, params, requestId) ->
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, params, requestId) ->
|
||||
event.sender.send "ATOM_SHELL_RESPONSE_#{requestId}", createGuest(event.sender, params)
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId, guestInstanceId, params) ->
|
||||
@@ -132,8 +136,8 @@ ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId,
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
|
||||
destroyGuest event.sender, id
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', (event, id, params) ->
|
||||
guestInstances[id]?.guest.setAutoSize params.enableAutoSize, params.min, params.max
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', (event, id, params) ->
|
||||
guestInstances[id]?.guest.setSize params
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', (event, id, allowtransparency) ->
|
||||
guestInstances[id]?.guest.setAllowTransparency allowtransparency
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_javascript_dialog_manager.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "atom/browser/web_dialog_helper.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
@@ -31,16 +28,12 @@
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||
#include "chrome/browser/ui/browser_dialogs.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/invalidate_type.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
#include "content/public/browser/notification_details.h"
|
||||
#include "content/public/browser/notification_source.h"
|
||||
#include "content/public/browser/notification_types.h"
|
||||
#include "content/public/browser/plugin_service.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
@@ -78,6 +71,7 @@ const char* kWebRuntimeFeatures[] = {
|
||||
switches::kOverlayScrollbars,
|
||||
switches::kOverlayFullscreenVideo,
|
||||
switches::kSharedWorker,
|
||||
switches::kPageVisibility,
|
||||
};
|
||||
|
||||
std::string RemoveWhitespace(const std::string& str) {
|
||||
@@ -92,21 +86,20 @@ std::string RemoveWhitespace(const std::string& str) {
|
||||
|
||||
NativeWindow::NativeWindow(content::WebContents* web_contents,
|
||||
const mate::Dictionary& options)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
: CommonWebContentsDelegate(false),
|
||||
content::WebContentsObserver(web_contents),
|
||||
has_frame_(true),
|
||||
transparent_(false),
|
||||
enable_larger_than_screen_(false),
|
||||
is_closed_(false),
|
||||
node_integration_(true),
|
||||
has_dialog_attached_(false),
|
||||
html_fullscreen_(false),
|
||||
native_fullscreen_(false),
|
||||
zoom_factor_(1.0),
|
||||
weak_factory_(this),
|
||||
inspectable_web_contents_(
|
||||
brightray::InspectableWebContents::Create(web_contents)) {
|
||||
weak_factory_(this) {
|
||||
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
|
||||
|
||||
InitWithWebContents(web_contents, this);
|
||||
|
||||
options.Get(switches::kFrame, &has_frame_);
|
||||
options.Get(switches::kTransparent, &transparent_);
|
||||
options.Get(switches::kEnableLargerThanScreen, &enable_larger_than_screen_);
|
||||
@@ -138,9 +131,6 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
|
||||
// Read the zoom factor before any navigation.
|
||||
options.Get(switches::kZoomFactor, &zoom_factor_);
|
||||
|
||||
web_contents->SetDelegate(this);
|
||||
inspectable_web_contents()->SetDelegate(this);
|
||||
|
||||
WindowList::AddWindow(this);
|
||||
|
||||
// Override the user agent to contain application and atom-shell's version.
|
||||
@@ -294,37 +284,6 @@ bool NativeWindow::HasModalDialog() {
|
||||
return has_dialog_attached_;
|
||||
}
|
||||
|
||||
void NativeWindow::OpenDevTools(bool can_dock) {
|
||||
inspectable_web_contents()->SetCanDock(can_dock);
|
||||
inspectable_web_contents()->ShowDevTools();
|
||||
}
|
||||
|
||||
void NativeWindow::CloseDevTools() {
|
||||
inspectable_web_contents()->CloseDevTools();
|
||||
}
|
||||
|
||||
bool NativeWindow::IsDevToolsOpened() {
|
||||
return inspectable_web_contents()->IsDevToolsViewShowing();
|
||||
}
|
||||
|
||||
void NativeWindow::InspectElement(int x, int y) {
|
||||
OpenDevTools(true);
|
||||
scoped_refptr<content::DevToolsAgentHost> agent(
|
||||
content::DevToolsAgentHost::GetOrCreateFor(GetWebContents()));
|
||||
agent->InspectElement(x, y);
|
||||
}
|
||||
|
||||
void NativeWindow::InspectServiceWorker() {
|
||||
for (const auto& agent_host : content::DevToolsAgentHost::GetOrCreateAll()) {
|
||||
if (agent_host->GetType() ==
|
||||
content::DevToolsAgentHost::TYPE_SERVICE_WORKER) {
|
||||
OpenDevTools(true);
|
||||
inspectable_web_contents()->AttachTo(agent_host);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindow::FocusOnWebView() {
|
||||
GetWebContents()->GetRenderViewHost()->Focus();
|
||||
}
|
||||
@@ -373,13 +332,6 @@ void NativeWindow::CapturePage(const gfx::Rect& rect,
|
||||
kBGRA_8888_SkColorType);
|
||||
}
|
||||
|
||||
void NativeWindow::DestroyWebContents() {
|
||||
if (!inspectable_web_contents_)
|
||||
return;
|
||||
|
||||
inspectable_web_contents_.reset();
|
||||
}
|
||||
|
||||
void NativeWindow::CloseWebContents() {
|
||||
bool prevent_default = false;
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver,
|
||||
@@ -409,20 +361,8 @@ void NativeWindow::CloseWebContents() {
|
||||
web_contents->Close();
|
||||
}
|
||||
|
||||
content::WebContents* NativeWindow::GetWebContents() const {
|
||||
if (!inspectable_web_contents_)
|
||||
return nullptr;
|
||||
return inspectable_web_contents()->GetWebContents();
|
||||
}
|
||||
|
||||
content::WebContents* NativeWindow::GetDevToolsWebContents() const {
|
||||
if (!inspectable_web_contents_)
|
||||
return nullptr;
|
||||
return inspectable_web_contents()->devtools_web_contents();
|
||||
}
|
||||
|
||||
void NativeWindow::AppendExtraCommandLineSwitches(
|
||||
base::CommandLine* command_line, int child_process_id) {
|
||||
base::CommandLine* command_line) {
|
||||
// Append --node-integration to renderer process.
|
||||
command_line->AppendSwitchASCII(switches::kNodeIntegration,
|
||||
node_integration_ ? "true" : "false");
|
||||
@@ -489,25 +429,6 @@ void NativeWindow::OverrideWebkitPrefs(content::WebPreferences* prefs) {
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindow::SetHtmlApiFullscreen(bool enter_fullscreen) {
|
||||
// Window is already in fullscreen mode, save the state.
|
||||
if (enter_fullscreen && IsFullscreen()) {
|
||||
native_fullscreen_ = true;
|
||||
html_fullscreen_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Exit html fullscreen state but not window's fullscreen mode.
|
||||
if (!enter_fullscreen && native_fullscreen_) {
|
||||
html_fullscreen_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
SetFullScreen(enter_fullscreen);
|
||||
html_fullscreen_ = enter_fullscreen;
|
||||
native_fullscreen_ = false;
|
||||
}
|
||||
|
||||
void NativeWindow::NotifyWindowClosed() {
|
||||
if (is_closed_)
|
||||
return;
|
||||
@@ -621,27 +542,7 @@ content::WebContents* NativeWindow::OpenURLFromTab(
|
||||
if (prevent_default)
|
||||
return nullptr;
|
||||
|
||||
content::NavigationController::LoadURLParams load_url_params(params.url);
|
||||
load_url_params.referrer = params.referrer;
|
||||
load_url_params.transition_type = params.transition;
|
||||
load_url_params.extra_headers = params.extra_headers;
|
||||
load_url_params.should_replace_current_entry =
|
||||
params.should_replace_current_entry;
|
||||
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
||||
load_url_params.transferred_global_request_id =
|
||||
params.transferred_global_request_id;
|
||||
load_url_params.should_clear_history_list = true;
|
||||
|
||||
source->GetController().LoadURLWithParams(load_url_params);
|
||||
return source;
|
||||
}
|
||||
|
||||
content::JavaScriptDialogManager* NativeWindow::GetJavaScriptDialogManager(
|
||||
content::WebContents* source) {
|
||||
if (!dialog_manager_)
|
||||
dialog_manager_.reset(new AtomJavaScriptDialogManager);
|
||||
|
||||
return dialog_manager_.get();
|
||||
return CommonWebContentsDelegate::OpenURLFromTab(source, params);
|
||||
}
|
||||
|
||||
void NativeWindow::RenderViewCreated(
|
||||
@@ -669,38 +570,6 @@ void NativeWindow::BeforeUnloadFired(content::WebContents* tab,
|
||||
}
|
||||
}
|
||||
|
||||
content::ColorChooser* NativeWindow::OpenColorChooser(
|
||||
content::WebContents* web_contents,
|
||||
SkColor color,
|
||||
const std::vector<content::ColorSuggestion>& suggestions) {
|
||||
return chrome::ShowColorChooser(web_contents, color);
|
||||
}
|
||||
|
||||
void NativeWindow::RunFileChooser(content::WebContents* web_contents,
|
||||
const content::FileChooserParams& params) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(this));
|
||||
web_dialog_helper_->RunFileChooser(web_contents, params);
|
||||
}
|
||||
|
||||
void NativeWindow::EnumerateDirectory(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
const base::FilePath& path) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(this));
|
||||
web_dialog_helper_->EnumerateDirectory(web_contents, request_id, path);
|
||||
}
|
||||
|
||||
void NativeWindow::RequestToLockMouse(content::WebContents* web_contents,
|
||||
bool user_gesture,
|
||||
bool last_unlocked_by_target) {
|
||||
GetWebContents()->GotResponseToLockMouseRequest(true);
|
||||
}
|
||||
|
||||
bool NativeWindow::CanOverscrollContent() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void NativeWindow::ActivateContents(content::WebContents* contents) {
|
||||
FocusOnWebView();
|
||||
}
|
||||
@@ -729,11 +598,6 @@ void NativeWindow::CloseContents(content::WebContents* source) {
|
||||
window_unresposive_closure_.Cancel();
|
||||
}
|
||||
|
||||
bool NativeWindow::IsPopupOrPanel(const content::WebContents* source) const {
|
||||
// Only popup window can use things like window.moveTo.
|
||||
return true;
|
||||
}
|
||||
|
||||
void NativeWindow::RendererUnresponsive(content::WebContents* source) {
|
||||
// Schedule the unresponsive shortly later, since we may receive the
|
||||
// responsive event soon. This could happen after the whole application had
|
||||
@@ -750,20 +614,6 @@ void NativeWindow::RendererResponsive(content::WebContents* source) {
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive());
|
||||
}
|
||||
|
||||
void NativeWindow::EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) {
|
||||
SetHtmlApiFullscreen(true);
|
||||
}
|
||||
|
||||
void NativeWindow::ExitFullscreenModeForTab(content::WebContents* source) {
|
||||
SetHtmlApiFullscreen(false);
|
||||
}
|
||||
|
||||
bool NativeWindow::IsFullscreenForTabOrPending(
|
||||
const content::WebContents* source) const {
|
||||
return is_html_api_fullscreen();
|
||||
}
|
||||
|
||||
void NativeWindow::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
|
||||
// Do nothing, we override this method just to avoid compilation error since
|
||||
// there are two virtual functions named BeforeUnloadFired.
|
||||
@@ -800,47 +650,18 @@ void NativeWindow::Observe(int type,
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindow::DevToolsSaveToFile(const std::string& url,
|
||||
const std::string& content,
|
||||
bool save_as) {
|
||||
base::FilePath path;
|
||||
PathsMap::iterator it = saved_files_.find(url);
|
||||
if (it != saved_files_.end() && !save_as) {
|
||||
path = it->second;
|
||||
} else {
|
||||
file_dialog::Filters filters;
|
||||
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
|
||||
if (!file_dialog::ShowSaveDialog(this, url, default_path, filters, &path)) {
|
||||
base::StringValue url_value(url);
|
||||
CallDevToolsFunction("DevToolsAPI.canceledSaveURL", &url_value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
saved_files_[url] = path;
|
||||
base::WriteFile(path, content.data(), content.size());
|
||||
|
||||
// Notify devtools.
|
||||
base::StringValue url_value(url);
|
||||
CallDevToolsFunction("DevToolsAPI.savedURL", &url_value);
|
||||
}
|
||||
|
||||
void NativeWindow::DevToolsAppendToFile(const std::string& url,
|
||||
const std::string& content) {
|
||||
PathsMap::iterator it = saved_files_.find(url);
|
||||
if (it == saved_files_.end())
|
||||
return;
|
||||
base::AppendToFile(it->second, content.data(), content.size());
|
||||
|
||||
// Notify devtools.
|
||||
base::StringValue url_value(url);
|
||||
CallDevToolsFunction("DevToolsAPI.appendedToURL", &url_value);
|
||||
}
|
||||
|
||||
void NativeWindow::DevToolsFocused() {
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus());
|
||||
}
|
||||
|
||||
void NativeWindow::DevToolsOpened() {
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsOpened());
|
||||
}
|
||||
|
||||
void NativeWindow::DevToolsClosed() {
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed());
|
||||
}
|
||||
|
||||
void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
|
||||
if (!window_unresposive_closure_.IsCancelled())
|
||||
return;
|
||||
@@ -869,27 +690,4 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
|
||||
callback.Run(bitmap);
|
||||
}
|
||||
|
||||
void NativeWindow::CallDevToolsFunction(const std::string& function_name,
|
||||
const base::Value* arg1,
|
||||
const base::Value* arg2,
|
||||
const base::Value* arg3) {
|
||||
std::string params;
|
||||
if (arg1) {
|
||||
std::string json;
|
||||
base::JSONWriter::Write(arg1, &json);
|
||||
params.append(json);
|
||||
if (arg2) {
|
||||
base::JSONWriter::Write(arg2, &json);
|
||||
params.append(", " + json);
|
||||
if (arg3) {
|
||||
base::JSONWriter::Write(arg3, &json);
|
||||
params.append(", " + json);
|
||||
}
|
||||
}
|
||||
}
|
||||
base::string16 javascript =
|
||||
base::UTF8ToUTF16(function_name + "(" + params + ");");
|
||||
GetDevToolsWebContents()->GetMainFrame()->ExecuteJavaScript(javascript);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -9,15 +9,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "atom/browser/native_window_observer.h"
|
||||
#include "atom/browser/ui/accelerator_util.h"
|
||||
#include "base/cancelable_callback.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "brightray/browser/default_web_contents_delegate.h"
|
||||
#include "brightray/browser/inspectable_web_contents_delegate.h"
|
||||
#include "brightray/browser/inspectable_web_contents_impl.h"
|
||||
#include "content/public/browser/notification_registrar.h"
|
||||
#include "content/public/browser/notification_observer.h"
|
||||
#include "content/public/browser/readback_types.h"
|
||||
@@ -50,12 +48,9 @@ class MenuModel;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomJavaScriptDialogManager;
|
||||
struct DraggableRegion;
|
||||
class WebDialogHelper;
|
||||
|
||||
class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
public brightray::InspectableWebContentsDelegate,
|
||||
class NativeWindow : public CommonWebContentsDelegate,
|
||||
public content::WebContentsObserver,
|
||||
public content::NotificationObserver {
|
||||
public:
|
||||
@@ -149,11 +144,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
virtual bool IsVisibleOnAllWorkspaces() = 0;
|
||||
|
||||
virtual bool IsClosed() const { return is_closed_; }
|
||||
virtual void OpenDevTools(bool can_dock);
|
||||
virtual void CloseDevTools();
|
||||
virtual bool IsDevToolsOpened();
|
||||
virtual void InspectElement(int x, int y);
|
||||
virtual void InspectServiceWorker();
|
||||
|
||||
virtual void FocusOnWebView();
|
||||
virtual void BlurWebView();
|
||||
@@ -181,24 +171,14 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
// Should be called by platform code when user want to close the window.
|
||||
virtual void CloseWebContents();
|
||||
|
||||
// Destroy the WebContents immediately.
|
||||
virtual void DestroyWebContents();
|
||||
|
||||
base::WeakPtr<NativeWindow> GetWeakPtr() {
|
||||
return weak_factory_.GetWeakPtr();
|
||||
}
|
||||
|
||||
content::WebContents* GetWebContents() const;
|
||||
content::WebContents* GetDevToolsWebContents() const;
|
||||
|
||||
// Called when renderer process is going to be started.
|
||||
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
|
||||
int child_process_id);
|
||||
void AppendExtraCommandLineSwitches(base::CommandLine* command_line);
|
||||
void OverrideWebkitPrefs(content::WebPreferences* prefs);
|
||||
|
||||
// Set fullscreen mode triggered by html api.
|
||||
void SetHtmlApiFullscreen(bool enter_fullscreen);
|
||||
|
||||
// Public API used by platform-dependent delegates and observers to send UI
|
||||
// related notifications.
|
||||
void NotifyWindowClosed();
|
||||
@@ -224,9 +204,11 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
observers_.RemoveObserver(obs);
|
||||
}
|
||||
|
||||
bool has_frame() const { return has_frame_; }
|
||||
brightray::InspectableWebContents* inspectable_web_contents() const {
|
||||
return managed_web_contents();
|
||||
}
|
||||
|
||||
bool is_html_api_fullscreen() const { return html_fullscreen_; }
|
||||
bool has_frame() const { return has_frame_; }
|
||||
|
||||
void set_has_dialog_attached(bool has_dialog_attached) {
|
||||
has_dialog_attached_ = has_dialog_attached;
|
||||
@@ -236,11 +218,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
explicit NativeWindow(content::WebContents* web_contents,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
brightray::InspectableWebContentsImpl* inspectable_web_contents() const {
|
||||
return static_cast<brightray::InspectableWebContentsImpl*>(
|
||||
inspectable_web_contents_.get());
|
||||
}
|
||||
|
||||
// Called when the window needs to update its draggable region.
|
||||
virtual void UpdateDraggableRegions(
|
||||
const std::vector<DraggableRegion>& regions) = 0;
|
||||
@@ -258,38 +235,16 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
content::WebContents* OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) override;
|
||||
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
|
||||
content::WebContents* source) override;
|
||||
void BeforeUnloadFired(content::WebContents* tab,
|
||||
bool proceed,
|
||||
bool* proceed_to_fire_unload) override;
|
||||
content::ColorChooser* OpenColorChooser(
|
||||
content::WebContents* web_contents,
|
||||
SkColor color,
|
||||
const std::vector<content::ColorSuggestion>& suggestions) override;
|
||||
void RunFileChooser(content::WebContents* web_contents,
|
||||
const content::FileChooserParams& params) override;
|
||||
void EnumerateDirectory(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
const base::FilePath& path) override;
|
||||
void RequestToLockMouse(content::WebContents* web_contents,
|
||||
bool user_gesture,
|
||||
bool last_unlocked_by_target) override;
|
||||
bool CanOverscrollContent() const override;
|
||||
void ActivateContents(content::WebContents* contents) override;
|
||||
void DeactivateContents(content::WebContents* contents) override;
|
||||
void MoveContents(content::WebContents* source,
|
||||
const gfx::Rect& pos) override;
|
||||
void CloseContents(content::WebContents* source) override;
|
||||
bool IsPopupOrPanel(
|
||||
const content::WebContents* source) const override;
|
||||
void RendererUnresponsive(content::WebContents* source) override;
|
||||
void RendererResponsive(content::WebContents* source) override;
|
||||
void EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) override;
|
||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||
bool IsFullscreenForTabOrPending(
|
||||
const content::WebContents* source) const override;
|
||||
|
||||
// Implementations of content::WebContentsObserver.
|
||||
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
||||
@@ -302,12 +257,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
const content::NotificationDetails& details) override;
|
||||
|
||||
// Implementations of brightray::InspectableWebContentsDelegate.
|
||||
void DevToolsSaveToFile(const std::string& url,
|
||||
const std::string& content,
|
||||
bool save_as) override;
|
||||
void DevToolsAppendToFile(const std::string& url,
|
||||
const std::string& content) override;
|
||||
void DevToolsFocused() override;
|
||||
void DevToolsOpened() override;
|
||||
void DevToolsClosed() override;
|
||||
|
||||
// Whether window has standard frame.
|
||||
bool has_frame_;
|
||||
@@ -328,12 +280,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
// Dispatch unresponsive event to observers.
|
||||
void NotifyWindowUnresponsive();
|
||||
|
||||
// Call a function in devtools.
|
||||
void CallDevToolsFunction(const std::string& function_name,
|
||||
const base::Value* arg1 = NULL,
|
||||
const base::Value* arg2 = NULL,
|
||||
const base::Value* arg3 = NULL);
|
||||
|
||||
// Called when CapturePage has done.
|
||||
void OnCapturePageDone(const CapturePageCallback& callback,
|
||||
const SkBitmap& bitmap,
|
||||
@@ -354,12 +300,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
// There is a dialog that has been attached to window.
|
||||
bool has_dialog_attached_;
|
||||
|
||||
// Whether window is fullscreened by HTML5 api.
|
||||
bool html_fullscreen_;
|
||||
|
||||
// Whether window is fullscreened by window api.
|
||||
bool native_fullscreen_;
|
||||
|
||||
// Closure that would be called when window is unresponsive when closing,
|
||||
// it should be cancelled when we can prove that the window is responsive.
|
||||
base::CancelableClosure window_unresposive_closure_;
|
||||
@@ -375,18 +315,6 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
|
||||
base::WeakPtrFactory<NativeWindow> weak_factory_;
|
||||
|
||||
scoped_ptr<WebDialogHelper> web_dialog_helper_;
|
||||
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
|
||||
|
||||
// Notice that inspectable_web_contents_ must be placed after dialog_manager_,
|
||||
// so we can make sure inspectable_web_contents_ is destroyed before
|
||||
// dialog_manager_, otherwise a crash would happen.
|
||||
scoped_ptr<brightray::InspectableWebContents> inspectable_web_contents_;
|
||||
|
||||
// Maps url to file path, used by the file requests sent from devtools.
|
||||
typedef std::map<std::string, base::FilePath> PathsMap;
|
||||
PathsMap saved_files_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeWindow);
|
||||
};
|
||||
|
||||
|
||||
@@ -55,8 +55,10 @@ class NativeWindowObserver {
|
||||
virtual void OnWindowEnterHtmlFullScreen() {}
|
||||
virtual void OnWindowLeaveHtmlFullScreen() {}
|
||||
|
||||
// Called when devtools window gets focused.
|
||||
// Redirect devtools events.
|
||||
virtual void OnDevToolsFocus() {}
|
||||
virtual void OnDevToolsOpened() {}
|
||||
virtual void OnDevToolsClosed() {}
|
||||
|
||||
// Called when renderer is hung.
|
||||
virtual void OnRendererUnresponsive() {}
|
||||
|
||||
@@ -541,6 +541,19 @@ bool NativeWindowViews::IsKiosk() {
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
|
||||
if (menu_model == nullptr) {
|
||||
// Remove accelerators
|
||||
accelerator_table_.clear();
|
||||
GetFocusManager()->UnregisterAccelerators(this);
|
||||
// and menu bar.
|
||||
#if defined(USE_X11)
|
||||
global_menu_bar_.reset();
|
||||
#endif
|
||||
SetMenuBarVisibility(false);
|
||||
menu_bar_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
RegisterAccelerators(menu_model);
|
||||
|
||||
#if defined(USE_X11)
|
||||
@@ -713,7 +726,8 @@ void NativeWindowViews::OnWidgetActivationChanged(
|
||||
else
|
||||
NotifyWindowBlur();
|
||||
|
||||
if (active && GetWebContents() && !IsDevToolsOpened())
|
||||
if (active && GetWebContents() &&
|
||||
!inspectable_web_contents()->IsDevToolsViewShowing())
|
||||
GetWebContents()->Focus();
|
||||
|
||||
// Hide menu bar when window is blured.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>atom.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.27.0</string>
|
||||
<string>0.27.3</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.8.0</string>
|
||||
<key>NSMainNibFile</key>
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,27,0,0
|
||||
PRODUCTVERSION 0,27,0,0
|
||||
FILEVERSION 0,27,3,0
|
||||
PRODUCTVERSION 0,27,3,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -68,12 +68,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "0.27.0"
|
||||
VALUE "FileVersion", "0.27.3"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "0.27.0"
|
||||
VALUE "ProductVersion", "0.27.3"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -12,10 +12,9 @@ namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
WebViewManager* GetManagerFromProcess(content::RenderProcessHost* process) {
|
||||
if (!process)
|
||||
return nullptr;
|
||||
auto context = process->GetBrowserContext();
|
||||
WebViewManager* GetManagerFromWebContents(
|
||||
const content::WebContents* web_contents) {
|
||||
auto context = web_contents->GetBrowserContext();
|
||||
if (!context)
|
||||
return nullptr;
|
||||
return static_cast<WebViewManager*>(context->GetGuestManager());
|
||||
@@ -24,28 +23,17 @@ WebViewManager* GetManagerFromProcess(content::RenderProcessHost* process) {
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
bool WebViewManager::GetInfoForProcess(content::RenderProcessHost* process,
|
||||
WebViewInfo* info) {
|
||||
auto manager = GetManagerFromProcess(process);
|
||||
bool WebViewManager::GetInfoForWebContents(
|
||||
const content::WebContents* web_contents, WebViewInfo* info) {
|
||||
auto manager = GetManagerFromWebContents(web_contents);
|
||||
if (!manager)
|
||||
return false;
|
||||
return manager->GetInfo(process->GetID(), info);
|
||||
}
|
||||
|
||||
// static
|
||||
void WebViewManager::UpdateGuestProcessID(
|
||||
content::RenderProcessHost* old_process,
|
||||
content::RenderProcessHost* new_process) {
|
||||
auto manager = GetManagerFromProcess(old_process);
|
||||
if (manager) {
|
||||
base::AutoLock auto_lock(manager->lock_);
|
||||
int old_id = old_process->GetID();
|
||||
int new_id = new_process->GetID();
|
||||
if (!ContainsKey(manager->webview_info_map_, old_id))
|
||||
return;
|
||||
manager->webview_info_map_[new_id] = manager->webview_info_map_[old_id];
|
||||
manager->webview_info_map_.erase(old_id);
|
||||
}
|
||||
base::AutoLock auto_lock(manager->lock_);
|
||||
auto iter = manager->webview_info_map_.find(web_contents);
|
||||
if (iter == manager->webview_info_map_.end())
|
||||
return false;
|
||||
*info = iter->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
WebViewManager::WebViewManager(content::BrowserContext* context) {
|
||||
@@ -61,9 +49,7 @@ void WebViewManager::AddGuest(int guest_instance_id,
|
||||
const WebViewInfo& info) {
|
||||
base::AutoLock auto_lock(lock_);
|
||||
web_contents_embdder_map_[guest_instance_id] = { web_contents, embedder };
|
||||
|
||||
int guest_process_id = web_contents->GetRenderProcessHost()->GetID();
|
||||
webview_info_map_[guest_process_id] = info;
|
||||
webview_info_map_[web_contents] = info;
|
||||
|
||||
// Map the element in embedder to guest.
|
||||
int owner_process_id = embedder->GetRenderProcessHost()->GetID();
|
||||
@@ -78,9 +64,7 @@ void WebViewManager::RemoveGuest(int guest_instance_id) {
|
||||
|
||||
auto web_contents = web_contents_embdder_map_[guest_instance_id].web_contents;
|
||||
web_contents_embdder_map_.erase(guest_instance_id);
|
||||
|
||||
int guest_process_id = web_contents->GetRenderProcessHost()->GetID();
|
||||
webview_info_map_.erase(guest_process_id);
|
||||
webview_info_map_.erase(web_contents);
|
||||
|
||||
// Remove the record of element in embedder too.
|
||||
for (const auto& element : element_instance_id_to_guest_map_)
|
||||
@@ -90,16 +74,6 @@ void WebViewManager::RemoveGuest(int guest_instance_id) {
|
||||
}
|
||||
}
|
||||
|
||||
bool WebViewManager::GetInfo(int guest_process_id, WebViewInfo* webview_info) {
|
||||
base::AutoLock auto_lock(lock_);
|
||||
WebViewInfoMap::iterator iter = webview_info_map_.find(guest_process_id);
|
||||
if (iter != webview_info_map_.end()) {
|
||||
*webview_info = iter->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
content::WebContents* WebViewManager::GetGuestByInstanceID(
|
||||
int owner_process_id,
|
||||
int element_instance_id) {
|
||||
|
||||
@@ -29,14 +29,10 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
||||
base::FilePath preload_script;
|
||||
};
|
||||
|
||||
// Finds the WebViewManager attached with |process| and returns the
|
||||
// Finds the WebViewManager attached with |web_contents| and returns the
|
||||
// WebViewInfo of it.
|
||||
static bool GetInfoForProcess(content::RenderProcessHost* process,
|
||||
WebViewInfo* info);
|
||||
|
||||
// Updates the guest process ID.
|
||||
static void UpdateGuestProcessID(content::RenderProcessHost* old_process,
|
||||
content::RenderProcessHost* new_process);
|
||||
static bool GetInfoForWebContents(const content::WebContents* web_contents,
|
||||
WebViewInfo* info);
|
||||
|
||||
explicit WebViewManager(content::BrowserContext* context);
|
||||
virtual ~WebViewManager();
|
||||
@@ -48,10 +44,6 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
||||
const WebViewInfo& info);
|
||||
void RemoveGuest(int guest_instance_id);
|
||||
|
||||
// Looks up the information for the embedder <webview> for a given render
|
||||
// view, if one exists. Called on the IO thread.
|
||||
bool GetInfo(int guest_process_id, WebViewInfo* webview_info);
|
||||
|
||||
protected:
|
||||
// content::BrowserPluginGuestManager:
|
||||
content::WebContents* GetGuestByInstanceID(int owner_process_id,
|
||||
@@ -89,8 +81,8 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
||||
// (embedder_process_id, element_instance_id) => guest_instance_id
|
||||
std::map<ElementInstanceKey, int> element_instance_id_to_guest_map_;
|
||||
|
||||
typedef std::map<int, WebViewInfo> WebViewInfoMap;
|
||||
// guest_process_id => (guest_instance_id, embedder, ...)
|
||||
typedef std::map<const content::WebContents*, WebViewInfo> WebViewInfoMap;
|
||||
// web_contents => (guest_instance_id, embedder, ...)
|
||||
WebViewInfoMap webview_info_map_;
|
||||
|
||||
base::Lock lock_;
|
||||
|
||||
@@ -37,6 +37,14 @@ struct Converter<ui::ClipboardType> {
|
||||
|
||||
namespace {
|
||||
|
||||
std::vector<base::string16> AvailableFormats(ui::ClipboardType type) {
|
||||
std::vector<base::string16> format_types;
|
||||
bool ignore;
|
||||
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
|
||||
clipboard->ReadAvailableTypes(type, &format_types, &ignore);
|
||||
return format_types;
|
||||
}
|
||||
|
||||
bool Has(const std::string& format_string, ui::ClipboardType type) {
|
||||
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
|
||||
ui::Clipboard::FormatType format(ui::Clipboard::GetFormatType(format_string));
|
||||
@@ -64,6 +72,24 @@ void WriteText(const base::string16& text, ui::ClipboardType type) {
|
||||
writer.WriteText(text);
|
||||
}
|
||||
|
||||
base::string16 ReadHtml(ui::ClipboardType type) {
|
||||
base::string16 data;
|
||||
base::string16 html;
|
||||
std::string url;
|
||||
uint32 start;
|
||||
uint32 end;
|
||||
ui::Clipboard::GetForCurrentThread()->ReadHTML(type, &html, &url,
|
||||
&start, &end);
|
||||
data = html.substr(start, end - start);
|
||||
return data;
|
||||
}
|
||||
|
||||
void WriteHtml(const base::string16& html,
|
||||
ui::ClipboardType type) {
|
||||
ui::ScopedClipboardWriter writer(type);
|
||||
writer.WriteHTML(html, std::string());
|
||||
}
|
||||
|
||||
gfx::Image ReadImage(ui::ClipboardType type) {
|
||||
SkBitmap bitmap = ui::Clipboard::GetForCurrentThread()->ReadImage(type);
|
||||
return gfx::Image::CreateFrom1xBitmap(bitmap);
|
||||
@@ -81,10 +107,13 @@ void Clear(ui::ClipboardType type) {
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("_availableFormats", &AvailableFormats);
|
||||
dict.SetMethod("_has", &Has);
|
||||
dict.SetMethod("_read", &Read);
|
||||
dict.SetMethod("_readText", &ReadText);
|
||||
dict.SetMethod("_writeText", &WriteText);
|
||||
dict.SetMethod("_readHtml", &ReadHtml);
|
||||
dict.SetMethod("_writeHtml", &WriteHtml);
|
||||
dict.SetMethod("_readImage", &ReadImage);
|
||||
dict.SetMethod("_writeImage", &WriteImage);
|
||||
dict.SetMethod("_clear", &Clear);
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using crash_reporter::CrashReporter;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
@@ -31,17 +33,30 @@ struct Converter<std::map<std::string, std::string> > {
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<CrashReporter::UploadReportResult> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const CrashReporter::UploadReportResult& reports) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("date", v8::Date::New(isolate, reports.first*1000.0));
|
||||
dict.Set("id", reports.second);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
using crash_reporter::CrashReporter;
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
auto report = base::Unretained(CrashReporter::GetInstance());
|
||||
dict.SetMethod("start",
|
||||
base::Bind(&CrashReporter::Start,
|
||||
base::Unretained(CrashReporter::GetInstance())));
|
||||
base::Bind(&CrashReporter::Start, report));
|
||||
dict.SetMethod("_getUploadedReports",
|
||||
base::Bind(&CrashReporter::GetUploadedReports, report));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
binding = process.atomBinding 'clipboard'
|
||||
module.exports =
|
||||
availableFormats: (type='standard') -> binding._availableFormats type
|
||||
has: (format, type='standard') -> binding._has format, type
|
||||
read: (format, type='standard') -> binding._read format, type
|
||||
readText: (type='standard') -> binding._readText type
|
||||
writeText: (text, type='standard') -> binding._writeText text, type
|
||||
readHtml: (type='standard') -> binding._readHtml type
|
||||
writeHtml: (markup, type='standard') -> binding._writeHtml markup, type
|
||||
readImage: (type='standard') -> binding._readImage type
|
||||
writeImage: (image, type='standard') -> binding._writeImage image, type
|
||||
clear: (type='standard') -> binding._clear type
|
||||
|
||||
@@ -41,6 +41,10 @@ class CrashReporter
|
||||
start()
|
||||
|
||||
getLastCrashReport: ->
|
||||
if process.platform is 'darwin'
|
||||
reports = binding._getUploadedReports()
|
||||
return if reports.length > 0 then reports[0] else null
|
||||
|
||||
tmpdir =
|
||||
if process.platform is 'win32'
|
||||
os.tmpdir()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#define ATOM_MAJOR_VERSION 0
|
||||
#define ATOM_MINOR_VERSION 27
|
||||
#define ATOM_PATCH_VERSION 0
|
||||
#define ATOM_PATCH_VERSION 3
|
||||
|
||||
#define ATOM_VERSION_IS_RELEASE 1
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef ATOM_COMMON_CHROME_VERSION_H_
|
||||
#define ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
||||
#define CHROME_VERSION_STRING "42.0.2311.107"
|
||||
#define CHROME_VERSION_STRING "43.0.2357.65"
|
||||
#define CHROME_VERSION "v" CHROME_VERSION_STRING
|
||||
|
||||
#endif // ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
||||
@@ -39,4 +39,9 @@ void CrashReporter::SetUploadParameters(const StringMap& parameters) {
|
||||
SetUploadParameters();
|
||||
}
|
||||
|
||||
std::vector<CrashReporter::UploadReportResult>
|
||||
CrashReporter::GetUploadedReports() {
|
||||
return std::vector<CrashReporter::UploadReportResult>();
|
||||
}
|
||||
|
||||
} // namespace crash_reporter
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
@@ -15,6 +17,7 @@ namespace crash_reporter {
|
||||
class CrashReporter {
|
||||
public:
|
||||
typedef std::map<std::string, std::string> StringMap;
|
||||
typedef std::pair<int, std::string> UploadReportResult; // upload-date, id
|
||||
|
||||
static CrashReporter* GetInstance();
|
||||
|
||||
@@ -25,6 +28,8 @@ class CrashReporter {
|
||||
bool skip_system_crash_handler,
|
||||
const StringMap& extra_parameters);
|
||||
|
||||
virtual std::vector<CrashReporter::UploadReportResult> GetUploadedReports();
|
||||
|
||||
protected:
|
||||
CrashReporter();
|
||||
virtual ~CrashReporter();
|
||||
|
||||
@@ -6,13 +6,20 @@
|
||||
#define ATOM_COMMON_CRASH_REPORTER_CRASH_REPORTER_MAC_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#import "vendor/breakpad/src/client/mac/Framework/Breakpad.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "vendor/crashpad/client/simple_string_dictionary.h"
|
||||
|
||||
template <typename T> struct DefaultSingletonTraits;
|
||||
|
||||
namespace crashpad {
|
||||
class CrashReportDatabase;
|
||||
}
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
class CrashReporterMac : public CrashReporter {
|
||||
@@ -33,7 +40,14 @@ class CrashReporterMac : public CrashReporter {
|
||||
CrashReporterMac();
|
||||
virtual ~CrashReporterMac();
|
||||
|
||||
BreakpadRef breakpad_;
|
||||
void SetUploadsEnabled(bool enable_uploads);
|
||||
void SetCrashKeyValue(const base::StringPiece& key,
|
||||
const base::StringPiece& value);
|
||||
|
||||
std::vector<UploadReportResult> GetUploadedReports() override;
|
||||
|
||||
scoped_ptr<crashpad::SimpleStringDictionary> simple_string_dictionary_;
|
||||
scoped_ptr<crashpad::CrashReportDatabase> crash_report_database_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CrashReporterMac);
|
||||
};
|
||||
|
||||
@@ -4,20 +4,24 @@
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter_mac.h"
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "base/memory/singleton.h"
|
||||
#include "base/strings/string_piece.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#import "vendor/breakpad/src/client/apple/Framework/BreakpadDefines.h"
|
||||
#include "vendor/crashpad/client/crash_report_database.h"
|
||||
#include "vendor/crashpad/client/crashpad_client.h"
|
||||
#include "vendor/crashpad/client/crashpad_info.h"
|
||||
#include "vendor/crashpad/client/settings.h"
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
CrashReporterMac::CrashReporterMac()
|
||||
: breakpad_(NULL) {
|
||||
CrashReporterMac::CrashReporterMac() {
|
||||
}
|
||||
|
||||
CrashReporterMac::~CrashReporterMac() {
|
||||
if (breakpad_ != NULL)
|
||||
BreakpadRelease(breakpad_);
|
||||
}
|
||||
|
||||
void CrashReporterMac::InitBreakpad(const std::string& product_name,
|
||||
@@ -26,54 +30,50 @@ void CrashReporterMac::InitBreakpad(const std::string& product_name,
|
||||
const std::string& submit_url,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) {
|
||||
if (breakpad_ != NULL)
|
||||
BreakpadRelease(breakpad_);
|
||||
|
||||
NSMutableDictionary* parameters =
|
||||
[NSMutableDictionary dictionaryWithCapacity:4];
|
||||
|
||||
[parameters setValue:@ATOM_PRODUCT_NAME
|
||||
forKey:@BREAKPAD_PRODUCT];
|
||||
[parameters setValue:base::SysUTF8ToNSString(product_name)
|
||||
forKey:@BREAKPAD_PRODUCT_DISPLAY];
|
||||
[parameters setValue:base::SysUTF8ToNSString(version)
|
||||
forKey:@BREAKPAD_VERSION];
|
||||
[parameters setValue:base::SysUTF8ToNSString(company_name)
|
||||
forKey:@BREAKPAD_VENDOR];
|
||||
[parameters setValue:base::SysUTF8ToNSString(submit_url)
|
||||
forKey:@BREAKPAD_URL];
|
||||
[parameters setValue:(auto_submit ? @"YES" : @"NO")
|
||||
forKey:@BREAKPAD_SKIP_CONFIRM];
|
||||
[parameters setValue:(skip_system_crash_handler ? @"YES" : @"NO")
|
||||
forKey:@BREAKPAD_SEND_AND_EXIT];
|
||||
|
||||
// Report all crashes (important for testing the crash reporter).
|
||||
[parameters setValue:@"0" forKey:@BREAKPAD_REPORT_INTERVAL];
|
||||
|
||||
// Put dump files under "/tmp/ProductName Crashes".
|
||||
std::string dump_dir = "/tmp/" + product_name + " Crashes";
|
||||
[parameters setValue:base::SysUTF8ToNSString(dump_dir)
|
||||
forKey:@BREAKPAD_DUMP_DIRECTORY];
|
||||
|
||||
// Temporarily run Breakpad in-process on 10.10 and later because APIs that
|
||||
// it depends on got broken (http://crbug.com/386208).
|
||||
// This can catch crashes in the browser process only.
|
||||
if (base::mac::IsOSYosemiteOrLater()) {
|
||||
[parameters setObject:[NSNumber numberWithBool:YES]
|
||||
forKey:@BREAKPAD_IN_PROCESS];
|
||||
}
|
||||
|
||||
breakpad_ = BreakpadCreate(parameters);
|
||||
if (!breakpad_) {
|
||||
LOG(ERROR) << "Failed to initialize breakpad";
|
||||
// check whether crashpad has been initilized.
|
||||
// Only need to initilize once.
|
||||
if (simple_string_dictionary_)
|
||||
return;
|
||||
|
||||
std::string dump_dir = "/tmp/" + product_name + " Crashes";
|
||||
base::FilePath database_path(dump_dir);
|
||||
if (is_browser_) {
|
||||
@autoreleasepool {
|
||||
base::FilePath framework_bundle_path = base::mac::FrameworkBundlePath();
|
||||
base::FilePath handler_path =
|
||||
framework_bundle_path.Append("Resources").Append("crashpad_handler");
|
||||
|
||||
crashpad::CrashpadClient crashpad_client;
|
||||
if (crashpad_client.StartHandler(handler_path, database_path,
|
||||
submit_url,
|
||||
StringMap(),
|
||||
std::vector<std::string>())) {
|
||||
crashpad_client.UseHandler();
|
||||
}
|
||||
} // @autoreleasepool
|
||||
}
|
||||
|
||||
for (StringMap::const_iterator iter = upload_parameters_.begin();
|
||||
iter != upload_parameters_.end(); ++iter) {
|
||||
BreakpadAddUploadParameter(breakpad_,
|
||||
base::SysUTF8ToNSString(iter->first),
|
||||
base::SysUTF8ToNSString(iter->second));
|
||||
crashpad::CrashpadInfo* crashpad_info =
|
||||
crashpad::CrashpadInfo::GetCrashpadInfo();
|
||||
if (skip_system_crash_handler) {
|
||||
crashpad_info->set_system_crash_reporter_forwarding(
|
||||
crashpad::TriState::kDisabled);
|
||||
}
|
||||
|
||||
simple_string_dictionary_.reset(new crashpad::SimpleStringDictionary());
|
||||
crashpad_info->set_simple_annotations(simple_string_dictionary_.get());
|
||||
|
||||
SetCrashKeyValue("prod", ATOM_PRODUCT_NAME);
|
||||
SetCrashKeyValue("process_type", is_browser_ ? "browser" : "renderer");
|
||||
SetCrashKeyValue("ver", version);
|
||||
|
||||
for (const auto& upload_parameter: upload_parameters_) {
|
||||
SetCrashKeyValue(upload_parameter.first, upload_parameter.second);
|
||||
}
|
||||
if (is_browser_) {
|
||||
crash_report_database_ = crashpad::CrashReportDatabase::Initialize(
|
||||
database_path);
|
||||
SetUploadsEnabled(auto_submit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,48 @@ void CrashReporterMac::SetUploadParameters() {
|
||||
upload_parameters_["platform"] = "darwin";
|
||||
}
|
||||
|
||||
void CrashReporterMac::SetUploadsEnabled(bool enable_uploads) {
|
||||
if (crash_report_database_) {
|
||||
crashpad::Settings* settings = crash_report_database_->GetSettings();
|
||||
settings->SetUploadsEnabled(enable_uploads);
|
||||
}
|
||||
}
|
||||
|
||||
void CrashReporterMac::SetCrashKeyValue(const base::StringPiece& key,
|
||||
const base::StringPiece& value) {
|
||||
simple_string_dictionary_->SetKeyValue(key.data(), value.data());
|
||||
}
|
||||
|
||||
std::vector<CrashReporter::UploadReportResult>
|
||||
CrashReporterMac::GetUploadedReports() {
|
||||
std::vector<CrashReporter::UploadReportResult> uploaded_reports;
|
||||
|
||||
if (!crash_report_database_) {
|
||||
return uploaded_reports;
|
||||
}
|
||||
|
||||
std::vector<crashpad::CrashReportDatabase::Report> completed_reports;
|
||||
crashpad::CrashReportDatabase::OperationStatus status =
|
||||
crash_report_database_->GetCompletedReports(&completed_reports);
|
||||
if (status != crashpad::CrashReportDatabase::kNoError) {
|
||||
return uploaded_reports;
|
||||
}
|
||||
|
||||
for (const crashpad::CrashReportDatabase::Report& completed_report :
|
||||
completed_reports) {
|
||||
if (completed_report.uploaded) {
|
||||
uploaded_reports.push_back(
|
||||
UploadReportResult(static_cast<int>(completed_report.creation_time),
|
||||
completed_report.id));
|
||||
}
|
||||
}
|
||||
|
||||
auto sort_by_time = [](const UploadReportResult& a,
|
||||
const UploadReportResult& b) {return a.first >= b.first;};
|
||||
std::sort(uploaded_reports.begin(), uploaded_reports.end(), sort_by_time);
|
||||
return uploaded_reports;
|
||||
}
|
||||
|
||||
// static
|
||||
CrashReporterMac* CrashReporterMac::GetInstance() {
|
||||
return Singleton<CrashReporterMac>::get();
|
||||
|
||||
@@ -178,6 +178,9 @@ void NodeBindings::LoadEnvironment(node::Environment* env) {
|
||||
|
||||
if (node::use_debug_agent)
|
||||
node::EnableDebug(env);
|
||||
|
||||
v8::Local<v8::Value> msg = mate::StringToV8(env->isolate(), "loaded");
|
||||
node::MakeCallback(env->isolate(), env->process_object(), "emit", 1, &msg);
|
||||
}
|
||||
|
||||
void NodeBindings::PrepareMessageLoop() {
|
||||
|
||||
@@ -95,6 +95,9 @@ const char kOverlayScrollbars[] = "overlay-scrollbars";
|
||||
const char kOverlayFullscreenVideo[] = "overlay-fullscreen-video";
|
||||
const char kSharedWorker[] = "shared-worker";
|
||||
|
||||
// Set page visiblity to always visible.
|
||||
const char kPageVisibility[] = "page-visibility";
|
||||
|
||||
// Disable HTTP cache.
|
||||
const char kDisableHttpCache[] = "disable-http-cache";
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ extern const char kSubpixelFontScaling[];
|
||||
extern const char kOverlayScrollbars[];
|
||||
extern const char kOverlayFullscreenVideo[];
|
||||
extern const char kSharedWorker[];
|
||||
extern const char kPageVisibility[];
|
||||
|
||||
extern const char kDisableHttpCache[];
|
||||
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
#define USE(WTF_FEATURE) (defined WTF_USE_##WTF_FEATURE && WTF_USE_##WTF_FEATURE) // NOLINT
|
||||
#define ENABLE(WTF_FEATURE) (defined ENABLE_##WTF_FEATURE && ENABLE_##WTF_FEATURE) // NOLINT
|
||||
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/renderer/api/atom_api_spell_check_client.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "third_party/WebKit/public/web/WebDocument.h"
|
||||
@@ -78,6 +80,14 @@ v8::Local<v8::Value> WebFrame::RegisterEmbedderCustomElement(
|
||||
return web_frame_->document().registerEmbedderCustomElement(name, options, c);
|
||||
}
|
||||
|
||||
void WebFrame::RegisterElementResizeCallback(
|
||||
int element_instance_id,
|
||||
const GuestViewContainer::ResizeCallback& callback) {
|
||||
auto guest_view_container = GuestViewContainer::FromID(element_instance_id);
|
||||
if (guest_view_container)
|
||||
guest_view_container->RegisterElementResizeCallback(callback);
|
||||
}
|
||||
|
||||
void WebFrame::AttachGuest(int id) {
|
||||
content::RenderFrame::FromWebFrame(web_frame_)->AttachGuest(id);
|
||||
}
|
||||
@@ -106,6 +116,8 @@ mate::ObjectTemplateBuilder WebFrame::GetObjectTemplateBuilder(
|
||||
.SetMethod("getZoomFactor", &WebFrame::GetZoomFactor)
|
||||
.SetMethod("registerEmbedderCustomElement",
|
||||
&WebFrame::RegisterEmbedderCustomElement)
|
||||
.SetMethod("registerElementResizeCallback",
|
||||
&WebFrame::RegisterElementResizeCallback)
|
||||
.SetMethod("attachGuest", &WebFrame::AttachGuest)
|
||||
.SetMethod("setSpellCheckProvider", &WebFrame::SetSpellCheckProvider)
|
||||
.SetMethod("registerUrlSchemeAsSecure",
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/renderer/guest_view_container.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
@@ -42,6 +43,9 @@ class WebFrame : public mate::Wrappable {
|
||||
|
||||
v8::Local<v8::Value> RegisterEmbedderCustomElement(
|
||||
const base::string16& name, v8::Local<v8::Object> options);
|
||||
void RegisterElementResizeCallback(
|
||||
int element_instance_id,
|
||||
const GuestViewContainer::ResizeCallback& callback);
|
||||
void AttachGuest(int element_instance_id);
|
||||
|
||||
// Set the provider that will be used by SpellCheckClient for spell check.
|
||||
|
||||
@@ -191,6 +191,21 @@ content::BrowserPluginDelegate* AtomRendererClient::CreateBrowserPluginDelegate(
|
||||
}
|
||||
}
|
||||
|
||||
bool AtomRendererClient::ShouldOverridePageVisibilityState(
|
||||
const content::RenderFrame* render_frame,
|
||||
blink::WebPageVisibilityState* override_state) {
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
bool b;
|
||||
|
||||
if (IsSwitchEnabled(command_line, switches::kPageVisibility, &b)
|
||||
&& b) {
|
||||
*override_state = blink::WebPageVisibilityStateVisible;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AtomRendererClient::EnableWebRuntimeFeatures() {
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
bool b;
|
||||
|
||||
@@ -55,6 +55,9 @@ class AtomRendererClient : public content::ContentRendererClient,
|
||||
content::RenderFrame* render_frame,
|
||||
const std::string& mime_type,
|
||||
const GURL& original_url) override;
|
||||
bool ShouldOverridePageVisibilityState(
|
||||
const content::RenderFrame* render_frame,
|
||||
blink::WebPageVisibilityState* override_state) override;
|
||||
|
||||
void EnableWebRuntimeFeatures();
|
||||
|
||||
|
||||
@@ -4,12 +4,54 @@
|
||||
|
||||
#include "atom/renderer/guest_view_container.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/lazy_instance.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
GuestViewContainer::GuestViewContainer(content::RenderFrame* render_frame) {
|
||||
namespace {
|
||||
|
||||
using GuestViewContainerMap = std::map<int, GuestViewContainer*>;
|
||||
static base::LazyInstance<GuestViewContainerMap> g_guest_view_container_map =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
} // namespace
|
||||
|
||||
GuestViewContainer::GuestViewContainer(content::RenderFrame* render_frame)
|
||||
: render_frame_(render_frame) {
|
||||
}
|
||||
|
||||
GuestViewContainer::~GuestViewContainer() {
|
||||
if (element_instance_id_ > 0)
|
||||
g_guest_view_container_map.Get().erase(element_instance_id_);
|
||||
}
|
||||
|
||||
// static
|
||||
GuestViewContainer* GuestViewContainer::FromID(int element_instance_id) {
|
||||
GuestViewContainerMap* guest_view_containers =
|
||||
g_guest_view_container_map.Pointer();
|
||||
auto it = guest_view_containers->find(element_instance_id);
|
||||
return it == guest_view_containers->end() ? nullptr : it->second;
|
||||
}
|
||||
|
||||
void GuestViewContainer::RegisterElementResizeCallback(
|
||||
const ResizeCallback& callback) {
|
||||
element_resize_callback_ = callback;
|
||||
}
|
||||
|
||||
void GuestViewContainer::SetElementInstanceID(int element_instance_id) {
|
||||
element_instance_id_ = element_instance_id;
|
||||
g_guest_view_container_map.Get().insert(
|
||||
std::make_pair(element_instance_id, this));
|
||||
}
|
||||
|
||||
void GuestViewContainer::DidResizeElement(const gfx::Size& old_size,
|
||||
const gfx::Size& new_size) {
|
||||
if (element_resize_callback_.is_null())
|
||||
return;
|
||||
|
||||
element_resize_callback_.Run(old_size, new_size);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -5,17 +5,38 @@
|
||||
#ifndef ATOM_RENDERER_GUEST_VIEW_CONTAINER_H_
|
||||
#define ATOM_RENDERER_GUEST_VIEW_CONTAINER_H_
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "content/public/renderer/browser_plugin_delegate.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace gfx {
|
||||
class Size;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class GuestViewContainer : public content::BrowserPluginDelegate {
|
||||
public:
|
||||
typedef base::Callback<void(const gfx::Size&, const gfx::Size&)>
|
||||
ResizeCallback;
|
||||
|
||||
explicit GuestViewContainer(content::RenderFrame* render_frame);
|
||||
~GuestViewContainer() override;
|
||||
|
||||
static GuestViewContainer* FromID(int element_instance_id);
|
||||
|
||||
void RegisterElementResizeCallback(const ResizeCallback& callback);
|
||||
|
||||
// content::BrowserPluginDelegate:
|
||||
void SetElementInstanceID(int element_instance_id) final;
|
||||
void DidResizeElement(const gfx::Size& old_size,
|
||||
const gfx::Size& new_size) final;
|
||||
|
||||
private:
|
||||
int element_instance_id_;
|
||||
content::RenderFrame* render_frame_;
|
||||
|
||||
ResizeCallback element_resize_callback_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(GuestViewContainer);
|
||||
};
|
||||
|
||||
|
||||
@@ -88,12 +88,8 @@ if nodeIntegration in ['true', 'all', 'except-iframe', 'manual-enable-iframe']
|
||||
window.addEventListener 'unload', ->
|
||||
process.emit 'exit'
|
||||
else
|
||||
# The Module.runMain will run process._tickCallck() immediately, so we are
|
||||
# able to delete the symbols in this tick even though we used process.nextTick
|
||||
# to schedule it.
|
||||
# It is important that we put this in process.nextTick, if we delete them now
|
||||
# some code in node.js will complain about "process not defined".
|
||||
process.nextTick ->
|
||||
# Delete Node's symbols after the Environment has been loaded.
|
||||
process.once 'loaded', ->
|
||||
delete global.process
|
||||
delete global.setImmediate
|
||||
delete global.clearImmediate
|
||||
|
||||
@@ -62,6 +62,7 @@ window.open = (url, frameName='', features='') ->
|
||||
window.alert = (message, title='') ->
|
||||
dialog = remote.require 'dialog'
|
||||
buttons = ['OK']
|
||||
message = message.toString()
|
||||
dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons}
|
||||
|
||||
# And the confirm().
|
||||
|
||||
@@ -55,9 +55,9 @@ module.exports =
|
||||
ipc.removeAllListeners "ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-#{viewInstanceId}"
|
||||
ipc.removeAllListeners "ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-#{viewInstanceId}"
|
||||
|
||||
createGuest: (type, params, callback) ->
|
||||
createGuest: (params, callback) ->
|
||||
requestId++
|
||||
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', type, params, requestId
|
||||
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', params, requestId
|
||||
ipc.once "ATOM_SHELL_RESPONSE_#{requestId}", callback
|
||||
|
||||
attachGuest: (elementInstanceId, guestInstanceId, params) ->
|
||||
@@ -67,8 +67,8 @@ module.exports =
|
||||
destroyGuest: (guestInstanceId) ->
|
||||
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId
|
||||
|
||||
setAutoSize: (guestInstanceId, params) ->
|
||||
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', guestInstanceId, params
|
||||
setSize: (guestInstanceId, params) ->
|
||||
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', guestInstanceId, params
|
||||
|
||||
setAllowTransparency: (guestInstanceId, allowtransparency) ->
|
||||
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', guestInstanceId, allowtransparency
|
||||
|
||||
@@ -28,7 +28,7 @@ class WebViewAttribute
|
||||
# Changes the attribute's value without triggering its mutation handler.
|
||||
setValueIgnoreMutation: (value) ->
|
||||
@ignoreMutation = true
|
||||
@webViewImpl.webviewNode.setAttribute(@name, value || '')
|
||||
@setValue value
|
||||
@ignoreMutation = false
|
||||
|
||||
# Defines this attribute as a property on the webview node.
|
||||
@@ -72,7 +72,7 @@ class AutosizeDimensionAttribute extends WebViewAttribute
|
||||
|
||||
handleMutation: (oldValue, newValue) ->
|
||||
return unless @webViewImpl.guestInstanceId
|
||||
guestViewInternal.setAutoSize @webViewImpl.guestInstanceId,
|
||||
guestViewInternal.setSize @webViewImpl.guestInstanceId,
|
||||
enableAutoSize: @webViewImpl.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue()
|
||||
min:
|
||||
width: parseInt @webViewImpl.attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() || 0
|
||||
@@ -119,6 +119,14 @@ class SrcAttribute extends WebViewAttribute
|
||||
else
|
||||
''
|
||||
|
||||
setValueIgnoreMutation: (value) ->
|
||||
WebViewAttribute::setValueIgnoreMutation value
|
||||
# takeRecords() is needed to clear queued up src mutations. Without it, it
|
||||
# is possible for this change to get picked up asyncronously by src's
|
||||
# mutation observer |observer|, and then get handled even though we do not
|
||||
# want to handle this mutation.
|
||||
@observer.takeRecords()
|
||||
|
||||
handleMutation: (oldValue, newValue) ->
|
||||
# Once we have navigated, we don't allow clearing the src attribute.
|
||||
# Once <webview> enters a navigated state, it cannot return to a
|
||||
@@ -138,7 +146,10 @@ class SrcAttribute extends WebViewAttribute
|
||||
setupMutationObserver: ->
|
||||
@observer = new MutationObserver (mutations) =>
|
||||
for mutation in mutations
|
||||
@handleMutation mutation.oldValue, @getValue()
|
||||
oldValue = mutation.oldValue
|
||||
newValue = @getValue()
|
||||
return if oldValue isnt newValue
|
||||
@handleMutation oldValue, newValue
|
||||
params =
|
||||
attributes: true,
|
||||
attributeOldValue: true,
|
||||
|
||||
@@ -13,7 +13,6 @@ class WebViewImpl
|
||||
constructor: (@webviewNode) ->
|
||||
v8Util.setHiddenValue @webviewNode, 'internal', this
|
||||
@attached = false
|
||||
@pendingGuestCreation = false
|
||||
@elementAttached = false
|
||||
|
||||
@beforeFirstNavigation = true
|
||||
@@ -87,9 +86,12 @@ class WebViewImpl
|
||||
@browserPluginNode.removeAttribute webViewConstants.ATTRIBUTE_INTERNALINSTANCEID
|
||||
@internalInstanceId = parseInt newValue
|
||||
|
||||
# Track when the element resizes using the element resize callback.
|
||||
webFrame.registerElementResizeCallback @internalInstanceId, @onElementResize.bind(this)
|
||||
|
||||
return unless @guestInstanceId
|
||||
|
||||
guestViewInternal.attachGuest @internalInstanceId, @guestInstanceId, @buildAttachParams()
|
||||
guestViewInternal.attachGuest @internalInstanceId, @guestInstanceId, @buildParams()
|
||||
|
||||
onSizeChanged: (webViewEvent) ->
|
||||
newWidth = webViewEvent.newWidth
|
||||
@@ -107,6 +109,9 @@ class WebViewImpl
|
||||
minWidth = @attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() | width
|
||||
minHeight = @attributes[webViewConstants.ATTRIBUTE_MINHEIGHT].getValue() | width
|
||||
|
||||
minWidth = Math.min minWidth, maxWidth
|
||||
minHeight = Math.min minHeight, maxHeight
|
||||
|
||||
if not @attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue() or
|
||||
(newWidth >= minWidth and
|
||||
newWidth <= maxWidth and
|
||||
@@ -118,17 +123,21 @@ class WebViewImpl
|
||||
# changed.
|
||||
@dispatchEvent webViewEvent
|
||||
|
||||
onElementResize: (oldSize, newSize) ->
|
||||
# Dispatch the 'resize' event.
|
||||
resizeEvent = new Event('resize', bubbles: true)
|
||||
resizeEvent.oldWidth = oldSize.width
|
||||
resizeEvent.oldHeight = oldSize.height
|
||||
resizeEvent.newWidth = newSize.width
|
||||
resizeEvent.newHeight = newSize.height
|
||||
@dispatchEvent resizeEvent
|
||||
|
||||
if @guestInstanceId
|
||||
guestViewInternal.setSize @guestInstanceId, normal: newSize
|
||||
|
||||
createGuest: ->
|
||||
return if @pendingGuestCreation
|
||||
params =
|
||||
storagePartitionId: @attributes[webViewConstants.ATTRIBUTE_PARTITION].getValue()
|
||||
guestViewInternal.createGuest 'webview', params, (guestInstanceId) =>
|
||||
@pendingGuestCreation = false
|
||||
unless @elementAttached
|
||||
guestViewInternal.destroyGuest guestInstanceId
|
||||
return
|
||||
guestViewInternal.createGuest @buildParams(), (guestInstanceId) =>
|
||||
@attachWindow guestInstanceId
|
||||
@pendingGuestCreation = true
|
||||
|
||||
dispatchEvent: (webViewEvent) ->
|
||||
@webviewNode.dispatchEvent webViewEvent
|
||||
@@ -160,21 +169,30 @@ class WebViewImpl
|
||||
onAttach: (storagePartitionId) ->
|
||||
@attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue storagePartitionId
|
||||
|
||||
buildAttachParams: ->
|
||||
buildParams: ->
|
||||
params =
|
||||
instanceId: @viewInstanceId
|
||||
userAgentOverride: @userAgentOverride
|
||||
for attributeName, attribute of @attributes
|
||||
params[attributeName] = attribute.getValue()
|
||||
# When the WebView is not participating in layout (display:none)
|
||||
# then getBoundingClientRect() would report a width and height of 0.
|
||||
# However, in the case where the WebView has a fixed size we can
|
||||
# use that value to initially size the guest so as to avoid a relayout of
|
||||
# the on display:block.
|
||||
css = window.getComputedStyle @webviewNode, null
|
||||
elementRect = @webviewNode.getBoundingClientRect()
|
||||
params.elementWidth = parseInt(elementRect.width) ||
|
||||
parseInt(css.getPropertyValue('width'))
|
||||
params.elementHeight = parseInt(elementRect.height) ||
|
||||
parseInt(css.getPropertyValue('height'))
|
||||
params
|
||||
|
||||
attachWindow: (guestInstanceId) ->
|
||||
@guestInstanceId = guestInstanceId
|
||||
params = @buildAttachParams()
|
||||
|
||||
return true unless @internalInstanceId
|
||||
|
||||
guestViewInternal.attachGuest @internalInstanceId, @guestInstanceId, params
|
||||
guestViewInternal.attachGuest @internalInstanceId, @guestInstanceId, @buildParams()
|
||||
|
||||
# Registers browser plugin <object> custom element.
|
||||
registerBrowserPluginElement = ->
|
||||
|
||||
@@ -31,8 +31,11 @@ class PdfFunctions {
|
||||
render_pdf_to_dc_func_(NULL) {}
|
||||
|
||||
bool Init() {
|
||||
base::FilePath pdf_module_path(FILE_PATH_LITERAL("pdf.dll"));
|
||||
pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL));
|
||||
base::FilePath module_path;
|
||||
if (!PathService::Get(base::DIR_MODULE, &module_path))
|
||||
return false;
|
||||
base::FilePath::StringType name(FILE_PATH_LITERAL("pdf.dll"));
|
||||
pdf_lib_.Reset(base::LoadNativeLibrary(module_path.Append(name), NULL));
|
||||
if (!pdf_lib_.is_valid()) {
|
||||
LOG(WARNING) << "Couldn't load PDF plugin";
|
||||
return false;
|
||||
|
||||
@@ -97,6 +97,10 @@ You can also create a window without chrome by using
|
||||
* `shared-worker` Boolean
|
||||
* `direct-write` Boolean - Whether the DirectWrite font rendering system on
|
||||
Windows is enabled
|
||||
* `page-visibility` Boolean - Page would be forced to be always in visible
|
||||
or hidden state once set, instead of reflecting current window's
|
||||
visibility. Users can set it to `true` to prevent throttling of DOM
|
||||
timers.
|
||||
|
||||
Creates a new `BrowserWindow` with native properties set by the `options`.
|
||||
Usually you only need to set the `width` and `height`, other properties will
|
||||
@@ -579,7 +583,8 @@ Same with `webContents.reload`.
|
||||
|
||||
* `menu` Menu
|
||||
|
||||
Sets the `menu` as the window top menu.
|
||||
Sets the `menu` as the window's menu bar, setting it to `null` will remove the
|
||||
menu bar.
|
||||
|
||||
__Note:__ This API is not available on OS X.
|
||||
|
||||
|
||||
@@ -30,6 +30,19 @@ Returns the content in clipboard as plain text.
|
||||
|
||||
Writes the `text` into clipboard as plain text.
|
||||
|
||||
## clipboard.readHtml([type])
|
||||
|
||||
* `type` String
|
||||
|
||||
Returns the content in clipboard as markup.
|
||||
|
||||
## clipboard.writeHtml(markup[, type])
|
||||
|
||||
* `markup` String
|
||||
* `type` String
|
||||
|
||||
Writes the `markup` into clipboard.
|
||||
|
||||
## clipboard.readImage([type])
|
||||
|
||||
* `type` String
|
||||
@@ -49,20 +62,29 @@ Writes the `image` into clipboard.
|
||||
|
||||
Clears everything in clipboard.
|
||||
|
||||
## clipboard.has(format[, type])
|
||||
## clipboard.availableFormats([type])
|
||||
|
||||
* `format` String
|
||||
Returns an array of supported `format` for the clipboard `type`.
|
||||
|
||||
## clipboard.has(data[, type])
|
||||
|
||||
* `data` String
|
||||
* `type` String
|
||||
|
||||
Returns whether clipboard has data in specified `format`.
|
||||
Returns whether clipboard supports the format of specified `data`.
|
||||
|
||||
```javascript
|
||||
var clipboard = require('clipboard');
|
||||
console.log(clipboard.has('<p>selection</p>'));
|
||||
```
|
||||
|
||||
**Note:** This API is experimental and could be removed in future.
|
||||
|
||||
## clipboard.read(format[, type])
|
||||
## clipboard.read(data[, type])
|
||||
|
||||
* `format` String
|
||||
* `data` String
|
||||
* `type` String
|
||||
|
||||
Reads the data in clipboard of the `format`.
|
||||
Reads the `data` in clipboard.
|
||||
|
||||
**Note:** This API is experimental and could be removed in future.
|
||||
|
||||
@@ -27,6 +27,11 @@ crashReporter.start({
|
||||
* Only string properties are send correctly.
|
||||
* Nested objects are not supported.
|
||||
|
||||
**Note:** On OS X, electron uses a new `crashpad` client, which is different
|
||||
with the `breakpad` on Windows and Linux. To enable crash collection feature,
|
||||
you are required to call `crashReporter.start` API to initiliaze `crashpad` in
|
||||
main process, even you only collect crash report in renderer process.
|
||||
|
||||
## crashReporter.getLastCrashReport()
|
||||
|
||||
Returns the date and ID of last crash report, when there was no crash report
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* Python 2.7
|
||||
* [Node.js](http://nodejs.org)
|
||||
* Clang 3.4 or later
|
||||
* Development headers of GTK+ and libnotify
|
||||
@@ -15,18 +16,6 @@ $ sudo apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \
|
||||
gcc-multilib g++-multilib
|
||||
```
|
||||
|
||||
Latest Node.js could be installed via ppa:
|
||||
|
||||
```bash
|
||||
$ sudo apt-get install python-software-properties software-properties-common
|
||||
$ sudo add-apt-repository ppa:chris-lea/node.js
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install nodejs
|
||||
|
||||
# Update to latest npm
|
||||
$ sudo npm install npm -g
|
||||
```
|
||||
|
||||
## Getting the code
|
||||
|
||||
```bash
|
||||
@@ -81,18 +70,6 @@ this:
|
||||
$ sudo apt-get install gcc-multilib g++-multilib
|
||||
```
|
||||
|
||||
### error adding symbols: DSO missing from command line
|
||||
|
||||
If you got an error like this:
|
||||
|
||||
````
|
||||
/usr/bin/ld: vendor/download/libchromiumcontent/Release/libchromiumcontent.so: undefined reference to symbol 'gconf_client_get'
|
||||
//usr/lib/x86_64-linux-gnu/libgconf-2.so.4: error adding symbols: DSO missing from command line
|
||||
````
|
||||
|
||||
libchromiumcontent.so is build with clang 3.0 which is incompatible with newer
|
||||
versions of clang. Try using clang 3.0, default version in Ubuntu 12.04.
|
||||
|
||||
### libudev.so.0 missing
|
||||
|
||||
If you get an error like:
|
||||
|
||||
@@ -111,7 +111,7 @@ environment variable and have a clean rebuild:
|
||||
|
||||
__Windows__
|
||||
|
||||
```cmd
|
||||
```bash
|
||||
> set "GYP_DEFINES=project_name=myapp product_name=MyApp"
|
||||
> python script\clean.py
|
||||
> python script\bootstrap.py
|
||||
|
||||
@@ -133,7 +133,7 @@ Electron binary to execute your app directly.
|
||||
|
||||
On Windows:
|
||||
|
||||
```cmd
|
||||
```bash
|
||||
$ .\electron\electron.exe your-app\
|
||||
```
|
||||
|
||||
|
||||
@@ -115,8 +115,6 @@
|
||||
'atom/browser/atom_javascript_dialog_manager.h',
|
||||
'atom/browser/atom_quota_permission_context.cc',
|
||||
'atom/browser/atom_quota_permission_context.h',
|
||||
'atom/browser/atom_resource_dispatcher_host_delegate.cc',
|
||||
'atom/browser/atom_resource_dispatcher_host_delegate.h',
|
||||
'atom/browser/atom_speech_recognition_manager_delegate.cc',
|
||||
'atom/browser/atom_speech_recognition_manager_delegate.h',
|
||||
'atom/browser/browser.cc',
|
||||
@@ -125,6 +123,8 @@
|
||||
'atom/browser/browser_mac.mm',
|
||||
'atom/browser/browser_win.cc',
|
||||
'atom/browser/browser_observer.h',
|
||||
'atom/browser/common_web_contents_delegate.cc',
|
||||
'atom/browser/common_web_contents_delegate.h',
|
||||
'atom/browser/javascript_environment.cc',
|
||||
'atom/browser/javascript_environment.h',
|
||||
'atom/browser/mac/atom_application.h',
|
||||
|
||||
@@ -15,6 +15,8 @@ LINUX_DEPS = [
|
||||
'libgnome-keyring-dev',
|
||||
'libgtk2.0-dev',
|
||||
'libnotify-dev',
|
||||
'gcc-4.8',
|
||||
'g++-4.8',
|
||||
'gcc-multilib',
|
||||
'g++-multilib',
|
||||
]
|
||||
@@ -26,6 +28,7 @@ def main():
|
||||
is_travis = (os.getenv('TRAVIS') == 'true')
|
||||
if is_travis and sys.platform == 'linux2':
|
||||
print 'Setup travis CI'
|
||||
execute(['sudo', 'add-apt-repository', '-y', 'ppa:ubuntu-toolchain-r/test'])
|
||||
execute(['sudo', 'apt-get', 'update'])
|
||||
execute(['sudo', 'apt-get', 'install'] + LINUX_DEPS)
|
||||
|
||||
@@ -41,8 +44,8 @@ def main():
|
||||
'libchromiumcontent'))
|
||||
|
||||
if is_travis and sys.platform == 'linux2':
|
||||
with scoped_env('CXX', 'g++'):
|
||||
with scoped_env('CC', 'gcc'):
|
||||
with scoped_env('CXX', 'g++-4.8'):
|
||||
with scoped_env('CC', 'gcc-4.8'):
|
||||
run_script('bootstrap.py', ['--dev'])
|
||||
run_script('update.py')
|
||||
else:
|
||||
|
||||
@@ -38,6 +38,7 @@ TARGET_BINARIES = {
|
||||
'msvcp120.dll',
|
||||
'msvcr120.dll',
|
||||
'node.dll',
|
||||
'pdf.dll',
|
||||
'content_resources_200_percent.pak',
|
||||
'ui_resources_200_percent.pak',
|
||||
'xinput1_3.dll',
|
||||
|
||||
@@ -7,7 +7,7 @@ import sys
|
||||
|
||||
|
||||
BASE_URL = 'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent'
|
||||
LIBCHROMIUMCONTENT_COMMIT = 'fa886209473d40eafda4e8263a79b5cf83eef95e'
|
||||
LIBCHROMIUMCONTENT_COMMIT = '5ccddd5f3968a7f63eaa888e6a8ba319ea8cd3b7'
|
||||
|
||||
PLATFORM = {
|
||||
'cygwin': 'win32',
|
||||
|
||||
@@ -91,8 +91,8 @@ describe 'browser-window module', ->
|
||||
|
||||
describe 'BrowserWindow.setSize(width, height)', ->
|
||||
it 'sets the window size', (done) ->
|
||||
size = [20, 400]
|
||||
w.on 'resize', ->
|
||||
size = [300, 400]
|
||||
w.once 'resize', ->
|
||||
newSize = w.getSize()
|
||||
assert.equal newSize[0], size[0]
|
||||
assert.equal newSize[1], size[1]
|
||||
@@ -102,7 +102,7 @@ describe 'browser-window module', ->
|
||||
describe 'BrowserWindow.setPosition(x, y)', ->
|
||||
it 'sets the window position', (done) ->
|
||||
pos = [10, 10]
|
||||
w.on 'move', ->
|
||||
w.once 'move', ->
|
||||
newPos = w.getPosition()
|
||||
assert.equal newPos[0], pos[0]
|
||||
assert.equal newPos[1], pos[1]
|
||||
|
||||
@@ -18,3 +18,17 @@ describe 'clipboard module', ->
|
||||
text = '千江有水千江月,万里无云万里天'
|
||||
clipboard.writeText text
|
||||
assert.equal clipboard.readText(), text
|
||||
|
||||
describe 'clipboard.readHtml()', ->
|
||||
it 'returns markup correctly', ->
|
||||
text = '<string>Hi</string>'
|
||||
markup =
|
||||
if process.platform is 'darwin'
|
||||
'<meta charset=\'utf-8\'><string>Hi</string>'
|
||||
else if process.platform is 'linux'
|
||||
'<meta http-equiv="content-type" ' +
|
||||
'content="text/html; charset=utf-8"><string>Hi</string>'
|
||||
else
|
||||
'<string>Hi</string>'
|
||||
clipboard.writeHtml text
|
||||
assert.equal clipboard.readHtml(), markup
|
||||
|
||||
@@ -5,12 +5,10 @@ url = require 'url'
|
||||
remote = require 'remote'
|
||||
formidable = require 'formidable'
|
||||
|
||||
crashReporter = remote.require 'crash-reporter'
|
||||
BrowserWindow = remote.require 'browser-window'
|
||||
|
||||
describe 'crash-reporter module', ->
|
||||
# We have trouble makeing crash reporter work on Yosemite.
|
||||
return if process.platform is 'darwin'
|
||||
|
||||
fixtures = path.resolve __dirname, 'fixtures'
|
||||
|
||||
w = null
|
||||
@@ -41,10 +39,15 @@ describe 'crash-reporter module', ->
|
||||
res.end('abc-123-def')
|
||||
server.close()
|
||||
done()
|
||||
server.listen 0, '127.0.0.1', ->
|
||||
# Server port is generated randomly for the first run, it will be reused
|
||||
# when page is refreshed.
|
||||
port = remote.process.port
|
||||
server.listen port, '127.0.0.1', ->
|
||||
{port} = server.address()
|
||||
remote.process.port = port
|
||||
url = url.format
|
||||
protocol: 'file'
|
||||
pathname: path.join fixtures, 'api', 'crash.html'
|
||||
search: "?port=#{port}"
|
||||
crashReporter.start {'submitUrl': 'http://127.0.0.1:' + port}
|
||||
w.loadUrl url
|
||||
|
||||
@@ -5,6 +5,7 @@ var BrowserWindow = require('browser-window');
|
||||
var Menu = require('menu');
|
||||
|
||||
var window = null;
|
||||
process.port = 0; // will be used by crash-reporter spec.
|
||||
|
||||
app.commandLine.appendSwitch('js-flags', '--expose_gc');
|
||||
app.commandLine.appendSwitch('ignore-certificate-errors');
|
||||
|
||||
2
vendor/brightray
vendored
2
vendor/brightray
vendored
Submodule vendor/brightray updated: 8fba2a8835...20af087dd3
1
vendor/crashpad
vendored
Submodule
1
vendor/crashpad
vendored
Submodule
Submodule vendor/crashpad added at e6a0d433b0
2
vendor/native_mate
vendored
2
vendor/native_mate
vendored
Submodule vendor/native_mate updated: 1696237a3f...ad207eeabb
Reference in New Issue
Block a user