Merge remote-tracking branch 'refs/remotes/atom/master'
This commit is contained in:
commit
a190b964c8
110 changed files with 2288 additions and 341 deletions
|
@ -52,6 +52,7 @@ contains documents describing how to build and contribute to Electron.
|
|||
- [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es)
|
||||
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||
- [Ukrainian](https://github.com/atom/electron/tree/master/docs-translations/uk-UA)
|
||||
- [Russian](https://github.com/atom/electron/tree/master/docs-translations/ru-RU)
|
||||
|
||||
## Quick Start
|
||||
|
|
7
atom.gyp
7
atom.gyp
|
@ -4,7 +4,7 @@
|
|||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '0.35.2',
|
||||
'version%': '0.36.0',
|
||||
},
|
||||
'includes': [
|
||||
'filenames.gypi',
|
||||
|
@ -256,6 +256,10 @@
|
|||
'vendor/node/deps/cares/include',
|
||||
# The `third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h` is using `platform/PlatformExport.h`.
|
||||
'<(libchromiumcontent_src_dir)/third_party/WebKit/Source',
|
||||
# The 'third_party/libyuv/include/libyuv/scale_argb.h' is using 'libyuv/basic_types.h'.
|
||||
'<(libchromiumcontent_src_dir)/third_party/libyuv/include',
|
||||
# The 'third_party/webrtc/modules/desktop_capture/desktop_frame.h' is using 'webrtc/base/scoped_ptr.h'.
|
||||
'<(libchromiumcontent_src_dir)/third_party/',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
|
@ -282,6 +286,7 @@
|
|||
'-lcomctl32.lib',
|
||||
'-lcomdlg32.lib',
|
||||
'-lwininet.lib',
|
||||
'-lwinmm.lib',
|
||||
],
|
||||
},
|
||||
'dependencies': [
|
||||
|
|
|
@ -31,8 +31,8 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
|||
plugin.path = path;
|
||||
plugin.permissions = ppapi::PERMISSION_ALL_BITS;
|
||||
|
||||
std::vector<std::string> flash_version_numbers;
|
||||
base::SplitString(version, '.', &flash_version_numbers);
|
||||
std::vector<std::string> flash_version_numbers = base::SplitString(
|
||||
version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
if (flash_version_numbers.size() < 1)
|
||||
flash_version_numbers.push_back("11");
|
||||
// |SplitString()| puts in an empty string given an empty string. :(
|
||||
|
@ -47,7 +47,7 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
|||
// E.g., "Shockwave Flash 10.2 r154":
|
||||
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
|
||||
flash_version_numbers[1] + " r" + flash_version_numbers[2];
|
||||
plugin.version = JoinString(flash_version_numbers, '.');
|
||||
plugin.version = base::JoinString(flash_version_numbers, ".");
|
||||
content::WebPluginMimeType swf_mime_type(
|
||||
content::kFlashPluginSwfMimeType,
|
||||
content::kFlashPluginSwfExtension,
|
||||
|
@ -81,19 +81,18 @@ std::string AtomContentClient::GetUserAgent() const {
|
|||
}
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(
|
||||
std::vector<std::string>* standard_schemes,
|
||||
std::vector<url::SchemeWithType>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto custom_schemes = command_line->GetSwitchValueASCII(
|
||||
switches::kRegisterStandardSchemes);
|
||||
if (!custom_schemes.empty()) {
|
||||
std::vector<std::string> schemes;
|
||||
base::SplitString(custom_schemes, ',', &schemes);
|
||||
standard_schemes->insert(standard_schemes->end(),
|
||||
schemes.begin(),
|
||||
schemes.end());
|
||||
std::vector<std::string> schemes = base::SplitString(
|
||||
custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
for (const std::string& scheme : schemes)
|
||||
standard_schemes->push_back({scheme.c_str(), url::SCHEME_WITHOUT_PORT});
|
||||
}
|
||||
standard_schemes->push_back("chrome-extension");
|
||||
standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT});
|
||||
}
|
||||
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
|
|
|
@ -22,7 +22,7 @@ class AtomContentClient : public brightray::ContentClient {
|
|||
std::string GetProduct() const override;
|
||||
std::string GetUserAgent() const override;
|
||||
void AddAdditionalSchemes(
|
||||
std::vector<std::string>* standard_schemes,
|
||||
std::vector<url::SchemeWithType>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes) override;
|
||||
void AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||
|
|
120
atom/browser/api/atom_api_desktop_capturer.cc
Normal file
120
atom/browser/api/atom_api_desktop_capturer.cc
Normal file
|
@ -0,0 +1,120 @@
|
|||
// 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/api/atom_api_desktop_capturer.h"
|
||||
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/browser/media/desktop_media_list.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<DesktopMediaList::Source> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const DesktopMediaList::Source& source) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
content::DesktopMediaID id = source.id;
|
||||
dict.Set("name", base::UTF16ToUTF8(source.name));
|
||||
dict.Set("id", id.ToString());
|
||||
dict.Set(
|
||||
"thumbnail",
|
||||
atom::api::NativeImage::Create(isolate, gfx::Image(source.thumbnail)));
|
||||
return ConvertToV8(isolate, dict);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
DesktopCapturer::DesktopCapturer() {
|
||||
}
|
||||
|
||||
DesktopCapturer::~DesktopCapturer() {
|
||||
}
|
||||
|
||||
void DesktopCapturer::StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size) {
|
||||
webrtc::DesktopCaptureOptions options =
|
||||
webrtc::DesktopCaptureOptions::CreateDefault();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// On windows, desktop effects (e.g. Aero) will be disabled when the Desktop
|
||||
// capture API is active by default.
|
||||
// We keep the desktop effects in most times. Howerver, the screen still
|
||||
// fickers when the API is capturing the window due to limitation of current
|
||||
// implemetation. This is a known and wontFix issue in webrtc (see:
|
||||
// http://code.google.com/p/webrtc/issues/detail?id=3373)
|
||||
options.set_disable_effects(false);
|
||||
#endif
|
||||
|
||||
scoped_ptr<webrtc::ScreenCapturer> screen_capturer(
|
||||
capture_screen ? webrtc::ScreenCapturer::Create(options) : nullptr);
|
||||
scoped_ptr<webrtc::WindowCapturer> window_capturer(
|
||||
capture_window ? webrtc::WindowCapturer::Create(options) : nullptr);
|
||||
media_list_.reset(new NativeDesktopMediaList(screen_capturer.Pass(),
|
||||
window_capturer.Pass()));
|
||||
|
||||
media_list_->SetThumbnailSize(thumbnail_size);
|
||||
media_list_->StartUpdating(this);
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceAdded(int index) {
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceRemoved(int index) {
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceMoved(int old_index, int new_index) {
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceNameChanged(int index) {
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceThumbnailChanged(int index) {
|
||||
}
|
||||
|
||||
bool DesktopCapturer::OnRefreshFinished() {
|
||||
Emit("finished", media_list_->GetSources());
|
||||
media_list_.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new DesktopCapturer);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("desktopCapturer", atom::api::DesktopCapturer::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_desktop_capturer, Initialize);
|
52
atom/browser/api/atom_api_desktop_capturer.h
Normal file
52
atom/browser/api/atom_api_desktop_capturer.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
// 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_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "chrome/browser/media/desktop_media_list_observer.h"
|
||||
#include "chrome/browser/media/native_desktop_media_list.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class DesktopCapturer: public mate::EventEmitter,
|
||||
public DesktopMediaListObserver {
|
||||
public:
|
||||
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||
|
||||
void StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size);
|
||||
|
||||
protected:
|
||||
DesktopCapturer();
|
||||
~DesktopCapturer();
|
||||
|
||||
// DesktopMediaListObserver overrides.
|
||||
void OnSourceAdded(int index) override;
|
||||
void OnSourceRemoved(int index) override;
|
||||
void OnSourceMoved(int old_index, int new_index) override;
|
||||
void OnSourceNameChanged(int index) override;
|
||||
void OnSourceThumbnailChanged(int index) override;
|
||||
bool OnRefreshFinished() override;
|
||||
|
||||
private:
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
scoped_ptr<DesktopMediaList> media_list_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
|
@ -51,7 +51,7 @@ struct ClearStorageDataOptions {
|
|||
uint32 GetStorageMask(const std::vector<std::string>& storage_types) {
|
||||
uint32 storage_mask = 0;
|
||||
for (const auto& it : storage_types) {
|
||||
auto type = base::StringToLowerASCII(it);
|
||||
auto type = base::ToLowerASCII(it);
|
||||
if (type == "appcache")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_APPCACHE;
|
||||
else if (type == "cookies")
|
||||
|
@ -75,7 +75,7 @@ uint32 GetStorageMask(const std::vector<std::string>& storage_types) {
|
|||
uint32 GetQuotaMask(const std::vector<std::string>& quota_types) {
|
||||
uint32 quota_mask = 0;
|
||||
for (const auto& it : quota_types) {
|
||||
auto type = base::StringToLowerASCII(it);
|
||||
auto type = base::ToLowerASCII(it);
|
||||
if (type == "temporary")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY;
|
||||
else if (type == "persistent")
|
||||
|
@ -233,7 +233,8 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
|
|||
const net::ProxyConfig& config,
|
||||
const base::Closure& callback) {
|
||||
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
||||
proxy_service->ResetConfigService(new net::ProxyConfigServiceFixed(config));
|
||||
proxy_service->ResetConfigService(make_scoped_ptr(
|
||||
new net::ProxyConfigServiceFixed(config)));
|
||||
// Refetches and applies the new pac script if provided.
|
||||
proxy_service->ForceReloadProxyConfig();
|
||||
RunCallbackInUI(callback);
|
||||
|
|
|
@ -148,7 +148,7 @@ struct Converter<net::HttpResponseHeaders*> {
|
|||
std::string key;
|
||||
std::string value;
|
||||
while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
|
||||
key = base::StringToLowerASCII(key);
|
||||
key = base::ToLowerASCII(key);
|
||||
if (response_headers.HasKey(key)) {
|
||||
base::ListValue* values = nullptr;
|
||||
if (response_headers.GetList(key, &values))
|
||||
|
@ -171,7 +171,7 @@ struct Converter<content::SavePageType> {
|
|||
std::string save_type;
|
||||
if (!ConvertFromV8(isolate, val, &save_type))
|
||||
return false;
|
||||
save_type = base::StringToLowerASCII(save_type);
|
||||
save_type = base::ToLowerASCII(save_type);
|
||||
if (save_type == "htmlonly") {
|
||||
*out = content::SAVE_PAGE_TYPE_AS_ONLY_HTML;
|
||||
} else if (save_type == "htmlcomplete") {
|
||||
|
|
|
@ -159,6 +159,10 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
|||
Window::~Window() {
|
||||
if (!window_->IsClosed())
|
||||
window_->CloseContents(nullptr);
|
||||
|
||||
// Destroy the native window in next tick because the native code might be
|
||||
// iterating all windows.
|
||||
base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
|
||||
}
|
||||
|
||||
void Window::WillCloseWindow(bool* prevent_default) {
|
||||
|
@ -484,6 +488,10 @@ bool Window::IsDocumentEdited() {
|
|||
return window_->IsDocumentEdited();
|
||||
}
|
||||
|
||||
void Window::SetIgnoreMouseEvents(bool ignore) {
|
||||
return window_->SetIgnoreMouseEvents(ignore);
|
||||
}
|
||||
|
||||
void Window::CapturePage(mate::Arguments* args) {
|
||||
gfx::Rect rect;
|
||||
base::Callback<void(const gfx::Image&)> callback;
|
||||
|
@ -658,6 +666,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
|
||||
.SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents)
|
||||
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
|
||||
.SetMethod("blurWebView", &Window::BlurWebView)
|
||||
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
|
||||
|
|
|
@ -126,6 +126,7 @@ class Window : public mate::TrackableObject<Window>,
|
|||
std::string GetRepresentedFilename();
|
||||
void SetDocumentEdited(bool edited);
|
||||
bool IsDocumentEdited();
|
||||
void SetIgnoreMouseEvents(bool ignore);
|
||||
void CapturePage(mate::Arguments* args);
|
||||
void SetProgressBar(double progress);
|
||||
void SetOverlayIcon(const gfx::Image& overlay,
|
||||
|
|
|
@ -24,12 +24,11 @@ bool FrameSubscriber::ShouldCaptureFrame(
|
|||
base::TimeTicks present_time,
|
||||
scoped_refptr<media::VideoFrame>* storage,
|
||||
DeliverFrameCallback* callback) {
|
||||
*storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_,
|
||||
gfx::Rect(size_), size_,
|
||||
base::TimeDelta());
|
||||
*storage = media::VideoFrame::CreateFrame(
|
||||
media::PIXEL_FORMAT_YV12,
|
||||
size_, gfx::Rect(size_), size_, base::TimeDelta());
|
||||
*callback = base::Bind(&FrameSubscriber::OnFrameDelivered,
|
||||
base::Unretained(this),
|
||||
*storage);
|
||||
base::Unretained(this), *storage);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ class MenuItem
|
|||
|
||||
{click, @selector, @type, @role, @label, @sublabel, @accelerator, @icon, @enabled, @visible, @checked, @submenu} = options
|
||||
|
||||
if @submenu? and @submenu.constructor isnt Menu
|
||||
@submenu = Menu.buildFromTemplate @submenu
|
||||
@type = 'submenu' if not @type? and @submenu?
|
||||
throw new Error('Invalid submenu') if @type is 'submenu' and @submenu?.constructor isnt Menu
|
||||
|
||||
|
|
|
@ -169,9 +169,8 @@ Menu.buildFromTemplate = (template) ->
|
|||
for item in positionedTemplate
|
||||
throw new TypeError('Invalid template for MenuItem') unless typeof item is 'object'
|
||||
|
||||
item.submenu = Menu.buildFromTemplate item.submenu if item.submenu?
|
||||
menuItem = new MenuItem(item)
|
||||
menuItem[key] = value for key, value of item when not menuItem[key]?
|
||||
menuItem[key] ?= value for key, value of item
|
||||
menu.append menuItem
|
||||
|
||||
menu
|
||||
|
|
|
@ -84,7 +84,7 @@ void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
|
|||
|
||||
void AtomBrowserClient::SetCustomSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
g_custom_schemes = JoinString(schemes, ',');
|
||||
g_custom_schemes = base::JoinString(schemes, ",");
|
||||
}
|
||||
|
||||
AtomBrowserClient::AtomBrowserClient() : delegate_(nullptr) {
|
||||
|
@ -116,7 +116,6 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
|||
prefs->javascript_can_open_windows_automatically = true;
|
||||
prefs->plugins_enabled = true;
|
||||
prefs->dom_paste_enabled = true;
|
||||
prefs->java_enabled = false;
|
||||
prefs->allow_scripts_to_close_windows = true;
|
||||
prefs->javascript_can_access_clipboard = true;
|
||||
prefs->local_storage_enabled = true;
|
||||
|
|
|
@ -61,7 +61,7 @@ std::string RemoveWhitespace(const std::string& str) {
|
|||
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
bool in_memory)
|
||||
: brightray::BrowserContext(partition, in_memory),
|
||||
cert_verifier_(new AtomCertVerifier),
|
||||
cert_verifier_(nullptr),
|
||||
job_factory_(new AtomURLRequestJobFactory),
|
||||
allow_ntlm_everywhere_(false) {
|
||||
}
|
||||
|
@ -86,7 +86,8 @@ std::string AtomBrowserContext::GetUserAgent() {
|
|||
return content::BuildUserAgentFromProduct(user_agent);
|
||||
}
|
||||
|
||||
net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
|
||||
scoped_ptr<net::URLRequestJobFactory>
|
||||
AtomBrowserContext::CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* handlers,
|
||||
content::URLRequestInterceptorScopedVector* interceptors) {
|
||||
scoped_ptr<AtomURLRequestJobFactory> job_factory(job_factory_);
|
||||
|
@ -131,7 +132,7 @@ net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
|
|||
top_job_factory.Pass(), make_scoped_ptr(*it)));
|
||||
interceptors->weak_clear();
|
||||
|
||||
return top_job_factory.release();
|
||||
return top_job_factory.Pass();
|
||||
}
|
||||
|
||||
net::HttpCache::BackendFactory*
|
||||
|
@ -160,8 +161,10 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
|
|||
return guest_manager_.get();
|
||||
}
|
||||
|
||||
net::CertVerifier* AtomBrowserContext::CreateCertVerifier() {
|
||||
return cert_verifier_;
|
||||
scoped_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() {
|
||||
DCHECK(!cert_verifier_);
|
||||
cert_verifier_ = new AtomCertVerifier;
|
||||
return make_scoped_ptr(cert_verifier_);
|
||||
}
|
||||
|
||||
net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
|
||||
|
|
|
@ -23,12 +23,12 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
|||
|
||||
// brightray::URLRequestContextGetter::Delegate:
|
||||
std::string GetUserAgent() override;
|
||||
net::URLRequestJobFactory* CreateURLRequestJobFactory(
|
||||
scoped_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* handlers,
|
||||
content::URLRequestInterceptorScopedVector* interceptors) override;
|
||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) override;
|
||||
net::CertVerifier* CreateCertVerifier() override;
|
||||
scoped_ptr<net::CertVerifier> CreateCertVerifier() override;
|
||||
net::SSLConfigService* CreateSSLConfigService() override;
|
||||
bool AllowNTLMCredentialsForDomain(const GURL& auth_origin) override;
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
|
|||
|
||||
PCWSTR Browser::GetAppUserModelID() {
|
||||
if (app_user_model_id_.empty()) {
|
||||
SetAppUserModelID(ReplaceStringPlaceholders(
|
||||
SetAppUserModelID(base::ReplaceStringPlaceholders(
|
||||
kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr));
|
||||
}
|
||||
|
||||
|
|
|
@ -380,7 +380,7 @@ gfx::ImageSkia CommonWebContentsDelegate::GetDevToolsWindowIcon() {
|
|||
void CommonWebContentsDelegate::GetDevToolsWindowWMClass(
|
||||
std::string* name, std::string* class_name) {
|
||||
*class_name = Browser::Get()->GetName();
|
||||
*name = base::StringToLowerASCII(*class_name);
|
||||
*name = base::ToLowerASCII(*class_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
37
atom/browser/lib/desktop-capturer.coffee
Normal file
37
atom/browser/lib/desktop-capturer.coffee
Normal file
|
@ -0,0 +1,37 @@
|
|||
{ipcMain} = require 'electron'
|
||||
{desktopCapturer} = process.atomBinding 'desktop_capturer'
|
||||
|
||||
deepEqual = (opt1, opt2) ->
|
||||
return JSON.stringify(opt1) is JSON.stringify(opt2)
|
||||
|
||||
# A queue for holding all requests from renderer process.
|
||||
requestsQueue = []
|
||||
|
||||
ipcMain.on 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', (event, captureWindow, captureScreen, thumbnailSize, id) ->
|
||||
request = id: id, options: {captureWindow, captureScreen, thumbnailSize}, webContents: event.sender
|
||||
requestsQueue.push request
|
||||
desktopCapturer.startHandling captureWindow, captureScreen, thumbnailSize if requestsQueue.length is 1
|
||||
# If the WebContents is destroyed before receiving result, just remove the
|
||||
# reference from requestsQueue to make the module not send the result to it.
|
||||
event.sender.once 'destroyed', ->
|
||||
request.webContents = null
|
||||
|
||||
desktopCapturer.emit = (event, name, sources) ->
|
||||
# Receiving sources result from main process, now send them back to renderer.
|
||||
handledRequest = requestsQueue.shift 0
|
||||
result = ({ id: source.id, name: source.name, thumbnail: source.thumbnail.toDataUrl() } for source in sources)
|
||||
handledRequest.webContents?.send "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{handledRequest.id}", result
|
||||
|
||||
# Check the queue to see whether there is other same request. If has, handle
|
||||
# it for reducing redunplicated `desktopCaptuer.startHandling` calls.
|
||||
unhandledRequestsQueue = []
|
||||
for request in requestsQueue
|
||||
if deepEqual handledRequest.options, request.options
|
||||
request.webContents?.send "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{request.id}", errorMessage, result
|
||||
else
|
||||
unhandledRequestsQueue.push request
|
||||
requestsQueue = unhandledRequestsQueue
|
||||
# If the requestsQueue is not empty, start a new request handling.
|
||||
if requestsQueue.length > 0
|
||||
{captureWindow, captureScreen, thumbnailSize} = requestsQueue[0].options
|
||||
desktopCapturer.startHandling captureWindow, captureScreen, thumbnailSize
|
|
@ -5,7 +5,7 @@ frameToGuest = {}
|
|||
|
||||
# Copy attribute of |parent| to |child| if it is not defined in |child|.
|
||||
mergeOptions = (child, parent) ->
|
||||
for own key, value of parent when key not in Object.keys child
|
||||
for own key, value of parent when key not of child
|
||||
if typeof value is 'object'
|
||||
child[key] = mergeOptions {}, value
|
||||
else
|
||||
|
@ -44,7 +44,7 @@ createGuest = (embedder, url, frameName, options) ->
|
|||
guest.removeListener 'closed', closedByUser
|
||||
guest.destroy()
|
||||
closedByUser = ->
|
||||
embedder.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', guestId
|
||||
embedder.send "ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_#{guestId}"
|
||||
embedder.removeListener 'render-view-deleted', closedByEmbedder
|
||||
embedder.once 'render-view-deleted', closedByEmbedder
|
||||
guest.once 'closed', closedByUser
|
||||
|
|
|
@ -108,6 +108,9 @@ app.setAppPath packagePath
|
|||
# Load the chrome extension support.
|
||||
require './chrome-extension'
|
||||
|
||||
# Load internal desktop-capturer module.
|
||||
require './desktop-capturer'
|
||||
|
||||
# Set main startup script of the app.
|
||||
mainStartupScript = packageJson.main or 'index.js'
|
||||
|
||||
|
|
|
@ -245,6 +245,9 @@ bool NativeWindow::IsDocumentEdited() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void NativeWindow::SetIgnoreMouseEvents(bool ignore) {
|
||||
}
|
||||
|
||||
void NativeWindow::SetMenu(ui::MenuModel* menu) {
|
||||
}
|
||||
|
||||
|
@ -291,10 +294,10 @@ void NativeWindow::CapturePage(const gfx::Rect& rect,
|
|||
const float scale =
|
||||
screen->GetDisplayNearestWindow(native_view).device_scale_factor();
|
||||
if (scale > 1.0f)
|
||||
bitmap_size = gfx::ToCeiledSize(gfx::ScaleSize(view_size, scale));
|
||||
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
|
||||
|
||||
host->CopyFromBackingStore(
|
||||
rect.IsEmpty() ? gfx::Rect(view_size) : rect,
|
||||
gfx::Rect(view_size),
|
||||
bitmap_size,
|
||||
base::Bind(&NativeWindow::OnCapturePageDone,
|
||||
weak_factory_.GetWeakPtr(),
|
||||
|
|
|
@ -139,6 +139,7 @@ class NativeWindow : public base::SupportsUserData,
|
|||
virtual std::string GetRepresentedFilename();
|
||||
virtual void SetDocumentEdited(bool edited);
|
||||
virtual bool IsDocumentEdited();
|
||||
virtual void SetIgnoreMouseEvents(bool ignore);
|
||||
virtual void SetMenu(ui::MenuModel* menu);
|
||||
virtual bool HasModalDialog();
|
||||
virtual gfx::NativeWindow GetNativeWindow() = 0;
|
||||
|
|
|
@ -62,6 +62,7 @@ class NativeWindowMac : public NativeWindow {
|
|||
std::string GetRepresentedFilename() override;
|
||||
void SetDocumentEdited(bool edited) override;
|
||||
bool IsDocumentEdited() override;
|
||||
void SetIgnoreMouseEvents(bool ignore) override;
|
||||
bool HasModalDialog() override;
|
||||
gfx::NativeWindow GetNativeWindow() override;
|
||||
void SetProgressBar(double progress) override;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#import "atom/browser/ui/cocoa/event_processing_window.h"
|
||||
#include "atom/common/draggable_region.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
|
@ -209,7 +208,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
|||
|
||||
@end
|
||||
|
||||
@interface AtomNSWindow : EventProcessingWindow {
|
||||
@interface AtomNSWindow : NSWindow {
|
||||
@private
|
||||
atom::NativeWindowMac* shell_;
|
||||
bool enable_larger_than_screen_;
|
||||
|
@ -232,6 +231,8 @@ bool ScopedDisableResize::disable_resize_ = false;
|
|||
enable_larger_than_screen_ = enable;
|
||||
}
|
||||
|
||||
// NSWindow overrides.
|
||||
|
||||
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen {
|
||||
// Resizing is disabled.
|
||||
if (ScopedDisableResize::IsResizeDisabled())
|
||||
|
@ -687,6 +688,10 @@ bool NativeWindowMac::IsDocumentEdited() {
|
|||
return [window_ isDocumentEdited];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetIgnoreMouseEvents(bool ignore) {
|
||||
[window_ setIgnoresMouseEvents:ignore];
|
||||
}
|
||||
|
||||
bool NativeWindowMac::HasModalDialog() {
|
||||
return [window_ attachedSheet] != nil;
|
||||
}
|
||||
|
@ -766,20 +771,14 @@ void NativeWindowMac::HandleKeyboardEvent(
|
|||
event.type == content::NativeWebKeyboardEvent::Char)
|
||||
return;
|
||||
|
||||
if (event.os_event.window == window_.get()) {
|
||||
EventProcessingWindow* event_window =
|
||||
static_cast<EventProcessingWindow*>(window_);
|
||||
DCHECK([event_window isKindOfClass:[EventProcessingWindow class]]);
|
||||
[event_window redispatchKeyEvent:event.os_event];
|
||||
} else {
|
||||
BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event];
|
||||
if (!handled && event.os_event.window != window_.get()) {
|
||||
// The event comes from detached devtools view, and it has already been
|
||||
// handled by the devtools itself, we now send it to application menu to
|
||||
// make menu acclerators work.
|
||||
BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event];
|
||||
// Handle the cmd+~ shortcut.
|
||||
if (!handled && (event.os_event.modifierFlags & NSCommandKeyMask) &&
|
||||
(event.os_event.keyCode == 50 /* ~ key */))
|
||||
(event.os_event.keyCode == 50 /* ~ key */)) {
|
||||
// Handle the cmd+~ shortcut.
|
||||
Focus(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ NativeWindowViews::NativeWindowViews(
|
|||
// Set WM_WINDOW_ROLE.
|
||||
params.wm_role_name = "browser-window";
|
||||
// Set WM_CLASS.
|
||||
params.wm_class_name = base::StringToLowerASCII(name);
|
||||
params.wm_class_name = base::ToLowerASCII(name);
|
||||
params.wm_class_class = name;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/url_fetcher.h"
|
||||
#include "net/url_request/url_fetcher_response_writer.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_builder.h"
|
||||
#include "net/url_request/url_request_status.h"
|
||||
|
||||
|
@ -23,7 +24,7 @@ namespace {
|
|||
|
||||
// Convert string to RequestType.
|
||||
net::URLFetcher::RequestType GetRequestType(const std::string& raw) {
|
||||
std::string method = base::StringToUpperASCII(raw);
|
||||
std::string method = base::ToUpperASCII(raw);
|
||||
if (method.empty() || method == "GET")
|
||||
return net::URLFetcher::GET;
|
||||
else if (method == "POST")
|
||||
|
@ -138,8 +139,9 @@ net::URLRequestContextGetter* URLRequestFetchJob::CreateRequestContext() {
|
|||
auto task_runner = base::ThreadTaskRunnerHandle::Get();
|
||||
net::URLRequestContextBuilder builder;
|
||||
builder.set_proxy_service(net::ProxyService::CreateDirect());
|
||||
url_request_context_getter_ =
|
||||
new net::TrivialURLRequestContextGetter(builder.Build(), task_runner);
|
||||
request_context_ = builder.Build();
|
||||
url_request_context_getter_ = new net::TrivialURLRequestContextGetter(
|
||||
request_context_.get(), task_runner);
|
||||
}
|
||||
return url_request_context_getter_.get();
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ class URLRequestFetchJob : public JsAsker<net::URLRequestJob>,
|
|||
// Create a independent request context.
|
||||
net::URLRequestContextGetter* CreateRequestContext();
|
||||
|
||||
scoped_ptr<net::URLRequestContext> request_context_;
|
||||
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
|
||||
scoped_ptr<net::URLFetcher> fetcher_;
|
||||
scoped_refptr<net::IOBuffer> pending_buffer_;
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
<key>CFBundleIconFile</key>
|
||||
<string>atom.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.35.2</string>
|
||||
<string>0.35.4</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.35.2</string>
|
||||
<string>0.35.4</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
|
|
@ -56,8 +56,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,35,2,0
|
||||
PRODUCTVERSION 0,35,2,0
|
||||
FILEVERSION 0,35,4,0
|
||||
PRODUCTVERSION 0,35,4,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -74,12 +74,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "0.35.2"
|
||||
VALUE "FileVersion", "0.35.4"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "0.35.2"
|
||||
VALUE "ProductVersion", "0.35.4"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
|
|
@ -24,10 +24,10 @@ bool StringToAccelerator(const std::string& description,
|
|||
LOG(ERROR) << "The accelerator string can only contain ASCII characters";
|
||||
return false;
|
||||
}
|
||||
std::string shortcut(base::StringToLowerASCII(description));
|
||||
std::string shortcut(base::ToLowerASCII(description));
|
||||
|
||||
std::vector<std::string> tokens;
|
||||
base::SplitString(shortcut, '+', &tokens);
|
||||
std::vector<std::string> tokens = base::SplitString(
|
||||
shortcut, "+", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
|
||||
// Now, parse it into an accelerator.
|
||||
int modifiers = ui::EF_NONE;
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_
|
||||
#define ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
// Override NSWindow to access unhandled keyboard events (for command
|
||||
// processing); subclassing NSWindow is the only method to do
|
||||
// this.
|
||||
@interface EventProcessingWindow : NSWindow {
|
||||
@private
|
||||
BOOL redispatchingEvent_;
|
||||
BOOL eventHandled_;
|
||||
}
|
||||
|
||||
// Sends a key event to |NSApp sendEvent:|, but also makes sure that it's not
|
||||
// short-circuited to the RWHV. This is used to send keyboard events to the menu
|
||||
// and the cmd-` handler if a keyboard event comes back unhandled from the
|
||||
// renderer. The event must be of type |NSKeyDown|, |NSKeyUp|, or
|
||||
// |NSFlagsChanged|.
|
||||
// Returns |YES| if |event| has been handled.
|
||||
- (BOOL)redispatchKeyEvent:(NSEvent*)event;
|
||||
|
||||
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
|
||||
@end
|
||||
|
||||
#endif // ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_
|
|
@ -1,106 +0,0 @@
|
|||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "atom/browser/ui/cocoa/event_processing_window.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#import "content/public/browser/render_widget_host_view_mac_base.h"
|
||||
|
||||
@interface EventProcessingWindow ()
|
||||
// Duplicate the given key event, but changing the associated window.
|
||||
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event;
|
||||
@end
|
||||
|
||||
@implementation EventProcessingWindow
|
||||
|
||||
- (BOOL)redispatchKeyEvent:(NSEvent*)event {
|
||||
DCHECK(event);
|
||||
NSEventType eventType = [event type];
|
||||
if (eventType != NSKeyDown &&
|
||||
eventType != NSKeyUp &&
|
||||
eventType != NSFlagsChanged) {
|
||||
NOTREACHED();
|
||||
return YES; // Pretend it's been handled in an effort to limit damage.
|
||||
}
|
||||
|
||||
// Ordinarily, the event's window should be this window. However, when
|
||||
// switching between normal and fullscreen mode, we switch out the window, and
|
||||
// the event's window might be the previous window (or even an earlier one if
|
||||
// the renderer is running slowly and several mode switches occur). In this
|
||||
// rare case, we synthesize a new key event so that its associate window
|
||||
// (number) is our own.
|
||||
if ([event window] != self)
|
||||
event = [self keyEventForWindow:self fromKeyEvent:event];
|
||||
|
||||
// Redispatch the event.
|
||||
eventHandled_ = YES;
|
||||
redispatchingEvent_ = YES;
|
||||
[NSApp sendEvent:event];
|
||||
redispatchingEvent_ = NO;
|
||||
|
||||
// If the event was not handled by [NSApp sendEvent:], the sendEvent:
|
||||
// method below will be called, and because |redispatchingEvent_| is YES,
|
||||
// |eventHandled_| will be set to NO.
|
||||
return eventHandled_;
|
||||
}
|
||||
|
||||
- (void)sendEvent:(NSEvent*)event {
|
||||
if (!redispatchingEvent_)
|
||||
[super sendEvent:event];
|
||||
else
|
||||
eventHandled_ = NO;
|
||||
}
|
||||
|
||||
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event {
|
||||
NSEventType eventType = [event type];
|
||||
|
||||
// Convert the event's location from the original window's coordinates into
|
||||
// our own.
|
||||
NSPoint eventLoc = [event locationInWindow];
|
||||
eventLoc = [self convertRectFromScreen:
|
||||
[[event window] convertRectToScreen:NSMakeRect(eventLoc.x, eventLoc.y, 0, 0)]].origin;
|
||||
|
||||
// Various things *only* apply to key down/up.
|
||||
BOOL eventIsARepeat = NO;
|
||||
NSString* eventCharacters = nil;
|
||||
NSString* eventUnmodCharacters = nil;
|
||||
if (eventType == NSKeyDown || eventType == NSKeyUp) {
|
||||
eventIsARepeat = [event isARepeat];
|
||||
eventCharacters = [event characters];
|
||||
eventUnmodCharacters = [event charactersIgnoringModifiers];
|
||||
}
|
||||
|
||||
// This synthesis may be slightly imperfect: we provide nil for the context,
|
||||
// since I (viettrungluu) am sceptical that putting in the original context
|
||||
// (if one is given) is valid.
|
||||
return [NSEvent keyEventWithType:eventType
|
||||
location:eventLoc
|
||||
modifierFlags:[event modifierFlags]
|
||||
timestamp:[event timestamp]
|
||||
windowNumber:[window windowNumber]
|
||||
context:nil
|
||||
characters:eventCharacters
|
||||
charactersIgnoringModifiers:eventUnmodCharacters
|
||||
isARepeat:eventIsARepeat
|
||||
keyCode:[event keyCode]];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)performKeyEquivalent:(NSEvent*)event {
|
||||
if (redispatchingEvent_)
|
||||
return NO;
|
||||
|
||||
// Give the web site a chance to handle the event. If it doesn't want to
|
||||
// handle it, it will call us back with one of the |handle*| methods above.
|
||||
NSResponder* r = [self firstResponder];
|
||||
if ([r conformsToProtocol:@protocol(RenderWidgetHostViewMacBase)])
|
||||
return [r performKeyEquivalent:event];
|
||||
|
||||
if ([super performKeyEquivalent:event])
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end // EventProcessingWindow
|
|
@ -22,7 +22,9 @@ gboolean FileFilterCaseInsensitive(const GtkFileFilterInfo* file_info,
|
|||
// Makes .* file extension matches all file types.
|
||||
if (*file_extension == ".*")
|
||||
return true;
|
||||
return base::EndsWith(file_info->filename, *file_extension, false);
|
||||
return base::EndsWith(
|
||||
file_info->filename,
|
||||
*file_extension, base::CompareCase::INSENSITIVE_ASCII);
|
||||
}
|
||||
|
||||
// Deletes |data| when gtk_file_filter_add_custom() is done with it.
|
||||
|
|
|
@ -51,7 +51,7 @@ void ConvertFilters(const Filters& filters,
|
|||
std::vector<std::string> extensions(filter.second);
|
||||
for (size_t j = 0; j < extensions.size(); ++j)
|
||||
extensions[j].insert(0, "*.");
|
||||
buffer->push_back(base::UTF8ToWide(JoinString(extensions, ";")));
|
||||
buffer->push_back(base::UTF8ToWide(base::JoinString(extensions, ";")));
|
||||
spec.pszSpec = buffer->back().c_str();
|
||||
|
||||
filterspec->push_back(spec);
|
||||
|
@ -273,7 +273,9 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
|
|||
bool matched = false;
|
||||
for (size_t i = 0; i < filter.second.size(); ++i) {
|
||||
if (filter.second[i] == "*" ||
|
||||
base::EndsWith(file_name, filter.second[i], false)) {
|
||||
base::EndsWith(
|
||||
file_name, filter.second[i],
|
||||
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||
matched = true;
|
||||
break;;
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ class GtkMessageBox {
|
|||
}
|
||||
|
||||
const char* TranslateToStock(int id, const std::string& text) {
|
||||
std::string lower = base::StringToLowerASCII(text);
|
||||
std::string lower = base::ToLowerASCII(text);
|
||||
if (lower == "cancel")
|
||||
return GTK_STOCK_CANCEL;
|
||||
else if (lower == "no")
|
||||
|
|
|
@ -34,7 +34,7 @@ struct CommonButtonID {
|
|||
int id;
|
||||
};
|
||||
CommonButtonID GetCommonID(const base::string16& button) {
|
||||
base::string16 lower = base::StringToLowerASCII(button);
|
||||
base::string16 lower = base::ToLowerASCII(button);
|
||||
if (lower == L"ok")
|
||||
return { TDCBF_OK_BUTTON, IDOK };
|
||||
else if (lower == L"yes")
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#if defined(OS_WIN)
|
||||
#include "ui/gfx/color_utils.h"
|
||||
#elif defined(USE_X11)
|
||||
#include "chrome/browser/ui/libgtk2ui/owned_widget_gtk2.h"
|
||||
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
|
||||
#endif
|
||||
|
||||
|
@ -33,15 +32,16 @@ const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233);
|
|||
#if defined(USE_X11)
|
||||
void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight,
|
||||
SkColor* hover, SkColor* background) {
|
||||
libgtk2ui::OwnedWidgetGtk fake_menu_bar;
|
||||
fake_menu_bar.Own(gtk_menu_bar_new());
|
||||
GtkWidget* menu_bar = gtk_menu_bar_new();
|
||||
|
||||
GtkStyle* style = gtk_rc_get_style(fake_menu_bar.get());
|
||||
GtkStyle* style = gtk_rc_get_style(menu_bar);
|
||||
*enabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_NORMAL]);
|
||||
*disabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_INSENSITIVE]);
|
||||
*highlight = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_SELECTED]);
|
||||
*hover = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_PRELIGHT]);
|
||||
*background = libgtk2ui::GdkColorToSkColor(style->bg[GTK_STATE_NORMAL]);
|
||||
|
||||
gtk_widget_destroy(menu_bar);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ void SetWindowType(::Window xwindow, const std::string& type) {
|
|||
XDisplay* xdisplay = gfx::GetXDisplay();
|
||||
std::string type_prefix = "_NET_WM_WINDOW_TYPE_";
|
||||
::Atom window_type = XInternAtom(
|
||||
xdisplay, (type_prefix + base::StringToUpperASCII(type)).c_str(), False);
|
||||
xdisplay, (type_prefix + base::ToUpperASCII(type)).c_str(), False);
|
||||
XChangeProperty(xdisplay, xwindow,
|
||||
XInternAtom(xdisplay, "_NET_WM_WINDOW_TYPE", False),
|
||||
XA_ATOM,
|
||||
|
|
|
@ -36,8 +36,6 @@ FeaturePair kWebRuntimeFeatures[] = {
|
|||
switches::kExperimentalCanvasFeatures },
|
||||
{ options::kOverlayScrollbars,
|
||||
switches::kOverlayScrollbars },
|
||||
{ options::kOverlayFullscreenVideo,
|
||||
switches::kOverlayFullscreenVideo },
|
||||
{ options::kSharedWorker,
|
||||
switches::kSharedWorker },
|
||||
{ options::kPageVisibility,
|
||||
|
@ -148,8 +146,6 @@ void WebContentsPreferences::OverrideWebkitPrefs(
|
|||
prefs->javascript_enabled = b;
|
||||
if (self->web_preferences_.GetBoolean("images", &b))
|
||||
prefs->images_enabled = b;
|
||||
if (self->web_preferences_.GetBoolean("java", &b))
|
||||
prefs->java_enabled = b;
|
||||
if (self->web_preferences_.GetBoolean("textAreasAreResizable", &b))
|
||||
prefs->text_areas_are_resizable = b;
|
||||
if (self->web_preferences_.GetBoolean("webgl", &b))
|
||||
|
|
|
@ -63,7 +63,8 @@ float GetScaleFactorFromPath(const base::FilePath& path) {
|
|||
// We don't try to convert string to float here because it is very very
|
||||
// expensive.
|
||||
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
|
||||
if (base::EndsWith(filename, kScaleFactorPairs[i].name, true))
|
||||
if (base::EndsWith(filename, kScaleFactorPairs[i].name,
|
||||
base::CompareCase::INSENSITIVE_ASCII))
|
||||
return kScaleFactorPairs[i].scale;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ v8::Local<v8::Value> CallEmitWithArgs(v8::Isolate* isolate,
|
|||
// Perform microtask checkpoint after running JavaScript.
|
||||
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
||||
Locker::IsBrowserProcess() ?
|
||||
nullptr : new blink::WebScopedRunV8Script(isolate));
|
||||
nullptr : new blink::WebScopedRunV8Script);
|
||||
// Use node::MakeCallback to call the callback, and it will also run pending
|
||||
// tasks in Node.js.
|
||||
return node::MakeCallback(
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#define ATOM_MAJOR_VERSION 0
|
||||
#define ATOM_MINOR_VERSION 35
|
||||
#define ATOM_PATCH_VERSION 2
|
||||
#define ATOM_PATCH_VERSION 4
|
||||
|
||||
#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 "45.0.2454.85"
|
||||
#define CHROME_VERSION_STRING "47.0.2526.73"
|
||||
#define CHROME_VERSION "v" CHROME_VERSION_STRING
|
||||
|
||||
#endif // ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
|
|
@ -48,11 +48,11 @@ CrashReporter::GetUploadedReports(const std::string& path) {
|
|||
std::vector<CrashReporter::UploadReportResult> result;
|
||||
if (base::ReadFileToString(base::FilePath::FromUTF8Unsafe(path),
|
||||
&file_content)) {
|
||||
std::vector<std::string> reports;
|
||||
base::SplitString(file_content, '\n', &reports);
|
||||
std::vector<std::string> reports = base::SplitString(
|
||||
file_content, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
for (const std::string& report : reports) {
|
||||
std::vector<std::string> report_item;
|
||||
base::SplitString(report, ',', &report_item);
|
||||
std::vector<std::string> report_item = base::SplitString(
|
||||
report, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
int report_time = 0;
|
||||
if (report_item.size() >= 2 && base::StringToInt(report_item[0],
|
||||
&report_time)) {
|
||||
|
|
|
@ -130,7 +130,7 @@ bool CrashReporterLinux::CrashDone(const MinidumpDescriptor& minidump,
|
|||
|
||||
// static
|
||||
CrashReporterLinux* CrashReporterLinux::GetInstance() {
|
||||
return Singleton<CrashReporterLinux>::get();
|
||||
return base::Singleton<CrashReporterLinux>::get();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
#include "base/compiler_specific.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
namespace base {
|
||||
template <typename T> struct DefaultSingletonTraits;
|
||||
}
|
||||
|
||||
namespace google_breakpad {
|
||||
class ExceptionHandler;
|
||||
|
@ -34,7 +36,7 @@ class CrashReporterLinux : public CrashReporter {
|
|||
void SetUploadParameters() override;
|
||||
|
||||
private:
|
||||
friend struct DefaultSingletonTraits<CrashReporterLinux>;
|
||||
friend struct base::DefaultSingletonTraits<CrashReporterLinux>;
|
||||
|
||||
CrashReporterLinux();
|
||||
virtual ~CrashReporterLinux();
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
#include "base/strings/string_piece.h"
|
||||
#include "vendor/crashpad/client/simple_string_dictionary.h"
|
||||
|
||||
namespace base {
|
||||
template <typename T> struct DefaultSingletonTraits;
|
||||
}
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
|
@ -31,7 +33,7 @@ class CrashReporterMac : public CrashReporter {
|
|||
void SetUploadParameters() override;
|
||||
|
||||
private:
|
||||
friend struct DefaultSingletonTraits<CrashReporterMac>;
|
||||
friend struct base::DefaultSingletonTraits<CrashReporterMac>;
|
||||
|
||||
CrashReporterMac();
|
||||
virtual ~CrashReporterMac();
|
||||
|
|
|
@ -126,7 +126,7 @@ CrashReporterMac::GetUploadedReports(const std::string& path) {
|
|||
|
||||
// static
|
||||
CrashReporterMac* CrashReporterMac::GetInstance() {
|
||||
return Singleton<CrashReporterMac>::get();
|
||||
return base::Singleton<CrashReporterMac>::get();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -153,9 +153,9 @@ void CrashReporterWin::InitBreakpad(const std::string& product_name,
|
|||
return;
|
||||
}
|
||||
|
||||
base::string16 pipe_name = ReplaceStringPlaceholders(
|
||||
base::string16 pipe_name = base::ReplaceStringPlaceholders(
|
||||
kPipeNameFormat, base::UTF8ToUTF16(product_name), NULL);
|
||||
base::string16 wait_name = ReplaceStringPlaceholders(
|
||||
base::string16 wait_name = base::ReplaceStringPlaceholders(
|
||||
kWaitEventFormat, base::UTF8ToUTF16(product_name), NULL);
|
||||
|
||||
// Wait until the crash service is started.
|
||||
|
@ -259,7 +259,7 @@ google_breakpad::CustomClientInfo* CrashReporterWin::GetCustomInfo(
|
|||
|
||||
// static
|
||||
CrashReporterWin* CrashReporterWin::GetInstance() {
|
||||
return Singleton<CrashReporterWin>::get();
|
||||
return base::Singleton<CrashReporterWin>::get();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
#include "base/memory/scoped_ptr.h"
|
||||
#include "vendor/breakpad/src/client/windows/handler/exception_handler.h"
|
||||
|
||||
namespace base {
|
||||
template <typename T> struct DefaultSingletonTraits;
|
||||
}
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
|
@ -33,7 +35,7 @@ class CrashReporterWin : public CrashReporter {
|
|||
int CrashForException(EXCEPTION_POINTERS* info);
|
||||
|
||||
private:
|
||||
friend struct DefaultSingletonTraits<CrashReporterWin>;
|
||||
friend struct base::DefaultSingletonTraits<CrashReporterWin>;
|
||||
|
||||
CrashReporterWin();
|
||||
virtual ~CrashReporterWin();
|
||||
|
|
|
@ -118,7 +118,7 @@ HWND g_top_window = NULL;
|
|||
bool CreateTopWindow(HINSTANCE instance,
|
||||
const base::string16& application_name,
|
||||
bool visible) {
|
||||
base::string16 class_name = ReplaceStringPlaceholders(
|
||||
base::string16 class_name = base::ReplaceStringPlaceholders(
|
||||
kClassNameFormat, application_name, NULL);
|
||||
|
||||
WNDCLASSEXW wcx = {0};
|
||||
|
@ -309,7 +309,7 @@ bool CrashService::Initialize(const base::string16& application_name,
|
|||
|
||||
// Create or open an event to signal the browser process that the crash
|
||||
// service is initialized.
|
||||
base::string16 wait_name = ReplaceStringPlaceholders(
|
||||
base::string16 wait_name = base::ReplaceStringPlaceholders(
|
||||
kWaitEventFormat, application_name, NULL);
|
||||
HANDLE wait_event = ::CreateEventW(NULL, TRUE, TRUE, wait_name.c_str());
|
||||
::SetEvent(wait_event);
|
||||
|
@ -524,4 +524,3 @@ PSECURITY_DESCRIPTOR CrashService::GetSecurityDescriptorForLowIntegrity() {
|
|||
}
|
||||
|
||||
} // namespace breakpad
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ int Main(const wchar_t* cmd) {
|
|||
VLOG(1) << "Session start. cmdline is [" << cmd << "]";
|
||||
|
||||
// Setting the crash reporter.
|
||||
base::string16 pipe_name = ReplaceStringPlaceholders(kPipeNameFormat,
|
||||
base::string16 pipe_name = base::ReplaceStringPlaceholders(kPipeNameFormat,
|
||||
application_name,
|
||||
NULL);
|
||||
cmd_line.AppendSwitch("no-window");
|
||||
|
|
|
@ -45,7 +45,7 @@ template<>
|
|||
struct Converter<blink::WebInputEvent::Type> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
blink::WebInputEvent::Type* out) {
|
||||
std::string type = base::StringToLowerASCII(V8ToString(val));
|
||||
std::string type = base::ToLowerASCII(V8ToString(val));
|
||||
if (type == "mousedown")
|
||||
*out = blink::WebInputEvent::MouseDown;
|
||||
else if (type == "mouseup")
|
||||
|
@ -82,7 +82,7 @@ template<>
|
|||
struct Converter<blink::WebMouseEvent::Button> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
blink::WebMouseEvent::Button* out) {
|
||||
std::string button = base::StringToLowerASCII(V8ToString(val));
|
||||
std::string button = base::ToLowerASCII(V8ToString(val));
|
||||
if (button == "left")
|
||||
*out = blink::WebMouseEvent::Button::ButtonLeft;
|
||||
else if (button == "middle")
|
||||
|
@ -97,7 +97,7 @@ template<>
|
|||
struct Converter<blink::WebInputEvent::Modifiers> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
blink::WebInputEvent::Modifiers* out) {
|
||||
std::string modifier = base::StringToLowerASCII(V8ToString(val));
|
||||
std::string modifier = base::ToLowerASCII(V8ToString(val));
|
||||
if (modifier == "shift")
|
||||
*out = blink::WebInputEvent::ShiftKey;
|
||||
else if (modifier == "control" || modifier == "ctrl")
|
||||
|
@ -166,7 +166,7 @@ bool Converter<blink::WebKeyboardEvent>::FromV8(
|
|||
out->windowsKeyCode = atom::KeyboardCodeFromCharCode(code, &shifted);
|
||||
else if (dict.Get("keyCode", &identifier))
|
||||
out->windowsKeyCode = atom::KeyboardCodeFromKeyIdentifier(
|
||||
base::StringToLowerASCII(identifier));
|
||||
base::ToLowerASCII(identifier));
|
||||
else
|
||||
return false;
|
||||
|
||||
|
@ -263,7 +263,7 @@ bool Converter<blink::WebDeviceEmulationParams>::FromV8(
|
|||
|
||||
std::string screen_position;
|
||||
if (dict.Get("screenPosition", &screen_position)) {
|
||||
screen_position = base::StringToLowerASCII(screen_position);
|
||||
screen_position = base::ToLowerASCII(screen_position);
|
||||
if (screen_position == "mobile")
|
||||
out->screenPosition = blink::WebDeviceEmulationParams::Mobile;
|
||||
else if (screen_position == "desktop")
|
||||
|
|
|
@ -51,7 +51,7 @@ struct V8FunctionInvoker<v8::Local<v8::Value>(ArgTypes...)> {
|
|||
return v8::Null(isolate);
|
||||
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
||||
Locker::IsBrowserProcess() ?
|
||||
nullptr : new blink::WebScopedRunV8Script(isolate));
|
||||
nullptr : new blink::WebScopedRunV8Script);
|
||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
@ -72,7 +72,7 @@ struct V8FunctionInvoker<void(ArgTypes...)> {
|
|||
return;
|
||||
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
||||
Locker::IsBrowserProcess() ?
|
||||
nullptr : new blink::WebScopedRunV8Script(isolate));
|
||||
nullptr : new blink::WebScopedRunV8Script);
|
||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
@ -93,7 +93,7 @@ struct V8FunctionInvoker<ReturnType(ArgTypes...)> {
|
|||
return ret;
|
||||
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
||||
Locker::IsBrowserProcess() ?
|
||||
nullptr : new blink::WebScopedRunV8Script(isolate));
|
||||
nullptr : new blink::WebScopedRunV8Script);
|
||||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
|
|
@ -35,6 +35,7 @@ REFERENCE_MODULE(atom_browser_app);
|
|||
REFERENCE_MODULE(atom_browser_auto_updater);
|
||||
REFERENCE_MODULE(atom_browser_content_tracing);
|
||||
REFERENCE_MODULE(atom_browser_dialog);
|
||||
REFERENCE_MODULE(atom_browser_desktop_capturer);
|
||||
REFERENCE_MODULE(atom_browser_download_item);
|
||||
REFERENCE_MODULE(atom_browser_menu);
|
||||
REFERENCE_MODULE(atom_browser_power_monitor);
|
||||
|
@ -227,7 +228,7 @@ void NodeBindings::UvRunOnce() {
|
|||
|
||||
// Perform microtask checkpoint after running JavaScript.
|
||||
scoped_ptr<blink::WebScopedRunV8Script> script_scope(
|
||||
is_browser_ ? nullptr : new blink::WebScopedRunV8Script(env->isolate()));
|
||||
is_browser_ ? nullptr : new blink::WebScopedRunV8Script);
|
||||
|
||||
// Deal with uv events.
|
||||
int r = uv_run(uv_loop_, UV_RUN_NOWAIT);
|
||||
|
|
|
@ -95,7 +95,6 @@ const char kDirectWrite[] = "directWrite";
|
|||
const char kExperimentalFeatures[] = "experimentalFeatures";
|
||||
const char kExperimentalCanvasFeatures[] = "experimentalCanvasFeatures";
|
||||
const char kOverlayScrollbars[] = "overlayScrollbars";
|
||||
const char kOverlayFullscreenVideo[] = "overlayFullscreenVideo";
|
||||
const char kSharedWorker[] = "sharedWorker";
|
||||
|
||||
} // namespace options
|
||||
|
@ -139,7 +138,6 @@ const char kGuestInstanceID[] = "guest-instance-id";
|
|||
const char kExperimentalFeatures[] = "experimental-features";
|
||||
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
|
||||
const char kOverlayScrollbars[] = "overlay-scrollbars";
|
||||
const char kOverlayFullscreenVideo[] = "overlay-fullscreen-video";
|
||||
const char kSharedWorker[] = "shared-worker";
|
||||
const char kPageVisibility[] = "page-visiblity";
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ extern const char kGuestInstanceID[];
|
|||
extern const char kExperimentalFeatures[];
|
||||
extern const char kExperimentalCanvasFeatures[];
|
||||
extern const char kOverlayScrollbars[];
|
||||
extern const char kOverlayFullscreenVideo[];
|
||||
extern const char kSharedWorker[];
|
||||
extern const char kPageVisibility[];
|
||||
|
||||
|
@ -79,7 +78,6 @@ extern const char kGuestInstanceID[];
|
|||
extern const char kExperimentalFeatures[];
|
||||
extern const char kExperimentalCanvasFeatures[];
|
||||
extern const char kOverlayScrollbars[];
|
||||
extern const char kOverlayFullscreenVideo[];
|
||||
extern const char kSharedWorker[];
|
||||
extern const char kPageVisibility[];
|
||||
|
||||
|
|
20
atom/renderer/api/lib/desktop-capturer.coffee
Normal file
20
atom/renderer/api/lib/desktop-capturer.coffee
Normal file
|
@ -0,0 +1,20 @@
|
|||
{ipcRenderer, nativeImage} = require 'electron'
|
||||
|
||||
nextId = 0
|
||||
getNextId = -> ++nextId
|
||||
|
||||
# |options.type| can not be empty and has to include 'window' or 'screen'.
|
||||
isValid = (options) ->
|
||||
return options?.types? and Array.isArray options.types
|
||||
|
||||
exports.getSources = (options, callback) ->
|
||||
return callback new Error('Invalid options') unless isValid options
|
||||
|
||||
captureWindow = 'window' in options.types
|
||||
captureScreen = 'screen' in options.types
|
||||
options.thumbnailSize ?= width: 150, height: 150
|
||||
|
||||
id = getNextId()
|
||||
ipcRenderer.send 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', captureWindow, captureScreen, options.thumbnailSize, id
|
||||
ipcRenderer.once "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{id}", (event, sources) ->
|
||||
callback null, ({id: source.id, name: source.name, thumbnail: nativeImage.createFromDataURL source.thumbnail} for source in sources)
|
|
@ -3,6 +3,9 @@ module.exports = require '../../../../common/api/lib/exports/electron'
|
|||
|
||||
Object.defineProperties module.exports,
|
||||
# Renderer side modules, please sort with alphabet order.
|
||||
desktopCapturer:
|
||||
enumerable: true
|
||||
get: -> require '../desktop-capturer'
|
||||
ipcRenderer:
|
||||
enumerable: true
|
||||
get: -> require '../ipc-renderer'
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
{EventEmitter} = require 'events'
|
||||
|
||||
binding = process.atomBinding 'ipc'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
|
||||
# Created by init.coffee.
|
||||
ipcRenderer = v8Util.getHiddenValue global, 'ipc'
|
||||
|
||||
# Delay the callback to next tick in case the browser is still in the middle
|
||||
# of sending a message while the callback sends a sync message to browser,
|
||||
# which can fail sometimes.
|
||||
ipcRenderer.emit = (args...) ->
|
||||
setTimeout (-> EventEmitter::emit.call ipcRenderer, args...), 0
|
||||
|
||||
ipcRenderer.send = (args...) ->
|
||||
binding.send 'ipc-message', [args...]
|
||||
|
||||
|
|
|
@ -226,8 +226,6 @@ void AtomRendererClient::EnableWebRuntimeFeatures() {
|
|||
blink::WebRuntimeFeatures::enableExperimentalCanvasFeatures(true);
|
||||
if (IsSwitchEnabled(command_line, switches::kOverlayScrollbars))
|
||||
blink::WebRuntimeFeatures::enableOverlayScrollbars(true);
|
||||
if (IsSwitchEnabled(command_line, switches::kOverlayFullscreenVideo))
|
||||
blink::WebRuntimeFeatures::enableOverlayFullscreenVideo(true);
|
||||
if (IsSwitchEnabled(command_line, switches::kSharedWorker))
|
||||
blink::WebRuntimeFeatures::enableSharedWorker(true);
|
||||
}
|
||||
|
|
|
@ -10,9 +10,8 @@ resolveURL = (url) ->
|
|||
class BrowserWindowProxy
|
||||
constructor: (@guestId) ->
|
||||
@closed = false
|
||||
ipcRenderer.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED', (event, guestId) =>
|
||||
if guestId is @guestId
|
||||
@closed = true
|
||||
ipcRenderer.once "ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_#{@guestId}", =>
|
||||
@closed = true
|
||||
|
||||
close: ->
|
||||
ipcRenderer.send 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', @guestId
|
||||
|
|
62
chromium_src/chrome/browser/media/desktop_media_list.h
Normal file
62
chromium_src/chrome/browser/media/desktop_media_list.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_
|
||||
#define CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/strings/string16.h"
|
||||
#include "base/time/time.h"
|
||||
#include "content/public/browser/desktop_media_id.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
|
||||
class DesktopMediaListObserver;
|
||||
|
||||
// DesktopMediaList provides the list of desktop media source (screens, windows,
|
||||
// tabs), and their thumbnails, to the desktop media picker dialog. It
|
||||
// transparently updates the list in the background, and notifies the desktop
|
||||
// media picker when something changes.
|
||||
class DesktopMediaList {
|
||||
public:
|
||||
// Struct used to represent each entry in the list.
|
||||
struct Source {
|
||||
// Id of the source.
|
||||
content::DesktopMediaID id;
|
||||
|
||||
// Name of the source that should be shown to the user.
|
||||
base::string16 name;
|
||||
|
||||
// The thumbnail for the source.
|
||||
gfx::ImageSkia thumbnail;
|
||||
};
|
||||
|
||||
virtual ~DesktopMediaList() {}
|
||||
|
||||
// Sets time interval between updates. By default list of sources and their
|
||||
// thumbnail are updated once per second. If called after StartUpdating() then
|
||||
// it will take effect only after the next update.
|
||||
virtual void SetUpdatePeriod(base::TimeDelta period) = 0;
|
||||
|
||||
// Sets size to which the thumbnails should be scaled. If called after
|
||||
// StartUpdating() then some thumbnails may be still scaled to the old size
|
||||
// until they are updated.
|
||||
virtual void SetThumbnailSize(const gfx::Size& thumbnail_size) = 0;
|
||||
|
||||
// Sets ID of the hosting desktop picker dialog. The window with this ID will
|
||||
// be filtered out from the list of sources.
|
||||
virtual void SetViewDialogWindowId(content::DesktopMediaID::Id dialog_id) = 0;
|
||||
|
||||
// Starts updating the model. The model is initially empty, so OnSourceAdded()
|
||||
// notifications will be generated for each existing source as it is
|
||||
// enumerated. After the initial enumeration the model will be refreshed based
|
||||
// on the update period, and notifications generated only for changes in the
|
||||
// model.
|
||||
virtual void StartUpdating(DesktopMediaListObserver* observer) = 0;
|
||||
|
||||
virtual int GetSourceCount() const = 0;
|
||||
virtual const Source& GetSource(int index) const = 0;
|
||||
virtual std::vector<Source> GetSources() const = 0;
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_OBSERVER_H_
|
||||
#define CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_OBSERVER_H_
|
||||
|
||||
// Interface implemented by the desktop media picker dialog to receive
|
||||
// notifications about changes in DesktopMediaList.
|
||||
class DesktopMediaListObserver {
|
||||
public:
|
||||
virtual void OnSourceAdded(int index) = 0;
|
||||
virtual void OnSourceRemoved(int index) = 0;
|
||||
virtual void OnSourceMoved(int old_index, int new_index) = 0;
|
||||
virtual void OnSourceNameChanged(int index) = 0;
|
||||
virtual void OnSourceThumbnailChanged(int index) = 0;
|
||||
virtual bool OnRefreshFinished() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~DesktopMediaListObserver() {}
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_OBSERVER_H_
|
375
chromium_src/chrome/browser/media/native_desktop_media_list.cc
Normal file
375
chromium_src/chrome/browser/media/native_desktop_media_list.cc
Normal file
|
@ -0,0 +1,375 @@
|
|||
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/browser/media/native_desktop_media_list.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
|
||||
#include "base/hash.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/sequenced_worker_pool.h"
|
||||
#include "chrome/browser/media/desktop_media_list_observer.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "media/base/video_util.h"
|
||||
#include "third_party/libyuv/include/libyuv/scale_argb.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::DesktopMediaID;
|
||||
|
||||
namespace {
|
||||
|
||||
// Update the list every second.
|
||||
const int kDefaultUpdatePeriod = 1000;
|
||||
|
||||
// Returns a hash of a DesktopFrame content to detect when image for a desktop
|
||||
// media source has changed.
|
||||
uint32 GetFrameHash(webrtc::DesktopFrame* frame) {
|
||||
int data_size = frame->stride() * frame->size().height();
|
||||
return base::SuperFastHash(reinterpret_cast<char*>(frame->data()), data_size);
|
||||
}
|
||||
|
||||
gfx::ImageSkia ScaleDesktopFrame(scoped_ptr<webrtc::DesktopFrame> frame,
|
||||
gfx::Size size) {
|
||||
gfx::Rect scaled_rect = media::ComputeLetterboxRegion(
|
||||
gfx::Rect(0, 0, size.width(), size.height()),
|
||||
gfx::Size(frame->size().width(), frame->size().height()));
|
||||
|
||||
SkBitmap result;
|
||||
result.allocN32Pixels(scaled_rect.width(), scaled_rect.height(), true);
|
||||
result.lockPixels();
|
||||
|
||||
uint8* pixels_data = reinterpret_cast<uint8*>(result.getPixels());
|
||||
libyuv::ARGBScale(frame->data(), frame->stride(),
|
||||
frame->size().width(), frame->size().height(),
|
||||
pixels_data, result.rowBytes(),
|
||||
scaled_rect.width(), scaled_rect.height(),
|
||||
libyuv::kFilterBilinear);
|
||||
|
||||
// Set alpha channel values to 255 for all pixels.
|
||||
// TODO(sergeyu): Fix screen/window capturers to capture alpha channel and
|
||||
// remove this code. Currently screen/window capturers (at least some
|
||||
// implementations) only capture R, G and B channels and set Alpha to 0.
|
||||
// crbug.com/264424
|
||||
for (int y = 0; y < result.height(); ++y) {
|
||||
for (int x = 0; x < result.width(); ++x) {
|
||||
pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 3] =
|
||||
0xff;
|
||||
}
|
||||
}
|
||||
|
||||
result.unlockPixels();
|
||||
|
||||
return gfx::ImageSkia::CreateFrom1xBitmap(result);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NativeDesktopMediaList::SourceDescription::SourceDescription(
|
||||
DesktopMediaID id,
|
||||
const base::string16& name)
|
||||
: id(id),
|
||||
name(name) {
|
||||
}
|
||||
|
||||
class NativeDesktopMediaList::Worker
|
||||
: public webrtc::DesktopCapturer::Callback {
|
||||
public:
|
||||
Worker(base::WeakPtr<NativeDesktopMediaList> media_list,
|
||||
scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
|
||||
scoped_ptr<webrtc::WindowCapturer> window_capturer);
|
||||
~Worker() override;
|
||||
|
||||
void Refresh(const gfx::Size& thumbnail_size,
|
||||
content::DesktopMediaID::Id view_dialog_id);
|
||||
|
||||
private:
|
||||
typedef std::map<DesktopMediaID, uint32> ImageHashesMap;
|
||||
|
||||
// webrtc::DesktopCapturer::Callback interface.
|
||||
webrtc::SharedMemory* CreateSharedMemory(size_t size) override;
|
||||
void OnCaptureCompleted(webrtc::DesktopFrame* frame) override;
|
||||
|
||||
base::WeakPtr<NativeDesktopMediaList> media_list_;
|
||||
|
||||
scoped_ptr<webrtc::ScreenCapturer> screen_capturer_;
|
||||
scoped_ptr<webrtc::WindowCapturer> window_capturer_;
|
||||
|
||||
scoped_ptr<webrtc::DesktopFrame> current_frame_;
|
||||
|
||||
ImageHashesMap image_hashes_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Worker);
|
||||
};
|
||||
|
||||
NativeDesktopMediaList::Worker::Worker(
|
||||
base::WeakPtr<NativeDesktopMediaList> media_list,
|
||||
scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
|
||||
scoped_ptr<webrtc::WindowCapturer> window_capturer)
|
||||
: media_list_(media_list),
|
||||
screen_capturer_(screen_capturer.Pass()),
|
||||
window_capturer_(window_capturer.Pass()) {
|
||||
if (screen_capturer_)
|
||||
screen_capturer_->Start(this);
|
||||
if (window_capturer_)
|
||||
window_capturer_->Start(this);
|
||||
}
|
||||
|
||||
NativeDesktopMediaList::Worker::~Worker() {}
|
||||
|
||||
void NativeDesktopMediaList::Worker::Refresh(
|
||||
const gfx::Size& thumbnail_size,
|
||||
content::DesktopMediaID::Id view_dialog_id) {
|
||||
std::vector<SourceDescription> sources;
|
||||
|
||||
if (screen_capturer_) {
|
||||
webrtc::ScreenCapturer::ScreenList screens;
|
||||
if (screen_capturer_->GetScreenList(&screens)) {
|
||||
bool mutiple_screens = screens.size() > 1;
|
||||
base::string16 title;
|
||||
for (size_t i = 0; i < screens.size(); ++i) {
|
||||
if (mutiple_screens) {
|
||||
title = base::UTF8ToUTF16("Screen " + base::IntToString(i+1));
|
||||
} else {
|
||||
title = base::UTF8ToUTF16("Entire screen");
|
||||
}
|
||||
sources.push_back(SourceDescription(DesktopMediaID(
|
||||
DesktopMediaID::TYPE_SCREEN, screens[i].id), title));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (window_capturer_) {
|
||||
webrtc::WindowCapturer::WindowList windows;
|
||||
if (window_capturer_->GetWindowList(&windows)) {
|
||||
for (webrtc::WindowCapturer::WindowList::iterator it = windows.begin();
|
||||
it != windows.end(); ++it) {
|
||||
// Skip the picker dialog window.
|
||||
if (it->id != view_dialog_id) {
|
||||
sources.push_back(SourceDescription(
|
||||
DesktopMediaID(DesktopMediaID::TYPE_WINDOW, it->id),
|
||||
base::UTF8ToUTF16(it->title)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update list of windows before updating thumbnails.
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&NativeDesktopMediaList::OnSourcesList,
|
||||
media_list_, sources));
|
||||
|
||||
ImageHashesMap new_image_hashes;
|
||||
|
||||
// Get a thumbnail for each source.
|
||||
for (size_t i = 0; i < sources.size(); ++i) {
|
||||
SourceDescription& source = sources[i];
|
||||
switch (source.id.type) {
|
||||
case DesktopMediaID::TYPE_SCREEN:
|
||||
if (!screen_capturer_->SelectScreen(source.id.id))
|
||||
continue;
|
||||
screen_capturer_->Capture(webrtc::DesktopRegion());
|
||||
break;
|
||||
|
||||
case DesktopMediaID::TYPE_WINDOW:
|
||||
if (!window_capturer_->SelectWindow(source.id.id))
|
||||
continue;
|
||||
window_capturer_->Capture(webrtc::DesktopRegion());
|
||||
break;
|
||||
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
// Expect that DesktopCapturer to always captures frames synchronously.
|
||||
// |current_frame_| may be NULL if capture failed (e.g. because window has
|
||||
// been closed).
|
||||
if (current_frame_) {
|
||||
uint32 frame_hash = GetFrameHash(current_frame_.get());
|
||||
new_image_hashes[source.id] = frame_hash;
|
||||
|
||||
// Scale the image only if it has changed.
|
||||
ImageHashesMap::iterator it = image_hashes_.find(source.id);
|
||||
if (it == image_hashes_.end() || it->second != frame_hash) {
|
||||
gfx::ImageSkia thumbnail =
|
||||
ScaleDesktopFrame(current_frame_.Pass(), thumbnail_size);
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&NativeDesktopMediaList::OnSourceThumbnail,
|
||||
media_list_, i, thumbnail));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image_hashes_.swap(new_image_hashes);
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&NativeDesktopMediaList::OnRefreshFinished, media_list_));
|
||||
}
|
||||
|
||||
webrtc::SharedMemory* NativeDesktopMediaList::Worker::CreateSharedMemory(
|
||||
size_t size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::Worker::OnCaptureCompleted(
|
||||
webrtc::DesktopFrame* frame) {
|
||||
current_frame_.reset(frame);
|
||||
}
|
||||
|
||||
NativeDesktopMediaList::NativeDesktopMediaList(
|
||||
scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
|
||||
scoped_ptr<webrtc::WindowCapturer> window_capturer)
|
||||
: screen_capturer_(screen_capturer.Pass()),
|
||||
window_capturer_(window_capturer.Pass()),
|
||||
update_period_(base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)),
|
||||
thumbnail_size_(100, 100),
|
||||
view_dialog_id_(-1),
|
||||
observer_(NULL),
|
||||
weak_factory_(this) {
|
||||
base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool();
|
||||
capture_task_runner_ = worker_pool->GetSequencedTaskRunner(
|
||||
worker_pool->GetSequenceToken());
|
||||
}
|
||||
|
||||
NativeDesktopMediaList::~NativeDesktopMediaList() {
|
||||
capture_task_runner_->DeleteSoon(FROM_HERE, worker_.release());
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::SetUpdatePeriod(base::TimeDelta period) {
|
||||
DCHECK(!observer_);
|
||||
update_period_ = period;
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::SetThumbnailSize(
|
||||
const gfx::Size& thumbnail_size) {
|
||||
thumbnail_size_ = thumbnail_size;
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::SetViewDialogWindowId(
|
||||
content::DesktopMediaID::Id dialog_id) {
|
||||
view_dialog_id_ = dialog_id;
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::StartUpdating(DesktopMediaListObserver* observer) {
|
||||
DCHECK(!observer_);
|
||||
DCHECK(screen_capturer_ || window_capturer_);
|
||||
|
||||
observer_ = observer;
|
||||
|
||||
worker_.reset(new Worker(weak_factory_.GetWeakPtr(),
|
||||
screen_capturer_.Pass(), window_capturer_.Pass()));
|
||||
Refresh();
|
||||
}
|
||||
|
||||
int NativeDesktopMediaList::GetSourceCount() const {
|
||||
return sources_.size();
|
||||
}
|
||||
|
||||
const DesktopMediaList::Source& NativeDesktopMediaList::GetSource(
|
||||
int index) const {
|
||||
return sources_[index];
|
||||
}
|
||||
|
||||
std::vector<DesktopMediaList::Source> NativeDesktopMediaList::GetSources() const {
|
||||
return sources_;
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::Refresh() {
|
||||
capture_task_runner_->PostTask(
|
||||
FROM_HERE, base::Bind(&Worker::Refresh, base::Unretained(worker_.get()),
|
||||
thumbnail_size_, view_dialog_id_));
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::OnSourcesList(
|
||||
const std::vector<SourceDescription>& new_sources) {
|
||||
typedef std::set<content::DesktopMediaID> SourceSet;
|
||||
SourceSet new_source_set;
|
||||
for (size_t i = 0; i < new_sources.size(); ++i) {
|
||||
new_source_set.insert(new_sources[i].id);
|
||||
}
|
||||
// Iterate through the old sources to find the removed sources.
|
||||
for (size_t i = 0; i < sources_.size(); ++i) {
|
||||
if (new_source_set.find(sources_[i].id) == new_source_set.end()) {
|
||||
observer_->OnSourceRemoved(i);
|
||||
sources_.erase(sources_.begin() + i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
// Iterate through the new sources to find the added sources.
|
||||
if (new_sources.size() > sources_.size()) {
|
||||
SourceSet old_source_set;
|
||||
for (size_t i = 0; i < sources_.size(); ++i) {
|
||||
old_source_set.insert(sources_[i].id);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < new_sources.size(); ++i) {
|
||||
if (old_source_set.find(new_sources[i].id) == old_source_set.end()) {
|
||||
sources_.insert(sources_.begin() + i, Source());
|
||||
sources_[i].id = new_sources[i].id;
|
||||
sources_[i].name = new_sources[i].name;
|
||||
observer_->OnSourceAdded(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
DCHECK_EQ(new_sources.size(), sources_.size());
|
||||
|
||||
// Find the moved/changed sources.
|
||||
size_t pos = 0;
|
||||
while (pos < sources_.size()) {
|
||||
if (!(sources_[pos].id == new_sources[pos].id)) {
|
||||
// Find the source that should be moved to |pos|, starting from |pos + 1|
|
||||
// of |sources_|, because entries before |pos| should have been sorted.
|
||||
size_t old_pos = pos + 1;
|
||||
for (; old_pos < sources_.size(); ++old_pos) {
|
||||
if (sources_[old_pos].id == new_sources[pos].id)
|
||||
break;
|
||||
}
|
||||
DCHECK(sources_[old_pos].id == new_sources[pos].id);
|
||||
|
||||
// Move the source from |old_pos| to |pos|.
|
||||
Source temp = sources_[old_pos];
|
||||
sources_.erase(sources_.begin() + old_pos);
|
||||
sources_.insert(sources_.begin() + pos, temp);
|
||||
|
||||
observer_->OnSourceMoved(old_pos, pos);
|
||||
}
|
||||
|
||||
if (sources_[pos].name != new_sources[pos].name) {
|
||||
sources_[pos].name = new_sources[pos].name;
|
||||
observer_->OnSourceNameChanged(pos);
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::OnSourceThumbnail(
|
||||
int index,
|
||||
const gfx::ImageSkia& image) {
|
||||
DCHECK_LT(index, static_cast<int>(sources_.size()));
|
||||
sources_[index].thumbnail = image;
|
||||
observer_->OnSourceThumbnailChanged(index);
|
||||
}
|
||||
|
||||
void NativeDesktopMediaList::OnRefreshFinished() {
|
||||
// Give a chance to the observer to stop the refresh work.
|
||||
bool is_continue = observer_->OnRefreshFinished();
|
||||
if (is_continue) {
|
||||
BrowserThread::PostDelayedTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&NativeDesktopMediaList::Refresh,
|
||||
weak_factory_.GetWeakPtr()),
|
||||
update_period_);
|
||||
}
|
||||
}
|
101
chromium_src/chrome/browser/media/native_desktop_media_list.h
Normal file
101
chromium_src/chrome/browser/media/native_desktop_media_list.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_
|
||||
#define CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/sequenced_task_runner.h"
|
||||
#include "chrome/browser/media/desktop_media_list.h"
|
||||
#include "content/public/browser/desktop_media_id.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
|
||||
namespace webrtc {
|
||||
class ScreenCapturer;
|
||||
class WindowCapturer;
|
||||
}
|
||||
|
||||
// Implementation of DesktopMediaList that shows native screens and
|
||||
// native windows.
|
||||
class NativeDesktopMediaList : public DesktopMediaList {
|
||||
public:
|
||||
// Caller may pass NULL for either of the arguments in case when only some
|
||||
// types of sources the model should be populated with (e.g. it will only
|
||||
// contain windows, if |screen_capturer| is NULL).
|
||||
NativeDesktopMediaList(
|
||||
scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
|
||||
scoped_ptr<webrtc::WindowCapturer> window_capturer);
|
||||
~NativeDesktopMediaList() override;
|
||||
|
||||
// DesktopMediaList interface.
|
||||
void SetUpdatePeriod(base::TimeDelta period) override;
|
||||
void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
|
||||
void StartUpdating(DesktopMediaListObserver* observer) override;
|
||||
int GetSourceCount() const override;
|
||||
const Source& GetSource(int index) const override;
|
||||
std::vector<Source> GetSources() const override;
|
||||
void SetViewDialogWindowId(content::DesktopMediaID::Id dialog_id) override;
|
||||
|
||||
private:
|
||||
class Worker;
|
||||
friend class Worker;
|
||||
|
||||
// Struct used to represent sources list the model gets from the Worker.
|
||||
struct SourceDescription {
|
||||
SourceDescription(content::DesktopMediaID id, const base::string16& name);
|
||||
|
||||
content::DesktopMediaID id;
|
||||
base::string16 name;
|
||||
};
|
||||
|
||||
// Order comparator for sources. Used to sort list of sources.
|
||||
static bool CompareSources(const SourceDescription& a,
|
||||
const SourceDescription& b);
|
||||
|
||||
// Post a task for the |worker_| to update list of windows and get thumbnails.
|
||||
void Refresh();
|
||||
|
||||
// Called by |worker_| to refresh the model. First it posts tasks for
|
||||
// OnSourcesList() with the fresh list of sources, then follows with
|
||||
// OnSourceThumbnail() for each changed thumbnail and then calls
|
||||
// OnRefreshFinished() at the end.
|
||||
void OnSourcesList(const std::vector<SourceDescription>& sources);
|
||||
void OnSourceThumbnail(int index, const gfx::ImageSkia& thumbnail);
|
||||
void OnRefreshFinished();
|
||||
|
||||
// Capturers specified in SetCapturers() and passed to the |worker_| later.
|
||||
scoped_ptr<webrtc::ScreenCapturer> screen_capturer_;
|
||||
scoped_ptr<webrtc::WindowCapturer> window_capturer_;
|
||||
|
||||
// Time interval between mode updates.
|
||||
base::TimeDelta update_period_;
|
||||
|
||||
// Size of thumbnails generated by the model.
|
||||
gfx::Size thumbnail_size_;
|
||||
|
||||
// ID of the hosting dialog.
|
||||
content::DesktopMediaID::Id view_dialog_id_;
|
||||
|
||||
// The observer passed to StartUpdating().
|
||||
DesktopMediaListObserver* observer_;
|
||||
|
||||
// Task runner used for the |worker_|.
|
||||
scoped_refptr<base::SequencedTaskRunner> capture_task_runner_;
|
||||
|
||||
// An object that does all the work of getting list of sources on a background
|
||||
// thread (see |capture_task_runner_|). Destroyed on |capture_task_runner_|
|
||||
// after the model is destroyed.
|
||||
scoped_ptr<Worker> worker_;
|
||||
|
||||
// Current list of sources.
|
||||
std::vector<Source> sources_;
|
||||
|
||||
base::WeakPtrFactory<NativeDesktopMediaList> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeDesktopMediaList);
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_
|
|
@ -410,7 +410,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
|||
// be CPU bound, the page overly complex/large or the system just
|
||||
// memory-bound.
|
||||
static const int kPrinterSettingsTimeout = 60000;
|
||||
base::OneShotTimer<base::MessageLoop> quit_timer;
|
||||
base::OneShotTimer quit_timer;
|
||||
quit_timer.Start(FROM_HERE,
|
||||
TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
|
||||
base::MessageLoop::current(), &base::MessageLoop::Quit);
|
||||
|
|
|
@ -503,7 +503,7 @@ class ProcessSingleton::LinuxWatcher
|
|||
// reads.
|
||||
size_t bytes_read_;
|
||||
|
||||
base::OneShotTimer<SocketReader> timer_;
|
||||
base::OneShotTimer timer_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SocketReader);
|
||||
};
|
||||
|
|
|
@ -111,7 +111,7 @@ TtsController* TtsController::GetInstance() {
|
|||
|
||||
// static
|
||||
TtsControllerImpl* TtsControllerImpl::GetInstance() {
|
||||
return Singleton<TtsControllerImpl>::get();
|
||||
return base::Singleton<TtsControllerImpl>::get();
|
||||
}
|
||||
|
||||
TtsControllerImpl::TtsControllerImpl()
|
||||
|
|
|
@ -77,7 +77,7 @@ class TtsControllerImpl : public TtsController {
|
|||
int GetMatchingVoice(const Utterance* utterance,
|
||||
std::vector<VoiceData>& voices);
|
||||
|
||||
friend struct DefaultSingletonTraits<TtsControllerImpl>;
|
||||
friend struct base::DefaultSingletonTraits<TtsControllerImpl>;
|
||||
|
||||
// The current utterance being spoken.
|
||||
Utterance* current_utterance_;
|
||||
|
@ -101,4 +101,4 @@ class TtsControllerImpl : public TtsController {
|
|||
DISALLOW_COPY_AND_ASSIGN(TtsControllerImpl);
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_SPEECH_TTS_CONTROLLER_IMPL_H_
|
||||
#endif // CHROME_BROWSER_SPEECH_TTS_CONTROLLER_IMPL_H_
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "base/synchronization/lock.h"
|
||||
#include "chrome/browser/speech/tts_platform.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
|
||||
#include "library_loaders/libspeechd.h"
|
||||
|
||||
|
@ -32,18 +33,17 @@ struct SPDChromeVoice {
|
|||
|
||||
class TtsPlatformImplLinux : public TtsPlatformImpl {
|
||||
public:
|
||||
virtual bool PlatformImplAvailable() override;
|
||||
virtual bool Speak(
|
||||
int utterance_id,
|
||||
const std::string& utterance,
|
||||
const std::string& lang,
|
||||
const VoiceData& voice,
|
||||
const UtteranceContinuousParameters& params) override;
|
||||
virtual bool StopSpeaking() override;
|
||||
virtual void Pause() override;
|
||||
virtual void Resume() override;
|
||||
virtual bool IsSpeaking() override;
|
||||
virtual void GetVoices(std::vector<VoiceData>* out_voices) override;
|
||||
bool PlatformImplAvailable() override;
|
||||
bool Speak(int utterance_id,
|
||||
const std::string& utterance,
|
||||
const std::string& lang,
|
||||
const VoiceData& voice,
|
||||
const UtteranceContinuousParameters& params) override;
|
||||
bool StopSpeaking() override;
|
||||
void Pause() override;
|
||||
void Resume() override;
|
||||
bool IsSpeaking() override;
|
||||
void GetVoices(std::vector<VoiceData>* out_voices) override;
|
||||
|
||||
void OnSpeechEvent(SPDNotificationType type);
|
||||
|
||||
|
@ -52,7 +52,7 @@ class TtsPlatformImplLinux : public TtsPlatformImpl {
|
|||
|
||||
private:
|
||||
TtsPlatformImplLinux();
|
||||
virtual ~TtsPlatformImplLinux();
|
||||
~TtsPlatformImplLinux() override;
|
||||
|
||||
// Initiate the connection with the speech dispatcher.
|
||||
void Initialize();
|
||||
|
@ -83,7 +83,7 @@ class TtsPlatformImplLinux : public TtsPlatformImpl {
|
|||
// uniquely identify a voice across all available modules.
|
||||
scoped_ptr<std::map<std::string, SPDChromeVoice> > all_native_voices_;
|
||||
|
||||
friend struct DefaultSingletonTraits<TtsPlatformImplLinux>;
|
||||
friend struct base::DefaultSingletonTraits<TtsPlatformImplLinux>;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplLinux);
|
||||
};
|
||||
|
@ -94,6 +94,11 @@ SPDNotificationType TtsPlatformImplLinux::current_notification_ =
|
|||
|
||||
TtsPlatformImplLinux::TtsPlatformImplLinux()
|
||||
: utterance_id_(0) {
|
||||
const base::CommandLine& command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
if (!command_line.HasSwitch(switches::kEnableSpeechDispatcher))
|
||||
return;
|
||||
|
||||
BrowserThread::PostTask(BrowserThread::FILE,
|
||||
FROM_HERE,
|
||||
base::Bind(&TtsPlatformImplLinux::Initialize,
|
||||
|
@ -111,7 +116,7 @@ void TtsPlatformImplLinux::Initialize() {
|
|||
// http://crbug.com/317360
|
||||
ANNOTATE_SCOPED_MEMORY_LEAK;
|
||||
conn_ = libspeechd_loader_.spd_open(
|
||||
"chrome", "extension_api", NULL, SPD_MODE_SINGLE);
|
||||
"chrome", "extension_api", NULL, SPD_MODE_THREADED);
|
||||
}
|
||||
if (!conn_)
|
||||
return;
|
||||
|
@ -146,7 +151,7 @@ void TtsPlatformImplLinux::Reset() {
|
|||
if (conn_)
|
||||
libspeechd_loader_.spd_close(conn_);
|
||||
conn_ = libspeechd_loader_.spd_open(
|
||||
"chrome", "extension_api", NULL, SPD_MODE_SINGLE);
|
||||
"chrome", "extension_api", NULL, SPD_MODE_THREADED);
|
||||
}
|
||||
|
||||
bool TtsPlatformImplLinux::PlatformImplAvailable() {
|
||||
|
@ -187,6 +192,10 @@ bool TtsPlatformImplLinux::Speak(
|
|||
libspeechd_loader_.spd_set_voice_rate(conn_, 100 * log10(rate) / log10(3));
|
||||
libspeechd_loader_.spd_set_voice_pitch(conn_, 100 * log10(pitch) / log10(3));
|
||||
|
||||
// Support languages other than the default
|
||||
if (!lang.empty())
|
||||
libspeechd_loader_.spd_set_language(conn_, lang.c_str());
|
||||
|
||||
utterance_ = utterance;
|
||||
utterance_id_ = utterance_id;
|
||||
|
||||
|
@ -337,8 +346,9 @@ void TtsPlatformImplLinux::IndexMarkCallback(size_t msg_id,
|
|||
|
||||
// static
|
||||
TtsPlatformImplLinux* TtsPlatformImplLinux::GetInstance() {
|
||||
return Singleton<TtsPlatformImplLinux,
|
||||
LeakySingletonTraits<TtsPlatformImplLinux> >::get();
|
||||
return base::Singleton<
|
||||
TtsPlatformImplLinux,
|
||||
base::LeakySingletonTraits<TtsPlatformImplLinux>>::get();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -91,7 +91,7 @@ class TtsPlatformImplMac : public TtsPlatformImpl {
|
|||
int last_char_index_;
|
||||
bool paused_;
|
||||
|
||||
friend struct DefaultSingletonTraits<TtsPlatformImplMac>;
|
||||
friend struct base::DefaultSingletonTraits<TtsPlatformImplMac>;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplMac);
|
||||
};
|
||||
|
@ -291,7 +291,7 @@ TtsPlatformImplMac::~TtsPlatformImplMac() {
|
|||
|
||||
// static
|
||||
TtsPlatformImplMac* TtsPlatformImplMac::GetInstance() {
|
||||
return Singleton<TtsPlatformImplMac>::get();
|
||||
return base::Singleton<TtsPlatformImplMac>::get();
|
||||
}
|
||||
|
||||
@implementation ChromeTtsDelegate
|
||||
|
|
|
@ -15,26 +15,26 @@
|
|||
|
||||
class TtsPlatformImplWin : public TtsPlatformImpl {
|
||||
public:
|
||||
virtual bool PlatformImplAvailable() {
|
||||
bool PlatformImplAvailable() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool Speak(
|
||||
bool Speak(
|
||||
int utterance_id,
|
||||
const std::string& utterance,
|
||||
const std::string& lang,
|
||||
const VoiceData& voice,
|
||||
const UtteranceContinuousParameters& params);
|
||||
const UtteranceContinuousParameters& params) override;
|
||||
|
||||
virtual bool StopSpeaking();
|
||||
bool StopSpeaking() override;
|
||||
|
||||
virtual void Pause();
|
||||
void Pause() override;
|
||||
|
||||
virtual void Resume();
|
||||
void Resume() override;
|
||||
|
||||
virtual bool IsSpeaking();
|
||||
bool IsSpeaking() override;
|
||||
|
||||
virtual void GetVoices(std::vector<VoiceData>* out_voices) override;
|
||||
void GetVoices(std::vector<VoiceData>* out_voices) override;
|
||||
|
||||
// Get the single instance of this class.
|
||||
static TtsPlatformImplWin* GetInstance();
|
||||
|
@ -43,7 +43,7 @@ class TtsPlatformImplWin : public TtsPlatformImpl {
|
|||
|
||||
private:
|
||||
TtsPlatformImplWin();
|
||||
virtual ~TtsPlatformImplWin() {}
|
||||
~TtsPlatformImplWin() override {}
|
||||
|
||||
void OnSpeechEvent();
|
||||
|
||||
|
@ -57,7 +57,7 @@ class TtsPlatformImplWin : public TtsPlatformImpl {
|
|||
int char_position_;
|
||||
bool paused_;
|
||||
|
||||
friend struct DefaultSingletonTraits<TtsPlatformImplWin>;
|
||||
friend struct base::DefaultSingletonTraits<TtsPlatformImplWin>;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplWin);
|
||||
};
|
||||
|
@ -220,6 +220,8 @@ void TtsPlatformImplWin::OnSpeechEvent() {
|
|||
utterance_id_, TTS_EVENT_SENTENCE, char_position_,
|
||||
std::string());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -246,12 +248,12 @@ TtsPlatformImplWin::TtsPlatformImplWin()
|
|||
|
||||
// static
|
||||
TtsPlatformImplWin* TtsPlatformImplWin::GetInstance() {
|
||||
return Singleton<TtsPlatformImplWin,
|
||||
LeakySingletonTraits<TtsPlatformImplWin> >::get();
|
||||
return base::Singleton<TtsPlatformImplWin,
|
||||
base::LeakySingletonTraits<TtsPlatformImplWin>>::get();
|
||||
}
|
||||
|
||||
// static
|
||||
void TtsPlatformImplWin::SpeechEventCallback(
|
||||
WPARAM w_param, LPARAM l_param) {
|
||||
GetInstance()->OnSpeechEvent();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ const char kAppMenuRegistrarPath[] = "/com/canonical/AppMenu/Registrar";
|
|||
|
||||
// static
|
||||
GlobalMenuBarRegistrarX11* GlobalMenuBarRegistrarX11::GetInstance() {
|
||||
return Singleton<GlobalMenuBarRegistrarX11>::get();
|
||||
return base::Singleton<GlobalMenuBarRegistrarX11>::get();
|
||||
}
|
||||
|
||||
void GlobalMenuBarRegistrarX11::OnWindowMapped(unsigned long xid) {
|
||||
|
@ -39,7 +39,7 @@ void GlobalMenuBarRegistrarX11::OnWindowUnmapped(unsigned long xid) {
|
|||
}
|
||||
|
||||
GlobalMenuBarRegistrarX11::GlobalMenuBarRegistrarX11()
|
||||
: registrar_proxy_(NULL) {
|
||||
: registrar_proxy_(nullptr) {
|
||||
// libdbusmenu uses the gio version of dbus; I tried using the code in dbus/,
|
||||
// but it looks like that's isn't sharing the bus name with the gio version,
|
||||
// even when |connection_type| is set to SHARED.
|
||||
|
@ -49,11 +49,11 @@ GlobalMenuBarRegistrarX11::GlobalMenuBarRegistrarX11()
|
|||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START),
|
||||
NULL,
|
||||
nullptr,
|
||||
kAppMenuRegistrarName,
|
||||
kAppMenuRegistrarPath,
|
||||
kAppMenuRegistrarName,
|
||||
NULL, // TODO: Probalby want a real cancelable.
|
||||
nullptr, // TODO: Probalby want a real cancelable.
|
||||
static_cast<GAsyncReadyCallback>(OnProxyCreatedThunk),
|
||||
this);
|
||||
}
|
||||
|
@ -84,9 +84,9 @@ void GlobalMenuBarRegistrarX11::RegisterXID(unsigned long xid) {
|
|||
"RegisterWindow",
|
||||
g_variant_new("(uo)", xid, path.c_str()),
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void GlobalMenuBarRegistrarX11::UnregisterXID(unsigned long xid) {
|
||||
|
@ -105,14 +105,14 @@ void GlobalMenuBarRegistrarX11::UnregisterXID(unsigned long xid) {
|
|||
"UnregisterWindow",
|
||||
g_variant_new("(u)", xid),
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void GlobalMenuBarRegistrarX11::OnProxyCreated(GObject* source,
|
||||
GAsyncResult* result) {
|
||||
GError* error = NULL;
|
||||
GError* error = nullptr;
|
||||
GDBusProxy* proxy = g_dbus_proxy_new_for_bus_finish(result, &error);
|
||||
if (error) {
|
||||
g_error_free(error);
|
||||
|
@ -128,7 +128,7 @@ void GlobalMenuBarRegistrarX11::OnProxyCreated(GObject* source,
|
|||
g_signal_connect(registrar_proxy_, "notify::g-name-owner",
|
||||
G_CALLBACK(OnNameOwnerChangedThunk), this);
|
||||
|
||||
OnNameOwnerChanged(NULL, NULL);
|
||||
OnNameOwnerChanged(nullptr, nullptr);
|
||||
}
|
||||
|
||||
void GlobalMenuBarRegistrarX11::OnNameOwnerChanged(GObject* /* ignored */,
|
||||
|
|
|
@ -28,7 +28,7 @@ class GlobalMenuBarRegistrarX11 {
|
|||
void OnWindowUnmapped(unsigned long xid);
|
||||
|
||||
private:
|
||||
friend struct DefaultSingletonTraits<GlobalMenuBarRegistrarX11>;
|
||||
friend struct base::DefaultSingletonTraits<GlobalMenuBarRegistrarX11>;
|
||||
|
||||
GlobalMenuBarRegistrarX11();
|
||||
~GlobalMenuBarRegistrarX11();
|
||||
|
|
|
@ -17,7 +17,7 @@ class FilePath;
|
|||
namespace chrome {
|
||||
|
||||
enum {
|
||||
PATH_START = 1000,
|
||||
PATH_START = 2000,
|
||||
|
||||
DIR_APP = PATH_START, // Directory where dlls and data reside.
|
||||
DIR_LOGS, // Directory where logs should be written.
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "third_party/skia/include/core/SkMatrix.h"
|
||||
#include "third_party/skia/include/core/SkPaint.h"
|
||||
#include "third_party/skia/include/core/SkPoint.h"
|
||||
#include "third_party/skia/include/core/SkTemplates.h"
|
||||
#include "third_party/skia/include/core/SkTypeface.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "url/gurl.h"
|
||||
|
@ -315,7 +314,7 @@ int32_t PepperFlashRendererHost::OnNavigate(
|
|||
bool rejected = false;
|
||||
while (header_iter.GetNext()) {
|
||||
std::string lower_case_header_name =
|
||||
base::StringToLowerASCII(header_iter.name());
|
||||
base::ToLowerASCII(header_iter.name());
|
||||
if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) {
|
||||
rejected = true;
|
||||
|
||||
|
|
|
@ -544,7 +544,6 @@ void PrepareFrameAndViewForPrint::CopySelection(
|
|||
// on the page).
|
||||
WebPreferences prefs = preferences;
|
||||
prefs.javascript_enabled = false;
|
||||
prefs.java_enabled = false;
|
||||
|
||||
blink::WebView* web_view = blink::WebView::create(this);
|
||||
owns_web_view_ = true;
|
||||
|
|
|
@ -135,7 +135,8 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame,
|
|||
printed_page_params.page_size = page_size_in_dpi[i];
|
||||
printed_page_params.content_area = content_area_in_dpi[i];
|
||||
Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params));
|
||||
printed_page_params.metafile_data_handle = INVALID_HANDLE_VALUE;
|
||||
// Send the rest of the pages with an invalid metafile handle.
|
||||
printed_page_params.metafile_data_handle = base::SharedMemoryHandle();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ class LibSpeechdLoader {
|
|||
decltype(&::spd_set_synthesis_voice) spd_set_synthesis_voice;
|
||||
decltype(&::spd_list_modules) spd_list_modules;
|
||||
decltype(&::spd_set_output_module) spd_set_output_module;
|
||||
decltype(&::spd_set_language) spd_set_language;
|
||||
|
||||
|
||||
private:
|
||||
|
|
|
@ -201,6 +201,19 @@ bool LibSpeechdLoader::Load(const std::string& library_name) {
|
|||
return false;
|
||||
}
|
||||
|
||||
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
|
||||
spd_set_language =
|
||||
reinterpret_cast<decltype(this->spd_set_language)>(
|
||||
dlsym(library_, "spd_set_language"));
|
||||
#endif
|
||||
#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
|
||||
spd_set_language = &::spd_set_language;
|
||||
#endif
|
||||
if (!spd_set_language) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
loaded_ = true;
|
||||
return true;
|
||||
|
@ -227,5 +240,6 @@ void LibSpeechdLoader::CleanUp(bool unload) {
|
|||
spd_set_synthesis_voice = NULL;
|
||||
spd_list_modules = NULL;
|
||||
spd_set_output_module = NULL;
|
||||
spd_set_language = NULL;
|
||||
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ void StreamListenSocket::CloseSocket() {
|
|||
void StreamListenSocket::WatchSocket(WaitState state) {
|
||||
#if defined(OS_WIN)
|
||||
WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ);
|
||||
watcher_.StartWatching(socket_event_, this);
|
||||
watcher_.StartWatchingOnce(socket_event_, this);
|
||||
#elif defined(OS_POSIX)
|
||||
// Implicitly calls StartWatchingFileDescriptor().
|
||||
base::MessageLoopForIO::current()->WatchFileDescriptor(
|
||||
|
@ -264,7 +264,7 @@ void StreamListenSocket::OnObjectSignaled(HANDLE object) {
|
|||
return;
|
||||
}
|
||||
// The object was reset by WSAEnumNetworkEvents. Watch for the next signal.
|
||||
watcher_.StartWatching(object, this);
|
||||
watcher_.StartWatchingOnce(object, this);
|
||||
|
||||
if (ev.lNetworkEvents == 0) {
|
||||
// Occasionally the event is set even though there is no new data.
|
||||
|
|
632
docs-translations/pt-BR/api/browser-window.md
Normal file
632
docs-translations/pt-BR/api/browser-window.md
Normal file
|
@ -0,0 +1,632 @@
|
|||
# BrowserWindow
|
||||
|
||||
A classe `BrowserWindow` lhe dá a habilidade de criar uma janela do browser. Por exemplo:
|
||||
|
||||
```javascript
|
||||
const BrowserWindow = require('electron').BrowserWindow;
|
||||
|
||||
var win = new BrowserWindow({ width: 800, height: 600, show: false });
|
||||
win.on('closed', function() {
|
||||
win = null;
|
||||
});
|
||||
|
||||
win.loadURL('https://github.com');
|
||||
win.show();
|
||||
```
|
||||
|
||||
Você também pode criar uma janela sem o chrome utilizando a API [Frameless Window](../../../docs/api/frameless-window.md).
|
||||
|
||||
## Classe: BrowserWindow
|
||||
|
||||
`BrowserWindow` é um [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter).
|
||||
|
||||
Ela cria uma nova `BrowserWindow` com propriedades nativas definidas pelo `options`.
|
||||
|
||||
### `new BrowserWindow([options])`
|
||||
|
||||
`options` Objeto (opcional), propriedades:
|
||||
|
||||
* `width` Integer - Largura da janela em pixels. O padrão é `800`.
|
||||
* `height` Integer - Altura da janela em pixels. O padrão é `600`.
|
||||
* `x` Integer - Deslocamento da janela da esquerda da tela. O padrão é centralizar a janela.
|
||||
* `y` Integer - Deslocamento da janela do topo da tela. O padrão é centralizar a janela.
|
||||
* `useContentSize` Boolean - `width` e `height` seriam utilizados como o tamanho da página web, o que significa que o tamanho real da janela irá incluir o tamanho da moldura da janela e será um pouco maior. O padrão é `false`.
|
||||
* `center` Boolean - Mostra a janela no centro da tela.
|
||||
* `minWidth` Integer - Largura mínima da janela. O padrão é `0`.
|
||||
* `minHeight` Integer - Altura mínima da janela. O padrão é `0`.
|
||||
* `maxWidth` Integer - Largura máxima da janela. O padrão é sem limites.
|
||||
* `maxHeight` Integer - Altura máxima da janela. O padrão é sem limites.
|
||||
* `resizable` Boolean - Se é possível modificar o tamanho da janela. O padrão é `true`.
|
||||
* `alwaysOnTop` Boolean - Se a janela deve sempre ficar à frente de outras janelas. O padrão é `false`.
|
||||
* `fullscreen` Boolean - Se a janela deve estar em tela cheia. Quando definido como `false`, o botão de tela cheia estará escondido ou desabilitado no OS X. O padrão é `false`.
|
||||
* `skipTaskbar` Boolean - Se deve mostrar a janela na barra de tarefas. O padrão é `false`.
|
||||
* `kiosk` Boolean - Modo *kiosk*. O padrão é `false`.
|
||||
* `title` String - Título padrão da janela. O padrão é `"Electron"`.
|
||||
* `icon` [NativeImage](../../../docs/api/native-image.md) - O ícone da janela, quando omitido no Windows, o ícone do executável é utilizado como o ícone da janela.
|
||||
* `show` Boolean - Se a janela deve ser exibida quando criada. O padrão é `true`.
|
||||
* `frame` Boolean - Defina como `false` para criar uma [Frameless Window](../../../docs/api/frameless-window.md). O padrão é `true`.
|
||||
* `acceptFirstMouse` Boolean - Se o *web view* aceita um evento *mouse-down* que ativa a janela simultaneamente. O padrão é `false`.
|
||||
* `disableAutoHideCursor` Boolean - Se deve esconder o cursor quando estiver digitando. O padrão é `false`.
|
||||
* `autoHideMenuBar` Boolean - Esconde a barra de menu automaticamente, a não ser que a tecla `Alt` seja pressionada. O padrão é `false`.
|
||||
* `enableLargerThanScreen` Boolean - Possibilita que o tamanho da janela seja maior que a tela. O padrão é `false`.
|
||||
* `backgroundColor` String - Cor de fundo da janela em hexadecimal, como `#66CD00` ou `#FFF`. Só é implementado no Linux e Windows. O padrão é `#000` (preto).
|
||||
* `darkTheme` Boolean - Força a utilização do tema *dark* na janela, só funciona em alguns ambientes de desktop GTK+3. O padrão é `false`.
|
||||
* `transparent` Boolean - Torna a janela [transparente](../../../docs/api/frameless-window.md). O padrão é `false`.
|
||||
* `type` String - Define o tipo da janela, que aplica propriedades adicionais específicas da plataforma. Por padrão é indefinido e será criada uma janela de aplicativo comum. Possíveis valores:
|
||||
* No Linux, os tipos possíveis são `desktop`, `dock`, `toolbar`, `splash`,
|
||||
`notification`.
|
||||
* No OS X, os tipos possíveis são `desktop`, `textured`. O tipo `textured` adiciona a aparência degradê metálica (`NSTexturedBackgroundWindowMask`). O tipo `desktop` coloca a janela no nível do fundo de tela do desktop (`kCGDesktopWindowLevel - 1`). Note que a janela `desktop` não irá receber foco, eventos de teclado ou mouse, mas você pode usar `globalShortcut` para receber entrada de dados ocasionalmente.
|
||||
* `titleBarStyle` String, OS X - Define o estilo da barra de título da janela. Esta opção está suportada a partir da versão OS X 10.10 Yosemite. Há três possíveis valores:
|
||||
* `default` ou não definido, resulta na barra de título cinza opaca padrão do Mac.
|
||||
* `hidden` resulta numa barra de título oculta e a janela de conteúdo no tamanho máximo, porém a barra de título ainda possui os controles padrões de janela ("semáforo") no canto superior esquerdo.
|
||||
* `hidden-inset` resulta numa barra de título oculta com uma aparência alternativa onde os botões de semáforo estão ligeiramente mais longe do canto da janela.
|
||||
* `webPreferences` Object - Configurações das características da página web, propriedades:
|
||||
* `nodeIntegration` Boolean - Se a integração com node está habilitada. O padrão é `true`.
|
||||
* `preload` String - Define um *script* que será carregado antes que outros scripts rodem na página. Este script sempre terá acesso às APIs do node, não importa se `nodeIntegration` esteja habilitada ou não. O valor deve ser o endereço absoluto do scriot. Quando `nodeIntegration` não está habilitada, o script `preload` pode reintroduzir símbolos globais Node de volta ao escopo global. Veja um exemplo [aqui](process.md#evento-loaded).
|
||||
* `partition` String - Define a sessão utilizada pela página. Se `partition` começa com `persist:`, a página irá utilizar uma sessão persistente disponível para todas as páginas do aplicativo com a mesma `partition`. Se não houver o prefixo `persist:`, a página irá utilizar uma sessão em memória. Ao utilizar a mesma `partition`, várias páginas podem compartilhar a mesma sessão. Se a `partition` for indefinida, então a sessão padrão do aplicativo será utilizada.
|
||||
* `zoomFactor` Number - O fator de *zoom* da página, `3.0` representa `300%`. O padrão é `1.0`.
|
||||
* `javascript` Boolean - Habilita suporte à JavaScript. O padrão é `true`.
|
||||
* `webSecurity` Boolean - Quando definido como `false`, irá desabilitar a política de mesma origem (Geralmente usando sites de teste por pessoas), e definir `allowDisplayingInsecureContent` e `allowRunningInsecureContent` como
|
||||
`true` se estas duas opções não tiverem sido definidas pelo usuário. O padrão é `true`.
|
||||
* `allowDisplayingInsecureContent` Boolean - Permite que uma página https exiba conteúdo como imagens de URLs http. O padrão é `false`.
|
||||
* `allowRunningInsecureContent` Boolean - Permite que uma página https rode JavaScript, CSS ou plugins de URLs http. O padrão é `false`.
|
||||
* `images` Boolean - Habilita suporte a imagens. O padrão é `true`.
|
||||
* `java` Boolean - Habilita suporte a Java. O padrão é `false`.
|
||||
* `textAreasAreResizable` Boolean - Faz com que os elementos *TextArea* elements tenham tamanho variável. O padrão é `true`.
|
||||
* `webgl` Boolean - Habiltia suporte a WebGL. O padrão é `true`.
|
||||
* `webaudio` Boolean - Habilita suporte a WebAudio. O padrão é `true`.
|
||||
* `plugins` Boolean - Se plugins devem ser habilitados. O padrão é `false`.
|
||||
* `experimentalFeatures` Boolean - Habilita as características experimentais do Chromium. O padrão é `false`.
|
||||
* `experimentalCanvasFeatures` Boolean - Habilita as características experimentais de canvas do Chromium. O padrão é `false`.
|
||||
* `overlayScrollbars` Boolean - Habilita sobreposição das barras de rolagem. O padrão é `false`.
|
||||
* `overlayFullscreenVideo` Boolean - Habilita sobreposição do vídeo em tela cheia. O padrão é `false`.
|
||||
* `sharedWorker` Boolean - Habilita suporte a *Shared Worker*. O padrão é `false`.
|
||||
* `directWrite` Boolean - Habilita o sistema de renderização de fontes *DirectWrite* no Windows. O padrão é `true`.
|
||||
* `pageVisibility` Boolean - A página é forçada a permanecer visível ou oculta quando definido, em vez de refletir a visibilidade atual da janela. Usuários podem definir como `true` para evitar que os temporizadores do *DOM* sejam suprimidos. O padrão é `false`.
|
||||
|
||||
## Eventos
|
||||
|
||||
O objeto `BrowserWindow` emite os seguintes eventos:
|
||||
|
||||
**Nota:** Alguns eventos só estão disponíveis em sistemas operacionais específicos e estão rotulados como tal.
|
||||
|
||||
### Evento: 'page-title-updated'
|
||||
|
||||
Retorna:
|
||||
|
||||
* `event` Evento
|
||||
|
||||
Emitido quando o documento muda seu título, chamar `event.preventDefault()` previne que o título nativo da janela mude.
|
||||
|
||||
### Evento: 'close'
|
||||
|
||||
Retorna:
|
||||
|
||||
* `event` Evento
|
||||
|
||||
Emitido quando a janela for fechar. É emitido antes dos eventos `beforeunload` e `unload` do DOM. Chamar `event.preventDefault()` cancela o fechamento.
|
||||
|
||||
Normalmente você utiliza o manipulador de eventos do `beforeunload` para decidir se a janela deve ser fechada, que também será chamado quando a janela é recarregada. No Electron, retornar uma string vazia ou `false` cancela o fechamento. Por exemplo:
|
||||
|
||||
```javascript
|
||||
window.onbeforeunload = function(e) {
|
||||
console.log('Não quero ser fechada');
|
||||
|
||||
// Diferente de navegadores comuns, nos quais uma string deve ser retornada e
|
||||
// o usuário deve confirmar se a janela será fechada, o Electron dá mais opções
|
||||
// aos desenvolvedores. Retornar uma string vazia ou false cancela o fechamento.
|
||||
// Você também pode usar a API de diálogo para deixar que o usuário confirme o
|
||||
// fechamento do aplicativo.
|
||||
e.returnValue = false;
|
||||
};
|
||||
```
|
||||
|
||||
### Evento: 'closed'
|
||||
|
||||
Emitido quando a janela é fechada. Após você ter recebido este evento, você deve remover a referência da janela e evitar utilizá-la.
|
||||
|
||||
### Evento: 'unresponsive'
|
||||
|
||||
Emitido quando a página web para de responder.
|
||||
|
||||
### Evento: 'responsive'
|
||||
|
||||
Emitido quando a página web que não respondia volta a responder novamente.
|
||||
|
||||
### Evento: 'blur'
|
||||
|
||||
Emitido quando a janela perde foco.
|
||||
|
||||
### Evento: 'focus'
|
||||
|
||||
Emitido quando a janela ganha foco.
|
||||
|
||||
### Evento: 'maximize'
|
||||
|
||||
Emitido quando a janela é maximizada.
|
||||
|
||||
### Evento: 'unmaximize'
|
||||
|
||||
Emitido quando a janela sai do estado maximizado.
|
||||
|
||||
### Evento: 'minimize'
|
||||
|
||||
Emitido quando a janela é minimizada.
|
||||
|
||||
### Evento: 'restore'
|
||||
|
||||
Emitido quando a janela é restaurada do estado minimizado.
|
||||
|
||||
### Evento: 'resize'
|
||||
|
||||
Emitido quando o tamanho da janela está sendo alterado.
|
||||
|
||||
### Evento: 'move'
|
||||
|
||||
Emitido quando está sendo movida para uma nova posição.
|
||||
|
||||
__Note__: No OS X este evento é apenas um apelido de `moved`.
|
||||
|
||||
### Evento: 'moved' _OS X_
|
||||
|
||||
Emitido uma vez quando a janela é movida para uma nova posição.
|
||||
|
||||
### Evento: 'enter-full-screen'
|
||||
|
||||
Emitido quando a janela entra no estado tela cheia.
|
||||
|
||||
### Evento: 'leave-full-screen'
|
||||
|
||||
Emitido quando a janela sai do estado de tela cheia.
|
||||
|
||||
### Evento: 'enter-html-full-screen'
|
||||
|
||||
Emitido quando a janela entra no estado tela cheia, ocasionado por uma api de html.
|
||||
|
||||
### Evento: 'leave-html-full-screen'
|
||||
|
||||
Emitido quando a janela sai do estado de tela cheia, ocasionado por uma api de html.
|
||||
|
||||
### Evento: 'app-command' _Windows_
|
||||
|
||||
Emitido quando um [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx) é invocado. Estes estão tipicamente relacionado às teclas de mídia do teclado, ou comandos do browser, assim como o botão "Voltar" existente em alguns modelos de mouse no Windows.
|
||||
|
||||
```js
|
||||
someWindow.on('app-command', function(e, cmd) {
|
||||
// Navega a janela 'para trás' quando o usuário pressiona o botão voltar do mouse
|
||||
if (cmd === 'browser-backward' && someWindow.webContents.canGoBack()) {
|
||||
someWindow.webContents.goBack();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Métodos
|
||||
|
||||
O objeto `BrowserWindow` possui os seguintes métodos:
|
||||
|
||||
### `BrowserWindow.getAllWindows()`
|
||||
|
||||
Retorna um array de todas as janelas abertas.
|
||||
|
||||
### `BrowserWindow.getFocusedWindow()`
|
||||
|
||||
Retorna a janela que está focada no aplicativo.
|
||||
|
||||
### `BrowserWindow.fromWebContents(webContents)`
|
||||
|
||||
* `webContents` [WebContents](../../../docs/api/web-contents.md)
|
||||
|
||||
Acha uma janela de acordo com os `webContents` que ela possui.
|
||||
|
||||
### `BrowserWindow.fromId(id)`
|
||||
|
||||
* `id` Integer
|
||||
|
||||
Acha uma janela de acordo com o seu ID.
|
||||
|
||||
### `BrowserWindow.addDevToolsExtension(path)`
|
||||
|
||||
* `path` String
|
||||
|
||||
Adiciona a extenção DevTools localizada no endereço `path`, e retorna o nome da extenção.
|
||||
|
||||
A extenção será lembrada, então você só precisa chamar esta API uma vez, esta API não é para uso de programação.
|
||||
|
||||
### `BrowserWindow.removeDevToolsExtension(name)`
|
||||
|
||||
* `name` String
|
||||
|
||||
Remove a extenção DevTools cujo nome é `name`.
|
||||
|
||||
## Propriedades de Instância
|
||||
|
||||
Objetos criados com `new BrowserWindow` possuem as seguintes propriedades:
|
||||
|
||||
```javascript
|
||||
// Neste exemplo `win` é a nossa instância
|
||||
var win = new BrowserWindow({ width: 800, height: 600 });
|
||||
```
|
||||
|
||||
### `win.webContents`
|
||||
|
||||
Todas os eventos e operações relacionados à pagina web serão feitos através do objeto `WebContents` que a esta janela possui.
|
||||
|
||||
Veja a [documentação do `webContents`](../../../docs/api/web-contents.md) para seus métodos e eventos.
|
||||
|
||||
### `win.id`
|
||||
|
||||
O ID único desta janela.
|
||||
|
||||
## Métodos de instância
|
||||
|
||||
Objetos criados com `new BrowserWindow` possuem os seguintes métodos de instância:
|
||||
|
||||
**Nota:** Alguns métodos só estão disponíveis em sistemas operacionais específicos e estão rotulados como tal.
|
||||
|
||||
### `win.destroy()`
|
||||
|
||||
Força o fechamento da janela, os eventos `unload` e `beforeunload` não serão emitidos para a página web, e o evento `close` também não será emitido para esta janela, mas garante que o evento `closed` será emitido.
|
||||
|
||||
Você só deve utilizar este método quando o processo renderizador (página web) congelar.
|
||||
|
||||
### `win.close()`
|
||||
|
||||
Tenta fechar a janela, tem o mesmo efeito que o usuário manualmente clicar o botão de fechar a janela. Entretanto, a página web pode cancelar o fechamento, veja o [evento close](#evento-close).
|
||||
|
||||
### `win.focus()`
|
||||
|
||||
Foca na janela.
|
||||
|
||||
### `win.isFocused()`
|
||||
|
||||
Retorna um boolean, indicando se a janela está com foco.
|
||||
|
||||
### `win.show()`
|
||||
|
||||
Exibe e dá foco à janela.
|
||||
|
||||
### `win.showInactive()`
|
||||
|
||||
Exibe a janela, porém não dá foco à ela.
|
||||
|
||||
### `win.hide()`
|
||||
|
||||
Esconde a janela.
|
||||
|
||||
### `win.isVisible()`
|
||||
|
||||
Retorna um boolean, indicando se a janela está visível para o usuário.
|
||||
|
||||
### `win.maximize()`
|
||||
|
||||
Maximiza a janela.
|
||||
|
||||
### `win.unmaximize()`
|
||||
|
||||
Sai do estado maximizado da janela.
|
||||
|
||||
### `win.isMaximized()`
|
||||
|
||||
Retorna um boolean, indicando se a janela está maximizada.
|
||||
|
||||
### `win.minimize()`
|
||||
|
||||
Minimiza a janela. Em algumas plataformas, a janela minimizada será exibida no *Dock*.
|
||||
|
||||
### `win.restore()`
|
||||
|
||||
Restaura a janela do estado minimizado para o estado anterior.
|
||||
|
||||
### `win.isMinimized()`
|
||||
|
||||
Retorna um boolean, indicando se a janela está minimizada.
|
||||
|
||||
### `win.setFullScreen(flag)`
|
||||
|
||||
* `flag` Boolean
|
||||
|
||||
Define se a janela deve estar em modo tela cheia.
|
||||
|
||||
### `win.isFullScreen()`
|
||||
|
||||
Retorna um boolean, indicando se a janela está em modo tela cheia.
|
||||
|
||||
### `win.setAspectRatio(aspectRatio[, extraSize])` _OS X_
|
||||
|
||||
* `aspectRatio` A proporção que queremos manter para uma porção do conteúdo da *view*.
|
||||
* `extraSize` Object (opcional) - O tamanho extra não incluído enquanto a proporção é mantida. Propriedades:
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
|
||||
Isto fará com que a janela mantenha sua proporção. O `extraSize` permite que o desenvolvedor tenha espaço, definido em pixels, não incluídos no cálculo da proporção. Esta API já leva em consideração a diferença entre o tamanho da janela e o tamanho de seu conteúdo.
|
||||
|
||||
Suponha que exista uma janela normal com um *player* de vídeo HD e seus controles associados. Talvez tenha 15 pixels de controles na borda esquerda, 25 pixels de controles na borda direita e 50 abaixo do player. Para que seja mantida a proporção de 16:9 (proporção padrão para HD em 1920x1080) no próprio player, nós chamaríamos esta função com os argumentos 16/9 e [ 40, 50 ]. Para o segundo argumento, não interessa onde a largura e altura extras estão no conteúdo da view--apenas que elas existam. Apenas some qualquer área de largura e altura extras que você tem dentro da view do conteúdo.
|
||||
|
||||
### `win.setBounds(options)`
|
||||
|
||||
`options` Object, propriedades:
|
||||
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
|
||||
Redefine o tamanho e move a janela para `width`, `height`, `x`, `y`.
|
||||
|
||||
### `win.getBounds()`
|
||||
|
||||
Retorna um objeto que contém a largura, altura, posição x e y da janela.
|
||||
|
||||
### `win.setSize(width, height)`
|
||||
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
|
||||
Redefine o tamanho da janela para largura `width` e altura `height`.
|
||||
|
||||
### `win.getSize()`
|
||||
|
||||
Retorna um array que contém a largura e altura da janela.
|
||||
|
||||
### `win.setContentSize(width, height)`
|
||||
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
|
||||
Redefine a área de cliente da janela (a página web) para largura `width` e altura `height`.
|
||||
|
||||
### `win.getContentSize()`
|
||||
|
||||
Retorna um array que contém a largura e altura da área de cliente da janela.
|
||||
|
||||
### `win.setMinimumSize(width, height)`
|
||||
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
|
||||
Define o tamanho mínimo da janela para largura `width` e altura `height`.
|
||||
|
||||
### `win.getMinimumSize()`
|
||||
|
||||
Retorna uma array que contém o tamanho mínimo da largura e altura da janela.
|
||||
|
||||
### `win.setMaximumSize(width, height)`
|
||||
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
|
||||
Define o tamanho máximo da janela para largura `width` e altura `height`.
|
||||
|
||||
### `win.getMaximumSize()`
|
||||
|
||||
Retorna uma array que contém o tamanho máximo da largura e altura da janela.
|
||||
|
||||
### `win.setResizable(resizable)`
|
||||
|
||||
* `resizable` Boolean
|
||||
|
||||
Define se a janela pode ter seu tamanho redefinido manualmente pelo usuário.
|
||||
|
||||
### `win.isResizable()`
|
||||
|
||||
Retorna um boolean indicando se a janela pode ter seu tamanho redefinido manualmente pelo usuário.
|
||||
|
||||
### `win.setAlwaysOnTop(flag)`
|
||||
|
||||
* `flag` Boolean
|
||||
|
||||
Define se a janela deve estar sempre em cima de outras janelas. Após definir isso, a janela continua sendo uma janela normal, não uma janela *toolbox* que não pode receber foco.
|
||||
|
||||
### `win.isAlwaysOnTop()`
|
||||
|
||||
Retorna um boolean indicando se a janela está sempre em cima de outras janelas.
|
||||
|
||||
### `win.center()`
|
||||
|
||||
Move a janela para o centro da tela.
|
||||
|
||||
### `win.setPosition(x, y)`
|
||||
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
|
||||
Move a janela para `x` e `y`.
|
||||
|
||||
### `win.getPosition()`
|
||||
|
||||
Retorna um array com a posição atual da janela.
|
||||
|
||||
### `win.setTitle(title)`
|
||||
|
||||
* `title` String
|
||||
|
||||
Muda o título da janela nativa para `title`.
|
||||
|
||||
### `win.getTitle()`
|
||||
|
||||
Retorna o título da janela nativa.
|
||||
|
||||
**Nota:** O título da página web pode ser diferente do título da janela nativa.
|
||||
|
||||
### `win.flashFrame(flag)`
|
||||
|
||||
* `flag` Boolean
|
||||
|
||||
Inicia ou para de piscar a janela para atrair a atenção do usuário.
|
||||
|
||||
### `win.setSkipTaskbar(skip)`
|
||||
|
||||
* `skip` Boolean
|
||||
|
||||
Faz com que a janela não apareça na barra de tarefas.
|
||||
|
||||
### `win.setKiosk(flag)`
|
||||
|
||||
* `flag` Boolean
|
||||
|
||||
Entra ou sai do modo *kiosk*.
|
||||
|
||||
### `win.isKiosk()`
|
||||
|
||||
Retorna um boolean indicando se janela está no modo *kiosk*.
|
||||
|
||||
### `win.hookWindowMessage(message, callback)` _Windows_
|
||||
|
||||
* `message` Integer
|
||||
* `callback` Function
|
||||
|
||||
Engancha uma mensagem de janela. O `callback` é chamado quando a mensagem é recebida no WndProc.
|
||||
|
||||
### `win.isWindowMessageHooked(message)` _Windows_
|
||||
|
||||
* `message` Integer
|
||||
|
||||
Retorna `true` ou `false` indicando se a mensagem está enganchada ou não.
|
||||
|
||||
### `win.unhookWindowMessage(message)` _Windows_
|
||||
|
||||
* `message` Integer
|
||||
|
||||
Desengancha a mensagem de janela.
|
||||
|
||||
### `win.unhookAllWindowMessages()` _Windows_
|
||||
|
||||
Desengancha todas as mensagens de janela.
|
||||
|
||||
### `win.setRepresentedFilename(filename)` _OS X_
|
||||
|
||||
* `filename` String
|
||||
|
||||
Define o endereço do arquivo que a janela representa, e o ícone do arquivo será exibido na barra de título da janela.
|
||||
|
||||
### `win.getRepresentedFilename()` _OS X_
|
||||
|
||||
Retorna o endereço do arquivo que a janela representa.
|
||||
|
||||
### `win.setDocumentEdited(edited)` _OS X_
|
||||
|
||||
* `edited` Boolean
|
||||
|
||||
Define se o documento da janela foi editado, e o ícone na barra de título se torna cinza quando definido como `true`.
|
||||
|
||||
### `win.isDocumentEdited()` _OS X_
|
||||
|
||||
Retorna um boolean indicando se o documento da janela foi editado.
|
||||
|
||||
### `win.focusOnWebView()`
|
||||
|
||||
### `win.blurWebView()`
|
||||
|
||||
### `win.capturePage([rect, ]callback)`
|
||||
|
||||
* `rect` Object (opcional)- A área da página a ser capturada. Propriedades:
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
* `width` Integer
|
||||
* `height` Integer
|
||||
* `callback` Function
|
||||
|
||||
Captura uma imagem da página dentro do `rect`. Após completar, `callback` será chamada com `callback(imagem)`. `imagem` é uma instância de [NativeImage](../../../docs/api/native-image.md) que guarda dados sobre a imagem. Omitir `rect` captura toda a página visível.
|
||||
|
||||
### `win.print([options])`
|
||||
|
||||
Igual a `webContents.print([options])`
|
||||
|
||||
### `win.printToPDF(options, callback)`
|
||||
|
||||
Igual a `webContents.printToPDF(options, callback)`
|
||||
|
||||
### `win.loadURL(url[, options])`
|
||||
|
||||
Igual a `webContents.loadURL(url[, options])`.
|
||||
|
||||
### `win.reload()`
|
||||
|
||||
Igual a `webContents.reload`.
|
||||
|
||||
### `win.setMenu(menu)` _Linux_ _Windows_
|
||||
|
||||
* `menu` Menu
|
||||
|
||||
Define `menu` como a barra de menu da janela, definir como `null` remove a barra de menu.
|
||||
|
||||
### `win.setProgressBar(progress)`
|
||||
|
||||
* `progress` Double
|
||||
|
||||
Define o valor do progresso na barra de progresso. Extensão válida é [0, 1.0].
|
||||
|
||||
Remove a barra de progresso quando `progress` < 0.
|
||||
Muda para o modo indeterminado quando `progress` > 1.
|
||||
|
||||
Na plataforma Linux, apenas suporta o ambiente de desktop Unity, você precisa definir o nome do arquivo como `*.desktop` no campo `desktopName` no `package.json`. Por padrão, irá assumir `app.getName().desktop`.
|
||||
|
||||
### `win.setOverlayIcon(overlay, description)` _Windows 7+_
|
||||
|
||||
* `overlay` [NativeImage](../../../docs/api/native-image.md) - o ícone a ser exibido no canto inferior direito da barra de tarefas. Se este parâmetro for `null`, a sobreposição é eliminada.
|
||||
* `description` String - uma descrição que será providenciada a leitores de tela de acessibilidade.
|
||||
|
||||
Define uma sobreposição de 16px sobre o ícone da barra de tarefas atual, geralmente utilizado para indicar algum tipo de status de aplicação, ou notificar passivamente o usuário.
|
||||
|
||||
### `win.setThumbarButtons(buttons)` _Windows 7+_
|
||||
|
||||
`buttons` Array de objetos `button`:
|
||||
|
||||
`button` Object, propriedades:
|
||||
|
||||
* `icon` [NativeImage](../../../docs/api/native-image.md) - O ícone exibido na barra de ferramentas miniatura.
|
||||
* `tooltip` String (opcional) - O texto do balão de dica do botão.
|
||||
* `flags` Array (opcional) - Controla estados e comportamentos específicos do botão. Utiliza `enabled` por padrão. Pode incluir as seguintes strings:
|
||||
* `enabled` - O botão está ativo e disponível para o usuário.
|
||||
* `disabled` - O botão está desabilitado. Está presente, mas possui um estado visual indicando que não irá responder às ações do usuário.
|
||||
* `dismissonclick` - Quando o botão é clicado, o *flyout* do botão da barra de tarefas fecha imediatamente.
|
||||
* `nobackground` - Não desenhe a borda do botão, apenas utilize a imagem.
|
||||
* `hidden` - O botão não é exibido para o usuário.
|
||||
* `noninteractive` - O botão está habilitado, mas não interage; Não é exibido o estado de botão pressionado. Este valor está destinado a instâncias nas quais o botão é utilizado em uma notificação.
|
||||
* `click` - Função
|
||||
|
||||
Adiciona uma barra de ferramentes miniatura com um conjunto de botões específicos à imagem miniatura de uma janela no layout de um botão de barra de tarefas. Retorna um objeto `Boolean` indicando se a miniatura foi adicionada com sucesso.
|
||||
|
||||
O número de botões na barra de ferramentas miniatura não deve ser maior que 7 devido ao espaço limitado. Uma vez que você define a barra de ferramentas miniatura, ela não pode ser removida por causa da limitação da plataforma. Mas você pode chamar a API com um array vazio para limpar todos os botões.
|
||||
|
||||
### `win.showDefinitionForSelection()` _OS X_
|
||||
|
||||
Mostra um dicionário *pop-up* que procura a palavra selecionada na página.
|
||||
|
||||
### `win.setAutoHideMenuBar(hide)`
|
||||
|
||||
* `hide` Boolean
|
||||
|
||||
Define se a barra de menu da janela deve se esconder automaticamente. Uma vez que for definida, a barra de menu só será exibida quando usuários pressionarem a tecla `Alt`.
|
||||
|
||||
Se a barra de menu já estiver visível, chamar `setAutoHideMenuBar(true)` não irá escondê-la imediatamente.
|
||||
|
||||
### `win.isMenuBarAutoHide()`
|
||||
|
||||
Retorna um boolean indicando se a barra de menu se esconde automaticamente.
|
||||
|
||||
### `win.setMenuBarVisibility(visible)`
|
||||
|
||||
* `visible` Boolean
|
||||
|
||||
Define se a barra de menu deve ser visível. Se a barra de menu se esconde automaticamente, os usuários ainda podem exibí-la ao pressionar a tecla `Alt`.
|
||||
|
||||
### `win.isMenuBarVisible()`
|
||||
|
||||
Retorna um boolean indicando se a barra de menu está visível.
|
||||
|
||||
### `win.setVisibleOnAllWorkspaces(visible)`
|
||||
|
||||
* `visible` Boolean
|
||||
|
||||
Define se a janela deve estar visível em todos os *workspaces*.
|
||||
|
||||
**Nota:** Esta API não faz nada no Windows.
|
||||
|
||||
### `win.isVisibleOnAllWorkspaces()`
|
||||
|
||||
Retorna um boolean indicando se a janela está visível em todos os *workspaces*.
|
||||
|
||||
**Nota:** Esta API sempre retorna `false` no Windows.
|
||||
|
||||
|
142
docs-translations/pt-BR/development/build-instructions-linux.md
Normal file
142
docs-translations/pt-BR/development/build-instructions-linux.md
Normal file
|
@ -0,0 +1,142 @@
|
|||
# Instruções de Build (Linux)
|
||||
|
||||
Siga as orientações abaixo pra fazer o build do Electron no Linux.
|
||||
|
||||
## Pré-requisitos
|
||||
|
||||
* Python 2.7.x. Algumas distribuições como CentOS ainda usam Python 2.6.x,
|
||||
então você precisa checar a sua versão do Python com `python -V`.
|
||||
* Node.js v0.12.x. Há várias maneiras de instalar o Node. Você pode baixar o
|
||||
código fonte do [Node.js](http://nodejs.org) e compilar a partir dele.
|
||||
Fazer isto permite que você instale o Node no seu próprio diretório home
|
||||
como um usuário comum.
|
||||
Ou tente repositórios como [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories).
|
||||
* Clang 3.4 ou mais recente.
|
||||
* Cabeçalhos de desenvolvimento do GTK+ e libnotify.
|
||||
|
||||
No Ubuntu, instale as seguintes bibliotecas:
|
||||
|
||||
```bash
|
||||
$ sudo apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \
|
||||
libnotify-dev libgnome-keyring-dev libgconf2-dev \
|
||||
libasound2-dev libcap-dev libcups2-dev libxtst-dev \
|
||||
libxss1 libnss3-dev gcc-multilib g++-multilib
|
||||
```
|
||||
|
||||
No Fedora, instale as seguintes bibliotecas:
|
||||
|
||||
```bash
|
||||
$ sudo yum install clang dbus-devel gtk2-devel libnotify-devel libgnome-keyring-devel \
|
||||
xorg-x11-server-utils libcap-devel cups-devel libXtst-devel \
|
||||
alsa-lib-devel libXrandr-devel GConf2-devel nss-devel
|
||||
```
|
||||
|
||||
Outras distribuições podem oferecer pacotes similares para instalação através
|
||||
do gerenciador de pacotes como o pacman. Ou você pode compilar a partir do
|
||||
código fonte.
|
||||
|
||||
## Se Você Utilizar Máquinas Virtuais Para Fazer O Build
|
||||
|
||||
Se você planeja fazer o build do Electron numa máquina virtual, você vai precisar
|
||||
de um container de tamanho fixo de pelo menos 25 gigabytes.
|
||||
|
||||
## Baixando o Código
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/atom/electron.git
|
||||
```
|
||||
|
||||
## Bootstrapping
|
||||
|
||||
O script de *boostrap* irá baixar todas as dependências de build necessárias
|
||||
e criar os arquivos de projeto do build. Você deve ter o Python 2.7.x para
|
||||
executar o script com sucesso.
|
||||
Baixar certos arquivos pode demorar bastante. Note que estamos utilizando
|
||||
`ninja` para fazer o build do Electron, então não há um `Makefile` gerado.
|
||||
|
||||
```bash
|
||||
$ cd electron
|
||||
$ ./script/bootstrap.py -v
|
||||
```
|
||||
|
||||
### Compilação Cruzada
|
||||
|
||||
Se você quer fazer o build para `arm`, você também deve instalar as seguintes
|
||||
dependências:
|
||||
|
||||
```bash
|
||||
$ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \
|
||||
g++-arm-linux-gnueabihf
|
||||
```
|
||||
|
||||
E para fazer a compilação cruzada para `arm` ou `ia32`, você deve passar
|
||||
o parâmetro `--target_arch` para o script `bootstrap.py`:
|
||||
|
||||
```bash
|
||||
$ ./script/bootstrap.py -v --target_arch=arm
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
Se você quiser fazer o build para `Release` e `Debug`:
|
||||
|
||||
```bash
|
||||
$ ./script/build.py
|
||||
```
|
||||
|
||||
Este script irá fazer com que um executável bem pesado do Electron seja
|
||||
criado no diretório `out/R`. O arquivo possui mais de 1.3 gigabytes.
|
||||
Isso acontece por que o binário do Release contém símbolos de debugging.
|
||||
Para reduzir o tamanho do arquivo, rode o script `create-dist.py`:
|
||||
|
||||
```bash
|
||||
$ ./script/create-dist.py
|
||||
```
|
||||
|
||||
Isso irá colocar uma distribuição funcional com arquivos muito menores
|
||||
no diretório `dist`. Depois de rodar o script `create-dist.py`, talvez
|
||||
você queira remover o binário de 1.3+ gigabytes que ainda está em `out/R`.
|
||||
|
||||
Você também pode fazer apenas o build de `Debug`:
|
||||
|
||||
```bash
|
||||
$ ./script/build.py -c D
|
||||
```
|
||||
|
||||
Depois de completar o build, você pode encontrar o binário de debug do `electron`
|
||||
em `out/D`.
|
||||
|
||||
## Limpando
|
||||
|
||||
Para limpar os arquivos de build:
|
||||
|
||||
```bash
|
||||
$ ./script/clean.py
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Certifique-se de que você tenha instalado todas as dependências do build.
|
||||
|
||||
### Error While Loading Shared Libraries: libtinfo.so.5
|
||||
|
||||
O `clang` prebuilt irá tentar fazer o link com `libtinfo.so.5`. Dependendo
|
||||
da arquitetura do host, faça um link simbólico para o `libncurses` apropriado:
|
||||
|
||||
```bash
|
||||
$ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5
|
||||
```
|
||||
|
||||
## Testes
|
||||
|
||||
Teste suas modificações conforme o estilo de código do projeto utilizando:
|
||||
|
||||
```bash
|
||||
$ ./script/cpplint.py
|
||||
```
|
||||
|
||||
Teste funcionalidade utilizando:
|
||||
|
||||
```bash
|
||||
$ ./script/test.py
|
||||
```
|
83
docs-translations/uk-UA/README.md
Normal file
83
docs-translations/uk-UA/README.md
Normal file
|
@ -0,0 +1,83 @@
|
|||
Будь ласка, переконайтесь що ви використовуєте документацію, яка відповідає вашій версії Electron.
|
||||
Номер версії повинен бути присутнім в URL адресі сторінки. Якщо це не так, Ви можливо,
|
||||
використовуєте документацію із development гілки,
|
||||
яка може містити зміни в API, які не сумісні з вашою версією Electron.
|
||||
Якщо це так, тоді Ви можете переключитись на іншу версію документації
|
||||
із списку [доступних версій](http://electron.atom.io/docs/) на atom.io,
|
||||
або якщо ви використовуєте інтеррфейс GitHub,
|
||||
тоді відкрийте список "Switch branches/tags" і виберіть потрібну вам
|
||||
версію із списку тегів.
|
||||
|
||||
## Довідник
|
||||
|
||||
* [Підтримувані платформи](tutorial/supported-platforms.md)
|
||||
* [Application Distribution](tutorial/application-distribution.md)
|
||||
* [Mac App Store Submission Guide](tutorial/mac-app-store-submission-guide.md)
|
||||
* [Упаковка додатку](tutorial/application-packaging.md)
|
||||
* [Використання Native Node модулів](tutorial/using-native-node-modules.md)
|
||||
* [Debugging Main Process](tutorial/debugging-main-process.md)
|
||||
* [Використання Selenium and WebDriver](tutorial/using-selenium-and-webdriver.md)
|
||||
* [DevTools Extension](tutorial/devtools-extension.md)
|
||||
* [Використання Pepper Flash плагіну](tutorial/using-pepper-flash-plugin.md)
|
||||
|
||||
## Підручники
|
||||
|
||||
* [Швидкий старт](tutorial/quick-start.md)
|
||||
* [Desktop Environment Integration](tutorial/desktop-environment-integration.md)
|
||||
* [Online/Offline Event Detection](tutorial/online-offline-events.md)
|
||||
|
||||
## API References
|
||||
|
||||
* [Synopsis](api/synopsis.md)
|
||||
* [Process Object](api/process.md)
|
||||
* [Supported Chrome Command Line Switches](api/chrome-command-line-switches.md)
|
||||
* [Environment Variables](api/environment-variables.md)
|
||||
|
||||
### Користувальницькі елементи DOM
|
||||
|
||||
* [`File` Object](api/file-object.md)
|
||||
* [`<webview>` Tag](api/web-view-tag.md)
|
||||
* [`window.open` Function](api/window-open.md)
|
||||
|
||||
### Модулі для Main Process:
|
||||
|
||||
* [app](api/app.md)
|
||||
* [autoUpdater](api/auto-updater.md)
|
||||
* [BrowserWindow](api/browser-window.md)
|
||||
* [contentTracing](api/content-tracing.md)
|
||||
* [dialog](api/dialog.md)
|
||||
* [globalShortcut](api/global-shortcut.md)
|
||||
* [ipcMain](api/ipc-main.md)
|
||||
* [Menu](api/menu.md)
|
||||
* [MenuItem](api/menu-item.md)
|
||||
* [powerMonitor](api/power-monitor.md)
|
||||
* [powerSaveBlocker](api/power-save-blocker.md)
|
||||
* [protocol](api/protocol.md)
|
||||
* [session](api/session.md)
|
||||
* [webContents](api/web-contents.md)
|
||||
* [Tray](api/tray.md)
|
||||
|
||||
### Модулі для Renderer Process (Web Page):
|
||||
|
||||
* [ipcRenderer](api/ipc-renderer.md)
|
||||
* [remote](api/remote.md)
|
||||
* [webFrame](api/web-frame.md)
|
||||
|
||||
### Модулі для Both Processes:
|
||||
|
||||
* [clipboard](api/clipboard.md)
|
||||
* [crashReporter](api/crash-reporter.md)
|
||||
* [nativeImage](api/native-image.md)
|
||||
* [screen](api/screen.md)
|
||||
* [shell](api/shell.md)
|
||||
|
||||
## Розробка
|
||||
|
||||
* [Стиль кодування](development/coding-style.md)
|
||||
* [Source Code Directory Structure](development/source-code-directory-structure.md)
|
||||
* [Technical Differences to NW.js (formerly node-webkit)](development/atom-shell-vs-node-webkit.md)
|
||||
* [Build System Overview](development/build-system-overview.md)
|
||||
* [Build Instructions (OS X)](development/build-instructions-osx.md)
|
||||
* [Build Instructions (Windows)](development/build-instructions-windows.md)
|
||||
* [Build Instructions (Linux)](development/build-instructions-linux.md)
|
||||
* [Setting Up Symbol Server in debugger](development/setting-up-symbol-server.md)
|
97
docs-translations/uk-UA/styleguide.md
Normal file
97
docs-translations/uk-UA/styleguide.md
Normal file
|
@ -0,0 +1,97 @@
|
|||
# Electron Documentation Styleguide
|
||||
|
||||
Find the appropriate section for your task: [reading Electron documentation](#reading-electron-documentation)
|
||||
or [writing Electron documentation](#writing-electron-documentation).
|
||||
|
||||
## Написання документації для Electron
|
||||
|
||||
Існує кілька способів за допомогою яких ми ствоюємо документацію для Electron.
|
||||
|
||||
- Maximum one `h1` title per page.
|
||||
- Use `bash` instead of `cmd` in code blocks (because of syntax highlighter).
|
||||
- Doc `h1` titles should match object name (i.e. `browser-window` →
|
||||
`BrowserWindow`).
|
||||
- Hyphen separated filenames, however, are fine.
|
||||
- No headers following headers, add at least a one-sentence description.
|
||||
- Methods headers are wrapped in `code` ticks.
|
||||
- Event headers are wrapped in single 'quotation' marks.
|
||||
- No nesting lists more than 2 levels (unfortunately because of markdown
|
||||
renderer).
|
||||
- Add section titles: Events, Class Methods and Instance Methods.
|
||||
- Use 'will' over 'would' when describing outcomes.
|
||||
- Events and methods are `h3` headers.
|
||||
- Optional arguments written as `function (required[, optional])`.
|
||||
- Optional arguments are denoted when called out in list.
|
||||
- Line length is 80-column wrapped.
|
||||
- Platform specific methods are noted in italics following method header.
|
||||
- ```### `method(foo, bar)` _OS X_```
|
||||
- Prefer 'in the ___ process' over 'on'
|
||||
|
||||
### Переклад документації
|
||||
|
||||
Переклади документації знаходяться в дерикторії `docs-translations`.
|
||||
|
||||
Щоб додати переклад (або частковий переклад) документації:
|
||||
|
||||
- Create a subdirectory named by language abbreviation.
|
||||
- Within that subdirectory, duplicate the `docs` directory, keeping the
|
||||
names of directories and files same.
|
||||
- Translate the files.
|
||||
- Update the `README.md` within your language directory to link to the files
|
||||
you have translated.
|
||||
- Add a link to your translation directory on the main Electron [README](https://github.com/atom/electron#documentation-translations).
|
||||
|
||||
## Читання документації Electron
|
||||
|
||||
Кілька порад для того щоб легше зрозуміти синтаксис документації Electron.
|
||||
|
||||
### Методи
|
||||
|
||||
Приклад [методу](https://developer.mozilla.org/en-US/docs/Glossary/Method)
|
||||
в документації:
|
||||
|
||||
---
|
||||
|
||||
`methodName(required[, optional]))`
|
||||
|
||||
* `require` String, **required**
|
||||
* `optional` Integer
|
||||
|
||||
---
|
||||
|
||||
The method name is followed by the arguments it takes. Optional arguments are
|
||||
notated by brackets surrounding the optional argument as well as the comma
|
||||
required if this optional argument follows another argument.
|
||||
|
||||
Below the method is more detailed information on each of the arguments. The type
|
||||
of argument is notated by either the common types:
|
||||
[`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String),
|
||||
[`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number),
|
||||
[`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object),
|
||||
[`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
|
||||
or a custom type like Electron's [`webContent`](api/web-content.md).
|
||||
|
||||
### Події
|
||||
|
||||
Приклад [події](https://developer.mozilla.org/en-US/docs/Web/API/Event)
|
||||
в документації:
|
||||
|
||||
---
|
||||
|
||||
Подія: 'wake-up'
|
||||
|
||||
Повердає:
|
||||
|
||||
* `time` Текст
|
||||
|
||||
---
|
||||
|
||||
The event is a string that is used after a `.on` listener method. If it returns
|
||||
a value it and its type is noted below. If you were to listen and respond to
|
||||
this event it might look something like this:
|
||||
|
||||
```javascript
|
||||
Alarm.on('wake-up', function(time) {
|
||||
console.log(time)
|
||||
})
|
||||
```
|
|
@ -0,0 +1,53 @@
|
|||
# 使用原生模块
|
||||
|
||||
Electron同样也支持原生模块,但由于和官方的Node相比使用了不同的V8引擎,如果你想编译原生模块,则需要手动设置Electron的headers的位置。
|
||||
|
||||
## 原生Node模块的兼容性
|
||||
|
||||
当Node开始换新的V8引擎版本时,原生模块可能“坏”掉。为确保一切工作正常,你需要检查你想要使用的原生模块是否被Electron内置的Node支持。你可以在[这里](https://github.com/atom/electron/releases)查看Electron内置的Node版本,或者使用`process.version`(参考:[快速入门](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md))查看。
|
||||
|
||||
考虑到[NAN](https://github.com/nodejs/nan/)可以使你的开发更容易对多版本Node的支持,建议使用它来开发你自己的模块。你也可以使用[NAN](https://github.com/nodejs/nan/)来移植旧的模块到新的Node版本,以使它们可以在新的Electron下良好工作。
|
||||
|
||||
## 如何安装原生模块
|
||||
|
||||
如下三种方法教你安装原生模块:
|
||||
|
||||
### 最简单方式
|
||||
|
||||
最简单的方式就是通过[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild)包重新编译原生模块,它帮你自动完成了下载headers、编译原生模块等步骤:
|
||||
|
||||
```sh
|
||||
npm install --save-dev electron-rebuild
|
||||
|
||||
# 每次运行"npm install"时,也运行这条命令
|
||||
./node_modules/.bin/electron-rebuild
|
||||
|
||||
# 在windows下如果上述命令遇到了问题,尝试这个:
|
||||
.\node_modules\.bin\electron-rebuild.cmd
|
||||
```
|
||||
|
||||
### 通过npm安装
|
||||
|
||||
你当然也可以通过`npm`安装原生模块。大部分步骤和安装普通模块时一样,除了以下一些系统环境变量你需要自己操作:
|
||||
|
||||
```bash
|
||||
export npm_config_disturl=https://atom.io/download/atom-shell
|
||||
export npm_config_target=0.33.1
|
||||
export npm_config_arch=x64
|
||||
export npm_config_runtime=electron
|
||||
HOME=~/.electron-gyp npm install module-name
|
||||
```
|
||||
|
||||
### 通过node-gyp安装
|
||||
|
||||
你需要告诉`node-gyp`去哪下载Electron的headers,以及下载什么版本:
|
||||
|
||||
```bash
|
||||
$ cd /path-to-module/
|
||||
$ HOME=~/.electron-gyp node-gyp rebuild --target=0.29.1 --arch=x64 --dist-url=https://atom.io/download/atom-shell
|
||||
```
|
||||
|
||||
`HOME=~/.electron-gyp`设置了去哪找开发时的headers。
|
||||
`--target=0.29.1`设置了Electron的版本
|
||||
`--dist-url=...`设置了Electron的headers的下载地址
|
||||
`--arch=x64`设置了该模块为适配64bit操作系统而编译
|
119
docs-translations/zh-CN/tutorial/using-selenium-and-webdriver.md
Normal file
119
docs-translations/zh-CN/tutorial/using-selenium-and-webdriver.md
Normal file
|
@ -0,0 +1,119 @@
|
|||
# 使用Selenium和WebDriver
|
||||
|
||||
引自[ChromeDriver - WebDriver for Chrome][chrome-driver]:
|
||||
|
||||
> WebDriver是一款开源的支持多浏览器的自动化测试工具。它提供了操作网页、用户输入、JavaScript执行等能力。ChromeDriver是一个实现了WebDriver与Chromium联接协议的独立服务。它也是由开发了Chromium和WebDriver的团队开发的。
|
||||
|
||||
为了能够使`chromedriver`和Electron一起正常工作,我们需要告诉它Electron在哪,并且让它相信Electron就是Chrome浏览器。
|
||||
|
||||
## 通过WebDriverJs配置
|
||||
|
||||
[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) 是一个可以配合WebDriver做测试的node模块,我们会用它来做个演示。
|
||||
|
||||
### 1. 启动ChromeDriver
|
||||
|
||||
首先,你要下载`chromedriver`,然后运行以下命令:
|
||||
|
||||
```bash
|
||||
$ ./chromedriver
|
||||
Starting ChromeDriver (v2.10.291558) on port 9515
|
||||
Only local connections are allowed.
|
||||
```
|
||||
|
||||
记住`9515`这个端口号,我们后面会用到
|
||||
|
||||
### 2. 安装WebDriverJS
|
||||
|
||||
```bash
|
||||
$ npm install selenium-webdriver
|
||||
```
|
||||
|
||||
### 3. 联接到ChromeDriver
|
||||
|
||||
在Electron下使用`selenium-webdriver`和其平时的用法并没有大的差异,只是你需要手动设置连接ChromeDriver,以及Electron的路径:
|
||||
|
||||
```javascript
|
||||
const webdriver = require('selenium-webdriver');
|
||||
|
||||
var driver = new webdriver.Builder()
|
||||
// "9515" 是ChromeDriver使用的端口
|
||||
.usingServer('http://localhost:9515')
|
||||
.withCapabilities({
|
||||
chromeOptions: {
|
||||
// 这里设置Electron的路径
|
||||
binary: '/Path-to-Your-App.app/Contents/MacOS/Atom',
|
||||
}
|
||||
})
|
||||
.forBrowser('electron')
|
||||
.build();
|
||||
|
||||
driver.get('http://www.google.com');
|
||||
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
|
||||
driver.findElement(webdriver.By.name('btnG')).click();
|
||||
driver.wait(function() {
|
||||
return driver.getTitle().then(function(title) {
|
||||
return title === 'webdriver - Google Search';
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
driver.quit();
|
||||
```
|
||||
|
||||
## 通过WebdriverIO配置
|
||||
|
||||
[WebdriverIO](http://webdriver.io/)也是一个配合WebDriver用来测试的node模块
|
||||
|
||||
### 1. 启动ChromeDriver
|
||||
|
||||
首先,下载`chromedriver`,然后运行以下命令:
|
||||
|
||||
```bash
|
||||
$ chromedriver --url-base=wd/hub --port=9515
|
||||
Starting ChromeDriver (v2.10.291558) on port 9515
|
||||
Only local connections are allowed.
|
||||
```
|
||||
|
||||
记住`9515`端口,后面会用到
|
||||
|
||||
### 2. 安装WebdriverIO
|
||||
|
||||
```bash
|
||||
$ npm install webdriverio
|
||||
```
|
||||
|
||||
### 3. 连接到ChromeDriver
|
||||
|
||||
```javascript
|
||||
const webdriverio = require('webdriverio');
|
||||
var options = {
|
||||
host: "localhost", // 使用localhost作为ChromeDriver服务器
|
||||
port: 9515, // "9515"是ChromeDriver使用的端口
|
||||
desiredCapabilities: {
|
||||
browserName: 'chrome',
|
||||
chromeOptions: {
|
||||
binary: '/Path-to-Your-App/electron', // Electron的路径
|
||||
args: [/* cli arguments */] // 可选参数,类似:'app=' + /path/to/your/app/
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var client = webdriverio.remote(options);
|
||||
|
||||
client
|
||||
.init()
|
||||
.url('http://google.com')
|
||||
.setValue('#q', 'webdriverio')
|
||||
.click('#btnG')
|
||||
.getTitle().then(function(title) {
|
||||
console.log('Title was: ' + title);
|
||||
})
|
||||
.end();
|
||||
```
|
||||
|
||||
## 工作流程
|
||||
|
||||
无需重新编译Electron,只要把app的源码放到[Electron的资源目录](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md)里就可直接开始测试了。
|
||||
|
||||
当然,你也可以在运行Electron时传入参数指定你app的所在文件夹。这步可以免去你拷贝-粘贴你的app到Electron的资源目录。
|
||||
|
||||
[chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/
|
|
@ -58,6 +58,7 @@ select the tag that matches your version.
|
|||
|
||||
### Modules for the Renderer Process (Web Page):
|
||||
|
||||
* [desktopCapturer](api/desktop-capturer.md)
|
||||
* [ipcRenderer](api/ipc-renderer.md)
|
||||
* [remote](api/remote.md)
|
||||
* [webFrame](api/web-frame.md)
|
||||
|
|
|
@ -123,7 +123,6 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
|||
* `allowRunningInsecureContent` Boolean - Allow a https page to run
|
||||
JavaScript, CSS or plugins from http URLs. Default is `false`.
|
||||
* `images` Boolean - Enables image support. Default is `true`.
|
||||
* `java` Boolean - Enables Java support. Default is `false`.
|
||||
* `textAreasAreResizable` Boolean - Make TextArea elements resizable. Default
|
||||
is `true`.
|
||||
* `webgl` Boolean - Enables WebGL support. Default is `true`.
|
||||
|
@ -135,8 +134,6 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
|||
canvas features. Default is `false`.
|
||||
* `overlayScrollbars` Boolean - Enables overlay scrollbars. Default is
|
||||
`false`.
|
||||
* `overlayFullscreenVideo` Boolean - Enables overlay fullscreen video. Default
|
||||
is `false`
|
||||
* `sharedWorker` Boolean - Enables Shared Worker support. Default is `false`.
|
||||
* `directWrite` Boolean - Enables DirectWrite font rendering system on
|
||||
Windows. Default is `true`.
|
||||
|
@ -750,3 +747,9 @@ Sets whether the window should be visible on all workspaces.
|
|||
Returns whether the window is visible on all workspaces.
|
||||
|
||||
**Note:** This API always returns false on Windows.
|
||||
|
||||
### `win.setIgnoreMouseEvents(ignore)` _OS X_
|
||||
|
||||
* `ignore` Boolean
|
||||
|
||||
Ignore all moused events that happened in the window.
|
||||
|
|
69
docs/api/desktop-capturer.md
Normal file
69
docs/api/desktop-capturer.md
Normal file
|
@ -0,0 +1,69 @@
|
|||
# desktopCapturer
|
||||
|
||||
The `desktopCapturer` module can be used to get available sources that can be
|
||||
used to be captured with `getUserMedia`.
|
||||
|
||||
```javascript
|
||||
// In the renderer process.
|
||||
var desktopCapturer = require('electron').desktopCapturer;
|
||||
|
||||
desktopCapturer.getSources({types: ['window', 'screen']}, function(error, sources) {
|
||||
if (error) throw error;
|
||||
for (var i = 0; i < sources.length; ++i) {
|
||||
if (sources[i].name == "Electron") {
|
||||
navigator.webkitGetUserMedia({
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: sources[i].id,
|
||||
minWidth: 1280,
|
||||
maxWidth: 1280,
|
||||
minHeight: 720,
|
||||
maxHeight: 720
|
||||
}
|
||||
}
|
||||
}, gotStream, getUserMediaError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function gotStream(stream) {
|
||||
document.querySelector('video').src = URL.createObjectURL(stream);
|
||||
}
|
||||
|
||||
function getUserMediaError(e) {
|
||||
console.log('getUserMediaError');
|
||||
}
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
The `desktopCapturer` module has the following methods:
|
||||
|
||||
### `desktopCapturer.getSources(options, callback)`
|
||||
|
||||
* `options` Object
|
||||
* `types` Array - An array of String that lists the types of desktop sources
|
||||
to be captured, available types are `screen` and `window`.
|
||||
* `thumbnailSize` Object (optional) - The suggested size that thumbnail should
|
||||
be scaled, it is `{width: 150, height: 150}` by default.
|
||||
* `callback` Function
|
||||
|
||||
Starts a request to get all desktop sources, `callback` will be called with
|
||||
`callback(error, sources)` when the request is completed.
|
||||
|
||||
The `sources` is an array of `Source` objects, each `Source` represents a
|
||||
captured screen or individual window, and has following properties:
|
||||
* `id` String - The id of the captured window or screen used in
|
||||
`navigator.webkitGetUserMedia`. The format looks like `window:XX` or
|
||||
`screen:XX` where `XX` is a random generated number.
|
||||
* `name` String - The described name of the capturing screen or window. If the
|
||||
source is a screen, the name will be `Entire Screen` or `Screen <index>`; if
|
||||
it is a window, the name will be the window's title.
|
||||
* `thumbnail` [NativeImage](NativeImage.md) - A thumbnail image.
|
||||
|
||||
**Note:** There is no guarantee that the size of `source.thumbnail` is always
|
||||
the same as the `thumnbailSize` in `options`. It also depends on the scale of
|
||||
the screen or window.
|
|
@ -68,4 +68,4 @@ Returns the `webContents` that sent the message, you can call
|
|||
`event.sender.send` to reply to the asynchronous message, see
|
||||
[webContents.send][webcontents-send] for more information.
|
||||
|
||||
[webcontents-send]: web-contents.md#webcontentssendchannel-args
|
||||
[webcontents-send]: web-contents.md#webcontentssendchannel-arg1-arg2-
|
||||
|
|
|
@ -26,7 +26,9 @@ Create a new `MenuItem` with the following method:
|
|||
* `visible` Boolean
|
||||
* `checked` Boolean
|
||||
* `submenu` Menu - Should be specified for `submenu` type menu item, when
|
||||
it's specified the `type: 'submenu'` can be omitted for the menu item
|
||||
it's specified the `type: 'submenu'` can be omitted for the menu item.
|
||||
If the value is not a `Menu` then it will be automatically converted to one
|
||||
using `Menu.buildFromTemplate`.
|
||||
* `id` String - Unique within a single menu. If defined then it can be used
|
||||
as a reference to this item by the position attribute.
|
||||
* `position` String - This field allows fine-grained definition of the
|
||||
|
|
|
@ -11,7 +11,7 @@ both processes.
|
|||
|
||||
The basic rule is: if a module is [GUI][gui] or low-level system related, then
|
||||
it should be only available in the main process. You need to be familiar with
|
||||
the concept of [main process vs. renderer process][mai-process] scripts to be
|
||||
the concept of [main process vs. renderer process][main-process] scripts to be
|
||||
able to use those modules.
|
||||
|
||||
The main process script is just like a normal Node.js script:
|
||||
|
|
|
@ -25,7 +25,7 @@ myNotification.onclick = function () {
|
|||
}
|
||||
```
|
||||
|
||||
While code and user experience across operating systems are similar, but there
|
||||
While code and user experience across operating systems are similar, there
|
||||
are fine differences.
|
||||
|
||||
### Windows
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
'atom/browser/api/lib/tray.coffee',
|
||||
'atom/browser/api/lib/web-contents.coffee',
|
||||
'atom/browser/lib/chrome-extension.coffee',
|
||||
'atom/browser/lib/desktop-capturer.coffee',
|
||||
'atom/browser/lib/guest-view-manager.coffee',
|
||||
'atom/browser/lib/guest-window-manager.coffee',
|
||||
'atom/browser/lib/init.coffee',
|
||||
|
@ -53,6 +54,7 @@
|
|||
'atom/renderer/lib/web-view/web-view.coffee',
|
||||
'atom/renderer/lib/web-view/web-view-attributes.coffee',
|
||||
'atom/renderer/lib/web-view/web-view-constants.coffee',
|
||||
'atom/renderer/api/lib/desktop-capturer.coffee',
|
||||
'atom/renderer/api/lib/exports/electron.coffee',
|
||||
'atom/renderer/api/lib/ipc.coffee',
|
||||
'atom/renderer/api/lib/ipc-renderer.coffee',
|
||||
|
@ -81,6 +83,8 @@
|
|||
'atom/browser/api/atom_api_content_tracing.cc',
|
||||
'atom/browser/api/atom_api_cookies.cc',
|
||||
'atom/browser/api/atom_api_cookies.h',
|
||||
'atom/browser/api/atom_api_desktop_capturer.cc',
|
||||
'atom/browser/api/atom_api_desktop_capturer.h',
|
||||
'atom/browser/api/atom_api_download_item.cc',
|
||||
'atom/browser/api/atom_api_download_item.h',
|
||||
'atom/browser/api/atom_api_dialog.cc',
|
||||
|
@ -200,8 +204,6 @@
|
|||
'atom/browser/ui/atom_menu_model.h',
|
||||
'atom/browser/ui/cocoa/atom_menu_controller.h',
|
||||
'atom/browser/ui/cocoa/atom_menu_controller.mm',
|
||||
'atom/browser/ui/cocoa/event_processing_window.h',
|
||||
'atom/browser/ui/cocoa/event_processing_window.mm',
|
||||
'atom/browser/ui/file_dialog.h',
|
||||
'atom/browser/ui/file_dialog_gtk.cc',
|
||||
'atom/browser/ui/file_dialog_mac.mm',
|
||||
|
@ -376,6 +378,10 @@
|
|||
'chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.h',
|
||||
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc',
|
||||
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h',
|
||||
'chromium_src/chrome/browser/media/desktop_media_list.h',
|
||||
'chromium_src/chrome/browser/media/desktop_media_list_observer.h',
|
||||
'chromium_src/chrome/browser/media/native_desktop_media_list.cc',
|
||||
'chromium_src/chrome/browser/media/native_desktop_media_list.h',
|
||||
'chromium_src/chrome/browser/printing/print_job.cc',
|
||||
'chromium_src/chrome/browser/printing/print_job.h',
|
||||
'chromium_src/chrome/browser/printing/print_job_manager.cc',
|
||||
|
|
|
@ -196,7 +196,7 @@ def create_chrome_version_h():
|
|||
def touch_config_gypi():
|
||||
config_gypi = os.path.join(SOURCE_ROOT, 'vendor', 'node', 'config.gypi')
|
||||
with open(config_gypi, 'w+') as f:
|
||||
content = '\n{}'
|
||||
content = "\n{'variables':{}}"
|
||||
if f.read() != content:
|
||||
f.write(content)
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ LINUX_DEPS = [
|
|||
'libgtk2.0-dev',
|
||||
'libnotify-dev',
|
||||
'libnss3-dev',
|
||||
'libxtst-dev',
|
||||
'gcc-multilib',
|
||||
'g++-multilib',
|
||||
]
|
||||
|
|
|
@ -7,8 +7,8 @@ import sys
|
|||
|
||||
|
||||
BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \
|
||||
'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent'
|
||||
LIBCHROMIUMCONTENT_COMMIT = '17a4337f7948a45b5ea4b8f391df152ba8db5979'
|
||||
'http://github-janky-artifacts.s3.amazonaws.com/libchromiumcontent'
|
||||
LIBCHROMIUMCONTENT_COMMIT = 'cfbe8ec7e14af4cabd1474386f54e197db1f7ac1'
|
||||
|
||||
PLATFORM = {
|
||||
'cygwin': 'win32',
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue