Merge remote-tracking branch 'refs/remotes/atom/master'

This commit is contained in:
Plusb Preco 2015-12-09 16:41:23 +09:00
commit a190b964c8
110 changed files with 2288 additions and 341 deletions

View file

@ -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

View file

@ -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': [

View file

@ -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(

View file

@ -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;

View 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);

View 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_

View file

@ -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);

View file

@ -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") {

View file

@ -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)

View file

@ -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,

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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() {

View file

@ -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;

View file

@ -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));
}

View file

@ -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

View 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

View file

@ -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

View file

@ -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'

View file

@ -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(),

View file

@ -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;

View file

@ -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;

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -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();
}

View file

@ -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_;

View file

@ -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>

View file

@ -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

View file

@ -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;

View file

@ -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_

View file

@ -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

View file

@ -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.

View file

@ -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;;
}

View file

@ -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")

View file

@ -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")

View file

@ -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

View file

@ -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,

View file

@ -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))

View file

@ -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;
}

View file

@ -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(

View file

@ -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

View file

@ -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_

View file

@ -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)) {

View file

@ -130,7 +130,7 @@ bool CrashReporterLinux::CrashDone(const MinidumpDescriptor& minidump,
// static
CrashReporterLinux* CrashReporterLinux::GetInstance() {
return Singleton<CrashReporterLinux>::get();
return base::Singleton<CrashReporterLinux>::get();
}
// static

View file

@ -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();

View file

@ -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();

View file

@ -126,7 +126,7 @@ CrashReporterMac::GetUploadedReports(const std::string& path) {
// static
CrashReporterMac* CrashReporterMac::GetInstance() {
return Singleton<CrashReporterMac>::get();
return base::Singleton<CrashReporterMac>::get();
}
// static

View file

@ -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

View file

@ -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();

View file

@ -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

View file

@ -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");

View file

@ -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")

View file

@ -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);

View file

@ -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);

View file

@ -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";

View file

@ -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[];

View 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)

View file

@ -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'

View file

@ -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...]

View file

@ -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);
}

View file

@ -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

View 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_

View file

@ -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_

View 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_);
}
}

View 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_

View file

@ -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);

View file

@ -503,7 +503,7 @@ class ProcessSingleton::LinuxWatcher
// reads.
size_t bytes_read_;
base::OneShotTimer<SocketReader> timer_;
base::OneShotTimer timer_;
DISALLOW_COPY_AND_ASSIGN(SocketReader);
};

View file

@ -111,7 +111,7 @@ TtsController* TtsController::GetInstance() {
// static
TtsControllerImpl* TtsControllerImpl::GetInstance() {
return Singleton<TtsControllerImpl>::get();
return base::Singleton<TtsControllerImpl>::get();
}
TtsControllerImpl::TtsControllerImpl()

View file

@ -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_

View file

@ -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

View file

@ -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

View file

@ -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();
}
}

View file

@ -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 */,

View file

@ -28,7 +28,7 @@ class GlobalMenuBarRegistrarX11 {
void OnWindowUnmapped(unsigned long xid);
private:
friend struct DefaultSingletonTraits<GlobalMenuBarRegistrarX11>;
friend struct base::DefaultSingletonTraits<GlobalMenuBarRegistrarX11>;
GlobalMenuBarRegistrarX11();
~GlobalMenuBarRegistrarX11();

View file

@ -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.

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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:

View file

@ -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;
}

View file

@ -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.

View 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.

View 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
```

View 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)

View 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)
})
```

View file

@ -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操作系统而编译

View 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/

View file

@ -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)

View file

@ -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.

View 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.

View file

@ -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-

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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',

View file

@ -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)

View file

@ -17,6 +17,7 @@ LINUX_DEPS = [
'libgtk2.0-dev',
'libnotify-dev',
'libnss3-dev',
'libxtst-dev',
'gcc-multilib',
'g++-multilib',
]

View file

@ -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